diff --git a/source/lib/res/cursor.cpp b/source/lib/res/cursor.cpp index 4e8a5335e0..c72deab37f 100755 --- a/source/lib/res/cursor.cpp +++ b/source/lib/res/cursor.cpp @@ -143,115 +143,32 @@ static int cursor_load(Handle ht, int hotspotx, int hotspoty, void** sysdep_curs } imgdata = (const u8*)bgra_mem; } -/* - const size_t size = round_up(w*h, 8)/8; - u8* mask = (u8*)malloc(size); - if(!mask) - { - ret = ERR_NO_MEM; - goto fail; - } -*/ -/* - uint bit = 0; - for(int i = 0; i < w*h; i++) - { - ++bit; - bit &= 7; - if(imgdata[i*4+3]) - mask[i/8] |= bit; - } -*/ -//memset(mask, 0, size); -/* - BITMAPINFO bi = - { - { - sizeof(BITMAPINFOHEADER), // biSize - w, // biWidth - -h, // biHeight; negative to indicate top-down (required) - 1, // biPlanes - 32, // biBitCount - BI_RGB, // biCompression - 0, // biSizeImage (not needed for BI_RGB) - 0, // biXPelsPerMeter (don't care) - 0, // biYPelsPerMeter " - 0, // biClrUser (not needed for BI_RGB) - 0 // biClrImportant " - }, // bmiHeader - 0 // bmiColors[] - }; - const HDC hDC = wglGetCurrentDC(); - HBITMAP hBitmap = CreateDIBitmap(hDC, &bi.bmiHeader, CBM_INIT, imgdata, &bi, DIB_RGB_COLORS); - if(!hBitmap) // not INVALID_HANDLE_VALUE - { - debug_warn("cursor CreateDIBitmap failed"); - goto fail; - } + HBITMAP hbmColor = CreateBitmap(w, h, 1, 32, imgdata); -//HANDLE hCursor = LoadImage(GetModuleHandle(0), "D:\\projects\\0ad\\svn\\binaries\\data\\mods\\official\\art\\textures\\cursors\\test.png", IMAGE_BITMAP, 32, 32, LR_LOADFROMFILE); - -*/ -/* - ICONINFO info = { FALSE, hotspotx, hotspoty, hBitmap, hBitmap }; - HICON hIcon = CreateIconIndirect(&info); - DeleteObject(hBitmap); -*/ -/* -HICON hIcon = CreateIcon(GetModuleHandle(0), w,h,1,32,mask,imgdata); -ICONINFO info; -GetIconInfo(hIcon, &info); -info.fIcon = FALSE; // cursor -info.xHotspot = hotspotx; -info.yHotspot = hotspoty; -HICON hIcon2 = CreateIconIndirect(&info); - -*/ -/* - BITMAPV5HEADER bi; - ZeroMemory(&bi,sizeof(BITMAPV5HEADER)); - bi.bV5Size = sizeof(BITMAPV5HEADER); - bi.bV5Width = w; - bi.bV5Height = h; - bi.bV5Planes = 1; - bi.bV5BitCount = 32; - bi.bV5Compression = BI_BITFIELDS; - // The following mask specification specifies a supported 32 BPP - // alpha format for Windows XP. - bi.bV5RedMask = 0x00FF0000; - bi.bV5GreenMask = 0x0000FF00; - bi.bV5BlueMask = 0x000000FF; - bi.bV5AlphaMask = 0xFF000000; -*/ -// HDC hDC = GetDC(NULL); - HBITMAP hBitmap = CreateBitmap(w, h, 1, 32, imgdata); - //(BITMAPINFO*)&bi, DIB_RGB_COLORS, &dst, 0,0); -// ReleaseDC(0, hDC); - - // Create an empty mask bitmap. - HBITMAP hMonoBitmap = CreateBitmap(w, h, 1, 1, 0); + // CreateIconIndirect doesn't access it; we just need to pass + // an empty bitmap. + HBITMAP hbmMask = CreateBitmap(w, h, 1, 1, 0); ICONINFO ii; ii.fIcon = FALSE; // cursor ii.xHotspot = hotspotx; ii.yHotspot = hotspoty; - ii.hbmMask = hMonoBitmap; - ii.hbmColor = hBitmap; + ii.hbmMask = hbmMask; + ii.hbmColor = hbmColor; + HICON hIcon = CreateIconIndirect(&ii); - // Create the alpha cursor with the alpha DIB section. - HICON hIcon2 = CreateIconIndirect(&ii); + // CreateIconIndirect makes copies, so we no longer need these. + DeleteObject(hbmMask); + DeleteObject(hbmColor); - DeleteObject(hBitmap); - DeleteObject(hMonoBitmap); - - if(!hIcon2) // not INVALID_HANDLE_VALUE + if(!hIcon) // not INVALID_HANDLE_VALUE { debug_warn("cursor CreateIconIndirect failed"); goto fail; } - *sysdep_cursor = ptr_from_HICON(hIcon2); + *sysdep_cursor = ptr_from_HICON(hIcon); ret = 0; } @@ -263,92 +180,6 @@ fail: } - - - - -void CreateAlphaCursor(void) -{ - HDC hMemDC; - DWORD dwWidth, dwHeight; - BITMAPV5HEADER bi; - HBITMAP hBitmap, hOldBitmap; - void *lpBits; - DWORD x,y; - HCURSOR hAlphaCursor = NULL; - - dwWidth = 32; // width of cursor - dwHeight = 32; // height of cursor - - ZeroMemory(&bi,sizeof(BITMAPV5HEADER)); - bi.bV5Size = sizeof(BITMAPV5HEADER); - bi.bV5Width = dwWidth; - bi.bV5Height = dwHeight; - bi.bV5Planes = 1; - bi.bV5BitCount = 32; - bi.bV5Compression = BI_BITFIELDS; - // The following mask specification specifies a supported 32 BPP - // alpha format for Windows XP. - bi.bV5RedMask = 0x00FF0000; - bi.bV5GreenMask = 0x0000FF00; - bi.bV5BlueMask = 0x000000FF; - bi.bV5AlphaMask = 0xFF000000; - - HDC hdc; - hdc = GetDC(NULL); - - // Create the DIB section with an alpha channel. - hBitmap = CreateDIBSection(hdc, (BITMAPINFO *)&bi, DIB_RGB_COLORS, - (void **)&lpBits, NULL, (DWORD)0); - - hMemDC = CreateCompatibleDC(hdc); - ReleaseDC(NULL,hdc); - - // Draw something on the DIB section. - hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap); - PatBlt(hMemDC,0,0,dwWidth,dwHeight,WHITENESS); - SetTextColor(hMemDC,RGB(0,0,0)); - SetBkMode(hMemDC,TRANSPARENT); - TextOut(hMemDC,0,9,"rgba",4); - SelectObject(hMemDC, hOldBitmap); - DeleteDC(hMemDC); - - // Create an empty mask bitmap. - HBITMAP hMonoBitmap = CreateBitmap(dwWidth,dwHeight,1,1,NULL); - - // Set the alpha values for each pixel in the cursor so that - // the complete cursor is semi-transparent. - DWORD *lpdwPixel; - lpdwPixel = (DWORD *)lpBits; - for (x=0;x max_number)\ + {\ + JS_ReportError(cx, #func_name ": too many parameters passed");\ + return JS_FALSE;\ + } +// .. accept at least N params (e.g. issueCommand) +#define REQUIRE_MIN_PARAMS(min_number, func_name)\ + if(argc < min_number)\ + {\ + JS_ReportError(cx, #func_name ": too few parameters passed");\ + return JS_FALSE;\ + } + + +//----------------------------------------------------------------------------- +// Output +//----------------------------------------------------------------------------- + +// Write values to the log file. +// params: any number of any type. +// returns: +// notes: +// - Each argument is converted to a string and then written to the log. +// - Output is in NORMAL style (see LOG). +JSBool WriteLog(JSContext* cx, JSObject*, uint argc, jsval* argv, jsval* UNUSEDPARAM(rval)) { - {"writeLog", WriteLog, 1, 0, 0}, - {"writeConsole", JSI_Console::writeConsole, 1, 0, 0 }, // Keep this variant available for now. - {"getEntityByHandle", getEntityByHandle, 1, 0, 0 }, - {"getEntityTemplate", getEntityTemplate, 1, 0, 0 }, - {"setTimeout", setTimeout, 2, 0, 0 }, - {"setInterval", setInterval, 2, 0, 0 }, - {"cancelInterval", cancelInterval, 0, 0, 0 }, -#ifndef NO_GUI - {"getGUIObjectByName", JSI_IGUIObject::getByName, 1, 0, 0 }, -#endif - {"getGlobal", getGlobal, 0, 0, 0 }, - {"getGUIGlobal", getGUIGlobal, 0, 0, 0 }, - {"setCursor", setCursor, 1, 0, 0 }, - {"addGlobalHandler", AddGlobalHandler, 2, 0, 0 }, - {"removeGlobalHandler", RemoveGlobalHandler, 2, 0, 0 }, - {"setCameraTarget", setCameraTarget, 1, 0, 0 }, - {"startGame", startGame, 0, 0, 0 }, - {"endGame", endGame, 0, 0, 0 }, - {"createClient", createClient, 0, 0, 0 }, - {"createServer", createServer, 0, 0, 0 }, - {"loadLanguage", loadLanguage, 1, 0, 0 }, - {"getLanguageID", getLanguageID, 0, 0, 0 }, - {"getFPS", getFPS, 0, 0, 0 }, - {"buildTime", buildTime, 0, 0, 0 }, - - // VFS: - {"buildFileList", JSI_VFS::BuildFileList, 1, 0, 0 }, - {"getFileMTime", JSI_VFS::GetFileMTime, 1, 0, 0 }, - {"getFileSize", JSI_VFS::GetFileSize, 1, 0, 0 }, - {"readFile", JSI_VFS::ReadFile, 1, 0, 0 }, - {"readFileLines", JSI_VFS::ReadFileLines, 1, 0, 0 }, - - {"v3dist", v3dist, 2, 0, 0 }, - - {"issueCommand", issueCommand, 2, 0, 0 }, - - {"exit", exitProgram, 0, 0, 0 }, - {"crash", crash, 0, 0, 0 }, - {"forceGC", forceGC, 0, 0, 0 }, - {"vmem", vmem, 0, 0, 0 }, - {"_rewriteMaps", _rewriteMaps, 0, 0, 0 }, - {"_lodbias", _lodbias, 0, 0, 0 }, - {0, 0, 0, 0, 0} -}; - -enum ScriptGlobalTinyIDs -{ - GLOBAL_SELECTION, - GLOBAL_GROUPSARRAY, - GLOBAL_CAMERA, - GLOBAL_CONSOLE, -}; - -JSPropertySpec ScriptGlobalTable[] = -{ - { "selection", GLOBAL_SELECTION, JSPROP_PERMANENT, JSI_Selection::getSelection, JSI_Selection::setSelection }, - { "groups", GLOBAL_GROUPSARRAY, JSPROP_PERMANENT, JSI_Selection::getGroups, JSI_Selection::setGroups }, - { "camera", GLOBAL_CAMERA, JSPROP_PERMANENT, JSI_Camera::getCamera, JSI_Camera::setCamera }, - { "console", GLOBAL_CONSOLE, JSPROP_PERMANENT | JSPROP_READONLY, JSI_Console::getConsole, NULL }, - { "entities", 0, JSPROP_PERMANENT | JSPROP_READONLY, GetEntitySet, NULL }, - { "players", 0, JSPROP_PERMANENT | JSPROP_READONLY, GetPlayerSet, NULL }, - { "localPlayer", 0, JSPROP_PERMANENT, GetLocalPlayer, SetLocalPlayer }, - { "gaiaPlayer", 0, JSPROP_PERMANENT | JSPROP_READONLY, GetGaiaPlayer, NULL }, - { "gameView", 0, JSPROP_PERMANENT | JSPROP_READONLY, GetGameView, NULL }, - { 0, 0, 0, 0, 0 }, -}; - -// Allow scripts to output to the global log file -JSBool WriteLog(JSContext* context, JSObject* UNUSEDPARAM(globalObject), unsigned int argc, jsval* argv, jsval* UNUSEDPARAM(rval)) -{ - if (argc < 1) - return JS_FALSE; + REQUIRE_MIN_PARAMS(1, WriteLog); CStr logMessage; @@ -144,9 +120,19 @@ JSBool WriteLog(JSContext* context, JSObject* UNUSEDPARAM(globalObject), unsigne return JS_TRUE; } -JSBool getEntityByHandle( JSContext* context, JSObject* UNUSEDPARAM(globalObject), unsigned int argc, jsval* argv, jsval* rval ) + +//----------------------------------------------------------------------------- +// Entity +//----------------------------------------------------------------------------- + +// Look up an Entity by entity handle. +// params: handle [int] +// returns: entity +JSBool getEntityByHandle( JSContext* cx, JSObject*, uint argc, jsval* argv, jsval* rval ) { - debug_assert( argc >= 1 ); + REQUIRE_PARAMS(1, getEntityByHandle); + *rval = JSVAL_NULL; + i32 handle; try { @@ -154,15 +140,13 @@ JSBool getEntityByHandle( JSContext* context, JSObject* UNUSEDPARAM(globalObject } catch( PSERROR_Scripting_ConversionFailed ) { - *rval = JSVAL_NULL; - JS_ReportError( context, "Invalid handle" ); + JS_ReportError( cx, "Invalid handle" ); return( JS_TRUE ); } HEntity* v = g_EntityManager.getByHandle( (u16)handle ); if( !v ) { - JS_ReportError( context, "No entity occupying handle: %d", handle ); - *rval = JSVAL_NULL; + JS_ReportError( cx, "No entity occupying handle: %d", handle ); return( JS_TRUE ); } JSObject* entity = (*v)->GetScript(); @@ -171,9 +155,15 @@ JSBool getEntityByHandle( JSContext* context, JSObject* UNUSEDPARAM(globalObject return( JS_TRUE ); } -JSBool getEntityTemplate( JSContext* context, JSObject* UNUSEDPARAM(globalObject), unsigned int argc, jsval* argv, jsval* rval ) + +// Look up an EntityTemplate by name. +// params: template name [wstring] +// returns: entity template object +JSBool getEntityTemplate( JSContext* cx, JSObject*, uint argc, jsval* argv, jsval* rval ) { - debug_assert( argc >= 1 ); + REQUIRE_PARAMS(1, getEntityTemplate); + *rval = JSVAL_NULL; + CStrW templateName; try { @@ -181,140 +171,116 @@ JSBool getEntityTemplate( JSContext* context, JSObject* UNUSEDPARAM(globalObject } catch( PSERROR_Scripting_ConversionFailed ) { - *rval = JSVAL_NULL; - JS_ReportError( context, "Invalid template identifier" ); + JS_ReportError( cx, "Invalid template identifier" ); return( JS_TRUE ); } CBaseEntity* v = g_EntityTemplateCollection.getTemplate( templateName ); if( !v ) { - *rval = JSVAL_NULL; - JS_ReportError( context, "No such template: %s", CStr8(templateName).c_str() ); + JS_ReportError( cx, "No such template: %s", CStr8(templateName).c_str() ); return( JS_TRUE ); } *rval = OBJECT_TO_JSVAL( v->GetScript() ); - return( JS_TRUE ); } -JSBool GetEntitySet( JSContext* context, JSObject* globalObject, jsval argv, jsval* vp ) + +//----------------------------------------------------------------------------- +// Events +//----------------------------------------------------------------------------- + +// Register a global handler for the specified DOM event. +// params: event type name [wstring], handler [fragment or function] +// returns: whether it was actually newly registered [bool] +JSBool AddGlobalHandler( JSContext* cx, JSObject* obj, uint argc, jsval* argv, jsval* rval ) { - std::vector* extant = g_EntityManager.getExtant(); + REQUIRE_PARAMS(2, AddGlobalHandler); - *vp = OBJECT_TO_JSVAL( EntityCollection::Create( *extant ) ); - delete( extant ); - - return( JS_TRUE ); -} - -JSBool GetPlayerSet( JSContext* cx, JSObject* globalObject, jsval id, jsval* vp ) -{ - std::vector* players = g_Game->GetPlayers(); - - *vp = OBJECT_TO_JSVAL( PlayerCollection::Create( *players ) ); - - return( JS_TRUE ); -} - -JSBool GetLocalPlayer( JSContext* cx, JSObject* globalObject, jsval id, jsval* vp ) -{ - *vp = OBJECT_TO_JSVAL( g_Game->GetLocalPlayer()->GetScript() ); - return( JS_TRUE ); -} - -JSBool GetGaiaPlayer( JSContext* cx, JSObject* globalObject, jsval id, jsval* vp ) -{ - *vp = OBJECT_TO_JSVAL( g_Game->GetPlayer( 0 )->GetScript() ); - return( JS_TRUE ); -} - -JSBool SetLocalPlayer( JSContext* context, JSObject* obj, jsval id, jsval* vp ) -{ - CPlayer* newLocalPlayer = ToNative( *vp ); - - if( !newLocalPlayer ) - { - JS_ReportError( context, "Not a valid Player." ); - return( JS_TRUE ); - } - - g_Game->SetLocalPlayer( newLocalPlayer ); - return( JS_TRUE ); -} - -JSBool GetGameView( JSContext* cx, JSObject* globalObject, jsval id, jsval* vp ) -{ - if (g_Game) - *vp = OBJECT_TO_JSVAL( g_Game->GetView()->GetScript() ); - else - *vp = JSVAL_NULL; - return( JS_TRUE ); -} - -JSBool AddGlobalHandler( JSContext* cx, JSObject* obj, unsigned int argc, jsval* argv, jsval* rval ) -{ *rval = BOOLEAN_TO_JSVAL( g_JSGameEvents.AddHandlerJS( cx, argc, argv ) ); return( JS_TRUE ); } -JSBool RemoveGlobalHandler( JSContext* cx, JSObject* obj, unsigned int argc, jsval* argv, jsval* rval ) + +// Remove a previously registered global handler for the specified DOM event. +// params: event type name [wstring], handler [fragment or function] +// returns: whether it was successfully removed [bool] +JSBool RemoveGlobalHandler( JSContext* cx, JSObject* obj, uint argc, jsval* argv, jsval* rval ) { + REQUIRE_PARAMS(2, RemoveGlobalHandler); + *rval = BOOLEAN_TO_JSVAL( g_JSGameEvents.RemoveHandlerJS( cx, argc, argv ) ); return( JS_TRUE ); } -JSBool setCameraTarget( JSContext* context, JSObject* obj, unsigned int argc, jsval* argv, jsval* rval ) -{ - CVector3D* target; - if( ( argc == 0 ) || !( target = ToNative( argv[0] ) ) ) - { - JS_ReportError( context, "Invalid camera target" ); - return( JS_TRUE ); - } - g_Game->GetView()->SetCameraTarget( *target ); - *rval = JSVAL_TRUE; - return( JS_TRUE ); -} +//----------------------------------------------------------------------------- +// Timer +//----------------------------------------------------------------------------- -JSBool setTimeout( JSContext* context, JSObject* UNUSEDPARAM(globalObject), unsigned int argc, jsval* argv, jsval* UNUSEDPARAM(rval) ) +// Request a callback be executed after the specified delay. +// params: callback [fragment or function], delay in milliseconds [int] +// returns: +// notes: +// - Scripts and functions registered this way are called on the first +// simulation frame after the specified period has elapsed. If this causes +// multiple segments of code to be executed in the same frame, +// relative timing is maintained. Delays of 0 milliseconds cause code to be +// executed on the following simulation frame. If more than one script or +// function is scheduled to execute in the same millisecond, the order of +// execution is undefined. Code is scheduled in simulation time, and is +// therefore suspended while the game is paused or frozen. Granularity of +// timing is also limited to 1/(Simulation frame rate); currently 100ms. +// The called function or script executes in the same scope as the +// code that called setTimeout (amongst other things, the +// 'this' reference is usually maintained) +JSBool setTimeout( JSContext* cx, JSObject*, uint argc, jsval* argv, jsval* UNUSEDPARAM(rval) ) { - debug_assert( argc >= 2 ); + REQUIRE_PARAMS(2, setTimeout); + size_t delay; try { delay = g_ScriptingHost.ValueToInt( argv[1] ); } - catch( ... ) + catch( PSERROR_Scripting_ConversionFailed ) { - JS_ReportError( context, "Invalid timer parameters" ); + JS_ReportError( cx, "Invalid timer parameters" ); return( JS_TRUE ); } - switch( JS_TypeOfValue( context, argv[0] ) ) + switch( JS_TypeOfValue( cx, argv[0] ) ) { case JSTYPE_STRING: { CStrW fragment = g_ScriptingHost.ValueToUCString( argv[0] ); - g_Scheduler.pushTime( delay, fragment, JS_GetScopeChain( context ) ); + g_Scheduler.pushTime( delay, fragment, JS_GetScopeChain( cx ) ); return( JS_TRUE ); } case JSTYPE_FUNCTION: { - JSFunction* fn = JS_ValueToFunction( context, argv[0] ); - g_Scheduler.pushTime( delay, fn, JS_GetScopeChain( context ) ); + JSFunction* fn = JS_ValueToFunction( cx, argv[0] ); + g_Scheduler.pushTime( delay, fn, JS_GetScopeChain( cx ) ); return( JS_TRUE ); } default: - JS_ReportError( context, "Invalid timer script" ); + JS_ReportError( cx, "Invalid timer script" ); return( JS_TRUE ); } } -JSBool setInterval( JSContext* context, JSObject* UNUSEDPARAM(globalObject), unsigned int argc, jsval* argv, jsval* UNUSEDPARAM(rval) ) + +// Request a callback be executed periodically. +// params: callback [fragment or function], initial delay in ms [int], period in ms [int] +// OR callback [fragment or function], period in ms [int] (initial delay = period) +// returns: +// notes: +// - setTimeout's notes apply here as well. +JSBool setInterval( JSContext* cx, JSObject*, uint argc, jsval* argv, jsval* UNUSEDPARAM(rval) ) { - debug_assert( argc >= 2 ); + REQUIRE_MIN_PARAMS(2, setInterval); + REQUIRE_MAX_PARAMS(3, setInterval); + size_t first, interval; try { @@ -330,122 +296,105 @@ JSBool setInterval( JSContext* context, JSObject* UNUSEDPARAM(globalObject), uns interval = first; } } - catch( ... ) + catch( PSERROR_Scripting_ConversionFailed ) { - JS_ReportError( context, "Invalid timer parameters" ); + JS_ReportError( cx, "Invalid timer parameters" ); return( JS_TRUE ); } - switch( JS_TypeOfValue( context, argv[0] ) ) + switch( JS_TypeOfValue( cx, argv[0] ) ) { case JSTYPE_STRING: { CStrW fragment = g_ScriptingHost.ValueToUCString( argv[0] ); - g_Scheduler.pushInterval( first, interval, fragment, JS_GetScopeChain( context ) ); + g_Scheduler.pushInterval( first, interval, fragment, JS_GetScopeChain( cx ) ); return( JS_TRUE ); } case JSTYPE_FUNCTION: { - JSFunction* fn = JS_ValueToFunction( context, argv[0] ); - g_Scheduler.pushInterval( first, interval, fn, JS_GetScopeChain( context ) ); + JSFunction* fn = JS_ValueToFunction( cx, argv[0] ); + g_Scheduler.pushInterval( first, interval, fn, JS_GetScopeChain( cx ) ); return( JS_TRUE ); } default: - JS_ReportError( context, "Invalid timer script" ); + JS_ReportError( cx, "Invalid timer script" ); return( JS_TRUE ); } } -JSBool cancelInterval( JSContext* UNUSEDPARAM(context), JSObject* UNUSEDPARAM(globalObject), unsigned int UNUSEDPARAM(argc), jsval* UNUSEDPARAM(argv), jsval* UNUSEDPARAM(rval) ) + +// Cause all periodic functions registered via setInterval to +// no longer be called. +// params: +// returns: +// notes: +// - Execution continues until the end of the triggered function or +// script fragment, but is not triggered again. +JSBool cancelInterval( JSContext* cx, JSObject*, uint argc, jsval* argv, jsval* UNUSEDPARAM(rval) ) { + REQUIRE_NO_PARAMS(cancelInterval); + g_Scheduler.m_abortInterval = true; return( JS_TRUE ); } -JSBool v3dist( JSContext* cx, JSObject* obj, unsigned int argc, jsval* argv, jsval* rval ) -{ - debug_assert( argc >= 2 ); - CVector3D* a = ToNative( argv[0] ); - CVector3D* b = ToNative( argv[1] ); - float dist = ( *a - *b ).GetLength(); - *rval = ToJSVal( dist ); - return( JS_TRUE ); -} -JSBool forceGC( JSContext* cx, JSObject* obj, unsigned int argc, jsval* argv, jsval* rval ) -{ - double time = get_time(); - JS_GC( cx ); - time = get_time() - time; - g_Console->InsertMessage( L"Garbage collection completed in: %f", time ); - *rval = JSVAL_TRUE; - return( JS_TRUE ); -} +//----------------------------------------------------------------------------- +// Game Setup +//----------------------------------------------------------------------------- -JSBool getGUIGlobal( JSContext* UNUSEDPARAM(context), JSObject* UNUSEDPARAM(globalObject), unsigned int UNUSEDPARAM(argc), jsval* UNUSEDPARAM(argv), jsval* rval ) +// Create a new network server object. +// params: +// returns: net server object +JSBool createServer(JSContext* cx, JSObject*, uint argc, jsval* argv, jsval* rval) { - *rval = OBJECT_TO_JSVAL( g_GUI.GetScriptObject() ); - return( JS_TRUE ); -} + REQUIRE_NO_PARAMS(createServer); -JSBool getGlobal( JSContext* UNUSEDPARAM(context), JSObject* globalObject, unsigned int UNUSEDPARAM(argc), jsval* UNUSEDPARAM(argv), jsval* rval ) -{ - *rval = OBJECT_TO_JSVAL( globalObject ); - return( JS_TRUE ); -} - - -extern CStr g_CursorName; // from main.cpp -JSBool setCursor(JSContext* UNUSEDPARAM(context), JSObject* UNUSEDPARAM(globalObject), unsigned int argc, jsval* argv, jsval* UNUSEDPARAM(rval)) -{ - if (argc != 1) - { - debug_assert(! "Invalid parameter count to setCursor"); - return JS_FALSE; - } - g_CursorName = g_ScriptingHost.ValueToString(argv[0]); - return JS_TRUE; -} - -JSBool createServer(JSContext* cx, JSObject* UNUSEDPARAM(globalObject), unsigned int argc, jsval* argv, jsval* rval) -{ - if (!g_Game) - g_Game=new CGame(); - if (!g_NetServer) - g_NetServer=new CNetServer(g_Game, &g_GameAttributes); + if( !g_Game ) + g_Game = new CGame(); + if( !g_NetServer ) + g_NetServer = new CNetServer(g_Game, &g_GameAttributes); - *rval=OBJECT_TO_JSVAL(g_NetServer->GetScript()); - return JS_TRUE; + *rval = OBJECT_TO_JSVAL(g_NetServer->GetScript()); + return( JS_TRUE ); } -// from main.cpp -extern void StartGame(); -JSBool createClient(JSContext* cx, JSObject* UNUSEDPARAM(globalObject), unsigned int argc, jsval* argv, jsval* rval) +// Create a new network client object. +// params: +// returns: net client object +JSBool createClient(JSContext* cx, JSObject*, uint argc, jsval* argv, jsval* rval) { - if (!g_Game) - g_Game=new CGame(); - if (!g_NetClient) - g_NetClient=new CNetClient(g_Game, &g_GameAttributes); - - *rval=OBJECT_TO_JSVAL(g_NetClient->GetScript()); - return JS_TRUE; + REQUIRE_NO_PARAMS(createClient); + + if( !g_Game ) + g_Game = new CGame(); + if( !g_NetClient ) + g_NetClient = new CNetClient(g_Game, &g_GameAttributes); + + *rval = OBJECT_TO_JSVAL(g_NetClient->GetScript()); + return( JS_TRUE ); } -// TODO Replace startGame with create(Game|Server|Client)/game.start() - after -// merging CGame and CGameAttributes -JSBool startGame(JSContext* cx, JSObject* UNUSEDPARAM(globalObject), unsigned int argc, jsval* argv, jsval* rval) -{ - if (argc != 0) - { - return JS_FALSE; - } - *rval=BOOLEAN_TO_JSVAL(JS_TRUE); +// Begin the process of starting a game. +// params: +// returns: success [bool] +// notes: +// - Performs necessary initialization while calling back into the +// main loop, so the game remains responsive to display+user input. +// - When complete, the engine calls the reallyStartGame JS function. +// TODO: Replace startGame with create(Game|Server|Client)/game.start() - +// after merging CGame and CGameAttributes +JSBool startGame(JSContext* cx, JSObject*, uint argc, jsval* argv, jsval* rval) +{ + REQUIRE_NO_PARAMS(startGame); + + *rval = BOOLEAN_TO_JSVAL(JS_TRUE); // Hosted MP Game if (g_NetServer) - *rval=BOOLEAN_TO_JSVAL(g_NetServer->StartGame() == 0); + *rval = BOOLEAN_TO_JSVAL(g_NetServer->StartGame() == 0); // Joined MP Game: startGame is invalid - do nothing else if (g_NetClient) { @@ -453,7 +402,7 @@ JSBool startGame(JSContext* cx, JSObject* UNUSEDPARAM(globalObject), unsigned in // Start an SP Game Session else if (!g_Game) { - g_Game=new CGame(); + g_Game = new CGame(); PSRETURN ret = g_Game->StartGame(&g_GameAttributes); if (ret != PSRETURN_OK) { @@ -462,37 +411,53 @@ JSBool startGame(JSContext* cx, JSObject* UNUSEDPARAM(globalObject), unsigned in delete g_Game; g_Game = NULL; - *rval=BOOLEAN_TO_JSVAL(JS_FALSE); - return JS_TRUE; + *rval = BOOLEAN_TO_JSVAL(JS_FALSE); + return( JS_TRUE ); } } - return JS_TRUE; + return( JS_TRUE ); } -extern void EndGame(); -JSBool endGame(JSContext* UNUSEDPARAM(context), JSObject* UNUSEDPARAM(globalObject), unsigned int UNUSEDPARAM(argc), jsval* UNUSEDPARAM(argv), jsval* UNUSEDPARAM(rval)) + +// Immediately ends the current game (if any). +// params: +// returns: +JSBool endGame(JSContext* cx, JSObject*, uint argc, jsval* argv, jsval* UNUSEDPARAM(rval)) { + REQUIRE_NO_PARAMS(endGame); + EndGame(); return JS_TRUE; } -JSBool loadLanguage(JSContext* cx, JSObject* UNUSEDPARAM(globalObject), unsigned int argc, jsval* argv, jsval* rval) +//----------------------------------------------------------------------------- +// Internationalization +//----------------------------------------------------------------------------- + +// Replaces the current language (locale) with a new one. +// params: language id [string] as in I18n::LoadLanguage +// returns: +JSBool loadLanguage(JSContext* cx, JSObject*, uint argc, jsval* argv, jsval* UNUSEDPARAM(rval)) { - if (argc != 1) - { - JS_ReportError(cx, "loadLanguage: needs 1 parameter"); - return JS_FALSE; - } + REQUIRE_PARAMS(1, loadLanguage); + CStr lang = g_ScriptingHost.ValueToString(argv[0]); I18n::LoadLanguage(lang); return JS_TRUE; } -JSBool getLanguageID(JSContext* cx, JSObject* UNUSEDPARAM(globalObject), unsigned int UNUSEDPARAM(argc), jsval* UNUSEDPARAM(argv), jsval* rval) + +// Return identifier of the current language (locale) in use. +// params: +// returns: language id [string] as in I18n::LoadLanguage +JSBool getLanguageID(JSContext* cx, JSObject*, uint argc, jsval* argv, jsval* rval) { + REQUIRE_NO_PARAMS(getLanguageID); + *rval = JSVAL_NULL; + JSString* s = JS_NewStringCopyZ(cx, I18n::CurrentLanguageName()); if (!s) { @@ -503,54 +468,125 @@ JSBool getLanguageID(JSContext* cx, JSObject* UNUSEDPARAM(globalObject), unsigne return JS_TRUE; } -extern "C" int fps; -JSBool getFPS(JSContext* UNUSEDPARAM(cx), JSObject* UNUSEDPARAM(globalObject), unsigned int UNUSEDPARAM(argc), jsval* UNUSEDPARAM(argv), jsval* rval) + +//----------------------------------------------------------------------------- +// Debug +//----------------------------------------------------------------------------- + + +// Deliberately cause the game to crash. +// params: +// returns: +// notes: +// - currently implemented via access violation (read of address 0) +// - useful for testing the crashlog/stack trace code. +JSBool crash(JSContext* cx, JSObject*, uint argc, jsval* argv, jsval* UNUSEDPARAM(rval)) { + REQUIRE_NO_PARAMS(crash); + + MICROLOG(L"Crashing at user's request."); + return *(JSBool*)0; +} + + +// Force a JS GC (garbage collection) cycle to take place immediately. +// params: +// returns: true [bool] +// notes: +// - writes an indication of how long this took to the console. +JSBool forceGC( JSContext* cx, JSObject* obj, uint argc, jsval* argv, jsval* rval ) +{ + REQUIRE_NO_PARAMS(forceGC); + + double time = get_time(); + JS_GC( cx ); + time = get_time() - time; + g_Console->InsertMessage( L"Garbage collection completed in: %f", time ); + *rval = JSVAL_TRUE; + return( JS_TRUE ); +} + + + +//----------------------------------------------------------------------------- +// Misc. Script System +//----------------------------------------------------------------------------- + +// Returns the sort-of-global object associated with the current GUI. +// params: +// returns: global object +// notes: +// - Useful for accessing an object from another scope. +JSBool getGUIGlobal( JSContext* cx, JSObject*, uint argc, jsval* argv, jsval* rval ) +{ + REQUIRE_NO_PARAMS(getGUIGlobal); + + *rval = OBJECT_TO_JSVAL( g_GUI.GetScriptObject() ); + return( JS_TRUE ); +} + + +// Returns the global object. +// params: +// returns: global object +// notes: +// - Useful for accessing an object from another scope. +JSBool getGlobal( JSContext* cx, JSObject* globalObject, uint argc, jsval* argv, jsval* rval ) +{ + REQUIRE_NO_PARAMS(getGlobal); + + *rval = OBJECT_TO_JSVAL( globalObject ); + return( JS_TRUE ); +} + + +//----------------------------------------------------------------------------- +// Misc. Engine Interface +//----------------------------------------------------------------------------- + +// Return the global frames-per-second value. +// params: +// returns: FPS [int] +// notes: +// - This value is recalculated once a frame. We take special care to +// filter it, so it is both accurate and free of jitter. +JSBool getFPS( JSContext* cx, JSObject*, uint argc, jsval* argv, jsval* rval ) +{ + REQUIRE_NO_PARAMS(getFPS); + *rval = INT_TO_JSVAL(fps); return JS_TRUE; } -JSBool buildTime(JSContext* context, JSObject* UNUSEDPARAM(globalObject), unsigned int argc, jsval* argv, jsval* rval) + +// Cause the game to exit gracefully. +// params: +// returns: +// notes: +// - Exit happens after the current main loop iteration ends +// (since this only sets a flag telling it to end) +JSBool exitProgram( JSContext* cx, JSObject*, uint argc, jsval* argv, jsval* UNUSEDPARAM(rval) ) { - if (argc > 1) - { - JS_ReportError(context, "buildTime: needs 0 or 1 parameter"); - return JS_FALSE; - } - // buildTime( ) = "date time" - // buildTime(0) = "date" - // buildTime(1) = "time" - JSString* s = JS_NewStringCopyZ(context, - argc && argv[0]==JSVAL_ONE ? __TIME__ - : argc ? __DATE__ - : __DATE__" "__TIME__ - ); - *rval = STRING_TO_JSVAL(s); - return JS_TRUE; -} + REQUIRE_NO_PARAMS(exitProgram); - - -extern void kill_mainloop(); // from main.cpp - -JSBool exitProgram(JSContext* context, JSObject* globalObject, unsigned int argc, jsval* UNUSEDPARAM(argv), jsval* UNUSEDPARAM(rval)) -{ kill_mainloop(); return JS_TRUE; } -JSBool crash(JSContext* context, JSObject* globalObject, unsigned int argc, jsval* argv, jsval* rval) -{ - MICROLOG(L"Crashing at user's request."); - uintptr_t ptr = 0xDEADC0DE; // oh dear, might this be an invalid pointer? - return *(JSBool*) ptr; -} -JSBool vmem(JSContext* context, JSObject* globalObject, unsigned int argc, jsval* argv, jsval* rval) +// Write an indication of total/available video RAM to console. +// params: +// returns: +// notes: +// - Not supported on all platforms. +// - Only a rough approximation; do not base low-level decisions +// ("should I allocate one more texture?") on this. +JSBool vmem( JSContext* cx, JSObject*, uint argc, jsval* argv, jsval* UNUSEDPARAM(rval) ) { + REQUIRE_NO_PARAMS(vmem); + #ifdef _WIN32 int left, total; - extern int GetVRAMInfo(int&, int&); if (GetVRAMInfo(left, total)) g_Console->InsertMessage(L"VRAM: used %d, total %d, free %d", total-left, total, left); else @@ -561,43 +597,315 @@ JSBool vmem(JSContext* context, JSObject* globalObject, unsigned int argc, jsval return JS_TRUE; } -JSBool _rewriteMaps(JSContext* context, JSObject* globalObject, unsigned int argc, jsval* argv, jsval* rval) + +// Change the mouse cursor. +// params: cursor name [string] (i.e. basename of definition file and texture) +// returns: +// notes: +// - Cursors are stored in "art\textures\cursors" +JSBool setCursor( JSContext* cx, JSObject*, uint argc, jsval* argv, jsval* UNUSEDPARAM(rval) ) { - extern CLightEnv g_LightEnv; + REQUIRE_PARAMS(1, setCursor); + + g_CursorName = g_ScriptingHost.ValueToString(argv[0]); + return JS_TRUE; +} + + +// Trigger a rewrite of all maps. +// params: +// returns: +// notes: +// - Usefulness is unclear. If you need it, consider renaming this and updating the docs. +JSBool _rewriteMaps( JSContext* cx, JSObject*, uint argc, jsval* argv, jsval* UNUSEDPARAM(rval) ) +{ + REQUIRE_NO_PARAMS(_rewriteMaps); + CMapWriter::RewriteAllMaps(g_Game->GetWorld()->GetTerrain(), g_Game->GetWorld()->GetUnitManager(), &g_LightEnv); return JS_TRUE; } -#include "Renderer.h" -JSBool _lodbias(JSContext* context, JSObject* globalObject, unsigned int argc, jsval* argv, jsval* rval) + +// Change the LOD bias. +// params: LOD bias [float] +// returns: +// notes: +// - value is as required by GL_TEXTURE_LOD_BIAS. +// - useful for adjusting image "sharpness" (since it affects which mipmap level is chosen) +JSBool _lodbias( JSContext* cx, JSObject*, uint argc, jsval* argv, jsval* UNUSEDPARAM(rval) ) { + REQUIRE_PARAMS(1, _lodbias); + g_Renderer.SetOptionFloat(CRenderer::OPT_LODBIAS, (float)g_ScriptingHost.ValueToDouble(argv[0])); return JS_TRUE; } -JSBool issueCommand(JSContext* context, JSObject* UNUSEDPARAM(globalObject), unsigned int argc, jsval* argv, jsval* rval) + +// Set the lookat target of the game camera. +// params: target position vector [CVector3D] +// returns: success [bool] +JSBool setCameraTarget( JSContext* cx, JSObject* obj, uint argc, jsval* argv, jsval* rval ) { - debug_assert(argc >= 2); + REQUIRE_PARAMS(1, setCameraTarget); + *rval = JSVAL_NULL; + + CVector3D* target; + if( !( target = ToNative( argv[0] ) ) ) + { + JS_ReportError( cx, "Invalid camera target" ); + return( JS_TRUE ); + } + g_Game->GetView()->SetCameraTarget( *target ); + + *rval = JSVAL_TRUE; + return( JS_TRUE ); +} + + +//----------------------------------------------------------------------------- +// Miscellany +//----------------------------------------------------------------------------- + +// Return the date/time at which the current executable was compiled. +// params: none (-> "date time") OR +// what to display [int]: 0 (-> "date"); 1 (-> "time") +// returns: date and/or time [string] +// notes: +// - Displayed on main menu screen; tells non-programmers which auto-build +// they are running. Could also be determined via .EXE file properties, +// but that's a bit more trouble. +// - To be exact, the date/time returned is when scriptglue.cpp was +// last compiled; since the auto-build does full rebuilds, that is moot. +JSBool buildTime( JSContext* cx, JSObject*, uint argc, jsval* argv, jsval* rval ) +{ + REQUIRE_MAX_PARAMS(1, buildTime); + + // buildTime( ) = "date time" + // buildTime(0) = "date" + // buildTime(1) = "time" + JSString* s = JS_NewStringCopyZ(cx, + argc && argv[0]==JSVAL_ONE ? __TIME__ + : argc ? __DATE__ + : __DATE__" "__TIME__ + ); + *rval = STRING_TO_JSVAL(s); + return JS_TRUE; +} + + +// Issue a command (network message) to an entity or collection. +// params: either an entity- or entity collection object, message ID [int], +// any further params needed by CNetMessage::CommandFromJSArgs +// returns: command in serialized form [string] +JSBool issueCommand( JSContext* cx, JSObject*, uint argc, jsval* argv, jsval* rval ) +{ + REQUIRE_MIN_PARAMS(2, issueCommand); debug_assert(JSVAL_IS_OBJECT(argv[0])); + *rval = JSVAL_NULL; CEntityList entities; if (JS_GetClass(JSVAL_TO_OBJECT(argv[0])) == &CEntity::JSI_class) entities.push_back( (ToNative(argv[0])) ->me); else - entities = *EntityCollection::RetrieveSet(context, JSVAL_TO_OBJECT(argv[0])); + entities = *EntityCollection::RetrieveSet(cx, JSVAL_TO_OBJECT(argv[0])); - CNetMessage *msg=CNetMessage::CommandFromJSArgs(entities, context, argc-1, argv+1); + CNetMessage *msg = CNetMessage::CommandFromJSArgs(entities, cx, argc-1, argv+1); if (msg) { g_Console->InsertMessage(L"issueCommand: %hs", msg->GetString().c_str()); - *rval = g_ScriptingHost.UCStringToValue(msg->GetString()); - g_Game->GetSimulation()->QueueLocalCommand(msg); + *rval = g_ScriptingHost.UCStringToValue(msg->GetString()); } - else - { - *rval = JSVAL_FALSE; - } + return JS_TRUE; } + + +// Return distance between 2 points. +// params: 2 position vectors [CVector3D] +// returns: Euclidean distance [float] +JSBool v3dist( JSContext* cx, JSObject* obj, uint argc, jsval* argv, jsval* rval ) +{ + REQUIRE_PARAMS(2, v3dist); + + CVector3D* a = ToNative( argv[0] ); + CVector3D* b = ToNative( argv[1] ); + float dist = ( *a - *b ).GetLength(); + *rval = ToJSVal( dist ); + return( JS_TRUE ); +} + + +//----------------------------------------------------------------------------- +// function table +//----------------------------------------------------------------------------- + +// the JS interpreter expects the table to contain 5-tuples as follows: +// - name the function will be called as from script; +// - function which will be called; +// - number of arguments this function expects +// - Flags (deprecated, always zero) +// - Extra (reserved for future use, always zero) +// +// we simplify this a bit with a macro: +#define JS_FUNC(script_name, cpp_function, min_params) { #script_name, cpp_function, min_params, 0, 0 }, + +JSFunctionSpec ScriptFunctionTable[] = +{ + // Output + JS_FUNC(writeLog, WriteLog, 1) + JS_FUNC(writeConsole, JSI_Console::writeConsole, 1) // external + + // Entity + JS_FUNC(getEntityByHandle, getEntityByHandle, 1) + JS_FUNC(getEntityTemplate, getEntityTemplate, 1) + + // Events + JS_FUNC(addGlobalHandler, AddGlobalHandler, 2) + JS_FUNC(removeGlobalHandler, RemoveGlobalHandler, 2) + + // Timer + JS_FUNC(setTimeout, setTimeout, 2) + JS_FUNC(setInterval, setInterval, 2) + JS_FUNC(cancelInterval, cancelInterval, 0) + + // Game Setup + JS_FUNC(startGame, startGame, 0) + JS_FUNC(endGame, endGame, 0) + JS_FUNC(createClient, createClient, 0) + JS_FUNC(createServer, createServer, 0) + + // VFS (external) + JS_FUNC(buildFileList, JSI_VFS::BuildFileList, 1) + JS_FUNC(getFileMTime, JSI_VFS::GetFileMTime, 1) + JS_FUNC(getFileSize, JSI_VFS::GetFileSize, 1) + JS_FUNC(readFile, JSI_VFS::ReadFile, 1) + JS_FUNC(readFileLines, JSI_VFS::ReadFileLines, 1) + + // Internationalization + JS_FUNC(loadLanguage, loadLanguage, 1) + JS_FUNC(getLanguageID, getLanguageID, 0) + + // Debug + JS_FUNC(crash, crash, 0) + JS_FUNC(forceGC, forceGC, 0) + + // Misc. Script System + JS_FUNC(getGlobal, getGlobal, 0) + JS_FUNC(getGUIGlobal, getGUIGlobal, 0) +#ifndef NO_GUI + JS_FUNC(getGUIObjectByName, JSI_IGUIObject::getByName, 1) // external +#endif + + // Misc. Engine Interface + JS_FUNC(exit, exitProgram, 0) + JS_FUNC(vmem, vmem, 0) + JS_FUNC(_rewriteMaps, _rewriteMaps, 0) + JS_FUNC(_lodbias, _lodbias, 0) + JS_FUNC(setCursor, setCursor, 1) + JS_FUNC(setCameraTarget, setCameraTarget, 1) + JS_FUNC(getFPS, getFPS, 0) + + // Miscellany + JS_FUNC(v3dist, v3dist, 2) + JS_FUNC(issueCommand, issueCommand, 2) + JS_FUNC(buildTime, buildTime, 0) + + // end of table marker + {0, 0, 0, 0, 0} +}; +#undef JS_FUNC + + +//----------------------------------------------------------------------------- +// property accessors +//----------------------------------------------------------------------------- + +JSBool GetEntitySet( JSContext* cx, JSObject*, jsval argv, jsval* vp ) +{ + std::vector* extant = g_EntityManager.getExtant(); + + *vp = OBJECT_TO_JSVAL( EntityCollection::Create( *extant ) ); + delete( extant ); + + return( JS_TRUE ); +} + + +JSBool GetPlayerSet( JSContext* cx, JSObject*, jsval id, jsval* vp ) +{ + std::vector* players = g_Game->GetPlayers(); + + *vp = OBJECT_TO_JSVAL( PlayerCollection::Create( *players ) ); + + return( JS_TRUE ); +} + + +JSBool GetLocalPlayer( JSContext* cx, JSObject*, jsval id, jsval* vp ) +{ + *vp = OBJECT_TO_JSVAL( g_Game->GetLocalPlayer()->GetScript() ); + return( JS_TRUE ); +} + + +JSBool GetGaiaPlayer( JSContext* cx, JSObject*, jsval id, jsval* vp ) +{ + *vp = OBJECT_TO_JSVAL( g_Game->GetPlayer( 0 )->GetScript() ); + return( JS_TRUE ); +} + + +JSBool SetLocalPlayer( JSContext* cx, JSObject* obj, jsval id, jsval* vp ) +{ + CPlayer* newLocalPlayer = ToNative( *vp ); + + if( !newLocalPlayer ) + { + JS_ReportError( cx, "Not a valid Player." ); + return( JS_TRUE ); + } + + g_Game->SetLocalPlayer( newLocalPlayer ); + return( JS_TRUE ); +} + + +JSBool GetGameView( JSContext* cx, JSObject*, jsval id, jsval* vp ) +{ + if (g_Game) + *vp = OBJECT_TO_JSVAL( g_Game->GetView()->GetScript() ); + else + *vp = JSVAL_NULL; + return( JS_TRUE ); +} + + +enum ScriptGlobalTinyIDs +{ + GLOBAL_SELECTION, + GLOBAL_GROUPSARRAY, + GLOBAL_CAMERA, + GLOBAL_CONSOLE, +}; + +// shorthand +#define PERM JSPROP_PERMANENT +#define CONST JSPROP_READONLY + +JSPropertySpec ScriptGlobalTable[] = +{ + { "selection" , GLOBAL_SELECTION, PERM, JSI_Selection::getSelection, JSI_Selection::setSelection }, + { "groups" , GLOBAL_GROUPSARRAY, PERM, JSI_Selection::getGroups, JSI_Selection::setGroups }, + { "camera" , GLOBAL_CAMERA, PERM, JSI_Camera::getCamera, JSI_Camera::setCamera }, + { "console" , GLOBAL_CONSOLE, PERM | CONST, JSI_Console::getConsole, 0 }, + { "entities" , 0, PERM | CONST, GetEntitySet, 0 }, + { "players" , 0, PERM | CONST, GetPlayerSet, 0 }, + { "localPlayer", 0, PERM , GetLocalPlayer, SetLocalPlayer }, + { "gaiaPlayer" , 0, PERM | CONST, GetGaiaPlayer, 0 }, + { "gameView" , 0, PERM | CONST, GetGameView, 0 }, + + // end of table marker + { 0, 0, 0, 0, 0 }, +}; diff --git a/source/scripting/ScriptGlue.h b/source/scripting/ScriptGlue.h index 706717e4b0..23129e0c2b 100755 --- a/source/scripting/ScriptGlue.h +++ b/source/scripting/ScriptGlue.h @@ -4,84 +4,23 @@ #include "ScriptingHost.h" -typedef JSBool JSFunc(JSContext* /*context*/, JSObject* /*globalObject*/, unsigned int /*argc*/, jsval* /*argv*/, jsval* /*rval*/); - -// Functions to be called from Javascript: - -JSFunc WriteLog; - -// Entity -JSFunc getEntityByHandle; -JSFunc getEntityTemplate; -JSBool GetEntitySet( JSContext* context, JSObject* globalObject, jsval id, jsval* vp ); - -// Player -JSBool GetPlayerSet( JSContext* context, JSObject* globalObject, jsval id, jsval* vp ); -JSBool GetLocalPlayer( JSContext* context, JSObject* globalObject, jsval id, jsval* vp ); -JSBool SetLocalPlayer( JSContext* context, JSObject* globalObject, jsval id, jsval* vp ); -JSBool GetGaiaPlayer( JSContext* context, JSObject* globalObject, jsval id, jsval* vp ); -// JSBool SetGaiaPlayer( JSContext* context, JSObject* globalObject, jsval argv, jsval* vp ); - -// Events system -JSFunc AddGlobalHandler; -JSFunc RemoveGlobalHandler; - -// Camera -JSFunc setCameraTarget; - -// Timer -JSFunc setTimeout; -JSFunc setInterval; -JSFunc cancelInterval; - -// Debug -JSBool forceGC( JSContext* context, JSObject* globalObject, unsigned int argc, jsval* argv, jsval* rval ); - -// Returns the sort-of-global object associated with the current GUI -JSFunc getGUIGlobal; - -// Returns the global object, e.g. for setting global variables. -JSFunc getGlobal; - -JSFunc setCursor; - -JSBool GetGameView( JSContext* context, JSObject* globalObject, jsval id, jsval* vp ); -JSFunc GetGameObject; -JSFunc createServer; -JSFunc createClient; -JSFunc startGame; -JSFunc endGame; - -// Replaces the current language (locale) with a new one -JSFunc loadLanguage; - -// Returns the current language's name, in the same form as passed to loadLanguage -JSFunc getLanguageID; - -JSFunc getFPS; -JSFunc getCursorPosition; -JSFunc v3dist; - -JSFunc issueCommand; - -// Returns a string that says when ScriptGlue.cpp was last recompiled -JSFunc buildTime; - -// Tells the main loop to stop looping -JSFunc exitProgram; - -// Crashes. -JSFunc crash; - -// Tries to print the amount of remaining video memory. -JSFunc vmem; - -// You probably don't want to use these. (If you do, give them better names -// and document them.) -JSFunc _rewriteMaps; -JSFunc _lodbias; +#include "LightEnv.h" // required by g_LightEnv declaration below. +// referenced by ScriptingHost.cpp extern JSFunctionSpec ScriptFunctionTable[]; extern JSPropertySpec ScriptGlobalTable[]; +// dependencies (moved to header to avoid L4 warnings) +// .. from main.cpp: +extern "C" int fps; +extern void kill_mainloop(); +extern CStr g_CursorName; +extern void StartGame(); +extern void EndGame(); +// .. other +extern CLightEnv g_LightEnv; +#ifdef _WIN32 +extern int GetVRAMInfo(int&, int&); #endif + +#endif // #ifndef _SCRIPTGLUE_H_