If you'd like to support our preservation efforts (and this wasn't cheap), please consider donating or supporting us on Patreon. Thank you!
Nyan Cat: Lost In Space (Android)
| Nyan Cat: Lost In Space |
|---|
|
Developer:
isTom Games
|
Nyan Cat's lost, so he's got to collect a bunch of stuff! Personally, I think the priority should be finding where in space he actually is...
Uncompiled Code
Inside the apk for at least one version is EngineActivity.java.bak: almost 40kb of uncompiled commented java code.
package com.istomgames.engine;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import com.adwhirl.AdWhirlLayout;
import com.adwhirl.AdWhirlManager;
import com.adwhirl.AdWhirlTargeting;
import com.google.ads.AdView;
import com.istomgames.engine.ExpansionDownloadService.XAPKFile;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.InputStream;
import java.lang.String;
import java.net.URL;
import java.util.Date;
import java.util.Vector;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Point;
import android.hardware.SensorManager;
import android.net.Uri;
import android.opengl.GLSurfaceView;
import android.opengl.GLUtils;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.StrictMode;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;
import android.widget.Toast;
public class EngineActivity extends Activity {
private static EngineActivity sInstance;
public static EngineActivity getInstance() { return sInstance; }
private String mFileDirPath;
private GLSurfaceView mGLView;
private GameRenderer mRenderer;
private SensorHandler mAccelerometer;
private boolean mLandscapeOriented = true;
private MusicPlayer mMusicPlayer;
private GameCenterHandler mGameCenter = null;
private FacebookHandler mFacebookHandler;
private Handler mJobHandler;
public static final String PackageName = "com.istomgames.engine";
// game center
public static final String ScoreLoopSecret = "";
// expansion download default ertekek
public static final XAPKFile[] xAPKS = {
new XAPKFile( true, // true signifies a main file
6, // the version of the APK that the file was uploaded against
60915415L // the length of the file in bytes
)
};
// az alap ertekekhez (a PackageInfo-bol kerdezi egyebkent)
public static final int majorVersion = 1;
public static final int minorVersion = 0;
private ExpansionDownloadService mExpansionDownload;
// reklamok
private AdView mAdView;
private boolean mAllowAd = true;
private int mAdWidth = 350;
private int mAdHeight = 50;
private LinearLayout mLinearLayout;
private AdWhirlLayout mAdWhirlLayout;
private final String ADWHIRL_ID = "527f7e4d17ea460d8ec588c586cc37b4";
// news update
private static final String HOST = "http://gamehs.ergosystem.hu";
static {
System.loadLibrary("openal");
System.loadLibrary("game");
}
public EngineActivity(){
sInstance = this;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i("EXP", "kell-e az expansion file?");
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int height = metrics.heightPixels;
int width = metrics.widthPixels;
// FONTOS! : jelenleg az utils.cpp-ben a GetDeviceFilenName() ugyanezt hasznalja,
// hogy eldontse melyik textura kell, ha az valtozik ezt is valtoztatni kell
int max = (width > height) ? width : height;
if (max >= 960)
{
Log.i("EXP", "igen, expansion file ellenorzese");
if (!ExpansionDownloadService.expansionFilesDelivered(this, xAPKS))
{
Intent myIntent = new Intent(EngineActivity.this, ExpansionDownloaderActivity.class);
EngineActivity.this.startActivity(myIntent);
finish();
return;
}
}
else Log.i("EXP", "nem, kis texturak hasznalata");
mJobHandler = new Handler();
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
if (mLandscapeOriented){
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
else{
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
Toast.makeText(this, "Loading...", Toast.LENGTH_SHORT).show();
try{
mAccelerometer = new SensorHandler((SensorManager)getSystemService(Context.SENSOR_SERVICE), false, true);
mMusicPlayer = new MusicPlayer(this);
/*
mGameCenter = new GameCenterHandler(getApplicationContext());
mGameCenter.login();
*/
mRenderer = new GameRenderer(this);
mGLView = new GameSurfaceView(this);
mGLView.setRenderer(mRenderer);
setContentView(mGLView);
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1)
// mGLView.setSystemUiVisibility(View.STATUS_BAR_HIDDEN);
}
catch(Exception e){
Log.e("JAVA", e.getMessage());
}
File f = this.getApplicationContext().getFilesDir();
mFileDirPath = f.toString();
mFacebookHandler = new FacebookHandler();
if (mAllowAd)
{
AdWhirlManager.setConfigExpireTimeout(1000 * 60 * 5);
AdWhirlTargeting.setKeywords("games gaming");
// AdWhirlTargeting.setTestMode(true);
mAdWhirlLayout = new AdWhirlLayout(this, ADWHIRL_ID);
mLinearLayout = new LinearLayout(this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
mLinearLayout.setGravity(Gravity.CENTER | Gravity.BOTTOM);
this.addContentView(mLinearLayout, params);
mAdWhirlLayout.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.TOP);
params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
mLinearLayout.addView(mAdWhirlLayout, params);
}
}
@Override
protected void onPause() { Log.i("JAVA", "onPause");
super.onPause();
if (mExpansionDownload == null)
{
adHide();
if (mGLView != null)
mGLView.onPause();
if (mAccelerometer != null)
mAccelerometer.pause();
if (mGameCenter != null)
mGameCenter.onPause();
}
}
@Override
protected void onResume() { Log.i("JAVA", "onResume");
super.onResume();
if (mExpansionDownload == null)
{
if (mGLView != null)
mGLView.onResume();
if (mAccelerometer != null)
mAccelerometer.resume();
if (mGameCenter != null)
mGameCenter.onResume();
if (mFacebookHandler != null)
mFacebookHandler.onResume();
}
}
protected void onStart() { Log.i("JAVA", "onStart");
super.onStart();
if (mMusicPlayer != null)
mMusicPlayer.reload();
nativeStart();
}
protected void onRestart() {
super.onRestart();
}
protected void onStop() { Log.i("JAVA", "onStop");
super.onStop();
if (mMusicPlayer != null)
mMusicPlayer.release();
nativeStop();
}
protected void onDestroy() { Log.i("JAVA", "onDestory");
nativeDestroy();
super.onDestroy();
if (mMusicPlayer != null)
mMusicPlayer.release();
if (mGameCenter != null)
mGameCenter.onExit();
if (mAdView != null)
mAdView.destroy();
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
mFacebookHandler.onActivityResult(requestCode, resultCode, data);
}
public boolean onKeyDown(int keyCode, KeyEvent event){
if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN ||
keyCode == KeyEvent.KEYCODE_VOLUME_UP ||
keyCode == KeyEvent.KEYCODE_MUTE)
return false;
GameSurfaceView.nativeKey(false, keyCode);
return true;
}
public boolean onKeyUp(int keyCode, KeyEvent event){
if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN ||
keyCode == KeyEvent.KEYCODE_VOLUME_UP ||
keyCode == KeyEvent.KEYCODE_MUTE)
return false;
GameSurfaceView.nativeKey(true, keyCode);
return true;
}
public boolean isLandscapeOriented(){
return mLandscapeOriented;
}
public GameCenterHandler getGameCenterHandler(){
return mGameCenter;
}
public int getAdWidth(){
return mAdWidth;
}
public int getAdHeight(){
return mAdHeight;
}
public Handler getJobHandler(){
return mJobHandler;
}
static public void showErrorMessage(final String msg){
sInstance.mJobHandler.post(new Runnable() {
public void run() {
Toast t = Toast.makeText(sInstance, "error: " + msg, Toast.LENGTH_LONG);
// t.setGravity(Gravity.TOP, 0, 0);
t.show();
}
});
}
static public void alertSmallResolution(){
sInstance.mJobHandler.post(new Runnable() {
public void run() {
try{
AlertDialog.Builder builder = new AlertDialog.Builder(EngineActivity.sInstance);
builder.setTitle("Small Resolution")
.setMessage("The resolution of your phone is not officially supported. " +
"You can still play but you may experience problems " +
"and graphical errors.")
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
}
catch (Exception e){
Log.i("Exception", e.toString());
}
}
});
}
//c++-bol hivodnak
static public void loadMusic(String path){
if (sInstance.mMusicPlayer != null){
sInstance.mMusicPlayer.load(path);
Log.i("MUSIC", "load music:" + path);
}
}
static public void startMusic(){
if (sInstance.mMusicPlayer != null)
sInstance.mMusicPlayer.start();
}
static public void stopMusic(){
if (sInstance.mMusicPlayer != null)
sInstance.mMusicPlayer.stop();
}
static public void pauseMusic(){
if (sInstance.mMusicPlayer != null)
sInstance.mMusicPlayer.pause();
}
static public void setVolume(float volume){
if (sInstance.mMusicPlayer != null)
sInstance.mMusicPlayer.setVolume(volume);
}
static public void openfeintLogin(){ Log.i("JAVA", "openfeintLogin");
if (sInstance.mGameCenter != null)
sInstance.mGameCenter.login();
}
static public void showLeaderboard(String leaderboardId){
if (sInstance.mGameCenter != null)
sInstance.mGameCenter.showLeaderboard(leaderboardId);
}
static public void reportScore(long score, String leaderboardId){
if (sInstance.mGameCenter != null)
sInstance.mGameCenter.reportScore(score, leaderboardId);
}
static public void openURL(String url){
if (!url.startsWith("http://") && !url.startsWith("https://"))
url = "http://" + url;
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
sInstance.startActivity(browserIntent);
}
static public void sendMail(String subject, String body){
Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, subject);
emailIntent.setType("text/plain");
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, body);
sInstance.startActivity(emailIntent);
}
static public void adShow(){
if (sInstance.mAllowAd)
{
sInstance.mJobHandler.post(new Runnable() {
public void run() {
try{
if(sInstance.mAdWhirlLayout.getVisibility() != AdWhirlLayout.VISIBLE)
{
sInstance.mAdWhirlLayout.setVisibility(AdWhirlLayout.VISIBLE);
sInstance.mLinearLayout.addView(sInstance.mAdWhirlLayout);
}
}
catch (Exception e){
Log.i("Exception", e.toString());
}
}
});
}
}
static public void adHide(){
if (sInstance.mAllowAd)
{
sInstance.mJobHandler.post(new Runnable() {
public void run() {
try{
if(sInstance.mAdWhirlLayout.getVisibility() == AdWhirlLayout.VISIBLE)
{
sInstance.mAdWhirlLayout.setVisibility(AdWhirlLayout.GONE);
sInstance.mLinearLayout.removeView(sInstance.mAdWhirlLayout);
}
}
catch (Exception e){
Log.i("Exception", e.toString());
}
}
});
}
}
static public void fbLogin(){
sInstance.mJobHandler.post(new Runnable() {
public void run() {
sInstance.mFacebookHandler.login();
}
});
}
static public void fbLogout(){
sInstance.mJobHandler.post(new Runnable() {
public void run() {
sInstance.mFacebookHandler.logout();
}
});
}
static public void fbPublish(final String attachName, final String attachCapiton, final String attachDescription, final String attachLink){
sInstance.mJobHandler.post(new Runnable() {
public void run() {
sInstance.mFacebookHandler.publishStream(attachName, attachCapiton, attachDescription, attachLink);
}
});
}
static public boolean fbIsLoggedIn() {
return sInstance.mFacebookHandler.isLoggedIn();
}
static public void sendTweet(String tweet){
// sInstance.mJobHandler.post(new Runnable() {
// public void run() {
Intent tweetIntent = new Intent(android.content.Intent.ACTION_SEND);
tweetIntent.setType("text/plain");
tweetIntent.putExtra(android.content.Intent.EXTRA_TEXT, tweet);
sInstance.startActivity(tweetIntent);
// }
// });
}
static public int getMajorVersion()
{
try{
PackageInfo pInfo = sInstance.getPackageManager().getPackageInfo(sInstance.getPackageName(), 0);
return Integer.parseInt(pInfo.versionName.substring(0, pInfo.versionName.indexOf('.')));
}
catch(Exception e) {
Log.w("JAVA", e.toString());
}
return majorVersion;
}
static public int getMinorVersion()
{
try{
PackageInfo pInfo = sInstance.getPackageManager().getPackageInfo(sInstance.getPackageName(), 0);
return Integer.parseInt(pInfo.versionName.substring(pInfo.versionName.indexOf('.')+1));
}
catch(Exception e) {
Log.w("JAVA", e.toString());
}
return minorVersion;
}
static public void displayExitDialog(){
sInstance.mJobHandler.post(new Runnable() {
public void run() {
AlertDialog dialog = new AlertDialog.Builder(sInstance).create();
dialog.setTitle("Quit");
dialog.setMessage("Are you sure you want to quit?");
dialog.setButton(AlertDialog.BUTTON_POSITIVE, "Yes, quit!", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
android.os.Process.killProcess(android.os.Process.myPid());
}
});
dialog.setButton(AlertDialog.BUTTON_NEGATIVE, "No, keep playing...", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
dialog.show();
}
});
}
static public void newsUpdate(){
new Thread(new Runnable() {
public void run() {
BufferedInputStream in = null;
FileOutputStream fout = null;
try{
String url = HOST + "/android_news/news.txt";
String filename = EngineActivity.sInstance.mFileDirPath;
filename += (filename.endsWith("/")) ? "cache/last_news.txt" : "/cache/last_news.txt";
// letolteni news.txt-t
in = new BufferedInputStream(new URL(url).openStream());
fout = new FileOutputStream(filename);
byte data[] = new byte[1024];
int count;
while ((count = in.read(data, 0, 1024)) != -1)
{
fout.write(data, 0, count);
}
in.close();
fout.close();
// kepnevek kiszedese
Vector<String> imageNames = new Vector<String>();
BufferedReader reader = new BufferedReader(new FileReader(filename));
String line;
int startIndex, endIndex;
String picName;
while ((line = reader.readLine()) != null) {
if (line.contains("filename")){
startIndex = line.indexOf("<t>") + 3;
endIndex = line.indexOf("</t>");
picName = line.substring(startIndex, endIndex);
if (line.contains("banner_base_filename")){
if (!sInstance.mLandscapeOriented)
picName += "_p";
picName += GetBannerPicPostFix();
}
imageNames.add(picName);
}
else if (line.contains("image")){
startIndex = line.indexOf('"') + 1;
endIndex = line.lastIndexOf('"');
picName = line.substring(startIndex, endIndex);
picName += GetBannerPicPostFix();
imageNames.add(picName);
}
}
reader.close();
//letoltes idejenek a beleirasa
Date d = new Date();
BufferedWriter writer = new BufferedWriter(new FileWriter(filename, true));
writer.newLine();
writer.append("downloaded = " + d.getTime());
writer.newLine();
writer.close();
// kepek letoltese
for (int i = 0; i < imageNames.size(); ++i){
StringBuilder picUrl = new StringBuilder();
picUrl.append(HOST); picUrl.append("/android_news/"); picUrl.append(imageNames.get(i)); picUrl.append(".png");
StringBuilder picFile = new StringBuilder();
picFile.append(EngineActivity.sInstance.mFileDirPath);
if (picFile.charAt(picFile.length() - 1) != '/')
picFile.append("/");
picFile.append("cache/");
picFile.append(imageNames.get(i));
picFile.append(".png");
java.io.File file = new java.io.File(picFile.toString());
if(!file.exists()){
Log.i("DOWNLOAD", "start image:"+picUrl.toString());
in = new BufferedInputStream(new URL(picUrl.toString()).openStream());
fout = new FileOutputStream(picFile.toString());
byte picData[] = new byte[1024];
int picCount;
while ((picCount = in.read(picData, 0, 1024)) != -1)
fout.write(picData, 0, picCount);
in.close();
fout.close();
Log.i("DOWNLOAD", "image downloaded:"+picUrl.toString());
}
else
Log.i("DOWNLOAD", "image skipped:"+picUrl.toString()+" (already exists)");
}
}
catch(Exception e){
Log.w("JAVA", "update chache error:"+e.toString());
}
finally {
/* try{
if (in != null) in.close();
if (fout != null) fout.close();
} catch (Exception e){
}*/
}
}
}).start();
}
static private String GetBannerPicPostFix()
{
int width = EngineActivity.sInstance.getWindowManager().getDefaultDisplay().getWidth();
if (width > 768)
return "_ipad";
else if (width > 480)
return "_ip4";
else
return "_ip";
}
//nativ hivasok
static private native void nativeStop();
static private native void nativeStart();
static private native void nativeDestroy();
}
class GameSurfaceView extends GLSurfaceView {
static private GameSurfaceView instance;
private Vector<TouchEvent> mTouchEvents = new Vector<TouchEvent>();
public GameSurfaceView(Context context) {
super(context);
this.setKeepScreenOn(true);
instance = this;
}
private float lastTouchX;
private float lastTouchY;
private int touchId = -1;
public boolean onTouchEvent(final MotionEvent event) {
switch(event.getAction())
{
case MotionEvent.ACTION_DOWN:
{
if (touchId < 0)
{
touchId = event.getPointerId(0);
float x = event.getX(0);
float y = event.getY(0);
//nativeTouch(toByte(MsgType.MT_ACTION_DOWN), x,y, 0.0f,0.0f, (byte)0);
mTouchEvents.add(new TouchEvent(toByte(MsgType.MT_ACTION_DOWN), x,y, 0.0f,0.0f, (byte)0));
lastTouchX = x;
lastTouchY = y;
}
break;
}
case MotionEvent.ACTION_UP:
{
int index = event.findPointerIndex(touchId);
if (index >= 0)
{
float x = event.getX(index);
float y = event.getY(index);
//nativeTouch(toByte(MsgType.MT_ACTION_UP), x, y, x - lastTouchX, y - lastTouchY, (byte)0);
mTouchEvents.add(new TouchEvent(toByte(MsgType.MT_ACTION_UP), x, y, x - lastTouchX, y - lastTouchY, (byte)0));
touchId = -1;
}
break;
}
case MotionEvent.ACTION_MOVE:
{
int index = event.findPointerIndex(touchId);
if (index >= 0)
{
float x = event.getX(index);
float y = event.getY(index);
//nativeTouch(toByte(MsgType.MT_ACTION_MOVE), x, y, x - lastTouchX, y - lastTouchY, (byte)0);
mTouchEvents.add(new TouchEvent(toByte(MsgType.MT_ACTION_MOVE), x, y, x - lastTouchX, y - lastTouchY, (byte)0));
lastTouchX = x;
lastTouchY = y;
}
break;
}
case MotionEvent.ACTION_CANCEL:
{
if (event.getPointerId(event.getActionIndex()) == touchId)
{
touchId = -1;
//nativeTouch(toByte(MsgType.MT_ACTION_CANCEL), 0.0f,0.0f ,0.0f,0.0f, (byte)0);
mTouchEvents.add(new TouchEvent(toByte(MsgType.MT_ACTION_CANCEL), 0.0f,0.0f ,0.0f,0.0f, (byte)0));
}
break;
}
}
return true;
}
private byte toByte(MsgType type){
return (byte)type.ordinal();
}
private enum MsgType
{
MT_ACTION_DOWN,
MT_ACTION_UP,
MT_ACTION_MOVE,
MT_ACTION_CANCEL,
MT_ACTION_SCROLL
}
class TouchEvent{
byte type;
float x;
float y;
float dx;
float dy;
byte modifiers;
public TouchEvent(byte type, float x, float y, float dx, float dy, byte modifiers){
this.type = type;
this.x = x;
this.y = y;
this.dx = dx;
this.dy = dy;
this.modifiers = modifiers;
}
public void SendToNative(){
nativeTouch(type, x, y, dx, dy, modifiers);
}
}
static public void sendNativeTouchEvents(){
if (instance.mTouchEvents.size() > 0){
for (int i = 0; i < instance.mTouchEvents.size(); ++i){
instance.mTouchEvents.get(i).SendToNative();
}
instance.mTouchEvents.clear();
}
}
private static native void nativeTouch(byte type, float x, float y, float dx, float dy, byte modifiers);
public static native void nativeKey(boolean up, int keycode);
}
class GameRenderer implements GLSurfaceView.Renderer {
private static GameRenderer instance;
private Context context;
private int width;
private int height;
private Vector<Integer> freeTextures = new Vector<Integer>();
private Vector<TextureData> loadedTextures = new Vector<TextureData>();
private Vector<TextureData> waitingTextures = new Vector<TextureData>();
private Vector<Integer> toBeDeleted = new Vector<Integer>();
private final int defaultHandleNum = 64;
public GameRenderer(Context context){
this.context = context;
instance = this;
}
boolean firstCreated = true;
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
if (firstCreated)
{
String apkFilePath = null;
ApplicationInfo appInfo = null;
PackageManager packMgr = context.getPackageManager();
try{
appInfo = packMgr.getApplicationInfo("com.istomgames.engine", 0);
}
catch (NameNotFoundException e){
e.printStackTrace();
throw new RuntimeException("Unable to locate assets, abort...");
}
createTextureHandles(gl, defaultHandleNum);
apkFilePath = appInfo.sourceDir;
File f = EngineActivity.getInstance().getApplicationContext().getFilesDir();
Log.i("file path", f.toString());
Log.i("JAVA", "nativeInit");
nativeInit(apkFilePath, f.toString());
firstCreated = false;
}
}
private boolean firstChange = true;
public void onSurfaceChanged(GL10 gl, int w, int h) { Log.i("JAVA", "onSurfaceChanged");
if (firstChange)
{
firstChange = false;
Log.i("JAVA", "nativeResize");
int max = (w > h) ? w : h;
Log.i("JAVA", "resolution:"+w+"x"+h);
if (max < 480)
EngineActivity.alertSmallResolution();
if (!EngineActivity.getInstance().isLandscapeOriented())
{
nativeResize(w, h);
width = w;
height = h;
}
else
{
nativeResize(h, w);
width = h;
height = w;
}
}
else
{
reloadTextures(gl);
nativeReloadGLResources();
}
}
public void onDrawFrame(GL10 gl) {
GameSurfaceView.sendNativeTouchEvents();
if (!toBeDeleted.isEmpty())
{
deleteToBeDeleted(gl);
}
else
if (!waitingTextures.isEmpty())
{
loadWaitingTextures(gl);
}
else
nativeRender();
}
public static native void nativeInit(String apkPath, String fileDirPath);
public static native void nativeResize(int w, int h);
public static native void nativeRender();
public static native void nativeReloadGLResources();
private void reloadTextures(GL10 gl){
for (int i = 0; i < loadedTextures.size(); ++i)
{
int[] texture = new int[1];
texture[0] = loadedTextures.get(i).id;
gl.glDeleteTextures(1, texture, 0);
}
while(freeTextures.size() > 0)
{
int[] texture = new int[1];
texture[0] = freeTextures.remove(0);
gl.glDeleteTextures(1, texture, 0);
}
freeTextures.clear();
createTextureHandles(gl, defaultHandleNum);
for (int i = 0; i < waitingTextures.size(); ++i)
{
waitingTextures.get(i).id = freeTextures.remove(0);
}
for (int i = 0; i < loadedTextures.size(); ++i)
{
TextureData data = loadedTextures.get(i);
addWaitingTexture(data.filename);
}
loadedTextures.clear();
System.gc();
Log.i("JAVA", "Reloaded texture num:" + loadedTextures.size());
}
private void createTextureHandles(GL10 gl, int num){
int[] textures = new int[num];
gl.glGenTextures(num, textures, 0);
for (int i = 0; i < textures.length; ++i)
freeTextures.add(textures[i]);
}
// ezt taroljuk
static public class TextureData {
public String filename;
public Bitmap bitmap;
public int id;
public int width;
public int height;
public TextureInfo toTextureInfo()
{
TextureInfo info = new TextureInfo();
info.id = id;
info.width = width;
info.height = height;
return info;
}
}
// ezt adja vissza, mikor valaki texturat akar betölteni
static public class TextureInfo {
public int width;
public int height;
public int id;
}
private void loadWaitingTextures(GL10 gl){
while (!waitingTextures.isEmpty())
{
TextureData data = waitingTextures.remove(0);
if (data.bitmap == null || data.bitmap.isRecycled())
Log.e("ERROR", "ERROR: loadWaitingTextures bitmap is null or recycled");
gl.glBindTexture(GL10.GL_TEXTURE_2D, data.id);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, data.bitmap, 0);
data.bitmap.recycle();
data.bitmap = null;
loadedTextures.add(data);
}
}
private TextureInfo loadTexture(String filename) {
TextureInfo result = null;
for (int i = 0; i < loadedTextures.size(); ++i)
if (loadedTextures.get(i).filename.equals(filename))
result = loadedTextures.get(i).toTextureInfo();
if (result == null){
for (int i = 0; i < waitingTextures.size(); ++i)
if (waitingTextures.get(i).filename.equals(filename))
return waitingTextures.get(i).toTextureInfo();
}
if (result == null)
result = addWaitingTexture(filename);
// a ha keres erkezik a textura betoltesre, akkor toroljuk ki a torlendok listajarol
if (toBeDeleted.size() > 0){
for (int i = 0; i < toBeDeleted.size(); ++i)
if (result.id == toBeDeleted.get(i))
toBeDeleted.remove(i);
}
return result;
}
private static Bitmap loadBitmap(String filename){
Bitmap bitmap = null;
InputStream stream = null;
try {
stream = new FileInputStream(filename);
}
catch (Exception e) {
try {
if (filename.startsWith("assets/"))
filename = filename.substring("assets/".length(), filename.length());
stream = EngineActivity.getInstance().getAssets().open(filename);
}
catch (Exception e2) {
Log.i("JAVA", "addWaitingTexture() file:"+filename+" error: " + e2.toString() + "(lehet hogy az expansion fajlban van)");
try {
// nincs stream, probaljuk az expansion file-t
if (filename.startsWith("assets/"))
filename = filename.substring("assets/".length(), filename.length());
Log.i("JAVA", "fajl betoltese expansion fajlbol:"+filename);
stream = ExpansionDownloadService.getFileFromMainExpansion(EngineActivity.getInstance(), EngineActivity.xAPKS[0], filename);
}
catch(Exception e3) {
Log.e("JAVA","addWaitingTexture() file:"+filename+" error: " + e3.toString());
}
}
}
bitmap = BitmapFactory.decodeStream(stream);
return bitmap;
}
private TextureInfo addWaitingTexture(String filename) {
TextureInfo info = new TextureInfo();
try {
Bitmap bitmap = loadBitmap(filename);
int textureId = freeTextures.remove(0);
if (bitmap != null)
Log.i("JAVA", "bitmap loaded: "+filename);
else
Log.i("JAVA", "bitmap is null! ("+filename+")");
info.width = bitmap.getWidth();
info.height = bitmap.getHeight();
info.id = textureId;
TextureData data = new TextureData();
data.filename = filename;
data.bitmap = bitmap;
data.id = textureId;
data.width = bitmap.getWidth();
data.height = bitmap.getHeight();
waitingTextures.add(data);
} catch(Exception e) {
Log.i("JAVA", "loadTexture() file: "+filename+" error: " + e.toString());
}
return info;
}
private void deleteToBeDeleted(GL10 gl){
TextureData data;
int id;
for (int i = 0;i < toBeDeleted.size(); ++i){
data = null;
id = toBeDeleted.get(i);
for (int j = 0; j < loadedTextures.size(); ++j){
if (loadedTextures.get(j).id == id){
data = loadedTextures.get(j);
loadedTextures.remove(j);
break;
}
}
if (data == null){
for (int k = 0; k < waitingTextures.size(); ++k){
if (waitingTextures.get(k).id == id){
data = waitingTextures.get(k);
waitingTextures.remove(k);
break;
}
}
}
if (data != null)
deleteTexture(gl, data);
}
toBeDeleted.clear();
System.gc();
}
private void deleteTexture(GL10 gl, TextureData data){
if (data.bitmap != null)
{
data.bitmap.recycle();
data.bitmap = null;
}
int[] texture = new int[]{data.id};
gl.glDeleteTextures(1, texture, 0);
System.gc();
Log.i("### JAVA TESZT ###", "delete texture:" + data.filename);
}
public static void releaseTexture(int id){
instance.toBeDeleted.add(id);
}
public static TextureInfo createTexture(String filename) {
return GameRenderer.instance.loadTexture(filename);
}
// fuggvenyek a CImageBits-hez
// a kis texturakhoz (pár kb-os háttér pixel texturak) (ha nagyobb texturakhoz is kell majd, akkor at kellene irni, hogy ne egyesevel kerdezze le a pixel ertekeket)
private static String lastFileName = null;
private static Bitmap lastBitmap = null;
private static Bitmap getLastBitmap(String filename){
Bitmap bitmap = null;
if (lastFileName != null && lastFileName.equals(filename)){
bitmap = lastBitmap;
}
else{
if (lastBitmap != null)
lastBitmap.recycle();
bitmap = loadBitmap(filename);
lastBitmap = bitmap;
lastFileName = filename;
}
return bitmap;
}
public static int getPixel(String filename, int x, int y){
Bitmap bitmap = getLastBitmap(filename);
int color = (bitmap != null) ? bitmap.getPixel(x, y) : 0;
color = (Color.alpha(color) << 24) | (Color.blue(color) << 16) | (Color.green(color) << 8) | Color.red(color);
return color;
}
public static int getWidth(String filename){
Bitmap bitmap = getLastBitmap(filename);
return (bitmap != null) ? bitmap.getWidth() : 0;
}
public static int getHeight(String filename){
Bitmap bitmap = getLastBitmap(filename);
return (bitmap != null) ? bitmap.getHeight() : 0;
}
}
A translation of the Hungarian text found in the above code:
| Hungarian: | English: |
| expansion download default ertekek | expansion download default values |
| az alap ertekekhez (a PackageInfo-bol kerdezi egyebkent) | for the default values (otherwise it queries PackageInfo) |
| reklamok | ads |
| kell-e az expansion file? | do we need the expansion file? |
| FONTOS! : jelenleg az utils.cpp-ben a GetDeviceFilenName() ugyanezt hasznalja,
hogy eldontse melyik textura kell, ha az valtozik ezt is valtoztatni kell |
IMPORTANT! : currently GetDeviceFilenName() in utils.cpp uses this
to decide which texture is needed, if that changes this needs to be changed too |
| igen, expansion file ellenorzese | yes, verifying expansion file |
| nem, kis texturak hasznalata | no, use small textures |
| c++-bol hivodnak | called from c++ |
| letoltes idejenek a beleirasa | write time of download |
| ezt adja vissza, mikor valaki texturat akar betölteni | this gets returned when someone wants to load a texture |
| a ha keres erkezik a textura betoltesre, akkor toroljuk ki a torlendok listajarol | if a request to load a texture arrives, remove it from the to-be-deleted list |
| (lehet hogy az expansion fajlban van) | (it's possible that it's in the expansion file) |
| ### JAVA TESZT ### | ### JAVA TEST ### |
| fuggvenyek a CImageBits-hez
a kis texturakhoz (pár kb-os háttér pixel texturak) (ha nagyobb texturakhoz is kell majd, akkor at kellene irni, hogy ne egyesevel kerdezze le a pixel ertekeket) |
functions for CImageBits
for small textures (background pixel textures weighing a few kilobytes) (if needed for bigger textures, it should be rewritten so that it doesn't read pixel values one by one) |