/* timeout tick task - calls event handlers when they expire * Event handlers may alter expiration, callback and data during operation. */ static void timeout_tick(void) { unsigned long tick = current_tick; struct timeout **p = tmo_list; struct timeout *curr; for(curr = *p; curr != NULL; curr = *(++p)) { int ticks; if(TIME_BEFORE(tick, curr->expires)) continue; /* this event has expired - call callback */ ticks = curr->callback(curr); if(ticks > 0) { curr->expires = tick + ticks; /* reload */ } else { timeout_cancel(curr); /* cancel */ } } }
static int time_menu_callback(int action, const struct menu_item_ex *this_item) { (void)this_item; int i; static int last_redraw = 0; bool redraw = false; if (TIME_BEFORE(last_redraw+HZ/2, current_tick)) redraw = true; switch (action) { case ACTION_REDRAW: redraw = true; break; case ACTION_STD_CONTEXT: talk_timedate(); action = ACTION_NONE; break; /* need to tell do_menu() to return, but then get time_screen() to return 0! ACTION_STD_MENU will return GO_TO_PREVIOUS from here so check do_menu()'s return val and menu_was_pressed */ case ACTION_STD_MENU: menu_was_pressed = true; break; } if (redraw) { last_redraw = current_tick; FOR_NB_SCREENS(i) draw_timedate(&clock[i], &screens[i]); } return action; }
void LCDFN(scroll_fn)(void) { struct font* pf; struct scrollinfo* s; int index; int xpos, ypos; struct viewport* old_vp = current_vp; for ( index = 0; index < LCDFN(scroll_info).lines; index++ ) { s = &LCDFN(scroll_info).scroll[index]; /* check pause */ if (TIME_BEFORE(current_tick, s->start_tick)) continue; LCDFN(set_viewport)(s->vp); if (s->backward) s->offset -= LCDFN(scroll_info).step; else s->offset += LCDFN(scroll_info).step; pf = font_get(current_vp->font); xpos = s->startx; ypos = s->y * pf->height + s->y_offset; if (s->bidir) { /* scroll bidirectional */ if (s->offset <= 0) { /* at beginning of line */ s->offset = 0; s->backward = false; s->start_tick = current_tick + LCDFN(scroll_info).delay * 2; } if (s->offset >= s->width - (current_vp->width - xpos)) { /* at end of line */ s->offset = s->width - (current_vp->width - xpos); s->backward = true; s->start_tick = current_tick + LCDFN(scroll_info).delay * 2; } } else { /* scroll forward the whole time */ if (s->offset >= s->width) s->offset %= s->width; } LCDFN(putsxyofs_style)(xpos, ypos, s->line, s->style, s->width, pf->height, s->offset); LCDFN(update_viewport_rect)(xpos, ypos, current_vp->width - xpos, pf->height); } LCDFN(set_viewport)(old_vp); }
/* This waits for an ATA interrupt using polling. In ATA_CONTROL, CONTROL_nIEN must be cleared. */ STATICIRAM ICODE_ATTR int ata_wait_intrq(void) { long timeout = current_tick + HZ*10; do { if (IDE0_CFG & IDE_CFG_INTRQ) return 1; ata_keep_active(); yield(); } while (TIME_BEFORE(current_tick, timeout)); return 0; /* timeout */ }
static ICODE_ATTR int wait_for_bsy(void) { long timeout = current_tick + HZ*30; do { if (!(ATA_IN8(ATA_STATUS) & STATUS_BSY)) return 1; last_disk_activity = current_tick; yield(); } while (TIME_BEFORE(current_tick, timeout)); return 0; /* timeout */ }
/* do the button loop as often as required for the peak meters to update * with a good refresh rate. */ int skin_wait_for_action(enum skinnable_screens skin, int context, int timeout) { (void)skin; /* silence charcell warning */ int button = ACTION_NONE; #ifdef HAVE_LCD_BITMAP int i; /* when the peak meter is enabled we want to have a few extra updates to make it look smooth. On the other hand we don't want to waste energy if it isn't displayed */ bool pm=false; FOR_NB_SCREENS(i) { if(skin_get_gwps(skin, i)->data->peak_meter_enabled) pm = true; } if (pm) { long next_refresh = current_tick; long next_big_refresh = current_tick + timeout; button = BUTTON_NONE; while (TIME_BEFORE(current_tick, next_big_refresh)) { button = get_action(context,TIMEOUT_NOBLOCK); if (button != ACTION_NONE) { break; } peak_meter_peek(); sleep(0); /* Sleep until end of current tick. */ if (TIME_AFTER(current_tick, next_refresh)) { FOR_NB_SCREENS(i) { if(skin_get_gwps(skin, i)->data->peak_meter_enabled) skin_update(skin, i, SKIN_REFRESH_PEAK_METER); next_refresh += HZ / PEAK_METER_FPS; } } } } /* The peak meter is disabled -> no additional screen updates needed */ else #endif {
static void fine_step_tune(int (*setcmp)(int regval), int regval, int step) { /* Registers are not always stable, timeout if best fit not found soon enough */ unsigned long abort = current_tick + HZ*2; int flags = 0; while (TIME_BEFORE(current_tick, abort)) { int cmp; regval = regval + step; cmp = setcmp(regval); if (cmp == 0) break; step = abs(step); if (cmp < 0) { flags |= TOO_SMALL; if (step == 1) flags |= APPROACH_UP_1; } else { step = -step; flags |= TOO_BIG; if (step == -1) step |= APPROACH_DOWN_1; } if ((flags & APPROACH_UP_1) && (flags & APPROACH_DOWN_1)) break; /* approached with step=1: best fit value found */ if ((flags & TOO_SMALL) && (flags & TOO_BIG)) { step /= 2; if (step == 0) step = 1; flags &= ~(TOO_SMALL | TOO_BIG); } } }
/* Returns battery voltage from ADC [millivolts] */ unsigned int battery_adc_voltage(void) { static unsigned last_tick = 0; if (TIME_BEFORE(last_tick+HZ, current_tick)) { short adc_val; if (get_pmu_type() == PCF50606) pcf50606_read_adc(PCF5060X_ADC_BATVOLT_RES, &adc_val, NULL); else pcf50635_read_adc(PCF5063X_ADCC1_MUX_BATSNS_RES, &adc_val, NULL); current_voltage = (adc_val * BATTERY_SCALE_FACTOR) >> 10; last_tick = current_tick; }
static int find_oldest_image_index(void) { int i; long oldest_tick = current_tick; int oldest_idx = -1; for(i = 0; ARRAYLEN(radioart); i++) { struct radioart *ra = &radioart[i]; /* last_tick is only valid if it's actually loaded, i.e. valid handle */ if (ra->handle >= 0 && TIME_BEFORE(ra->last_tick, oldest_tick)) { oldest_tick = ra->last_tick; oldest_idx = i; } } return oldest_idx; }
zchar do_input(int timeout, bool show_cursor) { int action; long timeout_at; zchar menu_ret; dumb_show_screen(show_cursor); /* Convert timeout (tenths of a second) to ticks */ if (timeout > 0) timeout = (timeout * HZ) / 10; else timeout = TIMEOUT_BLOCK; timeout_at = *rb->current_tick + timeout; for (;;) { action = pluginlib_getaction(timeout, plugin_contexts, 1); switch (action) { case PLA_QUIT: return ZC_HKEY_QUIT; case PLA_MENU: menu_ret = menu(); if (menu_ret != ZC_BAD) return menu_ret; timeout_at = *rb->current_tick + timeout; break; case PLA_FIRE: return ZC_RETURN; case PLA_START: return ZC_BAD; default: if (timeout != TIMEOUT_BLOCK && !TIME_BEFORE(*rb->current_tick, timeout_at)) return ZC_TIME_OUT; } } }
/*----------------------------------------------------------------------------*/ VOID timerStartTimer ( IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer, IN UINT_32 u4TimeoutMs ) { P_LINK_T prTimerList; OS_SYSTIME rExpiredSysTime; ASSERT(prAdapter); ASSERT(prTimer); prTimerList= &prAdapter->rTimerList; /* To avoid infinite loop in function wlanDoTimeOutCheck(), * zero interval is not permitted. */ if (u4TimeoutMs == 0) { u4TimeoutMs = 1; } rExpiredSysTime = kalGetTimeTick() + MSEC_TO_SYSTIME(u4TimeoutMs); /* If no timer pending or the fast time interval is used. */ if (prTimerList->prNext == (P_LINK_ENTRY_T)prTimerList || TIME_BEFORE(rExpiredSysTime, prAdapter->rNextExpiredSysTime)) { if (timerSetTimer(prAdapter, MSEC_TO_SYSTIME(u4TimeoutMs))) { prAdapter->rNextExpiredSysTime = rExpiredSysTime; } } /* Add this timer to checking list */ prTimer->rExpiredSysTime = rExpiredSysTime; if (!timerPendingTimer(prTimer)) { LINK_INSERT_TAIL(prTimerList, &prTimer->rLinkEntry); } return; } /* timerStartTimer */
static bool storage_should_wait(int drive, int prio) { int other_prio = thread_get_io_priority(storage_last_thread[drive]); if(TIME_BEFORE(current_tick,storage_last_activity[drive]+STORAGE_MINIMUM_IDLE_TIME)) { if(prio<=other_prio) { /* There is another active thread, but we have lower priority */ return false; } else { /* There is another active thread, but it has lower priority */ return true; } } else { /* There's nothing going on anyway */ return false; } }
/*{{{ tvm_sleep */ static void tvm_sleep (void) { WORD now = firmware->get_time (firmware); WORD timeout = 0; int set = 0; if (firmware->tptr != NOT_PROCESS_P) { timeout = firmware->tnext; set++; } if (user->tptr != NOT_PROCESS_P) { if (!set || TIME_BEFORE(user->tnext, timeout)) { timeout = user->tnext; set++; } } if (set && TIME_AFTER(timeout, now)) { unsigned int period = timeout - now; if (period > 0) { #if defined(HAVE_NANOSLEEP) struct timespec to; to.tv_sec = (period / 1000000); to.tv_nsec = ((period % 1000000) * 1000); nanosleep (&to, 0); #elif defined(HAVE_SLEEP) Sleep (period / 1000); #else #warning "Don't know how to sleep..." #endif } } }
void mouse_tick_task(void) { static int last_check = 0; int x,y; if (TIME_BEFORE(current_tick, last_check+(HZ/10))) return; last_check = current_tick; if (SDL_GetMouseState(&x, &y) & SDL_BUTTON(SDL_BUTTON_LEFT)) { if(background) { x -= UI_LCD_POSX; y -= UI_LCD_POSY; if(x<0 || y<0 || x>SIM_LCD_WIDTH || y>SIM_LCD_HEIGHT) return; } mouse_coords = (x<<16)|y; button_event(BUTTON_TOUCHSCREEN, true); if (debug_wps) printf("Mouse at: (%d, %d)\n", x, y); } }
static int clix_handle_game(struct clix_game_state_t* state) { int button; int blink_tick = *rb->current_tick + BLINK_TICKCOUNT; int time; int start; int end; int oldx, oldy; if (clix_menu(state, 0)) return 1; while(true) { if (TIME_AFTER(*rb->current_tick, blink_tick)) { state->blink = !state->blink; blink_tick = *rb->current_tick + BLINK_TICKCOUNT; } time = 6; /* number of ticks this function will loop reading keys */ start = *rb->current_tick; end = start + time; while(TIME_BEFORE(*rb->current_tick, end)) { oldx = state->x; oldy = state->y; button = rb->button_get_w_tmo(end - *rb->current_tick); #ifdef HAVE_TOUCHSCREEN if(button & BUTTON_TOUCHSCREEN) { int x = rb->button_get_data() >> 16; int y = rb->button_get_data() & 0xffff; x -= XOFS; y -= YOFS; if(x >= 0 && y >= 0) { x /= CELL_SIZE + 1; y /= CELL_SIZE + 1; if(x < BOARD_WIDTH && y < BOARD_HEIGHT && state->board[XYPOS(x, y)] != CC_BLACK) { if(state->x == x && state->y == y && button & BUTTON_REL) button = CLIX_BUTTON_CLICK; else { state->x = x; state->y = y; } } } } #endif switch( button) { #ifndef HAVE_TOUCHSCREEN #ifdef CLIX_BUTTON_SCROLL_BACK case CLIX_BUTTON_SCROLL_BACK: case CLIX_BUTTON_SCROLL_BACK|BUTTON_REPEAT: #endif case CLIX_BUTTON_UP: case CLIX_BUTTON_UP|BUTTON_REPEAT: if( state->y == 0 || state->board[ XYPOS( state->x, state->y - 1)] == CC_BLACK ) state->y = BOARD_HEIGHT - 1; else state->y--; clix_move_cursor(state, true); break; #ifdef CLIX_BUTTON_SCROLL_FWD case CLIX_BUTTON_SCROLL_FWD: case CLIX_BUTTON_SCROLL_FWD|BUTTON_REPEAT: #endif case CLIX_BUTTON_DOWN: case CLIX_BUTTON_DOWN|BUTTON_REPEAT: if( state->y == (BOARD_HEIGHT - 1)) state->y = 0; else state->y++; clix_move_cursor( state, true); break; case CLIX_BUTTON_RIGHT: case CLIX_BUTTON_RIGHT|BUTTON_REPEAT: if( state->x == (BOARD_WIDTH - 1)) state->x = 0; else state->x++; clix_move_cursor(state, false); break; case CLIX_BUTTON_LEFT: case CLIX_BUTTON_LEFT|BUTTON_REPEAT: if( state->x == 0) state->x = BOARD_WIDTH - 1; else state->x--; clix_move_cursor(state, true); break; #endif case CLIX_BUTTON_CLICK: if (clix_click(state) == 1) return 1; break; case CLIX_BUTTON_QUIT: if (clix_menu(state, 1) != 0) { rb->button_clear_queue(); return 1; } break; default: break; } if( (oldx != state->x || oldy != state->y) && state->board_selected[ XYPOS( oldx, oldy)] != state->board_selected[ XYPOS( state->x, state->y)] ) { clix_update_selected(state); } clix_draw(state); rb->sleep(time); } }
static int chopGameLoop(void) { int move_button, ret; bool exit=false; bool showsplash=true; int end, i=0, bdelay=0, last_button=BUTTON_NONE; if (chopUpdateTerrainRecycling(&mGround) == 1) /* mirror the sky if we've changed the ground */ chopCopyTerrain(&mGround, &mRoof, 0, - ( (iScreenY * 3) / 4)); ret = chopMenu(0); if (ret != -1) return PLUGIN_OK; while (!exit) { end = *rb->current_tick + CYCLETIME; if(chopUpdateTerrainRecycling(&mGround) == 1) /* mirror the sky if we've changed the ground */ chopCopyTerrain(&mGround, &mRoof, 0, - ( (iScreenY * 3) / 4)); iRotorOffset = iR(-1,1); /* We need to have this here so particles move when we're dead */ for (i=0; i < NUMBER_OF_PARTICLES; i++) if(mParticles[i].bIsActive == 1) { mParticles[i].iWorldX += mParticles[i].iSpeedX; mParticles[i].iWorldY += mParticles[i].iSpeedY; } /* Redraw the main window: */ chopDrawScene(); iGravityTimerCountdown--; if(iGravityTimerCountdown <= 0) { iGravityTimerCountdown = 3; chopAddParticle(iPlayerPosX, iPlayerPosY+5, 0, 0); } if(iCurrLevelMode == LEVEL_MODE_NORMAL) chopGenerateBlockIfNeeded(); if (showsplash) { chopDrawScene(); rb->splash(HZ, "Get Ready!"); showsplash = false; } move_button=rb->button_status(); if (rb->button_get(false) == QUIT) { ret = chopMenu(1); if (ret != -1) return PLUGIN_OK; showsplash = true; bdelay = 0; last_button = BUTTON_NONE; move_button = BUTTON_NONE; } switch (move_button) { case ACTION: #ifdef ACTION2 case ACTION2: #endif if (last_button != ACTION #ifdef ACTION2 && last_button != ACTION2 #endif ) bdelay = -2; if (bdelay == 0) iPlayerSpeedY = -3; break; default: if (last_button == ACTION #ifdef ACTION2 || last_button == ACTION2 #endif ) bdelay = 3; if (bdelay == 0) iPlayerSpeedY = 4; if (rb->default_event_handler(move_button) == SYS_USB_CONNECTED) return PLUGIN_USB_CONNECTED; break; } last_button = move_button; if (bdelay < 0) { iPlayerSpeedY = bdelay; bdelay++; } else if (bdelay > 0) { iPlayerSpeedY = bdelay; bdelay--; } iCameraPosX = iPlayerPosX - 25; iPlayerPosX += iPlayerSpeedX; iPlayerPosY += iPlayerSpeedY; chopCounter++; /* increase speed as we go along */ if (chopCounter == 100){ iPlayerSpeedX++; chopCounter=0; } if (iPlayerPosY > iScreenY-10 || iPlayerPosY < -5 || chopPointInTerrain(&mGround, iPlayerPosX, iPlayerPosY + 10, 0) || chopPointInTerrain(&mRoof, iPlayerPosX ,iPlayerPosY, 1)) { chopKillPlayer(); chopDrawScene(); ret = chopMenu(0); if (ret != -1) return ret; showsplash = true; } for (i=0; i < NUMBER_OF_BLOCKS; i++) if(mBlocks[i].bIsActive == 1) if(chopBlockCollideWithPlayer(&mBlocks[i])) { chopKillPlayer(); chopDrawScene(); ret = chopMenu(0); if (ret != -1) return ret; showsplash = true; } if (TIME_BEFORE(*rb->current_tick, end)) rb->sleep(end - *rb->current_tick); /* wait until time is over */ else rb->yield(); } return PLUGIN_OK; }
static void sd_thread(void) { struct queue_event ev; while (1) { queue_wait_w_tmo(&sd_queue, &ev, HZ); switch(ev.id) { case SYS_HOTSWAP_INSERTED: case SYS_HOTSWAP_EXTRACTED: { fat_lock(); /* lock-out FAT activity first - prevent deadlocking via disk_mount that would cause a reverse-order attempt with another thread */ mutex_lock(&sd_mutex); /* lock-out card activity - direct calls into driver that bypass the fat cache */ /* We now have exclusive control of fat cache and sd */ disk_unmount(sd_first_drive); /* release "by force", ensure file descriptors aren't leaked and any busy ones are invalid if mounting */ /* Force card init for new card, re-init for re-inserted one or * clear if the last attempt to init failed with an error. */ card_info.initialized = 0; if(ev.id == SYS_HOTSWAP_INSERTED) { int ret = sd_init_card(); if(ret == 0) { ret = disk_mount(sd_first_drive); /* 0 if fail */ if(ret < 0) DEBUGF("disk_mount failed: %d", ret); } else DEBUGF("sd_init_card failed: %d", ret); } /* * Mount succeeded, or this was an EXTRACTED event, * in both cases notify the system about the changed filesystems */ if(card_info.initialized) queue_broadcast(SYS_FS_CHANGED, 0); /* Access is now safe */ mutex_unlock(&sd_mutex); fat_unlock(); } break; case SYS_TIMEOUT: if(!TIME_BEFORE(current_tick, last_disk_activity+(3*HZ))) sd_enable(false); break; case SYS_USB_CONNECTED: usb_acknowledge(SYS_USB_CONNECTED_ACK); /* Wait until the USB cable is extracted again */ usb_wait_for_disconnect(&sd_queue); break; } } }
enum plugin_status plugin_start(const void* parameter) { int i; int f_width, f_height; int score_x; bool quit = false; int button; int cycletime = 300; int end; int pos_cur_brick = 0; int type_cur_brick = 0; int type_next_brick = 0; unsigned long int score = 34126; (void)parameter; #if LCD_DEPTH > 1 rb->lcd_set_backdrop(NULL); rb->lcd_set_background(LCD_BLACK); rb->lcd_set_foreground(LCD_WHITE); #endif rb->lcd_setfont(FONT_SYSFIXED); rb->lcd_getstringsize("100000000", &f_width, &f_height); rb->lcd_clear_display(); /*********** ** Draw EVERYTHING */ /* Playing filed box */ rb->lcd_vline(CENTER_X-2, CENTER_Y, CENTER_Y + (WIDTH*TILES+TILES)); rb->lcd_vline(CENTER_X + WIDTH + 1, CENTER_Y, CENTER_Y + (WIDTH*TILES+TILES)); rb->lcd_hline(CENTER_X-2, CENTER_X + WIDTH + 1, CENTER_Y + (WIDTH*TILES+TILES)); /* Score box */ #if (LCD_WIDTH > LCD_HEIGHT) rb->lcd_drawrect(SCORE_X-4, SCORE_Y-5, f_width+8, f_height+9); rb->lcd_putsxy(SCORE_X-4, SCORE_Y-6-f_height, "score"); #else rb->lcd_hline(0, LCD_WIDTH, SCORE_Y-5); rb->lcd_putsxy(2, SCORE_Y-6-f_height, "score"); #endif score_x = SCORE_X; /* Next box */ rb->lcd_getstringsize("next", &f_width, NULL); #if (LCD_WIDTH > LCD_HEIGHT) && !(LCD_WIDTH > 132) rb->lcd_drawrect(NEXT_X-5, NEXT_Y-5, WIDTH+10, NEXT_H+10); rb->lcd_putsxy(score_x-4, NEXT_Y-5, "next"); #else rb->lcd_drawrect(NEXT_X-5, NEXT_Y-5, WIDTH+10, NEXT_H+10); rb->lcd_putsxy(NEXT_X-5, NEXT_Y-5-f_height-1, "next"); #endif /*********** ** GAMELOOP */ rb->srand( *rb->current_tick ); type_cur_brick = 2 + mrand(3); type_next_brick = 2 + mrand(3); do { end = *rb->current_tick + (cycletime * HZ) / 1000; draw_brick(pos_cur_brick, type_cur_brick); /* Draw next brick */ rb->lcd_set_drawmode(DRMODE_BG|DRMODE_INVERSEVID); rb->lcd_fillrect(NEXT_X, NEXT_Y, WIDTH, WIDTH * 4 + 4); rb->lcd_set_drawmode(DRMODE_SOLID); for (i = 0; i < type_next_brick; ++i) { rb->lcd_fillrect(NEXT_X, NEXT_Y + ((type_next_brick % 2) ? (int)(WIDTH/2) : ((type_next_brick == 2) ? (WIDTH+1) : 0)) + (WIDTH*i) + i, WIDTH, WIDTH); } /* Score box */ rb->lcd_putsxyf(score_x, SCORE_Y, "%8ld0", score); rb->lcd_update(); button = rb->button_status(); switch(button) { case ONEDROCKBLOX_DOWN: case (ONEDROCKBLOX_DOWN|BUTTON_REPEAT): cycletime = 100; break; case ONEDROCKBLOX_QUIT: quit = true; break; default: cycletime = 300; if(rb->default_event_handler(button) == SYS_USB_CONNECTED) { quit = true; } } if ((pos_cur_brick + type_cur_brick) > 10) { type_cur_brick = type_next_brick; type_next_brick = 2 + mrand(3); score += (type_cur_brick - 1) * 2; pos_cur_brick = 1 - type_cur_brick; } else { ++pos_cur_brick; } if (TIME_BEFORE(*rb->current_tick, end)) rb->sleep(end-*rb->current_tick); else rb->yield(); } while (!quit); return PLUGIN_OK; }
static void power_thread(void) { long next_power_hist; /* Delay reading the first battery level */ #ifdef MROBE_100 while (battery_adc_voltage() > 4200) /* gives false readings initially */ #endif { sleep(HZ/100); } #if CONFIG_CHARGING /* Initialize power input status before calling other routines. */ power_thread_inputs = power_input_status(); #endif /* initialize the voltages for the exponential filter */ avgbat = battery_adc_voltage() + 15; #ifdef HAVE_DISK_STORAGE /* this adjustment is only needed for HD based */ /* The battery voltage is usually a little lower directly after turning on, because the disk was used heavily. Raise it by 5% */ #if CONFIG_CHARGING if (!charger_inserted()) /* only if charger not connected */ #endif { avgbat += (percent_to_volt_discharge[battery_type][6] - percent_to_volt_discharge[battery_type][5]) / 2; } #endif /* HAVE_DISK_STORAGE */ avgbat = avgbat * BATT_AVE_SAMPLES; battery_millivolts = avgbat / BATT_AVE_SAMPLES; power_history[0] = battery_millivolts; #if CONFIG_CHARGING if (charger_inserted()) { battery_percent = voltage_to_percent(battery_millivolts, percent_to_volt_charge); } else #endif { battery_percent = voltage_to_percent(battery_millivolts, percent_to_volt_discharge[battery_type]); battery_percent += battery_percent < 100; } powermgmt_init_target(); next_power_hist = current_tick + HZ*60; while (1) { #if CONFIG_CHARGING unsigned int pwr = power_input_status(); #ifdef HAVE_BATTERY_SWITCH if ((pwr ^ power_thread_inputs) & POWER_INPUT_BATTERY) { sleep(HZ/10); reset_battery_filter(battery_adc_voltage()); } #endif power_thread_inputs = pwr; if (!detect_charger(pwr)) #endif /* CONFIG_CHARGING */ { /* Steady state */ sleep(POWER_THREAD_STEP_TICKS); /* Do common power tasks */ power_thread_step(); } /* Perform target tasks */ charging_algorithm_step(); if (TIME_BEFORE(current_tick, next_power_hist)) continue; /* increment to ensure there is a record for every minute * rather than go forward from the current tick */ next_power_hist += HZ*60; /* rotate the power history */ memmove(&power_history[1], &power_history[0], sizeof(power_history) - sizeof(power_history[0])); /* insert new value at the start, in millivolts 8-) */ power_history[0] = battery_millivolts; handle_auto_poweroff(); } } /* power_thread */
/*----------------------------------------------------------------------------*/ VOID timerDoTimeOutCheck ( IN P_ADAPTER_T prAdapter ) { P_LINK_T prTimerList; P_LINK_ENTRY_T prLinkEntry; P_TIMER_T prTimer; OS_SYSTIME rCurSysTime; DEBUGFUNC("timerDoTimeOutCheck"); ASSERT(prAdapter); prTimerList= &prAdapter->rTimerList; GET_CURRENT_SYSTIME(&rCurSysTime); /* Set the permitted max timeout value for new one */ prAdapter->rNextExpiredSysTime = rCurSysTime + MGMT_MAX_TIMEOUT_INTERVAL; LINK_FOR_EACH(prLinkEntry, prTimerList) { prTimer = LINK_ENTRY(prLinkEntry, TIMER_T, rLinkEntry); /* Check if this entry is timeout. */ if (!TIME_BEFORE(rCurSysTime, prTimer->rExpiredSysTime)) { timerStopTimer(prAdapter, prTimer); #if CFG_USE_SW_ROOT_TIMER if (prTimer->fgNeedHwAccess) { ARB_ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); DBGLOG(INIT, INFO, ("Timer Handler: ->%s(): SYS_TIME = %ld\n", prTimer->aucDbgString, u4CurTime)); (prTimer->pfMgmtTimeOutFunc)(prTimer->u4Data); // It may add timer there. DBGLOG(INIT, INFO, ("Timer Handler: <-%s()\n", prTimer->aucDbgString)); ARB_RECLAIM_POWER_CONTROL_TO_PM(prAdapter); } else #endif { DBGLOG(INIT, INFO, ("(NO HW ACCESS)Timer Handler: ->%s(): SYS_TIME = %ld\n", prTimer->aucDbgString, rCurSysTime)); (prTimer->pfMgmtTimeOutFunc)(prTimer->u4Data); // It may add timer there. DBGLOG(INIT, INFO, ("(NO HW ACCESS)Timer Handler: <-%s()\n", prTimer->aucDbgString)); } /* Search entire list again because of nest del and add timers * and current MGMT_TIMER could be volatile after stopped */ prLinkEntry = (P_LINK_ENTRY_T)prTimerList; } else if (TIME_BEFORE(prTimer->rExpiredSysTime, prAdapter->rNextExpiredSysTime)) { prAdapter->rNextExpiredSysTime = prTimer->rExpiredSysTime; } } /* end of for loop */
static int keys(struct pong *p) { int key; #ifdef PONG_PAUSE static bool pause = false; #endif /* number of ticks this function will loop reading keys */ #ifndef HAVE_TOUCHSCREEN int time = 4; #else int time = 1; #endif int start = *rb->current_tick; int end = start + time; while(TIME_BEFORE(*rb->current_tick, end)) { key = rb->button_get_w_tmo(end - *rb->current_tick); #ifdef HAVE_TOUCHSCREEN short touch_x, touch_y; if(key & BUTTON_TOUCHSCREEN) { struct player *player; touch_x = rb->button_get_data() >> 16; touch_y = rb->button_get_data() & 0xFFFF; player = &p->player[0]; if(touch_x >= player->xpos && touch_x <= player->xpos+(PAD_WIDTH*4)) { padmove(&player->w_pad, touch_y-(player->e_pad*2+PAD_HEIGHT)/2); if (player->iscpu) { /* if left player presses control keys stop cpu player */ player->iscpu = false; p->player[0].score = p->player[1].score = 0; /* reset the score */ rb->lcd_clear_display(); /* get rid of the text */ } } player = &p->player[1]; if(touch_x >= player->xpos-(PAD_WIDTH*4) && touch_x <= player->xpos) { padmove(&player->w_pad, touch_y-(player->e_pad*2+PAD_HEIGHT)/2); if (player->iscpu) { /* if right player presses control keys stop cpu player */ player->iscpu = false; p->player[0].score = p->player[1].score = 0; /* reset the score */ rb->lcd_clear_display(); /* get rid of the text */ } } } #endif #ifdef HAS_BUTTON_HOLD if (rb->button_hold()) return 2; /* Pause game */ #endif if(key & PONG_QUIT #ifdef PONG_RC_QUIT || key & PONG_RC_QUIT #endif ) return 0; /* exit game NOW */ #ifdef PONG_PAUSE if(key == PONG_PAUSE) pause = !pause; if(pause) return 2; /* Pause game */ #endif key = rb->button_status(); /* ignore BUTTON_REPEAT */ key_pad(p, 0, (key & PONG_LEFT_UP), (key & PONG_LEFT_DOWN)); key_pad(p, 1, (key & PONG_RIGHT_UP), (key & PONG_RIGHT_DOWN)); if(rb->default_event_handler(key) == SYS_USB_CONNECTED) return -1; /* exit game because of USB */ } return 1; /* return 0 to exit game */ }
/* this is the plugin entry point */ enum plugin_status plugin_start(const void* parameter) { size_t plugin_buf_len; unsigned char * plugin_buf = (unsigned char *)rb->plugin_get_buffer(&plugin_buf_len); static char filename[MAX_PATH]; struct bitmap bm = { .width = LCD_WIDTH, .height = LCD_HEIGHT, }; int ret; if(!parameter) return PLUGIN_ERROR; rb->strcpy(filename, parameter); rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); rb->lcd_fillrect(0, 0, LCD_WIDTH, LCD_HEIGHT); rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_getstringsize("A", NULL, &font_h); int fd = rb->open(filename, O_RDONLY); if (fd < 0) { lcd_printf("file open failed: %d", fd); goto wait; } unsigned long filesize = rb->filesize(fd); if (filesize > plugin_buf_len) { lcd_printf("file too large"); goto wait; } plugin_buf_len -= filesize; unsigned char *jpeg_buf = plugin_buf; plugin_buf += filesize; rb->read(fd, jpeg_buf, filesize); rb->close(fd); bm.data = plugin_buf; struct dim jpeg_size; get_jpeg_dim_mem(jpeg_buf, filesize, &jpeg_size); lcd_printf("jpeg file size: %dx%d",jpeg_size.width, jpeg_size.height); bm.width = jpeg_size.width; bm.height = jpeg_size.height; char *size_str[] = { "1/1", "1/2", "1/4", "1/8" }; int i; for (i = 0; i < 4; i++) { lcd_printf("timing %s decode", size_str[i]); ret = decode_jpeg_mem(jpeg_buf, filesize, &bm, plugin_buf_len, FORMAT_NATIVE|FORMAT_RESIZE|FORMAT_KEEP_ASPECT, &format_null); if (ret == 1) { long t1, t2, t_end; int count = 0; t2 = *(rb->current_tick); while (t2 != (t1 = *(rb->current_tick))); t_end = t1 + 10 * HZ; do { decode_jpeg_mem(jpeg_buf, filesize, &bm, plugin_buf_len, FORMAT_NATIVE|FORMAT_RESIZE|FORMAT_KEEP_ASPECT, &format_null); count++; t2 = *(rb->current_tick); } while (TIME_BEFORE(t2, t_end) || count < 10); t2 -= t1; t2 *= 10; t2 += count >> 1; t2 /= count; t1 = t2 / 1000; t2 -= t1 * 1000; lcd_printf("%01d.%03d secs/decode", (int)t1, (int)t2); bm.width >>= 1; bm.height >>= 1; if (!(bm.width && bm.height)) break; } else
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 ( #if (CONFIG_PLATFORM & PLATFORM_NATIVE) !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) { #if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) if (lcd_active()) #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; } } }