Subversion Repositories freemyipod

Rev

Rev 667 | Rev 764 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
660 theseven 1
//
2
//
3
//    Copyright 2011 TheSeven
4
//
5
//
6
//    This file is part of emCORE.
7
//
8
//    emCORE is free software: you can redistribute it and/or
9
//    modify it under the terms of the GNU General Public License as
10
//    published by the Free Software Foundation, either version 2 of the
11
//    License, or (at your option) any later version.
12
//
13
//    emCORE is distributed in the hope that it will be useful,
14
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16
//    See the GNU General Public License for more details.
17
//
18
//    You should have received a copy of the GNU General Public License along
19
//    with emCORE.  If not, see <http://www.gnu.org/licenses/>.
20
//
21
//
22
 
23
 
528 theseven 24
#include "emcoreapp.h"
25
#include "libboot.h"
26
#include "libpng.h"
27
#include "libui.h"
660 theseven 28
#include "libmkfat32.h"
528 theseven 29
 
660 theseven 30
struct libpng_api* png;
31
struct libboot_api* boot;
32
struct libui_api* ui;
33
void* framebuf;
34
void* bg;
35
void* icons;
36
void* rbxlogo;
528 theseven 37
 
660 theseven 38
static struct emcorelib_header* loadlib(uint32_t identifier, uint32_t version, char* filename)
528 theseven 39
{
660 theseven 40
    struct emcorelib_header* lib = get_library(identifier, version, LIBSOURCE_BOOTFLASH, filename);
41
    if (!lib) panicf(PANIC_KILLTHREAD, "Could not load %s", filename);
42
    return lib;
43
}
44
 
45
static void* loadpng(const char* filename, void* (*decoder)(struct png_info* handle))
46
{
47
    int size = bootflash_filesize(filename);
48
    if (size == -1) panicf(PANIC_KILLTHREAD, "Could not load %s", filename);
49
    void* buf = memalign(0x10, size);
50
    if (!buf) panicf(PANIC_KILLTHREAD, "Could not allocate buffer for %s", filename);
51
    bootflash_read(filename, buf, 0, size);
52
    struct png_info* handle = png->png_open(buf, size);
53
    if (!handle) panicf(PANIC_KILLTHREAD, "Could not parse %s", filename);
54
    void* out = decoder(handle);
55
    if (!out) panicf(PANIC_KILLTHREAD, "Could not decode %s", filename);
56
    png->png_destroy(handle);
57
    free(buf);
58
    return out;
59
}
60
 
61
static void message(int x, const char* line1, const char* line2)
62
{
63
    rendertext(framebuf, x, 140, 320, 0xff3333ff, 0xa0000000, line1);
64
    rendertext(framebuf, x, 148, 320, 0xff3333ff, 0xa0000000, line2);
65
    displaylcd(0, 0, 320, 240, framebuf, 0, 0, 320);
66
    sleep(5000000);
67
}
68
 
69
struct chooser_renderer_list_itemdata toolchooser_rparams_mainchooser =
70
{
71
    .size = LIBUI_POINT(260, 10),
72
    .fill_box = LIBUI_BOX(LIBUI_POINT(0, 0), LIBUI_POINT(260, 10)),
73
    .fill_color = 0xa0000000,
74
    .fill_color_selected = 0x60ffffff,
75
    .icon_pos = LIBUI_POINT(0, 0),
76
    .icon = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
77
                          LIBUI_POINT(0, 0)),
78
    .icon_opacity = 0,
79
    .icon_selected = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
80
                                   LIBUI_POINT(0, 0)),
81
    .icon_selected_opacity = 0,
82
    .text = "Return to main menu",
83
    .text_pos = LIBUI_POINT(1, 1),
84
    .text_color = 0xffffffff,
85
    .text_color_selected = 0xff7fffff
86
};
87
 
