tweak and refactor frontends, menu and config
[libpicofe.git] / gp2x / plat.c
CommitLineData
d572cbad 1#include <stdio.h>
2#include <stdlib.h>
24b24674 3#include <string.h>
d572cbad 4#include <stdarg.h>
24b24674 5
fa5e045b 6#include "plat_gp2x.h"
d572cbad 7#include "soc.h"
fa5e045b 8#include "warm.h"
24b24674 9#include "../common/plat.h"
10#include "../common/readpng.h"
11#include "../common/menu.h"
e31266dd 12#include "../common/emu.h"
902972d1 13#include "../common/input.h"
d572cbad 14#include "../linux/sndout_oss.h"
24b24674 15
fa8d1331 16#include <pico/pico.h>
17
d572cbad 18/* GP2X local */
fa5e045b 19int default_cpu_clock;
b6072c17 20int gp2x_dev_id;
21int gp2x_current_bpp;
d572cbad 22void *gp2x_screens[4];
23
902972d1 24#include <linux/input.h>
25
26static const char * const caanoo_keys[KEY_MAX + 1] = {
27 [0 ... KEY_MAX] = NULL,
28 [KEY_UP] = "Up",
29 [KEY_LEFT] = "Left",
30 [KEY_RIGHT] = "Right",
31 [KEY_DOWN] = "Down",
32 [BTN_TRIGGER] = "A",
33 [BTN_THUMB] = "X",
34 [BTN_THUMB2] = "B",
35 [BTN_TOP] = "Y",
36 [BTN_TOP2] = "L",
37 [BTN_PINKIE] = "R",
38 [BTN_BASE] = "Home",
39 [BTN_BASE2] = "Lock",
40 [BTN_BASE3] = "I",
41 [BTN_BASE4] = "II",
42 [BTN_BASE5] = "Push",
43};
44
d572cbad 45void gp2x_video_changemode(int bpp)
46{
47 gp2x_video_changemode_ll(bpp);
48
b6072c17 49 gp2x_current_bpp = bpp < 0 ? -bpp : bpp;
d572cbad 50}
51
52static void gp2x_memcpy_buffers(int buffers, void *data, int offset, int len)
53{
54 char *dst;
55 if (buffers & (1<<0)) { dst = (char *)gp2x_screens[0] + offset; if (dst != data) memcpy(dst, data, len); }
56 if (buffers & (1<<1)) { dst = (char *)gp2x_screens[1] + offset; if (dst != data) memcpy(dst, data, len); }
57 if (buffers & (1<<2)) { dst = (char *)gp2x_screens[2] + offset; if (dst != data) memcpy(dst, data, len); }
58 if (buffers & (1<<3)) { dst = (char *)gp2x_screens[3] + offset; if (dst != data) memcpy(dst, data, len); }
59}
60
61void gp2x_memcpy_all_buffers(void *data, int offset, int len)
62{
63 gp2x_memcpy_buffers(0xf, data, offset, len);
64}
65
66void gp2x_memset_all_buffers(int offset, int byte, int len)
67{
68 memset((char *)gp2x_screens[0] + offset, byte, len);
69 memset((char *)gp2x_screens[1] + offset, byte, len);
70 memset((char *)gp2x_screens[2] + offset, byte, len);
71 memset((char *)gp2x_screens[3] + offset, byte, len);
72}
73
fa5e045b 74void gp2x_make_fb_bufferable(int yes)
75{
76 int ret = 0;
77
78 yes = yes ? 1 : 0;
79 ret |= warm_change_cb_range(WCB_B_BIT, yes, gp2x_screens[0], 320*240*2);
80 ret |= warm_change_cb_range(WCB_B_BIT, yes, gp2x_screens[1], 320*240*2);
81 ret |= warm_change_cb_range(WCB_B_BIT, yes, gp2x_screens[2], 320*240*2);
82 ret |= warm_change_cb_range(WCB_B_BIT, yes, gp2x_screens[3], 320*240*2);
83
84 if (ret)
85 fprintf(stderr, "could not make fb buferable.\n");
86 else
87 printf("made fb buferable.\n");
88}
89
d572cbad 90/* common */
24b24674 91void plat_video_menu_enter(int is_rom_loaded)
92{
b6072c17 93 if (gp2x_current_bpp != 16 || gp2x_dev_id == GP2X_DEV_WIZ) {
94 /* try to switch nicely avoiding glitches */
95 gp2x_video_wait_vsync();
96 memset(gp2x_screens[0], 0, 320*240*2);
97 memset(gp2x_screens[1], 0, 320*240*2);
98 gp2x_video_flip2(); // might flip to fb2/3
99 gp2x_video_flip2(); // ..so we do it again
b6072c17 100 }
902972d1 101 else
102 gp2x_video_flip2();
b7911801 103
24b24674 104 // switch to 16bpp
d572cbad 105 gp2x_video_changemode_ll(16);
24b24674 106 gp2x_video_RGB_setscaling(0, 320, 240);
24b24674 107}
108
109void plat_video_menu_begin(void)
110{
c66f49e6 111 g_menuscreen_ptr = g_screen_ptr;
24b24674 112}
113
114void plat_video_menu_end(void)
115{
24b24674 116 gp2x_video_flip2();
117}
118
fa8d1331 119void plat_early_init(void)
d572cbad 120{
121 gp2x_soc_t soc;
b6072c17 122 FILE *f;
d572cbad 123
124 soc = soc_detect();
125 switch (soc)
126 {
127 case SOCID_MMSP2:
fa5e045b 128 default_cpu_clock = 200;
b6072c17 129 gp2x_dev_id = GP2X_DEV_GP2X;
d572cbad 130 break;
131 case SOCID_POLLUX:
fa5e045b 132 default_cpu_clock = 533;
b6072c17 133 f = fopen("/dev/accel", "rb");
134 if (f) {
135 printf("detected Caanoo\n");
136 gp2x_dev_id = GP2X_DEV_CAANOO;
137 fclose(f);
138 }
139 else {
140 printf("detected Wiz\n");
141 gp2x_dev_id = GP2X_DEV_WIZ;
142 }
d572cbad 143 break;
144 default:
1eb704b6 145 printf("could not recognize SoC, running in dummy mode.\n");
146 break;
d572cbad 147 }
b6072c17 148
902972d1 149 // just use gettimeofday until plat_init()
150 gp2x_get_ticks_ms = plat_get_ticks_ms_good;
151 gp2x_get_ticks_us = plat_get_ticks_us_good;
fa8d1331 152}
153
154void plat_init(void)
155{
156 gp2x_soc_t soc;
157
158 soc = soc_detect();
159 switch (soc)
160 {
161 case SOCID_MMSP2:
162 mmsp2_init();
163 break;
164 case SOCID_POLLUX:
165 pollux_init();
fa8d1331 166 break;
167 default:
1eb704b6 168 dummy_init();
fa8d1331 169 break;
170 }
d572cbad 171
fa5e045b 172 warm_init();
173
d572cbad 174 gp2x_memset_all_buffers(0, 0, 320*240*2);
175
114dfebd 176 // use buffer2 for menubg to save mem (using only buffers 0, 1 in menu)
d2f29611 177 g_menubg_ptr = gp2x_screens[2];
178
d572cbad 179 // snd
180 sndout_oss_init();
902972d1 181
182 if (gp2x_dev_id == GP2X_DEV_CAANOO)
183 in_set_config(in_name_to_id("evdev:pollux-analog"), IN_CFG_KEY_NAMES,
184 caanoo_keys, sizeof(caanoo_keys));
185
186 gp2x_menu_init();
d572cbad 187}
188
189void plat_finish(void)
190{
fa5e045b 191 gp2x_soc_t soc;
192
193 warm_finish();
194
195 soc = soc_detect();
196 switch (soc)
d572cbad 197 {
198 case SOCID_MMSP2:
199 mmsp2_finish();
200 break;
201 case SOCID_POLLUX:
202 pollux_finish();
203 break;
1eb704b6 204 default:
205 dummy_finish();
206 break;
d572cbad 207 }
208
d572cbad 209 sndout_oss_exit();
210}
211
212void lprintf(const char *fmt, ...)
213{
214 va_list vl;
215
216 va_start(vl, fmt);
217 vprintf(fmt, vl);
218 va_end(vl);
219}
220