Add resolution change warning red text, add result resolution preview, make resolution custom fields appear in one line, make first use of FWGSLib, fix possible crash while activity is closed before engine thread was created

This commit is contained in:
Alibek Omarov (a1batross) 2017-09-30 02:29:55 +03:00
parent 1c02cfb443
commit 828ede1e3a
5 changed files with 257 additions and 128 deletions

View file

@ -273,16 +273,39 @@
android:layout_marginTop="10dp" android:layout_marginTop="10dp"
android:text="@string/resolution" /> android:text="@string/resolution" />
<RadioGroup <RadioGroup
android:id="@+id/scale_group"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="10dp" android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp" android:layout_marginLeft="10dp"
android:layout_marginRight="10dp" android:layout_marginRight="10dp"
android:layout_marginTop="10dp" android:layout_marginTop="10dp"
android:background="#444444"
android:orientation="vertical" android:orientation="vertical"
android:weightSum="1"> android:weightSum="1">
<RadioButton android:id="@+id/resolution_scale_r" android:text="@string/resolution_scale" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="3dp"
android:text="@string/resolution_mod_warn"
android:textAppearance="@style/red_small_text" />
<TextView
android:id="@+id/resolution_result"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="3dp"
android:textAppearance="?android:attr/textAppearanceSmall" />
<RadioButton
android:id="@+id/resolution_scale_r"
android:text="@string/resolution_scale"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<EditText <EditText
android:id="@+id/resolution_scale" android:id="@+id/resolution_scale"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -290,27 +313,49 @@
android:layout_marginBottom="10dp" android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp" android:layout_marginLeft="10dp"
android:layout_marginRight="10dp" android:layout_marginRight="10dp"
android:layout_marginTop="3dp" /> android:layout_marginTop="3dp"
android:numeric="decimal" />
<RadioButton android:id="@+id/resolution_custom_r" android:text="@string/resolution_custom" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <RadioButton
<EditText android:id="@+id/resolution_custom_r"
android:id="@+id/resolution_width" android:text="@string/resolution_custom"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="10dp" android:layout_marginBottom="0dp"
android:layout_marginLeft="10dp" android:layout_marginLeft="0dp"
android:layout_marginRight="10dp" android:layout_marginRight="0dp"
android:layout_marginTop="3dp" /> android:layout_marginTop="0dp"
<EditText android:orientation="horizontal"
android:id="@+id/resolution_height" android:weightSum="1">
android:layout_width="match_parent" <EditText
android:layout_height="wrap_content" android:id="@+id/resolution_width"
android:layout_marginBottom="10dp" android:layout_width="100dp"
android:layout_marginLeft="10dp" android:layout_height="wrap_content"
android:layout_marginRight="10dp" android:layout_marginBottom="10dp"
android:layout_marginTop="3dp" /> android:layout_marginLeft="10dp"
android:layout_marginRight="3dp"
android:layout_marginTop="3dp"
android:numeric="integer" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginTop="3dp"
android:text="x"
android:textAppearance="?android:attr/textAppearanceSmall" />
<EditText
android:id="@+id/resolution_height"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginLeft="3dp"
android:layout_marginTop="3dp"
android:numeric="integer" />
</LinearLayout>
</RadioGroup> </RadioGroup>
<TextView <TextView
android:id="@+id/textView7" android:id="@+id/textView7"

View file

@ -73,5 +73,7 @@
<string name="resolution">Fixed screen resolution (experimental)</string> <string name="resolution">Fixed screen resolution (experimental)</string>
<string name="resolution_scale">Scale screen keeping aspect ratio</string> <string name="resolution_scale">Scale screen keeping aspect ratio</string>
<string name="resolution_custom">Specify custom screen width and height</string> <string name="resolution_custom">Specify custom screen width and height</string>
<string name="resolution_result">Resolution: </string>
<string name="resolution_mod_warn">Use with caution! Some games does not support too low resolution, in case of bugs increase resolution to 640x480 or higher.\n
Resolution lower than 320x240 is not allowed.</string>
</resources> </resources>

