1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
diff --git a/apps/plugins/blackjack.c b/apps/plugins/blackjack.c
index 3a43a12..67a6614 100644
--- a/apps/plugins/blackjack.c
+++ b/apps/plugins/blackjack.c
@@ -29,8 +29,8 @@


 /* save files */
-#define SCORE_FILE PLUGIN_GAMES_DIR "/blackjack.score"
-#define SAVE_FILE  PLUGIN_GAMES_DIR "/blackjack.save"
+#define SCORE_FILE PLUGIN_GAMES_DATA_DIR "/blackjack.score"
+#define SAVE_FILE  PLUGIN_GAMES_DATA_DIR "/blackjack.save"
 #define NUM_SCORES 5

 /* final game return status */
diff --git a/apps/plugins/brickmania.c b/apps/plugins/brickmania.c
index 6295862..379aadf 100644
--- a/apps/plugins/brickmania.c
+++ b/apps/plugins/brickmania.c
@@ -450,8 +450,8 @@ CONFIG_KEYPAD == SANSA_M200_PAD
  */

 #define CONFIG_FILE_NAME "brickmania.cfg"
-#define SAVE_FILE  PLUGIN_GAMES_DIR "/brickmania.save"
-#define SCORE_FILE PLUGIN_GAMES_DIR "/brickmania.score"
+#define SAVE_FILE  PLUGIN_GAMES_DATA_DIR "/brickmania.save"
+#define SCORE_FILE PLUGIN_GAMES_DATA_DIR "/brickmania.score"
 #define NUM_SCORES 5


diff --git a/apps/plugins/bubbles.c b/apps/plugins/bubbles.c
index c7af502..1a2f96d 100644
--- a/apps/plugins/bubbles.c
+++ b/apps/plugins/bubbles.c
@@ -30,9 +30,9 @@
 #include "lib/highscore.h"

 /* files */
