v2.9.5.11-3dfx

- Fixed keyboard not showing up after changing resolution in VNC screen.
- Added opening VNC settings in VNC screen.
- New VNC settings section.
- Added option to force refresh when there is a change in VNC screen.
This commit is contained in:
An Bui 2025-09-28 13:52:48 +07:00
parent f732bfb6dd
commit 22002abd70
19 changed files with 298 additions and 54 deletions

View file

@ -11,7 +11,7 @@ android {
minSdk minApi
targetSdk targetApi
versionCode 21
versionName "v2.9.5.10-3dfx"
versionName "v2.9.5.11-3dfx"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled true
}

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.vectras.vm">
package="com.vectras.vm" >
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
@ -47,7 +47,11 @@
android:largeHeap="true"
android:requestLegacyExternalStorage="true"
android:supportsRtl="true"
android:theme="@style/AppTheme">
android:theme="@style/AppTheme" >
<activity
android:name=".settings.VNCSettingsActivity"
android:configChanges="orientation|screenSize|keyboardHidden|smallestScreenSize|screenLayout"
android:exported="false" />
<activity
android:name=".home.HomeActivity"
android:configChanges="orientation|screenSize|keyboardHidden|smallestScreenSize|screenLayout"
@ -58,13 +62,13 @@
android:configChanges="orientation|screenSize|keyboardHidden|smallestScreenSize|screenLayout"
android:exported="false" />
<activity
android:name=".settings.VNCActivity"
android:name=".settings.ExternalVNCSettingsActivity"
android:configChanges="orientation|screenSize|keyboardHidden|smallestScreenSize|screenLayout"
android:exported="false" />
<activity
android:name=".ReceiveRomFileActivity"
android:exported="true"
android:label="@string/importRom">
android:label="@string/importRom" >
<intent-filter>
<action android:name="android.intent.action.VIEW" />
@ -110,7 +114,7 @@
android:name=".SplashActivity"
android:configChanges="uiMode|orientation|screenSize|keyboardHidden|smallestScreenSize|screenLayout"
android:exported="true"
android:hardwareAccelerated="true">
android:hardwareAccelerated="true" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@ -228,7 +232,7 @@
android:exported="true"
android:resizeableActivity="true"
android:supportsPictureInPicture="false"
android:taskAffinity="com.vectras.vm.x11.LoriePreferences">
android:taskAffinity="com.vectras.vm.x11.LoriePreferences" >
<intent-filter>
<action android:name="android.intent.action.APPLICATION_PREFERENCES" />
<action android:name="android.intent.action.MAIN" />
@ -246,7 +250,7 @@
android:name=".x11.utils.KeyInterceptor"
android:exported="true"
android:label="Termux:X11 KeyInterceptor"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" >
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
@ -260,7 +264,7 @@
android:name=".x11.LoriePreferences$Receiver"
android:enabled="true"
android:exported="true"
tools:ignore="ExportedReceiver">
tools:ignore="ExportedReceiver" >
<intent-filter>
<action android:name="com.vectras.vm.x11.CHANGE_PREFERENCE" />
</intent-filter>

View file

@ -182,6 +182,7 @@ public class Config {
public static final String defaultInputMode = VncCanvasActivity.TOUCH_ZOOM_MODE;
public static String vmID = "";
public static String currentVNCServervmID = "";
public static boolean forceRefeshVNCDisplay = false;
public static void setDefault () {
defaultVNCHost = "0.0.0.0";

View file

@ -950,4 +950,16 @@ public class MainSettingsManager extends AppCompatActivity
return prefs.getInt("vncScaleMode", 0);
}
public static void setForceRefeshVNCDisplay(Context context, Boolean _boolean) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor edit = prefs.edit();
edit.putBoolean("forceRefeshVNCDisplay", _boolean);
edit.commit();
}
public static Boolean getForceRefeshVNCDisplay(Context context) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
return prefs.getBoolean("forceRefeshVNCDisplay", false);
}
}

View file

