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