Subversion Repositories freemyipod

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
671 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"
671 theseven 28
#include "libmkfat32.h"
528 theseven 29
 
768 user890104 30
extern char background_png[];
31
extern uint32_t background_png_size;
32
extern char icons_png[];
33
extern uint32_t icons_png_size;
34
extern char rockbox_png[];
35
extern uint32_t rockbox_png_size;
36
extern char crapple_png[];
37
extern uint32_t crapple_png_size;
38
 
671 theseven 39
struct libpng_api* png;
40
struct libboot_api* boot;
41
struct libui_api* ui;
42
void* framebuf;
43
void* framebuf2;
44
void* bg;
45
void* icons;
46
void* rbxlogo;
47
void* crapple;
528 theseven 48
 
671 theseven 49
static struct emcorelib_header* loadlib(uint32_t identifier, uint32_t version, char* filename)
528 theseven 50
{
671 theseven 51
    struct emcorelib_header* lib = get_library(identifier, version, LIBSOURCE_BOOTFLASH, filename);
52
    if (!lib) panicf(PANIC_KILLTHREAD, "Could not load %s", filename);
53
    return lib;
54
}
55
 
768 user890104 56
static void* loadpng(const char* buf, const uint32_t size, void* (*decoder)(struct png_info* handle))
671 theseven 57
{
768 user890104 58
    if (size == 0) panicf(PANIC_KILLTHREAD, "Could not load PNG at 0x%08X", buf);
671 theseven 59
    struct png_info* handle = png->png_open(buf, size);
768 user890104 60
    if (!handle) panicf(PANIC_KILLTHREAD, "Could not parse PNG at 0x%08X", buf);
671 theseven 61
    void* out = decoder(handle);
768 user890104 62
    if (!out) panicf(PANIC_KILLTHREAD, "Could not decode PNG at 0x%08X", buf);
671 theseven 63
    png->png_destroy(handle);
64
    return out;
65
}
66
 
67
static void message(int x, const char* line1, const char* line2)
68
{
69
    rendertext(framebuf, x, 73, 176, 0xff3333ff, 0xa0000000, line1);
70
    rendertext(framebuf, x, 81, 176, 0xff3333ff, 0xa0000000, line2);
806 theseven 71
    update_display(NULL);
671 theseven 72
    displaylcd(0, 0, 176, 132, framebuf, 0, 0, 176);
73
    sleep(5000000);
74
}
75
 
76
struct chooser_renderer_list_itemdata toolchooser_rparams_mainchooser =
77
{
78
    .size = LIBUI_POINT(160, 10),
79
    .fill_box = LIBUI_BOX(LIBUI_POINT(0, 0), LIBUI_POINT(160, 10)),
80
    .fill_color = 0xa0000000,
81
    .fill_color_selected = 0x60ffffff,
82
    .icon_pos = LIBUI_POINT(0, 0),
83
    .icon = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
84
                          LIBUI_POINT(0, 0)),
85
    .icon_opacity = 0,
86
    .icon_selected = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
87
                                   LIBUI_POINT(0, 0)),
88
    .icon_selected_opacity = 0,
89
    .text = "Return to main menu",
90
    .text_pos = LIBUI_POINT(1, 1),
91
    .text_color = 0xffffffff,
92
    .text_color_selected = 0xff7fffff
93
};
94
 
95
struct chooser_renderer_list_itemdata toolchooser_rparams_umsboot =
96
{
97
    .size = LIBUI_POINT(160, 10),
98
    .fill_box = LIBUI_BOX(LIBUI_POINT(0, 0), LIBUI_POINT(160, 10)),
99
    .fill_color = 0xa0000000,
100
    .fill_color_selected = 0x60ffffff,
101
    .icon_pos = LIBUI_POINT(0, 0),
102
    .icon = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
103
                          LIBUI_POINT(0, 0)),
104
    .icon_opacity = 0,
105
    .icon_selected = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
106
                                   LIBUI_POINT(0, 0)),
107
    .icon_selected_opacity = 0,
108
    .text = "Run UMSboot",
109
    .text_pos = LIBUI_POINT(1, 1),
110
    .text_color = 0xffffffff,
111
    .text_color_selected = 0xff7fffff
112
};
113
 
114
void run_umsboot(void** firmware, void** app, int* size)
115
{
116
    boot->load_from_flash(firmware, size, false, "umsboot ", 0x10000);
117
    if (!*firmware)
118
    {
119
        memcpy(framebuf, bg, 176 * 132 * 3);
120
        message(19, "Loading UMSboot failed!", "Returning to main menu.");
121
    }
122
}
123
 