88
struct chooser_renderer_list_itemdata toolchooser_rparams_umsboot =
89
{
90
    .size = LIBUI_POINT(260, 10),
91
    .fill_box = LIBUI_BOX(LIBUI_POINT(0, 0), LIBUI_POINT(260, 10)),
92
    .fill_color = 0xa0000000,
93
    .fill_color_selected = 0x60ffffff,
94
    .icon_pos = LIBUI_POINT(0, 0),
95
    .icon = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
96
                          LIBUI_POINT(0, 0)),
97
    .icon_opacity = 0,
98
    .icon_selected = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
99
                                   LIBUI_POINT(0, 0)),
100
    .icon_selected_opacity = 0,
101
    .text = "Run UMSboot",
102
    .text_pos = LIBUI_POINT(1, 1),
103
    .text_color = 0xffffffff,
104
    .text_color_selected = 0xff7fffff
105
};
106
 
107
void run_umsboot(void** firmware, void** app, int* size)
108
{
662 theseven 109
    boot->load_from_flash(firmware, size, false, "umsboot ", 0x10000);
660 theseven 110
    if (!*firmware)
111
    {
112
        memcpy(framebuf, bg, 320 * 240 * 3);
113
        message(91, "Loading UMSboot failed!", "Returning to main menu.");
114
    }
115
}
116
 
117
struct chooser_renderer_list_itemdata toolchooser_rparams_rockbox_fallback =
118
{
119
    .size = LIBUI_POINT(260, 10),
120
    .fill_box = LIBUI_BOX(LIBUI_POINT(0, 0), LIBUI_POINT(260, 10)),
121
    .fill_color = 0xa0000000,
122
    .fill_color_selected = 0x60ffffff,
123
    .icon_pos = LIBUI_POINT(0, 0),
124
    .icon = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
125
                          LIBUI_POINT(0, 0)),
126
    .icon_opacity = 0,
127
    .icon_selected = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
128
                                   LIBUI_POINT(0, 0)),
129
    .icon_selected_opacity = 0,
130
    .text = "Run Rockbox fallback image",
131
    .text_pos = LIBUI_POINT(1, 1),
132
    .text_color = 0xffffffff,
133
    .text_color_selected = 0xff7fffff
134
};
135
 
136
void run_rockbox_fallback(void** firmware, void** app, int* size)
137
{
138
    boot->load_from_flash(firmware, size, true, "rockbox ", 0x100000);
139
    if (!*firmware)
140
    {
141
        memcpy(framebuf, bg, 320 * 240 * 3);
142
        message(91, "Loading Rockbox failed!", "Returning to main menu.");
143
    }
144
}
145
 
146
struct chooser_renderer_list_itemdata toolchooser_rparams_clearcfg =
147
{
148
    .size = LIBUI_POINT(260, 10),
149
    .fill_box = LIBUI_BOX(LIBUI_POINT(0, 0), LIBUI_POINT(260, 10)),
150
    .fill_color = 0xa0000000,
151
    .fill_color_selected = 0x60ffffff,
152
    .icon_pos = LIBUI_POINT(0, 0),
153
    .icon = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
154
                          LIBUI_POINT(0, 0)),
155
    .icon_opacity = 0,
156
    .icon_selected = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
157
                                   LIBUI_POINT(0, 0)),
158
    .icon_selected_opacity = 0,
159
    .text = "Clear Rockbox configuration",
160
    .text_pos = LIBUI_POINT(1, 1),
161
    .text_color = 0xffffffff,
162
    .text_color_selected = 0xff7fffff
163
};
164
 
165
void run_clearcfg(void** firmware, void** app, int* size)
166
{
167
    remove("/.rockbox/config.cfg");
168
    memcpy(framebuf, bg, 320 * 240 * 3);
169
    message(97, "Rockbox configuration", "  has been cleared.  ");
170
}
171
 
172
struct chooser_renderer_list_itemdata toolchooser_rparams_cleardb =
173
{
174
    .size = LIBUI_POINT(260, 10),
175
    .fill_box = LIBUI_BOX(LIBUI_POINT(0, 0), LIBUI_POINT(260, 10)),
176
    .fill_color = 0xa0000000,
177
    .fill_color_selected = 0x60ffffff,
178
    .icon_pos = LIBUI_POINT(0, 0),
179
    .icon = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
180
                          LIBUI_POINT(0, 0)),