@ -764,6 +764,7 @@ public class MainVNCActivity extends VncCanvasActivity {
setUIModeMobile(screenMode == VNCScreenMode.FitToScreen);
binding.lnNosignal.setVisibility(View.GONE);
this.vncCanvas.setFocusableInTouchMode(true);
});
}
@ -800,7 +801,11 @@ public class MainVNCActivity extends VncCanvasActivity {
// }
} else {
// Try reconnect.
tryReconnect();
if (Config.forceRefeshVNCDisplay) {
finish();
} else {
tryReconnect();
}
}
}

View file

@ -14,8 +14,7 @@ import static com.vectras.vm.utils.LibraryChecker.isPackageInstalled2;
import static com.vectras.vm.utils.UIUtils.UIAlert;
import com.vectras.vm.settings.UpdaterActivity;
import com.vectras.vm.settings.VNCActivity;
import com.vectras.vm.utils.DeviceUtils;
import com.vectras.vm.settings.ExternalVNCSettingsActivity;
import com.vectras.vm.utils.DialogUtils;
import com.vectras.vm.utils.NetworkUtils;
import com.vectras.vm.utils.NotificationUtils;
@ -35,7 +34,6 @@ import android.os.Environment;
import android.os.Handler;
import android.os.StrictMode;
import android.provider.DocumentsContract;
import android.text.Html;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
@ -845,7 +843,7 @@ public class MainActivity extends AppCompatActivity {
activity.getString(R.string.go_to_settings),
activity.getString(R.string.close),
true, R.drawable.warning_48px, true,
() -> activity.startActivity(new Intent(activity, VNCActivity.class)),
() -> activity.startActivity(new Intent(activity, ExternalVNCSettingsActivity.class)),
null,
null);
return;

View file

@ -40,6 +40,7 @@ import com.vectras.qemu.VNCConfig;
import com.vectras.qemu.utils.QmpClient;
import com.vectras.vm.MainRoms.AdapterMainRoms;
import com.vectras.vm.home.HomeActivity;
import com.vectras.vm.settings.VNCSettingsActivity;
import com.vectras.vm.utils.DialogUtils;
import com.vectras.vm.utils.FileUtils;
import com.vectras.vm.utils.JSONUtils;
@ -922,6 +923,11 @@ public class VMManager {
_dialog.dismiss();
});
_view.findViewById(R.id.ln_settings).setOnClickListener(v -> {
_activity.startActivity(new Intent(_activity, VNCSettingsActivity.class));
_dialog.dismiss();
});
if (MainSettingsManager.getVNCScaleMode(_activity) == VNCConfig.oneToOne) {
_view.findViewById(R.id.iv_screenOneToOne).setBackgroundResource(R.drawable.dialog_shape_single_button);
} else {

View file

@ -300,6 +300,7 @@ public class HomeActivity extends AppCompatActivity implements RomStoreFragment.
Log.d(TAG, "onResume");
Config.ui = MainSettingsManager.getVmUi(this);
Config.defaultVNCPort = Integer.parseInt(MainSettingsManager.getVncExternalDisplay(this));
Config.forceRefeshVNCDisplay = MainSettingsManager.getForceRefeshVNCDisplay(this);
if (!MainSettingsManager.getVncExternal(this))
NotificationUtils.clearAll(this);

View file

@ -25,7 +25,7 @@ import com.vectras.vm.MainService;
import com.vectras.vm.R;
import com.vectras.vm.VMManager;
import com.vectras.vm.logger.VectrasStatus;
import com.vectras.vm.settings.VNCActivity;
import com.vectras.vm.settings.ExternalVNCSettingsActivity;
import com.vectras.vm.utils.DialogUtils;
import com.vectras.vm.utils.NetworkUtils;
import com.vectras.vm.utils.ServiceUtils;
@ -100,7 +100,7 @@ public class HomeStartVM {
activity.getString(R.string.go_to_settings),
activity.getString(R.string.close),
true, R.drawable.warning_48px, true,
() -> activity.startActivity(new Intent(activity, VNCActivity.class)),
() -> activity.startActivity(new Intent(activity, ExternalVNCSettingsActivity.class)),
null,
null);
return;

View file

@ -11,21 +11,21 @@ import androidx.appcompat.app.AppCompatActivity;
import com.vectras.qemu.MainSettingsManager;
import com.vectras.vm.R;
import com.vectras.vm.databinding.ActivityVncactivityBinding;
import com.vectras.vm.databinding.ActivityExternalVncSettingsBinding;
import com.vectras.vm.utils.ClipboardUltils;
import java.util.Objects;
public class VNCActivity extends AppCompatActivity {
public class ExternalVNCSettingsActivity extends AppCompatActivity {
ActivityVncactivityBinding binding;
ActivityExternalVncSettingsBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_vncactivity);
binding = ActivityVncactivityBinding.inflate(getLayoutInflater());
setContentView(R.layout.activity_external_vnc_settings);
binding = ActivityExternalVncSettingsBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
setSupportActionBar(binding.toolbar);
Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);

View file

@ -37,7 +37,7 @@ public class UpdaterActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_vncactivity);
setContentView(R.layout.activity_external_vnc_settings);
binding = ActivityUpdaterBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
setSupportActionBar(binding.toolbar);

