bugfix
[picodrive.git] / platform / gp2x / plat.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <stdarg.h>
5
6 #include "plat_gp2x.h"
7 #include "soc.h"
8 #include "warm.h"
9 #include "../common/plat.h"
10 #include "../common/readpng.h"
11 #include "../common/menu.h"
12 #include "../common/emu.h"
13 #include "../linux/sndout_oss.h"
14
15 #include <pico/pico.h>
16
17 /* GP2X local */
18 int default_cpu_clock;
19 void *gp2x_screens[4];
20
21 void gp2x_video_changemode(int bpp)
22 {
23         gp2x_video_changemode_ll(bpp);
24
25         gp2x_memset_all_buffers(0, 0, 320*240*2);
26         gp2x_video_flip();
27 }
28
29 static void gp2x_memcpy_buffers(int buffers, void *data, int offset, int len)
30 {
31         char *dst;
32         if (buffers & (1<<0)) { dst = (char *)gp2x_screens[0] + offset; if (dst != data) memcpy(dst, data, len); }
33         if (buffers & (1<<1)) { dst = (char *)gp2x_screens[1] + offset; if (dst != data) memcpy(dst, data, len); }
34         if (buffers & (1<<2)) { dst = (char *)gp2x_screens[2] + offset; if (dst != data) memcpy(dst, data, len); }
35         if (buffers & (1<<3)) { dst = (char *)gp2x_screens[3] + offset; if (dst != data) memcpy(dst, data, len); }
36 }
37
38 void gp2x_memcpy_all_buffers(void *data, int offset, int len)
39 {
40         gp2x_memcpy_buffers(0xf, data, offset, len);
41 }
42
43 void gp2x_memset_all_buffers(int offset, int byte, int len)
44 {
45         memset((char *)gp2x_screens[0] + offset, byte, len);
46         memset((char *)gp2x_screens[1] + offset, byte, len);
47         memset((char *)gp2x_screens[2] + offset, byte, len);
48         memset((char *)gp2x_screens[3] + offset, byte, len);
49 }
50
51 void gp2x_make_fb_bufferable(int yes)
52 {
53         int ret = 0;
54         
55         yes = yes ? 1 : 0;
56         ret |= warm_change_cb_range(WCB_B_BIT, yes, gp2x_screens[0], 320*240*2);
57         ret |= warm_change_cb_range(WCB_B_BIT, yes, gp2x_screens[1], 320*240*2);
58         ret |= warm_change_cb_range(WCB_B_BIT, yes, gp2x_screens[2], 320*240*2);
59         ret |= warm_change_cb_range(WCB_B_BIT, yes, gp2x_screens[3], 320*240*2);
60
61         if (ret)
62                 fprintf(stderr, "could not make fb buferable.\n");
63         else
64                 printf("made fb buferable.\n");
65 }
66
67 /* common */
68 char cpu_clk_name[16] = "GP2X CPU clocks";
69
70 void plat_video_menu_enter(int is_rom_loaded)
71 {
72         if (is_rom_loaded)
73         {
74                 // darken the active framebuffer
75                 memset(g_screen_ptr, 0, 320*8*2);
76                 menu_darken_bg((char *)g_screen_ptr + 320*8*2, 320*224, 1);
77                 memset((char *)g_screen_ptr + 320*232*2, 0, 320*8*2);
78         }
79         else
80         {
81                 char buff[256];
82
83                 // should really only happen once, on startup..
84                 emu_make_path(buff, "skin/background.png", sizeof(buff));
85                 if (readpng(g_screen_ptr, buff, READPNG_BG) < 0)
86                         memset(g_screen_ptr, 0, 320*240*2);
87         }
88
89         // copy to buffer2, switch to black
90         gp2x_memcpy_buffers((1<<2), g_screen_ptr, 0, 320*240*2);
91
92         /* try to switch nicely avoiding tearing on Wiz */
93         gp2x_video_wait_vsync();
94         memset(gp2x_screens[0], 0, 320*240*2);
95         memset(gp2x_screens[1], 0, 320*240*2);
96         gp2x_video_flip2();
97         gp2x_video_wait_vsync();
98         gp2x_video_wait_vsync();
99
100         // switch to 16bpp
101         gp2x_video_changemode_ll(16);
102         gp2x_video_RGB_setscaling(0, 320, 240);
103 }
104
105 void plat_video_menu_begin(void)
106 {
107         memcpy(g_screen_ptr, gp2x_screens[2], 320*240*2);
108 }
109
110 void plat_video_menu_end(void)
111 {
112         // FIXME
113         // gp2x_video_flush_cache();
114         gp2x_video_flip2();
115 }
116
117 void plat_validate_config(void)
118 {
119         gp2x_soc_t soc;
120
121         soc = soc_detect();
122         if (soc != SOCID_MMSP2)
123                 PicoOpt &= ~POPT_EXT_FM;
124         if (soc != SOCID_POLLUX)
125                 currentConfig.EmuOpt &= ~EOPT_WIZ_TEAR_FIX;
126
127         if (currentConfig.gamma < 10 || currentConfig.gamma > 300)
128                 currentConfig.gamma = 100;
129
130         if (currentConfig.CPUclock < 10 || currentConfig.CPUclock > 1024)
131                 currentConfig.CPUclock = default_cpu_clock;
132 }
133
134 void plat_early_init(void)
135 {
136         gp2x_soc_t soc;
137
138         soc = soc_detect();
139         switch (soc)
140         {
141         case SOCID_MMSP2:
142                 default_cpu_clock = 200;
143                 break;
144         case SOCID_POLLUX:
145                 strcpy(cpu_clk_name, "Wiz CPU clock");
146                 default_cpu_clock = 533;
147                 break;
148         default:
149                 fprintf(stderr, "could not recognize SoC, bailing out.\n");
150                 exit(1);
151         }
152 }
153
154 void 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                 menu_plat_setup(0);
164                 break;
165         case SOCID_POLLUX:
166                 pollux_init();
167                 menu_plat_setup(1);
168                 break;
169         default:
170                 break;
171         }
172
173         warm_init();
174
175         gp2x_memset_all_buffers(0, 0, 320*240*2);
176
177         // snd
178         sndout_oss_init();
179 }
180
181 void plat_finish(void)
182 {
183         gp2x_soc_t soc;
184
185         warm_finish();
186
187         soc = soc_detect();
188         switch (soc)
189         {
190         case SOCID_MMSP2:
191                 mmsp2_finish();
192                 break;
193         case SOCID_POLLUX:
194                 pollux_finish();
195                 break;
196         }
197
198         sndout_oss_exit();
199 }
200
201 void lprintf(const char *fmt, ...)
202 {
203         va_list vl;
204
205         va_start(vl, fmt);
206         vprintf(fmt, vl);
207         va_end(vl);
208 }
209