124
struct chooser_renderer_list_itemdata toolchooser_rparams_diagmode =
125
{
126
    .size = LIBUI_POINT(160, 10),
127
    .fill_box = LIBUI_BOX(LIBUI_POINT(0, 0), LIBUI_POINT(160, 10)),
128
    .fill_color = 0xa0000000,
129
    .fill_color_selected = 0x60ffffff,
130
    .icon_pos = LIBUI_POINT(0, 0),
131
    .icon = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
132
                          LIBUI_POINT(0, 0)),
133
    .icon_opacity = 0,
134
    .icon_selected = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
135
                                   LIBUI_POINT(0, 0)),
136
    .icon_selected_opacity = 0,
137
    .text = "Run diagnostics mode",
138
    .text_pos = LIBUI_POINT(1, 1),
139
    .text_color = 0xffffffff,
140
    .text_color_selected = 0xff7fffff
141
};
142
 
143
void run_diagmode(void** firmware, void** app, int* size)
144
{
145
    boot->load_from_flash(firmware, size, false, "diagmode", 0x100000);
146
    if (!*firmware)
147
    {
148
        memcpy(framebuf, bg, 176 * 132 * 3);
149
        message(16, "Loading diag mode failed!", " Returning to main menu. ");
150
    }
151
}
152
 
153
struct chooser_renderer_list_itemdata toolchooser_rparams_rockbox_fallback =
154
{
155
    .size = LIBUI_POINT(160, 10),
156
    .fill_box = LIBUI_BOX(LIBUI_POINT(0, 0), LIBUI_POINT(160, 10)),
157
    .fill_color = 0xa0000000,
158
    .fill_color_selected = 0x60ffffff,
159
    .icon_pos = LIBUI_POINT(0, 0),
160
    .icon = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
161
                          LIBUI_POINT(0, 0)),
162
    .icon_opacity = 0,
163
    .icon_selected = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
164
                                   LIBUI_POINT(0, 0)),
165
    .icon_selected_opacity = 0,
166
    .text = "Run Rockbox fallback image",
167
    .text_pos = LIBUI_POINT(1, 1),
168
    .text_color = 0xffffffff,
169
    .text_color_selected = 0xff7fffff
170
};
171
 
172
void run_rockbox_fallback(void** firmware, void** app, int* size)
173
{
174
    boot->load_from_flash(firmware, size, true, "rockbox ", 0x100000);
175
    if (!*firmware)
176
    {
177
        memcpy(framebuf, bg, 176 * 132 * 3);
178
        message(19, "Loading Rockbox failed!", "Returning to main menu.");
179
    }
180
}
181
 
182
struct chooser_renderer_list_itemdata toolchooser_rparams_clearcfg =
183
{
184
    .size = LIBUI_POINT(160, 10),
185
    .fill_box = LIBUI_BOX(LIBUI_POINT(0, 0), LIBUI_POINT(160, 10)),
186
    .fill_color = 0xa0000000,
187
    .fill_color_selected = 0x60ffffff,
188
    .icon_pos = LIBUI_POINT(0, 0),
189
    .icon = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
190
                          LIBUI_POINT(0, 0)),
191
    .icon_opacity = 0,
192
    .icon_selected = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
193
                                   LIBUI_POINT(0, 0)),
194
    .icon_selected_opacity = 0,
195
    .text = "Clear Rockbox configuration",
196
    .text_pos = LIBUI_POINT(1, 1),
197
    .text_color = 0xffffffff,
198
    .text_color_selected = 0xff7fffff
199
};
200
 
201
void run_clearcfg(void** firmware, void** app, int* size)
202
{
203
    remove("/.rockbox/config.cfg");
204
    memcpy(framebuf, bg, 176 * 132 * 3);
205
    message(25, "Rockbox configuration", "  has been cleared.  ");
206
}
207
 
208
struct chooser_renderer_list_itemdata toolchooser_rparams_cleardb =
209
{
210
    .size = LIBUI_POINT(160, 10),
211
    .fill_box = LIBUI_BOX(LIBUI_POINT(0, 0), LIBUI_POINT(160, 10)),
212
    .fill_color = 0xa0000000,
213
    .fill_color_selected = 0x60ffffff,
214
    .icon_pos = LIBUI_POINT(0, 0),
215
    .icon = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
216
                          LIBUI_POINT(0, 0)),
217
    .icon_opacity = 0,
218
    .icon_selected = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
219
                                   LIBUI_POINT(0, 0)),
220
    .icon_selected_opacity = 0,
221
    .text = "Clear Rockbox database",
222
    .text_pos = LIBUI_POINT(1, 1),
