Browse Source

WinRT enhancement

1. The render code is slightly refactored, so that aspect ratio is kept, the blank ranges are also rendered with blank.
2. Treat close & open operation as normal exit rhather than abnormal exit.
louyihua 8 years ago
parent
commit
12fb55e489

+ 14 - 13
util.c

@@ -290,7 +290,7 @@ TerminateOnError(
 {
    va_list argptr;
    char string[256];
-   extern VOID PAL_Shutdown(VOID);
+   extern VOID PAL_Shutdown(int);
 
    // concatenate all the arguments in one string
    va_start(argptr, fmt);
@@ -301,8 +301,18 @@ TerminateOnError(
 
 #if SDL_VERSION_ATLEAST(2, 0, 0)
    {
-      extern SDL_Window *gpWindow;
-      SDL_ShowSimpleMessageBox(0, "FATAL ERROR", string, gpWindow);
+	  extern SDL_Window *gpWindow;
+	  char buffer[300];
+	  SDL_MessageBoxButtonData buttons[2] = { { 0, 0, "Yes" },{ 0, 1, "No" } };
+	  SDL_MessageBoxData mbd = { SDL_MESSAGEBOX_ERROR, gpWindow, "FATAL ERROR", buffer, 2, buttons, NULL };
+	  int btnid;
+	  sprintf(buffer, "%sLaunch setting dialog on next start?\n", string);
+	  if (SDL_ShowMessageBox(&mbd, &btnid) == 0 && btnid == 0)
+	  {
+		  gConfig.fLaunchSetting = TRUE;
+		  PAL_SaveConfig();
+	  }
+	  PAL_Shutdown(255);
    }
 #else
 
@@ -416,16 +426,7 @@ UTIL_OpenRequiredFileForMode(
 
    if (fp == NULL)
    {
-	   extern SDL_Window *gpWindow;
-	   SDL_MessageBoxButtonData buttons[2] = { { 0, 0, "Yes" }, { 0, 1, "No"} };
-	   SDL_MessageBoxData mbd = { SDL_MESSAGEBOX_ERROR, gpWindow, "FATAL ERROR", va("File open error(%d): %s!\nLaunch setting dialog on next start?\n", errno, lpszFileName), 2, buttons, NULL };
-	   int btnid;
-	   if (SDL_ShowMessageBox(&mbd, &btnid) == 0 && btnid == 0)
-	   {
-		   gConfig.fLaunchSetting = TRUE;
-		   PAL_SaveConfig();
-	   }
-	   PAL_Shutdown(255);
+	   TerminateOnError("File open error(%d): %s!\n", errno, lpszFileName);
    }
 
    return fp;

+ 107 - 35
video.c

@@ -34,8 +34,8 @@ static SDL_Texture       *gpTexture          = NULL;
 # if PAL_HAS_TOUCH
 static SDL_Texture       *gpTouchOverlay     = NULL;
 # endif
-static SDL_Rect          *gpRenderRect       = NULL;
-static SDL_Rect           gRenderRect;
+static SDL_Rect           gOverlayRect;
+static SDL_Rect           gTextureRect;
 #endif
 
 // The real screen surface
@@ -57,6 +57,58 @@ static WORD               g_wShakeLevel      = 0;
 #define SDL_SoftStretch SDL_UpperBlit
 #endif
 
+static SDL_Texture *VIDEO_CreateTexture(int width, int height)
+{
+	int texture_width, texture_height;
+	float ratio = (float)width / (float)height;
+	//
+	// Check whether to keep the aspect ratio
+	//
+	if (gConfig.fKeepAspectRatio && ratio != 1.6f)
+	{
+		if (ratio > 1.6f)
+		{
+			texture_height = 200;
+			texture_width = (int)(200 * ratio) & ~0x3;
+			ratio = (float)height / 200.0f;
+		}
+		else
+		{
+			texture_width = 320;
+			texture_height = (int)(320 / ratio) & ~0x3;
+			ratio = (float)width / 320.0f;
+		}
+
+		WORD w = (WORD)(ratio * 320.0f) & ~0x3;
+		WORD h = (WORD)(ratio * 200.0f) & ~0x3;
+		gOverlayRect.x = (width - w) / 2;
+		gOverlayRect.y = (height - h) / 2;
+		gOverlayRect.w = w;
+		gOverlayRect.h = h;
+		gTextureRect.x = (texture_width - 320) / 2;
+		gTextureRect.y = (texture_height - 200) / 2;
+		gTextureRect.w = 320; gTextureRect.h = 200;
+# if PAL_HAS_TOUCH
+		PAL_SetTouchBounds(width, height, gOverlayRect);
+# endif
+	}
+	else
+	{
+		texture_width = 320;
+		texture_height = 200;
+		gOverlayRect.x = gOverlayRect.y = 0;
+		gOverlayRect.w = width;
+		gOverlayRect.h = height;
+		gTextureRect.x = gTextureRect.y = 0;
+		gTextureRect.w = 320; gTextureRect.h = 200;
+	}
+
+	//
+	// Create texture for screen.
+	//
+	return SDL_CreateTexture(gpRenderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, texture_width, texture_height);
+}
+
 INT
 VIDEO_Startup(
    VOID
@@ -112,8 +164,7 @@ VIDEO_Startup(
    //
    // Create texture for screen.
    //
-   gpTexture = SDL_CreateTexture(gpRenderer, SDL_PIXELFORMAT_ARGB8888,
-							  SDL_TEXTUREACCESS_STREAMING, 320, 200);
+   gpTexture = VIDEO_CreateTexture(gConfig.dwScreenWidth, gConfig.dwScreenHeight);
 
    //
    // Failed?
@@ -176,29 +227,29 @@ VIDEO_Startup(
    //
    // Check whether to keep the aspect ratio
    //
-   if (gConfig.fKeepAspectRatio)
-   {
-	   float ax = (float)gConfig.dwScreenWidth / 320.0f;
-	   float ay = (float)gConfig.dwScreenHeight / 200.0f;
-	   if (ax != ay)
-	   {
-		   float ratio = (ax > ay) ? ay : ax;
-		   WORD w = (WORD)(ratio * 320.0f);
-		   WORD h = (WORD)(ratio * 200.0f);
-		   if (w % 4 != 0) w &= ~0x3;
-		   if (h % 4 != 0) h &= ~0x3;
-		   gRenderRect.x = (gConfig.dwScreenWidth - w) / 2;
-		   gRenderRect.y = (gConfig.dwScreenHeight - h) / 2;
-		   gRenderRect.w = w;
-		   gRenderRect.h = h;
-		   gpRenderRect = &gRenderRect;
-# if PAL_HAS_TOUCH
-		   PAL_SetTouchBounds(gConfig.dwScreenWidth, gConfig.dwScreenHeight, gRenderRect);
-# endif
-	   }
-   }
-   else
-	   gpRenderRect = NULL;
+//   if (gConfig.fKeepAspectRatio)
+//   {
+//	   float ax = (float)gConfig.dwScreenWidth / 320.0f;
+//	   float ay = (float)gConfig.dwScreenHeight / 200.0f;
+//	   if (ax != ay)
+//	   {
+//		   float ratio = (ax > ay) ? ay : ax;
+//		   WORD w = (WORD)(ratio * 320.0f);
+//		   WORD h = (WORD)(ratio * 200.0f);
+//		   if (w % 4 != 0) w &= ~0x3;
+//		   if (h % 4 != 0) h &= ~0x3;
+//		   gOverlayRect.x = (gConfig.dwScreenWidth - w) / 2;
+//		   gOverlayRect.y = (gConfig.dwScreenHeight - h) / 2;
+//		   gOverlayRect.w = w;
+//		   gOverlayRect.h = h;
+//		   gpRenderRect = &gOverlayRect;
+//# if PAL_HAS_TOUCH
+//		   PAL_SetTouchBounds(gConfig.dwScreenWidth, gConfig.dwScreenHeight, gOverlayRect);
+//# endif
+//	   }
+//   }
+//   else
+//	   gpRenderRect = NULL;
 #else
 
    //
@@ -342,15 +393,33 @@ VIDEO_RenderCopy(
    VOID
 )
 {
-   SDL_UpdateTexture(gpTexture, NULL, gpScreenReal->pixels, gpScreenReal->pitch);
-   SDL_RenderCopy(gpRenderer, gpTexture, NULL, gpRenderRect);
+	void *texture_pixels;
+	int texture_pitch;
+	SDL_LockTexture(gpTexture, NULL, &texture_pixels, &texture_pitch);
+
+	memset(texture_pixels, 0, gTextureRect.y * texture_pitch);
+	uint8_t *pixels = (uint8_t *)texture_pixels + gTextureRect.y * texture_pitch;
+	uint8_t *src = (uint8_t *)gpScreenReal->pixels;
+	int left_pitch = gTextureRect.x << 2;
+	int right_pitch = texture_pitch - ((gTextureRect.x + gTextureRect.w) << 2);
+	for (int y = 0; y < gTextureRect.h; y++, src += gpScreenReal->pitch)
+	{
+		memset(pixels, 0, left_pitch); pixels += left_pitch;
+		memcpy(pixels, src, 320 << 2); pixels += 320 << 2;
+		memset(pixels, 0, right_pitch); pixels += right_pitch;
+	}
+	memset(pixels, 0, gTextureRect.y * texture_pitch);
+	//SDL_UpdateTexture(gpTexture, NULL, gpScreenReal->pixels, gpScreenReal->pitch);
+	SDL_UnlockTexture(gpTexture);
+
+	SDL_RenderCopy(gpRenderer, gpTexture, NULL, NULL);
 #if PAL_HAS_TOUCH
-   if (gpTouchOverlay)
-   {
-      SDL_RenderCopy(gpRenderer, gpTouchOverlay, NULL, gpRenderRect);
-   }
+	if (gpTouchOverlay)
+	{
+		SDL_RenderCopy(gpRenderer, gpTouchOverlay, NULL, &gOverlayRect);
+	}
 #endif
-   SDL_RenderPresent(gpRenderer);
+	   SDL_RenderPresent(gpRenderer);
 }
 #endif
 
@@ -568,7 +637,10 @@ VIDEO_Resize(
 --*/
 {
 #if SDL_VERSION_ATLEAST(2,0,0)
-   // TODO
+	if (gpTexture) SDL_DestroyTexture(gpTexture);
+	gpTexture = VIDEO_CreateTexture(w, h);
+	if (gpTexture == NULL)
+		TerminateOnError("Re-creating texture failed on window resize!\n");
 #else
    DWORD                    flags;
    PAL_LARGE SDL_Color      palette[256];

+ 33 - 5
winrt/SDLPal.Common/WinRTUtil.cpp

@@ -113,23 +113,51 @@ BOOL UTIL_TouchEnabled(VOID)
 
 static Windows::Storage::StorageFile^ g_running_file = nullptr;
 
-extern "C"
-INT UTIL_Platform_Init(int argc, char* argv[])
+static void CreateRunningFile()
 {
 	// Create the 'running' file for crash detection.
 	try { g_running_file = AWait(Windows::Storage::ApplicationData::Current->LocalFolder->CreateFileAsync("running", Windows::Storage::CreationCollisionOption::OpenIfExists), g_eventHandle); }
 	catch (Platform::Exception^) {}
+}
+
+static void DeleteRunningFile()
+{
+	// Delete the 'running' file on normal exit.
+	try { if (g_running_file) AWait(g_running_file->DeleteAsync()); g_running_file = nullptr; }
+	catch (Platform::Exception^) {}
+}
+
+static int SDLCALL WinRT_EventFilter(void *userdata, SDL_Event * event)
+{
+	switch (event->type)
+	{
+	case SDL_APP_DIDENTERFOREGROUND:
+		CreateRunningFile();
+		break;
+	case SDL_APP_DIDENTERBACKGROUND:
+	case SDL_APP_TERMINATING:
+		// Enter background or exiting, treat as normal exit
+		DeleteRunningFile();
+		break;
+	}
+	return 0;
+}
+
+extern "C"
+INT UTIL_Platform_Init(int argc, char* argv[])
+{
+	CreateRunningFile();
 
 	SDL_SetHint(SDL_HINT_ORIENTATIONS, "LandscapeRight");
 	SDL_SetHint(SDL_HINT_WINRT_HANDLE_BACK_BUTTON, "1");
 
+	SDL_AddEventWatch(WinRT_EventFilter, nullptr);
+
 	return 0;
 }
 
 extern "C"
 VOID UTIL_Platform_Quit(VOID)
 {
-	// Delete the 'running' file on normal exit.
-	try { if (g_running_file) AWait(g_running_file->DeleteAsync()); g_running_file = nullptr; }
-	catch (Platform::Exception^) {}
+	DeleteRunningFile();
 }

+ 1 - 1
winrt/SDLPal.Windows/Package.appxmanifest

@@ -15,7 +15,7 @@
   </Resources>
   <Applications>
     <Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="SDLPal.App">
-      <m2:VisualElements DisplayName="SDLPal" Square150x150Logo="Assets\Logo.png" Square30x30Logo="Assets\SmallLogo.png" Description="SDL-based reimplementation of classic Chinese RPG &quot;Xian Jian Qi Xia Zhuan&quot;." ForegroundText="light" BackgroundColor="transparent">
+      <m2:VisualElements DisplayName="SDLPal" Square150x150Logo="Assets\Logo.png" Square30x30Logo="Assets\SmallLogo.png" Description="SDL-based reimplementation of classic Chinese RPG &quot;Xian Jian Qi Xia Zhuan&quot;." ForegroundText="light" BackgroundColor="blue">
         <m2:DefaultTile Square70x70Logo="Assets\Square70x70Logo.png" Wide310x150Logo="Assets\WideLogo.png" Square310x310Logo="Assets\Square310x310Logo.png">
         </m2:DefaultTile>
         <m2:SplashScreen Image="Assets\SplashScreen.png" BackgroundColor="black" />

+ 2 - 0
winrt/SDLPal.Windows/SDLPal.vcxproj

@@ -206,6 +206,8 @@
     </Link>
   </ItemDefinitionGroup>
   <ItemGroup>
+    <ClInclude Include="..\SDLPal.Common\AsyncHelper.h" />
+    <ClInclude Include="..\SDLPal.Common\StringHelper.h" />
     <ClInclude Include="pch.h" />
     <ClInclude Include="App.xaml.h">
       <DependentUpon>App.xaml</DependentUpon>

+ 15 - 2
winrt/SDLPal.Windows/SDLPal.vcxproj.filters

@@ -17,6 +17,9 @@
     <Filter Include="Strings\zh-hant">
       <UniqueIdentifier>{a19db27b-07fb-4370-b502-068e5ab9ec1d}</UniqueIdentifier>
     </Filter>
+    <Filter Include="Common">
+      <UniqueIdentifier>{9981d43f-5af9-4f40-8df2-97916c5cc66a}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   <ItemGroup>
     <ApplicationDefinition Include="App.xaml" />
@@ -24,14 +27,24 @@
   <ItemGroup>
     <ClCompile Include="App.xaml.cpp" />
     <ClCompile Include="pch.cpp" />
-    <ClCompile Include="..\SDLPal.Common\SDLPal.cpp" />
-    <ClCompile Include="..\SDLPal.Common\WinRTUtil.cpp" />
     <ClCompile Include="..\SDLPal.Common\MainPage.xaml.cpp" />
+    <ClCompile Include="..\SDLPal.Common\WinRTUtil.cpp">
+      <Filter>Common</Filter>
+    </ClCompile>
+    <ClCompile Include="..\SDLPal.Common\SDLPal.cpp">
+      <Filter>Common</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="pch.h" />
     <ClInclude Include="App.xaml.h" />
     <ClInclude Include="..\SDLPal.Common\MainPage.xaml.h" />
+    <ClInclude Include="..\SDLPal.Common\AsyncHelper.h">
+      <Filter>Common</Filter>
+    </ClInclude>
+    <ClInclude Include="..\SDLPal.Common\StringHelper.h">
+      <Filter>Common</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <Image Include="Assets\Logo.scale-100.png">