181
    .icon_opacity = 0,
182
    .icon_selected = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
183
                                   LIBUI_POINT(0, 0)),
184
    .icon_selected_opacity = 0,
185
    .text = "Clear Rockbox database",
186
    .text_pos = LIBUI_POINT(1, 1),
187
    .text_color = 0xffffffff,
188
    .text_color_selected = 0xff7fffff
189
};
190
 
191
void run_cleardb(void** firmware, void** app, int* size)
192
{
193
    remove("/.rockbox/database_0.tcd");
194
    remove("/.rockbox/database_1.tcd");
195
    remove("/.rockbox/database_2.tcd");
196
    remove("/.rockbox/database_3.tcd");
197
    remove("/.rockbox/database_4.tcd");
198
    remove("/.rockbox/database_5.tcd");
199
    remove("/.rockbox/database_6.tcd");
200
    remove("/.rockbox/database_7.tcd");
201
    remove("/.rockbox/database_8.tcd");
202
    remove("/.rockbox/database_9.tcd");
203
    remove("/.rockbox/database_idx.tcd");
204
    remove("/.rockbox/database_tmp.tcd");
205
    remove("/.rockbox/database_state.tcd");
206
    remove("/.rockbox/database_changelog.txt");
207
    memcpy(framebuf, bg, 320 * 240 * 3);
208
    message(109, "Rockbox  database", "has been cleared.");
209
}
210
 
211
struct chooser_renderer_list_itemdata toolchooser_rparams_reformat =
212
{
213
    .size = LIBUI_POINT(260, 10),
214
    .fill_box = LIBUI_BOX(LIBUI_POINT(0, 0), LIBUI_POINT(260, 10)),
215
    .fill_color = 0xa0000000,
216
    .fill_color_selected = 0x60ffffff,
217
    .icon_pos = LIBUI_POINT(0, 0),
218
    .icon = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
219
                          LIBUI_POINT(0, 0)),
220
    .icon_opacity = 0,
221
    .icon_selected = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
222
                                   LIBUI_POINT(0, 0)),
223
    .icon_selected_opacity = 0,
224
    .text = "Reformat data partition",
225
    .text_pos = LIBUI_POINT(1, 1),
226
    .text_color = 0xffffffff,
227
    .text_color_selected = 0xff7fffff
228
};
229
 
230
void fat32_progressbar_init(void* user, int max)
231
{
232
    progressbar_init((struct progressbar_state*)user,
233
                     15, 304, 135, 159, 0x77ff, 0xe8, 0x125f, 0, max);
234
}
235
 
236
void fat32_progressbar_update(void* user, int current)
237
{
238
    progressbar_setpos((struct progressbar_state*)user, current, false);
239
}
240
 
241
void run_reformat(void** firmware, void** app, int* size)
242
{
243
    memcpy(framebuf, bg, 320 * 240 * 3);
244
    rendertext(framebuf, 70, 125, 320, 0xff7fffff, 0, "Reformatting data partition...");
245
    displaylcd(0, 0, 320, 240, framebuf, 0, 0, 320);
246
    struct emcorelib_header* libmkfat32 = loadlib(LIBMKFAT32_IDENTIFIER,
247
                                                  LIBMKFAT32_API_VERSION, "libmkf32");
248
    struct libmkfat32_api* mf32 = (struct libmkfat32_api*)libmkfat32->api;
249
    struct storage_info storageinfo;
250
    storage_get_info(0, &storageinfo);
251
    struct progressbar_state progressbar;
252
    int rc = mf32->mkfat32(0, 0, storageinfo.num_sectors, 4096, 1, "iPodClassic",
253
                           &progressbar, fat32_progressbar_init, fat32_progressbar_update);
254
    if (rc < 0) panicf(PANIC_KILLTHREAD, "Error formatting hard drive: %08X", rc);
255
    release_library(libmkfat32);
256
    library_unload(libmkfat32);
257
    memcpy(framebuf, bg, 320 * 240 * 3);
258
    message(106, "Data partition has", "been  reformatted.");
259
}
260
 
