From: TimePath Date: Thu, 10 Sep 2015 01:30:24 +0000 (+1000) Subject: Prefer lowercase filenames X-Git-Tag: xonotic-v0.8.2~1924^2~1 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=1fcf2f54c851dde50c1cc7ab0308b2112e300cf7;p=xonotic%2Fxonotic-data.pk3dir.git Prefer lowercase filenames --- diff --git a/qcsrc/lib/Accumulate.qh b/qcsrc/lib/Accumulate.qh deleted file mode 100644 index 7e1a1edc0..000000000 --- a/qcsrc/lib/Accumulate.qh +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef ACCUMULATE_H -#define ACCUMULATE_H - -#ifdef QCC_SUPPORT_ACCUMULATE -# define ACCUMULATE_FUNCTION(func, otherfunc) \ - [[accumulate]] void func() { otherfunc(); } -# define CALL_ACCUMULATED_FUNCTION(func) \ - func() -#else -#ifdef HAVE_YO_DAWG_CPP -// TODO make ascii art pic of xzibit -// YO DAWG! -// I HERD YO LIEK MACROS -// SO I PUT A MACRO DEFINITION IN YO MACRO DEFINITION -// SO YO CAN EXPAND MACROS WHILE YO EXPAND MACROS -# define ACCUMULATE_FUNCTION(func,otherfunc) \ - #ifdef func \ - void __merge__##otherfunc() { func(); otherfunc(); } \ - #undef func \ - #define func __merge__##otherfunc \ - #else \ - #define func otherfunc \ - #endif -# define CALL_ACCUMULATED_FUNCTION(func) \ - func() -#else -# define ACCUMULATE_FUNCTION(func,otherfunc) \ - .float _ACCUMULATE_##func##__##otherfunc; -void ACCUMULATE_call(string func) -{ - float i; - float n = numentityfields(); - string funcprefix = strcat("_ACCUMULATE_", func, "__"); - float funcprefixlen = strlen(funcprefix); - for(i = 0; i < n; ++i) - { - string name = entityfieldname(i); - if(substring(name, 0, funcprefixlen) == funcprefix) - callfunction(substring(name, funcprefixlen, -1)); - } -} -# define CALL_ACCUMULATED_FUNCTION(func) \ - ACCUMULATE_call(#func) -#endif -#endif - -// used for simplifying ACCUMULATE_FUNCTIONs -#define SET_FIRST_OR_LAST(input,first,count) if(!input) { input = (first + count); } -#define SET_FIELD_COUNT(field,first,count) if(!field) { field = (first + count); ++count; } -#define CHECK_MAX_COUNT(name,max,count,type) if(count > max) { error(strcat("Maximum ", type, " hit: ", #name, ": ", ftos(count), ".\n")); } - -#endif diff --git a/qcsrc/lib/Bool.qh b/qcsrc/lib/Bool.qh deleted file mode 100644 index 26169cd19..000000000 --- a/qcsrc/lib/Bool.qh +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef BOOL_H -#define BOOL_H - -#ifndef QCC_SUPPORT_BOOL - #define bool float - - // Boolean Constants - const int true = 1; - const int false = 0; -#endif - -// Transitional aliases -[[deprecated("use true")]] [[alias("true")]] const bool TRUE; -[[deprecated("use false")]] [[alias("false")]] const bool FALSE; - -// get true/false value of a string with multiple different inputs -float InterpretBoolean(string input) -{ - switch (strtolower(input)) - { - case "yes": - case "true": - case "on": - return true; - - case "no": - case "false": - case "off": - return false; - - default: return stof(input); - } -} - -float boolean(float value) { // if value is 0 return false (0), otherwise return true (1) - return (value == 0) ? false : true; -} - -#endif diff --git a/qcsrc/lib/Counting.qh b/qcsrc/lib/Counting.qh deleted file mode 100644 index cd0604bf5..000000000 --- a/qcsrc/lib/Counting.qh +++ /dev/null @@ -1,223 +0,0 @@ -#ifndef COUNTING_H -#define COUNTING_H - -#include "I18N.qh" - -// =============================================== -// Time processing and counting functions/macros -// =============================================== - -#define count_years_decs(time,decs) sprintf(ZCTX(_("CI_DEC^%s years")), ftos_decimals(time, decs)) -#define count_years(time) count_fill(time, \ - ZCTX(_("CI_ZER^%d years")), /* zeroth */ \ - ZCTX(_("CI_FIR^%d year")), /* first */ \ - ZCTX(_("CI_SEC^%d years")), /* year */ \ - ZCTX(_("CI_THI^%d years")), /* third */ \ - ZCTX(_("CI_MUL^%d years"))) /* multi */ - -#define count_weeks_decs(time,decs) sprintf(ZCTX(_("CI_DEC^%s weeks")), ftos_decimals(time, decs)) -#define count_weeks(time) count_fill(time, \ - ZCTX(_("CI_ZER^%d weeks")), /* zeroth */ \ - ZCTX(_("CI_FIR^%d week")), /* first */ \ - ZCTX(_("CI_SEC^%d weeks")), /* week */ \ - ZCTX(_("CI_THI^%d weeks")), /* third */ \ - ZCTX(_("CI_MUL^%d weeks"))) /* multi */ - -#define count_days_decs(time,decs) sprintf(ZCTX(_("CI_DEC^%s days")), ftos_decimals(time, decs)) -#define count_days(time) count_fill(time, \ - ZCTX(_("CI_ZER^%d days")), /* zeroth */ \ - ZCTX(_("CI_FIR^%d day")), /* first */ \ - ZCTX(_("CI_SEC^%d days")), /* day */ \ - ZCTX(_("CI_THI^%d days")), /* third */ \ - ZCTX(_("CI_MUL^%d days"))) /* multi */ - -#define count_hours_decs(time,decs) sprintf(ZCTX(_("CI_DEC^%s hours")), ftos_decimals(time, decs)) -#define count_hours(time) count_fill(time, \ - ZCTX(_("CI_ZER^%d hours")), /* zeroth */ \ - ZCTX(_("CI_FIR^%d hour")), /* first */ \ - ZCTX(_("CI_SEC^%d hours")), /* hour */ \ - ZCTX(_("CI_THI^%d hours")), /* third */ \ - ZCTX(_("CI_MUL^%d hours"))) /* multi */ - - -#define count_minutes_decs(time,decs) sprintf(ZCTX(_("CI_DEC^%s minutes")), ftos_decimals(time, decs)) -#define count_minutes(time) count_fill(time, \ - ZCTX(_("CI_ZER^%d minutes")), /* zeroth */ \ - ZCTX(_("CI_FIR^%d minute")), /* first */ \ - ZCTX(_("CI_SEC^%d minutes")), /* minute */ \ - ZCTX(_("CI_THI^%d minutes")), /* third */ \ - ZCTX(_("CI_MUL^%d minutes"))) /* multi */ - -#define count_seconds_decs(time,decs) sprintf(ZCTX(_("CI_DEC^%s seconds")), ftos_decimals(time, decs)) -#define count_seconds(time) count_fill(time, \ - ZCTX(_("CI_ZER^%d seconds")), /* zeroth */ \ - ZCTX(_("CI_FIR^%d second")), /* first */ \ - ZCTX(_("CI_SEC^%d seconds")), /* second */ \ - ZCTX(_("CI_THI^%d seconds")), /* third */ \ - ZCTX(_("CI_MUL^%d seconds"))) /* multi */ - -string count_ordinal(int interval) -{ - // This function is designed primarily for the English language, it's impossible - // to accomodate all languages unless we do a specific function for each one... - // and since that's not technically feasible/practical, this is all we've got folks. - - // Basically, it just allows you to represent a number or count in different ways - // depending on the number... like, with count_ordinal you can provide integers - // and retrieve 1st, 2nd, 3rd, nth ordinal numbers in a clean and simple way. - if(floor((interval % 100)/10) * 10 != 10) // examples: 12th, 111th, 213th will not execute this block - { - // otherwise, check normally for 1st,2nd,3rd insertions - switch(interval % 10) - { - case 1: return sprintf(_("%dst"), interval); - case 2: return sprintf(_("%dnd"), interval); - case 3: return sprintf(_("%drd"), interval); - default: return sprintf(_("%dth"), interval); - } - } - else { return sprintf(_("%dth"), interval); } - - return ""; -} - -string count_fill(float interval, string zeroth, string first, string second, string third, string multi) -{ - // This function is designed primarily for the English language, it's impossible - // to accomodate all languages unless we do a specific function for each one... - // and since that's not technically feasible/practical, this is all we've got folks. - - // Here you can insert specific strings based on the interval number, so you could do - // i.e. count_seconds which outputs like this: - // 0 seconds - // 1 second - // 2 seconds - // 3 seconds - // etc... minutes, hours, days, etc. - - switch(floor(interval)) - { - case 0: return sprintf(zeroth, interval); - case 1: - { - if(interval == 1) // EXACTLY value of 1 - return sprintf(first, interval); - else - return sprintf(multi, interval); - } - case 2: return sprintf(second, interval); - case 3: return sprintf(third, interval); - default: return sprintf(multi, interval); - } - return ""; -} - -string process_time(float outputtype, float seconds) -{ - float tmp_hours = 0, tmp_minutes = 0, tmp_seconds = 0; - float tmp_years = 0, tmp_weeks = 0, tmp_days = 0; - - tmp_seconds = floor(seconds); - - if(tmp_seconds) - { - tmp_minutes = floor(tmp_seconds / 60); - - if(tmp_minutes) - { - tmp_seconds -= (tmp_minutes * 60); - tmp_hours = floor(tmp_minutes / 60); - - if(tmp_hours) - { - tmp_minutes -= (tmp_hours * 60); - tmp_days = floor(tmp_hours / 24); - - if(tmp_days) - { - tmp_hours -= (tmp_days * 24); - tmp_weeks = floor(tmp_days / 7); - - if(tmp_weeks) - { - tmp_days -= (tmp_weeks * 7); - tmp_years = floor(tmp_weeks / 52); - } - } - } - } - } - - switch(outputtype) - { - case 1: return sprintf("%02d:%02d:%02d", tmp_hours, tmp_minutes, tmp_seconds); - case 2: - { - string output = ""; - - output = count_seconds(tmp_seconds); - - if(tmp_minutes) - { - output = sprintf( - "%s%s", - count_minutes(tmp_minutes), - ((output != "") ? sprintf(", %s", output) : "")); - } - - if(tmp_hours) - { - output = sprintf( - "%s%s", - count_hours(tmp_hours), - ((output != "") ? sprintf(", %s", output) : "")); - } - - if(tmp_days) - { - output = sprintf( - "%s%s", - count_days(tmp_days), - ((output != "") ? sprintf(", %s", output) : "")); - } - - if(tmp_weeks) - { - output = sprintf( - "%s%s", - count_weeks(tmp_weeks), - ((output != "") ? sprintf(", %s", output) : "")); - } - - if(tmp_years) - { - output = sprintf( - "%s%s", - count_years(tmp_years), - ((output != "") ? sprintf(", %s", output) : "")); - } - - return output; - } - case 3: - { - string output = ""; - - output = count_hours(tmp_hours); - - if(tmp_weeks) { tmp_days += (tmp_weeks * 7); } - if(tmp_years) { tmp_days += (tmp_years * 365); } - if(tmp_days) - { - output = sprintf( - "%s%s", - count_days(tmp_days), - ((output != "") ? sprintf(", %s", output) : "")); - } - - return output; - } - } - return ""; -} -#endif diff --git a/qcsrc/lib/Cvar.qh b/qcsrc/lib/Cvar.qh deleted file mode 100644 index b2093b13e..000000000 --- a/qcsrc/lib/Cvar.qh +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef CVAR_H -#define CVAR_H - -#include "Static.qh" - -void RegisterCvars(void(string name, string desc, bool archive, string file) f) { } - -void RegisterCvars_Set(string name, string desc, bool archive, string file) -{ - localcmd(sprintf("\n%1$s %2$s \"$%2$s\" \"%3$s\"\n", (archive ? "seta" : "set"), name, desc)); -} - -STATIC_INIT_LATE(Cvars) { RegisterCvars(RegisterCvars_Set); } - -#define AUTOCVAR_5(file, archive, var, type, desc) \ - [[accumulate]] void RegisterCvars(void(string, string, bool, string) f) { f(#var, desc, archive, file); } \ - type autocvar_##var -#define AUTOCVAR_6(file, archive, var, type, default, desc) \ - AUTOCVAR_5(file, archive, var, type, desc) = default -#define _AUTOCVAR(...) EVAL(OVERLOAD(AUTOCVAR, __FILE__, __VA_ARGS__)) -#define AUTOCVAR_SAVE(...) _AUTOCVAR(true, __VA_ARGS__) -#define AUTOCVAR(...) _AUTOCVAR(false, __VA_ARGS__) - -#endif diff --git a/qcsrc/lib/Defer.qh b/qcsrc/lib/Defer.qh deleted file mode 100644 index ca626dd7b..000000000 --- a/qcsrc/lib/Defer.qh +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef MENUQC -#ifndef DEFER_H -#define DEFER_H -#include "OO.qh" - -entityclass(Defer); -class(Defer) .entity owner; -class(Defer) .void() think; -class(Defer) .float nextthink; - -/* -================== -SUB_Remove - -Remove self -================== -*/ -void SUB_Remove() -{SELFPARAM(); - remove (self); -} - -void defer_think() -{SELFPARAM(); - self.think = SUB_Remove; - self.nextthink = time; - WITH(entity, self, self.owner, self.use()); -} - -/* - Execute func() after time + fdelay. - self when func is executed = self when defer is called -*/ -void defer(float fdelay, void() func) -{SELFPARAM(); - entity e; - - e = spawn(); - e.owner = self; - e.use = func; - e.think = defer_think; - e.nextthink = time + fdelay; -} - -#endif -#endif diff --git a/qcsrc/lib/Draw.qh b/qcsrc/lib/Draw.qh deleted file mode 100644 index 4ca536956..000000000 --- a/qcsrc/lib/Draw.qh +++ /dev/null @@ -1,133 +0,0 @@ -#ifdef CSQC -#ifndef DRAW_H -#define DRAW_H - -#include "I18N.qh" -#include "Vector.qh" - -#include "../client/defs.qh" - -void Draw_CylindricLine(vector from, vector to, float thickness, string texture, float aspect, float shift, vector rgb, float theAlpha, float drawflag, vector vieworg) -{ - // I want to draw a quad... - // from and to are MIDPOINTS. - - vector axis, thickdir, A, B, C, D; - float length_tex; - - axis = normalize(to - from); - length_tex = aspect * vlen(to - from) / thickness; - - // direction is perpendicular to the view normal, and perpendicular to the axis - thickdir = normalize(cross(axis, vieworg - from)); - - A = from - thickdir * (thickness / 2); - B = from + thickdir * (thickness / 2); - C = to + thickdir * (thickness / 2); - D = to - thickdir * (thickness / 2); - - R_BeginPolygon(texture, drawflag); - R_PolygonVertex(A, '0 0 0' + shift * '1 0 0', rgb, theAlpha); - R_PolygonVertex(B, '0 1 0' + shift * '1 0 0', rgb, theAlpha); - R_PolygonVertex(C, '0 1 0' + (shift + length_tex) * '1 0 0', rgb, theAlpha); - R_PolygonVertex(D, '0 0 0' + (shift + length_tex) * '1 0 0', rgb, theAlpha); - R_EndPolygon(); -} - -// a border picture is a texture containing nine parts: -// 1/4 width: left part -// 1/2 width: middle part (stretched) -// 1/4 width: right part -// divided into -// 1/4 height: top part -// 1/2 height: middle part (stretched) -// 1/4 height: bottom part -void draw_BorderPicture(vector theOrigin, string pic, vector theSize, vector theColor, float theAlpha, vector theBorderSize) -{ - if (theBorderSize.x < 0 && theBorderSize.y < 0) // draw whole image as it is - { - drawpic(theOrigin, pic, theSize, theColor, theAlpha, 0); - return; - } - if (theBorderSize.x == 0 && theBorderSize.y == 0) // no border - { - // draw only the central part - drawsubpic(theOrigin, theSize, pic, '0.25 0.25 0', '0.5 0.5 0', theColor, theAlpha, 0); - return; - } - - vector dX, dY; - vector width, height; - vector bW, bH; - //pic = draw_UseSkinFor(pic); - width = eX * theSize.x; - height = eY * theSize.y; - if(theSize.x <= theBorderSize.x * 2) - { - // not wide enough... draw just left and right then - bW = eX * (0.25 * theSize.x / (theBorderSize.x * 2)); - if(theSize.y <= theBorderSize.y * 2) - { - // not high enough... draw just corners - bH = eY * (0.25 * theSize.y / (theBorderSize.y * 2)); - drawsubpic(theOrigin, width * 0.5 + height * 0.5, pic, '0 0 0', bW + bH, theColor, theAlpha, 0); - drawsubpic(theOrigin + width * 0.5, width * 0.5 + height * 0.5, pic, eX - bW, bW + bH, theColor, theAlpha, 0); - drawsubpic(theOrigin + height * 0.5, width * 0.5 + height * 0.5, pic, eY - bH, bW + bH, theColor, theAlpha, 0); - drawsubpic(theOrigin + theSize * 0.5, width * 0.5 + height * 0.5, pic, eX + eY - bW - bH, bW + bH, theColor, theAlpha, 0); - } - else - { - dY = theBorderSize.x * eY; - drawsubpic(theOrigin, width * 0.5 + dY, pic, '0 0 0', '0 0.25 0' + bW, theColor, theAlpha, 0); - drawsubpic(theOrigin + width * 0.5, width * 0.5 + dY, pic, '0 0 0' + eX - bW, '0 0.25 0' + bW, theColor, theAlpha, 0); - drawsubpic(theOrigin + dY, width * 0.5 + height - 2 * dY, pic, '0 0.25 0', '0 0.5 0' + bW, theColor, theAlpha, 0); - drawsubpic(theOrigin + width * 0.5 + dY, width * 0.5 + height - 2 * dY, pic, '0 0.25 0' + eX - bW, '0 0.5 0' + bW, theColor, theAlpha, 0); - drawsubpic(theOrigin + height - dY, width * 0.5 + dY, pic, '0 0.75 0', '0 0.25 0' + bW, theColor, theAlpha, 0); - drawsubpic(theOrigin + width * 0.5 + height - dY, width * 0.5 + dY, pic, '0 0.75 0' + eX - bW, '0 0.25 0' + bW, theColor, theAlpha, 0); - } - } - else - { - if(theSize.y <= theBorderSize.y * 2) - { - // not high enough... draw just top and bottom then - bH = eY * (0.25 * theSize.y / (theBorderSize.y * 2)); - dX = theBorderSize.x * eX; - drawsubpic(theOrigin, dX + height * 0.5, pic, '0 0 0', '0.25 0 0' + bH, theColor, theAlpha, 0); - drawsubpic(theOrigin + dX, width - 2 * dX + height * 0.5, pic, '0.25 0 0', '0.5 0 0' + bH, theColor, theAlpha, 0); - drawsubpic(theOrigin + width - dX, dX + height * 0.5, pic, '0.75 0 0', '0.25 0 0' + bH, theColor, theAlpha, 0); - drawsubpic(theOrigin + height * 0.5, dX + height * 0.5, pic, '0 0 0' + eY - bH, '0.25 0 0' + bH, theColor, theAlpha, 0); - drawsubpic(theOrigin + dX + height * 0.5, width - 2 * dX + height * 0.5, pic, '0.25 0 0' + eY - bH, '0.5 0 0' + bH, theColor, theAlpha, 0); - drawsubpic(theOrigin + width - dX + height * 0.5, dX + height * 0.5, pic, '0.75 0 0' + eY - bH, '0.25 0 0' + bH, theColor, theAlpha, 0); - } - else - { - dX = theBorderSize.x * eX; - dY = theBorderSize.x * eY; - drawsubpic(theOrigin, dX + dY, pic, '0 0 0', '0.25 0.25 0', theColor, theAlpha, 0); - drawsubpic(theOrigin + dX, width - 2 * dX + dY, pic, '0.25 0 0', '0.5 0.25 0', theColor, theAlpha, 0); - drawsubpic(theOrigin + width - dX, dX + dY, pic, '0.75 0 0', '0.25 0.25 0', theColor, theAlpha, 0); - drawsubpic(theOrigin + dY, dX + height - 2 * dY, pic, '0 0.25 0', '0.25 0.5 0', theColor, theAlpha, 0); - drawsubpic(theOrigin + dY + dX, width - 2 * dX + height - 2 * dY, pic, '0.25 0.25 0', '0.5 0.5 0', theColor, theAlpha, 0); - drawsubpic(theOrigin + dY + width - dX, dX + height - 2 * dY, pic, '0.75 0.25 0', '0.25 0.5 0', theColor, theAlpha, 0); - drawsubpic(theOrigin + height - dY, dX + dY, pic, '0 0.75 0', '0.25 0.25 0', theColor, theAlpha, 0); - drawsubpic(theOrigin + height - dY + dX, width - 2 * dX + dY, pic, '0.25 0.75 0', '0.5 0.25 0', theColor, theAlpha, 0); - drawsubpic(theOrigin + height - dY + width - dX, dX + dY, pic, '0.75 0.75 0', '0.25 0.25 0', theColor, theAlpha, 0); - } - } -} - -void drawstringright(vector position, string text, vector theScale, vector rgb, float theAlpha, int flag) -{ - position.x -= 2 / 3 * strlen(text) * theScale.x; - drawstring(position, text, theScale, rgb, theAlpha, flag); -} - -void drawstringcenter(vector position, string text, vector theScale, vector rgb, float theAlpha, int flag) -{ - position.x = 0.5 * (vid_conwidth - 0.6025 * strlen(text) * theScale.x); - drawstring(position, text, theScale, rgb, theAlpha, flag); -} - -#endif -#endif diff --git a/qcsrc/lib/I18N.qh b/qcsrc/lib/I18N.qh deleted file mode 100644 index ab9aa7d20..000000000 --- a/qcsrc/lib/I18N.qh +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef I18N_H -#define I18N_H - -// translation helpers -string prvm_language; - -string language_filename(string s) -{ - string fn = prvm_language; - if (fn == "" || fn == "dump") - return s; - fn = strcat(s, ".", fn); - int fh = fopen(fn, FILE_READ); - if (fh >= 0) - { - fclose(fh); - return fn; - } - return s; -} - -string CTX(string s) -{ - int p = strstrofs(s, "^", 0); - if (p < 0) - return s; - return substring(s, p + 1, -1); -} - -#define ZCTX(s) strzone(CTX(s)) - -#endif diff --git a/qcsrc/lib/Lazy.qh b/qcsrc/lib/Lazy.qh deleted file mode 100644 index fcf065189..000000000 --- a/qcsrc/lib/Lazy.qh +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef LAZY_H -#define LAZY_H - -#include "OO.qh" - -CLASS(Lazy, Object) - ATTRIB(Lazy, m_get, entity(), func_null); - CONSTRUCTOR(Lazy, entity() _compute) { this.m_get = _compute; } -ENDCLASS(Lazy) - -#define LAZY(id) __lazy_##id -#define LAZY_NEW(id, compute) entity LAZY(id)() { \ - static bool done; \ - static entity it; \ - if (!done) { it = compute; done = true; } \ - return it; \ -} -#endif diff --git a/qcsrc/lib/Log.qh b/qcsrc/lib/Log.qh deleted file mode 100644 index f74dd4aa2..000000000 --- a/qcsrc/lib/Log.qh +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef LOG_H -#define LOG_H - -#define _printferr(...) error(sprintf(__VA_ARGS__)) -#define _printfbt(...) backtrace(sprintf(__VA_ARGS__)) -#define printf(...) print(sprintf(__VA_ARGS__)) -#define dprintf(...) dprint(sprintf(__VA_ARGS__)) -#define _dprintf2(...) do { if (autocvar_developer > 1) dprintf(__VA_ARGS__); } while (0) - -#define assert(expr, ...) do { if (!(expr)) LOG_WARNINGF(__VA_ARGS__); } while (0) - -#define _LOG(f, level, s) f("[::"level"] ["__FILE__":%s:%.0f] %s", __FUNC__, __LINE__, s) - -#define LOG_FATAL(...) _LOG_FATAL(strcat("", __VA_ARGS__)) -#define LOG_FATALF(...) _LOG_FATAL(sprintf(__VA_ARGS__)) -#define _LOG_FATAL(s) _LOG(_printferr, "FATAL", s) - -#define LOG_SEVERE(...) _LOG_SEVERE(strcat("", __VA_ARGS__)) -#define LOG_SEVEREF(...) _LOG_SEVERE(sprintf(__VA_ARGS__)) -#define _LOG_SEVERE(s) _LOG(_printfbt, "SEVERE", s) - -#define LOG_WARNING(...) _LOG_WARNING(strcat("", __VA_ARGS__)) -#define LOG_WARNINGF(...) _LOG_WARNING(sprintf(__VA_ARGS__)) -#define _LOG_WARNING(s) _LOG(printf, "WARNING", s) - -#define LOG_INFO(...) do { if (autocvar_developer) _LOG_INFO(strcat("", __VA_ARGS__)); else print (__VA_ARGS__); } while (0) -#define LOG_INFOF(...) do { if (autocvar_developer) _LOG_INFO(sprintf(__VA_ARGS__)); else printf(__VA_ARGS__); } while (0) -#define _LOG_INFO(s) _LOG(printf, "INFO", s) - -#define LOG_TRACE(...) _LOG_TRACE(strcat("", __VA_ARGS__)) -#define LOG_TRACEF(...) _LOG_TRACE(sprintf(__VA_ARGS__)) -#define _LOG_TRACE(s) _LOG(dprintf, "TRACE", s) - -#define LOG_DEBUG(...) _LOG_DEBUG(strcat("", __VA_ARGS__)) -#define LOG_DEBUGF(...) _LOG_DEBUG(sprintf(__VA_ARGS__)) -#define _LOG_DEBUG(s) _LOG(_dprintf2, "DEBUG", s) - -// TODO: this sucks, lets find a better way to do backtraces? -#ifdef SVQC -void builtin_remove(entity); -#define _backtrace() builtin_remove(NULL) -#else -void remove(entity); -#define _backtrace() remove(NULL) -#endif - -noref int autocvar_developer; -noref bool autocvar_prvm_backtraceforwarnings; - -#define backtrace(msg) do { \ - int dev = autocvar_developer; \ - bool war = autocvar_prvm_backtraceforwarnings; \ - cvar_set("developer", "1"); \ - cvar_set("prvm_backtraceforwarnings", "1"); \ - print("\n--- CUT HERE ---\n", msg, "\n"); \ - _backtrace(); \ - print("\n--- CUT UNTIL HERE ---\n"); \ - cvar_set("developer", ftos(dev)); \ - cvar_set("prvm_backtraceforwarnings", ftos(war)); \ -} while (0) - -#endif diff --git a/qcsrc/lib/Math.qh b/qcsrc/lib/Math.qh deleted file mode 100644 index a8a52907a..000000000 --- a/qcsrc/lib/Math.qh +++ /dev/null @@ -1,93 +0,0 @@ -#ifndef MATH_H -#define MATH_H - -void mean_accumulate(entity e, .float a, .float c, float mean, float value, float weight) -{ - if (weight == 0) - return; - if (mean == 0) - e.(a) *= pow(value, weight); - else - e.(a) += pow(value, mean) * weight; - e.(c) += weight; -} - -float mean_evaluate(entity e, .float a, .float c, float mean) -{ - if (e.(c) == 0) - return 0; - if (mean == 0) - return pow(e.(a), 1.0 / e.(c)); - else - return pow(e.(a) / e.(c), 1.0 / mean); -} - -#define MEAN_ACCUMULATE(prefix,v,w) mean_accumulate(self,prefix##_accumulator,prefix##_count,prefix##_mean,v,w) -#define MEAN_EVALUATE(prefix) mean_evaluate(self,prefix##_accumulator,prefix##_count,prefix##_mean) -#define MEAN_DECLARE(prefix,m) float prefix##_mean = m; .float prefix##_count, prefix##_accumulator - -/* -================== -crandom - -Returns a random number between -1.0 and 1.0 -================== -*/ -float crandom (void) -{ - return 2 * (random () - 0.5); -} - - -/* -================== -Angc used for animations -================== -*/ - - -float angc (float a1, float a2) -{ - float a; - - while (a1 > 180) - a1 = a1 - 360; - while (a1 < -179) - a1 = a1 + 360; - - while (a2 > 180) - a2 = a2 - 360; - while (a2 < -179) - a2 = a2 + 360; - - a = a1 - a2; - while (a > 180) - a = a - 360; - while (a < -179) - a = a + 360; - - return a; -} - -float fsnap(float val,float fsize) -{ - return rint(val / fsize) * fsize; -} - -vector vsnap(vector point,float fsize) -{ - vector vret; - - vret.x = rint(point.x / fsize) * fsize; - vret.y = rint(point.y / fsize) * fsize; - vret.z = ceil(point.z / fsize) * fsize; - - return vret; -} - -vector lerpv(float t0, vector v0, float t1, vector v1, float t) -{ - return v0 + (v1 - v0) * ((t - t0) / (t1 - t0)); -} - -#endif diff --git a/qcsrc/lib/Nil.qh b/qcsrc/lib/Nil.qh deleted file mode 100644 index 789b1f9c0..000000000 --- a/qcsrc/lib/Nil.qh +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef NIL_H -#define NIL_H - -#if QCC_SUPPORT_NIL -#define func_null nil -#define string_null nil -#else -// the NULL function -var void func_null(void); -string string_null; -#endif - -#endif diff --git a/qcsrc/lib/OO.qh b/qcsrc/lib/OO.qh deleted file mode 100644 index 96978baf7..000000000 --- a/qcsrc/lib/OO.qh +++ /dev/null @@ -1,152 +0,0 @@ -#ifndef OO_H -#define OO_H - -#include "Nil.qh" -#include "Registry.qh" - -#ifdef MENUQC - #define NULL (null_entity) -#else - #define NULL (world) -#endif - -.string classname; -/** Location entity was spawned from in source */ -.string sourceLocFile; -.int sourceLocLine; -entity _spawn(); -entity __spawn(string _classname, string _sourceFile, int _sourceLine) { - entity this = _spawn(); - this.classname = _classname; - this.sourceLocFile = _sourceFile; - this.sourceLocLine = _sourceLine; - return this; -} - - - -#define entityclass(...) EVAL(OVERLOAD(entityclass, __VA_ARGS__)) -#define entityclass_1(name) entityclass_2(name, Object) -#ifndef QCC_SUPPORT_ENTITYCLASS - #define entityclass_2(name, base) typedef entity name - #define class(name) - #define new(class) __spawn(#class, __FILE__, __LINE__) -#else - #define entityclass_2(name, base) entityclass name : base {} - #define class(name) [[class(name)]] - #define new(class) ((class) __spawn(#class, __FILE__, __LINE__)) -#endif - -// Classes have a `spawn##cname(entity)` constructor -// The parameter is used across [[accumulate]] functions - -// Macros to hide this implementation detail: -#ifdef GMQCC -#define NEW(cname, ...) \ - OVERLOAD(spawn##cname, new(cname), ##__VA_ARGS__) - -#define CONSTRUCT(cname, ...) \ - OVERLOAD(spawn##cname, this, ##__VA_ARGS__) -#else -#define NEW_(cname, ...) \ - OVERLOAD_(spawn##cname, __VA_ARGS__) -#define NEW(cname, ...) \ - NEW_(cname, new(cname), ##__VA_ARGS__)(new(cname), ##__VA_ARGS__) - -#define CONSTRUCT_(cname, ...) \ - OVERLOAD_(spawn##cname, __VA_ARGS__) -#define CONSTRUCT(cname, ...) \ - CONSTRUCT_(cname, this, ##__VA_ARGS__)(this, ##__VA_ARGS__) -#endif - -#define CONSTRUCTOR(cname, ...) \ - cname OVERLOAD(spawn##cname, cname this, __VA_ARGS__) { return = this; } \ - [[accumulate]] cname OVERLOAD(spawn##cname, cname this, __VA_ARGS__) - -.string vtblname; -.entity vtblbase; - -void RegisterClasses() { } -STATIC_INIT(RegisterClasses) { RegisterClasses(); } - -#define VTBL(cname, base) \ - INIT_STATIC(cname); \ - entity cname##_vtbl; \ - void cname##_vtbl_init() { \ - cname e = new(vtbl); \ - spawn##cname##_static(e); \ - e.vtblname = #cname; \ - /* Top level objects refer to themselves */ \ - e.vtblbase = base##_vtbl ? base##_vtbl : e; \ - cname##_vtbl = e; \ - } \ - ACCUMULATE_FUNCTION(RegisterClasses, cname##_vtbl_init) - -#define INIT_STATIC(cname) [[accumulate]] void spawn##cname##_static(cname this) -#define INIT(cname) [[accumulate]] cname spawn##cname##_1(cname this) - -#define CLASS(cname, base) \ - entityclass(cname, base); \ - class(cname) .bool instanceOf##cname; \ - VTBL(cname, base) \ - INIT_STATIC(cname) { \ - if (cname##_vtbl) { \ - copyentity(cname##_vtbl, this); \ - return; \ - } \ - spawn##base##_static(this); \ - this.instanceOf##cname = true; \ - } \ - INIT(cname) { \ - /* Only statically initialize the current class, it contains everything it inherits */ \ - if (cname##_vtbl.vtblname == this.classname) { \ - spawn##cname##_static(this); \ - this.classname = #cname; \ - this.vtblname = string_null; \ - this.vtblbase = cname##_vtbl; \ - } \ - spawn##base##_1(this); \ - } - -#define METHOD(cname, name, prototype) \ - class(cname) .prototype name; \ - prototype cname##_##name; \ - INIT_STATIC(cname) { this.name = cname##_##name; } \ - prototype cname##_##name - -#define ATTRIB(cname, name, type, val) \ - class(cname) .type name; \ - INIT(cname) { this.name = val; } - -#define ATTRIBARRAY(cname, name, type, cnt) \ - class(cname) .type name[cnt]; - -#define ENDCLASS(cname) \ - [[last]] INIT(cname) { return this; } - -#define SUPER(cname) (cname##_vtbl.vtblbase) -#define super (this.vtblbase.vtblbase) - -#define spawn_static(this) -#define spawn_1(this) -#define _vtbl NULL -CLASS(Object, ); - METHOD(Object, describe, string(entity this)) { - string s = _("No description"); - if (cvar("developer")) { - for (int i = 0, n = numentityfields(); i < n; ++i) { - string value = getentityfieldstring(i, this); - if (value != "") s = sprintf("%s\n%s = %s", s, entityfieldname(i), value); - } - } - return s; - } - METHOD(Object, display, void(entity this, void(string name, string icon) returns)) { - returns(sprintf("entity %i", this), "nopreview_map"); - } -ENDCLASS(Object) -#undef spawn_static -#undef spawn_1 -#undef _vtbl - -#endif diff --git a/qcsrc/lib/Player.qh b/qcsrc/lib/Player.qh deleted file mode 100644 index 07034a066..000000000 --- a/qcsrc/lib/Player.qh +++ /dev/null @@ -1,34 +0,0 @@ -#ifdef CSQC -#ifndef PLAYER_H -#define PLAYER_H - -#include "String.qh" - -#include "../client/main.qh" -#include "../common/teams.qh" - -int GetPlayerColorForce(int i) -{ - if(!teamplay) - return 0; - else - return stof(getplayerkeyvalue(i, "colors")) & 15; -} - -int GetPlayerColor(int i) -{ - if(!playerslots[i].gotscores) // unconnected - return NUM_SPECTATOR; - else if(stof(getplayerkeyvalue(i, "frags")) == FRAGS_SPECTATOR) - return NUM_SPECTATOR; - else - return GetPlayerColorForce(i); -} - -string GetPlayerName(int i) -{ - return ColorTranslateRGB(getplayerkeyvalue(i, "name")); -} - -#endif -#endif diff --git a/qcsrc/lib/Progname.qh b/qcsrc/lib/Progname.qh deleted file mode 100644 index ed112a5c2..000000000 --- a/qcsrc/lib/Progname.qh +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef PROGNAME_H -#define PROGNAME_H - -#if defined(MENUQC) - #define PROGNAME "MENUQC" -#elif defined(SVQC) - #define PROGNAME "SVQC" -#elif defined(CSQC) - #define PROGNAME "CSQC" -#else - #error "Unable to detect PROGNAME" -#endif - -#endif diff --git a/qcsrc/lib/Registry.qh b/qcsrc/lib/Registry.qh deleted file mode 100644 index ca0beae9d..000000000 --- a/qcsrc/lib/Registry.qh +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef REGISTRY_H -#define REGISTRY_H - -#include "OO.qh" - -#define REGISTER_INIT(ns, id) [[accumulate]] void Register_##ns##_##id##_init(entity this) -#define REGISTER_INIT_POST(ns, id) [[accumulate]] void Register_##ns##_##id##_init_post(entity this) - -#define REGISTER(initfunc, ns, array, counter, id, fld, inst) \ - entity ns##_##id; \ - REGISTER_INIT(ns, id) { } \ - REGISTER_INIT_POST(ns, id) { } \ - .entity enemy; /* internal next pointer */ \ - void Register_##ns##_##id() { \ - entity this = inst; \ - ns##_##id = this; \ - this.fld = counter; \ - array[counter++] = this; \ - if (!array##_first) array##_first = this; \ - if ( array##_last) array##_last.enemy = this; \ - array##_last = this; \ - Register_##ns##_##id##_init(this); \ - Register_##ns##_##id##_init_post(this); \ - } \ - ACCUMULATE_FUNCTION(initfunc, Register_##ns##_##id) \ - REGISTER_INIT(ns, id) - -#endif diff --git a/qcsrc/lib/Static.qh b/qcsrc/lib/Static.qh deleted file mode 100644 index d51a87175..000000000 --- a/qcsrc/lib/Static.qh +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef STATIC_H -#define STATIC_H - -void __static_init_early() { } -void __static_init() { CALL_ACCUMULATED_FUNCTION(__static_init_early); } -#define static_init() CALL_ACCUMULATED_FUNCTION(__static_init) -#define REGISTER_REGISTRY(func) ACCUMULATE_FUNCTION(__static_init_early, func) - -#define _STATIC_INIT(where, func) \ - void _static_##func(); \ - ACCUMULATE_FUNCTION(where, _static_##func) \ - void _static_##func() - -#define STATIC_INIT(func) _STATIC_INIT(__static_init_early, func##_early) -#define STATIC_INIT_LATE(func) _STATIC_INIT(__static_init, func) - -#endif diff --git a/qcsrc/lib/String.qh b/qcsrc/lib/String.qh deleted file mode 100644 index faf81b29d..000000000 --- a/qcsrc/lib/String.qh +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef STRING_H -#define STRING_H - -#ifndef SVQC -float stringwidth_colors(string s, vector theSize) -{ - return stringwidth(s, true, theSize); -} - -float stringwidth_nocolors(string s, vector theSize) -{ - return stringwidth(s, false, theSize); -} -#endif - -// Timer (#5) -// -// TODO: macro -string seconds_tostring(float sec) -{ - float minutes; - minutes = floor(sec / 60); - - sec -= minutes * 60; - return sprintf("%d:%02d", minutes, sec); -} - -int ColorTranslateMode; - -string ColorTranslateRGB(string s) -{ - if(ColorTranslateMode & 1) - return strdecolorize(s); - else - return s; -} - -#endif diff --git a/qcsrc/lib/Struct.qh b/qcsrc/lib/Struct.qh deleted file mode 100644 index 507c417f5..000000000 --- a/qcsrc/lib/Struct.qh +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef STRUCT_H -#define STRUCT_H - -#ifndef QCC_SUPPORT_STRUCT - #define _STRUCT_DECLARE(x, id, type, END) noref type x ##_## id ; - #define STRUCT_DECLARE(id, s) s(_STRUCT_DECLARE, id) - - #define _STRUCT_PARAM_(x, id, type) type x ##_## id , - #define _STRUCT_PARAM_END(x, id, type) type x ##_## id - #define _STRUCT_PARAM(x, id, type, isend) _STRUCT_PARAM_##isend(x, id, type) - #define STRUCT_PARAM(id, s) s(_STRUCT_PARAM, id) - - #define _STRUCT_PASS_(x, id, type) x ##_## id , - #define _STRUCT_PASS_END(x, id, type) x ##_## id - #define _STRUCT_PASS(x, id, type, END) _STRUCT_PASS_##END(x, id, type) - #define STRUCT_PASS(id, s) s(_STRUCT_PASS, id) - - #define _STRUCT_STORE_DST(_, it) it - #define _STRUCT_STORE_SRC(it, _) it - #define _CONCAT3_(a, b, c) a ## b ## c - #define _CONCAT3(a, b, c) _CONCAT3_(a, b, c) - #define _STRUCT_STORE(x, id, type, END) _CONCAT3(_STRUCT_STORE_DST x, _, id) = _CONCAT3(_STRUCT_STORE_SRC x, _, id); - #define STRUCT_STORE(from, to, s) s(_STRUCT_STORE, (from, to)) - - #define STRUCT(id, ...) -#else - #define STRUCT_DECLARE(id, type) type id; - #define STRUCT_PARAM(id, type) type id - #define STRUCT_PASS(id, type) id - #define STRUCT_STORE(from, to, s) to = from - #define _STRUCT_MEMBER(my, id, type, END) type id; - #define STRUCT(id, s) struct STRUCT_##id { s(_STRUCT_MEMBER, ) }; -#endif - -#endif diff --git a/qcsrc/lib/Vector.qh b/qcsrc/lib/Vector.qh deleted file mode 100644 index d81a79571..000000000 --- a/qcsrc/lib/Vector.qh +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef VECTOR_H -#define VECTOR_H - -const vector eX = '1 0 0'; -const vector eY = '0 1 0'; -const vector eZ = '0 0 1'; - -vector randompos(vector m1, vector m2) -{ - vector v; - m2 = m2 - m1; - v_x = m2_x * random() + m1_x; - v_y = m2_y * random() + m1_y; - v_z = m2_z * random() + m1_z; - return v; -} - -float vlen2d(vector v) -{ - return sqrt(v.x * v.x + v.y * v.y); -} - -float vlen_maxnorm2d(vector v) -{ - return max(v.x, v.y, -v.x, -v.y); -} - -float vlen_minnorm2d(vector v) -{ - return min(max(v.x, -v.x), max(v.y, -v.y)); -} - - -#endif diff --git a/qcsrc/lib/_all.inc b/qcsrc/lib/_all.inc index 1b7e61e9a..aa541bd69 100644 --- a/qcsrc/lib/_all.inc +++ b/qcsrc/lib/_all.inc @@ -1,28 +1,28 @@ -#include "Bool.qh" +#include "bool.qh" #include "../warpzonelib/mathlib.qc" -#include "Accumulate.qh" -#include "Counting.qh" -#include "Cvar.qh" -#include "Defer.qh" -#include "Draw.qh" -#include "I18N.qh" -#include "Lazy.qh" -#include "Log.qh" -#include "Math.qh" -#include "Nil.qh" +#include "accumulate.qh" +#include "counting.qh" +#include "cvar.qh" +#include "defer.qh" +#include "draw.qh" +#include "i18n.qh" +#include "lazy.qh" +#include "log.qh" +#include "math.qh" +#include "nil.qh" #include "noise.qc" -#include "OO.qh" +#include "oo.qh" #include "p2mathlib.qc" -#include "Player.qh" +#include "player.qh" #include "prandom.qc" -#include "Progname.qh" -#include "Registry.qh" +#include "progname.qh" +#include "registry.qh" #include "sortlist.qc" -#include "Static.qh" -#include "String.qh" -#include "Struct.qh" +#include "static.qh" +#include "string.qh" +#include "struct.qh" #include "test.qc" #include "urllib.qc" -#include "Vector.qh" +#include "vector.qh" diff --git a/qcsrc/lib/accumulate.qh b/qcsrc/lib/accumulate.qh new file mode 100644 index 000000000..7e1a1edc0 --- /dev/null +++ b/qcsrc/lib/accumulate.qh @@ -0,0 +1,52 @@ +#ifndef ACCUMULATE_H +#define ACCUMULATE_H + +#ifdef QCC_SUPPORT_ACCUMULATE +# define ACCUMULATE_FUNCTION(func, otherfunc) \ + [[accumulate]] void func() { otherfunc(); } +# define CALL_ACCUMULATED_FUNCTION(func) \ + func() +#else +#ifdef HAVE_YO_DAWG_CPP +// TODO make ascii art pic of xzibit +// YO DAWG! +// I HERD YO LIEK MACROS +// SO I PUT A MACRO DEFINITION IN YO MACRO DEFINITION +// SO YO CAN EXPAND MACROS WHILE YO EXPAND MACROS +# define ACCUMULATE_FUNCTION(func,otherfunc) \ + #ifdef func \ + void __merge__##otherfunc() { func(); otherfunc(); } \ + #undef func \ + #define func __merge__##otherfunc \ + #else \ + #define func otherfunc \ + #endif +# define CALL_ACCUMULATED_FUNCTION(func) \ + func() +#else +# define ACCUMULATE_FUNCTION(func,otherfunc) \ + .float _ACCUMULATE_##func##__##otherfunc; +void ACCUMULATE_call(string func) +{ + float i; + float n = numentityfields(); + string funcprefix = strcat("_ACCUMULATE_", func, "__"); + float funcprefixlen = strlen(funcprefix); + for(i = 0; i < n; ++i) + { + string name = entityfieldname(i); + if(substring(name, 0, funcprefixlen) == funcprefix) + callfunction(substring(name, funcprefixlen, -1)); + } +} +# define CALL_ACCUMULATED_FUNCTION(func) \ + ACCUMULATE_call(#func) +#endif +#endif + +// used for simplifying ACCUMULATE_FUNCTIONs +#define SET_FIRST_OR_LAST(input,first,count) if(!input) { input = (first + count); } +#define SET_FIELD_COUNT(field,first,count) if(!field) { field = (first + count); ++count; } +#define CHECK_MAX_COUNT(name,max,count,type) if(count > max) { error(strcat("Maximum ", type, " hit: ", #name, ": ", ftos(count), ".\n")); } + +#endif diff --git a/qcsrc/lib/bool.qh b/qcsrc/lib/bool.qh new file mode 100644 index 000000000..26169cd19 --- /dev/null +++ b/qcsrc/lib/bool.qh @@ -0,0 +1,39 @@ +#ifndef BOOL_H +#define BOOL_H + +#ifndef QCC_SUPPORT_BOOL + #define bool float + + // Boolean Constants + const int true = 1; + const int false = 0; +#endif + +// Transitional aliases +[[deprecated("use true")]] [[alias("true")]] const bool TRUE; +[[deprecated("use false")]] [[alias("false")]] const bool FALSE; + +// get true/false value of a string with multiple different inputs +float InterpretBoolean(string input) +{ + switch (strtolower(input)) + { + case "yes": + case "true": + case "on": + return true; + + case "no": + case "false": + case "off": + return false; + + default: return stof(input); + } +} + +float boolean(float value) { // if value is 0 return false (0), otherwise return true (1) + return (value == 0) ? false : true; +} + +#endif diff --git a/qcsrc/lib/counting.qh b/qcsrc/lib/counting.qh new file mode 100644 index 000000000..81103a51c --- /dev/null +++ b/qcsrc/lib/counting.qh @@ -0,0 +1,223 @@ +#ifndef COUNTING_H +#define COUNTING_H + +#include "i18n.qh" + +// =============================================== +// Time processing and counting functions/macros +// =============================================== + +#define count_years_decs(time,decs) sprintf(ZCTX(_("CI_DEC^%s years")), ftos_decimals(time, decs)) +#define count_years(time) count_fill(time, \ + ZCTX(_("CI_ZER^%d years")), /* zeroth */ \ + ZCTX(_("CI_FIR^%d year")), /* first */ \ + ZCTX(_("CI_SEC^%d years")), /* year */ \ + ZCTX(_("CI_THI^%d years")), /* third */ \ + ZCTX(_("CI_MUL^%d years"))) /* multi */ + +#define count_weeks_decs(time,decs) sprintf(ZCTX(_("CI_DEC^%s weeks")), ftos_decimals(time, decs)) +#define count_weeks(time) count_fill(time, \ + ZCTX(_("CI_ZER^%d weeks")), /* zeroth */ \ + ZCTX(_("CI_FIR^%d week")), /* first */ \ + ZCTX(_("CI_SEC^%d weeks")), /* week */ \ + ZCTX(_("CI_THI^%d weeks")), /* third */ \ + ZCTX(_("CI_MUL^%d weeks"))) /* multi */ + +#define count_days_decs(time,decs) sprintf(ZCTX(_("CI_DEC^%s days")), ftos_decimals(time, decs)) +#define count_days(time) count_fill(time, \ + ZCTX(_("CI_ZER^%d days")), /* zeroth */ \ + ZCTX(_("CI_FIR^%d day")), /* first */ \ + ZCTX(_("CI_SEC^%d days")), /* day */ \ + ZCTX(_("CI_THI^%d days")), /* third */ \ + ZCTX(_("CI_MUL^%d days"))) /* multi */ + +#define count_hours_decs(time,decs) sprintf(ZCTX(_("CI_DEC^%s hours")), ftos_decimals(time, decs)) +#define count_hours(time) count_fill(time, \ + ZCTX(_("CI_ZER^%d hours")), /* zeroth */ \ + ZCTX(_("CI_FIR^%d hour")), /* first */ \ + ZCTX(_("CI_SEC^%d hours")), /* hour */ \ + ZCTX(_("CI_THI^%d hours")), /* third */ \ + ZCTX(_("CI_MUL^%d hours"))) /* multi */ + + +#define count_minutes_decs(time,decs) sprintf(ZCTX(_("CI_DEC^%s minutes")), ftos_decimals(time, decs)) +#define count_minutes(time) count_fill(time, \ + ZCTX(_("CI_ZER^%d minutes")), /* zeroth */ \ + ZCTX(_("CI_FIR^%d minute")), /* first */ \ + ZCTX(_("CI_SEC^%d minutes")), /* minute */ \ + ZCTX(_("CI_THI^%d minutes")), /* third */ \ + ZCTX(_("CI_MUL^%d minutes"))) /* multi */ + +#define count_seconds_decs(time,decs) sprintf(ZCTX(_("CI_DEC^%s seconds")), ftos_decimals(time, decs)) +#define count_seconds(time) count_fill(time, \ + ZCTX(_("CI_ZER^%d seconds")), /* zeroth */ \ + ZCTX(_("CI_FIR^%d second")), /* first */ \ + ZCTX(_("CI_SEC^%d seconds")), /* second */ \ + ZCTX(_("CI_THI^%d seconds")), /* third */ \ + ZCTX(_("CI_MUL^%d seconds"))) /* multi */ + +string count_ordinal(int interval) +{ + // This function is designed primarily for the English language, it's impossible + // to accomodate all languages unless we do a specific function for each one... + // and since that's not technically feasible/practical, this is all we've got folks. + + // Basically, it just allows you to represent a number or count in different ways + // depending on the number... like, with count_ordinal you can provide integers + // and retrieve 1st, 2nd, 3rd, nth ordinal numbers in a clean and simple way. + if(floor((interval % 100)/10) * 10 != 10) // examples: 12th, 111th, 213th will not execute this block + { + // otherwise, check normally for 1st,2nd,3rd insertions + switch(interval % 10) + { + case 1: return sprintf(_("%dst"), interval); + case 2: return sprintf(_("%dnd"), interval); + case 3: return sprintf(_("%drd"), interval); + default: return sprintf(_("%dth"), interval); + } + } + else { return sprintf(_("%dth"), interval); } + + return ""; +} + +string count_fill(float interval, string zeroth, string first, string second, string third, string multi) +{ + // This function is designed primarily for the English language, it's impossible + // to accomodate all languages unless we do a specific function for each one... + // and since that's not technically feasible/practical, this is all we've got folks. + + // Here you can insert specific strings based on the interval number, so you could do + // i.e. count_seconds which outputs like this: + // 0 seconds + // 1 second + // 2 seconds + // 3 seconds + // etc... minutes, hours, days, etc. + + switch(floor(interval)) + { + case 0: return sprintf(zeroth, interval); + case 1: + { + if(interval == 1) // EXACTLY value of 1 + return sprintf(first, interval); + else + return sprintf(multi, interval); + } + case 2: return sprintf(second, interval); + case 3: return sprintf(third, interval); + default: return sprintf(multi, interval); + } + return ""; +} + +string process_time(float outputtype, float seconds) +{ + float tmp_hours = 0, tmp_minutes = 0, tmp_seconds = 0; + float tmp_years = 0, tmp_weeks = 0, tmp_days = 0; + + tmp_seconds = floor(seconds); + + if(tmp_seconds) + { + tmp_minutes = floor(tmp_seconds / 60); + + if(tmp_minutes) + { + tmp_seconds -= (tmp_minutes * 60); + tmp_hours = floor(tmp_minutes / 60); + + if(tmp_hours) + { + tmp_minutes -= (tmp_hours * 60); + tmp_days = floor(tmp_hours / 24); + + if(tmp_days) + { + tmp_hours -= (tmp_days * 24); + tmp_weeks = floor(tmp_days / 7); + + if(tmp_weeks) + { + tmp_days -= (tmp_weeks * 7); + tmp_years = floor(tmp_weeks / 52); + } + } + } + } + } + + switch(outputtype) + { + case 1: return sprintf("%02d:%02d:%02d", tmp_hours, tmp_minutes, tmp_seconds); + case 2: + { + string output = ""; + + output = count_seconds(tmp_seconds); + + if(tmp_minutes) + { + output = sprintf( + "%s%s", + count_minutes(tmp_minutes), + ((output != "") ? sprintf(", %s", output) : "")); + } + + if(tmp_hours) + { + output = sprintf( + "%s%s", + count_hours(tmp_hours), + ((output != "") ? sprintf(", %s", output) : "")); + } + + if(tmp_days) + { + output = sprintf( + "%s%s", + count_days(tmp_days), + ((output != "") ? sprintf(", %s", output) : "")); + } + + if(tmp_weeks) + { + output = sprintf( + "%s%s", + count_weeks(tmp_weeks), + ((output != "") ? sprintf(", %s", output) : "")); + } + + if(tmp_years) + { + output = sprintf( + "%s%s", + count_years(tmp_years), + ((output != "") ? sprintf(", %s", output) : "")); + } + + return output; + } + case 3: + { + string output = ""; + + output = count_hours(tmp_hours); + + if(tmp_weeks) { tmp_days += (tmp_weeks * 7); } + if(tmp_years) { tmp_days += (tmp_years * 365); } + if(tmp_days) + { + output = sprintf( + "%s%s", + count_days(tmp_days), + ((output != "") ? sprintf(", %s", output) : "")); + } + + return output; + } + } + return ""; +} +#endif diff --git a/qcsrc/lib/cvar.qh b/qcsrc/lib/cvar.qh new file mode 100644 index 000000000..1da1f276d --- /dev/null +++ b/qcsrc/lib/cvar.qh @@ -0,0 +1,24 @@ +#ifndef CVAR_H +#define CVAR_H + +#include "static.qh" + +void RegisterCvars(void(string name, string desc, bool archive, string file) f) { } + +void RegisterCvars_Set(string name, string desc, bool archive, string file) +{ + localcmd(sprintf("\n%1$s %2$s \"$%2$s\" \"%3$s\"\n", (archive ? "seta" : "set"), name, desc)); +} + +STATIC_INIT_LATE(Cvars) { RegisterCvars(RegisterCvars_Set); } + +#define AUTOCVAR_5(file, archive, var, type, desc) \ + [[accumulate]] void RegisterCvars(void(string, string, bool, string) f) { f(#var, desc, archive, file); } \ + type autocvar_##var +#define AUTOCVAR_6(file, archive, var, type, default, desc) \ + AUTOCVAR_5(file, archive, var, type, desc) = default +#define _AUTOCVAR(...) EVAL(OVERLOAD(AUTOCVAR, __FILE__, __VA_ARGS__)) +#define AUTOCVAR_SAVE(...) _AUTOCVAR(true, __VA_ARGS__) +#define AUTOCVAR(...) _AUTOCVAR(false, __VA_ARGS__) + +#endif diff --git a/qcsrc/lib/defer.qh b/qcsrc/lib/defer.qh new file mode 100644 index 000000000..2a1361116 --- /dev/null +++ b/qcsrc/lib/defer.qh @@ -0,0 +1,46 @@ +#ifndef MENUQC +#ifndef DEFER_H +#define DEFER_H +#include "oo.qh" + +entityclass(Defer); +class(Defer) .entity owner; +class(Defer) .void() think; +class(Defer) .float nextthink; + +/* +================== +SUB_Remove + +Remove self +================== +*/ +void SUB_Remove() +{SELFPARAM(); + remove (self); +} + +void defer_think() +{SELFPARAM(); + self.think = SUB_Remove; + self.nextthink = time; + WITH(entity, self, self.owner, self.use()); +} + +/* + Execute func() after time + fdelay. + self when func is executed = self when defer is called +*/ +void defer(float fdelay, void() func) +{SELFPARAM(); + entity e; + + e = spawn(); + e.owner = self; + e.use = func; + e.think = defer_think; + e.nextthink = time + fdelay; +} + +#endif +#endif diff --git a/qcsrc/lib/draw.qh b/qcsrc/lib/draw.qh new file mode 100644 index 000000000..90abcb2d3 --- /dev/null +++ b/qcsrc/lib/draw.qh @@ -0,0 +1,133 @@ +#ifdef CSQC +#ifndef DRAW_H +#define DRAW_H + +#include "i18n.qh" +#include "vector.qh" + +#include "../client/defs.qh" + +void Draw_CylindricLine(vector from, vector to, float thickness, string texture, float aspect, float shift, vector rgb, float theAlpha, float drawflag, vector vieworg) +{ + // I want to draw a quad... + // from and to are MIDPOINTS. + + vector axis, thickdir, A, B, C, D; + float length_tex; + + axis = normalize(to - from); + length_tex = aspect * vlen(to - from) / thickness; + + // direction is perpendicular to the view normal, and perpendicular to the axis + thickdir = normalize(cross(axis, vieworg - from)); + + A = from - thickdir * (thickness / 2); + B = from + thickdir * (thickness / 2); + C = to + thickdir * (thickness / 2); + D = to - thickdir * (thickness / 2); + + R_BeginPolygon(texture, drawflag); + R_PolygonVertex(A, '0 0 0' + shift * '1 0 0', rgb, theAlpha); + R_PolygonVertex(B, '0 1 0' + shift * '1 0 0', rgb, theAlpha); + R_PolygonVertex(C, '0 1 0' + (shift + length_tex) * '1 0 0', rgb, theAlpha); + R_PolygonVertex(D, '0 0 0' + (shift + length_tex) * '1 0 0', rgb, theAlpha); + R_EndPolygon(); +} + +// a border picture is a texture containing nine parts: +// 1/4 width: left part +// 1/2 width: middle part (stretched) +// 1/4 width: right part +// divided into +// 1/4 height: top part +// 1/2 height: middle part (stretched) +// 1/4 height: bottom part +void draw_BorderPicture(vector theOrigin, string pic, vector theSize, vector theColor, float theAlpha, vector theBorderSize) +{ + if (theBorderSize.x < 0 && theBorderSize.y < 0) // draw whole image as it is + { + drawpic(theOrigin, pic, theSize, theColor, theAlpha, 0); + return; + } + if (theBorderSize.x == 0 && theBorderSize.y == 0) // no border + { + // draw only the central part + drawsubpic(theOrigin, theSize, pic, '0.25 0.25 0', '0.5 0.5 0', theColor, theAlpha, 0); + return; + } + + vector dX, dY; + vector width, height; + vector bW, bH; + //pic = draw_UseSkinFor(pic); + width = eX * theSize.x; + height = eY * theSize.y; + if(theSize.x <= theBorderSize.x * 2) + { + // not wide enough... draw just left and right then + bW = eX * (0.25 * theSize.x / (theBorderSize.x * 2)); + if(theSize.y <= theBorderSize.y * 2) + { + // not high enough... draw just corners + bH = eY * (0.25 * theSize.y / (theBorderSize.y * 2)); + drawsubpic(theOrigin, width * 0.5 + height * 0.5, pic, '0 0 0', bW + bH, theColor, theAlpha, 0); + drawsubpic(theOrigin + width * 0.5, width * 0.5 + height * 0.5, pic, eX - bW, bW + bH, theColor, theAlpha, 0); + drawsubpic(theOrigin + height * 0.5, width * 0.5 + height * 0.5, pic, eY - bH, bW + bH, theColor, theAlpha, 0); + drawsubpic(theOrigin + theSize * 0.5, width * 0.5 + height * 0.5, pic, eX + eY - bW - bH, bW + bH, theColor, theAlpha, 0); + } + else + { + dY = theBorderSize.x * eY; + drawsubpic(theOrigin, width * 0.5 + dY, pic, '0 0 0', '0 0.25 0' + bW, theColor, theAlpha, 0); + drawsubpic(theOrigin + width * 0.5, width * 0.5 + dY, pic, '0 0 0' + eX - bW, '0 0.25 0' + bW, theColor, theAlpha, 0); + drawsubpic(theOrigin + dY, width * 0.5 + height - 2 * dY, pic, '0 0.25 0', '0 0.5 0' + bW, theColor, theAlpha, 0); + drawsubpic(theOrigin + width * 0.5 + dY, width * 0.5 + height - 2 * dY, pic, '0 0.25 0' + eX - bW, '0 0.5 0' + bW, theColor, theAlpha, 0); + drawsubpic(theOrigin + height - dY, width * 0.5 + dY, pic, '0 0.75 0', '0 0.25 0' + bW, theColor, theAlpha, 0); + drawsubpic(theOrigin + width * 0.5 + height - dY, width * 0.5 + dY, pic, '0 0.75 0' + eX - bW, '0 0.25 0' + bW, theColor, theAlpha, 0); + } + } + else + { + if(theSize.y <= theBorderSize.y * 2) + { + // not high enough... draw just top and bottom then + bH = eY * (0.25 * theSize.y / (theBorderSize.y * 2)); + dX = theBorderSize.x * eX; + drawsubpic(theOrigin, dX + height * 0.5, pic, '0 0 0', '0.25 0 0' + bH, theColor, theAlpha, 0); + drawsubpic(theOrigin + dX, width - 2 * dX + height * 0.5, pic, '0.25 0 0', '0.5 0 0' + bH, theColor, theAlpha, 0); + drawsubpic(theOrigin + width - dX, dX + height * 0.5, pic, '0.75 0 0', '0.25 0 0' + bH, theColor, theAlpha, 0); + drawsubpic(theOrigin + height * 0.5, dX + height * 0.5, pic, '0 0 0' + eY - bH, '0.25 0 0' + bH, theColor, theAlpha, 0); + drawsubpic(theOrigin + dX + height * 0.5, width - 2 * dX + height * 0.5, pic, '0.25 0 0' + eY - bH, '0.5 0 0' + bH, theColor, theAlpha, 0); + drawsubpic(theOrigin + width - dX + height * 0.5, dX + height * 0.5, pic, '0.75 0 0' + eY - bH, '0.25 0 0' + bH, theColor, theAlpha, 0); + } + else + { + dX = theBorderSize.x * eX; + dY = theBorderSize.x * eY; + drawsubpic(theOrigin, dX + dY, pic, '0 0 0', '0.25 0.25 0', theColor, theAlpha, 0); + drawsubpic(theOrigin + dX, width - 2 * dX + dY, pic, '0.25 0 0', '0.5 0.25 0', theColor, theAlpha, 0); + drawsubpic(theOrigin + width - dX, dX + dY, pic, '0.75 0 0', '0.25 0.25 0', theColor, theAlpha, 0); + drawsubpic(theOrigin + dY, dX + height - 2 * dY, pic, '0 0.25 0', '0.25 0.5 0', theColor, theAlpha, 0); + drawsubpic(theOrigin + dY + dX, width - 2 * dX + height - 2 * dY, pic, '0.25 0.25 0', '0.5 0.5 0', theColor, theAlpha, 0); + drawsubpic(theOrigin + dY + width - dX, dX + height - 2 * dY, pic, '0.75 0.25 0', '0.25 0.5 0', theColor, theAlpha, 0); + drawsubpic(theOrigin + height - dY, dX + dY, pic, '0 0.75 0', '0.25 0.25 0', theColor, theAlpha, 0); + drawsubpic(theOrigin + height - dY + dX, width - 2 * dX + dY, pic, '0.25 0.75 0', '0.5 0.25 0', theColor, theAlpha, 0); + drawsubpic(theOrigin + height - dY + width - dX, dX + dY, pic, '0.75 0.75 0', '0.25 0.25 0', theColor, theAlpha, 0); + } + } +} + +void drawstringright(vector position, string text, vector theScale, vector rgb, float theAlpha, int flag) +{ + position.x -= 2 / 3 * strlen(text) * theScale.x; + drawstring(position, text, theScale, rgb, theAlpha, flag); +} + +void drawstringcenter(vector position, string text, vector theScale, vector rgb, float theAlpha, int flag) +{ + position.x = 0.5 * (vid_conwidth - 0.6025 * strlen(text) * theScale.x); + drawstring(position, text, theScale, rgb, theAlpha, flag); +} + +#endif +#endif diff --git a/qcsrc/lib/i18n.qh b/qcsrc/lib/i18n.qh new file mode 100644 index 000000000..87c41cda5 --- /dev/null +++ b/qcsrc/lib/i18n.qh @@ -0,0 +1,34 @@ +#ifndef I18N_H +#define I18N_H + +#include "log.qh" + +// translation helpers +string prvm_language; + +string language_filename(string s) +{ + string fn = prvm_language; + if (fn == "" || fn == "dump") + return s; + fn = strcat(s, ".", fn); + int fh = fopen(fn, FILE_READ); + if (fh >= 0) + { + fclose(fh); + return fn; + } + return s; +} + +string CTX(string s) +{ + int p = strstrofs(s, "^", 0); + if (p < 0) + return s; + return substring(s, p + 1, -1); +} + +#define ZCTX(s) strzone(CTX(s)) + +#endif diff --git a/qcsrc/lib/lazy.qh b/qcsrc/lib/lazy.qh new file mode 100644 index 000000000..f632b38c3 --- /dev/null +++ b/qcsrc/lib/lazy.qh @@ -0,0 +1,18 @@ +#ifndef LAZY_H +#define LAZY_H + +#include "oo.qh" + +CLASS(Lazy, Object) + ATTRIB(Lazy, m_get, entity(), func_null); + CONSTRUCTOR(Lazy, entity() _compute) { this.m_get = _compute; } +ENDCLASS(Lazy) + +#define LAZY(id) __lazy_##id +#define LAZY_NEW(id, compute) entity LAZY(id)() { \ + static bool done; \ + static entity it; \ + if (!done) { it = compute; done = true; } \ + return it; \ +} +#endif diff --git a/qcsrc/lib/log.qh b/qcsrc/lib/log.qh new file mode 100644 index 000000000..f74dd4aa2 --- /dev/null +++ b/qcsrc/lib/log.qh @@ -0,0 +1,62 @@ +#ifndef LOG_H +#define LOG_H + +#define _printferr(...) error(sprintf(__VA_ARGS__)) +#define _printfbt(...) backtrace(sprintf(__VA_ARGS__)) +#define printf(...) print(sprintf(__VA_ARGS__)) +#define dprintf(...) dprint(sprintf(__VA_ARGS__)) +#define _dprintf2(...) do { if (autocvar_developer > 1) dprintf(__VA_ARGS__); } while (0) + +#define assert(expr, ...) do { if (!(expr)) LOG_WARNINGF(__VA_ARGS__); } while (0) + +#define _LOG(f, level, s) f("[::"level"] ["__FILE__":%s:%.0f] %s", __FUNC__, __LINE__, s) + +#define LOG_FATAL(...) _LOG_FATAL(strcat("", __VA_ARGS__)) +#define LOG_FATALF(...) _LOG_FATAL(sprintf(__VA_ARGS__)) +#define _LOG_FATAL(s) _LOG(_printferr, "FATAL", s) + +#define LOG_SEVERE(...) _LOG_SEVERE(strcat("", __VA_ARGS__)) +#define LOG_SEVEREF(...) _LOG_SEVERE(sprintf(__VA_ARGS__)) +#define _LOG_SEVERE(s) _LOG(_printfbt, "SEVERE", s) + +#define LOG_WARNING(...) _LOG_WARNING(strcat("", __VA_ARGS__)) +#define LOG_WARNINGF(...) _LOG_WARNING(sprintf(__VA_ARGS__)) +#define _LOG_WARNING(s) _LOG(printf, "WARNING", s) + +#define LOG_INFO(...) do { if (autocvar_developer) _LOG_INFO(strcat("", __VA_ARGS__)); else print (__VA_ARGS__); } while (0) +#define LOG_INFOF(...) do { if (autocvar_developer) _LOG_INFO(sprintf(__VA_ARGS__)); else printf(__VA_ARGS__); } while (0) +#define _LOG_INFO(s) _LOG(printf, "INFO", s) + +#define LOG_TRACE(...) _LOG_TRACE(strcat("", __VA_ARGS__)) +#define LOG_TRACEF(...) _LOG_TRACE(sprintf(__VA_ARGS__)) +#define _LOG_TRACE(s) _LOG(dprintf, "TRACE", s) + +#define LOG_DEBUG(...) _LOG_DEBUG(strcat("", __VA_ARGS__)) +#define LOG_DEBUGF(...) _LOG_DEBUG(sprintf(__VA_ARGS__)) +#define _LOG_DEBUG(s) _LOG(_dprintf2, "DEBUG", s) + +// TODO: this sucks, lets find a better way to do backtraces? +#ifdef SVQC +void builtin_remove(entity); +#define _backtrace() builtin_remove(NULL) +#else +void remove(entity); +#define _backtrace() remove(NULL) +#endif + +noref int autocvar_developer; +noref bool autocvar_prvm_backtraceforwarnings; + +#define backtrace(msg) do { \ + int dev = autocvar_developer; \ + bool war = autocvar_prvm_backtraceforwarnings; \ + cvar_set("developer", "1"); \ + cvar_set("prvm_backtraceforwarnings", "1"); \ + print("\n--- CUT HERE ---\n", msg, "\n"); \ + _backtrace(); \ + print("\n--- CUT UNTIL HERE ---\n"); \ + cvar_set("developer", ftos(dev)); \ + cvar_set("prvm_backtraceforwarnings", ftos(war)); \ +} while (0) + +#endif diff --git a/qcsrc/lib/math.qh b/qcsrc/lib/math.qh new file mode 100644 index 000000000..a8a52907a --- /dev/null +++ b/qcsrc/lib/math.qh @@ -0,0 +1,93 @@ +#ifndef MATH_H +#define MATH_H + +void mean_accumulate(entity e, .float a, .float c, float mean, float value, float weight) +{ + if (weight == 0) + return; + if (mean == 0) + e.(a) *= pow(value, weight); + else + e.(a) += pow(value, mean) * weight; + e.(c) += weight; +} + +float mean_evaluate(entity e, .float a, .float c, float mean) +{ + if (e.(c) == 0) + return 0; + if (mean == 0) + return pow(e.(a), 1.0 / e.(c)); + else + return pow(e.(a) / e.(c), 1.0 / mean); +} + +#define MEAN_ACCUMULATE(prefix,v,w) mean_accumulate(self,prefix##_accumulator,prefix##_count,prefix##_mean,v,w) +#define MEAN_EVALUATE(prefix) mean_evaluate(self,prefix##_accumulator,prefix##_count,prefix##_mean) +#define MEAN_DECLARE(prefix,m) float prefix##_mean = m; .float prefix##_count, prefix##_accumulator + +/* +================== +crandom + +Returns a random number between -1.0 and 1.0 +================== +*/ +float crandom (void) +{ + return 2 * (random () - 0.5); +} + + +/* +================== +Angc used for animations +================== +*/ + + +float angc (float a1, float a2) +{ + float a; + + while (a1 > 180) + a1 = a1 - 360; + while (a1 < -179) + a1 = a1 + 360; + + while (a2 > 180) + a2 = a2 - 360; + while (a2 < -179) + a2 = a2 + 360; + + a = a1 - a2; + while (a > 180) + a = a - 360; + while (a < -179) + a = a + 360; + + return a; +} + +float fsnap(float val,float fsize) +{ + return rint(val / fsize) * fsize; +} + +vector vsnap(vector point,float fsize) +{ + vector vret; + + vret.x = rint(point.x / fsize) * fsize; + vret.y = rint(point.y / fsize) * fsize; + vret.z = ceil(point.z / fsize) * fsize; + + return vret; +} + +vector lerpv(float t0, vector v0, float t1, vector v1, float t) +{ + return v0 + (v1 - v0) * ((t - t0) / (t1 - t0)); +} + +#endif diff --git a/qcsrc/lib/nil.qh b/qcsrc/lib/nil.qh new file mode 100644 index 000000000..789b1f9c0 --- /dev/null +++ b/qcsrc/lib/nil.qh @@ -0,0 +1,13 @@ +#ifndef NIL_H +#define NIL_H + +#if QCC_SUPPORT_NIL +#define func_null nil +#define string_null nil +#else +// the NULL function +var void func_null(void); +string string_null; +#endif + +#endif diff --git a/qcsrc/lib/oo.qh b/qcsrc/lib/oo.qh new file mode 100644 index 000000000..88c0ef8a4 --- /dev/null +++ b/qcsrc/lib/oo.qh @@ -0,0 +1,152 @@ +#ifndef OO_H +#define OO_H + +#include "nil.qh" +#include "registry.qh" + +#ifdef MENUQC + #define NULL (null_entity) +#else + #define NULL (world) +#endif + +.string classname; +/** Location entity was spawned from in source */ +.string sourceLocFile; +.int sourceLocLine; +entity _spawn(); +entity __spawn(string _classname, string _sourceFile, int _sourceLine) { + entity this = _spawn(); + this.classname = _classname; + this.sourceLocFile = _sourceFile; + this.sourceLocLine = _sourceLine; + return this; +} + + + +#define entityclass(...) EVAL(OVERLOAD(entityclass, __VA_ARGS__)) +#define entityclass_1(name) entityclass_2(name, Object) +#ifndef QCC_SUPPORT_ENTITYCLASS + #define entityclass_2(name, base) typedef entity name + #define class(name) + #define new(class) __spawn(#class, __FILE__, __LINE__) +#else + #define entityclass_2(name, base) entityclass name : base {} + #define class(name) [[class(name)]] + #define new(class) ((class) __spawn(#class, __FILE__, __LINE__)) +#endif + +// Classes have a `spawn##cname(entity)` constructor +// The parameter is used across [[accumulate]] functions + +// Macros to hide this implementation detail: +#ifdef GMQCC +#define NEW(cname, ...) \ + OVERLOAD(spawn##cname, new(cname), ##__VA_ARGS__) + +#define CONSTRUCT(cname, ...) \ + OVERLOAD(spawn##cname, this, ##__VA_ARGS__) +#else +#define NEW_(cname, ...) \ + OVERLOAD_(spawn##cname, __VA_ARGS__) +#define NEW(cname, ...) \ + NEW_(cname, new(cname), ##__VA_ARGS__)(new(cname), ##__VA_ARGS__) + +#define CONSTRUCT_(cname, ...) \ + OVERLOAD_(spawn##cname, __VA_ARGS__) +#define CONSTRUCT(cname, ...) \ + CONSTRUCT_(cname, this, ##__VA_ARGS__)(this, ##__VA_ARGS__) +#endif + +#define CONSTRUCTOR(cname, ...) \ + cname OVERLOAD(spawn##cname, cname this, __VA_ARGS__) { return = this; } \ + [[accumulate]] cname OVERLOAD(spawn##cname, cname this, __VA_ARGS__) + +.string vtblname; +.entity vtblbase; + +void RegisterClasses() { } +STATIC_INIT(RegisterClasses) { RegisterClasses(); } + +#define VTBL(cname, base) \ + INIT_STATIC(cname); \ + entity cname##_vtbl; \ + void cname##_vtbl_init() { \ + cname e = new(vtbl); \ + spawn##cname##_static(e); \ + e.vtblname = #cname; \ + /* Top level objects refer to themselves */ \ + e.vtblbase = base##_vtbl ? base##_vtbl : e; \ + cname##_vtbl = e; \ + } \ + ACCUMULATE_FUNCTION(RegisterClasses, cname##_vtbl_init) + +#define INIT_STATIC(cname) [[accumulate]] void spawn##cname##_static(cname this) +#define INIT(cname) [[accumulate]] cname spawn##cname##_1(cname this) + +#define CLASS(cname, base) \ + entityclass(cname, base); \ + class(cname) .bool instanceOf##cname; \ + VTBL(cname, base) \ + INIT_STATIC(cname) { \ + if (cname##_vtbl) { \ + copyentity(cname##_vtbl, this); \ + return; \ + } \ + spawn##base##_static(this); \ + this.instanceOf##cname = true; \ + } \ + INIT(cname) { \ + /* Only statically initialize the current class, it contains everything it inherits */ \ + if (cname##_vtbl.vtblname == this.classname) { \ + spawn##cname##_static(this); \ + this.classname = #cname; \ + this.vtblname = string_null; \ + this.vtblbase = cname##_vtbl; \ + } \ + spawn##base##_1(this); \ + } + +#define METHOD(cname, name, prototype) \ + class(cname) .prototype name; \ + prototype cname##_##name; \ + INIT_STATIC(cname) { this.name = cname##_##name; } \ + prototype cname##_##name + +#define ATTRIB(cname, name, type, val) \ + class(cname) .type name; \ + INIT(cname) { this.name = val; } + +#define ATTRIBARRAY(cname, name, type, cnt) \ + class(cname) .type name[cnt]; + +#define ENDCLASS(cname) \ + [[last]] INIT(cname) { return this; } + +#define SUPER(cname) (cname##_vtbl.vtblbase) +#define super (this.vtblbase.vtblbase) + +#define spawn_static(this) +#define spawn_1(this) +#define _vtbl NULL +CLASS(Object, ); + METHOD(Object, describe, string(entity this)) { + string s = _("No description"); + if (cvar("developer")) { + for (int i = 0, n = numentityfields(); i < n; ++i) { + string value = getentityfieldstring(i, this); + if (value != "") s = sprintf("%s\n%s = %s", s, entityfieldname(i), value); + } + } + return s; + } + METHOD(Object, display, void(entity this, void(string name, string icon) returns)) { + returns(sprintf("entity %i", this), "nopreview_map"); + } +ENDCLASS(Object) +#undef spawn_static +#undef spawn_1 +#undef _vtbl + +#endif diff --git a/qcsrc/lib/player.qh b/qcsrc/lib/player.qh new file mode 100644 index 000000000..f89a3b07a --- /dev/null +++ b/qcsrc/lib/player.qh @@ -0,0 +1,34 @@ +#ifdef CSQC +#ifndef PLAYER_H +#define PLAYER_H + +#include "string.qh" + +#include "../client/main.qh" +#include "../common/teams.qh" + +int GetPlayerColorForce(int i) +{ + if(!teamplay) + return 0; + else + return stof(getplayerkeyvalue(i, "colors")) & 15; +} + +int GetPlayerColor(int i) +{ + if(!playerslots[i].gotscores) // unconnected + return NUM_SPECTATOR; + else if(stof(getplayerkeyvalue(i, "frags")) == FRAGS_SPECTATOR) + return NUM_SPECTATOR; + else + return GetPlayerColorForce(i); +} + +string GetPlayerName(int i) +{ + return ColorTranslateRGB(getplayerkeyvalue(i, "name")); +} + +#endif +#endif diff --git a/qcsrc/lib/progname.qh b/qcsrc/lib/progname.qh new file mode 100644 index 000000000..ed112a5c2 --- /dev/null +++ b/qcsrc/lib/progname.qh @@ -0,0 +1,14 @@ +#ifndef PROGNAME_H +#define PROGNAME_H + +#if defined(MENUQC) + #define PROGNAME "MENUQC" +#elif defined(SVQC) + #define PROGNAME "SVQC" +#elif defined(CSQC) + #define PROGNAME "CSQC" +#else + #error "Unable to detect PROGNAME" +#endif + +#endif diff --git a/qcsrc/lib/registry.qh b/qcsrc/lib/registry.qh new file mode 100644 index 000000000..d9317e8cb --- /dev/null +++ b/qcsrc/lib/registry.qh @@ -0,0 +1,28 @@ +#ifndef REGISTRY_H +#define REGISTRY_H + +#include "oo.qh" + +#define REGISTER_INIT(ns, id) [[accumulate]] void Register_##ns##_##id##_init(entity this) +#define REGISTER_INIT_POST(ns, id) [[accumulate]] void Register_##ns##_##id##_init_post(entity this) + +#define REGISTER(initfunc, ns, array, counter, id, fld, inst) \ + entity ns##_##id; \ + REGISTER_INIT(ns, id) { } \ + REGISTER_INIT_POST(ns, id) { } \ + .entity enemy; /* internal next pointer */ \ + void Register_##ns##_##id() { \ + entity this = inst; \ + ns##_##id = this; \ + this.fld = counter; \ + array[counter++] = this; \ + if (!array##_first) array##_first = this; \ + if ( array##_last) array##_last.enemy = this; \ + array##_last = this; \ + Register_##ns##_##id##_init(this); \ + Register_##ns##_##id##_init_post(this); \ + } \ + ACCUMULATE_FUNCTION(initfunc, Register_##ns##_##id) \ + REGISTER_INIT(ns, id) + +#endif diff --git a/qcsrc/lib/static.qh b/qcsrc/lib/static.qh new file mode 100644 index 000000000..d51a87175 --- /dev/null +++ b/qcsrc/lib/static.qh @@ -0,0 +1,17 @@ +#ifndef STATIC_H +#define STATIC_H + +void __static_init_early() { } +void __static_init() { CALL_ACCUMULATED_FUNCTION(__static_init_early); } +#define static_init() CALL_ACCUMULATED_FUNCTION(__static_init) +#define REGISTER_REGISTRY(func) ACCUMULATE_FUNCTION(__static_init_early, func) + +#define _STATIC_INIT(where, func) \ + void _static_##func(); \ + ACCUMULATE_FUNCTION(where, _static_##func) \ + void _static_##func() + +#define STATIC_INIT(func) _STATIC_INIT(__static_init_early, func##_early) +#define STATIC_INIT_LATE(func) _STATIC_INIT(__static_init, func) + +#endif diff --git a/qcsrc/lib/string.qh b/qcsrc/lib/string.qh new file mode 100644 index 000000000..faf81b29d --- /dev/null +++ b/qcsrc/lib/string.qh @@ -0,0 +1,38 @@ +#ifndef STRING_H +#define STRING_H + +#ifndef SVQC +float stringwidth_colors(string s, vector theSize) +{ + return stringwidth(s, true, theSize); +} + +float stringwidth_nocolors(string s, vector theSize) +{ + return stringwidth(s, false, theSize); +} +#endif + +// Timer (#5) +// +// TODO: macro +string seconds_tostring(float sec) +{ + float minutes; + minutes = floor(sec / 60); + + sec -= minutes * 60; + return sprintf("%d:%02d", minutes, sec); +} + +int ColorTranslateMode; + +string ColorTranslateRGB(string s) +{ + if(ColorTranslateMode & 1) + return strdecolorize(s); + else + return s; +} + +#endif diff --git a/qcsrc/lib/struct.qh b/qcsrc/lib/struct.qh new file mode 100644 index 000000000..507c417f5 --- /dev/null +++ b/qcsrc/lib/struct.qh @@ -0,0 +1,35 @@ +#ifndef STRUCT_H +#define STRUCT_H + +#ifndef QCC_SUPPORT_STRUCT + #define _STRUCT_DECLARE(x, id, type, END) noref type x ##_## id ; + #define STRUCT_DECLARE(id, s) s(_STRUCT_DECLARE, id) + + #define _STRUCT_PARAM_(x, id, type) type x ##_## id , + #define _STRUCT_PARAM_END(x, id, type) type x ##_## id + #define _STRUCT_PARAM(x, id, type, isend) _STRUCT_PARAM_##isend(x, id, type) + #define STRUCT_PARAM(id, s) s(_STRUCT_PARAM, id) + + #define _STRUCT_PASS_(x, id, type) x ##_## id , + #define _STRUCT_PASS_END(x, id, type) x ##_## id + #define _STRUCT_PASS(x, id, type, END) _STRUCT_PASS_##END(x, id, type) + #define STRUCT_PASS(id, s) s(_STRUCT_PASS, id) + + #define _STRUCT_STORE_DST(_, it) it + #define _STRUCT_STORE_SRC(it, _) it + #define _CONCAT3_(a, b, c) a ## b ## c + #define _CONCAT3(a, b, c) _CONCAT3_(a, b, c) + #define _STRUCT_STORE(x, id, type, END) _CONCAT3(_STRUCT_STORE_DST x, _, id) = _CONCAT3(_STRUCT_STORE_SRC x, _, id); + #define STRUCT_STORE(from, to, s) s(_STRUCT_STORE, (from, to)) + + #define STRUCT(id, ...) +#else + #define STRUCT_DECLARE(id, type) type id; + #define STRUCT_PARAM(id, type) type id + #define STRUCT_PASS(id, type) id + #define STRUCT_STORE(from, to, s) to = from + #define _STRUCT_MEMBER(my, id, type, END) type id; + #define STRUCT(id, s) struct STRUCT_##id { s(_STRUCT_MEMBER, ) }; +#endif + +#endif diff --git a/qcsrc/lib/vector.qh b/qcsrc/lib/vector.qh new file mode 100644 index 000000000..d81a79571 --- /dev/null +++ b/qcsrc/lib/vector.qh @@ -0,0 +1,34 @@ +#ifndef VECTOR_H +#define VECTOR_H + +const vector eX = '1 0 0'; +const vector eY = '0 1 0'; +const vector eZ = '0 0 1'; + +vector randompos(vector m1, vector m2) +{ + vector v; + m2 = m2 - m1; + v_x = m2_x * random() + m1_x; + v_y = m2_y * random() + m1_y; + v_z = m2_z * random() + m1_z; + return v; +} + +float vlen2d(vector v) +{ + return sqrt(v.x * v.x + v.y * v.y); +} + +float vlen_maxnorm2d(vector v) +{ + return max(v.x, v.y, -v.x, -v.y); +} + +float vlen_minnorm2d(vector v) +{ + return min(max(v.x, -v.x), max(v.y, -v.y)); +} + + +#endif