223
    .text_color = 0xffffffff,
224
    .text_color_selected = 0xff7fffff
225
};
226
 
227
void run_cleardb(void** firmware, void** app, int* size)
228
{
229
    remove("/.rockbox/database_0.tcd");
230
    remove("/.rockbox/database_1.tcd");
231
    remove("/.rockbox/database_2.tcd");
232
    remove("/.rockbox/database_3.tcd");
233
    remove("/.rockbox/database_4.tcd");
234
    remove("/.rockbox/database_5.tcd");
235
    remove("/.rockbox/database_6.tcd");
236
    remove("/.rockbox/database_7.tcd");
237
    remove("/.rockbox/database_8.tcd");
238
    remove("/.rockbox/database_9.tcd");
239
    remove("/.rockbox/database_idx.tcd");
240
    remove("/.rockbox/database_tmp.tcd");
241
    remove("/.rockbox/database_state.tcd");
242
    remove("/.rockbox/database_changelog.txt");
243
    memcpy(framebuf, bg, 176 * 132 * 3);
244
    message(37, "Rockbox  database", "has been cleared.");
245
}
246
 
247
struct chooser_renderer_list_itemdata toolchooser_rparams_reformat =
248
{
249
    .size = LIBUI_POINT(160, 10),
250
    .fill_box = LIBUI_BOX(LIBUI_POINT(0, 0), LIBUI_POINT(160, 10)),
251
    .fill_color = 0xa0000000,
252
    .fill_color_selected = 0x60ffffff,
253
    .icon_pos = LIBUI_POINT(0, 0),
254
    .icon = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
255
                          LIBUI_POINT(0, 0)),
256
    .icon_opacity = 0,
257
    .icon_selected = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
258
                                   LIBUI_POINT(0, 0)),
259
    .icon_selected_opacity = 0,
260
    .text = "Reformat data partition",
261
    .text_pos = LIBUI_POINT(1, 1),
262
    .text_color = 0xffffffff,
263
    .text_color_selected = 0xff7fffff
264
};
265
 
266
void fat32_progressbar_init(void* user, int max)
267
{
268
    progressbar_init((struct progressbar_state*)user,
269
                     10, 165, 74, 83, 0x77ff, 0xe8, 0x125f, 0, max);
270
}
271
 
272
void fat32_progressbar_update(void* user, int current)
273
{
274
    progressbar_setpos((struct progressbar_state*)user, current, false);
275
}
276
 
277
void run_reformat(void** firmware, void** app, int* size)
278
{
279
    memcpy(framebuf, bg, 176 * 132 * 3);
280
    rendertext(framebuf, 7, 65, 176, 0xff7fffff, 0, "Reformatting data partition");
806 theseven 281
    update_display(NULL);
671 theseven 282
    displaylcd(0, 0, 176, 132, framebuf, 0, 0, 176);
283
    struct emcorelib_header* libmkfat32 = loadlib(LIBMKFAT32_IDENTIFIER,
284
                                                  LIBMKFAT32_API_VERSION, "libmkf32");
285
    struct libmkfat32_api* mf32 = (struct libmkfat32_api*)libmkfat32->api;
286
    struct storage_info storageinfo;
287
    storage_get_info(0, &storageinfo);
288
    struct progressbar_state progressbar;
289
    int rc = mf32->mkfat32(0, 0, storageinfo.num_sectors, 2048, 1, "iPod Nano2G",
290
                           &progressbar, fat32_progressbar_init, fat32_progressbar_update);
291
    if (rc < 0) panicf(PANIC_KILLTHREAD, "Error formatting data partition: %08X", rc);
292
    release_library(libmkfat32);
293
    library_unload(libmkfat32);
294
    memcpy(framebuf, bg, 176 * 132 * 3);
295
    message(34, "Data partition has", "been  reformatted.");
296
}
297
 
298
struct chooser_renderer_list_itemdata toolchooser_rparams_uninstaller =
299
{
300
    .size = LIBUI_POINT(160, 10),
301
    .fill_box = LIBUI_BOX(LIBUI_POINT(0, 0), LIBUI_POINT(160, 10)),
302
    .fill_color = 0xa0000000,
303
    .fill_color_selected = 0x60ffffff,
304
    .icon_pos = LIBUI_POINT(0, 0),
305
    .icon = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
306
                          LIBUI_POINT(0, 0)),
307
    .icon_opacity = 0,
308
    .icon_selected = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
309
                                   LIBUI_POINT(0, 0)),
310
    .icon_selected_opacity = 0,
311
    .text = "Uninstall emCORE",
312
    .text_pos = LIBUI_POINT(1, 1),