-#define SCORE_FILE PLUGIN_GAMES_DIR "/bubbles.score"
-#define SAVE_FILE  PLUGIN_GAMES_DIR "/bubbles.save"
-#define DATA_FILE  PLUGIN_GAMES_DIR "/bubbles.data"
+#define SCORE_FILE PLUGIN_GAMES_DATA_DIR "/bubbles.score"
+#define SAVE_FILE  PLUGIN_GAMES_DATA_DIR "/bubbles.save"
+#define DATA_FILE  PLUGIN_GAMES_DATA_DIR "/bubbles.data"

 /* final game return status */
 enum {
diff --git a/apps/plugins/calendar.c b/apps/plugins/calendar.c
index 1ca4025..11badbd 100644
--- a/apps/plugins/calendar.c
+++ b/apps/plugins/calendar.c
@@ -319,8 +319,8 @@
 #endif
 #endif

-#define MEMO_FILE PLUGIN_APPS_DIR "/.memo"
-#define TEMP_FILE PLUGIN_APPS_DIR "/~temp"
+#define MEMO_FILE PLUGIN_APPS_DATA_DIR "/.memo"
+#define TEMP_FILE PLUGIN_APPS_DATA_DIR "/~temp"

 #define X_OFFSET ((LCD_WIDTH%7)/2)
 #if LCD_HEIGHT <= 80
diff --git a/apps/plugins/chessbox/chessbox.c b/apps/plugins/chessbox/chessbox.c
index 9638168..4876231 100644
--- a/apps/plugins/chessbox/chessbox.c
+++ b/apps/plugins/chessbox/chessbox.c
@@ -59,7 +59,7 @@ extern const fb_data chessbox_pieces[];
 #define YOFS ((LCD_HEIGHT-8*TILE_HEIGHT)/2)

 /* save files */
-#define SAVE_FILE  PLUGIN_GAMES_DIR "/chessbox.save"
+#define SAVE_FILE  PLUGIN_GAMES_DATA_DIR "/chessbox.save"

 /* commands enum */
 #define COMMAND_NOP        0
diff --git a/apps/plugins/chessbox/chessbox_pgn.c b/apps/plugins/chessbox/chessbox_pgn.c
index 43da92e..846ea41 100644
--- a/apps/plugins/chessbox/chessbox_pgn.c
+++ b/apps/plugins/chessbox/chessbox_pgn.c
@@ -22,8 +22,8 @@
 #include "plugin.h"
 #include "chessbox_pgn.h"

-#define PGN_FILE  PLUGIN_GAMES_DIR  "/chessbox.pgn"
-#define LOG_FILE  PLUGIN_GAMES_DIR  "/chessbox.log"
+#define PGN_FILE  PLUGIN_GAMES_DATA_DIR  "/chessbox.pgn"
+#define LOG_FILE  PLUGIN_GAMES_DATA_DIR  "/chessbox.log"
 int loghandler;

 short kn_offs[8][2] = {{2,1},{2,-1},{-2,1},{-2,-1},{1,2},{1,-2},{-1,2},{-1,-2}};
diff --git a/apps/plugins/clix.c b/apps/plugins/clix.c
index 0c928e0..193d590 100644
--- a/apps/plugins/clix.c
+++ b/apps/plugins/clix.c
@@ -192,7 +192,7 @@
 #define CLIX_BUTTON_CLICK   BUTTON_CENTER
 #endif

-#define SCORE_FILE PLUGIN_GAMES_DIR "/clix.score"
+#define SCORE_FILE PLUGIN_GAMES_DATA_DIR "/clix.score"
 #define NUM_SCORES 5
 struct highscore highscores[NUM_SCORES];

diff --git a/apps/plugins/disktidy.c b/apps/plugins/disktidy.c
index 995fd6d..d42a62d 100644
--- a/apps/plugins/disktidy.c
+++ b/apps/plugins/disktidy.c
@@ -44,8 +44,8 @@ struct tidy_type {
 int tidy_type_count;
 bool tidy_loaded_and_changed = false;

-#define DEFAULT_FILES PLUGIN_APPS_DIR "/disktidy.config"
-#define CUSTOM_FILES  PLUGIN_APPS_DIR "/disktidy_custom.config"
+#define DEFAULT_FILES PLUGIN_APPS_DATA_DIR "/disktidy.config"
+#define CUSTOM_FILES  PLUGIN_APPS_DATA_DIR "/disktidy_custom.config"

 void add_item(const char* name, int index)
 {
diff --git a/apps/plugins/invadrox.c b/apps/plugins/invadrox.c
index 6b64fa7..1bbca81 100644
--- a/apps/plugins/invadrox.c
+++ b/apps/plugins/invadrox.c
@@ -632,7 +632,7 @@ CONFIG_KEYPAD == MROBE500_PAD
 #define TARGET_BOTTOM 3
 #define TARGET_UFO 4

-#define HISCOREFILE PLUGIN_GAMES_DIR "/invadrox.high"
+#define HISCOREFILE PLUGIN_GAMES_DATA_DIR "/invadrox.high"


 /* The time (in ms) for one iteration through the game loop - decrease this
diff --git a/apps/plugins/jewels.c b/apps/plugins/jewels.c
index 02f8143..2f8d679 100644
--- a/apps/plugins/jewels.c
+++ b/apps/plugins/jewels.c
@@ -461,8 +461,8 @@ struct puzzle_level puzzle_levels[NUM_PUZZLE_LEVELS] = {
               {4, 7, PUZZLE_TILE_LEFT|PUZZLE_TILE_UP} } },
 };

-#define SAVE_FILE  PLUGIN_GAMES_DIR "/jewels.save"
-#define SCORE_FILE PLUGIN_GAMES_DIR "/jewels.score"
+#define SAVE_FILE  PLUGIN_GAMES_DATA_DIR "/jewels.save"
+#define SCORE_FILE PLUGIN_GAMES_DATA_DIR "/jewels.score"
 struct highscore highscores[NUM_SCORES];

 static bool resume_file = false;
diff --git a/apps/plugins/keybox.c b/apps/plugins/keybox.c
index af41b3f..932fc5f 100644
--- a/apps/plugins/keybox.c
+++ b/apps/plugins/keybox.c
@@ -23,7 +23,7 @@
 #include "lib/md5.h"


-#define KEYBOX_FILE PLUGIN_APPS_DIR "/keybox.dat"
+#define KEYBOX_FILE PLUGIN_APPS_DATA_DIR "/keybox.dat"
 #define BLOCK_SIZE 8
 #define MAX_ENTRIES 12*BLOCK_SIZE /* keep this a multiple of BLOCK_SIZE */
 #define FIELD_LEN 32 /* should be enough for anyone ;) */
diff --git a/apps/plugins/lib/configfile.c b/apps/plugins/lib/configfile.c
index 0fb01c6..ab1e21a 100644
--- a/apps/plugins/lib/configfile.c
+++ b/apps/plugins/lib/configfile.c
@@ -23,12 +23,15 @@

 static void get_cfg_filename(char* buf, int buf_len, const char* filename)
 {
+#ifdef APPLICATION
+    rb->snprintf(buf, buf_len, PLUGIN_DATA_DIR "/%s", filename);
+#else
     char *s;
     rb->strcpy(buf, rb->plugin_get_current_filename());
     s = rb->strrchr(buf, '/');
     if (!s) /* should never happen */
     {
-        rb->snprintf(buf, buf_len, PLUGIN_DIR "/%s", filename);
+        rb->snprintf(buf, buf_len, PLUGIN_DATA_DIR "/%s", filename);
     }
     else
     {
@@ -36,6 +39,7 @@ static void get_cfg_filename(char* buf, int buf_len, const char* filename)
         *s = '\0';
         rb->strcat(s, filename);
     }
+#endif
 }

 int configfile_save(const char *filename, struct configdata *cfg,
diff --git a/apps/plugins/pictureflow/pictureflow.c b/apps/plugins/pictureflow/pictureflow.c
index caae9dc..97a3b82 100644
--- a/apps/plugins/pictureflow/pictureflow.c
+++ b/apps/plugins/pictureflow/pictureflow.c
@@ -228,7 +228,7 @@ typedef fb_data pix_t;
 #define MAX_SLIDES_COUNT 10

 #define THREAD_STACK_SIZE DEFAULT_STACK_SIZE + 0x200
-#define CACHE_PREFIX PLUGIN_DEMOS_DIR "/pictureflow"
+#define CACHE_PREFIX PLUGIN_DEMOS_DATA_DIR "/pictureflow"

 #define EV_EXIT 9999
 #define EV_WAKEUP 1337
diff --git a/apps/plugins/pitch_detector.c b/apps/plugins/pitch_detector.c
index 324a36b..5e68822 100644
--- a/apps/plugins/pitch_detector.c
+++ b/apps/plugins/pitch_detector.c
@@ -311,7 +311,7 @@ static struct tuner_settings
 /* Settings loading and saving(adapted from the clock plugin)      */
 /*=================================================================*/

-#define SETTINGS_FILENAME PLUGIN_APPS_DIR "/.pitch_detector_settings"
+#define SETTINGS_FILENAME PLUGIN_APPS_DATA_DIR "/.pitch_detector_settings"

 /* The settings as they exist on the hard disk, so that
  * we can know at saving time if changes have been made */
diff --git a/apps/plugins/rockblox.c b/apps/plugins/rockblox.c
index d86cb1c..b3767c1 100644
--- a/apps/plugins/rockblox.c
+++ b/apps/plugins/rockblox.c
@@ -800,8 +800,8 @@ bool resume = false;
 bool resume_file = false;

 /* Rockbox File System only supports full filenames inc dir */
-#define SCORE_FILE  PLUGIN_GAMES_DIR "/rockblox.score"
-#define RESUME_FILE PLUGIN_GAMES_DIR "/rockblox.resume"
+#define SCORE_FILE  PLUGIN_GAMES_DATA_DIR "/rockblox.score"
+#define RESUME_FILE PLUGIN_GAMES_DATA_DIR "/rockblox.resume"
 #define NUM_SCORES  5

 /* Default High Scores... */
diff --git a/apps/plugins/snake.c b/apps/plugins/snake.c
index 120485a..5e591ca 100644
--- a/apps/plugins/snake.c
+++ b/apps/plugins/snake.c
@@ -254,7 +254,7 @@ dir is the current direction of the snake - 0=up, 1=right, 2=down, 3=left;
 #define BOARD_HEIGHT (LCD_HEIGHT/4)

 #define CONFIG_FILE_NAME "snake.cfg"
-#define SCORE_FILE PLUGIN_GAMES_DIR "/snake.score"
+#define SCORE_FILE PLUGIN_GAMES_DATA_DIR "/snake.score"
 #define NUM_SCORES 5

 static int board[BOARD_WIDTH][BOARD_HEIGHT],snakelength;
diff --git a/apps/plugins/snake2.c b/apps/plugins/snake2.c
index 1b15267..3d8b973 100644
--- a/apps/plugins/snake2.c
+++ b/apps/plugins/snake2.c
@@ -413,7 +413,7 @@ static struct highscore highscores[NUM_SCORES];
 #define SOUTH_WEST  4096

 #define LEVELS_FILE PLUGIN_GAMES_DIR "/snake2.levels"
-#define SCORE_FILE  PLUGIN_GAMES_DIR "/snake2.score"
+#define SCORE_FILE  PLUGIN_GAMES_DATA_DIR "/snake2.score"

 int load_all_levels(void)
 {
diff --git a/apps/plugins/sokoban.c b/apps/plugins/sokoban.c
index 6fe2b26..4028833 100644
--- a/apps/plugins/sokoban.c
+++ b/apps/plugins/sokoban.c
@@ -29,8 +29,13 @@
 #define SOKOBAN_TITLE        "Sokoban"

 #define SOKOBAN_LEVELS_FILE  PLUGIN_GAMES_DIR "/sokoban.levels"
-#define SOKOBAN_SAVE_FILE    PLUGIN_GAMES_DIR "/sokoban.save"
+#define SOKOBAN_SAVE_FILE    PLUGIN_GAMES_DATA_DIR "/sokoban.save"
+
+#ifdef APPLICATION
+#define SOKOBAN_SAVE_FOLDER  PLUGIN_GAMES_DATA_DIR
+#else
 #define SOKOBAN_SAVE_FOLDER  "/games"
+#endif

 #include "pluginbitmaps/sokoban_tiles.h"
 #define SOKOBAN_TILESIZE BMPWIDTH_sokoban_tiles
diff --git a/apps/plugins/solitaire.c b/apps/plugins/solitaire.c
index 006e073..23ffa8b 100644
--- a/apps/plugins/solitaire.c
+++ b/apps/plugins/solitaire.c
@@ -1293,11 +1293,15 @@ int bouncing_cards( void )
  */
 void get_save_filename( char *buf )
 {
+#ifdef APPLICATION
+    rb->sprintf(buf, sizeof(buf), PLUGIN_DATA_DIR "/sol.sav");
+#else
     char *s;
     rb->strcpy( buf, rb->plugin_get_current_filename() );
     s = rb->strrchr( buf, '/' ) + 1;
     *s = '\0';
     rb->strcat( s, "sol.save" );
+#endif
 }

 int open_save_file( int flags )
diff --git a/apps/plugins/spacerocks.c b/apps/plugins/spacerocks.c
index 2e5600b..4011688 100644
--- a/apps/plugins/spacerocks.c
+++ b/apps/plugins/spacerocks.c
@@ -400,7 +400,7 @@
 #define SET_BG(x)
 #endif

-#define SCORE_FILE PLUGIN_GAMES_DIR "/spacerocks.score"
+#define SCORE_FILE PLUGIN_GAMES_DATA_DIR "/spacerocks.score"
 #define NUM_SCORES 5

 static struct highscore highscores[NUM_SCORES];
diff --git a/apps/plugins/stopwatch.c b/apps/plugins/stopwatch.c
index c07cfd9..f70d26b 100644
--- a/apps/plugins/stopwatch.c
+++ b/apps/plugins/stopwatch.c
@@ -32,7 +32,7 @@
 #define LAP_Y TIMER_Y+1
 #define MAX_LAPS 64

-#define STOPWATCH_FILE PLUGIN_APPS_DIR "/stopwatch.dat"
+#define STOPWATCH_FILE PLUGIN_APPS_DATA_DIR "/stopwatch.dat"

 /* variable button definitions */
 #if CONFIG_KEYPAD == RECORDER_PAD
diff --git a/apps/plugins/text_viewer/tv_settings.c b/apps/plugins/text_viewer/tv_settings.c
index 20e8212..3ed1576 100644
--- a/apps/plugins/text_viewer/tv_settings.c
+++ b/apps/plugins/text_viewer/tv_settings.c
@@ -54,8 +54,8 @@
  * font name              MAX_PATH
  */

-#define VIEWER_GLOBAL_SETTINGS_FILE      VIEWERS_DIR "/viewer.dat"
-#define TV_GLOBAL_SETTINGS_FILE          VIEWERS_DIR "/tv_global.dat"
+#define VIEWER_GLOBAL_SETTINGS_FILE      VIEWERS_DATA_DIR "/viewer.dat"
+#define TV_GLOBAL_SETTINGS_FILE          VIEWERS_DATA_DIR "/tv_global.dat"

 #define TV_GLOBAL_SETTINGS_HEADER        "\x54\x56\x47\x53" /* "TVGS" */
 #define TV_GLOBAL_SETTINGS_VERSION       0x38
@@ -108,11 +108,11 @@
  * ...
  * [last file]
  */
-#define VIEWER_SETTINGS_FILE      VIEWERS_DIR "/viewer_file.dat"
-#define TV_SETTINGS_FILE          VIEWERS_DIR "/tv_file.dat"
+#define VIEWER_SETTINGS_FILE      VIEWERS_DATA_DIR "/viewer_file.dat"
+#define TV_SETTINGS_FILE          VIEWERS_DATA_DIR "/tv_file.dat"

 /* temporary file */
-#define TV_SETTINGS_TMP_FILE      VIEWERS_DIR "/tv_file.tmp"
+#define TV_SETTINGS_TMP_FILE      VIEWERS_DATA_DIR "/tv_file.tmp"

 #define TV_SETTINGS_HEADER        "\x54\x56\x53" /* "TVS" */
 #define TV_SETTINGS_VERSION       0x39
diff --git a/apps/plugins/vu_meter.c b/apps/plugins/vu_meter.c
index 077a6e9..8877d7f 100644
--- a/apps/plugins/vu_meter.c
+++ b/apps/plugins/vu_meter.c
@@ -467,7 +467,7 @@ void calc_scales(void)
 }

 void load_settings(void) {
-    int fp = rb->open(PLUGIN_DEMOS_DIR "/.vu_meter", O_RDONLY);
+    int fp = rb->open(PLUGIN_DEMOS_DATA_DIR "/.vu_meter", O_RDONLY);
     if(fp>=0) {
             rb->read(fp, &vumeter_settings, sizeof(struct saved_settings));
             rb->close(fp);
@@ -479,7 +479,7 @@ void load_settings(void) {
 }

 void save_settings(void) {
-    int fp = rb->creat(PLUGIN_DEMOS_DIR "/.vu_meter", 0666);
+    int fp = rb->creat(PLUGIN_DEMOS_DATA_DIR "/.vu_meter", 0666);
     if(fp >= 0) {
         rb->write (fp, &vumeter_settings, sizeof(struct saved_settings));
         rb->close(fp);
diff --git a/firmware/common/rbpaths.c b/firmware/common/rbpaths.c
index cb56ab4..1bbed97 100644
--- a/firmware/common/rbpaths.c
+++ b/firmware/common/rbpaths.c
@@ -70,6 +70,7 @@ void paths_init(void)
     /* make sure $HOME/.config/rockbox.org exists, it's needed for config.cfg */
 #if (CONFIG_PLATFORM & PLATFORM_ANDROID)
     mkdir("/sdcard/rockbox");
+    mkdir("/sdcard/rockbox/rocks.data");
 #else
     char config_dir[MAX_PATH];

@@ -84,6 +85,9 @@ void paths_init(void)
     mkdir(config_dir);
     snprintf(config_dir, sizeof(config_dir), "%s/.config/rockbox.org", home);
     mkdir(config_dir);
+    /* Plugin data directory */
+    snprintf(config_dir, sizeof(config_dir), "%s/.config/rockbox.org/rocks.data", home);
+    mkdir(config_dir);
 #endif
 }

diff --git a/firmware/export/rbpaths.h b/firmware/export/rbpaths.h
index a15c5ae..ade7894 100644
--- a/firmware/export/rbpaths.h
+++ b/firmware/export/rbpaths.h
@@ -76,6 +76,19 @@ extern void paths_init(void);
 #define PLUGIN_DEMOS_DIR    PLUGIN_DIR "/demos"
 #define VIEWERS_DIR         PLUGIN_DIR "/viewers"

+#ifdef APPLICATION
+#define PLUGIN_DATA_DIR          "/.rockbox/rocks.data"
+#define PLUGIN_GAMES_DATA_DIR    PLUGIN_DATA_DIR
+#define PLUGIN_APPS_DATA_DIR     PLUGIN_DATA_DIR
+#define PLUGIN_DEMOS_DATA_DIR    PLUGIN_DATA_DIR
+#define VIEWERS_DATA_DIR         PLUGIN_DATA_DIR
+#else
+#define PLUGIN_DATA_DIR          PLUGIN_DIR
+#define PLUGIN_GAMES_DATA_DIR    PLUGIN_DIR "/games"
+#define PLUGIN_APPS_DATA_DIR     PLUGIN_DIR "/apps"
+#define PLUGIN_DEMOS_DATA_DIR    PLUGIN_DIR "/demos"
+#define VIEWERS_DATA_DIR         PLUGIN_DIR "/viewers"
+#endif

 #define WPS_DIR             ROCKBOX_DIR "/wps"
 #define SBS_DIR             WPS_DIR