View file

@ -0,0 +1,42 @@
package com.vectras.vm.settings;
import android.content.Intent;
import android.os.Bundle;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import com.vectras.qemu.MainSettingsManager;
import com.vectras.vm.R;
import com.vectras.vm.databinding.ActivityVncSettingsBinding;
import java.util.Objects;
public class VNCSettingsActivity extends AppCompatActivity {
ActivityVncSettingsBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_external_vnc_settings);
binding = ActivityVncSettingsBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
setSupportActionBar(binding.toolbar);
Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);
binding.toolbar.setNavigationOnClickListener(view -> onBackPressed());
initialize();
}
private void initialize() {
binding.swForcerefesh.setOnCheckedChangeListener((buttonView, isChecked) -> MainSettingsManager.setForceRefeshVNCDisplay(this, isChecked));
binding.lnForcerefesh.setOnClickListener(v -> binding.swForcerefesh.toggle());
binding.swExternal.setOnCheckedChangeListener((buttonView, isChecked) -> MainSettingsManager.setVncExternal(this, isChecked));
binding.lnExternal.setOnClickListener( v -> startActivity(new Intent(this, ExternalVNCSettingsActivity.class)));
binding.swForcerefesh.setChecked(MainSettingsManager.getForceRefeshVNCDisplay(this));
binding.swExternal.setChecked(MainSettingsManager.getVncExternal(this));
}
}

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M370,880L354,752Q341,747 329.5,740Q318,733 307,725L188,775L78,585L181,507Q180,500 180,493.5Q180,487 180,480Q180,473 180,466.5Q180,460 181,453L78,375L188,185L307,235Q318,227 330,220Q342,213 354,208L370,80L590,80L606,208Q619,213 630.5,220Q642,227 653,235L772,185L882,375L779,453Q780,460 780,466.5Q780,473 780,480Q780,487 780,493.5Q780,500 778,507L881,585L771,775L653,725Q642,733 630,740Q618,747 606,752L590,880L370,880ZM440,800L519,800L533,694Q564,686 590.5,670.5Q617,655 639,633L738,674L777,606L691,541Q696,527 698,511.5Q700,496 700,480Q700,464 698,448.5Q696,433 691,419L777,354L738,286L639,328Q617,305 590.5,289.5Q564,274 533,266L520,160L441,160L427,266Q396,274 369.5,289.5Q343,305 321,327L222,286L183,354L269,418Q264,433 262,448Q260,463 260,480Q260,496 262,511Q264,526 269,541L183,606L222,674L321,632Q343,655 369.5,670.5Q396,686 427,694L440,800ZM482,620Q540,620 581,579Q622,538 622,480Q622,422 581,381Q540,340 482,340Q423,340 382.5,381Q342,422 342,480Q342,538 382.5,579Q423,620 482,620ZM480,480L480,480Q480,480 480,480Q480,480 480,480L480,480L480,480L480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480L480,480L480,480L480,480Q480,480 480,480Q480,480 480,480L480,480L480,480L480,480Q480,480 480,480Q480,480 480,480L480,480L480,480L480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480L480,480L480,480L480,480Q480,480 480,480Q480,480 480,480L480,480Z"/>
</vector>

