Beispiel #1
0
template<> jsval ScriptInterface::ToJSVal<SDL_Event_>(JSContext* cx, SDL_Event_ const& val)
{
    const char* typeName;

    switch (val.ev.type)
    {
    case SDL_ACTIVEEVENT:
        typeName = "activeevent";
        break;
    case SDL_KEYDOWN:
        typeName = "keydown";
        break;
    case SDL_KEYUP:
        typeName = "keyup";
        break;
    case SDL_MOUSEMOTION:
        typeName = "mousemotion";
        break;
    case SDL_MOUSEBUTTONDOWN:
        typeName = "mousebuttondown";
        break;
    case SDL_MOUSEBUTTONUP:
        typeName = "mousebuttonup";
        break;
    case SDL_QUIT:
        typeName = "quit";
        break;
    case SDL_VIDEOEXPOSE:
        typeName = "videoexpose";
        break;
    case SDL_VIDEORESIZE:
        typeName = "videoresize";
        break;
    case SDL_HOTKEYDOWN:
        typeName = "hotkeydown";
        break;
    case SDL_HOTKEYUP:
        typeName = "hotkeyup";
        break;
    default:
        typeName = "(unknown)";
        break;
    }

    JSObject* obj = JS_NewObject(cx, NULL, NULL, NULL);
    if (! obj)
        return JSVAL_VOID;

    SET(obj, "type", typeName);

    switch (val.ev.type)
    {
    case SDL_ACTIVEEVENT:
    {
        SET(obj, "gain", (int)val.ev.active.gain);
        SET(obj, "state", (int)val.ev.active.state);
        break;
    }
    case SDL_KEYDOWN:
    case SDL_KEYUP:
    {
        // SET(obj, "which", (int)val.ev.key.which); // (not in wsdl.h)
        // SET(obj, "state", (int)val.ev.key.state); // (not in wsdl.h)

        JSObject* keysym = JS_NewObject(cx, NULL, NULL, NULL);
        if (! keysym)
            return JSVAL_VOID;
        jsval keysymVal = OBJECT_TO_JSVAL(keysym);
        JS_SetProperty(cx, obj, "keysym", &keysymVal);

        // SET(keysym, "scancode", (int)val.ev.key.keysym.scancode); // (not in wsdl.h)
        SET(keysym, "sym", (int)val.ev.key.keysym.sym);
        // SET(keysym, "mod", (int)val.ev.key.keysym.mod); // (not in wsdl.h)
        if (val.ev.key.keysym.unicode)
        {
            std::wstring unicode(1, (wchar_t)val.ev.key.keysym.unicode);
            SET(keysym, "unicode", unicode);
        }
        else
        {
            SET(keysym, "unicode", CScriptVal(JSVAL_VOID));
        }
        // TODO: scripts have no idea what all the key/mod enum values are;
        // we should probably expose them as constants if we expect scripts to use them

        break;
    }
    case SDL_MOUSEMOTION:
    {
        // SET(obj, "which", (int)val.ev.motion.which); // (not in wsdl.h)
        // SET(obj, "state", (int)val.ev.motion.state); // (not in wsdl.h)
        SET(obj, "x", (int)val.ev.motion.x);
        SET(obj, "y", (int)val.ev.motion.y);
        // SET(obj, "xrel", (int)val.ev.motion.xrel); // (not in wsdl.h)
        // SET(obj, "yrel", (int)val.ev.motion.yrel); // (not in wsdl.h)
        break;
    }
    case SDL_MOUSEBUTTONDOWN:
    case SDL_MOUSEBUTTONUP:
    {
        // SET(obj, "which", (int)val.ev.button.which); // (not in wsdl.h)
        SET(obj, "button", (int)val.ev.button.button);
        SET(obj, "state", (int)val.ev.button.state);
        SET(obj, "x", (int)val.ev.button.x);
        SET(obj, "y", (int)val.ev.button.y);
        break;
    }
    case SDL_HOTKEYDOWN:
    case SDL_HOTKEYUP:
    {
        SET(obj, "hotkey", static_cast<const char*>(val.ev.user.data1));
        break;
    }
    }

    jsval rval = OBJECT_TO_JSVAL(obj);

    return rval;
}
Beispiel #2
0
bool Autostart(const CmdLineArgs& args)
{
	/*
	 * Handle various command-line options, for quick testing of various features:
	 * -autostart=name					-- map name for scenario, or rms name for random map
	 * -autostart-ai=1:dummybot			-- adds the dummybot AI to player 1
	 * -autostart-playername=name		-- multiplayer player name
	 * -autostart-host					-- multiplayer host mode
	 * -autostart-players=2				-- number of players
	 * -autostart-client				-- multiplayer client mode
	 * -autostart-ip=127.0.0.1			-- multiplayer connect to 127.0.0.1
	 * -autostart-random=104			-- random map, optional seed value = 104 (default is 0, random is -1)
	 * -autostart-size=192				-- random map size in tiles = 192 (default is 192)
	 *
	 * Examples:
	 * -autostart=Acropolis -autostart-host -autostart-players=2		-- Host game on Acropolis map, 2 players
	 * -autostart=latium -autostart-random=-1							-- Start single player game on latium random map, random rng seed
	 */

	CStr autoStartName = args.Get("autostart");

#if OS_ANDROID
	// HACK: currently the most convenient way to test maps on Android;
	// should find a better solution
	autoStartName = "Oasis";
#endif

	if (autoStartName.empty())
	{
		return false;
	}

	g_Game = new CGame();

	ScriptInterface& scriptInterface = g_Game->GetSimulation2()->GetScriptInterface();

	CScriptValRooted attrs;
	scriptInterface.Eval("({})", attrs);
	CScriptVal settings;
	scriptInterface.Eval("({})", settings);
	CScriptVal playerData;
	scriptInterface.Eval("([])", playerData);

	// Set different attributes for random or scenario game
	if (args.Has("autostart-random"))
	{
		CStr seedArg = args.Get("autostart-random");

		// Default seed is 0
		uint32 seed = 0;
		if (!seedArg.empty())
		{
			if (seedArg.compare("-1") == 0)
			{	// Random seed value
				seed = rand();
			}
			else
			{
				seed = seedArg.ToULong();
			}
		}
		
		// Random map definition will be loaded from JSON file, so we need to parse it
		std::wstring mapPath = L"maps/random/";
		std::wstring scriptPath = mapPath + autoStartName.FromUTF8() + L".json";
		CScriptValRooted scriptData = scriptInterface.ReadJSONFile(scriptPath);
		if (!scriptData.undefined() && scriptInterface.GetProperty(scriptData.get(), "settings", settings))
		{
			// JSON loaded ok - copy script name over to game attributes
			std::wstring scriptFile;
			scriptInterface.GetProperty(settings.get(), "Script", scriptFile);
			scriptInterface.SetProperty(attrs.get(), "script", scriptFile);				// RMS filename
		}
		else
		{
			// Problem with JSON file
			LOGERROR(L"Error reading random map script '%ls'", scriptPath.c_str());
			throw PSERROR_Game_World_MapLoadFailed("Error reading random map script.\nCheck application log for details.");
		}

		// Get optional map size argument (default 192)
		uint mapSize = 192;
		if (args.Has("autostart-size"))
		{
			CStr size = args.Get("autostart-size");
			mapSize = size.ToUInt();
		}

		scriptInterface.SetProperty(attrs.get(), "map", std::string(autoStartName));
		scriptInterface.SetProperty(attrs.get(), "mapPath", mapPath);
		scriptInterface.SetProperty(attrs.get(), "mapType", std::string("random"));
		scriptInterface.SetProperty(settings.get(), "Seed", seed);									// Random seed
		scriptInterface.SetProperty(settings.get(), "Size", mapSize);								// Random map size (in patches)

		// Get optional number of players (default 2)
		size_t numPlayers = 2;
		if (args.Has("autostart-players"))
		{
			CStr num = args.Get("autostart-players");
			numPlayers = num.ToUInt();
		}

		// Set up player data
		for (size_t i = 0; i < numPlayers; ++i)
		{
			CScriptVal player;
			scriptInterface.Eval("({})", player);

			// We could load player_defaults.json here, but that would complicate the logic
			//	even more and autostart is only intended for developers anyway
			scriptInterface.SetProperty(player.get(), "Civ", std::string("athen"));
			scriptInterface.SetPropertyInt(playerData.get(), i, player);
		}
	}
	else
	{
		scriptInterface.SetProperty(attrs.get(), "map", std::string(autoStartName));
		scriptInterface.SetProperty(attrs.get(), "mapType", std::string("scenario"));
	}

	// Set player data for AIs
	//		attrs.settings = { PlayerData: [ { AI: ... }, ... ] }:
	if (args.Has("autostart-ai"))
	{
		std::vector<CStr> aiArgs = args.GetMultiple("autostart-ai");
		for (size_t i = 0; i < aiArgs.size(); ++i)
		{
			// Instead of overwriting existing player data, modify the array
			CScriptVal player;
			if (!scriptInterface.GetPropertyInt(playerData.get(), i, player) || player.undefined())
			{
				scriptInterface.Eval("({})", player);
			}

			int playerID = aiArgs[i].BeforeFirst(":").ToInt();
			CStr name = aiArgs[i].AfterFirst(":");

			scriptInterface.SetProperty(player.get(), "AI", std::string(name));
			scriptInterface.SetPropertyInt(playerData.get(), playerID-1, player);
		}
	}

	// Add player data to map settings
	scriptInterface.SetProperty(settings.get(), "PlayerData", playerData);

	// Add map settings to game attributes
	scriptInterface.SetProperty(attrs.get(), "settings", settings);

	CScriptVal mpInitData;
	g_GUI->GetScriptInterface().Eval("({isNetworked:true, playerAssignments:{}})", mpInitData);
	g_GUI->GetScriptInterface().SetProperty(mpInitData.get(), "attribs",
			CScriptVal(g_GUI->GetScriptInterface().CloneValueFromOtherContext(scriptInterface, attrs.get())));

	// Get optional playername
	CStrW userName = L"anonymous";
	if (args.Has("autostart-playername"))
	{
		userName = args.Get("autostart-playername").FromUTF8();
	}

	if (args.Has("autostart-host"))
	{
		InitPs(true, L"page_loading.xml", mpInitData.get());

		size_t maxPlayers = 2;
		if (args.Has("autostart-players"))
		{
			maxPlayers = args.Get("autostart-players").ToUInt();
		}

		g_NetServer = new CNetServer(maxPlayers);

		g_NetServer->UpdateGameAttributes(attrs.get(), scriptInterface);

		bool ok = g_NetServer->SetupConnection();
		ENSURE(ok);

		g_NetClient = new CNetClient(g_Game);
		g_NetClient->SetUserName(userName);
		g_NetClient->SetupConnection("127.0.0.1");
	}
	else if (args.Has("autostart-client"))
	{
		InitPs(true, L"page_loading.xml", mpInitData.get());

		g_NetClient = new CNetClient(g_Game);
		g_NetClient->SetUserName(userName);

		CStr ip = "127.0.0.1";
		if (args.Has("autostart-ip"))
		{
			ip = args.Get("autostart-ip");
		}

		bool ok = g_NetClient->SetupConnection(ip);
		ENSURE(ok);
	}
	else
	{
		g_Game->SetPlayerID(1);
		g_Game->StartGame(attrs, "");

		LDR_NonprogressiveLoad();

		PSRETURN ret = g_Game->ReallyStartGame();
		ENSURE(ret == PSRETURN_OK);

		InitPs(true, L"page_session.xml", JSVAL_VOID);
	}

	return true;
}
Beispiel #3
0
template<> void ScriptInterface::ToJSVal<SDL_Event_>(JSContext* cx, JS::Value& ret, SDL_Event_ const& val)
{
	JSAutoRequest rq(cx);
	const char* typeName;

	switch (val.ev.type)
	{
#if SDL_VERSION_ATLEAST(2, 0, 0)
	case SDL_WINDOWEVENT: typeName = "windowevent"; break;
#else
	case SDL_ACTIVEEVENT: typeName = "activeevent"; break;
	case SDL_VIDEOEXPOSE: typeName = "videoexpose"; break;
	case SDL_VIDEORESIZE: typeName = "videoresize"; break;
#endif
	case SDL_KEYDOWN: typeName = "keydown"; break;
	case SDL_KEYUP: typeName = "keyup"; break;
	case SDL_MOUSEMOTION: typeName = "mousemotion"; break;
	case SDL_MOUSEBUTTONDOWN: typeName = "mousebuttondown"; break;
	case SDL_MOUSEBUTTONUP: typeName = "mousebuttonup"; break;
	case SDL_QUIT: typeName = "quit"; break;
	case SDL_HOTKEYDOWN: typeName = "hotkeydown"; break;
	case SDL_HOTKEYUP: typeName = "hotkeyup"; break;
	default: typeName = "(unknown)"; break;
	}

	JSObject* obj = JS_NewObject(cx, NULL, NULL, NULL);
	if (! obj)
	{
		ret = JSVAL_VOID;
		return;
	}

	SET(obj, "type", typeName);

	switch (val.ev.type)
	{
#if !SDL_VERSION_ATLEAST(2, 0, 0)
	case SDL_ACTIVEEVENT:
	{
		SET(obj, "gain", (int)val.ev.active.gain);
		SET(obj, "state", (int)val.ev.active.state);
		break;
	}
#endif
	case SDL_KEYDOWN:
	case SDL_KEYUP:
	{
		// SET(obj, "which", (int)val.ev.key.which); // (not in wsdl.h)
		// SET(obj, "state", (int)val.ev.key.state); // (not in wsdl.h)

		JSObject* keysym = JS_NewObject(cx, NULL, NULL, NULL);
		if (! keysym)
		{
			ret = JSVAL_VOID;
			return;
		}
		JS::RootedValue keysymVal(cx, JS::ObjectValue(*keysym));
		JS_SetProperty(cx, obj, "keysym", keysymVal.address());

		// SET(keysym, "scancode", (int)val.ev.key.keysym.scancode); // (not in wsdl.h)
		SET(keysym, "sym", (int)val.ev.key.keysym.sym);
		// SET(keysym, "mod", (int)val.ev.key.keysym.mod); // (not in wsdl.h)
		if (val.ev.key.keysym.unicode)
		{
			std::wstring unicode(1, (wchar_t)val.ev.key.keysym.unicode);
			SET(keysym, "unicode", unicode);
		}
		else
		{
			SET(keysym, "unicode", CScriptVal(JSVAL_VOID));
		}
		// TODO: scripts have no idea what all the key/mod enum values are;
		// we should probably expose them as constants if we expect scripts to use them

		break;
	}
	case SDL_MOUSEMOTION:
	{
		// SET(obj, "which", (int)val.ev.motion.which); // (not in wsdl.h)
		// SET(obj, "state", (int)val.ev.motion.state); // (not in wsdl.h)
		SET(obj, "x", (int)val.ev.motion.x);
		SET(obj, "y", (int)val.ev.motion.y);
		// SET(obj, "xrel", (int)val.ev.motion.xrel); // (not in wsdl.h)
		// SET(obj, "yrel", (int)val.ev.motion.yrel); // (not in wsdl.h)
		break;
	}
	case SDL_MOUSEBUTTONDOWN:
	case SDL_MOUSEBUTTONUP:
	{
		// SET(obj, "which", (int)val.ev.button.which); // (not in wsdl.h)
		SET(obj, "button", (int)val.ev.button.button);
		SET(obj, "state", (int)val.ev.button.state);
		SET(obj, "x", (int)val.ev.button.x);
		SET(obj, "y", (int)val.ev.button.y);
		break;
	}
	case SDL_HOTKEYDOWN:
	case SDL_HOTKEYUP:
	{
		SET(obj, "hotkey", static_cast<const char*>(val.ev.user.data1));
		break;
	}
	}

	ret = JS::ObjectValue(*obj);
}