Hacking Sphere
From Spheriki
This document covers the main files relating to Sphere's scripting, ss_functions.table, script.cpp and script.hpp. Any function/method or object you have in Sphere will be listed in these files.
Contents |
Hacking your own functions into Sphere
Step 1: Declare your function
Open source/engine/ss_functions.table. Add your function like so:
SS_FUNCTION(GetPersonMask, 1)
This declares a function "GetPersonMask" that has a minimum of 1 parameters.
Step 2: Add your function
Open source/engine/script.cpp and add your function:
/**
- sets a color multiplier to use when drawing sprites. if the color is
RGBA:(255, 0, 0, 255), only the red elements of the sprite are drawn.
If the color is RGBA:(255, 255, 255, 128), the sprite is drawn at
half transparency.
*/
begin_func(SetPersonMask, 2)
arg_str(name);
arg_color(mask);
if (!This->m_Engine->GetMapEngine()->SetPersonMask(name, mask)) {
This->ReportMapEngineError("SetPersonMask() failed");
return JS_FALSE;
}
end_func()
Hacking your own methods into Sphere
Step 1: Declare your method
Open source/engine/ss_functions.table. Add a comment for your method in the relevant place like so:
//sound.setPitch(pitch)
Then open source/engine/script.hpp and declare your method:
declare_method(ssSoundSetPitch);
Step 2: Add your method to the object's function spec
Open source/engine/script.cpp and add your method. Add your method to the function spec:
// assign methods to the object
static JSFunctionSpec fs[] = {
{ "play", ssSoundPlay, 1, },
{ "pause", ssSoundPause, 0, },
{ "stop", ssSoundStop, 0, },
{ "setVolume", ssSoundSetVolume, 1, },
{ "getVolume", ssSoundGetVolume, 0, },
{ "setPan", ssSoundSetPan, 1, },
{ "getPan", ssSoundGetPan, 0, },
{ "setPitch", ssSoundSetPitch, 1, }, // add this line, the 1 stands for 1 minimum parameter
{ "getPitch", ssSoundGetPitch, 0, },
{ "isPlaying", ssSoundIsPlaying, 0, },
{ "isSeekable", ssSoundIsSeekable, 0, },
{ "getPosition", ssSoundGetPosition, 0, },
{ "setPosition", ssSoundSetPosition, 1, },
{ "getLength", ssSoundGetLength, 0, },
{ "clone", ssSoundClone, 0, },
{ 0, 0, 0, 0, 0 },
};
JS_DefineFunctions(cx, object, fs);
Now add your method:
/**
- pitch ranges from 0.5 to 2.0. 0.5 is an octave down (and half as fast)
while 2.0 is an octave up (and twice as fast). pitch defaults to 1
*/
begin_method(SS_SOUND, ssSoundSetPitch, 1)
arg_double(pitch);
if (object->sound) object->sound->setPitchShift(pitch);
end_method()
Hacking your own objects into Sphere
Step 1: Declare your object
Open source/engine/ss_functions.table. Add a section for your object in the relevant place like so:
// debugging
SS_FUNCTION(OpenLog, 1)
//log.write(text)
//log.beginBlock(name)
//log.endBlock()
Step 2: Declare your object's constructor/finalizer
Open source/engine/script.hpp.
// logs declare_constructor1(CreateLogObject, CLog* log); declare_finalizer(ssFinalizeLog);
Step 3: Add the magic number for the object
Open source/engine/script.cpp. Add the following, but make sure the number is different for each object.
const dword SS_LOG_MAGIC = 0x435262c9;
Step 4: Add your object type
Open source/engine/script.cpp. Add the following, each line inside the begin and end blocks are the properties for the object.
BEGIN_SS_OBJECT(SS_LOG)
CLog* log;
END_SS_OBJECT()
Step 5: Add your object
Open source/engine/script.cpp.
////////////////////////////////////////
// LOG OBJECTS /////////////////////////
////////////////////////////////////////
JSObject*
CScript::CreateLogObject(JSContext* cx, CLog* log)
{
// define log class
static JSClass clasp = {
"log", JSCLASS_HAS_PRIVATE,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, ssFinalizeLog,
};
// create the object
JSObject* object = JS_NewObject(cx, &clasp, NULL, NULL);
if (object == NULL) {
return NULL;
}
// assign methods to the object
static JSFunctionSpec fs[] = {
{ "write", ssLogWrite, 2, 0, 0 },
{ "beginBlock", ssLogBeginBlock, 1, 0, 0 },
{ "endBlock", ssLogEndBlock, 0, 0, 0 },
{ 0, 0, 0, 0, 0 },
};
JS_DefineFunctions(cx, object, fs);
// attach the log to this object
SS_LOG* log_object = new SS_LOG;
if (!log_object)
return NULL;
log_object->log = log;
JS_SetPrivate(cx, object, log_object);
return object;
}
Step 6: Implement methods
You'd now have to implement OpenLog/log.write/log.beginBlock/log.endBlock
That's it. :) Flikky