261
struct chooser_renderer_list_params toolchooser_rparams =
262
{
263
    .version = CHOOSER_RENDERER_LIST_PARAMS_VERSION,
264
    .copy_dest = LIBUI_LOCATION(LIBUI_BUFFER(NULL, 320), LIBUI_POINT(0, 0)),
265
    .copy_src = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 320), LIBUI_POINT(0, 0)),
266
                              LIBUI_POINT(320, 240)),
267
    .bg_dest = LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
268
    .bg_src = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
269
                            LIBUI_POINT(0, 0)),
270
    .bg_opacity = 0,
271
    .fill_dest = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
272
                               LIBUI_POINT(0, 0)),
273
    .fill_color = 0,
274
    .viewport = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 320), LIBUI_POINT(30, 50)),
275
                              LIBUI_POINT(260, 160)),
276
    .blit_dest = LIBUI_POINT(0, 0),
277
    .blit_src = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 320), LIBUI_POINT(0, 0)),
278
                              LIBUI_POINT(320, 240)),
279
    .preblit = NULL,
280
    .postblit = NULL
281
};
282
 
283
struct chooser_action_handler_wheel_params toolchooser_aparams =
284
{
285
    .version = CHOOSER_ACTION_HANDLER_WHEEL_PARAMS_VERSION,
286
    .stepsperitem = 128,
287
    .eventfilter = NULL,
288
    .timeout_initial = TIMEOUT_BLOCK,
289
    .timeout_idle = TIMEOUT_BLOCK,
290
    .timeout_item = 0,
291
    .tick_force_redraw = false,
292
    .buttoncount = 5,
293
    .buttonmap =
294
    {
295
        CHOOSER_ACTION_HANDLER_WHEEL_ACTION_SELECT,
296
        CHOOSER_ACTION_HANDLER_WHEEL_ACTION_NEXT,
297
        CHOOSER_ACTION_HANDLER_WHEEL_ACTION_PREV,
298
        CHOOSER_ACTION_HANDLER_WHEEL_ACTION_NEXT,
299
        CHOOSER_ACTION_HANDLER_WHEEL_ACTION_PREV
300
    }
301
};
302
 
303
struct chooser_info toolchooser =
304
{
305
    .version = CHOOSER_INFO_VERSION,
306
    .actionhandler = NULL,
307
    .actionhandlerparams = &toolchooser_aparams,
308
    .renderer = NULL,
309
    .rendererparams = &toolchooser_rparams,
310
    .userparams = NULL,
311
    .tickinterval = 10000000,
312
    .itemcount = 6,
313
    .defaultitem = 0,
314
    .items =
315
    {
316
        {
317
            .user = NULL,
318
            .actionparams = NULL,
319
            .renderparams = &toolchooser_rparams_mainchooser
320
        },
321
        {
322
            .user = run_umsboot,
323
            .actionparams = NULL,
324
            .renderparams = &toolchooser_rparams_umsboot
325
        },
326
        {
327
            .user = run_rockbox_fallback,
328
            .actionparams = NULL,
329
            .renderparams = &toolchooser_rparams_rockbox_fallback
330
        },
331
        {
332
            .user = run_clearcfg,
333
            .actionparams = NULL,
334
            .renderparams = &toolchooser_rparams_clearcfg
335
        },
336
        {
337
            .user = run_cleardb,
338
            .actionparams = NULL,
339
            .renderparams = &toolchooser_rparams_cleardb
340
        },
341
        {
342
            .user = run_reformat,
343
            .actionparams = NULL,
344
            .renderparams = &toolchooser_rparams_reformat
345
        }
346
    }
347
};
348
 
349
bool mainchooser_preblit(struct chooser_data* data)
350
{
528 theseven 351
    char buf[4];
352
    struct chooser_action_handler_wheel_data* adata;
353
    adata = (struct chooser_action_handler_wheel_data*)(data->actionhandlerdata);
354
    snprintf(buf, sizeof(buf), "%3d", adata->timeout_remaining / 1000000);
355
    rendertext(framebuf, 302, 232, 320, 0xffffcccc, 0, buf);
356
    return false;
357
}
358
 
