aboutsummaryrefslogtreecommitdiff
path: root/frontend
diff options
context:
space:
mode:
Diffstat (limited to 'frontend')
-rwxr-xr-xfrontend/320240/caanoo.gpe23
-rw-r--r--frontend/320240/haptic_s.cfg3
-rw-r--r--frontend/320240/haptic_w.cfg3
-rw-r--r--frontend/320240/pcsx26.pngbin4763 -> 0 bytes
-rw-r--r--frontend/320240/pcsx_rearmed.ini6
-rw-r--r--frontend/320240/pcsxb.pngbin24784 -> 0 bytes
-rw-r--r--frontend/320240/pollux_set.c389
-rw-r--r--frontend/320240/skin/background.pngbin36069 -> 0 bytes
-rw-r--r--frontend/320240/skin/font.pngbin3185 -> 0 bytes
-rw-r--r--frontend/320240/skin/readme.txt8
-rw-r--r--frontend/320240/skin/selector.pngbin261 -> 0 bytes
-rw-r--r--frontend/320240/skin/skin.txt4
-rw-r--r--frontend/320240/ui_gp2x.h15
-rw-r--r--frontend/3ds/3ds_utils.h68
-rw-r--r--frontend/3ds/pthread.h46
-rw-r--r--frontend/3ds/sys/mman.h107
-rw-r--r--frontend/3ds/zconf.h511
-rw-r--r--frontend/3ds/zlib.h1768
-rw-r--r--frontend/cspace.c50
m---------frontend/libpicofe0
-rw-r--r--frontend/libretro.c1859
-rwxr-xr-xfrontend/libretro.h1926
-rw-r--r--frontend/libretro_core_options.h1243
-rw-r--r--frontend/libretro_core_options_intl.h568
-rw-r--r--frontend/link.T5
-rw-r--r--frontend/main.c38
-rw-r--r--frontend/menu.c43
-rw-r--r--frontend/pandora/pcsx.pngbin7981 -> 0 bytes
-rw-r--r--frontend/pandora/pcsx.pxml.templ42
-rwxr-xr-xfrontend/pandora/pcsx.sh24
-rw-r--r--frontend/pandora/picorestore.c109
-rw-r--r--frontend/pandora/skin/background.pngbin183772 -> 0 bytes
-rw-r--r--frontend/pandora/skin/font.pngbin11264 -> 0 bytes
-rw-r--r--frontend/pandora/skin/readme.txt8
-rw-r--r--frontend/pandora/skin/selector.pngbin386 -> 0 bytes
-rw-r--r--frontend/pandora/skin/skin.txt4
-rw-r--r--frontend/pandora/ui_feat.h16
-rw-r--r--frontend/plugin.c57
-rw-r--r--frontend/plugin_lib.c16
-rw-r--r--frontend/plugin_lib.h18
-rw-r--r--frontend/switch/sys/mman.h125
-rw-r--r--frontend/switch/zconf.h511
-rw-r--r--frontend/switch/zlib.h1768
-rw-r--r--frontend/vita/retro_inline.h39
-rw-r--r--frontend/vita/sys/mman.h69
m---------frontend/warm0
46 files changed, 8662 insertions, 2827 deletions
diff --git a/frontend/320240/caanoo.gpe b/frontend/320240/caanoo.gpe
deleted file mode 100755
index 9d6154a..0000000
--- a/frontend/320240/caanoo.gpe
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/bin/sh
-
-# Wiz's timings are already good, apply this for Caanoo
-if [ -e /dev/accel ]; then
- ./pollux_set "ram_timings=3,9,4,1,1,1,1"
-fi
-
-# the sync mount causes problems when writing saves,
-# probably due to many write calls, so have to get rid of it
-if grep mmcblk /proc/mounts | grep -q '\<sync\>'; then
- oldmount=`grep mmcblk /proc/mounts | grep '\<sync\>' | awk '{print $4}'`
- mount /dev/mmcblk0p1 /mnt/sd/ -o remount,dirsync,noatime
-fi
-
-./pcsx "$@"
-sync
-
-if [ -n "$oldmount" ]; then
- mount /dev/mmcblk0p1 /mnt/sd/ -o remount,$oldmount
-fi
-
-cd /usr/gp2x
-exec ./gp2xmenu
diff --git a/frontend/320240/haptic_s.cfg b/frontend/320240/haptic_s.cfg
deleted file mode 100644
index 624056d..0000000
--- a/frontend/320240/haptic_s.cfg
+++ /dev/null
@@ -1,3 +0,0 @@
-0 126
-100 -126
-115 0
diff --git a/frontend/320240/haptic_w.cfg b/frontend/320240/haptic_w.cfg
deleted file mode 100644
index 3585a71..0000000
--- a/frontend/320240/haptic_w.cfg
+++ /dev/null
@@ -1,3 +0,0 @@
-0 54
-100 -126
-105 0
diff --git a/frontend/320240/pcsx26.png b/frontend/320240/pcsx26.png
deleted file mode 100644
index ed220a0..0000000
--- a/frontend/320240/pcsx26.png
+++ /dev/null
Binary files differ
diff --git a/frontend/320240/pcsx_rearmed.ini b/frontend/320240/pcsx_rearmed.ini
deleted file mode 100644
index b15497f..0000000
--- a/frontend/320240/pcsx_rearmed.ini
+++ /dev/null
@@ -1,6 +0,0 @@
-[info]
-name="PCSX ReARMed"
-icon="/pcsx_rearmed/pcsx26.png"
-path="/pcsx_rearmed/pcsx.gpe"
-title="/pcsx_rearmed/pcsxb.png"
-group="GAMES"
diff --git a/frontend/320240/pcsxb.png b/frontend/320240/pcsxb.png
deleted file mode 100644
index ff5a48a..0000000
--- a/frontend/320240/pcsxb.png
+++ /dev/null
Binary files differ
diff --git a/frontend/320240/pollux_set.c b/frontend/320240/pollux_set.c
deleted file mode 100644
index f49e777..0000000
--- a/frontend/320240/pollux_set.c
+++ /dev/null
@@ -1,389 +0,0 @@
-/*
- * quick tool to set various timings for Wiz
- *
- * Copyright (c) GraÅžvydas "notaz" Ignotas, 2009
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the organization nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * HTOTAL: X VTOTAL: 341
- * HSWIDTH: 1 VSWIDTH: 0
- * HASTART: 37 VASTART: 17
- * HAEND: 277 VAEND: 337
- *
- * 120Hz
- * pcd 8, 447: + 594us
- * pcd 9, 397: + 36us
- * pcd 10, 357: - 523us
- * pcd 11, 325: +1153us
- *
- * 'lcd_timings=397,1,37,277,341,0,17,337;dpc_clkdiv0=9'
- * 'ram_timings=2,9,4,1,1,1,1'
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-//#include "pollux_set.h"
-#define BINARY
-
-/* parse stuff */
-static int parse_lcd_timings(const char *str, void *data)
-{
- int *lcd_timings = data;
- const char *p = str;
- int ret, c;
- ret = sscanf(str, "%d,%d,%d,%d,%d,%d,%d,%d",
- &lcd_timings[0], &lcd_timings[1], &lcd_timings[2], &lcd_timings[3],
- &lcd_timings[4], &lcd_timings[5], &lcd_timings[6], &lcd_timings[7]);
- if (ret != 8)
- return -1;
- /* skip seven commas */
- for (c = 0; c < 7 && *p != 0; p++)
- if (*p == ',')
- c++;
- if (c != 7)
- return -1;
- /* skip last number */
- while ('0' <= *p && *p <= '9')
- p++;
-
- return p - str;
-}
-
-static int parse_ram_timings(const char *str, void *data)
-{
- int *ram_timings = data;
- const char *p = str;
- int ret, c;
- float cas;
-
- ret = sscanf(p, "%f,%d,%d,%d,%d,%d,%d",
- &cas, &ram_timings[1], &ram_timings[2], &ram_timings[3],
- &ram_timings[4], &ram_timings[5], &ram_timings[6]);
- if (ret != 7)
- return -1;
- if (cas == 2)
- ram_timings[0] = 1;
- else if (cas == 2.5)
- ram_timings[0] = 2;
- else if (cas == 3)
- ram_timings[0] = 3;
- else
- return -1;
- for (c = 0; c < 6 && *p != 0; p++)
- if (*p == ',')
- c++;
- if (c != 6)
- return -1;
- while ('0' <= *p && *p <= '9')
- p++;
-
- return p - str;
-}
-
-static int parse_decimal(const char *str, void *data)
-{
- char *ep;
-
- *(int *)data = strtoul(str, &ep, 10);
- if (ep == str)
- return -1;
-
- return ep - str;
-}
-
-/* validate and apply stuff */
-static int apply_lcd_timings(volatile unsigned short *memregs, void *data)
-{
- int *lcd_timings = data;
- int i;
-
- for (i = 0; i < 8; i++) {
- if (lcd_timings[i] & ~0xffff) {
- fprintf(stderr, "pollux_set: invalid lcd timing %d: %d\n", i, lcd_timings[i]);
- return -1;
- }
- }
-
- for (i = 0; i < 8; i++)
- memregs[(0x307c>>1) + i] = lcd_timings[i];
-
- return 0;
-}
-
-static const struct {
- signed char adj; /* how to adjust value passed by user */
- signed short min; /* range of */
- signed short max; /* allowed values (inclusive) */
-}
-ram_ranges[] = {
- { 0, 1, 3 }, /* cas (cl) */
- { -2, 0, 15 }, /* trc */
- { -2, 0, 15 }, /* tras */
- { 0, 0, 15 }, /* twr */
- { 0, 0, 15 }, /* tmrd */
- { 0, 0, 15 }, /* trp */
- { 0, 0, 15 }, /* trcd */
-};
-
-static int apply_ram_timings(volatile unsigned short *memregs, void *data)
-{
- int *ram_timings = data;
- int i, val;
-
- for (i = 0; i < 7; i++)
- {
- ram_timings[i] += ram_ranges[i].adj;
- if (ram_timings[i] < ram_ranges[i].min || ram_timings[i] > ram_ranges[i].max) {
- fprintf(stderr, "pollux_set: invalid RAM timing %d\n", i);
- return -1;
- }
- }
-
- val = memregs[0x14802>>1] & 0x0f00;
- val |= (ram_timings[4] << 12) | (ram_timings[5] << 4) | ram_timings[6];
- memregs[0x14802>>1] = val;
-
- val = memregs[0x14804>>1] & 0x4000;
- val |= (ram_timings[0] << 12) | (ram_timings[1] << 8) |
- (ram_timings[2] << 4) | ram_timings[3];
- val |= 0x8000;
- memregs[0x14804>>1] = val;
-
- for (i = 0; i < 0x100000 && (memregs[0x14804>>1] & 0x8000); i++)
- ;
-
- return 0;
-}
-
-static int apply_dpc_clkdiv0(volatile unsigned short *memregs, void *data)
-{
- int pcd = *(int *)data;
- int tmp;
-
- if ((pcd - 1) & ~0x3f) {
- fprintf(stderr, "pollux_set: invalid lcd clkdiv0: %d\n", pcd);
- return -1;
- }
-
- pcd = (pcd - 1) & 0x3f;
- tmp = memregs[0x31c4>>1];
- memregs[0x31c4>>1] = (tmp & ~0x3f0) | (pcd << 4);
-
- return 0;
-}
-
-static int apply_cpuclk(volatile unsigned short *memregs, void *data)
-{
- volatile unsigned int *memregl = (volatile void *)memregs;
- int mhz = *(int *)data;
- int adiv, mdiv, pdiv, sdiv = 0;
- int i, vf000, vf004;
-
- // m = MDIV, p = PDIV, s = SDIV
- #define SYS_CLK_FREQ 27
- pdiv = 9;
- mdiv = (mhz * pdiv) / SYS_CLK_FREQ;
- if (mdiv & ~0x3ff)
- return -1;
- vf004 = (pdiv<<18) | (mdiv<<8) | sdiv;
-
- // attempt to keep AHB the divider close to 250, but not higher
- for (adiv = 1; mhz / adiv > 250; adiv++)
- ;
-
- vf000 = memregl[0xf000>>2];
- vf000 = (vf000 & ~0x3c0) | ((adiv - 1) << 6);
- memregl[0xf000>>2] = vf000;
- memregl[0xf004>>2] = vf004;
- memregl[0xf07c>>2] |= 0x8000;
- for (i = 0; (memregl[0xf07c>>2] & 0x8000) && i < 0x100000; i++)
- ;
-
- printf("clock set to %dMHz, AHB set to %dMHz\n", mhz, mhz / adiv);
- return 0;
-}
-
-static int lcd_timings[8];
-static int ram_timings[7];
-static int dpc_clkdiv0;
-static int cpuclk;
-
-static const char lcd_t_help[] = "htotal,hswidth,hastart,haend,vtotal,vswidth,vastart,vaend";
-static const char ram_t_help[] = "CAS,tRC,tRAS,tWR,tMRD,tRP,tRCD";
-
-static const struct {
- const char *name;
- const char *help;
- int (*parse)(const char *str, void *data);
- int (*apply)(volatile unsigned short *memregs, void *data);
- void *data;
-}
-all_params[] = {
- { "lcd_timings", lcd_t_help, parse_lcd_timings, apply_lcd_timings, lcd_timings },
- { "ram_timings", ram_t_help, parse_ram_timings, apply_ram_timings, ram_timings },
- { "dpc_clkdiv0", "divider", parse_decimal, apply_dpc_clkdiv0, &dpc_clkdiv0 },
- { "clkdiv0", "divider", parse_decimal, apply_dpc_clkdiv0, &dpc_clkdiv0 }, /* alias */
- { "cpuclk", "MHZ", parse_decimal, apply_cpuclk, &cpuclk },
-};
-#define ALL_PARAM_COUNT (sizeof(all_params) / sizeof(all_params[0]))
-
-/*
- * set timings based on preformated string
- * returns 0 on success.
- */
-int pollux_set(volatile unsigned short *memregs, const char *str)
-{
- int parsed_params[ALL_PARAM_COUNT];
- int applied_params[ALL_PARAM_COUNT];
- int applied_something = 0;
- const char *p, *po;
- int i, ret;
-
- if (str == NULL)
- return -1;
-
- memset(parsed_params, 0, sizeof(parsed_params));
- memset(applied_params, 0, sizeof(applied_params));
-
- p = str;
- while (1)
- {
-again:
- while (*p == ';' || *p == ' ')
- p++;
- if (*p == 0)
- break;
-
- for (i = 0; i < ALL_PARAM_COUNT; i++)
- {
- int param_len = strlen(all_params[i].name);
- if (strncmp(p, all_params[i].name, param_len) == 0 && p[param_len] == '=')
- {
- p += param_len + 1;
- ret = all_params[i].parse(p, all_params[i].data);
- if (ret < 0) {
- fprintf(stderr, "pollux_set parser: error at %-10s\n", p);
- fprintf(stderr, " valid format is: <%s>\n", all_params[i].help);
- return -1;
- }
- parsed_params[i] = 1;
- p += ret;
- goto again;
- }
- }
-
- /* Unknown param. Attempt to be forward compatible and ignore it. */
- for (po = p; *p != 0 && *p != ';'; p++)
- ;
-
- fprintf(stderr, "unhandled param: ");
- fwrite(po, 1, p - po, stderr);
- fprintf(stderr, "\n");
- }
-
- /* validate and apply */
- for (i = 0; i < ALL_PARAM_COUNT; i++)
- {
- if (!parsed_params[i])
- continue;
-
- ret = all_params[i].apply(memregs, all_params[i].data);
- if (ret < 0) {
- fprintf(stderr, "pollux_set: failed to apply %s (bad value?)\n",
- all_params[i].name);
- continue;
- }
-
- applied_something = 1;
- applied_params[i] = 1;
- }
-
- if (applied_something)
- {
- int c;
- printf("applied: ");
- for (i = c = 0; i < ALL_PARAM_COUNT; i++)
- {
- if (!applied_params[i])
- continue;
- if (c != 0)
- printf(", ");
- printf("%s", all_params[i].name);
- c++;
- }
- printf("\n");
- }
-
- return 0;
-}
-
-#ifdef BINARY
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <unistd.h>
-
-static void usage(const char *binary)
-{
- int i;
- printf("usage:\n%s <set_str[;set_str[;...]]>\n"
- "set_str:\n", binary);
- for (i = 0; i < ALL_PARAM_COUNT; i++)
- printf(" %s=<%s>\n", all_params[i].name, all_params[i].help);
-}
-
-int main(int argc, char *argv[])
-{
- volatile unsigned short *memregs;
- int ret, memdev;
-
- if (argc != 2) {
- usage(argv[0]);
- return 1;
- }
-
- memdev = open("/dev/mem", O_RDWR);
- if (memdev == -1)
- {
- perror("open(/dev/mem) failed");
- return 1;
- }
-
- memregs = mmap(0, 0x20000, PROT_READ|PROT_WRITE, MAP_SHARED, memdev, 0xc0000000);
- if (memregs == MAP_FAILED)
- {
- perror("mmap(memregs) failed");
- close(memdev);
- return 1;
- }
-
- ret = pollux_set(memregs, argv[1]);
-
- munmap((void *)memregs, 0x20000);
- close(memdev);
-
- return ret;
-}
-#endif
diff --git a/frontend/320240/skin/background.png b/frontend/320240/skin/background.png
deleted file mode 100644
index 0efdd18..0000000
--- a/frontend/320240/skin/background.png
+++ /dev/null
Binary files differ
diff --git a/frontend/320240/skin/font.png b/frontend/320240/skin/font.png
deleted file mode 100644
index c526a08..0000000
--- a/frontend/320240/skin/font.png
+++ /dev/null
Binary files differ
diff --git a/frontend/320240/skin/readme.txt b/frontend/320240/skin/readme.txt
deleted file mode 100644
index dd83963..0000000
--- a/frontend/320240/skin/readme.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-The skin images can be customized, but there are several limitations:
-
-background.png - must be 320x240 image with 24bit RGB colors.
-font.png - must be 128x160 8bit grayscale image.
-selector.png - must be 8x10 8bit grayscale image.
-
-Font and selector colors can be changed by editing skin.txt.
-
diff --git a/frontend/320240/skin/selector.png b/frontend/320240/skin/selector.png
deleted file mode 100644
index 5062cc2..0000000
--- a/frontend/320240/skin/selector.png
+++ /dev/null
Binary files differ
diff --git a/frontend/320240/skin/skin.txt b/frontend/320240/skin/skin.txt
deleted file mode 100644
index 1d6979f..0000000
--- a/frontend/320240/skin/skin.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-// html-style hex color codes, ex. ff0000 is red, 0000ff is blue, etc.
-text_color=ffffc0
-selection_color=808010
-
diff --git a/frontend/320240/ui_gp2x.h b/frontend/320240/ui_gp2x.h
deleted file mode 100644
index a9c4413..0000000
--- a/frontend/320240/ui_gp2x.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef UI_FEATURES_H
-#define UI_FEATURES_H
-
-#define MENU_BIOS_PATH "pcsx_rearmed/bios/"
-#define MENU_SHOW_VARSCALER 0
-#define MENU_SHOW_VOUTMODE 0
-#define MENU_SHOW_SCALER2 1
-#define MENU_SHOW_NUBS_BTNS 0
-#define MENU_SHOW_VIBRATION 1
-#define MENU_SHOW_DEADZONE 1
-#define MENU_SHOW_MINIMIZE 0
-#define MENU_SHOW_FULLSCREEN 0
-#define MENU_SHOW_VOLUME 1
-
-#endif // UI_FEATURES_H
diff --git a/frontend/3ds/3ds_utils.h b/frontend/3ds/3ds_utils.h
new file mode 100644
index 0000000..1f12b84
--- /dev/null
+++ b/frontend/3ds/3ds_utils.h
@@ -0,0 +1,68 @@
+#ifndef _3DS_UTILS_H
+#define _3DS_UTILS_H
+
+#include <stdio.h>
+#include <stdbool.h>
+
+#define MEMOP_PROT 6
+#define MEMOP_MAP 4
+#define MEMOP_UNMAP 5
+
+void* linearMemAlign(size_t size, size_t alignment);
+void linearFree(void* mem);
+
+int32_t svcDuplicateHandle(uint32_t* out, uint32_t original);
+int32_t svcCloseHandle(uint32_t handle);
+int32_t svcControlMemory(void* addr_out, void* addr0, void* addr1, uint32_t size, uint32_t op, uint32_t perm);
+int32_t svcControlProcessMemory(uint32_t process, void* addr0, void* addr1, uint32_t size, uint32_t op, uint32_t perm);
+
+int32_t threadCreate(void *(*entrypoint)(void*), void* arg, size_t stack_size, int32_t prio, int32_t affinity, bool detached);
+int32_t threadJoin(int32_t thread, int64_t timeout_ns);
+void threadFree(int32_t thread);
+void threadExit(int32_t rc) __attribute__((noreturn));
+
+int32_t svcBackdoor(int32_t (*callback)(void));
+
+#define DEBUG_HOLD() do{printf("%s@%s:%d.\n",__FUNCTION__, __FILE__, __LINE__);fflush(stdout);wait_for_input();}while(0)
+
+void wait_for_input(void);
+
+extern __attribute__((weak)) int __ctr_svchax;
+
+typedef int32_t (*ctr_callback_type)(void);
+
+static inline void ctr_invalidate_ICache_kernel(void)
+{
+ __asm__ volatile(
+ "cpsid aif\n\t"
+ "mov r0, #0\n\t"
+ "mcr p15, 0, r0, c7, c5, 0\n\t");
+}
+
+static inline void ctr_flush_DCache_kernel(void)
+{
+ __asm__ volatile(
+ "cpsid aif\n\t"
+ "mov r0, #0\n\t"
+ "mcr p15, 0, r0, c7, c10, 0\n\t");
+}
+
+static inline void ctr_invalidate_ICache(void)
+{
+ svcBackdoor((ctr_callback_type)ctr_invalidate_ICache_kernel);
+}
+
+static inline void ctr_flush_DCache(void)
+{
+ svcBackdoor((ctr_callback_type)ctr_flush_DCache_kernel);
+}
+
+
+static inline void ctr_flush_invalidate_cache(void)
+{
+ ctr_flush_DCache();
+ ctr_invalidate_ICache();
+}
+
+
+#endif // _3DS_UTILS_H
diff --git a/frontend/3ds/pthread.h b/frontend/3ds/pthread.h
new file mode 100644
index 0000000..286ea7a
--- /dev/null
+++ b/frontend/3ds/pthread.h
@@ -0,0 +1,46 @@
+
+#ifndef _3DS_PTHREAD_WRAP__
+#define _3DS_PTHREAD_WRAP__
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "3ds_utils.h"
+
+#define CTR_PTHREAD_STACK_SIZE (1000000 * 12)
+
+typedef int32_t pthread_t;
+typedef int pthread_attr_t;
+
+static inline int pthread_create(pthread_t *thread,
+ const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg)
+{
+ thread = threadCreate(start_routine, arg, CTR_PTHREAD_STACK_SIZE, 0x25, -2, FALSE);
+ return 1;
+}
+
+
+static inline int pthread_join(pthread_t thread, void **retval)
+{
+ (void)retval;
+
+ if(threadJoin(thread, INT64_MAX))
+ return -1;
+
+ threadFree(thread);
+
+ return 0;
+}
+
+
+static inline void pthread_exit(void *retval)
+{
+ (void)retval;
+
+ threadExit(0);
+}
+
+
+#endif //_3DS_PTHREAD_WRAP__
+
diff --git a/frontend/3ds/sys/mman.h b/frontend/3ds/sys/mman.h
new file mode 100644
index 0000000..61dde6c
--- /dev/null
+++ b/frontend/3ds/sys/mman.h
@@ -0,0 +1,107 @@
+#ifndef MMAN_H
+#define MMAN_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <malloc.h>
+
+#include "3ds_utils.h"
+
+#define PROT_READ 0b001
+#define PROT_WRITE 0b010
+#define PROT_EXEC 0b100
+#define MAP_PRIVATE 2
+#define MAP_FIXED 0x10
+#define MAP_ANONYMOUS 0x20
+
+#define MAP_FAILED ((void *)-1)
+
+static void* dynarec_cache = NULL;
+static void* dynarec_cache_mapping = NULL;
+
+static inline void* mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset)
+{
+ (void)fd;
+ (void)offset;
+
+ void* addr_out;
+
+ if((prot == (PROT_READ | PROT_WRITE | PROT_EXEC)) &&
+ (flags == (MAP_PRIVATE | MAP_ANONYMOUS)))
+ {
+ if(__ctr_svchax)
+ {
+ /* this hack works only for pcsx_rearmed */
+ uint32_t currentHandle;
+
+ if(!dynarec_cache)
+ dynarec_cache = memalign(0x1000, len);
+
+ svcDuplicateHandle(&currentHandle, 0xFFFF8001);
+ svcControlProcessMemory(currentHandle, addr, dynarec_cache,
+ len, MEMOP_MAP, prot);
+ svcCloseHandle(currentHandle);
+ dynarec_cache_mapping = addr;
+ return addr;
+ }
+ else
+ {
+ printf("tried to mmap RWX pages without svcControlProcessMemory access !\n");
+ return MAP_FAILED;
+ }
+
+ }
+
+ addr_out = malloc(len);
+ if(!addr_out)
+ return MAP_FAILED;
+
+ return addr_out;
+}
+
+static inline int mprotect(void *addr, size_t len, int prot)
+{
+ if(__ctr_svchax)
+ {
+ uint32_t currentHandle;
+ svcDuplicateHandle(&currentHandle, 0xFFFF8001);
+ svcControlProcessMemory(currentHandle, addr, NULL,
+ len, MEMOP_PROT, prot);
+ svcCloseHandle(currentHandle);
+ return 0;
+ }
+
+ printf("mprotect called without svcControlProcessMemory access !\n");
+ return -1;
+}
+
+static inline int munmap(void *addr, size_t len)
+{
+ if((addr == dynarec_cache_mapping) && __ctr_svchax)
+ {
+ uint32_t currentHandle;
+ svcDuplicateHandle(&currentHandle, 0xFFFF8001);
+ svcControlProcessMemory(currentHandle,
+ dynarec_cache, dynarec_cache_mapping,
+ len, MEMOP_UNMAP, 0b111);
+ svcCloseHandle(currentHandle);
+ dynarec_cache_mapping = NULL;
+
+ }
+ else
+ free(addr);
+
+ return 0;
+}
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif // MMAN_H
+
diff --git a/frontend/3ds/zconf.h b/frontend/3ds/zconf.h
new file mode 100644
index 0000000..996fff2
--- /dev/null
+++ b/frontend/3ds/zconf.h
@@ -0,0 +1,511 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2013 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ * Even better than compiling with -DZ_PREFIX would be to use configure to set
+ * this permanently in zconf.h using "./configure --zprefix".
+ */
+#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */
+# define Z_PREFIX_SET
+
+/* all linked symbols */
+# define _dist_code z__dist_code
+# define _length_code z__length_code
+# define _tr_align z__tr_align
+# define _tr_flush_bits z__tr_flush_bits
+# define _tr_flush_block z__tr_flush_block
+# define _tr_init z__tr_init
+# define _tr_stored_block z__tr_stored_block
+# define _tr_tally z__tr_tally
+# define adler32 z_adler32
+# define adler32_combine z_adler32_combine
+# define adler32_combine64 z_adler32_combine64
+# ifndef Z_SOLO
+# define compress z_compress
+# define compress2 z_compress2
+# define compressBound z_compressBound
+# endif
+# define crc32 z_crc32
+# define crc32_combine z_crc32_combine
+# define crc32_combine64 z_crc32_combine64
+# define deflate z_deflate
+# define deflateBound z_deflateBound
+# define deflateCopy z_deflateCopy
+# define deflateEnd z_deflateEnd
+# define deflateInit2_ z_deflateInit2_
+# define deflateInit_ z_deflateInit_
+# define deflateParams z_deflateParams
+# define deflatePending z_deflatePending
+# define deflatePrime z_deflatePrime
+# define deflateReset z_deflateReset
+# define deflateResetKeep z_deflateResetKeep
+# define deflateSetDictionary z_deflateSetDictionary
+# define deflateSetHeader z_deflateSetHeader
+# define deflateTune z_deflateTune
+# define deflate_copyright z_deflate_copyright
+# define get_crc_table z_get_crc_table
+# ifndef Z_SOLO
+# define gz_error z_gz_error
+# define gz_intmax z_gz_intmax
+# define gz_strwinerror z_gz_strwinerror
+# define gzbuffer z_gzbuffer
+# define gzclearerr z_gzclearerr
+# define gzclose z_gzclose
+# define gzclose_r z_gzclose_r
+# define gzclose_w z_gzclose_w
+# define gzdirect z_gzdirect
+# define gzdopen z_gzdopen
+# define gzeof z_gzeof
+# define gzerror z_gzerror
+# define gzflush z_gzflush
+# define gzgetc z_gzgetc
+# define gzgetc_ z_gzgetc_
+# define gzgets z_gzgets
+# define gzoffset z_gzoffset
+# define gzoffset64 z_gzoffset64
+# define gzopen z_gzopen
+# define gzopen64 z_gzopen64
+# ifdef _WIN32
+# define gzopen_w z_gzopen_w
+# endif
+# define gzprintf z_gzprintf
+# define gzvprintf z_gzvprintf
+# define gzputc z_gzputc
+# define gzputs z_gzputs
+# define gzread z_gzread
+# define gzrewind z_gzrewind
+# define gzseek z_gzseek
+# define gzseek64 z_gzseek64
+# define gzsetparams z_gzsetparams
+# define gztell z_gztell
+# define gztell64 z_gztell64
+# define gzungetc z_gzungetc
+# define gzwrite z_gzwrite
+# endif
+# define inflate z_inflate
+# define inflateBack z_inflateBack
+# define inflateBackEnd z_inflateBackEnd
+# define inflateBackInit_ z_inflateBackInit_
+# define inflateCopy z_inflateCopy
+# define inflateEnd z_inflateEnd
+# define inflateGetHeader z_inflateGetHeader
+# define inflateInit2_ z_inflateInit2_
+# define inflateInit_ z_inflateInit_
+# define inflateMark z_inflateMark
+# define inflatePrime z_inflatePrime
+# define inflateReset z_inflateReset
+# define inflateReset2 z_inflateReset2
+# define inflateSetDictionary z_inflateSetDictionary
+# define inflateGetDictionary z_inflateGetDictionary
+# define inflateSync z_inflateSync
+# define inflateSyncPoint z_inflateSyncPoint
+# define inflateUndermine z_inflateUndermine
+# define inflateResetKeep z_inflateResetKeep
+# define inflate_copyright z_inflate_copyright
+# define inflate_fast z_inflate_fast
+# define inflate_table z_inflate_table
+# ifndef Z_SOLO
+# define uncompress z_uncompress
+# endif
+# define zError z_zError
+# ifndef Z_SOLO
+# define zcalloc z_zcalloc
+# define zcfree z_zcfree
+# endif
+# define zlibCompileFlags z_zlibCompileFlags
+# define zlibVersion z_zlibVersion
+
+/* all zlib typedefs in zlib.h and zconf.h */
+# define Byte z_Byte
+# define Bytef z_Bytef
+# define alloc_func z_alloc_func
+# define charf z_charf
+# define free_func z_free_func
+# ifndef Z_SOLO
+# define gzFile z_gzFile
+# endif
+# define gz_header z_gz_header
+# define gz_headerp z_gz_headerp
+# define in_func z_in_func
+# define intf z_intf
+# define out_func z_out_func
+# define uInt z_uInt
+# define uIntf z_uIntf
+# define uLong z_uLong
+# define uLongf z_uLongf
+# define voidp z_voidp
+# define voidpc z_voidpc
+# define voidpf z_voidpf
+
+/* all zlib structs in zlib.h and zconf.h */
+# define gz_header_s z_gz_header_s
+# define internal_state z_internal_state
+
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+# define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+# define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+# define WINDOWS
+#endif
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+# ifndef WIN32
+# define WIN32
+# endif
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+# ifndef SYS16BIT
+# define SYS16BIT
+# endif
+# endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+# define MAXSEG_64K
+#endif
+#ifdef MSDOS
+# define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+# ifndef STDC
+# define STDC
+# endif
+# if __STDC_VERSION__ >= 199901L
+# ifndef STDC99
+# define STDC99
+# endif
+# endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+# define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
+# define STDC
+#endif
+
+#ifndef STDC
+# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+# define const /* note: need a more gentle solution here */
+# endif
+#endif
+
+#if defined(ZLIB_CONST) && !defined(z_const)
+# define z_const const
+#else
+# define z_const
+#endif
+
+/* Some Mac compilers merge all .h files incorrectly: */
+#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
+# define NO_DUMMY_DECL
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+# ifdef MAXSEG_64K
+# define MAX_MEM_LEVEL 8
+# else
+# define MAX_MEM_LEVEL 9
+# endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+# define MAX_WBITS 15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+ (1 << (windowBits+2)) + (1 << (memLevel+9))
+ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+ The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+ /* Type declarations */
+
+#ifndef OF /* function prototypes */
+# ifdef STDC
+# define OF(args) args
+# else
+# define OF(args) ()
+# endif
+#endif
+
+#ifndef Z_ARG /* function prototypes for stdarg */
+# if defined(STDC) || defined(Z_HAVE_STDARG_H)
+# define Z_ARG(args) args
+# else
+# define Z_ARG(args) ()
+# endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+# if defined(M_I86SM) || defined(M_I86MM)
+ /* MSC small or medium model */
+# define SMALL_MEDIUM
+# ifdef _MSC_VER
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+# if (defined(__SMALL__) || defined(__MEDIUM__))
+ /* Turbo C small or medium model */
+# define SMALL_MEDIUM
+# ifdef __BORLANDC__
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+ /* If building or using zlib as a DLL, define ZLIB_DLL.
+ * This is not mandatory, but it offers a little performance increase.
+ */
+# ifdef ZLIB_DLL
+# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+# ifdef ZLIB_INTERNAL
+# define ZEXTERN extern __declspec(dllexport)
+# else
+# define ZEXTERN extern __declspec(dllimport)
+# endif
+# endif
+# endif /* ZLIB_DLL */
+ /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+ * define ZLIB_WINAPI.
+ * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+ */
+# ifdef ZLIB_WINAPI
+# ifdef FAR
+# undef FAR
+# endif
+# include <windows.h>
+ /* No need for _export, use ZLIB.DEF instead. */
+ /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+# define ZEXPORT WINAPI
+# ifdef WIN32
+# define ZEXPORTVA WINAPIV
+# else
+# define ZEXPORTVA FAR CDECL
+# endif
+# endif
+#endif
+
+#if defined (__BEOS__)
+# ifdef ZLIB_DLL
+# ifdef ZLIB_INTERNAL
+# define ZEXPORT __declspec(dllexport)
+# define ZEXPORTVA __declspec(dllexport)
+# else
+# define ZEXPORT __declspec(dllimport)
+# define ZEXPORTVA __declspec(dllimport)
+# endif
+# endif
+#endif
+
+#ifndef ZEXTERN
+# define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+# define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+# define ZEXPORTVA
+#endif
+
+#ifndef FAR
+# define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char Byte; /* 8 bits */
+#endif
+typedef unsigned int uInt; /* 16 bits or more */
+typedef unsigned long uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+ /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+# define Bytef Byte FAR
+#else
+ typedef Byte FAR Bytef;
+#endif
+typedef char FAR charf;
+typedef int FAR intf;
+typedef uInt FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+ typedef void const *voidpc;
+ typedef void FAR *voidpf;
+ typedef void *voidp;
+#else
+ typedef Byte const *voidpc;
+ typedef Byte FAR *voidpf;
+ typedef Byte *voidp;
+#endif
+
+#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)
+# include <limits.h>
+# if (UINT_MAX == 0xffffffffUL)
+# define Z_U4 unsigned
+# elif (ULONG_MAX == 0xffffffffUL)
+# define Z_U4 unsigned long
+# elif (USHRT_MAX == 0xffffffffUL)
+# define Z_U4 unsigned short
+# endif
+#endif
+
+#ifdef Z_U4
+ typedef Z_U4 z_crc_t;
+#else
+ typedef unsigned long z_crc_t;
+#endif
+
+#if 1 /* was set to #if 1 by ./configure */
+# define Z_HAVE_UNISTD_H
+#endif
+
+#if 1 /* was set to #if 1 by ./configure */
+# define Z_HAVE_STDARG_H
+#endif
+
+#ifdef STDC
+# ifndef Z_SOLO
+# include <sys/types.h> /* for off_t */
+# endif
+#endif
+
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+# ifndef Z_SOLO
+# include <stdarg.h> /* for va_list */
+# endif
+#endif
+
+#ifdef _WIN32
+# ifndef Z_SOLO
+# include <stddef.h> /* for wchar_t */
+# endif
+#endif
+
+/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
+ * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
+ * though the former does not conform to the LFS document), but considering
+ * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
+ * equivalently requesting no 64-bit operations
+ */
+#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
+# undef _LARGEFILE64_SOURCE
+#endif
+
+#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
+# define Z_HAVE_UNISTD_H
+#endif
+#ifndef Z_SOLO
+# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
+# include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
+# ifdef VMS
+# include <unixio.h> /* for off_t */
+# endif
+# ifndef z_off_t
+# define z_off_t off_t
+# endif
+# endif
+#endif
+
+#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0
+# define Z_LFS64
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)
+# define Z_LARGE64
+#endif
+
+#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)
+# define Z_WANT64
+#endif
+
+#if !defined(SEEK_SET) && !defined(Z_SOLO)
+# define SEEK_SET 0 /* Seek from beginning of file. */
+# define SEEK_CUR 1 /* Seek from current position. */
+# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
+#endif
+
+#ifndef z_off_t
+# define z_off_t long
+#endif
+
+#if !defined(_WIN32) && defined(Z_LARGE64)
+# define z_off64_t off64_t
+#else
+# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
+# define z_off64_t __int64
+# else
+# define z_off64_t z_off_t
+# endif
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+ #pragma map(deflateInit_,"DEIN")
+ #pragma map(deflateInit2_,"DEIN2")
+ #pragma map(deflateEnd,"DEEND")
+ #pragma map(deflateBound,"DEBND")
+ #pragma map(inflateInit_,"ININ")
+ #pragma map(inflateInit2_,"ININ2")
+ #pragma map(inflateEnd,"INEND")
+ #pragma map(inflateSync,"INSY")
+ #pragma map(inflateSetDictionary,"INSEDI")
+ #pragma map(compressBound,"CMBND")
+ #pragma map(inflate_table,"INTABL")
+ #pragma map(inflate_fast,"INFA")
+ #pragma map(inflate_copyright,"INCOPY")
+#endif
+
+#endif /* ZCONF_H */
diff --git a/frontend/3ds/zlib.h b/frontend/3ds/zlib.h
new file mode 100644
index 0000000..3e0c767
--- /dev/null
+++ b/frontend/3ds/zlib.h
@@ -0,0 +1,1768 @@
+/* zlib.h -- interface of the 'zlib' general purpose compression library
+ version 1.2.8, April 28th, 2013
+
+ Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ jloup@gzip.org madler@alumni.caltech.edu
+
+
+ The data format used by the zlib library is described by RFCs (Request for
+ Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
+ (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
+*/
+
+#ifndef ZLIB_H
+#define ZLIB_H
+
+#include "zconf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ZLIB_VERSION "1.2.8"
+#define ZLIB_VERNUM 0x1280
+#define ZLIB_VER_MAJOR 1
+#define ZLIB_VER_MINOR 2
+#define ZLIB_VER_REVISION 8
+#define ZLIB_VER_SUBREVISION 0
+
+/*
+ The 'zlib' compression library provides in-memory compression and
+ decompression functions, including integrity checks of the uncompressed data.
+ This version of the library supports only one compression method (deflation)
+ but other algorithms will be added later and will have the same stream
+ interface.
+
+ Compression can be done in a single step if the buffers are large enough,
+ or can be done by repeated calls of the compression function. In the latter
+ case, the application must provide more input and/or consume the output
+ (providing more output space) before each call.
+
+ The compressed data format used by default by the in-memory functions is
+ the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
+ around a deflate stream, which is itself documented in RFC 1951.
+
+ The library also supports reading and writing files in gzip (.gz) format
+ with an interface similar to that of stdio using the functions that start
+ with "gz". The gzip format is different from the zlib format. gzip is a
+ gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
+
+ This library can optionally read and write gzip streams in memory as well.
+
+ The zlib format was designed to be compact and fast for use in memory
+ and on communications channels. The gzip format was designed for single-
+ file compression on file systems, has a larger header than zlib to maintain
+ directory information, and uses a different, slower check method than zlib.
+
+ The library does not install any signal handler. The decoder checks
+ the consistency of the compressed data, so the library should never crash
+ even in case of corrupted input.
+*/
+
+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
+typedef void (*free_func) OF((voidpf opaque, voidpf address));
+
+struct internal_state;
+
+typedef struct z_stream_s {
+ z_const Bytef *next_in; /* next input byte */
+ uInt avail_in; /* number of bytes available at next_in */
+ uLong total_in; /* total number of input bytes read so far */
+
+ Bytef *next_out; /* next output byte should be put there */
+ uInt avail_out; /* remaining free space at next_out */
+ uLong total_out; /* total number of bytes output so far */
+
+ z_const char *msg; /* last error message, NULL if no error */
+ struct internal_state FAR *state; /* not visible by applications */
+
+ alloc_func zalloc; /* used to allocate the internal state */
+ free_func zfree; /* used to free the internal state */
+ voidpf opaque; /* private data object passed to zalloc and zfree */
+
+ int data_type; /* best guess about the data type: binary or text */
+ uLong adler; /* adler32 value of the uncompressed data */
+ uLong reserved; /* reserved for future use */
+} z_stream;
+
+typedef z_stream FAR *z_streamp;
+
+/*
+ gzip header information passed to and from zlib routines. See RFC 1952
+ for more details on the meanings of these fields.
+*/
+typedef struct gz_header_s {
+ int text; /* true if compressed data believed to be text */
+ uLong time; /* modification time */
+ int xflags; /* extra flags (not used when writing a gzip file) */
+ int os; /* operating system */
+ Bytef *extra; /* pointer to extra field or Z_NULL if none */
+ uInt extra_len; /* extra field length (valid if extra != Z_NULL) */
+ uInt extra_max; /* space at extra (only when reading header) */
+ Bytef *name; /* pointer to zero-terminated file name or Z_NULL */
+ uInt name_max; /* space at name (only when reading header) */
+ Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */
+ uInt comm_max; /* space at comment (only when reading header) */
+ int hcrc; /* true if there was or will be a header crc */
+ int done; /* true when done reading gzip header (not used
+ when writing a gzip file) */
+} gz_header;
+
+typedef gz_header FAR *gz_headerp;
+
+/*
+ The application must update next_in and avail_in when avail_in has dropped
+ to zero. It must update next_out and avail_out when avail_out has dropped
+ to zero. The application must initialize zalloc, zfree and opaque before
+ calling the init function. All other fields are set by the compression
+ library and must not be updated by the application.
+
+ The opaque value provided by the application will be passed as the first
+ parameter for calls of zalloc and zfree. This can be useful for custom
+ memory management. The compression library attaches no meaning to the
+ opaque value.
+
+ zalloc must return Z_NULL if there is not enough memory for the object.
+ If zlib is used in a multi-threaded application, zalloc and zfree must be
+ thread safe.
+
+ On 16-bit systems, the functions zalloc and zfree must be able to allocate
+ exactly 65536 bytes, but will not be required to allocate more than this if
+ the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers
+ returned by zalloc for objects of exactly 65536 bytes *must* have their
+ offset normalized to zero. The default allocation function provided by this
+ library ensures this (see zutil.c). To reduce memory requirements and avoid
+ any allocation of 64K objects, at the expense of compression ratio, compile
+ the library with -DMAX_WBITS=14 (see zconf.h).
+
+ The fields total_in and total_out can be used for statistics or progress
+ reports. After compression, total_in holds the total size of the
+ uncompressed data and may be saved for use in the decompressor (particularly
+ if the decompressor wants to decompress everything in a single step).
+*/
+
+ /* constants */
+
+#define Z_NO_FLUSH 0
+#define Z_PARTIAL_FLUSH 1
+#define Z_SYNC_FLUSH 2
+#define Z_FULL_FLUSH 3
+#define Z_FINISH 4
+#define Z_BLOCK 5
+#define Z_TREES 6
+/* Allowed flush values; see deflate() and inflate() below for details */
+
+#define Z_OK 0
+#define Z_STREAM_END 1
+#define Z_NEED_DICT 2
+#define Z_ERRNO (-1)
+#define Z_STREAM_ERROR (-2)
+#define Z_DATA_ERROR (-3)
+#define Z_MEM_ERROR (-4)
+#define Z_BUF_ERROR (-5)
+#define Z_VERSION_ERROR (-6)
+/* Return codes for the compression/decompression functions. Negative values
+ * are errors, positive values are used for special but normal events.
+ */
+
+#define Z_NO_COMPRESSION 0
+#define Z_BEST_SPEED 1
+#define Z_BEST_COMPRESSION 9
+#define Z_DEFAULT_COMPRESSION (-1)
+/* compression levels */
+
+#define Z_FILTERED 1
+#define Z_HUFFMAN_ONLY 2
+#define Z_RLE 3
+#define Z_FIXED 4
+#define Z_DEFAULT_STRATEGY 0
+/* compression strategy; see deflateInit2() below for details */
+
+#define Z_BINARY 0
+#define Z_TEXT 1
+#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */
+#define Z_UNKNOWN 2
+/* Possible values of the data_type field (though see inflate()) */
+
+#define Z_DEFLATED 8
+/* The deflate compression method (the only one supported in this version) */
+
+#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
+
+#define zlib_version zlibVersion()
+/* for compatibility with versions < 1.0.2 */
+
+
+ /* basic functions */
+
+ZEXTERN const char * ZEXPORT zlibVersion OF((void));
+/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
+ If the first character differs, the library code actually used is not
+ compatible with the zlib.h header file used by the application. This check
+ is automatically made by deflateInit and inflateInit.
+ */
+
+/*
+ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
+
+ Initializes the internal stream state for compression. The fields
+ zalloc, zfree and opaque must be initialized before by the caller. If
+ zalloc and zfree are set to Z_NULL, deflateInit updates them to use default
+ allocation functions.
+
+ The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
+ 1 gives best speed, 9 gives best compression, 0 gives no compression at all
+ (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION
+ requests a default compromise between speed and compression (currently
+ equivalent to level 6).
+
+ deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_STREAM_ERROR if level is not a valid compression level, or
+ Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
+ with the version assumed by the caller (ZLIB_VERSION). msg is set to null
+ if there is no error message. deflateInit does not perform any compression:
+ this will be done by deflate().
+*/
+
+
+ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
+/*
+ deflate compresses as much data as possible, and stops when the input
+ buffer becomes empty or the output buffer becomes full. It may introduce
+ some output latency (reading input without producing any output) except when
+ forced to flush.
+
+ The detailed semantics are as follows. deflate performs one or both of the
+ following actions:
+
+ - Compress more input starting at next_in and update next_in and avail_in
+ accordingly. If not all input can be processed (because there is not
+ enough room in the output buffer), next_in and avail_in are updated and
+ processing will resume at this point for the next call of deflate().
+
+ - Provide more output starting at next_out and update next_out and avail_out
+ accordingly. This action is forced if the parameter flush is non zero.
+ Forcing flush frequently degrades the compression ratio, so this parameter
+ should be set only when necessary (in interactive applications). Some
+ output may be provided even if flush is not set.
+
+ Before the call of deflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming more
+ output, and updating avail_in or avail_out accordingly; avail_out should
+ never be zero before the call. The application can consume the compressed
+ output when it wants, for example when the output buffer is full (avail_out
+ == 0), or after each call of deflate(). If deflate returns Z_OK and with
+ zero avail_out, it must be called again after making room in the output
+ buffer because there might be more output pending.
+
+ Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
+ decide how much data to accumulate before producing output, in order to
+ maximize compression.
+
+ If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
+ flushed to the output buffer and the output is aligned on a byte boundary, so
+ that the decompressor can get all input data available so far. (In
+ particular avail_in is zero after the call if enough output space has been
+ provided before the call.) Flushing may degrade compression for some
+ compression algorithms and so it should be used only when necessary. This
+ completes the current deflate block and follows it with an empty stored block
+ that is three bits plus filler bits to the next byte, followed by four bytes
+ (00 00 ff ff).
+
+ If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the
+ output buffer, but the output is not aligned to a byte boundary. All of the
+ input data so far will be available to the decompressor, as for Z_SYNC_FLUSH.
+ This completes the current deflate block and follows it with an empty fixed
+ codes block that is 10 bits long. This assures that enough bytes are output
+ in order for the decompressor to finish the block before the empty fixed code
+ block.
+
+ If flush is set to Z_BLOCK, a deflate block is completed and emitted, as
+ for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to
+ seven bits of the current block are held to be written as the next byte after
+ the next deflate block is completed. In this case, the decompressor may not
+ be provided enough bits at this point in order to complete decompression of
+ the data provided so far to the compressor. It may need to wait for the next
+ block to be emitted. This is for advanced applications that need to control
+ the emission of deflate blocks.
+
+ If flush is set to Z_FULL_FLUSH, all output is flushed as with
+ Z_SYNC_FLUSH, and the compression state is reset so that decompression can
+ restart from this point if previous compressed data has been damaged or if
+ random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
+ compression.
+
+ If deflate returns with avail_out == 0, this function must be called again
+ with the same value of the flush parameter and more output space (updated
+ avail_out), until the flush is complete (deflate returns with non-zero
+ avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
+ avail_out is greater than six to avoid repeated flush markers due to
+ avail_out == 0 on return.
+
+ If the parameter flush is set to Z_FINISH, pending input is processed,
+ pending output is flushed and deflate returns with Z_STREAM_END if there was
+ enough output space; if deflate returns with Z_OK, this function must be
+ called again with Z_FINISH and more output space (updated avail_out) but no
+ more input data, until it returns with Z_STREAM_END or an error. After
+ deflate has returned Z_STREAM_END, the only possible operations on the stream
+ are deflateReset or deflateEnd.
+
+ Z_FINISH can be used immediately after deflateInit if all the compression
+ is to be done in a single step. In this case, avail_out must be at least the
+ value returned by deflateBound (see below). Then deflate is guaranteed to
+ return Z_STREAM_END. If not enough output space is provided, deflate will
+ not return Z_STREAM_END, and it must be called again as described above.
+
+ deflate() sets strm->adler to the adler32 checksum of all input read
+ so far (that is, total_in bytes).
+
+ deflate() may update strm->data_type if it can make a good guess about
+ the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered
+ binary. This field is only for information purposes and does not affect the
+ compression algorithm in any manner.
+
+ deflate() returns Z_OK if some progress has been made (more input
+ processed or more output produced), Z_STREAM_END if all input has been
+ consumed and all output has been produced (only when flush is set to
+ Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
+ if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible
+ (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not
+ fatal, and deflate() can be called again with more input and more output
+ space to continue compressing.
+*/
+
+
+ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
+/*
+ All dynamically allocated data structures for this stream are freed.
+ This function discards any unprocessed input and does not flush any pending
+ output.
+
+ deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
+ stream state was inconsistent, Z_DATA_ERROR if the stream was freed
+ prematurely (some input or output was discarded). In the error case, msg
+ may be set but then points to a static string (which must not be
+ deallocated).
+*/
+
+
+/*
+ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
+
+ Initializes the internal stream state for decompression. The fields
+ next_in, avail_in, zalloc, zfree and opaque must be initialized before by
+ the caller. If next_in is not Z_NULL and avail_in is large enough (the
+ exact value depends on the compression method), inflateInit determines the
+ compression method from the zlib header and allocates all data structures
+ accordingly; otherwise the allocation will be deferred to the first call of
+ inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
+ use default allocation functions.
+
+ inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+ version assumed by the caller, or Z_STREAM_ERROR if the parameters are
+ invalid, such as a null pointer to the structure. msg is set to null if
+ there is no error message. inflateInit does not perform any decompression
+ apart from possibly reading the zlib header if present: actual decompression
+ will be done by inflate(). (So next_in and avail_in may be modified, but
+ next_out and avail_out are unused and unchanged.) The current implementation
+ of inflateInit() does not process any header information -- that is deferred
+ until inflate() is called.
+*/
+
+
+ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
+/*
+ inflate decompresses as much data as possible, and stops when the input
+ buffer becomes empty or the output buffer becomes full. It may introduce
+ some output latency (reading input without producing any output) except when
+ forced to flush.
+
+ The detailed semantics are as follows. inflate performs one or both of the
+ following actions:
+
+ - Decompress more input starting at next_in and update next_in and avail_in
+ accordingly. If not all input can be processed (because there is not
+ enough room in the output buffer), next_in is updated and processing will
+ resume at this point for the next call of inflate().
+
+ - Provide more output starting at next_out and update next_out and avail_out
+ accordingly. inflate() provides as much output as possible, until there is
+ no more input data or no more space in the output buffer (see below about
+ the flush parameter).
+
+ Before the call of inflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming more
+ output, and updating the next_* and avail_* values accordingly. The
+ application can consume the uncompressed output when it wants, for example
+ when the output buffer is full (avail_out == 0), or after each call of
+ inflate(). If inflate returns Z_OK and with zero avail_out, it must be
+ called again after making room in the output buffer because there might be
+ more output pending.
+
+ The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH,
+ Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much
+ output as possible to the output buffer. Z_BLOCK requests that inflate()
+ stop if and when it gets to the next deflate block boundary. When decoding
+ the zlib or gzip format, this will cause inflate() to return immediately
+ after the header and before the first block. When doing a raw inflate,
+ inflate() will go ahead and process the first block, and will return when it
+ gets to the end of that block, or when it runs out of data.
+
+ The Z_BLOCK option assists in appending to or combining deflate streams.
+ Also to assist in this, on return inflate() will set strm->data_type to the
+ number of unused bits in the last byte taken from strm->next_in, plus 64 if
+ inflate() is currently decoding the last block in the deflate stream, plus
+ 128 if inflate() returned immediately after decoding an end-of-block code or
+ decoding the complete header up to just before the first byte of the deflate
+ stream. The end-of-block will not be indicated until all of the uncompressed
+ data from that block has been written to strm->next_out. The number of
+ unused bits may in general be greater than seven, except when bit 7 of
+ data_type is set, in which case the number of unused bits will be less than
+ eight. data_type is set as noted here every time inflate() returns for all
+ flush options, and so can be used to determine the amount of currently
+ consumed input in bits.
+
+ The Z_TREES option behaves as Z_BLOCK does, but it also returns when the
+ end of each deflate block header is reached, before any actual data in that
+ block is decoded. This allows the caller to determine the length of the
+ deflate block header for later use in random access within a deflate block.
+ 256 is added to the value of strm->data_type when inflate() returns
+ immediately after reaching the end of the deflate block header.
+
+ inflate() should normally be called until it returns Z_STREAM_END or an
+ error. However if all decompression is to be performed in a single step (a
+ single call of inflate), the parameter flush should be set to Z_FINISH. In
+ this case all pending input is processed and all pending output is flushed;
+ avail_out must be large enough to hold all of the uncompressed data for the
+ operation to complete. (The size of the uncompressed data may have been
+ saved by the compressor for this purpose.) The use of Z_FINISH is not
+ required to perform an inflation in one step. However it may be used to
+ inform inflate that a faster approach can be used for the single inflate()
+ call. Z_FINISH also informs inflate to not maintain a sliding window if the
+ stream completes, which reduces inflate's memory footprint. If the stream
+ does not complete, either because not all of the stream is provided or not
+ enough output space is provided, then a sliding window will be allocated and
+ inflate() can be called again to continue the operation as if Z_NO_FLUSH had
+ been used.
+
+ In this implementation, inflate() always flushes as much output as
+ possible to the output buffer, and always uses the faster approach on the
+ first call. So the effects of the flush parameter in this implementation are
+ on the return value of inflate() as noted below, when inflate() returns early
+ when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of
+ memory for a sliding window when Z_FINISH is used.
+
+ If a preset dictionary is needed after this call (see inflateSetDictionary
+ below), inflate sets strm->adler to the Adler-32 checksum of the dictionary
+ chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
+ strm->adler to the Adler-32 checksum of all output produced so far (that is,
+ total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
+ below. At the end of the stream, inflate() checks that its computed adler32
+ checksum is equal to that saved by the compressor and returns Z_STREAM_END
+ only if the checksum is correct.
+
+ inflate() can decompress and check either zlib-wrapped or gzip-wrapped
+ deflate data. The header type is detected automatically, if requested when
+ initializing with inflateInit2(). Any information contained in the gzip
+ header is not retained, so applications that need that information should
+ instead use raw inflate, see inflateInit2() below, or inflateBack() and
+ perform their own processing of the gzip header and trailer. When processing
+ gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output
+ producted so far. The CRC-32 is checked against the gzip trailer.
+
+ inflate() returns Z_OK if some progress has been made (more input processed
+ or more output produced), Z_STREAM_END if the end of the compressed data has
+ been reached and all uncompressed output has been produced, Z_NEED_DICT if a
+ preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
+ corrupted (input stream not conforming to the zlib format or incorrect check
+ value), Z_STREAM_ERROR if the stream structure was inconsistent (for example
+ next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory,
+ Z_BUF_ERROR if no progress is possible or if there was not enough room in the
+ output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
+ inflate() can be called again with more input and more output space to
+ continue decompressing. If Z_DATA_ERROR is returned, the application may
+ then call inflateSync() to look for a good compression block if a partial
+ recovery of the data is desired.
+*/
+
+
+ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
+/*
+ All dynamically allocated data structures for this stream are freed.
+ This function discards any unprocessed input and does not flush any pending
+ output.
+
+ inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
+ was inconsistent. In the error case, msg may be set but then points to a
+ static string (which must not be deallocated).
+*/
+
+
+ /* Advanced functions */
+
+/*
+ The following functions are needed only in some special applications.
+*/
+
+/*
+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
+ int level,
+ int method,
+ int windowBits,
+ int memLevel,
+ int strategy));
+
+ This is another version of deflateInit with more compression options. The
+ fields next_in, zalloc, zfree and opaque must be initialized before by the
+ caller.
+
+ The method parameter is the compression method. It must be Z_DEFLATED in
+ this version of the library.
+
+ The windowBits parameter is the base two logarithm of the window size
+ (the size of the history buffer). It should be in the range 8..15 for this
+ version of the library. Larger values of this parameter result in better
+ compression at the expense of memory usage. The default value is 15 if
+ deflateInit is used instead.
+
+ windowBits can also be -8..-15 for raw deflate. In this case, -windowBits
+ determines the window size. deflate() will then generate raw deflate data
+ with no zlib header or trailer, and will not compute an adler32 check value.
+
+ windowBits can also be greater than 15 for optional gzip encoding. Add
+ 16 to windowBits to write a simple gzip header and trailer around the
+ compressed data instead of a zlib wrapper. The gzip header will have no
+ file name, no extra data, no comment, no modification time (set to zero), no
+ header crc, and the operating system will be set to 255 (unknown). If a
+ gzip stream is being written, strm->adler is a crc32 instead of an adler32.
+
+ The memLevel parameter specifies how much memory should be allocated
+ for the internal compression state. memLevel=1 uses minimum memory but is
+ slow and reduces compression ratio; memLevel=9 uses maximum memory for
+ optimal speed. The default value is 8. See zconf.h for total memory usage
+ as a function of windowBits and memLevel.
+
+ The strategy parameter is used to tune the compression algorithm. Use the
+ value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
+ filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
+ string match), or Z_RLE to limit match distances to one (run-length
+ encoding). Filtered data consists mostly of small values with a somewhat
+ random distribution. In this case, the compression algorithm is tuned to
+ compress them better. The effect of Z_FILTERED is to force more Huffman
+ coding and less string matching; it is somewhat intermediate between
+ Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as
+ fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The
+ strategy parameter only affects the compression ratio but not the
+ correctness of the compressed output even if it is not set appropriately.
+ Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler
+ decoder for special applications.
+
+ deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid
+ method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is
+ incompatible with the version assumed by the caller (ZLIB_VERSION). msg is
+ set to null if there is no error message. deflateInit2 does not perform any
+ compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
+ const Bytef *dictionary,
+ uInt dictLength));
+/*
+ Initializes the compression dictionary from the given byte sequence
+ without producing any compressed output. When using the zlib format, this
+ function must be called immediately after deflateInit, deflateInit2 or
+ deflateReset, and before any call of deflate. When doing raw deflate, this
+ function must be called either before any call of deflate, or immediately
+ after the completion of a deflate block, i.e. after all input has been
+ consumed and all output has been delivered when using any of the flush
+ options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The
+ compressor and decompressor must use exactly the same dictionary (see
+ inflateSetDictionary).
+
+ The dictionary should consist of strings (byte sequences) that are likely
+ to be encountered later in the data to be compressed, with the most commonly
+ used strings preferably put towards the end of the dictionary. Using a
+ dictionary is most useful when the data to be compressed is short and can be
+ predicted with good accuracy; the data can then be compressed better than
+ with the default empty dictionary.
+
+ Depending on the size of the compression data structures selected by
+ deflateInit or deflateInit2, a part of the dictionary may in effect be
+ discarded, for example if the dictionary is larger than the window size
+ provided in deflateInit or deflateInit2. Thus the strings most likely to be
+ useful should be put at the end of the dictionary, not at the front. In
+ addition, the current implementation of deflate will use at most the window
+ size minus 262 bytes of the provided dictionary.
+
+ Upon return of this function, strm->adler is set to the adler32 value
+ of the dictionary; the decompressor may later use this value to determine
+ which dictionary has been used by the compressor. (The adler32 value
+ applies to the whole dictionary even if only a subset of the dictionary is
+ actually used by the compressor.) If a raw deflate was requested, then the
+ adler32 value is not computed and strm->adler is not set.
+
+ deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
+ parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
+ inconsistent (for example if deflate has already been called for this stream
+ or if not at a block boundary for raw deflate). deflateSetDictionary does
+ not perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
+ z_streamp source));
+/*
+ Sets the destination stream as a complete copy of the source stream.
+
+ This function can be useful when several compression strategies will be
+ tried, for example when there are several ways of pre-processing the input
+ data with a filter. The streams that will be discarded should then be freed
+ by calling deflateEnd. Note that deflateCopy duplicates the internal
+ compression state which can be quite large, so this strategy is slow and can
+ consume lots of memory.
+
+ deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+ (such as zalloc being Z_NULL). msg is left unchanged in both source and
+ destination.
+*/
+
+ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
+/*
+ This function is equivalent to deflateEnd followed by deflateInit,
+ but does not free and reallocate all the internal compression state. The
+ stream will keep the same compression level and any other attributes that
+ may have been set by deflateInit2.
+
+ deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being Z_NULL).
+*/
+
+ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
+ int level,
+ int strategy));
+/*
+ Dynamically update the compression level and compression strategy. The
+ interpretation of level and strategy is as in deflateInit2. This can be
+ used to switch between compression and straight copy of the input data, or
+ to switch to a different kind of input data requiring a different strategy.
+ If the compression level is changed, the input available so far is
+ compressed with the old level (and may be flushed); the new level will take
+ effect only at the next call of deflate().
+
+ Before the call of deflateParams, the stream state must be set as for
+ a call of deflate(), since the currently available input may have to be
+ compressed and flushed. In particular, strm->avail_out must be non-zero.
+
+ deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
+ stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if
+ strm->avail_out was zero.
+*/
+
+ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
+ int good_length,
+ int max_lazy,
+ int nice_length,
+ int max_chain));
+/*
+ Fine tune deflate's internal compression parameters. This should only be
+ used by someone who understands the algorithm used by zlib's deflate for
+ searching for the best matching string, and even then only by the most
+ fanatic optimizer trying to squeeze out the last compressed bit for their
+ specific input data. Read the deflate.c source code for the meaning of the
+ max_lazy, good_length, nice_length, and max_chain parameters.
+
+ deflateTune() can be called after deflateInit() or deflateInit2(), and
+ returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
+ */
+
+ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
+ uLong sourceLen));
+/*
+ deflateBound() returns an upper bound on the compressed size after
+ deflation of sourceLen bytes. It must be called after deflateInit() or
+ deflateInit2(), and after deflateSetHeader(), if used. This would be used
+ to allocate an output buffer for deflation in a single pass, and so would be
+ called before deflate(). If that first deflate() call is provided the
+ sourceLen input bytes, an output buffer allocated to the size returned by
+ deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed
+ to return Z_STREAM_END. Note that it is possible for the compressed size to
+ be larger than the value returned by deflateBound() if flush options other
+ than Z_FINISH or Z_NO_FLUSH are used.
+*/
+
+ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm,
+ unsigned *pending,
+ int *bits));
+/*
+ deflatePending() returns the number of bytes and bits of output that have
+ been generated, but not yet provided in the available output. The bytes not
+ provided would be due to the available output space having being consumed.
+ The number of bits of output not provided are between 0 and 7, where they
+ await more bits to join them in order to fill out a full byte. If pending
+ or bits are Z_NULL, then those values are not set.
+
+ deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+ */
+
+ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
+ int bits,
+ int value));
+/*
+ deflatePrime() inserts bits in the deflate output stream. The intent
+ is that this function is used to start off the deflate output with the bits
+ leftover from a previous deflate stream when appending to it. As such, this
+ function can only be used for raw deflate, and must be used before the first
+ deflate() call after a deflateInit2() or deflateReset(). bits must be less
+ than or equal to 16, and that many of the least significant bits of value
+ will be inserted in the output.
+
+ deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough
+ room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the
+ source stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
+ gz_headerp head));
+/*
+ deflateSetHeader() provides gzip header information for when a gzip
+ stream is requested by deflateInit2(). deflateSetHeader() may be called
+ after deflateInit2() or deflateReset() and before the first call of
+ deflate(). The text, time, os, extra field, name, and comment information
+ in the provided gz_header structure are written to the gzip header (xflag is
+ ignored -- the extra flags are set according to the compression level). The
+ caller must assure that, if not Z_NULL, name and comment are terminated with
+ a zero byte, and that if extra is not Z_NULL, that extra_len bytes are
+ available there. If hcrc is true, a gzip header crc is included. Note that
+ the current versions of the command-line version of gzip (up through version
+ 1.3.x) do not support header crc's, and will report that it is a "multi-part
+ gzip file" and give up.
+
+ If deflateSetHeader is not used, the default gzip header has text false,
+ the time set to zero, and os set to 255, with no extra, name, or comment
+ fields. The gzip header is returned to the default state by deflateReset().
+
+ deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
+ int windowBits));
+
+ This is another version of inflateInit with an extra parameter. The
+ fields next_in, avail_in, zalloc, zfree and opaque must be initialized
+ before by the caller.
+
+ The windowBits parameter is the base two logarithm of the maximum window
+ size (the size of the history buffer). It should be in the range 8..15 for
+ this version of the library. The default value is 15 if inflateInit is used
+ instead. windowBits must be greater than or equal to the windowBits value
+ provided to deflateInit2() while compressing, or it must be equal to 15 if
+ deflateInit2() was not used. If a compressed stream with a larger window
+ size is given as input, inflate() will return with the error code
+ Z_DATA_ERROR instead of trying to allocate a larger window.
+
+ windowBits can also be zero to request that inflate use the window size in
+ the zlib header of the compressed stream.
+
+ windowBits can also be -8..-15 for raw inflate. In this case, -windowBits
+ determines the window size. inflate() will then process raw deflate data,
+ not looking for a zlib or gzip header, not generating a check value, and not
+ looking for any check values for comparison at the end of the stream. This
+ is for use with other formats that use the deflate compressed data format
+ such as zip. Those formats provide their own check values. If a custom
+ format is developed using the raw deflate format for compressed data, it is
+ recommended that a check value such as an adler32 or a crc32 be applied to
+ the uncompressed data as is done in the zlib, gzip, and zip formats. For
+ most applications, the zlib format should be used as is. Note that comments
+ above on the use in deflateInit2() applies to the magnitude of windowBits.
+
+ windowBits can also be greater than 15 for optional gzip decoding. Add
+ 32 to windowBits to enable zlib and gzip decoding with automatic header
+ detection, or add 16 to decode only the gzip format (the zlib format will
+ return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a
+ crc32 instead of an adler32.
+
+ inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+ version assumed by the caller, or Z_STREAM_ERROR if the parameters are
+ invalid, such as a null pointer to the structure. msg is set to null if
+ there is no error message. inflateInit2 does not perform any decompression
+ apart from possibly reading the zlib header if present: actual decompression
+ will be done by inflate(). (So next_in and avail_in may be modified, but
+ next_out and avail_out are unused and unchanged.) The current implementation
+ of inflateInit2() does not process any header information -- that is
+ deferred until inflate() is called.
+*/
+
+ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
+ const Bytef *dictionary,
+ uInt dictLength));
+/*
+ Initializes the decompression dictionary from the given uncompressed byte
+ sequence. This function must be called immediately after a call of inflate,
+ if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
+ can be determined from the adler32 value returned by that call of inflate.
+ The compressor and decompressor must use exactly the same dictionary (see
+ deflateSetDictionary). For raw inflate, this function can be called at any
+ time to set the dictionary. If the provided dictionary is smaller than the
+ window and there is already data in the window, then the provided dictionary
+ will amend what's there. The application must insure that the dictionary
+ that was used for compression is provided.
+
+ inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
+ parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
+ inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
+ expected one (incorrect adler32 value). inflateSetDictionary does not
+ perform any decompression: this will be done by subsequent calls of
+ inflate().
+*/
+
+ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm,
+ Bytef *dictionary,
+ uInt *dictLength));
+/*
+ Returns the sliding dictionary being maintained by inflate. dictLength is
+ set to the number of bytes in the dictionary, and that many bytes are copied
+ to dictionary. dictionary must have enough space, where 32768 bytes is
+ always enough. If inflateGetDictionary() is called with dictionary equal to
+ Z_NULL, then only the dictionary length is returned, and nothing is copied.
+ Similary, if dictLength is Z_NULL, then it is not set.
+
+ inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the
+ stream state is inconsistent.
+*/
+
+ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
+/*
+ Skips invalid compressed data until a possible full flush point (see above
+ for the description of deflate with Z_FULL_FLUSH) can be found, or until all
+ available input is skipped. No output is provided.
+
+ inflateSync searches for a 00 00 FF FF pattern in the compressed data.
+ All full flush points have this pattern, but not all occurrences of this
+ pattern are full flush points.
+
+ inflateSync returns Z_OK if a possible full flush point has been found,
+ Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point
+ has been found, or Z_STREAM_ERROR if the stream structure was inconsistent.
+ In the success case, the application may save the current current value of
+ total_in which indicates where valid compressed data was found. In the
+ error case, the application may repeatedly call inflateSync, providing more
+ input each time, until success or end of the input data.
+*/
+
+ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
+ z_streamp source));
+/*
+ Sets the destination stream as a complete copy of the source stream.
+
+ This function can be useful when randomly accessing a large stream. The
+ first pass through the stream can periodically record the inflate state,
+ allowing restarting inflate at those points when randomly accessing the
+ stream.
+
+ inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+ (such as zalloc being Z_NULL). msg is left unchanged in both source and
+ destination.
+*/
+
+ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
+/*
+ This function is equivalent to inflateEnd followed by inflateInit,
+ but does not free and reallocate all the internal decompression state. The
+ stream will keep attributes that may have been set by inflateInit2.
+
+ inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being Z_NULL).
+*/
+
+ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm,
+ int windowBits));
+/*
+ This function is the same as inflateReset, but it also permits changing
+ the wrap and window size requests. The windowBits parameter is interpreted
+ the same as it is for inflateInit2.
+
+ inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being Z_NULL), or if
+ the windowBits parameter is invalid.
+*/
+
+ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
+ int bits,
+ int value));
+/*
+ This function inserts bits in the inflate input stream. The intent is
+ that this function is used to start inflating at a bit position in the
+ middle of a byte. The provided bits will be used before any bytes are used
+ from next_in. This function should only be used with raw inflate, and
+ should be used before the first inflate() call after inflateInit2() or
+ inflateReset(). bits must be less than or equal to 16, and that many of the
+ least significant bits of value will be inserted in the input.
+
+ If bits is negative, then the input stream bit buffer is emptied. Then
+ inflatePrime() can be called again to put bits in the buffer. This is used
+ to clear out bits leftover after feeding inflate a block description prior
+ to feeding inflate codes.
+
+ inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm));
+/*
+ This function returns two values, one in the lower 16 bits of the return
+ value, and the other in the remaining upper bits, obtained by shifting the
+ return value down 16 bits. If the upper value is -1 and the lower value is
+ zero, then inflate() is currently decoding information outside of a block.
+ If the upper value is -1 and the lower value is non-zero, then inflate is in
+ the middle of a stored block, with the lower value equaling the number of
+ bytes from the input remaining to copy. If the upper value is not -1, then
+ it is the number of bits back from the current bit position in the input of
+ the code (literal or length/distance pair) currently being processed. In
+ that case the lower value is the number of bytes already emitted for that
+ code.
+
+ A code is being processed if inflate is waiting for more input to complete
+ decoding of the code, or if it has completed decoding but is waiting for
+ more output space to write the literal or match data.
+
+ inflateMark() is used to mark locations in the input data for random
+ access, which may be at bit positions, and to note those cases where the
+ output of a code may span boundaries of random access blocks. The current
+ location in the input stream can be determined from avail_in and data_type
+ as noted in the description for the Z_BLOCK flush parameter for inflate.
+
+ inflateMark returns the value noted above or -1 << 16 if the provided
+ source stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
+ gz_headerp head));
+/*
+ inflateGetHeader() requests that gzip header information be stored in the
+ provided gz_header structure. inflateGetHeader() may be called after
+ inflateInit2() or inflateReset(), and before the first call of inflate().
+ As inflate() processes the gzip stream, head->done is zero until the header
+ is completed, at which time head->done is set to one. If a zlib stream is
+ being decoded, then head->done is set to -1 to indicate that there will be
+ no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be
+ used to force inflate() to return immediately after header processing is
+ complete and before any actual data is decompressed.
+
+ The text, time, xflags, and os fields are filled in with the gzip header
+ contents. hcrc is set to true if there is a header CRC. (The header CRC
+ was valid if done is set to one.) If extra is not Z_NULL, then extra_max
+ contains the maximum number of bytes to write to extra. Once done is true,
+ extra_len contains the actual extra field length, and extra contains the
+ extra field, or that field truncated if extra_max is less than extra_len.
+ If name is not Z_NULL, then up to name_max characters are written there,
+ terminated with a zero unless the length is greater than name_max. If
+ comment is not Z_NULL, then up to comm_max characters are written there,
+ terminated with a zero unless the length is greater than comm_max. When any
+ of extra, name, or comment are not Z_NULL and the respective field is not
+ present in the header, then that field is set to Z_NULL to signal its
+ absence. This allows the use of deflateSetHeader() with the returned
+ structure to duplicate the header. However if those fields are set to
+ allocated memory, then the application will need to save those pointers
+ elsewhere so that they can be eventually freed.
+
+ If inflateGetHeader is not used, then the header information is simply
+ discarded. The header is always checked for validity, including the header
+ CRC if present. inflateReset() will reset the process to discard the header
+ information. The application would need to call inflateGetHeader() again to
+ retrieve the header from the next gzip stream.
+
+ inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
+ unsigned char FAR *window));
+
+ Initialize the internal stream state for decompression using inflateBack()
+ calls. The fields zalloc, zfree and opaque in strm must be initialized
+ before the call. If zalloc and zfree are Z_NULL, then the default library-
+ derived memory allocation routines are used. windowBits is the base two
+ logarithm of the window size, in the range 8..15. window is a caller
+ supplied buffer of that size. Except for special applications where it is
+ assured that deflate was used with small window sizes, windowBits must be 15
+ and a 32K byte window must be supplied to be able to decompress general
+ deflate streams.
+
+ See inflateBack() for the usage of these routines.
+
+ inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
+ the parameters are invalid, Z_MEM_ERROR if the internal state could not be
+ allocated, or Z_VERSION_ERROR if the version of the library does not match
+ the version of the header file.
+*/
+
+typedef unsigned (*in_func) OF((void FAR *,
+ z_const unsigned char FAR * FAR *));
+typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
+
+ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
+ in_func in, void FAR *in_desc,
+ out_func out, void FAR *out_desc));
+/*
+ inflateBack() does a raw inflate with a single call using a call-back
+ interface for input and output. This is potentially more efficient than
+ inflate() for file i/o applications, in that it avoids copying between the
+ output and the sliding window by simply making the window itself the output
+ buffer. inflate() can be faster on modern CPUs when used with large
+ buffers. inflateBack() trusts the application to not change the output
+ buffer passed by the output function, at least until inflateBack() returns.
+
+ inflateBackInit() must be called first to allocate the internal state
+ and to initialize the state with the user-provided window buffer.
+ inflateBack() may then be used multiple times to inflate a complete, raw
+ deflate stream with each call. inflateBackEnd() is then called to free the
+ allocated state.
+
+ A raw deflate stream is one with no zlib or gzip header or trailer.
+ This routine would normally be used in a utility that reads zip or gzip
+ files and writes out uncompressed files. The utility would decode the
+ header and process the trailer on its own, hence this routine expects only
+ the raw deflate stream to decompress. This is different from the normal
+ behavior of inflate(), which expects either a zlib or gzip header and
+ trailer around the deflate stream.
+
+ inflateBack() uses two subroutines supplied by the caller that are then
+ called by inflateBack() for input and output. inflateBack() calls those
+ routines until it reads a complete deflate stream and writes out all of the
+ uncompressed data, or until it encounters an error. The function's
+ parameters and return types are defined above in the in_func and out_func
+ typedefs. inflateBack() will call in(in_desc, &buf) which should return the
+ number of bytes of provided input, and a pointer to that input in buf. If
+ there is no input available, in() must return zero--buf is ignored in that
+ case--and inflateBack() will return a buffer error. inflateBack() will call
+ out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out()
+ should return zero on success, or non-zero on failure. If out() returns
+ non-zero, inflateBack() will return with an error. Neither in() nor out()
+ are permitted to change the contents of the window provided to
+ inflateBackInit(), which is also the buffer that out() uses to write from.
+ The length written by out() will be at most the window size. Any non-zero
+ amount of input may be provided by in().
+
+ For convenience, inflateBack() can be provided input on the first call by
+ setting strm->next_in and strm->avail_in. If that input is exhausted, then
+ in() will be called. Therefore strm->next_in must be initialized before
+ calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called
+ immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in
+ must also be initialized, and then if strm->avail_in is not zero, input will
+ initially be taken from strm->next_in[0 .. strm->avail_in - 1].
+
+ The in_desc and out_desc parameters of inflateBack() is passed as the
+ first parameter of in() and out() respectively when they are called. These
+ descriptors can be optionally used to pass any information that the caller-
+ supplied in() and out() functions need to do their job.
+
+ On return, inflateBack() will set strm->next_in and strm->avail_in to
+ pass back any unused input that was provided by the last in() call. The
+ return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
+ if in() or out() returned an error, Z_DATA_ERROR if there was a format error
+ in the deflate stream (in which case strm->msg is set to indicate the nature
+ of the error), or Z_STREAM_ERROR if the stream was not properly initialized.
+ In the case of Z_BUF_ERROR, an input or output error can be distinguished
+ using strm->next_in which will be Z_NULL only if in() returned an error. If
+ strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning
+ non-zero. (in() will always be called before out(), so strm->next_in is
+ assured to be defined if out() returns non-zero.) Note that inflateBack()
+ cannot return Z_OK.
+*/
+
+ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
+/*
+ All memory allocated by inflateBackInit() is freed.
+
+ inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream
+ state was inconsistent.
+*/
+
+ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
+/* Return flags indicating compile-time options.
+
+ Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
+ 1.0: size of uInt
+ 3.2: size of uLong
+ 5.4: size of voidpf (pointer)
+ 7.6: size of z_off_t
+
+ Compiler, assembler, and debug options:
+ 8: DEBUG
+ 9: ASMV or ASMINF -- use ASM code
+ 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
+ 11: 0 (reserved)
+
+ One-time table building (smaller code, but not thread-safe if true):
+ 12: BUILDFIXED -- build static block decoding tables when needed
+ 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed
+ 14,15: 0 (reserved)
+
+ Library content (indicates missing functionality):
+ 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking
+ deflate code when not needed)
+ 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect
+ and decode gzip streams (to avoid linking crc code)
+ 18-19: 0 (reserved)
+
+ Operation variations (changes in library functionality):
+ 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate
+ 21: FASTEST -- deflate algorithm with only one, lowest compression level
+ 22,23: 0 (reserved)
+
+ The sprintf variant used by gzprintf (zero is best):
+ 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format
+ 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!
+ 26: 0 = returns value, 1 = void -- 1 means inferred string length returned
+
+ Remainder:
+ 27-31: 0 (reserved)
+ */
+
+#ifndef Z_SOLO
+
+ /* utility functions */
+
+/*
+ The following utility functions are implemented on top of the basic
+ stream-oriented functions. To simplify the interface, some default options
+ are assumed (compression level and memory usage, standard memory allocation
+ functions). The source code of these utility functions can be modified if
+ you need special options.
+*/
+
+ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen));
+/*
+ Compresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total size
+ of the destination buffer, which must be at least the value returned by
+ compressBound(sourceLen). Upon exit, destLen is the actual size of the
+ compressed buffer.
+
+ compress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer.
+*/
+
+ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen,
+ int level));
+/*
+ Compresses the source buffer into the destination buffer. The level
+ parameter has the same meaning as in deflateInit. sourceLen is the byte
+ length of the source buffer. Upon entry, destLen is the total size of the
+ destination buffer, which must be at least the value returned by
+ compressBound(sourceLen). Upon exit, destLen is the actual size of the
+ compressed buffer.
+
+ compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+ Z_STREAM_ERROR if the level parameter is invalid.
+*/
+
+ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
+/*
+ compressBound() returns an upper bound on the compressed size after
+ compress() or compress2() on sourceLen bytes. It would be used before a
+ compress() or compress2() call to allocate the destination buffer.
+*/
+
+ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen));
+/*
+ Decompresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total size
+ of the destination buffer, which must be large enough to hold the entire
+ uncompressed data. (The size of the uncompressed data must have been saved
+ previously by the compressor and transmitted to the decompressor by some
+ mechanism outside the scope of this compression library.) Upon exit, destLen
+ is the actual size of the uncompressed buffer.
+
+ uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In
+ the case where there is not enough room, uncompress() will fill the output
+ buffer with the uncompressed data up to that point.
+*/
+
+ /* gzip file access functions */
+
+/*
+ This library supports reading and writing files in gzip (.gz) format with
+ an interface similar to that of stdio, using the functions that start with
+ "gz". The gzip format is different from the zlib format. gzip is a gzip
+ wrapper, documented in RFC 1952, wrapped around a deflate stream.
+*/
+
+typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */
+
+/*
+ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
+
+ Opens a gzip (.gz) file for reading or writing. The mode parameter is as
+ in fopen ("rb" or "wb") but can also include a compression level ("wb9") or
+ a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only
+ compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F'
+ for fixed code compression as in "wb9F". (See the description of
+ deflateInit2 for more information about the strategy parameter.) 'T' will
+ request transparent writing or appending with no compression and not using
+ the gzip format.
+
+ "a" can be used instead of "w" to request that the gzip stream that will
+ be written be appended to the file. "+" will result in an error, since
+ reading and writing to the same gzip file is not supported. The addition of
+ "x" when writing will create the file exclusively, which fails if the file
+ already exists. On systems that support it, the addition of "e" when
+ reading or writing will set the flag to close the file on an execve() call.
+
+ These functions, as well as gzip, will read and decode a sequence of gzip
+ streams in a file. The append function of gzopen() can be used to create
+ such a file. (Also see gzflush() for another way to do this.) When
+ appending, gzopen does not test whether the file begins with a gzip stream,
+ nor does it look for the end of the gzip streams to begin appending. gzopen
+ will simply append a gzip stream to the existing file.
+
+ gzopen can be used to read a file which is not in gzip format; in this
+ case gzread will directly read from the file without decompression. When
+ reading, this will be detected automatically by looking for the magic two-
+ byte gzip header.
+
+ gzopen returns NULL if the file could not be opened, if there was
+ insufficient memory to allocate the gzFile state, or if an invalid mode was
+ specified (an 'r', 'w', or 'a' was not provided, or '+' was provided).
+ errno can be checked to determine if the reason gzopen failed was that the
+ file could not be opened.
+*/
+
+ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
+/*
+ gzdopen associates a gzFile with the file descriptor fd. File descriptors
+ are obtained from calls like open, dup, creat, pipe or fileno (if the file
+ has been previously opened with fopen). The mode parameter is as in gzopen.
+
+ The next call of gzclose on the returned gzFile will also close the file
+ descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor
+ fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd,
+ mode);. The duplicated descriptor should be saved to avoid a leak, since
+ gzdopen does not close fd if it fails. If you are using fileno() to get the
+ file descriptor from a FILE *, then you will have to use dup() to avoid
+ double-close()ing the file descriptor. Both gzclose() and fclose() will
+ close the associated file descriptor, so they need to have different file
+ descriptors.
+
+ gzdopen returns NULL if there was insufficient memory to allocate the
+ gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not
+ provided, or '+' was provided), or if fd is -1. The file descriptor is not
+ used until the next gz* read, write, seek, or close operation, so gzdopen
+ will not detect if fd is invalid (unless fd is -1).
+*/
+
+ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size));
+/*
+ Set the internal buffer size used by this library's functions. The
+ default buffer size is 8192 bytes. This function must be called after
+ gzopen() or gzdopen(), and before any other calls that read or write the
+ file. The buffer memory allocation is always deferred to the first read or
+ write. Two buffers are allocated, either both of the specified size when
+ writing, or one of the specified size and the other twice that size when
+ reading. A larger buffer size of, for example, 64K or 128K bytes will
+ noticeably increase the speed of decompression (reading).
+
+ The new buffer size also affects the maximum length for gzprintf().
+
+ gzbuffer() returns 0 on success, or -1 on failure, such as being called
+ too late.
+*/
+
+ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
+/*
+ Dynamically update the compression level or strategy. See the description
+ of deflateInit2 for the meaning of these parameters.
+
+ gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
+ opened for writing.
+*/
+
+ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
+/*
+ Reads the given number of uncompressed bytes from the compressed file. If
+ the input file is not in gzip format, gzread copies the given number of
+ bytes into the buffer directly from the file.
+
+ After reaching the end of a gzip stream in the input, gzread will continue
+ to read, looking for another gzip stream. Any number of gzip streams may be
+ concatenated in the input file, and will all be decompressed by gzread().
+ If something other than a gzip stream is encountered after a gzip stream,
+ that remaining trailing garbage is ignored (and no error is returned).
+
+ gzread can be used to read a gzip file that is being concurrently written.
+ Upon reaching the end of the input, gzread will return with the available
+ data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then
+ gzclearerr can be used to clear the end of file indicator in order to permit
+ gzread to be tried again. Z_OK indicates that a gzip stream was completed
+ on the last gzread. Z_BUF_ERROR indicates that the input file ended in the
+ middle of a gzip stream. Note that gzread does not return -1 in the event
+ of an incomplete gzip stream. This error is deferred until gzclose(), which
+ will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip
+ stream. Alternatively, gzerror can be used before gzclose to detect this
+ case.
+
+ gzread returns the number of uncompressed bytes actually read, less than
+ len for end of file, or -1 for error.
+*/
+
+ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
+ voidpc buf, unsigned len));
+/*
+ Writes the given number of uncompressed bytes into the compressed file.
+ gzwrite returns the number of uncompressed bytes written or 0 in case of
+ error.
+*/
+
+ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...));
+/*
+ Converts, formats, and writes the arguments to the compressed file under
+ control of the format string, as in fprintf. gzprintf returns the number of
+ uncompressed bytes actually written, or 0 in case of error. The number of
+ uncompressed bytes written is limited to 8191, or one less than the buffer
+ size given to gzbuffer(). The caller should assure that this limit is not
+ exceeded. If it is exceeded, then gzprintf() will return an error (0) with
+ nothing written. In this case, there may also be a buffer overflow with
+ unpredictable consequences, which is possible only if zlib was compiled with
+ the insecure functions sprintf() or vsprintf() because the secure snprintf()
+ or vsnprintf() functions were not available. This can be determined using
+ zlibCompileFlags().
+*/
+
+ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
+/*
+ Writes the given null-terminated string to the compressed file, excluding
+ the terminating null character.
+
+ gzputs returns the number of characters written, or -1 in case of error.
+*/
+
+ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
+/*
+ Reads bytes from the compressed file until len-1 characters are read, or a
+ newline character is read and transferred to buf, or an end-of-file
+ condition is encountered. If any characters are read or if len == 1, the
+ string is terminated with a null character. If no characters are read due
+ to an end-of-file or len < 1, then the buffer is left untouched.
+
+ gzgets returns buf which is a null-terminated string, or it returns NULL
+ for end-of-file or in case of error. If there was an error, the contents at
+ buf are indeterminate.
+*/
+
+ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
+/*
+ Writes c, converted to an unsigned char, into the compressed file. gzputc
+ returns the value that was written, or -1 in case of error.
+*/
+
+ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
+/*
+ Reads one byte from the compressed file. gzgetc returns this byte or -1
+ in case of end of file or error. This is implemented as a macro for speed.
+ As such, it does not do all of the checking the other functions do. I.e.
+ it does not check to see if file is NULL, nor whether the structure file
+ points to has been clobbered or not.
+*/
+
+ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
+/*
+ Push one character back onto the stream to be read as the first character
+ on the next read. At least one character of push-back is allowed.
+ gzungetc() returns the character pushed, or -1 on failure. gzungetc() will
+ fail if c is -1, and may fail if a character has been pushed but not read
+ yet. If gzungetc is used immediately after gzopen or gzdopen, at least the
+ output buffer size of pushed characters is allowed. (See gzbuffer above.)
+ The pushed character will be discarded if the stream is repositioned with
+ gzseek() or gzrewind().
+*/
+
+ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
+/*
+ Flushes all pending output into the compressed file. The parameter flush
+ is as in the deflate() function. The return value is the zlib error number
+ (see function gzerror below). gzflush is only permitted when writing.
+
+ If the flush parameter is Z_FINISH, the remaining data is written and the
+ gzip stream is completed in the output. If gzwrite() is called again, a new
+ gzip stream will be started in the output. gzread() is able to read such
+ concatented gzip streams.
+
+ gzflush should be called only when strictly necessary because it will
+ degrade compression if called too often.
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
+ z_off_t offset, int whence));
+
+ Sets the starting position for the next gzread or gzwrite on the given
+ compressed file. The offset represents a number of bytes in the
+ uncompressed data stream. The whence parameter is defined as in lseek(2);
+ the value SEEK_END is not supported.
+
+ If the file is opened for reading, this function is emulated but can be
+ extremely slow. If the file is opened for writing, only forward seeks are
+ supported; gzseek then compresses a sequence of zeroes up to the new
+ starting position.
+
+ gzseek returns the resulting offset location as measured in bytes from
+ the beginning of the uncompressed stream, or -1 in case of error, in
+ particular if the file is opened for writing and the new starting position
+ would be before the current position.
+*/
+
+ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
+/*
+ Rewinds the given file. This function is supported only for reading.
+
+ gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
+
+ Returns the starting position for the next gzread or gzwrite on the given
+ compressed file. This position represents a number of bytes in the
+ uncompressed data stream, and is zero when starting, even if appending or
+ reading a gzip stream from the middle of a file using gzdopen().
+
+ gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file));
+
+ Returns the current offset in the file being read or written. This offset
+ includes the count of bytes that precede the gzip stream, for example when
+ appending or when using gzdopen() for reading. When reading, the offset
+ does not include as yet unused buffered input. This information can be used
+ for a progress indicator. On error, gzoffset() returns -1.
+*/
+
+ZEXTERN int ZEXPORT gzeof OF((gzFile file));
+/*
+ Returns true (1) if the end-of-file indicator has been set while reading,
+ false (0) otherwise. Note that the end-of-file indicator is set only if the
+ read tried to go past the end of the input, but came up short. Therefore,
+ just like feof(), gzeof() may return false even if there is no more data to
+ read, in the event that the last read request was for the exact number of
+ bytes remaining in the input file. This will happen if the input file size
+ is an exact multiple of the buffer size.
+
+ If gzeof() returns true, then the read functions will return no more data,
+ unless the end-of-file indicator is reset by gzclearerr() and the input file
+ has grown since the previous end of file was detected.
+*/
+
+ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
+/*
+ Returns true (1) if file is being copied directly while reading, or false
+ (0) if file is a gzip stream being decompressed.
+
+ If the input file is empty, gzdirect() will return true, since the input
+ does not contain a gzip stream.
+
+ If gzdirect() is used immediately after gzopen() or gzdopen() it will
+ cause buffers to be allocated to allow reading the file to determine if it
+ is a gzip file. Therefore if gzbuffer() is used, it should be called before
+ gzdirect().
+
+ When writing, gzdirect() returns true (1) if transparent writing was
+ requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note:
+ gzdirect() is not needed when writing. Transparent writing must be
+ explicitly requested, so the application already knows the answer. When
+ linking statically, using gzdirect() will include all of the zlib code for
+ gzip file reading and decompression, which may not be desired.)
+*/
+
+ZEXTERN int ZEXPORT gzclose OF((gzFile file));
+/*
+ Flushes all pending output if necessary, closes the compressed file and
+ deallocates the (de)compression state. Note that once file is closed, you
+ cannot call gzerror with file, since its structures have been deallocated.
+ gzclose must not be called more than once on the same file, just as free
+ must not be called more than once on the same allocation.
+
+ gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a
+ file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the
+ last read ended in the middle of a gzip stream, or Z_OK on success.
+*/
+
+ZEXTERN int ZEXPORT gzclose_r OF((gzFile file));
+ZEXTERN int ZEXPORT gzclose_w OF((gzFile file));
+/*
+ Same as gzclose(), but gzclose_r() is only for use when reading, and
+ gzclose_w() is only for use when writing or appending. The advantage to
+ using these instead of gzclose() is that they avoid linking in zlib
+ compression or decompression code that is not used when only reading or only
+ writing respectively. If gzclose() is used, then both compression and
+ decompression code will be included the application when linking to a static
+ zlib library.
+*/
+
+ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
+/*
+ Returns the error message for the last error which occurred on the given
+ compressed file. errnum is set to zlib error number. If an error occurred
+ in the file system and not in the compression library, errnum is set to
+ Z_ERRNO and the application may consult errno to get the exact error code.
+
+ The application must not modify the returned string. Future calls to
+ this function may invalidate the previously returned string. If file is
+ closed, then the string previously returned by gzerror will no longer be
+ available.
+
+ gzerror() should be used to distinguish errors from end-of-file for those
+ functions above that do not distinguish those cases in their return values.
+*/
+
+ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
+/*
+ Clears the error and end-of-file flags for file. This is analogous to the
+ clearerr() function in stdio. This is useful for continuing to read a gzip
+ file that is being written concurrently.
+*/
+
+#endif /* !Z_SOLO */
+
+ /* checksum functions */
+
+/*
+ These functions are not related to compression but are exported
+ anyway because they might be useful in applications using the compression
+ library.
+*/
+
+ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
+/*
+ Update a running Adler-32 checksum with the bytes buf[0..len-1] and
+ return the updated checksum. If buf is Z_NULL, this function returns the
+ required initial value for the checksum.
+
+ An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
+ much faster.
+
+ Usage example:
+
+ uLong adler = adler32(0L, Z_NULL, 0);
+
+ while (read_buffer(buffer, length) != EOF) {
+ adler = adler32(adler, buffer, length);
+ }
+ if (adler != original_adler) error();
+*/
+
+/*
+ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
+ z_off_t len2));
+
+ Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
+ and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
+ each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
+ seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note
+ that the z_off_t type (like off_t) is a signed integer. If len2 is
+ negative, the result has no meaning or utility.
+*/
+
+ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
+/*
+ Update a running CRC-32 with the bytes buf[0..len-1] and return the
+ updated CRC-32. If buf is Z_NULL, this function returns the required
+ initial value for the crc. Pre- and post-conditioning (one's complement) is
+ performed within this function so it shouldn't be done by the application.
+
+ Usage example:
+
+ uLong crc = crc32(0L, Z_NULL, 0);
+
+ while (read_buffer(buffer, length) != EOF) {
+ crc = crc32(crc, buffer, length);
+ }
+ if (crc != original_crc) error();
+*/
+
+/*
+ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
+
+ Combine two CRC-32 check values into one. For two sequences of bytes,
+ seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
+ calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32
+ check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
+ len2.
+*/
+
+
+ /* various hacks, don't look :) */
+
+/* deflateInit and inflateInit are macros to allow checking the zlib version
+ * and the compiler's view of z_stream:
+ */
+ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
+ int windowBits, int memLevel,
+ int strategy, const char *version,
+ int stream_size));
+ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
+ unsigned char FAR *window,
+ const char *version,
+ int stream_size));
+#define deflateInit(strm, level) \
+ deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream))
+#define inflateInit(strm) \
+ inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream))
+#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
+ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
+ (strategy), ZLIB_VERSION, (int)sizeof(z_stream))
+#define inflateInit2(strm, windowBits) \
+ inflateInit2_((strm), (windowBits), ZLIB_VERSION, \
+ (int)sizeof(z_stream))
+#define inflateBackInit(strm, windowBits, window) \
+ inflateBackInit_((strm), (windowBits), (window), \
+ ZLIB_VERSION, (int)sizeof(z_stream))
+
+#ifndef Z_SOLO
+
+/* gzgetc() macro and its supporting function and exposed data structure. Note
+ * that the real internal state is much larger than the exposed structure.
+ * This abbreviated structure exposes just enough for the gzgetc() macro. The
+ * user should not mess with these exposed elements, since their names or
+ * behavior could change in the future, perhaps even capriciously. They can
+ * only be used by the gzgetc() macro. You have been warned.
+ */
+struct gzFile_s {
+ unsigned have;
+ unsigned char *next;
+ z_off64_t pos;
+};
+ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */
+#ifdef Z_PREFIX_SET
+# undef z_gzgetc
+# define z_gzgetc(g) \
+ ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g))
+#else
+# define gzgetc(g) \
+ ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g))
+#endif
+
+/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or
+ * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if
+ * both are true, the application gets the *64 functions, and the regular
+ * functions are changed to 64 bits) -- in case these are set on systems
+ * without large file support, _LFS64_LARGEFILE must also be true
+ */
+#ifdef Z_LARGE64
+ ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+ ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
+ ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
+ ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
+ ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t));
+ ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t));
+#endif
+
+#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64)
+# ifdef Z_PREFIX_SET
+# define z_gzopen z_gzopen64
+# define z_gzseek z_gzseek64
+# define z_gztell z_gztell64
+# define z_gzoffset z_gzoffset64
+# define z_adler32_combine z_adler32_combine64
+# define z_crc32_combine z_crc32_combine64
+# else
+# define gzopen gzopen64
+# define gzseek gzseek64
+# define gztell gztell64
+# define gzoffset gzoffset64
+# define adler32_combine adler32_combine64
+# define crc32_combine crc32_combine64
+# endif
+# ifndef Z_LARGE64
+ ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+ ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int));
+ ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile));
+ ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile));
+ ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
+# endif
+#else
+ ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *));
+ ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int));
+ ZEXTERN z_off_t ZEXPORT gztell OF((gzFile));
+ ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile));
+ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
+#endif
+
+#else /* Z_SOLO */
+
+ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
+
+#endif /* !Z_SOLO */
+
+/* hack for buggy compilers */
+#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
+ struct internal_state {int dummy;};
+#endif
+
+/* undocumented functions */
+ZEXTERN const char * ZEXPORT zError OF((int));
+ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp));
+ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void));
+ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int));
+ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp));
+ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp));
+#if defined(_WIN32) && !defined(Z_SOLO)
+ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path,
+ const char *mode));
+#endif
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+# ifndef Z_SOLO
+ZEXTERN int ZEXPORTVA gzvprintf Z_ARG((gzFile file,
+ const char *format,
+ va_list va));
+# endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ZLIB_H */
diff --git a/frontend/cspace.c b/frontend/cspace.c
index 33a981d..55d4ac6 100644
--- a/frontend/cspace.c
+++ b/frontend/cspace.c
@@ -34,24 +34,46 @@ void bgr555_to_rgb565(void *dst_, const void *src_, int bytes)
#endif
+#ifdef __arm64__
+
+void bgr888_to_rgb565(void *dst_, const void *src_, int bytes)
+{
+ const unsigned char *src = src_;
+ unsigned int *dst = dst_;
+ unsigned int r1, g1, b1, r2, g2, b2;
+
+ for (; bytes >= 6; bytes -= 6, src += 6, dst++) {
+ r1 = src[0] & 0xf8;
+ g1 = src[1] & 0xfc;
+ b1 = src[2] & 0xf8;
+ r2 = src[3] & 0xf8;
+ g2 = src[4] & 0xfc;
+ b2 = src[5] & 0xf8;
+ *dst = (r2 << 24) | (g2 << 19) | (b2 << 13) |
+ (r1 << 8) | (g1 << 3) | (b1 >> 3);
+ }
+}
+
+#endif
+
#ifndef __ARM_NEON__
void bgr888_to_rgb565(void *dst_, const void *src_, int bytes)
{
- const unsigned char *src = src_;
- unsigned int *dst = dst_;
- unsigned int r1, g1, b1, r2, g2, b2;
-
- for (; bytes >= 6; bytes -= 6, src += 6, dst++) {
- r1 = src[0] & 0xf8;
- g1 = src[1] & 0xfc;
- b1 = src[2] & 0xf8;
- r2 = src[3] & 0xf8;
- g2 = src[4] & 0xfc;
- b2 = src[5] & 0xf8;
- *dst = (r2 << 24) | (g2 << 19) | (b2 << 13) |
- (r1 << 8) | (g1 << 3) | (b1 >> 3);
- }
+ const unsigned char *src = src_;
+ unsigned int *dst = dst_;
+ unsigned int r1, g1, b1, r2, g2, b2;
+
+ for (; bytes >= 6; bytes -= 6, src += 6, dst++) {
+ r1 = src[0] & 0xf8;
+ g1 = src[1] & 0xfc;
+ b1 = src[2] & 0xf8;
+ r2 = src[3] & 0xf8;
+ g2 = src[4] & 0xfc;
+ b2 = src[5] & 0xf8;
+ *dst = (r2 << 24) | (g2 << 19) | (b2 << 13) |
+ (r1 << 8) | (g1 << 3) | (b1 >> 3);
+ }
}
// TODO?
diff --git a/frontend/libpicofe b/frontend/libpicofe
deleted file mode 160000
-Subproject 21604a047941b8fe81d381ede0371c75da964af
diff --git a/frontend/libretro.c b/frontend/libretro.c
index 940ff05..cc443fe 100644
--- a/frontend/libretro.c
+++ b/frontend/libretro.c
@@ -15,6 +15,10 @@
#include <sys/syscall.h>
#endif
+#ifdef SWITCH
+#include <switch.h>
+#endif
+
#include "../libpcsxcore/misc.h"
#include "../libpcsxcore/psxcounters.h"
#include "../libpcsxcore/psxmem_map.h"
@@ -22,47 +26,147 @@
#include "../libpcsxcore/cdrom.h"
#include "../libpcsxcore/cdriso.h"
#include "../libpcsxcore/cheat.h"
+#include "../libpcsxcore/r3000a.h"
#include "../plugins/dfsound/out.h"
#include "../plugins/dfsound/spu_config.h"
#include "../plugins/dfinput/externals.h"
#include "cspace.h"
#include "main.h"
+#include "menu.h"
#include "plugin.h"
#include "plugin_lib.h"
#include "arm_features.h"
#include "revision.h"
-#include "libretro.h"
+
+#include <libretro.h>
+#include "libretro_core_options.h"
+
+#ifdef _3DS
+#include "3ds/3ds_utils.h"
+#endif
+
+#define PORTS_NUMBER 8
+
+#ifndef MIN
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif
+
+#ifndef MAX
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#endif
+
+#define ISHEXDEC ((buf[cursor]>='0') && (buf[cursor]<='9')) || ((buf[cursor]>='a') && (buf[cursor]<='f')) || ((buf[cursor]>='A') && (buf[cursor]<='F'))
+
+#define INTERNAL_FPS_SAMPLE_PERIOD 64
+
+#ifdef DRC_DISABLE
+int stop;
+u32 next_interupt;
+u32 event_cycles[PSXINT_COUNT];
+int cycle_multiplier;
+int new_dynarec_hacks;
+
+void new_dyna_before_save(void) { }
+void new_dyna_after_save(void) { }
+void new_dyna_freeze(void *f, int i) { }
+#endif
+
+//hack to prevent retroarch freezing when reseting in the menu but not while running with the hot key
+static int rebootemu = 0;
static retro_video_refresh_t video_cb;
static retro_input_poll_t input_poll_cb;
static retro_input_state_t input_state_cb;
static retro_environment_t environ_cb;
static retro_audio_sample_batch_t audio_batch_cb;
-static struct retro_rumble_interface rumble;
+static retro_set_rumble_state_t rumble_cb;
+static struct retro_log_callback logging;
+static retro_log_printf_t log_cb;
static void *vout_buf;
+static void * vout_buf_ptr;
static int vout_width, vout_height;
static int vout_doffs_old, vout_fb_dirty;
static bool vout_can_dupe;
static bool duping_enable;
+static bool found_bios;
+static bool display_internal_fps = false;
+static unsigned frame_count = 0;
+static bool libretro_supports_bitmasks = false;
+#ifdef GPU_PEOPS
+static int show_advanced_gpu_peops_settings = -1;
+#endif
+#ifdef GPU_UNAI
+static int show_advanced_gpu_unai_settings = -1;
+#endif
+
+static unsigned previous_width = 0;
+static unsigned previous_height = 0;
static int plugins_opened;
static int is_pal_mode;
/* memory card data */
extern char Mcd1Data[MCD_SIZE];
+extern char Mcd2Data[MCD_SIZE];
extern char McdDisable[2];
/* PCSX ReARMed core calls and stuff */
-int in_type1, in_type2;
-int in_a1[2] = { 127, 127 }, in_a2[2] = { 127, 127 };
-int in_keystate;
+int in_type[8] = { PSE_PAD_TYPE_NONE, PSE_PAD_TYPE_NONE,
+ PSE_PAD_TYPE_NONE, PSE_PAD_TYPE_NONE,
+ PSE_PAD_TYPE_NONE, PSE_PAD_TYPE_NONE,
+ PSE_PAD_TYPE_NONE, PSE_PAD_TYPE_NONE };
+int in_analog_left[8][2] = {{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 }};
+int in_analog_right[8][2] = {{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 }};
+unsigned short in_keystate[PORTS_NUMBER];
+int multitap1 = 0;
+int multitap2 = 0;
int in_enable_vibration = 1;
+// NegCon adjustment parameters
+// > The NegCon 'twist' action is somewhat awkward when mapped
+// to a standard analog stick -> user should be able to tweak
+// response/deadzone for comfort
+// > When response is linear, 'additional' deadzone (set here)
+// may be left at zero, since this is normally handled via in-game
+// options menus
+// > When response is non-linear, deadzone should be set to match the
+// controller being used (otherwise precision may be lost)
+// > negcon_linearity:
+// - 1: Response is linear - recommended when using racing wheel
+// peripherals, not recommended for standard gamepads
+// - 2: Response is quadratic - optimal setting for gamepads
+// - 3: Response is cubic - enables precise fine control, but
+// difficult to use...
+#define NEGCON_RANGE 0x7FFF
+static int negcon_deadzone = 0;
+static int negcon_linearity = 1;
+
+static bool axis_bounds_modifier;
+
/* PSX max resolution is 640x512, but with enhancement it's 1024x512 */
#define VOUT_MAX_WIDTH 1024
#define VOUT_MAX_HEIGHT 512
+//Dummy functions
+bool retro_load_game_special(unsigned game_type, const struct retro_game_info *info, size_t num_info){return false;}
+void retro_unload_game(void){}
+static int vout_open(void){return 0;}
+static void vout_close(void){}
+static int snd_init(void){return 0;}
+static void snd_finish(void){}
+static int snd_busy(void){return 0;}
+
+#define GPU_PEOPS_ODD_EVEN_BIT (1 << 0)
+#define GPU_PEOPS_EXPAND_SCREEN_WIDTH (1 << 1)
+#define GPU_PEOPS_IGNORE_BRIGHTNESS (1 << 2)
+#define GPU_PEOPS_DISABLE_COORD_CHECK (1 << 3)
+#define GPU_PEOPS_LAZY_SCREEN_UPDATE (1 << 6)
+#define GPU_PEOPS_OLD_FRAME_SKIP (1 << 7)
+#define GPU_PEOPS_REPEATED_TRIANGLES (1 << 8)
+#define GPU_PEOPS_QUADS_WITH_TRIANGLES (1 << 9)
+#define GPU_PEOPS_FAKE_BUSY_STATE (1 << 10)
+
static void init_memcard(char *mcd_data)
{
unsigned off = 0;
@@ -96,15 +200,36 @@ static void init_memcard(char *mcd_data)
}
}
-static int vout_open(void)
+static void set_vout_fb()
{
- return 0;
+ struct retro_framebuffer fb = {0};
+
+ fb.width = vout_width;
+ fb.height = vout_height;
+ fb.access_flags = RETRO_MEMORY_ACCESS_WRITE;
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_CURRENT_SOFTWARE_FRAMEBUFFER, &fb) && fb.format == RETRO_PIXEL_FORMAT_RGB565)
+ vout_buf_ptr = (uint16_t*)fb.data;
+ else
+ vout_buf_ptr = vout_buf;
}
static void vout_set_mode(int w, int h, int raw_w, int raw_h, int bpp)
{
- vout_width = w;
- vout_height = h;
+ vout_width = w;
+ vout_height = h;
+
+ if (previous_width != vout_width || previous_height != vout_height)
+ {
+ previous_width = vout_width;
+ previous_height = vout_height;
+
+ struct retro_system_av_info info;
+ retro_get_system_av_info(&info);
+ environ_cb(RETRO_ENVIRONMENT_SET_GEOMETRY, &info.geometry);
+ }
+
+ set_vout_fb();
}
#ifndef FRONTEND_SUPPORTS_RGB565
@@ -121,14 +246,14 @@ static void convert(void *buf, size_t bytes)
static void vout_flip(const void *vram, int stride, int bgr24, int w, int h)
{
- unsigned short *dest = vout_buf;
+ unsigned short *dest = vout_buf_ptr;
const unsigned short *src = vram;
int dstride = vout_width, h1 = h;
int doffs;
if (vram == NULL) {
// blanking
- memset(vout_buf, 0, dstride * h * 2);
+ memset(vout_buf_ptr, 0, dstride * h * 2);
goto out;
}
@@ -136,7 +261,7 @@ static void vout_flip(const void *vram, int stride, int bgr24, int w, int h)
doffs += (dstride - w) / 2 & ~1;
if (doffs != vout_doffs_old) {
// clear borders
- memset(vout_buf, 0, dstride * h * 2);
+ memset(vout_buf_ptr, 0, dstride * h * 2);
vout_doffs_old = doffs;
}
dest += doffs;
@@ -159,16 +284,173 @@ static void vout_flip(const void *vram, int stride, int bgr24, int w, int h)
out:
#ifndef FRONTEND_SUPPORTS_RGB565
- convert(vout_buf, vout_width * vout_height * 2);
+ convert(vout_buf_ptr, vout_width * vout_height * 2);
#endif
vout_fb_dirty = 1;
pl_rearmed_cbs.flip_cnt++;
}
-static void vout_close(void)
+#ifdef _3DS
+typedef struct
{
+ void* buffer;
+ uint32_t target_map;
+ size_t size;
+ enum psxMapTag tag;
+}psx_map_t;
+
+psx_map_t custom_psx_maps[] = {
+ {NULL, 0x13000000, 0x210000, MAP_TAG_RAM}, // 0x80000000
+ {NULL, 0x12800000, 0x010000, MAP_TAG_OTHER}, // 0x1f800000
+ {NULL, 0x12c00000, 0x080000, MAP_TAG_OTHER}, // 0x1fc00000
+ {NULL, 0x11000000, 0x800000, MAP_TAG_LUTS}, // 0x08000000
+ {NULL, 0x12000000, 0x200000, MAP_TAG_VRAM}, // 0x00000000
+};
+
+void* pl_3ds_mmap(unsigned long addr, size_t size, int is_fixed,
+ enum psxMapTag tag)
+{
+ (void)is_fixed;
+ (void)addr;
+
+ if (__ctr_svchax)
+ {
+ psx_map_t* custom_map = custom_psx_maps;
+
+ for (; custom_map->size; custom_map++)
+ {
+ if ((custom_map->size == size) && (custom_map->tag == tag))
+ {
+ uint32_t ptr_aligned, tmp;
+
+ custom_map->buffer = malloc(size + 0x1000);
+ ptr_aligned = (((u32)custom_map->buffer) + 0xFFF) & ~0xFFF;
+
+ if(svcControlMemory(&tmp, (void*)custom_map->target_map, (void*)ptr_aligned, size, MEMOP_MAP, 0x3) < 0)
+ {
+ SysPrintf("could not map memory @0x%08X\n", custom_map->target_map);
+ exit(1);
+ }
+
+ return (void*)custom_map->target_map;
+ }
+ }
+ }
+
+ return malloc(size);
+}
+
+void pl_3ds_munmap(void *ptr, size_t size, enum psxMapTag tag)
+{
+ (void)tag;
+
+ if (__ctr_svchax)
+ {
+ psx_map_t* custom_map = custom_psx_maps;
+
+ for (; custom_map->size; custom_map++)
+ {
+ if ((custom_map->target_map == (uint32_t)ptr))
+ {
+ uint32_t ptr_aligned, tmp;
+
+ ptr_aligned = (((u32)custom_map->buffer) + 0xFFF) & ~0xFFF;
+
+ svcControlMemory(&tmp, (void*)custom_map->target_map, (void*)ptr_aligned, size, MEMOP_UNMAP, 0x3);
+
+ free(custom_map->buffer);
+ custom_map->buffer = NULL;
+ return;
+ }
+ }
+ }
+
+ free(ptr);
+}
+#endif
+
+#ifdef VITA
+typedef struct
+{
+ void* buffer;
+ uint32_t target_map;
+ size_t size;
+ enum psxMapTag tag;
+}psx_map_t;
+
+void* addr = NULL;
+
+psx_map_t custom_psx_maps[] = {
+ {NULL, NULL, 0x210000, MAP_TAG_RAM}, // 0x80000000
+ {NULL, NULL, 0x010000, MAP_TAG_OTHER}, // 0x1f800000
+ {NULL, NULL, 0x080000, MAP_TAG_OTHER}, // 0x1fc00000
+ {NULL, NULL, 0x800000, MAP_TAG_LUTS}, // 0x08000000
+ {NULL, NULL, 0x200000, MAP_TAG_VRAM}, // 0x00000000
+};
+
+int init_vita_mmap(){
+ int n;
+ void * tmpaddr;
+ addr = malloc(64*1024*1024);
+ if(addr==NULL)
+ return -1;
+ tmpaddr = ((u32)(addr+0xFFFFFF))&~0xFFFFFF;
+ custom_psx_maps[0].buffer=tmpaddr+0x2000000;
+ custom_psx_maps[1].buffer=tmpaddr+0x1800000;
+ custom_psx_maps[2].buffer=tmpaddr+0x1c00000;
+ custom_psx_maps[3].buffer=tmpaddr+0x0000000;
+ custom_psx_maps[4].buffer=tmpaddr+0x1000000;
+#if 0
+ for(n = 0; n < 5; n++){
+ sceClibPrintf("addr reserved %x\n",custom_psx_maps[n].buffer);
+ }
+#endif
+ return 0;
+}
+
+void deinit_vita_mmap(){
+ free(addr);
}
+void* pl_vita_mmap(unsigned long addr, size_t size, int is_fixed,
+ enum psxMapTag tag)
+{
+ (void)is_fixed;
+ (void)addr;
+
+
+ psx_map_t* custom_map = custom_psx_maps;
+
+ for (; custom_map->size; custom_map++)
+ {
+ if ((custom_map->size == size) && (custom_map->tag == tag))
+ {
+ return custom_map->buffer;
+ }
+ }
+
+
+ return malloc(size);
+}
+
+void pl_vita_munmap(void *ptr, size_t size, enum psxMapTag tag)
+{
+ (void)tag;
+
+ psx_map_t* custom_map = custom_psx_maps;
+
+ for (; custom_map->size; custom_map++)
+ {
+ if ((custom_map->buffer == ptr))
+ {
+ return;
+ }
+ }
+
+ free(ptr);
+}
+#endif
+
static void *pl_mmap(unsigned int size)
{
return psxMap(0, size, 0, MAP_TAG_VRAM);
@@ -204,8 +486,14 @@ void pl_timing_prepare(int is_pal)
void plat_trigger_vibrate(int pad, int low, int high)
{
- rumble.set_rumble_state(pad, RETRO_RUMBLE_STRONG, high << 8);
- rumble.set_rumble_state(pad, RETRO_RUMBLE_WEAK, low ? 0xffff : 0x0);
+ if (!rumble_cb)
+ return;
+
+ if (in_enable_vibration)
+ {
+ rumble_cb(pad, RETRO_RUMBLE_STRONG, high << 8);
+ rumble_cb(pad, RETRO_RUMBLE_WEAK, low ? 0xffff : 0x0);
+ }
}
void pl_update_gun(int *xn, int *yn, int *xres, int *yres, int *in)
@@ -213,20 +501,6 @@ void pl_update_gun(int *xn, int *yn, int *xres, int *yres, int *in)
}
/* sound calls */
-static int snd_init(void)
-{
- return 0;
-}
-
-static void snd_finish(void)
-{
-}
-
-static int snd_busy(void)
-{
- return 0;
-}
-
static void snd_feed(void *buf, int bytes)
{
if (audio_batch_cb != NULL)
@@ -245,28 +519,12 @@ void out_register_libretro(struct out_driver *drv)
/* libretro */
void retro_set_environment(retro_environment_t cb)
{
- static const struct retro_variable vars[] = {
- { "pcsx_rearmed_frameskip", "Frameskip; 0|1|2|3" },
- { "pcsx_rearmed_region", "Region; Auto|NTSC|PAL" },
- { "pcsx_rearmed_pad1type", "Pad 1 Type; standard|analog" },
- { "pcsx_rearmed_pad2type", "Pad 2 Type; standard|analog" },
-#ifndef DRC_DISABLE
- { "pcsx_rearmed_drc", "Dynamic recompiler; enabled|disabled" },
-#endif
-#ifdef __ARM_NEON__
- { "pcsx_rearmed_neon_interlace_enable", "Enable interlacing mode(s); disabled|enabled" },
- { "pcsx_rearmed_neon_enhancement_enable", "Enhanced resolution (slow); disabled|enabled" },
- { "pcsx_rearmed_neon_enhancement_no_main", "Enhanced resolution speed hack; disabled|enabled" },
-#endif
- { "pcsx_rearmed_duping_enable", "Frame duping; on|off" },
- { "pcsx_rearmed_spu_reverb", "Sound: Reverb; on|off" },
- { "pcsx_rearmed_spu_interpolation", "Sound: Interpolation; simple|gaussian|cubic|off" },
- { NULL, NULL },
- };
-
environ_cb = cb;
- cb(RETRO_ENVIRONMENT_SET_VARIABLES, (void*)vars);
+ if (cb(RETRO_ENVIRONMENT_GET_LOG_INTERFACE, &logging))
+ log_cb = logging.log;
+
+ libretro_set_core_options(environ_cb);
}
void retro_set_video_refresh(retro_video_refresh_t cb) { video_cb = cb; }
@@ -280,34 +538,197 @@ unsigned retro_api_version(void)
return RETRO_API_VERSION;
}
+static int controller_port_variable(unsigned port, struct retro_variable *var)
+{
+ if (port >= PORTS_NUMBER)
+ return 0;
+
+ if (!environ_cb)
+ return 0;
+
+ var->value = NULL;
+ switch (port) {
+ case 0:
+ var->key = "pcsx_rearmed_pad1type";
+ break;
+ case 1:
+ var->key = "pcsx_rearmed_pad2type";
+ break;
+ case 2:
+ var->key = "pcsx_rearmed_pad3type";
+ break;
+ case 3:
+ var->key = "pcsx_rearmed_pad4type";
+ break;
+ case 4:
+ var->key = "pcsx_rearmed_pad5type";
+ break;
+ case 5:
+ var->key = "pcsx_rearmed_pad6type";
+ break;
+ case 6:
+ var->key = "pcsx_rearmed_pad7type";
+ break;
+ case 7:
+ var->key = "pcsx_rearmed_pad8type";
+ break;
+ }
+
+ return environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, var) || var->value;
+}
+
+static void update_controller_port_variable(unsigned port)
+{
+ if (port >= PORTS_NUMBER)
+ return;
+
+ struct retro_variable var;
+
+ if (controller_port_variable(port, &var))
+ {
+ if (strcmp(var.value, "standard") == 0)
+ in_type[port] = PSE_PAD_TYPE_STANDARD;
+ else if (strcmp(var.value, "analog") == 0)
+ in_type[port] = PSE_PAD_TYPE_ANALOGJOY;
+ else if (strcmp(var.value, "dualshock") == 0)
+ in_type[port] = PSE_PAD_TYPE_ANALOGPAD;
+ else if (strcmp(var.value, "negcon") == 0)
+ in_type[port] = PSE_PAD_TYPE_NEGCON;
+ else if (strcmp(var.value, "guncon") == 0)
+ in_type[port] = PSE_PAD_TYPE_GUNCON;
+ else if (strcmp(var.value, "none") == 0)
+ in_type[port] = PSE_PAD_TYPE_NONE;
+ // else 'default' case, do nothing
+ }
+}
+
+static void update_controller_port_device(unsigned port, unsigned device)
+{
+ if (port >= PORTS_NUMBER)
+ return;
+
+ struct retro_variable var;
+
+ if (!controller_port_variable(port, &var))
+ return;
+
+ if (strcmp(var.value, "default") != 0)
+ return;
+
+ switch (device)
+ {
+ case RETRO_DEVICE_JOYPAD:
+ in_type[port] = PSE_PAD_TYPE_STANDARD;
+ break;
+ case RETRO_DEVICE_ANALOG:
+ in_type[port] = PSE_PAD_TYPE_ANALOGPAD;
+ break;
+ case RETRO_DEVICE_MOUSE:
+ in_type[port] = PSE_PAD_TYPE_MOUSE;
+ break;
+ case RETRO_DEVICE_LIGHTGUN:
+ in_type[port] = PSE_PAD_TYPE_GUN;
+ break;
+ case RETRO_DEVICE_NONE:
+ default:
+ in_type[port] = PSE_PAD_TYPE_NONE;
+ }
+}
+
+static void update_multitap()
+{
+ struct retro_variable var;
+ int auto_case, port;
+
+ var.value = NULL;
+ var.key = "pcsx_rearmed_multitap1";
+ auto_case = 0;
+ if (environ_cb && (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value))
+ {
+ if (strcmp(var.value, "enabled") == 0)
+ multitap1 = 1;
+ else if (strcmp(var.value, "disabled") == 0)
+ multitap1 = 0;
+ else // 'auto' case
+ auto_case = 1;
+ }
+ else
+ auto_case = 1;
+
+ if (auto_case)
+ {
+ // If a gamepad is plugged after port 2, we need a first multitap.
+ multitap1 = 0;
+ for (port = 2; port < PORTS_NUMBER; port++)
+ multitap1 |= in_type[port] != PSE_PAD_TYPE_NONE;
+ }
+
+ var.value = NULL;
+ var.key = "pcsx_rearmed_multitap2";
+ auto_case = 0;
+ if (environ_cb && (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value))
+ {
+ if (strcmp(var.value, "enabled") == 0)
+ multitap2 = 1;
+ else if (strcmp(var.value, "disabled") == 0)
+ multitap2 = 0;
+ else // 'auto' case
+ auto_case = 1;
+ }
+ else
+ auto_case = 1;
+
+ if (auto_case)
+ {
+ // If a gamepad is plugged after port 4, we need a second multitap.
+ multitap2 = 0;
+ for (port = 4; port < PORTS_NUMBER; port++)
+ multitap2 |= in_type[port] != PSE_PAD_TYPE_NONE;
+ }
+}
+
void retro_set_controller_port_device(unsigned port, unsigned device)
{
+ SysPrintf("port %u device %u",port,device);
+
+ if (port >= PORTS_NUMBER)
+ return;
+
+ update_controller_port_device(port, device);
+ update_multitap();
}
void retro_get_system_info(struct retro_system_info *info)
{
memset(info, 0, sizeof(*info));
info->library_name = "PCSX-ReARMed";
- info->library_version = "r22";
- info->valid_extensions = "bin|cue|img|mdf|pbp|toc|cbn|m3u";
+#ifndef GIT_VERSION
+#define GIT_VERSION ""
+#endif
+ info->library_version = "r22" GIT_VERSION;
+ info->valid_extensions = "bin|cue|img|mdf|pbp|toc|cbn|m3u|chd";
info->need_fullpath = true;
}
void retro_get_system_av_info(struct retro_system_av_info *info)
{
+
+ unsigned geom_height = vout_height > 0 ? vout_height : 240;
+ unsigned geom_width = vout_width > 0 ? vout_width : 320;
+
memset(info, 0, sizeof(*info));
info->timing.fps = is_pal_mode ? 50 : 60;
info->timing.sample_rate = 44100;
- info->geometry.base_width = 320;
- info->geometry.base_height = 240;
+ info->geometry.base_width = geom_width;
+ info->geometry.base_height = geom_height;
info->geometry.max_width = VOUT_MAX_WIDTH;
info->geometry.max_height = VOUT_MAX_HEIGHT;
info->geometry.aspect_ratio = 4.0 / 3.0;
}
/* savestates */
-size_t retro_serialize_size(void)
-{
+size_t retro_serialize_size(void)
+{
// it's currently 4380651-4397047 bytes,
// but have some reserved for future
return 0x440000;
@@ -393,7 +814,7 @@ static void save_close(void *file)
}
bool retro_serialize(void *data, size_t size)
-{
+{
int ret = SaveState(data);
return ret == 0 ? true : false;
}
@@ -419,6 +840,21 @@ void retro_cheat_set(unsigned index, bool enabled, const char *code)
strncpy(buf, code, sizeof(buf));
buf[sizeof(buf) - 1] = 0;
+ //Prepare buffered cheat for PCSX's AddCheat fucntion.
+ int cursor=0;
+ int nonhexdec=0;
+ while (buf[cursor]){
+ if (!(ISHEXDEC)){
+ if (++nonhexdec%2){
+ buf[cursor]=' ';
+ } else {
+ buf[cursor]='\n';
+ }
+ }
+ cursor++;
+ }
+
+
if (index < NumCheats)
ret = EditCheat(index, "", buf);
else
@@ -430,15 +866,72 @@ void retro_cheat_set(unsigned index, bool enabled, const char *code)
Cheats[index].Enabled = enabled;
}
+// just in case, maybe a win-rt port in the future?
+#ifdef _WIN32
+#define SLASH '\\'
+#else
+#define SLASH '/'
+#endif
+
+#ifndef PATH_MAX
+#define PATH_MAX 4096
+#endif
+
/* multidisk support */
+static unsigned int disk_initial_index;
+static char disk_initial_path[PATH_MAX];
static bool disk_ejected;
static unsigned int disk_current_index;
static unsigned int disk_count;
static struct disks_state {
char *fname;
+ char *flabel;
int internal_index; // for multidisk eboots
} disks[8];
+static void get_disk_label(char *disk_label, const char *disk_path, size_t len)
+{
+ const char *base = NULL;
+
+ if (!disk_path || (*disk_path == '\0'))
+ return;
+
+ base = strrchr(disk_path, SLASH);
+ if (!base)
+ base = disk_path;
+
+ if (*base == SLASH)
+ base++;
+
+ strncpy(disk_label, base, len - 1);
+ disk_label[len - 1] = '\0';
+
+ char *ext = strrchr(disk_label, '.');
+ if (ext)
+ *ext = '\0';
+}
+
+static void disk_init(void)
+{
+ size_t i;
+
+ disk_ejected = false;
+ disk_current_index = 0;
+ disk_count = 0;
+
+ for (i = 0; i < sizeof(disks) / sizeof(disks[0]); i++) {
+ if (disks[i].fname != NULL) {
+ free(disks[i].fname);
+ disks[i].fname = NULL;
+ }
+ if (disks[i].flabel != NULL) {
+ free(disks[i].flabel);
+ disks[i].flabel = NULL;
+ }
+ disks[i].internal_index = 0;
+ }
+}
+
static bool disk_set_eject_state(bool ejected)
{
// weird PCSX API..
@@ -509,18 +1002,29 @@ static unsigned int disk_get_num_images(void)
static bool disk_replace_image_index(unsigned index,
const struct retro_game_info *info)
{
- char *old_fname;
- bool ret = true;
+ char *old_fname = NULL;
+ char *old_flabel = NULL;
+ bool ret = true;
if (index >= sizeof(disks) / sizeof(disks[0]))
return false;
- old_fname = disks[index].fname;
- disks[index].fname = NULL;
+ old_fname = disks[index].fname;
+ old_flabel = disks[index].flabel;
+
+ disks[index].fname = NULL;
+ disks[index].flabel = NULL;
disks[index].internal_index = 0;
if (info != NULL) {
+ char disk_label[PATH_MAX];
+ disk_label[0] = '\0';
+
disks[index].fname = strdup(info->path);
+
+ get_disk_label(disk_label, info->path, PATH_MAX);
+ disks[index].flabel = strdup(disk_label);
+
if (index == disk_current_index)
ret = disk_set_image_index(index);
}
@@ -528,6 +1032,9 @@ static bool disk_replace_image_index(unsigned index,
if (old_fname != NULL)
free(old_fname);
+ if (old_flabel != NULL)
+ free(old_flabel);
+
return ret;
}
@@ -540,6 +1047,64 @@ static bool disk_add_image_index(void)
return true;
}
+static bool disk_set_initial_image(unsigned index, const char *path)
+{
+ if (index >= sizeof(disks) / sizeof(disks[0]))
+ return false;
+
+ if (!path || (*path == '\0'))
+ return false;
+
+ disk_initial_index = index;
+
+ strncpy(disk_initial_path, path, sizeof(disk_initial_path) - 1);
+ disk_initial_path[sizeof(disk_initial_path) - 1] = '\0';
+
+ return true;
+}
+
+static bool disk_get_image_path(unsigned index, char *path, size_t len)
+{
+ const char *fname = NULL;
+
+ if (len < 1)
+ return false;
+
+ if (index >= sizeof(disks) / sizeof(disks[0]))
+ return false;
+
+ fname = disks[index].fname;
+
+ if (!fname || (*fname == '\0'))
+ return false;
+
+ strncpy(path, fname, len - 1);
+ path[len - 1] = '\0';
+
+ return true;
+}
+
+static bool disk_get_image_label(unsigned index, char *label, size_t len)
+{
+ const char *flabel = NULL;
+
+ if (len < 1)
+ return false;
+
+ if (index >= sizeof(disks) / sizeof(disks[0]))
+ return false;
+
+ flabel = disks[index].flabel;
+
+ if (!flabel || (*flabel == '\0'))
+ return false;
+
+ strncpy(label, flabel, len - 1);
+ label[len - 1] = '\0';
+
+ return true;
+}
+
static struct retro_disk_control_callback disk_control = {
.set_eject_state = disk_set_eject_state,
.get_eject_state = disk_get_eject_state,
@@ -550,18 +1115,24 @@ static struct retro_disk_control_callback disk_control = {
.add_image_index = disk_add_image_index,
};
-// just in case, maybe a win-rt port in the future?
-#ifdef _WIN32
-#define SLASH '\\'
-#else
-#define SLASH '/'
-#endif
+static struct retro_disk_control_ext_callback disk_control_ext = {
+ .set_eject_state = disk_set_eject_state,
+ .get_eject_state = disk_get_eject_state,
+ .get_image_index = disk_get_image_index,
+ .set_image_index = disk_set_image_index,
+ .get_num_images = disk_get_num_images,
+ .replace_image_index = disk_replace_image_index,
+ .add_image_index = disk_add_image_index,
+ .set_initial_image = disk_set_initial_image,
+ .get_image_path = disk_get_image_path,
+ .get_image_label = disk_get_image_label,
+};
-static char base_dir[PATH_MAX];
+static char base_dir[1024];
static bool read_m3u(const char *file)
{
- char line[PATH_MAX];
+ char line[1024];
char name[PATH_MAX];
FILE *f = fopen(file, "r");
if (!f)
@@ -579,8 +1150,16 @@ static bool read_m3u(const char *file)
if (line[0] != '\0')
{
+ char disk_label[PATH_MAX];
+ disk_label[0] = '\0';
+
snprintf(name, sizeof(name), "%s%c%s", base_dir, SLASH, line);
- disks[disk_count++].fname = strdup(name);
+ disks[disk_count].fname = strdup(name);
+
+ get_disk_label(disk_label, name, PATH_MAX);
+ disks[disk_count].flabel = strdup(disk_label);
+
+ disk_count++;
}
}
@@ -634,9 +1213,24 @@ strcasestr(const char *s, const char*find)
}
#endif
+static void set_retro_memmap(void)
+{
+ struct retro_memory_map retromap = { 0 };
+ struct retro_memory_descriptor mmap =
+ {
+ 0, psxM, 0, 0, 0, 0, 0x200000
+ };
+
+ retromap.descriptors = &mmap;
+ retromap.num_descriptors = 1;
+
+ environ_cb(RETRO_ENVIRONMENT_SET_MEMORY_MAPS, &retromap);
+}
+
bool retro_load_game(const struct retro_game_info *info)
{
size_t i;
+ unsigned int cd_index = 0;
bool is_m3u = (strcasestr(info->path, ".m3u") != NULL);
struct retro_input_descriptor desc[] = {
@@ -761,7 +1355,7 @@ bool retro_load_game(const struct retro_game_info *info)
{ 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "R2" },
{ 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3, "R3" },
{ 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select" },
- { 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" },
+ { 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" },
{ 5, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X, "Left Analog X" },
{ 5, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y, "Left Analog Y" },
{ 5, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X, "Right Analog X" },
@@ -782,7 +1376,7 @@ bool retro_load_game(const struct retro_game_info *info)
{ 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "R2" },
{ 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3, "R3" },
{ 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select" },
- { 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" },
+ { 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" },
{ 6, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X, "Left Analog X" },
{ 6, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y, "Left Analog Y" },
{ 6, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X, "Right Analog X" },
@@ -803,7 +1397,7 @@ bool retro_load_game(const struct retro_game_info *info)
{ 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "R2" },
{ 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3, "R3" },
{ 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select" },
- { 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" },
+ { 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" },
{ 7, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X, "Left Analog X" },
{ 7, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y, "Left Analog Y" },
{ 7, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X, "Right Analog X" },
@@ -812,6 +1406,8 @@ bool retro_load_game(const struct retro_game_info *info)
{ 0 },
};
+ frame_count = 0;
+
environ_cb(RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS, desc);
#ifdef FRONTEND_SUPPORTS_RGB565
@@ -831,32 +1427,44 @@ bool retro_load_game(const struct retro_game_info *info)
plugins_opened = 0;
}
- for (i = 0; i < sizeof(disks) / sizeof(disks[0]); i++) {
- if (disks[i].fname != NULL) {
- free(disks[i].fname);
- disks[i].fname = NULL;
- }
- disks[i].internal_index = 0;
- }
+ disk_init();
- disk_current_index = 0;
extract_directory(base_dir, info->path, sizeof(base_dir));
if (is_m3u) {
if (!read_m3u(info->path)) {
- SysPrintf("failed to read m3u file\n");
+ log_cb(RETRO_LOG_INFO, "failed to read m3u file\n");
return false;
}
} else {
+ char disk_label[PATH_MAX];
+ disk_label[0] = '\0';
+
disk_count = 1;
disks[0].fname = strdup(info->path);
+
+ get_disk_label(disk_label, info->path, PATH_MAX);
+ disks[0].flabel = strdup(disk_label);
}
- set_cd_image(disks[0].fname);
+ /* If this is an M3U file, attempt to set the
+ * initial disk image */
+ if (is_m3u &&
+ (disk_initial_index > 0) &&
+ (disk_initial_index < disk_count)) {
+ const char *fname = disks[disk_initial_index].fname;
+
+ if (fname && (*fname != '\0'))
+ if (strcmp(disk_initial_path, fname) == 0)
+ cd_index = disk_initial_index;
+ }
+
+ set_cd_image(disks[cd_index].fname);
+ disk_current_index = cd_index;
/* have to reload after set_cd_image for correct cdr plugin */
if (LoadPlugins() == -1) {
- SysPrintf("failed to load plugins\n");
+ log_cb(RETRO_LOG_INFO, "failed to load plugins\n");
return false;
}
@@ -864,48 +1472,94 @@ bool retro_load_game(const struct retro_game_info *info)
NetOpened = 0;
if (OpenPlugins() == -1) {
- SysPrintf("failed to open plugins\n");
+ log_cb(RETRO_LOG_INFO, "failed to open plugins\n");
return false;
}
+ /* Handle multi-disk images (i.e. PBP)
+ * > Cannot do this until after OpenPlugins() is
+ * called (since this sets the value of
+ * cdrIsoMultidiskCount) */
+ if (!is_m3u && (cdrIsoMultidiskCount > 1)) {
+ disk_count = cdrIsoMultidiskCount < 8 ? cdrIsoMultidiskCount : 8;
+
+ /* Small annoyance: We need to change the label
+ * of disk 0, so have to clear existing entries */
+ if (disks[0].fname != NULL)
+ free(disks[0].fname);
+ disks[0].fname = NULL;
+
+ if (disks[0].flabel != NULL)
+ free(disks[0].flabel);
+ disks[0].flabel = NULL;
+
+ for (i = 0; i < sizeof(disks) / sizeof(disks[0]) && i < cdrIsoMultidiskCount; i++) {
+ char disk_name[PATH_MAX];
+ char disk_label[PATH_MAX];
+ disk_name[0] = '\0';
+ disk_label[0] = '\0';
+
+ disks[i].fname = strdup(info->path);
+
+ get_disk_label(disk_name, info->path, PATH_MAX);
+ snprintf(disk_label, sizeof(disk_label), "%s #%u", disk_name, (unsigned)i + 1);
+ disks[i].flabel = strdup(disk_label);
+
+ disks[i].internal_index = i;
+ }
+
+ /* This is not an M3U file, so initial disk
+ * image has not yet been set - attempt to
+ * do so now */
+ if ((disk_initial_index > 0) &&
+ (disk_initial_index < disk_count)) {
+ const char *fname = disks[disk_initial_index].fname;
+
+ if (fname && (*fname != '\0'))
+ if (strcmp(disk_initial_path, fname) == 0)
+ cd_index = disk_initial_index;
+ }
+
+ if (cd_index > 0) {
+ CdromId[0] = '\0';
+ CdromLabel[0] = '\0';
+
+ cdrIsoMultidiskSelect = disks[cd_index].internal_index;
+ disk_current_index = cd_index;
+ set_cd_image(disks[cd_index].fname);
+
+ if (ReloadCdromPlugin() < 0) {
+ log_cb(RETRO_LOG_INFO, "failed to reload cdr plugins\n");
+ return false;
+ }
+ if (CDR_open() < 0) {
+ log_cb(RETRO_LOG_INFO, "failed to open cdr plugin\n");
+ return false;
+ }
+ }
+ }
+
plugin_call_rearmed_cbs();
dfinput_activate();
- Config.PsxAuto = 1;
if (CheckCdrom() == -1) {
- SysPrintf("unsupported/invalid CD image: %s\n", info->path);
+ log_cb(RETRO_LOG_INFO, "unsupported/invalid CD image: %s\n", info->path);
return false;
}
SysReset();
if (LoadCdrom() == -1) {
- SysPrintf("could not load CD-ROM!\n");
+ log_cb(RETRO_LOG_INFO, "could not load CD\n");
return false;
}
emu_on_new_cd(0);
- // multidisk images
- if (!is_m3u) {
- disk_count = cdrIsoMultidiskCount < 8 ? cdrIsoMultidiskCount : 8;
- for (i = 1; i < sizeof(disks) / sizeof(disks[0]) && i < cdrIsoMultidiskCount; i++) {
- disks[i].fname = strdup(info->path);
- disks[i].internal_index = i;
- }
- }
+ set_retro_memmap();
return true;
}
-bool retro_load_game_special(unsigned game_type, const struct retro_game_info *info, size_t num_info)
-{
- return false;
-}
-
-void retro_unload_game(void)
-{
-}
-
unsigned retro_get_region(void)
{
return is_pal_mode ? RETRO_REGION_PAL : RETRO_REGION_NTSC;
@@ -915,6 +1569,8 @@ void *retro_get_memory_data(unsigned id)
{
if (id == RETRO_MEMORY_SAVE_RAM)
return Mcd1Data;
+ else if (id == RETRO_MEMORY_SYSTEM_RAM)
+ return psxM;
else
return NULL;
}
@@ -923,13 +1579,17 @@ size_t retro_get_memory_size(unsigned id)
{
if (id == RETRO_MEMORY_SAVE_RAM)
return MCD_SIZE;
+ else if (id == RETRO_MEMORY_SYSTEM_RAM)
+ return 0x200000;
else
return 0;
}
void retro_reset(void)
{
- SysReset();
+ //hack to prevent retroarch freezing when reseting in the menu but not while running with the hot key
+ rebootemu = 1;
+ //SysReset();
}
static const unsigned short retro_psx_map[] = {
@@ -955,20 +1615,22 @@ static const unsigned short retro_psx_map[] = {
static void update_variables(bool in_flight)
{
struct retro_variable var;
-
+ int i;
+#ifdef GPU_PEOPS
+ int gpu_peops_fix = 0;
+#endif
+
var.value = NULL;
var.key = "pcsx_rearmed_frameskip";
-
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
pl_rearmed_cbs.frameskip = atoi(var.value);
var.value = NULL;
var.key = "pcsx_rearmed_region";
-
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
{
Config.PsxAuto = 0;
- if (strcmp(var.value, "Automatic") == 0)
+ if (strcmp(var.value, "auto") == 0)
Config.PsxAuto = 1;
else if (strcmp(var.value, "NTSC") == 0)
Config.PsxType = 0;
@@ -976,27 +1638,78 @@ static void update_variables(bool in_flight)
Config.PsxType = 1;
}
+ for (i = 0; i < PORTS_NUMBER; i++)
+ update_controller_port_variable(i);
+
+ update_multitap();
+
var.value = NULL;
- var.key = "pcsx_rearmed_pad1type";
+ var.key = "pcsx_rearmed_negcon_deadzone";
+ negcon_deadzone = 0;
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ negcon_deadzone = (int)(atoi(var.value) * 0.01f * NEGCON_RANGE);
+ }
+ var.value = NULL;
+ var.key = "pcsx_rearmed_negcon_response";
+ negcon_linearity = 1;
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
{
- in_type1 = PSE_PAD_TYPE_STANDARD;
- if (strcmp(var.value, "analog") == 0)
- in_type1 = PSE_PAD_TYPE_ANALOGPAD;
+ if (strcmp(var.value, "quadratic") == 0){
+ negcon_linearity = 2;
+ } else if (strcmp(var.value, "cubic") == 0){
+ negcon_linearity = 3;
+ }
}
var.value = NULL;
- var.key = "pcsx_rearmed_pad2type";
+ var.key = "pcsx_rearmed_analog_axis_modifier";
+ axis_bounds_modifier = true;
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ if (strcmp(var.value, "square") == 0) {
+ axis_bounds_modifier = true;
+ } else if (strcmp(var.value, "circle") == 0) {
+ axis_bounds_modifier = false;
+ }
+ }
+
+ var.value = NULL;
+ var.key = "pcsx_rearmed_vibration";
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
{
- in_type2 = PSE_PAD_TYPE_STANDARD;
- if (strcmp(var.value, "analog") == 0)
- in_type2 = PSE_PAD_TYPE_ANALOGPAD;
+ if (strcmp(var.value, "disabled") == 0)
+ in_enable_vibration = 0;
+ else if (strcmp(var.value, "enabled") == 0)
+ in_enable_vibration = 1;
}
+ var.value = NULL;
+ var.key = "pcsx_rearmed_dithering";
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ if (strcmp(var.value, "disabled") == 0) {
+ pl_rearmed_cbs.gpu_peops.iUseDither = 0;
+ pl_rearmed_cbs.gpu_peopsgl.bDrawDither = 0;
+ pl_rearmed_cbs.gpu_unai.dithering = 0;
#ifdef __ARM_NEON__
+ pl_rearmed_cbs.gpu_neon.allow_dithering = 0;
+#endif
+ }
+ else if (strcmp(var.value, "enabled") == 0) {
+ pl_rearmed_cbs.gpu_peops.iUseDither = 1;
+ pl_rearmed_cbs.gpu_peopsgl.bDrawDither = 1;
+ pl_rearmed_cbs.gpu_unai.dithering = 1;
+#ifdef __ARM_NEON__
+ pl_rearmed_cbs.gpu_neon.allow_dithering = 1;
+#endif
+ }
+ }
+
+#ifdef GPU_NEON
var.value = "NULL";
var.key = "pcsx_rearmed_neon_interlace_enable";
@@ -1036,12 +1749,23 @@ static void update_variables(bool in_flight)
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
{
- if (strcmp(var.value, "off") == 0)
+ if (strcmp(var.value, "disabled") == 0)
duping_enable = false;
- else if (strcmp(var.value, "on") == 0)
+ else if (strcmp(var.value, "enabled") == 0)
duping_enable = true;
}
+ var.value = "NULL";
+ var.key = "pcsx_rearmed_display_internal_fps";
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ if (strcmp(var.value, "disabled") == 0)
+ display_internal_fps = false;
+ else if (strcmp(var.value, "enabled") == 0)
+ display_internal_fps = true;
+ }
+
#ifndef DRC_DISABLE
var.value = NULL;
var.key = "pcsx_rearmed_drc";
@@ -1050,6 +1774,11 @@ static void update_variables(bool in_flight)
{
R3000Acpu *prev_cpu = psxCpu;
+#ifdef _3DS
+ if(!__ctr_svchax)
+ Config.Cpu = CPU_INTERPRETER;
+ else
+#endif
if (strcmp(var.value, "disabled") == 0)
Config.Cpu = CPU_INTERPRETER;
else if (strcmp(var.value, "enabled") == 0)
@@ -1069,9 +1798,9 @@ static void update_variables(bool in_flight)
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
{
- if (strcmp(var.value, "off") == 0)
+ if (strcmp(var.value, "disabled") == 0)
spu_config.iUseReverb = false;
- else if (strcmp(var.value, "on") == 0)
+ else if (strcmp(var.value, "enabled") == 0)
spu_config.iUseReverb = true;
}
@@ -1090,6 +1819,317 @@ static void update_variables(bool in_flight)
spu_config.iUseInterpolation = 0;
}
+ var.value = "NULL";
+ var.key = "pcsx_rearmed_pe2_fix";
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ if (strcmp(var.value, "disabled") == 0)
+ Config.RCntFix = 0;
+ else if (strcmp(var.value, "enabled") == 0)
+ Config.RCntFix = 1;
+ }
+
+ var.value = "NULL";
+ var.key = "pcsx_rearmed_idiablofix";
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ if (strcmp(var.value, "disabled") == 0)
+ spu_config.idiablofix = 0;
+ else if (strcmp(var.value, "enabled") == 0)
+ spu_config.idiablofix = 1;
+ }
+
+ var.value = "NULL";
+ var.key = "pcsx_rearmed_inuyasha_fix";
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ if (strcmp(var.value, "disabled") == 0)
+ Config.VSyncWA = 0;
+ else if (strcmp(var.value, "enabled") == 0)
+ Config.VSyncWA = 1;
+ }
+
+ var.value = NULL;
+ var.key = "pcsx_rearmed_noxadecoding";
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ if (strcmp(var.value, "disabled") == 0)
+ Config.Xa = 1;
+ else
+ Config.Xa = 0;
+ }
+
+ var.value = NULL;
+ var.key = "pcsx_rearmed_nocdaudio";
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ if (strcmp(var.value, "disabled") == 0)
+ Config.Cdda = 1;
+ else
+ Config.Cdda = 0;
+ }
+
+ var.value = NULL;
+ var.key = "pcsx_rearmed_spuirq";
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ if (strcmp(var.value, "disabled") == 0)
+ Config.SpuIrq = 0;
+ else
+ Config.SpuIrq = 1;
+ }
+
+#ifndef DRC_DISABLE
+ var.value = NULL;
+ var.key = "pcsx_rearmed_nosmccheck";
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ if (strcmp(var.value, "enabled") == 0)
+ new_dynarec_hacks |= NDHACK_NO_SMC_CHECK;
+ else
+ new_dynarec_hacks &= ~NDHACK_NO_SMC_CHECK;
+ }
+
+ var.value = NULL;
+ var.key = "pcsx_rearmed_gteregsunneeded";
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ if (strcmp(var.value, "enabled") == 0)
+ new_dynarec_hacks |= NDHACK_GTE_UNNEEDED;
+ else
+ new_dynarec_hacks &= ~NDHACK_GTE_UNNEEDED;
+ }
+
+ var.value = NULL;
+ var.key = "pcsx_rearmed_nogteflags";
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ if (strcmp(var.value, "enabled") == 0)
+ new_dynarec_hacks |= NDHACK_GTE_NO_FLAGS;
+ else
+ new_dynarec_hacks &= ~NDHACK_GTE_NO_FLAGS;
+ }
+#endif
+
+#ifdef GPU_PEOPS
+ var.value = "NULL";
+ var.key = "pcsx_rearmed_gpu_peops_odd_even_bit";
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
+ {
+ if (strcmp(var.value, "enabled") == 0)
+ gpu_peops_fix |= GPU_PEOPS_ODD_EVEN_BIT;
+ }
+
+ var.value = "NULL";
+ var.key = "pcsx_rearmed_gpu_peops_expand_screen_width";
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
+ {
+ if (strcmp(var.value, "enabled") == 0)
+ gpu_peops_fix |= GPU_PEOPS_EXPAND_SCREEN_WIDTH;
+ }
+
+ var.value = "NULL";
+ var.key = "pcsx_rearmed_gpu_peops_ignore_brightness";
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
+ {
+ if (strcmp(var.value, "enabled") == 0)
+ gpu_peops_fix |= GPU_PEOPS_IGNORE_BRIGHTNESS;
+ }
+
+ var.value = "NULL";
+ var.key = "pcsx_rearmed_gpu_peops_disable_coord_check";
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
+ {
+ if (strcmp(var.value, "enabled") == 0)
+ gpu_peops_fix |= GPU_PEOPS_DISABLE_COORD_CHECK;
+ }
+
+ var.value = "NULL";
+ var.key = "pcsx_rearmed_gpu_peops_lazy_screen_update";
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
+ {
+ if (strcmp(var.value, "enabled") == 0)
+ gpu_peops_fix |= GPU_PEOPS_LAZY_SCREEN_UPDATE;
+ }
+
+ var.value = "NULL";
+ var.key = "pcsx_rearmed_gpu_peops_old_frame_skip";
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
+ {
+ if (strcmp(var.value, "enabled") == 0)
+ gpu_peops_fix |= GPU_PEOPS_OLD_FRAME_SKIP;
+ }
+
+ var.value = "NULL";
+ var.key = "pcsx_rearmed_gpu_peops_repeated_triangles";
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
+ {
+ if (strcmp(var.value, "enabled") == 0)
+ gpu_peops_fix |= GPU_PEOPS_REPEATED_TRIANGLES;
+ }
+
+ var.value = "NULL";
+ var.key = "pcsx_rearmed_gpu_peops_quads_with_triangles";
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
+ {
+ if (strcmp(var.value, "enabled") == 0)
+ gpu_peops_fix |= GPU_PEOPS_QUADS_WITH_TRIANGLES;
+ }
+
+ var.value = "NULL";
+ var.key = "pcsx_rearmed_gpu_peops_fake_busy_state";
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
+ {
+ if (strcmp(var.value, "enabled") == 0)
+ gpu_peops_fix |= GPU_PEOPS_FAKE_BUSY_STATE;
+ }
+
+ if (pl_rearmed_cbs.gpu_peops.dwActFixes != gpu_peops_fix)
+ pl_rearmed_cbs.gpu_peops.dwActFixes = gpu_peops_fix;
+
+
+ /* Show/hide core options */
+
+ var.key = "pcsx_rearmed_show_gpu_peops_settings";
+ var.value = NULL;
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
+ {
+ int show_advanced_gpu_peops_settings_prev = show_advanced_gpu_peops_settings;
+
+ show_advanced_gpu_peops_settings = 1;
+ if (strcmp(var.value, "disabled") == 0)
+ show_advanced_gpu_peops_settings = 0;
+
+ if (show_advanced_gpu_peops_settings != show_advanced_gpu_peops_settings_prev)
+ {
+ unsigned i;
+ struct retro_core_option_display option_display;
+ char gpu_peops_option[9][45] = {
+ "pcsx_rearmed_gpu_peops_odd_even_bit",
+ "pcsx_rearmed_gpu_peops_expand_screen_width",
+ "pcsx_rearmed_gpu_peops_ignore_brightness",
+ "pcsx_rearmed_gpu_peops_disable_coord_check",
+ "pcsx_rearmed_gpu_peops_lazy_screen_update",
+ "pcsx_rearmed_gpu_peops_old_frame_skip",
+ "pcsx_rearmed_gpu_peops_repeated_triangles",
+ "pcsx_rearmed_gpu_peops_quads_with_triangles",
+ "pcsx_rearmed_gpu_peops_fake_busy_state",
+ };
+
+ option_display.visible = show_advanced_gpu_peops_settings;
+
+ for (i = 0; i < 9; i++)
+ {
+ option_display.key = gpu_peops_option[i];
+ environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, &option_display);
+ }
+ }
+ }
+#endif
+
+#ifdef GPU_UNAI
+ var.key = "pcsx_rearmed_gpu_unai_ilace_force";
+ var.value = NULL;
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ if (strcmp(var.value, "disabled") == 0)
+ pl_rearmed_cbs.gpu_unai.ilace_force = 0;
+ else if (strcmp(var.value, "enabled") == 0)
+ pl_rearmed_cbs.gpu_unai.ilace_force = 1;
+ }
+
+ var.key = "pcsx_rearmed_gpu_unai_pixel_skip";
+ var.value = NULL;
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ if (strcmp(var.value, "disabled") == 0)
+ pl_rearmed_cbs.gpu_unai.pixel_skip = 0;
+ else if (strcmp(var.value, "enabled") == 0)
+ pl_rearmed_cbs.gpu_unai.pixel_skip = 1;
+ }
+
+ var.key = "pcsx_rearmed_gpu_unai_lighting";
+ var.value = NULL;
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ if (strcmp(var.value, "disabled") == 0)
+ pl_rearmed_cbs.gpu_unai.lighting = 0;
+ else if (strcmp(var.value, "enabled") == 0)
+ pl_rearmed_cbs.gpu_unai.lighting = 1;
+ }
+
+ var.key = "pcsx_rearmed_gpu_unai_fast_lighting";
+ var.value = NULL;
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ if (strcmp(var.value, "disabled") == 0)
+ pl_rearmed_cbs.gpu_unai.fast_lighting = 0;
+ else if (strcmp(var.value, "enabled") == 0)
+ pl_rearmed_cbs.gpu_unai.fast_lighting = 1;
+ }
+
+ var.key = "pcsx_rearmed_gpu_unai_blending";
+ var.value = NULL;
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ if (strcmp(var.value, "disabled") == 0)
+ pl_rearmed_cbs.gpu_unai.blending = 0;
+ else if (strcmp(var.value, "enabled") == 0)
+ pl_rearmed_cbs.gpu_unai.blending = 1;
+ }
+
+ var.key = "pcsx_rearmed_show_gpu_unai_settings";
+ var.value = NULL;
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
+ {
+ int show_advanced_gpu_unai_settings_prev = show_advanced_gpu_unai_settings;
+
+ show_advanced_gpu_unai_settings = 1;
+ if (strcmp(var.value, "disabled") == 0)
+ show_advanced_gpu_unai_settings = 0;
+
+ if (show_advanced_gpu_unai_settings != show_advanced_gpu_unai_settings_prev)
+ {
+ unsigned i;
+ struct retro_core_option_display option_display;
+ char gpu_unai_option[5][40] = {
+ "pcsx_rearmed_gpu_unai_blending",
+ "pcsx_rearmed_gpu_unai_lighting",
+ "pcsx_rearmed_gpu_unai_fast_lighting",
+ "pcsx_rearmed_gpu_unai_ilace_force",
+ "pcsx_rearmed_gpu_unai_pixel_skip",
+ };
+
+ option_display.visible = show_advanced_gpu_unai_settings;
+
+ for (i = 0; i < 5; i++)
+ {
+ option_display.key = gpu_unai_option[i];
+ environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, &option_display);
+ }
+ }
+ }
+#endif // GPU_UNAI
+
if (in_flight) {
// inform core things about possible config changes
plugin_call_rearmed_cbs();
@@ -1101,11 +2141,119 @@ static void update_variables(bool in_flight)
dfinput_activate();
}
+ else
+ {
+ //not yet running
+
+ //bootlogo display hack
+ if (found_bios) {
+ var.value = "NULL";
+ var.key = "pcsx_rearmed_show_bios_bootlogo";
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ Config.SlowBoot = 0;
+ rebootemu = 0;
+ if (strcmp(var.value, "enabled") == 0)
+ {
+ Config.SlowBoot = 1;
+ rebootemu = 1;
+ }
+ }
+ }
+
+#if defined(LIGHTREC) || defined(NEW_DYNAREC)
+ var.value = "NULL";
+ var.key = "pcsx_rearmed_psxclock";
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ int psxclock = atoi(var.value);
+ cycle_multiplier = 10000 / psxclock;
+ }
+#endif
+ }
+}
+
+// Taken from beetle-psx-libretro
+static uint16_t get_analog_button(int16_t ret, retro_input_state_t input_state_cb, int player_index, int id)
+{
+ // NOTE: Analog buttons were added Nov 2017. Not all front-ends support this
+ // feature (or pre-date it) so we need to handle this in a graceful way.
+
+ // First, try and get an analog value using the new libretro API constant
+ uint16_t button = input_state_cb(player_index,
+ RETRO_DEVICE_ANALOG,
+ RETRO_DEVICE_INDEX_ANALOG_BUTTON,
+ id);
+ button = MIN(button / 128, 255);
+
+ if (button == 0)
+ {
+ // If we got exactly zero, we're either not pressing the button, or the front-end
+ // is not reporting analog values. We need to do a second check using the classic
+ // digital API method, to at least get some response - better than nothing.
+
+ // NOTE: If we're really just not holding the button, we're still going to get zero.
+
+ button = (ret & (1 << id)) ? 255 : 0;
+ }
+
+ return button;
+}
+
+unsigned char axis_range_modifier(int16_t axis_value, bool is_square) {
+ float modifier_axis_range = 0;
+
+ if(is_square) {
+ modifier_axis_range = round((axis_value >> 8) / 0.785) + 128;
+ if(modifier_axis_range < 0) {
+ modifier_axis_range = 0;
+ } else if(modifier_axis_range > 255) {
+ modifier_axis_range = 255;
+ }
+ } else {
+ modifier_axis_range = MIN(((axis_value >> 8) + 128), 255);
+ }
+
+ return modifier_axis_range;
}
-void retro_run(void)
+void retro_run(void)
{
int i;
+ //SysReset must be run while core is running,Not in menu (Locks up Retroarch)
+ if (rebootemu != 0) {
+ rebootemu = 0;
+ SysReset();
+ if (!Config.HLE && !Config.SlowBoot) {
+ // skip BIOS logos
+ psxRegs.pc = psxRegs.GPR.n.ra;
+ }
+ }
+
+ if (display_internal_fps) {
+ frame_count++;
+
+ if (frame_count % INTERNAL_FPS_SAMPLE_PERIOD == 0) {
+ unsigned internal_fps = pl_rearmed_cbs.flip_cnt * (is_pal_mode ? 50 : 60) / INTERNAL_FPS_SAMPLE_PERIOD;
+ char str[64];
+ const char *strc = (const char*)str;
+ struct retro_message msg =
+ {
+ strc,
+ 180
+ };
+
+ str[0] = '\0';
+
+ snprintf(str, sizeof(str), "Internal FPS: %2d", internal_fps);
+
+ pl_rearmed_cbs.flip_cnt = 0;
+
+ environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE, &msg);
+ }
+ }
+ else
+ frame_count = 0;
input_poll_cb();
@@ -1113,29 +2261,250 @@ void retro_run(void)
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated)
update_variables(true);
- in_keystate = 0;
- for (i = 0; i < RETRO_PSX_MAP_LEN; i++)
- if (input_state_cb(1, RETRO_DEVICE_JOYPAD, 0, i))
- in_keystate |= retro_psx_map[i];
- in_keystate <<= 16;
- for (i = 0; i < RETRO_PSX_MAP_LEN; i++)
- if (input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, i))
- in_keystate |= retro_psx_map[i];
+ // reset all keystate, query libretro for keystate
+ int j;
+ int lsx;
+ int rsy;
+ float negcon_twist_amplitude;
+ int negcon_i_rs;
+ int negcon_ii_rs;
+ for(i = 0; i < PORTS_NUMBER; i++)
+ {
+ int16_t ret = 0;
+ in_keystate[i] = 0;
- if (in_type1 == PSE_PAD_TYPE_ANALOGPAD)
- {
- in_a1[0] = (input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X) / 256) + 128;
- in_a1[1] = (input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y) / 256) + 128;
- in_a2[0] = (input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X) / 256) + 128;
- in_a2[1] = (input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y) / 256) + 128;
+ if (in_type[i] == PSE_PAD_TYPE_NONE)
+ continue;
+
+ if (libretro_supports_bitmasks)
+ ret = input_state_cb(i, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_MASK);
+ else
+ {
+ unsigned j;
+ for (j = 0; j < (RETRO_DEVICE_ID_JOYPAD_R3+1); j++)
+ {
+ if (input_state_cb(i, RETRO_DEVICE_JOYPAD, 0, j))
+ ret |= (1 << j);
+ }
+ }
+
+ if (in_type[i] == PSE_PAD_TYPE_GUNCON)
+ {
+ //ToDo move across to:
+ //RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X
+ //RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y
+ //RETRO_DEVICE_ID_LIGHTGUN_TRIGGER
+ //RETRO_DEVICE_ID_LIGHTGUN_RELOAD
+ //RETRO_DEVICE_ID_LIGHTGUN_AUX_A
+ //RETRO_DEVICE_ID_LIGHTGUN_AUX_B
+ //Though not sure these are hooked up properly on the Pi
+
+ //ToDo
+ //Put the controller index back to i instead of hardcoding to 1 when the libretro overlay crash bug is fixed
+ //This is required for 2 player
+
+ //GUNCON has 3 controls, Trigger,A,B which equal Circle,Start,Cross
+
+ // Trigger
+ //The 1 is hardcoded instead of i to prevent the overlay mouse button libretro crash bug
+ if (input_state_cb(1, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_LEFT)){
+ in_keystate[i] |= (1 << DKEY_CIRCLE);
+ }
+
+ // A
+ if (input_state_cb(1, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_RIGHT)){
+ in_keystate[i] |= (1 << DKEY_START);
+ }
+
+ // B
+ if (input_state_cb(1, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_MIDDLE)){
+ in_keystate[i] |= (1 << DKEY_CROSS);
+ }
+
+ //The 1 is hardcoded instead of i to prevent the overlay mouse button libretro crash bug
+ int gunx = input_state_cb(1, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X);
+ int guny = input_state_cb(1, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_Y);
+
+ //This adjustment process gives the user the ability to manually align the mouse up better
+ //with where the shots are in the emulator.
+
+ //Percentage distance of screen to adjust
+ int GunconAdjustX = 0;
+ int GunconAdjustY = 0;
+
+ //Used when out by a percentage
+ float GunconAdjustRatioX = 1;
+ float GunconAdjustRatioY = 1;
+
+ struct retro_variable var;
+ var.value = NULL;
+ var.key = "pcsx_rearmed_gunconadjustx";
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ GunconAdjustX = atoi(var.value);
+ }
+
+ var.value = NULL;
+ var.key = "pcsx_rearmed_gunconadjusty";
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ GunconAdjustY = atoi(var.value);
+ }
+
+
+ var.value = NULL;
+ var.key = "pcsx_rearmed_gunconadjustratiox";
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ GunconAdjustRatioX = atof(var.value);
+ }
+
+
+ var.value = NULL;
+ var.key = "pcsx_rearmed_gunconadjustratioy";
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ GunconAdjustRatioY = atof(var.value);
+ }
+
+ //Mouse range is -32767 -> 32767
+ //1% is about 655
+ //Use the left analog stick field to store the absolute coordinates
+ in_analog_left[0][0] = (gunx*GunconAdjustRatioX) + (GunconAdjustX * 655);
+ in_analog_left[0][1] = (guny*GunconAdjustRatioY) + (GunconAdjustY * 655);
+
+
+ }
+ if (in_type[i] == PSE_PAD_TYPE_NEGCON)
+ {
+ // Query digital inputs
+ //
+ // > Pad-Up
+ if (ret & (1 << RETRO_DEVICE_ID_JOYPAD_UP))
+ in_keystate[i] |= (1 << DKEY_UP);
+ // > Pad-Right
+ if (ret & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT))
+ in_keystate[i] |= (1 << DKEY_RIGHT);
+ // > Pad-Down
+ if (ret & (1 << RETRO_DEVICE_ID_JOYPAD_DOWN))
+ in_keystate[i] |= (1 << DKEY_DOWN);
+ // > Pad-Left
+ if (ret & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT))
+ in_keystate[i] |= (1 << DKEY_LEFT);
+ // > Start
+ if (ret & (1 << RETRO_DEVICE_ID_JOYPAD_START))
+ in_keystate[i] |= (1 << DKEY_START);
+ // > neGcon A
+ if (ret & (1 << RETRO_DEVICE_ID_JOYPAD_A))
+ in_keystate[i] |= (1 << DKEY_CIRCLE);
+ // > neGcon B
+ if (ret & (1 << RETRO_DEVICE_ID_JOYPAD_X))
+ in_keystate[i] |= (1 << DKEY_TRIANGLE);
+ // > neGcon R shoulder (digital)
+ if (ret & (1 << RETRO_DEVICE_ID_JOYPAD_R))
+ in_keystate[i] |= (1 << DKEY_R1);
+ // Query analog inputs
+ //
+ // From studying 'libpcsxcore/plugins.c' and 'frontend/plugin.c':
+ // >> pad->leftJoyX == in_analog_left[i][0] == NeGcon II
+ // >> pad->leftJoyY == in_analog_left[i][1] == NeGcon L
+ // >> pad->rightJoyX == in_analog_right[i][0] == NeGcon twist
+ // >> pad->rightJoyY == in_analog_right[i][1] == NeGcon I
+ // So we just have to map in_analog_left/right to more
+ // appropriate inputs...
+ //
+ // > NeGcon twist
+ // >> Get raw analog stick value and account for deadzone
+ lsx = input_state_cb(i, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X);
+ if (lsx > negcon_deadzone)
+ lsx = lsx - negcon_deadzone;
+ else if (lsx < -negcon_deadzone)
+ lsx = lsx + negcon_deadzone;
+ else
+ lsx = 0;
+ // >> Convert to an 'amplitude' [-1.0,1.0] and adjust response
+ negcon_twist_amplitude = (float)lsx / (float)(NEGCON_RANGE - negcon_deadzone);
+ if (negcon_linearity == 2)
+ {
+ if (negcon_twist_amplitude < 0.0)
+ negcon_twist_amplitude = -(negcon_twist_amplitude * negcon_twist_amplitude);
+ else
+ negcon_twist_amplitude = negcon_twist_amplitude * negcon_twist_amplitude;
+ }
+ else if (negcon_linearity == 3)
+ negcon_twist_amplitude = negcon_twist_amplitude * negcon_twist_amplitude * negcon_twist_amplitude;
+ // >> Convert to final 'in_analog' integer value [0,255]
+ in_analog_right[i][0] = MAX(MIN((int)(negcon_twist_amplitude * 128.0f) + 128, 255), 0);
+ // > NeGcon I + II
+ // >> Handle right analog stick vertical axis mapping...
+ // - Up (-Y) == accelerate == neGcon I
+ // - Down (+Y) == brake == neGcon II
+ negcon_i_rs = 0;
+ negcon_ii_rs = 0;
+ rsy = input_state_cb(i, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y);
+ if (rsy >= 0){
+ // Account for deadzone
+ // (Note: have never encountered a gamepad with significant differences
+ // in deadzone between left/right analog sticks, so use the regular 'twist'
+ // deadzone here)
+ if (rsy > negcon_deadzone)
+ rsy = rsy - negcon_deadzone;
+ else
+ rsy = 0;
+ // Convert to 'in_analog' integer value [0,255]
+ negcon_ii_rs = MIN((int)(((float)rsy / (float)(NEGCON_RANGE - negcon_deadzone)) * 255.0f), 255);
+ } else {
+ if (rsy < -negcon_deadzone)
+ rsy = -1 * (rsy + negcon_deadzone);
+ else
+ rsy = 0;
+ negcon_i_rs = MIN((int)(((float)rsy / (float)(NEGCON_RANGE - negcon_deadzone)) * 255.0f), 255);
+ }
+ // >> NeGcon I
+ in_analog_right[i][1] = MAX(
+ MAX(
+ get_analog_button(ret, input_state_cb, i, RETRO_DEVICE_ID_JOYPAD_R2),
+ get_analog_button(ret, input_state_cb, i, RETRO_DEVICE_ID_JOYPAD_B)
+ ),
+ negcon_i_rs
+ );
+ // >> NeGcon II
+ in_analog_left[i][0] = MAX(
+ MAX(
+ get_analog_button(ret, input_state_cb, i, RETRO_DEVICE_ID_JOYPAD_L2),
+ get_analog_button(ret, input_state_cb, i, RETRO_DEVICE_ID_JOYPAD_Y)
+ ),
+ negcon_ii_rs
+ );
+ // > NeGcon L
+ in_analog_left[i][1] = get_analog_button(ret, input_state_cb, i, RETRO_DEVICE_ID_JOYPAD_L);
+ }
+ if (in_type[i] != PSE_PAD_TYPE_NEGCON && in_type[i] != PSE_PAD_TYPE_GUNCON)
+ {
+ // Query digital inputs
+ for (j = 0; j < RETRO_PSX_MAP_LEN; j++)
+ if (ret & (1 << j))
+ in_keystate[i] |= retro_psx_map[j];
+
+ // Query analog inputs
+ if (in_type[i] == PSE_PAD_TYPE_ANALOGJOY || in_type[i] == PSE_PAD_TYPE_ANALOGPAD)
+ {
+ in_analog_left[i][0] = axis_range_modifier(input_state_cb(i, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X), axis_bounds_modifier);
+ in_analog_left[i][1] = axis_range_modifier(input_state_cb(i, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y), axis_bounds_modifier);
+ in_analog_right[i][0] = axis_range_modifier(input_state_cb(i, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X), axis_bounds_modifier);
+ in_analog_right[i][1] = axis_range_modifier(input_state_cb(i, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y), axis_bounds_modifier);
+ }
+ }
}
stop = 0;
psxCpu->Execute();
- video_cb((vout_fb_dirty || !vout_can_dupe || !duping_enable) ? vout_buf : NULL,
+ video_cb((vout_fb_dirty || !vout_can_dupe || !duping_enable) ? vout_buf_ptr : NULL,
vout_width, vout_height, vout_width * 2);
vout_fb_dirty = 0;
+
+ set_vout_fb();
}
static bool try_use_bios(const char *path)
@@ -1162,7 +2531,7 @@ static bool try_use_bios(const char *path)
return true;
}
-#if 1
+#ifndef VITA
#include <sys/types.h>
#include <dirent.h>
@@ -1177,10 +2546,10 @@ static bool find_any_bios(const char *dirpath, char *path, size_t path_size)
return false;
while ((ent = readdir(dir))) {
- if (strncasecmp(ent->d_name, "scph", 4) != 0)
+ if ((strncasecmp(ent->d_name, "scph", 4) != 0) && (strncasecmp(ent->d_name, "psx", 3) != 0))
continue;
- snprintf(path, path_size, "%s/%s", dirpath, ent->d_name);
+ snprintf(path, path_size, "%s%c%s", dirpath, SLASH, ent->d_name);
ret = try_use_bios(path);
if (ret)
break;
@@ -1198,63 +2567,163 @@ static void check_system_specs(void)
environ_cb(RETRO_ENVIRONMENT_SET_PERFORMANCE_LEVEL, &level);
}
-void retro_init(void)
+static int init_memcards(void)
+{
+ int ret = 0;
+ const char *dir;
+ struct retro_variable var = { .key="pcsx_rearmed_memcard2", .value=NULL };
+ static const char CARD2_FILE[] = "pcsx-card2.mcd";
+
+ // Memcard2 will be handled and is re-enabled if needed using core
+ // operations.
+ // Memcard1 is handled by libretro, doing this will set core to
+ // skip file io operations for memcard1 like SaveMcd
+ snprintf(Config.Mcd1, sizeof(Config.Mcd1), "none");
+ snprintf(Config.Mcd2, sizeof(Config.Mcd2), "none");
+ init_memcard(Mcd1Data);
+ // Memcard 2 is managed by the emulator on the filesystem,
+ // There is no need to initialize Mcd2Data like Mcd1Data.
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
+ SysPrintf("Memcard 2: %s\n", var.value);
+ if (memcmp(var.value, "enabled", 7) == 0) {
+ if (environ_cb(RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY, &dir) && dir) {
+ if (strlen(dir) + strlen(CARD2_FILE) + 2 > sizeof(Config.Mcd2)) {
+ SysPrintf("Path '%s' is too long. Cannot use memcard 2. Use a shorter path.\n", dir);
+ ret = -1;
+ } else {
+ McdDisable[1] = 0;
+ snprintf(Config.Mcd2, sizeof(Config.Mcd2), "%s/%s", dir, CARD2_FILE);
+ SysPrintf("Use memcard 2: %s\n", Config.Mcd2);
+ }
+ } else {
+ SysPrintf("Could not get save directory! Could not create memcard 2.");
+ ret = -1;
+ }
+ }
+ }
+ return ret;
+}
+
+static void loadPSXBios(void)
{
- const char *bios[] = { "scph1001", "scph5501", "scph7001" };
const char *dir;
- char path[256];
- int i, ret;
- bool found_bios = false;
+ char path[PATH_MAX];
+ unsigned useHLE = 0;
+
+ const char *bios[] = {
+ "PSXONPSP660", "psxonpsp660",
+ "SCPH101", "scph101",
+ "SCPH5501", "scph5501",
+ "SCPH7001", "scph7001",
+ "SCPH1001", "scph1001"
+ };
+
+ struct retro_variable var = {
+ .key = "pcsx_rearmed_bios",
+ .value = NULL
+ };
+
+ found_bios = 0;
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
+ if (!strcmp(var.value, "HLE"))
+ useHLE = 1;
+ }
+
+ if (!useHLE)
+ {
+ if (environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &dir) && dir)
+ {
+ unsigned i;
+ snprintf(Config.BiosDir, sizeof(Config.BiosDir), "%s", dir);
+
+ for (i = 0; i < sizeof(bios) / sizeof(bios[0]); i++) {
+ snprintf(path, sizeof(path), "%s%c%s.bin", dir, SLASH, bios[i]);
+ found_bios = try_use_bios(path);
+ if (found_bios)
+ break;
+ }
+
+ if (!found_bios)
+ found_bios = find_any_bios(dir, path, sizeof(path));
+ }
+ if (found_bios) {
+ SysPrintf("found BIOS file: %s\n", Config.Bios);
+ }
+ }
+
+ if (useHLE || !found_bios)
+ {
+ SysPrintf("no BIOS files found.\n");
+ struct retro_message msg =
+ {
+ "No PlayStation BIOS file found - add for better compatibility",
+ 180
+ };
+ environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE, (void*)&msg);
+ }
+}
+
+void retro_init(void)
+{
+ unsigned dci_version = 0;
+ struct retro_rumble_interface rumble;
+ int ret;
#ifdef __MACH__
// magic sauce to make the dynarec work on iOS
syscall(SYS_ptrace, 0 /*PTRACE_TRACEME*/, 0, 0, 0);
#endif
+#ifdef _3DS
+ psxMapHook = pl_3ds_mmap;
+ psxUnmapHook = pl_3ds_munmap;
+#endif
+#ifdef VITA
+ if(init_vita_mmap()<0)
+ abort();
+ psxMapHook = pl_vita_mmap;
+ psxUnmapHook = pl_vita_munmap;
+#endif
ret = emu_core_preinit();
+#ifdef _3DS
+ /* emu_core_preinit sets the cpu to dynarec */
+ if(!__ctr_svchax)
+ Config.Cpu = CPU_INTERPRETER;
+#endif
+ ret |= init_memcards();
+
ret |= emu_core_init();
if (ret != 0) {
SysPrintf("PCSX init failed.\n");
exit(1);
}
-#if defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L)
+#ifdef _3DS
+ vout_buf = linearMemAlign(VOUT_MAX_WIDTH * VOUT_MAX_HEIGHT * 2, 0x80);
+#elif defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L) && !defined(VITA) && !defined(__SWITCH__)
posix_memalign(&vout_buf, 16, VOUT_MAX_WIDTH * VOUT_MAX_HEIGHT * 2);
#else
vout_buf = malloc(VOUT_MAX_WIDTH * VOUT_MAX_HEIGHT * 2);
#endif
- if (environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &dir) && dir)
- {
- snprintf(Config.BiosDir, sizeof(Config.BiosDir), "%s/", dir);
+ vout_buf_ptr = vout_buf;
- for (i = 0; i < sizeof(bios) / sizeof(bios[0]); i++) {
- snprintf(path, sizeof(path), "%s/%s.bin", dir, bios[i]);
- found_bios = try_use_bios(path);
- if (found_bios)
- break;
- }
+ loadPSXBios();
- if (!found_bios)
- found_bios = find_any_bios(dir, path, sizeof(path));
- }
- if (found_bios) {
- SysPrintf("found BIOS file: %s\n", Config.Bios);
- }
+ environ_cb(RETRO_ENVIRONMENT_GET_CAN_DUPE, &vout_can_dupe);
+
+ disk_initial_index = 0;
+ disk_initial_path[0] = '\0';
+ if (environ_cb(RETRO_ENVIRONMENT_GET_DISK_CONTROL_INTERFACE_VERSION, &dci_version) && (dci_version >= 1))
+ environ_cb(RETRO_ENVIRONMENT_SET_DISK_CONTROL_EXT_INTERFACE, &disk_control_ext);
else
- {
- SysPrintf("no BIOS files found.\n");
- struct retro_message msg =
- {
- "no BIOS found, expect bugs!",
- 180
- };
- environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE, (void*)&msg);
- }
+ environ_cb(RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE, &disk_control);
- environ_cb(RETRO_ENVIRONMENT_GET_CAN_DUPE, &vout_can_dupe);
- environ_cb(RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE, &disk_control);
- environ_cb(RETRO_ENVIRONMENT_GET_RUMBLE_INTERFACE, &rumble);
+ rumble_cb = NULL;
+ if (environ_cb(RETRO_ENVIRONMENT_GET_RUMBLE_INTERFACE, &rumble))
+ rumble_cb = rumble.set_rumble_state;
/* Set how much slower PSX CPU runs * 100 (so that 200 is 2 times)
* we have to do this because cache misses and some IO penalties
@@ -1264,25 +2733,59 @@ void retro_init(void)
cycle_multiplier = 200;
#endif
pl_rearmed_cbs.gpu_peops.iUseDither = 1;
+ pl_rearmed_cbs.gpu_peops.dwActFixes = GPU_PEOPS_OLD_FRAME_SKIP;
spu_config.iUseFixedUpdates = 1;
- McdDisable[0] = 0;
- McdDisable[1] = 1;
- init_memcard(Mcd1Data);
-
SaveFuncs.open = save_open;
SaveFuncs.read = save_read;
SaveFuncs.write = save_write;
SaveFuncs.seek = save_seek;
SaveFuncs.close = save_close;
+ if (environ_cb(RETRO_ENVIRONMENT_GET_INPUT_BITMASKS, NULL))
+ libretro_supports_bitmasks = true;
+
update_variables(false);
check_system_specs();
}
void retro_deinit(void)
{
+ ClosePlugins();
SysClose();
+#ifdef _3DS
+ linearFree(vout_buf);
+#else
free(vout_buf);
+#endif
vout_buf = NULL;
+
+#ifdef VITA
+ deinit_vita_mmap();
+#endif
+ libretro_supports_bitmasks = false;
+
+ /* Have to reset disks struct, otherwise
+ * fnames/flabels will leak memory */
+ disk_init();
+}
+
+#ifdef VITA
+#include <psp2/kernel/threadmgr.h>
+int usleep (unsigned long us)
+{
+ sceKernelDelayThread(us);
+}
+#endif
+
+void SysPrintf(const char *fmt, ...) {
+ va_list list;
+ char msg[512];
+
+ va_start(list, fmt);
+ vsprintf(msg, fmt, list);
+ va_end(list);
+
+ if (log_cb)
+ log_cb(RETRO_LOG_INFO, "%s", msg);
}
diff --git a/frontend/libretro.h b/frontend/libretro.h
deleted file mode 100755
index 16c274a..0000000
--- a/frontend/libretro.h
+++ /dev/null
@@ -1,1926 +0,0 @@
-/* Copyright (C) 2010-2014 The RetroArch team
- *
- * ---------------------------------------------------------------------------------------
- * The following license statement only applies to this libretro API header (libretro.h).
- * ---------------------------------------------------------------------------------------
- *
- * Permission is hereby granted, free of charge,
- * to any person obtaining a copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
- * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef LIBRETRO_H__
-#define LIBRETRO_H__
-
-#include <stdint.h>
-#include <stddef.h>
-#include <limits.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef __cplusplus
-#if defined(_MSC_VER) && !defined(SN_TARGET_PS3)
-/* Hack applied for MSVC when compiling in C89 mode
- * as it isn't C99-compliant. */
-#define bool unsigned char
-#define true 1
-#define false 0
-#else
-#include <stdbool.h>
-#endif
-#endif
-
-/* Used for checking API/ABI mismatches that can break libretro
- * implementations.
- * It is not incremented for compatible changes to the API.
- */
-#define RETRO_API_VERSION 1
-
-/*
- * Libretro's fundamental device abstractions.
- *
- * Libretro's input system consists of some standardized device types,
- * such as a joypad (with/without analog), mouse, keyboard, lightgun
- * and a pointer.
- *
- * The functionality of these devices are fixed, and individual cores
- * map their own concept of a controller to libretro's abstractions.
- * This makes it possible for frontends to map the abstract types to a
- * real input device, and not having to worry about binding input
- * correctly to arbitrary controller layouts.
- */
-
-#define RETRO_DEVICE_TYPE_SHIFT 8
-#define RETRO_DEVICE_MASK ((1 << RETRO_DEVICE_TYPE_SHIFT) - 1)
-#define RETRO_DEVICE_SUBCLASS(base, id) (((id + 1) << RETRO_DEVICE_TYPE_SHIFT) | base)
-
-/* Input disabled. */
-#define RETRO_DEVICE_NONE 0
-
-/* The JOYPAD is called RetroPad. It is essentially a Super Nintendo
- * controller, but with additional L2/R2/L3/R3 buttons, similar to a
- * PS1 DualShock. */
-#define RETRO_DEVICE_JOYPAD 1
-
-/* The mouse is a simple mouse, similar to Super Nintendo's mouse.
- * X and Y coordinates are reported relatively to last poll (poll callback).
- * It is up to the libretro implementation to keep track of where the mouse
- * pointer is supposed to be on the screen.
- * The frontend must make sure not to interfere with its own hardware
- * mouse pointer.
- */
-#define RETRO_DEVICE_MOUSE 2
-
-/* KEYBOARD device lets one poll for raw key pressed.
- * It is poll based, so input callback will return with the current
- * pressed state.
- * For event/text based keyboard input, see
- * RETRO_ENVIRONMENT_SET_KEYBOARD_CALLBACK.
- */
-#define RETRO_DEVICE_KEYBOARD 3
-
-/* Lightgun X/Y coordinates are reported relatively to last poll,
- * similar to mouse. */
-#define RETRO_DEVICE_LIGHTGUN 4
-
-/* The ANALOG device is an extension to JOYPAD (RetroPad).
- * Similar to DualShock it adds two analog sticks.
- * This is treated as a separate device type as it returns values in the
- * full analog range of [-0x8000, 0x7fff]. Positive X axis is right.
- * Positive Y axis is down.
- * Only use ANALOG type when polling for analog values of the axes.
- */
-#define RETRO_DEVICE_ANALOG 5
-
-/* Abstracts the concept of a pointing mechanism, e.g. touch.
- * This allows libretro to query in absolute coordinates where on the
- * screen a mouse (or something similar) is being placed.
- * For a touch centric device, coordinates reported are the coordinates
- * of the press.
- *
- * Coordinates in X and Y are reported as:
- * [-0x7fff, 0x7fff]: -0x7fff corresponds to the far left/top of the screen,
- * and 0x7fff corresponds to the far right/bottom of the screen.
- * The "screen" is here defined as area that is passed to the frontend and
- * later displayed on the monitor.
- *
- * The frontend is free to scale/resize this screen as it sees fit, however,
- * (X, Y) = (-0x7fff, -0x7fff) will correspond to the top-left pixel of the
- * game image, etc.
- *
- * To check if the pointer coordinates are valid (e.g. a touch display
- * actually being touched), PRESSED returns 1 or 0.
- *
- * If using a mouse on a desktop, PRESSED will usually correspond to the
- * left mouse button, but this is a frontend decision.
- * PRESSED will only return 1 if the pointer is inside the game screen.
- *
- * For multi-touch, the index variable can be used to successively query
- * more presses.
- * If index = 0 returns true for _PRESSED, coordinates can be extracted
- * with _X, _Y for index = 0. One can then query _PRESSED, _X, _Y with
- * index = 1, and so on.
- * Eventually _PRESSED will return false for an index. No further presses
- * are registered at this point. */
-#define RETRO_DEVICE_POINTER 6
-
-/* Buttons for the RetroPad (JOYPAD).
- * The placement of these is equivalent to placements on the
- * Super Nintendo controller.
- * L2/R2/L3/R3 buttons correspond to the PS1 DualShock. */
-#define RETRO_DEVICE_ID_JOYPAD_B 0
-#define RETRO_DEVICE_ID_JOYPAD_Y 1
-#define RETRO_DEVICE_ID_JOYPAD_SELECT 2
-#define RETRO_DEVICE_ID_JOYPAD_START 3
-#define RETRO_DEVICE_ID_JOYPAD_UP 4
-#define RETRO_DEVICE_ID_JOYPAD_DOWN 5
-#define RETRO_DEVICE_ID_JOYPAD_LEFT 6
-#define RETRO_DEVICE_ID_JOYPAD_RIGHT 7
-#define RETRO_DEVICE_ID_JOYPAD_A 8
-#define RETRO_DEVICE_ID_JOYPAD_X 9
-#define RETRO_DEVICE_ID_JOYPAD_L 10
-#define RETRO_DEVICE_ID_JOYPAD_R 11
-#define RETRO_DEVICE_ID_JOYPAD_L2 12
-#define RETRO_DEVICE_ID_JOYPAD_R2 13
-#define RETRO_DEVICE_ID_JOYPAD_L3 14
-#define RETRO_DEVICE_ID_JOYPAD_R3 15
-
-/* Index / Id values for ANALOG device. */
-#define RETRO_DEVICE_INDEX_ANALOG_LEFT 0
-#define RETRO_DEVICE_INDEX_ANALOG_RIGHT 1
-#define RETRO_DEVICE_ID_ANALOG_X 0
-#define RETRO_DEVICE_ID_ANALOG_Y 1
-
-/* Id values for MOUSE. */
-#define RETRO_DEVICE_ID_MOUSE_X 0
-#define RETRO_DEVICE_ID_MOUSE_Y 1
-#define RETRO_DEVICE_ID_MOUSE_LEFT 2
-#define RETRO_DEVICE_ID_MOUSE_RIGHT 3
-#define RETRO_DEVICE_ID_MOUSE_WHEELUP 4
-#define RETRO_DEVICE_ID_MOUSE_WHEELDOWN 5
-#define RETRO_DEVICE_ID_MOUSE_MIDDLE 6
-
-/* Id values for LIGHTGUN types. */
-#define RETRO_DEVICE_ID_LIGHTGUN_X 0
-#define RETRO_DEVICE_ID_LIGHTGUN_Y 1
-#define RETRO_DEVICE_ID_LIGHTGUN_TRIGGER 2
-#define RETRO_DEVICE_ID_LIGHTGUN_CURSOR 3
-#define RETRO_DEVICE_ID_LIGHTGUN_TURBO 4
-#define RETRO_DEVICE_ID_LIGHTGUN_PAUSE 5
-#define RETRO_DEVICE_ID_LIGHTGUN_START 6
-
-/* Id values for POINTER. */
-#define RETRO_DEVICE_ID_POINTER_X 0
-#define RETRO_DEVICE_ID_POINTER_Y 1
-#define RETRO_DEVICE_ID_POINTER_PRESSED 2
-
-/* Returned from retro_get_region(). */
-#define RETRO_REGION_NTSC 0
-#define RETRO_REGION_PAL 1
-
-/* Id values for LANGUAGE */
-enum retro_language
-{
- RETRO_LANGUAGE_ENGLISH = 0,
- RETRO_LANGUAGE_JAPANESE = 1,
- RETRO_LANGUAGE_FRENCH = 2,
- RETRO_LANGUAGE_SPANISH = 3,
- RETRO_LANGUAGE_GERMAN = 4,
- RETRO_LANGUAGE_ITALIAN = 5,
- RETRO_LANGUAGE_DUTCH = 6,
- RETRO_LANGUAGE_PORTUGUESE = 7,
- RETRO_LANGUAGE_RUSSIAN = 8,
- RETRO_LANGUAGE_KOREAN = 9,
- RETRO_LANGUAGE_CHINESE_TRADITIONAL = 10,
- RETRO_LANGUAGE_CHINESE_SIMPLIFIED = 11,
- RETRO_LANGUAGE_LAST,
-
- /* Ensure sizeof(enum) == sizeof(int) */
- RETRO_LANGUAGE_DUMMY = INT_MAX
-};
-
-/* Passed to retro_get_memory_data/size().
- * If the memory type doesn't apply to the
- * implementation NULL/0 can be returned.
- */
-#define RETRO_MEMORY_MASK 0xff
-
-/* Regular save RAM. This RAM is usually found on a game cartridge,
- * backed up by a battery.
- * If save game data is too complex for a single memory buffer,
- * the SAVE_DIRECTORY (preferably) or SYSTEM_DIRECTORY environment
- * callback can be used. */
-#define RETRO_MEMORY_SAVE_RAM 0
-
-/* Some games have a built-in clock to keep track of time.
- * This memory is usually just a couple of bytes to keep track of time.
- */
-#define RETRO_MEMORY_RTC 1
-
-/* System ram lets a frontend peek into a game systems main RAM. */
-#define RETRO_MEMORY_SYSTEM_RAM 2
-
-/* Video ram lets a frontend peek into a game systems video RAM (VRAM). */
-#define RETRO_MEMORY_VIDEO_RAM 3
-
-/* Keysyms used for ID in input state callback when polling RETRO_KEYBOARD. */
-enum retro_key
-{
- RETROK_UNKNOWN = 0,
- RETROK_FIRST = 0,
- RETROK_BACKSPACE = 8,
- RETROK_TAB = 9,
- RETROK_CLEAR = 12,
- RETROK_RETURN = 13,
- RETROK_PAUSE = 19,
- RETROK_ESCAPE = 27,
- RETROK_SPACE = 32,
- RETROK_EXCLAIM = 33,
- RETROK_QUOTEDBL = 34,
- RETROK_HASH = 35,
- RETROK_DOLLAR = 36,
- RETROK_AMPERSAND = 38,
- RETROK_QUOTE = 39,
- RETROK_LEFTPAREN = 40,
- RETROK_RIGHTPAREN = 41,
- RETROK_ASTERISK = 42,
- RETROK_PLUS = 43,
- RETROK_COMMA = 44,
- RETROK_MINUS = 45,
- RETROK_PERIOD = 46,
- RETROK_SLASH = 47,
- RETROK_0 = 48,
- RETROK_1 = 49,
- RETROK_2 = 50,
- RETROK_3 = 51,
- RETROK_4 = 52,
- RETROK_5 = 53,
- RETROK_6 = 54,
- RETROK_7 = 55,
- RETROK_8 = 56,
- RETROK_9 = 57,
- RETROK_COLON = 58,
- RETROK_SEMICOLON = 59,
- RETROK_LESS = 60,
- RETROK_EQUALS = 61,
- RETROK_GREATER = 62,
- RETROK_QUESTION = 63,
- RETROK_AT = 64,
- RETROK_LEFTBRACKET = 91,
- RETROK_BACKSLASH = 92,
- RETROK_RIGHTBRACKET = 93,
- RETROK_CARET = 94,
- RETROK_UNDERSCORE = 95,
- RETROK_BACKQUOTE = 96,
- RETROK_a = 97,
- RETROK_b = 98,
- RETROK_c = 99,
- RETROK_d = 100,
- RETROK_e = 101,
- RETROK_f = 102,
- RETROK_g = 103,
- RETROK_h = 104,
- RETROK_i = 105,
- RETROK_j = 106,
- RETROK_k = 107,
- RETROK_l = 108,
- RETROK_m = 109,
- RETROK_n = 110,
- RETROK_o = 111,
- RETROK_p = 112,
- RETROK_q = 113,
- RETROK_r = 114,
- RETROK_s = 115,
- RETROK_t = 116,
- RETROK_u = 117,
- RETROK_v = 118,
- RETROK_w = 119,
- RETROK_x = 120,
- RETROK_y = 121,
- RETROK_z = 122,
- RETROK_DELETE = 127,
-
- RETROK_KP0 = 256,
- RETROK_KP1 = 257,
- RETROK_KP2 = 258,
- RETROK_KP3 = 259,
- RETROK_KP4 = 260,
- RETROK_KP5 = 261,
- RETROK_KP6 = 262,
- RETROK_KP7 = 263,
- RETROK_KP8 = 264,
- RETROK_KP9 = 265,
- RETROK_KP_PERIOD = 266,
- RETROK_KP_DIVIDE = 267,
- RETROK_KP_MULTIPLY = 268,
- RETROK_KP_MINUS = 269,
- RETROK_KP_PLUS = 270,
- RETROK_KP_ENTER = 271,
- RETROK_KP_EQUALS = 272,
-
- RETROK_UP = 273,
- RETROK_DOWN = 274,
- RETROK_RIGHT = 275,
- RETROK_LEFT = 276,
- RETROK_INSERT = 277,
- RETROK_HOME = 278,
- RETROK_END = 279,
- RETROK_PAGEUP = 280,
- RETROK_PAGEDOWN = 281,
-
- RETROK_F1 = 282,
- RETROK_F2 = 283,
- RETROK_F3 = 284,
- RETROK_F4 = 285,
- RETROK_F5 = 286,
- RETROK_F6 = 287,
- RETROK_F7 = 288,
- RETROK_F8 = 289,
- RETROK_F9 = 290,
- RETROK_F10 = 291,
- RETROK_F11 = 292,
- RETROK_F12 = 293,
- RETROK_F13 = 294,
- RETROK_F14 = 295,
- RETROK_F15 = 296,
-
- RETROK_NUMLOCK = 300,
- RETROK_CAPSLOCK = 301,
- RETROK_SCROLLOCK = 302,
- RETROK_RSHIFT = 303,
- RETROK_LSHIFT = 304,
- RETROK_RCTRL = 305,
- RETROK_LCTRL = 306,
- RETROK_RALT = 307,
- RETROK_LALT = 308,
- RETROK_RMETA = 309,
- RETROK_LMETA = 310,
- RETROK_LSUPER = 311,
- RETROK_RSUPER = 312,
- RETROK_MODE = 313,
- RETROK_COMPOSE = 314,
-
- RETROK_HELP = 315,
- RETROK_PRINT = 316,
- RETROK_SYSREQ = 317,
- RETROK_BREAK = 318,
- RETROK_MENU = 319,
- RETROK_POWER = 320,
- RETROK_EURO = 321,
- RETROK_UNDO = 322,
-
- RETROK_LAST,
-
- RETROK_DUMMY = INT_MAX /* Ensure sizeof(enum) == sizeof(int) */
-};
-
-enum retro_mod
-{
- RETROKMOD_NONE = 0x0000,
-
- RETROKMOD_SHIFT = 0x01,
- RETROKMOD_CTRL = 0x02,
- RETROKMOD_ALT = 0x04,
- RETROKMOD_META = 0x08,
-
- RETROKMOD_NUMLOCK = 0x10,
- RETROKMOD_CAPSLOCK = 0x20,
- RETROKMOD_SCROLLOCK = 0x40,
-
- RETROKMOD_DUMMY = INT_MAX /* Ensure sizeof(enum) == sizeof(int) */
-};
-
-/* If set, this call is not part of the public libretro API yet. It can
- * change or be removed at any time. */
-#define RETRO_ENVIRONMENT_EXPERIMENTAL 0x10000
-/* Environment callback to be used internally in frontend. */
-#define RETRO_ENVIRONMENT_PRIVATE 0x20000
-
-/* Environment commands. */
-#define RETRO_ENVIRONMENT_SET_ROTATION 1 /* const unsigned * --
- * Sets screen rotation of graphics.
- * Is only implemented if rotation can be accelerated by hardware.
- * Valid values are 0, 1, 2, 3, which rotates screen by 0, 90, 180,
- * 270 degrees counter-clockwise respectively.
- */
-#define RETRO_ENVIRONMENT_GET_OVERSCAN 2 /* bool * --
- * Boolean value whether or not the implementation should use overscan,
- * or crop away overscan.
- */
-#define RETRO_ENVIRONMENT_GET_CAN_DUPE 3 /* bool * --
- * Boolean value whether or not frontend supports frame duping,
- * passing NULL to video frame callback.
- */
-
- /* Environ 4, 5 are no longer supported (GET_VARIABLE / SET_VARIABLES),
- * and reserved to avoid possible ABI clash.
- */
-
-#define RETRO_ENVIRONMENT_SET_MESSAGE 6 /* const struct retro_message * --
- * Sets a message to be displayed in implementation-specific manner
- * for a certain amount of 'frames'.
- * Should not be used for trivial messages, which should simply be
- * logged via RETRO_ENVIRONMENT_GET_LOG_INTERFACE (or as a
- * fallback, stderr).
- */
-#define RETRO_ENVIRONMENT_SHUTDOWN 7 /* N/A (NULL) --
- * Requests the frontend to shutdown.
- * Should only be used if game has a specific
- * way to shutdown the game from a menu item or similar.
- */
-#define RETRO_ENVIRONMENT_SET_PERFORMANCE_LEVEL 8
- /* const unsigned * --
- * Gives a hint to the frontend how demanding this implementation
- * is on a system. E.g. reporting a level of 2 means
- * this implementation should run decently on all frontends
- * of level 2 and up.
- *
- * It can be used by the frontend to potentially warn
- * about too demanding implementations.
- *
- * The levels are "floating".
- *
- * This function can be called on a per-game basis,
- * as certain games an implementation can play might be
- * particularly demanding.
- * If called, it should be called in retro_load_game().
- */
-#define RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY 9
- /* const char ** --
- * Returns the "system" directory of the frontend.
- * This directory can be used to store system specific
- * content such as BIOSes, configuration data, etc.
- * The returned value can be NULL.
- * If so, no such directory is defined,
- * and it's up to the implementation to find a suitable directory.
- *
- * NOTE: Some cores used this folder also for "save" data such as
- * memory cards, etc, for lack of a better place to put it.
- * This is now discouraged, and if possible, cores should try to
- * use the new GET_SAVE_DIRECTORY.
- */
-#define RETRO_ENVIRONMENT_SET_PIXEL_FORMAT 10
- /* const enum retro_pixel_format * --
- * Sets the internal pixel format used by the implementation.
- * The default pixel format is RETRO_PIXEL_FORMAT_0RGB1555.
- * This pixel format however, is deprecated (see enum retro_pixel_format).
- * If the call returns false, the frontend does not support this pixel
- * format.
- *
- * This function should be called inside retro_load_game() or
- * retro_get_system_av_info().
- */
-#define RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS 11
- /* const struct retro_input_descriptor * --
- * Sets an array of retro_input_descriptors.
- * It is up to the frontend to present this in a usable way.
- * The array is terminated by retro_input_descriptor::description
- * being set to NULL.
- * This function can be called at any time, but it is recommended
- * to call it as early as possible.
- */
-#define RETRO_ENVIRONMENT_SET_KEYBOARD_CALLBACK 12
- /* const struct retro_keyboard_callback * --
- * Sets a callback function used to notify core about keyboard events.
- */
-#define RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE 13
- /* const struct retro_disk_control_callback * --
- * Sets an interface which frontend can use to eject and insert
- * disk images.
- * This is used for games which consist of multiple images and
- * must be manually swapped out by the user (e.g. PSX).
- */
-#define RETRO_ENVIRONMENT_SET_HW_RENDER 14
- /* struct retro_hw_render_callback * --
- * Sets an interface to let a libretro core render with
- * hardware acceleration.
- * Should be called in retro_load_game().
- * If successful, libretro cores will be able to render to a
- * frontend-provided framebuffer.
- * The size of this framebuffer will be at least as large as
- * max_width/max_height provided in get_av_info().
- * If HW rendering is used, pass only RETRO_HW_FRAME_BUFFER_VALID or
- * NULL to retro_video_refresh_t.
- */
-#define RETRO_ENVIRONMENT_GET_VARIABLE 15
- /* struct retro_variable * --
- * Interface to acquire user-defined information from environment
- * that cannot feasibly be supported in a multi-system way.
- * 'key' should be set to a key which has already been set by
- * SET_VARIABLES.
- * 'data' will be set to a value or NULL.
- */
-#define RETRO_ENVIRONMENT_SET_VARIABLES 16
- /* const struct retro_variable * --
- * Allows an implementation to signal the environment
- * which variables it might want to check for later using
- * GET_VARIABLE.
- * This allows the frontend to present these variables to
- * a user dynamically.
- * This should be called as early as possible (ideally in
- * retro_set_environment).
- *
- * 'data' points to an array of retro_variable structs
- * terminated by a { NULL, NULL } element.
- * retro_variable::key should be namespaced to not collide
- * with other implementations' keys. E.g. A core called
- * 'foo' should use keys named as 'foo_option'.
- * retro_variable::value should contain a human readable
- * description of the key as well as a '|' delimited list
- * of expected values.
- *
- * The number of possible options should be very limited,
- * i.e. it should be feasible to cycle through options
- * without a keyboard.
- *
- * First entry should be treated as a default.
- *
- * Example entry:
- * { "foo_option", "Speed hack coprocessor X; false|true" }
- *
- * Text before first ';' is description. This ';' must be
- * followed by a space, and followed by a list of possible
- * values split up with '|'.
- *
- * Only strings are operated on. The possible values will
- * generally be displayed and stored as-is by the frontend.
- */
-#define RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE 17
- /* bool * --
- * Result is set to true if some variables are updated by
- * frontend since last call to RETRO_ENVIRONMENT_GET_VARIABLE.
- * Variables should be queried with GET_VARIABLE.
- */
-#define RETRO_ENVIRONMENT_SET_SUPPORT_NO_GAME 18
- /* const bool * --
- * If true, the libretro implementation supports calls to
- * retro_load_game() with NULL as argument.
- * Used by cores which can run without particular game data.
- * This should be called within retro_set_environment() only.
- */
-#define RETRO_ENVIRONMENT_GET_LIBRETRO_PATH 19
- /* const char ** --
- * Retrieves the absolute path from where this libretro
- * implementation was loaded.
- * NULL is returned if the libretro was loaded statically
- * (i.e. linked statically to frontend), or if the path cannot be
- * determined.
- * Mostly useful in cooperation with SET_SUPPORT_NO_GAME as assets can
- * be loaded without ugly hacks.
- */
-
- /* Environment 20 was an obsolete version of SET_AUDIO_CALLBACK.
- * It was not used by any known core at the time,
- * and was removed from the API. */
-#define RETRO_ENVIRONMENT_SET_AUDIO_CALLBACK 22
- /* const struct retro_audio_callback * --
- * Sets an interface which is used to notify a libretro core about audio
- * being available for writing.
- * The callback can be called from any thread, so a core using this must
- * have a thread safe audio implementation.
- * It is intended for games where audio and video are completely
- * asynchronous and audio can be generated on the fly.
- * This interface is not recommended for use with emulators which have
- * highly synchronous audio.
- *
- * The callback only notifies about writability; the libretro core still
- * has to call the normal audio callbacks
- * to write audio. The audio callbacks must be called from within the
- * notification callback.
- * The amount of audio data to write is up to the implementation.
- * Generally, the audio callback will be called continously in a loop.
- *
- * Due to thread safety guarantees and lack of sync between audio and
- * video, a frontend can selectively disallow this interface based on
- * internal configuration. A core using this interface must also
- * implement the "normal" audio interface.
- *
- * A libretro core using SET_AUDIO_CALLBACK should also make use of
- * SET_FRAME_TIME_CALLBACK.
- */
-#define RETRO_ENVIRONMENT_SET_FRAME_TIME_CALLBACK 21
- /* const struct retro_frame_time_callback * --
- * Lets the core know how much time has passed since last
- * invocation of retro_run().
- * The frontend can tamper with the timing to fake fast-forward,
- * slow-motion, frame stepping, etc.
- * In this case the delta time will use the reference value
- * in frame_time_callback..
- */
-#define RETRO_ENVIRONMENT_GET_RUMBLE_INTERFACE 23
- /* struct retro_rumble_interface * --
- * Gets an interface which is used by a libretro core to set
- * state of rumble motors in controllers.
- * A strong and weak motor is supported, and they can be
- * controlled indepedently.
- */
-#define RETRO_ENVIRONMENT_GET_INPUT_DEVICE_CAPABILITIES 24
- /* uint64_t * --
- * Gets a bitmask telling which device type are expected to be
- * handled properly in a call to retro_input_state_t.
- * Devices which are not handled or recognized always return
- * 0 in retro_input_state_t.
- * Example bitmask: caps = (1 << RETRO_DEVICE_JOYPAD) | (1 << RETRO_DEVICE_ANALOG).
- * Should only be called in retro_run().
- */
-#define RETRO_ENVIRONMENT_GET_SENSOR_INTERFACE (25 | RETRO_ENVIRONMENT_EXPERIMENTAL)
- /* struct retro_sensor_interface * --
- * Gets access to the sensor interface.
- * The purpose of this interface is to allow
- * setting state related to sensors such as polling rate,
- * enabling/disable it entirely, etc.
- * Reading sensor state is done via the normal
- * input_state_callback API.
- */
-#define RETRO_ENVIRONMENT_GET_CAMERA_INTERFACE (26 | RETRO_ENVIRONMENT_EXPERIMENTAL)
- /* struct retro_camera_callback * --
- * Gets an interface to a video camera driver.
- * A libretro core can use this interface to get access to a
- * video camera.
- * New video frames are delivered in a callback in same
- * thread as retro_run().
- *
- * GET_CAMERA_INTERFACE should be called in retro_load_game().
- *
- * Depending on the camera implementation used, camera frames
- * will be delivered as a raw framebuffer,
- * or as an OpenGL texture directly.
- *
- * The core has to tell the frontend here which types of
- * buffers can be handled properly.
- * An OpenGL texture can only be handled when using a
- * libretro GL core (SET_HW_RENDER).
- * It is recommended to use a libretro GL core when
- * using camera interface.
- *
- * The camera is not started automatically. The retrieved start/stop
- * functions must be used to explicitly
- * start and stop the camera driver.
- */
-#define RETRO_ENVIRONMENT_GET_LOG_INTERFACE 27
- /* struct retro_log_callback * --
- * Gets an interface for logging. This is useful for
- * logging in a cross-platform way
- * as certain platforms cannot use use stderr for logging.
- * It also allows the frontend to
- * show logging information in a more suitable way.
- * If this interface is not used, libretro cores should
- * log to stderr as desired.
- */
-#define RETRO_ENVIRONMENT_GET_PERF_INTERFACE 28
- /* struct retro_perf_callback * --
- * Gets an interface for performance counters. This is useful
- * for performance logging in a cross-platform way and for detecting
- * architecture-specific features, such as SIMD support.
- */
-#define RETRO_ENVIRONMENT_GET_LOCATION_INTERFACE 29
- /* struct retro_location_callback * --
- * Gets access to the location interface.
- * The purpose of this interface is to be able to retrieve
- * location-based information from the host device,
- * such as current latitude / longitude.
- */
-#define RETRO_ENVIRONMENT_GET_CONTENT_DIRECTORY 30
- /* const char ** --
- * Returns the "content" directory of the frontend.
- * This directory can be used to store specific assets that the
- * core relies upon, such as art assets,
- * input data, etc etc.
- * The returned value can be NULL.
- * If so, no such directory is defined,
- * and it's up to the implementation to find a suitable directory.
- */
-#define RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY 31
- /* const char ** --
- * Returns the "save" directory of the frontend.
- * This directory can be used to store SRAM, memory cards,
- * high scores, etc, if the libretro core
- * cannot use the regular memory interface (retro_get_memory_data()).
- *
- * NOTE: libretro cores used to check GET_SYSTEM_DIRECTORY for
- * similar things before.
- * They should still check GET_SYSTEM_DIRECTORY if they want to
- * be backwards compatible.
- * The path here can be NULL. It should only be non-NULL if the
- * frontend user has set a specific save path.
- */
-#define RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO 32
- /* const struct retro_system_av_info * --
- * Sets a new av_info structure. This can only be called from
- * within retro_run().
- * This should *only* be used if the core is completely altering the
- * internal resolutions, aspect ratios, timings, sampling rate, etc.
- * Calling this can require a full reinitialization of video/audio
- * drivers in the frontend,
- *
- * so it is important to call it very sparingly, and usually only with
- * the users explicit consent.
- * An eventual driver reinitialize will happen so that video and
- * audio callbacks
- * happening after this call within the same retro_run() call will
- * target the newly initialized driver.
- *
- * This callback makes it possible to support configurable resolutions
- * in games, which can be useful to
- * avoid setting the "worst case" in max_width/max_height.
- *
- * ***HIGHLY RECOMMENDED*** Do not call this callback every time
- * resolution changes in an emulator core if it's
- * expected to be a temporary change, for the reasons of possible
- * driver reinitialization.
- * This call is not a free pass for not trying to provide
- * correct values in retro_get_system_av_info(). If you need to change
- * things like aspect ratio or nominal width/height,
- * use RETRO_ENVIRONMENT_SET_GEOMETRY, which is a softer variant
- * of SET_SYSTEM_AV_INFO.
- *
- * If this returns false, the frontend does not acknowledge a
- * changed av_info struct.
- */
-#define RETRO_ENVIRONMENT_SET_PROC_ADDRESS_CALLBACK 33
- /* const struct retro_get_proc_address_interface * --
- * Allows a libretro core to announce support for the
- * get_proc_address() interface.
- * This interface allows for a standard way to extend libretro where
- * use of environment calls are too indirect,
- * e.g. for cases where the frontend wants to call directly into the core.
- *
- * If a core wants to expose this interface, SET_PROC_ADDRESS_CALLBACK
- * **MUST** be called from within retro_set_environment().
- */
-#define RETRO_ENVIRONMENT_SET_SUBSYSTEM_INFO 34
- /* const struct retro_subsystem_info * --
- * This environment call introduces the concept of libretro "subsystems".
- * A subsystem is a variant of a libretro core which supports
- * different kinds of games.
- * The purpose of this is to support e.g. emulators which might
- * have special needs, e.g. Super Nintendo's Super GameBoy, Sufami Turbo.
- * It can also be used to pick among subsystems in an explicit way
- * if the libretro implementation is a multi-system emulator itself.
- *
- * Loading a game via a subsystem is done with retro_load_game_special(),
- * and this environment call allows a libretro core to expose which
- * subsystems are supported for use with retro_load_game_special().
- * A core passes an array of retro_game_special_info which is terminated
- * with a zeroed out retro_game_special_info struct.
- *
- * If a core wants to use this functionality, SET_SUBSYSTEM_INFO
- * **MUST** be called from within retro_set_environment().
- */
-#define RETRO_ENVIRONMENT_SET_CONTROLLER_INFO 35
- /* const struct retro_controller_info * --
- * This environment call lets a libretro core tell the frontend
- * which controller types are recognized in calls to
- * retro_set_controller_port_device().
- *
- * Some emulators such as Super Nintendo
- * support multiple lightgun types which must be specifically
- * selected from.
- * It is therefore sometimes necessary for a frontend to be able
- * to tell the core about a special kind of input device which is
- * not covered by the libretro input API.
- *
- * In order for a frontend to understand the workings of an input device,
- * it must be a specialized type
- * of the generic device types already defined in the libretro API.
- *
- * Which devices are supported can vary per input port.
- * The core must pass an array of const struct retro_controller_info which
- * is terminated with a blanked out struct. Each element of the struct
- * corresponds to an ascending port index to
- * retro_set_controller_port_device().
- * Even if special device types are set in the libretro core,
- * libretro should only poll input based on the base input device types.
- */
-#define RETRO_ENVIRONMENT_SET_MEMORY_MAPS (36 | RETRO_ENVIRONMENT_EXPERIMENTAL)
- /* const struct retro_memory_map * --
- * This environment call lets a libretro core tell the frontend
- * about the memory maps this core emulates.
- * This can be used to implement, for example, cheats in a core-agnostic way.
- *
- * Should only be used by emulators; it doesn't make much sense for
- * anything else.
- * It is recommended to expose all relevant pointers through
- * retro_get_memory_* as well.
- *
- * Can be called from retro_init and retro_load_game.
- */
-#define RETRO_ENVIRONMENT_SET_GEOMETRY 37
- /* const struct retro_game_geometry * --
- * This environment call is similar to SET_SYSTEM_AV_INFO for changing
- * video parameters, but provides a guarantee that drivers will not be
- * reinitialized.
- * This can only be called from within retro_run().
- *
- * The purpose of this call is to allow a core to alter nominal
- * width/heights as well as aspect ratios on-the-fly, which can be
- * useful for some emulators to change in run-time.
- *
- * max_width/max_height arguments are ignored and cannot be changed
- * with this call as this could potentially require a reinitialization or a
- * non-constant time operation.
- * If max_width/max_height are to be changed, SET_SYSTEM_AV_INFO is required.
- *
- * A frontend must guarantee that this environment call completes in
- * constant time.
- */
-#define RETRO_ENVIRONMENT_GET_USERNAME 38
- /* const char **
- * Returns the specified username of the frontend, if specified by the user.
- * This username can be used as a nickname for a core that has online facilities
- * or any other mode where personalization of the user is desirable.
- * The returned value can be NULL.
- * If this environ callback is used by a core that requires a valid username,
- * a default username should be specified by the core.
- */
-#define RETRO_ENVIRONMENT_GET_LANGUAGE 39
- /* unsigned * --
- * Returns the specified language of the frontend, if specified by the user.
- * It can be used by the core for localization purposes.
- */
-
-#define RETRO_MEMDESC_CONST (1 << 0) /* The frontend will never change this memory area once retro_load_game has returned. */
-#define RETRO_MEMDESC_BIGENDIAN (1 << 1) /* The memory area contains big endian data. Default is little endian. */
-#define RETRO_MEMDESC_ALIGN_2 (1 << 16) /* All memory access in this area is aligned to their own size, or 2, whichever is smaller. */
-#define RETRO_MEMDESC_ALIGN_4 (2 << 16)
-#define RETRO_MEMDESC_ALIGN_8 (3 << 16)
-#define RETRO_MEMDESC_MINSIZE_2 (1 << 24) /* All memory in this region is accessed at least 2 bytes at the time. */
-#define RETRO_MEMDESC_MINSIZE_4 (2 << 24)
-#define RETRO_MEMDESC_MINSIZE_8 (3 << 24)
-struct retro_memory_descriptor
-{
- uint64_t flags;
-
- /* Pointer to the start of the relevant ROM or RAM chip.
- * It's strongly recommended to use 'offset' if possible, rather than
- * doing math on the pointer.
- *
- * If the same byte is mapped my multiple descriptors, their descriptors
- * must have the same pointer.
- * If 'start' does not point to the first byte in the pointer, put the
- * difference in 'offset' instead.
- *
- * May be NULL if there's nothing usable here (e.g. hardware registers and
- * open bus). No flags should be set if the pointer is NULL.
- * It's recommended to minimize the number of descriptors if possible,
- * but not mandatory. */
- void *ptr;
- size_t offset;
-
- /* This is the location in the emulated address space
- * where the mapping starts. */
- size_t start;
-
- /* Which bits must be same as in 'start' for this mapping to apply.
- * The first memory descriptor to claim a certain byte is the one
- * that applies.
- * A bit which is set in 'start' must also be set in this.
- * Can be zero, in which case each byte is assumed mapped exactly once.
- * In this case, 'len' must be a power of two. */
- size_t select;
-
- /* If this is nonzero, the set bits are assumed not connected to the
- * memory chip's address pins. */
- size_t disconnect;
-
- /* This one tells the size of the current memory area.
- * If, after start+disconnect are applied, the address is higher than
- * this, the highest bit of the address is cleared.
- *
- * If the address is still too high, the next highest bit is cleared.
- * Can be zero, in which case it's assumed to be infinite (as limited
- * by 'select' and 'disconnect'). */
- size_t len;
-
- /* To go from emulated address to physical address, the following
- * order applies:
- * Subtract 'start', pick off 'disconnect', apply 'len', add 'offset'.
- *
- * The address space name must consist of only a-zA-Z0-9_-,
- * should be as short as feasible (maximum length is 8 plus the NUL),
- * and may not be any other address space plus one or more 0-9A-F
- * at the end.
- * However, multiple memory descriptors for the same address space is
- * allowed, and the address space name can be empty. NULL is treated
- * as empty.
- *
- * Address space names are case sensitive, but avoid lowercase if possible.
- * The same pointer may exist in multiple address spaces.
- *
- * Examples:
- * blank+blank - valid (multiple things may be mapped in the same namespace)
- * 'Sp'+'Sp' - valid (multiple things may be mapped in the same namespace)
- * 'A'+'B' - valid (neither is a prefix of each other)
- * 'S'+blank - valid ('S' is not in 0-9A-F)
- * 'a'+blank - valid ('a' is not in 0-9A-F)
- * 'a'+'A' - valid (neither is a prefix of each other)
- * 'AR'+blank - valid ('R' is not in 0-9A-F)
- * 'ARB'+blank - valid (the B can't be part of the address either, because
- * there is no namespace 'AR')
- * blank+'B' - not valid, because it's ambigous which address space B1234
- * would refer to.
- * The length can't be used for that purpose; the frontend may want
- * to append arbitrary data to an address, without a separator. */
- const char *addrspace;
-};
-
-/* The frontend may use the largest value of 'start'+'select' in a
- * certain namespace to infer the size of the address space.
- *
- * If the address space is larger than that, a mapping with .ptr=NULL
- * should be at the end of the array, with .select set to all ones for
- * as long as the address space is big.
- *
- * Sample descriptors (minus .ptr, and RETRO_MEMFLAG_ on the flags):
- * SNES WRAM:
- * .start=0x7E0000, .len=0x20000
- * (Note that this must be mapped before the ROM in most cases; some of the
- * ROM mappers
- * try to claim $7E0000, or at least $7E8000.)
- * SNES SPC700 RAM:
- * .addrspace="S", .len=0x10000
- * SNES WRAM mirrors:
- * .flags=MIRROR, .start=0x000000, .select=0xC0E000, .len=0x2000
- * .flags=MIRROR, .start=0x800000, .select=0xC0E000, .len=0x2000
- * SNES WRAM mirrors, alternate equivalent descriptor:
- * .flags=MIRROR, .select=0x40E000, .disconnect=~0x1FFF
- * (Various similar constructions can be created by combining parts of
- * the above two.)
- * SNES LoROM (512KB, mirrored a couple of times):
- * .flags=CONST, .start=0x008000, .select=0x408000, .disconnect=0x8000, .len=512*1024
- * .flags=CONST, .start=0x400000, .select=0x400000, .disconnect=0x8000, .len=512*1024
- * SNES HiROM (4MB):
- * .flags=CONST, .start=0x400000, .select=0x400000, .len=4*1024*1024
- * .flags=CONST, .offset=0x8000, .start=0x008000, .select=0x408000, .len=4*1024*1024
- * SNES ExHiROM (8MB):
- * .flags=CONST, .offset=0, .start=0xC00000, .select=0xC00000, .len=4*1024*1024
- * .flags=CONST, .offset=4*1024*1024, .start=0x400000, .select=0xC00000, .len=4*1024*1024
- * .flags=CONST, .offset=0x8000, .start=0x808000, .select=0xC08000, .len=4*1024*1024
- * .flags=CONST, .offset=4*1024*1024+0x8000, .start=0x008000, .select=0xC08000, .len=4*1024*1024
- * Clarify the size of the address space:
- * .ptr=NULL, .select=0xFFFFFF
- * .len can be implied by .select in many of them, but was included for clarity.
- */
-
-struct retro_memory_map
-{
- const struct retro_memory_descriptor *descriptors;
- unsigned num_descriptors;
-};
-
-struct retro_controller_description
-{
- /* Human-readable description of the controller. Even if using a generic
- * input device type, this can be set to the particular device type the
- * core uses. */
- const char *desc;
-
- /* Device type passed to retro_set_controller_port_device(). If the device
- * type is a sub-class of a generic input device type, use the
- * RETRO_DEVICE_SUBCLASS macro to create an ID.
- *
- * E.g. RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 1). */
- unsigned id;
-};
-
-struct retro_controller_info
-{
- const struct retro_controller_description *types;
- unsigned num_types;
-};
-
-struct retro_subsystem_memory_info
-{
- /* The extension associated with a memory type, e.g. "psram". */
- const char *extension;
-
- /* The memory type for retro_get_memory(). This should be at
- * least 0x100 to avoid conflict with standardized
- * libretro memory types. */
- unsigned type;
-};
-
-struct retro_subsystem_rom_info
-{
- /* Describes what the content is (SGB BIOS, GB ROM, etc). */
- const char *desc;
-
- /* Same definition as retro_get_system_info(). */
- const char *valid_extensions;
-
- /* Same definition as retro_get_system_info(). */
- bool need_fullpath;
-
- /* Same definition as retro_get_system_info(). */
- bool block_extract;
-
- /* This is set if the content is required to load a game.
- * If this is set to false, a zeroed-out retro_game_info can be passed. */
- bool required;
-
- /* Content can have multiple associated persistent
- * memory types (retro_get_memory()). */
- const struct retro_subsystem_memory_info *memory;
- unsigned num_memory;
-};
-
-struct retro_subsystem_info
-{
- /* Human-readable string of the subsystem type, e.g. "Super GameBoy" */
- const char *desc;
-
- /* A computer friendly short string identifier for the subsystem type.
- * This name must be [a-z].
- * E.g. if desc is "Super GameBoy", this can be "sgb".
- * This identifier can be used for command-line interfaces, etc.
- */
- const char *ident;
-
- /* Infos for each content file. The first entry is assumed to be the
- * "most significant" content for frontend purposes.
- * E.g. with Super GameBoy, the first content should be the GameBoy ROM,
- * as it is the most "significant" content to a user.
- * If a frontend creates new file paths based on the content used
- * (e.g. savestates), it should use the path for the first ROM to do so. */
- const struct retro_subsystem_rom_info *roms;
-
- /* Number of content files associated with a subsystem. */
- unsigned num_roms;
-
- /* The type passed to retro_load_game_special(). */
- unsigned id;
-};
-
-typedef void (*retro_proc_address_t)(void);
-
-/* libretro API extension functions:
- * (None here so far).
- *
- * Get a symbol from a libretro core.
- * Cores should only return symbols which are actual
- * extensions to the libretro API.
- *
- * Frontends should not use this to obtain symbols to standard
- * libretro entry points (static linking or dlsym).
- *
- * The symbol name must be equal to the function name,
- * e.g. if void retro_foo(void); exists, the symbol must be called "retro_foo".
- * The returned function pointer must be cast to the corresponding type.
- */
-typedef retro_proc_address_t (*retro_get_proc_address_t)(const char *sym);
-
-struct retro_get_proc_address_interface
-{
- retro_get_proc_address_t get_proc_address;
-};
-
-enum retro_log_level
-{
- RETRO_LOG_DEBUG = 0,
- RETRO_LOG_INFO,
- RETRO_LOG_WARN,
- RETRO_LOG_ERROR,
-
- RETRO_LOG_DUMMY = INT_MAX
-};
-
-/* Logging function. Takes log level argument as well. */
-typedef void (*retro_log_printf_t)(enum retro_log_level level,
- const char *fmt, ...);
-
-struct retro_log_callback
-{
- retro_log_printf_t log;
-};
-
-/* Performance related functions */
-
-/* ID values for SIMD CPU features */
-#define RETRO_SIMD_SSE (1 << 0)
-#define RETRO_SIMD_SSE2 (1 << 1)
-#define RETRO_SIMD_VMX (1 << 2)
-#define RETRO_SIMD_VMX128 (1 << 3)
-#define RETRO_SIMD_AVX (1 << 4)
-#define RETRO_SIMD_NEON (1 << 5)
-#define RETRO_SIMD_SSE3 (1 << 6)
-#define RETRO_SIMD_SSSE3 (1 << 7)
-#define RETRO_SIMD_MMX (1 << 8)
-#define RETRO_SIMD_MMXEXT (1 << 9)
-#define RETRO_SIMD_SSE4 (1 << 10)
-#define RETRO_SIMD_SSE42 (1 << 11)
-#define RETRO_SIMD_AVX2 (1 << 12)
-#define RETRO_SIMD_VFPU (1 << 13)
-#define RETRO_SIMD_PS (1 << 14)
-#define RETRO_SIMD_AES (1 << 15)
-
-typedef uint64_t retro_perf_tick_t;
-typedef int64_t retro_time_t;
-
-struct retro_perf_counter
-{
- const char *ident;
- retro_perf_tick_t start;
- retro_perf_tick_t total;
- retro_perf_tick_t call_cnt;
-
- bool registered;
-};
-
-/* Returns current time in microseconds.
- * Tries to use the most accurate timer available.
- */
-typedef retro_time_t (*retro_perf_get_time_usec_t)(void);
-
-/* A simple counter. Usually nanoseconds, but can also be CPU cycles.
- * Can be used directly if desired (when creating a more sophisticated
- * performance counter system).
- * */
-typedef retro_perf_tick_t (*retro_perf_get_counter_t)(void);
-
-/* Returns a bit-mask of detected CPU features (RETRO_SIMD_*). */
-typedef uint64_t (*retro_get_cpu_features_t)(void);
-
-/* Asks frontend to log and/or display the state of performance counters.
- * Performance counters can always be poked into manually as well.
- */
-typedef void (*retro_perf_log_t)(void);
-
-/* Register a performance counter.
- * ident field must be set with a discrete value and other values in
- * retro_perf_counter must be 0.
- * Registering can be called multiple times. To avoid calling to
- * frontend redundantly, you can check registered field first. */
-typedef void (*retro_perf_register_t)(struct retro_perf_counter *counter);
-
-/* Starts a registered counter. */
-typedef void (*retro_perf_start_t)(struct retro_perf_counter *counter);
-
-/* Stops a registered counter. */
-typedef void (*retro_perf_stop_t)(struct retro_perf_counter *counter);
-
-/* For convenience it can be useful to wrap register, start and stop in macros.
- * E.g.:
- * #ifdef LOG_PERFORMANCE
- * #define RETRO_PERFORMANCE_INIT(perf_cb, name) static struct retro_perf_counter name = {#name}; if (!name.registered) perf_cb.perf_register(&(name))
- * #define RETRO_PERFORMANCE_START(perf_cb, name) perf_cb.perf_start(&(name))
- * #define RETRO_PERFORMANCE_STOP(perf_cb, name) perf_cb.perf_stop(&(name))
- * #else
- * ... Blank macros ...
- * #endif
- *
- * These can then be used mid-functions around code snippets.
- *
- * extern struct retro_perf_callback perf_cb; * Somewhere in the core.
- *
- * void do_some_heavy_work(void)
- * {
- * RETRO_PERFORMANCE_INIT(cb, work_1;
- * RETRO_PERFORMANCE_START(cb, work_1);
- * heavy_work_1();
- * RETRO_PERFORMANCE_STOP(cb, work_1);
- *
- * RETRO_PERFORMANCE_INIT(cb, work_2);
- * RETRO_PERFORMANCE_START(cb, work_2);
- * heavy_work_2();
- * RETRO_PERFORMANCE_STOP(cb, work_2);
- * }
- *
- * void retro_deinit(void)
- * {
- * perf_cb.perf_log(); * Log all perf counters here for example.
- * }
- */
-
-struct retro_perf_callback
-{
- retro_perf_get_time_usec_t get_time_usec;
- retro_get_cpu_features_t get_cpu_features;
-
- retro_perf_get_counter_t get_perf_counter;
- retro_perf_register_t perf_register;
- retro_perf_start_t perf_start;
- retro_perf_stop_t perf_stop;
- retro_perf_log_t perf_log;
-};
-
-/* FIXME: Document the sensor API and work out behavior.
- * It will be marked as experimental until then.
- */
-enum retro_sensor_action
-{
- RETRO_SENSOR_ACCELEROMETER_ENABLE = 0,
- RETRO_SENSOR_ACCELEROMETER_DISABLE,
-
- RETRO_SENSOR_DUMMY = INT_MAX
-};
-
-/* Id values for SENSOR types. */
-#define RETRO_SENSOR_ACCELEROMETER_X 0
-#define RETRO_SENSOR_ACCELEROMETER_Y 1
-#define RETRO_SENSOR_ACCELEROMETER_Z 2
-
-typedef bool (*retro_set_sensor_state_t)(unsigned port,
- enum retro_sensor_action action, unsigned rate);
-
-typedef float (*retro_sensor_get_input_t)(unsigned port, unsigned id);
-
-struct retro_sensor_interface
-{
- retro_set_sensor_state_t set_sensor_state;
- retro_sensor_get_input_t get_sensor_input;
-};
-
-enum retro_camera_buffer
-{
- RETRO_CAMERA_BUFFER_OPENGL_TEXTURE = 0,
- RETRO_CAMERA_BUFFER_RAW_FRAMEBUFFER,
-
- RETRO_CAMERA_BUFFER_DUMMY = INT_MAX
-};
-
-/* Starts the camera driver. Can only be called in retro_run(). */
-typedef bool (*retro_camera_start_t)(void);
-
-/* Stops the camera driver. Can only be called in retro_run(). */
-typedef void (*retro_camera_stop_t)(void);
-
-/* Callback which signals when the camera driver is initialized
- * and/or deinitialized.
- * retro_camera_start_t can be called in initialized callback.
- */
-typedef void (*retro_camera_lifetime_status_t)(void);
-
-/* A callback for raw framebuffer data. buffer points to an XRGB8888 buffer.
- * Width, height and pitch are similar to retro_video_refresh_t.
- * First pixel is top-left origin.
- */
-typedef void (*retro_camera_frame_raw_framebuffer_t)(const uint32_t *buffer,
- unsigned width, unsigned height, size_t pitch);
-
-/* A callback for when OpenGL textures are used.
- *
- * texture_id is a texture owned by camera driver.
- * Its state or content should be considered immutable, except for things like
- * texture filtering and clamping.
- *
- * texture_target is the texture target for the GL texture.
- * These can include e.g. GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE, and possibly
- * more depending on extensions.
- *
- * affine points to a packed 3x3 column-major matrix used to apply an affine
- * transform to texture coordinates. (affine_matrix * vec3(coord_x, coord_y, 1.0))
- * After transform, normalized texture coord (0, 0) should be bottom-left
- * and (1, 1) should be top-right (or (width, height) for RECTANGLE).
- *
- * GL-specific typedefs are avoided here to avoid relying on gl.h in
- * the API definition.
- */
-typedef void (*retro_camera_frame_opengl_texture_t)(unsigned texture_id,
- unsigned texture_target, const float *affine);
-
-struct retro_camera_callback
-{
- /* Set by libretro core.
- * Example bitmask: caps = (1 << RETRO_CAMERA_BUFFER_OPENGL_TEXTURE) | (1 << RETRO_CAMERA_BUFFER_RAW_FRAMEBUFFER).
- */
- uint64_t caps;
-
- unsigned width; /* Desired resolution for camera. Is only used as a hint. */
- unsigned height;
- retro_camera_start_t start; /* Set by frontend. */
- retro_camera_stop_t stop; /* Set by frontend. */
-
- /* Set by libretro core if raw framebuffer callbacks will be used. */
- retro_camera_frame_raw_framebuffer_t frame_raw_framebuffer;
- /* Set by libretro core if OpenGL texture callbacks will be used. */
- retro_camera_frame_opengl_texture_t frame_opengl_texture;
-
- /* Set by libretro core. Called after camera driver is initialized and
- * ready to be started.
- * Can be NULL, in which this callback is not called.
- */
- retro_camera_lifetime_status_t initialized;
-
- /* Set by libretro core. Called right before camera driver is
- * deinitialized.
- * Can be NULL, in which this callback is not called.
- */
- retro_camera_lifetime_status_t deinitialized;
-};
-
-/* Sets the interval of time and/or distance at which to update/poll
- * location-based data.
- *
- * To ensure compatibility with all location-based implementations,
- * values for both interval_ms and interval_distance should be provided.
- *
- * interval_ms is the interval expressed in milliseconds.
- * interval_distance is the distance interval expressed in meters.
- */
-typedef void (*retro_location_set_interval_t)(unsigned interval_ms,
- unsigned interval_distance);
-
-/* Start location services. The device will start listening for changes to the
- * current location at regular intervals (which are defined with
- * retro_location_set_interval_t). */
-typedef bool (*retro_location_start_t)(void);
-
-/* Stop location services. The device will stop listening for changes
- * to the current location. */
-typedef void (*retro_location_stop_t)(void);
-
-/* Get the position of the current location. Will set parameters to
- * 0 if no new location update has happened since the last time. */
-typedef bool (*retro_location_get_position_t)(double *lat, double *lon,
- double *horiz_accuracy, double *vert_accuracy);
-
-/* Callback which signals when the location driver is initialized
- * and/or deinitialized.
- * retro_location_start_t can be called in initialized callback.
- */
-typedef void (*retro_location_lifetime_status_t)(void);
-
-struct retro_location_callback
-{
- retro_location_start_t start;
- retro_location_stop_t stop;
- retro_location_get_position_t get_position;
- retro_location_set_interval_t set_interval;
-
- retro_location_lifetime_status_t initialized;
- retro_location_lifetime_status_t deinitialized;
-};
-
-enum retro_rumble_effect
-{
- RETRO_RUMBLE_STRONG = 0,
- RETRO_RUMBLE_WEAK = 1,
-
- RETRO_RUMBLE_DUMMY = INT_MAX
-};
-
-/* Sets rumble state for joypad plugged in port 'port'.
- * Rumble effects are controlled independently,
- * and setting e.g. strong rumble does not override weak rumble.
- * Strength has a range of [0, 0xffff].
- *
- * Returns true if rumble state request was honored.
- * Calling this before first retro_run() is likely to return false. */
-typedef bool (*retro_set_rumble_state_t)(unsigned port,
- enum retro_rumble_effect effect, uint16_t strength);
-
-struct retro_rumble_interface
-{
- retro_set_rumble_state_t set_rumble_state;
-};
-
-/* Notifies libretro that audio data should be written. */
-typedef void (*retro_audio_callback_t)(void);
-
-/* True: Audio driver in frontend is active, and callback is
- * expected to be called regularily.
- * False: Audio driver in frontend is paused or inactive.
- * Audio callback will not be called until set_state has been
- * called with true.
- * Initial state is false (inactive).
- */
-typedef void (*retro_audio_set_state_callback_t)(bool enabled);
-
-struct retro_audio_callback
-{
- retro_audio_callback_t callback;
- retro_audio_set_state_callback_t set_state;
-};
-
-/* Notifies a libretro core of time spent since last invocation
- * of retro_run() in microseconds.
- *
- * It will be called right before retro_run() every frame.
- * The frontend can tamper with timing to support cases like
- * fast-forward, slow-motion and framestepping.
- *
- * In those scenarios the reference frame time value will be used. */
-typedef int64_t retro_usec_t;
-typedef void (*retro_frame_time_callback_t)(retro_usec_t usec);
-struct retro_frame_time_callback
-{
- retro_frame_time_callback_t callback;
- /* Represents the time of one frame. It is computed as
- * 1000000 / fps, but the implementation will resolve the
- * rounding to ensure that framestepping, etc is exact. */
- retro_usec_t reference;
-};
-
-/* Pass this to retro_video_refresh_t if rendering to hardware.
- * Passing NULL to retro_video_refresh_t is still a frame dupe as normal.
- * */
-#define RETRO_HW_FRAME_BUFFER_VALID ((void*)-1)
-
-/* Invalidates the current HW context.
- * Any GL state is lost, and must not be deinitialized explicitly.
- * If explicit deinitialization is desired by the libretro core,
- * it should implement context_destroy callback.
- * If called, all GPU resources must be reinitialized.
- * Usually called when frontend reinits video driver.
- * Also called first time video driver is initialized,
- * allowing libretro core to initialize resources.
- */
-typedef void (*retro_hw_context_reset_t)(void);
-
-/* Gets current framebuffer which is to be rendered to.
- * Could change every frame potentially.
- */
-typedef uintptr_t (*retro_hw_get_current_framebuffer_t)(void);
-
-/* Get a symbol from HW context. */
-typedef retro_proc_address_t (*retro_hw_get_proc_address_t)(const char *sym);
-
-enum retro_hw_context_type
-{
- RETRO_HW_CONTEXT_NONE = 0,
- /* OpenGL 2.x. Driver can choose to use latest compatibility context. */
- RETRO_HW_CONTEXT_OPENGL = 1,
- /* OpenGL ES 2.0. */
- RETRO_HW_CONTEXT_OPENGLES2 = 2,
- /* Modern desktop core GL context. Use version_major/
- * version_minor fields to set GL version. */
- RETRO_HW_CONTEXT_OPENGL_CORE = 3,
- /* OpenGL ES 3.0 */
- RETRO_HW_CONTEXT_OPENGLES3 = 4,
- /* OpenGL ES 3.1+. Set version_major/version_minor. For GLES2 and GLES3,
- * use the corresponding enums directly. */
- RETRO_HW_CONTEXT_OPENGLES_VERSION = 5,
-
- RETRO_HW_CONTEXT_DUMMY = INT_MAX
-};
-
-struct retro_hw_render_callback
-{
- /* Which API to use. Set by libretro core. */
- enum retro_hw_context_type context_type;
-
- /* Called when a context has been created or when it has been reset.
- * An OpenGL context is only valid after context_reset() has been called.
- *
- * When context_reset is called, OpenGL resources in the libretro
- * implementation are guaranteed to be invalid.
- *
- * It is possible that context_reset is called multiple times during an
- * application lifecycle.
- * If context_reset is called without any notification (context_destroy),
- * the OpenGL context was lost and resources should just be recreated
- * without any attempt to "free" old resources.
- */
- retro_hw_context_reset_t context_reset;
-
- /* Set by frontend. */
- retro_hw_get_current_framebuffer_t get_current_framebuffer;
-
- /* Set by frontend. */
- retro_hw_get_proc_address_t get_proc_address;
-
- /* Set if render buffers should have depth component attached. */
- bool depth;
-
- /* Set if stencil buffers should be attached. */
- bool stencil;
-
- /* If depth and stencil are true, a packed 24/8 buffer will be added.
- * Only attaching stencil is invalid and will be ignored. */
-
- /* Use conventional bottom-left origin convention. If false,
- * standard libretro top-left origin semantics are used. */
- bool bottom_left_origin;
-
- /* Major version number for core GL context or GLES 3.1+. */
- unsigned version_major;
-
- /* Minor version number for core GL context or GLES 3.1+. */
- unsigned version_minor;
-
- /* If this is true, the frontend will go very far to avoid
- * resetting context in scenarios like toggling fullscreen, etc.
- */
- bool cache_context;
-
- /* The reset callback might still be called in extreme situations
- * such as if the context is lost beyond recovery.
- *
- * For optimal stability, set this to false, and allow context to be
- * reset at any time.
- */
-
- /* A callback to be called before the context is destroyed in a
- * controlled way by the frontend. */
- retro_hw_context_reset_t context_destroy;
-
- /* OpenGL resources can be deinitialized cleanly at this step.
- * context_destroy can be set to NULL, in which resources will
- * just be destroyed without any notification.
- *
- * Even when context_destroy is non-NULL, it is possible that
- * context_reset is called without any destroy notification.
- * This happens if context is lost by external factors (such as
- * notified by GL_ARB_robustness).
- *
- * In this case, the context is assumed to be already dead,
- * and the libretro implementation must not try to free any OpenGL
- * resources in the subsequent context_reset.
- */
-
- /* Creates a debug context. */
- bool debug_context;
-};
-
-/* Callback type passed in RETRO_ENVIRONMENT_SET_KEYBOARD_CALLBACK.
- * Called by the frontend in response to keyboard events.
- * down is set if the key is being pressed, or false if it is being released.
- * keycode is the RETROK value of the char.
- * character is the text character of the pressed key. (UTF-32).
- * key_modifiers is a set of RETROKMOD values or'ed together.
- *
- * The pressed/keycode state can be indepedent of the character.
- * It is also possible that multiple characters are generated from a
- * single keypress.
- * Keycode events should be treated separately from character events.
- * However, when possible, the frontend should try to synchronize these.
- * If only a character is posted, keycode should be RETROK_UNKNOWN.
- *
- * Similarily if only a keycode event is generated with no corresponding
- * character, character should be 0.
- */
-typedef void (*retro_keyboard_event_t)(bool down, unsigned keycode,
- uint32_t character, uint16_t key_modifiers);
-
-struct retro_keyboard_callback
-{
- retro_keyboard_event_t callback;
-};
-
-/* Callbacks for RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE.
- * Should be set for implementations which can swap out multiple disk
- * images in runtime.
- *
- * If the implementation can do this automatically, it should strive to do so.
- * However, there are cases where the user must manually do so.
- *
- * Overview: To swap a disk image, eject the disk image with
- * set_eject_state(true).
- * Set the disk index with set_image_index(index). Insert the disk again
- * with set_eject_state(false).
- */
-
-/* If ejected is true, "ejects" the virtual disk tray.
- * When ejected, the disk image index can be set.
- */
-typedef bool (*retro_set_eject_state_t)(bool ejected);
-
-/* Gets current eject state. The initial state is 'not ejected'. */
-typedef bool (*retro_get_eject_state_t)(void);
-
-/* Gets current disk index. First disk is index 0.
- * If return value is >= get_num_images(), no disk is currently inserted.
- */
-typedef unsigned (*retro_get_image_index_t)(void);
-
-/* Sets image index. Can only be called when disk is ejected.
- * The implementation supports setting "no disk" by using an
- * index >= get_num_images().
- */
-typedef bool (*retro_set_image_index_t)(unsigned index);
-
-/* Gets total number of images which are available to use. */
-typedef unsigned (*retro_get_num_images_t)(void);
-
-struct retro_game_info;
-
-/* Replaces the disk image associated with index.
- * Arguments to pass in info have same requirements as retro_load_game().
- * Virtual disk tray must be ejected when calling this.
- *
- * Replacing a disk image with info = NULL will remove the disk image
- * from the internal list.
- * As a result, calls to get_image_index() can change.
- *
- * E.g. replace_image_index(1, NULL), and previous get_image_index()
- * returned 4 before.
- * Index 1 will be removed, and the new index is 3.
- */
-typedef bool (*retro_replace_image_index_t)(unsigned index,
- const struct retro_game_info *info);
-
-/* Adds a new valid index (get_num_images()) to the internal disk list.
- * This will increment subsequent return values from get_num_images() by 1.
- * This image index cannot be used until a disk image has been set
- * with replace_image_index. */
-typedef bool (*retro_add_image_index_t)(void);
-
-struct retro_disk_control_callback
-{
- retro_set_eject_state_t set_eject_state;
- retro_get_eject_state_t get_eject_state;
-
- retro_get_image_index_t get_image_index;
- retro_set_image_index_t set_image_index;
- retro_get_num_images_t get_num_images;
-
- retro_replace_image_index_t replace_image_index;
- retro_add_image_index_t add_image_index;
-};
-
-enum retro_pixel_format
-{
- /* 0RGB1555, native endian.
- * 0 bit must be set to 0.
- * This pixel format is default for compatibility concerns only.
- * If a 15/16-bit pixel format is desired, consider using RGB565. */
- RETRO_PIXEL_FORMAT_0RGB1555 = 0,
-
- /* XRGB8888, native endian.
- * X bits are ignored. */
- RETRO_PIXEL_FORMAT_XRGB8888 = 1,
-
- /* RGB565, native endian.
- * This pixel format is the recommended format to use if a 15/16-bit
- * format is desired as it is the pixel format that is typically
- * available on a wide range of low-power devices.
- *
- * It is also natively supported in APIs like OpenGL ES. */
- RETRO_PIXEL_FORMAT_RGB565 = 2,
-
- /* Ensure sizeof() == sizeof(int). */
- RETRO_PIXEL_FORMAT_UNKNOWN = INT_MAX
-};
-
-struct retro_message
-{
- const char *msg; /* Message to be displayed. */
- unsigned frames; /* Duration in frames of message. */
-};
-
-/* Describes how the libretro implementation maps a libretro input bind
- * to its internal input system through a human readable string.
- * This string can be used to better let a user configure input. */
-struct retro_input_descriptor
-{
- /* Associates given parameters with a description. */
- unsigned port;
- unsigned device;
- unsigned index;
- unsigned id;
-
- /* Human readable description for parameters.
- * The pointer must remain valid until
- * retro_unload_game() is called. */
- const char *description;
-};
-
-struct retro_system_info
-{
- /* All pointers are owned by libretro implementation, and pointers must
- * remain valid until retro_deinit() is called. */
-
- const char *library_name; /* Descriptive name of library. Should not
- * contain any version numbers, etc. */
- const char *library_version; /* Descriptive version of core. */
-
- const char *valid_extensions; /* A string listing probably content
- * extensions the core will be able to
- * load, separated with pipe.
- * I.e. "bin|rom|iso".
- * Typically used for a GUI to filter
- * out extensions. */
-
- /* If true, retro_load_game() is guaranteed to provide a valid pathname
- * in retro_game_info::path.
- * ::data and ::size are both invalid.
- *
- * If false, ::data and ::size are guaranteed to be valid, but ::path
- * might not be valid.
- *
- * This is typically set to true for libretro implementations that must
- * load from file.
- * Implementations should strive for setting this to false, as it allows
- * the frontend to perform patching, etc. */
- bool need_fullpath;
-
- /* If true, the frontend is not allowed to extract any archives before
- * loading the real content.
- * Necessary for certain libretro implementations that load games
- * from zipped archives. */
- bool block_extract;
-};
-
-struct retro_game_geometry
-{
- unsigned base_width; /* Nominal video width of game. */
- unsigned base_height; /* Nominal video height of game. */
- unsigned max_width; /* Maximum possible width of game. */
- unsigned max_height; /* Maximum possible height of game. */
-
- float aspect_ratio; /* Nominal aspect ratio of game. If
- * aspect_ratio is <= 0.0, an aspect ratio
- * of base_width / base_height is assumed.
- * A frontend could override this setting,
- * if desired. */
-};
-
-struct retro_system_timing
-{
- double fps; /* FPS of video content. */
- double sample_rate; /* Sampling rate of audio. */
-};
-
-struct retro_system_av_info
-{
- struct retro_game_geometry geometry;
- struct retro_system_timing timing;
-};
-
-struct retro_variable
-{
- /* Variable to query in RETRO_ENVIRONMENT_GET_VARIABLE.
- * If NULL, obtains the complete environment string if more
- * complex parsing is necessary.
- * The environment string is formatted as key-value pairs
- * delimited by semicolons as so:
- * "key1=value1;key2=value2;..."
- */
- const char *key;
-
- /* Value to be obtained. If key does not exist, it is set to NULL. */
- const char *value;
-};
-
-struct retro_game_info
-{
- const char *path; /* Path to game, UTF-8 encoded.
- * Usually used as a reference.
- * May be NULL if rom was loaded from stdin
- * or similar.
- * retro_system_info::need_fullpath guaranteed
- * that this path is valid. */
- const void *data; /* Memory buffer of loaded game. Will be NULL
- * if need_fullpath was set. */
- size_t size; /* Size of memory buffer. */
- const char *meta; /* String of implementation specific meta-data. */
-};
-
-/* Callbacks */
-
-/* Environment callback. Gives implementations a way of performing
- * uncommon tasks. Extensible. */
-typedef bool (*retro_environment_t)(unsigned cmd, void *data);
-
-/* Render a frame. Pixel format is 15-bit 0RGB1555 native endian
- * unless changed (see RETRO_ENVIRONMENT_SET_PIXEL_FORMAT).
- *
- * Width and height specify dimensions of buffer.
- * Pitch specifices length in bytes between two lines in buffer.
- *
- * For performance reasons, it is highly recommended to have a frame
- * that is packed in memory, i.e. pitch == width * byte_per_pixel.
- * Certain graphic APIs, such as OpenGL ES, do not like textures
- * that are not packed in memory.
- */
-typedef void (*retro_video_refresh_t)(const void *data, unsigned width,
- unsigned height, size_t pitch);
-
-/* Renders a single audio frame. Should only be used if implementation
- * generates a single sample at a time.
- * Format is signed 16-bit native endian.
- */
-typedef void (*retro_audio_sample_t)(int16_t left, int16_t right);
-
-/* Renders multiple audio frames in one go.
- *
- * One frame is defined as a sample of left and right channels, interleaved.
- * I.e. int16_t buf[4] = { l, r, l, r }; would be 2 frames.
- * Only one of the audio callbacks must ever be used.
- */
-typedef size_t (*retro_audio_sample_batch_t)(const int16_t *data,
- size_t frames);
-
-/* Polls input. */
-typedef void (*retro_input_poll_t)(void);
-
-/* Queries for input for player 'port'. device will be masked with
- * RETRO_DEVICE_MASK.
- *
- * Specialization of devices such as RETRO_DEVICE_JOYPAD_MULTITAP that
- * have been set with retro_set_controller_port_device()
- * will still use the higher level RETRO_DEVICE_JOYPAD to request input.
- */
-typedef int16_t (*retro_input_state_t)(unsigned port, unsigned device,
- unsigned index, unsigned id);
-
-/* Sets callbacks. retro_set_environment() is guaranteed to be called
- * before retro_init().
- *
- * The rest of the set_* functions are guaranteed to have been called
- * before the first call to retro_run() is made. */
-void retro_set_environment(retro_environment_t);
-void retro_set_video_refresh(retro_video_refresh_t);
-void retro_set_audio_sample(retro_audio_sample_t);
-void retro_set_audio_sample_batch(retro_audio_sample_batch_t);
-void retro_set_input_poll(retro_input_poll_t);
-void retro_set_input_state(retro_input_state_t);
-
-/* Library global initialization/deinitialization. */
-void retro_init(void);
-void retro_deinit(void);
-
-/* Must return RETRO_API_VERSION. Used to validate ABI compatibility
- * when the API is revised. */
-unsigned retro_api_version(void);
-
-/* Gets statically known system info. Pointers provided in *info
- * must be statically allocated.
- * Can be called at any time, even before retro_init(). */
-void retro_get_system_info(struct retro_system_info *info);
-
-/* Gets information about system audio/video timings and geometry.
- * Can be called only after retro_load_game() has successfully completed.
- * NOTE: The implementation of this function might not initialize every
- * variable if needed.
- * E.g. geom.aspect_ratio might not be initialized if core doesn't
- * desire a particular aspect ratio. */
-void retro_get_system_av_info(struct retro_system_av_info *info);
-
-/* Sets device to be used for player 'port'.
- * By default, RETRO_DEVICE_JOYPAD is assumed to be plugged into all
- * available ports.
- * Setting a particular device type is not a guarantee that libretro cores
- * will only poll input based on that particular device type. It is only a
- * hint to the libretro core when a core cannot automatically detect the
- * appropriate input device type on its own. It is also relevant when a
- * core can change its behavior depending on device type. */
-void retro_set_controller_port_device(unsigned port, unsigned device);
-
-/* Resets the current game. */
-void retro_reset(void);
-
-/* Runs the game for one video frame.
- * During retro_run(), input_poll callback must be called at least once.
- *
- * If a frame is not rendered for reasons where a game "dropped" a frame,
- * this still counts as a frame, and retro_run() should explicitly dupe
- * a frame if GET_CAN_DUPE returns true.
- * In this case, the video callback can take a NULL argument for data.
- */
-void retro_run(void);
-
-/* Returns the amount of data the implementation requires to serialize
- * internal state (save states).
- * Between calls to retro_load_game() and retro_unload_game(), the
- * returned size is never allowed to be larger than a previous returned
- * value, to ensure that the frontend can allocate a save state buffer once.
- */
-size_t retro_serialize_size(void);
-
-/* Serializes internal state. If failed, or size is lower than
- * retro_serialize_size(), it should return false, true otherwise. */
-bool retro_serialize(void *data, size_t size);
-bool retro_unserialize(const void *data, size_t size);
-
-void retro_cheat_reset(void);
-void retro_cheat_set(unsigned index, bool enabled, const char *code);
-
-/* Loads a game. */
-bool retro_load_game(const struct retro_game_info *game);
-
-/* Loads a "special" kind of game. Should not be used,
- * except in extreme cases. */
-bool retro_load_game_special(
- unsigned game_type,
- const struct retro_game_info *info, size_t num_info
-);
-
-/* Unloads a currently loaded game. */
-void retro_unload_game(void);
-
-/* Gets region of game. */
-unsigned retro_get_region(void);
-
-/* Gets region of memory. */
-void *retro_get_memory_data(unsigned id);
-size_t retro_get_memory_size(unsigned id);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/frontend/libretro_core_options.h b/frontend/libretro_core_options.h
new file mode 100644
index 0000000..badd856
--- /dev/null
+++ b/frontend/libretro_core_options.h
@@ -0,0 +1,1243 @@
+#ifndef LIBRETRO_CORE_OPTIONS_H__
+#define LIBRETRO_CORE_OPTIONS_H__
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <libretro.h>
+#include <retro_inline.h>
+
+#ifndef HAVE_NO_LANGEXTRA
+#include "libretro_core_options_intl.h"
+#endif
+
+/*
+ ********************************
+ * VERSION: 1.3
+ ********************************
+ *
+ * - 1.3: Move translations to libretro_core_options_intl.h
+ * - libretro_core_options_intl.h includes BOM and utf-8
+ * fix for MSVC 2010-2013
+ * - Added HAVE_NO_LANGEXTRA flag to disable translations
+ * on platforms/compilers without BOM support
+ * - 1.2: Use core options v1 interface when
+ * RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION is >= 1
+ * (previously required RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION == 1)
+ * - 1.1: Support generation of core options v0 retro_core_option_value
+ * arrays containing options with a single value
+ * - 1.0: First commit
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ ********************************
+ * Core Option Definitions
+ ********************************
+*/
+
+/* RETRO_LANGUAGE_ENGLISH */
+
+/* Default language:
+ * - All other languages must include the same keys and values
+ * - Will be used as a fallback in the event that frontend language
+ * is not available
+ * - Will be used as a fallback for any missing entries in
+ * frontend language definition
+ */
+
+struct retro_core_option_definition option_defs_us[] = {
+ {
+ "pcsx_rearmed_frameskip",
+ "Frameskip",
+ "Choose how much frames should be skipped to improve performance at the expense of visual smoothness.",
+ {
+ { "0", NULL },
+ { "1", NULL },
+ { "2", NULL },
+ { "3", NULL },
+ { NULL, NULL },
+ },
+ "0",
+ },
+ {
+ "pcsx_rearmed_bios",
+ "Use BIOS",
+ "Allows you to use real bios file (if available) or emulated bios (HLE). Its recommended to use official bios file for better compatibility.",
+ {
+ { "auto", "auto" },
+ { "HLE", "hle" },
+ { NULL, NULL },
+ },
+ "auto",
+ },
+ {
+ "pcsx_rearmed_region",
+ "Region",
+ "Choose what region the system is from. 60 Hz for NTSC, 50 Hz for PAL.",
+ {
+ { "auto", "auto" },
+ { "NTSC", "ntsc" },
+ { "PAL", "pal" },
+ { NULL, NULL },
+ },
+ "auto",
+ },
+ {
+ "pcsx_rearmed_memcard2",
+ "Enable Second Memory Card (Shared)",
+ "Enabled the memory card slot 2. This memory card is shared amongst all games.",
+ {
+ { "disabled", NULL },
+ { "enabled", NULL },
+ { NULL, NULL },
+ },
+ "disabled",
+ },
+ {
+ "pcsx_rearmed_pad1type",
+ "Pad 1 Type",
+ "Pad type for player 1",
+ {
+ { "standard", NULL },
+ { "analog", NULL },
+ { "dualshock", NULL },
+ { "negcon", NULL },
+ { "guncon", NULL },
+ { "none", NULL },
+ { NULL, NULL },
+ },
+ "standard",
+ },
+ {
+ "pcsx_rearmed_pad2type",
+ "Pad 2 Type",
+ "Pad type for player 2",
+ {
+ { "standard", NULL },
+ { "analog", NULL },
+ { "dualshock", NULL },
+ { "negcon", NULL },
+ { "guncon", NULL },
+ { "none", NULL },
+ { NULL, NULL },
+ },
+ "standard",
+ },
+ {
+ "pcsx_rearmed_pad3type",
+ "Pad 3 Type",
+ "Pad type for player 3",
+ {
+ { "standard", NULL },
+ { "analog", NULL },
+ { "dualshock", NULL },
+ { "negcon", NULL },
+ { "guncon", NULL },
+ { "none", NULL },
+ { NULL, NULL },
+ },
+ "none",
+ },
+ {
+ "pcsx_rearmed_pad4type",
+ "Pad 4 Type",
+ "Pad type for player 4",
+ {
+ { "standard", NULL },
+ { "analog", NULL },
+ { "dualshock", NULL },
+ { "negcon", NULL },
+ { "guncon", NULL },
+ { "none", NULL },
+ { NULL, NULL },
+ },
+ "none",
+ },
+ {
+ "pcsx_rearmed_pad5type",
+ "Pad 5 Type",
+ "Pad type for player 5",
+ {
+ { "standard", NULL },
+ { "analog", NULL },
+ { "dualshock", NULL },
+ { "negcon", NULL },
+ { "guncon", NULL },
+ { "none", NULL },
+ { NULL, NULL },
+ },
+ "none",
+ },{
+ "pcsx_rearmed_pad6type",
+ "Pad 6 Type",
+ "Pad type for player 6",
+ {
+ { "standard", NULL },
+ { "analog", NULL },
+ { "dualshock", NULL },
+ { "negcon", NULL },
+ { "guncon", NULL },
+ { "none", NULL },
+ { NULL, NULL },
+ },
+ "none",
+ },{
+ "pcsx_rearmed_pad7type",
+ "Pad 7 Type",
+ "Pad type for player 7",
+ {
+ { "standard", NULL },
+ { "analog", NULL },
+ { "dualshock", NULL },
+ { "negcon", NULL },
+ { "guncon", NULL },
+ { "none", NULL },
+ { NULL, NULL },
+ },
+ "none",
+ },{
+ "pcsx_rearmed_pad8type",
+ "Pad 8 Type",
+ "Pad type for player 8",
+ {
+ { "standard", NULL },
+ { "analog", NULL },
+ { "dualshock", NULL },
+ { "negcon", NULL },
+ { "guncon", NULL },
+ { "none", NULL },
+ { NULL, NULL },
+ },
+ "none",
+ },
+ {
+ "pcsx_rearmed_multitap1",
+ "Multitap 1",
+ "Enables/Disables multitap on port 1, allowing upto 5 players in games that permit it.",
+ {
+ { "auto", NULL },
+ { "disabled", NULL },
+ { "enabled", NULL },
+ { NULL, NULL },
+ },
+ "auto",
+ },
+ {
+ "pcsx_rearmed_multitap2",
+ "Multitap 2",
+ "Enables/Disables multitap on port 2, allowing up to 8 players in games that permit it. Multitap 1 has to be enabled for this to work.",
+ {
+ { "auto", NULL },
+ { "disabled", NULL },
+ { "enabled", NULL },
+ { NULL, NULL },
+ },
+ "auto",
+ },
+ {
+ "pcsx_rearmed_negcon_deadzone",
+ "NegCon Twist Deadzone (Percent)",
+ "Sets the deadzone of the RetroPad left analog stick when simulating the 'twist' action of emulated neGcon Controllers. Used to eliminate drift/unwanted input.",
+ {
+ { "0", NULL },
+ { "5", NULL },
+ { "10", NULL },
+ { "15", NULL },
+ { "20", NULL },
+ { "25", NULL },
+ { "30", NULL },
+ { NULL, NULL },
+ },
+ "0",
+ },
+ {
+ "pcsx_rearmed_negcon_response",
+ "NegCon Twist Response",
+ "Specifies the analog response when using a RetroPad left analog stick to simulate the 'twist' action of emulated neGcon Controllers.",
+ {
+ { "linear", NULL },
+ { "quadratic", NULL },
+ { "cubic", NULL },
+ { NULL, NULL },
+ },
+ "linear",
+ },
+ {
+ "pcsx_rearmed_analog_axis_modifier",
+ "Analog axis bounds.",
+ "Range bounds for analog axis. Square bounds help controllers with highly circular ranges that are unable to fully saturate the x and y axis at 45degree deflections.",
+ {
+ { "circle", NULL },
+ { "square", NULL },
+ { NULL, NULL },
+ },
+ "circle",
+ },
+ {
+ "pcsx_rearmed_vibration",
+ "Enable Vibration",
+ "Enables vibration feedback for controllers that supports vibration features.",
+ {
+ { "disabled", NULL },
+ { "enabled", NULL },
+ { NULL, NULL },
+ },
+ "enabled",
+ },
+ {
+ "pcsx_rearmed_gunconadjustx",
+ "Guncon Adjust X",
+ "When using Guncon mode, you can override aim in emulator if shots misaligned, this applies an increment on the x axis.",
+ {
+ { "0", NULL },
+ { "-25", NULL },
+ { "-24", NULL },
+ { "-23", NULL },
+ { "-22", NULL },
+ { "-21", NULL },
+ { "-20", NULL },
+ { "-19", NULL },
+ { "-18", NULL },
+ { "-17", NULL },
+ { "-16", NULL },
+ { "-15", NULL },
+ { "-14", NULL },
+ { "-13", NULL },
+ { "-12", NULL },
+ { "-11", NULL },
+ { "-10", NULL },
+ { "-09", NULL },
+ { "-08", NULL },
+ { "-07", NULL },
+ { "-06", NULL },
+ { "-05", NULL },
+ { "-04", NULL },
+ { "-03", NULL },
+ { "-02", NULL },
+ { "-01", NULL },
+ { "00", NULL },
+ { "01", NULL },
+ { "02", NULL },
+ { "03", NULL },
+ { "04", NULL },
+ { "05", NULL },
+ { "06", NULL },
+ { "07", NULL },
+ { "08", NULL },
+ { "09", NULL },
+ { "10", NULL },
+ { "11", NULL },
+ { "12", NULL },
+ { "13", NULL },
+ { "14", NULL },
+ { "15", NULL },
+ { "16", NULL },
+ { "17", NULL },
+ { "18", NULL },
+ { "19", NULL },
+ { "20", NULL },
+ { "21", NULL },
+ { "22", NULL },
+ { "23", NULL },
+ { "24", NULL },
+ { "25", NULL },
+ { NULL, NULL },
+ },
+ "0",
+ },
+ {
+ "pcsx_rearmed_gunconadjusty",
+ "Guncon Adjust Y",
+ "When using Guncon mode, you can override aim in emulator if shots misaligned, this applies an increment on the y axis.",
+ {
+ { "0", NULL },
+ { "-25", NULL },
+ { "-24", NULL },
+ { "-23", NULL },
+ { "-22", NULL },
+ { "-21", NULL },
+ { "-20", NULL },
+ { "-19", NULL },
+ { "-18", NULL },
+ { "-17", NULL },
+ { "-16", NULL },
+ { "-15", NULL },
+ { "-14", NULL },
+ { "-13", NULL },
+ { "-12", NULL },
+ { "-11", NULL },
+ { "-10", NULL },
+ { "-09", NULL },
+ { "-08", NULL },
+ { "-07", NULL },
+ { "-06", NULL },
+ { "-05", NULL },
+ { "-04", NULL },
+ { "-03", NULL },
+ { "-02", NULL },
+ { "-01", NULL },
+ { "00", NULL },
+ { "01", NULL },
+ { "02", NULL },
+ { "03", NULL },
+ { "04", NULL },
+ { "05", NULL },
+ { "06", NULL },
+ { "07", NULL },
+ { "08", NULL },
+ { "09", NULL },
+ { "10", NULL },
+ { "11", NULL },
+ { "12", NULL },
+ { "13", NULL },
+ { "14", NULL },
+ { "15", NULL },
+ { "16", NULL },
+ { "17", NULL },
+ { "18", NULL },
+ { "19", NULL },
+ { "20", NULL },
+ { "21", NULL },
+ { "22", NULL },
+ { "23", NULL },
+ { "24", NULL },
+ { "25", NULL },
+ { NULL, NULL },
+ },
+ "0",
+ },
+ {
+ "pcsx_rearmed_gunconadjustratiox",
+ "Guncon Adjust Ratio X",
+ "When using Guncon mode, you can override aim in emulator if shots misaligned, this applies a ratio on the x axis.",
+ {
+ { "1", NULL },
+ { "0.75", NULL },
+ { "0.76", NULL },
+ { "0.77", NULL },
+ { "0.78", NULL },
+ { "0.79", NULL },
+ { "0.80", NULL },
+ { "0.81", NULL },
+ { "0.82", NULL },
+ { "0.83", NULL },
+ { "0.84", NULL },
+ { "0.85", NULL },
+ { "0.86", NULL },
+ { "0.87", NULL },
+ { "0.88", NULL },
+ { "0.89", NULL },
+ { "0.90", NULL },
+ { "0.91", NULL },
+ { "0.92", NULL },
+ { "0.93", NULL },
+ { "0.94", NULL },
+ { "0.95", NULL },
+ { "0.96", NULL },
+ { "0.97", NULL },
+ { "0.98", NULL },
+ { "0.99", NULL },
+ { "1.00", NULL },
+ { "1.01", NULL },
+ { "1.02", NULL },
+ { "1.03", NULL },
+ { "1.04", NULL },
+ { "1.05", NULL },
+ { "1.06", NULL },
+ { "1.07", NULL },
+ { "1.08", NULL },
+ { "1.09", NULL },
+ { "1.10", NULL },
+ { "1.11", NULL },
+ { "1.12", NULL },
+ { "1.13", NULL },
+ { "1.14", NULL },
+ { "1.15", NULL },
+ { "1.16", NULL },
+ { "1.17", NULL },
+ { "1.18", NULL },
+ { "1.19", NULL },
+ { "1.20", NULL },
+ { "1.21", NULL },
+ { "1.22", NULL },
+ { "1.23", NULL },
+ { "1.24", NULL },
+ { "1.25", NULL },
+ { NULL, NULL },
+ },
+ "1",
+ },
+ {
+ "pcsx_rearmed_gunconadjustratioy",
+ "Guncon Adjust Ratio Y",
+ "When using Guncon mode, you can override aim in emulator if shots misaligned, this applies a ratio on the y axis.",
+ {
+ { "1", NULL },
+ { "0.75", NULL },
+ { "0.76", NULL },
+ { "0.77", NULL },
+ { "0.78", NULL },
+ { "0.79", NULL },
+ { "0.80", NULL },
+ { "0.81", NULL },
+ { "0.82", NULL },
+ { "0.83", NULL },
+ { "0.84", NULL },
+ { "0.85", NULL },
+ { "0.86", NULL },
+ { "0.87", NULL },
+ { "0.88", NULL },
+ { "0.89", NULL },
+ { "0.90", NULL },
+ { "0.91", NULL },
+ { "0.92", NULL },
+ { "0.93", NULL },
+ { "0.94", NULL },
+ { "0.95", NULL },
+ { "0.96", NULL },
+ { "0.97", NULL },
+ { "0.98", NULL },
+ { "0.99", NULL },
+ { "1.00", NULL },
+ { "1.01", NULL },
+ { "1.02", NULL },
+ { "1.03", NULL },
+ { "1.04", NULL },
+ { "1.05", NULL },
+ { "1.06", NULL },
+ { "1.07", NULL },
+ { "1.08", NULL },
+ { "1.09", NULL },
+ { "1.10", NULL },
+ { "1.11", NULL },
+ { "1.12", NULL },
+ { "1.13", NULL },
+ { "1.14", NULL },
+ { "1.15", NULL },
+ { "1.16", NULL },
+ { "1.17", NULL },
+ { "1.18", NULL },
+ { "1.19", NULL },
+ { "1.20", NULL },
+ { "1.21", NULL },
+ { "1.22", NULL },
+ { "1.23", NULL },
+ { "1.24", NULL },
+ { "1.25", NULL },
+ { NULL, NULL },
+ },
+ "1",
+ },
+ {
+ "pcsx_rearmed_dithering",
+ "Enable Dithering",
+ "If Off, disables the dithering pattern the PSX applies to combat color banding.",
+ {
+ { "disabled", NULL },
+ { "enabled", NULL },
+ { NULL, NULL },
+ },
+#ifdef HAVE_LIBNX
+ "disabled",
+#else
+ "enabled",
+#endif
+ },
+
+#ifndef DRC_DISABLE
+ {
+ "pcsx_rearmed_drc",
+ "Dynamic Recompiler",
+ "Enables core to use dynamic recompiler or interpreter (slower) CPU instructions.",
+ {
+ { "disabled", NULL },
+ { "enabled", NULL },
+ { NULL, NULL },
+ },
+ "enabled",
+ },
+ {
+ "pcsx_rearmed_psxclock",
+ "PSX CPU Clock",
+#ifdef HAVE_PRE_ARMV7
+ "Overclock or underclock the PSX clock. Default is 50",
+#else
+ "Overclock or underclock the PSX clock. Default is 57",
+#endif
+ {
+ { "30", NULL },
+ { "31", NULL },
+ { "32", NULL },
+ { "33", NULL },
+ { "34", NULL },
+ { "35", NULL },
+ { "36", NULL },
+ { "37", NULL },
+ { "38", NULL },
+ { "39", NULL },
+ { "40", NULL },
+ { "41", NULL },
+ { "42", NULL },
+ { "43", NULL },
+ { "44", NULL },
+ { "45", NULL },
+ { "46", NULL },
+ { "47", NULL },
+ { "48", NULL },
+ { "49", NULL },
+ { "50", NULL },
+ { "51", NULL },
+ { "52", NULL },
+ { "53", NULL },
+ { "54", NULL },
+ { "55", NULL },
+ { "56", NULL },
+ { "57", NULL },
+ { "58", NULL },
+ { "59", NULL },
+ { "60", NULL },
+ { "61", NULL },
+ { "62", NULL },
+ { "63", NULL },
+ { "64", NULL },
+ { "65", NULL },
+ { "66", NULL },
+ { "67", NULL },
+ { "68", NULL },
+ { "69", NULL },
+ { "70", NULL },
+ { "71", NULL },
+ { "72", NULL },
+ { "73", NULL },
+ { "74", NULL },
+ { "75", NULL },
+ { "76", NULL },
+ { "77", NULL },
+ { "78", NULL },
+ { "79", NULL },
+ { "80", NULL },
+ { "81", NULL },
+ { "82", NULL },
+ { "83", NULL },
+ { "84", NULL },
+ { "85", NULL },
+ { "86", NULL },
+ { "87", NULL },
+ { "88", NULL },
+ { "89", NULL },
+ { "90", NULL },
+ { "91", NULL },
+ { "92", NULL },
+ { "93", NULL },
+ { "94", NULL },
+ { "95", NULL },
+ { "96", NULL },
+ { "97", NULL },
+ { "98", NULL },
+ { "99", NULL },
+ { "100", NULL },
+ { NULL, NULL },
+ },
+#ifdef HAVE_PRE_ARMV7
+ "50",
+#else
+ "57",
+#endif
+ },
+#endif /* DRC_DISABLE */
+
+#ifdef GPU_NEON
+ {
+ "pcsx_rearmed_neon_interlace_enable",
+ "Enable Interlacing Mode",
+ "Enables fake scanlines effect.",
+ {
+ { "disabled", NULL },
+ { "enabled", NULL },
+ { NULL, NULL },
+ },
+ "disabled",
+ },
+ {
+ "pcsx_rearmed_neon_enhancement_enable",
+ "Enhanced Resolution (Slow)",
+ "Renders in double resolution at the cost of lower performance.",
+ {
+ { "disabled", NULL },
+ { "enabled", NULL },
+ { NULL, NULL },
+ },
+ "disabled",
+ },
+ {
+ "pcsx_rearmed_neon_enhancement_no_main",
+ "Enhanced Resolution (Speed Hack)",
+ "Speed hack for Enhanced resolution option (glitches some games).",
+ {
+ { "disabled", NULL },
+ { "enabled", NULL },
+ { NULL, NULL },
+ },
+ "disabled",
+ },
+#endif /* GPU_NEON */
+
+ {
+ "pcsx_rearmed_duping_enable",
+ "Frame Duping",
+ "A speedup, redraws/reuses the last frame if there was no new data.",
+ {
+ { "disabled", NULL },
+ { "enabled", NULL },
+ { NULL, NULL },
+ },
+ "enabled",
+ },
+ {
+ "pcsx_rearmed_display_internal_fps",
+ "Display Internal FPS",
+ "Shows an on-screen frames per second counter when enabled.",
+ {
+ { "disabled", NULL },
+ { "enabled", NULL },
+ { NULL, NULL },
+ },
+ "disabled",
+ },
+
+ /* GPU PEOPS OPTIONS */
+#ifdef GPU_PEOPS
+ {
+ "pcsx_rearmed_show_gpu_peops_settings",
+ "Advanced GPU P.E.Op.S. Settings",
+ "Shows or hides advanced GPU plugin settings. NOTE: Quick Menu must be toggled for this setting to take effect.",
+ {
+ { "disabled", NULL },
+ { "enabled", NULL },
+ { NULL, NULL },
+ },
+ "disabled",
+ },
+ {
+ "pcsx_rearmed_gpu_peops_odd_even_bit",
+ "(GPU) Odd/Even Bit Hack",
+ "Needed for Chrono Cross.",
+ {
+ { "disabled", NULL },
+ { "enabled", NULL },
+ { NULL, NULL },
+ },
+ "disabled",
+ },
+ {
+ "pcsx_rearmed_gpu_peops_expand_screen_width",
+ "(GPU) Expand Screen Width",
+ "Capcom fighting games",
+ {
+ { "disabled", NULL },
+ { "enabled", NULL },
+ { NULL, NULL },
+ },
+ "disabled",
+ },
+ {
+ "pcsx_rearmed_gpu_peops_ignore_brightness",
+ "(GPU) Ignore Brightness Color",
+ "Black screens in Lunar Silver Star Story games",
+ {
+ { "disabled", NULL },
+ { "enabled", NULL },
+ { NULL, NULL },
+ },
+ "disabled",
+ },
+ {
+ "pcsx_rearmed_gpu_peops_disable_coord_check",
+ "(GPU) Disable Coordinate Check",
+ "Compatibility mode",
+ {
+ { "disabled", NULL },
+ { "enabled", NULL },
+ { NULL, NULL },
+ },
+ "disabled",
+ },
+ {
+ "pcsx_rearmed_gpu_peops_lazy_screen_update",
+ "(GPU) Lazy Screen Update",
+ "Pandemonium 2",
+ {
+ { "disabled", NULL },
+ { "enabled", NULL },
+ { NULL, NULL },
+ },
+ "disabled",
+ },
+ {
+ "pcsx_rearmed_gpu_peops_old_frame_skip",
+ "(GPU) Old Frame Skipping",
+ "Skip every second frame",
+ {
+ { "disabled", NULL },
+ { "enabled", NULL },
+ { NULL, NULL },
+ },
+ "enabled",
+ },
+ {
+ "pcsx_rearmed_gpu_peops_repeated_triangles",
+ "(GPU) Repeated Flat Tex Triangles",
+ "Needed by Star Wars: Dark Forces",
+ {
+ { "disabled", NULL },
+ { "enabled", NULL },
+ { NULL, NULL },
+ },
+ "disabled",
+ },
+ {
+ "pcsx_rearmed_gpu_peops_quads_with_triangles",
+ "(GPU) Draw Quads with Triangles",
+ "Better g-colors, worse textures",
+ {
+ { "disabled", NULL },
+ { "enabled", NULL },
+ { NULL, NULL },
+ },
+ "disabled",
+ },
+ {
+ "pcsx_rearmed_gpu_peops_fake_busy_state",
+ "(GPU) Fake 'Gpu Busy' States",
+ "Toggle busy flags after drawing",
+ {
+ { "disabled", NULL },
+ { "enabled", NULL },
+ { NULL, NULL },
+ },
+ "disabled",
+ },
+#endif
+
+ /* GPU UNAI Advanced Options */
+#ifdef GPU_UNAI
+ {
+ "pcsx_rearmed_show_gpu_unai_settings",
+ "Advance GPU UNAI/PCSX4All Settings",
+ "Shows or hides advanced gpu settings. A core restart might be needed for settings to take effect. NOTE: Quick Menu must be toggled for this setting to take effect.",
+ {
+ { "disabled", NULL },
+ { "enabled", NULL },
+ { NULL, NULL},
+ },
+ "disabled",
+ },
+ {
+ "pcsx_rearmed_gpu_unai_blending",
+ "(GPU) Enable Blending",
+ NULL,
+ {
+ { "disabled", NULL },
+ { "enabled", NULL },
+ { NULL, NULL},
+ },
+ "enabled",
+ },
+ {
+ "pcsx_rearmed_gpu_unai_lighting",
+ "(GPU) Enable Lighting",
+ NULL,
+ {
+ { "disabled", NULL },
+ { "enabled", NULL },
+ { NULL, NULL},
+ },
+ "enabled",
+ },
+ {
+ "pcsx_rearmed_gpu_unai_fast_lighting",
+ "(GPU) Enable Fast Lighting",
+ NULL,
+ {
+ { "disabled", NULL },
+ { "enabled", NULL },
+ { NULL, NULL},
+ },
+ "enabled",
+ },
+ {
+ "pcsx_rearmed_gpu_unai_ilace_force",
+ "(GPU) Enable Forced Interlace",
+ NULL,
+ {
+ { "disabled", NULL },
+ { "enabled", NULL },
+ { NULL, NULL},
+ },
+ "disabled",
+ },
+ {
+ "pcsx_rearmed_gpu_unai_pixel_skip",
+ "(GPU) Enable Pixel Skip",
+ NULL,
+ {
+ { "disabled", NULL },
+ { "enabled", NULL },
+ { NULL, NULL},
+ },
+ "disabled",
+ },
+#endif /* GPU UNAI Advanced Settings */
+
+ {
+ "pcsx_rearmed_show_bios_bootlogo",
+ "Show Bios Bootlogo",
+ "When enabled, shows the PlayStation logo when starting or resetting. (Breaks some games).",
+ {
+ { "disabled", NULL },
+ { "enabled", NULL },
+ { NULL, NULL },
+ },
+ "disabled",
+ },
+ {
+ "pcsx_rearmed_spu_reverb",
+ "Sound Reverb",
+ "Enables or disables audio reverb effect.",
+ {
+ { "disabled", NULL },
+ { "enabled", NULL },
+ { NULL, NULL },
+ },
+ "enabled",
+ },
+ {
+ "pcsx_rearmed_spu_interpolation",
+ "Sound Interpolation",
+ NULL,
+ {
+ { "simple", "Simple" },
+ { "gaussian", "Gaussian" },
+ { "cubic", "Cubic" },
+ { "off", "disabled" },
+ { NULL, NULL },
+ },
+ "simple",
+ },
+ {
+ "pcsx_rearmed_idiablofix",
+ "Diablo Music Fix",
+ NULL,
+ {
+ { "disabled", NULL },
+ { "enabled", NULL },
+ { NULL, NULL },
+ },
+ "disabled",
+ },
+ {
+ "pcsx_rearmed_pe2_fix",
+ "Parasite Eve 2/Vandal Hearts 1/2 Fix",
+ NULL,
+ {
+ { "disabled", NULL },
+ { "enabled", NULL },
+ { NULL, NULL },
+ },
+ "disabled",
+ },
+ {
+ "pcsx_rearmed_inuyasha_fix",
+ "InuYasha Sengoku Battle Fix",
+ NULL,
+ {
+ { "disabled", NULL },
+ { "enabled", NULL },
+ { NULL, NULL },
+ },
+ "disabled",
+ },
+
+ /* ADVANCED OPTIONS */
+ {
+ "pcsx_rearmed_noxadecoding",
+ "XA Decoding",
+ NULL,
+ {
+ { "disabled", NULL },
+ { "enabled", NULL },
+ { NULL, NULL },
+ },
+ "enabled",
+ },
+ {
+ "pcsx_rearmed_nocdaudio",
+ "CD Audio",
+ NULL,
+ {
+ { "disabled", NULL },
+ { "enabled", NULL },
+ { NULL, NULL },
+ },
+ "enabled",
+ },
+ {
+ "pcsx_rearmed_spuirq",
+ "SPU IRQ Always Enabled",
+ "Compatibility tweak, should be left to off in most cases.",
+ {
+ { "disabled", NULL },
+ { "enabled", NULL },
+ { NULL, NULL },
+ },
+ "disabled",
+ },
+
+#ifndef DRC_DISABLE
+ {
+ "pcsx_rearmed_nosmccheck",
+ "(Speed Hack) Disable SMC Checks",
+ "Will cause crashes when loading, break memcards.",
+ {
+ { "disabled", NULL },
+ { "enabled", NULL },
+ { NULL, NULL },
+ },
+ "disabled",
+ },
+ {
+ "pcsx_rearmed_gteregsunneeded",
+ "(Speed Hack) Assume GTE Regs Unneeded",
+ "May cause graphical glitches.",
+ {
+ { "disabled", NULL },
+ { "enabled", NULL },
+ { NULL, NULL },
+ },
+ "disabled",
+ },
+ {
+ "pcsx_rearmed_nogteflags",
+ "(Speed Hack) Disable GTE Flags",
+ "Will cause graphical glitches.",
+ {
+ { "disabled", NULL },
+ { "enabled", NULL },
+ { NULL, NULL },
+ },
+ "disabled",
+ },
+#endif /* DRC_DISABLE */
+
+ { NULL, NULL, NULL, {{0}}, NULL },
+};
+
+/*
+ ********************************
+ * Language Mapping
+ ********************************
+*/
+
+#ifndef HAVE_NO_LANGEXTRA
+struct retro_core_option_definition *option_defs_intl[RETRO_LANGUAGE_LAST] = {
+ option_defs_us, /* RETRO_LANGUAGE_ENGLISH */
+ NULL, /* RETRO_LANGUAGE_JAPANESE */
+ NULL, /* RETRO_LANGUAGE_FRENCH */
+ NULL, /* RETRO_LANGUAGE_SPANISH */
+ NULL, /* RETRO_LANGUAGE_GERMAN */
+ NULL, /* RETRO_LANGUAGE_ITALIAN */
+ NULL, /* RETRO_LANGUAGE_DUTCH */
+ NULL, /* RETRO_LANGUAGE_PORTUGUESE_BRAZIL */
+ NULL, /* RETRO_LANGUAGE_PORTUGUESE_PORTUGAL */
+ NULL, /* RETRO_LANGUAGE_RUSSIAN */
+ NULL, /* RETRO_LANGUAGE_KOREAN */
+ NULL, /* RETRO_LANGUAGE_CHINESE_TRADITIONAL */
+ NULL, /* RETRO_LANGUAGE_CHINESE_SIMPLIFIED */
+ NULL, /* RETRO_LANGUAGE_ESPERANTO */
+ NULL, /* RETRO_LANGUAGE_POLISH */
+ NULL, /* RETRO_LANGUAGE_VIETNAMESE */
+ NULL, /* RETRO_LANGUAGE_ARABIC */
+ NULL, /* RETRO_LANGUAGE_GREEK */
+ option_defs_tr, /* RETRO_LANGUAGE_TURKISH */
+};
+#endif
+
+/*
+ ********************************
+ * Functions
+ ********************************
+*/
+
+/* Handles configuration/setting of core options.
+ * Should be called as early as possible - ideally inside
+ * retro_set_environment(), and no later than retro_load_game()
+ * > We place the function body in the header to avoid the
+ * necessity of adding more .c files (i.e. want this to
+ * be as painless as possible for core devs)
+ */
+
+static INLINE void libretro_set_core_options(retro_environment_t environ_cb)
+{
+ unsigned version = 0;
+
+ if (!environ_cb)
+ return;
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION, &version) && (version >= 1))
+ {
+#ifndef HAVE_NO_LANGEXTRA
+ struct retro_core_options_intl core_options_intl;
+ unsigned language = 0;
+
+ core_options_intl.us = option_defs_us;
+ core_options_intl.local = NULL;
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_LANGUAGE, &language) &&
+ (language < RETRO_LANGUAGE_LAST) && (language != RETRO_LANGUAGE_ENGLISH))
+ core_options_intl.local = option_defs_intl[language];
+
+ environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_INTL, &core_options_intl);
+#else
+ environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS, &option_defs_us);
+#endif
+ }
+ else
+ {
+ size_t i;
+ size_t option_index = 0;
+ size_t num_options = 0;
+ struct retro_variable *variables = NULL;
+ char **values_buf = NULL;
+
+ /* Determine number of options
+ * > Note: We are going to skip a number of irrelevant
+ * core options when building the retro_variable array,
+ * but we'll allocate space for all of them. The difference
+ * in resource usage is negligible, and this allows us to
+ * keep the code 'cleaner' */
+ while (true)
+ {
+ if (option_defs_us[num_options].key)
+ num_options++;
+ else
+ break;
+ }
+
+ /* Allocate arrays */
+ variables = (struct retro_variable *)calloc(num_options + 1, sizeof(struct retro_variable));
+ values_buf = (char **)calloc(num_options, sizeof(char *));
+
+ if (!variables || !values_buf)
+ goto error;
+
+ /* Copy parameters from option_defs_us array */
+ for (i = 0; i < num_options; i++)
+ {
+ const char *key = option_defs_us[i].key;
+ const char *desc = option_defs_us[i].desc;
+ const char *default_value = option_defs_us[i].default_value;
+ struct retro_core_option_value *values = option_defs_us[i].values;
+ size_t buf_len = 3;
+ size_t default_index = 0;
+
+ values_buf[i] = NULL;
+
+ /* Skip options that are irrelevant when using the
+ * old style core options interface */
+ if ((strcmp(key, "pcsx_rearmed_show_gpu_peops_settings") == 0))
+ continue;
+
+ if (desc)
+ {
+ size_t num_values = 0;
+
+ /* Determine number of values */
+ while (true)
+ {
+ if (values[num_values].value)
+ {
+ /* Check if this is the default value */
+ if (default_value)
+ if (strcmp(values[num_values].value, default_value) == 0)
+ default_index = num_values;
+
+ buf_len += strlen(values[num_values].value);
+ num_values++;
+ }
+ else
+ break;
+ }
+
+ /* Build values string */
+ if (num_values > 0)
+ {
+ size_t j;
+
+ buf_len += num_values - 1;
+ buf_len += strlen(desc);
+
+ values_buf[i] = (char *)calloc(buf_len, sizeof(char));
+ if (!values_buf[i])
+ goto error;
+
+ strcpy(values_buf[i], desc);
+ strcat(values_buf[i], "; ");
+
+ /* Default value goes first */
+ strcat(values_buf[i], values[default_index].value);
+
+ /* Add remaining values */
+ for (j = 0; j < num_values; j++)
+ {
+ if (j != default_index)
+ {
+ strcat(values_buf[i], "|");
+ strcat(values_buf[i], values[j].value);
+ }
+ }
+ }
+ }
+
+ variables[option_index].key = key;
+ variables[option_index].value = values_buf[i];
+ option_index++;
+ }
+
+ /* Set variables */
+ environ_cb(RETRO_ENVIRONMENT_SET_VARIABLES, variables);
+
+error:
+
+ /* Clean up */
+ if (values_buf)
+ {
+ for (i = 0; i < num_options; i++)
+ {
+ if (values_buf[i])
+ {
+ free(values_buf[i]);
+ values_buf[i] = NULL;
+ }
+ }
+
+ free(values_buf);
+ values_buf = NULL;
+ }
+
+ if (variables)
+ {
+ free(variables);
+ variables = NULL;
+ }
+ }
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/frontend/libretro_core_options_intl.h b/frontend/libretro_core_options_intl.h
new file mode 100644
index 0000000..16c40a0
--- /dev/null
+++ b/frontend/libretro_core_options_intl.h
@@ -0,0 +1,568 @@
+īģŋ#ifndef LIBRETRO_CORE_OPTIONS_INTL_H__
+#define LIBRETRO_CORE_OPTIONS_INTL_H__
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1500 && _MSC_VER < 1900)
+/* https://support.microsoft.com/en-us/kb/980263 */
+#pragma execution_character_set("utf-8")
+#pragma warning(disable:4566)
+#endif
+
+#include <libretro.h>
+
+/*
+ ********************************
+ * VERSION: 1.3
+ ********************************
+ *
+ * - 1.3: Move translations to libretro_core_options_intl.h
+ * - libretro_core_options_intl.h includes BOM and utf-8
+ * fix for MSVC 2010-2013
+ * - Added HAVE_NO_LANGEXTRA flag to disable translations
+ * on platforms/compilers without BOM support
+ * - 1.2: Use core options v1 interface when
+ * RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION is >= 1
+ * (previously required RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION == 1)
+ * - 1.1: Support generation of core options v0 retro_core_option_value
+ * arrays containing options with a single value
+ * - 1.0: First commit
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ ********************************
+ * Core Option Definitions
+ ********************************
+*/
+
+/* RETRO_LANGUAGE_JAPANESE */
+
+/* RETRO_LANGUAGE_FRENCH */
+
+/* RETRO_LANGUAGE_SPANISH */
+
+/* RETRO_LANGUAGE_GERMAN */
+
+/* RETRO_LANGUAGE_ITALIAN */
+
+/* RETRO_LANGUAGE_DUTCH */
+
+/* RETRO_LANGUAGE_PORTUGUESE_BRAZIL */
+
+/* RETRO_LANGUAGE_PORTUGUESE_PORTUGAL */
+
+/* RETRO_LANGUAGE_RUSSIAN */
+
+/* RETRO_LANGUAGE_KOREAN */
+
+/* RETRO_LANGUAGE_CHINESE_TRADITIONAL */
+
+/* RETRO_LANGUAGE_CHINESE_SIMPLIFIED */
+
+/* RETRO_LANGUAGE_ESPERANTO */
+
+/* RETRO_LANGUAGE_POLISH */
+
+/* RETRO_LANGUAGE_VIETNAMESE */
+
+/* RETRO_LANGUAGE_ARABIC */
+
+/* RETRO_LANGUAGE_GREEK */
+
+/* RETRO_LANGUAGE_TURKISH */
+
+struct retro_core_option_definition option_defs_tr[] = {
+ {
+ "pcsx_rearmed_frameskip",
+ "Kare Atlama",
+ "GÃļrsel pÃŧrÃŧzsÃŧzlÃŧk pahasÄąna performansÄą artÄąrmak için ne kadar karenin atlanmasÄą gerektiğini seçin.",
+ {
+ { NULL, NULL },
+ },
+ NULL
+ },
+ {
+ "pcsx_rearmed_bios",
+ "BIOS Kullan",
+ "Gerçek bios dosyasÄąnÄą (varsa) veya ÃļykÃŧnmÃŧş bios'u (HLE) kullanmanÄązÄą sağlar. Daha iyi uyumluluk için resmi bios dosyasÄąnÄą kullanmanÄąz Ãļnerilir.",
+ {
+ { "auto", "otomatik" },
+ { "HLE", "hle" },
+ { NULL, NULL },
+ },
+ "auto",
+ },
+ {
+ "pcsx_rearmed_region",
+ "BÃļlge",
+ "Sistemin hangi bÃļlgeden olduğunu seçin. NTSC için 60 Hz, PAL için 50 Hz.",
+ {
+ { "auto", "otomatik" },
+ { "NTSC", "ntsc" },
+ { "PAL", "pal" },
+ { NULL, NULL },
+ },
+ "auto",
+ },
+ {
+ "pcsx_rearmed_memcard2",
+ "Ä°kinci Bellek KartÄąnÄą Etkinleştir (PaylaÅŸÄąlan)",
+ "2. HafÄąza kartÄą yuvasÄąnÄą etkinleştirin. Bu hafÄąza kartÄą tÃŧm oyunlar arasÄąnda paylaÅŸÄąlÄąr.",
+ {
+ { NULL, NULL },
+ },
+ NULL
+ },
+ {
+ "pcsx_rearmed_pad1type",
+ "Kumanda 1 Tipi",
+ "1. Oyuncu için kontrolÃļr tipi",
+ {
+ { "standard", NULL },
+ { "analog", NULL },
+ { "dualshock", NULL },
+ { "negcon", NULL },
+ { "none", "hiçbiri" },
+ { NULL, NULL },
+ },
+ "standard",
+ },
+ {
+ "pcsx_rearmed_pad2type",
+ "Kumanda 2 Tipi",
+ "2. Oyuncu için kontrolÃļr tipi",
+ {
+ { "standard", NULL },
+ { "analog", NULL },
+ { "dualshock", NULL },
+ { "negcon", NULL },
+ { "none", "hiçbiri" },
+ { NULL, NULL },
+ },
+ "standard",
+ },
+ {
+ "pcsx_rearmed_pad3type",
+ "Kumanda 3 Tipi",
+ "3. Oyuncu için kontrolÃļr tipi",
+ {
+ { "standard", NULL },
+ { "analog", NULL },
+ { "dualshock", NULL },
+ { "negcon", NULL },
+ { "none", "hiçbiri" },
+ { NULL, NULL },
+ },
+ "none",
+ },
+ {
+ "pcsx_rearmed_pad4type",
+ "Kumanda 4 Tipi",
+ "4. Oyuncu için kontrolÃļr tipi",
+ {
+ { "standard", NULL },
+ { "analog", NULL },
+ { "dualshock", NULL },
+ { "negcon", NULL },
+ { "none", "hiçbiri" },
+ { NULL, NULL },
+ },
+ "none",
+ },
+ {
+ "pcsx_rearmed_pad5type",
+ "Kumanda 5 Tipi",
+ "5. Oyuncu için kontrolÃļr tipi",
+ {
+ { "standard", NULL },
+ { "analog", NULL },
+ { "dualshock", NULL },
+ { "negcon", NULL },
+ { "none", "hiçbiri" },
+ { NULL, NULL },
+ },
+ "none",
+ },{
+ "pcsx_rearmed_pad6type",
+ "Kumanda 6 Tipi",
+ "6. Oyuncu için kontrolÃļr tipi",
+ {
+ { "standard", NULL },
+ { "analog", NULL },
+ { "dualshock", NULL },
+ { "negcon", NULL },
+ { "none", "hiçbiri" },
+ { NULL, NULL },
+ },
+ "none",
+ },{
+ "pcsx_rearmed_pad7type",
+ "Kumanda 7 Tipi",
+ "7. Oyuncu için kontrolÃļr tipi",
+ {
+ { "standard", NULL },
+ { "analog", NULL },
+ { "dualshock", NULL },
+ { "negcon", NULL },
+ { "none", "hiçbiri" },
+ { NULL, NULL },
+ },
+ "none",
+ },{
+ "pcsx_rearmed_pad8type",
+ "Kumanda 8 Tipi",
+ "8. Oyuncu için kontrolÃļr tipi",
+ {
+ { "standard", NULL },
+ { "analog", NULL },
+ { "dualshock", NULL },
+ { "negcon", NULL },
+ { "none", "hiçbiri" },
+ { NULL, NULL },
+ },
+ "none",
+ },
+ {
+ "pcsx_rearmed_multitap1",
+ "Multitap 1",
+ "BağlantÄą noktasÄą 1'deki multitap'Äą etkinleştirir / devre dÄąÅŸÄą bÄąrakÄąr ve izin veren oyunlarda 5 oyuncuya kadar izin verir.",
+ {
+ { "auto", "otomatik" },
+ { "disabled", NULL },
+ { "enabled", NULL },
+ { NULL, NULL },
+ },
+ "auto",
+ },
+ {
+ "pcsx_rearmed_multitap2",
+ "Multitap 2",
+ "BağlantÄą noktasÄą 2'deki multitap'Äą etkinleştirir/devre dÄąÅŸÄą bÄąrakÄąr ve izin veren oyunlarda 8 oyuncuya kadar izin verir. Bunun çalÄąÅŸmasÄą için Multitap 1'in etkinleştirilmesi gerekir.",
+ {
+ { "auto", "otomatik" },
+ { "disabled", NULL },
+ { "enabled", NULL },
+ { NULL, NULL },
+ },
+ "auto",
+ },
+ {
+ "pcsx_rearmed_negcon_deadzone",
+ "NegCon Twist Deadzone (YÃŧzdelik)",
+ "ÖykÃŧnÃŧlmÃŧş neGcon kontrolÃļrÃŧnÃŧn 'bÃŧkÃŧm' eylemini simÃŧle ederken RetroPad sol analog çubuğunun ÃļlÃŧ bÃļlgesini ayarlar. SÃŧrÃŧklenme/istenmeyen girişi ortadan kaldÄąrmak için kullanÄąlÄąr.",
+ {
+ { NULL, NULL },
+ },
+ NULL
+ },
+ {
+ "pcsx_rearmed_negcon_response",
+ "NegCon Twist Response",
+ "ÖykÃŧnÃŧlmÃŧş neGcon kontrolÃļrÃŧnÃŧn 'bÃŧkÃŧmÃŧnÃŧ' simule etmek için bir RetroPad sol analog çubuğu kullanÄąrken analog cevabÄąnÄą belirtir.",
+ {
+ { NULL, NULL },
+ },
+ NULL
+ },
+ {
+ "pcsx_rearmed_vibration",
+ "Titreşimi Etkinleştir",
+ "Titreşim Ãļzelliklerini destekleyen kontrolÃļrler için titreşim geri bildirimini etkinleştirir.",
+ {
+ { NULL, NULL },
+ },
+ NULL
+ },
+ {
+ "pcsx_rearmed_dithering",
+ "Dithering Etkinleştir",
+ "KapalÄą ise, PSX'in renk bantlarÄąyla mÃŧcadele etmek için uyguladığı renk taklidi dÃŧzenini devre dÄąÅŸÄą bÄąrakÄąr.",
+ {
+ { NULL, NULL },
+ },
+ NULL
+ },
+
+#ifndef DRC_DISABLE
+ {
+ "pcsx_rearmed_drc",
+ "Dinamik Yeniden Derleyici",
+ "Çekirdeğin dinamik yeniden derleyici veya tercÃŧman(daha yavaş) CPU talimatlarÄąnÄą kullanmasÄąnÄą sağlar.",
+ {
+ { NULL, NULL },
+ },
+ NULL
+ },
+ {
+ "pcsx_rearmed_psxclock",
+ "PSX CPU Saat HÄązÄą",
+#ifdef HAVE_PRE_ARMV7
+ "Overclock or underclock the PSX clock. Default is 50",
+#else
+ "Overclock or underclock the PSX clock. Default is 57",
+#endif
+ {
+ { NULL, NULL },
+ },
+ NULL
+ },
+#endif /* DRC_DISABLE */
+
+#ifdef __ARM_NEON__
+ {
+ "pcsx_rearmed_neon_interlace_enable",
+ "Interlacing Mode'u etkinleştir",
+ "Sahte tarama çizgileri efektini etkinleştirir.",
+ {
+ { NULL, NULL },
+ },
+ NULL
+ },
+ {
+ "pcsx_rearmed_neon_enhancement_enable",
+ "Geliştirilmiş ÇÃļzÃŧnÃŧrlÃŧk (Yavaş)",
+ "DÃŧşÃŧk performans pahasÄąna çift çÃļzÃŧnÃŧrlÃŧkte işler.",
+ {
+ { NULL, NULL },
+ },
+ NULL
+ },
+ {
+ "pcsx_rearmed_neon_enhancement_no_main",
+ "Geliştirilmiş ÇÃļzÃŧnÃŧrlÃŧk (Speed Hack)",
+ "Geliştirilmiş çÃļzÃŧnÃŧrlÃŧk seçeneği için hÄąz aÅŸÄąrtma(bazÄą oyunlarda sorun Ã§Äąkartabilir).",
+ {
+ { NULL, NULL },
+ },
+ NULL
+ },
+#endif /* __ARM_NEON__ */
+
+ {
+ "pcsx_rearmed_duping_enable",
+ "Frame Duping",
+ "Yeni bir veri yoksa, bir hÄązlandÄąrma, son kareyi yeniden çizer/yeniden kullanÄąr.",
+ {
+ { NULL, NULL },
+ },
+ NULL
+ },
+ {
+ "pcsx_rearmed_display_internal_fps",
+ "Dahili FPS'yi gÃļrÃŧntÃŧle",
+ "Etkinleştirildiğinde ekranda saniye baÅŸÄąna kareyi gÃļsterir.",
+ {
+ { NULL, NULL },
+ },
+ NULL
+ },
+
+ /* GPU PEOPS OPTIONS */
+#ifdef DRC_DISABLE
+ {
+ "pcsx_rearmed_show_gpu_peops_settings",
+ "Gelişmiş GPU AyarlarÄąnÄą GÃļster",
+ "Çeşitli GPU dÃŧzeltmelerini etkinleştirin veya devre dÄąÅŸÄą bÄąrakÄąn. AyarlarÄąn etkili olmasÄą için core'un yeniden başlatÄąlmasÄą gerekebilir. NOT: Bu ayarÄąn etkili olabilmesi için HÄązlÄą MenÃŧ’nÃŧn değiştirilmesi gerekir.",
+ {
+ { NULL, NULL },
+ },
+ NULL
+ },
+ {
+ "pcsx_rearmed_gpu_peops_odd_even_bit",
+ "(GPU) Odd/Even Bit Hack",
+ "Chrono Cross için gerekli.",
+ {
+ { NULL, NULL },
+ },
+ NULL
+ },
+ {
+ "pcsx_rearmed_gpu_peops_expand_screen_width",
+ "(GPU) Ekran Genişliğini Genişlet",
+ "Capcom dÃļvÃŧş oyunlarÄą",
+ {
+ { NULL, NULL },
+ },
+ NULL
+ },
+ {
+ "pcsx_rearmed_gpu_peops_ignore_brightness",
+ "(GPU) ParlaklÄąk Rengini Yoksay",
+ "Lunar Silver Star Story oyunlarÄąnda siyah ekran",
+ {
+ { NULL, NULL },
+ },
+ NULL
+ },
+ {
+ "pcsx_rearmed_gpu_peops_disable_coord_check",
+ "(GPU) Koordinat KontrolÃŧnÃŧ Devre DÄąÅŸÄą BÄąrak",
+ "Uyumluluk modu",
+ {
+ { NULL, NULL },
+ },
+ NULL
+ },
+ {
+ "pcsx_rearmed_gpu_peops_lazy_screen_update",
+ "(GPU) Tembel Ekran GÃŧncellemesi",
+ "Pandemonium 2",
+ {
+ { NULL, NULL },
+ },
+ NULL
+ },
+ {
+ "pcsx_rearmed_gpu_peops_old_frame_skip",
+ "(GPU) Eski Çerçeve Atlama",
+ "Her ikinci kareyi atla",
+ {
+ { NULL, NULL },
+ },
+ NULL
+ },
+ {
+ "pcsx_rearmed_gpu_peops_repeated_triangles",
+ "(GPU) Tekrarlanan DÃŧz Doku Üçgenleri",
+ "Star Wars: Dark Forces için gerekli",
+ {
+ { NULL, NULL },
+ },
+ NULL
+ },
+ {
+ "pcsx_rearmed_gpu_peops_quads_with_triangles",
+ "(GPU) Üçgenler ile DÃļrtlÃŧ Çiz",
+ "Daha iyi g renkler, daha kÃļtÃŧ dokular",
+ {
+ { NULL, NULL },
+ },
+ NULL
+ },
+ {
+ "pcsx_rearmed_gpu_peops_fake_busy_state",
+ "(GPU) Sahte 'Gpu Meşgul' KonumlarÄą",
+ "Çizimden sonra meşgul bayraklarÄąnÄą değiştir",
+ {
+ { NULL, NULL },
+ },
+ NULL
+ },
+#endif
+
+ {
+ "pcsx_rearmed_show_bios_bootlogo",
+ "Bios Bootlogo'yu GÃļster",
+ "Etkinleştirildiğinde, başlatÄąrken veya sÄąfÄąrlarken PlayStation logosunu gÃļsterir. (BazÄą oyunlarÄą bozabilir).",
+ {
+ { NULL, NULL },
+ },
+ NULL
+ },
+ {
+ "pcsx_rearmed_spu_reverb",
+ "Ses YankÄąsÄą",
+ "Ses yankÄą efektini etkinleştirir veya devre dÄąÅŸÄą bÄąrakÄąr.",
+ {
+ { NULL, NULL },
+ },
+ NULL
+ },
+ {
+ "pcsx_rearmed_spu_interpolation",
+ "Ses Enterpolasyonu",
+ NULL,
+ {
+ { NULL, NULL },
+ },
+ NULL
+ },
+ {
+ "pcsx_rearmed_idiablofix",
+ "Diablo MÃŧzik DÃŧzeltmesi",
+ NULL,
+ {
+ { NULL, NULL },
+ },
+ NULL
+ },
+ {
+ "pcsx_rearmed_pe2_fix",
+ "Parasite Eve 2/Vandal Hearts 1/2 DÃŧzeltmleri",
+ NULL,
+ {
+ { NULL, NULL },
+ },
+ NULL
+ },
+ {
+ "pcsx_rearmed_inuyasha_fix",
+ "InuYasha Sengoku Battle DÃŧzeltmesi",
+ NULL,
+ {
+ { NULL, NULL },
+ },
+ NULL
+ },
+
+ /* ADVANCED OPTIONS */
+ {
+ "pcsx_rearmed_noxadecoding",
+ "XA Kod ÇÃļzme",
+ NULL,
+ {
+ { NULL, NULL },
+ },
+ NULL
+ },
+ {
+ "pcsx_rearmed_nocdaudio",
+ "CD Ses",
+ NULL,
+ {
+ { NULL, NULL },
+ },
+ NULL
+ },
+
+#ifndef DRC_DISABLE
+ {
+ "pcsx_rearmed_nosmccheck",
+ "(Speed Hack) SMC Kontrollerini Devre DÄąÅŸÄą BÄąrak",
+ "YÃŧkleme sÄąrasÄąnda çÃļkmelere neden olabilir, hafÄąza kartÄąnÄą bozabilir.",
+ {
+ { NULL, NULL },
+ },
+ NULL
+ },
+ {
+ "pcsx_rearmed_gteregsunneeded",
+ "(Speed Hack) GTE'nin Gereksiz Olduğunu Varsayın",
+ "Grafiksel bozukluklara neden olabilir.",
+ {
+ { NULL, NULL },
+ },
+ NULL
+ },
+ {
+ "pcsx_rearmed_nogteflags",
+ "(Speed Hack) GTE BayraklarÄąnÄą DevredÄąÅŸÄą BÄąrakÄąn",
+ "Grafiksel bozukluklara neden olur.",
+ {
+ { NULL, NULL },
+ },
+ NULL
+ },
+#endif /* DRC_DISABLE */
+
+ { NULL, NULL, NULL, {{0}}, NULL },
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/frontend/link.T b/frontend/link.T
new file mode 100644
index 0000000..b0c262d
--- /dev/null
+++ b/frontend/link.T
@@ -0,0 +1,5 @@
+{
+ global: retro_*;
+ local: *;
+};
+
diff --git a/frontend/main.c b/frontend/main.c
index 43a5548..64be927 100644
--- a/frontend/main.c
+++ b/frontend/main.c
@@ -11,7 +11,7 @@
#include <unistd.h>
#include <signal.h>
#include <time.h>
-#ifndef _WIN32
+#if !defined(_WIN32) && !defined(NO_DYLIB)
#include <dlfcn.h>
#endif
@@ -130,6 +130,13 @@ void emu_set_default_config(void)
pl_rearmed_cbs.gpu_neon.enhancement_no_main = 0;
pl_rearmed_cbs.gpu_peops.iUseDither = 0;
pl_rearmed_cbs.gpu_peops.dwActFixes = 1<<7;
+ pl_rearmed_cbs.gpu_unai.ilace_force = 0;
+ pl_rearmed_cbs.gpu_unai.pixel_skip = 1;
+ pl_rearmed_cbs.gpu_unai.lighting = 1;
+ pl_rearmed_cbs.gpu_unai.fast_lighting = 1;
+ pl_rearmed_cbs.gpu_unai.blending = 1;
+ pl_rearmed_cbs.gpu_unai.dithering = 0;
+ // old gpu_unai config
pl_rearmed_cbs.gpu_unai.abe_hack =
pl_rearmed_cbs.gpu_unai.no_light =
pl_rearmed_cbs.gpu_unai.no_blend = 0;
@@ -144,7 +151,7 @@ void emu_set_default_config(void)
spu_config.iVolume = 768;
spu_config.iTempo = 0;
spu_config.iUseThread = 1; // no effect if only 1 core is detected
-#ifdef HAVE_PRE_ARMV7 /* XXX GPH hack */
+#if defined(HAVE_PRE_ARMV7) && !defined(_3DS) /* XXX GPH hack */
spu_config.iUseReverb = 0;
spu_config.iUseInterpolation = 0;
spu_config.iTempo = 1;
@@ -152,8 +159,8 @@ void emu_set_default_config(void)
new_dynarec_hacks = 0;
cycle_multiplier = 200;
- in_type1 = PSE_PAD_TYPE_STANDARD;
- in_type2 = PSE_PAD_TYPE_STANDARD;
+ in_type[0] = PSE_PAD_TYPE_STANDARD;
+ in_type[1] = PSE_PAD_TYPE_STANDARD;
}
void do_emu_action(void)
@@ -722,10 +729,10 @@ void SysReset() {
// reset can run code, timing must be set
pl_timing_prepare(Config.PsxType);
- EmuReset();
-
- // hmh core forgets this
+ // hmh core forgets this
CDR_stop();
+
+ EmuReset();
GPU_updateLace = real_lace;
g_emu_resetting = 0;
@@ -773,7 +780,7 @@ int emu_save_state(int slot)
return ret;
ret = SaveState(fname);
-#ifdef HAVE_PRE_ARMV7 /* XXX GPH hack */
+#if defined(HAVE_PRE_ARMV7) && !defined(_3DS) && !defined(__SWITCH__) /* XXX GPH hack */
sync();
#endif
SysPrintf("* %s \"%s\" [%d]\n",
@@ -795,6 +802,7 @@ int emu_load_state(int slot)
return LoadState(fname);
}
+#ifndef HAVE_LIBRETRO
#ifndef ANDROID
void SysPrintf(const char *fmt, ...) {
@@ -819,6 +827,7 @@ void SysPrintf(const char *fmt, ...) {
}
#endif
+#endif /* HAVE_LIBRETRO */
void SysMessage(const char *fmt, ...) {
va_list list;
@@ -868,7 +877,7 @@ static int _OpenPlugins(void) {
if (Config.UseNet && !NetOpened) {
netInfo info;
- char path[MAXPATHLEN];
+ char path[MAXPATHLEN * 2];
char dotdir[MAXPATHLEN];
MAKE_PATH(dotdir, "/.pcsx/plugins/", NULL);
@@ -987,7 +996,7 @@ void *SysLoadLibrary(const char *lib) {
return (void *)(long)(PLUGIN_DL_BASE + builtin_plugin_ids[i]);
}
-#ifndef _WIN32
+#if !defined(_WIN32) && !defined(NO_DYLIB)
ret = dlopen(lib, RTLD_NOW);
if (ret == NULL)
SysMessage("dlopen: %s", dlerror());
@@ -1004,7 +1013,7 @@ void *SysLoadSym(void *lib, const char *sym) {
if (PLUGIN_DL_BASE <= plugid && plugid < PLUGIN_DL_BASE + ARRAY_SIZE(builtin_plugins))
return plugin_link(plugid - PLUGIN_DL_BASE, sym);
-#ifndef _WIN32
+#if !defined(_WIN32) && !defined(NO_DYLIB)
return dlsym(lib, sym);
#else
return NULL;
@@ -1012,7 +1021,9 @@ void *SysLoadSym(void *lib, const char *sym) {
}
const char *SysLibError() {
-#ifndef _WIN32
+#if defined(NO_DYLIB)
+ return NULL;
+#elif !defined(_WIN32)
return dlerror();
#else
return "not supported";
@@ -1025,8 +1036,7 @@ void SysCloseLibrary(void *lib) {
if (PLUGIN_DL_BASE <= plugid && plugid < PLUGIN_DL_BASE + ARRAY_SIZE(builtin_plugins))
return;
-#ifndef _WIN32
+#if !defined(_WIN32) && !defined(NO_DYLIB)
dlclose(lib);
#endif
}
-
diff --git a/frontend/menu.c b/frontend/menu.c
index 6d75373..f4a45ba 100644
--- a/frontend/menu.c
+++ b/frontend/menu.c
@@ -101,13 +101,10 @@ int scanlines, scanline_level = 20;
int soft_scaling, analog_deadzone; // for Caanoo
int soft_filter;
-#ifndef HAVE_PRE_ARMV7
-#define DEFAULT_PSX_CLOCK 57
-#define DEFAULT_PSX_CLOCK_S "57"
-#else
-#define DEFAULT_PSX_CLOCK 50
-#define DEFAULT_PSX_CLOCK_S "50"
-#endif
+// Default to 100% CPU speed as most hardware can handle it nowadays using the dynamic recompiler.
+// If not, the option is in the advanced speed hacks menu, so in a logical place.
+#define DEFAULT_PSX_CLOCK 100
+#define DEFAULT_PSX_CLOCK_S "100"
static const char *bioses[24];
static const char *gpu_plugins[16];
@@ -308,14 +305,14 @@ static void menu_sync_config(void)
cycle_multiplier = 10000 / psx_clock;
switch (in_type_sel1) {
- case 1: in_type1 = PSE_PAD_TYPE_ANALOGPAD; break;
- case 2: in_type1 = PSE_PAD_TYPE_GUNCON; break;
- default: in_type1 = PSE_PAD_TYPE_STANDARD;
+ case 1: in_type[0] = PSE_PAD_TYPE_ANALOGPAD; break;
+ case 2: in_type[0] = PSE_PAD_TYPE_NEGCON; break;
+ default: in_type[0] = PSE_PAD_TYPE_STANDARD;
}
switch (in_type_sel2) {
- case 1: in_type2 = PSE_PAD_TYPE_ANALOGPAD; break;
- case 2: in_type2 = PSE_PAD_TYPE_GUNCON; break;
- default: in_type2 = PSE_PAD_TYPE_STANDARD;
+ case 1: in_type[1] = PSE_PAD_TYPE_ANALOGPAD; break;
+ case 2: in_type[1] = PSE_PAD_TYPE_NEGCON; break;
+ default: in_type[1] = PSE_PAD_TYPE_STANDARD;
}
if (in_evdev_allow_abs_only != allow_abs_only_old) {
in_probe();
@@ -425,6 +422,12 @@ static const struct {
CE_INTVAL_V(frameskip, 3),
CE_INTVAL_P(gpu_peops.iUseDither),
CE_INTVAL_P(gpu_peops.dwActFixes),
+ CE_INTVAL_P(gpu_unai.ilace_force),
+ CE_INTVAL_P(gpu_unai.pixel_skip),
+ CE_INTVAL_P(gpu_unai.lighting),
+ CE_INTVAL_P(gpu_unai.fast_lighting),
+ CE_INTVAL_P(gpu_unai.blending),
+ CE_INTVAL_P(gpu_unai.dithering),
CE_INTVAL_P(gpu_unai.lineskip),
CE_INTVAL_P(gpu_unai.abe_hack),
CE_INTVAL_P(gpu_unai.no_light),
@@ -1361,10 +1364,16 @@ static int menu_loop_plugin_gpu_neon(int id, int keys)
static menu_entry e_menu_plugin_gpu_unai[] =
{
- mee_onoff ("Skip every 2nd line", 0, pl_rearmed_cbs.gpu_unai.lineskip, 1),
- mee_onoff ("Abe's Odyssey hack", 0, pl_rearmed_cbs.gpu_unai.abe_hack, 1),
- mee_onoff ("Disable lighting", 0, pl_rearmed_cbs.gpu_unai.no_light, 1),
- mee_onoff ("Disable blending", 0, pl_rearmed_cbs.gpu_unai.no_blend, 1),
+ //mee_onoff ("Skip every 2nd line", 0, pl_rearmed_cbs.gpu_unai.lineskip, 1),
+ //mee_onoff ("Abe's Odyssey hack", 0, pl_rearmed_cbs.gpu_unai.abe_hack, 1),
+ //mee_onoff ("Disable lighting", 0, pl_rearmed_cbs.gpu_unai.no_light, 1),
+ //mee_onoff ("Disable blending", 0, pl_rearmed_cbs.gpu_unai.no_blend, 1),
+ mee_onoff ("Interlace", 0, pl_rearmed_cbs.gpu_unai.ilace_force, 1),
+ mee_onoff ("Dithering", 0, pl_rearmed_cbs.gpu_unai.dithering, 1),
+ mee_onoff ("Lighting", 0, pl_rearmed_cbs.gpu_unai.lighting, 1),
+ mee_onoff ("Fast lighting", 0, pl_rearmed_cbs.gpu_unai.fast_lighting, 1),
+ mee_onoff ("Blending", 0, pl_rearmed_cbs.gpu_unai.blending, 1),
+ mee_onoff ("Pixel skip", 0, pl_rearmed_cbs.gpu_unai.pixel_skip, 1),
mee_end,
};
diff --git a/frontend/pandora/pcsx.png b/frontend/pandora/pcsx.png
deleted file mode 100644
index 71f36d0..0000000
--- a/frontend/pandora/pcsx.png
+++ /dev/null
Binary files differ
diff --git a/frontend/pandora/pcsx.pxml.templ b/frontend/pandora/pcsx.pxml.templ
deleted file mode 100644
index f748065..0000000
--- a/frontend/pandora/pcsx.pxml.templ
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<PXML xmlns="http://openpandora.org/namespaces/PXML" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="PXML_schema.xsd">
-<package id="package.pcsx_rearmed.notaz">
- <titles>
- <title lang="en_US">PCSX ReARMed</title>
- </titles>
- <version major="1" minor="9" release="93" build="%PR%"/>
- <author name="PCSX team/notaz" website="http://notaz.gp2x.de/"/>
-</package>
-<application id="pcsx_rearmed.notaz.%PR%" appdata="pcsx_rearmed">
- <titles>
- <title lang="en_US">PCSX ReARMed %PR%</title>
- </titles>
- <title lang="en_US">PCSX ReARMed %PR%</title>
-
- <descriptions>
- <description lang="en_US">PCSX ReARMed is heavily optimized PlayStation Emulator. It's a PCSX fork based on the PCSX-Reloaded project, which itself contains code from PCSX, PCSX-df and PCSX-Revolution.
-
-The emulator features MIPS->ARM recompiler by Ari64 and ARM NEON GPU by Exophase, that in many cases produces pixel perfect graphics at very high performance. There is also NEON-optimized GTE code, optimized P.E.Op.S. (Pete's) SPU; PCSX4ALL and traditional P.E.Op.S. GPUs are also available.</description>
- </descriptions>
-
- <exec command="pcsx.sh"/>
-
- <icon src="pcsx.png"/>
-
- <author name="PCSX team/notaz" website="http://notaz.gp2x.de/"/>
-
- <version major="1" minor="9" release="93" build="%PR%"/>
-
- <licenses>
- <license name="GPLv2+" url="http://www.gnu.org/licenses/gpl-2.0.html" sourcecodeurl="http://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=pcsx_rearmed.git"/>
- </licenses>
-
- <info name="PCSX ReARMed %PR% readme" type="text/plain" src="readme.txt"/>
-
- <categories>
- <category name="Game">
- <subcategory name="Emulator"/>
- </category>
- </categories>
-</application>
-</PXML>
diff --git a/frontend/pandora/pcsx.sh b/frontend/pandora/pcsx.sh
deleted file mode 100755
index 710f641..0000000
--- a/frontend/pandora/pcsx.sh
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/sh
-
-# stupid nub mode thing
-nub0mode=`cat /proc/pandora/nub0/mode`
-nub1mode=`cat /proc/pandora/nub1/mode`
-/usr/pandora/scripts/op_nubchange.sh absolute absolute
-
-# 4MB for RAM (2+align) + 2MB for vram (1+overdraw)
-# + 10MB for gpu_neon (8+overdraw) + 8MB LUTs
-# no big deal if this fails, only performance loss
-sudo -n /usr/pandora/scripts/op_hugetlb.sh 24
-
-# C64x DSP for SPU
-sudo -n /usr/pandora/scripts/op_dsp_c64.sh
-
-./pcsx "$@"
-
-# restore stuff if pcsx crashes
-./picorestore
-sudo -n /usr/pandora/scripts/op_lcdrate.sh 60
-sudo -n /usr/pandora/scripts/op_gamma.sh 0
-sudo -n /usr/pandora/scripts/op_hugetlb.sh 0
-
-/usr/pandora/scripts/op_nubchange.sh $nub0mode $nub1mode
diff --git a/frontend/pandora/picorestore.c b/frontend/pandora/picorestore.c
deleted file mode 100644
index 77f5720..0000000
--- a/frontend/pandora/picorestore.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * picorestore - clean up after an omapfb program crash
- *
- * Copyright (c) GraÅžvydas "notaz" Ignotas, 2010
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the organization nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <linux/fb.h>
-#include <linux/omapfb.h>
-#include <linux/kd.h>
-
-int main()
-{
- struct fb_var_screeninfo fbvar;
- struct omapfb_plane_info pi;
- struct omapfb_mem_info mi;
- int ret, fbdev, kbdfd;
-
- fbdev = open("/dev/fb0", O_RDWR);
- if (fbdev == -1) {
- perror("open fb0");
- goto end_fb0;
- }
-
- ret = ioctl(fbdev, FBIOGET_VSCREENINFO, &fbvar);
- if (ret == -1) {
- perror("FBIOGET_VSCREENINFO ioctl");
- goto end_fb0;
- }
-
- if (fbvar.yoffset != 0) {
- printf("fixing yoffset.. ");
- fbvar.yoffset = 0;
- ret = ioctl(fbdev, FBIOPAN_DISPLAY, &fbvar);
- if (ret < 0)
- perror("ioctl FBIOPAN_DISPLAY");
- else
- printf("ok\n");
- }
-
-end_fb0:
- if (fbdev >= 0)
- close(fbdev);
-
- fbdev = open("/dev/fb1", O_RDWR);
- if (fbdev == -1) {
- perror("open fb1");
- goto end_fb1;
- }
-
- ret = ioctl(fbdev, OMAPFB_QUERY_PLANE, &pi);
- ret |= ioctl(fbdev, OMAPFB_QUERY_MEM, &mi);
- if (ret != 0)
- perror("QUERY_*");
-
- pi.enabled = 0;
- ret = ioctl(fbdev, OMAPFB_SETUP_PLANE, &pi);
- if (ret != 0)
- perror("SETUP_PLANE");
-
- mi.size = 0;
- ret = ioctl(fbdev, OMAPFB_SETUP_MEM, &mi);
- if (ret != 0)
- perror("SETUP_MEM");
-
-end_fb1:
- if (fbdev >= 0)
- close(fbdev);
-
- kbdfd = open("/dev/tty", O_RDWR);
- if (kbdfd == -1) {
- perror("open /dev/tty");
- return 1;
- }
-
- if (ioctl(kbdfd, KDSETMODE, KD_TEXT) == -1)
- perror("KDSETMODE KD_TEXT");
-
- close(kbdfd);
-
- return 0;
-}
diff --git a/frontend/pandora/skin/background.png b/frontend/pandora/skin/background.png
deleted file mode 100644
index f4b4523..0000000
--- a/frontend/pandora/skin/background.png
+++ /dev/null
Binary files differ
diff --git a/frontend/pandora/skin/font.png b/frontend/pandora/skin/font.png
deleted file mode 100644
index 707a5b4..0000000
--- a/frontend/pandora/skin/font.png
+++ /dev/null
Binary files differ
diff --git a/frontend/pandora/skin/readme.txt b/frontend/pandora/skin/readme.txt
deleted file mode 100644
index dd83963..0000000
--- a/frontend/pandora/skin/readme.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-The skin images can be customized, but there are several limitations:
-
-background.png - must be 320x240 image with 24bit RGB colors.
-font.png - must be 128x160 8bit grayscale image.
-selector.png - must be 8x10 8bit grayscale image.
-
-Font and selector colors can be changed by editing skin.txt.
-
diff --git a/frontend/pandora/skin/selector.png b/frontend/pandora/skin/selector.png
deleted file mode 100644
index a439169..0000000
--- a/frontend/pandora/skin/selector.png
+++ /dev/null
Binary files differ
diff --git a/frontend/pandora/skin/skin.txt b/frontend/pandora/skin/skin.txt
deleted file mode 100644
index 1d6979f..0000000
--- a/frontend/pandora/skin/skin.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-// html-style hex color codes, ex. ff0000 is red, 0000ff is blue, etc.
-text_color=ffffc0
-selection_color=808010
-
diff --git a/frontend/pandora/ui_feat.h b/frontend/pandora/ui_feat.h
deleted file mode 100644
index 3bb808a..0000000
--- a/frontend/pandora/ui_feat.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef UI_FEATURES_H
-#define UI_FEATURES_H
-
-#define MENU_BIOS_PATH "<SD card>/pandora/appdata/pcsx_rearmed/bios/"
-#define BOOT_MSG "Booting up... (press SPACE for menu)"
-#define MENU_SHOW_VARSCALER 1
-#define MENU_SHOW_VOUTMODE 0
-#define MENU_SHOW_SCALER2 0
-#define MENU_SHOW_NUBS_BTNS 1
-#define MENU_SHOW_VIBRATION 0
-#define MENU_SHOW_DEADZONE 0
-#define MENU_SHOW_MINIMIZE 1
-#define MENU_SHOW_FULLSCREEN 0
-#define MENU_SHOW_VOLUME 0
-
-#endif // UI_FEATURES_H
diff --git a/frontend/plugin.c b/frontend/plugin.c
index d9eb04a..30b0e08 100644
--- a/frontend/plugin.c
+++ b/frontend/plugin.c
@@ -49,24 +49,49 @@ extern void CALLBACK SPUasync(unsigned int, unsigned int);
extern int CALLBACK SPUplayCDDAchannel(short *, int);
/* PAD */
-static long PADreadPort1(PadDataS *pad)
-{
- pad->controllerType = in_type1;
- pad->buttonStatus = ~in_keystate;
- if (in_type1 == PSE_PAD_TYPE_ANALOGPAD) {
- pad->leftJoyX = in_a1[0];
- pad->leftJoyY = in_a1[1];
- pad->rightJoyX = in_a2[0];
- pad->rightJoyY = in_a2[1];
- }
- return 0;
+static long PADreadPort1(PadDataS *pad) {
+ int pad_index = pad->requestPadIndex;
+ pad->controllerType = in_type[pad_index];
+ pad->buttonStatus = ~in_keystate[pad_index];
+ if (multitap1 == 1)
+ pad->portMultitap = 1;
+ else
+ pad->portMultitap = 0;
+
+ if (in_type[pad_index] == PSE_PAD_TYPE_ANALOGJOY || in_type[pad_index] == PSE_PAD_TYPE_ANALOGPAD || in_type[pad_index] == PSE_PAD_TYPE_NEGCON || in_type[pad_index] == PSE_PAD_TYPE_GUNCON)
+ {
+ pad->leftJoyX = in_analog_left[pad_index][0];
+ pad->leftJoyY = in_analog_left[pad_index][1];
+ pad->rightJoyX = in_analog_right[pad_index][0];
+ pad->rightJoyY = in_analog_right[pad_index][1];
+
+ pad->absoluteX = in_analog_left[pad_index][0];
+ pad->absoluteY = in_analog_left[pad_index][1];
+ }
+ return 0;
}
-static long PADreadPort2(PadDataS *pad)
-{
- pad->controllerType = in_type2;
- pad->buttonStatus = ~in_keystate >> 16;
- return 0;
+static long PADreadPort2(PadDataS *pad) {
+ int pad_index = pad->requestPadIndex;
+
+ pad->controllerType = in_type[pad_index];
+ pad->buttonStatus = ~in_keystate[pad_index];
+ if (multitap2 == 1)
+ pad->portMultitap = 2;
+ else
+ pad->portMultitap = 0;
+
+ if (in_type[pad_index] == PSE_PAD_TYPE_ANALOGJOY || in_type[pad_index] == PSE_PAD_TYPE_ANALOGPAD || in_type[pad_index] == PSE_PAD_TYPE_NEGCON || in_type[pad_index] == PSE_PAD_TYPE_GUNCON)
+ {
+ pad->leftJoyX = in_analog_left[pad_index][0];
+ pad->leftJoyY = in_analog_left[pad_index][1];
+ pad->rightJoyX = in_analog_right[pad_index][0];
+ pad->rightJoyY = in_analog_right[pad_index][1];
+
+ pad->absoluteX = in_analog_left[pad_index][0];
+ pad->absoluteY = in_analog_left[pad_index][1];
+ }
+ return 0;
}
/* GPU */
diff --git a/frontend/plugin_lib.c b/frontend/plugin_lib.c
index ab4d415..eee255b 100644
--- a/frontend/plugin_lib.c
+++ b/frontend/plugin_lib.c
@@ -36,11 +36,15 @@
#define HUD_HEIGHT 10
-int in_type1, in_type2;
-int in_a1[2] = { 127, 127 }, in_a2[2] = { 127, 127 };
+int in_type[8];
+int multitap1;
+int multitap2;
+int in_analog_left[8][2] = {{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 }};
+int in_analog_right[8][2] = {{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 }};
int in_adev[2] = { -1, -1 }, in_adev_axis[2][2] = {{ 0, 1 }, { 0, 1 }};
int in_adev_is_nublike[2];
-int in_keystate, in_state_gun;
+unsigned short in_keystate[8];
+int in_state_gun;
int in_enable_vibration;
void *tsdev;
void *pl_vout_buf;
@@ -560,7 +564,7 @@ static void update_analog_nub_adjust(int *x_, int *y_)
static void update_analogs(void)
{
- int *nubp[2] = { in_a1, in_a2 };
+ int *nubp[2] = { in_analog_left[0], in_analog_right[0] };
int vals[2];
int i, a, v, ret;
@@ -597,7 +601,7 @@ static void update_input(void)
unsigned int emu_act;
in_update(actions);
- if (in_type1 == PSE_PAD_TYPE_ANALOGPAD)
+ if (in_type[0] == PSE_PAD_TYPE_ANALOGJOY || in_type[0] == PSE_PAD_TYPE_ANALOGPAD)
update_analogs();
emu_act = actions[IN_BINDTYPE_EMU];
in_state_gun = (emu_act & SACTION_GUN_MASK) >> SACTION_GUN_TRIGGER;
@@ -611,7 +615,7 @@ static void update_input(void)
}
emu_set_action(emu_act);
- in_keystate = actions[IN_BINDTYPE_PLAYER12];
+ in_keystate[0] = actions[IN_BINDTYPE_PLAYER12];
}
#else /* MAEMO */
extern void update_input(void);
diff --git a/frontend/plugin_lib.h b/frontend/plugin_lib.h
index 4a11002..d51c5e7 100644
--- a/frontend/plugin_lib.h
+++ b/frontend/plugin_lib.h
@@ -17,8 +17,14 @@ enum {
DKEY_CROSS,
DKEY_SQUARE,
};
-extern int in_type1, in_type2;
-extern int in_keystate, in_state_gun, in_a1[2], in_a2[2];
+extern int in_state_gun;
+extern int in_type[8];
+extern int multitap1;
+extern int multitap2;
+extern int in_analog_left[8][2];
+extern int in_analog_right[8][2];
+extern unsigned short in_keystate[8];
+
extern int in_adev[2], in_adev_axis[2][2];
extern int in_adev_is_nublike[2];
extern int in_enable_vibration;
@@ -65,6 +71,7 @@ struct rearmed_cbs {
int allow_interlace; // 0 off, 1 on, 2 guess
int enhancement_enable;
int enhancement_no_main;
+ int allow_dithering;
} gpu_neon;
struct {
int iUseDither;
@@ -73,6 +80,13 @@ struct rearmed_cbs {
int dwFrameRateTicks;
} gpu_peops;
struct {
+ int ilace_force;
+ int pixel_skip;
+ int lighting;
+ int fast_lighting;
+ int blending;
+ int dithering;
+ // old gpu_unai config for compatibility
int abe_hack;
int no_light, no_blend;
int lineskip;
diff --git a/frontend/switch/sys/mman.h b/frontend/switch/sys/mman.h
new file mode 100644
index 0000000..5e8d22e
--- /dev/null
+++ b/frontend/switch/sys/mman.h
@@ -0,0 +1,125 @@
+#ifndef MMAN_H
+#define MMAN_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <malloc.h>
+#include <switch.h>
+#include <stdlib.h>
+
+//#include "3ds_utils.h"
+
+#define PROT_READ 0b001
+#define PROT_WRITE 0b010
+#define PROT_EXEC 0b100
+#define MAP_PRIVATE 2
+#define MAP_FIXED 0x10
+#define MAP_ANONYMOUS 0x20
+
+#define MAP_FAILED ((void *)-1)
+
+static void* dynarec_cache = NULL;
+static void* dynarec_cache_mapping = NULL;
+
+static inline void* mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset)
+{
+ (void)fd;
+ (void)offset;
+
+ //void* addr_out;
+ Result rc = svcMapPhysicalMemory(addr, len);
+ if (R_FAILED(rc))
+ {
+ printf("mmap failed\n");
+ return malloc(len);
+ }
+
+ return addr;
+
+// if((prot == (PROT_READ | PROT_WRITE | PROT_EXEC)) &&
+// (flags == (MAP_PRIVATE | MAP_ANONYMOUS)))
+// {
+// if(true)// __ctr_svchax)
+// {
+// /* this hack works only for pcsx_rearmed */
+// uint32_t currentHandle;
+//
+// if(!dynarec_cache)
+// dynarec_cache = memalign(0x1000, len);
+//
+// //svcDuplicateHandle(&currentHandle, 0xFFFF8001);
+// //svcControlProcessMemory(currentHandle, addr, dynarec_cache,
+// // len, MEMOP_MAP, prot);
+// svcCloseHandle(currentHandle);
+// dynarec_cache_mapping = addr;
+// return addr;
+// }
+// else
+// {
+// printf("tried to mmap RWX pages without svcControlProcessMemory access !\n");
+// return MAP_FAILED;
+// }
+//
+// }
+
+// addr_out = memalign(0x1000, len);
+// if(!addr_out)
+// return MAP_FAILED;
+//
+// return addr_out;
+}
+
+static inline int mprotect(void *addr, size_t len, int prot)
+{
+ return 0;
+ //if(true) // __ctr_svchax)
+ //{
+ // uint32_t currentHandle;
+ // //svcDuplicateHandle(&currentHandle, 0xFFFF8001);
+ // //svcControlProcessMemory(currentHandle, addr, NULL,
+ // // len, MEMOP_PROT, prot);
+ // svcCloseHandle(currentHandle);
+ // return 0;
+ //}
+
+ //printf("mprotect called without svcControlProcessMemory access !\n");
+ //return -1;
+}
+
+static inline int munmap(void *addr, size_t len)
+{
+ Result rc = svcUnmapPhysicalMemory(addr, len);
+ if (R_FAILED(rc))
+ {
+ printf("munmap failed\n");
+ free(addr);
+ }
+ return 0;
+// if((addr == dynarec_cache_mapping) && true)//__ctr_svchax)
+// {
+// uint32_t currentHandle;
+// //svcDuplicateHandle(&currentHandle, 0xFFFF8001);
+// //svcControlProcessMemory(currentHandle,
+// // dynarec_cache, dynarec_cache_mapping,
+// // len, MEMOP_UNMAP, 0b111);
+// svcCloseHandle(currentHandle);
+// dynarec_cache_mapping = NULL;
+//
+// }
+// else
+ free(addr);
+
+ return 0;
+}
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif // MMAN_H
+
diff --git a/frontend/switch/zconf.h b/frontend/switch/zconf.h
new file mode 100644
index 0000000..996fff2
--- /dev/null
+++ b/frontend/switch/zconf.h
@@ -0,0 +1,511 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2013 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ * Even better than compiling with -DZ_PREFIX would be to use configure to set
+ * this permanently in zconf.h using "./configure --zprefix".
+ */
+#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */
+# define Z_PREFIX_SET
+
+/* all linked symbols */
+# define _dist_code z__dist_code
+# define _length_code z__length_code
+# define _tr_align z__tr_align
+# define _tr_flush_bits z__tr_flush_bits
+# define _tr_flush_block z__tr_flush_block
+# define _tr_init z__tr_init
+# define _tr_stored_block z__tr_stored_block
+# define _tr_tally z__tr_tally
+# define adler32 z_adler32
+# define adler32_combine z_adler32_combine
+# define adler32_combine64 z_adler32_combine64
+# ifndef Z_SOLO
+# define compress z_compress
+# define compress2 z_compress2
+# define compressBound z_compressBound
+# endif
+# define crc32 z_crc32
+# define crc32_combine z_crc32_combine
+# define crc32_combine64 z_crc32_combine64
+# define deflate z_deflate
+# define deflateBound z_deflateBound
+# define deflateCopy z_deflateCopy
+# define deflateEnd z_deflateEnd
+# define deflateInit2_ z_deflateInit2_
+# define deflateInit_ z_deflateInit_
+# define deflateParams z_deflateParams
+# define deflatePending z_deflatePending
+# define deflatePrime z_deflatePrime
+# define deflateReset z_deflateReset
+# define deflateResetKeep z_deflateResetKeep
+# define deflateSetDictionary z_deflateSetDictionary
+# define deflateSetHeader z_deflateSetHeader
+# define deflateTune z_deflateTune
+# define deflate_copyright z_deflate_copyright
+# define get_crc_table z_get_crc_table
+# ifndef Z_SOLO
+# define gz_error z_gz_error
+# define gz_intmax z_gz_intmax
+# define gz_strwinerror z_gz_strwinerror
+# define gzbuffer z_gzbuffer
+# define gzclearerr z_gzclearerr
+# define gzclose z_gzclose
+# define gzclose_r z_gzclose_r
+# define gzclose_w z_gzclose_w
+# define gzdirect z_gzdirect
+# define gzdopen z_gzdopen
+# define gzeof z_gzeof
+# define gzerror z_gzerror
+# define gzflush z_gzflush
+# define gzgetc z_gzgetc
+# define gzgetc_ z_gzgetc_
+# define gzgets z_gzgets
+# define gzoffset z_gzoffset
+# define gzoffset64 z_gzoffset64
+# define gzopen z_gzopen
+# define gzopen64 z_gzopen64
+# ifdef _WIN32
+# define gzopen_w z_gzopen_w
+# endif
+# define gzprintf z_gzprintf
+# define gzvprintf z_gzvprintf
+# define gzputc z_gzputc
+# define gzputs z_gzputs
+# define gzread z_gzread
+# define gzrewind z_gzrewind
+# define gzseek z_gzseek
+# define gzseek64 z_gzseek64
+# define gzsetparams z_gzsetparams
+# define gztell z_gztell
+# define gztell64 z_gztell64
+# define gzungetc z_gzungetc
+# define gzwrite z_gzwrite
+# endif
+# define inflate z_inflate
+# define inflateBack z_inflateBack
+# define inflateBackEnd z_inflateBackEnd
+# define inflateBackInit_ z_inflateBackInit_
+# define inflateCopy z_inflateCopy
+# define inflateEnd z_inflateEnd
+# define inflateGetHeader z_inflateGetHeader
+# define inflateInit2_ z_inflateInit2_
+# define inflateInit_ z_inflateInit_
+# define inflateMark z_inflateMark
+# define inflatePrime z_inflatePrime
+# define inflateReset z_inflateReset
+# define inflateReset2 z_inflateReset2
+# define inflateSetDictionary z_inflateSetDictionary
+# define inflateGetDictionary z_inflateGetDictionary
+# define inflateSync z_inflateSync
+# define inflateSyncPoint z_inflateSyncPoint
+# define inflateUndermine z_inflateUndermine
+# define inflateResetKeep z_inflateResetKeep
+# define inflate_copyright z_inflate_copyright
+# define inflate_fast z_inflate_fast
+# define inflate_table z_inflate_table
+# ifndef Z_SOLO
+# define uncompress z_uncompress
+# endif
+# define zError z_zError
+# ifndef Z_SOLO
+# define zcalloc z_zcalloc
+# define zcfree z_zcfree
+# endif
+# define zlibCompileFlags z_zlibCompileFlags
+# define zlibVersion z_zlibVersion
+
+/* all zlib typedefs in zlib.h and zconf.h */
+# define Byte z_Byte
+# define Bytef z_Bytef
+# define alloc_func z_alloc_func
+# define charf z_charf
+# define free_func z_free_func
+# ifndef Z_SOLO
+# define gzFile z_gzFile
+# endif
+# define gz_header z_gz_header
+# define gz_headerp z_gz_headerp
+# define in_func z_in_func
+# define intf z_intf
+# define out_func z_out_func
+# define uInt z_uInt
+# define uIntf z_uIntf
+# define uLong z_uLong
+# define uLongf z_uLongf
+# define voidp z_voidp
+# define voidpc z_voidpc
+# define voidpf z_voidpf
+
+/* all zlib structs in zlib.h and zconf.h */
+# define gz_header_s z_gz_header_s
+# define internal_state z_internal_state
+
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+# define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+# define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+# define WINDOWS
+#endif
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+# ifndef WIN32
+# define WIN32
+# endif
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+# ifndef SYS16BIT
+# define SYS16BIT
+# endif
+# endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+# define MAXSEG_64K
+#endif
+#ifdef MSDOS
+# define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+# ifndef STDC
+# define STDC
+# endif
+# if __STDC_VERSION__ >= 199901L
+# ifndef STDC99
+# define STDC99
+# endif
+# endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+# define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
+# define STDC
+#endif
+
+#ifndef STDC
+# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+# define const /* note: need a more gentle solution here */
+# endif
+#endif
+
+#if defined(ZLIB_CONST) && !defined(z_const)
+# define z_const const
+#else
+# define z_const
+#endif
+
+/* Some Mac compilers merge all .h files incorrectly: */
+#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
+# define NO_DUMMY_DECL
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+# ifdef MAXSEG_64K
+# define MAX_MEM_LEVEL 8
+# else
+# define MAX_MEM_LEVEL 9
+# endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+# define MAX_WBITS 15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+ (1 << (windowBits+2)) + (1 << (memLevel+9))
+ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+ The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+ /* Type declarations */
+
+#ifndef OF /* function prototypes */
+# ifdef STDC
+# define OF(args) args
+# else
+# define OF(args) ()
+# endif
+#endif
+
+#ifndef Z_ARG /* function prototypes for stdarg */
+# if defined(STDC) || defined(Z_HAVE_STDARG_H)
+# define Z_ARG(args) args
+# else
+# define Z_ARG(args) ()
+# endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+# if defined(M_I86SM) || defined(M_I86MM)
+ /* MSC small or medium model */
+# define SMALL_MEDIUM
+# ifdef _MSC_VER
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+# if (defined(__SMALL__) || defined(__MEDIUM__))
+ /* Turbo C small or medium model */
+# define SMALL_MEDIUM
+# ifdef __BORLANDC__
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+ /* If building or using zlib as a DLL, define ZLIB_DLL.
+ * This is not mandatory, but it offers a little performance increase.
+ */
+# ifdef ZLIB_DLL
+# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+# ifdef ZLIB_INTERNAL
+# define ZEXTERN extern __declspec(dllexport)
+# else
+# define ZEXTERN extern __declspec(dllimport)
+# endif
+# endif
+# endif /* ZLIB_DLL */
+ /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+ * define ZLIB_WINAPI.
+ * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+ */
+# ifdef ZLIB_WINAPI
+# ifdef FAR
+# undef FAR
+# endif
+# include <windows.h>
+ /* No need for _export, use ZLIB.DEF instead. */
+ /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+# define ZEXPORT WINAPI
+# ifdef WIN32
+# define ZEXPORTVA WINAPIV
+# else
+# define ZEXPORTVA FAR CDECL
+# endif
+# endif
+#endif
+
+#if defined (__BEOS__)
+# ifdef ZLIB_DLL
+# ifdef ZLIB_INTERNAL
+# define ZEXPORT __declspec(dllexport)
+# define ZEXPORTVA __declspec(dllexport)
+# else
+# define ZEXPORT __declspec(dllimport)
+# define ZEXPORTVA __declspec(dllimport)
+# endif
+# endif
+#endif
+
+#ifndef ZEXTERN
+# define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+# define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+# define ZEXPORTVA
+#endif
+
+#ifndef FAR
+# define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char Byte; /* 8 bits */
+#endif
+typedef unsigned int uInt; /* 16 bits or more */
+typedef unsigned long uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+ /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+# define Bytef Byte FAR
+#else
+ typedef Byte FAR Bytef;
+#endif
+typedef char FAR charf;
+typedef int FAR intf;
+typedef uInt FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+ typedef void const *voidpc;
+ typedef void FAR *voidpf;
+ typedef void *voidp;
+#else
+ typedef Byte const *voidpc;
+ typedef Byte FAR *voidpf;
+ typedef Byte *voidp;
+#endif
+
+#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)
+# include <limits.h>
+# if (UINT_MAX == 0xffffffffUL)
+# define Z_U4 unsigned
+# elif (ULONG_MAX == 0xffffffffUL)
+# define Z_U4 unsigned long
+# elif (USHRT_MAX == 0xffffffffUL)
+# define Z_U4 unsigned short
+# endif
+#endif
+
+#ifdef Z_U4
+ typedef Z_U4 z_crc_t;
+#else
+ typedef unsigned long z_crc_t;
+#endif
+
+#if 1 /* was set to #if 1 by ./configure */
+# define Z_HAVE_UNISTD_H
+#endif
+
+#if 1 /* was set to #if 1 by ./configure */
+# define Z_HAVE_STDARG_H
+#endif
+
+#ifdef STDC
+# ifndef Z_SOLO
+# include <sys/types.h> /* for off_t */
+# endif
+#endif
+
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+# ifndef Z_SOLO
+# include <stdarg.h> /* for va_list */
+# endif
+#endif
+
+#ifdef _WIN32
+# ifndef Z_SOLO
+# include <stddef.h> /* for wchar_t */
+# endif
+#endif
+
+/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
+ * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
+ * though the former does not conform to the LFS document), but considering
+ * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
+ * equivalently requesting no 64-bit operations
+ */
+#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
+# undef _LARGEFILE64_SOURCE
+#endif
+
+#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
+# define Z_HAVE_UNISTD_H
+#endif
+#ifndef Z_SOLO
+# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
+# include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
+# ifdef VMS
+# include <unixio.h> /* for off_t */
+# endif
+# ifndef z_off_t
+# define z_off_t off_t
+# endif
+# endif
+#endif
+
+#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0
+# define Z_LFS64
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)
+# define Z_LARGE64
+#endif
+
+#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)
+# define Z_WANT64
+#endif
+
+#if !defined(SEEK_SET) && !defined(Z_SOLO)
+# define SEEK_SET 0 /* Seek from beginning of file. */
+# define SEEK_CUR 1 /* Seek from current position. */
+# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
+#endif
+
+#ifndef z_off_t
+# define z_off_t long
+#endif
+
+#if !defined(_WIN32) && defined(Z_LARGE64)
+# define z_off64_t off64_t
+#else
+# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
+# define z_off64_t __int64
+# else
+# define z_off64_t z_off_t
+# endif
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+ #pragma map(deflateInit_,"DEIN")
+ #pragma map(deflateInit2_,"DEIN2")
+ #pragma map(deflateEnd,"DEEND")
+ #pragma map(deflateBound,"DEBND")
+ #pragma map(inflateInit_,"ININ")
+ #pragma map(inflateInit2_,"ININ2")
+ #pragma map(inflateEnd,"INEND")
+ #pragma map(inflateSync,"INSY")
+ #pragma map(inflateSetDictionary,"INSEDI")
+ #pragma map(compressBound,"CMBND")
+ #pragma map(inflate_table,"INTABL")
+ #pragma map(inflate_fast,"INFA")
+ #pragma map(inflate_copyright,"INCOPY")
+#endif
+
+#endif /* ZCONF_H */
diff --git a/frontend/switch/zlib.h b/frontend/switch/zlib.h
new file mode 100644
index 0000000..3e0c767
--- /dev/null
+++ b/frontend/switch/zlib.h
@@ -0,0 +1,1768 @@
+/* zlib.h -- interface of the 'zlib' general purpose compression library
+ version 1.2.8, April 28th, 2013
+
+ Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ jloup@gzip.org madler@alumni.caltech.edu
+
+
+ The data format used by the zlib library is described by RFCs (Request for
+ Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
+ (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
+*/
+
+#ifndef ZLIB_H
+#define ZLIB_H
+
+#include "zconf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ZLIB_VERSION "1.2.8"
+#define ZLIB_VERNUM 0x1280
+#define ZLIB_VER_MAJOR 1
+#define ZLIB_VER_MINOR 2
+#define ZLIB_VER_REVISION 8
+#define ZLIB_VER_SUBREVISION 0
+
+/*
+ The 'zlib' compression library provides in-memory compression and
+ decompression functions, including integrity checks of the uncompressed data.
+ This version of the library supports only one compression method (deflation)
+ but other algorithms will be added later and will have the same stream
+ interface.
+
+ Compression can be done in a single step if the buffers are large enough,
+ or can be done by repeated calls of the compression function. In the latter
+ case, the application must provide more input and/or consume the output
+ (providing more output space) before each call.
+
+ The compressed data format used by default by the in-memory functions is
+ the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
+ around a deflate stream, which is itself documented in RFC 1951.
+
+ The library also supports reading and writing files in gzip (.gz) format
+ with an interface similar to that of stdio using the functions that start
+ with "gz". The gzip format is different from the zlib format. gzip is a
+ gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
+
+ This library can optionally read and write gzip streams in memory as well.
+
+ The zlib format was designed to be compact and fast for use in memory
+ and on communications channels. The gzip format was designed for single-
+ file compression on file systems, has a larger header than zlib to maintain
+ directory information, and uses a different, slower check method than zlib.
+
+ The library does not install any signal handler. The decoder checks
+ the consistency of the compressed data, so the library should never crash
+ even in case of corrupted input.
+*/
+
+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
+typedef void (*free_func) OF((voidpf opaque, voidpf address));
+
+struct internal_state;
+
+typedef struct z_stream_s {
+ z_const Bytef *next_in; /* next input byte */
+ uInt avail_in; /* number of bytes available at next_in */
+ uLong total_in; /* total number of input bytes read so far */
+
+ Bytef *next_out; /* next output byte should be put there */
+ uInt avail_out; /* remaining free space at next_out */
+ uLong total_out; /* total number of bytes output so far */
+
+ z_const char *msg; /* last error message, NULL if no error */
+ struct internal_state FAR *state; /* not visible by applications */
+
+ alloc_func zalloc; /* used to allocate the internal state */
+ free_func zfree; /* used to free the internal state */
+ voidpf opaque; /* private data object passed to zalloc and zfree */
+
+ int data_type; /* best guess about the data type: binary or text */
+ uLong adler; /* adler32 value of the uncompressed data */
+ uLong reserved; /* reserved for future use */
+} z_stream;
+
+typedef z_stream FAR *z_streamp;
+
+/*
+ gzip header information passed to and from zlib routines. See RFC 1952
+ for more details on the meanings of these fields.
+*/
+typedef struct gz_header_s {
+ int text; /* true if compressed data believed to be text */
+ uLong time; /* modification time */
+ int xflags; /* extra flags (not used when writing a gzip file) */
+ int os; /* operating system */
+ Bytef *extra; /* pointer to extra field or Z_NULL if none */
+ uInt extra_len; /* extra field length (valid if extra != Z_NULL) */
+ uInt extra_max; /* space at extra (only when reading header) */
+ Bytef *name; /* pointer to zero-terminated file name or Z_NULL */
+ uInt name_max; /* space at name (only when reading header) */
+ Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */
+ uInt comm_max; /* space at comment (only when reading header) */
+ int hcrc; /* true if there was or will be a header crc */
+ int done; /* true when done reading gzip header (not used
+ when writing a gzip file) */
+} gz_header;
+
+typedef gz_header FAR *gz_headerp;
+
+/*
+ The application must update next_in and avail_in when avail_in has dropped
+ to zero. It must update next_out and avail_out when avail_out has dropped
+ to zero. The application must initialize zalloc, zfree and opaque before
+ calling the init function. All other fields are set by the compression
+ library and must not be updated by the application.
+
+ The opaque value provided by the application will be passed as the first
+ parameter for calls of zalloc and zfree. This can be useful for custom
+ memory management. The compression library attaches no meaning to the
+ opaque value.
+
+ zalloc must return Z_NULL if there is not enough memory for the object.
+ If zlib is used in a multi-threaded application, zalloc and zfree must be
+ thread safe.
+
+ On 16-bit systems, the functions zalloc and zfree must be able to allocate
+ exactly 65536 bytes, but will not be required to allocate more than this if
+ the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers
+ returned by zalloc for objects of exactly 65536 bytes *must* have their
+ offset normalized to zero. The default allocation function provided by this
+ library ensures this (see zutil.c). To reduce memory requirements and avoid
+ any allocation of 64K objects, at the expense of compression ratio, compile
+ the library with -DMAX_WBITS=14 (see zconf.h).
+
+ The fields total_in and total_out can be used for statistics or progress
+ reports. After compression, total_in holds the total size of the
+ uncompressed data and may be saved for use in the decompressor (particularly
+ if the decompressor wants to decompress everything in a single step).
+*/
+
+ /* constants */
+
+#define Z_NO_FLUSH 0
+#define Z_PARTIAL_FLUSH 1
+#define Z_SYNC_FLUSH 2
+#define Z_FULL_FLUSH 3
+#define Z_FINISH 4
+#define Z_BLOCK 5
+#define Z_TREES 6
+/* Allowed flush values; see deflate() and inflate() below for details */
+
+#define Z_OK 0
+#define Z_STREAM_END 1
+#define Z_NEED_DICT 2
+#define Z_ERRNO (-1)
+#define Z_STREAM_ERROR (-2)
+#define Z_DATA_ERROR (-3)
+#define Z_MEM_ERROR (-4)
+#define Z_BUF_ERROR (-5)
+#define Z_VERSION_ERROR (-6)
+/* Return codes for the compression/decompression functions. Negative values
+ * are errors, positive values are used for special but normal events.
+ */
+
+#define Z_NO_COMPRESSION 0
+#define Z_BEST_SPEED 1
+#define Z_BEST_COMPRESSION 9
+#define Z_DEFAULT_COMPRESSION (-1)
+/* compression levels */
+
+#define Z_FILTERED 1
+#define Z_HUFFMAN_ONLY 2
+#define Z_RLE 3
+#define Z_FIXED 4
+#define Z_DEFAULT_STRATEGY 0
+/* compression strategy; see deflateInit2() below for details */
+
+#define Z_BINARY 0
+#define Z_TEXT 1
+#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */
+#define Z_UNKNOWN 2
+/* Possible values of the data_type field (though see inflate()) */
+
+#define Z_DEFLATED 8
+/* The deflate compression method (the only one supported in this version) */
+
+#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
+
+#define zlib_version zlibVersion()
+/* for compatibility with versions < 1.0.2 */
+
+
+ /* basic functions */
+
+ZEXTERN const char * ZEXPORT zlibVersion OF((void));
+/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
+ If the first character differs, the library code actually used is not
+ compatible with the zlib.h header file used by the application. This check
+ is automatically made by deflateInit and inflateInit.
+ */
+
+/*
+ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
+
+ Initializes the internal stream state for compression. The fields
+ zalloc, zfree and opaque must be initialized before by the caller. If
+ zalloc and zfree are set to Z_NULL, deflateInit updates them to use default
+ allocation functions.
+
+ The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
+ 1 gives best speed, 9 gives best compression, 0 gives no compression at all
+ (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION
+ requests a default compromise between speed and compression (currently
+ equivalent to level 6).
+
+ deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_STREAM_ERROR if level is not a valid compression level, or
+ Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
+ with the version assumed by the caller (ZLIB_VERSION). msg is set to null
+ if there is no error message. deflateInit does not perform any compression:
+ this will be done by deflate().
+*/
+
+
+ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
+/*
+ deflate compresses as much data as possible, and stops when the input
+ buffer becomes empty or the output buffer becomes full. It may introduce
+ some output latency (reading input without producing any output) except when
+ forced to flush.
+
+ The detailed semantics are as follows. deflate performs one or both of the
+ following actions:
+
+ - Compress more input starting at next_in and update next_in and avail_in
+ accordingly. If not all input can be processed (because there is not
+ enough room in the output buffer), next_in and avail_in are updated and
+ processing will resume at this point for the next call of deflate().
+
+ - Provide more output starting at next_out and update next_out and avail_out
+ accordingly. This action is forced if the parameter flush is non zero.
+ Forcing flush frequently degrades the compression ratio, so this parameter
+ should be set only when necessary (in interactive applications). Some
+ output may be provided even if flush is not set.
+
+ Before the call of deflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming more
+ output, and updating avail_in or avail_out accordingly; avail_out should
+ never be zero before the call. The application can consume the compressed
+ output when it wants, for example when the output buffer is full (avail_out
+ == 0), or after each call of deflate(). If deflate returns Z_OK and with
+ zero avail_out, it must be called again after making room in the output
+ buffer because there might be more output pending.
+
+ Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
+ decide how much data to accumulate before producing output, in order to
+ maximize compression.
+
+ If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
+ flushed to the output buffer and the output is aligned on a byte boundary, so
+ that the decompressor can get all input data available so far. (In
+ particular avail_in is zero after the call if enough output space has been
+ provided before the call.) Flushing may degrade compression for some
+ compression algorithms and so it should be used only when necessary. This
+ completes the current deflate block and follows it with an empty stored block
+ that is three bits plus filler bits to the next byte, followed by four bytes
+ (00 00 ff ff).
+
+ If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the
+ output buffer, but the output is not aligned to a byte boundary. All of the
+ input data so far will be available to the decompressor, as for Z_SYNC_FLUSH.
+ This completes the current deflate block and follows it with an empty fixed
+ codes block that is 10 bits long. This assures that enough bytes are output
+ in order for the decompressor to finish the block before the empty fixed code
+ block.
+
+ If flush is set to Z_BLOCK, a deflate block is completed and emitted, as
+ for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to
+ seven bits of the current block are held to be written as the next byte after
+ the next deflate block is completed. In this case, the decompressor may not
+ be provided enough bits at this point in order to complete decompression of
+ the data provided so far to the compressor. It may need to wait for the next
+ block to be emitted. This is for advanced applications that need to control
+ the emission of deflate blocks.
+
+ If flush is set to Z_FULL_FLUSH, all output is flushed as with
+ Z_SYNC_FLUSH, and the compression state is reset so that decompression can
+ restart from this point if previous compressed data has been damaged or if
+ random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
+ compression.
+
+ If deflate returns with avail_out == 0, this function must be called again
+ with the same value of the flush parameter and more output space (updated
+ avail_out), until the flush is complete (deflate returns with non-zero
+ avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
+ avail_out is greater than six to avoid repeated flush markers due to
+ avail_out == 0 on return.
+
+ If the parameter flush is set to Z_FINISH, pending input is processed,
+ pending output is flushed and deflate returns with Z_STREAM_END if there was
+ enough output space; if deflate returns with Z_OK, this function must be
+ called again with Z_FINISH and more output space (updated avail_out) but no
+ more input data, until it returns with Z_STREAM_END or an error. After
+ deflate has returned Z_STREAM_END, the only possible operations on the stream
+ are deflateReset or deflateEnd.
+
+ Z_FINISH can be used immediately after deflateInit if all the compression
+ is to be done in a single step. In this case, avail_out must be at least the
+ value returned by deflateBound (see below). Then deflate is guaranteed to
+ return Z_STREAM_END. If not enough output space is provided, deflate will
+ not return Z_STREAM_END, and it must be called again as described above.
+
+ deflate() sets strm->adler to the adler32 checksum of all input read
+ so far (that is, total_in bytes).
+
+ deflate() may update strm->data_type if it can make a good guess about
+ the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered
+ binary. This field is only for information purposes and does not affect the
+ compression algorithm in any manner.
+
+ deflate() returns Z_OK if some progress has been made (more input
+ processed or more output produced), Z_STREAM_END if all input has been
+ consumed and all output has been produced (only when flush is set to
+ Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
+ if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible
+ (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not
+ fatal, and deflate() can be called again with more input and more output
+ space to continue compressing.
+*/
+
+
+ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
+/*
+ All dynamically allocated data structures for this stream are freed.
+ This function discards any unprocessed input and does not flush any pending
+ output.
+
+ deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
+ stream state was inconsistent, Z_DATA_ERROR if the stream was freed
+ prematurely (some input or output was discarded). In the error case, msg
+ may be set but then points to a static string (which must not be
+ deallocated).
+*/
+
+
+/*
+ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
+
+ Initializes the internal stream state for decompression. The fields
+ next_in, avail_in, zalloc, zfree and opaque must be initialized before by
+ the caller. If next_in is not Z_NULL and avail_in is large enough (the
+ exact value depends on the compression method), inflateInit determines the
+ compression method from the zlib header and allocates all data structures
+ accordingly; otherwise the allocation will be deferred to the first call of
+ inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
+ use default allocation functions.
+
+ inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+ version assumed by the caller, or Z_STREAM_ERROR if the parameters are
+ invalid, such as a null pointer to the structure. msg is set to null if
+ there is no error message. inflateInit does not perform any decompression
+ apart from possibly reading the zlib header if present: actual decompression
+ will be done by inflate(). (So next_in and avail_in may be modified, but
+ next_out and avail_out are unused and unchanged.) The current implementation
+ of inflateInit() does not process any header information -- that is deferred
+ until inflate() is called.
+*/
+
+
+ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
+/*
+ inflate decompresses as much data as possible, and stops when the input
+ buffer becomes empty or the output buffer becomes full. It may introduce
+ some output latency (reading input without producing any output) except when
+ forced to flush.
+
+ The detailed semantics are as follows. inflate performs one or both of the
+ following actions:
+
+ - Decompress more input starting at next_in and update next_in and avail_in
+ accordingly. If not all input can be processed (because there is not
+ enough room in the output buffer), next_in is updated and processing will
+ resume at this point for the next call of inflate().
+
+ - Provide more output starting at next_out and update next_out and avail_out
+ accordingly. inflate() provides as much output as possible, until there is
+ no more input data or no more space in the output buffer (see below about
+ the flush parameter).
+
+ Before the call of inflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming more
+ output, and updating the next_* and avail_* values accordingly. The
+ application can consume the uncompressed output when it wants, for example
+ when the output buffer is full (avail_out == 0), or after each call of
+ inflate(). If inflate returns Z_OK and with zero avail_out, it must be
+ called again after making room in the output buffer because there might be
+ more output pending.
+
+ The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH,
+ Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much
+ output as possible to the output buffer. Z_BLOCK requests that inflate()
+ stop if and when it gets to the next deflate block boundary. When decoding
+ the zlib or gzip format, this will cause inflate() to return immediately
+ after the header and before the first block. When doing a raw inflate,
+ inflate() will go ahead and process the first block, and will return when it
+ gets to the end of that block, or when it runs out of data.
+
+ The Z_BLOCK option assists in appending to or combining deflate streams.
+ Also to assist in this, on return inflate() will set strm->data_type to the
+ number of unused bits in the last byte taken from strm->next_in, plus 64 if
+ inflate() is currently decoding the last block in the deflate stream, plus
+ 128 if inflate() returned immediately after decoding an end-of-block code or
+ decoding the complete header up to just before the first byte of the deflate
+ stream. The end-of-block will not be indicated until all of the uncompressed
+ data from that block has been written to strm->next_out. The number of
+ unused bits may in general be greater than seven, except when bit 7 of
+ data_type is set, in which case the number of unused bits will be less than
+ eight. data_type is set as noted here every time inflate() returns for all
+ flush options, and so can be used to determine the amount of currently
+ consumed input in bits.
+
+ The Z_TREES option behaves as Z_BLOCK does, but it also returns when the
+ end of each deflate block header is reached, before any actual data in that
+ block is decoded. This allows the caller to determine the length of the
+ deflate block header for later use in random access within a deflate block.
+ 256 is added to the value of strm->data_type when inflate() returns
+ immediately after reaching the end of the deflate block header.
+
+ inflate() should normally be called until it returns Z_STREAM_END or an
+ error. However if all decompression is to be performed in a single step (a
+ single call of inflate), the parameter flush should be set to Z_FINISH. In
+ this case all pending input is processed and all pending output is flushed;
+ avail_out must be large enough to hold all of the uncompressed data for the
+ operation to complete. (The size of the uncompressed data may have been
+ saved by the compressor for this purpose.) The use of Z_FINISH is not
+ required to perform an inflation in one step. However it may be used to
+ inform inflate that a faster approach can be used for the single inflate()
+ call. Z_FINISH also informs inflate to not maintain a sliding window if the
+ stream completes, which reduces inflate's memory footprint. If the stream
+ does not complete, either because not all of the stream is provided or not
+ enough output space is provided, then a sliding window will be allocated and
+ inflate() can be called again to continue the operation as if Z_NO_FLUSH had
+ been used.
+
+ In this implementation, inflate() always flushes as much output as
+ possible to the output buffer, and always uses the faster approach on the
+ first call. So the effects of the flush parameter in this implementation are
+ on the return value of inflate() as noted below, when inflate() returns early
+ when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of
+ memory for a sliding window when Z_FINISH is used.
+
+ If a preset dictionary is needed after this call (see inflateSetDictionary
+ below), inflate sets strm->adler to the Adler-32 checksum of the dictionary
+ chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
+ strm->adler to the Adler-32 checksum of all output produced so far (that is,
+ total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
+ below. At the end of the stream, inflate() checks that its computed adler32
+ checksum is equal to that saved by the compressor and returns Z_STREAM_END
+ only if the checksum is correct.
+
+ inflate() can decompress and check either zlib-wrapped or gzip-wrapped
+ deflate data. The header type is detected automatically, if requested when
+ initializing with inflateInit2(). Any information contained in the gzip
+ header is not retained, so applications that need that information should
+ instead use raw inflate, see inflateInit2() below, or inflateBack() and
+ perform their own processing of the gzip header and trailer. When processing
+ gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output
+ producted so far. The CRC-32 is checked against the gzip trailer.
+
+ inflate() returns Z_OK if some progress has been made (more input processed
+ or more output produced), Z_STREAM_END if the end of the compressed data has
+ been reached and all uncompressed output has been produced, Z_NEED_DICT if a
+ preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
+ corrupted (input stream not conforming to the zlib format or incorrect check
+ value), Z_STREAM_ERROR if the stream structure was inconsistent (for example
+ next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory,
+ Z_BUF_ERROR if no progress is possible or if there was not enough room in the
+ output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
+ inflate() can be called again with more input and more output space to
+ continue decompressing. If Z_DATA_ERROR is returned, the application may
+ then call inflateSync() to look for a good compression block if a partial
+ recovery of the data is desired.
+*/
+
+
+ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
+/*
+ All dynamically allocated data structures for this stream are freed.
+ This function discards any unprocessed input and does not flush any pending
+ output.
+
+ inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
+ was inconsistent. In the error case, msg may be set but then points to a
+ static string (which must not be deallocated).
+*/
+
+
+ /* Advanced functions */
+
+/*
+ The following functions are needed only in some special applications.
+*/
+
+/*
+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
+ int level,
+ int method,
+ int windowBits,
+ int memLevel,
+ int strategy));
+
+ This is another version of deflateInit with more compression options. The
+ fields next_in, zalloc, zfree and opaque must be initialized before by the
+ caller.
+
+ The method parameter is the compression method. It must be Z_DEFLATED in
+ this version of the library.
+
+ The windowBits parameter is the base two logarithm of the window size
+ (the size of the history buffer). It should be in the range 8..15 for this
+ version of the library. Larger values of this parameter result in better
+ compression at the expense of memory usage. The default value is 15 if
+ deflateInit is used instead.
+
+ windowBits can also be -8..-15 for raw deflate. In this case, -windowBits
+ determines the window size. deflate() will then generate raw deflate data
+ with no zlib header or trailer, and will not compute an adler32 check value.
+
+ windowBits can also be greater than 15 for optional gzip encoding. Add
+ 16 to windowBits to write a simple gzip header and trailer around the
+ compressed data instead of a zlib wrapper. The gzip header will have no
+ file name, no extra data, no comment, no modification time (set to zero), no
+ header crc, and the operating system will be set to 255 (unknown). If a
+ gzip stream is being written, strm->adler is a crc32 instead of an adler32.
+
+ The memLevel parameter specifies how much memory should be allocated
+ for the internal compression state. memLevel=1 uses minimum memory but is
+ slow and reduces compression ratio; memLevel=9 uses maximum memory for
+ optimal speed. The default value is 8. See zconf.h for total memory usage
+ as a function of windowBits and memLevel.
+
+ The strategy parameter is used to tune the compression algorithm. Use the
+ value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
+ filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
+ string match), or Z_RLE to limit match distances to one (run-length
+ encoding). Filtered data consists mostly of small values with a somewhat
+ random distribution. In this case, the compression algorithm is tuned to
+ compress them better. The effect of Z_FILTERED is to force more Huffman
+ coding and less string matching; it is somewhat intermediate between
+ Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as
+ fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The
+ strategy parameter only affects the compression ratio but not the
+ correctness of the compressed output even if it is not set appropriately.
+ Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler
+ decoder for special applications.
+
+ deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid
+ method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is
+ incompatible with the version assumed by the caller (ZLIB_VERSION). msg is
+ set to null if there is no error message. deflateInit2 does not perform any
+ compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
+ const Bytef *dictionary,
+ uInt dictLength));
+/*
+ Initializes the compression dictionary from the given byte sequence
+ without producing any compressed output. When using the zlib format, this
+ function must be called immediately after deflateInit, deflateInit2 or
+ deflateReset, and before any call of deflate. When doing raw deflate, this
+ function must be called either before any call of deflate, or immediately
+ after the completion of a deflate block, i.e. after all input has been
+ consumed and all output has been delivered when using any of the flush
+ options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The
+ compressor and decompressor must use exactly the same dictionary (see
+ inflateSetDictionary).
+
+ The dictionary should consist of strings (byte sequences) that are likely
+ to be encountered later in the data to be compressed, with the most commonly
+ used strings preferably put towards the end of the dictionary. Using a
+ dictionary is most useful when the data to be compressed is short and can be
+ predicted with good accuracy; the data can then be compressed better than
+ with the default empty dictionary.
+
+ Depending on the size of the compression data structures selected by
+ deflateInit or deflateInit2, a part of the dictionary may in effect be
+ discarded, for example if the dictionary is larger than the window size
+ provided in deflateInit or deflateInit2. Thus the strings most likely to be
+ useful should be put at the end of the dictionary, not at the front. In
+ addition, the current implementation of deflate will use at most the window
+ size minus 262 bytes of the provided dictionary.
+
+ Upon return of this function, strm->adler is set to the adler32 value
+ of the dictionary; the decompressor may later use this value to determine
+ which dictionary has been used by the compressor. (The adler32 value
+ applies to the whole dictionary even if only a subset of the dictionary is
+ actually used by the compressor.) If a raw deflate was requested, then the
+ adler32 value is not computed and strm->adler is not set.
+
+ deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
+ parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
+ inconsistent (for example if deflate has already been called for this stream
+ or if not at a block boundary for raw deflate). deflateSetDictionary does
+ not perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
+ z_streamp source));
+/*
+ Sets the destination stream as a complete copy of the source stream.
+
+ This function can be useful when several compression strategies will be
+ tried, for example when there are several ways of pre-processing the input
+ data with a filter. The streams that will be discarded should then be freed
+ by calling deflateEnd. Note that deflateCopy duplicates the internal
+ compression state which can be quite large, so this strategy is slow and can
+ consume lots of memory.
+
+ deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+ (such as zalloc being Z_NULL). msg is left unchanged in both source and
+ destination.
+*/
+
+ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
+/*
+ This function is equivalent to deflateEnd followed by deflateInit,
+ but does not free and reallocate all the internal compression state. The
+ stream will keep the same compression level and any other attributes that
+ may have been set by deflateInit2.
+
+ deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being Z_NULL).
+*/
+
+ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
+ int level,
+ int strategy));
+/*
+ Dynamically update the compression level and compression strategy. The
+ interpretation of level and strategy is as in deflateInit2. This can be
+ used to switch between compression and straight copy of the input data, or
+ to switch to a different kind of input data requiring a different strategy.
+ If the compression level is changed, the input available so far is
+ compressed with the old level (and may be flushed); the new level will take
+ effect only at the next call of deflate().
+
+ Before the call of deflateParams, the stream state must be set as for
+ a call of deflate(), since the currently available input may have to be
+ compressed and flushed. In particular, strm->avail_out must be non-zero.
+
+ deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
+ stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if
+ strm->avail_out was zero.
+*/
+
+ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
+ int good_length,
+ int max_lazy,
+ int nice_length,
+ int max_chain));
+/*
+ Fine tune deflate's internal compression parameters. This should only be
+ used by someone who understands the algorithm used by zlib's deflate for
+ searching for the best matching string, and even then only by the most
+ fanatic optimizer trying to squeeze out the last compressed bit for their
+ specific input data. Read the deflate.c source code for the meaning of the
+ max_lazy, good_length, nice_length, and max_chain parameters.
+
+ deflateTune() can be called after deflateInit() or deflateInit2(), and
+ returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
+ */
+
+ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
+ uLong sourceLen));
+/*
+ deflateBound() returns an upper bound on the compressed size after
+ deflation of sourceLen bytes. It must be called after deflateInit() or
+ deflateInit2(), and after deflateSetHeader(), if used. This would be used
+ to allocate an output buffer for deflation in a single pass, and so would be
+ called before deflate(). If that first deflate() call is provided the
+ sourceLen input bytes, an output buffer allocated to the size returned by
+ deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed
+ to return Z_STREAM_END. Note that it is possible for the compressed size to
+ be larger than the value returned by deflateBound() if flush options other
+ than Z_FINISH or Z_NO_FLUSH are used.
+*/
+
+ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm,
+ unsigned *pending,
+ int *bits));
+/*
+ deflatePending() returns the number of bytes and bits of output that have
+ been generated, but not yet provided in the available output. The bytes not
+ provided would be due to the available output space having being consumed.
+ The number of bits of output not provided are between 0 and 7, where they
+ await more bits to join them in order to fill out a full byte. If pending
+ or bits are Z_NULL, then those values are not set.
+
+ deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+ */
+
+ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
+ int bits,
+ int value));
+/*
+ deflatePrime() inserts bits in the deflate output stream. The intent
+ is that this function is used to start off the deflate output with the bits
+ leftover from a previous deflate stream when appending to it. As such, this
+ function can only be used for raw deflate, and must be used before the first
+ deflate() call after a deflateInit2() or deflateReset(). bits must be less
+ than or equal to 16, and that many of the least significant bits of value
+ will be inserted in the output.
+
+ deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough
+ room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the
+ source stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
+ gz_headerp head));
+/*
+ deflateSetHeader() provides gzip header information for when a gzip
+ stream is requested by deflateInit2(). deflateSetHeader() may be called
+ after deflateInit2() or deflateReset() and before the first call of
+ deflate(). The text, time, os, extra field, name, and comment information
+ in the provided gz_header structure are written to the gzip header (xflag is
+ ignored -- the extra flags are set according to the compression level). The
+ caller must assure that, if not Z_NULL, name and comment are terminated with
+ a zero byte, and that if extra is not Z_NULL, that extra_len bytes are
+ available there. If hcrc is true, a gzip header crc is included. Note that
+ the current versions of the command-line version of gzip (up through version
+ 1.3.x) do not support header crc's, and will report that it is a "multi-part
+ gzip file" and give up.
+
+ If deflateSetHeader is not used, the default gzip header has text false,
+ the time set to zero, and os set to 255, with no extra, name, or comment
+ fields. The gzip header is returned to the default state by deflateReset().
+
+ deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
+ int windowBits));
+
+ This is another version of inflateInit with an extra parameter. The
+ fields next_in, avail_in, zalloc, zfree and opaque must be initialized
+ before by the caller.
+
+ The windowBits parameter is the base two logarithm of the maximum window
+ size (the size of the history buffer). It should be in the range 8..15 for
+ this version of the library. The default value is 15 if inflateInit is used
+ instead. windowBits must be greater than or equal to the windowBits value
+ provided to deflateInit2() while compressing, or it must be equal to 15 if
+ deflateInit2() was not used. If a compressed stream with a larger window
+ size is given as input, inflate() will return with the error code
+ Z_DATA_ERROR instead of trying to allocate a larger window.
+
+ windowBits can also be zero to request that inflate use the window size in
+ the zlib header of the compressed stream.
+
+ windowBits can also be -8..-15 for raw inflate. In this case, -windowBits
+ determines the window size. inflate() will then process raw deflate data,
+ not looking for a zlib or gzip header, not generating a check value, and not
+ looking for any check values for comparison at the end of the stream. This
+ is for use with other formats that use the deflate compressed data format
+ such as zip. Those formats provide their own check values. If a custom
+ format is developed using the raw deflate format for compressed data, it is
+ recommended that a check value such as an adler32 or a crc32 be applied to
+ the uncompressed data as is done in the zlib, gzip, and zip formats. For
+ most applications, the zlib format should be used as is. Note that comments
+ above on the use in deflateInit2() applies to the magnitude of windowBits.
+
+ windowBits can also be greater than 15 for optional gzip decoding. Add
+ 32 to windowBits to enable zlib and gzip decoding with automatic header
+ detection, or add 16 to decode only the gzip format (the zlib format will
+ return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a
+ crc32 instead of an adler32.
+
+ inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+ version assumed by the caller, or Z_STREAM_ERROR if the parameters are
+ invalid, such as a null pointer to the structure. msg is set to null if
+ there is no error message. inflateInit2 does not perform any decompression
+ apart from possibly reading the zlib header if present: actual decompression
+ will be done by inflate(). (So next_in and avail_in may be modified, but
+ next_out and avail_out are unused and unchanged.) The current implementation
+ of inflateInit2() does not process any header information -- that is
+ deferred until inflate() is called.
+*/
+
+ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
+ const Bytef *dictionary,
+ uInt dictLength));
+/*
+ Initializes the decompression dictionary from the given uncompressed byte
+ sequence. This function must be called immediately after a call of inflate,
+ if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
+ can be determined from the adler32 value returned by that call of inflate.
+ The compressor and decompressor must use exactly the same dictionary (see
+ deflateSetDictionary). For raw inflate, this function can be called at any
+ time to set the dictionary. If the provided dictionary is smaller than the
+ window and there is already data in the window, then the provided dictionary
+ will amend what's there. The application must insure that the dictionary
+ that was used for compression is provided.
+
+ inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
+ parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
+ inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
+ expected one (incorrect adler32 value). inflateSetDictionary does not
+ perform any decompression: this will be done by subsequent calls of
+ inflate().
+*/
+
+ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm,
+ Bytef *dictionary,
+ uInt *dictLength));
+/*
+ Returns the sliding dictionary being maintained by inflate. dictLength is
+ set to the number of bytes in the dictionary, and that many bytes are copied
+ to dictionary. dictionary must have enough space, where 32768 bytes is
+ always enough. If inflateGetDictionary() is called with dictionary equal to
+ Z_NULL, then only the dictionary length is returned, and nothing is copied.
+ Similary, if dictLength is Z_NULL, then it is not set.
+
+ inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the
+ stream state is inconsistent.
+*/
+
+ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
+/*
+ Skips invalid compressed data until a possible full flush point (see above
+ for the description of deflate with Z_FULL_FLUSH) can be found, or until all
+ available input is skipped. No output is provided.
+
+ inflateSync searches for a 00 00 FF FF pattern in the compressed data.
+ All full flush points have this pattern, but not all occurrences of this
+ pattern are full flush points.
+
+ inflateSync returns Z_OK if a possible full flush point has been found,
+ Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point
+ has been found, or Z_STREAM_ERROR if the stream structure was inconsistent.
+ In the success case, the application may save the current current value of
+ total_in which indicates where valid compressed data was found. In the
+ error case, the application may repeatedly call inflateSync, providing more
+ input each time, until success or end of the input data.
+*/
+
+ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
+ z_streamp source));
+/*
+ Sets the destination stream as a complete copy of the source stream.
+
+ This function can be useful when randomly accessing a large stream. The
+ first pass through the stream can periodically record the inflate state,
+ allowing restarting inflate at those points when randomly accessing the
+ stream.
+
+ inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+ (such as zalloc being Z_NULL). msg is left unchanged in both source and
+ destination.
+*/
+
+ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
+/*
+ This function is equivalent to inflateEnd followed by inflateInit,
+ but does not free and reallocate all the internal decompression state. The
+ stream will keep attributes that may have been set by inflateInit2.
+
+ inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being Z_NULL).
+*/
+
+ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm,
+ int windowBits));
+/*
+ This function is the same as inflateReset, but it also permits changing
+ the wrap and window size requests. The windowBits parameter is interpreted
+ the same as it is for inflateInit2.
+
+ inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being Z_NULL), or if
+ the windowBits parameter is invalid.
+*/
+
+ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
+ int bits,
+ int value));
+/*
+ This function inserts bits in the inflate input stream. The intent is
+ that this function is used to start inflating at a bit position in the
+ middle of a byte. The provided bits will be used before any bytes are used
+ from next_in. This function should only be used with raw inflate, and
+ should be used before the first inflate() call after inflateInit2() or
+ inflateReset(). bits must be less than or equal to 16, and that many of the
+ least significant bits of value will be inserted in the input.
+
+ If bits is negative, then the input stream bit buffer is emptied. Then
+ inflatePrime() can be called again to put bits in the buffer. This is used
+ to clear out bits leftover after feeding inflate a block description prior
+ to feeding inflate codes.
+
+ inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm));
+/*
+ This function returns two values, one in the lower 16 bits of the return
+ value, and the other in the remaining upper bits, obtained by shifting the
+ return value down 16 bits. If the upper value is -1 and the lower value is
+ zero, then inflate() is currently decoding information outside of a block.
+ If the upper value is -1 and the lower value is non-zero, then inflate is in
+ the middle of a stored block, with the lower value equaling the number of
+ bytes from the input remaining to copy. If the upper value is not -1, then
+ it is the number of bits back from the current bit position in the input of
+ the code (literal or length/distance pair) currently being processed. In
+ that case the lower value is the number of bytes already emitted for that
+ code.
+
+ A code is being processed if inflate is waiting for more input to complete
+ decoding of the code, or if it has completed decoding but is waiting for
+ more output space to write the literal or match data.
+
+ inflateMark() is used to mark locations in the input data for random
+ access, which may be at bit positions, and to note those cases where the
+ output of a code may span boundaries of random access blocks. The current
+ location in the input stream can be determined from avail_in and data_type
+ as noted in the description for the Z_BLOCK flush parameter for inflate.
+
+ inflateMark returns the value noted above or -1 << 16 if the provided
+ source stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
+ gz_headerp head));
+/*
+ inflateGetHeader() requests that gzip header information be stored in the
+ provided gz_header structure. inflateGetHeader() may be called after
+ inflateInit2() or inflateReset(), and before the first call of inflate().
+ As inflate() processes the gzip stream, head->done is zero until the header
+ is completed, at which time head->done is set to one. If a zlib stream is
+ being decoded, then head->done is set to -1 to indicate that there will be
+ no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be
+ used to force inflate() to return immediately after header processing is
+ complete and before any actual data is decompressed.
+
+ The text, time, xflags, and os fields are filled in with the gzip header
+ contents. hcrc is set to true if there is a header CRC. (The header CRC
+ was valid if done is set to one.) If extra is not Z_NULL, then extra_max
+ contains the maximum number of bytes to write to extra. Once done is true,
+ extra_len contains the actual extra field length, and extra contains the
+ extra field, or that field truncated if extra_max is less than extra_len.
+ If name is not Z_NULL, then up to name_max characters are written there,
+ terminated with a zero unless the length is greater than name_max. If
+ comment is not Z_NULL, then up to comm_max characters are written there,
+ terminated with a zero unless the length is greater than comm_max. When any
+ of extra, name, or comment are not Z_NULL and the respective field is not
+ present in the header, then that field is set to Z_NULL to signal its
+ absence. This allows the use of deflateSetHeader() with the returned
+ structure to duplicate the header. However if those fields are set to
+ allocated memory, then the application will need to save those pointers
+ elsewhere so that they can be eventually freed.
+
+ If inflateGetHeader is not used, then the header information is simply
+ discarded. The header is always checked for validity, including the header
+ CRC if present. inflateReset() will reset the process to discard the header
+ information. The application would need to call inflateGetHeader() again to
+ retrieve the header from the next gzip stream.
+
+ inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
+ unsigned char FAR *window));
+
+ Initialize the internal stream state for decompression using inflateBack()
+ calls. The fields zalloc, zfree and opaque in strm must be initialized
+ before the call. If zalloc and zfree are Z_NULL, then the default library-
+ derived memory allocation routines are used. windowBits is the base two
+ logarithm of the window size, in the range 8..15. window is a caller
+ supplied buffer of that size. Except for special applications where it is
+ assured that deflate was used with small window sizes, windowBits must be 15
+ and a 32K byte window must be supplied to be able to decompress general
+ deflate streams.
+
+ See inflateBack() for the usage of these routines.
+
+ inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
+ the parameters are invalid, Z_MEM_ERROR if the internal state could not be
+ allocated, or Z_VERSION_ERROR if the version of the library does not match
+ the version of the header file.
+*/
+
+typedef unsigned (*in_func) OF((void FAR *,
+ z_const unsigned char FAR * FAR *));
+typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
+
+ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
+ in_func in, void FAR *in_desc,
+ out_func out, void FAR *out_desc));
+/*
+ inflateBack() does a raw inflate with a single call using a call-back
+ interface for input and output. This is potentially more efficient than
+ inflate() for file i/o applications, in that it avoids copying between the
+ output and the sliding window by simply making the window itself the output
+ buffer. inflate() can be faster on modern CPUs when used with large
+ buffers. inflateBack() trusts the application to not change the output
+ buffer passed by the output function, at least until inflateBack() returns.
+
+ inflateBackInit() must be called first to allocate the internal state
+ and to initialize the state with the user-provided window buffer.
+ inflateBack() may then be used multiple times to inflate a complete, raw
+ deflate stream with each call. inflateBackEnd() is then called to free the
+ allocated state.
+
+ A raw deflate stream is one with no zlib or gzip header or trailer.
+ This routine would normally be used in a utility that reads zip or gzip
+ files and writes out uncompressed files. The utility would decode the
+ header and process the trailer on its own, hence this routine expects only
+ the raw deflate stream to decompress. This is different from the normal
+ behavior of inflate(), which expects either a zlib or gzip header and
+ trailer around the deflate stream.
+
+ inflateBack() uses two subroutines supplied by the caller that are then
+ called by inflateBack() for input and output. inflateBack() calls those
+ routines until it reads a complete deflate stream and writes out all of the
+ uncompressed data, or until it encounters an error. The function's
+ parameters and return types are defined above in the in_func and out_func
+ typedefs. inflateBack() will call in(in_desc, &buf) which should return the
+ number of bytes of provided input, and a pointer to that input in buf. If
+ there is no input available, in() must return zero--buf is ignored in that
+ case--and inflateBack() will return a buffer error. inflateBack() will call
+ out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out()
+ should return zero on success, or non-zero on failure. If out() returns
+ non-zero, inflateBack() will return with an error. Neither in() nor out()
+ are permitted to change the contents of the window provided to
+ inflateBackInit(), which is also the buffer that out() uses to write from.
+ The length written by out() will be at most the window size. Any non-zero
+ amount of input may be provided by in().
+
+ For convenience, inflateBack() can be provided input on the first call by
+ setting strm->next_in and strm->avail_in. If that input is exhausted, then
+ in() will be called. Therefore strm->next_in must be initialized before
+ calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called
+ immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in
+ must also be initialized, and then if strm->avail_in is not zero, input will
+ initially be taken from strm->next_in[0 .. strm->avail_in - 1].
+
+ The in_desc and out_desc parameters of inflateBack() is passed as the
+ first parameter of in() and out() respectively when they are called. These
+ descriptors can be optionally used to pass any information that the caller-
+ supplied in() and out() functions need to do their job.
+
+ On return, inflateBack() will set strm->next_in and strm->avail_in to
+ pass back any unused input that was provided by the last in() call. The
+ return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
+ if in() or out() returned an error, Z_DATA_ERROR if there was a format error
+ in the deflate stream (in which case strm->msg is set to indicate the nature
+ of the error), or Z_STREAM_ERROR if the stream was not properly initialized.
+ In the case of Z_BUF_ERROR, an input or output error can be distinguished
+ using strm->next_in which will be Z_NULL only if in() returned an error. If
+ strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning
+ non-zero. (in() will always be called before out(), so strm->next_in is
+ assured to be defined if out() returns non-zero.) Note that inflateBack()
+ cannot return Z_OK.
+*/
+
+ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
+/*
+ All memory allocated by inflateBackInit() is freed.
+
+ inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream
+ state was inconsistent.
+*/
+
+ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
+/* Return flags indicating compile-time options.
+
+ Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
+ 1.0: size of uInt
+ 3.2: size of uLong
+ 5.4: size of voidpf (pointer)
+ 7.6: size of z_off_t
+
+ Compiler, assembler, and debug options:
+ 8: DEBUG
+ 9: ASMV or ASMINF -- use ASM code
+ 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
+ 11: 0 (reserved)
+
+ One-time table building (smaller code, but not thread-safe if true):
+ 12: BUILDFIXED -- build static block decoding tables when needed
+ 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed
+ 14,15: 0 (reserved)
+
+ Library content (indicates missing functionality):
+ 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking
+ deflate code when not needed)
+ 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect
+ and decode gzip streams (to avoid linking crc code)
+ 18-19: 0 (reserved)
+
+ Operation variations (changes in library functionality):
+ 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate
+ 21: FASTEST -- deflate algorithm with only one, lowest compression level
+ 22,23: 0 (reserved)
+
+ The sprintf variant used by gzprintf (zero is best):
+ 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format
+ 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!
+ 26: 0 = returns value, 1 = void -- 1 means inferred string length returned
+
+ Remainder:
+ 27-31: 0 (reserved)
+ */
+
+#ifndef Z_SOLO
+
+ /* utility functions */
+
+/*
+ The following utility functions are implemented on top of the basic
+ stream-oriented functions. To simplify the interface, some default options
+ are assumed (compression level and memory usage, standard memory allocation
+ functions). The source code of these utility functions can be modified if
+ you need special options.
+*/
+
+ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen));
+/*
+ Compresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total size
+ of the destination buffer, which must be at least the value returned by
+ compressBound(sourceLen). Upon exit, destLen is the actual size of the
+ compressed buffer.
+
+ compress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer.
+*/
+
+ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen,
+ int level));
+/*
+ Compresses the source buffer into the destination buffer. The level
+ parameter has the same meaning as in deflateInit. sourceLen is the byte
+ length of the source buffer. Upon entry, destLen is the total size of the
+ destination buffer, which must be at least the value returned by
+ compressBound(sourceLen). Upon exit, destLen is the actual size of the
+ compressed buffer.
+
+ compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+ Z_STREAM_ERROR if the level parameter is invalid.
+*/
+
+ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
+/*
+ compressBound() returns an upper bound on the compressed size after
+ compress() or compress2() on sourceLen bytes. It would be used before a
+ compress() or compress2() call to allocate the destination buffer.
+*/
+
+ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen));
+/*
+ Decompresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total size
+ of the destination buffer, which must be large enough to hold the entire
+ uncompressed data. (The size of the uncompressed data must have been saved
+ previously by the compressor and transmitted to the decompressor by some
+ mechanism outside the scope of this compression library.) Upon exit, destLen
+ is the actual size of the uncompressed buffer.
+
+ uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In
+ the case where there is not enough room, uncompress() will fill the output
+ buffer with the uncompressed data up to that point.
+*/
+
+ /* gzip file access functions */
+
+/*
+ This library supports reading and writing files in gzip (.gz) format with
+ an interface similar to that of stdio, using the functions that start with
+ "gz". The gzip format is different from the zlib format. gzip is a gzip
+ wrapper, documented in RFC 1952, wrapped around a deflate stream.
+*/
+
+typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */
+
+/*
+ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
+
+ Opens a gzip (.gz) file for reading or writing. The mode parameter is as
+ in fopen ("rb" or "wb") but can also include a compression level ("wb9") or
+ a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only
+ compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F'
+ for fixed code compression as in "wb9F". (See the description of
+ deflateInit2 for more information about the strategy parameter.) 'T' will
+ request transparent writing or appending with no compression and not using
+ the gzip format.
+
+ "a" can be used instead of "w" to request that the gzip stream that will
+ be written be appended to the file. "+" will result in an error, since
+ reading and writing to the same gzip file is not supported. The addition of
+ "x" when writing will create the file exclusively, which fails if the file
+ already exists. On systems that support it, the addition of "e" when
+ reading or writing will set the flag to close the file on an execve() call.
+
+ These functions, as well as gzip, will read and decode a sequence of gzip
+ streams in a file. The append function of gzopen() can be used to create
+ such a file. (Also see gzflush() for another way to do this.) When
+ appending, gzopen does not test whether the file begins with a gzip stream,
+ nor does it look for the end of the gzip streams to begin appending. gzopen
+ will simply append a gzip stream to the existing file.
+
+ gzopen can be used to read a file which is not in gzip format; in this
+ case gzread will directly read from the file without decompression. When
+ reading, this will be detected automatically by looking for the magic two-
+ byte gzip header.
+
+ gzopen returns NULL if the file could not be opened, if there was
+ insufficient memory to allocate the gzFile state, or if an invalid mode was
+ specified (an 'r', 'w', or 'a' was not provided, or '+' was provided).
+ errno can be checked to determine if the reason gzopen failed was that the
+ file could not be opened.
+*/
+
+ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
+/*
+ gzdopen associates a gzFile with the file descriptor fd. File descriptors
+ are obtained from calls like open, dup, creat, pipe or fileno (if the file
+ has been previously opened with fopen). The mode parameter is as in gzopen.
+
+ The next call of gzclose on the returned gzFile will also close the file
+ descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor
+ fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd,
+ mode);. The duplicated descriptor should be saved to avoid a leak, since
+ gzdopen does not close fd if it fails. If you are using fileno() to get the
+ file descriptor from a FILE *, then you will have to use dup() to avoid
+ double-close()ing the file descriptor. Both gzclose() and fclose() will
+ close the associated file descriptor, so they need to have different file
+ descriptors.
+
+ gzdopen returns NULL if there was insufficient memory to allocate the
+ gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not
+ provided, or '+' was provided), or if fd is -1. The file descriptor is not
+ used until the next gz* read, write, seek, or close operation, so gzdopen
+ will not detect if fd is invalid (unless fd is -1).
+*/
+
+ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size));
+/*
+ Set the internal buffer size used by this library's functions. The
+ default buffer size is 8192 bytes. This function must be called after
+ gzopen() or gzdopen(), and before any other calls that read or write the
+ file. The buffer memory allocation is always deferred to the first read or
+ write. Two buffers are allocated, either both of the specified size when
+ writing, or one of the specified size and the other twice that size when
+ reading. A larger buffer size of, for example, 64K or 128K bytes will
+ noticeably increase the speed of decompression (reading).
+
+ The new buffer size also affects the maximum length for gzprintf().
+
+ gzbuffer() returns 0 on success, or -1 on failure, such as being called
+ too late.
+*/
+
+ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
+/*
+ Dynamically update the compression level or strategy. See the description
+ of deflateInit2 for the meaning of these parameters.
+
+ gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
+ opened for writing.
+*/
+
+ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
+/*
+ Reads the given number of uncompressed bytes from the compressed file. If
+ the input file is not in gzip format, gzread copies the given number of
+ bytes into the buffer directly from the file.
+
+ After reaching the end of a gzip stream in the input, gzread will continue
+ to read, looking for another gzip stream. Any number of gzip streams may be
+ concatenated in the input file, and will all be decompressed by gzread().
+ If something other than a gzip stream is encountered after a gzip stream,
+ that remaining trailing garbage is ignored (and no error is returned).
+
+ gzread can be used to read a gzip file that is being concurrently written.
+ Upon reaching the end of the input, gzread will return with the available
+ data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then
+ gzclearerr can be used to clear the end of file indicator in order to permit
+ gzread to be tried again. Z_OK indicates that a gzip stream was completed
+ on the last gzread. Z_BUF_ERROR indicates that the input file ended in the
+ middle of a gzip stream. Note that gzread does not return -1 in the event
+ of an incomplete gzip stream. This error is deferred until gzclose(), which
+ will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip
+ stream. Alternatively, gzerror can be used before gzclose to detect this
+ case.
+
+ gzread returns the number of uncompressed bytes actually read, less than
+ len for end of file, or -1 for error.
+*/
+
+ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
+ voidpc buf, unsigned len));
+/*
+ Writes the given number of uncompressed bytes into the compressed file.
+ gzwrite returns the number of uncompressed bytes written or 0 in case of
+ error.
+*/
+
+ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...));
+/*
+ Converts, formats, and writes the arguments to the compressed file under
+ control of the format string, as in fprintf. gzprintf returns the number of
+ uncompressed bytes actually written, or 0 in case of error. The number of
+ uncompressed bytes written is limited to 8191, or one less than the buffer
+ size given to gzbuffer(). The caller should assure that this limit is not
+ exceeded. If it is exceeded, then gzprintf() will return an error (0) with
+ nothing written. In this case, there may also be a buffer overflow with
+ unpredictable consequences, which is possible only if zlib was compiled with
+ the insecure functions sprintf() or vsprintf() because the secure snprintf()
+ or vsnprintf() functions were not available. This can be determined using
+ zlibCompileFlags().
+*/
+
+ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
+/*
+ Writes the given null-terminated string to the compressed file, excluding
+ the terminating null character.
+
+ gzputs returns the number of characters written, or -1 in case of error.
+*/
+
+ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
+/*
+ Reads bytes from the compressed file until len-1 characters are read, or a
+ newline character is read and transferred to buf, or an end-of-file
+ condition is encountered. If any characters are read or if len == 1, the
+ string is terminated with a null character. If no characters are read due
+ to an end-of-file or len < 1, then the buffer is left untouched.
+
+ gzgets returns buf which is a null-terminated string, or it returns NULL
+ for end-of-file or in case of error. If there was an error, the contents at
+ buf are indeterminate.
+*/
+
+ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
+/*
+ Writes c, converted to an unsigned char, into the compressed file. gzputc
+ returns the value that was written, or -1 in case of error.
+*/
+
+ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
+/*
+ Reads one byte from the compressed file. gzgetc returns this byte or -1
+ in case of end of file or error. This is implemented as a macro for speed.
+ As such, it does not do all of the checking the other functions do. I.e.
+ it does not check to see if file is NULL, nor whether the structure file
+ points to has been clobbered or not.
+*/
+
+ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
+/*
+ Push one character back onto the stream to be read as the first character
+ on the next read. At least one character of push-back is allowed.
+ gzungetc() returns the character pushed, or -1 on failure. gzungetc() will
+ fail if c is -1, and may fail if a character has been pushed but not read
+ yet. If gzungetc is used immediately after gzopen or gzdopen, at least the
+ output buffer size of pushed characters is allowed. (See gzbuffer above.)
+ The pushed character will be discarded if the stream is repositioned with
+ gzseek() or gzrewind().
+*/
+
+ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
+/*
+ Flushes all pending output into the compressed file. The parameter flush
+ is as in the deflate() function. The return value is the zlib error number
+ (see function gzerror below). gzflush is only permitted when writing.
+
+ If the flush parameter is Z_FINISH, the remaining data is written and the
+ gzip stream is completed in the output. If gzwrite() is called again, a new
+ gzip stream will be started in the output. gzread() is able to read such
+ concatented gzip streams.
+
+ gzflush should be called only when strictly necessary because it will
+ degrade compression if called too often.
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
+ z_off_t offset, int whence));
+
+ Sets the starting position for the next gzread or gzwrite on the given
+ compressed file. The offset represents a number of bytes in the
+ uncompressed data stream. The whence parameter is defined as in lseek(2);
+ the value SEEK_END is not supported.
+
+ If the file is opened for reading, this function is emulated but can be
+ extremely slow. If the file is opened for writing, only forward seeks are
+ supported; gzseek then compresses a sequence of zeroes up to the new
+ starting position.
+
+ gzseek returns the resulting offset location as measured in bytes from
+ the beginning of the uncompressed stream, or -1 in case of error, in
+ particular if the file is opened for writing and the new starting position
+ would be before the current position.
+*/
+
+ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
+/*
+ Rewinds the given file. This function is supported only for reading.
+
+ gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
+
+ Returns the starting position for the next gzread or gzwrite on the given
+ compressed file. This position represents a number of bytes in the
+ uncompressed data stream, and is zero when starting, even if appending or
+ reading a gzip stream from the middle of a file using gzdopen().
+
+ gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file));
+
+ Returns the current offset in the file being read or written. This offset
+ includes the count of bytes that precede the gzip stream, for example when
+ appending or when using gzdopen() for reading. When reading, the offset
+ does not include as yet unused buffered input. This information can be used
+ for a progress indicator. On error, gzoffset() returns -1.
+*/
+
+ZEXTERN int ZEXPORT gzeof OF((gzFile file));
+/*
+ Returns true (1) if the end-of-file indicator has been set while reading,
+ false (0) otherwise. Note that the end-of-file indicator is set only if the
+ read tried to go past the end of the input, but came up short. Therefore,
+ just like feof(), gzeof() may return false even if there is no more data to
+ read, in the event that the last read request was for the exact number of
+ bytes remaining in the input file. This will happen if the input file size
+ is an exact multiple of the buffer size.
+
+ If gzeof() returns true, then the read functions will return no more data,
+ unless the end-of-file indicator is reset by gzclearerr() and the input file
+ has grown since the previous end of file was detected.
+*/
+
+ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
+/*
+ Returns true (1) if file is being copied directly while reading, or false
+ (0) if file is a gzip stream being decompressed.
+
+ If the input file is empty, gzdirect() will return true, since the input
+ does not contain a gzip stream.
+
+ If gzdirect() is used immediately after gzopen() or gzdopen() it will
+ cause buffers to be allocated to allow reading the file to determine if it
+ is a gzip file. Therefore if gzbuffer() is used, it should be called before
+ gzdirect().
+
+ When writing, gzdirect() returns true (1) if transparent writing was
+ requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note:
+ gzdirect() is not needed when writing. Transparent writing must be
+ explicitly requested, so the application already knows the answer. When
+ linking statically, using gzdirect() will include all of the zlib code for
+ gzip file reading and decompression, which may not be desired.)
+*/
+
+ZEXTERN int ZEXPORT gzclose OF((gzFile file));
+/*
+ Flushes all pending output if necessary, closes the compressed file and
+ deallocates the (de)compression state. Note that once file is closed, you
+ cannot call gzerror with file, since its structures have been deallocated.
+ gzclose must not be called more than once on the same file, just as free
+ must not be called more than once on the same allocation.
+
+ gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a
+ file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the
+ last read ended in the middle of a gzip stream, or Z_OK on success.
+*/
+
+ZEXTERN int ZEXPORT gzclose_r OF((gzFile file));
+ZEXTERN int ZEXPORT gzclose_w OF((gzFile file));
+/*
+ Same as gzclose(), but gzclose_r() is only for use when reading, and
+ gzclose_w() is only for use when writing or appending. The advantage to
+ using these instead of gzclose() is that they avoid linking in zlib
+ compression or decompression code that is not used when only reading or only
+ writing respectively. If gzclose() is used, then both compression and
+ decompression code will be included the application when linking to a static
+ zlib library.
+*/
+
+ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
+/*
+ Returns the error message for the last error which occurred on the given
+ compressed file. errnum is set to zlib error number. If an error occurred
+ in the file system and not in the compression library, errnum is set to
+ Z_ERRNO and the application may consult errno to get the exact error code.
+
+ The application must not modify the returned string. Future calls to
+ this function may invalidate the previously returned string. If file is
+ closed, then the string previously returned by gzerror will no longer be
+ available.
+
+ gzerror() should be used to distinguish errors from end-of-file for those
+ functions above that do not distinguish those cases in their return values.
+*/
+
+ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
+/*
+ Clears the error and end-of-file flags for file. This is analogous to the
+ clearerr() function in stdio. This is useful for continuing to read a gzip
+ file that is being written concurrently.
+*/
+
+#endif /* !Z_SOLO */
+
+ /* checksum functions */
+
+/*
+ These functions are not related to compression but are exported
+ anyway because they might be useful in applications using the compression
+ library.
+*/
+
+ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
+/*
+ Update a running Adler-32 checksum with the bytes buf[0..len-1] and
+ return the updated checksum. If buf is Z_NULL, this function returns the
+ required initial value for the checksum.
+
+ An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
+ much faster.
+
+ Usage example:
+
+ uLong adler = adler32(0L, Z_NULL, 0);
+
+ while (read_buffer(buffer, length) != EOF) {
+ adler = adler32(adler, buffer, length);
+ }
+ if (adler != original_adler) error();
+*/
+
+/*
+ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
+ z_off_t len2));
+
+ Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
+ and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
+ each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
+ seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note
+ that the z_off_t type (like off_t) is a signed integer. If len2 is
+ negative, the result has no meaning or utility.
+*/
+
+ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
+/*
+ Update a running CRC-32 with the bytes buf[0..len-1] and return the
+ updated CRC-32. If buf is Z_NULL, this function returns the required
+ initial value for the crc. Pre- and post-conditioning (one's complement) is
+ performed within this function so it shouldn't be done by the application.
+
+ Usage example:
+
+ uLong crc = crc32(0L, Z_NULL, 0);
+
+ while (read_buffer(buffer, length) != EOF) {
+ crc = crc32(crc, buffer, length);
+ }
+ if (crc != original_crc) error();
+*/
+
+/*
+ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
+
+ Combine two CRC-32 check values into one. For two sequences of bytes,
+ seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
+ calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32
+ check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
+ len2.
+*/
+
+
+ /* various hacks, don't look :) */
+
+/* deflateInit and inflateInit are macros to allow checking the zlib version
+ * and the compiler's view of z_stream:
+ */
+ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
+ int windowBits, int memLevel,
+ int strategy, const char *version,
+ int stream_size));
+ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
+ unsigned char FAR *window,
+ const char *version,
+ int stream_size));
+#define deflateInit(strm, level) \
+ deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream))
+#define inflateInit(strm) \
+ inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream))
+#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
+ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
+ (strategy), ZLIB_VERSION, (int)sizeof(z_stream))
+#define inflateInit2(strm, windowBits) \
+ inflateInit2_((strm), (windowBits), ZLIB_VERSION, \
+ (int)sizeof(z_stream))
+#define inflateBackInit(strm, windowBits, window) \
+ inflateBackInit_((strm), (windowBits), (window), \
+ ZLIB_VERSION, (int)sizeof(z_stream))
+
+#ifndef Z_SOLO
+
+/* gzgetc() macro and its supporting function and exposed data structure. Note
+ * that the real internal state is much larger than the exposed structure.
+ * This abbreviated structure exposes just enough for the gzgetc() macro. The
+ * user should not mess with these exposed elements, since their names or
+ * behavior could change in the future, perhaps even capriciously. They can
+ * only be used by the gzgetc() macro. You have been warned.
+ */
+struct gzFile_s {
+ unsigned have;
+ unsigned char *next;
+ z_off64_t pos;
+};
+ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */
+#ifdef Z_PREFIX_SET
+# undef z_gzgetc
+# define z_gzgetc(g) \
+ ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g))
+#else
+# define gzgetc(g) \
+ ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g))
+#endif
+
+/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or
+ * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if
+ * both are true, the application gets the *64 functions, and the regular
+ * functions are changed to 64 bits) -- in case these are set on systems
+ * without large file support, _LFS64_LARGEFILE must also be true
+ */
+#ifdef Z_LARGE64
+ ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+ ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
+ ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
+ ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
+ ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t));
+ ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t));
+#endif
+
+#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64)
+# ifdef Z_PREFIX_SET
+# define z_gzopen z_gzopen64
+# define z_gzseek z_gzseek64
+# define z_gztell z_gztell64
+# define z_gzoffset z_gzoffset64
+# define z_adler32_combine z_adler32_combine64
+# define z_crc32_combine z_crc32_combine64
+# else
+# define gzopen gzopen64
+# define gzseek gzseek64
+# define gztell gztell64
+# define gzoffset gzoffset64
+# define adler32_combine adler32_combine64
+# define crc32_combine crc32_combine64
+# endif
+# ifndef Z_LARGE64
+ ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+ ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int));
+ ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile));
+ ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile));
+ ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
+# endif
+#else
+ ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *));
+ ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int));
+ ZEXTERN z_off_t ZEXPORT gztell OF((gzFile));
+ ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile));
+ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
+#endif
+
+#else /* Z_SOLO */
+
+ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
+
+#endif /* !Z_SOLO */
+
+/* hack for buggy compilers */
+#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
+ struct internal_state {int dummy;};
+#endif
+
+/* undocumented functions */
+ZEXTERN const char * ZEXPORT zError OF((int));
+ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp));
+ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void));
+ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int));
+ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp));
+ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp));
+#if defined(_WIN32) && !defined(Z_SOLO)
+ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path,
+ const char *mode));
+#endif
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+# ifndef Z_SOLO
+ZEXTERN int ZEXPORTVA gzvprintf Z_ARG((gzFile file,
+ const char *format,
+ va_list va));
+# endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ZLIB_H */
diff --git a/frontend/vita/retro_inline.h b/frontend/vita/retro_inline.h
new file mode 100644
index 0000000..8535d84
--- /dev/null
+++ b/frontend/vita/retro_inline.h
@@ -0,0 +1,39 @@
+/* Copyright (C) 2010-2015 The RetroArch team
+ *
+ * ---------------------------------------------------------------------------------------
+ * The following license statement only applies to this file (retro_inline.h).
+ * ---------------------------------------------------------------------------------------
+ *
+ * Permission is hereby granted, free of charge,
+ * to any person obtaining a copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __LIBRETRO_SDK_INLINE_H
+#define __LIBRETRO_SDK_INLINE_H
+
+#ifndef INLINE
+
+#if !defined(__cplusplus) && defined(_WIN32)
+#define INLINE _inline
+#elif defined(__STDC_VERSION__) && __STDC_VERSION__>=199901L
+#define INLINE inline
+#elif defined(__GNUC__)
+#define INLINE __inline__
+#else
+#define INLINE
+#endif
+
+#endif
+#endif
diff --git a/frontend/vita/sys/mman.h b/frontend/vita/sys/mman.h
new file mode 100644
index 0000000..89da513
--- /dev/null
+++ b/frontend/vita/sys/mman.h
@@ -0,0 +1,69 @@
+#ifndef MMAN_H
+#define MMAN_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "stdlib.h"
+#include "stdio.h"
+
+#define PROT_READ 0b001
+#define PROT_WRITE 0b010
+#define PROT_EXEC 0b100
+#define MAP_PRIVATE 2
+#define MAP_ANONYMOUS 0x20
+
+#define MAP_FAILED ((void *)-1)
+
+static inline void* mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset)
+{
+ (void)prot;
+ (void)flags;
+ (void)fd;
+ (void)offset;
+
+ int block, ret;
+
+ block = sceKernelAllocMemBlockForVM("code", len);
+ if(block<=0){
+ sceClibPrintf("could not alloc mem block @0x%08X 0x%08X \n", block, len);
+ exit(1);
+ }
+
+ // get base address
+ ret = sceKernelGetMemBlockBase(block, &addr);
+ if (ret < 0)
+ {
+ sceClibPrintf("could get address @0x%08X 0x%08X \n", block, addr);
+ exit(1);
+ }
+
+
+ if(!addr)
+ return MAP_FAILED;
+
+ return addr;
+}
+
+static inline int mprotect(void *addr, size_t len, int prot)
+{
+ (void)addr;
+ (void)len;
+ (void)prot;
+ return 0;
+}
+
+static inline int munmap(void *addr, size_t len)
+{
+ int uid = sceKernelFindMemBlockByAddr(addr, len);
+
+ return sceKernelFreeMemBlock(uid);
+
+}
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif // MMAN_H
diff --git a/frontend/warm b/frontend/warm
deleted file mode 160000
-Subproject a6f015da3b10b82a476250793645c071340decb