diff --git a/res/layout/activity_launcher.xml b/res/layout/activity_launcher.xml index 0ee8c977..829b6001 100644 --- a/res/layout/activity_launcher.xml +++ b/res/layout/activity_launcher.xml @@ -273,16 +273,39 @@ android:layout_marginTop="10dp" android:text="@string/resolution" /> - + + + + + android:layout_marginTop="3dp" + android:numeric="decimal" /> - - + + - - - + android:layout_marginBottom="0dp" + android:layout_marginLeft="0dp" + android:layout_marginRight="0dp" + android:layout_marginTop="0dp" + android:orientation="horizontal" + android:weightSum="1"> + + + + Fixed screen resolution (experimental) Scale screen keeping aspect ratio Specify custom screen width and height - + Resolution: + 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. diff --git a/res/values/styles.xml b/res/values/styles.xml new file mode 100644 index 00000000..e8bfa3b8 --- /dev/null +++ b/res/values/styles.xml @@ -0,0 +1,6 @@ + + + + diff --git a/src/in/celest/xash3d/LauncherActivity.java b/src/in/celest/xash3d/LauncherActivity.java index 9dfa90d3..f3d99289 100644 --- a/src/in/celest/xash3d/LauncherActivity.java +++ b/src/in/celest/xash3d/LauncherActivity.java @@ -17,10 +17,11 @@ import java.io.*; import java.net.*; import org.json.*; import android.preference.*; +import su.xash.fwgslib.*; public class LauncherActivity extends Activity { // 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 static EditText cmdArgs; static EditText resPath; @@ -32,45 +33,54 @@ public class LauncherActivity extends Activity { static SharedPreferences mPref; static Spinner pixelSpinner; static TextView tvResPath; + static TextView resResult; static EditText resScale, resWidth, resHeight; static RadioButton radioScale, radioCustom; + static RadioGroup scaleGroup; static CheckBox resolution; - static int mWidth, mHeight; - String getDefaultPath() + static int mEngineWidth, mEngineHeight; + + public static void changeButtonsStyle( ViewGroup parent ) { - File dir = Environment.getExternalStorageDirectory(); - if( dir != null && dir.exists() ) - return dir.getPath() + "/xash"; - return "/sdcard/xash"; - } - public static void changeButtonsStyle(ViewGroup parent) { - if(sdk >= 21) + if( sdk >= 21 ) return; - for (int i = parent.getChildCount() - 1; i >= 0; i--) { - try{ - final View child = parent.getChildAt(i); - if( child == null ) - continue; - if (child instanceof ViewGroup) { - changeButtonsStyle((ViewGroup) child); - // DO SOMETHING WITH VIEWGROUP, AFTER CHILDREN HAS BEEN LOOPED - } else if (child instanceof Button) { - final Button b = (Button)child; - final Drawable bg = b.getBackground(); - if(bg!= null)bg.setAlpha(96); - 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); + + for( int i = parent.getChildCount() - 1; i >= 0; i-- ) + { + try + { + final View child = parent.getChildAt(i); + + if( child == null ) + continue; + + if( child instanceof ViewGroup ) + { + changeButtonsStyle((ViewGroup) child); + // DO SOMETHING WITH VIEWGROUP, AFTER CHILDREN HAS BEEN LOOPED + } + else if( child instanceof Button ) + { + final Button b = (Button)child; + final Drawable bg = b.getBackground(); + if(bg!= null)bg.setAlpha( 96 ); + 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); radioCustom = (RadioButton) findViewById(R.id.resolution_custom_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 = { "32 bit (RGBA8888)", @@ -146,38 +158,46 @@ public class LauncherActivity extends Activity { "16 bit (RGBA4444)", "8 bit (RGB332)" }; - ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_spinner_item, list); - adapter.setDropDownViewResource(android.R.layout.simple_spinner_item); + ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_spinner_dropdown_item, list); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); pixelSpinner.setAdapter(adapter); Button selectFolderButton = ( Button ) findViewById( R.id.button_select ); - selectFolderButton.setOnClickListener(new View.OnClickListener(){ - @Override - public void onClick(View v) { - selectFolder(v); - } - }); - ((Button)findViewById( R.id.button_launch )).setOnClickListener(new View.OnClickListener(){ - @Override - public void onClick(View v) { - startXash(v); - } - }); - ((Button)findViewById( R.id.button_shortcut )).setOnClickListener(new View.OnClickListener(){ - @Override - public void onClick(View v) { - createShortcut(v); - } - }); - ((Button)findViewById( R.id.button_about )).setOnClickListener(new View.OnClickListener(){ - @Override - public void onClick(View v) { - aboutXash(v); - } - }); + selectFolderButton.setOnClickListener(new View.OnClickListener() + { + @Override + public void onClick(View v) + { + selectFolder(v); + } + }); + ((Button)findViewById( R.id.button_launch )).setOnClickListener(new View.OnClickListener() + { + @Override + public void onClick(View v) + { + startXash(v); + } + }); + ((Button)findViewById( R.id.button_shortcut )).setOnClickListener(new View.OnClickListener() + { + @Override + public void onClick(View 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)); checkUpdates.setChecked(mPref.getBoolean("check_updates",true)); 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")); pixelSpinner.setSelection(mPref.getInt("pixelformat", 0)); resizeWorkaround.setChecked(mPref.getBoolean("enableResizeWorkaround", true)); @@ -187,16 +207,40 @@ public class LauncherActivity extends Activity { DisplayMetrics metrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metrics); - mWidth = metrics.widthPixels; - mHeight = metrics.heightPixels; - resWidth.setText(String.valueOf(mPref.getInt("resolution_width", mWidth ))); - resHeight.setText(String.valueOf(mPref.getInt("resolution_height", mHeight ))); - resScale.setText(String.valueOf(mPref.getFloat("resolution_scale",2.0f))); + // Swap resolution here, because engine is always(should be always) run in landscape mode + if( FWGSLib.isLandscapeOrientation( this ) ) + { + 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) ) radioCustom.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() { @Override @@ -233,33 +277,76 @@ public class LauncherActivity extends Activity { new CheckUpdate(true, updateToBeta.isChecked()).execute(UPDATE_LINK); } changeButtonsStyle((ViewGroup)tabHost.getParent()); - + hideResolutionSettings( !enableResolutionChange ); + updateResolutionResult(); + toggleResolutionFields(); } 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); } 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 ); - resHeight.setVisibility( View.GONE ); - resScale.setVisibility( View.GONE ); - radioCustom.setVisibility( View.GONE ); - radioScale.setVisibility( View.GONE ); + updateResolutionResult(); + } + }; + + void updateResolutionResult( ) + { + int w, h; + if( radioCustom.isChecked() ) + { + w = getCustomEngineWidth(); + h = getCustomEngineHeight(); } else { - resWidth.setVisibility( View.VISIBLE ); - resHeight.setVisibility( View.VISIBLE ); - resScale.setVisibility( View.VISIBLE ); - radioCustom.setVisibility( View.VISIBLE ); - radioScale.setVisibility( View.VISIBLE ); + final float scale = getResolutionScale(); + w = (int)((float)mEngineWidth / scale); + h = (int)((float)mEngineHeight / scale); } + + 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) @@ -276,32 +363,9 @@ public class LauncherActivity extends Activity { editor.putBoolean("check_updates", checkUpdates.isChecked()); editor.putBoolean("resolution_fixed", resolution.isChecked()); editor.putBoolean("resolution_custom", radioCustom.isChecked()); - - float scale = 1.0f; - int w = mWidth, h = mHeight; - - 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 ); + editor.putFloat("resolution_scale", getResolutionScale() ); + editor.putInt("resolution_width", getCustomEngineWidth() ); + editor.putInt("resolution_height", getCustomEngineHeight() ); if( sdk >= 19 ) editor.putBoolean("immersive_mode", immersiveMode.isChecked()); diff --git a/src/in/celest/xash3d/XashActivity.java b/src/in/celest/xash3d/XashActivity.java index 0c91e074..1d5a71a2 100644 --- a/src/in/celest/xash3d/XashActivity.java +++ b/src/in/celest/xash3d/XashActivity.java @@ -36,6 +36,8 @@ import in.celest.xash3d.JoystickHandler; import in.celest.xash3d.CertCheck; import android.provider.Settings.Secure; +import su.xash.fwgslib.*; + /** Xash Activity */ @@ -459,12 +461,21 @@ public class XashActivity extends Activity { String basedir = getStringExtraFromIntent( intent, "basedir", mPref.getString( "basedir", "/sdcard/xash/" ) ); 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; 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() ) @@ -1037,7 +1048,8 @@ class EngineSurface extends SurfaceView implements SurfaceHolder.Callback, View. Log.v( TAG, "engineThreadJoin()" ); try { - mEngThread.join( 5000 ); // wait until Xash will quit + if( mEngThread != null ) + mEngThread.join( 5000 ); // wait until Xash will quit } catch( InterruptedException e ) {