diff options
| author | Jari Vetoniemi <jari.vetoniemi@indooratlas.com> | 2020-03-16 18:49:26 +0900 | 
|---|---|---|
| committer | Jari Vetoniemi <jari.vetoniemi@indooratlas.com> | 2020-03-30 00:39:06 +0900 | 
| commit | fcbf63e62c627deae76c1b8cb8c0876c536ed811 (patch) | |
| tree | 64cb17de3f41a2b6fef2368028fbd00349946994 /src | |
Fresh start
Diffstat (limited to 'src')
| l--------- | src/org | 1 | ||||
| -rw-r--r-- | src/pw/cloudef/rpg/Base.java | 127 | ||||
| -rw-r--r-- | src/pw/cloudef/rpg/Button.java | 60 | ||||
| -rw-r--r-- | src/pw/cloudef/rpg/Easyrpg.java | 30 | ||||
| -rw-r--r-- | src/pw/cloudef/rpg/Launcher.java | 104 | ||||
| -rw-r--r-- | src/pw/cloudef/rpg/Mkxp.java | 18 | ||||
| -rw-r--r-- | src/pw/cloudef/rpg/Nodeweb.java | 58 | 
7 files changed, 398 insertions, 0 deletions
| @@ -0,0 +1 @@ +../jni/SDL/android-project/app/src/main/java/org
\ No newline at end of file diff --git a/src/pw/cloudef/rpg/Base.java b/src/pw/cloudef/rpg/Base.java new file mode 100644 index 0000000..ed56bda --- /dev/null +++ b/src/pw/cloudef/rpg/Base.java @@ -0,0 +1,127 @@ +package pw.cloudef.rpg; +import org.libsdl.app.SDLActivity; +import java.util.Map; +import java.util.HashMap; +import java.lang.Integer; +import java.lang.Boolean; +import java.lang.String; +import android.os.Bundle; +import android.content.Context; +import android.view.View; +import android.view.ViewGroup; +import android.view.LayoutInflater; +import android.view.KeyEvent; +import android.view.InputDevice; +import com.andretietz.android.controller.ActionView; +import com.andretietz.android.controller.InputView; +import android.system.Os; + +public class Base extends SDLActivity { +   private boolean gamepadHidden; +   private ActionView av; +   private ActionView dv; +   private Button hider; + +   protected int mainLayout() { +      return R.layout.base; +   } + +   protected boolean hideFully() { +      return false; +   } + +   protected String gameId() { +      return getIntent().getExtras().getString("id"); +   } + +   protected String baseDir() { +      return getApplicationContext().getFilesDir().toPath().toString() + "/data/" + gameId(); +   } + +   protected void onCreate(Bundle savedInstanceState) { +      try { Os.setenv("COMPAT_CHDIR",  baseDir(), true); } catch (Exception e) {} +      super.onCreate(savedInstanceState); +      final LayoutInflater li = LayoutInflater.from(getApplicationContext()); +      mLayout.addView((ViewGroup)li.inflate(mainLayout(), mLayout, false)); + +      final Map<Integer, Boolean> state = new HashMap<Integer, Boolean>(); +      state.put(KeyEvent.KEYCODE_C, false); +      state.put(KeyEvent.KEYCODE_CTRL_LEFT, false); +      state.put(KeyEvent.KEYCODE_X, false); +      state.put(KeyEvent.KEYCODE_Z, false); +      state.put(KeyEvent.KEYCODE_DPAD_RIGHT, false); +      state.put(KeyEvent.KEYCODE_DPAD_LEFT, false); +      state.put(KeyEvent.KEYCODE_DPAD_DOWN, false); +      state.put(KeyEvent.KEYCODE_DPAD_UP, false); + +      final Map<Integer, Integer> bcode = new HashMap<Integer, Integer>(); +      bcode.put(0, KeyEvent.KEYCODE_Z); +      bcode.put(1, KeyEvent.KEYCODE_X); +      bcode.put(2, KeyEvent.KEYCODE_CTRL_LEFT); +      bcode.put(3, KeyEvent.KEYCODE_C); + +      av = (ActionView)findViewById(R.id.viewAction); +      av.setOnButtonListener(new InputView.InputEventListener() { +         @Override public void onInputEvent(View view, int buttons) { +            for (int i = 0; i < 4; ++i) { +               if (((0x01 << i) & buttons) > 0 && !state.get(bcode.get(i))) { +                  dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, bcode.get(i))); +                  state.put(bcode.get(i), true); +               } else if (state.get(bcode.get(i))) { +                  dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, bcode.get(i))); +                  state.put(bcode.get(i), false); +               } +            } +         } +      }); + +      final Map<Integer, Integer> dcode = new HashMap<Integer, Integer>(); +      dcode.put(0, KeyEvent.KEYCODE_DPAD_RIGHT); +      dcode.put(1, KeyEvent.KEYCODE_DPAD_DOWN); +      dcode.put(2, KeyEvent.KEYCODE_DPAD_LEFT); +      dcode.put(3, KeyEvent.KEYCODE_DPAD_UP); + +      dv = (ActionView)findViewById(R.id.viewDirection); +      dv.setOnButtonListener(new InputView.InputEventListener() { +         @Override public void onInputEvent(View view, int buttons) { +            for (int i = 0; i < 4; ++i) { +               if (((0x01 << i) & buttons) > 0 && !state.get(dcode.get(i))) { +                  dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, dcode.get(i))); +                  state.put(dcode.get(i), true); +               } else if (state.get(dcode.get(i))) { +                  dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, dcode.get(i))); +                  state.put(dcode.get(i), false); +               } +            } +         } +      }); + +      hider = (Button)findViewById(R.id.hider); +      hider.setOnButtonListener(new InputView.InputEventListener() { +         @Override public void onInputEvent(View view, int buttons) { +            if (((0x01 << 0) & buttons) > 0) { +               gamepadHidden = !gamepadHidden; +               if (gamepadHidden) { +                  if (hideFully()) { +                     dv.setVisibility(View.GONE); +                     av.setVisibility(View.GONE); +                  } else { +                     dv.setAlpha(0.f); +                     av.setAlpha(0.f); +                  } +                  hider.setAlpha((hideFully() ? 0.f : 0.25f)); +               } else { +                  if (hideFully()) { +                     dv.setVisibility(View.VISIBLE); +                     av.setVisibility(View.VISIBLE); +                  } else { +                     dv.setAlpha(0.5f); +                     av.setAlpha(0.5f); +                  } +                  hider.setAlpha(0.5f); +               } +            } +         } +      }); +   } +} diff --git a/src/pw/cloudef/rpg/Button.java b/src/pw/cloudef/rpg/Button.java new file mode 100644 index 0000000..5d444a4 --- /dev/null +++ b/src/pw/cloudef/rpg/Button.java @@ -0,0 +1,60 @@ +package pw.cloudef.rpg; +import com.andretietz.android.controller.InputView; +import android.annotation.TargetApi; +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.support.v7.content.res.AppCompatResources; +import android.util.AttributeSet; + +public class Button extends InputView { +    private static final int BUTTON_COUNT = 1; +    private Drawable[][] drawables = new Drawable[BUTTON_COUNT][2]; +    private int[][] resources = new int[BUTTON_COUNT][2]; + +    public Button(Context context) { +        super(context); +    } + +    public Button(Context context, AttributeSet attrs) { +        super(context, attrs); +        init(context, attrs); +    } + +    public Button(Context context, AttributeSet attrs, int defStyleAttr) { +        super(context, attrs, defStyleAttr); +        init(context, attrs); +    } + +    @TargetApi(Build.VERSION_CODES.LOLLIPOP) +    public Button(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { +        super(context, attrs, defStyleAttr, defStyleRes); +        init(context, attrs); +    } + +    protected void init(Context context, AttributeSet attrs) { +        TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.ActionView, 0, R.style.default_actionview); +        super.init(context, attrs, R.style.default_actionview); +        try { +            resources[0][0] = a.getResourceId(R.styleable.ActionView_button1_enabled, R.drawable.action_usual); +            resources[0][1] = a.getResourceId(R.styleable.ActionView_button1_pressed, R.drawable.action_pressed); +        } finally { +            a.recycle(); +        } +    } + +    @Override +    protected Drawable getStateDrawable(int buttonIndex, ButtonState state) { +        if (null == drawables[buttonIndex][state.ordinal()]) { +            drawables[buttonIndex][state.ordinal()] = AppCompatResources +                    .getDrawable(getContext(), resources[buttonIndex][state.ordinal()]); +        } +        return drawables[buttonIndex][state.ordinal()]; +    } + +    @Override +    protected int getButtonCount() { +        return BUTTON_COUNT; +    } +} diff --git a/src/pw/cloudef/rpg/Easyrpg.java b/src/pw/cloudef/rpg/Easyrpg.java new file mode 100644 index 0000000..6c8d3de --- /dev/null +++ b/src/pw/cloudef/rpg/Easyrpg.java @@ -0,0 +1,30 @@ +package pw.cloudef.rpg; +import android.os.Bundle; +import android.system.Os; + +public class Easyrpg extends Base { +   protected String[] getLibraries() { +      return new String[] { +         "easyrpg" +      }; +   } + +   protected String[] getArguments() { +      return new String[] { +         "--fullscreen", +         "--encoding", "932" +      }; +   } + +   protected String getRtpPath() { +      return "rtp"; +   } + +   protected void onCreate(Bundle savedInstanceState) { +      try { +         Os.setenv("COMPAT_PHYSFS_FILE", "game.zip", true); +         Os.setenv("COMPAT_PHYSFS_FIND", "RPG_RT.exe", true); +      } catch (Exception e) {} +      super.onCreate(savedInstanceState); +   } +} diff --git a/src/pw/cloudef/rpg/Launcher.java b/src/pw/cloudef/rpg/Launcher.java new file mode 100644 index 0000000..626ac14 --- /dev/null +++ b/src/pw/cloudef/rpg/Launcher.java @@ -0,0 +1,104 @@ +package pw.cloudef.rpg; +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.net.Uri; +import android.util.Log; +import android.system.Os; +import java.io.File; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.FileOutputStream; +import java.nio.charset.Charset; +import java.util.zip.ZipFile; +import java.util.zip.ZipEntry; +import java.util.Enumeration; + +public class Launcher extends Activity { +   protected String gameId() { +      return getIntent().getExtras().getString("id"); +   } + +   protected String zipPath() { +      return getApplicationContext().getCacheDir().toPath().toString() + "/" + gameId() + ".zip"; +   } + +   protected String baseDir() { +      return getApplicationContext().getFilesDir().toPath().toString() + "/data/" + gameId(); +   } + +   protected String rtpDir() { +      return getApplicationContext().getFilesDir().toPath().toString() + "/rtp"; +   } + +   enum GameType { +      UNKNOWN, +      EASYRPG, +      MKXP, +      NODEWEB, +   }; + +   protected Class getActivityForZip(File file) { +      ZipFile zipFile; +      try { +         zipFile = new ZipFile(file, java.util.zip.ZipFile.OPEN_READ, Charset.forName("Windows-31J")); +      } catch (Exception e) { +         Log.d("pw.cloudef.rpg", e.toString()); +         return null; +      } + +      try { +         Enumeration zipEntries = zipFile.entries(); +         GameType type = GameType.UNKNOWN; +         while (zipEntries.hasMoreElements()) { +            String fname = ((ZipEntry)zipEntries.nextElement()).getName(); +            try { +               String base = fname.split(".+?/(?=[^/]+$)")[1]; +               String name = base.split("\\.(?=[^\\.]+$)")[0]; +               if (name.toUpperCase().equals("RPG_RT")) type = GameType.EASYRPG; +               else if (name.toUpperCase().equals("GAME")) type = GameType.MKXP; +               else if (base.toUpperCase().equals("RPG_CORE.JS")) type = GameType.NODEWEB; +            } catch (Exception e2) {} +            if (type == GameType.EASYRPG || type == GameType.NODEWEB) break; +         } +         switch (type) { +            case EASYRPG: return Easyrpg.class; +            case MKXP: return Mkxp.class; +            case NODEWEB: return Nodeweb.class; +         } +      } catch (Exception e) { +         Log.d("pw.cloudef.rpg", e.toString()); +      } + +      try { zipFile.close(); } catch (Exception e) {} +      return null; +   } + +   protected void onCreate(Bundle savedInstanceState) { +      super.onCreate(savedInstanceState); +      try { +         InputStream input = getContentResolver().openInputStream(getIntent().getData()); +         File file = new File(zipPath()); +         OutputStream output = new FileOutputStream(file); +         byte[] buf = new byte[8 * 1024]; +         for (int read = 0; (read = input.read(buf)) != -1;) output.write(buf, 0, read); +         Class activity = getActivityForZip(file); +         if (activity == null) throw new Exception("Can't handle this game"); +         new File(baseDir()).mkdirs(); +         new File(rtpDir()).mkdirs(); +         try { Os.remove(baseDir() + "/game.zip"); } catch (Exception e2) {} +         Os.symlink(zipPath(), baseDir() + "/game.zip"); +         try { Os.remove(baseDir() + "/rtp"); } catch (Exception e2) {} +         Os.symlink(rtpDir(), baseDir() + "/rtp"); +         Intent intent = new Intent(this, activity); +         intent.putExtra("id", gameId()); +         startActivity(intent); +         finish(); +      } catch (Exception e) { +         Log.d("pw.cloudef.rpg", e.toString()); +         try { Os.remove(zipPath()); } catch (Exception e2) {} +         try { Os.remove(baseDir() + "/game.zip"); } catch (Exception e2) {} +      } +      finishAndRemoveTask(); +   } +} diff --git a/src/pw/cloudef/rpg/Mkxp.java b/src/pw/cloudef/rpg/Mkxp.java new file mode 100644 index 0000000..f221917 --- /dev/null +++ b/src/pw/cloudef/rpg/Mkxp.java @@ -0,0 +1,18 @@ +package pw.cloudef.rpg; +import android.os.Bundle; +import android.system.Os; + +public class Mkxp extends Base { +   protected String[] getLibraries() { +      return new String[] { +         "mkxp" +      }; +   } + +   protected String[] getArguments() { +      return new String[] { +         "--RTP", "rtp/vxace.zip", +         "--zip", "game.zip", +      }; +   } +} diff --git a/src/pw/cloudef/rpg/Nodeweb.java b/src/pw/cloudef/rpg/Nodeweb.java new file mode 100644 index 0000000..ba79f60 --- /dev/null +++ b/src/pw/cloudef/rpg/Nodeweb.java @@ -0,0 +1,58 @@ +package pw.cloudef.rpg; +import android.os.Bundle; +import android.webkit.WebView; +import android.webkit.WebSettings; +import android.webkit.WebViewClient; +import android.view.KeyEvent; +import android.util.Log; + +public class Nodeweb extends Base { +   private WebView web; + +   protected String[] getLibraries() { +      return new String[] { +         "physfs-serve" +      }; +   } + +   protected String[] getArguments() { +      return new String[] { +         "-p", "1337", +         "-i", "localhost", +         "game.zip", +         "mv-overlay.zip", +      }; +   } + +   protected int mainLayout() { +      return R.layout.webview; +   } + +   protected boolean hideFully() { +      return true; +   } + +   @Override +   public boolean dispatchKeyEvent(KeyEvent event) { +      return web.dispatchKeyEvent(event); +   } + +   protected void onCreate(Bundle savedInstanceState) { +      super.onCreate(savedInstanceState); +      web = (WebView)findViewById(R.id.web); +      web.loadUrl("http://127.0.0.1:1337?webgl"); +      web.getSettings().setJavaScriptEnabled(true); +      web.setWebContentsDebuggingEnabled(true); +      web.getSettings().setDomStorageEnabled(true); +      web.getSettings().setDatabaseEnabled(true); +      web.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE); +      web.setWebViewClient(new WebViewClient(){ +         public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { +            Log.v("nodeweb", "error: " + errorCode); +            view.loadUrl(failingUrl); +         }; +      }); +      setWindowStyle(true); +      setOrientation(0, 0, true, ""); +   } +} | 
