remove a bunch of eol-style properties

This commit is contained in:
zeromus 2016-03-21 02:02:11 +00:00
parent 6724231a2d
commit 655dd15cc1
268 changed files with 75573 additions and 75573 deletions

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

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

View File

@ -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

View File

@ -1,3 +1,3 @@
#ifndef __GNUC__
#pragma pack(pop)
#endif
#ifndef __GNUC__
#pragma pack(pop)
#endif

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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_

View File

@ -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

View File

@ -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(&regionWriteMask_USR[0], 0, sizeof(regionWriteMask_USR));
memset(&regionWriteMask_SYS[0], 0, sizeof(regionWriteMask_SYS));
memset(&regionReadMask_USR[0], 0, sizeof(regionReadMask_USR));
memset(&regionReadMask_SYS[0], 0, sizeof(regionReadMask_SYS));
memset(&regionExecuteMask_USR[0], 0, sizeof(regionExecuteMask_USR));
memset(&regionExecuteMask_SYS[0], 0, sizeof(regionExecuteMask_SYS));
memset(&regionWriteSet_USR[0], 0, sizeof(regionWriteSet_USR));
memset(&regionWriteSet_SYS[0], 0, sizeof(regionWriteSet_SYS));
memset(&regionReadSet_USR[0], 0, sizeof(regionReadSet_USR));
memset(&regionReadSet_SYS[0], 0, sizeof(regionReadSet_SYS));
memset(&regionExecuteSet_USR[0], 0, sizeof(regionExecuteSet_USR));
memset(&regionExecuteSet_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(&regionWriteMask_USR[0], 0, sizeof(regionWriteMask_USR));
memset(&regionWriteMask_SYS[0], 0, sizeof(regionWriteMask_SYS));
memset(&regionReadMask_USR[0], 0, sizeof(regionReadMask_USR));
memset(&regionReadMask_SYS[0], 0, sizeof(regionReadMask_SYS));
memset(&regionExecuteMask_USR[0], 0, sizeof(regionExecuteMask_USR));
memset(&regionExecuteMask_SYS[0], 0, sizeof(regionExecuteMask_SYS));
memset(&regionWriteSet_USR[0], 0, sizeof(regionWriteSet_USR));
memset(&regionWriteSet_SYS[0], 0, sizeof(regionWriteSet_SYS));
memset(&regionReadSet_USR[0], 0, sizeof(regionReadSet_USR));
memset(&regionReadSet_SYS[0], 0, sizeof(regionReadSet_SYS));
memset(&regionExecuteSet_USR[0], 0, sizeof(regionExecuteSet_USR));
memset(&regionExecuteSet_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__*/

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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_ */

View File

@ -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_ */

File diff suppressed because it is too large Load Diff

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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__*/

View File

@ -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

View File

@ -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

View File

@ -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__ */

View File

@ -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();

View File

@ -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__*/

View File

@ -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__*/

View File

@ -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__*/

View File

@ -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

View File

@ -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

View File

@ -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__*/

View File

@ -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

View File

@ -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 '?';
}

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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"
};

View File

@ -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

View File

@ -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++];
}

View File

@ -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);
}

View File

@ -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();
}

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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]);
}

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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