Compare commits

...

15 commits

Author SHA1 Message Date
Simon
b7aedfd0a3 Update run.bat 2022-05-22 10:21:22 +01:00
Simon
7f7a5476bc Update ui_credits.c 2022-05-22 10:19:16 +01:00
Simon
b9e0fa74ff Update ui_credits.c 2022-05-22 10:15:57 +01:00
Simon
d2787fbd4a Fixed incorrect credits 2022-05-21 20:58:58 +01:00
Simon
50d253fcdc Allow a Quest running the demo pak to connect to another quest server 2022-05-21 09:37:27 +01:00
Simon
4b46ae002f Ensure roll angles are passed to the server if enabled 2022-05-19 22:34:13 +01:00
Petr Bartos
4eca4349d3 Do not create missionpack folder if not installed 2022-05-19 19:31:30 +01:00
Petr Bartos
b80e8bb7b6 Delete obsolete glsl folder on startup 2022-05-19 19:31:30 +01:00
Simon
8ac0ee5af5 Grey out non-demo servers if playing with demo pak0
- don't allow players to even start a MP game on a non-demo server
- fixed the website url
- updated the message about the demo in the main menu
2022-05-19 19:10:38 +01:00
Simon
d628dadf76 Merge pull request #82 from petr666/master
Generate random suffix for default player name
2022-05-17 21:15:56 +01:00
Simon
913459e45a Change to multiplayer menu message
also disabled the "specify" button as it is useless in this port
2022-05-15 18:06:26 +01:00
Petr Bartos
0a9aa45479 Remap face buttons along with switching thumbsticks 2022-05-15 16:11:46 +01:00
Simon
4428ebe881 Support for ForeceTube/ProTube Stock
Also added f2hunter to the credits
2022-05-15 10:33:49 +01:00
Petr Bartos
d33e09733b Hardcode A to skip server search in menu instead of using moveup bind hack 2022-05-12 18:59:25 +01:00
Simon
667edf7b5d Update to RC3 2022-05-12 18:58:20 +01:00
18 changed files with 215 additions and 73 deletions

Binary file not shown.

View file

@ -2,8 +2,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.drbeef.ioq3quest"
android:installLocation="preferExternal"
android:versionCode="49"
android:versionName="0.31.4">
android:versionCode="55"
android:versionName="1.1.0">
<uses-feature android:name="android.hardware.vr.headtracking" android:version="1" android:required="true" />
<uses-feature android:glEsVersion="0x00030001" />
<!-- <uses-feature android:name="oculus.software.overlay_keyboard" android:required="false"/>-->

View file

