summaryrefslogtreecommitdiffstats
path: root/firmware/target/hosted
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2010-08-02 20:34:47 +0000
committerThomas Martitz <kugel@rockbox.org>2010-08-02 20:34:47 +0000
commit240923a801382c86545d10be167a15892a556fb6 (patch)
tree3c0e07ec3abf0c493a0b24b0b57e8bbd0200f7f6 /firmware/target/hosted
parent850efead04f10488b478a0f255a2464a01156a7f (diff)
downloadrockbox-240923a801382c86545d10be167a15892a556fb6.tar.gz
rockbox-240923a801382c86545d10be167a15892a556fb6.tar.bz2
rockbox-240923a801382c86545d10be167a15892a556fb6.zip
Rockbox as an application: Commit current Android port progress.
General state is: Rockbox is usable (plays music, saves configuration, touchscreen works too). Problems: - Playing music in the background (i.e. when switching to another app) doesn't work reliably, but I'm working on that now. - no cabbiev2 (only some preliminary files for it), no other default theme. - screen flickers sometimes if the updates are too frequent - no multi screen apk/package - strange behavior when a phone call comes in The java files (and the eclipse project) resides in android/, which is also supposed to be the build folder. I've put a small README in there for instructions. There are some steps needed after the make part, which are described there, and which eclipse mostly handles. But there ought to be some script/makefile rules which do that instead in the future. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27668 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/hosted')
-rw-r--r--firmware/target/hosted/android/app/adc-target.h25
-rw-r--r--firmware/target/hosted/android/app/backlight-target.h25
-rw-r--r--firmware/target/hosted/android/app/button-application.c29
-rw-r--r--firmware/target/hosted/android/app/button-target.h64
-rw-r--r--firmware/target/hosted/android/app/i2c-target.h25
-rw-r--r--firmware/target/hosted/android/app/usb-target.h25
-rw-r--r--firmware/target/hosted/android/button-android.c87
-rw-r--r--firmware/target/hosted/android/buttonmap.h43
-rw-r--r--firmware/target/hosted/android/kernel-android.c106
-rw-r--r--firmware/target/hosted/android/lcd-android.c291
-rw-r--r--firmware/target/hosted/android/pcm-android.c174
-rw-r--r--firmware/target/hosted/android/system-android.c59
-rw-r--r--firmware/target/hosted/android/system-target.h39
-rw-r--r--firmware/target/hosted/android/thread-android-arm.c98
14 files changed, 1090 insertions, 0 deletions
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 <stdbool.h>
+#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 <jni.h>
+#include <stdbool.h>
+#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 <jni.h>
+#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,
+ "<init>",
+ "(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 <jni.h>
+#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 <jni.h>
+#include <stdbool.h>
+#include <system.h>
+#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, "<init>", "()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 <jni.h>
+#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 <android/log.h>
+#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 <jni.h>
+/*---------------------------------------------------------------------------
+ * 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();
+}
+
+