Weapon selection wheel, activated by touching the thumbrest

This commit is contained in:
Fighterguard 2024-10-17 22:28:22 +02:00
parent 40cf552716
commit 523f8d4aed
4 changed files with 370 additions and 78 deletions

View file

@ -21,6 +21,12 @@ Authors : Simon Brown
extern cvar_t *cl_forwardspeed;
cvar_t *sv_cheats;
extern cvar_t *vr_weapon_stabilised;
qboolean draw_wep_wheel;
vec3_t initialAngles;
vec3_t currentAngles;
vec2_t relativeAngles;
vec2_t polarCursor;
int segment;
@ -41,6 +47,10 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew,
uint32_t primaryButtonsOld;
uint32_t secondaryButtonsNew;
uint32_t secondaryButtonsOld;
uint32_t primaryTouchesNew;
uint32_t primaryTouchesOld;
uint32_t secondaryTouchesNew;
uint32_t secondaryTouchesOld;
int primaryButton1;
int primaryButton2;
int secondaryButton1;
@ -58,6 +68,12 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew,
secondaryButtonsNew = pDominantTrackedRemoteNew->Buttons;
secondaryButtonsOld = pDominantTrackedRemoteOld->Buttons;
primaryTouchesNew = pDominantTrackedRemoteNew->Touches;
primaryTouchesOld = pDominantTrackedRemoteOld->Touches;
secondaryTouchesNew = pOffTrackedRemoteNew->Touches;
secondaryTouchesOld = pOffTrackedRemoteOld->Touches;
primaryButton1 = offButton1;
primaryButton2 = offButton2;
secondaryButton1 = domButton1;
@ -75,6 +91,12 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew,
secondaryButtonsNew = pOffTrackedRemoteNew->Buttons;
secondaryButtonsOld = pOffTrackedRemoteOld->Buttons;
primaryTouchesNew = pDominantTrackedRemoteNew->Touches;
primaryTouchesOld = pDominantTrackedRemoteOld->Touches;
secondaryTouchesNew = pOffTrackedRemoteNew->Touches;
secondaryTouchesOld = pOffTrackedRemoteOld->Touches;
primaryButton1 = domButton1;
primaryButton2 = domButton2;
secondaryButton1 = offButton1;
@ -201,6 +223,72 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew,
sendButtonActionSimple("inven");
inventoryManagementMode = (secondaryButtonsNew & secondaryButton2) > 0;
}
if ((primaryTouchesNew & ovrTouch_ThumbRest) !=
(primaryTouchesOld & ovrTouch_ThumbRest)) {
sendButtonActionSimple("inven"); // send the "inven" command to force cl.inventory to be populated
}
// weapon selection wheel
{
static qboolean touching = false;
static qboolean runTouchLogic = false;
static int t_rel_t;
if ((primaryTouchesNew & ovrTouch_ThumbRest)) {
if (!touching) {
draw_wep_wheel = true;
QuatToYawPitchRoll(pDominantTracking->HeadPose.Pose.Orientation, 0.0f,
initialAngles);
VectorCopy(initialAngles, relativeAngles);
touching = true;
} else {
QuatToYawPitchRoll(pDominantTracking->HeadPose.Pose.Orientation, 0.0f,
currentAngles);
relativeAngles[0] = initialAngles[1] -
currentAngles[1]; // relative x -> pitch | Inverted to make right = positive
relativeAngles[1] = currentAngles[0] -
initialAngles[0]; // relative y -> yaw | to match display coordinates, down = positive
polarCursor[0] = sqrtf(
powf(relativeAngles[0], 2.0f) + powf(relativeAngles[1], 2.0f)); // r
if (polarCursor[0] > 15)
polarCursor[0] = 15; // to keep it within the ring
polarCursor[1] = atan2f(relativeAngles[1], relativeAngles[0]); // theta
segment = (int) (((polarCursor[1] + (M_PI / 11)) + (2.5 * M_PI)) *
(11 / (2 * M_PI))) %
11; // Top segment index = 0, clockwise up to 10
/*float th = M_PI/-2;
int r = 160;
float factor = M_PI * 2/11;
for(int i = 0; i < 11; i++){
int x, y;
x = r * cosf(th + (i * factor));
y = r * sinf(th + (i * factor));
ALOGV(" segment %i: x: %i y=%i", i, x, y);
}*/ // this snippet generated precalculated coordinates for each weapon icon, relative to the ring center
// I'll leave it here in case those values need to be calculated again
}
} else {
if(touching){
touching = false;
runTouchLogic = true;
t_rel_t = Sys_Milliseconds();
if (polarCursor[0] > 8) {
char useCom[50];
sprintf(useCom, "use %s", weaponIcons[segment].command);
sendButtonActionSimple(useCom);
}
}
// give it time for the "inven" commmand to be sent,
// preventing the "invisible" inventory window to be shown for a little bit
if(runTouchLogic && Sys_Milliseconds() - t_rel_t > 100) {
draw_wep_wheel = false;
runTouchLogic = false;
}
}
}
}
float controllerYawHeading = 0.0f;

View file

@ -26,6 +26,8 @@
#include "header/client.h"
extern qboolean draw_wep_wheel;
void
CL_ParseInventory(void)
{
@ -62,103 +64,103 @@ SetStringHighBit(char *s)
void
CL_DrawInventory(float separation)
{
int i, j;
int num, selected_num, item;
int index[MAX_ITEMS];
char string[1024];
int x, y;
char binding[1024];
const char *bind;
int selected;
int top;
if(!draw_wep_wheel) { // do not draw if weapon wheel is being drawn
Com_Printf("qiqiqiqi inventory drawn at %i", Sys_Milliseconds());
int i, j;
int num, selected_num, item;
int index[MAX_ITEMS];
char string[1024];
int x, y;
char binding[1024];
const char *bind;
int selected;
int top;
selected = cl.frame.playerstate.stats[STAT_SELECTED_ITEM];
selected = cl.frame.playerstate.stats[STAT_SELECTED_ITEM];
int offset_stereo= (separation>0) ? -25 : 25;
num = 0;
selected_num = 0;
int offset_stereo = (separation > 0) ? -25 : 25;
num = 0;
selected_num = 0;
float scale = SCR_GetHUDScale();
float scale = SCR_GetHUDScale();
for (i = 0; i < MAX_ITEMS; i++)
{
if (i == selected)
{
selected_num = num;
}
for (i = 0; i < MAX_ITEMS; i++)
{
if (i == selected) {
selected_num = num;
}
if (cl.inventory[i])
{
index[num] = i;
num++;
}
}
if (cl.inventory[i]) {
index[num] = i;
num++;
}
}
/* determine scroll point */
top = selected_num - DISPLAY_ITEMS / 2;
/* determine scroll point */
top = selected_num - DISPLAY_ITEMS / 2;
if (num - top < DISPLAY_ITEMS)
{
top = num - DISPLAY_ITEMS;
}
if (num - top < DISPLAY_ITEMS)
{
top = num - DISPLAY_ITEMS;
}
if (top < 0)
{
top = 0;
}
if (top < 0)
{
top = 0;
}
x = (viddef.width - scale*256) / 2;
y = viddef.height/2;
x = (viddef.width - scale * 256) / 2;
y = viddef.height / 2;
/* repaint everything next frame */
SCR_DirtyScreen();
/* repaint everything next frame */
SCR_DirtyScreen();
Draw_PicScaled(x+offset_stereo, y + scale*8, "inventory", scale);
Draw_PicScaled(x + offset_stereo, y + scale * 8, "inventory", scale);
y += scale*24;
x += scale*24;
y += scale * 24;
x += scale * 24;
//Inv_DrawStringScaled(x, y, "hotkey ### item", scale);
//Inv_DrawStringScaled(x, y + scale*8, "------ --- ----", scale);
//Inv_DrawStringScaled(x, y, "hotkey ### item", scale);
//Inv_DrawStringScaled(x, y + scale*8, "------ --- ----", scale);
y += scale*16;
y += scale * 16;
for (i = top; i < num && i < top + DISPLAY_ITEMS; i++)
{
item = index[i];
/* search for a binding */
Com_sprintf(binding, sizeof(binding), "use %s",
cl.configstrings[CS_ITEMS + item]);
bind = "";
for (i = top; i < num && i < top + DISPLAY_ITEMS; i++)
{
item = index[i];
/* search for a binding */
Com_sprintf(binding, sizeof(binding), "use %s",
cl.configstrings[CS_ITEMS + item]);
bind = "";
/*for (j = 0; j < 256; j++)
{
if (keybindings[j] && !Q_stricmp(keybindings[j], binding))
{
bind = Key_KeynumToString(j);
break;
}
}*/
/*for (j = 0; j < 256; j++)
{
if (keybindings[j] && !Q_stricmp(keybindings[j], binding))
{
bind = Key_KeynumToString(j);
break;
}
}*/
Com_sprintf(string, sizeof(string), "%6s %3i %s", bind,
cl.inventory[item], cl.configstrings[CS_ITEMS + item]);
Com_sprintf(string, sizeof(string), "%6s %3i %s", bind,
cl.inventory[item], cl.configstrings[CS_ITEMS + item]);
if (item != selected)
{
SetStringHighBit(string);
}
else
{
/* draw a blinky cursor by the selected item */
if ((int)(cls.realtime * 10) & 1)
{
Draw_CharScaled(x + offset_stereo - scale*8, y, 15, scale);
}
}
if (item != selected)
{
SetStringHighBit(string);
}
else
{
/* draw a blinky cursor by the selected item */
if ((int) (cls.realtime * 10) & 1) {
Draw_CharScaled(x + offset_stereo - scale * 8, y, 15, scale);
}
}
Inv_DrawStringScaled(x+offset_stereo, y, string, scale);
Inv_DrawStringScaled(x + offset_stereo, y, string, scale);
y += scale*8;
}
y += scale * 8;
}
}
}

View file

@ -72,6 +72,108 @@ extern cvar_t *crosshair_scale;
void SCR_TimeRefresh_f(void);
void SCR_Loading_f(void);
wheel_icon_t weaponIcons[11] = {
{
"blaster",
7,
"Blaster",
NULL,
0,
0,
-160
},
{
"shotgun",
8,
"Shotgun",
"shells",
18,
86,
-134
},
{
"sshotgun",
9,
"Super Shotgun",
"shells",
18,
145,
-66
},
{
"machinegun",
10,
"Machinegun",
"bullets",
19,
158,
22
},
{
"chaingun",
11,
"Chaingun",
"bullets",
19,
120,
104
},
{
"grenades",
12,
"Grenades",
"grenades",
12,
45,
153
},
{
"glauncher",
13,
"Grenade Launcher",
"grenades",
12,
-45,
153
},
{
"rlauncher",
14,
"Rocket Launcher",
"rockets",
21,
-120,
104
},
{
"hyperblaster",
15,
"HyperBlaster",
"cells",
20,
-158,
22
},
{
"railgun",
16,
"Railgun",
"slugs",
22,
-145,
-66
},
{
"bfg",
17,
"BFG10K",
"cells",
20,
-86,
-134
}
};
/*
* A new packet was just parsed
*/
@ -516,6 +618,91 @@ void SCR_DrawVignette (void)
}
}
extern qboolean draw_wep_wheel;
extern vec2_t polarCursor;
extern int segment;
static float cursorFactor = 200/15; // 200 is the radius of the ring image
// 15 is the same radius in VR scale
void
DrawNumberCenteredImageScaled(int x, int y, char* num, float scale)
{
int len = strlen(num);
int width = 8; // half of img width
int height = 12; // half of img height
for(int i = 0; i < len; i++){
char image[7];
sprintf(image, "anum_%c", num[i]);
float offset = width * ((i * 2) - (len));
Draw_PicScaled(x + offset, y - (height * scale), image,
scale);
}
}
void
SCR_DrawWeaponWheel (float separation)
{
if(draw_wep_wheel)
{
int offset_stereo = (separation>0) ? -25 : 25;
int picw, pich;
int curw, curh;
int vidwc = (viddef.width/2);
int vidhc = (viddef.height/2);
Draw_GetPicSize(&picw, &pich,"/ring.png");
Draw_PicScaled((vidwc - (picw/2)) + offset_stereo, (vidhc - (pich/2)), "/ring.png", 1.0f);
Draw_GetPicSize(&curw, &curh,"/cursor.png");
Draw_PicScaled((vidwc - (curw/2)) + ((polarCursor[0] * cosf(polarCursor[1])) * cursorFactor) + offset_stereo,
(vidwc - (curh/2)) + ((polarCursor[0] * sinf(polarCursor[1])) * cursorFactor),
"/cursor.png", 1.0f);
for(int i = 0; i < 11; i++)
{
if(cl.inventory[weaponIcons[i].index])
{ // if weapon is available in inventory
char iconName[35];
char ammoName[30];
char ammoAmount[4];
float iconFactor;
float ammoFactor = 4.0f;
int iconWidth = 12; // actually half of icon size. For centering purposes
if (i == segment && polarCursor[0] > 8)
{ // if cursor is inside the segment corresponding to the weapon
iconFactor = 2.5f;
sprintf(iconName, "/wheel/w_%s_selected.png", weaponIcons[i].name);
sprintf(ammoName, "/wheel/a_%s.png", weaponIcons[i].ammo);
DrawStringScaled(vidwc + offset_stereo - (strlen(weaponIcons[i].command) * 4),
vidhc - 100,
weaponIcons[i].command, 1.0f); // Weapon name
if(weaponIcons[i].ammo_i > 0)
{
sprintf(ammoAmount, "%i", cl.inventory[weaponIcons[i].ammo_i]);
DrawNumberCenteredImageScaled(vidwc + offset_stereo, vidhc + 100,
ammoAmount,
1.0f); // ammo amount in image numbers
}
Draw_PicScaled(vidwc - (iconWidth * ammoFactor) + offset_stereo, // ammo icon for the weapon
vidhc - (iconWidth * ammoFactor), ammoName,
ammoFactor);
Draw_PicScaled(vidwc + weaponIcons[i].x - (iconWidth * iconFactor) +
(offset_stereo * 1.3f),
vidhc + weaponIcons[i].y - (iconWidth * iconFactor), iconName,
iconFactor);
}
else
{
iconFactor = 1.5f;
sprintf(iconName, "/wheel/w_%s.png", weaponIcons[i].name);
Draw_PicScaled(vidwc + weaponIcons[i].x - (iconWidth * iconFactor) + (offset_stereo),
vidhc + weaponIcons[i].y - (iconWidth * iconFactor), iconName,
iconFactor);
}
}
}
}
}
void
SCR_DrawLoading(void)
{
@ -1647,6 +1834,8 @@ void SCR_UpdateForEye (int eye)
CL_DrawInventory(separation);
}
SCR_DrawWeaponWheel(separation);
SCR_DrawNet();
SCR_CheckDrawCenterString();

View file

@ -319,6 +319,19 @@ extern entity_state_t cl_parse_entities[MAX_PARSE_ENTITIES];
extern netadr_t net_from;
extern sizebuf_t net_message;
typedef struct
{
const char* name; // segment for matching icon file
const int index; // weapon index in inventory
const char* command; // command triggered when icon is selected. Also display name
const char* ammo; // type of ammo used by this weapon
const int ammo_i; // index of ammo amount in inventory
const int x; // h offset from center of selection wheel
const int y; // v offset from center of selection wheel
} wheel_icon_t;
extern wheel_icon_t weaponIcons[];
void DrawString (int x, int y, char *s);
void DrawStringScaled(int x, int y, char *s, float factor);
void DrawAltString (int x, int y, char *s); /* toggle high bit */