313
    .text_color = 0xffffffff,
314
    .text_color_selected = 0xff7fffff
315
};
316
 
317
void run_uninstaller(void** firmware, void** app, int* size)
318
{
319
    boot->load_from_flash(app, size, false, "uninst  ", 0);
320
    if (!*app)
321
    {
322
        memcpy(framebuf, bg, 176 * 132 * 3);
323
        message(7, "Loading uninstaller failed!", "  Returning to main menu.  ");
324
    }
325
}
326
 
765 user890104 327
bool update_display(struct chooser_data* data)
328
{
329
    char buf[6];
330
    struct rtc_datetime dt;
331
    rtc_read_datetime(&dt);
332
    snprintf(buf, sizeof(buf), "%02d:%02d", dt.hour, dt.minute);
333
    // clock
334
    rendertext(framebuf, 143, 4, 176, 0xffffcccc, 0, buf);
335
    unsigned int batt_level = 22 * read_battery_mwh_current(0) / read_battery_mwh_full(0);
336
    // remaining battery level
337
    ui->blendcolor(batt_level, 6, 0xc0ffcccc, framebuf, 5, 5, 176, framebuf, 5, 5, 176);
338
    // background of the rest space
339
    ui->blendcolor(22 - batt_level, 6, 0x40000000, framebuf, 5 + batt_level, 5, 176, framebuf, 5 + batt_level, 5, 176);
340
    return false;
341
}
342
 
671 theseven 343
struct chooser_renderer_list_params toolchooser_rparams =
344
{
345
    .version = CHOOSER_RENDERER_LIST_PARAMS_VERSION,
346
    .copy_dest = LIBUI_LOCATION(LIBUI_BUFFER(NULL, 176), LIBUI_POINT(0, 0)),
347
    .copy_src = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 176), LIBUI_POINT(0, 0)),
348
                              LIBUI_POINT(176, 132)),
349
    .bg_dest = LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
350
    .bg_src = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
351
                            LIBUI_POINT(0, 0)),
352
    .bg_opacity = 0,
353
    .fill_dest = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
354
                               LIBUI_POINT(0, 0)),
355
    .fill_color = 0,
356
    .viewport = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 176), LIBUI_POINT(7, 30)),
357
                              LIBUI_POINT(162, 80)),
358
    .blit_dest = LIBUI_POINT(0, 0),
359
    .blit_src = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 176), LIBUI_POINT(0, 0)),
360
                              LIBUI_POINT(176, 132)),
765 user890104 361
    .preblit = update_display,
671 theseven 362
    .postblit = NULL
363
};
364
 
365
struct chooser_action_handler_wheel_params toolchooser_aparams =
366
{
367
    .version = CHOOSER_ACTION_HANDLER_WHEEL_PARAMS_VERSION,
368
    .stepsperitem = 128,
369
    .eventfilter = NULL,
370
    .timeout_initial = TIMEOUT_BLOCK,
371
    .timeout_idle = TIMEOUT_BLOCK,
372
    .timeout_item = 0,
373
    .tick_force_redraw = false,
374
    .buttoncount = 5,
375
    .buttonmap =
376
    {
377
        CHOOSER_ACTION_HANDLER_WHEEL_ACTION_SELECT,
378
        CHOOSER_ACTION_HANDLER_WHEEL_ACTION_NEXT,
379
        CHOOSER_ACTION_HANDLER_WHEEL_ACTION_PREV,
380
        CHOOSER_ACTION_HANDLER_WHEEL_ACTION_NEXT,
381
        CHOOSER_ACTION_HANDLER_WHEEL_ACTION_PREV
382
    }
383
};
384
 
385
struct chooser_info toolchooser =
386
{
387
    .version = CHOOSER_INFO_VERSION,
388
    .actionhandler = NULL,
389
    .actionhandlerparams = &toolchooser_aparams,
390
    .renderer = NULL,
391
    .rendererparams = &toolchooser_rparams,
392
    .userparams = NULL,
393
    .tickinterval = 10000000,
394
    .itemcount = 8,
395
    .defaultitem = 0,
396
    .items =
397
    {
398
        {
399
            .user = NULL,
400
            .actionparams = NULL,
401
            .renderparams = &toolchooser_rparams_mainchooser
402
        },
403
        {
404
            .user = run_umsboot,
405
            .actionparams = NULL,
406
            .renderparams = &toolchooser_rparams_umsboot
407
        },
408
        {
409
            .user = run_diagmode,
410
            .actionparams = NULL,
411
            .renderparams = &toolchooser_rparams_diagmode
412
        },
413
        {
414
            .user = run_rockbox_fallback,
415
            .actionparams = NULL,
416
            .renderparams = &toolchooser_rparams_rockbox_fallback
417
        },
418
        {
419
            .user = run_clearcfg,
420
            .actionparams = NULL,
421
            .renderparams = &toolchooser_rparams_clearcfg
422
        },
423
        {
424
            .user = run_cleardb,
425
            .actionparams = NULL,
426
            .renderparams = &toolchooser_rparams_cleardb
427
        },
428
        {
429
            .user = run_reformat,
430
            .actionparams = NULL,
431
            .renderparams = &toolchooser_rparams_reformat
432
        },
433
        {
434
            .user = run_uninstaller,
435
            .actionparams = NULL,
436
            .renderparams = &toolchooser_rparams_uninstaller
437
        }
438
    }
439
};
440
 
