1
0
forked from 0ad/0ad

# Added Perlin Noise functions to random map generator.

This was SVN commit r4654.
This commit is contained in:
Matei 2006-11-25 18:32:10 +00:00
parent c92fc57a50
commit dd4d63cb68
11 changed files with 1120 additions and 129 deletions

View File

@ -0,0 +1,43 @@
#ifndef MATH_UTIL_H
#define MATH_UTIL_H
#ifndef PI
#define PI 3.14159265358979323846f
#endif
#define DEGTORAD(a) ((a) * (PI/180.0f))
#define RADTODEG(a) ((a) * (180.0f/PI))
#define SQR(x) ((x) * (x))
template <typename T>
T Interpolate(T& a, T& b, float l)
{
return a + (b - a) * l;
}
template <typename T>
inline T clamp(T value, T min, T max)
{
if (value <= min) return min;
else if (value >= max) return max;
else return value;
}
static inline int RoundUpToPowerOf2(int x)
{
if ((x & (x-1)) == 0)
return x;
int d = x;
while (d & (d-1))
d &= (d-1);
return d << 1;
}
inline float sgn(float a)
{
if (a > 0.0f) return 1.0f;
if (a < 0.0f) return -1.0f;
return 0.0f;
}
#endif

View File

@ -0,0 +1,99 @@
//***********************************************************
//
// Name: Vector2D.h
// Author: Matei Zaharia
//
// Description: Provides an interface for a vector in R4 and
// allows vector and scalar operations on it
//
//***********************************************************
#ifndef VECTOR2D_H
#define VECTOR2D_H
#include <math.h>
///////////////////////////////////////////////////////////////////////////////
// CVector2D_Maths:
class CVector2D_Maths
{
public:
CVector2D_Maths() {}
CVector2D_Maths(float x,float y) { X=x; Y=y; }
CVector2D_Maths(const CVector2D_Maths& p) { X=p.X; Y=p.Y; }
operator float*() {
return &X;
}
operator const float*() const {
return &X;
}
CVector2D_Maths operator-() const {
return CVector2D_Maths(-X, -Y);
}
CVector2D_Maths operator+(const CVector2D_Maths& t) const {
return CVector2D_Maths(X+t.X, Y+t.Y);
}
CVector2D_Maths operator-(const CVector2D_Maths& t) const {
return CVector2D_Maths(X-t.X, Y-t.Y);
}
CVector2D_Maths operator*(float f) const {
return CVector2D_Maths(X*f, Y*f);
}
CVector2D_Maths operator/(float f) const {
float inv=1.0f/f;
return CVector2D_Maths(X*inv, Y*inv);
}
CVector2D_Maths& operator+=(const CVector2D_Maths& t) {
X+=t.X; Y+=t.Y;
return *this;
}
CVector2D_Maths& operator-=(const CVector2D_Maths& t) {
X-=t.X; Y-=t.Y;
return *this;
}
CVector2D_Maths& operator*=(float f) {
X*=f; Y*=f;
return *this;
}
CVector2D_Maths& operator/=(float f) {
float invf=1.0f/f;
X*=invf; Y*=invf;
return *this;
}
float Dot(const CVector2D_Maths& a) const {
return X*a.X + Y*a.Y;
}
float LengthSquared() const {
return Dot(*this);
}
float Length() const {
return (float) sqrt(LengthSquared());
}
void Normalize() {
float mag=Length();
X/=mag; Y/=mag;
}
public:
float X, Y;
};
//////////////////////////////////////////////////////////////////////////////////
#endif

View File

