diff options
Diffstat (limited to 'apps/plugins')
-rw-r--r-- | apps/plugins/puzzles/rockbox.c | 635 |
1 files changed, 358 insertions, 277 deletions
diff --git a/apps/plugins/puzzles/rockbox.c b/apps/plugins/puzzles/rockbox.c index b79070cba8..529c4ae5b4 100644 --- a/apps/plugins/puzzles/rockbox.c +++ b/apps/plugins/puzzles/rockbox.c | |||
@@ -82,9 +82,10 @@ static int help_times = 0; | |||
82 | #endif | 82 | #endif |
83 | 83 | ||
84 | static void fix_size(void); | 84 | static void fix_size(void); |
85 | static int pause_menu(void); | ||
85 | 86 | ||
86 | static struct viewport clip_rect; | 87 | static struct viewport clip_rect; |
87 | static bool clipped = false, zoom_enabled = false; | 88 | static bool clipped = false, zoom_enabled = false, view_mode = true; |
88 | 89 | ||
89 | extern bool audiobuf_available; | 90 | extern bool audiobuf_available; |
90 | 91 | ||
@@ -1269,33 +1270,47 @@ static void rb_status_bar(void *handle, const char *text) | |||
1269 | LOGF("game title is %s\n", text); | 1270 | LOGF("game title is %s\n", text); |
1270 | } | 1271 | } |
1271 | 1272 | ||
1273 | static int get_titleheight(void) | ||
1274 | { | ||
1275 | return rb->font_get(FONT_UI)->height; | ||
1276 | } | ||
1277 | |||
1272 | static void draw_title(void) | 1278 | static void draw_title(void) |
1273 | { | 1279 | { |
1274 | const char *str = NULL; | 1280 | const char *base; |
1275 | if(titlebar) | 1281 | if(titlebar) |
1276 | str = titlebar; | 1282 | base = titlebar; |
1277 | else | 1283 | else |
1278 | str = midend_which_game(me)->name; | 1284 | base = midend_which_game(me)->name; |
1285 | |||
1286 | char str[128]; | ||
1287 | rb->snprintf(str, sizeof(str), "%s%s", base, zoom_enabled ? (view_mode ? " (viewing)" : " (interaction)") : ""); | ||
1279 | 1288 | ||
1280 | /* quick hack */ | 1289 | /* quick hack */ |
1281 | bool orig_clipped = clipped; | 1290 | bool orig_clipped; |
1282 | if(orig_clipped) | 1291 | if(!zoom_enabled) |
1283 | rb_unclip(NULL); | 1292 | { |
1293 | orig_clipped = clipped; | ||
1294 | if(orig_clipped) | ||
1295 | rb_unclip(NULL); | ||
1296 | } | ||
1284 | 1297 | ||
1285 | int h; | 1298 | int w, h; |
1286 | cur_font = FONT_UI; | 1299 | cur_font = FONT_UI; |
1287 | rb->lcd_setfont(cur_font); | 1300 | rb->lcd_setfont(cur_font); |
1288 | rb->lcd_getstringsize(str, NULL, &h); | 1301 | rb->lcd_getstringsize(str, &w, &h); |
1289 | 1302 | ||
1290 | rb->lcd_set_foreground(BG_COLOR); | 1303 | rb->lcd_set_foreground(BG_COLOR); |
1291 | rb->lcd_fillrect(0, LCD_HEIGHT - h, LCD_WIDTH, h); | 1304 | rb->lcd_fillrect(0, LCD_HEIGHT - h, w, h); |
1292 | 1305 | ||
1293 | rb->lcd_set_foreground(LCD_BLACK); | 1306 | rb->lcd_set_foreground(LCD_BLACK); |
1294 | rb->lcd_putsxy(0, LCD_HEIGHT - h, str); | 1307 | rb->lcd_putsxy(0, LCD_HEIGHT - h, str); |
1295 | rb->lcd_update_rect(0, LCD_HEIGHT - h, LCD_WIDTH, h); | ||
1296 | 1308 | ||
1297 | if(orig_clipped) | 1309 | if(!zoom_enabled) |
1298 | rb_clip(NULL, clip_rect.x, clip_rect.y, clip_rect.width, clip_rect.height); | 1310 | { |
1311 | if(orig_clipped) | ||
1312 | rb_clip(NULL, clip_rect.x, clip_rect.y, clip_rect.width, clip_rect.height); | ||
1313 | } | ||
1299 | } | 1314 | } |
1300 | 1315 | ||
1301 | static char *rb_text_fallback(void *handle, const char *const *strings, | 1316 | static char *rb_text_fallback(void *handle, const char *const *strings, |
@@ -1326,6 +1341,236 @@ const drawing_api rb_drawing = { | |||
1326 | NULL, | 1341 | NULL, |
1327 | }; | 1342 | }; |
1328 | 1343 | ||
1344 | static bool want_redraw = true; | ||
1345 | static bool accept_input = true; | ||
1346 | |||
1347 | /* set do_pausemenu to false to just return -1 on BTN_PAUSE and do | ||
1348 | * nothing else. */ | ||
1349 | static int process_input(int tmo, bool do_pausemenu) | ||
1350 | { | ||
1351 | LOGF("process_input start"); | ||
1352 | LOGF("------------------"); | ||
1353 | int state = 0; | ||
1354 | |||
1355 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | ||
1356 | rb->cpu_boost(false); /* about to block for button input */ | ||
1357 | #endif | ||
1358 | |||
1359 | int button = rb->button_get_w_tmo(tmo); | ||
1360 | |||
1361 | /* weird stuff */ | ||
1362 | exit_on_usb(button); | ||
1363 | |||
1364 | /* these games require a second input on long-press */ | ||
1365 | if(accept_input && (button == (BTN_FIRE | BUTTON_REPEAT)) && | ||
1366 | (strcmp("Mines", midend_which_game(me)->name) != 0 || | ||
1367 | strcmp("Magnets", midend_which_game(me)->name) != 0)) | ||
1368 | { | ||
1369 | accept_input = false; | ||
1370 | return ' '; | ||
1371 | } | ||
1372 | |||
1373 | button = rb->button_status(); | ||
1374 | |||
1375 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | ||
1376 | rb->cpu_boost(true); | ||
1377 | #endif | ||
1378 | |||
1379 | if(button == BTN_PAUSE) | ||
1380 | { | ||
1381 | if(do_pausemenu) | ||
1382 | { | ||
1383 | want_redraw = false; | ||
1384 | /* quick hack to preserve the clipping state */ | ||
1385 | bool orig_clipped = clipped; | ||
1386 | if(orig_clipped) | ||
1387 | rb_unclip(NULL); | ||
1388 | |||
1389 | int rc = pause_menu(); | ||
1390 | |||
1391 | if(orig_clipped) | ||
1392 | rb_clip(NULL, clip_rect.x, clip_rect.y, clip_rect.width, clip_rect.height); | ||
1393 | |||
1394 | last_keystate = 0; | ||
1395 | accept_input = true; | ||
1396 | |||
1397 | return rc; | ||
1398 | } | ||
1399 | else | ||
1400 | return -1; | ||
1401 | } | ||
1402 | |||
1403 | /* these games require, for one reason or another, that events | ||
1404 | * fire upon buttons being released rather than when they are | ||
1405 | * pressed */ | ||
1406 | if(strcmp("Inertia", midend_which_game(me)->name) == 0 || | ||
1407 | strcmp("Mines", midend_which_game(me)->name) == 0 || | ||
1408 | strcmp("Magnets", midend_which_game(me)->name) == 0 || | ||
1409 | strcmp("Map", midend_which_game(me)->name) == 0) | ||
1410 | { | ||
1411 | LOGF("received button 0x%08x", button); | ||
1412 | |||
1413 | unsigned released = ~button & last_keystate; | ||
1414 | |||
1415 | last_keystate = button; | ||
1416 | |||
1417 | if(!button) | ||
1418 | { | ||
1419 | if(!accept_input) | ||
1420 | { | ||
1421 | LOGF("ignoring, all keys released but not accepting input before, can accept input later"); | ||
1422 | accept_input = true; | ||
1423 | return 0; | ||
1424 | } | ||
1425 | } | ||
1426 | |||
1427 | if(!released || !accept_input) | ||
1428 | { | ||
1429 | LOGF("released keys detected: 0x%08x", released); | ||
1430 | LOGF("ignoring, either no keys released or not accepting input"); | ||
1431 | return 0; | ||
1432 | } | ||
1433 | |||
1434 | if(button) | ||
1435 | { | ||
1436 | LOGF("ignoring input from now until all released"); | ||
1437 | accept_input = false; | ||
1438 | } | ||
1439 | |||
1440 | button |= released; | ||
1441 | LOGF("accepting event 0x%08x", button); | ||
1442 | } | ||
1443 | /* default is to ignore repeats except for untangle */ | ||
1444 | else if(strcmp("Untangle", midend_which_game(me)->name) != 0) | ||
1445 | { | ||
1446 | /* start accepting input again after a release */ | ||
1447 | if(!button) | ||
1448 | { | ||
1449 | accept_input = true; | ||
1450 | return 0; | ||
1451 | } | ||
1452 | /* ignore repeats */ | ||
1453 | /* Untangle gets special treatment */ | ||
1454 | if(!accept_input) | ||
1455 | return 0; | ||
1456 | accept_input = false; | ||
1457 | } | ||
1458 | |||
1459 | switch(button) | ||
1460 | { | ||
1461 | case BTN_UP: | ||
1462 | state = CURSOR_UP; | ||
1463 | break; | ||
1464 | case BTN_DOWN: | ||
1465 | state = CURSOR_DOWN; | ||
1466 | break; | ||
1467 | case BTN_LEFT: | ||
1468 | state = CURSOR_LEFT; | ||
1469 | break; | ||
1470 | case BTN_RIGHT: | ||
1471 | state = CURSOR_RIGHT; | ||
1472 | break; | ||
1473 | |||
1474 | /* handle diagonals (mainly for Inertia) */ | ||
1475 | case BTN_DOWN | BTN_LEFT: | ||
1476 | #ifdef BTN_DOWN_LEFT | ||
1477 | case BTN_DOWN_LEFT: | ||
1478 | #endif | ||
1479 | state = '1' | MOD_NUM_KEYPAD; | ||
1480 | break; | ||
1481 | case BTN_DOWN | BTN_RIGHT: | ||
1482 | #ifdef BTN_DOWN_RIGHT | ||
1483 | case BTN_DOWN_RIGHT: | ||
1484 | #endif | ||
1485 | state = '3' | MOD_NUM_KEYPAD; | ||
1486 | break; | ||
1487 | case BTN_UP | BTN_LEFT: | ||
1488 | #ifdef BTN_UP_LEFT | ||
1489 | case BTN_UP_LEFT: | ||
1490 | #endif | ||
1491 | state = '7' | MOD_NUM_KEYPAD; | ||
1492 | break; | ||
1493 | case BTN_UP | BTN_RIGHT: | ||
1494 | #ifdef BTN_UP_RIGHT | ||
1495 | case BTN_UP_RIGHT: | ||
1496 | #endif | ||
1497 | state = '9' | MOD_NUM_KEYPAD; | ||
1498 | break; | ||
1499 | |||
1500 | case BTN_FIRE: | ||
1501 | if(!strcmp("Fifteen", midend_which_game(me)->name)) | ||
1502 | state = 'h'; /* hint */ | ||
1503 | else | ||
1504 | state = CURSOR_SELECT; | ||
1505 | break; | ||
1506 | |||
1507 | default: | ||
1508 | break; | ||
1509 | } | ||
1510 | |||
1511 | if(settings.shortcuts) | ||
1512 | { | ||
1513 | static bool shortcuts_ok = true; | ||
1514 | switch(button) | ||
1515 | { | ||
1516 | case BTN_LEFT | BTN_FIRE: | ||
1517 | if(shortcuts_ok) | ||
1518 | midend_process_key(me, 0, 0, 'u'); | ||
1519 | shortcuts_ok = false; | ||
1520 | break; | ||
1521 | case BTN_RIGHT | BTN_FIRE: | ||
1522 | if(shortcuts_ok) | ||
1523 | midend_process_key(me, 0, 0, 'r'); | ||
1524 | shortcuts_ok = false; | ||
1525 | break; | ||
1526 | case 0: | ||
1527 | shortcuts_ok = true; | ||
1528 | break; | ||
1529 | default: | ||
1530 | break; | ||
1531 | } | ||
1532 | } | ||
1533 | |||
1534 | LOGF("process_input done"); | ||
1535 | LOGF("------------------"); | ||
1536 | return state; | ||
1537 | } | ||
1538 | |||
1539 | static long last_tstamp; | ||
1540 | |||
1541 | static void timer_cb(void) | ||
1542 | { | ||
1543 | #if LCD_DEPTH != 24 | ||
1544 | if(settings.timerflash) | ||
1545 | { | ||
1546 | static bool what = false; | ||
1547 | what = !what; | ||
1548 | if(what) | ||
1549 | rb->lcd_framebuffer[0] = LCD_BLACK; | ||
1550 | else | ||
1551 | rb->lcd_framebuffer[0] = LCD_WHITE; | ||
1552 | rb->lcd_update(); | ||
1553 | } | ||
1554 | #endif | ||
1555 | |||
1556 | LOGF("timer callback"); | ||
1557 | midend_timer(me, ((float)(*rb->current_tick - last_tstamp) / (float)HZ) / settings.slowmo_factor); | ||
1558 | last_tstamp = *rb->current_tick; | ||
1559 | } | ||
1560 | |||
1561 | static volatile bool timer_on = false; | ||
1562 | |||
1563 | void activate_timer(frontend *fe) | ||
1564 | { | ||
1565 | last_tstamp = *rb->current_tick; | ||
1566 | timer_on = true; | ||
1567 | } | ||
1568 | |||
1569 | void deactivate_timer(frontend *fe) | ||
1570 | { | ||
1571 | timer_on = false; | ||
1572 | } | ||
1573 | |||
1329 | /* render to a virtual framebuffer and let the user pan (but not make any moves) */ | 1574 | /* render to a virtual framebuffer and let the user pan (but not make any moves) */ |
1330 | static void zoom(void) | 1575 | static void zoom(void) |
1331 | { | 1576 | { |
@@ -1356,54 +1601,106 @@ static void zoom(void) | |||
1356 | 1601 | ||
1357 | zoom_enabled = true; | 1602 | zoom_enabled = true; |
1358 | 1603 | ||
1359 | /* draws go to the enlarged framebuffer */ | 1604 | /* draws go to the zoom framebuffer */ |
1360 | midend_force_redraw(me); | 1605 | midend_force_redraw(me); |
1361 | 1606 | ||
1362 | int x = 0, y = 0; | 1607 | int x = 0, y = 0; |
1363 | 1608 | ||
1364 | rb->lcd_bitmap_part(zoom_fb, x, y, STRIDE(SCREEN_MAIN, zoom_w, zoom_h), | 1609 | rb->lcd_bitmap_part(zoom_fb, x, y, STRIDE(SCREEN_MAIN, zoom_w, zoom_h), |
1365 | 0, 0, LCD_WIDTH, LCD_HEIGHT); | 1610 | 0, 0, LCD_WIDTH, LCD_HEIGHT); |
1611 | draw_title(); | ||
1366 | rb->lcd_update(); | 1612 | rb->lcd_update(); |
1367 | 1613 | ||
1614 | /* Here's how this works: pressing select (or the target's | ||
1615 | * equivalent, it's whatever BTN_FIRE is) while in viewing mode | ||
1616 | * will toggle the mode to interaction mode. In interaction mode, | ||
1617 | * the buttons will behave as normal and be sent to the puzzle, | ||
1618 | * except for the pause/quit (BTN_PAUSE) button, which will return | ||
1619 | * to view mode. Finally, when in view mode, pause/quit will | ||
1620 | * return to the pause menu. */ | ||
1621 | |||
1622 | view_mode = true; | ||
1623 | |||
1368 | /* pan around the image */ | 1624 | /* pan around the image */ |
1369 | while(1) | 1625 | while(1) |
1370 | { | 1626 | { |
1371 | int button = rb->button_get(true); | 1627 | if(view_mode) |
1372 | switch(button) | ||
1373 | { | 1628 | { |
1374 | case BTN_UP: | 1629 | int button = rb->button_get_w_tmo(timer_on ? TIMER_INTERVAL : -1); |
1375 | y -= PAN_Y; /* clamped later */ | 1630 | switch(button) |
1376 | break; | 1631 | { |
1377 | case BTN_DOWN: | 1632 | case BTN_UP: |
1378 | y += PAN_Y; /* clamped later */ | 1633 | y -= PAN_Y; /* clamped later */ |
1379 | break; | 1634 | break; |
1380 | case BTN_LEFT: | 1635 | case BTN_DOWN: |
1381 | x -= PAN_X; /* clamped later */ | 1636 | y += PAN_Y; /* clamped later */ |
1382 | break; | 1637 | break; |
1383 | case BTN_RIGHT: | 1638 | case BTN_LEFT: |
1384 | x += PAN_X; /* clamped later */ | 1639 | x -= PAN_X; /* clamped later */ |
1385 | break; | 1640 | break; |
1386 | case BTN_PAUSE: | 1641 | case BTN_RIGHT: |
1387 | zoom_enabled = false; | 1642 | x += PAN_X; /* clamped later */ |
1388 | sfree(zoom_fb); | 1643 | break; |
1389 | fix_size(); | 1644 | case BTN_PAUSE: |
1390 | return; | 1645 | zoom_enabled = false; |
1391 | default: | 1646 | sfree(zoom_fb); |
1392 | break; | 1647 | fix_size(); |
1648 | return; | ||
1649 | case BTN_FIRE: | ||
1650 | view_mode = false; | ||
1651 | continue; | ||
1652 | default: | ||
1653 | break; | ||
1654 | } | ||
1655 | |||
1656 | if(y < 0) | ||
1657 | y = 0; | ||
1658 | if(x < 0) | ||
1659 | x = 0; | ||
1660 | |||
1661 | if(y + LCD_HEIGHT >= zoom_h) | ||
1662 | y = zoom_h - LCD_HEIGHT; | ||
1663 | if(x + LCD_WIDTH >= zoom_w) | ||
1664 | x = zoom_w - LCD_WIDTH; | ||
1665 | |||
1666 | if(timer_on) | ||
1667 | timer_cb(); | ||
1668 | |||
1669 | /* goes to zoom_fb */ | ||
1670 | midend_redraw(me); | ||
1671 | |||
1672 | rb->lcd_bitmap_part(zoom_fb, x, y, STRIDE(SCREEN_MAIN, zoom_w, zoom_h), | ||
1673 | 0, 0, LCD_WIDTH, LCD_HEIGHT); | ||
1674 | draw_title(); | ||
1675 | rb->lcd_update(); | ||
1676 | rb->yield(); | ||
1393 | } | 1677 | } |
1678 | else | ||
1679 | { | ||
1680 | /* basically a copy-pasta'd main loop */ | ||
1681 | int button = process_input(timer_on ? TIMER_INTERVAL : -1, false); | ||
1394 | 1682 | ||
1395 | if(y < 0) | 1683 | if(button < 0) |
1396 | y = 0; | 1684 | { |
1397 | if(x < 0) | 1685 | view_mode = true; |
1398 | x = 0; | 1686 | continue; |
1399 | if(y + LCD_HEIGHT >= zoom_h) | 1687 | } |
1400 | y = zoom_h - LCD_HEIGHT; | ||
1401 | if(x + LCD_WIDTH >= zoom_w) | ||
1402 | x = zoom_w - LCD_WIDTH; | ||
1403 | 1688 | ||
1404 | rb->lcd_bitmap_part(zoom_fb, x, y, STRIDE(SCREEN_MAIN, zoom_w, zoom_h), | 1689 | if(button) |
1405 | 0, 0, LCD_WIDTH, LCD_HEIGHT); | 1690 | midend_process_key(me, 0, 0, button); |
1406 | rb->lcd_update(); | 1691 | |
1692 | if(timer_on) | ||
1693 | timer_cb(); | ||
1694 | |||
1695 | if(want_redraw) | ||
1696 | midend_redraw(me); | ||
1697 | |||
1698 | rb->lcd_bitmap_part(zoom_fb, x, y, STRIDE(SCREEN_MAIN, zoom_w, zoom_h), | ||
1699 | 0, 0, LCD_WIDTH, LCD_HEIGHT); | ||
1700 | draw_title(); | ||
1701 | rb->lcd_update(); | ||
1702 | rb->yield(); | ||
1703 | } | ||
1407 | } | 1704 | } |
1408 | } | 1705 | } |
1409 | 1706 | ||
@@ -2163,229 +2460,6 @@ static int pause_menu(void) | |||
2163 | return 0; | 2460 | return 0; |
2164 | } | 2461 | } |
2165 | 2462 | ||
2166 | static bool want_redraw = true; | ||
2167 | static bool accept_input = true; | ||
2168 | |||
2169 | static int process_input(int tmo) | ||
2170 | { | ||
2171 | LOGF("process_input start"); | ||
2172 | LOGF("------------------"); | ||
2173 | int state = 0; | ||
2174 | |||
2175 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | ||
2176 | rb->cpu_boost(false); /* about to block for button input */ | ||
2177 | #endif | ||
2178 | |||
2179 | int button = rb->button_get_w_tmo(tmo); | ||
2180 | |||
2181 | /* weird stuff */ | ||
2182 | exit_on_usb(button); | ||
2183 | |||
2184 | /* these games require a second input on long-press */ | ||
2185 | if(accept_input && (button == (BTN_FIRE | BUTTON_REPEAT)) && | ||
2186 | (strcmp("Mines", midend_which_game(me)->name) != 0 || | ||
2187 | strcmp("Magnets", midend_which_game(me)->name) != 0)) | ||
2188 | { | ||
2189 | accept_input = false; | ||
2190 | return ' '; | ||
2191 | } | ||
2192 | |||
2193 | button = rb->button_status(); | ||
2194 | |||
2195 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | ||
2196 | rb->cpu_boost(true); | ||
2197 | #endif | ||
2198 | |||
2199 | if(button == BTN_PAUSE) | ||
2200 | { | ||
2201 | want_redraw = false; | ||
2202 | /* quick hack to preserve the clipping state */ | ||
2203 | bool orig_clipped = clipped; | ||
2204 | if(orig_clipped) | ||
2205 | rb_unclip(NULL); | ||
2206 | |||
2207 | int rc = pause_menu(); | ||
2208 | |||
2209 | if(orig_clipped) | ||
2210 | rb_clip(NULL, clip_rect.x, clip_rect.y, clip_rect.width, clip_rect.height); | ||
2211 | |||
2212 | last_keystate = 0; | ||
2213 | accept_input = true; | ||
2214 | |||
2215 | return rc; | ||
2216 | } | ||
2217 | |||
2218 | /* these games require, for one reason or another, that events | ||
2219 | * fire upon buttons being released rather than when they are | ||
2220 | * pressed */ | ||
2221 | if(strcmp("Inertia", midend_which_game(me)->name) == 0 || | ||
2222 | strcmp("Mines", midend_which_game(me)->name) == 0 || | ||
2223 | strcmp("Magnets", midend_which_game(me)->name) == 0 || | ||
2224 | strcmp("Map", midend_which_game(me)->name) == 0) | ||
2225 | { | ||
2226 | LOGF("received button 0x%08x", button); | ||
2227 | |||
2228 | unsigned released = ~button & last_keystate; | ||
2229 | |||
2230 | last_keystate = button; | ||
2231 | |||
2232 | if(!button) | ||
2233 | { | ||
2234 | if(!accept_input) | ||
2235 | { | ||
2236 | LOGF("ignoring, all keys released but not accepting input before, can accept input later"); | ||
2237 | accept_input = true; | ||
2238 | return 0; | ||
2239 | } | ||
2240 | } | ||
2241 | |||
2242 | if(!released || !accept_input) | ||
2243 | { | ||
2244 | LOGF("released keys detected: 0x%08x", released); | ||
2245 | LOGF("ignoring, either no keys released or not accepting input"); | ||
2246 | return 0; | ||
2247 | } | ||
2248 | |||
2249 | if(button) | ||
2250 | { | ||
2251 | LOGF("ignoring input from now until all released"); | ||
2252 | accept_input = false; | ||
2253 | } | ||
2254 | |||
2255 | button |= released; | ||
2256 | LOGF("accepting event 0x%08x", button); | ||
2257 | } | ||
2258 | /* default is to ignore repeats except for untangle */ | ||
2259 | else if(strcmp("Untangle", midend_which_game(me)->name) != 0) | ||
2260 | { | ||
2261 | /* start accepting input again after a release */ | ||
2262 | if(!button) | ||
2263 | { | ||
2264 | accept_input = true; | ||
2265 | return 0; | ||
2266 | } | ||
2267 | /* ignore repeats */ | ||
2268 | /* Untangle gets special treatment */ | ||
2269 | if(!accept_input) | ||
2270 | return 0; | ||
2271 | accept_input = false; | ||
2272 | } | ||
2273 | |||
2274 | switch(button) | ||
2275 | { | ||
2276 | case BTN_UP: | ||
2277 | state = CURSOR_UP; | ||
2278 | break; | ||
2279 | case BTN_DOWN: | ||
2280 | state = CURSOR_DOWN; | ||
2281 | break; | ||
2282 | case BTN_LEFT: | ||
2283 | state = CURSOR_LEFT; | ||
2284 | break; | ||
2285 | case BTN_RIGHT: | ||
2286 | state = CURSOR_RIGHT; | ||
2287 | break; | ||
2288 | |||
2289 | /* handle diagonals (mainly for Inertia) */ | ||
2290 | case BTN_DOWN | BTN_LEFT: | ||
2291 | #ifdef BTN_DOWN_LEFT | ||
2292 | case BTN_DOWN_LEFT: | ||
2293 | #endif | ||
2294 | state = '1' | MOD_NUM_KEYPAD; | ||
2295 | break; | ||
2296 | case BTN_DOWN | BTN_RIGHT: | ||
2297 | #ifdef BTN_DOWN_RIGHT | ||
2298 | case BTN_DOWN_RIGHT: | ||
2299 | #endif | ||
2300 | state = '3' | MOD_NUM_KEYPAD; | ||
2301 | break; | ||
2302 | case BTN_UP | BTN_LEFT: | ||
2303 | #ifdef BTN_UP_LEFT | ||
2304 | case BTN_UP_LEFT: | ||
2305 | #endif | ||
2306 | state = '7' | MOD_NUM_KEYPAD; | ||
2307 | break; | ||
2308 | case BTN_UP | BTN_RIGHT: | ||
2309 | #ifdef BTN_UP_RIGHT | ||
2310 | case BTN_UP_RIGHT: | ||
2311 | #endif | ||
2312 | state = '9' | MOD_NUM_KEYPAD; | ||
2313 | break; | ||
2314 | |||
2315 | case BTN_FIRE: | ||
2316 | if(!strcmp("Fifteen", midend_which_game(me)->name)) | ||
2317 | state = 'h'; /* hint */ | ||
2318 | else | ||
2319 | state = CURSOR_SELECT; | ||
2320 | break; | ||
2321 | |||
2322 | default: | ||
2323 | break; | ||
2324 | } | ||
2325 | |||
2326 | if(settings.shortcuts) | ||
2327 | { | ||
2328 | static bool shortcuts_ok = true; | ||
2329 | switch(button) | ||
2330 | { | ||
2331 | case BTN_LEFT | BTN_FIRE: | ||
2332 | if(shortcuts_ok) | ||
2333 | midend_process_key(me, 0, 0, 'u'); | ||
2334 | shortcuts_ok = false; | ||
2335 | break; | ||
2336 | case BTN_RIGHT | BTN_FIRE: | ||
2337 | if(shortcuts_ok) | ||
2338 | midend_process_key(me, 0, 0, 'r'); | ||
2339 | shortcuts_ok = false; | ||
2340 | break; | ||
2341 | case 0: | ||
2342 | shortcuts_ok = true; | ||
2343 | break; | ||
2344 | default: | ||
2345 | break; | ||
2346 | } | ||
2347 | } | ||
2348 | |||
2349 | LOGF("process_input done"); | ||
2350 | LOGF("------------------"); | ||
2351 | return state; | ||
2352 | } | ||
2353 | |||
2354 | static long last_tstamp; | ||
2355 | |||
2356 | static void timer_cb(void) | ||
2357 | { | ||
2358 | #if LCD_DEPTH != 24 | ||
2359 | if(settings.timerflash) | ||
2360 | { | ||
2361 | static bool what = false; | ||
2362 | what = !what; | ||
2363 | if(what) | ||
2364 | rb->lcd_framebuffer[0] = LCD_BLACK; | ||
2365 | else | ||
2366 | rb->lcd_framebuffer[0] = LCD_WHITE; | ||
2367 | rb->lcd_update(); | ||
2368 | } | ||
2369 | #endif | ||
2370 | |||
2371 | LOGF("timer callback"); | ||
2372 | midend_timer(me, ((float)(*rb->current_tick - last_tstamp) / (float)HZ) / settings.slowmo_factor); | ||
2373 | last_tstamp = *rb->current_tick; | ||
2374 | } | ||
2375 | |||
2376 | static volatile bool timer_on = false; | ||
2377 | |||
2378 | void activate_timer(frontend *fe) | ||
2379 | { | ||
2380 | last_tstamp = *rb->current_tick; | ||
2381 | timer_on = true; | ||
2382 | } | ||
2383 | |||
2384 | void deactivate_timer(frontend *fe) | ||
2385 | { | ||
2386 | timer_on = false; | ||
2387 | } | ||
2388 | |||
2389 | /* points to pluginbuf */ | 2463 | /* points to pluginbuf */ |
2390 | char *giant_buffer = NULL; | 2464 | char *giant_buffer = NULL; |
2391 | static size_t giant_buffer_len = 0; /* set on start */ | 2465 | static size_t giant_buffer_len = 0; /* set on start */ |
@@ -2795,6 +2869,7 @@ enum plugin_status plugin_start(const void *param) | |||
2795 | 2869 | ||
2796 | bool quit = false; | 2870 | bool quit = false; |
2797 | int sel = 0; | 2871 | int sel = 0; |
2872 | |||
2798 | while(!quit) | 2873 | while(!quit) |
2799 | { | 2874 | { |
2800 | switch(rb->do_menu(&menu, &sel, NULL, false)) | 2875 | switch(rb->do_menu(&menu, &sel, NULL, false)) |
@@ -2866,9 +2941,11 @@ enum plugin_status plugin_start(const void *param) | |||
2866 | { | 2941 | { |
2867 | want_redraw = true; | 2942 | want_redraw = true; |
2868 | 2943 | ||
2944 | int theight = get_titleheight(); | ||
2869 | draw_title(); | 2945 | draw_title(); |
2946 | rb->lcd_update_rect(0, LCD_HEIGHT - theight, LCD_WIDTH, theight); | ||
2870 | 2947 | ||
2871 | int button = process_input(timer_on ? TIMER_INTERVAL : -1); | 2948 | int button = process_input(timer_on ? TIMER_INTERVAL : -1, true); |
2872 | 2949 | ||
2873 | if(button < 0) | 2950 | if(button < 0) |
2874 | { | 2951 | { |
@@ -2881,35 +2958,39 @@ enum plugin_status plugin_start(const void *param) | |||
2881 | titlebar = NULL; | 2958 | titlebar = NULL; |
2882 | } | 2959 | } |
2883 | 2960 | ||
2884 | if(button == -1) | 2961 | switch(button) |
2885 | { | 2962 | { |
2963 | case -1: | ||
2886 | /* new game */ | 2964 | /* new game */ |
2887 | midend_free(me); | 2965 | midend_free(me); |
2888 | break; | 2966 | break; |
2889 | } | 2967 | case -2: |
2890 | else if(button == -2) | ||
2891 | { | ||
2892 | /* quit without saving */ | 2968 | /* quit without saving */ |
2893 | midend_free(me); | 2969 | midend_free(me); |
2894 | sfree(colors); | 2970 | sfree(colors); |
2895 | exit(PLUGIN_OK); | 2971 | exit(PLUGIN_OK); |
2896 | } | 2972 | case -3: |
2897 | else if(button == -3) | ||
2898 | { | ||
2899 | /* save and quit */ | 2973 | /* save and quit */ |
2900 | save_game(); | 2974 | save_game(); |
2901 | midend_free(me); | 2975 | midend_free(me); |
2902 | sfree(colors); | 2976 | sfree(colors); |
2903 | exit(PLUGIN_OK); | 2977 | exit(PLUGIN_OK); |
2978 | default: | ||
2979 | break; | ||
2904 | } | 2980 | } |
2905 | } | 2981 | } |
2906 | 2982 | ||
2907 | if(button) | 2983 | if(button) |
2908 | midend_process_key(me, 0, 0, button); | 2984 | midend_process_key(me, 0, 0, button); |
2909 | 2985 | ||
2986 | draw_title(); /* will draw to fb */ | ||
2987 | |||
2910 | if(want_redraw) | 2988 | if(want_redraw) |
2911 | midend_redraw(me); | 2989 | midend_redraw(me); |
2912 | 2990 | ||
2991 | /* push title to screen as well */ | ||
2992 | rb->lcd_update_rect(0, LCD_HEIGHT - theight, LCD_WIDTH, theight); | ||
2993 | |||
2913 | if(timer_on) | 2994 | if(timer_on) |
2914 | timer_cb(); | 2995 | timer_cb(); |
2915 | 2996 | ||