OSDN Git Service

航路管理画面を実装。
[gvonavish/GVONavish.git] / GVONavish / GVONavish / GVONavish.cpp
index a557043..489403a 100644 (file)
 #pragma comment(lib, "Comdlg32.lib")
 
 
+
 #include "GVONavish.h"
 #include "GVOConfig.h"
 #include "GVOGameProcess.h"
 #include "GVOWorldMap.h"
 #include "GVOShip.h"
-
-
+#include "GVOShipRouteList.h"
+#include "GVORenderer.h"
+#include "GVOTexture.h"
+#include "GVOShipRouteManageView.h"
 
 
 // \83f\83o\83b\83O\8e\9e\82Ì\95`\89æ\83p\83t\83H\81[\83}\83\93\83X\91ª\92è\97p\81B
@@ -64,12 +67,13 @@ static void s_updateWindowTitle( HWND, POINT, double );
 static void s_toggleKeepForeground( HWND );
 static void s_popupMenu( HWND, int16_t, int16_t );
 static void s_popupCoord( HWND, int16_t, int16_t );
+static void s_closeShipRoute();
 
 
 // \83\8d\81[\83J\83\8b\95Ï\90\94
 static LPCWSTR const k_appName = L"GVONavi\81i\82Á\82Û\82¢\89½\82©\81j";             // \83A\83v\83\8a\83P\81[\83V\83\87\83\93\96¼
-static LPCWSTR const k_version = L"ver 1.0.1";                                 // \83o\81[\83W\83\87\83\93\94Ô\8d\86
-static LPCWSTR const k_copyright = L"copyright(c) mandheling"; // \92\98\8dì\8c \95\\8e¦\81i\82¢\82¿\82¨\81[\81j
+static LPCWSTR const k_version = L"ver 1.2";                                   // \83o\81[\83W\83\87\83\93\94Ô\8d\86
+static LPCWSTR const k_copyright = L"copyright(c) @MandhelingFreak";   // \92\98\8dì\8c \95\\8e¦\81i\82¢\82¿\82¨\81[\81j
 
 static LPCWSTR const k_windowClassName = L"GVONavish";         // \83\81\83C\83\93 \83E\83B\83\93\83h\83\83N\83\89\83X\96¼
 static const LPCWSTR k_configFileName = L"GVONavish.ini";      // \90Ý\92è\83t\83@\83C\83\8b\96¼
@@ -85,7 +89,16 @@ static GVOConfig s_config( k_configFileName );
 static GVOGameProcess s_gvoGameProcess;
 static GVORenderer s_renderer;
 static GVOWorldMap s_worldMap;
+static std::unique_ptr<GVOShipRouteList> s_shipRouteList;
 static POINT s_latestSurveyCoord;
+static GVOVector s_latestShipVector;
+static double s_latestShipVelocity;
+static DWORD s_latestTimeStamp;
+static const DWORD k_surveyCoordLostThreshold = 5000;
+static std::unique_ptr<GVOShipRouteManageView> s_shipRouteManageView;
+
+//\88ê\8e\9e\92u\82«
+static std::unique_ptr<GVOTexture> s_shipTexture;
 
 static UINT s_pollingInterval = 1000;  // \8fó\91Ô\8aÄ\8e\8b\8aÔ\8au\81i1\95b\81j
 static bool s_isDragging = false;              // \83h\83\89\83b\83O\8fó\91Ô\83t\83\89\83O
@@ -123,7 +136,7 @@ int APIENTRY _tWinMain( _In_ HINSTANCE hInstance,
        TIMECAPS tc;
        ::timeGetDevCaps( &tc, sizeof(tc) );
        ::timeBeginPeriod( tc.wPeriodMin );
-       INITCOMMONCONTROLSEX icc = { sizeof(icc), ICC_WIN95_CLASSES };
+       INITCOMMONCONTROLSEX icc = { sizeof(icc), ICC_WIN95_CLASSES | ICC_STANDARD_CLASSES };
        ::InitCommonControlsEx( &icc );
        GdiplusStartup( &s_gdiToken, &s_gdisi, NULL );
        s_config.load();
@@ -157,7 +170,7 @@ static ATOM MyRegisterClass( HINSTANCE hInstance )
        wcex.hIcon = LoadIcon( hInstance, MAKEINTRESOURCE( IDR_MAINFRAME ) );
        wcex.hCursor = LoadCursor( NULL, IDC_ARROW );
        wcex.hbrBackground = (HBRUSH)::GetStockObject( BLACK_BRUSH );
-       //wcex.lpszMenuName     = MAKEINTRESOURCE(IDC_GVONAVISH);
+       wcex.lpszMenuName       = MAKEINTRESOURCE(IDR_MAINFRAME);
        wcex.lpszClassName = k_windowClassName;
        wcex.hIconSm = LoadIcon( wcex.hInstance, MAKEINTRESOURCE( IDI_SMALL ) );
 
@@ -177,7 +190,6 @@ static BOOL InitInstance( HINSTANCE hInstance, int nCmdShow )
                }
                s_config.m_mapFileName = fileName;
        }