@ -0,0 +1,138 @@
//***********************************************************
//
// Name: Vector3D.Cpp
// Last Update: 28/1/02
// Author: Poya Manouchehri
//
// Description: Provides an interface for a vector in R3 and
// allows vector and scalar operations on it
//
//***********************************************************
#include "stdafx.h"
#include "Vector3D.h"
#include <math.h>
#include "MathUtil.h"
int CVector3D::operator ! () const
{
if (X != 0.0f ||
Y != 0.0f ||
Z != 0.0f)
return 0;
return 1;
}
bool CVector3D::operator== (const CVector3D &vector) const
{
return (X == vector.X && Y == vector.Y && Z == vector.Z);
}
//vector addition
CVector3D CVector3D::operator + (const CVector3D &vector) const
{
return CVector3D(X+vector.X, Y+vector.Y, Z+vector.Z);
}
//vector addition/assignment
CVector3D &CVector3D::operator += (const CVector3D &vector)
{
X += vector.X;
Y += vector.Y;
Z += vector.Z;
return *this;
}
//vector subtraction
CVector3D CVector3D::operator - (const CVector3D &vector) const
{
return CVector3D(X-vector.X, Y-vector.Y, Z-vector.Z);
}
//vector negation
CVector3D CVector3D::operator-() const
{
return CVector3D(-X, -Y, -Z);
}
//vector subtrcation/assignment
CVector3D &CVector3D::operator -= (const CVector3D &vector)
{
X -= vector.X;
Y -= vector.Y;
Z -= vector.Z;
return *this;
}
//scalar multiplication
CVector3D CVector3D::operator * (float value) const
{
return CVector3D(X*value, Y*value, Z*value);
}
//scalar multiplication/assignment
CVector3D& CVector3D::operator *= (float value)
{
X *= value;
Y *= value;
Z *= value;
return *this;
}
void CVector3D::Set (float x, float y, float z)
{
X = x;
Y = y;
Z = z;
}
void CVector3D::Clear ()
{
X = Y = Z = 0.0f;
}
//Dot product
float CVector3D::Dot (const CVector3D &vector) const
{
return ( X * vector.X +
Y * vector.Y +
Z * vector.Z );
}
//Cross product
CVector3D CVector3D::Cross (const CVector3D &vector) const
{
CVector3D Temp;
Temp.X = (Y * vector.Z) - (Z * vector.Y);
Temp.Y = (Z * vector.X) - (X * vector.Z);
Temp.Z = (X * vector.Y) - (Y * vector.X);
return Temp;
}
float CVector3D::LengthSquared () const
{
return ( SQR(X) + SQR(Y) + SQR(Z) );
}
float CVector3D::GetLength () const
{
return sqrtf ( LengthSquared() );
}
void CVector3D::Normalize ()
{
float scale = 1.0f/GetLength ();
X *= scale;
Y *= scale;
Z *= scale;
}

View File

@ -0,0 +1,69 @@
//***********************************************************
//
// Name: Vector3D.H
// Last Update: 28/1/02
// Author: Poya Manouchehri
//
// Description: Provides an interface for a vector in R3 and
// allows vector and scalar operations on it
//
//***********************************************************
#ifndef VECTOR3D_H
#define VECTOR3D_H
class CVector3D
{
public:
float X, Y, Z;
public:
CVector3D () : X(0.0f), Y(0.0f), Z(0.0f) {}
CVector3D (float x, float y, float z) : X(x), Y(y), Z(z) {}
int operator!() const;
float& operator[](int index) { return *((&X)+index); }
const float& operator[](int index) const { return *((&X)+index); }
//vector equality (testing float equality, so please be careful if necessary)
bool operator== (const CVector3D &vector) const;
bool operator!= (const CVector3D &vector) const { return !operator==(vector); }
//vector addition
CVector3D operator + (const CVector3D &vector) const ;
//vector addition/assignment
CVector3D &operator += (const CVector3D &vector);
//vector subtraction
CVector3D operator - (const CVector3D &vector) const ;
//vector subtraction/assignment
CVector3D &operator -= (const CVector3D &vector);
//scalar multiplication
CVector3D operator * (float value) const ;
//scalar multiplication/assignment
CVector3D& operator *= (float value);
// negation
CVector3D operator-() const;
public:
void Set (float x, float y, float z);
void Clear ();
//Dot product
float Dot (const CVector3D &vector) const;
//Cross product
CVector3D Cross (const CVector3D &vector) const;
//Returns length of the vector
float GetLength () const;
float LengthSquared () const;
void Normalize ();
// Returns 3 element array of floats, e.g. for glVertex3fv
const float* GetFloatArray() const { return &X; }
};
#endif

View File

