2005-03-02 23:49:38 +00:00
|
|
|
/***************************************************************************
|
|
|
|
* __________ __ ___.
|
|
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
|
|
* \/ \/ \/ \/ \/
|
|
|
|
* $Id$
|
|
|
|
*
|
|
|
|
* Copyright (C) 2005 Michiel van der Kolk, Jens Arnold
|
|
|
|
*
|
2008-06-28 18:10:04 +00:00
|
|
|
* 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.
|
2005-03-02 23:49:38 +00:00
|
|
|
*
|
|
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
|
|
* KIND, either express or implied.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#include "rockmacros.h"
|
|
|
|
#include "fb.h"
|
|
|
|
#include "input.h"
|
2005-07-03 14:05:12 +00:00
|
|
|
#include "lcd-gb.h"
|
2005-03-02 23:49:38 +00:00
|
|
|
#include "hw.h"
|
|
|
|
#include "config.h"
|
|
|
|
|
2009-06-15 05:56:48 +00:00
|
|
|
#if CONFIG_KEYPAD == SANSA_E200_PAD || CONFIG_KEYPAD == SANSA_FUZE_PAD
|
2007-05-22 06:31:44 +00:00
|
|
|
#define ROCKBOY_SCROLLWHEEL
|
2008-01-10 08:08:31 +00:00
|
|
|
#define ROCKBOY_SCROLLWHEEL_CC BUTTON_SCROLL_BACK
|
|
|
|
#define ROCKBOY_SCROLLWHEEL_CW BUTTON_SCROLL_FWD
|
2006-01-20 20:59:07 +00:00
|
|
|
#endif
|
|
|
|
|
2007-02-06 21:41:08 +00:00
|
|
|
struct fb fb IBSS_ATTR;
|
2005-03-02 23:49:38 +00:00
|
|
|
|
|
|
|
extern int debug_trace;
|
|
|
|
|
2006-09-26 19:25:20 +00:00
|
|
|
#ifdef HAVE_WHEEL_POSITION
|
2014-01-18 22:06:40 +00:00
|
|
|
static int oldwheel = -1, wheel;
|
2006-09-26 19:25:20 +00:00
|
|
|
|
|
|
|
static int wheelmap[8] = {
|
|
|
|
PAD_UP, /* Top */
|
|
|
|
PAD_A, /* Top-right */
|
|
|
|
PAD_RIGHT, /* Right */
|
|
|
|
PAD_START, /* Bottom-right */
|
|
|
|
PAD_DOWN, /* Bottom */
|
|
|
|
PAD_SELECT, /* Bottom-left */
|
|
|
|
PAD_LEFT, /* Left */
|
|
|
|
PAD_B /* Top-left */
|
|
|
|
};
|
|
|
|
#endif
|
2005-03-02 23:49:38 +00:00
|
|
|
|
2014-01-18 18:47:55 +00:00
|
|
|
void ev_poll(void)
|
2007-05-22 06:31:44 +00:00
|
|
|
{
|
2014-01-18 18:47:55 +00:00
|
|
|
event_t ev;
|
|
|
|
|
2014-01-18 22:06:40 +00:00
|
|
|
static unsigned int oldbuttonstate;
|
2007-05-22 06:31:44 +00:00
|
|
|
unsigned int buttons = BUTTON_NONE;
|
2014-01-18 22:06:40 +00:00
|
|
|
unsigned int released, pressed;
|
2007-05-22 06:31:44 +00:00
|
|
|
unsigned int btn;
|
2014-01-18 22:06:40 +00:00
|
|
|
bool quit = false;
|
2007-05-22 06:31:44 +00:00
|
|
|
|
|
|
|
do
|
|
|
|
{
|
2014-01-18 18:47:55 +00:00
|
|
|
btn = rb->button_get(false);
|
2014-01-18 22:06:40 +00:00
|
|
|
/* BUTTON_NONE doesn't necessarily mean no button is pressed,
|
|
|
|
* it just means the button queue became empty for this tick.
|
|
|
|
* One can only be sure that no button is pressed by
|
|
|
|
* calling button_status(). */
|
|
|
|
if (btn == BUTTON_NONE)
|
|
|
|
{
|
|
|
|
/* loop only until all button events are popped off */
|
|
|
|
quit = true;
|
|
|
|
btn = rb->button_status();
|
|
|
|
}
|
2007-05-22 06:31:44 +00:00
|
|
|
buttons |= btn;
|
2014-01-18 18:47:55 +00:00
|
|
|
#if defined(HAVE_SCROLLWHEEL) && !defined(ROCKBOY_SCROLLWHEEL)
|
|
|
|
/* filter out scroll wheel events if not supported */
|
|
|
|
buttons &= ~(BUTTON_SCROLL_FWD|BUTTON_SCROLL_BACK);
|
|
|
|
#endif
|
2007-05-22 06:31:44 +00:00
|
|
|
}
|
2014-01-18 22:06:40 +00:00
|
|
|
while (!quit);
|
2007-05-22 06:31:44 +00:00
|
|
|
|
2014-01-18 18:47:55 +00:00
|
|
|
released = ~buttons & oldbuttonstate;
|
|
|
|
pressed = buttons & ~oldbuttonstate;
|
2014-01-18 22:06:40 +00:00
|
|
|
|
2014-01-18 18:47:55 +00:00
|
|
|
oldbuttonstate = buttons;
|
2007-04-09 17:47:32 +00:00
|
|
|
#if (LCD_WIDTH == 160) && (LCD_HEIGHT == 128) && (LCD_DEPTH == 2)
|
2014-01-18 18:47:55 +00:00
|
|
|
static unsigned int holdbutton;
|
2005-03-04 12:48:29 +00:00
|
|
|
if (rb->button_hold()&~holdbutton)
|
2005-03-05 00:04:31 +00:00
|
|
|
fb.mode=(fb.mode+1)%4;
|
2005-03-04 12:48:29 +00:00
|
|
|
holdbutton=rb->button_hold();
|
2005-03-03 20:06:08 +00:00
|
|
|
#endif
|
2006-09-26 19:25:20 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_WHEEL_POSITION
|
|
|
|
/* Get the current wheel position - 0..95 or -1 for untouched */
|
|
|
|
wheel = rb->wheel_status();
|
|
|
|
|
|
|
|
/* Convert to number from 0 to 7 - clockwise from top */
|
|
|
|
if ( wheel > 0 ){
|
|
|
|
wheel += 6;
|
|
|
|
wheel /= 12;
|
|
|
|
if ( wheel > 7 ) wheel = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( wheel != oldwheel ) {
|
|
|
|
if (oldwheel >= 0) {
|
|
|
|
ev.type = EV_RELEASE;
|
|
|
|
ev.code = wheelmap[oldwheel];
|
|
|
|
ev_postevent(&ev);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (wheel >= 0) {
|
|
|
|
ev.type = EV_PRESS;
|
|
|
|
ev.code = wheelmap[wheel];
|
|
|
|
ev_postevent(&ev);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
oldwheel = wheel;
|
|
|
|
if(released) {
|
|
|
|
ev.type = EV_RELEASE;
|
|
|
|
if ( released & (~BUTTON_SELECT) ) { ev.code=PAD_B; ev_postevent(&ev); }
|
|
|
|
if ( released & BUTTON_SELECT ) { ev.code=PAD_A; ev_postevent(&ev); }
|
|
|
|
}
|
|
|
|
if(pressed) { /* button press */
|
|
|
|
ev.type = EV_PRESS;
|
|
|
|
if ( pressed & (~BUTTON_SELECT) ) { ev.code=PAD_B; ev_postevent(&ev); }
|
|
|
|
if ( pressed & BUTTON_SELECT ) { ev.code=PAD_A; ev_postevent(&ev); }
|
|
|
|
}
|
|
|
|
#else
|
2005-03-02 23:49:38 +00:00
|
|
|
if(released) {
|
|
|
|
ev.type = EV_RELEASE;
|
2010-11-28 19:49:15 +00:00
|
|
|
#ifdef HAVE_LCD_COLOR
|
|
|
|
if (options.rotate == 1) /* if screen is rotated, rotate direction keys */
|
|
|
|
{
|
|
|
|
if(released & options.LEFT) {ev.code=PAD_DOWN; ev_postevent(&ev);}
|
|
|
|
if(released & options.RIGHT) {ev.code=PAD_UP; ev_postevent(&ev);}
|
|
|
|
if(released & options.DOWN) {ev.code=PAD_RIGHT; ev_postevent(&ev);}
|
|
|
|
if(released & options.UP) {ev.code=PAD_LEFT; ev_postevent(&ev);}
|
|
|
|
}
|
|
|
|
else if (options.rotate == 2) /* if screen is rotated, rotate direction keys */
|
|
|
|
{
|
|
|
|
if(released & options.LEFT) {ev.code=PAD_UP; ev_postevent(&ev);}
|
|
|
|
if(released & options.RIGHT) {ev.code=PAD_DOWN; ev_postevent(&ev);}
|
|
|
|
if(released & options.DOWN) {ev.code=PAD_LEFT; ev_postevent(&ev);}
|
|
|
|
if(released & options.UP) {ev.code=PAD_RIGHT; ev_postevent(&ev);}
|
|
|
|
}
|
|
|
|
else /* screen is not rotated, do not rotate direction keys */
|
|
|
|
{
|
|
|
|
if(released & options.LEFT) {ev.code=PAD_LEFT; ev_postevent(&ev);}
|
|
|
|
if(released & options.RIGHT) {ev.code=PAD_RIGHT; ev_postevent(&ev);}
|
|
|
|
if(released & options.DOWN) {ev.code=PAD_DOWN; ev_postevent(&ev);}
|
|
|
|
if(released & options.UP) {ev.code=PAD_UP; ev_postevent(&ev);}
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
if(released & options.LEFT) {ev.code=PAD_LEFT; ev_postevent(&ev);}
|
2007-06-24 16:00:55 +00:00
|
|
|
if(released & options.RIGHT) {ev.code=PAD_RIGHT; ev_postevent(&ev);}
|
2010-11-28 19:49:15 +00:00
|
|
|
if(released & options.DOWN) {ev.code=PAD_DOWN; ev_postevent(&ev);}
|
|
|
|
if(released & options.UP) {ev.code=PAD_UP; ev_postevent(&ev);}
|
|
|
|
#endif
|
2006-01-20 13:05:52 +00:00
|
|
|
if(released & options.A) { ev.code=PAD_A; ev_postevent(&ev); }
|
|
|
|
if(released & options.B) { ev.code=PAD_B; ev_postevent(&ev); }
|
|
|
|
if(released & options.START) {
|
2005-03-02 23:49:38 +00:00
|
|
|
ev.code=PAD_START;
|
|
|
|
ev_postevent(&ev);
|
|
|
|
}
|
2006-01-20 13:05:52 +00:00
|
|
|
if(released & options.SELECT) {
|
2005-03-02 23:49:38 +00:00
|
|
|
ev.code=PAD_SELECT;
|
|
|
|
ev_postevent(&ev);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(pressed) { /* button press */
|
|
|
|
ev.type = EV_PRESS;
|
2010-11-28 19:49:15 +00:00
|
|
|
#ifdef HAVE_LCD_COLOR
|
|
|
|
if (options.rotate == 1) /* if screen is rotated, rotate direction keys */
|
|
|
|
{
|
|
|
|
if(pressed & options.LEFT) {ev.code=PAD_DOWN; ev_postevent(&ev);}
|
|
|
|
if(pressed & options.RIGHT) {ev.code=PAD_UP; ev_postevent(&ev);}
|
|
|
|
if(pressed & options.DOWN) {ev.code=PAD_RIGHT; ev_postevent(&ev);}
|
|
|
|
if(pressed & options.UP) {ev.code=PAD_LEFT; ev_postevent(&ev);}
|
|
|
|
}
|
|
|
|
else if (options.rotate == 2) /* if screen is rotated, rotate direction keys */
|
|
|
|
{
|
|
|
|
if(pressed & options.LEFT) {ev.code=PAD_UP; ev_postevent(&ev);}
|
|
|
|
if(pressed & options.RIGHT) {ev.code=PAD_DOWN; ev_postevent(&ev);}
|
|
|
|
if(pressed & options.DOWN) {ev.code=PAD_LEFT; ev_postevent(&ev);}
|
|
|
|
if(pressed & options.UP) {ev.code=PAD_RIGHT; ev_postevent(&ev);}
|
|
|
|
}
|
|
|
|
else /* screen is not rotated, do not rotate direction keys */
|
|
|
|
{
|
|
|
|
if(pressed & options.LEFT) {ev.code=PAD_LEFT; ev_postevent(&ev);}
|
|
|
|
if(pressed & options.RIGHT) {ev.code=PAD_RIGHT; ev_postevent(&ev);}
|
|
|
|
if(pressed & options.DOWN) {ev.code=PAD_DOWN; ev_postevent(&ev);}
|
|
|
|
if(pressed & options.UP) {ev.code=PAD_UP; ev_postevent(&ev);}
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
if(pressed & options.LEFT) {ev.code=PAD_LEFT; ev_postevent(&ev);}
|
|
|
|
if(pressed & options.RIGHT) {ev.code=PAD_RIGHT; ev_postevent(&ev);}
|
|
|
|
if(pressed & options.DOWN) {ev.code=PAD_DOWN; ev_postevent(&ev);}
|
|
|
|
if(pressed & options.UP) {ev.code=PAD_UP; ev_postevent(&ev);}
|
|
|
|
#endif
|
2006-01-20 13:05:52 +00:00
|
|
|
if(pressed & options.A) { ev.code=PAD_A; ev_postevent(&ev); }
|
|
|
|
if(pressed & options.B) { ev.code=PAD_B; ev_postevent(&ev); }
|
|
|
|
if(pressed & options.START) {
|
2005-03-02 23:49:38 +00:00
|
|
|
ev.code=PAD_START;
|
|
|
|
ev_postevent(&ev);
|
|
|
|
}
|
2006-01-20 13:05:52 +00:00
|
|
|
if(pressed & options.SELECT) {
|
2005-03-02 23:49:38 +00:00
|
|
|
ev.code=PAD_SELECT;
|
|
|
|
ev_postevent(&ev);
|
|
|
|
}
|
2006-09-26 19:25:20 +00:00
|
|
|
#endif
|
|
|
|
#if CONFIG_KEYPAD == IPOD_4G_PAD
|
|
|
|
if(rb->button_hold()) {
|
|
|
|
#else
|
2006-01-20 13:05:52 +00:00
|
|
|
if(pressed & options.MENU) {
|
2006-09-26 19:25:20 +00:00
|
|
|
#endif
|
|
|
|
#ifdef HAVE_WHEEL_POSITION
|
|
|
|
rb->wheel_send_events(true);
|
|
|
|
#endif
|
|
|
|
if (do_user_menu() == USER_MENU_QUIT)
|
|
|
|
{
|
|
|
|
die("");
|
|
|
|
cleanshut=1;
|
|
|
|
}
|
|
|
|
#ifdef HAVE_WHEEL_POSITION
|
|
|
|
rb->wheel_send_events(false);
|
2005-03-03 20:22:58 +00:00
|
|
|
#endif
|
2005-03-02 23:49:38 +00:00
|
|
|
}
|
2006-09-26 19:25:20 +00:00
|
|
|
|
2006-09-26 20:10:58 +00:00
|
|
|
#ifndef HAVE_WHEEL_POSITION
|
|
|
|
}
|
2006-09-26 19:25:20 +00:00
|
|
|
#endif
|
2005-03-02 23:49:38 +00:00
|
|
|
}
|
|
|
|
|
2007-02-06 21:41:08 +00:00
|
|
|
/* New frameskip, makes more sense to me and performs as well */
|
2010-09-07 14:09:11 +00:00
|
|
|
void vid_begin(void)
|
2005-03-02 23:49:38 +00:00
|
|
|
{
|
2007-02-06 21:41:08 +00:00
|
|
|
static int skip = 0;
|
|
|
|
if (skip<options.frameskip)
|
|
|
|
{
|
|
|
|
skip++;
|
|
|
|
fb.enabled=0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
skip=0;
|
|
|
|
fb.enabled=1;
|
|
|
|
}
|
2005-03-02 23:49:38 +00:00
|
|
|
}
|
|
|
|
|
2005-03-04 12:31:08 +00:00
|
|
|
void vid_init(void)
|
2005-03-02 23:49:38 +00:00
|
|
|
{
|
|
|
|
fb.enabled=1;
|
2006-01-10 21:55:56 +00:00
|
|
|
|
|
|
|
#if defined(HAVE_LCD_COLOR)
|
2018-04-10 12:13:35 +00:00
|
|
|
#if LCD_DEPTH >= 24
|
2014-06-18 05:15:00 +00:00
|
|
|
fb.cc[0].r = 0; /* 8-8 (wasted bits on red) */
|
|
|
|
fb.cc[0].l = 16; /* this is the offset to the R bits (24-8) */
|
|
|
|
fb.cc[1].r = 0; /* 8-6 (wasted bits on green) */
|
|
|
|
fb.cc[1].l = 8; /* This is the offset to the G bits (24-8-8) */
|
|
|
|
fb.cc[2].r = 0; /* 8-5 (wasted bits on red) */
|
|
|
|
fb.cc[2].l = 0; /* This is the offset to the B bits (24-8-8-8) */
|
|
|
|
#else
|
2007-02-06 21:41:08 +00:00
|
|
|
fb.cc[0].r = 3; /* 8-5 (wasted bits on red) */
|
|
|
|
fb.cc[0].l = 11; /* this is the offset to the R bits (16-5) */
|
|
|
|
fb.cc[1].r = 2; /* 8-6 (wasted bits on green) */
|
|
|
|
fb.cc[1].l = 5; /* This is the offset to the G bits (16-5-6) */
|
|
|
|
fb.cc[2].r = 3; /* 8-5 (wasted bits on red) */
|
|
|
|
fb.cc[2].l = 0; /* This is the offset to the B bits (16-5-6-5) */
|
2014-06-18 05:15:00 +00:00
|
|
|
#endif
|
2007-02-06 21:41:08 +00:00
|
|
|
#else
|
|
|
|
fb.mode=3;
|
2005-11-16 22:59:28 +00:00
|
|
|
#endif
|
2006-01-10 21:55:56 +00:00
|
|
|
}
|
2005-11-16 22:59:28 +00:00
|
|
|
|
2006-06-19 01:47:45 +00:00
|
|
|
#if !defined(HAVE_LCD_COLOR)
|
|
|
|
/* Color targets are handled in lcd.c */
|
2006-01-10 21:55:56 +00:00
|
|
|
fb_data *frameb;
|
2005-03-02 23:49:38 +00:00
|
|
|
void vid_update(int scanline)
|
2006-01-20 13:05:52 +00:00
|
|
|
{
|
|
|
|
register int cnt=0;
|
2020-10-07 06:01:35 +00:00
|
|
|
static fb_data *lcd_fb = NULL;
|
|
|
|
if (!lcd_fb)
|
|
|
|
{
|
|
|
|
struct viewport *vp_main = *(rb->screens[SCREEN_MAIN]->current_viewport);
|
|
|
|
lcd_fb = vp_main->buffer->fb_ptr;
|
|
|
|
}
|
2006-01-10 21:55:56 +00:00
|
|
|
int scanline_remapped;
|
2010-05-18 12:46:53 +00:00
|
|
|
#if (LCD_HEIGHT == 64) && (LCD_DEPTH == 1) /* Archos, Clip, m200v4 */
|
2005-03-02 23:49:38 +00:00
|
|
|
int balance = 0;
|
2005-03-03 19:44:02 +00:00
|
|
|
if (fb.mode==1)
|
2005-11-16 22:59:28 +00:00
|
|
|
scanline-=16;
|
2005-03-04 20:56:49 +00:00
|
|
|
else if (fb.mode==2)
|
2005-11-16 22:59:28 +00:00
|
|
|
scanline-=8;
|
2016-06-25 14:30:37 +00:00
|
|
|
scanline_remapped = scanline / 16;
|
2020-10-07 06:01:35 +00:00
|
|
|
frameb = lcd_fb + scanline_remapped * LCD_WIDTH;
|
2005-03-02 23:49:38 +00:00
|
|
|
while (cnt < 160) {
|
|
|
|
balance += LCD_WIDTH;
|
|
|
|
if (balance > 0)
|
|
|
|
{
|
2005-11-16 22:59:28 +00:00
|
|
|
register unsigned scrbyte = 0;
|
|
|
|
if (scan.buf[0][cnt] & 0x02) scrbyte |= 0x01;
|
|
|
|
if (scan.buf[1][cnt] & 0x02) scrbyte |= 0x02;
|
|
|
|
if (scan.buf[2][cnt] & 0x02) scrbyte |= 0x04;
|
|
|
|
if (scan.buf[3][cnt] & 0x02) scrbyte |= 0x08;
|
|
|
|
if (scan.buf[4][cnt] & 0x02) scrbyte |= 0x10;
|
|
|
|
if (scan.buf[5][cnt] & 0x02) scrbyte |= 0x20;
|
|
|
|
if (scan.buf[6][cnt] & 0x02) scrbyte |= 0x40;
|
|
|
|
if (scan.buf[7][cnt] & 0x02) scrbyte |= 0x80;
|
|
|
|
*(frameb++) = scrbyte;
|
2005-03-02 23:49:38 +00:00
|
|
|
balance -= 160;
|
|
|
|
}
|
|
|
|
cnt ++;
|
|
|
|
}
|
|
|
|
rb->lcd_update_rect(0, (scanline/2) & ~7, LCD_WIDTH, 8);
|
2010-05-18 12:46:53 +00:00
|
|
|
#elif (LCD_HEIGHT == 128) && (LCD_DEPTH == 2) /* iriver H1x0, Samsung YH920 */
|
2005-03-03 19:44:02 +00:00
|
|
|
if (fb.mode==1)
|
2005-11-16 22:59:28 +00:00
|
|
|
scanline-=16;
|
2005-03-04 20:56:49 +00:00
|
|
|
else if (fb.mode==2)
|
2005-11-16 22:59:28 +00:00
|
|
|
scanline-=8;
|
2005-03-04 11:01:33 +00:00
|
|
|
scanline_remapped = scanline / 4;
|
2020-10-07 06:01:35 +00:00
|
|
|
frameb = lcd_fb + scanline_remapped * LCD_WIDTH;
|
2005-03-02 23:49:38 +00:00
|
|
|
while (cnt < 160) {
|
2005-03-04 11:01:33 +00:00
|
|
|
*(frameb++) = (scan.buf[0][cnt]&0x3) |
|
|
|
|
((scan.buf[1][cnt]&0x3)<<2) |
|
|
|
|
((scan.buf[2][cnt]&0x3)<<4) |
|
|
|
|
((scan.buf[3][cnt]&0x3)<<6);
|
|
|
|
cnt++;
|
|
|
|
}
|
2005-07-06 22:58:02 +00:00
|
|
|
rb->lcd_update_rect(0, scanline & ~3, LCD_WIDTH, 4);
|
2007-02-06 21:41:08 +00:00
|
|
|
#elif defined(HAVE_LCD_COLOR)
|
|
|
|
/* handled in lcd.c now */
|
2005-03-04 11:01:33 +00:00
|
|
|
#endif /* LCD_HEIGHT */
|
2005-03-02 23:49:38 +00:00
|
|
|
}
|
2006-01-20 13:05:52 +00:00
|
|
|
#endif
|