summaryrefslogblamecommitdiff
path: root/src/script-squirrel.cpp
blob: 7f7739b08a3ad7da79b4a5f488610001e3dc1133 (plain) (tree)
1
2
3
4
5
6
7
                            

                  

                     

                                 


















                                                   
                                                                       







                                                 
 

                                    
                                          
 
                         
         























                                                                     
         

                                    
     
                      
 
                      
                    
 
                

 




                                                                    
 




                               

 




                                                                   
 

                             
                                    
     







































                                        



                             

 





                                                         



                                   







                                                                       
                           
 

                                       
     

 
                                 

                                      


                  






                                     




                                                             




                                          























































































                                                      
      
#include "script-squirrel.h"
#include <cstring>

#ifdef SCRIPT_SUPPORT

void registerStdLib(HSQUIRRELVM);

/*
 * printfunc - Print function for Squirrel
 */
void printfunc(HSQUIRRELVM v, const SQChar *s, ...)
{
    va_list arglist;
    va_start(arglist, s);
    vprintf(s, arglist);
    va_end(arglist);
}

/*
 * functionCall - Call function with arguments
 * fn   - name of function
 * args - string with argument types.
 *        's' = String
 *        'i' = Integer
 *        'f' = Float
 */
bool functionCall(HSQUIRRELVM v, const char *fn, const char *args, ...)
{
    int argCount = 0;
    va_list arglist;
    va_start(arglist, args);

    int top = sq_gettop(v); //save stack
    sq_pushroottable(v);    //pushes global table
    sq_pushstring(v, _SC(fn), -1);

    if (SQ_SUCCEEDED(sq_get(v, -2)))
    {
        sq_pushroottable(v); //push 'this'

        if (args != NULL)
        {
            for (int i = 0; i < strlen(args); i++)
            {
                switch (args[i])
                {
                    case 'S':
                    case 's':
                        //string
                        argCount++;
                        sq_pushstring(v, va_arg(arglist, char*), -1);
                        break;
                    case 'I':
                    case 'i':
                        //integer
                        argCount++;
                        sq_pushinteger(v, va_arg(arglist, int));
                        break;
                    case 'F':
                    case 'f':
                        //float
                        argCount++;
                        sq_pushfloat(v, va_arg(arglist, float));
                        break;
                }
            }
        }

        sq_call(v, argCount + 1, 0);
    }
    else return false;

    sq_settop(v, top);
    va_end(arglist);

    return true;
}

/*
 * functionRegister
 * Registers a function in Squirrel VM
 */
void functionRegister(HSQUIRRELVM v, SQFUNCTION f, const char *name)
{
    sq_pushroottable(v);
    sq_pushstring(v, name, -1);
    sq_newclosure(v, f, 0);
    sq_createslot(v, -3);
    sq_pop(v, 1);
}

/*
 * Test function called from Squirrel (modified form Squirrel docs)
 * Prints the type of all arguments.
 */
int testFunc(HSQUIRRELVM v)
{
    int nargs = sq_gettop(v);

    for (int n = 1; n <= nargs; n++)
    {
        printf("arg: %d is ", n);

        switch (sq_gettype(v, n))
        {
            case OT_NULL:
                printf("null");
                break;
            case OT_INTEGER:
                printf("integer");
                break;
            case OT_FLOAT:
                printf("float");
                break;
            case OT_STRING:
                printf("string");
                break;
            case OT_TABLE:
                printf("table");
                break;
            case OT_ARRAY:
                printf("array");
                break;
            case OT_USERDATA:
                printf("userdata");
                break;
            case OT_CLOSURE:
                printf("closure");
                break;
            case OT_NATIVECLOSURE:
                printf("nativeclosure");
                break;
            case OT_GENERATOR:
                printf("generator");
                break;
            case OT_USERPOINTER:
                printf("userpointer");
                break;
            default:
                printf("unknown");
        }
    }
    printf("\n");
    sq_pushinteger(v, nargs);
    return 1;
}

/******/

ScriptSquirrel::ScriptSquirrel(const std::string &file) :
    Script(file)
{
    vm = sq_open(1024);  //1024 byte stack
    sqstd_seterrorhandlers(vm);
    sq_setprintfunc(vm, printfunc);

    sq_pushroottable(vm);

    if (!SQ_SUCCEEDED(sqstd_dofile(vm, _SC(scriptName.c_str()), 0, 1)))
    {
        std::cerr << "Error: ScriptSquirrel: could not execute "
                  << scriptName << std::endl;
    }
    else
    {
        registerStdLib(vm);

        functionCall(vm, "", NULL);
        functionCall(vm, "init", NULL);
    }
}

ScriptSquirrel::~ScriptSquirrel()
{
    functionCall(vm, "destroy", NULL);

    sq_pop(vm, 1);
    sq_close(vm);
}

void ScriptSquirrel::update()
{
    functionCall(vm, "update", NULL);
}

bool ScriptSquirrel::execute(const std::string &functionName)
{
    return functionCall(vm, functionName.c_str(), NULL);
}

void ScriptSquirrel::message(char *msg)
{
    functionCall(vm, "message", "s", msg);
}

/******************************/
/*
 * Standard Library Functions
 */
int getName(HSQUIRRELVM v)
{
    sq_pushstring(v, "no name", -1);
    return 1;
}

int getX(HSQUIRRELVM v)
{
    sq_pushinteger(v, 0);
    return 1;
}

int getY(HSQUIRRELVM v)
{
    sq_pushinteger(v, 0);
    return 1;
}

int getMap(HSQUIRRELVM v)
{
    sq_pushstring(v, "map1.map", -1);
    return 1;
}

int getLevel(HSQUIRRELVM v)
{
    sq_pushinteger(v, 0);
    return 1;
}

int getHealth(HSQUIRRELVM v)
{
    sq_pushinteger(v, 0);
    return 1;
}

int getMaxHealth(HSQUIRRELVM v)
{
    sq_pushinteger(v, 0);
    return 1;
}

int getAttack(HSQUIRRELVM v)
{
    sq_pushinteger(v, 0);
    return 1;
}

int getDefense(HSQUIRRELVM v)
{
    sq_pushinteger(v, 0);
    return 1;
}

int getLuck(HSQUIRRELVM v)
{
    sq_pushinteger(v, 0);
    return 1;
}

int getVitality(HSQUIRRELVM v)
{
    sq_pushinteger(v, 0);
    return 1;
}

/*
 *  Register standard functions for game script
 */
void registerStdLib(HSQUIRRELVM v)
{
    functionRegister(v, getName, "getName");
    functionRegister(v, getX, "getX");
    functionRegister(v, getY, "getY");
    functionRegister(v, getMap, "getMap");
    functionRegister(v, getLevel, "getLevel");
    functionRegister(v, getHealth, "getHealth");
    functionRegister(v, getMaxHealth, "getMaxHealth");
    functionRegister(v, getAttack, "getAttack");
    functionRegister(v, getDefense, "getDefense");
    functionRegister(v, getLuck, "getLuck");
    functionRegister(v, getVitality, "getVitality");
}

#endif