Subversion Repositories freemyipod

Rev

Rev 528 | Rev 651 | Go to most recent revision | Details | Compare with Previous | 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;
551 theseven 215
            for (i = 1; i <= 96; i += 19)
528 theseven 216
            {
551 theseven 217
                if (i < 96)
528 theseven 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);
551 theseven 221
                ui->blit(280, MIN(86, i), 3, framebuf, 20, MAX(0, i - 86), 320,
222
                         rbxlogo, 0, MAX(0, 86 - i), 280);
528 theseven 223
                displaylcd(0, 0, 320, 240, framebuf, 0, 0, 320);
224
            }
225
            int fd = file_open("/.rockbox/rockbox.ipod", O_RDONLY);
226
            if (fd > 0)
227
            {
228
                size = filesize(fd);
229
                if (size > 0)
230
                {
231
                    void* buf = memalign(0x10, size);
232
                    if (buf)
233
                    {
234
                        if (read(fd, buf, size) == size)
235
                            if (!boot->verify_rockbox_checksum(buf, size))
236
                                firmware = buf;
237
                        if (!firmware) free(buf);
238
                    }
239
                }
240
                close(fd);
241
            }
242
            if (!firmware)
243
            {
244
                rendertext(framebuf, 76, 140, 320, 0xff3333ff, 0xa0000000, "Loading rockbox.ipod failed!");
245
                rendertext(framebuf, 76, 148, 320, 0xff3333ff, 0xa0000000, "  Trying fallback image...  ");
246
                displaylcd(0, 0, 320, 240, framebuf, 0, 0, 320);
247
                sleep(5000000);
248
                size = bootflash_filesize("rockbox ");
249
                if (size > 0)
250
                {
251
                    void* buf = memalign(0x10, size);
252
                    if (buf)
253
                    {
254
                        bootflash_read("rockbox ", buf, 0, size);
255
                        if (bootflash_attributes("rockbox ") & 0x800)
256
                        {
257
                            void* buf2 = malloc(0x100000);
258
                            if (buf2)
259
                            {
260
                                if (!ucl_decompress(buf, size, buf2, (uint32_t*)&size))
261
                                {
262
                                    free(buf);
263
                                    buf = realloc(buf2, size);
264
                                    if (!buf) buf = buf2;
265
                                    if (!boot->verify_rockbox_checksum(buf, size))
266
                                        firmware = buf;
267
                                    else free(buf);
268
                                }
269
                                else
270
                                {
271
                                    free(buf2);
272
                                    free(buf);
273
                                }
274
                            }
275
                            else free(buf);
276
                        }
277
                        else
278
                        {
279
                            if (!boot->verify_rockbox_checksum(buf, size)) firmware = buf;
280
                            else free(buf);
281
                        }
282
                    }
283
                }
284
            }
285
            if (!firmware)
286
            {
287
                memcpy(framebuf, bg, 320 * 240 * 3);
288
                rendertext(framebuf, 91, 140, 320, 0xff3333ff, 0xa0000000, "Loading Rockbox failed!");
289
                rendertext(framebuf, 91, 148, 320, 0xff3333ff, 0xa0000000, "Returning to main menu.");
290
                displaylcd(0, 0, 320, 240, framebuf, 0, 0, 320);
291
                sleep(5000000);
292
            }
293
            break;
294
        }
295
        case 2:
296
            goto leave;
297
        case 3:
298
            size = bootflash_filesize("umsboot ");
299
            if (size > 0)
300
            {
301
                void* buf = memalign(0x10, size);
302
                if (buf)
303
                {
304
                    bootflash_read("umsboot ", buf, 0, size);
305
                    if (bootflash_attributes("umsboot ") & 0x800)
306
                    {
307
                        void* buf2 = malloc(0x10000);
308
                        if (buf2)
309
                        {
310
                            if (!ucl_decompress(buf, size, buf2, (uint32_t*)&size))
311
                            {
312
                                free(buf);
313
                                buf = realloc(buf2, size);
314
                                if (!buf) buf = buf2;
315
                                firmware = buf;
316
                            }
317
                            else
318
                            {
319
                                free(buf2);
320
                                free(buf);
321
                            }
322
                        }
323
                        else free(buf);
324
                    }
325
                    else firmware = buf;
326
                }
327
            }
328
            if (!firmware)
329
            {
330
                memcpy(framebuf, bg, 320 * 240 * 3);
331
                rendertext(framebuf, 91, 140, 320, 0xff3333ff, 0xa0000000, "Loading UMSboot failed!");
332
                rendertext(framebuf, 91, 148, 320, 0xff3333ff, 0xa0000000, "Returning to main menu.");
333
                displaylcd(0, 0, 320, 240, framebuf, 0, 0, 320);
334
                sleep(5000000);
335
            }
336
            break;
337
        }
338
    }
339
leave:
340
    free(framebuf);
341
    free(rbxlogo);
342
    free(icons);
343
    free(bg);
344
    release_library(libui);
551 theseven 345
    release_library(libpng);
346
    release_library(libboot);
528 theseven 347
    library_unload(libui);
348
    library_unload(libpng);
349
    library_unload(libboot);
350
    if (firmware)
351
    {
352
        shutdown(false);
353
        execfirmware((void*)0x08000000, firmware, size);
354
    }
355
    else cputs(3, "Dropped into emCORE console.\n");
356
}
357
 
358
 
359
EMCORE_APP_HEADER("Boot menu", main, 127)