660 theseven 359
struct chooser_renderer_iconflow_itemdata mainchooser_rparams_powerdown =
528 theseven 360
{
361
    .icon = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 80), LIBUI_POINT(0, 56)),
660 theseven 362
                          LIBUI_POINT(80, 79)),
528 theseven 363
    .icon_selected = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 80), LIBUI_POINT(0, 56)),
660 theseven 364
                                   LIBUI_POINT(80, 79)),
528 theseven 365
    .text = "Power off",
366
    .text_color = 0xffffcccc,
367
};
368
 
660 theseven 369
void run_powerdown(void** firmware, void** app, int* size)
528 theseven 370
{
660 theseven 371
    shutdown(true);
372
    power_off();
373
}
374
 
375
struct chooser_renderer_iconflow_itemdata mainchooser_rparams_rockbox =
376
{
528 theseven 377
    .icon = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 80), LIBUI_POINT(0, 0)),
378
                          LIBUI_POINT(80, 25)),
379
    .icon_selected = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 80), LIBUI_POINT(0, 0)),
380
                                   LIBUI_POINT(80, 25)),
381
    .text = "Rockbox",
382
    .text_color = 0xffffcccc,
383
};
384
 
660 theseven 385
void run_rockbox(void** firmware, void** app, int* size)
528 theseven 386
{
660 theseven 387
    int i;
388
    for (i = 1; i <= 96; i += 19)
389
    {
390
        if (i < 96)
391
            ui->blend(320, 240, 50, framebuf, 0, 0, 320,
392
                        framebuf, 0, 0, 320, bg, 0, 0, 320);
393
        else memcpy(framebuf, bg, 320 * 240 * 3);
394
        ui->blit(280, MIN(86, i), 3, framebuf, 20, MAX(0, i - 86), 320,
395
                    rbxlogo, 0, MAX(0, 86 - i), 280);
396
        displaylcd(0, 0, 320, 240, framebuf, 0, 0, 320);
397
    }
398
    boot->load_from_file(firmware, size, true, "/.rockbox/rockbox.ipod", 0);
399
    if (!*firmware)
400
    {
401
        message(76, "Loading rockbox.ipod failed!", "  Trying fallback image...  ");
402
        boot->load_from_flash(firmware, size, true, "rockbox ", 0x100000);
403
    }
404
    if (!*firmware)
405
    {
406
        memcpy(framebuf, bg, 320 * 240 * 3);
407
        message(91, "Loading Rockbox failed!", "Returning to main menu.");
408
    }
409
}
410
 
411
struct chooser_renderer_iconflow_itemdata mainchooser_rparams_console =
412
{
528 theseven 413
    .icon = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 80), LIBUI_POINT(0, 25)),
414
                          LIBUI_POINT(80, 31)),
415
    .icon_selected = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 80), LIBUI_POINT(0, 25)),
416
                                   LIBUI_POINT(80, 31)),
417
    .text = "emCORE console",
418
    .text_color = 0xffffcccc,
419
};
420
 
660 theseven 421
struct chooser_renderer_iconflow_itemdata mainchooser_rparams_toolchooser =
528 theseven 422
{
681 theseven 423
    .icon = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 80), LIBUI_POINT(0, 136)),
424
                          LIBUI_POINT(80, 84)),
425
    .icon_selected = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 80), LIBUI_POINT(0, 136)),
426
                                   LIBUI_POINT(80, 84)),
660 theseven 427
    .text = "Tools",
528 theseven 428
    .text_color = 0xffffcccc,
429
};
430
 
660 theseven 431
static void run_toolchooser(void** firmware, void** app, int* size)
528 theseven 432
{
660 theseven 433
    const struct chooser_item* result = ui->chooser_run(&toolchooser);
434
    if (!result->user) return;
435
    void (*selected_function)(void** firmware, void** app, int* size);
436
    selected_function = (void(*)(void** firmware, void** app, int* size))(result->user);
437
    selected_function(firmware, app, size);
438
}
439
 
