diff --git a/libs/gamecode/pr_load.c b/libs/gamecode/pr_load.c index 9fee72574..8bc554296 100644 --- a/libs/gamecode/pr_load.c +++ b/libs/gamecode/pr_load.c @@ -202,6 +202,8 @@ 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); } diff --git a/libs/gamecode/pr_opcode.c b/libs/gamecode/pr_opcode.c index a2a344a1e..f18fd2b42 100644 --- a/libs/gamecode/pr_opcode.c +++ b/libs/gamecode/pr_opcode.c @@ -77,6 +77,7 @@ VISIBLE const char *pr_type_name[ev_type_count] = { "integer", "uinteger", "short", + "double", "invalid", }; diff --git a/libs/gamecode/pr_strings.c b/libs/gamecode/pr_strings.c index 684551fda..85602e3d2 100644 --- a/libs/gamecode/pr_strings.c +++ b/libs/gamecode/pr_strings.c @@ -649,6 +649,8 @@ free_fmt_item (fmt_item_t *fi) #undef P_var #define P_var(p,n,t) (args[n]->t##_var) +#undef P_DOUBLE +#define P_DOUBLE(p,n) (*(double *) (args[n])) VISIBLE void PR_Sprintf (progs_t *pr, dstring_t *result, const char *name, const char *format, int count, pr_type_t **args) diff --git a/tools/qfcc/include/obj_file.h b/tools/qfcc/include/obj_file.h index 0e6096028..c32c67eb2 100644 --- a/tools/qfcc/include/obj_file.h +++ b/tools/qfcc/include/obj_file.h @@ -305,6 +305,19 @@ enum { */ #define QFO_var(q, s, t, o) ((q)->spaces[s].d.data[o].t##_var) +/** Access a double variable in the object file. Can be assigned to. + + \par QC type: + \c double + \param q pointer to ::qfo_t struct + \param s space index + \param o offset into object file data space + \return double lvalue + + \hideinitializer +*/ +#define QFO_DOUBLE(q, s, o) (*(double *) ((q)->spaces[s].d.data + o)) + /** Access a float variable in the object file. Can be assigned to. \par QC type: diff --git a/tools/qfcc/include/qfcc.h b/tools/qfcc/include/qfcc.h index 1a1793b34..e428831cb 100644 --- a/tools/qfcc/include/qfcc.h +++ b/tools/qfcc/include/qfcc.h @@ -92,6 +92,7 @@ extern pr_info_t pr; #define GETSTR(s) (pr.strings->strings + (s)) #define D_var(t, d) ((d)->space->data[(d)->offset].t##_var) +#define D_DOUBLE(d) (*(double *) ((d)->space->data + (d)->offset)) #define D_FLOAT(d) D_var (float, d) #define D_INT(d) D_var (integer, d) #define D_VECTOR(d) D_var (vector, d) diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index 0773e0a8f..d40214d77 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -867,7 +867,7 @@ expr_double (expr_t *e) if (e->type == ex_symbol && e->e.symbol->sy_type == sy_var && e->e.symbol->s.def->constant && is_double (e->e.symbol->s.def->type)) - return D_FLOAT (e->e.symbol->s.def); + return D_DOUBLE (e->e.symbol->s.def); internal_error (e, "not a double constant"); } @@ -1915,6 +1915,10 @@ build_function_call (expr_t *fexpr, type_t *ftype, expr_t *params) if (is_integer_val (e) && options.code.progsversion == PROG_ID_VERSION) convert_int (e); + if (is_float (get_type (e)) + && options.code.progsversion != PROG_ID_VERSION) { + t = &type_double; + } if (is_integer_val (e) && options.warnings.vararg_integer) warning (e, "passing integer constant into ... function"); } @@ -2611,8 +2615,7 @@ cast_expr (type_t *type, expr_t *e) e->e.value = convert_value (val, type); e->type = ex_value; c = e; - } else if ((is_float (type) && is_integral (e_type)) - || (is_integral (type) && is_float (e_type))) { + } else if (is_scalar (type) && is_scalar (e_type)) { c = new_unary_expr ('C', e); c->e.expr.type = type; } else if (e->type == ex_uexpr && e->e.expr.op == '.') { diff --git a/tools/qfcc/source/statements.c b/tools/qfcc/source/statements.c index cd49b3970..072d175cf 100644 --- a/tools/qfcc/source/statements.c +++ b/tools/qfcc/source/statements.c @@ -958,8 +958,7 @@ expr_cast (sblock_t *sblock, expr_t *e, operand_t **op) statement_t *s; src_type = get_type (e->e.expr.e1); - if ((src_type->type == ev_integer && type->type == ev_float) - || (src_type->type == ev_float && type->type == ev_integer)) { + if (is_scalar (src_type) && is_scalar (type)) { operand_t *src = 0; sblock = statement_subexpr (sblock, e->e.expr.e1, &src); *op = temp_operand (e->e.expr.type); diff --git a/tools/qfcc/test/triangle.r b/tools/qfcc/test/triangle.r index 6ef592ace..cec1f6884 100644 --- a/tools/qfcc/test/triangle.r +++ b/tools/qfcc/test/triangle.r @@ -1,6 +1,6 @@ void printf (string fmt, ...) = #0; float (string s) stof = #0; -float (float x) sqrt = #0; +@overload float (float x) sqrt = #0; float heron (float a, float b, float c)