@ -51,11 +51,11 @@ Map::Map(int size, Terrain* baseTerrain, float baseHeight) {
Map::Map(string fileName, int loadLevel)
{
const LOAD_NOTHING = 0;
const LOAD_TERRAIN = 1<<0;
const LOAD_INTERACTIVES = 1 << 1;
const LOAD_NONINTERACTIVES = 1 << 2;
//const SOMETHINGELSE = 1 << 3;
const int LOAD_NOTHING = 0;
const int LOAD_TERRAIN = 1<<0;
const int LOAD_INTERACTIVES = 1 << 1;
const int LOAD_NONINTERACTIVES = 1 << 2;
//const int SOMETHINGELSE = 1 << 3;
// HACK, this should probably be in a struct and be shared with the code in output.cpp

View File

@ -58,8 +58,8 @@ void OutputXml(Map* m, FILE* f) {
<SunColour r=\"1\" g=\"1\" b=\"1\" />\n\
<SunElevation angle=\"0.785398\" />\n\
<SunRotation angle=\"4.712389\" />\n\
<TerrainAmbientColour r=\"0\" g=\"0\" b=\"0\" />\n\
<UnitsAmbientColour r=\"0.4\" g=\"0.4\" b=\"0.4\" />\n\
<TerrainAmbientColour r=\"0.5\" g=\"0.5\" b=\"0.5\" />\n\
<UnitsAmbientColour r=\"0.52\" g=\"0.52\" b=\"0.52\" />\n\
</Environment>\n\
<Entities>\n";
OutputObjects(xml, m, true); // print entities

View File

@ -3,9 +3,12 @@
#include "map.h"
#include "output.h"
#include "api.h"
#include "scripting.h"
#include "random.h"
#include "noise.h"
using namespace std;
using namespace js;
JSRuntime *rt = 0;
JSContext *cx = 0;
@ -15,6 +18,20 @@ Map* theMap = 0;
// JS support functions
template<typename T> JSClass Class<T>::jsClass = {
"T", JSCLASS_HAS_PRIVATE,
JS_PropertyStub, JS_PropertyStub, Class<T>::getProperty, Class<T>::setProperty,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
// Note: the finalize stub should really be replaced by some function which
// deletes the object if it must be deleted; this requires that we use some
// kind of smart handles instead of just pointers though, so we don't delete
// objects that we actually want C++ to use (which is most objects)
};
template<typename T> JSNative Class<T>::constructor;
template<typename T> vector<JSFunctionSpec> Class<T>::methodSpecs;
template<typename T> vector<JSPropertySpec> Class<T>::propertySpecs;
template<typename T> vector<AbstractProperty*> Class<T>::properties;
void ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report) {
string path = string(report->filename);
int lastSlash = -1;
@ -45,6 +62,9 @@ void InitJS() {
JS_InitStandardClasses(cx, global);
JS_DefineFunctions(cx, global, globalFunctions);
Class<Noise2D>::addMethod(Method<Noise2D, float, float, float, &Noise2D::operator()>, 2, "eval");
Class<Noise2D>::init("Noise2D", Constructor<Noise2D, float>);
}
void Shutdown(int status) {

View File

@ -1,21 +1,19 @@
Microsoft Visual Studio Solution File, Format Version 8.00
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rmgen", "rmgen.vcproj", "{ED804376-98E9-4732-A1E9-717D5C6773FA}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
Release = Release
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{ED804376-98E9-4732-A1E9-717D5C6773FA}.Debug.ActiveCfg = Debug|Win32
{ED804376-98E9-4732-A1E9-717D5C6773FA}.Debug.Build.0 = Debug|Win32
{ED804376-98E9-4732-A1E9-717D5C6773FA}.Release.ActiveCfg = Release|Win32
{ED804376-98E9-4732-A1E9-717D5C6773FA}.Release.Build.0 = Release|Win32
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{ED804376-98E9-4732-A1E9-717D5C6773FA}.Debug|Win32.ActiveCfg = Debug|Win32
{ED804376-98E9-4732-A1E9-717D5C6773FA}.Debug|Win32.Build.0 = Debug|Win32
{ED804376-98E9-4732-A1E9-717D5C6773FA}.Release|Win32.ActiveCfg = Release|Win32
{ED804376-98E9-4732-A1E9-717D5C6773FA}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
GlobalSection(ExtensibilityAddIns) = postSolution
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -1,110 +1,174 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Version="8.00"
Name="rmgen"
ProjectGUID="{ED804376-98E9-4732-A1E9-717D5C6773FA}"
Keyword="Win32Proj">
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"/>
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../../binaries/system"
IntermediateDirectory="Debug"
ConfigurationType="1"
CharacterSet="2">
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../libraries/boost/include;../../../libraries/spidermonkey/include"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="TRUE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="3"
UsePrecompiledHeader="2"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCCustomBuildTool"/>
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/rmgen_dbg.exe"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
GenerateDebugInformation="true"
ProgramDatabaseFile="$(OutDir)/rmgen.pdb"
SubSystem="1"
TargetMachine="1"/>
TargetMachine="1"
/>
<Tool
Name="VCMIDLTool"/>
Name="VCALinkTool"
/>
<Tool
Name="VCPostBuildEventTool"/>
Name="VCManifestTool"
/>
<Tool
Name="VCPreBuildEventTool"/>
Name="VCXDCMakeTool"
/>
<Tool
Name="VCPreLinkEventTool"/>
Name="VCBscMakeTool"
/>
<Tool
Name="VCResourceCompilerTool"/>
Name="VCFxCopTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
Name="VCAppVerifierTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"/>
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../../binaries/system"
IntermediateDirectory="Release"
ConfigurationType="1"
CharacterSet="2">
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../libraries/boost/include;../../../libraries/spidermonkey/include"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="3"
UsePrecompiledHeader="3"
UsePrecompiledHeader="2"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCCustomBuildTool"/>
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/rmgen.exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
TargetMachine="1"
/>
<Tool
Name="VCMIDLTool"/>
Name="VCALinkTool"
/>
<Tool
Name="VCPostBuildEventTool"/>
Name="VCManifestTool"
/>
<Tool
Name="VCPreBuildEventTool"/>
Name="VCXDCMakeTool"
/>
<Tool
Name="VCPreLinkEventTool"/>
Name="VCBscMakeTool"
/>
<Tool
Name="VCResourceCompilerTool"/>
Name="VCFxCopTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
Name="VCAppVerifierTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"/>
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
@ -113,203 +177,296 @@
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\api.cpp">
RelativePath=".\api.cpp"
>
</File>
<File
RelativePath=".\area.cpp">
RelativePath=".\area.cpp"
>
</File>
<File
RelativePath=".\areapainter.cpp">
RelativePath=".\areapainter.cpp"
>
</File>
<File
RelativePath=".\areaplacer.cpp">
RelativePath=".\areaplacer.cpp"
>
</File>
<File
RelativePath=".\clumpplacer.cpp">
RelativePath=".\clumpplacer.cpp"
>
</File>
<File
RelativePath=".\constraint.cpp">
RelativePath=".\constraint.cpp"
>
</File>
<File
RelativePath=".\convert.cpp">
RelativePath=".\convert.cpp"
>
</File>
<File
RelativePath=".\layeredpainter.cpp">
RelativePath=".\layeredpainter.cpp"
>
</File>
<File
RelativePath=".\map.cpp">
RelativePath=".\map.cpp"
>
</File>
<File
RelativePath=".\object.cpp">
RelativePath=".\MathUtil.h"
>
</File>
<File
RelativePath=".\objectgroupplacer.cpp">
RelativePath=".\noise.cpp"
>
</File>
<File
RelativePath=".\output.cpp">
RelativePath=".\object.cpp"
>
</File>
<File
RelativePath=".\point.cpp">
RelativePath=".\objectgroupplacer.cpp"
>
</File>
<File
RelativePath=".\random.cpp">
RelativePath=".\output.cpp"
>
</File>
<File
RelativePath=".\rangeop.cpp">
RelativePath=".\point.cpp"
>
</File>
<File
RelativePath=".\rectplacer.cpp">
RelativePath=".\random.cpp"
>
</File>
<File
RelativePath=".\rmgen.cpp">
RelativePath=".\rangeop.cpp"
>
</File>
<File
RelativePath=".\simpleconstraints.cpp">
RelativePath=".\rectplacer.cpp"
>
</File>
<File
RelativePath=".\simplegroup.cpp">
RelativePath=".\rmgen.cpp"
>
</File>
<File
RelativePath=".\simplepainters.cpp">
RelativePath=".\simpleconstraints.cpp"
>
</File>
<File
RelativePath=".\smoothelevationpainter.cpp">
RelativePath=".\simplegroup.cpp"
>
</File>
<File
RelativePath=".\stdafx.cpp">
RelativePath=".\simplepainters.cpp"
>
</File>
<File
RelativePath=".\smoothelevationpainter.cpp"
>
</File>
<File
RelativePath=".\stdafx.cpp"
>
<FileConfiguration
Name="Debug|Win32">
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"/>
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"/>
UsePrecompiledHeader="1"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\terrain.cpp">
RelativePath=".\terrain.cpp"
>
</File>
<File
RelativePath=".\tileclass.cpp">
RelativePath=".\tileclass.cpp"
>
</File>
<File
RelativePath=".\Vector2D.h"
>
</File>
<File
RelativePath=".\Vector3D.cpp"
>
</File>
<File
RelativePath=".\Vector3D.h"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\api.h">
RelativePath=".\api.h"
>
</File>
<File
RelativePath=".\area.h">
RelativePath=".\area.h"
>
</File>
<File
RelativePath=".\areapainter.h">
RelativePath=".\areapainter.h"
>
</File>
<File
RelativePath=".\areaplacer.h">
RelativePath=".\areaplacer.h"
>
</File>
<File
RelativePath=".\clumpplacer.h">
RelativePath=".\clumpplacer.h"
>
</File>
<File
RelativePath=".\constraint.h">
RelativePath=".\constraint.h"
>
</File>
<File
RelativePath=".\convert.h">
RelativePath=".\convert.h"
>
</File>
<File
RelativePath=".\layeredpainter.h">
RelativePath=".\layeredpainter.h"
>
</File>
<File
RelativePath=".\map.h">
RelativePath=".\map.h"
>
</File>
<File
RelativePath=".\object.h">
RelativePath=".\noise.h"
>
</File>
<File
RelativePath=".\objectgroupplacer.h">
RelativePath=".\object.h"
>
</File>
<File
RelativePath=".\output.h">
RelativePath=".\objectgroupplacer.h"
>
</File>
<File
RelativePath=".\pmp_file.h">
RelativePath=".\output.h"
>
</File>
<File
RelativePath=".\point.h">
RelativePath=".\pmp_file.h"
>
</File>
<File
RelativePath=".\pointmap.h">
RelativePath=".\point.h"
>
</File>
<File
RelativePath=".\random.h">
RelativePath=".\pointmap.h"
>
</File>
<File
RelativePath=".\rangeop.h">
RelativePath=".\random.h"
>
</File>
<File
RelativePath=".\rectplacer.h">
RelativePath=".\rangeop.h"
>
</File>
<File
RelativePath=".\rmgen.h">
RelativePath=".\rectplacer.h"
>
</File>
<File
RelativePath=".\simpleconstraints.h">
RelativePath=".\rmgen.h"
>
</File>
<File
RelativePath=".\simplegroup.h">
RelativePath=".\scripting.h"
>
</File>
<File
RelativePath=".\simplepainters.h">
RelativePath=".\simpleconstraints.h"
>
</File>
<File
RelativePath=".\smoothelevationpainter.h">
RelativePath=".\simplegroup.h"
>
</File>
<File
RelativePath=".\stdafx.h">
RelativePath=".\simplepainters.h"
>
</File>
<File
RelativePath=".\terrain.h">
RelativePath=".\smoothelevationpainter.h"
>
</File>
<File
RelativePath=".\tileclass.h">
RelativePath=".\stdafx.h"
>
</File>
<File
RelativePath=".\terrain.h"
>
</File>
<File
RelativePath=".\tileclass.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
<File
RelativePath="..\..\..\binaries\data\mods\official\maps\random\andalucia.js">
RelativePath="..\..\..\binaries\data\mods\official\maps\random\andalucia.js"
>
</File>
<File
RelativePath="..\..\..\binaries\data\mods\official\maps\random\cantabrian_highlands.js">
RelativePath="..\..\..\binaries\data\mods\official\maps\random\cantabrian_highlands.js"
>
</File>
<File
RelativePath="..\..\..\libraries\spidermonkey\lib\js32d.lib">
RelativePath="..\..\..\libraries\spidermonkey\lib\js32d.lib"
>
</File>
<File
RelativePath="..\..\..\binaries\data\mods\official\maps\random\neareastern_badlands.js">
RelativePath="..\..\..\binaries\data\mods\official\maps\random\neareastern_badlands.js"
>
</File>
<File
RelativePath=".\ReadMe.txt">
RelativePath=".\ReadMe.txt"
>
</File>
<File
RelativePath="..\..\..\binaries\data\mods\official\maps\rmlibrary.js">
RelativePath="..\..\..\binaries\data\mods\official\maps\rmlibrary.js"
>
</File>
<File
RelativePath="..\..\..\binaries\data\mods\official\maps\random\test.js">
RelativePath="..\..\..\binaries\data\mods\official\maps\random\test.js"
>
</File>
<File
RelativePath="..\..\..\binaries\data\mods\official\maps\random\test2.js">
RelativePath="..\..\..\binaries\data\mods\official\maps\random\test2.js"
>
</File>
</Files>
<Globals>

View File

@ -0,0 +1,467 @@
#ifndef SCRIPTING_H
#define SCRIPTING_H
#define XP_WIN
#include <js/jsapi.h>
#include <string>
#include <vector>
#include <iostream>
#include <cstdlib>
extern JSContext* cx;
extern JSObject* global;
// Initialize scripting, declaring all our JS classes and functions
void ScriptingInit();
// Run a script
void RunScript(const std::string& filename);
// Shortcut for reporting a nice error to the user if an assertion fails
#define jsASSERT(expr) if(!(expr)) { JS_ReportError(cx, \
"Assertion failed in %s (%s:%d): " #expr, __FUNCTION__, __FILE__, __LINE__); return JS_FALSE; }
// A namespace containing utility functions used internally by the scripting API
namespace js {
// An interface to a property object (we'll have a subclass below once we have
// the conversion functions, but this is needed for Class which is needed for
// some of the conversion functions)
class AbstractProperty {
public:
virtual ~AbstractProperty() {};
virtual JSBool set(JSObject *obj, jsval *val) = 0;
virtual JSBool get(JSObject *obj, jsval *rval) = 0;
};
// An easy way to wrap an entire class into JavaScript; just call add on
// the methods and properties, then call Class<T>::init.
template<typename T> class Class
{
public:
static JSClass jsClass;
private:
static JSNative constructor;
static std::vector<JSFunctionSpec> methodSpecs;
static std::vector<JSPropertySpec> propertySpecs;
static std::vector<AbstractProperty*> properties;
public:
static void addMethod(JSNative func, int numArgs, const char* name) {
JSFunctionSpec spec = { name, func, numArgs, 0, 0 };
methodSpecs.push_back(spec);
}
static void addProperty(AbstractProperty* (*propGen)(), const char* name) {
AbstractProperty* prop = propGen();
int index = properties.size();
properties.push_back(prop);
JSPropertySpec spec = { name, index, JSPROP_ENUMERATE };
propertySpecs.push_back(spec);
}
private:
static JSBool getProperty(JSContext*, JSObject *obj, jsval id, jsval *vp) {
if(!JSVAL_IS_INT(id)) {
if(strcmp(JS_GetStringBytes(JSVAL_TO_STRING(id)), "constructor")==0) {
// For some reason this is called for the constructor
*vp = JSVAL_NULL; return JS_TRUE;
}
else {
return JS_TRUE;
}
};
int index = JSVAL_TO_INT(id);
properties[index]->get(obj, vp);
return JS_TRUE;
}
static JSBool setProperty(JSContext*, JSObject *obj, jsval id, jsval *vp) {
if(!JSVAL_IS_INT(id)) return JS_TRUE;
int index = JSVAL_TO_INT(id);
properties[index]->set(obj, vp);
return JS_TRUE;
}
public:
static void init(const char* name, JSNative cons) {
constructor = cons;
JSFunctionSpec* methods = new JSFunctionSpec[methodSpecs.size() + 1];
for(size_t i=0; i<methodSpecs.size(); i++) {
methods[i] = methodSpecs[i];
}
JSFunctionSpec endMethod = { 0 };
methods[methodSpecs.size()] = endMethod;
JSPropertySpec* props = new JSPropertySpec[propertySpecs.size() + 1];
for(size_t i=0; i<propertySpecs.size(); i++) {
props[i] = propertySpecs[i];
}
JSPropertySpec endProp = { 0 };
props[propertySpecs.size()] = endProp;
jsClass.name = name;
jsClass.construct = cons;
JS_InitClass(cx, global, 0, &jsClass, constructor, 0,
props, methods, 0, 0);
}
};
template<typename T> struct PointerClass {
typedef int type;
};
template<typename T> struct PointerClass<T*> {
typedef Class<T> type;
};
// Conversion functions from types to Javascript
template<typename T> jsval ToJsval(T v) { // T is really a pointer here (since we want to do ToJsval(pointer))
if(v == 0) {
return JSVAL_NULL;
}
else {
JSObject* obj = JS_NewObject(cx, &(PointerClass<T>::type::jsClass), 0, 0);
JS_SetPrivate(cx, obj, v);
return OBJECT_TO_JSVAL(obj);
}
}
template<> inline jsval ToJsval<bool>(bool v) {
return v ? JSVAL_TRUE : JSVAL_FALSE;
}
template<> inline jsval ToJsval<int>(int v) {
return INT_TO_JSVAL(v);
}
template<> inline jsval ToJsval<double>(double v) {
jsval ret;
JS_NewDoubleValue(cx, v, &ret);
return ret;
}
template<> inline jsval ToJsval<float>(float v) {
jsval ret;
JS_NewDoubleValue(cx, v, &ret);
return ret;
}
template<> inline jsval ToJsval<const char*>(const char* v) {
int length = strlen(v);
char* buf = (char*) JS_malloc(cx, length+1);
memcpy(buf, v, length+1);
return STRING_TO_JSVAL(JS_NewString(cx, buf, length+1));
}
template<> inline jsval ToJsval<const std::string&>(const std::string& v) {
return ToJsval(v.c_str());
}
template<> inline jsval ToJsval<JSFunction*>(JSFunction* v) {
if(v == 0) return JSVAL_NULL;
else return OBJECT_TO_JSVAL(JS_GetFunctionObject(v));
}
// Conversion functions from Javascript to types
template<typename T> T To(jsval v) { // T is really a pointer here (since we want to do To<pointer>(jsval))
if(v == JSVAL_NULL) {
return 0;
}
else {
JSObject* obj = JSVAL_TO_OBJECT(v);
return (T) JS_GetPrivate(cx, obj);
}
}
template<> inline bool To<bool>(jsval v) {
return (v==JSVAL_TRUE);
}
template<> inline int To<int>(jsval v) {
return JSVAL_TO_INT(v);
}
template<> inline double To<double>(jsval v) {
jsdouble d;
JS_ValueToNumber(cx, v, &d);
return d;
}
template<> inline float To<float>(jsval v) {
jsdouble d;
JS_ValueToNumber(cx, v, &d);
return (float) d;
}
template<> inline std::string To<std::string>(jsval v) {
return std::string(JS_GetStringBytes(JS_ValueToString(cx, v)));
}
template<> inline JSFunction* To<JSFunction*>(jsval v) {
if(v == JSVAL_NULL) return 0;
return JS_ValueToFunction(cx, v);
}
// A nice way of automatically creating a JS function for any
// function or method; could be made shorter by using some kind of
// preprocessor loop (boost), but that might get confusing.
// Combining member function pointers and templates... fun.
// Functions with return type R and up to three arguments A, B, C
template<typename R, R (*func)()>
JSBool Function
(JSContext *cx, JSObject*, uintN argc, jsval *argv, jsval *rval)
{
jsASSERT(argc==0);
*rval = ToJsval(func());
return JS_TRUE;
}
template<typename R, typename A, R (*func)(A)>
JSBool Function
(JSContext *cx, JSObject*, uintN argc, jsval *argv, jsval *rval)
{
jsASSERT(argc==1);
*rval = ToJsval(func(To<A>(argv[0])));
return JS_TRUE;
}
template<typename R, typename A, typename B, R (*func)(A,B)>
JSBool Function(JSContext *cx, JSObject*, uintN argc, jsval *argv, jsval *rval)
{
jsASSERT(argc==2);
*rval = ToJsval(func(To<A>(argv[0]), To<B>(argv[1])));
return JS_TRUE;
}
template<typename R, typename A, typename B, typename C, R (*func)(A,B,C)>
JSBool Function(JSContext *cx, JSObject*, uintN argc, jsval *argv, jsval *rval)
{
jsASSERT(argc==3);
*rval = ToJsval(func(To<A>(argv[0]), To<B>(argv[1]), To<C>(argv[2])));
return JS_TRUE;
}
// Void functions with up to three arguments A, B, C
template<void (*func)()>
JSBool VoidFunction
(JSContext *cx, JSObject*, uintN argc, jsval *argv, jsval *rval)
{
jsASSERT(argc==1);
func();
*rval = JSVAL_VOID;
return JS_TRUE;
}
template<typename A, void (*func)(A)>
JSBool VoidFunction
(JSContext *cx, JSObject*, uintN argc, jsval *argv, jsval *rval)
{
jsASSERT(argc==1);
func(To<A>(argv[0]));
*rval = JSVAL_VOID;
return JS_TRUE;
}
template<typename A, typename B, void (*func)(A,B)>
JSBool VoidFunction
(JSContext *cx, JSObject*, uintN argc, jsval *argv, jsval *rval)
{
jsASSERT(argc==2);
func(To<A>(argv[0]), To<B>(argv[1]));
*rval = JSVAL_VOID;
return JS_TRUE;
}
template<typename A, typename B, typename C, void (*func)(A,B,C)>
JSBool VoidFunction
(JSContext *cx, JSObject*, uintN argc, jsval *argv, jsval *rval)
{
jsASSERT(argc==3);
func(To<A>(argv[0]), To<B>(argv[1]), To<C>(argv[2]));
*rval = JSVAL_VOID;
return JS_TRUE;
}
// Methods of O with return type R and up to three arguments A, B, C
template<typename O, typename R, R (O::*func)()>
JSBool Method
(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsASSERT(argc==0);
O* o = (O*) JS_GetPrivate(cx, obj);
*rval = ToJsval((o->*func)());
return JS_TRUE;
}
template<typename O, typename R, typename A, R (O::*func)(A)>
JSBool Method
(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsASSERT(argc==1);
O* o = (O*) JS_GetPrivate(cx, obj);
*rval = ToJsval((o->*func)(To<A>(argv[0])));
return JS_TRUE;
}
template<typename O, typename R, typename A, typename B, R (O::*func)(A,B)>
JSBool Method
(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsASSERT(argc==2);
O* o = (O*) JS_GetPrivate(cx, obj);
*rval = ToJsval((o->*func)(To<A>(argv[0]), To<B>(argv[1])));
return JS_TRUE;
}
template<typename O, typename R, typename A, typename B, typename C, R (O::*func)(A,B,C)>
JSBool Method
(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsASSERT(argc==3);
O* o = (O*) JS_GetPrivate(cx, obj);
*rval = ToJsval((o->*func)(To<A>(argv[0]), To<B>(argv[1]), To<C>(argv[2])));
return JS_TRUE;
}
// Void methods of O with up to three arguments A, B, C
template<typename O, void (O::*func)()>
JSBool VoidMethod
(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsASSERT(argc==0);
O* o = (O*) JS_GetPrivate(cx, obj);
(o->*func)();
*rval = JSVAL_VOID;
return JS_TRUE;
}
template<typename O, typename A, void (O::*func)(A)>
JSBool VoidMethod
(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsASSERT(argc==1);
O* o = (O*) JS_GetPrivate(cx, obj);
(o->*func)(To<A>(argv[0]));
*rval = JSVAL_VOID;
return JS_TRUE;
}
template<typename O, typename A, typename B, void (O::*func)(A,B)>
JSBool VoidMethod
(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsASSERT(argc==2);
O* o = (O*) JS_GetPrivate(cx, obj);
(o->*func)(To<A>(argv[0]), To<B>(argv[1]));
*rval = JSVAL_VOID;
return JS_TRUE;
}
template<typename O, typename A, typename B, typename C, void (O::*func)(A,B,C)>
JSBool VoidMethod
(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsASSERT(argc==3);
O* o = (O*) JS_GetPrivate(cx, obj);
(o->*func)(To<A>(argv[0]), To<B>(argv[1]), To<C>(argv[2]));
*rval = JSVAL_VOID;
return JS_TRUE;
}
// Constructors of O with up to three arguments A, B, C
template<typename O>
JSBool Constructor
(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsASSERT(argc==0);
JS_SetPrivate(cx, obj, new O());
return JS_TRUE;
}
template<typename O, typename A>
JSBool Constructor
(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval*)
{
jsASSERT(argc==1);
JS_SetPrivate(cx, obj, new O(To<A>(argv[0])));
return JS_TRUE;
}
template<typename O, typename A, typename B>
JSBool Constructor
(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval*)
{
jsASSERT(argc==2);
JS_SetPrivate(cx, obj, new O(To<A>(argv[0]), To<B>(argv[1])));
return JS_TRUE;
}
template<typename O, typename A, typename B, typename C>
JSBool Constructor
(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval*)
{
jsASSERT(argc==3);
JS_SetPrivate(cx, obj, new O(To<A>(argv[0]), To<B>(argv[1]), To<C>(argv[2])));
return JS_TRUE;
}
template<typename O, typename A, typename B, typename C, typename D>
JSBool Constructor
(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval*)
{
jsASSERT(argc==4);
JS_SetPrivate(cx, obj, new O(
To<A>(argv[0]), To<B>(argv[1]), To<C>(argv[2]), To<D>(argv[3])));
return JS_TRUE;
}
// Implementation of AbstractProperty for a given field of an object
template<typename O, typename T, T O::*field> class PropertyImpl: public AbstractProperty {
public:
virtual ~PropertyImpl() {}
virtual JSBool set(JSObject *obj, jsval *val) {
O* o = (O*) JS_GetPrivate(cx, obj);
(o->*field) = To<T>(*val);
return JS_TRUE;
}
virtual JSBool get(JSObject *obj, jsval *rval) {
O* o = (O*) JS_GetPrivate(cx, obj);
*rval = ToJsval(o->*field);
return JS_TRUE;
}
};
// A nice function to pass to AddProperty so we don't have to type new PropertyImpl<blah>()
template<typename O, typename T, T O::*field> AbstractProperty* Property() {
return new PropertyImpl<O, T, field>();
}
}
// Call a void function with 1 argument
template<typename T> void CallJSFunction(JSFunction* f, T arg) {
if(f == 0) {
return;
}
jsval argv[1] = { js::ToJsval(arg) };
jsval rval;
JS_CallFunction(cx, global, f, 1, argv, &rval);
}
#endif

View File

@ -32,7 +32,7 @@
#else
#define XP_UNIX // TODO: Someone should actually test this on Linux
#endif
#include "jsapi.h"
#include <js/jsapi.h>
const float PI = acos(-1.0f);