mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-04-13 12:51:54 +00:00
Merge branch 'master' into vulkan
This commit is contained in:
commit
1a7add3f6d
309 changed files with 13119 additions and 4152 deletions
|
@ -75,8 +75,6 @@
|
|||
tools/qfvis/Makefile
|
||||
tools/qfvis/include/Makefile
|
||||
tools/qfvis/source/Makefile
|
||||
tools/qwaq/Makefile
|
||||
tools/qwaq/progs.src
|
||||
tools/wad/Makefile
|
||||
tools/wav/Makefile
|
||||
|
||||
|
@ -88,6 +86,7 @@
|
|||
ruamoko/gui/Makefile
|
||||
ruamoko/cl_menu/Makefile
|
||||
ruamoko/scheme/Makefile
|
||||
ruamoko/qwaq/Makefile
|
||||
|
||||
pkg-config/Makefile
|
||||
pkg-config/qfcc.pc
|
||||
|
|
|
@ -235,7 +235,11 @@ if test "x$ENABLE_tools_qfvis" = xyes; then
|
|||
QF_NEED(libs,[util])
|
||||
fi
|
||||
if test "x$ENABLE_tools_qwaq" = xyes; then
|
||||
QF_NEED(tools,[qwaq])
|
||||
if test "x$HAVE_PANEL" = xyes -a "x$HAVE_PTHREAD" = xyes; then
|
||||
QWAQ_TARGETS="$QWAQ_TARGETS qwaq-curses\$(EXEEXT)"
|
||||
fi
|
||||
QF_NEED(tools,[qfcc])
|
||||
QF_NEED(ruamoko,[qwaq])
|
||||
QF_NEED(libs,[ruamoko gamecode util])
|
||||
fi
|
||||
if test "x$ENABLE_tools_wad" = xyes; then
|
||||
|
@ -249,14 +253,24 @@ fi
|
|||
|
||||
QF_NEED(top, [libs hw nq qtv qw])
|
||||
|
||||
QF_PROCESS_NEED_DIRS(tools,[bsp2img carne pak qfbsp qfcc qflight qflmp qfmodelgen qfspritegen qfvis qwaq wad wav])
|
||||
QF_PROCESS_NEED_FUNC(tools,[bsp2img carne pak qfbsp qfcc qflight qflmp qfmodelgen qfspritegen qfvis qwaq wad wav], QF_NEED(top,tools))
|
||||
QF_PROCESS_NEED_DIRS(tools,[bsp2img carne pak qfbsp qfcc qflight qflmp qfmodelgen qfspritegen qfvis wad wav])
|
||||
QF_PROCESS_NEED_FUNC(tools,[bsp2img carne pak qfbsp qfcc qflight qflmp qfmodelgen qfspritegen qfvis wad wav], QF_NEED(top,tools))
|
||||
|
||||
QF_PROCESS_NEED_DIRS(libs,[util gamecode ruamoko gib audio image models video console net qw client])
|
||||
|
||||
QF_PROCESS_NEED_DIRS(ruamoko,[qwaq])
|
||||
|
||||
if test "$ENABLE_tools_qfcc" = "yes" -a "$ENABLE_tools_pak" = "yes"; then
|
||||
QF_NEED(top, [ruamoko])
|
||||
qfcc_include_qf="\$(qfcc_include_qf)"
|
||||
fi
|
||||
QF_SUBST(qfcc_include_qf)
|
||||
|
||||
if test x"${top_need_libs}" = xyes; then
|
||||
include_qf="\$(include_qf)"
|
||||
fi
|
||||
QF_SUBST(include_qf)
|
||||
|
||||
progs_gz=
|
||||
if test "$HAVE_ZLIB" = "yes"; then
|
||||
progs_gz=".gz"
|
||||
|
@ -380,6 +394,7 @@ QF_DEPS(QFCC,
|
|||
QF_DEPS(QFCC_TEST,
|
||||
[],
|
||||
[$(top_builddir)/libs/ruamoko/libQFruamoko.la
|
||||
$(top_builddir)/libs/gamecode/libQFgamecode.la
|
||||
$(top_builddir)/libs/util/libQFutil.la],
|
||||
[$(WIN32_LIBS)],
|
||||
)
|
||||
|
@ -414,6 +429,7 @@ QF_DEPS(QFVIS,
|
|||
QF_DEPS(QWAQ,
|
||||
[],
|
||||
[$(top_builddir)/libs/ruamoko/libQFruamoko.la
|
||||
$(top_builddir)/libs/gamecode/libQFgamecode.la
|
||||
$(top_builddir)/libs/util/libQFutil.la],
|
||||
[$(WIN32_LIBS)],
|
||||
)
|
||||
|
@ -421,6 +437,7 @@ QF_DEPS(CARNE,
|
|||
[],
|
||||
[$(top_builddir)/libs/gib/libQFgib.la
|
||||
$(top_builddir)/libs/ruamoko/libQFruamoko.la
|
||||
$(top_builddir)/libs/gamecode/libQFgamecode.la
|
||||
$(top_builddir)/libs/util/libQFutil.la],
|
||||
[$(WIN32_LIBS)],
|
||||
)
|
||||
|
|
|
@ -2,7 +2,7 @@ AC_ARG_ENABLE(curses,
|
|||
[ --disable-curses disable curses support]
|
||||
)
|
||||
if test "x$enable_curses" != "xno"; then
|
||||
AC_CHECK_HEADERS(curses.h)
|
||||
AC_CHECK_HEADER(curses.h)
|
||||
AC_CHECK_LIB(ncurses, initscr,
|
||||
CURSES_LIBS=-lncurses,
|
||||
AC_CHECK_LIB(pdcurses, initscr,
|
||||
|
@ -13,7 +13,32 @@ if test "x$enable_curses" != "xno"; then
|
|||
)
|
||||
)
|
||||
)
|
||||
if test "x$CURSES_LIBS" != "x"; then
|
||||
AC_DEFINE(HAVE_CURSES, 1, [Define if you have the ncurses library])
|
||||
HAVE_CURSES=yes
|
||||
else
|
||||
HAVE_CURSES=no
|
||||
fi
|
||||
else
|
||||
HAVE_CURSES=no
|
||||
CURSES_LIBS=
|
||||
fi
|
||||
AC_SUBST(CURSES_LIBS)
|
||||
|
||||
if test "x$HAVE_CURSES" == "xyes"; then
|
||||
AC_CHECK_HEADER(panel.h,
|
||||
[AC_CHECK_LIB(panel, new_panel,
|
||||
[AC_DEFINE(HAVE_PANEL, 1,
|
||||
[Define if you have the ncurses panel library])
|
||||
PANEL_LIBS=-lpanel
|
||||
HAVE_PANEL=yes],
|
||||
[HAVE_PANEL=no],
|
||||
$CURSES_LIBS
|
||||
)],
|
||||
HAVE_PANEL=no,
|
||||
[]
|
||||
)
|
||||
else
|
||||
PANEL_LIBS=
|
||||
fi
|
||||
AC_SUBST(PANEL_LIBS)
|
||||
|
|
|
@ -23,6 +23,7 @@ call_progs_main (progs_t *pr, int argc, const char **argv)
|
|||
PR_RESET_PARAMS (pr);
|
||||
P_INT (pr, 0) = argc;
|
||||
P_POINTER (pr, 1) = PR_SetPointer (pr, pr_argv);
|
||||
pr->pr_argc = 2;
|
||||
PR_ExecuteProgram (pr, progs_main);
|
||||
PR_PopFrame (pr);
|
||||
PR_Zone_Free (pr, pr_argv);
|
||||
|
|
|
@ -1566,7 +1566,7 @@ FORMULA_TRANSPARENT = YES
|
|||
# The default value is: NO.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
USE_MATHJAX = NO
|
||||
USE_MATHJAX = YES
|
||||
|
||||
# When MathJax is enabled you can set the default output format to be used for
|
||||
# the MathJax output. See the MathJax site (see:
|
||||
|
|
|
@ -1,15 +1,19 @@
|
|||
AUTOMAKE_OPTIONS = foreign
|
||||
pkgincludedir = $(includedir)/QF
|
||||
nobase_pkginclude_HEADERS = \
|
||||
#for header files that qfcc (ruamoko) will use
|
||||
pkgdatadir = $(datarootdir)/qfcc/include/QF
|
||||
|
||||
include_qf= \
|
||||
alloc.h bspfile.h cbuf.h cdaudio.h checksum.h clip_hull.h cmd.h \
|
||||
console.h crc.h csqc.h cvar.h darray.h dstring.h draw.h gib.h hash.h hl.h \
|
||||
console.h crc.h csqc.h cvar.h darray.h dstring.h draw.h gib.h hash.h \
|
||||
idparse.h image.h in_event.h info.h input.h iqm.h joystick.h keys.h \
|
||||
link.h llist.h locs.h mathlib.h mdfour.h mersenne.h model.h modelgen.h \
|
||||
msg.h object.h pak.h pakfile.h pcx.h png.h plugin.h pr_comp.h pr_debug.h \
|
||||
pr_obj.h pr_type.h progs.h qargs.h qdefs.h qendian.h qfplist.h qtypes.h \
|
||||
quakefs.h \
|
||||
quakeio.h render.h riff.h ruamoko.h screen.h script.h segtext.h set.h \
|
||||
sizebuf.h skin.h sound.h spritegn.h sys.h teamplay.h tga.h uint32.h va.h \
|
||||
quakeio.h render.h riff.h ringbuffer.h ruamoko.h \
|
||||
screen.h script.h segtext.h set.h \
|
||||
sizebuf.h skin.h sound.h spritegn.h sys.h teamplay.h tga.h va.h \
|
||||
ver_check.h vid.h vrect.h view.h wad.h wadfile.h winding.h zone.h \
|
||||
\
|
||||
GL/ati.h GL/defines.h GL/extensions.h GL/funcs.h GL/qf_draw.h \
|
||||
|
@ -26,3 +30,9 @@ nobase_pkginclude_HEADERS = \
|
|||
\
|
||||
plugin/cd.h plugin/console.h plugin/general.h plugin/input.h \
|
||||
plugin/snd_output.h plugin/snd_render.h plugin/vid_render.h
|
||||
|
||||
qfcc_include_qf=keys.h
|
||||
nobase_pkginclude_HEADERS = @include_qf@
|
||||
pkgdata_DATA=@qfcc_include_qf@
|
||||
|
||||
EXTRA_HEADERS = $(include_qf) $(qfcc_include_qf)
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
Boston, MA 02111-1307, USA
|
||||
|
||||
*/
|
||||
#ifndef __bspfile_h_
|
||||
#define __bspfile_h_
|
||||
#ifndef __QF_bspfile_h
|
||||
#define __QF_bspfile_h
|
||||
|
||||
#include "QF/qtypes.h"
|
||||
#include "QF/quakeio.h"
|
||||
|
@ -310,4 +310,4 @@ void BSP_AddVisibility (bsp_t *bsp, const byte *visdata, size_t visdatasize);
|
|||
void BSP_AddEntities (bsp_t *bsp, const char *entdata, size_t entdatasize);
|
||||
void BSP_AddTextures (bsp_t *bsp, const byte *texdata, size_t texdatasize);
|
||||
|
||||
#endif//__bspfile_h_
|
||||
#endif//__QF_bspfile_h
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef _CDAUDIO_H
|
||||
#define _CDAUDIO_H
|
||||
#ifndef __QF_cdaudio_h
|
||||
#define __QF_cdaudio_h
|
||||
|
||||
#include "QF/qtypes.h"
|
||||
|
||||
|
@ -37,4 +37,4 @@ void CDAudio_Pause(void);
|
|||
void CDAudio_Resume(void);
|
||||
void CDAudio_Update(void);
|
||||
|
||||
#endif // _CDAUDIO_H
|
||||
#endif//__QF_cdaudio_h
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef __checksum_h
|
||||
#define __checksum_h
|
||||
#ifndef __QF_checksum_h
|
||||
#define __QF_checksum_h
|
||||
|
||||
/** \addtogroup crc
|
||||
*/
|
||||
|
@ -40,4 +40,4 @@ byte COM_BlockSequenceCRCByte (const byte *base, int length, int sequence);
|
|||
|
||||
///@}
|
||||
|
||||
#endif // __checksum_h
|
||||
#endif//__QF_checksum_h
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef __console_h
|
||||
#define __console_h
|
||||
#ifndef __QF_console_h
|
||||
#define __QF_console_h
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
|
@ -150,4 +150,4 @@ void Menu_Leave_f (void);
|
|||
void Menu_Prev_f (void);
|
||||
void Menu_Next_f (void);
|
||||
|
||||
#endif // __console_h
|
||||
#endif//__QF_console_h
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef __crc_h
|
||||
#define __crc_h
|
||||
#ifndef __QF_crc_h
|
||||
#define __QF_crc_h
|
||||
|
||||
/** \defgroup crc Checksum generation.
|
||||
\ingroup utils
|
||||
|
@ -43,4 +43,4 @@ unsigned short CRC_Block (const byte *start, int count) __attribute__((pure));
|
|||
|
||||
///@}
|
||||
|
||||
#endif // __crc_h
|
||||
#endif//__QF_crc_h
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef __cvar_h
|
||||
#define __cvar_h
|
||||
#ifndef __QF_cvar_h
|
||||
#define __QF_cvar_h
|
||||
|
||||
/** \defgroup cvar Configuration variables
|
||||
\ingroup utils
|
||||
|
@ -140,4 +140,4 @@ extern cvar_t *cvar_vars;
|
|||
|
||||
///@}
|
||||
|
||||
#endif // __cvar_h
|
||||
#endif//__QF_cvar_h
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef _DRAW_H
|
||||
#define _DRAW_H
|
||||
#ifndef __QF_draw_h
|
||||
#define __QF_draw_h
|
||||
|
||||
/** \defgroup video Video Sub-sytem */
|
||||
|
||||
|
@ -234,4 +234,4 @@ void Draw_Picf (float x, float y, qpic_t *pic);
|
|||
void Draw_SubPic(int x, int y, qpic_t *pic, int srcx, int srcy, int width, int height);
|
||||
///@}
|
||||
|
||||
#endif // _DRAW_H
|
||||
#endif//__QF_draw_h
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef __dstring_h
|
||||
#define __dstring_h
|
||||
#ifndef __QF_dstring_h
|
||||
#define __QF_dstring_h
|
||||
|
||||
/** \defgroup dstring Dynamic Strings
|
||||
\ingroup utils
|
||||
|
@ -164,17 +164,17 @@ void dstring_clearstr (dstring_t *dstr);
|
|||
/** Formatted printing to dstrings. Existing data is replaced by the formatted
|
||||
string.
|
||||
*/
|
||||
int dvsprintf (dstring_t *dstr, const char *fmt, va_list args) __attribute__((format(printf,2,0)));
|
||||
int dsprintf (dstring_t *dstr, const char *fmt, ...) __attribute__((format(printf,2,3)));
|
||||
char *dvsprintf (dstring_t *dstr, const char *fmt, va_list args) __attribute__((format(printf,2,0)));
|
||||
char *dsprintf (dstring_t *dstr, const char *fmt, ...) __attribute__((format(printf,2,3)));
|
||||
///@}
|
||||
///@{
|
||||
/** Formatted printing to dstrings. Formatted string is appened to the dstring.
|
||||
Embedded nulls in the dstring are ignored.
|
||||
*/
|
||||
int davsprintf (dstring_t *dstr, const char *fmt, va_list args) __attribute__((format(printf,2,0)));
|
||||
int dasprintf (dstring_t *dstr, const char *fmt, ...) __attribute__((format(printf,2,3)));
|
||||
char *davsprintf (dstring_t *dstr, const char *fmt, va_list args) __attribute__((format(printf,2,0)));
|
||||
char *dasprintf (dstring_t *dstr, const char *fmt, ...) __attribute__((format(printf,2,3)));
|
||||
///@}
|
||||
|
||||
///@}
|
||||
|
||||
#endif // __dstring_h
|
||||
#endif//__QF_dstring_h
|
||||
|
|
|
@ -28,8 +28,8 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef __gib_h
|
||||
#define __gib_h
|
||||
#ifndef __QF_gib_h
|
||||
#define __QF_gib_h
|
||||
|
||||
// Dependencies
|
||||
|
||||
|
@ -216,4 +216,4 @@ unsigned long int GIB_Handle_New (gib_object_t *data);
|
|||
void GIB_Handle_Free (unsigned long int num);
|
||||
gib_object_t *GIB_Handle_Get (unsigned long int num) __attribute__((pure));
|
||||
|
||||
#endif
|
||||
#endif//__QF_gib_h
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef __hash_h
|
||||
#define __hash_h
|
||||
#ifndef __QF_hash_h
|
||||
#define __QF_hash_h
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -211,4 +211,4 @@ void Hash_Stats (hashtab_t *tab);
|
|||
|
||||
///@}
|
||||
|
||||
#endif // __hash_h
|
||||
#endif//__QF_hash_h
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
/*
|
||||
hl_bsp.h
|
||||
|
||||
Half Life file definitions
|
||||
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _HL_BSP_H
|
||||
#define _HL_BSP_H
|
||||
|
||||
#include "QF/qtypes.h"
|
||||
|
||||
extern void CL_ParseEntityLump(const char *entdata);
|
||||
extern void HL_Mod_LoadLighting (lump_t *l);
|
||||
extern void HL_Mod_LoadTextures (lump_t *l);
|
||||
extern byte *W_GetTexture(const char *name, int matchwidth, int matchheight);
|
||||
extern void W_LoadTextureWadFile (const char *filename, int complain);
|
||||
|
||||
#endif // _HL_BSP_H
|
|
@ -49,4 +49,4 @@ typedef struct tex_s {
|
|||
|
||||
tex_t *LoadImage (const char *imageFile);
|
||||
|
||||
#endif //__QF_image_h
|
||||
#endif//__QF_image_h
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef _INFO_H
|
||||
#define _INFO_H
|
||||
#ifndef __QF_info_h
|
||||
#define __QF_info_h
|
||||
|
||||
/** \defgroup info Info Keys
|
||||
\ingroup utils
|
||||
|
@ -65,4 +65,4 @@ void Info_AddKeys (info_t *info, info_t *keys);
|
|||
|
||||
///@}
|
||||
|
||||
#endif // _INFO_H
|
||||
#endif//__QF_info_h
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef __QF_input_h_
|
||||
#define __QF_input_h_
|
||||
#ifndef __QF_input_h
|
||||
#define __QF_input_h
|
||||
|
||||
#include "QF/keys.h"
|
||||
|
||||
|
@ -73,4 +73,4 @@ void IN_LL_Grab_Input (int grab);
|
|||
|
||||
extern kbutton_t in_strafe, in_klook, in_speed, in_mlook;
|
||||
|
||||
#endif // __QF_input_h_
|
||||
#endif//__QF_input_h
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef __QF_iqm_h__
|
||||
#define __QF_iqm_h__
|
||||
#ifndef __QF_iqm_h
|
||||
#define __QF_iqm_h
|
||||
|
||||
#include "QF/qtypes.h"
|
||||
|
||||
|
@ -149,4 +149,4 @@ typedef struct {
|
|||
void *extra_data;
|
||||
} iqm_t;
|
||||
|
||||
#endif//__QF_iqm_h__
|
||||
#endif//__QF_iqm_h
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef __QF_joystick_h_
|
||||
#define __QF_joystick_h_
|
||||
#ifndef __QF_joystick_h
|
||||
#define __QF_joystick_h
|
||||
|
||||
#include <QF/qtypes.h>
|
||||
#include "QF/quakeio.h"
|
||||
|
@ -154,4 +154,4 @@ int JOY_GetAxis_i (int dest, const char *c);
|
|||
|
||||
void Joy_WriteBindings (QFile *f);
|
||||
|
||||
#endif // __QF_joystick_h_
|
||||
#endif//__QF_joystick_h
|
||||
|
|
|
@ -26,8 +26,8 @@
|
|||
*/
|
||||
|
||||
|
||||
#ifndef _KEYS_H
|
||||
#define _KEYS_H
|
||||
#ifndef __QF_keys_h
|
||||
#define __QF_keys_h
|
||||
|
||||
#ifndef __QFCC__
|
||||
# include "QF/qtypes.h"
|
||||
|
@ -661,4 +661,4 @@ void Key_Progs_Init (struct progs_s *pr);
|
|||
|
||||
///@}
|
||||
|
||||
#endif // _KEYS_H
|
||||
#endif//__QF_keys_h
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef _LINK_H
|
||||
#define _LINK_H
|
||||
#ifndef __QF_link_h
|
||||
#define __QF_link_h
|
||||
|
||||
// (type *)STRUCT_FROM_LINK(link_t *link, type, member)
|
||||
// ent = STRUCT_FROM_LINK(link,entity_t,order)
|
||||
|
@ -43,4 +43,4 @@ void RemoveLink (link_t *l);
|
|||
void InsertLinkBefore (link_t *l, link_t *before);
|
||||
void InsertLinkAfter (link_t *l, link_t *after);
|
||||
|
||||
#endif // _LINK_H
|
||||
#endif//__QF_link_h
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef _LLIST_H
|
||||
#define _LLIST_H
|
||||
#ifndef __QF_llist_h
|
||||
#define __QF_llist_h
|
||||
|
||||
#include "QF/qtypes.h"
|
||||
|
||||
|
@ -112,4 +112,4 @@ void *llist_createarray (llist_t *list, size_t esize);
|
|||
|
||||
//@}
|
||||
|
||||
#endif
|
||||
#endif//__QF_llist_h
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef __locs_h
|
||||
#define __locs_h
|
||||
#ifndef __QF_locs_h
|
||||
#define __QF_locs_h
|
||||
|
||||
#include "QF/qtypes.h"
|
||||
|
||||
|
@ -47,4 +47,4 @@ void locs_reset (void);
|
|||
void locs_save (const char *filename, qboolean gz);
|
||||
void map_to_loc (const char *mapname, char *filename);
|
||||
|
||||
#endif // __locs_h
|
||||
#endif//__QF_locs_h
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef __mathlib_h
|
||||
#define __mathlib_h
|
||||
#ifndef __QF_mathlib_h
|
||||
#define __QF_mathlib_h
|
||||
|
||||
/** \defgroup mathlib Vector and matrix functions
|
||||
\ingroup utils
|
||||
|
@ -220,4 +220,4 @@ void BarycentricCoords (const vec_t **points, int num_points, const vec3_t p,
|
|||
|
||||
///@}
|
||||
|
||||
#endif // __mathlib_h
|
||||
#endif//__QF_mathlib_h
|
||||
|
|
|
@ -26,20 +26,20 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef __mdfour_h
|
||||
#define __mdfour_h
|
||||
#ifndef __QF_mdfour_h
|
||||
#define __QF_mdfour_h
|
||||
|
||||
#include "QF/qtypes.h"
|
||||
|
||||
/** \addtogroup crc
|
||||
*/
|
||||
///@{
|
||||
|
||||
#include "QF/uint32.h"
|
||||
|
||||
#define MDFOUR_DIGEST_BYTES 16
|
||||
|
||||
struct mdfour {
|
||||
uint32 A, B, C, D;
|
||||
uint32 totalN;
|
||||
uint32_t A, B, C, D;
|
||||
uint32_t totalN;
|
||||
};
|
||||
|
||||
void mdfour_begin(struct mdfour *md); // old: MD4Init
|
||||
|
@ -49,4 +49,4 @@ void mdfour(unsigned char *out, const unsigned char *in, int n);
|
|||
|
||||
///@}
|
||||
|
||||
#endif // __mdfour_h
|
||||
#endif//__QF_mdfour_h
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef _MODEL_H
|
||||
#define _MODEL_H
|
||||
#ifndef __QF_model_h
|
||||
#define __QF_model_h
|
||||
|
||||
#include "QF/qtypes.h"
|
||||
#include "QF/bspfile.h"
|
||||
|
@ -468,4 +468,4 @@ extern byte *mod_base;
|
|||
extern byte mod_novis[MAX_MAP_LEAFS / 8];
|
||||
extern int mod_lightmap_bytes;
|
||||
|
||||
#endif // _MODEL_H
|
||||
#endif//__QF_model_h
|
||||
|
|
|
@ -31,8 +31,8 @@
|
|||
// * pass data from one to the other via model files. *
|
||||
// *********************************************************
|
||||
|
||||
#ifndef _MODELGEN_H
|
||||
#define _MODELGEN_H
|
||||
#ifndef __QF_modelgen_h
|
||||
#define __QF_modelgen_h
|
||||
|
||||
#include "QF/mathlib.h"
|
||||
|
||||
|
@ -142,4 +142,4 @@ typedef struct {
|
|||
// little-endian "IDP2"
|
||||
#define IDHEADER_MD2 (('2'<<24)+('P'<<16)+('D'<<8)+'I')
|
||||
|
||||
#endif // _MODELGEN_H
|
||||
#endif//__QF_modelgen_h
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
Boston, MA 02111-1307, USA
|
||||
|
||||
*/
|
||||
#ifndef _MSG_H
|
||||
#define _MSG_H
|
||||
#ifndef __QF_msg_h
|
||||
#define __QF_msg_h
|
||||
|
||||
/** \defgroup msg Message reading and writing
|
||||
\ingroup utils
|
||||
|
@ -251,4 +251,4 @@ int MSG_ReadUTF8 (qmsg_t *msg);
|
|||
|
||||
///@}
|
||||
|
||||
#endif
|
||||
#endif//__QF_msg_h
|
||||
|
|
|
@ -32,8 +32,8 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef __object_h
|
||||
#define __object_h
|
||||
#ifndef __QF_object_h
|
||||
#define __QF_object_h
|
||||
|
||||
#include "QF/qtypes.h"
|
||||
|
||||
|
@ -115,4 +115,4 @@ void Object_Garbage_Collect (void);
|
|||
|
||||
#include "QF/classes/String.h"
|
||||
|
||||
#endif
|
||||
#endif//__QF_object_h
|
||||
|
|
|
@ -28,8 +28,8 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef __qf_pak_h
|
||||
#define __qf_pak_h
|
||||
#ifndef __QF_pak_h
|
||||
#define __QF_pak_h
|
||||
|
||||
/** \addtogroup pak
|
||||
*/
|
||||
|
@ -53,4 +53,4 @@ typedef struct {
|
|||
|
||||
///@}
|
||||
|
||||
#endif//__qf_pak_h
|
||||
#endif//__QF_pak_h
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
#ifndef __pcx_h
|
||||
#define __pcx_h
|
||||
#ifndef __QF_pcx_h
|
||||
#define __QF_pcx_h
|
||||
|
||||
#include "QF/qtypes.h"
|
||||
#include "QF/quakeio.h"
|
||||
|
@ -77,4 +77,4 @@ pcx_t *EncodePCX (byte *data, int width, int height, int rowbytes,
|
|||
*/
|
||||
struct tex_s *LoadPCX (QFile *f, qboolean convert, byte *pal);
|
||||
|
||||
#endif // __pcx_h
|
||||
#endif//__QF_pcx_h
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef __QF_plugin_h_
|
||||
#define __QF_plugin_h_
|
||||
#ifndef __QF_plugin_h
|
||||
#define __QF_plugin_h
|
||||
|
||||
/** \defgroup plugin Plugins
|
||||
\ingroup utils
|
||||
|
@ -113,4 +113,4 @@ void PI_Shutdown (void);
|
|||
|
||||
///@}
|
||||
|
||||
#endif // __QF_plugin_h_
|
||||
#endif//__QF_plugin_h
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
*/
|
||||
|
||||
// this file is shared by QuakeForge and qfcc
|
||||
#ifndef __pr_comp_h
|
||||
#define __pr_comp_h
|
||||
#ifndef __QF_pr_comp_h
|
||||
#define __QF_pr_comp_h
|
||||
|
||||
#include "QF/qtypes.h"
|
||||
|
||||
|
@ -27,7 +27,7 @@ typedef int16_t pr_short_t;
|
|||
typedef uint16_t pr_ushort_t;
|
||||
typedef int32_t pr_int_t;
|
||||
typedef uint32_t pr_uint_t;
|
||||
typedef pr_int_t func_t;
|
||||
typedef pr_uint_t func_t;
|
||||
typedef pr_int_t string_t;
|
||||
typedef pr_uint_t pointer_t;
|
||||
|
||||
|
@ -50,8 +50,8 @@ typedef enum {
|
|||
ev_type_count // not a type, gives number of types
|
||||
} etype_t;
|
||||
|
||||
extern int pr_type_size[ev_type_count];
|
||||
extern const char *pr_type_name[ev_type_count];
|
||||
extern const pr_ushort_t pr_type_size[ev_type_count];
|
||||
extern const char * const pr_type_name[ev_type_count];
|
||||
|
||||
#define OFS_NULL 0
|
||||
#define OFS_RETURN 1
|
||||
|
@ -395,7 +395,12 @@ typedef enum {
|
|||
OP_MOD_I,
|
||||
OP_MOD_F,
|
||||
OP_MOD_D,
|
||||
|
||||
OP_MEMSETI,
|
||||
OP_MEMSETP,
|
||||
OP_MEMSETPI,
|
||||
} pr_opcode_e;
|
||||
#define OP_BREAK 0x8000
|
||||
|
||||
typedef struct opcode_s {
|
||||
const char *name;
|
||||
|
@ -407,9 +412,9 @@ typedef struct opcode_s {
|
|||
const char *fmt;
|
||||
} opcode_t;
|
||||
|
||||
extern opcode_t pr_opcodes[];
|
||||
extern const opcode_t pr_opcodes[];
|
||||
opcode_t *PR_Opcode (pr_short_t opcode);
|
||||
void PR_Opcode_Init (void);
|
||||
void PR_Opcode_Init (void); // idempotent
|
||||
|
||||
typedef struct dstatement_s {
|
||||
pr_opcode_e op:16;
|
||||
|
@ -417,12 +422,30 @@ typedef struct dstatement_s {
|
|||
} GCC_STRUCT dstatement_t;
|
||||
|
||||
typedef struct ddef_s {
|
||||
pr_ushort_t type; // if DEF_SAVEGLOBGAL bit is set
|
||||
pr_ushort_t type; // if DEF_SAVEGLOBAL bit is set
|
||||
// the variable needs to be saved in savegames
|
||||
pr_ushort_t ofs;
|
||||
pr_int_t s_name;
|
||||
string_t s_name;
|
||||
} ddef_t;
|
||||
|
||||
typedef struct xdef_s {
|
||||
pointer_t type; ///< pointer to type definition
|
||||
pointer_t ofs; ///< 32-bit version of ddef_t.ofs
|
||||
} xdef_t;
|
||||
|
||||
typedef struct pr_xdefs_s {
|
||||
pointer_t xdefs;
|
||||
pr_int_t num_xdefs;
|
||||
} pr_xdefs_t;
|
||||
|
||||
typedef struct pr_def_s {
|
||||
pr_ushort_t type;
|
||||
pr_ushort_t size; ///< may not be correct
|
||||
pointer_t ofs;
|
||||
string_t name;
|
||||
pointer_t type_encoding;
|
||||
} pr_def_t;
|
||||
|
||||
typedef struct dparmsize_s {
|
||||
uint8_t size:5;
|
||||
uint8_t alignment:3;
|
||||
|
@ -435,11 +458,11 @@ typedef struct dparmsize_s {
|
|||
typedef struct dfunction_s {
|
||||
pr_int_t first_statement; // negative numbers are builtins
|
||||
pr_int_t parm_start;
|
||||
pr_int_t locals; // total ints of parms + locals
|
||||
pr_uint_t locals; // total ints of parms + locals
|
||||
|
||||
pr_int_t profile; // runtime
|
||||
pr_uint_t profile; // runtime
|
||||
|
||||
pr_int_t s_name;
|
||||
string_t s_name;
|
||||
pr_int_t s_file; // source file defined in
|
||||
|
||||
pr_int_t numparms;
|
||||
|
@ -484,10 +507,10 @@ typedef struct dprograms_s {
|
|||
pr_uint_t numfielddefs;
|
||||
|
||||
pr_uint_t ofs_functions;
|
||||
pr_int_t numfunctions; // function 0 is an empty
|
||||
pr_uint_t numfunctions; // function 0 is an empty
|
||||
|
||||
pr_uint_t ofs_strings;
|
||||
pr_int_t numstrings; // first string is a null string
|
||||
pr_uint_t numstrings; // first string is a null string
|
||||
|
||||
pr_uint_t ofs_globals;
|
||||
pr_uint_t numglobals;
|
||||
|
@ -495,4 +518,4 @@ typedef struct dprograms_s {
|
|||
pr_uint_t entityfields;
|
||||
} dprograms_t;
|
||||
|
||||
#endif // __pr_comp_h
|
||||
#endif//__QF_pr_comp_h
|
||||
|
|
|
@ -28,8 +28,8 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef __pr_debug_h
|
||||
#define __pr_debug_h
|
||||
#ifndef __QF_pr_debug_h
|
||||
#define __QF_pr_debug_h
|
||||
|
||||
#include "QF/pr_comp.h"
|
||||
|
||||
|
@ -39,8 +39,7 @@ typedef struct pr_auxfunction_s {
|
|||
pr_uint_t line_info; // index to first lineno entry
|
||||
pr_uint_t local_defs; // index to the first local def
|
||||
pr_uint_t num_locals; // number of local defs
|
||||
pr_short_t return_type; // return type of this function
|
||||
pr_short_t reserved;
|
||||
pr_uint_t return_type; // return type of this function
|
||||
} pr_auxfunction_t;
|
||||
|
||||
typedef struct pr_lineno_s {
|
||||
|
@ -51,7 +50,7 @@ typedef struct pr_lineno_s {
|
|||
pr_uint_t line;
|
||||
} pr_lineno_t;
|
||||
|
||||
#define PROG_DEBUG_VERSION 0x00001002 // MMmmmRRR 0.001.002 (hex)
|
||||
#define PROG_DEBUG_VERSION 0x00001003 // MMmmmRRR 0.001.002 (hex)
|
||||
|
||||
typedef struct pr_debug_header_s {
|
||||
pr_int_t version;
|
||||
|
@ -65,4 +64,4 @@ typedef struct pr_debug_header_s {
|
|||
pr_uint_t num_locals;
|
||||
} pr_debug_header_t;
|
||||
|
||||
#endif//__pr_debug_h
|
||||
#endif//__QF_pr_debug_h
|
||||
|
|
|
@ -28,8 +28,8 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef __pr_obj_h
|
||||
#define __pr_obj_h
|
||||
#ifndef __QF_pr_obj_h
|
||||
#define __QF_pr_obj_h
|
||||
|
||||
#include "QF/pr_comp.h"
|
||||
|
||||
|
@ -94,7 +94,7 @@ typedef struct pr_class_s {
|
|||
pr_int_t instance_size;
|
||||
pointer_t ivars; // pr_ivar_list_t
|
||||
pointer_t methods; // pr_method_list_t
|
||||
pointer_t dtable;
|
||||
pointer_t dtable; // resource index
|
||||
pointer_t subclass_list; // pr_class_t
|
||||
pointer_t sibling_class; // pr_class_t
|
||||
pointer_t protocols; // pr_protocol_list_t
|
||||
|
@ -185,4 +185,4 @@ typedef struct pr_super_s {
|
|||
pointer_t class;
|
||||
} pr_super_t;
|
||||
|
||||
#endif//__pr_obj_h
|
||||
#endif//__QF_pr_obj_h
|
||||
|
|
|
@ -28,8 +28,8 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef __pr_type_h
|
||||
#define __pr_type_h
|
||||
#ifndef __QF_pr_type_h
|
||||
#define __QF_pr_type_h
|
||||
|
||||
/** \defgroup qfcc_qfo_type Object file type encoding
|
||||
\ingroup progs
|
||||
|
@ -40,6 +40,16 @@
|
|||
|
||||
#include "QF/pr_comp.h"
|
||||
|
||||
typedef enum {
|
||||
ty_basic, ///< VM type (float, int, pointer, field, etc)
|
||||
ty_struct,
|
||||
ty_union,
|
||||
ty_enum,
|
||||
ty_array,
|
||||
ty_class,
|
||||
} ty_meta_e;
|
||||
|
||||
|
||||
typedef struct qfot_fldptr_s {
|
||||
pr_int_t type; ///< ev_field or ev_pointer
|
||||
pointer_t aux_type; ///< referenced type
|
||||
|
@ -88,20 +98,20 @@ typedef struct qfot_type_s {
|
|||
pr_int_t size; ///< total word size of this encoding
|
||||
string_t encoding; ///< Objective-QC encoding
|
||||
union {
|
||||
pr_int_t type; ///< basic type: etype_t
|
||||
qfot_fldptr_t fldptr; ///< ty_none, ev_pointer/ev_field
|
||||
qfot_func_t func; ///< ty_none, ev_func
|
||||
pr_int_t type; ///< ty_basic: etype_t
|
||||
qfot_fldptr_t fldptr; ///< ty_basic, ev_pointer/ev_field
|
||||
qfot_func_t func; ///< ty_basic, ev_func
|
||||
qfot_struct_t strct; ///< ty_struct/ty_union/ty_enum
|
||||
qfot_array_t array; ///< ty_array
|
||||
pointer_t class; ///< ty_class
|
||||
string_t class; ///< ty_class
|
||||
} t;
|
||||
} qfot_type_t;
|
||||
|
||||
typedef struct qfot_type_encodings_s {
|
||||
pointer_t types;
|
||||
pr_int_t size;
|
||||
pr_uint_t size;
|
||||
} qfot_type_encodings_t;
|
||||
|
||||
///@}
|
||||
|
||||
#endif//__pr_type_h
|
||||
#endif//__QF_pr_type_h
|
||||
|
|
|
@ -53,8 +53,12 @@ typedef struct edict_s edict_t;
|
|||
///@{
|
||||
|
||||
/** Initialize the progs engine.
|
||||
|
||||
The first call will initialize subsystems common to all progs instances.
|
||||
|
||||
\param pr The progs engine instance to initialize.
|
||||
*/
|
||||
void PR_Init (void);
|
||||
void PR_Init (progs_t *pr);
|
||||
|
||||
/** Initialize the Cvars for the progs engine. Call before calling PR_Init().
|
||||
*/
|
||||
|
@ -87,15 +91,63 @@ void PR_RunError (progs_t *pr, const char *error, ...) __attribute__((format(pri
|
|||
(pr)->pr_params[1] = (pr)->pr_real_params[1]; \
|
||||
} while (0)
|
||||
|
||||
/** Save the current parameters.
|
||||
\param pr pointer to ::progs_t VM struct
|
||||
/** \name Detouring Function Calls
|
||||
|
||||
These functions allow a builtin function that uses PR_CallFunction() to
|
||||
safely insert a call to another VM function. The +initialize diversion
|
||||
required by Objective-QuakeC uses this.
|
||||
|
||||
PR_PushFrame (pr);
|
||||
__auto_type params = PR_SaveParams (pr);
|
||||
... set up parameters to detour_function
|
||||
PR_ExecuteProgram (pr, detour_function)
|
||||
PR_RestoreParams (pr, params);
|
||||
PR_PopFrame (pr);
|
||||
|
||||
*/
|
||||
void PR_SaveParams (progs_t *pr);
|
||||
///@{
|
||||
typedef struct pr_stashed_params_s {
|
||||
pr_type_t *param_ptrs[2];
|
||||
int argc;
|
||||
pr_type_t params[1];
|
||||
} pr_stashed_params_t;
|
||||
|
||||
/** Save the current parameters to the provided stash.
|
||||
|
||||
\warning The memory for the parameter stash is allocated using
|
||||
alloca().
|
||||
|
||||
\param pr pointer to ::progs_t VM struct
|
||||
\return Pointer to a newly allocated and initialized parameter
|
||||
stash that has the current parameters saved to it.
|
||||
\hideinitializer
|
||||
*/
|
||||
#define PR_SaveParams(pr) \
|
||||
_PR_SaveParams((pr), \
|
||||
alloca (field_offset (pr_stashed_params_t, \
|
||||
params[(pr)->pr_argc \
|
||||
* (pr)->pr_param_size])))
|
||||
|
||||
/** [INTERNAL] Save the current parameters to the provided stash.
|
||||
|
||||
\warning Requires \a params to be correctly allocated. Use
|
||||
PR_SaveParams instead as it will create a suitable stash for
|
||||
saving the parameters.
|
||||
|
||||
\param pr pointer to ::progs_t VM struct
|
||||
\param params location to save the parameters, must be of adequade size
|
||||
to hold \a pr_argc * \a pr_param_size words in \a params
|
||||
\return \a params Allows the likes of:
|
||||
__auto_type params = PR_SaveParams (pr);
|
||||
*/
|
||||
pr_stashed_params_t *_PR_SaveParams (progs_t *pr, pr_stashed_params_t *params);
|
||||
|
||||
/** Restore the parameters saved by PR_SaveParams().
|
||||
\param pr pointer to ::progs_t VM struct
|
||||
\param params pointer to stash created by PR_SaveParams()
|
||||
*/
|
||||
void PR_RestoreParams (progs_t *pr);
|
||||
void PR_RestoreParams (progs_t *pr, pr_stashed_params_t *params);
|
||||
///@}
|
||||
|
||||
/** Push an execution frame onto the VM stack. Saves current execution state.
|
||||
\param pr pointer to ::progs_t VM struct
|
||||
|
@ -236,7 +288,7 @@ void ED_PrintNum (progs_t *pr, pr_int_t ent);
|
|||
// pr_parse.c
|
||||
struct script_s;
|
||||
struct plitem_s;
|
||||
qboolean ED_ParseEpair (progs_t *pr, pr_type_t *base, ddef_t *key,
|
||||
qboolean ED_ParseEpair (progs_t *pr, pr_type_t *base, pr_def_t *key,
|
||||
const char *s);
|
||||
struct plitem_s *ED_EntityDict (progs_t *pr, edict_t *ed);
|
||||
struct plitem_s *ED_GlobalsDict (progs_t *pr);
|
||||
|
@ -269,11 +321,13 @@ void ED_EntityParseFunction (progs_t *pr);
|
|||
*/
|
||||
///@{
|
||||
|
||||
ddef_t *PR_FieldAtOfs (progs_t *pr, pr_int_t ofs) __attribute__((pure));
|
||||
ddef_t *PR_GlobalAtOfs (progs_t *pr, pr_int_t ofs) __attribute__((pure));
|
||||
pr_def_t *PR_SearchDefs (pr_def_t *defs, unsigned num_defs, pointer_t offset)
|
||||
__attribute__((pure));
|
||||
pr_def_t *PR_FieldAtOfs (progs_t *pr, pointer_t ofs) __attribute__((pure));
|
||||
pr_def_t *PR_GlobalAtOfs (progs_t *pr, pointer_t ofs) __attribute__((pure));
|
||||
|
||||
ddef_t *PR_FindField (progs_t *pr, const char *name);
|
||||
ddef_t *PR_FindGlobal (progs_t *pr, const char *name);
|
||||
pr_def_t *PR_FindField (progs_t *pr, const char *name);
|
||||
pr_def_t *PR_FindGlobal (progs_t *pr, const char *name);
|
||||
dfunction_t *PR_FindFunction (progs_t *pr, const char *name);
|
||||
|
||||
int PR_ResolveGlobals (progs_t *pr);
|
||||
|
@ -510,6 +564,20 @@ void PR_Undefined (progs_t *pr, const char *type, const char *name) __attribute_
|
|||
*/
|
||||
#define P_var(p,n,t) ((p)->pr_params[n]->t##_var)
|
||||
|
||||
/** Access a parameter as an arbitray type.
|
||||
|
||||
\par QC type:
|
||||
\c struct etc small enough to fit in a single parameter
|
||||
\param p pointer to ::progs_t VM struct
|
||||
\param t C type of the structure
|
||||
\param n parameter number (0-7)
|
||||
\return structure lvalue. use & to make a pointer of the
|
||||
appropriate type.
|
||||
|
||||
\hideinitializer
|
||||
*/
|
||||
#define P_PACKED(p,t,n) (*(t *) (p)->pr_params[n])
|
||||
|
||||
/** Access a float parameter. Can be assigned to.
|
||||
|
||||
\par QC type:
|
||||
|
@ -532,7 +600,7 @@ void PR_Undefined (progs_t *pr, const char *type, const char *name) __attribute_
|
|||
|
||||
\hideinitializer
|
||||
*/
|
||||
#define P_DOUBLE(p,n) (*(double *) ((p)->pr_params[n]))
|
||||
#define P_DOUBLE(p,n) P_PACKED(p, double, n)
|
||||
|
||||
/** Access an integer parameter. Can be assigned to.
|
||||
|
||||
|
@ -618,7 +686,6 @@ void PR_Undefined (progs_t *pr, const char *type, const char *name) __attribute_
|
|||
*/
|
||||
#define P_POINTER(p,n) P_var (p, n, pointer)
|
||||
|
||||
|
||||
/** Access an entity parameter.
|
||||
|
||||
\par QC type:
|
||||
|
@ -715,6 +782,19 @@ void PR_Undefined (progs_t *pr, const char *type, const char *name) __attribute_
|
|||
*/
|
||||
#define R_var(p,t) ((p)->pr_return->t##_var)
|
||||
|
||||
/** Access the VM function return value parameter as an arbitray type.
|
||||
|
||||
\par QC type:
|
||||
\c struct etc small enough to fit in the return slot
|
||||
\param p pointer to ::progs_t VM struct
|
||||
\param t C type of the structure
|
||||
\return structure lvalue. use & to make a pointer of the
|
||||
appropriate type.
|
||||
|
||||
\hideinitializer
|
||||
*/
|
||||
#define R_PACKED(p,t) (*(t *) (p)->pr_return)
|
||||
|
||||
/** Access the VM function return value as a \c float
|
||||
|
||||
\par QC type:
|
||||
|
@ -735,7 +815,7 @@ void PR_Undefined (progs_t *pr, const char *type, const char *name) __attribute_
|
|||
|
||||
\hideinitializer
|
||||
*/
|
||||
#define R_DOUBLE(p) (*(double *) ((p)->pr_return))
|
||||
#define R_DOUBLE(p) R_PACKED (p, double)
|
||||
|
||||
/** Access the VM function return value as a \c ::pr_int_t (AKA int32_t)
|
||||
|
||||
|
@ -1142,12 +1222,12 @@ int PR_RelocateBuiltins (progs_t *pr);
|
|||
*/
|
||||
///@{
|
||||
|
||||
/** Initialize the string tables using the strings supplied by the progs.
|
||||
Called automatically during progs load.
|
||||
\param pr pointer to ::progs_t VM struct
|
||||
\return true for success, false for failure
|
||||
/** Initialize the string management subsystem.
|
||||
|
||||
\param pr The VM of which the string management subsystem will be
|
||||
initialized;
|
||||
*/
|
||||
int PR_LoadStrings (progs_t *pr);
|
||||
void PR_Strings_Init (progs_t *pr);
|
||||
|
||||
/** Check the validity of a string index.
|
||||
\param pr pointer to ::progs_t VM struct
|
||||
|
@ -1196,6 +1276,29 @@ string_t PR_SetReturnString(progs_t *pr, const char *s);
|
|||
*/
|
||||
string_t PR_SetTempString(progs_t *pr, const char *s);
|
||||
|
||||
/** Make a temporary memory block that will be freed when the current progs
|
||||
stack frame is exited. The contents may be anything and a new block is
|
||||
returned every time, and the block is in VM addressible space. To access
|
||||
the contents of the block (for reading, writing, etc), use PR_GetString()
|
||||
and cast the pointer as necessary.
|
||||
|
||||
\param pr pointer to ::progs_t VM struct
|
||||
\param size size of block in bytes
|
||||
\return string index of the block
|
||||
*/
|
||||
string_t PR_AllocTempBlock (progs_t *pr, size_t size);
|
||||
|
||||
/** Push a temporary string to the callee stack frame
|
||||
|
||||
This is for when the temp string needs to be freed when the called function
|
||||
returns rather than the calling function. It is an error to push a non-temp
|
||||
string.
|
||||
|
||||
\param pr pointer to ::progs_t VM struct
|
||||
\param num string index of the temp string
|
||||
*/
|
||||
void PR_PushTempString (progs_t *pr, string_t num);
|
||||
|
||||
/** Make a temporary progs string that is the concatenation of two C strings.
|
||||
\param pr pointer to ::progs_t VM struct
|
||||
\param a C string
|
||||
|
@ -1226,11 +1329,6 @@ string_t PR_NewMutableString (progs_t *pr);
|
|||
*/
|
||||
string_t PR_SetDynamicString (progs_t *pr, const char *s);
|
||||
|
||||
/** Clear all of the return string slots. Called at progs load.
|
||||
\param pr pointer to ::progs_t VM struct
|
||||
*/
|
||||
void PR_ClearReturnStrings (progs_t *pr);
|
||||
|
||||
/** Destroy a mutable, dynamic or temporary string.
|
||||
\param pr pointer to ::progs_t VM struct
|
||||
\param str string index of the string to be destroyed
|
||||
|
@ -1418,6 +1516,8 @@ void *PR_Resources_Find (progs_t *pr, const char *name);
|
|||
Any memory allocated to the resource must be freed before freeing the
|
||||
resource.
|
||||
|
||||
A reset resource map is guaranteed to allocate elements sequentially.
|
||||
|
||||
\param type The type of the resource. Must match the \c type parameter
|
||||
used for PR_RESMAP.
|
||||
\param map The resource map.
|
||||
|
@ -1432,6 +1532,8 @@ void *PR_Resources_Find (progs_t *pr, const char *name);
|
|||
*(type **) &map._free[j] = &map._free[j + 1]; \
|
||||
if (i < map._size - 1) \
|
||||
*(type **) &map._free[j] = &map._map[i + 1][0]; \
|
||||
else \
|
||||
*(type **) &map._free[j] = 0; \
|
||||
} \
|
||||
map._free = map._map[0];
|
||||
|
||||
|
@ -1488,19 +1590,66 @@ void *PR_Zone_Realloc (progs_t *pr, void *ptr, pr_int_t size);
|
|||
/// \addtogroup debug
|
||||
///@{
|
||||
|
||||
void PR_Debug_Init (void);
|
||||
struct qfot_type_s;
|
||||
|
||||
/** Callback for viewing progs data
|
||||
|
||||
\param type C pointer to the type definition by which to view the
|
||||
data.
|
||||
\param value C pointer to the data to be viewed.
|
||||
\param data User data.
|
||||
*/
|
||||
typedef void (*type_view_func) (struct qfot_type_s *type, pr_type_t *value,
|
||||
void *data);
|
||||
|
||||
/** Set of callbacks for viewing progs data
|
||||
|
||||
Each possible type has its own callback. Basic types (those for which the
|
||||
VM has specific instructions) all have separate callbacks, one for each
|
||||
type, but the callbacks for compound types are expected to some
|
||||
interpretation on their own, such as displaying a simple identifier or
|
||||
the entire contents of the data.
|
||||
*/
|
||||
typedef struct type_view_s {
|
||||
type_view_func void_view;
|
||||
type_view_func string_view;
|
||||
type_view_func float_view;
|
||||
type_view_func vector_view;
|
||||
type_view_func entity_view;
|
||||
type_view_func field_view;
|
||||
type_view_func func_view;
|
||||
type_view_func pointer_view;
|
||||
type_view_func quat_view;
|
||||
type_view_func integer_view;
|
||||
type_view_func uinteger_view;
|
||||
type_view_func short_view;
|
||||
type_view_func double_view;
|
||||
|
||||
type_view_func struct_view;
|
||||
type_view_func union_view;
|
||||
type_view_func enum_view;
|
||||
type_view_func array_view;
|
||||
type_view_func class_view;
|
||||
} type_view_t;
|
||||
|
||||
void PR_Debug_Init (progs_t *pr);
|
||||
void PR_Debug_Init_Cvars (void);
|
||||
int PR_LoadDebug (progs_t *pr);
|
||||
void PR_Debug_Watch (progs_t *pr, const char *expr);
|
||||
void PR_Debug_Print (progs_t *pr, const char *expr);
|
||||
pr_auxfunction_t *PR_Debug_AuxFunction (progs_t *pr, pr_uint_t func) __attribute__((pure));
|
||||
pr_auxfunction_t *PR_Debug_MappedAuxFunction (progs_t *pr, pr_uint_t func) __attribute__((pure));
|
||||
pr_def_t *PR_Debug_LocalDefs (progs_t *pr, pr_auxfunction_t *aux_function) __attribute__((pure));
|
||||
pr_lineno_t *PR_Debug_Linenos (progs_t *pr, pr_auxfunction_t *aux_function,
|
||||
pr_uint_t *num_linenos);
|
||||
pr_auxfunction_t *PR_Get_Lineno_Func (progs_t *pr, pr_lineno_t *lineno) __attribute__((pure));
|
||||
pr_uint_t PR_Get_Lineno_Addr (progs_t *pr, pr_lineno_t *lineno) __attribute__((pure));
|
||||
pr_uint_t PR_Get_Lineno_Line (progs_t *pr, pr_lineno_t *lineno) __attribute__((pure));
|
||||
pr_lineno_t *PR_Find_Lineno (progs_t *pr, pr_uint_t addr) __attribute__((pure));
|
||||
const char *PR_Get_Source_File (progs_t *pr, pr_lineno_t *lineno) __attribute__((pure));
|
||||
const char *PR_Get_Source_Line (progs_t *pr, pr_uint_t addr);
|
||||
ddef_t *PR_Get_Param_Def (progs_t *pr, dfunction_t *func, unsigned parm) __attribute__((pure));
|
||||
ddef_t *PR_Get_Local_Def (progs_t *pr, pr_int_t offs) __attribute__((pure));
|
||||
pr_def_t *PR_Get_Param_Def (progs_t *pr, dfunction_t *func, unsigned parm) __attribute__((pure));
|
||||
pr_def_t *PR_Get_Local_Def (progs_t *pr, pointer_t *offs) __attribute__((pure));
|
||||
void PR_PrintStatement (progs_t *pr, dstatement_t *s, int contents);
|
||||
void PR_DumpState (progs_t *pr);
|
||||
void PR_StackTrace (progs_t *pr);
|
||||
|
@ -1541,8 +1690,6 @@ typedef struct {
|
|||
strref_t *tstr; ///< Linked list of temporary strings.
|
||||
} prstack_t;
|
||||
|
||||
struct obj_list_s;
|
||||
|
||||
struct progs_s {
|
||||
int (*parse_field) (progs_t *pr, const char *key, const char *value);
|
||||
|
||||
|
@ -1550,7 +1697,7 @@ struct progs_s {
|
|||
int no_exec_limit;
|
||||
|
||||
void (*file_error) (progs_t *pr, const char *path);
|
||||
void *(*load_file) (progs_t *pr, const char *path);
|
||||
void *(*load_file) (progs_t *pr, const char *path, off_t *size);
|
||||
void *(*allocate_progs_mem) (progs_t *pr, int size);
|
||||
void (*free_progs_mem) (progs_t *pr, void *mem);
|
||||
|
||||
|
@ -1597,16 +1744,9 @@ struct progs_s {
|
|||
|
||||
/// \name string management
|
||||
///@{
|
||||
struct dstring_mem_s *ds_mem;
|
||||
strref_t *free_string_refs;
|
||||
strref_t *static_strings;
|
||||
strref_t **string_map;
|
||||
strref_t *return_strings[PR_RS_SLOTS];
|
||||
int rs_slot;
|
||||
unsigned dyn_str_size;
|
||||
struct hashtab_s *strref_hash;
|
||||
int num_strings;
|
||||
struct prstr_resources_s *pr_string_resources;
|
||||
strref_t *pr_xtstr;
|
||||
strref_t *pr_pushtstr;
|
||||
int float_promoted; ///< for PR_Sprintf
|
||||
///@}
|
||||
|
||||
|
@ -1616,8 +1756,8 @@ struct progs_s {
|
|||
bfunction_t *function_table;
|
||||
char *pr_strings;
|
||||
int pr_stringsize;
|
||||
ddef_t *pr_globaldefs;
|
||||
ddef_t *pr_fielddefs;
|
||||
pr_def_t *pr_globaldefs;
|
||||
pr_def_t *pr_fielddefs;
|
||||
dstatement_t *pr_statements;
|
||||
pr_type_t *pr_globals;
|
||||
unsigned globals_size;
|
||||
|
@ -1628,14 +1768,12 @@ struct progs_s {
|
|||
pr_type_t *pr_return;
|
||||
pr_type_t *pr_params[MAX_PARMS];
|
||||
pr_type_t *pr_real_params[MAX_PARMS];
|
||||
pr_type_t *pr_param_ptrs[2];
|
||||
pr_type_t *pr_saved_params;
|
||||
int pr_saved_argc;
|
||||
int pr_param_size; ///< covers both params and return
|
||||
int pr_param_alignment; ///< covers both params and return
|
||||
///@}
|
||||
|
||||
/// \name edicts
|
||||
/// \todo FIXME should this be outside the VM?
|
||||
///@{
|
||||
edict_t **edicts;
|
||||
int max_edicts; ///< set by user
|
||||
|
@ -1652,7 +1790,7 @@ struct progs_s {
|
|||
|
||||
/// \name execution state
|
||||
///@{
|
||||
int pr_argc;
|
||||
int pr_argc; //FIXME need a good way to ensure it is correct
|
||||
|
||||
qboolean pr_trace;
|
||||
int pr_trace_depth;
|
||||
|
@ -1687,28 +1825,13 @@ struct progs_s {
|
|||
|
||||
/// \name obj info
|
||||
///@{
|
||||
unsigned selector_index;
|
||||
unsigned selector_index_max;
|
||||
struct obj_list_s **selector_sels;
|
||||
string_t *selector_names;
|
||||
struct hashtab_s *selector_hash;
|
||||
struct hashtab_s *classes;
|
||||
struct hashtab_s *load_methods;
|
||||
struct obj_list_s *unresolved_classes;
|
||||
struct obj_list_s *unclaimed_categories;
|
||||
struct obj_list_s *unclaimed_proto_list;
|
||||
struct obj_list_s *module_list;
|
||||
struct obj_list_s *class_tree_list;
|
||||
struct probj_resources_s *pr_objective_resources;
|
||||
///@}
|
||||
|
||||
/// \name debug info
|
||||
/// \name debugging
|
||||
///@{
|
||||
const char *debugfile;
|
||||
struct pr_debug_header_s *debug;
|
||||
struct pr_auxfunction_s *auxfunctions;
|
||||
struct pr_auxfunction_s **auxfunction_map;
|
||||
struct pr_lineno_s *linenos;
|
||||
ddef_t *local_defs;
|
||||
struct prdeb_resources_s *pr_debug_resources;
|
||||
void (*breakpoint_handler) (progs_t *pr);
|
||||
pr_type_t *watch;
|
||||
int wp_conditional;
|
||||
pr_type_t wp_val;
|
||||
|
@ -1740,7 +1863,7 @@ struct progs_s {
|
|||
\return C pointer represented by the parameter. 0 offset -> NULL
|
||||
*/
|
||||
static inline pr_type_t *
|
||||
PR_GetPointer (progs_t *pr, pointer_t o)
|
||||
PR_GetPointer (const progs_t *pr, pointer_t o)
|
||||
{
|
||||
return o ? pr->pr_globals + o : 0;
|
||||
}
|
||||
|
@ -1751,9 +1874,9 @@ PR_GetPointer (progs_t *pr, pointer_t o)
|
|||
\return Progs offset/pointer represented by \c p. NULL -> 0 offset
|
||||
*/
|
||||
static inline pointer_t
|
||||
PR_SetPointer (progs_t *pr, void *p)
|
||||
PR_SetPointer (const progs_t *pr, const void *p)
|
||||
{
|
||||
return p ? (pr_type_t *) p - pr->pr_globals : 0;
|
||||
return p ? (const pr_type_t *) p - pr->pr_globals : 0;
|
||||
}
|
||||
|
||||
///@}
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef __qargs_h
|
||||
#define __qargs_h
|
||||
#ifndef __QF_qargs_h
|
||||
#define __QF_qargs_h
|
||||
|
||||
/** \addtogroup misc
|
||||
*/
|
||||
|
@ -52,4 +52,4 @@ void COM_ParseConfig (void);
|
|||
|
||||
///@}
|
||||
|
||||
#endif // __qargs_h
|
||||
#endif//__QF_qargs_h
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef __qdefs_h
|
||||
#define __qdefs_h
|
||||
#ifndef __QF_qdefs_h
|
||||
#define __QF_qdefs_h
|
||||
|
||||
#define MAX_QPATH 64
|
||||
#define MAX_CL_STATS 32
|
||||
|
@ -40,4 +40,4 @@
|
|||
|
||||
#define clc_stringcmd 4
|
||||
|
||||
#endif // __qdefs_h
|
||||
#endif//__QF_qdefs_h
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef __qendian_h
|
||||
#define __qendian_h
|
||||
#ifndef __QF_qendian_h
|
||||
#define __QF_qendian_h
|
||||
|
||||
/** \defgroup qendian Endian handling functions
|
||||
\ingroup utils
|
||||
|
@ -120,4 +120,4 @@ unsigned int ReadLong (struct QFile_s *file);
|
|||
|
||||
///@}
|
||||
|
||||
#endif // __qendian_h
|
||||
#endif//__QF_qendian_h
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef __QF_qfplist_h_
|
||||
#define __QF_qfplist_h_
|
||||
#ifndef __QF_qfplist_h
|
||||
#define __QF_qfplist_h
|
||||
|
||||
/** \defgroup qfplist Property lists
|
||||
\ingroup utils
|
||||
|
@ -228,4 +228,4 @@ void PL_Free (plitem_t *item);
|
|||
|
||||
///@}
|
||||
|
||||
#endif // __QF_qfplist_h_
|
||||
#endif//__QF_qfplist_h
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef __qtypes_h
|
||||
#define __qtypes_h
|
||||
#ifndef __QF_qtypes_h
|
||||
#define __QF_qtypes_h
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
@ -115,4 +115,4 @@ typedef struct sphere_s {
|
|||
vec_t radius;
|
||||
} sphere_t;
|
||||
|
||||
#endif // __qtypes_h
|
||||
#endif//__QF_qtypes_h
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef __quakefs_h
|
||||
#define __quakefs_h
|
||||
#ifndef __QF_quakefs_h
|
||||
#define __QF_quakefs_h
|
||||
|
||||
/** \defgroup quakefs Quake Filesystem
|
||||
\ingroup utils
|
||||
|
@ -420,4 +420,4 @@ void QFS_FilelistFree (filelist_t *list);
|
|||
|
||||
///@}
|
||||
|
||||
#endif // __quakefs_h
|
||||
#endif//__QF_quakefs_h
|
||||
|
|
|
@ -26,8 +26,8 @@
|
|||
Boston, MA 02111-1307, USA
|
||||
|
||||
*/
|
||||
#ifndef __quakeio_h
|
||||
#define __quakeio_h
|
||||
#ifndef __QF_quakeio_h
|
||||
#define __QF_quakeio_h
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
@ -62,4 +62,4 @@ const char *Qgetline(QFile *file);
|
|||
|
||||
///@}
|
||||
|
||||
#endif /*__quakeio_h*/
|
||||
#endif//__QF_quakeio_h
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef __render_h
|
||||
#define __render_h
|
||||
#ifndef __QF_render_h
|
||||
#define __QF_render_h
|
||||
|
||||
#include "QF/mathlib.h"
|
||||
#include "QF/model.h"
|
||||
|
@ -177,4 +177,4 @@ void R_LoadModule (struct vid_internal_s *vid_internal);
|
|||
struct progs_s;
|
||||
void R_Progs_Init (struct progs_s *pr);
|
||||
|
||||
#endif // __render_h
|
||||
#endif//__QF_render_h
|
||||
|
|
103
include/QF/ringbuffer.h
Normal file
103
include/QF/ringbuffer.h
Normal file
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
ringbuffer.h
|
||||
|
||||
ring buffer
|
||||
|
||||
Copyright (C) 2020 Bill Currie <bill@taniwha.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __QF_ringbuffer_h
|
||||
#define __QF_ringbuffer_h
|
||||
|
||||
#define RING_BUFFER(type, size) \
|
||||
struct { \
|
||||
type buffer[size]; \
|
||||
unsigned head; \
|
||||
unsigned tail; \
|
||||
}
|
||||
|
||||
#define RB_buffer_size(ring_buffer) \
|
||||
({ __auto_type rb = (ring_buffer); \
|
||||
sizeof (rb->buffer) / sizeof (rb->buffer[0]); \
|
||||
})
|
||||
|
||||
#define RB_SPACE_AVAILABLE(ring_buffer) \
|
||||
({ __auto_type rb = &(ring_buffer); \
|
||||
(rb->tail + RB_buffer_size(rb) - rb->head - 1) % RB_buffer_size(rb);\
|
||||
})
|
||||
|
||||
#define RB_DATA_AVAILABLE(ring_buffer) \
|
||||
({ __auto_type rb = &(ring_buffer); \
|
||||
(rb->head + RB_buffer_size (rb) - rb->tail) % RB_buffer_size (rb); \
|
||||
})
|
||||
|
||||
#define RB_WRITE_DATA(ring_buffer, data, count) \
|
||||
({ __auto_type rb = &(ring_buffer); \
|
||||
const typeof (rb->buffer[0]) *d = (data); \
|
||||
unsigned c = (count); \
|
||||
unsigned h = rb->head; \
|
||||
rb->head = (h + c) % RB_buffer_size (rb); \
|
||||
if (c > RB_buffer_size (rb) - h) { \
|
||||
memcpy (rb->buffer + h, d, \
|
||||
(RB_buffer_size (rb) - h) * sizeof (rb->buffer[0])); \
|
||||
c -= RB_buffer_size (rb) - h; \
|
||||
d += RB_buffer_size (rb) - h; \
|
||||
h = 0; \
|
||||
} \
|
||||
memcpy (rb->buffer + h, d, c * sizeof (rb->buffer[0])); \
|
||||
})
|
||||
|
||||
#define RB_READ_DATA(ring_buffer, data, count) \
|
||||
({ __auto_type rb = &(ring_buffer); \
|
||||
typeof (&rb->buffer[0]) d = (data); \
|
||||
unsigned c = (count); \
|
||||
unsigned oc = c; \
|
||||
unsigned t = rb->tail; \
|
||||
if (c > RB_buffer_size (rb) - t) { \
|
||||
memcpy (d, rb->buffer + t, \
|
||||
(RB_buffer_size (rb) - t) * sizeof (rb->buffer[0])); \
|
||||
c -= RB_buffer_size (rb) - t; \
|
||||
d += RB_buffer_size (rb) - t; \
|
||||
t = 0; \
|
||||
} \
|
||||
memcpy (d, rb->buffer + t, c * sizeof (rb->buffer[0])); \
|
||||
rb->tail = (t + oc) % RB_buffer_size (rb); \
|
||||
})
|
||||
|
||||
#define RB_DROP_DATA(ring_buffer, count) \
|
||||
({ __auto_type rb = &(ring_buffer); \
|
||||
unsigned c = (count); \
|
||||
unsigned t = rb->tail; \
|
||||
rb->tail = (t + c) % RB_buffer_size (rb); \
|
||||
})
|
||||
|
||||
#define RB_PEEK_DATA(ring_buffer, ahead) \
|
||||
({ __auto_type rb = &(ring_buffer); \
|
||||
rb->buffer[(rb->tail + ahead) % RB_buffer_size (rb)]; \
|
||||
})
|
||||
|
||||
#define RB_POKE_DATA(ring_buffer, ahead, data) \
|
||||
({ __auto_type rb = &(ring_buffer); \
|
||||
rb->buffer[(rb->tail + ahead) % RB_buffer_size (rb)] = (data); \
|
||||
})
|
||||
|
||||
#endif//__QF_ringbuffer_h
|
|
@ -26,8 +26,8 @@
|
|||
*/
|
||||
// screen.h
|
||||
|
||||
#ifndef __screen_h
|
||||
#define __screen_h
|
||||
#ifndef __QF_screen_h
|
||||
#define __QF_screen_h
|
||||
|
||||
#include "QF/qtypes.h"
|
||||
|
||||
|
@ -67,4 +67,4 @@ extern struct qpic_s *scr_turtle;
|
|||
|
||||
extern struct cvar_s *hud_fps, *hud_time;
|
||||
|
||||
#endif // __screen_h
|
||||
#endif//__QF_screen_h
|
||||
|
|
|
@ -41,8 +41,9 @@ typedef struct script_s {
|
|||
/// line number of the file being processed. used only for error reporting
|
||||
/// but updated internally.
|
||||
int line;
|
||||
/// if set, will be called instead of the internal error handler
|
||||
void (*error)(struct script_s *script, const char *msg);
|
||||
/// contains last error message or null if no error
|
||||
/// if set, no tokens will be parsed.
|
||||
const char *error;
|
||||
/// if set, multi line quoted tokens will be treated as errors
|
||||
int no_quote_lines;
|
||||
/// if set, characters in this string will always be lexed as single
|
||||
|
@ -65,6 +66,7 @@ void Script_Delete (script_t *script);
|
|||
/** Prepare a script_t object for parsing.
|
||||
The caller is responsible for freeing the memory associated with file and
|
||||
data when parsing is complete.
|
||||
Resets \a script->error
|
||||
\param script The script_t object being parsed
|
||||
\param file Name of the file being parsed. used only for error reporting
|
||||
\param data The script to be parsed
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
Boston, MA 02111-1307, USA
|
||||
|
||||
*/
|
||||
#ifndef __sizebuf_h
|
||||
#define __sizebuf_h
|
||||
#ifndef __QF_sizebuf_h
|
||||
#define __QF_sizebuf_h
|
||||
|
||||
/** \defgroup sizebuf Fixed Size Buffers
|
||||
\ingroup utils
|
||||
|
@ -53,4 +53,4 @@ void SZ_Print (sizebuf_t *buf, const char *data); // strcats onto the sizebuf
|
|||
|
||||
///@}
|
||||
|
||||
#endif // __sizebuf_h
|
||||
#endif//__QF_sizebuf_h
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef _SKIN_H
|
||||
#define _SKIN_H
|
||||
#ifndef __QF_skin_h
|
||||
#define __QF_skin_h
|
||||
|
||||
#include "QF/qtypes.h"
|
||||
#include "QF/vid.h"
|
||||
|
@ -57,4 +57,4 @@ typedef struct skin_s {
|
|||
int auxtex;
|
||||
} skin_t;
|
||||
|
||||
#endif
|
||||
#endif//__QF_skin_h
|
||||
|
|
|
@ -26,8 +26,8 @@
|
|||
*/
|
||||
// sound.h -- client sound i/o functions
|
||||
|
||||
#ifndef _SOUND_H
|
||||
#define _SOUND_H
|
||||
#ifndef __QF_sound_h
|
||||
#define __QF_sound_h
|
||||
|
||||
/** \defgroup sound QuakeForge sound engine
|
||||
*/
|
||||
|
@ -195,4 +195,4 @@ void S_Progs_Init (struct progs_s *pr);
|
|||
|
||||
///@}
|
||||
|
||||
#endif // _SOUND_H
|
||||
#endif//__QF_sound_h
|
||||
|
|
|
@ -45,8 +45,8 @@
|
|||
// <endrepeat>
|
||||
//-------------------------------------------------------
|
||||
|
||||
#ifndef _SPRITEGN_H
|
||||
#define _SPRITEGN_H
|
||||
#ifndef __QF_sprintgn_h
|
||||
#define __QF_sprintgn_h
|
||||
|
||||
#define SPR_VERSION 1
|
||||
#define SP2_VERSION 2
|
||||
|
@ -102,4 +102,4 @@ typedef struct {
|
|||
// little-endian "IDS2"
|
||||
#define IDHEADER_SP2 (('2'<<24)+('S'<<16)+('D'<<8)+'I')
|
||||
|
||||
#endif // _SPRITEGN_H
|
||||
#endif//__QF_sprintgn_h
|
||||
|
|
|
@ -25,10 +25,10 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef __sys_h
|
||||
#define __sys_h
|
||||
#ifndef __QF_sys_h
|
||||
#define __QF_sys_h
|
||||
|
||||
/** \defgroup sys Portability
|
||||
/** \defgroup sys System Portability
|
||||
\ingroup utils
|
||||
Non-portable functions
|
||||
*/
|
||||
|
@ -65,8 +65,8 @@ int Sys_mkdir (const char *path);
|
|||
typedef void (*sys_printf_t) (const char *fmt, va_list args) __attribute__((format(printf, 1, 0)));
|
||||
typedef void (*sys_error_t) (void *data);
|
||||
|
||||
void Sys_SetStdPrintf (sys_printf_t func);
|
||||
void Sys_SetErrPrintf (sys_printf_t func);
|
||||
sys_printf_t Sys_SetStdPrintf (sys_printf_t func);
|
||||
sys_printf_t Sys_SetErrPrintf (sys_printf_t func);
|
||||
|
||||
void Sys_PushErrorHandler (sys_error_t func, void *data);
|
||||
void Sys_PopErrorHandler (void);
|
||||
|
@ -161,4 +161,4 @@ char *Sys_ExpandSquiggle (const char *path);
|
|||
|
||||
///@}
|
||||
|
||||
#endif // __sys_h
|
||||
#endif//__QF_sys_h
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef __teamplay_h
|
||||
#define __teamplay_h
|
||||
#ifndef __QF_teamplay_h
|
||||
#define __QF_teamplay_h
|
||||
|
||||
extern struct cvar_s *cl_parsesay;
|
||||
extern struct cvar_s *cl_nofake;
|
||||
|
@ -47,4 +47,4 @@ const char *Team_ParseSay (struct dstring_s *buf, const char *);
|
|||
void Locs_Init (void);
|
||||
void Team_ParseChat (const char *string);
|
||||
void Team_ResetTimers (void);
|
||||
#endif // __teamplay_h
|
||||
#endif//__QF_teamplay_h
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef __tga_h
|
||||
#define __tga_h
|
||||
#ifndef __QF_tga_h
|
||||
#define __QF_tga_h
|
||||
|
||||
#include "QF/qtypes.h"
|
||||
#include "QF/quakeio.h"
|
||||
|
@ -70,4 +70,4 @@ typedef struct _TargaHeader {
|
|||
struct tex_s *LoadTGA (QFile *fin);
|
||||
void WriteTGAfile (const char *tganame, byte *data, int width, int height);
|
||||
|
||||
#endif // __tga_h
|
||||
#endif//__QF_tga_h
|
||||
|
|
98
include/QF/txtbuffer.h
Normal file
98
include/QF/txtbuffer.h
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
txtbuffer.h
|
||||
|
||||
Text buffer for edit or scrollback
|
||||
|
||||
Copyright (C) 2020 Bill Currie <bill@taniwha.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __QF_txtbuffer_h
|
||||
#define __QF_txtbuffer_h
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/** \defgroup txtbuffer Text buffers
|
||||
\ingroup utils
|
||||
*/
|
||||
///@{
|
||||
|
||||
/// must be a power of 2
|
||||
#define TXTBUFFER_GROW 0x4000
|
||||
|
||||
/** Text buffer implementing efficient editing.
|
||||
*/
|
||||
typedef struct txtbuffer_s {
|
||||
struct txtbuffer_s *next;
|
||||
char *text;
|
||||
size_t textSize; ///< amount of text in the buffer
|
||||
size_t bufferSize; ///< current capacity of the buffer
|
||||
size_t gapOffset; ///< beginning of the gap
|
||||
size_t gapSize; ///< size of gap. gapSize + textSize == bufferSize
|
||||
} txtbuffer_t;
|
||||
|
||||
/** Create a new, empty buffer.
|
||||
*/
|
||||
txtbuffer_t *TextBuffer_Create (void);
|
||||
|
||||
/** Destroy a buffer, freeing all resources connected to it.
|
||||
\param buffer The buffer to destroy.
|
||||
*/
|
||||
void TextBuffer_Destroy (txtbuffer_t *buffer);
|
||||
|
||||
/** Insert a block of text at the specified offset.
|
||||
|
||||
Text after the offset is moved to be after the inserted block of text.
|
||||
The buffer is resized as necessary.
|
||||
nul characters are not significant in that they do not mark the end of
|
||||
the text to be inserted.
|
||||
|
||||
\param buffer The buffer to be updated
|
||||
\param offset The offset in the buffer at which to insert the text block
|
||||
\param text The text block to be inserted. May contain nul ('\0')
|
||||
characters.
|
||||
\param text_len The number of characters to insert.
|
||||
\return 1 for success, 0 for failure (offset not valid or out
|
||||
of memory)
|
||||
*/
|
||||
int TextBuffer_InsertAt (txtbuffer_t *buffer, size_t offset,
|
||||
const char *text, size_t text_len);
|
||||
|
||||
/** Delete a block of text from the buffer.
|
||||
|
||||
The buffer is not resized. Rather, its capacity before resizing is require
|
||||
is increased.
|
||||
|
||||
\param buffer The buffer to be updated
|
||||
\param offset The offset of the beginning of the text block to be deleted
|
||||
\param len The amount of characters to be deleted. Values larger than
|
||||
the amount of text in the buffer beyond the beginning of
|
||||
block are truncated to the amount of remaining text. Thus
|
||||
using excessivly large values sets the offset to be the
|
||||
end of the buffer.
|
||||
\return 1 for success, 0 for failure (offset not valid)
|
||||
*/
|
||||
int TextBuffer_DeleteAt (txtbuffer_t *buffer, size_t offset, size_t len);
|
||||
|
||||
///@}
|
||||
|
||||
#endif//__QF_txtbuffer_h
|
|
@ -1,52 +0,0 @@
|
|||
/*
|
||||
uint32.h
|
||||
|
||||
Definitions for portable (?) unsigned int
|
||||
|
||||
Copyright (C) 2000 Jeff Teunissen <d2deek@pmail.net>
|
||||
|
||||
Author: Jeff Teunissen <d2deek@pmail.net>
|
||||
Date: 01 Jan 2000
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __uint32_h
|
||||
#define __uint32_h
|
||||
|
||||
#ifndef int32
|
||||
# if (SIZEOF_INT == 4)
|
||||
# define int32 int
|
||||
# elif (SIZEOF_LONG == 4)
|
||||
# define int32 long
|
||||
# elif (SIZEOF_SHORT == 4)
|
||||
# define int32 short
|
||||
# else
|
||||
/* I hope this works */
|
||||
# define int32 int
|
||||
# define LARGE_INT32
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef uint32
|
||||
# define uint32 unsigned int32
|
||||
#endif
|
||||
|
||||
#endif // __uint32_h
|
|
@ -26,8 +26,8 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef __va_h
|
||||
#define __va_h
|
||||
#ifndef __QF_va_h
|
||||
#define __QF_va_h
|
||||
|
||||
/** \addtogroup misc
|
||||
Formatted printing.
|
||||
|
@ -41,4 +41,4 @@ char *nva(const char *format, ...) __attribute__((format(printf,1,2)));
|
|||
|
||||
///@}
|
||||
|
||||
#endif // __va_h
|
||||
#endif//__QF_va_h
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef __ver_check_h_
|
||||
#define __ver_check_h_
|
||||
#ifndef __QF_ver_check_h
|
||||
#define __QF_ver_check_h
|
||||
|
||||
/** \defgroup utils Utils
|
||||
*/
|
||||
|
@ -47,4 +47,4 @@ int ver_compare (const char *, const char *);
|
|||
|
||||
///@}
|
||||
|
||||
#endif // __ver_check_h_
|
||||
#endif//__QF_ver_check_h
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef __vid_h_
|
||||
#define __vid_h_
|
||||
#ifndef __QF_vid_h
|
||||
#define __QF_vid_h
|
||||
|
||||
#include "QF/qtypes.h"
|
||||
#include "QF/vrect.h"
|
||||
|
@ -79,4 +79,4 @@ void VID_Init (byte *palette, byte *colormap);
|
|||
void VID_SetCaption (const char *text);
|
||||
void VID_ClearMemory (void);
|
||||
|
||||
#endif // __vid_h_
|
||||
#endif//__QF_vid_h
|
||||
|
|
|
@ -28,8 +28,8 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef __qf_view_h
|
||||
#define __qf_view_h
|
||||
#ifndef __QF_view_h
|
||||
#define __QF_view_h
|
||||
|
||||
/** \defgroup console_view Console View Objects
|
||||
\ingroup console
|
||||
|
@ -217,4 +217,4 @@ void view_move (view_t *view, int xp, int yp);
|
|||
|
||||
///@}
|
||||
|
||||
#endif//__qf_view_h
|
||||
#endif//__QF_view_h
|
||||
|
|
|
@ -26,8 +26,8 @@
|
|||
*/
|
||||
// wad.h
|
||||
|
||||
#ifndef _WAD_H
|
||||
#define _WAD_H
|
||||
#ifndef __QF_wad_h
|
||||
#define __QF_wad_h
|
||||
|
||||
/** \addtogroup wad
|
||||
Wad Files
|
||||
|
@ -48,4 +48,4 @@ void SwapPic (qpic_t *pic);
|
|||
|
||||
///@}
|
||||
|
||||
#endif // _WAD_H
|
||||
#endif//__QF_wad_h
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
Boston, MA 02111-1307, USA
|
||||
|
||||
*/
|
||||
#ifndef __zone_h
|
||||
#define __zone_h
|
||||
#ifndef __QF_zone_h
|
||||
#define __QF_zone_h
|
||||
|
||||
/** \defgroup zone Memory Management
|
||||
\ingroup utils
|
||||
|
@ -142,4 +142,4 @@ int Cache_ReadLock (cache_user_t *c) __attribute__((pure));
|
|||
|
||||
///@}
|
||||
|
||||
#endif // __zone_h
|
||||
#endif//__QF_zone_h
|
||||
|
|
|
@ -39,8 +39,6 @@ void RUA_Cmd_Init (struct progs_s *pr, int secure);
|
|||
|
||||
void RUA_Cvar_Init (struct progs_s *pr, int secure);
|
||||
|
||||
void RUA_File_Init (struct progs_s *pr, int secure);
|
||||
|
||||
void RUA_Hash_Init (struct progs_s *pr, int secure);
|
||||
|
||||
void RUA_Math_Init (struct progs_s *pr, int secure);
|
||||
|
|
|
@ -130,9 +130,11 @@ bi_inputline_enter (inputline_t *il)
|
|||
P_POINTER (pr, 0) = data->data[0];
|
||||
P_POINTER (pr, 1) = data->data[1];
|
||||
P_STRING (pr, 2) = PR_SetTempString (pr, line);
|
||||
pr->pr_argc = 3;
|
||||
} else {
|
||||
P_STRING (pr, 0) = PR_SetTempString (pr, line);
|
||||
P_POINTER (pr, 1) = data->data[0];
|
||||
pr->pr_argc = 2;
|
||||
}
|
||||
PR_ExecuteProgram (pr, data->enter);
|
||||
PR_PopFrame (pr);
|
||||
|
|
|
@ -92,7 +92,7 @@ Con_BufferAddText (con_buffer_t *buf, const char *text)
|
|||
}
|
||||
while (len--) {
|
||||
byte c = *pos++ = *text++;
|
||||
if ((size_t) (pos - buf->buffer) >= buf->buffer_size)
|
||||
if (pos >= buf->buffer + buf->buffer_size)
|
||||
pos = buf->buffer;
|
||||
cur_line->len++;
|
||||
if (pos == tail_line->text) {
|
||||
|
|
|
@ -117,7 +117,7 @@ static int
|
|||
menu_resolve_globals (progs_t *pr)
|
||||
{
|
||||
const char *sym;
|
||||
ddef_t *def;
|
||||
pr_def_t *def;
|
||||
dfunction_t *f;
|
||||
size_t i;
|
||||
|
||||
|
@ -439,6 +439,7 @@ bi_Menu_Enter (progs_t *pr)
|
|||
P_STRING (&menu_pr_state, 0) =
|
||||
PR_SetTempString (&menu_pr_state, item->text);
|
||||
P_INT (&menu_pr_state, 1) = 0;
|
||||
pr->pr_argc = 2;
|
||||
PR_ExecuteProgram (&menu_pr_state, item->func);
|
||||
PR_PopFrame (&menu_pr_state);
|
||||
run_menu_post ();
|
||||
|
@ -510,9 +511,11 @@ menu_free_progs_mem (progs_t *pr, void *mem)
|
|||
}
|
||||
|
||||
static void *
|
||||
menu_load_file (progs_t *pr, const char *path)
|
||||
menu_load_file (progs_t *pr, const char *path, off_t *size)
|
||||
{
|
||||
return QFS_LoadFile (QFS_FOpenFile (path), 0);
|
||||
void *data = QFS_LoadFile (QFS_FOpenFile (path), 0);
|
||||
*size = qfs_filesize;
|
||||
return data;
|
||||
}
|
||||
|
||||
static builtin_t builtins[] = {
|
||||
|
@ -581,6 +584,8 @@ Menu_Init (void)
|
|||
menu_pr_state.max_edicts = 0;
|
||||
menu_pr_state.zone_size = 1024 * 1024;
|
||||
|
||||
PR_Init (&menu_pr_state);
|
||||
|
||||
menu_hash = Hash_NewTable (61, menu_get_key, menu_free, 0);
|
||||
|
||||
PR_RegisterBuiltins (&menu_pr_state, builtins);
|
||||
|
@ -668,6 +673,7 @@ Menu_Draw (view_t *view)
|
|||
PR_RESET_PARAMS (&menu_pr_state);
|
||||
P_INT (&menu_pr_state, 0) = x;
|
||||
P_INT (&menu_pr_state, 1) = y;
|
||||
menu_pr_state.pr_argc = 2;
|
||||
PR_ExecuteProgram (&menu_pr_state, menu->draw);
|
||||
ret = R_INT (&menu_pr_state);
|
||||
run_menu_post ();
|
||||
|
@ -702,6 +708,7 @@ Menu_Draw (view_t *view)
|
|||
PR_RESET_PARAMS (&menu_pr_state);
|
||||
P_INT (&menu_pr_state, 0) = x + item->x;
|
||||
P_INT (&menu_pr_state, 1) = y + item->y;
|
||||
menu_pr_state.pr_argc = 2;
|
||||
PR_ExecuteProgram (&menu_pr_state, menu->cursor);
|
||||
run_menu_post ();
|
||||
} else {
|
||||
|
@ -734,6 +741,7 @@ Menu_KeyEvent (knum_t key, short unicode, qboolean down)
|
|||
P_INT (&menu_pr_state, 0) = key;
|
||||
P_INT (&menu_pr_state, 1) = unicode;
|
||||
P_INT (&menu_pr_state, 2) = down;
|
||||
menu_pr_state.pr_argc = 3;
|
||||
PR_ExecuteProgram (&menu_pr_state, menu->keyevent);
|
||||
ret = R_INT (&menu_pr_state);
|
||||
run_menu_post ();
|
||||
|
@ -748,6 +756,7 @@ Menu_KeyEvent (knum_t key, short unicode, qboolean down)
|
|||
P_STRING (&menu_pr_state, 0) = PR_SetTempString (&menu_pr_state,
|
||||
item->text);
|
||||
P_INT (&menu_pr_state, 1) = key;
|
||||
menu_pr_state.pr_argc = 2;
|
||||
PR_ExecuteProgram (&menu_pr_state, item->func);
|
||||
PR_PopFrame (&menu_pr_state);
|
||||
ret = R_INT (&menu_pr_state);
|
||||
|
|
|
@ -47,7 +47,6 @@
|
|||
#include "QF/quakefs.h"
|
||||
#include "QF/sys.h"
|
||||
#include "QF/zone.h"
|
||||
#include "QF/va.h"
|
||||
|
||||
#include "compat.h"
|
||||
|
||||
|
@ -158,7 +157,8 @@ bi_no_function (progs_t *pr)
|
|||
VISIBLE int
|
||||
PR_RelocateBuiltins (progs_t *pr)
|
||||
{
|
||||
pr_int_t i, ind;
|
||||
pr_uint_t i;
|
||||
pr_int_t ind;
|
||||
int bad = 0;
|
||||
dfunction_t *desc;
|
||||
bfunction_t *func;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -34,22 +34,10 @@
|
|||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "QF/cbuf.h"
|
||||
#include "QF/crc.h"
|
||||
#include "QF/cvar.h"
|
||||
#include "QF/dstring.h"
|
||||
#include "QF/hash.h"
|
||||
#include "QF/idparse.h"
|
||||
#include "QF/progs.h"
|
||||
#include "QF/qdefs.h"
|
||||
#include "QF/qendian.h"
|
||||
#include "QF/quakefs.h"
|
||||
#include "QF/sys.h"
|
||||
#include "QF/zone.h"
|
||||
#include "QF/va.h"
|
||||
|
||||
#include "compat.h"
|
||||
|
||||
|
@ -63,7 +51,7 @@ ED_ClearEdict (progs_t *pr, edict_t *e, int val)
|
|||
{
|
||||
pr_uint_t i;
|
||||
|
||||
if (NUM_FOR_EDICT (pr, e) < *pr->reserved_edicts)
|
||||
if (pr->reserved_edicts && NUM_FOR_EDICT (pr, e) < *pr->reserved_edicts)
|
||||
Sys_Printf ("clearing reserved edict %d\n", NUM_FOR_EDICT (pr, e));
|
||||
for (i=0; i < pr->progs->entityfields; i++)
|
||||
e->v[i].integer_var = val;
|
||||
|
@ -86,6 +74,9 @@ ED_Alloc (progs_t *pr)
|
|||
edict_t *e;
|
||||
int start = pr->reserved_edicts ? *pr->reserved_edicts : 0;
|
||||
|
||||
if (!pr->num_edicts) {
|
||||
PR_RunError (pr, "Edicts not supported in this VM\n");
|
||||
}
|
||||
for (i = start + 1; i < *pr->num_edicts; i++) {
|
||||
e = EDICT_NUM (pr, i);
|
||||
// the first couple seconds of server time can involve a lot of
|
||||
|
@ -145,6 +136,10 @@ ED_Free (progs_t *pr, edict_t *ed)
|
|||
VISIBLE void
|
||||
ED_PrintNum (progs_t *pr, pr_int_t ent)
|
||||
{
|
||||
if (!pr->num_edicts) {
|
||||
Sys_Printf ("Edicts not supported in this VM\n");
|
||||
return;
|
||||
}
|
||||
ED_Print (pr, EDICT_NUM (pr, ent));
|
||||
}
|
||||
|
||||
|
@ -158,13 +153,17 @@ ED_PrintEdicts (progs_t *pr, const char *fieldval)
|
|||
{
|
||||
pr_int_t i;
|
||||
int count;
|
||||
ddef_t *def;
|
||||
pr_def_t *def;
|
||||
|
||||
def = PR_FindField(pr, "classname");
|
||||
|
||||
if (!pr->num_edicts) {
|
||||
Sys_Printf ("Edicts not supported in this VM\n");
|
||||
return;
|
||||
}
|
||||
if (fieldval && fieldval[0] && def) {
|
||||
count = 0;
|
||||
for (i = 0; i < *(pr)->num_edicts; i++)
|
||||
for (i = 0; i < *pr->num_edicts; i++)
|
||||
if (strequal(fieldval,
|
||||
E_GSTRING (pr, EDICT_NUM(pr, i), def->ofs))) {
|
||||
ED_PrintNum (pr, i);
|
||||
|
@ -172,9 +171,9 @@ ED_PrintEdicts (progs_t *pr, const char *fieldval)
|
|||
}
|
||||
Sys_Printf ("%i entities\n", count);
|
||||
} else {
|
||||
for (i = 0; i < *(pr)->num_edicts; i++)
|
||||
for (i = 0; i < *pr->num_edicts; i++)
|
||||
ED_PrintNum (pr, i);
|
||||
Sys_Printf ("%i entities\n", *(pr)->num_edicts);
|
||||
Sys_Printf ("%i entities\n", *pr->num_edicts);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -188,14 +187,18 @@ ED_Count (progs_t *pr)
|
|||
{
|
||||
pr_int_t i;
|
||||
int active, models, solid, step, zombie;
|
||||
ddef_t *solid_def;
|
||||
ddef_t *model_def;
|
||||
pr_def_t *solid_def;
|
||||
pr_def_t *model_def;
|
||||
edict_t *ent;
|
||||
|
||||
if (!pr->num_edicts) {
|
||||
Sys_Printf ("Edicts not supported in this VM\n");
|
||||
return;
|
||||
}
|
||||
solid_def = PR_FindField (pr, "solid");
|
||||
model_def = PR_FindField (pr, "model");
|
||||
active = models = solid = step = zombie = 0;
|
||||
for (i = 0; i < *(pr)->num_edicts; i++) {
|
||||
for (i = 0; i < *pr->num_edicts; i++) {
|
||||
ent = EDICT_NUM (pr, i);
|
||||
if (ent->free) {
|
||||
if (pr->globals.time && *pr->globals.time - ent->freetime <= 0.5)
|
||||
|
@ -209,7 +212,7 @@ ED_Count (progs_t *pr)
|
|||
models++;
|
||||
}
|
||||
|
||||
Sys_Printf ("num_edicts:%3i\n", *(pr)->num_edicts);
|
||||
Sys_Printf ("num_edicts:%3i\n", *pr->num_edicts);
|
||||
Sys_Printf ("active :%3i\n", active);
|
||||
Sys_Printf ("view :%3i\n", models);
|
||||
Sys_Printf ("touch :%3i\n", solid);
|
||||
|
@ -234,7 +237,7 @@ ED_NumForEdict (progs_t *pr, edict_t *e)
|
|||
|
||||
b = NUM_FOR_BAD_EDICT (pr, e);
|
||||
|
||||
if (b && (b < 0 || b >= *(pr)->num_edicts))
|
||||
if (b && (b < 0 || b >= *pr->num_edicts))
|
||||
PR_RunError (pr, "NUM_FOR_EDICT: bad pointer %d %p %p", b, e,
|
||||
*(pr)->edicts);
|
||||
|
||||
|
@ -244,6 +247,9 @@ ED_NumForEdict (progs_t *pr, edict_t *e)
|
|||
qboolean
|
||||
PR_EdictValid (progs_t *pr, pr_int_t e)
|
||||
{
|
||||
if (!pr->num_edicts) {
|
||||
return false;
|
||||
}
|
||||
if (e < 0 || e >= pr->pr_edictareasize)
|
||||
return false;
|
||||
if (e % pr->pr_edict_size)
|
||||
|
|
|
@ -68,41 +68,45 @@ PR_RunError (progs_t * pr, const char *error, ...)
|
|||
|
||||
// dump the stack so PR_Error can shutdown functions
|
||||
pr->pr_depth = 0;
|
||||
pr->localstack_used = 0;
|
||||
|
||||
PR_Error (pr, "Program error: %s", string->str);
|
||||
}
|
||||
|
||||
VISIBLE void
|
||||
PR_SaveParams (progs_t *pr)
|
||||
VISIBLE pr_stashed_params_t *
|
||||
_PR_SaveParams (progs_t *pr, pr_stashed_params_t *params)
|
||||
{
|
||||
int i;
|
||||
int size = pr->pr_param_size * sizeof (pr_type_t);
|
||||
|
||||
pr->pr_param_ptrs[0] = pr->pr_params[0];
|
||||
pr->pr_param_ptrs[1] = pr->pr_params[1];
|
||||
params->param_ptrs[0] = pr->pr_params[0];
|
||||
params->param_ptrs[1] = pr->pr_params[1];
|
||||
pr->pr_params[0] = pr->pr_real_params[0];
|
||||
pr->pr_params[1] = pr->pr_real_params[1];
|
||||
for (i = 0; i < pr->pr_argc; i++) {
|
||||
memcpy (pr->pr_saved_params + i * pr->pr_param_size,
|
||||
memcpy (params->params + i * pr->pr_param_size,
|
||||
pr->pr_real_params[i], size);
|
||||
if (i < 2)
|
||||
memcpy (pr->pr_real_params[i], pr->pr_param_ptrs[0], size);
|
||||
if (i < 2) { //XXX FIXME what the what?!?
|
||||
memcpy (pr->pr_real_params[i], params->param_ptrs[0], size);
|
||||
}
|
||||
}
|
||||
pr->pr_saved_argc = pr->pr_argc;
|
||||
params->argc = pr->pr_argc;
|
||||
return params;
|
||||
}
|
||||
|
||||
VISIBLE void
|
||||
PR_RestoreParams (progs_t *pr)
|
||||
PR_RestoreParams (progs_t *pr, pr_stashed_params_t *params)
|
||||
{
|
||||
int i;
|
||||
int size = pr->pr_param_size * sizeof (pr_type_t);
|
||||
|
||||
pr->pr_params[0] = pr->pr_param_ptrs[0];
|
||||
pr->pr_params[1] = pr->pr_param_ptrs[1];
|
||||
pr->pr_argc = pr->pr_saved_argc;
|
||||
for (i = 0; i < pr->pr_argc; i++)
|
||||
pr->pr_params[0] = params->param_ptrs[0];
|
||||
pr->pr_params[1] = params->param_ptrs[1];
|
||||
pr->pr_argc = params->argc;
|
||||
for (i = 0; i < pr->pr_argc; i++) {
|
||||
memcpy (pr->pr_real_params[i],
|
||||
pr->pr_saved_params + i * pr->pr_param_size, size);
|
||||
params->params + i * pr->pr_param_size, size);
|
||||
}
|
||||
}
|
||||
|
||||
VISIBLE inline void
|
||||
|
@ -119,7 +123,8 @@ PR_PushFrame (progs_t *pr)
|
|||
frame->f = pr->pr_xfunction;
|
||||
frame->tstr = pr->pr_xtstr;
|
||||
|
||||
pr->pr_xtstr = 0;
|
||||
pr->pr_xtstr = pr->pr_pushtstr;
|
||||
pr->pr_pushtstr = 0;
|
||||
pr->pr_xfunction = 0;
|
||||
}
|
||||
|
||||
|
@ -133,6 +138,17 @@ PR_PopFrame (progs_t *pr)
|
|||
|
||||
if (pr->pr_xtstr)
|
||||
PR_FreeTempStrings (pr);
|
||||
// normally, this won't happen, but if a builtin pushed a temp string
|
||||
// when calling a function and the callee was another builtin that
|
||||
// did not call a progs function, then the push strings will still be
|
||||
// valid because PR_EnterFunction was never called
|
||||
// however, not if a temp string survived: better to hold on to the push
|
||||
// strings a little longer than lose one erroneously
|
||||
if (!pr->pr_xtstr && pr->pr_pushtstr) {
|
||||
pr->pr_xtstr = pr->pr_pushtstr;
|
||||
pr->pr_pushtstr = 0;
|
||||
PR_FreeTempStrings (pr);
|
||||
}
|
||||
|
||||
// up stack
|
||||
frame = pr->pr_stack + --pr->pr_depth;
|
||||
|
@ -183,6 +199,7 @@ PR_EnterFunction (progs_t *pr, bfunction_t *f)
|
|||
if (pr->pr_params[i] != pr->pr_real_params[i]) {
|
||||
copy_param (pr->pr_real_params[i], pr->pr_params[i],
|
||||
f->parm_size[i].size);
|
||||
pr->pr_params[i] = pr->pr_real_params[i];
|
||||
}
|
||||
}
|
||||
} else if (f->numparms < 0) {
|
||||
|
@ -194,6 +211,7 @@ PR_EnterFunction (progs_t *pr, bfunction_t *f)
|
|||
if (pr->pr_params[i] != pr->pr_real_params[i]) {
|
||||
copy_param (pr->pr_real_params[i], pr->pr_params[i],
|
||||
f->parm_size[i].size);
|
||||
pr->pr_params[i] = pr->pr_real_params[i];
|
||||
}
|
||||
}
|
||||
dparmsize_t parmsize = { pr->pr_param_size, pr->pr_param_alignment };
|
||||
|
@ -205,6 +223,7 @@ PR_EnterFunction (progs_t *pr, bfunction_t *f)
|
|||
if (pr->pr_params[i] != pr->pr_real_params[i]) {
|
||||
copy_param (pr->pr_real_params[i], pr->pr_params[i],
|
||||
parmsize.size);
|
||||
pr->pr_params[i] = pr->pr_real_params[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -385,6 +404,14 @@ check_stack_pointer (progs_t *pr, pointer_t stack, int size)
|
|||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
pr_memset (pr_type_t *dst, int val, int count)
|
||||
{
|
||||
while (count-- > 0) {
|
||||
(*dst++).integer_var = val;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
PR_ExecuteProgram
|
||||
|
||||
|
@ -436,7 +463,16 @@ PR_ExecuteProgram (progs_t *pr, func_t fnum)
|
|||
if (pr->pr_trace)
|
||||
PR_PrintStatement (pr, st, 1);
|
||||
|
||||
switch (st->op) {
|
||||
if (st->op & OP_BREAK) {
|
||||
if (pr->breakpoint_handler) {
|
||||
pr->breakpoint_handler (pr);
|
||||
} else {
|
||||
PR_RunError (pr, "breakpoint hit");
|
||||
}
|
||||
}
|
||||
|
||||
pr_opcode_e op = st->op & ~OP_BREAK;
|
||||
switch (op) {
|
||||
case OP_ADD_D:
|
||||
OPC_double_var = OPA_double_var + OPB_double_var;
|
||||
break;
|
||||
|
@ -1580,7 +1616,23 @@ op_call:
|
|||
pr->pr_globals + OPA.integer_var,
|
||||
st->b * 4);
|
||||
break;
|
||||
|
||||
case OP_MEMSETI:
|
||||
pr_memset (&OPC, OPA.integer_var, st->b);
|
||||
break;
|
||||
case OP_MEMSETP:
|
||||
if (pr_boundscheck->int_val) {
|
||||
PR_BoundsCheckSize (pr, OPC.pointer_var, OPB.integer_var);
|
||||
}
|
||||
pr_memset (pr->pr_globals + OPC.pointer_var, OPA.integer_var,
|
||||
OPB.integer_var);
|
||||
break;
|
||||
case OP_MEMSETPI:
|
||||
if (pr_boundscheck->int_val) {
|
||||
PR_BoundsCheckSize (pr, OPC.pointer_var, st->b);
|
||||
}
|
||||
pr_memset (pr->pr_globals + OPC.pointer_var, OPA.integer_var,
|
||||
st->b);
|
||||
break;
|
||||
case OP_GE_D:
|
||||
OPC.float_var = OPA_double_var >= OPB_double_var;
|
||||
break;
|
||||
|
@ -1636,6 +1688,7 @@ op_call:
|
|||
watch->integer_var);
|
||||
}
|
||||
exit_program:
|
||||
pr->pr_argc = 0;
|
||||
Sys_PopErrorHandler ();
|
||||
Sys_PopSignalHook ();
|
||||
}
|
||||
|
|
|
@ -34,22 +34,17 @@
|
|||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "QF/cmd.h"
|
||||
#include "QF/crc.h"
|
||||
#include "QF/cvar.h"
|
||||
#include "QF/dstring.h"
|
||||
#include "QF/hash.h"
|
||||
#include "QF/mathlib.h"
|
||||
#include "QF/progs.h"
|
||||
#include "QF/qdefs.h"
|
||||
#include "QF/qendian.h"
|
||||
#include "QF/quakefs.h"
|
||||
#include "QF/sys.h"
|
||||
#include "QF/zone.h"
|
||||
#include "QF/va.h"
|
||||
|
||||
#include "compat.h"
|
||||
|
||||
|
@ -70,8 +65,8 @@ static const char *
|
|||
var_get_key (const void *d, void *_pr)
|
||||
{
|
||||
progs_t *pr = (progs_t*)_pr;
|
||||
ddef_t *def = (ddef_t*)d;
|
||||
return PR_GetString (pr, def->s_name);
|
||||
pr_def_t *def = (pr_def_t*)d;
|
||||
return PR_GetString (pr, def->name);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -81,9 +76,11 @@ file_error (progs_t *pr, const char *path)
|
|||
}
|
||||
|
||||
static void *
|
||||
load_file (progs_t *pr, const char *path)
|
||||
load_file (progs_t *pr, const char *path, off_t *size)
|
||||
{
|
||||
return QFS_LoadHunkFile (QFS_FOpenFile (path));
|
||||
void *data = QFS_LoadHunkFile (QFS_FOpenFile (path));
|
||||
*size = qfs_filesize;
|
||||
return data;
|
||||
}
|
||||
|
||||
static void *
|
||||
|
@ -117,6 +114,9 @@ PR_LoadProgsFile (progs_t *pr, QFile *file, int size)
|
|||
dprograms_t progs;
|
||||
byte *base;
|
||||
byte *heap;
|
||||
pr_def_t *xdefs_def = 0;
|
||||
ddef_t *global_ddefs;
|
||||
ddef_t *field_ddefs;
|
||||
|
||||
if (!pr->file_error)
|
||||
pr->file_error = file_error;
|
||||
|
@ -128,7 +128,6 @@ PR_LoadProgsFile (progs_t *pr, QFile *file, int size)
|
|||
pr->free_progs_mem = free_progs_mem;
|
||||
|
||||
PR_Resources_Clear (pr);
|
||||
PR_ClearReturnStrings (pr);
|
||||
if (pr->progs)
|
||||
pr->free_progs_mem (pr, pr->progs);
|
||||
pr->progs = 0;
|
||||
|
@ -184,6 +183,7 @@ PR_LoadProgsFile (progs_t *pr, QFile *file, int size)
|
|||
pr->pr_edict_size = align_size (pr->pr_edict_size);
|
||||
|
||||
pr->pr_edictareasize = pr->max_edicts * pr->pr_edict_size;
|
||||
pr->edict_parse = 0;
|
||||
|
||||
mem_size = pr->progs_size + pr->zone_size + pr->pr_edictareasize
|
||||
+ pr->stack_size;
|
||||
|
@ -202,12 +202,11 @@ PR_LoadProgsFile (progs_t *pr, QFile *file, int size)
|
|||
base -= sizeof (progs); // offsets are from file start
|
||||
heap = ((byte *) pr->progs + pr->progs_size + pr->pr_edictareasize);
|
||||
|
||||
pr->float_promoted = progs.version == PROG_VERSION;
|
||||
|
||||
if (pr->edicts) {
|
||||
*pr->edicts = (edict_t *)((byte *) pr->progs + pr->progs_size);
|
||||
}
|
||||
|
||||
pr->zone = 0;
|
||||
if (pr->zone_size) {
|
||||
//FIXME zone_size needs to be at least as big as memzone_t, but
|
||||
//memzone_t is opaque so its size is unknown
|
||||
|
@ -218,8 +217,8 @@ PR_LoadProgsFile (progs_t *pr, QFile *file, int size)
|
|||
(dfunction_t *) (base + pr->progs->ofs_functions);
|
||||
pr->pr_strings = (char *) base + pr->progs->ofs_strings;
|
||||
pr->pr_stringsize = (char *) heap + pr->zone_size - (char *) base;
|
||||
pr->pr_globaldefs = (ddef_t *) (base + pr->progs->ofs_globaldefs);
|
||||
pr->pr_fielddefs = (ddef_t *) (base + pr->progs->ofs_fielddefs);
|
||||
global_ddefs = (ddef_t *) (base + pr->progs->ofs_globaldefs);
|
||||
field_ddefs = (ddef_t *) (base + pr->progs->ofs_fielddefs);
|
||||
pr->pr_statements = (dstatement_t *) (base + pr->progs->ofs_statements);
|
||||
|
||||
pr->pr_globals = (pr_type_t *) (base + pr->progs->ofs_globals);
|
||||
|
@ -270,24 +269,67 @@ PR_LoadProgsFile (progs_t *pr, QFile *file, int size)
|
|||
Hash_Add (pr->function_hash, &pr->pr_functions[i]);
|
||||
}
|
||||
|
||||
if (pr->pr_globaldefs) {
|
||||
free (pr->pr_globaldefs);
|
||||
}
|
||||
pr->pr_globaldefs = calloc (pr->progs->numglobaldefs, sizeof (pr_def_t));
|
||||
|
||||
for (i = 0; i < pr->progs->numglobaldefs; i++) {
|
||||
pr->pr_globaldefs[i].type = LittleShort (pr->pr_globaldefs[i].type);
|
||||
pr->pr_globaldefs[i].ofs = LittleShort (pr->pr_globaldefs[i].ofs);
|
||||
pr->pr_globaldefs[i].s_name = LittleLong (pr->pr_globaldefs[i].s_name);
|
||||
pr_ushort_t safe_type = global_ddefs[i].type & ~DEF_SAVEGLOBAL;
|
||||
global_ddefs[i].type = LittleShort (global_ddefs[i].type);
|
||||
global_ddefs[i].ofs = LittleShort (global_ddefs[i].ofs);
|
||||
global_ddefs[i].s_name = LittleLong (global_ddefs[i].s_name);
|
||||
|
||||
pr->pr_globaldefs[i].type = global_ddefs[i].type;
|
||||
pr->pr_globaldefs[i].size = pr_type_size[safe_type];
|
||||
pr->pr_globaldefs[i].ofs = global_ddefs[i].ofs;
|
||||
pr->pr_globaldefs[i].name = global_ddefs[i].s_name;
|
||||
Hash_Add (pr->global_hash, &pr->pr_globaldefs[i]);
|
||||
}
|
||||
|
||||
if (pr->pr_fielddefs) {
|
||||
free (pr->pr_fielddefs);
|
||||
}
|
||||
pr->pr_fielddefs = calloc (pr->progs->numfielddefs, sizeof (pr_def_t));
|
||||
for (i = 0; i < pr->progs->numfielddefs; i++) {
|
||||
pr->pr_fielddefs[i].type = LittleShort (pr->pr_fielddefs[i].type);
|
||||
if (pr->pr_fielddefs[i].type & DEF_SAVEGLOBAL)
|
||||
PR_Error (pr, "PR_LoadProgs: pr_fielddefs[i].type & DEF_SAVEGLOBAL");
|
||||
pr->pr_fielddefs[i].ofs = LittleShort (pr->pr_fielddefs[i].ofs);
|
||||
pr->pr_fielddefs[i].s_name = LittleLong (pr->pr_fielddefs[i].s_name);
|
||||
field_ddefs[i].type = LittleShort (field_ddefs[i].type);
|
||||
if (field_ddefs[i].type & DEF_SAVEGLOBAL)
|
||||
PR_Error (pr, "PR_LoadProgs: DEF_SAVEGLOBAL on field def %zd", i);
|
||||
field_ddefs[i].ofs = LittleShort (field_ddefs[i].ofs);
|
||||
field_ddefs[i].s_name = LittleLong (field_ddefs[i].s_name);
|
||||
|
||||
pr->pr_fielddefs[i].type = field_ddefs[i].type;
|
||||
pr->pr_fielddefs[i].ofs = field_ddefs[i].ofs;
|
||||
pr->pr_fielddefs[i].name = field_ddefs[i].s_name;
|
||||
Hash_Add (pr->field_hash, &pr->pr_fielddefs[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < pr->progs->numglobals; i++)
|
||||
((int *) pr->pr_globals)[i] = LittleLong (((int *) pr->pr_globals)[i]);
|
||||
|
||||
xdefs_def = PR_FindGlobal (pr, ".xdefs");
|
||||
if (xdefs_def) {
|
||||
pr_xdefs_t *xdefs = &G_STRUCT (pr, pr_xdefs_t, xdefs_def->ofs);
|
||||
xdef_t *xdef = &G_STRUCT (pr, xdef_t, xdefs->xdefs);
|
||||
pr_def_t *def;
|
||||
for (def = pr->pr_globaldefs, i = 0; i < pr->progs->numglobaldefs;
|
||||
i++, xdef++, def++) {
|
||||
def->ofs = xdef->ofs;
|
||||
def->type_encoding = xdef->type;
|
||||
}
|
||||
for (def = pr->pr_fielddefs, i = 0; i < pr->progs->numfielddefs;
|
||||
i++, xdef++, def++) {
|
||||
def->ofs = xdef->ofs;
|
||||
def->type_encoding = xdef->type;
|
||||
}
|
||||
}
|
||||
pr->pr_trace = 0;
|
||||
pr->pr_trace_depth = 0;
|
||||
pr->pr_xfunction = 0;
|
||||
pr->pr_xstatement = 0;
|
||||
pr->pr_depth = 0;
|
||||
pr->localstack_used = 0;
|
||||
pr->pr_argc = 0;
|
||||
}
|
||||
|
||||
VISIBLE void
|
||||
|
@ -321,7 +363,7 @@ PR_AddLoadFinishFunc (progs_t *pr, int (*func)(progs_t *))
|
|||
static int
|
||||
pr_run_ctors (progs_t *pr)
|
||||
{
|
||||
pr_int_t fnum;
|
||||
pr_uint_t fnum;
|
||||
dfunction_t *func;
|
||||
|
||||
for (fnum = 0; fnum < pr->progs->numfunctions; fnum++) {
|
||||
|
@ -333,9 +375,7 @@ pr_run_ctors (progs_t *pr)
|
|||
}
|
||||
|
||||
static int (*load_funcs_1[])(progs_t *) = {
|
||||
PR_LoadStrings,
|
||||
PR_RelocateBuiltins,
|
||||
PR_LoadDebug,
|
||||
0,
|
||||
};
|
||||
|
||||
|
@ -427,10 +467,12 @@ PR_Init_Cvars (void)
|
|||
}
|
||||
|
||||
VISIBLE void
|
||||
PR_Init (void)
|
||||
PR_Init (progs_t *pr)
|
||||
{
|
||||
PR_Opcode_Init ();
|
||||
PR_Debug_Init ();
|
||||
PR_Opcode_Init (); // idempotent
|
||||
PR_Resources_Init (pr);
|
||||
PR_Strings_Init (pr);
|
||||
PR_Debug_Init (pr);
|
||||
}
|
||||
|
||||
VISIBLE void
|
||||
|
|
|
@ -46,9 +46,9 @@
|
|||
|
||||
#include "compat.h"
|
||||
|
||||
hashtab_t *opcode_table;
|
||||
static hashtab_t *opcode_table;
|
||||
|
||||
VISIBLE int pr_type_size[ev_type_count] = {
|
||||
VISIBLE const pr_ushort_t pr_type_size[ev_type_count] = {
|
||||
1, // ev_void
|
||||
1, // ev_string
|
||||
1, // ev_float
|
||||
|
@ -62,9 +62,10 @@ VISIBLE int pr_type_size[ev_type_count] = {
|
|||
1, // ev_uinteger
|
||||
0, // ev_short value in opcode
|
||||
2, // ev_double
|
||||
0, // ev_invalid not a valid/simple type
|
||||
};
|
||||
|
||||
VISIBLE const char *pr_type_name[ev_type_count] = {
|
||||
VISIBLE const char * const pr_type_name[ev_type_count] = {
|
||||
"void",
|
||||
"string",
|
||||
"float",
|
||||
|
@ -97,7 +98,7 @@ VISIBLE const char *pr_type_name[ev_type_count] = {
|
|||
// c operand c
|
||||
// x place holder for P (padding)
|
||||
// 0-7 parameter index (for P)
|
||||
VISIBLE opcode_t pr_opcodes[] = {
|
||||
VISIBLE const opcode_t pr_opcodes[] = {
|
||||
{"<DONE>", "done", OP_DONE, false, // OP_DONE is actually the same as
|
||||
ev_entity, ev_field, ev_void, // OP_RETURN, the types are bogus
|
||||
PROG_ID_VERSION,
|
||||
|
@ -543,12 +544,12 @@ VISIBLE opcode_t pr_opcodes[] = {
|
|||
{"&", "lea", OP_LEA, false,
|
||||
ev_pointer, ev_integer, ev_pointer,
|
||||
PROG_VERSION,
|
||||
"%Ga, %Gb, %gc",
|
||||
"(%Ga + %Gb), %gc",
|
||||
},
|
||||
{"&", "leai", OP_LEAI, false,
|
||||
ev_pointer, ev_short, ev_pointer,
|
||||
PROG_VERSION,
|
||||
"%Ga, %sb, %gc",
|
||||
"(%Ga + %sb), %gc",
|
||||
},
|
||||
|
||||
{"<CONV>", "conv.if", OP_CONV_IF, false,
|
||||
|
@ -1180,8 +1181,23 @@ VISIBLE opcode_t pr_opcodes[] = {
|
|||
{"<MOVEP>", "movepi", OP_MOVEPI, true,
|
||||
ev_pointer, ev_short, ev_pointer,
|
||||
PROG_VERSION,
|
||||
"%Ga, %sb, %Gc",
|
||||
},
|
||||
{"<MEMSET>", "memseti", OP_MEMSETI, true,
|
||||
ev_integer, ev_short, ev_void,
|
||||
PROG_VERSION,
|
||||
"%Ga, %sb, %gc",
|
||||
},
|
||||
{"<MEMSETP>", "memsetp", OP_MEMSETP, true,
|
||||
ev_integer, ev_integer, ev_pointer,
|
||||
PROG_VERSION,
|
||||
"%Ga, %Gb, %Gc",
|
||||
},
|
||||
{"<MEMSETP>", "memsetpi", OP_MEMSETPI, true,
|
||||
ev_integer, ev_short, ev_pointer,
|
||||
PROG_VERSION,
|
||||
"%Ga, %sb, %Gc",
|
||||
},
|
||||
|
||||
{"<PUSH>", "push.s", OP_PUSH_S, false,
|
||||
ev_string, ev_invalid, ev_invalid,
|
||||
|
@ -1491,13 +1507,17 @@ PR_Opcode (pr_short_t opcode)
|
|||
VISIBLE void
|
||||
PR_Opcode_Init (void)
|
||||
{
|
||||
opcode_t *op;
|
||||
const opcode_t *op;
|
||||
|
||||
if (opcode_table) {
|
||||
// already initialized
|
||||
return;
|
||||
}
|
||||
opcode_table = Hash_NewTable (1021, 0, 0, 0);
|
||||
Hash_SetHashCompare (opcode_table, opcode_get_hash, opcode_compare);
|
||||
|
||||
for (op = pr_opcodes; op->name; op++) {
|
||||
Hash_AddElement (opcode_table, op);
|
||||
Hash_AddElement (opcode_table, (void *) op);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1535,7 +1555,7 @@ check_global (progs_t *pr, dstatement_t *st, opcode_t *op, etype_t type,
|
|||
unsigned short operand, int check_denorm)
|
||||
{
|
||||
const char *msg;
|
||||
ddef_t *def;
|
||||
pr_def_t *def;
|
||||
|
||||
switch (type) {
|
||||
case ev_short:
|
||||
|
@ -1695,6 +1715,9 @@ PR_Check_Opcodes (progs_t *pr)
|
|||
check_global_size (pr, st, op, st->b, st->a);
|
||||
check_global_size (pr, st, op, st->b, st->c);
|
||||
break;
|
||||
case OP_MEMSETI:
|
||||
check_global_size (pr, st, op, st->b, st->c);
|
||||
break;
|
||||
case OP_PUSHB_F:
|
||||
case OP_PUSHB_S:
|
||||
case OP_PUSHB_ENT:
|
||||
|
|
|
@ -43,21 +43,12 @@
|
|||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
#include "QF/cbuf.h"
|
||||
#include "QF/crc.h"
|
||||
#include "QF/cvar.h"
|
||||
#include "QF/dstring.h"
|
||||
#include "QF/hash.h"
|
||||
#include "QF/mathlib.h"
|
||||
#include "QF/progs.h"
|
||||
#include "QF/qdefs.h"
|
||||
#include "QF/qfplist.h"
|
||||
#include "QF/qendian.h"
|
||||
#include "QF/quakefs.h"
|
||||
#include "QF/script.h"
|
||||
#include "QF/sys.h"
|
||||
#include "QF/zone.h"
|
||||
#include "QF/va.h"
|
||||
|
||||
#include "compat.h"
|
||||
|
||||
|
@ -68,15 +59,11 @@
|
|||
Easier to parse than PR_ValueString
|
||||
*/
|
||||
static const char *
|
||||
PR_UglyValueString (progs_t *pr, etype_t type, pr_type_t *val)
|
||||
PR_UglyValueString (progs_t *pr, etype_t type, pr_type_t *val, dstring_t *line)
|
||||
{
|
||||
static dstring_t *line = 0;
|
||||
ddef_t *def;
|
||||
pr_def_t *def;
|
||||
dfunction_t *f;
|
||||
|
||||
if (!line)
|
||||
line = dstring_new ();
|
||||
|
||||
type &= ~DEF_SAVEGLOBAL;
|
||||
|
||||
switch (type) {
|
||||
|
@ -93,7 +80,7 @@ PR_UglyValueString (progs_t *pr, etype_t type, pr_type_t *val)
|
|||
break;
|
||||
case ev_field:
|
||||
def = PR_FieldAtOfs (pr, val->integer_var);
|
||||
dsprintf (line, "%s", PR_GetString (pr, def->s_name));
|
||||
dsprintf (line, "%s", PR_GetString (pr, def->name));
|
||||
break;
|
||||
case ev_void:
|
||||
dstring_copystr (line, "void");
|
||||
|
@ -121,6 +108,7 @@ PR_UglyValueString (progs_t *pr, etype_t type, pr_type_t *val)
|
|||
VISIBLE plitem_t *
|
||||
ED_EntityDict (progs_t *pr, edict_t *ed)
|
||||
{
|
||||
dstring_t *dstr = dstring_newstr ();
|
||||
plitem_t *entity = PL_NewDictionary ();
|
||||
pr_uint_t i;
|
||||
int j;
|
||||
|
@ -131,9 +119,9 @@ ED_EntityDict (progs_t *pr, edict_t *ed)
|
|||
|
||||
if (!ed->free) {
|
||||
for (i = 0; i < pr->progs->numfielddefs; i++) {
|
||||
ddef_t *d = &pr->pr_fielddefs[i];
|
||||
pr_def_t *d = &pr->pr_fielddefs[i];
|
||||
|
||||
name = PR_GetString (pr, d->s_name);
|
||||
name = PR_GetString (pr, d->name);
|
||||
if (!name[0])
|
||||
continue; // skip unnamed fields
|
||||
if (name[strlen (name) - 2] == '_')
|
||||
|
@ -149,10 +137,11 @@ ED_EntityDict (progs_t *pr, edict_t *ed)
|
|||
if (j == pr_type_size[type])
|
||||
continue;
|
||||
|
||||
value = PR_UglyValueString (pr, type, v);
|
||||
value = PR_UglyValueString (pr, type, v, dstr);
|
||||
PL_D_AddObject (entity, name, PL_NewString (value));
|
||||
}
|
||||
}
|
||||
dstring_delete (dstr);
|
||||
return entity;
|
||||
}
|
||||
|
||||
|
@ -165,11 +154,12 @@ ED_EntityDict (progs_t *pr, edict_t *ed)
|
|||
VISIBLE plitem_t *
|
||||
ED_GlobalsDict (progs_t *pr)
|
||||
{
|
||||
dstring_t *dstr = dstring_newstr ();
|
||||
plitem_t *globals = PL_NewDictionary ();
|
||||
pr_uint_t i;
|
||||
const char *name;
|
||||
const char *value;
|
||||
ddef_t *def;
|
||||
pr_def_t *def;
|
||||
int type;
|
||||
|
||||
for (i = 0; i < pr->progs->numglobaldefs; i++) {
|
||||
|
@ -182,10 +172,11 @@ ED_GlobalsDict (progs_t *pr)
|
|||
if (type != ev_string && type != ev_float && type != ev_entity)
|
||||
continue;
|
||||
|
||||
name = PR_GetString (pr, def->s_name);
|
||||
value = PR_UglyValueString (pr, type, &pr->pr_globals[def->ofs]);
|
||||
name = PR_GetString (pr, def->name);
|
||||
value = PR_UglyValueString (pr, type, &pr->pr_globals[def->ofs], dstr);
|
||||
PL_D_AddObject (globals, name, PL_NewString (value));
|
||||
}
|
||||
dstring_delete (dstr);
|
||||
return globals;
|
||||
}
|
||||
|
||||
|
@ -222,11 +213,11 @@ ED_NewString (progs_t *pr, const char *string)
|
|||
returns false if error
|
||||
*/
|
||||
VISIBLE qboolean
|
||||
ED_ParseEpair (progs_t *pr, pr_type_t *base, ddef_t *key, const char *s)
|
||||
ED_ParseEpair (progs_t *pr, pr_type_t *base, pr_def_t *key, const char *s)
|
||||
{
|
||||
int i;
|
||||
char *string;
|
||||
ddef_t *def;
|
||||
pr_def_t *def;
|
||||
char *v, *w;
|
||||
pr_type_t *d;
|
||||
dfunction_t *func;
|
||||
|
@ -301,6 +292,7 @@ ED_ParseEpair (progs_t *pr, pr_type_t *base, ddef_t *key, const char *s)
|
|||
VISIBLE plitem_t *
|
||||
ED_ConvertToPlist (script_t *script, int nohack)
|
||||
{
|
||||
dstring_t *dstr = dstring_newstr ();
|
||||
plitem_t *plist = PL_NewArray ();
|
||||
plitem_t *ent;
|
||||
plitem_t *key;
|
||||
|
@ -341,15 +333,18 @@ ED_ConvertToPlist (script_t *script, int nohack)
|
|||
token = script->token->str;
|
||||
if (strequal (token, "}"))
|
||||
Sys_Error ("ED_ConvertToPlist: closing brace without data");
|
||||
if (anglehack)
|
||||
value = PL_NewString (va ("0 %s 0", token));
|
||||
else
|
||||
if (anglehack) {
|
||||
dsprintf (dstr, "0 %s 0", token);
|
||||
value = PL_NewString (dstr->str);
|
||||
} else {
|
||||
value = PL_NewString (token);
|
||||
}
|
||||
PL_D_AddObject (ent, PL_String (key), value);
|
||||
PL_Free (key);
|
||||
}
|
||||
PL_A_AddObject (plist, ent);
|
||||
}
|
||||
dstring_delete (dstr);
|
||||
return plist;
|
||||
}
|
||||
|
||||
|
@ -357,8 +352,8 @@ ED_ConvertToPlist (script_t *script, int nohack)
|
|||
VISIBLE void
|
||||
ED_InitGlobals (progs_t *pr, plitem_t *globals)
|
||||
{
|
||||
ddef_t vector_def;
|
||||
ddef_t *global;
|
||||
pr_def_t vector_def;
|
||||
pr_def_t *global;
|
||||
plitem_t *keys;
|
||||
int count;
|
||||
const char *global_name;
|
||||
|
@ -405,7 +400,7 @@ ED_InitGlobals (progs_t *pr, plitem_t *globals)
|
|||
VISIBLE void
|
||||
ED_InitEntity (progs_t *pr, plitem_t *entity, edict_t *ent)
|
||||
{
|
||||
ddef_t *field;
|
||||
pr_def_t *field;
|
||||
plitem_t *keys;
|
||||
const char *field_name;
|
||||
const char *value;
|
||||
|
@ -524,6 +519,7 @@ ED_LoadFromFile (progs_t *pr, const char *data)
|
|||
PR_PushFrame (pr);
|
||||
PR_RESET_PARAMS (pr);
|
||||
P_INT (pr, 0) = PR_SetTempString (pr, data);
|
||||
pr->pr_argc = 1;
|
||||
PR_ExecuteProgram (pr, pr->edict_parse);
|
||||
PR_PopFrame (pr);
|
||||
return;
|
||||
|
|
|
@ -34,59 +34,59 @@
|
|||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "QF/cmd.h"
|
||||
#include "QF/crc.h"
|
||||
#include "QF/cvar.h"
|
||||
#include "QF/hash.h"
|
||||
#include "QF/progs.h"
|
||||
#include "QF/qdefs.h"
|
||||
#include "QF/qendian.h"
|
||||
#include "QF/quakefs.h"
|
||||
#include "QF/sys.h"
|
||||
#include "QF/zone.h"
|
||||
#include "QF/va.h"
|
||||
|
||||
#include "compat.h"
|
||||
|
||||
static const char param_str[] = ".param_0";
|
||||
|
||||
ddef_t *
|
||||
PR_GlobalAtOfs (progs_t * pr, pr_int_t ofs)
|
||||
pr_def_t *
|
||||
PR_SearchDefs (pr_def_t *defs, unsigned num_defs, pointer_t offset)
|
||||
{
|
||||
ddef_t *def;
|
||||
pr_uint_t i;
|
||||
// fuzzy bsearh
|
||||
unsigned left = 0;
|
||||
unsigned right = num_defs - 1;
|
||||
unsigned mid;
|
||||
|
||||
for (i = 0; i < pr->progs->numglobaldefs; i++) {
|
||||
def = &pr->pr_globaldefs[i];
|
||||
if (def->ofs == ofs)
|
||||
return def;
|
||||
if (!num_defs) {
|
||||
return 0;
|
||||
}
|
||||
return NULL;
|
||||
while (left != right) {
|
||||
mid = (left + right + 1) / 2;
|
||||
if (defs[mid].ofs > offset) {
|
||||
right = mid - 1;
|
||||
} else {
|
||||
left = mid;
|
||||
}
|
||||
}
|
||||
if (defs[left].ofs <= offset) {
|
||||
return defs + left;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
VISIBLE ddef_t *
|
||||
PR_FieldAtOfs (progs_t * pr, pr_int_t ofs)
|
||||
pr_def_t *
|
||||
PR_GlobalAtOfs (progs_t * pr, pointer_t ofs)
|
||||
{
|
||||
ddef_t *def;
|
||||
pr_uint_t i;
|
||||
|
||||
for (i = 0; i < pr->progs->numfielddefs; i++) {
|
||||
def = &pr->pr_fielddefs[i];
|
||||
if (def->ofs == ofs)
|
||||
return def;
|
||||
}
|
||||
return NULL;
|
||||
return PR_SearchDefs (pr->pr_globaldefs, pr->progs->numglobaldefs, ofs);
|
||||
}
|
||||
|
||||
VISIBLE ddef_t *
|
||||
VISIBLE pr_def_t *
|
||||
PR_FieldAtOfs (progs_t * pr, pointer_t ofs)
|
||||
{
|
||||
return PR_SearchDefs (pr->pr_fielddefs, pr->progs->numfielddefs, ofs);
|
||||
}
|
||||
|
||||
VISIBLE pr_def_t *
|
||||
PR_FindField (progs_t * pr, const char *name)
|
||||
{
|
||||
return Hash_Find (pr->field_hash, name);
|
||||
}
|
||||
|
||||
VISIBLE ddef_t *
|
||||
VISIBLE pr_def_t *
|
||||
PR_FindGlobal (progs_t * pr, const char *name)
|
||||
{
|
||||
return Hash_Find (pr->global_hash, name);
|
||||
|
@ -108,7 +108,7 @@ VISIBLE int
|
|||
PR_ResolveGlobals (progs_t *pr)
|
||||
{
|
||||
const char *sym;
|
||||
ddef_t *def;
|
||||
pr_def_t *def;
|
||||
int i;
|
||||
|
||||
if (pr->progs->version == PROG_ID_VERSION) {
|
||||
|
@ -124,11 +124,14 @@ PR_ResolveGlobals (progs_t *pr)
|
|||
pr->pr_param_size = OFS_PARM1 - OFS_PARM0;
|
||||
pr->pr_param_alignment = 0; // log2
|
||||
} else {
|
||||
char *param_n = alloca (sizeof (param_str));
|
||||
strcpy (param_n, param_str);
|
||||
if (!(def = PR_FindGlobal (pr, sym = ".return")))
|
||||
goto error;
|
||||
pr->pr_return = &pr->pr_globals[def->ofs];
|
||||
for (i = 0; i < MAX_PARMS; i++) {
|
||||
if (!(def = PR_FindGlobal (pr, sym = va(".param_%d", i))))
|
||||
param_n[sizeof (param_str) - 2] = i + '0';
|
||||
if (!(def = PR_FindGlobal (pr, sym = param_n)))
|
||||
goto error;
|
||||
pr->pr_params[i] = &pr->pr_globals[def->ofs];
|
||||
}
|
||||
|
@ -139,10 +142,6 @@ PR_ResolveGlobals (progs_t *pr)
|
|||
goto error;
|
||||
pr->pr_param_alignment = G_INT (pr, def->ofs);
|
||||
}
|
||||
if (pr->pr_saved_params)
|
||||
free (pr->pr_saved_params);
|
||||
pr->pr_saved_params = calloc (pr->pr_param_size * MAX_PARMS,
|
||||
sizeof (pr_type_t));
|
||||
memcpy (pr->pr_real_params, pr->pr_params, sizeof (pr->pr_params));
|
||||
if (!pr->globals.time) {
|
||||
if ((def = PR_FindGlobal (pr, "time")))
|
||||
|
@ -180,7 +179,7 @@ int
|
|||
PR_AccessField (progs_t *pr, const char *name, etype_t type,
|
||||
const char *file, int line)
|
||||
{
|
||||
ddef_t *def = PR_FindField (pr, name);
|
||||
pr_def_t *def = PR_FindField (pr, name);
|
||||
|
||||
if (!def)
|
||||
PR_Error (pr, "undefined field %s accessed at %s:%d", name, file, line);
|
||||
|
|
|
@ -42,26 +42,6 @@
|
|||
#include "QF/dstring.h"
|
||||
#include "QF/hash.h"
|
||||
#include "QF/progs.h"
|
||||
#include "QF/va.h"
|
||||
|
||||
typedef enum {
|
||||
str_free,
|
||||
str_static,
|
||||
str_dynamic,
|
||||
str_mutable,
|
||||
str_temp,
|
||||
str_return,
|
||||
} str_e;
|
||||
|
||||
struct strref_s {
|
||||
strref_t *next;
|
||||
strref_t **prev;
|
||||
str_e type;
|
||||
union {
|
||||
char *string;
|
||||
dstring_t *dstring;
|
||||
} s;
|
||||
};
|
||||
|
||||
// format adjustments
|
||||
#define FMT_ALTFORM (1<<0)
|
||||
|
@ -87,7 +67,45 @@ typedef struct fmt_item_s {
|
|||
struct fmt_item_s *next;
|
||||
} fmt_item_t;
|
||||
|
||||
static fmt_item_t *free_fmt_items;
|
||||
typedef struct strref_slot_s {
|
||||
struct strref_slot_s *next;
|
||||
struct strref_slot_s **prev;
|
||||
strref_t *strref;
|
||||
} strref_slot_t;
|
||||
|
||||
typedef struct prstr_resources_s {
|
||||
progs_t *pr;
|
||||
dstring_mem_t ds_mem;
|
||||
strref_t *free_string_refs;
|
||||
strref_t *static_strings;
|
||||
strref_t **string_map;
|
||||
strref_slot_t return_strings[PR_RS_SLOTS];
|
||||
strref_slot_t *rs_slot;
|
||||
unsigned dyn_str_size;
|
||||
struct hashtab_s *strref_hash;
|
||||
int num_strings;
|
||||
fmt_item_t *free_fmt_items;
|
||||
dstring_t *print_str;
|
||||
} prstr_resources_t;
|
||||
|
||||
typedef enum {
|
||||
str_free,
|
||||
str_static,
|
||||
str_dynamic,
|
||||
str_mutable,
|
||||
str_temp,
|
||||
str_return,
|
||||
} str_e;
|
||||
|
||||
struct strref_s {
|
||||
strref_t *next;
|
||||
strref_slot_t *rs_slot;
|
||||
str_e type;
|
||||
union {
|
||||
char *string;
|
||||
dstring_t *dstring;
|
||||
} s;
|
||||
};
|
||||
|
||||
static void *
|
||||
pr_strings_alloc (void *_pr, size_t size)
|
||||
|
@ -111,51 +129,50 @@ pr_strings_realloc (void *_pr, void *ptr, size_t size)
|
|||
}
|
||||
|
||||
static strref_t *
|
||||
new_string_ref (progs_t *pr)
|
||||
new_string_ref (prstr_resources_t *res)
|
||||
{
|
||||
strref_t *sr;
|
||||
if (!pr->free_string_refs) {
|
||||
if (!res->free_string_refs) {
|
||||
int i;
|
||||
size_t size;
|
||||
|
||||
pr->dyn_str_size++;
|
||||
size = pr->dyn_str_size * sizeof (strref_t *);
|
||||
pr->string_map = realloc (pr->string_map, size);
|
||||
if (!pr->string_map)
|
||||
PR_Error (pr, "out of memory");
|
||||
if (!(pr->free_string_refs = calloc (1024, sizeof (strref_t))))
|
||||
PR_Error (pr, "out of memory");
|
||||
pr->string_map[pr->dyn_str_size - 1] = pr->free_string_refs;
|
||||
for (i = 0, sr = pr->free_string_refs; i < 1023; i++, sr++)
|
||||
res->dyn_str_size++;
|
||||
size = res->dyn_str_size * sizeof (strref_t *);
|
||||
res->string_map = realloc (res->string_map, size);
|
||||
if (!res->string_map)
|
||||
PR_Error (res->pr, "out of memory");
|
||||
if (!(res->free_string_refs = calloc (1024, sizeof (strref_t))))
|
||||
PR_Error (res->pr, "out of memory");
|
||||
res->string_map[res->dyn_str_size - 1] = res->free_string_refs;
|
||||
for (i = 0, sr = res->free_string_refs; i < 1023; i++, sr++)
|
||||
sr->next = sr + 1;
|
||||
sr->next = 0;
|
||||
}
|
||||
sr = pr->free_string_refs;
|
||||
pr->free_string_refs = sr->next;
|
||||
sr = res->free_string_refs;
|
||||
res->free_string_refs = sr->next;
|
||||
sr->next = 0;
|
||||
sr->rs_slot = 0;
|
||||
return sr;
|
||||
}
|
||||
|
||||
static void
|
||||
free_string_ref (progs_t *pr, strref_t *sr)
|
||||
free_string_ref (prstr_resources_t *res, strref_t *sr)
|
||||
{
|
||||
sr->type = str_free;
|
||||
if (sr->prev)
|
||||
*sr->prev = sr->next;
|
||||
sr->next = pr->free_string_refs;
|
||||
pr->free_string_refs = sr;
|
||||
sr->next = res->free_string_refs;
|
||||
res->free_string_refs = sr;
|
||||
}
|
||||
|
||||
static __attribute__((pure)) string_t
|
||||
string_index (progs_t *pr, strref_t *sr)
|
||||
string_index (prstr_resources_t *res, strref_t *sr)
|
||||
{
|
||||
long o = (long) (sr - pr->static_strings);
|
||||
long o = (long) (sr - res->static_strings);
|
||||
unsigned i;
|
||||
|
||||
if (o >= 0 && o < pr->num_strings)
|
||||
return sr->s.string - pr->pr_strings;
|
||||
for (i = 0; i < pr->dyn_str_size; i++) {
|
||||
int d = sr - pr->string_map[i];
|
||||
if (o >= 0 && o < res->num_strings)
|
||||
return sr->s.string - res->pr->pr_strings;
|
||||
for (i = 0; i < res->dyn_str_size; i++) {
|
||||
int d = sr - res->string_map[i];
|
||||
if (d >= 0 && d < 1024)
|
||||
return ~(i * 1024 + d);
|
||||
}
|
||||
|
@ -172,70 +189,124 @@ strref_get_key (const void *_sr, void *notused)
|
|||
}
|
||||
|
||||
static void
|
||||
strref_free (void *_sr, void *_pr)
|
||||
strref_free (void *_sr, void *_res)
|
||||
{
|
||||
progs_t *pr = (progs_t*)_pr;
|
||||
strref_t *sr = (strref_t*)_sr;
|
||||
__auto_type res = (prstr_resources_t *) _res;
|
||||
__auto_type sr = (strref_t *) _sr;
|
||||
|
||||
// Since this is called only by Hash_FlushTable, the memory pointed
|
||||
// to by sr->string or sr->dstring has already been lost in the progs
|
||||
// load/reload and thus there's no need to free it.
|
||||
|
||||
// free the string and ref only if it's not a static string
|
||||
if (sr < pr->static_strings || sr >= pr->static_strings + pr->num_strings) {
|
||||
free_string_ref (pr, sr);
|
||||
if (sr < res->static_strings
|
||||
|| sr >= res->static_strings + res->num_strings) {
|
||||
free_string_ref (res, sr);
|
||||
}
|
||||
}
|
||||
|
||||
VISIBLE int
|
||||
static void
|
||||
pr_strings_clear (progs_t *pr, void *data)
|
||||
{
|
||||
__auto_type res = (prstr_resources_t *) data;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < PR_RS_SLOTS; i++) {
|
||||
if (res->return_strings[i].strref)
|
||||
free_string_ref (res, res->return_strings[i].strref);
|
||||
res->return_strings[i].strref = 0;
|
||||
}
|
||||
if (!res->rs_slot) {
|
||||
strref_slot_t * const rs = res->return_strings;
|
||||
for (i = 0; i < PR_RS_SLOTS; i++) {
|
||||
rs[i].next = &rs[(i + 1) % PR_RS_SLOTS];
|
||||
rs[i].prev = &rs[(i - 1 + PR_RS_SLOTS) % PR_RS_SLOTS].next;
|
||||
}
|
||||
res->rs_slot = rs;
|
||||
}
|
||||
|
||||
pr->pr_string_resources = res;
|
||||
pr->pr_xtstr = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
PR_LoadStrings (progs_t *pr)
|
||||
{
|
||||
prstr_resources_t *res = PR_Resources_Find (pr, "Strings");
|
||||
|
||||
char *end = pr->pr_strings + pr->progs->numstrings;
|
||||
char *str = pr->pr_strings;
|
||||
int count = 0;
|
||||
|
||||
pr->float_promoted = 0;
|
||||
|
||||
while (str < end) {
|
||||
count++;
|
||||
if (*str == '@' && pr->progs->version == PROG_VERSION) {
|
||||
if (!strcmp (str, "@float_promoted@")) {
|
||||
pr->float_promoted = 1;
|
||||
}
|
||||
}
|
||||
str += strlen (str) + 1;
|
||||
}
|
||||
|
||||
if (!pr->ds_mem) {
|
||||
pr->ds_mem = malloc (sizeof (dstring_mem_t));
|
||||
pr->ds_mem->alloc = pr_strings_alloc;
|
||||
pr->ds_mem->free = pr_strings_free;
|
||||
pr->ds_mem->realloc = pr_strings_realloc;
|
||||
pr->ds_mem->data = pr;
|
||||
}
|
||||
if (pr->strref_hash) {
|
||||
Hash_FlushTable (pr->strref_hash);
|
||||
res->ds_mem.alloc = pr_strings_alloc;
|
||||
res->ds_mem.free = pr_strings_free;
|
||||
res->ds_mem.realloc = pr_strings_realloc;
|
||||
res->ds_mem.data = pr;
|
||||
|
||||
if (res->strref_hash) {
|
||||
Hash_FlushTable (res->strref_hash);
|
||||
} else {
|
||||
pr->strref_hash = Hash_NewTable (1021, strref_get_key, strref_free,
|
||||
pr);
|
||||
pr->string_map = 0;
|
||||
pr->free_string_refs = 0;
|
||||
pr->dyn_str_size = 0;
|
||||
res->strref_hash = Hash_NewTable (1021, strref_get_key, strref_free,
|
||||
res);
|
||||
res->string_map = 0;
|
||||
res->free_string_refs = 0;
|
||||
res->dyn_str_size = 0;
|
||||
}
|
||||
|
||||
if (pr->static_strings)
|
||||
free (pr->static_strings);
|
||||
pr->static_strings = malloc (count * sizeof (strref_t));
|
||||
if (res->static_strings)
|
||||
free (res->static_strings);
|
||||
res->static_strings = calloc (count, sizeof (strref_t));
|
||||
count = 0;
|
||||
str = pr->pr_strings;
|
||||
while (str < end) {
|
||||
if (!Hash_Find (pr->strref_hash, str)) {
|
||||
pr->static_strings[count].type = str_static;
|
||||
pr->static_strings[count].s.string = str;
|
||||
Hash_Add (pr->strref_hash, &pr->static_strings[count]);
|
||||
if (!Hash_Find (res->strref_hash, str)) {
|
||||
res->static_strings[count].type = str_static;
|
||||
res->static_strings[count].s.string = str;
|
||||
Hash_Add (res->strref_hash, &res->static_strings[count]);
|
||||
count++;
|
||||
}
|
||||
str += strlen (str) + 1;
|
||||
}
|
||||
pr->num_strings = count;
|
||||
res->num_strings = count;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
requeue_strref (prstr_resources_t *res, strref_t *sr)
|
||||
{
|
||||
strref_slot_t *rs_slot = sr->rs_slot;
|
||||
if (rs_slot->next != res->rs_slot) {
|
||||
// this is the oldest slot, so advance res->rs_slot to the
|
||||
// next oldest slot so this slot does not get reused just yet
|
||||
if (res->rs_slot == rs_slot) {
|
||||
res->rs_slot = rs_slot->next;
|
||||
}
|
||||
// unlink this slot from the chain
|
||||
rs_slot->next->prev = rs_slot->prev;
|
||||
*rs_slot->prev = rs_slot->next;
|
||||
// link this slot just before the oldest slot: all the slots
|
||||
// form a doubly linked circular list
|
||||
rs_slot->prev = res->rs_slot->prev;
|
||||
rs_slot->next = res->rs_slot;
|
||||
*res->rs_slot->prev = rs_slot;
|
||||
res->rs_slot->prev = &rs_slot->next;
|
||||
}
|
||||
}
|
||||
|
||||
static inline strref_t *
|
||||
get_strref (progs_t *pr, string_t num)
|
||||
get_strref (prstr_resources_t *res, string_t num)
|
||||
{
|
||||
if (num < 0) {
|
||||
strref_t *ref;
|
||||
|
@ -243,9 +314,9 @@ get_strref (progs_t *pr, string_t num)
|
|||
|
||||
num = ~num % 1024;
|
||||
|
||||
if (row >= pr->dyn_str_size)
|
||||
if (row >= res->dyn_str_size)
|
||||
return 0;
|
||||
ref = &pr->string_map[row][num];
|
||||
ref = &res->string_map[row][num];
|
||||
if (ref->type == str_free)
|
||||
return 0;
|
||||
return ref;
|
||||
|
@ -256,22 +327,24 @@ get_strref (progs_t *pr, string_t num)
|
|||
static inline __attribute__((pure)) const char *
|
||||
get_string (progs_t *pr, string_t num)
|
||||
{
|
||||
__auto_type res = pr->pr_string_resources;
|
||||
if (num < 0) {
|
||||
strref_t *ref = get_strref (pr, num);
|
||||
strref_t *ref = get_strref (res, num);
|
||||
if (!ref)
|
||||
return 0;
|
||||
switch (ref->type) {
|
||||
case str_return:
|
||||
requeue_strref (res, ref);
|
||||
case str_static:
|
||||
case str_temp:
|
||||
case str_dynamic:
|
||||
case str_return:
|
||||
return ref->s.string;
|
||||
case str_mutable:
|
||||
return ref->s.dstring->str;
|
||||
case str_free:
|
||||
break;
|
||||
}
|
||||
PR_Error (pr, "internal string error");
|
||||
PR_Error (pr, "internal string error: %d", __LINE__);
|
||||
} else {
|
||||
if (num >= pr->pr_stringsize)
|
||||
return 0;
|
||||
|
@ -282,7 +355,10 @@ get_string (progs_t *pr, string_t num)
|
|||
VISIBLE qboolean
|
||||
PR_StringValid (progs_t *pr, string_t num)
|
||||
{
|
||||
return get_string (pr, num) != 0;
|
||||
if (num >= 0) {
|
||||
return num < pr->pr_stringsize;
|
||||
}
|
||||
return get_strref (pr->pr_string_resources, num) != 0;
|
||||
}
|
||||
|
||||
VISIBLE const char *
|
||||
|
@ -299,7 +375,7 @@ PR_GetString (progs_t *pr, string_t num)
|
|||
VISIBLE dstring_t *
|
||||
PR_GetMutableString (progs_t *pr, string_t num)
|
||||
{
|
||||
strref_t *ref = get_strref (pr, num);
|
||||
strref_t *ref = get_strref (pr->pr_string_resources, num);
|
||||
if (ref) {
|
||||
if (ref->type == str_mutable)
|
||||
return ref->s.dstring;
|
||||
|
@ -308,10 +384,16 @@ PR_GetMutableString (progs_t *pr, string_t num)
|
|||
PR_RunError (pr, "Invalid string offset: %d", num);
|
||||
}
|
||||
|
||||
static inline void *
|
||||
pr_strmalloc (progs_t *pr, size_t size)
|
||||
{
|
||||
return PR_Zone_Malloc (pr, size);
|
||||
}
|
||||
|
||||
static inline char *
|
||||
pr_stralloc (progs_t *pr, size_t len)
|
||||
{
|
||||
return PR_Zone_Malloc (pr, len + 1);
|
||||
return pr_strmalloc (pr, len + 1);
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
@ -331,70 +413,72 @@ pr_strdup (progs_t *pr, const char *s)
|
|||
VISIBLE string_t
|
||||
PR_SetString (progs_t *pr, const char *s)
|
||||
{
|
||||
prstr_resources_t *res = pr->pr_string_resources;
|
||||
strref_t *sr;
|
||||
|
||||
if (!s)
|
||||
s = "";
|
||||
sr = Hash_Find (pr->strref_hash, s);
|
||||
sr = Hash_Find (res->strref_hash, s);
|
||||
|
||||
if (__builtin_expect (!sr, 1)) {
|
||||
sr = new_string_ref (pr);
|
||||
sr = new_string_ref (res);
|
||||
sr->type = str_static;
|
||||
sr->s.string = pr_strdup(pr, s);
|
||||
Hash_Add (pr->strref_hash, sr);
|
||||
}
|
||||
return string_index (pr, sr);
|
||||
}
|
||||
|
||||
void
|
||||
PR_ClearReturnStrings (progs_t *pr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < PR_RS_SLOTS; i++) {
|
||||
if (pr->return_strings[i])
|
||||
free_string_ref (pr, pr->return_strings[i]);
|
||||
pr->return_strings[i] = 0;
|
||||
Hash_Add (res->strref_hash, sr);
|
||||
}
|
||||
return string_index (res, sr);
|
||||
}
|
||||
|
||||
VISIBLE string_t
|
||||
PR_SetReturnString (progs_t *pr, const char *s)
|
||||
{
|
||||
prstr_resources_t *res = pr->pr_string_resources;
|
||||
strref_t *sr;
|
||||
|
||||
if (!s)
|
||||
s = "";
|
||||
if ((sr = Hash_Find (pr->strref_hash, s))) {
|
||||
return string_index (pr, sr);
|
||||
if ((sr = Hash_Find (res->strref_hash, s))) {
|
||||
if (sr->type == str_return && sr->rs_slot) {
|
||||
requeue_strref (res, sr);
|
||||
} else if ((sr->type == str_return && !sr->rs_slot)
|
||||
|| (sr->type != str_return && sr->rs_slot)) {
|
||||
PR_Error (pr, "internal string error: %d %d %p", __LINE__,
|
||||
sr->type, sr->rs_slot);
|
||||
}
|
||||
return string_index (res, sr);
|
||||
}
|
||||
|
||||
if ((sr = pr->return_strings[pr->rs_slot])) {
|
||||
if (sr->type != str_return)
|
||||
PR_Error (pr, "internal string error");
|
||||
// grab the string ref from the oldest slot, or make a new one if the
|
||||
// slot is empty
|
||||
if ((sr = res->rs_slot->strref)) {
|
||||
if (sr->type != str_return || sr->rs_slot != res->rs_slot) {
|
||||
PR_Error (pr, "internal string error: %d", __LINE__);
|
||||
}
|
||||
pr_strfree (pr, sr->s.string);
|
||||
} else {
|
||||
sr = new_string_ref (pr);
|
||||
sr = new_string_ref (res);
|
||||
}
|
||||
sr->type = str_return;
|
||||
sr->rs_slot = res->rs_slot;
|
||||
sr->s.string = pr_strdup(pr, s);
|
||||
|
||||
pr->return_strings[pr->rs_slot++] = sr;
|
||||
pr->rs_slot %= PR_RS_SLOTS;
|
||||
return string_index (pr, sr);
|
||||
// the oldest slot just became the newest, so advance to the next oldest
|
||||
res->rs_slot = res->rs_slot->next;
|
||||
|
||||
return string_index (res, sr);
|
||||
}
|
||||
|
||||
static inline string_t
|
||||
pr_settempstring (progs_t *pr, char *s)
|
||||
pr_settempstring (progs_t *pr, prstr_resources_t *res, char *s)
|
||||
{
|
||||
strref_t *sr;
|
||||
|
||||
sr = new_string_ref (pr);
|
||||
sr = new_string_ref (res);
|
||||
sr->type = str_temp;
|
||||
sr->s.string = s;
|
||||
sr->next = pr->pr_xtstr;
|
||||
pr->pr_xtstr = sr;
|
||||
return string_index (pr, sr);
|
||||
return string_index (res, sr);
|
||||
}
|
||||
|
||||
VISIBLE string_t
|
||||
|
@ -410,46 +494,77 @@ PR_CatStrings (progs_t *pr, const char *a, const char *b)
|
|||
strcpy (c, a);
|
||||
strcpy (c + lena, b);
|
||||
|
||||
return pr_settempstring (pr, c);
|
||||
return pr_settempstring (pr, pr->pr_string_resources, c);
|
||||
}
|
||||
|
||||
VISIBLE string_t
|
||||
PR_SetTempString (progs_t *pr, const char *s)
|
||||
{
|
||||
prstr_resources_t *res = pr->pr_string_resources;
|
||||
strref_t *sr;
|
||||
|
||||
if (!s)
|
||||
return PR_SetString (pr, "");
|
||||
|
||||
if ((sr = Hash_Find (pr->strref_hash, s))) {
|
||||
return string_index (pr, sr);
|
||||
if ((sr = Hash_Find (res->strref_hash, s))) {
|
||||
return string_index (res, sr);
|
||||
}
|
||||
|
||||
return pr_settempstring (pr, pr_strdup (pr, s));
|
||||
return pr_settempstring (pr, res, pr_strdup (pr, s));
|
||||
}
|
||||
|
||||
VISIBLE string_t
|
||||
PR_AllocTempBlock (progs_t *pr, size_t size)
|
||||
{
|
||||
prstr_resources_t *res = pr->pr_string_resources;
|
||||
return pr_settempstring (pr, res, pr_strmalloc (pr, size));
|
||||
}
|
||||
|
||||
VISIBLE void
|
||||
PR_PushTempString (progs_t *pr, string_t num)
|
||||
{
|
||||
prstr_resources_t *res = pr->pr_string_resources;
|
||||
strref_t *ref = get_strref (res, num);
|
||||
strref_t **temp_ref;
|
||||
|
||||
if (!ref || ref->type != str_temp) {
|
||||
PR_Error (pr, "attempt to push a non-temp string");
|
||||
}
|
||||
for (temp_ref = &pr->pr_xtstr; *temp_ref; temp_ref = &(*temp_ref)->next) {
|
||||
if (*temp_ref == ref) {
|
||||
*temp_ref = ref->next;
|
||||
ref->next = pr->pr_pushtstr;
|
||||
pr->pr_pushtstr = ref;
|
||||
return;
|
||||
}
|
||||
}
|
||||
PR_Error (pr, "attempt to push stale temp string");
|
||||
}
|
||||
|
||||
VISIBLE string_t
|
||||
PR_SetDynamicString (progs_t *pr, const char *s)
|
||||
{
|
||||
prstr_resources_t *res = pr->pr_string_resources;
|
||||
strref_t *sr;
|
||||
|
||||
if (!s)
|
||||
return PR_SetString (pr, "");
|
||||
|
||||
if ((sr = Hash_Find (pr->strref_hash, s))) {
|
||||
return string_index (pr, sr);
|
||||
if ((sr = Hash_Find (res->strref_hash, s))) {
|
||||
return string_index (res, sr);
|
||||
}
|
||||
|
||||
sr = new_string_ref (pr);
|
||||
sr = new_string_ref (res);
|
||||
sr->type = str_dynamic;
|
||||
sr->s.string = pr_strdup (pr, s);
|
||||
return string_index (pr, sr);
|
||||
return string_index (res, sr);
|
||||
}
|
||||
|
||||
void
|
||||
PR_MakeTempString (progs_t *pr, string_t str)
|
||||
{
|
||||
strref_t *sr = get_strref (pr, str);
|
||||
prstr_resources_t *res = pr->pr_string_resources;
|
||||
strref_t *sr = get_strref (res, str);
|
||||
|
||||
if (!sr)
|
||||
PR_RunError (pr, "invalid string %d", str);
|
||||
|
@ -470,16 +585,18 @@ PR_MakeTempString (progs_t *pr, string_t str)
|
|||
VISIBLE string_t
|
||||
PR_NewMutableString (progs_t *pr)
|
||||
{
|
||||
strref_t *sr = new_string_ref (pr);
|
||||
prstr_resources_t *res = pr->pr_string_resources;
|
||||
strref_t *sr = new_string_ref (res);
|
||||
sr->type = str_mutable;
|
||||
sr->s.dstring = _dstring_newstr (pr->ds_mem);
|
||||
return string_index (pr, sr);
|
||||
sr->s.dstring = _dstring_newstr (&res->ds_mem);
|
||||
return string_index (res, sr);
|
||||
}
|
||||
|
||||
VISIBLE void
|
||||
PR_FreeString (progs_t *pr, string_t str)
|
||||
{
|
||||
strref_t *sr = get_strref (pr, str);
|
||||
prstr_resources_t *res = pr->pr_string_resources;
|
||||
strref_t *sr = get_strref (res, str);
|
||||
|
||||
if (sr) {
|
||||
switch (sr->type) {
|
||||
|
@ -494,32 +611,32 @@ PR_FreeString (progs_t *pr, string_t str)
|
|||
break;
|
||||
case str_return:
|
||||
default:
|
||||
PR_Error (pr, "internal string error");
|
||||
PR_Error (pr, "internal string error: %d", __LINE__);
|
||||
}
|
||||
free_string_ref (pr, sr);
|
||||
free_string_ref (res, sr);
|
||||
return;
|
||||
}
|
||||
if (!get_string (pr, str))
|
||||
PR_RunError (pr, "attempt to free invalid string %d", str);
|
||||
PR_RunError (pr, "attempt to free invalid string %d", str);
|
||||
}
|
||||
|
||||
void
|
||||
PR_FreeTempStrings (progs_t *pr)
|
||||
{
|
||||
prstr_resources_t *res = pr->pr_string_resources;
|
||||
strref_t *sr, *t;
|
||||
|
||||
for (sr = pr->pr_xtstr; sr; sr = t) {
|
||||
t = sr->next;
|
||||
if (sr->type != str_temp)
|
||||
PR_Error (pr, "internal string error");
|
||||
if (R_STRING (pr) < 0 && string_index (pr, sr) == R_STRING (pr)
|
||||
PR_Error (pr, "internal string error: %d", __LINE__);
|
||||
if (R_STRING (pr) < 0 && string_index (res, sr) == R_STRING (pr)
|
||||
&& pr->pr_depth) {
|
||||
prstack_t *frame = pr->pr_stack + pr->pr_depth - 1;
|
||||
sr->next = frame->tstr;
|
||||
frame->tstr = sr;
|
||||
} else {
|
||||
pr_strfree (pr, sr->s.string);
|
||||
free_string_ref (pr, sr);
|
||||
free_string_ref (res, sr);
|
||||
}
|
||||
}
|
||||
pr->pr_xtstr = 0;
|
||||
|
@ -551,10 +668,9 @@ PR_FreeTempStrings (progs_t *pr)
|
|||
list item.
|
||||
*/
|
||||
static void
|
||||
I_DoPrint (dstring_t *result, fmt_item_t *formatting)
|
||||
I_DoPrint (dstring_t *tmp, dstring_t *result, fmt_item_t *formatting)
|
||||
{
|
||||
fmt_item_t *current = formatting;
|
||||
dstring_t *tmp = dstring_new ();
|
||||
|
||||
while (current) {
|
||||
qboolean doPrecision, doWidth;
|
||||
|
@ -617,34 +733,33 @@ I_DoPrint (dstring_t *result, fmt_item_t *formatting)
|
|||
}
|
||||
current = current->next;
|
||||
}
|
||||
dstring_delete (tmp);
|
||||
}
|
||||
|
||||
static fmt_item_t *
|
||||
new_fmt_item (void)
|
||||
new_fmt_item (prstr_resources_t *res)
|
||||
{
|
||||
int i;
|
||||
fmt_item_t *fi;
|
||||
|
||||
if (!free_fmt_items) {
|
||||
free_fmt_items = malloc (16 * sizeof (fmt_item_t));
|
||||
if (!res->free_fmt_items) {
|
||||
res->free_fmt_items = malloc (16 * sizeof (fmt_item_t));
|
||||
for (i = 0; i < 15; i++)
|
||||
free_fmt_items[i].next = free_fmt_items + i + 1;
|
||||
free_fmt_items[i].next = 0;
|
||||
res->free_fmt_items[i].next = res->free_fmt_items + i + 1;
|
||||
res->free_fmt_items[i].next = 0;
|
||||
}
|
||||
|
||||
fi = free_fmt_items;
|
||||
free_fmt_items = fi->next;
|
||||
fi = res->free_fmt_items;
|
||||
res->free_fmt_items = fi->next;
|
||||
memset (fi, 0, sizeof (*fi));
|
||||
fi->precision = -1;
|
||||
return fi;
|
||||
}
|
||||
|
||||
static void
|
||||
free_fmt_item (fmt_item_t *fi)
|
||||
free_fmt_item (prstr_resources_t *res, fmt_item_t *fi)
|
||||
{
|
||||
fi->next = free_fmt_items;
|
||||
free_fmt_items = fi;
|
||||
fi->next = res->free_fmt_items;
|
||||
res->free_fmt_items = fi;
|
||||
}
|
||||
|
||||
#undef P_var
|
||||
|
@ -655,6 +770,7 @@ VISIBLE void
|
|||
PR_Sprintf (progs_t *pr, dstring_t *result, const char *name,
|
||||
const char *format, int count, pr_type_t **args)
|
||||
{
|
||||
prstr_resources_t *res = pr->pr_string_resources;
|
||||
const char *c, *l;
|
||||
const char *msg = "";
|
||||
fmt_item_t *fmt_items = 0;
|
||||
|
@ -664,7 +780,7 @@ PR_Sprintf (progs_t *pr, dstring_t *result, const char *name,
|
|||
if (!name)
|
||||
name = "PR_Sprintf";
|
||||
|
||||
*fi = new_fmt_item ();
|
||||
*fi = new_fmt_item (res);
|
||||
c = l = format;
|
||||
while (*c) {
|
||||
if (*c++ == '%') {
|
||||
|
@ -674,14 +790,14 @@ PR_Sprintf (progs_t *pr, dstring_t *result, const char *name,
|
|||
(*fi)->type = 's';
|
||||
(*fi)->data.string_var = l;
|
||||
|
||||
(*fi)->next = new_fmt_item ();
|
||||
(*fi)->next = new_fmt_item (res);
|
||||
fi = &(*fi)->next;
|
||||
}
|
||||
if (*c == '%') {
|
||||
(*fi)->type = 's';
|
||||
(*fi)->data.string_var = "%";
|
||||
|
||||
(*fi)->next = new_fmt_item ();
|
||||
(*fi)->next = new_fmt_item (res);
|
||||
fi = &(*fi)->next;
|
||||
} else {
|
||||
do {
|
||||
|
@ -729,7 +845,7 @@ PR_Sprintf (progs_t *pr, dstring_t *result, const char *name,
|
|||
case '@':
|
||||
// object
|
||||
fmt_count++;
|
||||
(*fi)->next = new_fmt_item ();
|
||||
(*fi)->next = new_fmt_item (res);
|
||||
fi = &(*fi)->next;
|
||||
break;
|
||||
case 'e':
|
||||
|
@ -739,7 +855,7 @@ PR_Sprintf (progs_t *pr, dstring_t *result, const char *name,
|
|||
P_EDICTNUM (pr, fmt_count);
|
||||
|
||||
fmt_count++;
|
||||
(*fi)->next = new_fmt_item ();
|
||||
(*fi)->next = new_fmt_item (res);
|
||||
fi = &(*fi)->next;
|
||||
break;
|
||||
case 'i':
|
||||
|
@ -750,7 +866,7 @@ PR_Sprintf (progs_t *pr, dstring_t *result, const char *name,
|
|||
(*fi)->data.integer_var = P_INT (pr, fmt_count);
|
||||
|
||||
fmt_count++;
|
||||
(*fi)->next = new_fmt_item ();
|
||||
(*fi)->next = new_fmt_item (res);
|
||||
fi = &(*fi)->next;
|
||||
break;
|
||||
case 'f':
|
||||
|
@ -769,7 +885,7 @@ PR_Sprintf (progs_t *pr, dstring_t *result, const char *name,
|
|||
}
|
||||
|
||||
fmt_count++;
|
||||
(*fi)->next = new_fmt_item ();
|
||||
(*fi)->next = new_fmt_item (res);
|
||||
fi = &(*fi)->next;
|
||||
break;
|
||||
case 'p':
|
||||
|
@ -779,7 +895,7 @@ PR_Sprintf (progs_t *pr, dstring_t *result, const char *name,
|
|||
(*fi)->data.uinteger_var = P_UINT (pr, fmt_count);
|
||||
|
||||
fmt_count++;
|
||||
(*fi)->next = new_fmt_item ();
|
||||
(*fi)->next = new_fmt_item (res);
|
||||
fi = &(*fi)->next;
|
||||
break;
|
||||
case 's':
|
||||
|
@ -788,7 +904,7 @@ PR_Sprintf (progs_t *pr, dstring_t *result, const char *name,
|
|||
(*fi)->data.string_var = P_GSTRING (pr, fmt_count);
|
||||
|
||||
fmt_count++;
|
||||
(*fi)->next = new_fmt_item ();
|
||||
(*fi)->next = new_fmt_item (res);
|
||||
fi = &(*fi)->next;
|
||||
break;
|
||||
case 'v':
|
||||
|
@ -815,7 +931,7 @@ PR_Sprintf (progs_t *pr, dstring_t *result, const char *name,
|
|||
(*fi)->type = 's';
|
||||
(*fi)->data.string_var = " ";
|
||||
}
|
||||
(*fi)->next = new_fmt_item ();
|
||||
(*fi)->next = new_fmt_item (res);
|
||||
fi = &(*fi)->next;
|
||||
|
||||
(*fi)->flags = flags;
|
||||
|
@ -825,7 +941,7 @@ PR_Sprintf (progs_t *pr, dstring_t *result, const char *name,
|
|||
(*fi)->data.float_var =
|
||||
P_VECTOR (pr, fmt_count)[i];
|
||||
|
||||
(*fi)->next = new_fmt_item ();
|
||||
(*fi)->next = new_fmt_item (res);
|
||||
fi = &(*fi)->next;
|
||||
}
|
||||
}
|
||||
|
@ -834,7 +950,7 @@ PR_Sprintf (progs_t *pr, dstring_t *result, const char *name,
|
|||
(*fi)->data.string_var = "'";
|
||||
|
||||
fmt_count++;
|
||||
(*fi)->next = new_fmt_item ();
|
||||
(*fi)->next = new_fmt_item (res);
|
||||
fi = &(*fi)->next;
|
||||
break;
|
||||
case 'x':
|
||||
|
@ -843,7 +959,7 @@ PR_Sprintf (progs_t *pr, dstring_t *result, const char *name,
|
|||
(*fi)->data.uinteger_var = P_UINT (pr, fmt_count);
|
||||
|
||||
fmt_count++;
|
||||
(*fi)->next = new_fmt_item ();
|
||||
(*fi)->next = new_fmt_item (res);
|
||||
fi = &(*fi)->next;
|
||||
break;
|
||||
}
|
||||
|
@ -859,7 +975,7 @@ PR_Sprintf (progs_t *pr, dstring_t *result, const char *name,
|
|||
(*fi)->type = 's';
|
||||
(*fi)->data.string_var = l;
|
||||
|
||||
(*fi)->next = new_fmt_item ();
|
||||
(*fi)->next = new_fmt_item (res);
|
||||
}
|
||||
|
||||
if (fmt_count != count) {
|
||||
|
@ -867,17 +983,30 @@ PR_Sprintf (progs_t *pr, dstring_t *result, const char *name,
|
|||
msg = "Not enough arguments for format string.";
|
||||
else
|
||||
msg = "Too many arguments for format string.";
|
||||
msg = va ("%s: %d %d", msg, fmt_count, count);
|
||||
dsprintf (res->print_str, "%s: %d %d", msg, fmt_count, count);
|
||||
msg = res->print_str->str;
|
||||
goto error;
|
||||
}
|
||||
|
||||
I_DoPrint (result, fmt_items);
|
||||
dstring_clear (res->print_str);
|
||||
I_DoPrint (res->print_str, result, fmt_items);
|
||||
while (fmt_items) {
|
||||
fmt_item_t *t = fmt_items->next;
|
||||
free_fmt_item (fmt_items);
|
||||
free_fmt_item (res, fmt_items);
|
||||
fmt_items = t;
|
||||
}
|
||||
return;
|
||||
error:
|
||||
PR_RunError (pr, "%s: %s", name, msg);
|
||||
}
|
||||
|
||||
void
|
||||
PR_Strings_Init (progs_t *pr)
|
||||
{
|
||||
prstr_resources_t *res = calloc (1, sizeof (*res));
|
||||
res->pr = pr;
|
||||
res->print_str = dstring_new ();
|
||||
|
||||
PR_Resources_Register (pr, "Strings", res, pr_strings_clear);
|
||||
PR_AddLoadFunc (pr, PR_LoadStrings);
|
||||
}
|
||||
|
|
|
@ -91,6 +91,7 @@ bi_gib_builtin_f (void)
|
|||
PR_RESET_PARAMS (builtin->pr);
|
||||
P_INT (builtin->pr, 0) = GIB_Argc();
|
||||
P_INT (builtin->pr, 1) = PR_SetPointer (builtin->pr, pr_list);
|
||||
builtin->pr->pr_argc = 2;
|
||||
PR_ExecuteProgram (builtin->pr, builtin->func);
|
||||
PR_PopFrame (builtin->pr);
|
||||
PR_Zone_Free (builtin->pr, pr_list);
|
||||
|
|
|
@ -16,6 +16,6 @@ libQFruamoko_la_LIBADD= $(rua_libs)
|
|||
libQFruamoko_la_DEPENDENCIES= $(rua_libs)
|
||||
libQFruamoko_la_SOURCES= \
|
||||
pr_cmds.c \
|
||||
rua_cbuf.c rua_cmd.c rua_cvar.c rua_file.c rua_hash.c rua_init.c \
|
||||
rua_cbuf.c rua_cmd.c rua_cvar.c rua_hash.c rua_init.c \
|
||||
rua_math.c rua_msgbuf.c rua_obj.c rua_plist.c rua_qfile.c rua_qfs.c \
|
||||
rua_script.c rua_set.c rua_string.c
|
||||
|
|
|
@ -255,7 +255,7 @@ PF_Find (progs_t *pr)
|
|||
int i; // ev_vector
|
||||
int e, f;
|
||||
etype_t type;
|
||||
ddef_t *field_def;
|
||||
pr_def_t *field_def;
|
||||
edict_t *ed;
|
||||
|
||||
e = P_EDICTNUM (pr, 0);
|
||||
|
@ -583,6 +583,25 @@ PF_sprintf (progs_t *pr)
|
|||
dstring_delete (dstr);
|
||||
}
|
||||
|
||||
static void
|
||||
PF_vsprintf (progs_t *pr)
|
||||
{
|
||||
const char *fmt = P_GSTRING (pr, 0);
|
||||
__auto_type args = &P_PACKED (pr, pr_va_list_t, 1);
|
||||
pr_type_t *list_start = PR_GetPointer (pr, args->list);
|
||||
pr_type_t **list = alloca (args->count * sizeof (*list));
|
||||
dstring_t *dstr;
|
||||
|
||||
for (int i = 0; i < args->count; i++) {
|
||||
list[i] = list_start + i * pr->pr_param_size;
|
||||
}
|
||||
|
||||
dstr = dstring_newstr ();
|
||||
PR_Sprintf (pr, dstr, "PF_vsprintf", fmt, args->count, list);
|
||||
RETURN_STRING (pr, dstr->str);
|
||||
dstring_delete (dstr);
|
||||
}
|
||||
|
||||
/*
|
||||
string () gametype
|
||||
*/
|
||||
|
@ -596,7 +615,7 @@ static void
|
|||
PF_PR_SetField (progs_t *pr)
|
||||
{
|
||||
edict_t *ent = P_EDICT (pr, 0);
|
||||
ddef_t *field = PR_FindField (pr, P_GSTRING (pr, 1));
|
||||
pr_def_t *field = PR_FindField (pr, P_GSTRING (pr, 1));
|
||||
const char *value = P_GSTRING (pr, 2);
|
||||
|
||||
R_INT (pr) = 0;
|
||||
|
@ -643,6 +662,7 @@ static builtin_t builtins[] = {
|
|||
{"strlen", PF_strlen, QF 100},
|
||||
{"charcount", PF_charcount, QF 101},
|
||||
{"sprintf", PF_sprintf, QF 109},
|
||||
{"vsprintf", PF_vsprintf, -1},
|
||||
{"ftoi", PF_ftoi, QF 110},
|
||||
{"itof", PF_itof, QF 111},
|
||||
{"itos", PF_itos, QF 112},
|
||||
|
|
|
@ -1,184 +0,0 @@
|
|||
/*
|
||||
bi_file.c
|
||||
|
||||
CSQC file builtins
|
||||
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FNMATCH_H
|
||||
# define model_t sunmodel_t
|
||||
# include <fnmatch.h>
|
||||
# undef model_t
|
||||
#else
|
||||
# ifdef _WIN32
|
||||
# include "fnmatch.h"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_FNMATCH_PROTO
|
||||
int fnmatch (const char *__pattern, const char *__string, int __flags);
|
||||
#endif
|
||||
|
||||
#include "QF/cvar.h"
|
||||
#include "QF/progs.h"
|
||||
#include "QF/quakefs.h"
|
||||
#include "QF/va.h"
|
||||
#include "QF/zone.h"
|
||||
|
||||
#include "rua_internal.h"
|
||||
|
||||
static const char *file_ban_list[] = {
|
||||
"default.cfg{,.gz}",
|
||||
"demo1.dem{,.gz}",
|
||||
"demo2.dem{,.gz}",
|
||||
"demo3.dem{,.gz}",
|
||||
"end1.bin{,.gz}",
|
||||
"end2.bin{,.gz}",
|
||||
"gfx.wad{,.gz}",
|
||||
"progs.dat{,.gz}",
|
||||
"quake.rc{,.gz}",
|
||||
0,
|
||||
};
|
||||
|
||||
static const char *dir_ban_list[] = {
|
||||
"gfx",
|
||||
"maps",
|
||||
"progs",
|
||||
"skins",
|
||||
"sound",
|
||||
0,
|
||||
};
|
||||
|
||||
static int
|
||||
file_readable (char *path)
|
||||
{
|
||||
char t;
|
||||
char *p = strchr (path, '/');
|
||||
const char **match;
|
||||
|
||||
if (p) {
|
||||
t = *p;
|
||||
*p = 0;
|
||||
for (match = dir_ban_list; *match; match++) {
|
||||
if (fnmatch (*match, path, FNM_PATHNAME) == 0) {
|
||||
*p = t;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (match = file_ban_list; *match; match++) {
|
||||
if (fnmatch (*match, path, FNM_PATHNAME) == 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
file_writeable (char *path)
|
||||
{
|
||||
return file_readable (path);
|
||||
}
|
||||
|
||||
static void
|
||||
bi_File_Open (progs_t *pr)
|
||||
{
|
||||
QFile *file;
|
||||
const char *pth = P_GSTRING (pr, 0);
|
||||
const char *mode = P_GSTRING (pr, 1);
|
||||
char *path;
|
||||
char *p;
|
||||
int do_write = 0;
|
||||
int do_read = 0;
|
||||
|
||||
p = strchr (mode, 'r');
|
||||
if (p) {
|
||||
do_read |= 1;
|
||||
if (p[1] == '+')
|
||||
do_write |= 1;
|
||||
}
|
||||
|
||||
p = strchr (mode, 'w');
|
||||
if (p) {
|
||||
do_write |= 1;
|
||||
if (p[1] == '+')
|
||||
do_read |= 1;
|
||||
}
|
||||
|
||||
p = strchr (mode, 'a');
|
||||
if (p) {
|
||||
do_write |= 1;
|
||||
if (p[1] == '+')
|
||||
do_read |= 1;
|
||||
}
|
||||
|
||||
path = QFS_CompressPath (pth);
|
||||
//printf ("'%s' '%s'\n", P_GSTRING (pr, 0), path);
|
||||
if (!path[0])
|
||||
goto error;
|
||||
if (path[0] == '.' && path[1] == '.' && (path[2] == '/' || path [2] == 0))
|
||||
goto error;
|
||||
if (path[strlen (path) - 1] =='/')
|
||||
goto error;
|
||||
if (!do_read && !do_write)
|
||||
goto error;
|
||||
if (do_read && !file_readable (path))
|
||||
goto error;
|
||||
if (do_write && !file_writeable (path))
|
||||
goto error;
|
||||
|
||||
file = QFS_Open (va ("%s/%s", qfs_gamedir->dir.def, path), mode);
|
||||
if (!file)
|
||||
goto error;
|
||||
free (path);
|
||||
if ((R_INT (pr) = QFile_AllocHandle (pr, file)))
|
||||
return;
|
||||
Qclose (file);
|
||||
return;
|
||||
error:
|
||||
free (path);
|
||||
R_INT (pr) = 0;
|
||||
}
|
||||
|
||||
static builtin_t builtins[] = {
|
||||
{"File_Open", bi_File_Open, -1},
|
||||
{0}
|
||||
};
|
||||
|
||||
void
|
||||
RUA_File_Init (progs_t *pr, int secure)
|
||||
{
|
||||
PR_RegisterBuiltins (pr, builtins);
|
||||
}
|
|
@ -98,6 +98,7 @@ bi_get_key (const void *key, void *_ht)
|
|||
PR_RESET_PARAMS (ht->pr);
|
||||
P_INT (ht->pr, 0) = (intptr_t) (key);
|
||||
P_INT (ht->pr, 1) = ht->ud;
|
||||
ht->pr->pr_argc = 2;
|
||||
PR_ExecuteProgram (ht->pr, ht->gk);
|
||||
return PR_GetString (ht->pr, R_STRING (ht->pr));
|
||||
}
|
||||
|
@ -109,6 +110,7 @@ bi_get_hash (const void *key, void *_ht)
|
|||
PR_RESET_PARAMS (ht->pr);
|
||||
P_INT (ht->pr, 0) = (intptr_t) (key);
|
||||
P_INT (ht->pr, 1) = ht->ud;
|
||||
ht->pr->pr_argc = 2;
|
||||
PR_ExecuteProgram (ht->pr, ht->gh);
|
||||
return R_INT (ht->pr);
|
||||
}
|
||||
|
@ -121,6 +123,7 @@ bi_compare (const void *key1, const void *key2, void *_ht)
|
|||
P_INT (ht->pr, 0) = (intptr_t) (key1);
|
||||
P_INT (ht->pr, 1) = (intptr_t) (key2);
|
||||
P_INT (ht->pr, 2) = ht->ud;
|
||||
ht->pr->pr_argc = 3;
|
||||
PR_ExecuteProgram (ht->pr, ht->cmp);
|
||||
return R_INT (ht->pr);
|
||||
}
|
||||
|
@ -132,6 +135,7 @@ bi_free (void *key, void *_ht)
|
|||
PR_RESET_PARAMS (ht->pr);
|
||||
P_INT (ht->pr, 0) = (intptr_t) (key);
|
||||
P_INT (ht->pr, 1) = ht->ud;
|
||||
ht->pr->pr_argc = 2;
|
||||
PR_ExecuteProgram (ht->pr, ht->f);
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,6 @@ static void (*init_funcs[])(progs_t *, int) = {
|
|||
RUA_Cbuf_Init,
|
||||
RUA_Cmd_Init,
|
||||
RUA_Cvar_Init,
|
||||
RUA_File_Init,
|
||||
RUA_Hash_Init,
|
||||
RUA_Math_Init,
|
||||
RUA_MsgBuf_Init,
|
||||
|
@ -56,7 +55,6 @@ RUA_Init (progs_t *pr, int secure)
|
|||
{
|
||||
size_t i;
|
||||
|
||||
PR_Resources_Init (pr);
|
||||
for (i = 0; i < sizeof (init_funcs) / sizeof (init_funcs[0]); i++)
|
||||
init_funcs[i] (pr, secure);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -38,9 +38,7 @@
|
|||
|
||||
#include "QF/dstring.h"
|
||||
#include "QF/progs.h"
|
||||
#include "QF/quakefs.h"
|
||||
#include "QF/va.h"
|
||||
#include "QF/zone.h"
|
||||
#include "QF/quakeio.h"
|
||||
|
||||
#include "rua_internal.h"
|
||||
|
||||
|
|
|
@ -181,6 +181,12 @@ bi_QFS_FilelistFree (progs_t *pr)
|
|||
PR_Zone_Free (pr, list);
|
||||
}
|
||||
|
||||
static void
|
||||
bi_QFS_GetDirectory (progs_t *pr)
|
||||
{
|
||||
RETURN_STRING (pr, qfs_gamedir->dir.def);
|
||||
}
|
||||
|
||||
static builtin_t builtins[] = {
|
||||
{"QFS_Open", bi_QFS_Open, -1},
|
||||
{"QFS_WOpen", bi_QFS_WOpen, -1},
|
||||
|
@ -190,6 +196,7 @@ static builtin_t builtins[] = {
|
|||
{"QFS_WriteFile", bi_QFS_WriteFile, -1},
|
||||
{"QFS_Filelist", bi_QFS_Filelist, -1},
|
||||
{"QFS_FilelistFree", bi_QFS_FilelistFree, -1},
|
||||
{"QFS_GetDirectory", bi_QFS_GetDirectory, -1},
|
||||
{0}
|
||||
};
|
||||
|
||||
|
|
|
@ -48,7 +48,6 @@ typedef struct {
|
|||
script_t script;
|
||||
string_t dstr;
|
||||
progs_t *pr;
|
||||
string_t err_msg;
|
||||
} rua_script_t;
|
||||
|
||||
typedef struct {
|
||||
|
@ -92,13 +91,6 @@ bi_script_clear (progs_t *pr, void *data)
|
|||
script_reset (res);
|
||||
}
|
||||
|
||||
static void
|
||||
bi_script_error (script_t *_script, const char *msg)
|
||||
{
|
||||
rua_script_t *script = (rua_script_t *)_script;
|
||||
script->err_msg = PR_SetString (script->pr, msg);
|
||||
}
|
||||
|
||||
static void
|
||||
bi_Script_New (progs_t *pr)
|
||||
{
|
||||
|
@ -110,7 +102,6 @@ bi_Script_New (progs_t *pr)
|
|||
|
||||
script->dstr = PR_NewMutableString (pr);
|
||||
script->script.token = PR_GetMutableString (pr, script->dstr);
|
||||
script->script.error = bi_script_error;
|
||||
script->pr = pr;
|
||||
R_INT (pr) = script_index (res, script);
|
||||
}
|
||||
|
@ -180,8 +171,8 @@ bi_Script_Error (progs_t *pr)
|
|||
|
||||
if (!script)
|
||||
PR_RunError (pr, "invalid script handle");
|
||||
R_STRING (pr) = script->err_msg;
|
||||
script->err_msg = 0;
|
||||
R_STRING (pr) = PR_SetString (pr, script->script.error);
|
||||
script->script.error = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -112,6 +112,10 @@ bi_str_mid (progs_t *pr)
|
|||
end = size;
|
||||
if (pos < 0 || pos >= size || end <= pos)
|
||||
return;
|
||||
if (end == size) {
|
||||
R_STRING (pr) = str + pos - pr->pr_strings;
|
||||
return;
|
||||
}
|
||||
temp = alloca (end - pos + 1);
|
||||
strncpy (temp, str + pos, end - pos);
|
||||
temp[end - pos] = 0;
|
||||
|
@ -130,6 +134,18 @@ bi_str_str (progs_t *pr)
|
|||
R_STRING (pr) = res - pr->pr_strings;
|
||||
}
|
||||
|
||||
static void
|
||||
bi_str_char (progs_t *pr)
|
||||
{
|
||||
const char *str = P_GSTRING (pr, 0);
|
||||
int ind = P_INT (pr, 1);
|
||||
|
||||
if (ind < 0) {
|
||||
PR_RunError (pr, "negative index to str_char");
|
||||
}
|
||||
R_INT (pr) = str[ind];
|
||||
}
|
||||
|
||||
static builtin_t builtins[] = {
|
||||
{"str_new", bi_str_new, -1},
|
||||
{"str_free", bi_str_free, -1},
|
||||
|
@ -139,6 +155,7 @@ static builtin_t builtins[] = {
|
|||
{"str_mid|*i", bi_str_mid, -1},
|
||||
{"str_mid|*ii", bi_str_mid, -1},
|
||||
{"str_str", bi_str_str, -1},
|
||||
{"str_char", bi_str_char, -1},
|
||||
{0}
|
||||
};
|
||||
|
||||
|
|
|
@ -53,7 +53,8 @@ libQFutil_la_SOURCES= \
|
|||
fendian.c hash.c idparse.c info.c link.c llist.c \
|
||||
mathlib.c mdfour.c mersenne.c msg.c pakfile.c plugin.c qargs.c qendian.c \
|
||||
qfplist.c quakefs.c quakeio.c riff.c script.c segtext.c set.c sizebuf.c \
|
||||
string.c sys.c va.c ver_check.c vrect.c wad.c wadfile.c zone.c \
|
||||
string.c sys.c txtbuffer.c va.c ver_check.c vrect.c wad.c wadfile.c \
|
||||
zone.c \
|
||||
$(dirent) $(fnmatch) $(getopt)
|
||||
|
||||
EXTRA_DIST= $(fnmatch_src) $(getopt_src)
|
||||
|
|
|
@ -299,7 +299,7 @@ dstring_clearstr (dstring_t *dstr)
|
|||
dstr->str[0] = 0;
|
||||
}
|
||||
|
||||
static __attribute__((format(printf, 3, 0))) int
|
||||
static __attribute__((format(printf, 3, 0))) char *
|
||||
_dvsprintf (dstring_t *dstr, int offs, const char *fmt, va_list args)
|
||||
{
|
||||
int size;
|
||||
|
@ -325,20 +325,20 @@ _dvsprintf (dstring_t *dstr, int offs, const char *fmt, va_list args)
|
|||
}
|
||||
dstr->size = size + offs + 1;
|
||||
dstr->str[dstr->size - 1] = 0;
|
||||
return size;
|
||||
return dstr->str;
|
||||
}
|
||||
|
||||
VISIBLE int
|
||||
VISIBLE char *
|
||||
dvsprintf (dstring_t *dstr, const char *fmt, va_list args)
|
||||
{
|
||||
return _dvsprintf (dstr, 0, fmt, args);
|
||||
}
|
||||
|
||||
VISIBLE int
|
||||
VISIBLE char *
|
||||
dsprintf (dstring_t *dstr, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int ret;
|
||||
char *ret;
|
||||
|
||||
va_start (args, fmt);
|
||||
ret = _dvsprintf (dstr, 0, fmt, args);
|
||||
|
@ -347,7 +347,7 @@ dsprintf (dstring_t *dstr, const char *fmt, ...)
|
|||
return ret;
|
||||
}
|
||||
|
||||
VISIBLE int
|
||||
VISIBLE char *
|
||||
davsprintf (dstring_t *dstr, const char *fmt, va_list args)
|
||||
{
|
||||
int offs = 0;
|
||||
|
@ -357,11 +357,11 @@ davsprintf (dstring_t *dstr, const char *fmt, va_list args)
|
|||
return _dvsprintf (dstr, offs, fmt, args);
|
||||
}
|
||||
|
||||
VISIBLE int
|
||||
VISIBLE char *
|
||||
dasprintf (dstring_t *dstr, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int ret;
|
||||
char *ret;
|
||||
int offs = 0;
|
||||
|
||||
if (dstr->size)
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
#endif
|
||||
|
||||
#include "QF/mdfour.h"
|
||||
#include "QF/uint32.h"
|
||||
|
||||
/* NOTE: This code makes no attempt to be fast!
|
||||
It assumes that a int is at least 32 bits long
|
||||
|
@ -62,12 +61,12 @@ static struct mdfour *m;
|
|||
|
||||
/* this applies md4 to 64 byte chunks */
|
||||
static void
|
||||
mdfour64 (uint32 * M)
|
||||
mdfour64 (uint32_t * M)
|
||||
{
|
||||
int j;
|
||||
uint32 AA, BB, CC, DD;
|
||||
uint32 X[16];
|
||||
uint32 A, B, C, D;
|
||||
uint32_t AA, BB, CC, DD;
|
||||
uint32_t X[16];
|
||||
uint32_t A, B, C, D;
|
||||
|
||||
for (j = 0; j < 16; j++)
|
||||
X[j] = M[j];
|
||||
|
@ -154,7 +153,7 @@ mdfour64 (uint32 * M)
|
|||
}
|
||||
|
||||
static void
|
||||
copy64 (uint32 * M, const unsigned char *in)
|
||||
copy64 (uint32_t * M, const unsigned char *in)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -164,7 +163,7 @@ copy64 (uint32 * M, const unsigned char *in)
|
|||
}
|
||||
|
||||
static void
|
||||
copy4 (unsigned char *out, uint32 x)
|
||||
copy4 (unsigned char *out, uint32_t x)
|
||||
{
|
||||
out[0] = x & 0xFF;
|
||||
out[1] = (x >> 8) & 0xFF;
|
||||
|
@ -186,8 +185,8 @@ static void
|
|||
mdfour_tail (const unsigned char *in, int n)
|
||||
{
|
||||
unsigned char buf[128];
|
||||
uint32 M[16];
|
||||
uint32 b;
|
||||
uint32_t M[16];
|
||||
uint32_t b;
|
||||
|
||||
m->totalN += n;
|
||||
|
||||
|
@ -214,7 +213,7 @@ mdfour_tail (const unsigned char *in, int n)
|
|||
VISIBLE void
|
||||
mdfour_update (struct mdfour *md, const unsigned char *in, int n)
|
||||
{
|
||||
uint32 M[16];
|
||||
uint32_t M[16];
|
||||
|
||||
if (n == 0)
|
||||
mdfour_tail (in, n);
|
||||
|
|
|
@ -34,19 +34,6 @@
|
|||
#include "QF/dstring.h"
|
||||
#include "QF/script.h"
|
||||
|
||||
static void __attribute__ ((format (printf, 2, 3), noreturn))
|
||||
script_error (script_t *script, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start (args, fmt);
|
||||
fprintf (stderr, "%s:%d: ", script->file, script->line);
|
||||
vfprintf (stderr, fmt, args);
|
||||
fprintf (stderr, "\n");
|
||||
va_end (args);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
VISIBLE script_t *
|
||||
Script_New (void)
|
||||
{
|
||||
|
@ -69,11 +56,16 @@ Script_Start (script_t *script, const char *file, const char *data)
|
|||
script->file = file;
|
||||
script->p = data;
|
||||
script->unget = false;
|
||||
script->error = 0;
|
||||
}
|
||||
|
||||
VISIBLE qboolean
|
||||
Script_TokenAvailable (script_t *script, qboolean crossline)
|
||||
{
|
||||
if (script->error) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (script->unget)
|
||||
return true;
|
||||
skipspace:
|
||||
|
@ -111,6 +103,10 @@ Script_GetToken (script_t *script, qboolean crossline)
|
|||
{
|
||||
const char *token_p;
|
||||
|
||||
if (script->error) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (script->unget) { // is a token allready waiting?
|
||||
script->unget = false;
|
||||
return true;
|
||||
|
@ -118,10 +114,7 @@ Script_GetToken (script_t *script, qboolean crossline)
|
|||
|
||||
if (!Script_TokenAvailable (script, crossline)) {
|
||||
if (!crossline) {
|
||||
if (script->error)
|
||||
script->error (script, "line is incomplete");
|
||||
else
|
||||
script_error (script, "line is incomplete");
|
||||
script->error = "line is incomplete";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -134,18 +127,13 @@ Script_GetToken (script_t *script, qboolean crossline)
|
|||
while (*script->p != '"') {
|
||||
if (!*script->p) {
|
||||
script->line = start_line;
|
||||
if (script->error)
|
||||
script->error (script, "EOF inside quoted token");
|
||||
else
|
||||
script_error (script, "EOF inside quoted token");
|
||||
script->error = "EOF inside quoted token";
|
||||
return false;
|
||||
}
|
||||
if (*script->p == '\n') {
|
||||
if (script->no_quote_lines) {
|
||||
if (script->error)
|
||||
script->error (script, "EOL inside quoted token");
|
||||
else
|
||||
script_error (script, "EOL inside quoted token");
|
||||
script->error = "EOL inside quoted token";
|
||||
return false;
|
||||
}
|
||||
script->line++;
|
||||
}
|
||||
|
@ -175,11 +163,16 @@ Script_GetToken (script_t *script, qboolean crossline)
|
|||
VISIBLE void
|
||||
Script_UngetToken (script_t *script)
|
||||
{
|
||||
script->unget = true;
|
||||
if (!script->error) {
|
||||
script->unget = true;
|
||||
}
|
||||
}
|
||||
|
||||
VISIBLE const char *
|
||||
Script_Token (script_t *script)
|
||||
{
|
||||
if (script->error) {
|
||||
return 0;
|
||||
}
|
||||
return script->token->str;
|
||||
}
|
||||
|
|
|
@ -126,18 +126,18 @@ qboolean stdin_ready;
|
|||
|
||||
/* The translation table between the graphical font and plain ASCII --KB */
|
||||
VISIBLE const char sys_char_map[256] = {
|
||||
'\0', '#', '#', '#', '#', '.', '#', '#',
|
||||
'#', 9, 10, '#', ' ', 13, '.', '.',
|
||||
0, '#', '#', '#', '#', '.', '#', '#',
|
||||
'#', 9, 10, '#', ' ', 13, '.', '.',
|
||||
'[', ']', '0', '1', '2', '3', '4', '5',
|
||||
'6', '7', '8', '9', '.', '<', '=', '>',
|
||||
' ', '!', '"', '#', '$', '%', '&', '\'',
|
||||
' ', '!', '"', '#', '$', '%', '&','\'',
|
||||
'(', ')', '*', '+', ',', '-', '.', '/',
|
||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', ':', ';', '<', '=', '>', '?',
|
||||
'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
|
||||
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
|
||||
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
|
||||
'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
|
||||
'X', 'Y', 'Z', '[','\\', ']', '^', '_',
|
||||
'`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
|
||||
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
|
||||
'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
|
||||
|
@ -147,14 +147,14 @@ VISIBLE const char sys_char_map[256] = {
|
|||
'#', '#', ' ', '#', ' ', '>', '.', '.',
|
||||
'[', ']', '0', '1', '2', '3', '4', '5',
|
||||
'6', '7', '8', '9', '.', '<', '=', '>',
|
||||
' ', '!', '"', '#', '$', '%', '&', '\'',
|
||||
' ', '!', '"', '#', '$', '%', '&','\'',
|
||||
'(', ')', '*', '+', ',', '-', '.', '/',
|
||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', ':', ';', '<', '=', '>', '?',
|
||||
'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
|
||||
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
|
||||
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
|
||||
'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
|
||||
'X', 'Y', 'Z', '[','\\', ']', '^', '_',
|
||||
'`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
|
||||
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
|
||||
'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
|
||||
|
@ -240,16 +240,20 @@ Sys_FileExists (const char *path)
|
|||
for want of a better name, but it sets the function pointer for the
|
||||
actual implementation of Sys_Printf.
|
||||
*/
|
||||
VISIBLE void
|
||||
VISIBLE sys_printf_t
|
||||
Sys_SetStdPrintf (sys_printf_t func)
|
||||
{
|
||||
sys_printf_t prev = sys_std_printf_function;
|
||||
sys_std_printf_function = func;
|
||||
return prev;
|
||||
}
|
||||
|
||||
VISIBLE void
|
||||
VISIBLE sys_printf_t
|
||||
Sys_SetErrPrintf (sys_printf_t func)
|
||||
{
|
||||
sys_printf_t prev = sys_err_printf_function;
|
||||
sys_err_printf_function = func;
|
||||
return prev;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -4,7 +4,8 @@ AM_CPPFLAGS= -I$(top_srcdir)/include
|
|||
|
||||
check_PROGRAMS= \
|
||||
test-bary test-cs test-darray test-dq test-half test-mat3 test-mat4 \
|
||||
test-plist test-qfs test-quat test-seb test-seg test-set test-vrect
|
||||
test-plist test-qfs test-quat test-seb test-seg test-set test-txtbuffer \
|
||||
test-vrect
|
||||
|
||||
test_bary_SOURCES=test-bary.c
|
||||
test_bary_LDADD=$(top_builddir)/libs/util/libQFutil.la
|
||||
|
@ -58,6 +59,10 @@ test_set_SOURCES=test-set.c
|
|||
test_set_LDADD=$(top_builddir)/libs/util/libQFutil.la
|
||||
test_set_DEPENDENCIES=$(top_builddir)/libs/util/libQFutil.la
|
||||
|
||||
test_txtbuffer_SOURCES=test-txtbuffer.c
|
||||
test_txtbuffer_LDADD=$(top_builddir)/libs/util/libQFutil.la
|
||||
test_txtbuffer_DEPENDENCIES=$(top_builddir)/libs/util/libQFutil.la
|
||||
|
||||
test_vrect_SOURCES=test-vrect.c
|
||||
test_vrect_LDADD=$(top_builddir)/libs/util/libQFutil.la
|
||||
test_vrect_DEPENDENCIES=$(top_builddir)/libs/util/libQFutil.la
|
||||
|
|
240
libs/util/test/test-txtbuffer.c
Normal file
240
libs/util/test/test-txtbuffer.c
Normal file
|
@ -0,0 +1,240 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "QF/txtbuffer.h"
|
||||
|
||||
static size_t
|
||||
check_text_ptr (txtbuffer_t *buffer, size_t offset, const char *txt,
|
||||
size_t length)
|
||||
{
|
||||
return buffer->text != 0;
|
||||
}
|
||||
|
||||
static size_t
|
||||
get_textSize (txtbuffer_t *buffer, size_t offset, const char *txt,
|
||||
size_t length)
|
||||
{
|
||||
return buffer->textSize;
|
||||
}
|
||||
|
||||
static size_t
|
||||
get_bufferSize (txtbuffer_t *buffer, size_t offset, const char *txt,
|
||||
size_t length)
|
||||
{
|
||||
return buffer->bufferSize;
|
||||
}
|
||||
|
||||
static size_t
|
||||
get_gapOffset (txtbuffer_t *buffer, size_t offset, const char *txt,
|
||||
size_t length)
|
||||
{
|
||||
return buffer->gapOffset;
|
||||
}
|
||||
|
||||
static size_t
|
||||
get_gapSize (txtbuffer_t *buffer, size_t offset, const char *txt,
|
||||
size_t length)
|
||||
{
|
||||
return buffer->gapSize;
|
||||
}
|
||||
|
||||
static size_t
|
||||
insert_text (txtbuffer_t *buffer, size_t offset, const char *txt,
|
||||
size_t length)
|
||||
{
|
||||
if (TextBuffer_InsertAt (buffer, offset, txt, length)) {
|
||||
memset (buffer->text + buffer->gapOffset, 0xff, buffer->gapSize);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static size_t
|
||||
delete_text (txtbuffer_t *buffer, size_t offset, const char *txt,
|
||||
size_t length)
|
||||
{
|
||||
if (TextBuffer_DeleteAt (buffer, offset, length)) {
|
||||
memset (buffer->text + buffer->gapOffset, 0xff, buffer->gapSize);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static size_t
|
||||
destroy_buffer (txtbuffer_t *buffer, size_t offset, const char *txt,
|
||||
size_t length)
|
||||
{
|
||||
TextBuffer_Destroy (buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef size_t (*test_func) (txtbuffer_t *buffer, size_t offset,
|
||||
const char *text, size_t length);
|
||||
|
||||
static const char test_text[] = {
|
||||
"Guarding the entrance to the Grendal\n"
|
||||
"Gorge is the Shadow Gate, a small keep\n"
|
||||
"and monastary which was once the home\n"
|
||||
"of the Shadow cult.\n\n"
|
||||
"For years the Shadow Gate existed in\n"
|
||||
"obscurity but after the cult discovered\n"
|
||||
"the \3023\354\341\343\353\240\307\341\364\345 in the caves below\n"
|
||||
"the empire took notice.\n"
|
||||
"A batallion of Imperial Knights were\n"
|
||||
"sent to the gate to destroy the cult\n"
|
||||
"and claim the artifact for the King.",
|
||||
};
|
||||
static const char empty[TXTBUFFER_GROW] = { };
|
||||
|
||||
static size_t
|
||||
compare_text (txtbuffer_t *buffer, size_t offset, const char *txt,
|
||||
size_t length)
|
||||
{
|
||||
//printf("%zd %ld %zd\n", offset, txt - test_text, length);
|
||||
size_t res = memcmp (buffer->text + offset, txt, length) == 0;
|
||||
if (!res) {
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
//printf ("%02x %02x\n", txt[i] & 0xff, buffer->text[offset + i] & 0xff);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
#define txtsize (sizeof (test_text) - 1)
|
||||
#define txtsize0 txtsize
|
||||
#define bufsize0 (TXTBUFFER_GROW)
|
||||
#define gapoffs0 txtsize0
|
||||
#define gapsize0 (bufsize0 - txtsize0)
|
||||
#define subtxtlen 200
|
||||
#define suboffs 200
|
||||
#define txtsize1 (txtsize0 + subtxtlen)
|
||||
#define bufsize1 (TXTBUFFER_GROW)
|
||||
#define gapoffs1 (suboffs + subtxtlen)
|
||||
#define gapsize1 (bufsize1 - txtsize1)
|
||||
#define deltxtlen 350
|
||||
#define deloffs 150
|
||||
#define txtsize2 (txtsize + subtxtlen - deltxtlen)
|
||||
#define bufsize2 (TXTBUFFER_GROW)
|
||||
#define gapoffs2 (deloffs)
|
||||
#define gapsize2 (bufsize2 - txtsize2)
|
||||
#define deltxtrem (txtsize2 - gapoffs2)
|
||||
#define emptyoffs 370
|
||||
#define txtsize3 (txtsize + sizeof (empty))
|
||||
#define bufsize3 (2 * TXTBUFFER_GROW)
|
||||
#define gapoffs3 (emptyoffs + sizeof (empty))
|
||||
#define gapsize3 (bufsize3 - txtsize3)
|
||||
#define txtsize4 (txtsize + 2 * sizeof (empty))
|
||||
#define bufsize4 (3 * TXTBUFFER_GROW)
|
||||
#define gapoffs4 (emptyoffs + sizeof (empty))
|
||||
#define gapsize4 (bufsize4 - txtsize4)
|
||||
|
||||
struct {
|
||||
test_func test;
|
||||
size_t offset_param;
|
||||
const char *text_param;
|
||||
size_t length_param;
|
||||
int test_expect;
|
||||
} tests[] = {
|
||||
{ check_text_ptr, 0, 0, 0, 0 },
|
||||
{ get_textSize, 0, 0, 0, 0 },
|
||||
{ get_bufferSize, 0, 0, 0, 0 },
|
||||
{ get_gapOffset, 0, 0, 0, 0 },
|
||||
{ get_gapSize, 0, 0, 0, 0 },
|
||||
{ insert_text, 0, test_text, txtsize, 1 },
|
||||
{ get_textSize, 0, 0, 0, txtsize0 },
|
||||
{ get_bufferSize, 0, 0, 0, bufsize0 },
|
||||
{ get_gapOffset, 0, 0, 0, gapoffs0 },
|
||||
{ get_gapSize, 0, 0, 0, gapsize0 },
|
||||
{ compare_text, 0, test_text, txtsize, 1 },
|
||||
{ insert_text, suboffs, test_text, subtxtlen, 1 },
|
||||
{ get_textSize, 0, 0, 0, txtsize1 },
|
||||
{ get_bufferSize, 0, 0, 0, bufsize1 },
|
||||
{ get_gapOffset, 0, 0, 0, gapoffs1 },
|
||||
{ get_gapSize, 0, 0, 0, gapsize1 },
|
||||
{ compare_text, 0, test_text, txtsize, 0 },
|
||||
{ compare_text, 0, test_text, suboffs, 1 },
|
||||
{ compare_text, suboffs, test_text, subtxtlen, 1 },
|
||||
{ compare_text, gapoffs1 + gapsize1, test_text + subtxtlen, txtsize - subtxtlen, 1 },
|
||||
{ delete_text, deloffs, 0, deltxtlen, 1 },
|
||||
{ get_textSize, 0, 0, 0, txtsize2 },
|
||||
{ get_bufferSize, 0, 0, 0, bufsize2 },
|
||||
{ get_gapOffset, 0, 0, 0, gapoffs2 },
|
||||
{ get_gapSize, 0, 0, 0, gapsize2 },
|
||||
{ compare_text, 0, test_text, suboffs, 0 },
|
||||
{ compare_text, suboffs, test_text, subtxtlen, 0 },
|
||||
{ compare_text, gapoffs1 + gapsize1, test_text + subtxtlen, txtsize - subtxtlen, 0 },
|
||||
{ compare_text, 0, test_text, deloffs, 1 },
|
||||
{ compare_text, gapoffs2 + gapsize2, test_text + txtsize - deltxtrem, deltxtrem, 1 },
|
||||
{ compare_text, gapoffs2 + gapsize2 - 1, test_text + txtsize - deltxtrem - 1, 1, 0 },
|
||||
{ delete_text, 0, 0, -1, 1 },
|
||||
{ check_text_ptr, 0, 0, 0, 1 },
|
||||
{ get_textSize, 0, 0, 0, 0 },
|
||||
{ get_bufferSize, 0, 0, 0, bufsize2 },
|
||||
{ get_gapOffset, 0, 0, 0, 0 },
|
||||
{ get_gapSize, 0, 0, 0, bufsize2 },
|
||||
{ insert_text, 1, test_text, txtsize, 0 },
|
||||
{ get_textSize, 0, 0, 0, 0 },
|
||||
{ get_bufferSize, 0, 0, 0, bufsize2 },
|
||||
{ get_gapOffset, 0, 0, 0, 0 },
|
||||
{ get_gapSize, 0, 0, 0, bufsize2 },
|
||||
{ insert_text, 0, test_text, txtsize, 1 },
|
||||
{ insert_text, 300, 0, 0, 1 },
|
||||
{ get_textSize, 0, 0, 0, txtsize0 },
|
||||
{ get_bufferSize, 0, 0, 0, bufsize2 },
|
||||
{ get_gapOffset, 0, 0, 0, 300 },
|
||||
{ get_gapSize, 0, 0, 0, gapsize0 },
|
||||
{ compare_text, 0, test_text, 300, 1 },
|
||||
{ compare_text, 300, test_text + 300, 1, 0 },
|
||||
{ compare_text, 300 + gapsize0, test_text + 300, txtsize - 300, 1 },
|
||||
{ compare_text, 300 + gapsize0 - 1, test_text + 300 - 1, 1, 0 },
|
||||
{ insert_text, 350, 0, 0, 1 },
|
||||
{ compare_text, (emptyoffs - 20) + gapsize0, test_text + (emptyoffs - 20), txtsize - (emptyoffs - 20), 1 },
|
||||
{ get_textSize, 0, 0, 0, txtsize0 },
|
||||
{ get_bufferSize, 0, 0, 0, bufsize2 },
|
||||
{ get_gapOffset, 0, 0, 0, (emptyoffs - 20) },
|
||||
{ get_gapSize, 0, 0, 0, gapsize0 },
|
||||
{ insert_text, emptyoffs, empty, sizeof (empty), 1 },
|
||||
{ get_textSize, 0, 0, 0, txtsize3 },
|
||||
{ get_bufferSize, 0, 0, 0, bufsize3 },
|
||||
{ get_gapOffset, 0, 0, 0, gapoffs3 },
|
||||
{ get_gapSize, 0, 0, 0, gapsize3 },
|
||||
{ insert_text, emptyoffs, empty, sizeof (empty), 1 },
|
||||
{ get_textSize, 0, 0, 0, txtsize4 },
|
||||
{ get_bufferSize, 0, 0, 0, bufsize4 },
|
||||
{ get_gapOffset, 0, 0, 0, gapoffs4 },
|
||||
{ get_gapSize, 0, 0, 0, gapsize4 },
|
||||
{ destroy_buffer, 0, 0, 0, 0 },
|
||||
};
|
||||
#define num_tests (sizeof (tests) / sizeof (tests[0]))
|
||||
int test_start_line = __LINE__ - num_tests - 2;
|
||||
|
||||
int
|
||||
main (int argc, const char **argv)
|
||||
{
|
||||
size_t i;
|
||||
int res = 0;
|
||||
|
||||
txtbuffer_t *buffer = TextBuffer_Create ();
|
||||
|
||||
for (i = 0; i < num_tests; i++) {
|
||||
if (tests[i].test) {
|
||||
int test_res;
|
||||
test_res = tests[i].test (buffer,
|
||||
tests[i].offset_param,
|
||||
tests[i].text_param,
|
||||
tests[i].length_param);
|
||||
if (test_res != tests[i].test_expect) {
|
||||
res |= 1;
|
||||
printf ("test %d (line %d) failed\n", (int) i,
|
||||
(int) i + test_start_line);
|
||||
printf ("expect: %d\n", tests[i].test_expect);
|
||||
printf ("got : %d\n", test_res);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
194
libs/util/txtbuffer.c
Normal file
194
libs/util/txtbuffer.c
Normal file
|
@ -0,0 +1,194 @@
|
|||
/*
|
||||
txtbuffer.c
|
||||
|
||||
Text buffer
|
||||
|
||||
Copyright (C) 2020 Bill Currie <bill@taniwha.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#include "QF/alloc.h"
|
||||
#include "QF/qtypes.h"
|
||||
#include "QF/sys.h"
|
||||
#include "QF/txtbuffer.h"
|
||||
|
||||
#include "compat.h"
|
||||
|
||||
static txtbuffer_t *txtbuffers_freelist;
|
||||
|
||||
static char *
|
||||
txtbuffer_open_gap (txtbuffer_t *buffer, size_t offset, size_t length)
|
||||
{
|
||||
size_t len;
|
||||
char *dst;
|
||||
char *src;
|
||||
|
||||
if (offset == buffer->gapOffset && length <= buffer->gapSize) {
|
||||
return buffer->text + buffer->gapOffset;
|
||||
}
|
||||
if (length <= buffer->gapSize) {
|
||||
// no resize needed
|
||||
if (offset < buffer->gapOffset) {
|
||||
len = buffer->gapOffset - offset;
|
||||
dst = buffer->text + buffer->gapOffset + buffer->gapSize - len;
|
||||
src = buffer->text + offset;
|
||||
} else {
|
||||
len = offset - buffer->gapOffset;
|
||||
dst = buffer->text + buffer->gapOffset;
|
||||
src = buffer->text + buffer->gapOffset + buffer->gapSize;
|
||||
}
|
||||
memmove (dst, src, len);
|
||||
} else {
|
||||
// need to resize the buffer
|
||||
// grow the buffer by the difference in lengths rounded up to the
|
||||
// next multiple of TXTBUFFER_GROW
|
||||
size_t new_size = buffer->bufferSize + length - buffer->gapSize;
|
||||
new_size = (new_size + TXTBUFFER_GROW - 1) & ~(TXTBUFFER_GROW - 1);
|
||||
char *new_text = realloc (buffer->text, new_size);
|
||||
|
||||
if (!new_text) {
|
||||
return 0;
|
||||
}
|
||||
buffer->text = new_text;
|
||||
|
||||
if (offset < buffer->gapOffset) {
|
||||
// move the old post-gap to the end of the new buffer
|
||||
len = buffer->bufferSize - (buffer->gapOffset + buffer->gapSize);
|
||||
dst = buffer->text + new_size - len;
|
||||
src = buffer->text + buffer->gapOffset + buffer->gapSize;
|
||||
memmove (dst, src, len);
|
||||
// move the remaining chunk to after the end of the new gap or
|
||||
// just before the location of the previous move
|
||||
len = buffer->gapOffset - offset;
|
||||
dst -= len;
|
||||
src = buffer->text + offset;
|
||||
memmove (dst, src, len);
|
||||
} else if (offset > buffer->gapOffset) {
|
||||
// move the old post-offset to the end of the new buffer
|
||||
len = buffer->bufferSize - (offset + buffer->gapSize);
|
||||
dst = buffer->text + new_size - len;
|
||||
src = buffer->text + offset + buffer->gapSize;
|
||||
memmove (dst, src, len);
|
||||
// move the old post-gap to offset block to before the new gap
|
||||
len = offset - buffer->gapOffset;
|
||||
dst = buffer->text + buffer->gapOffset;
|
||||
src = buffer->text + buffer->gapOffset + buffer->gapSize;
|
||||
memmove (dst, src, len);
|
||||
} else {
|
||||
// the gap only grew, did not move
|
||||
len = buffer->bufferSize - (offset + buffer->gapSize);
|
||||
dst = buffer->text + new_size - len;
|
||||
src = buffer->text + buffer->gapOffset + buffer->gapSize;
|
||||
memmove (dst, src, len);
|
||||
}
|
||||
buffer->gapSize += new_size - buffer->bufferSize;
|
||||
buffer->bufferSize = new_size;
|
||||
}
|
||||
buffer->gapOffset = offset;
|
||||
return buffer->text + buffer->gapOffset;
|
||||
}
|
||||
|
||||
static char *
|
||||
txtbuffer_delete_text (txtbuffer_t *buffer, size_t offset, size_t length)
|
||||
{
|
||||
size_t len;
|
||||
char *dst;
|
||||
char *src;
|
||||
|
||||
if (offset > buffer->gapOffset) {
|
||||
len = offset - buffer->gapOffset;
|
||||
dst = buffer->text + buffer->gapOffset;
|
||||
src = buffer->text + buffer->gapOffset + buffer->gapSize;
|
||||
memmove (dst, src, len);
|
||||
} else if (offset + length < buffer->gapOffset) {
|
||||
len = buffer->gapOffset - (offset + length);
|
||||
dst = buffer->text + buffer->gapSize + (offset + length);
|
||||
src = buffer->text + (offset + length);
|
||||
memmove (dst, src, len);
|
||||
}
|
||||
// don't need to do any copying when offset <= gapOffset &&
|
||||
// offset + length >= offset
|
||||
buffer->gapOffset = offset;
|
||||
buffer->gapSize += length;
|
||||
buffer->textSize -= length;
|
||||
return buffer->text + buffer->gapOffset;
|
||||
}
|
||||
|
||||
VISIBLE txtbuffer_t *
|
||||
TextBuffer_Create (void)
|
||||
{
|
||||
txtbuffer_t *buffer;
|
||||
ALLOC (16, txtbuffer_t, txtbuffers, buffer);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
VISIBLE void
|
||||
TextBuffer_Destroy (txtbuffer_t *buffer)
|
||||
{
|
||||
if (buffer->text) {
|
||||
free (buffer->text);
|
||||
}
|
||||
FREE (txtbuffers, buffer);
|
||||
}
|
||||
|
||||
VISIBLE int
|
||||
TextBuffer_InsertAt (txtbuffer_t *buffer, size_t offset,
|
||||
const char *text, size_t text_len)
|
||||
{
|
||||
char *dst;
|
||||
|
||||
if (offset > buffer->textSize) {
|
||||
return 0;
|
||||
}
|
||||
dst = txtbuffer_open_gap (buffer, offset, text_len);
|
||||
if (!dst) {
|
||||
return 0;
|
||||
}
|
||||
memcpy (dst, text, text_len);
|
||||
buffer->textSize += text_len;
|
||||
buffer->gapOffset += text_len;
|
||||
buffer->gapSize -= text_len;
|
||||
return 1;
|
||||
}
|
||||
|
||||
VISIBLE int
|
||||
TextBuffer_DeleteAt (txtbuffer_t *buffer, size_t offset, size_t len)
|
||||
{
|
||||
if (offset > buffer->textSize) {
|
||||
return 0;
|
||||
}
|
||||
// clamp len to the amount of text beyond offset
|
||||
if (len > buffer->textSize - offset) {
|
||||
len = buffer->textSize - offset;
|
||||
}
|
||||
txtbuffer_delete_text (buffer, offset, len);
|
||||
return 1;
|
||||
}
|
|
@ -51,16 +51,23 @@ VISIBLE char *
|
|||
va (const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
static dstring_t *string;
|
||||
static dstring_t *string[4];
|
||||
#define NUM_STRINGS (sizeof (string) / sizeof (string[0]))
|
||||
static int str_index;
|
||||
dstring_t *dstr;
|
||||
|
||||
if (!string)
|
||||
string = dstring_new ();
|
||||
if (!string[0]) {
|
||||
for (size_t i = 0; i < NUM_STRINGS; i++) {
|
||||
string[i] = dstring_new ();
|
||||
}
|
||||
}
|
||||
dstr = string[str_index++ % NUM_STRINGS];
|
||||
|
||||
va_start (args, fmt);
|
||||
dvsprintf (string, fmt, args);
|
||||
dvsprintf (dstr, fmt, args);
|
||||
va_end (args);
|
||||
|
||||
return string->str;
|
||||
return dstr->str;
|
||||
}
|
||||
|
||||
VISIBLE char *
|
||||
|
|
|
@ -672,7 +672,7 @@ event_focusin (XEvent *event)
|
|||
static void
|
||||
center_pointer (void)
|
||||
{
|
||||
XEvent event;
|
||||
XEvent event = {};
|
||||
|
||||
event.type = MotionNotify;
|
||||
event.xmotion.display = x_disp;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue