mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-10-14 02:27:39 -04:00
Scroll on main and remote with a single thread. Change the way system messages are defined before running out is an issue (which requires a full update of rockbox on the player).
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@14035 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
885cdfdeb9
commit
58fc279d26
17 changed files with 859 additions and 994 deletions
302
firmware/scroll_engine.c
Normal file
302
firmware/scroll_engine.c
Normal file
|
@ -0,0 +1,302 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2007 by Michael Sevakis
|
||||
*
|
||||
* LCD scrolling driver and scheduler
|
||||
*
|
||||
* Much collected and combined from the various Rockbox LCD drivers.
|
||||
*
|
||||
* All files in this archive are subject to the GNU General Public License.
|
||||
* See the file COPYING in the source tree root for full license agreement.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "config.h"
|
||||
#include "cpu.h"
|
||||
#include "kernel.h"
|
||||
#include "thread.h"
|
||||
#include "usb.h"
|
||||
#include "lcd.h"
|
||||
#include "font.h"
|
||||
#ifdef HAVE_REMOTE_LCD
|
||||
#include "lcd-remote.h"
|
||||
#endif
|
||||
#include "scroll_engine.h"
|
||||
|
||||
static const char scroll_tick_table[16] = {
|
||||
/* Hz values:
|
||||
1, 1.25, 1.55, 2, 2.5, 3.12, 4, 5, 6.25, 8.33, 10, 12.5, 16.7, 20, 25, 33 */
|
||||
100, 80, 64, 50, 40, 32, 25, 20, 16, 12, 10, 8, 6, 5, 4, 3
|
||||
};
|
||||
|
||||
static void scroll_thread(void);
|
||||
static char scroll_stack[DEFAULT_STACK_SIZE*3];
|
||||
static const char scroll_name[] = "scroll";
|
||||
|
||||
struct scrollinfo lcd_scroll[LCD_SCROLLABLE_LINES];
|
||||
|
||||
#ifdef HAVE_REMOTE_LCD
|
||||
struct scrollinfo lcd_remote_scroll[LCD_REMOTE_SCROLLABLE_LINES];
|
||||
struct event_queue scroll_queue;
|
||||
#endif
|
||||
|
||||
struct scroll_screen_info lcd_scroll_info =
|
||||
{
|
||||
.scroll = lcd_scroll,
|
||||
.lines = 0,
|
||||
.ticks = 12,
|
||||
.delay = HZ/2,
|
||||
.bidir_limit = 50,
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
.step = 6,
|
||||
#endif
|
||||
#ifdef HAVE_LCD_CHARCELLS
|
||||
.jump_scroll_delay = HZ/4,
|
||||
.jump_scroll = 0,
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef HAVE_REMOTE_LCD
|
||||
struct scroll_screen_info lcd_remote_scroll_info =
|
||||
{
|
||||
.scroll = lcd_remote_scroll,
|
||||
.lines = 0,
|
||||
.ticks = 12,
|
||||
.delay = HZ/2,
|
||||
.bidir_limit = 50,
|
||||
.step = 6,
|
||||
};
|
||||
#endif /* HAVE_REMOTE_LCD */
|
||||
|
||||
void lcd_stop_scroll(void)
|
||||
{
|
||||
lcd_scroll_info.lines = 0;
|
||||
}
|
||||
|
||||
void lcd_scroll_speed(int speed)
|
||||
{
|
||||
lcd_scroll_info.ticks = scroll_tick_table[speed];
|
||||
}
|
||||
|
||||
#if defined(HAVE_LCD_BITMAP)
|
||||
/* Reverse the invert setting of the scrolling line (if any) at given char
|
||||
position. Setting will go into affect next time line scrolls. */
|
||||
void lcd_invertscroll(int x, int y)
|
||||
{
|
||||
struct scrollinfo *s;
|
||||
|
||||
(void)x;
|
||||
|
||||
if((unsigned)y>=LCD_SCROLLABLE_LINES) return;
|
||||
|
||||
s = &lcd_scroll_info.scroll[y];
|
||||
s->invert = !s->invert;
|
||||
}
|
||||
|
||||
void lcd_scroll_step(int step)
|
||||
{
|
||||
lcd_scroll_info.step = step;
|
||||
}
|
||||
#endif
|
||||
|
||||
void lcd_scroll_delay(int ms)
|
||||
{
|
||||
lcd_scroll_info.delay = ms / (HZ / 10);
|
||||
}
|
||||
|
||||
void lcd_bidir_scroll(int percent)
|
||||
{
|
||||
lcd_scroll_info.bidir_limit = percent;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LCD_CHARCELLS
|
||||
void lcd_jump_scroll(int mode) /* 0=off, 1=once, ..., JUMP_SCROLL_ALWAYS */
|
||||
{
|
||||
lcd_scroll_info.jump_scroll = mode;
|
||||
}
|
||||
|
||||
void lcd_jump_scroll_delay(int ms)
|
||||
{
|
||||
lcd_scroll_info.jump_scroll_delay = ms / (HZ / 10);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_REMOTE_LCD
|
||||
/* Reverse the invert setting of the scrolling line (if any) at given char
|
||||
position. Setting will go into affect next time line scrolls. */
|
||||
void lcd_remote_invertscroll(int x, int y)
|
||||
{
|
||||
struct scrollinfo *s;
|
||||
|
||||
(void)x;
|
||||
|
||||
if((unsigned)y>=LCD_REMOTE_SCROLLABLE_LINES) return;
|
||||
|
||||
s = &lcd_remote_scroll_info.scroll[y];
|
||||
s->invert = !s->invert;
|
||||
}
|
||||
|
||||
void lcd_remote_stop_scroll(void)
|
||||
{
|
||||
lcd_remote_scroll_info.lines = 0;
|
||||
}
|
||||
|
||||
void lcd_remote_scroll_speed(int speed)
|
||||
{
|
||||
lcd_remote_scroll_info.ticks = scroll_tick_table[speed];
|
||||
}
|
||||
|
||||
void lcd_remote_scroll_step(int step)
|
||||
{
|
||||
lcd_remote_scroll_info.step = step;
|
||||
}
|
||||
|
||||
void lcd_remote_scroll_delay(int ms)
|
||||
{
|
||||
lcd_remote_scroll_info.delay = ms / (HZ / 10);
|
||||
}
|
||||
|
||||
void lcd_remote_bidir_scroll(int percent)
|
||||
{
|
||||
lcd_remote_scroll_info.bidir_limit = percent;
|
||||
}
|
||||
|
||||
static void sync_display_ticks(void)
|
||||
{
|
||||
lcd_scroll_info.last_scroll =
|
||||
lcd_remote_scroll_info.last_scroll = current_tick;
|
||||
}
|
||||
|
||||
static bool scroll_process_message(int delay)
|
||||
{
|
||||
struct event ev;
|
||||
|
||||
do
|
||||
{
|
||||
long tick = current_tick;
|
||||
queue_wait_w_tmo(&scroll_queue, &ev, delay);
|
||||
|
||||
switch (ev.id)
|
||||
{
|
||||
case SYS_TIMEOUT:
|
||||
return false;
|
||||
case SYS_USB_CONNECTED:
|
||||
usb_acknowledge(SYS_USB_CONNECTED_ACK);
|
||||
usb_wait_for_disconnect(&scroll_queue);
|
||||
sync_display_ticks();
|
||||
return true;
|
||||
#ifndef SIMULATOR
|
||||
case SYS_REMOTE_PLUGGED:
|
||||
if (!remote_initialized)
|
||||
sync_display_ticks();
|
||||
#endif
|
||||
}
|
||||
|
||||
delay -= current_tick - tick;
|
||||
}
|
||||
while (delay > 0);
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif /* HAVE_REMOTE_LCD */
|
||||
|
||||
static void scroll_thread(void) __attribute__((noreturn));
|
||||
#ifdef HAVE_REMOTE_LCD
|
||||
|
||||
static void scroll_thread(void)
|
||||
{
|
||||
enum
|
||||
{
|
||||
SCROLL_LCD = 0x1,
|
||||
SCROLL_LCD_REMOTE = 0x2,
|
||||
};
|
||||
|
||||
sync_display_ticks();
|
||||
|
||||
while ( 1 )
|
||||
{
|
||||
long delay;
|
||||
int scroll;
|
||||
long tick_lcd, tick_remote;
|
||||
|
||||
tick_lcd = lcd_scroll_info.last_scroll + lcd_scroll_info.ticks;
|
||||
delay = current_tick;
|
||||
|
||||
if (
|
||||
#ifndef SIMULATOR
|
||||
!remote_initialized ||
|
||||
#endif
|
||||
(tick_remote = lcd_remote_scroll_info.last_scroll +
|
||||
lcd_remote_scroll_info.ticks,
|
||||
TIME_BEFORE(tick_lcd, tick_remote)))
|
||||
{
|
||||
scroll = SCROLL_LCD;
|
||||
delay = tick_lcd - delay;
|
||||
}
|
||||
/* TIME_BEFORE(tick_remote, tick_lcd) */
|
||||
else if (tick_lcd != tick_remote)
|
||||
{
|
||||
scroll = SCROLL_LCD_REMOTE;
|
||||
delay = tick_remote - delay;
|
||||
}
|
||||
else
|
||||
{
|
||||
scroll = SCROLL_LCD | SCROLL_LCD_REMOTE;
|
||||
delay = tick_lcd - delay;
|
||||
}
|
||||
|
||||
if (scroll_process_message(delay))
|
||||
continue;
|
||||
|
||||
if (scroll & SCROLL_LCD)
|
||||
{
|
||||
#ifdef HAVE_LCD_ENABLE
|
||||
if (lcd_enabled())
|
||||
#endif
|
||||
lcd_scroll_fn();
|
||||
lcd_scroll_info.last_scroll = current_tick;
|
||||
}
|
||||
|
||||
if (scroll == (SCROLL_LCD | SCROLL_LCD_REMOTE))
|
||||
yield();
|
||||
|
||||
if (scroll & SCROLL_LCD_REMOTE)
|
||||
{
|
||||
lcd_remote_scroll_fn();
|
||||
lcd_remote_scroll_info.last_scroll = current_tick;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
static void scroll_thread(void)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
sleep(lcd_scroll_info.ticks);
|
||||
#ifdef HAVE_LCD_ENABLE
|
||||
if (lcd_enabled())
|
||||
#endif
|
||||
lcd_scroll_fn();
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_REMOTE_LCD */
|
||||
|
||||
void scroll_init(void)
|
||||
{
|
||||
#ifdef HAVE_REMOTE_LCD
|
||||
queue_init(&scroll_queue, true);
|
||||
#endif
|
||||
create_thread(scroll_thread, scroll_stack,
|
||||
sizeof(scroll_stack), scroll_name
|
||||
IF_PRIO(, PRIORITY_USER_INTERFACE)
|
||||
IF_COP(, CPU, false));
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue