Merge pull request #274 from PojavLauncherTeam/dalvikvm_gl4es_fixc

Bring latest commits to dalvikvm_gl4es
This commit is contained in:
Tran Khanh Duy
2020-08-09 17:34:08 +07:00
committed by GitHub
66 changed files with 1603 additions and 2052 deletions

59
.travis.yml Normal file
View File

@@ -0,0 +1,59 @@
language: android
sudo: required
jdk: oraclejdk8
env:
global:
- ANDROID_API_LEVEL=26
- ANDROID_BUILD_TOOLS_VERSION=26.0.0
- ANDROID_ABI=armeabi-v7a
- ANDROID_ABI=X86
- ANDROID_ABI=ARMEABI_V7A
android:
components:
- tools
- build-tools-$ANDROID_BUILD_TOOLS_VERSION
- android-$ANDROID_API_LEVEL
- extra-android-m2repository
licenses:
- yes | sudo sdkmanager --licenses
- 'android-sdk-preview-license-52d11cd2'
- 'android-sdk-license-.+'
- 'google-gdk-license-.+'
before_install:
- yes | sdkmanager "platforms;android-26"
- yes | sdkmanager "build-tools;26.0.0"
- yes | sdkmanager "platforms;android-28"
- yes | sdkmanager "build-tools;28.0.3"
before_cache:
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
- rm -fr $HOME/.gradle/caches/*/plugin-resolution/
cache:
directories:
- $HOME/.gradle/caches/
- $HOME/.gradle/wrapper/
- $HOME/.android/build-cache
before_script:
- chmod +x gradlew
script:
- ./gradlew clean build
- ./gradlew test
deploy:
provider: releases
api-key: $GITHUB_API_KEY
file: $TRAVIS_BUILD_DIR/app/build/outputs/apk/debug/app-debug.apk
skip_cleanup: true
name: autobuild-$TRAVIS_COMMIT
body: Automatic build of PojavLauncher from the latest source commit ($TRAVIS_COMMIT) built by Travis CI on $(date +'%F %T %Z').
prerelease: true
overwrite: true
target_commitish: $TRAVIS_COMMIT
on:
branch: gl4es

142
README.md
View File

@@ -1,14 +1,156 @@
![badge](https://api.travis-ci.com/PojavLauncherTeam/PojavLauncher.svg?branch=gl4es)
# PojavLauncher
An open source Minecraft: Java Edition launcher for Android based from Boardwalk. Support up-to Minecraft 1.11
(Codes has not been sorted yet, it contains ton of classes without packing to module).
Discord server: https://discord.gg/6RpEJda
## iOS version?
- Impossible for directly run. There's RoboVM but is AOT Compiler. You could also try UTM with Android-x86.
- OpenJDK 9 and GL4ES has iOS port so maybe run in a jailbreaked device. I don't have a Mac OS X device to build one.
## About this branch
- This branch attempt to launch Minecraft using command line like `dalvikvm` and `app_process`.
- Status: working partial, EGL Context not yet shared, process get crashed if attempt to execute OpenGL command.
## Anything if this successful?
- Able to custom min/max RAM heap.
- Solve some incompatible issues.
## Installing Forge?
Not implemented yet.
## Known issues
- Some Huawei devices can't run Minecraft or OptiFine.
- Can't run multiple versions at same time.
## FAQ
### • Unable to drag item in inventory?
Disable touchscreen mode. Open Minecraft Settings -> Controls -> Touchscreen Mode: Toggle to OFF.
### • Unable to install Minecraft 1.9 or above, can't convert library `net.java.dev.jna`?
Increase max DX references. Launcher Options -> Settings -> Increase max DX references to 8k.
### • Other bugs or still not working?
#### Report an issue with:
- Full error log: press **Show more** and copy.
#### If it isn't a Minecraft crash:
- Device name
- Android version
## Minecraft versions worked in PojavLauncher 2.4.2
<table>
<thead>
<tr>
<th></th>
<th align="center" colspan="7">Minecraft version</th>
</tr>
<tr>
<th>Android</th>
<th align="center">1.7.10</th>
<th align="center">1.8</th>
<th align="center">1.9</th>
<th align="center">1.10</th>
<th align="center">1.11</th>
<th align="center">1.12</th>
<th align="center">1.12.2</th>
</tr>
</thead>
<tbody>
<tr>
<td>5.x</td>
<td align="center"><b>Yes</b></td>
<td align="center"><b>Yes</b></td>
<td align="center"><b>Yes</b></td>
<td align="center">???</td>
<td align="center">???</td>
<td align="center"><a href="https://stackoverflow.com/a/57861173">No</a></td>
<td align="center"><a href="https://stackoverflow.com/a/57861173">No</a></td>
</tr>
<tr>
<td>6.0</td>
<td align="center"><b>Yes</b></td>
<td align="center"><b>Yes</b></td>
<td align="center"><b>Yes</b></td>
<td align="center">???</td>
<td align="center">???</td>
<td align="center"><a href="https://stackoverflow.com/a/57861173">No</a></td>
<td align="center"><a href="https://stackoverflow.com/a/57861173">No</a></td>
</tr>
</tbody>
<tbody>
<tr>
<td>7.x</td>
<td align="center">???</td>
<td align="center"><b>Yes</b></td>
<td align="center"><b>Yes</b></td>
<td align="center"><b>Yes</b></td>
<td align="center"><b>Yes</b></td>
<td align="center"><a href="https://stackoverflow.com/a/57861173">No</a></td>
<td align="center"><a href="https://stackoverflow.com/a/57861173">No</a></td>
</tr>
<tr>
<td>8.x</td>
<td align="center"><b>Yes</b></td>
<td align="center"><b>Yes</b></td>
<td align="center"><b>Yes</b></td>
<td align="center">???</td>
<td align="center">???</td>
<td align="center"><a href="https://stackoverflow.com/a/57861173">Java8</a></td>
<td align="center"><a href="https://stackoverflow.com/a/57861173">Java8</a></td>
</tr>
</tbody>
<tbody>
<tr>
<td>9.0</td>
<td align="center"><b>Yes</b></td>
<td align="center"><b>Yes</b></td>
<td align="center"><b>Yes</b></td>
<td align="center"><b>Yes</b></td>
<td align="center"><b>Yes</b></td>
<td align="center"><a href="https://stackoverflow.com/a/57861173">Java8</a></td>
<td align="center"><a href="https://stackoverflow.com/a/57861173">Java8</a></td>
</tr>
<tr>
<td>10.0</td>
<td align="center"><a href="https://github.com/khanhduytran0/PojavLauncher/issues/7#issue-586928527"><b>Yes</b></a></td>
<td align="center"><a href="https://github.com/khanhduytran0/PojavLauncher/issues/7#issue-586928527"><b>Yes</b></a></td>
<td align="center"><a href="https://github.com/khanhduytran0/PojavLauncher/issues/7#issue-586928527"><b>Yes</b></a></td>
<td align="center"><a href="https://github.com/khanhduytran0/PojavLauncher/issues/7#issue-586928527"><b>Yes</b></a></td>
<td align="center"><a href="https://github.com/khanhduytran0/PojavLauncher/issues/7#issue-586928527"><b>Yes</b></a></td>
<td align="center"><a href="https://stackoverflow.com/a/57861173">Java8</a></td>
<td align="center"><a href="https://stackoverflow.com/a/57861173">Java8</a></td>
</tr>
</tbody>
</table>
## OptiFine worked in PojavLauncher 2.4.2
|Android version | 9.0 |???|???|Manually Android 10|9.0|
|-----------------|------|---|---|-----|-----|
|Minecraft version|1.7.10|1.8|1.9| 1.10| 1.11|
|OptiFine |OptiFine_1.7.10_HD_U_E7|???|???|OptiFine_1.10_HD_U_H5|OptiFine_1.11_HD_U_F5|
|Status |[Worked](https://youtu.be/In_EPebQG7Q)|???|???|[Worked (manually)](https://youtu.be/TJeJcPFgzcI)|[Worked (with 1 hack)](https://youtu.be/eIawM9UmQ88)
## A note about 1.12.x
- Minecraft 1.12.x can be run on Android 8.0 and above by use d8 for desugar and dexing in the latest v2, but will crash in singleplayer.
## Solution found!
- [twaik/libcw](https://github.com/twaik/libcw) or [shodruky-rhyammer/gl-streaming](https://github.com/shodruky-rhyammer/gl-streaming) but I'm busy at v3.
## License
- PojavLauncher is licensed under [GNU GPLv3](https://github.com/khanhduytran0/PojavLauncher/blob/master/LICENSE).
## Using libraries & Third party licenses
- (v2) Boardwalk: [Apache License 2.0](https://github.com/zhuowei/Boardwalk/blob/master/LICENSE).
- (v2) LegacyLauncher: (unknown license).<br>
- (all) Android Support Libraries & DX Dexer: [Apache License 2.0](https://android.googlesource.com/platform/prebuilts/maven_repo/android/+/master/NOTICE.txt).
- (all) gl4es: [MIT License](https://github.com/ptitSeb/gl4es/blob/master/LICENSE).<br>
- (v3) BusyBox: [GNU GPLv2 License](https://busybox.net/license.html).<br>
- (v3) OpenJDK: [GNU GPLv2 License](https://openjdk.java.net/legal/gplv2+ce.html).<br>
- (v3) PRoot: [GNU GPLv2 License](https://github.com/termux/proot/blob/master/COPYING).<br>
- (v3) XVnc: [GNU GPLv3 License](https://github.com/theqvd/qvd-client-android/blob/master/LICENSE.txt).
- (all) LWJGL 2: [Legacy LWJGL License](http://legacy.lwjgl.org/license.php.html).<br>

View File

@@ -2,14 +2,19 @@ apply plugin: 'com.android.application'
android {
compileSdkVersion 26
buildToolsVersion '26.0.0'
dexOptions {
javaMaxHeapSize "4g"
}
lintOptions {
abortOnError false
}
defaultConfig {
applicationId "net.kdt.pojavlaunch"
minSdkVersion 21
targetSdkVersion 26
versionCode 156235
versionName "2.5.1_6398b_20200719"
versionName "2.5.3_6400b_20200802"
multiDexEnabled true //important
}
buildTypes {
@@ -17,7 +22,8 @@ android {
// Don't set to true or java.awt will be a.a or something similar.
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
multiDexEnabled = true
// defaultConfig already set
// multiDexEnabled = true
debuggable = true
}
}

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

@@ -15,6 +15,9 @@
android:icon="@drawable/ic_launcher"
android:roundIcon="@drawable/ic_launcher"
android:resizeableActivity="true">
<meta-data
android:name="android.max_aspect"
android:value="ratio_float"/>
<activity
android:screenOrientation="sensorLandscape"
@@ -27,6 +30,12 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:theme="@style/MenuDialog"
android:screenOrientation="sensorLandscape"
android:name=".FatalErrorActivity"
android:configChanges="keyboardHidden|orientation|screenSize"/>
<activity
android:screenOrientation="sensorLandscape"
@@ -42,7 +51,6 @@
android:launchMode="standard"
android:multiprocess="true"
android:screenOrientation="sensorLandscape"
android:theme="@style/RunTheme"
android:name=".MainActivity"
android:configChanges="keyboardHidden|orientation|screenSize"/>
@@ -55,6 +63,7 @@
android:screenOrientation="sensorLandscape"
android:name=".prefs.PojavPreferenceActivity"
android:configChanges="keyboardHidden|orientation|screenSize"/>
</application>
</manifest>

View File

Binary file not shown.

View File

@@ -0,0 +1,29 @@
package com.android.internal.awt;
import java.awt.*;
public class AndroidGraphicsDevice extends GraphicsDevice
{
public GraphicsConfiguration[] mConfigurations = new GraphicsConfiguration[]{new AndroidGraphicsConfiguration()};
@Override
public GraphicsConfiguration[] getConfigurations() {
return mConfigurations;
}
@Override
public GraphicsConfiguration getDefaultConfiguration() {
return mConfigurations[0];
}
@Override
public String getIDstring() {
return "Android";
}
@Override
public int getType() {
return TYPE_IMAGE_BUFFER;
}
}

View File

@@ -0,0 +1,51 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Alexey A. Petrenko, Oleg V. Khaschansky
* @version $Revision$
*/
package com.android.internal.awt;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Locale;
import org.apache.harmony.awt.gl.CommonGraphicsEnvironment;
import java.awt.*;
/**
* AndroidGraphicsEnvironment implementation
*
*/
public class AndroidGraphicsEnvironment extends CommonGraphicsEnvironment
{
public GraphicsDevice[] mGraphicsDevices = new GraphicsDevice[]{new AndroidGraphicsDevice()};
@Override
public GraphicsDevice getDefaultScreenDevice() throws HeadlessException {
return mGraphicsDevices[0];
}
@Override
public GraphicsDevice[] getScreenDevices() throws HeadlessException {
return mGraphicsDevices;
}
}

View File