440
struct chooser_renderer_iconflow_params mainchooser_rparams =
441
{
442
    .version = CHOOSER_RENDERER_ICONFLOW_PARAMS_VERSION,
528 theseven 443
    .copy_dest = LIBUI_LOCATION(LIBUI_BUFFER(NULL, 320), LIBUI_POINT(0, 0)),
444
    .copy_src = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 320), LIBUI_POINT(0, 0)),
445
                              LIBUI_POINT(320, 240)),
446
    .bg_dest = LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
447
    .bg_src = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
448
                            LIBUI_POINT(0, 0)),
449
    .bg_opacity = 0,
450
    .fill_dest = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
451
                               LIBUI_POINT(0, 0)),
452
    .fill_color = 0,
453
    .viewport = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 320), LIBUI_POINT(0, 30)),
454
                              LIBUI_POINT(320, 130)),
455
    .text_pos = LIBUI_POINT(160, 215),
456
    .blit_dest = LIBUI_POINT(0, 0),
457
    .blit_src = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 320), LIBUI_POINT(0, 0)),
458
                              LIBUI_POINT(320, 240)),
459
    .smoothness = 500000,
460
    .startposition = -3,
461
    .iconsinview = 4,
660 theseven 462
    .preblit = mainchooser_preblit,
528 theseven 463
    .postblit = NULL
464
};
465
 
660 theseven 466
struct chooser_action_handler_wheel_params mainchooser_aparams =
528 theseven 467
{
468
    .version = CHOOSER_ACTION_HANDLER_WHEEL_PARAMS_VERSION,
469
    .stepsperitem = 512,
470
    .eventfilter = NULL,
471
    .timeout_initial = 30500000,
472
    .timeout_idle = 300500000,
473
    .timeout_item = 0,
474
    .tick_force_redraw = true,
475
    .buttoncount = 3,
476
    .buttonmap =
477
    {
478
        CHOOSER_ACTION_HANDLER_WHEEL_ACTION_SELECT,
479
        CHOOSER_ACTION_HANDLER_WHEEL_ACTION_NEXT,
480
        CHOOSER_ACTION_HANDLER_WHEEL_ACTION_PREV
481
    }
482
};
483
 
660 theseven 484
struct chooser_info mainchooser =
528 theseven 485
{
486
    .version = CHOOSER_INFO_VERSION,
487
    .actionhandler = NULL,
660 theseven 488
    .actionhandlerparams = &mainchooser_aparams,
528 theseven 489
    .renderer = NULL,
660 theseven 490
    .rendererparams = &mainchooser_rparams,
528 theseven 491
    .userparams = NULL,
492
    .tickinterval = 990000,
493
    .itemcount = 4,
494
    .defaultitem = 1,
495
    .items =
496
    {
497
        {
667 theseven 498
            .user = run_powerdown,
528 theseven 499
            .actionparams = NULL,
660 theseven 500
            .renderparams = &mainchooser_rparams_powerdown
528 theseven 501
        },
502
        {
667 theseven 503
            .user = run_rockbox,
528 theseven 504
            .actionparams = NULL,
660 theseven 505
            .renderparams = &mainchooser_rparams_rockbox
528 theseven 506
        },
507
        {
660 theseven 508
            .user = NULL,
528 theseven 509
            .actionparams = NULL,
660 theseven 510
            .renderparams = &mainchooser_rparams_console
528 theseven 511
        },
512
        {
660 theseven 513
            .user = run_toolchooser,
528 theseven 514
            .actionparams = NULL,
660 theseven 515
            .renderparams = &mainchooser_rparams_toolchooser
528 theseven 516
        }
517
    }
518
};
519
 
660 theseven 520
static void run_mainchooser(void** firmware, void** app, int* size)
521
{
522
    while (!*firmware && !*app)
523
    {
524
        const struct chooser_item* result = ui->chooser_run(&mainchooser);
525
        if (!result->user) return;
526
        void (*selected_function)(void** firmware, void** app, int* size);
527
        selected_function = (void(*)(void** firmware, void** app, int* size))(result->user);
528
        selected_function(firmware, app, size);
529
    }
530
}
528 theseven 531
 