View file

@ -5,7 +5,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:fitsSystemWindows="true"
android:orientation="vertical"
tools:context=".settings.VNCActivity">
tools:context=".settings.ExternalVNCSettingsActivity">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"

View file

@ -0,0 +1,144 @@
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:fitsSystemWindows="true"
android:orientation="vertical"
tools:context=".settings.ExternalVNCSettingsActivity">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$Behavior">
<com.google.android.material.appbar.CollapsingToolbarLayout
style="?attr/collapsingToolbarLayoutLargeStyle"
android:layout_width="match_parent"
android:layout_height="?attr/collapsingToolbarLayoutLargeSize"
android:fitsSystemWindows="true"
app:collapsedTitleTextAppearance="@style/TextAppearance.Material3.TitleMedium"
app:expandedTitleTextAppearance="@style/TextAppearance.Material3.DisplaySmall"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:title="@string/vnc"
app:subtitle="@string/settings">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:elevation="0dp"
app:layout_collapseMode="pin" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
android:id="@+id/ln_all_options"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:animateLayoutChanges="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/ln_forcerefesh"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:padding="16dp">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/sw_forcerefesh"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/force_refresh"
android:textSize="18sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/force_refresh_vnc_description"
android:textColor="?android:attr/textColorSecondary"
android:textSize="14sp" />
</LinearLayout>
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/sw_forcerefesh"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:clickable="false"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/ln_external"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:padding="16dp">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/short_distance_in_external"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/external"
android:textSize="18sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/vnc_settings_description"
android:textColor="?android:attr/textColorSecondary"
android:textSize="14sp" />
</LinearLayout>
<View
android:id="@+id/short_distance_in_external"
android:layout_width="1dp"
android:layout_height="24dp"
android:layout_marginHorizontal="16dp"
android:background="?attr/colorOutline"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/sw_external"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/sw_external"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -174,26 +174,6 @@
android:text="@string/user_interface"
android:textSize="22sp"/>
<LinearLayout
android:id="@+id/ln_mouse"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:paddingVertical="8dp"
android:paddingHorizontal="16dp"
android:background="?attr/selectableItemBackground">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/touchpad_mouse_24px"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="8dp"
android:textColor="?attr/colorControlNormal"
android:text="@string/mouse_mode"/>
</LinearLayout>
<LinearLayout
android:id="@+id/ln_screenMode"
android:layout_width="match_parent"
@ -218,6 +198,46 @@
android:src="@drawable/fullscreen_24px"
android:background="?attr/selectableItemBackgroundBorderless"/>
</LinearLayout>
<LinearLayout
android:id="@+id/ln_mouse"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:paddingVertical="8dp"
android:paddingHorizontal="16dp"
android:background="?attr/selectableItemBackground">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/touchpad_mouse_24px"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="8dp"
android:textColor="?attr/colorControlNormal"
android:text="@string/mouse_mode"/>
</LinearLayout>
<LinearLayout
android:id="@+id/ln_settings"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:paddingVertical="8dp"
android:paddingHorizontal="16dp"
android:background="?attr/selectableItemBackground">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/settings_24px"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="8dp"
android:textColor="?attr/colorControlNormal"
android:text="@string/settings"/>
</LinearLayout>
</LinearLayout>

View file

@ -3,7 +3,7 @@
<string name="app_name">Vectras VM</string>
<!--======================VECTRAS STRINGS====================-->
<string name="app_version" translatable="false">v2.9.5.10-3dfx</string>
<string name="app_version" translatable="false">v2.9.5.11-3dfx</string>
<string name="qemu_version" translatable="false">Stable</string>
<string name="str_home">Home</string>
<string name="str_logger">Logger</string>
@ -553,7 +553,9 @@
<string name="not_enough_storage_to_set_up_content">There is not enough storage available on your device to set up. Please clear up and try again later.</string>
<string name="no_signal">No signal</string>
<string name="tap_to_try_again">Tap to try again.</string>
<string name="force_refresh">Force refresh</string>
<string name="force_refresh_vnc_description">The VNC screen will restart every time there is a change, which helps troubleshoot problems.</string>
<string name="settings_for_vnc">Settings for VNC.</string>
<!--======================TERMUX STRINGS====================-->
@ -814,7 +816,7 @@
<string name="common_loading">Loading…</string>
<string name="common_error">An error occurred.</string>
<string name="api_key" translatable="false">xyz123abc</string>
<!-- ======================= VIRTUAL MACHINE MANAGEMENT ===================== -->
<!-- ======================= VIRTUAL MACHINE MANAGEMENT ===================== -->
<!-- VM Creation & Setup -->
<string name="vm_create_new">New VM</string> <!-- Was: new_vm -->
@ -1052,7 +1054,6 @@
</string> -->
<!-- ========================== TERMUX-X11 STRINGS ========================== -->
<!-- <string name="plugin_info" translatable="false">lol</string> -->
</resources>

View file

@ -22,12 +22,12 @@
app:iconSpaceReserved="false" />
<Preference
android:key="vnc"
android:title="@string/vnc_server"
android:summary="@string/vnc_settings_description"
android:title="@string/vnc"
android:summary="@string/settings_for_vnc"
app:iconSpaceReserved="false">
<intent
android:targetPackage="com.vectras.vm"
android:targetClass="com.vectras.vm.settings.VNCActivity" />
android:targetClass="com.vectras.vm.settings.VNCSettingsActivity" />
</Preference>
<Preference
android:key="x11"

View file

