Subversion Repositories freemyipod

Rev

Go to most recent revision | Details | 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
 
765 user890104 261
bool update_display(struct chooser_data* data)
262
{
263
    char buf[6];
264
    struct rtc_datetime dt;
265
    rtc_read_datetime(&dt);
266
    snprintf(buf, sizeof(buf), "%02d:%02d", dt.hour, dt.minute);
267
    // clock
268
    rendertext(framebuf, 287, 4, 320, 0xffffcccc, 0, buf);
269
    unsigned int batt_level = 22 * read_battery_mwh_current(0) / read_battery_mwh_full(0);
270
    // remaining battery level
271
    ui->blendcolor(batt_level, 6, 0xc0ffcccc, framebuf, 5, 5, 320, framebuf, 5, 5, 320);
272
    // background of the rest space
273
    ui->blendcolor(22 - batt_level, 6, 0x40000000, framebuf, 5 + batt_level, 5, 320, framebuf, 5 + batt_level, 5, 320);
274
    return false;
275
}
276
 
660 theseven 277
struct chooser_renderer_list_params toolchooser_rparams =
278
{
279
    .version = CHOOSER_RENDERER_LIST_PARAMS_VERSION,
280
    .copy_dest = LIBUI_LOCATION(LIBUI_BUFFER(NULL, 320), LIBUI_POINT(0, 0)),
281
    .copy_src = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 320), LIBUI_POINT(0, 0)),
282
                              LIBUI_POINT(320, 240)),
283
    .bg_dest = LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
284
    .bg_src = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
285
                            LIBUI_POINT(0, 0)),
286
    .bg_opacity = 0,
287
    .fill_dest = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
288
                               LIBUI_POINT(0, 0)),
289
    .fill_color = 0,
290
    .viewport = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 320), LIBUI_POINT(30, 50)),
291
                              LIBUI_POINT(260, 160)),
292
    .blit_dest = LIBUI_POINT(0, 0),
293
    .blit_src = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 320), LIBUI_POINT(0, 0)),
294
                              LIBUI_POINT(320, 240)),
765 user890104 295
    .preblit = update_display,
660 theseven 296
    .postblit = NULL
297
};
298
 
299
struct chooser_action_handler_wheel_params toolchooser_aparams =
300
{
301
    .version = CHOOSER_ACTION_HANDLER_WHEEL_PARAMS_VERSION,
302
    .stepsperitem = 128,
303
    .eventfilter = NULL,
304
    .timeout_initial = TIMEOUT_BLOCK,
305
    .timeout_idle = TIMEOUT_BLOCK,
306
    .timeout_item = 0,
307
    .tick_force_redraw = false,
308
    .buttoncount = 5,
309
    .buttonmap =
310
    {
311
        CHOOSER_ACTION_HANDLER_WHEEL_ACTION_SELECT,
312
        CHOOSER_ACTION_HANDLER_WHEEL_ACTION_NEXT,
313
        CHOOSER_ACTION_HANDLER_WHEEL_ACTION_PREV,
314
        CHOOSER_ACTION_HANDLER_WHEEL_ACTION_NEXT,
315
        CHOOSER_ACTION_HANDLER_WHEEL_ACTION_PREV
316
    }
317
};
318
 
319
struct chooser_info toolchooser =
320
{
321
    .version = CHOOSER_INFO_VERSION,
322
    .actionhandler = NULL,
323
    .actionhandlerparams = &toolchooser_aparams,
324
    .renderer = NULL,
325
    .rendererparams = &toolchooser_rparams,
326
    .userparams = NULL,
327
    .tickinterval = 10000000,
328
    .itemcount = 6,
329
    .defaultitem = 0,
330
    .items =
331
    {
332
        {
333
            .user = NULL,
334
            .actionparams = NULL,
335
            .renderparams = &toolchooser_rparams_mainchooser
336
        },
337
        {
338
            .user = run_umsboot,
339
            .actionparams = NULL,
340
            .renderparams = &toolchooser_rparams_umsboot
341
        },
342
        {
343
            .user = run_rockbox_fallback,
344
            .actionparams = NULL,
345
            .renderparams = &toolchooser_rparams_rockbox_fallback
346
        },
347
        {
348
            .user = run_clearcfg,
349
            .actionparams = NULL,
350
            .renderparams = &toolchooser_rparams_clearcfg
351
        },
352
        {
353
            .user = run_cleardb,
354
            .actionparams = NULL,
355
            .renderparams = &toolchooser_rparams_cleardb
356
        },
357
        {
358
            .user = run_reformat,
359
            .actionparams = NULL,
360
            .renderparams = &toolchooser_rparams_reformat
361
        }
362
    }
363
};
364
 
