diff options
-rw-r--r-- | apps/Makefile | 8 | ||||
-rw-r--r-- | apps/demo_menu.c | 37 | ||||
-rw-r--r-- | apps/games_menu.c | 29 | ||||
-rw-r--r-- | apps/lang/english.lang | 76 | ||||
-rw-r--r-- | apps/player/icons.h | 3 | ||||
-rw-r--r-- | apps/plugin.c | 221 | ||||
-rw-r--r-- | apps/plugin.h | 161 | ||||
-rw-r--r-- | apps/plugins/Makefile | 45 | ||||
-rw-r--r-- | apps/plugins/bounce.c (renamed from apps/recorder/bounce.c) | 96 | ||||
-rw-r--r-- | apps/plugins/cube.c (renamed from apps/recorder/cube.c) | 63 | ||||
-rw-r--r-- | apps/plugins/helloworld.c | 48 | ||||
-rw-r--r-- | apps/plugins/oscillograph.c (renamed from apps/recorder/oscillograph.c) | 82 | ||||
-rw-r--r-- | apps/plugins/plugin.lds | 26 | ||||
-rw-r--r-- | apps/plugins/snow.c (renamed from apps/recorder/snow.c) | 46 | ||||
-rw-r--r-- | apps/plugins/sokoban.c | 868 | ||||
-rw-r--r-- | apps/plugins/viewer.c (renamed from apps/viewer.c) | 71 | ||||
-rw-r--r-- | apps/plugins/wormlet.c (renamed from apps/recorder/wormlet.c) | 427 | ||||
-rw-r--r-- | apps/recorder/icons.c | 1 | ||||
-rw-r--r-- | apps/recorder/icons.h | 1 | ||||
-rw-r--r-- | apps/recorder/sokoban.c | 891 | ||||
-rw-r--r-- | apps/recorder/sokoban.h | 28 | ||||
-rw-r--r-- | apps/recorder/tetris.c | 438 | ||||
-rw-r--r-- | apps/recorder/wormlet.h | 28 | ||||
-rw-r--r-- | apps/screens.c | 1 | ||||
-rw-r--r-- | apps/tree.c | 19 | ||||
-rw-r--r-- | apps/tree.h | 1 | ||||
-rw-r--r-- | apps/viewer.h | 24 | ||||
-rw-r--r-- | firmware/app.lds | 15 | ||||
-rw-r--r-- | firmware/drivers/lcd-player-charset.c | 4 |
29 files changed, 1869 insertions, 1889 deletions
diff --git a/apps/Makefile b/apps/Makefile index 3e5fbdc2dd..9614050cda 100644 --- a/apps/Makefile +++ b/apps/Makefile | |||
@@ -20,7 +20,7 @@ DOCSDIR := ../docs | |||
20 | 20 | ||
21 | INCLUDES= -I$(FIRMWARE)/include -I$(FIRMWARE)/export -I. -I$(OBJDIR) | 21 | INCLUDES= -I$(FIRMWARE)/include -I$(FIRMWARE)/export -I. -I$(OBJDIR) |
22 | 22 | ||
23 | CFLAGS = -O -W -Wall -m1 -nostdlib -ffreestanding -Wstrict-prototypes -fomit-frame-pointer -fschedule-insns $(INCLUDES) $(TARGET) $(DEFINES) -DAPPSVERSION=\"$(VERSION)\" $(EXTRA_DEFINES) -DMEM=${MEM} | 23 | CFLAGS = -O -W -Wall -m1 -nostdlib -ffreestanding -Wstrict-prototypes -fomit-frame-pointer -fschedule-insns $(INCLUDES) $(TARGET) $(DEFINES) -DAPPSVERSION=\"$(VERSION)\" $(EXTRA_DEFINES) -DMEM=${MEM} -DPLUGIN=1 |
24 | AFLAGS += -small -relax | 24 | AFLAGS += -small -relax |
25 | 25 | ||
26 | # Check if this is a kind of Recorder | 26 | # Check if this is a kind of Recorder |
@@ -71,7 +71,10 @@ ifndef TOOLSDIR | |||
71 | TOOLSDIR=../tools | 71 | TOOLSDIR=../tools |
72 | endif | 72 | endif |
73 | 73 | ||
74 | all : $(OBJDIR)/$(OUTNAME) | 74 | all : $(OBJDIR)/$(OUTNAME) rocks |
75 | |||
76 | rocks: | ||
77 | $(MAKE) -C plugins TARGET=$(TARGET) DEBUG=$(DEBUG) OBJDIR=$(OBJDIR) VERSION=$(VERSION) EXTRA_DEFINES="$(EXTRA_DEFINES)" | ||
75 | 78 | ||
76 | $(OBJDIR)/librockbox.a: | 79 | $(OBJDIR)/librockbox.a: |
77 | make -C $(FIRMWARE) TARGET=$(TARGET) DEBUG=$(DEBUG) OBJDIR=$(OBJDIR) | 80 | make -C $(FIRMWARE) TARGET=$(TARGET) DEBUG=$(DEBUG) OBJDIR=$(OBJDIR) |
@@ -117,6 +120,7 @@ clean: | |||
117 | $(OBJDIR)/lang.o $(OBJDIR)/build.lang $(OBJDIR)/lang.[ch] \ | 120 | $(OBJDIR)/lang.o $(OBJDIR)/build.lang $(OBJDIR)/lang.[ch] \ |
118 | $(OBJDIR)/credits.raw $(LINKFILE) | 121 | $(OBJDIR)/credits.raw $(LINKFILE) |
119 | -$(RM) -r $(OBJDIR)/$(DEPS) | 122 | -$(RM) -r $(OBJDIR)/$(DEPS) |
123 | $(MAKE) -C plugins clean | ||
120 | 124 | ||
121 | DEPS:=.deps | 125 | DEPS:=.deps |
122 | DEPDIRS:=$(DEPS) | 126 | DEPDIRS:=$(DEPS) |
diff --git a/apps/demo_menu.c b/apps/demo_menu.c index f6934e49be..be8e44522c 100644 --- a/apps/demo_menu.c +++ b/apps/demo_menu.c | |||
@@ -24,19 +24,38 @@ | |||
24 | 24 | ||
25 | #include <stdio.h> | 25 | #include <stdio.h> |
26 | #include <stdbool.h> | 26 | #include <stdbool.h> |
27 | #include "lcd.h" | ||
28 | #include "menu.h" | 27 | #include "menu.h" |
29 | #include "demo_menu.h" | 28 | #include "demo_menu.h" |
30 | #include "button.h" | ||
31 | #include "kernel.h" | ||
32 | #include "sprintf.h" | ||
33 | |||
34 | #include "lang.h" | 29 | #include "lang.h" |
30 | #include "plugin.h" | ||
31 | |||
32 | static bool bounce(void) | ||
33 | { | ||
34 | if (plugin_load("/.rockbox/rocks/bounce.rock",NULL)==PLUGIN_USB_CONNECTED) | ||
35 | return true; | ||
36 | return false; | ||
37 | } | ||
38 | |||
39 | static bool snow(void) | ||
40 | { | ||
41 | if (plugin_load("/.rockbox/rocks/snow.rock",NULL) == PLUGIN_USB_CONNECTED) | ||
42 | return true; | ||
43 | return false; | ||
44 | } | ||
45 | |||
46 | static bool cube(void) | ||
47 | { | ||
48 | if (plugin_load("/.rockbox/rocks/cube.rock",NULL) == PLUGIN_USB_CONNECTED) | ||
49 | return true; | ||
50 | return false; | ||
51 | } | ||
35 | 52 | ||
36 | extern bool bounce(void); | 53 | static bool oscillograph(void) |
37 | extern bool snow(void); | 54 | { |
38 | extern bool cube(void); | 55 | if (plugin_load("/.rockbox/rocks/oscillograph.rock",NULL)==PLUGIN_USB_CONNECTED) |
39 | extern bool oscillograph(void); | 56 | return true; |
57 | return false; | ||
58 | } | ||
40 | 59 | ||
41 | bool demo_menu(void) | 60 | bool demo_menu(void) |
42 | { | 61 | { |
diff --git a/apps/games_menu.c b/apps/games_menu.c index 0c37203f4e..780c4b7415 100644 --- a/apps/games_menu.c +++ b/apps/games_menu.c | |||
@@ -25,18 +25,31 @@ | |||
25 | 25 | ||
26 | #include <stdio.h> | 26 | #include <stdio.h> |
27 | #include <stdbool.h> | 27 | #include <stdbool.h> |
28 | #include "lcd.h" | ||
29 | #include "menu.h" | 28 | #include "menu.h" |
30 | #include "games_menu.h" | 29 | #include "games_menu.h" |
31 | #include "button.h" | ||
32 | #include "kernel.h" | ||
33 | #include "sprintf.h" | ||
34 | |||
35 | #include "sokoban.h" | ||
36 | #include "wormlet.h" | ||
37 | #include "lang.h" | 30 | #include "lang.h" |
31 | #include "plugin.h" | ||
38 | 32 | ||
39 | extern bool tetris(void); | 33 | static bool tetris(void) |
34 | { | ||
35 | if (plugin_load("/.rockbox/rocks/tetris.rock",NULL)==PLUGIN_USB_CONNECTED) | ||
36 | return true; | ||
37 | return false; | ||
38 | } | ||
39 | |||
40 | static bool sokoban(void) | ||
41 | { | ||
42 | if (plugin_load("/.rockbox/rocks/sokoban.rock",NULL)==PLUGIN_USB_CONNECTED) | ||
43 | return true; | ||
44 | return false; | ||
45 | } | ||
46 | |||
47 | static bool wormlet(void) | ||
48 | { | ||
49 | if (plugin_load("/.rockbox/rocks/wormlet.rock",NULL)==PLUGIN_USB_CONNECTED) | ||
50 | return true; | ||
51 | return false; | ||
52 | } | ||
40 | 53 | ||
41 | bool games_menu(void) | 54 | bool games_menu(void) |
42 | { | 55 | { |
diff --git a/apps/lang/english.lang b/apps/lang/english.lang index 12249ee048..1d7b3088a6 100644 --- a/apps/lang/english.lang +++ b/apps/lang/english.lang | |||
@@ -677,37 +677,37 @@ new: | |||
677 | 677 | ||
678 | id: LANG_SOKOBAN_LEVEL | 678 | id: LANG_SOKOBAN_LEVEL |
679 | desc: must be smaller than 6 characters | 679 | desc: must be smaller than 6 characters |
680 | eng: "Level" | 680 | eng: "" |
681 | new: | 681 | new: |
682 | 682 | ||
683 | id: LANG_SOKOBAN_MOVE | 683 | id: LANG_SOKOBAN_MOVE |
684 | desc: must be smaller than 6 characters | 684 | desc: must be smaller than 6 characters |
685 | eng: "Moves" | 685 | eng: "" |
686 | new: | 686 | new: |
687 | 687 | ||
688 | id: LANG_SOKOBAN_WIN | 688 | id: LANG_SOKOBAN_WIN |
689 | desc: displayed when you win | 689 | desc: displayed when you win |
690 | eng: "YOU WIN!!" | 690 | eng: "" |
691 | new: | 691 | new: |
692 | 692 | ||
693 | id: LANG_SOKOBAN_QUIT | 693 | id: LANG_SOKOBAN_QUIT |
694 | desc: how to quit game | 694 | desc: how to quit game |
695 | eng: "[OFF] To Stop" | 695 | eng: "" |
696 | new: | 696 | new: |
697 | 697 | ||
698 | id: LANG_SOKOBAN_F1 | 698 | id: LANG_SOKOBAN_F1 |
699 | desc: what does F1 do | 699 | desc: what does F1 do |
700 | eng: "[F1] - Level" | 700 | eng: "" |
701 | new: | 701 | new: |
702 | 702 | ||
703 | id: LANG_SOKOBAN_F2 | 703 | id: LANG_SOKOBAN_F2 |
704 | desc: what does F2 do | 704 | desc: what does F2 do |
705 | eng: "[F2] Same Level" | 705 | eng: "" |
706 | new: | 706 | new: |
707 | 707 | ||
708 | id: LANG_SOKOBAN_F3 | 708 | id: LANG_SOKOBAN_F3 |
709 | desc: what does F3 do | 709 | desc: what does F3 do |
710 | eng: "[F3] + Level" | 710 | eng: "" |
711 | new: | 711 | new: |
712 | 712 | ||
713 | # Next ids are for Worlmet Game. | 713 | # Next ids are for Worlmet Game. |
@@ -717,37 +717,37 @@ new: | |||
717 | 717 | ||
718 | id: LANG_WORMLET_LENGTH | 718 | id: LANG_WORMLET_LENGTH |
719 | desc: wormlet game | 719 | desc: wormlet game |
720 | eng: "Len:%d" | 720 | eng: "" |
721 | new: | 721 | new: |
722 | 722 | ||
723 | id: LANG_WORMLET_GROWING | 723 | id: LANG_WORMLET_GROWING |
724 | desc: wormlet game | 724 | desc: wormlet game |
725 | eng: "Growing" | 725 | eng: "" |
726 | new: | 726 | new: |
727 | 727 | ||
728 | id: LANG_WORMLET_HUNGRY | 728 | id: LANG_WORMLET_HUNGRY |
729 | desc: wormlet game | 729 | desc: wormlet game |
730 | eng: "Hungry" | 730 | eng: "" |
731 | new: | 731 | new: |
732 | 732 | ||
733 | id: LANG_WORMLET_WORMED | 733 | id: LANG_WORMLET_WORMED |
734 | desc: wormlet game | 734 | desc: wormlet game |
735 | eng: "Wormed" | 735 | eng: "" |
736 | new: | 736 | new: |
737 | 737 | ||
738 | id: LANG_WORMLET_ARGH | 738 | id: LANG_WORMLET_ARGH |
739 | desc: wormlet game | 739 | desc: wormlet game |
740 | eng: "Argh" | 740 | eng: "" |
741 | new: | 741 | new: |
742 | 742 | ||
743 | id: LANG_WORMLET_CRASHED | 743 | id: LANG_WORMLET_CRASHED |
744 | desc: wormlet game | 744 | desc: wormlet game |
745 | eng: "Crashed" | 745 | eng: "" |
746 | new: | 746 | new: |
747 | 747 | ||
748 | id: LANG_WORMLET_HIGHSCORE | 748 | id: LANG_WORMLET_HIGHSCORE |
749 | desc: wormlet game | 749 | desc: wormlet game |
750 | eng: "Hs: %d" | 750 | eng: "" |
751 | new: | 751 | new: |
752 | 752 | ||
753 | # Length restrictions for wormlet config screen strings (LANG_CS_XXX) | 753 | # Length restrictions for wormlet config screen strings (LANG_CS_XXX) |
@@ -756,49 +756,49 @@ new: | |||
756 | 756 | ||
757 | id: LANG_WORMLET_PLAYERS | 757 | id: LANG_WORMLET_PLAYERS |
758 | desc: wormlet game | 758 | desc: wormlet game |
759 | eng: "%d Players UP/DN" | 759 | eng: "" |
760 | new: | 760 | new: |
761 | 761 | ||
762 | id: LANG_WORMLET_WORMS | 762 | id: LANG_WORMLET_WORMS |
763 | desc: wormlet game | 763 | desc: wormlet game |
764 | eng: "%d Worms L/R" | 764 | eng: "" |
765 | new: | 765 | new: |
766 | 766 | ||
767 | id: LANG_WORMLET_REMOTE_CTRL | 767 | id: LANG_WORMLET_REMOTE_CTRL |
768 | desc: wormlet game | 768 | desc: wormlet game |
769 | eng: "Remote Control F1" | 769 | eng: "" |
770 | new: | 770 | new: |
771 | 771 | ||
772 | id: LANG_WORMLET_NO_REM_CTRL | 772 | id: LANG_WORMLET_NO_REM_CTRL |
773 | desc: wormlet game | 773 | desc: wormlet game |
774 | eng: "No Rem. Control F1" | 774 | eng: "" |
775 | new: | 775 | new: |
776 | 776 | ||
777 | id: LANG_WORMLET_2_KEY_CTRL | 777 | id: LANG_WORMLET_2_KEY_CTRL |
778 | desc: wormlet game | 778 | desc: wormlet game |
779 | eng: "2 Key Control F1" | 779 | eng: "" |
780 | new: | 780 | new: |
781 | 781 | ||
782 | id: LANG_WORMLET_4_KEY_CTRL | 782 | id: LANG_WORMLET_4_KEY_CTRL |
783 | desc: wormlet game | 783 | desc: wormlet game |
784 | eng: "4 Key Control F1" | 784 | eng: "" |
785 | new: | 785 | new: |
786 | 786 | ||
787 | id: LANG_WORMLET_NO_CONTROL | 787 | id: LANG_WORMLET_NO_CONTROL |
788 | desc: wormlet game | 788 | desc: wormlet game |
789 | eng: "Out Of Control" | 789 | eng: "" |
790 | new: | 790 | new: |
791 | 791 | ||
792 | # Wormlet game ids ended | 792 | # Wormlet game ids ended |
793 | 793 | ||
794 | id: LANG_TETRIS_LOSE | 794 | id: LANG_TETRIS_LOSE |
795 | desc: tetris game | 795 | desc: tetris game |
796 | eng: "You Lose!" | 796 | eng: "" |
797 | new: | 797 | new: |
798 | 798 | ||
799 | id: LANG_TETRIS_LEVEL | 799 | id: LANG_TETRIS_LEVEL |
800 | desc: tetris game | 800 | desc: tetris game |
801 | eng: "Rows - Level" | 801 | eng: "" |
802 | new: | 802 | new: |
803 | 803 | ||
804 | id: LANG_POWEROFF_IDLE | 804 | id: LANG_POWEROFF_IDLE |
@@ -1569,3 +1569,33 @@ id: LANG_CANCEL_WITH_ANY_RECORDER | |||
1569 | desc: Generic recorder string to use to cancel | 1569 | desc: Generic recorder string to use to cancel |
1570 | eng: "Any Other = No" | 1570 | eng: "Any Other = No" |
1571 | new: | 1571 | new: |
1572 | |||
1573 | ## | ||
1574 | ## Strings used in the plugin loader: | ||
1575 | ## | ||
1576 | |||
1577 | id: LANG_PLUGIN_CANT_OPEN | ||
1578 | desc: Plugin open error message | ||
1579 | eng: "Can't open %s" | ||
1580 | new: | ||
1581 | |||
1582 | id: LANG_READ_FAILED | ||
1583 | desc: There was an error reading a file | ||
1584 | eng: "Failed reading %s" | ||
1585 | new: | ||
1586 | |||
1587 | id: LANG_PLUGIN_WRONG_MODEL | ||
1588 | desc: The plugin is not compatible with the archos model trying to run it | ||
1589 | eng: "Incompatible model" | ||
1590 | new: | ||
1591 | |||
1592 | id: LANG_PLUGIN_WRONG_VERSION | ||
1593 | desc: The plugin is not compatible with the rockbox version trying to run it | ||
1594 | eng: "Incompatible version" | ||
1595 | new: | ||
1596 | |||
1597 | id: LANG_PLUGIN_ERROR | ||
1598 | desc: The plugin return an error code | ||
1599 | eng: "Plugin returned error" | ||
1600 | new: | ||
1601 | |||
diff --git a/apps/player/icons.h b/apps/player/icons.h index 1c9c68d66c..c96f821cfa 100644 --- a/apps/player/icons.h +++ b/apps/player/icons.h | |||
@@ -26,7 +26,8 @@ | |||
26 | 26 | ||
27 | enum { | 27 | enum { |
28 | Unknown=0x90, | 28 | Unknown=0x90, |
29 | Folder=0x18, Mod_Ajz, Language, File, Wps, Playlist, Text, Config | 29 | Plugin = 0x17, |
30 | Folder, Mod_Ajz, Language, File, Wps, Playlist, Text, Config, | ||
30 | }; | 31 | }; |
31 | 32 | ||
32 | #endif | 33 | #endif |
diff --git a/apps/plugin.c b/apps/plugin.c new file mode 100644 index 0000000000..6366580a56 --- /dev/null +++ b/apps/plugin.c | |||
@@ -0,0 +1,221 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 Björn Stenberg | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #include <stdbool.h> | ||
20 | #include <string.h> | ||
21 | #include <stdio.h> | ||
22 | #include "button.h" | ||
23 | #include "lcd.h" | ||
24 | #include "dir.h" | ||
25 | #include "file.h" | ||
26 | #include "kernel.h" | ||
27 | #include "sprintf.h" | ||
28 | #include "screens.h" | ||
29 | #include "misc.h" | ||
30 | #include "mas.h" | ||
31 | #include "plugin.h" | ||
32 | #include "lang.h" | ||
33 | |||
34 | #ifdef SIMULATOR | ||
35 | #include <dlfcn.h> | ||
36 | #define PREFIX(_x_) x11_ ## _x_ | ||
37 | #else | ||
38 | #define PREFIX(_x_) _x_ | ||
39 | #endif | ||
40 | |||
41 | static int plugin_test(int api_version, int model); | ||
42 | |||
43 | static struct plugin_api rockbox_api = { | ||
44 | PLUGIN_API_VERSION, | ||
45 | |||
46 | plugin_test, | ||
47 | |||
48 | /* lcd */ | ||
49 | lcd_clear_display, | ||
50 | lcd_puts, | ||
51 | lcd_puts_scroll, | ||
52 | lcd_stop_scroll, | ||
53 | #ifdef HAVE_LCD_CHARCELLS | ||
54 | lcd_define_pattern, | ||
55 | #else | ||
56 | lcd_putsxy, | ||
57 | lcd_bitmap, | ||
58 | lcd_drawline, | ||
59 | lcd_clearline, | ||
60 | lcd_drawpixel, | ||
61 | lcd_clearpixel, | ||
62 | lcd_setfont, | ||
63 | lcd_clearrect, | ||
64 | lcd_fillrect, | ||
65 | lcd_drawrect, | ||
66 | lcd_invertrect, | ||
67 | lcd_getstringsize, | ||
68 | lcd_update, | ||
69 | lcd_update_rect, | ||
70 | #ifndef SIMULATOR | ||
71 | lcd_roll, | ||
72 | #endif | ||
73 | #endif | ||
74 | |||
75 | /* button */ | ||
76 | button_get, | ||
77 | button_get_w_tmo, | ||
78 | |||
79 | /* file */ | ||
80 | PREFIX(open), | ||
81 | PREFIX(close), | ||
82 | read, | ||
83 | lseek, | ||
84 | PREFIX(creat), | ||
85 | write, | ||
86 | remove, | ||
87 | rename, | ||
88 | ftruncate, | ||
89 | PREFIX(filesize), | ||
90 | fprintf, | ||
91 | read_line, | ||
92 | |||
93 | /* dir */ | ||
94 | PREFIX(opendir), | ||
95 | PREFIX(closedir), | ||
96 | PREFIX(readdir), | ||
97 | |||
98 | /* kernel */ | ||
99 | PREFIX(sleep), | ||
100 | usb_screen, | ||
101 | ¤t_tick, | ||
102 | |||
103 | /* strings and memory */ | ||
104 | snprintf, | ||
105 | strcpy, | ||
106 | strlen, | ||
107 | memset, | ||
108 | memcpy, | ||
109 | |||
110 | /* sound */ | ||
111 | #ifndef SIMULATOR | ||
112 | #ifdef HAVE_MAS3587F | ||
113 | mas_codec_readreg, | ||
114 | #endif | ||
115 | #endif | ||
116 | |||
117 | /* misc */ | ||
118 | srand, | ||
119 | rand, | ||
120 | splash, | ||
121 | }; | ||
122 | |||
123 | int plugin_load(char* plugin, void* parameter) | ||
124 | { | ||
125 | enum plugin_status (*plugin_start)(struct plugin_api* api, void* param); | ||
126 | int rc; | ||
127 | char buf[64]; | ||
128 | #ifdef SIMULATOR | ||
129 | void* pd; | ||
130 | char path[256]; | ||
131 | #else | ||
132 | extern unsigned char pluginbuf[]; | ||
133 | int fd; | ||
134 | #endif | ||
135 | |||
136 | lcd_clear_display(); | ||
137 | #ifdef HAVE_LCD_BITMAP | ||
138 | lcd_setmargins(0,0); | ||
139 | lcd_update(); | ||
140 | #endif | ||
141 | #ifdef SIMULATOR | ||
142 | snprintf(path, sizeof path, "archos%s", plugin); | ||
143 | pd = dlopen(path, RTLD_NOW); | ||
144 | if (!pd) { | ||
145 | snprintf(buf, sizeof buf, "Can't open %s", plugin); | ||
146 | splash(HZ*2, 0, true, buf); | ||
147 | dlclose(pd); | ||
148 | return -1; | ||
149 | } | ||
150 | |||
151 | plugin_start = dlsym(pd, "plugin_start"); | ||
152 | if (!plugin_start) { | ||
153 | plugin_start = dlsym(pd, "_plugin_start"); | ||
154 | if (!plugin_start) { | ||
155 | splash(HZ*2, 0, true, "Can't find entry point"); | ||
156 | dlclose(pd); | ||
157 | return -1; | ||
158 | } | ||
159 | } | ||
160 | #else | ||
161 | fd = open(plugin, O_RDONLY); | ||
162 | if (fd < 0) { | ||
163 | snprintf(buf, sizeof buf, str(LANG_PLUGIN_CANT_OPEN), plugin); | ||
164 | splash(HZ*2, 0, true, buf); | ||
165 | return fd; | ||
166 | } | ||
167 | |||
168 | plugin_start = (void*)&pluginbuf; | ||
169 | rc = read(fd, plugin_start, 0x8000); | ||
170 | close(fd); | ||
171 | if (rc < 0) { | ||
172 | /* read error */ | ||
173 | snprintf(buf, sizeof buf, str(LANG_READ_FAILED), plugin); | ||
174 | splash(HZ*2, 0, true, buf); | ||
175 | return -1; | ||
176 | } | ||
177 | if (rc == 0) { | ||
178 | /* loaded a 0-byte plugin, implying it's not for this model */ | ||
179 | splash(HZ*2, 0, true, str(LANG_PLUGIN_WRONG_MODEL)); | ||
180 | return -1; | ||
181 | } | ||
182 | #endif | ||
183 | |||
184 | rc = plugin_start(&rockbox_api, parameter); | ||
185 | switch (rc) { | ||
186 | case PLUGIN_OK: | ||
187 | break; | ||
188 | |||
189 | case PLUGIN_USB_CONNECTED: | ||
190 | return PLUGIN_USB_CONNECTED; | ||
191 | |||
192 | case PLUGIN_WRONG_API_VERSION: | ||
193 | splash(HZ*2, 0, true, str(LANG_PLUGIN_WRONG_VERSION)); | ||
194 | break; | ||
195 | |||
196 | case PLUGIN_WRONG_MODEL: | ||
197 | splash(HZ*2, 0, true, str(LANG_PLUGIN_WRONG_MODEL)); | ||
198 | break; | ||
199 | |||
200 | default: | ||
201 | splash(HZ*2, 0, true, str(LANG_PLUGIN_ERROR)); | ||
202 | break; | ||
203 | } | ||
204 | |||
205 | #ifdef SIMULATOR | ||
206 | dlclose(pd); | ||
207 | #endif | ||
208 | |||
209 | return PLUGIN_OK; | ||
210 | } | ||
211 | |||
212 | int plugin_test(int api_version, int model) | ||
213 | { | ||
214 | if (api_version != PLUGIN_API_VERSION) | ||
215 | return PLUGIN_WRONG_API_VERSION; | ||
216 | |||
217 | if (model != MODEL) | ||
218 | return PLUGIN_WRONG_MODEL; | ||
219 | |||
220 | return PLUGIN_OK; | ||
221 | } | ||
diff --git a/apps/plugin.h b/apps/plugin.h new file mode 100644 index 0000000000..3b79edefc6 --- /dev/null +++ b/apps/plugin.h | |||
@@ -0,0 +1,161 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 Björn Stenberg | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #ifndef _PLUGIN_H_ | ||
20 | #define _PLUGIN_H_ | ||
21 | |||
22 | /* instruct simulator code to not redefine any symbols when compiling plugins. | ||
23 | (the PLUGIN macro is defined in apps/plugins/Makefile) */ | ||
24 | #ifdef PLUGIN | ||
25 | #define NO_REDEFINES_PLEASE | ||
26 | #endif | ||
27 | |||
28 | #include <stdbool.h> | ||
29 | #include <stdio.h> | ||
30 | #include <stdlib.h> | ||
31 | #include "config.h" | ||
32 | #include "dir.h" | ||
33 | #include "kernel.h" | ||
34 | #include "button.h" | ||
35 | #include "font.h" | ||
36 | #include "system.h" | ||
37 | #include "lcd.h" | ||
38 | |||
39 | /* increase this every time the api struct changes */ | ||
40 | #define PLUGIN_API_VERSION 1 | ||
41 | |||
42 | /* plugin return codes */ | ||
43 | enum plugin_status { | ||
44 | PLUGIN_OK = 0, | ||
45 | PLUGIN_USB_CONNECTED, | ||
46 | |||
47 | PLUGIN_WRONG_API_VERSION = -1, | ||
48 | PLUGIN_WRONG_MODEL = -2, | ||
49 | PLUGIN_ERROR = -3, | ||
50 | }; | ||
51 | |||
52 | /* different (incompatible) plugin models */ | ||
53 | enum model { | ||
54 | PLAYER, | ||
55 | RECORDER | ||
56 | }; | ||
57 | |||
58 | #ifdef HAVE_LCD_CHARCELLS | ||
59 | #define MODEL PLAYER | ||
60 | #else | ||
61 | #define MODEL RECORDER | ||
62 | #endif | ||
63 | |||
64 | /* compatibility test macro */ | ||
65 | #define TEST_PLUGIN_API(_api_) \ | ||
66 | do { \ | ||
67 | int _rc_ = _api_->plugin_test(PLUGIN_API_VERSION, MODEL); \ | ||
68 | if (_rc_<0) \ | ||
69 | return _rc_; \ | ||
70 | } while(0) | ||
71 | |||
72 | struct plugin_api { | ||
73 | /* these two fields must always be first, to ensure | ||
74 | TEST_PLUGIN_API will always work */ | ||
75 | int version; | ||
76 | int (*plugin_test)(int api_version, int model); | ||
77 | |||
78 | /* lcd */ | ||
79 | void (*lcd_clear_display)(void); | ||
80 | void (*lcd_puts)(int x, int y, unsigned char *string); | ||
81 | void (*lcd_puts_scroll)(int x, int y, unsigned char* string); | ||
82 | void (*lcd_stop_scroll)(void); | ||
83 | #ifdef HAVE_LCD_CHARCELLS | ||
84 | void (*lcd_define_pattern)(int which,char *pattern); | ||
85 | #else | ||
86 | void (*lcd_putsxy)(int x, int y, unsigned char *string); | ||
87 | void (*lcd_bitmap)(unsigned char *src, int x, int y, | ||
88 | int nx, int ny, bool clear); | ||
89 | void (*lcd_drawline)(int x1, int y1, int x2, int y2); | ||
90 | void (*lcd_clearline)(int x1, int y1, int x2, int y2); | ||
91 | void (*lcd_drawpixel)(int x, int y); | ||
92 | void (*lcd_clearpixel)(int x, int y); | ||
93 | void (*lcd_setfont)(int font); | ||
94 | void (*lcd_clearrect)(int x, int y, int nx, int ny); | ||
95 | void (*lcd_fillrect)(int x, int y, int nx, int ny); | ||
96 | void (*lcd_drawrect)(int x, int y, int nx, int ny); | ||
97 | void (*lcd_invertrect)(int x, int y, int nx, int ny); | ||
98 | int (*lcd_getstringsize)(unsigned char *str, int *w, int *h); | ||
99 | void (*lcd_update)(void); | ||
100 | void (*lcd_update_rect)(int x, int y, int width, int height); | ||
101 | #ifndef SIMULATOR | ||
102 | void (*lcd_roll)(int pixels); | ||
103 | #endif | ||
104 | #endif | ||
105 | |||
106 | /* button */ | ||
107 | int (*button_get)(bool block); | ||
108 | int (*button_get_w_tmo)(int ticks); | ||
109 | |||
110 | /* file */ | ||
111 | int (*open)(const char* pathname, int flags); | ||
112 | int (*close)(int fd); | ||
113 | int (*read)(int fd, void* buf, int count); | ||
114 | int (*lseek)(int fd, int offset, int whence); | ||
115 | int (*creat)(const char *pathname, int mode); | ||
116 | int (*write)(int fd, void* buf, int count); | ||
117 | int (*remove)(const char* pathname); | ||
118 | int (*rename)(const char* path, const char* newname); | ||
119 | int (*ftruncate)(int fd, unsigned int size); | ||
120 | int (*filesize)(int fd); | ||
121 | int (*fprintf)(int fd, const char *fmt, ...); | ||
122 | int (*read_line)(int fd, char* buffer, int buffer_size); | ||
123 | |||
124 | /* dir */ | ||
125 | DIR* (*opendir)(char* name); | ||
126 | int (*closedir)(DIR* dir); | ||
127 | struct dirent* (*readdir)(DIR* dir); | ||
128 | |||
129 | /* kernel */ | ||
130 | void (*sleep)(int ticks); | ||
131 | void (*usb_screen)(void); | ||
132 | long* current_tick; | ||
133 | |||
134 | /* strings and memory */ | ||
135 | int (*snprintf)(char *buf, size_t size, const char *fmt, ...); | ||
136 | char* (*strcpy)(char *dst, const char *src); | ||
137 | size_t (*strlen)(const char *str); | ||
138 | void* (*memset)(void *dst, int c, size_t length); | ||
139 | void* (*memcpy)(void *out, const void *in, size_t n); | ||
140 | |||
141 | /* sound */ | ||
142 | #ifndef SIMULATOR | ||
143 | #ifdef HAVE_MAS3587F | ||
144 | int (*mas_codec_readreg)(int reg); | ||
145 | #endif | ||
146 | #endif | ||
147 | |||
148 | /* misc */ | ||
149 | void (*srand)(unsigned int seed); | ||
150 | int (*rand)(void); | ||
151 | void (*splash)(int ticks, int keymask, bool center, char *fmt, ...); | ||
152 | }; | ||
153 | |||
154 | /* defined by the plugin loader (plugin.c) */ | ||
155 | int plugin_load(char* plugin, void* parameter); | ||
156 | |||
157 | /* defined by the plugin */ | ||
158 | enum plugin_status plugin_start(struct plugin_api* rockbox, void* parameter) | ||
159 | __attribute__ ((section (".entry"))); | ||
160 | |||
161 | #endif | ||
diff --git a/apps/plugins/Makefile b/apps/plugins/Makefile new file mode 100644 index 0000000000..4c02207016 --- /dev/null +++ b/apps/plugins/Makefile | |||
@@ -0,0 +1,45 @@ | |||
1 | # __________ __ ___. | ||
2 | # Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
3 | # Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
4 | # Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
5 | # Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
6 | # \/ \/ \/ \/ \/ | ||
7 | # $Id$ | ||
8 | # | ||
9 | |||
10 | CC = sh-elf-gcc | ||
11 | OC = sh-elf-objcopy | ||
12 | |||
13 | FIRMWARE = ../../firmware | ||
14 | |||
15 | INCLUDES = -I$(FIRMWARE)/include -I$(FIRMWARE)/export -I$(FIRMWARE)/common -I$(FIRMWARE)/drivers -I.. | ||
16 | CFLAGS = -O -W -Wall -m1 -nostdlib -ffreestanding -Wstrict-prototypes $(INCLUDES) $(TARGET) $(EXTRA_DEFINES) | ||
17 | |||
18 | LINKFILE = plugin.lds | ||
19 | |||
20 | SRC := $(wildcard *.c) | ||
21 | ROCKS := $(SRC:%.c=$(OBJDIR)/%.rock) | ||
22 | |||
23 | ifndef OBJDIR | ||
24 | no_configure: | ||
25 | @echo "Don't run make here. Run the tools/configure script from your own build" | ||
26 | @echo "directory, then run make there." | ||
27 | @echo | ||
28 | @echo "More help on how to build rockbox can be found here:" | ||
29 | @echo "http://rockbox.haxx.se/docs/how_to_compile.html" | ||
30 | endif | ||
31 | |||
32 | $(OBJDIR)/%.elf: $(OBJDIR)/%.o $(LINKFILE) | ||
33 | $(CC) -O -nostdlib -o $@ $< -lgcc -T$(LINKFILE) -Wl,-Map,$*.map | ||
34 | |||
35 | $(OBJDIR)/%.rock : $(OBJDIR)/%.elf | ||
36 | $(OC) -O binary $< $@ | ||
37 | |||
38 | $(OBJDIR)/%.o: %.c ../plugin.h Makefile | ||
39 | $(CC) $(CFLAGS) -c $< -o $@ | ||
40 | |||
41 | all: $(ROCKS) | ||
42 | @echo done | ||
43 | |||
44 | clean: | ||
45 | -rm -f $(ROCKS) | ||
diff --git a/apps/recorder/bounce.c b/apps/plugins/bounce.c index ed4885bc39..0c53d49887 100644 --- a/apps/recorder/bounce.c +++ b/apps/plugins/bounce.c | |||
@@ -15,26 +15,10 @@ | |||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | 15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY |
16 | * KIND, either express or implied. | 16 | * KIND, either express or implied. |
17 | * | 17 | * |
18 | ****************************************************************************/ | 18 | **************************************************************************/ |
19 | #include "plugin.h" | ||
19 | 20 | ||
20 | #include "config.h" | 21 | #ifdef HAVE_LCD_BITMAP |
21 | #include "options.h" | ||
22 | |||
23 | #ifdef USE_DEMOS | ||
24 | |||
25 | #include "lcd.h" | ||
26 | #include "button.h" | ||
27 | #include "kernel.h" | ||
28 | #include "menu.h" | ||
29 | #include "sprintf.h" | ||
30 | #include "rtc.h" | ||
31 | #include "font.h" | ||
32 | #include "screens.h" | ||
33 | |||
34 | #ifdef SIMULATOR | ||
35 | #include <stdio.h> | ||
36 | #endif | ||
37 | #include <string.h> | ||
38 | 22 | ||
39 | #define SS_TITLE "Bouncer" | 23 | #define SS_TITLE "Bouncer" |
40 | #define SS_TITLE_FONT 2 | 24 | #define SS_TITLE_FONT 2 |
@@ -45,6 +29,7 @@ | |||
45 | #define XSPEED 3 | 29 | #define XSPEED 3 |
46 | #define YADD -4 | 30 | #define YADD -4 |
47 | 31 | ||
32 | static struct plugin_api* rb; | ||
48 | 33 | ||
49 | static unsigned char table[]={ | 34 | static unsigned char table[]={ |
50 | 26,28,30,33,35,37,39,40,42,43,45,46,46,47,47,47,47,47,46,46,45,43,42,40,39,37,35,33,30,28,26,24,21,19,17,14,12,10,8,7,5,4,2,1,1,0,0,0,0,0,1,1,2,4,5,7,8,10,12,14,17,19,21,23, | 35 | 26,28,30,33,35,37,39,40,42,43,45,46,46,47,47,47,47,47,46,46,45,43,42,40,39,37,35,33,30,28,26,24,21,19,17,14,12,10,8,7,5,4,2,1,1,0,0,0,0,0,1,1,2,4,5,7,8,10,12,14,17,19,21,23, |
@@ -186,6 +171,7 @@ struct counter values[]={ | |||
186 | {"ydistt", -6}, | 171 | {"ydistt", -6}, |
187 | }; | 172 | }; |
188 | 173 | ||
174 | #ifdef USE_CLOCK | ||
189 | static unsigned char yminute[]={ | 175 | static unsigned char yminute[]={ |
190 | 53,53,52,52,51,50,49,47,46,44,42,40,38,36,34,32,29,27,25,23,21,19,17,16,14,13,12,11,11,10,10,10,11,11,12,13,14,16,17,19,21,23,25,27,29,31,34,36,38,40,42,44,46,47,49,50,51,52,52,53, | 176 | 53,53,52,52,51,50,49,47,46,44,42,40,38,36,34,32,29,27,25,23,21,19,17,16,14,13,12,11,11,10,10,10,11,11,12,13,14,16,17,19,21,23,25,27,29,31,34,36,38,40,42,44,46,47,49,50,51,52,52,53, |
191 | }; | 177 | }; |
@@ -216,23 +202,24 @@ static void addclock(void) | |||
216 | if(pos >= 60) | 202 | if(pos >= 60) |
217 | pos -= 60; | 203 | pos -= 60; |
218 | 204 | ||
219 | lcd_drawline(LCD_WIDTH/2, LCD_HEIGHT/2, xminute[pos], yminute[pos]); | 205 | rb->lcd_drawline(LCD_WIDTH/2, LCD_HEIGHT/2, xminute[pos], yminute[pos]); |
220 | 206 | ||
221 | hour = hour*5 + minute/12; | 207 | hour = hour*5 + minute/12; |
222 | pos = 90-hour; | 208 | pos = 90-hour; |
223 | if(pos >= 60) | 209 | if(pos >= 60) |
224 | pos -= 60; | 210 | pos -= 60; |
225 | 211 | ||
226 | lcd_drawline(LCD_WIDTH/2, LCD_HEIGHT/2, xhour[pos], yhour[pos]); | 212 | rb->lcd_drawline(LCD_WIDTH/2, LCD_HEIGHT/2, xhour[pos], yhour[pos]); |
227 | 213 | ||
228 | /* draw a circle */ | 214 | /* draw a circle */ |
229 | for(i=0; i < 60; i+=3) { | 215 | for(i=0; i < 60; i+=3) { |
230 | lcd_drawline( xminute[i], | 216 | rb->lcd_drawline( xminute[i], |
231 | yminute[i], | 217 | yminute[i], |
232 | xminute[(i+1)%60], | 218 | xminute[(i+1)%60], |
233 | yminute[(i+1)%60]); | 219 | yminute[(i+1)%60]); |
234 | } | 220 | } |
235 | } | 221 | } |
222 | #endif | ||
236 | 223 | ||
237 | static int scrollit(void) | 224 | static int scrollit(void) |
238 | { | 225 | { |
@@ -243,31 +230,33 @@ static int scrollit(void) | |||
243 | unsigned int i; | 230 | unsigned int i; |
244 | int textpos=0; | 231 | int textpos=0; |
245 | 232 | ||
246 | char rock[]="Rockbox! Pure pleasure. Pure fun. Oooh. What fun! ;-) "; | 233 | char* rock="Rockbox! Pure pleasure. Pure fun. Oooh. What fun! ;-) "; |
247 | int letter; | 234 | int letter; |
248 | 235 | ||
249 | lcd_clear_display(); | 236 | rb->lcd_clear_display(); |
250 | while(1) | 237 | while(1) |
251 | { | 238 | { |
252 | b = button_get_w_tmo(HZ/10); | 239 | b = rb->button_get_w_tmo(HZ/10); |
253 | if ( b == (BUTTON_OFF|BUTTON_REL) ) | 240 | if ( b == (BUTTON_OFF|BUTTON_REL) ) |
254 | return 0; | 241 | return 0; |
255 | else if ( b == (BUTTON_ON|BUTTON_REL) ) | 242 | else if ( b == (BUTTON_ON|BUTTON_REL) ) |
256 | return 1; | 243 | return 1; |
257 | 244 | ||
258 | lcd_clear_display(); | 245 | rb->lcd_clear_display(); |
259 | 246 | ||
260 | for(i=0, yy=y, xx=x; i< LETTERS_ON_SCREEN; i++) { | 247 | for(i=0, yy=y, xx=x; i< LETTERS_ON_SCREEN; i++) { |
261 | letter = rock[(i+textpos) % (sizeof(rock)-1) ]; | 248 | letter = rock[(i+textpos) % (sizeof(rock)-1) ]; |
262 | 249 | ||
263 | lcd_bitmap((char *)char_gen_12x16[letter-0x20], | 250 | rb->lcd_bitmap((char *)char_gen_12x16[letter-0x20], |
264 | xx, table[yy&63], | 251 | xx, table[yy&63], |
265 | 11, 16, false); | 252 | 11, 16, false); |
266 | yy += YADD; | 253 | yy += YADD; |
267 | xx+= LCD_WIDTH/LETTERS_ON_SCREEN; | 254 | xx+= LCD_WIDTH/LETTERS_ON_SCREEN; |
268 | } | 255 | } |
256 | #ifdef USE_CLOCK | ||
269 | addclock(); | 257 | addclock(); |
270 | lcd_update(); | 258 | #endif |
259 | rb->lcd_update(); | ||
271 | 260 | ||
272 | x-= XSPEED; | 261 | x-= XSPEED; |
273 | 262 | ||
@@ -292,21 +281,21 @@ static int loopit(void) | |||
292 | unsigned int ysanke=0; | 281 | unsigned int ysanke=0; |
293 | unsigned int xsanke=0; | 282 | unsigned int xsanke=0; |
294 | 283 | ||
295 | char rock[]="ROCKbox"; | 284 | char* rock="ROCKbox"; |
296 | 285 | ||
297 | int show=0; | 286 | int show=0; |
298 | int timeout=0; | 287 | int timeout=0; |
299 | char buffer[30]; | 288 | char buffer[30]; |
300 | 289 | ||
301 | lcd_clear_display(); | 290 | rb->lcd_clear_display(); |
302 | while(1) | 291 | while(1) |
303 | { | 292 | { |
304 | b = button_get_w_tmo(HZ/10); | 293 | b = rb->button_get_w_tmo(HZ/10); |
305 | if ( b == (BUTTON_OFF|BUTTON_REL) ) | 294 | if ( b == (BUTTON_OFF|BUTTON_REL) ) |
306 | return 0; | 295 | return 0; |
307 | 296 | ||
308 | if ( b == SYS_USB_CONNECTED) { | 297 | if ( b == SYS_USB_CONNECTED) { |
309 | usb_screen(); | 298 | rb->usb_screen(); |
310 | return 0; | 299 | return 0; |
311 | } | 300 | } |
312 | 301 | ||
@@ -318,10 +307,10 @@ static int loopit(void) | |||
318 | y+= speed[ysanke&15] + values[NUM_YADD].num; | 307 | y+= speed[ysanke&15] + values[NUM_YADD].num; |
319 | x+= speed[xsanke&15] + values[NUM_XADD].num; | 308 | x+= speed[xsanke&15] + values[NUM_XADD].num; |
320 | 309 | ||
321 | lcd_clear_display(); | 310 | rb->lcd_clear_display(); |
322 | 311 | #ifdef USE_CLOCK | |
323 | addclock(); | 312 | addclock(); |
324 | 313 | #endif | |
325 | if(timeout) { | 314 | if(timeout) { |
326 | switch(b) { | 315 | switch(b) { |
327 | case BUTTON_LEFT: | 316 | case BUTTON_LEFT: |
@@ -339,18 +328,18 @@ static int loopit(void) | |||
339 | show=NUM_LAST-1; | 328 | show=NUM_LAST-1; |
340 | break; | 329 | break; |
341 | } | 330 | } |
342 | snprintf(buffer, 30, "%s: %d", | 331 | rb->snprintf(buffer, 30, "%s: %d", |
343 | values[show].what, values[show].num); | 332 | values[show].what, values[show].num); |
344 | lcd_putsxy(0, 56, buffer); | 333 | rb->lcd_putsxy(0, 56, buffer); |
345 | timeout--; | 334 | timeout--; |
346 | } | 335 | } |
347 | for(i=0, yy=y, xx=x; | 336 | for(i=0, yy=y, xx=x; |
348 | i<sizeof(rock)-1; | 337 | i<sizeof(rock)-1; |
349 | i++, yy+=values[NUM_YDIST].num, xx+=values[NUM_XDIST].num) | 338 | i++, yy+=values[NUM_YDIST].num, xx+=values[NUM_XDIST].num) |
350 | lcd_bitmap((char *)char_gen_12x16[rock[i]-0x20], | 339 | rb->lcd_bitmap((char *)char_gen_12x16[rock[i]-0x20], |
351 | xtable[xx%71], table[yy&63], | 340 | xtable[xx%71], table[yy&63], |
352 | 11, 16, false); | 341 | 11, 16, false); |
353 | lcd_update(); | 342 | rb->lcd_update(); |
354 | 343 | ||
355 | ysanke+= values[NUM_YSANKE].num; | 344 | ysanke+= values[NUM_YSANKE].num; |
356 | xsanke+= values[NUM_XSANKE].num; | 345 | xsanke+= values[NUM_XSANKE].num; |
@@ -358,15 +347,19 @@ static int loopit(void) | |||
358 | } | 347 | } |
359 | 348 | ||
360 | 349 | ||
361 | bool bounce(void) | 350 | enum plugin_status plugin_start(struct plugin_api* api, void* parameter) |
362 | { | 351 | { |
363 | int w, h; | 352 | int w, h; |
364 | char *off = "[Off] to stop"; | 353 | char *off = "[Off] to stop"; |
365 | int len = strlen(SS_TITLE); | 354 | int len; |
366 | 355 | ||
367 | lcd_setfont(FONT_SYSFIXED); | 356 | TEST_PLUGIN_API(api); |
357 | (void)(parameter); | ||
358 | rb = api; | ||
368 | 359 | ||
369 | lcd_getstringsize(SS_TITLE,&w, &h); | 360 | len = rb->strlen(SS_TITLE); |
361 | rb->lcd_setfont(FONT_SYSFIXED); | ||
362 | rb->lcd_getstringsize(SS_TITLE,&w, &h); | ||
370 | 363 | ||
371 | /* Get horizontel centering for text */ | 364 | /* Get horizontel centering for text */ |
372 | len *= w; | 365 | len *= w; |
@@ -380,11 +373,11 @@ bool bounce(void) | |||
380 | else | 373 | else |
381 | h /= 2; | 374 | h /= 2; |
382 | 375 | ||
383 | lcd_clear_display(); | 376 | rb->lcd_clear_display(); |
384 | lcd_putsxy(LCD_WIDTH/2-len, (LCD_HEIGHT/2)-h, SS_TITLE); | 377 | rb->lcd_putsxy(LCD_WIDTH/2-len, (LCD_HEIGHT/2)-h, SS_TITLE); |
385 | 378 | ||
386 | len = 1; | 379 | len = 1; |
387 | lcd_getstringsize(off, &w, &h); | 380 | rb->lcd_getstringsize(off, &w, &h); |
388 | 381 | ||
389 | /* Get horizontel centering for text */ | 382 | /* Get horizontel centering for text */ |
390 | len *= w; | 383 | len *= w; |
@@ -398,10 +391,9 @@ bool bounce(void) | |||
398 | else | 391 | else |
399 | h /= 2; | 392 | h /= 2; |
400 | 393 | ||
401 | lcd_putsxy(LCD_WIDTH/2-len, LCD_HEIGHT-(2*h), off); | 394 | rb->lcd_putsxy(LCD_WIDTH/2-len, LCD_HEIGHT-(2*h), off); |
402 | 395 | rb->lcd_update(); | |
403 | lcd_update(); | 396 | rb->sleep(HZ); |
404 | sleep(HZ); | ||
405 | 397 | ||
406 | do { | 398 | do { |
407 | h= loopit(); | 399 | h= loopit(); |
@@ -409,7 +401,7 @@ bool bounce(void) | |||
409 | h = scrollit(); | 401 | h = scrollit(); |
410 | } while(h); | 402 | } while(h); |
411 | 403 | ||
412 | lcd_setfont(FONT_UI); | 404 | rb->lcd_setfont(FONT_UI); |
413 | 405 | ||
414 | return false; | 406 | return false; |
415 | } | 407 | } |
diff --git a/apps/recorder/cube.c b/apps/plugins/cube.c index ad3af91c87..996a1a81dd 100644 --- a/apps/recorder/cube.c +++ b/apps/plugins/cube.c | |||
@@ -16,22 +16,10 @@ | |||
16 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | 16 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY |
17 | * KIND, either express or implied. | 17 | * KIND, either express or implied. |
18 | * | 18 | * |
19 | ****************************************************************************/ | 19 | ***************************************************************************/ |
20 | #include "plugin.h" | ||
20 | 21 | ||
21 | #include "config.h" | 22 | #ifdef HAVE_LCD_BITMAP |
22 | #include "options.h" | ||
23 | |||
24 | #ifdef USE_DEMOS | ||
25 | |||
26 | #include <stdlib.h> | ||
27 | #include "lcd.h" | ||
28 | #include "config.h" | ||
29 | #include "kernel.h" | ||
30 | #include "menu.h" | ||
31 | #include "button.h" | ||
32 | #include "sprintf.h" | ||
33 | #include "screens.h" | ||
34 | #include "font.h" | ||
35 | 23 | ||
36 | /* Loops that the values are displayed */ | 24 | /* Loops that the values are displayed */ |
37 | #define DISP_TIME 30 | 25 | #define DISP_TIME 30 |
@@ -80,6 +68,8 @@ static int sin_table[91] = | |||
80 | 10000 | 68 | 10000 |
81 | }; | 69 | }; |
82 | 70 | ||
71 | static struct plugin_api* rb; | ||
72 | |||
83 | static long sin(int val) | 73 | static long sin(int val) |
84 | { | 74 | { |
85 | /* Speed improvement through sukzessive lookup */ | 75 | /* Speed improvement through sukzessive lookup */ |
@@ -214,7 +204,7 @@ static void cube_init(void) | |||
214 | 204 | ||
215 | static void line(int a, int b) | 205 | static void line(int a, int b) |
216 | { | 206 | { |
217 | lcd_drawline(point2D[a].x, point2D[a].y, point2D[b].x, point2D[b].y); | 207 | rb->lcd_drawline(point2D[a].x, point2D[a].y, point2D[b].x, point2D[b].y); |
218 | } | 208 | } |
219 | 209 | ||
220 | static void cube_draw(void) | 210 | static void cube_draw(void) |
@@ -234,7 +224,8 @@ static void cube_draw(void) | |||
234 | line(3,6); | 224 | line(3,6); |
235 | } | 225 | } |
236 | 226 | ||
237 | bool cube(void) | 227 | |
228 | enum plugin_status plugin_start(struct plugin_api* api, void* parameter) | ||
238 | { | 229 | { |
239 | int t_disp=0; | 230 | int t_disp=0; |
240 | char buffer[30]; | 231 | char buffer[30]; |
@@ -247,27 +238,31 @@ bool cube(void) | |||
247 | int zs=1; | 238 | int zs=1; |
248 | bool highspeed=0; | 239 | bool highspeed=0; |
249 | bool exit=0; | 240 | bool exit=0; |
250 | 241 | ||
251 | lcd_setfont(FONT_SYSFIXED); | 242 | TEST_PLUGIN_API(api); |
243 | (void)(parameter); | ||
244 | rb = api; | ||
245 | |||
246 | rb->lcd_setfont(FONT_SYSFIXED); | ||
252 | 247 | ||
253 | cube_init(); | 248 | cube_init(); |
254 | 249 | ||
255 | while(!exit) | 250 | while(!exit) |
256 | { | 251 | { |
257 | if (!highspeed) | 252 | if (!highspeed) |
258 | sleep(4); | 253 | rb->sleep(4); |
259 | 254 | ||
260 | lcd_clear_display(); | 255 | rb->lcd_clear_display(); |
261 | cube_rotate(xa,ya,za); | 256 | cube_rotate(xa,ya,za); |
262 | cube_viewport(); | 257 | cube_viewport(); |
263 | cube_draw(); | 258 | cube_draw(); |
264 | if (t_disp>0) | 259 | if (t_disp>0) |
265 | { | 260 | { |
266 | t_disp--; | 261 | t_disp--; |
267 | snprintf(buffer, 30, "x:%d y:%d z:%d h:%d",xs,ys,zs,highspeed); | 262 | rb->snprintf(buffer, 30, "x:%d y:%d z:%d h:%d",xs,ys,zs,highspeed); |
268 | lcd_putsxy(0, 56, buffer); | 263 | rb->lcd_putsxy(0, 56, buffer); |
269 | } | 264 | } |
270 | lcd_update(); | 265 | rb->lcd_update(); |
271 | 266 | ||
272 | xa+=xs; | 267 | xa+=xs; |
273 | if (xa>359) | 268 | if (xa>359) |
@@ -285,7 +280,7 @@ bool cube(void) | |||
285 | if (za<0) | 280 | if (za<0) |
286 | za+=360; | 281 | za+=360; |
287 | 282 | ||
288 | switch(button_get(false)) | 283 | switch(rb->button_get(false)) |
289 | { | 284 | { |
290 | case BUTTON_RIGHT: | 285 | case BUTTON_RIGHT: |
291 | xs+=1; | 286 | xs+=1; |
@@ -332,22 +327,12 @@ bool cube(void) | |||
332 | break; | 327 | break; |
333 | 328 | ||
334 | case SYS_USB_CONNECTED: | 329 | case SYS_USB_CONNECTED: |
335 | usb_screen(); | 330 | rb->usb_screen(); |
336 | lcd_setfont(FONT_UI); | 331 | return PLUGIN_USB_CONNECTED; |
337 | return true; | ||
338 | } | 332 | } |
339 | } | 333 | } |
340 | 334 | ||
341 | lcd_setfont(FONT_UI); | 335 | return PLUGIN_OK; |
342 | |||
343 | return false; | ||
344 | } | 336 | } |
345 | 337 | ||
346 | #endif /* USE_DEMOS */ | 338 | #endif |
347 | |||
348 | /* ----------------------------------------------------------------- | ||
349 | * vim: et sw=4 ts=8 sts=4 tw=78 | ||
350 | */ | ||
351 | |||
352 | |||
353 | |||
diff --git a/apps/plugins/helloworld.c b/apps/plugins/helloworld.c new file mode 100644 index 0000000000..ea347fbf79 --- /dev/null +++ b/apps/plugins/helloworld.c | |||
@@ -0,0 +1,48 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 Björn Stenberg | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #include "plugin.h" | ||
20 | |||
21 | /* welcome to the example rockbox plugin */ | ||
22 | |||
23 | /* here is a global api struct pointer. while not strictly necessary, | ||
24 | it's nice not to have to pass the api pointer in all function calls | ||
25 | in the plugin */ | ||
26 | static struct plugin_api* rb; | ||
27 | |||
28 | /* this is the plugin entry point */ | ||
29 | enum plugin_status plugin_start(struct plugin_api* api, void* parameter) | ||
30 | { | ||
31 | /* this macro should be called as the first thing you do in the plugin. | ||
32 | it test that the api version and model the plugin was compiled for | ||
33 | matches the machine it is running on */ | ||
34 | TEST_PLUGIN_API(api); | ||
35 | |||
36 | /* if you don't use the parameter, you can do like | ||
37 | this to avoid the compiler warning about it */ | ||
38 | (void)parameter; | ||
39 | |||
40 | /* if you are using a global api pointer, don't forget to copy it! | ||
41 | otherwise you will get lovely "I04: IllInstr" errors... :-) */ | ||
42 | rb = api; | ||
43 | |||
44 | /* now go ahead and have fun! */ | ||
45 | rb->splash(HZ*2, 0, true, "Hello world!"); | ||
46 | |||
47 | return PLUGIN_OK; | ||
48 | } | ||
diff --git a/apps/recorder/oscillograph.c b/apps/plugins/oscillograph.c index bf94db168f..a34aa8bfa9 100644 --- a/apps/recorder/oscillograph.c +++ b/apps/plugins/oscillograph.c | |||
@@ -16,17 +16,11 @@ | |||
16 | * KIND, either express or implied. | 16 | * KIND, either express or implied. |
17 | * | 17 | * |
18 | ****************************************************************************/ | 18 | ****************************************************************************/ |
19 | #include "plugin.h" | ||
19 | 20 | ||
21 | #ifdef HAVE_LCD_BITMAP | ||
20 | #ifndef SIMULATOR /* don't want this code in the simulator */ | 22 | #ifndef SIMULATOR /* don't want this code in the simulator */ |
21 | 23 | ||
22 | #include <stdlib.h> | ||
23 | #include <sprintf.h> | ||
24 | #include "menu.h" | ||
25 | #include "lcd.h" | ||
26 | #include "button.h" | ||
27 | #include "mas.h" | ||
28 | #include "system.h" | ||
29 | |||
30 | /* The different drawing modes */ | 24 | /* The different drawing modes */ |
31 | #define DRAW_MODE_FILLED 0 | 25 | #define DRAW_MODE_FILLED 0 |
32 | #define DRAW_MODE_OUTLINE 1 | 26 | #define DRAW_MODE_OUTLINE 1 |
@@ -47,7 +41,7 @@ static int drawMode = DRAW_MODE_FILLED; | |||
47 | * hardware scrolling of the display. The user can change | 41 | * hardware scrolling of the display. The user can change |
48 | * speed | 42 | * speed |
49 | */ | 43 | */ |
50 | bool oscillograph(void) | 44 | enum plugin_status plugin_start(struct plugin_api* rb, void* parameter) |
51 | { | 45 | { |
52 | /* stores current volume value left */ | 46 | /* stores current volume value left */ |
53 | int left; | 47 | int left; |
@@ -63,22 +57,25 @@ bool oscillograph(void) | |||
63 | 57 | ||
64 | bool exit = false; | 58 | bool exit = false; |
65 | 59 | ||
60 | TEST_PLUGIN_API(rb); | ||
61 | (void)parameter; | ||
62 | |||
66 | /* the main loop */ | 63 | /* the main loop */ |
67 | while (!exit) { | 64 | while (!exit) { |
68 | 65 | ||
69 | /* read the volume info from MAS */ | 66 | /* read the volume info from MAS */ |
70 | left = mas_codec_readreg(0xC) / (MAX_PEAK / (LCD_WIDTH / 2 - 2)); | 67 | left = rb->mas_codec_readreg(0xC) / (MAX_PEAK / (LCD_WIDTH / 2 - 2)); |
71 | right = mas_codec_readreg(0xD) / (MAX_PEAK / (LCD_WIDTH / 2 - 2)); | 68 | right = rb->mas_codec_readreg(0xD) / (MAX_PEAK / (LCD_WIDTH / 2 - 2)); |
72 | 69 | ||
73 | /* delete current line */ | 70 | /* delete current line */ |
74 | lcd_clearline(0, y, LCD_WIDTH-1, y); | 71 | rb->lcd_clearline(0, y, LCD_WIDTH-1, y); |
75 | 72 | ||
76 | switch (drawMode) { | 73 | switch (drawMode) { |
77 | case DRAW_MODE_FILLED: | 74 | case DRAW_MODE_FILLED: |
78 | lcd_drawline(LCD_WIDTH / 2 + 1 , y, | 75 | rb->lcd_drawline(LCD_WIDTH / 2 + 1 , y, |
79 | LCD_WIDTH / 2 + 1 + right, y); | 76 | LCD_WIDTH / 2 + 1 + right, y); |
80 | lcd_drawline(LCD_WIDTH / 2 - 1 , y, | 77 | rb->lcd_drawline(LCD_WIDTH / 2 - 1 , y, |
81 | LCD_WIDTH / 2 - 1 -left , y); | 78 | LCD_WIDTH / 2 - 1 -left , y); |
82 | break; | 79 | break; |
83 | 80 | ||
84 | case DRAW_MODE_OUTLINE: | 81 | case DRAW_MODE_OUTLINE: |
@@ -87,10 +84,10 @@ bool oscillograph(void) | |||
87 | 84 | ||
88 | /* Here real lines were neccessary because | 85 | /* Here real lines were neccessary because |
89 | anything else was ugly. */ | 86 | anything else was ugly. */ |
90 | lcd_drawline(LCD_WIDTH / 2 + right , y, | 87 | rb->lcd_drawline(LCD_WIDTH / 2 + right , y, |
91 | LCD_WIDTH / 2 + lastRight , lasty); | 88 | LCD_WIDTH / 2 + lastRight , lasty); |
92 | lcd_drawline(LCD_WIDTH / 2 - left , y, | 89 | rb->lcd_drawline(LCD_WIDTH / 2 - left , y, |
93 | LCD_WIDTH / 2 - lastLeft, lasty); | 90 | LCD_WIDTH / 2 - lastLeft, lasty); |
94 | 91 | ||
95 | /* have to store the old values for drawing lines | 92 | /* have to store the old values for drawing lines |
96 | the next time */ | 93 | the next time */ |
@@ -100,8 +97,8 @@ bool oscillograph(void) | |||
100 | 97 | ||
101 | case DRAW_MODE_PIXEL: | 98 | case DRAW_MODE_PIXEL: |
102 | /* straight and simple */ | 99 | /* straight and simple */ |
103 | lcd_drawpixel(LCD_WIDTH / 2 + right, y); | 100 | rb->lcd_drawpixel(LCD_WIDTH / 2 + right, y); |
104 | lcd_drawpixel(LCD_WIDTH / 2 - left, y); | 101 | rb->lcd_drawpixel(LCD_WIDTH / 2 - left, y); |
105 | break; | 102 | break; |
106 | } | 103 | } |
107 | 104 | ||
@@ -114,19 +111,19 @@ bool oscillograph(void) | |||
114 | /* I roll before update because otherwise the new | 111 | /* I roll before update because otherwise the new |
115 | line would appear at the wrong end of the display */ | 112 | line would appear at the wrong end of the display */ |
116 | if (roll) | 113 | if (roll) |
117 | lcd_roll(y); | 114 | rb->lcd_roll(y); |
118 | 115 | ||
119 | /* now finally make the new sample visible */ | 116 | /* now finally make the new sample visible */ |
120 | lcd_update_rect(0, MAX(y-1, 0), LCD_WIDTH, 2); | 117 | rb->lcd_update_rect(0, MAX(y-1, 0), LCD_WIDTH, 2); |
121 | 118 | ||
122 | /* There are two mechanisms to alter speed: | 119 | /* There are two mechanisms to alter speed: |
123 | 1.) slowing down is achieved by increasing | 120 | 1.) slowing down is achieved by increasing |
124 | the time waiting for user input. This | 121 | the time waiting for user input. This |
125 | mechanism uses positive values. | 122 | mechanism uses positive values. |
126 | 2.) speeding up is achieved by leaving out | 123 | 2.) speeding up is achieved by leaving out |
127 | the user input check for (-speed) volume | 124 | the user input check for (-speed) volume |
128 | samples. For this mechanism negative values | 125 | samples. For this mechanism negative values |
129 | are used. | 126 | are used. |
130 | */ | 127 | */ |
131 | 128 | ||
132 | if (speed >= 0 || ((speed < 0) && (y % (-speed) == 0))) { | 129 | if (speed >= 0 || ((speed < 0) && (y % (-speed) == 0))) { |
@@ -138,7 +135,7 @@ bool oscillograph(void) | |||
138 | it must be ensured that at least 1 is passed. */ | 135 | it must be ensured that at least 1 is passed. */ |
139 | 136 | ||
140 | /* react to user input */ | 137 | /* react to user input */ |
141 | switch (button_get_w_tmo(MAX(speed, 1))) { | 138 | switch (rb->button_get_w_tmo(MAX(speed, 1))) { |
142 | case BUTTON_UP: | 139 | case BUTTON_UP: |
143 | speed++; | 140 | speed++; |
144 | draw = true; | 141 | draw = true; |
@@ -151,7 +148,7 @@ bool oscillograph(void) | |||
151 | 148 | ||
152 | case BUTTON_PLAY: | 149 | case BUTTON_PLAY: |
153 | /* pause the demo */ | 150 | /* pause the demo */ |
154 | button_get(true); | 151 | rb->button_get(true); |
155 | break; | 152 | break; |
156 | 153 | ||
157 | case BUTTON_F1: | 154 | case BUTTON_F1: |
@@ -170,7 +167,7 @@ bool oscillograph(void) | |||
170 | That produces ugly results in DRAW_MODE_OUTLINE | 167 | That produces ugly results in DRAW_MODE_OUTLINE |
171 | mode. If rolling is enabled this change will | 168 | mode. If rolling is enabled this change will |
172 | be reverted before the next update anyway.*/ | 169 | be reverted before the next update anyway.*/ |
173 | lcd_roll(0); | 170 | rb->lcd_roll(0); |
174 | break; | 171 | break; |
175 | 172 | ||
176 | case BUTTON_F3: | 173 | case BUTTON_F3: |
@@ -181,27 +178,30 @@ bool oscillograph(void) | |||
181 | case BUTTON_OFF: | 178 | case BUTTON_OFF: |
182 | exit = true; | 179 | exit = true; |
183 | break; | 180 | break; |
181 | |||
182 | case SYS_USB_CONNECTED: | ||
183 | rb->usb_screen(); | ||
184 | return PLUGIN_USB_CONNECTED; | ||
184 | } | 185 | } |
185 | 186 | ||
186 | if (draw) { | 187 | if (draw) { |
187 | char buf[16]; | 188 | char buf[16]; |
188 | snprintf(buf, sizeof buf, "Speed: %d", -speed); | 189 | rb->snprintf(buf, sizeof buf, "Speed: %d", -speed); |
189 | lcd_putsxy(0, (y + LCD_HEIGHT - 8) % LCD_HEIGHT, buf); | 190 | rb->lcd_putsxy(0, (y + LCD_HEIGHT - 8) % LCD_HEIGHT, buf); |
190 | lcd_update_rect(0, (y + LCD_HEIGHT - 8) % LCD_HEIGHT, | 191 | rb->lcd_update_rect(0, (y + LCD_HEIGHT - 8) % LCD_HEIGHT, |
191 | LCD_WIDTH, 8); | 192 | LCD_WIDTH, 8); |
192 | } | 193 | } |
193 | } | 194 | } |
194 | } | 195 | } |
195 | 196 | ||
196 | /* restore to default roll position. | 197 | /* restore to default roll position. |
197 | Looks funny if you forget to do this... */ | 198 | Looks funny if you forget to do this... */ |
198 | lcd_roll(0); | 199 | rb->lcd_roll(0); |
199 | lcd_update(); | 200 | rb->lcd_update(); |
200 | 201 | ||
201 | /* standard return */ | 202 | /* standard return */ |
202 | return false; | 203 | return PLUGIN_OK; |
203 | } | 204 | } |
204 | 205 | ||
205 | #endif /* #ifndef SIMULATOR */ | 206 | #endif /* #ifndef SIMULATOR */ |
206 | 207 | #endif | |
207 | |||
diff --git a/apps/plugins/plugin.lds b/apps/plugins/plugin.lds new file mode 100644 index 0000000000..be6b6fd0a6 --- /dev/null +++ b/apps/plugins/plugin.lds | |||
@@ -0,0 +1,26 @@ | |||
1 | OUTPUT_FORMAT(elf32-sh) | ||
2 | |||
3 | MEMORY | ||
4 | { | ||
5 | PLUGIN_RAM : ORIGIN = 0x091f8000, LENGTH = 0x8000 | ||
6 | } | ||
7 | |||
8 | SECTIONS | ||
9 | { | ||
10 | .text : { | ||
11 | *(.entry) | ||
12 | *(.text) | ||
13 | } > PLUGIN_RAM | ||
14 | |||
15 | .data : { | ||
16 | *(.data) | ||
17 | } > PLUGIN_RAM | ||
18 | |||
19 | .bss : { | ||
20 | *(.bss) | ||
21 | } > PLUGIN_RAM | ||
22 | |||
23 | .rodata : { | ||
24 | *(.rodata) | ||
25 | } > PLUGIN_RAM | ||
26 | } | ||
diff --git a/apps/recorder/snow.c b/apps/plugins/snow.c index c4e952f21d..df9966eb38 100644 --- a/apps/recorder/snow.c +++ b/apps/plugins/snow.c | |||
@@ -15,17 +15,15 @@ | |||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | 15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY |
16 | * KIND, either express or implied. | 16 | * KIND, either express or implied. |
17 | * | 17 | * |
18 | ****************************************************************************/ | 18 | **************************************************************************/ |
19 | #include <stdlib.h> | 19 | #include "plugin.h" |
20 | #include "lcd.h" | 20 | |
21 | #include "config.h" | 21 | #ifdef HAVE_LCD_BITMAP |
22 | #include "kernel.h" | ||
23 | #include "menu.h" | ||
24 | #include "button.h" | ||
25 | 22 | ||
26 | #define NUM_PARTICLES 100 | 23 | #define NUM_PARTICLES 100 |
27 | 24 | ||
28 | static short particles[NUM_PARTICLES][2]; | 25 | static short particles[NUM_PARTICLES][2]; |
26 | static struct plugin_api* rb; | ||
29 | 27 | ||
30 | static bool particle_exists(int particle) | 28 | static bool particle_exists(int particle) |
31 | { | 29 | { |
@@ -42,7 +40,7 @@ static int create_particle(void) | |||
42 | 40 | ||
43 | for (i=0; i<NUM_PARTICLES; i++) { | 41 | for (i=0; i<NUM_PARTICLES; i++) { |
44 | if (!particle_exists(i)) { | 42 | if (!particle_exists(i)) { |
45 | particles[i][0]=(rand()%112); | 43 | particles[i][0]=(rb->rand()%112); |
46 | particles[i][1]=0; | 44 | particles[i][1]=0; |
47 | return i; | 45 | return i; |
48 | } | 46 | } |
@@ -54,13 +52,13 @@ static void snow_move(void) | |||
54 | { | 52 | { |
55 | int i; | 53 | int i; |
56 | 54 | ||
57 | if (!(rand()%2)) | 55 | if (!(rb->rand()%2)) |
58 | create_particle(); | 56 | create_particle(); |
59 | 57 | ||
60 | for (i=0; i<NUM_PARTICLES; i++) { | 58 | for (i=0; i<NUM_PARTICLES; i++) { |
61 | if (particle_exists(i)) { | 59 | if (particle_exists(i)) { |
62 | lcd_clearpixel(particles[i][0],particles[i][1]); | 60 | rb->lcd_clearpixel(particles[i][0],particles[i][1]); |
63 | switch ((rand()%7)) { | 61 | switch ((rb->rand()%7)) { |
64 | case 0: | 62 | case 0: |
65 | particles[i][0]++; | 63 | particles[i][0]++; |
66 | break; | 64 | break; |
@@ -77,7 +75,7 @@ static void snow_move(void) | |||
77 | break; | 75 | break; |
78 | } | 76 | } |
79 | if (particle_exists(i)) | 77 | if (particle_exists(i)) |
80 | lcd_drawpixel(particles[i][0],particles[i][1]); | 78 | rb->lcd_drawpixel(particles[i][0],particles[i][1]); |
81 | } | 79 | } |
82 | } | 80 | } |
83 | } | 81 | } |
@@ -90,28 +88,24 @@ static void snow_init(void) | |||
90 | particles[i][0]=-1; | 88 | particles[i][0]=-1; |
91 | particles[i][1]=-1; | 89 | particles[i][1]=-1; |
92 | } | 90 | } |
93 | lcd_clear_display(); | 91 | rb->lcd_clear_display(); |
94 | } | 92 | } |
95 | 93 | ||
96 | bool snow(void) | 94 | enum plugin_status plugin_start(struct plugin_api* api, void* parameter) |
97 | { | 95 | { |
98 | snow_init(); | 96 | TEST_PLUGIN_API(api); |
97 | (void)(parameter); | ||
98 | rb = api; | ||
99 | 99 | ||
100 | snow_init(); | ||
100 | while (1) { | 101 | while (1) { |
101 | snow_move(); | 102 | snow_move(); |
102 | lcd_update(); | 103 | rb->lcd_update(); |
103 | sleep(HZ/20); | 104 | rb->sleep(HZ/20); |
104 | 105 | ||
105 | if (button_get(false) == BUTTON_OFF) | 106 | if (rb->button_get(false) == BUTTON_OFF) |
106 | return false; | 107 | return false; |
107 | } | 108 | } |
108 | } | 109 | } |
109 | 110 | ||
110 | 111 | #endif | |
111 | |||
112 | |||
113 | |||
114 | |||
115 | |||
116 | |||
117 | |||
diff --git a/apps/plugins/sokoban.c b/apps/plugins/sokoban.c new file mode 100644 index 0000000000..2387fa9517 --- /dev/null +++ b/apps/plugins/sokoban.c | |||
@@ -0,0 +1,868 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 Eric Linenberg | ||
11 | * February 2003: Robert Hak performs a cleanup/rewrite/feature addition. | ||
12 | * Eric smiles. Bjorn cries. Linus say 'huh?'. | ||
13 | * | ||
14 | * All files in this archive are subject to the GNU General Public License. | ||
15 | * See the file COPYING in the source tree root for full license agreement. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #include "plugin.h" | ||
22 | |||
23 | #ifdef HAVE_LCD_BITMAP | ||
24 | |||
25 | #define SOKOBAN_TITLE "Sokoban" | ||
26 | #define SOKOBAN_TITLE_FONT 2 | ||
27 | |||
28 | #define LEVELS_FILE "/.rockbox/sokoban/levels.txt" | ||
29 | |||
30 | #define ROWS 16 | ||
31 | #define COLS 20 | ||
32 | #define MAX_UNDOS 5 | ||
33 | |||
34 | #define SOKOBAN_LEVEL_SIZE (ROWS*COLS) | ||
35 | |||
36 | static void init_undo(void); | ||
37 | static void undo(void); | ||
38 | static void add_undo(int button); | ||
39 | |||
40 | static int get_level(char *level, int level_size); | ||
41 | static int get_level_count(void); | ||
42 | static int load_level(void); | ||
43 | static void draw_level(void); | ||
44 | |||
45 | static void init_boards(void); | ||
46 | static void update_screen(void); | ||
47 | static bool sokoban_loop(void); | ||
48 | |||
49 | /* The Location, Undo and LevelInfo structs are OO-flavored. | ||
50 | * (oooh!-flavored as Schnueff puts it.) It makes more you have to know, | ||
51 | * but the overall data layout becomes more manageable. */ | ||
52 | |||
53 | /* We use the same three values in 2 structs. Makeing them a struct | ||
54 | * hopefully ensures that if you change things in one, the other changes | ||
55 | * as well. */ | ||
56 | struct LevelInfo { | ||
57 | short level; | ||
58 | short moves; | ||
59 | short boxes_to_go; | ||
60 | }; | ||
61 | |||
62 | /* What a given location on the board looks like at a given time */ | ||
63 | struct Location { | ||
64 | char spot; | ||
65 | short row; | ||
66 | short col; | ||
67 | }; | ||
68 | |||
69 | /* A single level of undo. Each undo move can affect upto, | ||
70 | * but not more then, 3 spots on the board */ | ||
71 | struct Undo { | ||
72 | struct LevelInfo level; | ||
73 | struct Location location[3]; | ||
74 | }; | ||
75 | |||
76 | /* Our full undo history */ | ||
77 | static struct UndoInfo { | ||
78 | short count; /* How many undos are there in history */ | ||
79 | short current; /* Which history is the current undo */ | ||
80 | struct Undo history[MAX_UNDOS]; | ||
81 | } undo_info; | ||
82 | |||
83 | /* Our playing board */ | ||
84 | static struct BoardInfo { | ||
85 | char board[ROWS][COLS]; | ||
86 | struct LevelInfo level; | ||
87 | struct Location player; | ||
88 | int max_level; /* How many levels do we have? */ | ||
89 | int level_offset; /* Where in the level file is this level */ | ||
90 | int loaded_level; /* Which level is in memory */ | ||
91 | } current_info; | ||
92 | |||
93 | static struct plugin_api* rb; | ||
94 | |||
95 | static void init_undo(void) | ||
96 | { | ||
97 | undo_info.count = 0; | ||
98 | undo_info.current = 0; | ||
99 | } | ||
100 | |||
101 | static void undo(void) | ||
102 | { | ||
103 | struct Undo *undo; | ||
104 | int i = 0; | ||
105 | short row, col; | ||
106 | |||
107 | if (undo_info.count == 0) | ||
108 | return; | ||
109 | |||
110 | /* Update board info */ | ||
111 | undo = &undo_info.history[undo_info.current]; | ||
112 | |||
113 | rb->memcpy(¤t_info.level, &undo->level, sizeof(undo->level)); | ||
114 | rb->memcpy(¤t_info.player, &undo->location[0], sizeof(undo->location[0])); | ||
115 | |||
116 | row = undo->location[0].row; | ||
117 | col = undo->location[0].col; | ||
118 | current_info.board[row][col] = '@'; | ||
119 | |||
120 | /* Update the two other possible spots */ | ||
121 | for (i = 1; i < 3; i++) { | ||
122 | if (undo->location[i].spot != '\0') { | ||
123 | row = undo->location[i].row; | ||
124 | col = undo->location[i].col; | ||
125 | current_info.board[row][col] = undo->location[i].spot; | ||
126 | undo->location[i].spot = '\0'; | ||
127 | } | ||
128 | } | ||
129 | |||
130 | /* Remove this undo from the list */ | ||
131 | if (undo_info.current == 0) { | ||
132 | if (undo_info.count > 1) | ||
133 | undo_info.current = MAX_UNDOS - 1; | ||
134 | } else { | ||
135 | undo_info.current--; | ||
136 | } | ||
137 | |||
138 | undo_info.count--; | ||
139 | |||
140 | return; | ||
141 | } | ||
142 | |||
143 | static void add_undo(int button) | ||
144 | { | ||
145 | struct Undo *undo; | ||
146 | int row, col, i; | ||
147 | bool storable; | ||
148 | |||
149 | if ((button != BUTTON_LEFT) && (button != BUTTON_RIGHT) && | ||
150 | (button != BUTTON_UP) && (button != BUTTON_DOWN)) | ||
151 | return; | ||
152 | |||
153 | if (undo_info.count != 0) { | ||
154 | if (undo_info.current < (MAX_UNDOS - 1)) | ||
155 | undo_info.current++; | ||
156 | else | ||
157 | undo_info.current = 0; | ||
158 | } | ||
159 | |||
160 | /* Make what follows more readable */ | ||
161 | undo = &undo_info.history[undo_info.current]; | ||
162 | |||
163 | /* Store our level info */ | ||
164 | rb->memcpy(&undo->level, ¤t_info.level, sizeof(undo->level)); | ||
165 | |||
166 | /* Store our player info */ | ||
167 | rb->memcpy(&undo->location[0], ¤t_info.player, sizeof(undo->location[0])); | ||
168 | |||
169 | /* Now we need to store upto 2 blocks that may be affected. | ||
170 | * If player.spot is NULL, then there is no info stored | ||
171 | * for that block */ | ||
172 | |||
173 | row = current_info.player.row; | ||
174 | col = current_info.player.col; | ||
175 | |||
176 | /* This must stay as _1_ because the first block (0) is the player */ | ||
177 | for (i = 1; i < 3; i++) { | ||
178 | storable = true; | ||
179 | |||
180 | switch (button) { | ||
181 | case BUTTON_LEFT: | ||
182 | col--; | ||
183 | if (col < 0) | ||
184 | storable = false; | ||
185 | break; | ||
186 | |||
187 | case BUTTON_RIGHT: | ||
188 | col++; | ||
189 | if (col >= COLS) | ||
190 | storable = false; | ||
191 | break; | ||
192 | |||
193 | case BUTTON_UP: | ||
194 | row--; | ||
195 | if (row < 0) | ||
196 | storable = false; | ||
197 | break; | ||
198 | |||
199 | case BUTTON_DOWN: | ||
200 | row++; | ||
201 | if (row >= ROWS) | ||
202 | storable = false; | ||
203 | break; | ||
204 | |||
205 | default: | ||
206 | return; | ||
207 | } | ||
208 | |||
209 | if (storable) { | ||
210 | undo->location[i].col = col; | ||
211 | undo->location[i].row = row; | ||
212 | undo->location[i].spot = current_info.board[row][col]; | ||
213 | } else { | ||
214 | undo->location[i].spot = '\0'; | ||
215 | } | ||
216 | } | ||
217 | |||
218 | if (undo_info.count < MAX_UNDOS) | ||
219 | undo_info.count++; | ||
220 | } | ||
221 | |||
222 | static void init_boards(void) | ||
223 | { | ||
224 | current_info.level.level = 0; | ||
225 | current_info.level.moves = 0; | ||
226 | current_info.level.boxes_to_go = 0; | ||
227 | current_info.player.row = 0; | ||
228 | current_info.player.col = 0; | ||
229 | current_info.player.spot = ' '; | ||
230 | current_info.max_level = 0; | ||
231 | current_info.level_offset = 0; | ||
232 | current_info.loaded_level = 0; | ||
233 | |||
234 | init_undo(); | ||
235 | } | ||
236 | |||
237 | static int get_level_count(void) | ||
238 | { | ||
239 | int fd = 0; | ||
240 | int lastlen = 0; | ||
241 | char buffer[COLS + 3]; /* COLS plus CR/LF and \0 */ | ||
242 | |||
243 | if ((fd = rb->open(LEVELS_FILE, O_RDONLY)) < 0) { | ||
244 | rb->splash(0, 0, true, "Unable to open %s", LEVELS_FILE); | ||
245 | return -1; | ||
246 | } | ||
247 | |||
248 | while(1) { | ||
249 | int len = rb->read_line(fd, buffer, sizeof(buffer)); | ||
250 | if(len <= 0) | ||
251 | break; | ||
252 | |||
253 | /* Two short lines in a row means new level */ | ||
254 | if(len < 3 && lastlen < 3) | ||
255 | current_info.max_level++; | ||
256 | |||
257 | lastlen = len; | ||
258 | } | ||
259 | |||
260 | rb->close(fd); | ||
261 | return 0; | ||
262 | } | ||
263 | |||
264 | static int get_level(char *level, int level_size) | ||
265 | { | ||
266 | int fd = 0, i = 0; | ||
267 | int nread = 0; | ||
268 | int count = 0; | ||
269 | int lastlen = 0; | ||
270 | int level_ct = 1; | ||
271 | unsigned char buffer[SOKOBAN_LEVEL_SIZE * 2]; | ||
272 | bool level_found = false; | ||
273 | |||
274 | /* open file */ | ||
275 | if ((fd = rb->open(LEVELS_FILE, O_RDONLY)) < 0) | ||
276 | return -1; | ||
277 | |||
278 | /* Lets not reparse the full file if we can avoid it */ | ||
279 | if (current_info.loaded_level < current_info.level.level) { | ||
280 | rb->lseek(fd, current_info.level_offset, SEEK_SET); | ||
281 | level_ct = current_info.loaded_level; | ||
282 | } | ||
283 | |||
284 | if(current_info.level.level > 1) { | ||
285 | while(!level_found) { | ||
286 | int len = rb->read_line(fd, buffer, SOKOBAN_LEVEL_SIZE); | ||
287 | if(len <= 0) { | ||
288 | rb->close(fd); | ||
289 | return -1; | ||
290 | } | ||
291 | |||
292 | /* Two short lines in a row means new level */ | ||
293 | if(len < 3 && lastlen < 3) { | ||
294 | level_ct++; | ||
295 | if(level_ct == current_info.level.level) | ||
296 | level_found = true; | ||
297 | } | ||
298 | lastlen = len; | ||
299 | } | ||
300 | } | ||
301 | |||
302 | /* Remember the current offset */ | ||
303 | current_info.level_offset = rb->lseek(fd, 0, SEEK_CUR); | ||
304 | |||
305 | /* read a full buffer chunk from here */ | ||
306 | nread = rb->read(fd, buffer, sizeof(buffer)-1); | ||
307 | if (nread < 0) | ||
308 | return -1; | ||
309 | buffer[nread] = 0; | ||
310 | |||
311 | rb->close(fd); | ||
312 | |||
313 | /* If we read less then a level, error */ | ||
314 | if (nread < level_size) | ||
315 | return -1; | ||
316 | |||
317 | /* Load our new level */ | ||
318 | for(i=0, count=0; (count < nread) && (i<level_size);) { | ||
319 | if (buffer[count] != '\n' && buffer[count] != '\r') | ||
320 | level[i++] = buffer[count]; | ||
321 | count++; | ||
322 | } | ||
323 | level[i] = 0; | ||
324 | |||
325 | current_info.loaded_level = current_info.level.level; | ||
326 | return 0; | ||
327 | } | ||
328 | |||
329 | /* return non-zero on error */ | ||
330 | static int load_level(void) | ||
331 | { | ||
332 | short c = 0; | ||
333 | short r = 0; | ||
334 | short i = 0; | ||
335 | char level[ROWS*COLS+1]; | ||
336 | int x = 0; | ||
337 | |||
338 | current_info.player.spot=' '; | ||
339 | current_info.level.boxes_to_go = 0; | ||
340 | current_info.level.moves = 0; | ||
341 | |||
342 | if (get_level(level, sizeof(level)) != 0) | ||
343 | return -1; | ||
344 | |||
345 | i = 0; | ||
346 | for (r = 0; r < ROWS; r++) { | ||
347 | x++; | ||
348 | for (c = 0; c < COLS; c++, i++) { | ||
349 | current_info.board[r][c] = level[i]; | ||
350 | |||
351 | if (current_info.board[r][c] == '.') | ||
352 | current_info.level.boxes_to_go++; | ||
353 | |||
354 | else if (current_info.board[r][c] == '@') { | ||
355 | current_info.player.row = r; | ||
356 | current_info.player.col = c; | ||
357 | } | ||
358 | } | ||
359 | } | ||
360 | |||
361 | return 0; | ||
362 | } | ||
363 | |||
364 | static void update_screen(void) | ||
365 | { | ||
366 | short b = 0, c = 0; | ||
367 | short rows = 0, cols = 0; | ||
368 | char s[25]; | ||
369 | |||
370 | short magnify = 4; | ||
371 | |||
372 | /* load the board to the screen */ | ||
373 | for (rows=0 ; rows < ROWS ; rows++) { | ||
374 | for (cols = 0 ; cols < COLS ; cols++) { | ||
375 | c = cols * magnify; | ||
376 | b = rows * magnify; | ||
377 | |||
378 | switch(current_info.board[rows][cols]) { | ||
379 | case 'X': /* black space */ | ||
380 | rb->lcd_drawrect(c, b, magnify, magnify); | ||
381 | rb->lcd_drawrect(c+1, b+1, 2, 2); | ||
382 | break; | ||
383 | |||
384 | case '#': /* this is a wall */ | ||
385 | rb->lcd_drawpixel(c, b); | ||
386 | rb->lcd_drawpixel(c+2, b); | ||
387 | rb->lcd_drawpixel(c+1, b+1); | ||
388 | rb->lcd_drawpixel(c+3, b+1); | ||
389 | rb->lcd_drawpixel(c, b+2); | ||
390 | rb->lcd_drawpixel(c+2, b+2); | ||
391 | rb->lcd_drawpixel(c+1, b+3); | ||
392 | rb->lcd_drawpixel(c+3, b+3); | ||
393 | break; | ||
394 | |||
395 | case '.': /* this is a home location */ | ||
396 | rb->lcd_drawrect(c+1, b+1, 2, 2); | ||
397 | break; | ||
398 | |||
399 | case '$': /* this is a box */ | ||
400 | rb->lcd_drawrect(c, b, magnify, magnify); | ||
401 | break; | ||
402 | |||
403 | case '@': /* this is you */ | ||
404 | rb->lcd_drawline(c+1, b, c+2, b); | ||
405 | rb->lcd_drawline(c, b+1, c+3, b+1); | ||
406 | rb->lcd_drawline(c+1, b+2, c+2, b+2); | ||
407 | |||
408 | rb->lcd_drawpixel(c, b+3); | ||
409 | rb->lcd_drawpixel(c+3, b+3); | ||
410 | break; | ||
411 | |||
412 | case '%': /* this is a box on a home spot */ | ||
413 | rb->lcd_drawrect(c, b, magnify, magnify); | ||
414 | rb->lcd_drawrect(c+1, b+1, 2, 2); | ||
415 | break; | ||
416 | } | ||
417 | } | ||
418 | } | ||
419 | |||
420 | |||
421 | rb->snprintf(s, sizeof(s), "%d", current_info.level.level); | ||
422 | rb->lcd_putsxy(86, 22, s); | ||
423 | rb->snprintf(s, sizeof(s), "%d", current_info.level.moves); | ||
424 | rb->lcd_putsxy(86, 54, s); | ||
425 | |||
426 | rb->lcd_drawrect(80,0,32,32); | ||
427 | rb->lcd_drawrect(80,32,32,64); | ||
428 | rb->lcd_putsxy(81, 10, "Level"); | ||
429 | rb->lcd_putsxy(81, 42, "Moves"); | ||
430 | |||
431 | /* print out the screen */ | ||
432 | rb->lcd_update(); | ||
433 | } | ||
434 | |||
435 | static void draw_level(void) | ||
436 | { | ||
437 | load_level(); | ||
438 | rb->lcd_clear_display(); | ||
439 | update_screen(); | ||
440 | } | ||
441 | |||
442 | static bool sokoban_loop(void) | ||
443 | { | ||
444 | char new_spot; | ||
445 | bool moved = true; | ||
446 | int i = 0, button = 0; | ||
447 | short r = 0, c = 0; | ||
448 | |||
449 | current_info.level.level = 1; | ||
450 | |||
451 | load_level(); | ||
452 | update_screen(); | ||
453 | |||
454 | while (1) { | ||
455 | moved = true; | ||
456 | |||
457 | r = current_info.player.row; | ||
458 | c = current_info.player.col; | ||
459 | |||
460 | button = rb->button_get(true); | ||
461 | |||
462 | add_undo(button); | ||
463 | |||
464 | switch(button) | ||
465 | { | ||
466 | case BUTTON_OFF: | ||
467 | /* get out of here */ | ||
468 | return PLUGIN_OK; | ||
469 | |||
470 | case BUTTON_ON: | ||
471 | case BUTTON_ON | BUTTON_REPEAT: | ||
472 | /* this is UNDO */ | ||
473 | undo(); | ||
474 | rb->lcd_clear_display(); | ||
475 | update_screen(); | ||
476 | moved = false; | ||
477 | break; | ||
478 | |||
479 | case BUTTON_F3: | ||
480 | case BUTTON_F3 | BUTTON_REPEAT: | ||
481 | /* increase level */ | ||
482 | init_undo(); | ||
483 | current_info.level.boxes_to_go=0; | ||
484 | moved = true; | ||
485 | break; | ||
486 | |||
487 | case BUTTON_F1: | ||
488 | case BUTTON_F1 | BUTTON_REPEAT: | ||
489 | /* previous level */ | ||
490 | init_undo(); | ||
491 | if (current_info.level.level > 1) | ||
492 | current_info.level.level--; | ||
493 | |||
494 | draw_level(); | ||
495 | moved = false; | ||
496 | break; | ||
497 | |||
498 | case BUTTON_F2: | ||
499 | case BUTTON_F2 | BUTTON_REPEAT: | ||
500 | /* same level */ | ||
501 | init_undo(); | ||
502 | draw_level(); | ||
503 | moved = false; | ||
504 | break; | ||
505 | |||
506 | case BUTTON_LEFT: | ||
507 | switch(current_info.board[r][c-1]) | ||
508 | { | ||
509 | case ' ': /* if it is a blank spot */ | ||
510 | case '.': /* if it is a home spot */ | ||
511 | new_spot = current_info.board[r][c-1]; | ||
512 | current_info.board[r][c-1] = '@'; | ||
513 | current_info.board[r][c] = current_info.player.spot; | ||
514 | current_info.player.spot = new_spot; | ||
515 | break; | ||
516 | |||
517 | case '$': | ||
518 | switch(current_info.board[r][c-2]) | ||
519 | { | ||
520 | case ' ': /* going from blank to blank */ | ||
521 | current_info.board[r][c-2] = current_info.board[r][c-1]; | ||
522 | current_info.board[r][c-1] = current_info.board[r][c]; | ||
523 | current_info.board[r][c] = current_info.player.spot; | ||
524 | current_info.player.spot = ' '; | ||
525 | break; | ||
526 | |||
527 | case '.': /* going from a blank to home */ | ||
528 | current_info.board[r][c-2] = '%'; | ||
529 | current_info.board[r][c-1] = current_info.board[r][c]; | ||
530 | current_info.board[r][c] = current_info.player.spot; | ||
531 | current_info.player.spot = ' '; | ||
532 | current_info.level.boxes_to_go--; | ||
533 | break; | ||
534 | |||
535 | default: | ||
536 | moved = false; | ||
537 | break; | ||
538 | } | ||
539 | break; | ||
540 | |||
541 | case '%': | ||
542 | switch(current_info.board[r][c-2]) { | ||
543 | case ' ': /* we are going from a home to a blank */ | ||
544 | current_info.board[r][c-2] = '$'; | ||
545 | current_info.board[r][c-1] = current_info.board[r][c]; | ||
546 | current_info.board[r][c] = current_info.player.spot; | ||
547 | current_info.player.spot = '.'; | ||
548 | current_info.level.boxes_to_go++; | ||
549 | break; | ||
550 | |||
551 | case '.': /* if we are going from a home to home */ | ||
552 | current_info.board[r][c-2] = '%'; | ||
553 | current_info.board[r][c-1] = current_info.board[r][c]; | ||
554 | current_info.board[r][c] = current_info.player.spot; | ||
555 | current_info.player.spot = '.'; | ||
556 | break; | ||
557 | |||
558 | default: | ||
559 | moved = false; | ||
560 | break; | ||
561 | } | ||
562 | break; | ||
563 | |||
564 | default: | ||
565 | moved = false; | ||
566 | break; | ||
567 | } | ||
568 | |||
569 | if (moved) | ||
570 | current_info.player.col--; | ||
571 | break; | ||
572 | |||
573 | case BUTTON_RIGHT: /* if it is a blank spot */ | ||
574 | switch(current_info.board[r][c+1]) { | ||
575 | case ' ': | ||
576 | case '.': /* if it is a home spot */ | ||
577 | new_spot = current_info.board[r][c+1]; | ||
578 | current_info.board[r][c+1] = '@'; | ||
579 | current_info.board[r][c] = current_info.player.spot; | ||
580 | current_info.player.spot = new_spot; | ||
581 | break; | ||
582 | |||
583 | case '$': | ||
584 | switch(current_info.board[r][c+2]) { | ||
585 | case ' ': /* going from blank to blank */ | ||
586 | current_info.board[r][c+2] = current_info.board[r][c+1]; | ||
587 | current_info.board[r][c+1] = current_info.board[r][c]; | ||
588 | current_info.board[r][c] = current_info.player.spot; | ||
589 | current_info.player.spot = ' '; | ||
590 | break; | ||
591 | |||
592 | case '.': /* going from a blank to home */ | ||
593 | current_info.board[r][c+2] = '%'; | ||
594 | current_info.board[r][c+1] = current_info.board[r][c]; | ||
595 | current_info.board[r][c] = current_info.player.spot; | ||
596 | current_info.player.spot = ' '; | ||
597 | current_info.level.boxes_to_go--; | ||
598 | break; | ||
599 | |||
600 | default: | ||
601 | moved = false; | ||
602 | break; | ||
603 | } | ||
604 | break; | ||
605 | |||
606 | case '%': | ||
607 | switch(current_info.board[r][c+2]) { | ||
608 | case ' ': /* going from a home to a blank */ | ||
609 | current_info.board[r][c+2] = '$'; | ||
610 | current_info.board[r][c+1] = current_info.board[r][c]; | ||
611 | current_info.board[r][c] = current_info.player.spot; | ||
612 | current_info.player.spot = '.'; | ||
613 | current_info.level.boxes_to_go++; | ||
614 | break; | ||
615 | |||
616 | case '.': | ||
617 | current_info.board[r][c+2] = '%'; | ||
618 | current_info.board[r][c+1] = current_info.board[r][c]; | ||
619 | current_info.board[r][c] = current_info.player.spot; | ||
620 | current_info.player.spot = '.'; | ||
621 | break; | ||
622 | |||
623 | default: | ||
624 | moved = false; | ||
625 | break; | ||
626 | } | ||
627 | break; | ||
628 | |||
629 | default: | ||
630 | moved = false; | ||
631 | break; | ||
632 | } | ||
633 | |||
634 | if (moved) | ||
635 | current_info.player.col++; | ||
636 | break; | ||
637 | |||
638 | case BUTTON_UP: | ||
639 | switch(current_info.board[r-1][c]) { | ||
640 | case ' ': /* if it is a blank spot */ | ||
641 | case '.': /* if it is a home spot */ | ||
642 | new_spot = current_info.board[r-1][c]; | ||
643 | current_info.board[r-1][c] = '@'; | ||
644 | current_info.board[r][c] = current_info.player.spot; | ||
645 | current_info.player.spot = new_spot; | ||
646 | break; | ||
647 | |||
648 | case '$': | ||
649 | switch(current_info.board[r-2][c]) { | ||
650 | case ' ': /* going from blank to blank */ | ||
651 | current_info.board[r-2][c] = current_info.board[r-1][c]; | ||
652 | current_info.board[r-1][c] = current_info.board[r][c]; | ||
653 | current_info.board[r][c] = current_info.player.spot; | ||
654 | current_info.player.spot = ' '; | ||
655 | break; | ||
656 | |||
657 | case '.': /* going from a blank to home */ | ||
658 | current_info.board[r-2][c] = '%'; | ||
659 | current_info.board[r-1][c] = current_info.board[r][c]; | ||
660 | current_info.board[r][c] = current_info.player.spot; | ||
661 | current_info.player.spot = ' '; | ||
662 | current_info.level.boxes_to_go--; | ||
663 | break; | ||
664 | |||
665 | default: | ||
666 | moved = false; | ||
667 | break; | ||
668 | } | ||
669 | break; | ||
670 | |||
671 | case '%': | ||
672 | switch(current_info.board[r-2][c]) { | ||
673 | case ' ': /* we are going from a home to a blank */ | ||
674 | current_info.board[r-2][c] = '$'; | ||
675 | current_info.board[r-1][c] = current_info.board[r][c]; | ||
676 | current_info.board[r][c] = current_info.player.spot; | ||
677 | current_info.player.spot = '.'; | ||
678 | current_info.level.boxes_to_go++; | ||
679 | break; | ||
680 | |||
681 | case '.': /* if we are going from a home to home */ | ||
682 | current_info.board[r-2][c] = '%'; | ||
683 | current_info.board[r-1][c] = current_info.board[r][c]; | ||
684 | current_info.board[r][c] = current_info.player.spot; | ||
685 | current_info.player.spot = '.'; | ||
686 | break; | ||
687 | |||
688 | default: | ||
689 | moved = false; | ||
690 | break; | ||
691 | } | ||
692 | break; | ||
693 | |||
694 | default: | ||
695 | moved = false; | ||
696 | break; | ||
697 | } | ||
698 | |||
699 | if (moved) | ||
700 | current_info.player.row--; | ||
701 | break; | ||
702 | |||
703 | case BUTTON_DOWN: | ||
704 | switch(current_info.board[r+1][c]) { | ||
705 | case ' ': /* if it is a blank spot */ | ||
706 | case '.': /* if it is a home spot */ | ||
707 | new_spot = current_info.board[r+1][c]; | ||
708 | current_info.board[r+1][c] = '@'; | ||
709 | current_info.board[r][c] = current_info.player.spot; | ||
710 | current_info.player.spot = new_spot; | ||
711 | break; | ||
712 | |||
713 | case '$': | ||
714 | switch(current_info.board[r+2][c]) { | ||
715 | case ' ': /* going from blank to blank */ | ||
716 | current_info.board[r+2][c] = current_info.board[r+1][c]; | ||
717 | current_info.board[r+1][c] = current_info.board[r][c]; | ||
718 | current_info.board[r][c] = current_info.player.spot; | ||
719 | current_info.player.spot = ' '; | ||
720 | break; | ||
721 | |||
722 | case '.': /* going from a blank to home */ | ||
723 | current_info.board[r+2][c] = '%'; | ||
724 | current_info.board[r+1][c] = current_info.board[r][c]; | ||
725 | current_info.board[r][c] = current_info.player.spot; | ||
726 | current_info.player.spot = ' '; | ||
727 | current_info.level.boxes_to_go--; | ||
728 | break; | ||
729 | |||
730 | default: | ||
731 | moved = false; | ||
732 | break; | ||
733 | } | ||
734 | break; | ||
735 | |||
736 | case '%': | ||
737 | switch(current_info.board[r+2][c]) { | ||
738 | case ' ': /* going from a home to a blank */ | ||
739 | current_info.board[r+2][c] = '$'; | ||
740 | current_info.board[r+1][c] = current_info.board[r][c]; | ||
741 | current_info.board[r][c] = current_info.player.spot; | ||
742 | current_info.player.spot = '.'; | ||
743 | current_info.level.boxes_to_go++; | ||
744 | break; | ||
745 | |||
746 | case '.': /* going from a home to home */ | ||
747 | current_info.board[r+2][c] = '%'; | ||
748 | current_info.board[r+1][c] = current_info.board[r][c]; | ||
749 | current_info.board[r][c] = current_info.player.spot; | ||
750 | current_info.player.spot = '.'; | ||
751 | break; | ||
752 | |||
753 | default: | ||
754 | moved = false; | ||
755 | break; | ||
756 | } | ||
757 | break; | ||
758 | |||
759 | default: | ||
760 | moved = false; | ||
761 | break; | ||
762 | } | ||
763 | |||
764 | if (moved) | ||
765 | current_info.player.row++; | ||
766 | break; | ||
767 | |||
768 | case SYS_USB_CONNECTED: | ||
769 | rb->usb_screen(); | ||
770 | return PLUGIN_USB_CONNECTED; | ||
771 | |||
772 | default: | ||
773 | moved = false; | ||
774 | break; | ||
775 | } | ||
776 | |||
777 | if (moved) { | ||
778 | current_info.level.moves++; | ||
779 | rb->lcd_clear_display(); | ||
780 | update_screen(); | ||
781 | } | ||
782 | |||
783 | /* We have completed this level */ | ||
784 | if (current_info.level.boxes_to_go == 0) { | ||
785 | current_info.level.level++; | ||
786 | |||
787 | /* clear undo stats */ | ||
788 | init_undo(); | ||
789 | |||
790 | rb->lcd_clear_display(); | ||
791 | |||
792 | if (current_info.level.level > current_info.max_level) { | ||
793 | rb->lcd_putsxy(10, 20, "You WIN!!"); | ||
794 | |||
795 | for (i = 0; i < 30000 ; i++) { | ||
796 | rb->lcd_invertrect(0, 0, 111, 63); | ||
797 | rb->lcd_update(); | ||
798 | |||
799 | button = rb->button_get(false); | ||
800 | if (button && ((button & BUTTON_REL) != BUTTON_REL)) | ||
801 | break; | ||
802 | } | ||
803 | |||
804 | return PLUGIN_OK; | ||
805 | } | ||
806 | |||
807 | load_level(); | ||
808 | update_screen(); | ||
809 | } | ||
810 | |||
811 | } /* end while */ | ||
812 | |||
813 | return PLUGIN_OK; | ||
814 | } | ||
815 | |||
816 | |||
817 | enum plugin_status plugin_start(struct plugin_api* api, void* parameter) | ||
818 | { | ||
819 | int w, h; | ||
820 | int len; | ||
821 | |||
822 | TEST_PLUGIN_API(api); | ||
823 | (void)(parameter); | ||
824 | rb = api; | ||
825 | |||
826 | rb->lcd_setfont(FONT_SYSFIXED); | ||
827 | rb->lcd_getstringsize(SOKOBAN_TITLE, &w, &h); | ||
828 | |||
829 | /* Get horizontel centering for text */ | ||
830 | len = w; | ||
831 | if (len%2 != 0) | ||
832 | len =((len+1)/2)+(w/2); | ||
833 | else | ||
834 | len /= 2; | ||
835 | |||
836 | if (h%2 != 0) | ||
837 | h = (h/2)+1; | ||
838 | else | ||
839 | h /= 2; | ||
840 | |||
841 | rb->lcd_clear_display(); | ||
842 | rb->lcd_putsxy(LCD_WIDTH/2-len,(LCD_HEIGHT/2)-h, SOKOBAN_TITLE); | ||
843 | rb->lcd_update(); | ||
844 | rb->sleep(HZ*2); | ||
845 | |||
846 | rb->lcd_clear_display(); | ||
847 | |||
848 | rb->lcd_putsxy(3, 6, "[OFF] To Stop"); | ||
849 | rb->lcd_putsxy(3, 16, "[ON] To Undo"); | ||
850 | rb->lcd_putsxy(3, 26, "[F1] - Level"); | ||
851 | rb->lcd_putsxy(3, 36, "[F2] Same Level"); | ||
852 | rb->lcd_putsxy(3, 46, "[F3] + Level"); | ||
853 | |||
854 | rb->lcd_update(); | ||
855 | rb->sleep(HZ*2); | ||
856 | rb->lcd_clear_display(); | ||
857 | |||
858 | init_boards(); | ||
859 | |||
860 | if (get_level_count() != 0) { | ||
861 | rb->splash(HZ*2,0,true,"Failed loading levels!"); | ||
862 | return PLUGIN_OK; | ||
863 | } | ||
864 | |||
865 | return sokoban_loop(); | ||
866 | } | ||
867 | |||
868 | #endif | ||
diff --git a/apps/viewer.c b/apps/plugins/viewer.c index f653866626..f8dc309a6e 100644 --- a/apps/viewer.c +++ b/apps/plugins/viewer.c | |||
@@ -17,24 +17,9 @@ | |||
17 | * KIND, either express or implied. | 17 | * KIND, either express or implied. |
18 | * | 18 | * |
19 | ****************************************************************************/ | 19 | ****************************************************************************/ |
20 | #include <stdio.h> | 20 | #include "plugin.h" |
21 | #include <string.h> | ||
22 | #include <stdlib.h> | ||
23 | #include <stdbool.h> | ||
24 | |||
25 | #include "file.h" | ||
26 | #include "lcd.h" | ||
27 | #include "button.h" | ||
28 | #include "kernel.h" | ||
29 | #include "font.h" | ||
30 | #include "settings.h" | ||
31 | #include "icons.h" | ||
32 | #include "screens.h" | ||
33 | #include "status.h" | ||
34 | |||
35 | 21 | ||
36 | #define BUFFER_SIZE 1024 | 22 | #define BUFFER_SIZE 1024 |
37 | |||
38 | #define OUTSIDE_BUFFER -10 | 23 | #define OUTSIDE_BUFFER -10 |
39 | #define OUTSIDE_FILE -11 | 24 | #define OUTSIDE_FILE -11 |
40 | 25 | ||
@@ -50,6 +35,7 @@ static int begin_line; /* Index of the first line displayed on the lcd */ | |||
50 | static int end_line; /* Index of the last line displayed on the lcd */ | 35 | static int end_line; /* Index of the last line displayed on the lcd */ |
51 | static int begin_line_pos; /* Position of the first_line in the bufffer */ | 36 | static int begin_line_pos; /* Position of the first_line in the bufffer */ |
52 | static int end_line_pos; /* Position of the last_line in the buffer */ | 37 | static int end_line_pos; /* Position of the last_line in the buffer */ |
38 | static struct plugin_api* rb; | ||
53 | 39 | ||
54 | /* | 40 | /* |
55 | * Known issue: The caching algorithm will fail (display incoherent data) if | 41 | * Known issue: The caching algorithm will fail (display incoherent data) if |
@@ -61,7 +47,7 @@ static void display_line_count(void) | |||
61 | { | 47 | { |
62 | #ifdef HAVE_LCD_BITMAP | 48 | #ifdef HAVE_LCD_BITMAP |
63 | int w,h; | 49 | int w,h; |
64 | lcd_getstringsize("M", &w, &h); | 50 | rb->lcd_getstringsize("M", &w, &h); |
65 | display_lines = LCD_HEIGHT / h; | 51 | display_lines = LCD_HEIGHT / h; |
66 | display_columns = LCD_WIDTH / w; | 52 | display_columns = LCD_WIDTH / w; |
67 | #else | 53 | #else |
@@ -126,7 +112,7 @@ static void viewer_draw(int col) | |||
126 | char* str; | 112 | char* str; |
127 | int line_pos; | 113 | int line_pos; |
128 | 114 | ||
129 | lcd_clear_display(); | 115 | rb->lcd_clear_display(); |
130 | 116 | ||
131 | line_pos = begin_line_pos; | 117 | line_pos = begin_line_pos; |
132 | 118 | ||
@@ -137,11 +123,12 @@ static void viewer_draw(int col) | |||
137 | str = buffer + line_pos + 1; | 123 | str = buffer + line_pos + 1; |
138 | for (j=0; j<col && *str!=0; ++j) | 124 | for (j=0; j<col && *str!=0; ++j) |
139 | str++; | 125 | str++; |
140 | lcd_puts(0, i, str); | 126 | rb->lcd_puts(0, i, str); |
141 | line_pos = find_next_line(line_pos); | 127 | line_pos = find_next_line(line_pos); |
142 | } | 128 | } |
143 | 129 | #ifdef HAVE_LCD_BITMAP | |
144 | lcd_update(); | 130 | rb->lcd_update(); |
131 | #endif | ||
145 | } | 132 | } |
146 | 133 | ||
147 | static void fill_buffer(int pos) | 134 | static void fill_buffer(int pos) |
@@ -154,8 +141,8 @@ static void fill_buffer(int pos) | |||
154 | if (pos<0) | 141 | if (pos<0) |
155 | pos = 0; | 142 | pos = 0; |
156 | 143 | ||
157 | lseek(fd, pos, SEEK_SET); | 144 | rb->lseek(fd, pos, SEEK_SET); |
158 | numread = read(fd, buffer, BUFFER_SIZE); | 145 | numread = rb->read(fd, buffer, BUFFER_SIZE); |
159 | 146 | ||
160 | begin_line_pos -= pos - buffer_pos; | 147 | begin_line_pos -= pos - buffer_pos; |
161 | end_line_pos -= pos - buffer_pos; | 148 | end_line_pos -= pos - buffer_pos; |
@@ -181,11 +168,11 @@ static bool viewer_init(char* file) | |||
181 | int i; | 168 | int i; |
182 | int ret; | 169 | int ret; |
183 | 170 | ||
184 | fd = open(file, O_RDONLY); | 171 | fd = rb->open(file, O_RDONLY); |
185 | if (fd==-1) | 172 | if (fd==-1) |
186 | return false; | 173 | return false; |
187 | 174 | ||
188 | file_size = lseek(fd, 0, SEEK_END); | 175 | file_size = rb->lseek(fd, 0, SEEK_END); |
189 | 176 | ||
190 | buffer_pos = 0; | 177 | buffer_pos = 0; |
191 | begin_line = 0; | 178 | begin_line = 0; |
@@ -207,7 +194,7 @@ static bool viewer_init(char* file) | |||
207 | 194 | ||
208 | static void viewer_exit(void) | 195 | static void viewer_exit(void) |
209 | { | 196 | { |
210 | close(fd); | 197 | rb->close(fd); |
211 | } | 198 | } |
212 | 199 | ||
213 | static void viewer_scroll_down(void) | 200 | static void viewer_scroll_down(void) |
@@ -264,7 +251,7 @@ static int pagescroll(int col) | |||
264 | int i; | 251 | int i; |
265 | 252 | ||
266 | while (!exit) { | 253 | while (!exit) { |
267 | switch (button_get(true)) { | 254 | switch (rb->button_get(true)) { |
268 | #ifdef HAVE_RECORDER_KEYPAD | 255 | #ifdef HAVE_RECORDER_KEYPAD |
269 | case BUTTON_ON | BUTTON_UP: | 256 | case BUTTON_ON | BUTTON_UP: |
270 | case BUTTON_ON | BUTTON_UP | BUTTON_REPEAT: | 257 | case BUTTON_ON | BUTTON_UP | BUTTON_REPEAT: |
@@ -328,31 +315,30 @@ static int pagescroll(int col) | |||
328 | 315 | ||
329 | return col; | 316 | return col; |
330 | } | 317 | } |
331 | bool viewer_run(char* file) | 318 | |
319 | enum plugin_status plugin_start(struct plugin_api* api, void* file) | ||
332 | { | 320 | { |
333 | bool exit=false; | 321 | bool exit=false; |
334 | int button; | 322 | int button; |
335 | int col = 0; | 323 | int col = 0; |
336 | int ok; | 324 | int ok; |
337 | 325 | ||
338 | #ifdef HAVE_LCD_BITMAP | 326 | TEST_PLUGIN_API(api); |
339 | /* no margins */ | 327 | rb = api; |
340 | lcd_setmargins(0, 0); | 328 | |
341 | #endif | 329 | if (!file) |
330 | return PLUGIN_ERROR; | ||
342 | 331 | ||
343 | ok = viewer_init(file); | 332 | ok = viewer_init(file); |
344 | if (!ok) { | 333 | if (!ok) { |
345 | lcd_clear_display(); | 334 | rb->splash(HZ, 0, false, "Error"); |
346 | lcd_puts(0, 0, "Error"); | ||
347 | lcd_update(); | ||
348 | sleep(HZ); | ||
349 | viewer_exit(); | 335 | viewer_exit(); |
350 | return false; | 336 | return PLUGIN_OK; |
351 | } | 337 | } |
352 | 338 | ||
353 | viewer_draw(col); | 339 | viewer_draw(col); |
354 | while (!exit) { | 340 | while (!exit) { |
355 | button = button_get(true); | 341 | button = rb->button_get(true); |
356 | 342 | ||
357 | switch ( button ) { | 343 | switch ( button ) { |
358 | 344 | ||
@@ -420,13 +406,10 @@ bool viewer_run(char* file) | |||
420 | break; | 406 | break; |
421 | 407 | ||
422 | case SYS_USB_CONNECTED: | 408 | case SYS_USB_CONNECTED: |
423 | usb_screen(); | 409 | rb->usb_screen(); |
424 | #ifdef HAVE_LCD_CHARCELLS | ||
425 | status_set_param(false); | ||
426 | #endif | ||
427 | viewer_exit(); | 410 | viewer_exit(); |
428 | return true; | 411 | return PLUGIN_USB_CONNECTED; |
429 | } | 412 | } |
430 | } | 413 | } |
431 | return false; | 414 | return PLUGIN_OK; |
432 | } | 415 | } |
diff --git a/apps/recorder/wormlet.c b/apps/plugins/wormlet.c index 2937a1bb83..be089cdb7c 100644 --- a/apps/recorder/wormlet.c +++ b/apps/plugins/wormlet.c | |||
@@ -16,26 +16,9 @@ | |||
16 | * KIND, either express or implied. | 16 | * KIND, either express or implied. |
17 | * | 17 | * |
18 | ****************************************************************************/ | 18 | ****************************************************************************/ |
19 | #include "plugin.h" | ||
19 | 20 | ||
20 | #include "config.h" | 21 | #ifdef HAVE_LCD_BITMAP |
21 | #include "options.h" | ||
22 | |||
23 | #ifdef USE_GAMES | ||
24 | |||
25 | /* #define DEBUG_WORMLET */ | ||
26 | |||
27 | #include <sprintf.h> | ||
28 | #include <stdlib.h> | ||
29 | #include <string.h> | ||
30 | #include "system.h" | ||
31 | #include "lcd.h" | ||
32 | #include "button.h" | ||
33 | #include "kernel.h" | ||
34 | #include "menu.h" | ||
35 | #include "rtc.h" | ||
36 | #include "lang.h" | ||
37 | #include "screens.h" | ||
38 | #include "font.h" | ||
39 | 22 | ||
40 | /* size of the field the worm lives in */ | 23 | /* size of the field the worm lives in */ |
41 | #define FIELD_RECT_X 1 | 24 | #define FIELD_RECT_X 1 |
@@ -149,6 +132,9 @@ static int player3_dir = EAST; | |||
149 | control a worm */ | 132 | control a worm */ |
150 | static int players = 1; | 133 | static int players = 1; |
151 | 134 | ||
135 | /* the rockbox plugin api */ | ||
136 | static struct plugin_api* rb; | ||
137 | |||
152 | #ifdef DEBUG_WORMLET | 138 | #ifdef DEBUG_WORMLET |
153 | static void set_debug_out(char *str){ | 139 | static void set_debug_out(char *str){ |
154 | strcpy(debugout, str); | 140 | strcpy(debugout, str); |
@@ -507,8 +493,8 @@ static int make_food(int index) { | |||
507 | do { | 493 | do { |
508 | /* make coordinates for a new food so that | 494 | /* make coordinates for a new food so that |
509 | the entire food lies within the FIELD */ | 495 | the entire food lies within the FIELD */ |
510 | x = rand() % (FIELD_RECT_WIDTH - FOOD_SIZE); | 496 | x = rb->rand() % (FIELD_RECT_WIDTH - FOOD_SIZE); |
511 | y = rand() % (FIELD_RECT_HEIGHT - FOOD_SIZE); | 497 | y = rb->rand() % (FIELD_RECT_HEIGHT - FOOD_SIZE); |
512 | tries ++; | 498 | tries ++; |
513 | 499 | ||
514 | /* Ensure that the new food doesn't collide with any | 500 | /* Ensure that the new food doesn't collide with any |
@@ -549,7 +535,7 @@ static int make_food(int index) { | |||
549 | static void clear_food(int index) | 535 | static void clear_food(int index) |
550 | { | 536 | { |
551 | /* remove the old food from the screen */ | 537 | /* remove the old food from the screen */ |
552 | lcd_clearrect(foodx[index] + FIELD_RECT_X, | 538 | rb->lcd_clearrect(foodx[index] + FIELD_RECT_X, |
553 | foody[index] + FIELD_RECT_Y, | 539 | foody[index] + FIELD_RECT_Y, |
554 | FOOD_SIZE, FOOD_SIZE); | 540 | FOOD_SIZE, FOOD_SIZE); |
555 | } | 541 | } |
@@ -563,10 +549,10 @@ static void clear_food(int index) | |||
563 | static void draw_food(int index) | 549 | static void draw_food(int index) |
564 | { | 550 | { |
565 | /* draw the food object */ | 551 | /* draw the food object */ |
566 | lcd_fillrect(foodx[index] + FIELD_RECT_X, | 552 | rb->lcd_fillrect(foodx[index] + FIELD_RECT_X, |
567 | foody[index] + FIELD_RECT_Y, | 553 | foody[index] + FIELD_RECT_Y, |
568 | FOOD_SIZE, FOOD_SIZE); | 554 | FOOD_SIZE, FOOD_SIZE); |
569 | lcd_clearrect(foodx[index] + FIELD_RECT_X + 1, | 555 | rb->lcd_clearrect(foodx[index] + FIELD_RECT_X + 1, |
570 | foody[index] + FIELD_RECT_Y + 1, | 556 | foody[index] + FIELD_RECT_Y + 1, |
571 | FOOD_SIZE - 2, FOOD_SIZE - 2); | 557 | FOOD_SIZE - 2, FOOD_SIZE - 2); |
572 | } | 558 | } |
@@ -588,8 +574,8 @@ static int make_argh(int index) | |||
588 | do { | 574 | do { |
589 | /* make coordinates for a new argh so that | 575 | /* make coordinates for a new argh so that |
590 | the entire food lies within the FIELD */ | 576 | the entire food lies within the FIELD */ |
591 | x = rand() % (FIELD_RECT_WIDTH - ARGH_SIZE); | 577 | x = rb->rand() % (FIELD_RECT_WIDTH - ARGH_SIZE); |
592 | y = rand() % (FIELD_RECT_HEIGHT - ARGH_SIZE); | 578 | y = rb->rand() % (FIELD_RECT_HEIGHT - ARGH_SIZE); |
593 | tries ++; | 579 | tries ++; |
594 | 580 | ||
595 | /* Ensure that the new argh doesn't intersect with any | 581 | /* Ensure that the new argh doesn't intersect with any |
@@ -631,7 +617,7 @@ static int make_argh(int index) | |||
631 | static void draw_argh(int index) | 617 | static void draw_argh(int index) |
632 | { | 618 | { |
633 | /* draw the new argh */ | 619 | /* draw the new argh */ |
634 | lcd_fillrect(arghx[index] + FIELD_RECT_X, | 620 | rb->lcd_fillrect(arghx[index] + FIELD_RECT_X, |
635 | arghy[index] + FIELD_RECT_Y, | 621 | arghy[index] + FIELD_RECT_Y, |
636 | ARGH_SIZE, ARGH_SIZE); | 622 | ARGH_SIZE, ARGH_SIZE); |
637 | } | 623 | } |
@@ -744,7 +730,7 @@ static void init_wormlet(void) | |||
744 | } | 730 | } |
745 | 731 | ||
746 | /* Needed when the game is restarted using BUTTON_ON */ | 732 | /* Needed when the game is restarted using BUTTON_ON */ |
747 | lcd_clear_display(); | 733 | rb->lcd_clear_display(); |
748 | 734 | ||
749 | /* make and display some food and argh */ | 735 | /* make and display some food and argh */ |
750 | argh_count = MAX_FOOD; | 736 | argh_count = MAX_FOOD; |
@@ -756,11 +742,11 @@ static void init_wormlet(void) | |||
756 | } | 742 | } |
757 | 743 | ||
758 | /* draw the game field */ | 744 | /* draw the game field */ |
759 | lcd_invertrect(0, 0, FIELD_RECT_WIDTH + 2, FIELD_RECT_HEIGHT + 2); | 745 | rb->lcd_invertrect(0, 0, FIELD_RECT_WIDTH + 2, FIELD_RECT_HEIGHT + 2); |
760 | lcd_invertrect(1, 1, FIELD_RECT_WIDTH, FIELD_RECT_HEIGHT); | 746 | rb->lcd_invertrect(1, 1, FIELD_RECT_WIDTH, FIELD_RECT_HEIGHT); |
761 | 747 | ||
762 | /* make everything visible */ | 748 | /* make everything visible */ |
763 | lcd_update(); | 749 | rb->lcd_update(); |
764 | } | 750 | } |
765 | 751 | ||
766 | 752 | ||
@@ -852,14 +838,14 @@ static void draw_worm(struct worm *w) | |||
852 | int x = w->x[w->head]; | 838 | int x = w->x[w->head]; |
853 | int y = w->y[w->head]; | 839 | int y = w->y[w->head]; |
854 | if (x >= 0 && x < FIELD_RECT_WIDTH && y >= 0 && y < FIELD_RECT_HEIGHT) { | 840 | if (x >= 0 && x < FIELD_RECT_WIDTH && y >= 0 && y < FIELD_RECT_HEIGHT) { |
855 | lcd_drawpixel(x + FIELD_RECT_X, y + FIELD_RECT_Y); | 841 | rb->lcd_drawpixel(x + FIELD_RECT_X, y + FIELD_RECT_Y); |
856 | } | 842 | } |
857 | 843 | ||
858 | /* clear the space behind the worm */ | 844 | /* clear the space behind the worm */ |
859 | x = w->x[w->tail] ; | 845 | x = w->x[w->tail] ; |
860 | y = w->y[w->tail] ; | 846 | y = w->y[w->tail] ; |
861 | if (x >= 0 && x < FIELD_RECT_WIDTH && y >= 0 && y < FIELD_RECT_HEIGHT) { | 847 | if (x >= 0 && x < FIELD_RECT_WIDTH && y >= 0 && y < FIELD_RECT_HEIGHT) { |
862 | lcd_clearpixel(x + FIELD_RECT_X, y + FIELD_RECT_Y); | 848 | rb->lcd_clearpixel(x + FIELD_RECT_X, y + FIELD_RECT_Y); |
863 | } | 849 | } |
864 | } | 850 | } |
865 | 851 | ||
@@ -1166,10 +1152,10 @@ static void virtual_player(struct worm *w) { | |||
1166 | static void score_board(void) | 1152 | static void score_board(void) |
1167 | { | 1153 | { |
1168 | char buf[15]; | 1154 | char buf[15]; |
1169 | char buf2[15]; | 1155 | char* buf2 = NULL; |
1170 | int i; | 1156 | int i; |
1171 | int y = 0; | 1157 | int y = 0; |
1172 | lcd_clearrect(FIELD_RECT_WIDTH + 2, 0, LCD_WIDTH - FIELD_RECT_WIDTH - 2, LCD_HEIGHT); | 1158 | rb->lcd_clearrect(FIELD_RECT_WIDTH + 2, 0, LCD_WIDTH - FIELD_RECT_WIDTH - 2, LCD_HEIGHT); |
1173 | for (i = 0; i < worm_count; i++) { | 1159 | for (i = 0; i < worm_count; i++) { |
1174 | int score = get_score(&worms[i]); | 1160 | int score = get_score(&worms[i]); |
1175 | 1161 | ||
@@ -1180,54 +1166,52 @@ static void score_board(void) | |||
1180 | } | 1166 | } |
1181 | } | 1167 | } |
1182 | 1168 | ||
1183 | /* length */ | 1169 | /* length */ |
1184 | snprintf(buf, sizeof (buf),str(LANG_WORMLET_LENGTH), score); | 1170 | rb->snprintf(buf, sizeof (buf),"Len:%d", score); |
1185 | 1171 | ||
1186 | /* worm state */ | 1172 | /* worm state */ |
1187 | switch (check_collision(&worms[i])) { | 1173 | switch (check_collision(&worms[i])) { |
1188 | case COLLISION_NONE: | 1174 | case COLLISION_NONE: |
1189 | if (worms[i].growing > 0){ | 1175 | if (worms[i].growing > 0) |
1190 | snprintf(buf2, sizeof(buf2), str(LANG_WORMLET_GROWING)); | 1176 | buf2 = "Growing"; |
1191 | } | ||
1192 | else { | 1177 | else { |
1193 | if (worms[i].alive) { | 1178 | if (worms[i].alive) |
1194 | snprintf(buf2, sizeof(buf2), str(LANG_WORMLET_HUNGRY)); | 1179 | buf2 = "Hungry"; |
1195 | } else { | 1180 | else |
1196 | snprintf(buf2, sizeof(buf2), str(LANG_WORMLET_WORMED)); | 1181 | buf2 = "Wormed"; |
1197 | } | ||
1198 | } | 1182 | } |
1199 | break; | 1183 | break; |
1200 | 1184 | ||
1201 | case COLLISION_WORM: | 1185 | case COLLISION_WORM: |
1202 | snprintf(buf2, sizeof(buf2), str(LANG_WORMLET_WORMED)); | 1186 | buf2 = "Wormed"; |
1203 | break; | 1187 | break; |
1204 | 1188 | ||
1205 | case COLLISION_FOOD: | 1189 | case COLLISION_FOOD: |
1206 | snprintf(buf2, sizeof(buf2), str(LANG_WORMLET_GROWING)); | 1190 | buf2 = "Growing"; |
1207 | break; | 1191 | break; |
1208 | 1192 | ||
1209 | case COLLISION_ARGH: | 1193 | case COLLISION_ARGH: |
1210 | snprintf(buf2, sizeof(buf2), str(LANG_WORMLET_ARGH)); | 1194 | buf2 = "Argh"; |
1211 | break; | 1195 | break; |
1212 | 1196 | ||
1213 | case COLLISION_FIELD: | 1197 | case COLLISION_FIELD: |
1214 | snprintf(buf2, sizeof(buf2), str(LANG_WORMLET_CRASHED)); | 1198 | buf2 = "Crashed"; |
1215 | break; | 1199 | break; |
1216 | } | 1200 | } |
1217 | lcd_putsxy(FIELD_RECT_WIDTH + 3, y , buf); | 1201 | rb->lcd_putsxy(FIELD_RECT_WIDTH + 3, y , buf); |
1218 | lcd_putsxy(FIELD_RECT_WIDTH + 3, y+8, buf2); | 1202 | rb->lcd_putsxy(FIELD_RECT_WIDTH + 3, y+8, buf2); |
1219 | 1203 | ||
1220 | if (!worms[i].alive){ | 1204 | if (!worms[i].alive){ |
1221 | lcd_invertrect(FIELD_RECT_WIDTH + 2, y, | 1205 | rb->lcd_invertrect(FIELD_RECT_WIDTH + 2, y, |
1222 | LCD_WIDTH - FIELD_RECT_WIDTH - 2, 17); | 1206 | LCD_WIDTH - FIELD_RECT_WIDTH - 2, 17); |
1223 | } | 1207 | } |
1224 | y += 19; | 1208 | y += 19; |
1225 | } | 1209 | } |
1226 | snprintf(buf , sizeof(buf), str(LANG_WORMLET_HIGHSCORE), highscore); | 1210 | rb->snprintf(buf , sizeof(buf), "Hs: %d", highscore); |
1227 | #ifndef DEBUG_WORMLET | 1211 | #ifndef DEBUG_WORMLET |
1228 | lcd_putsxy(FIELD_RECT_WIDTH + 3, LCD_HEIGHT - 8, buf); | 1212 | rb->lcd_putsxy(FIELD_RECT_WIDTH + 3, LCD_HEIGHT - 8, buf); |
1229 | #else | 1213 | #else |
1230 | lcd_putsxy(FIELD_RECT_WIDTH + 3, LCD_HEIGHT - 8, debugout); | 1214 | rb->lcd_putsxy(FIELD_RECT_WIDTH + 3, LCD_HEIGHT - 8, debugout); |
1231 | #endif | 1215 | #endif |
1232 | } | 1216 | } |
1233 | 1217 | ||
@@ -1305,7 +1289,7 @@ static bool run(void) | |||
1305 | /* initialize the board and so on */ | 1289 | /* initialize the board and so on */ |
1306 | init_wormlet(); | 1290 | init_wormlet(); |
1307 | 1291 | ||
1308 | cycle_start = current_tick; | 1292 | cycle_start = *rb->current_tick; |
1309 | /* change the direction of the worm */ | 1293 | /* change the direction of the worm */ |
1310 | while (button != BUTTON_OFF && ! wormDead) | 1294 | while (button != BUTTON_OFF && ! wormDead) |
1311 | { | 1295 | { |
@@ -1358,7 +1342,7 @@ static bool run(void) | |||
1358 | 1342 | ||
1359 | case BUTTON_PLAY: | 1343 | case BUTTON_PLAY: |
1360 | do { | 1344 | do { |
1361 | button = button_get(true); | 1345 | button = rb->button_get(true); |
1362 | } while (button != BUTTON_PLAY && | 1346 | } while (button != BUTTON_PLAY && |
1363 | button != BUTTON_OFF && | 1347 | button != BUTTON_OFF && |
1364 | button != BUTTON_ON); | 1348 | button != BUTTON_ON); |
@@ -1377,7 +1361,7 @@ static bool run(void) | |||
1377 | draw_worm(w); | 1361 | draw_worm(w); |
1378 | } | 1362 | } |
1379 | score_board(); | 1363 | score_board(); |
1380 | lcd_update(); | 1364 | rb->lcd_update(); |
1381 | if (button == BUTTON_ON) { | 1365 | if (button == BUTTON_ON) { |
1382 | wormDead = true; | 1366 | wormDead = true; |
1383 | } | 1367 | } |
@@ -1385,7 +1369,7 @@ static bool run(void) | |||
1385 | /* here the wormlet game cycle ends | 1369 | /* here the wormlet game cycle ends |
1386 | thus the current tick is stored | 1370 | thus the current tick is stored |
1387 | as end time */ | 1371 | as end time */ |
1388 | cycle_end = current_tick; | 1372 | cycle_end = *rb->current_tick; |
1389 | 1373 | ||
1390 | /* The duration of the game cycle */ | 1374 | /* The duration of the game cycle */ |
1391 | cycle_duration = cycle_end - cycle_start; | 1375 | cycle_duration = cycle_end - cycle_start; |
@@ -1403,15 +1387,14 @@ static bool run(void) | |||
1403 | max_cycle = cycle_duration; | 1387 | max_cycle = cycle_duration; |
1404 | ticks_to_max_cycle_reset = 20; | 1388 | ticks_to_max_cycle_reset = 20; |
1405 | } | 1389 | } |
1406 | snprintf(buf, sizeof buf, "ticks %d", max_cycle); | 1390 | rb->snprintf(buf, sizeof buf, "ticks %d", max_cycle); |
1407 | set_debug_out(buf); | 1391 | set_debug_out(buf); |
1408 | #endif | 1392 | #endif |
1409 | /* adjust the number of ticks to wait for a button. | 1393 | /* adjust the number of ticks to wait for a button. |
1410 | This ensures that a complete game cycle including | 1394 | This ensures that a complete game cycle including |
1411 | user input runs in constant time */ | 1395 | user input runs in constant time */ |
1412 | button = button_get_w_tmo(SPEED - cycle_duration); | 1396 | button = rb->button_get_w_tmo(SPEED - cycle_duration); |
1413 | cycle_start = current_tick; | 1397 | cycle_start = *rb->current_tick; |
1414 | |||
1415 | } | 1398 | } |
1416 | return wormDead; | 1399 | return wormDead; |
1417 | } | 1400 | } |
@@ -1425,7 +1408,7 @@ static bool run(void) | |||
1425 | static void test_worm_food_collision(void) { | 1408 | static void test_worm_food_collision(void) { |
1426 | int collision_count = 0; | 1409 | int collision_count = 0; |
1427 | int i; | 1410 | int i; |
1428 | lcd_clear_display(); | 1411 | rb->lcd_clear_display(); |
1429 | init_worm(&worms[0], 10, 10); | 1412 | init_worm(&worms[0], 10, 10); |
1430 | add_growing(&worms[0], 10); | 1413 | add_growing(&worms[0], 10); |
1431 | set_worm_dir(&worms[0], EAST); | 1414 | set_worm_dir(&worms[0], EAST); |
@@ -1451,12 +1434,12 @@ static void test_worm_food_collision(void) { | |||
1451 | if (collision) { | 1434 | if (collision) { |
1452 | collision_count++; | 1435 | collision_count++; |
1453 | } | 1436 | } |
1454 | snprintf(buf, sizeof buf, "collisions: %d", collision_count); | 1437 | rb->snprintf(buf, sizeof buf, "collisions: %d", collision_count); |
1455 | lcd_putsxy(0, LCD_HEIGHT -8, buf); | 1438 | rb->lcd_putsxy(0, LCD_HEIGHT -8, buf); |
1456 | lcd_update(); | 1439 | rb->lcd_update(); |
1457 | } | 1440 | } |
1458 | if (collision_count != FOOD_SIZE) { | 1441 | if (collision_count != FOOD_SIZE) { |
1459 | button_get(true); | 1442 | rb->button_get(true); |
1460 | } | 1443 | } |
1461 | 1444 | ||
1462 | 1445 | ||
@@ -1470,12 +1453,12 @@ static void test_worm_food_collision(void) { | |||
1470 | if (collision) { | 1453 | if (collision) { |
1471 | collision_count ++; | 1454 | collision_count ++; |
1472 | } | 1455 | } |
1473 | snprintf(buf, sizeof buf, "collisions: %d", collision_count); | 1456 | rb->snprintf(buf, sizeof buf, "collisions: %d", collision_count); |
1474 | lcd_putsxy(0, LCD_HEIGHT -8, buf); | 1457 | rb->lcd_putsxy(0, LCD_HEIGHT -8, buf); |
1475 | lcd_update(); | 1458 | rb->lcd_update(); |
1476 | } | 1459 | } |
1477 | if (collision_count != FOOD_SIZE * 2) { | 1460 | if (collision_count != FOOD_SIZE * 2) { |
1478 | button_get(true); | 1461 | rb->button_get(true); |
1479 | } | 1462 | } |
1480 | 1463 | ||
1481 | } | 1464 | } |
@@ -1498,7 +1481,7 @@ static void test_worm_argh_collision(void) { | |||
1498 | int i; | 1481 | int i; |
1499 | int dir; | 1482 | int dir; |
1500 | int collision_count = 0; | 1483 | int collision_count = 0; |
1501 | lcd_clear_display(); | 1484 | rb->lcd_clear_display(); |
1502 | init_worm(&worms[0], 10, 10); | 1485 | init_worm(&worms[0], 10, 10); |
1503 | add_growing(&worms[0], 40); | 1486 | add_growing(&worms[0], 40); |
1504 | for (dir = 0; dir < 4; dir++) { | 1487 | for (dir = 0; dir < 4; dir++) { |
@@ -1518,12 +1501,12 @@ static void test_worm_argh_collision(void) { | |||
1518 | if (collision) { | 1501 | if (collision) { |
1519 | collision_count ++; | 1502 | collision_count ++; |
1520 | } | 1503 | } |
1521 | snprintf(buf, sizeof buf, "collisions: %d", collision_count); | 1504 | rb->snprintf(buf, sizeof buf, "collisions: %d", collision_count); |
1522 | lcd_putsxy(0, LCD_HEIGHT -8, buf); | 1505 | rb->lcd_putsxy(0, LCD_HEIGHT -8, buf); |
1523 | lcd_update(); | 1506 | rb->lcd_update(); |
1524 | } | 1507 | } |
1525 | if (collision_count != ARGH_SIZE * 2) { | 1508 | if (collision_count != ARGH_SIZE * 2) { |
1526 | button_get(true); | 1509 | rb->button_get(true); |
1527 | } | 1510 | } |
1528 | 1511 | ||
1529 | arghy[0] = 12; | 1512 | arghy[0] = 12; |
@@ -1535,12 +1518,12 @@ static void test_worm_argh_collision(void) { | |||
1535 | if (collision) { | 1518 | if (collision) { |
1536 | collision_count ++; | 1519 | collision_count ++; |
1537 | } | 1520 | } |
1538 | snprintf(buf, sizeof buf, "collisions: %d", collision_count); | 1521 | rb->snprintf(buf, sizeof buf, "collisions: %d", collision_count); |
1539 | lcd_putsxy(0, LCD_HEIGHT -8, buf); | 1522 | rb->lcd_putsxy(0, LCD_HEIGHT -8, buf); |
1540 | lcd_update(); | 1523 | rb->lcd_update(); |
1541 | } | 1524 | } |
1542 | if (collision_count != ARGH_SIZE * 4) { | 1525 | if (collision_count != ARGH_SIZE * 4) { |
1543 | button_get(true); | 1526 | rb->button_get(true); |
1544 | } | 1527 | } |
1545 | } | 1528 | } |
1546 | 1529 | ||
@@ -1560,11 +1543,11 @@ static int testline_in_rect(void) { | |||
1560 | 1543 | ||
1561 | if (!line_in_rect(x1, y1, x2, y2, rx, ry, rw, rh) && | 1544 | if (!line_in_rect(x1, y1, x2, y2, rx, ry, rw, rh) && |
1562 | !line_in_rect(x2, y2, x1, y1, rx, ry, rw, rh)) { | 1545 | !line_in_rect(x2, y2, x1, y1, rx, ry, rw, rh)) { |
1563 | lcd_drawrect(rx, ry, rw, rh); | 1546 | rb->lcd_drawrect(rx, ry, rw, rh); |
1564 | lcd_drawline(x1, y1, x2, y2); | 1547 | rb->lcd_drawline(x1, y1, x2, y2); |
1565 | lcd_update(); | 1548 | rb->lcd_update(); |
1566 | lcd_putsxy(0, 0, "failed 1"); | 1549 | rb->lcd_putsxy(0, 0, "failed 1"); |
1567 | button_get(true); | 1550 | rb->button_get(true); |
1568 | testfailed = 1; | 1551 | testfailed = 1; |
1569 | } | 1552 | } |
1570 | 1553 | ||
@@ -1572,11 +1555,11 @@ static int testline_in_rect(void) { | |||
1572 | y2 = 20; | 1555 | y2 = 20; |
1573 | if (!line_in_rect(x1, y1, x2, y2, rx, ry, rw, rh) && | 1556 | if (!line_in_rect(x1, y1, x2, y2, rx, ry, rw, rh) && |
1574 | !line_in_rect(x2, y2, x1, y1, rx, ry, rw, rh)) { | 1557 | !line_in_rect(x2, y2, x1, y1, rx, ry, rw, rh)) { |
1575 | lcd_drawrect(rx, ry, rw, rh); | 1558 | rb->lcd_drawrect(rx, ry, rw, rh); |
1576 | lcd_drawline(x1, y1, x2, y2); | 1559 | rb->lcd_drawline(x1, y1, x2, y2); |
1577 | lcd_putsxy(0, 0, "failed 2"); | 1560 | rb->lcd_putsxy(0, 0, "failed 2"); |
1578 | lcd_update(); | 1561 | rb->lcd_update(); |
1579 | button_get(true); | 1562 | rb->button_get(true); |
1580 | testfailed = 2; | 1563 | testfailed = 2; |
1581 | } | 1564 | } |
1582 | 1565 | ||
@@ -1584,11 +1567,11 @@ static int testline_in_rect(void) { | |||
1584 | y1 = 30; | 1567 | y1 = 30; |
1585 | if (!line_in_rect(x1, y1, x2, y2, rx, ry, rw, rh) && | 1568 | if (!line_in_rect(x1, y1, x2, y2, rx, ry, rw, rh) && |
1586 | !line_in_rect(x2, y2, x1, y1, rx, ry, rw, rh)) { | 1569 | !line_in_rect(x2, y2, x1, y1, rx, ry, rw, rh)) { |
1587 | lcd_drawrect(rx, ry, rw, rh); | 1570 | rb->lcd_drawrect(rx, ry, rw, rh); |
1588 | lcd_drawline(x1, y1, x2, y2); | 1571 | rb->lcd_drawline(x1, y1, x2, y2); |
1589 | lcd_putsxy(0, 0, "failed 3"); | 1572 | rb->lcd_putsxy(0, 0, "failed 3"); |
1590 | lcd_update(); | 1573 | rb->lcd_update(); |
1591 | button_get(true); | 1574 | rb->button_get(true); |
1592 | testfailed = 3; | 1575 | testfailed = 3; |
1593 | } | 1576 | } |
1594 | 1577 | ||
@@ -1596,11 +1579,11 @@ static int testline_in_rect(void) { | |||
1596 | y2 = 45; | 1579 | y2 = 45; |
1597 | if (!line_in_rect(x1, y1, x2, y2, rx, ry, rw, rh) && | 1580 | if (!line_in_rect(x1, y1, x2, y2, rx, ry, rw, rh) && |
1598 | !line_in_rect(x2, y2, x1, y1, rx, ry, rw, rh)) { | 1581 | !line_in_rect(x2, y2, x1, y1, rx, ry, rw, rh)) { |
1599 | lcd_drawrect(rx, ry, rw, rh); | 1582 | rb->lcd_drawrect(rx, ry, rw, rh); |
1600 | lcd_drawline(x1, y1, x2, y2); | 1583 | rb->lcd_drawline(x1, y1, x2, y2); |
1601 | lcd_putsxy(0, 0, "failed 4"); | 1584 | rb->lcd_putsxy(0, 0, "failed 4"); |
1602 | lcd_update(); | 1585 | rb->lcd_update(); |
1603 | button_get(true); | 1586 | rb->button_get(true); |
1604 | testfailed = 4; | 1587 | testfailed = 4; |
1605 | } | 1588 | } |
1606 | 1589 | ||
@@ -1608,11 +1591,11 @@ static int testline_in_rect(void) { | |||
1608 | y1 = 50; | 1591 | y1 = 50; |
1609 | if (line_in_rect(x1, y1, x2, y2, rx, ry, rw, rh) || | 1592 | if (line_in_rect(x1, y1, x2, y2, rx, ry, rw, rh) || |
1610 | line_in_rect(x2, y2, x1, y1, rx, ry, rw, rh)) { | 1593 | line_in_rect(x2, y2, x1, y1, rx, ry, rw, rh)) { |
1611 | lcd_drawrect(rx, ry, rw, rh); | 1594 | rb->lcd_drawrect(rx, ry, rw, rh); |
1612 | lcd_drawline(x1, y1, x2, y2); | 1595 | rb->lcd_drawline(x1, y1, x2, y2); |
1613 | lcd_putsxy(0, 0, "failed 5"); | 1596 | rb->lcd_putsxy(0, 0, "failed 5"); |
1614 | lcd_update(); | 1597 | rb->lcd_update(); |
1615 | button_get(true); | 1598 | rb->button_get(true); |
1616 | testfailed = 5; | 1599 | testfailed = 5; |
1617 | } | 1600 | } |
1618 | 1601 | ||
@@ -1621,11 +1604,11 @@ static int testline_in_rect(void) { | |||
1621 | y2 = 7; | 1604 | y2 = 7; |
1622 | if (line_in_rect(x1, y1, x2, y2, rx, ry, rw, rh) || | 1605 | if (line_in_rect(x1, y1, x2, y2, rx, ry, rw, rh) || |
1623 | line_in_rect(x2, y2, x1, y1, rx, ry, rw, rh)) { | 1606 | line_in_rect(x2, y2, x1, y1, rx, ry, rw, rh)) { |
1624 | lcd_drawrect(rx, ry, rw, rh); | 1607 | rb->lcd_drawrect(rx, ry, rw, rh); |
1625 | lcd_drawline(x1, y1, x2, y2); | 1608 | rb->lcd_drawline(x1, y1, x2, y2); |
1626 | lcd_putsxy(0, 0, "failed 6"); | 1609 | rb->lcd_putsxy(0, 0, "failed 6"); |
1627 | lcd_update(); | 1610 | rb->lcd_update(); |
1628 | button_get(true); | 1611 | rb->button_get(true); |
1629 | testfailed = 6; | 1612 | testfailed = 6; |
1630 | } | 1613 | } |
1631 | 1614 | ||
@@ -1636,11 +1619,11 @@ static int testline_in_rect(void) { | |||
1636 | y2 = 20; | 1619 | y2 = 20; |
1637 | if (!line_in_rect(x1, y1, x2, y2, rx, ry, rw, rh) && | 1620 | if (!line_in_rect(x1, y1, x2, y2, rx, ry, rw, rh) && |
1638 | !line_in_rect(x2, y2, x1, y1, rx, ry, rw, rh)) { | 1621 | !line_in_rect(x2, y2, x1, y1, rx, ry, rw, rh)) { |
1639 | lcd_drawrect(rx, ry, rw, rh); | 1622 | rb->lcd_drawrect(rx, ry, rw, rh); |
1640 | lcd_drawline(x1, y1, x2, y2); | 1623 | rb->lcd_drawline(x1, y1, x2, y2); |
1641 | lcd_putsxy(0, 0, "failed 7"); | 1624 | rb->lcd_putsxy(0, 0, "failed 7"); |
1642 | lcd_update(); | 1625 | rb->lcd_update(); |
1643 | button_get(true); | 1626 | rb->button_get(true); |
1644 | testfailed = 7; | 1627 | testfailed = 7; |
1645 | } | 1628 | } |
1646 | 1629 | ||
@@ -1648,11 +1631,11 @@ static int testline_in_rect(void) { | |||
1648 | x2 = 12; | 1631 | x2 = 12; |
1649 | if (!line_in_rect(x1, y1, x2, y2, rx, ry, rw, rh) && | 1632 | if (!line_in_rect(x1, y1, x2, y2, rx, ry, rw, rh) && |
1650 | !line_in_rect(x2, y2, x1, y1, rx, ry, rw, rh)) { | 1633 | !line_in_rect(x2, y2, x1, y1, rx, ry, rw, rh)) { |
1651 | lcd_drawrect(rx, ry, rw, rh); | 1634 | rb->lcd_drawrect(rx, ry, rw, rh); |
1652 | lcd_drawline(x1, y1, x2, y2); | 1635 | rb->lcd_drawline(x1, y1, x2, y2); |
1653 | lcd_putsxy(0, 0, "failed 8"); | 1636 | rb->lcd_putsxy(0, 0, "failed 8"); |
1654 | lcd_update(); | 1637 | rb->lcd_update(); |
1655 | button_get(true); | 1638 | rb->button_get(true); |
1656 | testfailed = 8; | 1639 | testfailed = 8; |
1657 | } | 1640 | } |
1658 | 1641 | ||
@@ -1660,11 +1643,11 @@ static int testline_in_rect(void) { | |||
1660 | x1 = 25; | 1643 | x1 = 25; |
1661 | if (!line_in_rect(x1, y1, x2, y2, rx, ry, rw, rh) && | 1644 | if (!line_in_rect(x1, y1, x2, y2, rx, ry, rw, rh) && |
1662 | !line_in_rect(x2, y2, x1, y1, rx, ry, rw, rh)) { | 1645 | !line_in_rect(x2, y2, x1, y1, rx, ry, rw, rh)) { |
1663 | lcd_drawrect(rx, ry, rw, rh); | 1646 | rb->lcd_drawrect(rx, ry, rw, rh); |
1664 | lcd_drawline(x1, y1, x2, y2); | 1647 | rb->lcd_drawline(x1, y1, x2, y2); |
1665 | lcd_putsxy(0, 0, "failed 9"); | 1648 | rb->lcd_putsxy(0, 0, "failed 9"); |
1666 | lcd_update(); | 1649 | rb->lcd_update(); |
1667 | button_get(true); | 1650 | rb->button_get(true); |
1668 | testfailed = 9; | 1651 | testfailed = 9; |
1669 | } | 1652 | } |
1670 | 1653 | ||
@@ -1672,11 +1655,11 @@ static int testline_in_rect(void) { | |||
1672 | x2 = 37; | 1655 | x2 = 37; |
1673 | if (!line_in_rect(x1, y1, x2, y2, rx, ry, rw, rh) && | 1656 | if (!line_in_rect(x1, y1, x2, y2, rx, ry, rw, rh) && |
1674 | !line_in_rect(x2, y2, x1, y1, rx, ry, rw, rh)) { | 1657 | !line_in_rect(x2, y2, x1, y1, rx, ry, rw, rh)) { |
1675 | lcd_drawrect(rx, ry, rw, rh); | 1658 | rb->lcd_drawrect(rx, ry, rw, rh); |
1676 | lcd_drawline(x1, y1, x2, y2); | 1659 | rb->lcd_drawline(x1, y1, x2, y2); |
1677 | lcd_putsxy(0, 0, "failed 10"); | 1660 | rb->lcd_putsxy(0, 0, "failed 10"); |
1678 | lcd_update(); | 1661 | rb->lcd_update(); |
1679 | button_get(true); | 1662 | rb->button_get(true); |
1680 | testfailed = 10; | 1663 | testfailed = 10; |
1681 | } | 1664 | } |
1682 | 1665 | ||
@@ -1684,11 +1667,11 @@ static int testline_in_rect(void) { | |||
1684 | x1 = 42; | 1667 | x1 = 42; |
1685 | if (line_in_rect(x1, y1, x2, y2, rx, ry, rw, rh) || | 1668 | if (line_in_rect(x1, y1, x2, y2, rx, ry, rw, rh) || |
1686 | line_in_rect(x2, y2, x1, y1, rx, ry, rw, rh)) { | 1669 | line_in_rect(x2, y2, x1, y1, rx, ry, rw, rh)) { |
1687 | lcd_drawrect(rx, ry, rw, rh); | 1670 | rb->lcd_drawrect(rx, ry, rw, rh); |
1688 | lcd_drawline(x1, y1, x2, y2); | 1671 | rb->lcd_drawline(x1, y1, x2, y2); |
1689 | lcd_putsxy(0, 0, "failed 11"); | 1672 | rb->lcd_putsxy(0, 0, "failed 11"); |
1690 | lcd_update(); | 1673 | rb->lcd_update(); |
1691 | button_get(true); | 1674 | rb->button_get(true); |
1692 | testfailed = 11; | 1675 | testfailed = 11; |
1693 | } | 1676 | } |
1694 | 1677 | ||
@@ -1697,11 +1680,11 @@ static int testline_in_rect(void) { | |||
1697 | x2 = 7; | 1680 | x2 = 7; |
1698 | if (line_in_rect(x1, y1, x2, y2, rx, ry, rw, rh) || | 1681 | if (line_in_rect(x1, y1, x2, y2, rx, ry, rw, rh) || |
1699 | line_in_rect(x2, y2, x1, y1, rx, ry, rw, rh)) { | 1682 | line_in_rect(x2, y2, x1, y1, rx, ry, rw, rh)) { |
1700 | lcd_drawrect(rx, ry, rw, rh); | 1683 | rb->lcd_drawrect(rx, ry, rw, rh); |
1701 | lcd_drawline(x1, y1, x2, y2); | 1684 | rb->lcd_drawline(x1, y1, x2, y2); |
1702 | lcd_putsxy(0, 0, "failed 12"); | 1685 | rb->lcd_putsxy(0, 0, "failed 12"); |
1703 | lcd_update(); | 1686 | rb->lcd_update(); |
1704 | button_get(true); | 1687 | rb->button_get(true); |
1705 | testfailed = 12; | 1688 | testfailed = 12; |
1706 | } | 1689 | } |
1707 | 1690 | ||
@@ -1717,11 +1700,11 @@ static int testline_in_rect(void) { | |||
1717 | y2 = 20; | 1700 | y2 = 20; |
1718 | if (!(line_in_rect(x1, y1, x2, y2, rx, ry, rw, rh) && | 1701 | if (!(line_in_rect(x1, y1, x2, y2, rx, ry, rw, rh) && |
1719 | line_in_rect(x2, y2, x1, y1, rx, ry, rw, rh))) { | 1702 | line_in_rect(x2, y2, x1, y1, rx, ry, rw, rh))) { |
1720 | lcd_drawrect(rx, ry, rw, rh); | 1703 | rb->lcd_drawrect(rx, ry, rw, rh); |
1721 | lcd_drawline(x1, y1, x2, y2); | 1704 | rb->lcd_drawline(x1, y1, x2, y2); |
1722 | lcd_putsxy(0, 0, "failed 13"); | 1705 | rb->lcd_putsxy(0, 0, "failed 13"); |
1723 | lcd_update(); | 1706 | rb->lcd_update(); |
1724 | button_get(true); | 1707 | rb->button_get(true); |
1725 | testfailed = 13; | 1708 | testfailed = 13; |
1726 | } | 1709 | } |
1727 | 1710 | ||
@@ -1737,15 +1720,15 @@ static int testline_in_rect(void) { | |||
1737 | y2 = 19; | 1720 | y2 = 19; |
1738 | if (!(line_in_rect(x1, y1, x2, y2, rx, ry, rw, rh) && | 1721 | if (!(line_in_rect(x1, y1, x2, y2, rx, ry, rw, rh) && |
1739 | line_in_rect(x2, y2, x1, y1, rx, ry, rw, rh))) { | 1722 | line_in_rect(x2, y2, x1, y1, rx, ry, rw, rh))) { |
1740 | lcd_drawline(x1, y1, x2, y2); | 1723 | rb->lcd_drawline(x1, y1, x2, y2); |
1741 | lcd_invertrect(rx, ry, rw, rh); | 1724 | rb->lcd_invertrect(rx, ry, rw, rh); |
1742 | lcd_putsxy(0, 0, "failed 14"); | 1725 | rb->lcd_putsxy(0, 0, "failed 14"); |
1743 | lcd_update(); | 1726 | rb->lcd_update(); |
1744 | button_get(true); | 1727 | rb->button_get(true); |
1745 | testfailed = 14; | 1728 | testfailed = 14; |
1746 | } | 1729 | } |
1747 | 1730 | ||
1748 | lcd_clear_display(); | 1731 | rb->lcd_clear_display(); |
1749 | 1732 | ||
1750 | return testfailed; | 1733 | return testfailed; |
1751 | } | 1734 | } |
@@ -1759,7 +1742,7 @@ static int test_specific_worm_collision(void) { | |||
1759 | int x = 0; | 1742 | int x = 0; |
1760 | int y = 0; | 1743 | int y = 0; |
1761 | char buf[20]; | 1744 | char buf[20]; |
1762 | lcd_clear_display(); | 1745 | rb->lcd_clear_display(); |
1763 | init_worm(&worms[0], 10, 20); | 1746 | init_worm(&worms[0], 10, 20); |
1764 | add_growing(&worms[0], 20 - INITIAL_WORM_LENGTH); | 1747 | add_growing(&worms[0], 20 - INITIAL_WORM_LENGTH); |
1765 | 1748 | ||
@@ -1779,14 +1762,14 @@ static int test_specific_worm_collision(void) { | |||
1779 | if (specific_worm_collision(&worms[0], x, y) != -1) { | 1762 | if (specific_worm_collision(&worms[0], x, y) != -1) { |
1780 | collisions ++; | 1763 | collisions ++; |
1781 | } | 1764 | } |
1782 | lcd_invertpixel(x + FIELD_RECT_X, y + FIELD_RECT_Y); | 1765 | rb->lcd_invertpixel(x + FIELD_RECT_X, y + FIELD_RECT_Y); |
1783 | snprintf(buf, sizeof buf, "collisions %d", collisions); | 1766 | rb->snprintf(buf, sizeof buf, "collisions %d", collisions); |
1784 | lcd_putsxy(0, LCD_HEIGHT - 8, buf); | 1767 | rb->lcd_putsxy(0, LCD_HEIGHT - 8, buf); |
1785 | lcd_update(); | 1768 | rb->lcd_update(); |
1786 | } | 1769 | } |
1787 | } | 1770 | } |
1788 | if (collisions != 21) { | 1771 | if (collisions != 21) { |
1789 | button_get(true); | 1772 | rb->button_get(true); |
1790 | } | 1773 | } |
1791 | return collisions; | 1774 | return collisions; |
1792 | } | 1775 | } |
@@ -1798,7 +1781,7 @@ static void test_make_argh(void){ | |||
1798 | int failures = 0; | 1781 | int failures = 0; |
1799 | int last_failures = 0; | 1782 | int last_failures = 0; |
1800 | int i, worm_idx; | 1783 | int i, worm_idx; |
1801 | lcd_clear_display(); | 1784 | rb->lcd_clear_display(); |
1802 | worm_count = 3; | 1785 | worm_count = 3; |
1803 | 1786 | ||
1804 | for (worm_idx = 0; worm_idx < worm_count; worm_idx++) { | 1787 | for (worm_idx = 0; worm_idx < worm_count; worm_idx++) { |
@@ -1818,37 +1801,37 @@ static void test_make_argh(void){ | |||
1818 | } | 1801 | } |
1819 | } | 1802 | } |
1820 | 1803 | ||
1821 | lcd_update(); | 1804 | rb->lcd_update(); |
1822 | 1805 | ||
1823 | for (seed = 0; hit < 20; seed += 2) { | 1806 | for (seed = 0; hit < 20; seed += 2) { |
1824 | char buf[20]; | 1807 | char buf[20]; |
1825 | int x, y; | 1808 | int x, y; |
1826 | srand(seed); | 1809 | rb->srand(seed); |
1827 | x = rand() % (FIELD_RECT_WIDTH - ARGH_SIZE); | 1810 | x = rb->rand() % (FIELD_RECT_WIDTH - ARGH_SIZE); |
1828 | y = rand() % (FIELD_RECT_HEIGHT - ARGH_SIZE); | 1811 | y = rb->rand() % (FIELD_RECT_HEIGHT - ARGH_SIZE); |
1829 | 1812 | ||
1830 | for (worm_idx = 0; worm_idx < worm_count; worm_idx++){ | 1813 | for (worm_idx = 0; worm_idx < worm_count; worm_idx++){ |
1831 | if (expensive_worm_in_rect(&worms[worm_idx], x, y, ARGH_SIZE, ARGH_SIZE)) { | 1814 | if (expensive_worm_in_rect(&worms[worm_idx], x, y, ARGH_SIZE, ARGH_SIZE)) { |
1832 | int tries = 0; | 1815 | int tries = 0; |
1833 | srand(seed); | 1816 | rb->srand(seed); |
1834 | 1817 | ||
1835 | tries = make_argh(0); | 1818 | tries = make_argh(0); |
1836 | if ((x == arghx[0] && y == arghy[0]) || tries < 2) { | 1819 | if ((x == arghx[0] && y == arghy[0]) || tries < 2) { |
1837 | failures ++; | 1820 | failures ++; |
1838 | } | 1821 | } |
1839 | 1822 | ||
1840 | snprintf(buf, sizeof buf, "(%d;%d) fail%d try%d", x, y, failures, tries); | 1823 | rb->snprintf(buf, sizeof buf, "(%d;%d) fail%d try%d", x, y, failures, tries); |
1841 | lcd_putsxy(0, LCD_HEIGHT - 8, buf); | 1824 | rb->lcd_putsxy(0, LCD_HEIGHT - 8, buf); |
1842 | lcd_update(); | 1825 | rb->lcd_update(); |
1843 | lcd_invertrect(x + FIELD_RECT_X, y+ FIELD_RECT_Y, ARGH_SIZE, ARGH_SIZE); | 1826 | rb->lcd_invertrect(x + FIELD_RECT_X, y+ FIELD_RECT_Y, ARGH_SIZE, ARGH_SIZE); |
1844 | lcd_update(); | 1827 | rb->lcd_update(); |
1845 | draw_argh(0); | 1828 | draw_argh(0); |
1846 | lcd_update(); | 1829 | rb->lcd_update(); |
1847 | lcd_invertrect(x + FIELD_RECT_X, y + FIELD_RECT_Y, ARGH_SIZE, ARGH_SIZE); | 1830 | rb->lcd_invertrect(x + FIELD_RECT_X, y + FIELD_RECT_Y, ARGH_SIZE, ARGH_SIZE); |
1848 | lcd_clearrect(arghx[0] + FIELD_RECT_X, arghy[0] + FIELD_RECT_Y, ARGH_SIZE, ARGH_SIZE); | 1831 | rb->lcd_clearrect(arghx[0] + FIELD_RECT_X, arghy[0] + FIELD_RECT_Y, ARGH_SIZE, ARGH_SIZE); |
1849 | 1832 | ||
1850 | if (failures > last_failures) { | 1833 | if (failures > last_failures) { |
1851 | button_get(true); | 1834 | rb->button_get(true); |
1852 | } | 1835 | } |
1853 | last_failures = failures; | 1836 | last_failures = failures; |
1854 | hit ++; | 1837 | hit ++; |
@@ -1860,7 +1843,7 @@ static void test_make_argh(void){ | |||
1860 | static void test_worm_argh_collision_in_moves(void) { | 1843 | static void test_worm_argh_collision_in_moves(void) { |
1861 | int hit_count = 0; | 1844 | int hit_count = 0; |
1862 | int i; | 1845 | int i; |
1863 | lcd_clear_display(); | 1846 | rb->lcd_clear_display(); |
1864 | init_worm(&worms[0], 10, 20); | 1847 | init_worm(&worms[0], 10, 20); |
1865 | 1848 | ||
1866 | arghx[0] = 20; | 1849 | arghx[0] = 20; |
@@ -1875,12 +1858,12 @@ static void test_worm_argh_collision_in_moves(void) { | |||
1875 | if (worm_argh_collision_in_moves(&worms[0], 0, 5)){ | 1858 | if (worm_argh_collision_in_moves(&worms[0], 0, 5)){ |
1876 | hit_count ++; | 1859 | hit_count ++; |
1877 | } | 1860 | } |
1878 | snprintf(buf, sizeof buf, "in 5 moves hits: %d", hit_count); | 1861 | rb->snprintf(buf, sizeof buf, "in 5 moves hits: %d", hit_count); |
1879 | lcd_putsxy(0, LCD_HEIGHT - 8, buf); | 1862 | rb->lcd_putsxy(0, LCD_HEIGHT - 8, buf); |
1880 | lcd_update(); | 1863 | rb->lcd_update(); |
1881 | } | 1864 | } |
1882 | if (hit_count != ARGH_SIZE + 5) { | 1865 | if (hit_count != ARGH_SIZE + 5) { |
1883 | button_get(true); | 1866 | rb->button_get(true); |
1884 | } | 1867 | } |
1885 | } | 1868 | } |
1886 | #endif /* DEBUG_WORMLET */ | 1869 | #endif /* DEBUG_WORMLET */ |
@@ -1888,14 +1871,18 @@ static void test_worm_argh_collision_in_moves(void) { | |||
1888 | extern bool use_old_rect; | 1871 | extern bool use_old_rect; |
1889 | 1872 | ||
1890 | /** | 1873 | /** |
1891 | * Main entry point from the menu to start the game control. | 1874 | * Main entry point |
1892 | */ | 1875 | */ |
1893 | bool wormlet(void) | 1876 | enum plugin_status plugin_start(struct plugin_api* api, void* parameter) |
1894 | { | 1877 | { |
1895 | bool worm_dead = false; | 1878 | bool worm_dead = false; |
1896 | int button; | 1879 | int button; |
1897 | 1880 | ||
1898 | lcd_setfont(FONT_SYSFIXED); | 1881 | TEST_PLUGIN_API(api); |
1882 | (void)(parameter); | ||
1883 | |||
1884 | rb = api; | ||
1885 | rb->lcd_setfont(FONT_SYSFIXED); | ||
1899 | 1886 | ||
1900 | #ifdef DEBUG_WORMLET | 1887 | #ifdef DEBUG_WORMLET |
1901 | testline_in_rect(); | 1888 | testline_in_rect(); |
@@ -1905,44 +1892,44 @@ bool wormlet(void) | |||
1905 | test_worm_argh_collision(); | 1892 | test_worm_argh_collision(); |
1906 | test_specific_worm_collision(); | 1893 | test_specific_worm_collision(); |
1907 | #endif | 1894 | #endif |
1908 | lcd_setmargins(0,0); | ||
1909 | 1895 | ||
1910 | /* Setup screen */ | 1896 | /* Setup screen */ |
1911 | do { | 1897 | do { |
1912 | char buf[20]; | 1898 | char buf[20]; |
1913 | lcd_clear_display(); | 1899 | char* ptr; |
1900 | rb->lcd_clear_display(); | ||
1914 | 1901 | ||
1915 | /* first line players */ | 1902 | /* first line players */ |
1916 | snprintf(buf, sizeof buf, str(LANG_WORMLET_PLAYERS), players); | 1903 | rb->snprintf(buf, sizeof buf, "%d Players UP/DN", players); |
1917 | lcd_puts(0, 0, buf); | 1904 | rb->lcd_puts(0, 0, buf); |
1918 | 1905 | ||
1919 | /* second line worms */ | 1906 | /* second line worms */ |
1920 | snprintf(buf, sizeof buf, str(LANG_WORMLET_WORMS), worm_count); | 1907 | rb->snprintf(buf, sizeof buf, "%d Worms L/R", worm_count); |
1921 | lcd_puts(0, 1, buf); | 1908 | rb->lcd_puts(0, 1, buf); |
1922 | 1909 | ||
1923 | /* third line control */ | 1910 | /* third line control */ |
1924 | if (players > 1) { | 1911 | if (players > 1) { |
1925 | if (use_remote) { | 1912 | if (use_remote) { |
1926 | snprintf(buf, sizeof buf, str(LANG_WORMLET_REMOTE_CTRL)); | 1913 | ptr = "Remote Control F1"; |
1927 | } else { | 1914 | } else { |
1928 | snprintf(buf, sizeof buf, str(LANG_WORMLET_NO_REM_CTRL)); | 1915 | ptr = "No Rem. Control F1"; |
1929 | } | 1916 | } |
1930 | } else { | 1917 | } else { |
1931 | if (players > 0) { | 1918 | if (players > 0) { |
1932 | if (use_remote) { | 1919 | if (use_remote) { |
1933 | snprintf(buf, sizeof buf, str(LANG_WORMLET_2_KEY_CTRL)); | 1920 | ptr = "2 Key Control F1"; |
1934 | } else { | 1921 | } else { |
1935 | snprintf(buf, sizeof buf, str(LANG_WORMLET_4_KEY_CTRL)); | 1922 | ptr = "4 Key Control F1"; |
1936 | } | 1923 | } |
1937 | } else { | 1924 | } else { |
1938 | snprintf(buf, sizeof buf, str(LANG_WORMLET_NO_CONTROL)); | 1925 | ptr = "Out Of Control"; |
1939 | } | 1926 | } |
1940 | } | 1927 | } |
1941 | lcd_puts(0, 2, buf); | 1928 | rb->lcd_puts(0, 2, ptr); |
1942 | lcd_update(); | 1929 | rb->lcd_update(); |
1943 | 1930 | ||
1944 | /* user selection */ | 1931 | /* user selection */ |
1945 | button = button_get(true); | 1932 | button = rb->button_get(true); |
1946 | switch (button) { | 1933 | switch (button) { |
1947 | case BUTTON_UP: | 1934 | case BUTTON_UP: |
1948 | if (players < 3) { | 1935 | if (players < 3) { |
@@ -1981,14 +1968,13 @@ bool wormlet(void) | |||
1981 | break; | 1968 | break; |
1982 | 1969 | ||
1983 | case SYS_USB_CONNECTED: | 1970 | case SYS_USB_CONNECTED: |
1984 | usb_screen(); | 1971 | rb->usb_screen(); |
1985 | lcd_setfont(FONT_UI); | 1972 | return PLUGIN_USB_CONNECTED; |
1986 | return true; | ||
1987 | } | 1973 | } |
1988 | } while (button != BUTTON_PLAY && | 1974 | } while (button != BUTTON_PLAY && |
1989 | button != BUTTON_OFF && button != BUTTON_ON); | 1975 | button != BUTTON_OFF && button != BUTTON_ON); |
1990 | 1976 | ||
1991 | lcd_clear_display(); | 1977 | rb->lcd_clear_display(); |
1992 | /* end of setup */ | 1978 | /* end of setup */ |
1993 | 1979 | ||
1994 | do { | 1980 | do { |
@@ -2008,7 +1994,7 @@ bool wormlet(void) | |||
2008 | via BUTTON_OFF -> no need to wait for buttons. */ | 1994 | via BUTTON_OFF -> no need to wait for buttons. */ |
2009 | if (worm_dead) { | 1995 | if (worm_dead) { |
2010 | do { | 1996 | do { |
2011 | button = button_get(true); | 1997 | button = rb->button_get(true); |
2012 | } | 1998 | } |
2013 | /* BUTTON_ON -> start new game */ | 1999 | /* BUTTON_ON -> start new game */ |
2014 | /* BUTTON_OFF -> back to game menu */ | 2000 | /* BUTTON_OFF -> back to game menu */ |
@@ -2017,20 +2003,7 @@ bool wormlet(void) | |||
2017 | } | 2003 | } |
2018 | while (button != BUTTON_OFF); | 2004 | while (button != BUTTON_OFF); |
2019 | 2005 | ||
2020 | lcd_setfont(FONT_UI); | 2006 | return PLUGIN_OK; |
2021 | |||
2022 | return false; | ||
2023 | } | 2007 | } |
2024 | 2008 | ||
2025 | 2009 | #endif | |
2026 | #endif /* USE_GAMES */ | ||
2027 | |||
2028 | |||
2029 | |||
2030 | |||
2031 | |||
2032 | |||
2033 | |||
2034 | |||
2035 | |||
2036 | |||
diff --git a/apps/recorder/icons.c b/apps/recorder/icons.c index af0352094f..25d34d7591 100644 --- a/apps/recorder/icons.c +++ b/apps/recorder/icons.c | |||
@@ -64,6 +64,7 @@ unsigned char bitmap_icons_6x8[LastIcon][6] = | |||
64 | { 0x3e, 0x2a, 0x3e, 0x2a, 0x2a, 0x3e }, /* Language file */ | 64 | { 0x3e, 0x2a, 0x3e, 0x2a, 0x2a, 0x3e }, /* Language file */ |
65 | { 0x55, 0x55, 0x55, 0x55, 0x55, 0x55 }, /* Text file */ | 65 | { 0x55, 0x55, 0x55, 0x55, 0x55, 0x55 }, /* Text file */ |
66 | { 0x4e, 0x51, 0x51, 0x40, 0x55, 0x55 }, /* Config file */ | 66 | { 0x4e, 0x51, 0x51, 0x40, 0x55, 0x55 }, /* Config file */ |
67 | { 0x0a, 0x0a, 0x5f, 0x4e, 0x24, 0x18 }, /* Plugin file */ | ||
67 | }; | 68 | }; |
68 | 69 | ||
69 | unsigned char bitmap_icons_7x8[][7] = | 70 | unsigned char bitmap_icons_7x8[][7] = |
diff --git a/apps/recorder/icons.h b/apps/recorder/icons.h index a7858cd0ae..40418468f3 100644 --- a/apps/recorder/icons.h +++ b/apps/recorder/icons.h | |||
@@ -29,6 +29,7 @@ enum icons_6x8 { | |||
29 | Folder, Directory, Playlist, Repeat, | 29 | Folder, Directory, Playlist, Repeat, |
30 | Selected, Cursor, Wps, Mod_Ajz, | 30 | Selected, Cursor, Wps, Mod_Ajz, |
31 | Font, Language, Text, Config, | 31 | Font, Language, Text, Config, |
32 | Plugin, | ||
32 | LastIcon | 33 | LastIcon |
33 | }; | 34 | }; |
34 | 35 | ||
diff --git a/apps/recorder/sokoban.c b/apps/recorder/sokoban.c deleted file mode 100644 index d28e32f430..0000000000 --- a/apps/recorder/sokoban.c +++ /dev/null | |||
@@ -1,891 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 Eric Linenberg | ||
11 | * February 2003: Robert Hak performs a cleanup/rewrite/feature addition. | ||
12 | * Eric smiles. Bjorn cries. Linus say 'huh?'. | ||
13 | * | ||
14 | * All files in this archive are subject to the GNU General Public License. | ||
15 | * See the file COPYING in the source tree root for full license agreement. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #include "config.h" | ||
23 | #include "options.h" | ||
24 | |||
25 | #ifdef USE_GAMES | ||
26 | |||
27 | #include <sprintf.h> | ||
28 | #include "ctype.h" | ||
29 | #include "sokoban.h" | ||
30 | #include "lcd.h" | ||
31 | #include "button.h" | ||
32 | #include "kernel.h" | ||
33 | #include "menu.h" | ||
34 | #include "screens.h" | ||
35 | #include "font.h" | ||
36 | #include "file.h" | ||
37 | #include "misc.h" | ||
38 | #include "debug.h" | ||
39 | |||
40 | #ifdef SIMULATOR | ||
41 | #include <stdio.h> | ||
42 | #endif | ||
43 | #include <string.h> | ||
44 | #include "lang.h" | ||
45 | #include "sprintf.h" | ||
46 | |||
47 | #define SOKOBAN_TITLE "Sokoban" | ||
48 | #define SOKOBAN_TITLE_FONT 2 | ||
49 | |||
50 | #define LEVELS_FILE "/.rockbox/sokoban/levels.txt" | ||
51 | |||
52 | #define ROWS 16 | ||
53 | #define COLS 20 | ||
54 | #define MAX_UNDOS 5 | ||
55 | |||
56 | #define SOKOBAN_LEVEL_SIZE (ROWS*COLS) | ||
57 | |||
58 | static void init_undo(void); | ||
59 | static void undo(void); | ||
60 | static void add_undo(int button); | ||
61 | |||
62 | static int get_level(char *level, int level_size); | ||
63 | static int get_level_count(void); | ||
64 | static int load_level(void); | ||
65 | static void draw_level(void); | ||
66 | |||
67 | static void init_boards(void); | ||
68 | static void update_screen(void); | ||
69 | static bool sokoban_loop(void); | ||
70 | |||
71 | /* The Location, Undo and LevelInfo structs are OO-flavored. | ||
72 | * (oooh!-flavored as Schnueff puts it.) It makes more you have to know, | ||
73 | * but the overall data layout becomes more manageable. */ | ||
74 | |||
75 | /* We use the same three values in 2 structs. Makeing them a struct | ||
76 | * hopefully ensures that if you change things in one, the other changes | ||
77 | * as well. */ | ||
78 | struct LevelInfo { | ||
79 | short level; | ||
80 | short moves; | ||
81 | short boxes_to_go; | ||
82 | }; | ||
83 | |||
84 | /* What a given location on the board looks like at a given time */ | ||
85 | struct Location { | ||
86 | char spot; | ||
87 | short row; | ||
88 | short col; | ||
89 | }; | ||
90 | |||
91 | /* A single level of undo. Each undo move can affect upto, | ||
92 | * but not more then, 3 spots on the board */ | ||
93 | struct Undo { | ||
94 | struct LevelInfo level; | ||
95 | struct Location location[3]; | ||
96 | }; | ||
97 | |||
98 | /* Our full undo history */ | ||
99 | static struct UndoInfo { | ||
100 | short count; /* How many undos are there in history */ | ||
101 | short current; /* Which history is the current undo */ | ||
102 | struct Undo history[MAX_UNDOS]; | ||
103 | } undo_info; | ||
104 | |||
105 | /* Our playing board */ | ||
106 | static struct BoardInfo { | ||
107 | char board[ROWS][COLS]; | ||
108 | struct LevelInfo level; | ||
109 | struct Location player; | ||
110 | int max_level; /* How many levels do we have? */ | ||
111 | int level_offset; /* Where in the level file is this level */ | ||
112 | int loaded_level; /* Which level is in memory */ | ||
113 | } current_info; | ||
114 | |||
115 | |||
116 | static void init_undo(void) | ||
117 | { | ||
118 | undo_info.count = 0; | ||
119 | undo_info.current = 0; | ||
120 | } | ||
121 | |||
122 | static void undo(void) | ||
123 | { | ||
124 | struct Undo *undo; | ||
125 | int i = 0; | ||
126 | short row, col; | ||
127 | |||
128 | if (undo_info.count == 0) | ||
129 | return; | ||
130 | |||
131 | /* Update board info */ | ||
132 | undo = &undo_info.history[undo_info.current]; | ||
133 | |||
134 | current_info.level = undo->level; | ||
135 | current_info.player = undo->location[0]; | ||
136 | |||
137 | row = undo->location[0].row; | ||
138 | col = undo->location[0].col; | ||
139 | current_info.board[row][col] = '@'; | ||
140 | |||
141 | /* Update the two other possible spots */ | ||
142 | for (i = 1; i < 3; i++) { | ||
143 | if (undo->location[i].spot != '\0') { | ||
144 | row = undo->location[i].row; | ||
145 | col = undo->location[i].col; | ||
146 | current_info.board[row][col] = undo->location[i].spot; | ||
147 | undo->location[i].spot = '\0'; | ||
148 | } | ||
149 | } | ||
150 | |||
151 | /* Remove this undo from the list */ | ||
152 | if (undo_info.current == 0) { | ||
153 | if (undo_info.count > 1) | ||
154 | undo_info.current = MAX_UNDOS - 1; | ||
155 | } else { | ||
156 | undo_info.current--; | ||
157 | } | ||
158 | |||
159 | undo_info.count--; | ||
160 | |||
161 | return; | ||
162 | } | ||
163 | |||
164 | static void add_undo(int button) | ||
165 | { | ||
166 | struct Undo *undo; | ||
167 | int row, col, i; | ||
168 | bool storable; | ||
169 | |||
170 | if ((button != BUTTON_LEFT) && (button != BUTTON_RIGHT) && | ||
171 | (button != BUTTON_UP) && (button != BUTTON_DOWN)) | ||
172 | return; | ||
173 | |||
174 | if (undo_info.count != 0) { | ||
175 | if (undo_info.current < (MAX_UNDOS - 1)) | ||
176 | undo_info.current++; | ||
177 | else | ||
178 | undo_info.current = 0; | ||
179 | } | ||
180 | |||
181 | /* Make what follows more readable */ | ||
182 | undo = &undo_info.history[undo_info.current]; | ||
183 | |||
184 | /* Store our level info */ | ||
185 | undo->level = current_info.level; | ||
186 | |||
187 | /* Store our player info */ | ||
188 | undo->location[0] = current_info.player; | ||
189 | |||
190 | /* Now we need to store upto 2 blocks that may be affected. | ||
191 | * If player.spot is NULL, then there is no info stored | ||
192 | * for that block */ | ||
193 | |||
194 | row = current_info.player.row; | ||
195 | col = current_info.player.col; | ||
196 | |||
197 | /* This must stay as _1_ because the first block (0) is the player */ | ||
198 | for (i = 1; i < 3; i++) { | ||
199 | storable = true; | ||
200 | |||
201 | switch (button) { | ||
202 | case BUTTON_LEFT: | ||
203 | col--; | ||
204 | if (col < 0) | ||
205 | storable = false; | ||
206 | break; | ||
207 | |||
208 | case BUTTON_RIGHT: | ||
209 | col++; | ||
210 | if (col >= COLS) | ||
211 | storable = false; | ||
212 | break; | ||
213 | |||
214 | case BUTTON_UP: | ||
215 | row--; | ||
216 | if (row < 0) | ||
217 | storable = false; | ||
218 | break; | ||
219 | |||
220 | case BUTTON_DOWN: | ||
221 | row++; | ||
222 | if (row >= ROWS) | ||
223 | storable = false; | ||
224 | break; | ||
225 | |||
226 | default: | ||
227 | return; | ||
228 | } | ||
229 | |||
230 | if (storable) { | ||
231 | undo->location[i].col = col; | ||
232 | undo->location[i].row = row; | ||
233 | undo->location[i].spot = current_info.board[row][col]; | ||
234 | } else { | ||
235 | undo->location[i].spot = '\0'; | ||
236 | } | ||
237 | } | ||
238 | |||
239 | if (undo_info.count < MAX_UNDOS) | ||
240 | undo_info.count++; | ||
241 | } | ||
242 | |||
243 | static void init_boards(void) | ||
244 | { | ||
245 | current_info.level.level = 0; | ||
246 | current_info.level.moves = 0; | ||
247 | current_info.level.boxes_to_go = 0; | ||
248 | current_info.player.row = 0; | ||
249 | current_info.player.col = 0; | ||
250 | current_info.player.spot = ' '; | ||
251 | current_info.max_level = 0; | ||
252 | current_info.level_offset = 0; | ||
253 | current_info.loaded_level = 0; | ||
254 | |||
255 | init_undo(); | ||
256 | } | ||
257 | |||
258 | static int get_level_count(void) | ||
259 | { | ||
260 | int fd = 0; | ||
261 | int len, lastlen = 0; | ||
262 | char buffer[COLS + 3]; /* COLS plus CR/LF and \0 */ | ||
263 | |||
264 | if ((fd = open(LEVELS_FILE, O_RDONLY)) < 0) { | ||
265 | splash(0, 0, true, "Unable to open %s", LEVELS_FILE); | ||
266 | return -1; | ||
267 | } | ||
268 | |||
269 | while(1) { | ||
270 | len = read_line(fd, buffer, sizeof(buffer)); | ||
271 | if(len <= 0) | ||
272 | break; | ||
273 | |||
274 | /* Two short lines in a row means new level */ | ||
275 | if(len < 3 && lastlen < 3) | ||
276 | current_info.max_level++; | ||
277 | |||
278 | lastlen = len; | ||
279 | } | ||
280 | |||
281 | DEBUGF("%d levels loaded\n", current_info.max_level); | ||
282 | close(fd); | ||
283 | return 0; | ||
284 | } | ||
285 | |||
286 | static int get_level(char *level, int level_size) | ||
287 | { | ||
288 | int fd = 0, i = 0; | ||
289 | int nread = 0; | ||
290 | int count = 0; | ||
291 | int len, lastlen = 0; | ||
292 | int level_ct = 1; | ||
293 | unsigned char buffer[SOKOBAN_LEVEL_SIZE * 2]; | ||
294 | bool level_found = false; | ||
295 | |||
296 | /* open file */ | ||
297 | if ((fd = open(LEVELS_FILE, O_RDONLY)) < 0) | ||
298 | return -1; | ||
299 | |||
300 | /* Lets not reparse the full file if we can avoid it */ | ||
301 | if (current_info.loaded_level < current_info.level.level) { | ||
302 | lseek(fd, current_info.level_offset, SEEK_SET); | ||
303 | level_ct = current_info.loaded_level; | ||
304 | } | ||
305 | |||
306 | if(current_info.level.level > 1) { | ||
307 | while(!level_found) { | ||
308 | len = read_line(fd, buffer, SOKOBAN_LEVEL_SIZE); | ||
309 | if(len <= 0) { | ||
310 | close(fd); | ||
311 | return -1; | ||
312 | } | ||
313 | |||
314 | /* Two short lines in a row means new level */ | ||
315 | if(len < 3 && lastlen < 3) { | ||
316 | level_ct++; | ||
317 | if(level_ct == current_info.level.level) | ||
318 | level_found = true; | ||
319 | } | ||
320 | lastlen = len; | ||
321 | } | ||
322 | } | ||
323 | |||
324 | /* Remember the current offset */ | ||
325 | current_info.level_offset = lseek(fd, 0, SEEK_CUR); | ||
326 | |||
327 | /* read a full buffer chunk from here */ | ||
328 | nread = read(fd, buffer, sizeof(buffer)-1); | ||
329 | if (nread < 0) | ||
330 | return -1; | ||
331 | buffer[nread] = 0; | ||
332 | |||
333 | close(fd); | ||
334 | |||
335 | /* If we read less then a level, error */ | ||
336 | if (nread < level_size) | ||
337 | return -1; | ||
338 | |||
339 | /* Load our new level */ | ||
340 | for(i=0, count=0; (count < nread) && (i<level_size);) { | ||
341 | if (buffer[count] != '\n' && buffer[count] != '\r') | ||
342 | level[i++] = buffer[count]; | ||
343 | count++; | ||
344 | } | ||
345 | level[i] = 0; | ||
346 | |||
347 | current_info.loaded_level = current_info.level.level; | ||
348 | return 0; | ||
349 | } | ||
350 | |||
351 | /* return non-zero on error */ | ||
352 | static int load_level(void) | ||
353 | { | ||
354 | short c = 0; | ||
355 | short r = 0; | ||
356 | short i = 0; | ||
357 | char level[ROWS*COLS+1]; | ||
358 | int x = 0; | ||
359 | |||
360 | current_info.player.spot=' '; | ||
361 | current_info.level.boxes_to_go = 0; | ||
362 | current_info.level.moves = 0; | ||
363 | |||
364 | if (get_level(level, sizeof(level)) != 0) | ||
365 | return -1; | ||
366 | |||
367 | i = 0; | ||
368 | for (r = 0; r < ROWS; r++) { | ||
369 | x++; | ||
370 | for (c = 0; c < COLS; c++, i++) { | ||
371 | current_info.board[r][c] = level[i]; | ||
372 | |||
373 | if (current_info.board[r][c] == '.') | ||
374 | current_info.level.boxes_to_go++; | ||
375 | |||
376 | else if (current_info.board[r][c] == '@') { | ||
377 | current_info.player.row = r; | ||
378 | current_info.player.col = c; | ||
379 | } | ||
380 | } | ||
381 | } | ||
382 | |||
383 | return 0; | ||
384 | } | ||
385 | |||
386 | static void update_screen(void) | ||
387 | { | ||
388 | short b = 0, c = 0; | ||
389 | short rows = 0, cols = 0; | ||
390 | char s[25]; | ||
391 | |||
392 | short magnify = 4; | ||
393 | |||
394 | /* load the board to the screen */ | ||
395 | for (rows=0 ; rows < ROWS ; rows++) { | ||
396 | for (cols = 0 ; cols < COLS ; cols++) { | ||
397 | c = cols * magnify; | ||
398 | b = rows * magnify; | ||
399 | |||
400 | switch(current_info.board[rows][cols]) { | ||
401 | case 'X': /* black space */ | ||
402 | lcd_drawrect(c, b, magnify, magnify); | ||
403 | lcd_drawrect(c+1, b+1, 2, 2); | ||
404 | break; | ||
405 | |||
406 | case '#': /* this is a wall */ | ||
407 | lcd_drawpixel(c, b); | ||
408 | lcd_drawpixel(c+2, b); | ||
409 | lcd_drawpixel(c+1, b+1); | ||
410 | lcd_drawpixel(c+3, b+1); | ||
411 | lcd_drawpixel(c, b+2); | ||
412 | lcd_drawpixel(c+2, b+2); | ||
413 | lcd_drawpixel(c+1, b+3); | ||
414 | lcd_drawpixel(c+3, b+3); | ||
415 | break; | ||
416 | |||
417 | case '.': /* this is a home location */ | ||
418 | lcd_drawrect(c+1, b+1, 2, 2); | ||
419 | break; | ||
420 | |||
421 | case '$': /* this is a box */ | ||
422 | lcd_drawrect(c, b, magnify, magnify); | ||
423 | break; | ||
424 | |||
425 | case '@': /* this is you */ | ||
426 | lcd_drawline(c+1, b, c+2, b); | ||
427 | lcd_drawline(c, b+1, c+3, b+1); | ||
428 | lcd_drawline(c+1, b+2, c+2, b+2); | ||
429 | |||
430 | lcd_drawpixel(c, b+3); | ||
431 | lcd_drawpixel(c+3, b+3); | ||
432 | break; | ||
433 | |||
434 | case '%': /* this is a box on a home spot */ | ||
435 | lcd_drawrect(c, b, magnify, magnify); | ||
436 | lcd_drawrect(c+1, b+1, 2, 2); | ||
437 | break; | ||
438 | } | ||
439 | } | ||
440 | } | ||
441 | |||
442 | |||
443 | snprintf(s, sizeof(s), "%d", current_info.level.level); | ||
444 | lcd_putsxy(86, 22, s); | ||
445 | snprintf(s, sizeof(s), "%d", current_info.level.moves); | ||
446 | lcd_putsxy(86, 54, s); | ||
447 | |||
448 | lcd_drawrect(80,0,32,32); | ||
449 | lcd_drawrect(80,32,32,64); | ||
450 | lcd_putsxy(81, 10, str(LANG_SOKOBAN_LEVEL)); | ||
451 | lcd_putsxy(81, 42, str(LANG_SOKOBAN_MOVE)); | ||
452 | |||
453 | /* print out the screen */ | ||
454 | lcd_update(); | ||
455 | } | ||
456 | |||
457 | static void draw_level(void) | ||
458 | { | ||
459 | load_level(); | ||
460 | lcd_clear_display(); | ||
461 | update_screen(); | ||
462 | } | ||
463 | |||
464 | static bool sokoban_loop(void) | ||
465 | { | ||
466 | char new_spot; | ||
467 | bool moved = true; | ||
468 | int i = 0, button = 0; | ||
469 | short r = 0, c = 0; | ||
470 | |||
471 | current_info.level.level = 1; | ||
472 | |||
473 | load_level(); | ||
474 | update_screen(); | ||
475 | |||
476 | while (1) { | ||
477 | moved = true; | ||
478 | |||
479 | r = current_info.player.row; | ||
480 | c = current_info.player.col; | ||
481 | |||
482 | button = button_get(true); | ||
483 | |||
484 | add_undo(button); | ||
485 | |||
486 | switch(button) | ||
487 | { | ||
488 | case BUTTON_OFF: | ||
489 | /* get out of here */ | ||
490 | return false; | ||
491 | |||
492 | case BUTTON_ON: | ||
493 | case BUTTON_ON | BUTTON_REPEAT: | ||
494 | /* this is UNDO */ | ||
495 | undo(); | ||
496 | lcd_clear_display(); | ||
497 | update_screen(); | ||
498 | moved = false; | ||
499 | break; | ||
500 | |||
501 | case BUTTON_F3: | ||
502 | case BUTTON_F3 | BUTTON_REPEAT: | ||
503 | /* increase level */ | ||
504 | init_undo(); | ||
505 | current_info.level.boxes_to_go=0; | ||
506 | moved = true; | ||
507 | break; | ||
508 | |||
509 | case BUTTON_F1: | ||
510 | case BUTTON_F1 | BUTTON_REPEAT: | ||
511 | /* previous level */ | ||
512 | init_undo(); | ||
513 | if (current_info.level.level > 1) | ||
514 | current_info.level.level--; | ||
515 | |||
516 | draw_level(); | ||
517 | moved = false; | ||
518 | break; | ||
519 | |||
520 | case BUTTON_F2: | ||
521 | case BUTTON_F2 | BUTTON_REPEAT: | ||
522 | /* same level */ | ||
523 | init_undo(); | ||
524 | draw_level(); | ||
525 | moved = false; | ||
526 | break; | ||
527 | |||
528 | case BUTTON_LEFT: | ||
529 | switch(current_info.board[r][c-1]) | ||
530 | { | ||
531 | case ' ': /* if it is a blank spot */ | ||
532 | case '.': /* if it is a home spot */ | ||
533 | new_spot = current_info.board[r][c-1]; | ||
534 | current_info.board[r][c-1] = '@'; | ||
535 | current_info.board[r][c] = current_info.player.spot; | ||
536 | current_info.player.spot = new_spot; | ||
537 | break; | ||
538 | |||
539 | case '$': | ||
540 | switch(current_info.board[r][c-2]) | ||
541 | { | ||
542 | case ' ': /* going from blank to blank */ | ||
543 | current_info.board[r][c-2] = current_info.board[r][c-1]; | ||
544 | current_info.board[r][c-1] = current_info.board[r][c]; | ||
545 | current_info.board[r][c] = current_info.player.spot; | ||
546 | current_info.player.spot = ' '; | ||
547 | break; | ||
548 | |||
549 | case '.': /* going from a blank to home */ | ||
550 | current_info.board[r][c-2] = '%'; | ||
551 | current_info.board[r][c-1] = current_info.board[r][c]; | ||
552 | current_info.board[r][c] = current_info.player.spot; | ||
553 | current_info.player.spot = ' '; | ||
554 | current_info.level.boxes_to_go--; | ||
555 | break; | ||
556 | |||
557 | default: | ||
558 | moved = false; | ||
559 | break; | ||
560 | } | ||
561 | break; | ||
562 | |||
563 | case '%': | ||
564 | switch(current_info.board[r][c-2]) { | ||
565 | case ' ': /* we are going from a home to a blank */ | ||
566 | current_info.board[r][c-2] = '$'; | ||
567 | current_info.board[r][c-1] = current_info.board[r][c]; | ||
568 | current_info.board[r][c] = current_info.player.spot; | ||
569 | current_info.player.spot = '.'; | ||
570 | current_info.level.boxes_to_go++; | ||
571 | break; | ||
572 | |||
573 | case '.': /* if we are going from a home to home */ | ||
574 | current_info.board[r][c-2] = '%'; | ||
575 | current_info.board[r][c-1] = current_info.board[r][c]; | ||
576 | current_info.board[r][c] = current_info.player.spot; | ||
577 | current_info.player.spot = '.'; | ||
578 | break; | ||
579 | |||
580 | default: | ||
581 | moved = false; | ||
582 | break; | ||
583 | } | ||
584 | break; | ||
585 | |||
586 | default: | ||
587 | moved = false; | ||
588 | break; | ||
589 | } | ||
590 | |||
591 | if (moved) | ||
592 | current_info.player.col--; | ||
593 | break; | ||
594 | |||
595 | case BUTTON_RIGHT: /* if it is a blank spot */ | ||
596 | switch(current_info.board[r][c+1]) { | ||
597 | case ' ': | ||
598 | case '.': /* if it is a home spot */ | ||
599 | new_spot = current_info.board[r][c+1]; | ||
600 | current_info.board[r][c+1] = '@'; | ||
601 | current_info.board[r][c] = current_info.player.spot; | ||
602 | current_info.player.spot = new_spot; | ||
603 | break; | ||
604 | |||
605 | case '$': | ||
606 | switch(current_info.board[r][c+2]) { | ||
607 | case ' ': /* going from blank to blank */ | ||
608 | current_info.board[r][c+2] = current_info.board[r][c+1]; | ||
609 | current_info.board[r][c+1] = current_info.board[r][c]; | ||
610 | current_info.board[r][c] = current_info.player.spot; | ||
611 | current_info.player.spot = ' '; | ||
612 | break; | ||
613 | |||
614 | case '.': /* going from a blank to home */ | ||
615 | current_info.board[r][c+2] = '%'; | ||
616 | current_info.board[r][c+1] = current_info.board[r][c]; | ||
617 | current_info.board[r][c] = current_info.player.spot; | ||
618 | current_info.player.spot = ' '; | ||
619 | current_info.level.boxes_to_go--; | ||
620 | break; | ||
621 | |||
622 | default: | ||
623 | moved = false; | ||
624 | break; | ||
625 | } | ||
626 | break; | ||
627 | |||
628 | case '%': | ||
629 | switch(current_info.board[r][c+2]) { | ||
630 | case ' ': /* going from a home to a blank */ | ||
631 | current_info.board[r][c+2] = '$'; | ||
632 | current_info.board[r][c+1] = current_info.board[r][c]; | ||
633 | current_info.board[r][c] = current_info.player.spot; | ||
634 | current_info.player.spot = '.'; | ||
635 | current_info.level.boxes_to_go++; | ||
636 | break; | ||
637 | |||
638 | case '.': | ||
639 | current_info.board[r][c+2] = '%'; | ||
640 | current_info.board[r][c+1] = current_info.board[r][c]; | ||
641 | current_info.board[r][c] = current_info.player.spot; | ||
642 | current_info.player.spot = '.'; | ||
643 | break; | ||
644 | |||
645 | default: | ||
646 | moved = false; | ||
647 | break; | ||
648 | } | ||
649 | break; | ||
650 | |||
651 | default: | ||
652 | moved = false; | ||
653 | break; | ||
654 | } | ||
655 | |||
656 | if (moved) | ||
657 | current_info.player.col++; | ||
658 | break; | ||
659 | |||
660 | case BUTTON_UP: | ||
661 | switch(current_info.board[r-1][c]) { | ||
662 | case ' ': /* if it is a blank spot */ | ||
663 | case '.': /* if it is a home spot */ | ||
664 | new_spot = current_info.board[r-1][c]; | ||
665 | current_info.board[r-1][c] = '@'; | ||
666 | current_info.board[r][c] = current_info.player.spot; | ||
667 | current_info.player.spot = new_spot; | ||
668 | break; | ||
669 | |||
670 | case '$': | ||
671 | switch(current_info.board[r-2][c]) { | ||
672 | case ' ': /* going from blank to blank */ | ||
673 | current_info.board[r-2][c] = current_info.board[r-1][c]; | ||
674 | current_info.board[r-1][c] = current_info.board[r][c]; | ||
675 | current_info.board[r][c] = current_info.player.spot; | ||
676 | current_info.player.spot = ' '; | ||
677 | break; | ||
678 | |||
679 | case '.': /* going from a blank to home */ | ||
680 | current_info.board[r-2][c] = '%'; | ||
681 | current_info.board[r-1][c] = current_info.board[r][c]; | ||
682 | current_info.board[r][c] = current_info.player.spot; | ||
683 | current_info.player.spot = ' '; | ||
684 | current_info.level.boxes_to_go--; | ||
685 | break; | ||
686 | |||
687 | default: | ||
688 | moved = false; | ||
689 | break; | ||
690 | } | ||
691 | break; | ||
692 | |||
693 | case '%': | ||
694 | switch(current_info.board[r-2][c]) { | ||
695 | case ' ': /* we are going from a home to a blank */ | ||
696 | current_info.board[r-2][c] = '$'; | ||
697 | current_info.board[r-1][c] = current_info.board[r][c]; | ||
698 | current_info.board[r][c] = current_info.player.spot; | ||
699 | current_info.player.spot = '.'; | ||
700 | current_info.level.boxes_to_go++; | ||
701 | break; | ||
702 | |||
703 | case '.': /* if we are going from a home to home */ | ||
704 | current_info.board[r-2][c] = '%'; | ||
705 | current_info.board[r-1][c] = current_info.board[r][c]; | ||
706 | current_info.board[r][c] = current_info.player.spot; | ||
707 | current_info.player.spot = '.'; | ||
708 | break; | ||
709 | |||
710 | default: | ||
711 | moved = false; | ||
712 | break; | ||
713 | } | ||
714 | break; | ||
715 | |||
716 | default: | ||
717 | moved = false; | ||
718 | break; | ||
719 | } | ||
720 | |||
721 | if (moved) | ||
722 | current_info.player.row--; | ||
723 | break; | ||
724 | |||
725 | case BUTTON_DOWN: | ||
726 | switch(current_info.board[r+1][c]) { | ||
727 | case ' ': /* if it is a blank spot */ | ||
728 | case '.': /* if it is a home spot */ | ||
729 | new_spot = current_info.board[r+1][c]; | ||
730 | current_info.board[r+1][c] = '@'; | ||
731 | current_info.board[r][c] = current_info.player.spot; | ||
732 | current_info.player.spot = new_spot; | ||
733 | break; | ||
734 | |||
735 | case '$': | ||
736 | switch(current_info.board[r+2][c]) { | ||
737 | case ' ': /* going from blank to blank */ | ||
738 | current_info.board[r+2][c] = current_info.board[r+1][c]; | ||
739 | current_info.board[r+1][c] = current_info.board[r][c]; | ||
740 | current_info.board[r][c] = current_info.player.spot; | ||
741 | current_info.player.spot = ' '; | ||
742 | break; | ||
743 | |||
744 | case '.': /* going from a blank to home */ | ||
745 | current_info.board[r+2][c] = '%'; | ||
746 | current_info.board[r+1][c] = current_info.board[r][c]; | ||
747 | current_info.board[r][c] = current_info.player.spot; | ||
748 | current_info.player.spot = ' '; | ||
749 | current_info.level.boxes_to_go--; | ||
750 | break; | ||
751 | |||
752 | default: | ||
753 | moved = false; | ||
754 | break; | ||
755 | } | ||
756 | break; | ||
757 | |||
758 | case '%': | ||
759 | switch(current_info.board[r+2][c]) { | ||
760 | case ' ': /* going from a home to a blank */ | ||
761 | current_info.board[r+2][c] = '$'; | ||
762 | current_info.board[r+1][c] = current_info.board[r][c]; | ||
763 | current_info.board[r][c] = current_info.player.spot; | ||
764 | current_info.player.spot = '.'; | ||
765 | current_info.level.boxes_to_go++; | ||
766 | break; | ||
767 | |||
768 | case '.': /* going from a home to home */ | ||
769 | current_info.board[r+2][c] = '%'; | ||
770 | current_info.board[r+1][c] = current_info.board[r][c]; | ||
771 | current_info.board[r][c] = current_info.player.spot; | ||
772 | current_info.player.spot = '.'; | ||
773 | break; | ||
774 | |||
775 | default: | ||
776 | moved = false; | ||
777 | break; | ||
778 | } | ||
779 | break; | ||
780 | |||
781 | default: | ||
782 | moved = false; | ||
783 | break; | ||
784 | } | ||
785 | |||
786 | if (moved) | ||
787 | current_info.player.row++; | ||
788 | break; | ||
789 | |||
790 | case SYS_USB_CONNECTED: | ||
791 | usb_screen(); | ||
792 | return true; | ||
793 | |||
794 | default: | ||
795 | moved = false; | ||
796 | break; | ||
797 | } | ||
798 | |||
799 | if (moved) { | ||
800 | current_info.level.moves++; | ||
801 | lcd_clear_display(); | ||
802 | update_screen(); | ||
803 | } | ||
804 | |||
805 | /* We have completed this level */ | ||
806 | if (current_info.level.boxes_to_go == 0) { | ||
807 | current_info.level.level++; | ||
808 | |||
809 | /* clear undo stats */ | ||
810 | init_undo(); | ||
811 | |||
812 | lcd_clear_display(); | ||
813 | |||
814 | if (current_info.level.level > current_info.max_level) { | ||
815 | lcd_putsxy(10, 20, str(LANG_SOKOBAN_WIN)); | ||
816 | |||
817 | for (i = 0; i < 30000 ; i++) { | ||
818 | lcd_invertrect(0, 0, 111, 63); | ||
819 | lcd_update(); | ||
820 | |||
821 | button = button_get(false); | ||
822 | if (button && ((button & BUTTON_REL) != BUTTON_REL)) | ||
823 | break; | ||
824 | } | ||
825 | |||
826 | return false; | ||
827 | } | ||
828 | |||
829 | load_level(); | ||
830 | update_screen(); | ||
831 | } | ||
832 | |||
833 | } /* end while */ | ||
834 | |||
835 | return false; | ||
836 | } | ||
837 | |||
838 | |||
839 | bool sokoban(void) | ||
840 | { | ||
841 | bool result; | ||
842 | int w, h; | ||
843 | int len; | ||
844 | |||
845 | lcd_setfont(FONT_SYSFIXED); | ||
846 | |||
847 | lcd_getstringsize(SOKOBAN_TITLE, &w, &h); | ||
848 | |||
849 | /* Get horizontel centering for text */ | ||
850 | len = w; | ||
851 | if (len%2 != 0) | ||
852 | len =((len+1)/2)+(w/2); | ||
853 | else | ||
854 | len /= 2; | ||
855 | |||
856 | if (h%2 != 0) | ||
857 | h = (h/2)+1; | ||
858 | else | ||
859 | h /= 2; | ||
860 | |||
861 | lcd_clear_display(); | ||
862 | lcd_putsxy(LCD_WIDTH/2-len,(LCD_HEIGHT/2)-h, SOKOBAN_TITLE); | ||
863 | |||
864 | lcd_update(); | ||
865 | sleep(HZ*2); | ||
866 | |||
867 | lcd_clear_display(); | ||
868 | |||
869 | lcd_putsxy(3, 6, str(LANG_SOKOBAN_QUIT)); | ||
870 | lcd_putsxy(3, 16, str(LANG_SOKOBAN_ON)); | ||
871 | lcd_putsxy(3, 26, str(LANG_SOKOBAN_F1)); | ||
872 | lcd_putsxy(3, 36, str(LANG_SOKOBAN_F2)); | ||
873 | lcd_putsxy(3, 46, str(LANG_SOKOBAN_F3)); | ||
874 | |||
875 | lcd_update(); | ||
876 | sleep(HZ*2); | ||
877 | lcd_clear_display(); | ||
878 | |||
879 | init_boards(); | ||
880 | |||
881 | if (get_level_count() != 0) | ||
882 | return false; | ||
883 | |||
884 | result = sokoban_loop(); | ||
885 | |||
886 | lcd_setfont(FONT_UI); | ||
887 | |||
888 | return result; | ||
889 | } | ||
890 | |||
891 | #endif | ||
diff --git a/apps/recorder/sokoban.h b/apps/recorder/sokoban.h deleted file mode 100644 index f4f8fdd24f..0000000000 --- a/apps/recorder/sokoban.h +++ /dev/null | |||
@@ -1,28 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 Robert E. Hak | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #ifndef __SOKOBAN__ | ||
21 | #define __SOKOBAN__ | ||
22 | |||
23 | #include "menu.h" | ||
24 | |||
25 | bool sokoban(void); | ||
26 | |||
27 | #endif /*__SOKOBAN__ */ | ||
28 | |||
diff --git a/apps/recorder/tetris.c b/apps/recorder/tetris.c deleted file mode 100644 index 6302e40109..0000000000 --- a/apps/recorder/tetris.c +++ /dev/null | |||
@@ -1,438 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 1999 Mattis Wadman (nappe@sudac.org) | ||
11 | * | ||
12 | * Heavily modified for embedded use by Björn Stenberg (bjorn@haxx.se) | ||
13 | * | ||
14 | * All files in this archive are subject to the GNU General Public License. | ||
15 | * See the file COPYING in the source tree root for full license agreement. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #include "config.h" | ||
23 | #include "options.h" | ||
24 | |||
25 | #ifdef USE_GAMES | ||
26 | |||
27 | #include <stdbool.h> | ||
28 | #include <string.h> | ||
29 | #include "lcd.h" | ||
30 | #include "button.h" | ||
31 | #include "kernel.h" | ||
32 | #include "menu.h" | ||
33 | #include "screens.h" | ||
34 | #include "font.h" | ||
35 | |||
36 | #ifdef SIMULATOR | ||
37 | #include <stdio.h> | ||
38 | #endif | ||
39 | #include "sprintf.h" | ||
40 | #include "lang.h" | ||
41 | #define TETRIS_TITLE "Tetris!" | ||
42 | #define TETRIS_TITLE_FONT 1 | ||
43 | #define TETRIS_TITLE_XLOC 43 | ||
44 | #define TETRIS_TITLE_YLOC 15 | ||
45 | |||
46 | static const int start_x = 5; | ||
47 | static const int start_y = 5; | ||
48 | static const int max_x = 4 * 17; | ||
49 | static const int max_y = 3 * 10; | ||
50 | static const short level_speeds[10] = { | ||
51 | 1000, 900, 800, 700, 600, 500, 400, 300, 250, 200 | ||
52 | }; | ||
53 | static const int blocks = 7; | ||
54 | static const int block_frames[7] = {1,2,2,2,4,4,4}; | ||
55 | |||
56 | static int current_x, current_y, current_f, current_b; | ||
57 | static int level, score; | ||
58 | static int next_b, next_f; | ||
59 | static short lines; | ||
60 | static char virtual[LCD_WIDTH * LCD_HEIGHT]; | ||
61 | |||
62 | /* | ||
63 | block_data is built up the following way | ||
64 | |||
65 | first array index specifies the block number | ||
66 | second array index specifies the rotation of the block | ||
67 | third array index specifies: | ||
68 | 0: x-coordinates of pixels | ||
69 | 1: y-coordinates of pixels | ||
70 | fourth array index specifies the coordinate of a pixel | ||
71 | |||
72 | each block consists of four pixels whose relative coordinates are given | ||
73 | with block_data | ||
74 | */ | ||
75 | |||
76 | static const char block_data[7][4][2][4] = | ||
77 | { | ||
78 | { | ||
79 | {{0,1,0,1},{0,0,1,1}} | ||
80 | }, | ||
81 | { | ||
82 | {{0,1,1,2},{1,1,0,0}}, | ||
83 | {{0,0,1,1},{0,1,1,2}} | ||
84 | }, | ||
85 | { | ||
86 | {{0,1,1,2},{0,0,1,1}}, | ||
87 | {{1,1,0,0},{0,1,1,2}} | ||
88 | }, | ||
89 | { | ||
90 | {{1,1,1,1},{0,1,2,3}}, | ||
91 | {{0,1,2,3},{2,2,2,2}} | ||
92 | }, | ||
93 | { | ||
94 | {{1,1,1,2},{2,1,0,0}}, | ||
95 | {{0,1,2,2},{1,1,1,2}}, | ||
96 | {{0,1,1,1},{2,2,1,0}}, | ||
97 | {{0,0,1,2},{0,1,1,1}} | ||
98 | }, | ||
99 | { | ||
100 | {{0,1,1,1},{0,0,1,2}}, | ||
101 | {{0,1,2,2},{1,1,1,0}}, | ||
102 | {{1,1,1,2},{0,1,2,2}}, | ||
103 | {{0,0,1,2},{2,1,1,1}} | ||
104 | }, | ||
105 | { | ||
106 | {{1,0,1,2},{0,1,1,1}}, | ||
107 | {{2,1,1,1},{1,0,1,2}}, | ||
108 | {{1,0,1,2},{2,1,1,1}}, | ||
109 | {{0,1,1,1},{1,0,1,2}} | ||
110 | } | ||
111 | }; | ||
112 | |||
113 | static int t_rand(int range) | ||
114 | { | ||
115 | return current_tick % range; | ||
116 | } | ||
117 | |||
118 | static void draw_frame(int fstart_x,int fstop_x,int fstart_y,int fstop_y) | ||
119 | { | ||
120 | lcd_drawline(fstart_x, fstart_y, fstop_x, fstart_y); | ||
121 | lcd_drawline(fstart_x, fstop_y, fstop_x, fstop_y); | ||
122 | |||
123 | lcd_drawline(fstart_x, fstart_y, fstart_x, fstop_y); | ||
124 | lcd_drawline(fstop_x, fstart_y, fstop_x, fstop_y); | ||
125 | |||
126 | lcd_drawline(fstart_x - 1, fstart_y + 1, fstart_x - 1, fstop_y + 1); | ||
127 | lcd_drawline(fstart_x - 1, fstop_y + 1, fstop_x - 1, fstop_y + 1); | ||
128 | } | ||
129 | |||
130 | static void draw_block(int x, int y, int block, int frame, bool clear) | ||
131 | { | ||
132 | int i, a, b; | ||
133 | for(i=0;i < 4;i++) { | ||
134 | if (clear) | ||
135 | { | ||
136 | for (a = 0; a < 3; a++) | ||
137 | for (b = 0; b < 4; b++) | ||
138 | lcd_clearpixel(start_x + x + block_data[block][frame][1][i] * 4 - b, | ||
139 | start_y + y + block_data[block][frame][0][i] * 3 + a); | ||
140 | } | ||
141 | else | ||
142 | { | ||
143 | for (a = 0; a < 3; a++) | ||
144 | for (b = 0; b < 4; b++) | ||
145 | lcd_drawpixel(start_x+x+block_data[block][frame][1][i] * 4 - b, | ||
146 | start_y+y+block_data[block][frame][0][i] * 3 + a); | ||
147 | } | ||
148 | } | ||
149 | } | ||
150 | |||
151 | static void to_virtual(void) | ||
152 | { | ||
153 | int i, a, b; | ||
154 | |||
155 | for(i = 0; i < 4; i++) | ||
156 | for (a = 0; a < 3; a++) | ||
157 | for (b = 0; b < 4; b++) | ||
158 | *(virtual + | ||
159 | (current_y + block_data[current_b][current_f][0][i] * 3 + a) * | ||
160 | max_x + current_x + block_data[current_b][current_f][1][i] * | ||
161 | 4 - b) = current_b + 1; | ||
162 | } | ||
163 | |||
164 | static bool block_touch (int x, int y) | ||
165 | { | ||
166 | int a,b; | ||
167 | for (a = 0; a < 4; a++) | ||
168 | for (b = 0; b < 3; b++) | ||
169 | if (*(virtual + (y + b) * max_x + (x - a)) != 0) | ||
170 | return true; | ||
171 | return false; | ||
172 | } | ||
173 | |||
174 | static bool gameover(void) | ||
175 | { | ||
176 | int i; | ||
177 | int frame, block, y, x; | ||
178 | |||
179 | x = current_x; | ||
180 | y = current_y; | ||
181 | block = current_b; | ||
182 | frame = current_f; | ||
183 | |||
184 | for(i = 0; i < 4; i++){ | ||
185 | /* Do we have blocks touching? */ | ||
186 | if(block_touch(x + block_data[block][frame][1][i] * 4, | ||
187 | y + block_data[block][frame][0][i] * 3)) | ||
188 | { | ||
189 | /* Are we at the top of the frame? */ | ||
190 | if(x + block_data[block][frame][1][i] * 4 >= max_x - 16) | ||
191 | { | ||
192 | /* Game over ;) */ | ||
193 | return true; | ||
194 | } | ||
195 | } | ||
196 | } | ||
197 | return false; | ||
198 | } | ||
199 | |||
200 | static bool valid_position(int x, int y, int block, int frame) | ||
201 | { | ||
202 | int i; | ||
203 | for(i=0;i < 4;i++) | ||
204 | if ((y + block_data[block][frame][0][i] * 3 > max_y - 3) || | ||
205 | (x + block_data[block][frame][1][i] * 4 > max_x - 4) || | ||
206 | (y + block_data[block][frame][0][i] * 3 < 0) || | ||
207 | (x + block_data[block][frame][1][i] * 4 < 4) || | ||
208 | block_touch (x + block_data[block][frame][1][i] * 4, | ||
209 | y + block_data[block][frame][0][i] * 3)) | ||
210 | { | ||
211 | return false; | ||
212 | } | ||
213 | return true; | ||
214 | } | ||
215 | |||
216 | static void from_virtual(void) | ||
217 | { | ||
218 | int x,y; | ||
219 | for(y = 0; y < max_y; y++) | ||
220 | for(x = 1; x < max_x - 1; x++) | ||
221 | if(*(virtual + (y * max_x) + x) != 0) | ||
222 | lcd_drawpixel(start_x + x, start_y + y); | ||
223 | else | ||
224 | lcd_clearpixel(start_x + x, start_y + y); | ||
225 | } | ||
226 | |||
227 | static void move_block(int x,int y,int f) | ||
228 | { | ||
229 | int last_frame = current_f; | ||
230 | if(f != 0) | ||
231 | { | ||
232 | current_f += f; | ||
233 | if(current_f > block_frames[current_b]-1) | ||
234 | current_f = 0; | ||
235 | if(current_f < 0) | ||
236 | current_f = block_frames[current_b]-1; | ||
237 | } | ||
238 | |||
239 | if(valid_position(current_x + x, current_y + y, current_b, current_f)) | ||
240 | { | ||
241 | draw_block(current_x,current_y,current_b,last_frame,true); | ||
242 | current_x += x; | ||
243 | current_y += y; | ||
244 | draw_block(current_x,current_y,current_b,current_f,false); | ||
245 | lcd_update(); | ||
246 | } | ||
247 | else | ||
248 | current_f = last_frame; | ||
249 | } | ||
250 | |||
251 | static void new_block(void) | ||
252 | { | ||
253 | current_b = next_b; | ||
254 | current_f = next_f; | ||
255 | current_x = max_x - 16; | ||
256 | current_y = (int)12; | ||
257 | next_b = t_rand(blocks); | ||
258 | next_f = t_rand(block_frames[next_b]); | ||
259 | |||
260 | lcd_drawline (max_x + 7, start_y - 1, max_x + 29, start_y - 1); | ||
261 | lcd_drawline (max_x + 29, start_y, max_x + 29, start_y + 14); | ||
262 | lcd_drawline (max_x + 29, start_y + 14, max_x + 7, start_y + 14); | ||
263 | lcd_drawline (max_x + 7, start_y + 14, max_x + 7, start_y - 1); | ||
264 | lcd_drawline (max_x + 6, start_y + 15, max_x + 6, start_y); | ||
265 | lcd_drawline (max_x + 6, start_y + 15, max_x + 28, start_y + 15); | ||
266 | |||
267 | draw_block(max_x + 9, start_y - 4, current_b, current_f, true); | ||
268 | draw_block(max_x + 9, start_y - 4, next_b, next_f, false); | ||
269 | if(!valid_position(current_x, current_y, current_b, current_f)) | ||
270 | { | ||
271 | draw_block(current_x, current_y, current_b, current_f, false); | ||
272 | lcd_update(); | ||
273 | } | ||
274 | else | ||
275 | draw_block(current_x, current_y, current_b, current_f, false); | ||
276 | } | ||
277 | |||
278 | static int check_lines(void) | ||
279 | { | ||
280 | int x,y,i,j; | ||
281 | bool line; | ||
282 | int lines = 0; | ||
283 | for(x = 0; x < max_x; x++) | ||
284 | { | ||
285 | line = true; | ||
286 | for(y = 0; y < max_y; y++) | ||
287 | { | ||
288 | if(*(virtual + y * max_x + x) == 0) | ||
289 | { | ||
290 | line = false; | ||
291 | break; | ||
292 | } | ||
293 | } | ||
294 | |||
295 | if(line) | ||
296 | { | ||
297 | lines++; | ||
298 | /* move rows down */ | ||
299 | for(i = x; i < max_x - 1; i++) | ||
300 | for (j = 0; j < max_y; j++) | ||
301 | *(virtual + j * max_x + i)=*(virtual + j * max_x + (i + 1)); | ||
302 | |||
303 | x--; /* re-check this line */ | ||
304 | } | ||
305 | } | ||
306 | |||
307 | return lines / 4; | ||
308 | } | ||
309 | |||
310 | static void move_down(void) | ||
311 | { | ||
312 | int l; | ||
313 | char s[25]; | ||
314 | |||
315 | if(!valid_position(current_x - 4, current_y, current_b, current_f)) | ||
316 | { | ||
317 | to_virtual(); | ||
318 | l = check_lines(); | ||
319 | if(l) | ||
320 | { | ||
321 | lines += l; | ||
322 | level = (int)lines/10; | ||
323 | if(level > 9) | ||
324 | level = 9; | ||
325 | from_virtual(); | ||
326 | score += l*l; | ||
327 | } | ||
328 | |||
329 | snprintf (s, sizeof(s), "%d %s %d", lines, | ||
330 | str(LANG_TETRIS_LEVEL), level); | ||
331 | lcd_putsxy (2, 42, s); | ||
332 | |||
333 | new_block(); | ||
334 | move_block(0,0,0); | ||
335 | } | ||
336 | else | ||
337 | move_block(-4,0,0); | ||
338 | } | ||
339 | |||
340 | static bool game_loop(void) | ||
341 | { | ||
342 | while(1) | ||
343 | { | ||
344 | int count = 0; | ||
345 | while(count * 300 < level_speeds[level]) | ||
346 | { | ||
347 | switch(button_get_w_tmo(HZ/10)) | ||
348 | { | ||
349 | case BUTTON_OFF: | ||
350 | return false; | ||
351 | |||
352 | case BUTTON_UP: | ||
353 | case BUTTON_UP | BUTTON_REPEAT: | ||
354 | move_block(0,-3,0); | ||
355 | break; | ||
356 | |||
357 | case BUTTON_DOWN: | ||
358 | case BUTTON_DOWN | BUTTON_REPEAT: | ||
359 | move_block(0,3,0); | ||
360 | break; | ||
361 | |||
362 | case BUTTON_RIGHT: | ||
363 | case BUTTON_RIGHT | BUTTON_REPEAT: | ||
364 | move_block(0,0,1); | ||
365 | break; | ||
366 | |||
367 | case BUTTON_LEFT: | ||
368 | case BUTTON_LEFT | BUTTON_REPEAT: | ||
369 | move_down(); | ||
370 | break; | ||
371 | |||
372 | case SYS_USB_CONNECTED: | ||
373 | usb_screen(); | ||
374 | return true; | ||
375 | } | ||
376 | |||
377 | count++; | ||
378 | } | ||
379 | |||
380 | if(gameover()) | ||
381 | { | ||
382 | lcd_clearrect(0, 52, LCD_WIDTH, LCD_HEIGHT - 52); | ||
383 | lcd_putsxy (2, 52, str(LANG_TETRIS_LOSE)); | ||
384 | lcd_update(); | ||
385 | sleep(HZ * 3); | ||
386 | return false; | ||
387 | } | ||
388 | |||
389 | move_down(); | ||
390 | } | ||
391 | |||
392 | return false; | ||
393 | } | ||
394 | |||
395 | static void init_tetris(void) | ||
396 | { | ||
397 | memset(&virtual, 0, sizeof(virtual)); | ||
398 | |||
399 | current_x = 0; | ||
400 | current_y = 0; | ||
401 | current_f = 0; | ||
402 | current_b = 0; | ||
403 | level = 0; | ||
404 | lines = 0; | ||
405 | score = 0; | ||
406 | next_b = 0; | ||
407 | next_f = 0; | ||
408 | } | ||
409 | |||
410 | bool tetris(void) | ||
411 | { | ||
412 | char buf[20]; | ||
413 | bool val; | ||
414 | |||
415 | /* Lets use the default font */ | ||
416 | lcd_setfont(FONT_SYSFIXED); | ||
417 | |||
418 | init_tetris(); | ||
419 | |||
420 | draw_frame(start_x, start_x + max_x - 1, start_y - 1, start_y + max_y); | ||
421 | snprintf(buf, sizeof(buf), "0 %s 0", str(LANG_TETRIS_LEVEL)); | ||
422 | lcd_putsxy (2, 42, buf); | ||
423 | lcd_update(); | ||
424 | |||
425 | next_b = t_rand(blocks); | ||
426 | next_f = t_rand(block_frames[next_b]); | ||
427 | new_block(); | ||
428 | val = game_loop(); | ||
429 | |||
430 | lcd_setfont(FONT_UI); | ||
431 | |||
432 | return val; | ||
433 | } | ||
434 | |||
435 | #endif | ||
436 | |||
437 | |||
438 | |||
diff --git a/apps/recorder/wormlet.h b/apps/recorder/wormlet.h deleted file mode 100644 index 0aeea3cc77..0000000000 --- a/apps/recorder/wormlet.h +++ /dev/null | |||
@@ -1,28 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 Philipp Pertermann | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #ifndef __WORMLET__ | ||
21 | #define __WORMLET__ | ||
22 | |||
23 | #include "menu.h" | ||
24 | |||
25 | bool wormlet(void); | ||
26 | |||
27 | #endif /*__WORMLET__ */ | ||
28 | |||
diff --git a/apps/screens.c b/apps/screens.c index d12a93a4d4..6055be3a2d 100644 --- a/apps/screens.c +++ b/apps/screens.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include "status.h" | 31 | #include "status.h" |
32 | #include "playlist.h" | 32 | #include "playlist.h" |
33 | #include "sprintf.h" | 33 | #include "sprintf.h" |
34 | #include "kernel.h" | ||
34 | 35 | ||
35 | #ifdef HAVE_LCD_BITMAP | 36 | #ifdef HAVE_LCD_BITMAP |
36 | #define BMPHEIGHT_usb_logo 32 | 37 | #define BMPHEIGHT_usb_logo 32 |
diff --git a/apps/tree.c b/apps/tree.c index 9935d8263d..e61fdc50cb 100644 --- a/apps/tree.c +++ b/apps/tree.c | |||
@@ -46,12 +46,12 @@ | |||
46 | #include "rolo.h" | 46 | #include "rolo.h" |
47 | #include "icons.h" | 47 | #include "icons.h" |
48 | #include "lang.h" | 48 | #include "lang.h" |
49 | #include "viewer.h" | ||
50 | #include "language.h" | 49 | #include "language.h" |
51 | #include "screens.h" | 50 | #include "screens.h" |
52 | #include "keyboard.h" | 51 | #include "keyboard.h" |
53 | #include "onplay.h" | 52 | #include "onplay.h" |
54 | #include "buffer.h" | 53 | #include "buffer.h" |
54 | #include "plugin.h" | ||
55 | 55 | ||
56 | #ifdef HAVE_LCD_BITMAP | 56 | #ifdef HAVE_LCD_BITMAP |
57 | #include "widgets.h" | 57 | #include "widgets.h" |
@@ -318,6 +318,8 @@ static int showdir(char *path, int start) | |||
318 | else if (!strcasecmp(&entry->d_name[len-4], ".mod")) | 318 | else if (!strcasecmp(&entry->d_name[len-4], ".mod")) |
319 | #endif | 319 | #endif |
320 | dptr->attr |= TREE_ATTR_MOD; | 320 | dptr->attr |= TREE_ATTR_MOD; |
321 | else if (!strcasecmp(&entry->d_name[len-5], ".rock")) | ||
322 | dptr->attr |= TREE_ATTR_ROCK; | ||
321 | } | 323 | } |
322 | 324 | ||
323 | /* filter out all non-playlist files */ | 325 | /* filter out all non-playlist files */ |
@@ -468,6 +470,10 @@ static int showdir(char *path, int start) | |||
468 | icon_type = Mod_Ajz; | 470 | icon_type = Mod_Ajz; |
469 | break; | 471 | break; |
470 | 472 | ||
473 | case TREE_ATTR_ROCK: | ||
474 | icon_type = Plugin; | ||
475 | break; | ||
476 | |||
471 | #ifdef HAVE_LCD_BITMAP | 477 | #ifdef HAVE_LCD_BITMAP |
472 | case TREE_ATTR_FONT: | 478 | case TREE_ATTR_FONT: |
473 | icon_type = Font; | 479 | icon_type = Font; |
@@ -962,7 +968,7 @@ bool dirbrowse(char *root) | |||
962 | break; | 968 | break; |
963 | 969 | ||
964 | case TREE_ATTR_TXT: | 970 | case TREE_ATTR_TXT: |
965 | viewer_run(buf); | 971 | plugin_load("/.rockbox/rocks/viewer.rock",buf); |
966 | restore = true; | 972 | restore = true; |
967 | break; | 973 | break; |
968 | 974 | ||
@@ -998,6 +1004,14 @@ bool dirbrowse(char *root) | |||
998 | rolo_load(buf); | 1004 | rolo_load(buf); |
999 | break; | 1005 | break; |
1000 | #endif | 1006 | #endif |
1007 | |||
1008 | /* plugin file */ | ||
1009 | case TREE_ATTR_ROCK: | ||
1010 | if (plugin_load(buf,NULL) == PLUGIN_USB_CONNECTED) | ||
1011 | reload_root = true; | ||
1012 | else | ||
1013 | restore = true; | ||
1014 | break; | ||
1001 | } | 1015 | } |
1002 | 1016 | ||
1003 | if ( play ) { | 1017 | if ( play ) { |
@@ -1194,6 +1208,7 @@ bool dirbrowse(char *root) | |||
1194 | /* the sub-screen might've ruined the margins */ | 1208 | /* the sub-screen might've ruined the margins */ |
1195 | lcd_setmargins(MARGIN_X,MARGIN_Y); /* leave room for cursor and | 1209 | lcd_setmargins(MARGIN_X,MARGIN_Y); /* leave room for cursor and |
1196 | icon */ | 1210 | icon */ |
1211 | lcd_setfont(FONT_UI); | ||
1197 | #endif | 1212 | #endif |
1198 | numentries = showdir(currdir, dirstart); | 1213 | numentries = showdir(currdir, dirstart); |
1199 | update_all = true; | 1214 | update_all = true; |
diff --git a/apps/tree.h b/apps/tree.h index eb0aa8b98a..aa8f2127f3 100644 --- a/apps/tree.h +++ b/apps/tree.h | |||
@@ -30,6 +30,7 @@ | |||
30 | #define TREE_ATTR_TXT 0x500 /* text file */ | 30 | #define TREE_ATTR_TXT 0x500 /* text file */ |
31 | #define TREE_ATTR_FONT 0x800 /* font file */ | 31 | #define TREE_ATTR_FONT 0x800 /* font file */ |
32 | #define TREE_ATTR_LNG 0x1000 /* binary lang file */ | 32 | #define TREE_ATTR_LNG 0x1000 /* binary lang file */ |
33 | #define TREE_ATTR_ROCK 0x2000 /* binary rockbox plugin */ | ||
33 | #define TREE_ATTR_MASK 0xffd0 /* which bits tree.c uses (above + DIR) */ | 34 | #define TREE_ATTR_MASK 0xffd0 /* which bits tree.c uses (above + DIR) */ |
34 | 35 | ||
35 | void tree_init(void); | 36 | void tree_init(void); |
diff --git a/apps/viewer.h b/apps/viewer.h deleted file mode 100644 index ed9f64ca49..0000000000 --- a/apps/viewer.h +++ /dev/null | |||
@@ -1,24 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 Jerome Kuptz | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #ifndef _VIEWER_H | ||
20 | #define _VIEWER_H | ||
21 | |||
22 | bool viewer_run(char* file); | ||
23 | |||
24 | #endif | ||
diff --git a/firmware/app.lds b/firmware/app.lds index 46a6ca70fb..34ab1adf66 100644 --- a/firmware/app.lds +++ b/firmware/app.lds | |||
@@ -2,15 +2,17 @@ ENTRY(start) | |||
2 | OUTPUT_FORMAT(elf32-sh) | 2 | OUTPUT_FORMAT(elf32-sh) |
3 | INPUT(crt0.o) | 3 | INPUT(crt0.o) |
4 | 4 | ||
5 | #define PLUGINSIZE 0x8000 | ||
6 | |||
5 | #ifdef DEBUG | 7 | #ifdef DEBUG |
6 | #define DRAMSIZE 0x1f0000 | 8 | #define DRAMSIZE 0x1f0000 - PLUGINSIZE |
7 | #define ORIGADDR 0x09010000 | 9 | #define ORIGADDR 0x09010000 |
8 | #define ENDADDR 0x09200000 | 10 | |
9 | #else | 11 | #else |
10 | #define DRAMSIZE (MEMORYSIZE * 0x100000) | 12 | #define DRAMSIZE (MEMORYSIZE * 0x100000) - PLUGINSIZE |
11 | #define ORIGADDR 0x09000000 | 13 | #define ORIGADDR 0x09000000 |
12 | #define ENDADDR (ORIGADDR + DRAMSIZE) | ||
13 | #endif | 14 | #endif |
15 | #define ENDADDR (ORIGADDR + DRAMSIZE) | ||
14 | 16 | ||
15 | MEMORY | 17 | MEMORY |
16 | { | 18 | { |
@@ -91,6 +93,11 @@ SECTIONS | |||
91 | _topramend = .; | 93 | _topramend = .; |
92 | } > DRAM | 94 | } > DRAM |
93 | 95 | ||
96 | .plugin ENDADDR: | ||
97 | { | ||
98 | _pluginbuf = .; | ||
99 | } | ||
100 | |||
94 | .iram 0xf000000 : AT ( _iramcopy ) | 101 | .iram 0xf000000 : AT ( _iramcopy ) |
95 | { | 102 | { |
96 | _iramstart = .; | 103 | _iramstart = .; |
diff --git a/firmware/drivers/lcd-player-charset.c b/firmware/drivers/lcd-player-charset.c index 523158f49f..df4f3f016d 100644 --- a/firmware/drivers/lcd-player-charset.c +++ b/firmware/drivers/lcd-player-charset.c | |||
@@ -47,7 +47,7 @@ unsigned short new_lcd_rocklatin1_to_xlcd[] = | |||
47 | RESERVED_CHAR, /* 0x01-0x17 reserved */ | 47 | RESERVED_CHAR, /* 0x01-0x17 reserved */ |
48 | RESERVED_CHAR, /* 0x01-0x17 reserved */ | 48 | RESERVED_CHAR, /* 0x01-0x17 reserved */ |
49 | RESERVED_CHAR, /* 0x01-0x17 reserved */ | 49 | RESERVED_CHAR, /* 0x01-0x17 reserved */ |
50 | RESERVED_CHAR, /* 0x01-0x17 reserved */ | 50 | 0x217, /* 0x17 .. "plugin" icon */ |
51 | 0x218, /* 0x18 .. "folder" icon */ | 51 | 0x218, /* 0x18 .. "folder" icon */ |
52 | 0x219, /* 0x19 .. "MOD/AJZ" icon (winlatin o (dote in the middle) */ | 52 | 0x219, /* 0x19 .. "MOD/AJZ" icon (winlatin o (dote in the middle) */ |
53 | 0x21a, /* 0x1a .. "language" icon (winlatin - (a bit longer minus sign) */ | 53 | 0x21a, /* 0x1a .. "language" icon (winlatin - (a bit longer minus sign) */ |
@@ -668,7 +668,7 @@ unsigned char extended_font_player[NO_EXTENDED_LCD_CHARS][8] = { | |||
668 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 14 */ | 668 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 14 */ |
669 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 15 */ | 669 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 15 */ |
670 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 16 */ | 670 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 16 */ |
671 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 17 */ | 671 | { 0x04, 0x1e, 0x07, 0x1f, 0x05, 0x01, 0x06, 0x00}, /* 17 Plugin file icon */ |
672 | { 0x0c, 0x13, 0x11, 0x11, 0x11, 0x11, 0x1f, 0x00}, /* 18 Folder icon */ | 672 | { 0x0c, 0x13, 0x11, 0x11, 0x11, 0x11, 0x1f, 0x00}, /* 18 Folder icon */ |
673 | { 0x1f, 0x11, 0x1b, 0x15, 0x1b, 0x11, 0x1f, 0x00}, /* 19 MOD/AJZ icon */ | 673 | { 0x1f, 0x11, 0x1b, 0x15, 0x1b, 0x11, 0x1f, 0x00}, /* 19 MOD/AJZ icon */ |
674 | { 0x00, 0x1f, 0x15, 0x1f, 0x15, 0x1f, 0x00, 0x00}, /* 1a Language icon */ | 674 | { 0x00, 0x1f, 0x15, 0x1f, 0x15, 0x1f, 0x00, 0x00}, /* 1a Language icon */ |