stripped support for qvm-based plugins. rewrote native plugins to use a more efficient interface.

merged engine menus, native menus, game menus, plugin menus into a single layered menu interface, simplifying all the special-case input.
engine confirmation prompts can now show regardless of underlaying menus, including above the console.
skeletal formats can now provide their own way to build bones, for variable per-bone keyframes/interpolation methods/etc (used by gltf2).
updated various plugins for the new api.
removed qvm makefiles/scripts.


git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5530 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2019-09-04 07:59:40 +00:00
parent 6f00bc8e8a
commit d561772bb0
116 changed files with 4885 additions and 6715 deletions

View File

@ -94,7 +94,7 @@ IF(NOT PNG_FOUND)
MESSAGE(WARNING "libpng library NOT available. Good luck with screenshots.")
SET(FTE_LIB_DEFINES ${FTE_LIB_DEFINES};NO_PNG)
ENDIF()
FIND_PACKAGE(Freetype)
IF(FREETYPE_FOUND)
INCLUDE_DIRECTORIES( ${FREETYPE_INCLUDE_DIRS} )
@ -708,7 +708,6 @@ ELSE()
FIND_PACKAGE(Bullet)
IF (BULLET_FOUND)
ADD_LIBRARY(bullet MODULE
plugins/qvm_api.c
plugins/plugin.c
plugins/bullet/bulletplug.cpp
)
@ -850,7 +849,22 @@ ELSE()
SET(INSTALLTARGS ${INSTALLTARGS} fteqccgui)
ELSE()
FIND_PACKAGE(Qt5Widgets)
IF (Qt5Widgets_FOUND)
FIND_PATH(QSCINTILLA_INCLUDE_DIR
NAMES Qsci/qsciglobal.h
PATHS ${Qt5Widgets_INCLUDE_DIRS}
PATH_SUFFIXES Qsci
)
FIND_LIBRARY(QSCINTILLA_LIBRARY
NAMES qscintilla2_qt5
PATHS
${QT_LIBRARY_DIR}
/usr/local/lib
/usr/local/lib/qt5
/usr/lib
)
IF (QSCINTILLA_INCLUDE_DIR AND QSCINTILLA_LIBRARY AND Qt5Widgets_FOUND)
ADD_EXECUTABLE(fteqccgui
engine/qclib/qccguiqt.cpp
engine/qclib/qccguistuff.c
@ -864,10 +878,12 @@ ELSE()
engine/qclib/packager.c
engine/qclib/qcd_main.c
)
TARGET_INCLUDE_DIRECTORIES(fteqccgui PUBLIC ${Qt5Widgets_INCLUDE_DIRS})
TARGET_INCLUDE_DIRECTORIES(fteqccgui PUBLIC ${Qt5Widgets_INCLUDE_DIRS} ${QSCINTILLA_INCLUDE_DIR})
SET_TARGET_PROPERTIES(fteqccgui PROPERTIES COMPILE_DEFINITIONS "${FTE_LIB_DEFINES};${FTE_REVISON};${Qt5Widgets_COMPILE_DEFINITIONS}")
SET_PROPERTY(TARGET fteqccgui PROPERTY POSITION_INDEPENDENT_CODE TRUE)
TARGET_LINK_LIBRARIES(fteqccgui ${ZLIB_LIBRARIES} ${Qt5Widgets_LIBRARIES} qscintilla2_qt5)
TARGET_LINK_LIBRARIES(fteqccgui ${ZLIB_LIBRARIES} ${Qt5Widgets_LIBRARIES} ${QSCINTILLA_LIBRARY})
ELSE()
MESSAGE(WARNING "qscintilla/qt5widgets library not detected, no fteqccgui for you")
SET(INSTALLTARGS ${INSTALLTARGS} fteqccgui)
ENDIF()
ENDIF()
@ -875,7 +891,6 @@ ENDIF()
#Quake Injector Alike plugin
ADD_LIBRARY(qi MODULE
plugins/qvm_api.c
plugins/plugin.c
plugins/qi/qi.c
plugins/emailnot/md5.c
@ -892,7 +907,6 @@ FIND_PATH(LIBODE_INCLUDE_DIR ode/ode.h)
FIND_LIBRARY(LIBODE_LIBRARY ode)
IF (LIBODE_INCLUDE_DIR)
ADD_LIBRARY(ode MODULE
plugins/qvm_api.c
plugins/plugin.c
engine/common/com_phys_ode.c
engine/common/mathlib.c
@ -907,7 +921,6 @@ ENDIF()
#EzQuake Hud port plugin
ADD_LIBRARY(ezhud MODULE
plugins/qvm_api.c
plugins/plugin.c
plugins/ezhud/ezquakeisms.c
plugins/ezhud/hud.c
@ -920,9 +933,30 @@ SET_TARGET_PROPERTIES(ezhud PROPERTIES LINK_FLAGS "-Wl,--no-undefined")
TARGET_LINK_LIBRARIES(ezhud m)
SET(INSTALLTARGS ${INSTALLTARGS} ezhud)
#NameMaker string generation plugin
ADD_LIBRARY(namemaker MODULE
plugins/plugin.c
plugins/namemaker/namemaker.c
)
SET_TARGET_PROPERTIES(namemaker PROPERTIES COMPILE_DEFINITIONS "${FTE_LIB_DEFINES}")
SET_TARGET_PROPERTIES(namemaker PROPERTIES PREFIX "fteplug_")
SET_TARGET_PROPERTIES(namemaker PROPERTIES LINK_FLAGS "-Wl,--no-undefined")
TARGET_LINK_LIBRARIES(namemaker m)
SET(INSTALLTARGS ${INSTALLTARGS} namemaker)
#Terrain Generation plugin
ADD_LIBRARY(terrorgen MODULE
plugins/plugin.c
plugins/terrorgen/terragen.c
)
SET_TARGET_PROPERTIES(terrorgen PROPERTIES COMPILE_DEFINITIONS "FTEPLUGIN;${FTE_LIB_DEFINES}")
SET_TARGET_PROPERTIES(terrorgen PROPERTIES PREFIX "fteplug_")
SET_TARGET_PROPERTIES(terrorgen PROPERTIES LINK_FLAGS "-Wl,--no-undefined")
TARGET_LINK_LIBRARIES(terrorgen m)
SET(INSTALLTARGS ${INSTALLTARGS} terrorgen)
#IRC client plugin
ADD_LIBRARY(irc MODULE
plugins/qvm_api.c
plugins/plugin.c
plugins/irc/ircclient.c
)
@ -934,10 +968,10 @@ SET(INSTALLTARGS ${INSTALLTARGS} irc)
#model formats plugin
ADD_LIBRARY(models MODULE
plugins/qvm_api.c
plugins/plugin.c
plugins/models/models.c
plugins/models/gltf.c
plugins/models/exportiqm.c
)
SET_TARGET_PROPERTIES(models PROPERTIES COMPILE_DEFINITIONS "FTEPLUGIN;${FTE_LIB_DEFINES}")
SET_TARGET_PROPERTIES(models PROPERTIES PREFIX "fteplug_")
@ -945,20 +979,22 @@ SET_TARGET_PROPERTIES(models PROPERTIES LINK_FLAGS "-Wl,--no-undefined")
TARGET_LINK_LIBRARIES(models m)
SET(INSTALLTARGS ${INSTALLTARGS} models)
#x11 server plugin (note: for displaying other programs)
ADD_LIBRARY(x11 MODULE
plugins/qvm_api.c
plugins/plugin.c
plugins/xsv/m_x.c
plugins/xsv/x_reqs.c
plugins/xsv/x_res.c
engine/qclib/hash.c
)
SET_TARGET_PROPERTIES(x11 PROPERTIES COMPILE_DEFINITIONS "FTEPLUGIN;${FTE_LIB_DEFINES}")
SET_TARGET_PROPERTIES(x11 PROPERTIES PREFIX "fteplug_")
SET_TARGET_PROPERTIES(x11 PROPERTIES LINK_FLAGS "-Wl,--no-undefined")
TARGET_LINK_LIBRARIES(x11 m)
SET(INSTALLTARGS ${INSTALLTARGS} x11)
IF(0)
#x11 server plugin (note: for displaying other programs)
#not stable enough, and probably won't ever be
ADD_LIBRARY(x11sv MODULE
plugins/plugin.c
plugins/xsv/m_x.c
plugins/xsv/x_reqs.c
plugins/xsv/x_res.c
engine/qclib/hash.c
)
SET_TARGET_PROPERTIES(x11sv PROPERTIES COMPILE_DEFINITIONS "FTEPLUGIN;${FTE_LIB_DEFINES}")
SET_TARGET_PROPERTIES(x11sv PROPERTIES PREFIX "fteplug_")
SET_TARGET_PROPERTIES(x11sv PROPERTIES LINK_FLAGS "-Wl,--no-undefined")
TARGET_LINK_LIBRARIES(x11sv m)
SET(INSTALLTARGS ${INSTALLTARGS} x11sv)
ENDIF()
#ffmpeg client plugin. no proper way to detect dependancies right now, so I've gotta try the manual way.
FIND_PATH(AVCODEC_INCLUDE_DIR libavcodec/avcodec.h)
@ -972,7 +1008,6 @@ IF((AVFORMAT_INCLUDE_DIR) AND (AVSWSCALE_INCLUDE_DIR))
FIND_LIBRARY(AVSWSCALE_LIBRARY swscale)
ADD_LIBRARY(ffmpeg MODULE
plugins/qvm_api.c
plugins/plugin.c
plugins/avplug/avaudio.c
plugins/avplug/avdecode.c
@ -988,10 +1023,11 @@ ELSE()
MESSAGE(WARNING "ffmpeg library NOT available. Quake shouldn't be playing fmv anyway.")
ENDIF()
#TODO: cef plugin
IF(NOT ANDROID)
#XMPP/jabber client plugin
ADD_LIBRARY(xmpp MODULE
plugins/qvm_api.c
plugins/plugin.c
plugins/jabber/jabberclient.c
plugins/jabber/xml.c
@ -1016,5 +1052,3 @@ INSTALL(TARGETS ${INSTALLTARGS}
RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}${FTE_INSTALL_BINDIR}"
LIBRARY DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}"
)
#cef plugin

View File

@ -64,6 +64,7 @@ struct menu_inputevent_args_s
MIE_KEYUP = 1,
MIE_MOUSEDELTA = 2,
MIE_MOUSEABS = 3,
MIE_JOYAXIS = 4,
} eventtype;
unsigned int devid;
union
@ -78,6 +79,11 @@ struct menu_inputevent_args_s
float delta[2];
float screen[2]; //virtual coords
} mouse;
struct
{
unsigned int axis;
float val;
} axis;
};
};
@ -159,9 +165,10 @@ typedef struct {
void (*renderscene) (menuscene_t *scene);
// Menu specific stuff
qboolean (*setkeydest) (qboolean focused); //returns whether it changed.
int (*getkeydest) (void); //returns 0 if unfocused, -1 if active-but-unfocused, 1 if focused-and-active.
int (*setmousetarget) (const char *cursorname, float hot_x, float hot_y, float scale); //forces absolute mouse coords whenever cursorname isn't NULL
void (*pushmenu) (void *ctx); //will have key focus.
qboolean (*ismenupushed) (void *ctx); //reports if its still pushed (but not necessarily the active one!).
void (*killmenu) (void *ctx); //force-removes a menu.
int (*setmousecursor) (const char *cursorname, float hot_x, float hot_y, float scale); //forces absolute mouse coords whenever cursorname isn't NULL
const char *(*keynumtostring) (int keynum, int modifier);
int (*stringtokeynum) (const char *key, int *modifier);
int (*findkeysforcommand) (int bindmap, const char *command, int *out_scancodes, int *out_modifiers, int keycount);
@ -185,11 +192,13 @@ typedef struct {
void (*Init) (mintreason_t reason, float vwidth, float vheight, int pwidth, int pheight);
void (*Shutdown) (mintreason_t reason);
void (*Draw) (double frametime);
void (*DrawLoading) (double frametime);
void (*DrawLoading) (double frametime); //pure loading screen.
void (*Toggle) (int wantmode);
int (*InputEvent) (struct menu_inputevent_args_s ev);
qboolean(*ConsoleCommand) (const char *cmdline, int argc, char const*const*argv);
void (*Draw) (void *ctx, double frametime); //draws a menu.
qboolean(*InputEvent) (void *ctx, struct menu_inputevent_args_s ev); //return true to prevent the engine handling it (ie: because you already did).
void (*Closed) (void *ctx); //a pushed menu was closed.
} menu_export_t;
#ifndef NATIVEEXPORT

View File

@ -1081,10 +1081,10 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
break;
case CG_KEY_GETCATCHER:
VM_LONG(ret) = keycatcher;
VM_LONG(ret) = Q3_GetKeyCatcher();
break;
case CG_KEY_SETCATCHER:
keycatcher = VM_LONG(arg[0]);
Q3_SetKeyCatcher(VM_LONG(arg[0]));
break;
case CG_GETGLCONFIG:
@ -1313,7 +1313,7 @@ int CG_Refresh(void)
void CG_Stop (void)
{
keycatcher &= ~2;
Q3_SetKeyCatcher(Q3_GetKeyCatcher()&~2);
if (cgvm)
{
VM_Call(cgvm, CG_SHUTDOWN);
@ -1380,7 +1380,8 @@ void CG_Command_f(void)
qboolean CG_KeyPress(int key, int unicode, int down)
{
if (!cgvm || !(keycatcher&8))
int catcher = Q3_GetKeyCatcher();
if (!cgvm || !(catcher&8))
return false;
return VM_Call(cgvm, CG_KEY_EVENT, key, down);
}

View File

@ -547,8 +547,7 @@ qboolean CL_GetDemoMessage (void)
{ //start the timer only once we are connected.
//make sure everything is loaded, to avoid stalls
if (Key_Dest_Has(kdm_gmenu))
MP_Toggle(0);
Menu_PopAll();
COM_WorkerFullSync();
cls.td_starttime = Sys_DoubleTime();
@ -556,7 +555,6 @@ qboolean CL_GetDemoMessage (void)
//force the console up, we're done loading.
Key_Dest_Remove(kdm_console);
Key_Dest_Remove(kdm_emenu);
scr_con_current = 0;
}
@ -2619,7 +2617,7 @@ void CL_QTVPoll (void)
qboolean streamavailable = false;
qboolean saidheader = false;
#ifndef NOBUILTINMENUS
menu_t *sourcesmenu = NULL;
emenu_t *sourcesmenu = NULL;
#endif
int sourcenum = 0;
@ -2794,7 +2792,6 @@ void CL_QTVPoll (void)
//now put it on a menu
if (!sourcesmenu)
{
Key_Dest_Add(kdm_emenu);
sourcesmenu = M_CreateMenu(0);
MC_AddPicture(sourcesmenu, 16, 4, 32, 144, "gfx/qplaque.lmp");

View File

@ -35,6 +35,8 @@ extern cvar_t cl_item_bobbing;
extern cvar_t r_rocketlight;
extern cvar_t r_lightflicker;
extern cvar_t r_dimlight_colour;
extern cvar_t r_brightlight_colour;
extern cvar_t cl_r2g;
extern cvar_t r_powerupglow;
extern cvar_t v_powerupshell;
@ -1396,7 +1398,7 @@ entity_state_t *CL_FindOldPacketEntity(int num)
#ifdef NQPROT
void DP5_ParseDelta(entity_state_t *s, packet_entities_t *pack)
{
int bits;
unsigned int bits;
if (cl_shownet.ival >= 3)
Con_Printf("%3i: Update %i", msg_readcount, s->number);
@ -3992,17 +3994,13 @@ void CL_LinkPacketEntities (void)
if (state->effects & EF_BRIGHTLIGHT)
{
radius = max(radius,400);
colour[0] += 2.0;
colour[1] += 1.0;
colour[2] += 0.5;
radius = max(radius,r_dimlight_colour.vec4[3]);
VectorAdd(colour, r_dimlight_colour.vec4, colour);
}
if (state->effects & EF_DIMLIGHT)
{
radius = max(radius,200);
colour[0] += 2.0;
colour[1] += 1.0;
colour[2] += 0.5;
radius = max(radius,r_dimlight_colour.vec4[3]);
VectorAdd(colour, r_dimlight_colour.vec4, colour);
}
if (state->effects & EF_BLUE)
{
@ -4415,12 +4413,8 @@ void CL_LinkPacketEntities (void)
if (r_rocketlight.value && (modelflags & MF_ROCKET) && !(state->lightpflags & (PFLAGS_FULLDYNAMIC|PFLAGS_CORONA)))
{
float rad = 0;
vec3_t dclr;
dclr[0] = 2.0;
dclr[1] = 1.0;
dclr[2] = 0.25;
rad = 200;
extern cvar_t r_rocketlight_colour;
rad = r_rocketlight_colour.vec4[3];
rad += r_lightflicker.value?((flicker + state->number)&31):0;
dl = CL_AllocDlight (state->number);
@ -4430,7 +4424,7 @@ void CL_LinkPacketEntities (void)
if (modelflags & MF_ROCKET)
dl->origin[2] += 1; // is this even necessary
dl->radius = rad * r_rocketlight.value;
VectorCopy(dclr, dl->color);
VectorCopy(r_rocketlight_colour.vec4, dl->color);
}
}
}
@ -4856,7 +4850,7 @@ void CLQW_ParsePlayerinfo (void)
#ifdef PEXT_SCALE
if ((flags & PF_SCALE) && (cls.fteprotocolextensions & PEXT_SCALE))
state->scale = (float)MSG_ReadByte()/50;
state->scale = MSG_ReadByte()/50.0;
#endif
#ifdef PEXT_TRANS
if ((flags & PF_TRANS) && (cls.fteprotocolextensions & PEXT_TRANS))
@ -4864,7 +4858,7 @@ void CLQW_ParsePlayerinfo (void)
#endif
#ifdef PEXT_FATNESS
if ((flags & PF_FATNESS) && (cls.fteprotocolextensions & PEXT_FATNESS))
state->fatness = (float)MSG_ReadChar();
state->fatness = MSG_ReadChar();
#endif
#ifdef PEXT_HULLSIZE
if ((cls.fteprotocolextensions & PEXT_HULLSIZE) && (flags & PF_HULLSIZE_Z))
@ -5642,7 +5636,9 @@ void CL_SetSolidEntities (void)
model_t *mod;
VALGRIND_MAKE_MEM_UNDEFINED(&pmove, sizeof(pmove));
#ifdef CSQC_DAT
pmove.world = &csqc_world;
#endif
memset(&pmove.physents[0], 0, sizeof(physent_t));
pmove.physents[0].model = cl.worldmodel;

View File

@ -5536,7 +5536,7 @@ done:
if (!(f->flags & HRF_ACTION))
{
Key_Dest_Remove(kdm_console);
M_Menu_Prompt(Host_RunFilePrompted, f, va("Exec %s?\n", COM_SkipPath(f->fname)), "Yes", NULL, "Cancel");
Menu_Prompt(Host_RunFilePrompted, f, va("Exec %s?\n", COM_SkipPath(f->fname)), "Yes", NULL, "Cancel");
return;
}
if (f->flags & HRF_OPENED)
@ -5636,7 +5636,7 @@ done:
if (!(f->flags & HRF_ACTION))
{
Key_Dest_Remove(kdm_console);
M_Menu_Prompt(Host_RunFilePrompted, f, va("File already exists.\nWhat would you like to do?\n%s\n", displayname), "Overwrite", "Run old", "Cancel");
Menu_Prompt(Host_RunFilePrompted, f, va("File already exists.\nWhat would you like to do?\n%s\n", displayname), "Overwrite", "Run old", "Cancel");
return;
}
}
@ -5645,7 +5645,7 @@ done:
if (!(f->flags & HRF_ACTION))
{
Key_Dest_Remove(kdm_console);
M_Menu_Prompt(Host_RunFilePrompted, f, va("File appears new.\nWould you like to install\n%s\n", displayname), "Install!", "", "Cancel");
Menu_Prompt(Host_RunFilePrompted, f, va("File appears new.\nWould you like to install\n%s\n", displayname), "Install!", "", "Cancel");
return;
}
}
@ -5878,20 +5878,12 @@ double Host_Frame (double time)
if (startuppending)
CL_StartCinematicOrMenu();
#ifdef PLUGINS
Plug_Tick();
#endif
NET_Tick();
if (cl.paused)
cl.gametimemark += time;
//if we're at a menu/console/thing
idle = Key_Dest_Has_Higher(kdm_gmenu);
#ifdef VM_UI
idle |= UI_MenuState() != 0;
#endif
idle = ((cls.state == ca_disconnected) || cl.paused) && !idle; //idle if we're disconnected/paused and not at a menu
idle = !Key_Dest_Has_Higher(kdm_menu);
idle = ((cls.state == ca_disconnected) || cl.paused) && idle; //idle if we're disconnected/paused and not at a menu
idle |= !vid.activeapp; //always idle when tabbed out
//read packets early and always, so we don't have stuff waiting for reception quite so often.
@ -5924,6 +5916,11 @@ double Host_Frame (double time)
}
}
#ifdef PLUGINS
Plug_Tick();
#endif
NET_Tick();
/*
if (cl_maxfps.value)
fps = cl_maxfps.value;//max(30.0, min(cl_maxfps.value, 72.0));
@ -6285,7 +6282,7 @@ void CL_StartCinematicOrMenu(void)
#endif
}
if (!sv_state && !cls.demoinfile && !cls.state && !*cls.servername && !Media_PlayingFullScreen())
if (!sv_state && !cls.demoinfile && !cls.state && !*cls.servername)
{
TP_ExecTrigger("f_startup", true);
Cbuf_Execute ();
@ -6293,7 +6290,7 @@ void CL_StartCinematicOrMenu(void)
//and any startup cinematics
#ifdef HAVE_MEDIA_DECODER
if (!sv_state && !cls.demoinfile && !cls.state && !*cls.servername && !Media_PlayingFullScreen())
if (!sv_state && !cls.demoinfile && !cls.state && !*cls.servername)
{
int ol_depth;
int idcin_depth;
@ -6324,20 +6321,20 @@ void CL_StartCinematicOrMenu(void)
}
#endif
if (!sv_state && !cls.demoinfile && !cls.state && !*cls.servername && !Media_PlayingFullScreen())
if (!sv_state && !cls.demoinfile && !cls.state && !*cls.servername)
{
if (qrenderer > QR_NONE && !Key_Dest_Has(kdm_emenu))
if (qrenderer > QR_NONE && !Key_Dest_Has(kdm_menu))
{
#ifndef NOBUILTINMENUS
if (!cls.state && !Key_Dest_Has(kdm_emenu) && !*FS_GetGamedir(false))
if (!cls.state && !Key_Dest_Has(kdm_menu) && !*FS_GetGamedir(false))
M_Menu_Mods_f();
#endif
if (!cls.state && !Key_Dest_Has(kdm_emenu) && cl_demoreel.ival)
if (!cls.state && !Key_Dest_Has(kdm_menu) && cl_demoreel.ival)
{
cls.demonum = 0;
CL_NextDemo();
}
if (!cls.state && !Key_Dest_Has(kdm_emenu))
if (!cls.state && !Key_Dest_Has(kdm_menu))
//if we're (now) meant to be using csqc for menus, make sure that its running.
if (!CSQC_UnconnectedInit())
M_ToggleMenu_f();

View File

@ -2842,6 +2842,7 @@ static void CLDP_ParseDownloadBegin(char *s)
if (!dl || strcmp(fname, dl->remotename))
{
#ifdef CSQC_DAT
if (cls.demoplayback && !dl && cl_dp_csqc_progssize && size == cl_dp_csqc_progssize && !strcmp(fname, cl_dp_csqc_progsname))
{ //its somewhat common for demos to contain a copy of the csprogs, so that the same version is available when trying to play the demo back.
extern cvar_t cl_download_csprogs, cl_nocsqc;
@ -2857,6 +2858,7 @@ static void CLDP_ParseDownloadBegin(char *s)
return; //silently ignore it
}
else
#endif
{
Con_Printf("Warning: server started sending a file we did not request. Ignoring.\n");
return;
@ -4512,10 +4514,6 @@ static void CLQ2_ParseConfigString (void)
Con_Printf(CON_WARNING "WARNING: Client checksum does not match server checksum (%i != %i)", map_checksum, serverchecksum);
}
}
#ifdef VM_UI
UI_StringChanged(i);
#endif
}
#endif
@ -5720,21 +5718,20 @@ static void CL_MuzzleFlash (int entnum)
if (P_RunParticleEffectType(org, axis[0], 1, pt_muzzleflash))
{
extern cvar_t r_muzzleflash_colour;
extern cvar_t r_muzzleflash_fade;
dl = CL_AllocDlight (dlightkey);
VectorMA (org, 15, axis[0], dl->origin);
memcpy(dl->axis, axis, sizeof(dl->axis));
dl->radius = 200 + (rand()&31);
dl->minlight = 32;
dl->die = cl.time + 0.1;
dl->color[0] = 1.5;
dl->color[1] = 1.3;
dl->color[2] = 1.0;
dl->channelfade[0] = 1.5;
dl->channelfade[1] = 0.75;
dl->channelfade[2] = 0.375;
dl->decay = 1000;
VectorCopy(r_muzzleflash_colour.vec4, dl->color);
dl->radius = r_muzzleflash_colour.vec4[3] + (rand()&31);
VectorCopy(r_muzzleflash_fade.vec4, dl->channelfade);
dl->decay = r_muzzleflash_fade.vec4[3];
#ifdef RTLIGHTS
dl->lightcolourscales[2] = 4;
#endif
@ -7531,9 +7528,6 @@ isilegible:
case svcq2_layout:
s = MSG_ReadString ();
Q_strncpyz (cl.q2layout[seat], s, sizeof(cl.q2layout[seat]));
#ifdef VM_UI
UI_Q2LayoutChanged();
#endif
break;
case svcq2_inventory:
CLQ2_ParseInventory(seat);

File diff suppressed because it is too large Load Diff

View File

@ -943,7 +943,7 @@ void SCR_DrawCursor(void)
char *newc;
int prydoncursornum = 0;
extern qboolean cursor_active;
int cmod = kc_console;
struct key_cursor_s *kcurs;
void *oldcurs = NULL;
if (cursor_active && cl_prydoncursor.ival > 0)
@ -951,48 +951,54 @@ void SCR_DrawCursor(void)
else if (!Key_MouseShouldBeFree())
return;
if ((key_dest_mask & key_dest_absolutemouse & kdm_prompt))
{
if (promptmenu&&promptmenu->cursor)
kcurs = promptmenu->cursor;
else
kcurs = &key_customcursor[kc_console];
}
//choose the cursor based upon the module that has primary focus
if (key_dest_mask & key_dest_absolutemouse & (kdm_console|kdm_cwindows))
cmod = kc_console;
else if ((key_dest_mask & key_dest_absolutemouse & kdm_emenu))
cmod = kc_console;
else if ((key_dest_mask & key_dest_absolutemouse & kdm_gmenu))
cmod = kc_menu;
#ifdef MENU_NATIVECODE
else if ((key_dest_mask & key_dest_absolutemouse & kdm_nmenu))
cmod = kc_nmenu;
#endif
else if (key_dest_mask & key_dest_absolutemouse & (kdm_console|kdm_cwindows))
kcurs = &key_customcursor[kc_console];
else if ((key_dest_mask & key_dest_absolutemouse & kdm_menu))
{
if (topmenu&&topmenu->cursor)
kcurs = topmenu->cursor;
else
kcurs = &key_customcursor[kc_console];
}
else// if (key_dest_mask & key_dest_absolutemouse)
cmod = prydoncursornum?kc_console:kc_game;
kcurs = &key_customcursor[prydoncursornum?kc_console:kc_game];
if (cmod == kc_console)
if (kcurs == &key_customcursor[kc_console])
{
if (!*cl_cursor.string || prydoncursornum>1)
newc = va("gfx/prydoncursor%03i.lmp", prydoncursornum);
else
newc = cl_cursor.string;
if (strcmp(key_customcursor[kc_console].name, newc) || key_customcursor[kc_console].hotspot[0] != cl_cursorbiasx.value || key_customcursor[kc_console].hotspot[1] != cl_cursorbiasy.value || key_customcursor[kc_console].scale != cl_cursorscale.value)
if (strcmp(kcurs->name, newc) || kcurs->hotspot[0] != cl_cursorbiasx.value || kcurs->hotspot[1] != cl_cursorbiasy.value || kcurs->scale != cl_cursorscale.value)
{
key_customcursor[kc_console].dirty = true;
Q_strncpyz(key_customcursor[cmod].name, newc, sizeof(key_customcursor[cmod].name));
key_customcursor[kc_console].hotspot[0] = cl_cursorbiasx.value;
key_customcursor[kc_console].hotspot[1] = cl_cursorbiasy.value;
key_customcursor[kc_console].scale = cl_cursorscale.value;
kcurs->dirty = true;
Q_strncpyz(kcurs->name, newc, sizeof(kcurs->name));
kcurs->hotspot[0] = cl_cursorbiasx.value;
kcurs->hotspot[1] = cl_cursorbiasy.value;
kcurs->scale = cl_cursorscale.value;
}
}
if (key_customcursor[cmod].dirty)
if (kcurs->dirty)
{
if (key_customcursor[cmod].scale <= 0 || !*key_customcursor[cmod].name)
if (kcurs->scale <= 0 || !*kcurs->name)
{
key_customcursor[cmod].hotspot[0] = cl_cursorbiasx.value;
key_customcursor[cmod].hotspot[1] = cl_cursorbiasy.value;
key_customcursor[cmod].scale = cl_cursorscale.value;
kcurs->hotspot[0] = cl_cursorbiasx.value;
kcurs->hotspot[1] = cl_cursorbiasy.value;
kcurs->scale = cl_cursorscale.value;
}
key_customcursor[cmod].dirty = false;
oldcurs = key_customcursor[cmod].handle;
if (rf->VID_CreateCursor && strcmp(key_customcursor[cmod].name, "none"))
kcurs->dirty = false;
oldcurs = kcurs->handle;
if (rf->VID_CreateCursor && strcmp(kcurs->name, "none"))
{
image_t dummytex;
flocation_t loc;
@ -1003,16 +1009,16 @@ void SCR_DrawCursor(void)
void *filedata = NULL;
int filelen = 0, width, height;
key_customcursor[cmod].handle = NULL;
kcurs->handle = NULL;
memset(&dummytex, 0, sizeof(dummytex));
dummytex.flags = IF_NOREPLACE; //no dds files
*bestname = 0;
//first try the named image, if possible
if (!filedata && *key_customcursor[cmod].name)
if (!filedata && *kcurs->name)
{
dummytex.ident = key_customcursor[cmod].name;
dummytex.ident = kcurs->name;
if (Image_LocateHighResTexture(&dummytex, &loc, bestname, sizeof(bestname), &bestflags))
filelen = FS_LoadFile(bestname, &filedata);
}
@ -1050,7 +1056,7 @@ void SCR_DrawCursor(void)
#undef W
#undef B
};
key_customcursor[cmod].handle = rf->VID_CreateCursor(lamecursor, 8, 15, PTI_LLLA8, 0, 0, 1); //try the fallback
kcurs->handle = rf->VID_CreateCursor(lamecursor, 8, 15, PTI_LLLA8, 0, 0, 1); //try the fallback
}
else if (!filedata)
FS_FreeFile(filedata); //format not okay, just free it.
@ -1088,18 +1094,18 @@ void SCR_DrawCursor(void)
format = (format==PTI_LLLX8)?PTI_LLLA8:PTI_RGBA8;
}
key_customcursor[cmod].handle = rf->VID_CreateCursor(rgbadata, width, height, format, key_customcursor[cmod].hotspot[0], key_customcursor[cmod].hotspot[1], key_customcursor[cmod].scale); //try the fallback
kcurs->handle = rf->VID_CreateCursor(rgbadata, width, height, format, kcurs->hotspot[0], kcurs->hotspot[1], kcurs->scale); //try the fallback
BZ_Free(rgbadata);
}
}
}
else
key_customcursor[cmod].handle = NULL;
kcurs->handle = NULL;
}
if (scr_curcursor != key_customcursor[cmod].handle)
if (scr_curcursor != kcurs->handle)
{
scr_curcursor = key_customcursor[cmod].handle;
scr_curcursor = kcurs->handle;
rf->VID_SetCursor(scr_curcursor);
}
if (oldcurs)
@ -1109,16 +1115,16 @@ void SCR_DrawCursor(void)
return;
//system doesn't support a hardware cursor, so try to draw a software one.
if (!strcmp(key_customcursor[cmod].name, "none"))
if (!strcmp(kcurs->name, "none"))
return;
p = R2D_SafeCachePic(key_customcursor[cmod].name);
p = R2D_SafeCachePic(kcurs->name);
if (!p || !R_GetShaderSizes(p, NULL, NULL, false))
p = R2D_SafeCachePic("gfx/cursor.lmp");
if (p && R_GetShaderSizes(p, NULL, NULL, false))
{
R2D_ImageColours(1, 1, 1, 1);
R2D_Image(mousecursor_x-key_customcursor[cmod].hotspot[0], mousecursor_y-key_customcursor[cmod].hotspot[1], p->width*cl_cursorscale.value, p->height*cl_cursorscale.value, 0, 0, 1, 1, p);
R2D_Image(mousecursor_x-kcurs->hotspot[0], mousecursor_y-kcurs->hotspot[1], p->width*cl_cursorscale.value, p->height*cl_cursorscale.value, 0, 0, 1, 1, p);
}
else
{
@ -1905,7 +1911,7 @@ void SCR_DrawPause (void)
return;
#endif
if (Key_Dest_Has(kdm_emenu) || Key_Dest_Has(kdm_gmenu))
if (Key_Dest_Has(kdm_menu))
return;
pic = R2D_SafeCachePic ("gfx/pause.lmp");
@ -2305,7 +2311,7 @@ void SCR_SetUpToDrawConsole (void)
// Key_Dest_Add(kdm_console);
scr_con_target = scr_con_current = vid.height * fullscreenpercent;
}
else if (!startuppending && !Key_Dest_Has(kdm_emenu|kdm_gmenu) && (!Key_Dest_Has(~((!con_stayhidden.ival?kdm_console:0)|kdm_game))) && SCR_GetLoadingStage() == LS_NONE && cls.state < ca_active && !Media_PlayingFullScreen() && !CSQC_UnconnectedOkay(false))
else if (!startuppending && !Key_Dest_Has(kdm_menu) && (!Key_Dest_Has(~((!con_stayhidden.ival?kdm_console:0)|kdm_prompt|kdm_game))) && SCR_GetLoadingStage() == LS_NONE && cls.state < ca_active && !CSQC_UnconnectedOkay(false))
{
//go fullscreen if we're not doing anything
if (con_curwindow && !cls.state && !scr_drawloading && !Key_Dest_Has(kdm_console))
@ -2314,7 +2320,7 @@ void SCR_SetUpToDrawConsole (void)
scr_con_target = 0; // not looking at an normal console
}
#ifdef VM_UI
else if (UI_MenuState() || UI_OpenMenu())
else if (UI_OpenMenu())
scr_con_current = scr_con_target = 0; //force instantly hidden.
#endif
else
@ -2329,7 +2335,7 @@ void SCR_SetUpToDrawConsole (void)
{
if (CL_TryingToConnect()) //if we're trying to connect, make sure there's a loading/connecting screen showing instead of forcing the menu visible
SCR_SetLoadingStage(LS_CONNECTION);
else if (!Key_Dest_Has(kdm_emenu) && !startuppending) //don't force anything until the startup stuff has been done
else if (!Key_Dest_Has(kdm_menu) && !startuppending) //don't force anything until the startup stuff has been done
M_ToggleMenu_f();
}
}
@ -2396,7 +2402,7 @@ void SCR_DrawConsole (qboolean noback)
{
if (!scr_con_current)
{
if (!Key_Dest_Has(kdm_console|kdm_gmenu|kdm_emenu))
if (!Key_Dest_Has(kdm_console|kdm_menu))
Con_DrawNotify (); // only draw notify in game
}
Con_DrawConsole (scr_con_current, noback);
@ -3326,7 +3332,7 @@ void SCR_TileClear (int skipbottom)
// The 2d refresh stuff.
void SCR_DrawTwoDimensional(int uimenu, qboolean nohud)
void SCR_DrawTwoDimensional(qboolean nohud)
{
qboolean consolefocused = !!Key_Dest_Has(kdm_console|kdm_cwindows);
RSpeedMark();
@ -3386,19 +3392,14 @@ void SCR_DrawTwoDimensional(int uimenu, qboolean nohud)
if (!consolefocused)
SCR_DrawConsole (false);
#ifdef MENU_DAT
MP_Draw();
#endif
#ifdef MENU_NATIVECODE
if (mn_entry)
mn_entry->Draw(host_frametime);
#endif
M_Draw (uimenu);
Menu_Draw();
//but if the console IS focused, then always show it infront.
if (consolefocused)
SCR_DrawConsole (false);
Prompts_Draw();
SCR_DrawCursor();
SCR_DrawSimMTouchCursor();

View File

@ -240,8 +240,8 @@ typedef struct
trailstate_t *trailstate;
} explosion_t;
explosion_t *cl_explosions;
int cl_explosions_max;
static explosion_t *cl_explosions;
static int cl_explosions_max;
static int explosions_running;
static int beams_running;
@ -271,16 +271,23 @@ static tentmodels_t beamtypes[] =
};
sfx_t *cl_sfx_wizhit;
static sfx_t *cl_sfx_wizhit;
sfx_t *cl_sfx_knighthit;
sfx_t *cl_sfx_tink1;
sfx_t *cl_sfx_ric1;
sfx_t *cl_sfx_ric2;
sfx_t *cl_sfx_ric3;
static sfx_t *cl_sfx_tink1;
static sfx_t *cl_sfx_ric1;
static sfx_t *cl_sfx_ric2;
static sfx_t *cl_sfx_ric3;
sfx_t *cl_sfx_r_exp3;
cvar_t cl_expsprite = CVARFD("cl_expsprite", "1", CVAR_ARCHIVE, "Display a central sprite in explosion effects. QuakeWorld typically does so, NQ mods should not (which is problematic when played with the qw protocol).");
cvar_t r_explosionlight = CVARFC("r_explosionlight", "1", CVAR_ARCHIVE, Cvar_Limiter_ZeroToOne_Callback);
static cvar_t r_explosionlight_colour = CVARF("r_explosionlight_colour", "4.0 2.0 0.5", CVAR_ARCHIVE);
static cvar_t r_explosionlight_fade = CVARF("r_explosionlight_fade", "0.784 0.92 0.48", CVAR_ARCHIVE);
cvar_t r_dimlight_colour = CVARF("r_dimlight_colour", "2.0 1.0 0.5 200", CVAR_ARCHIVE);
cvar_t r_brightlight_colour = CVARF("r_brightlight_colour", "2.0 1.0 0.5 400", CVAR_ARCHIVE);
cvar_t r_rocketlight_colour = CVARF("r_rocketlight_colour", "2.0 1.0 0.25 200", CVAR_ARCHIVE);
cvar_t r_muzzleflash_colour = CVARF("r_muzzleflash_colour", "1.5 1.3 1.0 200", CVAR_ARCHIVE);
cvar_t r_muzzleflash_fade = CVARF("r_muzzleflash_fade", "1.5 0.75 0.375 1000", CVAR_ARCHIVE);
cvar_t cl_truelightning = CVARF("cl_truelightning", "0", CVAR_SEMICHEAT);
static cvar_t cl_beam_trace = CVAR("cl_beam_trace", "0");
static cvar_t cl_legacystains = CVARD("cl_legacystains", "1", "WARNING: this cvar will default to 0 and later removed at some point"); //FIXME: do as the description says!
@ -412,6 +419,13 @@ void CL_InitTEnts (void)
Cvar_Register (&cl_truelightning, "Temporary entity control");
Cvar_Register (&cl_beam_trace, "Temporary entity control");
Cvar_Register (&r_explosionlight, "Temporary entity control");
Cvar_Register (&r_explosionlight_colour, "Temporary entity control");
Cvar_Register (&r_explosionlight_fade, "Temporary entity control");
Cvar_Register (&r_muzzleflash_colour, "Temporary entity control");
Cvar_Register (&r_muzzleflash_fade, "Temporary entity control");
Cvar_Register (&r_dimlight_colour, "Temporary entity control");
Cvar_Register (&r_brightlight_colour, "Temporary entity control");
Cvar_Register (&r_rocketlight_colour, "Temporary entity control");
Cvar_Register (&cl_legacystains, "Temporary entity control");
Cvar_Register (&cl_shaftlight, "Temporary entity control");
@ -1379,12 +1393,8 @@ void CL_ParseTEnt (void)
dl->die = cl.time + 0.75;
dl->decay = dl->radius*2;
dl->color[0] = 4.0;
dl->color[1] = 2.0;
dl->color[2] = 0.5;
dl->channelfade[0] = 0.784;
dl->channelfade[1] = 0.92;
dl->channelfade[2] = 0.48;
VectorCopy(r_explosionlight_colour.vec4, dl->color);
VectorCopy(r_explosionlight_fade.vec4, dl->channelfade);
}

View File

@ -5,7 +5,7 @@
#include "cl_master.h"
#include "shader.h"
int keycatcher;
static int keycatcher;
#define TT_STRING 1 // string
#define TT_LITERAL 2 // literal
@ -29,6 +29,25 @@ typedef struct {
static script_t *scripts;
static int maxscripts;
static unsigned int ui_width, ui_height; //to track when it needs to be restarted (the api has no video mode changed event)
static menu_t uimenu;
void Q3_SetKeyCatcher(int newcatcher)
{
int delta = newcatcher^keycatcher;
keycatcher = newcatcher;
if (delta & 2)
{
uimenu.isopaque = false; //no surprises.
if (newcatcher&2)
Menu_Push(&uimenu, false);
else
Menu_Unlink(&uimenu);
}
}
int Q3_GetKeyCatcher(void)
{
return keycatcher;
}
#define Q3SCRIPTPUNCTUATION "(,{})(\':;=!><&|+-\""
void StripCSyntax (char *s)
{
@ -272,11 +291,6 @@ typedef float m3by3_t[3][3];
static vm_t *uivm;
static char *scr_centerstring;
char *Get_Q2ConfigString(int i);
#define MAX_PINGREQUESTS 32
struct
@ -1049,7 +1063,7 @@ static qintptr_t UI_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
VM_LONG(ret) = keycatcher;
break;
case UI_KEY_SETCATCHER:
keycatcher = VM_LONG(arg[0]);
Q3_SetKeyCatcher(VM_LONG(arg[0]));
break;
case UI_GETGLCONFIG: //get glconfig
@ -1388,41 +1402,6 @@ static qintptr_t UI_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
Q_strncpyz(vi->renderername, q_renderername, sizeof(vi->renderername));
}
break;
case UI_GET_STRING:
{
char *str = NULL;
switch (arg[0])
{
case SID_Q2STATUSBAR:
str = cl.q2statusbar;
break;
case SID_Q2LAYOUT:
str = cl.q2layout;
break;
case SID_CENTERPRINTTEXT:
str = scr_centerstring;
break;
case SID_SERVERNAME:
str = cls.servername;
break;
default:
str = Get_Q2ConfigString(arg[0]);
break;
}
if (!str)
return -1;
if (arg[1] + arg[2] >= mask || VM_POINTER(arg[1]) < offset)
return -1; //out of bounds.
if (strlen(str)>= arg[2])
return -1;
strcpy(VM_POINTER(arg[1]), str); //already made sure buffer is big enough
return strlen(str);
}
*/
case UI_PC_ADD_GLOBAL_DEFINE:
@ -1504,29 +1483,11 @@ static qintptr_t EXPORT_FN UI_SystemCallsNative(qintptr_t arg, ...)
return UI_SystemCalls(NULL, ~(quintptr_t)0, arg, args);
}
qboolean UI_DrawStatusBar(int scores)
static void UI_Release(menu_t *m)
{
return false;
/*
if (!uivm)
return false;
return VM_Call(uivm, UI_DRAWSTATUSBAR, scores);
*/
keycatcher &= ~2;
}
qboolean UI_DrawIntermission(void)
{
return false;
/*
if (!uivm)
return false;
return VM_Call(uivm, UI_INTERMISSION);
*/
}
void UI_DrawMenu(void)
static void UI_DrawMenu(menu_t *m)
{
if (uivm)
{
@ -1537,66 +1498,12 @@ void UI_DrawMenu(void)
VM_Call(uivm, UI_INIT);
}
VM_Call(uivm, UI_REFRESH, (int)(realtime * 1000));
uimenu.isopaque = VM_Call(uivm, UI_IS_FULLSCREEN);
}
}
qboolean UI_CenterPrint(char *text, qboolean finale)
{
scr_centerstring = text;
return false;
/*
if (!uivm)
return false;
return VM_Call(uivm, UI_STRINGCHANGED, SID_CENTERPRINTTEXT);
*/
}
qboolean UI_Q2LayoutChanged(void)
{
return false;
/*
if (!uivm)
return false;
return VM_Call(uivm, UI_STRINGCHANGED, SID_CENTERPRINTTEXT);
*/
}
void UI_StringChanged(int num)
{
/* if (uivm)
VM_Call(uivm, UI_STRINGCHANGED, num);
*/
}
void UI_Reset(void)
{
keycatcher &= ~2;
if (qrenderer == QR_NONE) //no renderer loaded
UI_Stop();
else if (uivm)
VM_Call(uivm, UI_INIT);
}
int UI_MenuState(void)
{
if (Key_Dest_Has(kdm_gmenu) || Key_Dest_Has(kdm_emenu))
{ //engine's menus take precedence over q3's ui
return false;
}
if (!uivm)
return false;
if (VM_Call(uivm, UI_IS_FULLSCREEN))
return 2;
else if (keycatcher&2)
return 3;
else
return 0;
}
qboolean UI_KeyPress(int key, int unicode, qboolean down)
qboolean UI_KeyPress(struct menu_s *m, qboolean isdown, unsigned int devid, int key, int unicode)
{
extern qboolean keydown[K_MAX];
extern int keyshift[K_MAX]; // key to map to if shift held down in console
@ -1607,13 +1514,8 @@ qboolean UI_KeyPress(int key, int unicode, qboolean down)
// return false;
if (!(keycatcher&2))
{
if (key == K_ESCAPE && down)
if (key == K_ESCAPE && isdown)
{
if (Media_PlayingFullScreen())
{
Media_StopFilm(true);
}
UI_OpenMenu();
return true;
}
@ -1625,35 +1527,39 @@ qboolean UI_KeyPress(int key, int unicode, qboolean down)
if (key < K_BACKSPACE && key >= ' ')
key |= 1024;
/*result = */VM_Call(uivm, UI_KEY_EVENT, key, down);
/*
if (!keycatcher && !cls.state && key == K_ESCAPE && down)
{
M_Menu_Main_f();
return true;
}*/
/*result = */VM_Call(uivm, UI_KEY_EVENT, key, isdown);
return true;
// return result;
}
qboolean UI_MousePosition(float xpos, float ypos)
{
if (uivm && (keycatcher&2))
static qboolean UI_MousePosition(struct menu_s *m, qboolean abs, unsigned int devid, float x, float y)
{ //q3ui is a peice of poo and only accepts relative mouse movements.
//which it then clamps arbitrarily
//which means we can't use hardware cursors
//which results in clumsyness when switching between q3ui and everything else.
if (uivm && !abs)
{
int px, py;
px = (xpos);//*640/(int)vid.width;
py = (ypos);//*480/(int)vid.height;
int px = x, py = y;
VM_Call(uivm, UI_MOUSE_EVENT, px, py);
return true;
}
return false;
}
void UI_Reset(void)
{
Menu_Unlink(&uimenu);
if (qrenderer == QR_NONE) //no renderer loaded
UI_Stop();
else if (uivm)
VM_Call(uivm, UI_INIT);
}
void UI_Stop (void)
{
keycatcher &= ~2;
Menu_Unlink(&uimenu);
if (uivm)
{
VM_Call(uivm, UI_SHUTDOWN);
@ -1683,6 +1589,11 @@ void UI_Start (void)
for (i = 0; i < MAX_PINGREQUESTS; i++)
ui_pings[i].adr.type = NA_INVALID;
uimenu.drawmenu = UI_DrawMenu;
uimenu.mousemove = UI_MousePosition;
uimenu.keyevent = UI_KeyPress;
uimenu.release = UI_Release;
ui_width = vid.width;
ui_height = vid.height;
uivm = VM_Create("ui", com_nogamedirnativecode.ival?NULL:UI_SystemCallsNative, "vm/ui", UI_SystemCallsVM);

View File

@ -1232,7 +1232,7 @@ int Master_FindBestRoute(char *server, char *out, size_t outsize, int *directcos
float CL_KeyState (kbutton_t *key, int pnum, qboolean noslowstart);
const char *Key_KeynumToString (int keynum, int modifier);
int Key_StringToKeynum (const char *str, int *modifier);
char *Key_GetBinding(int keynum, int bindmap, int modifier);
const char *Key_GetBinding(int keynum, int bindmap, int modifier);
void Key_GetBindMap(int *bindmaps);
void Key_SetBindMap(int *bindmaps);
@ -1530,7 +1530,7 @@ char* TP_EnemyTeam (void);
void TP_ExecTrigger (char *s, qboolean indemos);
qboolean TP_FilterMessage (char *s);
void TP_Init(void);
char* TP_LocationName (vec3_t location);
char* TP_LocationName (const vec3_t location);
char* TP_MapName (void);
void TP_NewMap (void);
void TP_ParsePlayerInfo(player_state_t *oldstate, player_state_t *state, player_info_t *info);
@ -1682,7 +1682,6 @@ typedef enum
CINSTATE_FLUSHED, //video will restart from beginning
} cinstates_t;
/*media playing system*/
qboolean Media_PlayingFullScreen(void);
qboolean Media_PlayFilm(char *name, qboolean enqueue);
qboolean Media_StopFilm(qboolean all);
struct cin_s *Media_StartCin(char *name);
@ -1701,8 +1700,6 @@ cinstates_t Media_GetState(cin_t *cin);
const char *Media_Send_GetProperty(cin_t *cin, const char *key);
#else
#define Media_Playing() false
#define Media_PlayingFullScreen() false
#define Media_PlayFilm(n,e) false
#define Media_StopFilm(a) (void)true
#endif

View File

@ -900,7 +900,6 @@ void CLQ3_SendCmd(usercmd_t *cmd)
outframe_t *frame, *oldframe;
int cmdcount, key;
usercmd_t *to, *from;
extern int keycatcher;
extern cvar_t cl_nodelta, cl_c2sdupe;
//reuse the q1 array
@ -928,7 +927,7 @@ void CLQ3_SendCmd(usercmd_t *cmd)
cmd->upmove = 100;
cmd->buttons &= ~2;
}
if (Key_Dest_Has(~kdm_game) || (keycatcher&3))
if (Key_Dest_Has(~kdm_game))
cmd->buttons |= 2; //add in the 'at console' button
cl.outframes[cl.movesequence&Q3CMD_MASK].cmd[0] = *cmd;

View File

@ -2,6 +2,9 @@
#define _Q3DEFS_H_
#define PROTOCOL_VERSION_Q3 68
void Q3_SetKeyCatcher(int newcatcher);
int Q3_GetKeyCatcher(void);
int StringKey( const char *string, int length );
typedef struct {

View File

@ -1075,7 +1075,7 @@ static void Con_PrintFromThread (void *ctx, void *data, size_t a, size_t b)
BZ_Free(data);
}
vfsfile_t *Con_POpen(char *conname)
vfsfile_t *Con_POpen(const char *conname)
{
if (!conname || !*conname)
{

View File

@ -9262,7 +9262,7 @@ qboolean Image_LocateHighResTexture(image_t *tex, flocation_t *bestloc, char *be
Q_strncpyz(bestname, fname, bestnamesize);
bestdepth = depth;
*bestloc = loc;
bestflags = 0;
*bestflags = 0;
}
#endif
@ -9324,7 +9324,7 @@ qboolean Image_LocateHighResTexture(image_t *tex, flocation_t *bestloc, char *be
Q_strncpyz(bestname, fname, bestnamesize);
bestdepth = depth;
*bestloc = loc;
bestflags = 0;
*bestflags = 0;
}
}
}
@ -9343,7 +9343,7 @@ qboolean Image_LocateHighResTexture(image_t *tex, flocation_t *bestloc, char *be
Q_strncpyz(bestname, fname, bestnamesize);
bestdepth = depth;
*bestloc = loc;
bestflags = 0;
*bestflags = 0;
}
}
}
@ -9408,7 +9408,7 @@ qboolean Image_LocateHighResTexture(image_t *tex, flocation_t *bestloc, char *be
Q_strncpyz(bestname, fname, bestnamesize);
bestdepth = depth;
*bestloc = loc;
bestflags = 0;
*bestflags = 0;
}
}
}

View File

@ -126,7 +126,7 @@ static cvar_t joy_radialdeadzone = CVARD("joyradialdeadzone", "1", "Treat contro
#define EVENTQUEUELENGTH 1024
struct eventlist_s
static struct eventlist_s
{
enum
{
@ -166,8 +166,8 @@ struct eventlist_s
} gyro;
};
} eventlist[EVENTQUEUELENGTH];
volatile int events_avail; /*volatile to make sure the cc doesn't try leaving these cached in a register*/
volatile int events_used;
static volatile int events_avail; /*volatile to make sure the cc doesn't try leaving these cached in a register*/
static volatile int events_used;
static struct eventlist_s *in_newevent(void)
{
@ -182,7 +182,7 @@ static void in_finishevent(void)
}
#define MAXPOINTERS 8
struct mouse_s
static struct mouse_s
{
enum
{
@ -202,11 +202,11 @@ struct mouse_s
unsigned int updates; //tracks updates per second
qboolean updated;
} ptr[MAXPOINTERS];
int touchcursor = -1; //the cursor follows whichever finger was most recently pressed in preference to any mouse also on the same system
static int touchcursor = -1; //the cursor follows whichever finger was most recently pressed in preference to any mouse also on the same system
#define MAXJOYAXIS 6
#define MAXJOYSTICKS 8
struct joy_s
static struct joy_s
{
unsigned int qdeviceid;
float axis[MAXJOYAXIS];
@ -466,11 +466,9 @@ void IN_Commands(void)
case IEV_JOYAXIS:
if (ev->devid < MAXJOYSTICKS && ev->joy.axis < MAXJOYAXIS)
{
#ifdef MENU_DAT
if (MP_JoystickAxis(ev->joy.axis, ev->joy.value, ev->devid))
if (topmenu && topmenu->joyaxis && topmenu->joyaxis(topmenu, ev->devid, ev->joy.axis, ev->joy.value))
joy[ev->devid].axis[ev->joy.axis] = 0;
else
#endif
#ifdef CSQC_DAT
if (CSQC_JoystickAxis(ev->joy.axis, ev->joy.value, ev->devid))
joy[ev->devid].axis[ev->joy.axis] = 0;
@ -659,19 +657,7 @@ void IN_MoveMouse(struct mouse_s *mouse, float *movements, int pnum, float frame
mousemove_y += my;
if (Key_MouseShouldBeFree())
{
mx=my=0;
}
else
{
#ifdef VM_UI
if (UI_MousePosition(mx, my))
{
mx = 0;
my = 0;
}
#endif
}
if (mouse->type == M_TOUCH)
{
@ -744,28 +730,12 @@ void IN_MoveMouse(struct mouse_s *mouse, float *movements, int pnum, float frame
mouse->updated = false;
if (!runningindepphys)
{
#ifdef MENU_NATIVECODE
if (mn_entry)
{
struct menu_inputevent_args_s ev = {MIE_MOUSEABS, mouse->qdeviceid};
ev.mouse.delta[0] = mx;
ev.mouse.delta[1] = my;
ev.mouse.screen[0] = (mouse->oldpos[0] * vid.width) / vid.pixelwidth;
ev.mouse.screen[1] = (mouse->oldpos[1] * vid.width) / vid.pixelwidth;
if (mn_entry->InputEvent(ev))
{
mx = 0;
my = 0;
}
}
#endif
#ifdef MENU_DAT
if (MP_MousePosition(mouse->oldpos[0], mouse->oldpos[1], mouse->qdeviceid))
if ((promptmenu && promptmenu->mousemove && promptmenu->mousemove(topmenu, true, mouse->qdeviceid, mouse->oldpos[0], mouse->oldpos[1])) ||
(topmenu && topmenu->mousemove && topmenu->mousemove(topmenu, true, mouse->qdeviceid, mouse->oldpos[0], mouse->oldpos[1])))
{
mx = 0;
my = 0;
}
#endif
#ifdef CSQC_DAT
if (!runningindepphys && CSQC_MousePosition(mouse->oldpos[0], mouse->oldpos[1], mouse->qdeviceid))
{
@ -778,30 +748,13 @@ void IN_MoveMouse(struct mouse_s *mouse, float *movements, int pnum, float frame
}
else
{
#ifdef MENU_NATIVECODE
if (mn_entry && Key_Dest_Has(kdm_nmenu) && (mx || my))
{
struct menu_inputevent_args_s ev = {MIE_MOUSEABS, mouse->qdeviceid};
ev.mouse.delta[0] = mx;
ev.mouse.delta[1] = my;
ev.mouse.screen[0] = (mouse->oldpos[0] * vid.width) / vid.pixelwidth;
ev.mouse.screen[1] = (mouse->oldpos[1] * vid.height) / vid.pixelheight;
if (mn_entry->InputEvent(ev))
{
mx = 0;
my = 0;
}
}
#endif
#ifdef MENU_DAT
if (Key_Dest_Has(kdm_gmenu))
if (Key_Dest_Has(kdm_menu))
if (mx || my)
if (!runningindepphys && MP_MouseMove(mx, my, mouse->qdeviceid))
if (!runningindepphys && topmenu && topmenu->mousemove && topmenu->mousemove(topmenu, false, mouse->qdeviceid, mx, my))
{
mx = 0;
my = 0;
}
#endif
#ifdef CSQC_DAT
if (mx || my)

View File

@ -1762,6 +1762,13 @@ qboolean Key_Console (console_t *con, int key, unsigned int unicode)
{
if (con->redirect && con->redirect(con, unicode, key))
return true;
#ifdef HAVE_MEDIA_DECODER
if (con->backshader && R_ShaderGetCinematic(con->backshader))
{
Media_Send_KeyEvent(R_ShaderGetCinematic(con->backshader), rkey, unicode, 0);
return true;
}
#endif
if (Key_IsTouchScreen() || con->mousecursor[0] > ((con->flags & CONF_ISWINDOW)?con->wnd_w-16:vid.width)-8)
{ //just scroll the console up/down
con->buttonsdown = CB_SCROLL;
@ -2100,7 +2107,7 @@ void Key_Message (int key, int unicode)
//============================================================================
//for qc
char *Key_GetBinding(int keynum, int bindmap, int modifier)
const char *Key_GetBinding(int keynum, int bindmap, int modifier)
{
char *key = NULL;
if (keynum < 0 || keynum >= K_MAX)
@ -2596,8 +2603,8 @@ void Key_Init (void)
}
key_linepos = 0;
key_dest_mask = kdm_game;
key_dest_absolutemouse = kdm_centerprint | kdm_console | kdm_cwindows | kdm_emenu;
Key_Dest_Add(kdm_game);
key_dest_absolutemouse = kdm_centerprint | kdm_console | kdm_cwindows | kdm_menu;
//
// init ascii characters in console mode
@ -2700,14 +2707,6 @@ qboolean Key_MouseShouldBeFree(void)
if (key_dest_absolutemouse & key_dest_mask)
return true;
#ifdef VM_UI
if (UI_MenuState())
return false;
#endif
if (Media_PlayingFullScreen())
return true;
if (cl_prydoncursor.ival)
return true;
@ -2786,7 +2785,7 @@ void Key_Event (unsigned int devid, int key, unsigned int unicode, qboolean down
//yes, csqc is allowed to steal the escape key.
if (key != '`' && (!down || key != K_ESCAPE || (!Key_Dest_Has(~kdm_game) && !shift_down)) &&
!Key_Dest_Has(~kdm_game) && !Media_PlayingFullScreen())
!Key_Dest_Has(~kdm_game))
{
#ifdef CSQC_DAT
if (CSQC_KeyPress(key, unicode, down, devid)) //give csqc a chance to handle it.
@ -2810,70 +2809,38 @@ void Key_Event (unsigned int devid, int key, unsigned int unicode, qboolean down
//
if (key == K_ESCAPE)
{
#ifdef VM_UI
#ifdef TEXTEDITOR
if (!Key_Dest_Has(~kdm_game) && !Key_Dest_Has(kdm_console))
#endif
if (!Key_Dest_Has(~kdm_game))
{
if (down && Media_PlayingFullScreen())
{
Media_StopFilm(false);
return;
}
if (UI_KeyPress(key, unicode, down)) //Allow the UI to see the escape key. It is possible that a developer may get stuck at a menu.
return;
}
#ifdef VM_UI
// if (UI_KeyPress(key, unicode, down)) //Allow the UI to see the escape key. It is possible that a developer may get stuck at a menu.
// return;
#endif
}
if (!down)
{
#ifdef MENU_DAT
if (Key_Dest_Has(kdm_gmenu) && !Key_Dest_Has(kdm_console|kdm_cwindows))
MP_Keyup (key, unicode, devid);
#endif
#ifdef MENU_NATIVECODE
if (mn_entry)
{
struct menu_inputevent_args_s ev = {MIE_KEYUP, devid};
ev.key.scancode = key;
ev.key.charcode = unicode;
mn_entry->InputEvent(ev);
}
#endif
if (Key_Dest_Has(kdm_prompt) || (Key_Dest_Has(kdm_menu) && !Key_Dest_Has(kdm_console|kdm_cwindows)))
Menu_KeyEvent (false, devid, key, unicode);
return;
}
if (Key_Dest_Has(kdm_console))
if (Key_Dest_Has(kdm_prompt))
Menu_KeyEvent (true, devid, key, unicode);
else if (Key_Dest_Has(kdm_console))
{
Key_Dest_Remove(kdm_console);
Key_Dest_Remove(kdm_cwindows);
if (!cls.state && !Key_Dest_Has(~kdm_game) && !Media_PlayingFullScreen())
if (!cls.state && !Key_Dest_Has(~kdm_game))
M_ToggleMenu_f ();
}
else if (Key_Dest_Has(kdm_cwindows))
{
Key_Dest_Remove(kdm_cwindows);
if (!cls.state && !Key_Dest_Has(~kdm_game) && !Media_PlayingFullScreen())
if (!cls.state && !Key_Dest_Has(~kdm_game))
M_ToggleMenu_f ();
}
else if (Key_Dest_Has(kdm_emenu))
M_Keydown (key, unicode);
#ifdef MENU_NATIVECODE
else if (Key_Dest_Has(kdm_nmenu))
{
if (mn_entry)
{
struct menu_inputevent_args_s ev = {MIE_KEYDOWN, devid};
ev.key.scancode = key;
ev.key.charcode = unicode;
mn_entry->InputEvent(ev);
}
}
#endif
#ifdef MENU_DAT
else if (Key_Dest_Has(kdm_gmenu))
MP_Keydown (key, unicode, devid);
#endif
else if (Key_Dest_Has(kdm_menu))
Menu_KeyEvent (true, devid, key, unicode);
else if (Key_Dest_Has(kdm_message))
{
Key_Dest_Remove(kdm_message);
@ -2882,16 +2849,7 @@ void Key_Event (unsigned int devid, int key, unsigned int unicode, qboolean down
chat_bufferpos = 0;
}
else
{
if (Media_PlayingFullScreen())
{
Media_StopFilm(true);
if (!cls.state)
M_ToggleMenu_f ();
}
else
M_ToggleMenu_f ();
}
M_ToggleMenu_f ();
return;
}
@ -2924,25 +2882,8 @@ void Key_Event (unsigned int devid, int key, unsigned int unicode, qboolean down
Key_ConsoleRelease(con, key, unicode);
}
}
if (Key_Dest_Has(kdm_emenu))
M_Keyup (key, unicode);
#ifdef MENU_NATIVECODE
if (Key_Dest_Has(kdm_nmenu) && mn_entry)
{
struct menu_inputevent_args_s ev = {MIE_KEYUP, devid};
ev.key.scancode = key;
ev.key.charcode = unicode;
mn_entry->InputEvent(ev);
}
#endif
#ifdef MENU_DAT
if (Key_Dest_Has(kdm_gmenu))
MP_Keyup (key, unicode, devid);
#endif
#ifdef HAVE_MEDIA_DECODER
if (Media_PlayingFullScreen())
Media_Send_KeyEvent(NULL, key, unicode, down?0:1);
#endif
if (Key_Dest_Has(kdm_menu|kdm_prompt))
Menu_KeyEvent (false, devid, key, unicode);
uc = releasecommand[key][devid%MAX_INDEVS];
if (uc) //this wasn't down, so don't crash on bad commands.
@ -2980,6 +2921,16 @@ void Key_Event (unsigned int devid, int key, unsigned int unicode, qboolean down
}
}
//prompts get the first chance
if (Key_Dest_Has(kdm_prompt))
{
if (key < K_F1 || key > K_F15)
{ //function keys don't get intercepted by the menu...
Menu_KeyEvent (true, devid, key, unicode);
return;
}
}
//
// if not a consolekey, send to the interpreter no matter what mode is
//
@ -2999,49 +2950,16 @@ void Key_Event (unsigned int devid, int key, unsigned int unicode, qboolean down
Key_Dest_Remove(kdm_cwindows);
}
#ifdef HAVE_MEDIA_DECODER
if (Media_PlayingFullScreen())
{
Media_Send_KeyEvent(NULL, key, unicode, down?0:1);
return;
}
#endif
#ifdef VM_UI
if (!Key_Dest_Has(~kdm_game) || !down)
{
if (UI_KeyPress(key, unicode, down) && down) //UI is allowed to take these keydowns. Keyups are always maintained.
return;
}
#endif
if (Key_Dest_Has(kdm_emenu))
//menus after console stuff
if (Key_Dest_Has(kdm_menu))
{
if (key < K_F1 || key > K_F15)
{ //function keys don't get intercepted by the menu...
M_Keydown (key, unicode);
Menu_KeyEvent (true, devid, key, unicode);
return;
}
}
#ifdef MENU_NATIVECODE
if (Key_Dest_Has(kdm_nmenu))
{
if (mn_entry)
{
struct menu_inputevent_args_s ev = {down?MIE_KEYDOWN:MIE_KEYUP, devid};
ev.key.scancode = key;
ev.key.charcode = unicode;
if (mn_entry->InputEvent(ev))
return;
}
}
#endif
#ifdef MENU_DAT
if (Key_Dest_Has(kdm_gmenu))
{
if (MP_Keydown (key, unicode, devid))
return;
}
#endif
if (Key_Dest_Has(kdm_message))
{
Key_Message (key, unicode);

View File

@ -250,15 +250,10 @@ typedef enum //highest has priority
kdm_game = 1u<<0, //should always be set
kdm_centerprint = 1u<<1, //enabled when there's a centerprint menu with clickable things.
kdm_message = 1u<<2,
kdm_gmenu = 1u<<3, //menu.dat
#ifdef MENU_NATIVECODE
kdm_nmenu = 1u<<4, //should probably reuse gmenu...
#else
kdm_nmenu = 0,
#endif
kdm_emenu = 1u<<5, //engine's menus
kdm_console = 1u<<6,
kdm_cwindows = 1u<<7,
kdm_menu = 1u<<3, //layered menus (engine menus, qc menus, or plugins/etc)
kdm_console = 1u<<4,
kdm_cwindows = 1u<<5,
kdm_prompt = 1u<<6, //highest priority - popups that require user interaction (eg: confirmation from untrusted console commands)
} keydestmask_t;
//unsigned int Key_Dest_Get(void); //returns highest priority destination
@ -277,12 +272,11 @@ extern int key_lastpress;
enum
{
kc_game, //csprogs.dat
kc_menu, //menu.dat
#ifdef MENU_NATIVECODE
kc_nmenu,
#endif
kc_console, //generic engine-defined cursor
kc_game, //csprogs.dat
kc_menuqc, //
kc_nativemenu, //
kc_plugin, //for plugins
kc_console, //generic engine-defined cursor
kc_max
};
extern struct key_cursor_s

View File

@ -1198,7 +1198,7 @@ static void PM_PreparePackageList(void)
{
pluginpromptshown = true;
#ifndef SERVERONLY
M_Menu_Prompt(PM_PluginDetected, NULL, "Plugin(s) appears to have\nbeen installed externally.\nUse the updates menu\nto enable them.", "View", NULL, "Disable");
Menu_Prompt(PM_PluginDetected, NULL, "Plugin(s) appears to have\nbeen installed externally.\nUse the updates menu\nto enable them.", "View", NULL, "Disable");
#endif
}
}
@ -1758,12 +1758,7 @@ static void PM_ListDownloaded(struct dl_download *dl)
#ifdef DOWNLOADMENU
if (!isDedicated)
{
if (Key_Dest_Has(kdm_emenu))
Key_Dest_Remove(kdm_emenu);
#ifdef MENU_DAT
if (Key_Dest_Has(kdm_gmenu))
MP_Toggle(0);
#endif
Menu_PopAll();
Cmd_ExecuteString("menu_download\n", RESTRICT_LOCAL);
}
else
@ -2717,7 +2712,7 @@ static void PM_PromptApplyChanges(void)
//lock it down, so noone can make any changes while this prompt is still displayed
if (pkg_updating)
{
M_Menu_Prompt(PM_PromptApplyChanges_Callback, NULL, "An update is already in progress\nPlease wait\n", NULL, NULL, "Cancel");
Menu_Prompt(PM_PromptApplyChanges_Callback, NULL, "An update is already in progress\nPlease wait\n", NULL, NULL, "Cancel");
return;
}
pkg_updating = true;
@ -2725,7 +2720,7 @@ static void PM_PromptApplyChanges(void)
strcpy(text, "Really decline the following\nrecommendedpackages?\n\n");
if (PM_DeclinedPackages(text+strlen(text), sizeof(text)-strlen(text)))
M_Menu_Prompt(PM_PromptApplyDecline_Callback, NULL, text, NULL, "Confirm", "Cancel");
Menu_Prompt(PM_PromptApplyDecline_Callback, NULL, text, NULL, "Confirm", "Cancel");
else
{
strcpy(text, "Apply the following changes?\n\n");
@ -2737,7 +2732,7 @@ static void PM_PromptApplyChanges(void)
#endif
}
else
M_Menu_Prompt(PM_PromptApplyChanges_Callback, NULL, text, "Apply", NULL, "Cancel");
Menu_Prompt(PM_PromptApplyChanges_Callback, NULL, text, "Apply", NULL, "Cancel");
}
}
#endif
@ -3105,7 +3100,7 @@ typedef struct {
qboolean populated;
} dlmenu_t;
static void MD_Draw (int x, int y, struct menucustom_s *c, struct menu_s *m)
static void MD_Draw (int x, int y, struct menucustom_s *c, struct emenu_s *m)
{
package_t *p;
char *n;
@ -3217,7 +3212,7 @@ static void MD_Draw (int x, int y, struct menucustom_s *c, struct menu_s *m)
}
}
static qboolean MD_Key (struct menucustom_s *c, struct menu_s *m, int key, unsigned int unicode)
static qboolean MD_Key (struct menucustom_s *c, struct emenu_s *m, int key, unsigned int unicode)
{
extern qboolean keydown[];
qboolean ctrl = keydown[K_LCTRL] || keydown[K_RCTRL];
@ -3329,7 +3324,7 @@ static qboolean MD_Key (struct menucustom_s *c, struct menu_s *m, int key, unsig
}
#ifdef WEBCLIENT
static void MD_AutoUpdate_Draw (int x, int y, struct menucustom_s *c, struct menu_s *m)
static void MD_AutoUpdate_Draw (int x, int y, struct menucustom_s *c, struct emenu_s *m)
{
char *settings[] =
{
@ -3345,7 +3340,7 @@ static void MD_AutoUpdate_Draw (int x, int y, struct menucustom_s *c, struct men
// else
Draw_FunString (x, y, text);
}
static qboolean MD_AutoUpdate_Key (struct menucustom_s *c, struct menu_s *m, int key, unsigned int unicode)
static qboolean MD_AutoUpdate_Key (struct menucustom_s *c, struct emenu_s *m, int key, unsigned int unicode)
{
if (key == K_ENTER || key == K_KP_ENTER || key == K_GP_START || key == K_MOUSE1)
{
@ -3360,7 +3355,7 @@ static qboolean MD_AutoUpdate_Key (struct menucustom_s *c, struct menu_s *m, int
return false;
}
static qboolean MD_MarkUpdatesButton (union menuoption_s *mo,struct menu_s *m,int key)
static qboolean MD_MarkUpdatesButton (union menuoption_s *mo,struct emenu_s *m,int key)
{
if (key == K_ENTER || key == K_KP_ENTER || key == K_GP_START || key == K_MOUSE1)
{
@ -3371,7 +3366,7 @@ static qboolean MD_MarkUpdatesButton (union menuoption_s *mo,struct menu_s *m,in
}
#endif
qboolean MD_PopMenu (union menuoption_s *mo,struct menu_s *m,int key)
qboolean MD_PopMenu (union menuoption_s *mo,struct emenu_s *m,int key)
{
if (key == K_ENTER || key == K_KP_ENTER || key == K_GP_START || key == K_MOUSE1)
{
@ -3381,7 +3376,7 @@ qboolean MD_PopMenu (union menuoption_s *mo,struct menu_s *m,int key)
return false;
}
static qboolean MD_ApplyDownloads (union menuoption_s *mo,struct menu_s *m,int key)
static qboolean MD_ApplyDownloads (union menuoption_s *mo,struct emenu_s *m,int key)
{
if (key == K_ENTER || key == K_KP_ENTER || key == K_GP_START || key == K_MOUSE1)
{
@ -3391,7 +3386,7 @@ static qboolean MD_ApplyDownloads (union menuoption_s *mo,struct menu_s *m,int k
return false;
}
static qboolean MD_RevertUpdates (union menuoption_s *mo,struct menu_s *m,int key)
static qboolean MD_RevertUpdates (union menuoption_s *mo,struct emenu_s *m,int key)
{
if (key == K_ENTER || key == K_KP_ENTER || key == K_GP_START || key == K_MOUSE1)
{
@ -3401,7 +3396,7 @@ static qboolean MD_RevertUpdates (union menuoption_s *mo,struct menu_s *m,int ke
return false;
}
static int MD_AddItemsToDownloadMenu(menu_t *m, int y, const char *pathprefix)
static int MD_AddItemsToDownloadMenu(emenu_t *m, int y, const char *pathprefix)
{
char path[MAX_QPATH];
package_t *p;
@ -3471,7 +3466,7 @@ static int MD_AddItemsToDownloadMenu(menu_t *m, int y, const char *pathprefix)
}
#include "shader.h"
static void MD_Download_UpdateStatus(struct menu_s *m)
static void MD_Download_UpdateStatus(struct emenu_s *m)
{
dlmenu_t *info = m->data;
int i, y;
@ -3621,15 +3616,13 @@ static void MD_Download_UpdateStatus(struct menu_s *m)
void Menu_DownloadStuff_f (void)
{
menu_t *menu;
emenu_t *menu;
dlmenu_t *info;
Key_Dest_Add(kdm_emenu);
menu = M_CreateMenu(sizeof(dlmenu_t));
info = menu->data;
menu->persist = true;
menu->menu.persist = true;
menu->predraw = MD_Download_UpdateStatus;
info->downloadablessequence = downloadablessequence;

View File

@ -78,16 +78,16 @@ void Draw_TextBox (int x, int y, int width, int lines)
#ifndef NOBUILTINMENUS
int omousex;
int omousey;
qboolean mousemoved;
qboolean bindingactive;
static int omousex;
static int omousey;
static qboolean mousemoved;
static qboolean bindingactive;
extern cvar_t cl_cursor;
extern cvar_t cl_cursorsize;
extern cvar_t cl_cursorbias;
extern cvar_t m_preset_chosen;
menu_t *topmenu;
menuoption_t *M_NextSelectableItem(menu_t *m, menuoption_t *old);
extern menu_t *topmenu;
menuoption_t *M_NextSelectableItem(emenu_t *m, menuoption_t *old);
#ifdef HEXEN2
//this function is so fucked up.
@ -266,7 +266,7 @@ int maxdots;
int mindot;
int dotofs;
static void MenuTooltipChange(menu_t *menu, const char *text)
static void MenuTooltipChange(emenu_t *menu, const char *text)
{
unsigned int MAX_CHARS=1024;
menutooltip_t *mtt;
@ -329,7 +329,7 @@ static qboolean MI_Selectable(menuoption_t *op)
}
}
static qboolean M_MouseMoved(menu_t *menu)
static qboolean M_MouseMoved(emenu_t *menu)
{
int ypos = menu->ypos, framescroll = 0;
menuoption_t *option;
@ -393,7 +393,7 @@ static qboolean M_MouseMoved(menu_t *menu)
return true;
}
static void M_CheckMouseMove(void)
static void M_CheckMouseMove(emenu_t *m)
{
if (omousex != (int)mousecursor_x || omousey != (int)mousecursor_y)
mousemoved = true;
@ -403,7 +403,7 @@ static void M_CheckMouseMove(void)
omousey = mousecursor_y;
if (mousemoved)
M_MouseMoved(topmenu);
M_MouseMoved(m);
}
static float M_DrawScrollbar(int x, int y, int width, int height, float frac, qboolean mgrabbed)
@ -461,7 +461,7 @@ static float M_DrawScrollbar(int x, int y, int width, int height, float frac, qb
return frac;
}
static void MenuDrawItems(int xpos, int ypos, menuoption_t *option, menu_t *menu)
static void MenuDrawItems(int xpos, int ypos, menuoption_t *option, emenu_t *menu)
{
int i;
mpic_t *p;
@ -479,7 +479,7 @@ static void MenuDrawItems(int xpos, int ypos, menuoption_t *option, menu_t *menu
if (option->common.ishidden)
continue;
if (menu == topmenu && menu->mouseitem == option)
if (&menu->menu == topmenu && menu->mouseitem == option)
{
float alphamax = 0.5, alphamin = 0.2;
R2D_ImageColours(.5,.4,0,(sin(realtime*2)+1)*0.5*(alphamax-alphamin)+alphamin);
@ -763,11 +763,8 @@ static void MenuDrawItems(int xpos, int ypos, menuoption_t *option, menu_t *menu
}
}
static void MenuDraw(menu_t *menu)
static void MenuDraw(emenu_t *menu)
{
if (!menu->exclusive && menu->prev) //popup menus draw the one underneath them
MenuDraw(menu->prev);
if (!menu->dontexpand)
menu->xpos = ((vid.width - 320)>>1);
if (menu->predraw)
@ -831,7 +828,7 @@ static void MenuDraw(menu_t *menu)
}
menutext_t *MC_AddWhiteText(menu_t *menu, int lhs, int rhs, int y, const char *text, int rightalign)
menutext_t *MC_AddWhiteText(emenu_t *menu, int lhs, int rhs, int y, const char *text, int rightalign)
{
menutext_t *n = Z_Malloc(sizeof(menutext_t) + (text?strlen(text):0)+1);
n->common.type = mt_text;
@ -851,7 +848,7 @@ menutext_t *MC_AddWhiteText(menu_t *menu, int lhs, int rhs, int y, const char *t
return n;
}
menutext_t *MC_AddBufferedText(menu_t *menu, int lhs, int rhs, int y, const char *text, int rightalign, qboolean red)
menutext_t *MC_AddBufferedText(emenu_t *menu, int lhs, int rhs, int y, const char *text, int rightalign, qboolean red)
{
menutext_t *n = Z_Malloc(sizeof(menutext_t) + strlen(text)+1);
n->common.type = mt_text;
@ -871,7 +868,7 @@ menutext_t *MC_AddBufferedText(menu_t *menu, int lhs, int rhs, int y, const char
return n;
}
menutext_t *MC_AddRedText(menu_t *menu, int lhs, int rhs, int y, const char *text, int rightalign)
menutext_t *MC_AddRedText(emenu_t *menu, int lhs, int rhs, int y, const char *text, int rightalign)
{
menutext_t *n;
n = MC_AddWhiteText(menu, lhs, rhs, y, text, rightalign);
@ -879,7 +876,7 @@ menutext_t *MC_AddRedText(menu_t *menu, int lhs, int rhs, int y, const char *tex
return n;
}
menubind_t *MC_AddBind(menu_t *menu, int cx, int bx, int y, const char *caption, char *command, char *tooltip)
menubind_t *MC_AddBind(emenu_t *menu, int cx, int bx, int y, const char *caption, char *command, char *tooltip)
{
menubind_t *n = Z_Malloc(sizeof(*n) + strlen(caption)+1 + strlen(command)+1 + (tooltip?strlen(tooltip)+1:0));
n->common.type = mt_bind;
@ -905,7 +902,7 @@ menubind_t *MC_AddBind(menu_t *menu, int cx, int bx, int y, const char *caption,
return n;
}
menupicture_t *MC_AddSelectablePicture(menu_t *menu, int x, int y, int height, char *picname)
menupicture_t *MC_AddSelectablePicture(emenu_t *menu, int x, int y, int height, char *picname)
{
char selname[MAX_QPATH];
menupicture_t *n;
@ -934,7 +931,7 @@ menupicture_t *MC_AddSelectablePicture(menu_t *menu, int x, int y, int height, c
return n;
}
menupicture_t *MC_AddPicture(menu_t *menu, int x, int y, int width, int height, char *picname)
menupicture_t *MC_AddPicture(emenu_t *menu, int x, int y, int width, int height, char *picname)
{
menupicture_t *n;
if (qrenderer == QR_NONE)
@ -957,7 +954,7 @@ menupicture_t *MC_AddPicture(menu_t *menu, int x, int y, int width, int height,
return n;
}
menupicture_t *MC_AddCenterPicture(menu_t *menu, int y, int height, char *picname)
menupicture_t *MC_AddCenterPicture(emenu_t *menu, int y, int height, char *picname)
{
int x;
int width;
@ -984,7 +981,7 @@ menupicture_t *MC_AddCenterPicture(menu_t *menu, int y, int height, char *picnam
return MC_AddPicture(menu, x, y, width, height, picname);
}
menuoption_t *MC_AddCursorSmall(menu_t *menu, menuresel_t *reselection, int x, int y)
menuoption_t *MC_AddCursorSmall(emenu_t *menu, menuresel_t *reselection, int x, int y)
{
menuoption_t *n = Z_Malloc(sizeof(menucommon_t));
if (reselection)
@ -1017,7 +1014,7 @@ menuoption_t *MC_AddCursorSmall(menu_t *menu, menuresel_t *reselection, int x, i
return n;
}
menupicture_t *MC_AddCursor(menu_t *menu, menuresel_t *reselection, int x, int y)
menupicture_t *MC_AddCursor(emenu_t *menu, menuresel_t *reselection, int x, int y)
{
int i;
menupicture_t *n = Z_Malloc(sizeof(menupicture_t));
@ -1089,7 +1086,7 @@ menupicture_t *MC_AddCursor(menu_t *menu, menuresel_t *reselection, int x, int y
return n;
}
menuedit_t *MC_AddEdit(menu_t *menu, int cx, int ex, int y, char *text, char *def)
menuedit_t *MC_AddEdit(emenu_t *menu, int cx, int ex, int y, char *text, char *def)
{
menuedit_t *n = Z_Malloc(sizeof(menuedit_t)+strlen(text)+1);
n->slim = false;
@ -1110,7 +1107,7 @@ menuedit_t *MC_AddEdit(menu_t *menu, int cx, int ex, int y, char *text, char *de
return n;
}
menuedit_t *MC_AddEditCvar(menu_t *menu, int cx, int ex, int y, char *text, char *name, qboolean isslim)
menuedit_t *MC_AddEditCvar(emenu_t *menu, int cx, int ex, int y, char *text, char *name, qboolean isslim)
{
menuedit_t *n = Z_Malloc(sizeof(menuedit_t)+strlen(text)+1);
cvar_t *cvar;
@ -1139,7 +1136,7 @@ menuedit_t *MC_AddEditCvar(menu_t *menu, int cx, int ex, int y, char *text, char
return n;
}
menubox_t *MC_AddBox(menu_t *menu, int x, int y, int width, int height)
menubox_t *MC_AddBox(emenu_t *menu, int x, int y, int width, int height)
{
menubox_t *n = Z_Malloc(sizeof(menubox_t));
n->common.type = mt_box;
@ -1154,7 +1151,7 @@ menubox_t *MC_AddBox(menu_t *menu, int x, int y, int width, int height)
return n;
}
menucustom_t *MC_AddCustom(menu_t *menu, int x, int y, void *dptr, int dint, const char *tooltip)
menucustom_t *MC_AddCustom(emenu_t *menu, int x, int y, void *dptr, int dint, const char *tooltip)
{
menucustom_t *n = Z_Malloc(sizeof(menucustom_t) + (tooltip?strlen(tooltip)+1:0));
n->common.type = mt_custom;
@ -1170,7 +1167,7 @@ menucustom_t *MC_AddCustom(menu_t *menu, int x, int y, void *dptr, int dint, con
return n;
}
menucheck_t *MC_AddCheckBox(menu_t *menu, int tx, int cx, int y, const char *text, cvar_t *var, int bits)
menucheck_t *MC_AddCheckBox(emenu_t *menu, int tx, int cx, int y, const char *text, cvar_t *var, int bits)
{
menucheck_t *n = Z_Malloc(sizeof(menucheck_t)+strlen(text)+1);
n->common.type = mt_checkbox;
@ -1200,7 +1197,7 @@ menucheck_t *MC_AddCheckBox(menu_t *menu, int tx, int cx, int y, const char *tex
menu->options = (menuoption_t *)n;
return n;
}
menuframe_t *MC_AddFrameStart(menu_t *menu, int y)
menuframe_t *MC_AddFrameStart(emenu_t *menu, int y)
{
menuframe_t *n = Z_Malloc(sizeof(menuframe_t));
n->common.type = mt_framestart;
@ -1214,7 +1211,7 @@ menuframe_t *MC_AddFrameStart(menu_t *menu, int y)
menu->options = (menuoption_t *)n;
return n;
}
menuframe_t *MC_AddFrameEnd(menu_t *menu, int y)
menuframe_t *MC_AddFrameEnd(emenu_t *menu, int y)
{
menuframe_t *n = Z_Malloc(sizeof(menuframe_t));
n->common.type = mt_frameend;
@ -1228,7 +1225,7 @@ menuframe_t *MC_AddFrameEnd(menu_t *menu, int y)
menu->options = (menuoption_t *)n;
return n;
}
menucheck_t *MC_AddCheckBoxFunc(menu_t *menu, int tx, int cx, int y, const char *text, qboolean (*func) (menucheck_t *option, menu_t *menu, chk_set_t set), int bits)
menucheck_t *MC_AddCheckBoxFunc(emenu_t *menu, int tx, int cx, int y, const char *text, qboolean (*func) (menucheck_t *option, emenu_t *menu, chk_set_t set), int bits)
{
menucheck_t *n = Z_Malloc(sizeof(menucheck_t)+strlen(text)+1);
n->common.type = mt_checkbox;
@ -1249,7 +1246,7 @@ menucheck_t *MC_AddCheckBoxFunc(menu_t *menu, int tx, int cx, int y, const char
}
//delta may be 0
menuslider_t *MC_AddSlider(menu_t *menu, int tx, int sx, int y, const char *text, cvar_t *var, float min, float max, float delta)
menuslider_t *MC_AddSlider(emenu_t *menu, int tx, int sx, int y, const char *text, cvar_t *var, float min, float max, float delta)
{
menuslider_t *n = Z_Malloc(sizeof(menuslider_t)+strlen(text)+1);
n->common.type = mt_slider;
@ -1285,7 +1282,7 @@ menuslider_t *MC_AddSlider(menu_t *menu, int tx, int sx, int y, const char *text
return n;
}
menucombo_t *MC_AddCombo(menu_t *menu, int tx, int cx, int y, const char *caption, const char **ops, int initialvalue)
menucombo_t *MC_AddCombo(emenu_t *menu, int tx, int cx, int y, const char *caption, const char **ops, int initialvalue)
{
int numopts;
int optlen;
@ -1344,7 +1341,7 @@ menucombo_t *MC_AddCombo(menu_t *menu, int tx, int cx, int y, const char *captio
return n;
}
menucombo_t *MC_AddCvarCombo(menu_t *menu, int tx, int cx, int y, const char *caption, cvar_t *cvar, const char **ops, const char **values)
menucombo_t *MC_AddCvarCombo(emenu_t *menu, int tx, int cx, int y, const char *caption, cvar_t *cvar, const char **ops, const char **values)
{
int numopts;
int optlen;
@ -1389,8 +1386,8 @@ menucombo_t *MC_AddCvarCombo(menu_t *menu, int tx, int cx, int y, const char *ca
n->caption = optbuf;
optbuf += strlen(optbuf)+1;
n->options = (const char **)newops;
n->values = (const char **)newvalues;
n->options = (char const*const*)newops;
n->values = (char const*const*)newvalues;
n->cvar = cvar;
// if (!(cvar->flags & CVAR_ARCHIVE))
@ -1421,7 +1418,7 @@ menucombo_t *MC_AddCvarCombo(menu_t *menu, int tx, int cx, int y, const char *ca
return n;
}
menubutton_t *MC_AddConsoleCommand(menu_t *menu, int lhs, int rhs, int y, const char *text, const char *command)
menubutton_t *MC_AddConsoleCommand(emenu_t *menu, int lhs, int rhs, int y, const char *text, const char *command)
{
menubutton_t *n = Z_Malloc(sizeof(menubutton_t)+strlen(text)+1+strlen(command)+1);
n->common.type = mt_button;
@ -1441,7 +1438,7 @@ menubutton_t *MC_AddConsoleCommand(menu_t *menu, int lhs, int rhs, int y, const
return n;
}
menubutton_t *MC_AddConsoleCommandQBigFont(menu_t *menu, int x, int y, const char *text, const char *command)
menubutton_t *MC_AddConsoleCommandQBigFont(emenu_t *menu, int x, int y, const char *text, const char *command)
{
menubutton_t *n = Z_Malloc(sizeof(menubutton_t)+strlen(text)+1+strlen(command)+1);
n->common.type = mt_qbuttonbigfont;
@ -1460,7 +1457,7 @@ menubutton_t *MC_AddConsoleCommandQBigFont(menu_t *menu, int x, int y, const cha
return n;
}
#ifdef HEXEN2
menubutton_t *MC_AddConsoleCommandHexen2BigFont(menu_t *menu, int x, int y, const char *text, const char *command)
menubutton_t *MC_AddConsoleCommandHexen2BigFont(emenu_t *menu, int x, int y, const char *text, const char *command)
{
menubutton_t *n = Z_Malloc(sizeof(menubutton_t)+strlen(text)+1+strlen(command)+1);
n->common.type = mt_hexen2buttonbigfont;
@ -1479,7 +1476,7 @@ menubutton_t *MC_AddConsoleCommandHexen2BigFont(menu_t *menu, int x, int y, cons
return n;
}
#endif
menubutton_t *MC_AddCommand(menu_t *menu, int lhs, int rhs, int y, char *text, qboolean (*command) (union menuoption_s *,struct menu_s *,int))
menubutton_t *MC_AddCommand(emenu_t *menu, int lhs, int rhs, int y, char *text, qboolean (*command) (union menuoption_s *,struct emenu_s *,int))
{
menubutton_t *n = Z_Malloc(sizeof(menubutton_t));
n->common.type = mt_button;
@ -1498,7 +1495,7 @@ menubutton_t *MC_AddCommand(menu_t *menu, int lhs, int rhs, int y, char *text, q
return n;
}
menubutton_t *VARGS MC_AddConsoleCommandf(menu_t *menu, int lhs, int rhs, int y, int rightalign, const char *text, char *command, ...)
menubutton_t *VARGS MC_AddConsoleCommandf(emenu_t *menu, int lhs, int rhs, int y, int rightalign, const char *text, char *command, ...)
{
va_list argptr;
static char string[1024];
@ -1598,7 +1595,7 @@ void MC_Slider_Key(menuslider_t *option, int key)
Cvar_SetValue(option->var, option->current);
}
void MC_CheckBox_Key(menucheck_t *option, menu_t *menu, int key)
void MC_CheckBox_Key(menucheck_t *option, emenu_t *menu, int key)
{
if (key != K_ENTER && key != K_KP_ENTER && key != K_GP_START && key != K_GP_A && key != K_GP_B && key != K_LEFTARROW && key != K_KP_LEFTARROW && key != K_GP_DPAD_LEFT && key != K_RIGHTARROW && key != K_KP_LEFTARROW && key != K_GP_DPAD_RIGHT && key != K_MWHEELUP && key != K_MWHEELDOWN && key != K_MOUSE1)
return;
@ -1686,61 +1683,73 @@ changed:
}
}
void M_AddMenu (menu_t *menu)
static qboolean menu_mousedown;
extern menu_t *menu_script;
static void M_Draw (menu_t *menu)
{
menu->prev = topmenu;
if (topmenu)
topmenu->next = menu;
menu->next = NULL;
topmenu = menu;
emenu_t *m = (emenu_t*)menu;
qboolean stillactive = false;
menu->exclusive = true;
}
menu_t *M_CreateMenu (int extrasize)
{
menu_t *menu;
menu = Z_Malloc(sizeof(menu_t)+extrasize);
menu->iszone=true;
menu->data = menu+1;
M_AddMenu(menu);
return menu;
}
menu_t *M_CreateMenuInfront (int extrasize)
{
menu_t *menu;
menu = Z_Malloc(sizeof(menu_t)+extrasize);
menu->iszone=true;
menu->data = menu+1;
M_AddMenu(menu);
menu->xpos = ((vid.width - 320)>>1);
menu->exclusive = false;
return menu;
}
void M_HideMenu (menu_t *menu)
{
if (menu == topmenu)
if (!Key_Dest_Has(kdm_menu))
{
topmenu = menu->prev;
if (topmenu)
topmenu->next = NULL;
menu->prev = NULL;
M_RemoveAllMenus(false);
menu_mousedown = false;
return;
}
if ((!menu_script || scr_con_current))
{
if (m->selecteditem && m->selecteditem->common.type == mt_slider && (m->selecteditem->slider.var == &v_gamma || m->selecteditem->slider.var == &v_contrast))
/*no menu tint if we're trying to adjust gamma*/;
else
R2D_FadeScreen ();
}
R2D_ImageColours(1, 1, 1, 1);
if (m)
{
M_CheckMouseMove(m);
MenuDraw(m);
stillactive = true;
}
if (!stillactive)
Key_Dest_Remove(kdm_menu);
}
static qboolean M_KeyEvent(menu_t *m, qboolean isdown, unsigned int devid, int key, int unicode)
{
emenu_t *menu = (emenu_t*)m;
if (isdown)
{
if (key == K_MOUSE1) //mouse clicks are deferred until the release event. this is for touch screens and aiming.
{
if (menu->mouseitem && menu->mouseitem->common.type == mt_frameend)
menu->mouseitem->frame.mousedown = true;
else
menu_mousedown = true;
}
else if (key == K_LSHIFT || key == K_RSHIFT || key == K_LALT || key == K_RALT || key == K_LCTRL || key == K_RCTRL)
; //modifiers are sent on up events instead.
else
M_Complex_Key (menu, key, unicode);
return true; //eat all keys...
}
else
{
menu_t *prev;
prev = menu->next;
if (prev)
prev->prev = menu->prev;
if (menu->prev)
menu->prev->next = menu;
if (key == K_MOUSE1 && menu_mousedown)
M_Complex_Key (menu, key, unicode);
else if (key == K_LSHIFT || key == K_RSHIFT || key == K_LALT || key == K_RALT || key == K_LCTRL || key == K_RCTRL)
M_Complex_Key (menu, key, unicode);
menu_mousedown = false;
return false;
}
}
void M_RemoveMenu (menu_t *menu)
void M_Release (menu_t *m)
{
emenu_t *menu = (emenu_t*)m;
menuoption_t *op, *oop;
if (menu->reselection)
{
@ -1750,21 +1759,6 @@ void M_RemoveMenu (menu_t *menu)
if (menu->remove)
menu->remove(menu);
if (menu == topmenu)
{
topmenu = menu->prev;
if (topmenu)
topmenu->next = NULL;
}
else
{
menu_t *prev;
prev = menu->next;
if (prev)
prev->prev = menu->prev;
if (menu->prev)
menu->prev->next = menu;
}
op = menu->options;
while(op)
@ -1789,14 +1783,41 @@ void M_RemoveMenu (menu_t *menu)
}
}
emenu_t *M_CreateMenu (int extrasize)
{
emenu_t *menu;
menu = Z_Malloc(sizeof(emenu_t)+extrasize);
menu->iszone=true;
menu->data = menu+1;
menu->menu.cursor = &key_customcursor[kc_console];
/*void (*videoreset) (struct menu_s *); //called after a video mode switch / shader reload.
void (*release) (struct menu_s *); //
qboolean (*keyevent)(struct menu_s *, qboolean isdown, unsigned int devid, int key, int unicode); //true if key was handled
qboolean (*mousemove)(struct menu_s *, qboolean abs, unsigned int devid, float x, float y);
qboolean (*joyaxis) (struct menu_s *, unsigned int devid, int axis, float val);
void (*drawmenu) (struct menu_s *);
*/
menu->menu.drawmenu = M_Draw;
menu->menu.keyevent = M_KeyEvent;
menu->menu.release = M_Release;
Menu_Push(&menu->menu, false);
return menu;
}
void M_RemoveMenu (emenu_t *menu)
{
Menu_Unlink((menu_t*)menu);
}
void M_ReloadMenus(void)
{
menu_t *m;
for (m = topmenu; m; m = m->prev)
{
if (m->reset)
m->reset(m);
if (m->videoreset)
m->videoreset(m);
}
}
@ -1807,10 +1828,10 @@ void M_RemoveAllMenus (qboolean leaveprompts)
for (link = &topmenu; *link; )
{
m = *link;
if ((m->persist || !m->exclusive) && leaveprompts)
if (m->persist && leaveprompts)
link = &m->prev;
else
M_RemoveMenu(m);
Menu_Unlink(m);
}
}
@ -1818,23 +1839,10 @@ void M_MenuPop_f (void)
{
if (!topmenu)
return;
M_RemoveMenu(topmenu);
Menu_Unlink(topmenu);
}
void M_Complex_Draw(void)
{
if (!topmenu)
{
Key_Dest_Remove(kdm_emenu);
return;
}
M_CheckMouseMove();
MenuDraw(topmenu);
}
menuoption_t *M_NextItem(menu_t *m, menuoption_t *old)
menuoption_t *M_NextItem(emenu_t *m, menuoption_t *old)
{
menuoption_t *op = m->options;
while(op->common.next)
@ -1846,7 +1854,7 @@ menuoption_t *M_NextItem(menu_t *m, menuoption_t *old)
}
return op;
}
menuoption_t *M_NextSelectableItem(menu_t *m, menuoption_t *old)
menuoption_t *M_NextSelectableItem(emenu_t *m, menuoption_t *old)
{
menuoption_t *op;
@ -1877,7 +1885,7 @@ menuoption_t *M_NextSelectableItem(menu_t *m, menuoption_t *old)
}
}
menuoption_t *M_PrevSelectableItem(menu_t *m, menuoption_t *old)
menuoption_t *M_PrevSelectableItem(emenu_t *m, menuoption_t *old)
{
menuoption_t *op;
@ -1904,13 +1912,12 @@ menuoption_t *M_PrevSelectableItem(menu_t *m, menuoption_t *old)
}
}
void M_Complex_Key(int key, int unicode)
void M_Complex_Key(emenu_t *currentmenu, int key, int unicode)
{
menu_t *currentmenu = topmenu;
if (!currentmenu)
return; //erm...
M_CheckMouseMove();
M_CheckMouseMove(currentmenu);
if (currentmenu->key)
if (currentmenu->key(key, currentmenu))
@ -2095,8 +2102,7 @@ void M_Complex_Key(int key, int unicode)
extern int m_save_demonum;
qboolean MC_Main_Key (int key, menu_t *menu) //here purly to restart demos.
qboolean MC_Main_Key (int key, emenu_t *menu) //here purly to restart demos.
{
if (key == K_ESCAPE || key == K_GP_BACK || key == K_MOUSE2)
{
@ -2106,14 +2112,11 @@ qboolean MC_Main_Key (int key, menu_t *menu) //here purly to restart demos.
if (con_stayhidden.ival && cls.state == ca_disconnected)
if (!CL_TryingToConnect())
return true;
Key_Dest_Remove(kdm_emenu);
return true;
}
return false;
}
static int M_Main_AddExtraOptions(menu_t *mainm, int y)
static int M_Main_AddExtraOptions(emenu_t *mainm, int y)
{
if (Cmd_AliasExist("mod_menu", RESTRICT_LOCAL))
{MC_AddConsoleCommandQBigFont(mainm, 72, y, va("%-14s", Cvar_Get("mod_menu", "Mod Menu", 0, NULL)->string), "mod_menu\n"); y += 20;}
@ -2142,7 +2145,7 @@ void M_Menu_Main_f (void)
{
extern cvar_t m_helpismedia;
menubutton_t *b;
menu_t *mainm = NULL;
emenu_t *mainm = NULL;
mpic_t *p;
static menuresel_t resel;
int y;
@ -2198,7 +2201,6 @@ void M_Menu_Main_f (void)
if (R_GetShaderSizes(R2D_SafeCachePic("pics/m_main_quit"), NULL, NULL, true) > 0)
{
int itemheight = 32;
Key_Dest_Add(kdm_emenu);
mainm = M_CreateMenu(0);
mainm->key = MC_Main_Key;
@ -2251,7 +2253,6 @@ void M_Menu_Main_f (void)
p = R2D_SafeCachePic("gfx/menu/title0.lmp");
if (R_GetShaderSizes(p, NULL, NULL, true) > 0)
{
Key_Dest_Add(kdm_emenu);
mainm = M_CreateMenu(0);
mainm->key = MC_Main_Key;
@ -2293,7 +2294,6 @@ void M_Menu_Main_f (void)
p = R2D_SafeCachePic("gfx/ttl_main.lmp");
if (R_GetShaderSizes(p, NULL, NULL, true) > 0)
{
Key_Dest_Add(kdm_emenu);
mainm = M_CreateMenu(0);
mainm->key = MC_Main_Key;
MC_AddPicture(mainm, 16, 4, 32, 144, "gfx/qplaque.lmp");
@ -2328,7 +2328,6 @@ void M_Menu_Main_f (void)
R2D_SafeCachePic("gfx/ttl_main.lmp");
if (R_GetShaderSizes(p, &width, NULL, true) > 0)
{
Key_Dest_Add(kdm_emenu);
mainm = M_CreateMenu(0);
mainm->key = MC_Main_Key;
@ -2379,7 +2378,6 @@ void M_Menu_Main_f (void)
if (!mainm)
{
Key_Dest_Add(kdm_emenu);
mainm = M_CreateMenu(0);
MC_AddRedText(mainm, 16, 170, 0, "MAIN MENU", false);
@ -2398,7 +2396,7 @@ void M_Menu_Main_f (void)
M_Menu_Preset_f();
}
int MC_AddBulk(struct menu_s *menu, menuresel_t *resel, menubulk_t *bulk, int xstart, int xtextend, int y)
int MC_AddBulk(struct emenu_s *menu, menuresel_t *resel, menubulk_t *bulk, int xstart, int xtextend, int y)
{
int selectedy = y;
menuoption_t *selected = NULL;

View File

@ -32,7 +32,7 @@ static int serverpreview;
extern cvar_t slist_writeserverstxt;
extern cvar_t slist_cacheinfo;
static void CalcFilters(menu_t *menu);
static void CalcFilters(emenu_t *menu);
void M_Serverlist_Init(void)
{
@ -104,7 +104,7 @@ static void SL_DrawColumnTitle (int *x, int y, int xlen, int mx, char *str, qboo
*x -= xlen + 8;
}
static void SL_TitlesDraw (int x, int y, menucustom_t *ths, menu_t *menu)
static void SL_TitlesDraw (int x, int y, menucustom_t *ths, emenu_t *menu)
{
int sf = Master_GetSortField();
int mx = mousecursor_x;
@ -128,7 +128,7 @@ static void SL_TitlesDraw (int x, int y, menucustom_t *ths, menu_t *menu)
SL_DrawColumnTitle(NULL, y, x, mx, "hostname ", (sf==SLKEY_NAME), clr, &filldraw);
}
static qboolean SL_TitlesKey (menucustom_t *ths, menu_t *menu, int key, unsigned int unicode)
static qboolean SL_TitlesKey (menucustom_t *ths, emenu_t *menu, int key, unsigned int unicode)
{
int x;
int mx = mousecursor_x/8;
@ -255,7 +255,7 @@ static servertypes_t flagstoservertype(int flags)
}
}
static void SL_ServerDraw (int x, int y, menucustom_t *ths, menu_t *menu)
static void SL_ServerDraw (int x, int y, menucustom_t *ths, emenu_t *menu)
{
serverlist_t *info = (serverlist_t*)(menu + 1);
serverinfo_t *si;
@ -305,7 +305,7 @@ static void SL_ServerDraw (int x, int y, menucustom_t *ths, menu_t *menu)
}
}
void MC_EditBox_Key(menuedit_t *edit, int key, unsigned int unicode);
static qboolean SL_ServerKey (menucustom_t *ths, menu_t *menu, int key, unsigned int unicode)
static qboolean SL_ServerKey (menucustom_t *ths, emenu_t *menu, int key, unsigned int unicode)
{
static int lastclick;
int curtime;
@ -375,7 +375,7 @@ static qboolean SL_ServerKey (menucustom_t *ths, menu_t *menu, int key, unsigned
}
return false;
}
static void SL_PreDraw (menu_t *menu)
static void SL_PreDraw (emenu_t *menu)
{
serverlist_t *info = (serverlist_t*)(menu + 1);
Master_CheckPollSockets();
@ -409,7 +409,7 @@ static void SL_PreDraw (menu_t *menu)
snprintf(info->refreshtext, sizeof(info->refreshtext), "Refresh - %u/%u/%u\n", info->numslots, Master_NumAlive(), Master_TotalCount());
}
qboolean NET_SendPollPacket(int len, void *data, netadr_t to);
static void SL_PostDraw (menu_t *menu)
static void SL_PostDraw (emenu_t *menu)
{
static char *helpstrings[] =
{
@ -725,7 +725,7 @@ static void SL_PostDraw (menu_t *menu)
}
}
}
static qboolean SL_Key (int key, menu_t *menu)
static qboolean SL_Key (int key, emenu_t *menu)
{
serverlist_t *info = (serverlist_t*)(menu + 1);
@ -916,7 +916,7 @@ dojoin:
return true;
}
static void SL_ServerPlayer (int x, int y, menucustom_t *ths, menu_t *menu)
static void SL_ServerPlayer (int x, int y, menucustom_t *ths, emenu_t *menu)
{
if (selectedserver.inuse)
{
@ -941,7 +941,7 @@ static void SL_ServerPlayer (int x, int y, menucustom_t *ths, menu_t *menu)
}
}
static void SL_SliderDraw (int x, int y, menucustom_t *ths, menu_t *menu)
static void SL_SliderDraw (int x, int y, menucustom_t *ths, emenu_t *menu)
{
extern qboolean keydown[K_MAX];
serverlist_t *info = (serverlist_t*)(menu + 1);
@ -1013,7 +1013,7 @@ static void SL_SliderDraw (int x, int y, menucustom_t *ths, menu_t *menu)
info->sliderpressed = false;
}
}
static qboolean SL_SliderKey (menucustom_t *ths, menu_t *menu, int key, unsigned int unicode)
static qboolean SL_SliderKey (menucustom_t *ths, emenu_t *menu, int key, unsigned int unicode)
{
if (key == K_MOUSE1)
{
@ -1043,7 +1043,7 @@ static qboolean SL_SliderKey (menucustom_t *ths, menu_t *menu, int key, unsigned
return false;
}
static void CalcFilters(menu_t *menu)
static void CalcFilters(emenu_t *menu)
{
serverlist_t *info = (serverlist_t*)(menu + 1);
info->filtermodcount = sb_filtertext.modified;
@ -1070,7 +1070,7 @@ static void CalcFilters(menu_t *menu)
Master_SortServers();
}
static qboolean SL_ReFilter (menucheck_t *option, menu_t *menu, chk_set_t set)
static qboolean SL_ReFilter (menucheck_t *option, emenu_t *menu, chk_set_t set)
{
serverlist_t *info = (serverlist_t*)(menu + 1);
switch(set)
@ -1097,7 +1097,7 @@ static qboolean SL_ReFilter (menucheck_t *option, menu_t *menu, chk_set_t set)
return true;
}
static void SL_Remove (menu_t *menu)
static void SL_Remove (emenu_t *menu)
{
serverlist_t *info = (serverlist_t*)(menu + 1);
@ -1108,7 +1108,7 @@ static void SL_Remove (menu_t *menu)
Cvar_Set(&sb_hidefull, info->filter[7]?"1":"0");
}
static qboolean SL_DoRefresh (menuoption_t *opt, menu_t *menu, int key)
static qboolean SL_DoRefresh (menuoption_t *opt, emenu_t *menu, int key)
{
if (key == K_MOUSE1 || key == K_MOUSE1 || key == K_ENTER || key == K_KP_ENTER)
{
@ -1122,7 +1122,7 @@ static qboolean SL_DoRefresh (menuoption_t *opt, menu_t *menu, int key)
void M_Menu_ServerList2_f(void)
{
int i, y, x;
menu_t *menu;
emenu_t *menu;
menucustom_t *cust;
serverlist_t *info;
qboolean descending;
@ -1138,7 +1138,6 @@ void M_Menu_ServerList2_f(void)
serverpreview = false; //in case it was lingering.
Key_Dest_Remove(kdm_console);
Key_Dest_Add(kdm_emenu);
menu = M_CreateMenu(sizeof(serverlist_t));
menu->predraw = SL_PreDraw;
@ -1262,7 +1261,7 @@ void M_Menu_ServerList2_f(void)
static float quickconnecttimeout;
static void M_QuickConnect_PreDraw(menu_t *menu)
static void M_QuickConnect_PreDraw(emenu_t *menu)
{
serverinfo_t *best = NULL;
serverinfo_t *s;
@ -1318,21 +1317,21 @@ static void M_QuickConnect_PreDraw(menu_t *menu)
}
}
static qboolean M_QuickConnect_Key (int key, menu_t *menu)
static qboolean M_QuickConnect_Key (int key, emenu_t *menu)
{
return false;
}
static void M_QuickConnect_Remove (menu_t *menu)
static void M_QuickConnect_Remove (emenu_t *menu)
{
}
static qboolean M_QuickConnect_Cancel (menuoption_t *opt, menu_t *menu, int key)
static qboolean M_QuickConnect_Cancel (menuoption_t *opt, emenu_t *menu, int key)
{
return false;
}
static void M_QuickConnect_DrawStatus (int x, int y, menucustom_t *ths, menu_t *menu)
static void M_QuickConnect_DrawStatus (int x, int y, menucustom_t *ths, emenu_t *menu)
{
Draw_FunString(x, y, va("Polling, %i secs\n", (int)(quickconnecttimeout - Sys_DoubleTime() + 0.9)));
}
@ -1340,9 +1339,7 @@ static void M_QuickConnect_DrawStatus (int x, int y, menucustom_t *ths, menu_t *
void M_QuickConnect_f(void)
{
menucustom_t *cust;
menu_t *menu;
Key_Dest_Add(kdm_emenu);
emenu_t *menu;
MasterInfo_Refresh(false);
isrefreshing = true;

View File

@ -128,7 +128,6 @@ cvar_t media_hijackwinamp = CVAR("media_hijackwinamp", "0");
#endif
int selectedoption=-1;
static int mouseselectedoption=-1;
int numtracks;
int nexttrack=-1;
mediatrack_t *tracks;
@ -136,6 +135,7 @@ mediatrack_t *tracks;
char media_iofilename[MAX_OSPATH]="";
#if !defined(NOMEDIAMENU) && !defined(NOBUILTINMENUS)
static int mouseselectedoption=-1;
void Media_LoadTrackNames (char *listname);
void Media_SaveTrackNames (char *listname);
int loadedtracknames;
@ -920,6 +920,8 @@ void Media_RemoveTrack(const char *fname)
}
}
}
#if !defined(NOMEDIAMENU) && !defined(NOBUILTINMENUS)
void M_Media_Add_f (void)
{
char *fname = Cmd_Argv(1);
@ -947,8 +949,6 @@ void M_Media_Remove_f (void)
}
#if !defined(NOMEDIAMENU) && !defined(NOBUILTINMENUS)
void Media_LoadTrackNames (char *listname);
#define MEDIA_MIN -7
@ -960,7 +960,7 @@ void Media_LoadTrackNames (char *listname);
#define MEDIA_SHUFFLE -2
#define MEDIA_REPEAT -1
void M_Media_Draw (menu_t *menu)
void M_Media_Draw (emenu_t *menu)
{
mediatrack_t *track;
int y;
@ -1145,7 +1145,7 @@ void Com_CompleateOSFileName(char *name)
strcpy(name, compleatenamename);
}
qboolean M_Media_Key (int key, menu_t *menu)
qboolean M_Media_Key (int key, emenu_t *menu)
{
int dir;
if (key == K_ESCAPE || key == K_GP_BACK || key == K_MOUSE2)
@ -1347,11 +1347,10 @@ qboolean M_Media_Key (int key, menu_t *menu)
void M_Menu_Media_f (void)
{
menu_t *menu;
emenu_t *menu;
if (!loadedtracknames)
Media_LoadTrackNames("sound/media.m3u");
Key_Dest_Add(kdm_emenu);
menu = M_CreateMenu(0);
// MC_AddPicture(menu, 16, 4, 32, 144, "gfx/qplaque.lmp");
@ -1668,7 +1667,8 @@ struct cin_s
qbyte *framedata; //Z_Malloced buffer
};
shader_t *videoshader;
static menu_t videomenu; //to capture keys+draws+etc. a singleton - multiple videos will be queued instead of simultaneous.
static shader_t *videoshader;
//////////////////////////////////////////////////////////////////////////////////
//AVI Support (windows)
@ -2412,11 +2412,6 @@ static cin_t *Media_Cin_TryLoad(char *name)
//Quake2 CIN Support
//////////////////////////////////////////////////////////////////////////////////
qboolean Media_PlayingFullScreen(void)
{
return videoshader!=NULL;
}
void Media_ShutdownCin(cin_t *cin)
{
if (!cin)
@ -2473,12 +2468,75 @@ cin_t *Media_StartCin(char *name)
return cin;
}
struct pendingfilms_s
static struct pendingfilms_s
{
struct pendingfilms_s *next;
char name[1];
} *pendingfilms;
qboolean Media_BeginNextFilm(void)
static void MediaView_DrawFilm(menu_t *m)
{
if (videoshader)
{
cin_t *cin = R_ShaderGetCinematic(videoshader);
if (cin && cin->playstate == CINSTATE_INVALID)
Media_SetState(cin, CINSTATE_PLAY); //err... wot? must have vid_reloaded or something
if (cin && cin->playstate == CINSTATE_ENDED)
Media_StopFilm(false);
else if (cin)
{
int cw, ch;
float aspect;
if (cin->cursormove)
cin->cursormove(cin, mousecursor_x/(float)vid.width, mousecursor_y/(float)vid.height);
if (cin->setsize)
cin->setsize(cin, vid.pixelwidth, vid.pixelheight);
//FIXME: should have a proper aspect ratio setting. RoQ files are always power of two, which makes things ugly.
if (cin->getsize)
cin->getsize(cin, &cw, &ch, &aspect);
else
{
cw = 4;
ch = 3;
}
R2D_Letterbox(0, 0, vid.fbvwidth, vid.fbvheight, videoshader, cw, ch);
SCR_SetUpToDrawConsole();
if (scr_con_current)
SCR_DrawConsole (false);
}
}
else if (!videoshader)
Menu_Unlink(m);
}
static qboolean MediaView_KeyEvent(menu_t *m, qboolean isdown, unsigned int devid, int key, int unicode)
{
if (isdown && key == K_ESCAPE)
{
Media_StopFilm(false); //skip to the next.
return true;
}
Media_Send_KeyEvent(NULL, key, unicode, !isdown);
return true;
}
static qboolean MediaView_MouseMove(menu_t *m, qboolean isabs, unsigned int devid, float x, float y)
{
cin_t *cin;
cin = R_ShaderGetCinematic(videoshader);
if (!cin || !cin->cursormove)
return false;
if (isabs)
cin->cursormove(cin, x, y);
return true;
}
static void MediaView_StopFilm(menu_t *m)
{ //display is going away for some reason. might as well kill them all
Media_StopFilm(true);
}
static qboolean Media_BeginNextFilm(void)
{
cin_t *cin;
char sname[MAX_QPATH];
@ -2513,6 +2571,19 @@ qboolean Media_BeginNextFilm(void)
videoshader = NULL;
}
Z_Free(p);
if (videoshader)
{
videomenu.cursor = NULL;
videomenu.release = MediaView_StopFilm;
videomenu.drawmenu = MediaView_DrawFilm;
videomenu.mousemove = MediaView_MouseMove;
videomenu.keyevent = MediaView_KeyEvent;
videomenu.isopaque = true;
Menu_Push(&videomenu, false);
}
else
Menu_Unlink(&videomenu);
return !!videoshader;
}
qboolean Media_StopFilm(qboolean all)
@ -2580,12 +2651,6 @@ qboolean Media_PlayFilm(char *name, qboolean enqueue)
#endif
SCR_EndLoadingPlaque();
if (Key_Dest_Has(kdm_emenu))
Key_Dest_Remove(kdm_emenu);
#ifdef MENU_DAT
if (Key_Dest_Has(kdm_gmenu))
MP_Toggle(0);
#endif
if (!Key_Dest_Has(kdm_console))
scr_con_current=0;
return true;
@ -2593,45 +2658,6 @@ qboolean Media_PlayFilm(char *name, qboolean enqueue)
else
return false;
}
qboolean Media_ShowFilm(void)
{
if (videoshader)
{
cin_t *cin = R_ShaderGetCinematic(videoshader);
if (cin && cin->playstate == CINSTATE_INVALID)
Media_SetState(cin, CINSTATE_PLAY); //err... wot? must have vid_reloaded or something
if (cin && cin->playstate == CINSTATE_ENDED)
{
Media_StopFilm(false);
}
else if (cin)
{
int cw, ch;
float aspect;
if (cin->cursormove)
cin->cursormove(cin, mousecursor_x/(float)vid.width, mousecursor_y/(float)vid.height);
if (cin->setsize)
cin->setsize(cin, vid.pixelwidth, vid.pixelheight);
//FIXME: should have a proper aspect ratio setting. RoQ files are always power of two, which makes things ugly.
if (cin->getsize)
cin->getsize(cin, &cw, &ch, &aspect);
else
{
cw = 4;
ch = 3;
}
R2D_Letterbox(0, 0, vid.fbvwidth, vid.fbvheight, videoshader, cw, ch);
SCR_SetUpToDrawConsole();
if (scr_con_current)
SCR_DrawConsole (false);
return true;
}
}
return false;
}
#ifndef SERVERONLY
void QDECL Media_UpdateTexture(void *ctx, uploadfmt_t fmt, int width, int height, void *data, void *palette)
@ -2852,8 +2878,6 @@ void Media_PlayVideoWindowed_f (void)
Con_SetActive(con);
}
#else
qboolean Media_ShowFilm(void){return false;}
#endif //HAVE_MEDIA_DECODER
@ -4116,12 +4140,9 @@ void Media_RecordDemo_f(void)
//FIXME: make sure it loaded okay
Media_RecordFilm(videoname, true);
scr_con_current=0;
Key_Dest_Remove(kdm_console|kdm_emenu);
#ifdef MENU_DAT
if (Key_Dest_Has(kdm_gmenu))
MP_Toggle(0);
#endif
Menu_PopAll();
Key_Dest_Remove(kdm_console);
if (!currentcapture_funcs)
CL_Stopdemo_f(); //capturing failed for some reason
@ -5123,9 +5144,9 @@ void Media_Init(void)
#endif
Cvar_Register(&media_shuffle, "Media player things");
Cvar_Register(&media_repeat, "Media player things");
Cmd_AddCommand ("media_add", M_Media_Add_f);
Cmd_AddCommand ("media_remove", M_Media_Remove_f);
#if !defined(NOMEDIAMENU) && !defined(NOBUILTINMENUS)
Cmd_AddCommand ("media_add", M_Media_Add_f);
Cmd_AddCommand ("media_remove", M_Media_Remove_f);
Cmd_AddCommand ("menu_media", M_Menu_Media_f);
#endif
#endif

View File

@ -12,13 +12,12 @@ extern cvar_t maxclients;
void M_Menu_MultiPlayer_f (void)
{
menubutton_t *b;
menu_t *menu;
emenu_t *menu;
mpic_t *p;
int mgt;
static menuresel_t resel;
p = NULL;
Key_Dest_Add(kdm_emenu);
mgt = M_GameType();
@ -133,7 +132,7 @@ typedef struct {
int tiwidth, tiheight;
qbyte translationimage[128*128];
} setupmenu_t;
qboolean ApplySetupMenu (union menuoption_s *option,struct menu_s *menu, int key)
qboolean ApplySetupMenu (union menuoption_s *option,struct emenu_s *menu, int key)
{
char bot[64], top[64];
setupmenu_t *info = menu->data;
@ -218,7 +217,7 @@ static unsigned int hsvtorgb(float inh, float s, float v)
return 0xff000000 | (r<<16)|(g<<8)|(b<<0);
};
qboolean SetupMenuColour (union menuoption_s *option,struct menu_s *menu, int key)
qboolean SetupMenuColour (union menuoption_s *option,struct emenu_s *menu, int key)
{
extern qboolean keydown[K_MAX];
setupmenu_t *info = menu->data;
@ -312,7 +311,7 @@ void q2skin_destroy(q2skinsearch_t *s)
BZ_Free(s);
}
qboolean MSetupQ2_ChangeSkin (struct menucustom_s *option,struct menu_s *menu, int key, unsigned int unicode)
qboolean MSetupQ2_ChangeSkin (struct menucustom_s *option,struct emenu_s *menu, int key, unsigned int unicode)
{
setupmenu_t *info = menu->data;
q2skinsearch_t *s = Z_Malloc(sizeof(*s));
@ -340,7 +339,7 @@ qboolean MSetupQ2_ChangeSkin (struct menucustom_s *option,struct menu_s *menu, i
q2skin_destroy(s);
return true;
}
void MSetupQ2_TransDraw (int x, int y, menucustom_t *option, menu_t *menu)
void MSetupQ2_TransDraw (int x, int y, menucustom_t *option, emenu_t *menu)
{
setupmenu_t *info = menu->data;
mpic_t *p;
@ -364,7 +363,7 @@ void MSetupQ2_TransDraw (int x, int y, menucustom_t *option, menu_t *menu)
R2D_ScalePic (x, y-8, w, h, p);
}
void MSetup_TransDraw (int x, int y, menucustom_t *option, menu_t *menu)
void MSetup_TransDraw (int x, int y, menucustom_t *option, emenu_t *menu)
{
unsigned int translationTable[256];
setupmenu_t *info = menu->data;
@ -431,7 +430,7 @@ void MSetup_TransDraw (int x, int y, menucustom_t *option, menu_t *menu)
void M_Menu_Setup_f (void)
{
setupmenu_t *info;
menu_t *menu;
emenu_t *menu;
menucustom_t *ci;
menubutton_t *b;
static menuresel_t resel;
@ -446,7 +445,6 @@ void M_Menu_Setup_f (void)
NULL
};
menucustom_t *cu;
Key_Dest_Add(kdm_emenu);
menu = M_CreateMenu(sizeof(setupmenu_t));
info = menu->data;
@ -470,8 +468,6 @@ void M_Menu_Setup_f (void)
}
#endif
Key_Dest_Add(kdm_emenu);
menu = M_CreateMenu(sizeof(setupmenu_t));
info = menu->data;
@ -563,7 +559,7 @@ static const char *numplayeroptions[] = {
NULL
};
qboolean MultiBeginGame (union menuoption_s *option,struct menu_s *menu, int key)
qboolean MultiBeginGame (union menuoption_s *option,struct emenu_s *menu, int key)
{
newmultimenu_t *info = menu->data;
if (key != K_ENTER && key != K_KP_ENTER && key != K_GP_START && key != K_MOUSE1)
@ -652,13 +648,11 @@ void M_Menu_GameOptions_f (void)
NULL
};
newmultimenu_t *info;
menu_t *menu;
emenu_t *menu;
int y = 40;
int mgt;
int players;
Key_Dest_Add(kdm_emenu);
menu = M_CreateMenu(sizeof(newmultimenu_t));
info = menu->data;
@ -757,13 +751,12 @@ void M_Menu_Teamplay_f (void)
MB_END()
};
static menuresel_t resel;
menu_t *menu = M_Options_Title(&y, 0);
emenu_t *menu = M_Options_Title(&y, 0);
MC_AddBulk(menu, &resel, bulk, 16, 200, y);
}
void M_Menu_Teamplay_Locations_f (void)
{
menu_t *menu;
int y;
menubulk_t bulk[] =
{
@ -792,13 +785,12 @@ void M_Menu_Teamplay_Locations_f (void)
MB_END()
};
static menuresel_t resel;
menu = M_Options_Title(&y, 0);
emenu_t *menu = M_Options_Title(&y, 0);
MC_AddBulk(menu, &resel, bulk, 16, 200, y);
}
void M_Menu_Teamplay_Needs_f (void)
{
menu_t *menu;
int y;
menubulk_t bulk[] =
{
@ -819,13 +811,12 @@ void M_Menu_Teamplay_Needs_f (void)
MB_END()
};
static menuresel_t resel;
menu = M_Options_Title(&y, 0);
emenu_t *menu = M_Options_Title(&y, 0);
MC_AddBulk(menu, &resel, bulk, 16, 200, y);
}
void M_Menu_Teamplay_Items_f (void)
{
menu_t *menu;
int y;
menubulk_t bulk[] =
{
@ -840,13 +831,12 @@ void M_Menu_Teamplay_Items_f (void)
MB_END()
};
static menuresel_t resel;
menu = M_Options_Title(&y, 0);
emenu_t *menu = M_Options_Title(&y, 0);
MC_AddBulk(menu, &resel, bulk, 16, 224, y);
}
void M_Menu_Teamplay_Items_Armor_f (void)
{
menu_t *menu;
int y;
menubulk_t bulk[] =
{
@ -863,13 +853,12 @@ void M_Menu_Teamplay_Items_Armor_f (void)
MB_END()
};
static menuresel_t resel;
menu = M_Options_Title(&y, 0);
emenu_t *menu = M_Options_Title(&y, 0);
MC_AddBulk(menu, &resel, bulk, 16, 200, y);
}
void M_Menu_Teamplay_Items_Weapons_f (void)
{
menu_t *menu;
int y;
menubulk_t bulk[] =
{
@ -888,13 +877,12 @@ void M_Menu_Teamplay_Items_Weapons_f (void)
MB_END()
};
static menuresel_t resel;
menu = M_Options_Title(&y, 0);
emenu_t *menu = M_Options_Title(&y, 0);
MC_AddBulk(menu, &resel, bulk, 16, 200, y);
}
void M_Menu_Teamplay_Items_Powerups_f (void)
{
menu_t *menu;
int y;
menubulk_t bulk[] =
{
@ -916,13 +904,12 @@ void M_Menu_Teamplay_Items_Powerups_f (void)
MB_END()
};
static menuresel_t resel;
menu = M_Options_Title(&y, 0);
emenu_t *menu = M_Options_Title(&y, 0);
MC_AddBulk(menu, &resel, bulk, 16, 200, y);
}
void M_Menu_Teamplay_Items_Ammo_Health_f (void)
{
menu_t *menu;
int y;
menubulk_t bulk[] =
{
@ -939,13 +926,12 @@ void M_Menu_Teamplay_Items_Ammo_Health_f (void)
MB_END()
};
static menuresel_t resel;
menu = M_Options_Title(&y, 0);
emenu_t *menu = M_Options_Title(&y, 0);
MC_AddBulk(menu, &resel, bulk, 16, 200, y);
}
void M_Menu_Teamplay_Items_Team_Fortress_f (void)
{
menu_t *menu;
int y;
menubulk_t bulk[] =
{
@ -957,13 +943,12 @@ void M_Menu_Teamplay_Items_Team_Fortress_f (void)
MB_END()
};
static menuresel_t resel;
menu = M_Options_Title(&y, 0);
emenu_t *menu = M_Options_Title(&y, 0);
MC_AddBulk(menu, &resel, bulk, 16, 200, y);
}
void M_Menu_Teamplay_Items_Status_Location_Misc_f (void)
{
menu_t *menu;
int y;
menubulk_t bulk[] =
{
@ -985,7 +970,7 @@ void M_Menu_Teamplay_Items_Status_Location_Misc_f (void)
MB_END()
};
static menuresel_t resel;
menu = M_Options_Title(&y, 0);
emenu_t *menu = M_Options_Title(&y, 0);
MC_AddBulk(menu, &resel, bulk, 16, 200, y);
}
@ -1026,7 +1011,6 @@ void M_Menu_Network_f (void)
static const char *smoothingvalues[] = {"0", "1", "2", NULL};
extern cvar_t cl_download_csprogs, cl_download_redirection, requiredownloads, cl_solid_players;
extern cvar_t cl_predict_players, cl_predict_smooth, cl_predict_extrapolate;
menu_t *menu;
static menuresel_t resel;
int y;
menubulk_t bulk[] =
@ -1050,7 +1034,7 @@ void M_Menu_Network_f (void)
#endif
MB_END()
};
menu = M_Options_Title(&y, 0);
emenu_t *menu = M_Options_Title(&y, 0);
MC_AddBulk(menu, &resel, bulk, 16, 200, y);
}
#endif

View File

@ -8,6 +8,55 @@ extern unsigned int r2d_be_flags;
#include "shader.h"
#include "cl_master.h"
//static void MN_Menu_VideoReset(struct menu_s *m);
//static void MN_Menu_Released(struct menu_s *m);
static qboolean MN_Menu_KeyEvent(struct menu_s *m, qboolean isdown, unsigned int devid, int key, int unicode)
{
if (mn_entry && mn_entry->InputEvent)
{
void *nctx = (m->ctx==libmenu)?NULL:m->ctx;
struct menu_inputevent_args_s ev = {isdown?MIE_KEYDOWN:MIE_KEYUP, devid};
ev.key.scancode = key;
ev.key.charcode = unicode;
return mn_entry->InputEvent(nctx, ev);
}
return false;
}
static qboolean MN_Menu_MouseMove(struct menu_s *m, qboolean abs, unsigned int devid, float x, float y)
{
if (mn_entry && mn_entry->InputEvent)
{
void *nctx = (m->ctx==libmenu)?NULL:m->ctx;
struct menu_inputevent_args_s ev = {abs?MIE_MOUSEABS:MIE_MOUSEDELTA, devid};
ev.mouse.delta[0] = x;
ev.mouse.delta[1] = y;
ev.mouse.screen[0] = mousecursor_x;
ev.mouse.screen[1] = mousecursor_y;
return mn_entry->InputEvent(nctx, ev);
}
return false;
}
static qboolean MN_Menu_JoyAxis(struct menu_s *m, unsigned int devid, int axis, float val)
{
if (mn_entry && mn_entry->InputEvent)
{
void *nctx = (m->ctx==libmenu)?NULL:m->ctx;
struct menu_inputevent_args_s ev = {MIE_JOYAXIS, devid};
ev.axis.axis = axis;
ev.axis.val = val;
return mn_entry->InputEvent(nctx, ev);
}
return false;
}
static void MN_Menu_DrawMenu(struct menu_s *m)
{
void *nctx = (m->ctx==libmenu)?NULL:m->ctx;
if (mn_entry && mn_entry->Draw)
mn_entry->Draw(nctx, host_frametime);
else
Menu_Unlink(m);
}
static int MN_CheckExtension(const char *extname)
{
unsigned int i;
@ -149,42 +198,60 @@ static void MN_DrawResetClipArea(void)
R2D_Flush();
BE_Scissor(NULL);
}
static qboolean MN_SetKeyDest(qboolean focused)
static void MN_PushMenu(void *ctx)
{
qboolean ret = Key_Dest_Has(kdm_nmenu);
if (ret == focused)
return false;
if (focused)
{
if (key_dest_absolutemouse & kdm_nmenu)
{ //we're activating the mouse cursor now... make sure the position is actually current.
//FIXME: we should probably get the input code to do this for us when switching cursor modes.
struct menu_inputevent_args_s ev = {MIE_MOUSEABS, -1};
ev.mouse.screen[0] = (mousecursor_x * vid.width) / vid.pixelwidth;
ev.mouse.screen[1] = (mousecursor_y * vid.height) / vid.pixelheight;
mn_entry->InputEvent(ev);
}
Key_Dest_Add(kdm_nmenu);
menu_t *m;
if (!ctx)
ctx = libmenu; //to match kill
m = Menu_FindContext(ctx);
if (!m)
{ //not created yet.
m = Z_Malloc(sizeof(*m));
m->ctx = ctx;
// m->videoreset = MN_Menu_VideoReset;
// m->release = MN_Menu_Released;
m->keyevent = MN_Menu_KeyEvent;
m->mousemove = MN_Menu_MouseMove;
m->joyaxis = MN_Menu_JoyAxis;
m->drawmenu = MN_Menu_DrawMenu;
}
m->cursor = &key_customcursor[kc_nativemenu];
Menu_Push(m, false);
if (ctx == libmenu)
ctx = NULL;
if (m->cursor)
{ //we're activating the mouse cursor now... make sure the position is actually current.
//FIXME: we should probably get the input code to do this for us when switching cursor modes.
struct menu_inputevent_args_s ev = {MIE_MOUSEABS, -1};
ev.mouse.screen[0] = mousecursor_x;
ev.mouse.screen[1] = mousecursor_y;
mn_entry->InputEvent(ctx, ev);
}
else
Key_Dest_Remove(kdm_nmenu);
return true;
}
static int MN_GetKeyDest(void)
static qboolean MN_IsMenuPushed(void *ctx)
{
if (Key_Dest_Has(kdm_nmenu))
{
if (Key_Dest_Has_Higher(kdm_nmenu))
return -1;
return 1;
}
return 0;
menu_t *m;
if (!ctx)
ctx = libmenu; //to match kill
m = Menu_FindContext(ctx);
return !!m;
}
static void MN_KillMenu(void *ctx)
{
menu_t *m;
if (!ctx)
ctx = libmenu; //don't allow null contexts, because that screws up any other menus.
m = Menu_FindContext(ctx);
if (m)
Menu_Unlink(m);
}
static int MN_SetMouseTarget(const char *cursorname, float hot_x, float hot_y, float scale)
{
if (cursorname)
{
struct key_cursor_s *m = &key_customcursor[kc_nmenu];
struct key_cursor_s *m = &key_customcursor[kc_nativemenu];
if (scale <= 0)
scale = 1;
if (!strcmp(m->name, cursorname) || m->hotspot[0] != hot_x || m->hotspot[1] != hot_y || m->scale != scale)
@ -195,10 +262,7 @@ static int MN_SetMouseTarget(const char *cursorname, float hot_x, float hot_y, f
m->scale = scale;
m->dirty = true;
}
key_dest_absolutemouse |= kdm_nmenu;
}
else
key_dest_absolutemouse &= ~kdm_nmenu;
return true;
}
@ -300,7 +364,6 @@ static void MN_RenderScene(menuscene_t *scene)
void MN_Shutdown(void)
{
Key_Dest_Remove(kdm_nmenu);
if (mn_entry)
{
mn_entry->Shutdown(MI_INIT);
@ -367,8 +430,9 @@ qboolean MN_Init(void)
MN_RenderScene,
// Menu specific stuff
MN_SetKeyDest,
MN_GetKeyDest,
MN_PushMenu,
MN_IsMenuPushed,
MN_KillMenu,
MN_SetMouseTarget,
Key_KeynumToString,
Key_StringToKeynum,
@ -420,8 +484,6 @@ qboolean MN_Init(void)
{
imports.engine_version = version_string();
key_dest_absolutemouse |= kdm_nmenu;
mn_entry = pGetMenuAPI (&imports);
if (mn_entry && mn_entry->api_version >= NATIVEMENU_API_VERSION_MIN && mn_entry->api_version <= NATIVEMENU_API_VERSION_MAX)
{

View File

@ -110,13 +110,11 @@ qboolean M_Vid_GetMode(qboolean forfullscreen, int num, int *w, int *h)
extern qboolean forcesaveprompt;
extern cvar_t pr_debugger;
menu_t *M_Options_Title(int *y, int infosize)
emenu_t *M_Options_Title(int *y, int infosize)
{
struct menu_s *menu;
struct emenu_s *menu;
*y = 32;
Key_Dest_Add(kdm_emenu);
menu = M_CreateMenu(infosize);
switch(M_GameType())
@ -140,7 +138,7 @@ menu_t *M_Options_Title(int *y, int infosize)
}
//these are awkward/strange
qboolean M_Options_AlwaysRun (menucheck_t *option, struct menu_s *menu, chk_set_t set)
qboolean M_Options_AlwaysRun (menucheck_t *option, struct emenu_s *menu, chk_set_t set)
{
if (M_GameType() == MGT_QUAKE2)
{
@ -171,7 +169,7 @@ qboolean M_Options_AlwaysRun (menucheck_t *option, struct menu_s *menu, chk_set_
}
}
}
qboolean M_Options_InvertMouse (menucheck_t *option, struct menu_s *menu, chk_set_t set)
qboolean M_Options_InvertMouse (menucheck_t *option, struct emenu_s *menu, chk_set_t set)
{
if (set == CHK_CHECKED)
return m_pitch.value < 0;
@ -341,7 +339,7 @@ void M_Menu_Options_f (void)
// removed singleplayer cheats (move this to single player menu)
MB_END()
};
menu_t *menu = M_Options_Title(&y, 0);
emenu_t *menu = M_Options_Title(&y, 0);
static menuresel_t resel;
int framey = y;
@ -383,7 +381,7 @@ typedef struct {
soundcardinfo_t *card;
} audiomenuinfo_t;
qboolean M_Audio_Key (int key, struct menu_s *menu)
qboolean M_Audio_Key (int key, struct emenu_s *menu)
{
int i;
audiomenuinfo_t *info = menu->data;
@ -432,7 +430,7 @@ qboolean M_Audio_Key (int key, struct menu_s *menu)
return false;
}
void M_Audio_StartSound (struct menu_s *menu)
void M_Audio_StartSound (struct emenu_s *menu)
{
int i;
vec3_t org;
@ -477,9 +475,7 @@ void M_Menu_Audio_Speakers_f (void)
{
int i;
audiomenuinfo_t *info;
menu_t *menu;
Key_Dest_Add(kdm_emenu);
emenu_t *menu;
menu = M_CreateMenu(sizeof(audiomenuinfo_t));
info = menu->data;
@ -505,7 +501,7 @@ struct audiomenuinfo
char **capdevdescs;
#endif
};
void M_Menu_Audio_Remove(menu_t *menu)
void M_Menu_Audio_Remove(emenu_t *menu)
{
int i;
struct audiomenuinfo *info = menu->data;
@ -524,7 +520,7 @@ void M_Menu_Audio_Remove(menu_t *menu)
Z_Free(info->capdevdescs);
#endif
}
struct audiomenuinfo *M_Menu_Audio_Setup(menu_t *menu)
struct audiomenuinfo *M_Menu_Audio_Setup(emenu_t *menu)
{
#ifdef VOICECHAT
extern cvar_t snd_voip_capturedevice_opts;
@ -564,7 +560,7 @@ struct audiomenuinfo *M_Menu_Audio_Setup(menu_t *menu)
void M_Menu_Audio_f (void)
{
int y;
menu_t *menu = M_Options_Title(&y, sizeof(struct audiomenuinfo));
emenu_t *menu = M_Options_Title(&y, sizeof(struct audiomenuinfo));
struct audiomenuinfo *info = M_Menu_Audio_Setup(menu);
extern cvar_t nosound, snd_leftisright, snd_device, snd_khz, snd_speakers, ambient_level, bgmvolume, snd_playersoundvolume, ambient_fade, cl_staticsounds, snd_inactive, _snd_mixahead, snd_doppler;
// extern cvar_t snd_noextraupdate, snd_eax, precache;
@ -720,7 +716,7 @@ void M_Menu_Audio_f (void)
void M_Menu_Particles_f (void)
{
menu_t *menu;
emenu_t *menu;
extern cvar_t r_bouncysparks, r_part_rain, gl_part_flame, r_grenadetrail, r_rockettrail, r_part_rain_quantity, r_particledesc, r_particle_tracelimit, r_part_contentswitch, r_bloodstains;
// extern cvar_t r_part_sparks_trifan, r_part_sparks_textured, r_particlesystem;
@ -1022,7 +1018,7 @@ static void ApplyPreset (int presetnum)
void M_Menu_Preset_f (void)
{
extern cvar_t cfg_save_auto;
menu_t *menu;
emenu_t *menu;
int y;
menubulk_t bulk[] =
{
@ -1214,7 +1210,7 @@ void FPS_Preset_f (void)
Con_Printf("%s\n", presetname[i]);
}
qboolean M_PresetApply (union menuoption_s *op, struct menu_s *menu, int key)
qboolean M_PresetApply (union menuoption_s *op, struct emenu_s *menu, int key)
{
fpsmenuinfo_t *info = (fpsmenuinfo_t*)menu->data;
@ -1267,7 +1263,7 @@ void M_Menu_FPS_f (void)
static const char *values_0_1_2[] = {"0", "1", "2", NULL};
static const char *values_0_1[] = {"0", "1", NULL};
menu_t *menu;
emenu_t *menu;
fpsmenuinfo_t *info;
extern cvar_t v_contentblend, show_fps, cl_r2g, cl_gibfilter, cl_expsprite, cl_deadbodyfilter, cl_lerp_players, cl_nolerp, cl_maxfps, cl_yieldcpu;
@ -1327,7 +1323,7 @@ void M_Menu_Render_f (void)
static const char *cshiftopts[] = {"Off", "Fullscreen", "Edges", NULL};
static const char *cshiftvalues[] = {"0", "1", "2", NULL};
menu_t *menu;
emenu_t *menu;
extern cvar_t r_novis, cl_item_bobbing, r_waterwarp, r_nolerp, r_noframegrouplerp, r_fastsky, gl_nocolors, gl_lerpimages, r_wateralpha, r_drawviewmodel, gl_cshiftenabled, r_hdr_irisadaptation, scr_logcenterprint, r_fxaa, r_graphics;
#ifdef GLQUAKE
extern cvar_t r_bloom;
@ -1459,7 +1455,7 @@ void M_Menu_Textures_f (void)
MB_COMBOCVAR("Max Texture Size", gl_max_size, texturesizeoptions, texturesizeoptions, NULL),
MB_END()
};
menu_t *menu = M_Options_Title(&y, 0);
emenu_t *menu = M_Options_Title(&y, 0);
static menuresel_t resel;
MC_AddFrameStart(menu, y);
MC_AddBulk(menu, &resel, bulk, 16, 216, y);
@ -1471,7 +1467,7 @@ typedef struct {
menucombo_t *dlightcombo;
} lightingmenuinfo_t;
qboolean M_VideoApplyShadowLighting (union menuoption_s *op,struct menu_s *menu,int key)
qboolean M_VideoApplyShadowLighting (union menuoption_s *op,struct emenu_s *menu,int key)
{
lightingmenuinfo_t *info = (lightingmenuinfo_t*)menu->data;
@ -1686,7 +1682,7 @@ void M_Menu_Lighting_f (void)
};
int y;
menu_t *menu = M_Options_Title(&y, sizeof(lightingmenuinfo_t));
emenu_t *menu = M_Options_Title(&y, sizeof(lightingmenuinfo_t));
int lightselect, dlightselect;
@ -1934,7 +1930,7 @@ static const char *mapoptions_q2[] =
#endif
#endif
qboolean M_Apply_SP_Cheats (union menuoption_s *op,struct menu_s *menu,int key)
qboolean M_Apply_SP_Cheats (union menuoption_s *op,struct emenu_s *menu,int key)
{
singleplayerinfo_t *info = menu->data;
@ -1988,7 +1984,7 @@ void M_Menu_Singleplayer_Cheats_Quake (void)
singleplayerinfo_t *info;
int cursorpositionY;
int y;
menu_t *menu = M_Options_Title(&y, sizeof(*info));
emenu_t *menu = M_Options_Title(&y, sizeof(*info));
info = menu->data;
cursorpositionY = (y + 24);
@ -2053,7 +2049,7 @@ menucombo_t *skillcombo;
menucombo_t *mapcombo;
} singleplayerq2info_t;
qboolean M_Apply_SP_Cheats_Q2 (union menuoption_s *op,struct menu_s *menu,int key)
qboolean M_Apply_SP_Cheats_Q2 (union menuoption_s *op,struct emenu_s *menu,int key)
{
singleplayerq2info_t *info = menu->data;
@ -2102,7 +2098,7 @@ void M_Menu_Singleplayer_Cheats_Quake2 (void)
extern cvar_t host_mapname;
#endif
int y;
menu_t *menu = M_Options_Title(&y, sizeof(*info));
emenu_t *menu = M_Options_Title(&y, sizeof(*info));
info = menu->data;
cursorpositionY = (y + 24);
@ -2176,7 +2172,7 @@ menucombo_t *skillcombo;
menucombo_t *mapcombo;
} singleplayerh2info_t;
qboolean M_Apply_SP_Cheats_H2 (union menuoption_s *op,struct menu_s *menu,int key)
qboolean M_Apply_SP_Cheats_H2 (union menuoption_s *op,struct emenu_s *menu,int key)
{
singleplayerh2info_t *info = menu->data;
@ -2384,7 +2380,7 @@ void M_Menu_Singleplayer_Cheats_Hexen2 (void)
#endif
extern cvar_t host_mapname;
int y;
menu_t *menu = M_Options_Title(&y, sizeof(*info));
emenu_t *menu = M_Options_Title(&y, sizeof(*info));
info = menu->data;
cursorpositionY = (y + 24);
@ -2565,7 +2561,7 @@ typedef struct {
menucombo_t *res2dsize[ASPECT_RATIOS];
} videomenuinfo_t;
void CheckCustomMode(struct menu_s *menu)
void CheckCustomMode(struct emenu_s *menu)
{
int i, sel;
videomenuinfo_t *info = (videomenuinfo_t*)menu->data;
@ -2658,7 +2654,7 @@ int M_MatchModes(int width, int height, int *outres)
return ratio;
}
qboolean M_VideoApply (union menuoption_s *op, struct menu_s *menu, int key)
qboolean M_VideoApply (union menuoption_s *op, struct emenu_s *menu, int key)
{
extern cvar_t vid_desktopsettings;
videomenuinfo_t *info = (videomenuinfo_t*)menu->data;
@ -2986,11 +2982,10 @@ void M_Menu_Video_f (void)
int y;
int resmodechoice, res2dmodechoice;
int reschoices[ASPECT_RATIOS], res2dchoices[ASPECT_RATIOS];
menu_t *menu;
emenu_t *menu;
//not calling M_Options_Title because of quake2's different banner.
y = 32;
Key_Dest_Add(kdm_emenu);
menu = M_CreateMenu(sizeof(videomenuinfo_t));
switch(M_GameType())
{
@ -3252,7 +3247,7 @@ static unsigned int tobit(unsigned int bitmask)
}
return 0;
}
static void M_ModelViewerDraw(int x, int y, struct menucustom_s *c, struct menu_s *m)
static void M_ModelViewerDraw(int x, int y, struct menucustom_s *c, struct emenu_s *m)
{
static playerview_t pv;
entity_t ent;
@ -3813,7 +3808,7 @@ static void M_ModelViewerDraw(int x, int y, struct menucustom_s *c, struct menu_
break;
}
}
static qboolean M_ModelViewerKey(struct menucustom_s *c, struct menu_s *m, int key, unsigned int unicode)
static qboolean M_ModelViewerKey(struct menucustom_s *c, struct emenu_s *m, int key, unsigned int unicode)
{
modelview_t *mods = c->dptr;
@ -3927,7 +3922,7 @@ static qboolean M_ModelViewerKey(struct menucustom_s *c, struct menu_s *m, int k
}
#ifdef RAGDOLL
void M_Modelviewer_Shutdown(struct menu_s *menu)
void M_Modelviewer_Shutdown(struct emenu_s *menu)
{
modelview_t *mv = menu->data;
rag_removedeltaent(&mv->ragent);
@ -3949,9 +3944,7 @@ void M_Menu_ModelViewer_f(void)
{
modelview_t *mv;
menucustom_t *c;
menu_t *menu;
Key_Dest_Add(kdm_emenu);
emenu_t *menu;
menu = M_CreateMenu(sizeof(*mv));
mv = menu->data;
@ -4028,7 +4021,7 @@ typedef struct
size_t nummods;
} modmenu_t;
static void Mods_Draw(int x, int y, struct menucustom_s *c, struct menu_s *m)
static void Mods_Draw(int x, int y, struct menucustom_s *c, struct emenu_s *m)
{
modmenu_t *mods = c->dptr;
int i = c->dint;
@ -4069,7 +4062,7 @@ static void Mods_Draw(int x, int y, struct menucustom_s *c, struct menu_s *m)
Draw_FunString(x, y, mods->mod[i].gamedir);
}
}
static qboolean Mods_Key(struct menucustom_s *c, struct menu_s *m, int key, unsigned int unicode)
static qboolean Mods_Key(struct menucustom_s *c, struct emenu_s *m, int key, unsigned int unicode)
{
modmenu_t *mods = c->dptr;
int i;
@ -4102,7 +4095,7 @@ static qboolean Mods_Key(struct menucustom_s *c, struct menu_s *m, int key, unsi
return false;
}
static void Mods_Remove (struct menu_s *m)
static void Mods_Remove (struct emenu_s *m)
{
modmenu_t *mods = m->data;
int i;
@ -4170,7 +4163,7 @@ void M_Menu_Mods_f (void)
{
modmenu_t mods;
menucustom_t *c;
menu_t *menu;
emenu_t *menu;
size_t i;
extern qboolean com_homepathenabled;
@ -4183,8 +4176,6 @@ void M_Menu_Mods_f (void)
//FIXME: sort by mtime?
Key_Dest_Add(kdm_emenu);
menu = M_CreateMenu(sizeof(modmenu_t));
*(modmenu_t*)menu->data = mods;
if (COM_FCheckExists("gfx/p_option.lmp"))

View File

@ -6,9 +6,9 @@
#ifndef NOBUILTINMENUS
int selectitem;
menu_t *menu_script;
emenu_t *menu_script;
void M_Script_Option (menu_t *menu, char *optionvalue, qboolean isexplicit)
void M_Script_Option (emenu_t *menu, char *optionvalue, qboolean isexplicit)
{
menuoption_t *mo;
char *scriptname = menu->data;
@ -50,14 +50,14 @@ void M_Script_Option (menu_t *menu, char *optionvalue, qboolean isexplicit)
Cbuf_AddText("\n", execlevel);
}
void M_Script_Remove (menu_t *menu)
void M_Script_Remove (emenu_t *menu)
{
if (menu == menu_script)
menu_script = NULL;
M_Script_Option(menu, "cancel", false);
}
qboolean M_Script_Key (int key, menu_t *menu)
qboolean M_Script_Key (int key, emenu_t *menu)
{
if (menu->selecteditem && menu->selecteditem->common.type == mt_edit)
return false;
@ -90,9 +90,7 @@ void M_MenuS_Clear_f (void)
void M_MenuS_Script_f (void) //create a menu.
{
int items;
menu_t *oldmenu;
char *alias = Cmd_Argv(1);
Key_Dest_Add(kdm_emenu);
selectitem = 0;
items=0;
@ -113,14 +111,7 @@ void M_MenuS_Script_f (void) //create a menu.
M_MenuS_Clear_f();
}
oldmenu = topmenu;
menu_script = M_CreateMenu(0);
if (oldmenu)
{
M_HideMenu(oldmenu); //bring to front
M_AddMenu(oldmenu);
}
menu_script->remove = M_Script_Remove;
menu_script->key = M_Script_Key;

View File

@ -139,7 +139,7 @@ static void M_ScanSaves (void)
M_ScanSave(i, va("s%i", i-SAVEFIRST_STANDARD), true);
}
static void M_Menu_LoadSave_UnloadShaders(menu_t *menu)
static void M_Menu_LoadSave_UnloadShaders(emenu_t *menu)
{
loadsavemenuinfo_t *info = menu->data;
if (info->picshader)
@ -150,7 +150,7 @@ static void M_Menu_LoadSave_UnloadShaders(menu_t *menu)
}
}
static void M_Menu_LoadSave_Preview_Draw(int x, int y, menucustom_t *item, menu_t *menu)
static void M_Menu_LoadSave_Preview_Draw(int x, int y, menucustom_t *item, emenu_t *menu)
{
loadsavemenuinfo_t *info = menu->data;
int slot;
@ -225,7 +225,7 @@ static void M_Menu_LoadSave_Preview_Draw(int x, int y, menucustom_t *item, menu_
void M_Menu_Save_f (void)
{
menuoption_t *op = NULL;
menu_t *menu;
emenu_t *menu;
int i;
if (!sv.state)
@ -234,8 +234,6 @@ void M_Menu_Save_f (void)
if (cl.intermissionmode != IM_NONE)
return;
Key_Dest_Add(kdm_emenu);
menu = M_CreateMenu(sizeof(loadsavemenuinfo_t));
menu->data = menu+1;
menu->remove = M_Menu_LoadSave_UnloadShaders;
@ -272,12 +270,10 @@ void M_Menu_Save_f (void)
void M_Menu_Load_f (void)
{
menuoption_t *op = NULL;
menu_t *menu;
emenu_t *menu;
int i;
char time[64];
Key_Dest_Add(kdm_emenu);
menu = M_CreateMenu(sizeof(loadsavemenuinfo_t));
menu->data = menu+1;
menu->remove = M_Menu_LoadSave_UnloadShaders;
@ -323,7 +319,7 @@ void M_Menu_Load_f (void)
extern cvar_t cl_splitscreen;
void M_Menu_SinglePlayer_f (void)
{
menu_t *menu;
emenu_t *menu;
#ifndef CLIENTONLY
menubutton_t *b;
mpic_t *p;
@ -349,8 +345,6 @@ void M_Menu_SinglePlayer_f (void)
};
#endif
Key_Dest_Add(kdm_emenu);
#ifdef CLIENTONLY
menu = M_CreateMenu(0);
@ -617,7 +611,7 @@ typedef struct {
demoitem_t *items;
} demomenu_t;
static void M_DemoDraw(int x, int y, menucustom_t *control, menu_t *menu)
static void M_DemoDraw(int x, int y, menucustom_t *control, emenu_t *menu)
{
extern qboolean keydown[K_MAX];
char *text;
@ -699,8 +693,8 @@ static void M_DemoDraw(int x, int y, menucustom_t *control, menu_t *menu)
item = item->next;
}
}
static void ShowDemoMenu (menu_t *menu, const char *path);
static qboolean M_DemoKey(menucustom_t *control, menu_t *menu, int key, unsigned int unicode)
static void ShowDemoMenu (emenu_t *menu, const char *path);
static qboolean M_DemoKey(menucustom_t *control, emenu_t *menu, int key, unsigned int unicode)
{
demomenu_t *info = menu->data;
demoitem_t *it;
@ -944,13 +938,13 @@ static void M_Demo_Flush (demomenu_t *info)
info->firstitem = NULL;
}
static void M_Demo_Remove (menu_t *menu)
static void M_Demo_Remove (emenu_t *menu)
{
demomenu_t *info = menu->data;
M_Demo_Flush(info);
}
static void ShowDemoMenu (menu_t *menu, const char *path)
static void ShowDemoMenu (emenu_t *menu, const char *path)
{
demomenu_t *info = menu->data;
@ -1071,10 +1065,9 @@ void M_Menu_Demos_f (void)
};
size_t u;
demomenu_t *info;
menu_t *menu;
emenu_t *menu;
static demoloc_t mediareenterloc = {FS_GAME, "demos/"};
Key_Dest_Add(kdm_emenu);
Key_Dest_Remove(kdm_console);
menu = M_CreateMenu(sizeof(demomenu_t));
@ -1131,11 +1124,9 @@ void M_Menu_Demos_f (void)
void M_Menu_MediaFiles_f (void)
{
demomenu_t *info;
menu_t *menu;
emenu_t *menu;
static demoloc_t mediareenterloc = {FS_GAME};
Key_Dest_Add(kdm_emenu);
menu = M_CreateMenu(sizeof(demomenu_t));
menu->remove = M_Demo_Remove;
info = menu->data;

View File

@ -22,7 +22,153 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "shader.h"
#include "cl_master.h"
qboolean menu_mousedown;
menu_t *topmenu;
menu_t *promptmenu;
void Menu_KeyEvent(qboolean isdown, int deviceid, int key, int unicode)
{
if (promptmenu && promptmenu->keyevent)
promptmenu->keyevent(promptmenu, isdown, deviceid, key, unicode);
else if (topmenu && topmenu->keyevent)
topmenu->keyevent(topmenu, isdown, deviceid, key, unicode);
else if (isdown)
Key_Dest_Remove(kdm_menu); //it doesn't want it then...
}
static void Menu_UpdateFocus(void)
{
if (!promptmenu || !promptmenu->keyevent)
Key_Dest_Remove(kdm_prompt); //can't take key presses, so don't take keys.
if (promptmenu && promptmenu->cursor)
key_dest_absolutemouse |= kdm_prompt;
else
key_dest_absolutemouse &= ~kdm_prompt;
if (!topmenu || !topmenu->keyevent)
Key_Dest_Remove(kdm_menu); //can't take key presses, so don't take keys.
if (topmenu && topmenu->cursor)
key_dest_absolutemouse |= kdm_menu;
else
key_dest_absolutemouse &= ~kdm_menu;
}
qboolean Menu_IsLinked(menu_t *menu)
{
menu_t *link;
for (link = topmenu; link; link = link->prev)
{
if (menu == link)
return true;
}
return false;
}
menu_t *Menu_FindContext(void *ctx)
{
menu_t *link;
for (link = promptmenu; link; link = link->prev)
{
if (link->ctx == ctx)
return link;
}
for (link = topmenu; link; link = link->prev)
{
if (link->ctx == ctx)
return link;
}
return NULL;
}
void Menu_Unlink(menu_t *menu)
{
menu_t **link;
for (link = &promptmenu; *link; link = &(*link)->prev)
{
if (menu == *link)
{
*link = menu->prev;
if (menu->release)
menu->release(menu);
Menu_UpdateFocus();
return;
}
}
for (link = &topmenu; *link; link = &(*link)->prev)
{
if (menu == *link)
{
*link = menu->prev;
if (menu->release)
menu->release(menu);
Menu_UpdateFocus();
return;
}
}
}
void Menu_Push(menu_t *menu, qboolean prompt)
{
if (!Menu_IsLinked(menu))
{ //only link once.
if (prompt)
{
menu->prev = promptmenu;
promptmenu = menu;
}
else
{
menu->prev = topmenu;
topmenu = menu;
}
}
if (menu == promptmenu)
{
Key_Dest_Add(kdm_prompt);
Menu_UpdateFocus();
}
if (menu == topmenu)
{
Key_Dest_Add(kdm_menu);
Menu_UpdateFocus();
}
}
void Menu_PopAll(void)
{
qboolean popped = false;
menu_t **link, *menu;
for (link = &topmenu; *link;)
{
menu = *link;
if (menu->persist)
link = &(*link)->prev;
else
{
*link = menu->prev;
menu->prev = NULL;
if (menu->release)
menu->release(menu);
popped = true;
}
}
if (popped)
Menu_UpdateFocus();
}
void Menu_Draw(void)
{
#ifdef MENU_DAT
//shitty always-drawn crap
MP_Draw();
#endif
//draw whichever menu has focus
if (topmenu && topmenu->drawmenu)
topmenu->drawmenu(topmenu);
}
void Prompts_Draw(void)
{
//prompts always appear over the top of everything else, particuarly other menus.
if (promptmenu && promptmenu->drawmenu)
promptmenu->drawmenu(promptmenu);
}
void M_DrawScalePic (int x, int y, int w, int h, mpic_t *pic)
{
@ -105,7 +251,7 @@ void M_DrawTextBox (int x, int y, int width, int lines)
M_DrawScalePic (cx, cy+8, 8, 8, p);
}
int M_FindKeysForBind (int bindmap, const char *command, int *keylist, int *keymods, int keycount)
int QDECL M_FindKeysForBind (int bindmap, const char *command, int *keylist, int *keymods, int keycount)
{
int count;
int j, m;
@ -203,13 +349,11 @@ M_ToggleMenu_f
*/
void M_ToggleMenu_f (void)
{
#ifndef NOBUILTINMENUS
if (topmenu)
{
Key_Dest_Add(kdm_emenu);
Key_Dest_Add(kdm_menu);
return;
}
#endif
#ifdef CSQC_DAT
if (CSQC_ConsoleCommand(-1, "togglemenu"))
@ -264,6 +408,200 @@ void M_Restart_f(void)
}
//=============================================================================
/* Various callback-based prompts */
typedef struct
{
menu_t m;
void (*callback)(void *, int);
void *ctx;
int lines;
const char *messages;
const char *buttons[3];
int kbutton, mbutton;
} promptmenu_t;
static qboolean Prompt_MenuKeyEvent(struct menu_s *gm, qboolean isdown, unsigned int devid, int key, int unicode)
{
promptmenu_t *m = (promptmenu_t*)gm;
int action;
void (*callback)(void *, int) = m->callback;
void *ctx = m->ctx;
extern qboolean keydown[];
if (!isdown != (key==K_MOUSE1))
return false; //don't care about releases, unless mouse1.
if (key == 'n' || key == 'N')
action = 1;
else if (key == 'y' || key == 'Y')
action = 0;
else if (key==K_RIGHTARROW || key==K_GP_DPAD_RIGHT || key==K_DOWNARROW || key==K_GP_DPAD_DOWN || (key == K_TAB && !keydown[K_LSHIFT] && !keydown[K_RSHIFT]))
{
for(;;)
{
m->kbutton++;
if (m->kbutton >= 3)
m->kbutton -= 3;
if (m->buttons[m->kbutton])
break;
}
return true;
}
else if (key == K_LEFTARROW || key == K_GP_DPAD_LEFT || key==K_UPARROW || key==K_GP_DPAD_UP || key==K_TAB)
{
for(;;)
{
m->kbutton--;
if (m->kbutton < 0)
m->kbutton += 3;
if (m->buttons[m->kbutton])
break;
}
return true;
}
else if (key == K_ESCAPE || key == K_GP_BACK || key == K_MOUSE2)
action = -1;
else if (key == K_ENTER || key == K_KP_ENTER || key == K_MOUSE1 || key == K_GP_A)
{
if (key == K_MOUSE1)
action = m->mbutton;
else
action = m->kbutton;
if (action == -1) //nothing focused
return false;
if (action == 2) //convert buttons to actions...
action = -1;
}
else
return false; // no idea what that is
m->callback = NULL; //so the remove handler can't fire.
Menu_Unlink(&m->m);
if (callback)
callback(ctx, action);
return true;
}
static void Prompt_Draw(struct menu_s *g)
{
promptmenu_t *m = (promptmenu_t*)g;
int x = 64;
int y = 76;
int w = 224;
int h = m->lines*8+16;
int i;
const char *msg = m->messages;
int bx[4];
x = ((vid.width-w)>>1);
Draw_TextBox(x-8, y, w/8, h/8);
y+=8;
for (i = 0; i < m->lines; i++, msg = msg+strlen(msg)+1)
{
Draw_FunStringWidth(x, y, msg, w, 2, false);
y+=8;
}
y+=8;
m->mbutton = -1;
bx[0] = x;
bx[1] = x+w/3;
bx[2] = x+w-w/3;
bx[3] = x+w;
if (mousecursor_y >= y && mousecursor_y <= y+8)
{
for (i = 0; i < 3; i++)
{
if (m->buttons[i] && mousecursor_x >= bx[i] && mousecursor_x < bx[i+1])
m->mbutton = i;
}
}
for (i = 0; i < 3; i++)
{
if (m->buttons[i])
{
if (m->mbutton == i)
{
float alphamax = 0.5, alphamin = 0.2;
R2D_ImageColours(.5,.4,0,(sin(realtime*2)+1)*0.5*(alphamax-alphamin)+alphamin);
R2D_FillBlock(bx[i], y, bx[i+1]-bx[i], 8);
R2D_ImageColours(1,1,1,1);
}
Draw_FunStringWidth(bx[i], y, m->buttons[i], bx[i+1]-bx[i], 2, m->kbutton==i);
}
}
}
static void Prompt_Release(struct menu_s *gm)
{
promptmenu_t *m = (promptmenu_t*)gm;
void (*callback)(void *, int) = m->callback;
void *ctx = m->ctx;
m->callback = NULL;
if (callback)
callback(ctx, -1);
Z_Free(m);
}
void Menu_Prompt (void (*callback)(void *, int), void *ctx, const char *messages, char *optionyes, char *optionno, char *optioncancel)
{
promptmenu_t *m;
char *t;
m = (promptmenu_t*)Z_Malloc(sizeof(*m) + strlen(messages)+(optionyes?strlen(optionyes):0)+(optionno?strlen(optionno):0)+(optioncancel?strlen(optioncancel):0)+7);
m->m.cursor = &key_customcursor[kc_console];
/*void (*videoreset) (struct menu_s *); //called after a video mode switch / shader reload.
void (*release) (struct menu_s *); //
qboolean (*keyevent)(struct menu_s *, qboolean isdown, unsigned int devid, int key, int unicode); //true if key was handled
qboolean (*mousemove)(struct menu_s *, qboolean abs, unsigned int devid, float x, float y);
qboolean (*joyaxis) (struct menu_s *, unsigned int devid, int axis, float val);
void (*drawmenu) (struct menu_s *);
*/
m->m.drawmenu = Prompt_Draw;
m->m.keyevent = Prompt_MenuKeyEvent;
m->m.release = Prompt_Release;
m->mbutton = -1;
m->kbutton = -1;
Menu_Push(&m->m, true);
m->callback = callback;
m->ctx = ctx;
t = (char*)(m+1);
if (optionyes)
{
m->buttons[0] = t;
strcpy(t, optionyes);
t += strlen(t)+1;
}
if (optionno)
{
m->buttons[1] = t;
strcpy(t, optionno);
t += strlen(t)+1;
}
if (optioncancel)
{
m->buttons[2] = t;
strcpy(t, optioncancel);
t += strlen(t)+1;
}
m->messages = t;
strcpy(t, messages);
for(messages = t; t;)
{
t = strchr(t, '\n');
if (t)
*t++ = 0;
m->lines++;
}
}
#ifndef NOBUILTINMENUS
void M_Menu_Audio_f (void);
@ -272,10 +610,6 @@ void M_Menu_Mods_f (void);
void M_Menu_ModelViewer_f(void);
void M_Menu_ModelViewer_c(int argn, const char *partial, struct xcommandargcompletioncb_s *ctx);
extern menu_t *menu_script;
qboolean m_recursiveDraw;
void M_ConfigureNetSubsystem(void);
cvar_t m_helpismedia = CVAR("m_helpismedia", "0");
@ -378,14 +712,11 @@ void M_BuildTranslationTable(unsigned int pc, unsigned int top, unsigned int bot
//=============================================================================
int m_save_demonum;
void M_CloseMenu_f (void)
{
if (!Key_Dest_Has(kdm_emenu))
if (!Key_Dest_Has(kdm_menu))
return;
M_RemoveAllMenus(false);
Key_Dest_Remove(kdm_emenu);
}
//=============================================================================
@ -517,14 +848,12 @@ int bind_grab;
void M_Menu_Keys_f (void)
{
int y;
menu_t *menu;
emenu_t *menu;
vfsfile_t *bindslist;
#if MAX_SPLITS > 1
extern cvar_t cl_splitscreen;
#endif
Key_Dest_Add(kdm_emenu);
menu = M_CreateMenu(0);
switch(M_GameType())
{
@ -658,7 +987,7 @@ struct
{"gfx/menu/help%02i.lmp",1} //hexen2
};
void M_Help_Draw (menu_t *m)
void M_Help_Draw (emenu_t *m)
{
int i;
mpic_t *pic = NULL;
@ -690,7 +1019,7 @@ void M_Help_Draw (menu_t *m)
R2D_ScalePic ((vid.width-width)/2, (vid.height-height)/2, width, height, pic);
}
}
qboolean M_Help_Key (int key, menu_t *m)
qboolean M_Help_Key (int key, emenu_t *m)
{
switch (key)
{
@ -726,8 +1055,7 @@ qboolean M_Help_Key (int key, menu_t *m)
void M_Menu_Help_f (void)
{
int i;
menu_t *helpmenu = M_CreateMenu(0);
Key_Dest_Add(kdm_emenu);
emenu_t *helpmenu = M_CreateMenu(0);
helpmenu->predraw = M_Help_Draw;
helpmenu->key = M_Help_Key;
@ -748,226 +1076,53 @@ void M_Menu_Help_f (void)
}
}
//=============================================================================
/* Various callback-based prompts */
typedef struct
{
menu_t m;
void (*callback)(void *, int);
void *ctx;
menubutton_t *b_yes;
menubutton_t *b_no;
menubutton_t *b_cancel;
} promptmenu_t;
static qboolean M_Menu_Prompt_Button (union menuoption_s *b,struct menu_s *gm, int key)
{
int action;
promptmenu_t *m = (promptmenu_t*)gm;
void (*callback)(void *, int) = m->callback;
void *ctx = m->ctx;
if (key != K_ENTER && key != K_KP_ENTER && key != K_MOUSE1)
return true;
if (b == (menuoption_t*)m->b_yes)
action = 0;
else if (b == (menuoption_t*)m->b_no)
action = 1;
else //if (b == (menuoption_t*)m->b_cancel)
action = -1;
m->callback = NULL;
M_RemoveMenu(&m->m);
if (callback)
callback(ctx, action);
return true;
}
static void M_Menu_Prompt_Cancel (struct menu_s *gm)
{
promptmenu_t *m = (promptmenu_t*)gm;
void (*callback)(void *, int) = m->callback;
void *ctx = m->ctx;
m->callback = NULL;
if (callback)
callback(ctx, -1);
}
void M_Menu_Prompt (void (*callback)(void *, int), void *ctx, const char *messages, char *optionyes, char *optionno, char *optioncancel)
{
promptmenu_t *m;
char *t;
int y;
int x = 64, w = 224;
Key_Dest_Add(kdm_emenu);
m = (promptmenu_t*)M_CreateMenuInfront(sizeof(*m) - sizeof(m->m) + strlen(messages)+(optionyes?strlen(optionyes):0)+(optionno?strlen(optionno):0)+(optioncancel?strlen(optioncancel):0)+6);
m->callback = callback;
m->ctx = ctx;
m->m.remove = M_Menu_Prompt_Cancel;
t = (char*)(m+1);
if (optionyes)
{
strcpy(t, optionyes);
optionyes = t;
t += strlen(t)+1;
}
if (optionno)
{
strcpy(t, optionno);
optionno = t;
t += strlen(t)+1;
}
if (optioncancel)
{
strcpy(t, optioncancel);
optioncancel = t;
t += strlen(t)+1;
}
y = 76;
y += 8; //top border
strcpy(t, messages);
for(messages = t; t; y += 8)
{
messages = t;
t = strchr(messages, '\n');
if (t)
*t++ = 0;
if (*messages)
MC_AddWhiteText(&m->m, x, x+w, y, messages, 2);
}
y += 8; //blank space
if (optionyes)
{
m->b_yes = MC_AddCommand(&m->m, x, x+70, y, optionyes, M_Menu_Prompt_Button);
m->b_yes->rightalign = 2;
}
if (optionno)
{
m->b_no = MC_AddCommand(&m->m, x+w/3, x+(2*w)/3, y, optionno, M_Menu_Prompt_Button);
m->b_no->rightalign = 2; //actually center align
}
if (optioncancel)
{
m->b_cancel = MC_AddCommand(&m->m, x+(2*w)/3, x+w, y, optioncancel, M_Menu_Prompt_Button);
m->b_cancel->rightalign = 2;
}
y += 8; //footer
y += 8; //bottom border
m->m.selecteditem = (menuoption_t *)m->b_cancel;
MC_AddBox (&m->m, x-8, 76, (w/8), (y-76)/8);
}
//=============================================================================
/* QUIT MENU */
int msgNumber;
int m_quit_prevstate;
qboolean wasInMenus;
char *quitMessage [] =
static char *quitMessage [] =
{
/* .........1.........2.... */
" Are you gonna quit ",
" this game just like ",
" everything else? ",
" ",
"Are you gonna quit\n"
"this game just like\n"
"everything else?",
" Milord, methinks that ",
" thou art a lowly ",
" quitter. Is this true? ",
" ",
"Milord, methinks that\n"
"thou art a lowly\n"
"quitter. Is this true?",
" Do I need to bust your ",
" face open for trying ",
" to quit? ",
" ",
"Do I need to bust your\n"
"face open for trying\n"
"to quit?",
" Man, I oughta smack you",
" for trying to quit! ",
" Press Y to get ",
" smacked out. ",
"Man, I oughta smack you\n"
"for trying to quit!\n"
"Press Y to get\n"
"smacked out.",
" Press Y to quit like a ",
" big loser in life. ",
" Press N to stay proud ",
" and successful! ",
"Press Y to quit like a\n"
"big loser in life.\n"
"Press N to stay proud\n"
"and successful!",
" If you press Y to ",
" quit, I will summon ",
" Satan all over your ",
" hard drive! ",
"If you press Y to\n"
"quit, I will summon\n"
"Satan all over your\n"
"hard drive!",
" Um, Asmodeus dislikes ",
" his children trying to ",
" quit. Press Y to return",
" to your Tinkertoys. ",
"Um, Asmodeus dislikes\n"
"his children trying to\n"
"quit. Press Y to return\n"
"to your Tinkertoys.",
" If you quit now, I'll ",
" throw a blanket-party ",
" for you next time! ",
" "
"If you quit now, I'll\n"
"throw a blanket-party\n"
"for you next time!",
};
/*
void OldM_Menu_Quit_f (void)
{
if (m_state == m_quit)
return;
wasInMenus = (key_dest == key_menu);
key_dest = key_menu;
m_quit_prevstate = m_state;
m_state = m_quit;
m_entersound = true;
msgNumber = rand()&7;
}
void M_Quit_Key (int key)
{
switch (key)
{
case K_ESCAPE:
case 'n':
case 'N':
if (wasInMenus)
{
m_state = m_quit_prevstate;
m_entersound = true;
}
else
key_dest = key_game;
break;
case 'Y':
case 'y':
key_dest = key_console;
CL_Disconnect ();
Sys_Quit ();
break;
default:
break;
}
}
void M_Quit_Draw (void)
{
#define VSTR(x) #x
#define VSTR2(x) VSTR(x)
char *cmsg[] = {
// 0123456789012345678901234567890123456789
/* char *cmsg[] = {
// 0123456789012345678901234567890123456789
"0 QuakeWorld",
"1 version " VSTR2(VERSION),
"1modified by Forethought Entertainment",
@ -990,108 +1145,28 @@ void M_Quit_Draw (void)
"0NIN(r) is a registered trademark",
"0licensed to Nothing Interactive, Inc.",
"0All rights reserved. Press y to exit",
NULL };
char **p;
int y;
if (wasInMenus)
{
m_state = m_quit_prevstate;
m_recursiveDraw = true;
M_Draw ();
m_state = m_quit;
}
#if 1
M_DrawTextBox (0, 0, 38, 23);
y = 12;
for (p = cmsg; *p; p++, y += 8) {
if (**p == '0')
M_PrintWhite (16, y, *p + 1);
else
M_Print (16, y, *p + 1);
}
#else
M_DrawTextBox (56, 76, 24, 4);
M_Print (64, 84, quitMessage[msgNumber*4+0]);
M_Print (64, 92, quitMessage[msgNumber*4+1]);
M_Print (64, 100, quitMessage[msgNumber*4+2]);
M_Print (64, 108, quitMessage[msgNumber*4+3]);
#endif
}
*/
qboolean MC_Quit_Key (int key, menu_t *menu)
{
switch (key)
{
case K_ESCAPE:
case K_GP_BACK:
case 'n':
case 'N':
M_RemoveMenu(menu);
break;
case 'q':
case 'Q':
case 'Y':
case 'y':
M_RemoveMenu(menu);
Key_Dest_Add(kdm_console);
CL_Disconnect (NULL);
Sys_Quit ();
break;
default:
return false;
}
return true;
}
NULL };*/
void Cmd_WriteConfig_f(void);
qboolean MC_SaveQuit_Key (int key, menu_t *menu)
static void M_Menu_DoQuit(void *ctx, int option)
{
switch (key)
{
case 'o':
case 'O':
case K_ESCAPE:
case K_GP_BACK:
case K_MOUSE2:
M_RemoveMenu(menu);
break;
case 'q':
case 'Q':
case 'n':
case 'N':
M_RemoveMenu(menu);
#ifndef FTE_TARGET_WEB
CL_Disconnect (NULL);
Sys_Quit ();
#endif
break;
case 'Y':
case 'y':
M_RemoveMenu(menu);
Cmd_ExecuteString("cfg_save", RESTRICT_LOCAL);
#ifndef FTE_TARGET_WEB
CL_Disconnect (NULL);
Sys_Quit ();
#endif
break;
default:
return false;
}
return true;
if (option == 0) //'yes - quit'
Cmd_ExecuteString("menu_quit force\n", RESTRICT_LOCAL);
// else if (option == 1) //'no - don't quit'
// else if (option == -1) //'cancel - don't quit'
}
static void M_Menu_DoQuitSave(void *ctx, int option)
{
if (option == 0) //'yes - save-and-quit'
Cmd_ExecuteString("menu_quit forcesave\n", RESTRICT_LOCAL);
else if (option == 1) //'no - nosave-and-quit'
Cmd_ExecuteString("menu_quit force\n", RESTRICT_LOCAL);
// else if (option == -1) //'cancel - don't quit'
}
//quit menu
void M_Menu_Quit_f (void)
{
menu_t *quitmenu;
int mode;
extern cvar_t cfg_save_auto;
char *arg = Cmd_Argv(1);
@ -1133,58 +1208,10 @@ void M_Menu_Quit_f (void)
#endif
break;
case 2:
Key_Dest_Add(kdm_emenu);
Key_Dest_Remove(kdm_console);
quitmenu = M_CreateMenuInfront(0);
quitmenu->key = MC_SaveQuit_Key;
MC_AddWhiteText(quitmenu, 64, 256, 84, "You have unsaved settings ", 2);
MC_AddWhiteText(quitmenu, 64, 256, 92, " Would you like to ", 2);
MC_AddWhiteText(quitmenu, 64, 256, 100, " save them now? ", 2);
quitmenu->selecteditem = (menuoption_t *)
#ifdef FTE_TARGET_WEB
MC_AddConsoleCommand (quitmenu, 64, 0, 116, "Yes", "cfg_save; menupop\n");
MC_AddConsoleCommand (quitmenu, 224,0, 116, "Cancel", "menupop\n");
#else
MC_AddConsoleCommand (quitmenu, 64, 0, 116, "Yes", "menu_quit forcesave\n");
MC_AddConsoleCommand (quitmenu, 144,0, 116, "No", "menu_quit force\n");
MC_AddConsoleCommand (quitmenu, 224,0, 116, "Cancel", "menupop\n");
#endif
MC_AddBox (quitmenu, 56, 76, 25, 5);
Menu_Prompt (M_Menu_DoQuitSave, NULL, "You have unsaved settings\nWould you like to\nsave them now?", "Yes", "No", "Cancel");
break;
case 1:
Key_Dest_Add(kdm_emenu);
Key_Dest_Remove(kdm_console);
quitmenu = M_CreateMenuInfront(0);
quitmenu->key = MC_Quit_Key;
#ifdef FTE_TARGET_WEB
// MC_AddWhiteText(quitmenu, 64, 256, 84, " ", 2);
MC_AddWhiteText(quitmenu, 64, 256, 92, " There is nothing to save ", 2);
// MC_AddWhiteText(quitmenu, 64, 256, 100, " ", 2);
quitmenu->selecteditem = (menuoption_t *)
MC_AddConsoleCommand (quitmenu, 120, 0, 116, "Oh", "menupop\n");
#else
{
int i = rand()&7;
MC_AddWhiteText(quitmenu, 64, 256, 84, quitMessage[i*4+0], 2);
MC_AddWhiteText(quitmenu, 64, 256, 92, quitMessage[i*4+1], 2);
MC_AddWhiteText(quitmenu, 64, 256, 100, quitMessage[i*4+2], 2);
MC_AddWhiteText(quitmenu, 64, 256, 108, quitMessage[i*4+3], 2);
}
quitmenu->selecteditem = (menuoption_t *)
MC_AddConsoleCommand (quitmenu, 100, 0, 116, "Quit", "menu_quit force\n");
MC_AddConsoleCommand (quitmenu, 194, 0, 116, "Cancel", "menupop\n");
#endif
MC_AddBox (quitmenu, 56, 76, 24, 5);
Menu_Prompt (M_Menu_DoQuit, NULL, quitMessage[rand()%countof(quitMessage)], "Quit", NULL, "Cancel");
break;
}
}
@ -1435,118 +1462,6 @@ void M_Init (void)
#endif
void M_Draw (int uimenu)
{
qboolean stillactive = false;
if (uimenu)
{
if (uimenu == 2)
R2D_FadeScreen ();
#ifdef VM_UI
UI_DrawMenu();
#endif
}
#ifndef NOBUILTINMENUS
if (!Key_Dest_Has(kdm_emenu))
{
M_RemoveAllMenus(false);
menu_mousedown = false;
return;
}
#endif
#ifndef NOBUILTINMENUS
if ((!menu_script || scr_con_current) && !m_recursiveDraw)
{
if (topmenu && topmenu->selecteditem && topmenu->selecteditem->common.type == mt_slider && (topmenu->selecteditem->slider.var == &v_gamma || topmenu->selecteditem->slider.var == &v_contrast))
/*no menu tint if we're trying to adjust gamma*/;
else
R2D_FadeScreen ();
}
else
{
m_recursiveDraw = false;
}
#endif
R2D_ImageColours(1, 1, 1, 1);
#ifdef PLUGINS
if (menuplug)
{
Plug_Menu_Event (0, (int)(realtime*1000));
stillactive = true;
}
#endif
#ifndef NOBUILTINMENUS
if (topmenu)
{
M_Complex_Draw ();
stillactive = true;
}
#endif
if (!stillactive)
Key_Dest_Remove(kdm_emenu);
}
void M_Keydown (int key, int unicode)
{
#ifndef NOBUILTINMENUS
if (topmenu)
{
if (key == K_MOUSE1) //mouse clicks are deferred until the release event. this is for touch screens and aiming.
{
if (topmenu->mouseitem && topmenu->mouseitem->common.type == mt_frameend)
topmenu->mouseitem->frame.mousedown = true;
else
menu_mousedown = true;
}
else if (key == K_LSHIFT || key == K_RSHIFT || key == K_LALT || key == K_RALT || key == K_LCTRL || key == K_RCTRL)
; //modifiers are sent on up events instead.
else
M_Complex_Key (key, unicode);
return;
}
#endif
#ifdef PLUGINS
if (menuplug)
{
Plug_Menu_Event (1, key);
return;
}
#endif
Key_Dest_Remove(kdm_emenu);
}
void M_Keyup (int key, int unicode)
{
#ifndef NOBUILTINMENUS
if (topmenu)
{
if (key == K_MOUSE1 && menu_mousedown)
M_Complex_Key (key, unicode);
else if (key == K_LSHIFT || key == K_RSHIFT || key == K_LALT || key == K_RALT || key == K_LCTRL || key == K_RCTRL)
M_Complex_Key (key, unicode);
menu_mousedown = false;
return;
}
#endif
#ifdef PLUGINS
if (menuplug)
{
Plug_Menu_Event (2, key);
return;
}
#endif
}
// Generic function to choose which game menu to draw
int M_GameType (void)
{

View File

@ -91,14 +91,38 @@ void M_SomeInitialisationFunctionCalledAtStartup(void)
}
*/
#ifdef PLUGINS
extern struct plugin_s *menuplug;
#endif
#ifndef NOBUILTINMENUS
extern struct menu_s *topmenu;
#endif
void M_DrawTextBox (int x, int y, int width, int lines);
//menus can have all sorts of implementation.
//however, to avoid a cacophony of ugly blends, these are always mutually exclusive - only one type of menu will be at the top and only that one will be drawn.
//if you want windows etc you can implement that inside a single one of these.
//each menu subsystem can implement this and then provide its own widgets.
typedef struct menu_s {
struct menu_s *prev;
void *ctx; //for finding a specific menu
void (*videoreset) (struct menu_s *); //called after a video mode switch / shader reload.
void (*release) (struct menu_s *); //
qboolean (*keyevent)(struct menu_s *, qboolean isdown, unsigned int devid, int key, int unicode); //true if key was handled
qboolean (*mousemove)(struct menu_s *, qboolean abs, unsigned int devid, float x, float y);
qboolean (*joyaxis) (struct menu_s *, unsigned int devid, int axis, float val);
void (*drawmenu) (struct menu_s *);
struct key_cursor_s *cursor; //NULL for relative motion
qboolean isopaque; //guarentees an opaque background
qboolean persist; //try really hard to not kill this.
} menu_t;
extern menu_t *topmenu; //the currently visible menu.
extern menu_t *promptmenu; //the currently visible prompt (separate from menus, so they always appear over the top of consoles too, they also always show the menu underneath)
void Menu_KeyEvent(qboolean down, int qdeviceid, int key, int unicode);
void Menu_Draw(void);
void Prompts_Draw(void);
void Menu_PopAll(void); //attempts to pop all menus (this is for map starts, some might linger)
void Menu_Unlink(menu_t *menu);
void Menu_Push(menu_t *menu, qboolean prompt);
menu_t *Menu_FindContext(void *ctx);
void Menu_Prompt (void (*callback)(void *, int), void *ctx, const char *messages, char *optionyes, char *optionno, char *optioncancel);
#ifndef NOBUILTINMENUS
//
@ -107,16 +131,12 @@ void M_DrawTextBox (int x, int y, int width, int lines);
void M_Init (void);
void M_Reinit(void);
void M_Shutdown(qboolean total);
void M_Keydown (int key, int unicode);
void M_Keyup (int key, int unicode);
void M_Draw (int uimenu);
void M_Menu_Mods_f (void); //used at startup if the current gamedirs look dodgy.
void M_Menu_Installer (void); //given an embedded manifest, this displays an install menu for said game.
mpic_t *M_CachePic (char *path);
void M_Menu_Quit_f (void);
void M_Menu_Prompt (void (*callback)(void *, int), void *ctx, const char *messages, char *optionyes, char *optionno, char *optioncancel);
struct menu_s;
void menufixme(void); //REMOVE REMOVE REMOVE
typedef struct emenu_s emenu_t;
typedef enum {
@ -161,7 +181,7 @@ typedef struct {
const char *text;
const char *command;
qboolean rightalign;
qboolean (*key) (union menuoption_s *option, struct menu_s *, int key);
qboolean (*key) (union menuoption_s *option, struct emenu_s *, int key);
} menubutton_t;
#define MAX_EDIT_LENGTH 256
@ -196,7 +216,7 @@ typedef struct menucheck_s {
cvar_t *var;
int bits;
float value;
qboolean (*func) (struct menucheck_s *option, struct menu_s *menu, chk_set_t set);
qboolean (*func) (struct menucheck_s *option, struct emenu_s *menu, chk_set_t set);
} menucheck_t;
typedef struct {
@ -210,8 +230,8 @@ typedef struct menucustom_s {
menucommon_t common;
void *dptr;
int dint;
void (*draw) (int x, int y, struct menucustom_s *, struct menu_s *);
qboolean (*key) (struct menucustom_s *, struct menu_s *, int key, unsigned int unicode);
void (*draw) (int x, int y, struct menucustom_s *, struct emenu_s *);
qboolean (*key) (struct menucustom_s *, struct emenu_s *, int key, unsigned int unicode);
} menucustom_t;
typedef struct {
@ -229,9 +249,9 @@ typedef struct {
menucommon_t common;
int captionwidth;
const char *caption;
const char **options;
const char **values;
char const*caption;
char const*const*options;
char const*const*values;
cvar_t *cvar;
int numoptions;
int selectedoption;
@ -276,7 +296,9 @@ typedef struct menuresel_s //THIS STRUCT MUST BE STATICALLY ALLOCATED.
int x, y;
} menuresel_t;
typedef struct menu_s {
struct emenu_s {
menu_t menu;
int xpos;
int ypos;
int width;
@ -286,16 +308,14 @@ typedef struct menu_s {
menuresel_t *reselection; //stores some info to restore selection properly.
qboolean iszone;
qboolean exclusive;
qboolean persist; //persists despite menuqc/engine changes etc
void *data; //typecast
void (*reset) (struct menu_s *); //called after a video mode switch / shader reload.
void (*remove) (struct menu_s *);
qboolean (*key) (int key, struct menu_s *); //true if key was handled
void (*predraw) (struct menu_s *);
void (*postdraw) (struct menu_s *);
void (*reset) (struct emenu_s *); //called after a video mode switch / shader reload.
void (*remove) (struct emenu_s *);
qboolean (*key) (int key, struct emenu_s *); //true if key was handled
void (*predraw) (struct emenu_s *);
void (*postdraw) (struct emenu_s *);
menuoption_t *options;
menuoption_t *selecteditem;
@ -304,39 +324,36 @@ typedef struct menu_s {
menutooltip_t *tooltip;
double tooltiptime;
struct menu_s *prev;
struct menu_s *next;
int cursorpos;
menuoption_t *cursoritem;
} menu_t;
};
menutext_t *MC_AddBufferedText(menu_t *menu, int lhs, int rhs, int y, const char *text, int rightalign, qboolean red);
menutext_t *MC_AddRedText(menu_t *menu, int lhs, int rhs, int y, const char *text, int rightalign);
menutext_t *MC_AddWhiteText(menu_t *menu, int lhs, int rhs, int y, const char *text, int rightalign);
menubind_t *MC_AddBind(menu_t *menu, int cx, int bx, int y, const char *caption, char *command, char *tooltip);
menubox_t *MC_AddBox(menu_t *menu, int x, int y, int width, int height);
menupicture_t *MC_AddPicture(menu_t *menu, int x, int y, int width, int height, char *picname);
menupicture_t *MC_AddSelectablePicture(menu_t *menu, int x, int y, int height, char *picname);
menupicture_t *MC_AddCenterPicture(menu_t *menu, int y, int height, char *picname);
menupicture_t *MC_AddCursor(menu_t *menu, menuresel_t *resel, int x, int y);
menuoption_t *MC_AddCursorSmall(menu_t *menu, menuresel_t *reselection, int x, int y);
menuslider_t *MC_AddSlider(menu_t *menu, int tx, int sx, int y, const char *text, cvar_t *var, float min, float max, float delta);
menucheck_t *MC_AddCheckBox(menu_t *menu, int tx, int cx, int y, const char *text, cvar_t *var, int cvarbitmask);
menucheck_t *MC_AddCheckBoxFunc(menu_t *menu, int tx, int cx, int y, const char *text, qboolean (*func) (menucheck_t *option, menu_t *menu, chk_set_t set), int bits);
menubutton_t *MC_AddConsoleCommand(menu_t *menu, int lhs, int rhs, int y, const char *text, const char *command);
menubutton_t *MC_AddConsoleCommandQBigFont(menu_t *menu, int x, int y, const char *text, const char *command);
menutext_t *MC_AddBufferedText(emenu_t *menu, int lhs, int rhs, int y, const char *text, int rightalign, qboolean red);
menutext_t *MC_AddRedText(emenu_t *menu, int lhs, int rhs, int y, const char *text, int rightalign);
menutext_t *MC_AddWhiteText(emenu_t *menu, int lhs, int rhs, int y, const char *text, int rightalign);
menubind_t *MC_AddBind(emenu_t *menu, int cx, int bx, int y, const char *caption, char *command, char *tooltip);
menubox_t *MC_AddBox(emenu_t *menu, int x, int y, int width, int height);
menupicture_t *MC_AddPicture(emenu_t *menu, int x, int y, int width, int height, char *picname);
menupicture_t *MC_AddSelectablePicture(emenu_t *menu, int x, int y, int height, char *picname);
menupicture_t *MC_AddCenterPicture(emenu_t *menu, int y, int height, char *picname);
menupicture_t *MC_AddCursor(emenu_t *menu, menuresel_t *resel, int x, int y);
menuoption_t *MC_AddCursorSmall(emenu_t *menu, menuresel_t *reselection, int x, int y);
menuslider_t *MC_AddSlider(emenu_t *menu, int tx, int sx, int y, const char *text, cvar_t *var, float min, float max, float delta);
menucheck_t *MC_AddCheckBox(emenu_t *menu, int tx, int cx, int y, const char *text, cvar_t *var, int cvarbitmask);
menucheck_t *MC_AddCheckBoxFunc(emenu_t *menu, int tx, int cx, int y, const char *text, qboolean (*func) (menucheck_t *option, emenu_t *menu, chk_set_t set), int bits);
menubutton_t *MC_AddConsoleCommand(emenu_t *menu, int lhs, int rhs, int y, const char *text, const char *command);
menubutton_t *MC_AddConsoleCommandQBigFont(emenu_t *menu, int x, int y, const char *text, const char *command);
mpic_t *QBigFontWorks(void);
menubutton_t *MC_AddConsoleCommandHexen2BigFont(menu_t *menu, int x, int y, const char *text, const char *command);
menubutton_t *VARGS MC_AddConsoleCommandf(menu_t *menu, int lhs, int rhs, int y, int rightalign, const char *text, char *command, ...);
menubutton_t *MC_AddCommand(menu_t *menu, int lhs, int rhs, int y, char *text, qboolean (*command) (union menuoption_s *,struct menu_s *,int));
menucombo_t *MC_AddCombo(menu_t *menu, int tx, int cx, int y, const char *caption, const char **ops, int initialvalue);
menucombo_t *MC_AddCvarCombo(menu_t *menu, int tx, int cx, int y, const char *caption, cvar_t *cvar, const char **ops, const char **values);
menuedit_t *MC_AddEdit(menu_t *menu, int cx, int ex, int y, char *text, char *def);
menuedit_t *MC_AddEditCvar(menu_t *menu, int cx, int ex, int y, char *text, char *name, qboolean slim);
menucustom_t *MC_AddCustom(menu_t *menu, int x, int y, void *dptr, int dint, const char *tooltip);
menuframe_t *MC_AddFrameStart(menu_t *menu, int y); //call before items are added
menuframe_t *MC_AddFrameEnd(menu_t *menu, int y); //and call AFTER that stuff with the same y.
menubutton_t *MC_AddConsoleCommandHexen2BigFont(emenu_t *menu, int x, int y, const char *text, const char *command);
menubutton_t *VARGS MC_AddConsoleCommandf(emenu_t *menu, int lhs, int rhs, int y, int rightalign, const char *text, char *command, ...);
menubutton_t *MC_AddCommand(emenu_t *menu, int lhs, int rhs, int y, char *text, qboolean (*command) (union menuoption_s *,struct emenu_s *,int));
menucombo_t *MC_AddCombo(emenu_t *menu, int tx, int cx, int y, const char *caption, const char **ops, int initialvalue);
menucombo_t *MC_AddCvarCombo(emenu_t *menu, int tx, int cx, int y, const char *caption, cvar_t *cvar, const char **ops, const char **values);
menuedit_t *MC_AddEdit(emenu_t *menu, int cx, int ex, int y, char *text, char *def);
menuedit_t *MC_AddEditCvar(emenu_t *menu, int cx, int ex, int y, char *text, char *name, qboolean slim);
menucustom_t *MC_AddCustom(emenu_t *menu, int x, int y, void *dptr, int dint, const char *tooltip);
menuframe_t *MC_AddFrameStart(emenu_t *menu, int y); //call before items are added
menuframe_t *MC_AddFrameEnd(emenu_t *menu, int y); //and call AFTER that stuff with the same y.
typedef struct menubulk_s {
menutype_t type;
@ -346,12 +363,12 @@ typedef struct menubulk_s {
char *consolecmd; // console command
cvar_t *cvar; // check box, slider
int flags; // check box
qboolean (*func) (struct menucheck_s *option, struct menu_s *menu, chk_set_t set); // check box
qboolean (*func) (struct menucheck_s *option, struct emenu_s *menu, chk_set_t set); // check box
float min; // slider
float max; // slider
float delta; // slider
qboolean rightalign; // text
qboolean (*command) (union menuoption_s *, struct menu_s *, int); // command
qboolean (*command) (union menuoption_s *, struct emenu_s *, int); // command
char *cvarname; // edit cvar
const char **options; // combo
const char **values; // cvar combo
@ -379,21 +396,17 @@ typedef struct menubulk_s {
#define MB_SPACING(space) {mt_text, 2, NULL, NULL, NULL, NULL, 0, NULL, 0, 0, 0, false, NULL, NULL, NULL, NULL, 0, NULL, space}
#define MB_END() {mt_text, -1}
int MC_AddBulk(struct menu_s *menu, menuresel_t *resel, menubulk_t *bulk, int xstart, int xtextend, int y);
int MC_AddBulk(emenu_t *menu, menuresel_t *resel, menubulk_t *bulk, int xstart, int xtextend, int y);
menu_t *M_Options_Title(int *y, int infosize); /*Create a menu with the default options titlebar*/
menu_t *M_CreateMenu (int extrasize);
menu_t *M_CreateMenuInfront (int extrasize);
void M_AddMenu (menu_t *menu);
void M_HideMenu (menu_t *menu);
void M_RemoveMenu (menu_t *menu);
emenu_t *M_Options_Title(int *y, int infosize); /*Create a menu with the default options titlebar*/
emenu_t *M_CreateMenu (int extrasize);
void M_RemoveMenu (emenu_t *menu);
void M_RemoveAllMenus (qboolean leaveprompts);
void M_ReloadMenus(void);
void M_Complex_Key(int key, int unicode);
void M_Complex_Draw(void);
void M_Complex_Key(emenu_t *currentmenu, int key, int unicode);
void M_Script_Init(void);
void M_Serverlist_Init(void);
@ -463,18 +476,14 @@ void M_UnbindCommand (const char *command);
#else
//no builtin menu code.
//stubs
#define M_Menu_Prompt(cb,ctx,messages,optionyes,optionno,optioncancel) (cb)(ctx,-1)
//#define M_Shutdown(t) MP_Shutdown()
void M_Init (void);
void M_Reinit(void);
void M_Shutdown(qboolean total);
void M_Keydown (int key, int unicode);
void M_Keyup (int key, int unicode);
void M_Draw (int uimenu);
#endif
int M_FindKeysForCommand (int bindmap, int pnum, const char *command, int *keylist, int *keymods, int keycount);
int M_FindKeysForBind (int bindmap, const char *command, int *keylist, int *keymods, int keycount);
int QDECL M_FindKeysForBind (int bindmap, const char *command, int *keylist, int *keymods, int keycount);
void M_ToggleMenu_f (void);
#ifdef MENU_DAT
@ -485,11 +494,6 @@ qboolean MP_Toggle(int mode);
void MP_Draw(void);
qboolean MP_UsingGamecodeLoadingScreen(void);
void MP_RegisterCvarsAndCmds(void);
qboolean MP_Keydown(int key, int unicode, unsigned int devid);
void MP_Keyup(int key, int unicode, unsigned int devid);
qboolean MP_MouseMove(float x, float y, unsigned int devid);
qboolean MP_MousePosition(float x, float y, unsigned int devid);
qboolean MP_JoystickAxis(int axis, float value, unsigned int devid);
int MP_BuiltinValid(const char *name, int num);
qboolean MP_ConsoleCommand(const char *cmdtext);
int MP_GetServerCategory(int index);
@ -509,3 +513,32 @@ qboolean MN_Init(void);
#define MGT_HEXEN2 1
#define MGT_QUAKE2 2
int M_GameType(void);
//plugin functions
#ifdef PLUGINS
qboolean Plug_CenterPrintMessage(char *buffer, int clientnum);
qboolean Plug_ChatMessage(char *buffer, int talkernum, int tpflags);
void Plug_Command_f(void);
int Plug_ConnectionlessClientPacket(char *buffer, int size);
qboolean Plug_ConsoleLink(char *text, char *info, const char *consolename);
qboolean Plug_ConsoleLinkMouseOver(float x, float y, char *text, char *info);
void Plug_DrawReloadImages(void);
void Plug_Initialise(qboolean fromgamedir);
void Plug_Shutdown(qboolean preliminary);
qboolean Plug_Menu_Event(int eventtype, int keyparam, int unicodeparam);
void Plug_ResChanged(void);
void Plug_SBar(playerview_t *pv);
qboolean Plug_ServerMessage(char *buffer, int messagelevel);
void Plug_Tick(void);
qboolean Plugin_ExecuteString(void);
#ifdef ANDROID
#define PLUGINPREFIX "libplug_" //android is kinda annoying and only extracts specific files.
#else
#define PLUGINPREFIX "fteplug_" //this string defines what consitutes a plugin, as opposed to some other dll
#endif
#endif

View File

@ -381,6 +381,7 @@ typedef struct texnums_s {
texid_t reflectcube;
texid_t reflectmask;
texid_t displacement;
texid_t occlusion; //occlusion map...
//the material's pushconstants. vulkan guarentees only 128 bytes. so 8 vec4s. note that lmscales should want 4 of them...
/*struct

View File

@ -405,7 +405,7 @@ void QCBUILTIN PF_cl_getkeybind (pubprogfuncs_t *prinst, struct globalvars_s *pr
{
int bindmap = (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)), bindmap, modifier);
const char *binding = Key_GetBinding(MP_TranslateQCtoFTECodes(G_FLOAT(OFS_PARM0)), bindmap, modifier);
RETURN_TSTRING(binding);
}
void QCBUILTIN PF_cl_setkeybind (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
@ -472,7 +472,7 @@ void QCBUILTIN PF_cl_setcursormode (pubprogfuncs_t *prinst, struct globalvars_s
if (prinst->callargc>1)
{
struct key_cursor_s *m = &key_customcursor[(world->keydestmask==kdm_game)?kc_game:kc_menu];
struct key_cursor_s *m = &key_customcursor[(world->keydestmask==kdm_game)?kc_game:kc_menuqc];
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;

View File

@ -2474,7 +2474,7 @@ static void QCBUILTIN PF_R_RenderScene(pubprogfuncs_t *prinst, struct globalvars
SCR_TileClear (0);
#endif
if (!Key_Dest_Has(kdm_emenu|kdm_gmenu|kdm_cwindows))
if (!Key_Dest_Has(kdm_menu|kdm_cwindows))
{
if (cl.intermissionmode == IM_NQFINALE || cl.intermissionmode == IM_NQCUTSCENE || cl.intermissionmode == IM_H2FINALE)
{
@ -6459,27 +6459,27 @@ static struct {
// {"?", PF_Fixme, 313}, // #313
//2d (immediate) operations
{"drawtextfield", PF_CL_DrawTextField, 0/*314*/},
{"drawline", PF_CL_drawline, 315}, // #315 void(float width, vector pos1, vector pos2) drawline (EXT_CSQC)
{"iscachedpic", PF_CL_is_cached_pic, 316}, // #316 float(string name) iscachedpic (EXT_CSQC)
{"precache_pic", PF_CL_precache_pic, 317}, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
{"r_uploadimage", PF_CL_uploadimage, 0},
{"r_readimage", PF_CL_readimage, 0},
{"drawgetimagesize", PF_CL_drawgetimagesize, 318}, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
{"freepic", PF_CL_free_pic, 319}, // #319 void(string name) freepic (EXT_CSQC)
{"drawtextfield", PF_CL_DrawTextField, 0/*314*/},
{"drawline", PF_CL_drawline, 315}, // #315 void(float width, vector pos1, vector pos2) drawline (EXT_CSQC)
{"iscachedpic", PF_CL_is_cached_pic, 316}, // #316 float(string name) iscachedpic (EXT_CSQC)
{"precache_pic", PF_CL_precache_pic, 317}, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
{"r_uploadimage", PF_CL_uploadimage, 0},
{"r_readimage", PF_CL_readimage, 0},
{"drawgetimagesize", PF_CL_drawgetimagesize, 318}, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
{"freepic", PF_CL_free_pic, 319}, // #319 void(string name) freepic (EXT_CSQC)
//320
{"drawcharacter", PF_CL_drawcharacter, 320}, // #320 float(vector position, float character, vector scale, vector rgb, float alpha [, float flag]) drawcharacter (EXT_CSQC, [EXT_CSQC_???])
{"drawrawstring", PF_CL_drawrawstring, 321}, // #321 float(vector position, string text, vector scale, vector rgb, float alpha [, float flag]) drawstring (EXT_CSQC, [EXT_CSQC_???])
{"drawpic", PF_CL_drawpic, 322}, // #322 float(vector position, string pic, vector size, vector rgb, float alpha [, float flag]) drawpic (EXT_CSQC, [EXT_CSQC_???])
{"drawrotpic", PF_CL_drawrotpic, 0},
{"drawfill", PF_CL_drawfill, 323}, // #323 float(vector position, vector size, vector rgb, float alpha [, float flag]) drawfill (EXT_CSQC, [EXT_CSQC_???])
{"drawcharacter", PF_CL_drawcharacter, 320}, // #320 float(vector position, float character, vector scale, vector rgb, float alpha [, float flag]) drawcharacter (EXT_CSQC, [EXT_CSQC_???])
{"drawrawstring", PF_CL_drawrawstring, 321}, // #321 float(vector position, string text, vector scale, vector rgb, float alpha [, float flag]) drawstring (EXT_CSQC, [EXT_CSQC_???])
{"drawpic", PF_CL_drawpic, 322}, // #322 float(vector position, string pic, vector size, vector rgb, float alpha [, float flag]) drawpic (EXT_CSQC, [EXT_CSQC_???])
{"drawrotpic", PF_CL_drawrotpic, 0},
{"drawfill", PF_CL_drawfill, 323}, // #323 float(vector position, vector size, vector rgb, float alpha [, float flag]) drawfill (EXT_CSQC, [EXT_CSQC_???])
{"drawsetcliparea", PF_CL_drawsetcliparea, 324}, // #324 void(float x, float y, float width, float height) drawsetcliparea (EXT_CSQC_???)
{"drawresetcliparea", PF_CL_drawresetcliparea, 325}, // #325 void(void) drawresetcliparea (EXT_CSQC_???)
{"drawresetcliparea", PF_CL_drawresetcliparea, 325}, // #325 void(void) drawresetcliparea (EXT_CSQC_???)
{"drawstring", PF_CL_drawcolouredstring, 326}, // #326
{"stringwidth", PF_CL_stringwidth, 327}, // #327 EXT_CSQC_'DARKPLACES'
{"drawsubpic", PF_CL_drawsubpic, 328}, // #328 EXT_CSQC_'DARKPLACES'
{"drawrotsubpic", PF_CL_drawrotsubpic, 0},
{"drawstring", PF_CL_drawcolouredstring, 326}, // #326
{"stringwidth", PF_CL_stringwidth, 327}, // #327 EXT_CSQC_'DARKPLACES'
{"drawsubpic", PF_CL_drawsubpic, 328}, // #328 EXT_CSQC_'DARKPLACES'
{"drawrotsubpic", PF_CL_drawrotsubpic, 0},
// {"?", PF_Fixme, 329}, // #329 EXT_CSQC_'DARKPLACES'
//330
@ -8177,7 +8177,7 @@ qboolean CSQC_DrawView(void)
G_FLOAT(OFS_PARM0) = vid.width;
G_FLOAT(OFS_PARM1) = vid.height;
}
G_FLOAT(OFS_PARM2) = !Key_Dest_Has(kdm_emenu|kdm_gmenu|kdm_cwindows) && !r_refdef.eyeoffset[0] && !r_refdef.eyeoffset[1];
G_FLOAT(OFS_PARM2) = !Key_Dest_Has(kdm_menu|kdm_cwindows) && !r_refdef.eyeoffset[0] && !r_refdef.eyeoffset[1];
if (csqcg.f_updateviewloading && cls.state && cls.state < ca_active)
PR_ExecuteProgram(csqcprogs, csqcg.f_updateviewloading);

View File

@ -10,10 +10,14 @@
#if defined(MENU_DAT) || defined(CSQC_DAT)
#include "cl_master.h"
qbyte mpkeysdown[K_MAX/8];
//MP_MouseMove(mx, my, mouse->qdeviceid)
static qbyte mpkeysdown[K_MAX/8];
extern qboolean csqc_dp_lastwas3d;
void M_Init_Internal (void);
void M_DeInit_Internal (void);
extern unsigned int r2d_be_flags;
#define DRAWFLAG_NORMAL 0
#define DRAWFLAG_ADD 1
@ -32,7 +36,9 @@ static unsigned int PF_SelectDPDrawFlag(pubprogfuncs_t *prinst, int flag)
PR_RunWarning(prinst, "Detected attempt to draw to framebuffer where framebuffer is not valid\n");
}
}
#ifdef CSQC_DAT
csqc_dp_lastwas3d = false; //for compat with dp's stupid beginpolygon
#endif
//flags:
//0 = blend
@ -69,7 +75,9 @@ void QCBUILTIN PF_CL_drawsetcliparea (pubprogfuncs_t *prinst, struct globalvars_
if (R2D_Flush)
R2D_Flush();
#ifdef CSQC_DAT
csqc_dp_lastwas3d = false;
#endif
srect.x = G_FLOAT(OFS_PARM0) / (float)vid.fbvwidth;
srect.y = G_FLOAT(OFS_PARM1) / (float)vid.fbvheight;
@ -88,7 +96,9 @@ void QCBUILTIN PF_CL_drawresetcliparea (pubprogfuncs_t *prinst, struct globalvar
if (R2D_Flush)
R2D_Flush();
#ifdef CSQC_DAT
csqc_dp_lastwas3d = false;
#endif
BE_Scissor(NULL);
G_FLOAT(OFS_RETURN) = 1;
@ -720,6 +730,7 @@ void QCBUILTIN PF_CL_precache_pic (pubprogfuncs_t *prinst, struct globalvars_s *
G_INT(OFS_RETURN) = 0;
}
#ifdef CSQC_DAT
//warning: not threaded.
void QCBUILTIN PF_CL_uploadimage (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
@ -777,6 +788,7 @@ void QCBUILTIN PF_CL_uploadimage (pubprogfuncs_t *prinst, struct globalvars_s *p
}
}
}
#endif
//warning: not threadable. hopefully noone abuses it.
void QCBUILTIN PF_CL_readimage (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
@ -1224,7 +1236,30 @@ static struct
} menuc_eval;
static playerview_t menuview;
int menuentsize;
static menu_t menuqc; //this is how the client forwards events etc.
static int inmenuprogs;
static progparms_t menuprogparms;
static menuedict_t *menu_edicts;
static int num_menu_edicts;
world_t menu_world;
static int menuentsize;
double menutime;
static struct
{
func_t init;
func_t shutdown;
func_t draw;
func_t drawloading;
func_t keydown;
func_t keyup;
func_t inputevent;
func_t toggle;
func_t consolecommand;
func_t gethostcachecategory;
} mpfuncs;
jmp_buf mp_abort;
// cvars
#define MENUPROGSGROUP "Menu progs control"
@ -1450,9 +1485,10 @@ void QCBUILTIN PF_cl_setkeydest (pubprogfuncs_t *prinst, struct globalvars_s *pr
{
case 0:
// key_game
if (Key_Dest_Has(kdm_gmenu))
if (Key_Dest_Has(kdm_menu))
{
Key_Dest_Remove(kdm_gmenu);
Menu_Unlink(&menuqc);
Key_Dest_Remove(kdm_menu);
// Key_Dest_Remove(kdm_message);
// if (cls.state == ca_disconnected)
// Key_Dest_Add(kdm_console);
@ -1461,9 +1497,9 @@ void QCBUILTIN PF_cl_setkeydest (pubprogfuncs_t *prinst, struct globalvars_s *pr
case 2:
// key_menu
Key_Dest_Remove(kdm_message);
if (!Key_Dest_Has(kdm_gmenu))
if (!Key_Dest_Has(kdm_menu))
Key_Dest_Remove(kdm_console);
Key_Dest_Add(kdm_gmenu);
Menu_Push(&menuqc, false);
break;
case 1:
// key_message
@ -1477,9 +1513,7 @@ void QCBUILTIN PF_cl_setkeydest (pubprogfuncs_t *prinst, struct globalvars_s *pr
//float getkeydest(void) = #602;
void QCBUILTIN PF_cl_getkeydest (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
if (Key_Dest_Has(kdm_emenu))
G_FLOAT(OFS_RETURN) = 3;
else if (Key_Dest_Has(kdm_gmenu))
if (Key_Dest_Has(kdm_menu))
G_FLOAT(OFS_RETURN) = 2;
// else if (Key_Dest_Has(kdm_message))
// G_FLOAT(OFS_RETURN) = 1;
@ -2191,17 +2225,23 @@ static struct {
{"clearscene", PF_m_clearscene, 300},
//no addentities
{"addentity", PF_m_addentity, 302},//FIXME: needs setmodel, origin, angles, colormap(eep), frame etc, skin,
#ifdef CSQC_DAT
{"setproperty", PF_R_SetViewFlag, 303},//should be okay to share
#endif
{"renderscene", PF_m_renderscene, 304},//too module-specific
// {"dynamiclight_add", PF_R_DynamicLight_Add, 305},//should be okay to share
{"R_BeginPolygon", PF_R_PolygonBegin, 306},//useful for 2d stuff
{"R_PolygonVertex", PF_R_PolygonVertex, 307},
{"R_EndPolygon", PF_R_PolygonEnd, 308},
#ifdef CSQC_DAT
{"getproperty", PF_R_GetViewFlag, 309},//should be okay to share
#endif
//unproject 310
//project 311
#ifdef CSQC_DAT
{"r_uploadimage", PF_CL_uploadimage, 0},
#endif
{"r_readimage", PF_CL_readimage, 0},
@ -2361,7 +2401,7 @@ static struct {
{"getgamedirinfo", PF_cl_getgamedirinfo, 626},
{"sprintf", PF_sprintf, 627},
//gap
{"setkeybind", PF_Fixme, 630},
{"setkeybind", PF_cl_setkeybind, 630},
{"getbindmaps", PF_cl_GetBindMap, 631},
{"setbindmaps", PF_cl_SetBindMap, 632},
{"crypto_getkeyfp", PF_crypto_getkeyfp, 633},
@ -2437,37 +2477,142 @@ static int PDECL PR_Menu_MapNamedBuiltin(pubprogfuncs_t *progfuncs, int headercr
return 0;
}
void M_Init_Internal (void);
void M_DeInit_Internal (void);
int inmenuprogs;
progparms_t menuprogparms;
menuedict_t *menu_edicts;
int num_menu_edicts;
world_t menu_world;
static struct
static qboolean MP_MouseMove(menu_t *menu, qboolean isabs, unsigned int devid, float xdelta, float ydelta)
{
func_t init;
func_t shutdown;
func_t draw;
func_t drawloading;
func_t keydown;
func_t keyup;
func_t inputevent;
func_t toggle;
func_t consolecommand;
func_t gethostcachecategory;
} mpfuncs;
void *pr_globals;
jmp_buf mp_abort;
if (!menu_world.progs || !mpfuncs.inputevent)
return false;
if (setjmp(mp_abort))
return false;
inmenuprogs++;
pr_globals = PR_globals(menu_world.progs, PR_CURRENT);
G_FLOAT(OFS_PARM0) = isabs?CSIE_MOUSEABS:CSIE_MOUSEDELTA;
G_FLOAT(OFS_PARM1) = (xdelta * vid.width) / vid.pixelwidth;
G_FLOAT(OFS_PARM2) = (ydelta * vid.height) / vid.pixelheight;
G_FLOAT(OFS_PARM3) = devid;
PR_ExecuteProgram (menu_world.progs, mpfuncs.inputevent);
if (R2D_Flush)
R2D_Flush();
inmenuprogs--;
return G_FLOAT(OFS_RETURN);
}
static qboolean MP_JoystickAxis(menu_t *menu, unsigned int devid, int axis, float value)
{
void *pr_globals;
if (!menu_world.progs || !mpfuncs.inputevent)
return false;
if (setjmp(mp_abort))
return false;
inmenuprogs++;
pr_globals = PR_globals(menu_world.progs, PR_CURRENT);
G_FLOAT(OFS_PARM0) = CSIE_JOYAXIS;
G_FLOAT(OFS_PARM1) = axis;
G_FLOAT(OFS_PARM2) = value;
G_FLOAT(OFS_PARM3) = devid;
PR_ExecuteProgram (menu_world.progs, mpfuncs.inputevent);
if (R2D_Flush)
R2D_Flush();
inmenuprogs--;
return G_FLOAT(OFS_RETURN);
}
static qboolean MP_KeyEvent(menu_t *menu, qboolean isdown, unsigned int devid, int key, int unicode)
{
qboolean result;
#ifdef TEXTEDITOR
if (editormodal)
return false;
#endif
if (setjmp(mp_abort))
return true;
if (isdown)
{
#ifndef NOBUILTINMENUS
if (key == 'c')
{
extern qboolean keydown[K_MAX];
if (keydown[K_LCTRL] || keydown[K_RCTRL])
{
MP_Shutdown();
M_Init_Internal();
return true;
}
}
#endif
mpkeysdown[key>>3] |= (1<<(key&7));
}
else
{ //don't fire up events if it was not actually pressed.
if (key && !(mpkeysdown[key>>3] & (1<<(key&7))))
return false;
mpkeysdown[key>>3] &= ~(1<<(key&7));
}
menutime = Sys_DoubleTime();
if (menu_world.g.time)
*menu_world.g.time = menutime;
inmenuprogs++;
if (mpfuncs.inputevent)
{
void *pr_globals = PR_globals(menu_world.progs, PR_CURRENT);
G_FLOAT(OFS_PARM0) = isdown?CSIE_KEYDOWN:CSIE_KEYUP;
G_FLOAT(OFS_PARM1) = MP_TranslateFTEtoQCCodes(key);
G_FLOAT(OFS_PARM2) = unicode;
G_FLOAT(OFS_PARM3) = devid;
if (isdown)
{
qcinput_scan = G_FLOAT(OFS_PARM1);
qcinput_unicode = G_FLOAT(OFS_PARM2);
}
PR_ExecuteProgram(menu_world.progs, mpfuncs.inputevent);
result = G_FLOAT(OFS_RETURN);
qcinput_scan = 0;
qcinput_unicode = 0;
}
else if (isdown && mpfuncs.keydown)
{
void *pr_globals = PR_globals(menu_world.progs, PR_CURRENT);
G_FLOAT(OFS_PARM0) = MP_TranslateFTEtoQCCodes(key);
G_FLOAT(OFS_PARM1) = unicode;
PR_ExecuteProgram(menu_world.progs, mpfuncs.keydown);
result = true; //doesn't have a return value, so if the menu is set up for key events, all events are considered eaten.
}
else if (!isdown && mpfuncs.keyup)
{
void *pr_globals = PR_globals(menu_world.progs, PR_CURRENT);
G_FLOAT(OFS_PARM0) = MP_TranslateFTEtoQCCodes(key);
G_FLOAT(OFS_PARM1) = unicode;
PR_ExecuteProgram(menu_world.progs, mpfuncs.keyup);
result = false; // doesn't have a return value, so don't block it
}
else
result = false;
inmenuprogs--;
if (R2D_Flush) //shouldn't be needed, but in case the mod is buggy.
R2D_Flush();
return result;
}
static void MP_TryRelease(menu_t *m)
{
MP_Toggle(0);
}
void MP_Shutdown (void)
{
func_t temp;
if (!menu_world.progs)
return;
Menu_Unlink(&menuqc);
/*
{
char *buffer;
@ -2486,7 +2631,7 @@ void MP_Shutdown (void)
PR_Common_Shutdown(menu_world.progs, false);
menu_world.progs->CloseProgs(menu_world.progs);
memset(&menu_world, 0, sizeof(menu_world));
PR_ReleaseFonts(kdm_gmenu);
PR_ReleaseFonts(kdm_menu);
#ifdef CL_MASTER
Master_ClearMasks();
@ -2494,8 +2639,8 @@ void MP_Shutdown (void)
Cmd_RemoveCommands(MP_ConsoleCommand_f);
Key_Dest_Remove(kdm_gmenu);
key_dest_absolutemouse &= ~kdm_gmenu;
Key_Dest_Remove(kdm_menu);
key_dest_absolutemouse &= ~kdm_menu;
}
void *VARGS PR_CB_Malloc(int size); //these functions should be tracked by the library reliably, so there should be no need to track them ourselves.
@ -2582,10 +2727,9 @@ static int PDECL MP_PRFileSize (const char *path)
return -1;
}
double menutime;
qboolean MP_Init (void)
{
struct key_cursor_s *m = &key_customcursor[kc_menu];
struct key_cursor_s *m = &key_customcursor[kc_menuqc];
if (qrenderer == QR_NONE)
{
@ -2639,16 +2783,22 @@ qboolean MP_Init (void)
menuprogparms.useeditor = QCEditor;//void (*useeditor) (char *filename, int line, int nump, char **parms);
menuprogparms.user = &menu_world;
menu_world.keydestmask = kdm_gmenu;
menu_world.keydestmask = kdm_menu;
//default to free mouse+hidden cursor, to match dp's default setting, and because its generally the right thing for a menu.
key_dest_absolutemouse |= kdm_gmenu;
Q_strncpyz(m->name, "none", sizeof(m->name));
m->hotspot[0] = 0;
m->hotspot[1] = 0;
m->scale = 1;
m->dirty = true;
menuqc.cursor = &key_customcursor[kc_menuqc];
menuqc.drawmenu = NULL; //menuqc sucks!
menuqc.mousemove = MP_MouseMove;
menuqc.keyevent = MP_KeyEvent;
menuqc.joyaxis = MP_JoystickAxis;
menuqc.release = MP_TryRelease;
menutime = Sys_DoubleTime();
if (!menu_world.progs)
{
@ -2890,168 +3040,6 @@ void MP_Draw(void)
inmenuprogs--;
}
qboolean MP_Keydown(int key, int unicode, unsigned int devid)
{
qboolean result = false;
#ifdef TEXTEDITOR
if (editormodal)
return true;
#endif
if (setjmp(mp_abort))
return true;
#ifndef NOBUILTINMENUS
if (key == 'c')
{
extern qboolean keydown[K_MAX];
if (keydown[K_LCTRL] || keydown[K_RCTRL])
{
MP_Shutdown();
M_Init_Internal();
return true;
}
}
#endif
mpkeysdown[key>>3] |= (1<<(key&7));
menutime = Sys_DoubleTime();
if (menu_world.g.time)
*menu_world.g.time = menutime;
inmenuprogs++;
if (mpfuncs.inputevent)
{
void *pr_globals = PR_globals(menu_world.progs, PR_CURRENT);
G_FLOAT(OFS_PARM0) = CSIE_KEYDOWN;
G_FLOAT(OFS_PARM1) = qcinput_scan = MP_TranslateFTEtoQCCodes(key);
G_FLOAT(OFS_PARM2) = qcinput_unicode = unicode;
G_FLOAT(OFS_PARM3) = devid;
PR_ExecuteProgram(menu_world.progs, mpfuncs.inputevent);
result = G_FLOAT(OFS_RETURN);
qcinput_scan = 0;
qcinput_unicode = 0;
}
else if (mpfuncs.keydown)
{
void *pr_globals = PR_globals(menu_world.progs, PR_CURRENT);
G_FLOAT(OFS_PARM0) = MP_TranslateFTEtoQCCodes(key);
G_FLOAT(OFS_PARM1) = unicode;
PR_ExecuteProgram(menu_world.progs, mpfuncs.keydown);
result = true; //doesn't have a return value, so if the menu is set up for key events, all events are considered eaten.
}
if (R2D_Flush)
R2D_Flush();
inmenuprogs--;
return result;
}
void MP_Keyup(int key, int unicode, unsigned int devid)
{
#ifdef TEXTEDITOR
if (editormodal)
return;
#endif
if (setjmp(mp_abort))
return;
if (key && !(mpkeysdown[key>>3] & (1<<(key&7))))
return;
mpkeysdown[key>>3] &= ~(1<<(key&7));
menutime = Sys_DoubleTime();
if (menu_world.g.time)
*menu_world.g.time = menutime;
inmenuprogs++;
if (mpfuncs.inputevent)
{
void *pr_globals = PR_globals(menu_world.progs, PR_CURRENT);
G_FLOAT(OFS_PARM0) = CSIE_KEYUP;
G_FLOAT(OFS_PARM1) = MP_TranslateFTEtoQCCodes(key);
G_FLOAT(OFS_PARM2) = unicode;
G_FLOAT(OFS_PARM3) = devid;
PR_ExecuteProgram(menu_world.progs, mpfuncs.inputevent);
}
else if (mpfuncs.keyup)
{
void *pr_globals = PR_globals(menu_world.progs, PR_CURRENT);
G_FLOAT(OFS_PARM0) = MP_TranslateFTEtoQCCodes(key);
G_FLOAT(OFS_PARM1) = unicode;
PR_ExecuteProgram(menu_world.progs, mpfuncs.keyup);
}
if (R2D_Flush)
R2D_Flush();
inmenuprogs--;
}
qboolean MP_MousePosition(float xabs, float yabs, unsigned int devid)
{
void *pr_globals;
if (!menu_world.progs || !mpfuncs.inputevent)
return false;
if (setjmp(mp_abort))
return false;
inmenuprogs++;
pr_globals = PR_globals(menu_world.progs, PR_CURRENT);
G_FLOAT(OFS_PARM0) = CSIE_MOUSEABS;
G_FLOAT(OFS_PARM1) = (xabs * vid.width) / vid.pixelwidth;
G_FLOAT(OFS_PARM2) = (yabs * vid.height) / vid.pixelheight;
G_FLOAT(OFS_PARM3) = devid;
PR_ExecuteProgram (menu_world.progs, mpfuncs.inputevent);
if (R2D_Flush)
R2D_Flush();
inmenuprogs--;
return G_FLOAT(OFS_RETURN);
}
qboolean MP_MouseMove(float xdelta, float ydelta, unsigned int devid)
{
void *pr_globals;
if (!menu_world.progs || !mpfuncs.inputevent)
return false;
if (setjmp(mp_abort))
return false;
inmenuprogs++;
pr_globals = PR_globals(menu_world.progs, PR_CURRENT);
G_FLOAT(OFS_PARM0) = CSIE_MOUSEDELTA;
G_FLOAT(OFS_PARM1) = (xdelta * vid.width) / vid.pixelwidth;
G_FLOAT(OFS_PARM2) = (ydelta * vid.height) / vid.pixelheight;
G_FLOAT(OFS_PARM3) = devid;
PR_ExecuteProgram (menu_world.progs, mpfuncs.inputevent);
if (R2D_Flush)
R2D_Flush();
inmenuprogs--;
return G_FLOAT(OFS_RETURN);
}
qboolean MP_JoystickAxis(int axis, float value, unsigned int devid)
{
void *pr_globals;
if (!menu_world.progs || !mpfuncs.inputevent)
return false;
if (setjmp(mp_abort))
return false;
inmenuprogs++;
pr_globals = PR_globals(menu_world.progs, PR_CURRENT);
G_FLOAT(OFS_PARM0) = CSIE_JOYAXIS;
G_FLOAT(OFS_PARM1) = axis;
G_FLOAT(OFS_PARM2) = value;
G_FLOAT(OFS_PARM3) = devid;
PR_ExecuteProgram (menu_world.progs, mpfuncs.inputevent);
if (R2D_Flush)
R2D_Flush();
inmenuprogs--;
return G_FLOAT(OFS_RETURN);
}
qboolean MP_Toggle(int mode)
{
if (!menu_world.progs)
@ -3061,7 +3049,7 @@ qboolean MP_Toggle(int mode)
return false;
#endif
if (!mode && !Key_Dest_Has(kdm_gmenu))
if (!mode && !Key_Dest_Has(kdm_menu))
return false;
if (setjmp(mp_abort))

View File

@ -965,7 +965,7 @@ void skel_info_f(void)
{
if (skelobjects[i].world)
{
#ifndef SERVERONLY
#if defined(HAVE_CLIENT) && defined(CSQC_DAT)
extern world_t csqc_world;
#endif
Con_Printf("doll %i:\n", i);
@ -973,7 +973,7 @@ void skel_info_f(void)
if (skelobjects[i].world == &sv.world)
Con_Printf(" SSQC\n");
#endif
#ifndef SERVERONLY
#if defined(HAVE_CLIENT) && defined(CSQC_DAT)
if (skelobjects[i].world == &csqc_world)
Con_Printf(" CSQC\n");
#endif

View File

@ -564,7 +564,6 @@ extern const size_t lightthreadctxsize;
extern struct model_s *currentmodel;
qboolean Media_ShowFilm(void);
void Media_CaptureDemoEnd(void);
void Media_RecordFrame (void);
qboolean Media_PausedDemo (qboolean fortiming);

View File

@ -2224,13 +2224,6 @@ qboolean Sbar_ShouldDraw (playerview_t *pv)
return false;
#endif
#ifdef VM_UI
if (UI_DrawStatusBar((pv->sb_showscores?1:0) + (pv->sb_showteamscores?2:0))>0)
return false;
if (UI_MenuState())
return false;
#endif
headsup = !(cl_sbar.value || (scr_viewsize.value<100));
if ((sb_updates >= vid.numpages) && !headsup)
return false;
@ -3803,11 +3796,6 @@ Sbar_IntermissionOverlay
*/
void Sbar_IntermissionOverlay (playerview_t *pv)
{
#ifdef VM_UI
if (UI_DrawIntermission()>0)
return;
#endif
Sbar_Start();
if (!cls.deathmatch)

View File

@ -233,7 +233,7 @@ typedef enum uploadfmt
qboolean SCR_ScreenShot (char *filename, enum fs_relative fsroot, void **buffer, int numbuffers, qintptr_t bytestride, int width, int height, enum uploadfmt fmt, qboolean writemeta);
void SCR_DrawTwoDimensional(int uimenu, qboolean nohud);
void SCR_DrawTwoDimensional(qboolean nohud);
enum
{

View File

@ -127,6 +127,7 @@ static AL_API void (AL_APIENTRY *palSourceQueueBuffers)(ALuint source, ALsizei n
static AL_API void (AL_APIENTRY *palSourceUnqueueBuffers)(ALuint source, ALsizei n, ALuint* buffers);
//for extensions like efx
static AL_API ALboolean (AL_APIENTRY *palIsExtensionPresent)(const ALchar *fextame);
static AL_API void*(AL_APIENTRY *palGetProcAddress)(const ALchar *fname);
#define AL_NONE 0
@ -288,6 +289,10 @@ static AL_API ALvoid (AL_APIENTRY *palEffectf)(ALuint effect, ALenum param, ALfl
static AL_API ALvoid (AL_APIENTRY *palEffectfv)(ALuint effect, ALenum param, const ALfloat *pflValues);
#endif
//AL_EXT_float32
#define AL_FORMAT_MONO_FLOAT32 0x10010
#define AL_FORMAT_STEREO_FLOAT32 0x10011
#define SOUNDVARS SDRVNAME" variables"
@ -342,6 +347,10 @@ typedef struct
ALfloat ListenVel[3]; // Velocity of the listener.
ALfloat ListenOri[6]; // Orientation of the listener. (first 3 elements are "at", second 3 are "up")
#ifdef MIXER_F32
qboolean canfloataudio;
#endif
int cureffect;
ALuint effectslot; //the global reverb slot
size_t numeffecttypes;
@ -384,7 +393,7 @@ static void PrintALError(char *string)
Con_Printf("OpenAL - %s: %x: %s\n",string,err,text);
}
static qboolean OpenAL_LoadCache(unsigned int *bufptr, sfxcache_t *sc, float volume)
static qboolean OpenAL_LoadCache(oalinfo_t *oali, unsigned int *bufptr, sfxcache_t *sc, float volume)
{
unsigned int fmt;
unsigned int size;
@ -421,6 +430,22 @@ static qboolean OpenAL_LoadCache(unsigned int *bufptr, sfxcache_t *sc, float vol
size = sc->length*2;
}
break;
#ifdef MIXER_F32
case 4:
if (!oali->canfloataudio)
return false;
if (sc->numchannels == 2)
{
fmt = AL_FORMAT_STEREO_FLOAT32;
size = sc->length*8;
}
else
{
fmt = AL_FORMAT_MONO_FLOAT32;
size = sc->length*4;
}
break;
#endif
default:
return false;
}
@ -461,6 +486,20 @@ static qboolean OpenAL_LoadCache(unsigned int *bufptr, sfxcache_t *sc, float vol
palBufferData(*bufptr, fmt, tmp, size, sc->speed);
free(tmp);
}
#ifdef MIXER_F32
else if (sc->width == 4)
{
float *tmp = malloc(size);
float *src = (float*)sc->data;
int i;
for (i = 0; i < (size>>1); i++)
{
tmp[i] = src[i]*volume; //signed. oversaturation isn't my problem
}
palBufferData(*bufptr, fmt, tmp, size, sc->speed);
free(tmp);
}
#endif
}
else
{
@ -476,7 +515,7 @@ static qboolean OpenAL_LoadCache(unsigned int *bufptr, sfxcache_t *sc, float vol
palBufferData(*bufptr, fmt, tmp, size, sc->speed);
free(tmp);
}
else if (sc->width == 2)
else if (sc->width == 2 || sc->width == 4)
{
#if 0
short *tmp = malloc(size);
@ -762,7 +801,7 @@ static void OpenAL_ChannelUpdate(soundcardinfo_t *sc, channel_t *chan, unsigned
{
//build a buffer with it and queue it up.
//buffer will be purged later on when its unqueued
OpenAL_LoadCache(&buf, &sbuf, max(1,cvolume));
OpenAL_LoadCache(oali, &buf, &sbuf, max(1,cvolume));
palSourceQueueBuffers(src, 1, &buf);
}
else
@ -774,7 +813,7 @@ static void OpenAL_ChannelUpdate(soundcardinfo_t *sc, channel_t *chan, unsigned
silence.data = NULL;
silence.length = 0.1 * silence.speed;
silence.soundoffset = 0;
OpenAL_LoadCache(&buf, &silence, 1);
OpenAL_LoadCache(oali, &buf, &silence, 1);
palSourceQueueBuffers(src, 1, &buf);
}
queuedbufs++;
@ -803,7 +842,7 @@ static void OpenAL_ChannelUpdate(soundcardinfo_t *sc, channel_t *chan, unsigned
silence.data = NULL;
silence.length = 0.1 * silence.speed;
silence.soundoffset = 0;
OpenAL_LoadCache(&buf, &silence, 1);
OpenAL_LoadCache(oali, &buf, &silence, 1);
palSourceQueueBuffers(src, 1, &buf);
queuedbufs++;
}
@ -828,7 +867,7 @@ static void OpenAL_ChannelUpdate(soundcardinfo_t *sc, channel_t *chan, unsigned
{
if (!sfx->decoder.buf)
return;
if (!OpenAL_LoadCache(&sfx->openal_buffer, sfx->decoder.buf, 1))
if (!OpenAL_LoadCache(oali, &sfx->openal_buffer, sfx->decoder.buf, 1))
return;
palSourcei(src, AL_BUFFER, sfx->openal_buffer);
}
@ -1016,6 +1055,7 @@ static qboolean OpenAL_InitLibrary(void)
{(void*)&palSpeedOfSound, "alSpeedOfSound"},
{(void*)&palDistanceModel, "alDistanceModel"},
{(void*)&palIsExtensionPresent, "alIsExtensionPresent"},
{(void*)&palGetProcAddress, "alGetProcAddress"},
{(void*)&palGetSourcei, "alGetSourcei"},
{(void*)&palSourceQueueBuffers, "alSourceQueueBuffers"},
@ -1383,6 +1423,9 @@ static qboolean QDECL OpenAL_InitCard(soundcardinfo_t *sc, const char *devname)
sc->Submit = OpenAL_Submit;
sc->GetDMAPos = OpenAL_GetDMAPos;
#ifdef MIXER_F32
oali->canfloataudio = palIsExtensionPresent("AL_EXT_float32");
#endif
sc->inactive_sound = true;
sc->selfpainting = true;

View File

@ -4196,6 +4196,7 @@ void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels,
double speedfactor;
qbyte *newcache;
streaming_t *s, *free=NULL;
for (s = s_streamers, i = 0; i < MAX_RAW_SOURCES; i++, s++)
{
if (!s->inuse)

View File

@ -794,34 +794,51 @@ static qboolean QDECL S_LoadBrowserFile (sfx_t *s, qbyte *data, size_t datalen,
#endif
//highest priority is last.
static S_LoadSound_t AudioInputPlugins[10] =
static struct
{
S_LoadSound_t loadfunc;
void *module;
} AudioInputPlugins[10] =
{
#ifdef FTE_TARGET_WEB
S_LoadBrowserFile,
{S_LoadBrowserFile},
#endif
#ifdef AVAIL_OGGVORBIS
S_LoadOVSound,
{S_LoadOVSound},
#endif
S_LoadWavSound,
{S_LoadWavSound},
#ifdef PACKAGE_DOOMWAD
S_LoadDoomSound,
// S_LoadDoomSpeakerSound,
{S_LoadDoomSound},
// {S_LoadDoomSpeakerSound},
#endif
};
qboolean S_RegisterSoundInputPlugin(S_LoadSound_t loadfnc)
qboolean S_RegisterSoundInputPlugin(void *module, S_LoadSound_t loadfnc)
{
int i;
for (i = 0; i < sizeof(AudioInputPlugins)/sizeof(AudioInputPlugins[0]); i++)
{
if (!AudioInputPlugins[i])
if (!AudioInputPlugins[i].loadfunc)
{
AudioInputPlugins[i] = loadfnc;
AudioInputPlugins[i].module = module;
AudioInputPlugins[i].loadfunc = loadfnc;
return true;
}
}
return false;
}
void S_UnregisterSoundInputModule(void *module)
{ //unregister all sound handlers for the given module.
int i;
for (i = 0; i < sizeof(AudioInputPlugins)/sizeof(AudioInputPlugins[0]); i++)
{
if (AudioInputPlugins[i].module == module)
{
AudioInputPlugins[i].module = NULL;
AudioInputPlugins[i].loadfunc = NULL;
}
}
}
static void S_LoadedOrFailed (void *ctx, void *ctxdata, size_t a, size_t b)
{
@ -941,9 +958,9 @@ static void S_LoadSoundWorker (void *ctx, void *ctxdata, size_t forcedecode, siz
for (i = sizeof(AudioInputPlugins)/sizeof(AudioInputPlugins[0])-1; i >= 0; i--)
{
if (AudioInputPlugins[i])
if (AudioInputPlugins[i].loadfunc)
{
if (AudioInputPlugins[i](s, data, filesize, snd_speed, forcedecode))
if (AudioInputPlugins[i].loadfunc(s, data, filesize, snd_speed, forcedecode))
{
//wake up the main thread in case it decided to wait for us.
COM_AddWork(WG_MAIN, S_LoadedOrFailed, s, NULL, SLS_LOADED, 0);

View File

@ -157,6 +157,14 @@ static void SND_PaintChannel16_O8I1 (channel_t *ch, sfxcache_t *sc, int count, i
static void SND_PaintChannel8_O2I2 (channel_t *ch, sfxcache_t *sc, int starttime, int count, int rate);
static void SND_PaintChannel16_O2I2 (channel_t *ch, sfxcache_t *sc, int starttime, int count, int rate);
#ifdef MIXER_F32
static void SND_PaintChannel32F_O2I1(channel_t *ch, sfxcache_t *sc, int starttime, int count, int rate);
static void SND_PaintChannel32F_O4I1(channel_t *ch, sfxcache_t *sc, int count, int rate);
static void SND_PaintChannel32F_O6I1(channel_t *ch, sfxcache_t *sc, int count, int rate);
static void SND_PaintChannel32F_O8I1(channel_t *ch, sfxcache_t *sc, int count, int rate);
static void SND_PaintChannel32F_O2I2(channel_t *ch, sfxcache_t *sc, int starttime, int count, int rate);
#endif
//NOTE: MAY NOT CALL SYS_ERROR
void S_PaintChannels(soundcardinfo_t *sc, int endtime)
{
@ -329,6 +337,21 @@ void S_PaintChannels(soundcardinfo_t *sc, int endtime)
else
SND_PaintChannel16_O8I1(ch, scache, count, rate);
}
#ifdef MIXER_F32
else if (scache->width == 4)
{
if (scache->numchannels==2)
SND_PaintChannel32F_O2I2(ch, scache, ltime-sc->paintedtime, count, rate);
else if (sc->sn.numchannels <= 2)
SND_PaintChannel32F_O2I1(ch, scache, ltime-sc->paintedtime, count, rate);
else if (sc->sn.numchannels <= 4)
SND_PaintChannel32F_O4I1(ch, scache, count, rate);
else if (sc->sn.numchannels <= 6)
SND_PaintChannel32F_O6I1(ch, scache, count, rate);
else
SND_PaintChannel32F_O8I1(ch, scache, count, rate);
}
#endif
ltime += count;
ch->pos += rate * count;
}
@ -720,4 +743,214 @@ static void SND_PaintChannel16_O8I1 (channel_t *ch, sfxcache_t *sc, int count, i
}
}
}
#ifdef MIXER_F32
static void SND_PaintChannel32F_O2I1 (channel_t *ch, sfxcache_t *sc, int starttime, int count, int rate)
{
float data;
int left, right;
int leftvol, rightvol;
float *sfx;
int i;
unsigned int pos = ch->pos-(sc->soundoffset<<PITCHSHIFT);
leftvol = ch->vol[0]*128;
rightvol = ch->vol[1]*128;
if (rate != (1<<PITCHSHIFT))
{
sfx = (float *)sc->data;
for (i=0 ; i<count ; i++)
{
float frac = pos&((1<<PITCHSHIFT)-1);
data = sfx[pos>>PITCHSHIFT] * (1-frac) + sfx[(pos>>PITCHSHIFT)+1] * frac;
pos += rate;
paintbuffer[starttime+i].s[0] += (leftvol * data);
paintbuffer[starttime+i].s[1] += (rightvol * data);
}
}
else
{
sfx = (float *)sc->data + (pos>>PITCHSHIFT);
for (i=0 ; i<count ; i++)
{
data = sfx[i];
left = (data * leftvol);
right = (data * rightvol);
paintbuffer[starttime+i].s[0] += left;
paintbuffer[starttime+i].s[1] += right;
}
}
}
static void SND_PaintChannel32F_O2I2 (channel_t *ch, sfxcache_t *sc, int starttime, int count, int rate)
{
float leftvol, rightvol;
float *sfx;
int i;
unsigned int pos = ch->pos-(sc->soundoffset<<PITCHSHIFT);
leftvol = ch->vol[0]*128;
rightvol = ch->vol[1]*128;
if (rate != (1<<PITCHSHIFT))
{
float l, r;
sfx = (float *)sc->data;
for (i=0 ; i<count ; i++)
{
l = sfx[(pos>>(PITCHSHIFT-1))&~1];
r = sfx[(pos>>(PITCHSHIFT-1))|1];
pos += rate;
paintbuffer[starttime+i].s[0] += (l * leftvol);
paintbuffer[starttime+i].s[1] += (r * rightvol);
}
}
else
{
sfx = (float *)sc->data + (pos>>PITCHSHIFT)*2;
for (i=0 ; i<count ; i++)
{
paintbuffer[starttime+i].s[0] += (*sfx++ * leftvol);
paintbuffer[starttime+i].s[1] += (*sfx++ * rightvol);
}
}
}
static void SND_PaintChannel32F_O4I1 (channel_t *ch, sfxcache_t *sc, int count, int rate)
{
int vol[4];
float *sfx;
int i;
unsigned int pos = ch->pos-(sc->soundoffset<<PITCHSHIFT);
vol[0] = ch->vol[0]*128;
vol[1] = ch->vol[1]*128;
vol[2] = ch->vol[2]*128;
vol[3] = ch->vol[3]*128;
if (rate != (1<<PITCHSHIFT))
{
float data;
sfx = (float *)sc->data;
for (i=0 ; i<count ; i++)
{
data = sfx[pos>>PITCHSHIFT];
pos += rate;
paintbuffer[i].s[0] += (vol[0] * data);
paintbuffer[i].s[1] += (vol[1] * data);
paintbuffer[i].s[2] += (vol[2] * data);
paintbuffer[i].s[3] += (vol[3] * data);
}
}
else
{
sfx = (float *)sc->data + (pos>>PITCHSHIFT);
for (i=0 ; i<count ; i++)
{
paintbuffer[i].s[0] += (sfx[i] * vol[0]);
paintbuffer[i].s[1] += (sfx[i] * vol[1]);
paintbuffer[i].s[2] += (sfx[i] * vol[2]);
paintbuffer[i].s[3] += (sfx[i] * vol[3]);
}
}
}
static void SND_PaintChannel32F_O6I1 (channel_t *ch, sfxcache_t *sc, int count, int rate)
{
int vol[6];
float *sfx;
int i;
unsigned int pos = ch->pos-(sc->soundoffset<<PITCHSHIFT);
vol[0] = ch->vol[0]*128;
vol[1] = ch->vol[1]*128;
vol[2] = ch->vol[2]*128;
vol[3] = ch->vol[3]*128;
vol[4] = ch->vol[4]*128;
vol[5] = ch->vol[5]*128;
if (rate != (1<<PITCHSHIFT))
{
float data;
sfx = (float *)sc->data;
for (i=0 ; i<count ; i++)
{
data = sfx[pos>>PITCHSHIFT];
pos += rate;
paintbuffer[i].s[0] += (vol[0] * data);
paintbuffer[i].s[1] += (vol[1] * data);
paintbuffer[i].s[2] += (vol[2] * data);
paintbuffer[i].s[3] += (vol[3] * data);
paintbuffer[i].s[4] += (vol[4] * data);
paintbuffer[i].s[5] += (vol[5] * data);
}
}
else
{
sfx = (float *)sc->data + (pos>>PITCHSHIFT);
for (i=0 ; i<count ; i++)
{
paintbuffer[i].s[0] += (sfx[i] * vol[0]);
paintbuffer[i].s[1] += (sfx[i] * vol[1]);
paintbuffer[i].s[2] += (sfx[i] * vol[2]);
paintbuffer[i].s[3] += (sfx[i] * vol[3]);
paintbuffer[i].s[4] += (sfx[i] * vol[4]);
paintbuffer[i].s[5] += (sfx[i] * vol[5]);
}
}
}
static void SND_PaintChannel32F_O8I1 (channel_t *ch, sfxcache_t *sc, int count, int rate)
{
int vol[8];
float *sfx;
int i;
unsigned int pos = ch->pos-(sc->soundoffset<<PITCHSHIFT);
//input is +/- 1, output is +/- 32767. ch->vol is 0-255, so we just need to scale up by an extra 128
vol[0] = ch->vol[0]*128;
vol[1] = ch->vol[1]*128;
vol[2] = ch->vol[2]*128;
vol[3] = ch->vol[3]*128;
vol[4] = ch->vol[4]*128;
vol[5] = ch->vol[5]*128;
vol[6] = ch->vol[6]*128;
vol[7] = ch->vol[7]*128;
if (rate != (1<<PITCHSHIFT))
{
float data;
sfx = (float *)sc->data;
for (i=0 ; i<count ; i++)
{
data = sfx[pos>>PITCHSHIFT];
pos += rate;
paintbuffer[i].s[0] += (vol[0] * data);
paintbuffer[i].s[1] += (vol[1] * data);
paintbuffer[i].s[2] += (vol[2] * data);
paintbuffer[i].s[3] += (vol[3] * data);
paintbuffer[i].s[4] += (vol[4] * data);
paintbuffer[i].s[5] += (vol[5] * data);
paintbuffer[i].s[6] += (vol[6] * data);
paintbuffer[i].s[7] += (vol[7] * data);
}
}
else
{
sfx = (float *)sc->data + (pos>>PITCHSHIFT);
for (i=0 ; i<count ; i++)
{
paintbuffer[i].s[0] += (sfx[i] * vol[0]);
paintbuffer[i].s[1] += (sfx[i] * vol[1]);
paintbuffer[i].s[2] += (sfx[i] * vol[2]);
paintbuffer[i].s[3] += (sfx[i] * vol[3]);
paintbuffer[i].s[4] += (sfx[i] * vol[4]);
paintbuffer[i].s[5] += (sfx[i] * vol[5]);
paintbuffer[i].s[6] += (sfx[i] * vol[6]);
paintbuffer[i].s[7] += (sfx[i] * vol[7]);
}
}
}
#endif
#endif

View File

@ -313,7 +313,8 @@ void S_LocalSound2 (const char *sound, int channel, float volume);
qboolean S_LoadSound (sfx_t *s, qboolean forcedecode);
typedef qboolean (QDECL *S_LoadSound_t) (sfx_t *s, qbyte *data, size_t datalen, int sndspeed, qboolean forcedecode);
qboolean S_RegisterSoundInputPlugin(S_LoadSound_t loadfnc); //called to register additional sound input plugins
qboolean S_RegisterSoundInputPlugin(void *module, S_LoadSound_t loadfnc); //called to register additional sound input plugins
void S_UnregisterSoundInputModule(void *module);
void S_AmbientOff (void);
void S_AmbientOn (void);

View File

@ -232,9 +232,9 @@ static void Con_Editor_DeleteSelection(console_t *con)
n = Con_EditorMerge(con, con->selstartline, n);
}
}
con->userline = con->selstartline;
con->useroffset = con->selstartoffset;
}
con->userline = con->selstartline;
con->useroffset = con->selstartoffset;
}
static void Con_Editor_DoPaste(void *ctx, char *utf8)
{
@ -850,7 +850,7 @@ qboolean Con_Editor_Close(console_t *con, qboolean force)
{
if (!strncmp(con->title, "MODIFIED: ", 10))
{
M_Menu_Prompt(Con_Editor_CloseCallback, con, va("Save changes?\n%s\n", con->name), "Yes", "No", "Cancel");
Menu_Prompt(Con_Editor_CloseCallback, con, va("Save changes?\n%s\n", con->name), "Yes", "No", "Cancel");
return false;
}
}

View File

@ -175,7 +175,6 @@ extern cvar_t host_mapname;
void TP_UpdateAutoStatus(void);
static void TP_FindModelNumbers (void);
static void TP_FindPoint (void);
char *TP_LocationName (vec3_t location);
#define MAX_LOC_NAME 48
@ -1640,7 +1639,7 @@ static void TP_LoadLocFile_f (void)
TP_LoadLocFile (Cmd_Argv(1), false);
}
char *TP_LocationName (vec3_t location)
char *TP_LocationName (const vec3_t location)
{
int i, j, minnum;
float dist, mindist;

View File

@ -23,7 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// release version
#define FTE_VER_MAJOR 1
#define FTE_VER_MINOR 6
#define FTE_VER_MINOR 7
#if defined(__APPLE__) && defined(__MACH__)
#define MACOSX
@ -562,7 +562,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define VM_UI
#endif
#if defined(VM_Q1) || defined(VM_UI) || defined(VM_CG) || defined(Q3SERVER) || defined(PLUGINS)
#if defined(VM_Q1) || defined(VM_UI) || defined(VM_CG) || defined(Q3SERVER)
#define VM_ANY
#endif

View File

@ -1009,6 +1009,7 @@ typedef struct
int lerpcount; //number of pose+frac entries.
float frac[FRAME_BLENDS*2]; //weight of this animation (1 if lerpcount is 1)
float *pose[FRAME_BLENDS*2]; //pointer to the raw frame data for bone 0.
void *needsfree[FRAME_BLENDS*2];
} skellerps_t;
static qboolean Alias_BuildSkelLerps(skellerps_t *lerps, const struct framestateregion_s *fs, int numbones, const galiasinfo_t *inf)
{
@ -1043,6 +1044,26 @@ static qboolean Alias_BuildSkelLerps(skellerps_t *lerps, const struct framestate
}
g = &inf->ofsanimations[frame];
if (lerps->skeltype == SKEL_IDENTITY)
lerps->skeltype = g->skeltype;
else if (lerps->skeltype != g->skeltype)
{
dropweight += fs->lerpweight[b];
continue; //oops, can't cope with mixed blend types
}
if (g->GetRawBones)
{
lerps->frac[l] = fs->lerpweight[b];
lerps->needsfree[l] = BZ_Malloc(sizeof(float)*12*numbones);
lerps->pose[l] = g->GetRawBones(inf, g, time, lerps->needsfree[l], numbones);
if (lerps->pose[l])
l++;
else
dropweight += lerps->frac[l];
continue;
}
if (!g->numposes)
{
dropweight += fs->lerpweight[b];
@ -1068,14 +1089,6 @@ static qboolean Alias_BuildSkelLerps(skellerps_t *lerps, const struct framestate
frame2=bound(0, frame2, g->numposes-1);
}
if (lerps->skeltype == SKEL_IDENTITY)
lerps->skeltype = g->skeltype;
else if (lerps->skeltype != g->skeltype)
{
dropweight += fs->lerpweight[b];
continue; //oops, can't cope with mixed blend types
}
if (frame1 == frame2)
mlerp = 0;
else if (r_noframegrouplerp.ival)
@ -1084,13 +1097,15 @@ static qboolean Alias_BuildSkelLerps(skellerps_t *lerps, const struct framestate
if (lerps->frac[l]>0)
{
totalweight += lerps->frac[l];
lerps->pose[l++] = g->boneofs + numbones*12*frame1;
lerps->needsfree[l] = NULL;
lerps->pose[l++] = (float*)g->boneofs + numbones*12*frame1;
}
lerps->frac[l] = (mlerp)*fs->lerpweight[b];
if (lerps->frac[l]>0)
{
totalweight += lerps->frac[l];
lerps->pose[l++] = g->boneofs + numbones*12*frame2;
lerps->needsfree[l] = NULL;
lerps->pose[l++] = (float*)g->boneofs + numbones*12*frame2;
}
}
}
@ -1157,6 +1172,7 @@ static int Alias_FindRawSkelData(galiasinfo_t *inf, const framestate_t *fstate,
if (!inf->baseframeofs)
continue; //nope, not happening.
lerps->skeltype = SKEL_ABSOLUTE;
lerps->needsfree[0] = NULL;
lerps->frac[0] = 1;
lerps->pose[0] = inf->baseframeofs;
lerps->lerpcount = 1;
@ -1186,32 +1202,34 @@ static int Alias_BlendBoneData(galiasinfo_t *inf, framestate_t *fstate, float *r
for (lerp = lerps; numgroups--; lerp++)
{
if (lerp[0].skeltype != skeltype)
continue; //egads, its buggy. should probably convert.
bone = lerp->firstbone;
endbone = lerp->endbone;
if (lerp->lerpcount == 1 && lerp->frac[0] == 1)
memcpy(result+bone*12, lerp->pose[0]+bone*12, (endbone-bone)*12*sizeof(float));
else
if (lerp->skeltype == skeltype)
{
//set up the identity matrix
for (; bone < endbone; bone++)
bone = lerp->firstbone;
endbone = lerp->endbone;
if (lerp->lerpcount == 1 && lerp->frac[0] == 1)
memcpy(result+bone*12, lerp->pose[0]+bone*12, (endbone-bone)*12*sizeof(float));
else
{
pose = result + 12*bone;
//set up the per-bone transform matrix
matrix = lerps->pose[0] + bone*12;
for (k = 0;k < 12;k++)
pose[k] = matrix[k] * lerp->frac[0];
for (b = 1;b < lerp->lerpcount;b++)
//set up the identity matrix
for (; bone < endbone; bone++)
{
matrix = lerps->pose[b] + bone*12;
pose = result + 12*bone;
//set up the per-bone transform matrix
matrix = lerps->pose[0] + bone*12;
for (k = 0;k < 12;k++)
pose[k] += matrix[k] * lerp->frac[b];
pose[k] = matrix[k] * lerp->frac[0];
for (b = 1;b < lerp->lerpcount;b++)
{
matrix = lerps->pose[b] + bone*12;
for (k = 0;k < 12;k++)
pose[k] += matrix[k] * lerp->frac[b];
}
}
}
}
for (k = 0; k < lerp->lerpcount; k++)
BZ_Free(lerp->needsfree[k]);
}
return endbone;
}
@ -1225,6 +1243,7 @@ static const float *Alias_GetBoneInformation(galiasinfo_t *inf, const framestate
skellerps_t lerps[FS_COUNT], *lerp;
size_t numgroups;
size_t bone, endbone;
const float *ret;
lerps[0].skeltype = SKEL_IDENTITY; //just in case.
#ifdef SKELETALOBJECTS
@ -1235,6 +1254,7 @@ static const float *Alias_GetBoneInformation(galiasinfo_t *inf, const framestate
lerps[0].endbone = framestate->bonecount;
lerps[0].pose[0] = framestate->bonestate;
lerps[0].frac[0] = 1;
lerps[0].needsfree[0] = NULL;
lerps[0].lerpcount = 1;
numgroups = 1;
}
@ -1246,7 +1266,11 @@ static const float *Alias_GetBoneInformation(galiasinfo_t *inf, const framestate
//try to return data in-place.
if (numgroups==1 && lerps[0].lerpcount == 1)
return Alias_ConvertBoneData(lerps[0].skeltype, lerps[0].pose[0], min(lerps[0].endbone, inf->numbones), inf->ofsbones, targettype, targetbuffer, targetbufferalt, maxbufferbones);
{
ret = Alias_ConvertBoneData(lerps[0].skeltype, lerps[0].pose[0], min(lerps[0].endbone, inf->numbones), inf->ofsbones, targettype, targetbuffer, targetbufferalt, maxbufferbones);
BZ_Free(lerps[0].needsfree[0]);
return ret;
}
for (lerp = lerps; numgroups--; lerp++)
{
@ -1265,6 +1289,8 @@ static const float *Alias_GetBoneInformation(galiasinfo_t *inf, const framestate
for (k = 0; k < 12; k++) //please please unroll!
out[k] = (pose1[k]*frac1) + (frac2*pose2[k]);
}
BZ_Free(lerp->needsfree[0]);
BZ_Free(lerp->needsfree[1]);
}
break;
case 3:
@ -1278,6 +1304,9 @@ static const float *Alias_GetBoneInformation(galiasinfo_t *inf, const framestate
for (k = 0; k < 12; k++) //please please unroll!
out[k] = (pose1[k]*frac1) + (frac2*pose2[k]) + (pose3[k]*frac3);
}
BZ_Free(lerp->needsfree[0]);
BZ_Free(lerp->needsfree[1]);
BZ_Free(lerp->needsfree[2]);
}
break;
case 4:
@ -1291,6 +1320,10 @@ static const float *Alias_GetBoneInformation(galiasinfo_t *inf, const framestate
for (k = 0; k < 12; k++) //please please unroll!
out[k] = (pose1[k]*frac1) + (frac2*pose2[k]) + (pose3[k]*frac3) + (frac4*pose4[k]);
}
BZ_Free(lerp->needsfree[0]);
BZ_Free(lerp->needsfree[1]);
BZ_Free(lerp->needsfree[2]);
BZ_Free(lerp->needsfree[3]);
}
break;
case 0:
@ -1316,6 +1349,7 @@ static const float *Alias_GetBoneInformation(galiasinfo_t *inf, const framestate
for (k = 0; k < 12; k++)
out[k] += (pose[k]*frac);
}
BZ_Free(lerp->needsfree[i]);
}
}
break;
@ -4609,6 +4643,7 @@ qboolean Mod_GetTag(model_t *model, int tagnum, framestate_t *fstate, float *res
lerps[0].pose[0] = fstate->bonestate;
lerps[0].frac[0] = 1;
lerps[0].needsfree[0] = 0;
lerps[0].lerpcount = 1;
lerps[0].firstbone = 0;
lerps[0].endbone = fstate->bonecount;
@ -4625,6 +4660,7 @@ qboolean Mod_GetTag(model_t *model, int tagnum, framestate_t *fstate, float *res
{
lerps[0].pose[0] = inf->baseframeofs;
lerps[0].frac[0] = 1;
lerps[0].needsfree[0] = 0;
lerps[0].lerpcount = 1;
lerps[0].firstbone = 0;
lerps[0].endbone = inf->numbones;
@ -4660,7 +4696,7 @@ qboolean Mod_GetTag(model_t *model, int tagnum, framestate_t *fstate, float *res
if (lerp->skeltype == SKEL_ABSOLUTE)
{
memcpy(result, m, sizeof(tempmatrix));
return true;
break;
}
memcpy(tempmatrix, result, sizeof(tempmatrix));
@ -4669,6 +4705,9 @@ qboolean Mod_GetTag(model_t *model, int tagnum, framestate_t *fstate, float *res
tagnum = bone[tagnum].parent;
}
for (b = 0; b < numbonegroups; lerp++, b++)
for (k = 0; k < lerps[b].lerpcount; k++)
BZ_Free(lerps[b].needsfree[k]);
return true;
}
#endif

View File

@ -13,6 +13,8 @@ extern "C" {
#include "model_hl.h"
#endif
struct galiasinfo_s; //per-surface info.
#ifdef NONSKELETALMODELS
//a single pose within an animation (note: always refered to via a framegroup, even if there's only one frame in that group).
typedef struct
@ -43,12 +45,13 @@ typedef struct galiasevent_s
} galiasevent_t;
//a frame group (aka: animation)
typedef struct
typedef struct galiasanimation_s
{
#ifdef SKELETALMODELS
skeltype_t skeltype; //for models with transforms, states that bones need to be transformed from their parent.
//this is actually bad, and can result in bones shortening as they interpolate.
float *boneofs; //numposes*12*numbones
float *(QDECL *GetRawBones)(const struct galiasinfo_s *mesh, const struct galiasanimation_s *a, float time, float *bonematrixstorage, int numbones);
void *boneofs; //numposes*12*numbones
#endif
qboolean loop;
int numposes;
@ -208,6 +211,8 @@ typedef struct galiasinfo_s
FTE_DEPRECATED int numtags;
FTE_DEPRECATED md3tag_t *ofstags;
#endif
void *ctx; //loader-specific stuff. must be ZG_Malloced if it lasts beyond the loader.
unsigned int warned; //passed around at load time, so we don't spam warnings
} galiasinfo_t;
@ -215,36 +220,36 @@ struct terrainfuncs_s;
typedef struct modplugfuncs_s
{
int version;
//format handling
int (QDECL *RegisterModelFormatText)(const char *formatname, char *magictext, qboolean (QDECL *load) (struct model_s *mod, void *buffer, size_t fsize));
int (QDECL *RegisterModelFormatMagic)(const char *formatname, unsigned int magic, qboolean (QDECL *load) (struct model_s *mod, void *buffer, size_t fsize));
void (QDECL *UnRegisterModelFormat)(int idx);
void (QDECL *UnRegisterAllModelFormats)(void);
//util
void *(QDECL *ZG_Malloc)(zonegroup_t *ctx, size_t size); //ctx=&mod->memgroup and the data will be freed when the model is freed.
void (QDECL *StripExtension) (const char *in, char *out, int outlen);
//matrix maths
void (QDECL *ConcatTransforms) (const float in1[3][4], const float in2[3][4], float out[3][4]);
void (QDECL *M3x4_Invert) (const float *in1, float *out);
void (QDECL *VectorAngles)(const float *forward, const float *up, float *result, qboolean meshpitch);
void (QDECL *AngleVectors)(const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up);
void (QDECL *GenMatrixPosQuat4Scale)(const vec3_t pos, const vec4_t quat, const vec3_t scale, float result[12]);
void (QDECL *StripExtension) (const char *in, char *out, int outlen);
//bone stuff
void (QDECL *ForceConvertBoneData)(skeltype_t sourcetype, const float *sourcedata, size_t bonecount, galiasbone_t *bones, skeltype_t desttype, float *destbuffer, size_t destbonecount);
struct terrainfuncs_s *(QDECL *GetTerrainFuncs)(void);
void *reserved2;
//texturing
image_t *(QDECL *GetTexture)(const char *identifier, const char *subpath, unsigned int flags, void *fallbackdata, void *fallbackpalette, int fallbackwidth, int fallbackheight, uploadfmt_t fallbackfmt);
vfsfile_t *(QDECL *OpenVFS)(const char *filename, const char *mode, enum fs_relative relativeto);
void (QDECL *AccumulateTextureVectors)(vecV_t *const vc, vec2_t *const tc, vec3_t *nv, vec3_t *sv, vec3_t *tv, const index_t *idx, int numidx, qboolean calcnorms);
void (QDECL *NormaliseTextureVectors)(vec3_t *n, vec3_t *s, vec3_t *t, int v, qboolean calcnorms);
void *unused5;
void *unused6;
void *unused7;
void *unused8;
void *unused9;
void *unused10;
} modplugfuncs_t;
#define MODPLUGFUNCS_VERSION 2
model_t *(QDECL *GetModel)(const char *identifier, enum mlverbosity_e verbosity);
#define plugmodfuncs_name "Models"
} plugmodfuncs_t;
#define MODPLUGFUNCS_VERSION 1
#ifdef SKELETALMODELS
void Alias_TransformVerticies(float *bonepose, galisskeletaltransforms_t *weights, int numweights, vecV_t *xyzout, vec3_t *normout);

View File

@ -29,10 +29,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef FTEPLUGIN
#define FTEENGINE
#define FTEPLUGIN
#define pCvar_Register Cvar_Get
#define pCvar_GetFloat(x) Cvar_FindVar(x)->value
#define Sys_Errorf Sys_Error
#define pSys_Error(p) Sys_Errorf("%s",p)
#define Plug_Init Plug_ODE_Init
#endif
@ -67,17 +63,6 @@ static int VectorCompare (const vec3_t v1, const vec3_t v2)
#endif
#define ARGNAMES ,name,funcs
static BUILTINR(dllhandle_t *, Sys_LoadLibrary, (const char *name,dllfunction_t *funcs));
#undef ARGNAMES
#define ARGNAMES ,hdl
static BUILTIN(void, Sys_CloseLibrary, (dllhandle_t *hdl));
#undef ARGNAMES
#define ARGNAMES ,version
static BUILTINR(rbeplugfuncs_t*, RBE_GetPluginFuncs, (int version));
#undef ARGNAMES
static rbeplugfuncs_t *rbefuncs;
cvar_t r_meshpitch;
@ -1288,29 +1273,29 @@ static qboolean World_ODE_Init(void)
};
#endif
physics_ode_quadtree_depth = pCvar_GetNVFDG("physics_ode_quadtree_depth", "5", 0, "desired subdivision level of quadtree culling space", "ODE Physics Library");
physics_ode_contactsurfacelayer = pCvar_GetNVFDG("physics_ode_contactsurfacelayer", "0", 0, "allows objects to overlap this many units to reduce jitter", "ODE Physics Library");
physics_ode_worldquickstep = pCvar_GetNVFDG("physics_ode_worldquickstep", "1", 0, "use dWorldQuickStep rather than dWorldStep", "ODE Physics Library");
physics_ode_worldquickstep_iterations = pCvar_GetNVFDG("physics_ode_worldquickstep_iterations", "20", 0, "parameter to dWorldQuickStep", "ODE Physics Library");
physics_ode_contact_mu = pCvar_GetNVFDG("physics_ode_contact_mu", "1", 0, "contact solver mu parameter - friction pyramid approximation 1 (see ODE User Guide)", "ODE Physics Library");
physics_ode_contact_erp = pCvar_GetNVFDG("physics_ode_contact_erp", "0.96", 0, "contact solver erp parameter - Error Restitution Percent (see ODE User Guide)", "ODE Physics Library");
physics_ode_contact_cfm = pCvar_GetNVFDG("physics_ode_contact_cfm", "0", 0, "contact solver cfm parameter - Constraint Force Mixing (see ODE User Guide)", "ODE Physics Library");
physics_ode_world_damping = pCvar_GetNVFDG("physics_ode_world_damping", "1", 0, "enabled damping scale (see ODE User Guide), this scales all damping values, be aware that behavior depends of step type", "ODE Physics Library");
physics_ode_world_damping_linear = pCvar_GetNVFDG("physics_ode_world_damping_linear", "-1",0, "world linear damping scale (see ODE User Guide); use defaults when set to -1", "ODE Physics Library");
physics_ode_world_damping_linear_threshold = pCvar_GetNVFDG("physics_ode_world_damping_linear_threshold", "-1", 0, "world linear damping threshold (see ODE User Guide); use defaults when set to -1", "ODE Physics Library");
physics_ode_world_damping_angular = pCvar_GetNVFDG("physics_ode_world_damping_angular", "-1",0, "world angular damping scale (see ODE User Guide); use defaults when set to -1", "ODE Physics Library");
physics_ode_world_damping_angular_threshold = pCvar_GetNVFDG("physics_ode_world_damping_angular_threshold", "-1", 0, "world angular damping threshold (see ODE User Guide); use defaults when set to -1", "ODE Physics Library");
physics_ode_world_erp = pCvar_GetNVFDG("physics_ode_world_erp", "-1", 0, "world solver erp parameter - Error Restitution Percent (see ODE User Guide); use defaults when set to -1", "ODE Physics Library");
physics_ode_world_cfm = pCvar_GetNVFDG("physics_ode_world_cfm", "-1", 0, "world solver cfm parameter - Constraint Force Mixing (see ODE User Guide); not touched when -1", "ODE Physics Library");
physics_ode_iterationsperframe = pCvar_GetNVFDG("physics_ode_iterationsperframe", "4", 0, "divisor for time step, runs multiple physics steps per frame", "ODE Physics Library");
physics_ode_movelimit = pCvar_GetNVFDG("physics_ode_movelimit", "0.5", 0, "clamp velocity if a single move would exceed this percentage of object thickness, to prevent flying through walls","ODE Physics Library");
physics_ode_spinlimit = pCvar_GetNVFDG("physics_ode_spinlimit", "10000",0, "reset spin velocity if it gets too large", "ODE Physics Library");
physics_ode_autodisable = pCvar_GetNVFDG("physics_ode_autodisable", "1", 0, "automatic disabling of objects which dont move for long period of time, makes object stacking a lot faster", "ODE Physics Library");
physics_ode_autodisable_steps = pCvar_GetNVFDG("physics_ode_autodisable_steps", "10", 0, "how many steps object should be dormant to be autodisabled", "ODE Physics Library");
physics_ode_autodisable_time = pCvar_GetNVFDG("physics_ode_autodisable_time", "0", 0, "how many seconds object should be dormant to be autodisabled", "ODE Physics Library");
physics_ode_autodisable_threshold_linear = pCvar_GetNVFDG("physics_ode_autodisable_threshold_linear", "0.2", 0, "body will be disabled if it's linear move below this value", "ODE Physics Library");
physics_ode_autodisable_threshold_angular = pCvar_GetNVFDG("physics_ode_autodisable_threshold_angular", "0.3", 0, "body will be disabled if it's angular move below this value", "ODE Physics Library");
physics_ode_autodisable_threshold_samples = pCvar_GetNVFDG("physics_ode_autodisable_threshold_samples", "5", 0, "average threshold with this number of samples", "ODE Physics Library");
physics_ode_quadtree_depth = cvarfuncs->GetNVFDG("physics_ode_quadtree_depth", "5", 0, "desired subdivision level of quadtree culling space", "ODE Physics Library");
physics_ode_contactsurfacelayer = cvarfuncs->GetNVFDG("physics_ode_contactsurfacelayer", "0", 0, "allows objects to overlap this many units to reduce jitter", "ODE Physics Library");
physics_ode_worldquickstep = cvarfuncs->GetNVFDG("physics_ode_worldquickstep", "1", 0, "use dWorldQuickStep rather than dWorldStep", "ODE Physics Library");
physics_ode_worldquickstep_iterations = cvarfuncs->GetNVFDG("physics_ode_worldquickstep_iterations", "20", 0, "parameter to dWorldQuickStep", "ODE Physics Library");
physics_ode_contact_mu = cvarfuncs->GetNVFDG("physics_ode_contact_mu", "1", 0, "contact solver mu parameter - friction pyramid approximation 1 (see ODE User Guide)", "ODE Physics Library");
physics_ode_contact_erp = cvarfuncs->GetNVFDG("physics_ode_contact_erp", "0.96", 0, "contact solver erp parameter - Error Restitution Percent (see ODE User Guide)", "ODE Physics Library");
physics_ode_contact_cfm = cvarfuncs->GetNVFDG("physics_ode_contact_cfm", "0", 0, "contact solver cfm parameter - Constraint Force Mixing (see ODE User Guide)", "ODE Physics Library");
physics_ode_world_damping = cvarfuncs->GetNVFDG("physics_ode_world_damping", "1", 0, "enabled damping scale (see ODE User Guide), this scales all damping values, be aware that behavior depends of step type", "ODE Physics Library");
physics_ode_world_damping_linear = cvarfuncs->GetNVFDG("physics_ode_world_damping_linear", "-1",0, "world linear damping scale (see ODE User Guide); use defaults when set to -1", "ODE Physics Library");
physics_ode_world_damping_linear_threshold = cvarfuncs->GetNVFDG("physics_ode_world_damping_linear_threshold", "-1", 0, "world linear damping threshold (see ODE User Guide); use defaults when set to -1", "ODE Physics Library");
physics_ode_world_damping_angular = cvarfuncs->GetNVFDG("physics_ode_world_damping_angular", "-1",0, "world angular damping scale (see ODE User Guide); use defaults when set to -1", "ODE Physics Library");
physics_ode_world_damping_angular_threshold = cvarfuncs->GetNVFDG("physics_ode_world_damping_angular_threshold", "-1", 0, "world angular damping threshold (see ODE User Guide); use defaults when set to -1", "ODE Physics Library");
physics_ode_world_erp = cvarfuncs->GetNVFDG("physics_ode_world_erp", "-1", 0, "world solver erp parameter - Error Restitution Percent (see ODE User Guide); use defaults when set to -1", "ODE Physics Library");
physics_ode_world_cfm = cvarfuncs->GetNVFDG("physics_ode_world_cfm", "-1", 0, "world solver cfm parameter - Constraint Force Mixing (see ODE User Guide); not touched when -1", "ODE Physics Library");
physics_ode_iterationsperframe = cvarfuncs->GetNVFDG("physics_ode_iterationsperframe", "4", 0, "divisor for time step, runs multiple physics steps per frame", "ODE Physics Library");
physics_ode_movelimit = cvarfuncs->GetNVFDG("physics_ode_movelimit", "0.5", 0, "clamp velocity if a single move would exceed this percentage of object thickness, to prevent flying through walls","ODE Physics Library");
physics_ode_spinlimit = cvarfuncs->GetNVFDG("physics_ode_spinlimit", "10000",0, "reset spin velocity if it gets too large", "ODE Physics Library");
physics_ode_autodisable = cvarfuncs->GetNVFDG("physics_ode_autodisable", "1", 0, "automatic disabling of objects which dont move for long period of time, makes object stacking a lot faster", "ODE Physics Library");
physics_ode_autodisable_steps = cvarfuncs->GetNVFDG("physics_ode_autodisable_steps", "10", 0, "how many steps object should be dormant to be autodisabled", "ODE Physics Library");
physics_ode_autodisable_time = cvarfuncs->GetNVFDG("physics_ode_autodisable_time", "0", 0, "how many seconds object should be dormant to be autodisabled", "ODE Physics Library");
physics_ode_autodisable_threshold_linear = cvarfuncs->GetNVFDG("physics_ode_autodisable_threshold_linear", "0.2", 0, "body will be disabled if it's linear move below this value", "ODE Physics Library");
physics_ode_autodisable_threshold_angular = cvarfuncs->GetNVFDG("physics_ode_autodisable_threshold_angular", "0.3", 0, "body will be disabled if it's angular move below this value", "ODE Physics Library");
physics_ode_autodisable_threshold_samples = cvarfuncs->GetNVFDG("physics_ode_autodisable_threshold_samples", "5", 0, "average threshold with this number of samples", "ODE Physics Library");
#ifdef ODE_DYNAMIC
// Load the DLL
@ -2753,12 +2738,12 @@ static void QDECL World_ODE_Start(world_t *world)
memset(ctx, 0, sizeof(*ctx));
world->rbe = &ctx->pub;
r_meshpitch.value = pCvar_GetFloat("r_meshpitch");
r_meshpitch.value = cvarfuncs->GetFloat("r_meshpitch");
VectorAvg(world->worldmodel->mins, world->worldmodel->maxs, center);
VectorSubtract(world->worldmodel->maxs, center, extents);
ctx->dworld = dWorldCreate();
ctx->space = dQuadTreeSpaceCreate(NULL, center, extents, bound(1, pCvar_GetFloat("physics_ode_quadtree_depth"), 10));
ctx->space = dQuadTreeSpaceCreate(NULL, center, extents, bound(1, cvarfuncs->GetFloat("physics_ode_quadtree_depth"), 10));
ctx->contactgroup = dJointGroupCreate(0);
ctx->pub.End = World_ODE_End;
@ -2836,38 +2821,28 @@ static void World_ODE_RunCmd(world_t *world, rbecommandqueue_t *cmd)
}
}
static qintptr_t QDECL Plug_ODE_Shutdown(qintptr_t *args)
static void QDECL Plug_ODE_Shutdown(void)
{
if (rbefuncs)
rbefuncs->UnregisterPhysicsEngine("ODE");
World_ODE_Shutdown();
return 0;
}
qintptr_t Plug_Init(qintptr_t *args)
qboolean Plug_Init(void)
{
CHECKBUILTIN(RBE_GetPluginFuncs);
#ifndef ODE_STATIC
CHECKBUILTIN(Sys_LoadLibrary);
CHECKBUILTIN(Sys_CloseLibrary);
#endif
if (BUILTINISVALID(RBE_GetPluginFuncs))
{
rbefuncs = pRBE_GetPluginFuncs(sizeof(rbeplugfuncs_t));
if (rbefuncs && rbefuncs->version < RBEPLUGFUNCS_VERSION)
rbefuncs = NULL;
}
rbefuncs = plugfuncs->GetEngineInterface("RBE", sizeof(rbeplugfuncs_t));
if (rbefuncs && rbefuncs->version < RBEPLUGFUNCS_VERSION)
rbefuncs = NULL;
if (!rbefuncs)
{
Con_Printf("ODE plugin failed: Engine does not support external rigid body engines.\n");
return false;
}
if (!BUILTINISVALID(Cvar_GetNVFDG))
{
Con_Printf("ODE plugin failed: Engine too old.\n");
return false;
}
#ifndef ODE_STATIC
if (!BUILTINISVALID(Sys_LoadLibrary) || !BUILTINISVALID(Sys_CloseLibrary))
{
@ -2888,7 +2863,7 @@ qintptr_t Plug_Init(qintptr_t *args)
rbefuncs->UnregisterPhysicsEngine("ODE");
return false;
}
Plug_Export("Shutdown", Plug_ODE_Shutdown);
plugfuncs->ExportFunction("Shutdown", Plug_ODE_Shutdown);
return true;
}
return false;

View File

@ -7615,7 +7615,7 @@ void SV_FlushRedirect (void);
vfsfile_t *con_pipe;
#ifdef HAVE_SERVER
vfsfile_t *Con_POpen(char *conname)
vfsfile_t *Con_POpen(const char *conname)
{
if (!conname || !*conname)
{

View File

@ -576,6 +576,7 @@ void VARGS VFS_PRINTF(vfsfile_t *vf, const char *fmt, ...) LIKEPRINTF(2);
enum fs_relative{
FS_BINARYPATH, //for dlls and stuff
FS_LIBRARYPATH, //for system dlls and stuff
FS_ROOT, //./ (effective -homedir if enabled, otherwise effective -basedir arg)
FS_SYSTEM, //a system path. absolute paths are explicitly allowed and expected, but not required.

View File

@ -254,7 +254,7 @@ void Con_ToggleConsole_Force(void);
int Con_ExecuteLine(console_t *con, const char *line); //takes normal console commands
int Con_Navigate(console_t *con, const char *line); //special webbrowser hacks
vfsfile_t *Con_POpen(char *conname);
vfsfile_t *Con_POpen(const char *conname);
void Con_CycleConsole (void);
int Con_IsActive (console_t *con);
void Con_Destroy (console_t *con);

View File

@ -787,9 +787,9 @@ qboolean CertLog_ConnectOkay(const char *hostname, void *cert, size_t certsize)
//FIXME: display some sort of fingerprint
if (!l)
M_Menu_Prompt(CertLog_Add_Prompted, ctx, va("%s\nServer certificate is\nself-signed", hostname), "Trust", NULL, "Disconnect");
Menu_Prompt(CertLog_Add_Prompted, ctx, va("%s\nServer certificate is\nself-signed", hostname), "Trust", NULL, "Disconnect");
else
M_Menu_Prompt(CertLog_Add_Prompted, ctx, va("%s\n^1Server certificate HAS CHANGED\nZomg\n^bFlee in Terror", hostname), "ReTrust", NULL, "Disconnect");
Menu_Prompt(CertLog_Add_Prompted, ctx, va("%s\n^1Server certificate HAS CHANGED\nZomg\n^bFlee in Terror", hostname), "ReTrust", NULL, "Disconnect");
}
return false; //can't connect yet...
}

View File

@ -62,7 +62,7 @@ typedef enum {
typedef enum {NS_CLIENT, NS_SERVER} netsrc_t;
typedef struct
typedef struct netadr_s
{
netadrtype_t type;
netproto_t prot;

File diff suppressed because it is too large Load Diff

View File

@ -1778,7 +1778,7 @@ typedef struct q1usercmd_s
// unused
#define E5_UNUSED30 (1<<30)
// bits2 > 0
#define E5_EXTEND4 (1<<31)
#define E5_EXTEND4 (1u<<31)
#define E5_ALLUNUSED (E5_UNUSED27|E5_UNUSED28|E5_UNUSED29|E5_UNUSED30)
#define E5_SERVERPRIVATE (E5_EXTEND1|E5_EXTEND2|E5_EXTEND3|E5_EXTEND4)

View File

@ -127,15 +127,6 @@ typedef enum {
// overlayed over whatever the cgame has drawn.
// a GetClientState syscall will be made to get the current strings
/*
UI_DRAWSTATUSBAR = 500,
UI_MOUSE_POS,
UI_INTERMISSION,
UI_FINALE,
UI_STRINGCHANGED, //parma is the string id
UI_NEWSERVER //indicates that all the strings have changed.
*/
} uiExport_t;
typedef enum {

View File

@ -31,33 +31,6 @@ void *VM_MemoryBase(vm_t *vm);
quintptr_t VM_MemoryMask(vm_t *vm);
//plugin functions
#ifdef PLUGINS
qboolean Plug_CenterPrintMessage(char *buffer, int clientnum);
qboolean Plug_ChatMessage(char *buffer, int talkernum, int tpflags);
void Plug_Command_f(void);
int Plug_ConnectionlessClientPacket(char *buffer, int size);
qboolean Plug_ConsoleLink(char *text, char *info, const char *consolename);
qboolean Plug_ConsoleLinkMouseOver(float x, float y, char *text, char *info);
void Plug_DrawReloadImages(void);
void Plug_Initialise(qboolean fromgamedir);
void Plug_Shutdown(qboolean preliminary);
qboolean Plug_Menu_Event(int eventtype, int param);
void Plug_ResChanged(void);
void Plug_SBar(playerview_t *pv);
qboolean Plug_ServerMessage(char *buffer, int messagelevel);
void Plug_Tick(void);
qboolean Plugin_ExecuteString(void);
#ifdef ANDROID
#define PLUGINPREFIX "libplug_" //android is kinda annoying and only extracts specific files.
#else
#define PLUGINPREFIX "fteplug_" //this string defines what consitutes a plugin, as opposed to some other dll
#endif
#endif
#define VM_TOSTRCACHE(a) VMQ3_StringToHandle(VM_POINTER(a))
#define VM_FROMSTRCACHE(a) VMQ3_StringFromHandle(a)
char *VMQ3_StringFromHandle(int handle);
@ -72,16 +45,8 @@ void UI_Start (void);
void UI_Stop (void);
qboolean UI_OpenMenu(void);
void UI_Restart_f(void);
qboolean UI_Q2LayoutChanged(void);
void UI_StringChanged(int num);
qboolean UI_MousePosition(float xpos, float ypos);
int UI_MenuState(void);
qboolean UI_KeyPress(int key, int unicode, qboolean down);
int UI_IsFullscreen(void);
void UI_Reset(void);
void UI_DrawMenu(void);
qboolean UI_DrawStatusBar(int scores);
qboolean UI_DrawIntermission(void);
int UI_MenuState(void);
//sans botlib
struct pc_token_s;

View File

@ -1288,6 +1288,12 @@ static void Shader_BindTextureForPass(int tmu, const shaderpass_t *pass)
else
t = r_whiteimage;
break;
case T_GEN_OCCLUSION:
if (shaderstate.curtexnums && TEXLOADED(shaderstate.curtexnums->occlusion))
t = shaderstate.curtexnums->occlusion;
else
t = r_whiteimage;
break;
case T_GEN_SHADOWMAP:
t = shaderstate.curshadowmap;
break;

View File

@ -12,7 +12,7 @@ See gl_terrain.h for terminology, networking notes, etc.
#include "gl_terrain.h"
static terrainfuncs_t terrainfuncs;
static plugterrainfuncs_t terrainfuncs;
struct patchvert_s
{
vec3_t v;
@ -6534,7 +6534,9 @@ void CL_Parse_BrushEdit(void)
else
mod->entityinfo[idx].keyvals = NULL;
#ifdef CSQC_DAT
CSQC_MapEntityEdited(modelindex, idx, data);
#endif
}
}
}
@ -8442,8 +8444,10 @@ void Mod_Terrain_Reload_f(void)
Terr_PurgeTerrainModel(mod, false, true);
}
terrainfuncs_t *QDECL Terr_GetTerrainFuncs(void)
plugterrainfuncs_t *Terr_GetTerrainFuncs(size_t structsize)
{
if (structsize != sizeof(plugterrainfuncs_t))
return NULL;
#ifdef SERVERONLY
return NULL; //dedicated server builds have all the visual stuff stripped, which makes APIs too inconsistent. Generate then save. Or fix up the API...
#else

View File

@ -1079,8 +1079,8 @@ float RadiusFromBounds (const vec3_t mins, const vec3_t maxs);
//
#ifdef TERRAIN
void Terr_Init(void);
struct terrainfuncs_s;
struct terrainfuncs_s *QDECL Terr_GetTerrainFuncs(void);
struct plugterrainfuncs_s;
struct plugterrainfuncs_s *Terr_GetTerrainFuncs(size_t structsize);
void Terr_DrawTerrainModel (batch_t **batch, entity_t *e);
void Terr_FreeModel(model_t *mod);
void Terr_FinishTerrain(model_t *model);

View File

@ -59,7 +59,6 @@ needs almost the entire 256k of stack space!
void SCR_DrawCursor(void);
qboolean GLSCR_UpdateScreen (void)
{
int uimenu;
qboolean nohud;
qboolean noworld;
extern cvar_t vid_srgb;
@ -127,11 +126,6 @@ qboolean GLSCR_UpdateScreen (void)
Shader_DoReload();
qglDisable(GL_SCISSOR_TEST);
#ifdef VM_UI
uimenu = UI_MenuState();
#else
uimenu = 0;
#endif
#ifdef TEXTEDITOR
if (editormodal)
@ -149,14 +143,6 @@ qboolean GLSCR_UpdateScreen (void)
}
else
#endif
if (Media_ShowFilm())
{
M_Draw(0);
V_UpdatePalette (false);
R2D_BrightenScreen();
Media_RecordFrame();
}
else
{
//
// do 3D refresh drawing, and then update the screen
@ -174,25 +160,23 @@ qboolean GLSCR_UpdateScreen (void)
depthcleared = true;
}
#ifdef VM_CG
if (CG_Refresh())
if (topmenu && topmenu->isopaque)
nohud = true;
#ifdef VM_CG
else if (CG_Refresh())
nohud = true;
else
#endif
#ifdef CSQC_DAT
if (CSQC_DrawView())
else if (CSQC_DrawView())
nohud = true;
else
#endif
else
{
if (uimenu != 1)
if (r_worldentity.model && cls.state == ca_active)
V_RenderView (nohud);
else
{
if (r_worldentity.model && cls.state == ca_active)
V_RenderView (nohud);
else
{
noworld = true;
}
noworld = true;
}
}
@ -212,7 +196,7 @@ qboolean GLSCR_UpdateScreen (void)
nohud = true;
}
SCR_DrawTwoDimensional(uimenu, nohud);
SCR_DrawTwoDimensional(nohud);
V_UpdatePalette (false);
R2D_BrightenScreen();

View File

@ -1198,15 +1198,16 @@ const struct sh_defaultsamplers_s sh_defaultsamplers[] =
{"s_reflectcube", 1u<<9},
{"s_reflectmask", 1u<<10},
{"s_displacement", 1u<<11},
{"s_lightmap", 1u<<12},
{"s_deluxemap", 1u<<13},
{"s_occlusion", 1u<<12},
{"s_lightmap", 1u<<13},
{"s_deluxemap", 1u<<14},
#if MAXRLIGHTMAPS > 1
{"s_lightmap1", 1u<<14},
{"s_lightmap2", 1u<<15},
{"s_lightmap3", 1u<<16},
{"s_deluxemap1", 1u<<17},
{"s_deluxemap2", 1u<<18},
{"s_deluxemap3", 1u<<19},
{"s_lightmap1", 1u<<15},
{"s_lightmap2", 1u<<16},
{"s_lightmap3", 1u<<17},
{"s_deluxemap1", 1u<<18},
{"s_deluxemap2", 1u<<19},
{"s_deluxemap3", 1u<<20},
#else
{"s_lightmap1", 0},
{"s_lightmap2", 0},
@ -4341,16 +4342,17 @@ void Shader_FixupProgPasses(parsestate_t *ps, shaderpass_t *pass)
{T_GEN_REFLECTCUBE, 0}, //9
{T_GEN_REFLECTMASK, 0}, //10
{T_GEN_DISPLACEMENT, SHADER_HASDISPLACEMENT},//11
{T_GEN_OCCLUSION, 0}, //12
// {T_GEN_REFLECTION, SHADER_HASREFLECT}, //
// {T_GEN_REFRACTION, SHADER_HASREFRACT}, //
// {T_GEN_REFRACTIONDEPTH, SHADER_HASREFRACTDEPTH},//
// {T_GEN_RIPPLEMAP, SHADER_HASRIPPLEMAP}, //
//batch
{T_GEN_LIGHTMAP, SHADER_HASLIGHTMAP}, //12
{T_GEN_DELUXMAP, 0}, //13
//more lightmaps //14,15,16
//mode deluxemaps //17,18,19
{T_GEN_LIGHTMAP, SHADER_HASLIGHTMAP}, //13
{T_GEN_DELUXMAP, 0}, //14
//more lightmaps //15,16,17
//mode deluxemaps //18,19,20
};
#ifdef HAVE_MEDIA_DECODER
@ -5464,16 +5466,17 @@ done:;
{T_GEN_REFLECTCUBE, 0}, //9
{T_GEN_REFLECTMASK, 0}, //10
{T_GEN_DISPLACEMENT, SHADER_HASDISPLACEMENT},//11
{T_GEN_OCCLUSION, 0}, //12
// {T_GEN_REFLECTION, SHADER_HASREFLECT}, //
// {T_GEN_REFRACTION, SHADER_HASREFRACT}, //
// {T_GEN_REFRACTIONDEPTH, SHADER_HASREFRACTDEPTH},//
// {T_GEN_RIPPLEMAP, SHADER_HASRIPPLEMAP}, //
//batch
{T_GEN_LIGHTMAP, SHADER_HASLIGHTMAP}, //12
{T_GEN_DELUXMAP, 0}, //13
//more lightmaps //14,15,16
//mode deluxemaps //17,18,19
{T_GEN_LIGHTMAP, SHADER_HASLIGHTMAP}, //13
{T_GEN_DELUXMAP, 0}, //14
//more lightmaps //15,16,17
//mode deluxemaps //18,19,20
};
#ifdef HAVE_MEDIA_DECODER
@ -7465,6 +7468,7 @@ static char *Shader_DecomposeSubPass(char *o, shader_t *s, shaderpass_t *p, qboo
case T_GEN_REFLECTCUBE: Shader_DecomposeSubPassMap(o, s, "map $reflectcube", s->defaulttextures[0].reflectcube); break;
case T_GEN_REFLECTMASK: Shader_DecomposeSubPassMap(o, s, "map $reflectmask", s->defaulttextures[0].reflectmask); break;
case T_GEN_DISPLACEMENT: Shader_DecomposeSubPassMap(o, s, "map $displacement", s->defaulttextures[0].displacement); break;
case T_GEN_OCCLUSION: Shader_DecomposeSubPassMap(o, s, "map $occlusion", s->defaulttextures[0].occlusion); break;
case T_GEN_CURRENTRENDER: sprintf(o, "map $currentrender "); break;
case T_GEN_SOURCECOLOUR: sprintf(o, "map $sourcecolour"); break;
case T_GEN_SOURCEDEPTH: sprintf(o, "map $sourcedepth"); break;

View File

@ -65,8 +65,6 @@ cvar_t r_shadow_realtime_dlight_specular = CVAR ("r_shadow_realtime_dlight_specu
cvar_t r_shadow_playershadows = CVARD ("r_shadow_playershadows", "1", "Controls the presence of shadows on the local player.");
cvar_t r_shadow_shadowmapping = CVARFD ("r_shadow_shadowmapping", "1", CVAR_ARCHIVE, "Enables soft shadows instead of stencil shadows.");
cvar_t r_shadow_shadowmapping_precision = CVARD ("r_shadow_shadowmapping_precision", "1", "Scales the shadowmap detail level up or down.");
extern cvar_t r_shadow_shadowmapping_nearclip;
extern cvar_t r_shadow_shadowmapping_bias;
cvar_t r_sun_dir = CVARD ("r_sun_dir", "0.2 0.5 0.8", "Specifies the direction that crepusular rays appear along");
cvar_t r_sun_colour = CVARFD ("r_sun_colour", "0 0 0", CVAR_ARCHIVE, "Specifies the colour of sunlight that appears in the form of crepuscular rays.");

View File

@ -396,7 +396,7 @@ typedef struct heightmap_s
qboolean brushesedited;
} heightmap_t;
typedef struct terrainfuncs_s
typedef struct plugterrainfuncs_s
{
void *(QDECL *GenerateWater) (hmsection_t *s, float maxheight);
qboolean (QDECL *InitLightmap) (hmsection_t *s, qboolean initialise);
@ -407,5 +407,6 @@ typedef struct terrainfuncs_s
void (QDECL *FinishedSection) (hmsection_t *s, qboolean success);
qboolean (QDECL *AutogenerateSection)(heightmap_t *hm, int sx, int sy, unsigned int tgsflags); //replace this if you want to make a terrain generator.
} terrainfuncs_t;
#define plugterrainfuncs_name "Terrain"
} plugterrainfuncs_t;
#endif

View File

@ -2314,6 +2314,7 @@ static GLhandleARB GLSlang_CreateShader (program_t *prog, const char *name, int
"uniform samplerCube s_reflectcube;\n",
"uniform sampler2D s_reflectmask;\n",
"uniform sampler2D s_displacement;\n",
"uniform sampler2D s_occlusion;\n",
"uniform sampler2D s_lightmap;\n#define s_lightmap0 s_lightmap\n",
"uniform sampler2D s_deluxemap;\n#define s_deluxemap0 s_deluxemap\n",

View File

@ -272,6 +272,7 @@ typedef struct shaderpass_s {
T_GEN_REFLECTCUBE, //dpreflectcube
T_GEN_REFLECTMASK, //dpreflectcube mask
T_GEN_DISPLACEMENT, //displacement texture (probably half-float or something so higher precision than normalmap.a)
T_GEN_OCCLUSION, //occlusion mask (instead of baking it into the texture itself, required for correct pbr)
T_GEN_CURRENTRENDER,//copy the current screen to a texture, and draw that

View File

@ -817,9 +817,8 @@ void SV_Map_f (void)
}
#endif
#if defined(MENU_DAT) && !defined(SERVERONLY)
if (Key_Dest_Has(kdm_gmenu))
MP_Toggle(0);
#ifdef HAVE_CLIENT
Menu_PopAll();
#endif
if (preserveplayers && svprogfuncs)

View File

@ -3060,6 +3060,9 @@ void SVC_DirectConnect(int expectedreliablesequence)
info.expectedreliablesequence = expectedreliablesequence;
#endif
#ifdef HUFFNETWORK
info.huffcrc = 0;
#endif
info.mtu = 0;
info.ftepext1 = 0;
info.ftepext2 = 0;
@ -3109,7 +3112,7 @@ void SVC_DirectConnect(int expectedreliablesequence)
Info_SetValueForKey(userinfo, "name", "UnnamedQ3", sizeof(userinfo));
#ifdef HUFFNETWORK
huffcrc = HUFFCRC_QUAKE3;
info.huffcrc = HUFFCRC_QUAKE3;
#endif
#endif
}

View File

@ -3040,7 +3040,6 @@ char *VKVID_GetRGBInfo (int *bytestride, int *truevidwidth, int *truevidheight
static void VK_PaintScreen(void)
{
int uimenu;
qboolean nohud;
qboolean noworld;
@ -3088,12 +3087,6 @@ static void VK_PaintScreen(void)
}
*/
#ifdef VM_UI
uimenu = UI_MenuState();
#else
uimenu = 0;
#endif
#ifdef TEXTEDITOR
if (editormodal)
{
@ -3112,16 +3105,6 @@ static void VK_PaintScreen(void)
return;
}
#endif
if (Media_ShowFilm())
{
M_Draw(0);
V_UpdatePalette (false);
R2D_BrightenScreen();
#if defined(_WIN32) && defined(GLQUAKE)
Media_RecordFrame();
#endif
return;
}
//
// do 3D refresh drawing, and then update the screen
@ -3131,25 +3114,23 @@ static void VK_PaintScreen(void)
noworld = false;
nohud = false;
#ifdef VM_CG
if (CG_Refresh())
if (topmenu && topmenu->isopaque)
nohud = true;
#ifdef VM_CG
else if (CG_Refresh())
nohud = true;
else
#endif
#ifdef CSQC_DAT
if (CSQC_DrawView())
else if (CSQC_DrawView())
nohud = true;
else
#endif
else
{
if (uimenu != 1)
if (r_worldentity.model && cls.state == ca_active)
V_RenderView (nohud);
else
{
if (r_worldentity.model && cls.state == ca_active)
V_RenderView (nohud);
else
{
noworld = true;
}
noworld = true;
}
}
@ -3175,7 +3156,7 @@ static void VK_PaintScreen(void)
nohud = true;
}
SCR_DrawTwoDimensional(uimenu, nohud);
SCR_DrawTwoDimensional(nohud);
V_UpdatePalette (false);
R2D_BrightenScreen();

View File

@ -91,39 +91,16 @@ PLUG_LDFLAGS:=-L../engine/libs-$(ARCH) $(PLUG_LDFLAGS)
PLUG_CFLAGS:=-I../engine/libs-$(ARCH) $(PLUG_CFLAGS)
PLUG_CXXFLAGS:=-I../engine/libs-$(ARCH) $(PLUG_CXXFLAGS)
all: ezscript qi hud irc
#legacy build rule, now equivelent to all
native: all
clean: ezscript-clean qi-clean hud-clean irc-clean
.PHONY: all ezscript hud irc native distclean clean
.PHONY: all native distclean clean
help:
@-echo make a subdirectory
ezscript:
$(MAKE) -C ezscript
ezscript-clean:
$(MAKE) clean -C ezscript
hud:
$(MAKE) -C hud
hud-clean:
$(MAKE) clean -C hud
qi:
$(MAKE) -C qi
qi-clean:
$(MAKE) clean -C qi
irc:
$(MAKE) -C irc
irc-clean:
$(MAKE) clean -C irc
#small script to download+install avformat for windows cross compiles.
#linux users are expected to have the library installed locally already. If your version is too old or missing, run the following command to install it (to /usr/local), then delete the gz and directory.
#wget http://ffmpeg.org/releases/ffmpeg-1.2.tar.gz && cd tar xvfz ffmpeg-1.2.tar.gz && cd ffmpeg-1.2/ && ./configure --disable-yasm --enable-shared && make && sudo make install
@ -161,7 +138,7 @@ else
endif
AVPLUG_OBJS= avplug/avaudio.c avplug/avencode.c avplug/avdecode.c plugin.c qvm_api.c
AVPLUG_OBJS= avplug/avaudio.c avplug/avencode.c avplug/avdecode.c plugin.c
ifeq ($(FTE_TARGET),win32)
FFMPEG_ZIP=$(OUT_DIR)/$(AV_VER)-x86.zip
#NATIVE_PLUGINS+=ffmpeg
@ -229,7 +206,7 @@ $(ODE_LIB): $(OUT_DIR)/../ode-$(ODE_VER).tar.gz
mkdir -p $(ODE_BASE) && cd $(ODE_BASE) && tar xvfz $<
cd $(ODE_BASE)ode-$(ODE_VER)/ && ./bootstrap && ./configure --enable-double-precision --disable-demos --without-x --with-pic CC="$(CC) $(PLUG_CXXFLAGS)" CXX="$(CC) $(PLUG_CXXFLAGS)" --host=`$(CC) -dumpmachine` && make
ODE_FILES=../engine/common/com_phys_ode.c ../engine/common/mathlib.c plugin.c qvm_api.c $(ODE_LIB)
ODE_FILES=../engine/common/com_phys_ode.c ../engine/common/mathlib.c plugin.c $(ODE_LIB)
$(PLUG_PREFIX)ode$(PLUG_NATIVE_EXT): $(ODE_FILES)
$(CC) -flto -s $(BASE_CFLAGS) $(CFLAGS) -Os -DFTEPLUGIN -DODE_STATIC -o $@ -shared $(PLUG_CFLAGS) -I$(ODE_BASE)ode-$(ODE_VER)/include $(ODE_FILES) $(PLUG_DEFFILE) $(PLUG_LDFLAGS) -static-libgcc `$(CC) -print-file-name=libstdc++.a` -lpthread
#NATIVE_PLUGINS+=ode
@ -255,22 +232,22 @@ $(BULLET_LIB): $(OUT_DIR)/../bullet3-$(BULLET_VER).tar.gz
#./configure --enable-double-precision --disable-demos --without-x CXX="$(CC)" CFLAGS="$(PLUG_CFLAGS)" CXXFLAGS="$(PLUG_CXXFLAGS)" --host=`$(CC) -dumpmachine` && make
$(PLUG_PREFIX)bullet$(PLUG_NATIVE_EXT): bullet/bulletplug.cpp plugin.c qvm_api.c $(BULLET_LIBS)
$(PLUG_PREFIX)bullet$(PLUG_NATIVE_EXT): bullet/bulletplug.cpp plugin.c $(BULLET_LIBS)
$(CXX) $(BASE_CFLAGS) $(CFLAGS) -DFTEPLUGIN -o $@ -shared $(PLUG_CFLAGS) $^ $(PLUG_DEFFILE) $(PLUG_LDFLAGS) $(BULLET_CFLAGS)
#NATIVE_PLUGINS+=bullet
-include Makefile.private
$(PLUG_PREFIX)mpq$(PLUG_NATIVE_EXT): mpq/fs_mpq.c mpq/blast.c plugin.c qvm_api.c
$(PLUG_PREFIX)mpq$(PLUG_NATIVE_EXT): mpq/fs_mpq.c mpq/blast.c plugin.c
$(CC) $(BASE_CFLAGS) $(CFLAGS) -DFTEPLUGIN -o $@ -shared $(PLUG_CFLAGS) -Impq $^ $(PLUG_DEFFILE) $(PLUG_LDFLAGS_ZLIB) $(PLUG_LDFLAGS)
NATIVE_PLUGINS+=mpq
$(PLUG_PREFIX)xmpp$(PLUG_NATIVE_EXT): jabber/jabberclient.c jabber/jingle.c jabber/sift.c jabber/xml.c plugin.c qvm_api.c ../engine/common/sha1.c emailnot/md5.c
$(PLUG_PREFIX)xmpp$(PLUG_NATIVE_EXT): jabber/jabberclient.c jabber/jingle.c jabber/sift.c jabber/xml.c plugin.c ../engine/common/sha1.c emailnot/md5.c
$(CC) $(BASE_CFLAGS) $(CFLAGS) -DFTEPLUGIN -o $@ -shared $(PLUG_CFLAGS) -Ijabber $^ $(PLUG_DEFFILE) $(PLUG_LDFLAGS) $(LIBRESOLV)
NATIVE_PLUGINS+=xmpp
$(PLUG_PREFIX)qi$(PLUG_NATIVE_EXT): qi/qi.c jabber/xml.c plugin.c qvm_api.c
$(PLUG_PREFIX)qi$(PLUG_NATIVE_EXT): qi/qi.c jabber/xml.c plugin.c
$(CC) $(BASE_CFLAGS) $(CFLAGS) -DFTEPLUGIN -o $@ -shared $(PLUG_CFLAGS) -Ijabber $^ $(PLUG_DEFFILE) $(PLUG_LDFLAGS)
NATIVE_PLUGINS+=qi
@ -308,7 +285,7 @@ cef/$(CEF_NAME)/rel.zip: cef/$(CEF_NAME)/include/cef_version.h
$(OUT_DIR)/cef_$(CEF_VER).zip: cef/$(CEF_NAME)/rel.zip
cp cef/$(CEF_NAME)/rel.zip $@
CEF_SOURCES=cef/cef.c plugin.c qvm_api.c
CEF_SOURCES=cef/cef.c plugin.c
$(PLUG_PREFIX)cef$(PLUG_NATIVE_EXT): $(CEF_SOURCES) $(OUT_DIR)/cef_$(CEF_VER).zip cef/$(CEF_NAME)/include/cef_version.h
$(CC) $(BASE_CFLAGS) $(CFLAGS) -DFTEPLUGIN -o $(PLUG_PREFIX)cef$(PLUG_NATIVE_EXT) -shared $(PLUG_CFLAGS) -Icef/$(CEF_NAME) $(CEF_SOURCES) $(PLUG_DEFFILE) $(PLUG_LDFLAGS) -Wl,-rpath,. $(PLUG_LDFLAGS_DL)
#NATIVE_PLUGINS+=cef
@ -318,18 +295,17 @@ $(PLUG_PREFIX)cef$(PLUG_NATIVE_EXT):
echo cef plugin not supported on this arch
endif
#irc plugin can still be built as a qvm.
$(PLUG_PREFIX)irc$(PLUG_NATIVE_EXT): irc/ircclient.c plugin.c qvm_api.c
$(PLUG_PREFIX)irc$(PLUG_NATIVE_EXT): irc/ircclient.c plugin.c
$(CC) $(BASE_CFLAGS) $(CFLAGS) -DFTEPLUGIN -o $@ -shared $(PLUG_CFLAGS) -Iirc $^ $(PLUG_DEFFILE) $(PLUG_LDFLAGS)
NATIVE_PLUGINS+=irc
#for compat with ezquake
$(PLUG_PREFIX)ezhud$(PLUG_NATIVE_EXT): ezhud/ezquakeisms.c ezhud/hud.c ezhud/hud_common.c ezhud/hud_editor.c plugin.c qvm_api.c
$(PLUG_PREFIX)ezhud$(PLUG_NATIVE_EXT): ezhud/ezquakeisms.c ezhud/hud.c ezhud/hud_common.c ezhud/hud_editor.c plugin.c
$(CC) $(BASE_CFLAGS) $(CFLAGS) -DFTEPLUGIN -o $@ -shared $(PLUG_CFLAGS) -Iezhud $^ $(PLUG_DEFFILE) $(PLUG_LDFLAGS)
NATIVE_PLUGINS+=ezhud
$(PLUG_PREFIX)models$(PLUG_NATIVE_EXT): models/gltf.c models/models.c plugin.c qvm_api.c
$(PLUG_PREFIX)models$(PLUG_NATIVE_EXT): models/gltf.c models/models.c plugin.c
$(CC) $(BASE_CFLAGS) $(CFLAGS) -DFTEPLUGIN -o $@ -shared $(PLUG_CFLAGS) -Imodels $^ $(PLUG_DEFFILE) $(PLUG_LDFLAGS)
#NATIVE_PLUGINS+=models
native: $(foreach FOO,$(NATIVE_PLUGINS), $(PLUG_PREFIX)$(FOO)$(PLUG_NATIVE_EXT))
all: $(foreach FOO,$(NATIVE_PLUGINS), $(PLUG_PREFIX)$(FOO)$(PLUG_NATIVE_EXT))

View File

@ -4,6 +4,7 @@
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
static size_t activedecoders;
static cvar_t *ffmpeg_audiodecoder, *pdeveloper;
#define HAVE_DECOUPLED_API (LIBAVCODEC_VERSION_MAJOR>57 || (LIBAVCODEC_VERSION_MAJOR==57&&LIBAVCODEC_VERSION_MINOR>=36))
@ -56,6 +57,8 @@ static void S_AV_Purge(sfx_t *s)
//file storage will be cleared here too
free(ctx);
if (s->decoder.ended)
activedecoders--;
memset(&s->decoder, 0, sizeof(s->decoder));
}
static void S_AV_ReadFrame(struct avaudioctx *ctx)
@ -329,15 +332,18 @@ static qboolean QDECL S_LoadAVSound (sfx_t *s, qbyte *data, size_t datalen, int
if (!ffmpeg_audiodecoder)
return false;
if (!ffmpeg_audiodecoder->value /* && *ffmpeg_audiodecoder.string */)
if (!ffmpeg_audiodecoder->ival /* && *ffmpeg_audiodecoder.string */)
return false;
if (!data || !datalen)
return false;
//ignore it if it looks like a wav file. that means we don't need to figure out how to calculate loopstart.
//FIXME: this also blocks playing the audio from avi files too!
if (datalen >= 4 && !strncmp(data, "RIFF", 4))
return false; //ignore it if it looks like a wav file. that means we don't need to figure out how to calculate loopstart.
return false;
// if (strcasecmp(COM_GetFileExtension(s->name), "wav")) //don't do .wav - I've no idea how to read the loopstart tag with ffmpeg.
// return false;
@ -402,20 +408,28 @@ static qboolean QDECL S_LoadAVSound (sfx_t *s, qbyte *data, size_t datalen, int
s->decoder.purge = S_AV_Purge;
s->decoder.decodedata = S_AV_Locate;
s->decoder.querydata = S_AV_Query;
activedecoders++;
return true;
}
}
S_AV_Purge(s);
return false;
}
qboolean AVAudio_MayUnload(void)
{
return activedecoders==0;
}
static qboolean AVAudio_Init(void)
{
if (!pPlug_ExportNative("S_LoadSound", S_LoadAVSound))
if (!plugfuncs->ExportFunction("MayUnload", AVAudio_MayUnload) ||
!plugfuncs->ExportFunction("S_LoadSound", S_LoadAVSound))
{
Con_Printf("avplug: Engine doesn't support audio decoder plugins\n");
Con_Printf("ffmpeg: Engine doesn't support audio decoder plugins\n");
return false;
}
ffmpeg_audiodecoder = pCvar_GetNVFDG("ffmpeg_audiodecoder_wip", "0", 0, "Enables the use of ffmpeg's decoder for pure audio files.", "ffmpeg");
ffmpeg_audiodecoder = cvarfuncs->GetNVFDG("ffmpeg_audiodecoder_wip", "1", 0, "Enables the use of ffmpeg's decoder for pure audio files.", "ffmpeg");
if (!ffmpeg_audiodecoder->ival)
Con_Printf("ffmpeg: audio decoding disabled, use \"set %s 1\" to enable ffmpeg audio decoding\n", ffmpeg_audiodecoder->name);
return true;
}
@ -427,14 +441,14 @@ static void AVLogCallback(void *avcl, int level, const char *fmt, va_list vl)
char string[1024];
Q_vsnprintf (string, sizeof(string), fmt, vl);
if (pdeveloper && pdeveloper->ival)
pCon_Print(string);
Con_Printf("%s", string);
#endif
}
//get the encoder/decoders to register themselves with the engine, then make sure avformat/avcodec have registered all they have to give.
qboolean AVEnc_Init(void);
qboolean AVDec_Init(void);
qintptr_t Plug_Init(qintptr_t *args)
qboolean Plug_Init(void)
{
qboolean okay = false;
@ -448,7 +462,7 @@ qintptr_t Plug_Init(qintptr_t *args)
avcodec_register_all();
#endif
pdeveloper = pCvar_GetNVFDG("developer", "0", 0, "Developer spam.", "ffmpeg");
pdeveloper = cvarfuncs->GetNVFDG("developer", "0", 0, "Developer spam.", "ffmpeg");
av_log_set_level(AV_LOG_WARNING);
av_log_set_callback(AVLogCallback);
}

View File

@ -1,6 +1,9 @@
#include "../plugin.h"
#include "../engine.h"
static plugfsfuncs_t *filefuncs;
static plugaudiofuncs_t *audiofuncs;
//#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
@ -24,12 +27,6 @@
#define DECODERNAME "ffmpeg"
#define PASSFLOAT(f) *(int*)&(f)
#define ARGNAMES ,sourceid, data, speed, samples, channels, width, PASSFLOAT(volume)
BUILTIN(void, S_RawAudio, (int sourceid, void *data, int speed, int samples, int channels, int width, float volume))
#undef ARGNAMES
/*should probably try threading this, though I suppose it should be the engine doing that.*/
/*timing is based upon the start time. this means overflow issues with rtsp etc*/
@ -37,7 +34,7 @@ struct decctx
{
unsigned int width, height;
qhandle_t file;
vfsfile_t *file;
int64_t fileofs;
int64_t filelen;
AVFormatContext *pFormatCtx;
@ -92,7 +89,7 @@ static int AVIO_Read(void *opaque, uint8_t *buf, int buf_size)
{
struct decctx *ctx = opaque;
int ammount;
ammount = pFS_Read(ctx->file, buf, buf_size);
ammount = VFS_READ(ctx->file, buf, buf_size);
if (ammount > 0)
ctx->fileofs += ammount;
return ammount;
@ -117,7 +114,7 @@ static int64_t AVIO_Seek(void *opaque, int64_t offset, int whence)
case AVSEEK_SIZE:
return ctx->filelen;
}
pFS_Seek(ctx->file, ctx->fileofs & 0xffffffff, ctx->fileofs>>32);
VFS_SEEK(ctx->file, ctx->fileofs);
return ctx->fileofs;
}
@ -139,8 +136,8 @@ static void AVDec_Destroy(void *vctx)
// Close the video file
avformat_close_input(&ctx->pFormatCtx);
if (ctx->file >= 0)
pFS_Close(ctx->file);
if (ctx->file)
VFS_CLOSE(ctx->file);
free(ctx);
}
@ -154,17 +151,17 @@ static void *AVDec_Create(const char *medianame)
qboolean useioctx = false;
/*always respond to av: media prefixes*/
if (!strncmp(medianame, "av:", 3))
if (!strncmp(medianame, "av:", 3) || !strncmp(medianame, "ff:", 3))
{
medianame = medianame + 3;
useioctx = true;
}
else if (!strncmp(medianame, "avs:", 4))
else if (!strncmp(medianame, "avs:", 4) || !strncmp(medianame, "ffs:", 4))
{
medianame = medianame + 4;
//let avformat do its own avio context stuff
}
else if (strchr(medianame, ':')) //block other types of url.
else if (strchr(medianame, ':')) //block other types of url/prefix.
return NULL;
else //if (!strcasecmp(extension, ".roq") || !strcasecmp(extension, ".roq"))
return NULL; //roq+cin should be played back via the engine instead.
@ -173,7 +170,7 @@ static void *AVDec_Create(const char *medianame)
memset(ctx, 0, sizeof(*ctx));
ctx->lasttime = -1;
ctx->file = -1;
ctx->file = NULL;
if (useioctx)
{
// Create internal Buffer for FFmpeg:
@ -181,14 +178,15 @@ static void *AVDec_Create(const char *medianame)
char *pBuffer = av_malloc(iBufSize);
AVIOContext *ioctx;
ctx->filelen = pFS_Open(medianame, &ctx->file, 1);
if (ctx->filelen < 0)
ctx->file = filefuncs->OpenVFS(medianame, "rb", FS_GAME);
if (!ctx->file)
{
Con_Printf("Unable to open %s\n", medianame);
free(ctx);
av_free(pBuffer);
return NULL;
}
ctx->filelen = VFS_GETLEN(ctx->file);
ioctx = avio_alloc_context(pBuffer, iBufSize, 0, ctx, AVIO_Read, 0, AVIO_Seek);
ctx->pFormatCtx = avformat_alloc_context();
@ -317,6 +315,8 @@ static qboolean VARGS AVDec_DisplayFrame(void *vctx, qboolean nosound, qboolean
int64_t curtime;
curtime = (mediatime * ctx->denum) / ctx->num;
nosound |= !audiofuncs;
while (1)
{
@ -374,18 +374,33 @@ static qboolean VARGS AVDec_DisplayFrame(void *vctx, qboolean nosound, qboolean
break;
case AV_SAMPLE_FMT_FLTP:
//FIXME: support float audio internally.
if (channels == 2)
{
#ifdef MIXER_F32
float *l = (float*)ctx->pAFrame->data[0], *r = (float*)ctx->pAFrame->data[1], *t;
unsigned int i;
unsigned int frames = ctx->pAFrame->nb_samples;
width = sizeof(*t);
auddatasize = frames*width*channels;
t = malloc(auddatasize);
for (i = 0; i < frames; i++)
{
t[2*i+0] = l[i];
t[2*i+1] = r[i];
}
audiofuncs->RawAudio(-1, t, ctx->pACodecCtx->sample_rate, auddatasize/(channels*width), channels, width, 1);
free(t);
continue;
#else
//note that we can only reformat in place because we are NOT outputting floats.
float *in[2] = {(float*)ctx->pAFrame->data[0],(float*)ctx->pAFrame->data[1]};
signed short *out = (void*)auddata;
int v;
unsigned int i, c;
unsigned int frames = ctx->pAFrame->nb_samples;
if (channels > 2)
channels = 2;
for (i = 0; i < frames; i++)
{
for (c = 0; c < channels; c++)
for (c = 0; c < 2; c++)
{
v = (short)(in[c][i]*32767);
if (v < -32767)
@ -397,10 +412,17 @@ static qboolean VARGS AVDec_DisplayFrame(void *vctx, qboolean nosound, qboolean
}
width = sizeof(*out);
auddatasize = frames*width*channels;
break;
#endif
}
break;
auddatasize /= channels;
channels = 1;
//fallthrough, using just the first channel as mono
case AV_SAMPLE_FMT_FLT:
//FIXME: support float audio internally.
#ifdef MIXER_F32
width = 4;
#else
{
float *in = (void*)auddata;
signed short *out = (void*)auddata;
@ -418,8 +440,8 @@ static qboolean VARGS AVDec_DisplayFrame(void *vctx, qboolean nosound, qboolean
auddatasize/=2;
width = 2;
}
#endif
break;
case AV_SAMPLE_FMT_DBLP:
auddatasize /= channels;
channels = 1;
@ -443,7 +465,7 @@ static qboolean VARGS AVDec_DisplayFrame(void *vctx, qboolean nosound, qboolean
}
break;
}
pS_RawAudio(-1, auddata, ctx->pACodecCtx->sample_rate, auddatasize/(channels*width), channels, width, 1);
audiofuncs->RawAudio(-1, auddata, ctx->pACodecCtx->sample_rate, auddatasize/(channels*width), channels, width, 1);
}
}
@ -561,7 +583,7 @@ static qboolean VARGS AVDec_DisplayFrame(void *vctx, qboolean nosound, qboolean
}
break;
}
pS_RawAudio(-1, auddata, ctx->pACodecCtx->sample_rate, auddatasize/(channels*width), channels, width, 1);
audiofuncs->RawAudio(-1, auddata, ctx->pACodecCtx->sample_rate, auddatasize/(channels*width), channels, width, 1);
}
}
packet.data = odata;
@ -608,7 +630,7 @@ static void AVDec_Rewind(void *vctx)
/*
//avcodec has no way to shut down properly.
static qintptr_t AVDec_Shutdown(qintptr_t *args)
static qboolean AVDec_Shutdown(void)
{
return 0;
}
@ -632,14 +654,14 @@ static media_decoder_funcs_t decoderfuncs =
qboolean AVDec_Init(void)
{
if (!pPlug_ExportNative("Media_VideoDecoder", &decoderfuncs))
filefuncs = plugfuncs->GetEngineInterface(plugfsfuncs_name, sizeof(*filefuncs));
audiofuncs = plugfuncs->GetEngineInterface(plugaudiofuncs_name, sizeof(*audiofuncs));
if (!filefuncs ||
!plugfuncs->ExportInterface("Media_VideoDecoder", &decoderfuncs, sizeof(decoderfuncs)))
{
Con_Printf(DECODERNAME": Engine doesn't support media decoder plugins\n");
return false;
}
CHECKBUILTIN(S_RawAudio);
CHECKBUILTIN(FS_Seek);
return true;
}

View File

@ -27,6 +27,8 @@
#define AV_ERROR_MAX_STRING_SIZE 64
#endif
static plugfsfuncs_t *filefuncs;
/*
Most of the logic in here came from here:
http://svn.gnumonks.org/tags/21c3-video/upstream/ffmpeg-0.4.9-pre1/output_example.c
@ -669,7 +671,7 @@ static void *AVEnc_Begin (char *streamname, int videorate, int width, int height
if (!(fmt->flags & AVFMT_NOFILE))
{
//okay, this is annoying, but I'm too lazy to figure out the issue I was having with avio stuff.
if (!pFS_NativePath(streamname, FS_GAMEONLY, ctx->abspath, sizeof(ctx->abspath)))
if (!filefuncs->NativePath(streamname, FS_GAMEONLY, ctx->abspath, sizeof(ctx->abspath)))
{
Con_Printf("Couldn't find system path for '%s'\n", streamname);
AVEnc_End(ctx);
@ -747,10 +749,10 @@ static media_encoder_funcs_t encoderfuncs =
};
qintptr_t AVEnc_ExecuteCommand(qintptr_t *args)
qboolean AVEnc_ExecuteCommand(qboolean isinsecure)
{
char cmd[256];
pCmd_Argv(0, cmd, sizeof(cmd));
cmdfuncs->Argv(0, cmd, sizeof(cmd));
/*
if (!strcmp(cmd, ENCODERNAME"_configure"))
{
@ -770,38 +772,38 @@ menutext 0 24 "Cancel"
*/
if (!strcmp(cmd, ENCODERNAME"_nvidia"))
{
pCvar_SetString("capturedriver", ENCODERNAME); //be sure to use our encoder
pCvar_SetString(ENCODERNAME"_videocodec", "h264_nvenc");
pCvar_SetString("capturerate", "60"); //we should be able to cope with it, and the default of 30 sucks
pCvar_SetString("capturedemowidth", "1920"); //force a specific size, some codecs need multiples of 16 or whatever.
pCvar_SetString("capturedemoheight", "1080"); //so this avoids issues with various video codecs.
cvarfuncs->SetString("capturedriver", ENCODERNAME); //be sure to use our encoder
cvarfuncs->SetString(ENCODERNAME"_videocodec", "h264_nvenc");
cvarfuncs->SetString("capturerate", "60"); //we should be able to cope with it, and the default of 30 sucks
cvarfuncs->SetString("capturedemowidth", "1920"); //force a specific size, some codecs need multiples of 16 or whatever.
cvarfuncs->SetString("capturedemoheight", "1080"); //so this avoids issues with various video codecs.
pCvar_SetString("capturesound", "1");
pCvar_SetString("capturesoundchannels", "2");
pCvar_SetString("capturesoundbits", "16");
cvarfuncs->SetString("capturesound", "1");
cvarfuncs->SetString("capturesoundchannels", "2");
cvarfuncs->SetString("capturesoundbits", "16");
Con_Printf(ENCODERNAME": now configured for nvidia's hardware encoder\n");
Con_Printf(ENCODERNAME": use ^[/capture foo.mp4^] or ^[/capturedemo foo.mvd foo.mkv^] commands to begin capturing\n");
}
if (!strcmp(cmd, ENCODERNAME"_defaults"))
{ //most formats will end up using the x264 encoder or something
pCvar_SetString(ENCODERNAME"_format_force", "");
pCvar_SetString(ENCODERNAME"_videocodec", "");
pCvar_SetString(ENCODERNAME"_videobitrate", "");
pCvar_SetString(ENCODERNAME"_videoforcewidth", "");
pCvar_SetString(ENCODERNAME"_videoforceheight", "");
pCvar_SetString(ENCODERNAME"_videopreset", "veryfast");
pCvar_SetString(ENCODERNAME"_video_crf", "");
pCvar_SetString(ENCODERNAME"_audiocodec", "");
pCvar_SetString(ENCODERNAME"_audiobitrate", "");
cvarfuncs->SetString(ENCODERNAME"_format_force", "");
cvarfuncs->SetString(ENCODERNAME"_videocodec", "");
cvarfuncs->SetString(ENCODERNAME"_videobitrate", "");
cvarfuncs->SetString(ENCODERNAME"_videoforcewidth", "");
cvarfuncs->SetString(ENCODERNAME"_videoforceheight", "");
cvarfuncs->SetString(ENCODERNAME"_videopreset", "veryfast");
cvarfuncs->SetString(ENCODERNAME"_video_crf", "");
cvarfuncs->SetString(ENCODERNAME"_audiocodec", "");
cvarfuncs->SetString(ENCODERNAME"_audiobitrate", "");
pCvar_SetString("capturedriver", ENCODERNAME);
pCvar_SetString("capturerate", "30");
pCvar_SetString("capturedemowidth", "0");
pCvar_SetString("capturedemoheight", "0");
pCvar_SetString("capturesound", "1");
pCvar_SetString("capturesoundchannels", "2");
pCvar_SetString("capturesoundbits", "16");
cvarfuncs->SetString("capturedriver", ENCODERNAME);
cvarfuncs->SetString("capturerate", "30");
cvarfuncs->SetString("capturedemowidth", "0");
cvarfuncs->SetString("capturedemoheight", "0");
cvarfuncs->SetString("capturesound", "1");
cvarfuncs->SetString("capturesoundchannels", "2");
cvarfuncs->SetString("capturesoundbits", "16");
Con_Printf(ENCODERNAME": capture settings reset to "ENCODERNAME" defaults\n");
Con_Printf(ENCODERNAME": Note that some codecs may have restrictions on video sizes\n");
@ -812,32 +814,27 @@ menutext 0 24 "Cancel"
qboolean AVEnc_Init(void)
{
CHECKBUILTIN(FS_NativePath);
if (!BUILTINISVALID(FS_NativePath))
{
Con_Printf(ENCODERNAME": Engine too old\n");
return false;
}
if (!pPlug_ExportNative("Media_VideoEncoder", &encoderfuncs))
filefuncs = plugfuncs->GetEngineInterface(plugfsfuncs_name, sizeof(*filefuncs));
if (!cvarfuncs || !cmdfuncs || !filefuncs || !plugfuncs->ExportInterface("Media_VideoEncoder", &encoderfuncs, sizeof(encoderfuncs)))
{
Con_Printf(ENCODERNAME": Engine doesn't support media encoder plugins\n");
return false;
}
ffmpeg_format_force = pCvar_GetNVFDG(ENCODERNAME"_format_force", "", 0, "Forces the output container format. If blank, will guess based upon filename extension.", ENCODERNAME);
ffmpeg_videocodec = pCvar_GetNVFDG(ENCODERNAME"_videocodec", "", 0, "Forces which video encoder to use. If blank, guesses based upon container defaults.\nCommon names are libx264 (software), x264_nvenc (hardware accelerated)", ENCODERNAME);
ffmpeg_videobitrate = pCvar_GetNVFDG(ENCODERNAME"_videobitrate", "", 0, "Specifies the target video bitrate", ENCODERNAME);
ffmpeg_videoforcewidth = pCvar_GetNVFDG(ENCODERNAME"_videoforcewidth", "", 0, "Rescales the input video width. Best to leave blank in order to record the video at the native resolution.", ENCODERNAME);
ffmpeg_videoforceheight = pCvar_GetNVFDG(ENCODERNAME"_videoforceheight", "", 0, "Rescales the input video height. Best to leave blank in order to record the video at the native resolution.", ENCODERNAME);
ffmpeg_videopreset = pCvar_GetNVFDG(ENCODERNAME"_videopreset", "veryfast", 0, "Specifies which codec preset to use, for codecs that support such presets.", ENCODERNAME);
ffmpeg_video_crf = pCvar_GetNVFDG(ENCODERNAME"_video_crf", "", 0, "Specifies the 'Constant Rate Factor' codec setting.\nA value of 0 is 'lossless', a value of 51 is 'worst quality posible', a value of 23 is default.", ENCODERNAME);
ffmpeg_audiocodec = pCvar_GetNVFDG(ENCODERNAME"_audiocodec", "", 0, "Forces which audio encoder to use. If blank, guesses based upon container defaults.", ENCODERNAME);
ffmpeg_audiobitrate = pCvar_GetNVFDG(ENCODERNAME"_audiobitrate", "", 0, "Specifies the target audio bitrate", ENCODERNAME);
ffmpeg_format_force = cvarfuncs->GetNVFDG(ENCODERNAME"_format_force", "", 0, "Forces the output container format. If blank, will guess based upon filename extension.", ENCODERNAME);
ffmpeg_videocodec = cvarfuncs->GetNVFDG(ENCODERNAME"_videocodec", "", 0, "Forces which video encoder to use. If blank, guesses based upon container defaults.\nCommon names are libx264 (software), x264_nvenc (hardware accelerated)", ENCODERNAME);
ffmpeg_videobitrate = cvarfuncs->GetNVFDG(ENCODERNAME"_videobitrate", "", 0, "Specifies the target video bitrate", ENCODERNAME);
ffmpeg_videoforcewidth = cvarfuncs->GetNVFDG(ENCODERNAME"_videoforcewidth", "", 0, "Rescales the input video width. Best to leave blank in order to record the video at the native resolution.", ENCODERNAME);
ffmpeg_videoforceheight = cvarfuncs->GetNVFDG(ENCODERNAME"_videoforceheight", "", 0, "Rescales the input video height. Best to leave blank in order to record the video at the native resolution.", ENCODERNAME);
ffmpeg_videopreset = cvarfuncs->GetNVFDG(ENCODERNAME"_videopreset", "veryfast", 0, "Specifies which codec preset to use, for codecs that support such presets.", ENCODERNAME);
ffmpeg_video_crf = cvarfuncs->GetNVFDG(ENCODERNAME"_video_crf", "", 0, "Specifies the 'Constant Rate Factor' codec setting.\nA value of 0 is 'lossless', a value of 51 is 'worst quality posible', a value of 23 is default.", ENCODERNAME);
ffmpeg_audiocodec = cvarfuncs->GetNVFDG(ENCODERNAME"_audiocodec", "", 0, "Forces which audio encoder to use. If blank, guesses based upon container defaults.", ENCODERNAME);
ffmpeg_audiobitrate = cvarfuncs->GetNVFDG(ENCODERNAME"_audiobitrate", "", 0, "Specifies the target audio bitrate", ENCODERNAME);
if (Plug_Export("ExecuteCommand", AVEnc_ExecuteCommand))
if (plugfuncs->ExportFunction("ExecuteCommand", AVEnc_ExecuteCommand))
{
// pCmd_AddCommand(ENCODERNAME"_configure");
pCmd_AddCommand(ENCODERNAME"_nvidia");
// cmdfuncs->AddCommand(ENCODERNAME"_configure");
cmdfuncs->AddCommand(ENCODERNAME"_nvidia");
}
return true;

View File

@ -84,14 +84,10 @@ static cvar_t *pr_meshpitch;
void World_Bullet_Init(void)
{
physics_bullet_enable = pCvar_GetNVFDG("physics_bullet_enable", "1", 0, "", "Bullet");
physics_bullet_maxiterationsperframe = pCvar_GetNVFDG("physics_bullet_maxiterationsperframe", "10", 0, "FIXME: should be 1 when CCD is working properly.", "Bullet");
physics_bullet_framerate = pCvar_GetNVFDG("physics_bullet_framerate", "60", 0, "Bullet physics run at a fixed framerate in order to preserve numerical stability (interpolation is used to smooth out the result). Higher framerates are of course more demanding.", "Bullet");
pr_meshpitch = pCvar_GetNVFDG("r_meshpitch", "-1", 0, "", "Bullet");
}
void World_Bullet_Shutdown(void)
{
physics_bullet_enable = cvarfuncs->GetNVFDG("physics_bullet_enable", "1", 0, "", "Bullet");
physics_bullet_maxiterationsperframe = cvarfuncs->GetNVFDG("physics_bullet_maxiterationsperframe", "10", 0, "FIXME: should be 1 when CCD is working properly.", "Bullet");
physics_bullet_framerate = cvarfuncs->GetNVFDG("physics_bullet_framerate", "60", 0, "Bullet physics run at a fixed framerate in order to preserve numerical stability (interpolation is used to smooth out the result). Higher framerates are of course more demanding.", "Bullet");
pr_meshpitch = cvarfuncs->GetNVFDG("r_meshpitch", "-1", 0, "", "Bullet");
}
typedef struct bulletcontext_s
@ -1786,11 +1782,10 @@ static void QDECL World_Bullet_Start(world_t *world)
*/
}
static qintptr_t QDECL World_Bullet_Shutdown(qintptr_t *args)
static void QDECL World_Bullet_Shutdown(void)
{
if (rbefuncs)
rbefuncs->UnregisterPhysicsEngine("Bullet");
return 0;
}
static bool World_Bullet_DoInit(void)
@ -1810,23 +1805,14 @@ static bool World_Bullet_DoInit(void)
return false;
}
#define ARGNAMES ,version
static BUILTINR(rbeplugfuncs_t*, RBE_GetPluginFuncs, (int version));
#undef ARGNAMES
extern "C" qintptr_t Plug_Init(qintptr_t *args)
extern "C" qboolean Plug_Init(void)
{
CHECKBUILTIN(RBE_GetPluginFuncs);
rbefuncs = (rbeplugfuncs_t*)plugfuncs->GetEngineInterface("RBE", sizeof(*rbefuncs));
if (rbefuncs && rbefuncs->version < RBEPLUGFUNCS_VERSION)
rbefuncs = nullptr;
if (BUILTINISVALID(RBE_GetPluginFuncs))
{
rbefuncs = pRBE_GetPluginFuncs(sizeof(rbeplugfuncs_t));
if (rbefuncs && rbefuncs->version < RBEPLUGFUNCS_VERSION)
rbefuncs = NULL;
}
Plug_Export("Shutdown", World_Bullet_Shutdown);
return World_Bullet_DoInit();
plugfuncs->ExportFunction("Shutdown", (funcptr_t)World_Bullet_Shutdown);
return World_Bullet_DoInit()?qtrue:qfalse;
}

View File

@ -1,6 +0,0 @@
LCC_FLAGS=-DQ3_VM -S -Wf-target=bytecode -Wf-g
qvm:
lcc $(LCC_FLAGS) imapnoti.c; lcc $(LCC_FLAGS) md5.c; lcc $(LCC_FLAGS) pop3noti.c; lcc $(LCC_FLAGS) ../memory.c; lcc $(LCC_FLAGS) ../plugin.c; lcc $(LCC_FLAGS) ../qvm_api.c; q3asm -f emailnot
clean:
rm -rf $(OBJECTS) $(OUTFILE) *.qvm *.asm

View File

@ -1,29 +0,0 @@
@echo off
call ..\paths.bat
del vm\*.asm
rmdir vm
mkdir vm
cd vm
lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g ../imapnoti.c
if errorlevel 1 goto error
lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g ../md5.c
if errorlevel 1 goto error
lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g ../pop3noti.c
if errorlevel 1 goto error
lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g ../../memory.c
if errorlevel 1 goto error
lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g ../../plugin.c
if errorlevel 1 goto error
lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g ../../qvm_api.c
if errorlevel 1 goto error
q3asm -f ../emailnot
:error
cd ..
pause
goto endbat
:endbat

View File

@ -3,6 +3,11 @@
#include "hud.h"
#include "hud_editor.h"
plug2dfuncs_t *drawfuncs;
plugclientfuncs_t *clientfuncs;
plugfsfuncs_t *filefuncs;
pluginputfuncs_t *inputfuncs;
int sb_lines;
float scr_con_current;
int sb_showteamscores;
@ -12,12 +17,18 @@ float alphamul;
cvar_t *scr_newHud;
static void QDECL EZHud_UpdateVideo(int width, int height)
{
vid.width = width;
vid.height = height;
}
char *Cmd_Argv(int arg)
{
static char buf[4][128];
if (arg >= 4)
return "";
pCmd_Argv(arg, buf[arg], sizeof(buf[arg]));
cmdfuncs->Argv(arg, buf[arg], sizeof(buf[arg]));
return buf[arg];
}
@ -29,15 +40,15 @@ void Draw_SetOverallAlpha(float a)
}
void Draw_AlphaFillRGB(float x, float y, float w, float h, qbyte r, qbyte g, qbyte b, qbyte a)
{
pDraw_Colour4f(r/255.0, g/255.0, b/255.0, a/255.0 * alphamul);
pDraw_Fill(x, y, w, h);
pDraw_Colour4f(1, 1, 1, 1);
drawfuncs->Colour4f(r/255.0, g/255.0, b/255.0, a/255.0 * alphamul);
drawfuncs->Fill(x, y, w, h);
drawfuncs->Colour4f(1, 1, 1, 1);
}
void Draw_Fill(float x, float y, float w, float h, qbyte pal)
{
pDraw_Colourpa(pal, alphamul);
pDraw_Fill(x, y, w, h);
pDraw_Colour4f(1, 1, 1, 1);
drawfuncs->Colourpa(pal, alphamul);
drawfuncs->Fill(x, y, w, h);
drawfuncs->Colour4f(1, 1, 1, 1);
}
const char *ColorNameToRGBString (const char *newval)
{
@ -62,10 +73,10 @@ void Draw_TextBox (int x, int y, int width, int lines)
{
}
char *TP_LocationName (vec3_t location)
char *TP_LocationName (const vec3_t location)
{
static char locname[256];
pGetLocationName(location, locname, sizeof(locname));
clientfuncs->GetLocationName(location, locname, sizeof(locname));
return locname;
}
@ -74,75 +85,75 @@ void Draw_SPic(float x, float y, mpic_t *pic, float scale)
{
qhandle_t image = (intptr_t)pic;
float w, h;
pDraw_ImageSize(image, &w, &h);
pDraw_Image(x, y, w*scale, h*scale, 0, 0, 1, 1, image);
drawfuncs->ImageSize(image, &w, &h);
drawfuncs->Image(x, y, w*scale, h*scale, 0, 0, 1, 1, image);
}
void Draw_SSubPic(float x, float y, mpic_t *pic, float s1, float t1, float s2, float t2, float scale)
{
qhandle_t image = (intptr_t)pic;
float w, h;
pDraw_ImageSize(image, &w, &h);
pDraw_Image(x, y, (s2-s1)*scale, (t2-t1)*scale, s1/w, t1/h, s2/w, t2/h, image);
drawfuncs->ImageSize(image, &w, &h);
drawfuncs->Image(x, y, (s2-s1)*scale, (t2-t1)*scale, s1/w, t1/h, s2/w, t2/h, image);
}
void Draw_EZString(float x, float y, char *str, float scale, qboolean red)
{
unsigned int flags = 0;
if (red)
flags |= 1;
pDraw_StringH(x, y, scale, flags, str);
drawfuncs->StringH(x, y, scale, flags, str);
}
#define Draw_STransPic Draw_SPic
void Draw_Character(float x, float y, unsigned int ch)
{
pDraw_Character(x, y, 0xe000|ch);
drawfuncs->Character(x, y, 0xe000|ch);
}
void Draw_SCharacter(float x, float y, unsigned int ch, float scale)
{
pDraw_CharacterH(x, y, 8*scale, 0, 0xe000|ch);
drawfuncs->CharacterH(x, y, 8*scale, 0, 0xe000|ch);
}
void SCR_DrawWadString(float x, float y, float scale, char *str)
{
pDraw_String(x, y, str); //FIXME
drawfuncs->String(x, y, str); //FIXME
}
void Draw_SAlphaSubPic2(float x, float y, mpic_t *pic, float s1, float t1, float s2, float t2, float sw, float sh, float alpha)
{
qhandle_t image = (intptr_t)pic;
float w, h;
pDraw_ImageSize(image, &w, &h);
pDraw_Colour4f(1, 1, 1, alpha * alphamul);
pDraw_Image(x, y, (s2-s1)*sw, (t2-t1)*sh, s1/w, t1/h, s2/w, t2/h, image);
pDraw_Colour4f(1, 1, 1, 1);
drawfuncs->ImageSize(image, &w, &h);
drawfuncs->Colour4f(1, 1, 1, alpha * alphamul);
drawfuncs->Image(x, y, (s2-s1)*sw, (t2-t1)*sh, s1/w, t1/h, s2/w, t2/h, image);
drawfuncs->Colour4f(1, 1, 1, 1);
}
void Draw_AlphaFill(float x, float y, float w, float h, unsigned int pal, float alpha)
{
if (pal >= 256)
pDraw_Colour4f(((pal>>16)&0xff)/255.0, ((pal>>8)&0xff)/255.0, ((pal>>0)&0xff)/255.0, alpha * alphamul);
drawfuncs->Colour4f(((pal>>16)&0xff)/255.0, ((pal>>8)&0xff)/255.0, ((pal>>0)&0xff)/255.0, alpha * alphamul);
else
pDraw_Colourpa(pal, alpha * alphamul);
pDraw_Fill(x, y, w, h);
pDraw_Colour4f(1, 1, 1, 1);
drawfuncs->Colourpa(pal, alpha * alphamul);
drawfuncs->Fill(x, y, w, h);
drawfuncs->Colour4f(1, 1, 1, 1);
}
void Draw_AlphaPic(float x, float y, mpic_t *pic, float alpha)
{
qhandle_t image = (intptr_t)pic;
float w, h;
pDraw_ImageSize(image, &w, &h);
pDraw_Colour4f(1, 1, 1, alpha * alphamul);
pDraw_Image(x, y, w, h, 0, 0, 1, 1, image);
pDraw_Colour4f(1, 1, 1, 1);
drawfuncs->ImageSize(image, &w, &h);
drawfuncs->Colour4f(1, 1, 1, alpha * alphamul);
drawfuncs->Image(x, y, w, h, 0, 0, 1, 1, image);
drawfuncs->Colour4f(1, 1, 1, 1);
}
void Draw_AlphaSubPic(float x, float y, mpic_t *pic, float s1, float t1, float s2, float t2, float alpha)
{
qhandle_t image = (intptr_t)pic;
float w, h;
pDraw_ImageSize(image, &w, &h);
pDraw_Colour4f(1, 1, 1, alpha * alphamul);
pDraw_Image(x, y, s2-s1, t2-t1, s1/w, t1/h, s2/w, t2/h, image);
pDraw_Colour4f(1, 1, 1, 1);
drawfuncs->ImageSize(image, &w, &h);
drawfuncs->Colour4f(1, 1, 1, alpha * alphamul);
drawfuncs->Image(x, y, s2-s1, t2-t1, s1/w, t1/h, s2/w, t2/h, image);
drawfuncs->Colour4f(1, 1, 1, 1);
}
void SCR_HUD_DrawBar(int direction, int value, float max_value, float *rgba, int x, int y, int width, int height)
{
@ -154,33 +165,33 @@ void SCR_HUD_DrawBar(int direction, int value, float max_value, float *rgba, int
else// left-right
amount = Q_rint(fabs((width * value) / max_value));
pDraw_Colour4f(rgba[0]/255.0, rgba[1]/255.0, rgba[2]/255.0, rgba[3]/255.0 * alphamul);
drawfuncs->Colour4f(rgba[0]/255.0, rgba[1]/255.0, rgba[2]/255.0, rgba[3]/255.0 * alphamul);
if(direction == 0)
// left->right
pDraw_Fill(x, y, amount, height);
drawfuncs->Fill(x, y, amount, height);
else if (direction == 1)
// right->left
pDraw_Fill(x + width - amount, y, amount, height);
drawfuncs->Fill(x + width - amount, y, amount, height);
else if (direction == 2)
// down -> up
pDraw_Fill(x, y + height - amount, width, amount);
drawfuncs->Fill(x, y + height - amount, width, amount);
else
// up -> down
pDraw_Fill(x, y, width, amount);
pDraw_Colour4f(1, 1, 1, 1);
drawfuncs->Fill(x, y, width, amount);
drawfuncs->Colour4f(1, 1, 1, 1);
}
void Draw_Polygon(int x, int y, vec3_t *vertices, int num_vertices, qbool fill, byte r, byte g, byte b, byte a)
{
pDraw_Colour4f(r/255.0, g/255.0, b/255.0, a/255.0 * alphamul);
// pDraw_Line(x1, y1, x2, y1);
pDraw_Colour4f(1, 1, 1, 1);
drawfuncs->Colour4f(r/255.0, g/255.0, b/255.0, a/255.0 * alphamul);
// drawfuncs->Line(x1, y1, x2, y1);
drawfuncs->Colour4f(1, 1, 1, 1);
}
void Draw_ColoredString3(float x, float y, const char *str, clrinfo_t *clr, int huh, int wut)
{
pDraw_Colour4f(clr->c[0]/255.0, clr->c[1]/255.0, clr->c[2]/255.0, clr->c[3]/255.0 * alphamul);
pDraw_String(x, y, str);
pDraw_Colour4f(1, 1, 1, 1);
drawfuncs->Colour4f(clr->c[0]/255.0, clr->c[1]/255.0, clr->c[2]/255.0, clr->c[3]/255.0 * alphamul);
drawfuncs->String(x, y, str);
drawfuncs->Colour4f(1, 1, 1, 1);
}
void UI_PrintTextBlock(void)
{
@ -191,29 +202,29 @@ void Draw_AlphaRectangleRGB(int x, int y, int w, int h, int foo, int bar, byte r
float x2 = x+w;
float y1 = y;
float y2 = y+h;
pDraw_Colour4f(r/255.0, g/255.0, b/255.0, a/255.0 * alphamul);
pDraw_Line(x1, y1, x2, y1);
pDraw_Line(x2, y1, x2, y2);
pDraw_Line(x1, y2, x2, y2);
pDraw_Line(x1, y1, x1, y2);
pDraw_Colour4f(1, 1, 1, 1);
drawfuncs->Colour4f(r/255.0, g/255.0, b/255.0, a/255.0 * alphamul);
drawfuncs->Line(x1, y1, x2, y1);
drawfuncs->Line(x2, y1, x2, y2);
drawfuncs->Line(x1, y2, x2, y2);
drawfuncs->Line(x1, y1, x1, y2);
drawfuncs->Colour4f(1, 1, 1, 1);
}
void Draw_AlphaLineRGB(float x1, float y1, float x2, float y2, float width, byte r, byte g, byte b, byte a)
{
pDraw_Colour4f(r/255.0, g/255.0, b/255.0, a/255.0 * alphamul);
pDraw_Line(x1, y1, x2, y2);
pDraw_Colour4f(1, 1, 1, 1);
drawfuncs->Colour4f(r/255.0, g/255.0, b/255.0, a/255.0 * alphamul);
drawfuncs->Line(x1, y1, x2, y2);
drawfuncs->Colour4f(1, 1, 1, 1);
}
mpic_t *Draw_CachePicSafe(const char *name, qbool crash, qbool ignorewad)
{
if (!*name)
return NULL;
return (mpic_t*)(qintptr_t)pDraw_LoadImage(name, false);
return (mpic_t*)(qintptr_t)drawfuncs->LoadImage(name, false);
}
mpic_t *Draw_CacheWadPic(const char *name)
{
return (mpic_t*)(qintptr_t)pDraw_LoadImage(name, true);
return (mpic_t*)(qintptr_t)drawfuncs->LoadImage(name, true);
}
mpic_t *SCR_LoadCursorImage(char *cursorimage)
@ -488,15 +499,15 @@ void SCR_DrawSmallClock(int x, int y, int style, int blink, float scale, const c
void EZHud_UseNquake_f(void)
{
const char *hudstr = builtin_hud_nquake;
pCmd_AddText(hudstr, true);
cmdfuncs->AddText(hudstr, true);
}
struct
static struct
{
xcommand_t cmd;
const char *name;
} concmds[128];
int numconcmds;
static int numconcmds;
qboolean Cmd_AddCommand (const char *funcname, xcommand_t function)
{
if (numconcmds < sizeof(concmds)/sizeof(concmds[0]))
@ -504,17 +515,17 @@ qboolean Cmd_AddCommand (const char *funcname, xcommand_t function)
concmds[numconcmds].cmd = function;
concmds[numconcmds].name = funcname;
numconcmds++;
pCmd_AddCommand(funcname);
cmdfuncs->AddCommand(funcname);
return true;
}
Con_Printf("ezhud: too many console commands\n");
return false;
};
qintptr_t EZHud_ExecuteCommand(qintptr_t *args)
static qboolean QDECL EZHud_ExecuteCommand(qboolean isinsecure)
{
char buffer[128];
int i;
pCmd_Argv(0, buffer, sizeof(buffer));
cmdfuncs->Argv(0, buffer, sizeof(buffer));
for (i = 0; i < numconcmds; i++)
{
if (!strcmp(buffer, concmds[i].name))
@ -537,17 +548,17 @@ double vid_vsync_lag;
vrect_t scr_vrect;
qintptr_t EZHud_Tick(qintptr_t *args)
void EZHud_Tick(double realtime, double gametime)
{
static float lasttime, lasttime_min = 99999;
static int framecount;
//realtime(ms), realtime(secs), servertime
float oldtime = cls.realtime;
cls.realtime = *(float*)&args[1];
cls.realtime = realtime;
cls.frametime = cls.realtime - oldtime;
cl.time = *(float*)&args[2];
cl.time = gametime;
if (cls.realtime - lasttime > 1)
{
@ -564,8 +575,6 @@ qintptr_t EZHud_Tick(qintptr_t *args)
cls.min_fps = cls.fps;
}
framecount++;
return 1;
}
char *findinfo(char *info, char *findkey)
{
@ -612,25 +621,25 @@ float infofloat(char *info, char *findkey, float def)
return atof(value);
return def;
}
qintptr_t EZHud_Draw(qintptr_t *args)
int EZHud_Draw(int seat, float viewx, float viewy, float viewwidth, float viewheight, int showscores)
{
char serverinfo[4096];
char val[64];
int i;
cl.splitscreenview = args[0];
scr_vrect.x = args[1];
scr_vrect.y = args[2];
scr_vrect.width = args[3];
scr_vrect.height = args[4];
sb_showscores = args[5] & 1;
sb_showteamscores = args[5] & 2;
cl.splitscreenview = seat;
scr_vrect.x = viewx;
scr_vrect.y = viewy;
scr_vrect.width = viewwidth;
scr_vrect.height = viewheight;
sb_showscores = showscores & 1;
sb_showteamscores = showscores & 2;
pCL_GetStats(0, cl.stats, sizeof(cl.stats)/sizeof(cl.stats[0]));
clientfuncs->GetStats(0, cl.stats, sizeof(cl.stats)/sizeof(cl.stats[0]));
for (i = 0; i < 32; i++)
pGetPlayerInfo(i, &cl.players[i]);
clientfuncs->GetPlayerInfo(i, &cl.players[i]);
pGetLocalPlayerNumbers(cl.splitscreenview, 1, &cl.playernum, &cl.tracknum);
pGetServerInfo(cl.serverinfo, sizeof(serverinfo));
clientfuncs->GetLocalPlayerNumbers(cl.splitscreenview, 1, &cl.playernum, &cl.tracknum);
clientfuncs->GetServerInfo(cl.serverinfo, sizeof(serverinfo));
cl.deathmatch = infofloat(cl.serverinfo, "deathmatch", 0);
cl.teamplay = infofloat(cl.serverinfo, "teamplay", 0);
cl.intermission = infofloat(cl.serverinfo, "intermission", 0);
@ -640,8 +649,6 @@ qintptr_t EZHud_Draw(qintptr_t *args)
cl.countdown = !strcmp(val, "countdown");
cl.matchstart = infofloat(cl.serverinfo, "matchstart", 0);
cls.state = ca_active;
vid.width = pvid.width;
vid.height = pvid.height;
infostring(cl.serverinfo, "demotype", val, sizeof(val));
cls.mvdplayback = !strcmp(val, "mvd");
@ -652,7 +659,7 @@ qintptr_t EZHud_Draw(qintptr_t *args)
static cvar_t *pscr_viewsize = NULL;
int size;
if (!pscr_viewsize)
pscr_viewsize = pCvar_GetNVFDG("viewsize", "100", 0, NULL, NULL);
pscr_viewsize = cvarfuncs->GetNVFDG("viewsize", "100", 0, NULL, NULL);
size = cl.intermission ? 120 : pscr_viewsize->value;
if (size >= 120)
sb_lines = 0; // no status bar at all
@ -686,14 +693,12 @@ float cursor_y;
float mouse_x;
float mouse_y;
mpic_t *scr_cursor_icon = NULL;
qintptr_t EZHud_MenuEvent(qintptr_t *args)
qboolean QDECL EZHud_MenuEvent(int eventtype, int keyparam, int unicodeparm, float mousecursor_x, float mousecursor_y, float vidwidth, float vidheight)
{
int eventtype = args[0];
int param = args[1];
mouse_x += args[2] - cursor_x; //FIXME: the hud editor should NOT need this sort of thing
mouse_y += args[3] - cursor_y;
cursor_x = args[2];
cursor_y = args[3];
mouse_x += mousecursor_x - cursor_x; //FIXME: the hud editor should NOT need this sort of thing
mouse_y += mousecursor_y - cursor_y;
cursor_x = mousecursor_x;
cursor_y = mousecursor_y;
HUD_Editor_MouseEvent(cursor_x, cursor_y);
@ -708,33 +713,39 @@ qintptr_t EZHud_MenuEvent(qintptr_t *args)
mouse_y = 0;
break;
case 1:
if (param < K_MAX)
keydown[param] = true;
HUD_Editor_Key(param, 0, true);
if (keyparam < K_MAX)
keydown[keyparam] = true;
HUD_Editor_Key(keyparam, 0, true);
break;
case 2:
if (param < K_MAX)
keydown[param] = false;
HUD_Editor_Key(param, 0, false);
if (keyparam < K_MAX)
keydown[keyparam] = false;
HUD_Editor_Key(keyparam, 0, false);
break;
}
return 1;
}
qintptr_t Plug_Init(qintptr_t *args)
qboolean Plug_Init(void)
{
if (BUILTINISVALID(Cvar_GetNVFDG) &&
BUILTINISVALID(Draw_ImageSize) &&
BUILTINISVALID(GetTeamInfo) &&
Plug_Export("SbarBase", EZHud_Draw) &&
Plug_Export("MenuEvent", EZHud_MenuEvent) &&
Plug_Export("Tick", EZHud_Tick) &&
Plug_Export("ExecuteCommand", EZHud_ExecuteCommand))
drawfuncs = plugfuncs->GetEngineInterface(plug2dfuncs_name, sizeof(*drawfuncs));
clientfuncs = plugfuncs->GetEngineInterface(plugclientfuncs_name, sizeof(*clientfuncs));
filefuncs = plugfuncs->GetEngineInterface(plugfsfuncs_name, sizeof(*filefuncs));
inputfuncs = plugfuncs->GetEngineInterface(pluginputfuncs_name, sizeof(*inputfuncs));
plugfuncs->ExportFunction("UpdateVideo", EZHud_UpdateVideo);
if (cvarfuncs && drawfuncs && clientfuncs && filefuncs && inputfuncs &&
plugfuncs->ExportFunction("SbarBase", EZHud_Draw) &&
plugfuncs->ExportFunction("MenuEvent", EZHud_MenuEvent) &&
plugfuncs->ExportFunction("Tick", EZHud_Tick) &&
plugfuncs->ExportFunction("ExecuteCommand", EZHud_ExecuteCommand))
{
Cmd_AddCommand("ezhud_nquake", EZHud_UseNquake_f);
HUD_Init();
HUD_Editor_Init();
return 1;
return true;
}
Con_Printf("EZHud: Unable to initiailise\n");
return false;
}

View File

@ -2,6 +2,11 @@
#include <assert.h>
#include <ctype.h>
extern plug2dfuncs_t *drawfuncs;
extern plugfsfuncs_t *filefuncs;
extern plugclientfuncs_t *clientfuncs;
extern pluginputfuncs_t *inputfuncs;
//ezquake sucks. I'd fix these, but that'd make diffs more messy.
#ifdef __GNUC__
#pragma GCC diagnostic ignored "-Wold-style-definition"
@ -14,12 +19,12 @@
#define qbool qboolean
#define Com_Printf Con_Printf
#define Com_DPrintf Con_DPrintf
#define Cvar_Find(n) pCvar_GetNVFDG(n,NULL,0,NULL,NULL)
#define Cvar_SetValue(var,val) pCvar_SetFloat(var->name,val)
#define Cvar_Set(var,val) pCvar_SetString(var->name,val)
#define Cmd_Argc pCmd_Argc
#define Cbuf_AddText(x) pCmd_AddText(x,false)
#define Sys_Error(x) pSys_Error(x)
#define Cvar_Find(n) cvarfuncs->GetNVFDG(n,NULL,0,NULL,NULL)
#define Cvar_SetValue(var,val) cvarfuncs->SetFloat(var->name,val)
#define Cvar_Set(var,val) cvarfuncs->SetString(var->name,val)
#define Cmd_Argc cmdfuncs->Argc
#define Cbuf_AddText(x) cmdfuncs->AddText(x,false)
#define Sys_Error(x) plugfuncs->Error(x)
#define Q_calloc calloc
#define Q_malloc malloc
#define Q_strdup strdup
@ -99,7 +104,7 @@ void Draw_Fill(float x, float y, float w, float h, qbyte pal);
const char *ColorNameToRGBString (const char *newval);
byte *StringToRGB(const char *str);
#define Draw_String pDraw_String
#define Draw_String drawfuncs->String
void Draw_EZString(float x, float y, char *str, float scale, qboolean red);
#define Draw_Alt_String(x,y,s) Draw_EZString(x,y,s,8,true)
@ -138,7 +143,7 @@ void Replace_In_String(char *string, size_t strsize, char leadchar, int patterns
#define Utils_RegExpMatch(regexp,term) (true)
#define clamp(v,min,max) v=bound(min,v,max)
#define strlen_color(line) (pDraw_StringWidth(8, 0, line)/8.0)
#define strlen_color(line) (drawfuncs->StringWidth(8, 0, line)/8.0)
#define TIMETYPE_CLOCK 0
#define TIMETYPE_GAMECLOCK 1
@ -160,10 +165,6 @@ void Draw_AlphaRectangleRGB(int x, int y, int w, int h, int foo, int bar, byte r
void Draw_AlphaLineRGB(float x1, float y1, float x2, float y2, float width, byte r, byte g, byte b, byte a);
void Draw_Polygon(int x, int y, vec3_t *vertices, int num_vertices, qbool fill, byte r, byte g, byte b, byte a);
//glue
EBUILTIN(cvar_t*, Cvar_GetNVFDG, (const char *name, const char *defaultval, unsigned int flags, const char *description, const char *groupname));
#undef sb_lines //just in case.
#ifndef SBAR_HEIGHT
#define SBAR_HEIGHT 24

View File

@ -796,22 +796,22 @@ void HUD_Export_f(void)
char fname[64];
char fdesc[256];
pCmd_Argv(1, fname, sizeof(fname));
pCmd_Argv(2, fdesc, sizeof(fdesc));
cmdfuncs->Argv(1, fname, sizeof(fname));
cmdfuncs->Argv(2, fdesc, sizeof(fdesc));
if (!*fdesc)
snprintf(fdesc, sizeof(fdesc), "%s", fname);
snprintf(line, sizeof(line), "configs/hud_%s.cfg", fname);
if (pFS_Open(line, &handle, 2) < 0)
if (filefuncs->Open(line, &handle, 2) < 0)
Com_Printf("Couldn't open %s\n", line);
else
{
//FIXME: should print the result of an flocate, but plugins are not really aware of that stuff.
Com_Printf("Writing %s\n", line);
snprintf(line, sizeof(line), "//desc:%s\n\n//hud cvar settings, for use with FTEQW's ezhud plugin.\n", fdesc);
pFS_Write(handle, line, strlen(line));
filefuncs->Write(handle, line, strlen(line));
for (hud = hud_huds; hud; hud = hud->next)
{
@ -820,11 +820,11 @@ void HUD_Export_f(void)
var = hud->params[i];
//fixme: deal with " and \n
snprintf(line, sizeof(line), "set %s \"%s\"\n", var->name, var->string);
pFS_Write(handle, line, strlen(line));
filefuncs->Write(handle, line, strlen(line));
}
}
pFS_Close(handle);
filefuncs->Close(handle);
}
}
@ -1168,7 +1168,7 @@ cvar_t * HUD_CreateVar(char *hud_name, char *subvar, char *value)
snprintf (buf, sizeof (buf), "hud_%s_%s", hud_name, subvar);
return pCvar_GetNVFDG(buf, value, 0, NULL, "ezhud");
return cvarfuncs->GetNVFDG(buf, value, 0, NULL, "ezhud");
}
//

View File

@ -147,14 +147,14 @@ void HUD_InitSbarImages(void)
sb_ibar = Draw_CacheWadPic("ibar");
}
vmnetinfo_t *GetNetworkInfo(void)
plugnetinfo_t *GetNetworkInfo(void)
{
static vmnetinfo_t ni;
static plugnetinfo_t ni;
static int uc;
if (uc != host_screenupdatecount && BUILTINISVALID(GetNetworkInfo))
if (uc != host_screenupdatecount)
{
uc = host_screenupdatecount;
pGetNetworkInfo(&ni, sizeof(ni));
clientfuncs->GetNetworkInfo(&ni, sizeof(ni));
}
return &ni;
}
@ -393,7 +393,7 @@ void SCR_HUD_DrawFPS(hud_t *hud)
if (HUD_PrepareDraw(hud, strlen(st)*8, 8, &x, &y))
{
vmnetinfo_t *netinfo = GetNetworkInfo();
plugnetinfo_t *netinfo = GetNetworkInfo();
if (netinfo->capturing == 2) //don't show fps if its locked to something anyway.
return;
@ -418,7 +418,7 @@ void SCR_HUD_DrawVidLag(hud_t *hud)
char st[128];
static cvar_t *hud_vidlag_style = NULL;
vmnetinfo_t *netinfo = GetNetworkInfo();
plugnetinfo_t *netinfo = GetNetworkInfo();
static double old_lag;
if (netinfo->vlatency)
@ -462,7 +462,7 @@ void SCR_HUD_DrawMouserate(hud_t *hud)
char st[80]; // string buffer
double t; // current time
static double lastframetime; // last refresh
vmnetinfo_t *netinfo = GetNetworkInfo();
plugnetinfo_t *netinfo = GetNetworkInfo();
static cvar_t *hud_mouserate_title = NULL,
*hud_mouserate_interval,
@ -655,7 +655,7 @@ static void SCR_HUD_DrawPing(hud_t *hud)
int width, height;
int x, y;
char buf[512];
vmnetinfo_t *netinfo = GetNetworkInfo();
plugnetinfo_t *netinfo = GetNetworkInfo();
static cvar_t
*hud_ping_period = NULL,
@ -823,12 +823,12 @@ static void SCR_HUD_DrawNotify(hud_t* hud)
if (HUD_PrepareDraw(hud, width, height, &x, &y))
{
pCvar_SetFloat("con_notify_x", (float)x / vid.width);
pCvar_SetFloat("con_notify_y", (float)y / vid.height);
pCvar_SetFloat("con_notify_w", (float)width / vid.width);
pCvar_SetFloat("con_numnotifylines",(int)(height/(8*hud_notify_scale->value) + 0.01));
pCvar_SetFloat("con_notifytime", (float)hud_notify_time->ival);
pCvar_SetFloat("con_textsize", 8.0 * hud_notify_scale->value);
cvarfuncs->SetFloat("con_notify_x", (float)x / vid.width);
cvarfuncs->SetFloat("con_notify_y", (float)y / vid.height);
cvarfuncs->SetFloat("con_notify_w", (float)width / vid.width);
cvarfuncs->SetFloat("con_numnotifylines",(int)(height/(8*hud_notify_scale->value) + 0.01));
cvarfuncs->SetFloat("con_notifytime", (float)hud_notify_time->ival);
cvarfuncs->SetFloat("con_textsize", 8.0 * hud_notify_scale->value);
// SCR_DrawNotify(x, y, hud_notify_scale->value, hud_notify_time->ival, hud_notify_rows->ival, hud_notify_cols->ival);
}
}
@ -926,7 +926,7 @@ void SCR_HUD_DrawDemoClock(hud_t *hud)
//
// network statistics
//
static void SCR_NetStats(int x, int y, float period, vmnetinfo_t *netinfo)
static void SCR_NetStats(int x, int y, float period, plugnetinfo_t *netinfo)
{
char line[128];
double t;
@ -1002,7 +1002,7 @@ static void SCR_NetStats(int x, int y, float period, vmnetinfo_t *netinfo)
clamp(bandwidth_out, 0, 99999);
clamp(bandwidth_all, 0, 99999);
with_delta = !pCvar_GetFloat("cl_nodelta");
with_delta = !cvarfuncs->GetFloat("cl_nodelta");
}
Draw_Alt_String(x+36, y, "latency");
@ -1068,7 +1068,7 @@ static void SCR_HUD_DrawNetStats(hud_t *hud)
int width, height;
int x, y;
vmnetinfo_t *netinfo = GetNetworkInfo();
plugnetinfo_t *netinfo = GetNetworkInfo();
static cvar_t *hud_net_period = NULL;
@ -2314,7 +2314,7 @@ void Draw_AMFStatLoss (int stat, hud_t* hud) {
else
alpha = 0;
pDraw_Colour4f(1,1,1,alpha);
drawfuncs->Colour4f(1,1,1,alpha);
{
static cvar_t *scale[2] = {NULL}, *style[2], *digits[2], *align[2];
if (scale[elem] == NULL) // first time called
@ -2327,7 +2327,7 @@ void Draw_AMFStatLoss (int stat, hud_t* hud) {
SCR_HUD_DrawNum (hud, abs(*vxdmgcnt), 1,
scale[elem]->value, style[elem]->value, digits[elem]->ival, align[elem]->string);
}
pDraw_Colour4f(1,1,1,1);
drawfuncs->Colour4f(1,1,1,1);
}
static void SCR_HUD_DrawHealthDamage(hud_t *hud)
@ -2476,11 +2476,11 @@ static void SCR_HUD_NetProblem (hud_t *hud) {
static cvar_t *scale = NULL;
int x, y;
extern qbool hud_editor;
vmnetinfo_t *netinfo = GetNetworkInfo();
plugnetinfo_t *netinfo = GetNetworkInfo();
float picwidth = 64;
float picheight = 64;
pDraw_ImageSize((intptr_t)sb_net, &picwidth, &picheight);
drawfuncs->ImageSize((intptr_t)sb_net, &picwidth, &picheight);
if(scale == NULL)
scale = HUD_FindVar(hud, "scale");
@ -2524,7 +2524,7 @@ void SCR_HUD_DrawGroup(hud_t *hud, int width, int height, mpic_t *pic, int pic_s
float picwidth = 64;
float picheight = 64;
if (pic && pDraw_ImageSize((intptr_t)pic, &picwidth, &picheight) <= 0)
if (pic && drawfuncs->ImageSize((intptr_t)pic, &picwidth, &picheight) <= 0)
{
pic = NULL;
picwidth = 64;
@ -2650,7 +2650,7 @@ void SCR_HUD_LoadGroupPic(cvar_t *var, mpic_t **hud_pic, char *oldval)
if (!(temp_pic = Draw_CachePicSafe(pic_path, false, true)))
{
Com_Printf("Couldn't load picture %s for hud group.\n", newpic);
pCvar_SetString(var->name, "");
cvarfuncs->SetString(var->name, "");
return;
}
@ -3305,7 +3305,7 @@ int TeamFrags_DrawExtraSpecInfo(int num, int px, int py, int width, int height,
{
float rl_width, rl_height;
mpic_t *pic = sb_weapons[0][5];
pDraw_ImageSize((intptr_t)pic, &rl_width, &rl_height);
drawfuncs->ImageSize((intptr_t)pic, &rl_width, &rl_height);
// Only allow this for spectators.
if (!(cls.demoplayback || cl.spectator)
@ -3415,7 +3415,7 @@ static int Frags_DrawExtraSpecInfo(player_info_t *info,
int health_spacing = 1;
int weapon_width = 24;
pDraw_ImageSize((intptr_t)rl_picture, &rl_width, &rl_height);
drawfuncs->ImageSize((intptr_t)rl_picture, &rl_width, &rl_height);
// Only allow this for spectators.
if (!(cls.demoplayback || cl.spectator))
@ -3686,7 +3686,7 @@ void SCR_HUD_DrawFrags(hud_t *hud)
mpic_t *rl_picture = sb_weapons[0][5];
float rl_width, rl_height;
pDraw_ImageSize((intptr_t)rl_picture, &rl_width, &rl_height);
drawfuncs->ImageSize((intptr_t)rl_picture, &rl_width, &rl_height);
if (hud_frags_cell_width == NULL) // first time
{
@ -4116,7 +4116,7 @@ void SCR_HUD_DrawTeamFrags(hud_t *hud)
mpic_t *rl_picture = sb_weapons[0][5];
float rl_width, rl_height;
pDraw_ImageSize((intptr_t)rl_picture, &rl_width, &rl_height);
drawfuncs->ImageSize((intptr_t)rl_picture, &rl_width, &rl_height);
if (hud_teamfrags_cell_width == 0) // first time
{
@ -4720,31 +4720,31 @@ void HUD_AutoLoad_MVD(int autoload) {
{
// Save old cfg_save values so that we don't screw the users
// settings when saving the temp config.
int old_cmdline = pCvar_GetFloat("cfg_save_cmdline");
int old_cvars = pCvar_GetFloat("cfg_save_cvars");
int old_cmds = pCvar_GetFloat("cfg_save_cmds");
int old_aliases = pCvar_GetFloat("cfg_save_aliases");
int old_binds = pCvar_GetFloat("cfg_save_binds");
int old_cmdline = cvarfuncs->GetFloat("cfg_save_cmdline");
int old_cvars = cvarfuncs->GetFloat("cfg_save_cvars");
int old_cmds = cvarfuncs->GetFloat("cfg_save_cmds");
int old_aliases = cvarfuncs->GetFloat("cfg_save_aliases");
int old_binds = cvarfuncs->GetFloat("cfg_save_binds");
autohud.old_fov = (int) scr_fov->value;
autohud.old_multiview = (int) cl_multiview->value;
autohud.old_newhud = (int) scr_newHud->value;
// Make sure everything current settings are saved.
pCvar_SetFloat("cfg_save_cmdline", 1);
pCvar_SetFloat("cfg_save_cvars", 1);
pCvar_SetFloat("cfg_save_cmds", 1);
pCvar_SetFloat("cfg_save_aliases", 1);
pCvar_SetFloat("cfg_save_binds", 1);
cvarfuncs->SetFloat("cfg_save_cmdline", 1);
cvarfuncs->SetFloat("cfg_save_cvars", 1);
cvarfuncs->SetFloat("cfg_save_cmds", 1);
cvarfuncs->SetFloat("cfg_save_aliases", 1);
cvarfuncs->SetFloat("cfg_save_binds", 1);
// Save a temporary config.
DumpConfig(TEMPHUD_NAME".cfg");
pCvar_SetFloat("cfg_save_cmdline", old_cmdline);
pCvar_SetFloat("cfg_save_cvars", old_cvars);
pCvar_SetFloat("cfg_save_cmds", old_cmds);
pCvar_SetFloat("cfg_save_aliases", old_aliases);
pCvar_SetFloat("cfg_save_binds", old_binds);
cvarfuncs->SetFloat("cfg_save_cmdline", old_cmdline);
cvarfuncs->SetFloat("cfg_save_cvars", old_cvars);
cvarfuncs->SetFloat("cfg_save_cmds", old_cmds);
cvarfuncs->SetFloat("cfg_save_aliases", old_aliases);
cvarfuncs->SetFloat("cfg_save_binds", old_binds);
}
// load MVD HUD config
@ -4778,9 +4778,9 @@ void HUD_AutoLoad_MVD(int autoload) {
Com_DPrintf("Unloading MVD Hud\n");
// load stored settings
pCvar_SetFloat(scr_fov->name, autohud.old_fov);
pCvar_SetFloat(cl_multiview->name, autohud.old_multiview);
pCvar_SetFloat(scr_newHud->name, autohud.old_newhud);
cvarfuncs->SetFloat(scr_fov->name, autohud.old_fov);
cvarfuncs->SetFloat(cl_multiview->name, autohud.old_multiview);
cvarfuncs->SetFloat(scr_newHud->name, autohud.old_newhud);
//Cmd_TokenizeString("exec "TEMPHUD_FULLPATH);
Cmd_TokenizeString("cfg_load "TEMPHUD_FULLPATH);
Cmd_Exec_f();
@ -5373,7 +5373,7 @@ static void SCR_HUD_DrawTeamInfo(hud_t *hud)
// if ( CURRVIEW != 1 && CURRVIEW != 0)
// return;
slots_num = pGetTeamInfo(ti_clients, countof(ti_clients), hud_teaminfo_show_enemies->ival, hud_teaminfo_show_self->ival);
slots_num = clientfuncs->GetTeamInfo(ti_clients, countof(ti_clients), hud_teaminfo_show_enemies->ival, hud_teaminfo_show_self->ival?-1:0);
// fill data we require to draw teaminfo
for ( maxloc = maxname = i = 0; i < slots_num; i++ ) {
@ -5537,7 +5537,7 @@ static int SCR_HudDrawTeamInfoPlayer(teamplayerinfo_t *ti_cl, int x, int y, int
case 1:
if(!width_only) {
if (Has_Both_RL_and_LG(ti_cl->items)) {
char *weap_str = pCvar_GetNVFDG("tp_name_rlg", "rlg", 0, NULL, NULL)->string;
char *weap_str = cvarfuncs->GetNVFDG("tp_name_rlg", "rlg", 0, NULL, NULL)->string;
char weap_white_stripped[32];
Util_SkipChars(weap_str, "{}", weap_white_stripped, 32);
Draw_ColoredString (x, y, weap_white_stripped, false);
@ -6362,13 +6362,8 @@ void SCR_HUD_DrawOwnFrags(hud_t *hud)
strcpy(ownfragtext, "Own Frags");
age = 0;
}
else if (BUILTINISVALID(GetTrackerOwnFrags))
age = pGetTrackerOwnFrags(0, ownfragtext, sizeof(ownfragtext));
else
{
strcpy(ownfragtext, "Engine does not support OwnFrags");
age = 0;
}
age = clientfuncs->GetTrackerOwnFrags(0, ownfragtext, sizeof(ownfragtext));
width = strlen(ownfragtext)*8;
width *= hud_ownfrags_scale->value;
@ -6388,9 +6383,9 @@ void SCR_HUD_DrawOwnFrags(hud_t *hud)
if (!HUD_PrepareDraw(hud, width, height, &x, &y))
return;
pDraw_Colour4f(1, 1, 1, alpha);
drawfuncs->Colour4f(1, 1, 1, alpha);
Draw_SString(x, y, ownfragtext, hud_ownfrags_scale->value);
pDraw_Colour4f(1, 1, 1, 1);
drawfuncs->Colour4f(1, 1, 1, 1);
}
#ifdef QUAKEHUD
@ -6415,10 +6410,7 @@ static void SCR_HUD_DrawWeaponStats(hud_t *hud)
int ws;
struct wstats_s wstats[16];
if (BUILTINISVALID(GetWeaponStats))
ws = pGetWeaponStats(-1, wstats, countof(wstats));
else
ws = 0;
ws = clientfuncs->GetWeaponStats(-1, wstats, countof(wstats));
if (hud_editor)
{
@ -6507,8 +6499,7 @@ void SCR_HUD_DrawKeys(hud_t *hud)
float scale;
memset(&b, 0, sizeof(b));
if (BUILTINISVALID(GetLastInputFrame))
pGetLastInputFrame(0, &b);
clientfuncs->GetLastInputFrame(0, &b);
if (!vscale) {
vscale = HUD_FindVar(hud, "scale");
@ -7714,24 +7705,24 @@ void CommonDraw_Init(void)
HUD_InitSbarImages();
// variables
hud_planmode = pCvar_GetNVFDG("hud_planmode", "0", 0, NULL, "ezhud");
hud_tp_need = pCvar_GetNVFDG("hud_tp_need", "0", 0, NULL, "ezhud");
hud_digits_trim = pCvar_GetNVFDG("hud_digits_trim", "1", 0, NULL, "ezhud");
mvd_autohud = pCvar_GetNVFDG("mvd_autohud", "0", 0, NULL, "ezhud");
cl_weaponpreselect = pCvar_GetNVFDG("cl_weaponpreselect", "0", 0, NULL, "ezhud");
cl_multiview = pCvar_GetNVFDG("cl_multiview", "0", 0, NULL, "ezhud");
hud_planmode = cvarfuncs->GetNVFDG("hud_planmode", "0", 0, NULL, "ezhud");
hud_tp_need = cvarfuncs->GetNVFDG("hud_tp_need", "0", 0, NULL, "ezhud");
hud_digits_trim = cvarfuncs->GetNVFDG("hud_digits_trim", "1", 0, NULL, "ezhud");
mvd_autohud = cvarfuncs->GetNVFDG("mvd_autohud", "0", 0, NULL, "ezhud");
cl_weaponpreselect = cvarfuncs->GetNVFDG("cl_weaponpreselect", "0", 0, NULL, "ezhud");
cl_multiview = cvarfuncs->GetNVFDG("cl_multiview", "0", 0, NULL, "ezhud");
tp_need_health = pCvar_GetNVFDG("tp_need_health", "50", 0, NULL, "ezhud");
tp_need_ra = pCvar_GetNVFDG("tp_need_ra", "50", 0, NULL, "ezhud");
tp_need_ya = pCvar_GetNVFDG("tp_need_ya", "50", 0, NULL, "ezhud");
tp_need_ga = pCvar_GetNVFDG("tp_need_ga", "50", 0, NULL, "ezhud");
tp_weapon_order = pCvar_GetNVFDG("tp_weapon_order", "78654321", 0, NULL, "ezhud");
tp_need_weapon = pCvar_GetNVFDG("tp_need_weapon", "35687", 0, NULL, "ezhud");
tp_need_shells = pCvar_GetNVFDG("tp_need_shells", "10", 0, NULL, "ezhud");
tp_need_nails = pCvar_GetNVFDG("tp_need_nails", "40", 0, NULL, "ezhud");
tp_need_rockets = pCvar_GetNVFDG("tp_need_rockets", "5", 0, NULL, "ezhud");
tp_need_cells = pCvar_GetNVFDG("tp_need_cells", "20", 0, NULL, "ezhud");
tp_need_health = cvarfuncs->GetNVFDG("tp_need_health", "50", 0, NULL, "ezhud");
tp_need_ra = cvarfuncs->GetNVFDG("tp_need_ra", "50", 0, NULL, "ezhud");
tp_need_ya = cvarfuncs->GetNVFDG("tp_need_ya", "50", 0, NULL, "ezhud");
tp_need_ga = cvarfuncs->GetNVFDG("tp_need_ga", "50", 0, NULL, "ezhud");
tp_weapon_order = cvarfuncs->GetNVFDG("tp_weapon_order", "78654321", 0, NULL, "ezhud");
tp_need_weapon = cvarfuncs->GetNVFDG("tp_need_weapon", "35687", 0, NULL, "ezhud");
tp_need_shells = cvarfuncs->GetNVFDG("tp_need_shells", "10", 0, NULL, "ezhud");
tp_need_nails = cvarfuncs->GetNVFDG("tp_need_nails", "40", 0, NULL, "ezhud");
tp_need_rockets = cvarfuncs->GetNVFDG("tp_need_rockets", "5", 0, NULL, "ezhud");
tp_need_cells = cvarfuncs->GetNVFDG("tp_need_cells", "20", 0, NULL, "ezhud");
// init HUD STAT table
for (i=0; i < MAX_CL_STATS; i++)

View File

@ -2438,7 +2438,7 @@ void HUD_Editor_Toggle_f(void)
{
// Start HUD Editor.
pMenu_Control(MENU_GRAB);
inputfuncs->SetMenuFocus(true, "", 0, 0, 0);
HUD_Editor_SetMode(hud_editmode_normal);
// Set planmode by default.
@ -2452,7 +2452,7 @@ void HUD_Editor_Toggle_f(void)
{
// Exit the HUD Editor.
pMenu_Control(MENU_CLEAR);
inputfuncs->SetMenuFocus(false, "", 0, 0, 0);
HUD_Editor_SetMode(hud_editmode_off);
scr_cursor_icon = NULL;
@ -2760,10 +2760,10 @@ void HUD_Editor_Init(void)
Cmd_AddCommand("hud_editor", HUD_Editor_Toggle_f);
// Register variables.
hud_editor_allowresize = pCvar_GetNVFDG("hud_editor_allowresize", "1", 0, NULL, "hud");
hud_editor_allowmove = pCvar_GetNVFDG("hud_editor_allowmove", "1", 0, NULL, "hud");
hud_editor_allowplace = pCvar_GetNVFDG("hud_editor_allowplace", "1", 0, NULL, "hud");
hud_editor_allowalign = pCvar_GetNVFDG("hud_editor_allowalign", "1", 0, NULL, "hud");
hud_editor_allowresize = cvarfuncs->GetNVFDG("hud_editor_allowresize", "1", 0, NULL, "hud");
hud_editor_allowmove = cvarfuncs->GetNVFDG("hud_editor_allowmove", "1", 0, NULL, "hud");
hud_editor_allowplace = cvarfuncs->GetNVFDG("hud_editor_allowplace", "1", 0, NULL, "hud");
hud_editor_allowalign = cvarfuncs->GetNVFDG("hud_editor_allowalign", "1", 0, NULL, "hud");
// Load HUD editor cursor icons.
hud_editor_move_icon = SCR_LoadCursorImage("gfx/hud_move_icon");

View File

@ -1,25 +0,0 @@
DO_CC=$(CC) -ggdb -fPIC -Wall $(CFLAGS) -o $@ -c $<
OBJECTS=ezscript.o plugin.o qvm_api.o
HEADERS=../plugin.h
OUTFILE=../ezscriptx86.so
LCC_FLAGS=-DQ3_VM -S -Wf-target=bytecode -Wf-g
all: $(OBJECTS)
$(CC) -ggdb -fPIC -shared $(OBJECTS) -o $(OUTFILE)
clean:
rm -rf $(OBJECTS) $(OUTFILE) *.qvm *.asm
qvm:
lcc $(LCC_FLAGS) ezscript.c; lcc $(LCC_FLAGS) ../plugin.c; lcc $(LCC_FLAGS) ../qvm_api.c; q3asm -f ezscript
ezscript.o: ezscript.c $(HEADERS)
$(DO_CC)
plugin.o: ../plugin.c $(HEADERS)
$(DO_CC)
qvm_api.o: ../qvm_api.c $(HEADERS)
$(DO_CC)

View File

@ -1,15 +0,0 @@
@echo off
call ..\paths.bat
del vm\*.asm
rmdir vm
mkdir vm
cd vm
lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g ../ezscript.c
lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g ../../plugin.c
lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g ../../qvm_api.c
q3asm -f ../ezscript
cd ..
pause

View File

@ -1,25 +0,0 @@
DO_CC=$(CC) -ggdb -fPIC -Wall $(CFLAGS) -o $@ -c $<
OBJECTS=ui_sbar.o plugin.o qvm_api.o
HEADERS=../plugin.h
OUTFILE=../hudx86.so
ASM=q3asm
#ASM=q3asm -vq3 #Uncomment this if you are using Icculus q3asm
LCC=q3lcc
LCC_FLAGS=-DQ3_VM -S -Wf-target=bytecode -Wf-g
all: $(OBJECTS)
$(CC) -ggdb -fPIC -shared $(OBJECTS) -o $(OUTFILE)
qvm:
$(LCC) $(LCC_FLAGS) ui_sbar.c; $(LCC) $(LCC_FLAGS) ../plugin.c; $(LCC) $(LCC_FLAGS) ../qvm_api.c; $(ASM) -f qwui
clean:
rm -rf $(OBJECTS) $(OUTFILE) *.qvm *.asm
ui_sbar.o: ui_sbar.c $(HEADERS)
$(DO_CC)
plugin.o: ../plugin.c $(HEADERS)
$(DO_CC)
qvm_api.o: ../qvm_api.c $(HEADERS)
$(DO_CC)

View File

@ -1,20 +0,0 @@
@echo off
call ..\paths.bat
del vm\*.asm
rmdir vm
mkdir vm
cd vm
lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g ../ui_sbar.c
if errorlevel 1 goto end
lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g ../../plugin.c
if errorlevel 1 goto end
lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g ../../qvm_api.c
if errorlevel 1 goto end
q3asm -f ../qwui
:end
cd ..
pause

View File

@ -1,25 +0,0 @@
DO_CC=$(CC) -fPIC $(CFLAGS) -o $@ -c $<
OBJECTS=ircclient.o plugin.o qvm_api.o
HEADERS=../plugin.h
OUTFILE=../ircx86.so
ASM=q3asm
#ASM=q3asm -vq3 #Uncomment this if you are using Icculus q3asm
LCC=q3lcc
LCC_FLAGS=-DQ3_VM -I/usr/include -S -Wf-target=bytecode -Wf-g
all: $(OBJECTS)
$(CC) --shared -ldl $(OBJECTS) -o $(OUTFILE)
qvm:
$(LCC) $(LCC_FLAGS) ircclient.c; $(LCC) $(LCC_FLAGS) ../plugin.c; $(LCC) $(LCC_FLAGS) ../qvm_api.c; $(ASM) -f ircclient
clean:
rm -rf $(OBJECTS) $(OUTFILE) *.qvm *.asm
ircclient.o: ircclient.c $(HEADERS)
$(DO_CC)
plugin.o: ../plugin.c $(HEADERS)
$(DO_CC)
qvm_api.o: ../qvm_api.c $(HEADERS)
$(DO_CC)

View File

@ -1,15 +0,0 @@
@echo off
call ..\paths.bat
del vm\*.asm
rmdir vm
mkdir vm
cd vm
lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g ../ircclient.c
lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g ../../plugin.c
lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g ../../qvm_api.c
q3asm -f ../ircclient
cd ..
pause

View File

@ -9,6 +9,10 @@
#include "../plugin.h"
static plugsubconsolefuncs_t *confuncs;
static plugfsfuncs_t *filefuncs;
static plugnetfuncs_t *netfuncs;
static plug2dfuncs_t *drawfuncs;
#include <time.h>
#include <ctype.h>
#include "../../engine/common/netinc.h"
@ -64,10 +68,22 @@ static char casevar[9][1000]; //numbered_command
#define COMMANDNAME "irc"
#define RELEASE __DATE__
static void (*Con_TrySubPrint)(const char *subname, const char *text);
static void Con_FakeSubPrint(const char *subname, const char *text)
static struct
{
pCon_Print(text);
int width;
int height;
} pvid;
static void QDECL IRC_UpdateVideo(int width, int height)
{
pvid.width = width;
pvid.height = height;
}
static qboolean (*Con_TrySubPrint)(const char *subname, const char *text);
static qboolean Con_FakeSubPrint(const char *subname, const char *text)
{
plugfuncs->Print(text);
return true;
}
//porting zone:
@ -248,14 +264,14 @@ static void IRC_SetFooter(ircclient_t *irc, const char *subname, const char *for
lwr[i] = '\0';
if (BUILTINISVALID(Con_SetConsoleFloat) && pCon_GetConsoleFloat(lwr, "iswindow") < true)
if (confuncs && confuncs->GetConsoleFloat(lwr, "iswindow") < true)
{
pCon_SetConsoleString(lwr, "title", *channame?channame:irc->server);
pCon_SetConsoleString(lwr, "prompt", va("[^1%s^7]: ", irc->nick));
pCon_SetConsoleFloat(lwr, "iswindow", 2);
pCon_SetConsoleFloat(lwr, "forceutf8", true);
pCon_SetConsoleFloat(lwr, "wnd_w", 256);
pCon_SetConsoleFloat(lwr, "wnd_h", 320);
confuncs->SetConsoleString(lwr, "title", *channame?channame:irc->server);
confuncs->SetConsoleString(lwr, "prompt", va("[^1%s^7]: ", irc->nick));
confuncs->SetConsoleFloat(lwr, "iswindow", 2);
confuncs->SetConsoleFloat(lwr, "forceutf8", true);
confuncs->SetConsoleFloat(lwr, "wnd_w", 256);
confuncs->SetConsoleFloat(lwr, "wnd_h", 320);
//lame, but whatever.
if (next_window_x + 256 > pvid.width)
@ -265,13 +281,13 @@ static void IRC_SetFooter(ircclient_t *irc, const char *subname, const char *for
if (next_window_y + 320 > pvid.height)
next_window_y = 0;
}
pCon_SetConsoleFloat(lwr, "wnd_x", next_window_x);
pCon_SetConsoleFloat(lwr, "wnd_y", next_window_y);
confuncs->SetConsoleFloat(lwr, "wnd_x", next_window_x);
confuncs->SetConsoleFloat(lwr, "wnd_y", next_window_y);
next_window_x += 256;
}
if (BUILTINISVALID(Con_SetConsoleString))
pCon_SetConsoleString(lwr, "footer", string);
if (confuncs)
confuncs->SetConsoleString(lwr, "footer", string);
}
}
static qboolean IRC_WindowShown(ircclient_t *irc, const char *subname)
@ -291,7 +307,7 @@ static qboolean IRC_WindowShown(ircclient_t *irc, const char *subname)
lwr[i] = '\0';
if (BUILTINISVALID(Con_SetConsoleFloat) && pCon_GetConsoleFloat(lwr, "iswindow") < true)
if (confuncs && confuncs->GetConsoleFloat(lwr, "iswindow") < true)
return false;
}
return true;
@ -310,7 +326,7 @@ static void IRC_Printf(ircclient_t *irc, const char *subname, const char *format
va_end (argptr);
if (!irc)
pCon_Print(string);
plugfuncs->Print(string);
else
{
Q_strlcpy(lwr, irc->id, sizeof(lwr));
@ -324,14 +340,14 @@ static void IRC_Printf(ircclient_t *irc, const char *subname, const char *format
lwr[i] = '\0';
if (BUILTINISVALID(Con_SetConsoleFloat) && pCon_GetConsoleFloat(lwr, "iswindow") < true)
if (confuncs && confuncs->GetConsoleFloat(lwr, "iswindow") < true)
{
pCon_SetConsoleString(lwr, "title", *channame?channame:irc->server);
pCon_SetConsoleString(lwr, "prompt", va("[^1%s^7]: ", irc->nick));
pCon_SetConsoleFloat(lwr, "iswindow", 2);
pCon_SetConsoleFloat(lwr, "forceutf8", true);
pCon_SetConsoleFloat(lwr, "wnd_w", 256);
pCon_SetConsoleFloat(lwr, "wnd_h", 320);
confuncs->SetConsoleString(lwr, "title", *channame?channame:irc->server);
confuncs->SetConsoleString(lwr, "prompt", va("[^1%s^7]: ", irc->nick));
confuncs->SetConsoleFloat(lwr, "iswindow", 2);
confuncs->SetConsoleFloat(lwr, "forceutf8", true);
confuncs->SetConsoleFloat(lwr, "wnd_w", 256);
confuncs->SetConsoleFloat(lwr, "wnd_h", 320);
//lame, but whatever.
if (next_window_x + 256 > pvid.width)
@ -341,12 +357,12 @@ static void IRC_Printf(ircclient_t *irc, const char *subname, const char *format
if (next_window_y + 320 > pvid.height)
next_window_y = 0;
}
pCon_SetConsoleFloat(lwr, "wnd_x", next_window_x);
pCon_SetConsoleFloat(lwr, "wnd_y", next_window_y);
confuncs->SetConsoleFloat(lwr, "wnd_x", next_window_x);
confuncs->SetConsoleFloat(lwr, "wnd_y", next_window_y);
next_window_x += 256;
}
if (!*string)
pCon_SetActive(lwr);
confuncs->SetActive(lwr);
Con_TrySubPrint(lwr, string);
}
@ -362,7 +378,7 @@ static void IRC_InitCvars(void)
for (i=0; cvarlist[i]; i++)
{
v = cvarlist[i];
v->handle = pCvar_Register(v->name, v->string, v->flags, v->group);
v->handle = cvarfuncs->Register(v->name, v->string, v->flags, v->group);
}
}
@ -373,71 +389,77 @@ static int IRC_CvarUpdate(void) // perhaps void instead?
for (i=0; cvarlist[i]; i++)
{
v = cvarlist[i];
v->modificationcount = pCvar_Update(v->handle, &v->modificationcount, v->string, &v->value);
cvarfuncs->Update(v->handle, &v->modificationcount, v->string, sizeof(v->string), &v->value);
}
return 0;
}
void IRC_Command(ircclient_t *ircclient, char *dest, char *args);
qintptr_t IRC_ExecuteCommand(qintptr_t *args);
qintptr_t IRC_ConExecuteCommand(qintptr_t *args);
qintptr_t IRC_Frame(qintptr_t *args);
qintptr_t IRC_ConsoleLink(qintptr_t *args);
qboolean IRC_ExecuteCommand(qboolean isinsecure);
int IRC_ConExecuteCommand(qboolean isinsecure);
void IRC_Frame(double realtime, double gametime);
qboolean IRC_ConsoleLink(void);
qintptr_t Plug_Init(qintptr_t *args)
qboolean Plug_Init(void)
{
if ( Plug_Export("Tick", IRC_Frame) &&
Plug_Export("ExecuteCommand", IRC_ExecuteCommand))
{
pCmd_AddCommand(COMMANDNAME);
confuncs = plugfuncs->GetEngineInterface(plugsubconsolefuncs_name, sizeof(*confuncs));
filefuncs = plugfuncs->GetEngineInterface(plugfsfuncs_name, sizeof(*filefuncs));
netfuncs = plugfuncs->GetEngineInterface(plugnetfuncs_name, sizeof(*netfuncs));
drawfuncs = plugfuncs->GetEngineInterface(plug2dfuncs_name, sizeof(*drawfuncs));
piceapi = plugfuncs->GetEngineInterface(ICE_API_CURRENT, sizeof(*piceapi));
plugfuncs->ExportFunction("UpdateVideo", IRC_UpdateVideo);
Plug_Export("ConsoleLink", IRC_ConsoleLink);
if (!Plug_Export("ConExecuteCommand", IRC_ConExecuteCommand))
if (netfuncs &&
filefuncs &&
plugfuncs->ExportFunction("Tick", IRC_Frame) &&
plugfuncs->ExportFunction("ExecuteCommand", IRC_ExecuteCommand))
{
cmdfuncs->AddCommand(COMMANDNAME);
plugfuncs->ExportFunction("ConsoleLink", IRC_ConsoleLink);
if (!confuncs || !plugfuncs->ExportFunction("ConExecuteCommand", IRC_ConExecuteCommand))
Con_TrySubPrint = Con_FakeSubPrint;
else
Con_TrySubPrint = pCon_SubPrint;
Con_TrySubPrint = confuncs->SubPrint;
reloadconfig = true;
IRC_InitCvars();
if (BUILTINISVALID(Plug_GetNativePointer))
piceapi = pPlug_GetNativePointer(ICE_API_CURRENT);
return true;
}
else
{
pCon_Print("IRC Client Plugin failed\n");
plugfuncs->Print("IRC Client Plugin failed\n");
}
return false;
}
qintptr_t IRC_ExecuteCommand(qintptr_t *args)
qboolean IRC_ExecuteCommand(qboolean isinsecure)
{
char cmd[256];
pCmd_Argv(0, cmd, sizeof(cmd));
cmdfuncs->Argv(0, cmd, sizeof(cmd));
if (!strcmp(cmd, COMMANDNAME))
{
ircclient_t *ircclient = ircclients;
char imsg[8192];
pCmd_Args(imsg, sizeof(imsg));
cmdfuncs->Args(imsg, sizeof(imsg));
//FIXME: select an irc network more inteligently
IRC_Command(ircclient, ircclient?ircclient->defaultdest:"", imsg);
return true;
}
return false;
}
qintptr_t IRC_ConExecuteCommand(qintptr_t *args)
int IRC_ConExecuteCommand(qboolean isinsecure)
{
char buffer[256];
char imsg[8192];
ircclient_t *ircclient;
//FIXME: select the right network
pCmd_Argv(0, buffer, sizeof(buffer));
pCmd_Args(imsg, sizeof(imsg));
cmdfuncs->Argv(0, buffer, sizeof(buffer));
cmdfuncs->Args(imsg, sizeof(imsg));
//buffer is something like: irc53:#foo
for (ircclient = ircclients; ircclient; ircclient = ircclient->next)
@ -576,7 +598,7 @@ static qboolean IRC_Establish(ircclient_t *irc)
irc->bufferedinammount = 0;
irc->quitting = false;
irc->socket = pNet_TCPConnect(irc->server, 6667); //port is only used if the url doesn't contain one. It's a default.
irc->socket = netfuncs->TCPConnect(irc->server, 6667); //port is only used if the url doesn't contain one. It's a default.
//not yet blocking. So no frequent attempts please...
//non blocking prevents connect from returning worthwhile sensible value.
@ -588,9 +610,9 @@ static qboolean IRC_Establish(ircclient_t *irc)
if (irc->tlsmode == TLS_INITIAL)
{
if (pNet_SetTLSClient(irc->socket, irc->server) < 0)
if (netfuncs->SetTLSClient(irc->socket, irc->server) < 0)
{
pNet_Close(irc->socket);
netfuncs->Close(irc->socket);
irc->socket = invalid_handle;
return false;
}
@ -614,14 +636,14 @@ static qboolean IRC_Establish(ircclient_t *irc)
static void IRC_ParseConfig(void)
{
qhandle_t config;
int len = pFS_Open("**plugconfig", &config, 1);
int len = filefuncs->Open("**plugconfig", &config, 1);
if (len >= 0)
{
char *buf = malloc(len+1);
char *msg = buf;
buf[len] = 0;
pFS_Read(config, buf, len);
pFS_Close(config);
filefuncs->Read(config, buf, len);
filefuncs->Close(config);
while (msg && *msg)
{
@ -668,7 +690,7 @@ static void IRC_WriteConfig(void)
if (irc_config.value == 0)
return;
pFS_Open("**plugconfig", &config, 2);
filefuncs->Open("**plugconfig", &config, 2);
if (config >= 0)
{
ircclient_t *irc;
@ -677,10 +699,10 @@ static void IRC_WriteConfig(void)
char *s = va("\"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"\n", irc->server, irc->autochannels, irc->primarynick, irc->pwd, irc->realname, irc->hostname, irc->username);
if (irc->quitting || !irc->persist)
continue;
pFS_Write(config, s, strlen(s));
filefuncs->Write(config, s, strlen(s));
}
pFS_Close(config);
filefuncs->Close(config);
}
}
static void IRC_MakeDefault(ircclient_t *irc)
@ -1286,7 +1308,7 @@ static void numbered_command(int comm, char *msg, ircclient_t *irc) // move vars
}
case 670: /* RPL_STARTTLS */
{
pNet_SetTLSClient(irc->socket, irc->server);
netfuncs->SetTLSClient(irc->socket, irc->server);
irc->tlsmode = TLS_START;
irc->nicktries = 0;
IRC_SetPass(irc, irc->pwd);
@ -1297,7 +1319,7 @@ static void numbered_command(int comm, char *msg, ircclient_t *irc) // move vars
case 691: /* ERR_STARTTLS */
{
IRC_Printf(irc, DEFAULTCONSOLE, COLOURYELLOW "STARTTLS Failed: %s\n", casevar[3]);
pNet_Close(irc->socket);
netfuncs->Close(irc->socket);
irc->socket = invalid_handle;
return;
}
@ -1706,7 +1728,7 @@ static void IRC_ICE_Authorise(ircclient_t *irc, const char *with, enum iceproto_
IRC_Printf(irc, announce, "Connection is already terminated\n");
}
qintptr_t IRC_ConsoleLink(qintptr_t *args)
qboolean IRC_ConsoleLink(void)
{
ircclient_t *irc;
char link[256];
@ -1716,9 +1738,9 @@ qintptr_t IRC_ConsoleLink(qintptr_t *args)
char whobuf[256];
char which[512];
enum iceproto_e type;
// pCmd_Argv(0, text, sizeof(text));
pCmd_Argv(1, link, sizeof(link));
pCmd_Argv(2, which, sizeof(which));
// cmdfuncs->Argv(0, text, sizeof(text));
cmdfuncs->Argv(1, link, sizeof(link));
cmdfuncs->Argv(2, which, sizeof(which));
Plug_Info_ValueForKey(link, "act", what, sizeof(what));
who = Plug_Info_ValueForKey(link, "who", whobuf, sizeof(whobuf));
@ -1863,7 +1885,7 @@ static int IRC_ClientFrame(ircclient_t *irc)
int i = 1;
ret = pNet_Recv(irc->socket, irc->bufferedinmessage+irc->bufferedinammount, sizeof(irc->bufferedinmessage)-1 - irc->bufferedinammount);
ret = netfuncs->Recv(irc->socket, irc->bufferedinmessage+irc->bufferedinammount, sizeof(irc->bufferedinmessage)-1 - irc->bufferedinammount);
if (ret == 0)
{
if (!irc->bufferedinammount) //if we are half way through a message, read any possible conjunctions.
@ -2037,8 +2059,8 @@ static int IRC_ClientFrame(ircclient_t *irc)
//message takes the form :FROM PRIVMSG TO :MESSAGE
if (BUILTINISVALID(LocalSound))
pLocalSound ("misc/talk.wav");
if (drawfuncs)
drawfuncs->LocalSound ("misc/talk.wav", 256, 1);
if ((!strcasecmp(var[4]+1, "\1VERSION\1")) && (!strncmp(var[2], "PRIVMSG ", 7)))
{
@ -2087,7 +2109,8 @@ static int IRC_ClientFrame(ircclient_t *irc)
*exc = '\0';
//a link to interact with the sender
Q_snprintf(link, sizeof(link), "^["COLOURGREEN"%s\\act\\user\\who\\%s^]", prefix, prefix);
if (Q_snprintf(link, sizeof(link), "^["COLOURGREEN"%s\\act\\user\\who\\%s^]", prefix, prefix) >= sizeof(link))
Q_snprintf(link, sizeof(link), "%s", prefix);
if (!strncmp(col, "\001", 1))
{
@ -2178,13 +2201,13 @@ static int IRC_ClientFrame(ircclient_t *irc)
*exc = '\0';
//fixme: print this in all channels as appropriate.
IRC_Printf(irc, DEFAULTCONSOLE, COLOURGREEN "%s changes name to %s\n", prefix, col+1);
if (BUILTINISVALID(Con_RenameSub))
if (confuncs)
{
char oldname[256];
char newname[256];
Q_snprintf(oldname, sizeof(oldname), irc->id, prefix);
Q_snprintf(newname, sizeof(newname), irc->id, col+1);
pCon_RenameSub(oldname, newname); //if we were pming to them, rename accordingly.
confuncs->RenameSub(oldname, newname); //if we were pming to them, rename accordingly.
}
}
else IRC_Printf(irc, DEFAULTCONSOLE, COLOURGREEN ":%s%s\n", prefix, msg+6);
@ -2377,7 +2400,7 @@ static int IRC_ClientFrame(ircclient_t *irc)
//functions above this line allow connections to multiple servers.
//it is just the control functions that only allow one server.
qintptr_t IRC_Frame(qintptr_t *args)
void IRC_Frame(double realtime, double gametime)
{
ircclient_t *ircclient;
if (reloadconfig)
@ -2395,7 +2418,7 @@ qintptr_t IRC_Frame(qintptr_t *args)
stat = IRC_ClientFrame(ircclient);
if (ircclient->bufferedoutammount)
{
int flushed = pNet_Send(ircclient->socket, ircclient->bufferedoutmessage, ircclient->bufferedoutammount); //FIXME: This needs rewriting to cope with errors+throttle.
int flushed = netfuncs->Send(ircclient->socket, ircclient->bufferedoutmessage, ircclient->bufferedoutammount); //FIXME: This needs rewriting to cope with errors+throttle.
if (flushed > 0)
{
memmove(ircclient->bufferedoutmessage, ircclient->bufferedoutmessage+flushed, ircclient->bufferedoutammount - flushed);
@ -2407,7 +2430,7 @@ qintptr_t IRC_Frame(qintptr_t *args)
stat = IRC_KILL;
if (stat == IRC_KILL)
{
pNet_Close(ircclient->socket);
netfuncs->Close(ircclient->socket);
ircclient->socket = invalid_handle;
IRC_Printf(ircclient, DEFAULTCONSOLE, "Disconnected from irc\n^[[Reconnect]\\act\\reconnect^]\n");
break; //lazy
@ -2415,7 +2438,6 @@ qintptr_t IRC_Frame(qintptr_t *args)
else
IRC_ICE_Frame(ircclient);
}
return 0;
}
void IRC_Command(ircclient_t *ircclient, char *dest, char *args)
@ -2458,7 +2480,7 @@ void IRC_Command(ircclient_t *ircclient, char *dest, char *args)
if (!*nick)
Q_strlcpy(nick, irc_nick.string, sizeof(nick));
if (!*nick)
pCvar_GetString("name", nick, sizeof(nick));
cvarfuncs->GetString("name", nick, sizeof(nick));
ircclient = IRC_FindAccount(server);
if (ircclient)
@ -2497,7 +2519,7 @@ void IRC_Command(ircclient_t *ircclient, char *dest, char *args)
{
msg = COM_Parse(msg, token, sizeof(token));
if (!ircclient) //not yet connected.
pCvar_SetString(irc_nick.name, token);
cvarfuncs->SetString(irc_nick.name, token);
else
{
if (!handleisvalid(ircclient->socket))
@ -2511,7 +2533,7 @@ void IRC_Command(ircclient_t *ircclient, char *dest, char *args)
else if (!strcmp(token+1, "user"))
{
msg = COM_Parse(msg, token, sizeof(token));
pCvar_SetString(irc_username.name, token);
cvarfuncs->SetString(irc_username.name, token);
if (ircclient)
IRC_SetUser(ircclient, token);

View File

@ -1,15 +0,0 @@
LCC_FLAGS=-DQ3_VM -S -Wf-target=bytecode -Wf-g
qvm:
lcc $(LCC_FLAGS) jabberclient.c; lcc $(LCC_FLAGS) ../memory.c; lcc $(LCC_FLAGS) ../plugin.c; lcc $(LCC_FLAGS) ../qvm_api.c; q3asm -f jabbercl
clean:
rm -rf $(OBJECTS) $(OUTFILE) *.qvm *.asm
all: native
native:
gcc -shared -fPIC -ggdb jabberclient.c ../qvm_api.c ../plugin.c -o jabberx86.so
install: native
cp jabberx86.so /opt/quake/fte/plugins/

View File

@ -1,22 +0,0 @@
@echo off
call ..\paths.bat
del vm\*.asm
rmdir vm
mkdir vm
cd vm
lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g ../jabberclient.c
if errorlevel 1 goto end
lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g ../../memory.c
if errorlevel 1 goto end
lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g ../../plugin.c
if errorlevel 1 goto end
lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g ../../qvm_api.c
if errorlevel 1 goto end
q3asm -f ../jabbercl
:end
cd ..
pause

File diff suppressed because it is too large Load Diff

View File

@ -72,8 +72,7 @@ static struct c2c_s *JCL_JingleAddContentToSession(jclient_t *jcl, struct c2c_s
//for msn, live.com has one, messanger.live.com has one, but messenger.live.com does NOT. seriously, the typo has more services. wtf microsoft?
//google doesn't provide a stun srv entry
//facebook doesn't provide a stun srv entry
Q_snprintf(stunhost, sizeof(stunhost), "_stun._udp.%s", jcl->domain);
if (NET_DNSLookup_SRV(stunhost, stunhost, sizeof(stunhost)))
if (Q_snprintf(stunhost, sizeof(stunhost), "_stun._udp.%s", jcl->domain) < sizeof(stunhost) && NET_DNSLookup_SRV(stunhost, stunhost, sizeof(stunhost)))
piceapi->ICE_Set(ice, "stunip", stunhost);
else
{
@ -581,10 +580,10 @@ void JCL_Join(jclient_t *jcl, const char *target, const char *sid, qboolean allo
JCL_GenLink(jcl, convolink, sizeof(convolink), NULL, target, NULL, NULL, "%s", target);
JCL_GenLink(jcl, hanguplink, sizeof(hanguplink), "jdeny", target, NULL, c2c->sid, "%s", "Hang Up");
XMPP_ConversationPrintf(b->accountdomain, b->name, "%s %s %s.\n", protocol==ICEP_VOICE?"Calling":"Requesting session with", convolink, hanguplink);
XMPP_ConversationPrintf(b->accountdomain, b->name, false, "%s %s %s.\n", protocol==ICEP_VOICE?"Calling":"Requesting session with", convolink, hanguplink);
}
else
XMPP_ConversationPrintf(b->accountdomain, b->name, "That session has expired.\n");
XMPP_ConversationPrintf(b->accountdomain, b->name, false, "That session has expired.\n");
}
else if (c2c->creator)
{
@ -592,16 +591,16 @@ void JCL_Join(jclient_t *jcl, const char *target, const char *sid, qboolean allo
//resend initiate if they've not acked it... I dunno...
JCL_JingleSend(jcl, c2c, "session-initiate");
JCL_GenLink(jcl, convolink, sizeof(convolink), NULL, target, NULL, NULL, "%s", target);
XMPP_ConversationPrintf(b->accountdomain, b->name, "Restarting session with %s.\n", convolink);
XMPP_ConversationPrintf(b->accountdomain, b->name, false, "Restarting session with %s.\n", convolink);
}
else if (c2c->accepted)
XMPP_ConversationPrintf(b->accountdomain, b->name, "That session was already accepted.\n");
XMPP_ConversationPrintf(b->accountdomain, b->name, false, "That session was already accepted.\n");
else
{
char convolink[512];
JCL_JingleSend(jcl, c2c, "session-accept");
JCL_GenLink(jcl, convolink, sizeof(convolink), NULL, target, NULL, NULL, "%s", target);
XMPP_ConversationPrintf(b->accountdomain, b->name, "Accepting session from %s.\n", convolink);
XMPP_ConversationPrintf(b->accountdomain, b->name, false, "Accepting session from %s.\n", convolink);
}
}
else
@ -611,10 +610,10 @@ void JCL_Join(jclient_t *jcl, const char *target, const char *sid, qboolean allo
char convolink[512];
JCL_JingleSend(jcl, c2c, "session-terminate");
JCL_GenLink(jcl, convolink, sizeof(convolink), NULL, target, NULL, NULL, "%s", target);
XMPP_ConversationPrintf(b->accountdomain, b->name, "Terminating session with %s.\n", convolink);
XMPP_ConversationPrintf(b->accountdomain, b->name, false, "Terminating session with %s.\n", convolink);
}
else
XMPP_ConversationPrintf(b->accountdomain, b->name, "That session has already expired.\n");
XMPP_ConversationPrintf(b->accountdomain, b->name, false, "That session has already expired.\n");
}
}
@ -853,9 +852,8 @@ static qboolean JCL_JingleHandleInitiate_GoogleSession(jclient_t *jcl, xmltree_t
JCL_GenLink(jcl, denylink, sizeof(denylink), "jdeny", from, NULL, sid, "%s", "Reject");
//show a prompt for it, send the reply when the user decides.
XMPP_ConversationPrintf(b->accountdomain, b->name,
XMPP_ConversationPrintf(b->accountdomain, b->name, true,
"%s %s. %s %s\n", convolink, offer, authlink, denylink);
pCon_SetActive(b->name);
return true;
}
else
@ -965,7 +963,7 @@ static struct c2c_s *JCL_JingleHandleInitiate(jclient_t *jcl, xmltree_t *inj, co
{
char convolink[512];
JCL_GenLink(jcl, convolink, sizeof(convolink), NULL, from, NULL, NULL, "%s", b->name);
XMPP_ConversationPrintf(b->accountdomain, b->name, "%s does not support any compatible codecs, and is unable to call you.\n", convolink);
XMPP_ConversationPrintf(b->accountdomain, b->name, false, "%s does not support any compatible codecs, and is unable to call you.\n", convolink);
if (c2c->content[c].ice)
piceapi->ICE_Close(c2c->content[c].ice);
@ -1001,14 +999,14 @@ static qboolean JCL_JingleHandleSessionTerminate(jclient_t *jcl, xmltree_t *tree
int c;
if (!c2c)
{
XMPP_ConversationPrintf(b->accountdomain, b->name, "Received session-terminate without an active session\n");
XMPP_ConversationPrintf(b->accountdomain, b->name, false, "Received session-terminate without an active session\n");
return false;
}
if (reason && reason->child)
XMPP_ConversationPrintf(b->accountdomain, b->name, "Session ended: %s\n", reason->child->name);
XMPP_ConversationPrintf(b->accountdomain, b->name, false, "Session ended: %s\n", reason->child->name);
else
XMPP_ConversationPrintf(b->accountdomain, b->name, "Session ended\n");
XMPP_ConversationPrintf(b->accountdomain, b->name, false, "Session ended\n");
//unlink it
for (link = &jcl->c2c; *link; link = &(*link)->next)
@ -1059,7 +1057,7 @@ static qboolean JCL_JingleHandleSessionAccept(jclient_t *jcl, xmltree_t *tree, c
{
return false;
}
XMPP_ConversationPrintf(b->accountdomain, b->name, "Session Accepted!\n");
XMPP_ConversationPrintf(b->accountdomain, b->name, false, "Session Accepted!\n");
// XML_ConPrintTree(tree, 0);
JCL_JingleParsePeerPorts(jcl, c2c, tree, from, XML_GetParameter(tree, "sid", ""));
@ -1305,12 +1303,12 @@ qboolean JCL_ParseJingle(jclient_t *jcl, xmltree_t *tree, const char *from, cons
{
switch(c2c->content[c].mediatype)
{
case ICEP_INVALID: break;
case ICEP_VOICE: voice = true; doprompt |= !pCvar_GetFloat("xmpp_autoacceptvoice"); break;
case ICEP_VIDEO: video = true; doprompt |= !pCvar_GetFloat("xmpp_autoacceptvoice"); break;
case ICEP_QWSERVER: server = true; doprompt |= !pCvar_GetFloat("xmpp_autoacceptjoins"); break;
case ICEP_QWCLIENT: client = true; doprompt |= !pCvar_GetFloat("xmpp_autoacceptinvites"); break;
default: doprompt |= true; break;
case ICEP_INVALID: break;
case ICEP_VOICE: voice = true; doprompt |= !cvarfuncs->GetFloat("xmpp_autoacceptvoice"); break;
case ICEP_VIDEO: video = true; doprompt |= !cvarfuncs->GetFloat("xmpp_autoacceptvoice"); break;
case ICEP_QWSERVER: server = true; doprompt |= !cvarfuncs->GetFloat("xmpp_autoacceptjoins"); break;
case ICEP_QWCLIENT: client = true; doprompt |= !cvarfuncs->GetFloat("xmpp_autoacceptinvites"); break;
default: doprompt |= true; break;
}
}
@ -1351,13 +1349,12 @@ qboolean JCL_ParseJingle(jclient_t *jcl, xmltree_t *tree, const char *from, cons
JCL_GenLink(jcl, denylink, sizeof(denylink), "jdeny", from, NULL, sid, "%s", "Reject");
//show a prompt for it, send the reply when the user decides.
XMPP_ConversationPrintf(b->accountdomain, b->name,
XMPP_ConversationPrintf(b->accountdomain, b->name, true,
"%s %s. %s %s\n", convolink, offer, authlink, denylink);
pCon_SetActive(b->accountdomain);
}
else
{
XMPP_ConversationPrintf(b->accountdomain, b->name, "Auto-accepting session from %s\n", convolink);
XMPP_ConversationPrintf(b->accountdomain, b->name, false, "Auto-accepting session from %s\n", convolink);
JCL_Join(jcl, from, sid, true, ICEP_INVALID);
}
}

View File

@ -20,14 +20,14 @@ void XMPP_FT_Frame(jclient_t *jcl)
if (ft->nexthost > 0)
{
ft->nexthost--;
ft->stream = pNet_TCPConnect(ft->streamhosts[ft->nexthost].host, ft->streamhosts[ft->nexthost].port);
ft->stream = netfuncs->TCPConnect(ft->streamhosts[ft->nexthost].host, ft->streamhosts[ft->nexthost].port);
if (ft->stream == -1)
continue;
ft->streamstatus = STRM_AUTH;
//'authenticate' with socks5 proxy. tell it that we only support 'authless'.
pNet_Send(ft->stream, "\x05\x01\x00", 3);
netfuncs->Send(ft->stream, "\x05\x01\x00", 3);
}
else
{
@ -47,13 +47,13 @@ void XMPP_FT_Frame(jclient_t *jcl)
int len;
if (ft->streamstatus == STRM_ACTIVE)
{
len = pNet_Recv(ft->stream, data, sizeof(data)-1);
len = netfuncs->Recv(ft->stream, data, sizeof(data)-1);
if (len > 0)
pFS_Write(ft->file, data, len);
filefuncs->Write(ft->file, data, len);
}
else
{
len = pNet_Recv(ft->stream, data, sizeof(data)-1);
len = netfuncs->Recv(ft->stream, data, sizeof(data)-1);
if (len > 0)
{
if (ft->streamstatus == STRM_AUTH)
@ -74,7 +74,7 @@ void XMPP_FT_Frame(jclient_t *jcl)
//connect with hostname(3).
req = va("\x05\x01%c\x03""%c%s%c%c", 0, (int)strlen(domain), domain, 0, 0);
pNet_Send(ft->stream, req, strlen(domain)+7);
netfuncs->Send(ft->stream, req, strlen(domain)+7);
ft->streamstatus = STRM_AUTHED;
}
else
@ -84,7 +84,7 @@ void XMPP_FT_Frame(jclient_t *jcl)
{
if (data[0] == 0x05 && data[1] == 0x00)
{
if (pFS_Open(ft->fname, &ft->file, 2) < 0)
if (filefuncs->Open(ft->fname, &ft->file, 2) < 0)
{
len = -1;
JCL_AddClientMessagef(jcl, "<iq id='%s' to='%s' type='error'/>", ft->iqid, ft->with);
@ -108,18 +108,18 @@ void XMPP_FT_Frame(jclient_t *jcl)
if (len == -1)
{
pNet_Close(ft->stream);
netfuncs->Close(ft->stream);
ft->stream = -1;
if (ft->streamstatus == STRM_ACTIVE)
{
int size;
if (ft->file != -1)
pFS_Close(ft->file);
filefuncs->Close(ft->file);
ft->file = -1;
size = pFS_Open(ft->fname, &ft->file, 1);
size = filefuncs->Open(ft->fname, &ft->file, 1);
if (ft->file != -1)
pFS_Close(ft->file);
filefuncs->Close(ft->file);
if (size == ft->size)
{
Con_Printf("File Transfer Completed\n");
@ -174,7 +174,7 @@ void XMPP_FT_AcceptFile(jclient_t *jcl, int fileid, qboolean accept)
}
if (ft->file != -1)
pFS_Close(ft->file);
filefuncs->Close(ft->file);
*link = ft->next;
free(ft);
}
@ -222,7 +222,7 @@ static qboolean XMPP_FT_IBBChunked(jclient_t *jcl, xmltree_t *x, struct iq_s *iq
char *base64;
char rawbuf[4096];
int sz;
sz = pFS_Read(ft->file, rawbuf, ft->blocksize);
sz = filefuncs->Read(ft->file, rawbuf, ft->blocksize);
Base64_Add(rawbuf, sz);
base64 = Base64_Finish();
@ -256,7 +256,7 @@ static qboolean XMPP_FT_IBBChunked(jclient_t *jcl, xmltree_t *x, struct iq_s *iq
//errored
if (ft->file != -1)
pFS_Close(ft->file);
filefuncs->Close(ft->file);
*link = ft->next;
free(ft);
return true;
@ -278,7 +278,7 @@ static qboolean XMPP_FT_IBBBegun(jclient_t *jcl, xmltree_t *x, struct iq_s *iq)
Con_Printf("%s aborted %s\n", ft->with, ft->fname);
//errored
if (ft->file != -1)
pFS_Close(ft->file);
filefuncs->Close(ft->file);
*link = ft->next;
free(ft);
}
@ -307,7 +307,7 @@ qboolean XMPP_FT_OfferAcked(jclient_t *jcl, xmltree_t *x, struct iq_s *iq)
Con_Printf("%s doesn't want %s\n", ft->with, ft->fname);
//errored
if (ft->file != -1)
pFS_Close(ft->file);
filefuncs->Close(ft->file);
*link = ft->next;
free(ft);
}
@ -338,19 +338,21 @@ void XMPP_FT_SendFile(jclient_t *jcl, const char *console, const char *to, const
ft = malloc(sizeof(*ft));
memset(ft, 0, sizeof(*ft));
ft->stream = -1;
ft->next = jcl->ft;
jcl->ft = ft;
ft->allowed = true;
ft->transmitting = true;
ft->blocksize = 4096;
Q_strlcpy(ft->fname, fname, sizeof(ft->fname));
Q_snprintf(ft->sid, sizeof(ft->sid), "%x%s", rand(), ft->fname);
if (Q_snprintf(ft->sid, sizeof(ft->sid), "%x%s", rand(), ft->fname) >= sizeof(ft->sid))
/*doesn't matter so long as its unique*/;
Q_strlcpy(ft->md5hash, "", sizeof(ft->md5hash));
ft->size = pFS_Open(ft->fname, &ft->file, 1);
ft->size = filefuncs->Open(ft->fname, &ft->file, 1);
ft->with = strdup(to);
ft->method = FT_IBB;
ft->begun = false;
ft->next = jcl->ft;
jcl->ft = ft;
//generate an offer.
xsi = XML_CreateNode(NULL, "si", "http://jabber.org/protocol/si", "");
XML_AddParameter(xsi, "profile", "http://jabber.org/protocol/si/profile/file-transfer");
@ -463,7 +465,7 @@ qboolean XMPP_FT_ParseIQSet(jclient_t *jcl, const char *iqfrom, const char *iqid
}
else
{ //it looks okay
pFS_Open(ft->fname, &ft->file, 2);
filefuncs->Open(ft->fname, &ft->file, 2);
ft->method = FT_IBB;
ft->blocksize = blocksize;
ft->begun = true;
@ -490,7 +492,7 @@ qboolean XMPP_FT_ParseIQSet(jclient_t *jcl, const char *iqfrom, const char *iqid
{
int size;
if (ft->file != -1)
pFS_Close(ft->file);
filefuncs->Close(ft->file);
if (ft->transmitting)
{
if (ft->eof)
@ -500,9 +502,9 @@ qboolean XMPP_FT_ParseIQSet(jclient_t *jcl, const char *iqfrom, const char *iqid
}
else
{
size = pFS_Open(ft->fname, &ft->file, 1);
size = filefuncs->Open(ft->fname, &ft->file, 1);
if (ft->file != -1)
pFS_Close(ft->file);
filefuncs->Close(ft->file);
if (size == ft->size)
Con_Printf("Received file \"%s\" successfully\n", ft->fname);
else
@ -534,7 +536,7 @@ qboolean XMPP_FT_ParseIQSet(jclient_t *jcl, const char *iqfrom, const char *iqid
blocksize = Base64_Decode(block, sizeof(block), ot->body, strlen(ot->body));
if (blocksize && blocksize <= ft->blocksize)
{
pFS_Write(ft->file, block, blocksize);
filefuncs->Write(ft->file, block, blocksize);
JCL_AddClientMessagef(jcl, "<iq id='%s' to='%s' type='result'/>", iqid, iqfrom);
return true;
}

View File

@ -1,4 +1,6 @@
#include "../plugin.h"
extern plugnetfuncs_t *netfuncs;
extern plugfsfuncs_t *filefuncs;
#include "xml.h"
@ -339,7 +341,7 @@ void JCL_ForgetBuddy(jclient_t *jcl, buddy_t *buddy, bresource_t *bres);
//quake functionality
void JCL_GenLink(jclient_t *jcl, char *out, int outlen, const char *action, const char *context, const char *contextres, const char *sid, const char *txtfmt, ...);
void Con_SubPrintf(const char *subname, const char *format, ...);
void XMPP_ConversationPrintf(const char *context, const char *title, char *format, ...);
void XMPP_ConversationPrintf(const char *context, const char *title, qboolean takefocus, char *format, ...);
//jingle functions
void JCL_Join(jclient_t *jcl, const char *target, const char *sid, qboolean allow, int protocol);

View File

@ -1,125 +0,0 @@
//a qvm compatable malloc/free interface
//This is seperate from qvm_api.c because this has a chunk of memory that simply isn't needed in all plugins.
#include "plugin.h"
struct memhead_s
{
int size;
int isfree;
struct memhead_s *next;
struct memhead_s *prev;
};
#ifndef MEMSIZE
#define MEMSIZE 1024*64 //64kb
#endif
static struct memhead_s *head;
static char memory[MEMSIZE];
//we create two dummies at the start and end
//these will never be freed
//we then have dynamic allocation in the middle.
//sizes include the headers
void *malloc(int size)
{
struct memhead_s *lasthead;
if (size <= 0)
return NULL;
size = ((size+4) & ~3) + sizeof(struct memhead_s); //round up
if (!head)
{ //first call
struct memhead_s *last;
struct memhead_s *middle;
struct memhead_s *first;
first = (struct memhead_s*)memory;
last= (struct memhead_s*)((char*)memory - sizeof(struct memhead_s));
first->size = last->size = sizeof(struct memhead_s);
first->isfree = last->isfree = false;
middle = (struct memhead_s*)((char*)first+first->size);
middle->size = sizeof(memory) - sizeof(struct memhead_s)*3;
middle->isfree = true;
last->next = first;
last->prev = middle;
first->next = middle;
first->prev = last;
middle->next = last;
middle->prev = first;
head = middle;
}
lasthead = head;
do
{
if (head->isfree)
if (head->size >= size)
{
struct memhead_s *split;
if (head->size > size + sizeof(struct memhead_s)+1)
{ //split
split = (struct memhead_s*)((char*)head + size);
split->size = head->size - size;
head->size = size;
split->next = head->next;
split->prev = head;
head->next = split;
split->next->prev = split;
split->isfree = true;
head->isfree = false;
}
else
{ //no point in splitting
head->isfree = false;
}
split = head;
head = head->next;
return (char*)split + sizeof(struct memhead_s);
}
head = head->next;
} while (lasthead != head);
Sys_Errorf("VM Out of memory on allocation of %i bytes\n", size);
return NULL;
}
static struct memhead_s *mergeblock(struct memhead_s *b1, struct memhead_s *b2)
{
//b1 and b2 must be in logical order
b1->next = b2->next;
b2->next->prev = b1;
b1->size += b2->size;
return b1;
}
void free(void *mem)
{ //the foot hopefully isn't going to be freed
struct memhead_s *block;
block = (struct memhead_s*)((char*)mem - sizeof(struct memhead_s));
if (block->isfree)
Sys_Error("(plugin) Double free\n");
block->isfree = true;
if (block->prev->isfree)
{ //merge previous with this
block = mergeblock(block->prev, block);
}
if (block->next)
{ //merge next with this
block = mergeblock(block, block->next);
}
head = (struct memhead_s*)memory;
}

View File

@ -1,10 +1,11 @@
#ifndef GLQUAKE
#define GLQUAKE //this is shit.
//#define GLQUAKE //this is shit.
#endif
#include "quakedef.h"
#include "../plugin.h"
#include "com_mesh.h"
extern modplugfuncs_t *modfuncs;
extern plugmodfuncs_t *modfuncs;
extern plugfsfuncs_t *filefuncs;
#ifdef SKELETALMODELS
#define GLTFMODELS
@ -355,6 +356,21 @@ static double JSON_GetIndexedFloat(json_t *t, unsigned int idx, double fallback)
Q_snprintf(idxname, sizeof(idxname), "%u", idx);
return JSON_GetFloat(t, idxname, fallback);
}
static const char *JSON_GetString(json_t *t, const char *child, char *buffer, size_t buffersize, const char *fallback)
{
if (child)
t = JSON_FindChild(t, child);
if (t)
{ //copy it to another buffer. can probably skip that tbh.
size_t l = t->bodyend-t->bodystart;
if (l > buffersize-1)
l = buffersize-1;
memcpy(buffer, t->bodystart, l);
buffer[l] = 0;
return buffer;
}
return fallback;
}
static void JSON_GetPath(json_t *t, qboolean ignoreroot, char *buffer, size_t buffersize)
{
@ -510,6 +526,13 @@ static size_t JSON_ReadBody(json_t *t, char *out, size_t outsize)
return t->bodyend-t->bodystart;
}
//glTF 1.0 and 2.0 differ in that 1 uses names and 2 uses indexes. There's also some significant differences with materials.
//we only support 2.0
@ -524,6 +547,11 @@ struct gltf_buffer
void *data;
size_t length;
};
struct galiasbone_gltf_s
{ //stored in galiasinfo_t->ctx
double rmatrix[16]; //gah
double quat[4], scale[3], trans[3]; //annoying smeg
};
typedef struct gltf_s
{
struct model_s *mod;
@ -538,11 +566,7 @@ typedef struct gltf_s
int camera;
double amatrix[16];
double inverse[16];
struct
{
double rmatrix[16]; //gah
double quat[4], scale[3], trans[3]; //annoying smeg
} rel;
struct galiasbone_gltf_s rel;
struct {
struct gltf_accessor *input;
@ -644,7 +668,7 @@ static struct gltf_buffer *GLTF_GetBufferData(gltf_t *gltf, int bufferidx)
char filename[MAX_QPATH];
JSON_ReadBody(uri, uritext, sizeof(uritext));
GLTF_RelativePath(gltf->mod->name, uritext, filename, sizeof(filename));
f = modfuncs->OpenVFS(filename, "rb", FS_GAME);
f = filefuncs->OpenVFS(filename, "rb", FS_GAME);
if (f)
{
out->length = VFS_GETLEN(f);
@ -775,8 +799,8 @@ static qboolean GLTF_GetAccessor(gltf_t *gltf, int accessorid, struct gltf_acces
maxs = JSON_FindChild(a, "max");
for (j = 0; j < (out->type>>8)*(out->type&0xff); j++)
{ //'must' be set in various situations.
out->mins[j] = JSON_GetIndexedInteger(mins, j, 0);
out->maxs[j] = JSON_GetIndexedInteger(maxs, j, 0);
out->mins[j] = JSON_GetIndexedFloat(mins, j, 0);
out->maxs[j] = JSON_GetIndexedFloat(maxs, j, 0);
}
// JSON_WarnIfChild(a, "sparse");
@ -1125,29 +1149,61 @@ static texid_t GLTF_LoadTexture(gltf_t *gltf, int texture, unsigned int flags)
JSON_FlagAsUsed(sampler, "name");
JSON_FlagAsUsed(sampler, "extensions");
(void)minFilter;
switch(magFilter)
{
default:
break;
case 9728: //NEAREST
flags |= IF_NOMIPMAP|IF_NEAREST;
if (minFilter != 9728)
if (gltf->warnlimit --> 0)
Con_Printf(CON_WARNING"%s: mixed min/mag filters\n", gltf->mod->name);
break;
case 9986: // NEAREST_MIPMAP_LINEAR
if (gltf->warnlimit --> 0)
Con_Printf(CON_WARNING"%s: mixed mag/mip filters\n", gltf->mod->name);
//fallthrough
case 9984: // NEAREST_MIPMAP_NEAREST
flags |= IF_NEAREST;
if (minFilter != 9728)
if (gltf->warnlimit --> 0)
Con_Printf(CON_WARNING"%s: mixed min/mag filters\n", gltf->mod->name);
break;
case 9729: //LINEAR
flags |= IF_NOMIPMAP|IF_LINEAR;
break;
case 9984: // NEAREST_MIPMAP_NEAREST
case 9986: // NEAREST_MIPMAP_LINEAR
flags |= IF_NEAREST;
if (minFilter != 9729)
if (gltf->warnlimit --> 0)
Con_Printf(CON_WARNING"%s: mixed min/mag filters\n", gltf->mod->name);
break;
case 9985: // LINEAR_MIPMAP_NEAREST
if (gltf->warnlimit --> 0)
Con_Printf(CON_WARNING"%s: mixed mag/mip filters\n", gltf->mod->name);
//fallthrough
case 9987: // LINEAR_MIPMAP_LINEAR
flags |= IF_LINEAR;
if (minFilter != 9729)
if (gltf->warnlimit --> 0)
Con_Printf(CON_WARNING"%s: mixed min/mag filters\n", gltf->mod->name);
break;
}
if (wrapS == 33071 || wrapT == 33071)
if (wrapS == 10497 && wrapT == 10497) //REPEAT
;
else if (wrapS == 33071 && wrapT == 33071) //CLAMP_TO_EDGE
flags |= IF_CLAMP;
else if (wrapS == 33648 && wrapT == 33648) //MIRRORED_REPEAT
{
if (gltf->warnlimit --> 0)
Con_Printf(CON_WARNING"%s: MIRRORED_REPEAT wrap mode not supported\n", gltf->mod->name);
}
else
{
if (gltf->warnlimit --> 0)
Con_Printf(CON_WARNING"%s: unsupported/mixed texture wrap modes %i,%i\n", gltf->mod->name, wrapS, wrapT);
if (wrapS == 33071 || wrapT == 33071)
flags |= IF_CLAMP;
}
flags |= IF_NOREPLACE;
@ -1164,6 +1220,8 @@ static galiasskin_t *GLTF_LoadMaterial(gltf_t *gltf, int material, qboolean vert
char alphaCutoffmodifier[128];
json_t *mat = JSON_FindIndexedChild(gltf->r, "materials", material);
galiasskin_t *ret;
char tmp[64];
const char *t;
json_t *nam, *unlit, *pbrsg, *pbrmr, *blinn;
@ -1175,12 +1233,19 @@ static galiasskin_t *GLTF_LoadMaterial(gltf_t *gltf, int material, qboolean vert
doubleSided = JSON_GetInteger(mat, "doubleSided", false);
alphaCutoff = JSON_GetFloat(mat, "alphaCutoff", 0.5);
if (JSON_Equals(mat, "alphaMode", "MASK"))
t = JSON_GetString(mat, "alphaMode", tmp, sizeof(tmp), "OPAQUE");
if (!strcmp(t, "MASK"))
alphaMode = 1;
else if (JSON_Equals(mat, "alphaMode", "BLEND"))
else if (!strcmp(t, "BLEND"))
alphaMode = 2;
else //if (JSON_Equals(mat, "alphaMode", "OPAQUE"))
else if (!strcmp(t, "OPAQUE"))
alphaMode = 0;
else
{
alphaMode = 0;
if (gltf->warnlimit --> 0)
Con_Printf(CON_WARNING"%s: unsupported alphaMode: %s\n", gltf->mod->name, t);
}
ret = modfuncs->ZG_Malloc(&gltf->mod->memgroup, sizeof(*ret));
ret->numframes = 1;
@ -1271,13 +1336,16 @@ static galiasskin_t *GLTF_LoadMaterial(gltf_t *gltf, int material, qboolean vert
}
else if (pbrsg)
{ //if this extension was used, then we can use rgb gloss instead of metalness stuff.
int occ = JSON_GetInteger(mat, "occlusionTexture.index", -1); //.r
ret->frame->texnums.base = GLTF_LoadTexture(gltf, JSON_GetInteger(pbrsg, "diffuseTexture.index", -1), 0);
ret->frame->texnums.specular = GLTF_LoadTexture(gltf, JSON_GetInteger(pbrsg, "specularGlossinessTexture.index", -1), 0);
if (occ != -1)
ret->frame->texnums.occlusion = GLTF_LoadTexture(gltf, occ, IF_NOSRGB);
Q_snprintf(shader, sizeof(shader),
"{\n"
"%s"//cull
"program defaultskin#SG#VC#NOOCCLUDE%s\n"
"program defaultskin#SG#VC%s%s\n"
"{\n"
"map $diffuse\n"
"%s" //blend
@ -1289,6 +1357,7 @@ static galiasskin_t *GLTF_LoadMaterial(gltf_t *gltf, int material, qboolean vert
"bemode rtlight rtlight_sg\n"
"}\n",
doubleSided?"cull disable\n":"",
(occ!=-1)?"#OCCLUDE":"",
alphaCutoffmodifier,
(alphaMode==1)?"":(alphaMode==2)?"blendfunc blend\n":"",
vertexcolours?"rgbgen vertex\nalphagen vertex\n":"",
@ -1299,7 +1368,7 @@ static galiasskin_t *GLTF_LoadMaterial(gltf_t *gltf, int material, qboolean vert
JSON_GetFloat(pbrsg, "specularFactor.0", 1),
JSON_GetFloat(pbrsg, "specularFactor.1", 1),
JSON_GetFloat(pbrsg, "specularFactor.2", 1),
JSON_GetFloat(pbrsg, "glossinessFactor", 1)*32, //this is fucked.
JSON_GetFloat(pbrsg, "glossinessFactor", 1),
JSON_GetFloat(mat, "emissiveFactor.0", 0),
JSON_GetFloat(mat, "emissiveFactor.1", 0),
JSON_GetFloat(mat, "emissiveFactor.2", 0)
@ -1315,12 +1384,9 @@ static galiasskin_t *GLTF_LoadMaterial(gltf_t *gltf, int material, qboolean vert
occ = JSON_GetInteger(mat, "extensions.MSFT_packing_occlusionRoughnessMetallic.occlusionRoughnessMetallicTexture.index", occ);
mrt = JSON_GetInteger(mat, "extensions.MSFT_packing_occlusionRoughnessMetallic.occlusionRoughnessMetallicTexture.index", mrt);
if (occ != mrt && occ != -1) //if its -1 then the mrt should have an unused channel set to 1. however, this isn't guarenteed...
{
occ = -1; //not supported. fixme: support some weird loadtexture channel merging stuff
if (gltf->warnlimit --> 0)
Con_Printf(CON_WARNING"%s: Separate occlusion and metallicRoughness textures are not supported\n", gltf->mod->name);
}
//ideally we use the ORM.r for the occlusion map, but some people just love being annoying.
if (occ != mrt && occ != -1)
ret->frame->texnums.occlusion = GLTF_LoadTexture(gltf, occ, IF_NOSRGB);
//note: extensions.MSFT_packing_normalRoughnessMetallic.normalRoughnessMetallicTexture.index gives rg=normalxy, b=roughness, .a=metalic
//(would still need an ao map, and probably wouldn't work well as bc3 either)
@ -1343,7 +1409,7 @@ static galiasskin_t *GLTF_LoadMaterial(gltf_t *gltf, int material, qboolean vert
"bemode rtlight rtlight_orm\n"
"}\n",
doubleSided?"cull disable\n":"",
(occ==-1)?"#NOOCCLUDE":"",
(occ==-1)?"#NOOCCLUDE":((occ!=mrt)?"#OCCLUDE":""),
alphaCutoffmodifier,
(alphaMode==1)?"":(alphaMode==2)?"blendfunc blend\n":"",
vertexcolours?"rgbgen vertex\nalphagen vertex\n":"",
@ -1781,23 +1847,58 @@ static qboolean GLTF_ProcessNode(gltf_t *gltf, int nodeidx, double pmatrix[16],
struct gltf_animsampler
{
struct gltf_accessor input;
struct gltf_accessor output;
enum {
AINTERP_LINEAR, //(s)lerp
AINTERP_STEP, //round down
AINTERP_CUBICSPLINE, //3 outputs per input, requires at least two inputs. messy.
} interptype;
struct gltf_accessor input; //timestamps
struct gltf_accessor output; //values
};
static void GLTF_Animation_Persist(gltf_t *gltf, struct gltf_accessor *accessor)
{
model_t *mod = gltf->mod;
qbyte *newdata = modfuncs->ZG_Malloc(&mod->memgroup, accessor->length);
memcpy(newdata, accessor->data, accessor->length);
accessor->data = newdata;
}
static struct gltf_animsampler GLTF_AnimationSampler(gltf_t *gltf, json_t *samplers, int sampleridx, int elems)
{
int outsperinput=1;
struct gltf_animsampler r;
json_t *sampler = JSON_FindIndexedChild(samplers, NULL, sampleridx);
char t[32];
const char *lerptype = JSON_GetString(sampler, "interpolation", t, sizeof(t), "LINEAR");
if (!strcmp(lerptype, "LINEAR"))
r.interptype = AINTERP_LINEAR;
else if (!strcmp(lerptype, "STEP"))
r.interptype = AINTERP_STEP;
else if (!strcmp(lerptype, "CUBICSPLINE"))
{
outsperinput = 3;
r.interptype = AINTERP_CUBICSPLINE;
}
else
{
Con_Printf("Unknown interpolation type %s\n", lerptype);
r.interptype = AINTERP_LINEAR;
}
GLTF_GetAccessor(gltf, JSON_GetInteger(sampler, "input", -1), &r.input);
GLTF_GetAccessor(gltf, JSON_GetInteger(sampler, "output", -1), &r.output);
if (!r.input.data || !r.output.data || r.input.count != r.output.count)
if (!r.input.data || !r.output.data || r.input.count*outsperinput != r.output.count)
memset(&r, 0, sizeof(r));
else
{
GLTF_Animation_Persist(gltf, &r.input);
GLTF_Animation_Persist(gltf, &r.output);
}
return r;
}
static float Anim_GetTime(struct gltf_accessor *in, int index)
static float Anim_GetTime(const struct gltf_accessor *in, int index)
{
//read the input sampler (to get timestamps)
switch(in->componentType)
@ -1815,11 +1916,11 @@ static float Anim_GetTime(struct gltf_accessor *in, int index)
case 5126: //FLOAT
return *(float*)((qbyte*)in->data + in->bytestride*index);
default:
Con_Printf("Unsupported input component type\n");
Con_Printf("Unsupported input component type %i\n", in->componentType);
return 0;
}
}
static void Anim_GetVal(struct gltf_accessor *in, int index, float *result, int elems)
static void Anim_GetVal(const struct gltf_accessor *in, int index, float *result, int elems)
{
//read the input sampler (to get timestamps)
switch(in->componentType)
@ -1849,58 +1950,136 @@ static void Anim_GetVal(struct gltf_accessor *in, int index, float *result, int
result[elems] = ((float*)((qbyte*)in->data + in->bytestride*index))[elems];
break;
default:
Con_Printf("Unsupported output component type\n");
Con_Printf("Unsupported output component type %i\n", in->componentType);
break;
}
}
static void LerpAnimData(gltf_t *gltf, struct gltf_animsampler *samp, float time, float *result, int elems)
static void QuaternionSlerp_(const vec4_t p, const vec4_t q, float t, vec4_t qt)
{
float t1, t2;
float w1, w2;
float v1[4], v2[4];
int f1 = 0, f2, c;
int i;
float omega, cosom, sinom, sclp, sclq;
vec4_t flipped;
struct gltf_accessor *in = &samp->input;
struct gltf_accessor *out = &samp->output;
// decide if one of the quaternions is backwards
float a = 0;
float b = 0;
for (i = 0; i < 4; i++) {
a += (p[i]-q[i])*(p[i]-q[i]);
b += (p[i]+q[i])*(p[i]+q[i]);
}
if (a > b) {
for (i = 0; i < 4; i++) {
flipped[i] = -q[i];
}
q = flipped;
}
t1 = t2 = Anim_GetTime(in, f1);
for (f2 = 1; f2 < in->count; f2++)
cosom = p[0]*q[0] + p[1]*q[1] + p[2]*q[2] + p[3]*q[3];
if ((1.0 + cosom) > 0.00000001) {
if ((1.0 - cosom) > 0.00000001) {
omega = acos( cosom );
sinom = sin( omega );
sclp = sin( (1.0 - t)*omega) / sinom;
sclq = sin( t*omega ) / sinom;
}
else {
sclp = 1.0 - t;
sclq = t;
}
for (i = 0; i < 4; i++) {
qt[i] = sclp * p[i] + sclq * q[i];
}
}
else {
qt[0] = -p[1];
qt[1] = p[0];
qt[2] = -p[3];
qt[3] = p[2];
sclp = sin( (1.0 - t) * 0.5 * M_PI);
sclq = sin( t * 0.5 * M_PI);
for (i = 0; i < 4; i++) {
qt[i] = sclp * p[i] + sclq * qt[i];
}
}
}
static void LerpAnimData(const struct gltf_animsampler *samp, float time, float *result, int elems)
{
float t0, t1;
float w0, w1;
float v0[4], v1[4];
int f0, f1, c;
const struct gltf_accessor *in = &samp->input;
const struct gltf_accessor *out = &samp->output;
t0 = t1 = Anim_GetTime(in, f1=f0=0);
while (time > t1 && f1 < in->count-1)
{
t2 = Anim_GetTime(in, f2);
if (t2 > time)
break; //now have before and after
t1 = t2;
f1 = f2;
t0 = t1;
f0 = f1;
f1++;
t1 = Anim_GetTime(in, f1);
}
if (time <= t1)
{ //if before the first time, clamp it.
w1 = 1;
w2 = 0;
}
else if (time >= t2)
{ //if after tha last frame we could find, clamp it to the last.
w1 = 0;
w2 = 1;
}
else
{ //assume linear
w2 = (time-t1)/(t2-t1);
// if (1) //step it. it'll still get lerped though. :(
// w2 = (w2>0.5)?1:0;
w1 = 1-w2;
}
if (w1 >= 1)
Anim_GetVal(out, f1, result, elems);
else if (w2 >= 1)
Anim_GetVal(out, f2, result, elems);
else
if (samp->interptype == AINTERP_CUBICSPLINE)
{
Anim_GetVal(out, f1, v1, elems);
Anim_GetVal(out, f2, v2, elems);
float step=t1-t0;
float t=bound(0, (time-t0)/step, 1);
float tt=t*t, ttt=tt*t;
//Hermite spline factors
float m0 = (2*ttt - 3*tt + 1);
float mb = (ttt - 2*tt + t)*step;
float m1 = (-2*ttt + 3*tt);
float ma = (ttt - tt)*step;
float a[4], b[4];
//get the relevant tangents+sample values
//<quote>When used with CUBICSPLINE interpolation, tangents (ak, bk) and values (vk) are grouped within keyframes:
//a1,a2,...an,v1,v2,...vn,b1,b2,...bn</quote>
//so ignore that and use avb,avb,avb groups...
Anim_GetVal(out, f1*3+0, a, elems);
Anim_GetVal(out, f0*3+1, v0, elems);
Anim_GetVal(out, f1*3+1, v1, elems);
Anim_GetVal(out, f0*3+2, b, elems);
//and compute the spline.
for (c = 0; c < elems; c++)
result[c] = v1[c]*w1 + w2*v2[c];
result[c] = m0*v0[c] + mb*b[c] + m1*v1[c] + ma*a[c];
//quats must be normalized.
if (elems == 4)
{
float len = sqrt(DotProduct4(result,result));
Vector4Scale(result, 1/len, result);
}
return;
}
else if (time <= t0) //if before the first time, clamp it.
w1 = 0;
else if (time >= t1) //if after tha last frame we could find, clamp it to the last.
w1 = 1;
else if (samp->interptype == AINTERP_LINEAR)
w1 = (time-t0)/(t1-t0);
else //if (samp->interptype == AINTERP_STEP)
w1 = 0;
if (w1 <= 0)
Anim_GetVal(out, f0, result, elems);
else if (w1 >= 1)
Anim_GetVal(out, f1, result, elems);
else
{
Anim_GetVal(out, f0, v0, elems);
Anim_GetVal(out, f1, v1, elems);
if (elems == 4)
QuaternionSlerp_(v0, v1, w1, result);
else
{
w0 = 1-w1;
for (c = 0; c < elems; c++)
result[c] = v0[c]*w0 + w1*v1[c];
}
}
}
@ -1953,6 +2132,63 @@ static void GLTF_RewriteBoneTree(gltf_t *gltf)
}
}
struct galiasanimation_gltf_s
{ //stored in galiasanimation_t->boneofs
float duration;
struct
{
struct gltf_animsampler rot,scale,trans;
} bone[1];
};
static float *QDECL GLTF_AnimateBones(const galiasinfo_t *surf, const galiasanimation_t *anim, float time, float *bonematrix, int numbones)
{
const struct galiasbone_gltf_s *defbone = surf->ctx;
int j = 0, l;
const struct galiasanimation_gltf_s *a = anim->boneofs;
if (anim->loop && time >= a->duration)
time = time - a->duration*floor(time/a->duration);
for (j = 0; j < numbones; j++, bonematrix+=12)
{
float scale[3];
float rot[4];
float trans[3];
//eww, weird inheritance crap.
if (a->bone[j].rot.input.data || a->bone[j].scale.input.data || a->bone[j].trans.input.data)
{
VectorCopy(defbone[j].scale, scale);
Vector4Copy(defbone[j].quat, rot);
VectorCopy(defbone[j].trans, trans);
if (a->bone[j].rot.input.data)
LerpAnimData(&a->bone[j].rot, time, rot, 4);
if (a->bone[j].scale.input.data)
LerpAnimData(&a->bone[j].scale, time, scale, 3);
if (a->bone[j].trans.input.data)
LerpAnimData(&a->bone[j].trans, time, trans, 3);
//figure out the bone matrix...
modfuncs->GenMatrixPosQuat4Scale(trans, rot, scale, bonematrix);
}
else
{ //nothing animated, use what we calculated earlier.
for (l = 0; l < 12; l++)
bonematrix[l] = defbone[j].rmatrix[l];
}
if (surf->ofsbones[j].parent < 0)
{ //rotate any root bones from gltf to quake's orientation.
float fnar[12];
static float toquake[12]={
0,0,GLTFSCALE, 0,
GLTFSCALE,0,0, 0,
0,GLTFSCALE,0, 0};
memcpy(fnar, bonematrix, sizeof(fnar));
modfuncs->ConcatTransforms((void*)toquake, (void*)fnar, (void*)bonematrix);
}
}
return bonematrix - j*12;
}
//okay, so gltf is some weird scene thing.
//mostly there should be some default scene, so we'll just use that.
//we do NOT supported nested nodes right now...
@ -1982,6 +2218,7 @@ static qboolean GLTF_LoadModel(struct model_s *mod, char *json, size_t jsonsize,
galiasanimation_t *framegroups = NULL;
unsigned int numframegroups = 0;
float *baseframe;
struct galiasbone_gltf_s *gltfbone;
memset(&gltf, 0, sizeof(gltf));
gltf.bonemap = malloc(sizeof(*gltf.bonemap)*MAX_BONES);
gltf.bones = malloc(sizeof(*gltf.bones)*MAX_BONES);
@ -2088,6 +2325,7 @@ static qboolean GLTF_LoadModel(struct model_s *mod, char *json, size_t jsonsize,
GLTF_RewriteBoneTree(&gltf);
gltfbone = modfuncs->ZG_Malloc(&mod->memgroup, sizeof(*gltfbone)*gltf.numbones);
bone = modfuncs->ZG_Malloc(&mod->memgroup, sizeof(*bone)*gltf.numbones);
baseframe = modfuncs->ZG_Malloc(&mod->memgroup, sizeof(float)*12*gltf.numbones);
for (j = 0; j < gltf.numbones; j++)
@ -2103,16 +2341,13 @@ static qboolean GLTF_LoadModel(struct model_s *mod, char *json, size_t jsonsize,
baseframe[j*12+k] = gltf.bones[j].amatrix[k];
bone[j].inverse[k] = gltf.bones[j].inverse[k];
}
gltfbone[j] = gltf.bones[j].rel;
}
for(anim = JSON_FindIndexedChild(gltf.r, "animations", 0); anim; anim = anim->sibling)
numframegroups++;
if (numframegroups)
{
struct
{
struct gltf_animsampler rot,scale,trans;
} *b = malloc(sizeof(*b)*gltf.numbones);
framegroups = modfuncs->ZG_Malloc(&mod->memgroup, sizeof(*framegroups)*numframegroups);
for (k = 0; k < numframegroups; k++)
{
@ -2120,9 +2355,9 @@ static qboolean GLTF_LoadModel(struct model_s *mod, char *json, size_t jsonsize,
json_t *anim = JSON_FindIndexedChild(gltf.r, "animations", k);
json_t *chan;
json_t *samps = JSON_FindChild(anim, "samplers");
int f, l;
// int f, l;
float maxtime = 0;
memset(b, 0, sizeof(*b)*gltf.numbones);
struct galiasanimation_gltf_s *a = modfuncs->ZG_Malloc(&mod->memgroup, sizeof(*a)+sizeof(a->bone[0])*(gltf.numbones-1));
if (!JSON_ReadBody(JSON_FindChild(anim, "name"), fg->name, sizeof(fg->name)))
{
@ -2152,11 +2387,11 @@ static qboolean GLTF_LoadModel(struct model_s *mod, char *json, size_t jsonsize,
s = GLTF_AnimationSampler(&gltf, samps, sampler, 4);
maxtime = max(maxtime, s.input.maxs[0]);
if (JSON_Equals(path, NULL, "rotation"))
b[bone].rot = s;
a->bone[bone].rot = s;
else if (JSON_Equals(path, NULL, "scale"))
b[bone].scale = s;
a->bone[bone].scale = s;
else if (JSON_Equals(path, NULL, "translation"))
b[bone].trans = s;
a->bone[bone].trans = s;
else if (gltf.warnlimit --> 0)
{ //these are unsupported
if (JSON_Equals(path, NULL, "weights")) //morph weights
@ -2166,6 +2401,8 @@ static qboolean GLTF_LoadModel(struct model_s *mod, char *json, size_t jsonsize,
}
}
a->duration = maxtime;
//TODO: make a guess at the framerate according to sampler intervals
fg->rate = 60;
fg->numposes = max(1, maxtime*fg->rate);
@ -2173,6 +2410,9 @@ static qboolean GLTF_LoadModel(struct model_s *mod, char *json, size_t jsonsize,
fg->rate = fg->numposes/maxtime; //fix up the rate so we hit the exact end of the animation (so it doesn't have to be quite so exact).
fg->skeltype = SKEL_RELATIVE;
fg->GetRawBones = GLTF_AnimateBones;
fg->boneofs = a;
#if 0
fg->boneofs = modfuncs->ZG_Malloc(&mod->memgroup, sizeof(*fg->boneofs)*12*gltf.numbones*fg->numposes);
for (f = 0; f < fg->numposes; f++)
@ -2192,11 +2432,11 @@ static qboolean GLTF_LoadModel(struct model_s *mod, char *json, size_t jsonsize,
VectorCopy(gltf.bones[j].rel.trans, trans);
if (b[j].rot.input.data)
LerpAnimData(&gltf, &b[j].rot, time, rot, 4);
LerpAnimData(&b[j].rot, time, rot, 4);
if (b[j].scale.input.data)
LerpAnimData(&gltf, &b[j].scale, time, scale, 3);
LerpAnimData(&b[j].scale, time, scale, 3);
if (b[j].trans.input.data)
LerpAnimData(&gltf, &b[j].trans, time, trans, 3);
LerpAnimData(&b[j].trans, time, trans, 3);
//figure out the bone matrix...
modfuncs->GenMatrixPosQuat4Scale(trans, rot, scale, bonematrix);
}
@ -2214,8 +2454,8 @@ static qboolean GLTF_LoadModel(struct model_s *mod, char *json, size_t jsonsize,
}
}
}
#endif
}
free(b);
}
for(surf = mod->meshinfo; surf; surf = surf->nextsurf)
@ -2223,6 +2463,7 @@ static qboolean GLTF_LoadModel(struct model_s *mod, char *json, size_t jsonsize,
surf->shares_bones = 0;
surf->numbones = gltf.numbones;
surf->ofsbones = bone;
surf->ctx = gltfbone;
surf->baseframeofs = baseframe;
surf->ofsanimations = framegroups;
surf->numanimations = numframegroups;

View File

@ -4,7 +4,8 @@
#include "quakedef.h"
#include "../plugin.h"
#include "com_mesh.h"
modplugfuncs_t *modfuncs;
plugmodfuncs_t *modfuncs;
plugfsfuncs_t *filefuncs;
//#define ASEMODELS //FIXME: TEST TEST TEST. shold be working iiuc
//#define LWOMODELS //not working
@ -812,21 +813,39 @@ static qboolean QDECL Mod_LoadLWOModel (struct model_s *mod, void *buffer, size_
}
#endif
qboolean QDECL Mod_LoadGLTFModel (struct model_s *mod, void *buffer, size_t fsize);
qboolean QDECL Mod_LoadGLBModel (struct model_s *mod, void *buffer, size_t fsize);
extern qboolean QDECL Mod_LoadGLTFModel (struct model_s *mod, void *buffer, size_t fsize);
extern qboolean QDECL Mod_LoadGLBModel (struct model_s *mod, void *buffer, size_t fsize);
extern void Mod_ExportIQM(char *fname, int flags, galiasinfo_t *mesh);
qintptr_t Plug_Init(qintptr_t *args)
qboolean Mod_ExecuteCommand(qboolean isinsecure)
{
CHECKBUILTIN(Mod_GetPluginModelFuncs);
if (BUILTINISVALID(Mod_GetPluginModelFuncs))
char tok[128];
cmdfuncs->Argv(0, tok, sizeof(tok));
if (!strcmp(tok, "exportiqm"))
{
modfuncs = pMod_GetPluginModelFuncs(sizeof(modplugfuncs_t));
if (modfuncs && modfuncs->version < MODPLUGFUNCS_VERSION)
modfuncs = NULL;
model_t *mod;
cmdfuncs->Argv(1, tok, sizeof(tok));
mod = modfuncs->GetModel(tok, true);
if (!mod || mod->type != mod_alias || !mod->meshinfo)
Con_Printf("Couldn't load \"%s\"\n", tok);
else
{
cmdfuncs->Argv(2, tok, sizeof(tok));
Mod_ExportIQM(tok, mod->flags, mod->meshinfo);
}
return true;
}
return false;
}
if (modfuncs)
qboolean Plug_Init(void)
{
filefuncs = plugfuncs->GetEngineInterface(plugfsfuncs_name, sizeof(*filefuncs));
modfuncs = plugfuncs->GetEngineInterface(plugmodfuncs_name, sizeof(*modfuncs));
if (modfuncs && modfuncs->version < MODPLUGFUNCS_VERSION)
modfuncs = NULL;
if (modfuncs && filefuncs)
{
#ifdef ASEMODELS
modfuncs->RegisterModelFormatText("ASE models (ase)", "*3DSMAX_ASCIIEXPORT", Mod_LoadASEModel);
@ -838,6 +857,9 @@ qintptr_t Plug_Init(qintptr_t *args)
modfuncs->RegisterModelFormatText("glTF2 models (glTF)", ".gltf", Mod_LoadGLTFModel);
modfuncs->RegisterModelFormatMagic("glTF2 models (glb)", (('F'<<24)+('T'<<16)+('l'<<8)+'g'), Mod_LoadGLBModel);
#endif
plugfuncs->ExportFunction("ExecuteCommand", Mod_ExecuteCommand);
cmdfuncs->AddCommand("exportiqm");
return true;
}
return false;

View File

@ -11,6 +11,7 @@
//http://www.zezula.net/en/mpq/main.html
//http://www.wc3c.net/tools/specs/QuantamMPQFormat.txt
size_t activempqcount; //number of active archives. we can't unload the dll while we still have files open.
#ifdef MULTITHREAD
threading_t *threading;
#define Sys_CreateMutex threading->CreateMutex
@ -273,6 +274,7 @@ static void MPQ_ClosePath(searchpathfuncs_t *handle)
free(mpq->hashdata);
free(mpq->listfile);
free(mpq);
activempqcount--;
}
static unsigned int MPQ_FindFile(searchpathfuncs_t *handle, flocation_t *loc, const char *name, void *hashedresult)
{
@ -517,7 +519,7 @@ static searchpathfuncs_t *MPQ_OpenArchive(vfsfile_t *file, const char *desc, con
);
}*/
activempqcount++;
mpq->references = 1;
mpq->mutex = Sys_CreateMutex();
@ -886,7 +888,12 @@ static vfsfile_t *MPQ_OpenVFS(searchpathfuncs_t *handle, flocation_t *loc, const
return &f->funcs;
}
qintptr_t Plug_Init(qintptr_t *args)
qboolean MPQ_MayShutdown(void)
{
return activempqcount==0;
}
qboolean Plug_Init(void)
{
mpq_init_cryptography();
@ -902,14 +909,14 @@ qintptr_t Plug_Init(qintptr_t *args)
//we can't cope with being closed randomly. files cannot be orphaned safely.
//so ask the engine to ensure we don't get closed before everything else is.
pPlug_ExportNative("UnsafeClose", NULL);
pPlug_ExportFunction("MayShutdown", NULL);
if (!pPlug_ExportNative("FS_RegisterArchiveType_mpq", MPQ_OpenArchive))
if (!pPlug_ExportFunction("FS_RegisterArchiveType_mpq", MPQ_OpenArchive))
{
Con_Printf("mpq: Engine doesn't support filesystem plugins\n");
return false;
}
if (!pPlug_ExportNative("FS_RegisterArchiveType_MPQ", MPQ_OpenArchive))
if (!pPlug_ExportFunction("FS_RegisterArchiveType_MPQ", MPQ_OpenArchive))
{
Con_Printf("mpq: Engine doesn't support filesystem plugins\n");
return false;

View File

@ -1,6 +0,0 @@
LCC_FLAGS=-DQ3_VM -S -Wf-target=bytecode -Wf-g
qvm:
lcc $(LCC_FLAGS) namemaker.c; lcc $(LCC_FLAGS) ../plugin.c; lcc $(LCC_FLAGS) ../qvm_api.c; q3asm -f namemaker
clean:
rm -rf $(OBJECTS) $(OUTFILE) *.qvm *.asm

Some files were not shown because too many files have changed in this diff Show More