6
res/values/styles.xml Normal file
View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="red_small_text" parent="@android:style/TextAppearance.Small">
<item name="android:textColor">#FF0000</item>
</style>
</resources>

View file

@ -17,10 +17,11 @@ import java.io.*;
import java.net.*; import java.net.*;
import org.json.*; import org.json.*;
import android.preference.*; import android.preference.*;
import su.xash.fwgslib.*;
public class LauncherActivity extends Activity { public class LauncherActivity extends Activity {
// public final static String ARGV = "in.celest.xash3d.MESSAGE"; // public final static String ARGV = "in.celest.xash3d.MESSAGE";
public final static int sdk = Integer.valueOf(Build.VERSION.SDK); public final static int sdk = FWGSLib.sdk;
public final static String UPDATE_LINK = "https://api.github.com/repos/FWGS/xash3d-android-project/releases"; // releases/latest doesn't return prerelease and drafts public final static String UPDATE_LINK = "https://api.github.com/repos/FWGS/xash3d-android-project/releases"; // releases/latest doesn't return prerelease and drafts
static EditText cmdArgs; static EditText cmdArgs;
static EditText resPath; static EditText resPath;
@ -32,45 +33,54 @@ public class LauncherActivity extends Activity {
static SharedPreferences mPref; static SharedPreferences mPref;
static Spinner pixelSpinner; static Spinner pixelSpinner;
static TextView tvResPath; static TextView tvResPath;
static TextView resResult;
static EditText resScale, resWidth, resHeight; static EditText resScale, resWidth, resHeight;
static RadioButton radioScale, radioCustom; static RadioButton radioScale, radioCustom;
static RadioGroup scaleGroup;
static CheckBox resolution; static CheckBox resolution;
static int mWidth, mHeight; static int mEngineWidth, mEngineHeight;
String getDefaultPath()
public static void changeButtonsStyle( ViewGroup parent )
{ {
File dir = Environment.getExternalStorageDirectory(); if( sdk >= 21 )
if( dir != null && dir.exists() )
return dir.getPath() + "/xash";
return "/sdcard/xash";
}
public static void changeButtonsStyle(ViewGroup parent) {
if(sdk >= 21)
return; return;
for (int i = parent.getChildCount() - 1; i >= 0; i--) {
try{ for( int i = parent.getChildCount() - 1; i >= 0; i-- )
final View child = parent.getChildAt(i); {
if( child == null ) try
continue; {
if (child instanceof ViewGroup) { final View child = parent.getChildAt(i);
changeButtonsStyle((ViewGroup) child);
// DO SOMETHING WITH VIEWGROUP, AFTER CHILDREN HAS BEEN LOOPED if( child == null )
} else if (child instanceof Button) { continue;
final Button b = (Button)child;
final Drawable bg = b.getBackground(); if( child instanceof ViewGroup )
if(bg!= null)bg.setAlpha(96); {
b.setTextColor(0xFFFFFFFF); changeButtonsStyle((ViewGroup) child);
b.setTextSize(15f); // DO SOMETHING WITH VIEWGROUP, AFTER CHILDREN HAS BEEN LOOPED
//b.setText(b.getText().toString().toUpperCase()); }
b.setTypeface(b.getTypeface(),Typeface.BOLD); else if( child instanceof Button )
}else if (child instanceof EditText) { {
final EditText b = (EditText)child; final Button b = (Button)child;
b.setBackgroundColor(0xFF353535); final Drawable bg = b.getBackground();
b.setTextColor(0xFFFFFFFF); if(bg!= null)bg.setAlpha( 96 );
b.setTextSize(15f); b.setTextColor( 0xFFFFFFFF );
b.setTextSize( 15f );
//b.setText(b.getText().toString().toUpperCase());
b.setTypeface( b.getTypeface(),Typeface.BOLD );
}
else if( child instanceof EditText )
{
final EditText b = ( EditText )child;
b.setBackgroundColor( 0xFF353535 );
b.setTextColor( 0xFFFFFFFF );
b.setTextSize( 15f );
} }
} }
catch(Exception e){} catch( Exception e )
{
}
} }
} }
@ -137,6 +147,8 @@ public class LauncherActivity extends Activity {
resScale = (EditText) findViewById(R.id.resolution_scale); resScale = (EditText) findViewById(R.id.resolution_scale);
radioCustom = (RadioButton) findViewById(R.id.resolution_custom_r); radioCustom = (RadioButton) findViewById(R.id.resolution_custom_r);
radioScale = (RadioButton) findViewById(R.id.resolution_scale_r); radioScale = (RadioButton) findViewById(R.id.resolution_scale_r);
scaleGroup = (RadioGroup) findViewById( R.id.scale_group );
resResult = (TextView) findViewById( R.id.resolution_result );
final String[] list = { final String[] list = {
"32 bit (RGBA8888)", "32 bit (RGBA8888)",
@ -146,38 +158,46 @@ public class LauncherActivity extends Activity {
"16 bit (RGBA4444)", "16 bit (RGBA4444)",
"8 bit (RGB332)" "8 bit (RGB332)"
}; };
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item, list); ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_dropdown_item, list);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_item); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
pixelSpinner.setAdapter(adapter); pixelSpinner.setAdapter(adapter);
Button selectFolderButton = ( Button ) findViewById( R.id.button_select ); Button selectFolderButton = ( Button ) findViewById( R.id.button_select );
selectFolderButton.setOnClickListener(new View.OnClickListener(){ selectFolderButton.setOnClickListener(new View.OnClickListener()
@Override {
public void onClick(View v) { @Override
selectFolder(v); public void onClick(View v)
} {
}); selectFolder(v);
((Button)findViewById( R.id.button_launch )).setOnClickListener(new View.OnClickListener(){ }
@Override });
public void onClick(View v) { ((Button)findViewById( R.id.button_launch )).setOnClickListener(new View.OnClickListener()
startXash(v); {
} @Override
}); public void onClick(View v)
((Button)findViewById( R.id.button_shortcut )).setOnClickListener(new View.OnClickListener(){ {
@Override startXash(v);
public void onClick(View v) { }
createShortcut(v); });
} ((Button)findViewById( R.id.button_shortcut )).setOnClickListener(new View.OnClickListener()
}); {
((Button)findViewById( R.id.button_about )).setOnClickListener(new View.OnClickListener(){ @Override
@Override public void onClick(View v)
public void onClick(View v) { {
aboutXash(v); createShortcut(v);
} }
}); });
((Button)findViewById( R.id.button_about )).setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
aboutXash(v);
}
});
useVolume.setChecked(mPref.getBoolean("usevolume",true)); useVolume.setChecked(mPref.getBoolean("usevolume",true));
checkUpdates.setChecked(mPref.getBoolean("check_updates",true)); checkUpdates.setChecked(mPref.getBoolean("check_updates",true));
updateToBeta.setChecked(mPref.getBoolean("check_betas", false)); updateToBeta.setChecked(mPref.getBoolean("check_betas", false));
updatePath(mPref.getString("basedir", getDefaultPath())); updatePath(mPref.getString("basedir", FWGSLib.getDefaultXashPath() ) );
cmdArgs.setText(mPref.getString("argv","-dev 3 -log")); cmdArgs.setText(mPref.getString("argv","-dev 3 -log"));
pixelSpinner.setSelection(mPref.getInt("pixelformat", 0)); pixelSpinner.setSelection(mPref.getInt("pixelformat", 0));
resizeWorkaround.setChecked(mPref.getBoolean("enableResizeWorkaround", true)); resizeWorkaround.setChecked(mPref.getBoolean("enableResizeWorkaround", true));
@ -187,16 +207,40 @@ public class LauncherActivity extends Activity {
DisplayMetrics metrics = new DisplayMetrics(); DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics); getWindowManager().getDefaultDisplay().getMetrics(metrics);
mWidth = metrics.widthPixels;
mHeight = metrics.heightPixels;
resWidth.setText(String.valueOf(mPref.getInt("resolution_width", mWidth ))); // Swap resolution here, because engine is always(should be always) run in landscape mode
resHeight.setText(String.valueOf(mPref.getInt("resolution_height", mHeight ))); if( FWGSLib.isLandscapeOrientation( this ) )
resScale.setText(String.valueOf(mPref.getFloat("resolution_scale",2.0f))); {
mEngineWidth = metrics.widthPixels;
mEngineHeight = metrics.heightPixels;
}
else
{
mEngineWidth = metrics.heightPixels;
mEngineHeight = metrics.widthPixels;
}
resWidth.setText(String.valueOf(mPref.getInt("resolution_width", mEngineWidth )));
resHeight.setText(String.valueOf(mPref.getInt("resolution_height", mEngineHeight )));
resScale.setText(String.valueOf(mPref.getFloat("resolution_scale", 2.0f)));
resWidth.addTextChangedListener( resTextChangeWatcher );
resHeight.addTextChangedListener( resTextChangeWatcher );
resScale.addTextChangedListener( resTextChangeWatcher );
if( mPref.getBoolean("resolution_custom", false) ) if( mPref.getBoolean("resolution_custom", false) )
radioCustom.setChecked(true); radioCustom.setChecked(true);
else radioScale.setChecked(true); else radioScale.setChecked(true);
hideResolutionSettings( !enableResolutionChange );
radioCustom.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener()
{
@Override
public void onCheckedChanged( CompoundButton v, boolean isChecked )
{
updateResolutionResult();
toggleResolutionFields();
}
} );
resolution.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener() resolution.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener()
{ {
@Override @Override
@ -233,33 +277,76 @@ public class LauncherActivity extends Activity {
new CheckUpdate(true, updateToBeta.isChecked()).execute(UPDATE_LINK); new CheckUpdate(true, updateToBeta.isChecked()).execute(UPDATE_LINK);
} }
changeButtonsStyle((ViewGroup)tabHost.getParent()); changeButtonsStyle((ViewGroup)tabHost.getParent());
hideResolutionSettings( !enableResolutionChange );
updateResolutionResult();
toggleResolutionFields();
} }
void updatePath( String text ) void updatePath( String text )
{ {
tvResPath.setText(getResources().getString(R.string.text_res_path) + ":\n" + text ); tvResPath.setText(getString(R.string.text_res_path) + ":\n" + text );
resPath.setText(text); resPath.setText(text);
} }
void hideResolutionSettings( boolean hide ) void hideResolutionSettings( boolean hide )
{ {
if( hide ) scaleGroup.setVisibility( hide ? View.GONE : View.VISIBLE );
}
TextWatcher resTextChangeWatcher = new TextWatcher()
{
@Override
public void afterTextChanged(Editable s){}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after){}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count)
{ {
resWidth.setVisibility( View.GONE ); updateResolutionResult();
resHeight.setVisibility( View.GONE ); }
resScale.setVisibility( View.GONE ); };
radioCustom.setVisibility( View.GONE );
radioScale.setVisibility( View.GONE ); void updateResolutionResult( )
{
int w, h;
if( radioCustom.isChecked() )
{
w = getCustomEngineWidth();
h = getCustomEngineHeight();
} }
else else
{ {
resWidth.setVisibility( View.VISIBLE ); final float scale = getResolutionScale();
resHeight.setVisibility( View.VISIBLE ); w = (int)((float)mEngineWidth / scale);
resScale.setVisibility( View.VISIBLE ); h = (int)((float)mEngineHeight / scale);
radioCustom.setVisibility( View.VISIBLE );
radioScale.setVisibility( View.VISIBLE );
} }
resResult.setText( getString( R.string.resolution_result ) + w + "x" + h );
}
void toggleResolutionFields()
{
boolean isChecked = radioCustom.isChecked();
resWidth.setEnabled( isChecked );
resHeight.setEnabled( isChecked );
resScale.setEnabled( !isChecked );
}
float getResolutionScale()
{
return FWGSLib.atof( resScale.getText().toString(), 1.0f );
}
int getCustomEngineHeight()
{
return FWGSLib.atoi( resHeight.getText().toString(), mEngineHeight );
}
int getCustomEngineWidth()
{
return FWGSLib.atoi( resWidth.getText().toString(), mEngineWidth );
} }
public void startXash(View view) public void startXash(View view)
@ -276,32 +363,9 @@ public class LauncherActivity extends Activity {
editor.putBoolean("check_updates", checkUpdates.isChecked()); editor.putBoolean("check_updates", checkUpdates.isChecked());
editor.putBoolean("resolution_fixed", resolution.isChecked()); editor.putBoolean("resolution_fixed", resolution.isChecked());
editor.putBoolean("resolution_custom", radioCustom.isChecked()); editor.putBoolean("resolution_custom", radioCustom.isChecked());
editor.putFloat("resolution_scale", getResolutionScale() );
float scale = 1.0f; editor.putInt("resolution_width", getCustomEngineWidth() );
int w = mWidth, h = mHeight; editor.putInt("resolution_height", getCustomEngineHeight() );
try
{
scale = Float.valueOf( resScale.getText().toString() );
}
catch( Exception e )
{
}
try
{
w = Integer.valueOf( resWidth.getText().toString() );
h = Integer.valueOf( resHeight.getText().toString() );
}
catch( Exception e )
{
w = mWidth;
h = mHeight;
}
editor.putFloat("resolution_scale", scale );
editor.putInt("resolution_width", w );
editor.putInt("resolution_height", h );
if( sdk >= 19 ) if( sdk >= 19 )
editor.putBoolean("immersive_mode", immersiveMode.isChecked()); editor.putBoolean("immersive_mode", immersiveMode.isChecked());

View file

@ -36,6 +36,8 @@ import in.celest.xash3d.JoystickHandler;
import in.celest.xash3d.CertCheck; import in.celest.xash3d.CertCheck;
import android.provider.Settings.Secure; import android.provider.Settings.Secure;
import su.xash.fwgslib.*;
/** /**
Xash Activity Xash Activity
*/ */
@ -459,12 +461,21 @@ public class XashActivity extends Activity {
String basedir = getStringExtraFromIntent( intent, "basedir", mPref.getString( "basedir", "/sdcard/xash/" ) ); String basedir = getStringExtraFromIntent( intent, "basedir", mPref.getString( "basedir", "/sdcard/xash/" ) );
String gdbsafe = intent.getStringExtra( "gdbsafe" ); String gdbsafe = intent.getStringExtra( "gdbsafe" );
bIsCstrike = ( gamedir == "cstrike" || gamedir == "czero" ); bIsCstrike = ( gamedir.equals("cstrike") || gamedir.equals("czero") || gamedir.equals("czeror") );
if( gamedir != "valve" ) if( bIsCstrike )
{ {
mMinWidth = 640; mMinWidth = 640;
mMinHeight = 480; mMinHeight = 480;
final String allowed = "in.celest.xash3d.cs16client";
if( !FWGSLib.checkGameLibDir( gamelibdir, allowed ) ||
CertCheck.dumbCertificateCheck( getContext(), allowed, null, true ) )
{
finish();
return;
}
} }
if( gdbsafe != null || Debug.isDebuggerConnected() ) if( gdbsafe != null || Debug.isDebuggerConnected() )
@ -1037,7 +1048,8 @@ class EngineSurface extends SurfaceView implements SurfaceHolder.Callback, View.
Log.v( TAG, "engineThreadJoin()" ); Log.v( TAG, "engineThreadJoin()" );
try try
{ {
mEngThread.join( 5000 ); // wait until Xash will quit if( mEngThread != null )
mEngThread.join( 5000 ); // wait until Xash will quit
} }
catch( InterruptedException e ) catch( InterruptedException e )
{ {