implement input publishing and receiving
Input publishing is currently toggled via Ctrl-A. This needs to be changed because pressing Ctrl makes doomguy attack. So every time input publishing is disabled the guy continues attacking. Use one of the unused F keys if there is one.
This commit is contained in:
parent
e2830e3d68
commit
062980d465
2 changed files with 70 additions and 9 deletions
|
@ -20,8 +20,8 @@
|
|||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "dp_common.h"
|
||||
#include "dp_util.hpp"
|
||||
#include "doomlib.hpp"
|
||||
|
||||
#if DoomBytesPerPixel == 3
|
||||
// FIXME: don't use, it's buggy
|
||||
|
@ -96,6 +96,8 @@ struct ControllerContext
|
|||
bool isMousePanning = false;
|
||||
bool isFullscreen = false;
|
||||
bool uiVisible = true;
|
||||
bool publishInputsMode = false;
|
||||
MsgInputs inputs;
|
||||
};
|
||||
|
||||
struct ControllerActions
|
||||
|
@ -221,7 +223,7 @@ void check_on_dooms(ControllerContext &ctx)
|
|||
|
||||
void do_networking(ControllerContext &ctx)
|
||||
{
|
||||
// Set to true if we receive at least on DP_DS_Ready DoomState update. Then
|
||||
// Set to true if we receive at least one DP_DS_Ready DoomState update. Then
|
||||
// a single DP_DC_RunDoom command is broadcast.
|
||||
bool sendRunDoom = false;
|
||||
|
||||
|
@ -390,6 +392,21 @@ void do_networking(ControllerContext &ctx)
|
|||
if ((res = nng_sendmsg(ctx.pub, msg, 0)))
|
||||
dp_nng_fatal("ctrl/sendmsg", res);
|
||||
}
|
||||
|
||||
if (ctx.publishInputsMode && ctx.inputs.eventCount)
|
||||
{
|
||||
nng_msg *msg = nullptr;
|
||||
int res = 0;
|
||||
if ((res = nng_msg_alloc(&msg, sizeof(MsgInputs))))
|
||||
dp_nng_fatal("ctrl/nng_msg_alloc", res);
|
||||
|
||||
auto dpmsg = DP_NNG_BODY_AS(msg, MsgInputs);
|
||||
*dpmsg = ctx.inputs;
|
||||
ctx.inputs.eventCount = 0;
|
||||
|
||||
if ((res = nng_sendmsg(ctx.pub, msg, 0)))
|
||||
dp_nng_fatal("ctrl/sendmsg", res);
|
||||
}
|
||||
}
|
||||
|
||||
void final_cleanup(ControllerContext &ctx)
|
||||
|
@ -405,6 +422,13 @@ void final_cleanup(ControllerContext &ctx)
|
|||
}
|
||||
}
|
||||
|
||||
// Same as D_PostEvent from d_main.c
|
||||
void post_doom_event(ControllerContext &ctx, const dp_doom_event_t &doom_event)
|
||||
{
|
||||
ctx.inputs.events[ctx.inputs.eventCount] = doom_event;
|
||||
ctx.inputs.eventCount = (ctx.inputs.eventCount+1) & (DoomMaxEvents-1);
|
||||
}
|
||||
|
||||
void render_dooms(ControllerContext &ctx)
|
||||
{
|
||||
SDL_Rect destRect = { ctx.offsetX, ctx.offsetY, DoomScreenWidth, DoomScreenHeight };
|
||||
|
@ -493,6 +517,8 @@ ControllerActions run_ui(ControllerContext &ctx)
|
|||
{
|
||||
if (ImGui::BeginMenu("Menu"))
|
||||
{
|
||||
ImGui::MenuItem("Send inputs to dooms", "Ctrl-A", &ctx.publishInputsMode, true);
|
||||
ImGui::Separator();
|
||||
ImGui::MenuItem("Quit", "Ctrl+Q", &ctx.quit, true);
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
@ -568,6 +594,12 @@ int doom_controller_loop(ControllerContext &ctx)
|
|||
|
||||
if (event.type == SDL_MOUSEWHEEL)
|
||||
mouseWheel += event.wheel.y;
|
||||
|
||||
if (ctx.publishInputsMode)
|
||||
{
|
||||
if (auto doomEvent = doomevent_from_sdlevent(event))
|
||||
post_doom_event(ctx, *doomEvent);
|
||||
}
|
||||
}
|
||||
|
||||
// Process input events not consumed by ImGui
|
||||
|
@ -577,6 +609,7 @@ int doom_controller_loop(ControllerContext &ctx)
|
|||
static const float ScaleStep = 0.01f;
|
||||
s32 PanStep = io.KeyCtrl ? 10 : 2;
|
||||
|
||||
// Ctrl-Q to quit
|
||||
if (io.KeyCtrl && ImGui::IsKeyDown(ImGuiKey_Q))
|
||||
ctx.quit = true;
|
||||
|
||||
|
@ -600,7 +633,7 @@ int doom_controller_loop(ControllerContext &ctx)
|
|||
if (ImGui::IsKeyDown(ImGuiKey_G))
|
||||
ctx.offsetX = ctx.offsetY = 0;
|
||||
|
||||
// fullscreen toggle
|
||||
// Alt-Enter fullscreen toggle
|
||||
if (io.KeyAlt && ImGui::IsKeyPressed(ImGuiKey_Enter, false))
|
||||
{
|
||||
u32 flag = (ctx.isFullscreen ? 0 : SDL_WINDOW_FULLSCREEN_DESKTOP);
|
||||
|
@ -608,16 +641,22 @@ int doom_controller_loop(ControllerContext &ctx)
|
|||
ctx.isFullscreen = !ctx.isFullscreen;
|
||||
}
|
||||
|
||||
// F10 to toggle ImGui visibility (skips the call to run_ui() if true)
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_F10, false))
|
||||
{
|
||||
ctx.uiVisible = !ctx.uiVisible;
|
||||
// FIXME: sadly this has issues: after toggling the ui off and
|
||||
// on again the mouse cursor is invisible. Even using
|
||||
// SDL_ShowCursor() unconditionally did not fix it. I suspect
|
||||
// it's caused by some interaction between SLD and ImGui.
|
||||
// it's caused by some interaction between SDL and ImGui.
|
||||
//if (SDL_SetRelativeMouseMode(ctx.uiVisible ? SDL_TRUE : SDL_FALSE) < 0)
|
||||
// log_warn("SDL_SetRelativeMouseMode: %s", SDL_GetError());
|
||||
}
|
||||
|
||||
// Ctrl-A to toggle sending input events to dooms.
|
||||
if (io.KeyCtrl && ImGui::IsKeyPressed(ImGuiKey_A, false))
|
||||
ctx.publishInputsMode = !ctx.publishInputsMode;
|
||||
|
||||
}
|
||||
|
||||
static ImVec2 panStartPos;
|
||||
|
@ -734,6 +773,8 @@ int main(int argc, char *argv[])
|
|||
ctx.sub = make_ctrl_sub(DoomUrlIpc);
|
||||
ctx.window = window;
|
||||
ctx.renderer = renderer;
|
||||
ctx.inputs.head.msgType = DP_MT_Inputs;
|
||||
ctx.inputs.eventCount = 0;
|
||||
|
||||
log_add_callback(log_to_imgui, &ctx, LOG_DEBUG);
|
||||
|
||||
|
|
|
@ -42,6 +42,13 @@
|
|||
#include <nng/protocol/pubsub0/sub.h>
|
||||
#include <dp_common.h>
|
||||
#include <unistd.h>
|
||||
#include <SDL.h>
|
||||
|
||||
_Static_assert(sizeof(event_t) == sizeof(dp_doom_event_t),
|
||||
"Size mismatch between dooms event_t and doompannings dp_doom_event_t. Packing?");
|
||||
|
||||
_Static_assert(MAXEVENTS == DoomMaxEvents,
|
||||
"MAXEVENTS (from d_event.h) and DoomMaxEvents (from dp_common.h) are not equal!");
|
||||
|
||||
typedef struct DoomContext DoomContext;
|
||||
|
||||
|
@ -208,11 +215,6 @@ void IB_StartTic (void)
|
|||
event.data1 = xlatekey(sdl_event.key.keysym.sym);
|
||||
D_PostEvent(&event);
|
||||
*/
|
||||
_Static_assert(sizeof(event_t) == sizeof(dp_doom_event_t),
|
||||
"Size mismatch between dooms event_t and doompannings dp_doom_event_t. Packing?");
|
||||
event_t event;
|
||||
static int button_state;
|
||||
//SDL_Event sdl_event;
|
||||
}
|
||||
|
||||
void IB_GetFramebuffer(unsigned char **pixels, size_t *pitch)
|
||||
|
@ -227,14 +229,22 @@ void IB_FinishUpdate (void)
|
|||
|
||||
assert(ctx->state == DP_DS_Running);
|
||||
|
||||
static const u64 MaxReceiveTime_ms = 10;
|
||||
u64 tStart = SDL_GetTicks64();
|
||||
|
||||
while (true)
|
||||
{
|
||||
int res = 0;
|
||||
nng_msg *msg = NULL;
|
||||
|
||||
if (SDL_GetTicks64() - tStart >= MaxReceiveTime_ms)
|
||||
break;
|
||||
|
||||
if ((res = dp_recv_new_msg_nonblock(ctx->sub, &msg)))
|
||||
{
|
||||
if (!dp_nng_is_timeout(res))
|
||||
dp_nng_fatal("doom/recvmsg", res);
|
||||
break; // timeout
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -254,6 +264,16 @@ void IB_FinishUpdate (void)
|
|||
MsgMcstCommand *msgCmd = DP_NNG_BODY_AS(msg, MsgMcstCommand);
|
||||
cmd = msgCmd->cmd;
|
||||
}
|
||||
else if (msgBase->msgType == DP_MT_Inputs)
|
||||
{
|
||||
MsgInputs *msgInputs = DP_NNG_BODY_AS(msg, MsgInputs);
|
||||
for (unsigned eventIndex=0; eventIndex<msgInputs->eventCount; ++eventIndex)
|
||||
{
|
||||
// Can do this cast. _Static_assert() at the top gives a bit
|
||||
// of ensurance.
|
||||
D_PostEvent((event_t *) msgInputs->events + eventIndex);
|
||||
}
|
||||
}
|
||||
|
||||
nng_msg_free(msg);
|
||||
|
||||
|
|
Loading…
Reference in a new issue