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 <sys/wait.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "dp_common.h"
|
|
||||||
#include "dp_util.hpp"
|
#include "dp_util.hpp"
|
||||||
|
#include "doomlib.hpp"
|
||||||
|
|
||||||
#if DoomBytesPerPixel == 3
|
#if DoomBytesPerPixel == 3
|
||||||
// FIXME: don't use, it's buggy
|
// FIXME: don't use, it's buggy
|
||||||
|
@ -96,6 +96,8 @@ struct ControllerContext
|
||||||
bool isMousePanning = false;
|
bool isMousePanning = false;
|
||||||
bool isFullscreen = false;
|
bool isFullscreen = false;
|
||||||
bool uiVisible = true;
|
bool uiVisible = true;
|
||||||
|
bool publishInputsMode = false;
|
||||||
|
MsgInputs inputs;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ControllerActions
|
struct ControllerActions
|
||||||
|
@ -221,7 +223,7 @@ void check_on_dooms(ControllerContext &ctx)
|
||||||
|
|
||||||
void do_networking(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.
|
// a single DP_DC_RunDoom command is broadcast.
|
||||||
bool sendRunDoom = false;
|
bool sendRunDoom = false;
|
||||||
|
|
||||||
|
@ -390,6 +392,21 @@ void do_networking(ControllerContext &ctx)
|
||||||
if ((res = nng_sendmsg(ctx.pub, msg, 0)))
|
if ((res = nng_sendmsg(ctx.pub, msg, 0)))
|
||||||
dp_nng_fatal("ctrl/sendmsg", res);
|
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)
|
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)
|
void render_dooms(ControllerContext &ctx)
|
||||||
{
|
{
|
||||||
SDL_Rect destRect = { ctx.offsetX, ctx.offsetY, DoomScreenWidth, DoomScreenHeight };
|
SDL_Rect destRect = { ctx.offsetX, ctx.offsetY, DoomScreenWidth, DoomScreenHeight };
|
||||||
|
@ -493,6 +517,8 @@ ControllerActions run_ui(ControllerContext &ctx)
|
||||||
{
|
{
|
||||||
if (ImGui::BeginMenu("Menu"))
|
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::MenuItem("Quit", "Ctrl+Q", &ctx.quit, true);
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
|
@ -568,6 +594,12 @@ int doom_controller_loop(ControllerContext &ctx)
|
||||||
|
|
||||||
if (event.type == SDL_MOUSEWHEEL)
|
if (event.type == SDL_MOUSEWHEEL)
|
||||||
mouseWheel += event.wheel.y;
|
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
|
// Process input events not consumed by ImGui
|
||||||
|
@ -577,6 +609,7 @@ int doom_controller_loop(ControllerContext &ctx)
|
||||||
static const float ScaleStep = 0.01f;
|
static const float ScaleStep = 0.01f;
|
||||||
s32 PanStep = io.KeyCtrl ? 10 : 2;
|
s32 PanStep = io.KeyCtrl ? 10 : 2;
|
||||||
|
|
||||||
|
// Ctrl-Q to quit
|
||||||
if (io.KeyCtrl && ImGui::IsKeyDown(ImGuiKey_Q))
|
if (io.KeyCtrl && ImGui::IsKeyDown(ImGuiKey_Q))
|
||||||
ctx.quit = true;
|
ctx.quit = true;
|
||||||
|
|
||||||
|
@ -600,7 +633,7 @@ int doom_controller_loop(ControllerContext &ctx)
|
||||||
if (ImGui::IsKeyDown(ImGuiKey_G))
|
if (ImGui::IsKeyDown(ImGuiKey_G))
|
||||||
ctx.offsetX = ctx.offsetY = 0;
|
ctx.offsetX = ctx.offsetY = 0;
|
||||||
|
|
||||||
// fullscreen toggle
|
// Alt-Enter fullscreen toggle
|
||||||
if (io.KeyAlt && ImGui::IsKeyPressed(ImGuiKey_Enter, false))
|
if (io.KeyAlt && ImGui::IsKeyPressed(ImGuiKey_Enter, false))
|
||||||
{
|
{
|
||||||
u32 flag = (ctx.isFullscreen ? 0 : SDL_WINDOW_FULLSCREEN_DESKTOP);
|
u32 flag = (ctx.isFullscreen ? 0 : SDL_WINDOW_FULLSCREEN_DESKTOP);
|
||||||
|
@ -608,16 +641,22 @@ int doom_controller_loop(ControllerContext &ctx)
|
||||||
ctx.isFullscreen = !ctx.isFullscreen;
|
ctx.isFullscreen = !ctx.isFullscreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// F10 to toggle ImGui visibility (skips the call to run_ui() if true)
|
||||||
if (ImGui::IsKeyPressed(ImGuiKey_F10, false))
|
if (ImGui::IsKeyPressed(ImGuiKey_F10, false))
|
||||||
{
|
{
|
||||||
ctx.uiVisible = !ctx.uiVisible;
|
ctx.uiVisible = !ctx.uiVisible;
|
||||||
// FIXME: sadly this has issues: after toggling the ui off and
|
// FIXME: sadly this has issues: after toggling the ui off and
|
||||||
// on again the mouse cursor is invisible. Even using
|
// on again the mouse cursor is invisible. Even using
|
||||||
// SDL_ShowCursor() unconditionally did not fix it. I suspect
|
// 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)
|
//if (SDL_SetRelativeMouseMode(ctx.uiVisible ? SDL_TRUE : SDL_FALSE) < 0)
|
||||||
// log_warn("SDL_SetRelativeMouseMode: %s", SDL_GetError());
|
// 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;
|
static ImVec2 panStartPos;
|
||||||
|
@ -734,6 +773,8 @@ int main(int argc, char *argv[])
|
||||||
ctx.sub = make_ctrl_sub(DoomUrlIpc);
|
ctx.sub = make_ctrl_sub(DoomUrlIpc);
|
||||||
ctx.window = window;
|
ctx.window = window;
|
||||||
ctx.renderer = renderer;
|
ctx.renderer = renderer;
|
||||||
|
ctx.inputs.head.msgType = DP_MT_Inputs;
|
||||||
|
ctx.inputs.eventCount = 0;
|
||||||
|
|
||||||
log_add_callback(log_to_imgui, &ctx, LOG_DEBUG);
|
log_add_callback(log_to_imgui, &ctx, LOG_DEBUG);
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,13 @@
|
||||||
#include <nng/protocol/pubsub0/sub.h>
|
#include <nng/protocol/pubsub0/sub.h>
|
||||||
#include <dp_common.h>
|
#include <dp_common.h>
|
||||||
#include <unistd.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;
|
typedef struct DoomContext DoomContext;
|
||||||
|
|
||||||
|
@ -208,11 +215,6 @@ void IB_StartTic (void)
|
||||||
event.data1 = xlatekey(sdl_event.key.keysym.sym);
|
event.data1 = xlatekey(sdl_event.key.keysym.sym);
|
||||||
D_PostEvent(&event);
|
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)
|
void IB_GetFramebuffer(unsigned char **pixels, size_t *pitch)
|
||||||
|
@ -227,14 +229,22 @@ void IB_FinishUpdate (void)
|
||||||
|
|
||||||
assert(ctx->state == DP_DS_Running);
|
assert(ctx->state == DP_DS_Running);
|
||||||
|
|
||||||
|
static const u64 MaxReceiveTime_ms = 10;
|
||||||
|
u64 tStart = SDL_GetTicks64();
|
||||||
|
|
||||||
|
while (true)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
nng_msg *msg = NULL;
|
nng_msg *msg = NULL;
|
||||||
|
|
||||||
|
if (SDL_GetTicks64() - tStart >= MaxReceiveTime_ms)
|
||||||
|
break;
|
||||||
|
|
||||||
if ((res = dp_recv_new_msg_nonblock(ctx->sub, &msg)))
|
if ((res = dp_recv_new_msg_nonblock(ctx->sub, &msg)))
|
||||||
{
|
{
|
||||||
if (!dp_nng_is_timeout(res))
|
if (!dp_nng_is_timeout(res))
|
||||||
dp_nng_fatal("doom/recvmsg", res);
|
dp_nng_fatal("doom/recvmsg", res);
|
||||||
|
break; // timeout
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -254,6 +264,16 @@ void IB_FinishUpdate (void)
|
||||||
MsgMcstCommand *msgCmd = DP_NNG_BODY_AS(msg, MsgMcstCommand);
|
MsgMcstCommand *msgCmd = DP_NNG_BODY_AS(msg, MsgMcstCommand);
|
||||||
cmd = msgCmd->cmd;
|
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);
|
nng_msg_free(msg);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue