frontend: update libpicofe
[pcsx_rearmed.git] / frontend / main.c
CommitLineData
e906c010 1/*
dde7da71 2 * (C) notaz, 2010-2012
e906c010 3 *
4 * This work is licensed under the terms of the GNU GPLv2 or later.
5 * See the COPYING file in the top-level directory.
6 */
7
80c2304e 8#include <stdio.h>
9#include <string.h>
10#include <stdarg.h>
11#include <dlfcn.h>
12#include <sys/stat.h>
13#include <sys/types.h>
14#include <unistd.h>
c5061935 15#include <signal.h>
29a8c4f3 16#include <time.h>
80c2304e 17
c5061935 18#include "main.h"
e906c010 19#include "plugin.h"
7c0f51de 20#include "plugin_lib.h"
14dffdb7 21#include "pcnt.h"
3c70c47b 22#include "menu.h"
47821672 23#include "plat.h"
80c2304e 24#include "../libpcsxcore/misc.h"
9c27c205 25#include "../libpcsxcore/cheat.h"
799b0b87 26#include "../libpcsxcore/new_dynarec/new_dynarec.h"
47bf65ab 27#include "../plugins/cdrcimg/cdrcimg.h"
38c2028e 28#include "revision.h"
80c2304e 29
cc56203b 30#ifndef NO_FRONTEND
31#include "libpicofe/input.h"
32#include "libpicofe/plat.h"
33#include "libpicofe/readpng.h"
87e5b45f 34
35static void toggle_fast_forward(int force_off);
e6495add 36static void check_profile(void);
37static void check_memcards(void);
cc56203b 38#endif
a1b44e36 39#ifndef BOOT_MSG
40#define BOOT_MSG "Booting up..."
41#endif
cc56203b 42
fc8145b7 43// don't include debug.h - it breaks ARM build (R1 redefined)
44void StartDebugger();
45void StopDebugger();
46
33400707 47// sound plugin
48extern int iUseReverb;
49extern int iUseInterpolation;
50extern int iXAPitch;
33400707 51extern int iVolume;
52
69e482e3 53int ready_to_go, g_emu_want_quit, g_emu_resetting;
c5061935 54unsigned long gpuDisp;
55char cfgfile_basename[MAXPATHLEN];
8f892648 56int state_slot;
57enum sched_action emu_action, emu_action_old;
58char hud_msg[64];
59int hud_new_msg;
60
80c2304e 61static void make_path(char *buf, size_t size, const char *dir, const char *fname)
62{
63 if (fname)
64 snprintf(buf, size, ".%s%s", dir, fname);
65 else
66 snprintf(buf, size, ".%s", dir);
67}
68#define MAKE_PATH(buf, dir, fname) \
69 make_path(buf, sizeof(buf), dir, fname)
70
29a8c4f3 71static int get_gameid_filename(char *buf, int size, const char *fmt, int i) {
72 char trimlabel[33];
73 int j;
74
75 strncpy(trimlabel, CdromLabel, 32);
76 trimlabel[32] = 0;
77 for (j = 31; j >= 0; j--)
78 if (trimlabel[j] == ' ')
79 trimlabel[j] = 0;
80 else
81 continue;
82
83 snprintf(buf, size, fmt, trimlabel, CdromId, i);
84
85 return 0;
80c2304e 86}
87
47bf65ab 88void set_cd_image(const char *fname)
89{
e16a7e51 90 const char *ext = NULL;
47bf65ab 91
33716956 92 if (fname != NULL)
93 ext = strrchr(fname, '.');
47bf65ab 94
33716956 95 if (ext && (
96 strcasecmp(ext, ".z") == 0 || strcasecmp(ext, ".bz") == 0 ||
9a92bffb 97 strcasecmp(ext, ".znx") == 0 /*|| strcasecmp(ext, ".pbp") == 0*/)) {
47bf65ab 98 SetIsoFile(NULL);
99 cdrcimg_set_fname(fname);
100 strcpy(Config.Cdr, "builtin_cdrcimg");
101 } else {
102 SetIsoFile(fname);
103 strcpy(Config.Cdr, "builtin_cdr");
104 }
105}
106
6fe1f056 107static void set_default_paths(void)
108{
e6495add 109#ifndef NO_FRONTEND
110 snprintf(Config.PatchesDir, sizeof(Config.PatchesDir), "." PATCHES_DIR);
6fe1f056 111 MAKE_PATH(Config.Mcd1, MEMCARD_DIR, "card1.mcd");
112 MAKE_PATH(Config.Mcd2, MEMCARD_DIR, "card2.mcd");
113 strcpy(Config.BiosDir, "bios");
e6495add 114#endif
6fe1f056 115
116 strcpy(Config.PluginsDir, "plugins");
117 strcpy(Config.Gpu, "builtin_gpu");
118 strcpy(Config.Spu, "builtin_spu");
119 strcpy(Config.Cdr, "builtin_cdr");
120 strcpy(Config.Pad1, "builtin_pad");
121 strcpy(Config.Pad2, "builtin_pad");
122 strcpy(Config.Net, "Disabled");
6fe1f056 123}
124
33400707 125void emu_set_default_config(void)
126{
127 // try to set sane config on which most games work
128 Config.Xa = Config.Cdda = Config.Sio =
129 Config.SpuIrq = Config.RCntFix = Config.VSyncWA = 0;
33400707 130 Config.PsxAuto = 1;
131
746fee51 132 pl_rearmed_cbs.gpu_neon.allow_interlace = 2; // auto
0b02eb77 133 pl_rearmed_cbs.gpu_neon.enhancement_enable =
134 pl_rearmed_cbs.gpu_neon.enhancement_no_main = 0;
33400707 135 pl_rearmed_cbs.gpu_peops.iUseDither = 0;
136 pl_rearmed_cbs.gpu_peops.dwActFixes = 1<<7;
137 pl_rearmed_cbs.gpu_unai.abe_hack =
138 pl_rearmed_cbs.gpu_unai.no_light =
139 pl_rearmed_cbs.gpu_unai.no_blend = 0;
e60da159 140 memset(&pl_rearmed_cbs.gpu_peopsgl, 0, sizeof(pl_rearmed_cbs.gpu_peopsgl));
746fee51 141 pl_rearmed_cbs.gpu_peopsgl.iVRamSize = 64;
cbb26048 142 pl_rearmed_cbs.gpu_peopsgl.iTexGarbageCollection = 1;
33400707 143
144 iUseReverb = 2;
145 iUseInterpolation = 1;
146 iXAPitch = 0;
33400707 147 iVolume = 768;
148#ifndef __ARM_ARCH_7A__ /* XXX */
149 iUseReverb = 0;
150 iUseInterpolation = 0;
151#endif
152 new_dynarec_hacks = 0;
153 cycle_multiplier = 200;
154
155 in_type1 = PSE_PAD_TYPE_STANDARD;
156 in_type2 = PSE_PAD_TYPE_STANDARD;
157}
158
8f892648 159void do_emu_action(void)
160{
161 int ret;
162
163 emu_action_old = emu_action;
164
165 switch (emu_action) {
8f892648 166 case SACTION_LOAD_STATE:
167 ret = emu_load_state(state_slot);
168 snprintf(hud_msg, sizeof(hud_msg), ret == 0 ? "LOADED" : "FAIL!");
169 break;
170 case SACTION_SAVE_STATE:
171 ret = emu_save_state(state_slot);
172 snprintf(hud_msg, sizeof(hud_msg), ret == 0 ? "SAVED" : "FAIL!");
173 break;
38c2028e 174#ifndef NO_FRONTEND
175 case SACTION_ENTER_MENU:
456f1b86 176 toggle_fast_forward(1);
38c2028e 177 menu_loop();
178 return;
8f892648 179 case SACTION_NEXT_SSLOT:
180 state_slot++;
181 if (state_slot > 9)
182 state_slot = 0;
183 goto do_state_slot;
184 case SACTION_PREV_SSLOT:
185 state_slot--;
186 if (state_slot < 0)
187 state_slot = 9;
38c2028e 188do_state_slot:
189 snprintf(hud_msg, sizeof(hud_msg), "STATE SLOT %d [%s]", state_slot,
190 emu_check_state(state_slot) == 0 ? "USED" : "FREE");
191 hud_new_msg = 3;
f29fbd53 192 SysPrintf("* %s\n", hud_msg);
38c2028e 193 break;
8f892648 194 case SACTION_TOGGLE_FSKIP:
ea4a16e7 195 pl_rearmed_cbs.fskip_advice = 0;
196 pl_rearmed_cbs.frameskip++;
197 if (pl_rearmed_cbs.frameskip > 1)
198 pl_rearmed_cbs.frameskip = -1;
199 snprintf(hud_msg, sizeof(hud_msg), "FRAMESKIP: %s",
200 pl_rearmed_cbs.frameskip == -1 ? "AUTO" :
201 pl_rearmed_cbs.frameskip == 0 ? "OFF" : "1" );
202 plugin_call_rearmed_cbs();
8f892648 203 break;
fa56d360 204 case SACTION_SWITCH_DISPMODE:
205 pl_switch_dispmode();
d81b8e97 206 plugin_call_rearmed_cbs();
fa56d360 207 if (GPU_open != NULL && GPU_close != NULL) {
208 GPU_close();
209 GPU_open(&gpuDisp, "PCSX", NULL);
210 }
d81b8e97 211 break;
456f1b86 212 case SACTION_FAST_FORWARD:
213 toggle_fast_forward(0);
214 plugin_call_rearmed_cbs();
215 break;
dde7da71 216 case SACTION_TOGGLE_FPS:
217 if ((g_opts & (OPT_SHOWFPS|OPT_SHOWCPU))
218 == (OPT_SHOWFPS|OPT_SHOWCPU))
219 g_opts &= ~(OPT_SHOWFPS|OPT_SHOWCPU);
220 else if (g_opts & OPT_SHOWFPS)
221 g_opts |= OPT_SHOWCPU;
222 else
223 g_opts |= OPT_SHOWFPS;
224 break;
a8376201 225 case SACTION_TOGGLE_FULLSCREEN:
5b9aa749 226 plat_target.vout_fullscreen = !plat_target.vout_fullscreen;
c9099d02 227 if (GPU_open != NULL && GPU_close != NULL) {
228 GPU_close();
229 GPU_open(&gpuDisp, "PCSX", NULL);
230 }
a8376201 231 break;
29a8c4f3 232 case SACTION_SCREENSHOT:
233 {
38c2028e 234 char buf[MAXPATHLEN];
29a8c4f3 235 void *scrbuf;
236 int w, h, bpp;
237 time_t t = time(NULL);
238 struct tm *tb = localtime(&t);
239 int ti = tb->tm_yday * 1000000 + tb->tm_hour * 10000 +
240 tb->tm_min * 100 + tb->tm_sec;
241
242 scrbuf = pl_prepare_screenshot(&w, &h, &bpp);
243 get_gameid_filename(buf, sizeof(buf),
244 "screenshots/%.32s-%.9s.%d.png", ti);
245 ret = -1;
246 if (scrbuf != 0 && bpp == 16)
247 ret = writepng(buf, scrbuf, w, h);
248 if (ret == 0)
249 snprintf(hud_msg, sizeof(hud_msg), "SCREENSHOT TAKEN");
250 break;
251 }
221be40d 252 case SACTION_VOLUME_UP:
253 case SACTION_VOLUME_DOWN:
bcfc48e3 254 {
255 static int volume;
256 plat_target_step_volume(&volume,
257 emu_action == SACTION_VOLUME_UP ? 1 : -1);
258 }
221be40d 259 return;
a805c855 260 case SACTION_MINIMIZE:
36dfb787 261 if (GPU_close != NULL)
262 GPU_close();
263
a805c855 264 plat_minimize();
36dfb787 265
266 if (GPU_open != NULL) {
267 ret = GPU_open(&gpuDisp, "PCSX", NULL);
268 if (ret)
f29fbd53 269 SysMessage("GPU_open returned %d", ret);
36dfb787 270 }
a805c855 271 return;
38c2028e 272#endif
4c08b9e7 273 default:
274 return;
8f892648 275 }
8f892648 276
8f892648 277 hud_new_msg = 3;
278}
279
cae602d4 280static char basic_lcase(char c)
281{
282 if ('A' <= c && c <= 'Z')
283 return c - 'A' + 'a';
284 return c;
285}
286
9c27c205 287static int cdidcmp(const char *id1, const char *id2)
288{
289 while (*id1 != 0 && *id2 != 0) {
290 if (*id1 == '_') { id1++; continue; }
291 if (*id2 == '_') { id2++; continue; }
cae602d4 292 if (basic_lcase(*id1) != basic_lcase(*id2))
9c27c205 293 break;
294 id1++;
295 id2++;
296 }
297
298 return *id1 - *id2;
299}
300
301static void parse_cwcheat(void)
302{
303 char line[256], buf[64], name[64], *p;
304 int newcheat = 1;
305 u32 a, v;
306 FILE *f;
307
308 f = fopen("cheatpops.db", "r");
309 if (f == NULL)
310 return;
311
312 /* find the game */
313 while (fgets(line, sizeof(line), f)) {
314 if (sscanf(line, "_S %63s", buf) != 1)
315 continue;
316 if (cdidcmp(buf, CdromId) == 0)
317 break;
318 }
319
320 if (feof(f))
321 goto out;
322
f29fbd53 323 SysPrintf("cwcheat section found for %s\n", CdromId);
9c27c205 324 while (fgets(line, sizeof(line), f))
325 {
326 p = line + strlen(line);
327 for (p--; p >= line && (*p == '\r' || *p == '\n' || *p == ' '); p--)
328 *p = 0;
329 if (*p == 0 || *p == '#' || *p == ';')
330 continue;
331
332 if (strncmp(line, "_S", 2) == 0)
333 break;
334 if (strncmp(line, "_G", 2) == 0) {
f29fbd53 335 SysPrintf(" cwcheat game name: '%s'\n", line + 3);
9c27c205 336 continue;
337 }
338 if (strncmp(line, "_C0", 3) == 0) {
339 if (!newcheat && Cheats[NumCheats - 1].n == 0) {
f29fbd53 340 SysPrintf("cheat '%s' failed to parse\n", name);
9c27c205 341 free(Cheats[NumCheats - 1].Descr);
342 NumCheats--;
343 }
344 snprintf(name, sizeof(name), "%s", line + 4);
345 newcheat = 1;
346 continue;
347 }
348 if (sscanf(line, "_L %x %x", &a, &v) != 2) {
f29fbd53 349 SysPrintf("line f