532
static void main()
533
{
660 theseven 534
    struct emcorelib_header* libpng = loadlib(LIBPNG_IDENTIFIER, LIBPNG_API_VERSION, "libpng  ");
535
    png = (struct libpng_api*)libpng->api;
536
    bg = loadpng("backgrnd", (void* (*)(struct png_info*))(png->png_decode_rgb));
537
    icons = loadpng("iconset ", (void* (*)(struct png_info*))(png->png_decode_rgba));
538
    rbxlogo = loadpng("rbxlogo ", (void* (*)(struct png_info*))(png->png_decode_rgb));
539
    release_library(libpng);
540
    library_unload(libpng);
541
    struct emcorelib_header* libboot = loadlib(LIBBOOT_IDENTIFIER,
542
                                               LIBBOOT_API_VERSION, "libboot ");
543
    boot = (struct libboot_api*)libboot->api;
544
    struct emcorelib_header* libui = loadlib(LIBUI_IDENTIFIER, LIBUI_API_VERSION, "libui   ");
545
    ui = (struct libui_api*)libui->api;
528 theseven 546
    framebuf = malloc(320 * 240 * 3);
547
    if (!framebuf) panicf(PANIC_KILLTHREAD, "Could not allocate framebuffer!");
660 theseven 548
 
549
    mainchooser.actionhandler = ui->chooser_action_handler_wheel;
550
    mainchooser.renderer = ui->chooser_renderer_iconflow;
551
    mainchooser_rparams.copy_dest.buf.addr = framebuf;
552
    mainchooser_rparams.copy_src.loc.buf.addr = bg;
553
    mainchooser_rparams.viewport.loc.buf.addr = framebuf;
554
    mainchooser_rparams.blit_src.loc.buf.addr = framebuf;
555
    mainchooser_rparams_powerdown.icon.loc.buf.addr = icons;
556
    mainchooser_rparams_powerdown.icon_selected.loc.buf.addr = icons;
557
    mainchooser_rparams_rockbox.icon.loc.buf.addr = icons;
558
    mainchooser_rparams_rockbox.icon_selected.loc.buf.addr = icons;
559
    mainchooser_rparams_console.icon.loc.buf.addr = icons;
560
    mainchooser_rparams_console.icon_selected.loc.buf.addr = icons;
561
    mainchooser_rparams_toolchooser.icon.loc.buf.addr = icons;
562
    mainchooser_rparams_toolchooser.icon_selected.loc.buf.addr = icons;
563
 
564
    toolchooser.actionhandler = ui->chooser_action_handler_wheel;
565
    toolchooser.renderer = ui->chooser_renderer_list;
566
    toolchooser_rparams.copy_dest.buf.addr = framebuf;
567
    toolchooser_rparams.copy_src.loc.buf.addr = bg;
568
    toolchooser_rparams.viewport.loc.buf.addr = framebuf;
569
    toolchooser_rparams.blit_src.loc.buf.addr = framebuf;
570
 
528 theseven 571
    void* firmware = NULL;
660 theseven 572
    void* app = NULL;
573
    int size;
574
    run_mainchooser(&firmware, &app, &size);
575
 
528 theseven 576
    free(framebuf);
577
    free(rbxlogo);
578
    free(icons);
579
    free(bg);
580
    release_library(libui);
551 theseven 581
    release_library(libboot);
528 theseven 582
    library_unload(libui);
583
    library_unload(libboot);
660 theseven 584
 
528 theseven 585
    if (firmware)
586
    {
587
        shutdown(false);
588
        execfirmware((void*)0x08000000, firmware, size);
589
    }
660 theseven 590
    else if (app) execimage(app, false);
528 theseven 591
    else cputs(3, "Dropped into emCORE console.\n");
592
}
593
 
594
EMCORE_APP_HEADER("Boot menu", main, 127)