@ -1318,6 +1318,10 @@ static void CG_LightningBolt( centity_t *cent, vec3_t origin ) {
vec3_t angle;
CG_CalculateVRWeaponPosition(muzzlePoint, angle);
AngleVectors(angle, forward, NULL, NULL );
//Handle this here so it is refreshed on every frame, not just when the lightning gun is first fired
int position = vr->weapon_stabilised ? 4 : (vr->right_handed ? 1 : 2);
trap_HapticEvent("RTCWQuest:fire_tesla", position, 0, 100, 0, 0);
} else {
// !CPMA
AngleVectors( cent->lerpAngles, forward, NULL, NULL );
@ -2529,7 +2533,7 @@ void CG_FireWeapon( centity_t *cent ) {
trap_HapticEvent("rocket_fire", position, 0, 100, 0, 0);
break;
case WP_LIGHTNING:
trap_HapticEvent("RTCWQuest:fire_tesla", position, 0, 100, 0, 0);
//Haptics handled in the CG_LightningBolt code
break;
case WP_RAILGUN:
trap_HapticEvent("RTCWQuest:fire_sniper", position, 0, 100, 0, 0);
@ -2543,7 +2547,7 @@ void CG_FireWeapon( centity_t *cent ) {
trap_HapticEvent("bfg_fire", position, 0, 100, 0, 0);
break;
case WP_GRAPPLING_HOOK:
trap_HapticEvent("chainsaw_fire", position, 0, 100, 0, 0);
//No Haptics
break;
#ifdef MISSIONPACK
case WP_NAILGUN:

View file

@ -620,6 +620,10 @@ void CL_FinishMove( usercmd_t *cmd ) {
{
angles[ROLL] = 0; // suppress roll
}
else
{
angles[ROLL] = vr.hmdorientation[ROLL];
}
for (i = 0; i < 3; i++) {
cmd->angles[i] = ANGLE2SHORT(angles[i]);

View file

@ -3622,7 +3622,12 @@ void CL_Init( void ) {
cl_consoleKeys = Cvar_Get( "cl_consoleKeys", "~ ` 0x7e 0x60", CVAR_ARCHIVE);
// userinfo
Cvar_Get ("name", "[VR] Player", CVAR_USERINFO | CVAR_ARCHIVE );
char playerName[256];
Com_sprintf(playerName, 256, "[VR] Player#%i", rand() % (99999999 - 10000000) + 10000000);
Cvar_Get ("name", playerName, CVAR_USERINFO | CVAR_ARCHIVE );
if (strcmp(Cvar_VariableString("name"), "[VR] Player") == 0) {
Cvar_Set( "name", playerName);
}
cl_rate = Cvar_Get ("rate", "25000", CVAR_USERINFO | CVAR_ARCHIVE );
Cvar_Get ("snaps", "40", CVAR_USERINFO | CVAR_ARCHIVE );
Cvar_Get ("model", "sarge", CVAR_USERINFO | CVAR_ARCHIVE );

View file

@ -213,6 +213,19 @@ static void Controls3_MenuEvent( void* ptr, int notification ) {
break;
case ID_SWITCHTHUMBSTICKS:
{
if (s_controls3.switchthumbsticks.curvalue) {
trap_Cvar_Set("vr_button_map_A", "+button2"); // Use Item
trap_Cvar_Set("vr_button_map_B", "+button3"); // Gesture
trap_Cvar_Set("vr_button_map_X", "+moveup"); // Jump
trap_Cvar_Set("vr_button_map_Y", "+movedown"); // Crouch
} else {
trap_Cvar_Set("vr_button_map_A", "+moveup"); // Jump
trap_Cvar_Set("vr_button_map_B", "+movedown"); // Crouch
trap_Cvar_Set("vr_button_map_X", "+button2"); // Use Item
trap_Cvar_Set("vr_button_map_Y", "+button3"); // Gesture
}
}
trap_Cvar_SetValue( "vr_switchThumbsticks", s_controls3.switchthumbsticks.curvalue );
break;

View file

@ -107,8 +107,8 @@ Additional Contributions
Bummser, Skillfur, Ceno, Cukier, Eispfogel, Pizzaluigi
Dedicated Beta Testers
XQuader, Ceno, Cukier, Bummser, Retro1N, Benny91, April, Ikarus,
Bim, Lubos, MasakaPete, Config2, Maniac, Ghostdog72, Slydog43,
f2hunter, XQuader, Ceno, Cukier, Bummser, Retro1N, Benny91, April, Ikarus,
GeTall, Lubos, MasakaPete, Config2, Maniac, Ghostdog72, Slydog43,
Cornelius, Ferret, RealityForge, PvtGenO, SatanSlayer
Special Thanks to the whole discord!
@ -145,11 +145,11 @@ Special Thanks to the whole discord!
y += 1.42 * PROP_HEIGHT * PROP_SMALL_SIZE_SCALE;
UI_DrawProportionalString( 320, y, "Dedicated Beta Testers", UI_CENTER|UI_SMALLFONT, color_red );
y += PROP_HEIGHT * PROP_SMALL_SIZE_SCALE;
UI_DrawString( 320, y, "XQuader, Ceno, Cukier, Bummser, Retro1N, Benny91, April, Ikarus,", UI_CENTER|UI_SMALLFONT, color_white );
UI_DrawString( 320, y, "f2hunter, XQuader, Ceno, Cukier, Bummser, Retro1N, Benny91, Ikarus,", UI_CENTER|UI_SMALLFONT, color_white );
y += PROP_HEIGHT * PROP_SMALL_SIZE_SCALE;
UI_DrawString( 320, y, "Bim, Lubos, MasakaPete, Config2, Maniac, Ghostdog72, Slydog43,", UI_CENTER|UI_SMALLFONT, color_white );
UI_DrawString( 320, y, "GeTall, Lubos, MasakaPete, Config2, Maniac, Ghostdog72, Slydog43,", UI_CENTER|UI_SMALLFONT, color_white );
y += PROP_HEIGHT * PROP_SMALL_SIZE_SCALE;
UI_DrawString( 320, y, "Cornelius, Ferret, RealityForge, PvtGenO, SatanSlayer", UI_CENTER|UI_SMALLFONT, color_white );
UI_DrawString( 320, y, "Myrothas, April, Cornelius, Ferret, RealityForge, PvtGenO, SatanSlayer", UI_CENTER|UI_SMALLFONT, color_white );
y += 1.42 * PROP_HEIGHT * PROP_SMALL_SIZE_SCALE;
UI_DrawProportionalString( 320, y, "Special Thanks to the whole Team Beef discord!", UI_CENTER|UI_SMALLFONT, color_red );
@ -163,7 +163,7 @@ Special Thanks to the whole discord!
UI_DrawProportionalString(320, y, "original ioquake3 contributors!", UI_CENTER | UI_SMALLFONT, color_orange);
}
UI_DrawString( 320, 459, "Quake3Quest: https://www.quake3.quakevr.com/", UI_CENTER|UI_SMALLFONT, color_red );
UI_DrawString( 320, 459, "Quake3Quest: https://quake3.quakevr.com/", UI_CENTER|UI_SMALLFONT, color_red );
}

View file

@ -229,7 +229,7 @@ static void Main_MenuDraw( void ) {
int yPos = 410;
if (uis.demoversion) {
yPos = 372;
UI_DrawString( 320, yPos, "Demo: Play the 1st tier of SP or MP on our demo servers", UI_CENTER|UI_SMALLFONT, color_white );
UI_DrawString( 320, yPos, "DEMO: You can only play on Demo-Servers and play first part of SP!", UI_CENTER|UI_SMALLFONT, color_white );
yPos += SMALLCHAR_HEIGHT;
UI_DrawString( 320, yPos, "Install full game for more!", UI_CENTER|UI_SMALLFONT, color_white );
yPos += SMALLCHAR_HEIGHT;

View file

@ -160,7 +160,7 @@ static char* netnames[] = {
NULL
};
static char quake3questMessage[] = "Visit quake3.quakevr.com - For the Team Beef Discord invite for news/events/chat";
static char quake3questMessage[] = "Meetups: 21h CET (EU) / 9pm EST (USA). stats.quakevr.com for server status.";
const char* punkbuster_items[] = {
"Disabled",
@ -194,6 +194,7 @@ typedef struct servernode_s {
int minPing;
int maxPing;
qboolean bPB;
qboolean demo;
} servernode_t;
@ -395,7 +396,6 @@ static void ArenaServers_UpdatePicture( void ) {
servernodeptr = g_arenaservers.table[g_arenaservers.list.curvalue].servernode;
Com_sprintf( picname, sizeof(picname), "levelshots/%s.tga", servernodeptr->mapname );
g_arenaservers.mappic.generic.name = picname;
}
// force shader update during draw
@ -500,7 +500,17 @@ static void ArenaServers_UpdateMenu( void ) {
return;
}
// build list box strings - apply culling filters
//Specify should always be grayed out
g_arenaservers.specify.generic.flags |= QMF_GRAYED;
servernode_t* servernode;
servernode = g_arenaservers.table[g_arenaservers.list.curvalue].servernode;
if( servernode && uis.demoversion && !servernode->demo) {
//Demo pak cannot connect to a non-demo server
g_arenaservers.go.generic.flags |= QMF_GRAYED;
}
// build list box strings - apply culling filters
servernodeptr = g_arenaservers.serverlist;
count = *g_arenaservers.numservers;
for( i = 0, j = 0; i < count; i++, servernodeptr++ ) {
@ -562,10 +572,20 @@ static void ArenaServers_UpdateMenu( void ) {
pingColor = S_COLOR_RED;
}
Com_sprintf( buff, MAX_LISTBOXWIDTH, "%-20.20s %-12.12s %2d/%2d %-8.8s %4s%s%3d " S_COLOR_YELLOW "%s",
servernodeptr->hostname, servernodeptr->mapname, servernodeptr->numclients,
servernodeptr->maxclients, servernodeptr->gamename,
netnames[servernodeptr->nettype], pingColor, servernodeptr->pingtime, servernodeptr->bPB ? "Yes" : "No" );
if (uis.demoversion && !servernodeptr->demo)
{
Com_sprintf( buff, MAX_LISTBOXWIDTH, S_COLOR_MID_GREY "%-20.20s %-12.12s %2d/%2d %-8.8s %4s%s%3d " S_COLOR_YELLOW "%s",
servernodeptr->hostname, servernodeptr->mapname, servernodeptr->numclients,
servernodeptr->maxclients, servernodeptr->gamename,
netnames[servernodeptr->nettype], pingColor, servernodeptr->pingtime, servernodeptr->bPB ? "Yes" : "No" );
}
else
{
Com_sprintf( buff, MAX_LISTBOXWIDTH, "%-20.20s %-12.12s %2d/%2d %-8.8s %4s%s%3d " S_COLOR_YELLOW "%s",
servernodeptr->hostname, servernodeptr->mapname, servernodeptr->numclients,
servernodeptr->maxclients, servernodeptr->gamename,
netnames[servernodeptr->nettype], pingColor, servernodeptr->pingtime, servernodeptr->bPB ? "Yes" : "No" );
}
j++;
}
@ -682,6 +702,8 @@ static void ArenaServers_Insert( char* adrstr, char* info, int pingtime )
servernodeptr->minPing = atoi( Info_ValueForKey( info, "minPing") );
servernodeptr->maxPing = atoi( Info_ValueForKey( info, "maxPing") );
servernodeptr->bPB = atoi( Info_ValueForKey( info, "punkbuster") );
servernodeptr->demo = (strcasestr(info, "demo") != NULL) ||
(strcmp(servernodeptr->hostname, "Quake3Quest") == 0); // Demo can connect to another quest
/*
s = Info_ValueForKey( info, "nettype" );
@ -1239,6 +1261,17 @@ static void ArenaServers_Event( void* ptr, int event ) {
case ID_LIST:
if( event == QM_GOTFOCUS ) {
ArenaServers_UpdatePicture();
servernode_t* servernode;
servernode = g_arenaservers.table[g_arenaservers.list.curvalue].servernode;
if( servernode && uis.demoversion && !servernode->demo) {
//Demo pak cannot connect to a non-demo server
g_arenaservers.go.generic.flags |= QMF_GRAYED;
}
else
{
g_arenaservers.go.generic.flags &= ~QMF_GRAYED;
}
}
break;
@ -1583,8 +1616,8 @@ static void ArenaServers_MenuInit( void ) {
Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.create );
Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.go );
Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.punkbuster );
Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.pblogo );
// Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.punkbuster );
// Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.pblogo );
ArenaServers_LoadFavorites();
@ -1602,7 +1635,7 @@ static void ArenaServers_MenuInit( void ) {
g_emptyservers = Com_Clamp( 0, 1, ui_browserShowEmpty.integer );
g_arenaservers.showempty.curvalue = g_emptyservers;
g_arenaservers.punkbuster.curvalue = Com_Clamp( 0, 1, trap_Cvar_VariableValue( "cl_punkbuster" ) );
// g_arenaservers.punkbuster.curvalue = Com_Clamp( 0, 1, trap_Cvar_VariableValue( "cl_punkbuster" ) );
// force to initial state and refresh
g_arenaservers.master.curvalue = g_servertype = ArenaServers_SetType(g_servertype);
@ -1631,7 +1664,7 @@ void ArenaServers_Cache( void ) {
trap_R_RegisterShaderNoMip( ART_ARROWS_UP );
trap_R_RegisterShaderNoMip( ART_ARROWS_DOWN );
trap_R_RegisterShaderNoMip( ART_UNKNOWNMAP );
trap_R_RegisterShaderNoMip( ART_PUNKBUSTER );
// trap_R_RegisterShaderNoMip( ART_PUNKBUSTER );
}

View file

@ -47,7 +47,7 @@ vec4_t colorLtGrey = {0.75, 0.75, 0.75, 1};
vec4_t colorMdGrey = {0.5, 0.5, 0.5, 1};
vec4_t colorDkGrey = {0.25, 0.25, 0.25, 1};
vec4_t g_color_table[8] =
vec4_t g_color_table[10] =
{
{0.0, 0.0, 0.0, 1.0},
{1.0, 0.0, 0.0, 1.0},
@ -57,6 +57,8 @@ vec4_t g_color_table[8] =
{0.0, 1.0, 1.0, 1.0},
{1.0, 0.0, 1.0, 1.0},
{1.0, 1.0, 1.0, 1.0},
{0.75, 0.75, 0.75, 1.0},
{0.5, 0.5, 0.5, 1.0},
};

View file

@ -431,7 +431,9 @@ qboolean Q_IsColorString(const char *p); // ^[0-9a-zA-Z]
#define COLOR_CYAN '5'
#define COLOR_MAGENTA '6'
#define COLOR_WHITE '7'
#define ColorIndexForNumber(c) ((c) & 0x07)
#define COLOR_LIGHT_GREY '8'
#define COLOR_MID_GREY '9'
#define ColorIndexForNumber(c) ((c) & 0x0f)
#define ColorIndex(c) (ColorIndexForNumber((c) - '0'))
#define S_COLOR_BLACK "^0"
@ -442,8 +444,10 @@ qboolean Q_IsColorString(const char *p); // ^[0-9a-zA-Z]
#define S_COLOR_CYAN "^5"
#define S_COLOR_MAGENTA "^6"
#define S_COLOR_WHITE "^7"
#define S_COLOR_LIGHT_GREY "^8"
#define S_COLOR_MID_GREY "^9"
extern vec4_t g_color_table[8];
extern vec4_t g_color_table[10];
#define MAKERGB( v, r, g, b ) v[0]=r;v[1]=g;v[2]=b
#define MAKERGBA( v, r, g, b, a ) v[0]=r;v[1]=g;v[2]=b;v[3]=a

View file

@ -3223,6 +3223,18 @@ static void UI_Update(const char *name) {
trap_Cvar_Set("vr_button_map_RTHUMBLEFT_ALT", ""); // unmapped
break;
}
} else if (Q_stricmp(name, "vr_switchThumbsticks") == 0) {
if (val) {
trap_Cvar_Set("vr_button_map_A", "+button2"); // Use Item
trap_Cvar_Set("vr_button_map_B", "+button3"); // Gesture
trap_Cvar_Set("vr_button_map_X", "+moveup"); // Jump
trap_Cvar_Set("vr_button_map_Y", "+movedown"); // Crouch
} else {
trap_Cvar_Set("vr_button_map_A", "+moveup"); // Jump
trap_Cvar_Set("vr_button_map_B", "+movedown"); // Crouch
trap_Cvar_Set("vr_button_map_X", "+button2"); // Use Item
trap_Cvar_Set("vr_button_map_Y", "+button3"); // Gesture
}
} else if (Q_stricmp(name, "vr_uturn") == 0) {
int controlSchema = (int)trap_Cvar_VariableValue( "vr_controlSchema" ) % 3;
if (val) {

View file

@ -161,14 +161,25 @@ void VR_InitCvars( void )
Cvar_Get ("vr_button_map_RTHUMBLEFT_ALT", "", CVAR_ARCHIVE); // unmapped
}
// Map face buttons based on thumbstick assigned to movement
// (cannot move and jump/crouch with same thumb at same time)
qboolean switchThumbsticks = Cvar_VariableValue( "vr_switchThumbsticks" ) != 0;
if (switchThumbsticks) {
Cvar_Get ("vr_button_map_A", "+button2", CVAR_ARCHIVE); // Use Item
Cvar_Get ("vr_button_map_B", "+button3", CVAR_ARCHIVE); // Gesture
Cvar_Get ("vr_button_map_X", "+moveup", CVAR_ARCHIVE); // Jump
Cvar_Get ("vr_button_map_Y", "+movedown", CVAR_ARCHIVE); // Crouch
} else {
Cvar_Get ("vr_button_map_A", "+moveup", CVAR_ARCHIVE); // Jump
Cvar_Get ("vr_button_map_B", "+movedown", CVAR_ARCHIVE); // Crouch
Cvar_Get ("vr_button_map_X", "+button2", CVAR_ARCHIVE); // Use Item
Cvar_Get ("vr_button_map_Y", "+button3", CVAR_ARCHIVE); // Gesture
}
//Remaining button mapping (buttons not affected by schemas)
Cvar_Get ("vr_button_map_A", "+moveup", CVAR_ARCHIVE); // Jump
Cvar_Get ("vr_button_map_A_ALT", "", CVAR_ARCHIVE); // unmapped
Cvar_Get ("vr_button_map_B", "+movedown", CVAR_ARCHIVE); // Crouch
Cvar_Get ("vr_button_map_B_ALT", "", CVAR_ARCHIVE); // unmapped
Cvar_Get ("vr_button_map_X", "+button2", CVAR_ARCHIVE); // Use Item
Cvar_Get ("vr_button_map_X_ALT", "", CVAR_ARCHIVE); // unmapped
Cvar_Get ("vr_button_map_Y", "+button3", CVAR_ARCHIVE); // Gesture
Cvar_Get ("vr_button_map_Y_ALT", "", CVAR_ARCHIVE); // unmapped
Cvar_Get ("vr_button_map_SECONDARYTHUMBSTICK", "+scores", CVAR_ARCHIVE); // Scoreboard
Cvar_Get ("vr_button_map_SECONDARYTHUMBSTICK_ALT", "", CVAR_ARCHIVE); // unmapped

View file

@ -1,16 +1,19 @@
package com.drbeef.ioq3quest;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.os.RemoteException;
import android.util.Log;
import android.util.Pair;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.drbeef.externalhapticsservice.HapticServiceClient;
import com.drbeef.externalhapticsservice.HapticsConstants;
import org.libsdl.app.SDLActivity;
@ -24,6 +27,7 @@ import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Vector;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
@ -40,7 +44,11 @@ public class MainActivity extends SDLActivity // implements KeyEvent.Callback
String commandLineParams;
private HapticServiceClient externalHapticsServiceClient = null;
private Vector<HapticServiceClient> externalHapticsServiceClients = new Vector<>();
//Use a vector of pairs, it is possible a given package _could_ in the future support more than one haptic service
//so a map here of Package -> Action would not work.
private static Vector<Pair<String, String>> externalHapticsServiceDetails = new Vector<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -53,6 +61,16 @@ public class MainActivity extends SDLActivity // implements KeyEvent.Callback
}
@Override protected void onDestroy()
{
Log.i(TAG, "onDestroy called");
for (HapticServiceClient externalHapticsServiceClient : externalHapticsServiceClients) {
externalHapticsServiceClient.stopBinding();
}
super.onDestroy();
}
/**
* Initializes the Activity only if the permission has been granted.
@ -88,26 +106,30 @@ public class MainActivity extends SDLActivity // implements KeyEvent.Callback
}
public void create() throws IOException {
//Make the directories
// Prepare base game directory
new File("/sdcard/ioquake3Quest/baseq3").mkdirs();
new File("/sdcard/ioquake3Quest/missionpack").mkdirs();
//Copy the command line params file
// Copy the command line params file and autoexec
copy_asset("/sdcard/ioquake3Quest", "commandline.txt", false);
copy_asset("/sdcard/ioquake3Quest/baseq3", "autoexec.cfg", false);
copy_asset("/sdcard/ioquake3Quest/missionpack", "autoexec.cfg", false);
//copy demo
copy_asset("/sdcard/ioquake3Quest/baseq3", "pak0.pk3", false);
//our special pak files
// Copy our special pak file and demo
copy_asset("/sdcard/ioquake3Quest/baseq3", "pakQ3Q.pk3", true);
copy_asset("/sdcard/ioquake3Quest/missionpack", "pakQ3Q.pk3", true);
copy_asset("/sdcard/ioquake3Quest/baseq3", "pak0.pk3", false);
// Cleanup incompatible shaders
delete_asset("/sdcard/ioquake3Quest/baseq3/glsl");
//If open arena is installed then copy necessary stuff
// If Team Arena is installed then copy necessary stuff
if (new File("/sdcard/ioquake3Quest/missionpack").exists()) {
copy_asset("/sdcard/ioquake3Quest/missionpack", "autoexec.cfg", false);
copy_asset("/sdcard/ioquake3Quest/missionpack", "pakQ3Q.pk3", true);
delete_asset("/sdcard/ioquake3Quest/missionpack/glsl");
}
// If Open Arena is installed then copy necessary stuff
if (new File("/sdcard/ioquake3Quest/baseoa").exists()) {
copy_asset("/sdcard/ioquake3Quest/baseoa", "autoexec_oa.cfg", "autoexec.cfg", false);
copy_asset("/sdcard/ioquake3Quest/baseoa", "pakQ3Q.pk3", true);
delete_asset("/sdcard/ioquake3Quest/baseoa/glsl");
}
//Read these from a file and pass through
@ -141,11 +163,15 @@ public class MainActivity extends SDLActivity // implements KeyEvent.Callback
} catch (Exception e) {
}
externalHapticsServiceClient = new HapticServiceClient(this, (state, desc) -> {
Log.v(TAG, "ExternalHapticsService is:" + desc);
});
for (Pair<String, String> serviceDetail : externalHapticsServiceDetails) {
HapticServiceClient client = new HapticServiceClient(this, (state, desc) -> {
Log.v(TAG, "ExternalHapticsService " + serviceDetail.second + ": " + desc);
}, new Intent(serviceDetail.second)
.setPackage(serviceDetail.first));
externalHapticsServiceClient.bindService();
client.bindService();
externalHapticsServiceClients.add(client);
}
Log.d(TAG, "nativeCreate");
nativeCreate(this);
@ -167,6 +193,23 @@ public class MainActivity extends SDLActivity // implements KeyEvent.Callback
}
}
public void delete_asset(String path) {
File file = new File(path);
delete_asset(file);
}
public void delete_asset(File file) {
if (!file.exists()) {
return;
}
if (file.isDirectory()) {
for (File nestedFile : file.listFiles()) {
delete_asset(nestedFile);
}
}
file.delete();
}
public void _copy_asset(String name_in, String name_out) {
AssetManager assets = this.getAssets();
@ -202,39 +245,48 @@ public class MainActivity extends SDLActivity // implements KeyEvent.Callback
static {
System.loadLibrary("main");
//Add possible external haptic service details here
externalHapticsServiceDetails.add(Pair.create(HapticsConstants.BHAPTICS_PACKAGE, HapticsConstants.BHAPTICS_ACTION_FILTER));
externalHapticsServiceDetails.add(Pair.create(HapticsConstants.FORCETUBE_PACKAGE, HapticsConstants.FORCETUBE_ACTION_FILTER));
}
public void haptic_event(String event, int position, int flags, int intensity, float angle, float yHeight) {
if (externalHapticsServiceClient.hasService()) {
try {
if (!hapticsEnabled)
{
externalHapticsServiceClient.getHapticsService().hapticEnable();
hapticsEnabled = true;
return;
}
boolean areHapticsEnabled = hapticsEnabled;
for (HapticServiceClient externalHapticsServiceClient : externalHapticsServiceClients) {
if (event.compareTo("frame_tick") == 0)
{
externalHapticsServiceClient.getHapticsService().hapticFrameTick();
}
if (externalHapticsServiceClient.hasService()) {
try {
//Enabled all haptics services if required
if (!areHapticsEnabled)
{
externalHapticsServiceClient.getHapticsService().hapticEnable();
hapticsEnabled = true;
continue;
}
//Use the Doom3Quest haptic patterns for now
String app = "Doom3Quest";
if (event.contains(":"))
{
String[] items = event.split(":");
app = items[0];
event = items[1];
if (event.compareTo("frame_tick") == 0)
{
externalHapticsServiceClient.getHapticsService().hapticFrameTick();
}
//Uses the Doom3Quest and RTCWQuest haptic patterns
String app = "Doom3Quest";
String eventID = event;
if (event.contains(":"))
{
String[] items = event.split(":");
app = items[0];
eventID = items[1];
}
externalHapticsServiceClient.getHapticsService().hapticEvent(app, eventID, position, flags, intensity, angle, yHeight);
}
catch (RemoteException r)
{
Log.v(TAG, r.toString());
}
externalHapticsServiceClient.getHapticsService().hapticEvent(app, event, position, flags, intensity, angle, yHeight);
}
catch (RemoteException r)
{
Log.v(TAG, r.toString());
}
}
}
}

View file

@ -157,6 +157,7 @@ itemDef {
textscale .333
forecolor 1 1 1 1
visible 1
action { uiScript update "vr_switchThumbsticks" }
}
itemDef {

View file

@ -279,6 +279,7 @@ itemDef {
textscale .25
forecolor 1 1 1 1
visible 1
action { uiScript update "vr_switchThumbsticks" }
}
itemDef {

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">ioquake3Quest</string>
<string name="app_name">Quake3Quest</string>
</resources>

View file

@ -3,7 +3,7 @@
setlocal
set BUILD_TYPE=release
set VERSION=0.31.4-multiview
set VERSION=1.1.0
@REM Define the following environment variables to sign a release build
@REM set KEYSTORE=