Browse Source

Merge pull request #56 from sdlpal/arbitrary_aspectratio

Allow user specified aspect ratio
Pal Lockheart 6 years ago
parent
commit
a17bab6628

+ 5 - 0
android/app/src/main/java/com/sdlpal/sdlpal/SettingsActivity.java

@@ -41,6 +41,7 @@ public class SettingsActivity extends AppCompatActivity {
     public static native String getGitRevision();
 
     private static final String KeepAspectRatio = "KeepAspectRatio";
+    private static final String AspectRatio = "AspectRatio";
     private static final String LaunchSetting = "LaunchSetting";
     private static final String Stereo = "Stereo";
     private static final String UseSurroundOPL = "UseSurroundOPL";
@@ -68,6 +69,7 @@ public class SettingsActivity extends AppCompatActivity {
     private static final String CDFormats[] = { "MP3", "OGG" };
     private static final String MusicFormats[] = { "MIDI", "RIX", "MP3", "OGG" };
     private static final String OPLFormats[] = { "DOSBOX", "MAME", "DOSBOXNEW" };
+    private static final String AspectRatios[] = { "16:10", "4:3" };
 
     private SettingsActivity mInstance = this;
 
@@ -305,6 +307,7 @@ public class SettingsActivity extends AppCompatActivity {
         ((AppCompatSpinner)findViewById(R.id.spMusFmt)).setSelection(findMatchedStringIndex(getConfigString(MusicFormat, true), MusicFormats, 1));    // RIX
         ((AppCompatSpinner)findViewById(R.id.spOPL)).setSelection(findMatchedStringIndex(getConfigString(OPLFormat, true), OPLFormats, 1));       // MAME
         ((AppCompatSpinner)findViewById(R.id.spOPLRate)).setSelection(findMatchedIntIndex(getConfigInt(OPLSampleRate, true), OPLSampleRates, 5));  // 49716Hz
+        ((AppCompatSpinner)findViewById(R.id.spAspectRatio)).setSelection(findMatchedStringIndex(getConfigString(AspectRatio, true), AspectRatios, 0));  // 16:10
     }
 
 
@@ -342,6 +345,7 @@ public class SettingsActivity extends AppCompatActivity {
         ((AppCompatSpinner)findViewById(R.id.spMusFmt)).setSelection(findMatchedStringIndex(getConfigString(MusicFormat, false), MusicFormats, 1));    // RIX
         ((AppCompatSpinner)findViewById(R.id.spOPL)).setSelection(findMatchedStringIndex(getConfigString(OPLFormat, false), OPLFormats, 1));       // MAME
         ((AppCompatSpinner)findViewById(R.id.spOPLRate)).setSelection(findMatchedIntIndex(getConfigInt(OPLSampleRate, false), OPLSampleRates, 5));  // 49716Hz
+        ((AppCompatSpinner)findViewById(R.id.spAspectRatio)).setSelection(findMatchedStringIndex(getConfigString(AspectRatio, false), AspectRatios, 0));  // 16:10
     }
 
     protected boolean setConfigs() {
@@ -380,6 +384,7 @@ public class SettingsActivity extends AppCompatActivity {
         setConfigString(MusicFormat, (String)((AppCompatSpinner)findViewById(R.id.spMusFmt)).getSelectedItem());
         setConfigString(OPLFormat, (String)((AppCompatSpinner)findViewById(R.id.spOPL)).getSelectedItem());
         setConfigInt(OPLSampleRate, Integer.parseInt((String)((AppCompatSpinner)findViewById(R.id.spOPLRate)).getSelectedItem()));
+        setConfigString(AspectRatio, (String)((AppCompatSpinner)findViewById(R.id.spAspectRatio)).getSelectedItem());
 
         return true;
     }

+ 11 - 0
android/app/src/main/res/layout/content_settings.xml

@@ -126,6 +126,17 @@
                 tools:layout_editor_absoluteX="8dp"
                 tools:layout_editor_absoluteY="269dp" />
 
+            <TextView
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/label_aspectratio" />
+
+            <android.support.v7.widget.AppCompatSpinner
+                android:id="@+id/spAspectRatio"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:entries="@array/aspect_ratio" />
+
             <android.support.v7.widget.SwitchCompat
                 android:id="@+id/swStereo"
                 android:layout_width="match_parent"

+ 1 - 0
android/app/src/main/res/values-zh-rCN/strings.xml

@@ -31,4 +31,5 @@
     <string name="toast_grantpermission">本应用需要存储设备读写权限以访问游戏资源。请点击“确定”后手动为本应用开启权限。</string>
     <string name="msg_data_not_found_header">无法在以下文件夹中找到游戏数据文件:</string>
     <string name="msg_data_not_found_footer">注意:由于版权问题,数据文件无法提供。请自行从百游官方下载并解压拷贝到手机中。</string>
+    <string name="label_aspectratio">纵横比</string>
 </resources>

+ 1 - 0
android/app/src/main/res/values-zh-rTW/strings.xml

@@ -31,4 +31,5 @@
     <string name="toast_grantpermission">本app需要存儲裝置讀寫許可權以訪問遊戲資料檔。請按「確定」後手動為本app開啟許可權。</string>
     <string name="msg_data_not_found_header">無法在以下資料夾中找到遊戲資料檔:</string>
     <string name="msg_data_not_found_footer">說明:為防止侵害大宇公司版權,恕不提供遊戲資料檔。请自行將正版PAL的資料檔復製到手機中。</string>
+    <string name="label_aspectratio">縱橫比</string>
 </resources>

+ 4 - 0
android/app/src/main/res/values/arrays.xml

@@ -34,6 +34,10 @@
         <item>44100</item>
         <item>49716</item>
     </string-array>
+    <string-array name="aspect_ratio" translatable="false">
+        <item>16:10</item>
+        <item>4:3</item>
+    </string-array>
     <string-array name="log_level">
         <item>Verbose</item>
         <item>Debug</item>

+ 1 - 0
android/app/src/main/res/values/strings.xml

@@ -16,6 +16,7 @@
     <string name="label_musfmt">Music format</string>
     <string name="label_oplrate">OPL emulator\'s samplerate</string>
     <string name="label_opl">OPL emulator</string>
+    <string name="label_aspectratio">Aspect Ratio</string>
     <string name="action_suropl">Surround OPL</string>
     <string name="action_default">Default</string>
     <string name="action_finish">Finish</string>

+ 1 - 1
ios/SDLPal/Podfile.lock

@@ -7,6 +7,6 @@ DEPENDENCIES:
 SPEC CHECKSUMS:
   ActionSheetPicker-3.0: d11a4c12c6aaf704b8a3f56d179198c99f3e41e6
 
-PODFILE CHECKSUM: cb0e67e3620d915f68ac1b0695b9a096f64afba1
+PODFILE CHECKSUM: '08d95c7a90827aceac47314762506861c0976bf8'
 
 COCOAPODS: 1.2.0

+ 44 - 15
ios/SDLPal/SDLPal/Base.lproj/Settings.storyboard

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12120" systemVersion="16F73" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="ka3-r9-J8N">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12120" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="ka3-r9-J8N">
     <device id="retina4_7" orientation="portrait">
         <adaptation id="fullscreen"/>
     </device>
@@ -179,9 +179,37 @@
                                             </constraints>
                                         </tableViewCellContentView>
                                     </tableViewCell>
-                                    <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" id="QIS-rz-zJd">
+                                    <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="CmI-Wd-gQ5">
                                         <rect key="frame" x="0.0" y="388" width="375" height="44"/>
                                         <autoresizingMask key="autoresizingMask"/>
+                                        <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="CmI-Wd-gQ5" id="VFU-PS-KP3">
+                                            <rect key="frame" x="0.0" y="0.0" width="375" height="43"/>
+                                            <autoresizingMask key="autoresizingMask"/>
+                                            <subviews>
+                                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="Aspect Ratio" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="p6J-yg-lGj">
+                                                    <rect key="frame" x="8" y="12" width="157" height="21"/>
+                                                    <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                                    <nil key="textColor"/>
+                                                    <nil key="highlightedColor"/>
+                                                </label>
+                                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Ves-fH-mIO">
+                                                    <rect key="frame" x="173" y="11" width="194" height="21"/>
+                                                    <fontDescription key="fontDescription" type="system" pointSize="15"/>
+                                                    <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
+                                                    <nil key="highlightedColor"/>
+                                                </label>
+                                            </subviews>
+                                            <constraints>
+                                                <constraint firstAttribute="trailingMargin" secondItem="Ves-fH-mIO" secondAttribute="trailing" id="AkJ-Ag-VZK"/>
+                                                <constraint firstAttribute="leadingMargin" secondItem="p6J-yg-lGj" secondAttribute="leading" id="LcY-ug-VTW"/>
+                                                <constraint firstItem="Ves-fH-mIO" firstAttribute="centerY" secondItem="VFU-PS-KP3" secondAttribute="centerY" id="jE3-Sd-RrD"/>
+                                                <constraint firstItem="p6J-yg-lGj" firstAttribute="centerY" secondItem="VFU-PS-KP3" secondAttribute="centerY" id="zfW-Zw-lfN"/>
+                                            </constraints>
+                                        </tableViewCellContentView>
+                                    </tableViewCell>
+                                    <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" id="QIS-rz-zJd">
+                                        <rect key="frame" x="0.0" y="432" width="375" height="44"/>
+                                        <autoresizingMask key="autoresizingMask"/>
                                         <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="QIS-rz-zJd" id="blf-1D-A3j">
                                             <rect key="frame" x="0.0" y="0.0" width="375" height="43"/>
                                             <autoresizingMask key="autoresizingMask"/>
@@ -209,7 +237,7 @@
                             <tableViewSection headerTitle="Audio" id="kPc-Yq-LOh">
                                 <cells>
                                     <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="3SU-Gc-7wH">
-                                        <rect key="frame" x="0.0" y="488" width="375" height="44"/>
+                                        <rect key="frame" x="0.0" y="532" width="375" height="44"/>
                                         <autoresizingMask key="autoresizingMask"/>
                                         <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="3SU-Gc-7wH" id="76m-CM-YAY">
                                             <rect key="frame" x="0.0" y="0.0" width="375" height="43"/>
@@ -237,7 +265,7 @@
                                         </tableViewCellContentView>
                                     </tableViewCell>
                                     <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="3qo-FD-4nl">
-                                        <rect key="frame" x="0.0" y="532" width="375" height="44"/>
+                                        <rect key="frame" x="0.0" y="576" width="375" height="44"/>
                                         <autoresizingMask key="autoresizingMask"/>
                                         <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="3qo-FD-4nl" id="A3N-bu-7U7">
                                             <rect key="frame" x="0.0" y="0.0" width="375" height="43"/>
@@ -265,7 +293,7 @@
                                         </tableViewCellContentView>
                                     </tableViewCell>
                                     <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" id="m0b-oW-cFG">
-                                        <rect key="frame" x="0.0" y="576" width="375" height="44"/>
+                                        <rect key="frame" x="0.0" y="620" width="375" height="44"/>
                                         <autoresizingMask key="autoresizingMask"/>
                                         <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="m0b-oW-cFG" id="C0a-eU-4ng">
                                             <rect key="frame" x="0.0" y="0.0" width="375" height="43"/>
@@ -293,7 +321,7 @@
                                         </tableViewCellContentView>
                                     </tableViewCell>
                                     <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" id="V3l-ah-ZFI">
-                                        <rect key="frame" x="0.0" y="620" width="375" height="44"/>
+                                        <rect key="frame" x="0.0" y="664" width="375" height="44"/>
                                         <autoresizingMask key="autoresizingMask"/>
                                         <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="V3l-ah-ZFI" id="eVR-TT-9qV">
                                             <rect key="frame" x="0.0" y="0.0" width="375" height="43"/>
@@ -321,7 +349,7 @@
                                         </tableViewCellContentView>
                                     </tableViewCell>
                                     <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="Wcd-0e-0uz">
-                                        <rect key="frame" x="0.0" y="664" width="375" height="44"/>
+                                        <rect key="frame" x="0.0" y="708" width="375" height="44"/>
                                         <autoresizingMask key="autoresizingMask"/>
                                         <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Wcd-0e-0uz" id="7gg-Gn-Rbv">
                                             <rect key="frame" x="0.0" y="0.0" width="375" height="43"/>
@@ -349,7 +377,7 @@
                                         </tableViewCellContentView>
                                     </tableViewCell>
                                     <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="5P5-9D-K9z">
-                                        <rect key="frame" x="0.0" y="708" width="375" height="44"/>
+                                        <rect key="frame" x="0.0" y="752" width="375" height="44"/>
                                         <autoresizingMask key="autoresizingMask"/>
                                         <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="5P5-9D-K9z" id="xWo-4q-ewi">
                                             <rect key="frame" x="0.0" y="0.0" width="375" height="43"/>
@@ -377,7 +405,7 @@
                                         </tableViewCellContentView>
                                     </tableViewCell>
                                     <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="nhG-Zy-1Uw">
-                                        <rect key="frame" x="0.0" y="752" width="375" height="44"/>
+                                        <rect key="frame" x="0.0" y="796" width="375" height="44"/>
                                         <autoresizingMask key="autoresizingMask"/>
                                         <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="nhG-Zy-1Uw" id="Urf-ql-u6V">
                                             <rect key="frame" x="0.0" y="0.0" width="375" height="43"/>
@@ -405,7 +433,7 @@
                                         </tableViewCellContentView>
                                     </tableViewCell>
                                     <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="2aX-ku-Pap">
-                                        <rect key="frame" x="0.0" y="796" width="375" height="44"/>
+                                        <rect key="frame" x="0.0" y="840" width="375" height="44"/>
                                         <autoresizingMask key="autoresizingMask"/>
                                         <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="2aX-ku-Pap" id="9ea-vH-MC4">
                                             <rect key="frame" x="0.0" y="0.0" width="375" height="43"/>
@@ -433,7 +461,7 @@
                                         </tableViewCellContentView>
                                     </tableViewCell>
                                     <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" id="6yy-RI-FfR">
-                                        <rect key="frame" x="0.0" y="840" width="375" height="44"/>
+                                        <rect key="frame" x="0.0" y="884" width="375" height="44"/>
                                         <autoresizingMask key="autoresizingMask"/>
                                         <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="6yy-RI-FfR" id="H5X-fx-gXk">
                                             <rect key="frame" x="0.0" y="0.0" width="375" height="43"/>
@@ -458,7 +486,7 @@
                                         </tableViewCellContentView>
                                     </tableViewCell>
                                     <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" id="WrT-Dr-FrF">
-                                        <rect key="frame" x="0.0" y="884" width="375" height="44"/>
+                                        <rect key="frame" x="0.0" y="928" width="375" height="44"/>
                                         <autoresizingMask key="autoresizingMask"/>
                                         <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="WrT-Dr-FrF" id="2Az-da-XqZ">
                                             <rect key="frame" x="0.0" y="0.0" width="375" height="43"/>
@@ -483,7 +511,7 @@
                                         </tableViewCellContentView>
                                     </tableViewCell>
                                     <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" id="H6k-zH-SLQ">
-                                        <rect key="frame" x="0.0" y="928" width="375" height="44"/>
+                                        <rect key="frame" x="0.0" y="972" width="375" height="44"/>
                                         <autoresizingMask key="autoresizingMask"/>
                                         <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="H6k-zH-SLQ" id="3vu-2x-gU2">
                                             <rect key="frame" x="0.0" y="0.0" width="375" height="43"/>
@@ -515,7 +543,7 @@
                             <tableViewSection headerTitle="Logging" id="Lil-2E-Cmo">
                                 <cells>
                                     <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="tqd-QN-Zcq">
-                                        <rect key="frame" x="0.0" y="1028" width="375" height="44"/>
+                                        <rect key="frame" x="0.0" y="1072" width="375" height="44"/>
                                         <autoresizingMask key="autoresizingMask"/>
                                         <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="tqd-QN-Zcq" id="9Vs-yb-gfS">
                                             <rect key="frame" x="0.0" y="0.0" width="375" height="43"/>
@@ -543,7 +571,7 @@
                                         </tableViewCellContentView>
                                     </tableViewCell>
                                     <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" id="GKK-ca-Bn8">
-                                        <rect key="frame" x="0.0" y="1072" width="375" height="44"/>
+                                        <rect key="frame" x="0.0" y="1116" width="375" height="44"/>
                                         <autoresizingMask key="autoresizingMask"/>
                                         <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="GKK-ca-Bn8" id="eiA-H0-J1K">
                                             <rect key="frame" x="0.0" y="0.0" width="375" height="43"/>
@@ -596,6 +624,7 @@
                     <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
                     <size key="freeformSize" width="375" height="667"/>
                     <connections>
+                        <outlet property="lblAspectRatio" destination="Ves-fH-mIO" id="uHS-uf-4KT"/>
                         <outlet property="lblAudioBufferSize" destination="gIJ-cp-Pvp" id="gMu-3d-fpY"/>
                         <outlet property="lblCDAudioSource" destination="RXF-wq-i6h" id="51D-b6-xqa"/>
                         <outlet property="lblFontFile" destination="EsV-LN-DsQ" id="JIk-yL-QhZ"/>

+ 11 - 2
ios/SDLPal/SDLPal/SettingsTableViewController.m

@@ -22,6 +22,8 @@
     NSArray *MusicFormats;
     NSArray *OPLFormats;
     NSArray *LogLevels;
+    NSArray *AspectRatios;
+    
     NSArray *allFiles;
     NSMutableArray *AvailFiles;
     BOOL checkAllFilesIncluded;
@@ -38,6 +40,7 @@
     
     IBOutlet UISwitch *toggleTouchScreenOverlay;
     IBOutlet UISwitch *toggleKeepAspect;
+    IBOutlet UILabel *lblAspectRatio;
     IBOutlet UISwitch *toggleSmoothScaling;
     
     IBOutlet UILabel *lblMusicType;
@@ -81,6 +84,7 @@
     MusicFormats = @[ @"MIDI", @"RIX", @"MP3", @"OGG" ];
     OPLFormats = @[ @"DOSBOX", @"MAME", @"DOSBOXNEW" ];
     LogLevels = @[ @"VERBOSE", @"DEBUG", @"INFO", @"WARNING", @"ERROR", @"FATAL" ];
+    AspectRatios = @[ @"16:10", @"4:3" ];
     
     UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
     tap.cancelsTouchesInView = NO;
@@ -161,7 +165,7 @@ typedef void(^SelectedBlock)(NSString *selected);
             rows = 2;
             break;
         case 2:
-            rows = 3;
+            rows = 4;
             break;
         case 3:
             rows = [lblMusicType.text isEqualToString:@"RIX"] ? 11 : 4;
@@ -185,7 +189,9 @@ typedef void(^SelectedBlock)(NSString *selected);
         toggleTouchScreenOverlay.on = !toggleTouchScreenOverlay.isOn;
     }else if( indexPath.section == 2 && indexPath.row == 1 ) { //keep aspect
         toggleKeepAspect.on = !toggleKeepAspect.isOn;
-    }else if( indexPath.section == 2 && indexPath.row == 2 ) { //smooth scaling
+    }else if( indexPath.section == 2 && indexPath.row == 2 ) { //aspect ratio
+        [self showPickerWithTitle:nil toLabel:lblAspectRatio inArray:AspectRatios origin:cell allowEmpty:NO];
+    }else if( indexPath.section == 2 && indexPath.row == 3 ) { //smooth scaling
         toggleSmoothScaling.on = !toggleSmoothScaling.isOn;
     }else if( indexPath.section == 3 && indexPath.row == 0 ) { //BGM
         [self showPickerWithTitle:nil toLabel:lblMusicType inArray:MusicFormats origin:cell allowEmpty:NO doneBlock:^(NSString *selected) {
@@ -254,6 +260,7 @@ typedef void(^SelectedBlock)(NSString *selected);
     
     toggleTouchScreenOverlay.on = gConfig.fUseTouchOverlay;
     toggleKeepAspect.on         = gConfig.fKeepAspectRatio;
+    lblAspectRatio.text         = [NSString stringWithFormat:@"%d:%d",gConfig.dwAspectX,gConfig.dwAspectY];
     toggleSmoothScaling.on      = gConfig.pszScaleQuality ? strncmp(gConfig.pszScaleQuality, "0", sizeof(char)) != 0 : NO;
     
     lblMusicType.text       = MusicFormats[gConfig.eMusicType];
@@ -282,6 +289,8 @@ typedef void(^SelectedBlock)(NSString *selected);
     gConfig.fUseSurroundOPL = toggleSurroundOPL.isOn;
     
     gConfig.fKeepAspectRatio = toggleKeepAspect.isOn;
+    gConfig.dwAspectX = [[lblAspectRatio.text componentsSeparatedByString:@":"][0] intValue];
+    gConfig.dwAspectY = [[lblAspectRatio.text componentsSeparatedByString:@":"][1] intValue];
     gConfig.fUseTouchOverlay = toggleTouchScreenOverlay.isOn;
     gConfig.pszScaleQuality  = strdup(toggleSmoothScaling.on ? "1" : "0");
    

+ 2 - 0
ios/SDLPal/SDLPal/zh-Hans.lproj/Settings.strings

@@ -79,3 +79,5 @@
 
 /* Class = "UILabel"; text = "SmoothScaling"; ObjectID = "VQA-I8-2Wf"; */
 "VQA-I8-2Wf.text" = "平滑缩放";
+
+"p6J-yg-lGj.text" = "纵横比";

+ 2 - 0
ios/SDLPal/SDLPal/zh-Hant.lproj/Settings.strings

@@ -79,3 +79,5 @@
 
 /* Class = "UILabel"; text = "SmoothScaling"; ObjectID = "VQA-I8-2Wf"; */
 "VQA-I8-2Wf.text" = "平滑縮放";
+
+"p6J-yg-lGj.text" = "縱橫比";

+ 31 - 0
palcfg.c

@@ -67,6 +67,7 @@ static const ConfigItem gConfigItems[PALCFG_ALL_MAX] = {
 	{ PALCFG_RIXEXTRAINIT,      PALCFG_STRING,   "RIXExtraInit",      12, MAKE_VALUE(NULL,     NULL, NULL) },
 	{ PALCFG_CLIMIDIPLAYER,     PALCFG_STRING,   "CLIMIDIPlayer",     13, MAKE_VALUE(NULL,     NULL, NULL) },
     { PALCFG_SCALEQUALITY,      PALCFG_STRING,   "ScaleQuality",      12, MAKE_VALUE("0",      NULL, NULL) },
+    { PALCFG_ASPECTRATIO,       PALCFG_STRING,   "AspectRatio",       11, MAKE_VALUE("16:10",  NULL, NULL) },
 };
 
 static const char *music_types[] = { "MIDI", "RIX", "MP3", "OGG", "RAW" };
@@ -273,6 +274,8 @@ PAL_LoadConfig(
 	MUSICTYPE eMusicType = MUSIC_RIX;
 	MUSICTYPE eCDType = MUSIC_OGG;
 	OPLTYPE   eOPLType = OPL_DOSBOX;
+	INT dwAspectX = -1;
+	INT dwAspectY = -1;
 	SCREENLAYOUT screen_layout = {
 		// Equipment Screen
 		PAL_XY(8, 8), PAL_XY(2, 95), PAL_XY(5, 70), PAL_XY(51, 57),
@@ -418,6 +421,17 @@ PAL_LoadConfig(
                 case PALCFG_SCALEQUALITY:
                     gConfig.pszScaleQuality = ParseStringValue(value.sValue, gConfig.pszScaleQuality);
                     break;
+                case PALCFG_ASPECTRATIO:
+                {
+                    char *aspectRatio = ParseStringValue(value.sValue, gConfig.pszScaleQuality);
+                    char *lasts;
+					if( strchr(aspectRatio,':') == NULL ) {
+						aspectRatio = ParseStringValue(item->DefaultValue.sValue, gConfig.pszScaleQuality);
+					}
+					dwAspectX = atoi(strtok_r(aspectRatio,":",&lasts));
+					dwAspectY = atoi(strtok_r(NULL,       ":",&lasts));
+                    break;
+                }
 				default:
 					values[item->Item] = value;
 					break;
@@ -458,6 +472,9 @@ PAL_LoadConfig(
 	gConfig.iMusicVolume = values[PALCFG_MUSICVOLUME].uValue;
 	gConfig.iSoundVolume = values[PALCFG_SOUNDVOLUME].uValue;
 
+	gConfig.dwAspectX = dwAspectX <= 0 ? 16 : dwAspectX;
+	gConfig.dwAspectY = dwAspectY <= 0 ? 10 : dwAspectY;
+
 	if (UTIL_GetScreenSize(&values[PALCFG_WINDOWWIDTH].uValue, &values[PALCFG_WINDOWHEIGHT].uValue))
 	{
 		gConfig.dwScreenWidth = values[PALCFG_WINDOWWIDTH].uValue;
@@ -512,6 +529,7 @@ PAL_SaveConfig(
 		if (gConfig.pszLogFile && *gConfig.pszLogFile) { sprintf(buf, "%s=%s\n", PAL_ConfigName(PALCFG_LOGFILE), gConfig.pszLogFile); fputs(buf, fp); }
         if (gConfig.pszCLIMIDIPlayerPath && *gConfig.pszCLIMIDIPlayerPath) { sprintf(buf, "%s=%s\n", PAL_ConfigName(PALCFG_CLIMIDIPLAYER), gConfig.pszCLIMIDIPlayerPath); fputs(buf, fp); }
         if (gConfig.pszScaleQuality && *gConfig.pszScaleQuality) { sprintf(buf, "%s=%s\n", PAL_ConfigName(PALCFG_SCALEQUALITY), gConfig.pszScaleQuality); fputs(buf, fp); }
+        if (gConfig.dwAspectX > 0 && gConfig.dwAspectY > 0) { sprintf(buf, "%s=%s\n", PAL_ConfigName(PALCFG_ASPECTRATIO), PAL_va(0,"%d:%d",gConfig.dwAspectX,gConfig.dwAspectY)); fputs(buf, fp); }
 
 		fclose(fp);
 
@@ -560,6 +578,7 @@ PAL_GetConfigItem(
 		case PALCFG_SCALEQUALITY:      value.sValue = gConfig.pszScaleQuality; break;
 		case PALCFG_MUSIC:             value.sValue = music_types[gConfig.eMusicType]; break;
 		case PALCFG_OPL:               value.sValue = opl_types[gConfig.eOPLType]; break;
+        case PALCFG_ASPECTRATIO:       value.sValue = PAL_va(0,"%d:%d",gConfig.dwAspectX,gConfig.dwAspectY); break;
 		default:                       break;
 		}
 	}
@@ -592,6 +611,18 @@ PAL_SetConfigItem(
 	case PALCFG_SOUNDVOLUME:       gConfig.iSoundVolume = value.uValue; break;
 	case PALCFG_WINDOWHEIGHT:      gConfig.dwScreenHeight = value.uValue; break;
 	case PALCFG_WINDOWWIDTH:       gConfig.dwScreenWidth = value.uValue; break;
+    case PALCFG_ASPECTRATIO:
+    {
+        char *lasts;
+        if( strchr(value.sValue,':') != NULL ) {
+            gConfig.dwAspectX = atoi(strtok_r((char*)value.sValue,":",&lasts));
+            gConfig.dwAspectY = atoi(strtok_r(NULL,               ":",&lasts));
+        }else{
+            gConfig.dwAspectX = 16;
+            gConfig.dwAspectY = 10;
+        }
+        break;
+    }
 	case PALCFG_GAMEPATH:
 		if (gConfig.pszGamePath) free(gConfig.pszGamePath);
 		gConfig.pszGamePath = value.sValue && value.sValue[0] ? strdup(value.sValue) : strdup(PAL_PREFIX);

+ 3 - 0
palcfg.h

@@ -81,6 +81,7 @@ typedef enum tagPALCFG_ITEM
 	PALCFG_RIXEXTRAINIT,
 	PALCFG_CLIMIDIPLAYER,
     PALCFG_SCALEQUALITY,
+    PALCFG_ASPECTRATIO,
 	/* Strings */
 	PALCFG_STRING_MAX,
 
@@ -173,6 +174,8 @@ typedef struct tagCONFIGURATION
 	DWORD            dwWordLength;
 	DWORD            dwScreenWidth;
 	DWORD            dwScreenHeight;
+    DWORD            dwAspectX;
+    DWORD            dwAspectY;
 	INT              iSurroundOPLOffset;
 	INT              iAudioChannels;
 	INT              iSampleRate;

+ 3 - 2
video.c

@@ -53,15 +53,16 @@ static WORD               g_wShakeLevel      = 0;
 
 #if SDL_VERSION_ATLEAST(2, 0, 0)
 #define SDL_SoftStretch SDL_UpperBlit
-
+#include <float.h>
 static SDL_Texture *VIDEO_CreateTexture(int width, int height)
 {
 	int texture_width, texture_height;
 	float ratio = (float)width / (float)height;
+	ratio *= 1.6f * (float)gConfig.dwAspectY / (float)gConfig.dwAspectX;
 	//
 	// Check whether to keep the aspect ratio
 	//
-	if (gConfig.fKeepAspectRatio && ratio != 1.6f)
+	if (gConfig.fKeepAspectRatio && fabs(ratio - 1.6f) > FLT_EPSILON)
 	{
 		if (ratio > 1.6f)
 		{

+ 4 - 0
win32/pal_config.h

@@ -59,3 +59,7 @@
 #define PAL_PATH_SEPARATORS "\\/"
 
 #define PAL_IS_PATH_SEPARATOR(x) ((x) == '\\' || (x) == '/')
+
+#ifndef __MINGW__
+#define strtok_r strtok_s
+#endif

+ 4 - 0
winrt/SDLPal.Common/MainPage.xaml

@@ -47,6 +47,10 @@
                 </Grid>
                 <ToggleSwitch x:Name="tsTouchOverlay" x:Uid="TouchOverlay" Header="启用触屏辅助" OffContent="否" OnContent="是" />
                 <ToggleSwitch x:Name="tsKeepAspect" x:Uid="AspectRatio" Header="保持纵横比" OffContent="否" OnContent="是" />
+                <ComboBox x:Name="cbAspectRatio" x:Uid="Ratio" HorizontalAlignment="Stretch" Header="纵横比" PlaceholderText="选择纵横比">
+                    <ComboBoxItem Content="16:10"/>
+                    <ComboBoxItem Content="4:3"/>
+                </ComboBox>
                 <ToggleSwitch x:Name="tsEnableAVI" x:Uid="EnableAVI" Header="启用 AVI 过场动画" OffContent="否" OnContent="是" />
                 <ToggleSwitch x:Name="tsStereo" x:Uid="Stereo" Header="立体声" OffContent="否" OnContent="是" />
                 <Slider x:Name="slMusicVolume" x:Uid="MusicVolume" Header="音乐音量" TickPlacement="Inline" TickFrequency="10" />

+ 8 - 0
winrt/SDLPal.Common/MainPage.xaml.cpp

@@ -112,6 +112,7 @@ void SDLPal::MainPage::LoadControlContents(bool loadDefault)
 	cbCD->SelectedIndex = (gConfig.eCDType == MUSIC_MP3) ? 0 : 1;
 	cbBGM->SelectedIndex = (gConfig.eMusicType <= MUSIC_OGG) ? gConfig.eMusicType : MUSIC_RIX;
 	cbOPL->SelectedIndex = (int)gConfig.eOPLType;
+	cbAspectRatio->SelectedIndex = gConfig.dwAspectY == 0 ? 0 : [](std::vector<float> &array, float toMatch) {return std::find_if(array.begin(), array.end(), [toMatch](float i)->bool { return fabs(toMatch - i) < FLT_EPSILON; }) - array.begin(); }(std::vector<float>({ 16.0f / 10.0f, 4.0f / 3.0f }), (float)gConfig.dwAspectX / gConfig.dwAspectY);
 
 	if (gConfig.iSampleRate <= 11025)
 		cbSampleRate->SelectedIndex = 0;
@@ -159,6 +160,13 @@ void SDLPal::MainPage::SaveControlContents()
 	gConfig.eMusicType = (MUSICTYPE)cbBGM->SelectedIndex;
 	gConfig.eOPLType = (OPLTYPE)cbOPL->SelectedIndex;
 
+	wchar_t *lasts;
+	wchar_t *selectedAspectRatio = (wchar_t*)static_cast<Platform::String^>(static_cast<ComboBoxItem^>(cbAspectRatio->SelectedItem)->Content)->Data();
+	wchar_t *w=wcstok_s(selectedAspectRatio, L":", &lasts);
+	gConfig.dwAspectX = _wtoi(w);
+	w = wcstok_s(NULL, L":", &lasts);
+	gConfig.dwAspectY = _wtoi(w);
+
 	gConfig.iSampleRate = wcstoul(static_cast<Platform::String^>(static_cast<ComboBoxItem^>(cbSampleRate->SelectedItem)->Content)->Data(), nullptr, 10);
 	gConfig.iOPLSampleRate = wcstoul(static_cast<Platform::String^>(static_cast<ComboBoxItem^>(cbOPLSR->SelectedItem)->Content)->Data(), nullptr, 10);
 	gConfig.wAudioBufferSize = wcstoul(static_cast<Platform::String^>(static_cast<ComboBoxItem^>(cbAudioBuffer->SelectedItem)->Content)->Data(), nullptr, 10);

+ 2 - 0
winrt/pal_config.h

@@ -57,6 +57,8 @@
 
 #define PAL_IS_PATH_SEPARATOR(x) ((x) == '\\' || (x) == '/')
 
+#define strtok_r strtok_s
+
 PAL_C_LINKAGE_BEGIN
 
 LPCSTR