1 // (c) Copyright 2006,2007 notaz, All rights reserved.
\r
2 // Free for non-commercial use.
\r
4 // For commercial use, separate licencing terms must be obtained.
\r
13 #include "readpng.h"
\r
14 #include "lprintf.h"
\r
16 #if defined(__GP2X__)
\r
17 #include "../gp2x/gp2x.h"
\r
18 #define SCREEN_WIDTH 320
\r
19 #define SCREEN_BUFFER gp2x_screen
\r
20 #elif defined(__GIZ__)
\r
21 //#include "../gizmondo/giz.h"
\r
22 #define SCREEN_WIDTH 321
\r
23 #define SCREEN_BUFFER menu_screen
\r
24 extern unsigned char *menu_screen;
\r
27 char menuErrorMsg[64] = { 0, };
\r
29 static unsigned char menu_font_data[10240];
\r
30 static int menu_text_color = 0xffff; // default to white
\r
31 static int menu_sel_color = -1; // disabled
\r
33 // draws text to current bbp16 screen
\r
34 static void text_out16_(int x, int y, const char *text, int color)
\r
36 int i, l, u, tr, tg, tb, len;
\r
37 unsigned short *dest = (unsigned short *)SCREEN_BUFFER + x + y*SCREEN_WIDTH;
\r
38 tr = (color & 0xf800) >> 8;
\r
39 tg = (color & 0x07e0) >> 3;
\r
40 tb = (color & 0x001f) << 3;
\r
42 if (text == (void *)1)
\r
51 for (i = 0; i < len; i++)
\r
53 unsigned char *src = menu_font_data + (unsigned int)text[i]*4*10;
\r
54 unsigned short *dst = dest;
\r
55 for (l = 0; l < 10; l++, dst += SCREEN_WIDTH-8)
\r
57 for (u = 8/2; u > 0; u--, src++)
\r
61 r = (*dst & 0xf800) >> 8;
\r
62 g = (*dst & 0x07e0) >> 3;
\r
63 b = (*dst & 0x001f) << 3;
\r
64 r = (c^0xf)*r/15 + c*tr/15;
\r
65 g = (c^0xf)*g/15 + c*tg/15;
\r
66 b = (c^0xf)*b/15 + c*tb/15;
\r
67 *dst++ = ((r<<8)&0xf800) | ((g<<3)&0x07e0) | (b>>3);
\r
69 r = (*dst & 0xf800) >> 8;
\r
70 g = (*dst & 0x07e0) >> 3;
\r
71 b = (*dst & 0x001f) << 3;
\r
72 r = (c^0xf)*r/15 + c*tr/15;
\r
73 g = (c^0xf)*g/15 + c*tg/15;
\r
74 b = (c^0xf)*b/15 + c*tb/15;
\r
75 *dst++ = ((r<<8)&0xf800) | ((g<<3)&0x07e0) | (b>>3);
\r
82 void text_out16(int x, int y, const char *texto, ...)
\r
87 va_start(args,texto);
\r
88 vsprintf(buffer,texto,args);
\r
91 text_out16_(x,y,buffer,menu_text_color);
\r
95 void smalltext_out16(int x, int y, const char *texto, int color)
\r
99 unsigned short *dst;
\r
101 for (i = 0;; i++, x += 6)
\r
103 unsigned char c = (unsigned char) texto[i];
\r
108 src = fontdata6x8[c];
\r
109 dst = (unsigned short *)SCREEN_BUFFER + x + y*SCREEN_WIDTH;
\r
116 if( *src & w ) *dst = color;
\r
122 dst += SCREEN_WIDTH-6;
\r
127 void smalltext_out16_lim(int x, int y, const char *texto, int color, int max)
\r
129 char buffer[SCREEN_WIDTH/6+1];
\r
131 strncpy(buffer, texto, SCREEN_WIDTH/6);
\r
132 if (max > SCREEN_WIDTH/6) max = SCREEN_WIDTH/6;
\r
133 if (max < 0) max = 0;
\r
136 smalltext_out16(x, y, buffer, color);
\r
139 void menu_draw_selection(int x, int y, int w)
\r
142 unsigned short *dst, *dest;
\r
144 text_out16_(x, y, (void *)1, (menu_sel_color < 0) ? menu_text_color : menu_sel_color);
\r
146 if (menu_sel_color < 0) return; // no selection hilight
\r
149 dest = (unsigned short *)SCREEN_BUFFER + x + y*SCREEN_WIDTH + 14;
\r
150 for (h = 11; h > 0; h--)
\r
153 for (i = w; i > 0; i--)
\r
154 *dst++ = menu_sel_color;
\r
155 dest += SCREEN_WIDTH;
\r
159 static int parse_hex_color(char *buff)
\r
162 int t = (int) strtoul(buff, &endp, 16);
\r
163 if (endp != buff) return ((t>>8)&0xf800) | ((t>>5)&0x07e0) | ((t>>3)&0x1f);
\r
167 void menu_init(void)
\r
170 unsigned char *fd = menu_font_data;
\r
174 // generate default font from fontdata8x8
\r
175 memset(menu_font_data, 0, sizeof(menu_font_data));
\r
176 for (c = 0; c < 256; c++)
\r
178 for (l = 0; l < 8; l++)
\r
180 unsigned char fd8x8 = fontdata8x8[c*8+l];
\r
181 if (fd8x8&0x80) *fd |= 0xf0;
\r
182 if (fd8x8&0x40) *fd |= 0x0f; fd++;
\r
183 if (fd8x8&0x20) *fd |= 0xf0;
\r
184 if (fd8x8&0x10) *fd |= 0x0f; fd++;
\r
185 if (fd8x8&0x08) *fd |= 0xf0;
\r
186 if (fd8x8&0x04) *fd |= 0x0f; fd++;
\r
187 if (fd8x8&0x02) *fd |= 0xf0;
\r
188 if (fd8x8&0x01) *fd |= 0x0f; fd++;
\r
190 fd += 8*2/2; // 2 empty lines
\r
193 // load custom font and selector (stored as 1st symbol in font table)
\r
194 readpng(menu_font_data, "skin/font.png", READPNG_FONT);
\r
195 memcpy(menu_font_data, menu_font_data + ((int)'>')*4*10, 4*10); // default selector symbol is '>'
\r
196 readpng(menu_font_data, "skin/selector.png", READPNG_SELECTOR);
\r
198 // load custom colors
\r
199 f = fopen("skin/skin.txt", "r");
\r
202 lprintf("found skin.txt\n");
\r
205 fgets(buff, sizeof(buff), f);
\r
206 if (buff[0] == '#' || buff[0] == '/') continue; // comment
\r
207 if (buff[0] == '\r' || buff[0] == '\n') continue; // empty line
\r
208 if (strncmp(buff, "text_color=", 11) == 0)
\r
210 int tmp = parse_hex_color(buff+11);
\r
211 if (tmp >= 0) menu_text_color = tmp;
\r
212 else lprintf("skin.txt: parse error for text_color\n");
\r
214 else if (strncmp(buff, "selection_color=", 16) == 0)
\r
216 int tmp = parse_hex_color(buff+16);
\r
217 if (tmp >= 0) menu_sel_color = tmp;
\r
218 else lprintf("skin.txt: parse error for selection_color\n");
\r
221 lprintf("skin.txt: parse error: %s\n", buff);
\r
228 int me_id2offset(const menu_entry *entries, int count, menu_id id)
\r
231 for (i = 0; i < count; i++)
\r
233 if (entries[i].id == id) return i;
\r
236 lprintf("%s: id %i not found\n", __FUNCTION__, id);
\r
240 void me_enable(menu_entry *entries, int count, menu_id id, int enable)
\r
242 int i = me_id2offset(entries, count, id);
\r
243 entries[i].enabled = enable;
\r
246 int me_count_enabled(const menu_entry *entries, int count)
\r
250 for (i = 0; i < count; i++)
\r
252 if (entries[i].enabled) ret++;
\r
258 menu_id me_index2id(const menu_entry *entries, int count, int index)
\r
262 for (i = 0; i < count; i++)
\r
264 if (entries[i].enabled)
\r
266 if (index == 0) break;
\r
270 if (i >= count) i = count - 1;
\r
271 return entries[i].id;
\r
274 void me_draw(const menu_entry *entries, int count, int x, int y, me_draw_custom_f *cust_draw, void *param)
\r
278 for (i = 0; i < count; i++)
\r
280 if (!entries[i].enabled) continue;
\r
281 if (entries[i].name == NULL)
\r
283 if (cust_draw != NULL)
\r
284 cust_draw(&entries[i], x, y1, param);
\r
288 text_out16(x, y1, entries[i].name);
\r
289 if (entries[i].beh == MB_ONOFF)
\r
290 text_out16(x + 27*8, y1, (*(int *)entries[i].var & entries[i].mask) ? "ON" : "OFF");
\r
291 else if (entries[i].beh == MB_RANGE)
\r
292 text_out16(x + 27*8, y1, "%i", *(int *)entries[i].var);
\r
297 int me_process(menu_entry *entries, int count, menu_id id, int is_next)
\r
299 int i = me_id2offset(entries, count, id);
\r
300 menu_entry *entry = &entries[i];
\r
301 switch (entry->beh)
\r
304 *(int *)entry->var ^= entry->mask;
\r
307 *(int *)entry->var += is_next ? 1 : -1;
\r
308 if (*(int *)entry->var < (int)entry->min) *(int *)entry->var = (int)entry->min;
\r
309 if (*(int *)entry->var > (int)entry->max) *(int *)entry->var = (int)entry->max;
\r