A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 233 lines 7.5 kB view raw
1/***************************************************************************** 2 * __________ __ ___. 3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 * Source | _// __ \_/ ___\| |/ /| __ \ / __ \ \/ / 5 * Jukebox | | ( (__) ) \___| ( | \_\ ( (__) ) ( 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 * \/ \/ \/ \/ \/ 8 * $Id$ 9 * 10 * Copyright (C) 2006 - 2008 Alexander Papst 11 * Idea from http://www.tetris1d.org 12 * 13 * This program is free software; you can redistribute it and/or 14 * modify it under the terms of the GNU General Public License 15 * as published by the Free Software Foundation; either version 2 16 * of the License, or (at your option) any later version. 17 * 18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19 * KIND, either express or implied. 20 * 21 ****************************************************************************/ 22 23#include "plugin.h" 24#include "lib/pluginlib_actions.h" 25 26/* this set the context to use with PLA */ 27static const struct button_mapping *plugin_contexts[] = { pla_main_ctx }; 28#define ONEDROCKBLOX_DOWN PLA_DOWN 29#define ONEDROCKBLOX_DOWN_REPEAT PLA_DOWN_REPEAT 30#define ONEDROCKBLOX_QUIT PLA_EXIT 31 32#if (CONFIG_KEYPAD == IPOD_1G2G_PAD) \ 33 || (CONFIG_KEYPAD == IPOD_3G_PAD) \ 34 || (CONFIG_KEYPAD == IPOD_4G_PAD) 35#define ONEDROCKBLOX_QUIT2 PLA_UP 36#else 37#define ONEDROCKBLOX_QUIT2 PLA_CANCEL 38#endif 39 40#define mrand(max) (short)(rb->rand()%max) 41 42#define TILES 11 43 44/********** 45** Lots of defines for the drawing stuff :-) 46** The most ugly way i could think of... 47*/ 48 49#if (LCD_WIDTH > LCD_HEIGHT) 50 /* Any screens larger than the minis LCD */ 51#if (LCD_WIDTH > 132) 52 /* Max size of one block */ 53# define WIDTH (int)((LCD_HEIGHT * 0.85) / TILES) 54 /* Align the playing filed centered */ 55# define CENTER_X (int)(LCD_WIDTH/2-(WIDTH/2)) 56# define CENTER_Y (int)(LCD_HEIGHT/2-((WIDTH*TILES+TILES)/2)) 57 /* Score box */ 58# define SCORE_X (int)(((CENTER_X+WIDTH+4) + (LCD_WIDTH-(CENTER_X+WIDTH+4))/2)-(f_width/2)) 59# define SCORE_Y (int)((LCD_HEIGHT/2)-(f_height/2)) 60 /* Max. size of bricks is 4 blocks */ 61# define NEXT_H (WIDTH*4+3) 62# define NEXT_X (int)(CENTER_X/2-WIDTH/2) 63# define NEXT_Y (int)(LCD_HEIGHT/2-NEXT_H/2) 64#else 65 /* Max size of one block */ 66# define WIDTH (int)((LCD_HEIGHT * 0.85) / TILES) 67 /* Align the playing left centered */ 68# define CENTER_X (int)(LCD_WIDTH*0.2) 69# define CENTER_Y (int)(LCD_HEIGHT/2-((WIDTH*TILES+TILES)/2)) 70 /* Score box */ 71# define SCORE_X (int)(((CENTER_X+WIDTH+4) + (LCD_WIDTH-(CENTER_X+WIDTH+4))/2)-(f_width/2)) 72# define SCORE_Y 16 73 /* Max. size of bricks is 4 blocks */ 74# define NEXT_H (WIDTH*4+3) 75# define NEXT_X (score_x+f_width+7) 76# define NEXT_Y (int)(LCD_HEIGHT-((4*WIDTH)+13)) 77#endif 78#else 79 /* Max size of one block */ 80# define WIDTH (int)((LCD_HEIGHT * 0.8) / TILES) 81 /* Align the playing filed centered */ 82# define CENTER_X (int)(LCD_WIDTH/2-(WIDTH/2)) 83# define CENTER_Y 2 84 /* Score box */ 85# define SCORE_X (int)((LCD_WIDTH/2)-(f_width/2)) 86# define SCORE_Y (LCD_HEIGHT-(f_height+2)) 87 /* Max. size of bricks is 4 blocks */ 88# define NEXT_H (WIDTH*4+3) 89# define NEXT_X (int)(CENTER_X/2-WIDTH/2) 90# define NEXT_Y (int)((LCD_HEIGHT * 0.8)/2-NEXT_H/2) 91#endif 92 93static void draw_brick(int pos, int length) { 94 int i = pos; 95 rb->lcd_set_drawmode(DRMODE_BG|DRMODE_INVERSEVID); 96 rb->lcd_fillrect(CENTER_X, CENTER_Y, WIDTH, WIDTH * TILES + TILES); 97 rb->lcd_set_drawmode(DRMODE_SOLID); 98 99 for (i = pos; i < length + pos; ++i) { 100 if (i >= 0) rb->lcd_fillrect(CENTER_X, CENTER_Y+i+(WIDTH*i), WIDTH, WIDTH); 101 } 102} 103 104enum plugin_status plugin_start(const void* parameter) 105{ 106 int i; 107 int f_width, f_height; 108 int score_x; 109 110 bool quit = false; 111 int button; 112 113 int cycletime = 300; 114 int end; 115 116 int pos_cur_brick = 0; 117 int type_cur_brick = 0; 118 int type_next_brick = 0; 119 120 unsigned long int score = 34126; 121 122 (void)parameter; 123 124#if LCD_DEPTH > 1 125 rb->lcd_set_backdrop(NULL); 126 rb->lcd_set_background(LCD_BLACK); 127 rb->lcd_set_foreground(LCD_WHITE); 128#endif 129 130 rb->lcd_setfont(FONT_SYSFIXED); 131 132 rb->lcd_getstringsize("100000000", &f_width, &f_height); 133 134 rb->lcd_clear_display(); 135 136 /*********** 137 ** Draw EVERYTHING 138 */ 139 140 /* Playing filed box */ 141 rb->lcd_vline(CENTER_X-2, CENTER_Y, CENTER_Y + (WIDTH*TILES+TILES)); 142 rb->lcd_vline(CENTER_X + WIDTH + 1, CENTER_Y, 143 CENTER_Y + (WIDTH*TILES+TILES)); 144 rb->lcd_hline(CENTER_X-2, CENTER_X + WIDTH + 1, 145 CENTER_Y + (WIDTH*TILES+TILES)); 146 147 /* Score box */ 148#if (LCD_WIDTH > LCD_HEIGHT) 149 rb->lcd_drawrect(SCORE_X-4, SCORE_Y-5, f_width+8, f_height+9); 150 rb->lcd_putsxy(SCORE_X-4, SCORE_Y-6-f_height, "score"); 151#else 152 rb->lcd_hline(0, LCD_WIDTH, SCORE_Y-5); 153 rb->lcd_putsxy(2, SCORE_Y-6-f_height, "score"); 154#endif 155 score_x = SCORE_X; 156 157 /* Next box */ 158 rb->lcd_getstringsize("next", &f_width, NULL); 159#if (LCD_WIDTH > LCD_HEIGHT) && !(LCD_WIDTH > 132) 160 rb->lcd_drawrect(NEXT_X-5, NEXT_Y-5, WIDTH+10, NEXT_H+10); 161 rb->lcd_putsxy(score_x-4, NEXT_Y-5, "next"); 162#else 163 rb->lcd_drawrect(NEXT_X-5, NEXT_Y-5, WIDTH+10, NEXT_H+10); 164 rb->lcd_putsxy(NEXT_X-5, NEXT_Y-5-f_height-1, "next"); 165#endif 166 167 /*********** 168 ** GAMELOOP 169 */ 170 rb->srand( *rb->current_tick ); 171 172 type_cur_brick = 2 + mrand(3); 173 type_next_brick = 2 + mrand(3); 174 175 do { 176 end = *rb->current_tick + (cycletime * HZ) / 1000; 177 178 draw_brick(pos_cur_brick, type_cur_brick); 179 180 /* Draw next brick */ 181 rb->lcd_set_drawmode(DRMODE_BG|DRMODE_INVERSEVID); 182 rb->lcd_fillrect(NEXT_X, NEXT_Y, WIDTH, WIDTH * 4 + 4); 183 rb->lcd_set_drawmode(DRMODE_SOLID); 184 185 for (i = 0; i < type_next_brick; ++i) { 186 rb->lcd_fillrect(NEXT_X, 187 NEXT_Y + ((type_next_brick % 2) ? (int)(WIDTH/2) : ((type_next_brick == 2) ? (WIDTH+1) : 0)) + (WIDTH*i) + i, 188 WIDTH, WIDTH); 189 } 190 191 /* Score box */ 192 rb->lcd_putsxyf(score_x, SCORE_Y, "%8ld0", score); 193 194 rb->lcd_update(); 195 196 /*We get button from PLA this way */ 197 button = pluginlib_getaction(TIMEOUT_NOBLOCK, plugin_contexts, 198 ARRAYLEN(plugin_contexts)); 199 200 switch(button) { 201 case ONEDROCKBLOX_DOWN: 202 case ONEDROCKBLOX_DOWN_REPEAT: 203 cycletime = 100; 204 break; 205 case ONEDROCKBLOX_QUIT: 206 case ONEDROCKBLOX_QUIT2: 207 quit = true; 208 break; 209 default: 210 cycletime = 300; 211 if(rb->default_event_handler(button) == SYS_USB_CONNECTED) { 212 quit = true; 213 } 214 } 215 216 if ((pos_cur_brick + type_cur_brick) > 10) { 217 type_cur_brick = type_next_brick; 218 type_next_brick = 2 + mrand(3); 219 score += (type_cur_brick - 1) * 2; 220 pos_cur_brick = 1 - type_cur_brick; 221 } else { 222 ++pos_cur_brick; 223 } 224 225 if (TIME_BEFORE(*rb->current_tick, end)) 226 rb->sleep(end-*rb->current_tick); 227 else 228 rb->yield(); 229 230 } while (!quit); 231 232 return PLUGIN_OK; 233}