441
bool mainchooser_preblit(struct chooser_data* data)
442
{
765 user890104 443
    char buf[4];
528 theseven 444
    struct chooser_action_handler_wheel_data* adata;
445
    adata = (struct chooser_action_handler_wheel_data*)(data->actionhandlerdata);
446
    snprintf(buf, sizeof(buf), "%3d", adata->timeout_remaining / 1000000);
764 user890104 447
    rendertext(framebuf, 155, 121, 176, 0xffffcccc, 0, buf);
765 user890104 448
    update_display(data);
528 theseven 449
    return false;
450
}
451
 
671 theseven 452
struct chooser_renderer_iconflow_itemdata mainchooser_rparams_powerdown =
528 theseven 453
{
777 user890104 454
    .icon = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 44), LIBUI_POINT(0, 0)),
671 theseven 455
                          LIBUI_POINT(44, 44)),
777 user890104 456
    .icon_selected = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 44), LIBUI_POINT(0, 0)),
671 theseven 457
                                   LIBUI_POINT(44, 44)),
528 theseven 458
    .text = "Power off",
459
    .text_color = 0xffffcccc,
460
};
461
 
671 theseven 462
void run_powerdown(void** firmware, void** app, int* size)
528 theseven 463
{
671 theseven 464
    shutdown(true);
465
    power_off();
466
}
467
 
468
struct chooser_renderer_iconflow_itemdata mainchooser_rparams_crapple =
469
{
777 user890104 470
    .icon = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 44), LIBUI_POINT(0, 44)),
471
                          LIBUI_POINT(44, 44)),
472
    .icon_selected = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 44), LIBUI_POINT(0, 44)),
473
                                   LIBUI_POINT(44, 44)),
545 theseven 474
    .text = "Original firmware",
528 theseven 475
    .text_color = 0xffffcccc,
476
};
477
 
671 theseven 478
void run_crapple(void** firmware, void** app, int* size)
528 theseven 479
{
671 theseven 480
    int i;
481
    for (i = 23; i <= 115; i += 23)
482
    {
483
        if (i < 115)
484
            ui->blend(176, 132, 50, framebuf, 0, 0, 176,
485
                      framebuf, 0, 0, 176, bg, 0, 0, 176);
486
        else memcpy(framebuf, bg, 176 * 132 * 3);
487
        memcpy(framebuf2, framebuf, 176 * 132 * 3);
488
        ui->blenda(111, i, 255, framebuf2, 32, 0, 176,
489
                   framebuf2, 32, 0, 176, crapple, 0, 115 - i, 111);
806 theseven 490
        update_display(NULL);
671 theseven 491
        displaylcd(0, 0, 176, 132, framebuf2, 0, 0, 176);
492
    }
493
    boot->load_from_file(firmware, size, false, "/.boot/appleos.ucl", 0x800000);
494
    if (!*firmware) boot->load_from_file(firmware, size, false, "/.boot/appleos.bin", 0);
495
    if (!*firmware) message(7, "Loading appleos.bin failed!", "  Returning to main menu.  ");
496
}
497
 
498
struct chooser_renderer_iconflow_itemdata mainchooser_rparams_rockbox =
499
{
777 user890104 500
    .icon = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 44), LIBUI_POINT(0, 88)),
501
                          LIBUI_POINT(44, 44)),
502
    .icon_selected = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 44), LIBUI_POINT(0, 88)),
503
                                   LIBUI_POINT(44, 44)),
545 theseven 504
    .text = "Rockbox",
528 theseven 505
    .text_color = 0xffffcccc,
506
};
507
 