@@ -34,12 +34,12 @@ import org.apache.harmony.awt.gl.CommonGraphics2DFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.content.Context;
import org.apache.harmony.awt.gl.*;
public class AndroidGraphicsFactory extends CommonGraphics2DFactory {
public GraphicsEnvironment createGraphicsEnvironment(WindowFactory wf) {
// TODO Auto-generated method stub
return null;
return new AndroidGraphicsEnvironment();
}
public Font embedFont(String fontFilePath) {

View File

@@ -47,7 +47,7 @@ public class ActionPopupWindow extends PinnedPopupWindow implements OnClickListe
try {
Field f = perType.getDeclaredField(name);
f.setAccessible(true);
return f.get(null);
return (int) f.get(null);
} catch (Throwable th) {
th.printStackTrace();
}
@@ -63,7 +63,7 @@ public class ActionPopupWindow extends PinnedPopupWindow implements OnClickListe
try {
Field f = perType.getDeclaredField(name);
f.setAccessible(true);
return f.get(null);
return (int) f.get(null);
} catch (Throwable th) {
th.printStackTrace();
}

View File

@@ -80,7 +80,7 @@ public abstract class HandleView extends View implements ViewPositionListener, V
try {
Field f = perType.getDeclaredField(name);
f.setAccessible(true);
return f.get(null);
return (int) f.get(null);
} catch (Throwable th) {
th.printStackTrace();
}

View File

@@ -7,6 +7,7 @@ import android.util.*;
import android.view.*;
import android.widget.*;
import android.view.View.*;
import net.kdt.pojavlaunch.*;
public class MineButton extends Button
{
@@ -42,20 +43,16 @@ public class MineButton extends Button
private LayerDrawable layerdrawable, layerdrawablefocus;
public MineButton(Context ctx)
{
super(ctx);
init();
public MineButton(Context ctx) {
this(ctx, null);
}
public MineButton(Context ctx, AttributeSet attrs)
{
public MineButton(Context ctx, AttributeSet attrs) {
super(ctx, attrs);
init();
}
public void init()
{
public void init() {
getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {

View File

@@ -4,6 +4,7 @@ import android.content.*;
import android.util.*;
import android.widget.*;
import net.kdt.pojavlaunch.*;
import android.graphics.*;
public class MineEditText extends EditText
{
@@ -21,7 +22,8 @@ public class MineEditText extends EditText
public void init()
{
setBackgroundResource(R.drawable.border_edittext);
// setBackgroundResource(R.drawable.border_edittext);
setBackgroundColor(Color.parseColor("#131313"));
setPadding(5, 5, 5, 5);
}
}

View File

@@ -6,39 +6,26 @@ import android.support.v7.app.*;
import android.view.*;
import android.widget.*;
import net.kdt.pojavlaunch.*;
import java.util.*;
import android.content.*;
import com.kdt.mcgui.*;
public class MineActivity extends AppCompatActivity implements View.OnClickListener
{
private int topId = 150001;
private boolean showBeforeView = true;
private FontChanger fontChanger;
private ImageButton menu;
private LinearLayout content, undertop;
private LayoutInflater li;
public ViewGroup replaceFonts(ViewGroup viewTree)
{
if (fontChanger == null) fontChanger = new FontChanger(getAssets(), "font/NotoSans-Bold.ttf");
return fontChanger.replaceFonts(viewTree);
}
public View replaceFont(TextView view)
{
if (fontChanger == null) fontChanger = new FontChanger(getAssets(), "font/NotoSans-Bold.ttf");
return fontChanger.replaceFont(view);
}
@Override
protected void onCreate(Bundle savedInstanceState)
{
protected void onCreate(Bundle savedInstanceState) {
this.onCreate(savedInstanceState, true);
}
protected void onCreate(Bundle savedInstanceState, boolean showBeforeView)
{
protected void onCreate(Bundle savedInstanceState, boolean showBeforeView) {
super.onCreate(savedInstanceState);
this.showBeforeView = showBeforeView;
@@ -59,10 +46,12 @@ public class MineActivity extends AppCompatActivity implements View.OnClickListe
li.inflate(R.layout.top_bar, top, true);
li.inflate(R.layout.bottom_bar, btm, true);
replaceFonts(btm);
replaceFont((TextView) top.findViewById(R.id.topbar_language_text));
FontChanger.changeFonts(btm);
// replaceFont((TextView) top.findViewById(R.id.topbar_navmenu_changelang));
Spinner changeLangSpinner = ((Spinner) top.findViewById(R.id.topbar_navmenu_changelang));
// Locale l = getResources().getConfiguration().locale;
RelativeLayout.LayoutParams conLay = new RelativeLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
conLay.addRule(root.BELOW, topId);
conLay.bottomMargin = 66;
@@ -99,7 +88,7 @@ public class MineActivity extends AppCompatActivity implements View.OnClickListe
}
li.inflate(resource, content, true);
replaceFonts(content);
FontChanger.changeFonts(content);
}
@Override
@@ -111,7 +100,7 @@ public class MineActivity extends AppCompatActivity implements View.OnClickListe
content.addView(view);
if (view instanceof ViewGroup) {
replaceFonts((ViewGroup) view);
FontChanger.changeFonts((ViewGroup) view);
}
}

View File

@@ -21,7 +21,8 @@
package java.awt;
import org.apache.harmony.awt.internal.nls.Messages;
import org.apache.harmony.awt.internal.nls.*;
import org.lwjgl.opengl.*;
/**
* The GraphicsDevice class describes the graphics devices (such as screens or
@@ -62,7 +63,7 @@ public abstract class GraphicsDevice {
* Constructor is not to be used directly as this class is abstract.
*/
protected GraphicsDevice() {
displayMode = new DisplayMode(0, 0, DisplayMode.BIT_DEPTH_MULTI,
displayMode = new DisplayMode(AndroidDisplay.windowWidth, AndroidDisplay.windowHeight, DisplayMode.BIT_DEPTH_MULTI,
DisplayMode.REFRESH_RATE_UNKNOWN);
}

View File

@@ -87,7 +87,10 @@ public abstract class GraphicsEnvironment {
* keyboard, or mouse, false otherwise.
*/
public static boolean isHeadless() {
return "true".equals(System.getProperty("java.awt.headless"));
return false;
// Disable headless...
// "true".equals(System.getProperty("java.awt.headless"));
}
/**

View File

@@ -169,14 +169,17 @@ public final class HeadlessToolkit extends ToolkitImpl {
try {
ComponentInternals.setComponentInternals(new ComponentInternalsImpl());
// ???AWT: new EventQueue(this); // create the system EventQueue
// ???AWT: dispatcher = new Dispatcher(this);
// ???AWT:
dispatcher = new Dispatcher(this);
desktopProperties = new HashMap<String, Object>();
// ???AWT: desktopPropsSupport = new PropertyChangeSupport(this);
// ???AWT: awtEventsManager = new AWTEventsManager();
// ???AWT:
awtEventsManager = new AWTEventsManager();
// ???AWT: dispatchThread = new HeadlessEventDispatchThread(this,
// dispatcher);
// ???AWT: dtk = DTK.getDTK();
dispatchThread.start();
// dispatchThread.start();
} finally {
unlockAWT();
}

View File

@@ -44,6 +44,16 @@ public class DroidToJavaKey {
}
*/
// Fix press 'e' key close inventory (while search item)
// Should it be or other ways?
/*
if (!AndroidDisplay.grab && keyEvent.getDisplayLabel() != 'e') {
mainActivity.sendKeyPress(keyEvent.getDisplayLabel(), status);
} else {
mainActivity.sendKeyPress(keyEvent.getDisplayLabel());
}
*/
mainActivity.sendKeyPress(keyEvent.getDisplayLabel(), status);
}
}

View File

@@ -0,0 +1,73 @@
package net.kdt.pojavlaunch;
import android.app.*;
import android.content.*;
import android.os.*;
import android.support.v7.app.*;
import android.util.*;
import java.awt.*;
import java.awt.datatransfer.*;
import android.support.v7.app.AlertDialog;
public class FatalErrorActivity extends AppCompatActivity
{
public static void showError(Context ctx, String savePath, boolean storageAllow, /* boolean isFatalErr, */ Throwable th) {
Intent ferrorIntent = new Intent(ctx, FatalErrorActivity.class);
ferrorIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
ferrorIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
ferrorIntent.putExtra("throwable", th);
ferrorIntent.putExtra("savePath", savePath);
ferrorIntent.putExtra("storageAllow", storageAllow);
// ferrorIntent.putExtra("isFatal", isFatalErr);
ctx.startActivity(ferrorIntent);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle extras = getIntent().getExtras();
boolean storageAllow = extras.getBoolean("storageAllow");
final String strStackTrace = Log.getStackTraceString((Throwable) extras.getSerializable("throwable"));
String strSavePath = extras.getString("savePath");
String errHeader = storageAllow ?
"Crash stack trace saved to " + strSavePath + "." :
"Storage permission is required to save crash stack trace!";
// boolean isFatalError = extras.getBoolean("isFatal", false);
new AlertDialog.Builder(this)
.setTitle(R.string.error_fatal)
.setMessage(errHeader + "\n\n" + strStackTrace)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface p1, int p2) {
finish();
}
})
.setNegativeButton(R.string.global_restart, new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface p1, int p2) {
startActivity(new Intent(FatalErrorActivity.this, PojavLoginActivity.class));
}
})
.setNeutralButton(android.R.string.copy, new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface p1, int p2) {
StringSelection errData = new StringSelection(strStackTrace);
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(errData, null);
finish();
}
})
//.setNegativeButton("Report (not available)", null)
.setCancelable(false)
.show();
// Tools.showError(this, isFatalError ? R.string.error_fatal : R.string.global_error, th, true);
}
}

View File

@@ -4,37 +4,31 @@ import android.content.res.*;
import android.graphics.*;
import android.view.*;
import android.widget.*;
import android.content.*;
import com.kdt.mcgui.*;
public class FontChanger
{
private Typeface typeface;
public FontChanger(Typeface typeface)
{
this.typeface = typeface;
}
public FontChanger(AssetManager assets, String assetsFontFileName)
{
typeface = Typeface.createFromAsset(assets, assetsFontFileName);
}
public ViewGroup replaceFonts(ViewGroup viewTree)
{
View child;
private static Typeface fNotoSans, fMinecraftTen;
public static void initFonts(Context ctx) {
fNotoSans = Typeface.createFromAsset(ctx.getAssets(), "font/NotoSans-Bold.ttf");
fMinecraftTen = Typeface.createFromAsset(ctx.getAssets(), "font/minecraft-ten.ttf");
}
public static void changeFonts(ViewGroup viewTree) {
View child;
for(int i = 0; i < viewTree.getChildCount(); ++i) {
child = viewTree.getChildAt(i);
if (child instanceof ViewGroup) {
replaceFonts((ViewGroup)child);
changeFonts((ViewGroup) child);
} else if (child instanceof TextView) {
replaceFont((TextView) child);
changeFont((TextView) child);
}
}
return viewTree;
}
}
public View replaceFont(TextView view) {
view.setTypeface(typeface);
return view;
public static void changeFont(TextView view) {
view.setTypeface(view instanceof MineButton ? fMinecraftTen : fNotoSans);
}
}

View File

@@ -13,7 +13,7 @@ public class JMinecraftVersionList {
public Version[] versions;
public static class Version {
// Since 1.13
// Since 1.13, so it's one of ways to check
public Arguments arguments;
public String assets;

View File

@@ -67,13 +67,29 @@ public class MCLauncherActivity extends AppCompatActivity
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
gson = new Gson();
DisplayMetrics dm = Tools.getDisplayMetrics(this);
AndroidDisplay.windowWidth = dm.widthPixels;
AndroidDisplay.windowHeight = dm.heightPixels;
viewInit();
final View decorView = getWindow().getDecorView();
decorView.setOnSystemUiVisibilityChangeListener (new View.OnSystemUiVisibilityChangeListener() {
@Override
public void onSystemUiVisibilityChange(int visibility) {
if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
decorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}
}
});
}
// DEBUG
//new android.support.design.widget.NavigationView(this);
@@ -116,7 +132,7 @@ public class MCLauncherActivity extends AppCompatActivity
} catch(Exception e) {
//Tools.throwError(this, e);
e.printStackTrace();
toast(getStr(R.string.toast_login_error) + " " + e.getMessage());
toast(getStr(R.string.toast_login_error, e.getMessage()));
finish();
}
@@ -400,9 +416,11 @@ public class MCLauncherActivity extends AppCompatActivity
}
@Override
protected void onResume()
{
protected void onResume(){
super.onResume();
final int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
final View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(uiOptions);
}
private boolean canBack = false;
@@ -533,6 +551,7 @@ public class MCLauncherActivity extends AppCompatActivity
libItem.name.startsWith("com.mojang:realms") ||
libItem.name.startsWith("net.java.jinput") ||
libItem.name.startsWith("net.minecraft.launchwrapper") ||
libItem.name.startsWith("optifine:launchwrapper-of") ||
// libItem.name.startsWith("org.lwjgl.lwjgl:lwjgl") ||
libItem.name.startsWith("org.lwjgl") ||
libItem.name.startsWith("tv.twitch")
@@ -610,7 +629,7 @@ public class MCLauncherActivity extends AppCompatActivity
}
}
publishProgress("5", getStr(R.string.mcl_launch_download_client) + p1[0]);
publishProgress("5", getStr(R.string.mcl_launch_download_client, p1[0]));
outUnpatchedConvert = new File(unpatchedPath);
boolean patchedExist = new File(patchedFile).exists();
if (!patchedExist) {

View File

@@ -3,7 +3,6 @@ package net.kdt.pojavlaunch;
import android.app.*;
import android.content.*;
import android.graphics.*;
import android.graphics.drawable.*;
import android.os.*;
import android.support.design.widget.*;
import android.support.v4.widget.*;
@@ -22,17 +21,16 @@ import java.io.*;
import java.lang.reflect.*;
import java.security.*;
import java.util.*;
import javax.crypto.*;
import javax.microedition.khronos.egl.*;
import javax.microedition.khronos.opengles.*;
import net.kdt.pojavlaunch.exit.*;
import net.kdt.pojavlaunch.prefs.*;
import net.kdt.pojavlaunch.value.customcontrols.*;
import optifine.*;
import org.apache.harmony.security.fortress.*;
import org.lwjgl.input.*;
import org.lwjgl.opengl.*;
import org.lwjgl.util.applet.*;
import org.lwjgl.util.glu.tessellation.*;
import sun.security.jca.*;
import android.app.AlertDialog;
import android.graphics.drawable.Drawable;
@@ -40,6 +38,7 @@ import net.kdt.pojavlaunch.value.customcontrols.*;
import com.google.android.gles_jni.*;
import com.kdt.minecraftegl.*;
public class MainActivity extends AppCompatActivity implements OnTouchListener, OnClickListener
{
public static final String initText = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ";
@@ -127,6 +126,7 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
private boolean lastGrab = false;
private boolean isExited = false;
private boolean isLogAllow = false;
private int navBarHeight = 40;
// private static Collection<? extends Provider.Service> rsaPkcs1List;
@@ -141,11 +141,100 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
setContentView(R.layout.main);
try {
final View decorView = getWindow().getDecorView();
decorView.setOnSystemUiVisibilityChangeListener (new View.OnSystemUiVisibilityChangeListener() {
@Override
public void onSystemUiVisibilityChange(int visibility) {
if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
decorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}
}
});
/*
ExitManager.setExitTrappedListener(new ExitManager.ExitTrappedListener(){
@Override
public void onExitTrapped()
{
runOnUiThread(new Runnable(){
@Override
public void run() {
isExited = true;
try {
SecondaryDexLoader.resetFieldArray(getClassLoader());
} catch (Throwable th) {
th.printStackTrace();
}
AlertDialog.Builder d = new AlertDialog.Builder(MainActivity.this);
d.setTitle(R.string.mcn_exit_title);
try {
File crashLog = Tools.lastFileModified(Tools.crashPath);
if(crashLog != null && Tools.read(crashLog.getAbsolutePath()).startsWith("---- Minecraft Crash Report ----")){
d.setMessage(R.string.mcn_exit_crash);
} else {
fullyExit();
return;
}
} catch (Throwable th) {
d.setMessage(getStr(R.string.mcn_exit_errcrash) + "\n" + Log.getStackTraceString(th));
}
d.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface p1, int p2)
{
fullyExit();
}
});
d.setCancelable(false);
d.show();
}
});
}
});
try {
ExitManager.disableSystemExit();
} catch (Throwable th) {
Log.w(Tools.APP_NAME, "Could not disable System.exit() method!", th);
}
*/
File optDir = getDir("dalvik-cache", 0);
optDir.mkdirs();
launchOptimizedDirectory = optDir.getAbsolutePath();
mProfile = PojavProfile.getCurrentProfileContent(this);
mVersionInfo = Tools.getVersionInfo(mProfile.getVersion());
setTitle("Minecraft " + mProfile.getVersion());
//System.loadLibrary("gl4es");
/*
if (mVersionInfo.arguments != null) {
System.loadLibrary("lwjgl32");
System.loadLibrary("lwjgl_opengl32");
System.loadLibrary("lwjgl_stb32");
}
*/
if (mVersionInfo.arguments == null) {
// Minecraft 1.12 and below
// TODO uncomment after fix
// SecondaryDexLoader.install(getClassLoader(), Arrays.asList(new File[]{new File(Tools.libraries + "/" + Tools.artifactToPath("org.lwjgl", "lwjglboardwalk", "2.9.1"))}), optDir);
}
this.displayMetrics = Tools.getDisplayMetrics(this);
AndroidDisplay.windowWidth = displayMetrics.widthPixels / scaleFactor;
@@ -598,6 +687,10 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
AndroidContextImplementation.draw = egl10.eglGetCurrentSurface(EGL10.EGL_DRAW);
egl10.eglMakeCurrent(AndroidContextImplementation.display, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
System.out.println(new StringBuffer().append("Gave up context: ").append(AndroidContextImplementation.context).toString());
AndroidDisplay.windowWidth += navBarHeight;
*/
EGLContextImpl eglContextImpl = (EGLContextImpl) egl10.eglGetCurrentContext();
@@ -608,6 +701,7 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
} catch (Throwable th) {
Tools.showError(MainActivity.this, th, true);
}
new Thread(new Runnable(){
@@ -636,7 +730,7 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
});
glSurfaceView.setPreserveEGLContextOnPause(true);
glSurfaceView.setRenderMode(MinecraftGLView.RENDERMODE_CONTINUOUSLY);
glSurfaceView.requestRender();
// glSurfaceView.requestRender();
} catch (Throwable e) {
e.printStackTrace();
Tools.showError(this, e, true);
@@ -693,7 +787,10 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
public void onResume() {
super.onResume();
mIsResuming = true;
glSurfaceView.requestRender();
if (glSurfaceView != null) glSurfaceView.requestRender();
final int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
final View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(uiOptions);
}
@Override
@@ -927,7 +1024,20 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
public static String launchOptimizedDirectory;
public static String launchLibrarySearchPath;
private void runCraft(long eglContext) throws Throwable
{
LoggerJava.OnStringPrintListener printLog = new LoggerJava.OnStringPrintListener(){
@Override
public void onCharPrint(char c) {
appendToLog(Character.toString(c));
}
};
PrintStream theStreamErr = new PrintStream(new LoggerJava.LoggerOutputStream(System.err, printLog));
PrintStream theStreamOut = new PrintStream(new LoggerJava.LoggerOutputStream(System.out, printLog));
System.setErr(theStreamErr);
System.setOut(theStreamOut);
String[] launchArgs = getMCArgs();
// Setup OptiFine
@@ -938,17 +1048,24 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
AndroidOptiFineUtilities.originalOptifineJar = PojavPreferenceActivity.PREF_FORGETOF ? "/null/file.jar" : optifineJar;
}
File optDir = getDir("dalvik-cache", 0);
optDir.mkdirs();
launchClassPath = Tools.generate(mProfile.getVersion());
launchOptimizedDirectory = optDir.getAbsolutePath();
launchClassPath = Tools.generateLaunchClassPath(mProfile.getVersion());
launchLibrarySearchPath = getApplicationInfo().nativeLibraryDir;
/* gl4es
if (mVersionInfo.mainClass.equals("net.minecraft.launchwrapper.Launch")) {
net.minecraft.launchwrapper.Launch.main(launchArgs);
} else {
/*
PrintStream theStreamErr = new PrintStream(new LoggerJava.LoggerOutputStream(System.err, printLog));
System.setErr(theStreamErr);
*/
fixRSAPadding(this);
appendlnToLog("Running Minecraft with classpath: \n" + launchClassPath + "\n", false);
// Load classpath
DexClassLoader launchBaseLoader = new DexClassLoader(launchClassPath, launchOptimizedDirectory, launchLibrarySearchPath, getClassLoader());
LoggerJava.OnStringPrintListener printLog = new LoggerJava.OnStringPrintListener(){
@Override
public void onCharPrint(char c) {
@@ -963,6 +1080,7 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
ShellProcessOperation shell = new ShellProcessOperation(new ShellProcessOperation.OnPrintListener(){
@Override
public void onPrintLine(String text) {
appendToLog(text);
@@ -1012,59 +1130,107 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
});
}
public static void fixRSAPadding(final Activity act) {
/*
private void createEGLHackStuff() {
}
public void fixRSAPadding() throws Exception {
*/
// welcome to the territory of YOLO; I'll be your tour guide for today.
final boolean isLegacyPatch = Build.VERSION.SDK_INT < 24;
try {
List<Provider.Service> rsaList, rsaPkcs1List;
if (android.os.Build.VERSION.SDK_INT > 23) { // Nougat
/*
* Since Android 7, it use OpenJDK sun.security.jca.GetInstance
* But it's not part of Android SDK.
*/
rsaList = getCipherServices("RSA");
rsaPkcs1List = getCipherServices("RSA/ECB/PKCS1PADDING");
} else {
rsaList = Services.getServices("Cipher.RSA");
rsaPkcs1List = Services.getServices("Cipher.RSA/ECB/PKCS1PADDING");
}
if (!isLegacyPatch) {
/*
System.out.println("RSAPadding BEFORE");
debug_printServiceInfo(System.out, "Cipher.RSA");
*/
/*
* Not .clear() directly since the entry removal is protected,
* so some reflections to reset it
*/
Modifiable.resetServiceList(rsaList);
rsaList.addAll(rsaPkcs1List);
Map<Provider, Provider.Service> rsaMap, rsaPkcs1Map;
rsaMap = getCipherServicesMap("Cipher", "RSA");
rsaPkcs1Map = getCipherServicesMap("Cipher", "RSA/ECB/PKCS1PADDING");
for (Map.Entry<Provider, Provider.Service> set : rsaMap.entrySet()) {
System.out.println(set.getKey().getName() + ": ");
for (Map.Entry en : set.getKey().entrySet()) {
if (en.getKey().toString().contains("Cipher.RSA"))
System.out.println(en.getKey().toString() + " = " + en.getValue().toString());
}
set.getKey().remove("Cipher.RSA SupportedKeyFormats");
int spend = 0;
for (Map.Entry<Provider, Provider.Service> s : rsaPkcs1Map.entrySet()) {
if (spend == 0) {
set.getKey().put("Cipher.RSA", s.getValue().getClassName());
set.getKey().put("Cipher.RSA SupportedKeyClasses", s.getKey().get("Cipher.RSA/ECB/PKCS1Padding SupportedKeyClasses"));
List<String> rsaAliasList = Modifiable.getServiceAliases(set.getValue());
rsaAliasList.clear();
rsaAliasList.addAll(Modifiable.getServiceAliases(s.getValue()));
spend++;
}
}
// printList(set.getKey().getServices());
/*
System.out.println("RSAPadding AFTER");
debug_printServiceInfo(System.out, "Cipher.RSA");
*/
}
} else {
Collection<Provider.Service> rsaList, rsaPkcs1List;
rsaList = getCipherServices("Cipher", "RSA");
rsaPkcs1List = getCipherServices("Cipher", "RSA/ECB/PKCS1PADDING");
rsaList.clear();
rsaList.addAll(rsaPkcs1List);
}
} catch (Throwable th) {
th.printStackTrace();
final File rsaFixFile = new File(Tools.MAIN_PATH, "rsapadding_error.txt");
// Debug information
PrintStream rsaFixStream = new PrintStream(rsaFixFile);
rsaFixStream.println("--- RSA PADDING ERROR ---");
rsaFixStream.println("• Error stack trace");
th.printStackTrace(rsaFixStream);
rsaFixStream.println();
rsaFixStream.println("• RSAPadding info");
rsaFixStream.println(" - Patch method: " + (Build.VERSION.SDK_INT < 24 ? "Direct (no" : "Reflection Bypass (with") + " security check)");
rsaFixStream.println(" - getDeclaredMethods() return");
debug_printMethodInfo(rsaFixStream, Provider.class.getDeclaredMethods());
rsaFixStream.println(" - getMethods() return");
debug_printMethodInfo(rsaFixStream, Provider.class.getMethods());
rsaFixStream.println("• System info");
rsaFixStream.println(" - Android version " + Build.VERSION.RELEASE + " (API " + Integer.toString(Build.VERSION.SDK_INT) + ")");
rsaFixStream.close();
try {
// Debug information
PrintStream rsaFixStream = new PrintStream(rsaFixFile);
rsaFixStream.println("--- RSA PADDING ERROR ---");
rsaFixStream.println("• Error stack trace");
th.printStackTrace(rsaFixStream);
rsaFixStream.println();
rsaFixStream.println("• RSAPadding info");
rsaFixStream.println(" - Patch method: " + (isLegacyPatch ? "Apache Harmony" : "OpenJDK sun.security.jca"));
if (!isLegacyPatch) {
rsaFixStream.println(" - sun.security.jca.ProviderList:");
debug_printMethodInfo(rsaFixStream, ProviderList.class.getDeclaredMethods());
}
rsaFixStream.println("• System info");
rsaFixStream.println(" - Android version " + Build.VERSION.RELEASE + " (API " + Integer.toString(Build.VERSION.SDK_INT) + ")");
rsaFixStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable(){
final String errMsg = "Unable to fix RSAPadding. Premium features is limited!" +
(Build.VERSION.SDK_INT == 23 ?
"Android 6 currently don't have solution" :
"Send the file at " + rsaFixFile.getAbsolutePath() + " to the developer");
if (act != null) {
act.runOnUiThread(new Runnable(){
@Override
public void run() {
Toast.makeText(MainActivity.this, "Unable to fix RSAPadding. Premium features is limited! Send the file at " + rsaFixFile.getAbsolutePath() + " to the developer", Toast.LENGTH_LONG).show();
Toast.makeText(act, errMsg, Toast.LENGTH_LONG).show();
}
});
} else {
System.err.println("RSAPadding error: " + errMsg);
}
}
/*
@@ -1077,13 +1243,19 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
*/
}
private List<Provider.Service> getCipherServices(String algorithm) throws InvocationTargetException, SecurityException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, ClassNotFoundException {
return (List<Provider.Service>) Class.forName("sun.security.jca.GetInstance")
.getDeclaredMethod("getServices", String.class, String.class)
.invoke(null, new Object[]{"Cipher", algorithm});
private static void debug_printServiceInfo(PrintStream stream, String key) {
String[] keyArr = key.split(".");
for (Provider p : getCipherServicesMap(keyArr[0], keyArr[1]).keySet()) {
stream.println("- " + p.getName() + ": " + p.getInfo());
for (Provider.Service s : p.getServices()) {
if (s.getAlgorithm().contains(key)) {
stream.println(s.toString());
}
}
}
}
private void debug_printMethodInfo(PrintStream stream, Method[] methods) {
private static void debug_printMethodInfo(PrintStream stream, Method[] methods) {
StringBuilder methodInfo = new StringBuilder();
for (Method method : methods) {
methodInfo.setLength(0);
@@ -1126,6 +1298,45 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
stream.println(methodInfo);
}
}
// From org.apache.harmony.security.fortress.Services:getServices(String type, String algorithm)
private static synchronized Collection<Provider.Service> getCipherServices(String type, String algorithm) {
if (Build.VERSION.SDK_INT < 23) {
// 5.1 (Lollipop) and below
return Services.getServices(type + "." + algorithm);
} else if (Build.VERSION.SDK_INT == 23) {
// 6.0 (Marshmallow) only
return Services.getServices(type, algorithm);
} else {
return getCipherServicesMap(type, algorithm).values();
}
}
private static synchronized Map<Provider, Provider.Service> getCipherServicesMap(String type, String algorithm) {
// 7.0 (Nougat) and above
ProviderList providerList = Providers.getProviderList();
Map<Provider, Provider.Service> services = null;
// Android 10
if (Build.VERSION.SDK_INT >= 29) {
services = new ArrayMap<>();
Provider.Service service = providerList.getService(type, algorithm);
services.put(service.getProvider(), service);
} else {
List<Provider> providers = providerList.providers();
for (Provider p : providers) {
Provider.Service s = p.getService(type, algorithm);
if (s != null) {
if (services == null) {
services = new ArrayMap<>(providers.size());
}
services.put(p, s);
}
}
}
return services;
}
public void printStream(InputStream stream) {
try {
@@ -1182,12 +1393,24 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
WindowAnimation.fadeOut(contentCanvas, 500);
}
*/
private void appendToLog(String text) {
appendToLog(text, true);
}
private void appendlnToLog(String text) {
appendToLog(text + "\n");
appendlnToLog(text, true);
}
private void appendlnToLog(String text, boolean checkAllow) {
appendToLog(text + "\n", checkAllow);
}
private void appendToLog(final String text, boolean checkAllow) {
if (checkAllow && !isLogAllow) return;
/*
private void appendToLog(final String text) {
// if (!isLogAllow) return;
*/
// if (!isLogAllow) r
textLog.post(new Runnable(){
@Override
public void run()

View File

@@ -38,19 +38,12 @@ public class Modifiable
return (Set<E>) modifyCollection(set);
}
// Get modifiable list from ServiceList
public static void resetServiceList(List<Provider.Service> list) throws Throwable {
Class<?> listClass = Class.forName("sun.security.jca.ProviderList$ServiceList");
Field servicesField = listClass.getDeclaredField("services");
Field firstServiceField = listClass.getDeclaredField("firstService");
servicesField.setAccessible(true);
firstServiceField.setAccessible(true);
List<Provider.Service> services = (List<Provider.Service>) servicesField.get(list);
firstServiceField.set(list, null);
if (services == null) {
System.err.println("ServiceList is null, how to erase?");
} else services.clear();
// Get alias list from Provider.Service
public static List<String> getServiceAliases(Provider.Service service) throws Throwable {
Method getAliasesMethod = service.getClass().getDeclaredMethod("getAliases");
getAliasesMethod.setAccessible(true);
return (List<String>) getAliasesMethod.invoke(service);
}
}

View File

@@ -8,13 +8,50 @@ import net.kdt.pojavlaunch.prefs.*;
import net.kdt.pojavlaunch.value.customcontrols.*;
import android.support.v7.preference.*;
import java.io.*;
import android.content.*;
import android.support.v4.app.*;
import android.util.*;
import net.kdt.pojavlaunch.exit.*;
import java.time.*;
import java.text.*;
import java.util.*;
public class PojavApplication extends Application
{
public static String CRASH_REPORT_TAG = "PojavCrashReport";
@Override
public void onCreate() {
super.onCreate();
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler(){
@Override
public void uncaughtException(Thread thread, Throwable th) {
boolean storagePermAllowed = Build.VERSION.SDK_INT < 23 || ActivityCompat.checkSelfPermission(PojavApplication.this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
File crashFile = new File(storagePermAllowed ? Tools.MAIN_PATH : Tools.datapath, "latestcrash.txt");
try {
// Write to file, since some devices may not able to show error
crashFile.createNewFile();
PrintStream crashStream = new PrintStream(crashFile);
crashStream.append("PojavLauncher crash report\n");
crashStream.append(" - Time: " + DateFormat.getDateTimeInstance().format(new Date()));
crashStream.append(" - Device: " + Build.PRODUCT + " " + Build.MODEL);
crashStream.append(" - Android version: " + Build.VERSION.RELEASE);
crashStream.append(" - Crash stack trace:");
crashStream.append(Log.getStackTraceString(th));
crashStream.close();
} catch (Throwable th2) {
Log.e(CRASH_REPORT_TAG, " - Exception attempt saving crash stack trace:", th2);
Log.e(CRASH_REPORT_TAG, " - The crash stack trace was:", th);
}
FatalErrorActivity.showError(PojavApplication.this, crashFile.getAbsolutePath(), storagePermAllowed, th);
// android.os.Process.killProcess(android.os.Process.myPid());
MainActivity.fullyExit();
}
});
try {
super.onCreate();
Tools.APP_NAME = getResources().getString(R.string.app_short_name);
PackageInfo thisApp = getPackageManager().getPackageInfo(getPackageName(), 0);
@@ -37,11 +74,11 @@ public class PojavApplication extends Application
specialButtons[3].name = getString(R.string.control_secondary);
specialButtons[4].name = getString(R.string.control_mouse);
new File(Tools.CTRLMAP_PATH).mkdirs();
new CustomControls(this).save(Tools.CTRLDEF_FILE);
} catch (Exception e) {
e.printStackTrace();
FontChanger.initFonts(this);
} catch (Throwable th) {
Intent ferrorIntent = new Intent(this, FatalErrorActivity.class);
ferrorIntent.putExtra("throwable", th);
startActivity(ferrorIntent);
}
}
}

View File

@@ -22,26 +22,31 @@ import android.system.*;
import android.net.*;
import static android.view.ViewGroup.LayoutParams.*;
import net.kdt.pojavlaunch.update.*;
import net.kdt.pojavlaunch.value.customcontrols.*;
import android.support.v7.app.AppCompatActivity;
public class PojavLoginActivity extends MineActivity
public class PojavLoginActivity extends AppCompatActivity
// MineActivity
{
private EditText edit2, edit3;
private int REQUEST_STORAGE_REQUEST_CODE = 1;
private ProgressBar prb;
private Switch sRemember, sOffline;
private CheckBox sRemember, sOffline;
private LinearLayout loginLayout;
private ImageView imageLogo;
private boolean isPromptingGrant = false;
// private boolean isPermGranted = false;
private SharedPreferences firstLaunchPrefs;
// private String PREF_IS_DONOTSHOWAGAIN_WARN = "isWarnDoNotShowAgain";
private String PREF_IS_INSTALLED_LIBRARIES = "isLibrariesExtracted";
private String PREF_IS_INSTALLED_LIBRARIES = "isLibrariesExtracted2";
private boolean isInitCalled = false;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState, false);
super.onCreate(savedInstanceState); // false);
if (!isInitCalled) {
init();
isInitCalled = true;
@@ -130,7 +135,7 @@ public class PojavLoginActivity extends MineActivity
LinearLayout startScr = new LinearLayout(PojavLoginActivity.this);
LayoutInflater.from(PojavLoginActivity.this).inflate(R.layout.start_screen, startScr);
replaceFonts(startScr);
FontChanger.changeFonts(startScr);
progress = (ProgressBar) startScr.findViewById(R.id.startscreenProgress);
//startScr.addView(progress);
@@ -229,14 +234,23 @@ public class PojavLoginActivity extends MineActivity
}
private void uiInit() {
setContentView(R.layout.launcher_login);
setContentView(R.layout.launcher_login_v2);
edit2 = (EditText) findViewById(R.id.launcherAccEmail);
edit3 = (EditText) findViewById(R.id.launcherAccPassword);
loginLayout = findViewById(R.id.login_layout_linear);
imageLogo = findViewById(R.id.login_image_logo);
loginLayout.postDelayed(new Runnable(){
@Override
public void run(){
imageLogo.setTranslationY(loginLayout.getY() - (imageLogo.getHeight() / 2f));
}
}, 100);
edit2 = (EditText) findViewById(R.id.login_edit_email);
edit3 = (EditText) findViewById(R.id.login_edit_password);
if(prb == null) prb = (ProgressBar) findViewById(R.id.launcherAccProgress);
sRemember = (Switch) findViewById(R.id.launcherAccRememberSwitch);
sOffline = (Switch) findViewById(R.id.launcherAccOffSwitch);
sRemember = findViewById(R.id.login_switch_remember);
sOffline = findViewById(R.id.login_switch_offline);
sOffline.setOnCheckedChangeListener(new OnCheckedChangeListener(){
@Override
@@ -248,29 +262,14 @@ public class PojavLoginActivity extends MineActivity
});
}
private boolean isAndroid7()
{
return Build.VERSION.SDK_INT >= 24;
}
/*
long lastTime = System.currentTimeMillis();
long lastDel = 0;
private void deAnr(String msg) {
long currt = System.currentTimeMillis();
lastDel = currt - lastTime;
lastTime = currt;
System.out.println("Time:" + lastDel + "ms||" + (lastDel / 1000) + "s: " + msg);
}
*/
@Override
public void onResume() {
super.onResume();
if (loginLayout != null && imageLogo != null) {
imageLogo.setTranslationY(loginLayout.getY() - (imageLogo.getHeight() / 2f));
}
// Clear current profile
PojavProfile.setCurrentProfile(this, null);
}
@@ -304,10 +303,13 @@ public class PojavLoginActivity extends MineActivity
try {
file3.createNewFile();
} catch (IOException e){}
try {
mkdirs(Tools.MAIN_PATH);
mkdirs(Tools.CTRLMAP_PATH);
new CustomControls(this).save(Tools.CTRLDEF_FILE);
Tools.copyAssetFile(this, "options.txt", Tools.MAIN_PATH, false);
// Extract launcher_profiles.json
@@ -334,10 +336,10 @@ public class PojavLoginActivity extends MineActivity
private boolean mkdirs(String path)
{
File mFileeee = new File(path);
if(mFileeee.getParentFile().exists())
return mFileeee.mkdir();
else return mFileeee.mkdirs();
File file = new File(path);
if(file.getParentFile().exists())
return file.mkdir();
else return file.mkdirs();
}
/*
@@ -362,7 +364,6 @@ public class PojavLoginActivity extends MineActivity
public void loginSavedAcc(View view)
{
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.login_select_account);
if (Tools.enableDevFeatures) {
/*
@@ -380,7 +381,7 @@ public class PojavLoginActivity extends MineActivity
}
builder.setPositiveButton(android.R.string.cancel, null);
builder.setTitle(this.getString(R.string.login_select_account));
final AlertDialog dialog = builder.create();
/*
@@ -391,6 +392,8 @@ public class PojavLoginActivity extends MineActivity
lpHint.weight = 1;
lpFlv.weight = 1;
*/
dialog.setTitle(this.getString(R.string.login_select_account));
System.out.println("Setting title...");
LinearLayout dialay = new LinearLayout(this);
dialay.setOrientation(LinearLayout.VERTICAL);
TextView fhint = new TextView(this);
@@ -459,6 +462,7 @@ public class PojavLoginActivity extends MineActivity
dialay.addView(flv);
dialog.setView(dialay);
dialog.setTitle(this.getString(R.string.login_select_account));
dialog.show();
}
@@ -493,50 +497,8 @@ public class PojavLoginActivity extends MineActivity
end skip*/
if (sOffline.isChecked()) {
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.setTitle(R.string.warning_title);
alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface p1, int p2)
{
sRemember.setChecked(true);
mProfile = loginOffline();
playProfile();
}
});
alert.setNegativeButton(R.string.login_offline_alert_skip, new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface p1, int p2)
{
mProfile = loginOffline();
playProfile();
}
});
alert.setNeutralButton(android.R.string.cancel, new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface p1, int p2)
{
mProfile = null;
}
});
if (!sRemember.isChecked()) {
alert.setMessage(R.string.login_offline_warning_1);
warning = alert.show();
} else {
mProfile = loginOffline();
playProfile();
}
/*
while (warning != null && warning.isShowing()) {
}
*/
mProfile = loginOffline();
playProfile();
} else {
new LoginTask().setLoginListener(new LoginListener(){

View File

@@ -0,0 +1,146 @@
package net.kdt.pojavlaunch;
import android.util.*;
import java.io.*;
import java.lang.reflect.*;
import java.util.*;
/*
* All methods there are from
* https://android.googlesource.com/platform/frameworks/multidex/+/refs/heads/master/library/src/androidx/multidex/MultiDex.java
*/
public class SecondaryDexLoader
{
public static String TAG = "SecondaryDexLoader";
private static int ADDITIONAL_CLASSES = 0;
public static void install(ClassLoader loader, List<File> additionalClassPathEntries, File optimizedDirectory) throws Throwable {
ADDITIONAL_CLASSES = additionalClassPathEntries.size();
/* The patched class loader is expected to be a descendant of
* dalvik.system.BaseDexClassLoader. We modify its
* dalvik.system.DexPathList pathList field to append additional DEX
* file entries.
*/
Object dexPathList = getDexPathList(loader);
ArrayList<IOException> suppressedExceptions = new ArrayList<IOException>();
expandFieldArray(dexPathList, "dexElements", makeDexElements(dexPathList,
new ArrayList<File>(additionalClassPathEntries), optimizedDirectory,
suppressedExceptions));
if (suppressedExceptions.size() > 0) {
for (IOException e : suppressedExceptions) {
Log.w(TAG, "Exception in makeDexElement", e);
}
Field suppressedExceptionsField =
findField(loader, "dexElementsSuppressedExceptions");
IOException[] dexElementsSuppressedExceptions =
(IOException[]) suppressedExceptionsField.get(loader);
if (dexElementsSuppressedExceptions == null) {
dexElementsSuppressedExceptions =
suppressedExceptions.toArray(
new IOException[suppressedExceptions.size()]);
} else {
IOException[] combined =
new IOException[suppressedExceptions.size() +
dexElementsSuppressedExceptions.length];
suppressedExceptions.toArray(combined);
System.arraycopy(dexElementsSuppressedExceptions, 0, combined,
suppressedExceptions.size(), dexElementsSuppressedExceptions.length);
dexElementsSuppressedExceptions = combined;
}
suppressedExceptionsField.set(loader, dexElementsSuppressedExceptions);
}
}
private static /* DexPathList */ Object getDexPathList(ClassLoader loader) throws Throwable {
Field pathListField = findField(loader, "pathList");
return pathListField.get(loader);
}
/**
* A wrapper around
* {@code private static final dalvik.system.DexPathList#makeDexElements}.
*/
private static Object[] makeDexElements(Object dexPathList, ArrayList<File> files, File optimizedDirectory, ArrayList<IOException> suppressedExceptions) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
Method makeDexElements = findMethod(dexPathList, "makeDexElements", ArrayList.class, File.class, ArrayList.class);
return (Object[]) makeDexElements.invoke(dexPathList, files, optimizedDirectory, suppressedExceptions);
}
/**
* Locates a given field anywhere in the class inheritance hierarchy.
*
* @param instance an object to search the field into.
* @param name field name
* @return a field object
* @throws NoSuchFieldException if the field cannot be located
*/
private static Field findField(Object instance, String name) throws NoSuchFieldException {
for (Class<?> clazz = instance.getClass(); clazz != null; clazz = clazz.getSuperclass()) {
try {
Field field = clazz.getDeclaredField(name);
if (!field.isAccessible()) {
field.setAccessible(true);
}
return field;
} catch (NoSuchFieldException e) {
// ignore and search next
}
}
throw new NoSuchFieldException("Field " + name + " not found in " + instance.getClass());
}
/**
* Locates a given method anywhere in the class inheritance hierarchy.
*
* @param instance an object to search the method into.
* @param name method name
* @param parameterTypes method parameter types
* @return a method object
* @throws NoSuchMethodException if the method cannot be located
*/
private static Method findMethod(Object instance, String name, Class<?>... parameterTypes) throws NoSuchMethodException {
for (Class<?> clazz = instance.getClass(); clazz != null; clazz = clazz.getSuperclass()) {
try {
Method method = clazz.getDeclaredMethod(name, parameterTypes);
if (!method.isAccessible()) {
method.setAccessible(true);
}
return method;
} catch (NoSuchMethodException e) {
// ignore and search next
}
}
throw new NoSuchMethodException("Method " + name + " with parameters " +
Arrays.asList(parameterTypes) + " not found in " + instance.getClass());
}
/**
* Replace the value of a field containing a non null array, by a new array containing the
* elements of the original array plus the elements of extraElements.
* @param instance the instance whose field is to be modified.
* @param fieldName the field to modify.
* @param extraElements elements to append at the end of the array.
*/
private static Object[] originalDex;
private static void expandFieldArray(Object instance, String fieldName, Object[] extraElements) throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
Field jlrField = findField(instance, fieldName);
originalDex = (Object[]) jlrField.get(instance);
Object[] combined = (Object[]) Array.newInstance(
originalDex.getClass().getComponentType(), originalDex.length + extraElements.length);
System.arraycopy(originalDex, 0, combined, 0, originalDex.length);
System.arraycopy(extraElements, 0, combined, originalDex.length, extraElements.length);
jlrField.set(instance, combined);
}
public static void resetFieldArray(ClassLoader loader) throws Throwable {
if (originalDex == null) return;
Object instance = getDexPathList(loader);
Field jlrField = findField(instance, "dexElements");
jlrField.set(instance, originalDex);
originalDex = null;
}
}

View File

@@ -37,7 +37,7 @@ public final class Tools
public static int usingVerCode = 1;
public static String usingVerName = "2.4.2";
public static String mhomeUrl = "https://khanhduytran0.github.io/PojavLauncher"; // "http://kdtjavacraft.eu5.net";
public static String mhomeUrl = "https://pojavlauncherteam.github.io/PojavLauncher"; // "http://kdtjavacraft.eu5.net";
public static String datapath = "/data/data/net.kdt.pojavlaunch";
public static String worksDir = datapath + "/app_working_dir";
@@ -76,11 +76,23 @@ public final class Tools
}
private static boolean isClientFirst = false;
public static String generate(String version) throws IOException
public static String generateLaunchClassPath(String version) throws IOException
{
StringBuilder libStr = new StringBuilder(); //versnDir + "/" + version + "/" + version + ".jar:";
String[] classpath = generateLibClasspath(getVersionInfo(version).libraries);
JMinecraftVersionList.Version info = getVersionInfo(version);
String[] classpath = generateLibClasspath(info);
// Debug: LWJGL 3 override
File lwjgl3Folder = new File(Tools.MAIN_PATH, "lwjgl3");
if (info.arguments != null && lwjgl3Folder.exists()) {
for (File file: lwjgl3Folder.listFiles()) {
if (file.getName().endsWith(".jar")) {
libStr.append(file.getAbsolutePath() + ":");
}
}
}
if (isClientFirst) {
libStr.append(getPatchedFile(version));
}
@@ -158,10 +170,15 @@ public final class Tools
public static void showError(final Context ctx, final Throwable e, final boolean exitIfOk)
{
showError(ctx, e, exitIfOk, false);
showError(ctx, R.string.global_error, e, exitIfOk, false);
}
private static void showError(final Context ctx, final Throwable e, final boolean exitIfOk, final boolean showMore)
public static void showError(final Context ctx, final int titleId, final Throwable e, final boolean exitIfOk)
{
showError(ctx, titleId, e, exitIfOk, false);
}
private static void showError(final Context ctx, final int titleId, final Throwable e, final boolean exitIfOk, final boolean showMore)
{
Runnable runnable = new Runnable(){
@@ -170,7 +187,7 @@ public final class Tools
{
final String errMsg = showMore ? Log.getStackTraceString(e): e.getMessage();
new AlertDialog.Builder((Context) ctx)
.setTitle(R.string.global_error)
.setTitle(titleId)
.setMessage(errMsg)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener(){
@@ -191,7 +208,7 @@ public final class Tools
@Override
public void onClick(DialogInterface p1, int p2)
{
showError(ctx, e, exitIfOk, !showMore);
showError(ctx, titleId, e, exitIfOk, !showMore);
}
})
.setNeutralButton(android.R.string.copy, new DialogInterface.OnClickListener(){
@@ -296,10 +313,10 @@ public final class Tools
}
}
*/
public static String[] generateLibClasspath(DependentLibrary[] libs)
{
public static String[] generateLibClasspath(JMinecraftVersionList.Version info) {
List<String> libDir = new ArrayList<String>();
for (DependentLibrary libItem: libs) {
for (DependentLibrary libItem: info.libraries) {
String[] libInfos = libItem.name.split(":");
libDir.add(Tools.libraries + "/" + Tools.artifactToPath(libInfos[0], libInfos[1], libInfos[2]));
}

View File

@@ -20,7 +20,7 @@ public class ConsoleFragment extends Fragment
consoleView = (TextView) view.findViewById(R.id.lmaintabconsoleLogTextView);
consoleView.setTypeface(Typeface.MONOSPACE);
consoleView.setHint("No log");
consoleView.setHint(this.getText(R.string.main_nolog));
return view;
}

View File

@@ -40,7 +40,7 @@ public class CrashFragment extends Fragment
crashView = (TextView) getView().findViewById(R.id.lmaintabconsoleLogCrashTextView);
crashView.setTypeface(Typeface.MONOSPACE);
crashView.setHint("No crash detected.");
crashView.setHint(this.getText(R.string.main_nocrash));
//new File(crashPath).mkdirs();
}

View File

@@ -162,7 +162,7 @@ public class PojavPreferenceActivity extends MineActivity implements OnCheckedCh
try {
Field field = R.id.class.getDeclaredField(getId(bar.getId()).replace("seekbar", "progressseek"));
((TextView) findViewById(field.get(null))).setText(currProgress + "/" + bar.getMax());
((TextView) findViewById((Integer) field.get(null))).setText(currProgress + "/" + bar.getMax());
} catch (Throwable th) {
throw new RuntimeException(th);
}

View File

@@ -59,7 +59,7 @@ public class ControlView extends Button implements OnLongClickListener, OnTouchL
} else if (properties.specialButtonListener instanceof View.OnTouchListener) {
setOnTouchListener((View.OnTouchListener) properties.specialButtonListener);
} else {
throw new IllegalArgumentException("Field " + ControlButton.class.getName() + ".specialButtonListener must be View.OnClickListener or View.OnTouchListener");
throw new IllegalArgumentException("Field " + ControlButton.class.getName() + ".specialButtonListener must be View.OnClickListener or View.OnTouchListener, but is " + properties.specialButtonListener.getClass().getName());
}
setLayoutParams(new FrameLayout.LayoutParams(properties.width, properties.height));

View File

@@ -160,6 +160,11 @@ public class Services {
public static synchronized ArrayList<Provider.Service> getServices(String key) {
return services.get(key);
}
public static synchronized ArrayList<Provider.Service> getServices(String type, String algorithm) {
return null;
}
/**
* Returns the default SecureRandom service description.
*/

View File

@@ -1,286 +0,0 @@
/*
* Copyright (c) 2002-2008 LWJGL Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'LWJGL' nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.lwjgl;
import java.nio.*;
/**
* <p>A class to check buffer boundaries in general. If there is unsufficient space
* in the buffer when the call is made then a buffer overflow would otherwise
* occur and cause unexpected behaviour, a crash, or worse, a security risk.
*
* Internal class, don't use.
* </p>
* @author cix_foo <cix_foo@users.sourceforge.net>
* @author elias_naur <elias_naur@users.sourceforge.net>
* @version $Revision$
* $Id$
*/
public class BufferChecks {
/** Static methods only! */
private BufferChecks() {
}
/**
* Helper methods to ensure a function pointer is not-null (0)
*/
public static void checkFunctionAddress(long pointer) {
if (LWJGLUtil.CHECKS && pointer == 0) {
// throw new IllegalStateException("Function is not supported");
}
}
/**
* Helper methods to ensure a ByteBuffer is null-terminated
*/
public static void checkNullTerminated(ByteBuffer buf) {
if ( LWJGLUtil.CHECKS && buf.get(buf.limit() - 1) != 0) {
throw new IllegalArgumentException("Missing null termination");
}
}
public static void checkNullTerminated(ByteBuffer buf, int count) {
if ( LWJGLUtil.CHECKS ) {
int nullFound = 0;
for ( int i = buf.position(); i < buf.limit(); i++ ) {
if ( buf.get(i) == 0 )
nullFound++;
}
if ( nullFound < count )
throw new IllegalArgumentException("Missing null termination");
}
}
/** Helper method to ensure an IntBuffer is null-terminated */
public static void checkNullTerminated(IntBuffer buf) {
if ( LWJGLUtil.CHECKS && buf.get(buf.limit() - 1) != 0 ) {
throw new IllegalArgumentException("Missing null termination");
}
}
/** Helper method to ensure a LongBuffer is null-terminated */
public static void checkNullTerminated(LongBuffer buf) {
if ( LWJGLUtil.CHECKS && buf.get(buf.limit() - 1) != 0 ) {
throw new IllegalArgumentException("Missing null termination");
}
}
/** Helper method to ensure a PointerBuffer is null-terminated */
public static void checkNullTerminated(PointerBuffer buf) {
if ( LWJGLUtil.CHECKS && buf.get(buf.limit() - 1) != 0 ) {
throw new IllegalArgumentException("Missing null termination");
}
}
public static void checkNotNull(Object o) {
if ( LWJGLUtil.CHECKS && o == null)
throw new IllegalArgumentException("Null argument");
}
/**
* Helper methods to ensure a buffer is direct (and, implicitly, non-null).
*/
public static void checkDirect(ByteBuffer buf) {
if ( LWJGLUtil.CHECKS && !buf.isDirect()) {
throw new IllegalArgumentException("ByteBuffer is not direct");
}
}
public static void checkDirect(ShortBuffer buf) {
if ( LWJGLUtil.CHECKS && !buf.isDirect()) {
throw new IllegalArgumentException("ShortBuffer is not direct");
}
}
public static void checkDirect(IntBuffer buf) {
if ( LWJGLUtil.CHECKS && !buf.isDirect()) {
throw new IllegalArgumentException("IntBuffer is not direct");
}
}
public static void checkDirect(LongBuffer buf) {
if ( LWJGLUtil.CHECKS && !buf.isDirect()) {
throw new IllegalArgumentException("LongBuffer is not direct");
}
}
public static void checkDirect(FloatBuffer buf) {
if ( LWJGLUtil.CHECKS && !buf.isDirect()) {
throw new IllegalArgumentException("FloatBuffer is not direct");
}
}
public static void checkDirect(DoubleBuffer buf) {
if ( LWJGLUtil.CHECKS && !buf.isDirect()) {
throw new IllegalArgumentException("DoubleBuffer is not direct");
}
}
public static void checkDirect(PointerBuffer buf) {
// NO-OP, PointerBuffer is always direct.
}
public static void checkArray(Object[] array) {
if ( LWJGLUtil.CHECKS && (array == null || array.length == 0) )
throw new IllegalArgumentException("Invalid array");
}
/**
* This is a separate call to help inline checkBufferSize.
*/
private static void throwBufferSizeException(Buffer buf, int size) {
throw new IllegalArgumentException("Number of remaining buffer elements is " + buf.remaining() + ", must be at least " + size + ". Because at most " + size + " elements can be returned, a buffer with at least " + size + " elements is required, regardless of actual returned element count");
}
private static void throwBufferSizeException(PointerBuffer buf, int size) {
throw new IllegalArgumentException("Number of remaining pointer buffer elements is " + buf.remaining() + ", must be at least " + size);
}
private static void throwArraySizeException(Object[] array, int size) {
throw new IllegalArgumentException("Number of array elements is " + array.length + ", must be at least " + size);
}
private static void throwArraySizeException(long[] array, int size) {
throw new IllegalArgumentException("Number of array elements is " + array.length + ", must be at least " + size);
}
/**
* Helper method to ensure a buffer is big enough to receive data from a
* glGet* operation.
*
* @param buf
* The buffer to check
* @param size
* The minimum buffer size
* @throws IllegalArgumentException
*/
public static void checkBufferSize(Buffer buf, int size) {
if ( LWJGLUtil.CHECKS && buf.remaining() < size) {
throwBufferSizeException(buf, size);
}
}
/**
* Detects the buffer type and performs the corresponding check
* and also returns the buffer position in bytes.
*
* @param buffer the buffer to check
* @param size the size to check
*
* @return the buffer position in bytes
*/
public static int checkBuffer(final Buffer buffer, final int size) {
final int posShift;
if ( buffer instanceof ByteBuffer ) {
BufferChecks.checkBuffer((ByteBuffer)buffer, size);
posShift = 0;
} else if ( buffer instanceof ShortBuffer ) {
BufferChecks.checkBuffer((ShortBuffer)buffer, size);
posShift = 1;
} else if ( buffer instanceof IntBuffer ) {
BufferChecks.checkBuffer((IntBuffer)buffer, size);
posShift = 2;
} else if ( buffer instanceof LongBuffer ) {
BufferChecks.checkBuffer((LongBuffer)buffer, size);
posShift = 4;
} else if ( buffer instanceof FloatBuffer ) {
BufferChecks.checkBuffer((FloatBuffer)buffer, size);
posShift = 2;
} else if ( buffer instanceof DoubleBuffer ) {
BufferChecks.checkBuffer((DoubleBuffer)buffer, size);
posShift = 4;
} else
throw new IllegalArgumentException("Unsupported Buffer type specified: " + buffer.getClass());
return buffer.position() << posShift;
}
public static void checkBuffer(ByteBuffer buf, int size) {
if ( LWJGLUtil.CHECKS ) {
checkBufferSize(buf, size);
checkDirect(buf);
}
}
public static void checkBuffer(ShortBuffer buf, int size) {
if ( LWJGLUtil.CHECKS ) {
checkBufferSize(buf, size);
checkDirect(buf);
}
}
public static void checkBuffer(IntBuffer buf, int size) {
if ( LWJGLUtil.CHECKS ) {
checkBufferSize(buf, size);
checkDirect(buf);
}
}
public static void checkBuffer(LongBuffer buf, int size) {
if ( LWJGLUtil.CHECKS ) {
checkBufferSize(buf, size);
checkDirect(buf);
}
}
public static void checkBuffer(FloatBuffer buf, int size) {
if ( LWJGLUtil.CHECKS ) {
checkBufferSize(buf, size);
checkDirect(buf);
}
}
public static void checkBuffer(DoubleBuffer buf, int size) {
if ( LWJGLUtil.CHECKS ) {
checkBufferSize(buf, size);
checkDirect(buf);
}
}
public static void checkBuffer(PointerBuffer buf, int size) {
if ( LWJGLUtil.CHECKS && buf.remaining() < size ) {
throwBufferSizeException(buf, size);
}
}
public static void checkArray(Object[] array, int size) {
if ( LWJGLUtil.CHECKS && array.length < size )
throwArraySizeException(array, size);
}
public static void checkArray(long[] array, int size) {
if ( LWJGLUtil.CHECKS && array.length < size )
throwArraySizeException(array, size);
}
}

View File

@@ -1,63 +0,0 @@
/*
* Copyright (c) 2002-2008 LWJGL Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'LWJGL' nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.lwjgl;
/**
*
* @author elias_naur <elias_naur@users.sourceforge.net>
* @version $Revision$
* $Id$
*/
abstract class DefaultSysImplementation implements SysImplementation {
public /* native */ int getJNIVersion() {
// Bypass JNI Version check.
return getRequiredJNIVersion();
}
public /* native */ int getPointerSize() {
return 1;
}
public native void setDebug(boolean debug);
public long getTimerResolution() {
return 1000;
}
public boolean has64Bit() {
return System.getProperty("os.arch").contains("64");
}
public abstract long getTime();
public abstract void alert(String title, String message);
public abstract String getClipboard();
}

View File

@@ -1,621 +0,0 @@
/*
* Copyright (c) 2002-2008 LWJGL Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'LWJGL' nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.lwjgl;
import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.nio.ByteBuffer;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.*;
/**
* <p>
* Internal library methods
* </p>
*
* @author Brian Matzon <brian@matzon.dk>
* @version $Revision$
* $Id$
*/
public class LWJGLUtil {
public static final int PLATFORM_LINUX = 1;
public static final int PLATFORM_MACOSX = 2;
public static final int PLATFORM_WINDOWS = 3;
public static final int PLATFORM_ANDROID = 1337;
public static final String PLATFORM_LINUX_NAME = "linux";
public static final String PLATFORM_MACOSX_NAME = "macosx";
public static final String PLATFORM_WINDOWS_NAME = "windows";
public static final String PLATFORM_ANDROID_NAME = "android";
private static final String LWJGL_ICON_DATA_16x16 =
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
"\377\377\377\377\377\377\377\377\376\377\377\377\302\327\350\377" +
"\164\244\313\377\120\213\275\377\124\216\277\377\206\257\322\377" +
"\347\357\366\377\377\377\377\377\377\377\377\377\377\377\377\377" +
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
"\377\377\377\377\365\365\365\377\215\217\221\377\166\202\215\377" +
"\175\215\233\377\204\231\252\377\224\267\325\377\072\175\265\377" +
"\110\206\272\377\332\347\361\377\377\377\377\377\377\377\377\377" +
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
"\364\370\373\377\234\236\240\377\000\000\000\377\000\000\000\377" +
"\000\000\000\377\000\000\000\377\344\344\344\377\204\255\320\377" +
"\072\175\265\377\133\222\301\377\374\375\376\377\377\377\377\377" +
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
"\221\266\325\377\137\137\137\377\000\000\000\377\000\000\000\377" +
"\000\000\000\377\042\042\042\377\377\377\377\377\350\360\366\377" +
"\071\174\265\377\072\175\265\377\304\330\351\377\377\377\377\377" +
"\377\377\377\377\377\377\377\377\377\377\377\377\306\331\351\377" +
"\201\253\316\377\035\035\035\377\000\000\000\377\000\000\000\377" +
"\000\000\000\377\146\146\146\377\377\377\377\377\320\340\355\377" +
"\072\175\265\377\072\175\265\377\215\264\324\377\377\377\377\377" +
"\362\362\362\377\245\245\245\377\337\337\337\377\242\301\334\377" +
"\260\305\326\377\012\012\012\377\000\000\000\377\000\000\000\377" +
"\000\000\000\377\250\250\250\377\377\377\377\377\227\272\330\377" +
"\072\175\265\377\072\175\265\377\161\241\312\377\377\377\377\377" +
"\241\241\241\377\000\000\000\377\001\001\001\377\043\043\043\377" +
"\314\314\314\377\320\320\320\377\245\245\245\377\204\204\204\377" +
"\134\134\134\377\357\357\357\377\377\377\377\377\140\226\303\377" +
"\072\175\265\377\072\175\265\377\155\236\310\377\377\377\377\377" +
"\136\136\136\377\000\000\000\377\000\000\000\377\000\000\000\377" +
"\317\317\317\377\037\037\037\377\003\003\003\377\053\053\053\377" +
"\154\154\154\377\306\306\306\377\372\374\375\377\236\277\332\377" +
"\167\245\314\377\114\211\274\377\174\250\316\377\377\377\377\377" +
"\033\033\033\377\000\000\000\377\000\000\000\377\027\027\027\377" +
"\326\326\326\377\001\001\001\377\000\000\000\377\000\000\000\377" +
"\000\000\000\377\122\122\122\377\345\345\345\377\075\075\075\377" +
"\150\150\150\377\246\246\247\377\332\336\341\377\377\377\377\377" +
"\164\164\164\377\016\016\016\377\000\000\000\377\131\131\131\377" +
"\225\225\225\377\000\000\000\377\000\000\000\377\000\000\000\377" +
"\000\000\000\377\221\221\221\377\233\233\233\377\000\000\000\377" +
"\000\000\000\377\000\000\000\377\002\002\002\377\103\103\103\377" +
"\377\377\377\377\356\356\356\377\214\214\214\377\277\277\277\377" +
"\126\126\126\377\000\000\000\377\000\000\000\377\000\000\000\377" +
"\000\000\000\377\323\323\323\377\130\130\130\377\000\000\000\377" +
"\000\000\000\377\000\000\000\377\000\000\000\377\063\063\063\377" +
"\377\377\377\377\377\377\377\377\374\375\376\377\377\377\377\377" +
"\300\300\300\377\100\100\100\377\002\002\002\377\000\000\000\377" +
"\033\033\033\377\373\373\373\377\027\027\027\377\000\000\000\377" +
"\000\000\000\377\000\000\000\377\000\000\000\377\170\170\170\377" +
"\377\377\377\377\377\377\377\377\322\341\356\377\176\251\316\377" +
"\340\352\363\377\377\377\377\377\324\324\324\377\155\155\155\377" +
"\204\204\204\377\323\323\323\377\000\000\000\377\000\000\000\377" +
"\000\000\000\377\000\000\000\377\000\000\000\377\275\275\275\377" +
"\377\377\377\377\377\377\377\377\376\376\376\377\146\232\305\377" +
"\075\177\266\377\202\254\320\377\344\355\365\377\377\377\377\377" +
"\377\377\377\377\345\345\345\377\055\055\055\377\000\000\000\377" +
"\000\000\000\377\000\000\000\377\014\014\014\377\366\366\366\377" +
"\377\377\377\377\377\377\377\377\377\377\377\377\342\354\364\377" +
"\115\211\274\377\072\175\265\377\076\200\266\377\207\260\322\377" +
"\347\357\366\377\377\377\377\377\376\376\376\377\274\274\274\377" +
"\117\117\117\377\003\003\003\377\112\112\112\377\377\377\377\377" +
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
"\353\362\370\377\214\263\324\377\126\220\300\377\120\214\275\377" +
"\167\245\314\377\355\363\370\377\377\377\377\377\377\377\377\377" +
"\377\377\377\377\337\337\337\377\346\346\346\377\377\377\377\377";
private static final String LWJGL_ICON_DATA_32x32 =
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\372\374\375\377" +
"\313\335\354\377\223\267\326\377\157\240\311\377\134\223\302\377\140\226\303\377\172\247\315\377\254\310\340\377\355\363\370\377" +
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\374\375\376\377\265\316\343\377\132\222\301\377" +
"\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\105\205\271\377" +
"\241\301\334\377\374\375\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\374\374\374\377\342\352\361\377\270\317\343\377\256\311\340\377" +
"\243\302\334\377\230\272\330\377\214\263\323\377\201\254\317\377\156\237\310\377\075\177\266\377\072\175\265\377\072\175\265\377" +
"\072\175\265\377\162\242\312\377\365\370\373\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
"\377\377\377\377\377\377\377\377\377\377\377\377\330\330\330\377\061\061\061\377\044\044\044\377\061\061\061\377\100\100\100\377" +
"\122\122\122\377\145\145\145\377\164\164\164\377\217\217\217\377\367\370\370\377\254\310\337\377\073\175\265\377\072\175\265\377" +
"\072\175\265\377\072\175\265\377\171\247\315\377\374\375\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
"\377\377\377\377\377\377\377\377\376\376\376\377\150\150\150\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
"\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\266\266\266\377\376\376\376\377\206\256\321\377\072\175\265\377" +
"\072\175\265\377\072\175\265\377\072\175\265\377\256\312\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
"\377\377\377\377\323\342\356\377\341\352\362\377\050\050\050\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
"\000\000\000\377\000\000\000\377\000\000\000\377\002\002\002\377\336\336\336\377\377\377\377\377\365\370\373\377\133\222\301\377" +
"\072\175\265\377\072\175\265\377\072\175\265\377\110\206\272\377\364\370\373\377\377\377\377\377\377\377\377\377\377\377\377\377" +
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
"\354\363\370\377\144\231\305\377\327\331\333\377\005\005\005\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
"\000\000\000\377\000\000\000\377\000\000\000\377\044\044\044\377\376\376\376\377\377\377\377\377\377\377\377\377\300\325\347\377" +
"\071\174\265\377\072\175\265\377\072\175\265\377\072\175\265\377\253\310\340\377\377\377\377\377\377\377\377\377\377\377\377\377" +
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\377\377\377" +
"\170\246\314\377\173\247\315\377\236\236\236\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
"\000\000\000\377\000\000\000\377\000\000\000\377\145\145\145\377\377\377\377\377\377\377\377\377\377\377\377\377\342\354\364\377" +
"\067\173\264\377\072\175\265\377\072\175\265\377\072\175\265\377\146\232\305\377\377\377\377\377\377\377\377\377\377\377\377\377" +
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\303\327\350\377" +
"\071\175\265\377\262\314\341\377\130\130\130\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
"\000\000\000\377\000\000\000\377\000\000\000\377\251\251\251\377\377\377\377\377\377\377\377\377\377\377\377\377\274\322\345\377" +
"\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\100\201\267\377\356\364\371\377\377\377\377\377\377\377\377\377" +
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\372\374\375\377\132\222\301\377" +
"\075\177\266\377\335\345\355\377\034\034\034\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
"\000\000\000\377\000\000\000\377\007\007\007\377\347\347\347\377\377\377\377\377\377\377\377\377\377\377\377\377\205\256\321\377" +
"\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\071\175\265\377\314\336\354\377\377\377\377\377\377\377\377\377" +
"\377\377\377\377\377\377\377\377\376\376\376\377\377\377\377\377\377\377\377\377\377\377\377\377\272\322\345\377\072\175\265\377" +
"\127\220\277\377\320\321\321\377\003\003\003\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
"\000\000\000\377\000\000\000\377\063\063\063\377\375\375\375\377\377\377\377\377\377\377\377\377\373\374\375\377\120\213\275\377" +
"\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\071\175\265\377\261\314\342\377\377\377\377\377\377\377\377\377" +
"\377\377\377\377\312\312\312\377\067\067\067\377\141\141\141\377\242\242\242\377\335\335\335\377\344\354\363\377\261\313\341\377" +
"\264\315\342\377\346\346\346\377\043\043\043\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
"\000\000\000\377\000\000\000\377\162\162\162\377\377\377\377\377\377\377\377\377\377\377\377\377\330\345\360\377\072\175\265\377" +
"\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\240\300\333\377\377\377\377\377\377\377\377\377" +
"\377\377\377\377\146\146\146\377\000\000\000\377\000\000\000\377\000\000\000\377\006\006\006\377\047\047\047\377\146\146\146\377" +
"\324\324\324\377\377\377\377\377\366\366\366\377\320\320\320\377\227\227\227\377\136\136\136\377\047\047\047\377\004\004\004\377" +
"\000\000\000\377\003\003\003\377\300\300\300\377\377\377\377\377\377\377\377\377\377\377\377\377\242\301\333\377\072\175\265\377" +
"\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\236\277\332\377\377\377\377\377\377\377\377\377" +
"\373\373\373\377\045\045\045\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
"\134\134\134\377\377\377\377\377\352\352\352\377\217\217\217\377\265\265\265\377\351\351\351\377\375\375\375\377\347\347\347\377" +
"\262\262\262\377\275\275\275\377\376\376\376\377\377\377\377\377\377\377\377\377\377\377\377\377\153\235\307\377\072\175\265\377" +
"\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\241\301\334\377\377\377\377\377\377\377\377\377" +
"\333\333\333\377\003\003\003\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
"\203\203\203\377\377\377\377\377\137\137\137\377\000\000\000\377\000\000\000\377\013\013\013\377\067\067\067\377\166\166\166\377" +
"\267\267\267\377\360\360\360\377\377\377\377\377\377\377\377\377\377\377\377\377\360\365\371\377\113\210\273\377\075\177\266\377" +
"\071\174\265\377\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\262\314\342\377\377\377\377\377\377\377\377\377" +
"\232\232\232\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
"\305\305\305\377\367\367\367\377\035\035\035\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
"\000\000\000\377\007\007\007\377\074\074\074\377\337\337\337\377\377\377\377\377\373\374\375\377\374\375\376\377\363\367\372\377" +
"\314\335\353\377\236\276\332\377\162\241\311\377\114\211\273\377\072\175\265\377\311\334\353\377\377\377\377\377\377\377\377\377" +
"\126\126\126\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\017\017\017\377" +
"\371\371\371\377\321\321\321\377\003\003\003\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
"\000\000\000\377\000\000\000\377\000\000\000\377\216\216\216\377\377\377\377\377\371\371\371\377\204\204\204\377\160\160\160\377" +
"\260\260\260\377\352\352\352\377\377\377\377\377\371\373\374\377\334\350\362\377\366\371\374\377\377\377\377\377\377\377\377\377" +
"\025\025\025\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\116\116\116\377" +
"\377\377\377\377\221\221\221\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
"\000\000\000\377\000\000\000\377\000\000\000\377\273\273\273\377\377\377\377\377\236\236\236\377\000\000\000\377\000\000\000\377" +
"\000\000\000\377\004\004\004\377\057\057\057\377\160\160\160\377\260\260\260\377\346\346\346\377\376\376\376\377\377\377\377\377" +
"\071\071\071\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\220\220\220\377" +
"\377\377\377\377\115\115\115\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
"\000\000\000\377\000\000\000\377\020\020\020\377\360\360\360\377\377\377\377\377\132\132\132\377\000\000\000\377\000\000\000\377" +
"\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\011\011\011\377\062\062\062\377\261\261\261\377" +
"\366\366\366\377\241\241\241\377\065\065\065\377\002\002\002\377\000\000\000\377\000\000\000\377\002\002\002\377\321\321\321\377" +
"\365\365\365\377\023\023\023\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
"\000\000\000\377\000\000\000\377\105\105\105\377\376\376\376\377\370\370\370\377\035\035\035\377\000\000\000\377\000\000\000\377" +
"\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\053\053\053\377" +
"\377\377\377\377\377\377\377\377\374\374\374\377\276\276\276\377\120\120\120\377\005\005\005\377\045\045\045\377\371\371\371\377" +
"\302\302\302\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
"\000\000\000\377\000\000\000\377\206\206\206\377\377\377\377\377\322\322\322\377\001\001\001\377\000\000\000\377\000\000\000\377" +
"\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\103\103\103\377" +
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\376\376\377\334\334\334\377\340\340\340\377\377\377\377\377" +
"\225\225\225\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
"\000\000\000\377\001\001\001\377\310\310\310\377\377\377\377\377\216\216\216\377\000\000\000\377\000\000\000\377\000\000\000\377" +
"\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\210\210\210\377" +
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
"\337\337\337\377\051\051\051\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
"\000\000\000\377\030\030\030\377\365\365\365\377\377\377\377\377\112\112\112\377\000\000\000\377\000\000\000\377\000\000\000\377" +
"\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\317\317\317\377" +
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\361\366\372\377\377\377\377\377\377\377\377\377" +
"\377\377\377\377\371\371\371\377\265\265\265\377\113\113\113\377\006\006\006\377\000\000\000\377\000\000\000\377\000\000\000\377" +
"\000\000\000\377\122\122\122\377\377\377\377\377\370\370\370\377\020\020\020\377\000\000\000\377\000\000\000\377\000\000\000\377" +
"\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\034\034\034\377\370\370\370\377" +
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\206\257\321\377\220\265\325\377\352\361\367\377" +
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\333\333\333\377\170\170\170\377\033\033\033\377\000\000\000\377" +
"\000\000\000\377\226\226\226\377\377\377\377\377\306\306\306\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
"\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\132\132\132\377\377\377\377\377" +
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\303\330\351\377\072\175\265\377\103\203\270\377" +
"\224\270\326\377\355\363\370\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\364\364\364\377\247\247\247\377" +
"\205\205\205\377\364\364\364\377\377\377\377\377\206\206\206\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
"\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\235\235\235\377\377\377\377\377" +
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\372\373\375\377\135\224\302\377\072\175\265\377" +
"\072\175\265\377\106\205\271\377\230\273\330\377\357\364\371\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
"\377\377\377\377\377\377\377\377\377\377\377\377\233\233\233\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" +
"\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\005\005\005\377\335\335\335\377\377\377\377\377" +
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\305\331\351\377\073\176\266\377" +
"\072\175\265\377\072\175\265\377\072\175\265\377\110\206\272\377\236\276\332\377\362\366\372\377\377\377\377\377\377\377\377\377" +
"\377\377\377\377\377\377\377\377\377\377\377\377\373\373\373\377\216\216\216\377\045\045\045\377\001\001\001\377\000\000\000\377" +
"\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\054\054\054\377\374\374\374\377\377\377\377\377" +
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\217\265\325\377" +
"\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\112\207\273\377\243\302\334\377\363\367\372\377" +
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\372\372\372\377\260\260\260\377\105\105\105\377" +
"\004\004\004\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\156\156\156\377\377\377\377\377\377\377\377\377" +
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\374\375\376\377" +
"\205\257\321\377\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\115\211\274\377" +
"\250\305\336\377\366\371\374\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\376\376\377" +
"\322\322\322\377\150\150\150\377\016\016\016\377\000\000\000\377\001\001\001\377\270\270\270\377\377\377\377\377\377\377\377\377" +
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
"\376\376\377\377\261\313\342\377\114\211\274\377\071\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377" +
"\072\175\265\377\115\211\274\377\277\324\347\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
"\377\377\377\377\377\377\377\377\354\354\354\377\223\223\223\377\233\233\233\377\375\375\375\377\377\377\377\377\377\377\377\377" +
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
"\377\377\377\377\377\377\377\377\363\367\372\377\265\316\343\377\201\254\320\377\145\231\305\377\141\227\304\377\154\236\310\377" +
"\217\265\325\377\305\331\351\377\367\372\374\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" +
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377";
/** LWJGL Logo - 16 by 16 pixels */
public static final ByteBuffer LWJGLIcon16x16 = loadIcon(LWJGL_ICON_DATA_16x16);
/** LWJGL Logo - 32 by 32 pixels */
public static final ByteBuffer LWJGLIcon32x32 = loadIcon(LWJGL_ICON_DATA_32x32);
/** Debug flag. */
public static final boolean DEBUG = true;/*getPrivilegedBoolean("org.lwjgl.util.Debug");*/
public static final boolean CHECKS = !getPrivilegedBoolean("org.lwjgl.util.NoChecks");
private static final int PLATFORM;
static {
/*final String osName = getPrivilegedProperty("os.name");
if ( osName.startsWith("Windows") )
PLATFORM = PLATFORM_WINDOWS;
else if ( osName.startsWith("Linux") || osName.startsWith("FreeBSD") || osName.startsWith("SunOS") || osName.startsWith("Unix") )
PLATFORM = PLATFORM_LINUX;
else if ( osName.startsWith("Mac OS X") || osName.startsWith("Darwin") )
PLATFORM = PLATFORM_MACOSX;
else
throw new LinkageError("Unknown platform: " + osName);*/
PLATFORM = PLATFORM_ANDROID;
}
private static ByteBuffer loadIcon(String data) {
int len = data.length();
ByteBuffer bb = BufferUtils.createByteBuffer(len);
for(int i=0 ; i<len ; i++) {
bb.put(i, (byte)data.charAt(i));
}
return bb.asReadOnlyBuffer();
}
/**
* @see #PLATFORM_WINDOWS
* @see #PLATFORM_LINUX
* @see #PLATFORM_MACOSX
* @return the current platform type
*/
public static int getPlatform() {
return PLATFORM;
}
/**
* @see #PLATFORM_WINDOWS_NAME
* @see #PLATFORM_LINUX_NAME
* @see #PLATFORM_MACOSX_NAME
* @return current platform name
*/
public static String getPlatformName() {
switch (LWJGLUtil.getPlatform()) {
case LWJGLUtil.PLATFORM_LINUX:
return PLATFORM_LINUX_NAME;
case LWJGLUtil.PLATFORM_MACOSX:
return PLATFORM_MACOSX_NAME;
case LWJGLUtil.PLATFORM_WINDOWS:
return PLATFORM_WINDOWS_NAME;
/*
case LWJGLUtil.PLATFORM_ANDROID:
return PLATFORM_ANDROID_NAME;
*/
default:
return PLATFORM_ANDROID_NAME;
}
}
/**
* Locates the paths required by a library.
*
* @param libname Local Library Name to search the classloader with ("openal").
* @param platform_lib_name The native library name ("libopenal.so")
* @param classloader The classloader to ask for library paths
* @return Paths to located libraries, if any
*/
public static String[] getLibraryPaths(String libname, String platform_lib_name, ClassLoader classloader) {
return getLibraryPaths(libname, new String[]{platform_lib_name}, classloader);
}
/**
* Locates the paths required by a library.
*
* @param libname Local Library Name to search the classloader with ("openal").
* @param platform_lib_names The list of possible library names ("libopenal.so")
* @param classloader The classloader to ask for library paths
* @return Paths to located libraries, if any
*/
public static String[] getLibraryPaths(String libname, String[] platform_lib_names, ClassLoader classloader) {
// need to pass path of possible locations of library to native side
List<String> possible_paths = new ArrayList<String>();
String classloader_path = getPathFromClassLoader(libname, classloader);
if (classloader_path != null) {
log("getPathFromClassLoader: Path found: " + classloader_path);
possible_paths.add(classloader_path);
}
for ( String platform_lib_name : platform_lib_names ) {
String lwjgl_classloader_path = getPathFromClassLoader("lwjgl", classloader);
if ( lwjgl_classloader_path != null ) {
log("getPathFromClassLoader: Path found: " + lwjgl_classloader_path);
possible_paths.add(lwjgl_classloader_path.substring(0, lwjgl_classloader_path.lastIndexOf(File.separator))
+ File.separator + platform_lib_name);
}
// add Installer path
String alternative_path = getPrivilegedProperty("org.lwjgl.librarypath");
if ( alternative_path != null ) {
possible_paths.add(alternative_path + File.separator + platform_lib_name);
}
// Add all possible paths from java.library.path
String java_library_path = getPrivilegedProperty("java.library.path");
StringTokenizer st = new StringTokenizer(java_library_path, File.pathSeparator);
while ( st.hasMoreTokens() ) {
String path = st.nextToken();
possible_paths.add(path + File.separator + platform_lib_name);
}
//add current path
String current_dir = getPrivilegedProperty("user.dir");
possible_paths.add(current_dir + File.separator + platform_lib_name);
//add pure library (no path, let OS search)
possible_paths.add(platform_lib_name);
}
//create needed string array
return possible_paths.toArray(new String[possible_paths.size()]);
}
static void execPrivileged(final String[] cmd_array) throws Exception {
try {
Process process = AccessController.doPrivileged(new PrivilegedExceptionAction<Process>() {
public Process run() throws Exception {
return Runtime.getRuntime().exec(cmd_array);
}
});
// Close unused streams to make sure the child process won't hang
process.getInputStream().close();
process.getOutputStream().close();
process.getErrorStream().close();
} catch (PrivilegedActionException e) {
throw (Exception)e.getCause();
}
}
private static String getPrivilegedProperty(final String property_name) {
return AccessController.doPrivileged(new PrivilegedAction<String>() {
public String run() {
return System.getProperty(property_name);
}
});
}
/**
* Tries to locate named library from the current ClassLoader
* This method exists because native libraries are loaded from native code, and as such
* is exempt from ClassLoader library loading rutines. It therefore always fails.
* We therefore invoke the protected method of the ClassLoader to see if it can
* locate it.
*
* @param libname Name of library to search for
* @param classloader Classloader to use
* @return Absolute path to library if found, otherwise null
*/
private static String getPathFromClassLoader(final String libname, final ClassLoader classloader) {
Class<?> c = null;
try {
log("getPathFromClassLoader: searching for: " + libname);
c = classloader.getClass();
while (c != null) {
final Class<?> clazz = c;
try {
return AccessController.doPrivileged(new PrivilegedExceptionAction<String>() {
public String run() throws Exception {
Method findLibrary = clazz.getDeclaredMethod("findLibrary", String.class);
findLibrary.setAccessible(true);
String path = (String)findLibrary.invoke(classloader, libname);
return path;
}
});
} catch (PrivilegedActionException e) {
log("Failed to locate findLibrary method: " + e.getCause());
c = c.getSuperclass();
}
}
} catch (Exception e) {
log("Failure locating " + e + " using classloader:" + c);
}
return null;
}
/**
* Gets a boolean property as a privileged action.
*/
public static boolean getPrivilegedBoolean(final String property_name) {
return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
public Boolean run() {
return Boolean.getBoolean(property_name);
}
});
}
/**
* Gets an integer property as a privileged action.
*
* @param property_name the integer property name
*
* @return the property value
*/
public static Integer getPrivilegedInteger(final String property_name) {
return AccessController.doPrivileged(new PrivilegedAction<Integer>() {
public Integer run() {
return Integer.getInteger(property_name);
}
});
}
/**
* Gets an integer property as a privileged action.
*
* @param property_name the integer property name
* @param default_val the default value to use if the property is not defined
*
* @return the property value
*/
public static Integer getPrivilegedInteger(final String property_name, final int default_val) {
return AccessController.doPrivileged(new PrivilegedAction<Integer>() {
public Integer run() {
return Integer.getInteger(property_name, default_val);
}
});
}
/**
* Prints the given message to System.err if DEBUG is true.
*
* @param msg Message to print
*/
public static void log(CharSequence msg) {
if (DEBUG) {
System.err.println("[LWJGL] " + msg);
}
}
/**
* Method to determine if the current system is running a version of
* Mac OS X better than the given version. This is only useful for Mac OS X
* specific code and will not work for any other platform.
*/
public static boolean isMacOSXEqualsOrBetterThan(int major_required, int minor_required) {
String os_version = getPrivilegedProperty("os.version");
StringTokenizer version_tokenizer = new StringTokenizer(os_version, ".");
int major;
int minor;
try {
String major_str = version_tokenizer.nextToken();
String minor_str = version_tokenizer.nextToken();
major = Integer.parseInt(major_str);
minor = Integer.parseInt(minor_str);
} catch (Exception e) {
LWJGLUtil.log("Exception occurred while trying to determine OS version: " + e);
// Best guess, no
return false;
}
return major > major_required || (major == major_required && minor >= minor_required);
}
/**
* Returns a map of public static final integer fields in the specified classes, to their String representations.
* An optional filter can be specified to only include specific fields. The target map may be null, in which
* case a new map is allocated and returned.
* <p>
* This method is useful when debugging to quickly identify values returned from the AL/GL/CL APIs.
*
* @param filter the filter to use (optional)
* @param target the target map (optional)
* @param tokenClasses an array of classes to get tokens from
*
* @return the token map
*/
public static Map<Integer, String> getClassTokens(final TokenFilter filter, final Map<Integer, String> target, final Class ... tokenClasses) {
return getClassTokens(filter, target, Arrays.asList(tokenClasses));
}
/**
* Returns a map of public static final integer fields in the specified classes, to their String representations.
* An optional filter can be specified to only include specific fields. The target map may be null, in which
* case a new map is allocated and returned.
* <p>
* This method is useful when debugging to quickly identify values returned from the AL/GL/CL APIs.
*
* @param filter the filter to use (optional)
* @param target the target map (optional)
* @param tokenClasses the classes to get tokens from
*
* @return the token map
*/
public static Map<Integer, String> getClassTokens(final TokenFilter filter, Map<Integer, String> target, final Iterable<Class> tokenClasses) {
if ( target == null )
target = new HashMap<Integer, String>();
final int TOKEN_MODIFIERS = Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL;
for ( final Class tokenClass : tokenClasses ) {
for ( final Field field : tokenClass.getDeclaredFields() ) {
// Get only <public static final int> fields.
if ( (field.getModifiers() & TOKEN_MODIFIERS) == TOKEN_MODIFIERS && field.getType() == int.class ) {
try {
final int value = field.getInt(null);
if ( filter != null && !filter.accept(field, value) )
continue;
if ( target.containsKey(value) ) // Print colliding tokens in their hex representation.
target.put(value, toHexString(value));
else
target.put(value, field.getName());
} catch (IllegalAccessException e) {
// Ignore
}
}
}
}
return target;
}
/**
* Returns a string representation of the integer argument as an
* unsigned integer in base&nbsp;16. The string will be uppercase
* and will have a leading '0x'.
*
* @param value the integer value
*
* @return the hex string representation
*/
public static String toHexString(final int value) {
return "0x" + Integer.toHexString(value).toUpperCase();
}
/** Simple interface for Field filtering. */
public interface TokenFilter {
/**
* Should return true if the specified Field passes the filter.
*
* @param field the Field to test
* @param value the integer value of the field
*
* @result true if the Field is accepted
*/
boolean accept(Field field, int value);
}
}

View File

@@ -1,420 +0,0 @@
/*
* Copyright (c) 2002-2008 LWJGL Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'LWJGL' nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.lwjgl.opengl;
import org.lwjgl.LWJGLException;
import org.lwjgl.LWJGLUtil;
import org.lwjgl.MemoryUtil;
import org.lwjgl.Sys;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
import java.util.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL30.*;
import static org.lwjgl.opengl.GL32.*;
/**
* <p/>
* Manages GL contexts. Before any rendering is done by a LWJGL system, a call should be made to GLContext.useContext() with a
* context. This will ensure that GLContext has an accurate reflection of the current context's capabilities and function
* pointers.
* <p/>
* This class is thread-safe in the sense that multiple threads can safely call all public methods. The class is also
* thread-aware in the sense that it tracks a per-thread current context (including capabilities and function pointers).
* That way, multiple threads can have multiple contexts current and render to them concurrently.
*
* @author elias_naur <elias_naur@users.sourceforge.net>
* @version $Revision$
* $Id$
*/
public final class GLContext {
/** Maps threads to their current context's ContextCapabilities, if any */
private static final ThreadLocal<ContextCapabilities> current_capabilities = new ThreadLocal<ContextCapabilities>();
/**
* The getCapabilities() method is a potential hot spot in any LWJGL application, since
* it is needed for context capability discovery (e.g. is OpenGL 2.0 supported?), and
* for the function pointers of gl functions. However, the 'current_capabilities' ThreadLocal
* is (relatively) expensive to look up, and since most OpenGL applications use are single threaded
* rendering, the following two is an optimization for this case.
* <p/>
* ThreadLocals can be thought of as a mapping between threads and values, so the idea
* is to use a lock-less cache of mappings between threads and the current ContextCapabilities. The cache
* could be any size, but in our case, we want a single sized cache for optimal performance
* in the single threaded case.
* <p/>
* 'fast_path_cache' is the most recent ContextCapabilities (potentially null) and its owner. By
* recent I mean the last thread setting the value in setCapabilities(). When getCapabilities()
* is called, a check to see if the current is the owner of the ContextCapabilities instance in
* fast_path_cache. If so, the instance is returned, if not, some thread has since taken ownership
* of the cache entry and the slower current_capabilities ThreadLocal is queried instead.
* <p/>
* No locks are needed in get/setCapabilities, because even though fast_path_cache can be accessed
* from multiple threads at once, we are guaranteed by the JVM spec that its value is always valid.
* Furthermore, if the ownership test in getCapabilities() succeeds, the cache entry can only contain
* the correct ContextCapabilites (that is, the one from getThreadLocalCapabilites()),
* since no other thread can set the owner to anyone else than itself.
*/
private static CapabilitiesCacheEntry fast_path_cache = new CapabilitiesCacheEntry();
/**
* Simple lock-free cache of CapabilitesEntryCache to avoid allocating more than one
* cache entry per thread
*/
private static final ThreadLocal<CapabilitiesCacheEntry> thread_cache_entries = new ThreadLocal<CapabilitiesCacheEntry>();
/**
* The weak mapping from context Object instances to ContextCapabilities. Used
* to avoid recreating a ContextCapabilities every time a context is made current.
*/
private static final Map<Object, ContextCapabilities> capability_cache = new WeakHashMap<Object, ContextCapabilities>();
/** Reference count of the native opengl implementation library */
private static int gl_ref_count;
private static boolean did_auto_load;
static {
Sys.initialize();
}
/**
* Get the current capabilities instance. It contains the flags used
* to test for support of a particular extension.
*
* @return The current capabilities instance.
*/
public static ContextCapabilities getCapabilities() {
ContextCapabilities caps = getCapabilitiesImpl();
if ( caps == null )
throw new RuntimeException("No OpenGL context found in the current thread.");
return caps;
}
private static ContextCapabilities getCapabilitiesImpl() {
CapabilitiesCacheEntry recent_cache_entry = fast_path_cache;
// Check owner of cache entry
if ( recent_cache_entry.owner == Thread.currentThread() ) {
/* The owner ship test succeeded, so the cache must contain the current ContextCapabilities instance
* assert recent_cache_entry.capabilities == getThreadLocalCapabilities();
*/
return recent_cache_entry.capabilities;
} else // Some other thread has written to the cache since, and we fall back to the slower path
return getThreadLocalCapabilities();
}
/**
* Returns the capabilities instance associated with the specified context object.
*
* @param context the context object
*
* @return the capabilities instance
*/
static ContextCapabilities getCapabilities(Object context) {
return capability_cache.get(context);
}
private static ContextCapabilities getThreadLocalCapabilities() {
return current_capabilities.get();
}
/**
* Set the current capabilities instance. It contains the flags used
* to test for support of a particular extension.
*
* @return The current capabilities instance.
*/
static void setCapabilities(ContextCapabilities capabilities) {
current_capabilities.set(capabilities);
CapabilitiesCacheEntry thread_cache_entry = thread_cache_entries.get();
if ( thread_cache_entry == null ) {
thread_cache_entry = new CapabilitiesCacheEntry();
thread_cache_entries.set(thread_cache_entry);
}
thread_cache_entry.owner = Thread.currentThread();
thread_cache_entry.capabilities = capabilities;
fast_path_cache = thread_cache_entry;
}
/**
* Helper method to get a pointer to a named function in the OpenGL library
* with a name dependent on the current platform
*/
static long getPlatformSpecificFunctionAddress(String function_prefix, String[] os_prefixes, String[] os_function_prefixes, String function) {
String os_name = AccessController.doPrivileged(new PrivilegedAction<String>() {
public String run() {
return System.getProperty("os.name");
}
});
for ( int i = 0; i < os_prefixes.length; i++ )
if ( os_name.startsWith(os_prefixes[i]) ) {
String platform_function_name = function.replaceFirst(function_prefix, os_function_prefixes[i]);
long address = getFunctionAddress(platform_function_name);
return address;
}
return 0;
}
/**
* Helper method to get a pointer to a named function with aliases in the OpenGL library.
*
* @param aliases the function name aliases.
*
* @return the function pointer address
*/
static long getFunctionAddress(String[] aliases) {
for ( String alias : aliases ) {
long address = getFunctionAddress(alias);
if ( address != 0 )
return address;
}
return 0;
}
/** Helper method to get a pointer to a named function in the OpenGL library. */
static long getFunctionAddress(String name) {
ByteBuffer buffer = MemoryUtil.encodeASCII(name);
return ngetFunctionAddress(MemoryUtil.getAddress(buffer));
}
private static native long ngetFunctionAddress(long name);
/**
* Determine which extensions are available and returns the context profile mask. Helper method to ContextCapabilities.
*
* @param supported_extensions the Set to fill with the available extension names
*
* @return the context profile mask, will be 0 for any version < 3.2
*/
static int getSupportedExtensions(final Set<String> supported_extensions) {
// Detect OpenGL version first
/* final */ String version = glGetString(GL_VERSION);
if (version == null) {
// throw new IllegalStateException("glGetString(GL_VERSION) returned null - possibly caused by missing current context.");
System.err.println("Unable to get real OpenGL version, inserting OpenGL 2.0.");
version = "2.0";
}
final StringTokenizer version_tokenizer = new StringTokenizer(version, ". ");
final String major_string = version_tokenizer.nextToken();
final String minor_string = version_tokenizer.nextToken();
int majorVersion = 0;
int minorVersion = 0;
try {
majorVersion = Integer.parseInt(major_string);
minorVersion = Integer.parseInt(minor_string);
} catch (NumberFormatException e) {
LWJGLUtil.log("The major and/or minor OpenGL version is malformed: " + e.getMessage());
}
final int[][] GL_VERSIONS = {
{ 1, 2, 3, 4, 5 }, // OpenGL 1
{ 0, 1 }, // OpenGL 2
{ 0, 1, 2, 3 }, // OpenGL 3
{ 0, 1, 2, 3, 4 }, // OpenGL 4
};
for ( int major = 1; major <= GL_VERSIONS.length; major++ ) {
int[] minors = GL_VERSIONS[major - 1];
for ( int minor : minors ) {
if ( major < majorVersion || (major == majorVersion && minor <= minorVersion) )
supported_extensions.add("OpenGL" + Integer.toString(major) + Integer.toString(minor));
}
}
int profileMask = 0;
if ( majorVersion < 3 ) {
// Parse EXTENSIONS string
final String extensions_string = glGetString(GL_EXTENSIONS);
if ( extensions_string == null )
throw new IllegalStateException("glGetString(GL_EXTENSIONS) returned null - is there a context current?");
final StringTokenizer tokenizer = new StringTokenizer(extensions_string);
while ( tokenizer.hasMoreTokens() )
supported_extensions.add(tokenizer.nextToken());
} else {
// Use forward compatible indexed EXTENSIONS
final int extensionCount = GL11.glGetInteger(GL_NUM_EXTENSIONS);
for ( int i = 0; i < extensionCount; i++ )
supported_extensions.add(glGetStringi(GL_EXTENSIONS, i));
// Get the context profile mask for versions >= 3.2
if ( 3 < majorVersion || 2 <= minorVersion ) {
Util.checkGLError(); // Make sure we have no errors up to this point
try {
profileMask = GL11.glGetInteger(GL_CONTEXT_PROFILE_MASK);
// Retrieving GL_CONTEXT_PROFILE_MASK may generate an INVALID_OPERATION error on certain implementations, ignore.
// Happens on pre10.1 ATI drivers, when ContextAttribs.withProfileCompatibility is not used
Util.checkGLError();
} catch (OpenGLException e) {
LWJGLUtil.log("Failed to retrieve CONTEXT_PROFILE_MASK");
}
}
}
return profileMask;
}
/**
* Helper method to ContextCapabilities. It will try to initialize the native stubs,
* and remove the given extension name from the extension set if the initialization fails.
*/
static void initNativeStubs(final Class<?> extension_class, Set supported_extensions, String ext_name) {
resetNativeStubs(extension_class);
if ( supported_extensions.contains(ext_name) ) {
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
public Object run() throws Exception {
Method init_stubs_method = extension_class.getDeclaredMethod("initNativeStubs");
init_stubs_method.invoke(null);
return null;
}
});
} catch (Exception e) {
LWJGLUtil.log("Failed to initialize extension " + extension_class + " - exception: " + e);
supported_extensions.remove(ext_name);
}
}
}
/**
* Makes a GL context the current LWJGL context by loading GL function pointers. The context must be current before a call to
* this method! Instead it simply ensures that the current context is reflected accurately by GLContext's extension caps and
* function pointers. Use useContext(null) when no context is active. <p>If the context is the same as last time, then this is
* a no-op. <p>If the context has not been encountered before it will be fully initialized from scratch. Otherwise a cached set
* of caps and function pointers will be used. <p>The reference to the context is held in a weak reference; therefore if no
* strong reference exists to the GL context it will automatically be forgotten by the VM at an indeterminate point in the
* future, freeing up a little RAM.
*
* @param context The context object, which uniquely identifies a GL context. If context is null, the native stubs are
* unloaded.
*
* @throws LWJGLException if context non-null, and the gl library can't be loaded or the basic GL11 functions can't be loaded
*/
public static synchronized void useContext(Object context) throws LWJGLException {
useContext(context, false);
}
/**
* Makes a GL context the current LWJGL context by loading GL function pointers. The context must be current before a call to
* this method! Instead it simply ensures that the current context is reflected accurately by GLContext's extension caps and
* function pointers. Use useContext(null) when no context is active. <p>If the context is the same as last time, then this is
* a no-op. <p>If the context has not been encountered before it will be fully initialized from scratch. Otherwise a cached set
* of caps and function pointers will be used. <p>The reference to the context is held in a weak reference; therefore if no
* strong reference exists to the GL context it will automatically be forgotten by the VM at an indeterminate point in the
* future, freeing up a little RAM.
* <p>If forwardCompatible is true, function pointers of deprecated GL11-GL21 functionality will not be loaded. Calling a deprecated
* function using the specified context will result in an <code>IllegalStateException</code>.
*
* @param context The context object, which uniquely identifies a GL context. If context is null, the native stubs are
* unloaded.
* @param forwardCompatible If the context is a forward compatible context (does not expose deprecated functionality, see XGL_ARB_create_context)
*
* @throws LWJGLException if context non-null, and the gl library can't be loaded or the basic GL11 functions can't be loaded
*/
public static synchronized void useContext(Object context, boolean forwardCompatible) throws LWJGLException {
if ( context == null ) {
ContextCapabilities.unloadAllStubs();
setCapabilities(null);
if ( did_auto_load )
unloadOpenGLLibrary();
return;
}
if ( gl_ref_count == 0 ) {
loadOpenGLLibrary();
did_auto_load = true;
}
try {
ContextCapabilities capabilities = capability_cache.get(context);
if ( capabilities == null ) {
/*
* The capabilities object registers itself as current. This behaviour is caused
* by a chicken-and-egg situation where the constructor needs to call GL functions
* as part of its capability discovery, but GL functions cannot be called before
* a capabilities object has been set.
*/
new ContextCapabilities(forwardCompatible);
capability_cache.put(context, getCapabilities());
} else
setCapabilities(capabilities);
} catch (LWJGLException e) {
if ( did_auto_load )
unloadOpenGLLibrary();
throw e;
}
}
/** If the OpenGL reference count is 0, the library is loaded. The reference count is then incremented. */
public static synchronized void loadOpenGLLibrary() throws LWJGLException {
if ( gl_ref_count == 0 )
nLoadOpenGLLibrary();
gl_ref_count++;
}
private static native void nLoadOpenGLLibrary() throws LWJGLException;
/** The OpenGL library reference count is decremented, and if it reaches 0, the library is unloaded. */
public static synchronized void unloadOpenGLLibrary() {
gl_ref_count--;
/*
* Unload the native OpenGL library unless we're on linux, since
* some drivers (NVIDIA proprietary) crash on exit when unloading the library.
*/
if ( gl_ref_count == 0 && LWJGLUtil.getPlatform() != LWJGLUtil.PLATFORM_LINUX )
nUnloadOpenGLLibrary();
}
private static native void nUnloadOpenGLLibrary();
/** Native method to clear native stub bindings */
static native void resetNativeStubs(Class clazz);
private static final class CapabilitiesCacheEntry {
Thread owner;
ContextCapabilities capabilities;
}
}

View File

@@ -1,38 +0,0 @@
/*
* Copyright LWJGL. All rights reserved.
* License terms: https://www.lwjgl.org/license
*/
package org.lwjgl.system;
/**
* Simple index checks.
*
* <p>On Java 9 these checks are replaced with the corresponding {@link java.util.Objects} methods, which perform better.</p>
*/
public final class CheckIntrinsics {
private CheckIntrinsics() {
}
public static int checkIndex(int index, int length) {
if (index < 0 || length <= index) {
throw new IndexOutOfBoundsException();
}
return index;
}
public static int checkFromToIndex(int fromIndex, int toIndex, int length) {
if (fromIndex < 0 || toIndex < fromIndex || length < toIndex) {
throw new IndexOutOfBoundsException();
}
return fromIndex;
}
public static int checkFromIndexSize(int fromIndex, int size, int length) {
if ((length | fromIndex | size) < 0 || length - fromIndex < size) {
throw new IndexOutOfBoundsException();
}
return fromIndex;
}
}

View File

@@ -1,83 +0,0 @@
#ifdef DOUBLE_FP
#ifdef AMD_FP
#pragma OPENCL EXTENSION cl_amd_fp64 : enable
#else
#ifndef CL_VERSION_1_2
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
#endif
#endif
#define varfloat double
#define _255 255.0
#else
#define varfloat float
#define _255 255.0f
#endif
#ifdef USE_TEXTURE
#define OUTPUT_TYPE __write_only image2d_t
#else
#define OUTPUT_TYPE global uint *
#endif
/**
* For a description of this algorithm please refer to
* http://en.wikipedia.org/wiki/Mandelbrot_set
* @author Michael Bien
*/
kernel void mandelbrot(
const int width, const int height,
const varfloat x0, const varfloat y0,
const varfloat rangeX, const varfloat rangeY,
OUTPUT_TYPE output, global uint *colorMap,
const int colorMapSize, const int maxIterations
) {
unsigned int ix = get_global_id(0);
unsigned int iy = get_global_id(1);
varfloat r = x0 + ix * rangeX / width;
varfloat i = y0 + iy * rangeY / height;
varfloat x = 0;
varfloat y = 0;
varfloat magnitudeSquared = 0;
int iteration = 0;
while ( magnitudeSquared < 4 && iteration < maxIterations ) {
varfloat x2 = x*x;
varfloat y2 = y*y;
y = 2 * x * y + i;
x = x2 - y2 + r;
magnitudeSquared = x2+y2;
iteration++;
}
if ( iteration == maxIterations ) {
#ifdef USE_TEXTURE
write_imagef(output, (int2)(ix, iy), (float4)0);
#else
output[iy * width + ix] = 0;
#endif
} else {
float alpha = (float)iteration / maxIterations;
int colorIndex = (int)(alpha * colorMapSize);
#ifdef USE_TEXTURE
// We could have changed colorMap to a texture + sampler, but the
// unpacking below has minimal overhead and it's kinda interesting.
// We could also use an R32UI texture and do the unpacking in GLSL,
// but then we'd require OpenGL 3.0 (GLSL 1.30).
uint c = colorMap[colorIndex];
float4 oc = (float4)(
(c & 0xFF) >> 0,
(c & 0xFF00) >> 8,
(c & 0xFF0000) >> 16,
255.0f
);
write_imagef(output, (int2)(ix, iy), oc / 255.0f);
#else
output[iy * width + ix] = colorMap[colorIndex];
#endif
// monochrom
//output[iy * width + ix] = 255*iteration/maxIterations;
}
}

View File

@@ -1,40 +0,0 @@
!!ARBfp1.0
OPTION ARB_precision_hint_fastest;
ATTRIB winPos = fragment.position;
ATTRIB iDots = fragment.texcoord[0];
PARAM ambience = state.lightmodel.ambient;
PARAM specularColor = state.light[0].specular;
PARAM UNIFORMS = program.local[0];
TEMP temp;
OUTPUT oColor = result.color;
# Offset window-space fragment position.
ADD temp.xyz, winPos, UNIFORMS.zwxx;
# Normalize position.
DP3 temp.w, temp, temp;
RSQ temp.w, temp.w;
MUL temp.xy, temp, temp.w;
# Multiply with current sin.
MUL temp.xy, temp, UNIFORMS.x;
# {-1..1} => {0..1}
MAD temp.xy, temp, 0.5, 0.5;
# Intensify colors.
MUL temp.xy, temp, 2.0;
MOV temp.z, 1.0;
# Accumulate color contributions.
MAD temp.xyz, iDots.x, temp, ambience;
# Calculate <specular dot product>^<specular exponent>
POW temp.w, iDots.y, UNIFORMS.y;
MAD oColor.xyz, temp.w, specularColor, temp;
MOV oColor.w, 1.0;
END

View File

@@ -1,37 +0,0 @@
!!ARBvp1.0
ATTRIB iPos = vertex.position;
ATTRIB iNormal = vertex.normal;
PARAM mvp[4] = { state.matrix.mvp };
PARAM mvIT[4] = { state.matrix.modelview.invtrans };
PARAM lightDir = state.light[0].position;
PARAM halfDir = state.light[0].half;
PARAM UNIFORMS = program.local[0];
TEMP normal, dots;
OUTPUT oPos = result.position;
OUTPUT oDots = result.texcoord[0];
# Transform the vertex to clip coordinates.
DP4 oPos.x, mvp[0], iPos;
DP4 oPos.y, mvp[1], iPos;
DP4 oPos.z, mvp[2], iPos;
DP4 oPos.w, mvp[3], iPos;
# Transform the normal to eye coordinates.
DP3 normal.x, mvIT[0], iNormal;
DP3 normal.y, mvIT[1], iNormal;
DP3 normal.z, mvIT[2], iNormal;
# Compute diffuse and specular dot products and clamp them.
DP3 dots.x, normal, lightDir;
MAX oDots.x, dots.x, 0.0;
DP3 dots.y, normal, halfDir;
MAX oDots.y, dots.y, 0.0;
END

View File

@@ -1,21 +0,0 @@
uniform vec4 UNIFORMS;
varying vec2 dots;
void main(void) {
// Offset window-space fragment position.
vec3 color2D = vec3(gl_FragCoord + UNIFORMS.zwxx);
// Normalize position.
// Multiply with current sin.
color2D.xy = normalize(color2D).xy * UNIFORMS.x;
// {-1..1} => {0..1} & Intensify colors.
color2D.xy = (vec2(color2D) * 0.5 + 0.5) * 2.0;
color2D.z = 1.0;
// Accumulate color contributions.
// Hardcoded ambience and specular color, due to buggy drivers.
color2D = dots.x * color2D + vec3(0.2, 0.2, 0.2);
gl_FragColor.rgb = pow(dots.y, UNIFORMS.y) * vec3(1.0, 1.0, 0.5) + color2D;
gl_FragColor.a = 1.0;
}

View File

@@ -1,13 +0,0 @@
uniform vec4 UNIFORMS;
varying vec2 dots;
void main(void) {
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
vec3 normal = gl_NormalMatrix * gl_Normal;
// Pass the dot products to the fragment shader.
dots.x = max(dot(normal, vec3(gl_LightSource[0].position)), 0.0);
dots.y = max(dot(normal, vec3(gl_LightSource[0].halfVector)), 0.0);
}

View File

@@ -1,28 +0,0 @@
#version 140
#extension GL_ARB_uniform_buffer_object : enable
layout(std140) uniform test {
vec2 uniformA;
vec3 uniformB;
};
void main(void) {
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
vec3 normal = gl_NormalMatrix * gl_Normal;
float diffuseDot = max(dot(normal, vec3(gl_LightSource[0].position)), 0.0);
float specularDot = max(dot(normal, vec3(gl_LightSource[0].halfVector)), 0.0);
specularDot = pow(specularDot, uniformA.y);
// Normalize position, to get a {-1..1} value for each vertex.
// Multiply with current sin.
vec3 color3D = normalize(vec3(gl_Vertex)) * uniformA.x;
// {-1..1} => {0..1} & Intensify colors.
color3D = (color3D * 0.5 + 0.5) * 2.0;
// Accumulate color contributions.
color3D = diffuseDot * (uniformB + color3D) + vec3(gl_LightModel.ambient);
gl_FrontColor.rgb = specularDot * vec3(gl_LightSource[0].specular) + color3D;
gl_FrontColor.a = 1.0;
}

View File

@@ -1,59 +0,0 @@
!!ARBvp1.0
ATTRIB iPos = vertex.position;
ATTRIB iNormal = vertex.normal;
PARAM mvp[4] = { state.matrix.mvp };
PARAM mvIT[4] = { state.matrix.modelview.invtrans };
PARAM ambience = state.lightmodel.ambient;
PARAM lightDir = state.light[0].position;
PARAM halfDir = state.light[0].half;
PARAM diffuseColor = state.light[0].diffuse;
PARAM specularColor = state.light[0].specular;
PARAM UNIFORMS = program.local[0];
TEMP temp, temp2, normal, dots;
OUTPUT oPos = result.position;
OUTPUT oColor = result.color;
# Transform the vertex to clip coordinates.
DP4 oPos.x, mvp[0], iPos;
DP4 oPos.y, mvp[1], iPos;
DP4 oPos.z, mvp[2], iPos;
DP4 oPos.w, mvp[3], iPos;
# Transform the normal to eye coordinates.
DP3 normal.x, mvIT[0], iNormal;
DP3 normal.y, mvIT[1], iNormal;
DP3 normal.z, mvIT[2], iNormal;
# Compute diffuse and specular dot products and use LIT to compute
# lighting coefficients.
DP3 dots.x, normal, lightDir;
DP3 dots.y, normal, halfDir;
MOV dots.w, UNIFORMS.y;
LIT dots, dots;
# Normalize position, to get a {-1..1} value for each vertex.
DP3 temp.w, iPos, iPos;
RSQ temp.w, temp.w;
MUL temp.xyz, iPos, temp.w;
# Multiply with current sin.
MUL temp.xyz, temp, UNIFORMS.x;
# {-1..1} => {0..1}
MAD temp.xyz, temp, 0.5, 0.5;
# Intensify colors.
MUL temp.xyz, temp, 2.0;
# Accumulate color contributions.
MAD temp.xyz, dots.y, temp, ambience;
MAD oColor.xyz, dots.z, specularColor, temp;
MOV oColor.w, 1.0;
END

View File

@@ -1,22 +0,0 @@
uniform vec2 UNIFORMS;
void main(void) {
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
vec3 normal = gl_NormalMatrix * gl_Normal;
float diffuseDot = max(dot(normal, vec3(gl_LightSource[0].position)), 0.0);
float specularDot = max(dot(normal, vec3(gl_LightSource[0].halfVector)), 0.0);
specularDot = pow(specularDot, UNIFORMS.y);
// Normalize position, to get a {-1..1} value for each vertex.
// Multiply with current sin.
vec3 color3D = normalize(vec3(gl_Vertex)) * UNIFORMS.x;
// {-1..1} => {0..1} & Intensify colors.
color3D = (color3D * 0.5 + 0.5) * 2.0;
// Accumulate color contributions.
color3D = diffuseDot * color3D + vec3(gl_LightModel.ambient);
gl_FrontColor.rgb = specularDot * vec3(gl_LightSource[0].specular) + color3D;
gl_FrontColor.a = 1.0;
}

View File

@@ -0,0 +1,17 @@
package sun.security.jca;
import java.security.*;
import java.util.*;
// Stub class to access to Android 7.0 hidden API
public final class ProviderList
{
// Since Android 10
public Provider.Service getService(String type, String name) {
return null;
}
public List<Provider> providers() {
return null;
}
}

View File

@@ -0,0 +1,8 @@
package sun.security.jca;
public class Providers
{
public static ProviderList getProviderList() {
return null;
}
}

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke android:width="5px" android:color="#000000" />
<stroke android:width="5px" android:color="#131313" />
</shape>

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 877 B

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item><layer-list>
<item><shape>
<solid android:color="@android:color/black" />
<corners android:radius="4dp" />
<padding android:left="8dp"/>
</shape></item>
<item><bitmap android:gravity="left"
android:src="@drawable/ic_earth"/>
</item>
</layer-list></item>
</selector>

View File

@@ -0,0 +1,113 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent">
<ImageView
android:layout_height="match_parent"
android:layout_width="match_parent"
android:scaleType="centerCrop"
android:adjustViewBounds="true"
android:background="@drawable/sign_in_background"/>
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="25dp"
android:background="#272727"
android:layout_gravity="center"
android:id="@+id/login_layout_linear">
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="@string/login_online_username_hint"
android:layout_gravity="left"/>
<com.kdt.mcgui.MineEditText
android:imeOptions="flagNoExtractUi"
android:layout_width="match_parent"
android:layout_height="30dp"
android:id="@+id/login_edit_email"
android:inputType="textEmailAddress"
android:layout_marginBottom="5dp"/>
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_gravity="left"
android:text="@string/login_online_password_hint"/>
<com.kdt.mcgui.MineEditText
android:imeOptions="flagNoExtractUi"
android:layout_width="match_parent"
android:layout_height="30dp"
android:id="@+id/login_edit_password"
android:inputType="textPassword"
android:layout_marginBottom="5dp"/>
<CheckBox
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_gravity="left"
android:text="@string/login_online_check_keeplogin"
android:id="@+id/login_switch_remember"/>
<CheckBox
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_gravity="left"
android:text="@string/login_offline_label"
android:id="@+id/login_switch_offline"/>
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:orientation="horizontal"
android:layout_marginBottom="10dp"
android:gravity="bottom|center_vertical">
<RelativeLayout
android:layout_height="42dp"
android:layout_width="210dp"
android:layout_marginRight="10dp">
<com.kdt.mcgui.MineButton
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/login_online_login_label"
android:onClick="loginMC"
android:gravity="center"/>
<ProgressBar
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#88000000"
android:id="@+id/launcherAccProgress"
android:visibility="gone"
android:layout_centerInParent="true"/>
</RelativeLayout>
<com.kdt.mcgui.MineButton
android:layout_width="210dip"
android:layout_height="42dp"
android:text="@string/login_select_account"
android:onClick="loginSavedAcc"/>
</LinearLayout>
</LinearLayout>
<ImageView
android:layout_height="48dp"
android:layout_width="300dp"
android:src="@drawable/logo"
android:id="@+id/login_image_logo"
android:layout_gravity="center_horizontal"/>
</FrameLayout>

View File

@@ -36,7 +36,6 @@
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#EEEEEE"
android:gravity="center_horizontal">
<ProgressBar
@@ -78,13 +77,13 @@
android:orientation="horizontal">
<TextView
android:layout_height="match_parent"
android:text="Version:"
android:textAppearance="?android:attr/textAppearanceMedium"
android:id="@+id/lMTVVer"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:textSize="12sp"
android:layout_width="wrap_content"/>
android:text="@string/main_version_"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="12sp" />
<Spinner
android:layout_width="match_parent"
@@ -94,24 +93,24 @@
</LinearLayout>
<Button
style="?android:attr/buttonBarButtonStyle"
android:layout_width="match_parent"
android:layout_height="40dp"
android:text="Options"
android:onClick="launcherMenu"
style="?android:attr/buttonBarButtonStyle"/>
android:text="@string/main_options" />
</LinearLayout>
<com.kdt.mcgui.MineButton
android:layout_toRightOf="@id/lMTVVer"
android:layout_toLeftOf="@id/launcherMainLeftLayout"
android:id="@+id/launcherMainPlayButton"
android:layout_width="wrap_content"
android:layout_height="80dp"
android:text="Play"
android:layout_alignParentBottom="true"
android:layout_margin="5dp"
android:layout_toLeftOf="@id/launcherMainLeftLayout"
android:layout_toRightOf="@id/lMTVVer"
android:onClick="launchGame"
android:id="@+id/launcherMainPlayButton"
android:layout_margin="5dp"/>
android:text="@string/main_play" />
<LinearLayout
android:id="@+id/launcherMainRightLayout"
@@ -130,10 +129,10 @@
<TextView
android:layout_width="wrap_content"
android:layout_height="20dp"
android:text="Welcome,"
android:layout_marginRight="4dp"
android:textSize="12sp"
android:gravity="center"/>
android:gravity="center"
android:text="@string/main_welcome"
android:textSize="12sp" />
<TextView
android:layout_width="wrap_content"
@@ -161,20 +160,20 @@
android:layout_height="wrap_content">
<Button
style="?android:attr/buttonBarButtonStyle"
android:layout_width="88dp"
android:layout_height="40dp"
android:text="Info (DEV)"
android:textSize="10sp"
android:onClick="mcaccSwitchUser"
style="?android:attr/buttonBarButtonStyle"/>
android:text="@string/main_infodev"
android:textSize="10sp" />
<Button
style="?android:attr/buttonBarButtonStyle"
android:layout_width="match_parent"
android:layout_height="40dp"
android:text="Switch user"
android:textSize="10sp"
android:onClick="mcaccLogout"
style="?android:attr/buttonBarButtonStyle"/>
android:text="@string/main_switchuser"
android:textSize="10sp" />
</LinearLayout>

View File

@@ -309,7 +309,7 @@
android:layout_width="200dp"
android:layout_height="match_parent"
android:layout_gravity="right"
android:fitsSystemWindows="true"
android:fitsSystemWindows="false"
app:menu="@menu/menu_runopt"
android:id="@+id/main_navigation_view"/>

View File

@@ -11,27 +11,11 @@
android:orientation="horizontal"
android:background="#000000">
<RelativeLayout
<Spinner
android:layout_height="match_parent"
android:layout_width="wrap_content">
<ImageView
android:layout_height="match_parent"
android:layout_width="42px"
android:background="#FFFFFF"
android:id="@+id/topbar_earth_icon"/>
<TextView
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:text="@string/language_name"
android:gravity="center_vertical"
android:paddingLeft="15px"
android:layout_toRightOf="@id/topbar_earth_icon"
android:textColor="#FFFFFF"
android:id="@+id/topbar_language_text"/>
</RelativeLayout>
android:layout_width="wrap_content"
style="@style/SpinnerChangeLanguage"
android:id="@+id/topbar_navmenu_changelang"/>
<LinearLayout
android:layout_height="wrap_content"

View File

@@ -24,7 +24,6 @@
<string name="login_online_create_account">(Stwórz nowe konto?)</string>
<string name="login_offline_switch">Konto offline?</string>
<string name="login_offline_warning_1">Logujesz się za pomocą konta offline, ale jeśli go nie zapiszesz, Twoje dane mogą zostać zresetowane na Twoich światach / multiplayerach / serwerach. Zalecamy, abyś go zapisał.</string>
<string name="login_offline_alert_skip">Pominąć</string>
<string name="login_error_short_username">Nazwa użytkownika musi mieć co najmniej 3 znaki</string>
@@ -51,11 +50,11 @@
<string name="alerttitle_installoptifine">Wybierz plik jar OptiFine</string>
<!-- Error messages -->
<string name="error_checklog">Błąd! Sprawdź dziennik poniżej:% s</string>
<string name="error_checklog">Błąd! Sprawdź dziennik poniżej: %s</string>
<string name="error_no_version">Brak wersji!</string>
<string name="error_load_version">Nie można załadować wersji% s</string>
<string name="error_convert_lib">Nie można przekonwertować biblioteki% s</string>
<string name="error_convert_client">Nie można przekonwertować% s Minecrafta</string>
<string name="error_load_version">Nie można załadować wersji %s</string>
<string name="error_convert_lib">Nie można przekonwertować biblioteki %s</string>
<string name="error_convert_client">Nie można przekonwertować %s Minecrafta</string>
<string name="error_show_more">Pokaż więcej</string>
<string name="error_show_less">Pokaż mniej</string>
@@ -73,14 +72,14 @@
<string name="mcl_tab_crash">Dziennik awarii</string>
<!-- MCLauncherActivity: Strings -->
<string name="mcl_version_msg">Gotowy do gry w Minecrafta% s</string>
<string name="mcl_version_msg">Gotowy do gry w Minecrafta %s</string>
<string name="mcl_launch_cleancache">Czyszczenie plików pamięci podręcznej</string>
<string name="mcl_launch_downloading">Pobieranie% s</string>
<string name="mcl_launch_download_lib">Pobieranie biblioteki% s</string>
<string name="mcl_launch_download_client">Pobieranie gry Minecraft% s</string>
<string name="mcl_launch_convert_lib">Konwertowanie biblioteki% s</string>
<string name="mcl_launch_convert_client">Konwertowanie Minecrafta% s</string>
<string name="mcl_launch_patch_client">Aktualizowanie Minecrafta% s</string>
<string name="mcl_launch_downloading">Pobieranie %s</string>
<string name="mcl_launch_download_lib">Pobieranie biblioteki %s</string>
<string name="mcl_launch_download_client">Pobieranie gry Minecraft %s</string>
<string name="mcl_launch_convert_lib">Konwertowanie biblioteki %s</string>
<string name="mcl_launch_convert_client">Konwertowanie Minecrafta %s</string>
<string name="mcl_launch_patch_client">Aktualizowanie Minecrafta %s</string>
<string name="mcl_launch_download_assets">Przygotowanie do pobrania zasobów</string>
<string name="mcl_options">Opcje</string>
@@ -155,16 +154,11 @@
<string name="control_keyboard">Klawiatura</string>
<string name="control_chat">Czat</string>
<string name="control_debug">Debug</string>
<string name="control_zoom">Zoom (C)</string>
<string name="control_zoom">Powiększenie (C)</string>
<string name="control_primary">Pri</string>
<string name="control_secondary">Sec</string>
<string name="control_shift"></string>
<string name="control_inventory">Inv</string>
<string name="control_up"></string>
<string name="control_left"></string>
<string name="control_right"></string>
<string name="control_down"></string>
<string name="control_jump"></string>
<string name="control_thirdperson">3rd</string>
<string name="control_listplayers">Tab</string>
<string name="control_mouse">Mysz</string>
@@ -189,5 +183,5 @@
<!-- Update part (unused now) -->
<string name="update_console">Zaktualizuj konsolę</string>
</resources>

View File

@@ -0,0 +1,202 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- App name part -->
<string name="app_name">PojavLauncher (Minecraft: Java Edition для Android)</string>
<string name="app_short_name">PojavLauncher</string>
<string name="app_motd">Запустите Minecraft: Java Edition на вашем устройстве!</string>
<!-- Action bar part -->
<string name="actionbar_help">ПОМОЩЬ</string>
<!-- Languages list part -->
<string name="language_name">РУССКИЙ - RU</string>
<!-- Logging output -->
<string name="log_title">Журнал</string>
<!-- Login strings -->
<string name="login_online_username_hint">Email или псевдоним</string>
<string name="login_online_username_question">(Что мне использовать?)</string>
<string name="login_online_password_hint">Пароль</string>
<string name="login_online_password_question">Забыли пароль?</string>
<string name="login_online_remember">Запомнить меня?</string>
<string name="login_online_login_label">Вход</string>
<string name="login_online_create_account">(Создать новый профиль?)</string>
<string name="login_offline_switch">Offline-профиль?</string>
<string name="login_offline_alert_skip">Пропустить</string>
<string name="login_error_short_username">Псевдоним должен быть длиной как минимум 3 символа</string>
<string name="login_error_exist_username">Этот псевдоним уже существует</string>
<string name="login_select_account">Выбрать профиль</string>
<!-- Hint -->
<string name="hint_select_account">Для выбора, нажмите. Для удаления, нажмите и задержите.</string>
<string name="hint_control_mapping">"Эта функция ещё не завершена и не может применять иные раскладки!\nПроведите справа налево чтобы открыть меню ◀\nЗадержите кнопку для настройки: изменить размер или удалить."</string>
<!-- Warning -->
<string name="warning_title">Предупреждение</string>
<string name="warning_msg">Это приложение может быть не совместимо с вашей версией Android (более свежей или равной 7.0). Попробуйте VMOS и установите его туда. Учтите, что VMOS придётся установить вручную.</string>
<string name="warning_noshowagain">Не показывать вновь</string>
<string name="warning_action_install">Установить VMOS</string>
<string name="warning_action_tryanyway">Всё равно попробуйте</string>
<string name="warning_action_exit">Выйти</string>
<string name="warning_remove_account">Этот профиль будет удалён!</string>
<!-- AlertDialog title -->
<string name="alerttitle_selectkeymap">Select a keymap json</string>
<string name="alerttitle_installmod">Добавить мод</string>
<string name="alerttitle_installoptifine">Выбрать файл OptiFine</string>
<!-- Error messages -->
<string name="error_fatal">Критическая ошибка</string>
<string name="error_checklog">Ошибка! Просмотрите журнал ниже: %s</string>
<string name="error_no_version">Нет версии!</string>
<string name="error_load_version">Ошибка при загрузке версии %s</string>
<string name="error_convert_lib">Ошибка при конвертации библиотеки %s</string>
<string name="error_convert_client">Ошибка при конвертации Minecraft %s</string>
<string name="error_show_more">Больше</string>
<string name="error_show_less">Меньше</string>
<!-- Toast messages -->
<string name="toast_permission_denied">К каталогу нет права на чтение и запись!</string>
<string name="toast_login_error">После входа что-то пошло не так. Пожалуйста, сообщите разработчику.\nОшибка: %s</string>
<string name="toast_optifine_success">Установка завершена</string>
<!--
<string name="toast_3">Exit</string>
-->
<!-- MCLauncherActivity: Tabs -->
<string name="mcl_tab_news">Новости</string>
<string name="mcl_tab_console">Терминал разработчика</string>
<!-- MCLauncherActivity: Strings -->
<string name="mcl_version_msg">Готовы к запуску Minecraft %s</string>
<string name="mcl_launch_cleancache">Удаляем временные файлы</string>
<string name="mcl_launch_downloading">Загружаем %s</string>
<string name="mcl_launch_download_lib">Загружаем библиотеку %s</string>
<string name="mcl_launch_download_client">Загружаем Minecraft %s</string>
<string name="mcl_launch_convert_lib">Конвертируем библиотеку %s</string>
<string name="mcl_launch_convert_client">Конвертируем Minecraft %s</string>
<string name="mcl_launch_patch_client">Патчим Minecraft %s</string>
<string name="mcl_launch_download_assets">Готовимся к скачиванию файлов игры</string>
<string name="mcl_options">Настройки</string>
<string name="mcl_option_modmgr">Менеджер модов (не работает)</string>
<string name="mcl_option_optifineinstall">Установить OptiFine</string>
<string name="mcl_option_checkupdate">Проверить на обновления</string>
<string name="mcl_option_customcontrol">Собстенное управление</string>
<string name="mcl_option_settings">Настройки</string>
<string name="mcl_option_about">Информация</string>
<string name="mcl_setting_title_setmaxdxref">Задать максимальное DX ссылок</string>
<string name="mcl_setting_subtitle_setmaxdxref">Увеличьте, если возникает ошибка при конвертации из-за большого количества ссылок. Рекомендуемое значение: 4096 или 8192.</string>
<string name="mcl_setting_title_freeform">Запуск Minecraft в режиме Freeform</string>
<string name="mcl_setting_subtitle_freeform">Запуск Minecraft в оконном режиме. Требуется Android 7.0+</string>
<string name="mcl_setting_subtitle_longpresstrigger">Изменить время длинного нажатия для ломания и выбрасывания</string>
<string name="mcl_setting_title_controlsize">Размер кнопок</string>
<string name="mcl_setting_title_forgetoptifpath">Заставить OptiFine не находить самого себя</string>
<string name="mcl_setting_subtitle_forgetoptifpath">Позволяет заработать OptiFine на некоторых устройствах.</string>
<string name="mcl_setting_category_general">Основные настройки</string>
<string name="mcl_setting_category_veroption">Тип версии будет показан в списке версий</string>
<string name="mcl_setting_veroption_release">Стабильные</string>
<string name="mcl_setting_veroption_snapshot">Частые</string>
<string name="mcl_setting_veroption_oldalpha">Старые (Альфа)</string>
<string name="mcl_setting_veroption_oldbeta">Старые (Бета)</string>
<string name="mcl_version_clone">Клонировать</string>
<!-- Global strings -->
<string name="global_add">Добавить</string>
<string name="global_edit">Редактировать</string>
<string name="global_error">Ошибка</string>
<string name="global_load">Загрузить</string>
<string name="global_name">Имя</string>
<string name="global_remove">Убрать</string>
<string name="global_save">Сохранить</string>
<string name="global_error_field_empty">Это поле не может быть пустым.</string>
<!--
<string name="mcl_about">
%1$s BETA (Minecraft Java launcher for Android), version " + PathTools.usingVerName + "\n" +
" - by Khanh Duy Tran (based from \"Boardwalk\" app)\n" +
//"© 2019 Khanh Duy Tran\n" +
"Using libraries:\n" +
" • LWJGL " + org.lwjgl.Sys.getVersion() + "\n" +
//" • Boardwalk memory manager (not used now).\n" +
" • gl4es: OpenGL for OpenGL ES devices by lunixbochs and ptitSeb.\n" +
" • dx: tool to convert.\n" +
" • Java AWT Implementation includes:\n" +
" - Boardwalk's makeshift.\n" +
" - Apache Harmony AWT Framework.\n" +
" - OpenJDK 7 codes implementation.\n" +
" - Developer code implement (copy text, open browser,...)\n" +
"\n" +
"* Notes:\n" +
" - This app is currently BETA, it will not be stable.\n" +
//"* This app will unstable on Android 7.0 or higher devices.\n" +
" - This app only use LWJGL2 and don't have a JRE8 desugar, so doesn't support 1.13 or higher versions.\n" +
" - This app is not affiliated with Minecraft, Mojang or Microsoft.\n")
</string>
-->
<!-- MainActivity: strings -->
<string name="mcn_exit_title">Игра закрылась</string>
<string name="mcn_exit_call">Выход</string>
<string name="mcn_exit_crash">Игра вылетела! Нажмите ОК для выхода.</string>
<string name="mcn_exit_errcrash">Unable to locate crash! You may ignore this.</string>
<string name="mcn_exit_confirm">Вы точно хотите закрыть игру немедленно?</string>
<!-- MainActivity: Control buttons -->
<string name="controls">Кнопки</string>
<string name="control_toggle">GUI</string>
<string name="control_keyboard">Клавиатура</string>
<string name="control_chat">Чат</string>
<string name="control_debug">Откладка</string>
<string name="control_zoom">Зум (C)</string>
<string name="control_primary">ЛКМ</string>
<string name="control_secondary">ПКМ</string>
<string name="control_shift"></string>
<string name="control_inventory">Инв</string>
<string name="control_up"></string>
<string name="control_left"></string>
<string name="control_right"></string>
<string name="control_down"></string>
<string name="control_jump"></string>
<string name="control_thirdperson">F5</string>
<string name="control_listplayers">Tab</string>
<string name="control_mouse">Мышь</string>
<string name="control_mouseoff">Мышь: выкл</string>
<string name="control_mouseon">Мышь: вкл </string>
<!-- MainActivity: Menu advanced controls -->
<string name="control_forceclose">Закрыть игру</string>
<string name="control_viewout">Журнал</string>
<string name="control_adebug">PointerCapture Debug</string>
<string name="control_customkey">Ввести клавишу</string>
<string name="control_more3"></string>
<string name="control_more4"></string>
<string name="customctrl_keyname">Имя</string>
<string name="customctrl_specialkey">Особенная кнопка</string>
<string name="customctrl_hidden">Спрятано</string>
<string name="customctrl_addbutton">Добавить кнопку</string>
<string name="customctrl_title_selectctrl">Выбрать раскладку по-умолчанию</string>
<string name="customctrl_selectdefault">Выбрать раскладку по-умолчанию</string>
<!-- Update part (unused now) -->
<string name="login_online_check_keeplogin">Запомнить меня</string>
<string name="login_offline_label">Войти как пират</string>
<string name="main_options">Опции</string>
<string name="main_play">Играть</string>
<string name="main_welcome">Добро пожаловать,</string>
<string name="main_infodev">Инфо (Р)</string>
<string name="main_switchuser">Сменить пользователя</string>
<string name="main_version_">Версия:</string>
<string name="mcl_setting_title_longpresstrigger">Сколько времени нужно держать кнопку</string>
<string name="mcl_tab_crash">Инфо о сбое</string>
<string name="update_console">Обновить консоль</string>
<string name="main_nocrash">Сбоев не обнаружено.</string>
<string name="main_nolog">Данных нет.</string>
</resources>

View File

@@ -20,11 +20,12 @@
<string name="login_online_password_hint">Password</string>
<string name="login_online_password_question">Forgot password?</string>
<string name="login_online_remember">Remember me?</string>
<string name="login_online_check_keeplogin">Keep me logged in</string>
<string name="login_online_login_label">Login</string>
<string name="login_online_create_account">(Create new account?)</string>
<string name="login_offline_switch">Offline account?</string>
<string name="login_offline_warning_1">You are logging in by an offline account, but if you don\'t save it, your data may be reset in your worlds/multiplayers/servers. We recommend you to save it.</string>
<string name="login_offline_label">Login as offline account</string>
<string name="login_offline_alert_skip">Skip</string>
<string name="login_error_short_username">Username must be at least 3 characters</string>
@@ -51,6 +52,7 @@
<string name="alerttitle_installoptifine">Select OptiFine jar file</string>
<!-- Error messages -->
<string name="error_fatal">PojavLauncher has unexpectedly crashed</string>
<string name="error_checklog">Error! Please check the log below: %s</string>
<string name="error_no_version">No version!</string>
<string name="error_load_version">Unable to load version %s</string>
@@ -116,6 +118,7 @@
<string name="global_load">Load</string>
<string name="global_name">Name</string>
<string name="global_remove">Remove</string>
<string name="global_restart">Restart</string>
<string name="global_save">Save</string>
<string name="global_error_field_empty">This field can\'t be empty</string>
@@ -189,5 +192,12 @@
<!-- Update part (unused now) -->
<string name="update_console">Update console</string>
<string name="main_options">Options</string>
<string name="main_play">Play</string>
<string name="main_welcome">Welcome,</string>
<string name="main_infodev">Info (DEV)</string>
<string name="main_switchuser">Switch user</string>
<string name="main_version_">Version:</string>
<string name="main_nocrash">No crash detected</string>
<string name="main_nolog">No log.</string>
</resources>

View File

@@ -1,24 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme" parent="@style/Theme.AppCompat.Light.NoActionBar">
<!-- Light or not? -->
<style name="AppTheme" parent="@style/Theme.AppCompat.NoActionBar">
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowTranslucentNavigation">true</item>
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
</style>
<style name="RunTheme" parent="@style/Theme.AppCompat.NoActionBar">
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowFullscreen">true</item>
<style name="AlertTheme" parent="@style/AppTheme">
</style>
<style name="AlertTheme" parent="@android:style/Theme.Material">
</style>
<style name="MenuDialog" parent="@android:style/Theme.Material">
<style name="MenuDialog" parent="@style/AppTheme">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
@@ -27,10 +22,17 @@
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowAnimationStyle">@style/MenuDialogAnimation</item>
<item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
</style>
<item name="android:windowTranslucentNavigation">true</item>
</style>
<style name="MenuDialogAnimation">
<item name="android:windowEnterAnimation">@anim/translate_left_side</item>
<item name="android:windowExitAnimation">@anim/translate_right_side</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
<style name="SpinnerChangeLanguage">
<item name="android:windowTranslucentNavigation">true</item>
<item name="android:background">@drawable/spinner_change_language</item>
</style>
</resources>

BIN
gradle/wrapper/gradle-wrapper.jar vendored Normal file
View File

Binary file not shown.

View File

@@ -0,0 +1,6 @@
#Mon Sep 12 09:22:55 CEST 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip

164
gradlew vendored Normal file
View File

@@ -0,0 +1,164 @@
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"