7c6eb18a76
android gets a couple more gamepad buttons. gamepads now have separate keybindings. I've created some default binds for mods that are unaware of gamepad buttons. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5142 fc73d0e0-1445-4013-8a0c-d673dee63da5
941 lines
28 KiB
C
941 lines
28 KiB
C
//file for builtin implementations relevent to only clientside VMs (menu+csqc).
|
|
#include "quakedef.h"
|
|
|
|
#include "pr_common.h"
|
|
#include "shader.h"
|
|
|
|
#if defined(CSQC_DAT) || defined(MENU_DAT)
|
|
|
|
//these two global qcinput variables are the current scan code being passed to qc, if valid. this protects against protected apis where the qc just passes stuff through.
|
|
int qcinput_scan;
|
|
int qcinput_unicode;
|
|
|
|
//QC key codes are based upon DP's keycode constants. This is on account of menu.dat coming first.
|
|
int MP_TranslateFTEtoQCCodes(int code)
|
|
{
|
|
switch(code)
|
|
{
|
|
case K_TAB: return 9;
|
|
case K_ENTER: return 13;
|
|
case K_ESCAPE: return 27;
|
|
case K_SPACE: return 32;
|
|
case K_BACKSPACE: return 127;
|
|
case K_UPARROW: return 128;
|
|
case K_DOWNARROW: return 129;
|
|
case K_LEFTARROW: return 130;
|
|
case K_RIGHTARROW: return 131;
|
|
case K_LALT: return 132;
|
|
case K_RALT: return -K_RALT;
|
|
case K_LCTRL: return 133;
|
|
case K_RCTRL: return -K_RCTRL;
|
|
case K_LSHIFT: return 134;
|
|
case K_RSHIFT: return -K_RSHIFT;
|
|
case K_F1: return 135;
|
|
case K_F2: return 136;
|
|
case K_F3: return 137;
|
|
case K_F4: return 138;
|
|
case K_F5: return 139;
|
|
case K_F6: return 140;
|
|
case K_F7: return 141;
|
|
case K_F8: return 142;
|
|
case K_F9: return 143;
|
|
case K_F10: return 144;
|
|
case K_F11: return 145;
|
|
case K_F12: return 146;
|
|
case K_INS: return 147;
|
|
case K_DEL: return 148;
|
|
case K_PGDN: return 149;
|
|
case K_PGUP: return 150;
|
|
case K_HOME: return 151;
|
|
case K_END: return 152;
|
|
case K_PAUSE: return 153;
|
|
case K_KP_NUMLOCK: return 154;
|
|
case K_CAPSLOCK: return 155;
|
|
case K_SCRLCK: return 156;
|
|
case K_KP_INS: return 157;
|
|
case K_KP_END: return 158;
|
|
case K_KP_DOWNARROW: return 159;
|
|
case K_KP_PGDN: return 160;
|
|
case K_KP_LEFTARROW: return 161;
|
|
case K_KP_5: return 162;
|
|
case K_KP_RIGHTARROW: return 163;
|
|
case K_KP_HOME: return 164;
|
|
case K_KP_UPARROW: return 165;
|
|
case K_KP_PGUP: return 166;
|
|
case K_KP_DEL: return 167;
|
|
case K_KP_SLASH: return 168;
|
|
case K_KP_STAR: return 169;
|
|
case K_KP_MINUS: return 170;
|
|
case K_KP_PLUS: return 171;
|
|
case K_KP_ENTER: return 172;
|
|
case K_KP_EQUALS: return 173;
|
|
case K_PRINTSCREEN: return 174;
|
|
|
|
case K_MOUSE1: return 512;
|
|
case K_MOUSE2: return 513;
|
|
case K_MOUSE3: return 514;
|
|
case K_MWHEELUP: return 515;
|
|
case K_MWHEELDOWN: return 516;
|
|
case K_MOUSE4: return 517;
|
|
case K_MOUSE5: return 518;
|
|
case K_MOUSE6: return 519;
|
|
case K_MOUSE7: return 520;
|
|
case K_MOUSE8: return 521;
|
|
case K_MOUSE9: return 522;
|
|
case K_MOUSE10: return 523;
|
|
// case K_MOUSE11: return 524;
|
|
// case K_MOUSE12: return 525;
|
|
// case K_MOUSE13: return 526;
|
|
// case K_MOUSE14: return 527;
|
|
// case K_MOUSE15: return 528;
|
|
// case K_MOUSE16: return 529;
|
|
|
|
case K_JOY1: return 768;
|
|
case K_JOY2: return 769;
|
|
case K_JOY3: return 770;
|
|
case K_JOY4: return 771;
|
|
// case K_JOY5: return 772;
|
|
// case K_JOY6: return 773;
|
|
// case K_JOY7: return 774;
|
|
// case K_JOY8: return 775;
|
|
// case K_JOY9: return 776;
|
|
// case K_JOY10: return 777;
|
|
// case K_JOY11: return 778;
|
|
// case K_JOY12: return 779;
|
|
// case K_JOY13: return 780;
|
|
// case K_JOY14: return 781;
|
|
// case K_JOY15: return 782;
|
|
// case K_JOY16: return 783;
|
|
|
|
case K_AUX1: return 784;
|
|
case K_AUX2: return 785;
|
|
case K_AUX3: return 786;
|
|
case K_AUX4: return 787;
|
|
case K_AUX5: return 788;
|
|
case K_AUX6: return 789;
|
|
case K_AUX7: return 790;
|
|
case K_AUX8: return 791;
|
|
case K_AUX9: return 792;
|
|
case K_AUX10: return 793;
|
|
case K_AUX11: return 794;
|
|
case K_AUX12: return 795;
|
|
case K_AUX13: return 796;
|
|
case K_AUX14: return 797;
|
|
case K_AUX15: return 798;
|
|
case K_AUX16: return 799;
|
|
case K_AUX17: return 800;
|
|
case K_AUX18: return 801;
|
|
case K_AUX19: return 802;
|
|
case K_AUX20: return 803;
|
|
case K_AUX21: return 804;
|
|
case K_AUX22: return 805;
|
|
case K_AUX23: return 806;
|
|
case K_AUX24: return 807;
|
|
case K_AUX25: return 808;
|
|
case K_AUX26: return 809;
|
|
case K_AUX27: return 810;
|
|
case K_AUX28: return 811;
|
|
case K_AUX29: return 812;
|
|
case K_AUX30: return 813;
|
|
case K_AUX31: return 814;
|
|
case K_AUX32: return 815;
|
|
|
|
case K_GP_DPAD_UP: return 816;
|
|
case K_GP_DPAD_DOWN: return 817;
|
|
case K_GP_DPAD_LEFT: return 818;
|
|
case K_GP_DPAD_RIGHT: return 819;
|
|
case K_GP_START: return 820;
|
|
case K_GP_BACK: return 821;
|
|
case K_GP_LEFT_THUMB: return 822;
|
|
case K_GP_RIGHT_THUMB: return 823;
|
|
case K_GP_LEFT_SHOULDER:return 824;
|
|
case K_GP_RIGHT_SHOULDER:return 825;
|
|
case K_GP_A: return 826;
|
|
case K_GP_B: return 827;
|
|
case K_GP_X: return 828;
|
|
case K_GP_Y: return 829;
|
|
case K_GP_LEFT_TRIGGER: return 830;
|
|
case K_GP_RIGHT_TRIGGER:return 831;
|
|
|
|
case K_VOLUP: return -code;
|
|
case K_VOLDOWN: return -code;
|
|
case K_APP: return -code;
|
|
case K_SEARCH: return -code;
|
|
|
|
default: return code;
|
|
}
|
|
}
|
|
|
|
int MP_TranslateQCtoFTECodes(int code)
|
|
{
|
|
switch(code)
|
|
{
|
|
case 9: return K_TAB;
|
|
case 13: return K_ENTER;
|
|
case 27: return K_ESCAPE;
|
|
case 32: return K_SPACE;
|
|
case 127: return K_BACKSPACE;
|
|
case 128: return K_UPARROW;
|
|
case 129: return K_DOWNARROW;
|
|
case 130: return K_LEFTARROW;
|
|
case 131: return K_RIGHTARROW;
|
|
case 132: return K_LALT;
|
|
case 133: return K_LCTRL;
|
|
case 134: return K_LSHIFT;
|
|
case 135: return K_F1;
|
|
case 136: return K_F2;
|
|
case 137: return K_F3;
|
|
case 138: return K_F4;
|
|
case 139: return K_F5;
|
|
case 140: return K_F6;
|
|
case 141: return K_F7;
|
|
case 142: return K_F8;
|
|
case 143: return K_F9;
|
|
case 144: return K_F10;
|
|
case 145: return K_F11;
|
|
case 146: return K_F12;
|
|
case 147: return K_INS;
|
|
case 148: return K_DEL;
|
|
case 149: return K_PGDN;
|
|
case 150: return K_PGUP;
|
|
case 151: return K_HOME;
|
|
case 152: return K_END;
|
|
case 153: return K_PAUSE;
|
|
case 154: return K_KP_NUMLOCK;
|
|
case 155: return K_CAPSLOCK;
|
|
case 156: return K_SCRLCK;
|
|
case 157: return K_KP_INS;
|
|
case 158: return K_KP_END;
|
|
case 159: return K_KP_DOWNARROW;
|
|
case 160: return K_KP_PGDN;
|
|
case 161: return K_KP_LEFTARROW;
|
|
case 162: return K_KP_5;
|
|
case 163: return K_KP_RIGHTARROW;
|
|
case 164: return K_KP_HOME;
|
|
case 165: return K_KP_UPARROW;
|
|
case 166: return K_KP_PGUP;
|
|
case 167: return K_KP_DEL;
|
|
case 168: return K_KP_SLASH;
|
|
case 169: return K_KP_STAR;
|
|
case 170: return K_KP_MINUS;
|
|
case 171: return K_KP_PLUS;
|
|
case 172: return K_KP_ENTER;
|
|
case 173: return K_KP_EQUALS;
|
|
case 174: return K_PRINTSCREEN;
|
|
|
|
case 512: return K_MOUSE1;
|
|
case 513: return K_MOUSE2;
|
|
case 514: return K_MOUSE3;
|
|
case 515: return K_MWHEELUP;
|
|
case 516: return K_MWHEELDOWN;
|
|
case 517: return K_MOUSE4;
|
|
case 518: return K_MOUSE5;
|
|
case 519: return K_MOUSE6;
|
|
case 520: return K_MOUSE7;
|
|
case 521: return K_MOUSE8;
|
|
case 522: return K_MOUSE9;
|
|
case 523: return K_MOUSE10;
|
|
// case 524: return K_MOUSE11;
|
|
// case 525: return K_MOUSE12;
|
|
// case 526: return K_MOUSE13;
|
|
// case 527: return K_MOUSE14;
|
|
// case 528: return K_MOUSE15;
|
|
// case 529: return K_MOUSE16;
|
|
|
|
case 768: return K_JOY1;
|
|
case 769: return K_JOY2;
|
|
case 770: return K_JOY3;
|
|
case 771: return K_JOY4;
|
|
// case 772: return K_JOY5;
|
|
// case 773: return K_JOY6;
|
|
// case 774: return K_JOY7;
|
|
// case 775: return K_JOY8;
|
|
// case 776: return K_JOY9;
|
|
// case 777: return K_JOY10;
|
|
// case 778: return K_JOY11;
|
|
// case 779: return K_JOY12;
|
|
// case 780: return K_JOY13;
|
|
// case 781: return K_JOY14;
|
|
// case 782: return K_JOY15;
|
|
// case 783: return K_JOY16;
|
|
|
|
case 784: return K_AUX1;
|
|
case 785: return K_AUX2;
|
|
case 786: return K_AUX3;
|
|
case 787: return K_AUX4;
|
|
case 788: return K_AUX5;
|
|
case 789: return K_AUX6;
|
|
case 790: return K_AUX7;
|
|
case 791: return K_AUX8;
|
|
case 792: return K_AUX9;
|
|
case 793: return K_AUX10;
|
|
case 794: return K_AUX11;
|
|
case 795: return K_AUX12;
|
|
case 796: return K_AUX13;
|
|
case 797: return K_AUX14;
|
|
case 798: return K_AUX15;
|
|
case 799: return K_AUX16;
|
|
case 800: return K_AUX17;
|
|
case 801: return K_AUX18;
|
|
case 802: return K_AUX19;
|
|
case 803: return K_AUX20;
|
|
case 804: return K_AUX21;
|
|
case 805: return K_AUX22;
|
|
case 806: return K_AUX23;
|
|
case 807: return K_AUX24;
|
|
case 808: return K_AUX25;
|
|
case 809: return K_AUX26;
|
|
case 810: return K_AUX27;
|
|
case 811: return K_AUX28;
|
|
case 812: return K_AUX29;
|
|
case 813: return K_AUX30;
|
|
case 814: return K_AUX31;
|
|
case 815: return K_AUX32;
|
|
|
|
case 816: return K_GP_DPAD_UP;
|
|
case 817: return K_GP_DPAD_DOWN;
|
|
case 818: return K_GP_DPAD_LEFT;
|
|
case 819: return K_GP_DPAD_RIGHT;
|
|
case 820: return K_GP_START;
|
|
case 821: return K_GP_BACK;
|
|
case 822: return K_GP_LEFT_THUMB;
|
|
case 823: return K_GP_RIGHT_THUMB;
|
|
case 824: return K_GP_LEFT_SHOULDER;
|
|
case 825: return K_GP_RIGHT_SHOULDER;
|
|
case 826: return K_GP_A;
|
|
case 827: return K_GP_B;
|
|
case 828: return K_GP_X;
|
|
case 829: return K_GP_Y;
|
|
case 830: return K_GP_LEFT_TRIGGER;
|
|
case 831: return K_GP_RIGHT_TRIGGER;
|
|
// case 832: return K_GP_LEFT_THUMB_UP;
|
|
// case 833: return K_GP_LEFT_THUMB_DOWN;
|
|
// case 834: return K_GP_LEFT_THUMB_LEFT;
|
|
// case 835: return K_GP_LEFT_THUMB_RIGHT;
|
|
// case 836: return K_GP_RIGHT_THUMB_UP;
|
|
// case 837: return K_GP_RIGHT_THUMB_DOWN;
|
|
// case 838: return K_GP_RIGHT_THUMB_LEFT;
|
|
// case 839: return K_GP_RIGHT_THUMB_RIGHT;
|
|
default:
|
|
if (code < 0) //negative values are 'fte-native' keys, for stuff that the api lacks.
|
|
return -code;
|
|
return code;
|
|
}
|
|
}
|
|
|
|
//string findkeysforcommand(string command) = #610;
|
|
void QCBUILTIN PF_cl_findkeysforcommand (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
const char *cmdname = PR_GetStringOfs(prinst, OFS_PARM0);
|
|
int bindmap = (prinst->callargc > 1)?G_FLOAT(OFS_PARM1):0;
|
|
int keynums[2];
|
|
char keyname[512];
|
|
|
|
M_FindKeysForCommand(bindmap, 0, cmdname, keynums, NULL, countof(keynums));
|
|
|
|
keyname[0] = '\0';
|
|
|
|
Q_strncatz (keyname, va(" \'%i\'", MP_TranslateFTEtoQCCodes(keynums[0])), sizeof(keyname));
|
|
Q_strncatz (keyname, va(" \'%i\'", MP_TranslateFTEtoQCCodes(keynums[1])), sizeof(keyname));
|
|
|
|
RETURN_TSTRING(keyname);
|
|
}
|
|
|
|
void QCBUILTIN PF_cl_findkeysforcommandex (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
const char *cmdname = PR_GetStringOfs(prinst, OFS_PARM0);
|
|
int bindmap = (prinst->callargc > 1)?G_FLOAT(OFS_PARM1):0;
|
|
int keynums[256];
|
|
int keymods[countof(keynums)];
|
|
char keyname[512];
|
|
int i, count;
|
|
|
|
count = M_FindKeysForBind(bindmap, cmdname, keynums, keymods, countof(keynums));
|
|
|
|
keyname[0] = '\0';
|
|
|
|
for (i = 0; i < count; i++)
|
|
{
|
|
if (i)
|
|
Q_strncatz (keyname, " ", sizeof(keyname));
|
|
Q_strncatz (keyname, Key_KeynumToString(keynums[i], keymods[i]), sizeof(keyname));
|
|
}
|
|
|
|
RETURN_TSTRING(keyname);
|
|
}
|
|
|
|
void QCBUILTIN PF_cl_getkeybind (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
int keymap = (prinst->callargc > 1)?G_FLOAT(OFS_PARM1):0;
|
|
int modifier = (prinst->callargc > 2)?G_FLOAT(OFS_PARM2):0;
|
|
char *binding = Key_GetBinding(MP_TranslateQCtoFTECodes(G_FLOAT(OFS_PARM0)), keymap, modifier);
|
|
RETURN_TSTRING(binding);
|
|
}
|
|
|
|
void QCBUILTIN PF_cl_stringtokeynum(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
int i;
|
|
int modifier;
|
|
const char *s;
|
|
|
|
s = PR_GetStringOfs(prinst, OFS_PARM0);
|
|
i = Key_StringToKeynum(s, &modifier);
|
|
if (i < 0 || modifier != ~0)
|
|
{
|
|
G_FLOAT(OFS_RETURN) = -1;
|
|
return;
|
|
}
|
|
i = MP_TranslateFTEtoQCCodes(i);
|
|
G_FLOAT(OFS_RETURN) = i;
|
|
}
|
|
|
|
//string keynumtostring(float keynum) = #609;
|
|
void QCBUILTIN PF_cl_keynumtostring (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
int code = G_FLOAT(OFS_PARM0);
|
|
|
|
code = MP_TranslateQCtoFTECodes (code);
|
|
|
|
RETURN_TSTRING(Key_KeynumToString(code, 0));
|
|
}
|
|
|
|
void QCBUILTIN PF_cl_setwindowcaption(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
const char *newcaption = PR_GetStringOfs(prinst, OFS_PARM0);
|
|
if (!cl.windowtitle || strcmp(cl.windowtitle, newcaption))
|
|
{
|
|
Z_Free(cl.windowtitle);
|
|
cl.windowtitle = NULL;
|
|
if (*newcaption)
|
|
cl.windowtitle = Z_StrDup(newcaption);
|
|
CL_UpdateWindowTitle();
|
|
}
|
|
}
|
|
|
|
//#343
|
|
void QCBUILTIN PF_cl_setcursormode (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
world_t *world = prinst->parms->user;
|
|
if (G_FLOAT(OFS_PARM0))
|
|
key_dest_absolutemouse |= world->keydestmask;
|
|
else
|
|
key_dest_absolutemouse &= ~world->keydestmask;
|
|
|
|
if (prinst->callargc>1)
|
|
{
|
|
struct key_cursor_s *m = &key_customcursor[(world->keydestmask==kdm_game)?kc_game:kc_menu];
|
|
Q_strncpyz(m->name, PR_GetStringOfs(prinst, OFS_PARM1), sizeof(m->name));
|
|
m->hotspot[0] = (prinst->callargc>2)?G_FLOAT(OFS_PARM2+0):0;
|
|
m->hotspot[1] = (prinst->callargc>2)?G_FLOAT(OFS_PARM2+1):0;
|
|
m->scale = (prinst->callargc>2)?G_FLOAT(OFS_PARM2+2):0;
|
|
if (m->scale <= 0)
|
|
m->scale = 1;
|
|
m->dirty = true;
|
|
}
|
|
}
|
|
|
|
void QCBUILTIN PF_cl_getcursormode (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
world_t *world = prinst->parms->user;
|
|
if (G_FLOAT(OFS_PARM0))
|
|
G_FLOAT(OFS_RETURN) = Key_MouseShouldBeFree();
|
|
else if (key_dest_absolutemouse & world->keydestmask)
|
|
G_FLOAT(OFS_RETURN) = true;
|
|
else
|
|
G_FLOAT(OFS_RETURN) = false;
|
|
}
|
|
|
|
void QCBUILTIN PF_cl_playingdemo (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
switch(cls.demoplayback)
|
|
{
|
|
case DPB_NONE:
|
|
G_FLOAT(OFS_RETURN) = 0;
|
|
break;
|
|
case DPB_MVD:
|
|
case DPB_EZTV:
|
|
G_FLOAT(OFS_RETURN) = 2;
|
|
break;
|
|
default:
|
|
G_FLOAT(OFS_RETURN) = 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
void QCBUILTIN PF_cl_runningserver (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
#ifdef CLIENTONLY
|
|
G_FLOAT(OFS_RETURN) = false;
|
|
#else
|
|
if (sv.state != ss_dead)
|
|
{
|
|
if (sv.allocated_client_slots > 1)
|
|
G_FLOAT(OFS_RETURN) = true;
|
|
else
|
|
G_FLOAT(OFS_RETURN) = 0.5; //give some half-way value if we're singleplayer. NOTE: DP returns 0 in this case, which is kinda useless for things like deciding whether a 'save' menu option can be used.
|
|
}
|
|
else
|
|
G_FLOAT(OFS_RETURN) = false;
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
#ifdef HAVE_MEDIA_DECODER
|
|
|
|
// #487 float(string name, string video="http:") gecko_create
|
|
void QCBUILTIN PF_cs_media_create (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
const char *shadername = PR_GetStringOfs(prinst, OFS_PARM0);
|
|
const char *videoname = (prinst->callargc > 1)?PR_GetStringOfs(prinst, OFS_PARM1):"http:";
|
|
cin_t *cin;
|
|
cin = R_ShaderGetCinematic(R_RegisterShader(shadername, SUF_2D, va(
|
|
"{\n"
|
|
"program default2d\n"
|
|
"{\n"
|
|
"videomap %s\n"
|
|
"rgbgen vertex\n"
|
|
"alphagen vertex\n"
|
|
"blendfunc blend\n"
|
|
"nodepth\n"
|
|
"}\n"
|
|
"}\n",
|
|
videoname)));
|
|
|
|
if (cin)
|
|
{
|
|
G_FLOAT(OFS_RETURN) = 1;
|
|
Media_Send_Reset(cin);
|
|
}
|
|
else
|
|
G_FLOAT(OFS_RETURN) = 0;
|
|
}
|
|
// #488 void(string name) gecko_destroy
|
|
void QCBUILTIN PF_cs_media_destroy (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
const char *shadername = PR_GetStringOfs(prinst, OFS_PARM0);
|
|
shader_t *shader = R_ShaderFind(shadername);
|
|
cin_t *cin;
|
|
if (!shader)
|
|
return;
|
|
cin = R_ShaderGetCinematic(shader);
|
|
if (cin && shader->uses > 1)
|
|
{
|
|
if (shader->uses > 1)
|
|
Media_Send_Reset(cin); //will still be active afterwards.
|
|
}
|
|
R_UnloadShader(shader);
|
|
}
|
|
// #489 void(string name, string URI) gecko_navigate
|
|
void QCBUILTIN PF_cs_media_command (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
const char *shader = PR_GetStringOfs(prinst, OFS_PARM0);
|
|
const char *command = PR_GetStringOfs(prinst, OFS_PARM1);
|
|
cin_t *cin;
|
|
cin = R_ShaderFindCinematic(shader);
|
|
if (!cin)
|
|
return;
|
|
Media_Send_Command(cin, command);
|
|
}
|
|
// #490 float(string name, float key, float eventtype) gecko_keyevent
|
|
void QCBUILTIN PF_cs_media_keyevent (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
const char *shader = PR_GetStringOfs(prinst, OFS_PARM0);
|
|
int key = G_FLOAT(OFS_PARM1);
|
|
int eventtype = G_FLOAT(OFS_PARM2);
|
|
cin_t *cin;
|
|
cin = R_ShaderFindCinematic(shader);
|
|
if (!cin)
|
|
return;
|
|
Media_Send_KeyEvent(cin, MP_TranslateQCtoFTECodes(key), (key>127)?0:key, eventtype);
|
|
}
|
|
// #491 void(string name, float x, float y) gecko_mousemove
|
|
void QCBUILTIN PF_cs_media_mousemove (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
const char *shader = PR_GetStringOfs(prinst, OFS_PARM0);
|
|
float posx = G_FLOAT(OFS_PARM1);
|
|
float posy = G_FLOAT(OFS_PARM2);
|
|
cin_t *cin;
|
|
cin = R_ShaderFindCinematic(shader);
|
|
if (!cin)
|
|
return;
|
|
Media_Send_MouseMove(cin, posx, posy);
|
|
}
|
|
// #492 void(string name, float w, float h) gecko_resize
|
|
void QCBUILTIN PF_cs_media_resize (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
const char *shader = PR_GetStringOfs(prinst, OFS_PARM0);
|
|
float sizex = G_FLOAT(OFS_PARM1);
|
|
float sizey = G_FLOAT(OFS_PARM2);
|
|
cin_t *cin;
|
|
cin = R_ShaderFindCinematic(shader);
|
|
if (!cin)
|
|
return;
|
|
Media_Send_Resize(cin, sizex, sizey);
|
|
}
|
|
// #493 vector(string name) gecko_get_texture_extent
|
|
void QCBUILTIN PF_cs_media_get_texture_extent (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
const char *shader = PR_GetStringOfs(prinst, OFS_PARM0);
|
|
float *ret = G_VECTOR(OFS_RETURN);
|
|
int sx = 0, sy = 0;
|
|
float aspect = 0;
|
|
cin_t *cin;
|
|
cin = R_ShaderFindCinematic(shader);
|
|
if (cin)
|
|
Media_Send_GetSize(cin, &sx, &sy, &aspect);
|
|
ret[0] = sx;
|
|
ret[1] = sy;
|
|
ret[2] = aspect;
|
|
}
|
|
void QCBUILTIN PF_cs_media_getproperty (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
const char *shader = PR_GetStringOfs(prinst, OFS_PARM0);
|
|
const char *propname = PR_GetStringOfs(prinst, OFS_PARM1);
|
|
const char *ret = NULL;
|
|
cin_t *cin;
|
|
cin = R_ShaderFindCinematic(shader);
|
|
if (cin)
|
|
ret = Media_Send_GetProperty(cin, propname);
|
|
|
|
G_INT(OFS_RETURN) = ret?PR_TempString(prinst, ret):0;
|
|
}
|
|
void QCBUILTIN PF_cs_media_getstate (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
const char *shader = PR_GetStringOfs(prinst, OFS_PARM0);
|
|
cinstates_t ret = CINSTATE_INVALID;
|
|
cin_t *cin;
|
|
cin = R_ShaderFindCinematic(shader);
|
|
if (cin)
|
|
ret = Media_GetState(cin);
|
|
|
|
G_FLOAT(OFS_RETURN) = ret;
|
|
}
|
|
void QCBUILTIN PF_cs_media_setstate (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
const char *shader = PR_GetStringOfs(prinst, OFS_PARM0);
|
|
cinstates_t state = G_FLOAT(OFS_PARM1);
|
|
cin_t *cin;
|
|
cin = R_ShaderFindCinematic(shader);
|
|
if (cin)
|
|
Media_SetState(cin, state);
|
|
}
|
|
|
|
void QCBUILTIN PF_cs_media_restart (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
const char *shader = PR_GetStringOfs(prinst, OFS_PARM0);
|
|
cin_t *cin;
|
|
cin = R_ShaderFindCinematic(shader);
|
|
if (cin)
|
|
Media_Send_Reset(cin);
|
|
}
|
|
#endif
|
|
|
|
void QCBUILTIN PF_soundlength (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
const char *sample = PR_GetStringOfs(prinst, OFS_PARM0);
|
|
|
|
sfx_t *sfx = S_PrecacheSound(sample);
|
|
if (sfx && sfx->loadstate == SLS_LOADING)
|
|
COM_WorkerPartialSync(sfx, &sfx->loadstate, SLS_LOADING);
|
|
if (!sfx || sfx->loadstate != SLS_LOADED)
|
|
G_FLOAT(OFS_RETURN) = 0;
|
|
else
|
|
{
|
|
sfxcache_t cachebuf, *cache;
|
|
if (sfx->decoder.querydata)
|
|
{
|
|
G_FLOAT(OFS_RETURN) = sfx->decoder.querydata(sfx, NULL, NULL, 0);
|
|
return;
|
|
}
|
|
else if (sfx->decoder.decodedata)
|
|
cache = sfx->decoder.decodedata(sfx, &cachebuf, 0x7ffffffe, 0);
|
|
else
|
|
cache = sfx->decoder.buf;
|
|
if (!cache)
|
|
G_FLOAT(OFS_RETURN) = 0;
|
|
else
|
|
G_FLOAT(OFS_RETURN) = (cache->soundoffset+cache->length) / (float)snd_speed;
|
|
}
|
|
}
|
|
|
|
qboolean M_Vid_GetMode(int num, int *w, int *h);
|
|
//a bit pointless really
|
|
void QCBUILTIN PF_cl_getresolution (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
float mode = G_FLOAT(OFS_PARM0);
|
|
// qboolean fixedmodes = (prinst->callargc >= 2)?!G_FLOAT(OFS_PARM1):false; //if true, we should return sane-sized modes suitable for a window... or the mod could make up its own, but whatever.
|
|
float *ret = G_VECTOR(OFS_RETURN);
|
|
int w, h;
|
|
|
|
w=h=0;
|
|
if (mode == -1)
|
|
{
|
|
int bpp, rate;
|
|
Sys_GetDesktopParameters(&w, &h, &bpp, &rate);
|
|
}
|
|
else
|
|
M_Vid_GetMode(mode, &w, &h);
|
|
|
|
ret[0] = w;
|
|
ret[1] = h;
|
|
ret[2] = (w&&h)?1:0;
|
|
}
|
|
|
|
#ifdef CL_MASTER
|
|
#include "cl_master.h"
|
|
|
|
void QCBUILTIN PF_cl_gethostcachevalue (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
hostcacheglobal_t hcg = G_FLOAT(OFS_PARM0);
|
|
G_FLOAT(OFS_RETURN) = 0;
|
|
switch(hcg)
|
|
{
|
|
case SLIST_HOSTCACHEVIEWCOUNT:
|
|
CL_QueryServers();
|
|
Master_CheckPollSockets();
|
|
G_FLOAT(OFS_RETURN) = Master_NumSorted();
|
|
return;
|
|
case SLIST_HOSTCACHETOTALCOUNT:
|
|
CL_QueryServers();
|
|
Master_CheckPollSockets();
|
|
G_FLOAT(OFS_RETURN) = Master_TotalCount();
|
|
return;
|
|
|
|
case SLIST_MASTERQUERYCOUNT:
|
|
case SLIST_MASTERREPLYCOUNT:
|
|
case SLIST_SERVERQUERYCOUNT:
|
|
case SLIST_SERVERREPLYCOUNT:
|
|
G_FLOAT(OFS_RETURN) = 0;
|
|
return;
|
|
|
|
case SLIST_SORTFIELD:
|
|
G_FLOAT(OFS_RETURN) = Master_GetSortField();
|
|
return;
|
|
case SLIST_SORTDESCENDING:
|
|
G_FLOAT(OFS_RETURN) = Master_GetSortDescending();
|
|
return;
|
|
default:
|
|
return;
|
|
}
|
|
}
|
|
|
|
//void resethostcachemasks(void) = #615;
|
|
void QCBUILTIN PF_cl_resethostcachemasks(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
Master_ClearMasks();
|
|
}
|
|
//void sethostcachemaskstring(float mask, float fld, string str, float op) = #616;
|
|
void QCBUILTIN PF_cl_sethostcachemaskstring(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
int mask = G_FLOAT(OFS_PARM0);
|
|
int field = G_FLOAT(OFS_PARM1);
|
|
const char *str = PR_GetStringOfs(prinst, OFS_PARM2);
|
|
int op = G_FLOAT(OFS_PARM3);
|
|
|
|
Master_SetMaskString(mask, field, str, op);
|
|
}
|
|
//void sethostcachemasknumber(float mask, float fld, float num, float op) = #617;
|
|
void QCBUILTIN PF_cl_sethostcachemasknumber(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
int mask = G_FLOAT(OFS_PARM0);
|
|
int field = G_FLOAT(OFS_PARM1);
|
|
int str = G_FLOAT(OFS_PARM2);
|
|
int op = G_FLOAT(OFS_PARM3);
|
|
|
|
Master_SetMaskInteger(mask, field, str, op);
|
|
}
|
|
//void resorthostcache(void) = #618;
|
|
void QCBUILTIN PF_cl_resorthostcache(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
Master_SortServers();
|
|
}
|
|
//void sethostcachesort(float fld, float descending) = #619;
|
|
void QCBUILTIN PF_cl_sethostcachesort(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
Master_SetSortField(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
|
|
}
|
|
//void refreshhostcache(void) = #620;
|
|
void QCBUILTIN PF_cl_refreshhostcache(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
MasterInfo_Refresh();
|
|
}
|
|
//float gethostcachenumber(float fld, float hostnr) = #621;
|
|
void QCBUILTIN PF_cl_gethostcachenumber(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
float ret = 0;
|
|
int keynum = G_FLOAT(OFS_PARM0);
|
|
int svnum = G_FLOAT(OFS_PARM1);
|
|
serverinfo_t *sv;
|
|
sv = Master_SortedServer(svnum);
|
|
|
|
ret = Master_ReadKeyFloat(sv, keynum);
|
|
|
|
G_FLOAT(OFS_RETURN) = ret;
|
|
}
|
|
void QCBUILTIN PF_cl_gethostcachestring (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
char *ret;
|
|
int keynum = G_FLOAT(OFS_PARM0);
|
|
int svnum = G_FLOAT(OFS_PARM1);
|
|
serverinfo_t *sv;
|
|
|
|
sv = Master_SortedServer(svnum);
|
|
ret = Master_ReadKeyString(sv, keynum);
|
|
|
|
RETURN_TSTRING(ret);
|
|
}
|
|
|
|
//float gethostcacheindexforkey(string key) = #622;
|
|
void QCBUILTIN PF_cl_gethostcacheindexforkey(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
const char *keyname = PR_GetStringOfs(prinst, OFS_PARM0);
|
|
|
|
G_FLOAT(OFS_RETURN) = Master_KeyForName(keyname);
|
|
}
|
|
//void addwantedhostcachekey(string key) = #623;
|
|
void QCBUILTIN PF_cl_addwantedhostcachekey(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
PF_cl_gethostcacheindexforkey(prinst, pr_globals);
|
|
}
|
|
|
|
void QCBUILTIN PF_cl_getextresponse(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
//this does something weird
|
|
G_INT(OFS_RETURN) = 0;
|
|
}
|
|
#else
|
|
void QCBUILTIN PF_cl_gethostcachevalue (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals){G_FLOAT(OFS_RETURN) = 0;}
|
|
void QCBUILTIN PF_cl_gethostcachestring (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) {G_INT(OFS_RETURN) = 0;}
|
|
//void resethostcachemasks(void) = #615;
|
|
void QCBUILTIN PF_cl_resethostcachemasks(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals){}
|
|
//void sethostcachemaskstring(float mask, float fld, string str, float op) = #616;
|
|
void QCBUILTIN PF_cl_sethostcachemaskstring(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals){}
|
|
//void sethostcachemasknumber(float mask, float fld, float num, float op) = #617;
|
|
void QCBUILTIN PF_cl_sethostcachemasknumber(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals){}
|
|
//void resorthostcache(void) = #618;
|
|
void QCBUILTIN PF_cl_resorthostcache(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals){}
|
|
//void sethostcachesort(float fld, float descending) = #619;
|
|
void QCBUILTIN PF_cl_sethostcachesort(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals){}
|
|
//void refreshhostcache(void) = #620;
|
|
void QCBUILTIN PF_cl_refreshhostcache(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) {}
|
|
//float gethostcachenumber(float fld, float hostnr) = #621;
|
|
void QCBUILTIN PF_cl_gethostcachenumber(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals){G_FLOAT(OFS_RETURN) = 0;}
|
|
//float gethostcacheindexforkey(string key) = #622;
|
|
void QCBUILTIN PF_cl_gethostcacheindexforkey(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals){G_FLOAT(OFS_RETURN) = 0;}
|
|
//void addwantedhostcachekey(string key) = #623;
|
|
void QCBUILTIN PF_cl_addwantedhostcachekey(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals){}
|
|
#endif
|
|
|
|
|
|
void QCBUILTIN PF_shaderforname (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
const char *str = PR_GetStringOfs(prinst, OFS_PARM0);
|
|
const char *defaultbody = PF_VarString(prinst, 1, pr_globals);
|
|
|
|
shader_t *shad;
|
|
|
|
if (*defaultbody)
|
|
shad = R_RegisterShader(str, SUF_NONE, defaultbody);
|
|
else
|
|
shad = R_RegisterSkin(str, NULL);
|
|
if (shad)
|
|
G_FLOAT(OFS_RETURN) = shad->id+1;
|
|
else
|
|
G_FLOAT(OFS_RETURN) = 0;
|
|
}
|
|
|
|
void QCBUILTIN PF_cl_GetBindMap (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
int bm[2];
|
|
Key_GetBindMap(bm);
|
|
G_VECTOR(OFS_RETURN)[0] = bm[0];
|
|
G_VECTOR(OFS_RETURN)[1] = bm[1];
|
|
G_VECTOR(OFS_RETURN)[2] = 0;
|
|
}
|
|
void QCBUILTIN PF_cl_SetBindMap (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
int bm[2] =
|
|
{
|
|
G_FLOAT(OFS_PARM0+0),
|
|
G_FLOAT(OFS_PARM0+1)
|
|
};
|
|
Key_SetBindMap(bm);
|
|
G_FLOAT(OFS_RETURN) = 1;
|
|
}
|
|
|
|
//void setmousetarget(float trg) = #603;
|
|
void QCBUILTIN PF_cl_setmousetarget (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
world_t *world = prinst->parms->user;
|
|
unsigned int target = world->keydestmask;
|
|
switch ((int)G_FLOAT(OFS_PARM0))
|
|
{
|
|
case 1: //1 is delta-based (mt_menu).
|
|
key_dest_absolutemouse &= ~target;
|
|
break;
|
|
case 2: //2 is absolute (mt_client).
|
|
key_dest_absolutemouse |= target;
|
|
break;
|
|
default:
|
|
PR_BIError(prinst, "PF_setmousetarget: not a valid destination\n");
|
|
}
|
|
}
|
|
|
|
//float getmousetarget(void) = #604;
|
|
void QCBUILTIN PF_cl_getmousetarget (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
world_t *world = prinst->parms->user;
|
|
unsigned int target = world->keydestmask;
|
|
G_FLOAT(OFS_RETURN) = (key_dest_absolutemouse&target)?2:1;
|
|
}
|
|
|
|
//evil builtins to pretend to be a server.
|
|
void QCBUILTIN PF_cl_sprint (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
//this is a bit pointless for menus as it doesn't know player names or anything.
|
|
#ifndef CLIENTONLY
|
|
int clientnum = G_FLOAT(OFS_PARM0);
|
|
const char *str = PF_VarString(prinst, 1, pr_globals);
|
|
if (sv.active && clientnum < sv.allocated_client_slots && svs.clients[clientnum].state >= cs_connected)
|
|
SV_PrintToClient(&svs.clients[clientnum], PRINT_HIGH, str);
|
|
#endif
|
|
}
|
|
void QCBUILTIN PF_cl_bprint (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
#ifndef CLIENTONLY
|
|
const char *str = PF_VarString(prinst, 0, pr_globals);
|
|
if (sv.active)
|
|
SV_BroadcastPrintf(PRINT_HIGH, "%s", str);
|
|
#endif
|
|
}
|
|
void QCBUILTIN PF_cl_clientcount (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
#ifndef CLIENTONLY
|
|
if (sv.active)
|
|
G_FLOAT(OFS_RETURN) = sv.allocated_client_slots;
|
|
else
|
|
G_FLOAT(OFS_RETURN) = 0;
|
|
#endif
|
|
}
|
|
|
|
void QCBUILTIN PF_cl_localsound(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
const char * s = PR_GetStringOfs(prinst, OFS_PARM0);
|
|
float chan = (prinst->callargc>=1)?G_FLOAT(OFS_PARM1):0;
|
|
float vol = (prinst->callargc>=2)?G_FLOAT(OFS_PARM2):1;
|
|
|
|
S_LocalSound2(s, chan, vol);
|
|
}
|
|
|
|
void QCBUILTIN PF_cl_getgamedirinfo(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{ //IMPLEMENTME
|
|
// int diridx = G_FLOAT(OFS_PARM0);
|
|
// int propidx = G_FLOAT(OFS_PARM1);
|
|
|
|
//propidx 0 == name
|
|
//propidx 1 == description (contents of modinfo.txt)
|
|
G_INT(OFS_RETURN) = 0;
|
|
}
|
|
|
|
#endif
|