@ -1,15 +1,15 @@
{
"versionCode":"21",
"versionName":"v2.9.5-3dfx,v2.9.5-3dfx-almondcake,v2.9.5-3dfx-bread,v2.9.5-3dfx-churro,v2.9.5-3dfx-doughnut,v2.9.5-3dfx-empanada,v2.9.5-3dfx-flan,v2.9.5-3dfx-gugelhupf,v2.9.5-3dfx-hamentaschen,v2.9.5-3dfx-italianice,v2.9.5-3dfx-ladyfingers,v2.9.5-3dfx-madeleine,v2.9.5-3dfx-neapolitanicecream,v2.9.5-3dfx-orangecake,v2.9.5-3dfx-profiterole,v2.9.5-3dfx-quincejelly,v2.9.5-3dfx-rugelach,v2.9.5-3dfx-scone,v2.9.5-3dfx-tart,v2.9.5-3dfx-ube-halaya,v2.9.5-3dfx-victoria-sponge,v2.9.5-3dfx-waffle,v2.9.5-3dfx-xangos,v2.9.5-3dfx-yorkshire-pudding,v2.9.5-3dfx-zeppole,v2.9.5.1-3dfx,v2.9.5.2-3dfx,v2.9.5.3-3dfx,v2.9.5.4-3dfx,v2.9.5.5-3dfx,v2.9.5.6-3dfx,v2.9.5.7-3dfx,v2.9.5.8-3dfx,v2.9.5.9-3dfx,v2.9.5.10-3dfx",
"versionName":"v2.9.5-3dfx,v2.9.5-3dfx-almondcake,v2.9.5-3dfx-bread,v2.9.5-3dfx-churro,v2.9.5-3dfx-doughnut,v2.9.5-3dfx-empanada,v2.9.5-3dfx-flan,v2.9.5-3dfx-gugelhupf,v2.9.5-3dfx-hamentaschen,v2.9.5-3dfx-italianice,v2.9.5-3dfx-ladyfingers,v2.9.5-3dfx-madeleine,v2.9.5-3dfx-neapolitanicecream,v2.9.5-3dfx-orangecake,v2.9.5-3dfx-profiterole,v2.9.5-3dfx-quincejelly,v2.9.5-3dfx-rugelach,v2.9.5-3dfx-scone,v2.9.5-3dfx-tart,v2.9.5-3dfx-ube-halaya,v2.9.5-3dfx-victoria-sponge,v2.9.5-3dfx-waffle,v2.9.5-3dfx-xangos,v2.9.5-3dfx-yorkshire-pudding,v2.9.5-3dfx-zeppole,v2.9.5.1-3dfx,v2.9.5.2-3dfx,v2.9.5.3-3dfx,v2.9.5.4-3dfx,v2.9.5.5-3dfx,v2.9.5.6-3dfx,v2.9.5.7-3dfx,v2.9.5.8-3dfx,v2.9.5.9-3dfx,v2.9.5.10-3dfx,v2.9.5.11-3dfx",
"size": "46 MB",
"url": "https://github.com/xoureldeen/Vectras-VM-Android/releases/v2.9.5",
"Message": "<h2>v2.9.5-3dfx</h2><ul><li>Bring back 3dfx support.</li><li>Enhance app execution.</li><li>Added some linux programs in x11 display.</li><li>Added alpine linux (x11).</li><li>Russian language by <a href=\"https://github.com/OFGING\" target=\"_blank\">@OFGING</a></li></ul><br><br>New updates are live!",
"cancellable": true,
"versionCodeBeta":"21",
"versionNameBeta":"v2.9.5.10-3dfx",
"versionNameBetas":"v2.9.5-3dfx-madeleine,v2.9.5-3dfx-neapolitanicecream,v2.9.5-3dfx-orangecake,v2.9.5-3dfx-profiterole,v2.9.5-3dfx-quincejelly,v2.9.5-3dfx-rugelach,v2.9.5-3dfx-scone,v2.9.5-3dfx-tart,v2.9.5-3dfx-victoria-sponge,v2.9.5-3dfx-waffle,v2.9.5-3dfx-xangos,v2.9.5-3dfx-yorkshire-pudding,v2.9.5-3dfx-zeppole,v2.9.5.1-3dfx,v2.9.5.2-3dfx,v2.9.5.3-3dfx,v2.9.5.4-3dfx,v2.9.5.5-3dfx,v2.9.5.6-3dfx,v2.9.5.7-3dfx,v2.9.5.8-3dfx,v2.9.5.9-3dfx,v2.9.5.10-3dfx",
"versionNameBeta":"v2.9.5.11-3dfx",
"versionNameBetas":"v2.9.5-3dfx-madeleine,v2.9.5-3dfx-neapolitanicecream,v2.9.5-3dfx-orangecake,v2.9.5-3dfx-profiterole,v2.9.5-3dfx-quincejelly,v2.9.5-3dfx-rugelach,v2.9.5-3dfx-scone,v2.9.5-3dfx-tart,v2.9.5-3dfx-victoria-sponge,v2.9.5-3dfx-waffle,v2.9.5-3dfx-xangos,v2.9.5-3dfx-yorkshire-pudding,v2.9.5-3dfx-zeppole,v2.9.5.1-3dfx,v2.9.5.2-3dfx,v2.9.5.3-3dfx,v2.9.5.4-3dfx,v2.9.5.5-3dfx,v2.9.5.6-3dfx,v2.9.5.7-3dfx,v2.9.5.8-3dfx,v2.9.5.9-3dfx,v2.9.5.10-3dfx,v2.9.5.11-3dfx",
"sizeBeta": "41 MB",
"urlBeta": "https://github.com/AnBui2004/Vectras-VM-Emu-Android/releases",
"MessageBeta": "<h2>v2.9.5.10-3dfx</h2>Bugs fixed.",
"MessageBeta": "<h2>v2.9.5.11-3dfx</h2>Bugs fixed.",
"cancellableBeta": true
}