diff --git a/360/frontend-xdk/main.c b/360/frontend-xdk/main.c index 4b4922f3fe..5cd65a1c77 100644 --- a/360/frontend-xdk/main.c +++ b/360/frontend-xdk/main.c @@ -27,7 +27,14 @@ #include #include "../../input/rarch_xinput2.h" -#include "../xdk_d3d.h" + +#ifdef _XBOX +#if defined(_XBOX1) +#include "../../xbox1/xdk_d3d8.h" +#elif defined(_XBOX360) +#include "../xdk_d3d9.h" +#endif +#endif #include "../../console/retroarch_console.h" #include "../../conf/config_file.h" diff --git a/360/frontend-xdk/menu.cpp b/360/frontend-xdk/menu.cpp index 81e766a560..d6a9efaa8a 100644 --- a/360/frontend-xdk/menu.cpp +++ b/360/frontend-xdk/menu.cpp @@ -20,7 +20,7 @@ #include #include "../../console/fileio/file_browser.h" #include "../../console/retroarch_console.h" -#include "../xdk_d3d.h" +#include "../xdk_d3d9.h" #include "menu.h" #include "../../message.h" diff --git a/360/xdk_d3d.cpp b/360/xdk_d3d9.cpp similarity index 92% rename from 360/xdk_d3d.cpp rename to 360/xdk_d3d9.cpp index 8fe2c1266a..7942ee44c4 100644 --- a/360/xdk_d3d.cpp +++ b/360/xdk_d3d9.cpp @@ -19,7 +19,7 @@ #endif #include "../driver.h" -#include "xdk_d3d.h" +#include "xdk_d3d9.h" #ifdef HAVE_HLSL #include "../gfx/shader_hlsl.h" @@ -34,9 +34,7 @@ #include "config.h" #endif -#ifdef _XBOX360 #include "xdk360_video_resources.h" -#endif static void check_window(xdk_d3d_video_t *d3d) { @@ -80,14 +78,8 @@ static void xdk_d3d_set_viewport(bool force_full) d3d->d3d_render_device->Clear(0, NULL, D3DCLEAR_TARGET, 0xff000000, 1.0f, 0); -#ifdef _XBOX360 int width = d3d->video_mode.fIsHiDef ? 1280 : 640; int height = d3d->video_mode.fIsHiDef ? 720 : 480; -#else - // FIXME: Hardcoded for Xbox 1 for now - int width = 640; - int height = 480; -#endif int m_viewport_x_temp, m_viewport_y_temp, m_viewport_width_temp, m_viewport_height_temp; float m_zNear, m_zFar; @@ -198,30 +190,24 @@ static void xdk_d3d_init_fbo(xdk_d3d_video_t *d3d) d3d->d3d_render_device->CreateTexture(512 * g_settings.video.fbo_scale_x, 512 * g_settings.video.fbo_scale_y, 1, 0, g_console.gamma_correction_enable ? ( D3DFORMAT )MAKESRGBFMT( D3DFMT_A8R8G8B8 ) : D3DFMT_A8R8G8B8, 0, &d3d->lpTexture_ot -#ifdef _XBOX360 , NULL -#endif ); d3d->d3d_render_device->CreateRenderTarget(512 * g_settings.video.fbo_scale_x, 512 * g_settings.video.fbo_scale_y, g_console.gamma_correction_enable ? ( D3DFORMAT )MAKESRGBFMT( D3DFMT_A8R8G8B8 ) : D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, 0, &d3d->lpSurface, NULL); -#ifdef _XBOX360 d3d->lpTexture_ot_as16srgb = *d3d->lpTexture_ot; xdk360_convert_texture_to_as16_srgb(d3d->lpTexture); xdk360_convert_texture_to_as16_srgb(&d3d->lpTexture_ot_as16srgb); -#endif d3d->fbo_enabled = 1; } #endif static void *xdk_d3d_init(const video_info_t *video, const input_driver_t **input, void **input_data) { -#ifndef _XBOX1 if (driver.video_data) return driver.video_data; -#endif xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)calloc(1, sizeof(xdk_d3d_video_t)); if (!d3d) @@ -238,7 +224,6 @@ static void *xdk_d3d_init(const video_info_t *video, const input_driver_t **inpu // no letterboxing in 4:3 mode (if widescreen is // unsupported -#ifdef _XBOX360 // Get video settings memset(&d3d->video_mode, 0, sizeof(d3d->video_mode)); XGetVideoMode(&d3d->video_mode); @@ -263,16 +248,6 @@ static void *xdk_d3d_init(const video_info_t *video, const input_driver_t **inpu } d3d->d3dpp.MultiSampleQuality = 0; d3d->d3dpp.PresentationInterval = video->vsync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE; -#else - /* Xbox 1 */ - d3d->d3dpp.BackBufferFormat = g_console.color_format ? D3DFMT_A8R8G8B8 : D3DFMT_LIN_A1R5G5B5; - - //FIXME: Hardcoded right now - d3d->d3dpp.BackBufferWidth = 640; - d3d->d3dpp.BackBufferHeight = 480; - - d3d->d3dpp.FullScreen_PresentationInterval = video->vsync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE; -#endif d3d->d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; d3d->d3dpp.BackBufferCount = 2; @@ -288,9 +263,7 @@ static void *xdk_d3d_init(const video_info_t *video, const input_driver_t **inpu d3d->d3d_render_device->CreateTexture(512, 512, 1, 0, D3DFMT_LIN_X1R5G5B5, 0, &d3d->lpTexture -#ifdef _XBOX360 , NULL -#endif ); #ifdef HAVE_FBO @@ -305,13 +278,8 @@ static void *xdk_d3d_init(const video_info_t *video, const input_driver_t **inpu d3d->last_width = 512; d3d->last_height = 512; -#ifdef _XBOX1 - d3d->d3d_render_device->CreateVertexBuffer(4 * sizeof(DrawVerticeFormats), - D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_MANAGED, &d3d->vertex_buf); -#else d3d->d3d_render_device->CreateVertexBuffer(4 * sizeof(DrawVerticeFormats), 0, 0, 0, &d3d->vertex_buf, NULL); -#endif static const DrawVerticeFormats init_verts[] = { { -1.0f, -1.0f, 0.0f, 1.0f }, @@ -320,16 +288,11 @@ static void *xdk_d3d_init(const video_info_t *video, const input_driver_t **inpu { 1.0f, 1.0f, 1.0f, 0.0f }, }; -#ifdef _XBOX1 - BYTE *verts_ptr; -#else void *verts_ptr; -#endif d3d->vertex_buf->Lock(0, 0, &verts_ptr, 0); memcpy(verts_ptr, init_verts, sizeof(init_verts)); d3d->vertex_buf->Unlock(); -#ifdef _XBOX360 static const D3DVERTEXELEMENT VertexElements[] = { { 0, 0 * sizeof(float), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, @@ -338,9 +301,6 @@ static void *xdk_d3d_init(const video_info_t *video, const input_driver_t **inpu }; d3d->d3d_render_device->CreateVertexDeclaration(VertexElements, &d3d->v_decl); -#else - d3d->d3d_render_device->SetVertexShader(D3DFVF_XYZ | D3DFVF_TEX1); -#endif d3d->d3d_render_device->Clear(0, NULL, D3DCLEAR_TARGET, 0xff000000, 1.0f, 0); @@ -349,14 +309,8 @@ static void *xdk_d3d_init(const video_info_t *video, const input_driver_t **inpu d3d->d3d_render_device->SetRenderState(D3DRS_ZENABLE, FALSE); D3DVIEWPORT vp = {0}; -#ifdef _XBOX360 vp.Width = d3d->video_mode.fIsHiDef ? 1280 : 640; vp.Height = d3d->video_mode.fIsHiDef ? 720 : 480; -#else - /* FIXME: Xbox 1 - hardcoded */ - vp.Width = 640; - vp.Height = 480; -#endif vp.MinZ = 0.0f; vp.MaxZ = 1.0f; d3d->d3d_render_device->SetViewport(&vp); @@ -411,11 +365,7 @@ static bool xdk_d3d_frame(void *data, const void *frame, verts[i].y += 0.5f / 512.0f; } -#ifdef _XBOX1 - BYTE *verts_ptr; -#else void *verts_ptr; -#endif d3d->vertex_buf->Lock(0, 0, &verts_ptr, 0); memcpy(verts_ptr, verts, sizeof(verts)); d3d->vertex_buf->Unlock(); @@ -485,15 +435,9 @@ static bool xdk_d3d_frame(void *data, const void *frame, d3d->d3d_render_device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER); d3d->d3d_render_device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER); -#ifdef _XBOX1 - d3d->d3d_render_device->SetVertexShader(D3DFVF_XYZ | D3DFVF_TEX1); -#else d3d->d3d_render_device->SetVertexDeclaration(d3d->v_decl); -#endif d3d->d3d_render_device->SetStreamSource(0, d3d->vertex_buf, -#ifdef _XBOX360 0, -#endif sizeof(DrawVerticeFormats)); d3d->d3d_render_device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); @@ -521,15 +465,12 @@ static bool xdk_d3d_frame(void *data, const void *frame, d3d->d3d_render_device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER); d3d->d3d_render_device->SetVertexDeclaration(d3d->v_decl); d3d->d3d_render_device->SetStreamSource(0, d3d->vertex_buf, -#ifdef _XBOX360 0, -#endif sizeof(DrawVerticeFormats)); d3d->d3d_render_device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); } #endif -#ifdef _XBOX360 /* XBox 360 specific font code */ if (msg && !menu_enabled) { @@ -541,7 +482,6 @@ static bool xdk_d3d_frame(void *data, const void *frame, xdk360_console_draw(); } -#endif if(!d3d->block_swap) gfx_ctx_swap_buffers(); @@ -589,14 +529,12 @@ static void xdk_d3d_start(void) gfx_ctx_set_swap_interval(d3d->vsync ? 1 : 0, false); -#ifdef _XBOX360 HRESULT hr = d3d9_init_font("game:\\media\\Arial_12.xpr"); if(hr < 0) { RARCH_ERR("Couldn't create debug console.\n"); } -#endif } static void xdk_d3d_restart(void) @@ -607,9 +545,7 @@ static void xdk_d3d_stop(void) { void *data = driver.video_data; driver.video_data = NULL; -#ifdef _XBOX360 d3d9_deinit_font(); -#endif xdk_d3d_free(data); } diff --git a/360/xdk_d3d9.h b/360/xdk_d3d9.h new file mode 100644 index 0000000000..9f6f36bcc6 --- /dev/null +++ b/360/xdk_d3d9.h @@ -0,0 +1,79 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2012 - Hans-Kristian Arntzen + * Copyright (C) 2011-2012 - 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 . + */ + +#ifndef _XDK360_VIDEO_H +#define _XDK360_VIDEO_H + +#include + +#define DFONT_MAX 4096 +#define PRIM_FVF (D3DFVF_XYZRHW | D3DFVF_TEX1) + +#define MIN_SCALING_FACTOR (1.0f) +#define MAX_SCALING_FACTOR (2.0f) + +typedef struct +{ + float x; + float y; + float z; + float rhw; + float u; + float v; +} primitive_t; + +typedef struct DrawVerticeFormats +{ + float x, y; + float u, v; +} DrawVerticeFormats; + +/* Direct3D 9 */ +#define LPDIRECT3D_PTR LPDIRECT3D9 +#define LPDIRECT3DDEVICE_PTR LPDIRECT3DDEVICE9 +#define LPDIRECT3DTEXTURE_PTR LPDIRECT3DTEXTURE9 +#define LPDIRECT3DSURFACE_PTR LPDIRECT3DSURFACE9 + +#define D3DVIEWPORT D3DVIEWPORT9 +#define D3DVERTEXELEMENT D3DVERTEXELEMENT9 + +#define direct3d_create_ctx Direct3DCreate9 +#define IDirect3DVertexBuffer IDirect3DVertexBuffer9 +#define IDirect3DVertexDeclaration IDirect3DVertexDeclaration9 + +typedef struct xdk_d3d_video +{ + bool block_swap; + bool fbo_enabled; + bool should_resize; + bool quitting; + bool vsync; + unsigned frame_count; + unsigned last_width; + unsigned last_height; + LPDIRECT3D_PTR d3d_device; + LPDIRECT3DDEVICE_PTR d3d_render_device; + IDirect3DVertexBuffer *vertex_buf; + LPDIRECT3DTEXTURE_PTR lpTexture; + D3DTexture lpTexture_ot_as16srgb; + LPDIRECT3DTEXTURE_PTR lpTexture_ot; + IDirect3DVertexDeclaration9* v_decl; + XVIDEO_MODE video_mode; + D3DPRESENT_PARAMETERS d3dpp; + LPDIRECT3DSURFACE_PTR lpSurface; +} xdk_d3d_video_t; + +#endif diff --git a/console/griffin/griffin.c b/console/griffin/griffin.c index ebf1d82e67..4f0f3352ea 100644 --- a/console/griffin/griffin.c +++ b/console/griffin/griffin.c @@ -98,8 +98,12 @@ VIDEO DRIVER #include "../../wii/video.c" #endif -#if defined(_XBOX) && (defined(HAVE_D3D8) || defined(HAVE_D3D9)) -#include "../../360/xdk_d3d.cpp" +#ifdef _XBOX +#if defined(HAVE_D3D9) +#include "../../360/xdk_d3d9.cpp" +#elif defined(HAVE_D3D8) +#include "../../xbox1/xdk_d3d8.cpp" +#endif #endif #include "../../gfx/null.c" @@ -123,9 +127,13 @@ INPUT #include "../../wii/input.c" #endif -#if defined(HAVE_XINPUT_XBOX1) || defined(HAVE_XINPUT2) +#ifdef _XBOX +#if defined(HAVE_XINPUT_XBOX1) +#include "../../xbox1/xinput_xbox_input.c" +#elif defined(HAVE_XINPUT2) #include "../../input/xinput2_input.c" #endif +#endif #include "../../input/null.c" diff --git a/gfx/context/xdk_ctx.h b/gfx/context/xdk_ctx.h index 5e73b3faa5..07977569d0 100644 --- a/gfx/context/xdk_ctx.h +++ b/gfx/context/xdk_ctx.h @@ -17,7 +17,13 @@ #ifndef _XDK360_CTX_H #define _XDK360_CTX_H -#include "../../360/xdk_d3d.h" +#ifdef _XBOX +#if defined(_XBOX1) +#include "../../360/xdk_d3d8.h" +#elif defined(_XBOX360) +#include "../../360/xdk_d3d9.h" +#endif +#endif void gfx_ctx_set_projection(xdk_d3d_video_t *d3d, const struct gl_ortho *ortho, bool allow_rotate); void gfx_ctx_set_aspect_ratio(void *data, unsigned aspectratio_index); diff --git a/input/rarch_xinput2.h b/input/rarch_xinput2.h index ba3e250a82..c3856a4b81 100644 --- a/input/rarch_xinput2.h +++ b/input/rarch_xinput2.h @@ -28,7 +28,7 @@ #ifndef HAVE_XINPUT_XBOX1 #define XINPUT_GAMEPAD_LEFT_TRIGGER (16777216) -#define XINPUT_GAMEPAD_RIGHT_TRIGGER (33554432) +#define XINPUT_GAMEPAD_RIGHT_TRIGGER (33554432) #endif #define DEADZONE (16000) diff --git a/input/xinput2_input.c b/input/xinput2_input.c index 8561f649a6..b6daf3cfc9 100644 --- a/input/xinput2_input.c +++ b/input/xinput2_input.c @@ -27,9 +27,6 @@ #include "rarch_xinput2.h" static uint64_t state[4]; -#ifdef HAVE_XINPUT_XBOX1 -HANDLE gamepads[4]; -#endif static unsigned pads_connected; static void xinput_input_poll(void *data) @@ -42,18 +39,9 @@ static void xinput_input_poll(void *data) { XINPUT_STATE state_tmp; unsigned long retval; -#ifdef HAVE_XINPUT_XBOX1 - gamepads[i] = XInputOpen(XDEVICE_TYPE_GAMEPAD, i, XDEVICE_NO_SLOT, NULL); - if(gamepads[i] != NULL) -#endif { -#ifdef HAVE_XINPUT_XBOX1 - retval = XInputGetState(gamepads[i], &state_tmp); - pads_connected += (retval != ERROR_SUCCESS) ? 0 : 1; -#else retval = XInputGetState(i, &state_tmp); pads_connected += (retval == ERROR_DEVICE_NOT_CONNECTED) ? 0 : 1; -#endif state[i] = state_tmp.Gamepad.wButtons; state[i] |= ((state_tmp.Gamepad.sThumbLX < -DEADZONE)) << 16; state[i] |= ((state_tmp.Gamepad.sThumbLX > DEADZONE)) << 17; @@ -63,13 +51,8 @@ static void xinput_input_poll(void *data) state[i] |= ((state_tmp.Gamepad.sThumbRX > DEADZONE)) << 21; state[i] |= ((state_tmp.Gamepad.sThumbRY > DEADZONE)) << 22; state[i] |= ((state_tmp.Gamepad.sThumbRY < -DEADZONE)) << 23; -#ifdef HAVE_XINPUT_XBOX1 - state[i] |= ((state_tmp.Gamepad.bAnalogButtons[XINPUT_GAMEPAD_LEFT_TRIGGER] > 128 ? 1 : 0)) << 24; - state[i] |= ((state_tmp.Gamepad.bAnalogButtons[XINPUT_GAMEPAD_RIGHT_TRIGGER] > 128 ? 1 : 0)) << 25; -#else state[i] |= ((state_tmp.Gamepad.bLeftTrigger > 128 ? 1 : 0)) << 24; state[i] |= ((state_tmp.Gamepad.bRightTrigger > 128 ? 1 : 0)) << 25; -#endif } } } @@ -121,17 +104,6 @@ void xdk360_input_map_dpad_to_stick(uint32_t map_dpad_enum, uint32_t controller_ static void* xinput_input_init(void) { -#ifdef HAVE_XINPUT_XBOX1 - XDEVICE_PREALLOC_TYPE types[] = - { - {XDEVICE_TYPE_GAMEPAD, 4}, - {XDEVICE_TYPE_MEMORY_UNIT, 2} - }; - - XInitDevices(sizeof(types) / sizeof(XDEVICE_PREALLOC_TYPE), - types ); -#endif - #ifdef _XBOX360 for(unsigned i = 0; i < 4; i++) xdk360_input_map_dpad_to_stick(g_settings.input.dpad_emulation[i], i); diff --git a/xbox1/xdk_d3d8.cpp b/xbox1/xdk_d3d8.cpp new file mode 100644 index 0000000000..56eeb65aeb --- /dev/null +++ b/xbox1/xdk_d3d8.cpp @@ -0,0 +1,389 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2012 - Hans-Kristian Arntzen + * Copyright (C) 2011-2012 - 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 . + */ + +#ifdef _XBOX +#include +#endif + +#include "../driver.h" +#include "xdk_d3d8.h" + +#include "./../gfx/gfx_context.h" +#include "../console/retroarch_console.h" +#include "../general.h" +#include "../message.h" + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +static void check_window(xdk_d3d_video_t *d3d) +{ + bool quit, resize; + + gfx_ctx_check_window(&quit, + &resize, NULL, NULL, + d3d->frame_count); + + if (quit) + d3d->quitting = true; + else if (resize) + d3d->should_resize = true; +} + +static void xdk_d3d_free(void * data) +{ +#ifdef RARCH_CONSOLE + if (driver.video_data) + return; +#endif + + xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)data; + + if (!d3d) + return; + + d3d->d3d_render_device->Release(); + d3d->d3d_device->Release(); + + free(d3d); +} + +static void xdk_d3d_set_viewport(bool force_full) +{ + xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)driver.video_data; + + d3d->d3d_render_device->Clear(0, NULL, D3DCLEAR_TARGET, + 0xff000000, 1.0f, 0); + + // FIXME: Hardcoded for Xbox 1 for now + int width = 640; + int height = 480; + int m_viewport_x_temp, m_viewport_y_temp, m_viewport_width_temp, m_viewport_height_temp; + float m_zNear, m_zFar; + + m_viewport_x_temp = 0; + m_viewport_y_temp = 0; + m_viewport_width_temp = width; + m_viewport_height_temp = height; + + m_zNear = 0.0f; + m_zFar = 1.0f; + + if (!force_full) + { + float desired_aspect = g_settings.video.aspect_ratio; + float device_aspect = (float)width / height; + float delta; + + // If the aspect ratios of screen and desired aspect ratio are sufficiently equal (floating point stuff), + if(g_console.aspect_ratio_index == ASPECT_RATIO_CUSTOM) + { + delta = (desired_aspect / device_aspect - 1.0) / 2.0 + 0.5; + m_viewport_x_temp = g_console.viewports.custom_vp.x; + m_viewport_y_temp = g_console.viewports.custom_vp.y; + m_viewport_width_temp = g_console.viewports.custom_vp.width; + m_viewport_height_temp = g_console.viewports.custom_vp.height; + } + else if (device_aspect > desired_aspect) + { + delta = (desired_aspect / device_aspect - 1.0) / 2.0 + 0.5; + m_viewport_x_temp = (int)(width * (0.5 - delta)); + m_viewport_width_temp = (int)(2.0 * width * delta); + width = (unsigned)(2.0 * width * delta); + } + else + { + delta = (device_aspect / desired_aspect - 1.0) / 2.0 + 0.5; + m_viewport_y_temp = (int)(height * (0.5 - delta)); + m_viewport_height_temp = (int)(2.0 * height * delta); + height = (unsigned)(2.0 * height * delta); + } + } + + D3DVIEWPORT vp = {0}; + vp.Width = m_viewport_width_temp; + vp.Height = m_viewport_height_temp; + vp.X = m_viewport_x_temp; + vp.Y = m_viewport_y_temp; + vp.MinZ = m_zNear; + vp.MaxZ = m_zFar; + d3d->d3d_render_device->SetViewport(&vp); + + //if(gl->overscan_enable && !force_full) + //{ + // m_left = -gl->overscan_amount/2; + // m_right = 1 + gl->overscan_amount/2; + // m_bottom = -gl->overscan_amount/2; + //} +} + +static void xdk_d3d_set_rotation(void * data, unsigned orientation) +{ + (void)data; + xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)data; + FLOAT angle; + + switch(orientation) + { + case ORIENTATION_NORMAL: + angle = M_PI * 0 / 180; + break; + case ORIENTATION_VERTICAL: + angle = M_PI * 270 / 180; + break; + case ORIENTATION_FLIPPED: + angle = M_PI * 180 / 180; + break; + case ORIENTATION_FLIPPED_ROTATED: + angle = M_PI * 90 / 180; + break; + } + + d3d->should_resize = TRUE; +} + +static void *xdk_d3d_init(const video_info_t *video, const input_driver_t **input, void **input_data) +{ + xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)calloc(1, sizeof(xdk_d3d_video_t)); + if (!d3d) + return NULL; + + d3d->d3d_device = direct3d_create_ctx(D3D_SDK_VERSION); + if (!d3d->d3d_device) + { + free(d3d); + return NULL; + } + + memset(&d3d->d3dpp, 0, sizeof(d3d->d3dpp)); + + // no letterboxing in 4:3 mode (if widescreen is + // unsupported + /* Xbox 1 */ + d3d->d3dpp.BackBufferFormat = g_console.color_format ? D3DFMT_A8R8G8B8 : D3DFMT_LIN_A1R5G5B5; + + //FIXME: Hardcoded right now + d3d->d3dpp.BackBufferWidth = 640; + d3d->d3dpp.BackBufferHeight = 480; + + d3d->d3dpp.FullScreen_PresentationInterval = video->vsync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE; + d3d->d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; + d3d->d3dpp.BackBufferCount = 2; + d3d->d3dpp.EnableAutoDepthStencil = FALSE; + d3d->d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + + d3d->d3d_device->CreateDevice(0, D3DDEVTYPE_HAL, NULL, D3DCREATE_HARDWARE_VERTEXPROCESSING, + &d3d->d3dpp, &d3d->d3d_render_device); + + d3d->d3d_render_device->CreateTexture(512, 512, 1, 0, D3DFMT_LIN_X1R5G5B5, + 0, &d3d->lpTexture); + + D3DLOCKED_RECT d3dlr; + d3d->lpTexture->LockRect(0, &d3dlr, NULL, D3DLOCK_NOSYSLOCK); + memset(d3dlr.pBits, 0, 512 * d3dlr.Pitch); + d3d->lpTexture->UnlockRect(0); + + d3d->last_width = 512; + d3d->last_height = 512; + + d3d->d3d_render_device->CreateVertexBuffer(4 * sizeof(DrawVerticeFormats), + D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_MANAGED, &d3d->vertex_buf); + + static const DrawVerticeFormats init_verts[] = { + { -1.0f, -1.0f, 0.0f, 1.0f }, + { 1.0f, -1.0f, 1.0f, 1.0f }, + { -1.0f, 1.0f, 0.0f, 0.0f }, + { 1.0f, 1.0f, 1.0f, 0.0f }, + }; + + BYTE *verts_ptr; + d3d->vertex_buf->Lock(0, 0, &verts_ptr, 0); + memcpy(verts_ptr, init_verts, sizeof(init_verts)); + d3d->vertex_buf->Unlock(); + + d3d->d3d_render_device->SetVertexShader(D3DFVF_XYZ | D3DFVF_TEX1); + d3d->d3d_render_device->Clear(0, NULL, D3DCLEAR_TARGET, + 0xff000000, 1.0f, 0); + + d3d->d3d_render_device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + d3d->d3d_render_device->SetRenderState(D3DRS_ZENABLE, FALSE); + + D3DVIEWPORT vp = {0}; + /* FIXME: Xbox 1 - hardcoded */ + vp.Width = 640; + vp.Height = 480; + vp.MinZ = 0.0f; + vp.MaxZ = 1.0f; + d3d->d3d_render_device->SetViewport(&vp); + + if(g_console.viewports.custom_vp.width == 0) + g_console.viewports.custom_vp.width = vp.Width; + + if(g_console.viewports.custom_vp.height == 0) + g_console.viewports.custom_vp.height = vp.Height; + + xdk_d3d_set_rotation(d3d, g_console.screen_orientation); + + d3d->vsync = video->vsync; + + return d3d; +} + +static bool xdk_d3d_frame(void *data, const void *frame, + unsigned width, unsigned height, unsigned pitch, const char *msg) +{ + if (!frame) + return true; + + xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)data; + bool menu_enabled = g_console.menu_enable; + + if (d3d->last_width != width || d3d->last_height != height) + { + D3DLOCKED_RECT d3dlr; + + d3d->lpTexture->LockRect(0, &d3dlr, NULL, D3DLOCK_NOSYSLOCK); + memset(d3dlr.pBits, 0, 512 * d3dlr.Pitch); + d3d->lpTexture->UnlockRect(0); + + float tex_w = width / 512.0f; + float tex_h = height / 512.0f; + + DrawVerticeFormats verts[] = { + { -1.0f, -1.0f, 0.0f, tex_h }, + { 1.0f, -1.0f, tex_w, tex_h }, + { -1.0f, 1.0f, 0.0f, 0.0f }, + { 1.0f, 1.0f, tex_w, 0.0f }, + }; + + // Align texels and vertices (D3D9 quirk). + for (unsigned i = 0; i < 4; i++) + { + verts[i].x -= 0.5f / 512.0f; + verts[i].y += 0.5f / 512.0f; + } + + BYTE *verts_ptr; + d3d->vertex_buf->Lock(0, 0, &verts_ptr, 0); + memcpy(verts_ptr, verts, sizeof(verts)); + d3d->vertex_buf->Unlock(); + + d3d->last_width = width; + d3d->last_height = height; + } + + if (d3d->should_resize) + xdk_d3d_set_viewport(false); + + d3d->d3d_render_device->Clear(0, NULL, D3DCLEAR_TARGET, + 0xff000000, 1.0f, 0); + d3d->frame_count++; + + d3d->d3d_render_device->SetTexture(0, d3d->lpTexture); + + D3DLOCKED_RECT d3dlr; + d3d->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)); + } + d3d->lpTexture->UnlockRect(0); + + d3d->d3d_render_device->SetSamplerState(0, D3DSAMP_MINFILTER, g_settings.video.smooth ? D3DTEXF_LINEAR : D3DTEXF_POINT); + d3d->d3d_render_device->SetSamplerState(0, D3DSAMP_MAGFILTER, g_settings.video.smooth ? D3DTEXF_LINEAR : D3DTEXF_POINT); + d3d->d3d_render_device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER); + d3d->d3d_render_device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER); + + d3d->d3d_render_device->SetVertexShader(D3DFVF_XYZ | D3DFVF_TEX1); + d3d->d3d_render_device->SetStreamSource(0, d3d->vertex_buf, sizeof(DrawVerticeFormats)); + + d3d->d3d_render_device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); + + if(!d3d->block_swap) + gfx_ctx_swap_buffers(); + + return true; +} + +static void xdk_d3d_set_nonblock_state(void *data, bool state) +{ + xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)data; + + if(d3d->vsync) + { + RARCH_LOG("D3D Vsync => %s\n", state ? "off" : "on"); + gfx_ctx_set_swap_interval(state ? 0 : 1, TRUE); + } +} + +static bool xdk_d3d_alive(void *data) +{ + xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)data; + check_window(d3d); + return !d3d->quitting; +} + +static bool xdk_d3d_focus(void *data) +{ + (void)data; + return gfx_ctx_window_has_focus(); +} + +static void xdk_d3d_start(void) +{ + video_info_t video_info = {0}; + + video_info.vsync = g_settings.video.vsync; + video_info.force_aspect = false; + video_info.fullscreen = true; + video_info.smooth = g_settings.video.smooth; + video_info.input_scale = 2; + + driver.video_data = xdk_d3d_init(&video_info, NULL, NULL); + + xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)driver.video_data; + + gfx_ctx_set_swap_interval(d3d->vsync ? 1 : 0, false); +} + +static void xdk_d3d_restart(void) +{ +} + +static void xdk_d3d_stop(void) +{ + void *data = driver.video_data; + driver.video_data = NULL; + xdk_d3d_free(data); +} + +const video_driver_t video_xdk_d3d = { + xdk_d3d_init, + xdk_d3d_frame, + xdk_d3d_set_nonblock_state, + xdk_d3d_alive, + xdk_d3d_focus, + NULL, + xdk_d3d_free, + "xdk_d3d", + xdk_d3d_start, + xdk_d3d_stop, + xdk_d3d_restart, + xdk_d3d_set_rotation, +}; diff --git a/360/xdk_d3d.h b/xbox1/xdk_d3d8.h similarity index 81% rename from 360/xdk_d3d.h rename to xbox1/xdk_d3d8.h index 9f905866a3..bc01f6fe67 100644 --- a/360/xdk_d3d.h +++ b/xbox1/xdk_d3d8.h @@ -42,7 +42,6 @@ typedef struct DrawVerticeFormats float u, v; } DrawVerticeFormats; -#ifdef _XBOX1 /* Direct3D 8 */ #define LPDIRECT3D_PTR LPDIRECT3D8 #define LPDIRECT3DDEVICE_PTR LPDIRECT3DDEVICE8 @@ -62,20 +61,6 @@ typedef struct DrawVerticeFormats #define D3DSAMP_ADDRESSV D3DTSS_ADDRESSV #define D3DSAMP_MAGFILTER D3DTSS_MAGFILTER #define D3DSAMP_MINFILTER D3DTSS_MINFILTER -#else -/* Direct3D 9 */ -#define LPDIRECT3D_PTR LPDIRECT3D9 -#define LPDIRECT3DDEVICE_PTR LPDIRECT3DDEVICE9 -#define LPDIRECT3DTEXTURE_PTR LPDIRECT3DTEXTURE9 -#define LPDIRECT3DSURFACE_PTR LPDIRECT3DSURFACE9 - -#define D3DVIEWPORT D3DVIEWPORT9 -#define D3DVERTEXELEMENT D3DVERTEXELEMENT9 - -#define direct3d_create_ctx Direct3DCreate9 -#define IDirect3DVertexBuffer IDirect3DVertexBuffer9 -#define IDirect3DVertexDeclaration IDirect3DVertexDeclaration9 -#endif typedef struct xdk_d3d_video { @@ -93,10 +78,6 @@ typedef struct xdk_d3d_video LPDIRECT3DTEXTURE_PTR lpTexture; D3DTexture lpTexture_ot_as16srgb; LPDIRECT3DTEXTURE_PTR lpTexture_ot; -#if defined(_XBOX360) - IDirect3DVertexDeclaration9* v_decl; - XVIDEO_MODE video_mode; -#endif D3DPRESENT_PARAMETERS d3dpp; LPDIRECT3DSURFACE_PTR lpSurface; } xdk_d3d_video_t; diff --git a/xbox1/xinput_xbox_input.c b/xbox1/xinput_xbox_input.c new file mode 100644 index 0000000000..192a00006f --- /dev/null +++ b/xbox1/xinput_xbox_input.c @@ -0,0 +1,110 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2012 - Hans-Kristian Arntzen + * Copyright (C) 2011-2012 - 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 . + */ + +#include +#include + +#ifdef _XBOX +#include +#endif + +#include "../driver.h" +#include "../general.h" +#include "../libretro.h" +#include "../input/rarch_xinput2.h" + +static uint64_t state[4]; +HANDLE gamepads[4]; + +static unsigned pads_connected; + +static void xinput_input_poll(void *data) +{ + (void)data; + + pads_connected = 0; + + for (unsigned i = 0; i < 4; i++) + { + XINPUT_STATE state_tmp; + unsigned long retval; + gamepads[i] = XInputOpen(XDEVICE_TYPE_GAMEPAD, i, XDEVICE_NO_SLOT, NULL); + if(gamepads[i] != NULL) + { + retval = XInputGetState(gamepads[i], &state_tmp); + pads_connected += (retval != ERROR_SUCCESS) ? 0 : 1; + state[i] = state_tmp.Gamepad.wButtons; + state[i] |= ((state_tmp.Gamepad.sThumbLX < -DEADZONE)) << 16; + state[i] |= ((state_tmp.Gamepad.sThumbLX > DEADZONE)) << 17; + state[i] |= ((state_tmp.Gamepad.sThumbLY > DEADZONE)) << 18; + state[i] |= ((state_tmp.Gamepad.sThumbLY < -DEADZONE)) << 19; + state[i] |= ((state_tmp.Gamepad.sThumbRX < -DEADZONE)) << 20; + state[i] |= ((state_tmp.Gamepad.sThumbRX > DEADZONE)) << 21; + state[i] |= ((state_tmp.Gamepad.sThumbRY > DEADZONE)) << 22; + state[i] |= ((state_tmp.Gamepad.sThumbRY < -DEADZONE)) << 23; + state[i] |= ((state_tmp.Gamepad.bAnalogButtons[XINPUT_GAMEPAD_LEFT_TRIGGER] > 128 ? 1 : 0)) << 24; + state[i] |= ((state_tmp.Gamepad.bAnalogButtons[XINPUT_GAMEPAD_RIGHT_TRIGGER] > 128 ? 1 : 0)) << 25; + } + } +} + +static int16_t xinput_input_state(void *data, const struct retro_keybind **binds, + unsigned port, unsigned device, + unsigned index, unsigned id) +{ + (void)data; + unsigned player = port; + uint64_t button = binds[player][id].joykey; + + return (state[player] & button) ? 1 : 0; +} + +static void xinput_input_free_input(void *data) +{ + (void)data; +} + +static void* xinput_input_init(void) +{ + XDEVICE_PREALLOC_TYPE types[] = + { + {XDEVICE_TYPE_GAMEPAD, 4}, + {XDEVICE_TYPE_MEMORY_UNIT, 2} + }; + + XInitDevices(sizeof(types) / sizeof(XDEVICE_PREALLOC_TYPE), + types ); + + return (void*)-1; +} + +static bool xinput_input_key_pressed(void *data, int key) +{ + (void)data; + bool retval = false; + + return retval; +} + +const input_driver_t input_xinput = +{ + xinput_input_init, + xinput_input_poll, + xinput_input_state, + xinput_input_key_pressed, + xinput_input_free_input, + "xinput" +};