Subversion Repositories freemyipod

Rev

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

Rev Author Line No. Line
528 theseven 1
#include "emcoreapp.h"
2
#include "libboot.h"
3
#include "libpng.h"
4
#include "libui.h"
5
 
6
 
7
void* framebuf;
8
 
9
 
10
bool mychooser_preblit(struct chooser_data* data)
11
{
12
    char buf[4];
13
    struct chooser_action_handler_wheel_data* adata;
14
    adata = (struct chooser_action_handler_wheel_data*)(data->actionhandlerdata);
15
    snprintf(buf, sizeof(buf), "%3d", adata->timeout_remaining / 1000000);
16
    rendertext(framebuf, 302, 232, 320, 0xffffcccc, 0, buf);
17
    return false;
18
}
19
 
20
 
21
struct chooser_renderer_iconflow_itemdata mychooser_rparams_0 =
22
{
23
    .icon = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 80), LIBUI_POINT(0, 56)),
24
                          LIBUI_POINT(80, 72)),
25
    .icon_selected = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 80), LIBUI_POINT(0, 56)),
26
                                   LIBUI_POINT(80, 72)),
27
    .text = "Power off",
28
    .text_color = 0xffffcccc,
29
};
30
 
31
struct chooser_renderer_iconflow_itemdata mychooser_rparams_1 =
32
{
33
    .icon = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 80), LIBUI_POINT(0, 0)),
34
                          LIBUI_POINT(80, 25)),
35
    .icon_selected = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 80), LIBUI_POINT(0, 0)),
36
                                   LIBUI_POINT(80, 25)),
37
    .text = "Rockbox",
38
    .text_color = 0xffffcccc,
39
};
40
 
41
struct chooser_renderer_iconflow_itemdata mychooser_rparams_2 =
42
{
43
    .icon = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 80), LIBUI_POINT(0, 25)),
44
                          LIBUI_POINT(80, 31)),
45
    .icon_selected = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 80), LIBUI_POINT(0, 25)),
46
                                   LIBUI_POINT(80, 31)),
47
    .text = "emCORE console",
48
    .text_color = 0xffffcccc,
49
};
50
 
51
struct chooser_renderer_iconflow_itemdata mychooser_rparams_3 =
52
{
53
    .icon = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 80), LIBUI_POINT(0, 130)),
54
                          LIBUI_POINT(80, 55)),
55
    .icon_selected = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 80), LIBUI_POINT(0, 130)),
56
                                   LIBUI_POINT(80, 55)),
57
    .text = "UMSboot",
58
    .text_color = 0xffffcccc,
59
};
60
 
61
struct chooser_renderer_iconflow_params mychooser_rparams =
62
{
63
    .version = CHOOSER_RENDERER_LIST_PARAMS_VERSION,
64
    .copy_dest = LIBUI_LOCATION(LIBUI_BUFFER(NULL, 320), LIBUI_POINT(0, 0)),
65
    .copy_src = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 320), LIBUI_POINT(0, 0)),
66
                              LIBUI_POINT(320, 240)),
67
    .bg_dest = LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
68
    .bg_src = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
69
                            LIBUI_POINT(0, 0)),
70
    .bg_opacity = 0,
71
    .fill_dest = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 0), LIBUI_POINT(0, 0)),
72
                               LIBUI_POINT(0, 0)),
73
    .fill_color = 0,
74
    .viewport = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 320), LIBUI_POINT(0, 30)),
75
                              LIBUI_POINT(320, 130)),
76
    .text_pos = LIBUI_POINT(160, 215),
77
    .blit_dest = LIBUI_POINT(0, 0),
78
    .blit_src = LIBUI_SURFACE(LIBUI_LOCATION(LIBUI_BUFFER(NULL, 320), LIBUI_POINT(0, 0)),
79
                              LIBUI_POINT(320, 240)),
80
    .smoothness = 500000,
81
    .startposition = -3,
82
    .iconsinview = 4,
83
    .preblit = mychooser_preblit,
84
    .postblit = NULL
85
};
86
 
