Skip to content

Commit

Permalink
Update app
Browse files Browse the repository at this point in the history
  • Loading branch information
brunodev85 committed Feb 1, 2024
1 parent ed046b4 commit eb2993c
Show file tree
Hide file tree
Showing 35 changed files with 653 additions and 178 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ android {
applicationId 'com.winlator'
minSdkVersion 26
targetSdkVersion 28
versionCode 10
versionName "4.0"
versionCode 11
versionName "5.0"
}

buildTypes {
Expand Down
3 changes: 1 addition & 2 deletions app/src/main/assets/box64_env_vars.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
[
{"name" : "BOX64_DYNAREC", "values" : ["0", "1"], "toggleSwitch" : true, "defaultValue" : "1"},
{"name" : "BOX64_DYNAREC_SAFEFLAGS", "values" : ["0", "1", "2"], "defaultValue" : "2"},
{"name" : "BOX64_DYNAREC_FASTNAN", "values" : ["0", "1"], "toggleSwitch" : true, "defaultValue" : "1"},
{"name" : "BOX64_DYNAREC_FASTROUND", "values" : ["0", "1"], "toggleSwitch" : true, "defaultValue" : "1"},
{"name" : "BOX64_DYNAREC_X87DOUBLE", "values" : ["0", "1"], "toggleSwitch" : true, "defaultValue" : "0"},
{"name" : "BOX64_DYNAREC_BIGBLOCK", "values" : ["0", "1", "2", "3"], "defaultValue" : "1"},
{"name" : "BOX64_DYNAREC_STRONGMEM", "values" : ["0", "1", "2", "3"], "defaultValue" : "0"},
{"name" : "BOX64_DYNAREC_FORWARD", "values" : ["0", "128", "256", "512", "1024"], "defaultValue" : "128"},
{"name" : "BOX64_DYNAREC_CALLRET", "values" : ["0", "1"], "toggleSwitch" : true, "defaultValue" : "0"},
{"name" : "BOX64_DYNAREC_CALLRET", "values" : ["0", "1"], "toggleSwitch" : true, "defaultValue" : "1"},
{"name" : "BOX64_DYNAREC_WAIT", "values" : ["0", "1"], "toggleSwitch" : true, "defaultValue" : "1"}
]
1 change: 0 additions & 1 deletion app/src/main/assets/box86_env_vars.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
[
{"name" : "BOX86_DYNAREC", "values" : ["0", "1"], "toggleSwitch" : true, "defaultValue" : "1"},
{"name" : "BOX86_DYNAREC_SAFEFLAGS", "values" : ["0", "1", "2"], "defaultValue" : "2"},
{"name" : "BOX86_DYNAREC_FASTNAN", "values" : ["0", "1"], "toggleSwitch" : true, "defaultValue" : "1"},
{"name" : "BOX86_DYNAREC_FASTROUND", "values" : ["0", "1"], "toggleSwitch" : true, "defaultValue" : "1"},
Expand Down
Binary file added app/src/main/assets/inputcontrols/icons/15.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/src/main/assets/inputcontrols/icons/16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion app/src/main/assets/inputcontrols/profiles/controls-3.icp
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"id":3,"name":"Virtual Gamepad","cursorSpeed":1,"elements":[{"type":"D_PAD","shape":"CIRCLE","bindings":["GAMEPAD_DPAD_UP","GAMEPAD_DPAD_RIGHT","GAMEPAD_DPAD_DOWN","GAMEPAD_DPAD_LEFT"],"scale":0.85,"x":0.21568627655506134,"y":0.35555556416511536,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"CIRCLE","bindings":["GAMEPAD_BUTTON_X","NONE","NONE","NONE"],"scale":1,"x":0.8133170008659363,"y":0.7333333492279053,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"CIRCLE","bindings":["GAMEPAD_BUTTON_Y","NONE","NONE","NONE"],"scale":1,"x":0.8721405267715454,"y":0.6000000238418579,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"CIRCLE","bindings":["GAMEPAD_BUTTON_A","NONE","NONE","NONE"],"scale":1,"x":0.8721405267715454,"y":0.8666666746139526,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"CIRCLE","bindings":["GAMEPAD_BUTTON_B","NONE","NONE","NONE"],"scale":1,"x":0.9309640526771545,"y":0.7333333492279053,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"RECT","bindings":["GAMEPAD_BUTTON_R2","NONE","NONE","NONE"],"scale":1,"x":0.9215686321258545,"y":0.2888889014720917,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"RECT","bindings":["GAMEPAD_BUTTON_R1","NONE","NONE","NONE"],"scale":1,"x":0.9215686321258545,"y":0.42222222685813904,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"RECT","bindings":["GAMEPAD_BUTTON_L1","NONE","NONE","NONE"],"scale":1,"x":0.0784313753247261,"y":0.42222222685813904,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"RECT","bindings":["GAMEPAD_BUTTON_L2","NONE","NONE","NONE"],"scale":1,"x":0.0784313753247261,"y":0.2888889014720917,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"ROUND_RECT","bindings":["GAMEPAD_BUTTON_START","NONE","NONE","NONE"],"scale":0.85,"x":0.538807213306427,"y":0.9111111164093018,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"ROUND_RECT","bindings":["GAMEPAD_BUTTON_SELECT","NONE","NONE","NONE"],"scale":0.85,"x":0.46078431606292725,"y":0.9111111164093018,"toggleSwitch":false,"text":"","iconId":0},{"type":"STICK","shape":"CIRCLE","bindings":["GAMEPAD_LEFT_THUMB_UP","GAMEPAD_LEFT_THUMB_RIGHT","GAMEPAD_LEFT_THUMB_DOWN","GAMEPAD_LEFT_THUMB_LEFT"],"scale":1,"x":0.10784313827753067,"y":0.7333333492279053,"toggleSwitch":false,"text":"","iconId":0},{"type":"STICK","shape":"CIRCLE","bindings":["GAMEPAD_RIGHT_THUMB_UP","GAMEPAD_RIGHT_THUMB_RIGHT","GAMEPAD_RIGHT_THUMB_DOWN","GAMEPAD_RIGHT_THUMB_LEFT"],"scale":1,"x":0.7843137383460999,"y":0.35555556416511536,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"CIRCLE","bindings":["GAMEPAD_BUTTON_L3","NONE","NONE","NONE"],"scale":0.85,"x":0.21568627655506134,"y":0.9111111164093018,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"CIRCLE","bindings":["GAMEPAD_BUTTON_R3","NONE","NONE","NONE"],"scale":0.85,"x":0.7843137383460999,"y":0.9111111164093018,"toggleSwitch":false,"text":"","iconId":0}]}
{"id":3,"name":"Virtual Gamepad","cursorSpeed":1,"elements":[{"type":"D_PAD","shape":"CIRCLE","bindings":["GAMEPAD_DPAD_UP","GAMEPAD_DPAD_RIGHT","GAMEPAD_DPAD_DOWN","GAMEPAD_DPAD_LEFT"],"scale":0.85,"x":0.21568627655506134,"y":0.35555556416511536,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"CIRCLE","bindings":["GAMEPAD_BUTTON_X","NONE","NONE","NONE"],"scale":1,"x":0.8133170008659363,"y":0.7333333492279053,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"CIRCLE","bindings":["GAMEPAD_BUTTON_Y","NONE","NONE","NONE"],"scale":1,"x":0.8721405267715454,"y":0.6000000238418579,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"CIRCLE","bindings":["GAMEPAD_BUTTON_A","NONE","NONE","NONE"],"scale":1,"x":0.8721405267715454,"y":0.8666666746139526,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"CIRCLE","bindings":["GAMEPAD_BUTTON_B","NONE","NONE","NONE"],"scale":1,"x":0.9309640526771545,"y":0.7333333492279053,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"RECT","bindings":["GAMEPAD_BUTTON_R2","NONE","NONE","NONE"],"scale":1,"x":0.9215686321258545,"y":0.2888889014720917,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"RECT","bindings":["GAMEPAD_BUTTON_R1","NONE","NONE","NONE"],"scale":1,"x":0.9215686321258545,"y":0.42222222685813904,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"RECT","bindings":["GAMEPAD_BUTTON_L1","NONE","NONE","NONE"],"scale":1,"x":0.0784313753247261,"y":0.42222222685813904,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"RECT","bindings":["GAMEPAD_BUTTON_L2","NONE","NONE","NONE"],"scale":1,"x":0.0784313753247261,"y":0.2888889014720917,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"ROUND_RECT","bindings":["GAMEPAD_BUTTON_START","NONE","NONE","NONE"],"scale":0.85,"x":0.538807213306427,"y":0.9111111164093018,"toggleSwitch":false,"text":"","iconId":15},{"type":"BUTTON","shape":"ROUND_RECT","bindings":["GAMEPAD_BUTTON_SELECT","NONE","NONE","NONE"],"scale":0.85,"x":0.46078431606292725,"y":0.9111111164093018,"toggleSwitch":false,"text":"","iconId":16},{"type":"STICK","shape":"CIRCLE","bindings":["GAMEPAD_LEFT_THUMB_UP","GAMEPAD_LEFT_THUMB_RIGHT","GAMEPAD_LEFT_THUMB_DOWN","GAMEPAD_LEFT_THUMB_LEFT"],"scale":1,"x":0.10784313827753067,"y":0.7333333492279053,"toggleSwitch":false,"text":"","iconId":0},{"type":"STICK","shape":"CIRCLE","bindings":["GAMEPAD_RIGHT_THUMB_UP","GAMEPAD_RIGHT_THUMB_RIGHT","GAMEPAD_RIGHT_THUMB_DOWN","GAMEPAD_RIGHT_THUMB_LEFT"],"scale":1,"x":0.7843137383460999,"y":0.35555556416511536,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"CIRCLE","bindings":["GAMEPAD_BUTTON_L3","NONE","NONE","NONE"],"scale":0.85,"x":0.21568627655506134,"y":0.9111111164093018,"toggleSwitch":false,"text":"","iconId":0},{"type":"BUTTON","shape":"CIRCLE","bindings":["GAMEPAD_BUTTON_R3","NONE","NONE","NONE"],"scale":0.85,"x":0.7843137383460999,"y":0.9111111164093018,"toggleSwitch":false,"text":"","iconId":0}]}
Binary file modified app/src/main/assets/patches.tzst
Binary file not shown.
2 changes: 1 addition & 1 deletion app/src/main/assets/wine_startmenu.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
},
{
"name" : "Wordpad",
"path" : "C:/windows/system32/wordpad.exe"
"path" : "C:/windows/system32/write.exe"
},
{
"name" : "Games",
Expand Down
26 changes: 23 additions & 3 deletions app/src/main/java/com/winlator/ContainerDetailFragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
Expand Down Expand Up @@ -38,8 +39,10 @@
import com.winlator.core.StringUtils;
import com.winlator.core.WineInfo;
import com.winlator.core.WineRegistryEditor;
import com.winlator.core.WineThemeManager;
import com.winlator.core.WineUtils;
import com.winlator.widget.CPUListView;
import com.winlator.widget.ColorPickerView;

import org.json.JSONArray;
import org.json.JSONException;
Expand Down Expand Up @@ -148,13 +151,13 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup r
final CPUListView cpuListView = view.findViewById(R.id.CPUListView);
if (editContainer) cpuListView.setCheckedCPUList(container.getCPUList());

createWineRegistryKeysTab(view);
createWineConfigurationTab(view);
createDXComponentsTab(view);
createEnvVarsTab(view);
createDrivesTab(view);

view.findViewById(R.id.BTAddEnvVar).setOnClickListener((v) -> (new AddEnvVarDialog(context, view)).show());
AppUtils.setupTabLayout(view, R.id.TabLayout, R.id.LLTabWineRegistryKeys, R.id.LLTabDXComponents, R.id.LLTabEnvVars, R.id.LLTabDrives, R.id.LLTabAdvanced);
AppUtils.setupTabLayout(view, R.id.TabLayout, R.id.LLTabWineConfiguration, R.id.LLTabDXComponents, R.id.LLTabEnvVars, R.id.LLTabDrives, R.id.LLTabAdvanced);

view.findViewById(R.id.BTConfirm).setOnClickListener((v) -> {
try {
Expand All @@ -171,6 +174,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup r
boolean stopServicesOnStartup = cbStopServicesOnStartup.isChecked();
String box86Preset = Box86_64PresetManager.getSpinnerSelectedId(sBox86Preset);
String box64Preset = Box86_64PresetManager.getSpinnerSelectedId(sBox64Preset);
String desktopTheme = getDesktopTheme(view);

if (editContainer) {
container.setName(name);
Expand All @@ -186,6 +190,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup r
container.setStopServicesOnStartup(stopServicesOnStartup);
container.setBox86Preset(box86Preset);
container.setBox64Preset(box64Preset);
container.setDesktopTheme(desktopTheme);
container.saveData();
saveWineRegistryKeys(view);
getActivity().onBackPressed();
Expand All @@ -205,6 +210,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup r
data.put("stopServicesOnStartup", stopServicesOnStartup);
data.put("box86Preset", box86Preset);
data.put("box64Preset", box64Preset);
data.put("desktopTheme", desktopTheme);

if (wineInfos.size() > 1) {
data.put("wineVersion", wineInfos.get(sWineVersion.getSelectedItemPosition()).identifier());
Expand Down Expand Up @@ -278,8 +284,15 @@ private void saveWineRegistryKeys(View view) {
}
}

private void createWineRegistryKeysTab(View view) {
private void createWineConfigurationTab(View view) {
Context context = getContext();

String[] desktopTheme = (container != null ? container.getDesktopTheme() : WineThemeManager.DEFAULT_THEME+","+WineThemeManager.DEFAULT_BACKGROUND).split(",");
Spinner sDesktopTheme = view.findViewById(R.id.SDesktopTheme);
sDesktopTheme.setSelection(WineThemeManager.Theme.valueOf(desktopTheme[0]).ordinal());
ColorPickerView cpvDesktopBackground = view.findViewById(R.id.CPVDesktopBackground);
cpvDesktopBackground.setColor(Color.parseColor(desktopTheme[1]));

File containerDir = container != null ? container.getRootDir() : null;
File userRegFile = new File(containerDir, ".wine/user.reg");

Expand Down Expand Up @@ -371,6 +384,13 @@ private String getScreenSize(View view) {
return StringUtils.parseIdentifier(value);
}

private String getDesktopTheme(View view) {
Spinner sDesktopTheme = view.findViewById(R.id.SDesktopTheme);
ColorPickerView cpvDesktopBackground = view.findViewById(R.id.CPVDesktopBackground);
WineThemeManager.Theme theme = WineThemeManager.Theme.values()[sDesktopTheme.getSelectedItemPosition()];
return theme+","+cpvDesktopBackground.getColorAsString();
}

private void loadScreenSizeSpinner(View view, String selectedValue) {
final Spinner sScreenSize = view.findViewById(R.id.SScreenSize);

Expand Down
8 changes: 8 additions & 0 deletions app/src/main/java/com/winlator/XServerDisplayActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import com.winlator.core.WineInfo;
import com.winlator.core.WineRegistryEditor;
import com.winlator.core.WineStartMenuCreator;
import com.winlator.core.WineThemeManager;
import com.winlator.core.WineUtils;
import com.winlator.inputcontrols.ControlsProfile;
import com.winlator.inputcontrols.ExternalController;
Expand Down Expand Up @@ -286,6 +287,13 @@ private void setupWineSystemFiles() {
containerDataChanged = true;
}

String desktopTheme = container.getDesktopTheme();
if (!desktopTheme.equals(container.getExtra("desktopTheme"))) {
String[] desktopThemeArray = desktopTheme.split(",");
WineThemeManager.apply(this, WineThemeManager.Theme.valueOf(desktopThemeArray[0]), desktopThemeArray[1]);
container.putExtra("desktopTheme", desktopTheme);
}

if (containerDataChanged) container.saveData();
WineStartMenuCreator.create(this, container);

Expand Down
11 changes: 11 additions & 0 deletions app/src/main/java/com/winlator/container/Container.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.winlator.box86_64.Box86_64Preset;
import com.winlator.core.FileUtils;
import com.winlator.core.WineInfo;
import com.winlator.core.WineThemeManager;
import com.winlator.xenvironment.ImageFs;

import org.json.JSONException;
Expand Down Expand Up @@ -35,6 +36,7 @@ public class Container {
private boolean showFPS;
private boolean stopServicesOnStartup;
private String cpuList;
private String desktopTheme = WineThemeManager.DEFAULT_THEME+","+WineThemeManager.DEFAULT_BACKGROUND;
private String box86Preset = Box86_64Preset.COMPATIBILITY;
private String box64Preset = Box86_64Preset.COMPATIBILITY;
private File rootDir;
Expand Down Expand Up @@ -209,6 +211,14 @@ public File getIconsDir(int size) {
return new File(rootDir, ".local/share/icons/hicolor/"+size+"x"+size+"/apps/");
}

public String getDesktopTheme() {
return desktopTheme;
}

public void setDesktopTheme(String desktopTheme) {
this.desktopTheme = desktopTheme;
}

public Iterable<String[]> drivesIterator() {
return drivesIterator(drives);
}
Expand Down Expand Up @@ -277,6 +287,7 @@ public void saveData() {
data.put("stopServicesOnStartup", stopServicesOnStartup);
data.put("box86Preset", box86Preset);
data.put("box64Preset", box64Preset);
data.put("desktopTheme", desktopTheme);
data.put("extraData", extraData);

if (!wineVersion.equals(WineInfo.MAIN_WINE_VERSION.identifier())) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ private void loadContainers() {
if (data.has("box86Preset")) container.setBox86Preset(data.getString("box86Preset"));
if (data.has("box64Preset")) container.setBox64Preset(data.getString("box64Preset"));
if (data.has("audioDriver")) container.setAudioDriver(data.getString("audioDriver"));
if (data.has("desktopTheme")) container.setDesktopTheme(data.getString("desktopTheme"));

containers.add(container);
maxContainerId = Math.max(maxContainerId, container.id);
Expand Down Expand Up @@ -130,6 +131,7 @@ private Container createContainer(JSONObject data) {
container.setStopServicesOnStartup(data.getBoolean("stopServicesOnStartup"));
container.setBox86Preset(data.getString("box86Preset"));
container.setBox64Preset(data.getString("box64Preset"));
container.setDesktopTheme(data.getString("desktopTheme"));

boolean isMainWineVersion = !data.has("wineVersion") || data.getString("wineVersion").equals(WineInfo.MAIN_WINE_VERSION.identifier());
if (!isMainWineVersion) container.setWineVersion(data.getString("wineVersion"));
Expand Down Expand Up @@ -174,6 +176,7 @@ private void duplicateContainer(Container srcContainer) {
dstContainer.setStopServicesOnStartup(srcContainer.isStopServicesOnStartup());
dstContainer.setBox86Preset(srcContainer.getBox86Preset());
dstContainer.setBox64Preset(srcContainer.getBox64Preset());
dstContainer.setDesktopTheme(srcContainer.getDesktopTheme());
dstContainer.saveData();

maxContainerId++;
Expand Down
18 changes: 18 additions & 0 deletions app/src/main/java/com/winlator/core/CPUStatus.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.winlator.core;

public abstract class CPUStatus {
public static short[] getCurrentClockSpeeds() {
int numProcessors = Runtime.getRuntime().availableProcessors();
short[] clockSpeeds = new short[numProcessors];
for (int i = 0; i < numProcessors; i++) {
int currFreq = FileUtils.readInt("/sys/devices/system/cpu/cpu"+i+"/cpufreq/scaling_cur_freq");
clockSpeeds[i] = (short)(currFreq / 1000);
}
return clockSpeeds;
}

public static short getMaxClockSpeed(int cpuIndex) {
int maxFreq = FileUtils.readInt("/sys/devices/system/cpu/cpu"+cpuIndex+"/cpufreq/cpuinfo_max_freq");
return (short)(maxFreq / 1000);
}
}
13 changes: 13 additions & 0 deletions app/src/main/java/com/winlator/core/FileUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
Expand Down Expand Up @@ -317,4 +318,16 @@ public static boolean isDirectory(Context context, String assetFile) {
public static String toRelativePath(String basePath, String fullPath) {
return StringUtils.removeEndSlash((fullPath.startsWith("/") ? "/" : "")+(new File(basePath).toURI().relativize(new File(fullPath).toURI()).getPath()));
}

public static int readInt(String path) {
int result = 0;
try {
try (RandomAccessFile reader = new RandomAccessFile(path, "r")) {
String line = reader.readLine();
result = !line.isEmpty() ? Integer.parseInt(line) : 0;
}
}
catch (Exception e) {}
return result;
}
}
7 changes: 6 additions & 1 deletion app/src/main/java/com/winlator/core/StringUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,15 @@ public static String getString(Context context, String resName) {
}

public static String formatBytes(long bytes) {
return formatBytes(bytes, true);
}

public static String formatBytes(long bytes, boolean withSuffix) {
if (bytes <= 0) return "0 bytes";
final String[] units = new String[]{"bytes", "KB", "MB", "GB", "TB"};
int digitGroups = (int)(Math.log10(bytes) / Math.log10(1024));
return String.format(Locale.ENGLISH, "%.2f", bytes / Math.pow(1024, digitGroups))+" "+units[digitGroups];
String suffix = withSuffix ? " "+units[digitGroups] : "";
return String.format(Locale.ENGLISH, "%.2f", bytes / Math.pow(1024, digitGroups))+suffix;
}

public static String fromANSIString(byte[] bytes) {
Expand Down
Loading

0 comments on commit eb2993c

Please sign in to comment.