mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +00:00
Add an option to dump frame files.
After running across a question about lists of animation frames and states, I decided giving qfcc the ability to generate such lists might be a nice distraction from the optimizer :) Works for both progs.src and separate compilation. No frame file is generated if no macros have been created.
This commit is contained in:
parent
d0c37bbc51
commit
1d34da26f7
7 changed files with 79 additions and 5 deletions
|
@ -75,6 +75,16 @@ Allow extended keywords in traditional mode.
|
|||
Generate \fIfiles.dat\fP.
|
||||
This list is created by checking the parameters to the precache_* functions.
|
||||
.TP
|
||||
.B \-\-frames
|
||||
Generate \fI<source>.frame\fP files.
|
||||
For each source file (listed either on the command line, or in
|
||||
\fBprogs.src\fP, write a file whose name is the base name of the source
|
||||
file with an extension of \fB.frame\fP, and contains a list of frame macro
|
||||
names with their associated frame numbers. Eg, \fBplayer.qc\fP will produce
|
||||
\fBplayer.frame\fPa. Note that files that do not create frame macros will
|
||||
not generate a frame file. At this time, the file is always written to the
|
||||
current directory.
|
||||
.TP
|
||||
.B \-g
|
||||
Generate debugging info.
|
||||
Synonym for \fB\-\-code debug\fP.
|
||||
|
|
|
@ -33,8 +33,10 @@
|
|||
|
||||
extern int grab_frame;
|
||||
extern int grab_other;
|
||||
extern int grab_write;
|
||||
|
||||
int do_grab (char *token);
|
||||
void add_frame_macro (char *token);
|
||||
int do_grab (const char *token);
|
||||
void add_frame_macro (const char *token);
|
||||
void write_frame_macros (const char *filename);
|
||||
|
||||
#endif//__grab_h
|
||||
|
|
|
@ -87,6 +87,7 @@ typedef struct {
|
|||
qboolean no_default_paths; // no default -I or -L
|
||||
qboolean save_temps; // save temporary files
|
||||
qboolean files_dat; // generate files.dat
|
||||
qboolean frames_files; // generate <basename>.frame files
|
||||
qboolean progdefs_h; // generate progdefs.h
|
||||
qboolean qccx_escapes; // use qccx escapes instead of standard C
|
||||
int traditional; // behave more like qcc
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include <ctype.h>
|
||||
|
||||
#include "QF/hash.h"
|
||||
#include "QF/quakeio.h"
|
||||
|
||||
#include "diagnostic.h"
|
||||
#include "expr.h"
|
||||
|
@ -51,6 +52,7 @@
|
|||
|
||||
int grab_frame;
|
||||
int grab_other;
|
||||
int grab_write;
|
||||
|
||||
static hashtab_t *frame_tab;
|
||||
static hashtab_t *grab_tab;
|
||||
|
@ -62,6 +64,8 @@ typedef struct frame_s {
|
|||
} frame_t;
|
||||
|
||||
static frame_t *free_frames;
|
||||
static frame_t *frame_list;
|
||||
static frame_t **frame_tail = &frame_list;
|
||||
|
||||
static frame_t grab_list[] = {
|
||||
{0, "cd", 0},
|
||||
|
@ -87,7 +91,7 @@ frame_free (void *_f, void *unused)
|
|||
}
|
||||
|
||||
int
|
||||
do_grab (char *token)
|
||||
do_grab (const char *token)
|
||||
{
|
||||
static int initialized;
|
||||
frame_t *frame;
|
||||
|
@ -110,6 +114,8 @@ do_grab (char *token)
|
|||
clear_frame_macros ();
|
||||
return -grab_other;
|
||||
}
|
||||
if (!strcmp (token, "frame_write"))
|
||||
return -grab_write;
|
||||
if (Hash_Find (grab_tab, token))
|
||||
return -grab_other;
|
||||
frame = Hash_Find (frame_tab, token);
|
||||
|
@ -121,7 +127,7 @@ do_grab (char *token)
|
|||
static int frame_number;
|
||||
|
||||
void
|
||||
add_frame_macro (char *token)
|
||||
add_frame_macro (const char *token)
|
||||
{
|
||||
frame_t *frame;
|
||||
|
||||
|
@ -133,6 +139,8 @@ add_frame_macro (char *token)
|
|||
}
|
||||
ALLOC (1024, frame_t, frames, frame);
|
||||
|
||||
*frame_tail = frame;
|
||||
frame_tail = &frame->next;
|
||||
frame->name = save_string (token);
|
||||
frame->num = frame_number++;
|
||||
Hash_Add (frame_tab, frame);
|
||||
|
@ -142,7 +150,22 @@ void
|
|||
clear_frame_macros (void)
|
||||
{
|
||||
frame_number = 0;
|
||||
frame_tail = &frame_list;
|
||||
frame_list = 0;
|
||||
if (frame_tab)
|
||||
Hash_FlushTable (frame_tab);
|
||||
}
|
||||
|
||||
void
|
||||
write_frame_macros (const char *filename)
|
||||
{
|
||||
frame_t *frame;
|
||||
QFile *file;
|
||||
|
||||
if (!frame_list)
|
||||
return;
|
||||
file = Qopen (filename, "wt");
|
||||
for (frame = frame_list; frame; frame = frame->next)
|
||||
Qprintf (file, "%s %d\n", frame->name, frame->num);
|
||||
Qclose (file);
|
||||
}
|
||||
|
|
|
@ -63,6 +63,7 @@ enum {
|
|||
OPT_BLOCK_DOT,
|
||||
OPT_CPP,
|
||||
OPT_EXTENDED,
|
||||
OPT_FRAMES,
|
||||
OPT_INCLUDE,
|
||||
OPT_NO_DEFAULT_PATHS,
|
||||
OPT_PROGDEFS,
|
||||
|
@ -78,6 +79,7 @@ static struct option const long_options[] = {
|
|||
{"define", required_argument, 0, 'D'},
|
||||
{"extended", no_argument, 0, OPT_EXTENDED},
|
||||
{"files", no_argument, 0, 'F'},
|
||||
{"frames", no_argument, 0, OPT_FRAMES},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"include", required_argument, 0, OPT_INCLUDE},
|
||||
{"no-default-paths", no_argument, 0, OPT_NO_DEFAULT_PATHS},
|
||||
|
@ -143,6 +145,7 @@ usage (int status)
|
|||
" -E Only preprocess\n"
|
||||
" --extended Allow extended keywords in traditional mode\n"
|
||||
" -F, --files Generate files.dat\n"
|
||||
" --frames Generate <source>.frame files\n"
|
||||
" -g Generate debugging info\n"
|
||||
" -h, --help Display this help and exit\n"
|
||||
" -I DIR Set directories for the preprocessor\n"
|
||||
|
@ -354,6 +357,9 @@ DecodeArgs (int argc, char **argv)
|
|||
case 'g': // debug
|
||||
options.code.debug = true;
|
||||
break;
|
||||
case OPT_FRAMES:
|
||||
options.frames_files = 1;
|
||||
break;
|
||||
case OPT_EXTENDED:
|
||||
options.traditional = 1;
|
||||
options.advanced = false;
|
||||
|
|
|
@ -100,11 +100,12 @@ ELLIPSIS \.\.\.
|
|||
FRAMEID {ID}(\.{ID})*
|
||||
STRING \"(\\.|[^"\\])*\"
|
||||
|
||||
%x GRAB_FRAME GRAB_OTHER COMMENT
|
||||
%x GRAB_FRAME GRAB_OTHER GRAB_WRITE COMMENT
|
||||
|
||||
%%
|
||||
grab_frame = GRAB_FRAME;
|
||||
grab_other = GRAB_OTHER;
|
||||
grab_write = GRAB_WRITE;
|
||||
|
||||
"/*" { BEGIN (COMMENT); }
|
||||
<COMMENT>"/*" { warning (0, "nested /* in comment"); }
|
||||
|
@ -234,6 +235,11 @@ STRING \"(\\.|[^"\\])*\"
|
|||
|
||||
<GRAB_FRAME>{FRAMEID} add_frame_macro (yytext);
|
||||
<GRAB_OTHER>[^\r\n]* /* skip */
|
||||
<GRAB_WRITE>{STRING} {
|
||||
const char *s = make_string (yytext, 0);
|
||||
write_frame_macros (s);
|
||||
BEGIN (GRAB_OTHER); // ignore rest of line
|
||||
}
|
||||
|
||||
<*>\r*\n {
|
||||
pr.source_line++;
|
||||
|
|
|
@ -76,6 +76,7 @@
|
|||
#include "emit.h"
|
||||
#include "expr.h"
|
||||
#include "function.h"
|
||||
#include "grab.h"
|
||||
#include "idstuff.h"
|
||||
#include "linker.h"
|
||||
#include "method.h"
|
||||
|
@ -306,6 +307,25 @@ strip_path (const char *filename)
|
|||
return filename;
|
||||
}
|
||||
|
||||
static const char *
|
||||
basename (const char *filename)
|
||||
{
|
||||
const char *p;
|
||||
const char *dot;
|
||||
static dstring_t *base;
|
||||
|
||||
if (!base)
|
||||
base = dstring_new ();
|
||||
for (dot = p = filename + strlen (filename); p > filename; p--) {
|
||||
if (p[-1] == '/' || p[-1] == '\\')
|
||||
break;
|
||||
if (p[0] == '.')
|
||||
dot = p;
|
||||
}
|
||||
dstring_copysubstr (base, p, dot - p);
|
||||
return base->str;
|
||||
}
|
||||
|
||||
static void
|
||||
setup_sym_file (const char *output_file)
|
||||
{
|
||||
|
@ -368,6 +388,7 @@ compile_to_obj (const char *file, const char *obj, lang_t lang)
|
|||
exit (1);
|
||||
}
|
||||
}
|
||||
write_frame_macros (va ("%s.frame", basename (file)));
|
||||
if (!err) {
|
||||
qfo_t *qfo;
|
||||
|
||||
|
@ -696,9 +717,14 @@ progs_src_compile (void)
|
|||
fprintf (single, "#line %d \"%s\"\n", script->line,
|
||||
script->file);
|
||||
fprintf (single, "#include \"%s\"\n", qc_filename->str);
|
||||
if (options.frames_files)
|
||||
fprintf (single, "$frame_write \"%s.frame\"\n",
|
||||
basename (qc_filename->str));
|
||||
} else {
|
||||
if (compile_file (qc_filename->str))
|
||||
return 1;
|
||||
write_frame_macros (va ("%s.frame",
|
||||
basename (qc_filename->str)));
|
||||
}
|
||||
if (!Script_TokenAvailable (script, 0))
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue