random fixes (root path and mmap svp tcache)
[libpicofe.git] / 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
90         gp2x_memcpy_buffers((1<<2), g_screen_ptr, 0, 320*240*2);
91
92         // switch to 16bpp
93         gp2x_video_changemode_ll(16);
94         gp2x_video_RGB_setscaling(0, 320, 240);
95         gp2x_video_flip2();
96 }
97
98 void plat_video_menu_begin(void)
99 {
100         memcpy(g_screen_ptr, gp2x_screens[2], 320*240*2);
101 }
102
103 void plat_video_menu_end(void)
104 {
105         // FIXME
106         // gp2x_video_flush_cache();
107         gp2x_video_flip2();
108 }
109
110 void plat_validate_config(void)
111 {
112         gp2x_soc_t soc;
113
114         soc = soc_detect();
115         if (soc != SOCID_MMSP2)
116                 PicoOpt &= ~POPT_EXT_FM;
117
118         if (currentConfig.gamma < 10 || currentConfig.gamma > 300)
119                 currentConfig.gamma = 100;
120
121         if (currentConfig.CPUclock < 10 || currentConfig.CPUclock > 1024)
122                 currentConfig.CPUclock = default_cpu_clock;
123 }
124
125 void plat_early_init(void)
126 {
127         gp2x_soc_t soc;
128
129         soc = soc_detect();
130         switch (soc)
131         {
132         case SOCID_MMSP2:
133                 default_cpu_clock = 200;
134                 break;
135         case SOCID_POLLUX:
136                 strcpy(cpu_clk_name, "Wiz CPU clock");
137                 default_cpu_clock = 533;
138                 break;
139         default:
140                 fprintf(stderr, "could not recognize SoC, bailing out.\n");
141                 exit(1);
142         }
143 }
144
145 void plat_init(void)
146 {
147         gp2x_soc_t soc;
148
149         soc = soc_detect();
150         switch (soc)
151         {
152         case SOCID_MMSP2:
153                 mmsp2_init();
154                 break;
155         case SOCID_POLLUX:
156                 pollux_init();
157                 menu_plat_setup(1);
158                 break;
159         default:
160                 break;
161         }
162
163         warm_init();
164
165         gp2x_memset_all_buffers(0, 0, 320*240*2);
166
167         // snd
168         sndout_oss_init();
169 }
170
171 void plat_finish(void)
172 {
173         gp2x_soc_t soc;
174
175         warm_finish();
176
177         soc = soc_detect();
178         switch (soc)
179         {
180         case SOCID_MMSP2:
181                 mmsp2_finish();
182                 break;
183         case SOCID_POLLUX:
184                 pollux_finish();
185                 break;
186         }
187
188         sndout_oss_exit();
189 }
190
191 void lprintf(const char *fmt, ...)
192 {
193         va_list vl;
194
195         va_start(vl, fmt);
196         vprintf(fmt, vl);
197         va_end(vl);
198 }
199