-       s_renderer.setWorldMap( s_worldMap );
 
        HWND hwnd;
 
@@ -202,11 +214,12 @@ static BOOL InitInstance( HINSTANCE hInstance, int nCmdShow )
 
        g_hwndMain = hwnd;
        g_hdcMain = ::GetDC( g_hwndMain );
-       s_renderer.setup( g_hdcMain );
 
+       s_renderer.setup( &s_config, g_hdcMain, &s_worldMap );
+
+       s_shipRouteList.reset( new GVOShipRouteList() );
        s_pollingInterval = s_config.m_pollingInterval;
        s_gvoGameProcess.setup( s_config );
-       s_renderer.setConfig( s_config );
 
        s_updateWindowTitle( hwnd, s_config.m_initialSurveyCoord, s_renderer.viewScale() );
 
@@ -221,7 +234,7 @@ static LRESULT s_mainLoop()
        MSG msg;
        HACCEL hAccelTable;
 
-       hAccelTable = LoadAccelerators( g_hinst, MAKEINTRESOURCE( IDC_GVONAVISH ) );
+       hAccelTable = LoadAccelerators( g_hinst, MAKEINTRESOURCE( IDR_MAINFRAME ) );
 
        for ( ;; ) {
                if ( ::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) {
@@ -282,6 +295,10 @@ LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wp, LPARAM lp )
                s_onPaint( hwnd );
                break;
 
+       case WM_TIMER:
+               s_updateFrame( hwnd );
+               break;
+
        case WM_MOVE:
                s_onMove( hwnd, int16_t( LOWORD( lp ) ), int16_t( HIWORD( lp ) ) );
                break;
@@ -308,7 +325,7 @@ LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wp, LPARAM lp )
                        s_renderer.enableTraceShip( s_config.m_traceShipPositionEnabled );
                        break;
                case IDM_ERASE_SHIP_ROUTE:
-                       s_renderer.clearShipRoute();
+                       s_shipRouteList->clearAllItems();
                        break;
                case IDM_TOGGLE_KEEP_FOREGROUND:
                        s_toggleKeepForeground( hwnd );
@@ -345,11 +362,33 @@ LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wp, LPARAM lp )
                                ::InvalidateRect( hwnd, NULL, FALSE );
                        }
                        break;
+               case IDM_SHOW_SHIPROUTEMANAGEVIEW:
+                       if ( !s_shipRouteManageView.get() ) {
+                               s_shipRouteManageView.reset( new GVOShipRouteManageView() );
+                               if ( !s_shipRouteManageView->setup( *s_shipRouteList.get() ) ) {
+                                       ::MessageBox( hwnd, L"\82È\82ñ\82©\82¦\82ç\81[\82Å\82·", L"\83G\83\89\81[", MB_OK | MB_ICONERROR );
+                               }
+                       }
+                       else {
+                               s_shipRouteManageView->activate();
+                       }
+                       break;
 #ifndef NDEBUG
                case IDM_TOGGLE_DEBUG_AUTO_CRUISE:
                        s_config.m_debugAutoCruiseEnabled = !s_config.m_debugAutoCruiseEnabled;
                        s_gvoGameProcess.enableDebugAutoCruise( s_config.m_debugAutoCruiseEnabled );
                        break;
+               case IDM_DEBUG_CLOSE_ROUTE:
+                       s_closeShipRoute();
+                       break;
+               case IDM_DEBUG_INTERVAL_NORMAL:
+                       s_pollingInterval = 1000;
+                       s_gvoGameProcess.setPollingInterval( s_pollingInterval );
+                       break;
+               case IDM_DEBUG_INTERVAL_HIGH:
+                       s_pollingInterval = 1;
+                       s_gvoGameProcess.setPollingInterval( s_pollingInterval );
+                       break;
 #endif
 
                default:
@@ -382,6 +421,9 @@ LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wp, LPARAM lp )
                }
                break;
        case WM_DESTROY:
+               if ( s_shipRouteManageView.get() ) {
+                       s_shipRouteManageView.reset();
+               }
                s_renderer.teardown();
                PostQuitMessage( 0 );
                break;
@@ -539,7 +581,7 @@ static void s_onPaint( HWND hwnd )
        const int64_t perfBegin = g_queryPerformanceCounter();
 #endif
 
-       s_renderer.render();
+       s_renderer.render( s_latestShipVector, s_latestShipVelocity, s_shipTexture.get(), s_shipRouteList.get() );
        ::ValidateRect( hwnd, NULL );
 
 #ifdef GVO_PERF_CHECK
@@ -600,11 +642,26 @@ static void s_updateFrame( HWND hwnd )
                return;
        }
 
