# HG changeset patch # User Xeli # Date 1319144074 -7200 # Node ID 10011f051f9cc5d8405f220610f64e1b70614447 # Parent 9a7cc0f29430948e758709498ef7f8b8f7ba4574 Changed package name from org.hedgewars.mobile to org.hedgewars.hedgeroid to upload it to the market diff -r 9a7cc0f29430 -r 10011f051f9c hedgewars/options.inc --- a/hedgewars/options.inc Sun Oct 09 20:41:17 2011 +0200 +++ b/hedgewars/options.inc Thu Oct 20 22:54:34 2011 +0200 @@ -33,7 +33,7 @@ {$DEFINE S3D_DISABLED} {$DEFINE GLunit:=gles11} {$DEFINE MOBILE} - {$DEFINE Java_Prefix := 'Java_org_hedgewars_mobile_EngineProtocol_PascalExports_'} + {$DEFINE Java_Prefix := 'Java_org_hedgewars_hedgeroid_EngineProtocol_PascalExports_'} {$ENDIF} {$IFDEF IPHONEOS} diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/AndroidManifest.xml --- a/project_files/Android-build/SDL-android-project/AndroidManifest.xml Sun Oct 09 20:41:17 2011 +0200 +++ b/project_files/Android-build/SDL-android-project/AndroidManifest.xml Thu Oct 20 22:54:34 2011 +0200 @@ -1,6 +1,6 @@ diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/jni/SDL/src/core/android/SDL_android.cpp --- a/project_files/Android-build/SDL-android-project/jni/SDL/src/core/android/SDL_android.cpp Sun Oct 09 20:41:17 2011 +0200 +++ b/project_files/Android-build/SDL-android-project/jni/SDL/src/core/android/SDL_android.cpp Thu Oct 20 22:54:34 2011 +0200 @@ -19,6 +19,9 @@ Sam Lantinga slouken@libsdl.org */ + +#define org_hedgewars_hedgeroid org_hedgewars_hedgeroid + #include "SDL_config.h" #include "SDL_stdinc.h" @@ -100,7 +103,7 @@ } // Resize -extern "C" void Java_org_hedgewars_mobile_SDLActivity_onNativeResize( +extern "C" void Java_org_hedgewars_hedgeroid_SDLActivity_onNativeResize( JNIEnv* env, jclass jcls, jint width, jint height, jint format) { @@ -108,21 +111,21 @@ } // Keydown -extern "C" void Java_org_hedgewars_mobile_SDLActivity_onNativeKeyDown( +extern "C" void Java_org_hedgewars_hedgeroid_SDLActivity_onNativeKeyDown( JNIEnv* env, jclass jcls, jint keycode) { Android_OnKeyDown(keycode); } // Keyup -extern "C" void Java_org_hedgewars_mobile_SDLActivity_onNativeKeyUp( +extern "C" void Java_org_hedgewars_hedgeroid_SDLActivity_onNativeKeyUp( JNIEnv* env, jclass jcls, jint keycode) { Android_OnKeyUp(keycode); } // Touch -extern "C" void Java_org_hedgewars_mobile_SDLActivity_onNativeTouch( +extern "C" void Java_org_hedgewars_hedgeroid_SDLActivity_onNativeTouch( JNIEnv* env, jclass jcls, jint action, jint pointerId, jfloat x, jfloat y, jfloat p) { @@ -130,7 +133,7 @@ } // Accelerometer -extern "C" void Java_org_hedgewars_mobile_SDLActivity_onNativeAccel( +extern "C" void Java_org_hedgewars_hedgeroid_SDLActivity_onNativeAccel( JNIEnv* env, jclass jcls, jfloat x, jfloat y, jfloat z) { @@ -140,14 +143,14 @@ } // Quit -extern "C" void Java_org_hedgewars_mobile_SDLActivity_nativeQuit( +extern "C" void Java_org_hedgewars_hedgeroid_SDLActivity_nativeQuit( JNIEnv* env, jclass cls) { // Inject a SDL_QUIT event SDL_SendQuit(); } -extern "C" void Java_org_hedgewars_mobile_SDLActivity_nativeRunAudioThread( +extern "C" void Java_org_hedgewars_hedgeroid_SDLActivity_nativeRunAudioThread( JNIEnv* env, jclass cls) { /* This is the audio thread, with a different environment */ diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/jni/SDL/src/main/android/SDL_android_main.cpp --- a/project_files/Android-build/SDL-android-project/jni/SDL/src/main/android/SDL_android_main.cpp Sun Oct 09 20:41:17 2011 +0200 +++ b/project_files/Android-build/SDL-android-project/jni/SDL/src/main/android/SDL_android_main.cpp Thu Oct 20 22:54:34 2011 +0200 @@ -17,7 +17,7 @@ } // Start up the SDL app -extern "C" void Java_org_hedgewars_mobile_SDLActivity_nativeInit(JNIEnv* env, jclass cls, jobjectArray strArray) +extern "C" void Java_org_hedgewars_hedgeroid_SDLActivity_nativeInit(JNIEnv* env, jclass cls, jobjectArray strArray) { /* This interface could expand with ABI negotiation, calbacks, etc. */ SDL_Android_Init(env, cls); diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadActivity.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadActivity.java Thu Oct 20 22:54:34 2011 +0200 @@ -0,0 +1,180 @@ +/* + * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game + * Copyright (c) 2011 Richard Deurwaarder + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +package org.hedgewars.hedgeroid.Downloader; + +import org.hedgewars.hedgeroid.MainActivity; +import org.hedgewars.mobile.R; + +import android.app.Activity; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.ServiceConnection; +import android.os.Bundle; +import android.os.Handler; +import android.os.IBinder; +import android.os.Message; +import android.os.Messenger; +import android.os.RemoteException; +import android.preference.PreferenceManager; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.Button; +import android.widget.ProgressBar; +import android.widget.TextView; +import android.widget.Toast; + +public class DownloadActivity extends Activity{ + private Messenger messageService; + private boolean boundToService = false; + + private TextView progress_sub; + private ProgressBar progress; + private Button positive, negative; + + public static final int MSG_START = 0; + public static final int MSG_UPDATE = 1; + public static final int MSG_DONE = 2; + public static final int MSG_FAILED = 3; + private Handler.Callback messageCallback = new Handler.Callback() { + + public boolean handleMessage(Message msg) { + switch(msg.what){ + case MSG_START: + progress.setMax(msg.arg1); + progress_sub.setText(String.format("%dkb/%dkb\n%s", 0, msg.arg1, "")); + positive.setText(R.string.download_background); + positive.setOnClickListener(backgroundClicker); + negative.setText(R.string.download_cancel); + negative.setOnClickListener(cancelClicker); + break; + case MSG_UPDATE: + progress_sub.setText(String.format("%d%% - %dkb/%dkb\n%s",(msg.arg1*100)/msg.arg2, msg.arg1, msg.arg2, msg.obj)); + progress.setProgress(msg.arg1); + break; + case MSG_DONE: + progress.setProgress(progress.getMax()); + progress_sub.setText(R.string.download_done); + + positive.setText(R.string.download_back); + positive.setOnClickListener(doneClicker); + + negative.setVisibility(View.INVISIBLE); + break; + case MSG_FAILED: + progress.setProgress(progress.getMax()); + progress_sub.setText(R.string.download_failed); + positive.setText(R.string.download_back); + positive.setOnClickListener(doneClicker); + + negative.setText(R.string.download_tryagain); + negative.setOnClickListener(tryAgainClicker); + break; + } + return false; + } + }; + private Handler messageHandler = new Handler(messageCallback); + private Messenger messenger = new Messenger(messageHandler); + + public void onCreate(Bundle savedInstanceState){ + super.onCreate(savedInstanceState); + setContentView(R.layout.download); + + progress_sub = (TextView)findViewById(R.id.progressbar_sub); + progress = (ProgressBar)findViewById(R.id.progressbar); + + positive = (Button) findViewById(R.id.background); + negative = (Button) findViewById(R.id.cancelDownload); + positive.setOnClickListener(backgroundClicker); + negative.setOnClickListener(cancelClicker); + + } + + private OnClickListener backgroundClicker = new OnClickListener(){ + public void onClick(View v){ + finish(); + } + }; + private OnClickListener cancelClicker = new OnClickListener(){ + public void onClick(View v){ + Intent i = new Intent(getApplicationContext(), DownloadService.class); + i.putExtra("taskID", DownloadService.TASKID_CANCEL); + startService(i); + finish(); + } + }; + private OnClickListener doneClicker = new OnClickListener(){ + public void onClick(View v){ + finish(); + startActivity(new Intent(getApplicationContext(), MainActivity.class)); + } + }; + + private OnClickListener tryAgainClicker = new OnClickListener(){ + public void onClick(View v){ + bindToService(DownloadService.TASKID_RETRY); + } + }; + + public void onStart(){ + super.onStart(); + bindToService(DownloadService.TASKID_START); + } + + public void onStop(){ + super.onStop(); + unBindFromService(); + } + + private ServiceConnection connection = new ServiceConnection(){ + + public void onServiceConnected(ComponentName name, IBinder service) { + messageService = new Messenger(service); + + try{ + Message msg = Message.obtain(null, DownloadService.MSG_REGISTER_CLIENT); + msg.replyTo = messenger; + messageService.send(msg); + + }catch (RemoteException e){} + } + + public void onServiceDisconnected(ComponentName name) { + messageService = null; + } + + }; + + private void bindToService(int taskId){ + Intent i = new Intent(getApplicationContext(), DownloadService.class); + i.putExtra("taskID", taskId); + startService(i); + bindService(new Intent(getApplicationContext(), DownloadService.class), connection, Context.BIND_AUTO_CREATE); + boundToService = true; + } + + private void unBindFromService(){ + if(boundToService){ + boundToService = false; + unbindService(connection); + } + } +} diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadAsyncTask.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadAsyncTask.java Thu Oct 20 22:54:34 2011 +0200 @@ -0,0 +1,212 @@ +/* + * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game + * Copyright (c) 2011 Richard Deurwaarder + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +package org.hedgewars.hedgeroid.Downloader; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URL; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import android.os.AsyncTask; +import android.util.Log; +/** + * This is an AsyncTask which will download a zip from an URL and unzip it to a specified path + * + * a typical call to start the task would be new DownloadAsyncTask().execute(getExternalStorage(), "www.hedgewars.org/data.zip"); + * @author Xeli + * + */ +public class DownloadAsyncTask extends AsyncTask { + + private final static String URL_WITHOUT_SUFFIX = "http://hedgewars.googlecode.com/files/data_5631."; + //private final static String URL_WITHOUT_SUFFIX = "http://www.xelification.com/tmp/firebutton."; + private final static String URL_ZIP_SUFFIX = "zip"; + private final static String URL_HASH_SUFFIX = "hash"; + + private DownloadService service; + private long lastUpdateMillis = 0; + + public DownloadAsyncTask(DownloadService _service){ + service = _service; + } + + /** + * + * @param params - 2 Strings, first is the path where the unzipped files will be stored, second is the URL to download from + */ + protected Long doInBackground(String... params) { + HttpURLConnection conn = null; + MessageDigest digester = null; + String rootZipDest = params[0]; + + File rootDest = new File(rootZipDest);//TODO check for nullpointer, it hints to the absence of an sdcard + rootDest.mkdir(); + + try { + URL url = new URL(URL_WITHOUT_SUFFIX + URL_ZIP_SUFFIX); + conn = (HttpURLConnection)url.openConnection(); + } catch (IOException e) { + e.printStackTrace(); + return -1l; + } + + String contentType = conn.getContentType(); + + if(contentType == null || contentType.contains("zip")){ //Seeing as we provide the url if the contentType is unknown lets assume zips + int bytesDecompressed = 0; + ZipEntry entry = null; + ZipInputStream input = null; + int kbytesToProcess = conn.getContentLength()/1024; + + byte[] buffer = new byte[1024]; + service.start(kbytesToProcess); + + try { + digester = MessageDigest.getInstance("MD5"); + + } catch (NoSuchAlgorithmException e1) { + e1.printStackTrace(); + } + + try{ + input = new ZipInputStream(conn.getInputStream()); + entry = input.getNextEntry(); + }catch(IOException e){ + e.printStackTrace(); + if(conn != null) conn.disconnect(); + return -1l; + } + + while(entry != null){ + if(isCancelled()) break; + + String fileName = entry.getName(); + File f = new File(rootZipDest + fileName); + bytesDecompressed += entry.getCompressedSize(); + + if(entry.isDirectory()){ + f.mkdir(); + }else{ + if(f.exists()){ + f.delete(); + } + + FileOutputStream output = null; + try { + f.createNewFile(); + output = new FileOutputStream(f); + + int count = 0; + while((count = input.read(buffer)) != -1){ + output.write(buffer, 0, count); + digester.update(buffer, 0, count); + if(System.currentTimeMillis() - lastUpdateMillis > 1000){ + lastUpdateMillis = System.currentTimeMillis(); + publishProgress(bytesDecompressed, kbytesToProcess, fileName); + } + } + output.flush(); + input.closeEntry(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + if(conn != null) conn.disconnect(); + return -1l; + } catch (IOException e) { + e.printStackTrace(); + if(conn != null) conn.disconnect(); + return -1l; + }finally{ + try { + if( output != null) output.close(); + } catch (IOException e) {} + } + } + try{ + entry = input.getNextEntry(); + }catch(IOException e){ + e.printStackTrace(); + if(conn != null) conn.disconnect(); + return -1l; + } + }//end while(entry != null) + + try { + input.close(); + } catch (IOException e) {} + }//end if contentType == "zip" + + if(conn != null) conn.disconnect(); + + if(checkMD5(digester))return 0l; + else return -1l; + } + + //TODO proper result handling + protected void onPostExecute(Long result){ + service.done(result > -1l); + } + + protected void onProgressUpdate(Object...objects){ + service.update((Integer)objects[0], (Integer)objects[1], (String)objects[2]); + } + + private boolean checkMD5(MessageDigest digester){ + if(digester != null) { + byte[] messageDigest = digester.digest(); + + try { + URL url = new URL(URL_WITHOUT_SUFFIX + URL_HASH_SUFFIX); + HttpURLConnection conn = (HttpURLConnection)url.openConnection(); + + byte[] buffer = new byte[1024];//size is large enough to hold the entire hash + BufferedInputStream bis = new BufferedInputStream(conn.getInputStream()); + int bytesRead = bis.read(buffer); + if(bytesRead > -1){ + String hash = new String(buffer, 0, bytesRead); + StringBuffer sb = new StringBuffer(); + Integer tmp = 0; + for(int i = 0; i < messageDigest.length; i++){ + tmp = 0xFF & messageDigest[i]; + if(tmp < 0xF) sb.append('0'); + sb.append(Integer.toHexString(tmp)); + } + sb.append('\n');//add newline to become identical with the hash file + + return hash.equals(sb.toString()); + } + return false; + } catch (IOException e) { + e.printStackTrace(); + return false; + } + }else{ + return false; + } + + } + +} diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadService.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadService.java Thu Oct 20 22:54:34 2011 +0200 @@ -0,0 +1,199 @@ +/* + * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game + * Copyright (c) 2011 Richard Deurwaarder + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +package org.hedgewars.hedgeroid.Downloader; + +import java.util.ArrayList; + +import org.hedgewars.hedgeroid.MainActivity; +import org.hedgewars.hedgeroid.Utils; +import org.hedgewars.mobile.R; + +import android.app.Notification; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.app.Service; +import android.content.Intent; +import android.os.Handler; +import android.os.IBinder; +import android.os.Message; +import android.os.Messenger; +import android.os.RemoteException; +import android.preference.PreferenceManager; +import android.util.Log; +import android.widget.RemoteViews; + +public class DownloadService extends Service { + + public static final String PREF_DOWNLOADED = "downloaded"; + public static final int MSG_CANCEL = 0; + public static final int MSG_REGISTER_CLIENT = 1; + public static final int MSG_UNREGISTER_CLIENT = 2; + + public static final int NOTIFICATION_PROCESSING = 0; + public static final int NOTIFICATION_DONE = 1; + + private DownloadAsyncTask downloadTask; + private final Messenger messenger = new Messenger(new DownloadHandler()); + private NotificationManager nM; + private RemoteViews contentView; + private Notification notification; + + private ArrayList clientList = new ArrayList(); + private Message onRegisterMessage = null; + + + class DownloadHandler extends Handler{ + + public void handleMessage(Message msg){ + switch(msg.what){ + case MSG_CANCEL: + downloadTask.cancel(false); + break; + case MSG_REGISTER_CLIENT: + clientList.add(msg.replyTo); + if(onRegisterMessage != null){ + try { + msg.replyTo.send(Message.obtain(onRegisterMessage)); + } catch (RemoteException e) { + e.printStackTrace(); + } + } + break; + case MSG_UNREGISTER_CLIENT: + clientList.remove(msg.replyTo); + break; + } + } + } + + public final static int TASKID_START = 0; + public final static int TASKID_CANCEL = 1; + public final static int TASKID_RETRY = 2; + + public int onStartCommand(Intent intent, int flags, int startId){ + switch(intent.getIntExtra("taskID", TASKID_START)){ + case TASKID_RETRY: + if(downloadTask != null){ + downloadTask.cancel(false); + downloadTask = null; + } + case TASKID_START: + nM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); + + notification = new Notification(R.drawable.statusbar, getString(R.string.notification_title), System.currentTimeMillis()); + //notification.flags |= Notification.FLAG_ONGOING_EVENT;// | Notification.FLAG_NO_CLEAR | Notification.FLAG_FOREGROUND_SERVICE; + notification.flags |= Notification.FLAG_ONGOING_EVENT; + + contentView = new RemoteViews(getPackageName(), R.layout.notification); + contentView.setProgressBar(R.id.notification_progress, 100, 34, false); + notification.contentView = contentView; + + PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, DownloadActivity.class), Intent.FLAG_ACTIVITY_NEW_TASK); + notification.contentIntent = contentIntent; + + //nM.notify(NOTIFICATION_PROCESSING, notification); + startForeground(NOTIFICATION_PROCESSING, notification); + + if(downloadTask == null){ + downloadTask = new DownloadAsyncTask(this); + downloadTask.execute(Utils.getDownloadPath(this)); + } + break; + case TASKID_CANCEL: + downloadTask.cancel(false); + stopService(); + break; + } + return 0; + } + + public void onDestroy(){ + Log.e("bla", "onDestroy"); + downloadTask.cancel(false); + } + + public IBinder onBind(Intent intent) { + return messenger.getBinder(); + } + + /* + * Thread safe method to let clients know the processing is starting and will process int max kbytes + */ + public void start(int max){ + onRegisterMessage = Message.obtain(null, DownloadActivity.MSG_START, max, -1); + sendMessageToClients(onRegisterMessage); + } + + /* + * periodically gets called by the ASyncTask, we can't tell for sure when it's called + */ + public void update(int progress, int max, String fileName){ + progress = (progress/1024); + updateNotification(progress, max, fileName); + + sendMessageToClients(Message.obtain(null, DownloadActivity.MSG_UPDATE, progress, max, fileName)); + } + + /* + * Call back from the ASync task when the task has either run into an error or finished otherwise + */ + public void done(boolean succesful){ + if(succesful){ + PreferenceManager.getDefaultSharedPreferences(this).edit().putBoolean(DownloadService.PREF_DOWNLOADED, true).commit(); + sendMessageToClients(Message.obtain(null, DownloadActivity.MSG_DONE)); + }else sendMessageToClients(Message.obtain(null, DownloadActivity.MSG_FAILED)); + stopService();//stopService clears all notifications and thus must be called before we show the ready notification + showDoneNotification(); + } + + private void stopService(){ + nM.cancelAll(); + stopForeground(true); + stopSelf(); + } + + private void updateNotification(int progress, int max, String fileName){ + + contentView.setProgressBar(R.id.notification_progress, max, progress, false); + contentView.setTextViewText(R.id.progressbar_sub, String.format("%dkb/%dkb (Compressed sizes)", progress, max)); + nM.notify(NOTIFICATION_PROCESSING, notification); + } + + private void showDoneNotification(){ + nM.cancelAll(); + stopForeground(true); + + String title = getString(R.string.notification_title); + + notification = new Notification(R.drawable.icon, title, System.currentTimeMillis()); + notification.flags |= Notification.FLAG_AUTO_CANCEL; + PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), Intent.FLAG_ACTIVITY_NEW_TASK); + notification.setLatestEventInfo(this, title, getString(R.string.notification_done), contentIntent); + nM.notify(NOTIFICATION_DONE, notification); + } + private void sendMessageToClients(Message msg){ + for(Messenger m : clientList){ + try { + m.send(Message.obtain(msg)); + } catch (RemoteException e) {}//TODO should we catch this properly? + } + } + +} diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/EngineProtocolNetwork.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/EngineProtocolNetwork.java Thu Oct 20 22:54:34 2011 +0200 @@ -0,0 +1,159 @@ +/* + * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game + * Copyright (c) 2011 Richard Deurwaarder + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +package org.hedgewars.hedgeroid.EngineProtocol; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.UnknownHostException; + +public class EngineProtocolNetwork extends Thread{ + + public static final String GAMEMODE_LOCAL = "TL"; + public static final String GAMEMODE_DEMO = "TD"; + public static final String GAMEMODE_NET = "TN"; + public static final String GAMEMODE_SAVE = "TS"; + + public static final int BUFFER_SIZE = 255; //From iOS code which got it from the origional frontend + + public static final int MODE_GENLANDPREVIEW = 0; + public static final int MODE_GAME = 1; + + private ServerSocket serverSocket; + private InputStream input; + private OutputStream output; + public int port; + private final GameConfig config; + private boolean clientQuit = false; + + public EngineProtocolNetwork(GameConfig _config){ + config = _config; + try { + serverSocket = new ServerSocket(0); + port = serverSocket.getLocalPort(); + Thread ipcThread = new Thread(this, "IPC - Thread"); + ipcThread.start(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void run(){ + //if(mode == MODE_GENLANDPREVIEW) genLandPreviewIPC(); + /*else if (mode == MODE_GAME)*/ gameIPC(); + } + + private void gameIPC(){ + Socket sock = null; + try{ + sock = serverSocket.accept(); + input = sock.getInputStream(); + output = sock.getOutputStream(); + + int msgSize = 0; + byte[] buffer = new byte[BUFFER_SIZE]; + + while(!clientQuit){ + msgSize = 0; + + input.read(buffer, 0, 1); + msgSize = buffer[0]; + + input.read(buffer, 0, msgSize); + System.out.println("IPC" + (char)buffer[0] + " : " + new String(buffer, 1,msgSize-1, "US_ASCII")); + switch(buffer[0]){ + case 'C'://game init + config.sendToEngine(this); + break; + case '?'://ping - pong + sendToEngine("!"); + break; + case 'e'://Send protocol version + System.out.println(new String(buffer)); + break; + case 'i'://game statistics + switch(buffer[1]){ + case 'r'://winning team + break; + case 'D'://best shot + break; + case 'k'://best hedgehog + break; + case 'K'://# hogs killed + break; + case 'H'://team health graph + break; + case 'T':// local team stats + break; + case 'P'://teams ranking + break; + case 's'://self damage + break; + case 'S'://friendly fire + break; + case 'B'://turn skipped + break; + default: + } + break; + case 'E'://error - quits game + System.out.println(new String(buffer)); + return; + case 'q'://game ended remove save file + + return; + case 'Q'://game ended but not finished + + return; + } + + } + }catch(IOException e){ + e.printStackTrace(); + }finally{ + try { + if(sock != null) sock.close(); + } catch (IOException e) {} + try{ + if(serverSocket != null) serverSocket.close(); + } catch (IOException e) {} + } + } + + public void sendToEngine(String s){ + int length = s.length(); + + try { + output.write(length); + output.write(s.getBytes(), 0, length); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void quitIPC(){ + clientQuit = true; + } + +} diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/FrontendDataUtils.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/FrontendDataUtils.java Thu Oct 20 22:54:34 2011 +0200 @@ -0,0 +1,215 @@ +/* + * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game + * Copyright (c) 2011 Richard Deurwaarder + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +package org.hedgewars.hedgeroid.EngineProtocol; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; + +import org.hedgewars.hedgeroid.Utils; +import org.hedgewars.hedgeroid.EngineProtocol.Map.MapType; +import org.hedgewars.mobile.R; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; + +public class FrontendDataUtils { + + + public static ArrayList getMaps(Context c){ + File[] files = Utils.getFilesFromRelativeDir(c,"Maps"); + ArrayList ret = new ArrayList(); + + for(File f : files){ + if(Utils.hasFileWithSuffix(f, ".lua")){ + ret.add(new Map(f,MapType.TYPE_MISSION, c)); + }else{ + ret.add(new Map(f, MapType.TYPE_DEFAULT,c)); + } + } + Collections.sort(ret); + + return ret; + } + + public static String[] getGameplay(Context c){ + String[] files = Utils.getFileNamesFromRelativeDir(c, "Scripts/Multiplayer"); + int retCounter = 0; + + for(int i = 0; i < files.length; i++){ + if(files[i].endsWith(".lua")){ + files[i] = files[i].replace('_', ' ').substring(0, files[i].length()-4); //replace _ by a space and removed the last four characters (.lua) + retCounter++; + }else files[i] = null; + } + String[] ret = new String[retCounter]; + retCounter = 0; + for(String s : files){ + if(s != null) ret[retCounter++] = s; + } + Arrays.sort(ret); + + return ret; + } + + public static String[] getThemes(Context c){ + return Utils.getDirsWithFileSuffix(c, "Themes", "icon.png"); + } + + public static ArrayList getSchemes(Context c){ + return Scheme.getSchemes(c); + } + + public static ArrayList getWeapons(Context c){ + return Weapon.getWeapons(c); + } + + public static ArrayList> getGraves(Context c){ + String pathPrefix = Utils.getDownloadPath(c) + "Graphics/Graves/"; + ArrayList names = Utils.getFilesFromDirWithSuffix(c, "Graphics/Graves", ".png", true); + ArrayList> data = new ArrayList>(names.size()); + + for(String s : names){ + HashMap map = new HashMap(); + map.put("txt", s); + Bitmap b = BitmapFactory.decodeFile(pathPrefix + s + ".png");//create a full path - decode to to a bitmap + int width = b.getWidth(); + if(b.getHeight() > width){//some pictures contain more 'frames' underneath each other, if so we only use the first frame + Bitmap tmp = Bitmap.createBitmap(b, 0, 0, width, width); + b.recycle(); + b = tmp; + } + map.put("img", b); + data.add(map); + } + return data; + } + + public static ArrayList> getFlags(Context c){ + String pathPrefix = Utils.getDownloadPath(c) + "Graphics/Flags/"; + ArrayList names = Utils.getFilesFromDirWithSuffix(c, "Graphics/Flags", ".png", true); + ArrayList> data = new ArrayList>(names.size()); + + for(String s : names){ + HashMap map = new HashMap(); + map.put("txt", s); + Bitmap b = BitmapFactory.decodeFile(pathPrefix + s + ".png");//create a full path - decode to to a bitmap + map.put("img", b); + data.add(map); + } + return data; + } + + public static ArrayList getVoices(Context c){ + File[] files = Utils.getFilesFromRelativeDir(c, "Sounds/voices"); + ArrayList ret = new ArrayList(); + + for(File f : files){ + if(f.isDirectory()) ret.add(f.getName()); + } + return ret; + } + + public static ArrayList getForts(Context c){ + return Utils.getFilesFromDirWithSuffix(c, "Forts", "L.png", true); + } + public static ArrayList> getTypes(Context c){ + ArrayList> data = new ArrayList>(6); + String[] levels = {c.getString(R.string.human), c.getString(R.string.bot5), c.getString(R.string.bot4), c.getString(R.string.bot3), c.getString(R.string.bot2), c.getString(R.string.bot1)}; + int[] images = {R.drawable.human, R.drawable.bot5, R.drawable.bot4, R.drawable.bot3, R.drawable.bot2, R.drawable.bot1}; + + for(int i = 0; i < levels.length; i++){ + HashMap map = new HashMap(); + map.put("txt", levels[i]); + map.put("img", images[i]); + data.add(map); + } + + return data; + } + + public static ArrayList> getHats(Context c){ + ArrayList files = Utils.getFilesFromDirWithSuffix(c, "Graphics/Hats", ".png", true); + String pathPrefix = Utils.getDownloadPath(c) + "Graphics/Hats/"; + int size = files.size(); + ArrayList> data = new ArrayList>(size); + + HashMap hashmap; + for(String s : files){ + hashmap = new HashMap(); + hashmap.put("txt", s); + Bitmap b = BitmapFactory.decodeFile(pathPrefix + s + ".png");//create a full path - decode to to a bitmap + b = Bitmap.createBitmap(b, 0,0,b.getWidth()/2, b.getWidth()/2); + hashmap.put("img", b); + data.add(hashmap); + } + + return data; + } + + public static ArrayList> getTeams(Context c){ + ArrayList> ret = new ArrayList>(); + + File teamsDir = new File(c.getFilesDir().getAbsolutePath() + '/' + Team.DIRECTORY_TEAMS); + File[] teamFileNames = teamsDir.listFiles(); + if(teamFileNames != null){ + for(File s : teamFileNames){ + Team t = Team.getTeamFromXml(s.getAbsolutePath()); + if(t != null){ + ret.add(teamToHashMap(t)); + } + } + } + return ret; + } + + public static HashMap teamToHashMap(Team t){ + HashMap hashmap = new HashMap(); + hashmap.put("team", t); + hashmap.put("txt", t.name); + hashmap.put("color", t.color); + hashmap.put("count", t.hogCount); + switch(t.levels[0]){ + case 0: + hashmap.put("img", R.drawable.human); + break; + case 1: + hashmap.put("img", R.drawable.bot5); + break; + case 2: + hashmap.put("img", R.drawable.bot4); + break; + case 3: + hashmap.put("img", R.drawable.bot3); + break; + case 4: + hashmap.put("img", R.drawable.bot2); + break; + default: + case 5: + hashmap.put("img", R.drawable.bot1); + break; + } + return hashmap; + } +} diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/GameConfig.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/GameConfig.java Thu Oct 20 22:54:34 2011 +0200 @@ -0,0 +1,117 @@ +/* + * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game + * Copyright (c) 2011 Richard Deurwaarder + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +package org.hedgewars.hedgeroid.EngineProtocol; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.UUID; + +import android.os.Parcel; +import android.os.Parcelable; +import android.util.Log; + +public class GameConfig implements Parcelable{ + + public GameMode mode = GameMode.MODE_LOCAL; + public Map map = null; + public String theme = null; + public Scheme scheme = null; + public Weapon weapon = null; + + public String mission = null; + public String seed = null; + + public ArrayList teams = new ArrayList(); + + public GameConfig(){ + + } + + public GameConfig(Parcel in){ + readFromParcel(in); + } + + + + public void sendToEngine(EngineProtocolNetwork epn) throws IOException{ + Log.d("HW_Frontend", "Sending Gameconfig..."); + int teamCount = 4; + epn.sendToEngine("TL"); //Write game mode + if(mission != null) epn.sendToEngine(mission); + + //seed info + epn.sendToEngine(String.format("eseed {%s}", UUID.randomUUID().toString())); + + map.sendToEngine(epn); + //dimensions of the map + //templatefilter_command + //mapgen_command + //mazesize_command + + epn.sendToEngine(String.format("etheme %s", theme)); + + scheme.sendToEngine(epn); + + weapon.sendToEngine(epn, teamCount); + + for(Team t : teams){ + if(t != null)t.sendToEngine(epn, teamCount, 50); + } + } + + public int describeContents() { + return 0; + } + + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(mode.name()); + dest.writeParcelable(map, flags); + dest.writeString(theme); + dest.writeParcelable(scheme, flags); + dest.writeParcelable(weapon, flags); + dest.writeString(mission); + dest.writeString(seed); + dest.writeParcelableArray((Team[])teams.toArray(new Team[1]), 0); + } + + private void readFromParcel(Parcel src){ + mode = GameMode.valueOf(src.readString()); + map = src.readParcelable(Map.class.getClassLoader()); + theme = src.readString(); + scheme = src.readParcelable(Scheme.class.getClassLoader()); + weapon = src.readParcelable(Weapon.class.getClassLoader()); + mission = src.readString(); + seed = src.readString(); + Parcelable[] parcelables = src.readParcelableArray(Team[].class.getClassLoader()); + for(Parcelable team : parcelables){ + teams.add((Team)team); + } + + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + public GameConfig createFromParcel(Parcel source) { + return new GameConfig(source); + } + public GameConfig[] newArray(int size) { + return new GameConfig[size]; + } + }; + +} diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/GameMode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/GameMode.java Thu Oct 20 22:54:34 2011 +0200 @@ -0,0 +1,24 @@ +/* + * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game + * Copyright (c) 2011 Richard Deurwaarder + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +package org.hedgewars.hedgeroid.EngineProtocol; + +public enum GameMode { + MODE_LOCAL, MODE_DEMO, MODE_NET, MODE_SAVE +} diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/Grave.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/Grave.java Thu Oct 20 22:54:34 2011 +0200 @@ -0,0 +1,36 @@ +/* + * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game + * Copyright (c) 2011 Richard Deurwaarder + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +package org.hedgewars.hedgeroid.EngineProtocol; + +public class Grave{ + + public final String name; + public final String path; + + public Grave(String _name, String _path) { + name = _name; + path = _path; + } + + public String toString(){ + return name; + } + +} diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/Map.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/Map.java Thu Oct 20 22:54:34 2011 +0200 @@ -0,0 +1,160 @@ +/* + * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game + * Copyright (c) 2011 Richard Deurwaarder + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +package org.hedgewars.hedgeroid.EngineProtocol; + +import java.io.File; +import java.io.IOException; + +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.os.Parcel; +import android.os.Parcelable; + +public class Map implements Comparable, Parcelable{ + + private static final String MISSION_PREFIX = "Mission: "; + + private String name; + private String path; + private String previewPath; + private MapType type; + + public Map(File mapDir, MapType _type, Context c){ + type = _type; + + name = mapDir.getName(); + path = mapDir.getAbsolutePath(); + previewPath = path + "/preview.png"; + + /*switch(type){ + case TYPE_DEFAULT: + + break; + case TYPE_GENERATED: + //TODO + break; + case TYPE_MISSION: + name = MISSION_PREFIX + mapDir.getName(); + path = mapDir.getAbsolutePath(); + break; + }*/ + + + } + + public Map(Parcel in){ + readFromParcel(in); + } + + public String toString(){ + switch(type){ + default: + case TYPE_DEFAULT: + return name; + case TYPE_GENERATED: + return "bla"; + case TYPE_MISSION: + return MISSION_PREFIX + name; + } + } + + public void sendToEngine(EngineProtocolNetwork epn) throws IOException{ + epn.sendToEngine(String.format("emap %s",name)); + } + + public MapType getType(){ + return type; + } + + public Drawable getDrawable(){ + switch(type){ + case TYPE_MISSION: + case TYPE_DEFAULT: + return Drawable.createFromPath(previewPath); + case TYPE_GENERATED: + + default: + return null; + } + } + + public int compareTo(Map another) { + switch(type){ + case TYPE_GENERATED: + switch(another.getType()){ + case TYPE_GENERATED: + return name.compareTo(another.name); + case TYPE_MISSION: + return -1; + case TYPE_DEFAULT: + return -1; + } + case TYPE_MISSION: + switch(another.getType()){ + case TYPE_GENERATED: + return 1; + case TYPE_MISSION: + return name.compareTo(another.name); + case TYPE_DEFAULT: + return -1; + } + case TYPE_DEFAULT: + switch(another.getType()){ + case TYPE_GENERATED: + return 1; + case TYPE_MISSION: + return 1; + case TYPE_DEFAULT: + return name.compareTo(another.name); + } + } + return 0;//default case this should never happen + } + + public enum MapType{ + TYPE_DEFAULT, TYPE_MISSION, TYPE_GENERATED + } + + public int describeContents() { + return 0; + } + + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(name); + dest.writeString(path); + dest.writeString(previewPath); + dest.writeString(type.name()); + } + + private void readFromParcel(Parcel src){ + name = src.readString(); + path = src.readString(); + previewPath = src.readString(); + type = MapType.valueOf(src.readString()); + } + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + public Map createFromParcel(Parcel source) { + return new Map(source); + } + public Map[] newArray(int size) { + return new Map[size]; + } + + }; +} diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/PascalExports.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/PascalExports.java Thu Oct 20 22:54:34 2011 +0200 @@ -0,0 +1,40 @@ +/* + * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game + * Copyright (c) 2011 Richard Deurwaarder + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +package org.hedgewars.hedgeroid.EngineProtocol; + +public class PascalExports { + + static{ + System.loadLibrary("SDL"); + System.loadLibrary("SDL_image"); + System.loadLibrary("mikmod"); + System.loadLibrary("SDL_net"); + System.loadLibrary("SDL_mixer"); + System.loadLibrary("SDL_ttf"); + System.loadLibrary("lua5.1"); + System.loadLibrary("hwengine"); + } + + public static native int HWversionInfoNetProto(); + public static native String HWversionInfoVersion(); + public static native int HWgetNumberOfWeapons(); + public static native int HWgetMaxNumberOfTeams(); + public static native int HWgetMaxNumberOfHogs(); + public static native int HWterminate(boolean b); +} diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/Scheme.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/Scheme.java Thu Oct 20 22:54:34 2011 +0200 @@ -0,0 +1,358 @@ +/* + * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game + * Copyright (c) 2011 Richard Deurwaarder + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +package org.hedgewars.hedgeroid.EngineProtocol; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.FilenameFilter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedHashMap; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlPullParserFactory; + +import android.content.Context; +import android.os.Parcel; +import android.os.Parcelable; + +public class Scheme implements Parcelable{ + + public static final String DIRECTORY_SCHEME = "schemes"; + + private String name; + //private ArrayList basic; + private Integer gamemod; + private ArrayList basic;; + private static ArrayList> basicflags = new ArrayList>(); + + public Scheme(String _name, ArrayList _basic, int _gamemod){ + name = _name; + gamemod = _gamemod; + basic = _basic; + + } + + public Scheme(Parcel in){ + readFromParcel(in); + } + + public void sendToEngine(EngineProtocolNetwork epn)throws IOException{ + epn.sendToEngine(String.format("e$gmflags %d", gamemod)); + + for(int pos = 0; pos < basic.size(); pos++){ + LinkedHashMap basicflag = basicflags.get(pos); + + String command = (String)basicflag.get("command"); + Integer value = basic.get(pos); + Boolean checkOverMax = (Boolean) basicflag.get("checkOverMax"); + Boolean times1000 = (Boolean) basicflag.get("times1000"); + Integer max = (Integer) basicflag.get("max"); + + if(checkOverMax && value >= max) value = max; + if(times1000) value *= 1000; + + epn.sendToEngine(String.format("%s %d", command, value)); + } + } + public String toString(){ + return name; + } + + + public static final int STATE_START = 0; + public static final int STATE_ROOT = 1; + public static final int STATE_NAME = 2; + public static final int STATE_BASICFLAGS = 3; + public static final int STATE_GAMEMOD = 4; + public static final int STATE_BASICFLAG_INTEGER = 5; + public static final int STATE_GAMEMOD_TRUE = 6; + public static final int STATE_GAMEMOD_FALSE = 7; + + public static ArrayList getSchemes(Context c) throws IllegalArgumentException{ + String dir = c.getFilesDir().getAbsolutePath() + '/' + DIRECTORY_SCHEME + '/'; + String[] files = new File(dir).list(fnf); + if(files == null) files = new String[]{}; + Arrays.sort(files); + ArrayList schemes = new ArrayList(); + + try { + XmlPullParserFactory xmlPullFactory = XmlPullParserFactory.newInstance(); + XmlPullParser xmlPuller = xmlPullFactory.newPullParser(); + + for(String file : files){ + BufferedReader br = new BufferedReader(new FileReader(dir + file), 1024); + xmlPuller.setInput(br); + String name = null; + ArrayList basic = new ArrayList(); + Integer gamemod = 0; + int mask = 0x000000004; + + int eventType = xmlPuller.getEventType(); + int state = STATE_START; + while(eventType != XmlPullParser.END_DOCUMENT){ + switch(state){ + case STATE_START: + if(eventType == XmlPullParser.START_TAG && xmlPuller.getName().equals("scheme")) state = STATE_ROOT; + else if(eventType != XmlPullParser.START_DOCUMENT) throwException(file, eventType); + break; + case STATE_ROOT: + if(eventType == XmlPullParser.START_TAG){ + if(xmlPuller.getName().equals("basicflags")) state = STATE_BASICFLAGS; + else if(xmlPuller.getName().toLowerCase().equals("gamemod")) state = STATE_GAMEMOD; + else if(xmlPuller.getName().toLowerCase().equals("name")) state = STATE_NAME; + else throwException(file, eventType); + }else if(eventType == XmlPullParser.END_TAG) state = STATE_START; + else throwException(xmlPuller.getText(), eventType); + break; + case STATE_BASICFLAGS: + if(eventType == XmlPullParser.START_TAG && xmlPuller.getName().toLowerCase().equals("integer")) state = STATE_BASICFLAG_INTEGER; + else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT; + else throwException(file, eventType); + break; + case STATE_GAMEMOD: + if(eventType == XmlPullParser.START_TAG){ + if(xmlPuller.getName().toLowerCase().equals("true")) state = STATE_GAMEMOD_TRUE; + else if(xmlPuller.getName().toLowerCase().equals("false")) state = STATE_GAMEMOD_FALSE; + else throwException(file, eventType); + }else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT; + else throwException(file, eventType); + break; + case STATE_NAME: + if(eventType == XmlPullParser.TEXT) name = xmlPuller.getText().trim(); + else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT; + else throwException(file, eventType); + break; + case STATE_BASICFLAG_INTEGER: + if(eventType == XmlPullParser.TEXT) basic.add(Integer.parseInt(xmlPuller.getText().trim())); + else if(eventType == XmlPullParser.END_TAG) state = STATE_BASICFLAGS; + else throwException(file, eventType); + break; + case STATE_GAMEMOD_FALSE: + if(eventType == XmlPullParser.TEXT) gamemod <<= 1; + else if(eventType == XmlPullParser.END_TAG) state = STATE_GAMEMOD; + else throwException(file, eventType); + break; + case STATE_GAMEMOD_TRUE: + if(eventType == XmlPullParser.TEXT){ + gamemod |= mask; + gamemod <<= 1; + }else if(eventType == XmlPullParser.END_TAG) state = STATE_GAMEMOD; + else throwException(file, eventType); + break; + } + eventType = getEventType(xmlPuller); + }//end while(eventtype != END_DOCUMENT + schemes.add(new Scheme(name, basic, gamemod)); + }//end for(string file : files + return schemes; + } catch (XmlPullParserException e) { + e.printStackTrace(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return new ArrayList();//TODO handle correctly + } + + private static FilenameFilter fnf = new FilenameFilter(){ + public boolean accept(File dir, String filename) { + return filename.toLowerCase().startsWith("scheme_"); + } + }; + + /** + * This method will parse the basic flags from a prespecified xml file. + * I use a raw xml file rather than one parsed by aatp at compile time + * to keep it generic with other frontends, ie in the future we could + * use one provided by the Data folder. + */ + public static void parseBasicFlags(Context c){ + String filename = String.format("%s/%s/basicflags", c.getFilesDir().getAbsolutePath(), DIRECTORY_SCHEME); + + XmlPullParser xmlPuller = null; + BufferedReader br = null; + try { + XmlPullParserFactory xmlPullFactory = XmlPullParserFactory.newInstance(); + xmlPuller = xmlPullFactory.newPullParser(); + br = new BufferedReader(new FileReader(filename), 1024); + xmlPuller.setInput(br); + + int eventType = getEventType(xmlPuller); + boolean continueParsing = true; + do{ + switch(eventType){ + + case XmlPullParser.START_TAG: + if(xmlPuller.getName().toLowerCase().equals("flag")){ + basicflags.add(parseFlag(xmlPuller)); + }else if(xmlPuller.getName().toLowerCase().equals("basicflags")){ + eventType = getEventType(xmlPuller); + }else{ + skipCurrentTag(xmlPuller); + eventType = getEventType(xmlPuller); + } + break; + case XmlPullParser.START_DOCUMENT://ignore all tags not being "flag" + case XmlPullParser.END_TAG: + case XmlPullParser.TEXT: + default: + continueParsing = true; + case XmlPullParser.END_DOCUMENT: + continueParsing = false; + } + }while(continueParsing); + + }catch(IOException e){ + e.printStackTrace(); + }catch (XmlPullParserException e) { + e.printStackTrace(); + }finally{ + if(br != null) + try { + br.close(); + } catch (IOException e) {} + } + + } + + /* + * * Parses a Tag structure from xml as example we use + * + * + * false + * + * + * + * It returns a LinkedHashMap with key/value pairs + */ + private static LinkedHashMap parseFlag(XmlPullParser xmlPuller)throws XmlPullParserException, IOException{ + LinkedHashMap hash = new LinkedHashMap(); + + int eventType = xmlPuller.getEventType();//Get the event type which triggered this method + if(eventType == XmlPullParser.START_TAG && xmlPuller.getName().toLowerCase().equals("flag")){//valid start of flag tag + String lcKey = null; + String lcType = null; + String value = null; + + eventType = getEventType(xmlPuller);// + while(eventType == XmlPullParser.START_TAG){ + lcKey = xmlPuller.getName();//checkOverMax + if(getEventType(xmlPuller) == XmlPullParser.START_TAG){// + lcType = xmlPuller.getName().toLowerCase(); + if(getEventType(xmlPuller) == XmlPullParser.TEXT){ + value = xmlPuller.getText(); + if(getEventType(xmlPuller) == XmlPullParser.END_TAG && // + getEventType(xmlPuller) == XmlPullParser.END_TAG){// + if(lcType.equals("boolean")) hash.put(lcKey, new Boolean(value)); + else if(lcType.equals("string"))hash.put(lcKey, value); + else if(lcType.equals("integer")){ + try{ + hash.put(lcKey, new Integer(value)); + }catch (NumberFormatException e){ + throw new XmlPullParserException("Wrong integer value in xml file"); + } + }else{ + throwException("basicflags", eventType); + } + }// / + }//if TEXT + }//if boolean + eventType = getEventType(xmlPuller);//start new loop + } + eventType = getEventType(xmlPuller);// + } + + return hash; + } + + private static void skipCurrentTag(XmlPullParser xmlPuller) throws XmlPullParserException, IOException{ + int eventType = xmlPuller.getEventType(); + if(eventType != XmlPullParser.START_TAG)return; + String tag = xmlPuller.getName().toLowerCase(); + + while(true){ + eventType = getEventType(xmlPuller);//getNext() + switch(eventType){ + case XmlPullParser.START_DOCUMENT://we're inside of a start tag so START_ or END_DOCUMENT is just wrong + case XmlPullParser.END_DOCUMENT: + throw new XmlPullParserException("invalid xml file"); + case XmlPullParser.START_TAG://if we get a new tag recursively handle it + skipCurrentTag(xmlPuller); + break; + case XmlPullParser.TEXT: + break; + case XmlPullParser.END_TAG: + if(!xmlPuller.getName().toLowerCase().equals(tag)){//if the end tag doesn't match the start tag + throw new XmlPullParserException("invalid xml file"); + }else{ + return;//skip completed + } + + } + } + } + + /** + * Skips whitespaces.. + */ + private static int getEventType(XmlPullParser xmlPuller)throws XmlPullParserException, IOException{ + int eventType = xmlPuller.next(); + while(eventType == XmlPullParser.TEXT && xmlPuller.isWhitespace()){ + eventType = xmlPuller.next(); + } + return eventType; + } + private static void throwException(String file, int eventType){ + throw new IllegalArgumentException(String.format("Xml file: %s malformed with error: %d.", file, eventType)); + } + + public int describeContents() { + // TODO Auto-generated method stub + return 0; + } + + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(name); + dest.writeInt(gamemod); + dest.writeList(basic); + + } + + public void readFromParcel(Parcel src){ + name = src.readString(); + gamemod = src.readInt(); + basic = src.readArrayList(ArrayList.class.getClassLoader()); + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + public Scheme createFromParcel(Parcel source) { + return new Scheme(source); + } + public Scheme[] newArray(int size) { + return new Scheme[size]; + } + + }; +} diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/Team.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/Team.java Thu Oct 20 22:54:34 2011 +0200 @@ -0,0 +1,345 @@ +/* + * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game + * Copyright (c) 2011 Richard Deurwaarder + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +package org.hedgewars.hedgeroid.EngineProtocol; + +import java.io.BufferedReader; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlPullParserFactory; +import org.xmlpull.v1.XmlSerializer; + +import android.os.Parcel; +import android.os.Parcelable; +import android.util.Xml; + +public class Team implements Parcelable{ + + public static final String DIRECTORY_TEAMS = "teams"; + private static final Integer[] TEAM_COLORS = { + 0xd12b42, /* red */ + 0x4980c1, /* blue */ + 0x6ab530, /* green */ + 0xbc64c4, /* purple */ + 0xe76d14, /* orange */ + 0x3fb6e6, /* cyan */ + 0xe3e90c, /* yellow */ + 0x61d4ac, /* mint */ + 0xf1c3e1, /* pink */ + /* add new colors here */ + }; + +// private static final Integer[] TEAM_COLORS = { +// 0xff0000, /* red */ +// 0x00ff00, /* blue */ +// 0x0000ff, /* green */ +// }; + + private static final int STATE_START = 0; + private static final int STATE_ROOT = 1; + private static final int STATE_HOG_ROOT = 2; + + public String name, grave, flag, voice, fort, hash; + + public static int maxNumberOfHogs = 0; + public static int maxNumberOfTeams = 0; + + static{ + maxNumberOfHogs = PascalExports.HWgetMaxNumberOfHogs(); + maxNumberOfTeams = PascalExports.HWgetMaxNumberOfTeams(); + } + public String[] hats = new String[maxNumberOfHogs]; + public String[] hogNames = new String[maxNumberOfHogs]; + public int[] levels = new int[maxNumberOfHogs]; + + public int hogCount = 4; + public int color = TEAM_COLORS[0]; + + public Team(){ + } + + public Team(Parcel in){ + readFromParcel(in); + } + + public boolean equals(Object o){ + if(super.equals(o)) return true; + else if(o instanceof Team){ + Team t = (Team)o; + boolean ret = name.equals(t.name); + ret &= grave.equals(t.grave); + ret &= flag.equals(t.flag); + ret &= voice.equals(t.voice); + ret &= fort.equals(t.fort); + ret &= hash.equals(t.hash); + return ret; + }else{ + return false; + } + } + + public void setRandomColor(int[] illegalcolors){ + Integer[] colorsToPickFrom = TEAM_COLORS; + if(illegalcolors != null){ + ArrayList colors = new ArrayList(); + for(int color : TEAM_COLORS){ + boolean validColor = true; + for(int illegal : illegalcolors){ + if(color == illegal) validColor = false; + } + if(validColor) colors.add(color); + } + if(colors.size() != 0) colorsToPickFrom = colors.toArray(new Integer[1]); + } + int index = (int)Math.round(Math.random()*(colorsToPickFrom.length-1)); + color = colorsToPickFrom[index]; + } + + + public void sendToEngine(EngineProtocolNetwork epn, int hogCount, int health) throws IOException{ + epn.sendToEngine(String.format("eaddteam %s %d %s", hash, color, name)); + epn.sendToEngine(String.format("egrave %s", grave)); + epn.sendToEngine(String.format("efort %s", fort)); + epn.sendToEngine(String.format("evoicepack %s", voice)); + epn.sendToEngine(String.format("eflag %s", flag)); + + for(int i = 0; i < hogCount; i++){ + epn.sendToEngine(String.format("eaddhh %d %d %s", levels[i], health, hogNames[i])); + epn.sendToEngine(String.format("ehat %s", hats[i])); + } + } + + /* + * XML METHODS + */ + + /** + * Read the xml file path and convert it to a Team object + * @param path absolute path to the xml file + * @return + */ + public static Team getTeamFromXml(String path){ + try { + XmlPullParserFactory xmlPullFactory = XmlPullParserFactory.newInstance(); + XmlPullParser xmlPuller = xmlPullFactory.newPullParser(); + + BufferedReader br = new BufferedReader(new FileReader(path), 1024); + xmlPuller.setInput(br); + Team team = new Team(); + int hogCounter = 0; + + int eventType = xmlPuller.getEventType(); + int state = STATE_START; + while(eventType != XmlPullParser.END_DOCUMENT){ + switch(state){ + case STATE_START: + if(eventType == XmlPullParser.START_TAG && xmlPuller.getName().equals("team")) state = STATE_ROOT; + else if(eventType != XmlPullParser.START_DOCUMENT) throwException(path, eventType); + break; + case STATE_ROOT: + if(eventType == XmlPullParser.START_TAG){ + if(xmlPuller.getName().toLowerCase().equals("name")){ + team.name = getXmlText(xmlPuller, "name"); + }else if(xmlPuller.getName().toLowerCase().equals("flag")){ + team.flag= getXmlText(xmlPuller, "flag"); + }else if(xmlPuller.getName().toLowerCase().equals("voice")){ + team.voice = getXmlText(xmlPuller, "voice"); + }else if(xmlPuller.getName().toLowerCase().equals("grave")){ + team.grave = getXmlText(xmlPuller, "grave"); + }else if(xmlPuller.getName().toLowerCase().equals("fort")){ + team.fort = getXmlText(xmlPuller, "fort"); + }else if(xmlPuller.getName().toLowerCase().equals("hash")){ + team.hash = getXmlText(xmlPuller, "hash"); + }else if(xmlPuller.getName().toLowerCase().equals("hog")){ + state = STATE_HOG_ROOT; + }else throwException(xmlPuller.getName(), eventType); + }else if(eventType == XmlPullParser.END_TAG) state = STATE_START; + else throwException(xmlPuller.getText(), eventType); + break; + case STATE_HOG_ROOT: + if(eventType == XmlPullParser.START_TAG){ + if(xmlPuller.getName().toLowerCase().equals("name")){ + team.hogNames[hogCounter] = getXmlText(xmlPuller, "name"); + }else if(xmlPuller.getName().toLowerCase().equals("hat")){ + team.hats[hogCounter] = getXmlText(xmlPuller, "hat"); + }else if(xmlPuller.getName().toLowerCase().equals("level")){ + team.levels[hogCounter] = Integer.parseInt(getXmlText(xmlPuller, "level")); + }else throwException(xmlPuller.getText(), eventType); + }else if(eventType == XmlPullParser.END_TAG){ + hogCounter++; + state = STATE_ROOT; + }else throwException(xmlPuller.getText(), eventType); + break; + } + eventType = getEventType(xmlPuller); + }//end while(eventtype != END_DOCUMENT + return team; + } catch (NumberFormatException e){ + e.printStackTrace(); + } catch (XmlPullParserException e) { + e.printStackTrace(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + private static String getXmlText(XmlPullParser xmlPuller, String parentTag)throws XmlPullParserException, IOException{ + if(getEventType(xmlPuller) == XmlPullParser.TEXT){ + String txt = xmlPuller.getText(); + if(getEventType(xmlPuller) == XmlPullParser.END_TAG && xmlPuller.getName().toLowerCase().equals(parentTag)){ + return txt; + } + } + throw new XmlPullParserException("malformed xml file on string read from tag: " + parentTag); + } + + /** + * Skips whitespaces.. + */ + private static int getEventType(XmlPullParser xmlPuller)throws XmlPullParserException, IOException{ + int eventType = xmlPuller.next(); + while(eventType == XmlPullParser.TEXT && xmlPuller.isWhitespace()){ + eventType = xmlPuller.next(); + } + return eventType; + } + + private static void throwException(String file, int eventType){ + throw new IllegalArgumentException(String.format("Xml file: %s malformed with error: %d.", file, eventType)); + } + + public void writeToXml(OutputStream os){ + XmlSerializer serializer = Xml.newSerializer(); + try{ + serializer.setOutput(os, "UTF-8"); + serializer.startDocument("UTF-8", true); + serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); + + serializer.startTag(null, "team"); + serializer.startTag(null, "name"); + serializer.text(name); + serializer.endTag(null, "name"); + serializer.startTag(null, "flag"); + serializer.text(flag); + serializer.endTag(null, "flag"); + serializer.startTag(null, "fort"); + serializer.text(fort); + serializer.endTag(null, "fort"); + serializer.startTag(null, "grave"); + serializer.text(grave); + serializer.endTag(null, "grave"); + serializer.startTag(null, "voice"); + serializer.text(voice); + serializer.endTag(null, "voice"); + serializer.startTag(null, "hash"); + serializer.text(hash); + serializer.endTag(null, "hash"); + + for(int i = 0; i < maxNumberOfHogs; i++){ + serializer.startTag(null, "hog"); + serializer.startTag(null, "name"); + serializer.text(hogNames[i]); + serializer.endTag(null, "name"); + serializer.startTag(null, "hat"); + serializer.text(hats[i]); + serializer.endTag(null, "hat"); + serializer.startTag(null, "level"); + serializer.text(String.valueOf(levels[i])); + serializer.endTag(null, "level"); + + serializer.endTag(null, "hog"); + } + serializer.endTag(null, "team"); + serializer.endDocument(); + serializer.flush(); + + } catch (IOException e) { + e.printStackTrace(); + }finally{ + try { + os.close(); + } catch (IOException e) {} + } + } + /* + * END XML METHODS + */ + + + + /* + * PARCABLE METHODS + */ + + public int describeContents() { + return 0; + } + + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(name); + dest.writeString(grave); + dest.writeString(flag); + dest.writeString(voice); + dest.writeString(fort); + dest.writeString(hash); + dest.writeStringArray(hats); + dest.writeStringArray(hogNames); + dest.writeIntArray(levels); + dest.writeInt(color); + dest.writeInt(hogCount); + } + + + public void readFromParcel(Parcel src){ + name = src.readString(); + grave = src.readString(); + flag = src.readString(); + voice = src.readString(); + fort = src.readString(); + hash = src.readString(); + src.readStringArray(hats); + src.readStringArray(hogNames); + src.readIntArray(levels); + color = src.readInt(); + hogCount = src.readInt(); + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + public Team createFromParcel(Parcel source) { + return new Team(source); + } + public Team[] newArray(int size) { + return new Team[size]; + } + + }; + + /* + * END PARCABLE METHODS + */ + +} diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/Weapon.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/Weapon.java Thu Oct 20 22:54:34 2011 +0200 @@ -0,0 +1,212 @@ +/* + * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game + * Copyright (c) 2011 Richard Deurwaarder + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +package org.hedgewars.hedgeroid.EngineProtocol; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlPullParserFactory; + +import android.content.Context; +import android.os.Parcel; +import android.os.Parcelable; + +public class Weapon implements Parcelable{ + + public static final String DIRECTORY_WEAPON = "weapons"; + + private String name; + private String QT; + private String prob; + private String delay; + private String crate; + private static int maxWeapons; + + static{ + //maxWeapons = PascalExports.HWgetNumberOfWeapons(); + } + + public Weapon(String _name, String _QT, String _prob, String _delay, String _crate){ + name = _name; + + //Incase there's a newer ammoStore which is bigger we append with zeros + StringBuffer sb = new StringBuffer(); + while(_QT.length() + sb.length() < maxWeapons){ + sb.append('0'); + } + + QT = String.format("e%s %s%s", "ammloadt", _QT, sb); + prob = String.format("e%s %s%s", "ammprob", _prob, sb); + delay = String.format("e%s %s%s", "ammdelay", _delay, sb); + crate = String.format("e%s %s%s", "ammreinf", _crate, sb); + } + + public Weapon(Parcel in){ + readFromParcel(in); + } + + public String toString(){ + return name; + } + + public void sendToEngine(EngineProtocolNetwork epn, int teamsCount) throws IOException{ + epn.sendToEngine(QT);//command prefix is already in string + epn.sendToEngine(prob); + epn.sendToEngine(delay); + epn.sendToEngine(crate); + + for(int i = 0; i < teamsCount; i++){ + epn.sendToEngine("eammstore"); + } + } + + public static final int STATE_START = 0; + public static final int STATE_ROOT = 1; + public static final int STATE_NAME = 2; + public static final int STATE_QT = 3; + public static final int STATE_PROBABILITY = 4; + public static final int STATE_DELAY = 5; + public static final int STATE_CRATE = 6; + + public static ArrayList getWeapons(Context c) throws IllegalArgumentException{ + String dir = c.getFilesDir().getAbsolutePath() + '/' + DIRECTORY_WEAPON + '/'; + String[] files = new File(dir).list(); + if(files == null) files = new String[]{}; + Arrays.sort(files); + + ArrayList weapons = new ArrayList(); + + try { + XmlPullParserFactory xmlPullFactory = XmlPullParserFactory.newInstance(); + XmlPullParser xmlPuller = xmlPullFactory.newPullParser(); + + for(String file : files){ + BufferedReader br = new BufferedReader(new FileReader(dir + file), 1024); + xmlPuller.setInput(br); + String name = null; + String qt = null; + String prob = null; + String delay = null; + String crate = null; + + int eventType = xmlPuller.getEventType(); + int state = STATE_START; + while(eventType != XmlPullParser.END_DOCUMENT){ + switch(state){ + case STATE_START: + if(eventType == XmlPullParser.START_TAG && xmlPuller.getName().equals("weapon")) state = STATE_ROOT; + else if(eventType != XmlPullParser.START_DOCUMENT) throwException(file, eventType); + break; + case STATE_ROOT: + if(eventType == XmlPullParser.START_TAG){ + if(xmlPuller.getName().toLowerCase().equals("qt")) state = STATE_QT; + else if(xmlPuller.getName().toLowerCase().equals("name")) state = STATE_NAME; + else if(xmlPuller.getName().toLowerCase().equals("probability")) state = STATE_PROBABILITY; + else if(xmlPuller.getName().toLowerCase().equals("delay")) state = STATE_DELAY; + else if(xmlPuller.getName().toLowerCase().equals("crate")) state = STATE_CRATE; + else throwException(file, eventType); + }else if(eventType == XmlPullParser.END_TAG) state = STATE_START; + else throwException(xmlPuller.getText(), eventType); + break; + case STATE_NAME: + if(eventType == XmlPullParser.TEXT) name = xmlPuller.getText().trim(); + else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT; + else throwException(file, eventType); + break; + case STATE_QT: + if(eventType == XmlPullParser.TEXT) qt = xmlPuller.getText().trim(); + else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT; + else throwException(file, eventType); + break; + case STATE_PROBABILITY: + if(eventType == XmlPullParser.TEXT) prob = xmlPuller.getText().trim(); + else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT; + else throwException(file, eventType); + break; + case STATE_DELAY: + if(eventType == XmlPullParser.TEXT) delay = xmlPuller.getText().trim(); + else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT; + else throwException(file, eventType); + break; + case STATE_CRATE: + if(eventType == XmlPullParser.TEXT) crate = xmlPuller.getText().trim(); + else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT; + else throwException(file, eventType); + break; + } + eventType = xmlPuller.next(); + while(eventType == XmlPullParser.TEXT && xmlPuller.isWhitespace()){//Skip whitespaces + eventType = xmlPuller.next(); + } + }//end while(eventtype != END_DOCUMENT + weapons.add(new Weapon(name, qt, prob, delay, crate)); + }//end for(string file : files + return weapons; + + } catch (XmlPullParserException e) { + e.printStackTrace(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return new ArrayList();//TODO handle correctly + } + + private static void throwException(String file, int eventType){ + throw new IllegalArgumentException(String.format("Xml file: %s malformed with eventType: %d.", file, eventType)); + } + + public int describeContents() { + return 0; + } + + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(name); + dest.writeString(QT); + dest.writeString(prob); + dest.writeString(delay); + dest.writeString(crate); + } + + private void readFromParcel(Parcel src){ + name = src.readString(); + QT = src.readString(); + prob = src.readString(); + delay = src.readString(); + crate = src.readString(); + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + public Weapon createFromParcel(Parcel source) { + return new Weapon(source); + } + public Weapon[] newArray(int size) { + return new Weapon[size]; + } + + }; +} diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/MainActivity.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/MainActivity.java Thu Oct 20 22:54:34 2011 +0200 @@ -0,0 +1,68 @@ +/* + * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game + * Copyright (c) 2011 Richard Deurwaarder + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +package org.hedgewars.hedgeroid; + +import org.hedgewars.hedgeroid.Downloader.DownloadActivity; +import org.hedgewars.hedgeroid.Downloader.DownloadService; +import org.hedgewars.mobile.R; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.Button; +import android.widget.Toast; + +public class MainActivity extends Activity { + + Button downloader, startGame; + + public void onCreate(Bundle sis){ + super.onCreate(sis); + setContentView(R.layout.main); + + downloader = (Button)findViewById(R.id.downloader); + startGame = (Button)findViewById(R.id.startGame); + + downloader.setOnClickListener(downloadClicker); + startGame.setOnClickListener(startGameClicker); + } + + + + private OnClickListener downloadClicker = new OnClickListener(){ + public void onClick(View v){ + startActivityForResult(new Intent(getApplicationContext(), DownloadActivity.class), 0); + } + }; + + private OnClickListener startGameClicker = new OnClickListener(){ + public void onClick(View v){ + if(PreferenceManager.getDefaultSharedPreferences(MainActivity.this).getBoolean(DownloadService.PREF_DOWNLOADED, false)) + startActivity(new Intent(getApplicationContext(), StartGameActivity.class)); + else { + Toast.makeText(MainActivity.this, R.string.download_userexplain, Toast.LENGTH_LONG).show(); + startActivityForResult(new Intent(getApplicationContext(), DownloadActivity.class), 0); + } + } + }; + +} diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/SDLActivity.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/SDLActivity.java Thu Oct 20 22:54:34 2011 +0200 @@ -0,0 +1,565 @@ +package org.hedgewars.hedgeroid; + +import javax.microedition.khronos.egl.EGL10; +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.egl.EGLContext; +import javax.microedition.khronos.egl.EGLDisplay; +import javax.microedition.khronos.egl.EGLSurface; + +import org.hedgewars.hedgeroid.EngineProtocol.EngineProtocolNetwork; +import org.hedgewars.hedgeroid.EngineProtocol.GameConfig; +import org.hedgewars.hedgeroid.EngineProtocol.PascalExports; +import org.hedgewars.hedgeroid.TouchInterface.TouchInterface; + +import android.app.Activity; +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.PixelFormat; +import android.hardware.Sensor; +import android.hardware.SensorEvent; +import android.hardware.SensorEventListener; +import android.hardware.SensorManager; +import android.media.AudioFormat; +import android.media.AudioManager; +import android.media.AudioTrack; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.util.Log; +import android.view.KeyEvent; +import android.view.SurfaceHolder; +import android.view.SurfaceView; +import android.view.View; + +/** + * SDL Activity + */ +public class SDLActivity extends Activity { + + // Main components + public static SDLActivity mSingleton; + public static SDLSurface mSurface; + + // Audio + private static Thread mAudioThread; + private static AudioTrack mAudioTrack; + + // Load the .so + static { + System.loadLibrary("SDL"); + System.loadLibrary("SDL_image"); + System.loadLibrary("mikmod"); + System.loadLibrary("SDL_net"); + System.loadLibrary("SDL_mixer"); + System.loadLibrary("SDL_ttf"); + System.loadLibrary("lua5.1"); + System.loadLibrary("hwengine"); + System.loadLibrary("main"); + } + + // Setup + protected void onCreate(Bundle savedInstanceState) { + // Log.v("SDL", "onCreate()"); + super.onCreate(savedInstanceState); + + // So we can call stuff from static callbacks + mSingleton = this; + + // Set up the surface + GameConfig config = getIntent().getParcelableExtra("config"); + mSurface = new SDLSurface(getApplication(), config); + setContentView(mSurface); + SurfaceHolder holder = mSurface.getHolder(); + holder.setType(SurfaceHolder.SURFACE_TYPE_GPU); + } + + // Events + protected void onPause() { + // Log.v("SDL", "onPause()"); + super.onPause(); + + } + + protected void onResume() { + // Log.v("SDL", "onResume()"); + super.onResume(); + } + + public void onBackPressed(){ + nativeQuit(); + super.onBackPressed(); + } + + // Messages from the SDLMain thread + static int COMMAND_CHANGE_TITLE = 1; + + // Handler for the messages + Handler commandHandler = new Handler() { + public void handleMessage(Message msg) { + if (msg.arg1 == COMMAND_CHANGE_TITLE) { + setTitle((String) msg.obj); + } + } + }; + + // Send a message from the SDLMain thread + void sendCommand(int command, Object data) { + Message msg = commandHandler.obtainMessage(); + msg.arg1 = command; + msg.obj = data; + commandHandler.sendMessage(msg); + } + + // C functions we call + public static native void nativeInit(String[] argv); + + public static native void nativeQuit(); + + public static native void onNativeResize(int x, int y, int format); + + public static native void onNativeKeyDown(int keycode); + + public static native void onNativeKeyUp(int keycode); + + public static native void onNativeTouch(int action, int pointer, float x, float y, + float p); + + public static native void onNativeAccel(float x, float y, float z); + + public static native void nativeRunAudioThread(); + + // Java functions called from C + + public static boolean createGLContext(int majorVersion, int minorVersion) { + return mSurface.initEGL(majorVersion, minorVersion); + } + + public static void flipBuffers() { + mSurface.flipEGL(); + } + + public static void setActivityTitle(String title) { + // Called from SDLMain() thread and can't directly affect the view + mSingleton.sendCommand(COMMAND_CHANGE_TITLE, title); + } + + // Audio + private static Object buf; + + public static Object audioInit(int sampleRate, boolean is16Bit, + boolean isStereo, int desiredFrames) { + int channelConfig = isStereo ? AudioFormat.CHANNEL_CONFIGURATION_STEREO + : AudioFormat.CHANNEL_CONFIGURATION_MONO; + int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT + : AudioFormat.ENCODING_PCM_8BIT; + int frameSize = (isStereo ? 2 : 1) * (is16Bit ? 2 : 1); + + Log.v("SDL", "SDL audio: wanted " + (isStereo ? "stereo" : "mono") + + " " + (is16Bit ? "16-bit" : "8-bit") + " " + + ((float) sampleRate / 1000f) + "kHz, " + desiredFrames + + " frames buffer"); + + // Let the user pick a larger buffer if they really want -- but ye + // gods they probably shouldn't, the minimums are horrifyingly high + // latency already + desiredFrames = Math.max( + desiredFrames, + (AudioTrack.getMinBufferSize(sampleRate, channelConfig, + audioFormat) + frameSize - 1) + / frameSize); + + mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, + channelConfig, audioFormat, desiredFrames * frameSize, + AudioTrack.MODE_STREAM); + + audioStartThread(); + + Log.v("SDL", + "SDL audio: got " + + ((mAudioTrack.getChannelCount() >= 2) ? "stereo" + : "mono") + + " " + + ((mAudioTrack.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT) ? "16-bit" + : "8-bit") + " " + + ((float) mAudioTrack.getSampleRate() / 1000f) + + "kHz, " + desiredFrames + " frames buffer"); + + if (is16Bit) { + buf = new short[desiredFrames * (isStereo ? 2 : 1)]; + } else { + buf = new byte[desiredFrames * (isStereo ? 2 : 1)]; + } + return buf; + } + + public static void audioStartThread() { + mAudioThread = new Thread(new Runnable() { + public void run() { + mAudioTrack.play(); + nativeRunAudioThread(); + } + }); + + // I'd take REALTIME if I could get it! + mAudioThread.setPriority(Thread.MAX_PRIORITY); + mAudioThread.start(); + } + + public static void audioWriteShortBuffer(short[] buffer) { + for (int i = 0; i < buffer.length;) { + int result = mAudioTrack.write(buffer, i, buffer.length - i); + if (result > 0) { + i += result; + } else if (result == 0) { + try { + Thread.sleep(1); + } catch (InterruptedException e) { + // Nom nom + } + } else { + Log.w("SDL", "SDL audio: error return from write(short)"); + return; + } + } + } + + public static void audioWriteByteBuffer(byte[] buffer) { + for (int i = 0; i < buffer.length;) { + int result = mAudioTrack.write(buffer, i, buffer.length - i); + if (result > 0) { + i += result; + } else if (result == 0) { + try { + Thread.sleep(1); + } catch (InterruptedException e) { + // Nom nom + } + } else { + Log.w("SDL", "SDL audio: error return from write(short)"); + return; + } + } + } + + public static void audioQuit() { + if (mAudioThread != null) { + try { + mAudioThread.join(); + } catch (Exception e) { + Log.v("SDL", "Problem stopping audio thread: " + e); + } + mAudioThread = null; + + // Log.v("SDL", "Finished waiting for audio thread"); + } + + if (mAudioTrack != null) { + mAudioTrack.stop(); + mAudioTrack = null; + } + } +} + +/** + * Simple nativeInit() runnable + */ +class SDLMain implements Runnable { + private int surfaceWidth, surfaceHeight; + private GameConfig config; + + public SDLMain(int width, int height, GameConfig _config) { + config = _config; + surfaceWidth = width; + surfaceHeight = height; + } + + public void run() { + //Set up the IPC socket server to communicate with the engine + EngineProtocolNetwork ipc = new EngineProtocolNetwork(config); + + String path = Utils.getDownloadPath(SDLActivity.mSingleton);//This represents the data directory + path = path.substring(0, path.length()-1);//remove the trailing '/' + + + // Runs SDL_main() with added parameters + SDLActivity.nativeInit(new String[] { String.valueOf(ipc.port), + String.valueOf(surfaceWidth), String.valueOf(surfaceHeight), + "0", "null", "xeli", "1", "1", "1", path, "" }); + + try { + ipc.quitIPC(); + ipc.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + //Log.v("SDL", "SDL thread terminated"); + SDLActivity.mSingleton.finish(); + } +} + +/** + * SDLSurface. This is what we draw on, so we need to know when it's created in + * order to do anything useful. + * + * Because of this, that's where we set up the SDL thread + */ +class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, + View.OnKeyListener, SensorEventListener { + + // This is what SDL runs in. It invokes SDL_main(), eventually + private Thread mSDLThread; + + // EGL private objects + private EGLContext mEGLContext; + private EGLSurface mEGLSurface; + private EGLDisplay mEGLDisplay; + + // Sensors + private static SensorManager mSensorManager; + + private GameConfig config; + + // Startup + public SDLSurface(Context context, GameConfig _config) { + super(context); + getHolder().addCallback(this); + + setFocusable(true); + setFocusableInTouchMode(true); + requestFocus(); + setOnKeyListener(this); + setOnTouchListener(TouchInterface.getTouchInterface()); + + mSensorManager = (SensorManager) context.getSystemService("sensor"); + + config = _config; + } + + // Called when we have a valid drawing surface + public void surfaceCreated(SurfaceHolder holder) { + Log.v("SDL", "surfaceCreated()"); + + //enableSensor(Sensor.TYPE_ACCELEROMETER, true); + } + + // Called when we lose the surface + public void surfaceDestroyed(SurfaceHolder holder) { + Log.v("SDL", "surfaceDestroyed()"); + + // Send a quit message to the application + //SDLActivity.nativeQuit(); + PascalExports.HWterminate(true); + + // Now wait for the SDL thread to quit + if (mSDLThread != null) { + try { + mSDLThread.join(); + } catch (Exception e) { + Log.v("SDL", "Problem stopping thread: " + e); + } + mSDLThread = null; + + Log.v("SDL", "Finished waiting for SDL thread"); + } + + //enableSensor(Sensor.TYPE_ACCELEROMETER, false); + } + + // Called when the surface is resized + public void surfaceChanged(SurfaceHolder holder, int format, int width, + int height) { + Log.d("SDL", "surfaceChanged()" + width + " + " + height); + + int sdlFormat = 0x85151002; // SDL_PIXELFORMAT_RGB565 by default + switch (format) { + case PixelFormat.A_8: + Log.v("SDL", "pixel format A_8"); + break; + case PixelFormat.LA_88: + Log.v("SDL", "pixel format LA_88"); + break; + case PixelFormat.L_8: + Log.v("SDL", "pixel format L_8"); + break; + case PixelFormat.RGBA_4444: + Log.v("SDL", "pixel format RGBA_4444"); + sdlFormat = 0x85421002; // SDL_PIXELFORMAT_RGBA4444 + break; + case PixelFormat.RGBA_5551: + Log.v("SDL", "pixel format RGBA_5551"); + sdlFormat = 0x85441002; // SDL_PIXELFORMAT_RGBA5551 + break; + case PixelFormat.RGBA_8888: + Log.v("SDL", "pixel format RGBA_8888"); + sdlFormat = 0x86462004; // SDL_PIXELFORMAT_RGBA8888 + break; + case PixelFormat.RGBX_8888: + Log.v("SDL", "pixel format RGBX_8888"); + sdlFormat = 0x86262004; // SDL_PIXELFORMAT_RGBX8888 + break; + case PixelFormat.RGB_332: + Log.v("SDL", "pixel format RGB_332"); + sdlFormat = 0x84110801; // SDL_PIXELFORMAT_RGB332 + break; + case PixelFormat.RGB_565: + Log.v("SDL", "pixel format RGB_565"); + sdlFormat = 0x85151002; // SDL_PIXELFORMAT_RGB565 + break; + case PixelFormat.RGB_888: + Log.v("SDL", "pixel format RGB_888"); + // Not sure this is right, maybe SDL_PIXELFORMAT_RGB24 instead? + sdlFormat = 0x86161804; // SDL_PIXELFORMAT_RGB888 + break; + default: + Log.v("SDL", "pixel format unknown " + format); + break; + } + SDLActivity.onNativeResize(width, height, sdlFormat); + + // Now start up the C app thread + if (mSDLThread == null) { + mSDLThread = new Thread(new SDLMain(width, height, config), + "SDLThread"); + mSDLThread.start(); + } + } + + // unused + public void onDraw(Canvas canvas) { + } + + // EGL functions + public boolean initEGL(int majorVersion, int minorVersion) { + Log.v("SDL", "Starting up OpenGL ES " + majorVersion + "." + + minorVersion); + + try { + EGL10 egl = (EGL10) EGLContext.getEGL(); + + EGLDisplay dpy = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); + + int[] version = new int[2]; + egl.eglInitialize(dpy, version); + + int EGL_OPENGL_ES_BIT = 1; + int EGL_OPENGL_ES2_BIT = 4; + int renderableType = 0; + if (majorVersion == 2) { + renderableType = EGL_OPENGL_ES2_BIT; + } else if (majorVersion == 1) { + renderableType = EGL_OPENGL_ES_BIT; + } + int[] configSpec = { + // EGL10.EGL_DEPTH_SIZE, 16, + EGL10.EGL_RENDERABLE_TYPE, renderableType, EGL10.EGL_NONE }; + EGLConfig[] configs = new EGLConfig[1]; + int[] num_config = new int[1]; + if (!egl.eglChooseConfig(dpy, configSpec, configs, 1, num_config) + || num_config[0] == 0) { + Log.e("SDL", "No EGL config available"); + return false; + } + EGLConfig config = configs[0]; + + EGLContext ctx = egl.eglCreateContext(dpy, config, + EGL10.EGL_NO_CONTEXT, null); + if (ctx == EGL10.EGL_NO_CONTEXT) { + Log.e("SDL", "Couldn't create context"); + return false; + } + + EGLSurface surface = egl.eglCreateWindowSurface(dpy, config, this, + null); + if (surface == EGL10.EGL_NO_SURFACE) { + Log.e("SDL", "Couldn't create surface"); + return false; + } + + if (!egl.eglMakeCurrent(dpy, surface, surface, ctx)) { + Log.e("SDL", "Couldn't make context current"); + return false; + } + + mEGLContext = ctx; + mEGLDisplay = dpy; + mEGLSurface = surface; + + } catch (Exception e) { + Log.v("SDL", e + ""); + for (StackTraceElement s : e.getStackTrace()) { + Log.v("SDL", s.toString()); + } + } + + return true; + } + + // EGL buffer flip + public void flipEGL() { + try { + EGL10 egl = (EGL10) EGLContext.getEGL(); + + egl.eglWaitNative(EGL10.EGL_NATIVE_RENDERABLE, null); + + // drawing here + + egl.eglWaitGL(); + + egl.eglSwapBuffers(mEGLDisplay, mEGLSurface); + + } catch (Exception e) { + Log.v("SDL", "flipEGL(): " + e); + for (StackTraceElement s : e.getStackTrace()) { + Log.v("SDL", s.toString()); + } + + } + } + + // Key events + public boolean onKey(View v, int keyCode, KeyEvent event) { + if(keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP) return false; + if (event.getAction() == KeyEvent.ACTION_DOWN) { + Log.v("SDL", "key down: " + keyCode); + if(keyCode == KeyEvent.KEYCODE_BACK){//TODO ask user to quit or not + PascalExports.HWterminate(true); + //SDLActivity.mSingleton.finish(); + }else{ + SDLActivity.onNativeKeyDown(keyCode); + } + + return true; + } else if (event.getAction() == KeyEvent.ACTION_UP) { + Log.v("SDL", "key up: " + keyCode); + SDLActivity.onNativeKeyUp(keyCode); + return true; + } + + return false; + } + + // Sensor events + public void enableSensor(int sensortype, boolean enabled) { + // TODO: This uses getDefaultSensor - what if we have >1 accels? + if (enabled) { + mSensorManager.registerListener(this, + mSensorManager.getDefaultSensor(sensortype), + SensorManager.SENSOR_DELAY_GAME, null); + } else { + mSensorManager.unregisterListener(this, + mSensorManager.getDefaultSensor(sensortype)); + } + } + + public void onAccuracyChanged(Sensor sensor, int accuracy) { + // TODO + } + + public void onSensorChanged(SensorEvent event) { + if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { + SDLActivity.onNativeAccel(event.values[0], event.values[1], + event.values[2]); + } + } + +} diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/StartGameActivity.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/StartGameActivity.java Thu Oct 20 22:54:34 2011 +0200 @@ -0,0 +1,211 @@ +/* + * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game + * Copyright (c) 2011 Richard Deurwaarder + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +package org.hedgewars.hedgeroid; + +import org.hedgewars.hedgeroid.EngineProtocol.FrontendDataUtils; +import org.hedgewars.hedgeroid.EngineProtocol.GameConfig; +import org.hedgewars.hedgeroid.EngineProtocol.Map; +import org.hedgewars.hedgeroid.EngineProtocol.Scheme; +import org.hedgewars.hedgeroid.EngineProtocol.Team; +import org.hedgewars.hedgeroid.EngineProtocol.Weapon; +import org.hedgewars.mobile.R; + +import android.app.Activity; +import android.content.Intent; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.os.Parcelable; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemSelectedListener; +import android.widget.ArrayAdapter; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.Spinner; +import android.widget.Toast; + +public class StartGameActivity extends Activity { + + public static final int ACTIVITY_TEAM_SELECTOR = 0; + + private GameConfig config = null; + private ImageButton start, back, team; + private Spinner maps, gameplay, gamescheme, weapons, themes; + private ImageView themeIcon, mapPreview, teamCount; + + public void onCreate(Bundle savedInstanceState){ + super.onCreate(savedInstanceState); + + //SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); + //Copy all the xml files to the device TODO only do first time launch of the app... + Utils.resRawToFilesDir(this,R.array.schemes, Scheme.DIRECTORY_SCHEME); + Utils.resRawToFilesDir(this, R.array.weapons, Weapon.DIRECTORY_WEAPON); + Scheme.parseBasicFlags(this); + + config = new GameConfig(); + + setContentView(R.layout.starting_game); + + back = (ImageButton) findViewById(R.id.btnBack); + team = (ImageButton) findViewById(R.id.btnTeams); + start = (ImageButton) findViewById(R.id.btnStart); + + maps = (Spinner) findViewById(R.id.spinMaps); + gameplay = (Spinner) findViewById(R.id.spinGameplay); + gamescheme = (Spinner) findViewById(R.id.spinGamescheme); + weapons = (Spinner) findViewById(R.id.spinweapons); + themes = (Spinner) findViewById(R.id.spinTheme); + + themeIcon = (ImageView) findViewById(R.id.imgTheme); + mapPreview = (ImageView) findViewById(R.id.mapPreview); + teamCount = (ImageView) findViewById(R.id.imgTeamsCount); + + start.setOnClickListener(startClicker); + back.setOnClickListener(backClicker); + team.setOnClickListener(teamClicker); + + ArrayAdapter adapter = new ArrayAdapter(this, R.layout.listview_item, FrontendDataUtils.getMaps(this)); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + maps.setAdapter(adapter); + maps.setOnItemSelectedListener(mapsClicker); + + adapter = new ArrayAdapter(this, R.layout.listview_item, FrontendDataUtils.getGameplay(this)); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + gameplay.setAdapter(adapter); + gameplay.setOnItemSelectedListener(gameplayClicker); + + adapter = new ArrayAdapter(this, R.layout.listview_item, FrontendDataUtils.getSchemes(this)); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + gamescheme.setAdapter(adapter); + gamescheme.setOnItemSelectedListener(schemeClicker); + + adapter = new ArrayAdapter(this, R.layout.listview_item, FrontendDataUtils.getWeapons(this)); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + weapons.setAdapter(adapter); + weapons.setOnItemSelectedListener(weaponClicker); + + adapter = new ArrayAdapter(this, R.layout.listview_item, FrontendDataUtils.getThemes(this)); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + themes.setAdapter(adapter); + themes.setOnItemSelectedListener(themesClicker); + + } + + private void startTeamsActivity(){ + Intent i = new Intent(StartGameActivity.this, TeamSelectionActivity.class); + i.putParcelableArrayListExtra("teams", config.teams); + startActivityForResult(i, ACTIVITY_TEAM_SELECTOR); + } + + public void onActivityResult(int requestCode, int resultCode, Intent data){ + switch(requestCode){ + case ACTIVITY_TEAM_SELECTOR: + if(resultCode == Activity.RESULT_OK){ + Parcelable[] parcelables = (Parcelable[])data.getParcelableArrayExtra("teams"); + config.teams.clear(); + for(Parcelable t : parcelables){ + config.teams.add((Team)t); + } + teamCount.getDrawable().setLevel(config.teams.size()); + } + break; + } + } + + + private OnItemSelectedListener themesClicker = new OnItemSelectedListener(){ + + public void onItemSelected(AdapterView arg0, View view, int position, long rowId) { + String themeName = (String) arg0.getAdapter().getItem(position); + Drawable themeIconDrawable = Drawable.createFromPath(Utils.getDownloadPath(StartGameActivity.this) + "Themes/" + themeName + "/icon@2X.png"); + themeIcon.setImageDrawable(themeIconDrawable); + config.theme = themeName; + } + + public void onNothingSelected(AdapterView arg0) { + } + + }; + + private OnItemSelectedListener mapsClicker = new OnItemSelectedListener(){ + + public void onItemSelected(AdapterView arg0, View view, int position,long rowId) { + Map map = (Map)arg0.getAdapter().getItem(position); + mapPreview.setImageDrawable(map.getDrawable()); + config.map = map; + } + + public void onNothingSelected(AdapterView arg0) { + } + + }; + + private OnItemSelectedListener weaponClicker = new OnItemSelectedListener(){ + public void onItemSelected(AdapterView arg0, View arg1, int arg2, long arg3) { + config.weapon = (Weapon)arg0.getAdapter().getItem(arg2); + } + public void onNothingSelected(AdapterView arg0) { + + } + }; + private OnItemSelectedListener schemeClicker = new OnItemSelectedListener(){ + public void onItemSelected(AdapterView arg0, View arg1, int arg2, long arg3) { + config.scheme = (Scheme)arg0.getAdapter().getItem(arg2); + } + public void onNothingSelected(AdapterView arg0) { + + } + }; + private OnItemSelectedListener gameplayClicker = new OnItemSelectedListener(){ + public void onItemSelected(AdapterView arg0, View arg1, int arg2, long arg3) { + //config = ()arg0.getAdapter().getItem(arg2); + } + public void onNothingSelected(AdapterView arg0) { + + } + }; + + private OnClickListener startClicker = new OnClickListener(){ + public void onClick(View v) { + if(config.teams.size() < 2){ + Toast.makeText(StartGameActivity.this, R.string.not_enough_teams, Toast.LENGTH_LONG).show(); + startTeamsActivity(); + } + else{ + Intent i = new Intent(StartGameActivity.this, SDLActivity.class); + i.putExtra("config", config); + startActivity(i);} + } + }; + + private OnClickListener backClicker = new OnClickListener(){ + public void onClick(View v) { + finish(); + } + }; + + private OnClickListener teamClicker = new OnClickListener(){ + public void onClick(View v) { + startTeamsActivity(); + } + }; + +} diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamCreatorActivity.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamCreatorActivity.java Thu Oct 20 22:54:34 2011 +0200 @@ -0,0 +1,357 @@ +/* + * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game + * Copyright (c) 2011 Richard Deurwaarder + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +package org.hedgewars.hedgeroid; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; + +import org.hedgewars.hedgeroid.EngineProtocol.FrontendDataUtils; +import org.hedgewars.hedgeroid.EngineProtocol.Team; +import org.hedgewars.mobile.R; + +import android.app.Activity; +import android.graphics.Bitmap; +import android.graphics.drawable.Drawable; +import android.media.MediaPlayer; +import android.os.Bundle; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.View.OnFocusChangeListener; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemSelectedListener; +import android.widget.ArrayAdapter; +import android.widget.EditText; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.RelativeLayout; +import android.widget.ScrollView; +import android.widget.SimpleAdapter; +import android.widget.Spinner; +import android.widget.TextView; +import android.widget.Toast; + +public class TeamCreatorActivity extends Activity { + + private TextView name; + private Spinner difficulty, grave, flag, voice, fort; + private ImageView imgFort; + private ArrayList hogDice = new ArrayList(); + private ArrayList hogHat = new ArrayList(); + private ArrayList hogName = new ArrayList(); + private ImageButton back, save, voiceButton; + private ScrollView scroller; + private MediaPlayer mp = null; + private boolean settingsChanged = false; + private boolean saved = false; + + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.team_creation); + + name = (TextView) findViewById(R.id.txtName); + difficulty = (Spinner) findViewById(R.id.spinType); + grave = (Spinner) findViewById(R.id.spinGrave); + flag = (Spinner) findViewById(R.id.spinFlag); + voice = (Spinner) findViewById(R.id.spinVoice); + fort = (Spinner) findViewById(R.id.spinFort); + + imgFort = (ImageView) findViewById(R.id.imgFort); + + back = (ImageButton) findViewById(R.id.btnBack); + save = (ImageButton) findViewById(R.id.btnSave); + voiceButton = (ImageButton) findViewById(R.id.btnPlay); + + scroller = (ScrollView) findViewById(R.id.scroller); + + save.setOnClickListener(saveClicker); + back.setOnClickListener(backClicker); + + LinearLayout ll = (LinearLayout) findViewById(R.id.HogsContainer); + for (int i = 0; i < ll.getChildCount(); i++) { + RelativeLayout team_creation_entry = (RelativeLayout) ll + .getChildAt(i); + + hogHat.add((Spinner) team_creation_entry + .findViewById(R.id.spinTeam1)); + hogDice.add((ImageButton) team_creation_entry + .findViewById(R.id.btnTeam1)); + hogName.add((EditText) team_creation_entry + .findViewById(R.id.txtTeam1)); + } + ArrayList> gravesData = FrontendDataUtils + .getGraves(this); + SimpleAdapter sa = new SimpleAdapter(this, gravesData, + R.layout.spinner_textimg_entry, new String[] { "txt", "img" }, + new int[] { R.id.spinner_txt, R.id.spinner_img }); + + sa.setViewBinder(viewBinder); + grave.setAdapter(sa); + grave.setOnFocusChangeListener(focusser); + + ArrayList> flagsData = FrontendDataUtils + .getFlags(this); + sa = new SimpleAdapter(this, flagsData, R.layout.spinner_textimg_entry, + new String[] { "txt", "img" }, new int[] { R.id.spinner_txt, + R.id.spinner_img }); + sa.setViewBinder(viewBinder); + flag.setAdapter(sa); + flag.setOnFocusChangeListener(focusser); + + ArrayList> typesData = FrontendDataUtils + .getTypes(this); + sa = new SimpleAdapter(this, typesData, R.layout.spinner_textimg_entry, + new String[] { "txt", "img" }, new int[] { R.id.spinner_txt, + R.id.spinner_img }); + difficulty.setAdapter(sa); + difficulty.setOnFocusChangeListener(focusser); + + ArrayList> hatsData = FrontendDataUtils + .getHats(this); + sa = new SimpleAdapter(this, hatsData, R.layout.spinner_textimg_entry, + new String[] { "txt", "img" }, new int[] { R.id.spinner_txt, + R.id.spinner_img }); + sa.setViewBinder(viewBinder); + for (Spinner spin : hogHat) { + spin.setAdapter(sa); + } + + ArrayAdapter adapter = new ArrayAdapter(this, + R.layout.listview_item, FrontendDataUtils.getVoices(this)); + voice.setAdapter(adapter); + voice.setOnFocusChangeListener(focusser); + voiceButton.setOnClickListener(voiceClicker); + + adapter = new ArrayAdapter(this, R.layout.listview_item, + FrontendDataUtils.getForts(this)); + fort.setAdapter(adapter); + fort.setOnItemSelectedListener(fortSelector); + fort.setOnFocusChangeListener(focusser); + + Team t = this.getIntent().getParcelableExtra("team"); + if (t != null) { + name.setText(t.name); + int position = ((ArrayAdapter) voice.getAdapter()) + .getPosition(t.voice); + voice.setSelection(position); + + position = ((ArrayAdapter) fort.getAdapter()) + .getPosition(t.fort); + fort.setSelection(position); + + position = 0; + for (HashMap hashmap : typesData) { + if (hashmap.get("txt").equals(t.levels[0])) { + difficulty.setSelection(position); + break; + } + } + + position = 0; + for (HashMap hashmap : gravesData) { + if (hashmap.get("txt").equals(t.grave)) { + grave.setSelection(position); + break; + } + } + + position = 0; + for (HashMap hashmap : typesData) { + if (hashmap.get("txt").equals(t.flag)) { + flag.setSelection(position); + break; + } + } + + for (int i = 0; i < Team.maxNumberOfHogs; i++) { + position = 0; + for (HashMap hashmap : hatsData) { + if (hashmap.get("txt").equals(t.hats[i])) { + hogHat.get(i).setSelection(position); + } + } + + hogName.get(i).setText(t.hogNames[i]); + } + } + } + + public void onDestroy() { + super.onDestroy(); + if (mp != null) { + mp.release(); + mp = null; + } + } + + private OnFocusChangeListener focusser = new OnFocusChangeListener() { + public void onFocusChange(View v, boolean hasFocus) { + settingsChanged = true; + } + + }; + + public void onBackPressed() { + onFinishing(); + super.onBackPressed(); + + } + + private OnClickListener backClicker = new OnClickListener() { + public void onClick(View v) { + onFinishing(); + finish(); + } + }; + + private void onFinishing() { + if (settingsChanged) { + setResult(RESULT_OK); + } else { + setResult(RESULT_CANCELED); + } + } + + private OnClickListener saveClicker = new OnClickListener() { + public void onClick(View v) { + Toast.makeText(TeamCreatorActivity.this, R.string.saved, Toast.LENGTH_SHORT).show(); + saved = true; + Team team = new Team(); + team.name = name.getText().toString(); + HashMap hashmap = (HashMap) flag + .getSelectedItem(); + + team.flag = (String) hashmap.get("txt"); + team.fort = fort.getSelectedItem().toString(); + hashmap = (HashMap) grave.getSelectedItem(); + team.grave = hashmap.get("txt").toString(); + team.hash = "0"; + team.voice = voice.getSelectedItem().toString(); + + hashmap = ((HashMap) difficulty.getSelectedItem()); + String levelString = hashmap.get("txt").toString(); + int levelInt; + if (levelString.equals(getString(R.string.human))) { + levelInt = 0; + } else if (levelString.equals(getString(R.string.bot5))) { + levelInt = 1; + } else if (levelString.equals(getString(R.string.bot4))) { + levelInt = 2; + } else if (levelString.equals(getString(R.string.bot3))) { + levelInt = 3; + } else if (levelString.equals(getString(R.string.bot2))) { + levelInt = 4; + } else { + levelInt = 5; + } + + for (int i = 0; i < hogName.size(); i++) { + team.hogNames[i] = hogName.get(i).getText().toString(); + hashmap = (HashMap) hogHat.get(i) + .getSelectedItem(); + team.hats[i] = hashmap.get("txt").toString(); + team.levels[i] = levelInt; + } + try { + File teamsDir = new File(getFilesDir().getAbsolutePath() + '/' + + Team.DIRECTORY_TEAMS); + if (!teamsDir.exists()) + teamsDir.mkdir(); + FileOutputStream fos = new FileOutputStream(String.format( + "%s/%s.xml", teamsDir.getAbsolutePath(), team.name)); + team.writeToXml(fos); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + } + + }; + + private OnItemSelectedListener fortSelector = new OnItemSelectedListener() { + @SuppressWarnings("unchecked") + public void onItemSelected(AdapterView arg0, View arg1, + int position, long arg3) { + settingsChanged = true; + String fortName = (String) arg0.getAdapter().getItem(position); + Drawable fortIconDrawable = Drawable.createFromPath(Utils + .getDownloadPath(TeamCreatorActivity.this) + + "Forts/" + + fortName + "L.png"); + imgFort.setImageDrawable(fortIconDrawable); + scroller.fullScroll(ScrollView.FOCUS_DOWN);// Scroll the scrollview + // to the bottom, work + // around for scollview + // invalidation (scrolls + // back to top) + } + + public void onNothingSelected(AdapterView arg0) { + } + + }; + + private OnClickListener voiceClicker = new OnClickListener() { + public void onClick(View v) { + try { + File dir = new File(String.format("%sSounds/voices/%s", + Utils.getDownloadPath(TeamCreatorActivity.this), + voice.getSelectedItem())); + String file = ""; + File[] dirs = dir.listFiles(); + File f = dirs[(int) Math.round(Math.random() * dirs.length)]; + if (f.getName().endsWith(".ogg")) + file = f.getAbsolutePath(); + + if (mp == null) + mp = new MediaPlayer(); + else + mp.reset(); + mp.setDataSource(file); + mp.prepare(); + mp.start(); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (IllegalStateException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + }; + + private SimpleAdapter.ViewBinder viewBinder = new SimpleAdapter.ViewBinder() { + + public boolean setViewValue(View view, Object data, + String textRepresentation) { + if (view instanceof ImageView && data instanceof Bitmap) { + ImageView v = (ImageView) view; + v.setImageBitmap((Bitmap) data); + return true; + } else { + return false; + } + } + }; + +} diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamSelectionActivity.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamSelectionActivity.java Thu Oct 20 22:54:34 2011 +0200 @@ -0,0 +1,290 @@ +/* + * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game + * Copyright (c) 2011 Richard Deurwaarder + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +package org.hedgewars.hedgeroid; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; + +import org.hedgewars.hedgeroid.EngineProtocol.FrontendDataUtils; +import org.hedgewars.hedgeroid.EngineProtocol.Team; +import org.hedgewars.mobile.R; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.os.Parcelable; +import android.view.ContextMenu; +import android.view.MenuItem; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.AdapterView; +import android.widget.AdapterView.AdapterContextMenuInfo; +import android.widget.AdapterView.OnItemClickListener; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.ListView; +import android.widget.RelativeLayout; +import android.widget.SimpleAdapter; +import android.widget.SimpleAdapter.ViewBinder; +import android.widget.TextView; + +public class TeamSelectionActivity extends Activity{ + + private static final int ACTIVITY_TEAMCREATION = 0; + + private ImageButton addTeam, back; + private ListView availableTeams, selectedTeams; + private ArrayList> availableTeamsList, selectedTeamsList; + private TextView txtInfo; + + public void onCreate(Bundle savedInstanceState){ + super.onCreate(savedInstanceState); + + setContentView(R.layout.team_selector); + + addTeam = (ImageButton) findViewById(R.id.btnAdd); + back = (ImageButton) findViewById(R.id.btnBack); + txtInfo = (TextView) findViewById(R.id.txtInfo); + + addTeam.setOnClickListener(addTeamClicker); + back.setOnClickListener(backClicker); + + availableTeams = (ListView) findViewById(R.id.availableTeams); + availableTeamsList = FrontendDataUtils.getTeams(this); + SimpleAdapter adapter = new SimpleAdapter(this, availableTeamsList, R.layout.team_selection_entry_simple, new String[]{"txt", "img"}, new int[]{R.id.txtName, R.id.imgDifficulty}); + availableTeams.setAdapter(adapter); + registerForContextMenu(availableTeams); + availableTeams.setOnItemClickListener(availableClicker); + + selectedTeams = (ListView) findViewById(R.id.selectedTeams); + selectedTeamsList = new ArrayList>(); + ArrayList> toBeRemoved = new ArrayList>(); + ArrayList teamsStartGame = getIntent().getParcelableArrayListExtra("teams"); + for(HashMap hashmap : availableTeamsList){ + for(Team t : teamsStartGame){ + if(((Team)hashmap.get("team")).equals(t)){ + toBeRemoved.add(hashmap); + selectedTeamsList.add(FrontendDataUtils.teamToHashMap(t));//create a new hashmap to ensure all variables are entered into the map + } + } + } + for(HashMap hashmap : toBeRemoved) availableTeamsList.remove(hashmap); + + adapter = new SimpleAdapter(this, selectedTeamsList, R.layout.team_selection_entry, new String[]{"txt", "img", "color", "count"}, new int[]{R.id.txtName, R.id.imgDifficulty, R.id.teamColor, R.id.teamCount}); + adapter.setViewBinder(viewBinder); + selectedTeams.setAdapter(adapter); + selectedTeams.setOnItemClickListener(selectedClicker); + + txtInfo.setText(String.format(getResources().getString(R.string.teams_info_template), selectedTeams.getChildCount())); + } + + private ViewBinder viewBinder = new ViewBinder(){ + public boolean setViewValue(View view, Object data, String textRepresentation) { + switch(view.getId()){ + case R.id.teamColor: + setTeamColor(view, (Integer)data); + return true; + case R.id.teamCount: + setTeamHogCount((ImageView)view, (Integer)data); + return true; + default: + return false; + } + } + }; + + public void onActivityResult(int requestCode, int resultCode, Intent data){ + if(requestCode == ACTIVITY_TEAMCREATION){ + if(resultCode == Activity.RESULT_OK){ + updateListViews(); + } + }else{ + super.onActivityResult(requestCode, resultCode, data); + } + } + + private void updateListViews(){ + unregisterForContextMenu(availableTeams); + availableTeamsList = FrontendDataUtils.getTeams(this); + ArrayList> toBeRemoved = new ArrayList>(); + for(HashMap hashmap : selectedTeamsList){ + String name = (String)hashmap.get("txt"); + + for(HashMap hash : availableTeamsList){ + if(name.equals((String)hash.get("txt"))){ + toBeRemoved.add(hash); + } + } + } + for(HashMap hash: toBeRemoved) availableTeamsList.remove(hash); + + SimpleAdapter adapter = new SimpleAdapter(this, availableTeamsList, R.layout.team_selection_entry, new String[]{"txt", "img"}, new int[]{R.id.txtName, R.id.imgDifficulty}); + availableTeams.setAdapter(adapter); + registerForContextMenu(availableTeams); + availableTeams.setOnItemClickListener(availableClicker); + + + } + + private void setTeamColor(int position, int color){ + View iv = ((RelativeLayout)selectedTeams.getChildAt(position)).findViewById(R.id.teamCount); + setTeamColor(iv, color); + } + private void setTeamColor(View iv, int color){ + iv.setBackgroundColor(0xFF000000 + color); + } + + private void setTeamHogCount(int position, int count){ + ImageView iv = (ImageView)((RelativeLayout)selectedTeams.getChildAt(position)).findViewById(R.id.teamCount); + setTeamHogCount(iv, count); + } + + private void setTeamHogCount(ImageView iv, int count){ + + switch(count){ + case 0: + iv.setImageResource(R.drawable.teamcount0); + break; + case 1: + iv.setImageResource(R.drawable.teamcount1); + break; + case 2: + iv.setImageResource(R.drawable.teamcount2); + break; + case 3: + iv.setImageResource(R.drawable.teamcount3); + break; + case 4: + iv.setImageResource(R.drawable.teamcount4); + break; + case 5: + iv.setImageResource(R.drawable.teamcount5); + break; + case 6: + iv.setImageResource(R.drawable.teamcount6); + break; + case 7: + iv.setImageResource(R.drawable.teamcount7); + break; + case 8: + iv.setImageResource(R.drawable.teamcount8); + break; + case 9: + iv.setImageResource(R.drawable.teamcount9); + break; + } + } + + public void onBackPressed(){ + returnTeams(); + super.onBackPressed(); + } + + private OnClickListener addTeamClicker = new OnClickListener(){ + public void onClick(View v) { + startActivityForResult(new Intent(TeamSelectionActivity.this, TeamCreatorActivity.class), ACTIVITY_TEAMCREATION); + } + }; + + private OnClickListener backClicker = new OnClickListener(){ + public void onClick(View v){ + returnTeams(); + finish(); + } + }; + + private OnItemClickListener availableClicker = new OnItemClickListener(){ + public void onItemClick(AdapterView arg0, View arg1, int position,long arg3) { + selectAvailableTeamsItem(position); + } + }; + private OnItemClickListener selectedClicker = new OnItemClickListener(){ + public void onItemClick(AdapterView arg0, View arg1, int position,long arg3) { + availableTeamsList.add((HashMap) selectedTeamsList.get(position)); + selectedTeamsList.remove(position); + ((SimpleAdapter)availableTeams.getAdapter()).notifyDataSetChanged(); + ((SimpleAdapter)selectedTeams.getAdapter()).notifyDataSetChanged(); + + txtInfo.setText(String.format(getResources().getString(R.string.teams_info_template), selectedTeamsList.size())); + } + + }; + + public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuinfo){ + menu.add(ContextMenu.NONE, 0, ContextMenu.NONE, R.string.select); + menu.add(ContextMenu.NONE, 2, ContextMenu.NONE, R.string.edit); + menu.add(ContextMenu.NONE, 1, ContextMenu.NONE, R.string.delete); + + } + public boolean onContextItemSelected(MenuItem item){ + AdapterView.AdapterContextMenuInfo menuInfo = (AdapterContextMenuInfo) item.getMenuInfo(); + int position = menuInfo.position; + switch(item.getItemId()){ + case 0://select + selectAvailableTeamsItem(position); + return true; + case 1://delete + File f = new File(String.format("%s/%s/%s.xml", TeamSelectionActivity.this.getFilesDir(), Team.DIRECTORY_TEAMS, availableTeamsList.get(position).get("txt"))); + f.delete(); + availableTeamsList.remove(position); + ((SimpleAdapter)availableTeams.getAdapter()).notifyDataSetChanged(); + return true; + case 2://edit + Intent i = new Intent(TeamSelectionActivity.this, TeamCreatorActivity.class); + Team t = (Team)availableTeamsList.get(position).get("team"); + i.putExtra("team", t); + startActivityForResult(i, ACTIVITY_TEAMCREATION); + return true; + } + return false; + } + + private void selectAvailableTeamsItem(int position){ + HashMap hash = (HashMap) availableTeamsList.get(position); + Team t = (Team)hash.get("team"); + int[] illegalcolors = new int[selectedTeamsList.size()]; + for(int i = 0; i < selectedTeamsList.size(); i++){ + illegalcolors[i] = ((Team)selectedTeamsList.get(i).get("team")).color; + } + t.setRandomColor(illegalcolors); + hash.put("color", t.color); + hash.put("count", t.hogCount); + + selectedTeamsList.add(hash); + availableTeamsList.remove(position); + ((SimpleAdapter)availableTeams.getAdapter()).notifyDataSetChanged(); + ((SimpleAdapter)selectedTeams.getAdapter()).notifyDataSetChanged(); + + txtInfo.setText(String.format(getResources().getString(R.string.teams_info_template), selectedTeamsList.size())); + } + + private void returnTeams(){ + int teamsCount = selectedTeamsList.size(); + Intent i = new Intent(); + Parcelable[] teams = new Parcelable[teamsCount]; + for(int x = 0 ; x < teamsCount; x++){ + teams[x] = (Team)selectedTeamsList.get(x).get("team"); + } + i.putExtra("teams", teams); + setResult(Activity.RESULT_OK, i); + + } +} diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TextImageAdapter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TextImageAdapter.java Thu Oct 20 22:54:34 2011 +0200 @@ -0,0 +1,76 @@ +/* + * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game + * Copyright (c) 2011 Richard Deurwaarder + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +package org.hedgewars.hedgeroid; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import org.hedgewars.mobile.R; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.SimpleAdapter; +import android.widget.TextView; + + +public class TextImageAdapter extends SimpleAdapter { + + private Context context; + private ArrayList> data; + + public TextImageAdapter(Context _context, ArrayList> _data, int resource, String[] from, int[] to) { + super(_context, _data, resource, from, to); + context = _context; + data = _data; + } + + public static TextImageAdapter createAdapter(Context c, String[] txt, String[] img, String[] from, int[] to){ + if(txt.length != img.length) throw new IllegalArgumentException("txt and img parameters not equal"); + + ArrayList> data = new ArrayList>(txt.length); + + for(int i = 0; i < txt.length; i++){ + HashMap map = new HashMap(); + map.put("txt", txt[i]); + map.put("img", BitmapFactory.decodeFile(img[i])); + data.add(map); + } + return new TextImageAdapter(c, data, R.layout.spinner_textimg_entry, from, to); + } + + public View getView(int position, View convertView, ViewGroup parent){ + if(convertView == null){ + LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + convertView = inflater.inflate(R.layout.spinner_textimg_entry, parent); + } + TextView tv = (TextView) convertView.findViewById(R.id.spinner_txt); + ImageView img = (ImageView) convertView.findViewById(R.id.spinner_img); + + tv.setText((String)data.get(position).get("txt")); + img.setImageBitmap((Bitmap)data.get(position).get("img")); + + return convertView; + } +} diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TouchInterface/TouchInterface.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TouchInterface/TouchInterface.java Thu Oct 20 22:54:34 2011 +0200 @@ -0,0 +1,108 @@ +/* + * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game + * Copyright (c) 2011 Richard Deurwaarder + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +package org.hedgewars.hedgeroid.TouchInterface; + +import org.hedgewars.hedgeroid.SDLActivity; + +import android.os.Build; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.view.View.OnTouchListener; + +public class TouchInterface{ + + public static OnTouchListener getTouchInterface(){ + OnTouchListener toucher; + if(Build.VERSION.SDK_INT < 5){//8 == Build.VERSION_CODES.FROYO + toucher = new TouchInterfaceST(); + }else{ + toucher = new TouchInterfaceMT(); + } + + return toucher; + } +} +/** + * Touch interface with multitouch + */ +class TouchInterfaceMT implements OnTouchListener { + + private boolean firstEvent = true; + + public boolean onTouch(View v, MotionEvent event) { + //dumpEvent(event); + + if(firstEvent){ + firstEvent = false; + SDLActivity.onNativeTouch(-1, -1, v.getWidth(), v.getHeight(), 1); + } + + int action = event.getAction(); + int actionCode = action & MotionEvent.ACTION_MASK; + + for (int i = 0; i < event.getPointerCount(); i++) { + SDLActivity.onNativeTouch(actionCode, event.getPointerId(i), (int)event.getX(i), (int)event.getY(i), event.getPressure(i)); +// Log.d("Android", String.format("x=%f, y=%f, pntr=%d", event.getX(i), event.getY(i), event.getPointerId(i))); + } + return true; + } + + /** Show an event in the LogCat view, for debugging */ + private void dumpEvent(MotionEvent event) { + String names[] = { "DOWN" , "UP" , "MOVE" , "CANCEL" , "OUTSIDE" , + "POINTER_DOWN" , "POINTER_UP" , "7?" , "8?" , "9?" }; + StringBuilder sb = new StringBuilder(); + int action = event.getAction(); + int actionCode = action & MotionEvent.ACTION_MASK; + sb.append("event ACTION_" ).append(names[actionCode]); + if (actionCode == MotionEvent.ACTION_POINTER_DOWN + || actionCode == MotionEvent.ACTION_POINTER_UP) { + sb.append("(pid " ).append( + action >> MotionEvent.ACTION_POINTER_ID_SHIFT); + sb.append(")" ); + } + sb.append("[" ); + for (int i = 0; i < event.getPointerCount(); i++) { + sb.append("#" ).append(i); + sb.append("(pid " ).append(event.getPointerId(i)); + sb.append(")=" ).append((int) event.getX(i)); + sb.append("," ).append((int) event.getY(i)); + if (i + 1 < event.getPointerCount()) + sb.append(";" ); + } + sb.append("]" ); + Log.d("HW_APP_TOUCH", sb.toString()); + } + +} + +/** + * Touch interface without multitouch + */ +class TouchInterfaceST implements OnTouchListener { + + public boolean onTouch(View v, MotionEvent event) { + return false; + } + + + +} + diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Utils.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Utils.java Thu Oct 20 22:54:34 2011 +0200 @@ -0,0 +1,215 @@ +/* + * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game + * Copyright (c) 2011 Richard Deurwaarder + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +package org.hedgewars.hedgeroid; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; + +import org.hedgewars.mobile.R; + +import android.content.Context; +import android.content.res.TypedArray; +import android.os.Build; +import android.os.Environment; +import android.widget.Toast; + +public class Utils { + + + /** + * get the path to which we should download all the data files + * @param c context + * @return absolute path + */ + public static String getDownloadPath(Context c){ + if(Build.VERSION.SDK_INT < 8){//8 == Build.VERSION_CODES.FROYO + return PreFroyoSDCardDir.getDownloadPath(c); + }else{ + return FroyoSDCardDir.getDownloadPath(c); + } + } + + static class FroyoSDCardDir{ + public static String getDownloadPath(Context c){ + File f = c.getExternalCacheDir(); + if(f != null){ + return f.getAbsolutePath() + "/Data/"; + }else{ + Toast.makeText(c, R.string.sdcard_not_mounted, Toast.LENGTH_LONG).show(); + return null; + } + } + } + + static class PreFroyoSDCardDir{ + public static String getDownloadPath(Context c){ + if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ + if(Environment.getExternalStorageDirectory() != null) + return Environment.getExternalStorageDirectory().getAbsolutePath() + "/Hedgewars/"; + } + Toast.makeText(c, R.string.sdcard_not_mounted, Toast.LENGTH_LONG).show(); + return null; + } + } + + /** + * Get files from dirName, dir name is relative to {@link getDownloadPath} + * @param dirName + * @param c context + * @return string of files + */ + public static String[] getFileNamesFromRelativeDir(Context c, String dirName){ + String prefix = getDownloadPath(c); + File f = new File(prefix + dirName); + + if(f.exists() && f.isDirectory()) return f.list(); + else throw new IllegalArgumentException("File not a directory or doesn't exist dirName = " + f.getAbsolutePath()); + } + + /** + * Return a File array with all the files from dirName + * @param c + * @param dirName + * @return + */ + public static File[] getFilesFromRelativeDir(Context c, String dirName){ + String prefix = getDownloadPath(c); + File f = new File(prefix + dirName); + + if(f.exists() && f.isDirectory()) return f.listFiles(); + else throw new IllegalArgumentException("File not a directory or doesn't exist dirName = " + f.getAbsolutePath()); + } + + /** + * Checks if this directory has a file with suffix suffix + * @param f - directory + * @return + */ + public static boolean hasFileWithSuffix(File f, String suffix){ + if(f.isDirectory()){ + for(String s : f.list()){ + if(s.endsWith(suffix)) return true; + } + return false; + }else{ + return false; + } + } + + /** + * Gives back all dirs which contain a file with suffix fileSuffix + * @param c + * @param path + * @param fileSuffix + * @return + */ + public static String[] getDirsWithFileSuffix(Context c, String path, String fileSuffix){ + File[] files = getFilesFromRelativeDir(c,path); + String[] validFiles = new String[files.length]; + int validCounter = 0; + + for(File f : files){ + if(hasFileWithSuffix(f, fileSuffix)) validFiles[validCounter++] = f.getName(); + } + String[] ret = new String[validCounter]; + System.arraycopy(validFiles, 0, ret, 0, validCounter); + return ret; + } + + /** + * Get all files from directory dir which have the given suffix + * @param c + * @param dir + * @param suffix + * @param removeSuffix + * @return + */ + public static ArrayList getFilesFromDirWithSuffix(Context c, String dir, String suffix, boolean removeSuffix){ + String[] files = Utils.getFileNamesFromRelativeDir(c, dir); + ArrayList ret = new ArrayList(); + for(String s : files){ + if(s.endsWith(suffix)){ + if(removeSuffix) ret.add(s.substring(0, s.length()-suffix.length())); + else ret.add(s); + } + } + return ret; + } + + /** + * Moves resources pointed to by sourceResId (from @res/raw/) to the app's private data directory + * @param c + * @param sourceResId + * @param directory + */ + public static void resRawToFilesDir(Context c, int sourceResId, String directory){ + byte[] buffer = new byte[1024]; + InputStream bis = null; + BufferedOutputStream bos = null; + File schemesDirFile = new File(c.getFilesDir().getAbsolutePath() + '/' + directory); + schemesDirFile.mkdirs(); + String schemesDirPath = schemesDirFile.getAbsolutePath() + '/'; + + //Get an array with the resource files ID + TypedArray ta = c.getResources().obtainTypedArray(sourceResId); + int[] resIds = new int[ta.length()]; + for(int i = 0; i < ta.length(); i++){ + resIds[i] = ta.getResourceId(i, 0); + } + + for(int id : resIds){ + String fileName = c.getResources().getResourceEntryName(id); + File f = new File(schemesDirPath + fileName); + try { + if(!f.createNewFile()){ + f.delete(); + f.createNewFile(); + } + + bis = c.getResources().openRawResource(id); + bos = new BufferedOutputStream(new FileOutputStream(f), 1024); + int read = 0; + while((read = bis.read(buffer)) != -1){ + bos.write(buffer, 0, read); + } + + } catch (IOException e) { + e.printStackTrace(); + }finally{ + if(bis != null) + try { + bis.close(); + } catch (IOException e) { + e.printStackTrace(); + } + if(bos != null) + try { + bos.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } +} diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/Downloader/DownloadActivity.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/Downloader/DownloadActivity.java Sun Oct 09 20:41:17 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,180 +0,0 @@ -/* - * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game - * Copyright (c) 2011 Richard Deurwaarder - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - - -package org.hedgewars.mobile.Downloader; - -import org.hedgewars.mobile.MainActivity; -import org.hedgewars.mobile.R; - -import android.app.Activity; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.ServiceConnection; -import android.os.Bundle; -import android.os.Handler; -import android.os.IBinder; -import android.os.Message; -import android.os.Messenger; -import android.os.RemoteException; -import android.preference.PreferenceManager; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.Button; -import android.widget.ProgressBar; -import android.widget.TextView; -import android.widget.Toast; - -public class DownloadActivity extends Activity{ - private Messenger messageService; - private boolean boundToService = false; - - private TextView progress_sub; - private ProgressBar progress; - private Button positive, negative; - - public static final int MSG_START = 0; - public static final int MSG_UPDATE = 1; - public static final int MSG_DONE = 2; - public static final int MSG_FAILED = 3; - private Handler.Callback messageCallback = new Handler.Callback() { - - public boolean handleMessage(Message msg) { - switch(msg.what){ - case MSG_START: - progress.setMax(msg.arg1); - progress_sub.setText(String.format("%dkb/%dkb\n%s", 0, msg.arg1, "")); - positive.setText(R.string.download_background); - positive.setOnClickListener(backgroundClicker); - negative.setText(R.string.download_cancel); - negative.setOnClickListener(cancelClicker); - break; - case MSG_UPDATE: - progress_sub.setText(String.format("%d%% - %dkb/%dkb\n%s",(msg.arg1*100)/msg.arg2, msg.arg1, msg.arg2, msg.obj)); - progress.setProgress(msg.arg1); - break; - case MSG_DONE: - progress.setProgress(progress.getMax()); - progress_sub.setText(R.string.download_done); - - positive.setText(R.string.download_back); - positive.setOnClickListener(doneClicker); - - negative.setVisibility(View.INVISIBLE); - break; - case MSG_FAILED: - progress.setProgress(progress.getMax()); - progress_sub.setText(R.string.download_failed); - positive.setText(R.string.download_back); - positive.setOnClickListener(doneClicker); - - negative.setText(R.string.download_tryagain); - negative.setOnClickListener(tryAgainClicker); - break; - } - return false; - } - }; - private Handler messageHandler = new Handler(messageCallback); - private Messenger messenger = new Messenger(messageHandler); - - public void onCreate(Bundle savedInstanceState){ - super.onCreate(savedInstanceState); - setContentView(R.layout.download); - - progress_sub = (TextView)findViewById(R.id.progressbar_sub); - progress = (ProgressBar)findViewById(R.id.progressbar); - - positive = (Button) findViewById(R.id.background); - negative = (Button) findViewById(R.id.cancelDownload); - positive.setOnClickListener(backgroundClicker); - negative.setOnClickListener(cancelClicker); - - } - - private OnClickListener backgroundClicker = new OnClickListener(){ - public void onClick(View v){ - finish(); - } - }; - private OnClickListener cancelClicker = new OnClickListener(){ - public void onClick(View v){ - Intent i = new Intent(getApplicationContext(), DownloadService.class); - i.putExtra("taskID", DownloadService.TASKID_CANCEL); - startService(i); - finish(); - } - }; - private OnClickListener doneClicker = new OnClickListener(){ - public void onClick(View v){ - finish(); - startActivity(new Intent(getApplicationContext(), MainActivity.class)); - } - }; - - private OnClickListener tryAgainClicker = new OnClickListener(){ - public void onClick(View v){ - bindToService(DownloadService.TASKID_RETRY); - } - }; - - public void onStart(){ - super.onStart(); - bindToService(DownloadService.TASKID_START); - } - - public void onStop(){ - super.onStop(); - unBindFromService(); - } - - private ServiceConnection connection = new ServiceConnection(){ - - public void onServiceConnected(ComponentName name, IBinder service) { - messageService = new Messenger(service); - - try{ - Message msg = Message.obtain(null, DownloadService.MSG_REGISTER_CLIENT); - msg.replyTo = messenger; - messageService.send(msg); - - }catch (RemoteException e){} - } - - public void onServiceDisconnected(ComponentName name) { - messageService = null; - } - - }; - - private void bindToService(int taskId){ - Intent i = new Intent(getApplicationContext(), DownloadService.class); - i.putExtra("taskID", taskId); - startService(i); - bindService(new Intent(getApplicationContext(), DownloadService.class), connection, Context.BIND_AUTO_CREATE); - boundToService = true; - } - - private void unBindFromService(){ - if(boundToService){ - boundToService = false; - unbindService(connection); - } - } -} diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/Downloader/DownloadAsyncTask.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/Downloader/DownloadAsyncTask.java Sun Oct 09 20:41:17 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,212 +0,0 @@ -/* - * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game - * Copyright (c) 2011 Richard Deurwaarder - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - - -package org.hedgewars.mobile.Downloader; - -import java.io.BufferedInputStream; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.net.HttpURLConnection; -import java.net.URL; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; - -import android.os.AsyncTask; -import android.util.Log; -/** - * This is an AsyncTask which will download a zip from an URL and unzip it to a specified path - * - * a typical call to start the task would be new DownloadAsyncTask().execute(getExternalStorage(), "www.hedgewars.org/data.zip"); - * @author Xeli - * - */ -public class DownloadAsyncTask extends AsyncTask { - - private final static String URL_WITHOUT_SUFFIX = "http://hedgewars.googlecode.com/files/data_5631."; - //private final static String URL_WITHOUT_SUFFIX = "http://www.xelification.com/tmp/firebutton."; - private final static String URL_ZIP_SUFFIX = "zip"; - private final static String URL_HASH_SUFFIX = "hash"; - - private DownloadService service; - private long lastUpdateMillis = 0; - - public DownloadAsyncTask(DownloadService _service){ - service = _service; - } - - /** - * - * @param params - 2 Strings, first is the path where the unzipped files will be stored, second is the URL to download from - */ - protected Long doInBackground(String... params) { - HttpURLConnection conn = null; - MessageDigest digester = null; - String rootZipDest = params[0]; - - File rootDest = new File(rootZipDest);//TODO check for nullpointer, it hints to the absence of an sdcard - rootDest.mkdir(); - - try { - URL url = new URL(URL_WITHOUT_SUFFIX + URL_ZIP_SUFFIX); - conn = (HttpURLConnection)url.openConnection(); - } catch (IOException e) { - e.printStackTrace(); - return -1l; - } - - String contentType = conn.getContentType(); - - if(contentType == null || contentType.contains("zip")){ //Seeing as we provide the url if the contentType is unknown lets assume zips - int bytesDecompressed = 0; - ZipEntry entry = null; - ZipInputStream input = null; - int kbytesToProcess = conn.getContentLength()/1024; - - byte[] buffer = new byte[1024]; - service.start(kbytesToProcess); - - try { - digester = MessageDigest.getInstance("MD5"); - - } catch (NoSuchAlgorithmException e1) { - e1.printStackTrace(); - } - - try{ - input = new ZipInputStream(conn.getInputStream()); - entry = input.getNextEntry(); - }catch(IOException e){ - e.printStackTrace(); - if(conn != null) conn.disconnect(); - return -1l; - } - - while(entry != null){ - if(isCancelled()) break; - - String fileName = entry.getName(); - File f = new File(rootZipDest + fileName); - bytesDecompressed += entry.getCompressedSize(); - - if(entry.isDirectory()){ - f.mkdir(); - }else{ - if(f.exists()){ - f.delete(); - } - - FileOutputStream output = null; - try { - f.createNewFile(); - output = new FileOutputStream(f); - - int count = 0; - while((count = input.read(buffer)) != -1){ - output.write(buffer, 0, count); - digester.update(buffer, 0, count); - if(System.currentTimeMillis() - lastUpdateMillis > 1000){ - lastUpdateMillis = System.currentTimeMillis(); - publishProgress(bytesDecompressed, kbytesToProcess, fileName); - } - } - output.flush(); - input.closeEntry(); - } catch (FileNotFoundException e) { - e.printStackTrace(); - if(conn != null) conn.disconnect(); - return -1l; - } catch (IOException e) { - e.printStackTrace(); - if(conn != null) conn.disconnect(); - return -1l; - }finally{ - try { - if( output != null) output.close(); - } catch (IOException e) {} - } - } - try{ - entry = input.getNextEntry(); - }catch(IOException e){ - e.printStackTrace(); - if(conn != null) conn.disconnect(); - return -1l; - } - }//end while(entry != null) - - try { - input.close(); - } catch (IOException e) {} - }//end if contentType == "zip" - - if(conn != null) conn.disconnect(); - - if(checkMD5(digester))return 0l; - else return -1l; - } - - //TODO proper result handling - protected void onPostExecute(Long result){ - service.done(result > -1l); - } - - protected void onProgressUpdate(Object...objects){ - service.update((Integer)objects[0], (Integer)objects[1], (String)objects[2]); - } - - private boolean checkMD5(MessageDigest digester){ - if(digester != null) { - byte[] messageDigest = digester.digest(); - - try { - URL url = new URL(URL_WITHOUT_SUFFIX + URL_HASH_SUFFIX); - HttpURLConnection conn = (HttpURLConnection)url.openConnection(); - - byte[] buffer = new byte[1024];//size is large enough to hold the entire hash - BufferedInputStream bis = new BufferedInputStream(conn.getInputStream()); - int bytesRead = bis.read(buffer); - if(bytesRead > -1){ - String hash = new String(buffer, 0, bytesRead); - StringBuffer sb = new StringBuffer(); - Integer tmp = 0; - for(int i = 0; i < messageDigest.length; i++){ - tmp = 0xFF & messageDigest[i]; - if(tmp < 0xF) sb.append('0'); - sb.append(Integer.toHexString(tmp)); - } - sb.append('\n');//add newline to become identical with the hash file - - return hash.equals(sb.toString()); - } - return false; - } catch (IOException e) { - e.printStackTrace(); - return false; - } - }else{ - return false; - } - - } - -} diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/Downloader/DownloadService.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/Downloader/DownloadService.java Sun Oct 09 20:41:17 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,199 +0,0 @@ -/* - * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game - * Copyright (c) 2011 Richard Deurwaarder - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - - -package org.hedgewars.mobile.Downloader; - -import java.util.ArrayList; - -import org.hedgewars.mobile.MainActivity; -import org.hedgewars.mobile.R; -import org.hedgewars.mobile.Utils; - -import android.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.app.Service; -import android.content.Intent; -import android.os.Handler; -import android.os.IBinder; -import android.os.Message; -import android.os.Messenger; -import android.os.RemoteException; -import android.preference.PreferenceManager; -import android.util.Log; -import android.widget.RemoteViews; - -public class DownloadService extends Service { - - public static final String PREF_DOWNLOADED = "downloaded"; - public static final int MSG_CANCEL = 0; - public static final int MSG_REGISTER_CLIENT = 1; - public static final int MSG_UNREGISTER_CLIENT = 2; - - public static final int NOTIFICATION_PROCESSING = 0; - public static final int NOTIFICATION_DONE = 1; - - private DownloadAsyncTask downloadTask; - private final Messenger messenger = new Messenger(new DownloadHandler()); - private NotificationManager nM; - private RemoteViews contentView; - private Notification notification; - - private ArrayList clientList = new ArrayList(); - private Message onRegisterMessage = null; - - - class DownloadHandler extends Handler{ - - public void handleMessage(Message msg){ - switch(msg.what){ - case MSG_CANCEL: - downloadTask.cancel(false); - break; - case MSG_REGISTER_CLIENT: - clientList.add(msg.replyTo); - if(onRegisterMessage != null){ - try { - msg.replyTo.send(Message.obtain(onRegisterMessage)); - } catch (RemoteException e) { - e.printStackTrace(); - } - } - break; - case MSG_UNREGISTER_CLIENT: - clientList.remove(msg.replyTo); - break; - } - } - } - - public final static int TASKID_START = 0; - public final static int TASKID_CANCEL = 1; - public final static int TASKID_RETRY = 2; - - public int onStartCommand(Intent intent, int flags, int startId){ - switch(intent.getIntExtra("taskID", TASKID_START)){ - case TASKID_RETRY: - if(downloadTask != null){ - downloadTask.cancel(false); - downloadTask = null; - } - case TASKID_START: - nM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); - - notification = new Notification(R.drawable.statusbar, getString(R.string.notification_title), System.currentTimeMillis()); - //notification.flags |= Notification.FLAG_ONGOING_EVENT;// | Notification.FLAG_NO_CLEAR | Notification.FLAG_FOREGROUND_SERVICE; - notification.flags |= Notification.FLAG_ONGOING_EVENT; - - contentView = new RemoteViews(getPackageName(), R.layout.notification); - contentView.setProgressBar(R.id.notification_progress, 100, 34, false); - notification.contentView = contentView; - - PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, DownloadActivity.class), Intent.FLAG_ACTIVITY_NEW_TASK); - notification.contentIntent = contentIntent; - - //nM.notify(NOTIFICATION_PROCESSING, notification); - startForeground(NOTIFICATION_PROCESSING, notification); - - if(downloadTask == null){ - downloadTask = new DownloadAsyncTask(this); - downloadTask.execute(Utils.getDownloadPath(this)); - } - break; - case TASKID_CANCEL: - downloadTask.cancel(false); - stopService(); - break; - } - return 0; - } - - public void onDestroy(){ - Log.e("bla", "onDestroy"); - downloadTask.cancel(false); - } - - public IBinder onBind(Intent intent) { - return messenger.getBinder(); - } - - /* - * Thread safe method to let clients know the processing is starting and will process int max kbytes - */ - public void start(int max){ - onRegisterMessage = Message.obtain(null, DownloadActivity.MSG_START, max, -1); - sendMessageToClients(onRegisterMessage); - } - - /* - * periodically gets called by the ASyncTask, we can't tell for sure when it's called - */ - public void update(int progress, int max, String fileName){ - progress = (progress/1024); - updateNotification(progress, max, fileName); - - sendMessageToClients(Message.obtain(null, DownloadActivity.MSG_UPDATE, progress, max, fileName)); - } - - /* - * Call back from the ASync task when the task has either run into an error or finished otherwise - */ - public void done(boolean succesful){ - if(succesful){ - PreferenceManager.getDefaultSharedPreferences(this).edit().putBoolean(DownloadService.PREF_DOWNLOADED, true).commit(); - sendMessageToClients(Message.obtain(null, DownloadActivity.MSG_DONE)); - }else sendMessageToClients(Message.obtain(null, DownloadActivity.MSG_FAILED)); - stopService();//stopService clears all notifications and thus must be called before we show the ready notification - showDoneNotification(); - } - - private void stopService(){ - nM.cancelAll(); - stopForeground(true); - stopSelf(); - } - - private void updateNotification(int progress, int max, String fileName){ - - contentView.setProgressBar(R.id.notification_progress, max, progress, false); - contentView.setTextViewText(R.id.progressbar_sub, String.format("%dkb/%dkb (Compressed sizes)", progress, max)); - nM.notify(NOTIFICATION_PROCESSING, notification); - } - - private void showDoneNotification(){ - nM.cancelAll(); - stopForeground(true); - - String title = getString(R.string.notification_title); - - notification = new Notification(R.drawable.icon, title, System.currentTimeMillis()); - notification.flags |= Notification.FLAG_AUTO_CANCEL; - PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), Intent.FLAG_ACTIVITY_NEW_TASK); - notification.setLatestEventInfo(this, title, getString(R.string.notification_done), contentIntent); - nM.notify(NOTIFICATION_DONE, notification); - } - private void sendMessageToClients(Message msg){ - for(Messenger m : clientList){ - try { - m.send(Message.obtain(msg)); - } catch (RemoteException e) {}//TODO should we catch this properly? - } - } - -} diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/EngineProtocol/EngineProtocolNetwork.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/EngineProtocol/EngineProtocolNetwork.java Sun Oct 09 20:41:17 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,159 +0,0 @@ -/* - * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game - * Copyright (c) 2011 Richard Deurwaarder - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - - -package org.hedgewars.mobile.EngineProtocol; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.ServerSocket; -import java.net.Socket; -import java.net.UnknownHostException; - -public class EngineProtocolNetwork extends Thread{ - - public static final String GAMEMODE_LOCAL = "TL"; - public static final String GAMEMODE_DEMO = "TD"; - public static final String GAMEMODE_NET = "TN"; - public static final String GAMEMODE_SAVE = "TS"; - - public static final int BUFFER_SIZE = 255; //From iOS code which got it from the origional frontend - - public static final int MODE_GENLANDPREVIEW = 0; - public static final int MODE_GAME = 1; - - private ServerSocket serverSocket; - private InputStream input; - private OutputStream output; - public int port; - private final GameConfig config; - private boolean clientQuit = false; - - public EngineProtocolNetwork(GameConfig _config){ - config = _config; - try { - serverSocket = new ServerSocket(0); - port = serverSocket.getLocalPort(); - Thread ipcThread = new Thread(this, "IPC - Thread"); - ipcThread.start(); - } catch (UnknownHostException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - public void run(){ - //if(mode == MODE_GENLANDPREVIEW) genLandPreviewIPC(); - /*else if (mode == MODE_GAME)*/ gameIPC(); - } - - private void gameIPC(){ - Socket sock = null; - try{ - sock = serverSocket.accept(); - input = sock.getInputStream(); - output = sock.getOutputStream(); - - int msgSize = 0; - byte[] buffer = new byte[BUFFER_SIZE]; - - while(!clientQuit){ - msgSize = 0; - - input.read(buffer, 0, 1); - msgSize = buffer[0]; - - input.read(buffer, 0, msgSize); - System.out.println("IPC" + (char)buffer[0] + " : " + new String(buffer, 1,msgSize-1, "US_ASCII")); - switch(buffer[0]){ - case 'C'://game init - config.sendToEngine(this); - break; - case '?'://ping - pong - sendToEngine("!"); - break; - case 'e'://Send protocol version - System.out.println(new String(buffer)); - break; - case 'i'://game statistics - switch(buffer[1]){ - case 'r'://winning team - break; - case 'D'://best shot - break; - case 'k'://best hedgehog - break; - case 'K'://# hogs killed - break; - case 'H'://team health graph - break; - case 'T':// local team stats - break; - case 'P'://teams ranking - break; - case 's'://self damage - break; - case 'S'://friendly fire - break; - case 'B'://turn skipped - break; - default: - } - break; - case 'E'://error - quits game - System.out.println(new String(buffer)); - return; - case 'q'://game ended remove save file - - return; - case 'Q'://game ended but not finished - - return; - } - - } - }catch(IOException e){ - e.printStackTrace(); - }finally{ - try { - if(sock != null) sock.close(); - } catch (IOException e) {} - try{ - if(serverSocket != null) serverSocket.close(); - } catch (IOException e) {} - } - } - - public void sendToEngine(String s){ - int length = s.length(); - - try { - output.write(length); - output.write(s.getBytes(), 0, length); - } catch (IOException e) { - e.printStackTrace(); - } - } - - public void quitIPC(){ - clientQuit = true; - } - -} diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/EngineProtocol/FrontendDataUtils.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/EngineProtocol/FrontendDataUtils.java Sun Oct 09 20:41:17 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,215 +0,0 @@ -/* - * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game - * Copyright (c) 2011 Richard Deurwaarder - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - - -package org.hedgewars.mobile.EngineProtocol; - -import java.io.File; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; - -import org.hedgewars.mobile.R; -import org.hedgewars.mobile.Utils; -import org.hedgewars.mobile.EngineProtocol.Map.MapType; - -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; - -public class FrontendDataUtils { - - - public static ArrayList getMaps(Context c){ - File[] files = Utils.getFilesFromRelativeDir(c,"Maps"); - ArrayList ret = new ArrayList(); - - for(File f : files){ - if(Utils.hasFileWithSuffix(f, ".lua")){ - ret.add(new Map(f,MapType.TYPE_MISSION, c)); - }else{ - ret.add(new Map(f, MapType.TYPE_DEFAULT,c)); - } - } - Collections.sort(ret); - - return ret; - } - - public static String[] getGameplay(Context c){ - String[] files = Utils.getFileNamesFromRelativeDir(c, "Scripts/Multiplayer"); - int retCounter = 0; - - for(int i = 0; i < files.length; i++){ - if(files[i].endsWith(".lua")){ - files[i] = files[i].replace('_', ' ').substring(0, files[i].length()-4); //replace _ by a space and removed the last four characters (.lua) - retCounter++; - }else files[i] = null; - } - String[] ret = new String[retCounter]; - retCounter = 0; - for(String s : files){ - if(s != null) ret[retCounter++] = s; - } - Arrays.sort(ret); - - return ret; - } - - public static String[] getThemes(Context c){ - return Utils.getDirsWithFileSuffix(c, "Themes", "icon.png"); - } - - public static ArrayList getSchemes(Context c){ - return Scheme.getSchemes(c); - } - - public static ArrayList getWeapons(Context c){ - return Weapon.getWeapons(c); - } - - public static ArrayList> getGraves(Context c){ - String pathPrefix = Utils.getDownloadPath(c) + "Graphics/Graves/"; - ArrayList names = Utils.getFilesFromDirWithSuffix(c, "Graphics/Graves", ".png", true); - ArrayList> data = new ArrayList>(names.size()); - - for(String s : names){ - HashMap map = new HashMap(); - map.put("txt", s); - Bitmap b = BitmapFactory.decodeFile(pathPrefix + s + ".png");//create a full path - decode to to a bitmap - int width = b.getWidth(); - if(b.getHeight() > width){//some pictures contain more 'frames' underneath each other, if so we only use the first frame - Bitmap tmp = Bitmap.createBitmap(b, 0, 0, width, width); - b.recycle(); - b = tmp; - } - map.put("img", b); - data.add(map); - } - return data; - } - - public static ArrayList> getFlags(Context c){ - String pathPrefix = Utils.getDownloadPath(c) + "Graphics/Flags/"; - ArrayList names = Utils.getFilesFromDirWithSuffix(c, "Graphics/Flags", ".png", true); - ArrayList> data = new ArrayList>(names.size()); - - for(String s : names){ - HashMap map = new HashMap(); - map.put("txt", s); - Bitmap b = BitmapFactory.decodeFile(pathPrefix + s + ".png");//create a full path - decode to to a bitmap - map.put("img", b); - data.add(map); - } - return data; - } - - public static ArrayList getVoices(Context c){ - File[] files = Utils.getFilesFromRelativeDir(c, "Sounds/voices"); - ArrayList ret = new ArrayList(); - - for(File f : files){ - if(f.isDirectory()) ret.add(f.getName()); - } - return ret; - } - - public static ArrayList getForts(Context c){ - return Utils.getFilesFromDirWithSuffix(c, "Forts", "L.png", true); - } - public static ArrayList> getTypes(Context c){ - ArrayList> data = new ArrayList>(6); - String[] levels = {c.getString(R.string.human), c.getString(R.string.bot5), c.getString(R.string.bot4), c.getString(R.string.bot3), c.getString(R.string.bot2), c.getString(R.string.bot1)}; - int[] images = {R.drawable.human, R.drawable.bot5, R.drawable.bot4, R.drawable.bot3, R.drawable.bot2, R.drawable.bot1}; - - for(int i = 0; i < levels.length; i++){ - HashMap map = new HashMap(); - map.put("txt", levels[i]); - map.put("img", images[i]); - data.add(map); - } - - return data; - } - - public static ArrayList> getHats(Context c){ - ArrayList files = Utils.getFilesFromDirWithSuffix(c, "Graphics/Hats", ".png", true); - String pathPrefix = Utils.getDownloadPath(c) + "Graphics/Hats/"; - int size = files.size(); - ArrayList> data = new ArrayList>(size); - - HashMap hashmap; - for(String s : files){ - hashmap = new HashMap(); - hashmap.put("txt", s); - Bitmap b = BitmapFactory.decodeFile(pathPrefix + s + ".png");//create a full path - decode to to a bitmap - b = Bitmap.createBitmap(b, 0,0,b.getWidth()/2, b.getWidth()/2); - hashmap.put("img", b); - data.add(hashmap); - } - - return data; - } - - public static ArrayList> getTeams(Context c){ - ArrayList> ret = new ArrayList>(); - - File teamsDir = new File(c.getFilesDir().getAbsolutePath() + '/' + Team.DIRECTORY_TEAMS); - File[] teamFileNames = teamsDir.listFiles(); - if(teamFileNames != null){ - for(File s : teamFileNames){ - Team t = Team.getTeamFromXml(s.getAbsolutePath()); - if(t != null){ - ret.add(teamToHashMap(t)); - } - } - } - return ret; - } - - public static HashMap teamToHashMap(Team t){ - HashMap hashmap = new HashMap(); - hashmap.put("team", t); - hashmap.put("txt", t.name); - hashmap.put("color", t.color); - hashmap.put("count", t.hogCount); - switch(t.levels[0]){ - case 0: - hashmap.put("img", R.drawable.human); - break; - case 1: - hashmap.put("img", R.drawable.bot5); - break; - case 2: - hashmap.put("img", R.drawable.bot4); - break; - case 3: - hashmap.put("img", R.drawable.bot3); - break; - case 4: - hashmap.put("img", R.drawable.bot2); - break; - default: - case 5: - hashmap.put("img", R.drawable.bot1); - break; - } - return hashmap; - } -} diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/EngineProtocol/GameConfig.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/EngineProtocol/GameConfig.java Sun Oct 09 20:41:17 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,117 +0,0 @@ -/* - * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game - * Copyright (c) 2011 Richard Deurwaarder - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -package org.hedgewars.mobile.EngineProtocol; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.UUID; - -import android.os.Parcel; -import android.os.Parcelable; -import android.util.Log; - -public class GameConfig implements Parcelable{ - - public GameMode mode = GameMode.MODE_LOCAL; - public Map map = null; - public String theme = null; - public Scheme scheme = null; - public Weapon weapon = null; - - public String mission = null; - public String seed = null; - - public ArrayList teams = new ArrayList(); - - public GameConfig(){ - - } - - public GameConfig(Parcel in){ - readFromParcel(in); - } - - - - public void sendToEngine(EngineProtocolNetwork epn) throws IOException{ - Log.d("HW_Frontend", "Sending Gameconfig..."); - int teamCount = 4; - epn.sendToEngine("TL"); //Write game mode - if(mission != null) epn.sendToEngine(mission); - - //seed info - epn.sendToEngine(String.format("eseed {%s}", UUID.randomUUID().toString())); - - map.sendToEngine(epn); - //dimensions of the map - //templatefilter_command - //mapgen_command - //mazesize_command - - epn.sendToEngine(String.format("etheme %s", theme)); - - scheme.sendToEngine(epn); - - weapon.sendToEngine(epn, teamCount); - - for(Team t : teams){ - if(t != null)t.sendToEngine(epn, teamCount, 50); - } - } - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(mode.name()); - dest.writeParcelable(map, flags); - dest.writeString(theme); - dest.writeParcelable(scheme, flags); - dest.writeParcelable(weapon, flags); - dest.writeString(mission); - dest.writeString(seed); - dest.writeParcelableArray((Team[])teams.toArray(new Team[1]), 0); - } - - private void readFromParcel(Parcel src){ - mode = GameMode.valueOf(src.readString()); - map = src.readParcelable(Map.class.getClassLoader()); - theme = src.readString(); - scheme = src.readParcelable(Scheme.class.getClassLoader()); - weapon = src.readParcelable(Weapon.class.getClassLoader()); - mission = src.readString(); - seed = src.readString(); - Parcelable[] parcelables = src.readParcelableArray(Team[].class.getClassLoader()); - for(Parcelable team : parcelables){ - teams.add((Team)team); - } - - } - - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - public GameConfig createFromParcel(Parcel source) { - return new GameConfig(source); - } - public GameConfig[] newArray(int size) { - return new GameConfig[size]; - } - }; - -} diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/EngineProtocol/GameMode.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/EngineProtocol/GameMode.java Sun Oct 09 20:41:17 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,24 +0,0 @@ -/* - * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game - * Copyright (c) 2011 Richard Deurwaarder - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - - -package org.hedgewars.mobile.EngineProtocol; - -public enum GameMode { - MODE_LOCAL, MODE_DEMO, MODE_NET, MODE_SAVE -} diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/EngineProtocol/Grave.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/EngineProtocol/Grave.java Sun Oct 09 20:41:17 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -/* - * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game - * Copyright (c) 2011 Richard Deurwaarder - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - - -package org.hedgewars.mobile.EngineProtocol; - -public class Grave{ - - public final String name; - public final String path; - - public Grave(String _name, String _path) { - name = _name; - path = _path; - } - - public String toString(){ - return name; - } - -} diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/EngineProtocol/Map.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/EngineProtocol/Map.java Sun Oct 09 20:41:17 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,160 +0,0 @@ -/* - * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game - * Copyright (c) 2011 Richard Deurwaarder - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -package org.hedgewars.mobile.EngineProtocol; - -import java.io.File; -import java.io.IOException; - -import android.content.Context; -import android.graphics.drawable.Drawable; -import android.os.Parcel; -import android.os.Parcelable; - -public class Map implements Comparable, Parcelable{ - - private static final String MISSION_PREFIX = "Mission: "; - - private String name; - private String path; - private String previewPath; - private MapType type; - - public Map(File mapDir, MapType _type, Context c){ - type = _type; - - name = mapDir.getName(); - path = mapDir.getAbsolutePath(); - previewPath = path + "/preview.png"; - - /*switch(type){ - case TYPE_DEFAULT: - - break; - case TYPE_GENERATED: - //TODO - break; - case TYPE_MISSION: - name = MISSION_PREFIX + mapDir.getName(); - path = mapDir.getAbsolutePath(); - break; - }*/ - - - } - - public Map(Parcel in){ - readFromParcel(in); - } - - public String toString(){ - switch(type){ - default: - case TYPE_DEFAULT: - return name; - case TYPE_GENERATED: - return "bla"; - case TYPE_MISSION: - return MISSION_PREFIX + name; - } - } - - public void sendToEngine(EngineProtocolNetwork epn) throws IOException{ - epn.sendToEngine(String.format("emap %s",name)); - } - - public MapType getType(){ - return type; - } - - public Drawable getDrawable(){ - switch(type){ - case TYPE_MISSION: - case TYPE_DEFAULT: - return Drawable.createFromPath(previewPath); - case TYPE_GENERATED: - - default: - return null; - } - } - - public int compareTo(Map another) { - switch(type){ - case TYPE_GENERATED: - switch(another.getType()){ - case TYPE_GENERATED: - return name.compareTo(another.name); - case TYPE_MISSION: - return -1; - case TYPE_DEFAULT: - return -1; - } - case TYPE_MISSION: - switch(another.getType()){ - case TYPE_GENERATED: - return 1; - case TYPE_MISSION: - return name.compareTo(another.name); - case TYPE_DEFAULT: - return -1; - } - case TYPE_DEFAULT: - switch(another.getType()){ - case TYPE_GENERATED: - return 1; - case TYPE_MISSION: - return 1; - case TYPE_DEFAULT: - return name.compareTo(another.name); - } - } - return 0;//default case this should never happen - } - - public enum MapType{ - TYPE_DEFAULT, TYPE_MISSION, TYPE_GENERATED - } - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(name); - dest.writeString(path); - dest.writeString(previewPath); - dest.writeString(type.name()); - } - - private void readFromParcel(Parcel src){ - name = src.readString(); - path = src.readString(); - previewPath = src.readString(); - type = MapType.valueOf(src.readString()); - } - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - public Map createFromParcel(Parcel source) { - return new Map(source); - } - public Map[] newArray(int size) { - return new Map[size]; - } - - }; -} diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/EngineProtocol/PascalExports.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/EngineProtocol/PascalExports.java Sun Oct 09 20:41:17 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* - * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game - * Copyright (c) 2011 Richard Deurwaarder - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -package org.hedgewars.mobile.EngineProtocol; - -public class PascalExports { - - static{ - System.loadLibrary("SDL"); - System.loadLibrary("SDL_image"); - System.loadLibrary("mikmod"); - System.loadLibrary("SDL_net"); - System.loadLibrary("SDL_mixer"); - System.loadLibrary("SDL_ttf"); - System.loadLibrary("lua5.1"); - System.loadLibrary("hwengine"); - } - - public static native int HWversionInfoNetProto(); - public static native String HWversionInfoVersion(); - public static native int HWgetNumberOfWeapons(); - public static native int HWgetMaxNumberOfTeams(); - public static native int HWgetMaxNumberOfHogs(); - public static native int HWterminate(boolean b); -} diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/EngineProtocol/Scheme.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/EngineProtocol/Scheme.java Sun Oct 09 20:41:17 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,358 +0,0 @@ -/* - * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game - * Copyright (c) 2011 Richard Deurwaarder - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -package org.hedgewars.mobile.EngineProtocol; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.FilenameFilter; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.LinkedHashMap; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; -import org.xmlpull.v1.XmlPullParserFactory; - -import android.content.Context; -import android.os.Parcel; -import android.os.Parcelable; - -public class Scheme implements Parcelable{ - - public static final String DIRECTORY_SCHEME = "schemes"; - - private String name; - //private ArrayList basic; - private Integer gamemod; - private ArrayList basic;; - private static ArrayList> basicflags = new ArrayList>(); - - public Scheme(String _name, ArrayList _basic, int _gamemod){ - name = _name; - gamemod = _gamemod; - basic = _basic; - - } - - public Scheme(Parcel in){ - readFromParcel(in); - } - - public void sendToEngine(EngineProtocolNetwork epn)throws IOException{ - epn.sendToEngine(String.format("e$gmflags %d", gamemod)); - - for(int pos = 0; pos < basic.size(); pos++){ - LinkedHashMap basicflag = basicflags.get(pos); - - String command = (String)basicflag.get("command"); - Integer value = basic.get(pos); - Boolean checkOverMax = (Boolean) basicflag.get("checkOverMax"); - Boolean times1000 = (Boolean) basicflag.get("times1000"); - Integer max = (Integer) basicflag.get("max"); - - if(checkOverMax && value >= max) value = max; - if(times1000) value *= 1000; - - epn.sendToEngine(String.format("%s %d", command, value)); - } - } - public String toString(){ - return name; - } - - - public static final int STATE_START = 0; - public static final int STATE_ROOT = 1; - public static final int STATE_NAME = 2; - public static final int STATE_BASICFLAGS = 3; - public static final int STATE_GAMEMOD = 4; - public static final int STATE_BASICFLAG_INTEGER = 5; - public static final int STATE_GAMEMOD_TRUE = 6; - public static final int STATE_GAMEMOD_FALSE = 7; - - public static ArrayList getSchemes(Context c) throws IllegalArgumentException{ - String dir = c.getFilesDir().getAbsolutePath() + '/' + DIRECTORY_SCHEME + '/'; - String[] files = new File(dir).list(fnf); - if(files == null) files = new String[]{}; - Arrays.sort(files); - ArrayList schemes = new ArrayList(); - - try { - XmlPullParserFactory xmlPullFactory = XmlPullParserFactory.newInstance(); - XmlPullParser xmlPuller = xmlPullFactory.newPullParser(); - - for(String file : files){ - BufferedReader br = new BufferedReader(new FileReader(dir + file), 1024); - xmlPuller.setInput(br); - String name = null; - ArrayList basic = new ArrayList(); - Integer gamemod = 0; - int mask = 0x000000004; - - int eventType = xmlPuller.getEventType(); - int state = STATE_START; - while(eventType != XmlPullParser.END_DOCUMENT){ - switch(state){ - case STATE_START: - if(eventType == XmlPullParser.START_TAG && xmlPuller.getName().equals("scheme")) state = STATE_ROOT; - else if(eventType != XmlPullParser.START_DOCUMENT) throwException(file, eventType); - break; - case STATE_ROOT: - if(eventType == XmlPullParser.START_TAG){ - if(xmlPuller.getName().equals("basicflags")) state = STATE_BASICFLAGS; - else if(xmlPuller.getName().toLowerCase().equals("gamemod")) state = STATE_GAMEMOD; - else if(xmlPuller.getName().toLowerCase().equals("name")) state = STATE_NAME; - else throwException(file, eventType); - }else if(eventType == XmlPullParser.END_TAG) state = STATE_START; - else throwException(xmlPuller.getText(), eventType); - break; - case STATE_BASICFLAGS: - if(eventType == XmlPullParser.START_TAG && xmlPuller.getName().toLowerCase().equals("integer")) state = STATE_BASICFLAG_INTEGER; - else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT; - else throwException(file, eventType); - break; - case STATE_GAMEMOD: - if(eventType == XmlPullParser.START_TAG){ - if(xmlPuller.getName().toLowerCase().equals("true")) state = STATE_GAMEMOD_TRUE; - else if(xmlPuller.getName().toLowerCase().equals("false")) state = STATE_GAMEMOD_FALSE; - else throwException(file, eventType); - }else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT; - else throwException(file, eventType); - break; - case STATE_NAME: - if(eventType == XmlPullParser.TEXT) name = xmlPuller.getText().trim(); - else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT; - else throwException(file, eventType); - break; - case STATE_BASICFLAG_INTEGER: - if(eventType == XmlPullParser.TEXT) basic.add(Integer.parseInt(xmlPuller.getText().trim())); - else if(eventType == XmlPullParser.END_TAG) state = STATE_BASICFLAGS; - else throwException(file, eventType); - break; - case STATE_GAMEMOD_FALSE: - if(eventType == XmlPullParser.TEXT) gamemod <<= 1; - else if(eventType == XmlPullParser.END_TAG) state = STATE_GAMEMOD; - else throwException(file, eventType); - break; - case STATE_GAMEMOD_TRUE: - if(eventType == XmlPullParser.TEXT){ - gamemod |= mask; - gamemod <<= 1; - }else if(eventType == XmlPullParser.END_TAG) state = STATE_GAMEMOD; - else throwException(file, eventType); - break; - } - eventType = getEventType(xmlPuller); - }//end while(eventtype != END_DOCUMENT - schemes.add(new Scheme(name, basic, gamemod)); - }//end for(string file : files - return schemes; - } catch (XmlPullParserException e) { - e.printStackTrace(); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - return new ArrayList();//TODO handle correctly - } - - private static FilenameFilter fnf = new FilenameFilter(){ - public boolean accept(File dir, String filename) { - return filename.toLowerCase().startsWith("scheme_"); - } - }; - - /** - * This method will parse the basic flags from a prespecified xml file. - * I use a raw xml file rather than one parsed by aatp at compile time - * to keep it generic with other frontends, ie in the future we could - * use one provided by the Data folder. - */ - public static void parseBasicFlags(Context c){ - String filename = String.format("%s/%s/basicflags", c.getFilesDir().getAbsolutePath(), DIRECTORY_SCHEME); - - XmlPullParser xmlPuller = null; - BufferedReader br = null; - try { - XmlPullParserFactory xmlPullFactory = XmlPullParserFactory.newInstance(); - xmlPuller = xmlPullFactory.newPullParser(); - br = new BufferedReader(new FileReader(filename), 1024); - xmlPuller.setInput(br); - - int eventType = getEventType(xmlPuller); - boolean continueParsing = true; - do{ - switch(eventType){ - - case XmlPullParser.START_TAG: - if(xmlPuller.getName().toLowerCase().equals("flag")){ - basicflags.add(parseFlag(xmlPuller)); - }else if(xmlPuller.getName().toLowerCase().equals("basicflags")){ - eventType = getEventType(xmlPuller); - }else{ - skipCurrentTag(xmlPuller); - eventType = getEventType(xmlPuller); - } - break; - case XmlPullParser.START_DOCUMENT://ignore all tags not being "flag" - case XmlPullParser.END_TAG: - case XmlPullParser.TEXT: - default: - continueParsing = true; - case XmlPullParser.END_DOCUMENT: - continueParsing = false; - } - }while(continueParsing); - - }catch(IOException e){ - e.printStackTrace(); - }catch (XmlPullParserException e) { - e.printStackTrace(); - }finally{ - if(br != null) - try { - br.close(); - } catch (IOException e) {} - } - - } - - /* - * * Parses a Tag structure from xml as example we use - * - * - * false - * - * - * - * It returns a LinkedHashMap with key/value pairs - */ - private static LinkedHashMap parseFlag(XmlPullParser xmlPuller)throws XmlPullParserException, IOException{ - LinkedHashMap hash = new LinkedHashMap(); - - int eventType = xmlPuller.getEventType();//Get the event type which triggered this method - if(eventType == XmlPullParser.START_TAG && xmlPuller.getName().toLowerCase().equals("flag")){//valid start of flag tag - String lcKey = null; - String lcType = null; - String value = null; - - eventType = getEventType(xmlPuller);// - while(eventType == XmlPullParser.START_TAG){ - lcKey = xmlPuller.getName();//checkOverMax - if(getEventType(xmlPuller) == XmlPullParser.START_TAG){// - lcType = xmlPuller.getName().toLowerCase(); - if(getEventType(xmlPuller) == XmlPullParser.TEXT){ - value = xmlPuller.getText(); - if(getEventType(xmlPuller) == XmlPullParser.END_TAG && // - getEventType(xmlPuller) == XmlPullParser.END_TAG){// - if(lcType.equals("boolean")) hash.put(lcKey, new Boolean(value)); - else if(lcType.equals("string"))hash.put(lcKey, value); - else if(lcType.equals("integer")){ - try{ - hash.put(lcKey, new Integer(value)); - }catch (NumberFormatException e){ - throw new XmlPullParserException("Wrong integer value in xml file"); - } - }else{ - throwException("basicflags", eventType); - } - }// / - }//if TEXT - }//if boolean - eventType = getEventType(xmlPuller);//start new loop - } - eventType = getEventType(xmlPuller);// - } - - return hash; - } - - private static void skipCurrentTag(XmlPullParser xmlPuller) throws XmlPullParserException, IOException{ - int eventType = xmlPuller.getEventType(); - if(eventType != XmlPullParser.START_TAG)return; - String tag = xmlPuller.getName().toLowerCase(); - - while(true){ - eventType = getEventType(xmlPuller);//getNext() - switch(eventType){ - case XmlPullParser.START_DOCUMENT://we're inside of a start tag so START_ or END_DOCUMENT is just wrong - case XmlPullParser.END_DOCUMENT: - throw new XmlPullParserException("invalid xml file"); - case XmlPullParser.START_TAG://if we get a new tag recursively handle it - skipCurrentTag(xmlPuller); - break; - case XmlPullParser.TEXT: - break; - case XmlPullParser.END_TAG: - if(!xmlPuller.getName().toLowerCase().equals(tag)){//if the end tag doesn't match the start tag - throw new XmlPullParserException("invalid xml file"); - }else{ - return;//skip completed - } - - } - } - } - - /** - * Skips whitespaces.. - */ - private static int getEventType(XmlPullParser xmlPuller)throws XmlPullParserException, IOException{ - int eventType = xmlPuller.next(); - while(eventType == XmlPullParser.TEXT && xmlPuller.isWhitespace()){ - eventType = xmlPuller.next(); - } - return eventType; - } - private static void throwException(String file, int eventType){ - throw new IllegalArgumentException(String.format("Xml file: %s malformed with error: %d.", file, eventType)); - } - - public int describeContents() { - // TODO Auto-generated method stub - return 0; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(name); - dest.writeInt(gamemod); - dest.writeList(basic); - - } - - public void readFromParcel(Parcel src){ - name = src.readString(); - gamemod = src.readInt(); - basic = src.readArrayList(ArrayList.class.getClassLoader()); - } - - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - public Scheme createFromParcel(Parcel source) { - return new Scheme(source); - } - public Scheme[] newArray(int size) { - return new Scheme[size]; - } - - }; -} diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/EngineProtocol/Team.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/EngineProtocol/Team.java Sun Oct 09 20:41:17 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,345 +0,0 @@ -/* - * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game - * Copyright (c) 2011 Richard Deurwaarder - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -package org.hedgewars.mobile.EngineProtocol; - -import java.io.BufferedReader; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; -import org.xmlpull.v1.XmlPullParserFactory; -import org.xmlpull.v1.XmlSerializer; - -import android.os.Parcel; -import android.os.Parcelable; -import android.util.Xml; - -public class Team implements Parcelable{ - - public static final String DIRECTORY_TEAMS = "teams"; - private static final Integer[] TEAM_COLORS = { - 0xd12b42, /* red */ - 0x4980c1, /* blue */ - 0x6ab530, /* green */ - 0xbc64c4, /* purple */ - 0xe76d14, /* orange */ - 0x3fb6e6, /* cyan */ - 0xe3e90c, /* yellow */ - 0x61d4ac, /* mint */ - 0xf1c3e1, /* pink */ - /* add new colors here */ - }; - -// private static final Integer[] TEAM_COLORS = { -// 0xff0000, /* red */ -// 0x00ff00, /* blue */ -// 0x0000ff, /* green */ -// }; - - private static final int STATE_START = 0; - private static final int STATE_ROOT = 1; - private static final int STATE_HOG_ROOT = 2; - - public String name, grave, flag, voice, fort, hash; - - public static int maxNumberOfHogs = 0; - public static int maxNumberOfTeams = 0; - - static{ - maxNumberOfHogs = PascalExports.HWgetMaxNumberOfHogs(); - maxNumberOfTeams = PascalExports.HWgetMaxNumberOfTeams(); - } - public String[] hats = new String[maxNumberOfHogs]; - public String[] hogNames = new String[maxNumberOfHogs]; - public int[] levels = new int[maxNumberOfHogs]; - - public int hogCount = 4; - public int color = TEAM_COLORS[0]; - - public Team(){ - } - - public Team(Parcel in){ - readFromParcel(in); - } - - public boolean equals(Object o){ - if(super.equals(o)) return true; - else if(o instanceof Team){ - Team t = (Team)o; - boolean ret = name.equals(t.name); - ret &= grave.equals(t.grave); - ret &= flag.equals(t.flag); - ret &= voice.equals(t.voice); - ret &= fort.equals(t.fort); - ret &= hash.equals(t.hash); - return ret; - }else{ - return false; - } - } - - public void setRandomColor(int[] illegalcolors){ - Integer[] colorsToPickFrom = TEAM_COLORS; - if(illegalcolors != null){ - ArrayList colors = new ArrayList(); - for(int color : TEAM_COLORS){ - boolean validColor = true; - for(int illegal : illegalcolors){ - if(color == illegal) validColor = false; - } - if(validColor) colors.add(color); - } - if(colors.size() != 0) colorsToPickFrom = colors.toArray(new Integer[1]); - } - int index = (int)Math.round(Math.random()*(colorsToPickFrom.length-1)); - color = colorsToPickFrom[index]; - } - - - public void sendToEngine(EngineProtocolNetwork epn, int hogCount, int health) throws IOException{ - epn.sendToEngine(String.format("eaddteam %s %d %s", hash, color, name)); - epn.sendToEngine(String.format("egrave %s", grave)); - epn.sendToEngine(String.format("efort %s", fort)); - epn.sendToEngine(String.format("evoicepack %s", voice)); - epn.sendToEngine(String.format("eflag %s", flag)); - - for(int i = 0; i < hogCount; i++){ - epn.sendToEngine(String.format("eaddhh %d %d %s", levels[i], health, hogNames[i])); - epn.sendToEngine(String.format("ehat %s", hats[i])); - } - } - - /* - * XML METHODS - */ - - /** - * Read the xml file path and convert it to a Team object - * @param path absolute path to the xml file - * @return - */ - public static Team getTeamFromXml(String path){ - try { - XmlPullParserFactory xmlPullFactory = XmlPullParserFactory.newInstance(); - XmlPullParser xmlPuller = xmlPullFactory.newPullParser(); - - BufferedReader br = new BufferedReader(new FileReader(path), 1024); - xmlPuller.setInput(br); - Team team = new Team(); - int hogCounter = 0; - - int eventType = xmlPuller.getEventType(); - int state = STATE_START; - while(eventType != XmlPullParser.END_DOCUMENT){ - switch(state){ - case STATE_START: - if(eventType == XmlPullParser.START_TAG && xmlPuller.getName().equals("team")) state = STATE_ROOT; - else if(eventType != XmlPullParser.START_DOCUMENT) throwException(path, eventType); - break; - case STATE_ROOT: - if(eventType == XmlPullParser.START_TAG){ - if(xmlPuller.getName().toLowerCase().equals("name")){ - team.name = getXmlText(xmlPuller, "name"); - }else if(xmlPuller.getName().toLowerCase().equals("flag")){ - team.flag= getXmlText(xmlPuller, "flag"); - }else if(xmlPuller.getName().toLowerCase().equals("voice")){ - team.voice = getXmlText(xmlPuller, "voice"); - }else if(xmlPuller.getName().toLowerCase().equals("grave")){ - team.grave = getXmlText(xmlPuller, "grave"); - }else if(xmlPuller.getName().toLowerCase().equals("fort")){ - team.fort = getXmlText(xmlPuller, "fort"); - }else if(xmlPuller.getName().toLowerCase().equals("hash")){ - team.hash = getXmlText(xmlPuller, "hash"); - }else if(xmlPuller.getName().toLowerCase().equals("hog")){ - state = STATE_HOG_ROOT; - }else throwException(xmlPuller.getName(), eventType); - }else if(eventType == XmlPullParser.END_TAG) state = STATE_START; - else throwException(xmlPuller.getText(), eventType); - break; - case STATE_HOG_ROOT: - if(eventType == XmlPullParser.START_TAG){ - if(xmlPuller.getName().toLowerCase().equals("name")){ - team.hogNames[hogCounter] = getXmlText(xmlPuller, "name"); - }else if(xmlPuller.getName().toLowerCase().equals("hat")){ - team.hats[hogCounter] = getXmlText(xmlPuller, "hat"); - }else if(xmlPuller.getName().toLowerCase().equals("level")){ - team.levels[hogCounter] = Integer.parseInt(getXmlText(xmlPuller, "level")); - }else throwException(xmlPuller.getText(), eventType); - }else if(eventType == XmlPullParser.END_TAG){ - hogCounter++; - state = STATE_ROOT; - }else throwException(xmlPuller.getText(), eventType); - break; - } - eventType = getEventType(xmlPuller); - }//end while(eventtype != END_DOCUMENT - return team; - } catch (NumberFormatException e){ - e.printStackTrace(); - } catch (XmlPullParserException e) { - e.printStackTrace(); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - return null; - } - - private static String getXmlText(XmlPullParser xmlPuller, String parentTag)throws XmlPullParserException, IOException{ - if(getEventType(xmlPuller) == XmlPullParser.TEXT){ - String txt = xmlPuller.getText(); - if(getEventType(xmlPuller) == XmlPullParser.END_TAG && xmlPuller.getName().toLowerCase().equals(parentTag)){ - return txt; - } - } - throw new XmlPullParserException("malformed xml file on string read from tag: " + parentTag); - } - - /** - * Skips whitespaces.. - */ - private static int getEventType(XmlPullParser xmlPuller)throws XmlPullParserException, IOException{ - int eventType = xmlPuller.next(); - while(eventType == XmlPullParser.TEXT && xmlPuller.isWhitespace()){ - eventType = xmlPuller.next(); - } - return eventType; - } - - private static void throwException(String file, int eventType){ - throw new IllegalArgumentException(String.format("Xml file: %s malformed with error: %d.", file, eventType)); - } - - public void writeToXml(OutputStream os){ - XmlSerializer serializer = Xml.newSerializer(); - try{ - serializer.setOutput(os, "UTF-8"); - serializer.startDocument("UTF-8", true); - serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); - - serializer.startTag(null, "team"); - serializer.startTag(null, "name"); - serializer.text(name); - serializer.endTag(null, "name"); - serializer.startTag(null, "flag"); - serializer.text(flag); - serializer.endTag(null, "flag"); - serializer.startTag(null, "fort"); - serializer.text(fort); - serializer.endTag(null, "fort"); - serializer.startTag(null, "grave"); - serializer.text(grave); - serializer.endTag(null, "grave"); - serializer.startTag(null, "voice"); - serializer.text(voice); - serializer.endTag(null, "voice"); - serializer.startTag(null, "hash"); - serializer.text(hash); - serializer.endTag(null, "hash"); - - for(int i = 0; i < maxNumberOfHogs; i++){ - serializer.startTag(null, "hog"); - serializer.startTag(null, "name"); - serializer.text(hogNames[i]); - serializer.endTag(null, "name"); - serializer.startTag(null, "hat"); - serializer.text(hats[i]); - serializer.endTag(null, "hat"); - serializer.startTag(null, "level"); - serializer.text(String.valueOf(levels[i])); - serializer.endTag(null, "level"); - - serializer.endTag(null, "hog"); - } - serializer.endTag(null, "team"); - serializer.endDocument(); - serializer.flush(); - - } catch (IOException e) { - e.printStackTrace(); - }finally{ - try { - os.close(); - } catch (IOException e) {} - } - } - /* - * END XML METHODS - */ - - - - /* - * PARCABLE METHODS - */ - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(name); - dest.writeString(grave); - dest.writeString(flag); - dest.writeString(voice); - dest.writeString(fort); - dest.writeString(hash); - dest.writeStringArray(hats); - dest.writeStringArray(hogNames); - dest.writeIntArray(levels); - dest.writeInt(color); - dest.writeInt(hogCount); - } - - - public void readFromParcel(Parcel src){ - name = src.readString(); - grave = src.readString(); - flag = src.readString(); - voice = src.readString(); - fort = src.readString(); - hash = src.readString(); - src.readStringArray(hats); - src.readStringArray(hogNames); - src.readIntArray(levels); - color = src.readInt(); - hogCount = src.readInt(); - } - - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - public Team createFromParcel(Parcel source) { - return new Team(source); - } - public Team[] newArray(int size) { - return new Team[size]; - } - - }; - - /* - * END PARCABLE METHODS - */ - -} diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/EngineProtocol/Weapon.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/EngineProtocol/Weapon.java Sun Oct 09 20:41:17 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,212 +0,0 @@ -/* - * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game - * Copyright (c) 2011 Richard Deurwaarder - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -package org.hedgewars.mobile.EngineProtocol; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; -import org.xmlpull.v1.XmlPullParserFactory; - -import android.content.Context; -import android.os.Parcel; -import android.os.Parcelable; - -public class Weapon implements Parcelable{ - - public static final String DIRECTORY_WEAPON = "weapons"; - - private String name; - private String QT; - private String prob; - private String delay; - private String crate; - private static int maxWeapons; - - static{ - //maxWeapons = PascalExports.HWgetNumberOfWeapons(); - } - - public Weapon(String _name, String _QT, String _prob, String _delay, String _crate){ - name = _name; - - //Incase there's a newer ammoStore which is bigger we append with zeros - StringBuffer sb = new StringBuffer(); - while(_QT.length() + sb.length() < maxWeapons){ - sb.append('0'); - } - - QT = String.format("e%s %s%s", "ammloadt", _QT, sb); - prob = String.format("e%s %s%s", "ammprob", _prob, sb); - delay = String.format("e%s %s%s", "ammdelay", _delay, sb); - crate = String.format("e%s %s%s", "ammreinf", _crate, sb); - } - - public Weapon(Parcel in){ - readFromParcel(in); - } - - public String toString(){ - return name; - } - - public void sendToEngine(EngineProtocolNetwork epn, int teamsCount) throws IOException{ - epn.sendToEngine(QT);//command prefix is already in string - epn.sendToEngine(prob); - epn.sendToEngine(delay); - epn.sendToEngine(crate); - - for(int i = 0; i < teamsCount; i++){ - epn.sendToEngine("eammstore"); - } - } - - public static final int STATE_START = 0; - public static final int STATE_ROOT = 1; - public static final int STATE_NAME = 2; - public static final int STATE_QT = 3; - public static final int STATE_PROBABILITY = 4; - public static final int STATE_DELAY = 5; - public static final int STATE_CRATE = 6; - - public static ArrayList getWeapons(Context c) throws IllegalArgumentException{ - String dir = c.getFilesDir().getAbsolutePath() + '/' + DIRECTORY_WEAPON + '/'; - String[] files = new File(dir).list(); - if(files == null) files = new String[]{}; - Arrays.sort(files); - - ArrayList weapons = new ArrayList(); - - try { - XmlPullParserFactory xmlPullFactory = XmlPullParserFactory.newInstance(); - XmlPullParser xmlPuller = xmlPullFactory.newPullParser(); - - for(String file : files){ - BufferedReader br = new BufferedReader(new FileReader(dir + file), 1024); - xmlPuller.setInput(br); - String name = null; - String qt = null; - String prob = null; - String delay = null; - String crate = null; - - int eventType = xmlPuller.getEventType(); - int state = STATE_START; - while(eventType != XmlPullParser.END_DOCUMENT){ - switch(state){ - case STATE_START: - if(eventType == XmlPullParser.START_TAG && xmlPuller.getName().equals("weapon")) state = STATE_ROOT; - else if(eventType != XmlPullParser.START_DOCUMENT) throwException(file, eventType); - break; - case STATE_ROOT: - if(eventType == XmlPullParser.START_TAG){ - if(xmlPuller.getName().toLowerCase().equals("qt")) state = STATE_QT; - else if(xmlPuller.getName().toLowerCase().equals("name")) state = STATE_NAME; - else if(xmlPuller.getName().toLowerCase().equals("probability")) state = STATE_PROBABILITY; - else if(xmlPuller.getName().toLowerCase().equals("delay")) state = STATE_DELAY; - else if(xmlPuller.getName().toLowerCase().equals("crate")) state = STATE_CRATE; - else throwException(file, eventType); - }else if(eventType == XmlPullParser.END_TAG) state = STATE_START; - else throwException(xmlPuller.getText(), eventType); - break; - case STATE_NAME: - if(eventType == XmlPullParser.TEXT) name = xmlPuller.getText().trim(); - else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT; - else throwException(file, eventType); - break; - case STATE_QT: - if(eventType == XmlPullParser.TEXT) qt = xmlPuller.getText().trim(); - else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT; - else throwException(file, eventType); - break; - case STATE_PROBABILITY: - if(eventType == XmlPullParser.TEXT) prob = xmlPuller.getText().trim(); - else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT; - else throwException(file, eventType); - break; - case STATE_DELAY: - if(eventType == XmlPullParser.TEXT) delay = xmlPuller.getText().trim(); - else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT; - else throwException(file, eventType); - break; - case STATE_CRATE: - if(eventType == XmlPullParser.TEXT) crate = xmlPuller.getText().trim(); - else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT; - else throwException(file, eventType); - break; - } - eventType = xmlPuller.next(); - while(eventType == XmlPullParser.TEXT && xmlPuller.isWhitespace()){//Skip whitespaces - eventType = xmlPuller.next(); - } - }//end while(eventtype != END_DOCUMENT - weapons.add(new Weapon(name, qt, prob, delay, crate)); - }//end for(string file : files - return weapons; - - } catch (XmlPullParserException e) { - e.printStackTrace(); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - return new ArrayList();//TODO handle correctly - } - - private static void throwException(String file, int eventType){ - throw new IllegalArgumentException(String.format("Xml file: %s malformed with eventType: %d.", file, eventType)); - } - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(name); - dest.writeString(QT); - dest.writeString(prob); - dest.writeString(delay); - dest.writeString(crate); - } - - private void readFromParcel(Parcel src){ - name = src.readString(); - QT = src.readString(); - prob = src.readString(); - delay = src.readString(); - crate = src.readString(); - } - - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - public Weapon createFromParcel(Parcel source) { - return new Weapon(source); - } - public Weapon[] newArray(int size) { - return new Weapon[size]; - } - - }; -} diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/MainActivity.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/MainActivity.java Sun Oct 09 20:41:17 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -/* - * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game - * Copyright (c) 2011 Richard Deurwaarder - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -package org.hedgewars.mobile; - -import org.hedgewars.mobile.Downloader.DownloadActivity; -import org.hedgewars.mobile.Downloader.DownloadService; - -import android.app.Activity; -import android.content.Intent; -import android.os.Bundle; -import android.preference.PreferenceManager; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.Button; -import android.widget.Toast; - -public class MainActivity extends Activity { - - Button downloader, startGame; - - public void onCreate(Bundle sis){ - super.onCreate(sis); - setContentView(R.layout.main); - - downloader = (Button)findViewById(R.id.downloader); - startGame = (Button)findViewById(R.id.startGame); - - downloader.setOnClickListener(downloadClicker); - startGame.setOnClickListener(startGameClicker); - } - - - - private OnClickListener downloadClicker = new OnClickListener(){ - public void onClick(View v){ - startActivityForResult(new Intent(getApplicationContext(), DownloadActivity.class), 0); - } - }; - - private OnClickListener startGameClicker = new OnClickListener(){ - public void onClick(View v){ - if(PreferenceManager.getDefaultSharedPreferences(MainActivity.this).getBoolean(DownloadService.PREF_DOWNLOADED, false)) - startActivity(new Intent(getApplicationContext(), StartGameActivity.class)); - else { - Toast.makeText(MainActivity.this, R.string.download_userexplain, Toast.LENGTH_LONG).show(); - startActivityForResult(new Intent(getApplicationContext(), DownloadActivity.class), 0); - } - } - }; - -} diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/SDLActivity.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/SDLActivity.java Sun Oct 09 20:41:17 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,565 +0,0 @@ -package org.hedgewars.mobile; - -import javax.microedition.khronos.egl.EGL10; -import javax.microedition.khronos.egl.EGLConfig; -import javax.microedition.khronos.egl.EGLContext; -import javax.microedition.khronos.egl.EGLDisplay; -import javax.microedition.khronos.egl.EGLSurface; - -import org.hedgewars.mobile.EngineProtocol.EngineProtocolNetwork; -import org.hedgewars.mobile.EngineProtocol.GameConfig; -import org.hedgewars.mobile.EngineProtocol.PascalExports; -import org.hedgewars.mobile.TouchInterface.TouchInterface; - -import android.app.Activity; -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.PixelFormat; -import android.hardware.Sensor; -import android.hardware.SensorEvent; -import android.hardware.SensorEventListener; -import android.hardware.SensorManager; -import android.media.AudioFormat; -import android.media.AudioManager; -import android.media.AudioTrack; -import android.os.Bundle; -import android.os.Handler; -import android.os.Message; -import android.util.Log; -import android.view.KeyEvent; -import android.view.SurfaceHolder; -import android.view.SurfaceView; -import android.view.View; - -/** - * SDL Activity - */ -public class SDLActivity extends Activity { - - // Main components - public static SDLActivity mSingleton; - public static SDLSurface mSurface; - - // Audio - private static Thread mAudioThread; - private static AudioTrack mAudioTrack; - - // Load the .so - static { - System.loadLibrary("SDL"); - System.loadLibrary("SDL_image"); - System.loadLibrary("mikmod"); - System.loadLibrary("SDL_net"); - System.loadLibrary("SDL_mixer"); - System.loadLibrary("SDL_ttf"); - System.loadLibrary("lua5.1"); - System.loadLibrary("hwengine"); - System.loadLibrary("main"); - } - - // Setup - protected void onCreate(Bundle savedInstanceState) { - // Log.v("SDL", "onCreate()"); - super.onCreate(savedInstanceState); - - // So we can call stuff from static callbacks - mSingleton = this; - - // Set up the surface - GameConfig config = getIntent().getParcelableExtra("config"); - mSurface = new SDLSurface(getApplication(), config); - setContentView(mSurface); - SurfaceHolder holder = mSurface.getHolder(); - holder.setType(SurfaceHolder.SURFACE_TYPE_GPU); - } - - // Events - protected void onPause() { - // Log.v("SDL", "onPause()"); - super.onPause(); - - } - - protected void onResume() { - // Log.v("SDL", "onResume()"); - super.onResume(); - } - - public void onBackPressed(){ - nativeQuit(); - super.onBackPressed(); - } - - // Messages from the SDLMain thread - static int COMMAND_CHANGE_TITLE = 1; - - // Handler for the messages - Handler commandHandler = new Handler() { - public void handleMessage(Message msg) { - if (msg.arg1 == COMMAND_CHANGE_TITLE) { - setTitle((String) msg.obj); - } - } - }; - - // Send a message from the SDLMain thread - void sendCommand(int command, Object data) { - Message msg = commandHandler.obtainMessage(); - msg.arg1 = command; - msg.obj = data; - commandHandler.sendMessage(msg); - } - - // C functions we call - public static native void nativeInit(String[] argv); - - public static native void nativeQuit(); - - public static native void onNativeResize(int x, int y, int format); - - public static native void onNativeKeyDown(int keycode); - - public static native void onNativeKeyUp(int keycode); - - public static native void onNativeTouch(int action, int pointer, float x, float y, - float p); - - public static native void onNativeAccel(float x, float y, float z); - - public static native void nativeRunAudioThread(); - - // Java functions called from C - - public static boolean createGLContext(int majorVersion, int minorVersion) { - return mSurface.initEGL(majorVersion, minorVersion); - } - - public static void flipBuffers() { - mSurface.flipEGL(); - } - - public static void setActivityTitle(String title) { - // Called from SDLMain() thread and can't directly affect the view - mSingleton.sendCommand(COMMAND_CHANGE_TITLE, title); - } - - // Audio - private static Object buf; - - public static Object audioInit(int sampleRate, boolean is16Bit, - boolean isStereo, int desiredFrames) { - int channelConfig = isStereo ? AudioFormat.CHANNEL_CONFIGURATION_STEREO - : AudioFormat.CHANNEL_CONFIGURATION_MONO; - int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT - : AudioFormat.ENCODING_PCM_8BIT; - int frameSize = (isStereo ? 2 : 1) * (is16Bit ? 2 : 1); - - Log.v("SDL", "SDL audio: wanted " + (isStereo ? "stereo" : "mono") - + " " + (is16Bit ? "16-bit" : "8-bit") + " " - + ((float) sampleRate / 1000f) + "kHz, " + desiredFrames - + " frames buffer"); - - // Let the user pick a larger buffer if they really want -- but ye - // gods they probably shouldn't, the minimums are horrifyingly high - // latency already - desiredFrames = Math.max( - desiredFrames, - (AudioTrack.getMinBufferSize(sampleRate, channelConfig, - audioFormat) + frameSize - 1) - / frameSize); - - mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, - channelConfig, audioFormat, desiredFrames * frameSize, - AudioTrack.MODE_STREAM); - - audioStartThread(); - - Log.v("SDL", - "SDL audio: got " - + ((mAudioTrack.getChannelCount() >= 2) ? "stereo" - : "mono") - + " " - + ((mAudioTrack.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT) ? "16-bit" - : "8-bit") + " " - + ((float) mAudioTrack.getSampleRate() / 1000f) - + "kHz, " + desiredFrames + " frames buffer"); - - if (is16Bit) { - buf = new short[desiredFrames * (isStereo ? 2 : 1)]; - } else { - buf = new byte[desiredFrames * (isStereo ? 2 : 1)]; - } - return buf; - } - - public static void audioStartThread() { - mAudioThread = new Thread(new Runnable() { - public void run() { - mAudioTrack.play(); - nativeRunAudioThread(); - } - }); - - // I'd take REALTIME if I could get it! - mAudioThread.setPriority(Thread.MAX_PRIORITY); - mAudioThread.start(); - } - - public static void audioWriteShortBuffer(short[] buffer) { - for (int i = 0; i < buffer.length;) { - int result = mAudioTrack.write(buffer, i, buffer.length - i); - if (result > 0) { - i += result; - } else if (result == 0) { - try { - Thread.sleep(1); - } catch (InterruptedException e) { - // Nom nom - } - } else { - Log.w("SDL", "SDL audio: error return from write(short)"); - return; - } - } - } - - public static void audioWriteByteBuffer(byte[] buffer) { - for (int i = 0; i < buffer.length;) { - int result = mAudioTrack.write(buffer, i, buffer.length - i); - if (result > 0) { - i += result; - } else if (result == 0) { - try { - Thread.sleep(1); - } catch (InterruptedException e) { - // Nom nom - } - } else { - Log.w("SDL", "SDL audio: error return from write(short)"); - return; - } - } - } - - public static void audioQuit() { - if (mAudioThread != null) { - try { - mAudioThread.join(); - } catch (Exception e) { - Log.v("SDL", "Problem stopping audio thread: " + e); - } - mAudioThread = null; - - // Log.v("SDL", "Finished waiting for audio thread"); - } - - if (mAudioTrack != null) { - mAudioTrack.stop(); - mAudioTrack = null; - } - } -} - -/** - * Simple nativeInit() runnable - */ -class SDLMain implements Runnable { - private int surfaceWidth, surfaceHeight; - private GameConfig config; - - public SDLMain(int width, int height, GameConfig _config) { - config = _config; - surfaceWidth = width; - surfaceHeight = height; - } - - public void run() { - //Set up the IPC socket server to communicate with the engine - EngineProtocolNetwork ipc = new EngineProtocolNetwork(config); - - String path = Utils.getDownloadPath(SDLActivity.mSingleton);//This represents the data directory - path = path.substring(0, path.length()-1);//remove the trailing '/' - - - // Runs SDL_main() with added parameters - SDLActivity.nativeInit(new String[] { String.valueOf(ipc.port), - String.valueOf(surfaceWidth), String.valueOf(surfaceHeight), - "0", "null", "xeli", "1", "1", "1", path, "" }); - - try { - ipc.quitIPC(); - ipc.join(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - //Log.v("SDL", "SDL thread terminated"); - SDLActivity.mSingleton.finish(); - } -} - -/** - * SDLSurface. This is what we draw on, so we need to know when it's created in - * order to do anything useful. - * - * Because of this, that's where we set up the SDL thread - */ -class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, - View.OnKeyListener, SensorEventListener { - - // This is what SDL runs in. It invokes SDL_main(), eventually - private Thread mSDLThread; - - // EGL private objects - private EGLContext mEGLContext; - private EGLSurface mEGLSurface; - private EGLDisplay mEGLDisplay; - - // Sensors - private static SensorManager mSensorManager; - - private GameConfig config; - - // Startup - public SDLSurface(Context context, GameConfig _config) { - super(context); - getHolder().addCallback(this); - - setFocusable(true); - setFocusableInTouchMode(true); - requestFocus(); - setOnKeyListener(this); - setOnTouchListener(TouchInterface.getTouchInterface()); - - mSensorManager = (SensorManager) context.getSystemService("sensor"); - - config = _config; - } - - // Called when we have a valid drawing surface - public void surfaceCreated(SurfaceHolder holder) { - Log.v("SDL", "surfaceCreated()"); - - //enableSensor(Sensor.TYPE_ACCELEROMETER, true); - } - - // Called when we lose the surface - public void surfaceDestroyed(SurfaceHolder holder) { - Log.v("SDL", "surfaceDestroyed()"); - - // Send a quit message to the application - //SDLActivity.nativeQuit(); - PascalExports.HWterminate(true); - - // Now wait for the SDL thread to quit - if (mSDLThread != null) { - try { - mSDLThread.join(); - } catch (Exception e) { - Log.v("SDL", "Problem stopping thread: " + e); - } - mSDLThread = null; - - Log.v("SDL", "Finished waiting for SDL thread"); - } - - //enableSensor(Sensor.TYPE_ACCELEROMETER, false); - } - - // Called when the surface is resized - public void surfaceChanged(SurfaceHolder holder, int format, int width, - int height) { - Log.d("SDL", "surfaceChanged()" + width + " + " + height); - - int sdlFormat = 0x85151002; // SDL_PIXELFORMAT_RGB565 by default - switch (format) { - case PixelFormat.A_8: - Log.v("SDL", "pixel format A_8"); - break; - case PixelFormat.LA_88: - Log.v("SDL", "pixel format LA_88"); - break; - case PixelFormat.L_8: - Log.v("SDL", "pixel format L_8"); - break; - case PixelFormat.RGBA_4444: - Log.v("SDL", "pixel format RGBA_4444"); - sdlFormat = 0x85421002; // SDL_PIXELFORMAT_RGBA4444 - break; - case PixelFormat.RGBA_5551: - Log.v("SDL", "pixel format RGBA_5551"); - sdlFormat = 0x85441002; // SDL_PIXELFORMAT_RGBA5551 - break; - case PixelFormat.RGBA_8888: - Log.v("SDL", "pixel format RGBA_8888"); - sdlFormat = 0x86462004; // SDL_PIXELFORMAT_RGBA8888 - break; - case PixelFormat.RGBX_8888: - Log.v("SDL", "pixel format RGBX_8888"); - sdlFormat = 0x86262004; // SDL_PIXELFORMAT_RGBX8888 - break; - case PixelFormat.RGB_332: - Log.v("SDL", "pixel format RGB_332"); - sdlFormat = 0x84110801; // SDL_PIXELFORMAT_RGB332 - break; - case PixelFormat.RGB_565: - Log.v("SDL", "pixel format RGB_565"); - sdlFormat = 0x85151002; // SDL_PIXELFORMAT_RGB565 - break; - case PixelFormat.RGB_888: - Log.v("SDL", "pixel format RGB_888"); - // Not sure this is right, maybe SDL_PIXELFORMAT_RGB24 instead? - sdlFormat = 0x86161804; // SDL_PIXELFORMAT_RGB888 - break; - default: - Log.v("SDL", "pixel format unknown " + format); - break; - } - SDLActivity.onNativeResize(width, height, sdlFormat); - - // Now start up the C app thread - if (mSDLThread == null) { - mSDLThread = new Thread(new SDLMain(width, height, config), - "SDLThread"); - mSDLThread.start(); - } - } - - // unused - public void onDraw(Canvas canvas) { - } - - // EGL functions - public boolean initEGL(int majorVersion, int minorVersion) { - Log.v("SDL", "Starting up OpenGL ES " + majorVersion + "." - + minorVersion); - - try { - EGL10 egl = (EGL10) EGLContext.getEGL(); - - EGLDisplay dpy = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); - - int[] version = new int[2]; - egl.eglInitialize(dpy, version); - - int EGL_OPENGL_ES_BIT = 1; - int EGL_OPENGL_ES2_BIT = 4; - int renderableType = 0; - if (majorVersion == 2) { - renderableType = EGL_OPENGL_ES2_BIT; - } else if (majorVersion == 1) { - renderableType = EGL_OPENGL_ES_BIT; - } - int[] configSpec = { - // EGL10.EGL_DEPTH_SIZE, 16, - EGL10.EGL_RENDERABLE_TYPE, renderableType, EGL10.EGL_NONE }; - EGLConfig[] configs = new EGLConfig[1]; - int[] num_config = new int[1]; - if (!egl.eglChooseConfig(dpy, configSpec, configs, 1, num_config) - || num_config[0] == 0) { - Log.e("SDL", "No EGL config available"); - return false; - } - EGLConfig config = configs[0]; - - EGLContext ctx = egl.eglCreateContext(dpy, config, - EGL10.EGL_NO_CONTEXT, null); - if (ctx == EGL10.EGL_NO_CONTEXT) { - Log.e("SDL", "Couldn't create context"); - return false; - } - - EGLSurface surface = egl.eglCreateWindowSurface(dpy, config, this, - null); - if (surface == EGL10.EGL_NO_SURFACE) { - Log.e("SDL", "Couldn't create surface"); - return false; - } - - if (!egl.eglMakeCurrent(dpy, surface, surface, ctx)) { - Log.e("SDL", "Couldn't make context current"); - return false; - } - - mEGLContext = ctx; - mEGLDisplay = dpy; - mEGLSurface = surface; - - } catch (Exception e) { - Log.v("SDL", e + ""); - for (StackTraceElement s : e.getStackTrace()) { - Log.v("SDL", s.toString()); - } - } - - return true; - } - - // EGL buffer flip - public void flipEGL() { - try { - EGL10 egl = (EGL10) EGLContext.getEGL(); - - egl.eglWaitNative(EGL10.EGL_NATIVE_RENDERABLE, null); - - // drawing here - - egl.eglWaitGL(); - - egl.eglSwapBuffers(mEGLDisplay, mEGLSurface); - - } catch (Exception e) { - Log.v("SDL", "flipEGL(): " + e); - for (StackTraceElement s : e.getStackTrace()) { - Log.v("SDL", s.toString()); - } - - } - } - - // Key events - public boolean onKey(View v, int keyCode, KeyEvent event) { - if(keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP) return false; - if (event.getAction() == KeyEvent.ACTION_DOWN) { - Log.v("SDL", "key down: " + keyCode); - if(keyCode == KeyEvent.KEYCODE_BACK){//TODO ask user to quit or not - PascalExports.HWterminate(true); - //SDLActivity.mSingleton.finish(); - }else{ - SDLActivity.onNativeKeyDown(keyCode); - } - - return true; - } else if (event.getAction() == KeyEvent.ACTION_UP) { - Log.v("SDL", "key up: " + keyCode); - SDLActivity.onNativeKeyUp(keyCode); - return true; - } - - return false; - } - - // Sensor events - public void enableSensor(int sensortype, boolean enabled) { - // TODO: This uses getDefaultSensor - what if we have >1 accels? - if (enabled) { - mSensorManager.registerListener(this, - mSensorManager.getDefaultSensor(sensortype), - SensorManager.SENSOR_DELAY_GAME, null); - } else { - mSensorManager.unregisterListener(this, - mSensorManager.getDefaultSensor(sensortype)); - } - } - - public void onAccuracyChanged(Sensor sensor, int accuracy) { - // TODO - } - - public void onSensorChanged(SensorEvent event) { - if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { - SDLActivity.onNativeAccel(event.values[0], event.values[1], - event.values[2]); - } - } - -} diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/StartGameActivity.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/StartGameActivity.java Sun Oct 09 20:41:17 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,210 +0,0 @@ -/* - * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game - * Copyright (c) 2011 Richard Deurwaarder - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - - -package org.hedgewars.mobile; - -import org.hedgewars.mobile.EngineProtocol.FrontendDataUtils; -import org.hedgewars.mobile.EngineProtocol.GameConfig; -import org.hedgewars.mobile.EngineProtocol.Map; -import org.hedgewars.mobile.EngineProtocol.Scheme; -import org.hedgewars.mobile.EngineProtocol.Team; -import org.hedgewars.mobile.EngineProtocol.Weapon; - -import android.app.Activity; -import android.content.Intent; -import android.graphics.drawable.Drawable; -import android.os.Bundle; -import android.os.Parcelable; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemSelectedListener; -import android.widget.ArrayAdapter; -import android.widget.ImageButton; -import android.widget.ImageView; -import android.widget.Spinner; -import android.widget.Toast; - -public class StartGameActivity extends Activity { - - public static final int ACTIVITY_TEAM_SELECTOR = 0; - - private GameConfig config = null; - private ImageButton start, back, team; - private Spinner maps, gameplay, gamescheme, weapons, themes; - private ImageView themeIcon, mapPreview, teamCount; - - public void onCreate(Bundle savedInstanceState){ - super.onCreate(savedInstanceState); - - //SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); - //Copy all the xml files to the device TODO only do first time launch of the app... - Utils.resRawToFilesDir(this,R.array.schemes, Scheme.DIRECTORY_SCHEME); - Utils.resRawToFilesDir(this, R.array.weapons, Weapon.DIRECTORY_WEAPON); - Scheme.parseBasicFlags(this); - - config = new GameConfig(); - - setContentView(R.layout.starting_game); - - back = (ImageButton) findViewById(R.id.btnBack); - team = (ImageButton) findViewById(R.id.btnTeams); - start = (ImageButton) findViewById(R.id.btnStart); - - maps = (Spinner) findViewById(R.id.spinMaps); - gameplay = (Spinner) findViewById(R.id.spinGameplay); - gamescheme = (Spinner) findViewById(R.id.spinGamescheme); - weapons = (Spinner) findViewById(R.id.spinweapons); - themes = (Spinner) findViewById(R.id.spinTheme); - - themeIcon = (ImageView) findViewById(R.id.imgTheme); - mapPreview = (ImageView) findViewById(R.id.mapPreview); - teamCount = (ImageView) findViewById(R.id.imgTeamsCount); - - start.setOnClickListener(startClicker); - back.setOnClickListener(backClicker); - team.setOnClickListener(teamClicker); - - ArrayAdapter adapter = new ArrayAdapter(this, R.layout.listview_item, FrontendDataUtils.getMaps(this)); - adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - maps.setAdapter(adapter); - maps.setOnItemSelectedListener(mapsClicker); - - adapter = new ArrayAdapter(this, R.layout.listview_item, FrontendDataUtils.getGameplay(this)); - adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - gameplay.setAdapter(adapter); - gameplay.setOnItemSelectedListener(gameplayClicker); - - adapter = new ArrayAdapter(this, R.layout.listview_item, FrontendDataUtils.getSchemes(this)); - adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - gamescheme.setAdapter(adapter); - gamescheme.setOnItemSelectedListener(schemeClicker); - - adapter = new ArrayAdapter(this, R.layout.listview_item, FrontendDataUtils.getWeapons(this)); - adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - weapons.setAdapter(adapter); - weapons.setOnItemSelectedListener(weaponClicker); - - adapter = new ArrayAdapter(this, R.layout.listview_item, FrontendDataUtils.getThemes(this)); - adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - themes.setAdapter(adapter); - themes.setOnItemSelectedListener(themesClicker); - - } - - private void startTeamsActivity(){ - Intent i = new Intent(StartGameActivity.this, TeamSelectionActivity.class); - i.putParcelableArrayListExtra("teams", config.teams); - startActivityForResult(i, ACTIVITY_TEAM_SELECTOR); - } - - public void onActivityResult(int requestCode, int resultCode, Intent data){ - switch(requestCode){ - case ACTIVITY_TEAM_SELECTOR: - if(resultCode == Activity.RESULT_OK){ - Parcelable[] parcelables = (Parcelable[])data.getParcelableArrayExtra("teams"); - config.teams.clear(); - for(Parcelable t : parcelables){ - config.teams.add((Team)t); - } - teamCount.getDrawable().setLevel(config.teams.size()); - } - break; - } - } - - - private OnItemSelectedListener themesClicker = new OnItemSelectedListener(){ - - public void onItemSelected(AdapterView arg0, View view, int position, long rowId) { - String themeName = (String) arg0.getAdapter().getItem(position); - Drawable themeIconDrawable = Drawable.createFromPath(Utils.getDownloadPath(StartGameActivity.this) + "Themes/" + themeName + "/icon@2X.png"); - themeIcon.setImageDrawable(themeIconDrawable); - config.theme = themeName; - } - - public void onNothingSelected(AdapterView arg0) { - } - - }; - - private OnItemSelectedListener mapsClicker = new OnItemSelectedListener(){ - - public void onItemSelected(AdapterView arg0, View view, int position,long rowId) { - Map map = (Map)arg0.getAdapter().getItem(position); - mapPreview.setImageDrawable(map.getDrawable()); - config.map = map; - } - - public void onNothingSelected(AdapterView arg0) { - } - - }; - - private OnItemSelectedListener weaponClicker = new OnItemSelectedListener(){ - public void onItemSelected(AdapterView arg0, View arg1, int arg2, long arg3) { - config.weapon = (Weapon)arg0.getAdapter().getItem(arg2); - } - public void onNothingSelected(AdapterView arg0) { - - } - }; - private OnItemSelectedListener schemeClicker = new OnItemSelectedListener(){ - public void onItemSelected(AdapterView arg0, View arg1, int arg2, long arg3) { - config.scheme = (Scheme)arg0.getAdapter().getItem(arg2); - } - public void onNothingSelected(AdapterView arg0) { - - } - }; - private OnItemSelectedListener gameplayClicker = new OnItemSelectedListener(){ - public void onItemSelected(AdapterView arg0, View arg1, int arg2, long arg3) { - //config = ()arg0.getAdapter().getItem(arg2); - } - public void onNothingSelected(AdapterView arg0) { - - } - }; - - private OnClickListener startClicker = new OnClickListener(){ - public void onClick(View v) { - if(config.teams.size() < 2){ - Toast.makeText(StartGameActivity.this, R.string.not_enough_teams, Toast.LENGTH_LONG).show(); - startTeamsActivity(); - } - else{ - Intent i = new Intent(StartGameActivity.this, SDLActivity.class); - i.putExtra("config", config); - startActivity(i);} - } - }; - - private OnClickListener backClicker = new OnClickListener(){ - public void onClick(View v) { - finish(); - } - }; - - private OnClickListener teamClicker = new OnClickListener(){ - public void onClick(View v) { - startTeamsActivity(); - } - }; - -} diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/TeamCreatorActivity.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/TeamCreatorActivity.java Sun Oct 09 20:41:17 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,356 +0,0 @@ -/* - * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game - * Copyright (c) 2011 Richard Deurwaarder - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - - -package org.hedgewars.mobile; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; - -import org.hedgewars.mobile.EngineProtocol.FrontendDataUtils; -import org.hedgewars.mobile.EngineProtocol.Team; - -import android.app.Activity; -import android.graphics.Bitmap; -import android.graphics.drawable.Drawable; -import android.media.MediaPlayer; -import android.os.Bundle; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.View.OnFocusChangeListener; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemSelectedListener; -import android.widget.ArrayAdapter; -import android.widget.EditText; -import android.widget.ImageButton; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.RelativeLayout; -import android.widget.ScrollView; -import android.widget.SimpleAdapter; -import android.widget.Spinner; -import android.widget.TextView; -import android.widget.Toast; - -public class TeamCreatorActivity extends Activity { - - private TextView name; - private Spinner difficulty, grave, flag, voice, fort; - private ImageView imgFort; - private ArrayList hogDice = new ArrayList(); - private ArrayList hogHat = new ArrayList(); - private ArrayList hogName = new ArrayList(); - private ImageButton back, save, voiceButton; - private ScrollView scroller; - private MediaPlayer mp = null; - private boolean settingsChanged = false; - private boolean saved = false; - - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.team_creation); - - name = (TextView) findViewById(R.id.txtName); - difficulty = (Spinner) findViewById(R.id.spinType); - grave = (Spinner) findViewById(R.id.spinGrave); - flag = (Spinner) findViewById(R.id.spinFlag); - voice = (Spinner) findViewById(R.id.spinVoice); - fort = (Spinner) findViewById(R.id.spinFort); - - imgFort = (ImageView) findViewById(R.id.imgFort); - - back = (ImageButton) findViewById(R.id.btnBack); - save = (ImageButton) findViewById(R.id.btnSave); - voiceButton = (ImageButton) findViewById(R.id.btnPlay); - - scroller = (ScrollView) findViewById(R.id.scroller); - - save.setOnClickListener(saveClicker); - back.setOnClickListener(backClicker); - - LinearLayout ll = (LinearLayout) findViewById(R.id.HogsContainer); - for (int i = 0; i < ll.getChildCount(); i++) { - RelativeLayout team_creation_entry = (RelativeLayout) ll - .getChildAt(i); - - hogHat.add((Spinner) team_creation_entry - .findViewById(R.id.spinTeam1)); - hogDice.add((ImageButton) team_creation_entry - .findViewById(R.id.btnTeam1)); - hogName.add((EditText) team_creation_entry - .findViewById(R.id.txtTeam1)); - } - ArrayList> gravesData = FrontendDataUtils - .getGraves(this); - SimpleAdapter sa = new SimpleAdapter(this, gravesData, - R.layout.spinner_textimg_entry, new String[] { "txt", "img" }, - new int[] { R.id.spinner_txt, R.id.spinner_img }); - - sa.setViewBinder(viewBinder); - grave.setAdapter(sa); - grave.setOnFocusChangeListener(focusser); - - ArrayList> flagsData = FrontendDataUtils - .getFlags(this); - sa = new SimpleAdapter(this, flagsData, R.layout.spinner_textimg_entry, - new String[] { "txt", "img" }, new int[] { R.id.spinner_txt, - R.id.spinner_img }); - sa.setViewBinder(viewBinder); - flag.setAdapter(sa); - flag.setOnFocusChangeListener(focusser); - - ArrayList> typesData = FrontendDataUtils - .getTypes(this); - sa = new SimpleAdapter(this, typesData, R.layout.spinner_textimg_entry, - new String[] { "txt", "img" }, new int[] { R.id.spinner_txt, - R.id.spinner_img }); - difficulty.setAdapter(sa); - difficulty.setOnFocusChangeListener(focusser); - - ArrayList> hatsData = FrontendDataUtils - .getHats(this); - sa = new SimpleAdapter(this, hatsData, R.layout.spinner_textimg_entry, - new String[] { "txt", "img" }, new int[] { R.id.spinner_txt, - R.id.spinner_img }); - sa.setViewBinder(viewBinder); - for (Spinner spin : hogHat) { - spin.setAdapter(sa); - } - - ArrayAdapter adapter = new ArrayAdapter(this, - R.layout.listview_item, FrontendDataUtils.getVoices(this)); - voice.setAdapter(adapter); - voice.setOnFocusChangeListener(focusser); - voiceButton.setOnClickListener(voiceClicker); - - adapter = new ArrayAdapter(this, R.layout.listview_item, - FrontendDataUtils.getForts(this)); - fort.setAdapter(adapter); - fort.setOnItemSelectedListener(fortSelector); - fort.setOnFocusChangeListener(focusser); - - Team t = this.getIntent().getParcelableExtra("team"); - if (t != null) { - name.setText(t.name); - int position = ((ArrayAdapter) voice.getAdapter()) - .getPosition(t.voice); - voice.setSelection(position); - - position = ((ArrayAdapter) fort.getAdapter()) - .getPosition(t.fort); - fort.setSelection(position); - - position = 0; - for (HashMap hashmap : typesData) { - if (hashmap.get("txt").equals(t.levels[0])) { - difficulty.setSelection(position); - break; - } - } - - position = 0; - for (HashMap hashmap : gravesData) { - if (hashmap.get("txt").equals(t.grave)) { - grave.setSelection(position); - break; - } - } - - position = 0; - for (HashMap hashmap : typesData) { - if (hashmap.get("txt").equals(t.flag)) { - flag.setSelection(position); - break; - } - } - - for (int i = 0; i < Team.maxNumberOfHogs; i++) { - position = 0; - for (HashMap hashmap : hatsData) { - if (hashmap.get("txt").equals(t.hats[i])) { - hogHat.get(i).setSelection(position); - } - } - - hogName.get(i).setText(t.hogNames[i]); - } - } - } - - public void onDestroy() { - super.onDestroy(); - if (mp != null) { - mp.release(); - mp = null; - } - } - - private OnFocusChangeListener focusser = new OnFocusChangeListener() { - public void onFocusChange(View v, boolean hasFocus) { - settingsChanged = true; - } - - }; - - public void onBackPressed() { - onFinishing(); - super.onBackPressed(); - - } - - private OnClickListener backClicker = new OnClickListener() { - public void onClick(View v) { - onFinishing(); - finish(); - } - }; - - private void onFinishing() { - if (settingsChanged) { - setResult(RESULT_OK); - } else { - setResult(RESULT_CANCELED); - } - } - - private OnClickListener saveClicker = new OnClickListener() { - public void onClick(View v) { - Toast.makeText(TeamCreatorActivity.this, R.string.saved, Toast.LENGTH_SHORT).show(); - saved = true; - Team team = new Team(); - team.name = name.getText().toString(); - HashMap hashmap = (HashMap) flag - .getSelectedItem(); - - team.flag = (String) hashmap.get("txt"); - team.fort = fort.getSelectedItem().toString(); - hashmap = (HashMap) grave.getSelectedItem(); - team.grave = hashmap.get("txt").toString(); - team.hash = "0"; - team.voice = voice.getSelectedItem().toString(); - - hashmap = ((HashMap) difficulty.getSelectedItem()); - String levelString = hashmap.get("txt").toString(); - int levelInt; - if (levelString.equals(getString(R.string.human))) { - levelInt = 0; - } else if (levelString.equals(getString(R.string.bot5))) { - levelInt = 1; - } else if (levelString.equals(getString(R.string.bot4))) { - levelInt = 2; - } else if (levelString.equals(getString(R.string.bot3))) { - levelInt = 3; - } else if (levelString.equals(getString(R.string.bot2))) { - levelInt = 4; - } else { - levelInt = 5; - } - - for (int i = 0; i < hogName.size(); i++) { - team.hogNames[i] = hogName.get(i).getText().toString(); - hashmap = (HashMap) hogHat.get(i) - .getSelectedItem(); - team.hats[i] = hashmap.get("txt").toString(); - team.levels[i] = levelInt; - } - try { - File teamsDir = new File(getFilesDir().getAbsolutePath() + '/' - + Team.DIRECTORY_TEAMS); - if (!teamsDir.exists()) - teamsDir.mkdir(); - FileOutputStream fos = new FileOutputStream(String.format( - "%s/%s.xml", teamsDir.getAbsolutePath(), team.name)); - team.writeToXml(fos); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - } - - }; - - private OnItemSelectedListener fortSelector = new OnItemSelectedListener() { - @SuppressWarnings("unchecked") - public void onItemSelected(AdapterView arg0, View arg1, - int position, long arg3) { - settingsChanged = true; - String fortName = (String) arg0.getAdapter().getItem(position); - Drawable fortIconDrawable = Drawable.createFromPath(Utils - .getDownloadPath(TeamCreatorActivity.this) - + "Forts/" - + fortName + "L.png"); - imgFort.setImageDrawable(fortIconDrawable); - scroller.fullScroll(ScrollView.FOCUS_DOWN);// Scroll the scrollview - // to the bottom, work - // around for scollview - // invalidation (scrolls - // back to top) - } - - public void onNothingSelected(AdapterView arg0) { - } - - }; - - private OnClickListener voiceClicker = new OnClickListener() { - public void onClick(View v) { - try { - File dir = new File(String.format("%sSounds/voices/%s", - Utils.getDownloadPath(TeamCreatorActivity.this), - voice.getSelectedItem())); - String file = ""; - File[] dirs = dir.listFiles(); - File f = dirs[(int) Math.round(Math.random() * dirs.length)]; - if (f.getName().endsWith(".ogg")) - file = f.getAbsolutePath(); - - if (mp == null) - mp = new MediaPlayer(); - else - mp.reset(); - mp.setDataSource(file); - mp.prepare(); - mp.start(); - } catch (IllegalArgumentException e) { - e.printStackTrace(); - } catch (IllegalStateException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - } - }; - - private SimpleAdapter.ViewBinder viewBinder = new SimpleAdapter.ViewBinder() { - - public boolean setViewValue(View view, Object data, - String textRepresentation) { - if (view instanceof ImageView && data instanceof Bitmap) { - ImageView v = (ImageView) view; - v.setImageBitmap((Bitmap) data); - return true; - } else { - return false; - } - } - }; - -} diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/TeamSelectionActivity.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/TeamSelectionActivity.java Sun Oct 09 20:41:17 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,289 +0,0 @@ -/* - * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game - * Copyright (c) 2011 Richard Deurwaarder - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - - -package org.hedgewars.mobile; - -import java.io.File; -import java.util.ArrayList; -import java.util.HashMap; - -import org.hedgewars.mobile.EngineProtocol.FrontendDataUtils; -import org.hedgewars.mobile.EngineProtocol.Team; - -import android.app.Activity; -import android.content.Intent; -import android.os.Bundle; -import android.os.Parcelable; -import android.view.ContextMenu; -import android.view.MenuItem; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.AdapterView; -import android.widget.AdapterView.AdapterContextMenuInfo; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.ImageButton; -import android.widget.ImageView; -import android.widget.ListView; -import android.widget.RelativeLayout; -import android.widget.SimpleAdapter; -import android.widget.SimpleAdapter.ViewBinder; -import android.widget.TextView; - -public class TeamSelectionActivity extends Activity{ - - private static final int ACTIVITY_TEAMCREATION = 0; - - private ImageButton addTeam, back; - private ListView availableTeams, selectedTeams; - private ArrayList> availableTeamsList, selectedTeamsList; - private TextView txtInfo; - - public void onCreate(Bundle savedInstanceState){ - super.onCreate(savedInstanceState); - - setContentView(R.layout.team_selector); - - addTeam = (ImageButton) findViewById(R.id.btnAdd); - back = (ImageButton) findViewById(R.id.btnBack); - txtInfo = (TextView) findViewById(R.id.txtInfo); - - addTeam.setOnClickListener(addTeamClicker); - back.setOnClickListener(backClicker); - - availableTeams = (ListView) findViewById(R.id.availableTeams); - availableTeamsList = FrontendDataUtils.getTeams(this); - SimpleAdapter adapter = new SimpleAdapter(this, availableTeamsList, R.layout.team_selection_entry_simple, new String[]{"txt", "img"}, new int[]{R.id.txtName, R.id.imgDifficulty}); - availableTeams.setAdapter(adapter); - registerForContextMenu(availableTeams); - availableTeams.setOnItemClickListener(availableClicker); - - selectedTeams = (ListView) findViewById(R.id.selectedTeams); - selectedTeamsList = new ArrayList>(); - ArrayList> toBeRemoved = new ArrayList>(); - ArrayList teamsStartGame = getIntent().getParcelableArrayListExtra("teams"); - for(HashMap hashmap : availableTeamsList){ - for(Team t : teamsStartGame){ - if(((Team)hashmap.get("team")).equals(t)){ - toBeRemoved.add(hashmap); - selectedTeamsList.add(FrontendDataUtils.teamToHashMap(t));//create a new hashmap to ensure all variables are entered into the map - } - } - } - for(HashMap hashmap : toBeRemoved) availableTeamsList.remove(hashmap); - - adapter = new SimpleAdapter(this, selectedTeamsList, R.layout.team_selection_entry, new String[]{"txt", "img", "color", "count"}, new int[]{R.id.txtName, R.id.imgDifficulty, R.id.teamColor, R.id.teamCount}); - adapter.setViewBinder(viewBinder); - selectedTeams.setAdapter(adapter); - selectedTeams.setOnItemClickListener(selectedClicker); - - txtInfo.setText(String.format(getResources().getString(R.string.teams_info_template), selectedTeams.getChildCount())); - } - - private ViewBinder viewBinder = new ViewBinder(){ - public boolean setViewValue(View view, Object data, String textRepresentation) { - switch(view.getId()){ - case R.id.teamColor: - setTeamColor(view, (Integer)data); - return true; - case R.id.teamCount: - setTeamHogCount((ImageView)view, (Integer)data); - return true; - default: - return false; - } - } - }; - - public void onActivityResult(int requestCode, int resultCode, Intent data){ - if(requestCode == ACTIVITY_TEAMCREATION){ - if(resultCode == Activity.RESULT_OK){ - updateListViews(); - } - }else{ - super.onActivityResult(requestCode, resultCode, data); - } - } - - private void updateListViews(){ - unregisterForContextMenu(availableTeams); - availableTeamsList = FrontendDataUtils.getTeams(this); - ArrayList> toBeRemoved = new ArrayList>(); - for(HashMap hashmap : selectedTeamsList){ - String name = (String)hashmap.get("txt"); - - for(HashMap hash : availableTeamsList){ - if(name.equals((String)hash.get("txt"))){ - toBeRemoved.add(hash); - } - } - } - for(HashMap hash: toBeRemoved) availableTeamsList.remove(hash); - - SimpleAdapter adapter = new SimpleAdapter(this, availableTeamsList, R.layout.team_selection_entry, new String[]{"txt", "img"}, new int[]{R.id.txtName, R.id.imgDifficulty}); - availableTeams.setAdapter(adapter); - registerForContextMenu(availableTeams); - availableTeams.setOnItemClickListener(availableClicker); - - - } - - private void setTeamColor(int position, int color){ - View iv = ((RelativeLayout)selectedTeams.getChildAt(position)).findViewById(R.id.teamCount); - setTeamColor(iv, color); - } - private void setTeamColor(View iv, int color){ - iv.setBackgroundColor(0xFF000000 + color); - } - - private void setTeamHogCount(int position, int count){ - ImageView iv = (ImageView)((RelativeLayout)selectedTeams.getChildAt(position)).findViewById(R.id.teamCount); - setTeamHogCount(iv, count); - } - - private void setTeamHogCount(ImageView iv, int count){ - - switch(count){ - case 0: - iv.setImageResource(R.drawable.teamcount0); - break; - case 1: - iv.setImageResource(R.drawable.teamcount1); - break; - case 2: - iv.setImageResource(R.drawable.teamcount2); - break; - case 3: - iv.setImageResource(R.drawable.teamcount3); - break; - case 4: - iv.setImageResource(R.drawable.teamcount4); - break; - case 5: - iv.setImageResource(R.drawable.teamcount5); - break; - case 6: - iv.setImageResource(R.drawable.teamcount6); - break; - case 7: - iv.setImageResource(R.drawable.teamcount7); - break; - case 8: - iv.setImageResource(R.drawable.teamcount8); - break; - case 9: - iv.setImageResource(R.drawable.teamcount9); - break; - } - } - - public void onBackPressed(){ - returnTeams(); - super.onBackPressed(); - } - - private OnClickListener addTeamClicker = new OnClickListener(){ - public void onClick(View v) { - startActivityForResult(new Intent(TeamSelectionActivity.this, TeamCreatorActivity.class), ACTIVITY_TEAMCREATION); - } - }; - - private OnClickListener backClicker = new OnClickListener(){ - public void onClick(View v){ - returnTeams(); - finish(); - } - }; - - private OnItemClickListener availableClicker = new OnItemClickListener(){ - public void onItemClick(AdapterView arg0, View arg1, int position,long arg3) { - selectAvailableTeamsItem(position); - } - }; - private OnItemClickListener selectedClicker = new OnItemClickListener(){ - public void onItemClick(AdapterView arg0, View arg1, int position,long arg3) { - availableTeamsList.add((HashMap) selectedTeamsList.get(position)); - selectedTeamsList.remove(position); - ((SimpleAdapter)availableTeams.getAdapter()).notifyDataSetChanged(); - ((SimpleAdapter)selectedTeams.getAdapter()).notifyDataSetChanged(); - - txtInfo.setText(String.format(getResources().getString(R.string.teams_info_template), selectedTeamsList.size())); - } - - }; - - public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuinfo){ - menu.add(ContextMenu.NONE, 0, ContextMenu.NONE, R.string.select); - menu.add(ContextMenu.NONE, 2, ContextMenu.NONE, R.string.edit); - menu.add(ContextMenu.NONE, 1, ContextMenu.NONE, R.string.delete); - - } - public boolean onContextItemSelected(MenuItem item){ - AdapterView.AdapterContextMenuInfo menuInfo = (AdapterContextMenuInfo) item.getMenuInfo(); - int position = menuInfo.position; - switch(item.getItemId()){ - case 0://select - selectAvailableTeamsItem(position); - return true; - case 1://delete - File f = new File(String.format("%s/%s/%s.xml", TeamSelectionActivity.this.getFilesDir(), Team.DIRECTORY_TEAMS, availableTeamsList.get(position).get("txt"))); - f.delete(); - availableTeamsList.remove(position); - ((SimpleAdapter)availableTeams.getAdapter()).notifyDataSetChanged(); - return true; - case 2://edit - Intent i = new Intent(TeamSelectionActivity.this, TeamCreatorActivity.class); - Team t = (Team)availableTeamsList.get(position).get("team"); - i.putExtra("team", t); - startActivityForResult(i, ACTIVITY_TEAMCREATION); - return true; - } - return false; - } - - private void selectAvailableTeamsItem(int position){ - HashMap hash = (HashMap) availableTeamsList.get(position); - Team t = (Team)hash.get("team"); - int[] illegalcolors = new int[selectedTeamsList.size()]; - for(int i = 0; i < selectedTeamsList.size(); i++){ - illegalcolors[i] = ((Team)selectedTeamsList.get(i).get("team")).color; - } - t.setRandomColor(illegalcolors); - hash.put("color", t.color); - hash.put("count", t.hogCount); - - selectedTeamsList.add(hash); - availableTeamsList.remove(position); - ((SimpleAdapter)availableTeams.getAdapter()).notifyDataSetChanged(); - ((SimpleAdapter)selectedTeams.getAdapter()).notifyDataSetChanged(); - - txtInfo.setText(String.format(getResources().getString(R.string.teams_info_template), selectedTeamsList.size())); - } - - private void returnTeams(){ - int teamsCount = selectedTeamsList.size(); - Intent i = new Intent(); - Parcelable[] teams = new Parcelable[teamsCount]; - for(int x = 0 ; x < teamsCount; x++){ - teams[x] = (Team)selectedTeamsList.get(x).get("team"); - } - i.putExtra("teams", teams); - setResult(Activity.RESULT_OK, i); - - } -} diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/TextImageAdapter.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/TextImageAdapter.java Sun Oct 09 20:41:17 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,76 +0,0 @@ -/* - * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game - * Copyright (c) 2011 Richard Deurwaarder - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - - -package org.hedgewars.mobile; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; - -import org.hedgewars.mobile.R; - -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.SimpleAdapter; -import android.widget.TextView; - - -public class TextImageAdapter extends SimpleAdapter { - - private Context context; - private ArrayList> data; - - public TextImageAdapter(Context _context, ArrayList> _data, int resource, String[] from, int[] to) { - super(_context, _data, resource, from, to); - context = _context; - data = _data; - } - - public static TextImageAdapter createAdapter(Context c, String[] txt, String[] img, String[] from, int[] to){ - if(txt.length != img.length) throw new IllegalArgumentException("txt and img parameters not equal"); - - ArrayList> data = new ArrayList>(txt.length); - - for(int i = 0; i < txt.length; i++){ - HashMap map = new HashMap(); - map.put("txt", txt[i]); - map.put("img", BitmapFactory.decodeFile(img[i])); - data.add(map); - } - return new TextImageAdapter(c, data, R.layout.spinner_textimg_entry, from, to); - } - - public View getView(int position, View convertView, ViewGroup parent){ - if(convertView == null){ - LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - convertView = inflater.inflate(R.layout.spinner_textimg_entry, parent); - } - TextView tv = (TextView) convertView.findViewById(R.id.spinner_txt); - ImageView img = (ImageView) convertView.findViewById(R.id.spinner_img); - - tv.setText((String)data.get(position).get("txt")); - img.setImageBitmap((Bitmap)data.get(position).get("img")); - - return convertView; - } -} diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/TouchInterface/TouchInterface.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/TouchInterface/TouchInterface.java Sun Oct 09 20:41:17 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,108 +0,0 @@ -/* - * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game - * Copyright (c) 2011 Richard Deurwaarder - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -package org.hedgewars.mobile.TouchInterface; - -import org.hedgewars.mobile.SDLActivity; - -import android.os.Build; -import android.util.Log; -import android.view.MotionEvent; -import android.view.View; -import android.view.View.OnTouchListener; - -public class TouchInterface{ - - public static OnTouchListener getTouchInterface(){ - OnTouchListener toucher; - if(Build.VERSION.SDK_INT < 5){//8 == Build.VERSION_CODES.FROYO - toucher = new TouchInterfaceST(); - }else{ - toucher = new TouchInterfaceMT(); - } - - return toucher; - } -} -/** - * Touch interface with multitouch - */ -class TouchInterfaceMT implements OnTouchListener { - - private boolean firstEvent = true; - - public boolean onTouch(View v, MotionEvent event) { - //dumpEvent(event); - - if(firstEvent){ - firstEvent = false; - SDLActivity.onNativeTouch(-1, -1, v.getWidth(), v.getHeight(), 1); - } - - int action = event.getAction(); - int actionCode = action & MotionEvent.ACTION_MASK; - - for (int i = 0; i < event.getPointerCount(); i++) { - SDLActivity.onNativeTouch(actionCode, event.getPointerId(i), (int)event.getX(i), (int)event.getY(i), event.getPressure(i)); -// Log.d("Android", String.format("x=%f, y=%f, pntr=%d", event.getX(i), event.getY(i), event.getPointerId(i))); - } - return true; - } - - /** Show an event in the LogCat view, for debugging */ - private void dumpEvent(MotionEvent event) { - String names[] = { "DOWN" , "UP" , "MOVE" , "CANCEL" , "OUTSIDE" , - "POINTER_DOWN" , "POINTER_UP" , "7?" , "8?" , "9?" }; - StringBuilder sb = new StringBuilder(); - int action = event.getAction(); - int actionCode = action & MotionEvent.ACTION_MASK; - sb.append("event ACTION_" ).append(names[actionCode]); - if (actionCode == MotionEvent.ACTION_POINTER_DOWN - || actionCode == MotionEvent.ACTION_POINTER_UP) { - sb.append("(pid " ).append( - action >> MotionEvent.ACTION_POINTER_ID_SHIFT); - sb.append(")" ); - } - sb.append("[" ); - for (int i = 0; i < event.getPointerCount(); i++) { - sb.append("#" ).append(i); - sb.append("(pid " ).append(event.getPointerId(i)); - sb.append(")=" ).append((int) event.getX(i)); - sb.append("," ).append((int) event.getY(i)); - if (i + 1 < event.getPointerCount()) - sb.append(";" ); - } - sb.append("]" ); - Log.d("HW_APP_TOUCH", sb.toString()); - } - -} - -/** - * Touch interface without multitouch - */ -class TouchInterfaceST implements OnTouchListener { - - public boolean onTouch(View v, MotionEvent event) { - return false; - } - - - -} - diff -r 9a7cc0f29430 -r 10011f051f9c project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/Utils.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/Utils.java Sun Oct 09 20:41:17 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,213 +0,0 @@ -/* - * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game - * Copyright (c) 2011 Richard Deurwaarder - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - - -package org.hedgewars.mobile; - -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; - -import android.content.Context; -import android.content.res.TypedArray; -import android.os.Build; -import android.os.Environment; -import android.widget.Toast; - -public class Utils { - - - /** - * get the path to which we should download all the data files - * @param c context - * @return absolute path - */ - public static String getDownloadPath(Context c){ - if(Build.VERSION.SDK_INT < 8){//8 == Build.VERSION_CODES.FROYO - return PreFroyoSDCardDir.getDownloadPath(c); - }else{ - return FroyoSDCardDir.getDownloadPath(c); - } - } - - static class FroyoSDCardDir{ - public static String getDownloadPath(Context c){ - File f = c.getExternalCacheDir(); - if(f != null){ - return f.getAbsolutePath() + "/Data/"; - }else{ - Toast.makeText(c, R.string.sdcard_not_mounted, Toast.LENGTH_LONG).show(); - return null; - } - } - } - - static class PreFroyoSDCardDir{ - public static String getDownloadPath(Context c){ - if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ - if(Environment.getExternalStorageDirectory() != null) - return Environment.getExternalStorageDirectory().getAbsolutePath() + "/Hedgewars/"; - } - Toast.makeText(c, R.string.sdcard_not_mounted, Toast.LENGTH_LONG).show(); - return null; - } - } - - /** - * Get files from dirName, dir name is relative to {@link getDownloadPath} - * @param dirName - * @param c context - * @return string of files - */ - public static String[] getFileNamesFromRelativeDir(Context c, String dirName){ - String prefix = getDownloadPath(c); - File f = new File(prefix + dirName); - - if(f.exists() && f.isDirectory()) return f.list(); - else throw new IllegalArgumentException("File not a directory or doesn't exist dirName = " + f.getAbsolutePath()); - } - - /** - * Return a File array with all the files from dirName - * @param c - * @param dirName - * @return - */ - public static File[] getFilesFromRelativeDir(Context c, String dirName){ - String prefix = getDownloadPath(c); - File f = new File(prefix + dirName); - - if(f.exists() && f.isDirectory()) return f.listFiles(); - else throw new IllegalArgumentException("File not a directory or doesn't exist dirName = " + f.getAbsolutePath()); - } - - /** - * Checks if this directory has a file with suffix suffix - * @param f - directory - * @return - */ - public static boolean hasFileWithSuffix(File f, String suffix){ - if(f.isDirectory()){ - for(String s : f.list()){ - if(s.endsWith(suffix)) return true; - } - return false; - }else{ - return false; - } - } - - /** - * Gives back all dirs which contain a file with suffix fileSuffix - * @param c - * @param path - * @param fileSuffix - * @return - */ - public static String[] getDirsWithFileSuffix(Context c, String path, String fileSuffix){ - File[] files = getFilesFromRelativeDir(c,path); - String[] validFiles = new String[files.length]; - int validCounter = 0; - - for(File f : files){ - if(hasFileWithSuffix(f, fileSuffix)) validFiles[validCounter++] = f.getName(); - } - String[] ret = new String[validCounter]; - System.arraycopy(validFiles, 0, ret, 0, validCounter); - return ret; - } - - /** - * Get all files from directory dir which have the given suffix - * @param c - * @param dir - * @param suffix - * @param removeSuffix - * @return - */ - public static ArrayList getFilesFromDirWithSuffix(Context c, String dir, String suffix, boolean removeSuffix){ - String[] files = Utils.getFileNamesFromRelativeDir(c, dir); - ArrayList ret = new ArrayList(); - for(String s : files){ - if(s.endsWith(suffix)){ - if(removeSuffix) ret.add(s.substring(0, s.length()-suffix.length())); - else ret.add(s); - } - } - return ret; - } - - /** - * Moves resources pointed to by sourceResId (from @res/raw/) to the app's private data directory - * @param c - * @param sourceResId - * @param directory - */ - public static void resRawToFilesDir(Context c, int sourceResId, String directory){ - byte[] buffer = new byte[1024]; - InputStream bis = null; - BufferedOutputStream bos = null; - File schemesDirFile = new File(c.getFilesDir().getAbsolutePath() + '/' + directory); - schemesDirFile.mkdirs(); - String schemesDirPath = schemesDirFile.getAbsolutePath() + '/'; - - //Get an array with the resource files ID - TypedArray ta = c.getResources().obtainTypedArray(sourceResId); - int[] resIds = new int[ta.length()]; - for(int i = 0; i < ta.length(); i++){ - resIds[i] = ta.getResourceId(i, 0); - } - - for(int id : resIds){ - String fileName = c.getResources().getResourceEntryName(id); - File f = new File(schemesDirPath + fileName); - try { - if(!f.createNewFile()){ - f.delete(); - f.createNewFile(); - } - - bis = c.getResources().openRawResource(id); - bos = new BufferedOutputStream(new FileOutputStream(f), 1024); - int read = 0; - while((read = bis.read(buffer)) != -1){ - bos.write(buffer, 0, read); - } - - } catch (IOException e) { - e.printStackTrace(); - }finally{ - if(bis != null) - try { - bis.close(); - } catch (IOException e) { - e.printStackTrace(); - } - if(bos != null) - try { - bos.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - } -}