From 15dbe443b0924ecf18de0b37e4ea0a02130eebaa Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 18 Nov 2021 15:27:44 +0900 Subject: [PATCH] [nq] Hook up the new input and config systems This gets nq in line with qw (and highlights more places than need merging, *sigh*) --- nq/include/client.h | 4 +- nq/source/cl_input.c | 106 +++++++++++++++++++++++++++++++++++++------ nq/source/cl_main.c | 50 ++++++++++++++++---- nq/source/host.c | 32 ++++++++++--- nq/source/sv_ded.c | 6 +++ 5 files changed, 168 insertions(+), 30 deletions(-) diff --git a/nq/include/client.h b/nq/include/client.h index 6c10ef375..4a35a3770 100644 --- a/nq/include/client.h +++ b/nq/include/client.h @@ -284,6 +284,7 @@ struct cbuf_s; void CL_Init (struct cbuf_s *cbuf); void CL_InitCvars (void); void CL_ClearMemory (void); +int CL_ReadConfiguration (const char *cfg_name); void CL_EstablishConnection (const char *host); void CL_Signon1 (void); @@ -297,7 +298,8 @@ void CL_NextDemo (void); // cl_input -void CL_Input_Init (void); +void CL_Input_Init (struct cbuf_s *cbuf); +void CL_Input_Activate (void); void CL_SendCmd (void); void CL_SendMove (usercmd_t *cmd); diff --git a/nq/source/cl_input.c b/nq/source/cl_input.c index 3f22eafee..021b73bed 100644 --- a/nq/source/cl_input.c +++ b/nq/source/cl_input.c @@ -36,12 +36,14 @@ #endif #include "QF/cmd.h" +#include "QF/console.h" #include "QF/cvar.h" #include "QF/input.h" #include "QF/keys.h" #include "QF/msg.h" #include "QF/sys.h" +#include "QF/input/event.h" #include "QF/plugin/vid_render.h" #include "compat.h" @@ -50,6 +52,42 @@ #include "nq/include/client.h" #include "nq/include/host.h" +int cl_game_context; +int cl_demo_context; +static int cl_event_id; + +in_axis_t viewdelta_position_forward = { + .mode = ina_accumulate, + .name = "move.forward", + .description = "Move forward (negative) or backward (positive)", +}; +in_axis_t viewdelta_position_side = { + .mode = ina_accumulate, + .name = "move.side", + .description = "Move right (positive) or left (negative)", +}; +in_axis_t viewdelta_position_up = { + .mode = ina_accumulate, + .name = "move.up", + .description = "Move up (positive) or down (negative)", +}; + +in_axis_t viewdelta_angles_pitch = { + .mode = ina_accumulate, + .name = "move.pitch", + .description = "Pitch axis", +}; +in_axis_t viewdelta_angles_yaw = { + .mode = ina_accumulate, + .name = "move.yaw", + .description = "Yaw axis", +}; +in_axis_t viewdelta_angles_roll = { + .mode = ina_accumulate, + .name = "move.roll", + .description = "Roll axis", +}; + in_button_t in_left = { .name = "left", .description = "When active the player is turning left" @@ -124,6 +162,16 @@ in_button_t in_mlook = { "+lookdown" }; +static in_axis_t *cl_in_axes[] = { + &viewdelta_position_forward, + &viewdelta_position_side, + &viewdelta_position_up, + &viewdelta_angles_pitch, + &viewdelta_angles_yaw, + &viewdelta_angles_roll, + 0, +}; + static in_button_t *cl_in_buttons[] = { &in_left, &in_right, @@ -269,11 +317,6 @@ CL_BaseMove (usercmd_t *cmd) if (freelook) V_StopPitchDrift (); - viewdelta.angles[0] = viewdelta.angles[1] = viewdelta.angles[2] = 0; - viewdelta.position[0] = viewdelta.position[1] = viewdelta.position[2] = 0; - - IN_Move (); - // adjust for chase camera angles /*FIXME:chase figure out just what this does and get it working if (cl.chase @@ -294,12 +337,19 @@ CL_BaseMove (usercmd_t *cmd) } */ - cmd->forwardmove += viewdelta.position[2] * m_forward->value; - cmd->sidemove += viewdelta.position[0] * m_side->value; - cmd->upmove += viewdelta.position[1]; - cl.viewstate.angles[PITCH] += viewdelta.angles[PITCH] * m_pitch->value; - cl.viewstate.angles[YAW] += viewdelta.angles[YAW] * m_yaw->value; - cl.viewstate.angles[ROLL] += viewdelta.angles[ROLL]; + cmd->forwardmove -= viewdelta_position_forward.value * m_forward->value; + cmd->sidemove += viewdelta_position_side.value * m_side->value; + cmd->upmove -= viewdelta_position_up.value; + cl.viewstate.angles[PITCH] -= viewdelta_angles_pitch.value * m_pitch->value; + cl.viewstate.angles[YAW] -= viewdelta_angles_yaw.value * m_yaw->value; + cl.viewstate.angles[ROLL] -= viewdelta_angles_roll.value * m_pitch->value; + + viewdelta_angles_pitch.value = 0; + viewdelta_angles_yaw.value = 0; + viewdelta_angles_roll.value = 0; + viewdelta_position_forward.value = 0; + viewdelta_position_side.value = 0; + viewdelta_position_up.value = 0; if (freelook && !(in_strafe.state & inb_down)) { cl.viewstate.angles[PITCH] @@ -359,12 +409,42 @@ CL_SendMove (usercmd_t *cmd) } } -void -CL_Input_Init (void) +static int +cl_event_handler (const IE_event_t *ie_event, void *unused) { + if (ie_event->type == ie_key) { + if (ie_event->key.code == QFK_ESCAPE) { + // FIXME this should bring up the menu + Con_SetState (con_active); + return 1; + } + } + return IN_Binding_HandleEvent (ie_event); +} + +void +CL_Input_Init (cbuf_t *cbuf) +{ + cl_event_id = IE_Add_Handler (cl_event_handler, 0); + + for (int i = 0; cl_in_axes[i]; i++) { + IN_RegisterAxis (cl_in_axes[i]); + } for (int i = 0; cl_in_buttons[i]; i++) { IN_RegisterButton (cl_in_buttons[i]); } + cl_game_context = IMT_CreateContext ("key_game"); + IMT_SetContextCbuf (cl_game_context, cbuf); + cl_demo_context = IMT_CreateContext ("key_demo"); + IMT_SetContextCbuf (cl_demo_context, cbuf); Cmd_AddDataCommand ("impulse", IN_Impulse, 0, "Call a game function or QuakeC function."); } + +void +CL_Input_Activate (void) +{ + host_in_game = 1; + IMT_SetContext (cl_game_context); + IE_Set_Focus (cl_event_id); +} diff --git a/nq/source/cl_main.c b/nq/source/cl_main.c index c1c879cac..865da8507 100644 --- a/nq/source/cl_main.c +++ b/nq/source/cl_main.c @@ -106,21 +106,50 @@ CL_WriteConfiguration (void) // dedicated servers initialize the host but don't parse and set the // config.cfg cvars if (host_initialized && !isDedicated && cl_writecfg->int_val) { + plitem_t *config = PL_NewDictionary (0); //FIXME hashlinks + Cvar_SaveConfig (config); + IN_SaveConfig (config); + const char *path = va (0, "%s/quakeforge.cfg", qfs_gamedir->dir.def); QFile *f = QFS_WOpen (path, 0); if (!f) { Sys_Printf ("Couldn't write quakeforge.cfg.\n"); - return; + } else { + char *cfg = PL_WritePropertyList (config); + Qputs (f, cfg); + free (cfg); + Qclose (f); } - - //Key_WriteBindings (f); - Cvar_WriteVariables (f); - - Qclose (f); + PL_Free (config); } } +int +CL_ReadConfiguration (const char *cfg_name) +{ + QFile *cfg_file = QFS_FOpenFile (cfg_name); + if (!cfg_file) { + return 0; + } + size_t len = Qfilesize (cfg_file); + char *cfg = malloc (len + 1); + Qread (cfg_file, cfg, len); + cfg[len] = 0; + Qclose (cfg_file); + + plitem_t *config = PL_GetPropertyList (cfg, 0); // FIXME hashlinks + if (!config) { + return 0; + } + + Cvar_LoadConfig (config); + IN_LoadConfig (config); + + PL_Free (config); + return 1; +} + static void CL_Shutdown (void *data) { @@ -527,8 +556,11 @@ CL_SetState (cactive_t state) } CL_UpdateScreen (cl.time); } - if (con_module) - con_module->data->console->force_commandline = (state < ca_connected); + host_in_game = 0; + Con_SetState (state == ca_active ? con_inactive : con_fullscreen); + if (state != old_state && state == ca_active) { + CL_Input_Activate (); + } } static void @@ -566,7 +598,7 @@ CL_Init (cbuf_t *cbuf) Sbar_Init (); - CL_Input_Init (); + CL_Input_Init (cbuf); CL_TEnts_Init (); CL_ClearState (); diff --git a/nq/source/host.c b/nq/source/host.c index 2128e7f74..d4d33e10c 100644 --- a/nq/source/host.c +++ b/nq/source/host.c @@ -847,13 +847,33 @@ Host_Init_Memory (void) Sys_Printf ("%4.1f megabyte heap\n", host_mem_size->value); } -#if 0 + static void -host_keydest_callback (keydest_t kd, void *data) +Host_ExecConfig (cbuf_t *cbuf, int skip_quakerc) { - host_in_game = kd == key_game; + // quakeforge.cfg overrides quake.rc as it contains quakeforge-specific + // commands. If it doesn't exist, then this is the first time quakeforge + // has been used in this installation, thus any existing legacy config + // should be used to set up defaults on the assumption that the user has + // things set up to work with another (hopefully compatible) client + if (CL_ReadConfiguration ("quakeforge.cfg")) { + Cmd_Exec_File (cbuf, fs_usercfg->string, 0); + Cmd_StuffCmds (cbuf); + COM_Check_quakerc ("startdemos", cbuf); + } else { + if (!skip_quakerc) { + Cbuf_InsertText (cbuf, "exec quake.rc\n"); + } + Cmd_Exec_File (cbuf, fs_usercfg->string, 0); + // Reparse the command line for + commands. + // (sets still done, but it doesn't matter) + // (Note, no non-base commands exist yet) + if (skip_quakerc || !COM_Check_quakerc ("stuffcmds", 0)) { + Cmd_StuffCmds (cbuf); + } + } } -#endif + void Host_Init (void) { @@ -888,8 +908,6 @@ Host_Init (void) Mod_Init (); - //Key_KeydestCallback (host_keydest_callback, 0); - SV_Init (); if (cls.state != ca_dedicated) @@ -905,7 +923,7 @@ Host_Init (void) CL_UpdateScreen (cl.time); CL_UpdateScreen (cl.time); - COM_ExecConfig (host_cbuf, isDedicated || !cl_quakerc->int_val); + Host_ExecConfig (host_cbuf, isDedicated || !cl_quakerc->int_val); Hunk_AllocName (0, 0, "-HOST_HUNKLEVEL-"); host_hunklevel = Hunk_LowMark (0); diff --git a/nq/source/sv_ded.c b/nq/source/sv_ded.c index 6a854084a..80eefe3ec 100644 --- a/nq/source/sv_ded.c +++ b/nq/source/sv_ded.c @@ -118,6 +118,12 @@ CL_NextDemo (void) { } +__attribute__((const)) int +CL_ReadConfiguration (const char *cfg_name) +{ + return 0; +} + __attribute__((const)) int CL_ReadFromServer (void) {