671 theseven 508
void run_rockbox(void** firmware, void** app, int* size)
528 theseven 509
{
671 theseven 510
    int i;
511
    for (i = 2; i <= 52; i += 10)
512
    {
513
        if (i < 52)
514
            ui->blend(176, 132, 50, framebuf, 0, 0, 176,
515
                      framebuf, 0, 0, 176, bg, 0, 0, 176);
516
        else memcpy(framebuf, bg, 176 * 132 * 3);
517
        ui->blit(154, MIN(47, i), 3, framebuf, 11, MAX(0, i - 47), 176,
518
                 rbxlogo, 0, MAX(0, 47 - i), 154);
806 theseven 519
        update_display(NULL);
671 theseven 520
        displaylcd(0, 0, 176, 132, framebuf, 0, 0, 176);
521
    }
522
    boot->load_from_file(firmware, size, true, "/.rockbox/rockbox.ipod", 0);
523
    if (!*firmware)
524
    {
525
        message(4, "Loading rockbox.ipod failed!", "  Trying fallback image...  ");
526
        boot->load_from_flash(firmware, size, true, "rockbox ", 0x100000);
527
    }
528
    if (!*firmware)
529
    {
530
        memcpy(framebuf, bg, 176 * 132 * 3);
531
        message(19, "Loading Rockbox failed!", "Returning to main menu.");
532
    }
533
}
534
 
535
struct chooser_renderer_iconflow_itemdata mainchooser_rparams_diskmode =
545 theseven 536
{
777 user890104 537
    .icon = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 44), LIBUI_POINT(0, 132)),
538
                          LIBUI_POINT(44, 44)),
539
    .icon_selected = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 44), LIBUI_POINT(0, 132)),
540
                                   LIBUI_POINT(44, 44)),
671 theseven 541
    .text = "Disk mode",
528 theseven 542
    .text_color = 0xffffcccc,
543
};
544
 
671 theseven 545
void run_diskmode(void** firmware, void** app, int* size)
545 theseven 546
{
671 theseven 547
    boot->load_from_flash(firmware, size, false, "diskmode", 0x100000);
548
    if (!*firmware)
549
    {
550
        memcpy(framebuf, bg, 176 * 132 * 3);
551
        message(13, "Loading disk mode failed!", " Returning to main menu. ");
552
    }
553
}
545 theseven 554
 
777 user890104 555
struct chooser_renderer_iconflow_itemdata mainchooser_rparams_console =
556
{
557
    .icon = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 44), LIBUI_POINT(0, 176)),
558
                          LIBUI_POINT(44, 44)),
559
    .icon_selected = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 44), LIBUI_POINT(0, 176)),
560
                                   LIBUI_POINT(44, 44)),
561
    .text = "emCORE console",
562
    .text_color = 0xffffcccc,
563
};
564
 
671 theseven 565
struct chooser_renderer_iconflow_itemdata mainchooser_rparams_toolchooser =
545 theseven 566
{
777 user890104 567
    .icon = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 44), LIBUI_POINT(0, 220)),
568
                          LIBUI_POINT(44, 44)),
569
    .icon_selected = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 44), LIBUI_POINT(0, 220)),
570
                                   LIBUI_POINT(44, 44)),
671 theseven 571
    .text = "Tools",
545 theseven 572
    .text_color = 0xffffcccc,
573
};
574
 
671 theseven 575
static void run_toolchooser(void** firmware, void** app, int* size)
528 theseven 576
{
671 theseven 577
    const struct chooser_item* result = ui->chooser_run(&toolchooser);
578
    if (!result->user) return;
579
    void (*selected_function)(void** firmware, void** app, int* size);
580
    selected_function = (void(*)(void** firmware, void** app, int* size))(result->user);
581
    selected_function(firmware, app, size);
582
}
583
 
584
struct chooser_renderer_iconflow_params mainchooser_rparams =
585
{
586
    .version = CHOOSER_RENDERER_ICONFLOW_PARAMS_VERSION,
545 theseven 587
    .copy_dest = LIBUI_LOCATION(LIBUI_BUFFER(NULL, 176), LIBUI_POINT(0, 0)),
588
    .copy_src = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 176), LIBUI_POINT(0, 0)),
589
                              LIBUI_POINT(176, 132)),
528 theseven 590
    .bg_dest = LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
591
    .bg_src = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
592
                            LIBUI_POINT(0, 0)),
593
    .bg_opacity = 0,
594
    .fill_dest = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
595
                               LIBUI_POINT(0, 0)),
596
    .fill_color = 0,
545 theseven 597
    .viewport = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 176), LIBUI_POINT(0, 16)),
598
                              LIBUI_POINT(176, 72)),
599
    .text_pos = LIBUI_POINT(88, 118),
528 theseven 600
    .blit_dest = LIBUI_POINT(0, 0),
545 theseven 601
    .blit_src = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 176), LIBUI_POINT(0, 0)),
602
                              LIBUI_POINT(176, 132)),
528 theseven 603
    .smoothness = 500000,
604
    .startposition = -3,
605
    .iconsinview = 4,
671 theseven 606
    .preblit = mainchooser_preblit,
528 theseven 607
    .postblit = NULL
608
};
609
 
671 theseven 610
struct chooser_action_handler_wheel_params mainchooser_aparams =
528 theseven 611
{
612
    .version = CHOOSER_ACTION_HANDLER_WHEEL_PARAMS_VERSION,
613
    .stepsperitem = 512,
614
    .eventfilter = NULL,
615
    .timeout_initial = 30500000,
616
    .timeout_idle = 300500000,
617
    .timeout_item = 0,
618
    .tick_force_redraw = true,
619
    .buttoncount = 3,
620
    .buttonmap =
621
    {
622
        CHOOSER_ACTION_HANDLER_WHEEL_ACTION_SELECT,
623
        CHOOSER_ACTION_HANDLER_WHEEL_ACTION_NEXT,
624
        CHOOSER_ACTION_HANDLER_WHEEL_ACTION_PREV
625
    }
626
};
627
 
671 theseven 628
struct chooser_info mainchooser =
528 theseven 629
{
630
    .version = CHOOSER_INFO_VERSION,
631
    .actionhandler = NULL,
671 theseven 632
    .actionhandlerparams = &mainchooser_aparams,
528 theseven 633
    .renderer = NULL,
671 theseven 634
    .rendererparams = &mainchooser_rparams,
528 theseven 635
    .userparams = NULL,
636
    .tickinterval = 990000,
671 theseven 637
    .itemcount = 6,
545 theseven 638
    .defaultitem = 2,
528 theseven 639
    .items =
640
    {
641
        {
671 theseven 642
            .user = run_powerdown,
528 theseven 643
            .actionparams = NULL,
671 theseven 644
            .renderparams = &mainchooser_rparams_powerdown
528 theseven 645
        },
646
        {
671 theseven 647
            .user = run_crapple,
528 theseven 648
            .actionparams = NULL,
671 theseven 649
            .renderparams = &mainchooser_rparams_crapple
528 theseven 650
        },
651
        {
671 theseven 652
            .user = run_rockbox,
528 theseven 653
            .actionparams = NULL,
671 theseven 654
            .renderparams = &mainchooser_rparams_rockbox
528 theseven 655
        },
656
        {
777 user890104 657
            .user = run_diskmode,
528 theseven 658
            .actionparams = NULL,
777 user890104 659
            .renderparams = &mainchooser_rparams_diskmode
545 theseven 660
        },
661
        {
777 user890104 662
            .user = NULL,
545 theseven 663
            .actionparams = NULL,
777 user890104 664
            .renderparams = &mainchooser_rparams_console
545 theseven 665
        },
666
        {
671 theseven 667
            .user = run_toolchooser,
545 theseven 668
            .actionparams = NULL,
671 theseven 669
            .renderparams = &mainchooser_rparams_toolchooser
528 theseven 670
        }
671
    }
672
};
673
 
671 theseven 674
static void run_mainchooser(void** firmware, void** app, int* size)
675
{
676
    while (!*firmware && !*app)
677
    {
678
        const struct chooser_item* result = ui->chooser_run(&mainchooser);
679
        if (!result->user) return;
680
        void (*selected_function)(void** firmware, void** app, int* size);
681
        selected_function = (void(*)(void** firmware, void** app, int* size))(result->user);
682
        selected_function(firmware, app, size);
683
    }
684
}
528 theseven 685
 
686
static void main()
687
{
671 theseven 688
    struct emcorelib_header* libpng = loadlib(LIBPNG_IDENTIFIER, LIBPNG_API_VERSION, "libpng  ");
689
    png = (struct libpng_api*)libpng->api;
768 user890104 690
    bg = loadpng(background_png, background_png_size, (void* (*)(struct png_info*))(png->png_decode_rgb));
691
    icons = loadpng(icons_png, icons_png_size, (void* (*)(struct png_info*))(png->png_decode_rgba));
692
    rbxlogo = loadpng(rockbox_png, rockbox_png_size, (void* (*)(struct png_info*))(png->png_decode_rgb));
693
    crapple = loadpng(crapple_png, crapple_png_size, (void* (*)(struct png_info*))(png->png_decode_rgba));
671 theseven 694
    release_library(libpng);
695
    library_unload(libpng);
696
    struct emcorelib_header* libboot = loadlib(LIBBOOT_IDENTIFIER,
697
                                               LIBBOOT_API_VERSION, "libboot ");
698
    boot = (struct libboot_api*)libboot->api;
699
    struct emcorelib_header* libui = loadlib(LIBUI_IDENTIFIER, LIBUI_API_VERSION, "libui   ");
700
    ui = (struct libui_api*)libui->api;
764 user890104 701
    // draw the battery meter box
702
    // top line
703
    ui->blendcolor(24, 1, 0xffffcccc, bg, 4, 4, 176, bg, 4, 4, 176);
704
    // bottom line
705
    ui->blendcolor(24, 1, 0xffffcccc, bg, 4, 11, 176, bg, 4, 11, 176);
706
    // left line
707
    ui->blendcolor(1, 6, 0xffffcccc, bg, 4, 5, 176, bg, 4, 5, 176);
708
    // right line
709
    ui->blendcolor(1, 6, 0xffffcccc, bg, 27, 5, 176, bg, 27, 5, 176);
710
    // tip - right
711
    ui->blendcolor(1, 4, 0xffffcccc, bg, 28, 6, 176, bg, 28, 6, 176);
545 theseven 712
    framebuf = malloc(176 * 132 * 3);
528 theseven 713
    if (!framebuf) panicf(PANIC_KILLTHREAD, "Could not allocate framebuffer!");
671 theseven 714
    framebuf2 = malloc(176 * 132 * 3);
545 theseven 715
    if (!framebuf2) panicf(PANIC_KILLTHREAD, "Could not allocate framebuffer 2!");
671 theseven 716
    mainchooser.actionhandler = ui->chooser_action_handler_wheel;
717
    mainchooser.renderer = ui->chooser_renderer_iconflow;
718
    mainchooser_rparams.copy_dest.buf.addr = framebuf;
719
    mainchooser_rparams.copy_src.loc.buf.addr = bg;
720
    mainchooser_rparams.viewport.loc.buf.addr = framebuf;
721
    mainchooser_rparams.blit_src.loc.buf.addr = framebuf;
722
    mainchooser_rparams_powerdown.icon.loc.buf.addr = icons;
723
    mainchooser_rparams_powerdown.icon_selected.loc.buf.addr = icons;
724
    mainchooser_rparams_crapple.icon.loc.buf.addr = icons;
725
    mainchooser_rparams_crapple.icon_selected.loc.buf.addr = icons;
726
    mainchooser_rparams_rockbox.icon.loc.buf.addr = icons;
727
    mainchooser_rparams_rockbox.icon_selected.loc.buf.addr = icons;
728
    mainchooser_rparams_console.icon.loc.buf.addr = icons;
729
    mainchooser_rparams_console.icon_selected.loc.buf.addr = icons;
730
    mainchooser_rparams_diskmode.icon.loc.buf.addr = icons;
731
    mainchooser_rparams_diskmode.icon_selected.loc.buf.addr = icons;
732
    mainchooser_rparams_toolchooser.icon.loc.buf.addr = icons;
733
    mainchooser_rparams_toolchooser.icon_selected.loc.buf.addr = icons;
734
 
735
    toolchooser.actionhandler = ui->chooser_action_handler_wheel;
736
    toolchooser.renderer = ui->chooser_renderer_list;
737
    toolchooser_rparams.copy_dest.buf.addr = framebuf;
738
    toolchooser_rparams.copy_src.loc.buf.addr = bg;
739
    toolchooser_rparams.viewport.loc.buf.addr = framebuf;
740
    toolchooser_rparams.blit_src.loc.buf.addr = framebuf;
741
 
551 theseven 742
    backlight_set_brightness(177);
528 theseven 743
    void* firmware = NULL;
671 theseven 744
    void* app = NULL;
745
    int size;
746
    run_mainchooser(&firmware, &app, &size);
747
 
545 theseven 748
    free(framebuf2);
528 theseven 749
    free(framebuf);
545 theseven 750
    free(crapple);
528 theseven 751
    free(rbxlogo);
752
    free(icons);
753
    free(bg);
754
    release_library(libui);
545 theseven 755
    release_library(libboot);
528 theseven 756
    library_unload(libui);
757
    library_unload(libboot);
671 theseven 758
 
528 theseven 759
    if (firmware)
760
    {
761
        shutdown(false);
762
        execfirmware((void*)0x08000000, firmware, size);
763
    }
671 theseven 764
    else if (app) execimage(app, false);
528 theseven 765
    else cputs(3, "Dropped into emCORE console.\n");
766
}
767
 
768
 
769
EMCORE_APP_HEADER("Boot menu", main, 127)