mirror of
https://github.com/DrBeef/Quake2Quest.git
synced 2025-03-01 06:30:52 +00:00
Weapon selection wheel, activated by touching the thumbrest
This commit is contained in:
parent
40cf552716
commit
523f8d4aed
4 changed files with 370 additions and 78 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue