diff --git a/360/main.c b/360/main.c index 6c07d7abe2..4c6097e732 100644 --- a/360/main.c +++ b/360/main.c @@ -53,6 +53,7 @@ char SYS_CONFIG_FILE[MAX_PATH_LENGTH]; extern "C" int __stdcall ObCreateSymbolicLink( STRING*, STRING*); int Mounted[20]; +uint64_t ingame_menu_item = 0; int ssnes_main(int argc, char *argv[]); @@ -280,6 +281,76 @@ static void get_environment_settings (void) strlcpy(SYS_CONFIG_FILE, "game:\\ssnes.cfg", sizeof(SYS_CONFIG_FILE)); } +static void ingame_menu (void) +{ + uint32_t menuitem_colors[MENU_ITEM_LAST]; + char comment[256]; + xdk360_video_t *vid = (xdk360_video_t*)g_d3d; + + xdk360_block_swap(); + + do + { + XINPUT_STATE state; + XInputGetState(0, &state); + static uint64_t blocking = 0; + + ssnes_render_cached_frame(); + + if(IS_TIMER_EXPIRED() && blocking == false) + { + if(state.Gamepad.wButtons & XINPUT_GAMEPAD_B) + { + g_console.frame_advance_enable = false; + ingame_menu_item = 0; + g_console.ingame_menu_enable = false; + g_console.mode_switch = MODE_EMULATION; + } + + switch(ingame_menu_item) + { + case MENU_ITEM_LOAD_STATE: + break; + case MENU_ITEM_SAVE_STATE: + break; + case MENU_ITEM_KEEP_ASPECT_RATIO: + break; + case MENU_ITEM_OVERSCAN_AMOUNT: + break; + case MENU_ITEM_ORIENTATION: + break; + case MENU_ITEM_FRAME_ADVANCE: + break; + case MENU_ITEM_RESIZE_MODE: + break; + case MENU_ITEM_SCREENSHOT_MODE: + break; + case MENU_ITEM_RETURN_TO_GAME: + break; + case MENU_ITEM_RESET: + break; + case MENU_ITEM_RETURN_TO_MENU: + break; + case MENU_ITEM_RETURN_TO_DASHBOARD: + break; + } + + float x_position = 0.3f; + float font_size = 1.1f; + float ypos = 0.19f; + float ypos_increment = 0.04f; + + g_screen_console.m_Font.SetFontSize(3.0f, 3.0f); + + vid->xdk360_render_device->Present(NULL, NULL, NULL, NULL); + } + }while(g_console.ingame_menu_enable); + + g_screen_console.m_Font.SetFontSize(2.0f, 2.0f); + + xdk360_unblock_swap(); +} + int main(int argc, char *argv[]) { get_environment_settings(); @@ -296,8 +367,18 @@ int main(int argc, char *argv[]) begin_loop: if(g_console.mode_switch == MODE_EMULATION) { + bool repeat = false; + if(ingame_menu_item != 0) + g_console.ingame_menu_enable = true; + input_xdk360.poll(NULL); - while(ssnes_main_iterate()); + + do{ + repeat = ssnes_main_iterate(); + }while(repeat && !g_console.frame_advance_enable); + + if(g_console.ingame_menu_enable) + ingame_menu(); } else if(g_console.mode_switch == MODE_MENU) { diff --git a/360/shared.h b/360/shared.h index 734231da3e..65a4ae9915 100644 --- a/360/shared.h +++ b/360/shared.h @@ -24,3 +24,20 @@ enum MODE_MENU, MODE_EXIT }; + +enum { + MENU_ITEM_LOAD_STATE = 0, + MENU_ITEM_SAVE_STATE, + MENU_ITEM_KEEP_ASPECT_RATIO, + MENU_ITEM_OVERSCAN_AMOUNT, + MENU_ITEM_ORIENTATION, + MENU_ITEM_RESIZE_MODE, + MENU_ITEM_FRAME_ADVANCE, + MENU_ITEM_SCREENSHOT_MODE, + MENU_ITEM_RESET, + MENU_ITEM_RETURN_TO_GAME, + MENU_ITEM_RETURN_TO_MENU, + MENU_ITEM_RETURN_TO_DASHBOARD +}; + +#define MENU_ITEM_LAST MENU_ITEM_RETURN_TO_DASHBOARD+1 diff --git a/360/xdk360_input.cpp b/360/xdk360_input.cpp index 1a9d9b3e9f..a0ba9a6fb9 100644 --- a/360/xdk360_input.cpp +++ b/360/xdk360_input.cpp @@ -114,37 +114,55 @@ static bool xdk360_key_pressed(void *data, int key) { (void)data; XInputGetState(0, &state[0]); + bool retval; + + retval = false; switch(key) { - case SSNES_FAST_FORWARD_HOLD_KEY: - return ((state[0].Gamepad.sThumbRY < -DEADZONE) && !(state[0].Gamepad.bRightTrigger > 128)); - case SSNES_LOAD_STATE_KEY: - return ((state[0].Gamepad.sThumbRY > DEADZONE) && (state[0].Gamepad.bRightTrigger > 128)); - case SSNES_SAVE_STATE_KEY: - return ((state[0].Gamepad.sThumbRY < -DEADZONE) && (state[0].Gamepad.bRightTrigger > 128)); - case SSNES_STATE_SLOT_PLUS: - return ((state[0].Gamepad.sThumbRX > DEADZONE) && (state[0].Gamepad.bRightTrigger > 128)); - case SSNES_STATE_SLOT_MINUS: - return ((state[0].Gamepad.sThumbRX < -DEADZONE) && (state[0].Gamepad.bRightTrigger > 128)); - case SSNES_REWIND: - return ((state[0].Gamepad.sThumbRY > DEADZONE) && !(state[0].Gamepad.bRightTrigger > 128)); - case SSNES_QUIT_KEY: - g_console.menu_enable = ((state[0].Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB) - && (state[0].Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB) && IS_TIMER_EXPIRED()); - if(g_console.menu_enable) - { - g_console.mode_switch = MODE_MENU; - SET_TIMER_EXPIRATION(60); - } - else - g_console.mode_switch = MODE_EMULATION; - return g_console.menu_enable; - default: - return false; + case SSNES_FAST_FORWARD_HOLD_KEY: + return ((state[0].Gamepad.sThumbRY < -DEADZONE) && !(state[0].Gamepad.bRightTrigger > 128)); + case SSNES_LOAD_STATE_KEY: + return ((state[0].Gamepad.sThumbRY > DEADZONE) && (state[0].Gamepad.bRightTrigger > 128)); + case SSNES_SAVE_STATE_KEY: + return ((state[0].Gamepad.sThumbRY < -DEADZONE) && (state[0].Gamepad.bRightTrigger > 128)); + case SSNES_STATE_SLOT_PLUS: + return ((state[0].Gamepad.sThumbRX > DEADZONE) && (state[0].Gamepad.bRightTrigger > 128)); + case SSNES_STATE_SLOT_MINUS: + return ((state[0].Gamepad.sThumbRX < -DEADZONE) && (state[0].Gamepad.bRightTrigger > 128)); + case SSNES_FRAMEADVANCE: + if(g_console.frame_advance_enable) + { + g_console.menu_enable = false; + g_console.ingame_menu_enable = true; + g_console.mode_switch = MODE_EMULATION; + } + return g_console.frame_advance_enable; + case SSNES_REWIND: + return ((state[0].Gamepad.sThumbRY > DEADZONE) && !(state[0].Gamepad.bRightTrigger > 128)); + case SSNES_QUIT_KEY: + { + uint32_t left_thumb_pressed = (state[0].Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB); + uint32_t right_thumb_pressed = (state[0].Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB); + + g_console.menu_enable = right_thumb_pressed && left_thumb_pressed && IS_TIMER_EXPIRED(); + g_console.ingame_menu_enable = right_thumb_pressed && !left_thumb_pressed; + + if(g_console.menu_enable && !g_console.ingame_menu_enable) + { + g_console.mode_switch = MODE_MENU; + SET_TIMER_EXPIRATION(60); + retval = g_console.menu_enable; + } + else + { + g_console.mode_switch = MODE_EMULATION; + retval = g_console.ingame_menu_enable; + } + } } - return false; + return retval; } const input_driver_t input_xdk360 = { diff --git a/360/xdk360_video.cpp b/360/xdk360_video.cpp index 3ed8953077..5853ea4015 100644 --- a/360/xdk360_video.cpp +++ b/360/xdk360_video.cpp @@ -287,11 +287,26 @@ static bool xdk360_gfx_frame(void *data, const void *frame, g_screen_console.Render(); } - vid->xdk360_render_device->Present(NULL, NULL, NULL, NULL); + if(!vid->block_swap) + vid->xdk360_render_device->Present(NULL, NULL, NULL, NULL); return true; } +void xdk360_block_swap (void) +{ + xdk360_video_t *vid = (xdk360_video_t*)g_d3d; + vid->block_swap = true; + SSNES_LOG("Swap is set to blocked.\n"); +} + +void xdk360_unblock_swap (void) +{ + xdk360_video_t * vid = (xdk360_video_t*)g_d3d; + vid->block_swap = false; + SSNES_LOG("Swap is set to non-blocked.\n"); +} + static void xdk360_gfx_set_nonblock_state(void *data, bool state) { xdk360_video_t *vid = (xdk360_video_t*)data; diff --git a/360/xdk360_video.h b/360/xdk360_video.h index 63fd380833..645682d881 100644 --- a/360/xdk360_video.h +++ b/360/xdk360_video.h @@ -35,6 +35,7 @@ typedef struct { typedef struct xdk360_video { + bool block_swap; bool vsync; unsigned last_width, last_height; IDirect3D9* xdk360_device; @@ -55,6 +56,8 @@ typedef struct xdk360_video void xdk360_video_init(void); void xdk360_video_deinit(void); void xdk360_video_set_vsync(bool vsync); +void xdk360_block_swap (void); +void xdk360_unblock_swap (void); extern Console g_screen_console; extern unsigned g_frame_count; diff --git a/360/xdk360_video_console.cpp b/360/xdk360_video_console.cpp index a4ce07bedb..3443764b03 100644 --- a/360/xdk360_video_console.cpp +++ b/360/xdk360_video_console.cpp @@ -82,7 +82,10 @@ HRESULT Console::Create( LPCSTR strFontFileName, unsigned long colBackColor, for( unsigned int i = 0; i < m_cScreenHeightVirtual; i++ ) m_Lines[ i ] = m_Buffer + ( m_cScreenWidth + 1 ) * i; - CLEAR_SCREEN(); + m_nCurLine = 0; + m_cCurLineLength = 0; + memset( m_Buffer, 0, m_cScreenHeightVirtual * ( m_cScreenWidth + 1 ) * sizeof( wchar_t ) ); + Render(); return hr; } @@ -168,7 +171,9 @@ void Console::Add( wchar_t wch ) // If this is a newline, just increment lines and move on if( wch == L'\n' ) { - INCREMENT_LINE(); + m_nCurLine = ( m_nCurLine + 1 ) % m_cScreenHeightVirtual; + m_cCurLineLength = 0; + memset( m_Lines[m_nCurLine], 0, ( m_cScreenWidth + 1 ) * sizeof( wchar_t ) ); return; } @@ -192,7 +197,9 @@ void Console::Add( wchar_t wch ) // If we need to skip to the next line, do so if( bIncrementLine ) { - INCREMENT_LINE(); + m_nCurLine = ( m_nCurLine + 1 ) % m_cScreenHeightVirtual; + m_cCurLineLength = 0; + memset( m_Lines[m_nCurLine], 0, ( m_cScreenWidth + 1 ) * sizeof( wchar_t ) ); m_Lines[ m_nCurLine ][0] = wch; } @@ -209,7 +216,9 @@ void Console::Format(int clear_screen, _In_z_ _Printf_format_string_ LPCSTR strF { if(clear_screen) { - CLEAR_SCREEN(); + m_nCurLine = 0; + m_cCurLineLength = 0; + memset( m_Buffer, 0, m_cScreenHeightVirtual * ( m_cScreenWidth + 1 ) * sizeof( wchar_t ) ); } va_list pArgList; @@ -225,7 +234,9 @@ void Console::Format(int clear_screen, _In_z_ _Printf_format_string_ LPCWSTR wst { if(clear_screen) { - CLEAR_SCREEN(); + m_nCurLine = 0; + m_cCurLineLength = 0; + memset( m_Buffer, 0, m_cScreenHeightVirtual * ( m_cScreenWidth + 1 ) * sizeof( wchar_t ) ); } va_list pArgList; diff --git a/360/xdk360_video_console.h b/360/xdk360_video_console.h index f6ac741a24..a436b23677 100644 --- a/360/xdk360_video_console.h +++ b/360/xdk360_video_console.h @@ -32,17 +32,6 @@ #define SAFE_AREA_PCT_4x3 85 #define SAFE_AREA_PCT_HDTV 90 -#define INCREMENT_LINE() \ - m_nCurLine = ( m_nCurLine + 1 ) % m_cScreenHeightVirtual; \ - m_cCurLineLength = 0; \ - memset( m_Lines[m_nCurLine], 0, ( m_cScreenWidth + 1 ) * sizeof( wchar_t ) ); - -#define CLEAR_SCREEN() \ - m_nCurLine = 0; \ - m_cCurLineLength = 0; \ - memset( m_Buffer, 0, m_cScreenHeightVirtual * ( m_cScreenWidth + 1 ) * sizeof( wchar_t ) ); \ - Render(); - //-------------------------------------------------------------------------------------- // Name: class Console // Desc: Class to implement the console. @@ -69,6 +58,8 @@ public: // method for rendering the console void Render(); + // Font for rendering text + XdkFont m_Font; private: int first_message; // Safe area dimensions @@ -78,9 +69,6 @@ private: unsigned int m_cxSafeAreaOffset; unsigned int m_cySafeAreaOffset; - // Font for rendering text - XdkFont m_Font; - // Colors unsigned long m_colBackColor; unsigned long m_colTextColor; diff --git a/360/xdk360_video_debugfonts.cpp b/360/xdk360_video_debugfonts.cpp index 0e370437d8..43fd436cdb 100644 --- a/360/xdk360_video_debugfonts.cpp +++ b/360/xdk360_video_debugfonts.cpp @@ -288,6 +288,11 @@ XdkFont::~XdkFont() Destroy(); } +void XdkFont::SetFontSize(float x, float y) +{ + m_fXScaleFactor = x; + m_fYScaleFactor = y; +} //-------------------------------------------------------------------------------------- // Name: Create() diff --git a/360/xdk360_video_debugfonts.h b/360/xdk360_video_debugfonts.h index 3be4d62f68..64056d49ab 100644 --- a/360/xdk360_video_debugfonts.h +++ b/360/xdk360_video_debugfonts.h @@ -113,6 +113,7 @@ public: void SetWindow( long x1, long y1, long x2, long y2 ); void GetWindow(D3DRECT &rcWindow) const; void SetCursorPosition( float fCursorX, float fCursorY ); + void SetFontSize(float x, float y); // Public calls to render text. Callers can simply call DrawText(), but for // performance, they should batch multiple calls together, bracketed by calls to