+       // \83Q\81[\83\80\83v\83\8d\83Z\83X\82Ì\83A\83C\83R\83\93\83e\83N\83X\83`\83\83\81[\82ª\96¢\8dì\90¬\82È\82ç\82Î\8dì\90¬\82ð\8e\8e\82Ý\82é
+       if ( !s_shipTexture.get() ) {
+               const GVOImage * image = s_gvoGameProcess.shipIconImage();
+               if ( image ) {
+                       s_shipTexture.reset( s_renderer.createTextureFromImage( *image ) );
+               }
+       }
+
        for ( std::vector<GVOGameStatus>::const_iterator it = gameStats.begin(); it != gameStats.end(); ++it ) {
                const GVOGameStatus& status = *it;
                s_latestSurveyCoord = status.m_surveyCoord;
+               s_latestShipVector = status.m_shipVector;
+               s_latestShipVelocity = status.m_shipVelocity;
                s_config.m_initialSurveyCoord = s_latestSurveyCoord;
-               s_renderer.updateShipState( s_latestSurveyCoord, status.m_shipVector, status.m_shipVelocity );
+               s_renderer.setShipPositionInWorld( s_latestSurveyCoord );
+               if ( (s_latestTimeStamp + k_surveyCoordLostThreshold) <= status.m_timeStamp ) {
+                       s_closeShipRoute();
+               }
+               s_latestTimeStamp = status.m_timeStamp;
+               s_shipRouteList->addRoutePoint( s_worldMap.normalizedPoint( s_latestSurveyCoord ) );
        }
 #ifndef GVO_PERF_CHECK
        s_updateWindowTitle( hwnd, s_latestSurveyCoord, s_renderer.viewScale() );
@@ -640,7 +697,7 @@ static void s_toggleKeepForeground( HWND hwnd )
 
 static void s_popupMenu( HWND hwnd, int16_t x, int16_t y )
 {
-       HMENU hmenu = ::LoadMenu( g_hinst, MAKEINTRESOURCE( IDC_POPUPMENU ) );
+       HMENU hmenu = ::LoadMenu( g_hinst, MAKEINTRESOURCE( IDR_POPUPMENU ) );
        HMENU popupMenu = ::GetSubMenu( hmenu, 0 );
 
        ::CheckMenuItem( popupMenu, IDM_TOGGLE_TRACE_SHIP, s_config.m_traceShipPositionEnabled ? MF_CHECKED : MF_UNCHECKED );
@@ -652,23 +709,46 @@ static void s_popupMenu( HWND hwnd, int16_t x, int16_t y )
        MENUITEMINFO mii = { sizeof(mii) };
        mii.fMask = MIIM_TYPE | MIIM_ID;
        mii.fType = MFT_STRING;
+
+       // \83f\83o\83b\83O\97p\8e©\93®\8dq\8ds\82Ì\90Ø\82è\91Ö\82¦
        mii.wID = IDM_TOGGLE_DEBUG_AUTO_CRUISE;
        mii.dwTypeData = L"[DEBUG]\8e©\93®\8dq\8ds\82ð\97L\8cø";
        ::InsertMenuItem( popupMenu, ::GetMenuItemCount( popupMenu ), TRUE, &mii );
-       
        ::CheckMenuItem( popupMenu, IDM_TOGGLE_DEBUG_AUTO_CRUISE, s_config.m_debugAutoCruiseEnabled ? MF_CHECKED : MF_UNCHECKED );
+
+       mii.wID = IDM_DEBUG_CLOSE_ROUTE;
+       mii.dwTypeData = L"[DEBUG]\8dq\98H\82ð\95Â\82\82é";
+       ::InsertMenuItem( popupMenu, ::GetMenuItemCount( popupMenu ), TRUE, &mii );
+
+       mii.wID = IDM_DEBUG_INTERVAL_NORMAL;
+       mii.dwTypeData = L"[DEBUG]\8dX\90V\8aÔ\8au - \95W\8f\80";
+       ::InsertMenuItem( popupMenu, ::GetMenuItemCount( popupMenu ), TRUE, &mii );
+
+       mii.wID = IDM_DEBUG_INTERVAL_HIGH;
+       mii.dwTypeData = L"[DEBUG]\8dX\90V\8aÔ\8au - \8d\82\95p\93x";
+       ::InsertMenuItem( popupMenu, ::GetMenuItemCount( popupMenu ), TRUE, &mii );
 #endif
 
+       // \83\81\83j\83\85\81[\95\\8e¦\92\86\82Í\83\81\83b\83Z\81[\83W\83|\83\93\83v\82©\82ç\94²\82¯\82ç\82ê\82È\82¢\82Ì\82Å\83^\83C\83}\81[\82Å\8dX\90V\82ð\8aÄ\8e\8b\82µ\82Ä\82¨\82­\81B
+       const UINT_PTR timerID = ::SetTimer( hwnd, 0, s_pollingInterval, NULL );
+       s_updateFrame( hwnd );
+
        POINT p = { x, y };
        ::ClientToScreen( hwnd, &p );
        ::TrackPopupMenu( popupMenu, TPM_NONOTIFY | TPM_NOANIMATION | TPM_LEFTALIGN | TPM_TOPALIGN,
                p.x, p.y, 0, hwnd, NULL );
-
        ::DestroyMenu( popupMenu );
+
+       ::KillTimer( hwnd, timerID );
 }
 
 
 static void s_popupCoord( HWND hwnd, int16_t x, int16_t y )
 {
+}
+
 
+static void s_closeShipRoute()
+{
+       s_shipRouteList->closeRoute();
 }