87
struct chooser_action_handler_wheel_params mychooser_aparams =
88
{
89
    .version = CHOOSER_ACTION_HANDLER_WHEEL_PARAMS_VERSION,
90
    .stepsperitem = 512,
91
    .eventfilter = NULL,
92
    .timeout_initial = 30500000,
93
    .timeout_idle = 300500000,
94
    .timeout_item = 0,
95
    .tick_force_redraw = true,
96
    .buttoncount = 3,
97
    .buttonmap =
98
    {
99
        CHOOSER_ACTION_HANDLER_WHEEL_ACTION_SELECT,
100
        CHOOSER_ACTION_HANDLER_WHEEL_ACTION_NEXT,
101
        CHOOSER_ACTION_HANDLER_WHEEL_ACTION_PREV
102
    }
103
};
104
 
105
struct chooser_info mychooser =
106
{
107
    .version = CHOOSER_INFO_VERSION,
108
    .actionhandler = NULL,
109
    .actionhandlerparams = &mychooser_aparams,
110
    .renderer = NULL,
111
    .rendererparams = &mychooser_rparams,
112
    .userparams = NULL,
113
    .tickinterval = 990000,
114
    .itemcount = 4,
115
    .defaultitem = 1,
116
    .items =
117
    {
118
        {
119
            .user = (void*)0,
120
            .actionparams = NULL,
121
            .renderparams = &mychooser_rparams_0
122
        },
123
        {
124
            .user = (void*)1,
125
            .actionparams = NULL,
126
            .renderparams = &mychooser_rparams_1
127
        },
128
        {
129
            .user = (void*)2,
130
            .actionparams = NULL,
131
            .renderparams = &mychooser_rparams_2
132
        },
133
        {
134
            .user = (void*)3,
135
            .actionparams = NULL,
136
            .renderparams = &mychooser_rparams_3
137
        }
138
    }
139
};
140
 
141
 
