diff --git a/android/.classpath b/android/.classpath new file mode 100644 index 0000000000..6efcbb739a --- /dev/null +++ b/android/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/android/.project b/android/.project new file mode 100644 index 0000000000..7e8d136317 --- /dev/null +++ b/android/.project @@ -0,0 +1,33 @@ + + + Rockbox + + + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml new file mode 100644 index 0000000000..a22c393379 --- /dev/null +++ b/android/AndroidManifest.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/android/README b/android/README new file mode 100644 index 0000000000..e41bfa6c0c --- /dev/null +++ b/android/README @@ -0,0 +1,34 @@ +This folder contains the java parts needed to build an Rockbox as an +application for android. + +* Build instructions + +Until there's a script which does all the work the procedure is documented here. + +First, make sure you have the ANDROID_NDK_PATH environment variable set up, +otherwise configure will fail to find the compiler. + +Use this as your build folder, using '../tools/configure' etc. + $ ../tools/configure + $ make + +After the build finished, you need to copy librockbox.so to libs/armeabi/. + $ cp librockbox.so libs/armeabi + +For the other files (codecs, themes), you execute 'make zip'. Then you copy the +zip to libs/armeabi, using the name libmisc.so. This is needed, since there's no +way to bundle stuff into apk's and have access to them from native code other +than pretending it was a library. + $ make zip + $ cp rockbox.zip lib/armeabi/libmisc.so + +rockbox.zip..err, libmisc.so will be unpacked at runtime. + +To finish, you can follow this guide [1], or use eclipse. Simply install eclipse +and the android plugins, then import this folder as a new Android project and run it. +See [2] for a guide on how to set up eclipse for android development. + + + +[1]: http://asantoso.wordpress.com/2009/09/15/how-to-build-android-application-package-apk-from-the-command-line-using-the-sdk-tools-continuously-integrated-using-cruisecontrol/ +[2]: http://developer.android.com/sdk/installing.html diff --git a/android/default.properties b/android/default.properties new file mode 100644 index 0000000000..9d79b12c71 --- /dev/null +++ b/android/default.properties @@ -0,0 +1,11 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system use, +# "build.properties", and override values to adapt the script to your +# project structure. + +# Project target. +target=android-4 diff --git a/android/gen/org/rockbox/R.java b/android/gen/org/rockbox/R.java new file mode 100644 index 0000000000..38c177ef36 --- /dev/null +++ b/android/gen/org/rockbox/R.java @@ -0,0 +1,22 @@ +/* AUTO-GENERATED FILE. DO NOT MODIFY. + * + * This class was automatically generated by the + * aapt tool from the resource data it found. It + * should not be modified by hand. + */ + +package org.rockbox; + +public final class R { + public static final class attr { + } + public static final class drawable { + public static final int icon=0x7f020000; + } + public static final class layout { + public static final int main=0x7f030000; + } + public static final class string { + public static final int app_name=0x7f040000; + } +} diff --git a/android/res/drawable-hdpi/icon.png b/android/res/drawable-hdpi/icon.png new file mode 100644 index 0000000000..8074c4c571 Binary files /dev/null and b/android/res/drawable-hdpi/icon.png differ diff --git a/android/res/drawable-ldpi/icon.png b/android/res/drawable-ldpi/icon.png new file mode 100644 index 0000000000..1095584ec2 Binary files /dev/null and b/android/res/drawable-ldpi/icon.png differ diff --git a/android/res/drawable-mdpi/icon.png b/android/res/drawable-mdpi/icon.png new file mode 100644 index 0000000000..a07c69fa5a Binary files /dev/null and b/android/res/drawable-mdpi/icon.png differ diff --git a/android/res/layout/main.xml b/android/res/layout/main.xml new file mode 100644 index 0000000000..4361cfe8aa --- /dev/null +++ b/android/res/layout/main.xml @@ -0,0 +1,7 @@ + + + diff --git a/android/res/values/strings.xml b/android/res/values/strings.xml new file mode 100644 index 0000000000..6c3c8464fd --- /dev/null +++ b/android/res/values/strings.xml @@ -0,0 +1,5 @@ + + + + Rockbox + diff --git a/android/src/org/rockbox/RockboxActivity.java b/android/src/org/rockbox/RockboxActivity.java new file mode 100644 index 0000000000..791cad90ff --- /dev/null +++ b/android/src/org/rockbox/RockboxActivity.java @@ -0,0 +1,148 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 Thomas Martitz + * + * 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; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +package org.rockbox; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.util.Enumeration; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +import android.app.Activity; +import android.graphics.Rect; +import android.os.Bundle; +import android.util.Log; +import android.view.Window; +import android.view.WindowManager; + +public class RockboxActivity extends Activity { + /** Called when the activity is first created. */ + public RockboxFramebuffer fb; + private Thread rb; + static final int BUFFER = 2048; + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + LOG("start rb"); + requestWindowFeature(Window.FEATURE_NO_TITLE); + getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN + ,WindowManager.LayoutParams.FLAG_FULLSCREEN); + fb = new RockboxFramebuffer(this); + if (true) { + try + { + BufferedOutputStream dest = null; + BufferedInputStream is = null; + ZipEntry entry; + File file = new File("/data/data/org.rockbox/lib/libmisc.so"); + /* use arbitary file to determine whether extracting is needed */ + File file2 = new File("/data/data/org.rockbox/app_rockbox/rockbox/codecs/mpa.codec"); + if (!file2.exists() || (file.lastModified() > file2.lastModified())) + { + ZipFile zipfile = new ZipFile(file); + Enumeration e = zipfile.entries(); + File folder; + while(e.hasMoreElements()) { + entry = (ZipEntry) e.nextElement(); + LOG("Extracting: " +entry); + if (entry.isDirectory()) + { + folder = new File(entry.getName()); + LOG("mkdir "+ entry); + try { + folder.mkdirs(); + } catch (SecurityException ex){ + LOG(ex.getMessage()); + } + continue; + } + is = new BufferedInputStream(zipfile.getInputStream(entry)); + int count; + byte data[] = new byte[BUFFER]; + folder = new File(new File(entry.getName()).getParent()); + LOG("" + folder.getAbsolutePath()); + if (!folder.exists()) + folder.mkdirs(); + FileOutputStream fos = new FileOutputStream(entry.getName()); + dest = new BufferedOutputStream(fos, BUFFER); + while ((count = is.read(data, 0, BUFFER)) != -1) { + dest.write(data, 0, count); + } + dest.flush(); + dest.close(); + is.close(); + } + } + } catch(Exception e) { + e.printStackTrace(); + }} + Rect r = new Rect(); + fb.getDrawingRect(r); + LOG(r.left + " " + r.top + " " + r.right + " " + r.bottom); + rb = new Thread(new Runnable() + { + public void run() + { + main(); + } + },"Rockbox thread"); + System.loadLibrary("rockbox"); + rb.setDaemon(false); + setContentView(fb); + } + + private void LOG(CharSequence text) + { + Log.d("RockboxBootloader", (String) text); + } + + public synchronized void onStart() + { + super.onStart(); + if (!rb.isAlive()) + rb.start(); + } + + public void onPause() + { + super.onPause(); + } + + public void onResume() + { + super.onResume(); + switch (rb.getState()) { + case BLOCKED: LOG("BLOCKED"); break; + case RUNNABLE: LOG("RUNNABLE"); break; + case NEW: LOG("NEW"); break; + case TERMINATED: LOG("TERMINATED"); break; + case TIMED_WAITING: LOG("TIMED_WAITING"); break; + case WAITING: LOG("WAITING"); break; + } + } + + + private native void main(); +} \ No newline at end of file diff --git a/android/src/org/rockbox/RockboxFramebuffer.java b/android/src/org/rockbox/RockboxFramebuffer.java new file mode 100644 index 0000000000..f947806bb4 --- /dev/null +++ b/android/src/org/rockbox/RockboxFramebuffer.java @@ -0,0 +1,98 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 Thomas Martitz + * + * 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; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +package org.rockbox; + +import java.nio.ByteBuffer; +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.os.Handler; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; + +public class RockboxFramebuffer extends View +{ + private Bitmap btm; + private ByteBuffer native_buf; + private Handler update_handler; + private Runnable cb; + + + public RockboxFramebuffer(Context c) + { + super(c); + update_handler = new Handler(); + cb = new Runnable() { + public void run() + { + btm.copyPixelsFromBuffer(native_buf); + invalidate(); + } + }; + btm = null; + } + + public void onDraw(Canvas c) + { + if (btm != null) + c.drawBitmap(btm, 0.0f, 0.0f, null); + } + + public void java_lcd_init(int lcd_width, int lcd_height, ByteBuffer native_fb) + { + btm = Bitmap.createBitmap(lcd_width, lcd_height, Bitmap.Config.RGB_565); + native_buf = native_fb; + } + + public void java_lcd_update() + { + update_handler.post(cb); + } + + private void LOG(CharSequence text) + { + Log.d("RockboxBootloader", (String) text); + } + + public boolean onTouchEvent(MotionEvent me) + { + LOG("onTouchEvent"); + switch (me.getAction()) + { + case MotionEvent.ACTION_CANCEL: + case MotionEvent.ACTION_UP: + touchHandler(0); + break; + case MotionEvent.ACTION_MOVE: + case MotionEvent.ACTION_DOWN: + touchHandler(1); + break; + + } + pixelHandler((int)me.getX(), (int)me.getY()); + return true; + } + + public native void pixelHandler(int x, int y); + public native void touchHandler(int down); +} diff --git a/android/src/org/rockbox/RockboxPCM.java b/android/src/org/rockbox/RockboxPCM.java new file mode 100644 index 0000000000..f098df6991 --- /dev/null +++ b/android/src/org/rockbox/RockboxPCM.java @@ -0,0 +1,155 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 Thomas Martitz + * + * 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; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +package org.rockbox; + +import android.media.AudioFormat; +import android.media.AudioManager; +import android.media.AudioTrack; +import android.util.Log; + +public class RockboxPCM extends AudioTrack +{ + byte[] raw_data; + + private void LOG(CharSequence text) + { + Log.d("RockboxBootloader", (String) text); + } + + public RockboxPCM() + { + super(AudioManager.STREAM_MUSIC, + 44100, + /* should be CHANNEL_OUT_STEREO in 2.0 and above */ + AudioFormat.CHANNEL_CONFIGURATION_STEREO, + AudioFormat.ENCODING_PCM_16BIT, + 24<<10, + AudioTrack.MODE_STREAM); + int buf_len = 24<<10; + + raw_data = new byte[buf_len*2]; + for(int i = 0; i < raw_data.length; i++) raw_data[i] = (byte) 0x00; + /* fill with silence */ + write(raw_data, 0, raw_data.length); + if (getState() == AudioTrack.STATE_INITIALIZED) + { + if (setNotificationMarkerPosition(bytes2frames(buf_len*2)/4) != AudioTrack.SUCCESS) + LOG("setNotificationMarkerPosition Error"); + setPlaybackPositionUpdateListener(new PCMListener(buf_len*2)); + } + } + + + + int bytes2frames(int bytes) { + /* 1 sample is 2 bytes, 2 samples are 1 frame */ + return (bytes/4); + } + + int frames2bytes(int frames) { + /* 1 frame is 2 samples, 1 sample is 2 bytes */ + return (frames*4); + } + + @SuppressWarnings("unused") + private void play_pause(boolean pause) { + LOG("play_pause()"); + if (pause) + pause(); + else + { + if (getPlayState() == AudioTrack.PLAYSTATE_STOPPED) + { + for(int i = 0; i < raw_data.length; i++) raw_data[i] = (byte) 0x00; + LOG("Writing silence"); + /* fill with silence */ + write(raw_data, 0, raw_data.length); + } + play(); + } + LOG("play_pause() return"); + } + + @SuppressWarnings("unused") + private void set_volume(int volume) + { + /* volume comes from 0..-990 from Rockbox */ + /* TODO volume is in dB, but this code acts as if it were in %, convert? */ + float fvolume; + /* special case min and max volume to not suffer from floating point accuracy */ + if (volume == 0) + fvolume = 1.0f; + else if (volume == -990) + fvolume = 0.0f; + else + fvolume = (volume + 990)/990.0f; + setStereoVolume(fvolume, fvolume); + } + + public native void pcmSamplesToByteArray(byte[] dest); + + private class PCMListener implements OnPlaybackPositionUpdateListener { + int max_len; + byte[] buf; + public PCMListener(int len) { + max_len = len; + buf = new byte[len/2]; + } + @Override + public void onMarkerReached(AudioTrack track) { + // push new data to the hardware + int result = 1; + pcmSamplesToByteArray(buf); + //LOG("Trying to write " + buf.length + " bytes"); + result = track.write(buf, 0, buf.length); + if (result > 0) + { + //LOG(result + " bytes written"); + track.setPlaybackPositionUpdateListener(this); + track.setNotificationMarkerPosition(bytes2frames(max_len)/4); + switch(track.getPlayState()) + { + case AudioTrack.PLAYSTATE_PLAYING: + //LOG("State PLAYING"); + break; + case AudioTrack.PLAYSTATE_PAUSED: + LOG("State PAUSED"); + break; + case AudioTrack.PLAYSTATE_STOPPED: + LOG("State STOPPED"); + break; + } + } + else + { + LOG("Error in onMarkerReached"); + track.stop(); + } + } + + @Override + public void onPeriodicNotification(AudioTrack track) { + // TODO Auto-generated method stub + + } + } +} diff --git a/android/src/org/rockbox/RockboxTimer.java b/android/src/org/rockbox/RockboxTimer.java new file mode 100644 index 0000000000..c7239b4ee6 --- /dev/null +++ b/android/src/org/rockbox/RockboxTimer.java @@ -0,0 +1,93 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 Thomas Martitz + * + * 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; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +package org.rockbox; + +import java.util.Timer; +import java.util.TimerTask; + +import android.util.Log; + +public class RockboxTimer extends Timer +{ + RockboxTimerTask task; + long interval; + + private class RockboxTimerTask extends TimerTask { + private RockboxTimer t; + public RockboxTimerTask(RockboxTimer parent) { + super(); + t = parent; + } + + @Override + public void run() { + timerTask(); + synchronized(t) { + t.notify(); + } + } + } + + public void pause() + { + cancel(); + } + public void resume() + { + try { + schedule(task, 0, interval); + } catch (IllegalStateException e) { + /* not an error */ + } catch (Exception e) { + LOG(e.toString()); + } + } + + public RockboxTimer(long period_inverval_in_ms) + { + super("tick timer", false); + task = new RockboxTimerTask(this); + schedule(task, 0, period_inverval_in_ms); + interval = period_inverval_in_ms; + } + + private void LOG(CharSequence text) + { + Log.d("RockboxBootloader", (String) text); + } + + + /* methods called from native, keep them simple */ + public void java_wait_for_interrupt() + { + synchronized(this) { + try { + this.wait(); + } catch (InterruptedException e) { + /* wakeup and return */ + } catch (Exception e) { + LOG(e.toString()); + } + } + } + public native void timerTask(); +} diff --git a/apps/codecs/codec_crt0.c b/apps/codecs/codec_crt0.c index dd0f99ffd8..c680030fee 100644 --- a/apps/codecs/codec_crt0.c +++ b/apps/codecs/codec_crt0.c @@ -34,6 +34,10 @@ extern unsigned char plugin_end_addr[]; extern enum codec_status codec_main(void); +/* stub, the entry point is called via its reference in __header to + * avoid warning with certain compilers */ +int _start(void) {return 0;} + enum codec_status codec_start(void) { #if (CONFIG_PLATFORM & PLATFORM_NATIVE) diff --git a/apps/codecs/libwavpack/wavpack.h b/apps/codecs/libwavpack/wavpack.h index 5b5385a521..ee7c969b4c 100644 --- a/apps/codecs/libwavpack/wavpack.h +++ b/apps/codecs/libwavpack/wavpack.h @@ -16,7 +16,9 @@ typedef unsigned char uchar; typedef unsigned short ushort; +#if 0 // unused and causing compiler errrors typedef unsigned int uint; +#endif #include diff --git a/backdrops/cabbiev2.320x480x16.bmp b/backdrops/cabbiev2.320x480x16.bmp new file mode 100644 index 0000000000..6933fd0675 Binary files /dev/null and b/backdrops/cabbiev2.320x480x16.bmp differ diff --git a/bootloader/common.c b/bootloader/common.c index 362c3b4d11..1099b9f453 100644 --- a/bootloader/common.c +++ b/bootloader/common.c @@ -68,7 +68,7 @@ void reset_screen(void) #endif } -void printf(const char *format, ...) +int printf(const char *format, ...) { int len; unsigned char *ptr; @@ -91,6 +91,7 @@ void printf(const char *format, ...) if(remote_line >= LCD_REMOTE_HEIGHT/SYSFONT_HEIGHT) remote_line = 0; #endif + return len; } char *strerror(int error) diff --git a/bootloader/common.h b/bootloader/common.h index 6713585ad8..7d5425c9c8 100644 --- a/bootloader/common.h +++ b/bootloader/common.h @@ -41,7 +41,7 @@ extern bool verbose; /* Functions common to all bootloaders */ void reset_screen(void); -void printf(const char *format, ...); +int printf(const char *format, ...); char *strerror(int error); void error(int errortype, int error, bool shutdown); int load_firmware(unsigned char* buf, char* firmware, int buffer_size); diff --git a/firmware/SOURCES b/firmware/SOURCES index d8cfadef11..4092f71e04 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -1698,3 +1698,14 @@ target/coldfire/mpio/fmradio_i2c-mpio.c #endif /* BOOTLOADER */ #endif /* SIMULATOR */ #endif + + +#if (CONFIG_PLATFORM & PLATFORM_ANDROID) +target/hosted/android/lcd-android.c +target/hosted/android/button-android.c +target/hosted/android/kernel-android.c +target/hosted/android/pcm-android.c +target/hosted/android/system-android.c +drivers/audio/android.c +thread.c +#endif diff --git a/firmware/common/rbpaths.c b/firmware/common/rbpaths.c index 69bc1387ef..b63586c9f4 100644 --- a/firmware/common/rbpaths.c +++ b/firmware/common/rbpaths.c @@ -33,9 +33,13 @@ void paths_init(void) { /* make sure $HOME/.config/rockbox.org exists, it's needed for config.cfg */ +#if (CONFIG_PLATFORM & PLATFORM_ANDROID) + mkdir("/sdcard/rockbox"); +#else char home_path[MAX_PATH]; snprintf(home_path, sizeof(home_path), "%s/.config/rockbox.org", getenv("HOME")); mkdir(home_path); +#endif } const char* get_user_file_path(const char *path, @@ -50,7 +54,11 @@ const char* get_user_file_path(const char *path, pos += ROCKBOX_DIR_LEN; if (*pos == '/') pos += 1; +#if (CONFIG_PLATFORM & PLATFORM_ANDROID) + if (snprintf(buf, bufsize, "/sdcard/rockbox/%s", pos) +#else if (snprintf(buf, bufsize, "%s/.config/rockbox.org/%s", getenv("HOME"), pos) +#endif >= (int)bufsize) return NULL; diff --git a/firmware/drivers/audio/android.c b/firmware/drivers/audio/android.c new file mode 100644 index 0000000000..300bb08482 --- /dev/null +++ b/firmware/drivers/audio/android.c @@ -0,0 +1,61 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright © 2010 Thomas Martitz + * + * 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; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + + +#include "config.h" +#include "audiohw.h" + +const struct sound_settings_info audiohw_settings[] = { + [SOUND_VOLUME] = {"dB", 0, 1, VOLUME_MIN / 10, VOLUME_MAX / 10, -25}, +/* Bass and treble tone controls */ +#ifdef AUDIOHW_HAVE_BASS + [SOUND_BASS] = {"dB", 0, 1, -24, 24, 0}, +#endif +#ifdef AUDIOHW_HAVE_TREBLE + [SOUND_TREBLE] = {"dB", 0, 1, -24, 24, 0}, +#endif + [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0}, + [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0}, + [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100}, +#if defined(HAVE_RECORDING) + [SOUND_LEFT_GAIN] = {"dB", 1, 1,-128, 96, 0}, + [SOUND_RIGHT_GAIN] = {"dB", 1, 1,-128, 96, 0}, + [SOUND_MIC_GAIN] = {"dB", 1, 1,-128, 108, 16}, +#endif +#if defined(AUDIOHW_HAVE_BASS_CUTOFF) + [SOUND_BASS_CUTOFF] = {"", 0, 1, 1, 4, 1}, +#endif +#if defined(AUDIOHW_HAVE_TREBLE_CUTOFF) + [SOUND_TREBLE_CUTOFF] = {"", 0, 1, 1, 4, 1}, +#endif +}; + + +void audiohw_set_volume(int volume) +{ + extern void pcm_set_mixer_volume(int); + pcm_set_mixer_volume(volume); +} + +void audiohw_set_balance(int balance) +{ + (void)balance; +} diff --git a/firmware/export/audiohw.h b/firmware/export/audiohw.h index d4861aac5a..658dd1301c 100644 --- a/firmware/export/audiohw.h +++ b/firmware/export/audiohw.h @@ -66,7 +66,7 @@ #elif defined(HAVE_AK4537) #include "ak4537.h" #endif -#if defined(HAVE_SDL_AUDIO) +#if (CONFIG_PLATFORM & PLATFORM_HOSTED) /* #include gives errors in other code areas, * we don't really need it here, so don't. but it should maybe be fixed */ #ifndef SIMULATOR /* simulator gets values from the target .h files */ diff --git a/firmware/export/config.h b/firmware/export/config.h index 1b8a782f39..3b59004549 100644 --- a/firmware/export/config.h +++ b/firmware/export/config.h @@ -78,8 +78,10 @@ * bit fields to allow PLATFORM_HOSTED to be OR'ed e.g. with a * possible future PLATFORM_ANDROID (some OSes might need totally different * handling to run on them than a stand-alone application) */ -#define PLATFORM_NATIVE (1<<0) -#define PLATFORM_HOSTED (1<<1) +#define PLATFORM_NATIVE (1<<0) +#define PLATFORM_HOSTED (1<<1) +#define PLATFORM_ANDROID (1<<2) +#define PLATFORM_SDL (1<<3) /* CONFIG_KEYPAD */ #define PLAYER_PAD 1 @@ -427,6 +429,8 @@ Lyre prototype 1 */ #elif defined(APPLICATION) #include "config/application.h" +#define CONFIG_CPU 0 +#define CONFIG_STORAGE 0 #else /* no known platform */ #endif @@ -689,11 +693,17 @@ Lyre prototype 1 */ #define HAVE_EXTENDED_MESSAGING_AND_NAME #define HAVE_WAKEUP_EXT_CB + +#if (CONFIG_PLATFORM & PLATFORM_ANDROID) +#define HAVE_PRIORITY_SCHEDULING +#endif + #if (CONFIG_PLATFORM & PLATFORM_NATIVE) #define HAVE_PRIORITY_SCHEDULING #define HAVE_SCHEDULER_BOOSTCTRL #endif /* PLATFORM_NATIVE */ + #define HAVE_SEMAPHORE_OBJECTS #if defined(HAVE_USBSTACK) && CONFIG_USBOTG == USBOTG_ARC diff --git a/firmware/export/config/application.h b/firmware/export/config/application.h index a5583ded75..988f0d51ac 100644 --- a/firmware/export/config/application.h +++ b/firmware/export/config/application.h @@ -4,11 +4,13 @@ #define TARGET_TREE /* this target is using the target tree system */ /* We don't run on hardware directly */ -#define CONFIG_PLATFORM PLATFORM_HOSTED +#ifdef ANDROID +#define CONFIG_PLATFORM (PLATFORM_HOSTED|PLATFORM_ANDROID) +#else +#define CONFIG_PLATFORM (PLATFORM_HOSTED|PLATFORM_SDL) +#endif /* For Rolo and boot loader */ -/* -#define MODEL_NUMBER 24 -*/ +#define MODEL_NUMBER 100 #define MODEL_NAME "Rockbox" @@ -37,9 +39,17 @@ /* define this if you would like tagcache to build on this target */ #define HAVE_TAGCACHE -/* LCD dimensions */ +/* LCD dimensions + * + * overriden by configure for application builds */ +#ifndef LCD_WIDTH #define LCD_WIDTH 320 -#define LCD_HEIGHT 240 +#endif + +#ifndef LCD_HEIGHT +#define LCD_HEIGHT 480 +#endif + #define LCD_DEPTH 16 #define LCD_PIXELFORMAT 565 @@ -62,10 +72,10 @@ #define CONFIG_CODEC SWCODEC #define CONFIG_KEYPAD COWON_D2_PAD + +#if (CONFIG_PLATFORM & PLATFORM_SDL) /* Use SDL audio/pcm in a SDL app build */ #define HAVE_SDL - -#ifdef HAVE_SDL #define HAVE_SDL_AUDIO #endif @@ -92,3 +102,5 @@ /* Define this if a programmable hotkey is mapped */ //#define HAVE_HOTKEY + +#define BOOTDIR "/.rockbox" diff --git a/firmware/export/config/sim.h b/firmware/export/config/sim.h index 5dcb4f6f2d..066201ad08 100644 --- a/firmware/export/config/sim.h +++ b/firmware/export/config/sim.h @@ -99,7 +99,8 @@ #define DEFAULT_BRIGHTNESS_SETTING MAX_BRIGHTNESS_SETTING #endif +#define CONFIG_PLATFORM (PLATFORM_HOSTED|PLATFORM_SDL) #define HAVE_SDL #define HAVE_SDL_AUDIO -#define CONFIG_PLATFORM PLATFORM_HOSTED + #define _ISOC99_SOURCE 1 diff --git a/firmware/export/debug.h b/firmware/export/debug.h index f7f0f32426..f19a96c526 100644 --- a/firmware/export/debug.h +++ b/firmware/export/debug.h @@ -21,6 +21,7 @@ #ifndef DEBUG_H #define DEBUG_H +#include "config.h" #include "gcc_extensions.h" extern void debug_init(void); @@ -34,7 +35,11 @@ extern void ldebugf(const char* file, int line, const char *fmt, ...) /* */ #if defined(SIMULATOR) && !defined(__PCTOOL__) #define DEBUGF debugf -#define LDEBUGF(...) ldebugf(__FILE__, __LINE__, __VA_ARGS__) +#define LDEBUGF(...) ldebugf(__FILE__, __LINE__, __VA_ARGS__) && defined(DEBUG) +#elif (CONFIG_PLATFORM & PLATFORM_ANDROID) +#include "system-target.h" +#define DEBUGF LOG +#define LDEBUGF(...) #else #if defined(DEBUG) diff --git a/firmware/export/thread.h b/firmware/export/thread.h index c4b7d1fa22..2853c0b121 100644 --- a/firmware/export/thread.h +++ b/firmware/export/thread.h @@ -79,9 +79,19 @@ #define MAXTHREADS (BASETHREADS+TARGET_EXTRA_THREADS) +/* + * We need more stack when we run under a host + * maybe more expensive C lib functions? + * + * simulator doesn't simulate stack usage anyway but well ... */ +#if ((CONFIG_PLATFORM & PLATFORM_NATIVE) || defined(SIMULATOR)) #define DEFAULT_STACK_SIZE 0x400 /* Bytes */ +#else +#define DEFAULT_STACK_SIZE 0x1000 /* Bytes */ +#endif -#if (CONFIG_PLATFORM & PLATFORM_NATIVE) + +#if (CONFIG_PLATFORM & (PLATFORM_NATIVE|PLATFORM_ANDROID)) /* Need to keep structures inside the header file because debug_menu * needs them. */ #ifdef CPU_COLDFIRE @@ -101,7 +111,7 @@ struct regs uint32_t pr; /* 32 - Procedure register */ uint32_t start; /* 36 - Thread start address, or NULL when started */ }; -#elif defined(CPU_ARM) +#elif defined(CPU_ARM) || (CONFIG_PLATFORM & PLATFORM_ANDROID) struct regs { uint32_t r[8]; /* 0-28 - Registers r4-r11 */ diff --git a/firmware/sound.c b/firmware/sound.c index 76f1dd0df6..4cc63f4583 100644 --- a/firmware/sound.c +++ b/firmware/sound.c @@ -273,7 +273,7 @@ static void set_prescaled_volume(void) #elif defined(HAVE_TLV320) || defined(HAVE_WM8978) || defined(HAVE_WM8985) audiohw_set_headphone_vol(tenthdb2master(l), tenthdb2master(r)); -#elif defined(HAVE_JZ4740_CODEC) || defined(HAVE_SDL_AUDIO) +#elif defined(HAVE_JZ4740_CODEC) || defined(HAVE_SDL_AUDIO) || defined(ANDROID) audiohw_set_volume(current_volume); #endif #else /* HAVE_SDL_AUDIO */ diff --git a/firmware/target/hosted/android/app/adc-target.h b/firmware/target/hosted/android/app/adc-target.h new file mode 100644 index 0000000000..f8069be6f5 --- /dev/null +++ b/firmware/target/hosted/android/app/adc-target.h @@ -0,0 +1,25 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 by Thomas Martitz + * + * 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; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifndef __ADC_TARGET_H__ +#define __ADC_TARGET_H__ + +#endif /* __ADC_TARGET_H__ */ diff --git a/firmware/target/hosted/android/app/backlight-target.h b/firmware/target/hosted/android/app/backlight-target.h new file mode 100644 index 0000000000..f753e7c1dd --- /dev/null +++ b/firmware/target/hosted/android/app/backlight-target.h @@ -0,0 +1,25 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 by Thomas Martitz + * + * 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; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifndef __BACKLIGHT_TARGET_H__ +#define __BACKLIGHT_TARGET_H__ + +#endif /* __BACKLIGHT_TARGET_H__ */ diff --git a/firmware/target/hosted/android/app/button-application.c b/firmware/target/hosted/android/app/button-application.c new file mode 100644 index 0000000000..a27f769718 --- /dev/null +++ b/firmware/target/hosted/android/app/button-application.c @@ -0,0 +1,29 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 Thomas Martitz + * + * 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; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************9*************************/ + + +#include "button.h" + +int key_to_button(int keyboard_key) +{ + (void)keyboard_key; + return BUTTON_NONE; +} diff --git a/firmware/target/hosted/android/app/button-target.h b/firmware/target/hosted/android/app/button-target.h new file mode 100644 index 0000000000..329ed651af --- /dev/null +++ b/firmware/target/hosted/android/app/button-target.h @@ -0,0 +1,64 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2007 by Rob Purchase + * + * 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; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifndef _BUTTON_TARGET_H_ +#define _BUTTON_TARGET_H_ + +#include +#include "config.h" + +#undef button_init_device +void button_init_device(void); +int button_read_device(int *data); + +/* Main unit's buttons */ +#define BUTTON_POWER 0x00000001 +#define BUTTON_PLUS 0x00000002 +#define BUTTON_MINUS 0x00000004 +#define BUTTON_MENU 0x00000008 + +/* Compatibility hacks for flipping. Needs a somewhat better fix. */ +#define BUTTON_LEFT BUTTON_MIDLEFT +#define BUTTON_RIGHT BUTTON_MIDRIGHT +#define BUTTON_UP BUTTON_TOPMIDDLE +#define BUTTON_DOWN BUTTON_BOTTOMMIDDLE + +/* Touch Screen Area Buttons */ +#define BUTTON_TOPLEFT 0x00000010 +#define BUTTON_TOPMIDDLE 0x00000020 +#define BUTTON_TOPRIGHT 0x00000040 +#define BUTTON_MIDLEFT 0x00000080 +#define BUTTON_CENTER 0x00000100 +#define BUTTON_MIDRIGHT 0x00000200 +#define BUTTON_BOTTOMLEFT 0x00000400 +#define BUTTON_BOTTOMMIDDLE 0x00000800 +#define BUTTON_BOTTOMRIGHT 0x00001000 + +#define BUTTON_MAIN 0x1FFF + +/* No remote */ +#define BUTTON_REMOTE 0 + +/* Software power-off */ +#define POWEROFF_BUTTON BUTTON_POWER +#define POWEROFF_COUNT 10 + +#endif /* _BUTTON_TARGET_H_ */ diff --git a/firmware/target/hosted/android/app/i2c-target.h b/firmware/target/hosted/android/app/i2c-target.h new file mode 100644 index 0000000000..89f0436b9e --- /dev/null +++ b/firmware/target/hosted/android/app/i2c-target.h @@ -0,0 +1,25 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 by Thomas Martitz + * + * 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; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifndef __I2C_TARGET_H__ +#define __I2C_TARGET_H__ + +#endif /* __I2C_TARGET_H__ */ diff --git a/firmware/target/hosted/android/app/usb-target.h b/firmware/target/hosted/android/app/usb-target.h new file mode 100644 index 0000000000..10e04677f9 --- /dev/null +++ b/firmware/target/hosted/android/app/usb-target.h @@ -0,0 +1,25 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 by Thomas Martitz + * + * 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; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifndef __USB_TARGET_H__ +#define __USB_TARGET_H__ + +#endif /* __USB_TARGET_H__ */ diff --git a/firmware/target/hosted/android/button-android.c b/firmware/target/hosted/android/button-android.c new file mode 100644 index 0000000000..67e8ca1f89 --- /dev/null +++ b/firmware/target/hosted/android/button-android.c @@ -0,0 +1,87 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (c) 2010 Thomas Martitz + * + * 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; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + + +#include +#include +#include "config.h" +#include "kernel.h" +#include "system.h" +#include "touchscreen.h" + +static long last_touch; +static int last_y, last_x; + +static enum { + STATE_UNKNOWN, + STATE_UP, + STATE_DOWN, +} last_state = STATE_UNKNOWN; + + +/* + * this writes in an interrupt-like fashion the last pixel coordinates + * that the user pressed on the screen */ +JNIEXPORT void JNICALL +Java_org_rockbox_RockboxFramebuffer_pixelHandler(JNIEnv*env, jobject this, + int x, int y) +{ + (void)env; + (void)this; + last_x = x; + last_y = y; + last_touch = current_tick; +} + +/* + * this notifies us in an interrupt-like fashion whether the user just + * began or stopped the touch action */ +JNIEXPORT void JNICALL +Java_org_rockbox_RockboxFramebuffer_touchHandler(JNIEnv*env, jobject this, + int down) +{ + (void)env; + (void)this; + if (down) + last_state = STATE_DOWN; + else + last_state = STATE_UP; +} + +void button_init_device(void) +{ + last_touch = current_tick; +} + +int button_read_device(int *data) +{ + /* get grid button/coordinates based on the current touchscreen mode */ + int btn = touchscreen_to_pixels(last_x, last_y, data); + if (last_state == STATE_DOWN) + { + return btn; + } + else + { + *data = last_x = last_y = 0; + return 0; + } +} diff --git a/firmware/target/hosted/android/buttonmap.h b/firmware/target/hosted/android/buttonmap.h new file mode 100644 index 0000000000..e90b8a40d4 --- /dev/null +++ b/firmware/target/hosted/android/buttonmap.h @@ -0,0 +1,43 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 by Fred Bauer + * + * 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; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifndef __BUTTONMAP_H__ +#define __BUTTONMAP_H__ +/* Button maps: simulated key, x, y, radius, name */ +/* Run sim with --mapping to get coordinates */ +/* or --debugbuttons to check */ +/* The First matching button is returned */ +struct button_map { + int button, x, y, radius; + char *description; +}; + +extern struct button_map bm[]; + +int xy2button( int x, int y); + +/* for the sim, these function is implemented in uisimulator/buttonmap/ *.c */ +int key_to_button(int keyboard_button); +#ifdef HAVE_TOUCHSCREEN +int key_to_touch(int keyboard_button, unsigned int mouse_coords); +#endif + +#endif /* __BUTTONMAP_H__ */ diff --git a/firmware/target/hosted/android/kernel-android.c b/firmware/target/hosted/android/kernel-android.c new file mode 100644 index 0000000000..9594516460 --- /dev/null +++ b/firmware/target/hosted/android/kernel-android.c @@ -0,0 +1,106 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (c) 2010 Thomas Martitz + * + * 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; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + + +#include +#include "config.h" +#include "system.h" + +extern JNIEnv *env_ptr; +extern jclass RockboxActivity_class; +extern jobject RockboxActivity_instance; + +static jclass RockboxTimer_class; +static jobject RockboxTimer_instance; +static jmethodID java_wait_for_interrupt; +static bool initialized = false; + +/* + * This is called from the separate Timer java thread. I have not added any + * interrupt simulation to it (like the sdl counterpart does), + * I think this is probably not needed, unless code calls disable_interrupt() + * in order to be protected from tick tasks, but I can't remember a place right + * now. + * + * No synchronisation mechanism either. This could possibly be problematic, + * but we'll see :) + */ +JNIEXPORT void JNICALL +Java_org_rockbox_RockboxTimer_timerTask(JNIEnv *env, jobject this) +{ + (void)env; + (void)this; + call_tick_tasks(); +} + +void tick_start(unsigned int interval_in_ms) +{ + JNIEnv e = *env_ptr; + /* first, create a new Timer instance */ + RockboxTimer_class = e->FindClass(env_ptr, "org/rockbox/RockboxTimer"); + jmethodID constructor = e->GetMethodID(env_ptr, + RockboxTimer_class, + "", + "(J)V"); + /* the constructor will do the tick_start */ + RockboxTimer_instance = e->NewObject(env_ptr, + RockboxTimer_class, + constructor, + (jlong)interval_in_ms); + + /* get our wfi func also */ + java_wait_for_interrupt = e->GetMethodID(env_ptr, + RockboxTimer_class, + "java_wait_for_interrupt", + "()V"); + /* it's now safe to call java_wait_for_interrupt */ + initialized = true; +} + +void wait_for_interrupt(void) +{ + if (LIKELY(initialized)) + { + (*env_ptr)->CallVoidMethod(env_ptr, + RockboxTimer_instance, + java_wait_for_interrupt); + } +} + +bool timer_register(int reg_prio, void (*unregister_callback)(void), + long cycles, void (*timer_callback)(void)) +{ + (void)reg_prio; + (void)unregister_callback; + (void)cycles; + (void)timer_callback; + return false; +} + +bool timer_set_period(long cycles) +{ + (void)cycles; + return false; +} + +void timer_unregister(void) +{ +} diff --git a/firmware/target/hosted/android/lcd-android.c b/firmware/target/hosted/android/lcd-android.c new file mode 100644 index 0000000000..ef4004ef2a --- /dev/null +++ b/firmware/target/hosted/android/lcd-android.c @@ -0,0 +1,291 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (c) 2010 Thomas Martitz + * + * 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; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + + +#include +#include "config.h" +#include "system.h" +#include "lcd.h" + +extern JNIEnv *env_ptr; +extern jclass RockboxActivity_class; +extern jobject RockboxActivity_instance; + +static jobject Framebuffer_instance; +static jmethodID java_lcd_update; + +void lcd_init_device(void) +{ + /* get the RockboxFramebuffer instance allocated by the activity */ + jfieldID id = (*env_ptr)->GetFieldID(env_ptr, + RockboxActivity_class, + "fb", + "Lorg/rockbox/RockboxFramebuffer;"); + + Framebuffer_instance = (*env_ptr)->GetObjectField(env_ptr, + RockboxActivity_instance, + id); + + jclass Framebuffer_class = (*env_ptr)->GetObjectClass(env_ptr, + Framebuffer_instance); + + /* get the java init function and call it. it'll set up a bitmap + * based on LCD_WIDTH, LCD_HEIGHT and the ByteBuffer which directly maps + * our framebuffer */ + + jmethodID java_init_lcd = (*env_ptr)->GetMethodID(env_ptr, + Framebuffer_class, + "java_lcd_init", + "(IILjava/nio/ByteBuffer;)V"); + java_lcd_update = (*env_ptr)->GetMethodID(env_ptr, + Framebuffer_class, + "java_lcd_update", + "()V"); + + /* map the framebuffer to a ByteBuffer, this way lcd updates will + * be directly feched from the framebuffer */ + jobject buf = (*env_ptr)->NewDirectByteBuffer(env_ptr, + lcd_framebuffer, + sizeof(lcd_framebuffer)); + + (*env_ptr)->CallVoidMethod(env_ptr, + Framebuffer_instance, + java_init_lcd, + LCD_WIDTH, LCD_HEIGHT, buf); +} + +void lcd_update() +{ + /* tell the system we're ready for drawing */ + (*env_ptr)->CallVoidMethod(env_ptr, Framebuffer_instance, java_lcd_update); +} + +void lcd_update_rect(int x, int y, int height, int width) +{ + /* can't do partial updates yet */ + (void)x; (void)y; (void)height; (void)width; + lcd_update(); +} + +/* below is a plain copy from lcd-sdl.c */ + +/** + * |R| |1.000000 -0.000001 1.402000| |Y'| + * |G| = |1.000000 -0.334136 -0.714136| |Pb| + * |B| |1.000000 1.772000 0.000000| |Pr| + * Scaled, normalized, rounded and tweaked to yield RGB 565: + * |R| |74 0 101| |Y' - 16| >> 9 + * |G| = |74 -24 -51| |Cb - 128| >> 8 + * |B| |74 128 0| |Cr - 128| >> 9 + */ +#define YFAC (74) +#define RVFAC (101) +#define GUFAC (-24) +#define GVFAC (-51) +#define BUFAC (128) + +static inline int clamp(int val, int min, int max) +{ + if (val < min) + val = min; + else if (val > max) + val = max; + return val; +} + +void lcd_yuv_set_options(unsigned options) +{ + (void)options; +} + +/* Draw a partial YUV colour bitmap - similiar behavior to lcd_blit_yuv + in the core */ +void lcd_blit_yuv(unsigned char * const src[3], + int src_x, int src_y, int stride, + int x, int y, int width, int height) +{ + const unsigned char *ysrc, *usrc, *vsrc; + int linecounter; + fb_data *dst, *row_end; + long z; + + /* width and height must be >= 2 and an even number */ + width &= ~1; + linecounter = height >> 1; + +#if LCD_WIDTH >= LCD_HEIGHT + dst = &lcd_framebuffer[y][x]; + row_end = dst + width; +#else + dst = &lcd_framebuffer[x][LCD_WIDTH - y - 1]; + row_end = dst + LCD_WIDTH * width; +#endif + + z = stride * src_y; + ysrc = src[0] + z + src_x; + usrc = src[1] + (z >> 2) + (src_x >> 1); + vsrc = src[2] + (usrc - src[1]); + + /* stride => amount to jump from end of last row to start of next */ + stride -= width; + + /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */ + + do + { + do + { + int y, cb, cr, rv, guv, bu, r, g, b; + + y = YFAC*(*ysrc++ - 16); + cb = *usrc++ - 128; + cr = *vsrc++ - 128; + + rv = RVFAC*cr; + guv = GUFAC*cb + GVFAC*cr; + bu = BUFAC*cb; + + r = y + rv; + g = y + guv; + b = y + bu; + + if ((unsigned)(r | g | b) > 64*256-1) + { + r = clamp(r, 0, 64*256-1); + g = clamp(g, 0, 64*256-1); + b = clamp(b, 0, 64*256-1); + } + + *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9); + +#if LCD_WIDTH >= LCD_HEIGHT + dst++; +#else + dst += LCD_WIDTH; +#endif + + y = YFAC*(*ysrc++ - 16); + r = y + rv; + g = y + guv; + b = y + bu; + + if ((unsigned)(r | g | b) > 64*256-1) + { + r = clamp(r, 0, 64*256-1); + g = clamp(g, 0, 64*256-1); + b = clamp(b, 0, 64*256-1); + } + + *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9); + +#if LCD_WIDTH >= LCD_HEIGHT + dst++; +#else + dst += LCD_WIDTH; +#endif + } + while (dst < row_end); + + ysrc += stride; + usrc -= width >> 1; + vsrc -= width >> 1; + +#if LCD_WIDTH >= LCD_HEIGHT + row_end += LCD_WIDTH; + dst += LCD_WIDTH - width; +#else + row_end -= 1; + dst -= LCD_WIDTH*width + 1; +#endif + + do + { + int y, cb, cr, rv, guv, bu, r, g, b; + + y = YFAC*(*ysrc++ - 16); + cb = *usrc++ - 128; + cr = *vsrc++ - 128; + + rv = RVFAC*cr; + guv = GUFAC*cb + GVFAC*cr; + bu = BUFAC*cb; + + r = y + rv; + g = y + guv; + b = y + bu; + + if ((unsigned)(r | g | b) > 64*256-1) + { + r = clamp(r, 0, 64*256-1); + g = clamp(g, 0, 64*256-1); + b = clamp(b, 0, 64*256-1); + } + + *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9); + +#if LCD_WIDTH >= LCD_HEIGHT + dst++; +#else + dst += LCD_WIDTH; +#endif + + y = YFAC*(*ysrc++ - 16); + r = y + rv; + g = y + guv; + b = y + bu; + + if ((unsigned)(r | g | b) > 64*256-1) + { + r = clamp(r, 0, 64*256-1); + g = clamp(g, 0, 64*256-1); + b = clamp(b, 0, 64*256-1); + } + + *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9); + +#if LCD_WIDTH >= LCD_HEIGHT + dst++; +#else + dst += LCD_WIDTH; +#endif + } + while (dst < row_end); + + ysrc += stride; + usrc += stride >> 1; + vsrc += stride >> 1; + +#if LCD_WIDTH >= LCD_HEIGHT + row_end += LCD_WIDTH; + dst += LCD_WIDTH - width; +#else + row_end -= 1; + dst -= LCD_WIDTH*width + 1; +#endif + } + while (--linecounter > 0); + +#if LCD_WIDTH >= LCD_HEIGHT + lcd_update_rect(x, y, width, height); +#else + lcd_update_rect(LCD_WIDTH - y - height, x, height, width); +#endif +} diff --git a/firmware/target/hosted/android/pcm-android.c b/firmware/target/hosted/android/pcm-android.c new file mode 100644 index 0000000000..91978f422b --- /dev/null +++ b/firmware/target/hosted/android/pcm-android.c @@ -0,0 +1,174 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (c) 2010 Thomas Martitz + * + * 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; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include +#include +#include +#include "pcm.h" + +extern JNIEnv *env_ptr; +extern jclass RockboxActivity_class; +extern jobject RockboxActivity_instance; + +/* infos about our pcm chunks */ +static size_t pcm_data_size; +static char *pcm_data_start; + +/* cache frequently called methods */ +static jmethodID play_pause_method; +static jmethodID stop_method; +static jmethodID set_volume_method; +static jclass RockboxPCM_class; +static jobject RockboxPCM_instance; + + +/* + * transfer our raw data into a java array + * + * a bit of a monster functions, but it should cover all cases to overcome + * the issue that the chunk size of the java layer and our pcm chunks are + * differently sized + * + * afterall, it only copies the raw pcm data from pcm_data_start to + * the passed byte[]-array + * + * it is called from the PositionMarker callback of AudioTrack + **/ +JNIEXPORT void JNICALL +Java_org_rockbox_RockboxPCM_pcmSamplesToByteArray(JNIEnv *env, + jobject this, + jbyteArray arr) +{ + (void)this; + size_t len; + size_t array_size = (*env)->GetArrayLength(env, arr); + if (array_size > pcm_data_size) + len = pcm_data_size; + else + len = array_size; + + (*env)->SetByteArrayRegion(env, arr, 0, len, pcm_data_start); + + if (array_size > pcm_data_size) + { /* didn't have enough data for the array ? */ + size_t remaining = array_size - pcm_data_size; + size_t offset = len; + retry: + pcm_play_get_more_callback((void**)&pcm_data_start, &pcm_data_size); + if (pcm_data_size == 0) + return; + if (remaining > pcm_data_size) + { /* got too little data, get more ... */ + (*env)->SetByteArrayRegion(env, arr, offset, pcm_data_size, pcm_data_start); + /* advance in the java array by the amount we copied */ + offset += pcm_data_size; + /* we copied at least a bit */ + remaining -= pcm_data_size; + /* let's get another buch of data and try again */ + goto retry; + } + else + (*env)->SetByteArrayRegion(env, arr, offset, remaining, pcm_data_start); + len = remaining; + } + pcm_data_start += len; + pcm_data_size -= len; +} + +void pcm_play_lock(void) +{ +} + +void pcm_play_unlock(void) +{ +} + +void pcm_dma_apply_settings(void) +{ +} + +void pcm_play_dma_start(const void *addr, size_t size) +{ + pcm_data_start = (char*)addr; + pcm_data_size = size; + + pcm_play_dma_pause(false); +} + +void pcm_play_dma_stop(void) +{ + (*env_ptr)->CallVoidMethod(env_ptr, + RockboxPCM_instance, + stop_method); +} + +void pcm_play_dma_pause(bool pause) +{ + (*env_ptr)->CallVoidMethod(env_ptr, + RockboxPCM_instance, + play_pause_method, + (int)pause); +} + +size_t pcm_get_bytes_waiting(void) +{ + return pcm_data_size; +} + +const void * pcm_play_dma_get_peak_buffer(int *count) +{ + uintptr_t addr = (uintptr_t)pcm_data_start; + *count = pcm_data_size / 4; + return (void *)((addr + 3) & ~3); +} + +void pcm_play_dma_init(void) +{ + /* in order to have background music playing after leaving the activity, + * we need to allocate the PCM object from the Rockbox thread (the Activity + * runs in a separate thread because it would otherwise kill us when + * stopping it) + * + * Luckily we only reference the PCM object from here, so it's safe (and + * clean) to allocate it here + **/ + JNIEnv e = *env_ptr; + /* get the class and its constructor */ + RockboxPCM_class = e->FindClass(env_ptr, "org/rockbox/RockboxPCM"); + jmethodID constructor = e->GetMethodID(env_ptr, RockboxPCM_class, "", "()V"); + /* instance = new RockboxPCM() */ + RockboxPCM_instance = e->NewObject(env_ptr, RockboxPCM_class, constructor); + /* cache needed methods */ + play_pause_method = e->GetMethodID(env_ptr, RockboxPCM_class, "play_pause", "(Z)V"); + set_volume_method = e->GetMethodID(env_ptr, RockboxPCM_class, "set_volume", "(I)V"); + stop_method = e->GetMethodID(env_ptr, RockboxPCM_class, "stop", "()V"); + /* get initial pcm data, if any */ + pcm_play_get_more_callback((void*)&pcm_data_start, &pcm_data_size); +} + +void pcm_postinit(void) +{ +} + +void pcm_set_mixer_volume(int volume) +{ + (*env_ptr)->CallVoidMethod(env_ptr, RockboxPCM_instance, set_volume_method, volume); +} diff --git a/firmware/target/hosted/android/system-android.c b/firmware/target/hosted/android/system-android.c new file mode 100644 index 0000000000..07dff2ed56 --- /dev/null +++ b/firmware/target/hosted/android/system-android.c @@ -0,0 +1,59 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (c) 2010 Thomas Martitz + * + * 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; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + + +#include +#include "config.h" +#include "system.h" + +void system_exception_wait(void) { } +void system_reboot(void) { } +void power_off(void) { } +void system_init(void) { } + + +/* global fields for use with various JNI calls */ +JNIEnv *env_ptr; +jobject RockboxActivity_instance; +jclass RockboxActivity_class; + +uintptr_t *stackbegin; +uintptr_t *stackend; + +extern int main(void); +/* this is the entry point of the android app initially called by jni */ +JNIEXPORT void JNICALL +Java_org_rockbox_RockboxActivity_main(JNIEnv *env, jobject this) +{ + /* hack!!! we can't have a valid stack pointer otherwise. + * but we don't really need it anyway, thread.c only needs it + * for overflow detection which doesn't apply for the main thread + * (it's managed by the OS) */ + + (void)env; + (void)this; + volatile uintptr_t stack = 0; + stackbegin = stackend = &stack; + env_ptr = env; + RockboxActivity_instance = this; + RockboxActivity_class = (*env)->GetObjectClass(env, this); + main(); +} diff --git a/firmware/target/hosted/android/system-target.h b/firmware/target/hosted/android/system-target.h new file mode 100644 index 0000000000..210d191d6c --- /dev/null +++ b/firmware/target/hosted/android/system-target.h @@ -0,0 +1,39 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 by Thomas Martitz + * + * 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; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#ifndef __SYSTEM_TARGET_H__ +#define __SYSTEM_TARGET_H__ + +#define disable_irq() +#define enable_irq() +#define disable_irq_save() 0 +#define restore_irq(level) (void)level + +void power_off(void); + +#include +#define LOG_TAG "Rockbox" +#define LOG(args...) \ + __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, ##args); + +#endif /* __SYSTEM_TARGET_H__ */ + +#define NEED_GENERIC_BYTESWAPS + diff --git a/firmware/target/hosted/android/thread-android-arm.c b/firmware/target/hosted/android/thread-android-arm.c new file mode 100644 index 0000000000..baf8b84b65 --- /dev/null +++ b/firmware/target/hosted/android/thread-android-arm.c @@ -0,0 +1,98 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2005 by Thom Johansen + * Copyright (C) 2010 by Thomas Martitz (Android-suitable core_sleep()) + * + * Generic ARM threading support + * + * 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; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include +/*--------------------------------------------------------------------------- + * Start the thread running and terminate it if it returns + *--------------------------------------------------------------------------- + */ +static void __attribute__((naked,used)) start_thread(void) +{ + /* r0 = context */ + asm volatile ( + "ldr sp, [r0, #32] \n" /* Load initial sp */ + "ldr r4, [r0, #40] \n" /* start in r4 since it's non-volatile */ + "mov r1, #0 \n" /* Mark thread as running */ + "str r1, [r0, #40] \n" + "mov lr, pc \n" /* Call thread function */ + "bx r4 \n" + ); /* No clobber list - new thread doesn't care */ + thread_exit(); +} + +/* For startup, place context pointer in r4 slot, start_thread pointer in r5 + * slot, and thread function pointer in context.start. See load_context for + * what happens when thread is initially going to run. */ +#define THREAD_STARTUP_INIT(core, thread, function) \ + ({ (thread)->context.r[0] = (uint32_t)&(thread)->context, \ + (thread)->context.r[1] = (uint32_t)start_thread, \ + (thread)->context.start = (uint32_t)function; }) + + +/*--------------------------------------------------------------------------- + * Store non-volatile context. + *--------------------------------------------------------------------------- + */ +static inline void store_context(void* addr) +{ + asm volatile( + "stmia %0, { r4-r11, sp, lr } \n" + : : "r" (addr) + ); +} + +/*--------------------------------------------------------------------------- + * Load non-volatile context. + *--------------------------------------------------------------------------- + */ +static inline void load_context(const void* addr) +{ + asm volatile( + "ldr r0, [%0, #40] \n" /* Load start pointer */ + "cmp r0, #0 \n" /* Check for NULL */ + + /* If not already running, jump to start */ + "ldmneia %0, { r0, pc } \n" + "ldmia %0, { r4-r11, sp, lr } \n" /* Load regs r4 to r14 from context */ + : : "r" (addr) : "r0" /* only! */ + ); +} + +/* + * this core sleep suspends the OS thread rockbox runs under, which greatly + * reduces cpu usage (~100% to <10%) + * + * it returns when the RockboxTimer notified us, i.e. at each tick + * (after it called the tick tasks) + * + * wait_for_interrupt is implemented in kernel-android.c + **/ + +extern void wait_for_interrupt(void); +static inline void core_sleep(void) +{ + wait_for_interrupt(); +} + + diff --git a/firmware/thread.c b/firmware/thread.c index c00fc36e3f..b3d8ec3970 100644 --- a/firmware/thread.c +++ b/firmware/thread.c @@ -123,8 +123,13 @@ static struct core_entry cores[NUM_CORES] IBSS_ATTR; struct thread_entry threads[MAXTHREADS] IBSS_ATTR; static const char main_thread_name[] = "main"; +#if (CONFIG_PLATFORM & PLATFORM_NATIVE) extern uintptr_t stackbegin[]; extern uintptr_t stackend[]; +#else +extern uintptr_t *stackbegin; +extern uintptr_t *stackend; +#endif static inline void core_sleep(IF_COP_VOID(unsigned int core)) __attribute__((always_inline)); @@ -170,7 +175,9 @@ void switch_thread(void) /**************************************************************************** * Processor-specific section - include necessary core support */ -#if defined(CPU_ARM) +#if defined(ANDROID) +#include "thread-android-arm.c" +#elif defined(CPU_ARM) #include "thread-arm.c" #if defined (CPU_PP) #include "thread-pp.c" @@ -1150,7 +1157,7 @@ void switch_thread(void) store_context(&thread->context); /* Check if the current thread stack is overflown */ - if (UNLIKELY(thread->stack[0] != DEADBEEF)) + if (UNLIKELY(thread->stack[0] != DEADBEEF) && thread->stack_size > 0) thread_stkov(thread); #if NUM_CORES > 1 @@ -2319,7 +2326,9 @@ static int stack_usage(uintptr_t *stackptr, size_t stack_size) */ int thread_stack_usage(const struct thread_entry *thread) { - return stack_usage(thread->stack, thread->stack_size); + if (LIKELY(thread->stack_size > 0)) + return stack_usage(thread->stack, thread->stack_size); + return 0; } #if NUM_CORES > 1 diff --git a/tools/buildzip.pl b/tools/buildzip.pl index 7a127dea20..094214de72 100755 --- a/tools/buildzip.pl +++ b/tools/buildzip.pl @@ -631,6 +631,8 @@ sub runone { } else { unless (".rockbox" eq $rbdir) { + mkpath($rbdir); + rmtree($rbdir); move(".rockbox", $rbdir); print "mv .rockbox $rbdir\n" if $verbose; } diff --git a/tools/configure b/tools/configure index ce23c2a965..7504d562c9 100755 --- a/tools/configure +++ b/tools/configure @@ -14,6 +14,7 @@ CCOPTS="-W -Wall -Wundef -O -nostdlib -ffreestanding -Wstrict-prototypes -pipe" # global LD options for all platforms GLOBAL_LDOPTS="" +extradefines="" use_logf="#undef ROCKBOX_HAS_LOGF" use_bootchart="#undef DO_BOOTCHART" @@ -25,7 +26,10 @@ bindir= libdir= bindir_full= libdir_full= - + +app_platform= +app_lcd_width= +app_lcd_height= # # Begin Function Definitions # @@ -47,6 +51,59 @@ prefixtools () { OC=${prefix}objcopy } +app_get_platform() { + echo "Select your platform: (S)DL, (A)ndroid (default: Android)" + choice=`input` + case $choice in + s|S*) app_platform="sdl" ;; + *|a|A*) app_platform="android" ;; + esac + + echo "Selected $app_platform platform" + echo "Select the LCD resolution seperated with enter: XxY (default: 320x480)" + app_lcd_width=`input` + if [ -z "$app_lcd_width" ]; then app_lcd_width="320"; fi + app_lcd_height=`input` + if [ -z "$app_lcd_height" ]; then app_lcd_height="480"; fi + echo "Selected $app_lcd_width x $app_lcd_height resolution" + + app_lcd_width="#define LCD_WIDTH $app_lcd_width" + app_lcd_height="#define LCD_HEIGHT $app_lcd_height" + # setup files and paths depending on the platform + if [ "$app_platform" = "sdl" ]; then + if [ -z "$PREFIX" ]; then + rbdir="/usr/local/share/rockbox" + bindir="/usr/local/bin" + bindir_full=$bindir + libdir="/usr/local/lib" + libdir_full=$libdir + else + rbdir=`realpath $PREFIX/share/rockbox` + bindir="$PREFIX/bin" + libdir="$PREFIX/lib" + if [ -d bindir ]; then + bindir_full=`realpath $bindir` + fi + if [ -d libdir ]; then + libdir_full=`realpath $libdir` + fi + fi + output="rockbox" + bootoutput="rockbox" + elif [ "$app_platform" = "android" ]; then + if [ -n "$PREFIX" ]; then + echo "WARNING: PREFIX not supported on Android. You can however use --rbdir" + fi + rbdir="/data/data/org.rockbox/app_rockbox/rockbox" + bindir="/data/data/org.rockbox/lib" + bindir_full=$bindir + libdir="/data/data/org.rockbox/app_rockbox" + libdir_full=$libdir + output="librockbox.so" + bootoutput="librockbox.so" + fi +} + findarmgcc() { if [ "$ARG_ARM_EABI" != "0" ]; then prefixtools arm-elf-eabi- @@ -102,6 +159,15 @@ findsdl(){ done } +appcc () { + if [ "$1" = "sdl" ]; then + simcc "sdl-app" + elif [ "$1" = "android" ]; then + app_type=$1 + androidcc + fi +} + simcc () { # default tool setup for native building @@ -114,15 +180,17 @@ simcc () { GCCOPTIMIZE='' LDOPTS='-lm' # button-sdl.c uses sqrt() - # default output binary name - output="rockboxui" + # default output binary name, don't override app_get_platform() + if [ "$app_type" != "sdl-app" ]; then + output="rockboxui" + fi # default share option, override below if needed SHARED_FLAG="-shared" if [ "$win32crosscompile" = "yes" ]; then LDOPTS="$LDOPTS -mconsole" - output="rockboxui.exe" + output="$output.exe" winbuild="yes" else case $uname in @@ -130,7 +198,7 @@ simcc () { echo "Cygwin host detected" LDOPTS="$LDOPTS -mconsole" - output="rockboxui.exe" + output="$output.exe" winbuild="yes" ;; @@ -138,7 +206,7 @@ simcc () { echo "MinGW host detected" LDOPTS="$LDOPTS -mconsole" - output="rockboxui.exe" + output="$output.exe" winbuild="yes" ;; @@ -188,6 +256,7 @@ simcc () { LDOPTS="$LDOPTS `$sdl --libs`" fi fi + GCCOPTS="$GCCOPTS -I\$(SIMDIR)" @@ -379,6 +448,18 @@ mipselcc () { gccchoice="4.1.2" } +androidcc () { + gccchoice="4.4.0" + prefixtools $ANDROID_NDK_PATH/build/prebuilt/linux-x86/arm-eabi-$gccchoice/bin/arm-eabi- + GCCOPTS=`echo $CCOPTS | sed -e s/-ffreestanding// -e s/-nostdlib// -e s/-Wundef//` + GCCOPTS="$GCCOPTS -std=gnu99 -ffunction-sections -fno-short-enums -march=armv5te -mtune=xscale -msoft-float -fomit-frame-pointer" + GLOBAL_LDOPTS="$GLOBAL_LDOPTS -nostdlib -lc -Wl,--no-undefined -Wl,--gc-sections -Wl,-z,noexecstack -L$ANDROID_NDK_PATH/build/platforms/android-4/arch-arm/usr/lib/ -Wl,-rpath-link=$ANDROID_NKD_PATH/build/platforms/android-4/arch-arm/usr/lib" + LDOPTS="$LDOPTS -shared -nostdlib -lm -ldl -llog" + extradefines="$extradefines -DANDROID" + endian="little" + SHARED_FLAG="-shared" +} + whichadvanced () { atype=`echo "$1" | cut -c 2-` ################################################################## @@ -975,7 +1056,7 @@ cat < autoconf.h \ -e "s<@have_backlight@<$have_backlight autoconf.h \ @config_rtc@ @have_rtc_alarm@ +/* lcd dimensions for application builds from configure */ +@lcd_width@ +@lcd_height@ + /* root of Rockbox */ #define ROCKBOX_DIR "@RBDIR@" #define ROCKBOX_BINARY_PATH "@binpath@" @@ -3089,6 +3159,10 @@ if test -n "$t_cpu"; then TARGET_INC="$TARGET_INC -I\$(FIRMDIR)/target/hosted/sdl/" TARGET_INC="$TARGET_INC -I\$(FIRMDIR)/target/hosted/" fi + if [ -n "$app_platform" -a "$app_platform" = "android" ]; then + # android's gcc doesn't add this :/ + TARGET_INC="$TARGET_INC -I$ANDROID_NDK_PATH/build/platforms/android-4/arch-arm/usr/include" + fi TARGET_INC="$TARGET_INC -I\$(FIRMDIR)/target/$t_cpu/$t_manufacturer" TARGET_INC="$TARGET_INC -I\$(FIRMDIR)/target/$t_cpu" GCCOPTS="$GCCOPTS" diff --git a/uisimulator/common/io.c b/uisimulator/common/io.c index 260e880b62..4c0fa33be5 100644 --- a/uisimulator/common/io.c +++ b/uisimulator/common/io.c @@ -25,7 +25,11 @@ #include #include #include -#ifndef WIN32 +#include "config.h" + +#define HAVE_STATVFS (0 == (CONFIG_PLATFORM & PLATFORM_ANDROID) && !defined(WIN32)) + +#if HAVE_STATVFS #include #endif @@ -41,14 +45,18 @@ #endif #include +#if (CONFIG_PLATFORM & PLATFORM_SDL) #include #include +#include "thread-sdl.h" +#else +#define sim_thread_unlock() NULL +#define sim_thread_lock(a) +#endif #include "thread.h" #include "kernel.h" #include "debug.h" -#include "config.h" #include "ata.h" /* for IF_MV2 et al. */ -#include "thread-sdl.h" #include "rbpaths.h" /* keep this in sync with file.h! */ @@ -193,7 +201,7 @@ static unsigned int rockbox2sim(int opt) /** Simulator I/O engine routines **/ #define IO_YIELD_THRESHOLD 512 -enum +enum io_dir { IO_READ, IO_WRITE, @@ -225,7 +233,7 @@ int ata_spinup_time(void) return HZ; } -static ssize_t io_trigger_and_wait(int cmd) +static ssize_t io_trigger_and_wait(enum io_dir cmd) { void *mythread = NULL; ssize_t result; @@ -246,6 +254,9 @@ static ssize_t io_trigger_and_wait(int cmd) case IO_WRITE: result = write(io.fd, io.buf, io.count); break; + /* shut up gcc */ + default: + result = -1; } /* Regain our status as current */ @@ -480,7 +491,7 @@ void fat_size(IF_MV2(int volume,) unsigned long* size, unsigned long* free) if (free) *free = free_clusters * secperclus / 2 * (bytespersec / 512); } -#else +#elif HAVE_STATVFS struct statvfs vfs; if (!statvfs(".", &vfs)) { @@ -490,9 +501,9 @@ void fat_size(IF_MV2(int volume,) unsigned long* size, unsigned long* free) *size = vfs.f_blocks / 2 * (vfs.f_frsize / 512); if (free) *free = vfs.f_bfree / 2 * (vfs.f_frsize / 512); - } + } else #endif - else { + { if (size) *size = 0; if (free) @@ -537,9 +548,19 @@ void *sim_codec_load_ram(char* codecptr, int size, void **pd) to find an unused filename */ for (codec_count = 0; codec_count < 10; codec_count++) { +#if (CONFIG_PLATFORM & PLATFORM_ANDROID) + /* we need that path fixed, since get_user_file_path() + * gives us the folder on the sdcard where we cannot load libraries + * from (no exec permissions) + */ + snprintf(path, sizeof(path), + "/data/data/org.rockbox/app_rockbox/libtemp_codec_%d.so", + codec_count); +#else char name[MAX_PATH]; const char *_name = get_user_file_path(ROCKBOX_DIR, 0, name, sizeof(name)); snprintf(path, sizeof(path), "%s/_temp_codec%d.dll", get_sim_pathname(_name), codec_count); +#endif fd = OPEN(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, S_IRWXU); if (fd >= 0) break; /* Created a file ok */ diff --git a/uisimulator/common/stubs.c b/uisimulator/common/stubs.c index 6d7d7de06b..a9011b9aa5 100644 --- a/uisimulator/common/stubs.c +++ b/uisimulator/common/stubs.c @@ -21,8 +21,6 @@ #include #include #include -#include "thread-sdl.h" - #include "debug.h" #include "screens.h" @@ -35,7 +33,6 @@ #include "ata.h" /* for volume definitions */ -extern char having_new_lcd; static bool storage_spinning = false; #if CONFIG_CODEC != SWCODEC @@ -211,10 +208,13 @@ bool spdif_powered(void) } #endif +#ifdef ARCHOS_PLAYER bool is_new_player(void) { + extern char having_new_lcd; return having_new_lcd; } +#endif #ifdef HAVE_USB_POWER bool usb_powered(void) diff --git a/uisimulator/uisimulator.make b/uisimulator/uisimulator.make index b06b48c0d2..dcbd79988f 100644 --- a/uisimulator/uisimulator.make +++ b/uisimulator/uisimulator.make @@ -30,7 +30,6 @@ $(SIMLIB): $$(SIMOBJ) $(UIBMP) $(SILENT)$(shell rm -f $@) $(call PRINTS,AR $(@F))$(AR) rcs $@ $^ >/dev/null -# SIMLIB needs to be linked twice for some reason $(BUILDDIR)/$(BINARY): $$(OBJ) $(SIMLIB) $(VOICESPEEXLIB) $(FIRMLIB) $(SKINLIB) $(call PRINTS,LD $(BINARY))$(CC) -o $@ $^ $(SIMLIB) $(LDOPTS) $(GLOBAL_LDOPTS) diff --git a/wps/WPSLIST b/wps/WPSLIST index 3068f48513..938caa13fa 100644 --- a/wps/WPSLIST +++ b/wps/WPSLIST @@ -292,6 +292,7 @@ RSBS: Author: Johannes Voggenthaler, Apoo Maha, Marc Guay, Alex Vanderpol, Jerry Lange, Keith Perri, Mark Fawcus, and Marianne Arnold with support from Rockbox developers and forums. Based on Cabbie by Yohann Misquitta. # Preferred font (including .fnt extension - leave blank for player): +Font.320x480x16: 16-Adobe-Helvetica.fnt Font.320x240x16: 15-Adobe-Helvetica.fnt Font.240x400x16: 16-Adobe-Helvetica.fnt Font.240x320x16: 15-Adobe-Helvetica.fnt @@ -320,6 +321,7 @@ line selector text color: 000000 filetype colours: #backdrop - remember this is the source file name in your SVN folder, not dest name! +backdrop.320x480x16: backdrops/cabbiev2.320x480x16.bmp backdrop.320x240x16: backdrops/cabbiev2.320x240x16.bmp backdrop.128x128x16: backdrops/cabbiev2.128x128x16.bmp backdrop.132x80x16: backdrops/cabbiev2.132x80x16.bmp @@ -333,6 +335,7 @@ backdrop.240x320x16: backdrops/cabbiev2.240x320x16.bmp backdrop.240x400x16: backdrops/cabbiev2.240x400x16.bmp #selection bar settings for color targets +selector type.320x480x16: bar (gradient) selector type.320x240x16: bar (gradient) selector type.128x128x16: bar (gradient) selector type.132x80x16: bar (gradient) @@ -346,6 +349,7 @@ selector type.160x128x2: bar (inverse) selector type.138x110x2: bar (inverse) #icons +iconset.320x480x16: icons/tango_small.bmp iconset.320x240x16: icons/tango_small.bmp iconset.128x128x16: icons/tango_small.bmp iconset.132x80x16: icons/tango_small.bmp @@ -359,6 +363,7 @@ iconset.240x320x16: icons/tango_small.bmp iconset.240x400x16: icons/tango_small.bmp #viewer icons +viewers iconset.320x480x16: icons/tango_small_viewers.bmp viewers iconset.320x240x16: icons/tango_small_viewers.bmp viewers iconset.128x128x16: icons/tango_small_viewers.bmp viewers iconset.132x80x16: icons/tango_small_viewers.bmp diff --git a/wps/cabbiev2.320x480x16.wps b/wps/cabbiev2.320x480x16.wps new file mode 100644 index 0000000000..a64fa6fcf7 --- /dev/null +++ b/wps/cabbiev2.320x480x16.wps @@ -0,0 +1,79 @@ +# cabbie 2.0 +# (C) 2007, Johannes Voggenthaler (Zinc Alloy) +# (C) 2009, Maurus Cuelenaere (mcuelenaere) ported to Onda VX747 +# derived from "cabbie" (C) Yohann Misquitta + +%wd +%X(wpsbackdrop-240x400x16.bmp) +%Cl(55,50,130,130,c,c) +%pb(22,284,199,13,pb-240x320x16.bmp) +%T(22,284,199,13,progressbar) +%T(90,238,60,20,playlist) +%?Tl(2.5)<%Vd(t)|%Vd(u)> +%V(0,0,240,330,1) + + +%?C<|> +%?C<|> +%?C<|%s%ac%?it<%it|%fn>> +%?C<|%s%ac%?ia<%ia|%?d(2)<%d(2)|%(root%)>>> +%?C<|%s%ac%?id<%id|%?d(1)<%d(1)|%(root%)>>> +%?C<|%ac%?iy<%iy|>> +%?C<|> +%?C<|%ac%?ig<%ig|>> +%?C<|%ac%?fv<%(vbr%) |>%fb kbit/s %fc> +%?C<|> +%?C<%s%ac%?it<%it|%fn>|> +%?C<%s%ac%?ia<%ia|%?d(2)<%d(2)|%(root%)>>|%ac%Sx(Next Track:)> +%?C<%s%ac%?id<%id|%?d(1)<%d(1)|%(root%)>>|%ac%s%?It<%It|%Fn>> +%?C<|%s%ac%?Ia<%Ia|%?D(2)<%D(2)|%(root%)>>> +%?C<%s%ac%Sx(Next:) %?Ia<%Ia|%?D(2)<%D(2)|%(root%)>> - %?It<%It|%Fn>|%s%ac%?Id<%Id|%?D(1)<%D(1)|%(root%)>>> + + + %pc%ac%?Sr<%pe %Sx(of) %pp|%pp %Sx(of) %pe>%ar%pr + +%?C<%Cd> + +%xl(A,lock-240x320x16.bmp,11,0,2) +%xl(B,battery-240x320x16.bmp,46,0,10) +%xl(C,volume-240x320x16.bmp,98,0,10) +%xl(D,shuffle-240x320x16.bmp,139,0) +%xl(E,repeat-240x320x16.bmp,182,0,4) +%xl(F,playmode-240x320x16.bmp,206,0,5) + +%V(0,372,240,-,1) +%?mh<%xd(Aa)|%xd(Ab)> +%?bp<%?bc<%xd(Ba)|%xd(Bb)>|%?bl<|%xd(Bc)|%xd(Bd)|%xd(Be)|%xd(Bf)|%xd(Bg)|%xd(Bh)|%xd(Bi)|%xd(Bj)>> +%?pv<%xd(Ca)|%xd(Cb)|%xd(Cc)|%xd(Cd)|%xd(Ce)|%xd(Cf)|%xd(Cg)|%xd(Ch)|%xd(Ci)|%xd(Cj)> +%?ps<%xd(D)> +%?mm<|%xd(Ea)|%xd(Eb)|%xd(Ec)|%xd(Ed)> +%?mp<%xd(Fa)|%xd(Fb)|%xd(Fc)|%xd(Fd)|%xd(Fe)> + +%T(206,0,24,24,play) +%T(206,0,24,24,&stop) +%T(182,0,18,92,repmode) +%T(139,0,37,23,shuffle) +%T(98,0,33,23,volume) + +#viewport for the touch icons +%xl(G,browser-320x240x16.bmp,0,0) +%xl(I,pitch-320x240x16.bmp,39,0) +%xl(H,context-320x240x16.bmp,58,0) +%xl(J,quick-320x240x16.bmp,86,0) +%xl(K,rew-320x240x16.bmp,115,0) +%xl(L,ff-320x240x16.bmp,144,0) + +%Vl(t,70,335,-,30,1) +%xd(G) %xd(H) %xd(I) %xd(J) %xd(K) %xd(L) +%T(0,0,37,24,browse) +%T(39,5,24,24,pitch) +%T(58,0,24,24,contextmenu) +%T(86,0,24,24,quickscreen) +%T(115,0,24,23,&rwd) +%T(144,0,24,23,&ffwd) +%T(115,0,24,23,prev) +%T(144,0,24,23,next) + +%Vl(u,70,335,-,30,1) +#purposely left blank + diff --git a/wps/cabbiev2/wpsbackdrop-320x480x16.bmp b/wps/cabbiev2/wpsbackdrop-320x480x16.bmp new file mode 100644 index 0000000000..3278c0d965 Binary files /dev/null and b/wps/cabbiev2/wpsbackdrop-320x480x16.bmp differ