365
bool mainchooser_preblit(struct chooser_data* data)
366
{
765 user890104 367
    char buf[4];
528 theseven 368
    struct chooser_action_handler_wheel_data* adata;
369
    adata = (struct chooser_action_handler_wheel_data*)(data->actionhandlerdata);
370
    snprintf(buf, sizeof(buf), "%3d", adata->timeout_remaining / 1000000);
764 user890104 371
    rendertext(framebuf, 299, 229, 320, 0xffffcccc, 0, buf);
765 user890104 372
    update_display(data);
528 theseven 373
    return false;
374
}
375
 
660 theseven 376
struct chooser_renderer_iconflow_itemdata mainchooser_rparams_powerdown =
528 theseven 377
{
378
    .icon = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 80), LIBUI_POINT(0, 56)),
660 theseven 379
                          LIBUI_POINT(80, 79)),
528 theseven 380
    .icon_selected = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 80), LIBUI_POINT(0, 56)),
660 theseven 381
                                   LIBUI_POINT(80, 79)),
528 theseven 382
    .text = "Power off",
383
    .text_color = 0xffffcccc,
384
};
385
 
660 theseven 386
void run_powerdown(void** firmware, void** app, int* size)
528 theseven 387
{
660 theseven 388
    shutdown(true);
389
    power_off();
390
}
391
 
392
struct chooser_renderer_iconflow_itemdata mainchooser_rparams_rockbox =
393
{
528 theseven 394
    .icon = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 80), LIBUI_POINT(0, 0)),
395
                          LIBUI_POINT(80, 25)),
396
    .icon_selected = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 80), LIBUI_POINT(0, 0)),
397
                                   LIBUI_POINT(80, 25)),
398
    .text = "Rockbox",
399
    .text_color = 0xffffcccc,
400
};
401
 
660 theseven 402
void run_rockbox(void** firmware, void** app, int* size)
528 theseven 403
{
660 theseven 404
    int i;
405
    for (i = 1; i <= 96; i += 19)
406
    {
407
        if (i < 96)
408
            ui->blend(320, 240, 50, framebuf, 0, 0, 320,
409
                        framebuf, 0, 0, 320, bg, 0, 0, 320);
410
        else memcpy(framebuf, bg, 320 * 240 * 3);
411
        ui->blit(280, MIN(86, i), 3, framebuf, 20, MAX(0, i - 86), 320,
412
                    rbxlogo, 0, MAX(0, 86 - i), 280);
413
        displaylcd(0, 0, 320, 240, framebuf, 0, 0, 320);
414
    }
415
    boot->load_from_file(firmware, size, true, "/.rockbox/rockbox.ipod", 0);
416
    if (!*firmware)
417
    {
418
        message(76, "Loading rockbox.ipod failed!", "  Trying fallback image...  ");
419
        boot->load_from_flash(firmware, size, true, "rockbox ", 0x100000);
420
    }
421
    if (!*firmware)
422
    {
423
        memcpy(framebuf, bg, 320 * 240 * 3);
424
        message(91, "Loading Rockbox failed!", "Returning to main menu.");
425
    }
426
}
427
 
428
struct chooser_renderer_iconflow_itemdata mainchooser_rparams_console =
429
{
528 theseven 430
    .icon = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 80), LIBUI_POINT(0, 25)),
431
                          LIBUI_POINT(80, 31)),
432
    .icon_selected = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 80), LIBUI_POINT(0, 25)),
433
                                   LIBUI_POINT(80, 31)),
434
    .text = "emCORE console",
435
    .text_color = 0xffffcccc,
436
};
437
 
660 theseven 438
struct chooser_renderer_iconflow_itemdata mainchooser_rparams_toolchooser =
528 theseven 439
{
681 theseven 440
    .icon = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 80), LIBUI_POINT(0, 136)),
441
                          LIBUI_POINT(80, 84)),
442
    .icon_selected = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 80), LIBUI_POINT(0, 136)),
443
                                   LIBUI_POINT(80, 84)),
660 theseven 444
    .text = "Tools",
528 theseven 445
    .text_color = 0xffffcccc,
446
};
447
 