142
static void main()
143
{
144
    struct emcorelib_header* libboot = get_library(0x4c424365, LIBBOOT_API_VERSION, LIBSOURCE_BOOTFLASH, "libboot ");
145
    if (!libboot) panicf(PANIC_KILLTHREAD, "Could not load booting library!");
146
    struct libboot_api* boot = (struct libboot_api*)libboot->api;
147
    struct emcorelib_header* libpng = get_library(0x64474e50, LIBPNG_API_VERSION, LIBSOURCE_BOOTFLASH, "libpng  ");
148
    if (!libpng) panicf(PANIC_KILLTHREAD, "Could not load PNG decoder library!");
149
    struct libpng_api* png = (struct libpng_api*)libpng->api;
150
    struct emcorelib_header* libui = get_library(0x49554365, LIBUI_API_VERSION, LIBSOURCE_BOOTFLASH, "libui   ");
151
    if (!libui) panicf(PANIC_KILLTHREAD, "Could not load user interface library!");
152
    struct libui_api* ui = (struct libui_api*)libui->api;
153
    int size = bootflash_filesize("backgrnd");
154
    if (size == -1) panicf(PANIC_KILLTHREAD, "Could not find background image!");
155
    void* buf = memalign(0x10, size);
156
    if (!buf) panicf(PANIC_KILLTHREAD, "Could not allocate buffer for background image!");
157
    bootflash_read("backgrnd", buf, 0, size);
158
    struct png_info* handle = png->png_open(buf, size);
159
    if (!handle) panicf(PANIC_KILLTHREAD, "Could not parse background image!");
160
    struct png_rgb* bg = png->png_decode_rgb(handle);
161
    if (!bg) panicf(PANIC_KILLTHREAD, "Could not decode background image!");
162
    png->png_destroy(handle);
163
    free(buf);
164
    size = bootflash_filesize("iconset ");
165
    if (size == -1) panicf(PANIC_KILLTHREAD, "Could not find icon set!");
166
    buf = memalign(0x10, size);
167
    if (!buf) panicf(PANIC_KILLTHREAD, "Could not allocate buffer for icon set!");
168
    bootflash_read("iconset ", buf, 0, size);
169
    handle = png->png_open(buf, size);
170
    if (!handle) panicf(PANIC_KILLTHREAD, "Could not parse icon set!");
171
    struct png_rgba* icons = png->png_decode_rgba(handle);
172
    if (!icons) panicf(PANIC_KILLTHREAD, "Could not decode icon set!");
173
    png->png_destroy(handle);
174
    free(buf);
175
    size = bootflash_filesize("rbxlogo ");
176
    if (size == -1) panicf(PANIC_KILLTHREAD, "Could not find Rockbox logo!");
177
    buf = memalign(0x10, size);
178
    if (!buf) panicf(PANIC_KILLTHREAD, "Could not allocate buffer for Rockbox logo!");
179
    bootflash_read("rbxlogo ", buf, 0, size);
180
    handle = png->png_open(buf, size);
181
    if (!handle) panicf(PANIC_KILLTHREAD, "Could not parse Rockbox logo!");
182
    struct png_rgb* rbxlogo = png->png_decode_rgb(handle);
183
    if (!rbxlogo) panicf(PANIC_KILLTHREAD, "Could not decode Rockbox logo!");
184
    png->png_destroy(handle);
185
    free(buf);
186
    framebuf = malloc(320 * 240 * 3);
187
    if (!framebuf) panicf(PANIC_KILLTHREAD, "Could not allocate framebuffer!");
188
    mychooser.actionhandler = ui->chooser_action_handler_wheel;
189
    mychooser.renderer = ui->chooser_renderer_iconflow;
190
    mychooser_rparams.copy_dest.buf.addr = framebuf;
191
    mychooser_rparams.copy_src.loc.buf.addr = bg;
192
    mychooser_rparams.viewport.loc.buf.addr = framebuf;
193
    mychooser_rparams.blit_src.loc.buf.addr = framebuf;
194
    mychooser_rparams_0.icon.loc.buf.addr = icons;
195
    mychooser_rparams_0.icon_selected.loc.buf.addr = icons;
196
    mychooser_rparams_1.icon.loc.buf.addr = icons;
197
    mychooser_rparams_1.icon_selected.loc.buf.addr = icons;
198
    mychooser_rparams_2.icon.loc.buf.addr = icons;
199
    mychooser_rparams_2.icon_selected.loc.buf.addr = icons;
200
    mychooser_rparams_3.icon.loc.buf.addr = icons;
201
    mychooser_rparams_3.icon_selected.loc.buf.addr = icons;
202
    void* firmware = NULL;
203
    while (!firmware)
204
    {
205
        const struct chooser_item* result = ui->chooser_run(&mychooser);
206
        switch ((int)(result->user))
207
        {
208
        case 0:
209
            shutdown(true);
210
            power_off();
211
            break;
212
        case 1:
213
        {
214
            int i;
215
            for (i = 0; i <= 300; i += 60)
216
            {
217
                if (i < 300)
218
                    ui->blend(320, 240, 50, framebuf, 0, 0, 320,
219
                              framebuf, 0, 0, 320, bg, 0, 0, 320);
220
                else memcpy(framebuf, bg, 320 * 240 * 3);
221
                ui->blit(MIN(280, i), 86, 3, framebuf, 320 - i, 10, 320, rbxlogo, 0, 0, 280);
222
                displaylcd(0, 0, 320, 240, framebuf, 0, 0, 320);
223
            }
224
            int fd = file_open("/.rockbox/rockbox.ipod", O_RDONLY);
225
            if (fd > 0)
226
            {
227
                size = filesize(fd);
228
                if (size > 0)
229
                {
230
                    void* buf = memalign(0x10, size);
231
                    if (buf)
232
                    {
233
                        if (read(fd, buf, size) == size)
234
                            if (!boot->verify_rockbox_checksum(buf, size))
235
                                firmware = buf;
236
                        if (!firmware) free(buf);
237
                    }
238
                }
239
                close(fd);
240
            }
241
            if (!firmware)
242
            {
243
                rendertext(framebuf, 76, 140, 320, 0xff3333ff, 0xa0000000, "Loading rockbox.ipod failed!");
244
                rendertext(framebuf, 76, 148, 320, 0xff3333ff, 0xa0000000, "  Trying fallback image...  ");
245
                displaylcd(0, 0, 320, 240, framebuf, 0, 0, 320);
246
                sleep(5000000);
247
                size = bootflash_filesize("rockbox ");
248
                if (size > 0)
249
                {
250
                    void* buf = memalign(0x10, size);
251
                    if (buf)
252
                    {
253
                        bootflash_read("rockbox ", buf, 0, size);
254
                        if (bootflash_attributes("rockbox ") & 0x800)
255
                        {
256
                            void* buf2 = malloc(0x100000);
257
                            if (buf2)
258
                            {
259
                                if (!ucl_decompress(buf, size, buf2, (uint32_t*)&size))
260
                                {
261
                                    free(buf);
262
                                    buf = realloc(buf2, size);
263
                                    if (!buf) buf = buf2;
264
                                    if (!boot->verify_rockbox_checksum(buf, size))
265
                                        firmware = buf;
266
                                    else free(buf);
267
                                }
268
                                else
269
                                {
270
                                    free(buf2);
271
                                    free(buf);
272
                                }
273
                            }
274
                            else free(buf);
275
                        }
276
                        else
277
                        {
278
                            if (!boot->verify_rockbox_checksum(buf, size)) firmware = buf;
279
                            else free(buf);
280
                        }
281
                    }
282
                }
283
            }
284
            if (!firmware)
285
            {
286
                memcpy(framebuf, bg, 320 * 240 * 3);
287
                rendertext(framebuf, 91, 140, 320, 0xff3333ff, 0xa0000000, "Loading Rockbox failed!");
288
                rendertext(framebuf, 91, 148, 320, 0xff3333ff, 0xa0000000, "Returning to main menu.");
289
                displaylcd(0, 0, 320, 240, framebuf, 0, 0, 320);
290
                sleep(5000000);
291
            }
292
            break;
293
        }
294
        case 2:
295
            goto leave;
296
        case 3:
297
            size = bootflash_filesize("umsboot ");
298
            if (size > 0)
299
            {
300
                void* buf = memalign(0x10, size);
301
                if (buf)
302
                {
303
                    bootflash_read("umsboot ", buf, 0, size);
304
                    if (bootflash_attributes("umsboot ") & 0x800)
305
                    {
306
                        void* buf2 = malloc(0x10000);
307
                        if (buf2)
308
                        {
309
                            if (!ucl_decompress(buf, size, buf2, (uint32_t*)&size))
310
                            {
311
                                free(buf);
312
                                buf = realloc(buf2, size);
313
                                if (!buf) buf = buf2;
314
                                firmware = buf;
315
                            }
316
                            else
317
                            {
318
                                free(buf2);
319
                                free(buf);
320
                            }
321
                        }
322
                        else free(buf);
323
                    }
324
                    else firmware = buf;
325
                }
326
            }
327
            if (!firmware)
328
            {
329
                memcpy(framebuf, bg, 320 * 240 * 3);
330
                rendertext(framebuf, 91, 140, 320, 0xff3333ff, 0xa0000000, "Loading UMSboot failed!");
331
                rendertext(framebuf, 91, 148, 320, 0xff3333ff, 0xa0000000, "Returning to main menu.");
332
                displaylcd(0, 0, 320, 240, framebuf, 0, 0, 320);
333
                sleep(5000000);
334
            }
335
            break;
336
        }
337
    }
338
leave:
339
    free(framebuf);
340
    free(rbxlogo);
341
    free(icons);
342
    free(bg);
343
    release_library(libui);
344
    library_unload(libui);
345
    release_library(libpng);
346
    library_unload(libpng);
347
    release_library(libboot);
348
    library_unload(libboot);
349
    if (firmware)
350
    {
351
        shutdown(false);
352
        execfirmware((void*)0x08000000, firmware, size);
353
    }
354
    else cputs(3, "Dropped into emCORE console.\n");
355
}
356
 
357
 
358
EMCORE_APP_HEADER("Boot menu", main, 127)