📄 math.cpp
字号:
// Copyright (C) 1999-2005 Open Source Telecom Corporation.// // 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 the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.// // As a special exception, you may use this file as part of a free software// library without restriction. Specifically, if other files instantiate// templates or use macros or inline functions from this file, or you compile// this file and link it with other files to produce an executable, this// file does not by itself cause the resulting executable to be covered by// the GNU General Public License. This exception does not however// invalidate any other reasons why the executable file might be covered by// the GNU General Public License.//// This exception applies only to the code released under the name GNU// ccScript. If you copy code from other releases into a copy of GNU// ccScript, as the General Public License permits, the exception does// not apply to the code that you add in this way. To avoid misleading// anyone as to the status of such modified files, you must delete// this exception notice from them.//// If you write modifications of your own for GNU ccScript, it is your choice// whether to permit this exception to apply to your modifications.// If you do not wish that, delete this exception notice.//#include "script3.h"#include <cmath>#ifndef M_PI#define M_PI 3.14159265358979323846#endifnamespace ccscript3Extension {using namespace std;using namespace ost;class MathMethods : public ScriptMethods{public: bool scrRandom(void); bool scrSeed(void);};class MathChecks : public ScriptChecks{public: const char *chkRandom(Line *line, ScriptImage *img); const char *chkSeed(Line *line, ScriptImage *img);};class MathRuntime : public ScriptBinder{public: MathRuntime();};static Script::Define runtime[] = { {"seed", false, (Script::Method)&MathMethods::scrSeed, (Script::Check)&MathChecks::chkSeed}, {"random", false, (Script::Method)&MathMethods::scrRandom, (Script::Check)&MathChecks::chkRandom}, {NULL, false, NULL, NULL}}; static long fRandom(long *values, unsigned prec) {return (long)(((double)(*values)) * (rand()/(RAND_MAX + 0.)));};static long fSine(long *values, unsigned prec) {return (long)(sin(values[0] * M_PI / values[1]) * values[1]);}static long fCosine(long *values, unsigned prec) {return (long)(cos(values[0] * M_PI / values[1]) * values[1]);}static long fTangent(long *values, unsigned prec) {return (long)(tan(values[0] * M_PI / values[1]) * values[1]);}; static long fArcTangent(long *values, unsigned prec) {return (long)(atan(values[0] * M_PI / values[1]) * values[1]);}; static long fPi(long *values, unsigned prec){ char pi[10]; strcpy(pi, "3141592653"); pi[prec + 1] = 0; return atol(pi);}static long fAbs(long *values, unsigned prec){ if(*values < 0) return -*values; else return *values;}static long fMin(long *values, unsigned prec){ if(values[0] < values[1]) return values[0]; return values[1];}static long fMax(long *values, unsigned prec){ if(values[0] > values[1]) return values[0]; return values[1];}static long fLimit(long *values, unsigned prec){ if(values[0] < values[1]) return values[1]; if(values[0] > values[2]) return values[2]; return values[0];}static long fRound(long *values, unsigned prec){ if(!values[1]) return values[0]; return (values[0] / values[1]) * values[1];}static long fSqrt(long *values, unsigned prec){ double sq = sqrt(ScriptMethods::getDouble(*values, prec)); return ScriptMethods::getRealValue(sq, prec);}static long fInt(long *values, unsigned prec){ return ScriptMethods::getInteger(*values, prec) * ScriptMethods::getTens(prec);}static MathRuntime math;MathRuntime::MathRuntime() : ScriptBinder(){ addFunction("abs", 1, &fAbs); addFunction("pi", 0, &fPi); addFunction("min", 2, &fMin); addFunction("max", 2, &fMax); addFunction("round", 2, &fRound); addFunction("limit", 3, &fLimit); addFunction("int", 1, &fInt); addFunction("sqrt", 1, &fSqrt); addFunction("sine", 2, &fSine); addFunction("cosine", 2, &fCosine); addFunction("tangent", 2, &fTangent); addFunction("arctangent", 2, &fArcTangent); addFunction("random", 1, &fRandom); bind(runtime);}const char *MathChecks::chkRandom(Line *line, ScriptImage *img){ const char *cp = getMember(line); if(cp) { if(atoi(++cp) < 1) return "random member must be integer range"; } else if(!findKeyword(line, "range")) return "random requires range keyword or member"; if(!useKeywords(line, "=range=seed=offset=min=max=reroll=count")) return "unknown or invalid keyword used"; return chkAllVars(line, img);}const char *MathChecks::chkSeed(Line *line, ScriptImage *img){ if(getMember(line)) return "seed does not use members"; if(line->argc > 1) return "invalid number of arguments for seed"; return NULL;}bool MathMethods::scrSeed(void){ const char *cp = getValue(NULL); char buf[12]; time_t now; if(!cp) { snprintf(buf, sizeof(buf), "%ld", time(&now)); cp = buf; } srand(atoi(cp)); skip(); return true;}bool MathMethods::scrRandom(void){ const char *cp = getMember(); unsigned range = 0, count = 1, roll; int val, offset = 0, min = 1, max = 0, reroll = 0; Symbol *sym; const char *errmsg = NULL; char buf[12]; if(cp) range = atoi(cp); cp = getKeyword("range"); if(cp) range = atoi(cp); if(!range) { error("random-range-invalid"); return true; } cp = getKeyword("count"); if(cp) count = atoi(cp); cp = getKeyword("seed"); if(cp) srand(atoi(cp)); cp = getKeyword("offset"); if(cp) offset = atoi(cp); cp = getKeyword("min"); if(cp) min = atoi(cp); cp = getKeyword("max"); if(cp) max = atoi(cp); cp = getKeyword("reroll"); if(cp) reroll = atoi(cp); while(NULL != (cp = getOption(NULL))) { sym = mapSymbol(cp, 11); if(!sym) { errmsg = "symbol-invalid"; continue; } if(sym->type == symINITIAL) sym->type = symNUMBER;retry: val = offset; roll = count; while(roll--) val += 1 + (int)(((double)(range)) * rand()/(RAND_MAX + 1.0)); if(val < min) val = min; if(val <= reroll) goto retry; if(val > max && max) val = max; snprintf(buf, sizeof(buf), "%d", val); commit(sym, buf); } if(errmsg) error(errmsg); else skip(); return true;}};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -