load state ability from command line
[libpicofe.git] / pandora / pandora.c
1 \r
2 #include <stdio.h>\r
3 #include <stdlib.h>\r
4 #include <stdarg.h>\r
5 #include <string.h>\r
6 #include <unistd.h>\r
7 #include <sys/mman.h>\r
8 #include <sys/types.h>\r
9 #include <sys/stat.h>\r
10 #include <sys/ioctl.h>\r
11 #include <sys/soundcard.h>\r
12 #include <linux/fb.h>\r
13 #include <fcntl.h>\r
14 #include <errno.h>\r
15 \r
16 #include "../gp2x/gp2x.h"\r
17 #include "../gp2x/usbjoy.h"\r
18 #include "../common/arm_utils.h"\r
19 \r
20 static volatile unsigned int *memregs = MAP_FAILED;\r
21 //static\r
22 int memdev = 0;\r
23 static int fbdev = -1, sounddev = -1, mixerdev = -1, touchdev = -1;\r
24 static int touchcal[7] = { 6203, 0, -1501397, 0, -4200, 16132680, 65536 };\r
25 \r
26 //#define SCREEN_MAP_SIZE (((800*(480+11)*2)+0xfff)&~0xfff)\r
27 #define SCREEN_MAP_SIZE (800*480*2)\r
28 static void *screen = MAP_FAILED;\r
29 void *gp2x_screen;\r
30 \r
31 \r
32 /* video stuff */\r
33 void gp2x_video_flip(void)\r
34 {\r
35 }\r
36 \r
37 /* doulblebuffered flip */\r
38 void gp2x_video_flip2(void)\r
39 {\r
40 }\r
41 \r
42 \r
43 void gp2x_video_changemode2(int bpp)\r
44 {\r
45 }\r
46 \r
47 \r
48 void gp2x_video_changemode(int bpp)\r
49 {\r
50 }\r
51 \r
52 \r
53 void gp2x_video_setpalette(int *pal, int len)\r
54 {\r
55 }\r
56 \r
57 \r
58 void gp2x_video_RGB_setscaling(int ln_offs, int W, int H)\r
59 {\r
60 }\r
61 \r
62 \r
63 void gp2x_video_wait_vsync(void)\r
64 {\r
65 }\r
66 \r
67 \r
68 void gp2x_video_flush_cache(void)\r
69 {\r
70 //      flushcache(gp2x_screen, (char *)gp2x_screen + 320*240*2, 0);\r
71 }\r
72 \r
73 \r
74 void gp2x_memcpy_buffers(int buffers, void *data, int offset, int len)\r
75 {\r
76 }\r
77 \r
78 \r
79 void gp2x_memcpy_all_buffers(void *data, int offset, int len)\r
80 {\r
81 }\r
82 \r
83 \r
84 void gp2x_memset_all_buffers(int offset, int byte, int len)\r
85 {\r
86         memset((char *)gp2x_screen + offset, byte, len);\r
87 }\r
88 \r
89 \r
90 void gp2x_pd_clone_buffer2(void)\r
91 {\r
92 }\r
93 \r
94 \r
95 unsigned long gp2x_joystick_read(int allow_usb_joy)\r
96 {\r
97         unsigned long value = 0;\r
98         int i;\r
99 \r
100         if (allow_usb_joy && num_of_joys > 0) {\r
101                 // check the usb joy as well..\r
102                 gp2x_usbjoy_update();\r
103                 for (i = 0; i < num_of_joys; i++)\r
104                         value |= gp2x_usbjoy_check(i);\r
105         }\r
106 \r
107         return value;\r
108 }\r
109 \r
110 typedef struct ucb1x00_ts_event\r
111 {\r
112         unsigned short pressure;\r
113         unsigned short x;\r
114         unsigned short y;\r
115         unsigned short pad;\r
116         struct timeval stamp;\r
117 } UCB1X00_TS_EVENT;\r
118 \r
119 int gp2x_touchpad_read(int *x, int *y)\r
120 {\r
121         UCB1X00_TS_EVENT event;\r
122         static int zero_seen = 0;\r
123         int retval;\r
124 \r
125         if (touchdev < 0) return -1;\r
126 \r
127         retval = read(touchdev, &event, sizeof(event));\r
128         if (retval <= 0) {\r
129                 printf("touch read failed %i %i\n", retval, errno);\r
130                 return -1;\r
131         }\r
132         // this is to ignore the messed-up 4.1.x driver\r
133         if (event.pressure == 0) zero_seen = 1;\r
134 \r
135         if (x) *x = (event.x * touchcal[0] + touchcal[2]) >> 16;\r
136         if (y) *y = (event.y * touchcal[4] + touchcal[5]) >> 16;\r
137         // printf("read %i %i %i\n", event.pressure, *x, *y);\r
138 \r
139         return zero_seen ? event.pressure : 0;\r
140 }\r
141 \r
142 \r
143 //static int s_oldrate = 0, s_oldbits = 0, s_oldstereo = 0;\r
144 \r
145 void gp2x_start_sound(int rate, int bits, int stereo)\r
146 {\r
147 #if 0\r
148         int frag = 0, bsize, buffers;\r
149 \r
150         // if no settings change, we don't need to do anything\r
151         if (rate == s_oldrate && s_oldbits == bits && s_oldstereo == stereo) return;\r
152 \r
153         if (sounddev > 0) close(sounddev);\r
154         sounddev = open("/dev/dsp", O_WRONLY|O_ASYNC);\r
155         if (sounddev == -1)\r
156                 printf("open(\"/dev/dsp\") failed with %i\n", errno);\r
157 \r
158         ioctl(sounddev, SNDCTL_DSP_SETFMT, &bits);\r
159         ioctl(sounddev, SNDCTL_DSP_SPEED,  &rate);\r
160         ioctl(sounddev, SNDCTL_DSP_STEREO, &stereo);\r
161         // calculate buffer size\r
162         buffers = 16;\r
163         bsize = rate / 32;\r
164         if (rate > 22050) { bsize*=4; buffers*=2; } // 44k mode seems to be very demanding\r
165         while ((bsize>>=1)) frag++;\r
166         frag |= buffers<<16; // 16 buffers\r
167         ioctl(sounddev, SNDCTL_DSP_SETFRAGMENT, &frag);\r
168         usleep(192*1024);\r
169 \r
170         printf("gp2x_set_sound: %i/%ibit/%s, %i buffers of %i bytes\n",\r
171                 rate, bits, stereo?"stereo":"mono", frag>>16, 1<<(frag&0xffff));\r
172 \r
173         s_oldrate = rate; s_oldbits = bits; s_oldstereo = stereo;\r
174 #endif\r
175 }\r
176 \r
177 \r
178 void gp2x_sound_write(void *buff, int len)\r
179 {\r
180 //      write(sounddev, buff, len);\r
181 }\r
182 \r
183 void gp2x_sound_sync(void)\r
184 {\r
185 //      ioctl(sounddev, SOUND_PCM_SYNC, 0);\r
186 }\r
187 \r
188 void gp2x_sound_volume(int l, int r)\r
189 {\r
190 #if 0\r
191         l=l<0?0:l; l=l>255?255:l; r=r<0?0:r; r=r>255?255:r;\r
192         l<<=8; l|=r;\r
193         ioctl(mixerdev, SOUND_MIXER_WRITE_PCM, &l); /*SOUND_MIXER_WRITE_VOLUME*/\r
194 #endif\r
195 }\r
196 \r
197 \r
198 /* common */\r
199 void gp2x_init(void)\r
200 {\r
201         struct fb_fix_screeninfo fbfix;\r
202         int ret;\r
203 \r
204         printf("entering init()\n"); fflush(stdout);\r
205 \r
206         memdev = open("/dev/mem", O_RDWR);\r
207         if (memdev == -1)\r
208         {\r
209                 printf("open(\"/dev/mem\") failed with %i\n", errno);\r
210                 exit(1);\r
211         }\r
212 /*\r
213         memregs = mmap(0, 0x01000000, PROT_READ|PROT_WRITE, MAP_SHARED, memdev, 0x48000000);\r
214         if (memregs == MAP_FAILED)\r
215         {\r
216                 printf("mmap(memregs) failed with %i\n", errno);\r
217                 exit(1);\r
218         }\r
219 */\r
220         ret = ioctl(fbdev, FBIOGET_FSCREENINFO, &fbfix);\r
221         if (ret == -1)\r
222         {\r
223                 printf("ioctl(fbdev) failed with %i\n", errno);\r
224                 exit(1);\r
225         }\r
226 \r
227         // squidge hack\r
228         if (fbfix.line_length != 800*2)\r
229         {\r
230                 gp2x_screen = malloc(800*640*2);\r
231                 return;\r
232         }\r
233 \r
234         fbdev = open("/dev/fb0", O_RDWR);\r
235         if (fbdev == -1)\r
236         {\r
237                 printf("open(\"/dev/fb0\") failed with %i\n", errno);\r
238                 exit(1);\r
239         }\r
240 \r
241         screen = mmap(0, SCREEN_MAP_SIZE, PROT_WRITE|PROT_READ, MAP_SHARED, fbdev, 0);\r
242         if (screen == MAP_FAILED)\r
243         {\r
244                 printf("mmap(fbptr) failed with %i\n", errno);\r
245                 exit(1);\r
246         }\r
247         printf("fbptr %p\n", screen);\r
248 //      gp2x_screen = (char *)screen + 800*10*2-64;\r
249         gp2x_screen = screen;\r
250 \r
251 \r
252         // snd\r
253         mixerdev = open("/dev/mixer", O_RDWR);\r
254         if (mixerdev == -1)\r
255                 printf("open(\"/dev/mixer\") failed with %i\n", errno);\r
256 \r
257         /* init usb joys -GnoStiC */\r
258         gp2x_usbjoy_init();\r
259 \r
260         // touchscreen\r
261         touchdev = open("/dev/touchscreen/wm97xx", O_RDONLY);\r
262         if (touchdev >= 0) {\r
263                 FILE *pcf = fopen("/etc/pointercal", "r");\r
264                 if (pcf) {\r
265                         fscanf(pcf, "%d %d %d %d %d %d %d", &touchcal[0], &touchcal[1],\r
266                                 &touchcal[2], &touchcal[3], &touchcal[4], &touchcal[5], &touchcal[6]);\r
267                         fclose(pcf);\r
268                 }\r
269                 printf("found touchscreen/wm97xx\n");\r
270         }\r
271 \r
272         printf("exitting init()\n"); fflush(stdout);\r
273 }\r
274 \r
275 void gp2x_deinit(void)\r
276 {\r
277         //gp2x_video_changemode(15);\r
278 \r
279         if (screen != MAP_FAILED)\r
280                 munmap(screen, SCREEN_MAP_SIZE);\r
281         if (memregs != MAP_FAILED)\r
282                 munmap((void *)memregs, 0x10000);\r
283         close(memdev);\r
284         if (fbdev >= 0)    close(fbdev);\r
285         if (mixerdev >= 0) close(mixerdev);\r
286         if (sounddev >= 0) close(sounddev);\r
287         if (touchdev >= 0) close(touchdev);\r
288 \r
289         gp2x_usbjoy_deinit();\r
290 \r
291         printf("all done");\r
292 }\r
293 \r
294 /* lprintf */\r
295 void lprintf(const char *fmt, ...)\r
296 {\r
297         va_list vl;\r
298 \r
299         va_start(vl, fmt);\r
300         vprintf(fmt, vl);\r
301         va_end(vl);\r
302 }\r
303 \r
304 \r
305 /* fake GP2X */\r
306 int crashed_940 = 0;\r
307 \r
308 int readpng(void *dest, const char *fname, int what) { return -1; }\r
309 void set_gamma(int g100, int A_SNs_curve) {}\r
310 void set_FCLK(unsigned MHZ) {}\r
311 void set_LCD_custom_rate(int rate) {}\r
312 void unset_LCD_custom_rate(void) {}\r
313 void Pause940(int yes) {}\r
314 void Reset940(int yes, int bank) {}\r
315 \r