/*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * $Id$ * * Copyright (C) 2005 Michiel van der Kolk, Jens Arnold * * 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 "rockmacros.h" #include "fb.h" #include "input.h" #include "lcd-gb.h" #include "hw.h" #include "config.h" #if CONFIG_KEYPAD == SANSA_E200_PAD || CONFIG_KEYPAD == SANSA_FUZE_PAD #define ROCKBOY_SCROLLWHEEL #define ROCKBOY_SCROLLWHEEL_CC BUTTON_SCROLL_BACK #define ROCKBOY_SCROLLWHEEL_CW BUTTON_SCROLL_FWD #endif struct fb fb IBSS_ATTR; extern int debug_trace; unsigned int oldbuttonstate = 0, newbuttonstate,holdbutton; #ifdef HAVE_WHEEL_POSITION int oldwheel = -1, wheel; 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 int released, pressed; #ifdef ROCKBOY_SCROLLWHEEL /* Scrollwheel events are posted directly and not polled by the button driver - synthesize polling */ static inline unsigned int read_scroll_wheel(void) { unsigned int buttons = BUTTON_NONE; unsigned int btn; /* Empty out the button queue and see if any scrollwheel events were posted */ do { btn = rb->button_get_w_tmo(0); buttons |= btn; } while (btn != BUTTON_NONE); return buttons & (ROCKBOY_SCROLLWHEEL_CC | ROCKBOY_SCROLLWHEEL_CW); } #endif void ev_poll(void) { event_t ev; newbuttonstate = rb->button_status(); #ifdef ROCKBOY_SCROLLWHEEL newbuttonstate |= read_scroll_wheel(); #endif released = ~newbuttonstate & oldbuttonstate; pressed = newbuttonstate & ~oldbuttonstate; oldbuttonstate = newbuttonstate; #if (LCD_WIDTH == 160) && (LCD_HEIGHT == 128) && (LCD_DEPTH == 2) if (rb->button_hold()&~holdbutton) fb.mode=(fb.mode+1)%4; holdbutton=rb->button_hold(); #elif CONFIG_KEYPAD == RECORDER_PAD if (pressed & BUTTON_ON) fb.mode=(fb.mode+1)%4; #endif #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 if(released) { ev.type = EV_RELEASE; #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);} 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);} #endif 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) { ev.code=PAD_START; ev_postevent(&ev); } if(released & options.SELECT) { ev.code=PAD_SELECT; ev_postevent(&ev); } } if(pressed) { /* button press */ ev.type = EV_PRESS; #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 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) { ev.code=PAD_START; ev_postevent(&ev); } if(pressed & options.SELECT) { ev.code=PAD_SELECT; ev_postevent(&ev); } #endif #if CONFIG_KEYPAD == IPOD_4G_PAD if(rb->button_hold()) { #else if(pressed & options.MENU) { #endif #if (CONFIG_KEYPAD != RECORDER_PAD) #ifdef HAVE_WHEEL_POSITION rb->wheel_send_events(true); #endif if (do_user_menu() == USER_MENU_QUIT) #endif { die(""); cleanshut=1; } #ifdef HAVE_WHEEL_POSITION rb->wheel_send_events(false); #endif } #ifndef HAVE_WHEEL_POSITION } #endif } /* New frameskip, makes more sense to me and performs as well */ void vid_begin(void) { static int skip = 0; if (skiplcd_framebuffer + scanline_remapped * LCD_WIDTH; while (cnt < 160) { balance += LCD_WIDTH; if (balance > 0) { #if (CONFIG_CPU == SH7034) && !defined(SIMULATOR) asm volatile ( "mov.b @%0,r0 \n" "add %1,%0 \n" "tst #0x02, r0 \n" /* ~bit 1 */ "rotcr r1 \n" "mov.b @%0,r0 \n" "add %1,%0 \n" "tst #0x02, r0 \n" /* ~bit 1 */ "rotcr r1 \n" "mov.b @%0,r0 \n" "add %1,%0 \n" "tst #0x02, r0 \n" /* ~bit 1 */ "rotcr r1 \n" "mov.b @%0,r0 \n" "add %1,%0 \n" "tst #0x02, r0 \n" /* ~bit 1 */ "rotcr r1 \n" "mov.b @%0,r0 \n" "add %1,%0 \n" "tst #0x02, r0 \n" /* ~bit 1 */ "rotcr r1 \n" "mov.b @%0,r0 \n" "add %1,%0 \n" "tst #0x02, r0 \n" /* ~bit 1 */ "rotcr r1 \n" "mov.b @%0,r0 \n" "add %1,%0 \n" "tst #0x02, r0 \n" /* ~bit 1 */ "rotcr r1 \n" "mov.b @%0,r0 \n" "add %1,%0 \n" "tst #0x02, r0 \n" /* ~bit 1 */ "rotcr r1 \n" "shlr16 r1 \n" "shlr8 r1 \n" "not r1,r1 \n" /* account for negated bits */ "mov.b r1,@%2 \n" : /* outputs */ : /* inputs */ /* %0 */ "r"(scan.buf[0] + cnt), /* %1 */ "r"(256), /* scan.buf line length */ /* %2 */ "r"(frameb++) : /* clobbers */ "r0", "r1" ); #else 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; #endif balance -= 160; } cnt ++; } rb->lcd_update_rect(0, (scanline/2) & ~7, LCD_WIDTH, 8); #elif (LCD_HEIGHT == 128) && (LCD_DEPTH == 2) /* iriver H1x0, Samsung YH920 */ if (fb.mode==1) scanline-=16; else if (fb.mode==2) scanline-=8; scanline_remapped = scanline / 4; frameb = rb->lcd_framebuffer + scanline_remapped * LCD_WIDTH; while (cnt < 160) { *(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++; } rb->lcd_update_rect(0, scanline & ~3, LCD_WIDTH, 4); #elif defined(HAVE_LCD_COLOR) /* handled in lcd.c now */ #endif /* LCD_HEIGHT */ } #endif