mirror of
https://github.com/spice2x/spice2x.github.io.git
synced 2026-08-01 22:30:42 -07:00
popn: subscreen overlay (#631)
## Link to GitHub Issue or related Pull Request, if one exists #618 ## Description of change Add overlay for subscreen. Add an option for no subscreen window. Use the same "force redraw subscreen" logic we used in SDVX to fix the same issue. Known issues: * still crashing when running windowed if there is only one monitor * having only one monitor causes sunscreen overlay to not work (NumberOfAdaptersInGroup issue?) ## Testing
This commit is contained in:
@@ -583,6 +583,7 @@ set(SOURCE_FILES ${SOURCE_FILES}
|
||||
overlay/windows/log.cpp
|
||||
overlay/windows/midi.cpp
|
||||
overlay/windows/patch_manager.cpp
|
||||
overlay/windows/popn_sub.cpp
|
||||
overlay/windows/wnd_manager.cpp
|
||||
|
||||
# rawinput
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "bi3a_hook.h"
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include "hooks/graphics/graphics.h"
|
||||
#include "rawinput/rawinput.h"
|
||||
#include "util/detour.h"
|
||||
#include "util/fileutils.h"
|
||||
@@ -17,11 +18,15 @@
|
||||
#include "misc/eamuse.h"
|
||||
#include "util/sysutils.h"
|
||||
#include "io.h"
|
||||
#include "util/deferlog.h"
|
||||
#include "misc/wintouchemu.h"
|
||||
|
||||
namespace games::popn {
|
||||
|
||||
bool SHOW_PIKA_MONITOR_WARNING = false;
|
||||
|
||||
#if SPICE64 && !SPICE_XP
|
||||
|
||||
|
||||
static decltype(DisplayConfigGetDeviceInfo) *DisplayConfigGetDeviceInfo_orig = nullptr;
|
||||
|
||||
static
|
||||
@@ -406,6 +411,29 @@ namespace games::popn {
|
||||
#endif
|
||||
|
||||
#if SPICE64 && !SPICE_XP
|
||||
if (!GRAPHICS_WINDOWED && D3D9_ADAPTER.has_value()) {
|
||||
SHOW_PIKA_MONITOR_WARNING = true;
|
||||
log_warning(
|
||||
"popn",
|
||||
"\n\n"
|
||||
"!!! using -dxmainadapter option is NOT recommended due to known !!!\n"
|
||||
"!!! compatibility issues with the game !!!\n"
|
||||
"!!! !!!\n"
|
||||
"!!! * game may launch in wrong resolution or refresh rate !!!\n"
|
||||
"!!! * touch / mouse input may stop working in subscreen / overlay !!!\n"
|
||||
"!!! !!!\n"
|
||||
"!!! recommendation is to use the Change Main Monitor (-mainmonitor) !!!\n"
|
||||
"!!! option instead of -dxmainadapter !!!\n\n"
|
||||
);
|
||||
|
||||
deferredlogs::defer_error_messages({
|
||||
"-dxmainadapter option is NOT recommended due to known compatibility ",
|
||||
" issues with the game!",
|
||||
" * game may launch in wrong resolution or refresh rate",
|
||||
" * touch / mouse input may stop working in subscreen / overlay",
|
||||
" use Change Main Monitor (-mainmonitor) option instead"
|
||||
});
|
||||
}
|
||||
|
||||
// monitor hook
|
||||
DisplayConfigGetDeviceInfo_orig =
|
||||
@@ -445,6 +473,10 @@ namespace games::popn {
|
||||
// 00000100 0000000B 00000001 (button 9)
|
||||
// set third column to 0 and it will work with BIO2
|
||||
|
||||
wintouchemu::FORCE = true;
|
||||
wintouchemu::INJECT_MOUSE_AS_WM_TOUCH = true;
|
||||
wintouchemu::hook_title_ends("", "Main Screen", avs::game::DLL_INSTANCE);
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
@@ -6,9 +6,17 @@
|
||||
namespace games::popn {
|
||||
|
||||
static inline bool is_pikapika_model() {
|
||||
|
||||
#if SPICE64
|
||||
return (avs::game::is_model("M39") && avs::game::SPEC[0] == 'D');
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
extern bool SHOW_PIKA_MONITOR_WARNING;
|
||||
|
||||
class POPNGame : public games::Game {
|
||||
public:
|
||||
POPNGame();
|
||||
|
||||
@@ -661,7 +661,7 @@ HRESULT STDMETHODCALLTYPE WrappedIDirect3D9::GetDeviceCaps(UINT Adapter, D3DDEVT
|
||||
}
|
||||
// in windowed mode, LDJ will always launch two windows, no special handling needed here
|
||||
} else if (avs::game::is_model("KFC")) {
|
||||
if (GRAPHICS_WINDOWED & GRAPHICS_PREVENT_SECONDARY_WINDOW) {
|
||||
if (GRAPHICS_WINDOWED && GRAPHICS_PREVENT_SECONDARY_WINDOW) {
|
||||
// user wants windowed mode but does not want subscreen at all
|
||||
pCaps->NumberOfAdaptersInGroup = 1;
|
||||
} else {
|
||||
@@ -1206,7 +1206,10 @@ static void graphics_d3d9_ldj_on_present(IDirect3DDevice9 *wrapped_device) {
|
||||
if (SUB_SWAP_CHAIN != nullptr) {
|
||||
wintouchemu::update();
|
||||
|
||||
if (GRAPHICS_WINDOWED || SUBSCREEN_FORCE_REDRAW) {
|
||||
// newer versions of exceed gear needs SUBSCREEN_FORCE_REDRAW
|
||||
// (when enabled on older versions of EG, you end up with graphical glitches on the subscreen
|
||||
// early versions of popn HC needs this as well, otherwise the subscreen doesn't update at all
|
||||
if (GRAPHICS_WINDOWED || SUBSCREEN_FORCE_REDRAW || games::popn::is_pikapika_model()) {
|
||||
SUB_SWAP_CHAIN->Present(nullptr, nullptr, nullptr, nullptr, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "games/ddr/ddr.h"
|
||||
#include "games/gitadora/gitadora.h"
|
||||
#include "games/iidx/iidx.h"
|
||||
#include "games/popn/popn.h"
|
||||
#include "hooks/graphics/backends/d3d9/d3d9_backend.h"
|
||||
#include "launcher/shutdown.h"
|
||||
#include "overlay/overlay.h"
|
||||
@@ -401,7 +402,9 @@ static HWND WINAPI CreateWindowExA_hook(DWORD dwExStyle, LPCSTR lpClassName, LPC
|
||||
|
||||
if (is_popn_sub_window) {
|
||||
POPN_SUBSCREEN_WINDOW = result;
|
||||
graphics_hook_subscreen_window(POPN_SUBSCREEN_WINDOW);
|
||||
if (!GRAPHICS_PREVENT_SECONDARY_WINDOW) {
|
||||
graphics_hook_subscreen_window(POPN_SUBSCREEN_WINDOW);
|
||||
}
|
||||
}
|
||||
|
||||
disable_touch_indicators(result);
|
||||
@@ -671,6 +674,13 @@ static BOOL WINAPI ShowWindow_hook(HWND hWnd, int nCmdShow) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (games::popn::is_pikapika_model() &&
|
||||
GRAPHICS_PREVENT_SECONDARY_WINDOW &&
|
||||
hWnd == POPN_SUBSCREEN_WINDOW) {
|
||||
log_info("graphics", "ShowWindow_hook - hiding sub window {}", fmt::ptr(hWnd));
|
||||
return true;
|
||||
}
|
||||
|
||||
// call original
|
||||
return ShowWindow_orig(hWnd, nCmdShow);
|
||||
}
|
||||
|
||||
@@ -590,6 +590,10 @@ int main_implementation(int argc, char *argv[]) {
|
||||
if (options[launcher::Options::PopnMusicForceSDMode].value_bool()) {
|
||||
avs::ea3::PCB_TYPE = 0;
|
||||
}
|
||||
if (options[launcher::Options::PopnNoSub].value_bool()) {
|
||||
GRAPHICS_FORCE_SINGLE_ADAPTER = true;
|
||||
GRAPHICS_PREVENT_SECONDARY_WINDOW = true;
|
||||
}
|
||||
if (options[launcher::Options::LoadMetalGearArcadeModule].value_bool()) {
|
||||
attach_mga = true;
|
||||
}
|
||||
|
||||
@@ -988,6 +988,15 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
|
||||
.game_name = "Pop'n Music",
|
||||
.category = "Game Options",
|
||||
},
|
||||
{
|
||||
// PopnNoSub
|
||||
.title = "Pop'n Music PikaPika Subscreen Disable",
|
||||
.name = "popnnosub",
|
||||
.desc = "Prevents PikaPika model subscreen from launching a separate window.",
|
||||
.type = OptionType::Bool,
|
||||
.game_name = "Pop'n Music",
|
||||
.category = "Game Options",
|
||||
},
|
||||
{
|
||||
.title = "Force Load HELLO! Pop'n Music Module",
|
||||
.name = "hpm",
|
||||
|
||||
@@ -99,6 +99,7 @@ namespace launcher {
|
||||
LoadPopnMusicModule,
|
||||
PopnMusicForceHDMode,
|
||||
PopnMusicForceSDMode,
|
||||
PopnNoSub,
|
||||
LoadHelloPopnMusicModule,
|
||||
LoadGitaDoraModule,
|
||||
GitaDoraTwoChannelAudio,
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "cfg/screen_resize.h"
|
||||
#include "games/gitadora/gitadora.h"
|
||||
#include "games/iidx/iidx.h"
|
||||
#include "games/popn/popn.h"
|
||||
#include "hooks/graphics/graphics.h"
|
||||
#include "overlay/overlay.h"
|
||||
#include "overlay/windows/generic_sub.h"
|
||||
@@ -405,6 +406,10 @@ namespace wintouchemu {
|
||||
// use mouse position as ImGui overlay will block the touch window
|
||||
log_info("wintouchemu", "use mouse cursor API for ldj overlay subscreen");
|
||||
USE_MOUSE = true;
|
||||
} else if (games::popn::is_pikapika_model()) {
|
||||
// same as iidx case above
|
||||
log_info("wintouchemu", "use mouse cursor API for popn overlay subscreen");
|
||||
USE_MOUSE = true;
|
||||
} else if (games::gitadora::is_arena_model() && games::gitadora::ARENA_SINGLE_WINDOW) {
|
||||
log_info("wintouchemu", "use mouse cursor API for gitadora overlay subscreen");
|
||||
USE_MOUSE = true;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "games/io.h"
|
||||
#include "games/gitadora/gitadora.h"
|
||||
#include "games/iidx/iidx.h"
|
||||
#include "games/popn/popn.h"
|
||||
#include "hooks/graphics/graphics.h"
|
||||
#include "misc/eamuse.h"
|
||||
#include "touch/touch.h"
|
||||
@@ -35,6 +36,7 @@
|
||||
#include "windows/iopanel_ddr.h"
|
||||
#include "windows/iopanel_gfdm.h"
|
||||
#include "windows/iopanel_iidx.h"
|
||||
#include "windows/popn_sub.h"
|
||||
#include "windows/sdvx_sub.h"
|
||||
#include "windows/keypad.h"
|
||||
#include "windows/log.h"
|
||||
@@ -415,6 +417,8 @@ void overlay::SpiceOverlay::init() {
|
||||
window_sub = new overlay::windows::SDVXSubScreen(this);
|
||||
} else if (games::gitadora::is_arena_model() && games::gitadora::ARENA_SINGLE_WINDOW) {
|
||||
window_sub = new overlay::windows::GitaDoraSubScreen(this);
|
||||
} else if (games::popn::is_pikapika_model()) {
|
||||
window_sub = new overlay::windows::PopnSubScreen(this);
|
||||
}
|
||||
|
||||
if (window_sub) {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "util/logging.h"
|
||||
#include "games/iidx/iidx.h"
|
||||
#include "games/gitadora/gitadora.h"
|
||||
#include "games/popn/popn.h"
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
@@ -72,6 +73,8 @@ namespace overlay::windows {
|
||||
sub = "Show DRS Dance Floor";
|
||||
} else if (games::gitadora::is_arena_model() && games::gitadora::ARENA_SINGLE_WINDOW) {
|
||||
sub = "Show GITADORA Subscreen";
|
||||
} else if (games::popn::is_pikapika_model()) {
|
||||
sub = "Show Pop'n Subscreen";
|
||||
}
|
||||
|
||||
build_button(this->overlay->window_sub, sub, size, NextItem::NEW_LINE, false);
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
#undef CINTERFACE
|
||||
|
||||
#include "avs/game.h"
|
||||
#include "popn_sub.h"
|
||||
#include "games/popn/popn.h"
|
||||
#include "hooks/graphics/graphics.h"
|
||||
#include "touch/touch.h"
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
PopnSubScreen::PopnSubScreen(SpiceOverlay *overlay) : GenericSubScreen(overlay) {
|
||||
this->title = "Pop'n Subscreen";
|
||||
|
||||
if (!games::popn::is_pikapika_model()) {
|
||||
this->disabled_message = "Game did not launch as Pikapika Pop-kun (invalid <spec>)!";
|
||||
} else if (games::popn::SHOW_PIKA_MONITOR_WARNING) {
|
||||
this->disabled_message = "Subscreen overlay is not compatible with -dxmainadapter option, use -mainmonitor instead";
|
||||
} else if (GRAPHICS_WINDOWED && !GRAPHICS_PREVENT_SECONDARY_WINDOW) {
|
||||
this->disabled_message = "Subscren overlay was not enabled in spicecfg. Use the second window (ALT+TAB).";
|
||||
}
|
||||
|
||||
this->resize_callback = keep_16_by_10;
|
||||
float size = 0.5f;
|
||||
this->init_size = ImVec2(
|
||||
ImGui::GetIO().DisplaySize.x * size,
|
||||
(ImGui::GetIO().DisplaySize.x * size * 10 / 16) + ImGui::GetFrameHeight());
|
||||
|
||||
this->size_max = ImVec2(
|
||||
ImGui::GetIO().DisplaySize.x - ImGui::GetFrameHeight() * 2,
|
||||
ImGui::GetIO().DisplaySize.y - ImGui::GetFrameHeight() * 2);
|
||||
|
||||
// middle / bottom
|
||||
this->init_pos = ImVec2(
|
||||
ImGui::GetIO().DisplaySize.x / 2 - this->init_size.x / 2,
|
||||
ImGui::GetIO().DisplaySize.y - this->init_size.y - (ImGui::GetFrameHeight() / 2));
|
||||
}
|
||||
|
||||
void PopnSubScreen::touch_transform(const ImVec2 xy_in, LONG *x_out, LONG *y_out) {
|
||||
if (!this->get_active()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (GRAPHICS_WINDOWED) {
|
||||
// Touch needs to be registered on global coords
|
||||
*x_out = SPICETOUCH_TOUCH_X + xy_in.x * SPICETOUCH_TOUCH_WIDTH;
|
||||
*y_out = SPICETOUCH_TOUCH_Y + xy_in.y * SPICETOUCH_TOUCH_HEIGHT;
|
||||
} else {
|
||||
// Fullscreen mode, scale to game coords
|
||||
*x_out = xy_in.x * ImGui::GetIO().DisplaySize.x;
|
||||
*y_out = xy_in.y * ImGui::GetIO().DisplaySize.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "overlay/window.h"
|
||||
#include "overlay/windows/generic_sub.h"
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
class PopnSubScreen : public GenericSubScreen {
|
||||
public:
|
||||
PopnSubScreen(SpiceOverlay *overlay);
|
||||
|
||||
protected:
|
||||
void touch_transform(const ImVec2 xy_in, LONG *x_out, LONG *y_out) override;
|
||||
|
||||
private:
|
||||
static void keep_16_by_10(ImGuiSizeCallbackData* data) {
|
||||
data->DesiredSize.y = (data->DesiredSize.x * 10.f / 16.f) + ImGui::GetFrameHeight();
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user