• R/O
  • HTTP
  • SSH
  • HTTPS

shootinggame: Commit

Metro Style Appとして作成してみます。


Commit MetaInfo

Revision9a2e2a2edb6b4c0c959513895285fea8ba43a3f9 (tree)
Time2012-06-17 13:32:43
Authorsfpgmr <sfpg@user...>
Commitersfpgmr

Log Message

Boost.MSMを試してみる。

Change Summary

Incremental Difference

--- a/ShootingGame/App.xaml.cpp
+++ b/ShootingGame/App.xaml.cpp
@@ -64,25 +64,27 @@ void App::OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEvent
6464 //TODO: 以前中断したアプリケーションから状態を読み込みます。
6565 }
6666
67- //// ナビゲーション コンテキストとして動作するフレームを作成し、最初のページに移動します
67+ // ナビゲーション コンテキストとして動作するフレームを作成し、最初のページに移動します
6868 //auto rootFrame = ref new Frame();
6969 //if (!rootFrame->Navigate(TypeName(MainPage::typeid)))
7070 //{
7171 // throw ref new FailureException("Failed to create initial page");
7272 //}
73+// mainPage_ = safe_cast<MainPage^>(rootFrame->Content);//ref new MainPage();
74+// Window::Current->Content = rootFrame;
75+// Window::Current->Activate();
7376
74- //// フレームを現在のウィンドウに配置し、アクティブであることを確認します
75- //Window::Current->Content = rootFrame;
76- //Window::Current->Activate();
77+ // フレームを現在のウィンドウに配置し、アクティブであることを確認します
78+ mainPage_ = ref new MainPage();
7779
78- mainPage_ = ref new MainPage();
7980
8081 // Place the frame in the current Window and ensure that it is active
8182 Window::Current->Content = mainPage_;
8283 Window::Current->Activated += ref new WindowActivatedEventHandler(this, &App::OnWindowActivationChanged);
8384 Window::Current->Activate();
8485
85- gameMain_ = ref new GameMain();
86+ //state_;
87+ gameMain_ = ref new GameMain();
8688 gameMain_->Initialize(Window::Current->CoreWindow,mainPage_->SwapChainBackgroundPanel(),DisplayProperties::LogicalDpi);
8789
8890 eventToken_ =
--- a/ShootingGame/App.xaml.h
+++ b/ShootingGame/App.xaml.h
@@ -22,6 +22,11 @@ namespace ShootingGame
2222 App();
2323 virtual void OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ pArgs) override;
2424
25+ Windows::UI::Xaml::Controls::SwapChainBackgroundPanel^ App::SwapChainBackGrroundPanel()
26+ {
27+ return mainPage_->SwapChainBackgroundPanel();
28+ }
29+
2530 private:
2631 MainPage^ mainPage_;
2732 GameMain^ gameMain_;
--- a/ShootingGame/Common/BindableBase.h
+++ b/ShootingGame/Common/BindableBase.h
@@ -1,27 +1,20 @@
11 #pragma once
22
3-#include "pch.h"
4-
53 namespace ShootingGame
64 {
75 namespace Common
86 {
9- // Suppress class "not consumable from JavaScript because it's not marked 'sealed'" warning
10- // currently emitted despite the WebHostHidden attribute
11- #pragma warning(push)
12- #pragma warning(disable: 4449)
137 /// <summary>
148 /// Implementation of <see cref="INotifyPropertyChanged"/> to simplify models.
159 /// </summary>
1610 [Windows::Foundation::Metadata::WebHostHidden]
1711 public ref class BindableBase : Windows::UI::Xaml::Data::INotifyPropertyChanged
1812 {
19- internal:
20- event Windows::UI::Xaml::Data::PropertyChangedEventHandler^ PropertyChanged;
13+ public:
14+ virtual event Windows::UI::Xaml::Data::PropertyChangedEventHandler^ PropertyChanged;
2115
2216 protected:
23- void OnPropertyChanged(Platform::String^ propertyName);
17+ virtual void OnPropertyChanged(Platform::String^ propertyName);
2418 };
25- #pragma warning(pop)
2619 }
2720 }
--- a/ShootingGame/Common/BooleanNegationConverter.cpp
+++ b/ShootingGame/Common/BooleanNegationConverter.cpp
@@ -7,15 +7,23 @@ using namespace Platform;
77 using namespace Windows::Foundation;
88 using namespace Windows::UI::Xaml::Interop;
99
10-Object^ BooleanNegationConverter::Convert(Object^ value, TypeName targetType, Object^ parameter, String^)
10+Object^ BooleanNegationConverter::Convert(Object^ value, TypeName targetType, Object^ parameter, String^ language)
1111 {
12+ (void) targetType; // Unused parameter
13+ (void) parameter; // Unused parameter
14+ (void) language; // Unused parameter
15+
1216 auto boxedBool = dynamic_cast<Box<bool>^>(value);
1317 auto boolValue = (boxedBool != nullptr && boxedBool->Value);
1418 return !boolValue;
1519 }
1620
17-Object^ BooleanNegationConverter::ConvertBack(Object^ value, TypeName targetType, Object^ parameter, String^)
21+Object^ BooleanNegationConverter::ConvertBack(Object^ value, TypeName targetType, Object^ parameter, String^ language)
1822 {
23+ (void) targetType; // Unused parameter
24+ (void) parameter; // Unused parameter
25+ (void) language; // Unused parameter
26+
1927 auto boxedBool = dynamic_cast<Box<bool>^>(value);
2028 auto boolValue = (boxedBool != nullptr && boxedBool->Value);
2129 return !boolValue;
--- a/ShootingGame/Common/BooleanNegationConverter.h
+++ b/ShootingGame/Common/BooleanNegationConverter.h
@@ -1,7 +1,5 @@
11 #pragma once
22
3-#include "pch.h"
4-
53 namespace ShootingGame
64 {
75 namespace Common
@@ -12,8 +10,8 @@ namespace ShootingGame
1210 public ref class BooleanNegationConverter sealed : Windows::UI::Xaml::Data::IValueConverter
1311 {
1412 public:
15- virtual Object^ Convert(Object^ value, Windows::UI::Xaml::Interop::TypeName targetType, Object^ parameter, Platform::String^);
16- virtual Object^ ConvertBack(Object^ value, Windows::UI::Xaml::Interop::TypeName targetType, Object^ parameter, Platform::String^);
13+ virtual Platform::Object^ Convert(Platform::Object^ value, Windows::UI::Xaml::Interop::TypeName targetType, Platform::Object^ parameter, Platform::String^ language);
14+ virtual Platform::Object^ ConvertBack(Platform::Object^ value, Windows::UI::Xaml::Interop::TypeName targetType, Platform::Object^ parameter, Platform::String^ language);
1715 };
1816 }
1917 }
--- a/ShootingGame/Common/BooleanToVisibilityConverter.cpp
+++ b/ShootingGame/Common/BooleanToVisibilityConverter.cpp
@@ -8,15 +8,23 @@ using namespace Windows::Foundation;
88 using namespace Windows::UI::Xaml;
99 using namespace Windows::UI::Xaml::Interop;
1010
11-Object^ BooleanToVisibilityConverter::Convert(Object^ value, TypeName targetType, Object^ parameter, String^)
11+Object^ BooleanToVisibilityConverter::Convert(Object^ value, TypeName targetType, Object^ parameter, String^ language)
1212 {
13+ (void) targetType; // Unused parameter
14+ (void) parameter; // Unused parameter
15+ (void) language; // Unused parameter
16+
1317 auto boxedBool = dynamic_cast<Box<bool>^>(value);
1418 auto boolValue = (boxedBool != nullptr && boxedBool->Value);
1519 return (boolValue ? Visibility::Visible : Visibility::Collapsed);
1620 }
1721
18-Object^ BooleanToVisibilityConverter::ConvertBack(Object^ value, TypeName targetType, Object^ parameter, String^)
22+Object^ BooleanToVisibilityConverter::ConvertBack(Object^ value, TypeName targetType, Object^ parameter, String^ language)
1923 {
24+ (void) targetType; // Unused parameter
25+ (void) parameter; // Unused parameter
26+ (void) language; // Unused parameter
27+
2028 auto visibility = dynamic_cast<Box<Visibility>^>(value);
2129 return (visibility != nullptr && visibility->Value == Visibility::Visible);
2230 }
--- a/ShootingGame/Common/BooleanToVisibilityConverter.h
+++ b/ShootingGame/Common/BooleanToVisibilityConverter.h
@@ -1,20 +1,18 @@
11 #pragma once
22
3-#include "pch.h"
4-
53 namespace ShootingGame
64 {
75 namespace Common
86 {
97 /// <summary>
10- /// Value converter that translates true to <see cref="Visibility.Visible"/> and false
11- /// to <see cref="Visibility.Collapsed"/>.
8+ /// Value converter that translates true to <see cref="Visibility::Visible"/> and false
9+ /// to <see cref="Visibility::Collapsed"/>.
1210 /// </summary>
1311 public ref class BooleanToVisibilityConverter sealed : Windows::UI::Xaml::Data::IValueConverter
1412 {
1513 public:
16- virtual Object^ Convert(Object^ value, Windows::UI::Xaml::Interop::TypeName targetType, Object^ parameter, Platform::String^);
17- virtual Object^ ConvertBack(Object^ value, Windows::UI::Xaml::Interop::TypeName targetType, Object^ parameter, Platform::String^);
14+ virtual Platform::Object^ Convert(Platform::Object^ value, Windows::UI::Xaml::Interop::TypeName targetType, Platform::Object^ parameter, Platform::String^ language);
15+ virtual Platform::Object^ ConvertBack(Platform::Object^ value, Windows::UI::Xaml::Interop::TypeName targetType, Platform::Object^ parameter, Platform::String^ language);
1816 };
1917 }
2018 }
--- a/ShootingGame/Common/LayoutAwarePage.cpp
+++ b/ShootingGame/Common/LayoutAwarePage.cpp
@@ -1,3 +1,14 @@
1+//*********************************************************
2+//
3+// Copyright (c) Microsoft. All rights reserved.
4+// This code is licensed under the Microsoft Public License.
5+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
6+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
7+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
8+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
9+//
10+//*********************************************************
11+
112 #include "pch.h"
213 #include "LayoutAwarePage.h"
314
@@ -10,67 +21,52 @@ using namespace Windows::Foundation::Collections;
1021 using namespace Windows::UI::ViewManagement;
1122 using namespace Windows::UI::Xaml;
1223 using namespace Windows::UI::Xaml::Controls;
24+using namespace Windows::UI::Xaml::Interop;
1325
1426 /// <summary>
1527 /// Initializes a new instance of the <see cref="LayoutAwarePage"/> class.
1628 /// </summary>
1729 LayoutAwarePage::LayoutAwarePage()
1830 {
19- if (Windows::ApplicationModel::DesignMode::DesignModeEnabled) return;
31+ if (Windows::ApplicationModel::DesignMode::DesignModeEnabled) return;
2032
21- // Map application view state to visual state for this page when it is part of the visual tree
22- Loaded += ref new RoutedEventHandler(this, &LayoutAwarePage::StartLayoutUpdates);
23- Unloaded += ref new RoutedEventHandler(this, &LayoutAwarePage::StopLayoutUpdates);
33+ // Create an empty default view model
34+ DefaultViewModel = ref new Map<String^, Object^>(std::less<String^>());
2435
25- // Establish the default view model as the initial DataContext
26- DataContext = _defaultViewModel = ref new Map<String^, Object^>(std::less<String^>());
36+ // Map application view state to visual state for this page when it is part of the visual tree
37+ Loaded += ref new RoutedEventHandler(this, &LayoutAwarePage::StartLayoutUpdates);
38+ Unloaded += ref new RoutedEventHandler(this, &LayoutAwarePage::StopLayoutUpdates);
2739 }
2840
41+static TypeName _thisType = { LayoutAwarePage::typeid->FullName, TypeKind::Custom };
42+static TypeName _observableMapType = { IObservableMap<Platform::String^, Object^>::typeid->FullName, TypeKind::Metadata };
43+static Windows::UI::Xaml::DependencyProperty^ _defaultViewModelProperty =
44+ DependencyProperty::Register("DefaultViewModel", _observableMapType, _thisType, nullptr);
45+
2946 /// <summary>
30-/// Gets an implementation of <see cref="IObservableMap<String, Object>"/> set as the page's
31-/// default <see cref="DataContext"/>. This instance can be bound and surfaces property change
32-/// notifications making it suitable for use as a trivial view model.
47+/// Identifies the <see cref="DefaultViewModel"/> dependency property.
3348 /// </summary>
34-IObservableMap<Platform::String^, Object^>^ LayoutAwarePage::DefaultViewModel::get()
49+DependencyProperty^ LayoutAwarePage::DefaultViewModelProperty::get()
3550 {
36- return _defaultViewModel;
51+ return _defaultViewModelProperty;
3752 }
3853
3954 /// <summary>
40-/// Gets a value indicating whether visual states can be a loose interpretation of the actual
41-/// application view state. This is often convenient when a page layout is space constrained.
55+/// Gets an implementation of <see cref="IObservableMap&lt;String, Object&gt;"/> designed to be
56+/// used as a trivial view model.
4257 /// </summary>
43-/// <remarks>
44-/// The default value of false indicates that the visual state is identical to the view state,
45-/// meaning that Filled is only used when another application is snapped. When set to true
46-/// FullScreenLandscape is used to indicate that at least 1366 virtual pixels of horizontal real
47-/// estate are available - even if another application is snapped - and Filled indicates a lesser
48-/// width, even if no other application is snapped. On a smaller display such as a 1024x768
49-/// panel this will result in the visual state Filled whenever the device is in landscape
50-/// orientation.
51-/// </remarks>
52-bool LayoutAwarePage::UseFilledStateForNarrowWindow::get()
58+IObservableMap<Platform::String^, Object^>^ LayoutAwarePage::DefaultViewModel::get()
5359 {
54- return _useFilledStateForNarrowWindow;
60+ return safe_cast<Windows::Foundation::Collections::IObservableMap<Platform::String^, Object^>^>(GetValue(DefaultViewModelProperty));
5561 }
5662
5763 /// <summary>
58-/// Sets a value indicating whether visual states can be a loose interpretation of the actual
59-/// application view state. This is often convenient when a page layout is space constrained.
64+/// Sets an implementation of <see cref="IObservableMap&lt;String, Object&gt;"/> designed to be
65+/// used as a trivial view model.
6066 /// </summary>
61-/// <remarks>
62-/// The default value of false indicates that the visual state is identical to the view state,
63-/// meaning that Filled is only used when another application is snapped. When set to true
64-/// FullScreenLandscape is used to indicate that at least 1366 virtual pixels of horizontal real
65-/// estate are available - even if another application is snapped - and Filled indicates a lesser
66-/// width, even if no other application is snapped. On a smaller display such as a 1024x768
67-/// panel this will result in the visual state Filled whenever the device is in landscape
68-/// orientation.
69-/// </remarks>
70-void LayoutAwarePage::UseFilledStateForNarrowWindow::set(bool value)
67+void LayoutAwarePage::DefaultViewModel::set(IObservableMap<Platform::String^, Object^>^ value)
7168 {
72- _useFilledStateForNarrowWindow = value;
73- this->InvalidateVisualState();
69+ SetValue(DefaultViewModelProperty, value);
7470 }
7571
7672 /// <summary>
@@ -81,11 +77,11 @@ void LayoutAwarePage::UseFilledStateForNarrowWindow::set(bool value)
8177 /// <param name="e">Event data describing the conditions that led to the event.</param>
8278 void LayoutAwarePage::GoHome(Object^ sender, RoutedEventArgs^ e)
8379 {
84- // Use the navigation frame to return to the topmost page
85- if (Frame != nullptr)
86- {
87- while (Frame->CanGoBack) Frame->GoBack();
88- }
80+ // Use the navigation frame to return to the topmost page
81+ if (Frame != nullptr)
82+ {
83+ while (Frame->CanGoBack) Frame->GoBack();
84+ }
8985 }
9086
9187 /// <summary>
@@ -96,8 +92,8 @@ void LayoutAwarePage::GoHome(Object^ sender, RoutedEventArgs^ e)
9692 /// <param name="e">Event data describing the conditions that led to the event.</param>
9793 void LayoutAwarePage::GoBack(Object^ sender, RoutedEventArgs^ e)
9894 {
99- // Use the navigation frame to return to the previous page
100- if (Frame != nullptr && Frame->CanGoBack) Frame->GoBack();
95+ // Use the navigation frame to return to the previous page
96+ if (Frame != nullptr && Frame->CanGoBack) Frame->GoBack();
10197 }
10298
10399 /// <summary>
@@ -117,27 +113,21 @@ void LayoutAwarePage::GoBack(Object^ sender, RoutedEventArgs^ e)
117113 /// <seealso cref="InvalidateVisualState"/>
118114 void LayoutAwarePage::StartLayoutUpdates(Object^ sender, RoutedEventArgs^ e)
119115 {
120- auto control = safe_cast<Control^>(sender);
121- if (_layoutAwareControls == nullptr) {
122- // Start listening to view state changes when there are controls interested in updates
123- _layoutAwareControls = ref new Vector<Control^>();
124- _viewStateEventToken = ApplicationView::GetForCurrentView()->ViewStateChanged += ref new TypedEventHandler<ApplicationView^,ApplicationViewStateChangedEventArgs^>(this, &LayoutAwarePage::ViewStateChanged);
125- _windowSizeEventToken = Window::Current->SizeChanged += ref new WindowSizeChangedEventHandler(this, &LayoutAwarePage::WindowSizeChanged);
126- }
127- _layoutAwareControls->Append(control);
128-
129- // Set the initial visual state of the control
130- VisualStateManager::GoToState(control, DetermineVisualState(ApplicationView::Value), false);
131-}
132-
133-void LayoutAwarePage::ViewStateChanged(ApplicationView^ sender, ApplicationViewStateChangedEventArgs^ e)
134-{
135- InvalidateVisualState(e->ViewState);
116+ auto control = safe_cast<Control^>(sender);
117+ if (_layoutAwareControls == nullptr) {
118+ // Start listening to view state changes when there are controls interested in updates
119+ _layoutAwareControls = ref new Vector<Control^>();
120+ _windowSizeEventToken = Window::Current->SizeChanged += ref new WindowSizeChangedEventHandler(this, &LayoutAwarePage::WindowSizeChanged);
121+ }
122+ _layoutAwareControls->Append(control);
123+
124+ // Set the initial visual state of the control
125+ VisualStateManager::GoToState(control, DetermineVisualState(ApplicationView::Value), false);
136126 }
137127
138128 void LayoutAwarePage::WindowSizeChanged(Object^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ e)
139129 {
140- if (_useFilledStateForNarrowWindow) InvalidateVisualState();
130+ InvalidateVisualState();
141131 }
142132
143133 /// <summary>
@@ -153,19 +143,18 @@ void LayoutAwarePage::WindowSizeChanged(Object^ sender, Windows::UI::Core::Windo
153143 /// <seealso cref="StartLayoutUpdates"/>
154144 void LayoutAwarePage::StopLayoutUpdates(Object^ sender, RoutedEventArgs^ e)
155145 {
156- auto control = safe_cast<Control^>(sender);
157- unsigned int index;
158- if (_layoutAwareControls != nullptr && _layoutAwareControls->IndexOf(control, &index))
159- {
160- _layoutAwareControls->RemoveAt(index);
161- if (_layoutAwareControls->Size == 0)
162- {
163- // Stop listening to view state changes when no controls are interested in updates
164- ApplicationView::GetForCurrentView()->ViewStateChanged -= _viewStateEventToken;
165- Window::Current->SizeChanged -= _windowSizeEventToken;
166- _layoutAwareControls = nullptr;
167- }
168- }
146+ auto control = safe_cast<Control^>(sender);
147+ unsigned int index;
148+ if (_layoutAwareControls != nullptr && _layoutAwareControls->IndexOf(control, &index))
149+ {
150+ _layoutAwareControls->RemoveAt(index);
151+ if (_layoutAwareControls->Size == 0)
152+ {
153+ // Stop listening to view state changes when no controls are interested in updates
154+ Window::Current->SizeChanged -= _windowSizeEventToken;
155+ _layoutAwareControls = nullptr;
156+ }
157+ }
169158 }
170159
171160 /// <summary>
@@ -178,23 +167,13 @@ void LayoutAwarePage::StopLayoutUpdates(Object^ sender, RoutedEventArgs^ e)
178167 /// <seealso cref="InvalidateVisualState"/>
179168 Platform::String^ LayoutAwarePage::DetermineVisualState(ApplicationViewState viewState)
180169 {
181- auto actualViewState = viewState;
182- if (_useFilledStateForNarrowWindow &&
183- (viewState == ApplicationViewState::Filled ||
184- viewState == ApplicationViewState::FullScreenLandscape))
185- {
186- // Allow pages to request that the Filled state be used only for landscape layouts narrower
187- // than 1366 virtual pixels
188- auto windowWidth = Window::Current->Bounds.Width;
189- actualViewState = windowWidth >= 1366 ? ApplicationViewState::FullScreenLandscape : ApplicationViewState::Filled;
190- }
191- switch (actualViewState)
192- {
193- case ApplicationViewState::Filled: return "Filled";
194- case ApplicationViewState::Snapped: return "Snapped";
195- case ApplicationViewState::FullScreenPortrait: return "FullScreenPortrait";
196- default: case ApplicationViewState::FullScreenLandscape: return "FullScreenLandscape";
197- }
170+ switch (viewState)
171+ {
172+ case ApplicationViewState::Filled: return "Filled";
173+ case ApplicationViewState::Snapped: return "Snapped";
174+ case ApplicationViewState::FullScreenPortrait: return "FullScreenPortrait";
175+ default: case ApplicationViewState::FullScreenLandscape: return "FullScreenLandscape";
176+ }
198177 }
199178
200179 /// <summary>
@@ -207,30 +186,15 @@ Platform::String^ LayoutAwarePage::DetermineVisualState(ApplicationViewState vie
207186 /// </remarks>
208187 void LayoutAwarePage::InvalidateVisualState()
209188 {
210- InvalidateVisualState(ApplicationView::Value);
211-}
212-
213-/// <summary>
214-/// Updates all controls that are listening for visual state changes with the correct visual
215-/// state.
216-/// </summary>
217-/// <remarks>
218-/// Typically used in conjunction with overriding <see cref="DetermineVisualState"/> to
219-/// signal that a different value may be returned even though the view state has not changed.
220-/// </remarks>
221-/// <param name="viewState">The desired view state, or null if the current view state should be
222-/// used.</param>
223-void LayoutAwarePage::InvalidateVisualState(ApplicationViewState viewState)
224-{
225- if (_layoutAwareControls != nullptr)
226- {
227- String^ visualState = DetermineVisualState(viewState);
228- auto controlIterator = _layoutAwareControls->First();
229- while (controlIterator->HasCurrent)
230- {
231- auto control = controlIterator->Current;
232- VisualStateManager::GoToState(control, visualState, false);
233- controlIterator->MoveNext();
234- }
235- }
189+ if (_layoutAwareControls != nullptr)
190+ {
191+ String^ visualState = DetermineVisualState(ApplicationView::Value);
192+ auto controlIterator = _layoutAwareControls->First();
193+ while (controlIterator->HasCurrent)
194+ {
195+ auto control = controlIterator->Current;
196+ VisualStateManager::GoToState(control, visualState, false);
197+ controlIterator->MoveNext();
198+ }
199+ }
236200 }
--- a/ShootingGame/Common/LayoutAwarePage.h
+++ b/ShootingGame/Common/LayoutAwarePage.h
@@ -1,3 +1,14 @@
1+//*********************************************************
2+//
3+// Copyright (c) Microsoft. All rights reserved.
4+// This code is licensed under the Microsoft Public License.
5+// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
6+// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
7+// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
8+// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
9+//
10+//*********************************************************
11+
112 #pragma once
213
314 #include "pch.h"
@@ -5,50 +16,48 @@
516
617 namespace ShootingGame
718 {
8- namespace Common
9- {
10- // Suppress class "not consumable from JavaScript because it's not marked 'sealed'" warning
11- // currently emitted despite the WebHostHidden attribute
12- #pragma warning(push)
13- #pragma warning(disable: 4449)
14- /// <summary>
15- /// Typical implementation of Page that provides several important conveniences: application
16- /// view state to visual state mapping, GoBack and GoHome event handlers, and a default view
17- /// model.
18- /// </summary>
19- [Windows::Foundation::Metadata::WebHostHidden]
20- public ref class LayoutAwarePage : Windows::UI::Xaml::Controls::Page
21- {
22- public:
23- LayoutAwarePage();
24- void StartLayoutUpdates(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
25- void StopLayoutUpdates(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
26- void InvalidateVisualState();
27- void InvalidateVisualState(Windows::UI::ViewManagement::ApplicationViewState viewState);
28- property bool UseFilledStateForNarrowWindow
29- {
30- bool get();
31- void set(bool value);
32- }
33- property Windows::Foundation::Collections::IObservableMap<Platform::String^, Object^>^ DefaultViewModel
34- {
35- Windows::Foundation::Collections::IObservableMap<Platform::String^, Object^>^ get();
36- }
19+ namespace Common
20+ {
21+ // Suppress class "not consumable from JavaScript because it's not marked 'sealed'" warning
22+ // currently emitted despite the WebHostHidden attribute
23+ #pragma warning(push)
24+ #pragma warning(disable: 4449)
25+ /// <summary>
26+ /// Typical implementation of Page that provides several important conveniences: application
27+ /// view state to visual state mapping, GoBack and GoHome event handlers, and a default view
28+ /// model.
29+ /// </summary>
30+ [Windows::Foundation::Metadata::WebHostHidden]
31+ public ref class LayoutAwarePage : Windows::UI::Xaml::Controls::Page
32+ {
33+ internal:
34+ LayoutAwarePage();
35+
36+ public:
37+ void StartLayoutUpdates(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
38+ void StopLayoutUpdates(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
39+ void InvalidateVisualState();
40+ static property Windows::UI::Xaml::DependencyProperty^ DefaultViewModelProperty
41+ {
42+ Windows::UI::Xaml::DependencyProperty^ get();
43+ };
44+ property Windows::Foundation::Collections::IObservableMap<Platform::String^, Object^>^ DefaultViewModel
45+ {
46+ Windows::Foundation::Collections::IObservableMap<Platform::String^, Object^>^ get();
47+ void set(Windows::Foundation::Collections::IObservableMap<Platform::String^, Object^>^ value);
48+ }
3749
38- protected:
39- virtual void GoHome(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
40- virtual void GoBack(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
41- virtual Platform::String^ DetermineVisualState(Windows::UI::ViewManagement::ApplicationViewState viewState);
50+ protected:
51+ virtual void GoHome(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
52+ virtual void GoBack(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
53+ virtual Platform::String^ DetermineVisualState(Windows::UI::ViewManagement::ApplicationViewState viewState);
4254
43- private:
44- bool _useFilledStateForNarrowWindow;
45- Platform::Collections::Map<Platform::String^, Object^>^ _defaultViewModel;
46- Windows::Foundation::EventRegistrationToken _viewStateEventToken;
47- Windows::Foundation::EventRegistrationToken _windowSizeEventToken;
48- Platform::Collections::Vector<Windows::UI::Xaml::Controls::Control^>^ _layoutAwareControls;
49- void ViewStateChanged(Windows::UI::ViewManagement::ApplicationView^ sender, Windows::UI::ViewManagement::ApplicationViewStateChangedEventArgs^ e);
50- void WindowSizeChanged(Object^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ e);
51- };
52- #pragma warning(pop)
53- }
55+ private:
56+ Platform::Collections::Map<Platform::String^, Object^>^ _defaultViewModel;
57+ Windows::Foundation::EventRegistrationToken _windowSizeEventToken;
58+ Platform::Collections::Vector<Windows::UI::Xaml::Controls::Control^>^ _layoutAwareControls;
59+ void WindowSizeChanged(Object^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ e);
60+ };
61+ #pragma warning(pop)
62+ }
5463 }
--- a/ShootingGame/Common/ReadMe.txt
+++ b/ShootingGame/Common/ReadMe.txt
@@ -1,7 +1,12 @@
11 The Common directory contains classes and XAML styles that simplify application development.
22
33 These are not merely convenient, but are required by most Visual Studio project and item templates.
4-Removing, renaming, or otherwise modifying the content of these files may result in a project that
5-does not build, or that will not build once additional pages are added. If variations on these
6-classes or styles are desired it is recommended that you copy the content under a new name and
7-modify your private copy.
4+If you need a variation on one of the styles in StandardStyles it is recommended that you make a
5+copy in your own resource dictionary. When right-clicking on a styled control in the design
6+surface the context menu includes an option to Edit a Copy to simplify this process.
7+
8+Classes in the Common directory form part of your project and may be further enhanced to meet your
9+needs. Care should be taken when altering existing methods and properties as incompatible changes
10+will require corresponding changes to code included in a variety of Visual Studio templates. For
11+example, additional pages added to your project are written assuming that the original methods and
12+properties in Common classes are still present and that the names of the types have not changed.
\ No newline at end of file
--- a/ShootingGame/Common/RichTextColumns.cpp
+++ b/ShootingGame/Common/RichTextColumns.cpp
@@ -10,47 +10,37 @@ using namespace Windows::UI::Xaml;
1010 using namespace Windows::UI::Xaml::Controls;
1111 using namespace Windows::UI::Xaml::Interop;
1212
13-static Windows::UI::Xaml::DependencyProperty^ _richTextContentProperty;
14-static Windows::UI::Xaml::DependencyProperty^ _columnTemplateProperty;
15-
1613 /// <summary>
1714 /// Initializes a new instance of the <see cref="RichTextColumns"/> class.
1815 /// </summary>
1916 RichTextColumns::RichTextColumns()
2017 {
21- HorizontalAlignment = ::HorizontalAlignment::Left;
18+ HorizontalAlignment = Windows::UI::Xaml::HorizontalAlignment::Left;
2219 }
2320
21+static DependencyProperty^ _columnTemplateProperty =
22+ DependencyProperty::Register("ColumnTemplate", TypeName(DataTemplate::typeid), TypeName(RichTextColumns::typeid),
23+ ref new PropertyMetadata(nullptr, ref new PropertyChangedCallback(
24+ &RichTextColumns::ResetOverflowLayout)));
25+
2426 /// <summary>
25-/// Gets the initial rich text content to be used as the first column.
27+/// Identifies the <see cref="ColumnTemplate"/> dependency property.
2628 /// </summary>
2729 DependencyProperty^ RichTextColumns::ColumnTemplateProperty::get()
2830 {
29- if (_columnTemplateProperty == nullptr)
30- {
31- TypeName thisType = { RichTextColumns::typeid->FullName, TypeKind::Custom };
32- TypeName dataTemplateType = { DataTemplate::typeid->FullName, TypeKind::Metadata };
33- _columnTemplateProperty = DependencyProperty::Register("ColumnTemplate",
34- dataTemplateType, thisType, ref new PropertyMetadata(nullptr,
35- ref new PropertyChangedCallback(&RichTextColumns::ResetOverflowLayout)));
36- }
3731 return _columnTemplateProperty;
3832 }
3933
34+static DependencyProperty^ _richTextContentProperty =
35+ DependencyProperty::Register("RichTextContent", TypeName(RichTextBlock::typeid), TypeName(RichTextColumns::typeid),
36+ ref new PropertyMetadata(nullptr, ref new PropertyChangedCallback(
37+ &RichTextColumns::ResetOverflowLayout)));
38+
4039 /// <summary>
41-/// Gets the template used to create additional
42-/// <see cref="RichTextBlockOverflow"/> instances.
40+/// Identifies the <see cref="RichTextContent"/> dependency property.
4341 /// </summary>
4442 DependencyProperty^ RichTextColumns::RichTextContentProperty::get()
4543 {
46- if (_richTextContentProperty == nullptr)
47- {
48- TypeName thisType = { RichTextColumns::typeid->FullName, TypeKind::Custom };
49- TypeName richTextBlockType = { RichTextBlock::typeid->FullName, TypeKind::Metadata };
50- _richTextContentProperty = DependencyProperty::Register("RichTextContent",
51- richTextBlockType, thisType, ref new PropertyMetadata(nullptr,
52- ref new PropertyChangedCallback(&RichTextColumns::ResetOverflowLayout)));
53- }
5444 return _richTextContentProperty;
5545 }
5646
@@ -62,6 +52,8 @@ DependencyProperty^ RichTextColumns::RichTextContentProperty::get()
6252 /// <param name="e">Event data describing the specific change.</param>
6353 void RichTextColumns::ResetOverflowLayout(DependencyObject^ d, DependencyPropertyChangedEventArgs^ e)
6454 {
55+ (void) e; // Unused parameter
56+
6557 auto target = dynamic_cast<RichTextColumns^>(d);
6658 if (target != nullptr)
6759 {
@@ -92,9 +84,7 @@ Size RichTextColumns::MeasureOverride(Size availableSize)
9284 // done yet
9385 if (_overflowColumns == nullptr)
9486 {
95- // Appending to the child collection currently returns S_FALSE on success,
96- // which results in an exception when called from C++
97- try { Children->Append(RichTextContent); } catch (COMException^ ex) { if (ex->HResult != 1) throw ex; }
87+ Children->Append(RichTextContent);
9888 _overflowColumns = ref new Vector<RichTextBlockOverflow^>();
9989 }
10090
@@ -119,9 +109,7 @@ Size RichTextColumns::MeasureOverride(Size availableSize)
119109 {
120110 overflow = safe_cast<RichTextBlockOverflow^>(ColumnTemplate->LoadContent());
121111 _overflowColumns->Append(overflow);
122- // Appending to the child collection currently returns S_FALSE on success,
123- // which results in an exception when called from C++
124- try { Children->Append(overflow); } catch (COMException^ ex) { if (ex->HResult != 1) throw ex; }
112+ Children->Append(overflow);
125113 if (overflowIndex == 0)
126114 {
127115 RichTextContent->OverflowContentTarget = overflow;
--- a/ShootingGame/Common/RichTextColumns.h
+++ b/ShootingGame/Common/RichTextColumns.h
@@ -1,6 +1,5 @@
11 #pragma once
22
3-#include "pch.h"
43 #include <collection.h>
54
65 namespace ShootingGame
@@ -61,9 +60,11 @@ namespace ShootingGame
6160 virtual Windows::Foundation::Size MeasureOverride(Windows::Foundation::Size availableSize) override;
6261 virtual Windows::Foundation::Size ArrangeOverride(Windows::Foundation::Size finalSize) override;
6362
63+ internal:
64+ static void ResetOverflowLayout(Windows::UI::Xaml::DependencyObject^ d, Windows::UI::Xaml::DependencyPropertyChangedEventArgs^ e);
65+
6466 private:
6567 Platform::Collections::Vector<Windows::UI::Xaml::Controls::RichTextBlockOverflow^>^ _overflowColumns;
66- static void ResetOverflowLayout(Windows::UI::Xaml::DependencyObject^ d, Windows::UI::Xaml::DependencyPropertyChangedEventArgs^ e);
6768 };
6869 }
6970 }
--- /dev/null
+++ b/ShootingGame/Common/SuspensionManager.cpp
@@ -0,0 +1,468 @@
1+//
2+// SuspensionManager.cpp
3+// Implementation of the SuspensionManager class
4+//
5+
6+#include "pch.h"
7+#include "SuspensionManager.h"
8+
9+#include <collection.h>
10+#include <algorithm>
11+
12+using namespace ShootingGame::Common;
13+
14+using namespace Concurrency;
15+using namespace Platform;
16+using namespace Platform::Collections;
17+using namespace Windows::Foundation;
18+using namespace Windows::Foundation::Collections;
19+using namespace Windows::Storage;
20+using namespace Windows::Storage::FileProperties;
21+using namespace Windows::Storage::Streams;
22+using namespace Windows::UI::Xaml;
23+using namespace Windows::UI::Xaml::Controls;
24+using namespace Windows::UI::Xaml::Interop;
25+
26+namespace
27+{
28+ Map<String^, Object^>^ _sessionState = ref new Map<String^, Object^>();
29+ String^ sessionStateFilename = "_sessionState.dat";
30+
31+ // Forward declarations for object object read / write support
32+ void WriteObject(Windows::Storage::Streams::DataWriter^ writer, Platform::Object^ object);
33+ Platform::Object^ ReadObject(Windows::Storage::Streams::DataReader^ reader);
34+}
35+
36+/// <summary>
37+/// Provides access to global session state for the current session. This state is serialized by
38+/// <see cref="SaveAsync"/> and restored by <see cref="RestoreAsync"/> which require values to be
39+/// one of the following: boxed values including integers, floating-point singles and doubles,
40+/// wide characters, boolean, Strings and Guids, or Map<String^, Object^> where map values are
41+/// subject to the same constraints. Session state should be as compact as possible.
42+/// </summary>
43+IMap<String^, Object^>^ SuspensionManager::SessionState::get(void)
44+{
45+ return _sessionState;
46+}
47+
48+/// <summary>
49+/// Wrap a WeakReference as a reference object for use in a collection.
50+/// </summary>
51+private ref class WeakFrame sealed
52+{
53+private:
54+ WeakReference _frameReference;
55+
56+internal:
57+ WeakFrame(Frame^ frame) { _frameReference = frame; }
58+ property Frame^ ResolvedFrame
59+ {
60+ Frame^ get(void) { return _frameReference.Resolve<Frame>(); }
61+ };
62+};
63+
64+namespace
65+{
66+ std::vector<WeakFrame^> _registeredFrames;
67+ DependencyProperty^ FrameSessionStateKeyProperty =
68+ DependencyProperty::RegisterAttached("_FrameSessionStateKeyProperty",
69+ TypeName(String::typeid), TypeName(SuspensionManager::typeid), nullptr);
70+ DependencyProperty^ FrameSessionStateProperty =
71+ DependencyProperty::RegisterAttached("_FrameSessionStateProperty",
72+ TypeName(IMap<String^, Object^>::typeid), TypeName(SuspensionManager::typeid), nullptr);
73+}
74+
75+/// <summary>
76+/// Registers a <see cref="Frame"/> instance to allow its navigation history to be saved to
77+/// and restored from <see cref="SessionState"/>. Frames should be registered once
78+/// immediately after creation if they will participate in session state management. Upon
79+/// registration if state has already been restored for the specified key
80+/// the navigation history will immediately be restored. Subsequent invocations of
81+/// <see cref="RestoreAsync(String)"/> will also restore navigation history.
82+/// </summary>
83+/// <param name="frame">An instance whose navigation history should be managed by
84+/// <see cref="SuspensionManager"/></param>
85+/// <param name="sessionStateKey">A unique key into <see cref="SessionState"/> used to
86+/// store navigation-related information.</param>
87+void SuspensionManager::RegisterFrame(Frame^ frame, String^ sessionStateKey)
88+{
89+ if (frame->GetValue(FrameSessionStateKeyProperty) != nullptr)
90+ {
91+ throw ref new FailureException("Frames can only be registered to one session state key");
92+ }
93+
94+ if (frame->GetValue(FrameSessionStateProperty) != nullptr)
95+ {
96+ throw ref new FailureException("Frames must be either be registered before accessing frame session state, or not registered at all");
97+ }
98+
99+ // Use a dependency property to associate the session key with a frame, and keep a list of frames whose
100+ // navigation state should be managed
101+ frame->SetValue(FrameSessionStateKeyProperty, sessionStateKey);
102+ _registeredFrames.insert(_registeredFrames.begin(), ref new WeakFrame(frame));
103+
104+ // Check to see if navigation state can be restored
105+ RestoreFrameNavigationState(frame);
106+}
107+
108+/// <summary>
109+/// Disassociates a <see cref="Frame"/> previously registered by <see cref="RegisterFrame"/>
110+/// from <see cref="SessionState"/>. Any navigation state previously captured will be
111+/// removed.
112+/// </summary>
113+/// <param name="frame">An instance whose navigation history should no longer be
114+/// managed.</param>
115+void SuspensionManager::UnregisterFrame(Frame^ frame)
116+{
117+ // Remove session state and remove the frame from the list of frames whose navigation
118+ // state will be saved (along with any weak references that are no longer reachable)
119+ auto key = safe_cast<String^>(frame->GetValue(FrameSessionStateKeyProperty));
120+ if (SessionState->HasKey(key)) SessionState->Remove(key);
121+ _registeredFrames.erase(
122+ std::remove_if(_registeredFrames.begin(), _registeredFrames.end(), [=](WeakFrame^& e)
123+ {
124+ auto testFrame = e->ResolvedFrame;
125+ return testFrame == nullptr || testFrame == frame;
126+ }),
127+ _registeredFrames.end()
128+ );
129+}
130+
131+/// <summary>
132+/// Provides storage for session state associated with the specified <see cref="Frame"/>.
133+/// Frames that have been previously registered with <see cref="RegisterFrame"/> have
134+/// their session state saved and restored automatically as a part of the global
135+/// <see cref="SessionState"/>. Frames that are not registered have transient state
136+/// that can still be useful when restoring pages that have been discarded from the
137+/// navigation cache.
138+/// </summary>
139+/// <remarks>Apps may choose to rely on <see cref="LayoutAwarePage"/> to manage
140+/// page-specific state instead of working with frame session state directly.</remarks>
141+/// <param name="frame">The instance for which session state is desired.</param>
142+/// <returns>A collection of state subject to the same serialization mechanism as
143+/// <see cref="SessionState"/>.</returns>
144+IMap<String^, Object^>^ SuspensionManager::SessionStateForFrame(Frame^ frame)
145+{
146+ auto frameState = safe_cast<IMap<String^, Object^>^>(frame->GetValue(FrameSessionStateProperty));
147+
148+ if (frameState == nullptr)
149+ {
150+ auto frameSessionKey = safe_cast<String^>(frame->GetValue(FrameSessionStateKeyProperty));
151+ if (frameSessionKey != nullptr)
152+ {
153+ // Registered frames reflect the corresponding session state
154+ if (!_sessionState->HasKey(frameSessionKey))
155+ {
156+ _sessionState->Insert(frameSessionKey, ref new Map<String^, Object^>());
157+ }
158+ frameState = safe_cast<IMap<String^, Object^>^>(_sessionState->Lookup(frameSessionKey));
159+ }
160+ else
161+ {
162+ // Frames that aren't registered have transient state
163+ frameState = ref new Map<String^, Object^>();
164+ }
165+ frame->SetValue(FrameSessionStateProperty, frameState);
166+ }
167+ return frameState;
168+}
169+
170+void SuspensionManager::RestoreFrameNavigationState(Frame^ frame)
171+{
172+ auto frameState = SessionStateForFrame(frame);
173+ if (frameState->HasKey("Navigation"))
174+ {
175+ frame->SetNavigationState(safe_cast<String^>(frameState->Lookup("Navigation")));
176+ }
177+}
178+
179+void SuspensionManager::SaveFrameNavigationState(Frame^ frame)
180+{
181+ auto frameState = SessionStateForFrame(frame);
182+ frameState->Insert("Navigation", frame->GetNavigationState());
183+}
184+
185+/// <summary>
186+/// Save the current <see cref="SessionState"/>. Any <see cref="Frame"/> instances
187+/// registered with <see cref="RegisterFrame"/> will also preserve their current
188+/// navigation stack, which in turn gives their active <see cref="Page"/> an opportunity
189+/// to save its state.
190+/// </summary>
191+/// <returns>An asynchronous task that reflects when session state has been saved.</returns>
192+task<void> SuspensionManager::SaveAsync(void)
193+{
194+ // Save the navigation state for all registered frames
195+ for (auto&& weakFrame : _registeredFrames)
196+ {
197+ auto frame = weakFrame->ResolvedFrame;
198+ if (frame != nullptr) SaveFrameNavigationState(frame);
199+ }
200+
201+ // Serialize the session state synchronously to avoid asynchronous access to shared
202+ // state
203+ auto sessionData = ref new InMemoryRandomAccessStream();
204+ auto sessionDataWriter = ref new DataWriter(sessionData->GetOutputStreamAt(0));
205+ WriteObject(sessionDataWriter, _sessionState);
206+
207+ // Once session state has been captured synchronously, begin the asynchronous process
208+ // of writing the result to disk
209+ return task<unsigned int>(sessionDataWriter->StoreAsync()).then([=](unsigned int)
210+ {
211+ return sessionDataWriter->FlushAsync();
212+ }).then([=](bool flushSucceeded)
213+ {
214+ return ApplicationData::Current->LocalFolder->CreateFileAsync(sessionStateFilename,
215+ CreationCollisionOption::ReplaceExisting);
216+ }).then([=](StorageFile^ createdFile)
217+ {
218+ return createdFile->OpenAsync(FileAccessMode::ReadWrite);
219+ }).then([=](IRandomAccessStream^ newStream)
220+ {
221+ return RandomAccessStream::CopyAndCloseAsync(
222+ sessionData->GetInputStreamAt(0), newStream->GetOutputStreamAt(0));
223+ }).then([=](UINT64 copiedBytes)
224+ {
225+ return;
226+ });
227+}
228+
229+/// <summary>
230+/// Restores previously saved <see cref="SessionState"/>. Any <see cref="Frame"/> instances
231+/// registered with <see cref="RegisterFrame"/> will also restore their prior navigation
232+/// state, which in turn gives their active <see cref="Page"/> an opportunity restore its
233+/// state.
234+/// </summary>
235+/// <param name="version">A version identifer compared to the session state to prevent
236+/// incompatible versions of session state from reaching app code. Saved state with a
237+/// different version will be ignored, resulting in an empty <see cref="SessionState"/>
238+/// dictionary.</param>
239+/// <returns>An asynchronous task that reflects when session state has been read. The
240+/// content of <see cref="SessionState"/> should not be relied upon until this task
241+/// completes.</returns>
242+task<void> SuspensionManager::RestoreAsync(void)
243+{
244+ _sessionState->Clear();
245+
246+ task<StorageFile^> getFileTask(ApplicationData::Current->LocalFolder->GetFileAsync(sessionStateFilename));
247+ return getFileTask.then([=](StorageFile^ stateFile)
248+ {
249+ task<BasicProperties^> getBasicPropertiesTask(stateFile->GetBasicPropertiesAsync());
250+ return getBasicPropertiesTask.then([=](BasicProperties^ stateFileProperties)
251+ {
252+ auto size = unsigned int(stateFileProperties->Size);
253+ if (size != stateFileProperties->Size) throw ref new FailureException("Session state larger than 4GB");
254+ task<IRandomAccessStreamWithContentType^> openReadTask(stateFile->OpenReadAsync());
255+ return openReadTask.then([=](IRandomAccessStreamWithContentType^ stateFileStream)
256+ {
257+ auto stateReader = ref new DataReader(stateFileStream);
258+ return task<unsigned int>(stateReader->LoadAsync(size)).then([=](unsigned int bytesRead)
259+ {
260+ // Deserialize the Session State
261+ Object^ content = ReadObject(stateReader);
262+ _sessionState = (Map<String^, Object^>^)content;
263+
264+ // Restore any registered frames to their saved state
265+ for (auto&& weakFrame : _registeredFrames)
266+ {
267+ auto frame = weakFrame->ResolvedFrame;
268+ if (frame != nullptr)
269+ {
270+ frame->ClearValue(FrameSessionStateProperty);
271+ RestoreFrameNavigationState(frame);
272+ }
273+ }
274+ }, task_continuation_context::use_current());
275+ });
276+ });
277+ });
278+}
279+
280+#pragma region Object serialization for a known set of types
281+
282+namespace
283+{
284+ // Codes used for identifying serialized types
285+ enum StreamTypes {
286+ NullPtrType = 0,
287+
288+ // Supported IPropertyValue types
289+ UInt8Type, UInt16Type, UInt32Type, UInt64Type, Int16Type, Int32Type, Int64Type,
290+ SingleType, DoubleType, BooleanType, Char16Type, GuidType, StringType,
291+
292+ // Additional supported types
293+ StringToObjectMapType,
294+
295+ // Marker values used to ensure stream integrity
296+ MapEndMarker
297+ };
298+
299+ void WriteString(DataWriter^ writer, String^ string)
300+ {
301+ writer->WriteByte(StringType);
302+ writer->WriteUInt32(writer->MeasureString(string));
303+ writer->WriteString(string);
304+ }
305+
306+ void WriteProperty(DataWriter^ writer, IPropertyValue^ propertyValue)
307+ {
308+ switch (propertyValue->Type)
309+ {
310+ case PropertyType::UInt8:
311+ writer->WriteByte(UInt8Type);
312+ writer->WriteByte(propertyValue->GetUInt8());
313+ return;
314+ case PropertyType::UInt16:
315+ writer->WriteByte(UInt16Type);
316+ writer->WriteUInt16(propertyValue->GetUInt16());
317+ return;
318+ case PropertyType::UInt32:
319+ writer->WriteByte(UInt32Type);
320+ writer->WriteUInt32(propertyValue->GetUInt32());
321+ return;
322+ case PropertyType::UInt64:
323+ writer->WriteByte(UInt64Type);
324+ writer->WriteUInt64(propertyValue->GetUInt64());
325+ return;
326+ case PropertyType::Int16:
327+ writer->WriteByte(Int16Type);
328+ writer->WriteUInt16(propertyValue->GetInt16());
329+ return;
330+ case PropertyType::Int32:
331+ writer->WriteByte(Int32Type);
332+ writer->WriteUInt32(propertyValue->GetInt32());
333+ return;
334+ case PropertyType::Int64:
335+ writer->WriteByte(Int64Type);
336+ writer->WriteUInt64(propertyValue->GetInt64());
337+ return;
338+ case PropertyType::Single:
339+ writer->WriteByte(SingleType);
340+ writer->WriteSingle(propertyValue->GetSingle());
341+ return;
342+ case PropertyType::Double:
343+ writer->WriteByte(DoubleType);
344+ writer->WriteDouble(propertyValue->GetDouble());
345+ return;
346+ case PropertyType::Boolean:
347+ writer->WriteByte(BooleanType);
348+ writer->WriteBoolean(propertyValue->GetBoolean());
349+ return;
350+ case PropertyType::Char16:
351+ writer->WriteByte(Char16Type);
352+ writer->WriteUInt16(propertyValue->GetChar16());
353+ return;
354+ case PropertyType::Guid:
355+ writer->WriteByte(GuidType);
356+ writer->WriteGuid(propertyValue->GetGuid());
357+ return;
358+ case PropertyType::String:
359+ WriteString(writer, propertyValue->GetString());
360+ return;
361+ default:
362+ throw ref new InvalidArgumentException("Unsupported property type");
363+ }
364+ }
365+
366+ void WriteStringToObjectMap(DataWriter^ writer, IMap<String^, Object^>^ map)
367+ {
368+ writer->WriteByte(StringToObjectMapType);
369+ writer->WriteUInt32(map->Size);
370+ for (auto&& pair : map)
371+ {
372+ WriteObject(writer, pair->Key);
373+ WriteObject(writer, pair->Value);
374+ }
375+ writer->WriteByte(MapEndMarker);
376+ }
377+
378+ void WriteObject(DataWriter^ writer, Object^ object)
379+ {
380+ if (object == nullptr)
381+ {
382+ writer->WriteByte(NullPtrType);
383+ return;
384+ }
385+
386+ auto propertyObject = dynamic_cast<IPropertyValue^>(object);
387+ if (propertyObject != nullptr)
388+ {
389+ WriteProperty(writer, propertyObject);
390+ return;
391+ }
392+
393+ auto mapObject = dynamic_cast<IMap<String^, Object^>^>(object);
394+ if (mapObject != nullptr)
395+ {
396+ WriteStringToObjectMap(writer, mapObject);
397+ return;
398+ }
399+
400+ throw ref new InvalidArgumentException("Unsupported data type");
401+ }
402+
403+ String^ ReadString(DataReader^ reader)
404+ {
405+ int length = reader->ReadUInt32();
406+ String^ string = reader->ReadString(length);
407+ return string;
408+ }
409+
410+ IMap<String^, Object^>^ ReadStringToObjectMap(DataReader^ reader)
411+ {
412+ auto map = ref new Map<String^, Object^>();
413+ auto size = reader->ReadUInt32();
414+ for (unsigned int index = 0; index < size; index++)
415+ {
416+ auto key = safe_cast<String^>(ReadObject(reader));
417+ auto value = ReadObject(reader);
418+ map->Insert(key, value);
419+ }
420+ if (reader->ReadByte() != MapEndMarker)
421+ {
422+ throw ref new InvalidArgumentException("Invalid stream");
423+ }
424+ return map;
425+ }
426+
427+ Object^ ReadObject(DataReader^ reader)
428+ {
429+ auto type = reader->ReadByte();
430+ switch (type)
431+ {
432+ case NullPtrType:
433+ return nullptr;
434+ case UInt8Type:
435+ return reader->ReadByte();
436+ case UInt16Type:
437+ return reader->ReadUInt16();
438+ case UInt32Type:
439+ return reader->ReadUInt32();
440+ case UInt64Type:
441+ return reader->ReadUInt64();
442+ case Int16Type:
443+ return reader->ReadInt16();
444+ case Int32Type:
445+ return reader->ReadInt32();
446+ case Int64Type:
447+ return reader->ReadInt64();
448+ case SingleType:
449+ return reader->ReadSingle();
450+ case DoubleType:
451+ return reader->ReadDouble();
452+ case BooleanType:
453+ return reader->ReadBoolean();
454+ case Char16Type:
455+ return (char16_t)reader->ReadUInt16();
456+ case GuidType:
457+ return reader->ReadGuid();
458+ case StringType:
459+ return ReadString(reader);
460+ case StringToObjectMapType:
461+ return ReadStringToObjectMap(reader);
462+ default:
463+ throw ref new InvalidArgumentException("Unsupported property type");
464+ }
465+ }
466+}
467+
468+#pragma endregion
--- /dev/null
+++ b/ShootingGame/Common/SuspensionManager.h
@@ -0,0 +1,40 @@
1+//
2+// SuspensionManager.h
3+// Declaration of the SuspensionManager class
4+//
5+
6+#pragma once
7+
8+#include <ppltasks.h>
9+
10+namespace ShootingGame
11+{
12+ namespace Common
13+ {
14+ /// <summary>
15+ /// SuspensionManager captures global session state to simplify process lifetime management
16+ /// for an application. Note that session state will be automatically cleared under a variety
17+ /// of conditions and should only be used to store information that would be convenient to
18+ /// carry across sessions, but that should be disacarded when an application crashes or is
19+ /// upgraded.
20+ /// </summary>
21+ ref class SuspensionManager sealed
22+ {
23+ internal:
24+ static void RegisterFrame(Windows::UI::Xaml::Controls::Frame^ frame, Platform::String^ sessionStateKey);
25+ static void UnregisterFrame(Windows::UI::Xaml::Controls::Frame^ frame);
26+ static Concurrency::task<void> SaveAsync(void);
27+ static Concurrency::task<void> RestoreAsync(void);
28+ static property Windows::Foundation::Collections::IMap<Platform::String^, Platform::Object^>^ SessionState
29+ {
30+ Windows::Foundation::Collections::IMap<Platform::String^, Platform::Object^>^ get(void);
31+ };
32+ static Windows::Foundation::Collections::IMap<Platform::String^, Platform::Object^>^ SessionStateForFrame(
33+ Windows::UI::Xaml::Controls::Frame^ frame);
34+
35+ private:
36+ static void RestoreFrameNavigationState(Windows::UI::Xaml::Controls::Frame^ frame);
37+ static void SaveFrameNavigationState(Windows::UI::Xaml::Controls::Frame^ frame);
38+ };
39+ }
40+}
--- /dev/null
+++ b/ShootingGame/EnvelopeEditorControl.xaml
@@ -0,0 +1,24 @@
1+<UserControl
2+ x:Class="ShootingGame.EnvelopeEditorControl"
3+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
4+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
5+ xmlns:local="using:ShootingGame"
6+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
7+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
8+ mc:Ignorable="d" Height="212.667" Width="453.667">
9+
10+ <Grid>
11+ <Slider HorizontalAlignment="Left" Margin="13.333,13,0,0" VerticalAlignment="Top" Width="310" Height="43" UseLayoutRounding="True" ScrollViewer.VerticalScrollBarVisibility="Auto"/>
12+ <Slider HorizontalAlignment="Left" Margin="13.333,61,0,0" VerticalAlignment="Top" Width="310" Height="44"/>
13+ <Slider HorizontalAlignment="Left" Margin="13.333,110,0,0" VerticalAlignment="Top" Width="310" Height="43"/>
14+ <Slider HorizontalAlignment="Left" Margin="13.333,158,0,0" VerticalAlignment="Top" Width="310" Height="45.333"/>
15+ <TextBlock HorizontalAlignment="Left" Margin="13.333,13,0,0" TextWrapping="Wrap" Text="Attack" VerticalAlignment="Top" Width="65" FontSize="13.333" Height="15" LineHeight="13.333"/>
16+ <TextBlock HorizontalAlignment="Left" Margin="13.333,61,0,0" TextWrapping="Wrap" Text="Decay" VerticalAlignment="Top" Width="65" FontSize="13.333" Height="16"/>
17+ <TextBlock HorizontalAlignment="Left" Margin="13.333,110,0,0" TextWrapping="Wrap" Text="Suatain" VerticalAlignment="Top" Width="65" FontSize="13.333" Height="15"/>
18+ <TextBlock HorizontalAlignment="Left" Margin="13.333,158,0,0" TextWrapping="Wrap" Text="Release" VerticalAlignment="Top" Width="65" FontSize="13.333" Height="16"/>
19+ <TextBox HorizontalAlignment="Left" Height="43" Margin="328.333,13,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="114" FontSize="13.333"/>
20+ <TextBox HorizontalAlignment="Left" Height="44" Margin="328.333,61,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="114" FontSize="13.333"/>
21+ <TextBox HorizontalAlignment="Left" Height="43" Margin="328.333,110,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="114" FontSize="13.333"/>
22+ <TextBox HorizontalAlignment="Left" Height="45" Margin="328.333,158,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="114" FontSize="13.333"/>
23+ </Grid>
24+</UserControl>
--- /dev/null
+++ b/ShootingGame/EnvelopeEditorControl.xaml.cpp
@@ -0,0 +1,27 @@
1+//
2+//EnvelopeEditorControl.xaml.cpp
3+//EnvelopeEditorControl クラスの実装
4+//
5+
6+#include "pch.h"
7+#include "EnvelopeEditorControl.xaml.h"
8+
9+using namespace ShootingGame;
10+
11+using namespace Platform;
12+using namespace Windows::Foundation;
13+using namespace Windows::Foundation::Collections;
14+using namespace Windows::UI::Xaml;
15+using namespace Windows::UI::Xaml::Controls;
16+using namespace Windows::UI::Xaml::Controls::Primitives;
17+using namespace Windows::UI::Xaml::Data;
18+using namespace Windows::UI::Xaml::Input;
19+using namespace Windows::UI::Xaml::Media;
20+using namespace Windows::UI::Xaml::Navigation;
21+
22+// ユーザー コントロールのアイテム テンプレートについては、http://go.microsoft.com/fwlink/?LinkId=234236 を参照してください
23+
24+EnvelopeEditorControl::EnvelopeEditorControl()
25+{
26+ InitializeComponent();
27+}
--- /dev/null
+++ b/ShootingGame/EnvelopeEditorControl.xaml.h
@@ -0,0 +1,17 @@
1+//
2+//EnvelopeEditorControl.xaml.h
3+//EnvelopeEditorControl クラスの宣言
4+//
5+
6+#pragma once
7+
8+#include "EnvelopeEditorControl.g.h"
9+
10+namespace ShootingGame
11+{
12+ public ref class EnvelopeEditorControl sealed
13+ {
14+ public:
15+ EnvelopeEditorControl();
16+ };
17+}
--- a/ShootingGame/GameMain.cpp
+++ b/ShootingGame/GameMain.cpp
@@ -8,8 +8,8 @@
88 #include "pch.h"
99 #include "SoundDriver.h"
1010 #include "GameMain.h"
11-#include "BasicLoader.h"
1211 #include "windows.ui.xaml.media.dxinterop.h"
12+#include "GameStateMachine.h"
1313
1414 using namespace Microsoft::WRL;
1515 using namespace Windows::Foundation;
@@ -27,100 +27,86 @@ using namespace concurrency;
2727
2828
2929 using namespace BasicSprites;
30-
30+using namespace boost;
31+namespace ShootingGame {
3132 const float GameMain::BACKBUFFER_WIDTH = 320.0f;
3233 const float GameMain::BACKBUFFER_HEIGHT = 240.0f;
3334
3435
35-GameMain::GameMain() : backBufferViewPort_(0.0f,0.0f,BACKBUFFER_WIDTH,BACKBUFFER_HEIGHT) , isDestroy_(false)
36+GameMain::GameMain() : backBufferViewPort_(0.0f,0.0f,BACKBUFFER_WIDTH,BACKBUFFER_HEIGHT) , isDestroy_(true),state_(this)
3637 {
38+// GameStateMachine machine;
3739 soundDriver_.reset(new sf::SoundDriver());
38- soundManager_.reset(new sf::SoundManager(*soundDriver_.get()));
39- // サウンド再生スレッドの開始
40- soundTask_ = task<void>(create_async([this]()
41- {
42- ExecuteSoundThread();
43- })
44- );
45- //soundThread_ = std::thread(
46- // [this]() -> void
47- // {
48- // ExecuteSoundThread();
49- // }
50- //);
40+ soundManager_.reset(new sf::SoundManager(*soundDriver_.get()));
41+
42+
43+ //soundThread_ = std::thread(
44+ // [this]() -> void
45+ // {
46+ // ExecuteSoundThread();
47+ // }
48+ //);
5149 }
5250
5351 GameMain::~GameMain()
5452 {
55- // サウンド再生スレッドの停止
56- isDestroy_ = true;
57- soundTask_.wait();
58-
59- //if(soundThread_.joinable())
60- //{
61- // soundThread_.join();
62- //}
53+ StopSound();
54+
55+ //if(soundThread_.joinable())
56+ //{
57+ // soundThread_.join();
58+ //}
6359 };
6460
6561 void GameMain::CreateDeviceIndependentResources()
6662 {
67- DirectXBase::CreateDeviceIndependentResources();
63+ DirectXBase::CreateDeviceIndependentResources();
6864
69- // Create the performance throttler.
65+ // Create the performance throttler.
7066
71- autoThrottle_ = ref new AutoThrottle(1.0f / 60.0f);
67+ autoThrottle_ = ref new ::AutoThrottle(1.0f / 60.0f);
7268 }
7369
7470 void GameMain::Initialize(
75- _In_ Windows::UI::Core::CoreWindow^ window,
76- _In_ Windows::UI::Xaml::Controls::SwapChainBackgroundPanel^ swapChainPanel,
77- _In_ float dpi
78- )
71+ _In_ Windows::UI::Core::CoreWindow^ window,
72+ _In_ Windows::UI::Xaml::Controls::SwapChainBackgroundPanel^ swapChainPanel,
73+ _In_ float dpi
74+ )
7975 {
80- panel_ = swapChainPanel;
81- Initialize(window,dpi);
76+ panel_ = swapChainPanel;
77+ Initialize(window,dpi);
78+ state_.Start();
79+ state_.ProcessEvent(Event::Init());
8280 }
8381
8482 void GameMain::CreateDeviceResources()
8583 {
86- DirectXBase::CreateDeviceResources();
87-
88- // Create the sprite batch.
84+ DirectXBase::CreateDeviceResources();
8985
90- spriteBatch_ = ref new SpriteBatch();
91- unsigned int capacity = 1024;
92- if (m_featureLevel < D3D_FEATURE_LEVEL_9_3)
93- {
94- capacity = min(Parameters::MaximumCapacityCompatible, capacity);
95- }
96- spriteBatch_->Initialize(
97- m_d3dDevice.Get(),
98- capacity
99- );
100-
101- // Load the sprite textures.
86+ // Create the sprite batch.
10287
103- BasicLoader^ loader = ref new BasicLoader(m_d3dDevice.Get(), m_wicFactory.Get());
104-
105- loader->LoadTexture(
106- "explosion.png",
107- &test_,
108- nullptr
109- );
88+ spriteBatch_ = ref new BasicSprites::SpriteBatch();
89+ unsigned int capacity = 1024;
90+ if (m_featureLevel < D3D_FEATURE_LEVEL_9_3)
91+ {
92+ capacity = min(Parameters::MaximumCapacityCompatible, capacity);
93+ }
94+ spriteBatch_->Initialize(
95+ m_d3dDevice.Get(),
96+ capacity
97+ );
11098
111- spriteBatch_->AddTexture(test_.Get(),float2(64.0,64.0));
99+ // Create the Sample Overlay.
112100
113- // Create the Sample Overlay.
114-
115- sampleOverlay_ = ref new SampleOverlay();
101+ sampleOverlay_ = ref new ::SampleOverlay();
116102
117- sampleOverlay_->Initialize(
118- m_d2dDevice.Get(),
119- m_d2dContext.Get(),
120- m_wicFactory.Get(),
121- m_dwriteFactory.Get(),
122- L"シューティングゲーム"
123- );
103+ sampleOverlay_->Initialize(
104+ m_d2dDevice.Get(),
105+ m_d2dContext.Get(),
106+ m_wicFactory.Get(),
107+ m_dwriteFactory.Get(),
108+ L"シューティングゲーム"
109+ );
124110
125111
126112
@@ -128,676 +114,533 @@ void GameMain::CreateDeviceResources()
128114
129115 void GameMain::CreateWindowSizeDependentResources()
130116 {
131-// DirectXBase::CreateWindowSizeDependentResources();
132- // Store the window bounds so the next time we get a SizeChanged event we can
133- // avoid rebuilding everything if the size is identical.
134- m_windowBounds = m_window->Bounds;
117+ // DirectXBase::CreateWindowSizeDependentResources();
118+ // Store the window bounds so the next time we get a SizeChanged event we can
119+ // avoid rebuilding everything if the size is identical.
120+ m_windowBounds = m_window->Bounds;
135121
136- // If the swap chain already exists, resize it.
137- if(m_swapChain != nullptr)
138- {
139- DX::ThrowIfFailed(
140- m_swapChain->ResizeBuffers(2, 0, 0, DXGI_FORMAT_B8G8R8A8_UNORM, 0)
141- );
142- }
143- // Otherwise, create a new one.
144- else
145- {
146- // Allocate a descriptor.
147- DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0};
148- scale_ = floorf(m_window->Bounds.Width * m_dpi / ( 96.0f * BACKBUFFER_WIDTH));
149- swapChainDesc.Width = static_cast<UINT>(m_window->Bounds.Width * m_dpi / 96.0f); // Can not use 0 to get the default on Composition SwapChain
150- swapChainDesc.Height = static_cast<UINT>(m_window->Bounds.Height * m_dpi / 96.0f);
151- swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; // this is the most common swapchain format
152- swapChainDesc.Stereo = false;
153- swapChainDesc.SampleDesc.Count = 1; // don't use multi-sampling
154- swapChainDesc.SampleDesc.Quality = 0;
155- swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
156- swapChainDesc.BufferCount = 2; // use double buffering to enable flip
157- swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
158- swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // all Metro style apps must use this SwapEffect
159- swapChainDesc.Flags = 0;
160-
161- // Once the desired swap chain description is configured, it must be created on the same adapter as our D3D Device
162-
163- // First, retrieve the underlying DXGI Device from the D3D Device.
164- ComPtr<IDXGIDevice1> dxgiDevice;
165- DX::ThrowIfFailed(
166- m_d3dDevice.As(&dxgiDevice)
167- );
168-
169- // Identify the physical adapter (GPU or card) this device is running on.
170- ComPtr<IDXGIAdapter> dxgiAdapter;
171- DX::ThrowIfFailed(
172- dxgiDevice->GetAdapter(&dxgiAdapter)
173- );
174-
175- // And obtain the factory object that created it.
176- ComPtr<IDXGIFactory2> dxgiFactory;
177- DX::ThrowIfFailed(
178- dxgiAdapter->GetParent(IID_PPV_ARGS(&dxgiFactory))
179- );
180-
181- // Obtain the final swap chain for this window from the DXGI factory.
182- DX::ThrowIfFailed(
183- dxgiFactory->CreateSwapChainForComposition(
184- m_d3dDevice.Get(),
185- &swapChainDesc,
186- nullptr, // allow on all displays
187- &m_swapChain
188- )
189- );
190-
191- ComPtr<ISwapChainBackgroundPanelNative> dxRootPanelAsNative;
192-
193- // set the swap chain on the SwapChainBackgroundPanel
194- reinterpret_cast<IUnknown*>(panel_)->QueryInterface(__uuidof(ISwapChainBackgroundPanelNative), (void**)&dxRootPanelAsNative);
195-
196- DX::ThrowIfFailed(
197- dxRootPanelAsNative->SetSwapChain(m_swapChain.Get())
198- );
199-
200- // Ensure that DXGI does not queue more than one frame at a time. This both reduces
201- // latency and ensures that the application will only render after each VSync, minimizing
202- // power consumption.
203- DX::ThrowIfFailed(
204- dxgiDevice->SetMaximumFrameLatency(1)
205- );
206-
207- }
208-
209- // Obtain the backbuffer for this window which will be the final 3D rendertarget.
210- ComPtr<ID3D11Texture2D> backBuffer;
122+ // If the swap chain already exists, resize it.
123+ if(m_swapChain != nullptr)
124+ {
211125 DX::ThrowIfFailed(
212- m_swapChain->GetBuffer(0, IID_PPV_ARGS(&backBuffer))
213- );
126+ m_swapChain->ResizeBuffers(2, 0, 0, DXGI_FORMAT_B8G8R8A8_UNORM, 0)
127+ );
128+ }
129+ // Otherwise, create a new one.
130+ else
131+ {
132+ // Allocate a descriptor.
133+ DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0};
134+ scale_ = floorf(m_window->Bounds.Width * m_dpi / ( 96.0f * BACKBUFFER_WIDTH));
135+ swapChainDesc.Width = static_cast<UINT>(m_window->Bounds.Width * m_dpi / 96.0f); // Can not use 0 to get the default on Composition SwapChain
136+ swapChainDesc.Height = static_cast<UINT>(m_window->Bounds.Height * m_dpi / 96.0f);
137+ swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; // this is the most common swapchain format
138+ swapChainDesc.Stereo = false;
139+ swapChainDesc.SampleDesc.Count = 1; // don't use multi-sampling
140+ swapChainDesc.SampleDesc.Quality = 0;
141+ swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
142+ swapChainDesc.BufferCount = 2; // use double buffering to enable flip
143+ swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
144+ swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // all Metro style apps must use this SwapEffect
145+ swapChainDesc.Flags = 0;
146+
147+ // Once the desired swap chain description is configured, it must be created on the same adapter as our D3D Device
148+
149+ // First, retrieve the underlying DXGI Device from the D3D Device.
150+ ComPtr<IDXGIDevice1> dxgiDevice;
151+ DX::ThrowIfFailed(
152+ m_d3dDevice.As(&dxgiDevice)
153+ );
214154
215- // Create a view interface on the rendertarget to use on bind.
155+ // Identify the physical adapter (GPU or card) this device is running on.
156+ ComPtr<IDXGIAdapter> dxgiAdapter;
216157 DX::ThrowIfFailed(
217- m_d3dDevice->CreateRenderTargetView(
218- backBuffer.Get(),
219- nullptr,
220- &m_renderTargetView
221- )
222- );
223-
224- // Cache the rendertarget dimensions in our helper class for convenient use.
225- D3D11_TEXTURE2D_DESC backBufferDesc = {0};
226- backBuffer->GetDesc(&backBufferDesc);
227- m_renderTargetSize.Width = static_cast<float>(backBufferDesc.Width);
228- m_renderTargetSize.Height = static_cast<float>(backBufferDesc.Height);
229-
230- // Create a descriptor for the depth/stencil buffer.
231- CD3D11_TEXTURE2D_DESC depthStencilDesc(
232- DXGI_FORMAT_D24_UNORM_S8_UINT,
233- backBufferDesc.Width,
234- backBufferDesc.Height,
235- 1,
236- 1,
237- D3D11_BIND_DEPTH_STENCIL
238- );
239-
240- // Allocate a 2-D surface as the depth/stencil buffer.
241- ComPtr<ID3D11Texture2D> depthStencil;
158+ dxgiDevice->GetAdapter(&dxgiAdapter)
159+ );
160+
161+ // And obtain the factory object that created it.
162+ ComPtr<IDXGIFactory2> dxgiFactory;
242163 DX::ThrowIfFailed(
243- m_d3dDevice->CreateTexture2D(
244- &depthStencilDesc,
245- nullptr,
246- &depthStencil
247- )
248- );
249-
250- // Create a DepthStencil view on this surface to use on bind.
164+ dxgiAdapter->GetParent(IID_PPV_ARGS(&dxgiFactory))
165+ );
166+
167+ // Obtain the final swap chain for this window from the DXGI factory.
251168 DX::ThrowIfFailed(
252- m_d3dDevice->CreateDepthStencilView(
253- depthStencil.Get(),
254- &CD3D11_DEPTH_STENCIL_VIEW_DESC(D3D11_DSV_DIMENSION_TEXTURE2D),
255- &m_depthStencilView
256- )
257- );
258-
259- // Create a viewport descriptor of the full window size.
260- swapChainViewPort_.Width = static_cast<float>(backBufferDesc.Width);
261- swapChainViewPort_.Height = static_cast<float>(backBufferDesc.Height);
262-
263- // Set the current viewport using the descriptor.
264- m_d3dContext->RSSetViewports(1, &swapChainViewPort_);
265-
266- // Now we set up the Direct2D render target bitmap linked to the swapchain.
267- // Whenever we render to this bitmap, it will be directly rendered to the
268- // swapchain associated with the window.
269- D2D1_BITMAP_PROPERTIES1 bitmapProperties =
270- BitmapProperties1(
271- D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW,
272- PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED),
273- m_dpi,
274- m_dpi
275- );
276-
277- // Direct2D needs the dxgi version of the backbuffer surface pointer.
278- ComPtr<IDXGISurface> dxgiBackBuffer;
169+ dxgiFactory->CreateSwapChainForComposition(
170+ m_d3dDevice.Get(),
171+ &swapChainDesc,
172+ nullptr, // allow on all displays
173+ &m_swapChain
174+ )
175+ );
176+
177+ ComPtr<ISwapChainBackgroundPanelNative> dxRootPanelAsNative;
178+
179+ // set the swap chain on the SwapChainBackgroundPanel
180+ reinterpret_cast<IUnknown*>(panel_)->QueryInterface(__uuidof(ISwapChainBackgroundPanelNative), (void**)&dxRootPanelAsNative);
181+
279182 DX::ThrowIfFailed(
280- m_swapChain->GetBuffer(0, IID_PPV_ARGS(&dxgiBackBuffer))
281- );
183+ dxRootPanelAsNative->SetSwapChain(m_swapChain.Get())
184+ );
282185
283- // Get a D2D surface from the DXGI back buffer to use as the D2D render target.
186+ // Ensure that DXGI does not queue more than one frame at a time. This both reduces
187+ // latency and ensures that the application will only render after each VSync, minimizing
188+ // power consumption.
284189 DX::ThrowIfFailed(
285- m_d2dContext->CreateBitmapFromDxgiSurface(
286- dxgiBackBuffer.Get(),
287- &bitmapProperties,
288- &m_d2dTargetBitmap
289- )
290- );
291-
292- // So now we can set the Direct2D render target.
293- m_d2dContext->SetTarget(m_d2dTargetBitmap.Get());
294-
295- // Set D2D text anti-alias mode to Grayscale to ensure proper rendering of text on intermediate surfaces.
296- m_d2dContext->SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE);
297-
298- // Randomly generate some non-interactive asteroids to fit the screen.
299-
300- sampleOverlay_->UpdateForWindowSizeChange();
301- // バックバッファの作成
302- //ComPtr<ID3D11Texture2D> backBuffer;
303- //DX::ThrowIfFailed(
304- // m_swapChain->GetBuffer(0, IID_PPV_ARGS(&backBuffer))
305- // );
306- //D3D11_TEXTURE2D_DESC backBufferDesc = {0};
307- //backBuffer->GetDesc(&backBufferDesc);
308-
309- D3D11_TEXTURE2D_DESC desc = {0};
310- desc.Width = 320;
311- desc.Height = 240;
312- desc.Format = backBufferDesc.Format;
313- desc.MipLevels = 1;
314- desc.SampleDesc.Count = 1;
315- desc.SampleDesc.Quality = 0;
316- desc.ArraySize = 1;
317- desc.Usage = D3D11_USAGE_DEFAULT;
318- desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
319-// desc.MiscFlags = D3D11_RESOURCE_MISC_GDI_COMPATIBLE;
320-
321- DX::ThrowIfFailed(m_d3dDevice->CreateTexture2D(&desc,NULL,&backBuffer_));
322-
323- DX::ThrowIfFailed(m_d3dDevice->CreateRenderTargetView(backBuffer_.Get(),0,&backBufferRenderTargetView_));
324-
325- // // 深度バッファの作成
326- // D3D11_TEXTURE2D_DESC depth = {} ;
327- // depth.Width = desc.Width;//rc.right - rc.left;client_width_;
328- // depth.Height = desc.Height;//rc.bottom - rc.top;client_height_;
329- // depth.MipLevels = 1;
330- // depth.ArraySize = 1;
331- // depth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
332- // depth.SampleDesc.Count = 1;
333- // depth.SampleDesc.Quality = 0;
334- // depth.Usage = D3D11_USAGE_DEFAULT;
335- // depth.BindFlags = D3D11_BIND_DEPTH_STENCIL;
336- // depth.CPUAccessFlags = 0;
337- // depth.MiscFlags = 0;
338- // ComPtr<ID3D11Texture2D> depthT;
339- //DX::ThrowIfFailed(m_d3dDevice->CreateTexture2D( &depth, NULL, &depthT ));
340-
341- // D3D11_DEPTH_STENCIL_VIEW_DESC dsv = {};
342- // dsv.Format = depth.Format;
343- // dsv.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
344- // dsv.Texture2D.MipSlice = 0;
345-
346- //DX::ThrowIfFailed(m_d3dDevice->CreateDepthStencilView( depthT.Get(), &dsv, &backBufferDepthStencilView_ ));
347-
348- spriteBatch_->AddTexture(backBuffer_.Get(),float2());
349-
350- // 深度ステンシルステートを作成する
351- //D3D11_DEPTH_STENCIL_DESC ddsDesc;
352- //::ZeroMemory( &ddsDesc, sizeof( ddsDesc ) );
353- //ddsDesc.DepthEnable = TRUE; // 深度テストを使用する
354- //ddsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
355- //ddsDesc.DepthFunc = D3D11_COMPARISON_LESS;
356- //ddsDesc.StencilEnable = FALSE;
357- //DX::ThrowIfFailed(m_d3dDevice->CreateDepthStencilState( &ddsDesc, &backBufferDepthStencilState_ ));
190+ dxgiDevice->SetMaximumFrameLatency(1)
191+ );
192+
193+ }
194+
195+ // Obtain the backbuffer for this window which will be the final 3D rendertarget.
196+ ComPtr<ID3D11Texture2D> backBuffer;
197+ DX::ThrowIfFailed(
198+ m_swapChain->GetBuffer(0, IID_PPV_ARGS(&backBuffer))
199+ );
200+
201+ // Create a view interface on the rendertarget to use on bind.
202+ DX::ThrowIfFailed(
203+ m_d3dDevice->CreateRenderTargetView(
204+ backBuffer.Get(),
205+ nullptr,
206+ &m_renderTargetView
207+ )
208+ );
209+
210+ // Cache the rendertarget dimensions in our helper class for convenient use.
211+ D3D11_TEXTURE2D_DESC backBufferDesc = {0};
212+ backBuffer->GetDesc(&backBufferDesc);
213+ m_renderTargetSize.Width = static_cast<float>(backBufferDesc.Width);
214+ m_renderTargetSize.Height = static_cast<float>(backBufferDesc.Height);
215+
216+ // Create a descriptor for the depth/stencil buffer.
217+ CD3D11_TEXTURE2D_DESC depthStencilDesc(
218+ DXGI_FORMAT_D24_UNORM_S8_UINT,
219+ backBufferDesc.Width,
220+ backBufferDesc.Height,
221+ 1,
222+ 1,
223+ D3D11_BIND_DEPTH_STENCIL
224+ );
225+
226+ // Allocate a 2-D surface as the depth/stencil buffer.
227+ ComPtr<ID3D11Texture2D> depthStencil;
228+ DX::ThrowIfFailed(
229+ m_d3dDevice->CreateTexture2D(
230+ &depthStencilDesc,
231+ nullptr,
232+ &depthStencil
233+ )
234+ );
235+
236+ // Create a DepthStencil view on this surface to use on bind.
237+ DX::ThrowIfFailed(
238+ m_d3dDevice->CreateDepthStencilView(
239+ depthStencil.Get(),
240+ &CD3D11_DEPTH_STENCIL_VIEW_DESC(D3D11_DSV_DIMENSION_TEXTURE2D),
241+ &m_depthStencilView
242+ )
243+ );
244+
245+ // Create a viewport descriptor of the full window size.
246+ swapChainViewPort_.Width = static_cast<float>(backBufferDesc.Width);
247+ swapChainViewPort_.Height = static_cast<float>(backBufferDesc.Height);
248+
249+ // Set the current viewport using the descriptor.
250+ m_d3dContext->RSSetViewports(1, &swapChainViewPort_);
251+
252+ // Now we set up the Direct2D render target bitmap linked to the swapchain.
253+ // Whenever we render to this bitmap, it will be directly rendered to the
254+ // swapchain associated with the window.
255+ D2D1_BITMAP_PROPERTIES1 bitmapProperties =
256+ BitmapProperties1(
257+ D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW,
258+ PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED),
259+ m_dpi,
260+ m_dpi
261+ );
262+
263+ // Direct2D needs the dxgi version of the backbuffer surface pointer.
264+ ComPtr<IDXGISurface> dxgiBackBuffer;
265+ DX::ThrowIfFailed(
266+ m_swapChain->GetBuffer(0, IID_PPV_ARGS(&dxgiBackBuffer))
267+ );
268+
269+ // Get a D2D surface from the DXGI back buffer to use as the D2D render target.
270+ DX::ThrowIfFailed(
271+ m_d2dContext->CreateBitmapFromDxgiSurface(
272+ dxgiBackBuffer.Get(),
273+ &bitmapProperties,
274+ &m_d2dTargetBitmap
275+ )
276+ );
277+
278+ // So now we can set the Direct2D render target.
279+ m_d2dContext->SetTarget(m_d2dTargetBitmap.Get());
280+
281+ // Set D2D text anti-alias mode to Grayscale to ensure proper rendering of text on intermediate surfaces.
282+ m_d2dContext->SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE);
283+
284+ // Randomly generate some non-interactive asteroids to fit the screen.
285+
286+ sampleOverlay_->UpdateForWindowSizeChange();
287+ // バックバッファの作成
288+ //ComPtr<ID3D11Texture2D> backBuffer;
289+ //DX::ThrowIfFailed(
290+ // m_swapChain->GetBuffer(0, IID_PPV_ARGS(&backBuffer))
291+ // );
292+ //D3D11_TEXTURE2D_DESC backBufferDesc = {0};
293+ //backBuffer->GetDesc(&backBufferDesc);
294+
295+ D3D11_TEXTURE2D_DESC desc = {0};
296+ desc.Width = 320;
297+ desc.Height = 240;
298+ desc.Format = backBufferDesc.Format;
299+ desc.MipLevels = 1;
300+ desc.SampleDesc.Count = 1;
301+ desc.SampleDesc.Quality = 0;
302+ desc.ArraySize = 1;
303+ desc.Usage = D3D11_USAGE_DEFAULT;
304+ desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
305+ // desc.MiscFlags = D3D11_RESOURCE_MISC_GDI_COMPATIBLE;
306+
307+ DX::ThrowIfFailed(m_d3dDevice->CreateTexture2D(&desc,NULL,&backBuffer_));
308+
309+ DX::ThrowIfFailed(m_d3dDevice->CreateRenderTargetView(backBuffer_.Get(),0,&backBufferRenderTargetView_));
310+
311+ // // 深度バッファの作成
312+ // D3D11_TEXTURE2D_DESC depth = {} ;
313+ // depth.Width = desc.Width;//rc.right - rc.left;client_width_;
314+ // depth.Height = desc.Height;//rc.bottom - rc.top;client_height_;
315+ // depth.MipLevels = 1;
316+ // depth.ArraySize = 1;
317+ // depth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
318+ // depth.SampleDesc.Count = 1;
319+ // depth.SampleDesc.Quality = 0;
320+ // depth.Usage = D3D11_USAGE_DEFAULT;
321+ // depth.BindFlags = D3D11_BIND_DEPTH_STENCIL;
322+ // depth.CPUAccessFlags = 0;
323+ // depth.MiscFlags = 0;
324+ // ComPtr<ID3D11Texture2D> depthT;
325+ //DX::ThrowIfFailed(m_d3dDevice->CreateTexture2D( &depth, NULL, &depthT ));
326+
327+ // D3D11_DEPTH_STENCIL_VIEW_DESC dsv = {};
328+ // dsv.Format = depth.Format;
329+ // dsv.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
330+ // dsv.Texture2D.MipSlice = 0;
331+
332+ //DX::ThrowIfFailed(m_d3dDevice->CreateDepthStencilView( depthT.Get(), &dsv, &backBufferDepthStencilView_ ));
333+
334+ spriteBatch_->AddTexture(backBuffer_.Get(),float2());
335+
336+ // 深度ステンシルステートを作成する
337+ //D3D11_DEPTH_STENCIL_DESC ddsDesc;
338+ //::ZeroMemory( &ddsDesc, sizeof( ddsDesc ) );
339+ //ddsDesc.DepthEnable = TRUE; // 深度テストを使用する
340+ //ddsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
341+ //ddsDesc.DepthFunc = D3D11_COMPARISON_LESS;
342+ //ddsDesc.StencilEnable = FALSE;
343+ //DX::ThrowIfFailed(m_d3dDevice->CreateDepthStencilState( &ddsDesc, &backBufferDepthStencilState_ ));
358344
359345 }
360346
361347 void GameMain::Update(float timeTotal, float timeDelta)
362348 {
363- // Update the performance throttler.
364-
365- auto control = autoThrottle_->Update(timeDelta);
366-
367- //if (control == FrameWorkload::Increase)
368- //{
369- // m_numParticlesToDraw += SampleSettings::Performance::ParticleCountDelta;
370- //}
371- //if (control == FrameWorkload::Decrease)
372- //{
373- // m_numParticlesToDraw -= SampleSettings::Performance::ParticleCountDelta;
374- //}
375- //if (control != FrameWorkload::Maintain)
376- //{
377- // m_numParticlesToDraw = max(SampleSettings::Performance::ParticleCountMin, min(SampleSettings::Performance::ParticleCountMax, m_numParticlesToDraw));
378- // if (m_featureLevel < D3D_FEATURE_LEVEL_9_3)
379- // {
380- // m_numParticlesToDraw = min(static_cast<int>(Parameters::MaximumCapacityCompatible - SampleSettings::NumAsteroids - 1), m_numParticlesToDraw);
381- // }
382- //}
383-
384- // Update the non-interactive asteroids.
385- // Their behavior is to drift across the window with a fixed translational and rotational
386- // velocity. Upon crossing a boundary outside the window, their position wraps.
387-
388- //for (auto asteroid = m_asteroidData.begin(); asteroid != m_asteroidData.end(); asteroid++)
389- //{
390- // static const float border = 100.0f;
391- // asteroid->pos = asteroid->pos + asteroid->vel * timeDelta;
392- // if (asteroid->vel.x < 0)
393- // {
394- // if (asteroid->pos.x < -border)
395- // {
396- // asteroid->pos.x = m_windowBounds.Width + border;
397- // }
398- // }
399- // else
400- // {
401- // if (asteroid->pos.x > m_windowBounds.Width + border)
402- // {
403- // asteroid->pos.x = -border;
404- // }
405- // }
406- // if (asteroid->vel.y < 0)
407- // {
408- // if (asteroid->pos.y < -border)
409- // {
410- // asteroid->pos.y = m_windowBounds.Height + border;
411- // }
412- // }
413- // else
414- // {
415- // if (asteroid->pos.y > m_windowBounds.Height + border)
416- // {
417- // asteroid->pos.y = -border;
418- // }
419- // }
420-
421- // asteroid->rot += asteroid->rotVel * timeDelta;
422- // if (asteroid->rot > static_cast<float>(M_PI))
423- // {
424- // asteroid->rot -= 2.0f * static_cast<float>(M_PI);
425- // }
426- // if (asteroid->rot < static_cast<float>(-M_PI))
427- // {
428- // asteroid->rot += 2.0f * static_cast<float>(M_PI);
429- // }
430- //}
431-
432- //// Update the interactive particles.
433- //// Their behavior is to be gravitationally attracted to two oscillating gravity
434- //// wells and repelled by any pressed pointer points. Upon reaching the edge of
435- //// the window, the particles bounce.
436-
437- //// Add two gravity wells that move throughout the window.
438- //float2 wellPositions[] =
439- //{
440- // float2(
441- // (1.0f + 0.8f * cosf(timeTotal / (2.0f * static_cast<float>(M_PI)) + 3.0f)) * m_windowBounds.Width / 2.0f,
442- // (1.0f + 0.8f * sinf(timeTotal / 5.0f)) * m_windowBounds.Height / 2.0f
443- // ),
444- // float2(
445- // (1.0f + 0.8f * cosf(timeTotal / static_cast<float>(M_PI * M_PI) + 1.0f)) * m_windowBounds.Width / 2.0f,
446- // (1.0f + 0.8f * sinf(timeTotal / static_cast<float>(M_PI))) * m_windowBounds.Height / 2.0f
447- // )
448- //};
449-
450- //for (auto particle = m_particleData.begin(); particle != m_particleData.begin() + m_numParticlesToDraw; particle++)
451- //{
452- // if (particle->pos.x < 0)
453- // {
454- // particle->vel.x = abs(particle->vel.x);
455- // }
456- // if (particle->pos.x > m_windowBounds.Width)
457- // {
458- // particle->vel.x = -abs(particle->vel.x);
459- // }
460- // if (particle->pos.y < 0)
461- // {
462- // particle->vel.y = abs(particle->vel.y);
463- // }
464- // if (particle->pos.y > m_windowBounds.Height)
465- // {
466- // particle->vel.y = -abs(particle->vel.y);
467- // }
468-
469- // for (auto repulsor = m_repulsors.begin(); repulsor != m_repulsors.end(); repulsor++)
470- // {
471- // float2 delta = particle->pos - repulsor->second;
472- // float deltaLength = length(delta) + 24.0f; // Offset length to avoid division by zero.
473- // float deltaLengthCubed = deltaLength * deltaLength * deltaLength;
474- // particle->vel = particle->vel + SampleSettings::Physics::Gravity * timeDelta * delta / deltaLengthCubed;
475- // }
476-
477- // for (int i = 0; i < ARRAYSIZE(wellPositions); i++)
478- // {
479- // float gravitySign = 1.0f;
480- // if ((static_cast<int>(timeTotal / 2.0f) + 1) % 10 == 0)
481- // {
482- // // Every 20 seconds, "explode" the gravity wells for 2 seconds.
483- // gravitySign = -1.0f;
484- // }
485- // float2 delta = wellPositions[i] - particle->pos;
486- // float deltaLength = length(delta) + 24.0f;
487- // float deltaLengthCubed = deltaLength * deltaLength * deltaLength;
488- // particle->vel = particle->vel + gravitySign * 0.2f * SampleSettings::Physics::Gravity * timeDelta * delta / deltaLengthCubed;
489- // }
490-
491- // particle->vel = particle->vel * (1.0f - SampleSettings::Physics::Damping);
492-
493- // // Add random noise to the velocity to prevent particles from locking together.
494- //
495- // particle->vel.x += RandFloat(-0.5f, 0.5f);
496- // particle->vel.y += RandFloat(-0.5f, 0.5f);
497-
498- // particle->pos = particle->pos + particle->vel * timeDelta;
499- //}
349+ // Update the performance throttler.
350+
351+ auto control = autoThrottle_->Update(timeDelta);
352+ state_.ProcessEvent(Event::Update());
353+ //if (control == FrameWorkload::Increase)
354+ //{
355+ // m_numParticlesToDraw += SampleSettings::Performance::ParticleCountDelta;
356+ //}
357+ //if (control == FrameWorkload::Decrease)
358+ //{
359+ // m_numParticlesToDraw -= SampleSettings::Performance::ParticleCountDelta;
360+ //}
361+ //if (control != FrameWorkload::Maintain)
362+ //{
363+ // m_numParticlesToDraw = max(SampleSettings::Performance::ParticleCountMin, min(SampleSettings::Performance::ParticleCountMax, m_numParticlesToDraw));
364+ // if (m_featureLevel < D3D_FEATURE_LEVEL_9_3)
365+ // {
366+ // m_numParticlesToDraw = min(static_cast<int>(Parameters::MaximumCapacityCompatible - SampleSettings::NumAsteroids - 1), m_numParticlesToDraw);
367+ // }
368+ //}
369+
370+ // Update the non-interactive asteroids.
371+ // Their behavior is to drift across the window with a fixed translational and rotational
372+ // velocity. Upon crossing a boundary outside the window, their position wraps.
373+
374+ //for (auto asteroid = m_asteroidData.begin(); asteroid != m_asteroidData.end(); asteroid++)
375+ //{
376+ // static const float border = 100.0f;
377+ // asteroid->pos = asteroid->pos + asteroid->vel * timeDelta;
378+ // if (asteroid->vel.x < 0)
379+ // {
380+ // if (asteroid->pos.x < -border)
381+ // {
382+ // asteroid->pos.x = m_windowBounds.Width + border;
383+ // }
384+ // }
385+ // else
386+ // {
387+ // if (asteroid->pos.x > m_windowBounds.Width + border)
388+ // {
389+ // asteroid->pos.x = -border;
390+ // }
391+ // }
392+ // if (asteroid->vel.y < 0)
393+ // {
394+ // if (asteroid->pos.y < -border)
395+ // {
396+ // asteroid->pos.y = m_windowBounds.Height + border;
397+ // }
398+ // }
399+ // else
400+ // {
401+ // if (asteroid->pos.y > m_windowBounds.Height + border)
402+ // {
403+ // asteroid->pos.y = -border;
404+ // }
405+ // }
406+
407+ // asteroid->rot += asteroid->rotVel * timeDelta;
408+ // if (asteroid->rot > static_cast<float>(M_PI))
409+ // {
410+ // asteroid->rot -= 2.0f * static_cast<float>(M_PI);
411+ // }
412+ // if (asteroid->rot < static_cast<float>(-M_PI))
413+ // {
414+ // asteroid->rot += 2.0f * static_cast<float>(M_PI);
415+ // }
416+ //}
417+
418+ //// Update the interactive particles.
419+ //// Their behavior is to be gravitationally attracted to two oscillating gravity
420+ //// wells and repelled by any pressed pointer points. Upon reaching the edge of
421+ //// the window, the particles bounce.
422+
423+ //// Add two gravity wells that move throughout the window.
424+ //float2 wellPositions[] =
425+ //{
426+ // float2(
427+ // (1.0f + 0.8f * cosf(timeTotal / (2.0f * static_cast<float>(M_PI)) + 3.0f)) * m_windowBounds.Width / 2.0f,
428+ // (1.0f + 0.8f * sinf(timeTotal / 5.0f)) * m_windowBounds.Height / 2.0f
429+ // ),
430+ // float2(
431+ // (1.0f + 0.8f * cosf(timeTotal / static_cast<float>(M_PI * M_PI) + 1.0f)) * m_windowBounds.Width / 2.0f,
432+ // (1.0f + 0.8f * sinf(timeTotal / static_cast<float>(M_PI))) * m_windowBounds.Height / 2.0f
433+ // )
434+ //};
435+
436+ //for (auto particle = m_particleData.begin(); particle != m_particleData.begin() + m_numParticlesToDraw; particle++)
437+ //{
438+ // if (particle->pos.x < 0)
439+ // {
440+ // particle->vel.x = abs(particle->vel.x);
441+ // }
442+ // if (particle->pos.x > m_windowBounds.Width)
443+ // {
444+ // particle->vel.x = -abs(particle->vel.x);
445+ // }
446+ // if (particle->pos.y < 0)
447+ // {
448+ // particle->vel.y = abs(particle->vel.y);
449+ // }
450+ // if (particle->pos.y > m_windowBounds.Height)
451+ // {
452+ // particle->vel.y = -abs(particle->vel.y);
453+ // }
454+
455+ // for (auto repulsor = m_repulsors.begin(); repulsor != m_repulsors.end(); repulsor++)
456+ // {
457+ // float2 delta = particle->pos - repulsor->second;
458+ // float deltaLength = length(delta) + 24.0f; // Offset length to avoid division by zero.
459+ // float deltaLengthCubed = deltaLength * deltaLength * deltaLength;
460+ // particle->vel = particle->vel + SampleSettings::Physics::Gravity * timeDelta * delta / deltaLengthCubed;
461+ // }
462+
463+ // for (int i = 0; i < ARRAYSIZE(wellPositions); i++)
464+ // {
465+ // float gravitySign = 1.0f;
466+ // if ((static_cast<int>(timeTotal / 2.0f) + 1) % 10 == 0)
467+ // {
468+ // // Every 20 seconds, "explode" the gravity wells for 2 seconds.
469+ // gravitySign = -1.0f;
470+ // }
471+ // float2 delta = wellPositions[i] - particle->pos;
472+ // float deltaLength = length(delta) + 24.0f;
473+ // float deltaLengthCubed = deltaLength * deltaLength * deltaLength;
474+ // particle->vel = particle->vel + gravitySign * 0.2f * SampleSettings::Physics::Gravity * timeDelta * delta / deltaLengthCubed;
475+ // }
476+
477+ // particle->vel = particle->vel * (1.0f - SampleSettings::Physics::Damping);
478+
479+ // // Add random noise to the velocity to prevent particles from locking together.
480+ //
481+ // particle->vel.x += RandFloat(-0.5f, 0.5f);
482+ // particle->vel.y += RandFloat(-0.5f, 0.5f);
483+
484+ // particle->pos = particle->pos + particle->vel * timeDelta;
485+ //}
500486 }
501487
502488 void GameMain::Render()
503489 {
504- static int frame_count = 0;
505-
506- m_d3dContext->OMSetRenderTargets(
507- 1,
508- backBufferRenderTargetView_.GetAddressOf(),
509- nullptr//backBufferDepthStencilView_.Get()
510- );
511-// m_d3dContext->OMSetDepthStencilState(backBufferDepthStencilState_.Get(),0);
512- m_d3dContext->RSSetViewports(1, &backBufferViewPort_);
513- //m_d3dContext->RSSetState(
514-
515-
516- m_d3dContext->ClearRenderTargetView(
517- backBufferRenderTargetView_.Get(),
518- reinterpret_cast<float*>(&D2D1::ColorF(D2D1::ColorF::Black))
519- );
520-
521- //m_d3dContext->ClearDepthStencilView(backBufferDepthStencilView_.Get(),D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL,1.0f,0);
522-
523-
524- spriteBatch_->Begin();
525-
526- // Draw the background.
527-
528- spriteBatch_->Draw(
529- test_.Get(),
530- float4(160.0f, 120.0f,0.7f,1.0f),
531- PositionUnits::Pixels,
532- float2(64.0f, 64.0f),
533- SizeUnits::Pixels,
534- float4(1.0f, 1.0f, 1.0f, 1.0f),
535- 0.0f,
536- BlendMode::Additive,
537- float2((float)((frame_count >> 3) % 4) * 64.0f,(float)((frame_count >> 3) / 4) * 64.0f)
538- );
539-
540- spriteBatch_->Draw(
541- test_.Get(),
542- float4(128.0f, 100.0f,0.7f,1.0f),
543- PositionUnits::Pixels,
544- float2(32.0f, 32.0f),
545- SizeUnits::Pixels,
546- float4(1.0f, 1.0f, 1.0f, 1.0f),
547- 0.0f,
548- BlendMode::Additive,
549- float2((float)((frame_count >> 3) % 4) * 64.0f,(float)((frame_count >> 3) / 4) * 64.0f)
550- );
551-
552- spriteBatch_->Draw(
553- test_.Get(),
554- float4(128.0f, 50.0f,0.7f,1.0f),
555- PositionUnits::Pixels,
556- float2(96.0f, 96.0f),
557- SizeUnits::Pixels,
558- float4(1.0f, 1.0f, 1.0f, 1.0f),
559- 0.0f,
560- BlendMode::Additive,
561- float2((float)((frame_count >> 3) % 4) * 64.0f,(float)((frame_count >> 3) / 4) * 64.0f)
562- );
563-
564- frame_count = (frame_count + 1) & (0x7f);
565-
566- //// Draw the non-interactive asteroids.
567-
568- //for (auto asteroid = m_asteroidData.begin(); asteroid != m_asteroidData.end(); asteroid++)
569- //{
570- // spriteBatch_->Draw(
571- // m_asteroid.Get(),
572- // asteroid->pos,
573- // PositionUnits::DIPs,
574- // float2(1.0f, 1.0f) * asteroid->scale,
575- // SizeUnits::Normalized,
576- // float4(0.8f, 0.8f, 1.0f, 1.0f),
577- // asteroid->rot
578- // );
579- //}
580-
581- //// Draw the interactive particles.
582-
583- //for (auto particle = m_particleData.begin(); particle != m_particleData.begin() + m_numParticlesToDraw; particle++)
584- //{
585- // float alpha = length(particle->vel) / 200.0f;
586- // spriteBatch_->Draw(
587- // m_particle.Get(),
588- // particle->pos,
589- // PositionUnits::DIPs,
590- // float2(32.0f, 32.0f),
591- // SizeUnits::DIPs,
592- // float4(0.1f, 0.02f, 0.0f, alpha),
593- // 0.0f,
594- // BlendMode::Additive
595- // );
596- //}
597-
598- spriteBatch_->End();
599-
600- m_d3dContext->OMSetRenderTargets(
601- 1,
602- m_renderTargetView.GetAddressOf(),
603- nullptr/*m_depthStencilView.Get()*/
604- );
605-
606- m_d3dContext->RSSetViewports(1, &swapChainViewPort_);
607-
608-
609- m_d3dContext->ClearRenderTargetView(
610- m_renderTargetView.Get(),
611- reinterpret_cast<float*>(&D2D1::ColorF(D2D1::ColorF::MidnightBlue))
612- );
613-
614- //m_d3dContext->ClearDepthStencilView(m_depthStencilView.Get(),D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL,1.0f,0);
615-
616- spriteBatch_->Begin();
617-
618- spriteBatch_->Draw(
619- backBuffer_.Get(),
620- float4(m_window->Bounds.Width / 2.0f,m_window->Bounds.Height / 2.0f,0.0f,1.0f),
621- PositionUnits::DIPs,
622- float2(1.0f, 1.0f) * scale_,
623- SizeUnits::Normalized,
624- float4(1.0f, 1.0f, 1.0f, 1.0f),
625- 0.0f,
626- BlendMode::Alpha
627- );
628-
629- spriteBatch_->End();
630-
631- // Render the Sample Overlay.
632- sampleOverlay_->Render();
490+ state_.ProcessEvent(Event::Render());
491+
492+
493+
494+ //// Draw the non-interactive asteroids.
495+
496+ //for (auto asteroid = m_asteroidData.begin(); asteroid != m_asteroidData.end(); asteroid++)
497+ //{
498+ // spriteBatch_->Draw(
499+ // m_asteroid.Get(),
500+ // asteroid->pos,
501+ // PositionUnits::DIPs,
502+ // float2(1.0f, 1.0f) * asteroid->scale,
503+ // SizeUnits::Normalized,
504+ // float4(0.8f, 0.8f, 1.0f, 1.0f),
505+ // asteroid->rot
506+ // );
507+ //}
508+
509+ //// Draw the interactive particles.
510+
511+ //for (auto particle = m_particleData.begin(); particle != m_particleData.begin() + m_numParticlesToDraw; particle++)
512+ //{
513+ // float alpha = length(particle->vel) / 200.0f;
514+ // spriteBatch_->Draw(
515+ // m_particle.Get(),
516+ // particle->pos,
517+ // PositionUnits::DIPs,
518+ // float2(32.0f, 32.0f),
519+ // SizeUnits::DIPs,
520+ // float4(0.1f, 0.02f, 0.0f, alpha),
521+ // 0.0f,
522+ // BlendMode::Additive
523+ // );
524+ //}
525+
633526 }
634527
635528
636529
637530 float GameMain::RandFloat(float min, float max)
638531 {
639- return (static_cast<float>(rand() % RAND_MAX) / static_cast<float>(RAND_MAX)) * (max - min) + min;
532+ return (static_cast<float>(rand() % RAND_MAX) / static_cast<float>(RAND_MAX)) * (max - min) + min;
640533 }
641534
642535 // サウンド再生スレッド
643536 void GameMain::ExecuteSoundThread()
644537 {
645- //sf::com_init comInit;
646- InitSound();
538+ //sf::com_init comInit;
539+// InitSound();
647540 soundManager_->Sequencer().Play();
648- while(!isDestroy_)
649- {
541+ while(!isDestroy_)
542+ {
650543 soundDriver_->Render();
651-// Concurrency::wait(800);
652- // soundDriver_->Update();
653- // soundDriver_->Render();
654- }
544+ // Concurrency::wait(800);
545+ // soundDriver_->Update();
546+ // soundDriver_->Render();
547+ }
548+}
549+
550+void GameMain::StartSound()
551+{
552+ if(isDestroy_) {
553+ isDestroy_ = false;
554+ // サウンド再生スレッドの開始
555+ soundTask_ = task<void>(create_async([this]()
556+ {
557+ ExecuteSoundThread();
558+ })
559+ );
560+ }
655561 }
656562
657-void GameMain::InitSound()
563+void GameMain::StopSound()
658564 {
659- // 鋸波テーブルを作る
660- {
661- sf::Synthesizer::WaveTable sawtbl;
662- sawtbl.sampleRate = 440.0f;
663- sawtbl.basePitch = 0.0f;
664- sawtbl.stereo = false;
665-
666- float v = -1.0f,d = 2.0f / 1024.0f;
667- for(int i = 0;i < 1024;++i)
668- {
669- // if(i < 15) v = -1.0f; else v = 1.0f;
670- sawtbl.waveData.push_back(v) ;
671- v += d;
672- }
673- soundManager_->Synthesizer().WaveTables().push_back(std::move(sawtbl));
674- }
675-
676- // 矩形波テーブルを作る
677- {
678- sf::Synthesizer::WaveTable squaretbl;
679- squaretbl.sampleRate = 440.0f;
680- squaretbl.basePitch = 0.0f;
681- squaretbl.stereo = false;
682-
683- float v = 0.0f;
684- for(int i = 0;i < 32;++i)
685- {
686- if(i < 15) v = -1.0f; else v = 1.0f;
687- squaretbl.waveData.push_back(v) ;
688- }
689- soundManager_->Synthesizer().WaveTables().push_back(std::move(squaretbl));
690- }
691-
692- // 三角波テーブル
693- {
694- sf::Synthesizer::WaveTable tritbl;
695- tritbl.sampleRate = 440.0f;
696- tritbl.basePitch = 0.0f;
697- tritbl.stereo = false;
698-
699- float v = -1.0f,d = 2.0f / 16.0f;
700- for(int i = 0;i < 32;++i)
701- {
702- if(i < 15) d = -d;
703- tritbl.waveData.push_back(v) ;
704- v += d;
705- }
706- soundManager_->Synthesizer().WaveTables().push_back(std::move(tritbl));
707- }
708-
709- // sinテーブル
710- {
711- sf::Synthesizer::WaveTable sintbl;
712- sintbl.sampleRate = 440.0f;
713- sintbl.basePitch = 0.0f;
714- sintbl.stereo = false;
715-
716- float v = 0.0f,d = 2.0f * M_PI / 128.0f;
717- for(int i = 0;i < 128;++i)
718- {
719- sintbl.waveData.push_back(sinf(v));
720- v += d;
721- }
722- soundManager_->Synthesizer().WaveTables().push_back(std::move(sintbl));
723- }
724-
725- // LFO用 Sinテーブル
726- {
727- sf::Synthesizer::WaveTable sintbl;
728- sintbl.sampleRate = 440.0f;
729- sintbl.basePitch = 0.0f;
730- sintbl.stereo = false;
731-
732- float v = 0.0f,d = 2.0f * M_PI / 128.0f;
733- for(int i = 0;i < 128;++i)
734- {
735- sintbl.waveData.push_back(sinf(v) / 2.0f + 0.5f);
736- v += d;
737- }
738- soundManager_->Synthesizer().WaveTables().push_back(std::move(sintbl));
739- }
740-
741-
742-
743-
744- // ::OutputDebugStringW((boost::wformat(L"waveTable size: %d") % osc_[0].WaveData().size()).str().c_str());
745-
746- // timberのセットアップ
747- for(int i = 0; i < 4;++i){
748-
749- sf::Synthesizer::Timber timber;
750- timber.oscillator.reset(new sf::Synthesizer::WaveTableOscillator(&soundManager_->Synthesizer().WaveTables().at(0)));
751- timber.amplitude.gain = 1.0f;
752- timber.amplitude.envelope.releaseNoteOff = true;
753- timber.amplitude.envelope.attackTime = 0.01f;
754- timber.amplitude.envelope.decayTime = 0.02f;
755- timber.amplitude.envelope.sustainLevel = 0.5f;
756- timber.amplitude.envelope.releaseTime = 0.2f;
757- timber.amplitude.envelope.gain = 1.0f;
758- timber.amplitude.lfo.waveForm = &(soundManager_->Synthesizer().WaveTables()[4]);
759- timber.amplitude.lfo.freq = 5.0f;
760- timber.amplitude.lfo.gain = 0.0f;
761-
762- timber.pitch.lfo.freq = 10.0f;
763- timber.pitch.lfo.gain = 0.000f;
764- timber.pitch.lfo.waveForm = &(soundManager_->Synthesizer().WaveTables()[4]);
765- timber.pitch.lfo.startNoteOn = true;
766- timber.pitch.envelope.attackTime = 0.0f;
767- timber.pitch.envelope.decayTime = 0.02f;
768- timber.pitch.envelope.sustainLevel = 0.5f;
769- timber.pitch.envelope.gain =0.0f;
770- timber.pitch.pitch = 0.0f;
771-
772- timber.pan.lfo.freq = 2.0f;
773- timber.pan.lfo.gain = 1.0f;
774- timber.pan.lfo.waveForm = &(soundManager_->Synthesizer().WaveTables()[3]);
775- timber.pan.lfo.startNoteOn = true;
776- timber.pan.envelope.enable = false;
777- timber.pan.lfo.envelope.enable = false;
778- timber.pan.pan = 0.0f;
779-
780- timber.filter.lfo.freq = 5.0f;
781- timber.filter.lfo.gain = 1.0f;
782- timber.filter.lfo.waveForm = &(soundManager_->Synthesizer().WaveTables()[3]);
783- timber.filter.lfo.startNoteOn = true;
784- timber.filter.cutoff = 10000.0f;
785- timber.filter.resonance = 0.0f;
786- timber.filter.envelope.attackTime = 0.01f;
787- timber.filter.envelope.decayTime = 0.03f;
788- timber.filter.envelope.sustainLevel = 0.05f;
789- timber.filter.envelope.releaseTime = 0.2f;
790- timber.filter.envelope.gain = 10000.0f;
791-
792- soundManager_->Synthesizer().AddProgram(sf::Synthesizer::Program(std::move((boost::wformat(L"Program No.%d") % i).str()),std::move(timber)));
793- // timbers_.push_back(std::move(timber));
794- }
795-
796- for(int i = 0,end = soundManager_->Synthesizer().Voices();i < end;++i)
797- {
798- soundManager_->Synthesizer().AssignProgramToVoice(0,i);
799- }
800-
801- soundManager_->Synthesizer().isEnable(true);
565+ // サウンド再生スレッドの停止
566+ if(!isDestroy_){
567+ isDestroy_ = true;
568+ soundTask_.wait();
569+ }
570+}
571+
572+void GameMain::ClearScreen()
573+{
574+ m_d3dContext->OMSetRenderTargets(
575+ 1,
576+ backBufferRenderTargetView_.GetAddressOf(),
577+ nullptr//backBufferDepthStencilView_.Get()
578+ );
579+ // m_d3dContext->OMSetDepthStencilState(backBufferDepthStencilState_.Get(),0);
580+ m_d3dContext->RSSetViewports(1, &backBufferViewPort_);
581+ //m_d3dContext->RSSetState(
582+
583+
584+ m_d3dContext->ClearRenderTargetView(
585+ backBufferRenderTargetView_.Get(),
586+ reinterpret_cast<float*>(&D2D1::ColorF(D2D1::ColorF::Black))
587+ );
588+
589+ //m_d3dContext->ClearDepthStencilView(backBufferDepthStencilView_.Get(),D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL,1.0f,0);
590+
591+}
592+
593+void GameMain::RenderScreen()
594+{
595+ m_d3dContext->OMSetRenderTargets(
596+ 1,
597+ m_renderTargetView.GetAddressOf(),
598+ nullptr/*m_depthStencilView.Get()*/
599+ );
600+
601+ m_d3dContext->RSSetViewports(1, &swapChainViewPort_);
602+
603+
604+ m_d3dContext->ClearRenderTargetView(
605+ m_renderTargetView.Get(),
606+ reinterpret_cast<float*>(&D2D1::ColorF(D2D1::ColorF::MidnightBlue))
607+ );
608+
609+ //m_d3dContext->ClearDepthStencilView(m_depthStencilView.Get(),D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL,1.0f,0);
610+
611+ spriteBatch_->Begin();
612+
613+ spriteBatch_->Draw(
614+ backBuffer_.Get(),
615+ float4(m_window->Bounds.Width / 2.0f,m_window->Bounds.Height / 2.0f,0.0f,1.0f),
616+ PositionUnits::DIPs,
617+ float2(1.0f, 1.0f) * scale_,
618+ SizeUnits::Normalized,
619+ float4(1.0f, 1.0f, 1.0f, 1.0f),
620+ 0.0f,
621+ BlendMode::Alpha
622+ );
623+
624+ spriteBatch_->End();
625+
626+ // Render the Sample Overlay.
627+ sampleOverlay_->Render();
628+
629+}
630+
631+void GameMain::LoadTexture(const std::wstring& filename,ID3D11Texture2D** texPtrAddr)
632+{
633+ // Load the sprite textures.
634+
635+ BasicLoader^ loader = ref new BasicLoader(m_d3dDevice.Get(), m_wicFactory.Get());
636+ Platform::String^ f = ref new Platform::String(filename.c_str());
637+
638+ loader->LoadTexture(
639+ f,
640+ texPtrAddr,
641+ nullptr
642+ );
643+}
644+
802645 }
803646
--- a/ShootingGame/GameMain.h
+++ b/ShootingGame/GameMain.h
@@ -11,8 +11,11 @@
1111 #include "SampleOverlay.h"
1212 #include "AutoThrottle.h"
1313 #include "BasicSprites.h"
14+#include "BasicLoader.h"
1415 #include "SoundManager.h"
16+#include "GameStateMachine.h"
1517
18+namespace ShootingGame {
1619 struct CharacterData
1720 {
1821 float2 pos;
@@ -43,16 +46,38 @@ internal:
4346 static const float BACKBUFFER_WIDTH;
4447 static const float BACKBUFFER_HEIGHT;
4548
49+ sf::SoundManager& GameMain::SoundManager()
50+ {
51+ return *soundManager_;
52+ }
4653
54+ sf::SoundDriver& GameMain::SoundDriver()
55+ {
56+ return *soundDriver_;
57+ }
4758
59+ BasicSprites::SpriteBatch^ GameMain::SpriteBatch()
60+ {
61+ return spriteBatch_;
62+ }
63+
64+ ::AutoThrottle^ GameMain::AutoThrottle() {return autoThrottle_;}
65+ ::SampleOverlay^ GameMain::SampleOverlay() {return sampleOverlay_;}
66+
67+// void InitSound();
68+ float RandFloat(float min, float max);
69+ void StartSound();
70+ void StopSound();
71+ void ClearScreen();
72+ void RenderScreen();
73+
74+ void LoadTexture(const std::wstring& filename,ID3D11Texture2D** texPtrAddr);
4875 private:
76+ GameStateMachine state_;
4977 void ExecuteSoundThread();
50- void InitSound();
51- float RandFloat(float min, float max);
52- SampleOverlay^ sampleOverlay_;
53- AutoThrottle^ autoThrottle_;
78+ ::SampleOverlay^ sampleOverlay_;
79+ ::AutoThrottle^ autoThrottle_;
5480 BasicSprites::SpriteBatch^ spriteBatch_;
55- Microsoft::WRL::ComPtr<ID3D11Texture2D> test_;
5681 Microsoft::WRL::ComPtr<ID3D11Texture2D> backBuffer_;
5782 Microsoft::WRL::ComPtr<ID3D11RenderTargetView> backBufferRenderTargetView_;
5883 // Microsoft::WRL::ComPtr<ID3D11DepthStencilView> backBufferDepthStencilView_;
@@ -68,3 +93,4 @@ private:
6893 //std::thread soundThread_;
6994 concurrency::task<void> soundTask_;
7095 };
96+}
--- /dev/null
+++ b/ShootingGame/GameStateMachine.cpp
@@ -0,0 +1,448 @@
1+#include "pch.h"
2+//#define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
3+//#define BOOST_MPL_LIMIT_VECTOR_SIZE 30 //or whatever you need
4+//#define BOOST_MPL_LIMIT_MAP_SIZE 30 //or whatever you need
5+#include <boost/msm/back/state_machine.hpp>
6+#include <boost/msm/front/state_machine_def.hpp>
7+#include <boost/msm/front/functor_row.hpp>
8+
9+#include "GameStateMachine.h"
10+#include "GameMain.h"
11+#include "SoundDriver.h"
12+
13+using namespace Microsoft::WRL;
14+using namespace Windows::Foundation;
15+using namespace Windows::Foundation::Collections;
16+using namespace Windows::UI::Core;
17+using namespace Windows::UI::ViewManagement;
18+
19+using namespace Windows::UI::ApplicationSettings;
20+using namespace Windows::UI::Popups;
21+using namespace Windows::UI::Xaml::Controls;
22+using namespace Windows::Graphics::Display;
23+using namespace DirectX;
24+using namespace D2D1;
25+using namespace concurrency;
26+
27+
28+using namespace BasicSprites;
29+
30+namespace msmf = boost::msm::front;
31+namespace msmb = boost::msm::back;
32+
33+namespace ShootingGame
34+{
35+
36+ namespace State
37+ {
38+ struct Init : boost::msm::front::state<>
39+ {
40+ template <class Event, class Fsm>
41+ void on_entry(Event const& e, Fsm& f )
42+ {
43+ gameMain_ = f.GameMain();
44+ };
45+
46+ private:
47+ GameMain^ gameMain_;
48+ };
49+
50+ struct Title : boost::msm::front::state<>
51+ {
52+ template <class Event, class Fsm>
53+ void on_entry(Event const&, Fsm& ) {};
54+ template <class Event, class Fsm>
55+ void on_exit(Event const&, Fsm& ) {};
56+ };
57+
58+ struct Demo : boost::msm::front::state<>
59+ {
60+ template <class Event, class Fsm>
61+ void on_entry(Event const&, Fsm& ) {};
62+ template <class Event, class Fsm>
63+ void on_exit(Event const&, Fsm& ) {};
64+ };
65+
66+ struct Menu : boost::msm::front::state<>
67+ {
68+ template <class Event, class Fsm>
69+ void on_entry(Event const&, Fsm& ) {};
70+ template <class Event, class Fsm>
71+ void on_exit(Event const&, Fsm& ) {};
72+ };
73+
74+ struct Running_ : boost::msm::front::state_machine_def<Running_>
75+ {
76+
77+ struct Update
78+ {
79+ template <class Fsm,class Evt,class SourceState,class TargetState>
80+ void operator()(Evt const& e, Fsm& fsm, SourceState&,TargetState& )
81+ {
82+
83+ }
84+ };
85+
86+ struct Render
87+ {
88+ template <class Fsm,class Evt,class SourceState,class TargetState>
89+ void operator()(Evt const& e, Fsm& fsm, SourceState&,TargetState& )
90+ {
91+ ShootingGame::GameMain^ gameMain = fsm.GameMain();
92+ BasicSprites::SpriteBatch^ spriteBatch = fsm.GameMain()->SpriteBatch();
93+ ID3D11Texture2D * test_(fsm.texture());
94+ static int frame_count = 0;
95+ frame_count = (frame_count + 1) & (0x7f);
96+
97+ gameMain->ClearScreen();
98+
99+ spriteBatch->Begin();
100+
101+ // Draw the background.
102+
103+ spriteBatch->Draw(
104+ test_,
105+ float4(160.0f, 120.0f,0.7f,1.0f),
106+ PositionUnits::Pixels,
107+ float2(64.0f, 64.0f),
108+ SizeUnits::Pixels,
109+ float4(1.0f, 1.0f, 1.0f, 1.0f),
110+ 0.0f,
111+ BlendMode::Additive,
112+ float2((float)((frame_count >> 3) % 4) * 64.0f,(float)((frame_count >> 3) / 4) * 64.0f)
113+ );
114+
115+ spriteBatch->Draw(
116+ test_,
117+ float4(128.0f, 100.0f,0.7f,1.0f),
118+ PositionUnits::Pixels,
119+ float2(32.0f, 32.0f),
120+ SizeUnits::Pixels,
121+ float4(1.0f, 1.0f, 1.0f, 1.0f),
122+ 0.0f,
123+ BlendMode::Additive,
124+ float2((float)((frame_count >> 3) % 4) * 64.0f,(float)((frame_count >> 3) / 4) * 64.0f)
125+ );
126+
127+ spriteBatch->Draw(
128+ test_,
129+ float4(128.0f, 50.0f,0.7f,1.0f),
130+ PositionUnits::Pixels,
131+ float2(96.0f, 96.0f),
132+ SizeUnits::Pixels,
133+ float4(1.0f, 1.0f, 1.0f, 1.0f),
134+ 0.0f,
135+ BlendMode::Additive,
136+ float2((float)((frame_count >> 3) % 4) * 64.0f,(float)((frame_count >> 3) / 4) * 64.0f)
137+ );
138+
139+ spriteBatch->End();
140+ gameMain->RenderScreen();
141+ }
142+
143+ };
144+
145+ struct Action : msmf::state<>{};
146+
147+ template <class Event, class Fsm>
148+ void on_entry(Event const& evt, Fsm& fsm)
149+ {
150+ gameMain_ = fsm.GameMain();
151+ gameMain_->StopSound();
152+ InitSound();
153+ gameMain_->StartSound();
154+ LoadTexture();
155+ };
156+
157+ typedef boost::mpl::vector<Action> initial_state;
158+ template <class FSM,class Event>
159+ void no_transition(Event const& ,FSM&, int state)
160+ {
161+ BOOST_ASSERT(false);
162+ }
163+
164+ template <class Event, class Fsm>
165+ void on_exit(Event const&, Fsm& ) {};
166+ struct transition_table
167+ : boost::mpl::vector<
168+ msmf::Row<Action,Event::Update,msmf::none,Update,msmf::none>,
169+ msmf::Row<Action,Event::Render,msmf::none,Render,msmf::none>
170+ >
171+ {};
172+
173+ ShootingGame::GameMain^ Running_::GameMain(){return gameMain_;}
174+ ID3D11Texture2D * texture()
175+ {
176+ return test_.Get();
177+ };
178+ private:
179+ void InitSound()
180+ {
181+ sf::SoundManager& sm(gameMain_->SoundManager());
182+ sm.Synthesizer().isEnable(false);
183+ sm.Synthesizer().Clear();
184+ // sm.Synthesizer().WaveTables().clear();
185+
186+ // 鋸波テーブルを作る
187+ {
188+ sf::Synthesizer::WaveTable sawtbl;
189+ sawtbl.sampleRate = 440.0f;
190+ sawtbl.basePitch = 0.0f;
191+ sawtbl.stereo = false;
192+
193+ float v = -1.0f,d = 2.0f / 1024.0f;
194+ for(int i = 0;i < 1024;++i)
195+ {
196+ // if(i < 15) v = -1.0f; else v = 1.0f;
197+ sawtbl.waveData.push_back(v) ;
198+ v += d;
199+ }
200+ sm.Synthesizer().WaveTables().push_back(std::move(sawtbl));
201+ }
202+
203+ // 矩形波テーブルを作る
204+ {
205+ sf::Synthesizer::WaveTable squaretbl;
206+ squaretbl.sampleRate = 440.0f;
207+ squaretbl.basePitch = 0.0f;
208+ squaretbl.stereo = false;
209+
210+ float v = 0.0f;
211+ for(int i = 0;i < 32;++i)
212+ {
213+ if(i < 15) v = -1.0f; else v = 1.0f;
214+ squaretbl.waveData.push_back(v) ;
215+ }
216+ sm.Synthesizer().WaveTables().push_back(std::move(squaretbl));
217+ }
218+
219+ // 三角波テーブル
220+ {
221+ sf::Synthesizer::WaveTable tritbl;
222+ tritbl.sampleRate = 440.0f;
223+ tritbl.basePitch = 0.0f;
224+ tritbl.stereo = false;
225+
226+ float v = -1.0f,d = 2.0f / 16.0f;
227+ for(int i = 0;i < 32;++i)
228+ {
229+ if(i < 15) d = -d;
230+ tritbl.waveData.push_back(v) ;
231+ v += d;
232+ }
233+ sm.Synthesizer().WaveTables().push_back(std::move(tritbl));
234+ }
235+
236+ // sinテーブル
237+ {
238+ sf::Synthesizer::WaveTable sintbl;
239+ sintbl.sampleRate = 440.0f;
240+ sintbl.basePitch = 0.0f;
241+ sintbl.stereo = false;
242+
243+ float v = 0.0f,d = 2.0f * M_PI / 128.0f;
244+ for(int i = 0;i < 128;++i)
245+ {
246+ sintbl.waveData.push_back(sinf(v));
247+ v += d;
248+ }
249+ sm.Synthesizer().WaveTables().push_back(std::move(sintbl));
250+ }
251+
252+ // LFO用 Sinテーブル
253+ {
254+ sf::Synthesizer::WaveTable sintbl;
255+ sintbl.sampleRate = 440.0f;
256+ sintbl.basePitch = 0.0f;
257+ sintbl.stereo = false;
258+
259+ float v = 0.0f,d = 2.0f * M_PI / 128.0f;
260+ for(int i = 0;i < 128;++i)
261+ {
262+ sintbl.waveData.push_back(sinf(v) / 2.0f + 0.5f);
263+ v += d;
264+ }
265+ sm.Synthesizer().WaveTables().push_back(std::move(sintbl));
266+ }
267+
268+
269+
270+
271+ // ::OutputDebugStringW((boost::wformat(L"waveTable size: %d") % osc_[0].WaveData().size()).str().c_str());
272+
273+ // timberのセットアップ
274+ for(int i = 0; i < 4;++i){
275+
276+ sf::Synthesizer::Timber timber;
277+ timber.oscillator.reset(new sf::Synthesizer::WaveTableOscillator(&sm.Synthesizer().WaveTables().at(0)));
278+ timber.amplitude.gain = 1.0f;
279+ timber.amplitude.envelope.releaseNoteOff = true;
280+ timber.amplitude.envelope.attackTime = 0.01f;
281+ timber.amplitude.envelope.decayTime = 0.02f;
282+ timber.amplitude.envelope.sustainLevel = 0.5f;
283+ timber.amplitude.envelope.releaseTime = 0.2f;
284+ timber.amplitude.envelope.gain = 1.0f;
285+ timber.amplitude.lfo.waveForm = &(sm.Synthesizer().WaveTables()[4]);
286+ timber.amplitude.lfo.freq = 5.0f;
287+ timber.amplitude.lfo.gain = 0.0f;
288+
289+ timber.pitch.lfo.freq = 10.0f;
290+ timber.pitch.lfo.gain = 0.000f;
291+ timber.pitch.lfo.waveForm = &(sm.Synthesizer().WaveTables()[4]);
292+ timber.pitch.lfo.startNoteOn = true;
293+ timber.pitch.envelope.attackTime = 0.0f;
294+ timber.pitch.envelope.decayTime = 0.02f;
295+ timber.pitch.envelope.sustainLevel = 0.5f;
296+ timber.pitch.envelope.gain =0.0f;
297+ timber.pitch.pitch = 0.0f;
298+
299+ timber.pan.lfo.freq = 2.0f;
300+ timber.pan.lfo.gain = 1.0f;
301+ timber.pan.lfo.waveForm = &(sm.Synthesizer().WaveTables()[3]);
302+ timber.pan.lfo.startNoteOn = true;
303+ timber.pan.envelope.enable = false;
304+ timber.pan.lfo.envelope.enable = false;
305+ timber.pan.pan = 0.0f;
306+
307+ timber.filter.lfo.freq = 5.0f;
308+ timber.filter.lfo.gain = 1.0f;
309+ timber.filter.lfo.waveForm = &(sm.Synthesizer().WaveTables()[3]);
310+ timber.filter.lfo.startNoteOn = true;
311+ timber.filter.cutoff = 10000.0f;
312+ timber.filter.resonance = 0.0f;
313+ timber.filter.envelope.attackTime = 0.01f;
314+ timber.filter.envelope.decayTime = 0.03f;
315+ timber.filter.envelope.sustainLevel = 0.05f;
316+ timber.filter.envelope.releaseTime = 0.2f;
317+ timber.filter.envelope.gain = 10000.0f;
318+
319+ sm.Synthesizer().AddProgram(sf::Synthesizer::Program(std::move((boost::wformat(L"Program No.%d") % i).str()),std::move(timber)));
320+ // timbers_.push_back(std::move(timber));
321+ }
322+
323+ for(int i = 0,end = sm.Synthesizer().Voices();i < end;++i)
324+ {
325+ sm.Synthesizer().AssignProgramToVoice(0,i);
326+ }
327+
328+ sm.Synthesizer().isEnable(true);
329+
330+ }
331+
332+ void LoadTexture()
333+ {
334+ gameMain_->LoadTexture(L"explosion.png",&test_);
335+ gameMain_->SpriteBatch()->AddTexture(test_.Get(),float2(64.0,64.0));
336+ }
337+
338+ ShootingGame::GameMain^ gameMain_;
339+ Microsoft::WRL::ComPtr<ID3D11Texture2D> test_;
340+ };
341+
342+ typedef boost::msm::back::state_machine<Running_> Running;
343+
344+ struct SoundEdit : boost::msm::front::state<>
345+ {
346+ template <class Event, class Fsm>
347+ void on_entry(Event const&, Fsm& ) {};
348+ template <class Event, class Fsm>
349+ void on_exit(Event const&, Fsm& ) {};
350+ };
351+
352+ struct Exit : boost::msm::front::state<>
353+ {
354+ template <class Event, class Fsm>
355+ void on_entry(Event const&, Fsm& ) {};
356+ template <class Event, class Fsm>
357+ void on_exit(Event const&, Fsm& ) {};
358+ };
359+ }
360+
361+ struct GameStateMachine_ : boost::msm::front::state_machine_def<GameStateMachine_>
362+ {
363+ typedef State::Init initial_state;
364+
365+ template <class Event, class Fsm>
366+ void on_entry(Event const&, Fsm& ) {};
367+
368+ template <class Event, class Fsm>
369+ void on_exit(Event const&, Fsm& ) {};
370+
371+ struct transition_table
372+ : boost::mpl::vector<
373+ msmf::Row<State::Init,Event::Init,State::Running>//,
374+ // msmf::Row<State::Running,Event::Update,boost::msm::front::none,State::Running::Update>
375+ /* _row<State::Menu,Event::PushStart,State::Running>,
376+ _row<State::Menu,Event::PushSoundEdit,State::SoundEdit>,
377+ _row<State::Menu,Event::TimeOut,State::Demo>,
378+ _row<State::Running,Event::Escape,State::Menu>,
379+ _row<State::SoundEdit,Event::Escape,State::Menu>*/
380+ >{};
381+
382+ template <class FSM,class Event>
383+ void no_transition(Event const& ,FSM&, int state)
384+ {
385+ // BOOST_ASSERT(false);
386+ }
387+
388+ explicit GameStateMachine_(GameMain^ main) :gameMain_(main)
389+ {
390+
391+ }
392+
393+ ~GameStateMachine_()
394+ {
395+
396+ }
397+
398+ ShootingGame::GameMain^ GameStateMachine_::GameMain(){return gameMain_;}
399+
400+ private:
401+ ShootingGame::GameMain ^gameMain_;
402+ };
403+
404+ typedef boost::msm::back::state_machine<GameStateMachine_> GameStateMachineImpl;
405+
406+ struct GameStateMachine::impl
407+ {
408+ impl(GameMain ^ main) : impl_(main) {};
409+ ~impl(){impl_.stop();}
410+ template <class Event> void ProcessEvent(Event const & e) {impl_.process_event(e);}
411+ void Start() {impl_.start();}
412+ void Stop() {impl_.stop();}
413+ private:
414+ GameStateMachineImpl impl_;
415+ };
416+
417+ GameStateMachine::GameStateMachine(GameMain^ main)
418+ : impl_(new impl(main))
419+ {
420+
421+ }
422+
423+ GameStateMachine::~GameStateMachine()
424+ {
425+ impl_.reset();
426+ }
427+
428+ template <class Event> void GameStateMachine::ProcessEvent(Event const& e)
429+ {
430+ impl_->ProcessEvent(e);
431+ }
432+
433+ void GameStateMachine::Start()
434+ {
435+ impl_->Start();
436+
437+ }
438+
439+ void GameStateMachine::Stop()
440+ {
441+ impl_->Stop();
442+ }
443+
444+ template void GameStateMachine::ProcessEvent<Event::Init>(Event::Init const &e);
445+ template void GameStateMachine::ProcessEvent<Event::Update>(Event::Update const &e);
446+ template void GameStateMachine::ProcessEvent<Event::Render>(Event::Render const &e);
447+
448+}
--- /dev/null
+++ b/ShootingGame/GameStateMachine.h
@@ -0,0 +1,33 @@
1+#pragma once
2+namespace ShootingGame
3+{
4+
5+ namespace Event
6+ {
7+ struct Init{};
8+ struct PushStart {};
9+ struct PushSoundEdit {};
10+ struct TimeOut {};
11+ struct Update {};
12+ struct Render {};
13+ struct Escape {};
14+ }
15+
16+ ref class GameMain;
17+
18+ struct GameStateMachine {
19+ private:
20+ struct impl;
21+ public:
22+
23+ explicit GameStateMachine(GameMain^ main);
24+ template <class Event> void ProcessEvent(Event const& e);
25+ void Start();
26+ void Stop();
27+ ~GameStateMachine();
28+ private:
29+ std::unique_ptr<impl> impl_;
30+ };
31+
32+}
33+
--- a/ShootingGame/MainPage.xaml
+++ b/ShootingGame/MainPage.xaml
@@ -1,4 +1,4 @@
1-<Page
1+<common:LayoutAwarePage
22 x:Class="ShootingGame.MainPage"
33 IsTabStop="false"
44 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
@@ -6,17 +6,30 @@
66 xmlns:local="using:ShootingGame"
77 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
88 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
9- mc:Ignorable="d">
10- <SwapChainBackgroundPanel x:Name="DXSwapChainPanel">
11- <TextBlock HorizontalAlignment="Left" Height="23" Margin="486,24,0,0" TextWrapping="Wrap" Text="処理時間" VerticalAlignment="Top" Width="86" FontSize="20"/>
12- <TextBlock x:Name="processTime" HorizontalAlignment="Left" Height="23" Margin="572,24,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="121" FontSize="20"/>
13- <TextBlock HorizontalAlignment="Left" Height="23" Margin="773,24,0,0" TextWrapping="Wrap" Text="フレームレート" VerticalAlignment="Top" Width="139" FontSize="20"/>
14- <TextBlock x:Name="frameTime" HorizontalAlignment="Left" Height="23" Margin="917,24,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="121" FontSize="20"/>
15- <TextBlock HorizontalAlignment="Left" Height="23" Margin="773,52,0,0" TextWrapping="Wrap" Text="最大" VerticalAlignment="Top" Width="139" FontSize="20"/>
16- <TextBlock x:Name="frameTimeMax" HorizontalAlignment="Left" Height="23" Margin="917,52,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="121" FontSize="20"/>
17- <TextBlock HorizontalAlignment="Left" Height="23" Margin="773,80,0,0" TextWrapping="Wrap" Text="最小" VerticalAlignment="Top" Width="139" FontSize="20"/>
18- <TextBlock x:Name="frameTimeMin" HorizontalAlignment="Left" Height="23" Margin="917,80,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="121" FontSize="20"/>
19- <TextBlock HorizontalAlignment="Left" Height="23" Margin="773,108,0,0" TextWrapping="Wrap" Text="平均" VerticalAlignment="Top" Width="139" FontSize="20"/>
20- <TextBlock x:Name="frameTimeAvg" HorizontalAlignment="Left" Height="23" Margin="917,108,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="121" FontSize="20"/>
9+ xmlns:common="using:ShootingGame.Common"
10+
11+ mc:Ignorable="d" Foreground="#FFFBF5F5" >
12+ <SwapChainBackgroundPanel x:Name="DXSwapChainPanel" >
13+<Grid x:Name="RouteGrid">
14+ <Grid.RowDefinitions>
15+ <RowDefinition Height="109*"/>
16+ <RowDefinition Height="659*"/>
17+ </Grid.RowDefinitions>
18+ <Grid Grid.Row="0">
19+
20+ <TextBlock HorizontalAlignment="Left" Height="23" Margin="486,24,0,0" TextWrapping="Wrap" Text="処理時間" VerticalAlignment="Top" Width="86" FontSize="20"/>
21+ <TextBlock x:Name="processTime" HorizontalAlignment="Left" Height="23" Margin="572,24,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="121" FontSize="20"/>
22+ <TextBlock HorizontalAlignment="Left" Height="18" Margin="833,29,0,0" TextWrapping="Wrap" Text="フレームレート" VerticalAlignment="Top" Width="139" FontSize="12"/>
23+ <TextBlock x:Name="frameTime" HorizontalAlignment="Left" Height="18" Margin="977,29,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="121" FontSize="20"/>
24+ <TextBlock HorizontalAlignment="Left" Height="18" Margin="833,47,0,0" TextWrapping="Wrap" Text="最大" VerticalAlignment="Top" Width="139" FontSize="12"/>
25+ <TextBlock x:Name="frameTimeMax" HorizontalAlignment="Left" Height="18" Margin="977,47,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="121" FontSize="20"/>
26+ <TextBlock HorizontalAlignment="Left" Height="15" Margin="833,65,0,0" TextWrapping="Wrap" Text="最小" VerticalAlignment="Top" Width="139" FontSize="12"/>
27+ <TextBlock x:Name="frameTimeMin" HorizontalAlignment="Left" Height="15" Margin="977,65,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="121" FontSize="20"/>
28+ <TextBlock HorizontalAlignment="Left" Height="19" Margin="833,85,0,0" TextWrapping="Wrap" Text="平均" VerticalAlignment="Top" Width="139" FontSize="12"/>
29+ <TextBlock x:Name="frameTimeAvg" HorizontalAlignment="Left" Height="19" Margin="977,85,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="121" FontSize="12"/>
30+<Button Content="Button" HorizontalAlignment="Left" Margin="317,61,0,0" VerticalAlignment="Top" Click="Button_Click_1"/>
31+ </Grid>
32+ <UserControl x:Name="SubContent" Grid.Row="1" />
33+ </Grid>
2134 </SwapChainBackgroundPanel>
22-</Page>
35+</common:LayoutAwarePage >
--- a/ShootingGame/MainPage.xaml.cpp
+++ b/ShootingGame/MainPage.xaml.cpp
@@ -5,6 +5,7 @@
55
66 #include "pch.h"
77 #include "MainPage.xaml.h"
8+#include "SoundEditorPage.xaml.h"
89
910 using namespace ShootingGame;
1011
@@ -17,13 +18,28 @@ using namespace Windows::UI::Xaml::Controls::Primitives;
1718 using namespace Windows::UI::Xaml::Data;
1819 using namespace Windows::UI::Xaml::Input;
1920 using namespace Windows::UI::Xaml::Media;
21+using namespace Windows::UI::Xaml::Interop;
2022 using namespace Windows::UI::Xaml::Navigation;
2123
2224 // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
2325
2426 MainPage::MainPage()
2527 {
26- InitializeComponent();
28+ InitializeComponent();
29+
30+ hiddenFrame_ = ref new Windows::UI::Xaml::Controls::Frame();
31+ hiddenFrame_->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
32+ RouteGrid->Children->Append(hiddenFrame_);
33+ TypeName t = {ref new String(L"ShootingGame.SoundEditorPage"),TypeKind::Custom};
34+ if(!hiddenFrame_->Navigate(t,this))
35+ {
36+ throw ref new FailureException(ref new String(L"サウンドエディタに切り替えできませんでした。"));
37+ };
38+
39+ Page^ hiddenPage = safe_cast<Page^>(hiddenFrame_->Content);
40+ UIElement^ content = hiddenPage->Content;
41+ hiddenPage->Content = nullptr;
42+ SubContent->Content = content;
2743 }
2844
2945 /// <summary>
@@ -33,18 +49,45 @@ MainPage::MainPage()
3349 /// property is typically used to configure the page.</param>
3450 void MainPage::OnNavigatedTo(NavigationEventArgs^ e)
3551 {
36- (void) e; // Unused parameter
52+ (void) e; // Unused parameter
3753 }
3854
3955 void MainPage::UpdateProcessTime(float delta)
4056 {
41- processTime->Text = ref new String((boost::wformat(L"%1.4f") % delta).str().c_str());
57+ processTime->Text = ref new String((boost::wformat(L"%1.4f") % delta).str().c_str());
4258 }
4359
4460 void MainPage::UpdateFrameTime(float delta,float max,float min,float avg)
4561 {
46- frameTime->Text = ref new String((boost::wformat(L"%1.4f") % delta).str().c_str());
47- frameTimeMax->Text = ref new String((boost::wformat(L"%1.4f") % max).str().c_str());
48- frameTimeMin->Text = ref new String((boost::wformat(L"%1.4f") % min).str().c_str());
49- frameTimeAvg->Text = ref new String((boost::wformat(L"%1.4f") % avg).str().c_str());
62+ frameTime->Text = ref new String((boost::wformat(L"%1.4f") % delta).str().c_str());
63+ frameTimeMax->Text = ref new String((boost::wformat(L"%1.4f") % max).str().c_str());
64+ frameTimeMin->Text = ref new String((boost::wformat(L"%1.4f") % min).str().c_str());
65+ frameTimeAvg->Text = ref new String((boost::wformat(L"%1.4f") % avg).str().c_str());
5066 }
67+
68+
69+void ShootingGame::MainPage::Button_Click_1(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
70+{
71+ //TypeName t = {ref new String(L"ShootingGame.SoundEditorPage"),TypeKind::Custom};
72+ // if(!hiddenFrame_->Navigate(t,this))
73+ // {
74+ // throw ref new FailureException(ref new String(L"サウンドエディタに切り替えできませんでした。"));
75+ // };
76+
77+ // Page^ hiddenPage = safe_cast<Page^>(hiddenFrame_->Content);
78+ // UIElement^ content = hiddenPage->Content;
79+ // hiddenPage->Content = nullptr;
80+ // SubContent->Content = content;
81+
82+ //Grid^ grid = safe_cast<Grid^>(hiddenPage->FindName(L"LayoutRoot"));
83+ //if(grid != nullptr){
84+ //// Get each element.
85+ //UIElement^ c = safe_cast<UIElement^>(grid->FindName(L"Editor"));
86+ //UIElementCollection^ collection = grid->Children;
87+ //unsigned int index;
88+ //collection->IndexOf(c, &index);
89+ //collection->RemoveAt(index);
90+ //SubContent->Content = c;
91+ //}
92+
93+}
--- a/ShootingGame/MainPage.xaml.h
+++ b/ShootingGame/MainPage.xaml.h
@@ -4,7 +4,7 @@
44 //
55
66 #pragma once
7-
7+#include "Common\LayoutAwarePage.h"
88 #include "MainPage.g.h"
99
1010 namespace ShootingGame
@@ -25,5 +25,8 @@ namespace ShootingGame
2525
2626 protected:
2727 virtual void OnNavigatedTo(Windows::UI::Xaml::Navigation::NavigationEventArgs^ e) override;
28- };
28+ private:
29+ Windows::UI::Xaml::Controls::Frame^ hiddenFrame_;
30+ void Button_Click_1(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
31+ };
2932 }
--- a/ShootingGame/Package.appxmanifest
+++ b/ShootingGame/Package.appxmanifest
@@ -1,39 +1,27 @@
11 <?xml version="1.0" encoding="utf-8"?>
22 <Package xmlns="http://schemas.microsoft.com/appx/2010/manifest">
3-
4- <Identity Name="4237ad92-85a0-4a00-ad85-837bf7e456f4"
5- Publisher="CN=sfpgm_000"
6- Version="1.0.0.0" />
7-
3+ <Identity Name="4237ad92-85a0-4a00-ad85-837bf7e456f4" Publisher="CN=sfpgm_000" Version="1.0.0.0" />
84 <Properties>
95 <DisplayName>ShootingGame</DisplayName>
106 <PublisherDisplayName>sfpgm_000</PublisherDisplayName>
117 <Logo>Assets\StoreLogo.png</Logo>
128 </Properties>
13-
149 <Prerequisites>
1510 <OSMinVersion>6.2.0</OSMinVersion>
1611 <OSMaxVersionTested>6.2.0</OSMaxVersionTested>
1712 </Prerequisites>
18-
1913 <Resources>
20- <Resource Language="x-generate"/>
14+ <Resource Language="x-generate" />
2115 </Resources>
22-
2316 <Applications>
24- <Application Id="App"
25- Executable="$targetnametoken$.exe"
26- EntryPoint="ShootingGame.App">
27- <VisualElements
28- DisplayName="ShootingGame"
29- Logo="Assets\Logo.png"
30- SmallLogo="Assets\SmallLogo.png"
31- Description="ShootingGame"
32- ForegroundText="light"
33- BackgroundColor="#464646">
34- <DefaultTile ShowName="allLogos" />
35- <SplashScreen Image="Assets\SplashScreen.png" />
36- </VisualElements>
17+ <Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="ShootingGame.App">
18+ <VisualElements DisplayName="ShootingGame" Logo="Assets\Logo.png" SmallLogo="Assets\SmallLogo.png" Description="ShootingGame" ForegroundText="light" BackgroundColor="#464646">
19+ <DefaultTile ShowName="allLogos" />
20+ <SplashScreen Image="Assets\SplashScreen.png" />
21+ <InitialRotationPreference>
22+ <Rotation Preference="landscape" />
23+ </InitialRotationPreference>
24+ </VisualElements>
3725 </Application>
3826 </Applications>
3927 <Capabilities>
--- a/ShootingGame/ShootingGame.vcxproj
+++ b/ShootingGame/ShootingGame.vcxproj
@@ -115,7 +115,7 @@
115115 </ItemDefinitionGroup>
116116 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
117117 <ClCompile>
118- <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
118+ <AdditionalOptions>/bigobj /Zm1000 %(AdditionalOptions)</AdditionalOptions>
119119 </ClCompile>
120120 </ItemDefinitionGroup>
121121 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -131,11 +131,21 @@
131131 <ClInclude Include="BasicShapes.h" />
132132 <ClInclude Include="BasicSprites.h" />
133133 <ClInclude Include="BasicTimer.h" />
134+ <ClInclude Include="Common\BindableBase.h" />
135+ <ClInclude Include="Common\BooleanNegationConverter.h" />
136+ <ClInclude Include="Common\BooleanToVisibilityConverter.h" />
137+ <ClInclude Include="Common\LayoutAwarePage.h" />
138+ <ClInclude Include="Common\RichTextColumns.h" />
139+ <ClInclude Include="Common\SuspensionManager.h" />
134140 <ClInclude Include="DDSTextureLoader.h" />
135141 <ClInclude Include="DirectXBase.h" />
136142 <ClInclude Include="DirectXSample.h" />
143+ <ClInclude Include="EnvelopeEditorControl.xaml.h">
144+ <DependentUpon>EnvelopeEditorControl.xaml</DependentUpon>
145+ </ClInclude>
137146 <ClInclude Include="exception.h" />
138147 <ClInclude Include="GameMain.h" />
148+ <ClInclude Include=".\GameStateMachine.h" />
139149 <ClInclude Include="pch.h" />
140150 <ClInclude Include="App.xaml.h">
141151 <DependentUpon>App.xaml</DependentUpon>
@@ -148,6 +158,9 @@
148158 <ClInclude Include="sf_com.h" />
149159 <ClInclude Include="sf_memory.h" />
150160 <ClInclude Include="SoundDriver.h" />
161+ <ClInclude Include="SoundEditorPage.xaml.h">
162+ <DependentUpon>SoundEditorPage.xaml</DependentUpon>
163+ </ClInclude>
151164 <ClInclude Include="SoundManager.h" />
152165 <ClInclude Include="TestSong.h" />
153166 <ClInclude Include="WaveTableSynth.h" />
@@ -159,9 +172,16 @@
159172 <Page Include="Common\StandardStyles.xaml">
160173 <SubType>Designer</SubType>
161174 </Page>
175+ <Page Include="EnvelopeEditorControl.xaml">
176+ <SubType>Designer</SubType>
177+ </Page>
162178 <Page Include="MainPage.xaml">
163179 <SubType>Designer</SubType>
164180 </Page>
181+ <Page Include="SoundEditorPage.xaml">
182+ <SubType>Designer</SubType>
183+ </Page>
184+ <Page Include="Themes\Generic.xaml" />
165185 </ItemGroup>
166186 <ItemGroup>
167187 <AppxManifest Include="Package.appxmanifest">
@@ -189,9 +209,19 @@
189209 <ClCompile Include="BasicReaderWriter.cpp" />
190210 <ClCompile Include="BasicSprites.cpp" />
191211 <ClCompile Include="BasicTimer.cpp" />
212+ <ClCompile Include="Common\BindableBase.cpp" />
213+ <ClCompile Include="Common\BooleanNegationConverter.cpp" />
214+ <ClCompile Include="Common\BooleanToVisibilityConverter.cpp" />
215+ <ClCompile Include="Common\LayoutAwarePage.cpp" />
216+ <ClCompile Include="Common\RichTextColumns.cpp" />
217+ <ClCompile Include="Common\SuspensionManager.cpp" />
192218 <ClCompile Include="DDSTextureLoader.cpp" />
193219 <ClCompile Include="DirectXBase.cpp" />
220+ <ClCompile Include="EnvelopeEditorControl.xaml.cpp">
221+ <DependentUpon>EnvelopeEditorControl.xaml</DependentUpon>
222+ </ClCompile>
194223 <ClCompile Include="GameMain.cpp" />
224+ <ClCompile Include=".\GameStateMachine.cpp" />
195225 <ClCompile Include="MainPage.xaml.cpp">
196226 <DependentUpon>MainPage.xaml</DependentUpon>
197227 </ClCompile>
@@ -207,6 +237,9 @@
207237 <ClCompile Include="Sequencer.cpp" />
208238 <ClCompile Include="sf_com.cpp" />
209239 <ClCompile Include="SoundDriver.cpp" />
240+ <ClCompile Include="SoundEditorPage.xaml.cpp">
241+ <DependentUpon>SoundEditorPage.xaml</DependentUpon>
242+ </ClCompile>
210243 <ClCompile Include="SoundManager.cpp" />
211244 <ClCompile Include="TestSong.cpp" />
212245 <ClCompile Include="WaveTableSynth.cpp" />
@@ -215,24 +248,57 @@
215248 <FxCompile Include="BasicSprites.GeometryShader.gs.hlsl">
216249 <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">5.0</ShaderModel>
217250 <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Geometry</ShaderType>
251+ <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">5.0</ShaderModel>
252+ <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Geometry</ShaderType>
253+ <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Geometry</ShaderType>
254+ <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">5.0</ShaderModel>
255+ <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Geometry</ShaderType>
256+ <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">5.0</ShaderModel>
218257 </FxCompile>
219258 <FxCompile Include="BasicSprites.GeometryShader.vs.hlsl">
220259 <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Vertex</ShaderType>
221- <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">4.0</ShaderModel>
260+ <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">5.0</ShaderModel>
261+ <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Vertex</ShaderType>
262+ <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">5.0</ShaderModel>
263+ <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Vertex</ShaderType>
264+ <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">5.0</ShaderModel>
265+ <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Vertex</ShaderType>
266+ <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">5.0</ShaderModel>
222267 </FxCompile>
223268 <FxCompile Include="BasicSprites.Instancing.vs.hlsl">
224269 <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Vertex</ShaderType>
225- <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">4.0</ShaderModel>
270+ <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">5.0</ShaderModel>
271+ <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Vertex</ShaderType>
272+ <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">5.0</ShaderModel>
273+ <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Vertex</ShaderType>
274+ <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">5.0</ShaderModel>
275+ <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Vertex</ShaderType>
276+ <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">5.0</ShaderModel>
226277 </FxCompile>
227278 <FxCompile Include="BasicSprites.ps.hlsl">
228279 <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Pixel</ShaderType>
229- <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">4.0</ShaderModel>
280+ <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">5.0</ShaderModel>
281+ <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Pixel</ShaderType>
282+ <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">5.0</ShaderModel>
283+ <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Pixel</ShaderType>
284+ <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">5.0</ShaderModel>
285+ <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Pixel</ShaderType>
286+ <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">5.0</ShaderModel>
230287 </FxCompile>
231288 <FxCompile Include="BasicSprites.Replication.vs.hlsl">
232289 <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Vertex</ShaderType>
233- <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">4.0</ShaderModel>
290+ <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">5.0</ShaderModel>
291+ <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Vertex</ShaderType>
292+ <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">5.0</ShaderModel>
293+ <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Vertex</ShaderType>
294+ <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">5.0</ShaderModel>
295+ <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Vertex</ShaderType>
296+ <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">5.0</ShaderModel>
234297 </FxCompile>
235298 </ItemGroup>
299+ <ItemGroup>
300+ <Text Include="Common\ReadMe.txt" />
301+ </ItemGroup>
236302 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
237303 <ImportGroup Label="ExtensionTargets">
238304 </ImportGroup>
--- /dev/null
+++ b/ShootingGame/SoundEditorPage.xaml
@@ -0,0 +1,60 @@
1+<common:LayoutAwarePage
2+ x:Name="pageRoot"
3+ x:Class="ShootingGame.SoundEditorPage"
4+ DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}"
5+ IsTabStop="false"
6+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
7+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
8+ xmlns:local="using:ShootingGame"
9+ xmlns:common="using:ShootingGame.Common"
10+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
11+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
12+ mc:Ignorable="d">
13+
14+ <Page.Resources>
15+
16+ <!-- TODO: Delete this line if the key AppName is declared in App.xaml -->
17+ <x:String x:Key="AppName">My Application</x:String>
18+ </Page.Resources>
19+
20+ <!--
21+ This grid acts as a root panel for the page that defines two rows:
22+ * Row 0 contains the back button and page title
23+ * Row 1 contains the rest of the page layout
24+ -->
25+<!-- <Grid x:Name="LayoutRoot" Style="{StaticResource LayoutRootStyle}"> -->
26+<Grid x:Name="LayoutRoot" >
27+<local:EnvelopeEditorControl Margin="10,10.5,902,546.052" Height="Auto" Width="Auto"/>
28+ <TextBlock HorizontalAlignment="Left" Height="90" Margin="697.956,31.955,0,0" TextWrapping="Wrap" Text="Sound Editor Page" VerticalAlignment="Top" Width="221"/>
29+
30+ <VisualStateManager.VisualStateGroups>
31+
32+ <!-- Visual states reflect the application's view state -->
33+ <VisualStateGroup x:Name="ApplicationViewStates">
34+ <VisualState x:Name="FullScreenLandscape"/>
35+ <VisualState x:Name="Filled"/>
36+
37+ <!-- The entire page respects the narrower 100-pixel margin convention for portrait -->
38+ <VisualState x:Name="FullScreenPortrait">
39+ <Storyboard>
40+ <ObjectAnimationUsingKeyFrames Storyboard.TargetName="backButton" Storyboard.TargetProperty="Style">
41+ <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PortraitBackButtonStyle}"/>
42+ </ObjectAnimationUsingKeyFrames>
43+ </Storyboard>
44+ </VisualState>
45+
46+ <!-- The back button and title have different styles when snapped -->
47+ <VisualState x:Name="Snapped">
48+ <Storyboard>
49+ <ObjectAnimationUsingKeyFrames Storyboard.TargetName="backButton" Storyboard.TargetProperty="Style">
50+ <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource SnappedBackButtonStyle}"/>
51+ </ObjectAnimationUsingKeyFrames>
52+ <ObjectAnimationUsingKeyFrames Storyboard.TargetName="pageTitle" Storyboard.TargetProperty="Style">
53+ <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource SnappedPageHeaderTextStyle}"/>
54+ </ObjectAnimationUsingKeyFrames>
55+ </Storyboard>
56+ </VisualState>
57+ </VisualStateGroup>
58+ </VisualStateManager.VisualStateGroups>
59+ </Grid>
60+</common:LayoutAwarePage>
--- /dev/null
+++ b/ShootingGame/SoundEditorPage.xaml.cpp
@@ -0,0 +1,53 @@
1+//
2+// SoundEditorPage.xaml.cpp
3+// Implementation of the SoundEditorPage class
4+//
5+
6+#include "pch.h"
7+#include "SoundEditorPage.xaml.h"
8+
9+using namespace ShootingGame;
10+
11+using namespace Platform;
12+using namespace Windows::Foundation;
13+using namespace Windows::Foundation::Collections;
14+using namespace Windows::UI::Xaml;
15+using namespace Windows::UI::Xaml::Controls;
16+using namespace Windows::UI::Xaml::Controls::Primitives;
17+using namespace Windows::UI::Xaml::Data;
18+using namespace Windows::UI::Xaml::Input;
19+using namespace Windows::UI::Xaml::Media;
20+using namespace Windows::UI::Xaml::Navigation;
21+
22+// The Basic Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234237
23+
24+SoundEditorPage::SoundEditorPage()
25+{
26+ InitializeComponent();
27+}
28+
29+/// <summary>
30+/// Populates the page with content passed during navigation. Any saved state is also
31+/// provided when recreating a page from a prior session.
32+/// </summary>
33+/// <param name="navigationParameter">The parameter value passed to
34+/// <see cref="Frame::Navigate(Type, Object)"/> when this page was initially requested.
35+/// </param>
36+/// <param name="pageState">A map of state preserved by this page during an earlier
37+/// session. This will be null the first time a page is visited.</param>
38+void SoundEditorPage::LoadState(Object^ navigationParameter, IMap<String^, Object^>^ pageState)
39+{
40+ (void) navigationParameter; // Unused parameter
41+ (void) pageState; // Unused parameter
42+}
43+
44+/// <summary>
45+/// Preserves state associated with this page in case the application is suspended or the
46+/// page is discarded from the navigation cache. Values must conform to the serialization
47+/// requirements of <see cref="SuspensionManager::SessionState"/>.
48+/// </summary>
49+/// <param name="pageState">An empty map to be populated with serializable state.</param>
50+void SoundEditorPage::SaveState(IMap<String^, Object^>^ pageState)
51+{
52+ (void) pageState; // Unused parameter
53+}
--- /dev/null
+++ b/ShootingGame/SoundEditorPage.xaml.h
@@ -0,0 +1,26 @@
1+//
2+// SoundEditorPage.xaml.h
3+// Declaration of the SoundEditorPage class
4+//
5+
6+#pragma once
7+
8+#include "Common\LayoutAwarePage.h" // Required by generated header
9+#include "SoundEditorPage.g.h"
10+
11+namespace ShootingGame
12+{
13+ /// <summary>
14+ /// A basic page that provides characteristics common to most applications.
15+ /// </summary>
16+ public ref class SoundEditorPage sealed
17+ {
18+ public:
19+ SoundEditorPage();
20+
21+ protected:
22+ virtual void LoadState(Platform::Object^ navigationParameter,
23+ Windows::Foundation::Collections::IMap<Platform::String^, Platform::Object^>^ pageState) override;
24+ virtual void SaveState(Windows::Foundation::Collections::IMap<Platform::String^, Platform::Object^>^ pageState) override;
25+ };
26+}
--- /dev/null
+++ b/ShootingGame/SoundManager.cpp
@@ -0,0 +1,40 @@
1+#include "pch.h"
2+#include "SoundManager.h"
3+using namespace std::placeholders;
4+
5+namespace sf {
6+SoundManager::SoundManager(SoundDriver& driver) : driver_(driver),synth_(driver_.Format()),sequencer_(synth_,driver_.Format())
7+{
8+ sequencer_.Tempo(150.0f);
9+ TestSong song(sequencer_.SequenceTracks());
10+ driver_.SetProcessBufferFunc(std::bind(&SoundManager::ProcessBuffer,this,_1,_2));
11+}
12+
13+void SoundManager::ProcessBuffer(boost::shared_array<float> arr,int bufferSize)
14+{
15+ // 今のところ出力はステレオ前提
16+ //for(int j = 0;j < voices_.size();++j)
17+ //{
18+ // voices_[j].Process(buffer);
19+ // *ptr += buffer[0];
20+ // *(ptr + 1) += buffer[1];
21+ //}
22+ float *ptr = arr.get();
23+
24+ ZeroMemory(ptr,sizeof(float) * bufferSize * 2);
25+
26+ for(int i = 0;i < bufferSize;++i)
27+ {
28+ sequencer_.Process();
29+ synth_.Process(ptr);
30+ ptr += 2;
31+ }
32+
33+}
34+
35+
36+
37+SoundManager::~SoundManager()
38+{
39+}
40+}
--- /dev/null
+++ b/ShootingGame/SoundManager.h
@@ -0,0 +1,22 @@
1+#pragma once
2+
3+#include "SoundDriver.h"
4+#include "WaveTableSynth.h"
5+#include "Sequencer.h"
6+#include "TestSong.h"
7+
8+namespace sf {
9+ struct SoundManager
10+ {
11+ SoundManager(SoundDriver& driver);
12+ void ProcessBuffer(boost::shared_array<float> arr,int bufferSize);
13+ virtual ~SoundManager();
14+ sf::Synthesizer& SoundManager::Synthesizer() {return synth_;}
15+ sf::Sequencer& SoundManager::Sequencer() {return sequencer_;}
16+ private:
17+ SoundDriver& driver_;
18+ sf::Synthesizer synth_;
19+ sf::Sequencer sequencer_;
20+ };
21+}
22+
--- /dev/null
+++ b/ShootingGame/Themes/Generic.xaml
@@ -0,0 +1,19 @@
1+<ResourceDictionary
2+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4+ xmlns:local="using:ShootingGame">
5+
6+ <Style TargetType="local:EnvelopeEditorControl">
7+ <Setter Property="Template">
8+ <Setter.Value>
9+ <ControlTemplate TargetType="local:EnvelopeEditorControl">
10+ <Border
11+ Background="{TemplateBinding Background}"
12+ BorderBrush="{TemplateBinding BorderBrush}"
13+ BorderThickness="{TemplateBinding BorderThickness}">
14+ </Border>
15+ </ControlTemplate>
16+ </Setter.Value>
17+ </Setter>
18+ </Style>
19+</ResourceDictionary>
--- a/ShootingGame/WaveTableSynth.cpp
+++ b/ShootingGame/WaveTableSynth.cpp
@@ -1011,6 +1011,12 @@ namespace sf {
10111011 bool isEnable() const {return isEnable_;}
10121012 void isEnable(bool v) {isEnable_ = v;}
10131013
1014+ void Clear()
1015+ {
1016+ WaveTable::WaveTables.clear();
1017+ programs_.clear();
1018+ }
1019+
10141020 private:
10151021 bool isEnable_;
10161022 WAVEFORMATEXTENSIBLE format_;
@@ -1099,4 +1105,9 @@ namespace sf {
10991105 impl_->isEnable(v);
11001106 }
11011107
1108+ void Synthesizer::Clear()
1109+ {
1110+ impl_->Clear();
1111+ }
1112+
11021113 }
--- a/ShootingGame/WaveTableSynth.h
+++ b/ShootingGame/WaveTableSynth.h
@@ -669,6 +669,8 @@ namespace sf {
669669 bool isEnable() const ;
670670 void isEnable(bool v);
671671
672+ void Clear();
673+
672674 private:
673675 struct impl;
674676 std::unique_ptr<impl> impl_;
Show on old repository browser