remove a bunch of eol-style properties
This commit is contained in:
parent
6724231a2d
commit
655dd15cc1
|
@ -1,31 +1,31 @@
|
|||
/*
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2006-2009 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DISASSEMBLER_H
|
||||
#define DISASSEMBLER_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
typedef char* (* DisasmOpFunc)(u32 adr, u32 i, char * txt);
|
||||
|
||||
extern const DisasmOpFunc des_arm_instructions_set[4096];
|
||||
extern const DisasmOpFunc des_thumb_instructions_set[1024];
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2006-2009 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DISASSEMBLER_H
|
||||
#define DISASSEMBLER_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
typedef char* (* DisasmOpFunc)(u32 adr, u32 i, char * txt);
|
||||
|
||||
extern const DisasmOpFunc des_arm_instructions_set[4096];
|
||||
extern const DisasmOpFunc des_thumb_instructions_set[1024];
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -1,92 +1,92 @@
|
|||
/*
|
||||
Copyright 2006 yopyop
|
||||
Copyright 2007 shash
|
||||
Copyright 2007-2011 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef FIFO_H
|
||||
#define FIFO_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
//=================================================== IPC FIFO
|
||||
typedef struct
|
||||
{
|
||||
u32 buf[16];
|
||||
|
||||
u8 head;
|
||||
u8 tail;
|
||||
u8 size;
|
||||
} IPC_FIFO;
|
||||
|
||||
extern IPC_FIFO ipc_fifo[2];
|
||||
extern void IPC_FIFOinit(u8 proc);
|
||||
extern void IPC_FIFOsend(u8 proc, u32 val);
|
||||
extern u32 IPC_FIFOrecv(u8 proc);
|
||||
extern void IPC_FIFOcnt(u8 proc, u16 val);
|
||||
|
||||
//=================================================== GFX FIFO
|
||||
|
||||
//yeah, its oversize for now. thats a simpler solution
|
||||
//moon seems to overdrive the fifo with immediate dmas
|
||||
//i think this might be nintendo code too
|
||||
#define HACK_GXIFO_SIZE 200000
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 cmd[HACK_GXIFO_SIZE];
|
||||
u32 param[HACK_GXIFO_SIZE];
|
||||
|
||||
u32 head; // start position
|
||||
u32 tail; // tail
|
||||
u32 size; // size FIFO buffer
|
||||
u32 matrix_stack_op_size; //number of matrix stack items in the fifo (stack is busy when this is nonzero)
|
||||
} GFX_FIFO;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 cmd[4];
|
||||
u32 param[4];
|
||||
|
||||
u8 head;
|
||||
u8 tail;
|
||||
u8 size;
|
||||
} GFX_PIPE;
|
||||
|
||||
extern GFX_PIPE gxPIPE;
|
||||
extern GFX_FIFO gxFIFO;
|
||||
void GFX_PIPEclear();
|
||||
void GFX_FIFOclear();
|
||||
void GFX_FIFOsend(u8 cmd, u32 param);
|
||||
BOOL GFX_PIPErecv(u8 *cmd, u32 *param);
|
||||
void GFX_FIFOcnt(u32 val);
|
||||
|
||||
//=================================================== Display memory FIFO
|
||||
typedef struct
|
||||
{
|
||||
u32 buf[0x6000]; // 256x192 32K color
|
||||
u32 head; // head
|
||||
u32 tail; // tail
|
||||
} DISP_FIFO;
|
||||
|
||||
extern DISP_FIFO disp_fifo;
|
||||
void DISP_FIFOinit();
|
||||
void DISP_FIFOsend(u32 val);
|
||||
u32 DISP_FIFOrecv();
|
||||
void DISP_FIFOreset();
|
||||
|
||||
#endif
|
||||
/*
|
||||
Copyright 2006 yopyop
|
||||
Copyright 2007 shash
|
||||
Copyright 2007-2011 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef FIFO_H
|
||||
#define FIFO_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
//=================================================== IPC FIFO
|
||||
typedef struct
|
||||
{
|
||||
u32 buf[16];
|
||||
|
||||
u8 head;
|
||||
u8 tail;
|
||||
u8 size;
|
||||
} IPC_FIFO;
|
||||
|
||||
extern IPC_FIFO ipc_fifo[2];
|
||||
extern void IPC_FIFOinit(u8 proc);
|
||||
extern void IPC_FIFOsend(u8 proc, u32 val);
|
||||
extern u32 IPC_FIFOrecv(u8 proc);
|
||||
extern void IPC_FIFOcnt(u8 proc, u16 val);
|
||||
|
||||
//=================================================== GFX FIFO
|
||||
|
||||
//yeah, its oversize for now. thats a simpler solution
|
||||
//moon seems to overdrive the fifo with immediate dmas
|
||||
//i think this might be nintendo code too
|
||||
#define HACK_GXIFO_SIZE 200000
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 cmd[HACK_GXIFO_SIZE];
|
||||
u32 param[HACK_GXIFO_SIZE];
|
||||
|
||||
u32 head; // start position
|
||||
u32 tail; // tail
|
||||
u32 size; // size FIFO buffer
|
||||
u32 matrix_stack_op_size; //number of matrix stack items in the fifo (stack is busy when this is nonzero)
|
||||
} GFX_FIFO;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 cmd[4];
|
||||
u32 param[4];
|
||||
|
||||
u8 head;
|
||||
u8 tail;
|
||||
u8 size;
|
||||
} GFX_PIPE;
|
||||
|
||||
extern GFX_PIPE gxPIPE;
|
||||
extern GFX_FIFO gxFIFO;
|
||||
void GFX_PIPEclear();
|
||||
void GFX_FIFOclear();
|
||||
void GFX_FIFOsend(u8 cmd, u32 param);
|
||||
BOOL GFX_PIPErecv(u8 *cmd, u32 *param);
|
||||
void GFX_FIFOcnt(u32 val);
|
||||
|
||||
//=================================================== Display memory FIFO
|
||||
typedef struct
|
||||
{
|
||||
u32 buf[0x6000]; // 256x192 32K color
|
||||
u32 head; // head
|
||||
u32 tail; // tail
|
||||
} DISP_FIFO;
|
||||
|
||||
extern DISP_FIFO disp_fifo;
|
||||
void DISP_FIFOinit();
|
||||
void DISP_FIFOsend(u32 val);
|
||||
u32 DISP_FIFOrecv();
|
||||
void DISP_FIFOreset();
|
||||
|
||||
#endif
|
||||
|
|
3262
desmume/src/GPU.h
3262
desmume/src/GPU.h
File diff suppressed because it is too large
Load Diff
|
@ -1,143 +1,143 @@
|
|||
/*
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2008-2012 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GPU_OSD_
|
||||
#define __GPU_OSD_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#ifdef HAVE_LIBAGG
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "aggdraw.h"
|
||||
|
||||
#define OSD_MAX_LINES 4
|
||||
#define OSD_TIMER_SECS 2
|
||||
|
||||
|
||||
struct HudCoordinates{
|
||||
int x;
|
||||
int y;
|
||||
int xsize;
|
||||
int ysize;
|
||||
int storedx;
|
||||
int storedy;
|
||||
int clicked;
|
||||
};
|
||||
|
||||
struct HudStruct
|
||||
{
|
||||
public:
|
||||
HudStruct()
|
||||
{
|
||||
resetTransient();
|
||||
}
|
||||
|
||||
void resetTransient()
|
||||
{
|
||||
fps = 0;
|
||||
fps3d = 0;
|
||||
cpuload[0] = cpuload[1] = 0;
|
||||
cpuloopIterationCount = 0;
|
||||
memset(rtcString, 0, sizeof(rtcString));
|
||||
clicked = false;
|
||||
}
|
||||
|
||||
HudCoordinates SavestateSlots;
|
||||
HudCoordinates FpsDisplay;
|
||||
HudCoordinates FrameCounter;
|
||||
HudCoordinates InputDisplay;
|
||||
HudCoordinates GraphicalInputDisplay;
|
||||
HudCoordinates LagFrameCounter;
|
||||
HudCoordinates Microphone;
|
||||
HudCoordinates RTCDisplay;
|
||||
HudCoordinates Dummy;
|
||||
|
||||
HudCoordinates &hud(int i) { return ((HudCoordinates*)this)[i]; }
|
||||
void reset();
|
||||
|
||||
int fps, fps3d, cpuload[2], cpuloopIterationCount;
|
||||
char rtcString[25];
|
||||
bool clicked;
|
||||
};
|
||||
|
||||
void EditHud(s32 x, s32 y, HudStruct *hudstruct);
|
||||
void HudClickRelease(HudStruct *hudstruct);
|
||||
|
||||
void DrawHUD();
|
||||
|
||||
extern HudStruct Hud;
|
||||
extern bool HudEditorMode;
|
||||
|
||||
class OSDCLASS
|
||||
{
|
||||
private:
|
||||
u64 offset;
|
||||
u8 mode;
|
||||
|
||||
u16 rotAngle;
|
||||
|
||||
u16 lineText_x;
|
||||
u16 lineText_y;
|
||||
AggColor lineText_color;
|
||||
u8 lastLineText;
|
||||
char *lineText[OSD_MAX_LINES+1];
|
||||
time_t lineTimer[OSD_MAX_LINES+1];
|
||||
AggColor lineColor[OSD_MAX_LINES+1];
|
||||
|
||||
bool needUpdate;
|
||||
|
||||
bool checkTimers();
|
||||
|
||||
public:
|
||||
char name[7]; // for debuging
|
||||
bool singleScreen;
|
||||
bool swapScreens;
|
||||
|
||||
OSDCLASS(u8 core);
|
||||
~OSDCLASS();
|
||||
|
||||
void setOffset(u16 ofs);
|
||||
void setRotate(u16 angle);
|
||||
void update();
|
||||
void clear();
|
||||
void setListCoord(u16 x, u16 y);
|
||||
void setLineColor(u8 r, u8 b, u8 g);
|
||||
void addLine(const char *fmt, ...);
|
||||
void addFixed(u16 x, u16 y, const char *fmt, ...);
|
||||
void border(bool enabled);
|
||||
};
|
||||
|
||||
extern OSDCLASS *osd;
|
||||
#else /* HAVE_LIBAGG */
|
||||
void DrawHUD();
|
||||
|
||||
class OSDCLASS {
|
||||
public:
|
||||
OSDCLASS(u8 core);
|
||||
~OSDCLASS();
|
||||
void update();
|
||||
void clear();
|
||||
void setLineColor(u8 r, u8 b, u8 g);
|
||||
void addLine(const char *fmt, ...);
|
||||
};
|
||||
|
||||
extern OSDCLASS *osd;
|
||||
#endif
|
||||
#endif
|
||||
/*
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2008-2012 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GPU_OSD_
|
||||
#define __GPU_OSD_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#ifdef HAVE_LIBAGG
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "aggdraw.h"
|
||||
|
||||
#define OSD_MAX_LINES 4
|
||||
#define OSD_TIMER_SECS 2
|
||||
|
||||
|
||||
struct HudCoordinates{
|
||||
int x;
|
||||
int y;
|
||||
int xsize;
|
||||
int ysize;
|
||||
int storedx;
|
||||
int storedy;
|
||||
int clicked;
|
||||
};
|
||||
|
||||
struct HudStruct
|
||||
{
|
||||
public:
|
||||
HudStruct()
|
||||
{
|
||||
resetTransient();
|
||||
}
|
||||
|
||||
void resetTransient()
|
||||
{
|
||||
fps = 0;
|
||||
fps3d = 0;
|
||||
cpuload[0] = cpuload[1] = 0;
|
||||
cpuloopIterationCount = 0;
|
||||
memset(rtcString, 0, sizeof(rtcString));
|
||||
clicked = false;
|
||||
}
|
||||
|
||||
HudCoordinates SavestateSlots;
|
||||
HudCoordinates FpsDisplay;
|
||||
HudCoordinates FrameCounter;
|
||||
HudCoordinates InputDisplay;
|
||||
HudCoordinates GraphicalInputDisplay;
|
||||
HudCoordinates LagFrameCounter;
|
||||
HudCoordinates Microphone;
|
||||
HudCoordinates RTCDisplay;
|
||||
HudCoordinates Dummy;
|
||||
|
||||
HudCoordinates &hud(int i) { return ((HudCoordinates*)this)[i]; }
|
||||
void reset();
|
||||
|
||||
int fps, fps3d, cpuload[2], cpuloopIterationCount;
|
||||
char rtcString[25];
|
||||
bool clicked;
|
||||
};
|
||||
|
||||
void EditHud(s32 x, s32 y, HudStruct *hudstruct);
|
||||
void HudClickRelease(HudStruct *hudstruct);
|
||||
|
||||
void DrawHUD();
|
||||
|
||||
extern HudStruct Hud;
|
||||
extern bool HudEditorMode;
|
||||
|
||||
class OSDCLASS
|
||||
{
|
||||
private:
|
||||
u64 offset;
|
||||
u8 mode;
|
||||
|
||||
u16 rotAngle;
|
||||
|
||||
u16 lineText_x;
|
||||
u16 lineText_y;
|
||||
AggColor lineText_color;
|
||||
u8 lastLineText;
|
||||
char *lineText[OSD_MAX_LINES+1];
|
||||
time_t lineTimer[OSD_MAX_LINES+1];
|
||||
AggColor lineColor[OSD_MAX_LINES+1];
|
||||
|
||||
bool needUpdate;
|
||||
|
||||
bool checkTimers();
|
||||
|
||||
public:
|
||||
char name[7]; // for debuging
|
||||
bool singleScreen;
|
||||
bool swapScreens;
|
||||
|
||||
OSDCLASS(u8 core);
|
||||
~OSDCLASS();
|
||||
|
||||
void setOffset(u16 ofs);
|
||||
void setRotate(u16 angle);
|
||||
void update();
|
||||
void clear();
|
||||
void setListCoord(u16 x, u16 y);
|
||||
void setLineColor(u8 r, u8 b, u8 g);
|
||||
void addLine(const char *fmt, ...);
|
||||
void addFixed(u16 x, u16 y, const char *fmt, ...);
|
||||
void border(bool enabled);
|
||||
};
|
||||
|
||||
extern OSDCLASS *osd;
|
||||
#else /* HAVE_LIBAGG */
|
||||
void DrawHUD();
|
||||
|
||||
class OSDCLASS {
|
||||
public:
|
||||
OSDCLASS(u8 core);
|
||||
~OSDCLASS();
|
||||
void update();
|
||||
void clear();
|
||||
void setLineColor(u8 r, u8 b, u8 g);
|
||||
void addLine(const char *fmt, ...);
|
||||
};
|
||||
|
||||
extern OSDCLASS *osd;
|
||||
#endif
|
||||
#endif
|
||||
|
|
2002
desmume/src/MMU.h
2002
desmume/src/MMU.h
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,12 +1,12 @@
|
|||
#ifndef __GNUC__
|
||||
#pragma pack(push, 1)
|
||||
#pragma warning(disable : 4103)
|
||||
#endif
|
||||
|
||||
#ifndef __PACKED
|
||||
#ifdef __GNUC__
|
||||
#define __PACKED __attribute__((__packed__))
|
||||
#else
|
||||
#define __PACKED
|
||||
#endif
|
||||
#endif
|
||||
#ifndef __GNUC__
|
||||
#pragma pack(push, 1)
|
||||
#pragma warning(disable : 4103)
|
||||
#endif
|
||||
|
||||
#ifndef __PACKED
|
||||
#ifdef __GNUC__
|
||||
#define __PACKED __attribute__((__packed__))
|
||||
#else
|
||||
#define __PACKED
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
#ifndef __GNUC__
|
||||
#pragma pack(pop)
|
||||
#endif
|
||||
#ifndef __GNUC__
|
||||
#pragma pack(pop)
|
||||
#endif
|
||||
|
|
|
@ -1,50 +1,50 @@
|
|||
/*
|
||||
Copyright (C) 2007 Guillaume Duhamel
|
||||
Copyright (C) 2007 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_LIBZ
|
||||
#include <zlib.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define ROMREADER_DEFAULT -1
|
||||
#define ROMREADER_STD 0
|
||||
#define ROMREADER_GZIP 1
|
||||
#define ROMREADER_ZIP 2
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int id;
|
||||
const char * Name;
|
||||
void * (*Init)(const char * filename);
|
||||
void (*DeInit)(void * file);
|
||||
u32 (*Size)(void * file);
|
||||
int (*Seek)(void * file, int offset, int whence);
|
||||
int (*Read)(void * file, void * buffer, u32 size);
|
||||
} ROMReader_struct;
|
||||
|
||||
extern ROMReader_struct STDROMReader;
|
||||
#ifdef HAVE_LIBZ
|
||||
extern ROMReader_struct GZIPROMReader;
|
||||
#endif
|
||||
#ifdef HAVE_LIBZZIP
|
||||
extern ROMReader_struct ZIPROMReader;
|
||||
#endif
|
||||
|
||||
ROMReader_struct * ROMReaderInit(char ** filename);
|
||||
/*
|
||||
Copyright (C) 2007 Guillaume Duhamel
|
||||
Copyright (C) 2007 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_LIBZ
|
||||
#include <zlib.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define ROMREADER_DEFAULT -1
|
||||
#define ROMREADER_STD 0
|
||||
#define ROMREADER_GZIP 1
|
||||
#define ROMREADER_ZIP 2
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int id;
|
||||
const char * Name;
|
||||
void * (*Init)(const char * filename);
|
||||
void (*DeInit)(void * file);
|
||||
u32 (*Size)(void * file);
|
||||
int (*Seek)(void * file, int offset, int whence);
|
||||
int (*Read)(void * file, void * buffer, u32 size);
|
||||
} ROMReader_struct;
|
||||
|
||||
extern ROMReader_struct STDROMReader;
|
||||
#ifdef HAVE_LIBZ
|
||||
extern ROMReader_struct GZIPROMReader;
|
||||
#endif
|
||||
#ifdef HAVE_LIBZZIP
|
||||
extern ROMReader_struct ZIPROMReader;
|
||||
#endif
|
||||
|
||||
ROMReader_struct * ROMReaderInit(char ** filename);
|
||||
|
|
|
@ -1,303 +1,303 @@
|
|||
/*
|
||||
Copyright 2006 Theo Berkau
|
||||
Copyright (C) 2006-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SPU_H
|
||||
#define SPU_H
|
||||
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "matrix.h"
|
||||
#include "metaspu/metaspu.h"
|
||||
|
||||
class EMUFILE;
|
||||
|
||||
#define SNDCORE_DEFAULT -1
|
||||
#define SNDCORE_DUMMY 0
|
||||
|
||||
#define CHANSTAT_STOPPED 0
|
||||
#define CHANSTAT_PLAY 1
|
||||
|
||||
|
||||
//who made these static? theyre used in multiple places.
|
||||
FORCEINLINE u32 sputrunc(float f) { return u32floor(f); }
|
||||
FORCEINLINE u32 sputrunc(double d) { return u32floor(d); }
|
||||
FORCEINLINE s32 spumuldiv7(s32 val, u8 multiplier) {
|
||||
assert(multiplier <= 127);
|
||||
return (multiplier == 127) ? val : ((val * multiplier) >> 7);
|
||||
}
|
||||
|
||||
enum SPUInterpolationMode
|
||||
{
|
||||
SPUInterpolation_None = 0,
|
||||
SPUInterpolation_Linear = 1,
|
||||
SPUInterpolation_Cosine = 2
|
||||
};
|
||||
|
||||
struct SoundInterface_struct
|
||||
{
|
||||
int id;
|
||||
const char *Name;
|
||||
int (*Init)(int buffersize);
|
||||
void (*DeInit)();
|
||||
void (*UpdateAudio)(s16 *buffer, u32 num_samples);
|
||||
u32 (*GetAudioSpace)();
|
||||
void (*MuteAudio)();
|
||||
void (*UnMuteAudio)();
|
||||
void (*SetVolume)(int volume);
|
||||
void (*ClearBuffer)();
|
||||
void (*FetchSamples)(s16 *sampleBuffer, size_t sampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer);
|
||||
size_t (*PostProcessSamples)(s16 *postProcessBuffer, size_t requestedSampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer);
|
||||
};
|
||||
|
||||
extern SoundInterface_struct SNDDummy;
|
||||
extern SoundInterface_struct SNDFile;
|
||||
extern int SPU_currentCoreNum;
|
||||
|
||||
struct channel_struct
|
||||
{
|
||||
channel_struct() : num(0),
|
||||
vol(0),
|
||||
volumeDiv(0),
|
||||
hold(0),
|
||||
pan(0),
|
||||
waveduty(0),
|
||||
repeat(0),
|
||||
format(0),
|
||||
keyon(0),
|
||||
status(0),
|
||||
addr(0),
|
||||
timer(0),
|
||||
loopstart(0),
|
||||
length(0),
|
||||
totlength(0),
|
||||
double_totlength_shifted(0.0),
|
||||
sampcnt(0.0),
|
||||
sampinc(0.0),
|
||||
lastsampcnt(0),
|
||||
pcm16b(0),
|
||||
pcm16b_last(0),
|
||||
loop_pcm16b(0),
|
||||
index(0),
|
||||
loop_index(0),
|
||||
x(0),
|
||||
psgnoise_last(0)
|
||||
{}
|
||||
u32 num;
|
||||
u8 vol;
|
||||
u8 volumeDiv;
|
||||
u8 hold;
|
||||
u8 pan;
|
||||
u8 waveduty;
|
||||
u8 repeat;
|
||||
u8 format;
|
||||
u8 keyon;
|
||||
u8 status;
|
||||
u32 addr;
|
||||
u16 timer;
|
||||
u16 loopstart;
|
||||
u32 length;
|
||||
u32 totlength;
|
||||
double double_totlength_shifted;
|
||||
double sampcnt;
|
||||
double sampinc;
|
||||
// ADPCM specific
|
||||
u32 lastsampcnt;
|
||||
s16 pcm16b, pcm16b_last;
|
||||
s16 loop_pcm16b;
|
||||
int index;
|
||||
int loop_index;
|
||||
u16 x;
|
||||
s16 psgnoise_last;
|
||||
};
|
||||
|
||||
class SPUFifo
|
||||
{
|
||||
public:
|
||||
SPUFifo();
|
||||
void enqueue(s16 val);
|
||||
s16 dequeue();
|
||||
s16 buffer[16];
|
||||
s32 head,tail,size;
|
||||
void save(EMUFILE* fp);
|
||||
bool load(EMUFILE* fp);
|
||||
void reset();
|
||||
};
|
||||
|
||||
class SPU_struct
|
||||
{
|
||||
public:
|
||||
SPU_struct(int buffersize);
|
||||
u32 bufpos;
|
||||
u32 buflength;
|
||||
s32 *sndbuf;
|
||||
s32 lastdata; //the last sample that a channel generated
|
||||
s16 *outbuf;
|
||||
u32 bufsize;
|
||||
channel_struct channels[16];
|
||||
|
||||
//registers
|
||||
struct REGS {
|
||||
REGS()
|
||||
: mastervol(0)
|
||||
, ctl_left(0)
|
||||
, ctl_right(0)
|
||||
, ctl_ch1bypass(0)
|
||||
, ctl_ch3bypass(0)
|
||||
, masteren(0)
|
||||
, soundbias(0)
|
||||
{}
|
||||
|
||||
u8 mastervol;
|
||||
u8 ctl_left, ctl_right;
|
||||
u8 ctl_ch1bypass, ctl_ch3bypass;
|
||||
u8 masteren;
|
||||
u16 soundbias;
|
||||
|
||||
enum LeftOutputMode
|
||||
{
|
||||
LOM_LEFT_MIXER=0, LOM_CH1=1, LOM_CH3=2, LOM_CH1_PLUS_CH3=3
|
||||
};
|
||||
|
||||
enum RightOutputMode
|
||||
{
|
||||
ROM_RIGHT_MIXER=0, ROM_CH1=1, ROM_CH3=2, ROM_CH1_PLUS_CH3=3
|
||||
};
|
||||
|
||||
struct CAP {
|
||||
CAP()
|
||||
: add(0), source(0), oneshot(0), bits8(0), active(0), dad(0), len(0)
|
||||
{}
|
||||
u8 add, source, oneshot, bits8, active;
|
||||
u32 dad;
|
||||
u16 len;
|
||||
struct Runtime {
|
||||
Runtime()
|
||||
: running(0), curdad(0), maxdad(0)
|
||||
{}
|
||||
u8 running;
|
||||
u32 curdad;
|
||||
u32 maxdad;
|
||||
double sampcnt;
|
||||
SPUFifo fifo;
|
||||
} runtime;
|
||||
} cap[2];
|
||||
} regs;
|
||||
|
||||
void reset();
|
||||
~SPU_struct();
|
||||
void KeyOff(int channel);
|
||||
void KeyOn(int channel);
|
||||
void KeyProbe(int channel);
|
||||
void ProbeCapture(int which);
|
||||
void WriteByte(u32 addr, u8 val);
|
||||
void WriteWord(u32 addr, u16 val);
|
||||
void WriteLong(u32 addr, u32 val);
|
||||
u8 ReadByte(u32 addr);
|
||||
u16 ReadWord(u32 addr);
|
||||
u32 ReadLong(u32 addr);
|
||||
bool isSPU(u32 addr) { return ((addr >= 0x04000400) && (addr < 0x04000520)); }
|
||||
|
||||
//kills all channels but leaves SPU otherwise running normally
|
||||
void ShutUp();
|
||||
};
|
||||
|
||||
extern SPU_struct *SPU_core, *SPU_user;
|
||||
extern int spu_core_samples;
|
||||
|
||||
int SPU_ChangeSoundCore(int coreid, int buffersize);
|
||||
SoundInterface_struct *SPU_SoundCore();
|
||||
|
||||
void SPU_ReInit(bool fakeBoot = false);
|
||||
int SPU_Init(int coreid, int buffersize);
|
||||
void SPU_Pause(int pause);
|
||||
void SPU_SetVolume(int volume);
|
||||
void SPU_SetSynchMode(int mode, int method);
|
||||
void SPU_ClearOutputBuffer(void);
|
||||
void SPU_Reset(void);
|
||||
void SPU_DeInit(void);
|
||||
void SPU_KeyOn(int channel);
|
||||
static FORCEINLINE void SPU_WriteByte(u32 addr, u8 val)
|
||||
{
|
||||
addr &= 0xFFF;
|
||||
|
||||
SPU_core->WriteByte(addr,val);
|
||||
if(SPU_user)
|
||||
SPU_user->WriteByte(addr,val);
|
||||
}
|
||||
static FORCEINLINE void SPU_WriteWord(u32 addr, u16 val)
|
||||
{
|
||||
addr &= 0xFFF;
|
||||
|
||||
SPU_core->WriteWord(addr,val);
|
||||
if(SPU_user)
|
||||
SPU_user->WriteWord(addr,val);
|
||||
}
|
||||
static FORCEINLINE void SPU_WriteLong(u32 addr, u32 val)
|
||||
{
|
||||
addr &= 0xFFF;
|
||||
|
||||
SPU_core->WriteLong(addr,val);
|
||||
if(SPU_user)
|
||||
SPU_user->WriteLong(addr,val);
|
||||
}
|
||||
static FORCEINLINE u8 SPU_ReadByte(u32 addr) { return SPU_core->ReadByte(addr & 0x0FFF); }
|
||||
static FORCEINLINE u16 SPU_ReadWord(u32 addr) { return SPU_core->ReadWord(addr & 0x0FFF); }
|
||||
static FORCEINLINE u32 SPU_ReadLong(u32 addr) { return SPU_core->ReadLong(addr & 0x0FFF); }
|
||||
void SPU_Emulate_core(void);
|
||||
void SPU_Emulate_user(bool mix = true);
|
||||
void SPU_DefaultFetchSamples(s16 *sampleBuffer, size_t sampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer);
|
||||
size_t SPU_DefaultPostProcessSamples(s16 *postProcessBuffer, size_t requestedSampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer);
|
||||
|
||||
void spu_savestate(EMUFILE* os);
|
||||
bool spu_loadstate(EMUFILE* is, int size);
|
||||
|
||||
enum WAVMode
|
||||
{
|
||||
WAVMODE_ANY = -1,
|
||||
WAVMODE_CORE = 0,
|
||||
WAVMODE_USER = 1
|
||||
};
|
||||
|
||||
class WavWriter
|
||||
{
|
||||
public:
|
||||
WavWriter();
|
||||
bool open(const std::string & fname);
|
||||
void close();
|
||||
void update(void* soundData, int numSamples);
|
||||
bool isRecording() const;
|
||||
WAVMode mode;
|
||||
private:
|
||||
FILE *spufp;
|
||||
};
|
||||
|
||||
void WAV_End();
|
||||
bool WAV_Begin(const char* fname, WAVMode mode=WAVMODE_CORE);
|
||||
bool WAV_IsRecording(WAVMode mode=WAVMODE_ANY);
|
||||
void WAV_WavSoundUpdate(void* soundData, int numSamples, WAVMode mode=WAVMODE_CORE);
|
||||
|
||||
// we should make this configurable eventually
|
||||
// but at least defining it somewhere is probably a step in the right direction
|
||||
#define DESMUME_SAMPLE_RATE 44100
|
||||
//#define DESMUME_SAMPLE_RATE 48000
|
||||
|
||||
#endif
|
||||
/*
|
||||
Copyright 2006 Theo Berkau
|
||||
Copyright (C) 2006-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SPU_H
|
||||
#define SPU_H
|
||||
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "matrix.h"
|
||||
#include "metaspu/metaspu.h"
|
||||
|
||||
class EMUFILE;
|
||||
|
||||
#define SNDCORE_DEFAULT -1
|
||||
#define SNDCORE_DUMMY 0
|
||||
|
||||
#define CHANSTAT_STOPPED 0
|
||||
#define CHANSTAT_PLAY 1
|
||||
|
||||
|
||||
//who made these static? theyre used in multiple places.
|
||||
FORCEINLINE u32 sputrunc(float f) { return u32floor(f); }
|
||||
FORCEINLINE u32 sputrunc(double d) { return u32floor(d); }
|
||||
FORCEINLINE s32 spumuldiv7(s32 val, u8 multiplier) {
|
||||
assert(multiplier <= 127);
|
||||
return (multiplier == 127) ? val : ((val * multiplier) >> 7);
|
||||
}
|
||||
|
||||
enum SPUInterpolationMode
|
||||
{
|
||||
SPUInterpolation_None = 0,
|
||||
SPUInterpolation_Linear = 1,
|
||||
SPUInterpolation_Cosine = 2
|
||||
};
|
||||
|
||||
struct SoundInterface_struct
|
||||
{
|
||||
int id;
|
||||
const char *Name;
|
||||
int (*Init)(int buffersize);
|
||||
void (*DeInit)();
|
||||
void (*UpdateAudio)(s16 *buffer, u32 num_samples);
|
||||
u32 (*GetAudioSpace)();
|
||||
void (*MuteAudio)();
|
||||
void (*UnMuteAudio)();
|
||||
void (*SetVolume)(int volume);
|
||||
void (*ClearBuffer)();
|
||||
void (*FetchSamples)(s16 *sampleBuffer, size_t sampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer);
|
||||
size_t (*PostProcessSamples)(s16 *postProcessBuffer, size_t requestedSampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer);
|
||||
};
|
||||
|
||||
extern SoundInterface_struct SNDDummy;
|
||||
extern SoundInterface_struct SNDFile;
|
||||
extern int SPU_currentCoreNum;
|
||||
|
||||
struct channel_struct
|
||||
{
|
||||
channel_struct() : num(0),
|
||||
vol(0),
|
||||
volumeDiv(0),
|
||||
hold(0),
|
||||
pan(0),
|
||||
waveduty(0),
|
||||
repeat(0),
|
||||
format(0),
|
||||
keyon(0),
|
||||
status(0),
|
||||
addr(0),
|
||||
timer(0),
|
||||
loopstart(0),
|
||||
length(0),
|
||||
totlength(0),
|
||||
double_totlength_shifted(0.0),
|
||||
sampcnt(0.0),
|
||||
sampinc(0.0),
|
||||
lastsampcnt(0),
|
||||
pcm16b(0),
|
||||
pcm16b_last(0),
|
||||
loop_pcm16b(0),
|
||||
index(0),
|
||||
loop_index(0),
|
||||
x(0),
|
||||
psgnoise_last(0)
|
||||
{}
|
||||
u32 num;
|
||||
u8 vol;
|
||||
u8 volumeDiv;
|
||||
u8 hold;
|
||||
u8 pan;
|
||||
u8 waveduty;
|
||||
u8 repeat;
|
||||
u8 format;
|
||||
u8 keyon;
|
||||
u8 status;
|
||||
u32 addr;
|
||||
u16 timer;
|
||||
u16 loopstart;
|
||||
u32 length;
|
||||
u32 totlength;
|
||||
double double_totlength_shifted;
|
||||
double sampcnt;
|
||||
double sampinc;
|
||||
// ADPCM specific
|
||||
u32 lastsampcnt;
|
||||
s16 pcm16b, pcm16b_last;
|
||||
s16 loop_pcm16b;
|
||||
int index;
|
||||
int loop_index;
|
||||
u16 x;
|
||||
s16 psgnoise_last;
|
||||
};
|
||||
|
||||
class SPUFifo
|
||||
{
|
||||
public:
|
||||
SPUFifo();
|
||||
void enqueue(s16 val);
|
||||
s16 dequeue();
|
||||
s16 buffer[16];
|
||||
s32 head,tail,size;
|
||||
void save(EMUFILE* fp);
|
||||
bool load(EMUFILE* fp);
|
||||
void reset();
|
||||
};
|
||||
|
||||
class SPU_struct
|
||||
{
|
||||
public:
|
||||
SPU_struct(int buffersize);
|
||||
u32 bufpos;
|
||||
u32 buflength;
|
||||
s32 *sndbuf;
|
||||
s32 lastdata; //the last sample that a channel generated
|
||||
s16 *outbuf;
|
||||
u32 bufsize;
|
||||
channel_struct channels[16];
|
||||
|
||||
//registers
|
||||
struct REGS {
|
||||
REGS()
|
||||
: mastervol(0)
|
||||
, ctl_left(0)
|
||||
, ctl_right(0)
|
||||
, ctl_ch1bypass(0)
|
||||
, ctl_ch3bypass(0)
|
||||
, masteren(0)
|
||||
, soundbias(0)
|
||||
{}
|
||||
|
||||
u8 mastervol;
|
||||
u8 ctl_left, ctl_right;
|
||||
u8 ctl_ch1bypass, ctl_ch3bypass;
|
||||
u8 masteren;
|
||||
u16 soundbias;
|
||||
|
||||
enum LeftOutputMode
|
||||
{
|
||||
LOM_LEFT_MIXER=0, LOM_CH1=1, LOM_CH3=2, LOM_CH1_PLUS_CH3=3
|
||||
};
|
||||
|
||||
enum RightOutputMode
|
||||
{
|
||||
ROM_RIGHT_MIXER=0, ROM_CH1=1, ROM_CH3=2, ROM_CH1_PLUS_CH3=3
|
||||
};
|
||||
|
||||
struct CAP {
|
||||
CAP()
|
||||
: add(0), source(0), oneshot(0), bits8(0), active(0), dad(0), len(0)
|
||||
{}
|
||||
u8 add, source, oneshot, bits8, active;
|
||||
u32 dad;
|
||||
u16 len;
|
||||
struct Runtime {
|
||||
Runtime()
|
||||
: running(0), curdad(0), maxdad(0)
|
||||
{}
|
||||
u8 running;
|
||||
u32 curdad;
|
||||
u32 maxdad;
|
||||
double sampcnt;
|
||||
SPUFifo fifo;
|
||||
} runtime;
|
||||
} cap[2];
|
||||
} regs;
|
||||
|
||||
void reset();
|
||||
~SPU_struct();
|
||||
void KeyOff(int channel);
|
||||
void KeyOn(int channel);
|
||||
void KeyProbe(int channel);
|
||||
void ProbeCapture(int which);
|
||||
void WriteByte(u32 addr, u8 val);
|
||||
void WriteWord(u32 addr, u16 val);
|
||||
void WriteLong(u32 addr, u32 val);
|
||||
u8 ReadByte(u32 addr);
|
||||
u16 ReadWord(u32 addr);
|
||||
u32 ReadLong(u32 addr);
|
||||
bool isSPU(u32 addr) { return ((addr >= 0x04000400) && (addr < 0x04000520)); }
|
||||
|
||||
//kills all channels but leaves SPU otherwise running normally
|
||||
void ShutUp();
|
||||
};
|
||||
|
||||
extern SPU_struct *SPU_core, *SPU_user;
|
||||
extern int spu_core_samples;
|
||||
|
||||
int SPU_ChangeSoundCore(int coreid, int buffersize);
|
||||
SoundInterface_struct *SPU_SoundCore();
|
||||
|
||||
void SPU_ReInit(bool fakeBoot = false);
|
||||
int SPU_Init(int coreid, int buffersize);
|
||||
void SPU_Pause(int pause);
|
||||
void SPU_SetVolume(int volume);
|
||||
void SPU_SetSynchMode(int mode, int method);
|
||||
void SPU_ClearOutputBuffer(void);
|
||||
void SPU_Reset(void);
|
||||
void SPU_DeInit(void);
|
||||
void SPU_KeyOn(int channel);
|
||||
static FORCEINLINE void SPU_WriteByte(u32 addr, u8 val)
|
||||
{
|
||||
addr &= 0xFFF;
|
||||
|
||||
SPU_core->WriteByte(addr,val);
|
||||
if(SPU_user)
|
||||
SPU_user->WriteByte(addr,val);
|
||||
}
|
||||
static FORCEINLINE void SPU_WriteWord(u32 addr, u16 val)
|
||||
{
|
||||
addr &= 0xFFF;
|
||||
|
||||
SPU_core->WriteWord(addr,val);
|
||||
if(SPU_user)
|
||||
SPU_user->WriteWord(addr,val);
|
||||
}
|
||||
static FORCEINLINE void SPU_WriteLong(u32 addr, u32 val)
|
||||
{
|
||||
addr &= 0xFFF;
|
||||
|
||||
SPU_core->WriteLong(addr,val);
|
||||
if(SPU_user)
|
||||
SPU_user->WriteLong(addr,val);
|
||||
}
|
||||
static FORCEINLINE u8 SPU_ReadByte(u32 addr) { return SPU_core->ReadByte(addr & 0x0FFF); }
|
||||
static FORCEINLINE u16 SPU_ReadWord(u32 addr) { return SPU_core->ReadWord(addr & 0x0FFF); }
|
||||
static FORCEINLINE u32 SPU_ReadLong(u32 addr) { return SPU_core->ReadLong(addr & 0x0FFF); }
|
||||
void SPU_Emulate_core(void);
|
||||
void SPU_Emulate_user(bool mix = true);
|
||||
void SPU_DefaultFetchSamples(s16 *sampleBuffer, size_t sampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer);
|
||||
size_t SPU_DefaultPostProcessSamples(s16 *postProcessBuffer, size_t requestedSampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer);
|
||||
|
||||
void spu_savestate(EMUFILE* os);
|
||||
bool spu_loadstate(EMUFILE* is, int size);
|
||||
|
||||
enum WAVMode
|
||||
{
|
||||
WAVMODE_ANY = -1,
|
||||
WAVMODE_CORE = 0,
|
||||
WAVMODE_USER = 1
|
||||
};
|
||||
|
||||
class WavWriter
|
||||
{
|
||||
public:
|
||||
WavWriter();
|
||||
bool open(const std::string & fname);
|
||||
void close();
|
||||
void update(void* soundData, int numSamples);
|
||||
bool isRecording() const;
|
||||
WAVMode mode;
|
||||
private:
|
||||
FILE *spufp;
|
||||
};
|
||||
|
||||
void WAV_End();
|
||||
bool WAV_Begin(const char* fname, WAVMode mode=WAVMODE_CORE);
|
||||
bool WAV_IsRecording(WAVMode mode=WAVMODE_ANY);
|
||||
void WAV_WavSoundUpdate(void* soundData, int numSamples, WAVMode mode=WAVMODE_CORE);
|
||||
|
||||
// we should make this configurable eventually
|
||||
// but at least defining it somewhere is probably a step in the right direction
|
||||
#define DESMUME_SAMPLE_RATE 44100
|
||||
//#define DESMUME_SAMPLE_RATE 48000
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,352 +1,352 @@
|
|||
/*
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2006-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ARM_CPU
|
||||
#define ARM_CPU
|
||||
|
||||
#include "types.h"
|
||||
#include "bits.h"
|
||||
#include "MMU.h"
|
||||
|
||||
#define CODE(i) (((i)>>25)&0x7)
|
||||
#define OPCODE(i) (((i)>>21)&0xF)
|
||||
#define SIGNEBIT(i) BIT_N(i,20)
|
||||
|
||||
#define EXCEPTION_RESET 0x00
|
||||
#define EXCEPTION_UNDEFINED_INSTRUCTION 0x04
|
||||
#define EXCEPTION_SWI 0x08
|
||||
#define EXCEPTION_PREFETCH_ABORT 0x0C
|
||||
#define EXCEPTION_DATA_ABORT 0x10
|
||||
#define EXCEPTION_RESERVED_0x14 0x14
|
||||
#define EXCEPTION_IRQ 0x18
|
||||
#define EXCEPTION_FAST_IRQ 0x1C
|
||||
|
||||
#define INSTRUCTION_INDEX(i) ((((i)>>16)&0xFF0)|(((i)>>4)&0xF))
|
||||
|
||||
inline u32 ROR(u32 i, u32 j) { return ((((u32)(i))>>(j)) | (((u32)(i))<<(32-(j)))); }
|
||||
|
||||
template<typename T>
|
||||
inline T UNSIGNED_OVERFLOW(T a,T b,T c) { return BIT31(((a)&(b)) | (((a)|(b))&(~c))); }
|
||||
|
||||
template<typename T>
|
||||
inline T UNSIGNED_UNDERFLOW(T a,T b,T c) { return BIT31(((~a)&(b)) | (((~a)|(b))&(c))); }
|
||||
|
||||
template<typename T>
|
||||
inline T SIGNED_OVERFLOW(T a,T b,T c) { return BIT31(((a)&(b)&(~c)) | ((~a)&(~(b))&(c))); }
|
||||
|
||||
template<typename T>
|
||||
inline T SIGNED_UNDERFLOW(T a,T b,T c) { return BIT31(((a)&(~(b))&(~c)) | ((~a)&(b)&(c))); }
|
||||
|
||||
#if !defined(bswap32)
|
||||
#define bswap32(val) \
|
||||
( (val << 24) & 0xFF000000) | \
|
||||
( (val << 8) & 0x00FF0000) | \
|
||||
( (val >> 8) & 0x0000FF00) | \
|
||||
( (val >> 24) & 0x000000FF)
|
||||
#endif
|
||||
|
||||
#if !defined(bswap64)
|
||||
#define bswap64(x) \
|
||||
( (x << 56) & 0xff00000000000000ULL ) | \
|
||||
( (x << 40) & 0x00ff000000000000ULL ) | \
|
||||
( (x << 24) & 0x0000ff0000000000ULL ) | \
|
||||
( (x << 8) & 0x000000ff00000000ULL ) | \
|
||||
( (x >> 8) & 0x00000000ff000000ULL ) | \
|
||||
( (x >> 24) & 0x0000000000ff0000ULL ) | \
|
||||
( (x >> 40) & 0x000000000000ff00ULL ) | \
|
||||
( (x >> 56) & 0x00000000000000ffULL )
|
||||
#endif
|
||||
|
||||
// ============================= CPRS flags funcs
|
||||
inline bool CarryFrom(s32 left, s32 right)
|
||||
{
|
||||
u32 res = (0xFFFFFFFFU - (u32)left);
|
||||
|
||||
return ((u32)right > res);
|
||||
}
|
||||
|
||||
inline bool BorrowFrom(s32 left, s32 right)
|
||||
{
|
||||
return ((u32)right > (u32)left);
|
||||
}
|
||||
|
||||
inline bool OverflowFromADD(s32 alu_out, s32 left, s32 right)
|
||||
{
|
||||
return ((left >= 0 && right >= 0) || (left < 0 && right < 0))
|
||||
&& ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
|
||||
}
|
||||
|
||||
inline bool OverflowFromSUB(s32 alu_out, s32 left, s32 right)
|
||||
{
|
||||
return ((left < 0 && right >= 0) || (left >= 0 && right < 0))
|
||||
&& ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
|
||||
}
|
||||
|
||||
//zero 15-feb-2009 - these werent getting used and they were getting in my way
|
||||
//#define EQ 0x0
|
||||
//#define NE 0x1
|
||||
//#define CS 0x2
|
||||
//#define CC 0x3
|
||||
//#define MI 0x4
|
||||
//#define PL 0x5
|
||||
//#define VS 0x6
|
||||
//#define VC 0x7
|
||||
//#define HI 0x8
|
||||
//#define LS 0x9
|
||||
//#define GE 0xA
|
||||
//#define LT 0xB
|
||||
//#define GT 0xC
|
||||
//#define LE 0xD
|
||||
//#define AL 0xE
|
||||
|
||||
static const u8 arm_cond_table[16*16] = {
|
||||
// N=0, Z=0, C=0, V=0
|
||||
0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF, // 0x00
|
||||
0x00,0xFF,0xFF,0x00,0xFF,0x00,0xFF,0x20, // 0x00
|
||||
// N=0, Z=0, C=0, V=1
|
||||
0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x00, // 0x10
|
||||
0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
|
||||
// N=0, Z=0, C=1, V=0
|
||||
0x00,0xFF,0xFF,0x00,0x00,0xFF,0x00,0xFF, // 0x20
|
||||
0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x20,
|
||||
// N=0, Z=0, C=1, V=1
|
||||
0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x00, // 0x30
|
||||
0xFF,0x00,0x00,0xFF,0x00,0xFF,0xFF,0x20,
|
||||
// N=0, Z=1, C=0, V=0
|
||||
0xFF,0x00,0x00,0xFF,0x00,0xFF,0x00,0xFF, // 0x40
|
||||
0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x20,
|
||||
// N=0, Z=1, C=0, V=1
|
||||
0xFF,0x00,0x00,0xFF,0x00,0xFF,0xFF,0x00, // 0x50
|
||||
0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
|
||||
// N=0, Z=1, C=1, V=0
|
||||
0xFF,0x00,0xFF,0x00,0x00,0xFF,0x00,0xFF, // 0x60
|
||||
0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x20,
|
||||
// N=0, Z=1, C=1, V=1
|
||||
0xFF,0x00,0xFF,0x00,0x00,0xFF,0xFF,0x00, // 0x70
|
||||
0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
|
||||
// N=1, Z=0, C=0, V=0
|
||||
0x00,0xFF,0x00,0xFF,0xFF,0x00,0x00,0xFF, // 0x80
|
||||
0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
|
||||
// N=1, Z=0, C=0, V=1
|
||||
0x00,0xFF,0x00,0xFF,0xFF,0x00,0xFF,0x00, // 0x90
|
||||
0x00,0xFF,0xFF,0x00,0xFF,0x00,0xFF,0x20,
|
||||
// N=1, Z=0, C=1, V=0
|
||||
0x00,0xFF,0xFF,0x00,0xFF,0x00,0x00,0xFF, // 0xA0
|
||||
0xFF,0x00,0x00,0xFF,0x00,0xFF,0xFF,0x20,
|
||||
// N=1, Z=0, C=1, V=1
|
||||
0x00,0xFF,0xFF,0x00,0xFF,0x00,0xFF,0x00, // 0xB0
|
||||
0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x20,
|
||||
// N=1, Z=1, C=0, V=0
|
||||
0xFF,0x00,0x00,0xFF,0xFF,0x00,0x00,0xFF, // 0xC0
|
||||
0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
|
||||
// N=1, Z=1, C=0, V=1
|
||||
0xFF,0x00,0x00,0xFF,0xFF,0x00,0xFF,0x00, // 0xD0
|
||||
0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x20,
|
||||
// N=1, Z=1, C=1, V=0
|
||||
0xFF,0x00,0xFF,0x00,0xFF,0x00,0x00,0xFF, // 0xE0
|
||||
0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
|
||||
// N=1, Z=1, C=1, V=1
|
||||
0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00, // 0xF0
|
||||
0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x20
|
||||
};
|
||||
|
||||
#define TEST_COND(cond, inst, CPSR) ((arm_cond_table[((CPSR.val >> 24) & 0xf0)|(cond)]) & (1 << (inst)))
|
||||
|
||||
|
||||
enum Mode
|
||||
{
|
||||
USR = 0x10,
|
||||
FIQ = 0x11,
|
||||
IRQ = 0x12,
|
||||
SVC = 0x13,
|
||||
ABT = 0x17,
|
||||
UND = 0x1B,
|
||||
SYS = 0x1F
|
||||
};
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
u32 N : 1,
|
||||
Z : 1,
|
||||
C : 1,
|
||||
V : 1,
|
||||
Q : 1,
|
||||
RAZ : 19,
|
||||
I : 1,
|
||||
F : 1,
|
||||
T : 1,
|
||||
mode : 5;
|
||||
} bits;
|
||||
u32 val;
|
||||
} Status_Reg;
|
||||
#else
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
u32 mode : 5,
|
||||
T : 1,
|
||||
F : 1,
|
||||
I : 1,
|
||||
RAZ : 19,
|
||||
Q : 1,
|
||||
V : 1,
|
||||
C : 1,
|
||||
Z : 1,
|
||||
N : 1;
|
||||
} bits;
|
||||
u32 val;
|
||||
} Status_Reg;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The control interface to a CPU
|
||||
*/
|
||||
struct armcpu_ctrl_iface
|
||||
{
|
||||
/** stall the processor */
|
||||
void (*stall)( void *instance);
|
||||
|
||||
/** unstall the processor */
|
||||
void (*unstall)( void *instance);
|
||||
|
||||
/** read a register value */
|
||||
u32 (*read_reg)( void *instance, u32 reg_num);
|
||||
|
||||
/** set a register value */
|
||||
void (*set_reg)( void *instance, u32 reg_num, u32 value);
|
||||
|
||||
/** install the post execute function */
|
||||
void (*install_post_ex_fn)( void *instance,
|
||||
void (*fn)( void *, u32 adr, int thumb),
|
||||
void *fn_data);
|
||||
|
||||
/** remove the post execute function */
|
||||
void (*remove_post_ex_fn)( void *instance);
|
||||
|
||||
/** the private data passed to all interface functions */
|
||||
void *data;
|
||||
};
|
||||
|
||||
|
||||
typedef void* armcp_t;
|
||||
|
||||
struct armcpu_t
|
||||
{
|
||||
u32 proc_ID;
|
||||
u32 instruction; //4
|
||||
u32 instruct_adr; //8
|
||||
u32 next_instruction; //12
|
||||
|
||||
u32 R[16]; //16
|
||||
Status_Reg CPSR; //80
|
||||
Status_Reg SPSR;
|
||||
|
||||
void SetControlInterface(const armcpu_ctrl_iface *theCtrlInterface);
|
||||
armcpu_ctrl_iface* GetControlInterface();
|
||||
void SetControlInterfaceData(void *theData);
|
||||
void* GetControlInterfaceData();
|
||||
|
||||
void SetCurrentMemoryInterface(armcpu_memory_iface *theMemInterface);
|
||||
armcpu_memory_iface* GetCurrentMemoryInterface();
|
||||
void SetCurrentMemoryInterfaceData(void *theData);
|
||||
void* GetCurrentMemoryInterfaceData();
|
||||
|
||||
void SetBaseMemoryInterface(const armcpu_memory_iface *theMemInterface);
|
||||
armcpu_memory_iface* GetBaseMemoryInterface();
|
||||
void SetBaseMemoryInterfaceData(void *theData);
|
||||
void* GetBaseMemoryInterfaceData();
|
||||
|
||||
void ResetMemoryInterfaceToBase();
|
||||
|
||||
void changeCPSR();
|
||||
|
||||
u32 R13_usr, R14_usr;
|
||||
u32 R13_svc, R14_svc;
|
||||
u32 R13_abt, R14_abt;
|
||||
u32 R13_und, R14_und;
|
||||
u32 R13_irq, R14_irq;
|
||||
u32 R8_fiq, R9_fiq, R10_fiq, R11_fiq, R12_fiq, R13_fiq, R14_fiq;
|
||||
Status_Reg SPSR_svc, SPSR_abt, SPSR_und, SPSR_irq, SPSR_fiq;
|
||||
|
||||
u32 intVector;
|
||||
u8 LDTBit; //1 : ARMv5 style 0 : non ARMv5 (earlier)
|
||||
BOOL waitIRQ;
|
||||
BOOL halt_IE_and_IF; //the cpu is halted, waiting for IE&IF to signal something
|
||||
u8 intrWaitARM_state;
|
||||
|
||||
BOOL BIOS_loaded;
|
||||
|
||||
u32 (* *swi_tab)();
|
||||
|
||||
// flag indicating if the processor is stalled (for debugging)
|
||||
int stalled;
|
||||
|
||||
#if defined(_M_X64) || defined(__x86_64__)
|
||||
u8 cond_table[16*16];
|
||||
#endif
|
||||
|
||||
/** there is a pending irq for the cpu */
|
||||
int irq_flag;
|
||||
|
||||
/** the post executed function (if installed) */
|
||||
void (*post_ex_fn)( void *, u32 adr, int thumb);
|
||||
|
||||
/** data for the post executed function */
|
||||
void *post_ex_fn_data;
|
||||
|
||||
/** the memory interface */
|
||||
armcpu_memory_iface *mem_if; // This is the memory interface currently in use.
|
||||
armcpu_memory_iface base_mem_if; // This is the CPU's base memory interface.
|
||||
|
||||
/** the ctrl interface */
|
||||
armcpu_ctrl_iface ctrl_iface;
|
||||
};
|
||||
|
||||
int armcpu_new( armcpu_t *armcpu, u32 id);
|
||||
void armcpu_init(armcpu_t *armcpu, u32 adr);
|
||||
u32 armcpu_switchMode(armcpu_t *armcpu, u8 mode);
|
||||
|
||||
|
||||
BOOL armcpu_irqException(armcpu_t *armcpu);
|
||||
BOOL armcpu_flagIrq( armcpu_t *armcpu);
|
||||
void armcpu_exception(armcpu_t *cpu, u32 number);
|
||||
u32 TRAPUNDEF(armcpu_t* cpu);
|
||||
u32 armcpu_Wait4IRQ(armcpu_t *cpu);
|
||||
|
||||
extern armcpu_t NDS_ARM7;
|
||||
extern armcpu_t NDS_ARM9;
|
||||
extern const armcpu_ctrl_iface arm_default_ctrl_iface;
|
||||
|
||||
template<int PROCNUM> u32 armcpu_exec();
|
||||
#ifdef HAVE_JIT
|
||||
template<int PROCNUM, bool jit> u32 armcpu_exec();
|
||||
#endif
|
||||
|
||||
void setIF(int PROCNUM, u32 flag);
|
||||
char* decodeIntruction(bool thumb_mode, u32 instr);
|
||||
|
||||
static INLINE void NDS_makeIrq(int PROCNUM, u32 num)
|
||||
{
|
||||
setIF(PROCNUM,1<<num);
|
||||
}
|
||||
|
||||
#endif
|
||||
/*
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2006-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ARM_CPU
|
||||
#define ARM_CPU
|
||||
|
||||
#include "types.h"
|
||||
#include "bits.h"
|
||||
#include "MMU.h"
|
||||
|
||||
#define CODE(i) (((i)>>25)&0x7)
|
||||
#define OPCODE(i) (((i)>>21)&0xF)
|
||||
#define SIGNEBIT(i) BIT_N(i,20)
|
||||
|
||||
#define EXCEPTION_RESET 0x00
|
||||
#define EXCEPTION_UNDEFINED_INSTRUCTION 0x04
|
||||
#define EXCEPTION_SWI 0x08
|
||||
#define EXCEPTION_PREFETCH_ABORT 0x0C
|
||||
#define EXCEPTION_DATA_ABORT 0x10
|
||||
#define EXCEPTION_RESERVED_0x14 0x14
|
||||
#define EXCEPTION_IRQ 0x18
|
||||
#define EXCEPTION_FAST_IRQ 0x1C
|
||||
|
||||
#define INSTRUCTION_INDEX(i) ((((i)>>16)&0xFF0)|(((i)>>4)&0xF))
|
||||
|
||||
inline u32 ROR(u32 i, u32 j) { return ((((u32)(i))>>(j)) | (((u32)(i))<<(32-(j)))); }
|
||||
|
||||
template<typename T>
|
||||
inline T UNSIGNED_OVERFLOW(T a,T b,T c) { return BIT31(((a)&(b)) | (((a)|(b))&(~c))); }
|
||||
|
||||
template<typename T>
|
||||
inline T UNSIGNED_UNDERFLOW(T a,T b,T c) { return BIT31(((~a)&(b)) | (((~a)|(b))&(c))); }
|
||||
|
||||
template<typename T>
|
||||
inline T SIGNED_OVERFLOW(T a,T b,T c) { return BIT31(((a)&(b)&(~c)) | ((~a)&(~(b))&(c))); }
|
||||
|
||||
template<typename T>
|
||||
inline T SIGNED_UNDERFLOW(T a,T b,T c) { return BIT31(((a)&(~(b))&(~c)) | ((~a)&(b)&(c))); }
|
||||
|
||||
#if !defined(bswap32)
|
||||
#define bswap32(val) \
|
||||
( (val << 24) & 0xFF000000) | \
|
||||
( (val << 8) & 0x00FF0000) | \
|
||||
( (val >> 8) & 0x0000FF00) | \
|
||||
( (val >> 24) & 0x000000FF)
|
||||
#endif
|
||||
|
||||
#if !defined(bswap64)
|
||||
#define bswap64(x) \
|
||||
( (x << 56) & 0xff00000000000000ULL ) | \
|
||||
( (x << 40) & 0x00ff000000000000ULL ) | \
|
||||
( (x << 24) & 0x0000ff0000000000ULL ) | \
|
||||
( (x << 8) & 0x000000ff00000000ULL ) | \
|
||||
( (x >> 8) & 0x00000000ff000000ULL ) | \
|
||||
( (x >> 24) & 0x0000000000ff0000ULL ) | \
|
||||
( (x >> 40) & 0x000000000000ff00ULL ) | \
|
||||
( (x >> 56) & 0x00000000000000ffULL )
|
||||
#endif
|
||||
|
||||
// ============================= CPRS flags funcs
|
||||
inline bool CarryFrom(s32 left, s32 right)
|
||||
{
|
||||
u32 res = (0xFFFFFFFFU - (u32)left);
|
||||
|
||||
return ((u32)right > res);
|
||||
}
|
||||
|
||||
inline bool BorrowFrom(s32 left, s32 right)
|
||||
{
|
||||
return ((u32)right > (u32)left);
|
||||
}
|
||||
|
||||
inline bool OverflowFromADD(s32 alu_out, s32 left, s32 right)
|
||||
{
|
||||
return ((left >= 0 && right >= 0) || (left < 0 && right < 0))
|
||||
&& ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
|
||||
}
|
||||
|
||||
inline bool OverflowFromSUB(s32 alu_out, s32 left, s32 right)
|
||||
{
|
||||
return ((left < 0 && right >= 0) || (left >= 0 && right < 0))
|
||||
&& ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
|
||||
}
|
||||
|
||||
//zero 15-feb-2009 - these werent getting used and they were getting in my way
|
||||
//#define EQ 0x0
|
||||
//#define NE 0x1
|
||||
//#define CS 0x2
|
||||
//#define CC 0x3
|
||||
//#define MI 0x4
|
||||
//#define PL 0x5
|
||||
//#define VS 0x6
|
||||
//#define VC 0x7
|
||||
//#define HI 0x8
|
||||
//#define LS 0x9
|
||||
//#define GE 0xA
|
||||
//#define LT 0xB
|
||||
//#define GT 0xC
|
||||
//#define LE 0xD
|
||||
//#define AL 0xE
|
||||
|
||||
static const u8 arm_cond_table[16*16] = {
|
||||
// N=0, Z=0, C=0, V=0
|
||||
0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF, // 0x00
|
||||
0x00,0xFF,0xFF,0x00,0xFF,0x00,0xFF,0x20, // 0x00
|
||||
// N=0, Z=0, C=0, V=1
|
||||
0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x00, // 0x10
|
||||
0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
|
||||
// N=0, Z=0, C=1, V=0
|
||||
0x00,0xFF,0xFF,0x00,0x00,0xFF,0x00,0xFF, // 0x20
|
||||
0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x20,
|
||||
// N=0, Z=0, C=1, V=1
|
||||
0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x00, // 0x30
|
||||
0xFF,0x00,0x00,0xFF,0x00,0xFF,0xFF,0x20,
|
||||
// N=0, Z=1, C=0, V=0
|
||||
0xFF,0x00,0x00,0xFF,0x00,0xFF,0x00,0xFF, // 0x40
|
||||
0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x20,
|
||||
// N=0, Z=1, C=0, V=1
|
||||
0xFF,0x00,0x00,0xFF,0x00,0xFF,0xFF,0x00, // 0x50
|
||||
0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
|
||||
// N=0, Z=1, C=1, V=0
|
||||
0xFF,0x00,0xFF,0x00,0x00,0xFF,0x00,0xFF, // 0x60
|
||||
0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x20,
|
||||
// N=0, Z=1, C=1, V=1
|
||||
0xFF,0x00,0xFF,0x00,0x00,0xFF,0xFF,0x00, // 0x70
|
||||
0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
|
||||
// N=1, Z=0, C=0, V=0
|
||||
0x00,0xFF,0x00,0xFF,0xFF,0x00,0x00,0xFF, // 0x80
|
||||
0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
|
||||
// N=1, Z=0, C=0, V=1
|
||||
0x00,0xFF,0x00,0xFF,0xFF,0x00,0xFF,0x00, // 0x90
|
||||
0x00,0xFF,0xFF,0x00,0xFF,0x00,0xFF,0x20,
|
||||
// N=1, Z=0, C=1, V=0
|
||||
0x00,0xFF,0xFF,0x00,0xFF,0x00,0x00,0xFF, // 0xA0
|
||||
0xFF,0x00,0x00,0xFF,0x00,0xFF,0xFF,0x20,
|
||||
// N=1, Z=0, C=1, V=1
|
||||
0x00,0xFF,0xFF,0x00,0xFF,0x00,0xFF,0x00, // 0xB0
|
||||
0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x20,
|
||||
// N=1, Z=1, C=0, V=0
|
||||
0xFF,0x00,0x00,0xFF,0xFF,0x00,0x00,0xFF, // 0xC0
|
||||
0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
|
||||
// N=1, Z=1, C=0, V=1
|
||||
0xFF,0x00,0x00,0xFF,0xFF,0x00,0xFF,0x00, // 0xD0
|
||||
0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x20,
|
||||
// N=1, Z=1, C=1, V=0
|
||||
0xFF,0x00,0xFF,0x00,0xFF,0x00,0x00,0xFF, // 0xE0
|
||||
0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
|
||||
// N=1, Z=1, C=1, V=1
|
||||
0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00, // 0xF0
|
||||
0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x20
|
||||
};
|
||||
|
||||
#define TEST_COND(cond, inst, CPSR) ((arm_cond_table[((CPSR.val >> 24) & 0xf0)|(cond)]) & (1 << (inst)))
|
||||
|
||||
|
||||
enum Mode
|
||||
{
|
||||
USR = 0x10,
|
||||
FIQ = 0x11,
|
||||
IRQ = 0x12,
|
||||
SVC = 0x13,
|
||||
ABT = 0x17,
|
||||
UND = 0x1B,
|
||||
SYS = 0x1F
|
||||
};
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
u32 N : 1,
|
||||
Z : 1,
|
||||
C : 1,
|
||||
V : 1,
|
||||
Q : 1,
|
||||
RAZ : 19,
|
||||
I : 1,
|
||||
F : 1,
|
||||
T : 1,
|
||||
mode : 5;
|
||||
} bits;
|
||||
u32 val;
|
||||
} Status_Reg;
|
||||
#else
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
u32 mode : 5,
|
||||
T : 1,
|
||||
F : 1,
|
||||
I : 1,
|
||||
RAZ : 19,
|
||||
Q : 1,
|
||||
V : 1,
|
||||
C : 1,
|
||||
Z : 1,
|
||||
N : 1;
|
||||
} bits;
|
||||
u32 val;
|
||||
} Status_Reg;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The control interface to a CPU
|
||||
*/
|
||||
struct armcpu_ctrl_iface
|
||||
{
|
||||
/** stall the processor */
|
||||
void (*stall)( void *instance);
|
||||
|
||||
/** unstall the processor */
|
||||
void (*unstall)( void *instance);
|
||||
|
||||
/** read a register value */
|
||||
u32 (*read_reg)( void *instance, u32 reg_num);
|
||||
|
||||
/** set a register value */
|
||||
void (*set_reg)( void *instance, u32 reg_num, u32 value);
|
||||
|
||||
/** install the post execute function */
|
||||
void (*install_post_ex_fn)( void *instance,
|
||||
void (*fn)( void *, u32 adr, int thumb),
|
||||
void *fn_data);
|
||||
|
||||
/** remove the post execute function */
|
||||
void (*remove_post_ex_fn)( void *instance);
|
||||
|
||||
/** the private data passed to all interface functions */
|
||||
void *data;
|
||||
};
|
||||
|
||||
|
||||
typedef void* armcp_t;
|
||||
|
||||
struct armcpu_t
|
||||
{
|
||||
u32 proc_ID;
|
||||
u32 instruction; //4
|
||||
u32 instruct_adr; //8
|
||||
u32 next_instruction; //12
|
||||
|
||||
u32 R[16]; //16
|
||||
Status_Reg CPSR; //80
|
||||
Status_Reg SPSR;
|
||||
|
||||
void SetControlInterface(const armcpu_ctrl_iface *theCtrlInterface);
|
||||
armcpu_ctrl_iface* GetControlInterface();
|
||||
void SetControlInterfaceData(void *theData);
|
||||
void* GetControlInterfaceData();
|
||||
|
||||
void SetCurrentMemoryInterface(armcpu_memory_iface *theMemInterface);
|
||||
armcpu_memory_iface* GetCurrentMemoryInterface();
|
||||
void SetCurrentMemoryInterfaceData(void *theData);
|
||||
void* GetCurrentMemoryInterfaceData();
|
||||
|
||||
void SetBaseMemoryInterface(const armcpu_memory_iface *theMemInterface);
|
||||
armcpu_memory_iface* GetBaseMemoryInterface();
|
||||
void SetBaseMemoryInterfaceData(void *theData);
|
||||
void* GetBaseMemoryInterfaceData();
|
||||
|
||||
void ResetMemoryInterfaceToBase();
|
||||
|
||||
void changeCPSR();
|
||||
|
||||
u32 R13_usr, R14_usr;
|
||||
u32 R13_svc, R14_svc;
|
||||
u32 R13_abt, R14_abt;
|
||||
u32 R13_und, R14_und;
|
||||
u32 R13_irq, R14_irq;
|
||||
u32 R8_fiq, R9_fiq, R10_fiq, R11_fiq, R12_fiq, R13_fiq, R14_fiq;
|
||||
Status_Reg SPSR_svc, SPSR_abt, SPSR_und, SPSR_irq, SPSR_fiq;
|
||||
|
||||
u32 intVector;
|
||||
u8 LDTBit; //1 : ARMv5 style 0 : non ARMv5 (earlier)
|
||||
BOOL waitIRQ;
|
||||
BOOL halt_IE_and_IF; //the cpu is halted, waiting for IE&IF to signal something
|
||||
u8 intrWaitARM_state;
|
||||
|
||||
BOOL BIOS_loaded;
|
||||
|
||||
u32 (* *swi_tab)();
|
||||
|
||||
// flag indicating if the processor is stalled (for debugging)
|
||||
int stalled;
|
||||
|
||||
#if defined(_M_X64) || defined(__x86_64__)
|
||||
u8 cond_table[16*16];
|
||||
#endif
|
||||
|
||||
/** there is a pending irq for the cpu */
|
||||
int irq_flag;
|
||||
|
||||
/** the post executed function (if installed) */
|
||||
void (*post_ex_fn)( void *, u32 adr, int thumb);
|
||||
|
||||
/** data for the post executed function */
|
||||
void *post_ex_fn_data;
|
||||
|
||||
/** the memory interface */
|
||||
armcpu_memory_iface *mem_if; // This is the memory interface currently in use.
|
||||
armcpu_memory_iface base_mem_if; // This is the CPU's base memory interface.
|
||||
|
||||
/** the ctrl interface */
|
||||
armcpu_ctrl_iface ctrl_iface;
|
||||
};
|
||||
|
||||
int armcpu_new( armcpu_t *armcpu, u32 id);
|
||||
void armcpu_init(armcpu_t *armcpu, u32 adr);
|
||||
u32 armcpu_switchMode(armcpu_t *armcpu, u8 mode);
|
||||
|
||||
|
||||
BOOL armcpu_irqException(armcpu_t *armcpu);
|
||||
BOOL armcpu_flagIrq( armcpu_t *armcpu);
|
||||
void armcpu_exception(armcpu_t *cpu, u32 number);
|
||||
u32 TRAPUNDEF(armcpu_t* cpu);
|
||||
u32 armcpu_Wait4IRQ(armcpu_t *cpu);
|
||||
|
||||
extern armcpu_t NDS_ARM7;
|
||||
extern armcpu_t NDS_ARM9;
|
||||
extern const armcpu_ctrl_iface arm_default_ctrl_iface;
|
||||
|
||||
template<int PROCNUM> u32 armcpu_exec();
|
||||
#ifdef HAVE_JIT
|
||||
template<int PROCNUM, bool jit> u32 armcpu_exec();
|
||||
#endif
|
||||
|
||||
void setIF(int PROCNUM, u32 flag);
|
||||
char* decodeIntruction(bool thumb_mode, u32 instr);
|
||||
|
||||
static INLINE void NDS_makeIrq(int PROCNUM, u32 num)
|
||||
{
|
||||
setIF(PROCNUM,1<<num);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
/*
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2006-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef BIOS_H
|
||||
#define BIOS_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
extern u32 (* ARM_swi_tab[2][32])();
|
||||
extern const char* ARM_swi_names[2][32];
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2006-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef BIOS_H
|
||||
#define BIOS_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
extern u32 (* ARM_swi_tab[2][32])();
|
||||
extern const char* ARM_swi_names[2][32];
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,44 +1,44 @@
|
|||
#ifndef BITS_H
|
||||
#define BITS_H
|
||||
|
||||
#define BIT(n) (1<<(n))
|
||||
|
||||
#define BIT_N(i,n) (((i)>>(n))&1)
|
||||
#define BIT0(i) ((i)&1)
|
||||
#define BIT1(i) BIT_N(i,1)
|
||||
#define BIT2(i) BIT_N(i,2)
|
||||
#define BIT3(i) BIT_N(i,3)
|
||||
#define BIT4(i) BIT_N(i,4)
|
||||
#define BIT5(i) BIT_N(i,5)
|
||||
#define BIT6(i) BIT_N(i,6)
|
||||
#define BIT7(i) BIT_N(i,7)
|
||||
#define BIT8(i) BIT_N(i,8)
|
||||
#define BIT9(i) BIT_N(i,9)
|
||||
#define BIT10(i) BIT_N(i,10)
|
||||
#define BIT11(i) BIT_N(i,11)
|
||||
#define BIT12(i) BIT_N(i,12)
|
||||
#define BIT13(i) BIT_N(i,13)
|
||||
#define BIT14(i) BIT_N(i,14)
|
||||
#define BIT15(i) BIT_N(i,15)
|
||||
#define BIT16(i) BIT_N(i,16)
|
||||
#define BIT17(i) BIT_N(i,17)
|
||||
#define BIT18(i) BIT_N(i,18)
|
||||
#define BIT19(i) BIT_N(i,19)
|
||||
#define BIT20(i) BIT_N(i,20)
|
||||
#define BIT21(i) BIT_N(i,21)
|
||||
#define BIT22(i) BIT_N(i,22)
|
||||
#define BIT23(i) BIT_N(i,23)
|
||||
#define BIT24(i) BIT_N(i,24)
|
||||
#define BIT25(i) BIT_N(i,25)
|
||||
#define BIT26(i) BIT_N(i,26)
|
||||
#define BIT27(i) BIT_N(i,27)
|
||||
#define BIT28(i) BIT_N(i,28)
|
||||
#define BIT29(i) BIT_N(i,29)
|
||||
#define BIT30(i) BIT_N(i,30)
|
||||
#define BIT31(i) ((i)>>31)
|
||||
|
||||
#define CONDITION(i) (i)>>28
|
||||
|
||||
#define REG_POS(i,n) (((i)>>n)&0xF)
|
||||
|
||||
#endif
|
||||
#ifndef BITS_H
|
||||
#define BITS_H
|
||||
|
||||
#define BIT(n) (1<<(n))
|
||||
|
||||
#define BIT_N(i,n) (((i)>>(n))&1)
|
||||
#define BIT0(i) ((i)&1)
|
||||
#define BIT1(i) BIT_N(i,1)
|
||||
#define BIT2(i) BIT_N(i,2)
|
||||
#define BIT3(i) BIT_N(i,3)
|
||||
#define BIT4(i) BIT_N(i,4)
|
||||
#define BIT5(i) BIT_N(i,5)
|
||||
#define BIT6(i) BIT_N(i,6)
|
||||
#define BIT7(i) BIT_N(i,7)
|
||||
#define BIT8(i) BIT_N(i,8)
|
||||
#define BIT9(i) BIT_N(i,9)
|
||||
#define BIT10(i) BIT_N(i,10)
|
||||
#define BIT11(i) BIT_N(i,11)
|
||||
#define BIT12(i) BIT_N(i,12)
|
||||
#define BIT13(i) BIT_N(i,13)
|
||||
#define BIT14(i) BIT_N(i,14)
|
||||
#define BIT15(i) BIT_N(i,15)
|
||||
#define BIT16(i) BIT_N(i,16)
|
||||
#define BIT17(i) BIT_N(i,17)
|
||||
#define BIT18(i) BIT_N(i,18)
|
||||
#define BIT19(i) BIT_N(i,19)
|
||||
#define BIT20(i) BIT_N(i,20)
|
||||
#define BIT21(i) BIT_N(i,21)
|
||||
#define BIT22(i) BIT_N(i,22)
|
||||
#define BIT23(i) BIT_N(i,23)
|
||||
#define BIT24(i) BIT_N(i,24)
|
||||
#define BIT25(i) BIT_N(i,25)
|
||||
#define BIT26(i) BIT_N(i,26)
|
||||
#define BIT27(i) BIT_N(i,27)
|
||||
#define BIT28(i) BIT_N(i,28)
|
||||
#define BIT29(i) BIT_N(i,29)
|
||||
#define BIT30(i) BIT_N(i,30)
|
||||
#define BIT31(i) ((i)>>31)
|
||||
|
||||
#define CONDITION(i) (i)>>28
|
||||
|
||||
#define REG_POS(i,n) (((i)>>n)&0xF)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,201 +1,201 @@
|
|||
/*
|
||||
Copyright (C) 2009-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "types.h"
|
||||
|
||||
#define CHEAT_VERSION_MAJOR 2
|
||||
#define CHEAT_VERSION_MINOR 0
|
||||
#define MAX_CHEAT_LIST 100
|
||||
#define MAX_XX_CODE 1024
|
||||
#define CHEAT_FILE_MIN_FGETS_BUFFER 32768
|
||||
#define CHEAT_DB_GAME_TITLE_SIZE 256
|
||||
|
||||
#define CHEAT_TYPE_EMPTY 0xFF
|
||||
#define CHEAT_TYPE_INTERNAL 0
|
||||
#define CHEAT_TYPE_AR 1
|
||||
#define CHEAT_TYPE_CODEBREAKER 2
|
||||
|
||||
struct CHEATS_LIST
|
||||
{
|
||||
CHEATS_LIST()
|
||||
{
|
||||
memset(this,0,sizeof(*this));
|
||||
type = 0xFF;
|
||||
}
|
||||
u8 type;
|
||||
BOOL enabled;
|
||||
// TODO
|
||||
u8 freezeType; // 0 - normal freeze
|
||||
// 1 - can decrease
|
||||
// 2 - can increase
|
||||
u32 code[MAX_XX_CODE][2];
|
||||
char description[1024];
|
||||
int num;
|
||||
u8 size;
|
||||
};
|
||||
|
||||
class CHEATS
|
||||
{
|
||||
private:
|
||||
std::vector<CHEATS_LIST> list;
|
||||
u8 filename[MAX_PATH];
|
||||
u32 currentGet;
|
||||
|
||||
void clear();
|
||||
void ARparser(CHEATS_LIST& cheat);
|
||||
char *clearCode(char *s);
|
||||
|
||||
public:
|
||||
CHEATS()
|
||||
: currentGet(0)
|
||||
{
|
||||
memset(filename, 0, sizeof(filename));
|
||||
}
|
||||
~CHEATS() {}
|
||||
|
||||
void init(char *path);
|
||||
BOOL add(u8 size, u32 address, u32 val, char *description, BOOL enabled);
|
||||
BOOL update(u8 size, u32 address, u32 val, char *description, BOOL enabled, u32 pos);
|
||||
BOOL add_AR(char *code, char *description, BOOL enabled);
|
||||
BOOL update_AR(char *code, char *description, BOOL enabled, u32 pos);
|
||||
BOOL add_AR_Direct(CHEATS_LIST cheat);
|
||||
BOOL add_CB(char *code, char *description, BOOL enabled);
|
||||
BOOL update_CB(char *code, char *description, BOOL enabled, u32 pos);
|
||||
BOOL remove(u32 pos);
|
||||
void getListReset();
|
||||
BOOL getList(CHEATS_LIST *cheat);
|
||||
CHEATS_LIST* getListPtr();
|
||||
BOOL get(CHEATS_LIST *cheat, u32 pos);
|
||||
CHEATS_LIST* getItemByIndex(const u32 pos);
|
||||
u32 getSize();
|
||||
size_t getActiveCount();
|
||||
void setDescription(const char *description, u32 pos);
|
||||
BOOL save();
|
||||
BOOL load();
|
||||
void process(int targetType);
|
||||
void getXXcodeString(CHEATS_LIST cheat, char *res_buf);
|
||||
|
||||
static BOOL XXCodeFromString(CHEATS_LIST *cheatItem, const std::string codeString);
|
||||
static BOOL XXCodeFromString(CHEATS_LIST *cheatItem, const char *codeString);
|
||||
};
|
||||
|
||||
class CHEATSEARCH
|
||||
{
|
||||
private:
|
||||
u8 *statMem;
|
||||
u8 *mem;
|
||||
u32 amount;
|
||||
u32 lastRecord;
|
||||
|
||||
u32 _type;
|
||||
u32 _size;
|
||||
u32 _sign;
|
||||
|
||||
public:
|
||||
CHEATSEARCH()
|
||||
: statMem(0), mem(0), amount(0), lastRecord(0), _type(0), _size(0), _sign(0)
|
||||
{}
|
||||
~CHEATSEARCH() { close(); }
|
||||
BOOL start(u8 type, u8 size, u8 sign);
|
||||
BOOL close();
|
||||
u32 search(u32 val);
|
||||
u32 search(u8 comp);
|
||||
u32 getAmount();
|
||||
BOOL getList(u32 *address, u32 *curVal);
|
||||
void getListReset();
|
||||
};
|
||||
|
||||
enum CHEATS_DB_TYPE
|
||||
{
|
||||
CHEATS_DB_R4 = 0
|
||||
};
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
typedef struct FAT_R4
|
||||
{
|
||||
u8 serial[4];
|
||||
u32 CRC;
|
||||
u64 addr;
|
||||
} FAT_R4;
|
||||
#pragma pack(pop)
|
||||
|
||||
class CHEATSEXPORT
|
||||
{
|
||||
private:
|
||||
CHEATS_DB_TYPE type;
|
||||
bool encrypted;
|
||||
FILE *fp;
|
||||
u32 fsize;
|
||||
u32 dataSize;
|
||||
u32 encOffset;
|
||||
FAT_R4 fat;
|
||||
bool search();
|
||||
bool getCodes();
|
||||
void R4decrypt(u8 *buf, u32 len, u32 n);
|
||||
|
||||
u32 numCheats;
|
||||
CHEATS_LIST *cheats;
|
||||
|
||||
u8 error; // 0 - no errors
|
||||
// 1 - open failed/file not found
|
||||
// 2 - file format is wrong (no valid header ID)
|
||||
// 3 - cheat not found in database
|
||||
// 4 - export error from database
|
||||
|
||||
public:
|
||||
CHEATSEXPORT() :
|
||||
fp(NULL),
|
||||
fsize(0),
|
||||
dataSize(0),
|
||||
encOffset(0),
|
||||
type(CHEATS_DB_R4),
|
||||
encrypted(false),
|
||||
numCheats(0),
|
||||
cheats(0),
|
||||
CRC(0),
|
||||
error(0)
|
||||
{
|
||||
memset(date, 0, sizeof(date));
|
||||
gametitle = (u8 *)malloc(CHEAT_DB_GAME_TITLE_SIZE);
|
||||
memset(gametitle, 0, CHEAT_DB_GAME_TITLE_SIZE);
|
||||
}
|
||||
~CHEATSEXPORT()
|
||||
{
|
||||
free(gametitle);
|
||||
gametitle = NULL;
|
||||
}
|
||||
|
||||
u8 *gametitle;
|
||||
u8 date[17];
|
||||
u32 CRC;
|
||||
bool load(char *path);
|
||||
void close();
|
||||
CHEATS_LIST *getCheats();
|
||||
u32 getCheatsNum();
|
||||
u8 getErrorCode() { return error; }
|
||||
};
|
||||
|
||||
extern CHEATS *cheats;
|
||||
extern CHEATSEARCH *cheatSearch;
|
||||
|
||||
|
||||
/*
|
||||
Copyright (C) 2009-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "types.h"
|
||||
|
||||
#define CHEAT_VERSION_MAJOR 2
|
||||
#define CHEAT_VERSION_MINOR 0
|
||||
#define MAX_CHEAT_LIST 100
|
||||
#define MAX_XX_CODE 1024
|
||||
#define CHEAT_FILE_MIN_FGETS_BUFFER 32768
|
||||
#define CHEAT_DB_GAME_TITLE_SIZE 256
|
||||
|
||||
#define CHEAT_TYPE_EMPTY 0xFF
|
||||
#define CHEAT_TYPE_INTERNAL 0
|
||||
#define CHEAT_TYPE_AR 1
|
||||
#define CHEAT_TYPE_CODEBREAKER 2
|
||||
|
||||
struct CHEATS_LIST
|
||||
{
|
||||
CHEATS_LIST()
|
||||
{
|
||||
memset(this,0,sizeof(*this));
|
||||
type = 0xFF;
|
||||
}
|
||||
u8 type;
|
||||
BOOL enabled;
|
||||
// TODO
|
||||
u8 freezeType; // 0 - normal freeze
|
||||
// 1 - can decrease
|
||||
// 2 - can increase
|
||||
u32 code[MAX_XX_CODE][2];
|
||||
char description[1024];
|
||||
int num;
|
||||
u8 size;
|
||||
};
|
||||
|
||||
class CHEATS
|
||||
{
|
||||
private:
|
||||
std::vector<CHEATS_LIST> list;
|
||||
u8 filename[MAX_PATH];
|
||||
u32 currentGet;
|
||||
|
||||
void clear();
|
||||
void ARparser(CHEATS_LIST& cheat);
|
||||
char *clearCode(char *s);
|
||||
|
||||
public:
|
||||
CHEATS()
|
||||
: currentGet(0)
|
||||
{
|
||||
memset(filename, 0, sizeof(filename));
|
||||
}
|
||||
~CHEATS() {}
|
||||
|
||||
void init(char *path);
|
||||
BOOL add(u8 size, u32 address, u32 val, char *description, BOOL enabled);
|
||||
BOOL update(u8 size, u32 address, u32 val, char *description, BOOL enabled, u32 pos);
|
||||
BOOL add_AR(char *code, char *description, BOOL enabled);
|
||||
BOOL update_AR(char *code, char *description, BOOL enabled, u32 pos);
|
||||
BOOL add_AR_Direct(CHEATS_LIST cheat);
|
||||
BOOL add_CB(char *code, char *description, BOOL enabled);
|
||||
BOOL update_CB(char *code, char *description, BOOL enabled, u32 pos);
|
||||
BOOL remove(u32 pos);
|
||||
void getListReset();
|
||||
BOOL getList(CHEATS_LIST *cheat);
|
||||
CHEATS_LIST* getListPtr();
|
||||
BOOL get(CHEATS_LIST *cheat, u32 pos);
|
||||
CHEATS_LIST* getItemByIndex(const u32 pos);
|
||||
u32 getSize();
|
||||
size_t getActiveCount();
|
||||
void setDescription(const char *description, u32 pos);
|
||||
BOOL save();
|
||||
BOOL load();
|
||||
void process(int targetType);
|
||||
void getXXcodeString(CHEATS_LIST cheat, char *res_buf);
|
||||
|
||||
static BOOL XXCodeFromString(CHEATS_LIST *cheatItem, const std::string codeString);
|
||||
static BOOL XXCodeFromString(CHEATS_LIST *cheatItem, const char *codeString);
|
||||
};
|
||||
|
||||
class CHEATSEARCH
|
||||
{
|
||||
private:
|
||||
u8 *statMem;
|
||||
u8 *mem;
|
||||
u32 amount;
|
||||
u32 lastRecord;
|
||||
|
||||
u32 _type;
|
||||
u32 _size;
|
||||
u32 _sign;
|
||||
|
||||
public:
|
||||
CHEATSEARCH()
|
||||
: statMem(0), mem(0), amount(0), lastRecord(0), _type(0), _size(0), _sign(0)
|
||||
{}
|
||||
~CHEATSEARCH() { close(); }
|
||||
BOOL start(u8 type, u8 size, u8 sign);
|
||||
BOOL close();
|
||||
u32 search(u32 val);
|
||||
u32 search(u8 comp);
|
||||
u32 getAmount();
|
||||
BOOL getList(u32 *address, u32 *curVal);
|
||||
void getListReset();
|
||||
};
|
||||
|
||||
enum CHEATS_DB_TYPE
|
||||
{
|
||||
CHEATS_DB_R4 = 0
|
||||
};
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
typedef struct FAT_R4
|
||||
{
|
||||
u8 serial[4];
|
||||
u32 CRC;
|
||||
u64 addr;
|
||||
} FAT_R4;
|
||||
#pragma pack(pop)
|
||||
|
||||
class CHEATSEXPORT
|
||||
{
|
||||
private:
|
||||
CHEATS_DB_TYPE type;
|
||||
bool encrypted;
|
||||
FILE *fp;
|
||||
u32 fsize;
|
||||
u32 dataSize;
|
||||
u32 encOffset;
|
||||
FAT_R4 fat;
|
||||
bool search();
|
||||
bool getCodes();
|
||||
void R4decrypt(u8 *buf, u32 len, u32 n);
|
||||
|
||||
u32 numCheats;
|
||||
CHEATS_LIST *cheats;
|
||||
|
||||
u8 error; // 0 - no errors
|
||||
// 1 - open failed/file not found
|
||||
// 2 - file format is wrong (no valid header ID)
|
||||
// 3 - cheat not found in database
|
||||
// 4 - export error from database
|
||||
|
||||
public:
|
||||
CHEATSEXPORT() :
|
||||
fp(NULL),
|
||||
fsize(0),
|
||||
dataSize(0),
|
||||
encOffset(0),
|
||||
type(CHEATS_DB_R4),
|
||||
encrypted(false),
|
||||
numCheats(0),
|
||||
cheats(0),
|
||||
CRC(0),
|
||||
error(0)
|
||||
{
|
||||
memset(date, 0, sizeof(date));
|
||||
gametitle = (u8 *)malloc(CHEAT_DB_GAME_TITLE_SIZE);
|
||||
memset(gametitle, 0, CHEAT_DB_GAME_TITLE_SIZE);
|
||||
}
|
||||
~CHEATSEXPORT()
|
||||
{
|
||||
free(gametitle);
|
||||
gametitle = NULL;
|
||||
}
|
||||
|
||||
u8 *gametitle;
|
||||
u8 date[17];
|
||||
u32 CRC;
|
||||
bool load(char *path);
|
||||
void close();
|
||||
CHEATS_LIST *getCheats();
|
||||
u32 getCheatsNum();
|
||||
u8 getErrorCode() { return error; }
|
||||
};
|
||||
|
||||
extern CHEATS *cheats;
|
||||
extern CHEATSEARCH *cheatSearch;
|
||||
|
||||
|
||||
|
|
|
@ -1,70 +1,70 @@
|
|||
/* Copyright (C) 2007 Jeff Bland
|
||||
|
||||
This file is part of DeSmuME
|
||||
|
||||
DeSmuME is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
DeSmuME is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with DeSmuME; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
/* The main window class instanciates an input object,
|
||||
and places it after the window in the responder chain, so
|
||||
any events not handled by a the window get sent here.
|
||||
*/
|
||||
|
||||
@class VideoOutputWindow;
|
||||
@class CocoaDSController;
|
||||
|
||||
|
||||
@interface ControlsDelegate : NSObject {}
|
||||
|
||||
+ (id)sharedObject;
|
||||
|
||||
@end
|
||||
|
||||
@interface InputHandler : NSResponder
|
||||
{
|
||||
@private
|
||||
VideoOutputWindow *my_ds;
|
||||
CocoaDSController *cdsController;
|
||||
}
|
||||
//preferences
|
||||
+ (NSView*)createPreferencesView:(float)width;
|
||||
+ (NSDictionary*)appDefaults;
|
||||
|
||||
//creation/deletion
|
||||
- (id) initWithCdsController:(CocoaDSController *)theController;
|
||||
|
||||
- (void) setCdsController:(CocoaDSController *)theController;
|
||||
- (CocoaDSController *) cdsController;
|
||||
|
||||
//keyboard input
|
||||
- (void)keyDown:(NSEvent*)event;
|
||||
- (void)keyUp:(NSEvent*)event;
|
||||
|
||||
@end
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
int testKey(NSString *chars_pressed, NSString *chars_for_key);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Copyright (C) 2007 Jeff Bland
|
||||
|
||||
This file is part of DeSmuME
|
||||
|
||||
DeSmuME is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
DeSmuME is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with DeSmuME; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
/* The main window class instanciates an input object,
|
||||
and places it after the window in the responder chain, so
|
||||
any events not handled by a the window get sent here.
|
||||
*/
|
||||
|
||||
@class VideoOutputWindow;
|
||||
@class CocoaDSController;
|
||||
|
||||
|
||||
@interface ControlsDelegate : NSObject {}
|
||||
|
||||
+ (id)sharedObject;
|
||||
|
||||
@end
|
||||
|
||||
@interface InputHandler : NSResponder
|
||||
{
|
||||
@private
|
||||
VideoOutputWindow *my_ds;
|
||||
CocoaDSController *cdsController;
|
||||
}
|
||||
//preferences
|
||||
+ (NSView*)createPreferencesView:(float)width;
|
||||
+ (NSDictionary*)appDefaults;
|
||||
|
||||
//creation/deletion
|
||||
- (id) initWithCdsController:(CocoaDSController *)theController;
|
||||
|
||||
- (void) setCdsController:(CocoaDSController *)theController;
|
||||
- (CocoaDSController *) cdsController;
|
||||
|
||||
//keyboard input
|
||||
- (void)keyDown:(NSEvent*)event;
|
||||
- (void)keyUp:(NSEvent*)event;
|
||||
|
||||
@end
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
int testKey(NSString *chars_pressed, NSString *chars_for_key);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -1,46 +1,46 @@
|
|||
/*
|
||||
Copyright (C) 2007 Jeff Bland
|
||||
Copyright (C) 2007-2014 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _OSXSOUNDINTERFACE_
|
||||
#define _OSXSOUNDINTERFACE_
|
||||
|
||||
#include <pthread.h>
|
||||
#include "../SPU.h"
|
||||
#undef BOOL
|
||||
|
||||
#define SNDCORE_OSX 58325 //hopefully this is unique number
|
||||
|
||||
extern SoundInterface_struct SNDOSX; // Sound interface to the SPU
|
||||
extern pthread_rwlock_t *rwlockAudioEmulateCore; // RWlock for the emulation core - used when mixing audio in Dual Synch/Asynch mode in post-process
|
||||
|
||||
// Core Audio functions for the sound interface
|
||||
int SNDOSXInit(int buffer_size);
|
||||
void SNDOSXDeInit();
|
||||
int SNDOSXReset();
|
||||
void SNDOSXUpdateAudio(s16 *buffer, u32 num_samples);
|
||||
u32 SNDOSXGetAudioSpace();
|
||||
void SNDOSXMuteAudio();
|
||||
void SNDOSXUnMuteAudio();
|
||||
void SNDOSXPauseAudio();
|
||||
void SNDOSXUnpauseAudio();
|
||||
void SNDOSXSetVolume(int volume);
|
||||
void SNDOSXClearBuffer();
|
||||
void SNDOSXFetchSamples(s16 *sampleBuffer, size_t sampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer);
|
||||
size_t SNDOSXPostProcessSamples(s16 *postProcessBuffer, size_t requestedSampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer);
|
||||
|
||||
#endif // _OSXSOUNDINTERFACE_
|
||||
/*
|
||||
Copyright (C) 2007 Jeff Bland
|
||||
Copyright (C) 2007-2014 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _OSXSOUNDINTERFACE_
|
||||
#define _OSXSOUNDINTERFACE_
|
||||
|
||||
#include <pthread.h>
|
||||
#include "../SPU.h"
|
||||
#undef BOOL
|
||||
|
||||
#define SNDCORE_OSX 58325 //hopefully this is unique number
|
||||
|
||||
extern SoundInterface_struct SNDOSX; // Sound interface to the SPU
|
||||
extern pthread_rwlock_t *rwlockAudioEmulateCore; // RWlock for the emulation core - used when mixing audio in Dual Synch/Asynch mode in post-process
|
||||
|
||||
// Core Audio functions for the sound interface
|
||||
int SNDOSXInit(int buffer_size);
|
||||
void SNDOSXDeInit();
|
||||
int SNDOSXReset();
|
||||
void SNDOSXUpdateAudio(s16 *buffer, u32 num_samples);
|
||||
u32 SNDOSXGetAudioSpace();
|
||||
void SNDOSXMuteAudio();
|
||||
void SNDOSXUnMuteAudio();
|
||||
void SNDOSXPauseAudio();
|
||||
void SNDOSXUnpauseAudio();
|
||||
void SNDOSXSetVolume(int volume);
|
||||
void SNDOSXClearBuffer();
|
||||
void SNDOSXFetchSamples(s16 *sampleBuffer, size_t sampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer);
|
||||
size_t SNDOSXPostProcessSamples(s16 *postProcessBuffer, size_t requestedSampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer);
|
||||
|
||||
#endif // _OSXSOUNDINTERFACE_
|
||||
|
|
|
@ -1,96 +1,96 @@
|
|||
/*
|
||||
Copyright (C) 2008-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
//TODO - dismantle this file
|
||||
|
||||
#ifndef _COMMON_H_
|
||||
#define _COMMON_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include "types.h"
|
||||
|
||||
#if defined(WIN32)
|
||||
#define CLASSNAME "DeSmuME"
|
||||
#else // non Windows
|
||||
#define sscanf_s sscanf
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
T reverseBits(T x)
|
||||
{
|
||||
T h = 0;
|
||||
T i = 0;
|
||||
|
||||
for (i = 0; i < sizeof(T)*8; i++)
|
||||
{
|
||||
h = (h << 1) + (x & 1);
|
||||
x >>= 1;
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
char *intToBin(T val)
|
||||
{
|
||||
char buf[256] = {0};
|
||||
for (int i = sizeof(T)*8, t = 0; i > 0; --i, t++)
|
||||
{
|
||||
buf[i-1] = (val & (1<<t))?'1':'0';
|
||||
}
|
||||
return strdup(buf);
|
||||
}
|
||||
|
||||
extern char *trim(char *s, int len=-1);
|
||||
extern char *removeSpecialChars(char *s);
|
||||
|
||||
// ===============================================================================
|
||||
// Message dialogs
|
||||
// ===============================================================================
|
||||
#define CALL_CONVENTION
|
||||
typedef struct
|
||||
{
|
||||
void (CALL_CONVENTION* info) (const char *fmt, ...);
|
||||
bool (CALL_CONVENTION* confirm)(const char *fmt, ...);
|
||||
void (CALL_CONVENTION* error) (const char *fmt, ...);
|
||||
void (CALL_CONVENTION* warn) (const char *fmt, ...);
|
||||
} msgBoxInterface;
|
||||
|
||||
extern msgBoxInterface *msgbox;
|
||||
|
||||
// ===============================================================================
|
||||
// Maker codes
|
||||
// ===============================================================================
|
||||
|
||||
struct MAKER
|
||||
{
|
||||
u16 code;
|
||||
const char* name;
|
||||
};
|
||||
|
||||
std::string getDeveloperNameByID(u16 id);
|
||||
|
||||
void* malloc_aligned(size_t length, size_t alignment);
|
||||
void* malloc_aligned16(size_t length);
|
||||
void* malloc_aligned32(size_t length);
|
||||
void* malloc_aligned64(size_t length);
|
||||
void* malloc_alignedCacheLine(size_t length);
|
||||
void free_aligned(void *ptr);
|
||||
|
||||
#endif
|
||||
/*
|
||||
Copyright (C) 2008-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
//TODO - dismantle this file
|
||||
|
||||
#ifndef _COMMON_H_
|
||||
#define _COMMON_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include "types.h"
|
||||
|
||||
#if defined(WIN32)
|
||||
#define CLASSNAME "DeSmuME"
|
||||
#else // non Windows
|
||||
#define sscanf_s sscanf
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
T reverseBits(T x)
|
||||
{
|
||||
T h = 0;
|
||||
T i = 0;
|
||||
|
||||
for (i = 0; i < sizeof(T)*8; i++)
|
||||
{
|
||||
h = (h << 1) + (x & 1);
|
||||
x >>= 1;
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
char *intToBin(T val)
|
||||
{
|
||||
char buf[256] = {0};
|
||||
for (int i = sizeof(T)*8, t = 0; i > 0; --i, t++)
|
||||
{
|
||||
buf[i-1] = (val & (1<<t))?'1':'0';
|
||||
}
|
||||
return strdup(buf);
|
||||
}
|
||||
|
||||
extern char *trim(char *s, int len=-1);
|
||||
extern char *removeSpecialChars(char *s);
|
||||
|
||||
// ===============================================================================
|
||||
// Message dialogs
|
||||
// ===============================================================================
|
||||
#define CALL_CONVENTION
|
||||
typedef struct
|
||||
{
|
||||
void (CALL_CONVENTION* info) (const char *fmt, ...);
|
||||
bool (CALL_CONVENTION* confirm)(const char *fmt, ...);
|
||||
void (CALL_CONVENTION* error) (const char *fmt, ...);
|
||||
void (CALL_CONVENTION* warn) (const char *fmt, ...);
|
||||
} msgBoxInterface;
|
||||
|
||||
extern msgBoxInterface *msgbox;
|
||||
|
||||
// ===============================================================================
|
||||
// Maker codes
|
||||
// ===============================================================================
|
||||
|
||||
struct MAKER
|
||||
{
|
||||
u16 code;
|
||||
const char* name;
|
||||
};
|
||||
|
||||
std::string getDeveloperNameByID(u16 id);
|
||||
|
||||
void* malloc_aligned(size_t length, size_t alignment);
|
||||
void* malloc_aligned16(size_t length);
|
||||
void* malloc_aligned32(size_t length);
|
||||
void* malloc_aligned64(size_t length);
|
||||
void* malloc_alignedCacheLine(size_t length);
|
||||
void free_aligned(void *ptr);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,131 +1,131 @@
|
|||
/*
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2006-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __CP15_H__
|
||||
#define __CP15_H__
|
||||
|
||||
#include <string.h>
|
||||
#include "types.h"
|
||||
|
||||
class EMUFILE;
|
||||
|
||||
#define CP15_ACCESS_WRITE 0
|
||||
#define CP15_ACCESS_READ 2
|
||||
#define CP15_ACCESS_EXECUTE 4
|
||||
#define CP15_ACCESS_WRITEUSR CP15_ACCESS_WRITE
|
||||
#define CP15_ACCESS_WRITESYS 1
|
||||
#define CP15_ACCESS_READUSR CP15_ACCESS_READ
|
||||
#define CP15_ACCESS_READSYS 3
|
||||
#define CP15_ACCESS_EXECUSR CP15_ACCESS_EXECUTE
|
||||
#define CP15_ACCESS_EXECSYS 5
|
||||
|
||||
#define CP15_SIZEBINARY(val) (1 << (CP15_SIZEIDENTIFIER(val)+1))
|
||||
#define CP15_SIZEIDENTIFIER(val) ((((val) >> 1) & 0x1F))
|
||||
#define CP15_MASKFROMREG(val) (~((CP15_SIZEBINARY(val)-1) | 0x3F))
|
||||
#define CP15_SETFROMREG(val) ((val) & CP15_MASKFROMREG(val))
|
||||
|
||||
struct armcp15_t
|
||||
{
|
||||
public:
|
||||
u32 IDCode;
|
||||
u32 cacheType;
|
||||
u32 TCMSize;
|
||||
u32 ctrl;
|
||||
u32 DCConfig;
|
||||
u32 ICConfig;
|
||||
u32 writeBuffCtrl;
|
||||
u32 und;
|
||||
u32 DaccessPerm;
|
||||
u32 IaccessPerm;
|
||||
u32 protectBaseSize[8];
|
||||
u32 cacheOp;
|
||||
u32 DcacheLock;
|
||||
u32 IcacheLock;
|
||||
u32 ITCMRegion;
|
||||
u32 DTCMRegion;
|
||||
u32 processID;
|
||||
u32 RAM_TAG;
|
||||
u32 testState;
|
||||
u32 cacheDbg;
|
||||
/* calculated bitmasks for the regions to decide rights uppon */
|
||||
/* calculation is done in the MCR instead of on mem access for performance */
|
||||
u32 regionWriteMask_USR[8] ;
|
||||
u32 regionWriteMask_SYS[8] ;
|
||||
u32 regionReadMask_USR[8] ;
|
||||
u32 regionReadMask_SYS[8] ;
|
||||
u32 regionExecuteMask_USR[8] ;
|
||||
u32 regionExecuteMask_SYS[8] ;
|
||||
u32 regionWriteSet_USR[8] ;
|
||||
u32 regionWriteSet_SYS[8] ;
|
||||
u32 regionReadSet_USR[8] ;
|
||||
u32 regionReadSet_SYS[8] ;
|
||||
u32 regionExecuteSet_USR[8] ;
|
||||
u32 regionExecuteSet_SYS[8] ;
|
||||
|
||||
void setSingleRegionAccess(u8 num, u32 mask, u32 set);
|
||||
void maskPrecalc();
|
||||
|
||||
public:
|
||||
armcp15_t() : IDCode(0x41059461),
|
||||
cacheType(0x0F0D2112),
|
||||
TCMSize(0x00140180),
|
||||
ctrl(0x00012078),
|
||||
DCConfig(0),
|
||||
ICConfig(0),
|
||||
writeBuffCtrl(0),
|
||||
und(0),
|
||||
DaccessPerm(0x22222222),
|
||||
IaccessPerm(0x22222222),
|
||||
cacheOp(0),
|
||||
DcacheLock(0),
|
||||
IcacheLock(0),
|
||||
ITCMRegion(0x0C),
|
||||
DTCMRegion(0x0080000A),
|
||||
processID(0),
|
||||
RAM_TAG(0),
|
||||
testState(0),
|
||||
cacheDbg(0)
|
||||
{
|
||||
//printf("CP15 Reset\n");
|
||||
memset(&protectBaseSize[0], 0, sizeof(protectBaseSize));
|
||||
memset(®ionWriteMask_USR[0], 0, sizeof(regionWriteMask_USR));
|
||||
memset(®ionWriteMask_SYS[0], 0, sizeof(regionWriteMask_SYS));
|
||||
memset(®ionReadMask_USR[0], 0, sizeof(regionReadMask_USR));
|
||||
memset(®ionReadMask_SYS[0], 0, sizeof(regionReadMask_SYS));
|
||||
memset(®ionExecuteMask_USR[0], 0, sizeof(regionExecuteMask_USR));
|
||||
memset(®ionExecuteMask_SYS[0], 0, sizeof(regionExecuteMask_SYS));
|
||||
memset(®ionWriteSet_USR[0], 0, sizeof(regionWriteSet_USR));
|
||||
memset(®ionWriteSet_SYS[0], 0, sizeof(regionWriteSet_SYS));
|
||||
memset(®ionReadSet_USR[0], 0, sizeof(regionReadSet_USR));
|
||||
memset(®ionReadSet_SYS[0], 0, sizeof(regionReadSet_SYS));
|
||||
memset(®ionExecuteSet_USR[0], 0, sizeof(regionExecuteSet_USR));
|
||||
memset(®ionExecuteSet_SYS[0], 0, sizeof(regionExecuteSet_SYS));
|
||||
}
|
||||
BOOL dataProcess(u8 CRd, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2);
|
||||
BOOL load(u8 CRd, u8 adr);
|
||||
BOOL store(u8 CRd, u8 adr);
|
||||
BOOL moveCP2ARM(u32 * R, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2);
|
||||
BOOL moveARM2CP(u32 val, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2);
|
||||
BOOL isAccessAllowed(u32 address,u32 access);
|
||||
// savestate
|
||||
void saveone(EMUFILE* os);
|
||||
bool loadone(EMUFILE* is);
|
||||
};
|
||||
|
||||
extern armcp15_t cp15;
|
||||
#endif /* __CP15_H__*/
|
||||
/*
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2006-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __CP15_H__
|
||||
#define __CP15_H__
|
||||
|
||||
#include <string.h>
|
||||
#include "types.h"
|
||||
|
||||
class EMUFILE;
|
||||
|
||||
#define CP15_ACCESS_WRITE 0
|
||||
#define CP15_ACCESS_READ 2
|
||||
#define CP15_ACCESS_EXECUTE 4
|
||||
#define CP15_ACCESS_WRITEUSR CP15_ACCESS_WRITE
|
||||
#define CP15_ACCESS_WRITESYS 1
|
||||
#define CP15_ACCESS_READUSR CP15_ACCESS_READ
|
||||
#define CP15_ACCESS_READSYS 3
|
||||
#define CP15_ACCESS_EXECUSR CP15_ACCESS_EXECUTE
|
||||
#define CP15_ACCESS_EXECSYS 5
|
||||
|
||||
#define CP15_SIZEBINARY(val) (1 << (CP15_SIZEIDENTIFIER(val)+1))
|
||||
#define CP15_SIZEIDENTIFIER(val) ((((val) >> 1) & 0x1F))
|
||||
#define CP15_MASKFROMREG(val) (~((CP15_SIZEBINARY(val)-1) | 0x3F))
|
||||
#define CP15_SETFROMREG(val) ((val) & CP15_MASKFROMREG(val))
|
||||
|
||||
struct armcp15_t
|
||||
{
|
||||
public:
|
||||
u32 IDCode;
|
||||
u32 cacheType;
|
||||
u32 TCMSize;
|
||||
u32 ctrl;
|
||||
u32 DCConfig;
|
||||
u32 ICConfig;
|
||||
u32 writeBuffCtrl;
|
||||
u32 und;
|
||||
u32 DaccessPerm;
|
||||
u32 IaccessPerm;
|
||||
u32 protectBaseSize[8];
|
||||
u32 cacheOp;
|
||||
u32 DcacheLock;
|
||||
u32 IcacheLock;
|
||||
u32 ITCMRegion;
|
||||
u32 DTCMRegion;
|
||||
u32 processID;
|
||||
u32 RAM_TAG;
|
||||
u32 testState;
|
||||
u32 cacheDbg;
|
||||
/* calculated bitmasks for the regions to decide rights uppon */
|
||||
/* calculation is done in the MCR instead of on mem access for performance */
|
||||
u32 regionWriteMask_USR[8] ;
|
||||
u32 regionWriteMask_SYS[8] ;
|
||||
u32 regionReadMask_USR[8] ;
|
||||
u32 regionReadMask_SYS[8] ;
|
||||
u32 regionExecuteMask_USR[8] ;
|
||||
u32 regionExecuteMask_SYS[8] ;
|
||||
u32 regionWriteSet_USR[8] ;
|
||||
u32 regionWriteSet_SYS[8] ;
|
||||
u32 regionReadSet_USR[8] ;
|
||||
u32 regionReadSet_SYS[8] ;
|
||||
u32 regionExecuteSet_USR[8] ;
|
||||
u32 regionExecuteSet_SYS[8] ;
|
||||
|
||||
void setSingleRegionAccess(u8 num, u32 mask, u32 set);
|
||||
void maskPrecalc();
|
||||
|
||||
public:
|
||||
armcp15_t() : IDCode(0x41059461),
|
||||
cacheType(0x0F0D2112),
|
||||
TCMSize(0x00140180),
|
||||
ctrl(0x00012078),
|
||||
DCConfig(0),
|
||||
ICConfig(0),
|
||||
writeBuffCtrl(0),
|
||||
und(0),
|
||||
DaccessPerm(0x22222222),
|
||||
IaccessPerm(0x22222222),
|
||||
cacheOp(0),
|
||||
DcacheLock(0),
|
||||
IcacheLock(0),
|
||||
ITCMRegion(0x0C),
|
||||
DTCMRegion(0x0080000A),
|
||||
processID(0),
|
||||
RAM_TAG(0),
|
||||
testState(0),
|
||||
cacheDbg(0)
|
||||
{
|
||||
//printf("CP15 Reset\n");
|
||||
memset(&protectBaseSize[0], 0, sizeof(protectBaseSize));
|
||||
memset(®ionWriteMask_USR[0], 0, sizeof(regionWriteMask_USR));
|
||||
memset(®ionWriteMask_SYS[0], 0, sizeof(regionWriteMask_SYS));
|
||||
memset(®ionReadMask_USR[0], 0, sizeof(regionReadMask_USR));
|
||||
memset(®ionReadMask_SYS[0], 0, sizeof(regionReadMask_SYS));
|
||||
memset(®ionExecuteMask_USR[0], 0, sizeof(regionExecuteMask_USR));
|
||||
memset(®ionExecuteMask_SYS[0], 0, sizeof(regionExecuteMask_SYS));
|
||||
memset(®ionWriteSet_USR[0], 0, sizeof(regionWriteSet_USR));
|
||||
memset(®ionWriteSet_SYS[0], 0, sizeof(regionWriteSet_SYS));
|
||||
memset(®ionReadSet_USR[0], 0, sizeof(regionReadSet_USR));
|
||||
memset(®ionReadSet_SYS[0], 0, sizeof(regionReadSet_SYS));
|
||||
memset(®ionExecuteSet_USR[0], 0, sizeof(regionExecuteSet_USR));
|
||||
memset(®ionExecuteSet_SYS[0], 0, sizeof(regionExecuteSet_SYS));
|
||||
}
|
||||
BOOL dataProcess(u8 CRd, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2);
|
||||
BOOL load(u8 CRd, u8 adr);
|
||||
BOOL store(u8 CRd, u8 adr);
|
||||
BOOL moveCP2ARM(u32 * R, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2);
|
||||
BOOL moveARM2CP(u32 val, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2);
|
||||
BOOL isAccessAllowed(u32 address,u32 access);
|
||||
// savestate
|
||||
void saveone(EMUFILE* os);
|
||||
bool loadone(EMUFILE* is);
|
||||
};
|
||||
|
||||
extern armcp15_t cp15;
|
||||
#endif /* __CP15_H__*/
|
||||
|
|
|
@ -1,119 +1,119 @@
|
|||
/*
|
||||
Copyright (C) 2007 Pascal Giard
|
||||
Copyright (C) 2007-2011 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CTRLSSDL_H
|
||||
#define CTRLSSDL_H
|
||||
|
||||
#ifdef HAVE_GL_GL_H
|
||||
#include <GL/gl.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <SDL.h>
|
||||
#include "MMU.h"
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define ADD_KEY(keypad,key) ( (keypad) |= (key) )
|
||||
#define RM_KEY(keypad,key) ( (keypad) &= ~(key) )
|
||||
#define KEYMASK_(k) (1 << (k))
|
||||
|
||||
#define JOY_AXIS 0
|
||||
#define JOY_HAT 1
|
||||
#define JOY_BUTTON 2
|
||||
|
||||
#define JOY_HAT_RIGHT 0
|
||||
#define JOY_HAT_LEFT 1
|
||||
#define JOY_HAT_UP 2
|
||||
#define JOY_HAT_DOWN 3
|
||||
|
||||
#define NB_KEYS 15
|
||||
#define KEY_NONE 0
|
||||
#define KEY_A 1
|
||||
#define KEY_B 2
|
||||
#define KEY_SELECT 3
|
||||
#define KEY_START 4
|
||||
#define KEY_RIGHT 5
|
||||
#define KEY_LEFT 6
|
||||
#define KEY_UP 7
|
||||
#define KEY_DOWN 8
|
||||
#define KEY_R 9
|
||||
#define KEY_L 10
|
||||
#define KEY_X 11
|
||||
#define KEY_Y 12
|
||||
#define KEY_DEBUG 13
|
||||
#define KEY_BOOST 14
|
||||
#define KEY_LID 15
|
||||
|
||||
/* Keypad key names */
|
||||
extern const char *key_names[NB_KEYS];
|
||||
/* Current keyboard configuration */
|
||||
extern u16 keyboard_cfg[NB_KEYS];
|
||||
/* Current joypad configuration */
|
||||
extern u16 joypad_cfg[NB_KEYS];
|
||||
/* Number of detected joypads */
|
||||
extern u16 nbr_joy;
|
||||
|
||||
#ifndef GTK_UI
|
||||
struct mouse_status
|
||||
{
|
||||
signed long x;
|
||||
signed long y;
|
||||
BOOL click;
|
||||
BOOL down;
|
||||
};
|
||||
|
||||
extern mouse_status mouse;
|
||||
#endif // !GTK_UI
|
||||
|
||||
struct ctrls_event_config {
|
||||
unsigned short keypad;
|
||||
float nds_screen_size_ratio;
|
||||
int auto_pause;
|
||||
int focused;
|
||||
int sdl_quit;
|
||||
int boost;
|
||||
int fake_mic;
|
||||
#ifdef HAVE_GL_GL_H
|
||||
GLuint *screen_texture;
|
||||
void (*resize_cb)(u16 width, u16 height, GLuint *screen_texture);
|
||||
#else
|
||||
void *screen_texture;
|
||||
void (*resize_cb)(u16 width, u16 height, void *screen_texture);
|
||||
#endif
|
||||
};
|
||||
|
||||
void load_default_config(const u16 kbCfg[]);
|
||||
BOOL init_joy( void);
|
||||
void uninit_joy( void);
|
||||
u16 get_joy_key(int index);
|
||||
u16 get_set_joy_key(int index);
|
||||
void update_keypad(u16 keys);
|
||||
u16 get_keypad( void);
|
||||
u16 lookup_key (u16 keyval);
|
||||
u16 lookup_joy_key (u16 keyval);
|
||||
void
|
||||
process_ctrls_event( SDL_Event& event,
|
||||
struct ctrls_event_config *cfg);
|
||||
|
||||
void
|
||||
process_joystick_events( u16 *keypad);
|
||||
|
||||
#endif /* CTRLSSDL_H */
|
||||
/*
|
||||
Copyright (C) 2007 Pascal Giard
|
||||
Copyright (C) 2007-2011 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CTRLSSDL_H
|
||||
#define CTRLSSDL_H
|
||||
|
||||
#ifdef HAVE_GL_GL_H
|
||||
#include <GL/gl.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <SDL.h>
|
||||
#include "MMU.h"
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define ADD_KEY(keypad,key) ( (keypad) |= (key) )
|
||||
#define RM_KEY(keypad,key) ( (keypad) &= ~(key) )
|
||||
#define KEYMASK_(k) (1 << (k))
|
||||
|
||||
#define JOY_AXIS 0
|
||||
#define JOY_HAT 1
|
||||
#define JOY_BUTTON 2
|
||||
|
||||
#define JOY_HAT_RIGHT 0
|
||||
#define JOY_HAT_LEFT 1
|
||||
#define JOY_HAT_UP 2
|
||||
#define JOY_HAT_DOWN 3
|
||||
|
||||
#define NB_KEYS 15
|
||||
#define KEY_NONE 0
|
||||
#define KEY_A 1
|
||||
#define KEY_B 2
|
||||
#define KEY_SELECT 3
|
||||
#define KEY_START 4
|
||||
#define KEY_RIGHT 5
|
||||
#define KEY_LEFT 6
|
||||
#define KEY_UP 7
|
||||
#define KEY_DOWN 8
|
||||
#define KEY_R 9
|
||||
#define KEY_L 10
|
||||
#define KEY_X 11
|
||||
#define KEY_Y 12
|
||||
#define KEY_DEBUG 13
|
||||
#define KEY_BOOST 14
|
||||
#define KEY_LID 15
|
||||
|
||||
/* Keypad key names */
|
||||
extern const char *key_names[NB_KEYS];
|
||||
/* Current keyboard configuration */
|
||||
extern u16 keyboard_cfg[NB_KEYS];
|
||||
/* Current joypad configuration */
|
||||
extern u16 joypad_cfg[NB_KEYS];
|
||||
/* Number of detected joypads */
|
||||
extern u16 nbr_joy;
|
||||
|
||||
#ifndef GTK_UI
|
||||
struct mouse_status
|
||||
{
|
||||
signed long x;
|
||||
signed long y;
|
||||
BOOL click;
|
||||
BOOL down;
|
||||
};
|
||||
|
||||
extern mouse_status mouse;
|
||||
#endif // !GTK_UI
|
||||
|
||||
struct ctrls_event_config {
|
||||
unsigned short keypad;
|
||||
float nds_screen_size_ratio;
|
||||
int auto_pause;
|
||||
int focused;
|
||||
int sdl_quit;
|
||||
int boost;
|
||||
int fake_mic;
|
||||
#ifdef HAVE_GL_GL_H
|
||||
GLuint *screen_texture;
|
||||
void (*resize_cb)(u16 width, u16 height, GLuint *screen_texture);
|
||||
#else
|
||||
void *screen_texture;
|
||||
void (*resize_cb)(u16 width, u16 height, void *screen_texture);
|
||||
#endif
|
||||
};
|
||||
|
||||
void load_default_config(const u16 kbCfg[]);
|
||||
BOOL init_joy( void);
|
||||
void uninit_joy( void);
|
||||
u16 get_joy_key(int index);
|
||||
u16 get_set_joy_key(int index);
|
||||
void update_keypad(u16 keys);
|
||||
u16 get_keypad( void);
|
||||
u16 lookup_key (u16 keyval);
|
||||
u16 lookup_joy_key (u16 keyval);
|
||||
void
|
||||
process_ctrls_event( SDL_Event& event,
|
||||
struct ctrls_event_config *cfg);
|
||||
|
||||
void
|
||||
process_joystick_events( u16 *keypad);
|
||||
|
||||
#endif /* CTRLSSDL_H */
|
||||
|
|
|
@ -1,219 +1,219 @@
|
|||
/*
|
||||
Copyright (C) 2006 Guillaume Duhamel
|
||||
Copyright (C) 2006-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DEBUG_H
|
||||
#define DEBUG_H
|
||||
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <cstdarg>
|
||||
#include <bitset>
|
||||
|
||||
#include "types.h"
|
||||
#include "mem.h"
|
||||
|
||||
struct armcpu_t;
|
||||
class EMUFILE;
|
||||
|
||||
struct DebugStatistics
|
||||
{
|
||||
DebugStatistics();
|
||||
struct InstructionHits {
|
||||
InstructionHits();
|
||||
u32 thumb[1024];
|
||||
u32 arm[4096];
|
||||
} instructionHits[2]; //one for each cpu
|
||||
|
||||
s32 sequencerExecutionCounters[32];
|
||||
|
||||
void print();
|
||||
void printSequencerExecutionCounters();
|
||||
};
|
||||
|
||||
extern DebugStatistics DEBUG_statistics;
|
||||
|
||||
void DEBUG_reset();
|
||||
void DEBUG_dumpMemory(EMUFILE* fp);
|
||||
|
||||
struct armcpu_t;
|
||||
|
||||
class Logger {
|
||||
protected:
|
||||
void (*callback)(const Logger& logger, const char * format);
|
||||
std::ostream * out;
|
||||
unsigned int flags;
|
||||
|
||||
static std::vector<Logger *> channels;
|
||||
|
||||
static void fixSize(unsigned int channel);
|
||||
public:
|
||||
Logger();
|
||||
~Logger();
|
||||
|
||||
void vprintf(const char * format, va_list l, const char * filename, unsigned int line);
|
||||
void setOutput(std::ostream * o);
|
||||
void setCallback(void (*cback)(const Logger& logger, const char * message));
|
||||
void setFlag(unsigned int flag);
|
||||
|
||||
std::ostream& getOutput() const;
|
||||
|
||||
static const int LINE = 1;
|
||||
static const int FILE = 2;
|
||||
|
||||
static void log(unsigned int channel, const char * file, unsigned int line, const char * format, ...);
|
||||
static void log(unsigned int channel, const char * file, unsigned int line, std::ostream& os);
|
||||
static void log(unsigned int channel, const char * file, unsigned int line, unsigned int flag);
|
||||
static void log(unsigned int channel, const char * file, unsigned int line, void (*callback)(const Logger& logger, const char * message));
|
||||
};
|
||||
|
||||
#if defined(DEBUG) || defined(GPUDEBUG) || defined(DIVDEBUG) || defined(SQRTDEBUG) || defined(DMADEBUG) || defined(DEVELOPER)
|
||||
#define LOGC(channel, ...) Logger::log(channel, __FILE__, __LINE__, __VA_ARGS__)
|
||||
#else
|
||||
#define LOGC(...) {}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
#define LOG(...) LOGC(0, __VA_ARGS__)
|
||||
#else
|
||||
#define LOG(...) {}
|
||||
#endif
|
||||
|
||||
#ifdef GPUDEBUG
|
||||
#define GPULOG(...) LOGC(1, __VA_ARGS__)
|
||||
#else
|
||||
#define GPULOG(...) {}
|
||||
#endif
|
||||
|
||||
#ifdef DIVDEBUG
|
||||
#define DIVLOG(...) LOGC(2, __VA_ARGS__)
|
||||
#else
|
||||
#define DIVLOG(...) {}
|
||||
#endif
|
||||
|
||||
#ifdef SQRTDEBUG
|
||||
#define SQRTLOG(...) LOGC(3, __VA_ARGS__)
|
||||
#else
|
||||
#define SQRTLOG(...) {}
|
||||
#endif
|
||||
|
||||
#ifdef DMADEBUG
|
||||
#define DMALOG(...) LOGC(4, __VA_ARGS__)
|
||||
#else
|
||||
#define DMALOG(...) {}
|
||||
#endif
|
||||
|
||||
#ifdef CFLASHDEBUG
|
||||
#define CFLASHLOG(...) LOGC(5, __VA_ARGS__)
|
||||
#else
|
||||
#define CFLASHLOG(...) {}
|
||||
#endif
|
||||
|
||||
#ifdef UNTESTEDOPCODEDEBUG
|
||||
#define UNTESTEDOPCODELOG(...) LOGC(6, __VA_ARGS__)
|
||||
#else
|
||||
#define UNTESTEDOPCODELOG(...) {}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef DEVELOPER
|
||||
#define PROGINFO(...) LOGC(7, __VA_ARGS__)
|
||||
#else
|
||||
#define PROGINFO(...) {}
|
||||
#endif
|
||||
|
||||
|
||||
#define INFOC(channel, ...) Logger::log(channel, __FILE__, __LINE__, __VA_ARGS__)
|
||||
#define INFO(...) INFOC(10, __VA_ARGS__)
|
||||
|
||||
void IdeasLog(armcpu_t* cpu);
|
||||
void NocashMessage(armcpu_t* cpu, int offset);
|
||||
|
||||
enum EDEBUG_EVENT
|
||||
{
|
||||
DEBUG_EVENT_READ=1, //read from arm9 or arm7 bus, including cpu prefetch
|
||||
DEBUG_EVENT_WRITE=2, //write on arm9 or arm7 bus
|
||||
DEBUG_EVENT_EXECUTE=3, //prefetch on arm9 or arm7, triggered after the read event
|
||||
DEBUG_EVENT_ACL_EXCEPTION=4, //acl exception on arm9
|
||||
DEBUG_EVENT_CACHE_MISS=5, //cache miss on arm9
|
||||
};
|
||||
|
||||
enum EDEBUG_NOTIFY
|
||||
{
|
||||
DEBUG_NOTIFY_READ_BEYOND_END_OF_CART,
|
||||
DEBUG_NOTIFY_MAX
|
||||
};
|
||||
|
||||
class DebugNotify
|
||||
{
|
||||
public:
|
||||
void NextFrame();
|
||||
void ReadBeyondEndOfCart(u32 addr, u32 romsize);
|
||||
private:
|
||||
std::bitset<DEBUG_NOTIFY_MAX> pingBits;
|
||||
std::bitset<DEBUG_NOTIFY_MAX> enableBits;
|
||||
bool ping(EDEBUG_NOTIFY which);
|
||||
};
|
||||
|
||||
extern DebugNotify DEBUG_Notify;
|
||||
|
||||
//information about a debug event will be stuffed into here by the generator
|
||||
struct TDebugEventData
|
||||
{
|
||||
MMU_ACCESS_TYPE memAccessType;
|
||||
u32 procnum, addr, size, val;
|
||||
armcpu_t* cpu();
|
||||
};
|
||||
|
||||
extern TDebugEventData DebugEventData;
|
||||
|
||||
//bits in here are set according to what debug handlers are installed?
|
||||
//for now it is just a single bit
|
||||
extern u32 debugFlag;
|
||||
|
||||
FORCEINLINE bool CheckDebugEvent(EDEBUG_EVENT event)
|
||||
{
|
||||
//for now, debug events are only handled in dev+ builds
|
||||
#ifndef DEVELOPER
|
||||
return false;
|
||||
#endif
|
||||
|
||||
if(!debugFlag) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void HandleDebugEvent_Read();
|
||||
void HandleDebugEvent_Write();
|
||||
void HandleDebugEvent_Execute();
|
||||
void HandleDebugEvent_ACL_Exception();
|
||||
void HandleDebugEvent_CacheMiss();
|
||||
|
||||
inline void HandleDebugEvent(EDEBUG_EVENT event)
|
||||
{
|
||||
switch(event)
|
||||
{
|
||||
case DEBUG_EVENT_READ: HandleDebugEvent_Read(); return;
|
||||
case DEBUG_EVENT_WRITE: HandleDebugEvent_Write(); return;
|
||||
case DEBUG_EVENT_EXECUTE: HandleDebugEvent_Execute(); return;
|
||||
case DEBUG_EVENT_ACL_EXCEPTION: HandleDebugEvent_ACL_Exception(); return;
|
||||
case DEBUG_EVENT_CACHE_MISS: HandleDebugEvent_CacheMiss(); return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
/*
|
||||
Copyright (C) 2006 Guillaume Duhamel
|
||||
Copyright (C) 2006-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DEBUG_H
|
||||
#define DEBUG_H
|
||||
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <cstdarg>
|
||||
#include <bitset>
|
||||
|
||||
#include "types.h"
|
||||
#include "mem.h"
|
||||
|
||||
struct armcpu_t;
|
||||
class EMUFILE;
|
||||
|
||||
struct DebugStatistics
|
||||
{
|
||||
DebugStatistics();
|
||||
struct InstructionHits {
|
||||
InstructionHits();
|
||||
u32 thumb[1024];
|
||||
u32 arm[4096];
|
||||
} instructionHits[2]; //one for each cpu
|
||||
|
||||
s32 sequencerExecutionCounters[32];
|
||||
|
||||
void print();
|
||||
void printSequencerExecutionCounters();
|
||||
};
|
||||
|
||||
extern DebugStatistics DEBUG_statistics;
|
||||
|
||||
void DEBUG_reset();
|
||||
void DEBUG_dumpMemory(EMUFILE* fp);
|
||||
|
||||
struct armcpu_t;
|
||||
|
||||
class Logger {
|
||||
protected:
|
||||
void (*callback)(const Logger& logger, const char * format);
|
||||
std::ostream * out;
|
||||
unsigned int flags;
|
||||
|
||||
static std::vector<Logger *> channels;
|
||||
|
||||
static void fixSize(unsigned int channel);
|
||||
public:
|
||||
Logger();
|
||||
~Logger();
|
||||
|
||||
void vprintf(const char * format, va_list l, const char * filename, unsigned int line);
|
||||
void setOutput(std::ostream * o);
|
||||
void setCallback(void (*cback)(const Logger& logger, const char * message));
|
||||
void setFlag(unsigned int flag);
|
||||
|
||||
std::ostream& getOutput() const;
|
||||
|
||||
static const int LINE = 1;
|
||||
static const int FILE = 2;
|
||||
|
||||
static void log(unsigned int channel, const char * file, unsigned int line, const char * format, ...);
|
||||
static void log(unsigned int channel, const char * file, unsigned int line, std::ostream& os);
|
||||
static void log(unsigned int channel, const char * file, unsigned int line, unsigned int flag);
|
||||
static void log(unsigned int channel, const char * file, unsigned int line, void (*callback)(const Logger& logger, const char * message));
|
||||
};
|
||||
|
||||
#if defined(DEBUG) || defined(GPUDEBUG) || defined(DIVDEBUG) || defined(SQRTDEBUG) || defined(DMADEBUG) || defined(DEVELOPER)
|
||||
#define LOGC(channel, ...) Logger::log(channel, __FILE__, __LINE__, __VA_ARGS__)
|
||||
#else
|
||||
#define LOGC(...) {}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
#define LOG(...) LOGC(0, __VA_ARGS__)
|
||||
#else
|
||||
#define LOG(...) {}
|
||||
#endif
|
||||
|
||||
#ifdef GPUDEBUG
|
||||
#define GPULOG(...) LOGC(1, __VA_ARGS__)
|
||||
#else
|
||||
#define GPULOG(...) {}
|
||||
#endif
|
||||
|
||||
#ifdef DIVDEBUG
|
||||
#define DIVLOG(...) LOGC(2, __VA_ARGS__)
|
||||
#else
|
||||
#define DIVLOG(...) {}
|
||||
#endif
|
||||
|
||||
#ifdef SQRTDEBUG
|
||||
#define SQRTLOG(...) LOGC(3, __VA_ARGS__)
|
||||
#else
|
||||
#define SQRTLOG(...) {}
|
||||
#endif
|
||||
|
||||
#ifdef DMADEBUG
|
||||
#define DMALOG(...) LOGC(4, __VA_ARGS__)
|
||||
#else
|
||||
#define DMALOG(...) {}
|
||||
#endif
|
||||
|
||||
#ifdef CFLASHDEBUG
|
||||
#define CFLASHLOG(...) LOGC(5, __VA_ARGS__)
|
||||
#else
|
||||
#define CFLASHLOG(...) {}
|
||||
#endif
|
||||
|
||||
#ifdef UNTESTEDOPCODEDEBUG
|
||||
#define UNTESTEDOPCODELOG(...) LOGC(6, __VA_ARGS__)
|
||||
#else
|
||||
#define UNTESTEDOPCODELOG(...) {}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef DEVELOPER
|
||||
#define PROGINFO(...) LOGC(7, __VA_ARGS__)
|
||||
#else
|
||||
#define PROGINFO(...) {}
|
||||
#endif
|
||||
|
||||
|
||||
#define INFOC(channel, ...) Logger::log(channel, __FILE__, __LINE__, __VA_ARGS__)
|
||||
#define INFO(...) INFOC(10, __VA_ARGS__)
|
||||
|
||||
void IdeasLog(armcpu_t* cpu);
|
||||
void NocashMessage(armcpu_t* cpu, int offset);
|
||||
|
||||
enum EDEBUG_EVENT
|
||||
{
|
||||
DEBUG_EVENT_READ=1, //read from arm9 or arm7 bus, including cpu prefetch
|
||||
DEBUG_EVENT_WRITE=2, //write on arm9 or arm7 bus
|
||||
DEBUG_EVENT_EXECUTE=3, //prefetch on arm9 or arm7, triggered after the read event
|
||||
DEBUG_EVENT_ACL_EXCEPTION=4, //acl exception on arm9
|
||||
DEBUG_EVENT_CACHE_MISS=5, //cache miss on arm9
|
||||
};
|
||||
|
||||
enum EDEBUG_NOTIFY
|
||||
{
|
||||
DEBUG_NOTIFY_READ_BEYOND_END_OF_CART,
|
||||
DEBUG_NOTIFY_MAX
|
||||
};
|
||||
|
||||
class DebugNotify
|
||||
{
|
||||
public:
|
||||
void NextFrame();
|
||||
void ReadBeyondEndOfCart(u32 addr, u32 romsize);
|
||||
private:
|
||||
std::bitset<DEBUG_NOTIFY_MAX> pingBits;
|
||||
std::bitset<DEBUG_NOTIFY_MAX> enableBits;
|
||||
bool ping(EDEBUG_NOTIFY which);
|
||||
};
|
||||
|
||||
extern DebugNotify DEBUG_Notify;
|
||||
|
||||
//information about a debug event will be stuffed into here by the generator
|
||||
struct TDebugEventData
|
||||
{
|
||||
MMU_ACCESS_TYPE memAccessType;
|
||||
u32 procnum, addr, size, val;
|
||||
armcpu_t* cpu();
|
||||
};
|
||||
|
||||
extern TDebugEventData DebugEventData;
|
||||
|
||||
//bits in here are set according to what debug handlers are installed?
|
||||
//for now it is just a single bit
|
||||
extern u32 debugFlag;
|
||||
|
||||
FORCEINLINE bool CheckDebugEvent(EDEBUG_EVENT event)
|
||||
{
|
||||
//for now, debug events are only handled in dev+ builds
|
||||
#ifndef DEVELOPER
|
||||
return false;
|
||||
#endif
|
||||
|
||||
if(!debugFlag) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void HandleDebugEvent_Read();
|
||||
void HandleDebugEvent_Write();
|
||||
void HandleDebugEvent_Execute();
|
||||
void HandleDebugEvent_ACL_Exception();
|
||||
void HandleDebugEvent_CacheMiss();
|
||||
|
||||
inline void HandleDebugEvent(EDEBUG_EVENT event)
|
||||
{
|
||||
switch(event)
|
||||
{
|
||||
case DEBUG_EVENT_READ: HandleDebugEvent_Read(); return;
|
||||
case DEBUG_EVENT_WRITE: HandleDebugEvent_Write(); return;
|
||||
case DEBUG_EVENT_EXECUTE: HandleDebugEvent_Execute(); return;
|
||||
case DEBUG_EVENT_ACL_EXCEPTION: HandleDebugEvent_ACL_Exception(); return;
|
||||
case DEBUG_EVENT_CACHE_MISS: HandleDebugEvent_CacheMiss(); return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,29 +1,29 @@
|
|||
/*
|
||||
Copyright (C) 2009-2010 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _DESMUME_GTK_CONFIG
|
||||
#define _DESMUME_GTK_CONFIG
|
||||
|
||||
GKeyFile *desmume_config_read_file(const u16 *);
|
||||
void desmume_config_dispose(GKeyFile *);
|
||||
|
||||
gboolean desmume_config_update_keys(GKeyFile*);
|
||||
gboolean desmume_config_update_joykeys(GKeyFile*);
|
||||
gboolean desmume_config_read_keys(GKeyFile*);
|
||||
gboolean desmume_config_read_joykeys(GKeyFile*);
|
||||
|
||||
#endif
|
||||
/*
|
||||
Copyright (C) 2009-2010 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _DESMUME_GTK_CONFIG
|
||||
#define _DESMUME_GTK_CONFIG
|
||||
|
||||
GKeyFile *desmume_config_read_file(const u16 *);
|
||||
void desmume_config_dispose(GKeyFile *);
|
||||
|
||||
gboolean desmume_config_update_keys(GKeyFile*);
|
||||
gboolean desmume_config_update_joykeys(GKeyFile*);
|
||||
gboolean desmume_config_read_keys(GKeyFile*);
|
||||
gboolean desmume_config_read_joykeys(GKeyFile*);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
/*
|
||||
Copyright (C) 2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _DESMUME_IMAGEOUT_H_
|
||||
#define _DESMUME_IMAGEOUT_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
int NDS_WritePNG_15bpp(int width, int height, const u16 *data, const char *fname);
|
||||
int NDS_WriteBMP_15bpp(int width, int height, const u16 *data, const char *filename);
|
||||
int NDS_WriteBMP_32bppBuffer(int width, int height, const void* buf, const char *filename);
|
||||
|
||||
/*
|
||||
Copyright (C) 2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _DESMUME_IMAGEOUT_H_
|
||||
#define _DESMUME_IMAGEOUT_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
int NDS_WritePNG_15bpp(int width, int height, const u16 *data, const char *fname);
|
||||
int NDS_WriteBMP_15bpp(int width, int height, const u16 *data, const char *filename);
|
||||
int NDS_WriteBMP_32bppBuffer(int width, int height, const void* buf, const char *filename);
|
||||
|
||||
#endif
|
|
@ -1,43 +1,43 @@
|
|||
/*
|
||||
Copyright (C) 2006 Guillaume Duhamel
|
||||
Copyright (C) 2007-2010 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef FS_H
|
||||
#define FS_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define FS_IS_DIR 1
|
||||
|
||||
#define FS_ERR_UNKNOWN -1
|
||||
#define FS_ERR_NO_MORE_FILES 1
|
||||
|
||||
extern const char FS_SEPARATOR;
|
||||
|
||||
typedef struct {
|
||||
char cFileName[256];
|
||||
char cAlternateFileName[14];
|
||||
u32 flags;
|
||||
u32 fileSize;
|
||||
} FsEntry;
|
||||
|
||||
void * FsReadFirst(const char * path, FsEntry * entry);
|
||||
int FsReadNext(void * search, FsEntry * entry);
|
||||
void FsClose(void * search);
|
||||
int FsError(void);
|
||||
|
||||
#endif
|
||||
/*
|
||||
Copyright (C) 2006 Guillaume Duhamel
|
||||
Copyright (C) 2007-2010 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef FS_H
|
||||
#define FS_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define FS_IS_DIR 1
|
||||
|
||||
#define FS_ERR_UNKNOWN -1
|
||||
#define FS_ERR_NO_MORE_FILES 1
|
||||
|
||||
extern const char FS_SEPARATOR;
|
||||
|
||||
typedef struct {
|
||||
char cFileName[256];
|
||||
char cAlternateFileName[14];
|
||||
u32 flags;
|
||||
u32 fileSize;
|
||||
} FsEntry;
|
||||
|
||||
void * FsReadFirst(const char * path, FsEntry * entry);
|
||||
int FsReadNext(void * search, FsEntry * entry);
|
||||
void FsClose(void * search);
|
||||
int FsError(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,60 +1,60 @@
|
|||
/*
|
||||
Copyright (C) 2006 Ben Jaques
|
||||
Copyright (C) 2008-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _GDBSTUB_H_
|
||||
#define _GDBSTUB_H_ 1
|
||||
|
||||
#include "types.h"
|
||||
|
||||
typedef void *gdbstub_handle_t;
|
||||
struct armcpu_t;
|
||||
struct armcpu_memory_iface;
|
||||
|
||||
void gdbstub_mutex_init();
|
||||
void gdbstub_mutex_destroy();
|
||||
void gdbstub_mutex_lock();
|
||||
void gdbstub_mutex_unlock();
|
||||
|
||||
/*
|
||||
* The function interface
|
||||
*/
|
||||
|
||||
gdbstub_handle_t
|
||||
createStub_gdb( u16 port,
|
||||
armcpu_t *theCPU,
|
||||
const armcpu_memory_iface *direct_memio);
|
||||
|
||||
void
|
||||
destroyStub_gdb( gdbstub_handle_t stub);
|
||||
|
||||
void
|
||||
activateStub_gdb( gdbstub_handle_t stub);
|
||||
|
||||
/*
|
||||
* An implementation of the following functions is required
|
||||
* for the GDB stub to function.
|
||||
*/
|
||||
void *
|
||||
createThread_gdb( void (WINAPI *thread_function)( void *data),
|
||||
void *thread_data);
|
||||
|
||||
void
|
||||
joinThread_gdb( void *thread_handle);
|
||||
|
||||
#endif /* End of _GDBSTUB_H_ */
|
||||
|
||||
/*
|
||||
Copyright (C) 2006 Ben Jaques
|
||||
Copyright (C) 2008-2015 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _GDBSTUB_H_
|
||||
#define _GDBSTUB_H_ 1
|
||||
|
||||
#include "types.h"
|
||||
|
||||
typedef void *gdbstub_handle_t;
|
||||
struct armcpu_t;
|
||||
struct armcpu_memory_iface;
|
||||
|
||||
void gdbstub_mutex_init();
|
||||
void gdbstub_mutex_destroy();
|
||||
void gdbstub_mutex_lock();
|
||||
void gdbstub_mutex_unlock();
|
||||
|
||||
/*
|
||||
* The function interface
|
||||
*/
|
||||
|
||||
gdbstub_handle_t
|
||||
createStub_gdb( u16 port,
|
||||
armcpu_t *theCPU,
|
||||
const armcpu_memory_iface *direct_memio);
|
||||
|
||||
void
|
||||
destroyStub_gdb( gdbstub_handle_t stub);
|
||||
|
||||
void
|
||||
activateStub_gdb( gdbstub_handle_t stub);
|
||||
|
||||
/*
|
||||
* An implementation of the following functions is required
|
||||
* for the GDB stub to function.
|
||||
*/
|
||||
void *
|
||||
createThread_gdb( void (WINAPI *thread_function)( void *data),
|
||||
void *thread_data);
|
||||
|
||||
void
|
||||
joinThread_gdb( void *thread_handle);
|
||||
|
||||
#endif /* End of _GDBSTUB_H_ */
|
||||
|
||||
|
|
|
@ -1,186 +1,186 @@
|
|||
/*
|
||||
Copyright (C) 2008-2015 DeSmuME team
|
||||
|
||||
Originally written by Ben Jaques.
|
||||
|
||||
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 _GDBSTUB_INTERNAL_H_
|
||||
#define _GDBSTUB_INTERNAL_H_ 1
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#include <stdint.h>
|
||||
|
||||
#include <winsock2.h>
|
||||
#define SOCKET_TYPE SOCKET
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#define SOCKET_TYPE int
|
||||
#endif
|
||||
|
||||
|
||||
enum stop_type {
|
||||
STOP_UNKNOWN,
|
||||
STOP_HOST_BREAK,
|
||||
STOP_STEP_BREAK,
|
||||
STOP_BREAKPOINT,
|
||||
STOP_WATCHPOINT,
|
||||
STOP_RWATCHPOINT,
|
||||
STOP_AWATCHPOINT
|
||||
};
|
||||
|
||||
struct armcpu_ctrl_iface;
|
||||
struct armcpu_memory_iface;
|
||||
|
||||
/**
|
||||
* The structure describing a breakpoint.
|
||||
*/
|
||||
struct breakpoint_gdb {
|
||||
/** link them in a list */
|
||||
struct breakpoint_gdb *next;
|
||||
|
||||
/** The address of the breakpoint */
|
||||
uint32_t addr;
|
||||
|
||||
/** The size of the breakpoint */
|
||||
uint32_t size;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
*/
|
||||
#define BUFMAX_GDB 2048
|
||||
|
||||
struct packet_reader_gdb {
|
||||
int state;
|
||||
|
||||
int pos_index;
|
||||
|
||||
uint8_t checksum;
|
||||
|
||||
uint8_t read_checksum;
|
||||
|
||||
uint8_t buffer[BUFMAX_GDB];
|
||||
};
|
||||
|
||||
/** The maximum number of breakpoints (of all types) available to the stub */
|
||||
#define BREAKPOINT_POOL_SIZE 100
|
||||
|
||||
|
||||
struct gdb_stub_state {
|
||||
/** flag indicating if the stub is active */
|
||||
int active;
|
||||
|
||||
int main_stop_flag;
|
||||
|
||||
/** the listener thread */
|
||||
void *thread;
|
||||
|
||||
void *arm_cpu_object;
|
||||
|
||||
/** the id of the cpu the is under control */
|
||||
//u32 cpu_id;
|
||||
|
||||
/** the interface used to control the CPU */
|
||||
armcpu_ctrl_iface *cpu_ctrl;
|
||||
|
||||
/** the CPU's memory interface */
|
||||
armcpu_memory_iface *cpu_memio;
|
||||
|
||||
/** the direct interface to the memory system */
|
||||
armcpu_memory_iface *direct_memio;
|
||||
|
||||
/** GDB stub's memory interface passed to the CPU */
|
||||
armcpu_memory_iface *gdb_memio;
|
||||
|
||||
/** the list of active instruction breakpoints */
|
||||
struct breakpoint_gdb *instr_breakpoints;
|
||||
|
||||
/** the list of active read breakpoints */
|
||||
struct breakpoint_gdb *read_breakpoints;
|
||||
|
||||
/** the list of active write breakpoints */
|
||||
struct breakpoint_gdb *write_breakpoints;
|
||||
|
||||
/** the list of active access breakpoints */
|
||||
struct breakpoint_gdb *access_breakpoints;
|
||||
|
||||
/** the pointer to the step break point (not NULL if set) */
|
||||
//struct breakpoint_gdb *step_breakpoint;
|
||||
|
||||
uint32_t step_instr_address;
|
||||
|
||||
/** the state of the stub as seen by the emulator, the emulator side can
|
||||
* set this to STOPPING_EMU_GDB_STATE to indicate that the a breakpoint has been hit,
|
||||
* and STOPPED_EMU_GDB_STATE when it has informed the gdb thread that a breakpoint has
|
||||
* been hit.
|
||||
* When handled the stub side will set it back to RUNNING_EMU_GDB_STATE.
|
||||
*
|
||||
* The emulator should only run the corresponding ARM if this is set to
|
||||
* RUNNING_EMU_GDB_STATE.
|
||||
*/
|
||||
enum EMU_STUB_STATE { STOPPED_EMU_GDB_STATE, STOPPING_EMU_GDB_STATE, RUNNING_EMU_GDB_STATE} emu_stub_state;
|
||||
|
||||
/** the state of the stub as set by the stub control thread */
|
||||
enum CTL_STUB_STATE { STOPPED_GDB_STATE, RUNNING_GDB_STATE,
|
||||
STEPPING_GDB_STATE, START_RUN_GDB_STATE} ctl_stub_state;
|
||||
|
||||
struct packet_reader_gdb rx_packet;
|
||||
|
||||
/** the socket information */
|
||||
uint16_t port_num;
|
||||
SOCKET_TYPE sock_fd;
|
||||
|
||||
/** The listening socket */
|
||||
SOCKET_TYPE listen_fd;
|
||||
|
||||
/** the type of event that caused the stop */
|
||||
enum stop_type stop_type;
|
||||
|
||||
/** the address of the stop */
|
||||
uint32_t stop_address;
|
||||
|
||||
/** The step break point decsriptor */
|
||||
struct breakpoint_gdb step_breakpoint_descr;
|
||||
|
||||
/** the breakpoint descriptor pool */
|
||||
struct breakpoint_gdb breakpoint_pool[BREAKPOINT_POOL_SIZE];
|
||||
|
||||
/** the free breakpoint descriptor list */
|
||||
struct breakpoint_gdb *free_breakpoints;
|
||||
|
||||
/** the control pipe (or socket) to the gdb stub */
|
||||
SOCKET_TYPE ctl_pipe[2];
|
||||
};
|
||||
|
||||
|
||||
enum read_res_gdb {
|
||||
READ_NOT_FINISHED,
|
||||
READ_SOCKET_ERROR,
|
||||
READ_COMPLETE,
|
||||
READ_BREAK
|
||||
};
|
||||
|
||||
#endif /* End of _GDBSTUB_INTERNAL_H_ */
|
||||
/*
|
||||
Copyright (C) 2008-2015 DeSmuME team
|
||||
|
||||
Originally written by Ben Jaques.
|
||||
|
||||
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 _GDBSTUB_INTERNAL_H_
|
||||
#define _GDBSTUB_INTERNAL_H_ 1
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#include <stdint.h>
|
||||
|
||||
#include <winsock2.h>
|
||||
#define SOCKET_TYPE SOCKET
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#define SOCKET_TYPE int
|
||||
#endif
|
||||
|
||||
|
||||
enum stop_type {
|
||||
STOP_UNKNOWN,
|
||||
STOP_HOST_BREAK,
|
||||
STOP_STEP_BREAK,
|
||||
STOP_BREAKPOINT,
|
||||
STOP_WATCHPOINT,
|
||||
STOP_RWATCHPOINT,
|
||||
STOP_AWATCHPOINT
|
||||
};
|
||||
|
||||
struct armcpu_ctrl_iface;
|
||||
struct armcpu_memory_iface;
|
||||
|
||||
/**
|
||||
* The structure describing a breakpoint.
|
||||
*/
|
||||
struct breakpoint_gdb {
|
||||
/** link them in a list */
|
||||
struct breakpoint_gdb *next;
|
||||
|
||||
/** The address of the breakpoint */
|
||||
uint32_t addr;
|
||||
|
||||
/** The size of the breakpoint */
|
||||
uint32_t size;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
*/
|
||||
#define BUFMAX_GDB 2048
|
||||
|
||||
struct packet_reader_gdb {
|
||||
int state;
|
||||
|
||||
int pos_index;
|
||||
|
||||
uint8_t checksum;
|
||||
|
||||
uint8_t read_checksum;
|
||||
|
||||
uint8_t buffer[BUFMAX_GDB];
|
||||
};
|
||||
|
||||
/** The maximum number of breakpoints (of all types) available to the stub */
|
||||
#define BREAKPOINT_POOL_SIZE 100
|
||||
|
||||
|
||||
struct gdb_stub_state {
|
||||
/** flag indicating if the stub is active */
|
||||
int active;
|
||||
|
||||
int main_stop_flag;
|
||||
|
||||
/** the listener thread */
|
||||
void *thread;
|
||||
|
||||
void *arm_cpu_object;
|
||||
|
||||
/** the id of the cpu the is under control */
|
||||
//u32 cpu_id;
|
||||
|
||||
/** the interface used to control the CPU */
|
||||
armcpu_ctrl_iface *cpu_ctrl;
|
||||
|
||||
/** the CPU's memory interface */
|
||||
armcpu_memory_iface *cpu_memio;
|
||||
|
||||
/** the direct interface to the memory system */
|
||||
armcpu_memory_iface *direct_memio;
|
||||
|
||||
/** GDB stub's memory interface passed to the CPU */
|
||||
armcpu_memory_iface *gdb_memio;
|
||||
|
||||
/** the list of active instruction breakpoints */
|
||||
struct breakpoint_gdb *instr_breakpoints;
|
||||
|
||||
/** the list of active read breakpoints */
|
||||
struct breakpoint_gdb *read_breakpoints;
|
||||
|
||||
/** the list of active write breakpoints */
|
||||
struct breakpoint_gdb *write_breakpoints;
|
||||
|
||||
/** the list of active access breakpoints */
|
||||
struct breakpoint_gdb *access_breakpoints;
|
||||
|
||||
/** the pointer to the step break point (not NULL if set) */
|
||||
//struct breakpoint_gdb *step_breakpoint;
|
||||
|
||||
uint32_t step_instr_address;
|
||||
|
||||
/** the state of the stub as seen by the emulator, the emulator side can
|
||||
* set this to STOPPING_EMU_GDB_STATE to indicate that the a breakpoint has been hit,
|
||||
* and STOPPED_EMU_GDB_STATE when it has informed the gdb thread that a breakpoint has
|
||||
* been hit.
|
||||
* When handled the stub side will set it back to RUNNING_EMU_GDB_STATE.
|
||||
*
|
||||
* The emulator should only run the corresponding ARM if this is set to
|
||||
* RUNNING_EMU_GDB_STATE.
|
||||
*/
|
||||
enum EMU_STUB_STATE { STOPPED_EMU_GDB_STATE, STOPPING_EMU_GDB_STATE, RUNNING_EMU_GDB_STATE} emu_stub_state;
|
||||
|
||||
/** the state of the stub as set by the stub control thread */
|
||||
enum CTL_STUB_STATE { STOPPED_GDB_STATE, RUNNING_GDB_STATE,
|
||||
STEPPING_GDB_STATE, START_RUN_GDB_STATE} ctl_stub_state;
|
||||
|
||||
struct packet_reader_gdb rx_packet;
|
||||
|
||||
/** the socket information */
|
||||
uint16_t port_num;
|
||||
SOCKET_TYPE sock_fd;
|
||||
|
||||
/** The listening socket */
|
||||
SOCKET_TYPE listen_fd;
|
||||
|
||||
/** the type of event that caused the stop */
|
||||
enum stop_type stop_type;
|
||||
|
||||
/** the address of the stop */
|
||||
uint32_t stop_address;
|
||||
|
||||
/** The step break point decsriptor */
|
||||
struct breakpoint_gdb step_breakpoint_descr;
|
||||
|
||||
/** the breakpoint descriptor pool */
|
||||
struct breakpoint_gdb breakpoint_pool[BREAKPOINT_POOL_SIZE];
|
||||
|
||||
/** the free breakpoint descriptor list */
|
||||
struct breakpoint_gdb *free_breakpoints;
|
||||
|
||||
/** the control pipe (or socket) to the gdb stub */
|
||||
SOCKET_TYPE ctl_pipe[2];
|
||||
};
|
||||
|
||||
|
||||
enum read_res_gdb {
|
||||
READ_NOT_FINISHED,
|
||||
READ_SOCKET_ERROR,
|
||||
READ_COMPLETE,
|
||||
READ_BREAK
|
||||
};
|
||||
|
||||
#endif /* End of _GDBSTUB_INTERNAL_H_ */
|
||||
|
|
1580
desmume/src/gfx3d.h
1580
desmume/src/gfx3d.h
File diff suppressed because it is too large
Load Diff
|
@ -1,75 +1,75 @@
|
|||
/* callbacks.h - this file is part of DeSmuME
|
||||
*
|
||||
* Copyright (C) 2007 Damien Nozay (damdoum)
|
||||
* Author: damdoum at users.sourceforge.net
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "globals.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
/* MENU FILE */
|
||||
G_MODULE_EXPORT void on_menu_open_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_menu_pscreen_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_menu_quit_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
|
||||
/* MENU SAVES */
|
||||
G_MODULE_EXPORT void on_loadstateXX_activate (GtkMenuItem *, gpointer );
|
||||
G_MODULE_EXPORT void on_savestateXX_activate (GtkMenuItem *, gpointer );
|
||||
G_MODULE_EXPORT void on_savetypeXX_activate (GtkMenuItem *, gpointer );
|
||||
|
||||
/* MENU EMULATION */
|
||||
G_MODULE_EXPORT void on_menu_exec_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_menu_pause_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_menu_reset_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_menu_layers_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_fsXX_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_sizeXX_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
|
||||
/* MENU CONFIG */
|
||||
G_MODULE_EXPORT void on_menu_controls_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_menu_joy_controls_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_menu_audio_on_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_menu_gapscreen_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_menu_nogap_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_menu_rightscreen_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_menu_rotatescreen_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
|
||||
/* MENU TOOLS */
|
||||
G_MODULE_EXPORT void on_menu_wtoolsXX_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_menu_IO_regs_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_menu_memview_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_menu_palview_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_menu_tileview_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
|
||||
/* MENU ? */
|
||||
G_MODULE_EXPORT void on_menu_apropos_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
|
||||
|
||||
/* TOOLBAR */
|
||||
G_MODULE_EXPORT void on_wgt_Open_clicked (GtkToolButton *toolbutton, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_wgt_Exec_toggled (GtkToggleToolButton *toggletoolbutton,
|
||||
gpointer user_data);
|
||||
G_MODULE_EXPORT void on_wgt_Reset_clicked (GtkToolButton *toolbutton, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_wgt_Quit_clicked (GtkToolButton *toolbutton, gpointer user_data);
|
||||
|
||||
/* LAYERS TOGGLE */
|
||||
G_MODULE_EXPORT void on_wc_1_BGXX_toggled (GtkToggleButton *togglebutton, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_wc_2_BGXX_toggled (GtkToggleButton *togglebutton, gpointer user_data);
|
||||
|
||||
}
|
||||
/* callbacks.h - this file is part of DeSmuME
|
||||
*
|
||||
* Copyright (C) 2007 Damien Nozay (damdoum)
|
||||
* Author: damdoum at users.sourceforge.net
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "globals.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
/* MENU FILE */
|
||||
G_MODULE_EXPORT void on_menu_open_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_menu_pscreen_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_menu_quit_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
|
||||
/* MENU SAVES */
|
||||
G_MODULE_EXPORT void on_loadstateXX_activate (GtkMenuItem *, gpointer );
|
||||
G_MODULE_EXPORT void on_savestateXX_activate (GtkMenuItem *, gpointer );
|
||||
G_MODULE_EXPORT void on_savetypeXX_activate (GtkMenuItem *, gpointer );
|
||||
|
||||
/* MENU EMULATION */
|
||||
G_MODULE_EXPORT void on_menu_exec_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_menu_pause_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_menu_reset_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_menu_layers_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_fsXX_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_sizeXX_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
|
||||
/* MENU CONFIG */
|
||||
G_MODULE_EXPORT void on_menu_controls_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_menu_joy_controls_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_menu_audio_on_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_menu_gapscreen_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_menu_nogap_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_menu_rightscreen_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_menu_rotatescreen_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
|
||||
/* MENU TOOLS */
|
||||
G_MODULE_EXPORT void on_menu_wtoolsXX_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_menu_IO_regs_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_menu_memview_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_menu_palview_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_menu_tileview_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
|
||||
/* MENU ? */
|
||||
G_MODULE_EXPORT void on_menu_apropos_activate (GtkMenuItem *menuitem, gpointer user_data);
|
||||
|
||||
|
||||
/* TOOLBAR */
|
||||
G_MODULE_EXPORT void on_wgt_Open_clicked (GtkToolButton *toolbutton, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_wgt_Exec_toggled (GtkToggleToolButton *toggletoolbutton,
|
||||
gpointer user_data);
|
||||
G_MODULE_EXPORT void on_wgt_Reset_clicked (GtkToolButton *toolbutton, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_wgt_Quit_clicked (GtkToolButton *toolbutton, gpointer user_data);
|
||||
|
||||
/* LAYERS TOGGLE */
|
||||
G_MODULE_EXPORT void on_wc_1_BGXX_toggled (GtkToggleButton *togglebutton, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_wc_2_BGXX_toggled (GtkToggleButton *togglebutton, gpointer user_data);
|
||||
|
||||
}
|
||||
|
|
|
@ -1,51 +1,51 @@
|
|||
/* callbacks_IO.h - this file is part of DeSmuME
|
||||
*
|
||||
* Copyright (C) 2007 Damien Nozay (damdoum)
|
||||
* Copyright (C) 2007 Pascal Giard (evilynux)
|
||||
* Author: damdoum at users.sourceforge.net
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "globals.h"
|
||||
#include "gdk_gl.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
/* INPUT BUTTONS / KEYBOARD */
|
||||
G_MODULE_EXPORT gboolean on_wMainW_key_press_event (GtkWidget *widget, GdkEventKey *event, gpointer user_data);
|
||||
G_MODULE_EXPORT gboolean on_wMainW_key_release_event (GtkWidget *widget, GdkEventKey *event, gpointer user_data);
|
||||
|
||||
/* OUTPUT SCREENS */
|
||||
G_MODULE_EXPORT gboolean on_wDrawScreen_expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer user_data);
|
||||
G_MODULE_EXPORT gboolean on_wDrawScreen_configure_event(GtkWidget *widget, GdkEventConfigure *event, gpointer data);
|
||||
|
||||
|
||||
/* INPUT STYLUS / MOUSE */
|
||||
G_MODULE_EXPORT gboolean on_wDrawScreen_motion_notify_event (GtkWidget *widget, GdkEventMotion *event, gpointer user_data);
|
||||
G_MODULE_EXPORT gboolean on_wDrawScreen_button_release_event(GtkWidget *widget, GdkEventButton *event, gpointer user_data);
|
||||
G_MODULE_EXPORT gboolean on_wDrawScreen_button_press_event (GtkWidget *widget, GdkEventButton *event, gpointer user_data);
|
||||
G_MODULE_EXPORT gboolean on_wDrawScreen_scroll_event (GtkWidget *widget, GdkEvent *event, gpointer user_data);
|
||||
|
||||
/* KEYBOARD CONFIG / KEY DEFINITION */
|
||||
G_MODULE_EXPORT gboolean on_wKeyDlg_key_press_event (GtkWidget *widget, GdkEventKey *event, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_wKeybConfDlg_response (GtkDialog *dialog, gint arg1, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_button_kb_key_clicked (GtkButton *button, gpointer user_data);
|
||||
|
||||
/* Joystick configuration / Key definition */
|
||||
G_MODULE_EXPORT void on_button_joy_key_clicked (GtkButton *button, gpointer user_data);
|
||||
|
||||
}
|
||||
/* callbacks_IO.h - this file is part of DeSmuME
|
||||
*
|
||||
* Copyright (C) 2007 Damien Nozay (damdoum)
|
||||
* Copyright (C) 2007 Pascal Giard (evilynux)
|
||||
* Author: damdoum at users.sourceforge.net
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "globals.h"
|
||||
#include "gdk_gl.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
/* INPUT BUTTONS / KEYBOARD */
|
||||
G_MODULE_EXPORT gboolean on_wMainW_key_press_event (GtkWidget *widget, GdkEventKey *event, gpointer user_data);
|
||||
G_MODULE_EXPORT gboolean on_wMainW_key_release_event (GtkWidget *widget, GdkEventKey *event, gpointer user_data);
|
||||
|
||||
/* OUTPUT SCREENS */
|
||||
G_MODULE_EXPORT gboolean on_wDrawScreen_expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer user_data);
|
||||
G_MODULE_EXPORT gboolean on_wDrawScreen_configure_event(GtkWidget *widget, GdkEventConfigure *event, gpointer data);
|
||||
|
||||
|
||||
/* INPUT STYLUS / MOUSE */
|
||||
G_MODULE_EXPORT gboolean on_wDrawScreen_motion_notify_event (GtkWidget *widget, GdkEventMotion *event, gpointer user_data);
|
||||
G_MODULE_EXPORT gboolean on_wDrawScreen_button_release_event(GtkWidget *widget, GdkEventButton *event, gpointer user_data);
|
||||
G_MODULE_EXPORT gboolean on_wDrawScreen_button_press_event (GtkWidget *widget, GdkEventButton *event, gpointer user_data);
|
||||
G_MODULE_EXPORT gboolean on_wDrawScreen_scroll_event (GtkWidget *widget, GdkEvent *event, gpointer user_data);
|
||||
|
||||
/* KEYBOARD CONFIG / KEY DEFINITION */
|
||||
G_MODULE_EXPORT gboolean on_wKeyDlg_key_press_event (GtkWidget *widget, GdkEventKey *event, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_wKeybConfDlg_response (GtkDialog *dialog, gint arg1, gpointer user_data);
|
||||
G_MODULE_EXPORT void on_button_kb_key_clicked (GtkButton *button, gpointer user_data);
|
||||
|
||||
/* Joystick configuration / Key definition */
|
||||
G_MODULE_EXPORT void on_button_joy_key_clicked (GtkButton *button, gpointer user_data);
|
||||
|
||||
}
|
||||
|
|
|
@ -1,79 +1,79 @@
|
|||
/* callbacks_dtools.h - this file is part of DeSmuME
|
||||
*
|
||||
* Copyright (C) 2007 Damien Nozay (damdoum)
|
||||
* Author: damdoum at users.sourceforge.net
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __CALLBACKS_DTOOLS_H__
|
||||
#define __CALLBACKS_DTOOLS_H__
|
||||
|
||||
#include "../globals.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
/* ***** ***** IO REGISTERS ***** ***** */
|
||||
G_MODULE_EXPORT void on_wtools_1_combo_cpu_changed (GtkComboBox *, gpointer );
|
||||
G_MODULE_EXPORT void on_wtools_1_IOregs_show (GtkWidget *, gpointer );
|
||||
G_MODULE_EXPORT gboolean on_wtools_1_IOregs_close (GtkWidget *, ...);
|
||||
G_MODULE_EXPORT gboolean on_wtools_1_draw_button_release_event(GtkWidget *, GdkEventButton *, gpointer );
|
||||
G_MODULE_EXPORT gboolean on_wtools_1_draw_expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer user_data);
|
||||
|
||||
/* ***** ***** MEMORY VIEWER ***** ***** */
|
||||
G_MODULE_EXPORT void on_wtools_2_MemView_show (GtkWidget *, gpointer );
|
||||
G_MODULE_EXPORT gboolean on_wtools_2_MemView_close (GtkWidget *, ...);
|
||||
|
||||
G_MODULE_EXPORT void on_wtools_2_cpu_changed (GtkComboBox *, gpointer );
|
||||
G_MODULE_EXPORT void on_wtools_2_r8_toggled (GtkToggleButton *, gpointer );
|
||||
G_MODULE_EXPORT void on_wtools_2_r16_toggled (GtkToggleButton *, gpointer );
|
||||
G_MODULE_EXPORT void on_wtools_2_r32_toggled (GtkToggleButton *, gpointer );
|
||||
G_MODULE_EXPORT void on_wtools_2_GotoAddress_activate (GtkEntry *, gpointer );
|
||||
G_MODULE_EXPORT void on_wtools_2_GotoAddress_changed (GtkEntry *, gpointer );
|
||||
G_MODULE_EXPORT void on_wtools_2_GotoButton_clicked (GtkButton *, gpointer );
|
||||
G_MODULE_EXPORT void on_wtools_2_scroll_value_changed (GtkRange *, gpointer );
|
||||
G_MODULE_EXPORT gboolean on_wtools_2_draw_button_release_event(GtkWidget *, GdkEventButton *, gpointer );
|
||||
G_MODULE_EXPORT gboolean on_wtools_2_draw_expose_event (GtkWidget *, GdkEventExpose *, gpointer );
|
||||
G_MODULE_EXPORT gboolean on_wtools_2_draw_scroll_event (GtkWidget *, GdkEventScroll *, gpointer );
|
||||
|
||||
/* ***** ***** PALETTE VIEWER ***** ***** */
|
||||
// initialise combo box for all palettes
|
||||
void init_combo_palette(GtkComboBox *combo, u16 ** addresses);
|
||||
|
||||
G_MODULE_EXPORT void on_wtools_3_PalView_show (GtkWidget *, gpointer );
|
||||
G_MODULE_EXPORT gboolean on_wtools_3_PalView_close (GtkWidget *, ...);
|
||||
G_MODULE_EXPORT gboolean on_wtools_3_PalView_delete_event (GtkWidget *, GdkEvent *, gpointer );
|
||||
G_MODULE_EXPORT gboolean on_wtools_3_draw_expose_event (GtkWidget *, GdkEventExpose *, gpointer );
|
||||
G_MODULE_EXPORT void on_wtools_3_palette_changed (GtkComboBox *, gpointer );
|
||||
G_MODULE_EXPORT void on_wtools_3_palnum_value_changed (GtkSpinButton *, gpointer );
|
||||
|
||||
|
||||
/* ***** ***** TILE VIEWER ***** ***** */
|
||||
// initialise combo box for all palettes
|
||||
void init_combo_memory(GtkComboBox *combo, u8 ** addresses);
|
||||
|
||||
G_MODULE_EXPORT void on_wtools_4_TileView_show (GtkWidget *, gpointer );
|
||||
G_MODULE_EXPORT gboolean on_wtools_4_TileView_close (GtkWidget *, ...);
|
||||
G_MODULE_EXPORT gboolean on_wtools_4_TileView_delete_event (GtkWidget *, GdkEvent *, gpointer );
|
||||
G_MODULE_EXPORT void on_wtools_4_memory_changed (GtkComboBox *, gpointer );
|
||||
G_MODULE_EXPORT void on_wtools_4_palette_changed (GtkComboBox *, gpointer );
|
||||
G_MODULE_EXPORT void on_wtools_4_palnum_value_changed (GtkSpinButton *, gpointer );
|
||||
G_MODULE_EXPORT void on_wtools_4_rXX_toggled (GtkToggleButton *togglebutton, gpointer user_data);
|
||||
G_MODULE_EXPORT gboolean on_wDraw_Tile_expose_event (GtkWidget *, GdkEventExpose *, gpointer );
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
/* callbacks_dtools.h - this file is part of DeSmuME
|
||||
*
|
||||
* Copyright (C) 2007 Damien Nozay (damdoum)
|
||||
* Author: damdoum at users.sourceforge.net
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __CALLBACKS_DTOOLS_H__
|
||||
#define __CALLBACKS_DTOOLS_H__
|
||||
|
||||
#include "../globals.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
/* ***** ***** IO REGISTERS ***** ***** */
|
||||
G_MODULE_EXPORT void on_wtools_1_combo_cpu_changed (GtkComboBox *, gpointer );
|
||||
G_MODULE_EXPORT void on_wtools_1_IOregs_show (GtkWidget *, gpointer );
|
||||
G_MODULE_EXPORT gboolean on_wtools_1_IOregs_close (GtkWidget *, ...);
|
||||
G_MODULE_EXPORT gboolean on_wtools_1_draw_button_release_event(GtkWidget *, GdkEventButton *, gpointer );
|
||||
G_MODULE_EXPORT gboolean on_wtools_1_draw_expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer user_data);
|
||||
|
||||
/* ***** ***** MEMORY VIEWER ***** ***** */
|
||||
G_MODULE_EXPORT void on_wtools_2_MemView_show (GtkWidget *, gpointer );
|
||||
G_MODULE_EXPORT gboolean on_wtools_2_MemView_close (GtkWidget *, ...);
|
||||
|
||||
G_MODULE_EXPORT void on_wtools_2_cpu_changed (GtkComboBox *, gpointer );
|
||||
G_MODULE_EXPORT void on_wtools_2_r8_toggled (GtkToggleButton *, gpointer );
|
||||
G_MODULE_EXPORT void on_wtools_2_r16_toggled (GtkToggleButton *, gpointer );
|
||||
G_MODULE_EXPORT void on_wtools_2_r32_toggled (GtkToggleButton *, gpointer );
|
||||
G_MODULE_EXPORT void on_wtools_2_GotoAddress_activate (GtkEntry *, gpointer );
|
||||
G_MODULE_EXPORT void on_wtools_2_GotoAddress_changed (GtkEntry *, gpointer );
|
||||
G_MODULE_EXPORT void on_wtools_2_GotoButton_clicked (GtkButton *, gpointer );
|
||||
G_MODULE_EXPORT void on_wtools_2_scroll_value_changed (GtkRange *, gpointer );
|
||||
G_MODULE_EXPORT gboolean on_wtools_2_draw_button_release_event(GtkWidget *, GdkEventButton *, gpointer );
|
||||
G_MODULE_EXPORT gboolean on_wtools_2_draw_expose_event (GtkWidget *, GdkEventExpose *, gpointer );
|
||||
G_MODULE_EXPORT gboolean on_wtools_2_draw_scroll_event (GtkWidget *, GdkEventScroll *, gpointer );
|
||||
|
||||
/* ***** ***** PALETTE VIEWER ***** ***** */
|
||||
// initialise combo box for all palettes
|
||||
void init_combo_palette(GtkComboBox *combo, u16 ** addresses);
|
||||
|
||||
G_MODULE_EXPORT void on_wtools_3_PalView_show (GtkWidget *, gpointer );
|
||||
G_MODULE_EXPORT gboolean on_wtools_3_PalView_close (GtkWidget *, ...);
|
||||
G_MODULE_EXPORT gboolean on_wtools_3_PalView_delete_event (GtkWidget *, GdkEvent *, gpointer );
|
||||
G_MODULE_EXPORT gboolean on_wtools_3_draw_expose_event (GtkWidget *, GdkEventExpose *, gpointer );
|
||||
G_MODULE_EXPORT void on_wtools_3_palette_changed (GtkComboBox *, gpointer );
|
||||
G_MODULE_EXPORT void on_wtools_3_palnum_value_changed (GtkSpinButton *, gpointer );
|
||||
|
||||
|
||||
/* ***** ***** TILE VIEWER ***** ***** */
|
||||
// initialise combo box for all palettes
|
||||
void init_combo_memory(GtkComboBox *combo, u8 ** addresses);
|
||||
|
||||
G_MODULE_EXPORT void on_wtools_4_TileView_show (GtkWidget *, gpointer );
|
||||
G_MODULE_EXPORT gboolean on_wtools_4_TileView_close (GtkWidget *, ...);
|
||||
G_MODULE_EXPORT gboolean on_wtools_4_TileView_delete_event (GtkWidget *, GdkEvent *, gpointer );
|
||||
G_MODULE_EXPORT void on_wtools_4_memory_changed (GtkComboBox *, gpointer );
|
||||
G_MODULE_EXPORT void on_wtools_4_palette_changed (GtkComboBox *, gpointer );
|
||||
G_MODULE_EXPORT void on_wtools_4_palnum_value_changed (GtkSpinButton *, gpointer );
|
||||
G_MODULE_EXPORT void on_wtools_4_rXX_toggled (GtkToggleButton *togglebutton, gpointer user_data);
|
||||
G_MODULE_EXPORT gboolean on_wDraw_Tile_expose_event (GtkWidget *, GdkEventExpose *, gpointer );
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,110 +1,110 @@
|
|||
/* dTools_display.c
|
||||
*
|
||||
* Copyright (C) 2007 Damien Nozay (damdoum)
|
||||
* Author: damdoum at users.sourceforge.net
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _DTOOLS_DISPLAY_H_
|
||||
#define _DTOOLS_DISPLAY_H_
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
typedef struct {
|
||||
GtkWidget *widget;
|
||||
GdkDrawable *draw;
|
||||
GdkGC *gc_fg;
|
||||
GdkGC *gc_bg;
|
||||
PangoLayout* playout;
|
||||
int size_w, size_h;
|
||||
int char_w, char_h, padding;
|
||||
GList * colors_rgb;
|
||||
GList * attr_list;
|
||||
PangoAttrList * curr_attr;
|
||||
} dTools_dsp;
|
||||
|
||||
static void inline dTools_display_set_size(dTools_dsp * dsp, int w, int h, int pad) {
|
||||
dsp->size_w = w;
|
||||
dsp->size_h = h;
|
||||
dsp->padding = pad;
|
||||
// gtk_widget_set_size_request(dsp->widget,
|
||||
// dsp->char_w * w + pad * 2, dsp->char_h * h + pad * 2);
|
||||
gtk_widget_set_usize(dsp->widget,
|
||||
dsp->char_w * w + pad * 2, dsp->char_h * h + pad * 2);
|
||||
}
|
||||
|
||||
static void inline dTools_display_init(dTools_dsp * dsp, GtkWidget * widget, int w, int h, int pad) {
|
||||
dsp->widget = widget;
|
||||
dsp->draw = widget->window;
|
||||
dsp->gc_fg = widget->style->fg_gc[widget->state];
|
||||
dsp->gc_bg = widget->style->white_gc;
|
||||
dsp->playout = gtk_widget_create_pango_layout(widget, NULL);
|
||||
|
||||
dsp->colors_rgb = NULL;
|
||||
dsp->attr_list = NULL;
|
||||
dsp->curr_attr = NULL;
|
||||
|
||||
pango_layout_set_markup(dsp->playout, "<tt>X</tt>",-1);
|
||||
pango_layout_get_pixel_size(dsp->playout, &dsp->char_w, &dsp->char_h);
|
||||
dTools_display_set_size(dsp, w, h, pad);
|
||||
}
|
||||
|
||||
// void unref (gpointer data, ...) {
|
||||
// pango_attr_list_unref(data);
|
||||
// }
|
||||
|
||||
static void inline dTools_display_free(dTools_dsp * dsp) {
|
||||
// g_list_foreach(dsp->attr_list, (GFunc)unref, NULL);
|
||||
// g_object_unref(dsp->playout); // not alloc
|
||||
}
|
||||
|
||||
static void inline dTools_display_add_markup(dTools_dsp * dsp, const char * markup) {
|
||||
PangoAttrList *attr;
|
||||
pango_parse_markup (markup, -1, 0, &attr, NULL, NULL, NULL);
|
||||
dsp->attr_list = g_list_append(dsp->attr_list, attr);
|
||||
dsp->curr_attr = attr;
|
||||
}
|
||||
|
||||
static void inline dTools_display_clear(dTools_dsp * dsp) {
|
||||
gdk_draw_rectangle(dsp->draw, dsp->gc_bg, TRUE, 0, 0,
|
||||
dsp->widget->allocation.width, dsp->widget->allocation.height);
|
||||
}
|
||||
|
||||
static void inline dTools_display_clear_char(dTools_dsp * dsp, int x, int y, int nb) {
|
||||
gdk_draw_rectangle(dsp->draw, dsp->gc_bg, TRUE,
|
||||
x * dsp->char_w + dsp->padding, y * dsp->char_h + dsp->padding,
|
||||
nb * dsp->char_w, dsp->char_h);
|
||||
}
|
||||
|
||||
static void inline dTools_display_select_attr(dTools_dsp * dsp, int index) {
|
||||
PangoAttrList *attr = NULL;
|
||||
attr = (PangoAttrList*) g_list_nth_data(dsp->attr_list, index);
|
||||
if (attr != NULL) {
|
||||
dsp->curr_attr = attr;
|
||||
}
|
||||
pango_layout_set_attributes(dsp->playout, dsp->curr_attr);
|
||||
}
|
||||
|
||||
static void inline dTools_display_draw_text(dTools_dsp * dsp, int x, int y, const char * txt) {
|
||||
pango_layout_set_text(dsp->playout, txt, -1);
|
||||
gdk_draw_layout(dsp->draw, dsp->gc_fg,
|
||||
x * dsp->char_w + dsp->padding,
|
||||
y * dsp->char_h + dsp->padding,
|
||||
dsp->playout);
|
||||
}
|
||||
|
||||
#endif
|
||||
/* dTools_display.c
|
||||
*
|
||||
* Copyright (C) 2007 Damien Nozay (damdoum)
|
||||
* Author: damdoum at users.sourceforge.net
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _DTOOLS_DISPLAY_H_
|
||||
#define _DTOOLS_DISPLAY_H_
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
typedef struct {
|
||||
GtkWidget *widget;
|
||||
GdkDrawable *draw;
|
||||
GdkGC *gc_fg;
|
||||
GdkGC *gc_bg;
|
||||
PangoLayout* playout;
|
||||
int size_w, size_h;
|
||||
int char_w, char_h, padding;
|
||||
GList * colors_rgb;
|
||||
GList * attr_list;
|
||||
PangoAttrList * curr_attr;
|
||||
} dTools_dsp;
|
||||
|
||||
static void inline dTools_display_set_size(dTools_dsp * dsp, int w, int h, int pad) {
|
||||
dsp->size_w = w;
|
||||
dsp->size_h = h;
|
||||
dsp->padding = pad;
|
||||
// gtk_widget_set_size_request(dsp->widget,
|
||||
// dsp->char_w * w + pad * 2, dsp->char_h * h + pad * 2);
|
||||
gtk_widget_set_usize(dsp->widget,
|
||||
dsp->char_w * w + pad * 2, dsp->char_h * h + pad * 2);
|
||||
}
|
||||
|
||||
static void inline dTools_display_init(dTools_dsp * dsp, GtkWidget * widget, int w, int h, int pad) {
|
||||
dsp->widget = widget;
|
||||
dsp->draw = widget->window;
|
||||
dsp->gc_fg = widget->style->fg_gc[widget->state];
|
||||
dsp->gc_bg = widget->style->white_gc;
|
||||
dsp->playout = gtk_widget_create_pango_layout(widget, NULL);
|
||||
|
||||
dsp->colors_rgb = NULL;
|
||||
dsp->attr_list = NULL;
|
||||
dsp->curr_attr = NULL;
|
||||
|
||||
pango_layout_set_markup(dsp->playout, "<tt>X</tt>",-1);
|
||||
pango_layout_get_pixel_size(dsp->playout, &dsp->char_w, &dsp->char_h);
|
||||
dTools_display_set_size(dsp, w, h, pad);
|
||||
}
|
||||
|
||||
// void unref (gpointer data, ...) {
|
||||
// pango_attr_list_unref(data);
|
||||
// }
|
||||
|
||||
static void inline dTools_display_free(dTools_dsp * dsp) {
|
||||
// g_list_foreach(dsp->attr_list, (GFunc)unref, NULL);
|
||||
// g_object_unref(dsp->playout); // not alloc
|
||||
}
|
||||
|
||||
static void inline dTools_display_add_markup(dTools_dsp * dsp, const char * markup) {
|
||||
PangoAttrList *attr;
|
||||
pango_parse_markup (markup, -1, 0, &attr, NULL, NULL, NULL);
|
||||
dsp->attr_list = g_list_append(dsp->attr_list, attr);
|
||||
dsp->curr_attr = attr;
|
||||
}
|
||||
|
||||
static void inline dTools_display_clear(dTools_dsp * dsp) {
|
||||
gdk_draw_rectangle(dsp->draw, dsp->gc_bg, TRUE, 0, 0,
|
||||
dsp->widget->allocation.width, dsp->widget->allocation.height);
|
||||
}
|
||||
|
||||
static void inline dTools_display_clear_char(dTools_dsp * dsp, int x, int y, int nb) {
|
||||
gdk_draw_rectangle(dsp->draw, dsp->gc_bg, TRUE,
|
||||
x * dsp->char_w + dsp->padding, y * dsp->char_h + dsp->padding,
|
||||
nb * dsp->char_w, dsp->char_h);
|
||||
}
|
||||
|
||||
static void inline dTools_display_select_attr(dTools_dsp * dsp, int index) {
|
||||
PangoAttrList *attr = NULL;
|
||||
attr = (PangoAttrList*) g_list_nth_data(dsp->attr_list, index);
|
||||
if (attr != NULL) {
|
||||
dsp->curr_attr = attr;
|
||||
}
|
||||
pango_layout_set_attributes(dsp->playout, dsp->curr_attr);
|
||||
}
|
||||
|
||||
static void inline dTools_display_draw_text(dTools_dsp * dsp, int x, int y, const char * txt) {
|
||||
pango_layout_set_text(dsp->playout, txt, -1);
|
||||
gdk_draw_layout(dsp->draw, dsp->gc_fg,
|
||||
x * dsp->char_w + dsp->padding,
|
||||
y * dsp->char_h + dsp->padding,
|
||||
dsp->playout);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,47 +1,47 @@
|
|||
/* desmume.h - this file is part of DeSmuME
|
||||
*
|
||||
* Copyright (C) 2007-2015 DeSmuME Team
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __DESMUME_H__
|
||||
#define __DESMUME_H__
|
||||
|
||||
#include "globals.h"
|
||||
|
||||
#define FPS_LIMITER_FRAME_PERIOD 5
|
||||
extern SDL_sem *glade_fps_limiter_semaphore;
|
||||
extern int glade_fps_limiter_disabled;
|
||||
|
||||
extern void desmume_init( void);
|
||||
extern void desmume_free( void);
|
||||
|
||||
extern int desmume_open(const char *filename);
|
||||
extern void desmume_savetype(int type);
|
||||
extern void desmume_pause( void);
|
||||
extern void desmume_resume( void);
|
||||
extern void desmume_reset( void);
|
||||
extern void desmume_toggle( void);
|
||||
//extern BOOL desmume_running( void);
|
||||
INLINE BOOL desmume_running(void)
|
||||
{
|
||||
return execute;
|
||||
}
|
||||
|
||||
extern INLINE void desmume_cycle( void);
|
||||
#endif /*__DESMUME_H__*/
|
||||
|
||||
/* desmume.h - this file is part of DeSmuME
|
||||
*
|
||||
* Copyright (C) 2007-2015 DeSmuME Team
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __DESMUME_H__
|
||||
#define __DESMUME_H__
|
||||
|
||||
#include "globals.h"
|
||||
|
||||
#define FPS_LIMITER_FRAME_PERIOD 5
|
||||
extern SDL_sem *glade_fps_limiter_semaphore;
|
||||
extern int glade_fps_limiter_disabled;
|
||||
|
||||
extern void desmume_init( void);
|
||||
extern void desmume_free( void);
|
||||
|
||||
extern int desmume_open(const char *filename);
|
||||
extern void desmume_savetype(int type);
|
||||
extern void desmume_pause( void);
|
||||
extern void desmume_resume( void);
|
||||
extern void desmume_reset( void);
|
||||
extern void desmume_toggle( void);
|
||||
//extern BOOL desmume_running( void);
|
||||
INLINE BOOL desmume_running(void)
|
||||
{
|
||||
return execute;
|
||||
}
|
||||
|
||||
extern INLINE void desmume_cycle( void);
|
||||
#endif /*__DESMUME_H__*/
|
||||
|
||||
|
|
|
@ -1,32 +1,32 @@
|
|||
/* $Id: gdk_3Demu.h,v 1.1 2007-04-21 19:45:07 evilynux Exp $
|
||||
*/
|
||||
/*
|
||||
Copyright (C) 2006-2007 Ben Jaques
|
||||
|
||||
This file is part of DeSmuME
|
||||
|
||||
DeSmuME is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
DeSmuME is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with DeSmuME; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifdef GTKGLEXT_AVAILABLE
|
||||
/*
|
||||
* The GDK 3D emulation.
|
||||
* This uses the OpenGL Collector plugin, using gdkGLext for the platform
|
||||
* specific helper functions.
|
||||
*/
|
||||
|
||||
int
|
||||
init_opengl_gdk_3Demu( GdkDrawable * drawable);
|
||||
|
||||
#endif
|
||||
/* $Id: gdk_3Demu.h,v 1.1 2007-04-21 19:45:07 evilynux Exp $
|
||||
*/
|
||||
/*
|
||||
Copyright (C) 2006-2007 Ben Jaques
|
||||
|
||||
This file is part of DeSmuME
|
||||
|
||||
DeSmuME is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
DeSmuME is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with DeSmuME; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifdef GTKGLEXT_AVAILABLE
|
||||
/*
|
||||
* The GDK 3D emulation.
|
||||
* This uses the OpenGL Collector plugin, using gdkGLext for the platform
|
||||
* specific helper functions.
|
||||
*/
|
||||
|
||||
int
|
||||
init_opengl_gdk_3Demu( GdkDrawable * drawable);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,48 +1,48 @@
|
|||
/* gdk_gl.h - this file is part of DeSmuME
|
||||
*
|
||||
* Copyright (C) 2007 Damien Nozay (damdoum)
|
||||
* Author: damdoum at users.sourceforge.net
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GDKGL_H__
|
||||
#define __GDKGL_H__
|
||||
|
||||
#include "globals.h"
|
||||
|
||||
#ifdef GTKGLEXT_AVAILABLE
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glext.h>
|
||||
#include <gdk/gdkgl.h>
|
||||
#include <gtk/gtkglwidget.h>
|
||||
#endif
|
||||
|
||||
|
||||
BOOL my_gl_Begin (int screen);
|
||||
void my_gl_End (int screen);
|
||||
void my_gl_Clear(int screen);
|
||||
void my_gl_DrawBeautifulQuad( void);
|
||||
void my_gl_Identity( void);
|
||||
|
||||
void init_GL_capabilities( int use_software_convert);
|
||||
void init_GL(GtkWidget * widget, int screen, int share_num);
|
||||
int init_GL_free_s(GtkWidget * widget, int share_num);
|
||||
int init_GL_free(GtkWidget * widget);
|
||||
void reshape (GtkWidget * widget, int screen);
|
||||
gboolean screen (GtkWidget * widget, int off);
|
||||
|
||||
#endif
|
||||
/* gdk_gl.h - this file is part of DeSmuME
|
||||
*
|
||||
* Copyright (C) 2007 Damien Nozay (damdoum)
|
||||
* Author: damdoum at users.sourceforge.net
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GDKGL_H__
|
||||
#define __GDKGL_H__
|
||||
|
||||
#include "globals.h"
|
||||
|
||||
#ifdef GTKGLEXT_AVAILABLE
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glext.h>
|
||||
#include <gdk/gdkgl.h>
|
||||
#include <gtk/gtkglwidget.h>
|
||||
#endif
|
||||
|
||||
|
||||
BOOL my_gl_Begin (int screen);
|
||||
void my_gl_End (int screen);
|
||||
void my_gl_Clear(int screen);
|
||||
void my_gl_DrawBeautifulQuad( void);
|
||||
void my_gl_Identity( void);
|
||||
|
||||
void init_GL_capabilities( int use_software_convert);
|
||||
void init_GL(GtkWidget * widget, int screen, int share_num);
|
||||
int init_GL_free_s(GtkWidget * widget, int share_num);
|
||||
int init_GL_free(GtkWidget * widget);
|
||||
void reshape (GtkWidget * widget, int screen);
|
||||
gboolean screen (GtkWidget * widget, int off);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,132 +1,132 @@
|
|||
/* globals.h - this file is part of DeSmuME
|
||||
*
|
||||
* Copyright (C) 2007-2015 DeSmuME Team
|
||||
* Copyright (C) 2007 Damien Nozay (damdoum)
|
||||
* Author: damdoum at users.sourceforge.net
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GLOBALS_H__
|
||||
#define __GLOBALS_H__
|
||||
|
||||
#ifndef GTK_UI
|
||||
#define GTK_UI
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// Localization
|
||||
#include <libintl.h>
|
||||
#define _(String) gettext (String)
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
// fix gtk-glade on windows with no configure
|
||||
#ifndef DATADIR
|
||||
#define DATADIR " "
|
||||
#endif
|
||||
#ifndef GLADEUI_UNINSTALLED_DIR
|
||||
#define GLADEUI_UNINSTALLED_DIR "glade/"
|
||||
#endif
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
#include <glade/glade.h>
|
||||
#include <glade/glade-xml.h>
|
||||
|
||||
|
||||
typedef union _callback_arg{
|
||||
gpointer my_pointer;
|
||||
gconstpointer my_constpointer;
|
||||
|
||||
gfloat my_float;
|
||||
gdouble my_double;
|
||||
gsize my_size;
|
||||
gssize my_ssize;
|
||||
|
||||
gboolean my_boolean;
|
||||
|
||||
guchar my_uchar;
|
||||
guint my_uint;
|
||||
guint8 my_uint8;
|
||||
guint16 my_uint16;
|
||||
guint32 my_uint32;
|
||||
guint64 my_uint64;
|
||||
gushort my_ushort;
|
||||
gulong my_ulong;
|
||||
|
||||
gchar my_char;
|
||||
gint my_int;
|
||||
gint8 my_int8;
|
||||
gint16 my_int16;
|
||||
gint32 my_int32;
|
||||
gint64 my_int64;
|
||||
gshort my_short;
|
||||
glong my_long;
|
||||
} callback_arg;
|
||||
#define dyn_CAST(gtype,var) (((callback_arg*)var)->my_##gtype)
|
||||
|
||||
#include "../MMU.h"
|
||||
#include "../registers.h"
|
||||
#include "../armcpu.h"
|
||||
#include "../NDSSystem.h"
|
||||
#include "../GPU.h"
|
||||
#include "../sndsdl.h"
|
||||
#include "../ctrlssdl.h"
|
||||
#include "../types.h"
|
||||
#include "../saves.h"
|
||||
#include "../render3D.h"
|
||||
#include "desmume.h"
|
||||
|
||||
// autoconnect with strings as user_data
|
||||
|
||||
void
|
||||
glade_xml_signal_autoconnect_StringObject (GladeXML *self);
|
||||
|
||||
//---
|
||||
|
||||
extern int Frameskip;
|
||||
|
||||
/* main.cpp */
|
||||
extern GtkWidget * pWindow;
|
||||
extern GtkWidget * pDrawingArea, * pDrawingArea2;
|
||||
extern GladeXML * xml, * xml_tools;
|
||||
|
||||
typedef void (*VoidFunPtr)();
|
||||
void notify_Tools();
|
||||
void register_Tool(VoidFunPtr fun);
|
||||
void unregister_Tool(VoidFunPtr fun);
|
||||
gchar * get_ui_file (const char *filename);
|
||||
|
||||
/* callbacks.cpp */
|
||||
void enable_rom_features();
|
||||
void resize (float Size1, float Size2);
|
||||
void rotate(float angle);
|
||||
extern gboolean ScreenInvert;
|
||||
|
||||
/* callbacks_IO.cpp */
|
||||
extern float ScreenCoeff_Size[2];
|
||||
extern float ScreenRotate;
|
||||
|
||||
void black_screen ();
|
||||
void edit_controls();
|
||||
void init_joy_labels();
|
||||
|
||||
#endif /* __GLOBALS_H__ */
|
||||
/* globals.h - this file is part of DeSmuME
|
||||
*
|
||||
* Copyright (C) 2007-2015 DeSmuME Team
|
||||
* Copyright (C) 2007 Damien Nozay (damdoum)
|
||||
* Author: damdoum at users.sourceforge.net
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GLOBALS_H__
|
||||
#define __GLOBALS_H__
|
||||
|
||||
#ifndef GTK_UI
|
||||
#define GTK_UI
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// Localization
|
||||
#include <libintl.h>
|
||||
#define _(String) gettext (String)
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
// fix gtk-glade on windows with no configure
|
||||
#ifndef DATADIR
|
||||
#define DATADIR " "
|
||||
#endif
|
||||
#ifndef GLADEUI_UNINSTALLED_DIR
|
||||
#define GLADEUI_UNINSTALLED_DIR "glade/"
|
||||
#endif
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
#include <glade/glade.h>
|
||||
#include <glade/glade-xml.h>
|
||||
|
||||
|
||||
typedef union _callback_arg{
|
||||
gpointer my_pointer;
|
||||
gconstpointer my_constpointer;
|
||||
|
||||
gfloat my_float;
|
||||
gdouble my_double;
|
||||
gsize my_size;
|
||||
gssize my_ssize;
|
||||
|
||||
gboolean my_boolean;
|
||||
|
||||
guchar my_uchar;
|
||||
guint my_uint;
|
||||
guint8 my_uint8;
|
||||
guint16 my_uint16;
|
||||
guint32 my_uint32;
|
||||
guint64 my_uint64;
|
||||
gushort my_ushort;
|
||||
gulong my_ulong;
|
||||
|
||||
gchar my_char;
|
||||
gint my_int;
|
||||
gint8 my_int8;
|
||||
gint16 my_int16;
|
||||
gint32 my_int32;
|
||||
gint64 my_int64;
|
||||
gshort my_short;
|
||||
glong my_long;
|
||||
} callback_arg;
|
||||
#define dyn_CAST(gtype,var) (((callback_arg*)var)->my_##gtype)
|
||||
|
||||
#include "../MMU.h"
|
||||
#include "../registers.h"
|
||||
#include "../armcpu.h"
|
||||
#include "../NDSSystem.h"
|
||||
#include "../GPU.h"
|
||||
#include "../sndsdl.h"
|
||||
#include "../ctrlssdl.h"
|
||||
#include "../types.h"
|
||||
#include "../saves.h"
|
||||
#include "../render3D.h"
|
||||
#include "desmume.h"
|
||||
|
||||
// autoconnect with strings as user_data
|
||||
|
||||
void
|
||||
glade_xml_signal_autoconnect_StringObject (GladeXML *self);
|
||||
|
||||
//---
|
||||
|
||||
extern int Frameskip;
|
||||
|
||||
/* main.cpp */
|
||||
extern GtkWidget * pWindow;
|
||||
extern GtkWidget * pDrawingArea, * pDrawingArea2;
|
||||
extern GladeXML * xml, * xml_tools;
|
||||
|
||||
typedef void (*VoidFunPtr)();
|
||||
void notify_Tools();
|
||||
void register_Tool(VoidFunPtr fun);
|
||||
void unregister_Tool(VoidFunPtr fun);
|
||||
gchar * get_ui_file (const char *filename);
|
||||
|
||||
/* callbacks.cpp */
|
||||
void enable_rom_features();
|
||||
void resize (float Size1, float Size2);
|
||||
void rotate(float angle);
|
||||
extern gboolean ScreenInvert;
|
||||
|
||||
/* callbacks_IO.cpp */
|
||||
extern float ScreenCoeff_Size[2];
|
||||
extern float ScreenRotate;
|
||||
|
||||
void black_screen ();
|
||||
void edit_controls();
|
||||
void init_joy_labels();
|
||||
|
||||
#endif /* __GLOBALS_H__ */
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
/* keyval_names.h - this file is part of DeSmuME
|
||||
*
|
||||
* Copyright (C) 2007 Damien Nozay (damdoum)
|
||||
* Author: damdoum at users.sourceforge.net
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
const char * KEYNAME(int k);
|
||||
void init_keyvals();
|
||||
/* keyval_names.h - this file is part of DeSmuME
|
||||
*
|
||||
* Copyright (C) 2007 Damien Nozay (damdoum)
|
||||
* Author: damdoum at users.sourceforge.net
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
const char * KEYNAME(int k);
|
||||
void init_keyvals();
|
||||
|
|
|
@ -1,29 +1,29 @@
|
|||
/* cheatsGtk.h - this file is part of DeSmuME
|
||||
*
|
||||
* Copyright (C) 2006,2007 DeSmuME Team
|
||||
* Copyright (C) 2007 Pascal Giard (evilynux)
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __CHEATS_H__
|
||||
#define __CHEATS_H__
|
||||
|
||||
void CheatSearch ();
|
||||
void CheatList ();
|
||||
|
||||
#endif /*__CHEATS_H__*/
|
||||
|
||||
/* cheatsGtk.h - this file is part of DeSmuME
|
||||
*
|
||||
* Copyright (C) 2006,2007 DeSmuME Team
|
||||
* Copyright (C) 2007 Pascal Giard (evilynux)
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __CHEATS_H__
|
||||
#define __CHEATS_H__
|
||||
|
||||
void CheatSearch ();
|
||||
void CheatList ();
|
||||
|
||||
#endif /*__CHEATS_H__*/
|
||||
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
#ifndef __DTOOL_H__
|
||||
#define __DTOOL_H__
|
||||
|
||||
typedef void (*dTool_openFn)(int id);
|
||||
typedef void (*dTool_updateFn)();
|
||||
typedef void (*dTool_closeFn)();
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* this should be the same name of the action in the gui xml */
|
||||
const char shortname[16];
|
||||
const char name[32];
|
||||
dTool_openFn open;
|
||||
dTool_updateFn update;
|
||||
dTool_closeFn close;
|
||||
} dTool_t;
|
||||
|
||||
extern void dTool_CloseCallback(int id);
|
||||
|
||||
#endif /*__DTOOL_H__*/
|
||||
#ifndef __DTOOL_H__
|
||||
#define __DTOOL_H__
|
||||
|
||||
typedef void (*dTool_openFn)(int id);
|
||||
typedef void (*dTool_updateFn)();
|
||||
typedef void (*dTool_closeFn)();
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* this should be the same name of the action in the gui xml */
|
||||
const char shortname[16];
|
||||
const char name[32];
|
||||
dTool_openFn open;
|
||||
dTool_updateFn update;
|
||||
dTool_closeFn close;
|
||||
} dTool_t;
|
||||
|
||||
extern void dTool_CloseCallback(int id);
|
||||
|
||||
#endif /*__DTOOL_H__*/
|
||||
|
|
|
@ -1,36 +1,36 @@
|
|||
/* desmume.h - this file is part of DeSmuME
|
||||
*
|
||||
* Copyright (C) 2006,2007 DeSmuME Team
|
||||
* Copyright (C) 2007 Pascal Giard (evilynux)
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __DESMUME_H__
|
||||
#define __DESMUME_H__
|
||||
|
||||
extern void desmume_init( int disable_sound);
|
||||
extern void desmume_free( void);
|
||||
|
||||
extern void desmume_pause( void);
|
||||
extern void desmume_resume( void);
|
||||
extern void desmume_toggle( void);
|
||||
extern bool desmume_running( void);
|
||||
|
||||
extern void desmume_cycle( void);
|
||||
|
||||
#endif /*__DESMUME_H__*/
|
||||
|
||||
/* desmume.h - this file is part of DeSmuME
|
||||
*
|
||||
* Copyright (C) 2006,2007 DeSmuME Team
|
||||
* Copyright (C) 2007 Pascal Giard (evilynux)
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __DESMUME_H__
|
||||
#define __DESMUME_H__
|
||||
|
||||
extern void desmume_init( int disable_sound);
|
||||
extern void desmume_free( void);
|
||||
|
||||
extern void desmume_pause( void);
|
||||
extern void desmume_resume( void);
|
||||
extern void desmume_toggle( void);
|
||||
extern bool desmume_running( void);
|
||||
|
||||
extern void desmume_cycle( void);
|
||||
|
||||
#endif /*__DESMUME_H__*/
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef __DESMUME_GTK_MAIN_H__
|
||||
#define __DESMUME_GTK_MAIN_H__
|
||||
|
||||
void Pause();
|
||||
void Launch();
|
||||
|
||||
#endif
|
||||
#ifndef __DESMUME_GTK_MAIN_H__
|
||||
#define __DESMUME_GTK_MAIN_H__
|
||||
|
||||
void Pause();
|
||||
void Launch();
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
/*
|
||||
Copyright (C) 2009 Guillaume Duhamel
|
||||
|
||||
This file is part of DeSmuME
|
||||
|
||||
DeSmuME is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
DeSmuME is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with DeSmuME; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_LIBOSMESA
|
||||
int init_osmesa_3Demu(void);
|
||||
void deinit_osmesa_3Demu(void);
|
||||
#endif
|
||||
/*
|
||||
Copyright (C) 2009 Guillaume Duhamel
|
||||
|
||||
This file is part of DeSmuME
|
||||
|
||||
DeSmuME is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
DeSmuME is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with DeSmuME; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_LIBOSMESA
|
||||
int init_osmesa_3Demu(void);
|
||||
void deinit_osmesa_3Demu(void);
|
||||
#endif
|
||||
|
|
|
@ -1,29 +1,29 @@
|
|||
/* ioregsview.h - this file is part of DeSmuME
|
||||
*
|
||||
* Copyright (C) 2006,2007 DeSmuME Team
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __IOREGSVIEW_H__
|
||||
#define __IOREGSVIEW_H__
|
||||
|
||||
#include "../dTool.h"
|
||||
|
||||
extern dTool_t dTool_ioregsView;
|
||||
|
||||
#endif /*__IOREGSVIEW_H__*/
|
||||
|
||||
/* ioregsview.h - this file is part of DeSmuME
|
||||
*
|
||||
* Copyright (C) 2006,2007 DeSmuME Team
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __IOREGSVIEW_H__
|
||||
#define __IOREGSVIEW_H__
|
||||
|
||||
#include "../dTool.h"
|
||||
|
||||
extern dTool_t dTool_ioregsView;
|
||||
|
||||
#endif /*__IOREGSVIEW_H__*/
|
||||
|
||||
|
|
|
@ -1,157 +1,157 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (compat_fnmatch.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if __TEST_FNMATCH__
|
||||
#include <assert.h>
|
||||
#endif
|
||||
|
||||
#include <compat/fnmatch.h>
|
||||
|
||||
/* Implemnentation of fnmatch(3) so it can be
|
||||
* distributed to non *nix platforms.
|
||||
*
|
||||
* No flags are implemented ATM.
|
||||
* We don't use them. Add flags as needed. */
|
||||
|
||||
int rl_fnmatch(const char *pattern, const char *string, int flags)
|
||||
{
|
||||
const char *c;
|
||||
int charmatch = 0;
|
||||
int rv;
|
||||
for (c = pattern; *c != '\0'; c++)
|
||||
{
|
||||
/* String ended before pattern */
|
||||
if ((*c != '*') && (*string == '\0'))
|
||||
return FNM_NOMATCH;
|
||||
|
||||
switch (*c)
|
||||
{
|
||||
/* Match any number of unknown chars */
|
||||
case '*':
|
||||
/* Find next node in the pattern
|
||||
* ignoring multiple asterixes
|
||||
*/
|
||||
do {
|
||||
c++;
|
||||
if (*c == '\0')
|
||||
return 0;
|
||||
} while (*c == '*');
|
||||
|
||||
/* Match the remaining pattern
|
||||
* ignoring more and more characters. */
|
||||
do {
|
||||
/* We reached the end of the string without a
|
||||
* match. There is a way to optimize this by
|
||||
* calculating the minimum chars needed to
|
||||
* match the remaining pattern but I don't
|
||||
* think it is worth the work ATM.
|
||||
*/
|
||||
if (*string == '\0')
|
||||
return FNM_NOMATCH;
|
||||
|
||||
rv = rl_fnmatch(c, string, flags);
|
||||
string++;
|
||||
} while (rv != 0);
|
||||
|
||||
return 0;
|
||||
/* Match char from list */
|
||||
case '[':
|
||||
charmatch = 0;
|
||||
for (c++; *c != ']'; c++)
|
||||
{
|
||||
/* Bad format */
|
||||
if (*c == '\0')
|
||||
return FNM_NOMATCH;
|
||||
|
||||
/* Match already found */
|
||||
if (charmatch)
|
||||
continue;
|
||||
|
||||
if (*c == *string)
|
||||
charmatch = 1;
|
||||
}
|
||||
|
||||
/* No match in list */
|
||||
if (!charmatch)
|
||||
return FNM_NOMATCH;
|
||||
|
||||
string++;
|
||||
break;
|
||||
/* Has any character */
|
||||
case '?':
|
||||
string++;
|
||||
break;
|
||||
/* Match following character verbatim */
|
||||
case '\\':
|
||||
c++;
|
||||
/* Dangling escape at end of pattern.
|
||||
* FIXME: Was c == '\0' (makes no sense).
|
||||
* Not sure if c == NULL or *c == '\0'
|
||||
* is intended. Assuming *c due to c++ right before. */
|
||||
if (*c == '\0')
|
||||
return FNM_NOMATCH;
|
||||
default:
|
||||
if (*c != *string)
|
||||
return FNM_NOMATCH;
|
||||
string++;
|
||||
}
|
||||
}
|
||||
|
||||
/* End of string and end of pattend */
|
||||
if (*string == '\0')
|
||||
return 0;
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
|
||||
#if __TEST_FNMATCH__
|
||||
int main(void)
|
||||
{
|
||||
assert(rl_fnmatch("TEST", "TEST", 0) == 0);
|
||||
assert(rl_fnmatch("TE?T", "TEST", 0) == 0);
|
||||
assert(rl_fnmatch("TE[Ssa]T", "TEST", 0) == 0);
|
||||
assert(rl_fnmatch("TE[Ssda]T", "TEsT", 0) == 0);
|
||||
assert(rl_fnmatch("TE[Ssda]T", "TEdT", 0) == 0);
|
||||
assert(rl_fnmatch("TE[Ssda]T", "TEaT", 0) == 0);
|
||||
assert(rl_fnmatch("TEST*", "TEST", 0) == 0);
|
||||
assert(rl_fnmatch("TEST**", "TEST", 0) == 0);
|
||||
assert(rl_fnmatch("TE*ST*", "TEST", 0) == 0);
|
||||
assert(rl_fnmatch("TE**ST*", "TEST", 0) == 0);
|
||||
assert(rl_fnmatch("TE**ST*", "TExST", 0) == 0);
|
||||
assert(rl_fnmatch("TE**ST", "TEST", 0) == 0);
|
||||
assert(rl_fnmatch("TE**ST", "TExST", 0) == 0);
|
||||
assert(rl_fnmatch("TE\\**ST", "TE*xST", 0) == 0);
|
||||
assert(rl_fnmatch("*.*", "test.jpg", 0) == 0);
|
||||
assert(rl_fnmatch("*.jpg", "test.jpg", 0) == 0);
|
||||
assert(rl_fnmatch("*.[Jj][Pp][Gg]", "test.jPg", 0) == 0);
|
||||
assert(rl_fnmatch("*.[Jj]*[Gg]", "test.jPg", 0) == 0);
|
||||
assert(rl_fnmatch("TEST?", "TEST", 0) == FNM_NOMATCH);
|
||||
assert(rl_fnmatch("TES[asd", "TEST", 0) == FNM_NOMATCH);
|
||||
assert(rl_fnmatch("TEST\\", "TEST", 0) == FNM_NOMATCH);
|
||||
assert(rl_fnmatch("TEST*S", "TEST", 0) == FNM_NOMATCH);
|
||||
assert(rl_fnmatch("TE**ST", "TExT", 0) == FNM_NOMATCH);
|
||||
assert(rl_fnmatch("TE\\*T", "TExT", 0) == FNM_NOMATCH);
|
||||
assert(rl_fnmatch("TES?", "TES", 0) == FNM_NOMATCH);
|
||||
assert(rl_fnmatch("TE", "TEST", 0) == FNM_NOMATCH);
|
||||
assert(rl_fnmatch("TEST!", "TEST", 0) == FNM_NOMATCH);
|
||||
assert(rl_fnmatch("DSAD", "TEST", 0) == FNM_NOMATCH);
|
||||
}
|
||||
#endif
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (compat_fnmatch.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if __TEST_FNMATCH__
|
||||
#include <assert.h>
|
||||
#endif
|
||||
|
||||
#include <compat/fnmatch.h>
|
||||
|
||||
/* Implemnentation of fnmatch(3) so it can be
|
||||
* distributed to non *nix platforms.
|
||||
*
|
||||
* No flags are implemented ATM.
|
||||
* We don't use them. Add flags as needed. */
|
||||
|
||||
int rl_fnmatch(const char *pattern, const char *string, int flags)
|
||||
{
|
||||
const char *c;
|
||||
int charmatch = 0;
|
||||
int rv;
|
||||
for (c = pattern; *c != '\0'; c++)
|
||||
{
|
||||
/* String ended before pattern */
|
||||
if ((*c != '*') && (*string == '\0'))
|
||||
return FNM_NOMATCH;
|
||||
|
||||
switch (*c)
|
||||
{
|
||||
/* Match any number of unknown chars */
|
||||
case '*':
|
||||
/* Find next node in the pattern
|
||||
* ignoring multiple asterixes
|
||||
*/
|
||||
do {
|
||||
c++;
|
||||
if (*c == '\0')
|
||||
return 0;
|
||||
} while (*c == '*');
|
||||
|
||||
/* Match the remaining pattern
|
||||
* ignoring more and more characters. */
|
||||
do {
|
||||
/* We reached the end of the string without a
|
||||
* match. There is a way to optimize this by
|
||||
* calculating the minimum chars needed to
|
||||
* match the remaining pattern but I don't
|
||||
* think it is worth the work ATM.
|
||||
*/
|
||||
if (*string == '\0')
|
||||
return FNM_NOMATCH;
|
||||
|
||||
rv = rl_fnmatch(c, string, flags);
|
||||
string++;
|
||||
} while (rv != 0);
|
||||
|
||||
return 0;
|
||||
/* Match char from list */
|
||||
case '[':
|
||||
charmatch = 0;
|
||||
for (c++; *c != ']'; c++)
|
||||
{
|
||||
/* Bad format */
|
||||
if (*c == '\0')
|
||||
return FNM_NOMATCH;
|
||||
|
||||
/* Match already found */
|
||||
if (charmatch)
|
||||
continue;
|
||||
|
||||
if (*c == *string)
|
||||
charmatch = 1;
|
||||
}
|
||||
|
||||
/* No match in list */
|
||||
if (!charmatch)
|
||||
return FNM_NOMATCH;
|
||||
|
||||
string++;
|
||||
break;
|
||||
/* Has any character */
|
||||
case '?':
|
||||
string++;
|
||||
break;
|
||||
/* Match following character verbatim */
|
||||
case '\\':
|
||||
c++;
|
||||
/* Dangling escape at end of pattern.
|
||||
* FIXME: Was c == '\0' (makes no sense).
|
||||
* Not sure if c == NULL or *c == '\0'
|
||||
* is intended. Assuming *c due to c++ right before. */
|
||||
if (*c == '\0')
|
||||
return FNM_NOMATCH;
|
||||
default:
|
||||
if (*c != *string)
|
||||
return FNM_NOMATCH;
|
||||
string++;
|
||||
}
|
||||
}
|
||||
|
||||
/* End of string and end of pattend */
|
||||
if (*string == '\0')
|
||||
return 0;
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
|
||||
#if __TEST_FNMATCH__
|
||||
int main(void)
|
||||
{
|
||||
assert(rl_fnmatch("TEST", "TEST", 0) == 0);
|
||||
assert(rl_fnmatch("TE?T", "TEST", 0) == 0);
|
||||
assert(rl_fnmatch("TE[Ssa]T", "TEST", 0) == 0);
|
||||
assert(rl_fnmatch("TE[Ssda]T", "TEsT", 0) == 0);
|
||||
assert(rl_fnmatch("TE[Ssda]T", "TEdT", 0) == 0);
|
||||
assert(rl_fnmatch("TE[Ssda]T", "TEaT", 0) == 0);
|
||||
assert(rl_fnmatch("TEST*", "TEST", 0) == 0);
|
||||
assert(rl_fnmatch("TEST**", "TEST", 0) == 0);
|
||||
assert(rl_fnmatch("TE*ST*", "TEST", 0) == 0);
|
||||
assert(rl_fnmatch("TE**ST*", "TEST", 0) == 0);
|
||||
assert(rl_fnmatch("TE**ST*", "TExST", 0) == 0);
|
||||
assert(rl_fnmatch("TE**ST", "TEST", 0) == 0);
|
||||
assert(rl_fnmatch("TE**ST", "TExST", 0) == 0);
|
||||
assert(rl_fnmatch("TE\\**ST", "TE*xST", 0) == 0);
|
||||
assert(rl_fnmatch("*.*", "test.jpg", 0) == 0);
|
||||
assert(rl_fnmatch("*.jpg", "test.jpg", 0) == 0);
|
||||
assert(rl_fnmatch("*.[Jj][Pp][Gg]", "test.jPg", 0) == 0);
|
||||
assert(rl_fnmatch("*.[Jj]*[Gg]", "test.jPg", 0) == 0);
|
||||
assert(rl_fnmatch("TEST?", "TEST", 0) == FNM_NOMATCH);
|
||||
assert(rl_fnmatch("TES[asd", "TEST", 0) == FNM_NOMATCH);
|
||||
assert(rl_fnmatch("TEST\\", "TEST", 0) == FNM_NOMATCH);
|
||||
assert(rl_fnmatch("TEST*S", "TEST", 0) == FNM_NOMATCH);
|
||||
assert(rl_fnmatch("TE**ST", "TExT", 0) == FNM_NOMATCH);
|
||||
assert(rl_fnmatch("TE\\*T", "TExT", 0) == FNM_NOMATCH);
|
||||
assert(rl_fnmatch("TES?", "TES", 0) == FNM_NOMATCH);
|
||||
assert(rl_fnmatch("TE", "TEST", 0) == FNM_NOMATCH);
|
||||
assert(rl_fnmatch("TEST!", "TEST", 0) == FNM_NOMATCH);
|
||||
assert(rl_fnmatch("DSAD", "TEST", 0) == FNM_NOMATCH);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,219 +1,219 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (compat_getopt.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <boolean.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <retro_miscellaneous.h>
|
||||
|
||||
#include <compat/getopt.h>
|
||||
#include <compat/strl.h>
|
||||
#include <compat/strcasestr.h>
|
||||
#include <compat/posix_string.h>
|
||||
|
||||
#include <retro_assert.h>
|
||||
|
||||
char *optarg;
|
||||
int optind, opterr, optopt;
|
||||
|
||||
static bool is_short_option(const char *str)
|
||||
{
|
||||
return str[0] == '-' && str[1] != '-';
|
||||
}
|
||||
|
||||
static bool is_long_option(const char *str)
|
||||
{
|
||||
return str[0] == '-' && str[1] == '-';
|
||||
}
|
||||
|
||||
static int find_short_index(char * const *argv)
|
||||
{
|
||||
int idx;
|
||||
for (idx = 0; argv[idx]; idx++)
|
||||
{
|
||||
if (is_short_option(argv[idx]))
|
||||
return idx;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int find_long_index(char * const *argv)
|
||||
{
|
||||
int idx;
|
||||
for (idx = 0; argv[idx]; idx++)
|
||||
{
|
||||
if (is_long_option(argv[idx]))
|
||||
return idx;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int parse_short(const char *optstring, char * const *argv)
|
||||
{
|
||||
bool extra_opt, takes_arg, embedded_arg;
|
||||
const char *opt = NULL;
|
||||
char arg = argv[0][1];
|
||||
|
||||
if (arg == ':')
|
||||
return '?';
|
||||
|
||||
opt = strchr(optstring, arg);
|
||||
if (!opt)
|
||||
return '?';
|
||||
|
||||
extra_opt = argv[0][2];
|
||||
takes_arg = opt[1] == ':';
|
||||
|
||||
/* If we take an argument, and we see additional characters,
|
||||
* this is in fact the argument (i.e. -cfoo is same as -c foo). */
|
||||
embedded_arg = extra_opt && takes_arg;
|
||||
|
||||
if (takes_arg)
|
||||
{
|
||||
if (embedded_arg)
|
||||
{
|
||||
optarg = argv[0] + 2;
|
||||
optind++;
|
||||
}
|
||||
else
|
||||
{
|
||||
optarg = argv[1];
|
||||
optind += 2;
|
||||
}
|
||||
|
||||
return optarg ? opt[0] : '?';
|
||||
}
|
||||
|
||||
if (embedded_arg)
|
||||
{
|
||||
/* If we see additional characters,
|
||||
* and they don't take arguments, this
|
||||
* means we have multiple flags in one. */
|
||||
memmove(&argv[0][1], &argv[0][2], strlen(&argv[0][2]) + 1);
|
||||
return opt[0];
|
||||
}
|
||||
|
||||
optind++;
|
||||
return opt[0];
|
||||
}
|
||||
|
||||
static int parse_long(const struct option *longopts, char * const *argv)
|
||||
{
|
||||
size_t indice;
|
||||
const struct option *opt = NULL;
|
||||
for (indice = 0; longopts[indice].name; indice++)
|
||||
{
|
||||
if (!strcmp(longopts[indice].name, &argv[0][2]))
|
||||
{
|
||||
opt = &longopts[indice];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!opt)
|
||||
return '?';
|
||||
|
||||
/* getopt_long has an "optional" arg, but we don't bother with that. */
|
||||
if (opt->has_arg && !argv[1])
|
||||
return '?';
|
||||
|
||||
if (opt->has_arg)
|
||||
{
|
||||
optarg = argv[1];
|
||||
optind += 2;
|
||||
}
|
||||
else
|
||||
optind++;
|
||||
|
||||
if (opt->flag)
|
||||
{
|
||||
*opt->flag = opt->val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return opt->val;
|
||||
}
|
||||
|
||||
static void shuffle_block(char **begin, char **last, char **end)
|
||||
{
|
||||
ptrdiff_t len = last - begin;
|
||||
const char **tmp = (const char**)calloc(len, sizeof(const char*));
|
||||
|
||||
retro_assert(tmp);
|
||||
|
||||
memcpy(tmp, begin, len * sizeof(const char*));
|
||||
memmove(begin, last, (end - last) * sizeof(const char*));
|
||||
memcpy(end - len, tmp, len * sizeof(const char*));
|
||||
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
int getopt_long(int argc, char *argv[],
|
||||
const char *optstring, const struct option *longopts, int *longindex)
|
||||
{
|
||||
int short_index, long_index;
|
||||
|
||||
(void)longindex;
|
||||
|
||||
if (optind == 0)
|
||||
optind = 1;
|
||||
|
||||
if (argc == 1)
|
||||
return -1;
|
||||
|
||||
short_index = find_short_index(&argv[optind]);
|
||||
long_index = find_long_index(&argv[optind]);
|
||||
|
||||
/* We're done here. */
|
||||
if (short_index == -1 && long_index == -1)
|
||||
return -1;
|
||||
|
||||
/* Reorder argv so that non-options come last.
|
||||
* Non-POSIXy, but that's what getopt does by default. */
|
||||
if ((short_index > 0) && ((short_index < long_index) || (long_index == -1)))
|
||||
{
|
||||
shuffle_block(&argv[optind], &argv[optind + short_index], &argv[argc]);
|
||||
short_index = 0;
|
||||
}
|
||||
else if ((long_index > 0) && ((long_index < short_index)
|
||||
|| (short_index == -1)))
|
||||
{
|
||||
shuffle_block(&argv[optind], &argv[optind + long_index], &argv[argc]);
|
||||
long_index = 0;
|
||||
}
|
||||
|
||||
retro_assert(short_index == 0 || long_index == 0);
|
||||
|
||||
if (short_index == 0)
|
||||
return parse_short(optstring, &argv[optind]);
|
||||
if (long_index == 0)
|
||||
return parse_long(longopts, &argv[optind]);
|
||||
|
||||
return '?';
|
||||
}
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (compat_getopt.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <boolean.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <retro_miscellaneous.h>
|
||||
|
||||
#include <compat/getopt.h>
|
||||
#include <compat/strl.h>
|
||||
#include <compat/strcasestr.h>
|
||||
#include <compat/posix_string.h>
|
||||
|
||||
#include <retro_assert.h>
|
||||
|
||||
char *optarg;
|
||||
int optind, opterr, optopt;
|
||||
|
||||
static bool is_short_option(const char *str)
|
||||
{
|
||||
return str[0] == '-' && str[1] != '-';
|
||||
}
|
||||
|
||||
static bool is_long_option(const char *str)
|
||||
{
|
||||
return str[0] == '-' && str[1] == '-';
|
||||
}
|
||||
|
||||
static int find_short_index(char * const *argv)
|
||||
{
|
||||
int idx;
|
||||
for (idx = 0; argv[idx]; idx++)
|
||||
{
|
||||
if (is_short_option(argv[idx]))
|
||||
return idx;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int find_long_index(char * const *argv)
|
||||
{
|
||||
int idx;
|
||||
for (idx = 0; argv[idx]; idx++)
|
||||
{
|
||||
if (is_long_option(argv[idx]))
|
||||
return idx;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int parse_short(const char *optstring, char * const *argv)
|
||||
{
|
||||
bool extra_opt, takes_arg, embedded_arg;
|
||||
const char *opt = NULL;
|
||||
char arg = argv[0][1];
|
||||
|
||||
if (arg == ':')
|
||||
return '?';
|
||||
|
||||
opt = strchr(optstring, arg);
|
||||
if (!opt)
|
||||
return '?';
|
||||
|
||||
extra_opt = argv[0][2];
|
||||
takes_arg = opt[1] == ':';
|
||||
|
||||
/* If we take an argument, and we see additional characters,
|
||||
* this is in fact the argument (i.e. -cfoo is same as -c foo). */
|
||||
embedded_arg = extra_opt && takes_arg;
|
||||
|
||||
if (takes_arg)
|
||||
{
|
||||
if (embedded_arg)
|
||||
{
|
||||
optarg = argv[0] + 2;
|
||||
optind++;
|
||||
}
|
||||
else
|
||||
{
|
||||
optarg = argv[1];
|
||||
optind += 2;
|
||||
}
|
||||
|
||||
return optarg ? opt[0] : '?';
|
||||
}
|
||||
|
||||
if (embedded_arg)
|
||||
{
|
||||
/* If we see additional characters,
|
||||
* and they don't take arguments, this
|
||||
* means we have multiple flags in one. */
|
||||
memmove(&argv[0][1], &argv[0][2], strlen(&argv[0][2]) + 1);
|
||||
return opt[0];
|
||||
}
|
||||
|
||||
optind++;
|
||||
return opt[0];
|
||||
}
|
||||
|
||||
static int parse_long(const struct option *longopts, char * const *argv)
|
||||
{
|
||||
size_t indice;
|
||||
const struct option *opt = NULL;
|
||||
for (indice = 0; longopts[indice].name; indice++)
|
||||
{
|
||||
if (!strcmp(longopts[indice].name, &argv[0][2]))
|
||||
{
|
||||
opt = &longopts[indice];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!opt)
|
||||
return '?';
|
||||
|
||||
/* getopt_long has an "optional" arg, but we don't bother with that. */
|
||||
if (opt->has_arg && !argv[1])
|
||||
return '?';
|
||||
|
||||
if (opt->has_arg)
|
||||
{
|
||||
optarg = argv[1];
|
||||
optind += 2;
|
||||
}
|
||||
else
|
||||
optind++;
|
||||
|
||||
if (opt->flag)
|
||||
{
|
||||
*opt->flag = opt->val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return opt->val;
|
||||
}
|
||||
|
||||
static void shuffle_block(char **begin, char **last, char **end)
|
||||
{
|
||||
ptrdiff_t len = last - begin;
|
||||
const char **tmp = (const char**)calloc(len, sizeof(const char*));
|
||||
|
||||
retro_assert(tmp);
|
||||
|
||||
memcpy(tmp, begin, len * sizeof(const char*));
|
||||
memmove(begin, last, (end - last) * sizeof(const char*));
|
||||
memcpy(end - len, tmp, len * sizeof(const char*));
|
||||
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
int getopt_long(int argc, char *argv[],
|
||||
const char *optstring, const struct option *longopts, int *longindex)
|
||||
{
|
||||
int short_index, long_index;
|
||||
|
||||
(void)longindex;
|
||||
|
||||
if (optind == 0)
|
||||
optind = 1;
|
||||
|
||||
if (argc == 1)
|
||||
return -1;
|
||||
|
||||
short_index = find_short_index(&argv[optind]);
|
||||
long_index = find_long_index(&argv[optind]);
|
||||
|
||||
/* We're done here. */
|
||||
if (short_index == -1 && long_index == -1)
|
||||
return -1;
|
||||
|
||||
/* Reorder argv so that non-options come last.
|
||||
* Non-POSIXy, but that's what getopt does by default. */
|
||||
if ((short_index > 0) && ((short_index < long_index) || (long_index == -1)))
|
||||
{
|
||||
shuffle_block(&argv[optind], &argv[optind + short_index], &argv[argc]);
|
||||
short_index = 0;
|
||||
}
|
||||
else if ((long_index > 0) && ((long_index < short_index)
|
||||
|| (short_index == -1)))
|
||||
{
|
||||
shuffle_block(&argv[optind], &argv[optind + long_index], &argv[argc]);
|
||||
long_index = 0;
|
||||
}
|
||||
|
||||
retro_assert(short_index == 0 || long_index == 0);
|
||||
|
||||
if (short_index == 0)
|
||||
return parse_short(optstring, &argv[optind]);
|
||||
if (long_index == 0)
|
||||
return parse_long(longopts, &argv[optind]);
|
||||
|
||||
return '?';
|
||||
}
|
||||
|
|
|
@ -1,106 +1,106 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (compat.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include <compat/posix_string.h>
|
||||
|
||||
#include <retro_assert.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#undef strcasecmp
|
||||
#undef strdup
|
||||
#undef isblank
|
||||
#undef strtok_r
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <compat/strl.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
int retro_strcasecmp__(const char *a, const char *b)
|
||||
{
|
||||
while (*a && *b)
|
||||
{
|
||||
int a_ = tolower(*a);
|
||||
int b_ = tolower(*b);
|
||||
|
||||
if (a_ != b_)
|
||||
return a_ - b_;
|
||||
|
||||
a++;
|
||||
b++;
|
||||
}
|
||||
|
||||
return tolower(*a) - tolower(*b);
|
||||
}
|
||||
|
||||
char *retro_strdup__(const char *orig)
|
||||
{
|
||||
size_t len = strlen(orig) + 1;
|
||||
char *ret = (char*)malloc(len);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
strlcpy(ret, orig, len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int retro_isblank__(int c)
|
||||
{
|
||||
return (c == ' ') || (c == '\t');
|
||||
}
|
||||
|
||||
char *retro_strtok_r__(char *str, const char *delim, char **saveptr)
|
||||
{
|
||||
char *first = NULL;
|
||||
if (!saveptr || !delim)
|
||||
return NULL;
|
||||
|
||||
if (str)
|
||||
*saveptr = str;
|
||||
|
||||
do
|
||||
{
|
||||
char *ptr = NULL;
|
||||
first = *saveptr;
|
||||
while (*first && strchr(delim, *first))
|
||||
*first++ = '\0';
|
||||
|
||||
if (*first == '\0')
|
||||
return NULL;
|
||||
|
||||
ptr = first + 1;
|
||||
|
||||
while (*ptr && !strchr(delim, *ptr))
|
||||
ptr++;
|
||||
|
||||
*saveptr = ptr + (*ptr ? 1 : 0);
|
||||
*ptr = '\0';
|
||||
} while (strlen(first) == 0);
|
||||
|
||||
return first;
|
||||
}
|
||||
|
||||
#endif
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (compat.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include <compat/posix_string.h>
|
||||
|
||||
#include <retro_assert.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#undef strcasecmp
|
||||
#undef strdup
|
||||
#undef isblank
|
||||
#undef strtok_r
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <compat/strl.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
int retro_strcasecmp__(const char *a, const char *b)
|
||||
{
|
||||
while (*a && *b)
|
||||
{
|
||||
int a_ = tolower(*a);
|
||||
int b_ = tolower(*b);
|
||||
|
||||
if (a_ != b_)
|
||||
return a_ - b_;
|
||||
|
||||
a++;
|
||||
b++;
|
||||
}
|
||||
|
||||
return tolower(*a) - tolower(*b);
|
||||
}
|
||||
|
||||
char *retro_strdup__(const char *orig)
|
||||
{
|
||||
size_t len = strlen(orig) + 1;
|
||||
char *ret = (char*)malloc(len);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
strlcpy(ret, orig, len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int retro_isblank__(int c)
|
||||
{
|
||||
return (c == ' ') || (c == '\t');
|
||||
}
|
||||
|
||||
char *retro_strtok_r__(char *str, const char *delim, char **saveptr)
|
||||
{
|
||||
char *first = NULL;
|
||||
if (!saveptr || !delim)
|
||||
return NULL;
|
||||
|
||||
if (str)
|
||||
*saveptr = str;
|
||||
|
||||
do
|
||||
{
|
||||
char *ptr = NULL;
|
||||
first = *saveptr;
|
||||
while (*first && strchr(delim, *first))
|
||||
*first++ = '\0';
|
||||
|
||||
if (*first == '\0')
|
||||
return NULL;
|
||||
|
||||
ptr = first + 1;
|
||||
|
||||
while (*ptr && !strchr(delim, *ptr))
|
||||
ptr++;
|
||||
|
||||
*saveptr = ptr + (*ptr ? 1 : 0);
|
||||
*ptr = '\0';
|
||||
} while (strlen(first) == 0);
|
||||
|
||||
return first;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,53 +1,53 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (compat_snprintf.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* THIS FILE HAS NOT BEEN VALIDATED ON PLATFORMS BESIDES MSVC */
|
||||
|
||||
#include <retro_common.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
/* http://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010 */
|
||||
|
||||
int c99_vsnprintf_retro__(char *outBuf, size_t size, const char *format, va_list ap)
|
||||
{
|
||||
int count = -1;
|
||||
|
||||
if (size != 0)
|
||||
count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap);
|
||||
if (count == -1)
|
||||
count = _vscprintf(format, ap);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int c99_snprintf_retro__(char *outBuf, size_t size, const char *format, ...)
|
||||
{
|
||||
int count;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
count = c99_vsnprintf_retro__(outBuf, size, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
return count;
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (compat_snprintf.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* THIS FILE HAS NOT BEEN VALIDATED ON PLATFORMS BESIDES MSVC */
|
||||
|
||||
#include <retro_common.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
/* http://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010 */
|
||||
|
||||
int c99_vsnprintf_retro__(char *outBuf, size_t size, const char *format, va_list ap)
|
||||
{
|
||||
int count = -1;
|
||||
|
||||
if (size != 0)
|
||||
count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap);
|
||||
if (count == -1)
|
||||
count = _vscprintf(format, ap);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int c99_snprintf_retro__(char *outBuf, size_t size, const char *format, ...)
|
||||
{
|
||||
int count;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
count = c99_vsnprintf_retro__(outBuf, size, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
return count;
|
||||
}
|
|
@ -1,59 +1,59 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (compat_strcasestr.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include <compat/strcasestr.h>
|
||||
#include <retro_assert.h>
|
||||
|
||||
/* Pretty much strncasecmp. */
|
||||
static int casencmp(const char *a, const char *b, size_t n)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
int a_lower = tolower(a[i]);
|
||||
int b_lower = tolower(b[i]);
|
||||
if (a_lower != b_lower)
|
||||
return a_lower - b_lower;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *strcasestr_retro__(const char *haystack, const char *needle)
|
||||
{
|
||||
size_t i, hay_len, needle_len, search_off;
|
||||
|
||||
hay_len = strlen(haystack);
|
||||
needle_len = strlen(needle);
|
||||
if (needle_len > hay_len)
|
||||
return NULL;
|
||||
|
||||
search_off = hay_len - needle_len;
|
||||
for (i = 0; i <= search_off; i++)
|
||||
if (!casencmp(haystack + i, needle, needle_len))
|
||||
return (char*)haystack + i;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (compat_strcasestr.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include <compat/strcasestr.h>
|
||||
#include <retro_assert.h>
|
||||
|
||||
/* Pretty much strncasecmp. */
|
||||
static int casencmp(const char *a, const char *b, size_t n)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
int a_lower = tolower(a[i]);
|
||||
int b_lower = tolower(b[i]);
|
||||
if (a_lower != b_lower)
|
||||
return a_lower - b_lower;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *strcasestr_retro__(const char *haystack, const char *needle)
|
||||
{
|
||||
size_t i, hay_len, needle_len, search_off;
|
||||
|
||||
hay_len = strlen(haystack);
|
||||
needle_len = strlen(needle);
|
||||
if (needle_len > hay_len)
|
||||
return NULL;
|
||||
|
||||
search_off = hay_len - needle_len;
|
||||
for (i = 0; i <= search_off; i++)
|
||||
if (!casencmp(haystack + i, needle, needle_len))
|
||||
return (char*)haystack + i;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -1,61 +1,61 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (compat_strl.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include <compat/strl.h>
|
||||
#include <compat/posix_string.h>
|
||||
|
||||
#include <retro_assert.h>
|
||||
|
||||
/* Implementation of strlcpy()/strlcat() based on OpenBSD. */
|
||||
|
||||
size_t strlcpy(char *dest, const char *source, size_t size)
|
||||
{
|
||||
size_t src_size = 0;
|
||||
size_t n = size;
|
||||
|
||||
if (n)
|
||||
while (--n && (*dest++ = *source++)) src_size++;
|
||||
|
||||
if (!n)
|
||||
{
|
||||
if (size) *dest = '\0';
|
||||
while (*source++) src_size++;
|
||||
}
|
||||
|
||||
return src_size;
|
||||
}
|
||||
|
||||
size_t strlcat(char *dest, const char *source, size_t size)
|
||||
{
|
||||
size_t len = strlen(dest);
|
||||
|
||||
dest += len;
|
||||
|
||||
if (len > size)
|
||||
size = 0;
|
||||
else
|
||||
size -= len;
|
||||
|
||||
return len + strlcpy(dest, source, size);
|
||||
}
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (compat_strl.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include <compat/strl.h>
|
||||
#include <compat/posix_string.h>
|
||||
|
||||
#include <retro_assert.h>
|
||||
|
||||
/* Implementation of strlcpy()/strlcat() based on OpenBSD. */
|
||||
|
||||
size_t strlcpy(char *dest, const char *source, size_t size)
|
||||
{
|
||||
size_t src_size = 0;
|
||||
size_t n = size;
|
||||
|
||||
if (n)
|
||||
while (--n && (*dest++ = *source++)) src_size++;
|
||||
|
||||
if (!n)
|
||||
{
|
||||
if (size) *dest = '\0';
|
||||
while (*source++) src_size++;
|
||||
}
|
||||
|
||||
return src_size;
|
||||
}
|
||||
|
||||
size_t strlcat(char *dest, const char *source, size_t size)
|
||||
{
|
||||
size_t len = strlen(dest);
|
||||
|
||||
dest += len;
|
||||
|
||||
if (len > size)
|
||||
size = 0;
|
||||
else
|
||||
size -= len;
|
||||
|
||||
return len + strlcpy(dest, source, size);
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#ifndef __LIBRETRO_SDK_CRT_STRING_H_
|
||||
#define __LIBRETRO_SDK_CRT_STRING_H_
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
void *memcpy(void *dst, const void *src, size_t len);
|
||||
|
||||
void *memset(void *b, int c, size_t len);
|
||||
|
||||
#endif
|
||||
#ifndef __LIBRETRO_SDK_CRT_STRING_H_
|
||||
#define __LIBRETRO_SDK_CRT_STRING_H_
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
void *memcpy(void *dst, const void *src, size_t len);
|
||||
|
||||
void *memset(void *b, int c, size_t len);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,34 +1,34 @@
|
|||
#ifdef _MSC_VER
|
||||
#include <cruntime.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
void *memset(void *dst, int val, size_t count)
|
||||
{
|
||||
void *start = dst;
|
||||
|
||||
#if defined(_M_IA64) || defined (_M_AMD64) || defined(_M_ALPHA) || defined (_M_PPC)
|
||||
extern void RtlFillMemory(void *, size_t count, char);
|
||||
|
||||
RtlFillMemory(dst, count, (char)val);
|
||||
#else
|
||||
while (count--)
|
||||
{
|
||||
*(char*)dst = (char)val;
|
||||
dst = (char*)dst + 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
void *memcpy(void *dst, const void *src, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
((unsigned char *)dst)[i] = ((unsigned char *)src)[i];
|
||||
|
||||
return dst;
|
||||
}
|
||||
#ifdef _MSC_VER
|
||||
#include <cruntime.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
void *memset(void *dst, int val, size_t count)
|
||||
{
|
||||
void *start = dst;
|
||||
|
||||
#if defined(_M_IA64) || defined (_M_AMD64) || defined(_M_ALPHA) || defined (_M_PPC)
|
||||
extern void RtlFillMemory(void *, size_t count, char);
|
||||
|
||||
RtlFillMemory(dst, count, (char)val);
|
||||
#else
|
||||
while (count--)
|
||||
{
|
||||
*(char*)dst = (char)val;
|
||||
dst = (char*)dst + 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
void *memcpy(void *dst, const void *src, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
((unsigned char *)dst)[i] = ((unsigned char *)src)[i];
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
|
|
@ -1,150 +1,150 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (dylib.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <dynamic/dylib.h>
|
||||
|
||||
#ifdef NEED_DYNAMIC
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <compat/posix_string.h>
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
static char last_dyn_error[512];
|
||||
|
||||
static void set_dl_error(void)
|
||||
{
|
||||
DWORD err = GetLastError();
|
||||
|
||||
if (FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
NULL,
|
||||
err,
|
||||
MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),
|
||||
last_dyn_error,
|
||||
sizeof(last_dyn_error) - 1,
|
||||
NULL) == 0)
|
||||
snprintf(last_dyn_error, sizeof(last_dyn_error) - 1,
|
||||
"unknown error %lu", err);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* dylib_load:
|
||||
* @path : Path to libretro core library.
|
||||
*
|
||||
* Platform independent dylib loading.
|
||||
*
|
||||
* Returns: library handle on success, otherwise NULL.
|
||||
**/
|
||||
dylib_t dylib_load(const char *path)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
int prevmode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
|
||||
dylib_t lib = LoadLibrary(path);
|
||||
|
||||
SetErrorMode(prevmode);
|
||||
|
||||
if (!lib)
|
||||
{
|
||||
set_dl_error();
|
||||
return NULL;
|
||||
}
|
||||
last_dyn_error[0] = 0;
|
||||
#else
|
||||
dylib_t lib = dlopen(path, RTLD_LAZY);
|
||||
#endif
|
||||
return lib;
|
||||
}
|
||||
|
||||
char *dylib_error(void)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (last_dyn_error[0])
|
||||
return last_dyn_error;
|
||||
return NULL;
|
||||
#else
|
||||
return (char*)dlerror();
|
||||
#endif
|
||||
}
|
||||
|
||||
function_t dylib_proc(dylib_t lib, const char *proc)
|
||||
{
|
||||
function_t sym;
|
||||
|
||||
#ifdef _WIN32
|
||||
sym = (function_t)GetProcAddress(lib ?
|
||||
(HMODULE)lib : GetModuleHandle(NULL), proc);
|
||||
if (!sym)
|
||||
{
|
||||
set_dl_error();
|
||||
return NULL;
|
||||
}
|
||||
last_dyn_error[0] = 0;
|
||||
#else
|
||||
void *ptr_sym = NULL;
|
||||
|
||||
if (lib)
|
||||
ptr_sym = dlsym(lib, proc);
|
||||
else
|
||||
{
|
||||
void *handle = dlopen(NULL, RTLD_LAZY);
|
||||
if (handle)
|
||||
{
|
||||
ptr_sym = dlsym(handle, proc);
|
||||
dlclose(handle);
|
||||
}
|
||||
}
|
||||
|
||||
/* Dirty hack to workaround the non-legality of
|
||||
* (void*) -> fn-pointer casts. */
|
||||
memcpy(&sym, &ptr_sym, sizeof(void*));
|
||||
#endif
|
||||
|
||||
return sym;
|
||||
}
|
||||
|
||||
/**
|
||||
* dylib_close:
|
||||
* @lib : Library handle.
|
||||
*
|
||||
* Frees library handle.
|
||||
**/
|
||||
void dylib_close(dylib_t lib)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (!FreeLibrary((HMODULE)lib))
|
||||
set_dl_error();
|
||||
last_dyn_error[0] = 0;
|
||||
#else
|
||||
#ifndef NO_DLCLOSE
|
||||
dlclose(lib);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (dylib.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <dynamic/dylib.h>
|
||||
|
||||
#ifdef NEED_DYNAMIC
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <compat/posix_string.h>
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
static char last_dyn_error[512];
|
||||
|
||||
static void set_dl_error(void)
|
||||
{
|
||||
DWORD err = GetLastError();
|
||||
|
||||
if (FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
NULL,
|
||||
err,
|
||||
MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),
|
||||
last_dyn_error,
|
||||
sizeof(last_dyn_error) - 1,
|
||||
NULL) == 0)
|
||||
snprintf(last_dyn_error, sizeof(last_dyn_error) - 1,
|
||||
"unknown error %lu", err);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* dylib_load:
|
||||
* @path : Path to libretro core library.
|
||||
*
|
||||
* Platform independent dylib loading.
|
||||
*
|
||||
* Returns: library handle on success, otherwise NULL.
|
||||
**/
|
||||
dylib_t dylib_load(const char *path)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
int prevmode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
|
||||
dylib_t lib = LoadLibrary(path);
|
||||
|
||||
SetErrorMode(prevmode);
|
||||
|
||||
if (!lib)
|
||||
{
|
||||
set_dl_error();
|
||||
return NULL;
|
||||
}
|
||||
last_dyn_error[0] = 0;
|
||||
#else
|
||||
dylib_t lib = dlopen(path, RTLD_LAZY);
|
||||
#endif
|
||||
return lib;
|
||||
}
|
||||
|
||||
char *dylib_error(void)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (last_dyn_error[0])
|
||||
return last_dyn_error;
|
||||
return NULL;
|
||||
#else
|
||||
return (char*)dlerror();
|
||||
#endif
|
||||
}
|
||||
|
||||
function_t dylib_proc(dylib_t lib, const char *proc)
|
||||
{
|
||||
function_t sym;
|
||||
|
||||
#ifdef _WIN32
|
||||
sym = (function_t)GetProcAddress(lib ?
|
||||
(HMODULE)lib : GetModuleHandle(NULL), proc);
|
||||
if (!sym)
|
||||
{
|
||||
set_dl_error();
|
||||
return NULL;
|
||||
}
|
||||
last_dyn_error[0] = 0;
|
||||
#else
|
||||
void *ptr_sym = NULL;
|
||||
|
||||
if (lib)
|
||||
ptr_sym = dlsym(lib, proc);
|
||||
else
|
||||
{
|
||||
void *handle = dlopen(NULL, RTLD_LAZY);
|
||||
if (handle)
|
||||
{
|
||||
ptr_sym = dlsym(handle, proc);
|
||||
dlclose(handle);
|
||||
}
|
||||
}
|
||||
|
||||
/* Dirty hack to workaround the non-legality of
|
||||
* (void*) -> fn-pointer casts. */
|
||||
memcpy(&sym, &ptr_sym, sizeof(void*));
|
||||
#endif
|
||||
|
||||
return sym;
|
||||
}
|
||||
|
||||
/**
|
||||
* dylib_close:
|
||||
* @lib : Library handle.
|
||||
*
|
||||
* Frees library handle.
|
||||
**/
|
||||
void dylib_close(dylib_t lib)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (!FreeLibrary((HMODULE)lib))
|
||||
set_dl_error();
|
||||
last_dyn_error[0] = 0;
|
||||
#else
|
||||
#ifndef NO_DLCLOSE
|
||||
dlclose(lib);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,210 +1,210 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (encodings_utf.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <boolean.h>
|
||||
#include <compat/strl.h>
|
||||
#include <retro_inline.h>
|
||||
|
||||
static INLINE unsigned leading_ones(uint8_t c)
|
||||
{
|
||||
unsigned ones = 0;
|
||||
while (c & 0x80)
|
||||
{
|
||||
ones++;
|
||||
c <<= 1;
|
||||
}
|
||||
|
||||
return ones;
|
||||
}
|
||||
|
||||
/* Simple implementation. Assumes the sequence is
|
||||
* properly synchronized and terminated. */
|
||||
|
||||
size_t utf8_conv_utf32(uint32_t *out, size_t out_chars,
|
||||
const char *in, size_t in_size)
|
||||
{
|
||||
unsigned i;
|
||||
size_t ret = 0;
|
||||
while (in_size && out_chars)
|
||||
{
|
||||
unsigned extra, shift;
|
||||
uint32_t c;
|
||||
uint8_t first = *in++;
|
||||
unsigned ones = leading_ones(first);
|
||||
|
||||
if (ones > 6 || ones == 1) /* Invalid or desync. */
|
||||
break;
|
||||
|
||||
extra = ones ? ones - 1 : ones;
|
||||
if (1 + extra > in_size) /* Overflow. */
|
||||
break;
|
||||
|
||||
shift = (extra - 1) * 6;
|
||||
c = (first & ((1 << (7 - ones)) - 1)) << (6 * extra);
|
||||
|
||||
for (i = 0; i < extra; i++, in++, shift -= 6)
|
||||
c |= (*in & 0x3f) << shift;
|
||||
|
||||
*out++ = c;
|
||||
in_size -= 1 + extra;
|
||||
out_chars--;
|
||||
ret++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool utf16_conv_utf8(uint8_t *out, size_t *out_chars,
|
||||
const uint16_t *in, size_t in_size)
|
||||
{
|
||||
static uint8_t kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
|
||||
size_t out_pos = 0;
|
||||
size_t in_pos = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
unsigned numAdds;
|
||||
uint32_t value;
|
||||
|
||||
if (in_pos == in_size)
|
||||
{
|
||||
*out_chars = out_pos;
|
||||
return true;
|
||||
}
|
||||
value = in[in_pos++];
|
||||
if (value < 0x80)
|
||||
{
|
||||
if (out)
|
||||
out[out_pos] = (char)value;
|
||||
out_pos++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (value >= 0xD800 && value < 0xE000)
|
||||
{
|
||||
uint32_t c2;
|
||||
|
||||
if (value >= 0xDC00 || in_pos == in_size)
|
||||
break;
|
||||
c2 = in[in_pos++];
|
||||
if (c2 < 0xDC00 || c2 >= 0xE000)
|
||||
break;
|
||||
value = (((value - 0xD800) << 10) | (c2 - 0xDC00)) + 0x10000;
|
||||
}
|
||||
|
||||
for (numAdds = 1; numAdds < 5; numAdds++)
|
||||
if (value < (((uint32_t)1) << (numAdds * 5 + 6)))
|
||||
break;
|
||||
if (out)
|
||||
out[out_pos] = (char)(kUtf8Limits[numAdds - 1]
|
||||
+ (value >> (6 * numAdds)));
|
||||
out_pos++;
|
||||
do
|
||||
{
|
||||
numAdds--;
|
||||
if (out)
|
||||
out[out_pos] = (char)(0x80
|
||||
+ ((value >> (6 * numAdds)) & 0x3F));
|
||||
out_pos++;
|
||||
}while (numAdds != 0);
|
||||
}
|
||||
|
||||
*out_chars = out_pos;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Acts mostly like strlcpy.
|
||||
*
|
||||
* Copies the given number of UTF-8 characters,
|
||||
* but at most d_len bytes.
|
||||
*
|
||||
* Always NULL terminates.
|
||||
* Does not copy half a character.
|
||||
*
|
||||
* Returns number of bytes. 's' is assumed valid UTF-8.
|
||||
* Use only if 'chars' is considerably less than 'd_len'. */
|
||||
size_t utf8cpy(char *d, size_t d_len, const char *s, size_t chars)
|
||||
{
|
||||
#ifdef HAVE_UTF8
|
||||
char *d_org = d;
|
||||
char *d_end = d+d_len;
|
||||
const uint8_t *sb = (const uint8_t*)s;
|
||||
const uint8_t *sb_org = sb;
|
||||
|
||||
while (*sb && chars-- > 0)
|
||||
{
|
||||
sb++;
|
||||
while ((*sb&0xC0) == 0x80) sb++;
|
||||
}
|
||||
|
||||
if (sb - sb_org > d_len-1 /* NUL */)
|
||||
{
|
||||
sb = sb_org + d_len-1;
|
||||
while ((*sb&0xC0) == 0x80) sb--;
|
||||
}
|
||||
|
||||
memcpy(d, sb_org, sb-sb_org);
|
||||
d[sb-sb_org] = '\0';
|
||||
|
||||
return sb-sb_org;
|
||||
#else
|
||||
return strlcpy(d, s, chars + 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
const char *utf8skip(const char *str, size_t chars)
|
||||
{
|
||||
#ifdef HAVE_UTF8
|
||||
const uint8_t *strb = (const uint8_t*)str;
|
||||
if (!chars)
|
||||
return str;
|
||||
do
|
||||
{
|
||||
strb++;
|
||||
while ((*strb&0xC0)==0x80) strb++;
|
||||
chars--;
|
||||
} while(chars);
|
||||
return (const char*)strb;
|
||||
#else
|
||||
return str + chars;
|
||||
#endif
|
||||
}
|
||||
|
||||
size_t utf8len(const char *string)
|
||||
{
|
||||
#ifdef HAVE_UTF8
|
||||
size_t ret = 0;
|
||||
while (*string)
|
||||
{
|
||||
if ((*string & 0xC0) != 0x80)
|
||||
ret++;
|
||||
string++;
|
||||
}
|
||||
return ret;
|
||||
#else
|
||||
return strlen(string);
|
||||
#endif
|
||||
}
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (encodings_utf.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <boolean.h>
|
||||
#include <compat/strl.h>
|
||||
#include <retro_inline.h>
|
||||
|
||||
static INLINE unsigned leading_ones(uint8_t c)
|
||||
{
|
||||
unsigned ones = 0;
|
||||
while (c & 0x80)
|
||||
{
|
||||
ones++;
|
||||
c <<= 1;
|
||||
}
|
||||
|
||||
return ones;
|
||||
}
|
||||
|
||||
/* Simple implementation. Assumes the sequence is
|
||||
* properly synchronized and terminated. */
|
||||
|
||||
size_t utf8_conv_utf32(uint32_t *out, size_t out_chars,
|
||||
const char *in, size_t in_size)
|
||||
{
|
||||
unsigned i;
|
||||
size_t ret = 0;
|
||||
while (in_size && out_chars)
|
||||
{
|
||||
unsigned extra, shift;
|
||||
uint32_t c;
|
||||
uint8_t first = *in++;
|
||||
unsigned ones = leading_ones(first);
|
||||
|
||||
if (ones > 6 || ones == 1) /* Invalid or desync. */
|
||||
break;
|
||||
|
||||
extra = ones ? ones - 1 : ones;
|
||||
if (1 + extra > in_size) /* Overflow. */
|
||||
break;
|
||||
|
||||
shift = (extra - 1) * 6;
|
||||
c = (first & ((1 << (7 - ones)) - 1)) << (6 * extra);
|
||||
|
||||
for (i = 0; i < extra; i++, in++, shift -= 6)
|
||||
c |= (*in & 0x3f) << shift;
|
||||
|
||||
*out++ = c;
|
||||
in_size -= 1 + extra;
|
||||
out_chars--;
|
||||
ret++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool utf16_conv_utf8(uint8_t *out, size_t *out_chars,
|
||||
const uint16_t *in, size_t in_size)
|
||||
{
|
||||
static uint8_t kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
|
||||
size_t out_pos = 0;
|
||||
size_t in_pos = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
unsigned numAdds;
|
||||
uint32_t value;
|
||||
|
||||
if (in_pos == in_size)
|
||||
{
|
||||
*out_chars = out_pos;
|
||||
return true;
|
||||
}
|
||||
value = in[in_pos++];
|
||||
if (value < 0x80)
|
||||
{
|
||||
if (out)
|
||||
out[out_pos] = (char)value;
|
||||
out_pos++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (value >= 0xD800 && value < 0xE000)
|
||||
{
|
||||
uint32_t c2;
|
||||
|
||||
if (value >= 0xDC00 || in_pos == in_size)
|
||||
break;
|
||||
c2 = in[in_pos++];
|
||||
if (c2 < 0xDC00 || c2 >= 0xE000)
|
||||
break;
|
||||
value = (((value - 0xD800) << 10) | (c2 - 0xDC00)) + 0x10000;
|
||||
}
|
||||
|
||||
for (numAdds = 1; numAdds < 5; numAdds++)
|
||||
if (value < (((uint32_t)1) << (numAdds * 5 + 6)))
|
||||
break;
|
||||
if (out)
|
||||
out[out_pos] = (char)(kUtf8Limits[numAdds - 1]
|
||||
+ (value >> (6 * numAdds)));
|
||||
out_pos++;
|
||||
do
|
||||
{
|
||||
numAdds--;
|
||||
if (out)
|
||||
out[out_pos] = (char)(0x80
|
||||
+ ((value >> (6 * numAdds)) & 0x3F));
|
||||
out_pos++;
|
||||
}while (numAdds != 0);
|
||||
}
|
||||
|
||||
*out_chars = out_pos;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Acts mostly like strlcpy.
|
||||
*
|
||||
* Copies the given number of UTF-8 characters,
|
||||
* but at most d_len bytes.
|
||||
*
|
||||
* Always NULL terminates.
|
||||
* Does not copy half a character.
|
||||
*
|
||||
* Returns number of bytes. 's' is assumed valid UTF-8.
|
||||
* Use only if 'chars' is considerably less than 'd_len'. */
|
||||
size_t utf8cpy(char *d, size_t d_len, const char *s, size_t chars)
|
||||
{
|
||||
#ifdef HAVE_UTF8
|
||||
char *d_org = d;
|
||||
char *d_end = d+d_len;
|
||||
const uint8_t *sb = (const uint8_t*)s;
|
||||
const uint8_t *sb_org = sb;
|
||||
|
||||
while (*sb && chars-- > 0)
|
||||
{
|
||||
sb++;
|
||||
while ((*sb&0xC0) == 0x80) sb++;
|
||||
}
|
||||
|
||||
if (sb - sb_org > d_len-1 /* NUL */)
|
||||
{
|
||||
sb = sb_org + d_len-1;
|
||||
while ((*sb&0xC0) == 0x80) sb--;
|
||||
}
|
||||
|
||||
memcpy(d, sb_org, sb-sb_org);
|
||||
d[sb-sb_org] = '\0';
|
||||
|
||||
return sb-sb_org;
|
||||
#else
|
||||
return strlcpy(d, s, chars + 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
const char *utf8skip(const char *str, size_t chars)
|
||||
{
|
||||
#ifdef HAVE_UTF8
|
||||
const uint8_t *strb = (const uint8_t*)str;
|
||||
if (!chars)
|
||||
return str;
|
||||
do
|
||||
{
|
||||
strb++;
|
||||
while ((*strb&0xC0)==0x80) strb++;
|
||||
chars--;
|
||||
} while(chars);
|
||||
return (const char*)strb;
|
||||
#else
|
||||
return str + chars;
|
||||
#endif
|
||||
}
|
||||
|
||||
size_t utf8len(const char *string)
|
||||
{
|
||||
#ifdef HAVE_UTF8
|
||||
size_t ret = 0;
|
||||
while (*string)
|
||||
{
|
||||
if ((*string & 0xC0) != 0x80)
|
||||
ret++;
|
||||
string++;
|
||||
}
|
||||
return ret;
|
||||
#else
|
||||
return strlen(string);
|
||||
#endif
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,128 +1,128 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (config_file_userdata.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <file/config_file_userdata.h>
|
||||
#include <file/file_path.h>
|
||||
#include <string/string_list.h>
|
||||
|
||||
#define get_array_setup() \
|
||||
char key[2][256]; \
|
||||
bool got; \
|
||||
struct config_file_userdata *usr = (struct config_file_userdata*)userdata; \
|
||||
char *str = NULL; \
|
||||
fill_pathname_join_delim(key[0], usr->prefix[0], key_str, '_', sizeof(key[0])); \
|
||||
fill_pathname_join_delim(key[1], usr->prefix[1], key_str, '_', sizeof(key[1])); \
|
||||
got = config_get_string(usr->conf, key[0], &str); \
|
||||
got = got || config_get_string(usr->conf, key[1], &str);
|
||||
|
||||
#define get_array_body(T) \
|
||||
if (got) \
|
||||
{ \
|
||||
unsigned i; \
|
||||
struct string_list *list = string_split(str, " "); \
|
||||
*values = (T*)calloc(list->size, sizeof(T)); \
|
||||
for (i = 0; i < list->size; i++) \
|
||||
(*values)[i] = (T)strtod(list->elems[i].data, NULL); \
|
||||
*out_num_values = list->size; \
|
||||
string_list_free(list); \
|
||||
return true; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
*values = (T*)calloc(num_default_values, sizeof(T)); \
|
||||
memcpy(*values, default_values, sizeof(T) * num_default_values); \
|
||||
*out_num_values = num_default_values; \
|
||||
return false; \
|
||||
}
|
||||
|
||||
int config_userdata_get_float(void *userdata, const char *key_str,
|
||||
float *value, float default_value)
|
||||
{
|
||||
bool got;
|
||||
char key[2][256];
|
||||
struct config_file_userdata *usr = (struct config_file_userdata*)userdata;
|
||||
|
||||
fill_pathname_join_delim(key[0], usr->prefix[0], key_str, '_', sizeof(key[0]));
|
||||
fill_pathname_join_delim(key[1], usr->prefix[1], key_str, '_', sizeof(key[1]));
|
||||
|
||||
got = config_get_float (usr->conf, key[0], value);
|
||||
got = got || config_get_float(usr->conf, key[1], value);
|
||||
|
||||
if (!got)
|
||||
*value = default_value;
|
||||
return got;
|
||||
}
|
||||
|
||||
int config_userdata_get_int(void *userdata, const char *key_str,
|
||||
int *value, int default_value)
|
||||
{
|
||||
bool got;
|
||||
char key[2][256];
|
||||
struct config_file_userdata *usr = (struct config_file_userdata*)userdata;
|
||||
|
||||
fill_pathname_join_delim(key[0], usr->prefix[0], key_str, '_', sizeof(key[0]));
|
||||
fill_pathname_join_delim(key[1], usr->prefix[1], key_str, '_', sizeof(key[1]));
|
||||
|
||||
got = config_get_int (usr->conf, key[0], value);
|
||||
got = got || config_get_int(usr->conf, key[1], value);
|
||||
|
||||
if (!got)
|
||||
*value = default_value;
|
||||
return got;
|
||||
}
|
||||
|
||||
int config_userdata_get_float_array(void *userdata, const char *key_str,
|
||||
float **values, unsigned *out_num_values,
|
||||
const float *default_values, unsigned num_default_values)
|
||||
{
|
||||
get_array_setup()
|
||||
get_array_body(float)
|
||||
}
|
||||
|
||||
int config_userdata_get_int_array(void *userdata, const char *key_str,
|
||||
int **values, unsigned *out_num_values,
|
||||
const int *default_values, unsigned num_default_values)
|
||||
{
|
||||
get_array_setup()
|
||||
get_array_body(int)
|
||||
}
|
||||
|
||||
int config_userdata_get_string(void *userdata, const char *key_str,
|
||||
char **output, const char *default_output)
|
||||
{
|
||||
get_array_setup()
|
||||
|
||||
if (got)
|
||||
{
|
||||
*output = str;
|
||||
return true;
|
||||
}
|
||||
|
||||
*output = strdup(default_output);
|
||||
return false;
|
||||
}
|
||||
|
||||
void config_userdata_free(void *ptr)
|
||||
{
|
||||
if (ptr)
|
||||
free(ptr);
|
||||
}
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (config_file_userdata.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <file/config_file_userdata.h>
|
||||
#include <file/file_path.h>
|
||||
#include <string/string_list.h>
|
||||
|
||||
#define get_array_setup() \
|
||||
char key[2][256]; \
|
||||
bool got; \
|
||||
struct config_file_userdata *usr = (struct config_file_userdata*)userdata; \
|
||||
char *str = NULL; \
|
||||
fill_pathname_join_delim(key[0], usr->prefix[0], key_str, '_', sizeof(key[0])); \
|
||||
fill_pathname_join_delim(key[1], usr->prefix[1], key_str, '_', sizeof(key[1])); \
|
||||
got = config_get_string(usr->conf, key[0], &str); \
|
||||
got = got || config_get_string(usr->conf, key[1], &str);
|
||||
|
||||
#define get_array_body(T) \
|
||||
if (got) \
|
||||
{ \
|
||||
unsigned i; \
|
||||
struct string_list *list = string_split(str, " "); \
|
||||
*values = (T*)calloc(list->size, sizeof(T)); \
|
||||
for (i = 0; i < list->size; i++) \
|
||||
(*values)[i] = (T)strtod(list->elems[i].data, NULL); \
|
||||
*out_num_values = list->size; \
|
||||
string_list_free(list); \
|
||||
return true; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
*values = (T*)calloc(num_default_values, sizeof(T)); \
|
||||
memcpy(*values, default_values, sizeof(T) * num_default_values); \
|
||||
*out_num_values = num_default_values; \
|
||||
return false; \
|
||||
}
|
||||
|
||||
int config_userdata_get_float(void *userdata, const char *key_str,
|
||||
float *value, float default_value)
|
||||
{
|
||||
bool got;
|
||||
char key[2][256];
|
||||
struct config_file_userdata *usr = (struct config_file_userdata*)userdata;
|
||||
|
||||
fill_pathname_join_delim(key[0], usr->prefix[0], key_str, '_', sizeof(key[0]));
|
||||
fill_pathname_join_delim(key[1], usr->prefix[1], key_str, '_', sizeof(key[1]));
|
||||
|
||||
got = config_get_float (usr->conf, key[0], value);
|
||||
got = got || config_get_float(usr->conf, key[1], value);
|
||||
|
||||
if (!got)
|
||||
*value = default_value;
|
||||
return got;
|
||||
}
|
||||
|
||||
int config_userdata_get_int(void *userdata, const char *key_str,
|
||||
int *value, int default_value)
|
||||
{
|
||||
bool got;
|
||||
char key[2][256];
|
||||
struct config_file_userdata *usr = (struct config_file_userdata*)userdata;
|
||||
|
||||
fill_pathname_join_delim(key[0], usr->prefix[0], key_str, '_', sizeof(key[0]));
|
||||
fill_pathname_join_delim(key[1], usr->prefix[1], key_str, '_', sizeof(key[1]));
|
||||
|
||||
got = config_get_int (usr->conf, key[0], value);
|
||||
got = got || config_get_int(usr->conf, key[1], value);
|
||||
|
||||
if (!got)
|
||||
*value = default_value;
|
||||
return got;
|
||||
}
|
||||
|
||||
int config_userdata_get_float_array(void *userdata, const char *key_str,
|
||||
float **values, unsigned *out_num_values,
|
||||
const float *default_values, unsigned num_default_values)
|
||||
{
|
||||
get_array_setup()
|
||||
get_array_body(float)
|
||||
}
|
||||
|
||||
int config_userdata_get_int_array(void *userdata, const char *key_str,
|
||||
int **values, unsigned *out_num_values,
|
||||
const int *default_values, unsigned num_default_values)
|
||||
{
|
||||
get_array_setup()
|
||||
get_array_body(int)
|
||||
}
|
||||
|
||||
int config_userdata_get_string(void *userdata, const char *key_str,
|
||||
char **output, const char *default_output)
|
||||
{
|
||||
get_array_setup()
|
||||
|
||||
if (got)
|
||||
{
|
||||
*output = str;
|
||||
return true;
|
||||
}
|
||||
|
||||
*output = strdup(default_output);
|
||||
return false;
|
||||
}
|
||||
|
||||
void config_userdata_free(void *ptr)
|
||||
{
|
||||
if (ptr)
|
||||
free(ptr);
|
||||
}
|
||||
|
|
|
@ -1,214 +1,214 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (dir_list.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <file/dir_list.h>
|
||||
#include <file/file_path.h>
|
||||
#include <string/string_list.h>
|
||||
|
||||
#include <compat/strl.h>
|
||||
#include <retro_dirent.h>
|
||||
|
||||
#include <retro_miscellaneous.h>
|
||||
|
||||
static int qstrcmp_plain(const void *a_, const void *b_)
|
||||
{
|
||||
const struct string_list_elem *a = (const struct string_list_elem*)a_;
|
||||
const struct string_list_elem *b = (const struct string_list_elem*)b_;
|
||||
|
||||
return strcasecmp(a->data, b->data);
|
||||
}
|
||||
|
||||
static int qstrcmp_dir(const void *a_, const void *b_)
|
||||
{
|
||||
const struct string_list_elem *a = (const struct string_list_elem*)a_;
|
||||
const struct string_list_elem *b = (const struct string_list_elem*)b_;
|
||||
int a_type = a->attr.i;
|
||||
int b_type = b->attr.i;
|
||||
|
||||
|
||||
/* Sort directories before files. */
|
||||
if (a_type != b_type)
|
||||
return b_type - a_type;
|
||||
return strcasecmp(a->data, b->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* dir_list_sort:
|
||||
* @list : pointer to the directory listing.
|
||||
* @dir_first : move the directories in the listing to the top?
|
||||
*
|
||||
* Sorts a directory listing.
|
||||
*
|
||||
**/
|
||||
void dir_list_sort(struct string_list *list, bool dir_first)
|
||||
{
|
||||
if (list)
|
||||
qsort(list->elems, list->size, sizeof(struct string_list_elem),
|
||||
dir_first ? qstrcmp_dir : qstrcmp_plain);
|
||||
}
|
||||
|
||||
/**
|
||||
* dir_list_free:
|
||||
* @list : pointer to the directory listing
|
||||
*
|
||||
* Frees a directory listing.
|
||||
*
|
||||
**/
|
||||
void dir_list_free(struct string_list *list)
|
||||
{
|
||||
string_list_free(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* parse_dir_entry:
|
||||
* @name : name of the directory listing entry.
|
||||
* @file_path : file path of the directory listing entry.
|
||||
* @is_dir : is the directory listing a directory?
|
||||
* @include_dirs : include directories as part of the finished directory listing?
|
||||
* @include_compressed : Include compressed files, even if not part of ext_list.
|
||||
* @list : pointer to directory listing.
|
||||
* @ext_list : pointer to allowed file extensions listing.
|
||||
* @file_ext : file extension of the directory listing entry.
|
||||
*
|
||||
* Parses a directory listing.
|
||||
*
|
||||
* Returns: zero on success, -1 on error, 1 if we should
|
||||
* continue to the next entry in the directory listing.
|
||||
**/
|
||||
static int parse_dir_entry(const char *name, char *file_path,
|
||||
bool is_dir, bool include_dirs, bool include_compressed,
|
||||
struct string_list *list, struct string_list *ext_list,
|
||||
const char *file_ext)
|
||||
{
|
||||
union string_list_elem_attr attr;
|
||||
bool is_compressed_file = false;
|
||||
bool supported_by_core = false;
|
||||
|
||||
attr.i = RARCH_FILETYPE_UNSET;
|
||||
|
||||
if (!is_dir)
|
||||
{
|
||||
is_compressed_file = path_is_compressed_file(file_path);
|
||||
if (string_list_find_elem_prefix(ext_list, ".", file_ext))
|
||||
supported_by_core = true;
|
||||
}
|
||||
|
||||
if (!include_dirs && is_dir)
|
||||
return 1;
|
||||
|
||||
if (!strcmp(name, ".") || !strcmp(name, ".."))
|
||||
return 1;
|
||||
|
||||
if (!is_dir && ext_list &&
|
||||
((!is_compressed_file && !supported_by_core) ||
|
||||
(!supported_by_core && !include_compressed)))
|
||||
return 1;
|
||||
|
||||
if (is_dir)
|
||||
attr.i = RARCH_DIRECTORY;
|
||||
if (is_compressed_file)
|
||||
attr.i = RARCH_COMPRESSED_ARCHIVE;
|
||||
/* The order of these ifs is important.
|
||||
* If the file format is explicitly supported by the libretro-core, we
|
||||
* need to immediately load it and not designate it as a compressed file.
|
||||
*
|
||||
* Example: .zip could be supported as a image by the core and as a
|
||||
* compressed_file. In that case, we have to interpret it as a image.
|
||||
*
|
||||
* */
|
||||
if (supported_by_core)
|
||||
attr.i = RARCH_PLAIN_FILE;
|
||||
|
||||
if (!string_list_append(list, file_path, attr))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* dir_list_new:
|
||||
* @dir : directory path.
|
||||
* @ext : allowed extensions of file directory entries to include.
|
||||
* @include_dirs : include directories as part of the finished directory listing?
|
||||
* @include_compressed : Only include files which match ext. Do not try to match compressed files, etc.
|
||||
*
|
||||
* Create a directory listing.
|
||||
*
|
||||
* Returns: pointer to a directory listing of type 'struct string_list *' on success,
|
||||
* NULL in case of error. Has to be freed manually.
|
||||
**/
|
||||
struct string_list *dir_list_new(const char *dir,
|
||||
const char *ext, bool include_dirs, bool include_compressed)
|
||||
{
|
||||
struct RDIR *entry = NULL;
|
||||
struct string_list *ext_list = NULL;
|
||||
struct string_list *list = NULL;
|
||||
|
||||
if (!(list = string_list_new()))
|
||||
return NULL;
|
||||
|
||||
if (ext)
|
||||
ext_list = string_split(ext, "|");
|
||||
|
||||
entry = retro_opendir(dir);
|
||||
|
||||
if (!entry)
|
||||
goto error;
|
||||
|
||||
if (retro_dirent_error(entry))
|
||||
goto error;
|
||||
|
||||
while (retro_readdir(entry))
|
||||
{
|
||||
char file_path[PATH_MAX_LENGTH];
|
||||
bool is_dir;
|
||||
int ret = 0;
|
||||
const char *name = retro_dirent_get_name(entry);
|
||||
const char *file_ext = path_get_extension(name);
|
||||
|
||||
fill_pathname_join(file_path, dir, name, sizeof(file_path));
|
||||
is_dir = retro_dirent_is_dir(entry, file_path);
|
||||
|
||||
ret = parse_dir_entry(name, file_path, is_dir,
|
||||
include_dirs, include_compressed, list, ext_list, file_ext);
|
||||
|
||||
if (ret == -1)
|
||||
goto error;
|
||||
|
||||
if (ret == 1)
|
||||
continue;
|
||||
}
|
||||
|
||||
retro_closedir(entry);
|
||||
|
||||
string_list_free(ext_list);
|
||||
return list;
|
||||
|
||||
error:
|
||||
retro_closedir(entry);
|
||||
|
||||
string_list_free(list);
|
||||
string_list_free(ext_list);
|
||||
return NULL;
|
||||
}
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (dir_list.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <file/dir_list.h>
|
||||
#include <file/file_path.h>
|
||||
#include <string/string_list.h>
|
||||
|
||||
#include <compat/strl.h>
|
||||
#include <retro_dirent.h>
|
||||
|
||||
#include <retro_miscellaneous.h>
|
||||
|
||||
static int qstrcmp_plain(const void *a_, const void *b_)
|
||||
{
|
||||
const struct string_list_elem *a = (const struct string_list_elem*)a_;
|
||||
const struct string_list_elem *b = (const struct string_list_elem*)b_;
|
||||
|
||||
return strcasecmp(a->data, b->data);
|
||||
}
|
||||
|
||||
static int qstrcmp_dir(const void *a_, const void *b_)
|
||||
{
|
||||
const struct string_list_elem *a = (const struct string_list_elem*)a_;
|
||||
const struct string_list_elem *b = (const struct string_list_elem*)b_;
|
||||
int a_type = a->attr.i;
|
||||
int b_type = b->attr.i;
|
||||
|
||||
|
||||
/* Sort directories before files. */
|
||||
if (a_type != b_type)
|
||||
return b_type - a_type;
|
||||
return strcasecmp(a->data, b->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* dir_list_sort:
|
||||
* @list : pointer to the directory listing.
|
||||
* @dir_first : move the directories in the listing to the top?
|
||||
*
|
||||
* Sorts a directory listing.
|
||||
*
|
||||
**/
|
||||
void dir_list_sort(struct string_list *list, bool dir_first)
|
||||
{
|
||||
if (list)
|
||||
qsort(list->elems, list->size, sizeof(struct string_list_elem),
|
||||
dir_first ? qstrcmp_dir : qstrcmp_plain);
|
||||
}
|
||||
|
||||
/**
|
||||
* dir_list_free:
|
||||
* @list : pointer to the directory listing
|
||||
*
|
||||
* Frees a directory listing.
|
||||
*
|
||||
**/
|
||||
void dir_list_free(struct string_list *list)
|
||||
{
|
||||
string_list_free(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* parse_dir_entry:
|
||||
* @name : name of the directory listing entry.
|
||||
* @file_path : file path of the directory listing entry.
|
||||
* @is_dir : is the directory listing a directory?
|
||||
* @include_dirs : include directories as part of the finished directory listing?
|
||||
* @include_compressed : Include compressed files, even if not part of ext_list.
|
||||
* @list : pointer to directory listing.
|
||||
* @ext_list : pointer to allowed file extensions listing.
|
||||
* @file_ext : file extension of the directory listing entry.
|
||||
*
|
||||
* Parses a directory listing.
|
||||
*
|
||||
* Returns: zero on success, -1 on error, 1 if we should
|
||||
* continue to the next entry in the directory listing.
|
||||
**/
|
||||
static int parse_dir_entry(const char *name, char *file_path,
|
||||
bool is_dir, bool include_dirs, bool include_compressed,
|
||||
struct string_list *list, struct string_list *ext_list,
|
||||
const char *file_ext)
|
||||
{
|
||||
union string_list_elem_attr attr;
|
||||
bool is_compressed_file = false;
|
||||
bool supported_by_core = false;
|
||||
|
||||
attr.i = RARCH_FILETYPE_UNSET;
|
||||
|
||||
if (!is_dir)
|
||||
{
|
||||
is_compressed_file = path_is_compressed_file(file_path);
|
||||
if (string_list_find_elem_prefix(ext_list, ".", file_ext))
|
||||
supported_by_core = true;
|
||||
}
|
||||
|
||||
if (!include_dirs && is_dir)
|
||||
return 1;
|
||||
|
||||
if (!strcmp(name, ".") || !strcmp(name, ".."))
|
||||
return 1;
|
||||
|
||||
if (!is_dir && ext_list &&
|
||||
((!is_compressed_file && !supported_by_core) ||
|
||||
(!supported_by_core && !include_compressed)))
|
||||
return 1;
|
||||
|
||||
if (is_dir)
|
||||
attr.i = RARCH_DIRECTORY;
|
||||
if (is_compressed_file)
|
||||
attr.i = RARCH_COMPRESSED_ARCHIVE;
|
||||
/* The order of these ifs is important.
|
||||
* If the file format is explicitly supported by the libretro-core, we
|
||||
* need to immediately load it and not designate it as a compressed file.
|
||||
*
|
||||
* Example: .zip could be supported as a image by the core and as a
|
||||
* compressed_file. In that case, we have to interpret it as a image.
|
||||
*
|
||||
* */
|
||||
if (supported_by_core)
|
||||
attr.i = RARCH_PLAIN_FILE;
|
||||
|
||||
if (!string_list_append(list, file_path, attr))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* dir_list_new:
|
||||
* @dir : directory path.
|
||||
* @ext : allowed extensions of file directory entries to include.
|
||||
* @include_dirs : include directories as part of the finished directory listing?
|
||||
* @include_compressed : Only include files which match ext. Do not try to match compressed files, etc.
|
||||
*
|
||||
* Create a directory listing.
|
||||
*
|
||||
* Returns: pointer to a directory listing of type 'struct string_list *' on success,
|
||||
* NULL in case of error. Has to be freed manually.
|
||||
**/
|
||||
struct string_list *dir_list_new(const char *dir,
|
||||
const char *ext, bool include_dirs, bool include_compressed)
|
||||
{
|
||||
struct RDIR *entry = NULL;
|
||||
struct string_list *ext_list = NULL;
|
||||
struct string_list *list = NULL;
|
||||
|
||||
if (!(list = string_list_new()))
|
||||
return NULL;
|
||||
|
||||
if (ext)
|
||||
ext_list = string_split(ext, "|");
|
||||
|
||||
entry = retro_opendir(dir);
|
||||
|
||||
if (!entry)
|
||||
goto error;
|
||||
|
||||
if (retro_dirent_error(entry))
|
||||
goto error;
|
||||
|
||||
while (retro_readdir(entry))
|
||||
{
|
||||
char file_path[PATH_MAX_LENGTH];
|
||||
bool is_dir;
|
||||
int ret = 0;
|
||||
const char *name = retro_dirent_get_name(entry);
|
||||
const char *file_ext = path_get_extension(name);
|
||||
|
||||
fill_pathname_join(file_path, dir, name, sizeof(file_path));
|
||||
is_dir = retro_dirent_is_dir(entry, file_path);
|
||||
|
||||
ret = parse_dir_entry(name, file_path, is_dir,
|
||||
include_dirs, include_compressed, list, ext_list, file_ext);
|
||||
|
||||
if (ret == -1)
|
||||
goto error;
|
||||
|
||||
if (ret == 1)
|
||||
continue;
|
||||
}
|
||||
|
||||
retro_closedir(entry);
|
||||
|
||||
string_list_free(ext_list);
|
||||
return list;
|
||||
|
||||
error:
|
||||
retro_closedir(entry);
|
||||
|
||||
string_list_free(list);
|
||||
string_list_free(ext_list);
|
||||
return NULL;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,213 +1,213 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (file_archive_zlib.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <compat/zlib.h>
|
||||
#include <file/file_archive.h>
|
||||
#include <retro_file.h>
|
||||
|
||||
static void *zlib_stream_new(void)
|
||||
{
|
||||
return (z_stream*)calloc(1, sizeof(z_stream));
|
||||
}
|
||||
|
||||
static void zlib_stream_free(void *data)
|
||||
{
|
||||
z_stream *ret = (z_stream*)data;
|
||||
if (ret)
|
||||
inflateEnd(ret);
|
||||
}
|
||||
|
||||
static void zlib_stream_set(void *data,
|
||||
uint32_t avail_in,
|
||||
uint32_t avail_out,
|
||||
const uint8_t *next_in,
|
||||
uint8_t *next_out
|
||||
)
|
||||
{
|
||||
z_stream *stream = (z_stream*)data;
|
||||
|
||||
if (!stream)
|
||||
return;
|
||||
|
||||
stream->avail_in = avail_in;
|
||||
stream->avail_out = avail_out;
|
||||
|
||||
stream->next_in = (uint8_t*)next_in;
|
||||
stream->next_out = next_out;
|
||||
}
|
||||
|
||||
static uint32_t zlib_stream_get_avail_in(void *data)
|
||||
{
|
||||
z_stream *stream = (z_stream*)data;
|
||||
|
||||
if (!stream)
|
||||
return 0;
|
||||
|
||||
return stream->avail_in;
|
||||
}
|
||||
|
||||
static uint32_t zlib_stream_get_avail_out(void *data)
|
||||
{
|
||||
z_stream *stream = (z_stream*)data;
|
||||
|
||||
if (!stream)
|
||||
return 0;
|
||||
|
||||
return stream->avail_out;
|
||||
}
|
||||
|
||||
static uint64_t zlib_stream_get_total_out(void *data)
|
||||
{
|
||||
z_stream *stream = (z_stream*)data;
|
||||
|
||||
if (!stream)
|
||||
return 0;
|
||||
|
||||
return stream->total_out;
|
||||
}
|
||||
|
||||
static void zlib_stream_decrement_total_out(void *data, unsigned subtraction)
|
||||
{
|
||||
z_stream *stream = (z_stream*)data;
|
||||
|
||||
if (stream)
|
||||
stream->total_out -= subtraction;
|
||||
}
|
||||
|
||||
static void zlib_stream_compress_free(void *data)
|
||||
{
|
||||
z_stream *ret = (z_stream*)data;
|
||||
if (ret)
|
||||
deflateEnd(ret);
|
||||
}
|
||||
|
||||
static int zlib_stream_compress_data_to_file(void *data)
|
||||
{
|
||||
int zstatus;
|
||||
z_stream *stream = (z_stream*)data;
|
||||
|
||||
if (!stream)
|
||||
return -1;
|
||||
|
||||
zstatus = deflate(stream, Z_FINISH);
|
||||
|
||||
if (zstatus == Z_STREAM_END)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool zlib_stream_decompress_init(void *data)
|
||||
{
|
||||
z_stream *stream = (z_stream*)data;
|
||||
|
||||
if (!stream)
|
||||
return false;
|
||||
if (inflateInit(stream) != Z_OK)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool zlib_stream_decompress_data_to_file_init(
|
||||
file_archive_file_handle_t *handle,
|
||||
const uint8_t *cdata, uint32_t csize, uint32_t size)
|
||||
{
|
||||
if (!handle)
|
||||
return false;
|
||||
|
||||
if (!(handle->stream = (z_stream*)zlib_stream_new()))
|
||||
goto error;
|
||||
|
||||
if (inflateInit2((z_streamp)handle->stream, -MAX_WBITS) != Z_OK)
|
||||
goto error;
|
||||
|
||||
handle->data = (uint8_t*)malloc(size);
|
||||
|
||||
if (!handle->data)
|
||||
goto error;
|
||||
|
||||
zlib_stream_set(handle->stream, csize, size,
|
||||
(const uint8_t*)cdata, handle->data);
|
||||
|
||||
return true;
|
||||
|
||||
error:
|
||||
zlib_stream_free(handle->stream);
|
||||
free(handle->stream);
|
||||
if (handle->data)
|
||||
free(handle->data);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int zlib_stream_decompress_data_to_file_iterate(void *data)
|
||||
{
|
||||
int zstatus;
|
||||
z_stream *stream = (z_stream*)data;
|
||||
|
||||
if (!stream)
|
||||
return -1;
|
||||
|
||||
zstatus = inflate(stream, Z_NO_FLUSH);
|
||||
|
||||
if (zstatus == Z_STREAM_END)
|
||||
return 1;
|
||||
|
||||
if (zstatus != Z_OK && zstatus != Z_BUF_ERROR)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void zlib_stream_compress_init(void *data, int level)
|
||||
{
|
||||
z_stream *stream = (z_stream*)data;
|
||||
|
||||
if (stream)
|
||||
deflateInit(stream, level);
|
||||
}
|
||||
|
||||
static uint32_t zlib_stream_crc32_calculate(uint32_t crc,
|
||||
const uint8_t *data, size_t length)
|
||||
{
|
||||
return crc32(crc, data, length);
|
||||
}
|
||||
|
||||
const struct file_archive_file_backend zlib_backend = {
|
||||
zlib_stream_new,
|
||||
zlib_stream_free,
|
||||
zlib_stream_set,
|
||||
zlib_stream_get_avail_in,
|
||||
zlib_stream_get_avail_out,
|
||||
zlib_stream_get_total_out,
|
||||
zlib_stream_decrement_total_out,
|
||||
zlib_stream_decompress_init,
|
||||
zlib_stream_decompress_data_to_file_init,
|
||||
zlib_stream_decompress_data_to_file_iterate,
|
||||
zlib_stream_compress_init,
|
||||
zlib_stream_compress_free,
|
||||
zlib_stream_compress_data_to_file,
|
||||
zlib_stream_crc32_calculate,
|
||||
"zlib"
|
||||
};
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (file_archive_zlib.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <compat/zlib.h>
|
||||
#include <file/file_archive.h>
|
||||
#include <retro_file.h>
|
||||
|
||||
static void *zlib_stream_new(void)
|
||||
{
|
||||
return (z_stream*)calloc(1, sizeof(z_stream));
|
||||
}
|
||||
|
||||
static void zlib_stream_free(void *data)
|
||||
{
|
||||
z_stream *ret = (z_stream*)data;
|
||||
if (ret)
|
||||
inflateEnd(ret);
|
||||
}
|
||||
|
||||
static void zlib_stream_set(void *data,
|
||||
uint32_t avail_in,
|
||||
uint32_t avail_out,
|
||||
const uint8_t *next_in,
|
||||
uint8_t *next_out
|
||||
)
|
||||
{
|
||||
z_stream *stream = (z_stream*)data;
|
||||
|
||||
if (!stream)
|
||||
return;
|
||||
|
||||
stream->avail_in = avail_in;
|
||||
stream->avail_out = avail_out;
|
||||
|
||||
stream->next_in = (uint8_t*)next_in;
|
||||
stream->next_out = next_out;
|
||||
}
|
||||
|
||||
static uint32_t zlib_stream_get_avail_in(void *data)
|
||||
{
|
||||
z_stream *stream = (z_stream*)data;
|
||||
|
||||
if (!stream)
|
||||
return 0;
|
||||
|
||||
return stream->avail_in;
|
||||
}
|
||||
|
||||
static uint32_t zlib_stream_get_avail_out(void *data)
|
||||
{
|
||||
z_stream *stream = (z_stream*)data;
|
||||
|
||||
if (!stream)
|
||||
return 0;
|
||||
|
||||
return stream->avail_out;
|
||||
}
|
||||
|
||||
static uint64_t zlib_stream_get_total_out(void *data)
|
||||
{
|
||||
z_stream *stream = (z_stream*)data;
|
||||
|
||||
if (!stream)
|
||||
return 0;
|
||||
|
||||
return stream->total_out;
|
||||
}
|
||||
|
||||
static void zlib_stream_decrement_total_out(void *data, unsigned subtraction)
|
||||
{
|
||||
z_stream *stream = (z_stream*)data;
|
||||
|
||||
if (stream)
|
||||
stream->total_out -= subtraction;
|
||||
}
|
||||
|
||||
static void zlib_stream_compress_free(void *data)
|
||||
{
|
||||
z_stream *ret = (z_stream*)data;
|
||||
if (ret)
|
||||
deflateEnd(ret);
|
||||
}
|
||||
|
||||
static int zlib_stream_compress_data_to_file(void *data)
|
||||
{
|
||||
int zstatus;
|
||||
z_stream *stream = (z_stream*)data;
|
||||
|
||||
if (!stream)
|
||||
return -1;
|
||||
|
||||
zstatus = deflate(stream, Z_FINISH);
|
||||
|
||||
if (zstatus == Z_STREAM_END)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool zlib_stream_decompress_init(void *data)
|
||||
{
|
||||
z_stream *stream = (z_stream*)data;
|
||||
|
||||
if (!stream)
|
||||
return false;
|
||||
if (inflateInit(stream) != Z_OK)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool zlib_stream_decompress_data_to_file_init(
|
||||
file_archive_file_handle_t *handle,
|
||||
const uint8_t *cdata, uint32_t csize, uint32_t size)
|
||||
{
|
||||
if (!handle)
|
||||
return false;
|
||||
|
||||
if (!(handle->stream = (z_stream*)zlib_stream_new()))
|
||||
goto error;
|
||||
|
||||
if (inflateInit2((z_streamp)handle->stream, -MAX_WBITS) != Z_OK)
|
||||
goto error;
|
||||
|
||||
handle->data = (uint8_t*)malloc(size);
|
||||
|
||||
if (!handle->data)
|
||||
goto error;
|
||||
|
||||
zlib_stream_set(handle->stream, csize, size,
|
||||
(const uint8_t*)cdata, handle->data);
|
||||
|
||||
return true;
|
||||
|
||||
error:
|
||||
zlib_stream_free(handle->stream);
|
||||
free(handle->stream);
|
||||
if (handle->data)
|
||||
free(handle->data);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int zlib_stream_decompress_data_to_file_iterate(void *data)
|
||||
{
|
||||
int zstatus;
|
||||
z_stream *stream = (z_stream*)data;
|
||||
|
||||
if (!stream)
|
||||
return -1;
|
||||
|
||||
zstatus = inflate(stream, Z_NO_FLUSH);
|
||||
|
||||
if (zstatus == Z_STREAM_END)
|
||||
return 1;
|
||||
|
||||
if (zstatus != Z_OK && zstatus != Z_BUF_ERROR)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void zlib_stream_compress_init(void *data, int level)
|
||||
{
|
||||
z_stream *stream = (z_stream*)data;
|
||||
|
||||
if (stream)
|
||||
deflateInit(stream, level);
|
||||
}
|
||||
|
||||
static uint32_t zlib_stream_crc32_calculate(uint32_t crc,
|
||||
const uint8_t *data, size_t length)
|
||||
{
|
||||
return crc32(crc, data, length);
|
||||
}
|
||||
|
||||
const struct file_archive_file_backend zlib_backend = {
|
||||
zlib_stream_new,
|
||||
zlib_stream_free,
|
||||
zlib_stream_set,
|
||||
zlib_stream_get_avail_in,
|
||||
zlib_stream_get_avail_out,
|
||||
zlib_stream_get_total_out,
|
||||
zlib_stream_decrement_total_out,
|
||||
zlib_stream_decompress_init,
|
||||
zlib_stream_decompress_data_to_file_init,
|
||||
zlib_stream_decompress_data_to_file_iterate,
|
||||
zlib_stream_compress_init,
|
||||
zlib_stream_compress_free,
|
||||
zlib_stream_compress_data_to_file,
|
||||
zlib_stream_crc32_calculate,
|
||||
"zlib"
|
||||
};
|
||||
|
|
|
@ -1,411 +1,411 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (file_list.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <retro_common.h>
|
||||
#include <file/file_list.h>
|
||||
#include <compat/strcasestr.h>
|
||||
|
||||
void file_list_push(file_list_t *list,
|
||||
const char *path, const char *label,
|
||||
unsigned type, size_t directory_ptr,
|
||||
size_t entry_idx)
|
||||
{
|
||||
if (list->size >= list->capacity)
|
||||
{
|
||||
list->capacity += 1;
|
||||
list->capacity *= 2;
|
||||
|
||||
list->list = (struct item_file*)realloc(list->list,
|
||||
list->capacity * sizeof(struct item_file));
|
||||
|
||||
if (!list->list)
|
||||
return;
|
||||
}
|
||||
|
||||
list->list[list->size].label = NULL;
|
||||
list->list[list->size].path = NULL;
|
||||
list->list[list->size].alt = NULL;
|
||||
list->list[list->size].userdata = NULL;
|
||||
list->list[list->size].actiondata = NULL;
|
||||
list->list[list->size].type = type;
|
||||
list->list[list->size].directory_ptr = directory_ptr;
|
||||
list->list[list->size].entry_idx = entry_idx;
|
||||
|
||||
if (label)
|
||||
list->list[list->size].label = strdup(label);
|
||||
if (path)
|
||||
list->list[list->size].path = strdup(path);
|
||||
|
||||
list->size++;
|
||||
}
|
||||
|
||||
size_t file_list_get_size(const file_list_t *list)
|
||||
{
|
||||
if (!list)
|
||||
return 0;
|
||||
return list->size;
|
||||
}
|
||||
|
||||
size_t file_list_get_entry_index(const file_list_t *list)
|
||||
{
|
||||
size_t size = 0;
|
||||
if (!list)
|
||||
return 0;
|
||||
size = file_list_get_size(list);
|
||||
return list->list[size].entry_idx;
|
||||
}
|
||||
|
||||
size_t file_list_get_directory_ptr(const file_list_t *list)
|
||||
{
|
||||
size_t size = file_list_get_size(list);
|
||||
return list->list[size].directory_ptr;
|
||||
}
|
||||
|
||||
|
||||
void file_list_pop(file_list_t *list, size_t *directory_ptr)
|
||||
{
|
||||
if (!list)
|
||||
return;
|
||||
|
||||
if (list->size != 0)
|
||||
{
|
||||
--list->size;
|
||||
if (list->list[list->size].path)
|
||||
free(list->list[list->size].path);
|
||||
list->list[list->size].path = NULL;
|
||||
|
||||
if (list->list[list->size].label)
|
||||
free(list->list[list->size].label);
|
||||
list->list[list->size].label = NULL;
|
||||
}
|
||||
|
||||
if (directory_ptr)
|
||||
*directory_ptr = list->list[list->size].directory_ptr;
|
||||
}
|
||||
|
||||
void file_list_free(file_list_t *list)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (!list)
|
||||
return;
|
||||
|
||||
for (i = 0; i < list->size; i++)
|
||||
{
|
||||
file_list_free_userdata(list, i);
|
||||
file_list_free_actiondata(list, i);
|
||||
|
||||
if (list->list[i].path)
|
||||
free(list->list[i].path);
|
||||
list->list[i].path = NULL;
|
||||
|
||||
if (list->list[i].label)
|
||||
free(list->list[i].label);
|
||||
list->list[i].label = NULL;
|
||||
|
||||
if (list->list[i].alt)
|
||||
free(list->list[i].alt);
|
||||
list->list[i].alt = NULL;
|
||||
}
|
||||
if (list->list)
|
||||
free(list->list);
|
||||
list->list = NULL;
|
||||
free(list);
|
||||
}
|
||||
|
||||
void file_list_clear(file_list_t *list)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (!list)
|
||||
return;
|
||||
|
||||
for (i = 0; i < list->size; i++)
|
||||
{
|
||||
if (list->list[i].path)
|
||||
free(list->list[i].path);
|
||||
list->list[i].path = NULL;
|
||||
|
||||
if (list->list[i].label)
|
||||
free(list->list[i].label);
|
||||
list->list[i].label = NULL;
|
||||
|
||||
if (list->list[i].alt)
|
||||
free(list->list[i].alt);
|
||||
list->list[i].alt = NULL;
|
||||
}
|
||||
|
||||
list->size = 0;
|
||||
}
|
||||
|
||||
void file_list_copy(const file_list_t *src, file_list_t *dst)
|
||||
{
|
||||
struct item_file *item;
|
||||
|
||||
if (!src || !dst)
|
||||
return;
|
||||
|
||||
if (dst->list)
|
||||
{
|
||||
for (item = dst->list; item < &dst->list[dst->size]; ++item)
|
||||
{
|
||||
if (item->path)
|
||||
free(item->path);
|
||||
|
||||
if (item->label)
|
||||
free(item->label);
|
||||
|
||||
if (item->alt)
|
||||
free(item->alt);
|
||||
}
|
||||
|
||||
free(dst->list);
|
||||
}
|
||||
|
||||
dst->size = 0;
|
||||
dst->capacity = 0;
|
||||
dst->list = (struct item_file*)malloc(src->size * sizeof(struct item_file));
|
||||
|
||||
if (!dst->list)
|
||||
return;
|
||||
|
||||
dst->size = dst->capacity = src->size;
|
||||
|
||||
memcpy(dst->list, src->list, dst->size * sizeof(struct item_file));
|
||||
|
||||
for (item = dst->list; item < &dst->list[dst->size]; ++item)
|
||||
{
|
||||
if (item->path)
|
||||
item->path = strdup(item->path);
|
||||
|
||||
if (item->label)
|
||||
item->label = strdup(item->label);
|
||||
|
||||
if (item->alt)
|
||||
item->alt = strdup(item->alt);
|
||||
}
|
||||
}
|
||||
|
||||
void file_list_set_label_at_offset(file_list_t *list, size_t idx,
|
||||
const char *label)
|
||||
{
|
||||
if (!list)
|
||||
return;
|
||||
|
||||
if (list->list[idx].label)
|
||||
free(list->list[idx].label);
|
||||
list->list[idx].alt = NULL;
|
||||
|
||||
if (label)
|
||||
list->list[idx].label = strdup(label);
|
||||
}
|
||||
|
||||
void file_list_get_label_at_offset(const file_list_t *list, size_t idx,
|
||||
const char **label)
|
||||
{
|
||||
if (!label || !list)
|
||||
return;
|
||||
|
||||
*label = list->list[idx].path;
|
||||
if (list->list[idx].label)
|
||||
*label = list->list[idx].label;
|
||||
}
|
||||
|
||||
void file_list_set_alt_at_offset(file_list_t *list, size_t idx,
|
||||
const char *alt)
|
||||
{
|
||||
if (!list || !alt)
|
||||
return;
|
||||
|
||||
if (list->list[idx].alt)
|
||||
free(list->list[idx].alt);
|
||||
list->list[idx].alt = NULL;
|
||||
|
||||
if (alt)
|
||||
list->list[idx].alt = strdup(alt);
|
||||
}
|
||||
|
||||
void file_list_get_alt_at_offset(const file_list_t *list, size_t idx,
|
||||
const char **alt)
|
||||
{
|
||||
if (!list)
|
||||
return;
|
||||
|
||||
if (alt)
|
||||
*alt = list->list[idx].alt ?
|
||||
list->list[idx].alt : list->list[idx].path;
|
||||
}
|
||||
|
||||
static int file_list_alt_cmp(const void *a_, const void *b_)
|
||||
{
|
||||
const struct item_file *a = (const struct item_file*)a_;
|
||||
const struct item_file *b = (const struct item_file*)b_;
|
||||
const char *cmp_a = a->alt ? a->alt : a->path;
|
||||
const char *cmp_b = b->alt ? b->alt : b->path;
|
||||
return strcasecmp(cmp_a, cmp_b);
|
||||
}
|
||||
|
||||
static int file_list_type_cmp(const void *a_, const void *b_)
|
||||
{
|
||||
const struct item_file *a = (const struct item_file*)a_;
|
||||
const struct item_file *b = (const struct item_file*)b_;
|
||||
if (a->type < b->type)
|
||||
return -1;
|
||||
if (a->type == b->type)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void file_list_sort_on_alt(file_list_t *list)
|
||||
{
|
||||
qsort(list->list, list->size, sizeof(list->list[0]), file_list_alt_cmp);
|
||||
}
|
||||
|
||||
void file_list_sort_on_type(file_list_t *list)
|
||||
{
|
||||
qsort(list->list, list->size, sizeof(list->list[0]), file_list_type_cmp);
|
||||
}
|
||||
|
||||
void *file_list_get_userdata_at_offset(const file_list_t *list, size_t idx)
|
||||
{
|
||||
if (!list)
|
||||
return NULL;
|
||||
return list->list[idx].userdata;
|
||||
}
|
||||
|
||||
void file_list_set_userdata(const file_list_t *list, size_t idx, void *ptr)
|
||||
{
|
||||
if (!list || !ptr)
|
||||
return;
|
||||
list->list[idx].userdata = ptr;
|
||||
}
|
||||
|
||||
void file_list_set_actiondata(const file_list_t *list, size_t idx, void *ptr)
|
||||
{
|
||||
if (!list || !ptr)
|
||||
return;
|
||||
list->list[idx].actiondata = ptr;
|
||||
}
|
||||
|
||||
void *file_list_get_actiondata_at_offset(const file_list_t *list, size_t idx)
|
||||
{
|
||||
if (!list)
|
||||
return NULL;
|
||||
return list->list[idx].actiondata;
|
||||
}
|
||||
|
||||
void file_list_free_actiondata(const file_list_t *list, size_t idx)
|
||||
{
|
||||
if (!list)
|
||||
return;
|
||||
if (list->list[idx].actiondata)
|
||||
free(list->list[idx].actiondata);
|
||||
list->list[idx].actiondata = NULL;
|
||||
}
|
||||
|
||||
void file_list_free_userdata(const file_list_t *list, size_t idx)
|
||||
{
|
||||
if (!list)
|
||||
return;
|
||||
if (list->list[idx].userdata)
|
||||
free(list->list[idx].userdata);
|
||||
list->list[idx].userdata = NULL;
|
||||
}
|
||||
|
||||
void *file_list_get_last_actiondata(const file_list_t *list)
|
||||
{
|
||||
if (!list)
|
||||
return NULL;
|
||||
return list->list[list->size - 1].actiondata;
|
||||
}
|
||||
|
||||
void file_list_get_at_offset(const file_list_t *list, size_t idx,
|
||||
const char **path, const char **label, unsigned *file_type,
|
||||
size_t *entry_idx)
|
||||
{
|
||||
if (!list)
|
||||
return;
|
||||
|
||||
if (path)
|
||||
*path = list->list[idx].path;
|
||||
if (label)
|
||||
*label = list->list[idx].label;
|
||||
if (file_type)
|
||||
*file_type = list->list[idx].type;
|
||||
if (entry_idx)
|
||||
*entry_idx = list->list[idx].entry_idx;
|
||||
}
|
||||
|
||||
void file_list_get_last(const file_list_t *list,
|
||||
const char **path, const char **label,
|
||||
unsigned *file_type, size_t *entry_idx)
|
||||
{
|
||||
if (!list)
|
||||
return;
|
||||
|
||||
if (list->size)
|
||||
file_list_get_at_offset(list, list->size - 1, path, label, file_type, entry_idx);
|
||||
}
|
||||
|
||||
bool file_list_search(const file_list_t *list, const char *needle, size_t *idx)
|
||||
{
|
||||
size_t i;
|
||||
const char *alt;
|
||||
bool ret = false;
|
||||
|
||||
if (!list)
|
||||
return false;
|
||||
|
||||
for (i = 0; i < list->size; i++)
|
||||
{
|
||||
const char *str;
|
||||
file_list_get_alt_at_offset(list, i, &alt);
|
||||
if (!alt)
|
||||
{
|
||||
file_list_get_label_at_offset(list, i, &alt);
|
||||
if (!alt)
|
||||
continue;
|
||||
}
|
||||
|
||||
str = (const char *)strcasestr(alt, needle);
|
||||
if (str == alt)
|
||||
{
|
||||
/* Found match with first chars, best possible match. */
|
||||
*idx = i;
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
else if (str && !ret)
|
||||
{
|
||||
/* Found mid-string match, but try to find a match with
|
||||
* first characters before we settle. */
|
||||
*idx = i;
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (file_list.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <retro_common.h>
|
||||
#include <file/file_list.h>
|
||||
#include <compat/strcasestr.h>
|
||||
|
||||
void file_list_push(file_list_t *list,
|
||||
const char *path, const char *label,
|
||||
unsigned type, size_t directory_ptr,
|
||||
size_t entry_idx)
|
||||
{
|
||||
if (list->size >= list->capacity)
|
||||
{
|
||||
list->capacity += 1;
|
||||
list->capacity *= 2;
|
||||
|
||||
list->list = (struct item_file*)realloc(list->list,
|
||||
list->capacity * sizeof(struct item_file));
|
||||
|
||||
if (!list->list)
|
||||
return;
|
||||
}
|
||||
|
||||
list->list[list->size].label = NULL;
|
||||
list->list[list->size].path = NULL;
|
||||
list->list[list->size].alt = NULL;
|
||||
list->list[list->size].userdata = NULL;
|
||||
list->list[list->size].actiondata = NULL;
|
||||
list->list[list->size].type = type;
|
||||
list->list[list->size].directory_ptr = directory_ptr;
|
||||
list->list[list->size].entry_idx = entry_idx;
|
||||
|
||||
if (label)
|
||||
list->list[list->size].label = strdup(label);
|
||||
if (path)
|
||||
list->list[list->size].path = strdup(path);
|
||||
|
||||
list->size++;
|
||||
}
|
||||
|
||||
size_t file_list_get_size(const file_list_t *list)
|
||||
{
|
||||
if (!list)
|
||||
return 0;
|
||||
return list->size;
|
||||
}
|
||||
|
||||
size_t file_list_get_entry_index(const file_list_t *list)
|
||||
{
|
||||
size_t size = 0;
|
||||
if (!list)
|
||||
return 0;
|
||||
size = file_list_get_size(list);
|
||||
return list->list[size].entry_idx;
|
||||
}
|
||||
|
||||
size_t file_list_get_directory_ptr(const file_list_t *list)
|
||||
{
|
||||
size_t size = file_list_get_size(list);
|
||||
return list->list[size].directory_ptr;
|
||||
}
|
||||
|
||||
|
||||
void file_list_pop(file_list_t *list, size_t *directory_ptr)
|
||||
{
|
||||
if (!list)
|
||||
return;
|
||||
|
||||
if (list->size != 0)
|
||||
{
|
||||
--list->size;
|
||||
if (list->list[list->size].path)
|
||||
free(list->list[list->size].path);
|
||||
list->list[list->size].path = NULL;
|
||||
|
||||
if (list->list[list->size].label)
|
||||
free(list->list[list->size].label);
|
||||
list->list[list->size].label = NULL;
|
||||
}
|
||||
|
||||
if (directory_ptr)
|
||||
*directory_ptr = list->list[list->size].directory_ptr;
|
||||
}
|
||||
|
||||
void file_list_free(file_list_t *list)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (!list)
|
||||
return;
|
||||
|
||||
for (i = 0; i < list->size; i++)
|
||||
{
|
||||
file_list_free_userdata(list, i);
|
||||
file_list_free_actiondata(list, i);
|
||||
|
||||
if (list->list[i].path)
|
||||
free(list->list[i].path);
|
||||
list->list[i].path = NULL;
|
||||
|
||||
if (list->list[i].label)
|
||||
free(list->list[i].label);
|
||||
list->list[i].label = NULL;
|
||||
|
||||
if (list->list[i].alt)
|
||||
free(list->list[i].alt);
|
||||
list->list[i].alt = NULL;
|
||||
}
|
||||
if (list->list)
|
||||
free(list->list);
|
||||
list->list = NULL;
|
||||
free(list);
|
||||
}
|
||||
|
||||
void file_list_clear(file_list_t *list)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (!list)
|
||||
return;
|
||||
|
||||
for (i = 0; i < list->size; i++)
|
||||
{
|
||||
if (list->list[i].path)
|
||||
free(list->list[i].path);
|
||||
list->list[i].path = NULL;
|
||||
|
||||
if (list->list[i].label)
|
||||
free(list->list[i].label);
|
||||
list->list[i].label = NULL;
|
||||
|
||||
if (list->list[i].alt)
|
||||
free(list->list[i].alt);
|
||||
list->list[i].alt = NULL;
|
||||
}
|
||||
|
||||
list->size = 0;
|
||||
}
|
||||
|
||||
void file_list_copy(const file_list_t *src, file_list_t *dst)
|
||||
{
|
||||
struct item_file *item;
|
||||
|
||||
if (!src || !dst)
|
||||
return;
|
||||
|
||||
if (dst->list)
|
||||
{
|
||||
for (item = dst->list; item < &dst->list[dst->size]; ++item)
|
||||
{
|
||||
if (item->path)
|
||||
free(item->path);
|
||||
|
||||
if (item->label)
|
||||
free(item->label);
|
||||
|
||||
if (item->alt)
|
||||
free(item->alt);
|
||||
}
|
||||
|
||||
free(dst->list);
|
||||
}
|
||||
|
||||
dst->size = 0;
|
||||
dst->capacity = 0;
|
||||
dst->list = (struct item_file*)malloc(src->size * sizeof(struct item_file));
|
||||
|
||||
if (!dst->list)
|
||||
return;
|
||||
|
||||
dst->size = dst->capacity = src->size;
|
||||
|
||||
memcpy(dst->list, src->list, dst->size * sizeof(struct item_file));
|
||||
|
||||
for (item = dst->list; item < &dst->list[dst->size]; ++item)
|
||||
{
|
||||
if (item->path)
|
||||
item->path = strdup(item->path);
|
||||
|
||||
if (item->label)
|
||||
item->label = strdup(item->label);
|
||||
|
||||
if (item->alt)
|
||||
item->alt = strdup(item->alt);
|
||||
}
|
||||
}
|
||||
|
||||
void file_list_set_label_at_offset(file_list_t *list, size_t idx,
|
||||
const char *label)
|
||||
{
|
||||
if (!list)
|
||||
return;
|
||||
|
||||
if (list->list[idx].label)
|
||||
free(list->list[idx].label);
|
||||
list->list[idx].alt = NULL;
|
||||
|
||||
if (label)
|
||||
list->list[idx].label = strdup(label);
|
||||
}
|
||||
|
||||
void file_list_get_label_at_offset(const file_list_t *list, size_t idx,
|
||||
const char **label)
|
||||
{
|
||||
if (!label || !list)
|
||||
return;
|
||||
|
||||
*label = list->list[idx].path;
|
||||
if (list->list[idx].label)
|
||||
*label = list->list[idx].label;
|
||||
}
|
||||
|
||||
void file_list_set_alt_at_offset(file_list_t *list, size_t idx,
|
||||
const char *alt)
|
||||
{
|
||||
if (!list || !alt)
|
||||
return;
|
||||
|
||||
if (list->list[idx].alt)
|
||||
free(list->list[idx].alt);
|
||||
list->list[idx].alt = NULL;
|
||||
|
||||
if (alt)
|
||||
list->list[idx].alt = strdup(alt);
|
||||
}
|
||||
|
||||
void file_list_get_alt_at_offset(const file_list_t *list, size_t idx,
|
||||
const char **alt)
|
||||
{
|
||||
if (!list)
|
||||
return;
|
||||
|
||||
if (alt)
|
||||
*alt = list->list[idx].alt ?
|
||||
list->list[idx].alt : list->list[idx].path;
|
||||
}
|
||||
|
||||
static int file_list_alt_cmp(const void *a_, const void *b_)
|
||||
{
|
||||
const struct item_file *a = (const struct item_file*)a_;
|
||||
const struct item_file *b = (const struct item_file*)b_;
|
||||
const char *cmp_a = a->alt ? a->alt : a->path;
|
||||
const char *cmp_b = b->alt ? b->alt : b->path;
|
||||
return strcasecmp(cmp_a, cmp_b);
|
||||
}
|
||||
|
||||
static int file_list_type_cmp(const void *a_, const void *b_)
|
||||
{
|
||||
const struct item_file *a = (const struct item_file*)a_;
|
||||
const struct item_file *b = (const struct item_file*)b_;
|
||||
if (a->type < b->type)
|
||||
return -1;
|
||||
if (a->type == b->type)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void file_list_sort_on_alt(file_list_t *list)
|
||||
{
|
||||
qsort(list->list, list->size, sizeof(list->list[0]), file_list_alt_cmp);
|
||||
}
|
||||
|
||||
void file_list_sort_on_type(file_list_t *list)
|
||||
{
|
||||
qsort(list->list, list->size, sizeof(list->list[0]), file_list_type_cmp);
|
||||
}
|
||||
|
||||
void *file_list_get_userdata_at_offset(const file_list_t *list, size_t idx)
|
||||
{
|
||||
if (!list)
|
||||
return NULL;
|
||||
return list->list[idx].userdata;
|
||||
}
|
||||
|
||||
void file_list_set_userdata(const file_list_t *list, size_t idx, void *ptr)
|
||||
{
|
||||
if (!list || !ptr)
|
||||
return;
|
||||
list->list[idx].userdata = ptr;
|
||||
}
|
||||
|
||||
void file_list_set_actiondata(const file_list_t *list, size_t idx, void *ptr)
|
||||
{
|
||||
if (!list || !ptr)
|
||||
return;
|
||||
list->list[idx].actiondata = ptr;
|
||||
}
|
||||
|
||||
void *file_list_get_actiondata_at_offset(const file_list_t *list, size_t idx)
|
||||
{
|
||||
if (!list)
|
||||
return NULL;
|
||||
return list->list[idx].actiondata;
|
||||
}
|
||||
|
||||
void file_list_free_actiondata(const file_list_t *list, size_t idx)
|
||||
{
|
||||
if (!list)
|
||||
return;
|
||||
if (list->list[idx].actiondata)
|
||||
free(list->list[idx].actiondata);
|
||||
list->list[idx].actiondata = NULL;
|
||||
}
|
||||
|
||||
void file_list_free_userdata(const file_list_t *list, size_t idx)
|
||||
{
|
||||
if (!list)
|
||||
return;
|
||||
if (list->list[idx].userdata)
|
||||
free(list->list[idx].userdata);
|
||||
list->list[idx].userdata = NULL;
|
||||
}
|
||||
|
||||
void *file_list_get_last_actiondata(const file_list_t *list)
|
||||
{
|
||||
if (!list)
|
||||
return NULL;
|
||||
return list->list[list->size - 1].actiondata;
|
||||
}
|
||||
|
||||
void file_list_get_at_offset(const file_list_t *list, size_t idx,
|
||||
const char **path, const char **label, unsigned *file_type,
|
||||
size_t *entry_idx)
|
||||
{
|
||||
if (!list)
|
||||
return;
|
||||
|
||||
if (path)
|
||||
*path = list->list[idx].path;
|
||||
if (label)
|
||||
*label = list->list[idx].label;
|
||||
if (file_type)
|
||||
*file_type = list->list[idx].type;
|
||||
if (entry_idx)
|
||||
*entry_idx = list->list[idx].entry_idx;
|
||||
}
|
||||
|
||||
void file_list_get_last(const file_list_t *list,
|
||||
const char **path, const char **label,
|
||||
unsigned *file_type, size_t *entry_idx)
|
||||
{
|
||||
if (!list)
|
||||
return;
|
||||
|
||||
if (list->size)
|
||||
file_list_get_at_offset(list, list->size - 1, path, label, file_type, entry_idx);
|
||||
}
|
||||
|
||||
bool file_list_search(const file_list_t *list, const char *needle, size_t *idx)
|
||||
{
|
||||
size_t i;
|
||||
const char *alt;
|
||||
bool ret = false;
|
||||
|
||||
if (!list)
|
||||
return false;
|
||||
|
||||
for (i = 0; i < list->size; i++)
|
||||
{
|
||||
const char *str;
|
||||
file_list_get_alt_at_offset(list, i, &alt);
|
||||
if (!alt)
|
||||
{
|
||||
file_list_get_label_at_offset(list, i, &alt);
|
||||
if (!alt)
|
||||
continue;
|
||||
}
|
||||
|
||||
str = (const char *)strcasestr(alt, needle);
|
||||
if (str == alt)
|
||||
{
|
||||
/* Found match with first chars, best possible match. */
|
||||
*idx = i;
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
else if (str && !ret)
|
||||
{
|
||||
/* Found mid-string match, but try to find a match with
|
||||
* first characters before we settle. */
|
||||
*idx = i;
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,142 +1,142 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (memory_stream.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <file/memory_stream.h>
|
||||
|
||||
static uint8_t* g_buffer = NULL;
|
||||
static size_t g_size = 0;
|
||||
static size_t last_file_size = 0;
|
||||
|
||||
struct memstream
|
||||
{
|
||||
uint8_t *m_buf;
|
||||
size_t m_size;
|
||||
size_t m_ptr;
|
||||
};
|
||||
|
||||
void memstream_set_buffer(uint8_t *buffer, size_t size)
|
||||
{
|
||||
g_buffer = buffer;
|
||||
g_size = size;
|
||||
}
|
||||
|
||||
size_t memstream_get_last_size(void)
|
||||
{
|
||||
return last_file_size;
|
||||
}
|
||||
|
||||
static void memstream_init(memstream_t *stream, uint8_t *buffer, size_t max_size)
|
||||
{
|
||||
stream->m_buf = buffer;
|
||||
stream->m_size = max_size;
|
||||
stream->m_ptr = 0;
|
||||
}
|
||||
|
||||
memstream_t *memstream_open(void)
|
||||
{
|
||||
memstream_t *stream;
|
||||
if (!g_buffer || !g_size)
|
||||
return NULL;
|
||||
|
||||
stream = (memstream_t*)calloc(1, sizeof(*stream));
|
||||
memstream_init(stream, g_buffer, g_size);
|
||||
|
||||
g_buffer = NULL;
|
||||
g_size = 0;
|
||||
return stream;
|
||||
}
|
||||
|
||||
void memstream_close(memstream_t *stream)
|
||||
{
|
||||
last_file_size = stream->m_ptr;
|
||||
free(stream);
|
||||
}
|
||||
|
||||
size_t memstream_read(memstream_t *stream, void *data, size_t bytes)
|
||||
{
|
||||
size_t avail = stream->m_size - stream->m_ptr;
|
||||
if (bytes > avail)
|
||||
bytes = avail;
|
||||
|
||||
memcpy(data, stream->m_buf + stream->m_ptr, bytes);
|
||||
stream->m_ptr += bytes;
|
||||
return bytes;
|
||||
}
|
||||
|
||||
size_t memstream_write(memstream_t *stream, const void *data, size_t bytes)
|
||||
{
|
||||
size_t avail = stream->m_size - stream->m_ptr;
|
||||
if (bytes > avail)
|
||||
bytes = avail;
|
||||
|
||||
memcpy(stream->m_buf + stream->m_ptr, data, bytes);
|
||||
stream->m_ptr += bytes;
|
||||
return bytes;
|
||||
}
|
||||
|
||||
int memstream_seek(memstream_t *stream, int offset, int whence)
|
||||
{
|
||||
size_t ptr;
|
||||
|
||||
switch (whence)
|
||||
{
|
||||
case SEEK_SET:
|
||||
ptr = offset;
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
ptr = stream->m_ptr + offset;
|
||||
break;
|
||||
case SEEK_END:
|
||||
ptr = stream->m_size + offset;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ptr <= stream->m_size)
|
||||
{
|
||||
stream->m_ptr = ptr;
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t memstream_pos(memstream_t *stream)
|
||||
{
|
||||
return stream->m_ptr;
|
||||
}
|
||||
|
||||
char *memstream_gets(memstream_t *stream, char *buffer, size_t len)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int memstream_getc(memstream_t *stream)
|
||||
{
|
||||
if (stream->m_ptr >= stream->m_size)
|
||||
return EOF;
|
||||
return stream->m_buf[stream->m_ptr++];
|
||||
}
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (memory_stream.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <file/memory_stream.h>
|
||||
|
||||
static uint8_t* g_buffer = NULL;
|
||||
static size_t g_size = 0;
|
||||
static size_t last_file_size = 0;
|
||||
|
||||
struct memstream
|
||||
{
|
||||
uint8_t *m_buf;
|
||||
size_t m_size;
|
||||
size_t m_ptr;
|
||||
};
|
||||
|
||||
void memstream_set_buffer(uint8_t *buffer, size_t size)
|
||||
{
|
||||
g_buffer = buffer;
|
||||
g_size = size;
|
||||
}
|
||||
|
||||
size_t memstream_get_last_size(void)
|
||||
{
|
||||
return last_file_size;
|
||||
}
|
||||
|
||||
static void memstream_init(memstream_t *stream, uint8_t *buffer, size_t max_size)
|
||||
{
|
||||
stream->m_buf = buffer;
|
||||
stream->m_size = max_size;
|
||||
stream->m_ptr = 0;
|
||||
}
|
||||
|
||||
memstream_t *memstream_open(void)
|
||||
{
|
||||
memstream_t *stream;
|
||||
if (!g_buffer || !g_size)
|
||||
return NULL;
|
||||
|
||||
stream = (memstream_t*)calloc(1, sizeof(*stream));
|
||||
memstream_init(stream, g_buffer, g_size);
|
||||
|
||||
g_buffer = NULL;
|
||||
g_size = 0;
|
||||
return stream;
|
||||
}
|
||||
|
||||
void memstream_close(memstream_t *stream)
|
||||
{
|
||||
last_file_size = stream->m_ptr;
|
||||
free(stream);
|
||||
}
|
||||
|
||||
size_t memstream_read(memstream_t *stream, void *data, size_t bytes)
|
||||
{
|
||||
size_t avail = stream->m_size - stream->m_ptr;
|
||||
if (bytes > avail)
|
||||
bytes = avail;
|
||||
|
||||
memcpy(data, stream->m_buf + stream->m_ptr, bytes);
|
||||
stream->m_ptr += bytes;
|
||||
return bytes;
|
||||
}
|
||||
|
||||
size_t memstream_write(memstream_t *stream, const void *data, size_t bytes)
|
||||
{
|
||||
size_t avail = stream->m_size - stream->m_ptr;
|
||||
if (bytes > avail)
|
||||
bytes = avail;
|
||||
|
||||
memcpy(stream->m_buf + stream->m_ptr, data, bytes);
|
||||
stream->m_ptr += bytes;
|
||||
return bytes;
|
||||
}
|
||||
|
||||
int memstream_seek(memstream_t *stream, int offset, int whence)
|
||||
{
|
||||
size_t ptr;
|
||||
|
||||
switch (whence)
|
||||
{
|
||||
case SEEK_SET:
|
||||
ptr = offset;
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
ptr = stream->m_ptr + offset;
|
||||
break;
|
||||
case SEEK_END:
|
||||
ptr = stream->m_size + offset;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ptr <= stream->m_size)
|
||||
{
|
||||
stream->m_ptr = ptr;
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t memstream_pos(memstream_t *stream)
|
||||
{
|
||||
return stream->m_ptr;
|
||||
}
|
||||
|
||||
char *memstream_gets(memstream_t *stream, char *buffer, size_t len)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int memstream_getc(memstream_t *stream)
|
||||
{
|
||||
if (stream->m_ptr >= stream->m_size)
|
||||
return EOF;
|
||||
return stream->m_buf[stream->m_ptr++];
|
||||
}
|
||||
|
|
|
@ -1,206 +1,206 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <file/nbio.h>
|
||||
|
||||
struct nbio_t
|
||||
{
|
||||
FILE* f;
|
||||
void* data;
|
||||
size_t progress;
|
||||
size_t len;
|
||||
/*
|
||||
* possible values:
|
||||
* NBIO_READ, NBIO_WRITE - obvious
|
||||
* -1 - currently doing nothing
|
||||
* -2 - the pointer was reallocated since the last operation
|
||||
*/
|
||||
signed char op;
|
||||
signed char mode;
|
||||
};
|
||||
|
||||
static const char * modes[]={ "rb", "wb", "r+b", "rb", "wb", "r+b" };
|
||||
|
||||
struct nbio_t* nbio_open(const char * filename, unsigned mode)
|
||||
{
|
||||
struct nbio_t* handle = NULL;
|
||||
FILE* f = fopen(filename, modes[mode]);
|
||||
if (!f)
|
||||
return NULL;
|
||||
|
||||
handle = (struct nbio_t*)malloc(sizeof(struct nbio_t));
|
||||
|
||||
if (!handle)
|
||||
goto error;
|
||||
|
||||
handle->f = f;
|
||||
handle->len = 0;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case NBIO_WRITE:
|
||||
case BIO_WRITE:
|
||||
break;
|
||||
default:
|
||||
fseek(handle->f, 0, SEEK_END);
|
||||
handle->len = ftell(handle->f);
|
||||
break;
|
||||
}
|
||||
|
||||
handle->mode = mode;
|
||||
handle->data = malloc(handle->len);
|
||||
|
||||
if (handle->len && !handle->data)
|
||||
goto error;
|
||||
|
||||
handle->progress = handle->len;
|
||||
handle->op = -2;
|
||||
|
||||
return handle;
|
||||
|
||||
error:
|
||||
if (handle)
|
||||
{
|
||||
if (handle->data)
|
||||
free(handle->data);
|
||||
handle->data = NULL;
|
||||
free(handle);
|
||||
}
|
||||
handle = NULL;
|
||||
fclose(f);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void nbio_begin_read(struct nbio_t* handle)
|
||||
{
|
||||
if (!handle)
|
||||
return;
|
||||
|
||||
if (handle->op >= 0)
|
||||
{
|
||||
puts("ERROR - attempted file read operation while busy");
|
||||
abort();
|
||||
}
|
||||
|
||||
fseek(handle->f, 0, SEEK_SET);
|
||||
|
||||
handle->op = NBIO_READ;
|
||||
handle->progress = 0;
|
||||
}
|
||||
|
||||
void nbio_begin_write(struct nbio_t* handle)
|
||||
{
|
||||
if (!handle)
|
||||
return;
|
||||
|
||||
if (handle->op >= 0)
|
||||
{
|
||||
puts("ERROR - attempted file write operation while busy");
|
||||
abort();
|
||||
}
|
||||
|
||||
fseek(handle->f, 0, SEEK_SET);
|
||||
handle->op = NBIO_WRITE;
|
||||
handle->progress = 0;
|
||||
}
|
||||
|
||||
bool nbio_iterate(struct nbio_t* handle)
|
||||
{
|
||||
size_t amount = 65536;
|
||||
|
||||
if (!handle)
|
||||
return false;
|
||||
|
||||
if (amount > handle->len - handle->progress)
|
||||
amount = handle->len - handle->progress;
|
||||
|
||||
switch (handle->op)
|
||||
{
|
||||
case NBIO_READ:
|
||||
if (handle->mode == BIO_READ)
|
||||
{
|
||||
amount = handle->len;
|
||||
fread((char*)handle->data, 1, amount, handle->f);
|
||||
}
|
||||
else
|
||||
fread((char*)handle->data + handle->progress, 1, amount, handle->f);
|
||||
break;
|
||||
case NBIO_WRITE:
|
||||
if (handle->mode == BIO_WRITE)
|
||||
{
|
||||
size_t written = 0;
|
||||
amount = handle->len;
|
||||
written = fwrite((char*)handle->data, 1, amount, handle->f);
|
||||
if (written != amount)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
fwrite((char*)handle->data + handle->progress, 1, amount, handle->f);
|
||||
break;
|
||||
}
|
||||
|
||||
handle->progress += amount;
|
||||
|
||||
if (handle->progress == handle->len)
|
||||
handle->op = -1;
|
||||
return (handle->op < 0);
|
||||
}
|
||||
|
||||
void nbio_resize(struct nbio_t* handle, size_t len)
|
||||
{
|
||||
if (!handle)
|
||||
return;
|
||||
|
||||
if (handle->op >= 0)
|
||||
{
|
||||
puts("ERROR - attempted file resize operation while busy");
|
||||
abort();
|
||||
}
|
||||
if (len < handle->len)
|
||||
{
|
||||
puts("ERROR - attempted file shrink operation, not implemented");
|
||||
abort();
|
||||
}
|
||||
|
||||
handle->len = len;
|
||||
handle->data = realloc(handle->data, handle->len);
|
||||
handle->op = -1;
|
||||
handle->progress = handle->len;
|
||||
}
|
||||
|
||||
void* nbio_get_ptr(struct nbio_t* handle, size_t* len)
|
||||
{
|
||||
if (!handle)
|
||||
return NULL;
|
||||
if (len)
|
||||
*len = handle->len;
|
||||
if (handle->op == -1)
|
||||
return handle->data;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void nbio_cancel(struct nbio_t* handle)
|
||||
{
|
||||
if (!handle)
|
||||
return;
|
||||
|
||||
handle->op = -1;
|
||||
handle->progress = handle->len;
|
||||
}
|
||||
|
||||
void nbio_free(struct nbio_t* handle)
|
||||
{
|
||||
if (!handle)
|
||||
return;
|
||||
if (handle->op >= 0)
|
||||
{
|
||||
puts("ERROR - attempted free() while busy");
|
||||
abort();
|
||||
}
|
||||
fclose(handle->f);
|
||||
free(handle->data);
|
||||
|
||||
handle->f = NULL;
|
||||
handle->data = NULL;
|
||||
free(handle);
|
||||
}
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <file/nbio.h>
|
||||
|
||||
struct nbio_t
|
||||
{
|
||||
FILE* f;
|
||||
void* data;
|
||||
size_t progress;
|
||||
size_t len;
|
||||
/*
|
||||
* possible values:
|
||||
* NBIO_READ, NBIO_WRITE - obvious
|
||||
* -1 - currently doing nothing
|
||||
* -2 - the pointer was reallocated since the last operation
|
||||
*/
|
||||
signed char op;
|
||||
signed char mode;
|
||||
};
|
||||
|
||||
static const char * modes[]={ "rb", "wb", "r+b", "rb", "wb", "r+b" };
|
||||
|
||||
struct nbio_t* nbio_open(const char * filename, unsigned mode)
|
||||
{
|
||||
struct nbio_t* handle = NULL;
|
||||
FILE* f = fopen(filename, modes[mode]);
|
||||
if (!f)
|
||||
return NULL;
|
||||
|
||||
handle = (struct nbio_t*)malloc(sizeof(struct nbio_t));
|
||||
|
||||
if (!handle)
|
||||
goto error;
|
||||
|
||||
handle->f = f;
|
||||
handle->len = 0;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case NBIO_WRITE:
|
||||
case BIO_WRITE:
|
||||
break;
|
||||
default:
|
||||
fseek(handle->f, 0, SEEK_END);
|
||||
handle->len = ftell(handle->f);
|
||||
break;
|
||||
}
|
||||
|
||||
handle->mode = mode;
|
||||
handle->data = malloc(handle->len);
|
||||
|
||||
if (handle->len && !handle->data)
|
||||
goto error;
|
||||
|
||||
handle->progress = handle->len;
|
||||
handle->op = -2;
|
||||
|
||||
return handle;
|
||||
|
||||
error:
|
||||
if (handle)
|
||||
{
|
||||
if (handle->data)
|
||||
free(handle->data);
|
||||
handle->data = NULL;
|
||||
free(handle);
|
||||
}
|
||||
handle = NULL;
|
||||
fclose(f);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void nbio_begin_read(struct nbio_t* handle)
|
||||
{
|
||||
if (!handle)
|
||||
return;
|
||||
|
||||
if (handle->op >= 0)
|
||||
{
|
||||
puts("ERROR - attempted file read operation while busy");
|
||||
abort();
|
||||
}
|
||||
|
||||
fseek(handle->f, 0, SEEK_SET);
|
||||
|
||||
handle->op = NBIO_READ;
|
||||
handle->progress = 0;
|
||||
}
|
||||
|
||||
void nbio_begin_write(struct nbio_t* handle)
|
||||
{
|
||||
if (!handle)
|
||||
return;
|
||||
|
||||
if (handle->op >= 0)
|
||||
{
|
||||
puts("ERROR - attempted file write operation while busy");
|
||||
abort();
|
||||
}
|
||||
|
||||
fseek(handle->f, 0, SEEK_SET);
|
||||
handle->op = NBIO_WRITE;
|
||||
handle->progress = 0;
|
||||
}
|
||||
|
||||
bool nbio_iterate(struct nbio_t* handle)
|
||||
{
|
||||
size_t amount = 65536;
|
||||
|
||||
if (!handle)
|
||||
return false;
|
||||
|
||||
if (amount > handle->len - handle->progress)
|
||||
amount = handle->len - handle->progress;
|
||||
|
||||
switch (handle->op)
|
||||
{
|
||||
case NBIO_READ:
|
||||
if (handle->mode == BIO_READ)
|
||||
{
|
||||
amount = handle->len;
|
||||
fread((char*)handle->data, 1, amount, handle->f);
|
||||
}
|
||||
else
|
||||
fread((char*)handle->data + handle->progress, 1, amount, handle->f);
|
||||
break;
|
||||
case NBIO_WRITE:
|
||||
if (handle->mode == BIO_WRITE)
|
||||
{
|
||||
size_t written = 0;
|
||||
amount = handle->len;
|
||||
written = fwrite((char*)handle->data, 1, amount, handle->f);
|
||||
if (written != amount)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
fwrite((char*)handle->data + handle->progress, 1, amount, handle->f);
|
||||
break;
|
||||
}
|
||||
|
||||
handle->progress += amount;
|
||||
|
||||
if (handle->progress == handle->len)
|
||||
handle->op = -1;
|
||||
return (handle->op < 0);
|
||||
}
|
||||
|
||||
void nbio_resize(struct nbio_t* handle, size_t len)
|
||||
{
|
||||
if (!handle)
|
||||
return;
|
||||
|
||||
if (handle->op >= 0)
|
||||
{
|
||||
puts("ERROR - attempted file resize operation while busy");
|
||||
abort();
|
||||
}
|
||||
if (len < handle->len)
|
||||
{
|
||||
puts("ERROR - attempted file shrink operation, not implemented");
|
||||
abort();
|
||||
}
|
||||
|
||||
handle->len = len;
|
||||
handle->data = realloc(handle->data, handle->len);
|
||||
handle->op = -1;
|
||||
handle->progress = handle->len;
|
||||
}
|
||||
|
||||
void* nbio_get_ptr(struct nbio_t* handle, size_t* len)
|
||||
{
|
||||
if (!handle)
|
||||
return NULL;
|
||||
if (len)
|
||||
*len = handle->len;
|
||||
if (handle->op == -1)
|
||||
return handle->data;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void nbio_cancel(struct nbio_t* handle)
|
||||
{
|
||||
if (!handle)
|
||||
return;
|
||||
|
||||
handle->op = -1;
|
||||
handle->progress = handle->len;
|
||||
}
|
||||
|
||||
void nbio_free(struct nbio_t* handle)
|
||||
{
|
||||
if (!handle)
|
||||
return;
|
||||
if (handle->op >= 0)
|
||||
{
|
||||
puts("ERROR - attempted free() while busy");
|
||||
abort();
|
||||
}
|
||||
fclose(handle->f);
|
||||
free(handle->data);
|
||||
|
||||
handle->f = NULL;
|
||||
handle->data = NULL;
|
||||
free(handle);
|
||||
}
|
||||
|
|
|
@ -1,63 +1,63 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <file/nbio.h>
|
||||
|
||||
static void nbio_write_test(void)
|
||||
{
|
||||
size_t size;
|
||||
bool looped = false;
|
||||
void* ptr = NULL;
|
||||
struct nbio_t* write = nbio_open("test.bin", NBIO_WRITE);
|
||||
|
||||
nbio_resize(write, 1024*1024);
|
||||
|
||||
ptr = nbio_get_ptr(write, &size);
|
||||
if (size != 1024*1024)
|
||||
puts("ERROR: wrong size (1)");
|
||||
|
||||
memset(ptr, 0x42, 1024*1024);
|
||||
nbio_begin_write(write);
|
||||
|
||||
while (!nbio_iterate(write)) looped=true;
|
||||
|
||||
if (!looped)
|
||||
puts("Write finished immediately?");
|
||||
|
||||
nbio_free(write);
|
||||
}
|
||||
|
||||
static void nbio_read_test(void)
|
||||
{
|
||||
size_t size;
|
||||
bool looped = false;
|
||||
struct nbio_t* read = nbio_open("test.bin", NBIO_READ);
|
||||
void* ptr = nbio_get_ptr(read, &size);
|
||||
|
||||
if (size != 1024*1024)
|
||||
puts("ERROR: wrong size (2)");
|
||||
if (ptr)
|
||||
puts("Read pointer is available before iterating?");
|
||||
|
||||
nbio_begin_read(read);
|
||||
|
||||
while (!nbio_iterate(read)) looped=true;
|
||||
|
||||
if (!looped)
|
||||
puts("Read finished immediately?");
|
||||
|
||||
ptr = nbio_get_ptr(read, &size);
|
||||
|
||||
if (size != 1024*1024)
|
||||
puts("ERROR: wrong size (3)");
|
||||
if (*(char*)ptr != 0x42 || memcmp(ptr, (char*)ptr+1, 1024*1024-1))
|
||||
puts("ERROR: wrong data");
|
||||
|
||||
nbio_free(read);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
nbio_write_test();
|
||||
nbio_read_test();
|
||||
}
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <file/nbio.h>
|
||||
|
||||
static void nbio_write_test(void)
|
||||
{
|
||||
size_t size;
|
||||
bool looped = false;
|
||||
void* ptr = NULL;
|
||||
struct nbio_t* write = nbio_open("test.bin", NBIO_WRITE);
|
||||
|
||||
nbio_resize(write, 1024*1024);
|
||||
|
||||
ptr = nbio_get_ptr(write, &size);
|
||||
if (size != 1024*1024)
|
||||
puts("ERROR: wrong size (1)");
|
||||
|
||||
memset(ptr, 0x42, 1024*1024);
|
||||
nbio_begin_write(write);
|
||||
|
||||
while (!nbio_iterate(write)) looped=true;
|
||||
|
||||
if (!looped)
|
||||
puts("Write finished immediately?");
|
||||
|
||||
nbio_free(write);
|
||||
}
|
||||
|
||||
static void nbio_read_test(void)
|
||||
{
|
||||
size_t size;
|
||||
bool looped = false;
|
||||
struct nbio_t* read = nbio_open("test.bin", NBIO_READ);
|
||||
void* ptr = nbio_get_ptr(read, &size);
|
||||
|
||||
if (size != 1024*1024)
|
||||
puts("ERROR: wrong size (2)");
|
||||
if (ptr)
|
||||
puts("Read pointer is available before iterating?");
|
||||
|
||||
nbio_begin_read(read);
|
||||
|
||||
while (!nbio_iterate(read)) looped=true;
|
||||
|
||||
if (!looped)
|
||||
puts("Read finished immediately?");
|
||||
|
||||
ptr = nbio_get_ptr(read, &size);
|
||||
|
||||
if (size != 1024*1024)
|
||||
puts("ERROR: wrong size (3)");
|
||||
if (*(char*)ptr != 0x42 || memcmp(ptr, (char*)ptr+1, 1024*1024-1))
|
||||
puts("ERROR: wrong data");
|
||||
|
||||
nbio_free(read);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
nbio_write_test();
|
||||
nbio_read_test();
|
||||
}
|
||||
|
|
|
@ -1,202 +1,202 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (retro_dirent.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <retro_common.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
# ifdef _MSC_VER
|
||||
# define setmode _setmode
|
||||
# endif
|
||||
# ifdef _XBOX
|
||||
# include <xtl.h>
|
||||
# define INVALID_FILE_ATTRIBUTES -1
|
||||
# else
|
||||
# include <io.h>
|
||||
# include <fcntl.h>
|
||||
# include <direct.h>
|
||||
# include <windows.h>
|
||||
# endif
|
||||
#elif defined(VITA)
|
||||
# include <psp2/io/fcntl.h>
|
||||
# include <psp2/io/dirent.h>
|
||||
#else
|
||||
# if defined(PSP)
|
||||
# include <pspiofilemgr.h>
|
||||
# endif
|
||||
# include <sys/types.h>
|
||||
# include <sys/stat.h>
|
||||
# include <dirent.h>
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef __CELLOS_LV2__
|
||||
#include <cell/cell_fs.h>
|
||||
#endif
|
||||
|
||||
#include <boolean.h>
|
||||
#include <retro_stat.h>
|
||||
#include <retro_dirent.h>
|
||||
|
||||
struct RDIR
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
WIN32_FIND_DATA entry;
|
||||
HANDLE directory;
|
||||
#elif defined(VITA) || defined(PSP)
|
||||
SceUID directory;
|
||||
SceIoDirent entry;
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
CellFsErrno error;
|
||||
int directory;
|
||||
CellFsDirent entry;
|
||||
#else
|
||||
DIR *directory;
|
||||
const struct dirent *entry;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct RDIR *retro_opendir(const char *name)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
char path_buf[1024];
|
||||
#endif
|
||||
struct RDIR *rdir = (struct RDIR*)calloc(1, sizeof(*rdir));
|
||||
|
||||
if (!rdir)
|
||||
return NULL;
|
||||
|
||||
#if defined(_WIN32)
|
||||
snprintf(path_buf, sizeof(path_buf), "%s\\*", name);
|
||||
rdir->directory = FindFirstFile(path_buf, &rdir->entry);
|
||||
#elif defined(VITA) || defined(PSP)
|
||||
rdir->directory = sceIoDopen(name);
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
rdir->error = cellFsOpendir(name, &rdir->directory);
|
||||
#else
|
||||
rdir->directory = opendir(name);
|
||||
rdir->entry = NULL;
|
||||
#endif
|
||||
|
||||
return rdir;
|
||||
}
|
||||
|
||||
bool retro_dirent_error(struct RDIR *rdir)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
return (rdir->directory == INVALID_HANDLE_VALUE);
|
||||
#elif defined(VITA) || defined(PSP)
|
||||
return (rdir->directory < 0);
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
return (rdir->error != CELL_FS_SUCCEEDED);
|
||||
#else
|
||||
return !(rdir->directory);
|
||||
#endif
|
||||
}
|
||||
|
||||
int retro_readdir(struct RDIR *rdir)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
return (FindNextFile(rdir->directory, &rdir->entry) != 0);
|
||||
#elif defined(VITA) || defined(PSP)
|
||||
return (sceIoDread(rdir->directory, &rdir->entry) > 0);
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
uint64_t nread;
|
||||
rdir->error = cellFsReaddir(rdir->directory, &rdir->entry, &nread);
|
||||
return (nread != 0);
|
||||
#else
|
||||
return ((rdir->entry = readdir(rdir->directory)) != NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
const char *retro_dirent_get_name(struct RDIR *rdir)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
return rdir->entry.cFileName;
|
||||
#elif defined(VITA) || defined(PSP) || defined(__CELLOS_LV2__)
|
||||
return rdir->entry.d_name;
|
||||
#else
|
||||
return rdir->entry->d_name;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* retro_dirent_is_dir:
|
||||
* @rdir : pointer to the directory entry.
|
||||
* @path : path to the directory entry.
|
||||
*
|
||||
* Is the directory listing entry a directory?
|
||||
*
|
||||
* Returns: true if directory listing entry is
|
||||
* a directory, false if not.
|
||||
*/
|
||||
bool retro_dirent_is_dir(struct RDIR *rdir, const char *path)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
const WIN32_FIND_DATA *entry = (const WIN32_FIND_DATA*)&rdir->entry;
|
||||
return entry->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
|
||||
#elif defined(PSP) || defined(VITA)
|
||||
const SceIoDirent *entry = (const SceIoDirent*)&rdir->entry;
|
||||
#if defined(PSP)
|
||||
return (entry->d_stat.st_attr & FIO_SO_IFDIR) == FIO_SO_IFDIR;
|
||||
#elif defined(VITA)
|
||||
return PSP2_S_ISDIR(entry->d_stat.st_mode);
|
||||
#endif
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
CellFsDirent *entry = (CellFsDirent*)&rdir->entry;
|
||||
return (entry->d_type == CELL_FS_TYPE_DIRECTORY);
|
||||
#elif defined(DT_DIR)
|
||||
const struct dirent *entry = (const struct dirent*)rdir->entry;
|
||||
if (entry->d_type == DT_DIR)
|
||||
return true;
|
||||
/* This can happen on certain file systems. */
|
||||
if (entry->d_type == DT_UNKNOWN || entry->d_type == DT_LNK)
|
||||
return path_is_directory(path);
|
||||
return false;
|
||||
#else
|
||||
/* dirent struct doesn't have d_type, do it the slow way ... */
|
||||
return path_is_directory(path);
|
||||
#endif
|
||||
}
|
||||
|
||||
void retro_closedir(struct RDIR *rdir)
|
||||
{
|
||||
if (!rdir)
|
||||
return;
|
||||
|
||||
#if defined(_WIN32)
|
||||
if (rdir->directory != INVALID_HANDLE_VALUE)
|
||||
FindClose(rdir->directory);
|
||||
#elif defined(VITA) || defined(PSP)
|
||||
sceIoDclose(rdir->directory);
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
rdir->error = cellFsClosedir(rdir->directory);
|
||||
#else
|
||||
if (rdir->directory)
|
||||
closedir(rdir->directory);
|
||||
#endif
|
||||
|
||||
free(rdir);
|
||||
}
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (retro_dirent.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <retro_common.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
# ifdef _MSC_VER
|
||||
# define setmode _setmode
|
||||
# endif
|
||||
# ifdef _XBOX
|
||||
# include <xtl.h>
|
||||
# define INVALID_FILE_ATTRIBUTES -1
|
||||
# else
|
||||
# include <io.h>
|
||||
# include <fcntl.h>
|
||||
# include <direct.h>
|
||||
# include <windows.h>
|
||||
# endif
|
||||
#elif defined(VITA)
|
||||
# include <psp2/io/fcntl.h>
|
||||
# include <psp2/io/dirent.h>
|
||||
#else
|
||||
# if defined(PSP)
|
||||
# include <pspiofilemgr.h>
|
||||
# endif
|
||||
# include <sys/types.h>
|
||||
# include <sys/stat.h>
|
||||
# include <dirent.h>
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef __CELLOS_LV2__
|
||||
#include <cell/cell_fs.h>
|
||||
#endif
|
||||
|
||||
#include <boolean.h>
|
||||
#include <retro_stat.h>
|
||||
#include <retro_dirent.h>
|
||||
|
||||
struct RDIR
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
WIN32_FIND_DATA entry;
|
||||
HANDLE directory;
|
||||
#elif defined(VITA) || defined(PSP)
|
||||
SceUID directory;
|
||||
SceIoDirent entry;
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
CellFsErrno error;
|
||||
int directory;
|
||||
CellFsDirent entry;
|
||||
#else
|
||||
DIR *directory;
|
||||
const struct dirent *entry;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct RDIR *retro_opendir(const char *name)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
char path_buf[1024];
|
||||
#endif
|
||||
struct RDIR *rdir = (struct RDIR*)calloc(1, sizeof(*rdir));
|
||||
|
||||
if (!rdir)
|
||||
return NULL;
|
||||
|
||||
#if defined(_WIN32)
|
||||
snprintf(path_buf, sizeof(path_buf), "%s\\*", name);
|
||||
rdir->directory = FindFirstFile(path_buf, &rdir->entry);
|
||||
#elif defined(VITA) || defined(PSP)
|
||||
rdir->directory = sceIoDopen(name);
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
rdir->error = cellFsOpendir(name, &rdir->directory);
|
||||
#else
|
||||
rdir->directory = opendir(name);
|
||||
rdir->entry = NULL;
|
||||
#endif
|
||||
|
||||
return rdir;
|
||||
}
|
||||
|
||||
bool retro_dirent_error(struct RDIR *rdir)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
return (rdir->directory == INVALID_HANDLE_VALUE);
|
||||
#elif defined(VITA) || defined(PSP)
|
||||
return (rdir->directory < 0);
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
return (rdir->error != CELL_FS_SUCCEEDED);
|
||||
#else
|
||||
return !(rdir->directory);
|
||||
#endif
|
||||
}
|
||||
|
||||
int retro_readdir(struct RDIR *rdir)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
return (FindNextFile(rdir->directory, &rdir->entry) != 0);
|
||||
#elif defined(VITA) || defined(PSP)
|
||||
return (sceIoDread(rdir->directory, &rdir->entry) > 0);
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
uint64_t nread;
|
||||
rdir->error = cellFsReaddir(rdir->directory, &rdir->entry, &nread);
|
||||
return (nread != 0);
|
||||
#else
|
||||
return ((rdir->entry = readdir(rdir->directory)) != NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
const char *retro_dirent_get_name(struct RDIR *rdir)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
return rdir->entry.cFileName;
|
||||
#elif defined(VITA) || defined(PSP) || defined(__CELLOS_LV2__)
|
||||
return rdir->entry.d_name;
|
||||
#else
|
||||
return rdir->entry->d_name;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* retro_dirent_is_dir:
|
||||
* @rdir : pointer to the directory entry.
|
||||
* @path : path to the directory entry.
|
||||
*
|
||||
* Is the directory listing entry a directory?
|
||||
*
|
||||
* Returns: true if directory listing entry is
|
||||
* a directory, false if not.
|
||||
*/
|
||||
bool retro_dirent_is_dir(struct RDIR *rdir, const char *path)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
const WIN32_FIND_DATA *entry = (const WIN32_FIND_DATA*)&rdir->entry;
|
||||
return entry->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
|
||||
#elif defined(PSP) || defined(VITA)
|
||||
const SceIoDirent *entry = (const SceIoDirent*)&rdir->entry;
|
||||
#if defined(PSP)
|
||||
return (entry->d_stat.st_attr & FIO_SO_IFDIR) == FIO_SO_IFDIR;
|
||||
#elif defined(VITA)
|
||||
return PSP2_S_ISDIR(entry->d_stat.st_mode);
|
||||
#endif
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
CellFsDirent *entry = (CellFsDirent*)&rdir->entry;
|
||||
return (entry->d_type == CELL_FS_TYPE_DIRECTORY);
|
||||
#elif defined(DT_DIR)
|
||||
const struct dirent *entry = (const struct dirent*)rdir->entry;
|
||||
if (entry->d_type == DT_DIR)
|
||||
return true;
|
||||
/* This can happen on certain file systems. */
|
||||
if (entry->d_type == DT_UNKNOWN || entry->d_type == DT_LNK)
|
||||
return path_is_directory(path);
|
||||
return false;
|
||||
#else
|
||||
/* dirent struct doesn't have d_type, do it the slow way ... */
|
||||
return path_is_directory(path);
|
||||
#endif
|
||||
}
|
||||
|
||||
void retro_closedir(struct RDIR *rdir)
|
||||
{
|
||||
if (!rdir)
|
||||
return;
|
||||
|
||||
#if defined(_WIN32)
|
||||
if (rdir->directory != INVALID_HANDLE_VALUE)
|
||||
FindClose(rdir->directory);
|
||||
#elif defined(VITA) || defined(PSP)
|
||||
sceIoDclose(rdir->directory);
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
rdir->error = cellFsClosedir(rdir->directory);
|
||||
#else
|
||||
if (rdir->directory)
|
||||
closedir(rdir->directory);
|
||||
#endif
|
||||
|
||||
free(rdir);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,213 +1,213 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (retro_stat.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
#ifdef _MSC_VER
|
||||
#define setmode _setmode
|
||||
#endif
|
||||
#ifdef _XBOX
|
||||
#include <xtl.h>
|
||||
#define INVALID_FILE_ATTRIBUTES -1
|
||||
#else
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
#include <direct.h>
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#elif defined(VITA)
|
||||
#define SCE_ERROR_ERRNO_EEXIST 0x80010011
|
||||
#include <psp2/io/fcntl.h>
|
||||
#include <psp2/io/dirent.h>
|
||||
#include <psp2/io/stat.h>
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if defined(PSP)
|
||||
#include <pspkernel.h>
|
||||
#endif
|
||||
|
||||
#ifdef __HAIKU__
|
||||
#include <kernel/image.h>
|
||||
#endif
|
||||
|
||||
#if defined(__CELLOS_LV2__)
|
||||
#include <cell/cell_fs.h>
|
||||
#endif
|
||||
|
||||
#if defined(VITA)
|
||||
#define FIO_S_ISDIR PSP2_S_ISDIR
|
||||
#endif
|
||||
|
||||
#if (defined(__CELLOS_LV2__) && !defined(__PSL1GHT__)) || defined(__QNX__) || defined(PSP)
|
||||
#include <unistd.h> /* stat() is defined here */
|
||||
#endif
|
||||
|
||||
#include <retro_miscellaneous.h>
|
||||
#include <boolean.h>
|
||||
|
||||
enum stat_mode
|
||||
{
|
||||
IS_DIRECTORY = 0,
|
||||
IS_CHARACTER_SPECIAL,
|
||||
IS_VALID
|
||||
};
|
||||
|
||||
static bool path_stat(const char *path, enum stat_mode mode, int32_t *size)
|
||||
{
|
||||
#if defined(VITA) || defined(PSP)
|
||||
SceIoStat buf;
|
||||
char *tmp = strdup(path);
|
||||
size_t len = strlen(tmp);
|
||||
if (tmp[len-1] == '/')
|
||||
tmp[len-1]='\0';
|
||||
|
||||
if (sceIoGetstat(tmp, &buf) < 0)
|
||||
{
|
||||
free(tmp);
|
||||
return false;
|
||||
}
|
||||
free(tmp);
|
||||
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
CellFsStat buf;
|
||||
if (cellFsStat(path, &buf) < 0)
|
||||
return false;
|
||||
#elif defined(_WIN32)
|
||||
WIN32_FILE_ATTRIBUTE_DATA file_info;
|
||||
GET_FILEEX_INFO_LEVELS fInfoLevelId = GetFileExInfoStandard;
|
||||
DWORD ret = GetFileAttributesEx(path, fInfoLevelId, &file_info);
|
||||
if (ret == 0)
|
||||
return false;
|
||||
#else
|
||||
struct stat buf;
|
||||
if (stat(path, &buf) < 0)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
if (size)
|
||||
*size = file_info.nFileSizeLow;
|
||||
#else
|
||||
if (size)
|
||||
*size = buf.st_size;
|
||||
#endif
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case IS_DIRECTORY:
|
||||
#if defined(VITA) || defined(PSP)
|
||||
return FIO_S_ISDIR(buf.st_mode);
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
return ((buf.st_mode & S_IFMT) == S_IFDIR);
|
||||
#elif defined(_WIN32)
|
||||
return (file_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
|
||||
#else
|
||||
return S_ISDIR(buf.st_mode);
|
||||
#endif
|
||||
case IS_CHARACTER_SPECIAL:
|
||||
#if defined(VITA) || defined(PSP) || defined(__CELLOS_LV2__) || defined(_WIN32)
|
||||
return false;
|
||||
#else
|
||||
return S_ISCHR(buf.st_mode);
|
||||
#endif
|
||||
case IS_VALID:
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* path_is_directory:
|
||||
* @path : path
|
||||
*
|
||||
* Checks if path is a directory.
|
||||
*
|
||||
* Returns: true (1) if path is a directory, otherwise false (0).
|
||||
*/
|
||||
bool path_is_directory(const char *path)
|
||||
{
|
||||
return path_stat(path, IS_DIRECTORY, NULL);
|
||||
}
|
||||
|
||||
bool path_is_character_special(const char *path)
|
||||
{
|
||||
return path_stat(path, IS_CHARACTER_SPECIAL, NULL);
|
||||
}
|
||||
|
||||
bool path_is_valid(const char *path)
|
||||
{
|
||||
return path_stat(path, IS_VALID, NULL);
|
||||
}
|
||||
|
||||
int32_t path_get_size(const char *path)
|
||||
{
|
||||
int32_t filesize = 0;
|
||||
if (path_stat(path, IS_VALID, &filesize))
|
||||
return filesize;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* path_mkdir_norecurse:
|
||||
* @dir : directory
|
||||
*
|
||||
* Create directory on filesystem.
|
||||
*
|
||||
* Returns: true (1) if directory could be created, otherwise false (0).
|
||||
**/
|
||||
bool mkdir_norecurse(const char *dir)
|
||||
{
|
||||
int ret;
|
||||
#if defined(_WIN32)
|
||||
ret = _mkdir(dir);
|
||||
#elif defined(IOS)
|
||||
ret = mkdir(dir, 0755);
|
||||
#elif defined(VITA) || defined(PSP)
|
||||
ret = sceIoMkdir(dir, 0777);
|
||||
#else
|
||||
ret = mkdir(dir, 0750);
|
||||
#endif
|
||||
/* Don't treat this as an error. */
|
||||
#if defined(VITA)
|
||||
if ((ret == SCE_ERROR_ERRNO_EEXIST) && path_is_directory(dir))
|
||||
ret = 0;
|
||||
#elif defined(PSP) || defined(_3DS)
|
||||
if ((ret == -1) && path_is_directory(dir))
|
||||
ret = 0;
|
||||
#else
|
||||
if (ret < 0 && errno == EEXIST && path_is_directory(dir))
|
||||
ret = 0;
|
||||
#endif
|
||||
if (ret < 0)
|
||||
printf("mkdir(%s) error: %s.\n", dir, strerror(errno));
|
||||
return ret == 0;
|
||||
}
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (retro_stat.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
#ifdef _MSC_VER
|
||||
#define setmode _setmode
|
||||
#endif
|
||||
#ifdef _XBOX
|
||||
#include <xtl.h>
|
||||
#define INVALID_FILE_ATTRIBUTES -1
|
||||
#else
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
#include <direct.h>
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#elif defined(VITA)
|
||||
#define SCE_ERROR_ERRNO_EEXIST 0x80010011
|
||||
#include <psp2/io/fcntl.h>
|
||||
#include <psp2/io/dirent.h>
|
||||
#include <psp2/io/stat.h>
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if defined(PSP)
|
||||
#include <pspkernel.h>
|
||||
#endif
|
||||
|
||||
#ifdef __HAIKU__
|
||||
#include <kernel/image.h>
|
||||
#endif
|
||||
|
||||
#if defined(__CELLOS_LV2__)
|
||||
#include <cell/cell_fs.h>
|
||||
#endif
|
||||
|
||||
#if defined(VITA)
|
||||
#define FIO_S_ISDIR PSP2_S_ISDIR
|
||||
#endif
|
||||
|
||||
#if (defined(__CELLOS_LV2__) && !defined(__PSL1GHT__)) || defined(__QNX__) || defined(PSP)
|
||||
#include <unistd.h> /* stat() is defined here */
|
||||
#endif
|
||||
|
||||
#include <retro_miscellaneous.h>
|
||||
#include <boolean.h>
|
||||
|
||||
enum stat_mode
|
||||
{
|
||||
IS_DIRECTORY = 0,
|
||||
IS_CHARACTER_SPECIAL,
|
||||
IS_VALID
|
||||
};
|
||||
|
||||
static bool path_stat(const char *path, enum stat_mode mode, int32_t *size)
|
||||
{
|
||||
#if defined(VITA) || defined(PSP)
|
||||
SceIoStat buf;
|
||||
char *tmp = strdup(path);
|
||||
size_t len = strlen(tmp);
|
||||
if (tmp[len-1] == '/')
|
||||
tmp[len-1]='\0';
|
||||
|
||||
if (sceIoGetstat(tmp, &buf) < 0)
|
||||
{
|
||||
free(tmp);
|
||||
return false;
|
||||
}
|
||||
free(tmp);
|
||||
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
CellFsStat buf;
|
||||
if (cellFsStat(path, &buf) < 0)
|
||||
return false;
|
||||
#elif defined(_WIN32)
|
||||
WIN32_FILE_ATTRIBUTE_DATA file_info;
|
||||
GET_FILEEX_INFO_LEVELS fInfoLevelId = GetFileExInfoStandard;
|
||||
DWORD ret = GetFileAttributesEx(path, fInfoLevelId, &file_info);
|
||||
if (ret == 0)
|
||||
return false;
|
||||
#else
|
||||
struct stat buf;
|
||||
if (stat(path, &buf) < 0)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
if (size)
|
||||
*size = file_info.nFileSizeLow;
|
||||
#else
|
||||
if (size)
|
||||
*size = buf.st_size;
|
||||
#endif
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case IS_DIRECTORY:
|
||||
#if defined(VITA) || defined(PSP)
|
||||
return FIO_S_ISDIR(buf.st_mode);
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
return ((buf.st_mode & S_IFMT) == S_IFDIR);
|
||||
#elif defined(_WIN32)
|
||||
return (file_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
|
||||
#else
|
||||
return S_ISDIR(buf.st_mode);
|
||||
#endif
|
||||
case IS_CHARACTER_SPECIAL:
|
||||
#if defined(VITA) || defined(PSP) || defined(__CELLOS_LV2__) || defined(_WIN32)
|
||||
return false;
|
||||
#else
|
||||
return S_ISCHR(buf.st_mode);
|
||||
#endif
|
||||
case IS_VALID:
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* path_is_directory:
|
||||
* @path : path
|
||||
*
|
||||
* Checks if path is a directory.
|
||||
*
|
||||
* Returns: true (1) if path is a directory, otherwise false (0).
|
||||
*/
|
||||
bool path_is_directory(const char *path)
|
||||
{
|
||||
return path_stat(path, IS_DIRECTORY, NULL);
|
||||
}
|
||||
|
||||
bool path_is_character_special(const char *path)
|
||||
{
|
||||
return path_stat(path, IS_CHARACTER_SPECIAL, NULL);
|
||||
}
|
||||
|
||||
bool path_is_valid(const char *path)
|
||||
{
|
||||
return path_stat(path, IS_VALID, NULL);
|
||||
}
|
||||
|
||||
int32_t path_get_size(const char *path)
|
||||
{
|
||||
int32_t filesize = 0;
|
||||
if (path_stat(path, IS_VALID, &filesize))
|
||||
return filesize;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* path_mkdir_norecurse:
|
||||
* @dir : directory
|
||||
*
|
||||
* Create directory on filesystem.
|
||||
*
|
||||
* Returns: true (1) if directory could be created, otherwise false (0).
|
||||
**/
|
||||
bool mkdir_norecurse(const char *dir)
|
||||
{
|
||||
int ret;
|
||||
#if defined(_WIN32)
|
||||
ret = _mkdir(dir);
|
||||
#elif defined(IOS)
|
||||
ret = mkdir(dir, 0755);
|
||||
#elif defined(VITA) || defined(PSP)
|
||||
ret = sceIoMkdir(dir, 0777);
|
||||
#else
|
||||
ret = mkdir(dir, 0750);
|
||||
#endif
|
||||
/* Don't treat this as an error. */
|
||||
#if defined(VITA)
|
||||
if ((ret == SCE_ERROR_ERRNO_EEXIST) && path_is_directory(dir))
|
||||
ret = 0;
|
||||
#elif defined(PSP) || defined(_3DS)
|
||||
if ((ret == -1) && path_is_directory(dir))
|
||||
ret = 0;
|
||||
#else
|
||||
if (ret < 0 && errno == EEXIST && path_is_directory(dir))
|
||||
ret = 0;
|
||||
#endif
|
||||
if (ret < 0)
|
||||
printf("mkdir(%s) error: %s.\n", dir, strerror(errno));
|
||||
return ret == 0;
|
||||
}
|
||||
|
|
|
@ -1,220 +1,220 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (rbmp_encode.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <retro_file.h>
|
||||
#include <formats/rbmp.h>
|
||||
|
||||
static bool write_header_bmp(RFILE *file, unsigned width, unsigned height, bool is32bpp)
|
||||
{
|
||||
unsigned line_size = (width * (is32bpp?4:3) + 3) & ~3;
|
||||
unsigned size = line_size * height + 54;
|
||||
unsigned size_array = line_size * height;
|
||||
uint8_t header[54];
|
||||
|
||||
/* Generic BMP stuff. */
|
||||
|
||||
/* signature */
|
||||
header[0] = 'B';
|
||||
header[1] = 'M';
|
||||
/* file size */
|
||||
header[2] = (uint8_t)(size >> 0);
|
||||
header[3] = (uint8_t)(size >> 8);
|
||||
header[4] = (uint8_t)(size >> 16);
|
||||
header[5] = (uint8_t)(size >> 24);
|
||||
/* reserved */
|
||||
header[6] = 0;
|
||||
header[7] = 0;
|
||||
header[8] = 0;
|
||||
header[9] = 0;
|
||||
/* offset */
|
||||
header[10] = 54;
|
||||
header[11] = 0;
|
||||
header[12] = 0;
|
||||
header[13] = 0;
|
||||
/* DIB size */
|
||||
header[14] = 40;
|
||||
header[15] = 0;
|
||||
header[16] = 0;
|
||||
header[17] = 0;
|
||||
/* Width */
|
||||
header[18] = (uint8_t)(width >> 0);
|
||||
header[19] = (uint8_t)(width >> 8);
|
||||
header[20] = (uint8_t)(width >> 16);
|
||||
header[21] = (uint8_t)(width >> 24);
|
||||
/* Height */
|
||||
header[22] = (uint8_t)(height >> 0);
|
||||
header[23] = (uint8_t)(height >> 8);
|
||||
header[24] = (uint8_t)(height >> 16);
|
||||
header[25] = (uint8_t)(height >> 24);
|
||||
/* Color planes */
|
||||
header[26] = 1;
|
||||
header[27] = 0;
|
||||
/* Bits per pixel */
|
||||
header[28] = is32bpp?32:24;
|
||||
header[29] = 0;
|
||||
/* Compression method */
|
||||
header[30] = 0;
|
||||
header[31] = 0;
|
||||
header[32] = 0;
|
||||
header[33] = 0;
|
||||
/* Image data size */
|
||||
header[34] = (uint8_t)(size_array >> 0);
|
||||
header[35] = (uint8_t)(size_array >> 8);
|
||||
header[36] = (uint8_t)(size_array >> 16);
|
||||
header[37] = (uint8_t)(size_array >> 24);
|
||||
/* Horizontal resolution */
|
||||
header[38] = 19;
|
||||
header[39] = 11;
|
||||
header[40] = 0;
|
||||
header[41] = 0;
|
||||
/* Vertical resolution */
|
||||
header[42] = 19;
|
||||
header[43] = 11;
|
||||
header[44] = 0;
|
||||
header[45] = 0;
|
||||
/* Palette size */
|
||||
header[46] = 0;
|
||||
header[47] = 0;
|
||||
header[48] = 0;
|
||||
header[49] = 0;
|
||||
/* Important color count */
|
||||
header[50] = 0;
|
||||
header[51] = 0;
|
||||
header[52] = 0;
|
||||
header[53] = 0;
|
||||
|
||||
return retro_fwrite(file, header, sizeof(header)) == sizeof(header);
|
||||
}
|
||||
|
||||
static void dump_line_565_to_24(uint8_t *line, const uint16_t *src, unsigned width)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < width; i++)
|
||||
{
|
||||
uint16_t pixel = *src++;
|
||||
uint8_t b = (pixel >> 0) & 0x1f;
|
||||
uint8_t g = (pixel >> 5) & 0x3f;
|
||||
uint8_t r = (pixel >> 11) & 0x1f;
|
||||
*line++ = (b << 3) | (b >> 2);
|
||||
*line++ = (g << 2) | (g >> 4);
|
||||
*line++ = (r << 3) | (r >> 2);
|
||||
}
|
||||
}
|
||||
|
||||
static void dump_line_32_to_24(uint8_t *line, const uint32_t *src, unsigned width)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < width; i++)
|
||||
{
|
||||
uint32_t pixel = *src++;
|
||||
*line++ = (pixel >> 0) & 0xff;
|
||||
*line++ = (pixel >> 8) & 0xff;
|
||||
*line++ = (pixel >> 16) & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
static void dump_content(RFILE *file, const void *frame,
|
||||
int width, int height, int pitch, rbmp_source_type type)
|
||||
{
|
||||
uint8_t *line;
|
||||
size_t line_size;
|
||||
int i, j;
|
||||
int bytes_per_pixel = (type==RBMP_SOURCE_TYPE_ARGB8888?4:3);
|
||||
union
|
||||
{
|
||||
const uint8_t *u8;
|
||||
const uint16_t *u16;
|
||||
const uint32_t *u32;
|
||||
} u;
|
||||
|
||||
u.u8 = (const uint8_t*)frame + (height-1) * pitch;
|
||||
line_size = (width * bytes_per_pixel + 3) & ~3;
|
||||
|
||||
if (type == RBMP_SOURCE_TYPE_BGR24)
|
||||
{
|
||||
/* BGR24 byte order input matches output. Can directly copy, but... need to make sure we pad it. */
|
||||
uint32_t zeros = 0;
|
||||
int pad = line_size-pitch;
|
||||
for (j = height-1; j >= 0; j--, u.u8 -= pitch)
|
||||
{
|
||||
retro_fwrite(file, u.u8, pitch);
|
||||
if(pad != 0) retro_fwrite(file, &zeros, pad);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if(type == RBMP_SOURCE_TYPE_ARGB8888)
|
||||
{
|
||||
/* ARGB8888 byte order input matches output. Can directly copy. */
|
||||
for (j = height-1; j >= 0; j--, u.u8 -= pitch)
|
||||
{
|
||||
retro_fwrite(file, u.u8, line_size);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* allocate line buffer, and initialize the final four bytes to zero, for deterministic padding */
|
||||
line = (uint8_t*)malloc(line_size);
|
||||
if (!line) return;
|
||||
*(uint32_t*)(line + line_size - 4) = 0;
|
||||
|
||||
if (type == RBMP_SOURCE_TYPE_XRGB888)
|
||||
{
|
||||
for (j = height-1; j >= 0; j--, u.u8 -= pitch)
|
||||
{
|
||||
dump_line_32_to_24(line, u.u32, width);
|
||||
retro_fwrite(file, line, line_size);
|
||||
}
|
||||
}
|
||||
else /* type == RBMP_SOURCE_TYPE_RGB565 */
|
||||
{
|
||||
for (j = height-1; j >= 0; j--, u.u8 -= pitch)
|
||||
{
|
||||
dump_line_565_to_24(line, u.u16, width);
|
||||
retro_fwrite(file, line, line_size);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool rbmp_save_image(const char *filename, const void *frame,
|
||||
unsigned width, unsigned height,
|
||||
unsigned pitch, rbmp_source_type type)
|
||||
{
|
||||
bool ret;
|
||||
RFILE *file = retro_fopen(filename, RFILE_MODE_WRITE, -1);
|
||||
if (!file)
|
||||
return false;
|
||||
|
||||
ret = write_header_bmp(file, width, height, type==RBMP_SOURCE_TYPE_ARGB8888);
|
||||
|
||||
if (ret)
|
||||
dump_content(file, frame, width, height, pitch, type);
|
||||
|
||||
retro_fclose(file);
|
||||
|
||||
return ret;
|
||||
}
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (rbmp_encode.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <retro_file.h>
|
||||
#include <formats/rbmp.h>
|
||||
|
||||
static bool write_header_bmp(RFILE *file, unsigned width, unsigned height, bool is32bpp)
|
||||
{
|
||||
unsigned line_size = (width * (is32bpp?4:3) + 3) & ~3;
|
||||
unsigned size = line_size * height + 54;
|
||||
unsigned size_array = line_size * height;
|
||||
uint8_t header[54];
|
||||
|
||||
/* Generic BMP stuff. */
|
||||
|
||||
/* signature */
|
||||
header[0] = 'B';
|
||||
header[1] = 'M';
|
||||
/* file size */
|
||||
header[2] = (uint8_t)(size >> 0);
|
||||
header[3] = (uint8_t)(size >> 8);
|
||||
header[4] = (uint8_t)(size >> 16);
|
||||
header[5] = (uint8_t)(size >> 24);
|
||||
/* reserved */
|
||||
header[6] = 0;
|
||||
header[7] = 0;
|
||||
header[8] = 0;
|
||||
header[9] = 0;
|
||||
/* offset */
|
||||
header[10] = 54;
|
||||
header[11] = 0;
|
||||
header[12] = 0;
|
||||
header[13] = 0;
|
||||
/* DIB size */
|
||||
header[14] = 40;
|
||||
header[15] = 0;
|
||||
header[16] = 0;
|
||||
header[17] = 0;
|
||||
/* Width */
|
||||
header[18] = (uint8_t)(width >> 0);
|
||||
header[19] = (uint8_t)(width >> 8);
|
||||
header[20] = (uint8_t)(width >> 16);
|
||||
header[21] = (uint8_t)(width >> 24);
|
||||
/* Height */
|
||||
header[22] = (uint8_t)(height >> 0);
|
||||
header[23] = (uint8_t)(height >> 8);
|
||||
header[24] = (uint8_t)(height >> 16);
|
||||
header[25] = (uint8_t)(height >> 24);
|
||||
/* Color planes */
|
||||
header[26] = 1;
|
||||
header[27] = 0;
|
||||
/* Bits per pixel */
|
||||
header[28] = is32bpp?32:24;
|
||||
header[29] = 0;
|
||||
/* Compression method */
|
||||
header[30] = 0;
|
||||
header[31] = 0;
|
||||
header[32] = 0;
|
||||
header[33] = 0;
|
||||
/* Image data size */
|
||||
header[34] = (uint8_t)(size_array >> 0);
|
||||
header[35] = (uint8_t)(size_array >> 8);
|
||||
header[36] = (uint8_t)(size_array >> 16);
|
||||
header[37] = (uint8_t)(size_array >> 24);
|
||||
/* Horizontal resolution */
|
||||
header[38] = 19;
|
||||
header[39] = 11;
|
||||
header[40] = 0;
|
||||
header[41] = 0;
|
||||
/* Vertical resolution */
|
||||
header[42] = 19;
|
||||
header[43] = 11;
|
||||
header[44] = 0;
|
||||
header[45] = 0;
|
||||
/* Palette size */
|
||||
header[46] = 0;
|
||||
header[47] = 0;
|
||||
header[48] = 0;
|
||||
header[49] = 0;
|
||||
/* Important color count */
|
||||
header[50] = 0;
|
||||
header[51] = 0;
|
||||
header[52] = 0;
|
||||
header[53] = 0;
|
||||
|
||||
return retro_fwrite(file, header, sizeof(header)) == sizeof(header);
|
||||
}
|
||||
|
||||
static void dump_line_565_to_24(uint8_t *line, const uint16_t *src, unsigned width)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < width; i++)
|
||||
{
|
||||
uint16_t pixel = *src++;
|
||||
uint8_t b = (pixel >> 0) & 0x1f;
|
||||
uint8_t g = (pixel >> 5) & 0x3f;
|
||||
uint8_t r = (pixel >> 11) & 0x1f;
|
||||
*line++ = (b << 3) | (b >> 2);
|
||||
*line++ = (g << 2) | (g >> 4);
|
||||
*line++ = (r << 3) | (r >> 2);
|
||||
}
|
||||
}
|
||||
|
||||
static void dump_line_32_to_24(uint8_t *line, const uint32_t *src, unsigned width)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < width; i++)
|
||||
{
|
||||
uint32_t pixel = *src++;
|
||||
*line++ = (pixel >> 0) & 0xff;
|
||||
*line++ = (pixel >> 8) & 0xff;
|
||||
*line++ = (pixel >> 16) & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
static void dump_content(RFILE *file, const void *frame,
|
||||
int width, int height, int pitch, rbmp_source_type type)
|
||||
{
|
||||
uint8_t *line;
|
||||
size_t line_size;
|
||||
int i, j;
|
||||
int bytes_per_pixel = (type==RBMP_SOURCE_TYPE_ARGB8888?4:3);
|
||||
union
|
||||
{
|
||||
const uint8_t *u8;
|
||||
const uint16_t *u16;
|
||||
const uint32_t *u32;
|
||||
} u;
|
||||
|
||||
u.u8 = (const uint8_t*)frame + (height-1) * pitch;
|
||||
line_size = (width * bytes_per_pixel + 3) & ~3;
|
||||
|
||||
if (type == RBMP_SOURCE_TYPE_BGR24)
|
||||
{
|
||||
/* BGR24 byte order input matches output. Can directly copy, but... need to make sure we pad it. */
|
||||
uint32_t zeros = 0;
|
||||
int pad = line_size-pitch;
|
||||
for (j = height-1; j >= 0; j--, u.u8 -= pitch)
|
||||
{
|
||||
retro_fwrite(file, u.u8, pitch);
|
||||
if(pad != 0) retro_fwrite(file, &zeros, pad);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if(type == RBMP_SOURCE_TYPE_ARGB8888)
|
||||
{
|
||||
/* ARGB8888 byte order input matches output. Can directly copy. */
|
||||
for (j = height-1; j >= 0; j--, u.u8 -= pitch)
|
||||
{
|
||||
retro_fwrite(file, u.u8, line_size);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* allocate line buffer, and initialize the final four bytes to zero, for deterministic padding */
|
||||
line = (uint8_t*)malloc(line_size);
|
||||
if (!line) return;
|
||||
*(uint32_t*)(line + line_size - 4) = 0;
|
||||
|
||||
if (type == RBMP_SOURCE_TYPE_XRGB888)
|
||||
{
|
||||
for (j = height-1; j >= 0; j--, u.u8 -= pitch)
|
||||
{
|
||||
dump_line_32_to_24(line, u.u32, width);
|
||||
retro_fwrite(file, line, line_size);
|
||||
}
|
||||
}
|
||||
else /* type == RBMP_SOURCE_TYPE_RGB565 */
|
||||
{
|
||||
for (j = height-1; j >= 0; j--, u.u8 -= pitch)
|
||||
{
|
||||
dump_line_565_to_24(line, u.u16, width);
|
||||
retro_fwrite(file, line, line_size);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool rbmp_save_image(const char *filename, const void *frame,
|
||||
unsigned width, unsigned height,
|
||||
unsigned pitch, rbmp_source_type type)
|
||||
{
|
||||
bool ret;
|
||||
RFILE *file = retro_fopen(filename, RFILE_MODE_WRITE, -1);
|
||||
if (!file)
|
||||
return false;
|
||||
|
||||
ret = write_header_bmp(file, width, height, type==RBMP_SOURCE_TYPE_ARGB8888);
|
||||
|
||||
if (ret)
|
||||
dump_content(file, frame, width, height, pitch, type);
|
||||
|
||||
retro_fclose(file);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1,316 +1,316 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (jsonsax.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <retro_inline.h>
|
||||
#include <formats/jsonsax.h>
|
||||
|
||||
#ifdef JSONSAX_ERRORS
|
||||
const char* jsonsax_errors[] =
|
||||
{
|
||||
"Ok",
|
||||
"Interrupted",
|
||||
"Missing key",
|
||||
"Unterminated key",
|
||||
"Missing value",
|
||||
"Unterminated object",
|
||||
"Unterminated array",
|
||||
"Unterminated string",
|
||||
"Invalid value"
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const jsonsax_handlers_t* handlers;
|
||||
|
||||
const char* json;
|
||||
void* ud;
|
||||
jmp_buf env;
|
||||
}
|
||||
state_t;
|
||||
|
||||
static INLINE void skip_spaces( state_t* state )
|
||||
{
|
||||
while ( isspace( *state->json ) )
|
||||
state->json++;
|
||||
}
|
||||
|
||||
static INLINE void skip_digits( state_t* state )
|
||||
{
|
||||
while ( isdigit( *state->json ) )
|
||||
state->json++;
|
||||
}
|
||||
|
||||
#define HANDLE_0( event ) \
|
||||
do { \
|
||||
if ( state->handlers->event && state->handlers->event( state->ud ) ) \
|
||||
longjmp( state->env, JSONSAX_INTERRUPTED ); \
|
||||
} while ( 0 )
|
||||
|
||||
#define HANDLE_1( event, arg1 ) \
|
||||
do { \
|
||||
if ( state->handlers->event && state->handlers->event( state->ud, arg1 ) ) \
|
||||
longjmp( state->env, JSONSAX_INTERRUPTED ); \
|
||||
} while ( 0 )
|
||||
|
||||
#define HANDLE_2( event, arg1, arg2 ) \
|
||||
do { \
|
||||
if ( state->handlers->event && state->handlers->event( state->ud, arg1, arg2 ) ) \
|
||||
longjmp( state->env, JSONSAX_INTERRUPTED ); \
|
||||
} while ( 0 )
|
||||
|
||||
static void jsonx_parse_value(state_t* state);
|
||||
|
||||
static void jsonx_parse_object( state_t* state )
|
||||
{
|
||||
state->json++; /* we're sure the current character is a '{' */
|
||||
skip_spaces( state );
|
||||
HANDLE_0( start_object );
|
||||
|
||||
while ( *state->json != '}' )
|
||||
{
|
||||
const char *name = NULL;
|
||||
if ( *state->json != '"' )
|
||||
longjmp( state->env, JSONSAX_MISSING_KEY );
|
||||
|
||||
name = ++state->json;
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
const char* quote = strchr( state->json, '"' );
|
||||
|
||||
if ( !quote )
|
||||
longjmp( state->env, JSONSAX_UNTERMINATED_KEY );
|
||||
|
||||
state->json = quote + 1;
|
||||
|
||||
if ( quote[ -1 ] != '\\' )
|
||||
break;
|
||||
}
|
||||
|
||||
HANDLE_2( key, name, state->json - name - 1 );
|
||||
skip_spaces( state );
|
||||
|
||||
if ( *state->json != ':' )
|
||||
longjmp( state->env, JSONSAX_MISSING_VALUE );
|
||||
|
||||
state->json++;
|
||||
skip_spaces( state );
|
||||
jsonx_parse_value( state );
|
||||
skip_spaces( state );
|
||||
|
||||
if ( *state->json != ',' )
|
||||
break;
|
||||
|
||||
state->json++;
|
||||
skip_spaces( state );
|
||||
}
|
||||
|
||||
if ( *state->json != '}' )
|
||||
longjmp( state->env, JSONSAX_UNTERMINATED_OBJECT );
|
||||
|
||||
state->json++;
|
||||
HANDLE_0( end_object );
|
||||
}
|
||||
|
||||
static void jsonx_parse_array(state_t* state)
|
||||
{
|
||||
unsigned int ndx = 0;
|
||||
|
||||
state->json++; /* we're sure the current character is a '[' */
|
||||
skip_spaces( state );
|
||||
HANDLE_0( start_array );
|
||||
|
||||
while ( *state->json != ']' )
|
||||
{
|
||||
HANDLE_1( index, ndx++ );
|
||||
jsonx_parse_value( state );
|
||||
skip_spaces( state );
|
||||
|
||||
if ( *state->json != ',' )
|
||||
break;
|
||||
|
||||
state->json++;
|
||||
skip_spaces( state );
|
||||
}
|
||||
|
||||
if ( *state->json != ']' )
|
||||
longjmp( state->env, JSONSAX_UNTERMINATED_ARRAY );
|
||||
|
||||
state->json++;
|
||||
HANDLE_0( end_array );
|
||||
}
|
||||
|
||||
static void jsonx_parse_string(state_t* state)
|
||||
{
|
||||
const char* string = ++state->json;
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
const char* quote = strchr( state->json, '"' );
|
||||
|
||||
if ( !quote )
|
||||
longjmp( state->env, JSONSAX_UNTERMINATED_STRING );
|
||||
|
||||
state->json = quote + 1;
|
||||
|
||||
if ( quote[ -1 ] != '\\' )
|
||||
break;
|
||||
}
|
||||
|
||||
HANDLE_2( string, string, state->json - string - 1 );
|
||||
}
|
||||
|
||||
static void jsonx_parse_boolean(state_t* state)
|
||||
{
|
||||
if ( !strncmp( state->json, "true", 4 ) )
|
||||
{
|
||||
state->json += 4;
|
||||
HANDLE_1( boolean, 1 );
|
||||
}
|
||||
else if ( !strncmp( state->json, "false", 5 ) )
|
||||
{
|
||||
state->json += 5;
|
||||
HANDLE_1( boolean, 0 );
|
||||
}
|
||||
else
|
||||
longjmp( state->env, JSONSAX_INVALID_VALUE );
|
||||
}
|
||||
|
||||
static void jsonx_parse_null(state_t* state)
|
||||
{
|
||||
if ( !strncmp( state->json + 1, "ull", 3 ) ) /* we're sure the current character is a 'n' */
|
||||
{
|
||||
state->json += 4;
|
||||
HANDLE_0( null );
|
||||
}
|
||||
else
|
||||
longjmp( state->env, JSONSAX_INVALID_VALUE );
|
||||
}
|
||||
|
||||
static void jsonx_parse_number(state_t* state)
|
||||
{
|
||||
const char* number = state->json;
|
||||
|
||||
if ( *state->json == '-' )
|
||||
state->json++;
|
||||
|
||||
if ( !isdigit( *state->json ) )
|
||||
longjmp( state->env, JSONSAX_INVALID_VALUE );
|
||||
|
||||
skip_digits( state );
|
||||
|
||||
if ( *state->json == '.' )
|
||||
{
|
||||
state->json++;
|
||||
|
||||
if ( !isdigit( *state->json ) )
|
||||
longjmp( state->env, JSONSAX_INVALID_VALUE );
|
||||
|
||||
skip_digits( state );
|
||||
}
|
||||
|
||||
if ( *state->json == 'e' || *state->json == 'E' )
|
||||
{
|
||||
state->json++;
|
||||
|
||||
if ( *state->json == '-' || *state->json == '+' )
|
||||
state->json++;
|
||||
|
||||
if ( !isdigit( *state->json ) )
|
||||
longjmp( state->env, JSONSAX_INVALID_VALUE );
|
||||
|
||||
skip_digits( state );
|
||||
}
|
||||
|
||||
HANDLE_2( number, number, state->json - number );
|
||||
}
|
||||
|
||||
static void jsonx_parse_value(state_t* state)
|
||||
{
|
||||
skip_spaces( state );
|
||||
|
||||
switch ( *state->json )
|
||||
{
|
||||
case '{':
|
||||
jsonx_parse_object(state);
|
||||
break;
|
||||
case '[':
|
||||
jsonx_parse_array( state );
|
||||
break;
|
||||
case '"':
|
||||
jsonx_parse_string( state );
|
||||
break;
|
||||
case 't':
|
||||
case 'f':
|
||||
jsonx_parse_boolean( state );
|
||||
break;
|
||||
case 'n':
|
||||
jsonx_parse_null( state );
|
||||
break;
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
case '-':
|
||||
jsonx_parse_number( state );
|
||||
break;
|
||||
|
||||
default:
|
||||
longjmp( state->env, JSONSAX_INVALID_VALUE );
|
||||
}
|
||||
}
|
||||
|
||||
int jsonsax_parse( const char* json, const jsonsax_handlers_t* handlers, void* userdata )
|
||||
{
|
||||
state_t state;
|
||||
int res;
|
||||
|
||||
state.json = json;
|
||||
state.handlers = handlers;
|
||||
state.ud = userdata;
|
||||
|
||||
if ( ( res = setjmp( state.env ) ) == 0 )
|
||||
{
|
||||
if ( handlers->start_document )
|
||||
handlers->start_document( userdata );
|
||||
|
||||
jsonx_parse_value(&state);
|
||||
|
||||
if ( handlers->end_document )
|
||||
handlers->end_document( userdata );
|
||||
|
||||
res = JSONSAX_OK;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (jsonsax.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <retro_inline.h>
|
||||
#include <formats/jsonsax.h>
|
||||
|
||||
#ifdef JSONSAX_ERRORS
|
||||
const char* jsonsax_errors[] =
|
||||
{
|
||||
"Ok",
|
||||
"Interrupted",
|
||||
"Missing key",
|
||||
"Unterminated key",
|
||||
"Missing value",
|
||||
"Unterminated object",
|
||||
"Unterminated array",
|
||||
"Unterminated string",
|
||||
"Invalid value"
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const jsonsax_handlers_t* handlers;
|
||||
|
||||
const char* json;
|
||||
void* ud;
|
||||
jmp_buf env;
|
||||
}
|
||||
state_t;
|
||||
|
||||
static INLINE void skip_spaces( state_t* state )
|
||||
{
|
||||
while ( isspace( *state->json ) )
|
||||
state->json++;
|
||||
}
|
||||
|
||||
static INLINE void skip_digits( state_t* state )
|
||||
{
|
||||
while ( isdigit( *state->json ) )
|
||||
state->json++;
|
||||
}
|
||||
|
||||
#define HANDLE_0( event ) \
|
||||
do { \
|
||||
if ( state->handlers->event && state->handlers->event( state->ud ) ) \
|
||||
longjmp( state->env, JSONSAX_INTERRUPTED ); \
|
||||
} while ( 0 )
|
||||
|
||||
#define HANDLE_1( event, arg1 ) \
|
||||
do { \
|
||||
if ( state->handlers->event && state->handlers->event( state->ud, arg1 ) ) \
|
||||
longjmp( state->env, JSONSAX_INTERRUPTED ); \
|
||||
} while ( 0 )
|
||||
|
||||
#define HANDLE_2( event, arg1, arg2 ) \
|
||||
do { \
|
||||
if ( state->handlers->event && state->handlers->event( state->ud, arg1, arg2 ) ) \
|
||||
longjmp( state->env, JSONSAX_INTERRUPTED ); \
|
||||
} while ( 0 )
|
||||
|
||||
static void jsonx_parse_value(state_t* state);
|
||||
|
||||
static void jsonx_parse_object( state_t* state )
|
||||
{
|
||||
state->json++; /* we're sure the current character is a '{' */
|
||||
skip_spaces( state );
|
||||
HANDLE_0( start_object );
|
||||
|
||||
while ( *state->json != '}' )
|
||||
{
|
||||
const char *name = NULL;
|
||||
if ( *state->json != '"' )
|
||||
longjmp( state->env, JSONSAX_MISSING_KEY );
|
||||
|
||||
name = ++state->json;
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
const char* quote = strchr( state->json, '"' );
|
||||
|
||||
if ( !quote )
|
||||
longjmp( state->env, JSONSAX_UNTERMINATED_KEY );
|
||||
|
||||
state->json = quote + 1;
|
||||
|
||||
if ( quote[ -1 ] != '\\' )
|
||||
break;
|
||||
}
|
||||
|
||||
HANDLE_2( key, name, state->json - name - 1 );
|
||||
skip_spaces( state );
|
||||
|
||||
if ( *state->json != ':' )
|
||||
longjmp( state->env, JSONSAX_MISSING_VALUE );
|
||||
|
||||
state->json++;
|
||||
skip_spaces( state );
|
||||
jsonx_parse_value( state );
|
||||
skip_spaces( state );
|
||||
|
||||
if ( *state->json != ',' )
|
||||
break;
|
||||
|
||||
state->json++;
|
||||
skip_spaces( state );
|
||||
}
|
||||
|
||||
if ( *state->json != '}' )
|
||||
longjmp( state->env, JSONSAX_UNTERMINATED_OBJECT );
|
||||
|
||||
state->json++;
|
||||
HANDLE_0( end_object );
|
||||
}
|
||||
|
||||
static void jsonx_parse_array(state_t* state)
|
||||
{
|
||||
unsigned int ndx = 0;
|
||||
|
||||
state->json++; /* we're sure the current character is a '[' */
|
||||
skip_spaces( state );
|
||||
HANDLE_0( start_array );
|
||||
|
||||
while ( *state->json != ']' )
|
||||
{
|
||||
HANDLE_1( index, ndx++ );
|
||||
jsonx_parse_value( state );
|
||||
skip_spaces( state );
|
||||
|
||||
if ( *state->json != ',' )
|
||||
break;
|
||||
|
||||
state->json++;
|
||||
skip_spaces( state );
|
||||
}
|
||||
|
||||
if ( *state->json != ']' )
|
||||
longjmp( state->env, JSONSAX_UNTERMINATED_ARRAY );
|
||||
|
||||
state->json++;
|
||||
HANDLE_0( end_array );
|
||||
}
|
||||
|
||||
static void jsonx_parse_string(state_t* state)
|
||||
{
|
||||
const char* string = ++state->json;
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
const char* quote = strchr( state->json, '"' );
|
||||
|
||||
if ( !quote )
|
||||
longjmp( state->env, JSONSAX_UNTERMINATED_STRING );
|
||||
|
||||
state->json = quote + 1;
|
||||
|
||||
if ( quote[ -1 ] != '\\' )
|
||||
break;
|
||||
}
|
||||
|
||||
HANDLE_2( string, string, state->json - string - 1 );
|
||||
}
|
||||
|
||||
static void jsonx_parse_boolean(state_t* state)
|
||||
{
|
||||
if ( !strncmp( state->json, "true", 4 ) )
|
||||
{
|
||||
state->json += 4;
|
||||
HANDLE_1( boolean, 1 );
|
||||
}
|
||||
else if ( !strncmp( state->json, "false", 5 ) )
|
||||
{
|
||||
state->json += 5;
|
||||
HANDLE_1( boolean, 0 );
|
||||
}
|
||||
else
|
||||
longjmp( state->env, JSONSAX_INVALID_VALUE );
|
||||
}
|
||||
|
||||
static void jsonx_parse_null(state_t* state)
|
||||
{
|
||||
if ( !strncmp( state->json + 1, "ull", 3 ) ) /* we're sure the current character is a 'n' */
|
||||
{
|
||||
state->json += 4;
|
||||
HANDLE_0( null );
|
||||
}
|
||||
else
|
||||
longjmp( state->env, JSONSAX_INVALID_VALUE );
|
||||
}
|
||||
|
||||
static void jsonx_parse_number(state_t* state)
|
||||
{
|
||||
const char* number = state->json;
|
||||
|
||||
if ( *state->json == '-' )
|
||||
state->json++;
|
||||
|
||||
if ( !isdigit( *state->json ) )
|
||||
longjmp( state->env, JSONSAX_INVALID_VALUE );
|
||||
|
||||
skip_digits( state );
|
||||
|
||||
if ( *state->json == '.' )
|
||||
{
|
||||
state->json++;
|
||||
|
||||
if ( !isdigit( *state->json ) )
|
||||
longjmp( state->env, JSONSAX_INVALID_VALUE );
|
||||
|
||||
skip_digits( state );
|
||||
}
|
||||
|
||||
if ( *state->json == 'e' || *state->json == 'E' )
|
||||
{
|
||||
state->json++;
|
||||
|
||||
if ( *state->json == '-' || *state->json == '+' )
|
||||
state->json++;
|
||||
|
||||
if ( !isdigit( *state->json ) )
|
||||
longjmp( state->env, JSONSAX_INVALID_VALUE );
|
||||
|
||||
skip_digits( state );
|
||||
}
|
||||
|
||||
HANDLE_2( number, number, state->json - number );
|
||||
}
|
||||
|
||||
static void jsonx_parse_value(state_t* state)
|
||||
{
|
||||
skip_spaces( state );
|
||||
|
||||
switch ( *state->json )
|
||||
{
|
||||
case '{':
|
||||
jsonx_parse_object(state);
|
||||
break;
|
||||
case '[':
|
||||
jsonx_parse_array( state );
|
||||
break;
|
||||
case '"':
|
||||
jsonx_parse_string( state );
|
||||
break;
|
||||
case 't':
|
||||
case 'f':
|
||||
jsonx_parse_boolean( state );
|
||||
break;
|
||||
case 'n':
|
||||
jsonx_parse_null( state );
|
||||
break;
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
case '-':
|
||||
jsonx_parse_number( state );
|
||||
break;
|
||||
|
||||
default:
|
||||
longjmp( state->env, JSONSAX_INVALID_VALUE );
|
||||
}
|
||||
}
|
||||
|
||||
int jsonsax_parse( const char* json, const jsonsax_handlers_t* handlers, void* userdata )
|
||||
{
|
||||
state_t state;
|
||||
int res;
|
||||
|
||||
state.json = json;
|
||||
state.handlers = handlers;
|
||||
state.ud = userdata;
|
||||
|
||||
if ( ( res = setjmp( state.env ) ) == 0 )
|
||||
{
|
||||
if ( handlers->start_document )
|
||||
handlers->start_document( userdata );
|
||||
|
||||
jsonx_parse_value(&state);
|
||||
|
||||
if ( handlers->end_document )
|
||||
handlers->end_document( userdata );
|
||||
|
||||
res = JSONSAX_OK;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,387 +1,387 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (rpng.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <retro_file.h>
|
||||
|
||||
#include "rpng_internal.h"
|
||||
|
||||
#undef GOTO_END_ERROR
|
||||
#define GOTO_END_ERROR() do { \
|
||||
fprintf(stderr, "[RPNG]: Error in line %d.\n", __LINE__); \
|
||||
ret = false; \
|
||||
goto end; \
|
||||
} while(0)
|
||||
|
||||
#ifdef HAVE_ZLIB_DEFLATE
|
||||
|
||||
static void dword_write_be(uint8_t *buf, uint32_t val)
|
||||
{
|
||||
*buf++ = (uint8_t)(val >> 24);
|
||||
*buf++ = (uint8_t)(val >> 16);
|
||||
*buf++ = (uint8_t)(val >> 8);
|
||||
*buf++ = (uint8_t)(val >> 0);
|
||||
}
|
||||
|
||||
static bool png_write_crc(RFILE *file, const uint8_t *data, size_t size)
|
||||
{
|
||||
uint8_t crc_raw[4] = {0};
|
||||
const struct file_archive_file_backend *stream_backend =
|
||||
file_archive_get_default_file_backend();
|
||||
uint32_t crc = stream_backend->stream_crc_calculate(0, data, size);
|
||||
|
||||
dword_write_be(crc_raw, crc);
|
||||
return retro_fwrite(file, crc_raw, sizeof(crc_raw)) == sizeof(crc_raw);
|
||||
}
|
||||
|
||||
static bool png_write_ihdr(RFILE *file, const struct png_ihdr *ihdr)
|
||||
{
|
||||
uint8_t ihdr_raw[21];
|
||||
|
||||
ihdr_raw[0] = '0'; /* Size */
|
||||
ihdr_raw[1] = '0';
|
||||
ihdr_raw[2] = '0';
|
||||
ihdr_raw[3] = '0';
|
||||
ihdr_raw[4] = 'I';
|
||||
ihdr_raw[5] = 'H';
|
||||
ihdr_raw[6] = 'D';
|
||||
ihdr_raw[7] = 'R';
|
||||
ihdr_raw[8] = 0; /* Width */
|
||||
ihdr_raw[9] = 0;
|
||||
ihdr_raw[10] = 0;
|
||||
ihdr_raw[11] = 0;
|
||||
ihdr_raw[12] = 0; /* Height */
|
||||
ihdr_raw[13] = 0;
|
||||
ihdr_raw[14] = 0;
|
||||
ihdr_raw[15] = 0;
|
||||
ihdr_raw[16] = ihdr->depth; /* Depth */
|
||||
ihdr_raw[17] = ihdr->color_type;
|
||||
ihdr_raw[18] = ihdr->compression;
|
||||
ihdr_raw[19] = ihdr->filter;
|
||||
ihdr_raw[20] = ihdr->interlace;
|
||||
|
||||
dword_write_be(ihdr_raw + 0, sizeof(ihdr_raw) - 8);
|
||||
dword_write_be(ihdr_raw + 8, ihdr->width);
|
||||
dword_write_be(ihdr_raw + 12, ihdr->height);
|
||||
if (retro_fwrite(file, ihdr_raw, sizeof(ihdr_raw)) != sizeof(ihdr_raw))
|
||||
return false;
|
||||
|
||||
if (!png_write_crc(file, ihdr_raw + sizeof(uint32_t),
|
||||
sizeof(ihdr_raw) - sizeof(uint32_t)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool png_write_idat(RFILE *file, const uint8_t *data, size_t size)
|
||||
{
|
||||
if (retro_fwrite(file, data, size) != (ssize_t)size)
|
||||
return false;
|
||||
|
||||
if (!png_write_crc(file, data + sizeof(uint32_t), size - sizeof(uint32_t)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool png_write_iend(RFILE *file)
|
||||
{
|
||||
const uint8_t data[] = {
|
||||
0, 0, 0, 0,
|
||||
'I', 'E', 'N', 'D',
|
||||
};
|
||||
|
||||
if (retro_fwrite(file, data, sizeof(data)) != sizeof(data))
|
||||
return false;
|
||||
|
||||
if (!png_write_crc(file, data + sizeof(uint32_t),
|
||||
sizeof(data) - sizeof(uint32_t)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void copy_argb_line(uint8_t *dst, const uint32_t *src, unsigned width)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < width; i++)
|
||||
{
|
||||
uint32_t col = src[i];
|
||||
*dst++ = (uint8_t)(col >> 16);
|
||||
*dst++ = (uint8_t)(col >> 8);
|
||||
*dst++ = (uint8_t)(col >> 0);
|
||||
*dst++ = (uint8_t)(col >> 24);
|
||||
}
|
||||
}
|
||||
|
||||
static void copy_bgr24_line(uint8_t *dst, const uint8_t *src, unsigned width)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < width; i++, dst += 3, src += 3)
|
||||
{
|
||||
dst[2] = src[0];
|
||||
dst[1] = src[1];
|
||||
dst[0] = src[2];
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned count_sad(const uint8_t *data, size_t size)
|
||||
{
|
||||
size_t i;
|
||||
unsigned cnt = 0;
|
||||
for (i = 0; i < size; i++)
|
||||
cnt += abs((int8_t)data[i]);
|
||||
return cnt;
|
||||
}
|
||||
|
||||
static unsigned filter_up(uint8_t *target, const uint8_t *line,
|
||||
const uint8_t *prev, unsigned width, unsigned bpp)
|
||||
{
|
||||
unsigned i;
|
||||
width *= bpp;
|
||||
for (i = 0; i < width; i++)
|
||||
target[i] = line[i] - prev[i];
|
||||
|
||||
return count_sad(target, width);
|
||||
}
|
||||
|
||||
static unsigned filter_sub(uint8_t *target, const uint8_t *line,
|
||||
unsigned width, unsigned bpp)
|
||||
{
|
||||
unsigned i;
|
||||
width *= bpp;
|
||||
for (i = 0; i < bpp; i++)
|
||||
target[i] = line[i];
|
||||
for (i = bpp; i < width; i++)
|
||||
target[i] = line[i] - line[i - bpp];
|
||||
|
||||
return count_sad(target, width);
|
||||
}
|
||||
|
||||
static unsigned filter_avg(uint8_t *target, const uint8_t *line,
|
||||
const uint8_t *prev, unsigned width, unsigned bpp)
|
||||
{
|
||||
unsigned i;
|
||||
width *= bpp;
|
||||
for (i = 0; i < bpp; i++)
|
||||
target[i] = line[i] - (prev[i] >> 1);
|
||||
for (i = bpp; i < width; i++)
|
||||
target[i] = line[i] - ((line[i - bpp] + prev[i]) >> 1);
|
||||
|
||||
return count_sad(target, width);
|
||||
}
|
||||
|
||||
static unsigned filter_paeth(uint8_t *target,
|
||||
const uint8_t *line, const uint8_t *prev,
|
||||
unsigned width, unsigned bpp)
|
||||
{
|
||||
unsigned i;
|
||||
width *= bpp;
|
||||
for (i = 0; i < bpp; i++)
|
||||
target[i] = line[i] - paeth(0, prev[i], 0);
|
||||
for (i = bpp; i < width; i++)
|
||||
target[i] = line[i] - paeth(line[i - bpp], prev[i], prev[i - bpp]);
|
||||
|
||||
return count_sad(target, width);
|
||||
}
|
||||
|
||||
static bool rpng_save_image(const char *path,
|
||||
const uint8_t *data,
|
||||
unsigned width, unsigned height, unsigned pitch, unsigned bpp)
|
||||
{
|
||||
unsigned h;
|
||||
bool ret = true;
|
||||
struct png_ihdr ihdr = {0};
|
||||
|
||||
const struct file_archive_file_backend *stream_backend = NULL;
|
||||
size_t encode_buf_size = 0;
|
||||
uint8_t *encode_buf = NULL;
|
||||
uint8_t *deflate_buf = NULL;
|
||||
uint8_t *rgba_line = NULL;
|
||||
uint8_t *up_filtered = NULL;
|
||||
uint8_t *sub_filtered = NULL;
|
||||
uint8_t *avg_filtered = NULL;
|
||||
uint8_t *paeth_filtered = NULL;
|
||||
uint8_t *prev_encoded = NULL;
|
||||
uint8_t *encode_target = NULL;
|
||||
void *stream = NULL;
|
||||
RFILE *file = retro_fopen(path, RFILE_MODE_WRITE, -1);
|
||||
if (!file)
|
||||
GOTO_END_ERROR();
|
||||
|
||||
stream_backend = file_archive_get_default_file_backend();
|
||||
|
||||
if (retro_fwrite(file, png_magic, sizeof(png_magic)) != sizeof(png_magic))
|
||||
GOTO_END_ERROR();
|
||||
|
||||
ihdr.width = width;
|
||||
ihdr.height = height;
|
||||
ihdr.depth = 8;
|
||||
ihdr.color_type = bpp == sizeof(uint32_t) ? 6 : 2; /* RGBA or RGB */
|
||||
if (!png_write_ihdr(file, &ihdr))
|
||||
GOTO_END_ERROR();
|
||||
|
||||
encode_buf_size = (width * bpp + 1) * height;
|
||||
encode_buf = (uint8_t*)malloc(encode_buf_size);
|
||||
if (!encode_buf)
|
||||
GOTO_END_ERROR();
|
||||
|
||||
prev_encoded = (uint8_t*)calloc(1, width * bpp);
|
||||
if (!prev_encoded)
|
||||
GOTO_END_ERROR();
|
||||
|
||||
rgba_line = (uint8_t*)malloc(width * bpp);
|
||||
up_filtered = (uint8_t*)malloc(width * bpp);
|
||||
sub_filtered = (uint8_t*)malloc(width * bpp);
|
||||
avg_filtered = (uint8_t*)malloc(width * bpp);
|
||||
paeth_filtered = (uint8_t*)malloc(width * bpp);
|
||||
if (!rgba_line || !up_filtered || !sub_filtered || !avg_filtered || !paeth_filtered)
|
||||
GOTO_END_ERROR();
|
||||
|
||||
encode_target = encode_buf;
|
||||
for (h = 0; h < height;
|
||||
h++, encode_target += width * bpp, data += pitch)
|
||||
{
|
||||
if (bpp == sizeof(uint32_t))
|
||||
copy_argb_line(rgba_line, (const uint32_t*)data, width);
|
||||
else
|
||||
copy_bgr24_line(rgba_line, data, width);
|
||||
|
||||
/* Try every filtering method, and choose the method
|
||||
* which has most entries as zero.
|
||||
*
|
||||
* This is probably not very optimal, but it's very
|
||||
* simple to implement.
|
||||
*/
|
||||
{
|
||||
unsigned none_score = count_sad(rgba_line, width * bpp);
|
||||
unsigned up_score = filter_up(up_filtered, rgba_line, prev_encoded, width, bpp);
|
||||
unsigned sub_score = filter_sub(sub_filtered, rgba_line, width, bpp);
|
||||
unsigned avg_score = filter_avg(avg_filtered, rgba_line, prev_encoded, width, bpp);
|
||||
unsigned paeth_score = filter_paeth(paeth_filtered, rgba_line, prev_encoded, width, bpp);
|
||||
|
||||
uint8_t filter = 0;
|
||||
unsigned min_sad = none_score;
|
||||
const uint8_t *chosen_filtered = rgba_line;
|
||||
|
||||
if (sub_score < min_sad)
|
||||
{
|
||||
filter = 1;
|
||||
chosen_filtered = sub_filtered;
|
||||
min_sad = sub_score;
|
||||
}
|
||||
|
||||
if (up_score < min_sad)
|
||||
{
|
||||
filter = 2;
|
||||
chosen_filtered = up_filtered;
|
||||
min_sad = up_score;
|
||||
}
|
||||
|
||||
if (avg_score < min_sad)
|
||||
{
|
||||
filter = 3;
|
||||
chosen_filtered = avg_filtered;
|
||||
min_sad = avg_score;
|
||||
}
|
||||
|
||||
if (paeth_score < min_sad)
|
||||
{
|
||||
filter = 4;
|
||||
chosen_filtered = paeth_filtered;
|
||||
min_sad = paeth_score;
|
||||
}
|
||||
|
||||
*encode_target++ = filter;
|
||||
memcpy(encode_target, chosen_filtered, width * bpp);
|
||||
|
||||
memcpy(prev_encoded, rgba_line, width * bpp);
|
||||
}
|
||||
}
|
||||
|
||||
deflate_buf = (uint8_t*)malloc(encode_buf_size * 2); /* Just to be sure. */
|
||||
if (!deflate_buf)
|
||||
GOTO_END_ERROR();
|
||||
|
||||
stream = stream_backend->stream_new();
|
||||
|
||||
if (!stream)
|
||||
GOTO_END_ERROR();
|
||||
|
||||
stream_backend->stream_set(
|
||||
stream,
|
||||
encode_buf_size,
|
||||
encode_buf_size * 2,
|
||||
encode_buf,
|
||||
deflate_buf + 8);
|
||||
|
||||
stream_backend->stream_compress_init(stream, 9);
|
||||
|
||||
if (stream_backend->stream_compress_data_to_file(stream) != 1)
|
||||
{
|
||||
stream_backend->stream_compress_free(stream);
|
||||
GOTO_END_ERROR();
|
||||
}
|
||||
|
||||
stream_backend->stream_compress_free(stream);
|
||||
|
||||
memcpy(deflate_buf + 4, "IDAT", 4);
|
||||
dword_write_be(deflate_buf + 0, stream_backend->stream_get_total_out(stream));
|
||||
if (!png_write_idat(file, deflate_buf, stream_backend->stream_get_total_out(stream) + 8))
|
||||
GOTO_END_ERROR();
|
||||
|
||||
if (!png_write_iend(file))
|
||||
GOTO_END_ERROR();
|
||||
|
||||
end:
|
||||
retro_fclose(file);
|
||||
free(encode_buf);
|
||||
free(deflate_buf);
|
||||
free(rgba_line);
|
||||
free(prev_encoded);
|
||||
free(up_filtered);
|
||||
free(sub_filtered);
|
||||
free(avg_filtered);
|
||||
free(paeth_filtered);
|
||||
|
||||
stream_backend->stream_free(stream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool rpng_save_image_argb(const char *path, const uint32_t *data,
|
||||
unsigned width, unsigned height, unsigned pitch)
|
||||
{
|
||||
return rpng_save_image(path, (const uint8_t*)data,
|
||||
width, height, pitch, sizeof(uint32_t));
|
||||
}
|
||||
|
||||
bool rpng_save_image_bgr24(const char *path, const uint8_t *data,
|
||||
unsigned width, unsigned height, unsigned pitch)
|
||||
{
|
||||
return rpng_save_image(path, (const uint8_t*)data,
|
||||
width, height, pitch, 3);
|
||||
}
|
||||
|
||||
#endif
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (rpng.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <retro_file.h>
|
||||
|
||||
#include "rpng_internal.h"
|
||||
|
||||
#undef GOTO_END_ERROR
|
||||
#define GOTO_END_ERROR() do { \
|
||||
fprintf(stderr, "[RPNG]: Error in line %d.\n", __LINE__); \
|
||||
ret = false; \
|
||||
goto end; \
|
||||
} while(0)
|
||||
|
||||
#ifdef HAVE_ZLIB_DEFLATE
|
||||
|
||||
static void dword_write_be(uint8_t *buf, uint32_t val)
|
||||
{
|
||||
*buf++ = (uint8_t)(val >> 24);
|
||||
*buf++ = (uint8_t)(val >> 16);
|
||||
*buf++ = (uint8_t)(val >> 8);
|
||||
*buf++ = (uint8_t)(val >> 0);
|
||||
}
|
||||
|
||||
static bool png_write_crc(RFILE *file, const uint8_t *data, size_t size)
|
||||
{
|
||||
uint8_t crc_raw[4] = {0};
|
||||
const struct file_archive_file_backend *stream_backend =
|
||||
file_archive_get_default_file_backend();
|
||||
uint32_t crc = stream_backend->stream_crc_calculate(0, data, size);
|
||||
|
||||
dword_write_be(crc_raw, crc);
|
||||
return retro_fwrite(file, crc_raw, sizeof(crc_raw)) == sizeof(crc_raw);
|
||||
}
|
||||
|
||||
static bool png_write_ihdr(RFILE *file, const struct png_ihdr *ihdr)
|
||||
{
|
||||
uint8_t ihdr_raw[21];
|
||||
|
||||
ihdr_raw[0] = '0'; /* Size */
|
||||
ihdr_raw[1] = '0';
|
||||
ihdr_raw[2] = '0';
|
||||
ihdr_raw[3] = '0';
|
||||
ihdr_raw[4] = 'I';
|
||||
ihdr_raw[5] = 'H';
|
||||
ihdr_raw[6] = 'D';
|
||||
ihdr_raw[7] = 'R';
|
||||
ihdr_raw[8] = 0; /* Width */
|
||||
ihdr_raw[9] = 0;
|
||||
ihdr_raw[10] = 0;
|
||||
ihdr_raw[11] = 0;
|
||||
ihdr_raw[12] = 0; /* Height */
|
||||
ihdr_raw[13] = 0;
|
||||
ihdr_raw[14] = 0;
|
||||
ihdr_raw[15] = 0;
|
||||
ihdr_raw[16] = ihdr->depth; /* Depth */
|
||||
ihdr_raw[17] = ihdr->color_type;
|
||||
ihdr_raw[18] = ihdr->compression;
|
||||
ihdr_raw[19] = ihdr->filter;
|
||||
ihdr_raw[20] = ihdr->interlace;
|
||||
|
||||
dword_write_be(ihdr_raw + 0, sizeof(ihdr_raw) - 8);
|
||||
dword_write_be(ihdr_raw + 8, ihdr->width);
|
||||
dword_write_be(ihdr_raw + 12, ihdr->height);
|
||||
if (retro_fwrite(file, ihdr_raw, sizeof(ihdr_raw)) != sizeof(ihdr_raw))
|
||||
return false;
|
||||
|
||||
if (!png_write_crc(file, ihdr_raw + sizeof(uint32_t),
|
||||
sizeof(ihdr_raw) - sizeof(uint32_t)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool png_write_idat(RFILE *file, const uint8_t *data, size_t size)
|
||||
{
|
||||
if (retro_fwrite(file, data, size) != (ssize_t)size)
|
||||
return false;
|
||||
|
||||
if (!png_write_crc(file, data + sizeof(uint32_t), size - sizeof(uint32_t)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool png_write_iend(RFILE *file)
|
||||
{
|
||||
const uint8_t data[] = {
|
||||
0, 0, 0, 0,
|
||||
'I', 'E', 'N', 'D',
|
||||
};
|
||||
|
||||
if (retro_fwrite(file, data, sizeof(data)) != sizeof(data))
|
||||
return false;
|
||||
|
||||
if (!png_write_crc(file, data + sizeof(uint32_t),
|
||||
sizeof(data) - sizeof(uint32_t)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void copy_argb_line(uint8_t *dst, const uint32_t *src, unsigned width)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < width; i++)
|
||||
{
|
||||
uint32_t col = src[i];
|
||||
*dst++ = (uint8_t)(col >> 16);
|
||||
*dst++ = (uint8_t)(col >> 8);
|
||||
*dst++ = (uint8_t)(col >> 0);
|
||||
*dst++ = (uint8_t)(col >> 24);
|
||||
}
|
||||
}
|
||||
|
||||
static void copy_bgr24_line(uint8_t *dst, const uint8_t *src, unsigned width)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < width; i++, dst += 3, src += 3)
|
||||
{
|
||||
dst[2] = src[0];
|
||||
dst[1] = src[1];
|
||||
dst[0] = src[2];
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned count_sad(const uint8_t *data, size_t size)
|
||||
{
|
||||
size_t i;
|
||||
unsigned cnt = 0;
|
||||
for (i = 0; i < size; i++)
|
||||
cnt += abs((int8_t)data[i]);
|
||||
return cnt;
|
||||
}
|
||||
|
||||
static unsigned filter_up(uint8_t *target, const uint8_t *line,
|
||||
const uint8_t *prev, unsigned width, unsigned bpp)
|
||||
{
|
||||
unsigned i;
|
||||
width *= bpp;
|
||||
for (i = 0; i < width; i++)
|
||||
target[i] = line[i] - prev[i];
|
||||
|
||||
return count_sad(target, width);
|
||||
}
|
||||
|
||||
static unsigned filter_sub(uint8_t *target, const uint8_t *line,
|
||||
unsigned width, unsigned bpp)
|
||||
{
|
||||
unsigned i;
|
||||
width *= bpp;
|
||||
for (i = 0; i < bpp; i++)
|
||||
target[i] = line[i];
|
||||
for (i = bpp; i < width; i++)
|
||||
target[i] = line[i] - line[i - bpp];
|
||||
|
||||
return count_sad(target, width);
|
||||
}
|
||||
|
||||
static unsigned filter_avg(uint8_t *target, const uint8_t *line,
|
||||
const uint8_t *prev, unsigned width, unsigned bpp)
|
||||
{
|
||||
unsigned i;
|
||||
width *= bpp;
|
||||
for (i = 0; i < bpp; i++)
|
||||
target[i] = line[i] - (prev[i] >> 1);
|
||||
for (i = bpp; i < width; i++)
|
||||
target[i] = line[i] - ((line[i - bpp] + prev[i]) >> 1);
|
||||
|
||||
return count_sad(target, width);
|
||||
}
|
||||
|
||||
static unsigned filter_paeth(uint8_t *target,
|
||||
const uint8_t *line, const uint8_t *prev,
|
||||
unsigned width, unsigned bpp)
|
||||
{
|
||||
unsigned i;
|
||||
width *= bpp;
|
||||
for (i = 0; i < bpp; i++)
|
||||
target[i] = line[i] - paeth(0, prev[i], 0);
|
||||
for (i = bpp; i < width; i++)
|
||||
target[i] = line[i] - paeth(line[i - bpp], prev[i], prev[i - bpp]);
|
||||
|
||||
return count_sad(target, width);
|
||||
}
|
||||
|
||||
static bool rpng_save_image(const char *path,
|
||||
const uint8_t *data,
|
||||
unsigned width, unsigned height, unsigned pitch, unsigned bpp)
|
||||
{
|
||||
unsigned h;
|
||||
bool ret = true;
|
||||
struct png_ihdr ihdr = {0};
|
||||
|
||||
const struct file_archive_file_backend *stream_backend = NULL;
|
||||
size_t encode_buf_size = 0;
|
||||
uint8_t *encode_buf = NULL;
|
||||
uint8_t *deflate_buf = NULL;
|
||||
uint8_t *rgba_line = NULL;
|
||||
uint8_t *up_filtered = NULL;
|
||||
uint8_t *sub_filtered = NULL;
|
||||
uint8_t *avg_filtered = NULL;
|
||||
uint8_t *paeth_filtered = NULL;
|
||||
uint8_t *prev_encoded = NULL;
|
||||
uint8_t *encode_target = NULL;
|
||||
void *stream = NULL;
|
||||
RFILE *file = retro_fopen(path, RFILE_MODE_WRITE, -1);
|
||||
if (!file)
|
||||
GOTO_END_ERROR();
|
||||
|
||||
stream_backend = file_archive_get_default_file_backend();
|
||||
|
||||
if (retro_fwrite(file, png_magic, sizeof(png_magic)) != sizeof(png_magic))
|
||||
GOTO_END_ERROR();
|
||||
|
||||
ihdr.width = width;
|
||||
ihdr.height = height;
|
||||
ihdr.depth = 8;
|
||||
ihdr.color_type = bpp == sizeof(uint32_t) ? 6 : 2; /* RGBA or RGB */
|
||||
if (!png_write_ihdr(file, &ihdr))
|
||||
GOTO_END_ERROR();
|
||||
|
||||
encode_buf_size = (width * bpp + 1) * height;
|
||||
encode_buf = (uint8_t*)malloc(encode_buf_size);
|
||||
if (!encode_buf)
|
||||
GOTO_END_ERROR();
|
||||
|
||||
prev_encoded = (uint8_t*)calloc(1, width * bpp);
|
||||
if (!prev_encoded)
|
||||
GOTO_END_ERROR();
|
||||
|
||||
rgba_line = (uint8_t*)malloc(width * bpp);
|
||||
up_filtered = (uint8_t*)malloc(width * bpp);
|
||||
sub_filtered = (uint8_t*)malloc(width * bpp);
|
||||
avg_filtered = (uint8_t*)malloc(width * bpp);
|
||||
paeth_filtered = (uint8_t*)malloc(width * bpp);
|
||||
if (!rgba_line || !up_filtered || !sub_filtered || !avg_filtered || !paeth_filtered)
|
||||
GOTO_END_ERROR();
|
||||
|
||||
encode_target = encode_buf;
|
||||
for (h = 0; h < height;
|
||||
h++, encode_target += width * bpp, data += pitch)
|
||||
{
|
||||
if (bpp == sizeof(uint32_t))
|
||||
copy_argb_line(rgba_line, (const uint32_t*)data, width);
|
||||
else
|
||||
copy_bgr24_line(rgba_line, data, width);
|
||||
|
||||
/* Try every filtering method, and choose the method
|
||||
* which has most entries as zero.
|
||||
*
|
||||
* This is probably not very optimal, but it's very
|
||||
* simple to implement.
|
||||
*/
|
||||
{
|
||||
unsigned none_score = count_sad(rgba_line, width * bpp);
|
||||
unsigned up_score = filter_up(up_filtered, rgba_line, prev_encoded, width, bpp);
|
||||
unsigned sub_score = filter_sub(sub_filtered, rgba_line, width, bpp);
|
||||
unsigned avg_score = filter_avg(avg_filtered, rgba_line, prev_encoded, width, bpp);
|
||||
unsigned paeth_score = filter_paeth(paeth_filtered, rgba_line, prev_encoded, width, bpp);
|
||||
|
||||
uint8_t filter = 0;
|
||||
unsigned min_sad = none_score;
|
||||
const uint8_t *chosen_filtered = rgba_line;
|
||||
|
||||
if (sub_score < min_sad)
|
||||
{
|
||||
filter = 1;
|
||||
chosen_filtered = sub_filtered;
|
||||
min_sad = sub_score;
|
||||
}
|
||||
|
||||
if (up_score < min_sad)
|
||||
{
|
||||
filter = 2;
|
||||
chosen_filtered = up_filtered;
|
||||
min_sad = up_score;
|
||||
}
|
||||
|
||||
if (avg_score < min_sad)
|
||||
{
|
||||
filter = 3;
|
||||
chosen_filtered = avg_filtered;
|
||||
min_sad = avg_score;
|
||||
}
|
||||
|
||||
if (paeth_score < min_sad)
|
||||
{
|
||||
filter = 4;
|
||||
chosen_filtered = paeth_filtered;
|
||||
min_sad = paeth_score;
|
||||
}
|
||||
|
||||
*encode_target++ = filter;
|
||||
memcpy(encode_target, chosen_filtered, width * bpp);
|
||||
|
||||
memcpy(prev_encoded, rgba_line, width * bpp);
|
||||
}
|
||||
}
|
||||
|
||||
deflate_buf = (uint8_t*)malloc(encode_buf_size * 2); /* Just to be sure. */
|
||||
if (!deflate_buf)
|
||||
GOTO_END_ERROR();
|
||||
|
||||
stream = stream_backend->stream_new();
|
||||
|
||||
if (!stream)
|
||||
GOTO_END_ERROR();
|
||||
|
||||
stream_backend->stream_set(
|
||||
stream,
|
||||
encode_buf_size,
|
||||
encode_buf_size * 2,
|
||||
encode_buf,
|
||||
deflate_buf + 8);
|
||||
|
||||
stream_backend->stream_compress_init(stream, 9);
|
||||
|
||||
if (stream_backend->stream_compress_data_to_file(stream) != 1)
|
||||
{
|
||||
stream_backend->stream_compress_free(stream);
|
||||
GOTO_END_ERROR();
|
||||
}
|
||||
|
||||
stream_backend->stream_compress_free(stream);
|
||||
|
||||
memcpy(deflate_buf + 4, "IDAT", 4);
|
||||
dword_write_be(deflate_buf + 0, stream_backend->stream_get_total_out(stream));
|
||||
if (!png_write_idat(file, deflate_buf, stream_backend->stream_get_total_out(stream) + 8))
|
||||
GOTO_END_ERROR();
|
||||
|
||||
if (!png_write_iend(file))
|
||||
GOTO_END_ERROR();
|
||||
|
||||
end:
|
||||
retro_fclose(file);
|
||||
free(encode_buf);
|
||||
free(deflate_buf);
|
||||
free(rgba_line);
|
||||
free(prev_encoded);
|
||||
free(up_filtered);
|
||||
free(sub_filtered);
|
||||
free(avg_filtered);
|
||||
free(paeth_filtered);
|
||||
|
||||
stream_backend->stream_free(stream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool rpng_save_image_argb(const char *path, const uint32_t *data,
|
||||
unsigned width, unsigned height, unsigned pitch)
|
||||
{
|
||||
return rpng_save_image(path, (const uint8_t*)data,
|
||||
width, height, pitch, sizeof(uint32_t));
|
||||
}
|
||||
|
||||
bool rpng_save_image_bgr24(const char *path, const uint8_t *data,
|
||||
unsigned width, unsigned height, unsigned pitch)
|
||||
{
|
||||
return rpng_save_image(path, (const uint8_t*)data,
|
||||
width, height, pitch, 3);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,71 +1,71 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (rpng.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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 _RPNG_COMMON_H
|
||||
#define _RPNG_COMMON_H
|
||||
|
||||
#include <retro_inline.h>
|
||||
#include <formats/rpng.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#undef GOTO_END_ERROR
|
||||
#define GOTO_END_ERROR() do { \
|
||||
fprintf(stderr, "[RPNG]: Error in line %d.\n", __LINE__); \
|
||||
ret = false; \
|
||||
goto end; \
|
||||
} while(0)
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
||||
#endif
|
||||
|
||||
static const uint8_t png_magic[8] = {
|
||||
0x89, 'P', 'N', 'G', 0x0d, 0x0a, 0x1a, 0x0a,
|
||||
};
|
||||
|
||||
struct png_ihdr
|
||||
{
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint8_t depth;
|
||||
uint8_t color_type;
|
||||
uint8_t compression;
|
||||
uint8_t filter;
|
||||
uint8_t interlace;
|
||||
};
|
||||
|
||||
/* Paeth prediction filter. */
|
||||
static INLINE int paeth(int a, int b, int c)
|
||||
{
|
||||
int p = a + b - c;
|
||||
int pa = abs(p - a);
|
||||
int pb = abs(p - b);
|
||||
int pc = abs(p - c);
|
||||
|
||||
if (pa <= pb && pa <= pc)
|
||||
return a;
|
||||
else if (pb <= pc)
|
||||
return b;
|
||||
return c;
|
||||
}
|
||||
|
||||
#endif
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (rpng.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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 _RPNG_COMMON_H
|
||||
#define _RPNG_COMMON_H
|
||||
|
||||
#include <retro_inline.h>
|
||||
#include <formats/rpng.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#undef GOTO_END_ERROR
|
||||
#define GOTO_END_ERROR() do { \
|
||||
fprintf(stderr, "[RPNG]: Error in line %d.\n", __LINE__); \
|
||||
ret = false; \
|
||||
goto end; \
|
||||
} while(0)
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
||||
#endif
|
||||
|
||||
static const uint8_t png_magic[8] = {
|
||||
0x89, 'P', 'N', 'G', 0x0d, 0x0a, 0x1a, 0x0a,
|
||||
};
|
||||
|
||||
struct png_ihdr
|
||||
{
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint8_t depth;
|
||||
uint8_t color_type;
|
||||
uint8_t compression;
|
||||
uint8_t filter;
|
||||
uint8_t interlace;
|
||||
};
|
||||
|
||||
/* Paeth prediction filter. */
|
||||
static INLINE int paeth(int a, int b, int c)
|
||||
{
|
||||
int p = a + b - c;
|
||||
int pa = abs(p - a);
|
||||
int pb = abs(p - b);
|
||||
int pc = abs(p - c);
|
||||
|
||||
if (pa <= pb && pa <= pc)
|
||||
return a;
|
||||
else if (pb <= pc)
|
||||
return b;
|
||||
return c;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,133 +1,133 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (rpng_test.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_IMLIB2
|
||||
#include <Imlib2.h>
|
||||
#endif
|
||||
|
||||
#include <file/nbio.h>
|
||||
#include <formats/rpng.h>
|
||||
|
||||
static int test_rpng(const char *in_path)
|
||||
{
|
||||
#ifdef HAVE_IMLIB2
|
||||
Imlib_Image img;
|
||||
const uint32_t *imlib_data = NULL;
|
||||
#endif
|
||||
const uint32_t test_data[] = {
|
||||
0xff000000 | 0x50, 0xff000000 | 0x80,
|
||||
0xff000000 | 0x40, 0xff000000 | 0x88,
|
||||
0xff000000 | 0x50, 0xff000000 | 0x80,
|
||||
0xff000000 | 0x40, 0xff000000 | 0x88,
|
||||
0xff000000 | 0xc3, 0xff000000 | 0xd3,
|
||||
0xff000000 | 0xc3, 0xff000000 | 0xd3,
|
||||
0xff000000 | 0xc3, 0xff000000 | 0xd3,
|
||||
0xff000000 | 0xc3, 0xff000000 | 0xd3,
|
||||
};
|
||||
uint32_t *data = NULL;
|
||||
unsigned width = 0;
|
||||
unsigned height = 0;
|
||||
|
||||
if (!rpng_save_image_argb("/tmp/test.png", test_data, 4, 4, 16))
|
||||
return 1;
|
||||
|
||||
if (!rpng_load_image_argb(in_path, &data, &width, &height))
|
||||
return 2;
|
||||
|
||||
fprintf(stderr, "Path: %s.\n", in_path);
|
||||
fprintf(stderr, "Got image: %u x %u.\n", width, height);
|
||||
|
||||
#if 0
|
||||
fprintf(stderr, "\nRPNG:\n");
|
||||
for (unsigned h = 0; h < height; h++)
|
||||
{
|
||||
unsigned w;
|
||||
for (w = 0; w < width; w++)
|
||||
fprintf(stderr, "[%08x] ", data[h * width + w]);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IMLIB2
|
||||
/* Validate with imlib2 as well. */
|
||||
img = imlib_load_image(in_path);
|
||||
if (!img)
|
||||
return 4;
|
||||
|
||||
imlib_context_set_image(img);
|
||||
|
||||
width = imlib_image_get_width();
|
||||
height = imlib_image_get_width();
|
||||
imlib_data = imlib_image_get_data_for_reading_only();
|
||||
|
||||
#if 0
|
||||
fprintf(stderr, "\nImlib:\n");
|
||||
for (unsigned h = 0; h < height; h++)
|
||||
{
|
||||
for (unsigned w = 0; w < width; w++)
|
||||
fprintf(stderr, "[%08x] ", imlib_data[h * width + w]);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (memcmp(imlib_data, data, width * height * sizeof(uint32_t)) != 0)
|
||||
{
|
||||
fprintf(stderr, "Imlib and RPNG differs!\n");
|
||||
return 5;
|
||||
}
|
||||
else
|
||||
fprintf(stderr, "Imlib and RPNG are equivalent!\n");
|
||||
|
||||
imlib_free_image();
|
||||
#endif
|
||||
free(data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
const char *in_path = "/tmp/test.png";
|
||||
|
||||
if (argc > 2)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s <png file>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (argc == 2)
|
||||
in_path = argv[1];
|
||||
|
||||
fprintf(stderr, "Doing tests...\n");
|
||||
|
||||
if (test_rpng(in_path) != 0)
|
||||
{
|
||||
fprintf(stderr, "Test failed.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (rpng_test.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_IMLIB2
|
||||
#include <Imlib2.h>
|
||||
#endif
|
||||
|
||||
#include <file/nbio.h>
|
||||
#include <formats/rpng.h>
|
||||
|
||||
static int test_rpng(const char *in_path)
|
||||
{
|
||||
#ifdef HAVE_IMLIB2
|
||||
Imlib_Image img;
|
||||
const uint32_t *imlib_data = NULL;
|
||||
#endif
|
||||
const uint32_t test_data[] = {
|
||||
0xff000000 | 0x50, 0xff000000 | 0x80,
|
||||
0xff000000 | 0x40, 0xff000000 | 0x88,
|
||||
0xff000000 | 0x50, 0xff000000 | 0x80,
|
||||
0xff000000 | 0x40, 0xff000000 | 0x88,
|
||||
0xff000000 | 0xc3, 0xff000000 | 0xd3,
|
||||
0xff000000 | 0xc3, 0xff000000 | 0xd3,
|
||||
0xff000000 | 0xc3, 0xff000000 | 0xd3,
|
||||
0xff000000 | 0xc3, 0xff000000 | 0xd3,
|
||||
};
|
||||
uint32_t *data = NULL;
|
||||
unsigned width = 0;
|
||||
unsigned height = 0;
|
||||
|
||||
if (!rpng_save_image_argb("/tmp/test.png", test_data, 4, 4, 16))
|
||||
return 1;
|
||||
|
||||
if (!rpng_load_image_argb(in_path, &data, &width, &height))
|
||||
return 2;
|
||||
|
||||
fprintf(stderr, "Path: %s.\n", in_path);
|
||||
fprintf(stderr, "Got image: %u x %u.\n", width, height);
|
||||
|
||||
#if 0
|
||||
fprintf(stderr, "\nRPNG:\n");
|
||||
for (unsigned h = 0; h < height; h++)
|
||||
{
|
||||
unsigned w;
|
||||
for (w = 0; w < width; w++)
|
||||
fprintf(stderr, "[%08x] ", data[h * width + w]);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IMLIB2
|
||||
/* Validate with imlib2 as well. */
|
||||
img = imlib_load_image(in_path);
|
||||
if (!img)
|
||||
return 4;
|
||||
|
||||
imlib_context_set_image(img);
|
||||
|
||||
width = imlib_image_get_width();
|
||||
height = imlib_image_get_width();
|
||||
imlib_data = imlib_image_get_data_for_reading_only();
|
||||
|
||||
#if 0
|
||||
fprintf(stderr, "\nImlib:\n");
|
||||
for (unsigned h = 0; h < height; h++)
|
||||
{
|
||||
for (unsigned w = 0; w < width; w++)
|
||||
fprintf(stderr, "[%08x] ", imlib_data[h * width + w]);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (memcmp(imlib_data, data, width * height * sizeof(uint32_t)) != 0)
|
||||
{
|
||||
fprintf(stderr, "Imlib and RPNG differs!\n");
|
||||
return 5;
|
||||
}
|
||||
else
|
||||
fprintf(stderr, "Imlib and RPNG are equivalent!\n");
|
||||
|
||||
imlib_free_image();
|
||||
#endif
|
||||
free(data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
const char *in_path = "/tmp/test.png";
|
||||
|
||||
if (argc > 2)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s <png file>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (argc == 2)
|
||||
in_path = argv[1];
|
||||
|
||||
fprintf(stderr, "Doing tests...\n");
|
||||
|
||||
if (test_rpng(in_path) != 0)
|
||||
{
|
||||
fprintf(stderr, "Test failed.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,96 +1,96 @@
|
|||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2015 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <formats/tga.h>
|
||||
#include <formats/image.h>
|
||||
|
||||
bool rtga_image_load_shift(uint8_t *buf,
|
||||
void *data,
|
||||
unsigned a_shift, unsigned r_shift,
|
||||
unsigned g_shift, unsigned b_shift)
|
||||
{
|
||||
unsigned i, bits, size, bits_mul;
|
||||
uint8_t info[6] = {0};
|
||||
unsigned width = 0;
|
||||
unsigned height = 0;
|
||||
const uint8_t *tmp = NULL;
|
||||
struct texture_image *out_img = (struct texture_image*)data;
|
||||
|
||||
if (!buf || buf[2] != 2)
|
||||
{
|
||||
fprintf(stderr, "TGA image is not uncompressed RGB.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
memcpy(info, buf + 12, 6);
|
||||
|
||||
width = info[0] + ((unsigned)info[1] * 256);
|
||||
height = info[2] + ((unsigned)info[3] * 256);
|
||||
bits = info[4];
|
||||
|
||||
fprintf(stderr, "Loaded TGA: (%ux%u @ %u bpp)\n", width, height, bits);
|
||||
|
||||
size = width * height * sizeof(uint32_t);
|
||||
out_img->pixels = (uint32_t*)malloc(size);
|
||||
out_img->width = width;
|
||||
out_img->height = height;
|
||||
|
||||
if (!out_img->pixels)
|
||||
{
|
||||
fprintf(stderr, "Failed to allocate TGA pixels.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
tmp = buf + 18;
|
||||
bits_mul = 3;
|
||||
|
||||
if (bits != 32 && bits != 24)
|
||||
{
|
||||
fprintf(stderr, "Bit depth of TGA image is wrong. Only 32-bit and 24-bit supported.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (bits == 32)
|
||||
bits_mul = 4;
|
||||
|
||||
for (i = 0; i < width * height; i++)
|
||||
{
|
||||
uint32_t b = tmp[i * bits_mul + 0];
|
||||
uint32_t g = tmp[i * bits_mul + 1];
|
||||
uint32_t r = tmp[i * bits_mul + 2];
|
||||
uint32_t a = tmp[i * bits_mul + 3];
|
||||
|
||||
if (bits == 24)
|
||||
a = 0xff;
|
||||
|
||||
out_img->pixels[i] = (a << a_shift) |
|
||||
(r << r_shift) | (g << g_shift) | (b << b_shift);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
error:
|
||||
if (out_img->pixels)
|
||||
free(out_img->pixels);
|
||||
|
||||
out_img->pixels = NULL;
|
||||
out_img->width = out_img->height = 0;
|
||||
return false;
|
||||
}
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2015 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <formats/tga.h>
|
||||
#include <formats/image.h>
|
||||
|
||||
bool rtga_image_load_shift(uint8_t *buf,
|
||||
void *data,
|
||||
unsigned a_shift, unsigned r_shift,
|
||||
unsigned g_shift, unsigned b_shift)
|
||||
{
|
||||
unsigned i, bits, size, bits_mul;
|
||||
uint8_t info[6] = {0};
|
||||
unsigned width = 0;
|
||||
unsigned height = 0;
|
||||
const uint8_t *tmp = NULL;
|
||||
struct texture_image *out_img = (struct texture_image*)data;
|
||||
|
||||
if (!buf || buf[2] != 2)
|
||||
{
|
||||
fprintf(stderr, "TGA image is not uncompressed RGB.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
memcpy(info, buf + 12, 6);
|
||||
|
||||
width = info[0] + ((unsigned)info[1] * 256);
|
||||
height = info[2] + ((unsigned)info[3] * 256);
|
||||
bits = info[4];
|
||||
|
||||
fprintf(stderr, "Loaded TGA: (%ux%u @ %u bpp)\n", width, height, bits);
|
||||
|
||||
size = width * height * sizeof(uint32_t);
|
||||
out_img->pixels = (uint32_t*)malloc(size);
|
||||
out_img->width = width;
|
||||
out_img->height = height;
|
||||
|
||||
if (!out_img->pixels)
|
||||
{
|
||||
fprintf(stderr, "Failed to allocate TGA pixels.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
tmp = buf + 18;
|
||||
bits_mul = 3;
|
||||
|
||||
if (bits != 32 && bits != 24)
|
||||
{
|
||||
fprintf(stderr, "Bit depth of TGA image is wrong. Only 32-bit and 24-bit supported.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (bits == 32)
|
||||
bits_mul = 4;
|
||||
|
||||
for (i = 0; i < width * height; i++)
|
||||
{
|
||||
uint32_t b = tmp[i * bits_mul + 0];
|
||||
uint32_t g = tmp[i * bits_mul + 1];
|
||||
uint32_t r = tmp[i * bits_mul + 2];
|
||||
uint32_t a = tmp[i * bits_mul + 3];
|
||||
|
||||
if (bits == 24)
|
||||
a = 0xff;
|
||||
|
||||
out_img->pixels[i] = (a << a_shift) |
|
||||
(r << r_shift) | (g << g_shift) | (b << b_shift);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
error:
|
||||
if (out_img->pixels)
|
||||
free(out_img->pixels);
|
||||
|
||||
out_img->pixels = NULL;
|
||||
out_img->width = out_img->height = 0;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1,492 +1,492 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (rxml.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include <boolean.h>
|
||||
#include <retro_file.h>
|
||||
#include <compat/posix_string.h>
|
||||
|
||||
#include <formats/rxml.h>
|
||||
|
||||
struct rxml_document
|
||||
{
|
||||
struct rxml_node *root_node;
|
||||
};
|
||||
|
||||
struct rxml_node *rxml_root_node(rxml_document_t *doc)
|
||||
{
|
||||
if (doc)
|
||||
return doc->root_node;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void rxml_free_node(struct rxml_node *node)
|
||||
{
|
||||
struct rxml_node *head = NULL;
|
||||
struct rxml_attrib_node *attrib_node_head = NULL;
|
||||
|
||||
if (!node)
|
||||
return;
|
||||
|
||||
for (head = node->children; head; )
|
||||
{
|
||||
struct rxml_node *next_node = (struct rxml_node*)head->next;
|
||||
rxml_free_node(head);
|
||||
head = next_node;
|
||||
}
|
||||
|
||||
for (attrib_node_head = node->attrib; attrib_node_head; )
|
||||
{
|
||||
struct rxml_attrib_node *next_attrib = NULL;
|
||||
|
||||
if (!attrib_node_head)
|
||||
continue;
|
||||
|
||||
next_attrib = (struct rxml_attrib_node*)attrib_node_head->next;
|
||||
|
||||
if (!next_attrib)
|
||||
continue;
|
||||
|
||||
if (attrib_node_head->attrib)
|
||||
free(attrib_node_head->attrib);
|
||||
if (attrib_node_head->value)
|
||||
free(attrib_node_head->value);
|
||||
if (attrib_node_head)
|
||||
free(attrib_node_head);
|
||||
|
||||
attrib_node_head = next_attrib;
|
||||
}
|
||||
|
||||
if (node->name)
|
||||
free(node->name);
|
||||
if (node->data)
|
||||
free(node->data);
|
||||
if (node)
|
||||
free(node);
|
||||
}
|
||||
|
||||
static bool validate_header(const char **ptr)
|
||||
{
|
||||
if (memcmp(*ptr, "<?xml", 5) == 0)
|
||||
{
|
||||
const char *eol = strstr(*ptr, "?>\n");
|
||||
if (!eol)
|
||||
return false;
|
||||
|
||||
/* Always use UTF-8. Don't really care to check. */
|
||||
*ptr = eol + 3;
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool range_is_space(const char *begin, const char *end)
|
||||
{
|
||||
for (; begin < end; begin++)
|
||||
if (!isspace(*begin))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void skip_spaces(const char **ptr_)
|
||||
{
|
||||
const char *ptr = *ptr_;
|
||||
while (isspace(*ptr))
|
||||
ptr++;
|
||||
|
||||
*ptr_ = ptr;
|
||||
}
|
||||
|
||||
static char *strdup_range(const char *begin, const char *end)
|
||||
{
|
||||
ptrdiff_t len = end - begin;
|
||||
char *ret = (char*)malloc(len + 1);
|
||||
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
memcpy(ret, begin, len);
|
||||
ret[len] = '\0';
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char *strdup_range_escape(const char *begin, const char *end)
|
||||
{
|
||||
/* Escaping is ignored. Assume we don't deal with that. */
|
||||
return strdup_range(begin, end);
|
||||
}
|
||||
|
||||
static struct rxml_attrib_node *rxml_parse_attrs(const char *str)
|
||||
{
|
||||
char *copy = strdup(str);
|
||||
if (!copy)
|
||||
return NULL;
|
||||
|
||||
char *last_char = copy + strlen(copy) - 1;
|
||||
if (*last_char == '/')
|
||||
*last_char = '\0';
|
||||
|
||||
struct rxml_attrib_node *list = NULL;
|
||||
struct rxml_attrib_node *tail = NULL;
|
||||
|
||||
char *attrib = NULL;
|
||||
char *value = NULL;
|
||||
char *save;
|
||||
const char *elem = strtok_r(copy, " \n\t\f\v\r", &save);
|
||||
while (elem)
|
||||
{
|
||||
const char *eq = strstr(elem, "=\"");
|
||||
if (!eq)
|
||||
goto end;
|
||||
|
||||
const char *end = strrchr(eq + 2, '\"');
|
||||
if (!end || end != (elem + strlen(elem) - 1))
|
||||
goto end;
|
||||
|
||||
attrib = strdup_range_escape(elem, eq);
|
||||
value = strdup_range_escape(eq + 2, end);
|
||||
if (!attrib || !value)
|
||||
goto end;
|
||||
|
||||
struct rxml_attrib_node *new_node =
|
||||
(struct rxml_attrib_node*)calloc(1, sizeof(*new_node));
|
||||
if (!new_node)
|
||||
goto end;
|
||||
|
||||
new_node->attrib = attrib;
|
||||
new_node->value = value;
|
||||
attrib = NULL;
|
||||
value = NULL;
|
||||
|
||||
if (tail)
|
||||
{
|
||||
tail->next = new_node;
|
||||
tail = new_node;
|
||||
}
|
||||
else
|
||||
list = tail = new_node;
|
||||
|
||||
elem = strtok_r(NULL, " \n\t\f\v\r", &save);
|
||||
}
|
||||
|
||||
end:
|
||||
if (copy)
|
||||
free(copy);
|
||||
if (attrib)
|
||||
free(attrib);
|
||||
if (value)
|
||||
free(value);
|
||||
return list;
|
||||
}
|
||||
|
||||
static char *find_first_space(const char *str)
|
||||
{
|
||||
while (*str && !isspace(*str))
|
||||
str++;
|
||||
|
||||
return isspace(*str) ? (char*)str : NULL;
|
||||
}
|
||||
|
||||
static bool rxml_parse_tag(struct rxml_node *node, const char *str)
|
||||
{
|
||||
const char *str_ptr = str;
|
||||
skip_spaces(&str_ptr);
|
||||
|
||||
const char *name_end = find_first_space(str_ptr);
|
||||
if (name_end)
|
||||
{
|
||||
node->name = strdup_range(str_ptr, name_end);
|
||||
if (!node->name || !*node->name)
|
||||
return false;
|
||||
|
||||
node->attrib = rxml_parse_attrs(name_end);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
node->name = strdup(str_ptr);
|
||||
return node->name && *node->name;
|
||||
}
|
||||
}
|
||||
|
||||
static struct rxml_node *rxml_parse_node(const char **ptr_)
|
||||
{
|
||||
const char *ptr = NULL;
|
||||
const char *closing = NULL;
|
||||
char *str = NULL;
|
||||
bool is_closing = false;
|
||||
|
||||
struct rxml_node *node = (struct rxml_node*)calloc(1, sizeof(*node));
|
||||
if (!node)
|
||||
return NULL;
|
||||
|
||||
skip_spaces(ptr_);
|
||||
|
||||
ptr = *ptr_;
|
||||
if (*ptr != '<')
|
||||
goto error;
|
||||
|
||||
closing = strchr(ptr, '>');
|
||||
if (!closing)
|
||||
goto error;
|
||||
|
||||
str = strdup_range(ptr + 1, closing);
|
||||
if (!str)
|
||||
goto error;
|
||||
|
||||
if (!rxml_parse_tag(node, str))
|
||||
goto error;
|
||||
|
||||
/* Are spaces between / and > allowed? */
|
||||
is_closing = strstr(ptr, "/>") + 1 == closing;
|
||||
|
||||
/* Look for more data. Either child nodes or data. */
|
||||
if (!is_closing)
|
||||
{
|
||||
size_t closing_tag_size = strlen(node->name) + 4;
|
||||
char *closing_tag = (char*)malloc(closing_tag_size);
|
||||
|
||||
const char *cdata_start = NULL;
|
||||
const char *child_start = NULL;
|
||||
const char *closing_start = NULL;
|
||||
|
||||
if (!closing_tag)
|
||||
goto error;
|
||||
|
||||
snprintf(closing_tag, closing_tag_size, "</%s>", node->name);
|
||||
|
||||
cdata_start = strstr(closing + 1, "<![CDATA[");
|
||||
child_start = strchr(closing + 1, '<');
|
||||
closing_start = strstr(closing + 1, closing_tag);
|
||||
|
||||
if (!closing_start)
|
||||
{
|
||||
free(closing_tag);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (cdata_start && range_is_space(closing + 1, cdata_start))
|
||||
{
|
||||
/* CDATA section */
|
||||
const char *cdata_end = strstr(cdata_start, "]]>");
|
||||
if (!cdata_end)
|
||||
{
|
||||
free(closing_tag);
|
||||
goto error;
|
||||
}
|
||||
|
||||
node->data = strdup_range(cdata_start +
|
||||
strlen("<![CDATA["), cdata_end);
|
||||
}
|
||||
else if (closing_start && closing_start == child_start) /* Simple Data */
|
||||
node->data = strdup_range(closing + 1, closing_start);
|
||||
else
|
||||
{
|
||||
/* Parse all child nodes. */
|
||||
struct rxml_node *list = NULL;
|
||||
struct rxml_node *tail = NULL;
|
||||
const char *first_start = NULL;
|
||||
const char *first_closing = NULL;
|
||||
|
||||
ptr = child_start;
|
||||
first_start = strchr(ptr, '<');
|
||||
first_closing = strstr(ptr, "</");
|
||||
|
||||
while (
|
||||
first_start &&
|
||||
first_closing &&
|
||||
(first_start < first_closing)
|
||||
)
|
||||
{
|
||||
struct rxml_node *new_node = rxml_parse_node(&ptr);
|
||||
|
||||
if (!new_node)
|
||||
{
|
||||
free(closing_tag);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (tail)
|
||||
{
|
||||
tail->next = new_node;
|
||||
tail = new_node;
|
||||
}
|
||||
else
|
||||
list = tail = new_node;
|
||||
|
||||
first_start = strchr(ptr, '<');
|
||||
first_closing = strstr(ptr, "</");
|
||||
}
|
||||
|
||||
node->children = list;
|
||||
|
||||
closing_start = strstr(ptr, closing_tag);
|
||||
if (!closing_start)
|
||||
{
|
||||
free(closing_tag);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
*ptr_ = closing_start + strlen(closing_tag);
|
||||
free(closing_tag);
|
||||
}
|
||||
else
|
||||
*ptr_ = closing + 1;
|
||||
|
||||
if (str)
|
||||
free(str);
|
||||
return node;
|
||||
|
||||
error:
|
||||
if (str)
|
||||
free(str);
|
||||
rxml_free_node(node);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *purge_xml_comments(const char *str)
|
||||
{
|
||||
size_t len = strlen(str);
|
||||
char *new_str = (char*)malloc(len + 1);
|
||||
if (!new_str)
|
||||
return NULL;
|
||||
|
||||
new_str[len] = '\0';
|
||||
|
||||
char *copy_dest = new_str;
|
||||
const char *copy_src = str;
|
||||
for (;;)
|
||||
{
|
||||
ptrdiff_t copy_len;
|
||||
const char *comment_start = strstr(copy_src, "<!--");
|
||||
const char *comment_end = strstr(copy_src, "-->");
|
||||
|
||||
if (!comment_start || !comment_end)
|
||||
break;
|
||||
|
||||
copy_len = comment_start - copy_src;
|
||||
memcpy(copy_dest, copy_src, copy_len);
|
||||
|
||||
copy_dest += copy_len;
|
||||
copy_src = comment_end + strlen("-->");
|
||||
}
|
||||
|
||||
/* Avoid strcpy() as OpenBSD is anal and hates you
|
||||
* for using it even when it's perfectly safe. */
|
||||
len = strlen(copy_src);
|
||||
memcpy(copy_dest, copy_src, len);
|
||||
copy_dest[len] = '\0';
|
||||
|
||||
return new_str;
|
||||
}
|
||||
|
||||
rxml_document_t *rxml_load_document(const char *path)
|
||||
{
|
||||
#ifndef RXML_TEST
|
||||
RARCH_WARN("Using RXML as drop in for libxml2. Behavior might be very buggy.\n");
|
||||
#endif
|
||||
|
||||
char *memory_buffer = NULL;
|
||||
char *new_memory_buffer = NULL;
|
||||
const char *mem_ptr = NULL;
|
||||
long len = 0;
|
||||
RFILE *file = retro_fopen(path, RFILE_MODE_READ, -1);
|
||||
if (!file)
|
||||
return NULL;
|
||||
|
||||
rxml_document_t *doc = (rxml_document_t*)calloc(1, sizeof(*doc));
|
||||
if (!doc)
|
||||
goto error;
|
||||
|
||||
retro_fseek(file, 0, SEEK_END);
|
||||
len = retro_ftell(file);
|
||||
retro_frewind(file);
|
||||
|
||||
memory_buffer = (char*)malloc(len + 1);
|
||||
if (!memory_buffer)
|
||||
goto error;
|
||||
|
||||
memory_buffer[len] = '\0';
|
||||
if (retro_fread(file, memory_buffer, len) != (size_t)len)
|
||||
goto error;
|
||||
|
||||
retro_fclose(file);
|
||||
file = NULL;
|
||||
|
||||
mem_ptr = memory_buffer;
|
||||
|
||||
if (!validate_header(&mem_ptr))
|
||||
goto error;
|
||||
|
||||
new_memory_buffer = purge_xml_comments(mem_ptr);
|
||||
if (!new_memory_buffer)
|
||||
goto error;
|
||||
|
||||
free(memory_buffer);
|
||||
mem_ptr = memory_buffer = new_memory_buffer;
|
||||
|
||||
doc->root_node = rxml_parse_node(&mem_ptr);
|
||||
if (!doc->root_node)
|
||||
goto error;
|
||||
|
||||
free(memory_buffer);
|
||||
return doc;
|
||||
|
||||
error:
|
||||
free(memory_buffer);
|
||||
retro_fclose(file);
|
||||
rxml_free_document(doc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void rxml_free_document(rxml_document_t *doc)
|
||||
{
|
||||
if (!doc)
|
||||
return;
|
||||
|
||||
if (doc->root_node)
|
||||
rxml_free_node(doc->root_node);
|
||||
|
||||
free(doc);
|
||||
}
|
||||
|
||||
char *rxml_node_attrib(struct rxml_node *node, const char *attrib)
|
||||
{
|
||||
struct rxml_attrib_node *attribs = NULL;
|
||||
for (attribs = node->attrib; attribs; attribs = attribs->next)
|
||||
{
|
||||
if (!strcmp(attrib, attribs->attrib))
|
||||
return attribs->value;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (rxml.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include <boolean.h>
|
||||
#include <retro_file.h>
|
||||
#include <compat/posix_string.h>
|
||||
|
||||
#include <formats/rxml.h>
|
||||
|
||||
struct rxml_document
|
||||
{
|
||||
struct rxml_node *root_node;
|
||||
};
|
||||
|
||||
struct rxml_node *rxml_root_node(rxml_document_t *doc)
|
||||
{
|
||||
if (doc)
|
||||
return doc->root_node;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void rxml_free_node(struct rxml_node *node)
|
||||
{
|
||||
struct rxml_node *head = NULL;
|
||||
struct rxml_attrib_node *attrib_node_head = NULL;
|
||||
|
||||
if (!node)
|
||||
return;
|
||||
|
||||
for (head = node->children; head; )
|
||||
{
|
||||
struct rxml_node *next_node = (struct rxml_node*)head->next;
|
||||
rxml_free_node(head);
|
||||
head = next_node;
|
||||
}
|
||||
|
||||
for (attrib_node_head = node->attrib; attrib_node_head; )
|
||||
{
|
||||
struct rxml_attrib_node *next_attrib = NULL;
|
||||
|
||||
if (!attrib_node_head)
|
||||
continue;
|
||||
|
||||
next_attrib = (struct rxml_attrib_node*)attrib_node_head->next;
|
||||
|
||||
if (!next_attrib)
|
||||
continue;
|
||||
|
||||
if (attrib_node_head->attrib)
|
||||
free(attrib_node_head->attrib);
|
||||
if (attrib_node_head->value)
|
||||
free(attrib_node_head->value);
|
||||
if (attrib_node_head)
|
||||
free(attrib_node_head);
|
||||
|
||||
attrib_node_head = next_attrib;
|
||||
}
|
||||
|
||||
if (node->name)
|
||||
free(node->name);
|
||||
if (node->data)
|
||||
free(node->data);
|
||||
if (node)
|
||||
free(node);
|
||||
}
|
||||
|
||||
static bool validate_header(const char **ptr)
|
||||
{
|
||||
if (memcmp(*ptr, "<?xml", 5) == 0)
|
||||
{
|
||||
const char *eol = strstr(*ptr, "?>\n");
|
||||
if (!eol)
|
||||
return false;
|
||||
|
||||
/* Always use UTF-8. Don't really care to check. */
|
||||
*ptr = eol + 3;
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool range_is_space(const char *begin, const char *end)
|
||||
{
|
||||
for (; begin < end; begin++)
|
||||
if (!isspace(*begin))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void skip_spaces(const char **ptr_)
|
||||
{
|
||||
const char *ptr = *ptr_;
|
||||
while (isspace(*ptr))
|
||||
ptr++;
|
||||
|
||||
*ptr_ = ptr;
|
||||
}
|
||||
|
||||
static char *strdup_range(const char *begin, const char *end)
|
||||
{
|
||||
ptrdiff_t len = end - begin;
|
||||
char *ret = (char*)malloc(len + 1);
|
||||
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
memcpy(ret, begin, len);
|
||||
ret[len] = '\0';
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char *strdup_range_escape(const char *begin, const char *end)
|
||||
{
|
||||
/* Escaping is ignored. Assume we don't deal with that. */
|
||||
return strdup_range(begin, end);
|
||||
}
|
||||
|
||||
static struct rxml_attrib_node *rxml_parse_attrs(const char *str)
|
||||
{
|
||||
char *copy = strdup(str);
|
||||
if (!copy)
|
||||
return NULL;
|
||||
|
||||
char *last_char = copy + strlen(copy) - 1;
|
||||
if (*last_char == '/')
|
||||
*last_char = '\0';
|
||||
|
||||
struct rxml_attrib_node *list = NULL;
|
||||
struct rxml_attrib_node *tail = NULL;
|
||||
|
||||
char *attrib = NULL;
|
||||
char *value = NULL;
|
||||
char *save;
|
||||
const char *elem = strtok_r(copy, " \n\t\f\v\r", &save);
|
||||
while (elem)
|
||||
{
|
||||
const char *eq = strstr(elem, "=\"");
|
||||
if (!eq)
|
||||
goto end;
|
||||
|
||||
const char *end = strrchr(eq + 2, '\"');
|
||||
if (!end || end != (elem + strlen(elem) - 1))
|
||||
goto end;
|
||||
|
||||
attrib = strdup_range_escape(elem, eq);
|
||||
value = strdup_range_escape(eq + 2, end);
|
||||
if (!attrib || !value)
|
||||
goto end;
|
||||
|
||||
struct rxml_attrib_node *new_node =
|
||||
(struct rxml_attrib_node*)calloc(1, sizeof(*new_node));
|
||||
if (!new_node)
|
||||
goto end;
|
||||
|
||||
new_node->attrib = attrib;
|
||||
new_node->value = value;
|
||||
attrib = NULL;
|
||||
value = NULL;
|
||||
|
||||
if (tail)
|
||||
{
|
||||
tail->next = new_node;
|
||||
tail = new_node;
|
||||
}
|
||||
else
|
||||
list = tail = new_node;
|
||||
|
||||
elem = strtok_r(NULL, " \n\t\f\v\r", &save);
|
||||
}
|
||||
|
||||
end:
|
||||
if (copy)
|
||||
free(copy);
|
||||
if (attrib)
|
||||
free(attrib);
|
||||
if (value)
|
||||
free(value);
|
||||
return list;
|
||||
}
|
||||
|
||||
static char *find_first_space(const char *str)
|
||||
{
|
||||
while (*str && !isspace(*str))
|
||||
str++;
|
||||
|
||||
return isspace(*str) ? (char*)str : NULL;
|
||||
}
|
||||
|
||||
static bool rxml_parse_tag(struct rxml_node *node, const char *str)
|
||||
{
|
||||
const char *str_ptr = str;
|
||||
skip_spaces(&str_ptr);
|
||||
|
||||
const char *name_end = find_first_space(str_ptr);
|
||||
if (name_end)
|
||||
{
|
||||
node->name = strdup_range(str_ptr, name_end);
|
||||
if (!node->name || !*node->name)
|
||||
return false;
|
||||
|
||||
node->attrib = rxml_parse_attrs(name_end);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
node->name = strdup(str_ptr);
|
||||
return node->name && *node->name;
|
||||
}
|
||||
}
|
||||
|
||||
static struct rxml_node *rxml_parse_node(const char **ptr_)
|
||||
{
|
||||
const char *ptr = NULL;
|
||||
const char *closing = NULL;
|
||||
char *str = NULL;
|
||||
bool is_closing = false;
|
||||
|
||||
struct rxml_node *node = (struct rxml_node*)calloc(1, sizeof(*node));
|
||||
if (!node)
|
||||
return NULL;
|
||||
|
||||
skip_spaces(ptr_);
|
||||
|
||||
ptr = *ptr_;
|
||||
if (*ptr != '<')
|
||||
goto error;
|
||||
|
||||
closing = strchr(ptr, '>');
|
||||
if (!closing)
|
||||
goto error;
|
||||
|
||||
str = strdup_range(ptr + 1, closing);
|
||||
if (!str)
|
||||
goto error;
|
||||
|
||||
if (!rxml_parse_tag(node, str))
|
||||
goto error;
|
||||
|
||||
/* Are spaces between / and > allowed? */
|
||||
is_closing = strstr(ptr, "/>") + 1 == closing;
|
||||
|
||||
/* Look for more data. Either child nodes or data. */
|
||||
if (!is_closing)
|
||||
{
|
||||
size_t closing_tag_size = strlen(node->name) + 4;
|
||||
char *closing_tag = (char*)malloc(closing_tag_size);
|
||||
|
||||
const char *cdata_start = NULL;
|
||||
const char *child_start = NULL;
|
||||
const char *closing_start = NULL;
|
||||
|
||||
if (!closing_tag)
|
||||
goto error;
|
||||
|
||||
snprintf(closing_tag, closing_tag_size, "</%s>", node->name);
|
||||
|
||||
cdata_start = strstr(closing + 1, "<![CDATA[");
|
||||
child_start = strchr(closing + 1, '<');
|
||||
closing_start = strstr(closing + 1, closing_tag);
|
||||
|
||||
if (!closing_start)
|
||||
{
|
||||
free(closing_tag);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (cdata_start && range_is_space(closing + 1, cdata_start))
|
||||
{
|
||||
/* CDATA section */
|
||||
const char *cdata_end = strstr(cdata_start, "]]>");
|
||||
if (!cdata_end)
|
||||
{
|
||||
free(closing_tag);
|
||||
goto error;
|
||||
}
|
||||
|
||||
node->data = strdup_range(cdata_start +
|
||||
strlen("<![CDATA["), cdata_end);
|
||||
}
|
||||
else if (closing_start && closing_start == child_start) /* Simple Data */
|
||||
node->data = strdup_range(closing + 1, closing_start);
|
||||
else
|
||||
{
|
||||
/* Parse all child nodes. */
|
||||
struct rxml_node *list = NULL;
|
||||
struct rxml_node *tail = NULL;
|
||||
const char *first_start = NULL;
|
||||
const char *first_closing = NULL;
|
||||
|
||||
ptr = child_start;
|
||||
first_start = strchr(ptr, '<');
|
||||
first_closing = strstr(ptr, "</");
|
||||
|
||||
while (
|
||||
first_start &&
|
||||
first_closing &&
|
||||
(first_start < first_closing)
|
||||
)
|
||||
{
|
||||
struct rxml_node *new_node = rxml_parse_node(&ptr);
|
||||
|
||||
if (!new_node)
|
||||
{
|
||||
free(closing_tag);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (tail)
|
||||
{
|
||||
tail->next = new_node;
|
||||
tail = new_node;
|
||||
}
|
||||
else
|
||||
list = tail = new_node;
|
||||
|
||||
first_start = strchr(ptr, '<');
|
||||
first_closing = strstr(ptr, "</");
|
||||
}
|
||||
|
||||
node->children = list;
|
||||
|
||||
closing_start = strstr(ptr, closing_tag);
|
||||
if (!closing_start)
|
||||
{
|
||||
free(closing_tag);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
*ptr_ = closing_start + strlen(closing_tag);
|
||||
free(closing_tag);
|
||||
}
|
||||
else
|
||||
*ptr_ = closing + 1;
|
||||
|
||||
if (str)
|
||||
free(str);
|
||||
return node;
|
||||
|
||||
error:
|
||||
if (str)
|
||||
free(str);
|
||||
rxml_free_node(node);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *purge_xml_comments(const char *str)
|
||||
{
|
||||
size_t len = strlen(str);
|
||||
char *new_str = (char*)malloc(len + 1);
|
||||
if (!new_str)
|
||||
return NULL;
|
||||
|
||||
new_str[len] = '\0';
|
||||
|
||||
char *copy_dest = new_str;
|
||||
const char *copy_src = str;
|
||||
for (;;)
|
||||
{
|
||||
ptrdiff_t copy_len;
|
||||
const char *comment_start = strstr(copy_src, "<!--");
|
||||
const char *comment_end = strstr(copy_src, "-->");
|
||||
|
||||
if (!comment_start || !comment_end)
|
||||
break;
|
||||
|
||||
copy_len = comment_start - copy_src;
|
||||
memcpy(copy_dest, copy_src, copy_len);
|
||||
|
||||
copy_dest += copy_len;
|
||||
copy_src = comment_end + strlen("-->");
|
||||
}
|
||||
|
||||
/* Avoid strcpy() as OpenBSD is anal and hates you
|
||||
* for using it even when it's perfectly safe. */
|
||||
len = strlen(copy_src);
|
||||
memcpy(copy_dest, copy_src, len);
|
||||
copy_dest[len] = '\0';
|
||||
|
||||
return new_str;
|
||||
}
|
||||
|
||||
rxml_document_t *rxml_load_document(const char *path)
|
||||
{
|
||||
#ifndef RXML_TEST
|
||||
RARCH_WARN("Using RXML as drop in for libxml2. Behavior might be very buggy.\n");
|
||||
#endif
|
||||
|
||||
char *memory_buffer = NULL;
|
||||
char *new_memory_buffer = NULL;
|
||||
const char *mem_ptr = NULL;
|
||||
long len = 0;
|
||||
RFILE *file = retro_fopen(path, RFILE_MODE_READ, -1);
|
||||
if (!file)
|
||||
return NULL;
|
||||
|
||||
rxml_document_t *doc = (rxml_document_t*)calloc(1, sizeof(*doc));
|
||||
if (!doc)
|
||||
goto error;
|
||||
|
||||
retro_fseek(file, 0, SEEK_END);
|
||||
len = retro_ftell(file);
|
||||
retro_frewind(file);
|
||||
|
||||
memory_buffer = (char*)malloc(len + 1);
|
||||
if (!memory_buffer)
|
||||
goto error;
|
||||
|
||||
memory_buffer[len] = '\0';
|
||||
if (retro_fread(file, memory_buffer, len) != (size_t)len)
|
||||
goto error;
|
||||
|
||||
retro_fclose(file);
|
||||
file = NULL;
|
||||
|
||||
mem_ptr = memory_buffer;
|
||||
|
||||
if (!validate_header(&mem_ptr))
|
||||
goto error;
|
||||
|
||||
new_memory_buffer = purge_xml_comments(mem_ptr);
|
||||
if (!new_memory_buffer)
|
||||
goto error;
|
||||
|
||||
free(memory_buffer);
|
||||
mem_ptr = memory_buffer = new_memory_buffer;
|
||||
|
||||
doc->root_node = rxml_parse_node(&mem_ptr);
|
||||
if (!doc->root_node)
|
||||
goto error;
|
||||
|
||||
free(memory_buffer);
|
||||
return doc;
|
||||
|
||||
error:
|
||||
free(memory_buffer);
|
||||
retro_fclose(file);
|
||||
rxml_free_document(doc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void rxml_free_document(rxml_document_t *doc)
|
||||
{
|
||||
if (!doc)
|
||||
return;
|
||||
|
||||
if (doc->root_node)
|
||||
rxml_free_node(doc->root_node);
|
||||
|
||||
free(doc);
|
||||
}
|
||||
|
||||
char *rxml_node_attrib(struct rxml_node *node, const char *attrib)
|
||||
{
|
||||
struct rxml_attrib_node *attribs = NULL;
|
||||
for (attribs = node->attrib; attribs; attribs = attribs->next)
|
||||
{
|
||||
if (!strcmp(attrib, attribs->attrib))
|
||||
return attribs->value;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,67 +1,67 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (rxml_test.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <formats/rxml.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static void print_siblings(struct rxml_node *node, unsigned level)
|
||||
{
|
||||
fprintf(stderr, "\n%*sName: %s\n", level * 4, "", node->name);
|
||||
if (node->data)
|
||||
fprintf(stderr, "%*sData: %s\n", level * 4, "", node->data);
|
||||
|
||||
for (const struct rxml_attrib_node *attrib =
|
||||
node->attrib; attrib; attrib = attrib->next)
|
||||
fprintf(stderr, "%*s Attrib: %s = %s\n", level * 4, "",
|
||||
attrib->attrib, attrib->value);
|
||||
|
||||
if (node->children)
|
||||
print_siblings(node->children, level + 1);
|
||||
|
||||
if (node->next)
|
||||
print_siblings(node->next, level);
|
||||
}
|
||||
|
||||
static void rxml_log_document(const char *path)
|
||||
{
|
||||
rxml_document_t *doc = rxml_load_document(path);
|
||||
if (!doc)
|
||||
{
|
||||
fprintf(stderr, "rxml: Failed to load document: %s\n", path);
|
||||
return;
|
||||
}
|
||||
|
||||
print_siblings(rxml_root_node(doc), 0);
|
||||
rxml_free_document(doc);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if (argc != 2)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s <path>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
rxml_log_document(argv[1]);
|
||||
}
|
||||
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (rxml_test.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <formats/rxml.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static void print_siblings(struct rxml_node *node, unsigned level)
|
||||
{
|
||||
fprintf(stderr, "\n%*sName: %s\n", level * 4, "", node->name);
|
||||
if (node->data)
|
||||
fprintf(stderr, "%*sData: %s\n", level * 4, "", node->data);
|
||||
|
||||
for (const struct rxml_attrib_node *attrib =
|
||||
node->attrib; attrib; attrib = attrib->next)
|
||||
fprintf(stderr, "%*s Attrib: %s = %s\n", level * 4, "",
|
||||
attrib->attrib, attrib->value);
|
||||
|
||||
if (node->children)
|
||||
print_siblings(node->children, level + 1);
|
||||
|
||||
if (node->next)
|
||||
print_siblings(node->next, level);
|
||||
}
|
||||
|
||||
static void rxml_log_document(const char *path)
|
||||
{
|
||||
rxml_document_t *doc = rxml_load_document(path);
|
||||
if (!doc)
|
||||
{
|
||||
fprintf(stderr, "rxml: Failed to load document: %s\n", path);
|
||||
return;
|
||||
}
|
||||
|
||||
print_siblings(rxml_root_node(doc), 0);
|
||||
rxml_free_document(doc);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if (argc != 2)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s <path>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
rxml_log_document(argv[1]);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,251 +1,251 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (matrix_3x3.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <gfx/math/matrix_3x3.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#define floats_are_equal(x, y) (fabs(x - y) <= 0.00001f * ((x) > (y) ? (y) : (x)))
|
||||
#define float_is_zero(x) (floats_are_equal((x) + 1, 1))
|
||||
|
||||
void matrix_3x3_identity(math_matrix_3x3 *mat)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
memset(mat, 0, sizeof(*mat));
|
||||
for (i = 0; i < 3; i++)
|
||||
MAT_ELEM_3X3(*mat, i, i) = 1.0f;
|
||||
}
|
||||
|
||||
void matrix_3x3_inits(math_matrix_3x3 *mat,
|
||||
const float n11, const float n12, const float n13,
|
||||
const float n21, const float n22, const float n23,
|
||||
const float n31, const float n32, const float n33)
|
||||
{
|
||||
MAT_ELEM_3X3(*mat, 0, 0) = n11;
|
||||
MAT_ELEM_3X3(*mat, 0, 1) = n12;
|
||||
MAT_ELEM_3X3(*mat, 0, 2) = n13;
|
||||
MAT_ELEM_3X3(*mat, 1, 0) = n21;
|
||||
MAT_ELEM_3X3(*mat, 1, 1) = n22;
|
||||
MAT_ELEM_3X3(*mat, 1, 2) = n23;
|
||||
MAT_ELEM_3X3(*mat, 2, 0) = n31;
|
||||
MAT_ELEM_3X3(*mat, 2, 1) = n32;
|
||||
MAT_ELEM_3X3(*mat, 2, 2) = n33;
|
||||
}
|
||||
|
||||
void matrix_3x3_transpose(math_matrix_3x3 *out, const math_matrix_3x3 *in)
|
||||
{
|
||||
unsigned i, j;
|
||||
math_matrix_3x3 mat;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
for (j = 0; j < 3; j++)
|
||||
MAT_ELEM_3X3(mat, j, i) = MAT_ELEM_3X3(*in, i, j);
|
||||
|
||||
*out = mat;
|
||||
}
|
||||
|
||||
void matrix_3x3_multiply(math_matrix_3x3 *out,
|
||||
const math_matrix_3x3 *a, const math_matrix_3x3 *b)
|
||||
{
|
||||
unsigned r, c, k;
|
||||
math_matrix_3x3 mat;
|
||||
|
||||
for (r = 0; r < 3; r++)
|
||||
{
|
||||
for (c = 0; c < 3; c++)
|
||||
{
|
||||
float dot = 0.0f;
|
||||
for (k = 0; k < 3; k++)
|
||||
dot += MAT_ELEM_3X3(*a, r, k) * MAT_ELEM_3X3(*b, k, c);
|
||||
MAT_ELEM_3X3(mat, r, c) = dot;
|
||||
}
|
||||
}
|
||||
|
||||
*out = mat;
|
||||
}
|
||||
|
||||
void matrix_3x3_divide_scalar(math_matrix_3x3 *mat, const float s)
|
||||
{
|
||||
unsigned i, j;
|
||||
for (i = 0; i < 3; i++)
|
||||
for (j = 0; j < 3; j++)
|
||||
MAT_ELEM_3X3(*mat, i, j) /= s;
|
||||
}
|
||||
|
||||
float matrix_3x3_determinant(const math_matrix_3x3 *mat)
|
||||
{
|
||||
float det = MAT_ELEM_3X3(*mat, 0, 0) * (MAT_ELEM_3X3(*mat, 1, 1) * MAT_ELEM_3X3(*mat, 2, 2) - MAT_ELEM_3X3(*mat, 1, 2) * MAT_ELEM_3X3(*mat, 2, 1));
|
||||
det -= MAT_ELEM_3X3(*mat, 0, 1) * (MAT_ELEM_3X3(*mat, 1, 0) * MAT_ELEM_3X3(*mat, 2, 2) - MAT_ELEM_3X3(*mat, 1, 2) * MAT_ELEM_3X3(*mat, 2, 0));
|
||||
det += MAT_ELEM_3X3(*mat, 0, 2) * (MAT_ELEM_3X3(*mat, 1, 0) * MAT_ELEM_3X3(*mat, 2, 1) - MAT_ELEM_3X3(*mat, 1, 1) * MAT_ELEM_3X3(*mat, 2, 0));
|
||||
|
||||
return det;
|
||||
}
|
||||
|
||||
void matrix_3x3_adjoint(math_matrix_3x3 *mat)
|
||||
{
|
||||
math_matrix_3x3 out;
|
||||
|
||||
MAT_ELEM_3X3(out, 0, 0) = (MAT_ELEM_3X3(*mat, 1, 1) * MAT_ELEM_3X3(*mat, 2, 2) - MAT_ELEM_3X3(*mat, 1, 2) * MAT_ELEM_3X3(*mat, 2, 1));
|
||||
MAT_ELEM_3X3(out, 0, 1) = -(MAT_ELEM_3X3(*mat, 0, 1) * MAT_ELEM_3X3(*mat, 2, 2) - MAT_ELEM_3X3(*mat, 0, 2) * MAT_ELEM_3X3(*mat, 2, 1));
|
||||
MAT_ELEM_3X3(out, 0, 2) = (MAT_ELEM_3X3(*mat, 0, 1) * MAT_ELEM_3X3(*mat, 1, 1) - MAT_ELEM_3X3(*mat, 0, 2) * MAT_ELEM_3X3(*mat, 1, 1));
|
||||
MAT_ELEM_3X3(out, 1, 0) = -(MAT_ELEM_3X3(*mat, 1, 0) * MAT_ELEM_3X3(*mat, 2, 2) - MAT_ELEM_3X3(*mat, 1, 2) * MAT_ELEM_3X3(*mat, 2, 0));
|
||||
MAT_ELEM_3X3(out, 1, 1) = (MAT_ELEM_3X3(*mat, 0, 0) * MAT_ELEM_3X3(*mat, 2, 2) - MAT_ELEM_3X3(*mat, 0, 2) * MAT_ELEM_3X3(*mat, 2, 0));
|
||||
MAT_ELEM_3X3(out, 1, 2) = -(MAT_ELEM_3X3(*mat, 0, 0) * MAT_ELEM_3X3(*mat, 1, 2) - MAT_ELEM_3X3(*mat, 0, 2) * MAT_ELEM_3X3(*mat, 1, 0));
|
||||
MAT_ELEM_3X3(out, 2, 0) = (MAT_ELEM_3X3(*mat, 1, 0) * MAT_ELEM_3X3(*mat, 2, 1) - MAT_ELEM_3X3(*mat, 1, 1) * MAT_ELEM_3X3(*mat, 2, 0));
|
||||
MAT_ELEM_3X3(out, 2, 1) = -(MAT_ELEM_3X3(*mat, 0, 0) * MAT_ELEM_3X3(*mat, 2, 1) - MAT_ELEM_3X3(*mat, 0, 1) * MAT_ELEM_3X3(*mat, 2, 0));
|
||||
MAT_ELEM_3X3(out, 2, 2) = (MAT_ELEM_3X3(*mat, 0, 0) * MAT_ELEM_3X3(*mat, 1, 1) - MAT_ELEM_3X3(*mat, 0, 1) * MAT_ELEM_3X3(*mat, 1, 0));
|
||||
|
||||
*mat = out;
|
||||
}
|
||||
|
||||
bool matrix_3x3_invert(math_matrix_3x3 *mat)
|
||||
{
|
||||
float det = matrix_3x3_determinant(mat);
|
||||
|
||||
if (float_is_zero(det))
|
||||
return false;
|
||||
|
||||
matrix_3x3_adjoint(mat);
|
||||
matrix_3x3_divide_scalar(mat, det);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* the following code is Copyright 2009 VMware, Inc. All Rights Reserved.
|
||||
*
|
||||
* 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, sub license, 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 (including the
|
||||
* next paragraph) 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 NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
bool matrix_3x3_square_to_quad(const float dx0, const float dy0,
|
||||
const float dx1, const float dy1,
|
||||
const float dx3, const float dy3,
|
||||
const float dx2, const float dy2,
|
||||
math_matrix_3x3 *mat)
|
||||
{
|
||||
float ax = dx0 - dx1 + dx2 - dx3;
|
||||
float ay = dy0 - dy1 + dy2 - dy3;
|
||||
|
||||
if (float_is_zero(ax) && float_is_zero(ay))
|
||||
{
|
||||
/* affine case */
|
||||
matrix_3x3_inits(mat,
|
||||
dx1 - dx0, dy1 - dy0, 0,
|
||||
dx2 - dx1, dy2 - dy1, 0,
|
||||
dx0, dy0, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
float a, b, c, d, e, f, g, h;
|
||||
float ax1 = dx1 - dx2;
|
||||
float ax2 = dx3 - dx2;
|
||||
float ay1 = dy1 - dy2;
|
||||
float ay2 = dy3 - dy2;
|
||||
|
||||
/* determinants */
|
||||
float gtop = ax * ay2 - ax2 * ay;
|
||||
float htop = ax1 * ay - ax * ay1;
|
||||
float bottom = ax1 * ay2 - ax2 * ay1;
|
||||
|
||||
if (!bottom)
|
||||
return false;
|
||||
|
||||
g = gtop / bottom;
|
||||
h = htop / bottom;
|
||||
|
||||
a = dx1 - dx0 + g * dx1;
|
||||
b = dx3 - dx0 + h * dx3;
|
||||
c = dx0;
|
||||
d = dy1 - dy0 + g * dy1;
|
||||
e = dy3 - dy0 + h * dy3;
|
||||
f = dy0;
|
||||
|
||||
matrix_3x3_inits(mat,
|
||||
a, d, g,
|
||||
b, e, h,
|
||||
c, f, 1.f);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool matrix_3x3_quad_to_square(const float sx0, const float sy0,
|
||||
const float sx1, const float sy1,
|
||||
const float sx2, const float sy2,
|
||||
const float sx3, const float sy3,
|
||||
math_matrix_3x3 *mat)
|
||||
{
|
||||
if (!matrix_3x3_square_to_quad(sx0, sy0, sx1, sy1,
|
||||
sx2, sy2, sx3, sy3,
|
||||
mat))
|
||||
return false;
|
||||
|
||||
return matrix_3x3_invert(mat);
|
||||
}
|
||||
|
||||
bool matrix_3x3_quad_to_quad(const float dx0, const float dy0,
|
||||
const float dx1, const float dy1,
|
||||
const float dx2, const float dy2,
|
||||
const float dx3, const float dy3,
|
||||
const float sx0, const float sy0,
|
||||
const float sx1, const float sy1,
|
||||
const float sx2, const float sy2,
|
||||
const float sx3, const float sy3,
|
||||
math_matrix_3x3 *mat)
|
||||
{
|
||||
math_matrix_3x3 quad_to_square, square_to_quad;
|
||||
|
||||
if (!matrix_3x3_square_to_quad(dx0, dy0, dx1, dy1,
|
||||
dx2, dy2, dx3, dy3,
|
||||
&square_to_quad))
|
||||
return false;
|
||||
|
||||
if (!matrix_3x3_quad_to_square(sx0, sy0, sx1, sy1,
|
||||
sx2, sy2, sx3, sy3,
|
||||
&quad_to_square))
|
||||
return false;
|
||||
|
||||
matrix_3x3_multiply(mat, &quad_to_square, &square_to_quad);
|
||||
|
||||
return true;
|
||||
}
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (matrix_3x3.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <gfx/math/matrix_3x3.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#define floats_are_equal(x, y) (fabs(x - y) <= 0.00001f * ((x) > (y) ? (y) : (x)))
|
||||
#define float_is_zero(x) (floats_are_equal((x) + 1, 1))
|
||||
|
||||
void matrix_3x3_identity(math_matrix_3x3 *mat)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
memset(mat, 0, sizeof(*mat));
|
||||
for (i = 0; i < 3; i++)
|
||||
MAT_ELEM_3X3(*mat, i, i) = 1.0f;
|
||||
}
|
||||
|
||||
void matrix_3x3_inits(math_matrix_3x3 *mat,
|
||||
const float n11, const float n12, const float n13,
|
||||
const float n21, const float n22, const float n23,
|
||||
const float n31, const float n32, const float n33)
|
||||
{
|
||||
MAT_ELEM_3X3(*mat, 0, 0) = n11;
|
||||
MAT_ELEM_3X3(*mat, 0, 1) = n12;
|
||||
MAT_ELEM_3X3(*mat, 0, 2) = n13;
|
||||
MAT_ELEM_3X3(*mat, 1, 0) = n21;
|
||||
MAT_ELEM_3X3(*mat, 1, 1) = n22;
|
||||
MAT_ELEM_3X3(*mat, 1, 2) = n23;
|
||||
MAT_ELEM_3X3(*mat, 2, 0) = n31;
|
||||
MAT_ELEM_3X3(*mat, 2, 1) = n32;
|
||||
MAT_ELEM_3X3(*mat, 2, 2) = n33;
|
||||
}
|
||||
|
||||
void matrix_3x3_transpose(math_matrix_3x3 *out, const math_matrix_3x3 *in)
|
||||
{
|
||||
unsigned i, j;
|
||||
math_matrix_3x3 mat;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
for (j = 0; j < 3; j++)
|
||||
MAT_ELEM_3X3(mat, j, i) = MAT_ELEM_3X3(*in, i, j);
|
||||
|
||||
*out = mat;
|
||||
}
|
||||
|
||||
void matrix_3x3_multiply(math_matrix_3x3 *out,
|
||||
const math_matrix_3x3 *a, const math_matrix_3x3 *b)
|
||||
{
|
||||
unsigned r, c, k;
|
||||
math_matrix_3x3 mat;
|
||||
|
||||
for (r = 0; r < 3; r++)
|
||||
{
|
||||
for (c = 0; c < 3; c++)
|
||||
{
|
||||
float dot = 0.0f;
|
||||
for (k = 0; k < 3; k++)
|
||||
dot += MAT_ELEM_3X3(*a, r, k) * MAT_ELEM_3X3(*b, k, c);
|
||||
MAT_ELEM_3X3(mat, r, c) = dot;
|
||||
}
|
||||
}
|
||||
|
||||
*out = mat;
|
||||
}
|
||||
|
||||
void matrix_3x3_divide_scalar(math_matrix_3x3 *mat, const float s)
|
||||
{
|
||||
unsigned i, j;
|
||||
for (i = 0; i < 3; i++)
|
||||
for (j = 0; j < 3; j++)
|
||||
MAT_ELEM_3X3(*mat, i, j) /= s;
|
||||
}
|
||||
|
||||
float matrix_3x3_determinant(const math_matrix_3x3 *mat)
|
||||
{
|
||||
float det = MAT_ELEM_3X3(*mat, 0, 0) * (MAT_ELEM_3X3(*mat, 1, 1) * MAT_ELEM_3X3(*mat, 2, 2) - MAT_ELEM_3X3(*mat, 1, 2) * MAT_ELEM_3X3(*mat, 2, 1));
|
||||
det -= MAT_ELEM_3X3(*mat, 0, 1) * (MAT_ELEM_3X3(*mat, 1, 0) * MAT_ELEM_3X3(*mat, 2, 2) - MAT_ELEM_3X3(*mat, 1, 2) * MAT_ELEM_3X3(*mat, 2, 0));
|
||||
det += MAT_ELEM_3X3(*mat, 0, 2) * (MAT_ELEM_3X3(*mat, 1, 0) * MAT_ELEM_3X3(*mat, 2, 1) - MAT_ELEM_3X3(*mat, 1, 1) * MAT_ELEM_3X3(*mat, 2, 0));
|
||||
|
||||
return det;
|
||||
}
|
||||
|
||||
void matrix_3x3_adjoint(math_matrix_3x3 *mat)
|
||||
{
|
||||
math_matrix_3x3 out;
|
||||
|
||||
MAT_ELEM_3X3(out, 0, 0) = (MAT_ELEM_3X3(*mat, 1, 1) * MAT_ELEM_3X3(*mat, 2, 2) - MAT_ELEM_3X3(*mat, 1, 2) * MAT_ELEM_3X3(*mat, 2, 1));
|
||||
MAT_ELEM_3X3(out, 0, 1) = -(MAT_ELEM_3X3(*mat, 0, 1) * MAT_ELEM_3X3(*mat, 2, 2) - MAT_ELEM_3X3(*mat, 0, 2) * MAT_ELEM_3X3(*mat, 2, 1));
|
||||
MAT_ELEM_3X3(out, 0, 2) = (MAT_ELEM_3X3(*mat, 0, 1) * MAT_ELEM_3X3(*mat, 1, 1) - MAT_ELEM_3X3(*mat, 0, 2) * MAT_ELEM_3X3(*mat, 1, 1));
|
||||
MAT_ELEM_3X3(out, 1, 0) = -(MAT_ELEM_3X3(*mat, 1, 0) * MAT_ELEM_3X3(*mat, 2, 2) - MAT_ELEM_3X3(*mat, 1, 2) * MAT_ELEM_3X3(*mat, 2, 0));
|
||||
MAT_ELEM_3X3(out, 1, 1) = (MAT_ELEM_3X3(*mat, 0, 0) * MAT_ELEM_3X3(*mat, 2, 2) - MAT_ELEM_3X3(*mat, 0, 2) * MAT_ELEM_3X3(*mat, 2, 0));
|
||||
MAT_ELEM_3X3(out, 1, 2) = -(MAT_ELEM_3X3(*mat, 0, 0) * MAT_ELEM_3X3(*mat, 1, 2) - MAT_ELEM_3X3(*mat, 0, 2) * MAT_ELEM_3X3(*mat, 1, 0));
|
||||
MAT_ELEM_3X3(out, 2, 0) = (MAT_ELEM_3X3(*mat, 1, 0) * MAT_ELEM_3X3(*mat, 2, 1) - MAT_ELEM_3X3(*mat, 1, 1) * MAT_ELEM_3X3(*mat, 2, 0));
|
||||
MAT_ELEM_3X3(out, 2, 1) = -(MAT_ELEM_3X3(*mat, 0, 0) * MAT_ELEM_3X3(*mat, 2, 1) - MAT_ELEM_3X3(*mat, 0, 1) * MAT_ELEM_3X3(*mat, 2, 0));
|
||||
MAT_ELEM_3X3(out, 2, 2) = (MAT_ELEM_3X3(*mat, 0, 0) * MAT_ELEM_3X3(*mat, 1, 1) - MAT_ELEM_3X3(*mat, 0, 1) * MAT_ELEM_3X3(*mat, 1, 0));
|
||||
|
||||
*mat = out;
|
||||
}
|
||||
|
||||
bool matrix_3x3_invert(math_matrix_3x3 *mat)
|
||||
{
|
||||
float det = matrix_3x3_determinant(mat);
|
||||
|
||||
if (float_is_zero(det))
|
||||
return false;
|
||||
|
||||
matrix_3x3_adjoint(mat);
|
||||
matrix_3x3_divide_scalar(mat, det);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* the following code is Copyright 2009 VMware, Inc. All Rights Reserved.
|
||||
*
|
||||
* 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, sub license, 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 (including the
|
||||
* next paragraph) 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 NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
bool matrix_3x3_square_to_quad(const float dx0, const float dy0,
|
||||
const float dx1, const float dy1,
|
||||
const float dx3, const float dy3,
|
||||
const float dx2, const float dy2,
|
||||
math_matrix_3x3 *mat)
|
||||
{
|
||||
float ax = dx0 - dx1 + dx2 - dx3;
|
||||
float ay = dy0 - dy1 + dy2 - dy3;
|
||||
|
||||
if (float_is_zero(ax) && float_is_zero(ay))
|
||||
{
|
||||
/* affine case */
|
||||
matrix_3x3_inits(mat,
|
||||
dx1 - dx0, dy1 - dy0, 0,
|
||||
dx2 - dx1, dy2 - dy1, 0,
|
||||
dx0, dy0, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
float a, b, c, d, e, f, g, h;
|
||||
float ax1 = dx1 - dx2;
|
||||
float ax2 = dx3 - dx2;
|
||||
float ay1 = dy1 - dy2;
|
||||
float ay2 = dy3 - dy2;
|
||||
|
||||
/* determinants */
|
||||
float gtop = ax * ay2 - ax2 * ay;
|
||||
float htop = ax1 * ay - ax * ay1;
|
||||
float bottom = ax1 * ay2 - ax2 * ay1;
|
||||
|
||||
if (!bottom)
|
||||
return false;
|
||||
|
||||
g = gtop / bottom;
|
||||
h = htop / bottom;
|
||||
|
||||
a = dx1 - dx0 + g * dx1;
|
||||
b = dx3 - dx0 + h * dx3;
|
||||
c = dx0;
|
||||
d = dy1 - dy0 + g * dy1;
|
||||
e = dy3 - dy0 + h * dy3;
|
||||
f = dy0;
|
||||
|
||||
matrix_3x3_inits(mat,
|
||||
a, d, g,
|
||||
b, e, h,
|
||||
c, f, 1.f);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool matrix_3x3_quad_to_square(const float sx0, const float sy0,
|
||||
const float sx1, const float sy1,
|
||||
const float sx2, const float sy2,
|
||||
const float sx3, const float sy3,
|
||||
math_matrix_3x3 *mat)
|
||||
{
|
||||
if (!matrix_3x3_square_to_quad(sx0, sy0, sx1, sy1,
|
||||
sx2, sy2, sx3, sy3,
|
||||
mat))
|
||||
return false;
|
||||
|
||||
return matrix_3x3_invert(mat);
|
||||
}
|
||||
|
||||
bool matrix_3x3_quad_to_quad(const float dx0, const float dy0,
|
||||
const float dx1, const float dy1,
|
||||
const float dx2, const float dy2,
|
||||
const float dx3, const float dy3,
|
||||
const float sx0, const float sy0,
|
||||
const float sx1, const float sy1,
|
||||
const float sx2, const float sy2,
|
||||
const float sx3, const float sy3,
|
||||
math_matrix_3x3 *mat)
|
||||
{
|
||||
math_matrix_3x3 quad_to_square, square_to_quad;
|
||||
|
||||
if (!matrix_3x3_square_to_quad(dx0, dy0, dx1, dy1,
|
||||
dx2, dy2, dx3, dy3,
|
||||
&square_to_quad))
|
||||
return false;
|
||||
|
||||
if (!matrix_3x3_quad_to_square(sx0, sy0, sx1, sy1,
|
||||
sx2, sy2, sx3, sy3,
|
||||
&quad_to_square))
|
||||
return false;
|
||||
|
||||
matrix_3x3_multiply(mat, &quad_to_square, &square_to_quad);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1,192 +1,192 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (matrix.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <gfx/math/matrix_4x4.h>
|
||||
|
||||
/*
|
||||
* Sets mat to an identity matrix
|
||||
*/
|
||||
void matrix_4x4_identity(math_matrix_4x4 *mat)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
memset(mat, 0, sizeof(*mat));
|
||||
for (i = 0; i < 4; i++)
|
||||
MAT_ELEM_4X4(*mat, i, i) = 1.0f;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets out to the transposed matrix of in
|
||||
*/
|
||||
void matrix_4x4_transpose(math_matrix_4x4 *out, const math_matrix_4x4 *in)
|
||||
{
|
||||
unsigned i, j;
|
||||
math_matrix_4x4 mat;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
for (j = 0; j < 4; j++)
|
||||
MAT_ELEM_4X4(mat, j, i) = MAT_ELEM_4X4(*in, i, j);
|
||||
|
||||
*out = mat;
|
||||
}
|
||||
|
||||
/*
|
||||
* Builds an X-axis rotation matrix
|
||||
*/
|
||||
void matrix_4x4_rotate_x(math_matrix_4x4 *mat, float rad)
|
||||
{
|
||||
float cosine = cosf(rad);
|
||||
float sine = sinf(rad);
|
||||
|
||||
matrix_4x4_identity(mat);
|
||||
|
||||
MAT_ELEM_4X4(*mat, 1, 1) = cosine;
|
||||
MAT_ELEM_4X4(*mat, 2, 2) = cosine;
|
||||
MAT_ELEM_4X4(*mat, 1, 2) = -sine;
|
||||
MAT_ELEM_4X4(*mat, 2, 1) = sine;
|
||||
}
|
||||
|
||||
/*
|
||||
* Builds a rotation matrix using the
|
||||
* rotation around the Y-axis.
|
||||
*/
|
||||
void matrix_4x4_rotate_y(math_matrix_4x4 *mat, float rad)
|
||||
{
|
||||
float cosine = cosf(rad);
|
||||
float sine = sinf(rad);
|
||||
|
||||
matrix_4x4_identity(mat);
|
||||
|
||||
MAT_ELEM_4X4(*mat, 0, 0) = cosine;
|
||||
MAT_ELEM_4X4(*mat, 2, 2) = cosine;
|
||||
MAT_ELEM_4X4(*mat, 0, 2) = -sine;
|
||||
MAT_ELEM_4X4(*mat, 2, 0) = sine;
|
||||
}
|
||||
|
||||
/*
|
||||
* Builds a rotation matrix using the
|
||||
* rotation around the Z-axis.
|
||||
*/
|
||||
void matrix_4x4_rotate_z(math_matrix_4x4 *mat, float rad)
|
||||
{
|
||||
float cosine = cosf(rad);
|
||||
float sine = sinf(rad);
|
||||
|
||||
matrix_4x4_identity(mat);
|
||||
|
||||
MAT_ELEM_4X4(*mat, 0, 0) = cosine;
|
||||
MAT_ELEM_4X4(*mat, 1, 1) = cosine;
|
||||
MAT_ELEM_4X4(*mat, 0, 1) = -sine;
|
||||
MAT_ELEM_4X4(*mat, 1, 0) = sine;
|
||||
}
|
||||
|
||||
/*
|
||||
* Creates an orthographic projection matrix.
|
||||
*/
|
||||
void matrix_4x4_ortho(math_matrix_4x4 *mat,
|
||||
float left, float right,
|
||||
float bottom, float top,
|
||||
float znear, float zfar)
|
||||
{
|
||||
float tx, ty, tz;
|
||||
|
||||
matrix_4x4_identity(mat);
|
||||
|
||||
tx = -(right + left) / (right - left);
|
||||
ty = -(top + bottom) / (top - bottom);
|
||||
tz = -(zfar + znear) / (zfar - znear);
|
||||
|
||||
MAT_ELEM_4X4(*mat, 0, 0) = 2.0f / (right - left);
|
||||
MAT_ELEM_4X4(*mat, 1, 1) = 2.0f / (top - bottom);
|
||||
MAT_ELEM_4X4(*mat, 2, 2) = -2.0f / (zfar - znear);
|
||||
MAT_ELEM_4X4(*mat, 0, 3) = tx;
|
||||
MAT_ELEM_4X4(*mat, 1, 3) = ty;
|
||||
MAT_ELEM_4X4(*mat, 2, 3) = tz;
|
||||
}
|
||||
|
||||
void matrix_4x4_scale(math_matrix_4x4 *out, float x, float y,
|
||||
float z)
|
||||
{
|
||||
memset(out, 0, sizeof(*out));
|
||||
MAT_ELEM_4X4(*out, 0, 0) = x;
|
||||
MAT_ELEM_4X4(*out, 1, 1) = y;
|
||||
MAT_ELEM_4X4(*out, 2, 2) = z;
|
||||
MAT_ELEM_4X4(*out, 3, 3) = 1.0f;
|
||||
}
|
||||
|
||||
/*
|
||||
* Builds a translation matrix. All other elements in
|
||||
* the matrix will be set to zero except for the
|
||||
* diagonal which is set to 1.0
|
||||
*/
|
||||
void matrix_4x4_translate(math_matrix_4x4 *out, float x,
|
||||
float y, float z)
|
||||
{
|
||||
matrix_4x4_identity(out);
|
||||
MAT_ELEM_4X4(*out, 0, 3) = x;
|
||||
MAT_ELEM_4X4(*out, 1, 3) = y;
|
||||
MAT_ELEM_4X4(*out, 2, 3) = z;
|
||||
}
|
||||
|
||||
/*
|
||||
* Creates a perspective projection matrix.
|
||||
*/
|
||||
void matrix_4x4_projection(math_matrix_4x4 *out, float znear,
|
||||
float zfar)
|
||||
{
|
||||
float delta_z = zfar - znear;
|
||||
|
||||
memset(out, 0, sizeof(*out));
|
||||
MAT_ELEM_4X4(*out, 0, 0) = znear;
|
||||
MAT_ELEM_4X4(*out, 1, 1) = zfar;
|
||||
MAT_ELEM_4X4(*out, 2, 2) = (zfar + znear) / delta_z;
|
||||
MAT_ELEM_4X4(*out, 2, 3) = -2.0f * zfar * znear / delta_z;
|
||||
MAT_ELEM_4X4(*out, 3, 2) = -1.0f;
|
||||
}
|
||||
|
||||
/*
|
||||
* Multiplies a with b, stores the result in out
|
||||
*/
|
||||
void matrix_4x4_multiply(
|
||||
math_matrix_4x4 *out,
|
||||
const math_matrix_4x4 *a,
|
||||
const math_matrix_4x4 *b)
|
||||
{
|
||||
unsigned r, c, k;
|
||||
math_matrix_4x4 mat;
|
||||
|
||||
for (r = 0; r < 4; r++)
|
||||
{
|
||||
for (c = 0; c < 4; c++)
|
||||
{
|
||||
float dot = 0.0f;
|
||||
for (k = 0; k < 4; k++)
|
||||
dot += MAT_ELEM_4X4(*a, r, k) * MAT_ELEM_4X4(*b, k, c);
|
||||
MAT_ELEM_4X4(mat, r, c) = dot;
|
||||
}
|
||||
}
|
||||
|
||||
*out = mat;
|
||||
}
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (matrix.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <gfx/math/matrix_4x4.h>
|
||||
|
||||
/*
|
||||
* Sets mat to an identity matrix
|
||||
*/
|
||||
void matrix_4x4_identity(math_matrix_4x4 *mat)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
memset(mat, 0, sizeof(*mat));
|
||||
for (i = 0; i < 4; i++)
|
||||
MAT_ELEM_4X4(*mat, i, i) = 1.0f;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets out to the transposed matrix of in
|
||||
*/
|
||||
void matrix_4x4_transpose(math_matrix_4x4 *out, const math_matrix_4x4 *in)
|
||||
{
|
||||
unsigned i, j;
|
||||
math_matrix_4x4 mat;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
for (j = 0; j < 4; j++)
|
||||
MAT_ELEM_4X4(mat, j, i) = MAT_ELEM_4X4(*in, i, j);
|
||||
|
||||
*out = mat;
|
||||
}
|
||||
|
||||
/*
|
||||
* Builds an X-axis rotation matrix
|
||||
*/
|
||||
void matrix_4x4_rotate_x(math_matrix_4x4 *mat, float rad)
|
||||
{
|
||||
float cosine = cosf(rad);
|
||||
float sine = sinf(rad);
|
||||
|
||||
matrix_4x4_identity(mat);
|
||||
|
||||
MAT_ELEM_4X4(*mat, 1, 1) = cosine;
|
||||
MAT_ELEM_4X4(*mat, 2, 2) = cosine;
|
||||
MAT_ELEM_4X4(*mat, 1, 2) = -sine;
|
||||
MAT_ELEM_4X4(*mat, 2, 1) = sine;
|
||||
}
|
||||
|
||||
/*
|
||||
* Builds a rotation matrix using the
|
||||
* rotation around the Y-axis.
|
||||
*/
|
||||
void matrix_4x4_rotate_y(math_matrix_4x4 *mat, float rad)
|
||||
{
|
||||
float cosine = cosf(rad);
|
||||
float sine = sinf(rad);
|
||||
|
||||
matrix_4x4_identity(mat);
|
||||
|
||||
MAT_ELEM_4X4(*mat, 0, 0) = cosine;
|
||||
MAT_ELEM_4X4(*mat, 2, 2) = cosine;
|
||||
MAT_ELEM_4X4(*mat, 0, 2) = -sine;
|
||||
MAT_ELEM_4X4(*mat, 2, 0) = sine;
|
||||
}
|
||||
|
||||
/*
|
||||
* Builds a rotation matrix using the
|
||||
* rotation around the Z-axis.
|
||||
*/
|
||||
void matrix_4x4_rotate_z(math_matrix_4x4 *mat, float rad)
|
||||
{
|
||||
float cosine = cosf(rad);
|
||||
float sine = sinf(rad);
|
||||
|
||||
matrix_4x4_identity(mat);
|
||||
|
||||
MAT_ELEM_4X4(*mat, 0, 0) = cosine;
|
||||
MAT_ELEM_4X4(*mat, 1, 1) = cosine;
|
||||
MAT_ELEM_4X4(*mat, 0, 1) = -sine;
|
||||
MAT_ELEM_4X4(*mat, 1, 0) = sine;
|
||||
}
|
||||
|
||||
/*
|
||||
* Creates an orthographic projection matrix.
|
||||
*/
|
||||
void matrix_4x4_ortho(math_matrix_4x4 *mat,
|
||||
float left, float right,
|
||||
float bottom, float top,
|
||||
float znear, float zfar)
|
||||
{
|
||||
float tx, ty, tz;
|
||||
|
||||
matrix_4x4_identity(mat);
|
||||
|
||||
tx = -(right + left) / (right - left);
|
||||
ty = -(top + bottom) / (top - bottom);
|
||||
tz = -(zfar + znear) / (zfar - znear);
|
||||
|
||||
MAT_ELEM_4X4(*mat, 0, 0) = 2.0f / (right - left);
|
||||
MAT_ELEM_4X4(*mat, 1, 1) = 2.0f / (top - bottom);
|
||||
MAT_ELEM_4X4(*mat, 2, 2) = -2.0f / (zfar - znear);
|
||||
MAT_ELEM_4X4(*mat, 0, 3) = tx;
|
||||
MAT_ELEM_4X4(*mat, 1, 3) = ty;
|
||||
MAT_ELEM_4X4(*mat, 2, 3) = tz;
|
||||
}
|
||||
|
||||
void matrix_4x4_scale(math_matrix_4x4 *out, float x, float y,
|
||||
float z)
|
||||
{
|
||||
memset(out, 0, sizeof(*out));
|
||||
MAT_ELEM_4X4(*out, 0, 0) = x;
|
||||
MAT_ELEM_4X4(*out, 1, 1) = y;
|
||||
MAT_ELEM_4X4(*out, 2, 2) = z;
|
||||
MAT_ELEM_4X4(*out, 3, 3) = 1.0f;
|
||||
}
|
||||
|
||||
/*
|
||||
* Builds a translation matrix. All other elements in
|
||||
* the matrix will be set to zero except for the
|
||||
* diagonal which is set to 1.0
|
||||
*/
|
||||
void matrix_4x4_translate(math_matrix_4x4 *out, float x,
|
||||
float y, float z)
|
||||
{
|
||||
matrix_4x4_identity(out);
|
||||
MAT_ELEM_4X4(*out, 0, 3) = x;
|
||||
MAT_ELEM_4X4(*out, 1, 3) = y;
|
||||
MAT_ELEM_4X4(*out, 2, 3) = z;
|
||||
}
|
||||
|
||||
/*
|
||||
* Creates a perspective projection matrix.
|
||||
*/
|
||||
void matrix_4x4_projection(math_matrix_4x4 *out, float znear,
|
||||
float zfar)
|
||||
{
|
||||
float delta_z = zfar - znear;
|
||||
|
||||
memset(out, 0, sizeof(*out));
|
||||
MAT_ELEM_4X4(*out, 0, 0) = znear;
|
||||
MAT_ELEM_4X4(*out, 1, 1) = zfar;
|
||||
MAT_ELEM_4X4(*out, 2, 2) = (zfar + znear) / delta_z;
|
||||
MAT_ELEM_4X4(*out, 2, 3) = -2.0f * zfar * znear / delta_z;
|
||||
MAT_ELEM_4X4(*out, 3, 2) = -1.0f;
|
||||
}
|
||||
|
||||
/*
|
||||
* Multiplies a with b, stores the result in out
|
||||
*/
|
||||
void matrix_4x4_multiply(
|
||||
math_matrix_4x4 *out,
|
||||
const math_matrix_4x4 *a,
|
||||
const math_matrix_4x4 *b)
|
||||
{
|
||||
unsigned r, c, k;
|
||||
math_matrix_4x4 mat;
|
||||
|
||||
for (r = 0; r < 4; r++)
|
||||
{
|
||||
for (c = 0; c < 4; c++)
|
||||
{
|
||||
float dot = 0.0f;
|
||||
for (k = 0; k < 4; k++)
|
||||
dot += MAT_ELEM_4X4(*a, r, k) * MAT_ELEM_4X4(*b, k, c);
|
||||
MAT_ELEM_4X4(mat, r, c) = dot;
|
||||
}
|
||||
}
|
||||
|
||||
*out = mat;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,379 +1,379 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (scaler.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <gfx/scaler/scaler.h>
|
||||
#include <gfx/scaler/scaler_int.h>
|
||||
#include <gfx/scaler/filter.h>
|
||||
#include <gfx/scaler/pixconv.h>
|
||||
|
||||
/**
|
||||
* scaler_alloc:
|
||||
* @elem_size : size of the elements to be used.
|
||||
* @siz : size of the image that the scaler needs to handle.
|
||||
*
|
||||
* Allocate and returns a scaler object.
|
||||
*
|
||||
* Returns: pointer to a scaler object of type 'void *' on success,
|
||||
* NULL in case of error. Has to be freed manually.
|
||||
**/
|
||||
void *scaler_alloc(size_t elem_size, size_t size)
|
||||
{
|
||||
void *ptr = calloc(elem_size, size);
|
||||
if (!ptr)
|
||||
return NULL;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* scaler_free:
|
||||
* @ptr : pointer to scaler object.
|
||||
*
|
||||
* Frees a scaler object.
|
||||
**/
|
||||
void scaler_free(void *ptr)
|
||||
{
|
||||
if (ptr)
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
static bool allocate_frames(struct scaler_ctx *ctx)
|
||||
{
|
||||
ctx->scaled.stride = ((ctx->out_width + 7) & ~7) * sizeof(uint64_t);
|
||||
ctx->scaled.width = ctx->out_width;
|
||||
ctx->scaled.height = ctx->in_height;
|
||||
ctx->scaled.frame = (uint64_t*)
|
||||
scaler_alloc(sizeof(uint64_t),
|
||||
(ctx->scaled.stride * ctx->scaled.height) >> 3);
|
||||
if (!ctx->scaled.frame)
|
||||
return false;
|
||||
|
||||
if (ctx->in_fmt != SCALER_FMT_ARGB8888)
|
||||
{
|
||||
ctx->input.stride = ((ctx->in_width + 7) & ~7) * sizeof(uint32_t);
|
||||
ctx->input.frame = (uint32_t*)
|
||||
scaler_alloc(sizeof(uint32_t),
|
||||
(ctx->input.stride * ctx->in_height) >> 2);
|
||||
if (!ctx->input.frame)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ctx->out_fmt != SCALER_FMT_ARGB8888)
|
||||
{
|
||||
ctx->output.stride = ((ctx->out_width + 7) & ~7) * sizeof(uint32_t);
|
||||
ctx->output.frame = (uint32_t*)
|
||||
scaler_alloc(sizeof(uint32_t),
|
||||
(ctx->output.stride * ctx->out_height) >> 2);
|
||||
if (!ctx->output.frame)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* set_direct_pix_conv:
|
||||
* @ctx : pointer to scaler context object.
|
||||
*
|
||||
* Bind a pixel converter callback function to the 'direct_pixconv' function pointer
|
||||
* of the scaler context object.
|
||||
*
|
||||
* Returns: true if a pixel converter function callback could be bound, false if not.
|
||||
* If false, the function callback 'direct_pixconv' is still unbound.
|
||||
**/
|
||||
static bool set_direct_pix_conv(struct scaler_ctx *ctx)
|
||||
{
|
||||
if (ctx->in_fmt == ctx->out_fmt)
|
||||
{
|
||||
ctx->direct_pixconv = conv_copy;
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (ctx->in_fmt)
|
||||
{
|
||||
case SCALER_FMT_0RGB1555:
|
||||
switch (ctx->out_fmt)
|
||||
{
|
||||
case SCALER_FMT_ARGB8888:
|
||||
ctx->direct_pixconv = conv_0rgb1555_argb8888;
|
||||
break;
|
||||
case SCALER_FMT_RGB565:
|
||||
ctx->direct_pixconv = conv_0rgb1555_rgb565;
|
||||
break;
|
||||
case SCALER_FMT_BGR24:
|
||||
ctx->direct_pixconv = conv_0rgb1555_bgr24;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SCALER_FMT_RGB565:
|
||||
switch (ctx->out_fmt)
|
||||
{
|
||||
case SCALER_FMT_ARGB8888:
|
||||
ctx->direct_pixconv = conv_rgb565_argb8888;
|
||||
break;
|
||||
case SCALER_FMT_BGR24:
|
||||
ctx->direct_pixconv = conv_rgb565_bgr24;
|
||||
break;
|
||||
case SCALER_FMT_0RGB1555:
|
||||
ctx->direct_pixconv = conv_rgb565_0rgb1555;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SCALER_FMT_BGR24:
|
||||
switch (ctx->out_fmt)
|
||||
{
|
||||
case SCALER_FMT_ARGB8888:
|
||||
ctx->direct_pixconv = conv_bgr24_argb8888;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SCALER_FMT_ARGB8888:
|
||||
switch (ctx->out_fmt)
|
||||
{
|
||||
case SCALER_FMT_0RGB1555:
|
||||
ctx->direct_pixconv = conv_argb8888_0rgb1555;
|
||||
break;
|
||||
case SCALER_FMT_BGR24:
|
||||
ctx->direct_pixconv = conv_argb8888_bgr24;
|
||||
break;
|
||||
case SCALER_FMT_ABGR8888:
|
||||
ctx->direct_pixconv = conv_argb8888_abgr8888;
|
||||
break;
|
||||
case SCALER_FMT_RGBA4444:
|
||||
ctx->direct_pixconv = conv_argb8888_rgba4444;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SCALER_FMT_YUYV:
|
||||
switch (ctx->out_fmt)
|
||||
{
|
||||
case SCALER_FMT_ARGB8888:
|
||||
ctx->direct_pixconv = conv_yuyv_argb8888;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SCALER_FMT_RGBA4444:
|
||||
switch (ctx->out_fmt)
|
||||
{
|
||||
case SCALER_FMT_ARGB8888:
|
||||
ctx->direct_pixconv = conv_rgba4444_argb8888;
|
||||
break;
|
||||
case SCALER_FMT_RGB565:
|
||||
ctx->direct_pixconv = conv_rgba4444_rgb565;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SCALER_FMT_ABGR8888:
|
||||
/* FIXME/TODO */
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ctx->direct_pixconv)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool set_pix_conv(struct scaler_ctx *ctx)
|
||||
{
|
||||
switch (ctx->in_fmt)
|
||||
{
|
||||
case SCALER_FMT_ARGB8888:
|
||||
/* No need to convert :D */
|
||||
break;
|
||||
|
||||
case SCALER_FMT_0RGB1555:
|
||||
ctx->in_pixconv = conv_0rgb1555_argb8888;
|
||||
break;
|
||||
|
||||
case SCALER_FMT_RGB565:
|
||||
ctx->in_pixconv = conv_rgb565_argb8888;
|
||||
break;
|
||||
|
||||
case SCALER_FMT_BGR24:
|
||||
ctx->in_pixconv = conv_bgr24_argb8888;
|
||||
break;
|
||||
|
||||
case SCALER_FMT_RGBA4444:
|
||||
ctx->in_pixconv = conv_rgba4444_argb8888;
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (ctx->out_fmt)
|
||||
{
|
||||
case SCALER_FMT_ARGB8888:
|
||||
/* No need to convert :D */
|
||||
break;
|
||||
|
||||
case SCALER_FMT_RGBA4444:
|
||||
ctx->out_pixconv = conv_argb8888_rgba4444;
|
||||
break;
|
||||
|
||||
case SCALER_FMT_0RGB1555:
|
||||
ctx->out_pixconv = conv_argb8888_0rgb1555;
|
||||
break;
|
||||
|
||||
case SCALER_FMT_BGR24:
|
||||
ctx->out_pixconv = conv_argb8888_bgr24;
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool scaler_ctx_gen_filter(struct scaler_ctx *ctx)
|
||||
{
|
||||
scaler_ctx_gen_reset(ctx);
|
||||
|
||||
if (ctx->in_width == ctx->out_width && ctx->in_height == ctx->out_height)
|
||||
ctx->unscaled = true; /* Only pixel format conversion ... */
|
||||
else
|
||||
{
|
||||
ctx->scaler_horiz = scaler_argb8888_horiz;
|
||||
ctx->scaler_vert = scaler_argb8888_vert;
|
||||
ctx->unscaled = false;
|
||||
}
|
||||
|
||||
ctx->scaler_special = NULL;
|
||||
|
||||
if (!allocate_frames(ctx))
|
||||
return false;
|
||||
|
||||
if (ctx->unscaled)
|
||||
{
|
||||
if (!set_direct_pix_conv(ctx))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!set_pix_conv(ctx))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ctx->unscaled && !scaler_gen_filter(ctx))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void scaler_ctx_gen_reset(struct scaler_ctx *ctx)
|
||||
{
|
||||
scaler_free(ctx->horiz.filter);
|
||||
scaler_free(ctx->horiz.filter_pos);
|
||||
scaler_free(ctx->vert.filter);
|
||||
scaler_free(ctx->vert.filter_pos);
|
||||
scaler_free(ctx->scaled.frame);
|
||||
scaler_free(ctx->input.frame);
|
||||
scaler_free(ctx->output.frame);
|
||||
|
||||
memset(&ctx->horiz, 0, sizeof(ctx->horiz));
|
||||
memset(&ctx->vert, 0, sizeof(ctx->vert));
|
||||
memset(&ctx->scaled, 0, sizeof(ctx->scaled));
|
||||
memset(&ctx->input, 0, sizeof(ctx->input));
|
||||
memset(&ctx->output, 0, sizeof(ctx->output));
|
||||
}
|
||||
|
||||
/**
|
||||
* scaler_ctx_scale:
|
||||
* @ctx : pointer to scaler context object.
|
||||
* @output : pointer to output image.
|
||||
* @input : pointer to input image.
|
||||
*
|
||||
* Scales an input image to an output image.
|
||||
**/
|
||||
void scaler_ctx_scale(struct scaler_ctx *ctx,
|
||||
void *output, const void *input)
|
||||
{
|
||||
const void *input_frame = input;
|
||||
void *output_frame = output;
|
||||
int input_stride = ctx->in_stride;
|
||||
int output_stride = ctx->out_stride;
|
||||
|
||||
if (ctx->unscaled)
|
||||
{
|
||||
/* Just perform straight pixel conversion. */
|
||||
ctx->direct_pixconv(output, input,
|
||||
ctx->out_width, ctx->out_height,
|
||||
ctx->out_stride, ctx->in_stride);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctx->in_fmt != SCALER_FMT_ARGB8888)
|
||||
{
|
||||
ctx->in_pixconv(ctx->input.frame, input,
|
||||
ctx->in_width, ctx->in_height,
|
||||
ctx->input.stride, ctx->in_stride);
|
||||
|
||||
input_frame = ctx->input.frame;
|
||||
input_stride = ctx->input.stride;
|
||||
}
|
||||
|
||||
if (ctx->out_fmt != SCALER_FMT_ARGB8888)
|
||||
{
|
||||
output_frame = ctx->output.frame;
|
||||
output_stride = ctx->output.stride;
|
||||
}
|
||||
|
||||
if (ctx->scaler_special)
|
||||
{
|
||||
/* Take some special, and (hopefully) more optimized path. */
|
||||
ctx->scaler_special(ctx, output_frame, input_frame,
|
||||
ctx->out_width, ctx->out_height,
|
||||
ctx->in_width, ctx->in_height,
|
||||
output_stride, input_stride);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Take generic filter path. */
|
||||
if (ctx->scaler_horiz)
|
||||
ctx->scaler_horiz(ctx, input_frame, input_stride);
|
||||
if (ctx->scaler_vert)
|
||||
ctx->scaler_vert (ctx, output, output_stride);
|
||||
}
|
||||
|
||||
if (ctx->out_fmt != SCALER_FMT_ARGB8888)
|
||||
ctx->out_pixconv(output, ctx->output.frame,
|
||||
ctx->out_width, ctx->out_height,
|
||||
ctx->out_stride, ctx->output.stride);
|
||||
}
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (scaler.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <gfx/scaler/scaler.h>
|
||||
#include <gfx/scaler/scaler_int.h>
|
||||
#include <gfx/scaler/filter.h>
|
||||
#include <gfx/scaler/pixconv.h>
|
||||
|
||||
/**
|
||||
* scaler_alloc:
|
||||
* @elem_size : size of the elements to be used.
|
||||
* @siz : size of the image that the scaler needs to handle.
|
||||
*
|
||||
* Allocate and returns a scaler object.
|
||||
*
|
||||
* Returns: pointer to a scaler object of type 'void *' on success,
|
||||
* NULL in case of error. Has to be freed manually.
|
||||
**/
|
||||
void *scaler_alloc(size_t elem_size, size_t size)
|
||||
{
|
||||
void *ptr = calloc(elem_size, size);
|
||||
if (!ptr)
|
||||
return NULL;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* scaler_free:
|
||||
* @ptr : pointer to scaler object.
|
||||
*
|
||||
* Frees a scaler object.
|
||||
**/
|
||||
void scaler_free(void *ptr)
|
||||
{
|
||||
if (ptr)
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
static bool allocate_frames(struct scaler_ctx *ctx)
|
||||
{
|
||||
ctx->scaled.stride = ((ctx->out_width + 7) & ~7) * sizeof(uint64_t);
|
||||
ctx->scaled.width = ctx->out_width;
|
||||
ctx->scaled.height = ctx->in_height;
|
||||
ctx->scaled.frame = (uint64_t*)
|
||||
scaler_alloc(sizeof(uint64_t),
|
||||
(ctx->scaled.stride * ctx->scaled.height) >> 3);
|
||||
if (!ctx->scaled.frame)
|
||||
return false;
|
||||
|
||||
if (ctx->in_fmt != SCALER_FMT_ARGB8888)
|
||||
{
|
||||
ctx->input.stride = ((ctx->in_width + 7) & ~7) * sizeof(uint32_t);
|
||||
ctx->input.frame = (uint32_t*)
|
||||
scaler_alloc(sizeof(uint32_t),
|
||||
(ctx->input.stride * ctx->in_height) >> 2);
|
||||
if (!ctx->input.frame)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ctx->out_fmt != SCALER_FMT_ARGB8888)
|
||||
{
|
||||
ctx->output.stride = ((ctx->out_width + 7) & ~7) * sizeof(uint32_t);
|
||||
ctx->output.frame = (uint32_t*)
|
||||
scaler_alloc(sizeof(uint32_t),
|
||||
(ctx->output.stride * ctx->out_height) >> 2);
|
||||
if (!ctx->output.frame)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* set_direct_pix_conv:
|
||||
* @ctx : pointer to scaler context object.
|
||||
*
|
||||
* Bind a pixel converter callback function to the 'direct_pixconv' function pointer
|
||||
* of the scaler context object.
|
||||
*
|
||||
* Returns: true if a pixel converter function callback could be bound, false if not.
|
||||
* If false, the function callback 'direct_pixconv' is still unbound.
|
||||
**/
|
||||
static bool set_direct_pix_conv(struct scaler_ctx *ctx)
|
||||
{
|
||||
if (ctx->in_fmt == ctx->out_fmt)
|
||||
{
|
||||
ctx->direct_pixconv = conv_copy;
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (ctx->in_fmt)
|
||||
{
|
||||
case SCALER_FMT_0RGB1555:
|
||||
switch (ctx->out_fmt)
|
||||
{
|
||||
case SCALER_FMT_ARGB8888:
|
||||
ctx->direct_pixconv = conv_0rgb1555_argb8888;
|
||||
break;
|
||||
case SCALER_FMT_RGB565:
|
||||
ctx->direct_pixconv = conv_0rgb1555_rgb565;
|
||||
break;
|
||||
case SCALER_FMT_BGR24:
|
||||
ctx->direct_pixconv = conv_0rgb1555_bgr24;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SCALER_FMT_RGB565:
|
||||
switch (ctx->out_fmt)
|
||||
{
|
||||
case SCALER_FMT_ARGB8888:
|
||||
ctx->direct_pixconv = conv_rgb565_argb8888;
|
||||
break;
|
||||
case SCALER_FMT_BGR24:
|
||||
ctx->direct_pixconv = conv_rgb565_bgr24;
|
||||
break;
|
||||
case SCALER_FMT_0RGB1555:
|
||||
ctx->direct_pixconv = conv_rgb565_0rgb1555;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SCALER_FMT_BGR24:
|
||||
switch (ctx->out_fmt)
|
||||
{
|
||||
case SCALER_FMT_ARGB8888:
|
||||
ctx->direct_pixconv = conv_bgr24_argb8888;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SCALER_FMT_ARGB8888:
|
||||
switch (ctx->out_fmt)
|
||||
{
|
||||
case SCALER_FMT_0RGB1555:
|
||||
ctx->direct_pixconv = conv_argb8888_0rgb1555;
|
||||
break;
|
||||
case SCALER_FMT_BGR24:
|
||||
ctx->direct_pixconv = conv_argb8888_bgr24;
|
||||
break;
|
||||
case SCALER_FMT_ABGR8888:
|
||||
ctx->direct_pixconv = conv_argb8888_abgr8888;
|
||||
break;
|
||||
case SCALER_FMT_RGBA4444:
|
||||
ctx->direct_pixconv = conv_argb8888_rgba4444;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SCALER_FMT_YUYV:
|
||||
switch (ctx->out_fmt)
|
||||
{
|
||||
case SCALER_FMT_ARGB8888:
|
||||
ctx->direct_pixconv = conv_yuyv_argb8888;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SCALER_FMT_RGBA4444:
|
||||
switch (ctx->out_fmt)
|
||||
{
|
||||
case SCALER_FMT_ARGB8888:
|
||||
ctx->direct_pixconv = conv_rgba4444_argb8888;
|
||||
break;
|
||||
case SCALER_FMT_RGB565:
|
||||
ctx->direct_pixconv = conv_rgba4444_rgb565;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SCALER_FMT_ABGR8888:
|
||||
/* FIXME/TODO */
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ctx->direct_pixconv)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool set_pix_conv(struct scaler_ctx *ctx)
|
||||
{
|
||||
switch (ctx->in_fmt)
|
||||
{
|
||||
case SCALER_FMT_ARGB8888:
|
||||
/* No need to convert :D */
|
||||
break;
|
||||
|
||||
case SCALER_FMT_0RGB1555:
|
||||
ctx->in_pixconv = conv_0rgb1555_argb8888;
|
||||
break;
|
||||
|
||||
case SCALER_FMT_RGB565:
|
||||
ctx->in_pixconv = conv_rgb565_argb8888;
|
||||
break;
|
||||
|
||||
case SCALER_FMT_BGR24:
|
||||
ctx->in_pixconv = conv_bgr24_argb8888;
|
||||
break;
|
||||
|
||||
case SCALER_FMT_RGBA4444:
|
||||
ctx->in_pixconv = conv_rgba4444_argb8888;
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (ctx->out_fmt)
|
||||
{
|
||||
case SCALER_FMT_ARGB8888:
|
||||
/* No need to convert :D */
|
||||
break;
|
||||
|
||||
case SCALER_FMT_RGBA4444:
|
||||
ctx->out_pixconv = conv_argb8888_rgba4444;
|
||||
break;
|
||||
|
||||
case SCALER_FMT_0RGB1555:
|
||||
ctx->out_pixconv = conv_argb8888_0rgb1555;
|
||||
break;
|
||||
|
||||
case SCALER_FMT_BGR24:
|
||||
ctx->out_pixconv = conv_argb8888_bgr24;
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool scaler_ctx_gen_filter(struct scaler_ctx *ctx)
|
||||
{
|
||||
scaler_ctx_gen_reset(ctx);
|
||||
|
||||
if (ctx->in_width == ctx->out_width && ctx->in_height == ctx->out_height)
|
||||
ctx->unscaled = true; /* Only pixel format conversion ... */
|
||||
else
|
||||
{
|
||||
ctx->scaler_horiz = scaler_argb8888_horiz;
|
||||
ctx->scaler_vert = scaler_argb8888_vert;
|
||||
ctx->unscaled = false;
|
||||
}
|
||||
|
||||
ctx->scaler_special = NULL;
|
||||
|
||||
if (!allocate_frames(ctx))
|
||||
return false;
|
||||
|
||||
if (ctx->unscaled)
|
||||
{
|
||||
if (!set_direct_pix_conv(ctx))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!set_pix_conv(ctx))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ctx->unscaled && !scaler_gen_filter(ctx))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void scaler_ctx_gen_reset(struct scaler_ctx *ctx)
|
||||
{
|
||||
scaler_free(ctx->horiz.filter);
|
||||
scaler_free(ctx->horiz.filter_pos);
|
||||
scaler_free(ctx->vert.filter);
|
||||
scaler_free(ctx->vert.filter_pos);
|
||||
scaler_free(ctx->scaled.frame);
|
||||
scaler_free(ctx->input.frame);
|
||||
scaler_free(ctx->output.frame);
|
||||
|
||||
memset(&ctx->horiz, 0, sizeof(ctx->horiz));
|
||||
memset(&ctx->vert, 0, sizeof(ctx->vert));
|
||||
memset(&ctx->scaled, 0, sizeof(ctx->scaled));
|
||||
memset(&ctx->input, 0, sizeof(ctx->input));
|
||||
memset(&ctx->output, 0, sizeof(ctx->output));
|
||||
}
|
||||
|
||||
/**
|
||||
* scaler_ctx_scale:
|
||||
* @ctx : pointer to scaler context object.
|
||||
* @output : pointer to output image.
|
||||
* @input : pointer to input image.
|
||||
*
|
||||
* Scales an input image to an output image.
|
||||
**/
|
||||
void scaler_ctx_scale(struct scaler_ctx *ctx,
|
||||
void *output, const void *input)
|
||||
{
|
||||
const void *input_frame = input;
|
||||
void *output_frame = output;
|
||||
int input_stride = ctx->in_stride;
|
||||
int output_stride = ctx->out_stride;
|
||||
|
||||
if (ctx->unscaled)
|
||||
{
|
||||
/* Just perform straight pixel conversion. */
|
||||
ctx->direct_pixconv(output, input,
|
||||
ctx->out_width, ctx->out_height,
|
||||
ctx->out_stride, ctx->in_stride);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctx->in_fmt != SCALER_FMT_ARGB8888)
|
||||
{
|
||||
ctx->in_pixconv(ctx->input.frame, input,
|
||||
ctx->in_width, ctx->in_height,
|
||||
ctx->input.stride, ctx->in_stride);
|
||||
|
||||
input_frame = ctx->input.frame;
|
||||
input_stride = ctx->input.stride;
|
||||
}
|
||||
|
||||
if (ctx->out_fmt != SCALER_FMT_ARGB8888)
|
||||
{
|
||||
output_frame = ctx->output.frame;
|
||||
output_stride = ctx->output.stride;
|
||||
}
|
||||
|
||||
if (ctx->scaler_special)
|
||||
{
|
||||
/* Take some special, and (hopefully) more optimized path. */
|
||||
ctx->scaler_special(ctx, output_frame, input_frame,
|
||||
ctx->out_width, ctx->out_height,
|
||||
ctx->in_width, ctx->in_height,
|
||||
output_stride, input_stride);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Take generic filter path. */
|
||||
if (ctx->scaler_horiz)
|
||||
ctx->scaler_horiz(ctx, input_frame, input_stride);
|
||||
if (ctx->scaler_vert)
|
||||
ctx->scaler_vert (ctx, output, output_stride);
|
||||
}
|
||||
|
||||
if (ctx->out_fmt != SCALER_FMT_ARGB8888)
|
||||
ctx->out_pixconv(output, ctx->output.frame,
|
||||
ctx->out_width, ctx->out_height,
|
||||
ctx->out_stride, ctx->output.stride);
|
||||
}
|
||||
|
|
|
@ -1,278 +1,278 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (scaler_filter.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <gfx/scaler/filter.h>
|
||||
#include <gfx/scaler/scaler_int.h>
|
||||
#include <retro_miscellaneous.h>
|
||||
#include <retro_inline.h>
|
||||
#include <filters.h>
|
||||
|
||||
static bool allocate_filters(struct scaler_ctx *ctx)
|
||||
{
|
||||
ctx->horiz.filter = (int16_t*)scaler_alloc(sizeof(int16_t), ctx->horiz.filter_stride * ctx->out_width);
|
||||
ctx->horiz.filter_pos = (int*)scaler_alloc(sizeof(int), ctx->out_width);
|
||||
|
||||
ctx->vert.filter = (int16_t*)scaler_alloc(sizeof(int16_t), ctx->vert.filter_stride * ctx->out_height);
|
||||
ctx->vert.filter_pos = (int*)scaler_alloc(sizeof(int), ctx->out_height);
|
||||
|
||||
return ctx->horiz.filter && ctx->vert.filter;
|
||||
}
|
||||
|
||||
static void gen_filter_point_sub(struct scaler_filter *filter,
|
||||
int len, int pos, int step)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < len; i++, pos += step)
|
||||
{
|
||||
filter->filter_pos[i] = pos >> 16;
|
||||
filter->filter[i] = FILTER_UNITY;
|
||||
}
|
||||
}
|
||||
|
||||
static bool gen_filter_point(struct scaler_ctx *ctx)
|
||||
{
|
||||
int x_pos, x_step, y_pos, y_step;
|
||||
|
||||
ctx->horiz.filter_len = 1;
|
||||
ctx->horiz.filter_stride = 1;
|
||||
ctx->vert.filter_len = 1;
|
||||
ctx->vert.filter_stride = 1;
|
||||
|
||||
if (!allocate_filters(ctx))
|
||||
return false;
|
||||
|
||||
x_pos = (1 << 15) * ctx->in_width / ctx->out_width - (1 << 15);
|
||||
x_step = (1 << 16) * ctx->in_width / ctx->out_width;
|
||||
y_pos = (1 << 15) * ctx->in_height / ctx->out_height - (1 << 15);
|
||||
y_step = (1 << 16) * ctx->in_height / ctx->out_height;
|
||||
|
||||
gen_filter_point_sub(&ctx->horiz, ctx->out_width, x_pos, x_step);
|
||||
gen_filter_point_sub(&ctx->vert, ctx->out_height, y_pos, y_step);
|
||||
|
||||
ctx->scaler_special = scaler_argb8888_point_special;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void gen_filter_bilinear_sub(struct scaler_filter *filter,
|
||||
int len, int pos, int step)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < len; i++, pos += step)
|
||||
{
|
||||
filter->filter_pos[i] = pos >> 16;
|
||||
filter->filter[i * 2 + 1] = (pos & 0xffff) >> 2;
|
||||
filter->filter[i * 2 + 0] = FILTER_UNITY - filter->filter[i * 2 + 1];
|
||||
}
|
||||
}
|
||||
|
||||
static bool gen_filter_bilinear(struct scaler_ctx *ctx)
|
||||
{
|
||||
int x_pos, x_step, y_pos, y_step;
|
||||
|
||||
ctx->horiz.filter_len = 2;
|
||||
ctx->horiz.filter_stride = 2;
|
||||
ctx->vert.filter_len = 2;
|
||||
ctx->vert.filter_stride = 2;
|
||||
|
||||
if (!allocate_filters(ctx))
|
||||
return false;
|
||||
|
||||
x_pos = (1 << 15) * ctx->in_width / ctx->out_width - (1 << 15);
|
||||
x_step = (1 << 16) * ctx->in_width / ctx->out_width;
|
||||
y_pos = (1 << 15) * ctx->in_height / ctx->out_height - (1 << 15);
|
||||
y_step = (1 << 16) * ctx->in_height / ctx->out_height;
|
||||
|
||||
gen_filter_bilinear_sub(&ctx->horiz, ctx->out_width, x_pos, x_step);
|
||||
gen_filter_bilinear_sub(&ctx->vert, ctx->out_height, y_pos, y_step);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void gen_filter_sinc_sub(struct scaler_filter *filter,
|
||||
int len, int pos, int step, double phase_mul)
|
||||
{
|
||||
int i, j;
|
||||
const int sinc_size = filter->filter_len;
|
||||
|
||||
for (i = 0; i < len; i++, pos += step)
|
||||
{
|
||||
filter->filter_pos[i] = pos >> 16;
|
||||
|
||||
for (j = 0; j < sinc_size; j++)
|
||||
{
|
||||
double sinc_phase = M_PI * ((double)((sinc_size << 15) + (pos & 0xffff)) / 0x10000 - j);
|
||||
double lanczos_phase = sinc_phase / ((sinc_size >> 1));
|
||||
int16_t sinc_val = FILTER_UNITY * sinc(sinc_phase * phase_mul) * sinc(lanczos_phase) * phase_mul;
|
||||
|
||||
filter->filter[i * sinc_size + j] = sinc_val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool gen_filter_sinc(struct scaler_ctx *ctx)
|
||||
{
|
||||
int x_pos, x_step, y_pos, y_step;
|
||||
double phase_mul_horiz, phase_mul_vert;
|
||||
/* Need to expand the filter when downsampling
|
||||
* to get a proper low-pass effect. */
|
||||
const int sinc_size = 8 * ((ctx->in_width > ctx->out_width)
|
||||
? next_pow2(ctx->in_width / ctx->out_width) : 1);
|
||||
|
||||
ctx->horiz.filter_len = sinc_size;
|
||||
ctx->horiz.filter_stride = sinc_size;
|
||||
ctx->vert.filter_len = sinc_size;
|
||||
ctx->vert.filter_stride = sinc_size;
|
||||
|
||||
if (!allocate_filters(ctx))
|
||||
return false;
|
||||
|
||||
x_pos = (1 << 15) * ctx->in_width / ctx->out_width - (1 << 15) - (sinc_size << 15);
|
||||
x_step = (1 << 16) * ctx->in_width / ctx->out_width;
|
||||
y_pos = (1 << 15) * ctx->in_height / ctx->out_height - (1 << 15) - (sinc_size << 15);
|
||||
y_step = (1 << 16) * ctx->in_height / ctx->out_height;
|
||||
|
||||
phase_mul_horiz = ctx->in_width > ctx->out_width ? (double)ctx->out_width / ctx->in_width : 1.0;
|
||||
phase_mul_vert = ctx->in_height > ctx->out_height ? (double)ctx->out_height / ctx->in_height : 1.0;
|
||||
|
||||
gen_filter_sinc_sub(&ctx->horiz, ctx->out_width, x_pos, x_step, phase_mul_horiz);
|
||||
gen_filter_sinc_sub(&ctx->vert, ctx->out_height, y_pos, y_step, phase_mul_vert);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool validate_filter(struct scaler_ctx *ctx)
|
||||
{
|
||||
int i;
|
||||
int max_h_pos;
|
||||
int max_w_pos = ctx->in_width - ctx->horiz.filter_len;
|
||||
|
||||
for (i = 0; i < ctx->out_width; i++)
|
||||
{
|
||||
if (ctx->horiz.filter_pos[i] > max_w_pos || ctx->horiz.filter_pos[i] < 0)
|
||||
{
|
||||
fprintf(stderr, "Out X = %d => In X = %d\n", i, ctx->horiz.filter_pos[i]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
max_h_pos = ctx->in_height - ctx->vert.filter_len;
|
||||
|
||||
for (i = 0; i < ctx->out_height; i++)
|
||||
{
|
||||
if (ctx->vert.filter_pos[i] > max_h_pos || ctx->vert.filter_pos[i] < 0)
|
||||
{
|
||||
fprintf(stderr, "Out Y = %d => In Y = %d\n", i, ctx->vert.filter_pos[i]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void fixup_filter_sub(struct scaler_filter *filter, int out_len, int in_len)
|
||||
{
|
||||
int i;
|
||||
int max_pos = in_len - filter->filter_len;
|
||||
|
||||
for (i = 0; i < out_len; i++)
|
||||
{
|
||||
int postsample = filter->filter_pos[i] - max_pos;
|
||||
int presample = -filter->filter_pos[i];
|
||||
|
||||
if (postsample > 0)
|
||||
{
|
||||
int16_t *base_filter = NULL;
|
||||
filter->filter_pos[i] -= postsample;
|
||||
|
||||
base_filter = filter->filter + i * filter->filter_stride;
|
||||
|
||||
if (postsample > (int)filter->filter_len)
|
||||
memset(base_filter, 0, filter->filter_len * sizeof(int16_t));
|
||||
else
|
||||
{
|
||||
memmove(base_filter + postsample, base_filter,
|
||||
(filter->filter_len - postsample) * sizeof(int16_t));
|
||||
memset(base_filter, 0, postsample * sizeof(int16_t));
|
||||
}
|
||||
}
|
||||
|
||||
if (presample > 0)
|
||||
{
|
||||
int16_t *base_filter = NULL;
|
||||
filter->filter_pos[i] += presample;
|
||||
base_filter = filter->filter + i * filter->filter_stride;
|
||||
|
||||
if (presample > (int)filter->filter_len)
|
||||
memset(base_filter, 0, filter->filter_len * sizeof(int16_t));
|
||||
else
|
||||
{
|
||||
memmove(base_filter, base_filter + presample,
|
||||
(filter->filter_len - presample) * sizeof(int16_t));
|
||||
memset(base_filter + (filter->filter_len - presample), 0, presample * sizeof(int16_t));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Makes sure that we never sample outside our rectangle. */
|
||||
static void fixup_filter(struct scaler_ctx *ctx)
|
||||
{
|
||||
fixup_filter_sub(&ctx->horiz, ctx->out_width, ctx->in_width);
|
||||
fixup_filter_sub(&ctx->vert, ctx->out_height, ctx->in_height);
|
||||
}
|
||||
|
||||
|
||||
bool scaler_gen_filter(struct scaler_ctx *ctx)
|
||||
{
|
||||
bool ret = true;
|
||||
|
||||
switch (ctx->scaler_type)
|
||||
{
|
||||
case SCALER_TYPE_POINT:
|
||||
ret = gen_filter_point(ctx);
|
||||
break;
|
||||
|
||||
case SCALER_TYPE_BILINEAR:
|
||||
ret = gen_filter_bilinear(ctx);
|
||||
break;
|
||||
|
||||
case SCALER_TYPE_SINC:
|
||||
ret = gen_filter_sinc(ctx);
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
return false;
|
||||
|
||||
fixup_filter(ctx);
|
||||
|
||||
return validate_filter(ctx);
|
||||
}
|
||||
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (scaler_filter.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <gfx/scaler/filter.h>
|
||||
#include <gfx/scaler/scaler_int.h>
|
||||
#include <retro_miscellaneous.h>
|
||||
#include <retro_inline.h>
|
||||
#include <filters.h>
|
||||
|
||||
static bool allocate_filters(struct scaler_ctx *ctx)
|
||||
{
|
||||
ctx->horiz.filter = (int16_t*)scaler_alloc(sizeof(int16_t), ctx->horiz.filter_stride * ctx->out_width);
|
||||
ctx->horiz.filter_pos = (int*)scaler_alloc(sizeof(int), ctx->out_width);
|
||||
|
||||
ctx->vert.filter = (int16_t*)scaler_alloc(sizeof(int16_t), ctx->vert.filter_stride * ctx->out_height);
|
||||
ctx->vert.filter_pos = (int*)scaler_alloc(sizeof(int), ctx->out_height);
|
||||
|
||||
return ctx->horiz.filter && ctx->vert.filter;
|
||||
}
|
||||
|
||||
static void gen_filter_point_sub(struct scaler_filter *filter,
|
||||
int len, int pos, int step)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < len; i++, pos += step)
|
||||
{
|
||||
filter->filter_pos[i] = pos >> 16;
|
||||
filter->filter[i] = FILTER_UNITY;
|
||||
}
|
||||
}
|
||||
|
||||
static bool gen_filter_point(struct scaler_ctx *ctx)
|
||||
{
|
||||
int x_pos, x_step, y_pos, y_step;
|
||||
|
||||
ctx->horiz.filter_len = 1;
|
||||
ctx->horiz.filter_stride = 1;
|
||||
ctx->vert.filter_len = 1;
|
||||
ctx->vert.filter_stride = 1;
|
||||
|
||||
if (!allocate_filters(ctx))
|
||||
return false;
|
||||
|
||||
x_pos = (1 << 15) * ctx->in_width / ctx->out_width - (1 << 15);
|
||||
x_step = (1 << 16) * ctx->in_width / ctx->out_width;
|
||||
y_pos = (1 << 15) * ctx->in_height / ctx->out_height - (1 << 15);
|
||||
y_step = (1 << 16) * ctx->in_height / ctx->out_height;
|
||||
|
||||
gen_filter_point_sub(&ctx->horiz, ctx->out_width, x_pos, x_step);
|
||||
gen_filter_point_sub(&ctx->vert, ctx->out_height, y_pos, y_step);
|
||||
|
||||
ctx->scaler_special = scaler_argb8888_point_special;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void gen_filter_bilinear_sub(struct scaler_filter *filter,
|
||||
int len, int pos, int step)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < len; i++, pos += step)
|
||||
{
|
||||
filter->filter_pos[i] = pos >> 16;
|
||||
filter->filter[i * 2 + 1] = (pos & 0xffff) >> 2;
|
||||
filter->filter[i * 2 + 0] = FILTER_UNITY - filter->filter[i * 2 + 1];
|
||||
}
|
||||
}
|
||||
|
||||
static bool gen_filter_bilinear(struct scaler_ctx *ctx)
|
||||
{
|
||||
int x_pos, x_step, y_pos, y_step;
|
||||
|
||||
ctx->horiz.filter_len = 2;
|
||||
ctx->horiz.filter_stride = 2;
|
||||
ctx->vert.filter_len = 2;
|
||||
ctx->vert.filter_stride = 2;
|
||||
|
||||
if (!allocate_filters(ctx))
|
||||
return false;
|
||||
|
||||
x_pos = (1 << 15) * ctx->in_width / ctx->out_width - (1 << 15);
|
||||
x_step = (1 << 16) * ctx->in_width / ctx->out_width;
|
||||
y_pos = (1 << 15) * ctx->in_height / ctx->out_height - (1 << 15);
|
||||
y_step = (1 << 16) * ctx->in_height / ctx->out_height;
|
||||
|
||||
gen_filter_bilinear_sub(&ctx->horiz, ctx->out_width, x_pos, x_step);
|
||||
gen_filter_bilinear_sub(&ctx->vert, ctx->out_height, y_pos, y_step);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void gen_filter_sinc_sub(struct scaler_filter *filter,
|
||||
int len, int pos, int step, double phase_mul)
|
||||
{
|
||||
int i, j;
|
||||
const int sinc_size = filter->filter_len;
|
||||
|
||||
for (i = 0; i < len; i++, pos += step)
|
||||
{
|
||||
filter->filter_pos[i] = pos >> 16;
|
||||
|
||||
for (j = 0; j < sinc_size; j++)
|
||||
{
|
||||
double sinc_phase = M_PI * ((double)((sinc_size << 15) + (pos & 0xffff)) / 0x10000 - j);
|
||||
double lanczos_phase = sinc_phase / ((sinc_size >> 1));
|
||||
int16_t sinc_val = FILTER_UNITY * sinc(sinc_phase * phase_mul) * sinc(lanczos_phase) * phase_mul;
|
||||
|
||||
filter->filter[i * sinc_size + j] = sinc_val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool gen_filter_sinc(struct scaler_ctx *ctx)
|
||||
{
|
||||
int x_pos, x_step, y_pos, y_step;
|
||||
double phase_mul_horiz, phase_mul_vert;
|
||||
/* Need to expand the filter when downsampling
|
||||
* to get a proper low-pass effect. */
|
||||
const int sinc_size = 8 * ((ctx->in_width > ctx->out_width)
|
||||
? next_pow2(ctx->in_width / ctx->out_width) : 1);
|
||||
|
||||
ctx->horiz.filter_len = sinc_size;
|
||||
ctx->horiz.filter_stride = sinc_size;
|
||||
ctx->vert.filter_len = sinc_size;
|
||||
ctx->vert.filter_stride = sinc_size;
|
||||
|
||||
if (!allocate_filters(ctx))
|
||||
return false;
|
||||
|
||||
x_pos = (1 << 15) * ctx->in_width / ctx->out_width - (1 << 15) - (sinc_size << 15);
|
||||
x_step = (1 << 16) * ctx->in_width / ctx->out_width;
|
||||
y_pos = (1 << 15) * ctx->in_height / ctx->out_height - (1 << 15) - (sinc_size << 15);
|
||||
y_step = (1 << 16) * ctx->in_height / ctx->out_height;
|
||||
|
||||
phase_mul_horiz = ctx->in_width > ctx->out_width ? (double)ctx->out_width / ctx->in_width : 1.0;
|
||||
phase_mul_vert = ctx->in_height > ctx->out_height ? (double)ctx->out_height / ctx->in_height : 1.0;
|
||||
|
||||
gen_filter_sinc_sub(&ctx->horiz, ctx->out_width, x_pos, x_step, phase_mul_horiz);
|
||||
gen_filter_sinc_sub(&ctx->vert, ctx->out_height, y_pos, y_step, phase_mul_vert);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool validate_filter(struct scaler_ctx *ctx)
|
||||
{
|
||||
int i;
|
||||
int max_h_pos;
|
||||
int max_w_pos = ctx->in_width - ctx->horiz.filter_len;
|
||||
|
||||
for (i = 0; i < ctx->out_width; i++)
|
||||
{
|
||||
if (ctx->horiz.filter_pos[i] > max_w_pos || ctx->horiz.filter_pos[i] < 0)
|
||||
{
|
||||
fprintf(stderr, "Out X = %d => In X = %d\n", i, ctx->horiz.filter_pos[i]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
max_h_pos = ctx->in_height - ctx->vert.filter_len;
|
||||
|
||||
for (i = 0; i < ctx->out_height; i++)
|
||||
{
|
||||
if (ctx->vert.filter_pos[i] > max_h_pos || ctx->vert.filter_pos[i] < 0)
|
||||
{
|
||||
fprintf(stderr, "Out Y = %d => In Y = %d\n", i, ctx->vert.filter_pos[i]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void fixup_filter_sub(struct scaler_filter *filter, int out_len, int in_len)
|
||||
{
|
||||
int i;
|
||||
int max_pos = in_len - filter->filter_len;
|
||||
|
||||
for (i = 0; i < out_len; i++)
|
||||
{
|
||||
int postsample = filter->filter_pos[i] - max_pos;
|
||||
int presample = -filter->filter_pos[i];
|
||||
|
||||
if (postsample > 0)
|
||||
{
|
||||
int16_t *base_filter = NULL;
|
||||
filter->filter_pos[i] -= postsample;
|
||||
|
||||
base_filter = filter->filter + i * filter->filter_stride;
|
||||
|
||||
if (postsample > (int)filter->filter_len)
|
||||
memset(base_filter, 0, filter->filter_len * sizeof(int16_t));
|
||||
else
|
||||
{
|
||||
memmove(base_filter + postsample, base_filter,
|
||||
(filter->filter_len - postsample) * sizeof(int16_t));
|
||||
memset(base_filter, 0, postsample * sizeof(int16_t));
|
||||
}
|
||||
}
|
||||
|
||||
if (presample > 0)
|
||||
{
|
||||
int16_t *base_filter = NULL;
|
||||
filter->filter_pos[i] += presample;
|
||||
base_filter = filter->filter + i * filter->filter_stride;
|
||||
|
||||
if (presample > (int)filter->filter_len)
|
||||
memset(base_filter, 0, filter->filter_len * sizeof(int16_t));
|
||||
else
|
||||
{
|
||||
memmove(base_filter, base_filter + presample,
|
||||
(filter->filter_len - presample) * sizeof(int16_t));
|
||||
memset(base_filter + (filter->filter_len - presample), 0, presample * sizeof(int16_t));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Makes sure that we never sample outside our rectangle. */
|
||||
static void fixup_filter(struct scaler_ctx *ctx)
|
||||
{
|
||||
fixup_filter_sub(&ctx->horiz, ctx->out_width, ctx->in_width);
|
||||
fixup_filter_sub(&ctx->vert, ctx->out_height, ctx->in_height);
|
||||
}
|
||||
|
||||
|
||||
bool scaler_gen_filter(struct scaler_ctx *ctx)
|
||||
{
|
||||
bool ret = true;
|
||||
|
||||
switch (ctx->scaler_type)
|
||||
{
|
||||
case SCALER_TYPE_POINT:
|
||||
ret = gen_filter_point(ctx);
|
||||
break;
|
||||
|
||||
case SCALER_TYPE_BILINEAR:
|
||||
ret = gen_filter_bilinear(ctx);
|
||||
break;
|
||||
|
||||
case SCALER_TYPE_SINC:
|
||||
ret = gen_filter_sinc(ctx);
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
return false;
|
||||
|
||||
fixup_filter(ctx);
|
||||
|
||||
return validate_filter(ctx);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,285 +1,285 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (scaler_int.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <gfx/scaler/scaler_int.h>
|
||||
|
||||
#include <retro_inline.h>
|
||||
|
||||
#ifdef SCALER_NO_SIMD
|
||||
#undef __SSE2__
|
||||
#endif
|
||||
|
||||
#if defined(__SSE2__)
|
||||
#include <emmintrin.h>
|
||||
#ifdef _WIN32
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* ARGB8888 scaler is split in two:
|
||||
*
|
||||
* First, horizontal scaler is applied.
|
||||
* Here, all 8-bit channels are expanded to 16-bit. Values are then shifted 7 to left to occupy 15 bits.
|
||||
* The sign bit is kept empty as we have to do signed multiplication for the filter.
|
||||
* A mulhi [(a * b) >> 16] is applied which loses some precision, but is very efficient for SIMD.
|
||||
* It is accurate enough for 8-bit purposes.
|
||||
*
|
||||
* The fixed point 1.0 for filter is (1 << 14). After horizontal scale, the output is kept
|
||||
* with 16-bit channels, and will now have 13 bits of precision as [(a * (1 << 14)) >> 16] is effectively a right shift by 2.
|
||||
*
|
||||
* Vertical scaler takes the 13 bit channels, and performs the same mulhi steps.
|
||||
* Another 2 bits of precision is lost, which ends up as 11 bits.
|
||||
* Scaling is now complete. Channels are shifted right by 3, and saturated into 8-bit values.
|
||||
*
|
||||
* The C version of scalers perform the exact same operations as the SIMD code for testing purposes.
|
||||
*/
|
||||
|
||||
#if defined(__SSE2__)
|
||||
void scaler_argb8888_vert(const struct scaler_ctx *ctx, void *output_, int stride)
|
||||
{
|
||||
int h, w, y;
|
||||
const uint64_t *input = ctx->scaled.frame;
|
||||
uint32_t *output = (uint32_t*)output_;
|
||||
|
||||
const int16_t *filter_vert = ctx->vert.filter;
|
||||
|
||||
for (h = 0; h < ctx->out_height; h++, filter_vert += ctx->vert.filter_stride, output += stride >> 2)
|
||||
{
|
||||
const uint64_t *input_base = input + ctx->vert.filter_pos[h] * (ctx->scaled.stride >> 3);
|
||||
|
||||
for (w = 0; w < ctx->out_width; w++)
|
||||
{
|
||||
__m128i final;
|
||||
__m128i res = _mm_setzero_si128();
|
||||
|
||||
const uint64_t *input_base_y = input_base + w;
|
||||
|
||||
for (y = 0; (y + 1) < ctx->vert.filter_len; y += 2, input_base_y += (ctx->scaled.stride >> 2))
|
||||
{
|
||||
__m128i coeff = _mm_set_epi64x(filter_vert[y + 1] * 0x0001000100010001ll, filter_vert[y + 0] * 0x0001000100010001ll);
|
||||
__m128i col = _mm_set_epi64x(input_base_y[ctx->scaled.stride >> 3], input_base_y[0]);
|
||||
|
||||
res = _mm_adds_epi16(_mm_mulhi_epi16(col, coeff), res);
|
||||
}
|
||||
|
||||
for (; y < ctx->vert.filter_len; y++, input_base_y += (ctx->scaled.stride >> 3))
|
||||
{
|
||||
__m128i coeff = _mm_set_epi64x(0, filter_vert[y] * 0x0001000100010001ll);
|
||||
__m128i col = _mm_set_epi64x(0, input_base_y[0]);
|
||||
|
||||
res = _mm_adds_epi16(_mm_mulhi_epi16(col, coeff), res);
|
||||
}
|
||||
|
||||
res = _mm_adds_epi16(_mm_srli_si128(res, 8), res);
|
||||
res = _mm_srai_epi16(res, (7 - 2 - 2));
|
||||
|
||||
final = _mm_packus_epi16(res, res);
|
||||
|
||||
output[w] = _mm_cvtsi128_si32(final);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
void scaler_argb8888_vert(const struct scaler_ctx *ctx, void *output_, int stride)
|
||||
{
|
||||
int h, w, y;
|
||||
const uint64_t *input = ctx->scaled.frame;
|
||||
uint32_t *output = (uint32_t*)output_;
|
||||
|
||||
const int16_t *filter_vert = ctx->vert.filter;
|
||||
|
||||
for (h = 0; h < ctx->out_height; h++, filter_vert += ctx->vert.filter_stride, output += stride >> 2)
|
||||
{
|
||||
const uint64_t *input_base = input + ctx->vert.filter_pos[h] * (ctx->scaled.stride >> 3);
|
||||
|
||||
for (w = 0; w < ctx->out_width; w++)
|
||||
{
|
||||
int16_t res_a = 0;
|
||||
int16_t res_r = 0;
|
||||
int16_t res_g = 0;
|
||||
int16_t res_b = 0;
|
||||
|
||||
const uint64_t *input_base_y = input_base + w;
|
||||
for (y = 0; y < ctx->vert.filter_len; y++, input_base_y += (ctx->scaled.stride >> 3))
|
||||
{
|
||||
uint64_t col = *input_base_y;
|
||||
|
||||
int16_t a = (col >> 48) & 0xffff;
|
||||
int16_t r = (col >> 32) & 0xffff;
|
||||
int16_t g = (col >> 16) & 0xffff;
|
||||
int16_t b = (col >> 0) & 0xffff;
|
||||
|
||||
int16_t coeff = filter_vert[y];
|
||||
|
||||
res_a += (a * coeff) >> 16;
|
||||
res_r += (r * coeff) >> 16;
|
||||
res_g += (g * coeff) >> 16;
|
||||
res_b += (b * coeff) >> 16;
|
||||
}
|
||||
|
||||
res_a >>= (7 - 2 - 2);
|
||||
res_r >>= (7 - 2 - 2);
|
||||
res_g >>= (7 - 2 - 2);
|
||||
res_b >>= (7 - 2 - 2);
|
||||
|
||||
output[w] = (clamp_8bit(res_a) << 24) | (clamp_8bit(res_r) << 16) | (clamp_8bit(res_g) << 8) | (clamp_8bit(res_b) << 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__SSE2__)
|
||||
void scaler_argb8888_horiz(const struct scaler_ctx *ctx, const void *input_, int stride)
|
||||
{
|
||||
int h, w, x;
|
||||
const uint32_t *input = (const uint32_t*)input_;
|
||||
uint64_t *output = ctx->scaled.frame;
|
||||
|
||||
for (h = 0; h < ctx->scaled.height; h++, input += stride >> 2, output += ctx->scaled.stride >> 3)
|
||||
{
|
||||
const int16_t *filter_horiz = ctx->horiz.filter;
|
||||
|
||||
for (w = 0; w < ctx->scaled.width; w++, filter_horiz += ctx->horiz.filter_stride)
|
||||
{
|
||||
__m128i res = _mm_setzero_si128();
|
||||
|
||||
const uint32_t *input_base_x = input + ctx->horiz.filter_pos[w];
|
||||
|
||||
for (x = 0; (x + 1) < ctx->horiz.filter_len; x += 2)
|
||||
{
|
||||
__m128i coeff = _mm_set_epi64x(filter_horiz[x + 1] * 0x0001000100010001ll, filter_horiz[x + 0] * 0x0001000100010001ll);
|
||||
|
||||
__m128i col = _mm_unpacklo_epi8(_mm_set_epi64x(0,
|
||||
((uint64_t)input_base_x[x + 1] << 32) | input_base_x[x + 0]), _mm_setzero_si128());
|
||||
|
||||
col = _mm_slli_epi16(col, 7);
|
||||
res = _mm_adds_epi16(_mm_mulhi_epi16(col, coeff), res);
|
||||
}
|
||||
|
||||
for (; x < ctx->horiz.filter_len; x++)
|
||||
{
|
||||
__m128i coeff = _mm_set_epi64x(0, filter_horiz[x] * 0x0001000100010001ll);
|
||||
__m128i col = _mm_unpacklo_epi8(_mm_set_epi32(0, 0, 0, input_base_x[x]), _mm_setzero_si128());
|
||||
|
||||
col = _mm_slli_epi16(col, 7);
|
||||
res = _mm_adds_epi16(_mm_mulhi_epi16(col, coeff), res);
|
||||
}
|
||||
|
||||
res = _mm_adds_epi16(_mm_srli_si128(res, 8), res);
|
||||
|
||||
#ifdef __x86_64__
|
||||
output[w] = _mm_cvtsi128_si64(res);
|
||||
#else /* 32-bit doesn't have si64. Do it in two steps. */
|
||||
union
|
||||
{
|
||||
uint32_t *u32;
|
||||
uint64_t *u64;
|
||||
} u;
|
||||
u.u64 = output + w;
|
||||
u.u32[0] = _mm_cvtsi128_si32(res);
|
||||
u.u32[1] = _mm_cvtsi128_si32(_mm_srli_si128(res, 4));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
static INLINE uint64_t build_argb64(uint16_t a, uint16_t r, uint16_t g, uint16_t b)
|
||||
{
|
||||
return ((uint64_t)a << 48) | ((uint64_t)r << 32) | ((uint64_t)g << 16) | ((uint64_t)b << 0);
|
||||
}
|
||||
|
||||
void scaler_argb8888_horiz(const struct scaler_ctx *ctx, const void *input_, int stride)
|
||||
{
|
||||
int h, w, x;
|
||||
const uint32_t *input = (uint32_t*)input_;
|
||||
uint64_t *output = ctx->scaled.frame;
|
||||
|
||||
for (h = 0; h < ctx->scaled.height; h++, input += stride >> 2, output += ctx->scaled.stride >> 3)
|
||||
{
|
||||
const int16_t *filter_horiz = ctx->horiz.filter;
|
||||
|
||||
for (w = 0; w < ctx->scaled.width; w++, filter_horiz += ctx->horiz.filter_stride)
|
||||
{
|
||||
const uint32_t *input_base_x = input + ctx->horiz.filter_pos[w];
|
||||
|
||||
int16_t res_a = 0;
|
||||
int16_t res_r = 0;
|
||||
int16_t res_g = 0;
|
||||
int16_t res_b = 0;
|
||||
|
||||
for (x = 0; x < ctx->horiz.filter_len; x++)
|
||||
{
|
||||
uint32_t col = input_base_x[x];
|
||||
|
||||
int16_t a = (col >> (24 - 7)) & (0xff << 7);
|
||||
int16_t r = (col >> (16 - 7)) & (0xff << 7);
|
||||
int16_t g = (col >> ( 8 - 7)) & (0xff << 7);
|
||||
int16_t b = (col << ( 0 + 7)) & (0xff << 7);
|
||||
|
||||
int16_t coeff = filter_horiz[x];
|
||||
|
||||
res_a += (a * coeff) >> 16;
|
||||
res_r += (r * coeff) >> 16;
|
||||
res_g += (g * coeff) >> 16;
|
||||
res_b += (b * coeff) >> 16;
|
||||
}
|
||||
|
||||
output[w] = build_argb64(res_a, res_r, res_g, res_b);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void scaler_argb8888_point_special(const struct scaler_ctx *ctx,
|
||||
void *output_, const void *input_,
|
||||
int out_width, int out_height,
|
||||
int in_width, int in_height,
|
||||
int out_stride, int in_stride)
|
||||
{
|
||||
int h, w;
|
||||
const uint32_t *input = NULL;
|
||||
uint32_t *output = NULL;
|
||||
int x_pos = (1 << 15) * in_width / out_width - (1 << 15);
|
||||
int x_step = (1 << 16) * in_width / out_width;
|
||||
int y_pos = (1 << 15) * in_height / out_height - (1 << 15);
|
||||
int y_step = (1 << 16) * in_height / out_height;
|
||||
|
||||
(void)ctx;
|
||||
|
||||
if (x_pos < 0)
|
||||
x_pos = 0;
|
||||
if (y_pos < 0)
|
||||
y_pos = 0;
|
||||
|
||||
input = (const uint32_t*)input_;
|
||||
output = (uint32_t*)output_;
|
||||
|
||||
for (h = 0; h < out_height; h++, y_pos += y_step, output += out_stride >> 2)
|
||||
{
|
||||
int x = x_pos;
|
||||
const uint32_t *inp = input + (y_pos >> 16) * (in_stride >> 2);
|
||||
|
||||
for (w = 0; w < out_width; w++, x += x_step)
|
||||
output[w] = inp[x >> 16];
|
||||
}
|
||||
}
|
||||
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (scaler_int.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <gfx/scaler/scaler_int.h>
|
||||
|
||||
#include <retro_inline.h>
|
||||
|
||||
#ifdef SCALER_NO_SIMD
|
||||
#undef __SSE2__
|
||||
#endif
|
||||
|
||||
#if defined(__SSE2__)
|
||||
#include <emmintrin.h>
|
||||
#ifdef _WIN32
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* ARGB8888 scaler is split in two:
|
||||
*
|
||||
* First, horizontal scaler is applied.
|
||||
* Here, all 8-bit channels are expanded to 16-bit. Values are then shifted 7 to left to occupy 15 bits.
|
||||
* The sign bit is kept empty as we have to do signed multiplication for the filter.
|
||||
* A mulhi [(a * b) >> 16] is applied which loses some precision, but is very efficient for SIMD.
|
||||
* It is accurate enough for 8-bit purposes.
|
||||
*
|
||||
* The fixed point 1.0 for filter is (1 << 14). After horizontal scale, the output is kept
|
||||
* with 16-bit channels, and will now have 13 bits of precision as [(a * (1 << 14)) >> 16] is effectively a right shift by 2.
|
||||
*
|
||||
* Vertical scaler takes the 13 bit channels, and performs the same mulhi steps.
|
||||
* Another 2 bits of precision is lost, which ends up as 11 bits.
|
||||
* Scaling is now complete. Channels are shifted right by 3, and saturated into 8-bit values.
|
||||
*
|
||||
* The C version of scalers perform the exact same operations as the SIMD code for testing purposes.
|
||||
*/
|
||||
|
||||
#if defined(__SSE2__)
|
||||
void scaler_argb8888_vert(const struct scaler_ctx *ctx, void *output_, int stride)
|
||||
{
|
||||
int h, w, y;
|
||||
const uint64_t *input = ctx->scaled.frame;
|
||||
uint32_t *output = (uint32_t*)output_;
|
||||
|
||||
const int16_t *filter_vert = ctx->vert.filter;
|
||||
|
||||
for (h = 0; h < ctx->out_height; h++, filter_vert += ctx->vert.filter_stride, output += stride >> 2)
|
||||
{
|
||||
const uint64_t *input_base = input + ctx->vert.filter_pos[h] * (ctx->scaled.stride >> 3);
|
||||
|
||||
for (w = 0; w < ctx->out_width; w++)
|
||||
{
|
||||
__m128i final;
|
||||
__m128i res = _mm_setzero_si128();
|
||||
|
||||
const uint64_t *input_base_y = input_base + w;
|
||||
|
||||
for (y = 0; (y + 1) < ctx->vert.filter_len; y += 2, input_base_y += (ctx->scaled.stride >> 2))
|
||||
{
|
||||
__m128i coeff = _mm_set_epi64x(filter_vert[y + 1] * 0x0001000100010001ll, filter_vert[y + 0] * 0x0001000100010001ll);
|
||||
__m128i col = _mm_set_epi64x(input_base_y[ctx->scaled.stride >> 3], input_base_y[0]);
|
||||
|
||||
res = _mm_adds_epi16(_mm_mulhi_epi16(col, coeff), res);
|
||||
}
|
||||
|
||||
for (; y < ctx->vert.filter_len; y++, input_base_y += (ctx->scaled.stride >> 3))
|
||||
{
|
||||
__m128i coeff = _mm_set_epi64x(0, filter_vert[y] * 0x0001000100010001ll);
|
||||
__m128i col = _mm_set_epi64x(0, input_base_y[0]);
|
||||
|
||||
res = _mm_adds_epi16(_mm_mulhi_epi16(col, coeff), res);
|
||||
}
|
||||
|
||||
res = _mm_adds_epi16(_mm_srli_si128(res, 8), res);
|
||||
res = _mm_srai_epi16(res, (7 - 2 - 2));
|
||||
|
||||
final = _mm_packus_epi16(res, res);
|
||||
|
||||
output[w] = _mm_cvtsi128_si32(final);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
void scaler_argb8888_vert(const struct scaler_ctx *ctx, void *output_, int stride)
|
||||
{
|
||||
int h, w, y;
|
||||
const uint64_t *input = ctx->scaled.frame;
|
||||
uint32_t *output = (uint32_t*)output_;
|
||||
|
||||
const int16_t *filter_vert = ctx->vert.filter;
|
||||
|
||||
for (h = 0; h < ctx->out_height; h++, filter_vert += ctx->vert.filter_stride, output += stride >> 2)
|
||||
{
|
||||
const uint64_t *input_base = input + ctx->vert.filter_pos[h] * (ctx->scaled.stride >> 3);
|
||||
|
||||
for (w = 0; w < ctx->out_width; w++)
|
||||
{
|
||||
int16_t res_a = 0;
|
||||
int16_t res_r = 0;
|
||||
int16_t res_g = 0;
|
||||
int16_t res_b = 0;
|
||||
|
||||
const uint64_t *input_base_y = input_base + w;
|
||||
for (y = 0; y < ctx->vert.filter_len; y++, input_base_y += (ctx->scaled.stride >> 3))
|
||||
{
|
||||
uint64_t col = *input_base_y;
|
||||
|
||||
int16_t a = (col >> 48) & 0xffff;
|
||||
int16_t r = (col >> 32) & 0xffff;
|
||||
int16_t g = (col >> 16) & 0xffff;
|
||||
int16_t b = (col >> 0) & 0xffff;
|
||||
|
||||
int16_t coeff = filter_vert[y];
|
||||
|
||||
res_a += (a * coeff) >> 16;
|
||||
res_r += (r * coeff) >> 16;
|
||||
res_g += (g * coeff) >> 16;
|
||||
res_b += (b * coeff) >> 16;
|
||||
}
|
||||
|
||||
res_a >>= (7 - 2 - 2);
|
||||
res_r >>= (7 - 2 - 2);
|
||||
res_g >>= (7 - 2 - 2);
|
||||
res_b >>= (7 - 2 - 2);
|
||||
|
||||
output[w] = (clamp_8bit(res_a) << 24) | (clamp_8bit(res_r) << 16) | (clamp_8bit(res_g) << 8) | (clamp_8bit(res_b) << 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__SSE2__)
|
||||
void scaler_argb8888_horiz(const struct scaler_ctx *ctx, const void *input_, int stride)
|
||||
{
|
||||
int h, w, x;
|
||||
const uint32_t *input = (const uint32_t*)input_;
|
||||
uint64_t *output = ctx->scaled.frame;
|
||||
|
||||
for (h = 0; h < ctx->scaled.height; h++, input += stride >> 2, output += ctx->scaled.stride >> 3)
|
||||
{
|
||||
const int16_t *filter_horiz = ctx->horiz.filter;
|
||||
|
||||
for (w = 0; w < ctx->scaled.width; w++, filter_horiz += ctx->horiz.filter_stride)
|
||||
{
|
||||
__m128i res = _mm_setzero_si128();
|
||||
|
||||
const uint32_t *input_base_x = input + ctx->horiz.filter_pos[w];
|
||||
|
||||
for (x = 0; (x + 1) < ctx->horiz.filter_len; x += 2)
|
||||
{
|
||||
__m128i coeff = _mm_set_epi64x(filter_horiz[x + 1] * 0x0001000100010001ll, filter_horiz[x + 0] * 0x0001000100010001ll);
|
||||
|
||||
__m128i col = _mm_unpacklo_epi8(_mm_set_epi64x(0,
|
||||
((uint64_t)input_base_x[x + 1] << 32) | input_base_x[x + 0]), _mm_setzero_si128());
|
||||
|
||||
col = _mm_slli_epi16(col, 7);
|
||||
res = _mm_adds_epi16(_mm_mulhi_epi16(col, coeff), res);
|
||||
}
|
||||
|
||||
for (; x < ctx->horiz.filter_len; x++)
|
||||
{
|
||||
__m128i coeff = _mm_set_epi64x(0, filter_horiz[x] * 0x0001000100010001ll);
|
||||
__m128i col = _mm_unpacklo_epi8(_mm_set_epi32(0, 0, 0, input_base_x[x]), _mm_setzero_si128());
|
||||
|
||||
col = _mm_slli_epi16(col, 7);
|
||||
res = _mm_adds_epi16(_mm_mulhi_epi16(col, coeff), res);
|
||||
}
|
||||
|
||||
res = _mm_adds_epi16(_mm_srli_si128(res, 8), res);
|
||||
|
||||
#ifdef __x86_64__
|
||||
output[w] = _mm_cvtsi128_si64(res);
|
||||
#else /* 32-bit doesn't have si64. Do it in two steps. */
|
||||
union
|
||||
{
|
||||
uint32_t *u32;
|
||||
uint64_t *u64;
|
||||
} u;
|
||||
u.u64 = output + w;
|
||||
u.u32[0] = _mm_cvtsi128_si32(res);
|
||||
u.u32[1] = _mm_cvtsi128_si32(_mm_srli_si128(res, 4));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
static INLINE uint64_t build_argb64(uint16_t a, uint16_t r, uint16_t g, uint16_t b)
|
||||
{
|
||||
return ((uint64_t)a << 48) | ((uint64_t)r << 32) | ((uint64_t)g << 16) | ((uint64_t)b << 0);
|
||||
}
|
||||
|
||||
void scaler_argb8888_horiz(const struct scaler_ctx *ctx, const void *input_, int stride)
|
||||
{
|
||||
int h, w, x;
|
||||
const uint32_t *input = (uint32_t*)input_;
|
||||
uint64_t *output = ctx->scaled.frame;
|
||||
|
||||
for (h = 0; h < ctx->scaled.height; h++, input += stride >> 2, output += ctx->scaled.stride >> 3)
|
||||
{
|
||||
const int16_t *filter_horiz = ctx->horiz.filter;
|
||||
|
||||
for (w = 0; w < ctx->scaled.width; w++, filter_horiz += ctx->horiz.filter_stride)
|
||||
{
|
||||
const uint32_t *input_base_x = input + ctx->horiz.filter_pos[w];
|
||||
|
||||
int16_t res_a = 0;
|
||||
int16_t res_r = 0;
|
||||
int16_t res_g = 0;
|
||||
int16_t res_b = 0;
|
||||
|
||||
for (x = 0; x < ctx->horiz.filter_len; x++)
|
||||
{
|
||||
uint32_t col = input_base_x[x];
|
||||
|
||||
int16_t a = (col >> (24 - 7)) & (0xff << 7);
|
||||
int16_t r = (col >> (16 - 7)) & (0xff << 7);
|
||||
int16_t g = (col >> ( 8 - 7)) & (0xff << 7);
|
||||
int16_t b = (col << ( 0 + 7)) & (0xff << 7);
|
||||
|
||||
int16_t coeff = filter_horiz[x];
|
||||
|
||||
res_a += (a * coeff) >> 16;
|
||||
res_r += (r * coeff) >> 16;
|
||||
res_g += (g * coeff) >> 16;
|
||||
res_b += (b * coeff) >> 16;
|
||||
}
|
||||
|
||||
output[w] = build_argb64(res_a, res_r, res_g, res_b);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void scaler_argb8888_point_special(const struct scaler_ctx *ctx,
|
||||
void *output_, const void *input_,
|
||||
int out_width, int out_height,
|
||||
int in_width, int in_height,
|
||||
int out_stride, int in_stride)
|
||||
{
|
||||
int h, w;
|
||||
const uint32_t *input = NULL;
|
||||
uint32_t *output = NULL;
|
||||
int x_pos = (1 << 15) * in_width / out_width - (1 << 15);
|
||||
int x_step = (1 << 16) * in_width / out_width;
|
||||
int y_pos = (1 << 15) * in_height / out_height - (1 << 15);
|
||||
int y_step = (1 << 16) * in_height / out_height;
|
||||
|
||||
(void)ctx;
|
||||
|
||||
if (x_pos < 0)
|
||||
x_pos = 0;
|
||||
if (y_pos < 0)
|
||||
y_pos = 0;
|
||||
|
||||
input = (const uint32_t*)input_;
|
||||
output = (uint32_t*)output_;
|
||||
|
||||
for (h = 0; h < out_height; h++, y_pos += y_step, output += out_stride >> 2)
|
||||
{
|
||||
int x = x_pos;
|
||||
const uint32_t *inp = input + (y_pos >> 16) * (in_stride >> 2);
|
||||
|
||||
for (w = 0; w < out_width; w++, x += x_step)
|
||||
output[w] = inp[x >> 16];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,87 +1,87 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this libretro SDK code part (glsym).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <glsym/glsym.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#define SYM(x) { "gl" #x, &(gl##x) }
|
||||
const struct rglgen_sym_map rglgen_symbol_map[] = {
|
||||
SYM(DebugMessageControlKHR),
|
||||
SYM(DebugMessageInsertKHR),
|
||||
SYM(DebugMessageCallbackKHR),
|
||||
SYM(GetDebugMessageLogKHR),
|
||||
SYM(PushDebugGroupKHR),
|
||||
SYM(PopDebugGroupKHR),
|
||||
SYM(ObjectLabelKHR),
|
||||
SYM(GetObjectLabelKHR),
|
||||
SYM(ObjectPtrLabelKHR),
|
||||
SYM(GetObjectPtrLabelKHR),
|
||||
SYM(GetPointervKHR),
|
||||
SYM(EGLImageTargetTexture2DOES),
|
||||
SYM(EGLImageTargetRenderbufferStorageOES),
|
||||
SYM(GetProgramBinaryOES),
|
||||
SYM(ProgramBinaryOES),
|
||||
SYM(MapBufferOES),
|
||||
SYM(UnmapBufferOES),
|
||||
SYM(GetBufferPointervOES),
|
||||
SYM(TexImage3DOES),
|
||||
SYM(TexSubImage3DOES),
|
||||
SYM(CopyTexSubImage3DOES),
|
||||
SYM(CompressedTexImage3DOES),
|
||||
SYM(CompressedTexSubImage3DOES),
|
||||
SYM(FramebufferTexture3DOES),
|
||||
SYM(BindVertexArrayOES),
|
||||
SYM(DeleteVertexArraysOES),
|
||||
SYM(GenVertexArraysOES),
|
||||
SYM(IsVertexArrayOES),
|
||||
|
||||
{ NULL, NULL },
|
||||
};
|
||||
RGLSYMGLDEBUGMESSAGECONTROLKHRPROC __rglgen_glDebugMessageControlKHR;
|
||||
RGLSYMGLDEBUGMESSAGEINSERTKHRPROC __rglgen_glDebugMessageInsertKHR;
|
||||
RGLSYMGLDEBUGMESSAGECALLBACKKHRPROC __rglgen_glDebugMessageCallbackKHR;
|
||||
RGLSYMGLGETDEBUGMESSAGELOGKHRPROC __rglgen_glGetDebugMessageLogKHR;
|
||||
RGLSYMGLPUSHDEBUGGROUPKHRPROC __rglgen_glPushDebugGroupKHR;
|
||||
RGLSYMGLPOPDEBUGGROUPKHRPROC __rglgen_glPopDebugGroupKHR;
|
||||
RGLSYMGLOBJECTLABELKHRPROC __rglgen_glObjectLabelKHR;
|
||||
RGLSYMGLGETOBJECTLABELKHRPROC __rglgen_glGetObjectLabelKHR;
|
||||
RGLSYMGLOBJECTPTRLABELKHRPROC __rglgen_glObjectPtrLabelKHR;
|
||||
RGLSYMGLGETOBJECTPTRLABELKHRPROC __rglgen_glGetObjectPtrLabelKHR;
|
||||
RGLSYMGLGETPOINTERVKHRPROC __rglgen_glGetPointervKHR;
|
||||
RGLSYMGLEGLIMAGETARGETTEXTURE2DOESPROC __rglgen_glEGLImageTargetTexture2DOES;
|
||||
RGLSYMGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC __rglgen_glEGLImageTargetRenderbufferStorageOES;
|
||||
RGLSYMGLGETPROGRAMBINARYOESPROC __rglgen_glGetProgramBinaryOES;
|
||||
RGLSYMGLPROGRAMBINARYOESPROC __rglgen_glProgramBinaryOES;
|
||||
RGLSYMGLMAPBUFFEROESPROC __rglgen_glMapBufferOES;
|
||||
RGLSYMGLUNMAPBUFFEROESPROC __rglgen_glUnmapBufferOES;
|
||||
RGLSYMGLGETBUFFERPOINTERVOESPROC __rglgen_glGetBufferPointervOES;
|
||||
RGLSYMGLTEXIMAGE3DOESPROC __rglgen_glTexImage3DOES;
|
||||
RGLSYMGLTEXSUBIMAGE3DOESPROC __rglgen_glTexSubImage3DOES;
|
||||
RGLSYMGLCOPYTEXSUBIMAGE3DOESPROC __rglgen_glCopyTexSubImage3DOES;
|
||||
RGLSYMGLCOMPRESSEDTEXIMAGE3DOESPROC __rglgen_glCompressedTexImage3DOES;
|
||||
RGLSYMGLCOMPRESSEDTEXSUBIMAGE3DOESPROC __rglgen_glCompressedTexSubImage3DOES;
|
||||
RGLSYMGLFRAMEBUFFERTEXTURE3DOESPROC __rglgen_glFramebufferTexture3DOES;
|
||||
RGLSYMGLBINDVERTEXARRAYOESPROC __rglgen_glBindVertexArrayOES;
|
||||
RGLSYMGLDELETEVERTEXARRAYSOESPROC __rglgen_glDeleteVertexArraysOES;
|
||||
RGLSYMGLGENVERTEXARRAYSOESPROC __rglgen_glGenVertexArraysOES;
|
||||
RGLSYMGLISVERTEXARRAYOESPROC __rglgen_glIsVertexArrayOES;
|
||||
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this libretro SDK code part (glsym).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <glsym/glsym.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#define SYM(x) { "gl" #x, &(gl##x) }
|
||||
const struct rglgen_sym_map rglgen_symbol_map[] = {
|
||||
SYM(DebugMessageControlKHR),
|
||||
SYM(DebugMessageInsertKHR),
|
||||
SYM(DebugMessageCallbackKHR),
|
||||
SYM(GetDebugMessageLogKHR),
|
||||
SYM(PushDebugGroupKHR),
|
||||
SYM(PopDebugGroupKHR),
|
||||
SYM(ObjectLabelKHR),
|
||||
SYM(GetObjectLabelKHR),
|
||||
SYM(ObjectPtrLabelKHR),
|
||||
SYM(GetObjectPtrLabelKHR),
|
||||
SYM(GetPointervKHR),
|
||||
SYM(EGLImageTargetTexture2DOES),
|
||||
SYM(EGLImageTargetRenderbufferStorageOES),
|
||||
SYM(GetProgramBinaryOES),
|
||||
SYM(ProgramBinaryOES),
|
||||
SYM(MapBufferOES),
|
||||
SYM(UnmapBufferOES),
|
||||
SYM(GetBufferPointervOES),
|
||||
SYM(TexImage3DOES),
|
||||
SYM(TexSubImage3DOES),
|
||||
SYM(CopyTexSubImage3DOES),
|
||||
SYM(CompressedTexImage3DOES),
|
||||
SYM(CompressedTexSubImage3DOES),
|
||||
SYM(FramebufferTexture3DOES),
|
||||
SYM(BindVertexArrayOES),
|
||||
SYM(DeleteVertexArraysOES),
|
||||
SYM(GenVertexArraysOES),
|
||||
SYM(IsVertexArrayOES),
|
||||
|
||||
{ NULL, NULL },
|
||||
};
|
||||
RGLSYMGLDEBUGMESSAGECONTROLKHRPROC __rglgen_glDebugMessageControlKHR;
|
||||
RGLSYMGLDEBUGMESSAGEINSERTKHRPROC __rglgen_glDebugMessageInsertKHR;
|
||||
RGLSYMGLDEBUGMESSAGECALLBACKKHRPROC __rglgen_glDebugMessageCallbackKHR;
|
||||
RGLSYMGLGETDEBUGMESSAGELOGKHRPROC __rglgen_glGetDebugMessageLogKHR;
|
||||
RGLSYMGLPUSHDEBUGGROUPKHRPROC __rglgen_glPushDebugGroupKHR;
|
||||
RGLSYMGLPOPDEBUGGROUPKHRPROC __rglgen_glPopDebugGroupKHR;
|
||||
RGLSYMGLOBJECTLABELKHRPROC __rglgen_glObjectLabelKHR;
|
||||
RGLSYMGLGETOBJECTLABELKHRPROC __rglgen_glGetObjectLabelKHR;
|
||||
RGLSYMGLOBJECTPTRLABELKHRPROC __rglgen_glObjectPtrLabelKHR;
|
||||
RGLSYMGLGETOBJECTPTRLABELKHRPROC __rglgen_glGetObjectPtrLabelKHR;
|
||||
RGLSYMGLGETPOINTERVKHRPROC __rglgen_glGetPointervKHR;
|
||||
RGLSYMGLEGLIMAGETARGETTEXTURE2DOESPROC __rglgen_glEGLImageTargetTexture2DOES;
|
||||
RGLSYMGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC __rglgen_glEGLImageTargetRenderbufferStorageOES;
|
||||
RGLSYMGLGETPROGRAMBINARYOESPROC __rglgen_glGetProgramBinaryOES;
|
||||
RGLSYMGLPROGRAMBINARYOESPROC __rglgen_glProgramBinaryOES;
|
||||
RGLSYMGLMAPBUFFEROESPROC __rglgen_glMapBufferOES;
|
||||
RGLSYMGLUNMAPBUFFEROESPROC __rglgen_glUnmapBufferOES;
|
||||
RGLSYMGLGETBUFFERPOINTERVOESPROC __rglgen_glGetBufferPointervOES;
|
||||
RGLSYMGLTEXIMAGE3DOESPROC __rglgen_glTexImage3DOES;
|
||||
RGLSYMGLTEXSUBIMAGE3DOESPROC __rglgen_glTexSubImage3DOES;
|
||||
RGLSYMGLCOPYTEXSUBIMAGE3DOESPROC __rglgen_glCopyTexSubImage3DOES;
|
||||
RGLSYMGLCOMPRESSEDTEXIMAGE3DOESPROC __rglgen_glCompressedTexImage3DOES;
|
||||
RGLSYMGLCOMPRESSEDTEXSUBIMAGE3DOESPROC __rglgen_glCompressedTexSubImage3DOES;
|
||||
RGLSYMGLFRAMEBUFFERTEXTURE3DOESPROC __rglgen_glFramebufferTexture3DOES;
|
||||
RGLSYMGLBINDVERTEXARRAYOESPROC __rglgen_glBindVertexArrayOES;
|
||||
RGLSYMGLDELETEVERTEXARRAYSOESPROC __rglgen_glDeleteVertexArraysOES;
|
||||
RGLSYMGLGENVERTEXARRAYSOESPROC __rglgen_glGenVertexArraysOES;
|
||||
RGLSYMGLISVERTEXARRAYOESPROC __rglgen_glIsVertexArrayOES;
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,43 +1,43 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this libretro SDK code part (glsym).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <glsym/rglgen.h>
|
||||
#include <glsym/glsym.h>
|
||||
|
||||
void rglgen_resolve_symbols_custom(rglgen_proc_address_t proc,
|
||||
const struct rglgen_sym_map *map)
|
||||
{
|
||||
for (; map->sym; map++)
|
||||
{
|
||||
rglgen_func_t func = proc(map->sym);
|
||||
memcpy(map->ptr, &func, sizeof(func));
|
||||
}
|
||||
}
|
||||
|
||||
void rglgen_resolve_symbols(rglgen_proc_address_t proc)
|
||||
{
|
||||
rglgen_resolve_symbols_custom(proc, rglgen_symbol_map);
|
||||
}
|
||||
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this libretro SDK code part (glsym).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <glsym/rglgen.h>
|
||||
#include <glsym/glsym.h>
|
||||
|
||||
void rglgen_resolve_symbols_custom(rglgen_proc_address_t proc,
|
||||
const struct rglgen_sym_map *map)
|
||||
{
|
||||
for (; map->sym; map++)
|
||||
{
|
||||
rglgen_func_t func = proc(map->sym);
|
||||
memcpy(map->ptr, &func, sizeof(func));
|
||||
}
|
||||
}
|
||||
|
||||
void rglgen_resolve_symbols(rglgen_proc_address_t proc)
|
||||
{
|
||||
rglgen_resolve_symbols_custom(proc, rglgen_symbol_map);
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,39 +1,39 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (boolean.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_BOOLEAN_H
|
||||
#define __LIBRETRO_SDK_BOOLEAN_H
|
||||
|
||||
#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
|
||||
|
||||
#endif
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (boolean.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_BOOLEAN_H
|
||||
#define __LIBRETRO_SDK_BOOLEAN_H
|
||||
|
||||
#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
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,65 +1,65 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (boolean.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_CLAMPING_H
|
||||
#define _LIBRETRO_SDK_CLAMPING_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <retro_inline.h>
|
||||
|
||||
/**
|
||||
* clamp_float:
|
||||
* @val : initial value
|
||||
* @lower : lower limit that value should be clamped against
|
||||
* @upper : upper limit that value should be clamped against
|
||||
*
|
||||
* Clamps a floating point value.
|
||||
*
|
||||
* Returns: a clamped value of initial float value @val.
|
||||
*/
|
||||
static INLINE float clamp_float(float val, float lower, float upper)
|
||||
{
|
||||
if (val < lower)
|
||||
return lower;
|
||||
if (val > upper)
|
||||
return upper;
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* clamp_8bit:
|
||||
* @val : initial value
|
||||
*
|
||||
* Clamps an unsigned 8-bit value.
|
||||
*
|
||||
* Returns: a clamped value of initial unsigned 8-bit value @val.
|
||||
*/
|
||||
static INLINE uint8_t clamp_8bit(int val)
|
||||
{
|
||||
if (val > 255)
|
||||
return 255;
|
||||
if (val < 0)
|
||||
return 0;
|
||||
return (uint8_t)val;
|
||||
}
|
||||
|
||||
#endif
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (boolean.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_CLAMPING_H
|
||||
#define _LIBRETRO_SDK_CLAMPING_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <retro_inline.h>
|
||||
|
||||
/**
|
||||
* clamp_float:
|
||||
* @val : initial value
|
||||
* @lower : lower limit that value should be clamped against
|
||||
* @upper : upper limit that value should be clamped against
|
||||
*
|
||||
* Clamps a floating point value.
|
||||
*
|
||||
* Returns: a clamped value of initial float value @val.
|
||||
*/
|
||||
static INLINE float clamp_float(float val, float lower, float upper)
|
||||
{
|
||||
if (val < lower)
|
||||
return lower;
|
||||
if (val > upper)
|
||||
return upper;
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* clamp_8bit:
|
||||
* @val : initial value
|
||||
*
|
||||
* Clamps an unsigned 8-bit value.
|
||||
*
|
||||
* Returns: a clamped value of initial unsigned 8-bit value @val.
|
||||
*/
|
||||
static INLINE uint8_t clamp_8bit(int val)
|
||||
{
|
||||
if (val > 255)
|
||||
return 255;
|
||||
if (val < 0)
|
||||
return 0;
|
||||
return (uint8_t)val;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,49 +1,49 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (apple_compat.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.
|
||||
*/
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <AvailabilityMacros.h>
|
||||
#endif
|
||||
|
||||
#ifdef __OBJC__
|
||||
|
||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4)
|
||||
typedef int NSInteger;
|
||||
typedef unsigned NSUInteger;
|
||||
typedef float CGFloat;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef IOS
|
||||
#ifndef __IPHONE_5_0
|
||||
#warning "This project uses features only available in iOS SDK 5.0 and later."
|
||||
#endif
|
||||
|
||||
#ifdef __OBJC__
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <GLKit/GLKit.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#include <objc/objc-runtime.h>
|
||||
#endif
|
||||
#endif
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (apple_compat.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.
|
||||
*/
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <AvailabilityMacros.h>
|
||||
#endif
|
||||
|
||||
#ifdef __OBJC__
|
||||
|
||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4)
|
||||
typedef int NSInteger;
|
||||
typedef unsigned NSUInteger;
|
||||
typedef float CGFloat;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef IOS
|
||||
#ifndef __IPHONE_5_0
|
||||
#warning "This project uses features only available in iOS SDK 5.0 and later."
|
||||
#endif
|
||||
|
||||
#ifdef __OBJC__
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <GLKit/GLKit.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#include <objc/objc-runtime.h>
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -1,30 +1,30 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (compat_fnmatch.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_COMPAT_FNMATCH_H__
|
||||
#define __LIBRETRO_SDK_COMPAT_FNMATCH_H__
|
||||
|
||||
#define FNM_NOMATCH 1
|
||||
|
||||
int rl_fnmatch(const char *pattern, const char *string, int flags);
|
||||
|
||||
#endif
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (compat_fnmatch.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_COMPAT_FNMATCH_H__
|
||||
#define __LIBRETRO_SDK_COMPAT_FNMATCH_H__
|
||||
|
||||
#define FNM_NOMATCH 1
|
||||
|
||||
int rl_fnmatch(const char *pattern, const char *string, int flags);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,76 +1,76 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (compat_getopt.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_COMPAT_GETOPT_H
|
||||
#define __LIBRETRO_SDK_COMPAT_GETOPT_H
|
||||
|
||||
#if defined(RARCH_INTERNAL) && defined(HAVE_CONFIG_H)
|
||||
#include "../../../config.h"
|
||||
#endif
|
||||
|
||||
/* Custom implementation of the GNU getopt_long for portability.
|
||||
* Not designed to be fully compatible, but compatible with
|
||||
* the features RetroArch uses. */
|
||||
|
||||
#ifdef HAVE_GETOPT_LONG
|
||||
#include <getopt.h>
|
||||
#else
|
||||
/* Avoid possible naming collisions during link since we
|
||||
* prefer to use the actual name. */
|
||||
#define getopt_long(argc, argv, optstring, longopts, longindex) __getopt_long_retro(argc, argv, optstring, longopts, longindex)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct option
|
||||
{
|
||||
const char *name;
|
||||
int has_arg;
|
||||
int *flag;
|
||||
int val;
|
||||
};
|
||||
|
||||
/* argv[] is declared with char * const argv[] in GNU,
|
||||
* but this makes no sense, as non-POSIX getopt_long
|
||||
* mutates argv (non-opts are moved to the end). */
|
||||
int getopt_long(int argc, char *argv[],
|
||||
const char *optstring, const struct option *longopts, int *longindex);
|
||||
extern char *optarg;
|
||||
extern int optind, opterr, optopt;
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If these are variously #defined, then we have bigger problems */
|
||||
#ifndef no_argument
|
||||
#define no_argument 0
|
||||
#define required_argument 1
|
||||
#define optional_argument 2
|
||||
#endif
|
||||
|
||||
/* HAVE_GETOPT_LONG */
|
||||
#endif
|
||||
|
||||
/* pragma once */
|
||||
#endif
|
||||
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (compat_getopt.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_COMPAT_GETOPT_H
|
||||
#define __LIBRETRO_SDK_COMPAT_GETOPT_H
|
||||
|
||||
#if defined(RARCH_INTERNAL) && defined(HAVE_CONFIG_H)
|
||||
#include "../../../config.h"
|
||||
#endif
|
||||
|
||||
/* Custom implementation of the GNU getopt_long for portability.
|
||||
* Not designed to be fully compatible, but compatible with
|
||||
* the features RetroArch uses. */
|
||||
|
||||
#ifdef HAVE_GETOPT_LONG
|
||||
#include <getopt.h>
|
||||
#else
|
||||
/* Avoid possible naming collisions during link since we
|
||||
* prefer to use the actual name. */
|
||||
#define getopt_long(argc, argv, optstring, longopts, longindex) __getopt_long_retro(argc, argv, optstring, longopts, longindex)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct option
|
||||
{
|
||||
const char *name;
|
||||
int has_arg;
|
||||
int *flag;
|
||||
int val;
|
||||
};
|
||||
|
||||
/* argv[] is declared with char * const argv[] in GNU,
|
||||
* but this makes no sense, as non-POSIX getopt_long
|
||||
* mutates argv (non-opts are moved to the end). */
|
||||
int getopt_long(int argc, char *argv[],
|
||||
const char *optstring, const struct option *longopts, int *longindex);
|
||||
extern char *optarg;
|
||||
extern int optind, opterr, optopt;
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If these are variously #defined, then we have bigger problems */
|
||||
#ifndef no_argument
|
||||
#define no_argument 0
|
||||
#define required_argument 1
|
||||
#define optional_argument 2
|
||||
#endif
|
||||
|
||||
/* HAVE_GETOPT_LONG */
|
||||
#endif
|
||||
|
||||
/* pragma once */
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,103 +1,103 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (msvc_compat.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_COMPAT_MSVC_H
|
||||
#define __LIBRETRO_SDK_COMPAT_MSVC_H
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Pre-MSVC 2015 compilers don't implement snprintf in a cross-platform manner. */
|
||||
#if _MSC_VER < 1900
|
||||
#include <stdlib.h>
|
||||
#ifndef snprintf
|
||||
#define snprintf c99_snprintf_retro__
|
||||
#endif
|
||||
|
||||
int c99_snprintf_retro__(char *outBuf, size_t size, const char *format, ...);
|
||||
#endif
|
||||
|
||||
/* Pre-MSVC 2010 compilers don't implement vsnprintf in a cross-platform manner? Not sure about this one. */
|
||||
#if _MSC_VER < 1600
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#ifndef vsnprintf
|
||||
#define vsnprintf c99_vsnprintf_retro__
|
||||
#endif
|
||||
int c99_vsnprintf_retro__(char *outBuf, size_t size, const char *format, va_list ap);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef UNICODE /* Do not bother with UNICODE at this time. */
|
||||
#include <direct.h>
|
||||
#include <stddef.h>
|
||||
#include <math.h>
|
||||
|
||||
/* Python headers defines ssize_t and sets HAVE_SSIZE_T.
|
||||
* Cannot duplicate these efforts.
|
||||
*/
|
||||
#ifndef HAVE_SSIZE_T
|
||||
#if defined(_WIN64)
|
||||
typedef __int64 ssize_t;
|
||||
#elif defined(_WIN32)
|
||||
typedef int ssize_t;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define mkdir(dirname, unused) _mkdir(dirname)
|
||||
#define strtoull _strtoui64
|
||||
#undef strcasecmp
|
||||
#define strcasecmp _stricmp
|
||||
#undef strncasecmp
|
||||
#define strncasecmp _strnicmp
|
||||
|
||||
/* Disable some of the annoying warnings. */
|
||||
#pragma warning(disable : 4800)
|
||||
#pragma warning(disable : 4805)
|
||||
#pragma warning(disable : 4244)
|
||||
#pragma warning(disable : 4305)
|
||||
#pragma warning(disable : 4146)
|
||||
#pragma warning(disable : 4267)
|
||||
#pragma warning(disable : 4723)
|
||||
#pragma warning(disable : 4996)
|
||||
|
||||
#if _MSC_VER < 1200
|
||||
#define roundf(in) (in >= 0.0f ? floorf(in + 0.5f) : ceilf(in - 0.5f))
|
||||
#endif
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX _MAX_PATH
|
||||
#endif
|
||||
|
||||
#ifndef SIZE_MAX
|
||||
#define SIZE_MAX _UI32_MAX
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (msvc_compat.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_COMPAT_MSVC_H
|
||||
#define __LIBRETRO_SDK_COMPAT_MSVC_H
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Pre-MSVC 2015 compilers don't implement snprintf in a cross-platform manner. */
|
||||
#if _MSC_VER < 1900
|
||||
#include <stdlib.h>
|
||||
#ifndef snprintf
|
||||
#define snprintf c99_snprintf_retro__
|
||||
#endif
|
||||
|
||||
int c99_snprintf_retro__(char *outBuf, size_t size, const char *format, ...);
|
||||
#endif
|
||||
|
||||
/* Pre-MSVC 2010 compilers don't implement vsnprintf in a cross-platform manner? Not sure about this one. */
|
||||
#if _MSC_VER < 1600
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#ifndef vsnprintf
|
||||
#define vsnprintf c99_vsnprintf_retro__
|
||||
#endif
|
||||
int c99_vsnprintf_retro__(char *outBuf, size_t size, const char *format, va_list ap);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef UNICODE /* Do not bother with UNICODE at this time. */
|
||||
#include <direct.h>
|
||||
#include <stddef.h>
|
||||
#include <math.h>
|
||||
|
||||
/* Python headers defines ssize_t and sets HAVE_SSIZE_T.
|
||||
* Cannot duplicate these efforts.
|
||||
*/
|
||||
#ifndef HAVE_SSIZE_T
|
||||
#if defined(_WIN64)
|
||||
typedef __int64 ssize_t;
|
||||
#elif defined(_WIN32)
|
||||
typedef int ssize_t;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define mkdir(dirname, unused) _mkdir(dirname)
|
||||
#define strtoull _strtoui64
|
||||
#undef strcasecmp
|
||||
#define strcasecmp _stricmp
|
||||
#undef strncasecmp
|
||||
#define strncasecmp _strnicmp
|
||||
|
||||
/* Disable some of the annoying warnings. */
|
||||
#pragma warning(disable : 4800)
|
||||
#pragma warning(disable : 4805)
|
||||
#pragma warning(disable : 4244)
|
||||
#pragma warning(disable : 4305)
|
||||
#pragma warning(disable : 4146)
|
||||
#pragma warning(disable : 4267)
|
||||
#pragma warning(disable : 4723)
|
||||
#pragma warning(disable : 4996)
|
||||
|
||||
#if _MSC_VER < 1200
|
||||
#define roundf(in) (in >= 0.0f ? floorf(in + 0.5f) : ceilf(in - 0.5f))
|
||||
#endif
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX _MAX_PATH
|
||||
#endif
|
||||
|
||||
#ifndef SIZE_MAX
|
||||
#define SIZE_MAX _UI32_MAX
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,254 +1,254 @@
|
|||
/* ISO C9x compliant stdint.h for Microsoft Visual Studio
|
||||
* Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
|
||||
*
|
||||
* Copyright (c) 2006-2008 Alexander Chemeris
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*
|
||||
* 3. The name of the author may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 THE AUTHOR 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.
|
||||
*/
|
||||
|
||||
#ifndef __RARCH_STDINT_H
|
||||
#define __RARCH_STDINT_H
|
||||
|
||||
#if _MSC_VER && (_MSC_VER < 1600)
|
||||
/* Pre-MSVC 2010 needs an implementation of stdint.h. */
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
/* For Visual Studio 6 in C++ mode and for many Visual Studio versions when
|
||||
* compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
|
||||
* or compiler give many errors like this:
|
||||
*
|
||||
* error C2733: second C linkage of overloaded function 'wmemchr' not allowed
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
# include <wchar.h>
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Define _W64 macros to mark types changing their size, like intptr_t. */
|
||||
#ifndef _W64
|
||||
# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
|
||||
# define _W64 __w64
|
||||
# else
|
||||
# define _W64
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/* 7.18.1 Integer types. */
|
||||
|
||||
/* 7.18.1.1 Exact-width integer types. */
|
||||
|
||||
/* Visual Studio 6 and Embedded Visual C++ 4 doesn't
|
||||
* realize that, e.g. char has the same size as __int8
|
||||
* so we give up on __intX for them.
|
||||
*/
|
||||
#if (_MSC_VER < 1300)
|
||||
typedef signed char int8_t;
|
||||
typedef signed short int16_t;
|
||||
typedef signed int int32_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
#else
|
||||
typedef signed __int8 int8_t;
|
||||
typedef signed __int16 int16_t;
|
||||
typedef signed __int32 int32_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
#endif
|
||||
typedef signed __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
|
||||
|
||||
/* 7.18.1.2 Minimum-width integer types. */
|
||||
typedef int8_t int_least8_t;
|
||||
typedef int16_t int_least16_t;
|
||||
typedef int32_t int_least32_t;
|
||||
typedef int64_t int_least64_t;
|
||||
typedef uint8_t uint_least8_t;
|
||||
typedef uint16_t uint_least16_t;
|
||||
typedef uint32_t uint_least32_t;
|
||||
typedef uint64_t uint_least64_t;
|
||||
|
||||
/* 7.18.1.3 Fastest minimum-width integer types. */
|
||||
typedef int8_t int_fast8_t;
|
||||
typedef int16_t int_fast16_t;
|
||||
typedef int32_t int_fast32_t;
|
||||
typedef int64_t int_fast64_t;
|
||||
typedef uint8_t uint_fast8_t;
|
||||
typedef uint16_t uint_fast16_t;
|
||||
typedef uint32_t uint_fast32_t;
|
||||
typedef uint64_t uint_fast64_t;
|
||||
|
||||
/* 7.18.1.4 Integer types capable of holding object pointers. */
|
||||
#ifdef _WIN64 /* [ */
|
||||
typedef signed __int64 intptr_t;
|
||||
typedef unsigned __int64 uintptr_t;
|
||||
#else /* _WIN64 ][ */
|
||||
typedef _W64 signed int intptr_t;
|
||||
typedef _W64 unsigned int uintptr_t;
|
||||
#endif /* _WIN64 ] */
|
||||
|
||||
/* 7.18.1.5 Greatest-width integer types. */
|
||||
typedef int64_t intmax_t;
|
||||
typedef uint64_t uintmax_t;
|
||||
|
||||
/* 7.18.2 Limits of specified-width integer types. */
|
||||
|
||||
#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS)
|
||||
/* [ See footnote 220 at page 257 and footnote 221 at page 259. */
|
||||
|
||||
/* 7.18.2.1 Limits of exact-width integer types. */
|
||||
#define INT8_MIN ((int8_t)_I8_MIN)
|
||||
#define INT8_MAX _I8_MAX
|
||||
#define INT16_MIN ((int16_t)_I16_MIN)
|
||||
#define INT16_MAX _I16_MAX
|
||||
#define INT32_MIN ((int32_t)_I32_MIN)
|
||||
#define INT32_MAX _I32_MAX
|
||||
#define INT64_MIN ((int64_t)_I64_MIN)
|
||||
#define INT64_MAX _I64_MAX
|
||||
#define UINT8_MAX _UI8_MAX
|
||||
#define UINT16_MAX _UI16_MAX
|
||||
#define UINT32_MAX _UI32_MAX
|
||||
#define UINT64_MAX _UI64_MAX
|
||||
|
||||
/* 7.18.2.2 Limits of minimum-width integer types. */
|
||||
#define INT_LEAST8_MIN INT8_MIN
|
||||
#define INT_LEAST8_MAX INT8_MAX
|
||||
#define INT_LEAST16_MIN INT16_MIN
|
||||
#define INT_LEAST16_MAX INT16_MAX
|
||||
#define INT_LEAST32_MIN INT32_MIN
|
||||
#define INT_LEAST32_MAX INT32_MAX
|
||||
#define INT_LEAST64_MIN INT64_MIN
|
||||
#define INT_LEAST64_MAX INT64_MAX
|
||||
#define UINT_LEAST8_MAX UINT8_MAX
|
||||
#define UINT_LEAST16_MAX UINT16_MAX
|
||||
#define UINT_LEAST32_MAX UINT32_MAX
|
||||
#define UINT_LEAST64_MAX UINT64_MAX
|
||||
|
||||
/* 7.18.2.3 Limits of fastest minimum-width integer types. */
|
||||
#define INT_FAST8_MIN INT8_MIN
|
||||
#define INT_FAST8_MAX INT8_MAX
|
||||
#define INT_FAST16_MIN INT16_MIN
|
||||
#define INT_FAST16_MAX INT16_MAX
|
||||
#define INT_FAST32_MIN INT32_MIN
|
||||
#define INT_FAST32_MAX INT32_MAX
|
||||
#define INT_FAST64_MIN INT64_MIN
|
||||
#define INT_FAST64_MAX INT64_MAX
|
||||
#define UINT_FAST8_MAX UINT8_MAX
|
||||
#define UINT_FAST16_MAX UINT16_MAX
|
||||
#define UINT_FAST32_MAX UINT32_MAX
|
||||
#define UINT_FAST64_MAX UINT64_MAX
|
||||
|
||||
/* 7.18.2.4 Limits of integer types capable of holding object pointers. */
|
||||
#ifdef _WIN64 /* [ */
|
||||
# define INTPTR_MIN INT64_MIN
|
||||
# define INTPTR_MAX INT64_MAX
|
||||
# define UINTPTR_MAX UINT64_MAX
|
||||
#else /* _WIN64 ][ */
|
||||
# define INTPTR_MIN INT32_MIN
|
||||
# define INTPTR_MAX INT32_MAX
|
||||
# define UINTPTR_MAX UINT32_MAX
|
||||
#endif /* _WIN64 ] */
|
||||
|
||||
/* 7.18.2.5 Limits of greatest-width integer types */
|
||||
#define INTMAX_MIN INT64_MIN
|
||||
#define INTMAX_MAX INT64_MAX
|
||||
#define UINTMAX_MAX UINT64_MAX
|
||||
|
||||
/* 7.18.3 Limits of other integer types */
|
||||
|
||||
#ifdef _WIN64 /* [ */
|
||||
# define PTRDIFF_MIN _I64_MIN
|
||||
# define PTRDIFF_MAX _I64_MAX
|
||||
#else /* _WIN64 ][ */
|
||||
# define PTRDIFF_MIN _I32_MIN
|
||||
# define PTRDIFF_MAX _I32_MAX
|
||||
#endif /* _WIN64 ] */
|
||||
|
||||
#define SIG_ATOMIC_MIN INT_MIN
|
||||
#define SIG_ATOMIC_MAX INT_MAX
|
||||
|
||||
#ifndef SIZE_MAX /* [ */
|
||||
# ifdef _WIN64 /* [ */
|
||||
# define SIZE_MAX _UI64_MAX
|
||||
# else /* _WIN64 ][ */
|
||||
# define SIZE_MAX _UI32_MAX
|
||||
# endif /* _WIN64 ] */
|
||||
#endif /* SIZE_MAX ] */
|
||||
|
||||
/* WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h> */
|
||||
#ifndef WCHAR_MIN /* [ */
|
||||
# define WCHAR_MIN 0
|
||||
#endif /* WCHAR_MIN ] */
|
||||
#ifndef WCHAR_MAX // [
|
||||
# define WCHAR_MAX _UI16_MAX
|
||||
#endif /* WCHAR_MAX ] */
|
||||
|
||||
#define WINT_MIN 0
|
||||
#define WINT_MAX _UI16_MAX
|
||||
|
||||
#endif /* __STDC_LIMIT_MACROS ] */
|
||||
|
||||
/* 7.18.4 Limits of other integer types */
|
||||
|
||||
#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS)
|
||||
/* [ See footnote 224 at page 260 */
|
||||
|
||||
/* 7.18.4.1 Macros for minimum-width integer constants */
|
||||
|
||||
#define INT8_C(val) val##i8
|
||||
#define INT16_C(val) val##i16
|
||||
#define INT32_C(val) val##i32
|
||||
#define INT64_C(val) val##i64
|
||||
|
||||
#define UINT8_C(val) val##ui8
|
||||
#define UINT16_C(val) val##ui16
|
||||
#define UINT32_C(val) val##ui32
|
||||
#define UINT64_C(val) val##ui64
|
||||
|
||||
/* 7.18.4.2 Macros for greatest-width integer constants */
|
||||
#define INTMAX_C INT64_C
|
||||
#define UINTMAX_C UINT64_C
|
||||
|
||||
#endif
|
||||
/* __STDC_CONSTANT_MACROS ] */
|
||||
|
||||
#else
|
||||
/* Sanity for everything else. */
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* ISO C9x compliant stdint.h for Microsoft Visual Studio
|
||||
* Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
|
||||
*
|
||||
* Copyright (c) 2006-2008 Alexander Chemeris
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*
|
||||
* 3. The name of the author may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 THE AUTHOR 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.
|
||||
*/
|
||||
|
||||
#ifndef __RARCH_STDINT_H
|
||||
#define __RARCH_STDINT_H
|
||||
|
||||
#if _MSC_VER && (_MSC_VER < 1600)
|
||||
/* Pre-MSVC 2010 needs an implementation of stdint.h. */
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
/* For Visual Studio 6 in C++ mode and for many Visual Studio versions when
|
||||
* compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
|
||||
* or compiler give many errors like this:
|
||||
*
|
||||
* error C2733: second C linkage of overloaded function 'wmemchr' not allowed
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
# include <wchar.h>
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Define _W64 macros to mark types changing their size, like intptr_t. */
|
||||
#ifndef _W64
|
||||
# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
|
||||
# define _W64 __w64
|
||||
# else
|
||||
# define _W64
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/* 7.18.1 Integer types. */
|
||||
|
||||
/* 7.18.1.1 Exact-width integer types. */
|
||||
|
||||
/* Visual Studio 6 and Embedded Visual C++ 4 doesn't
|
||||
* realize that, e.g. char has the same size as __int8
|
||||
* so we give up on __intX for them.
|
||||
*/
|
||||
#if (_MSC_VER < 1300)
|
||||
typedef signed char int8_t;
|
||||
typedef signed short int16_t;
|
||||
typedef signed int int32_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
#else
|
||||
typedef signed __int8 int8_t;
|
||||
typedef signed __int16 int16_t;
|
||||
typedef signed __int32 int32_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
#endif
|
||||
typedef signed __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
|
||||
|
||||
/* 7.18.1.2 Minimum-width integer types. */
|
||||
typedef int8_t int_least8_t;
|
||||
typedef int16_t int_least16_t;
|
||||
typedef int32_t int_least32_t;
|
||||
typedef int64_t int_least64_t;
|
||||
typedef uint8_t uint_least8_t;
|
||||
typedef uint16_t uint_least16_t;
|
||||
typedef uint32_t uint_least32_t;
|
||||
typedef uint64_t uint_least64_t;
|
||||
|
||||
/* 7.18.1.3 Fastest minimum-width integer types. */
|
||||
typedef int8_t int_fast8_t;
|
||||
typedef int16_t int_fast16_t;
|
||||
typedef int32_t int_fast32_t;
|
||||
typedef int64_t int_fast64_t;
|
||||
typedef uint8_t uint_fast8_t;
|
||||
typedef uint16_t uint_fast16_t;
|
||||
typedef uint32_t uint_fast32_t;
|
||||
typedef uint64_t uint_fast64_t;
|
||||
|
||||
/* 7.18.1.4 Integer types capable of holding object pointers. */
|
||||
#ifdef _WIN64 /* [ */
|
||||
typedef signed __int64 intptr_t;
|
||||
typedef unsigned __int64 uintptr_t;
|
||||
#else /* _WIN64 ][ */
|
||||
typedef _W64 signed int intptr_t;
|
||||
typedef _W64 unsigned int uintptr_t;
|
||||
#endif /* _WIN64 ] */
|
||||
|
||||
/* 7.18.1.5 Greatest-width integer types. */
|
||||
typedef int64_t intmax_t;
|
||||
typedef uint64_t uintmax_t;
|
||||
|
||||
/* 7.18.2 Limits of specified-width integer types. */
|
||||
|
||||
#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS)
|
||||
/* [ See footnote 220 at page 257 and footnote 221 at page 259. */
|
||||
|
||||
/* 7.18.2.1 Limits of exact-width integer types. */
|
||||
#define INT8_MIN ((int8_t)_I8_MIN)
|
||||
#define INT8_MAX _I8_MAX
|
||||
#define INT16_MIN ((int16_t)_I16_MIN)
|
||||
#define INT16_MAX _I16_MAX
|
||||
#define INT32_MIN ((int32_t)_I32_MIN)
|
||||
#define INT32_MAX _I32_MAX
|
||||
#define INT64_MIN ((int64_t)_I64_MIN)
|
||||
#define INT64_MAX _I64_MAX
|
||||
#define UINT8_MAX _UI8_MAX
|
||||
#define UINT16_MAX _UI16_MAX
|
||||
#define UINT32_MAX _UI32_MAX
|
||||
#define UINT64_MAX _UI64_MAX
|
||||
|
||||
/* 7.18.2.2 Limits of minimum-width integer types. */
|
||||
#define INT_LEAST8_MIN INT8_MIN
|
||||
#define INT_LEAST8_MAX INT8_MAX
|
||||
#define INT_LEAST16_MIN INT16_MIN
|
||||
#define INT_LEAST16_MAX INT16_MAX
|
||||
#define INT_LEAST32_MIN INT32_MIN
|
||||
#define INT_LEAST32_MAX INT32_MAX
|
||||
#define INT_LEAST64_MIN INT64_MIN
|
||||
#define INT_LEAST64_MAX INT64_MAX
|
||||
#define UINT_LEAST8_MAX UINT8_MAX
|
||||
#define UINT_LEAST16_MAX UINT16_MAX
|
||||
#define UINT_LEAST32_MAX UINT32_MAX
|
||||
#define UINT_LEAST64_MAX UINT64_MAX
|
||||
|
||||
/* 7.18.2.3 Limits of fastest minimum-width integer types. */
|
||||
#define INT_FAST8_MIN INT8_MIN
|
||||
#define INT_FAST8_MAX INT8_MAX
|
||||
#define INT_FAST16_MIN INT16_MIN
|
||||
#define INT_FAST16_MAX INT16_MAX
|
||||
#define INT_FAST32_MIN INT32_MIN
|
||||
#define INT_FAST32_MAX INT32_MAX
|
||||
#define INT_FAST64_MIN INT64_MIN
|
||||
#define INT_FAST64_MAX INT64_MAX
|
||||
#define UINT_FAST8_MAX UINT8_MAX
|
||||
#define UINT_FAST16_MAX UINT16_MAX
|
||||
#define UINT_FAST32_MAX UINT32_MAX
|
||||
#define UINT_FAST64_MAX UINT64_MAX
|
||||
|
||||
/* 7.18.2.4 Limits of integer types capable of holding object pointers. */
|
||||
#ifdef _WIN64 /* [ */
|
||||
# define INTPTR_MIN INT64_MIN
|
||||
# define INTPTR_MAX INT64_MAX
|
||||
# define UINTPTR_MAX UINT64_MAX
|
||||
#else /* _WIN64 ][ */
|
||||
# define INTPTR_MIN INT32_MIN
|
||||
# define INTPTR_MAX INT32_MAX
|
||||
# define UINTPTR_MAX UINT32_MAX
|
||||
#endif /* _WIN64 ] */
|
||||
|
||||
/* 7.18.2.5 Limits of greatest-width integer types */
|
||||
#define INTMAX_MIN INT64_MIN
|
||||
#define INTMAX_MAX INT64_MAX
|
||||
#define UINTMAX_MAX UINT64_MAX
|
||||
|
||||
/* 7.18.3 Limits of other integer types */
|
||||
|
||||
#ifdef _WIN64 /* [ */
|
||||
# define PTRDIFF_MIN _I64_MIN
|
||||
# define PTRDIFF_MAX _I64_MAX
|
||||
#else /* _WIN64 ][ */
|
||||
# define PTRDIFF_MIN _I32_MIN
|
||||
# define PTRDIFF_MAX _I32_MAX
|
||||
#endif /* _WIN64 ] */
|
||||
|
||||
#define SIG_ATOMIC_MIN INT_MIN
|
||||
#define SIG_ATOMIC_MAX INT_MAX
|
||||
|
||||
#ifndef SIZE_MAX /* [ */
|
||||
# ifdef _WIN64 /* [ */
|
||||
# define SIZE_MAX _UI64_MAX
|
||||
# else /* _WIN64 ][ */
|
||||
# define SIZE_MAX _UI32_MAX
|
||||
# endif /* _WIN64 ] */
|
||||
#endif /* SIZE_MAX ] */
|
||||
|
||||
/* WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h> */
|
||||
#ifndef WCHAR_MIN /* [ */
|
||||
# define WCHAR_MIN 0
|
||||
#endif /* WCHAR_MIN ] */
|
||||
#ifndef WCHAR_MAX // [
|
||||
# define WCHAR_MAX _UI16_MAX
|
||||
#endif /* WCHAR_MAX ] */
|
||||
|
||||
#define WINT_MIN 0
|
||||
#define WINT_MAX _UI16_MAX
|
||||
|
||||
#endif /* __STDC_LIMIT_MACROS ] */
|
||||
|
||||
/* 7.18.4 Limits of other integer types */
|
||||
|
||||
#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS)
|
||||
/* [ See footnote 224 at page 260 */
|
||||
|
||||
/* 7.18.4.1 Macros for minimum-width integer constants */
|
||||
|
||||
#define INT8_C(val) val##i8
|
||||
#define INT16_C(val) val##i16
|
||||
#define INT32_C(val) val##i32
|
||||
#define INT64_C(val) val##i64
|
||||
|
||||
#define UINT8_C(val) val##ui8
|
||||
#define UINT16_C(val) val##ui16
|
||||
#define UINT32_C(val) val##ui32
|
||||
#define UINT64_C(val) val##ui64
|
||||
|
||||
/* 7.18.4.2 Macros for greatest-width integer constants */
|
||||
#define INTMAX_C INT64_C
|
||||
#define UINTMAX_C UINT64_C
|
||||
|
||||
#endif
|
||||
/* __STDC_CONSTANT_MACROS ] */
|
||||
|
||||
#else
|
||||
/* Sanity for everything else. */
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,62 +1,62 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (posix_string.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_COMPAT_POSIX_STRING_H
|
||||
#define __LIBRETRO_SDK_COMPAT_POSIX_STRING_H
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <compat/msvc.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#undef strtok_r
|
||||
#define strtok_r(str, delim, saveptr) retro_strtok_r__(str, delim, saveptr)
|
||||
|
||||
char *strtok_r(char *str, const char *delim, char **saveptr);
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#undef strcasecmp
|
||||
#undef strdup
|
||||
#define strcasecmp(a, b) retro_strcasecmp__(a, b)
|
||||
#define strdup(orig) retro_strdup__(orig)
|
||||
int strcasecmp(const char *a, const char *b);
|
||||
char *strdup(const char *orig);
|
||||
|
||||
#if _MSC_VER < 1200
|
||||
#undef isblank
|
||||
#define isblank(c) retro_isblank__(c)
|
||||
int isblank(int c);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (posix_string.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_COMPAT_POSIX_STRING_H
|
||||
#define __LIBRETRO_SDK_COMPAT_POSIX_STRING_H
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <compat/msvc.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#undef strtok_r
|
||||
#define strtok_r(str, delim, saveptr) retro_strtok_r__(str, delim, saveptr)
|
||||
|
||||
char *strtok_r(char *str, const char *delim, char **saveptr);
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#undef strcasecmp
|
||||
#undef strdup
|
||||
#define strcasecmp(a, b) retro_strcasecmp__(a, b)
|
||||
#define strdup(orig) retro_strdup__(orig)
|
||||
int strcasecmp(const char *a, const char *b);
|
||||
char *strdup(const char *orig);
|
||||
|
||||
#if _MSC_VER < 1200
|
||||
#undef isblank
|
||||
#define isblank(c) retro_isblank__(c)
|
||||
int isblank(int c);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,49 +1,49 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (strcasestr.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_COMPAT_STRCASESTR_H
|
||||
#define __LIBRETRO_SDK_COMPAT_STRCASESTR_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(RARCH_INTERNAL) && defined(HAVE_CONFIG_H)
|
||||
#include "../../../config.h"
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRCASESTR
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Avoid possible naming collisions during link
|
||||
* since we prefer to use the actual name. */
|
||||
#define strcasestr(haystack, needle) strcasestr_retro__(haystack, needle)
|
||||
|
||||
char *strcasestr(const char *haystack, const char *needle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (strcasestr.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_COMPAT_STRCASESTR_H
|
||||
#define __LIBRETRO_SDK_COMPAT_STRCASESTR_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(RARCH_INTERNAL) && defined(HAVE_CONFIG_H)
|
||||
#include "../../../config.h"
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRCASESTR
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Avoid possible naming collisions during link
|
||||
* since we prefer to use the actual name. */
|
||||
#define strcasestr(haystack, needle) strcasestr_retro__(haystack, needle)
|
||||
|
||||
char *strcasestr(const char *haystack, const char *needle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,60 +1,60 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (strl.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_COMPAT_STRL_H
|
||||
#define __LIBRETRO_SDK_COMPAT_STRL_H
|
||||
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../../../config.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __MACH__
|
||||
#ifndef HAVE_STRL
|
||||
#define HAVE_STRL
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRL
|
||||
/* Avoid possible naming collisions during link since
|
||||
* we prefer to use the actual name. */
|
||||
#define strlcpy(dst, src, size) strlcpy_retro__(dst, src, size)
|
||||
|
||||
#define strlcat(dst, src, size) strlcat_retro__(dst, src, size)
|
||||
|
||||
size_t strlcpy(char *dest, const char *source, size_t size);
|
||||
size_t strlcat(char *dest, const char *source, size_t size);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (strl.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_COMPAT_STRL_H
|
||||
#define __LIBRETRO_SDK_COMPAT_STRL_H
|
||||
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../../../config.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __MACH__
|
||||
#ifndef HAVE_STRL
|
||||
#define HAVE_STRL
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRL
|
||||
/* Avoid possible naming collisions during link since
|
||||
* we prefer to use the actual name. */
|
||||
#define strlcpy(dst, src, size) strlcpy_retro__(dst, src, size)
|
||||
|
||||
#define strlcat(dst, src, size) strlcat_retro__(dst, src, size)
|
||||
|
||||
size_t strlcpy(char *dest, const char *source, size_t size);
|
||||
size_t strlcat(char *dest, const char *source, size_t size);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,265 +1,265 @@
|
|||
#ifndef _COMPAT_ZUTIL_H
|
||||
#define _COMPAT_ZUTIL_H
|
||||
|
||||
#ifdef WANT_ZLIB
|
||||
|
||||
/* zutil.h -- internal interface and configuration of the compression library
|
||||
* Copyright (C) 1995-2013 Jean-loup Gailly.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* WARNING: this file should *not* be used by applications. It is
|
||||
part of the implementation of the compression library and is
|
||||
subject to change. Applications should only use zlib.h.
|
||||
*/
|
||||
|
||||
/* @(#) $Id$ */
|
||||
|
||||
#ifndef ZUTIL_H
|
||||
#define ZUTIL_H
|
||||
|
||||
#ifdef HAVE_HIDDEN
|
||||
# define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
|
||||
#else
|
||||
# define ZLIB_INTERNAL
|
||||
#endif
|
||||
|
||||
#include <compat/zlib.h>
|
||||
|
||||
#if defined(STDC) && !defined(Z_SOLO)
|
||||
# if !(defined(_WIN32_WCE) && defined(_MSC_VER))
|
||||
# include <stddef.h>
|
||||
# endif
|
||||
# include <string.h>
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef Z_SOLO
|
||||
typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */
|
||||
#endif
|
||||
|
||||
#ifndef local
|
||||
# define local static
|
||||
#endif
|
||||
/* compile with -Dlocal if your debugger can't find static symbols */
|
||||
|
||||
typedef unsigned char uch;
|
||||
typedef uch FAR uchf;
|
||||
typedef unsigned short ush;
|
||||
typedef ush FAR ushf;
|
||||
typedef unsigned long ulg;
|
||||
|
||||
extern char z_errmsg[10][21]; /* indexed by 2-zlib_error */
|
||||
/* (array size given to avoid silly warnings with Visual C++) */
|
||||
/* (array entry size given to avoid silly string cast warnings) */
|
||||
|
||||
#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
|
||||
|
||||
#define ERR_RETURN(strm,err) \
|
||||
return (strm->msg = ERR_MSG(err), (err))
|
||||
/* To be used only when the state is known to be valid */
|
||||
|
||||
/* common constants */
|
||||
|
||||
#ifndef DEF_WBITS
|
||||
# define DEF_WBITS MAX_WBITS
|
||||
#endif
|
||||
/* default windowBits for decompression. MAX_WBITS is for compression only */
|
||||
|
||||
#if MAX_MEM_LEVEL >= 8
|
||||
# define DEF_MEM_LEVEL 8
|
||||
#else
|
||||
# define DEF_MEM_LEVEL MAX_MEM_LEVEL
|
||||
#endif
|
||||
/* default memLevel */
|
||||
|
||||
#define STORED_BLOCK 0
|
||||
#define STATIC_TREES 1
|
||||
#define DYN_TREES 2
|
||||
/* The three kinds of block type */
|
||||
|
||||
#define MIN_MATCH 3
|
||||
#define MAX_MATCH 258
|
||||
/* The minimum and maximum match lengths */
|
||||
|
||||
#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
|
||||
|
||||
/* target dependencies */
|
||||
|
||||
#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
|
||||
# define OS_CODE 0x00
|
||||
# ifndef Z_SOLO
|
||||
# if defined(__TURBOC__) || defined(__BORLANDC__)
|
||||
# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
|
||||
/* Allow compilation with ANSI keywords only enabled */
|
||||
void _Cdecl farfree( void *block );
|
||||
void *_Cdecl farmalloc( unsigned long nbytes );
|
||||
# else
|
||||
# include <alloc.h>
|
||||
# endif
|
||||
# else /* MSC or DJGPP */
|
||||
# include <malloc.h>
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef AMIGA
|
||||
# define OS_CODE 0x01
|
||||
#endif
|
||||
|
||||
#if defined(VAXC) || defined(VMS)
|
||||
# define OS_CODE 0x02
|
||||
# define F_OPEN(name, mode) \
|
||||
fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
|
||||
#endif
|
||||
|
||||
#if defined(ATARI) || defined(atarist)
|
||||
# define OS_CODE 0x05
|
||||
#endif
|
||||
|
||||
#ifdef OS2
|
||||
# define OS_CODE 0x06
|
||||
# if defined(M_I86) && !defined(Z_SOLO)
|
||||
# include <malloc.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(MACOS) || defined(TARGET_OS_MAC)
|
||||
# define OS_CODE 0x07
|
||||
# ifndef Z_SOLO
|
||||
# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
|
||||
# include <unix.h> /* for fdopen */
|
||||
# else
|
||||
# ifndef fdopen
|
||||
# define fdopen(fd,mode) NULL /* No fdopen() */
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef TOPS20
|
||||
# define OS_CODE 0x0a
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */
|
||||
# define OS_CODE 0x0b
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __50SERIES /* Prime/PRIMOS */
|
||||
# define OS_CODE 0x0f
|
||||
#endif
|
||||
|
||||
#if defined(_BEOS_) || defined(RISCOS)
|
||||
# define fdopen(fd,mode) NULL /* No fdopen() */
|
||||
#endif
|
||||
|
||||
#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX
|
||||
# if defined(_WIN32_WCE)
|
||||
# define fdopen(fd,mode) NULL /* No fdopen() */
|
||||
# ifndef _PTRDIFF_T_DEFINED
|
||||
typedef int ptrdiff_t;
|
||||
# define _PTRDIFF_T_DEFINED
|
||||
# endif
|
||||
# else
|
||||
# define fdopen(fd,type) _fdopen(fd,type)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(__BORLANDC__) && !defined(MSDOS)
|
||||
#pragma warn -8004
|
||||
#pragma warn -8008
|
||||
#pragma warn -8066
|
||||
#endif
|
||||
|
||||
/* provide prototypes for these when building zlib without LFS */
|
||||
#if !defined(_WIN32) && \
|
||||
(!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0)
|
||||
ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
|
||||
ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
|
||||
#endif
|
||||
|
||||
/* common defaults */
|
||||
|
||||
#ifndef OS_CODE
|
||||
# define OS_CODE 0x03 /* assume Unix */
|
||||
#endif
|
||||
|
||||
#ifndef F_OPEN
|
||||
# define F_OPEN(name, mode) fopen((name), (mode))
|
||||
#endif
|
||||
|
||||
/* functions */
|
||||
|
||||
#if defined(pyr) || defined(Z_SOLO)
|
||||
# define NO_MEMCPY
|
||||
#endif
|
||||
#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
|
||||
/* Use our own functions for small and medium model with MSC <= 5.0.
|
||||
* You may have to use the same strategy for Borland C (untested).
|
||||
* The __SC__ check is for Symantec.
|
||||
*/
|
||||
# define NO_MEMCPY
|
||||
#endif
|
||||
#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
|
||||
# define HAVE_MEMCPY
|
||||
#endif
|
||||
#ifdef HAVE_MEMCPY
|
||||
# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
|
||||
# define zmemcpy _fmemcpy
|
||||
# define zmemcmp _fmemcmp
|
||||
# define zmemzero(dest, len) _fmemset(dest, 0, len)
|
||||
# else
|
||||
# define zmemcpy memcpy
|
||||
# define zmemcmp memcmp
|
||||
# define zmemzero(dest, len) memset(dest, 0, len)
|
||||
# endif
|
||||
#else
|
||||
void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
|
||||
int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
|
||||
void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len));
|
||||
#endif
|
||||
|
||||
/* Diagnostic functions */
|
||||
#ifdef DEBUG
|
||||
# include <stdio.h>
|
||||
extern int ZLIB_INTERNAL z_verbose;
|
||||
extern void ZLIB_INTERNAL z_error OF((char *m));
|
||||
# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
|
||||
# define Trace(x) {if (z_verbose>=0) fprintf x ;}
|
||||
# define Tracev(x) {if (z_verbose>0) fprintf x ;}
|
||||
# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
|
||||
# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
|
||||
# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
|
||||
#else
|
||||
# define Assert(cond,msg)
|
||||
# define Trace(x)
|
||||
# define Tracev(x)
|
||||
# define Tracevv(x)
|
||||
# define Tracec(c,x)
|
||||
# define Tracecv(c,x)
|
||||
#endif
|
||||
|
||||
#ifndef Z_SOLO
|
||||
voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items,
|
||||
unsigned size));
|
||||
void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr));
|
||||
#endif
|
||||
|
||||
#define ZALLOC(strm, items, size) \
|
||||
(*((strm)->zalloc))((strm)->opaque, (items), (size))
|
||||
#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
|
||||
#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
|
||||
|
||||
/* Reverse the bytes in a 32-bit value */
|
||||
#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
|
||||
(((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
|
||||
|
||||
#endif /* ZUTIL_H */
|
||||
|
||||
#else
|
||||
#include <zutil.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#ifndef _COMPAT_ZUTIL_H
|
||||
#define _COMPAT_ZUTIL_H
|
||||
|
||||
#ifdef WANT_ZLIB
|
||||
|
||||
/* zutil.h -- internal interface and configuration of the compression library
|
||||
* Copyright (C) 1995-2013 Jean-loup Gailly.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* WARNING: this file should *not* be used by applications. It is
|
||||
part of the implementation of the compression library and is
|
||||
subject to change. Applications should only use zlib.h.
|
||||
*/
|
||||
|
||||
/* @(#) $Id$ */
|
||||
|
||||
#ifndef ZUTIL_H
|
||||
#define ZUTIL_H
|
||||
|
||||
#ifdef HAVE_HIDDEN
|
||||
# define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
|
||||
#else
|
||||
# define ZLIB_INTERNAL
|
||||
#endif
|
||||
|
||||
#include <compat/zlib.h>
|
||||
|
||||
#if defined(STDC) && !defined(Z_SOLO)
|
||||
# if !(defined(_WIN32_WCE) && defined(_MSC_VER))
|
||||
# include <stddef.h>
|
||||
# endif
|
||||
# include <string.h>
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef Z_SOLO
|
||||
typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */
|
||||
#endif
|
||||
|
||||
#ifndef local
|
||||
# define local static
|
||||
#endif
|
||||
/* compile with -Dlocal if your debugger can't find static symbols */
|
||||
|
||||
typedef unsigned char uch;
|
||||
typedef uch FAR uchf;
|
||||
typedef unsigned short ush;
|
||||
typedef ush FAR ushf;
|
||||
typedef unsigned long ulg;
|
||||
|
||||
extern char z_errmsg[10][21]; /* indexed by 2-zlib_error */
|
||||
/* (array size given to avoid silly warnings with Visual C++) */
|
||||
/* (array entry size given to avoid silly string cast warnings) */
|
||||
|
||||
#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
|
||||
|
||||
#define ERR_RETURN(strm,err) \
|
||||
return (strm->msg = ERR_MSG(err), (err))
|
||||
/* To be used only when the state is known to be valid */
|
||||
|
||||
/* common constants */
|
||||
|
||||
#ifndef DEF_WBITS
|
||||
# define DEF_WBITS MAX_WBITS
|
||||
#endif
|
||||
/* default windowBits for decompression. MAX_WBITS is for compression only */
|
||||
|
||||
#if MAX_MEM_LEVEL >= 8
|
||||
# define DEF_MEM_LEVEL 8
|
||||
#else
|
||||
# define DEF_MEM_LEVEL MAX_MEM_LEVEL
|
||||
#endif
|
||||
/* default memLevel */
|
||||
|
||||
#define STORED_BLOCK 0
|
||||
#define STATIC_TREES 1
|
||||
#define DYN_TREES 2
|
||||
/* The three kinds of block type */
|
||||
|
||||
#define MIN_MATCH 3
|
||||
#define MAX_MATCH 258
|
||||
/* The minimum and maximum match lengths */
|
||||
|
||||
#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
|
||||
|
||||
/* target dependencies */
|
||||
|
||||
#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
|
||||
# define OS_CODE 0x00
|
||||
# ifndef Z_SOLO
|
||||
# if defined(__TURBOC__) || defined(__BORLANDC__)
|
||||
# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
|
||||
/* Allow compilation with ANSI keywords only enabled */
|
||||
void _Cdecl farfree( void *block );
|
||||
void *_Cdecl farmalloc( unsigned long nbytes );
|
||||
# else
|
||||
# include <alloc.h>
|
||||
# endif
|
||||
# else /* MSC or DJGPP */
|
||||
# include <malloc.h>
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef AMIGA
|
||||
# define OS_CODE 0x01
|
||||
#endif
|
||||
|
||||
#if defined(VAXC) || defined(VMS)
|
||||
# define OS_CODE 0x02
|
||||
# define F_OPEN(name, mode) \
|
||||
fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
|
||||
#endif
|
||||
|
||||
#if defined(ATARI) || defined(atarist)
|
||||
# define OS_CODE 0x05
|
||||
#endif
|
||||
|
||||
#ifdef OS2
|
||||
# define OS_CODE 0x06
|
||||
# if defined(M_I86) && !defined(Z_SOLO)
|
||||
# include <malloc.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(MACOS) || defined(TARGET_OS_MAC)
|
||||
# define OS_CODE 0x07
|
||||
# ifndef Z_SOLO
|
||||
# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
|
||||
# include <unix.h> /* for fdopen */
|
||||
# else
|
||||
# ifndef fdopen
|
||||
# define fdopen(fd,mode) NULL /* No fdopen() */
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef TOPS20
|
||||
# define OS_CODE 0x0a
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */
|
||||
# define OS_CODE 0x0b
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __50SERIES /* Prime/PRIMOS */
|
||||
# define OS_CODE 0x0f
|
||||
#endif
|
||||
|
||||
#if defined(_BEOS_) || defined(RISCOS)
|
||||
# define fdopen(fd,mode) NULL /* No fdopen() */
|
||||
#endif
|
||||
|
||||
#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX
|
||||
# if defined(_WIN32_WCE)
|
||||
# define fdopen(fd,mode) NULL /* No fdopen() */
|
||||
# ifndef _PTRDIFF_T_DEFINED
|
||||
typedef int ptrdiff_t;
|
||||
# define _PTRDIFF_T_DEFINED
|
||||
# endif
|
||||
# else
|
||||
# define fdopen(fd,type) _fdopen(fd,type)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(__BORLANDC__) && !defined(MSDOS)
|
||||
#pragma warn -8004
|
||||
#pragma warn -8008
|
||||
#pragma warn -8066
|
||||
#endif
|
||||
|
||||
/* provide prototypes for these when building zlib without LFS */
|
||||
#if !defined(_WIN32) && \
|
||||
(!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0)
|
||||
ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
|
||||
ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
|
||||
#endif
|
||||
|
||||
/* common defaults */
|
||||
|
||||
#ifndef OS_CODE
|
||||
# define OS_CODE 0x03 /* assume Unix */
|
||||
#endif
|
||||
|
||||
#ifndef F_OPEN
|
||||
# define F_OPEN(name, mode) fopen((name), (mode))
|
||||
#endif
|
||||
|
||||
/* functions */
|
||||
|
||||
#if defined(pyr) || defined(Z_SOLO)
|
||||
# define NO_MEMCPY
|
||||
#endif
|
||||
#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
|
||||
/* Use our own functions for small and medium model with MSC <= 5.0.
|
||||
* You may have to use the same strategy for Borland C (untested).
|
||||
* The __SC__ check is for Symantec.
|
||||
*/
|
||||
# define NO_MEMCPY
|
||||
#endif
|
||||
#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
|
||||
# define HAVE_MEMCPY
|
||||
#endif
|
||||
#ifdef HAVE_MEMCPY
|
||||
# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
|
||||
# define zmemcpy _fmemcpy
|
||||
# define zmemcmp _fmemcmp
|
||||
# define zmemzero(dest, len) _fmemset(dest, 0, len)
|
||||
# else
|
||||
# define zmemcpy memcpy
|
||||
# define zmemcmp memcmp
|
||||
# define zmemzero(dest, len) memset(dest, 0, len)
|
||||
# endif
|
||||
#else
|
||||
void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
|
||||
int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
|
||||
void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len));
|
||||
#endif
|
||||
|
||||
/* Diagnostic functions */
|
||||
#ifdef DEBUG
|
||||
# include <stdio.h>
|
||||
extern int ZLIB_INTERNAL z_verbose;
|
||||
extern void ZLIB_INTERNAL z_error OF((char *m));
|
||||
# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
|
||||
# define Trace(x) {if (z_verbose>=0) fprintf x ;}
|
||||
# define Tracev(x) {if (z_verbose>0) fprintf x ;}
|
||||
# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
|
||||
# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
|
||||
# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
|
||||
#else
|
||||
# define Assert(cond,msg)
|
||||
# define Trace(x)
|
||||
# define Tracev(x)
|
||||
# define Tracevv(x)
|
||||
# define Tracec(c,x)
|
||||
# define Tracecv(c,x)
|
||||
#endif
|
||||
|
||||
#ifndef Z_SOLO
|
||||
voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items,
|
||||
unsigned size));
|
||||
void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr));
|
||||
#endif
|
||||
|
||||
#define ZALLOC(strm, items, size) \
|
||||
(*((strm)->zalloc))((strm)->opaque, (items), (size))
|
||||
#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
|
||||
#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
|
||||
|
||||
/* Reverse the bytes in a 32-bit value */
|
||||
#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
|
||||
(((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
|
||||
|
||||
#endif /* ZUTIL_H */
|
||||
|
||||
#else
|
||||
#include <zutil.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,74 +1,74 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (dylib.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 __DYLIB_H
|
||||
#define __DYLIB_H
|
||||
|
||||
#include <boolean.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_DYNAMIC) || defined(HAVE_DYLIB)
|
||||
#define NEED_DYNAMIC
|
||||
#else
|
||||
#undef NEED_DYNAMIC
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void *dylib_t;
|
||||
typedef void (*function_t)(void);
|
||||
|
||||
#ifdef NEED_DYNAMIC
|
||||
/**
|
||||
* dylib_load:
|
||||
* @path : Path to libretro core library.
|
||||
*
|
||||
* Platform independent dylib loading.
|
||||
*
|
||||
* Returns: library handle on success, otherwise NULL.
|
||||
**/
|
||||
dylib_t dylib_load(const char *path);
|
||||
|
||||
/**
|
||||
* dylib_close:
|
||||
* @lib : Library handle.
|
||||
*
|
||||
* Frees library handle.
|
||||
**/
|
||||
void dylib_close(dylib_t lib);
|
||||
|
||||
char *dylib_error(void);
|
||||
|
||||
function_t dylib_proc(dylib_t lib, const char *proc);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (dylib.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 __DYLIB_H
|
||||
#define __DYLIB_H
|
||||
|
||||
#include <boolean.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_DYNAMIC) || defined(HAVE_DYLIB)
|
||||
#define NEED_DYNAMIC
|
||||
#else
|
||||
#undef NEED_DYNAMIC
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void *dylib_t;
|
||||
typedef void (*function_t)(void);
|
||||
|
||||
#ifdef NEED_DYNAMIC
|
||||
/**
|
||||
* dylib_load:
|
||||
* @path : Path to libretro core library.
|
||||
*
|
||||
* Platform independent dylib loading.
|
||||
*
|
||||
* Returns: library handle on success, otherwise NULL.
|
||||
**/
|
||||
dylib_t dylib_load(const char *path);
|
||||
|
||||
/**
|
||||
* dylib_close:
|
||||
* @lib : Library handle.
|
||||
*
|
||||
* Frees library handle.
|
||||
**/
|
||||
void dylib_close(dylib_t lib);
|
||||
|
||||
char *dylib_error(void);
|
||||
|
||||
function_t dylib_proc(dylib_t lib, const char *proc);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,43 +1,43 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (utf.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_ENCODINGS_UTF_H
|
||||
#define _LIBRETRO_ENCODINGS_UTF_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <boolean.h>
|
||||
|
||||
size_t utf8_conv_utf32(uint32_t *out, size_t out_chars,
|
||||
const char *in, size_t in_size);
|
||||
|
||||
bool utf16_conv_utf8(uint8_t *out, size_t *out_chars,
|
||||
const uint16_t *in, size_t in_size);
|
||||
|
||||
size_t utf8len(const char *string);
|
||||
|
||||
size_t utf8cpy(char *d, size_t d_len, const char *s, size_t chars);
|
||||
|
||||
const char *utf8skip(const char *str, size_t chars);
|
||||
|
||||
#endif
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (utf.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_ENCODINGS_UTF_H
|
||||
#define _LIBRETRO_ENCODINGS_UTF_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <boolean.h>
|
||||
|
||||
size_t utf8_conv_utf32(uint32_t *out, size_t out_chars,
|
||||
const char *in, size_t in_size);
|
||||
|
||||
bool utf16_conv_utf8(uint8_t *out, size_t *out_chars,
|
||||
const uint16_t *in, size_t in_size);
|
||||
|
||||
size_t utf8len(const char *string);
|
||||
|
||||
size_t utf8cpy(char *d, size_t d_len, const char *s, size_t chars);
|
||||
|
||||
const char *utf8skip(const char *str, size_t chars);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,166 +1,166 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (config_file.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_CONFIG_FILE_H
|
||||
#define __LIBRETRO_SDK_CONFIG_FILE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <boolean.h>
|
||||
|
||||
#define CONFIG_GET_BOOL_BASE(conf, base, var, key) do { \
|
||||
bool tmp = false; \
|
||||
if (config_get_bool(conf, key, &tmp)) \
|
||||
base->var = tmp; \
|
||||
} while(0)
|
||||
|
||||
#define CONFIG_GET_INT_BASE(conf, base, var, key) do { \
|
||||
int tmp = 0; \
|
||||
if (config_get_int(conf, key, &tmp)) \
|
||||
base->var = tmp; \
|
||||
} while(0)
|
||||
|
||||
#define CONFIG_GET_FLOAT_BASE(conf, base, var, key) do { \
|
||||
float tmp = 0.0f; \
|
||||
if (config_get_float(conf, key, &tmp)) \
|
||||
base->var = tmp; \
|
||||
} while(0)
|
||||
|
||||
typedef struct config_file config_file_t;
|
||||
|
||||
/* Config file format
|
||||
* - # are treated as comments. Rest of the line is ignored.
|
||||
* - Format is: key = value. There can be as many spaces as you like in-between.
|
||||
* - Value can be wrapped inside "" for multiword strings. (foo = "hai u")
|
||||
* - #include includes a config file in-place.
|
||||
*
|
||||
* Path is relative to where config file was loaded unless an absolute path is chosen.
|
||||
* Key/value pairs from an #include are read-only, and cannot be modified.
|
||||
*/
|
||||
|
||||
/* Loads a config file. Returns NULL if file doesn't exist.
|
||||
* NULL path will create an empty config file. */
|
||||
config_file_t *config_file_new(const char *path);
|
||||
|
||||
/* Load a config file from a string. */
|
||||
config_file_t *config_file_new_from_string(const char *from_string);
|
||||
|
||||
/* Frees config file. */
|
||||
void config_file_free(config_file_t *conf);
|
||||
|
||||
/* Loads a new config, and appends its data to conf.
|
||||
* The key-value pairs of the new config file takes priority over the old. */
|
||||
bool config_append_file(config_file_t *conf, const char *path);
|
||||
|
||||
/* All extract functions return true when value is valid and exists.
|
||||
* Returns false otherwise. */
|
||||
|
||||
bool config_entry_exists(config_file_t *conf, const char *entry);
|
||||
|
||||
struct config_entry_list;
|
||||
struct config_file_entry
|
||||
{
|
||||
const char *key;
|
||||
const char *value;
|
||||
/* Used intentionally. Opaque here. */
|
||||
const struct config_entry_list *next;
|
||||
};
|
||||
|
||||
bool config_get_entry_list_head(config_file_t *conf, struct config_file_entry *entry);
|
||||
bool config_get_entry_list_next(struct config_file_entry *entry);
|
||||
|
||||
/* Extracts a double from config file. */
|
||||
bool config_get_double(config_file_t *conf, const char *entry, double *in);
|
||||
|
||||
/* Extracts a float from config file. */
|
||||
bool config_get_float(config_file_t *conf, const char *entry, float *in);
|
||||
|
||||
/* Extracts an int from config file. */
|
||||
bool config_get_int(config_file_t *conf, const char *entry, int *in);
|
||||
|
||||
/* Extracts an uint from config file. */
|
||||
bool config_get_uint(config_file_t *conf, const char *entry, unsigned *in);
|
||||
|
||||
#if defined(__STDC_VERSION__) && __STDC_VERSION__>=199901L
|
||||
/* Extracts an uint64 from config file. */
|
||||
bool config_get_uint64(config_file_t *conf, const char *entry, uint64_t *in);
|
||||
#endif
|
||||
|
||||
/* Extracts an unsigned int from config file treating input as hex. */
|
||||
bool config_get_hex(config_file_t *conf, const char *entry, unsigned *in);
|
||||
|
||||
/* Extracts a single char. If value consists of several chars,
|
||||
* this is an error. */
|
||||
bool config_get_char(config_file_t *conf, const char *entry, char *in);
|
||||
|
||||
/* Extracts an allocated string in *in. This must be free()-d if
|
||||
* this function succeeds. */
|
||||
bool config_get_string(config_file_t *conf, const char *entry, char **in);
|
||||
|
||||
/* Extracts a string to a preallocated buffer. Avoid memory allocation. */
|
||||
bool config_get_array(config_file_t *conf, const char *entry, char *s, size_t len);
|
||||
|
||||
/* Extracts a string to a preallocated buffer. Avoid memory allocation.
|
||||
* Recognized magic like ~/. Similar to config_get_array() otherwise. */
|
||||
bool config_get_path(config_file_t *conf, const char *entry, char *s, size_t len);
|
||||
|
||||
/* Extracts a string to a preallocated buffer. Avoid memory allocation. */
|
||||
bool config_get_config_path(config_file_t *conf, char *s, size_t len);
|
||||
|
||||
/* Extracts a boolean from config.
|
||||
* Valid boolean true are "true" and "1". Valid false are "false" and "0".
|
||||
* Other values will be treated as an error. */
|
||||
bool config_get_bool(config_file_t *conf, const char *entry, bool *in);
|
||||
|
||||
/* Setters. Similar to the getters.
|
||||
* Will not write to entry if the entry was obtained from an #include. */
|
||||
void config_set_double(config_file_t *conf, const char *entry, double value);
|
||||
void config_set_float(config_file_t *conf, const char *entry, float value);
|
||||
void config_set_int(config_file_t *conf, const char *entry, int val);
|
||||
void config_set_hex(config_file_t *conf, const char *entry, unsigned val);
|
||||
void config_set_uint64(config_file_t *conf, const char *entry, uint64_t val);
|
||||
void config_set_char(config_file_t *conf, const char *entry, char val);
|
||||
void config_set_string(config_file_t *conf, const char *entry, const char *val);
|
||||
void config_unset(config_file_t *conf, const char *key);
|
||||
void config_set_path(config_file_t *conf, const char *entry, const char *val);
|
||||
void config_set_bool(config_file_t *conf, const char *entry, bool val);
|
||||
|
||||
/* Write the current config to a file. */
|
||||
bool config_file_write(config_file_t *conf, const char *path);
|
||||
|
||||
/* Dump the current config to an already opened file.
|
||||
* Does not close the file. */
|
||||
void config_file_dump(config_file_t *conf, FILE *file);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (config_file.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_CONFIG_FILE_H
|
||||
#define __LIBRETRO_SDK_CONFIG_FILE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <boolean.h>
|
||||
|
||||
#define CONFIG_GET_BOOL_BASE(conf, base, var, key) do { \
|
||||
bool tmp = false; \
|
||||
if (config_get_bool(conf, key, &tmp)) \
|
||||
base->var = tmp; \
|
||||
} while(0)
|
||||
|
||||
#define CONFIG_GET_INT_BASE(conf, base, var, key) do { \
|
||||
int tmp = 0; \
|
||||
if (config_get_int(conf, key, &tmp)) \
|
||||
base->var = tmp; \
|
||||
} while(0)
|
||||
|
||||
#define CONFIG_GET_FLOAT_BASE(conf, base, var, key) do { \
|
||||
float tmp = 0.0f; \
|
||||
if (config_get_float(conf, key, &tmp)) \
|
||||
base->var = tmp; \
|
||||
} while(0)
|
||||
|
||||
typedef struct config_file config_file_t;
|
||||
|
||||
/* Config file format
|
||||
* - # are treated as comments. Rest of the line is ignored.
|
||||
* - Format is: key = value. There can be as many spaces as you like in-between.
|
||||
* - Value can be wrapped inside "" for multiword strings. (foo = "hai u")
|
||||
* - #include includes a config file in-place.
|
||||
*
|
||||
* Path is relative to where config file was loaded unless an absolute path is chosen.
|
||||
* Key/value pairs from an #include are read-only, and cannot be modified.
|
||||
*/
|
||||
|
||||
/* Loads a config file. Returns NULL if file doesn't exist.
|
||||
* NULL path will create an empty config file. */
|
||||
config_file_t *config_file_new(const char *path);
|
||||
|
||||
/* Load a config file from a string. */
|
||||
config_file_t *config_file_new_from_string(const char *from_string);
|
||||
|
||||
/* Frees config file. */
|
||||
void config_file_free(config_file_t *conf);
|
||||
|
||||
/* Loads a new config, and appends its data to conf.
|
||||
* The key-value pairs of the new config file takes priority over the old. */
|
||||
bool config_append_file(config_file_t *conf, const char *path);
|
||||
|
||||
/* All extract functions return true when value is valid and exists.
|
||||
* Returns false otherwise. */
|
||||
|
||||
bool config_entry_exists(config_file_t *conf, const char *entry);
|
||||
|
||||
struct config_entry_list;
|
||||
struct config_file_entry
|
||||
{
|
||||
const char *key;
|
||||
const char *value;
|
||||
/* Used intentionally. Opaque here. */
|
||||
const struct config_entry_list *next;
|
||||
};
|
||||
|
||||
bool config_get_entry_list_head(config_file_t *conf, struct config_file_entry *entry);
|
||||
bool config_get_entry_list_next(struct config_file_entry *entry);
|
||||
|
||||
/* Extracts a double from config file. */
|
||||
bool config_get_double(config_file_t *conf, const char *entry, double *in);
|
||||
|
||||
/* Extracts a float from config file. */
|
||||
bool config_get_float(config_file_t *conf, const char *entry, float *in);
|
||||
|
||||
/* Extracts an int from config file. */
|
||||
bool config_get_int(config_file_t *conf, const char *entry, int *in);
|
||||
|
||||
/* Extracts an uint from config file. */
|
||||
bool config_get_uint(config_file_t *conf, const char *entry, unsigned *in);
|
||||
|
||||
#if defined(__STDC_VERSION__) && __STDC_VERSION__>=199901L
|
||||
/* Extracts an uint64 from config file. */
|
||||
bool config_get_uint64(config_file_t *conf, const char *entry, uint64_t *in);
|
||||
#endif
|
||||
|
||||
/* Extracts an unsigned int from config file treating input as hex. */
|
||||
bool config_get_hex(config_file_t *conf, const char *entry, unsigned *in);
|
||||
|
||||
/* Extracts a single char. If value consists of several chars,
|
||||
* this is an error. */
|
||||
bool config_get_char(config_file_t *conf, const char *entry, char *in);
|
||||
|
||||
/* Extracts an allocated string in *in. This must be free()-d if
|
||||
* this function succeeds. */
|
||||
bool config_get_string(config_file_t *conf, const char *entry, char **in);
|
||||
|
||||
/* Extracts a string to a preallocated buffer. Avoid memory allocation. */
|
||||
bool config_get_array(config_file_t *conf, const char *entry, char *s, size_t len);
|
||||
|
||||
/* Extracts a string to a preallocated buffer. Avoid memory allocation.
|
||||
* Recognized magic like ~/. Similar to config_get_array() otherwise. */
|
||||
bool config_get_path(config_file_t *conf, const char *entry, char *s, size_t len);
|
||||
|
||||
/* Extracts a string to a preallocated buffer. Avoid memory allocation. */
|
||||
bool config_get_config_path(config_file_t *conf, char *s, size_t len);
|
||||
|
||||
/* Extracts a boolean from config.
|
||||
* Valid boolean true are "true" and "1". Valid false are "false" and "0".
|
||||
* Other values will be treated as an error. */
|
||||
bool config_get_bool(config_file_t *conf, const char *entry, bool *in);
|
||||
|
||||
/* Setters. Similar to the getters.
|
||||
* Will not write to entry if the entry was obtained from an #include. */
|
||||
void config_set_double(config_file_t *conf, const char *entry, double value);
|
||||
void config_set_float(config_file_t *conf, const char *entry, float value);
|
||||
void config_set_int(config_file_t *conf, const char *entry, int val);
|
||||
void config_set_hex(config_file_t *conf, const char *entry, unsigned val);
|
||||
void config_set_uint64(config_file_t *conf, const char *entry, uint64_t val);
|
||||
void config_set_char(config_file_t *conf, const char *entry, char val);
|
||||
void config_set_string(config_file_t *conf, const char *entry, const char *val);
|
||||
void config_unset(config_file_t *conf, const char *key);
|
||||
void config_set_path(config_file_t *conf, const char *entry, const char *val);
|
||||
void config_set_bool(config_file_t *conf, const char *entry, bool val);
|
||||
|
||||
/* Write the current config to a file. */
|
||||
bool config_file_write(config_file_t *conf, const char *path);
|
||||
|
||||
/* Dump the current config to an already opened file.
|
||||
* Does not close the file. */
|
||||
void config_file_dump(config_file_t *conf, FILE *file);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue