Merge branch 'master' of github.com:Themaister/SSNES

This commit is contained in:
Twinaphex 2012-04-18 15:36:53 +02:00
commit f764808578
13 changed files with 330 additions and 155 deletions

View File

@ -27,7 +27,7 @@ static xdk360_video_font_t m_Font;
void xdk360_console_draw(void)
{
xdk360_video_t *vid = (xdk360_video_t*)g_d3d;
D3DDevice *m_pd3dDevice = vid->xdk360_render_device;
D3DDevice *m_pd3dDevice = vid->d3d_render_device;
// The top line
unsigned int nTextLine = ( video_console.m_nCurLine -
@ -55,7 +55,7 @@ HRESULT xdk360_console_init( LPCSTR strFontFileName, unsigned long colBackColor,
unsigned long colTextColor)
{
xdk360_video_t *vid = (xdk360_video_t*)g_d3d;
D3DDevice *m_pd3dDevice = vid->xdk360_render_device;
D3DDevice *m_pd3dDevice = vid->d3d_render_device;
video_console.first_message = true;
video_console.m_Buffer = NULL;
@ -354,7 +354,7 @@ static HRESULT xdk360_video_font_create_shaders (xdk360_video_font_t * font)
// Cache this global into a register
xdk360_video_t *vid = (xdk360_video_t*)g_d3d;
D3DDevice *pd3dDevice = vid->xdk360_render_device;
D3DDevice *pd3dDevice = vid->d3d_render_device;
hr = pd3dDevice->CreateVertexDeclaration( decl, &s_FontLocals.m_pFontVertexDecl );
@ -482,7 +482,7 @@ HRESULT xdk360_video_font_init(xdk360_video_font_t * font, const char * strFontF
}
xdk360_video_t *vid = (xdk360_video_t*)g_d3d;
D3DDevice *pd3dDevice = vid->xdk360_render_device;
D3DDevice *pd3dDevice = vid->d3d_render_device;
// Initialize the window
D3DDISPLAYMODE DisplayMode;
@ -604,7 +604,7 @@ void xdk360_video_font_begin (xdk360_video_font_t * font)
{
// Cache the global pointer into a register
xdk360_video_t *vid = (xdk360_video_t*)g_d3d;
D3DDevice *pD3dDevice = vid->xdk360_render_device;
D3DDevice *pD3dDevice = vid->d3d_render_device;
// Save state
if( font->m_bSaveState )
@ -681,7 +681,7 @@ void xdk360_video_font_end(xdk360_video_font_t * font)
{
// Cache the global pointer into a register
xdk360_video_t *vid = (xdk360_video_t*)g_d3d;
D3DDevice *pD3dDevice = vid->xdk360_render_device;
D3DDevice *pD3dDevice = vid->d3d_render_device;
D3DDevice_SetTexture_Inline(pD3dDevice, 0, NULL);
D3DDevice_SetVertexDeclaration(pD3dDevice, NULL);
@ -711,7 +711,7 @@ void xdk360_video_font_draw_text(xdk360_video_font_t * font, float fOriginX, flo
return;
xdk360_video_t *vid = (xdk360_video_t*)g_d3d;
D3DDevice *pd3dDevice = vid->xdk360_render_device;
D3DDevice *pd3dDevice = vid->d3d_render_device;
// Set the color as a vertex shader constant
float vColor[4];

View File

@ -416,6 +416,7 @@ begin_shutdown:
if(path_file_exists(SYS_CONFIG_FILE))
save_settings();
menu_deinit();
xdk360_video_deinit();
ssnes_exec();

View File

@ -489,7 +489,7 @@ int menu_init (void)
xdk360_video_t *vid = (xdk360_video_t*)g_d3d;
hr = app.InitShared(vid->xdk360_render_device, &vid->d3dpp, XuiPNGTextureLoader);
hr = app.InitShared(vid->d3d_render_device, &vid->d3dpp, XuiPNGTextureLoader);
if (FAILED(hr))
{
@ -526,6 +526,11 @@ int menu_init (void)
return 0;
}
void menu_deinit (void)
{
app.Uninit();
}
void menu_loop(void)
{
g_console.menu_enable = true;
@ -544,8 +549,8 @@ void menu_loop(void)
ssnes_render_cached_frame();
}
else
D3DDevice_Clear(vid->xdk360_render_device, 0, NULL,
D3DCLEAR_TARGET, D3DCOLOR_ARGB(255, 32, 32, 64), 1.0, 0, FALSE);
vid->d3d_render_device->Clear(0, NULL, D3DCLEAR_TARGET,
D3DCOLOR_ARGB(255, 32, 32, 64), 1.0f, 0);
XINPUT_STATE state;
XInputGetState(0, &state);

View File

@ -138,6 +138,7 @@ public:
};
int menu_init (void);
void menu_deinit (void);
void menu_loop (void);
extern CSSNES app;

View File

@ -14,8 +14,10 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
// Xbox 360-specific headers
#include <xtl.h>
#include <xgraphics.h>
#include "../driver.h"
#include "xdk360_video.h"
#include "xdk360_video_resources.h"
@ -34,6 +36,76 @@ static bool g_first_msg;
unsigned g_frame_count;
void *g_d3d;
/* Xbox 360 specific code */
const DWORD g_MapLinearToSrgbGpuFormat[] =
{
GPUTEXTUREFORMAT_1_REVERSE,
GPUTEXTUREFORMAT_1,
GPUTEXTUREFORMAT_8,
GPUTEXTUREFORMAT_1_5_5_5,
GPUTEXTUREFORMAT_5_6_5,
GPUTEXTUREFORMAT_6_5_5,
GPUTEXTUREFORMAT_8_8_8_8_AS_16_16_16_16,
GPUTEXTUREFORMAT_2_10_10_10_AS_16_16_16_16,
GPUTEXTUREFORMAT_8_A,
GPUTEXTUREFORMAT_8_B,
GPUTEXTUREFORMAT_8_8,
GPUTEXTUREFORMAT_Cr_Y1_Cb_Y0_REP,
GPUTEXTUREFORMAT_Y1_Cr_Y0_Cb_REP,
GPUTEXTUREFORMAT_16_16_EDRAM,
GPUTEXTUREFORMAT_8_8_8_8_A,
GPUTEXTUREFORMAT_4_4_4_4,
GPUTEXTUREFORMAT_10_11_11_AS_16_16_16_16,
GPUTEXTUREFORMAT_11_11_10_AS_16_16_16_16,
GPUTEXTUREFORMAT_DXT1_AS_16_16_16_16,
GPUTEXTUREFORMAT_DXT2_3_AS_16_16_16_16,
GPUTEXTUREFORMAT_DXT4_5_AS_16_16_16_16,
GPUTEXTUREFORMAT_16_16_16_16_EDRAM,
GPUTEXTUREFORMAT_24_8,
GPUTEXTUREFORMAT_24_8_FLOAT,
GPUTEXTUREFORMAT_16,
GPUTEXTUREFORMAT_16_16,
GPUTEXTUREFORMAT_16_16_16_16,
GPUTEXTUREFORMAT_16_EXPAND,
GPUTEXTUREFORMAT_16_16_EXPAND,
GPUTEXTUREFORMAT_16_16_16_16_EXPAND,
GPUTEXTUREFORMAT_16_FLOAT,
GPUTEXTUREFORMAT_16_16_FLOAT,
GPUTEXTUREFORMAT_16_16_16_16_FLOAT,
GPUTEXTUREFORMAT_32,
GPUTEXTUREFORMAT_32_32,
GPUTEXTUREFORMAT_32_32_32_32,
GPUTEXTUREFORMAT_32_FLOAT,
GPUTEXTUREFORMAT_32_32_FLOAT,
GPUTEXTUREFORMAT_32_32_32_32_FLOAT,
GPUTEXTUREFORMAT_32_AS_8,
GPUTEXTUREFORMAT_32_AS_8_8,
GPUTEXTUREFORMAT_16_MPEG,
GPUTEXTUREFORMAT_16_16_MPEG,
GPUTEXTUREFORMAT_8_INTERLACED,
GPUTEXTUREFORMAT_32_AS_8_INTERLACED,
GPUTEXTUREFORMAT_32_AS_8_8_INTERLACED,
GPUTEXTUREFORMAT_16_INTERLACED,
GPUTEXTUREFORMAT_16_MPEG_INTERLACED,
GPUTEXTUREFORMAT_16_16_MPEG_INTERLACED,
GPUTEXTUREFORMAT_DXN,
GPUTEXTUREFORMAT_8_8_8_8_AS_16_16_16_16,
GPUTEXTUREFORMAT_DXT1_AS_16_16_16_16,
GPUTEXTUREFORMAT_DXT2_3_AS_16_16_16_16,
GPUTEXTUREFORMAT_DXT4_5_AS_16_16_16_16,
GPUTEXTUREFORMAT_2_10_10_10_AS_16_16_16_16,
GPUTEXTUREFORMAT_10_11_11_AS_16_16_16_16,
GPUTEXTUREFORMAT_11_11_10_AS_16_16_16_16,
GPUTEXTUREFORMAT_32_32_32_FLOAT,
GPUTEXTUREFORMAT_DXT3A,
GPUTEXTUREFORMAT_DXT5A,
GPUTEXTUREFORMAT_CTX1,
GPUTEXTUREFORMAT_DXT3A_AS_1_1_1_1,
GPUTEXTUREFORMAT_8_8_8_8_GAMMA_EDRAM,
GPUTEXTUREFORMAT_2_10_10_10_FLOAT_EDRAM,
};
struct XPR_HEADER
{
unsigned long dwMagic;
@ -179,6 +251,8 @@ void PackedResource::Destroy()
m_bInitialized = FALSE;
}
/* end of Xbox 360 specific code */
static void xdk360_gfx_free(void * data)
{
if (g_d3d)
@ -189,14 +263,9 @@ static void xdk360_gfx_free(void * data)
if (!vid)
return;
D3DResource_Release((D3DResource *)vid->lpTexture);
D3DResource_Release((D3DResource *)vid->vertex_buf);
D3DResource_Release((D3DResource *)vid->v_decl);
D3DDevice_Release(vid->xdk360_render_device);
Direct3D_Release();
//breaks right now
//hlsl_deinit();
hlsl_deinit();
vid->d3d_render_device->Release();
vid->d3d_device->Release();
free(vid);
}
@ -204,8 +273,8 @@ static void xdk360_gfx_free(void * data)
static void set_viewport(bool force_full)
{
xdk360_video_t *vid = (xdk360_video_t*)g_d3d;
D3DDevice_Clear(vid->xdk360_render_device, 0, NULL, D3DCLEAR_TARGET,
0xff000000, 1.0f, 0, FALSE);
vid->d3d_render_device->Clear(0, NULL, D3DCLEAR_TARGET,
0xff000000, 1.0f, 0);
int width = vid->video_mode.fIsHiDef ? 1280 : 640;
int height = vid->video_mode.fIsHiDef ? 720 : 480;
@ -257,7 +326,7 @@ static void set_viewport(bool force_full)
vp.Y = m_viewport_y_temp;
vp.MinZ = m_zNear;
vp.MaxZ = m_zFar;
D3DDevice_SetViewport(vid->xdk360_render_device, &vp);
vid->d3d_render_device->SetViewport(&vp);
//if(gl->overscan_enable && !force_full)
//{
@ -289,6 +358,7 @@ static void xdk360_set_orientation(void * data, uint32_t orientation)
break;
}
/* TODO: Move to D3DXMATRIX here */
hlsl_set_proj_matrix(XMMatrixRotationZ(angle));
}
@ -301,10 +371,21 @@ static void xdk360_set_aspect_ratio(void * data, uint32_t aspectratio_index)
set_viewport(false);
}
static void xdk360_convert_texture_to_as16_srgb( D3DTexture *pTexture )
{
pTexture->Format.SignX = GPUSIGN_GAMMA;
pTexture->Format.SignY = GPUSIGN_GAMMA;
pTexture->Format.SignZ = GPUSIGN_GAMMA;
XGTEXTURE_DESC desc;
XGGetTextureDesc( pTexture, 0, &desc );
//convert to AS_16_16_16_16 format
pTexture->Format.DataFormat = g_MapLinearToSrgbGpuFormat[ (desc.Format & D3DFORMAT_TEXTUREFORMAT_MASK) >> D3DFORMAT_TEXTUREFORMAT_SHIFT ];
}
static void *xdk360_gfx_init(const video_info_t *video, const input_driver_t **input, void **input_data)
{
HRESULT ret;
if (g_d3d)
return g_d3d;
@ -312,8 +393,8 @@ static void *xdk360_gfx_init(const video_info_t *video, const input_driver_t **i
if (!vid)
return NULL;
vid->xdk360_device = Direct3DCreate9(D3D_SDK_VERSION);
if (!vid->xdk360_device)
vid->d3d_device = Direct3DCreate9(D3D_SDK_VERSION);
if (!vid->d3d_device)
{
free(vid);
return NULL;
@ -344,22 +425,26 @@ static void *xdk360_gfx_init(const video_info_t *video, const input_driver_t **i
vid->d3dpp.PresentationInterval = video->vsync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
// D3DCREATE_HARDWARE_VERTEXPROCESSING is ignored on 360
ret = Direct3D_CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, NULL, D3DCREATE_HARDWARE_VERTEXPROCESSING, &vid->d3dpp, &vid->xdk360_render_device);
vid->d3d_device->CreateDevice(0, D3DDEVTYPE_HAL, NULL, D3DCREATE_HARDWARE_VERTEXPROCESSING,
&vid->d3dpp, &vid->d3d_render_device);
hlsl_init(g_settings.video.cg_shader_path, vid->xdk360_render_device);
hlsl_init(g_settings.video.cg_shader_path, vid->d3d_render_device);
vid->lpTexture = (D3DTexture*) D3DDevice_CreateTexture(512, 512, 1, 1, 0, D3DFMT_LIN_X1R5G5B5,
0, D3DRTYPE_TEXTURE);
vid->d3d_render_device->CreateTexture(512, 512, 1, 0, D3DFMT_LIN_X1R5G5B5,
0, &vid->lpTexture, NULL);
xdk360_convert_texture_to_as16_srgb(vid->lpTexture);
D3DLOCKED_RECT d3dlr;
D3DTexture_LockRect(vid->lpTexture, 0, &d3dlr, NULL, D3DLOCK_NOSYSLOCK);
vid->lpTexture->LockRect(0, &d3dlr, NULL, D3DLOCK_NOSYSLOCK);
memset(d3dlr.pBits, 0, 512 * d3dlr.Pitch);
D3DTexture_UnlockRect(vid->lpTexture, 0);
vid->lpTexture->UnlockRect(0);
vid->last_width = 512;
vid->last_height = 512;
vid->vertex_buf = D3DDevice_CreateVertexBuffer(4 * sizeof(DrawVerticeFormats), 0, 0);
vid->d3d_render_device->CreateVertexBuffer(4 * sizeof(DrawVerticeFormats),
0, 0, 0, &vid->vertex_buf, NULL);
static const DrawVerticeFormats init_verts[] = {
{ -1.0f, -1.0f, 0.0f, 1.0f },
@ -368,9 +453,10 @@ static void *xdk360_gfx_init(const video_info_t *video, const input_driver_t **i
{ 1.0f, 1.0f, 1.0f, 0.0f },
};
void *verts_ptr = (BYTE*)D3DVertexBuffer_Lock(vid->vertex_buf, 0, 0, 0);
void *verts_ptr;
vid->vertex_buf->Lock(0, 0, &verts_ptr, 0);
memcpy(verts_ptr, init_verts, sizeof(init_verts));
D3DVertexBuffer_Unlock(vid->vertex_buf);
vid->vertex_buf->Unlock();
static const D3DVERTEXELEMENT9 VertexElements[] =
{
@ -379,20 +465,20 @@ static void *xdk360_gfx_init(const video_info_t *video, const input_driver_t **i
D3DDECL_END()
};
vid->v_decl = D3DDevice_CreateVertexDeclaration(VertexElements);
vid->d3d_render_device->CreateVertexDeclaration(VertexElements, &vid->v_decl);
D3DDevice_Clear(vid->xdk360_render_device, 0, NULL, D3DCLEAR_TARGET,
0xff000000, 1.0f, 0, FALSE);
vid->d3d_render_device->Clear(0, NULL, D3DCLEAR_TARGET,
0xff000000, 1.0f, 0);
D3DDevice_SetRenderState_CullMode(vid->xdk360_render_device, D3DCULL_NONE);
D3DDevice_SetRenderState_ZEnable(vid->xdk360_render_device, FALSE);
vid->d3d_render_device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
vid->d3d_render_device->SetRenderState(D3DRS_ZENABLE, FALSE);
D3DVIEWPORT9 vp = {0};
vp.Width = vid->video_mode.fIsHiDef ? 1280 : 640;
vp.Height = vid->video_mode.fIsHiDef ? 720 : 480;
vp.MinZ = 0.0f;
vp.MaxZ = 1.0f;
D3DDevice_SetViewport(vid->xdk360_render_device, &vp);
vid->d3d_render_device->SetViewport(&vp);
xdk360_set_orientation(NULL, g_console.screen_orientation);
@ -404,17 +490,17 @@ static bool xdk360_gfx_frame(void *data, const void *frame,
{
xdk360_video_t *vid = (xdk360_video_t*)data;
D3DDevice_Clear(vid->xdk360_render_device, 0, NULL, D3DCLEAR_TARGET,
0xff000000, 1.0f, 0, FALSE);
vid->d3d_render_device->Clear(0, NULL, D3DCLEAR_TARGET,
0xff000000, 1.0f, 0);
g_frame_count++;
if (vid->last_width != width || vid->last_height != height)
{
D3DLOCKED_RECT d3dlr;
D3DTexture_LockRect(vid->lpTexture, 0, &d3dlr, NULL, D3DLOCK_NOSYSLOCK);
vid->lpTexture->LockRect(0, &d3dlr, NULL, D3DLOCK_NOSYSLOCK);
memset(d3dlr.pBits, 0, 512 * d3dlr.Pitch);
D3DTexture_UnlockRect(vid->lpTexture, 0);
vid->lpTexture->UnlockRect(0);
float tex_w = width / 512.0f;
float tex_h = height / 512.0f;
@ -426,9 +512,10 @@ static bool xdk360_gfx_frame(void *data, const void *frame,
{ 1.0f, 1.0f, tex_w, 0.0f },
};
void *verts_ptr = (BYTE*)D3DVertexBuffer_Lock(vid->vertex_buf, 0, 0, 0);
void *verts_ptr;
vid->vertex_buf->Lock(0, 0, &verts_ptr, 0);
memcpy(verts_ptr, verts, sizeof(verts));
D3DVertexBuffer_Unlock(vid->vertex_buf);
vid->vertex_buf->Unlock();
vid->last_width = width;
vid->last_height = height;
@ -438,41 +525,44 @@ static bool xdk360_gfx_frame(void *data, const void *frame,
hlsl_set_params(width, height, 512, 512, vid->d3dpp.BackBufferWidth,
vid->d3dpp.BackBufferHeight, g_frame_count);
vid->d3d_render_device->SetTexture(0, NULL);
D3DLOCKED_RECT d3dlr;
D3DTexture_LockRect(vid->lpTexture, 0, &d3dlr, NULL, D3DLOCK_NOSYSLOCK);
vid->lpTexture->LockRect(0, &d3dlr, NULL, D3DLOCK_NOSYSLOCK);
for (unsigned y = 0; y < height; y++)
{
const uint8_t *in = (const uint8_t*)frame + y * pitch;
uint8_t *out = (uint8_t*)d3dlr.pBits + y * d3dlr.Pitch;
memcpy(out, in, width * sizeof(uint16_t));
}
D3DTexture_UnlockRect(vid->lpTexture, 0);
vid->lpTexture->UnlockRect(0);
D3DDevice_SetTexture_Inline(vid->xdk360_render_device, 0, vid->lpTexture);
D3DDevice_SetSamplerState(vid->xdk360_render_device, 0, D3DSAMP_MINFILTER, g_settings.video.smooth ? D3DTEXF_LINEAR : D3DTEXF_POINT);
D3DDevice_SetSamplerState(vid->xdk360_render_device, 0, D3DSAMP_MAGFILTER, g_settings.video.smooth ? D3DTEXF_LINEAR : D3DTEXF_POINT);
D3DDevice_SetSamplerState(vid->xdk360_render_device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER);
D3DDevice_SetSamplerState(vid->xdk360_render_device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER);
vid->d3d_render_device->SetTexture(0, vid->lpTexture);
vid->d3d_render_device->SetSamplerState(0, D3DSAMP_MINFILTER, g_settings.video.smooth ? D3DTEXF_LINEAR : D3DTEXF_POINT);
vid->d3d_render_device->SetSamplerState(0, D3DSAMP_MAGFILTER, g_settings.video.smooth ? D3DTEXF_LINEAR : D3DTEXF_POINT);
vid->d3d_render_device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER);
vid->d3d_render_device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER);
D3DDevice_SetVertexDeclaration(vid->xdk360_render_device, vid->v_decl);
D3DDevice_SetStreamSource_Inline(vid->xdk360_render_device, 0, vid->vertex_buf, 0,
sizeof(DrawVerticeFormats));
vid->d3d_render_device->SetVertexDeclaration(vid->v_decl);
vid->d3d_render_device->SetStreamSource(0, vid->vertex_buf, 0, sizeof(DrawVerticeFormats));
D3DDevice_DrawVertices(vid->xdk360_render_device, D3DPT_TRIANGLESTRIP, 0, D3DVERTEXCOUNT(D3DPT_TRIANGLESTRIP, 2));
vid->d3d_render_device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
/* XBox 360 specific font code */
if (msg)
{
if(IS_TIMER_EXPIRED() || g_first_msg)
{
xdk360_console_format(msg);
g_first_msg = 0;
SET_TIMER_EXPIRATION(30);
g_first_msg = 0;
SET_TIMER_EXPIRATION(30);
}
xdk360_console_draw();
}
if(!vid->block_swap)
D3DDevice_Present(vid->xdk360_render_device);
vid->d3d_render_device->Present(NULL, NULL, NULL, NULL);
return true;
}
@ -493,17 +583,18 @@ static void xdk360_swap (void * data)
{
(void)data;
xdk360_video_t *vid = (xdk360_video_t*)g_d3d;
D3DDevice_Present(vid->xdk360_render_device);
vid->d3d_render_device->Present(NULL, NULL, NULL, NULL);
}
static void xdk360_gfx_set_nonblock_state(void *data, bool state)
{
xdk360_video_t *vid = (xdk360_video_t*)data;
SSNES_LOG("D3D Vsync => %s\n", state ? "off" : "on");
/* XBox 360 specific code */
if(state)
D3DDevice_SetRenderState_PresentInterval(vid->xdk360_render_device, D3DPRESENT_INTERVAL_IMMEDIATE);
vid->d3d_render_device->SetRenderState(D3DRS_PRESENTINTERVAL, D3DPRESENT_INTERVAL_IMMEDIATE);
else
D3DDevice_SetRenderState_PresentInterval(vid->xdk360_render_device, D3DPRESENT_INTERVAL_ONE);
vid->d3d_render_device->SetRenderState(D3DRS_PRESENTINTERVAL, D3DPRESENT_INTERVAL_ONE);
}
static bool xdk360_gfx_alive(void *data)
@ -541,6 +632,7 @@ void xdk360_video_init(void)
g_first_msg = true;
/* XBox 360 specific font code */
HRESULT hr = xdk360_console_init("game:\\media\\Arial_12.xpr",
0xff000000, 0xffffffff );

View File

@ -46,8 +46,8 @@ typedef struct xdk360_video
bool vsync;
unsigned last_width;
unsigned last_height;
IDirect3D9* xdk360_device;
IDirect3DDevice9* xdk360_render_device;
IDirect3D9* d3d_device;
IDirect3DDevice9* d3d_render_device;
IDirect3DVertexBuffer9* vertex_buf;
IDirect3DTexture9* lpTexture;
IDirect3DVertexDeclaration9* v_decl;

View File

@ -190,7 +190,7 @@ ifeq ($(DEBUG), 1)
OPTIMIZE_FLAG = -O0
endif
CFLAGS += -Wall $(OPTIMIZE_FLAG) -g -I. -pedantic
CFLAGS += -Wall -Wno-unused-result $(OPTIMIZE_FLAG) -g -I. -pedantic
ifeq ($(CXX_BUILD), 1)
CFLAGS += -std=c++0x -xc++ -D__STDC_CONSTANT_MACROS
else

View File

@ -153,7 +153,7 @@ ifneq ($(V), 1)
Q := @
endif
CFLAGS += -Wall -O3 -I.
CFLAGS += -Wall -Wno-unused-result -O3 -I.
ifeq ($(CXX_BUILD), 1)
CFLAGS += -std=c++0x -xc++ -D__STDC_CONSTANT_MACROS
else

View File

@ -1,11 +1,13 @@
# SSNES
SSNES is a simple frontend for the libsnes library.
SSNES is a simple frontend for the libretro API. An API that attempts to generalize
a retro gaming system, such as SNES, NES, GameBoy, Arcade machines, etc.
# libsnes
# libretro
libsnes is the emulator core of [bSNES](http://www.byuu.org), the most accurate SNES emulator to date, in library form. The libsnes API has been implemented by SNES9x as well, allowing multiple different cores to be used for an emulator that supports libsnes.
This enables the possibility of custom front-ends for the emulator.
libretro is an API that exposes the core of a retro gaming system.
A frontend for libretro handles video output, audio output and input.
A libretro core written in portable C or C++ can run seamlessly on many platforms.
# Binaries
@ -24,11 +26,10 @@ SSNES has been ported to the following platforms :
- Xbox 360 (Libxenon/XeXDK)
- Wii (Libogc)
# Dependencies
# Dependencies (PC)
SSNES requires these libraries to build:
- [libsnes](http://byuu.org/bsnes/)
- SDL
SSNES can utilize these libraries if enabled:
@ -50,26 +51,25 @@ SSNES needs at least one of these audio driver libraries:
- XAudio2 (Win32)
- PulseAudio
# Building libsnes
To run properly, SSNES requires a libretro implementation present, however, as it's typically loaded
dynamically, it's not required at build time.
- Download bSNES source (link over).
- Add -fPIC to flags in Makefile.
- <tt>$ make library profile=performance</tt> (accuracy, compatibility are the other profiles. compatibility is a great choice for decent PCs. :D)
- <tt># make prefix=/usr library-install</tt>
- <tt># cp snes/libsnes/libsnes.hpp /usr/include/</tt>
- ?!?!
- Profit!
# Dependencies (Console ports)
Console ports have their own dependencies, but generally do not require
anything other than what the respective SDKs provide.
# Configuring
The default configuration is defined in config.def.h.
These can later be tweaked by using the ssnes config file.
These can later be tweaked by using a config file.
A sample configuration file is installed to /etc/ssnes.cfg.
This is the system-wide config file.
Each user should create a config file in $XDG\_CONFIG\_HOME/ssnes/ssnes.cfg.
The users only need to configure a certain option if the desired value deviates from the value defined in config.def.h.
To configure joypads, start up <tt>jstest /dev/input/js0</tt> to determine which joypad buttons (and axis) to use. It is also possible to use the <tt>ssnes-joyconfig</tt> tool as well for simple configuration.
To configure joypads, start up <tt>jstest /dev/input/js0</tt> to determine which joypad buttons (and axis) to use.
It is also possible to use the <tt>ssnes-joyconfig</tt> tool as well for simple configuration.
# Compiling and installing
@ -78,8 +78,8 @@ As most packages, SSNES is built using the standard <tt>./configure && make && m
Do note that the build system is not autotools based, but resembles it.
Notable options for ./configure:
--with-libsnes=: Normally libsnes is located with -lsnes, however, this can be overridden.
--enable-dynamic: Do not link to libsnes at compile time, but load libsnes dynamically at runtime. libsnes\_path in config file defines which library to load. Useful for development.
--with-libretro=: Normally libretro is located with -lsnes, however, this can be overridden.
--enable-dynamic: Do not link to libretro at compile time, but load libretro dynamically at runtime. libretro\_path in config file defines which library to load. Useful for development.
Do note that these two options are mutually exclusive.
@ -87,12 +87,12 @@ Do note that these two options are mutually exclusive.
It is possible with MinGW to compile for Windows in either msys or Linux/Unix based systems. Do note that Windows build uses a static Makefile since configuration scripts create more harm than good on this platform. Libraries, headers, etc, needed to compile and run SSNES can be fetched with a Makefile target.
In Linux/Unix:<br/>
<tt>make -f Makefile.win32 libs</tt></br>
<tt>make -f Makefile.win32 CC=i486-mingw32-gcc CXX=i486-mingw32-g++</tt></br>
<tt>make -f Makefile.win libs</tt></br>
<tt>make -f Makefile.win CC=i486-mingw32-gcc CXX=i486-mingw32-g++</tt></br>
In MSYS:
<tt>mingw32-make -f Makefile.win32 libs</tt>. # You will need to have wget in your patch for this command! MSYS should provide this.</br>
<tt>mingw32-make -f Makefile.win32</tt>
<tt>mingw32-make -f Makefile.win libs</tt>. # You will need to have wget in your patch for this command! MSYS should provide this.</br>
<tt>mingw32-make -f Makefile.win</tt>
<b>Win32 (MSVC)</b><br />
In addition to Mingw, it is also possible to compile a Win32 version of SSNES with Microsoft Visual Studio 2010.
@ -109,7 +109,7 @@ The solution file can be found at the following location:
A PKG file will be built which you will be able to install on a jailbroken PS3.
NOTE: A pre-existing libsnes library needs to be present in the root directory in order to link SSNES PS3. This file needs to be called 'libsnes.a'.
NOTE: A pre-existing libretro library needs to be present in the root directory in order to link SSNES PS3. This file needs to be called 'libretro.a'.
<b> Xbox 360 (XeXDK)</b><br />
@ -119,7 +119,7 @@ The solution file can be found at the following location:
<tt>msvc-360/SSNES-360/SSNES-360.sln</tt>
NOTE: A pre-existing libsnes library needs to be present in the root directory in order to link SSNES 360.
NOTE: A pre-existing libretro library needs to be present in the root directory in order to link SSNES 360.
<b> Xbox 360 (Libxenon)</b><br />
@ -127,7 +127,7 @@ You will need to have the libxenon libraries and a working Devkit Xenon toolchai
<tt>make -f Makefile.xenon</tt>
NOTE: A pre-existing libsnes library needs to be present in the root directory in order to link SSNES 360 Libxenon. This file needs to be called 'libsnes.a'.
NOTE: A pre-existing libretro library needs to be present in the root directory in order to link SSNES 360 Libxenon. This file needs to be called 'libretro.a'.
<b> Wii</b><br >
@ -135,7 +135,7 @@ You will need to have the libogc libraries and a working Devkit PPC toolchain in
<tt>make -f Makefile.wii</tt>
NOTE: A pre-existing libsnes library needs to be present in the root directory in order to link SSNES Wii. This file needs to be called 'libsnes.a'.
NOTE: A pre-existing libretro library needs to be present in the root directory in order to link SSNES Wii. This file needs to be called 'libretro.a'.
# Filters, bSNES XML shaders and Cg shader support

View File

@ -36,18 +36,18 @@ struct hlsl_program
D3DXHANDLE mvp;
LPD3DXCONSTANTTABLE v_ctable;
LPD3DXCONSTANTTABLE f_ctable;
XMMATRIX mvp_val;
XMMATRIX mvp_val; /* TODO: Move to D3DXMATRIX here */
};
static IDirect3DDevice9 * d3d_device_ptr;
static IDirect3DDevice9 *d3d_device_ptr;
static struct hlsl_program prg[SSNES_HLSL_MAX_SHADERS] = {0};
static bool hlsl_active = false;
static unsigned active_index = 0;
static const char* stock_hlsl_program =
static const char *stock_hlsl_program =
"void main_vertex "
"( "
" float2 position : POSITION, "
" float2 position : POSITION, "
" float2 texCoord : TEXCOORD0, "
" uniform float4x4 modelViewProj : register(c0), "
" out float4 oPosition : POSITION, "
@ -57,21 +57,21 @@ static const char* stock_hlsl_program =
" oPosition = mul(modelViewProj, float4(position, 0.0, 1.0)); "
" otexCoord = texCoord; "
"} "
" "
" "
"struct output "
"{ "
"{ "
" float4 color: COLOR; "
"}; "
" "
" "
"struct input "
"{ "
" float2 video_size; "
" float2 texture_size; "
" float2 output_size; "
" float2 output_size; "
"}; "
" "
" "
"output main_fragment(float2 texCoord : TEXCOORD0, "
"uniform sampler2D decal : register(s0), uniform input IN) "
"uniform sampler2D decal : register(s0), uniform input IN) "
"{ "
" output OUT; "
" OUT.color = tex2D(decal, tex); "
@ -85,9 +85,9 @@ void hlsl_set_proj_matrix(XMMATRIX rotation_value)
}
#define set_param_2f(param, xy, constanttable) \
if (param) constanttable->SetFloatArray(d3d_device_ptr, param, xy, 2);
if (param) constanttable->SetFloatArray(d3d_device_ptr, param, xy, 2)
#define set_param_1f(param, x, constanttable) \
if (param) constanttable->SetFloat(d3d_device_ptr, param, x);
if (param) constanttable->SetFloat(d3d_device_ptr, param, x)
void hlsl_set_params(unsigned width, unsigned height,
unsigned tex_width, unsigned tex_height,
@ -97,20 +97,27 @@ void hlsl_set_params(unsigned width, unsigned height,
if (!hlsl_active)
return;
const float ori_size[2] = {(float)width, (float)height };
const float out_size[2] = {(float)out_width, (float)out_height};
const float tex_size[2] = {(float)tex_width, (float)tex_height};
const float ori_size[2] = { (float)width, (float)height };
const float tex_size[2] = { (float)tex_width, (float)tex_height };
const float out_size[2] = { (float)out_width, (float)out_height };
float frame_cnt = frame_count;
prg[active_index].f_ctable->SetDefaults(d3d_device_ptr);
prg[active_index].v_ctable->SetDefaults(d3d_device_ptr);
set_param_2f(prg[active_index].vid_size_f, ori_size, prg[active_index].f_ctable);
set_param_2f(prg[active_index].tex_size_f, tex_size, prg[active_index].f_ctable);
set_param_2f(prg[active_index].out_size_f, out_size, prg[active_index].f_ctable);
set_param_1f(prg[active_index].frame_cnt_f, (float)frame_count, prg[active_index].f_ctable);
set_param_1f(prg[active_index].frame_cnt_f, frame_cnt, prg[active_index].f_ctable);
set_param_1f(prg[active_index].frame_dir_f, g_extern.frame_is_reverse ? -1.0 : 1.0,prg[active_index].f_ctable);
set_param_2f(prg[active_index].vid_size_v, ori_size, prg[active_index].v_ctable);
set_param_2f(prg[active_index].tex_size_v, tex_size, prg[active_index].v_ctable);
set_param_2f(prg[active_index].out_size_v, out_size, prg[active_index].v_ctable);
set_param_1f(prg[active_index].frame_cnt_v, (float)frame_count, prg[active_index].v_ctable);
set_param_1f(prg[active_index].frame_cnt_v, frame_cnt, prg[active_index].v_ctable);
set_param_1f(prg[active_index].frame_dir_v, g_extern.frame_is_reverse ? -1.0 : 1.0,prg[active_index].v_ctable);
/* TODO: Move to D3DXMATRIX here */
prg[active_index].v_ctable->SetMatrix(d3d_device_ptr, prg[active_index].mvp, (D3DXMATRIX*)&prg[active_index].mvp_val);
}
@ -126,21 +133,25 @@ static bool load_program(unsigned index, const char *prog, bool path_is_file)
ret_fp = false;
ret_vp = false;
if(prg[index].f_ctable)
D3DResource_Release((D3DResource *)prg[index].f_ctable);
if(prg[index].v_ctable)
D3DResource_Release((D3DResource *)prg[0].v_ctable);
if (prg[index].f_ctable)
prg[index].f_ctable->Release();
if (prg[index].v_ctable)
prg[index].v_ctable->Release();
if (path_is_file)
{
ret_fp = D3DXCompileShaderFromFile(prog, NULL, NULL, "main_fragment", "ps_2_0", 0, &code_f, &listing_f, &prg[index].f_ctable);
ret_vp = D3DXCompileShaderFromFile(prog, NULL, NULL, "main_vertex", "vs_2_0", 0, &code_v, &listing_v, &prg[index].v_ctable);
ret_fp = D3DXCompileShaderFromFile(prog, NULL, NULL,
"main_fragment", "ps_3_0", 0, &code_f, &listing_f, &prg[index].f_ctable);
ret_vp = D3DXCompileShaderFromFile(prog, NULL, NULL,
"main_vertex", "vs_3_0", 0, &code_v, &listing_v, &prg[index].v_ctable);
}
else
{
/* TODO - crashes currently - to do with 'end of line' of stock shader */
ret_fp = D3DXCompileShader(prog, (UINT)strlen(prog), NULL, NULL, "main_fragment", "ps_2_0", 0, &code_f, &listing_f, &prg[index].f_ctable );
ret_vp = D3DXCompileShader(prog, (UINT)strlen(prog), NULL, NULL, "main_vertex", "vs_2_0", 0, &code_v, &listing_v, &prg[index].v_ctable );
ret_fp = D3DXCompileShader(prog, (UINT)strlen(prog), NULL, NULL,
"main_fragment", "ps_3_0", 0, &code_f, &listing_f, &prg[index].f_ctable );
ret_vp = D3DXCompileShader(prog, (UINT)strlen(prog), NULL, NULL,
"main_vertex", "vs_3_0", 0, &code_v, &listing_v, &prg[index].v_ctable );
}
if (FAILED(ret_fp) || FAILED(ret_vp) || listing_v || listing_f)
@ -155,20 +166,20 @@ static bool load_program(unsigned index, const char *prog, bool path_is_file)
goto end;
}
if(prg[index].fprg)
D3DResource_Release((D3DResource *)prg[0].fprg);
if(prg[index].vprg)
D3DResource_Release((D3DResource *)prg[0].vprg);
if (prg[index].fprg)
prg[index].fprg->Release();
if (prg[index].vprg)
prg[index].vprg->Release();
prg[index].fprg = D3DDevice_CreatePixelShader((const DWORD*)code_f->GetBufferPointer());
prg[index].vprg = D3DDevice_CreateVertexShader((const DWORD*)code_v->GetBufferPointer());
d3d_device_ptr->CreatePixelShader((const DWORD*)code_f->GetBufferPointer(), &prg[index].fprg);
d3d_device_ptr->CreateVertexShader((const DWORD*)code_v->GetBufferPointer(), &prg[index].vprg);
code_f->Release();
code_v->Release();
end:
if(listing_f)
if (listing_f)
listing_f->Release();
if(listing_v)
if (listing_v)
listing_v->Release();
return ret;
}
@ -201,6 +212,13 @@ static bool load_plain(const char *path)
static void hlsl_deinit_progs(void)
{
for(int i = 0; i < SSNES_HLSL_MAX_SHADERS; i++)
{
if (prg[i].fprg)
prg[i].fprg->Release();
if (prg[i].vprg)
prg[i].vprg->Release();
}
}
static void hlsl_deinit_state(void)
@ -234,7 +252,7 @@ static void set_program_attributes(unsigned i)
bool hlsl_init(const char *path, IDirect3DDevice9 * device_ptr)
{
if(!device_ptr)
if (!device_ptr)
return false;
d3d_device_ptr = device_ptr;
@ -259,12 +277,12 @@ bool hlsl_init(const char *path, IDirect3DDevice9 * device_ptr)
void hlsl_use(unsigned index)
{
if (hlsl_active && prg[index].vprg && prg[index].fprg)
{
active_index = index;
D3DDevice_SetVertexShader(d3d_device_ptr, prg[index].vprg);
D3DDevice_SetPixelShader(d3d_device_ptr, prg[index].fprg);
}
if (!hlsl_active)
return;
active_index = index;
d3d_device_ptr->SetVertexShader(prg[index].vprg);
d3d_device_ptr->SetPixelShader(prg[index].fprg);
}
// Full deinit.
@ -275,3 +293,4 @@ void hlsl_deinit(void)
hlsl_deinit_state();
}

View File

@ -21,7 +21,7 @@
#include "../boolean.h"
#include <stdint.h>
bool hlsl_init(const char *path, IDirect3DDevice9 * device_ptr);
bool hlsl_init(const char *path, IDirect3DDevice9 *device_ptr);
void hlsl_deinit(void);

View File

@ -105,20 +105,31 @@ extern "C" {
//
#define RETRO_ENVIRONMENT_SET_MESSAGE 6 // const struct retro_message * --
// Sets a message to be displayed in implementation-specific manner for a certain amount of 'frames'.
// Should not be used for trivial messages, which should simply be logged to stderr.
struct retro_message
{
const char *msg;
unsigned frames;
const char *msg; // Message to be displayed.
unsigned frames; // Duration in frames of message.
};
struct retro_system_info
{
const char *library_name;
const char *library_version;
const char *valid_extensions;
bool need_fullpath;
bool block_extract;
const char *library_name; // Descriptive name of library. Should not contain any version numbers, etc.
const char *library_version; // Descriptive version of core.
const char *valid_extensions; // A string listing probably rom extensions the core will be able to load, separated with pipe.
// I.e. "bin|rom|iso".
// Typically used for a GUI to filter out extensions.
bool need_fullpath; // If true, retro_load_game() is guaranteed to provide a valid pathname in retro_game_info::path.
// ::data and ::size are both invalid.
// If false, ::data and ::size are guaranteed to be valid, but ::path might not be valid.
// This is typically set to true for libretro implementations that must load from file.
// Implementations should strive for setting this to false, as it allows the frontend to perform patching, etc.
bool block_extract; // If true, the frontend is not allowed to extract any archives before loading the real ROM.
// Necessary for certain libretro implementations that load games from zipped archives.
};
struct retro_game_geometry
@ -158,32 +169,39 @@ struct retro_game_info
{
const char *path; // Path to game, UTF-8 encoded. Usually used as a reference.
// May be NULL if rom was loaded from stdin or similar.
// SET_NEED_FULLPATH path guaranteed that this path is valid.
const void *data; // Memory buffer of loaded game.
// If the game is too big to load in one go.
// SET_NEED_FULLPATH should be used.
// In this case, data and size will be 0,
// and game can be loaded from path.
// retro_system_info::need_fullpath guaranteed that this path is valid.
const void *data; // Memory buffer of loaded game. Will be NULL if need_fullpath was set.
size_t size; // Size of memory buffer.
const char *meta; // String of implementation specific meta-data.
};
// Callbacks
//
// Environment callback. Gives implementations a way of performing uncommon tasks. Extensible.
typedef bool (*retro_environment_t)(unsigned cmd, void *data);
// Render a frame. Pixel format is 15-bit XRGB1555 native endian.
// Width and height specify dimensions of buffer.
// Pitch specifices length in bytes between two lines in buffer.
typedef void (*retro_video_refresh_t)(const void *data, unsigned width, unsigned height, size_t pitch);
// Renders a single audio frame. Should only be used if implementation generates a single sample at a time.
// Format is signed 16-bit native endian.
typedef void (*retro_audio_sample_t)(int16_t left, int16_t right);
// Renders multiple audio frames in one go. One frame is defined as a sample of left and right channels, interleaved.
// I.e. int16_t buf[4] = { l, r, l, r }; would be 2 frames.
// Only one of the audio callbacks must ever be used.
typedef size_t (*retro_audio_sample_batch_t)(const int16_t *data, size_t frames);
// Polls input.
typedef void (*retro_input_poll_t)(void);
// Queries for input for player 'port'. device will be masked with RETRO_DEVICE_MASK.
// Specialization of devices such as RETRO_DEVICE_JOYPAD_MULTITAP that have been set with retro_set_controller_port_device()
// will still use the higher level RETRO_DEVICE_JOYPAD to request input.
typedef int16_t (*retro_input_state_t)(unsigned port, unsigned device, unsigned index, unsigned id);
void retro_init(void);
void retro_deinit(void);
unsigned retro_api_version(void);
void retro_get_system_info(struct retro_system_info *info);
void retro_get_system_av_info(struct retro_system_av_info *info);
// Sets callbacks. retro_set_environment() is guaranteed to be called before retro_init().
// The rest of the set_* functions are guaranteed to have been called before the first call to retro_run() is made.
void retro_set_environment(retro_environment_t);
void retro_set_video_refresh(retro_video_refresh_t);
void retro_set_audio_sample(retro_audio_sample_t);
@ -191,29 +209,63 @@ void retro_set_audio_sample_batch(retro_audio_sample_batch_t);
void retro_set_input_poll(retro_input_poll_t);
void retro_set_input_state(retro_input_state_t);
// Library global initialization/deinitialization.
void retro_init(void);
void retro_deinit(void);
// Must return RETRO_API_VERSION. Used to validate ABI compatibility when the API is revised.
unsigned retro_api_version(void);
// Gets statically known system info. Pointers provided in *info must be statically allocated.
// Can be called at any time, even before retro_init().
void retro_get_system_info(struct retro_system_info *info);
// Gets information about system audio/video timings and geometry.
// Can be called only after retro_load_game() has successfully completed.
void retro_get_system_av_info(struct retro_system_av_info *info);
// Sets device to be used for player 'port'.
void retro_set_controller_port_device(unsigned port, unsigned device);
// Resets the current game.
void retro_reset(void);
// Runs the game for one video frame.
// During retro_run(), input_poll callback must be called at least once.
//
// If a frame is not rendered for reasons where a game "dropped" a frame,
// this still counts as a frame, and retro_run() should explicitly dupe a frame if GET_CAN_DUPE returns true.
// In this case, the video callback can take a NULL argument for data.
void retro_run(void);
// Returns the amount of data the implementation requires to serialize internal state (save states).
// Beetween calls to retro_load_game() and retro_unload_game(), the returned size is never allowed to be larger than a previous returned value, to
// ensure that the frontend can allocate a save state buffer once.
size_t retro_serialize_size(void);
// Serializes internal state. If failed, or size is lower than retro_serialize_size(), it should return false, true otherwise.
bool retro_serialize(void *data, size_t size);
bool retro_unserialize(const void *data, size_t size);
void retro_cheat_reset(void);
void retro_cheat_set(unsigned index, bool enabled, const char *code);
// Loads a game.
bool retro_load_game(const struct retro_game_info *game);
// Loads a "special" kind of game. Should not be used except in extreme cases.
bool retro_load_game_special(
unsigned game_type,
const struct retro_game_info *info, size_t num_info
);
// Unloads a currently loaded game.
void retro_unload_game(void);
// Gets region of game.
unsigned retro_get_region(void);
// Gets region of memory.
void *retro_get_memory_data(unsigned id);
size_t retro_get_memory_size(unsigned id);

View File

@ -563,6 +563,11 @@
<Command Condition="'$(Configuration)|$(Platform)'=='Profile_FastCap|Xbox 360'">copy %(FullPath) $(OutDir)media\shaders\stock.cg</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release_LTCG|Xbox 360'">copy %(FullPath) $(OutDir)media\shaders\stock.cg</Command>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Xbox 360'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CodeAnalysis|Xbox 360'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Xbox 360'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Profile|Xbox 360'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Profile_FastCap|Xbox 360'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_LTCG|Xbox 360'">true</ExcludedFromBuild>
</CustomBuild>
</ItemGroup>
<ItemGroup>