660 theseven 448
static void run_toolchooser(void** firmware, void** app, int* size)
528 theseven 449
{
660 theseven 450
    const struct chooser_item* result = ui->chooser_run(&toolchooser);
451
    if (!result->user) return;
452
    void (*selected_function)(void** firmware, void** app, int* size);
453
    selected_function = (void(*)(void** firmware, void** app, int* size))(result->user);
454
    selected_function(firmware, app, size);
455
}
456
 
457
struct chooser_renderer_iconflow_params mainchooser_rparams =
458
{
459
    .version = CHOOSER_RENDERER_ICONFLOW_PARAMS_VERSION,
528 theseven 460
    .copy_dest = LIBUI_LOCATION(LIBUI_BUFFER(NULL, 320), LIBUI_POINT(0, 0)),
461
    .copy_src = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 320), LIBUI_POINT(0, 0)),
462
                              LIBUI_POINT(320, 240)),
463
    .bg_dest = LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
464
    .bg_src = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
465
                            LIBUI_POINT(0, 0)),
466
    .bg_opacity = 0,
467
    .fill_dest = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
468
                               LIBUI_POINT(0, 0)),
469
    .fill_color = 0,
470
    .viewport = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 320), LIBUI_POINT(0, 30)),
471
                              LIBUI_POINT(320, 130)),
472
    .text_pos = LIBUI_POINT(160, 215),
473
    .blit_dest = LIBUI_POINT(0, 0),
474
    .blit_src = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 320), LIBUI_POINT(0, 0)),
475
                              LIBUI_POINT(320, 240)),
476
    .smoothness = 500000,
477
    .startposition = -3,
478
    .iconsinview = 4,
660 theseven 479
    .preblit = mainchooser_preblit,
528 theseven 480
    .postblit = NULL
481
};
482
 
660 theseven 483
struct chooser_action_handler_wheel_params mainchooser_aparams =
528 theseven 484
{
485
    .version = CHOOSER_ACTION_HANDLER_WHEEL_PARAMS_VERSION,
486
    .stepsperitem = 512,
487
    .eventfilter = NULL,
488
    .timeout_initial = 30500000,
489
    .timeout_idle = 300500000,
490
    .timeout_item = 0,
491
    .tick_force_redraw = true,
492
    .buttoncount = 3,
493
    .buttonmap =
494
    {
495
        CHOOSER_ACTION_HANDLER_WHEEL_ACTION_SELECT,
496
        CHOOSER_ACTION_HANDLER_WHEEL_ACTION_NEXT,
497
        CHOOSER_ACTION_HANDLER_WHEEL_ACTION_PREV
498
    }
499
};
500
 
660 theseven 501
struct chooser_info mainchooser =
528 theseven 502
{
503
    .version = CHOOSER_INFO_VERSION,
504
    .actionhandler = NULL,
660 theseven 505
    .actionhandlerparams = &mainchooser_aparams,
528 theseven 506
    .renderer = NULL,
660 theseven 507
    .rendererparams = &mainchooser_rparams,
528 theseven 508
    .userparams = NULL,
509
    .tickinterval = 990000,
510
    .itemcount = 4,
511
    .defaultitem = 1,
512
    .items =
513
    {
514
        {
667 theseven 515
            .user = run_powerdown,
528 theseven 516
            .actionparams = NULL,
660 theseven 517
            .renderparams = &mainchooser_rparams_powerdown
528 theseven 518
        },
519
        {
667 theseven 520
            .user = run_rockbox,
528 theseven 521
            .actionparams = NULL,
660 theseven 522
            .renderparams = &mainchooser_rparams_rockbox
528 theseven 523
        },
524
        {
660 theseven 525
            .user = NULL,
528 theseven 526
            .actionparams = NULL,
660 theseven 527
            .renderparams = &mainchooser_rparams_console
528 theseven 528
        },
529
        {
660 theseven 530
            .user = run_toolchooser,
528 theseven 531
            .actionparams = NULL,
660 theseven 532
            .renderparams = &mainchooser_rparams_toolchooser
528 theseven 533
        }
534
    }
535
};
536
 
660 theseven 537
static void run_mainchooser(void** firmware, void** app, int* size)
538
{
539
    while (!*firmware && !*app)
540
    {
541
        const struct chooser_item* result = ui->chooser_run(&mainchooser);
542
        if (!result->user) return;
543
        void (*selected_function)(void** firmware, void** app, int* size);
544
        selected_function = (void(*)(void** firmware, void** app, int* size))(result->user);
545
        selected_function(firmware, app, size);
546
    }
547
}
528 theseven 548
 
549
static void main()
550
{
660 theseven 551
    struct emcorelib_header* libpng = loadlib(LIBPNG_IDENTIFIER, LIBPNG_API_VERSION, "libpng  ");
552
    png = (struct libpng_api*)libpng->api;
553
    bg = loadpng("backgrnd", (void* (*)(struct png_info*))(png->png_decode_rgb));
554
    icons = loadpng("iconset ", (void* (*)(struct png_info*))(png->png_decode_rgba));
555
    rbxlogo = loadpng("rbxlogo ", (void* (*)(struct png_info*))(png->png_decode_rgb));
556
    release_library(libpng);
557
    library_unload(libpng);
558
    struct emcorelib_header* libboot = loadlib(LIBBOOT_IDENTIFIER,
559
                                               LIBBOOT_API_VERSION, "libboot ");
560
    boot = (struct libboot_api*)libboot->api;
561
    struct emcorelib_header* libui = loadlib(LIBUI_IDENTIFIER, LIBUI_API_VERSION, "libui   ");
562
    ui = (struct libui_api*)libui->api;
764 user890104 563
    // draw the battery meter box
564
    // top line
565
    ui->blendcolor(24, 1, 0xffffcccc, bg, 4, 4, 320, bg, 4, 4, 320);
566
    // bottom line
567
    ui->blendcolor(24, 1, 0xffffcccc, bg, 4, 11, 320, bg, 4, 11, 320);
568
    // left line
569
    ui->blendcolor(1, 6, 0xffffcccc, bg, 4, 5, 320, bg, 4, 5, 320);
570
    // right line
571
    ui->blendcolor(1, 6, 0xffffcccc, bg, 27, 5, 320, bg, 27, 5, 320);
572
    // tip - right
573
    ui->blendcolor(1, 4, 0xffffcccc, bg, 28, 6, 320, bg, 28, 6, 320);
528 theseven 574
    framebuf = malloc(320 * 240 * 3);
575
    if (!framebuf) panicf(PANIC_KILLTHREAD, "Could not allocate framebuffer!");
660 theseven 576
 
577
    mainchooser.actionhandler = ui->chooser_action_handler_wheel;
578
    mainchooser.renderer = ui->chooser_renderer_iconflow;
579
    mainchooser_rparams.copy_dest.buf.addr = framebuf;
580
    mainchooser_rparams.copy_src.loc.buf.addr = bg;
581
    mainchooser_rparams.viewport.loc.buf.addr = framebuf;
582
    mainchooser_rparams.blit_src.loc.buf.addr = framebuf;
583
    mainchooser_rparams_powerdown.icon.loc.buf.addr = icons;
584
    mainchooser_rparams_powerdown.icon_selected.loc.buf.addr = icons;
585
    mainchooser_rparams_rockbox.icon.loc.buf.addr = icons;
586
    mainchooser_rparams_rockbox.icon_selected.loc.buf.addr = icons;
587
    mainchooser_rparams_console.icon.loc.buf.addr = icons;
588
    mainchooser_rparams_console.icon_selected.loc.buf.addr = icons;
589
    mainchooser_rparams_toolchooser.icon.loc.buf.addr = icons;
590
    mainchooser_rparams_toolchooser.icon_selected.loc.buf.addr = icons;
591
 
592
    toolchooser.actionhandler = ui->chooser_action_handler_wheel;
593
    toolchooser.renderer = ui->chooser_renderer_list;
594
    toolchooser_rparams.copy_dest.buf.addr = framebuf;
595
    toolchooser_rparams.copy_src.loc.buf.addr = bg;
596
    toolchooser_rparams.viewport.loc.buf.addr = framebuf;
597
    toolchooser_rparams.blit_src.loc.buf.addr = framebuf;
598
 
528 theseven 599
    void* firmware = NULL;
660 theseven 600
    void* app = NULL;
601
    int size;
602
    run_mainchooser(&firmware, &app, &size);
603
 
528 theseven 604
    free(framebuf);
605
    free(rbxlogo);
606
    free(icons);
607
    free(bg);
608
    release_library(libui);
551 theseven 609
    release_library(libboot);
528 theseven 610
    library_unload(libui);
611
    library_unload(libboot);
660 theseven 612
 
528 theseven 613
    if (firmware)
614
    {
615
        shutdown(false);
616
        execfirmware((void*)0x08000000, firmware, size);
617
    }
660 theseven 618
    else if (app) execimage(app, false);
528 theseven 619
    else cputs(3, "Dropped into emCORE console.\n");
620
}
621
 
622
EMCORE_APP_HEADER("Boot menu", main, 127)