Example #1
0
bool
Track::Private::play(int _iterations)
{
	/* sanity checks */
	if (_iterations == 0) {
		MMDEBUG("Trying to play track with no iterations");
		if (iterations) stop();
		return(false);
	}
	else if (iterations) {
		MMERROR("Track already playing!");
		return(false);
	}

	iterations = _iterations;
	skip_decode = false;
	codec->reset();

	bsize = pcm->bufferSize();
	buffer = new char[bsize];

	update();

	return(true);
}
Example #2
0
bool
TMXLoader::Private::processTileset(XMLElement &e)
{
	int l_first_gid;
	const char *l_name;
	int l_tile_width;
	int l_tile_height;
	int l_tile_margin = 0;
	int l_tile_spacing = 0;

	if ((XML_SUCCESS != e.QueryIntAttribute("firstgid", &l_first_gid))
	 || (!(l_name = e.Attribute("name")))
	 || (XML_SUCCESS != e.QueryIntAttribute("tilewidth", &l_tile_width))
	 || (XML_SUCCESS != e.QueryIntAttribute("tileheight", &l_tile_height))) {
		MMWARNING("Tileset element is missing one or more required attributes.");
		return(false);
	}

	/* check for margin and spacing */
	MMIGNORE e.QueryIntAttribute("margin", &l_tile_margin);
	MMIGNORE e.QueryIntAttribute("spacing", &l_tile_spacing);

	XMLElement *l_image = e.FirstChildElement(TMXTILESET_IMAGE_NODE);
	if (!l_image) {
		MMWARNING("Tileset element is missing an image element.");
		return(false);
	}

	/*
	 * Texture sources are required to be relative to TMX file.
	 *  - So say we all.
	 */
	const std::string l_source =
	    base_directory + "/" + l_image->Attribute("source");

#if 0   // TODO(gamaral) use transparent color.
	const char *l_trans = l_image->Attribute("trans");
	(void) l_trans;
#endif

	Graphics::SharedTextureData l_texture = Graphics::Factory::CreateTextureData();
	if (!l_texture->load(l_source)) {
		MMERROR("Failed to load tileset texture.");
		return(false);
	}

	Graphics::Tileset *l_tileset = new Graphics::Tileset;
	l_tileset->setName(l_name);
	l_tileset->setMargin(l_tile_margin);
	l_tileset->setSpacing(l_tile_spacing);
	l_tileset->setTileSize(Math::Size2i(l_tile_width, l_tile_height));
	l_tileset->setTextureData(l_texture);
	tilesets[static_cast<uint16_t>(l_first_gid)] = l_tileset;

	return(true);
}
Example #3
0
void
Track::setCodec(const Audio::SharedCodec &_codec)
{
	if (isPlaying()) {
		MMERROR("Tried to replace codec of a playing track!");
		return;
	}

	m_p->codec = _codec;
}
Example #4
0
void
Track::setPCM(const Audio::WeakPCM &_pcm)
{
	if (isPlaying()) {
		MMERROR("Tried to replace PCM of a playing track!");
		return;
	}

	m_p->pcm = _pcm;
}
Example #5
0
MARSHMALLOW_NAMESPACE_USE

static void
SignalHandler(int signal, siginfo_t *siginfo, void *context)
{
	MMUNUSED(signal);
	MMUNUSED(siginfo);
	MMUNUSED(context);

	if (!Event::EventManager::Instance()) {
		MMERROR("\n*** Unix system signal received. But can't queueing quit event message yet... Ignoring. ***\n");
		return;
	}

	MMDEBUG("\n*** Unix system signal received. Queueing quit event message. ***\n");
	Event::SharedEvent l_event = new Event::QuitEvent;
	Event::EventManager::Instance()->queue(l_event);
}
void
PlayerEntity::update(float d)
{
	if (!m_init) {
		Game::SharedSizeComponent l_size_component =
		    getComponentType(Game::SizeComponent::Type()).staticCast<Game::SizeComponent>();
		if (!l_size_component) {
			MMERROR("Player entity requires a size component to be present");
			return;
		}

		m_animation_component =
		    new Game::AnimationComponent("animation", *this);

		m_animation_component->pushFrame("stand-left",  115, 12);
		m_animation_component->pushFrame("stand-left",  116, 4);
		m_animation_component->pushFrame("stand-right", 111, 12);
		m_animation_component->pushFrame("stand-right", 112, 4);

		m_animation_component->pushFrame("walk-left", 117, 1);
		m_animation_component->pushFrame("walk-left", 118, 1);
		m_animation_component->setFrameRate("walk-left", 16);
		m_animation_component->pushFrame("walk-right", 113, 1);
		m_animation_component->pushFrame("walk-right", 114, 1);
		m_animation_component->setFrameRate("walk-right", 16);

		m_animation_component->pushFrame("jump-left", 118, 1);
		m_animation_component->setFrameRate("jump-left", 1);
		m_animation_component->pushFrame("jump-right", 113, 1);
		m_animation_component->setFrameRate("jump-right", 1);

		m_animation_component->pushFrame("dying", 126, 1);
		m_animation_component->pushFrame("dying", 127, 1);

		pushComponent(m_animation_component.staticCast<Game::IComponent>());

		/* movement component */
		m_movement_component =
		    new Game::MovementComponent("movement", *this);
		pushComponent(m_movement_component.staticCast<Game::IComponent>());

		/* collider component */
		m_collider_component =
		    new ActorColliderComponent("collider", *this);
		pushComponent(m_collider_component.staticCast<Game::IComponent>());

		/* input component */
		m_input_component = new InputComponent("input", *this);
		pushComponent(m_input_component.staticCast<Game::IComponent>());

		m_direction = -1;

		m_init = true;
	}

	/*
	 * XXX(gamaral): Most of this needs to be moved elsewhere.
	 */
	else if (m_input_component->isEnabled()) {
		/* make camera follow player */
		Game::SharedPositionComponent l_pos_component =
		    getComponentType(Game::PositionComponent::Type()).staticCast<Game::PositionComponent>();
		if (l_pos_component) {
			Math::Point2 l_pos = l_pos_component->position();
			const Math::Size2f &l_zoom = Graphics::Camera::Zoom();

			if (m_input_component->inMotion()) {
				const float l_lratio = m_input_component->linearRatio();
				m_animation_component->setPlaybackRatio(l_lratio < 0 ? -l_lratio : l_lratio);
			}
			else m_animation_component->setPlaybackRatio(1.f);

			void setFrameRate(const Core::Identifier &animation, float fps);
			/* camara snap - calculate using map */

			float l_limit;
			Game::SharedTilemapSceneLayer l_platform_layer =
			    Game::Engine::Instance()->sceneManager()->activeScene()->getLayer("platform").staticCast<Game::TilemapSceneLayer>();
			const Math::Size2f &l_hrsize = l_platform_layer->virtualHalfSize();

			l_limit = l_hrsize.width - (Graphics::Viewport::Size().width / (2.f * l_zoom.width));
			if (l_pos.x < -l_limit) l_pos.x = -l_limit;
			else if (l_pos.x > l_limit) l_pos.x = l_limit;
			l_limit = l_hrsize.height - (Graphics::Viewport::Size().height / (2.f * l_zoom.height));
			if (l_pos.y < -l_limit) l_pos.y = -l_limit;
			else if (l_pos.y > l_limit) l_pos.y = l_limit;

			Graphics::Camera::SetPosition(l_pos);

			/* translate background layers (parallax) */

			Game::SharedTilemapSceneLayer l_clouds =
			    Game::Engine::Instance()->sceneManager()->activeScene()->
			        getLayer("clouds").staticCast<Game::TilemapSceneLayer>();
			if (l_clouds) {
				if ((m_moving_sky += 8.f * d) > l_clouds->virtualSize().area())
					m_moving_sky = 8.f * d;
				l_clouds->setTranslation(Math::Vector2(m_moving_sky + (l_pos.x * .15f), m_moving_sky));
			}

			Game::SharedTilemapSceneLayer l_cloudbg =
			    Game::Engine::Instance()->sceneManager()->activeScene()->
			        getLayer("cloudbg").staticCast<Game::TilemapSceneLayer>();
			if (l_cloudbg) {
				if ((m_moving_sky_bg += 2.f * d) > l_cloudbg->virtualSize().area())
					m_moving_sky_bg = 2.f * d;
				l_cloudbg->setTranslation(Math::Vector2(m_moving_sky_bg + (l_pos.x * .05f), m_moving_sky_bg));
			}

		}

		/* update animation */
		switch(m_input_component->direction()) {

		case InputComponent::ICDLeft:
			if (m_direction == InputComponent::ICDLeft
			 && m_in_motion == m_input_component->inMotion()
			 && m_on_platform == m_collider_component->onPlatform())
				break;

			m_direction = InputComponent::ICDLeft;
			m_in_motion = m_input_component->inMotion();
			m_on_platform = m_collider_component->onPlatform();

			if (m_on_platform) {
				if (m_in_motion)
					m_animation_component->play("walk-left", true);
				else
					m_animation_component->play("stand-left", true);
			} else m_animation_component->play("jump-left", true);
			break;

		case InputComponent::ICDRight:
			if (m_direction == InputComponent::ICDRight
			 && m_in_motion == m_input_component->inMotion()
			 && m_on_platform == m_collider_component->onPlatform())
				break;

			m_direction = InputComponent::ICDRight;
			m_in_motion = m_input_component->inMotion();
			m_on_platform = m_collider_component->onPlatform();

			if (m_on_platform) {
				if (m_in_motion)
					m_animation_component->play("walk-right", true);
				else
					m_animation_component->play("stand-right", true);
			} else m_animation_component->play("jump-right", true);
			break;

		default: break;
		}
	}

	Game::EntityBase::update(d);
}
Example #7
0
LRESULT CALLBACK MixerPlus_MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	static HMIXER hMixer = NULL;
	static DWORD dwLines = 0;						// Must always count plinfo correctly
	static PMIXERPLUS_INFO pinfo = NULL;
	static PMIXERPLUS_LINE_INFO plinfo = NULL;		// Array
	static HWND hCFader = NULL;

	static DWORD dwControlFlags = 0;
	static MIXERLINE mxlineDest;
	static MIXERPLUS_CONTROL_FEED feed;

	UINT i, j;
	RECT rcCtrl, rcCFader, rcWnd;
	SCROLLINFO si;
	MIXERCAPS mxcaps;
	MIXERLINE mxlineSrc;
	MIXERLINECONTROLS mxlctls;
	MIXERCONTROL mxctl;
	MIXERCONTROLDETAILS mxcdtls;
	TCHAR szTitle[MIXERPLUS_MAX_TITLE];

	switch(uMsg)
	{
		case MM_MIXM_LINE_CHANGE:

			for(i = 0; i < dwLines; i++)
				if(((DWORD) lParam) == plinfo[i].dwLineID)
				{
					SendMessage(plinfo[i].hCtrl, uMsg, wParam, lParam);
					return 0;
				}

			break;

		case MM_MIXM_CONTROL_CHANGE:

			for(i = 0; i < dwLines; i++)
			{
				/* Check if child contains control for which this message is intended */
				if(((plinfo[i].dwControlFlags & MIXERPLUS_LINE_CONTROL_VOLUME)
					&& ((DWORD) lParam) == plinfo[i].volume.dwID)
					|| ((plinfo[i].dwControlFlags & MIXERPLUS_LINE_CONTROL_MUTE)
					&& ((DWORD) lParam) == plinfo[i].mute.dwID))
				{
					SendMessage(plinfo[i].hCtrl, uMsg, wParam, lParam);
					return 0;
				}
			}

			if((dwControlFlags & MIXERPLUS_LINE_CONTROL_FEED)
				&& (((DWORD) lParam) == feed.dwID))
			{
				mxlctls.cbStruct = sizeof(mxlctls);
				mxlctls.cbmxctrl = sizeof(mxctl);
				mxlctls.dwControlID = feed.dwID;
				mxlctls.pamxctrl = &mxctl;

				if(MMERROR(mixerGetLineControls((HMIXEROBJ) hMixer,
													&mxlctls,
													MIXER_GETLINECONTROLSF_ONEBYID)))
				{
					return 0;
				}

				if(feed.dwSources != mxctl.cMultipleItems)
				{
					/* Reallocate */
					HeapFree(pinfo->hHeap, 0, feed.pmxcdtls_lt);
					HeapFree(pinfo->hHeap, 0, feed.pmxcdtls_b);

					feed.pmxcdtls_lt =
						(LPMIXERCONTROLDETAILS_LISTTEXT) HeapAlloc(pinfo->hHeap, 0,
							mxctl.cMultipleItems * sizeof(MIXERCONTROLDETAILS_LISTTEXT));

					feed.pmxcdtls_b =
						(LPMIXERCONTROLDETAILS_BOOLEAN) HeapAlloc(pinfo->hHeap, 0,
							mxctl.cMultipleItems * sizeof(MIXERCONTROLDETAILS_BOOLEAN));

					if(!feed.pmxcdtls_lt || !feed.pmxcdtls_b)
					{
						dwControlFlags &= ~MIXERPLUS_LINE_CONTROL_FEED;
						MixerPlus_ErrorBox(hWnd, TEXT("Cannot allocate memory. Check available memory."));
						DestroyWindow(hWnd);
						return 0;
					}

					feed.dwSources = mxctl.cMultipleItems;
				}

				mxcdtls.cbStruct = sizeof(mxcdtls);
				mxcdtls.cbDetails = sizeof(MIXERCONTROLDETAILS_LISTTEXT);
				mxcdtls.dwControlID = feed.dwID;
				mxcdtls.cMultipleItems = feed.dwSources;
				mxcdtls.cChannels = 1;
				mxcdtls.paDetails = feed.pmxcdtls_lt;

				if(MMERROR(mixerGetControlDetails((HMIXEROBJ) hMixer,
													&mxcdtls,
													MIXER_GETCONTROLDETAILSF_LISTTEXT)))
				{
					return 0;
				}

				mxcdtls.cbStruct = sizeof(mxcdtls);
				mxcdtls.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN);
				mxcdtls.dwControlID = feed.dwID;
				mxcdtls.cMultipleItems = feed.dwSources;
				mxcdtls.cChannels = 1;
				mxcdtls.paDetails = feed.pmxcdtls_b;

				if(MMERROR(mixerGetControlDetails((HMIXEROBJ) hMixer,
													&mxcdtls,
													MIXER_GETCONTROLDETAILSF_VALUE)))
				{
					return 0;
				}

				for(i = 0; i < dwLines; i++)
				for(j = 0; j < feed.dwSources; j++)
					if(plinfo[i].dwLineID == feed.pmxcdtls_lt[j].dwParam1)
						CheckDlgButton(plinfo[i].hCtrl,
										IDB_POWER,
										feed.pmxcdtls_b[j].fValue ? BST_CHECKED : BST_UNCHECKED);
			}

			break;

		case WM_HSCROLL:

			/* Get scroll position */
			si.cbSize = sizeof(si);
			si.fMask = SIF_ALL;
			GetScrollInfo(hWnd, SB_HORZ, &si);

			/* Adjust */
			switch(LOWORD(wParam))
			{
				case SB_THUMBTRACK: si.nPos = si.nTrackPos; break;
				case SB_LINELEFT:
				case SB_PAGELEFT:
					si.nPos--; break;
				case SB_LINERIGHT:
				case SB_PAGERIGHT:
					si.nPos++; break;
				case SB_LEFT: si.nPos = si.nMin; break;
				case SB_RIGHT: si.nPos = si.nMax; break;
			}

			SetScrollInfo(hWnd, SB_HORZ, &si, TRUE);

			/* Allow for adjustments by Windows */
			si.cbSize = sizeof(si);
			si.fMask = SIF_POS;
			GetScrollInfo(hWnd, SB_HORZ, &si);

			/* Move child windows */
			for(i = 0; i < dwLines; i++)
			{
				GetWindowRect(plinfo[i].hCtrl, &rcCtrl);
				MoveWindow(plinfo[i].hCtrl,
							(i - si.nPos) * (rcCtrl.right - rcCtrl.left), 0,
							(rcCtrl.right - rcCtrl.left), (rcCtrl.bottom - rcCtrl.top),
							TRUE);
			}

			return TRUE;

		case WM_COMMAND:

			/* Passed from crossfader */
			if(LOWORD(wParam) == IDB_FADE && HIWORD(wParam) == BN_CLICKED)
			{
				/* Get indices */
				i = (DWORD) SendDlgItemMessage(hCFader,
												IDC_SOURCE,
												CB_GETCURSEL,
												0, 0);

				j = (DWORD) SendDlgItemMessage(hCFader,
												IDC_TARGET,
												CB_GETCURSEL,
												0, 0);

				/* Do nothing if source is target */
				if(i == j)
					return TRUE;

				/* Start faders */
				SendMessage(plinfo[i].hCtrl,
								WM_COMMAND,
								MAKEWPARAM(IDB_FADEOUT, BN_CLICKED),
								(LPARAM) GetDlgItem(plinfo[i].hCtrl, IDB_FADEOUT));

				SendMessage(plinfo[j].hCtrl,
								WM_COMMAND,
								MAKEWPARAM(IDB_FADEIN, BN_CLICKED),
								(LPARAM) GetDlgItem(plinfo[j].hCtrl, IDB_FADEIN));

				return TRUE;
			}

			/* Passed from feed button */
			else if((dwControlFlags & MIXERPLUS_LINE_CONTROL_FEED)
					&& LOWORD(wParam) == IDB_POWER && HIWORD(wParam) == BN_CLICKED)
			{
				mxcdtls.cbStruct = sizeof(mxcdtls);
				mxcdtls.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN);
				mxcdtls.dwControlID = feed.dwID;
				mxcdtls.cMultipleItems = feed.dwSources;
				mxcdtls.cChannels = 1;
				mxcdtls.paDetails = feed.pmxcdtls_b;

				for(i = 0; i < dwLines; i++)
					if(((HWND) lParam) == GetDlgItem(plinfo[i].hCtrl, IDB_POWER))
					{
						for(j = 0; j < feed.dwSources; j++)
							if(plinfo[i].dwLineID == feed.pmxcdtls_lt[j].dwParam1)
							{
								ZeroMemory(feed.pmxcdtls_b, feed.dwSources * sizeof(MIXERCONTROLDETAILS_BOOLEAN));
								feed.pmxcdtls_b[j].fValue = !(IsDlgButtonChecked(plinfo[i].hCtrl, IDB_POWER) == BST_CHECKED);

								mixerSetControlDetails((HMIXEROBJ) hMixer,
														&mxcdtls,
														MIXER_SETCONTROLDETAILSF_VALUE);

								return TRUE;
							}

						break;
					}

				return TRUE;
			}

			switch(LOWORD(wParam))
			{
				case ID_FILE_EXIT:

					SendMessage(hWnd, WM_CLOSE, 0, 0);
					return 0;

				case ID_TOOLS_OPTIONS:

					/* Show options dialog box */
					if(DialogBoxParam(pinfo->hInstance,
										MAKEINTRESOURCE(IDD_OPTIONS),
										hWnd,
										(DLGPROC) MixerPlus_OptionsDlgProc,
										(LPARAM) pinfo) != IDOK)
					{
						return TRUE;
					}

					/* Destroy everything */
					for(i = 0; i < dwLines; i++)
						DestroyWindow(plinfo[i].hCtrl);

					if(hCFader)
					{
						DestroyWindow(hCFader);
						hCFader = NULL;
					}

					if(dwControlFlags & MIXERPLUS_LINE_CONTROL_FEED)
					{
						dwControlFlags &= ~MIXERPLUS_LINE_CONTROL_FEED;
						HeapFree(pinfo->hHeap, 0, feed.pmxcdtls_lt);
						HeapFree(pinfo->hHeap, 0, feed.pmxcdtls_b);
					}

					if(plinfo)
					{
						HeapFree(pinfo->hHeap, 0, plinfo);
						plinfo = NULL;
						dwLines = 0;
					}

					if(hMixer)
					{
						mixerClose(hMixer);
						hMixer = NULL;
					}

					/* Recreate */
					SendMessage(hWnd,
								WM_CREATE,
								0,
								0);		// Do not need to set this since pinfo not NULL

					return 0;

				case ID_HELP_ABOUT:

					MessageBox(hWnd,
								TEXT("Mixer Plus v0.2\n\nWritten by John Peloquin"),
								TEXT("Mixer Plus"),
								MB_ICONINFORMATION);

					return 0;
			}

			break;

		case WM_CREATE:

			/* NOTE: This message is also simulated when the user changes options */

			/* Get init info if we do not aleady have it */
			if(!pinfo)
				pinfo = (PMIXERPLUS_INFO)(((LPCREATESTRUCT) lParam)->lpCreateParams);

			/* Open mixer device */
			if(MMERROR(mixerOpen(&hMixer,
									pinfo->dwMixerID,
									(DWORD_PTR) hWnd, 0,
									MIXER_OBJECTF_MIXER | CALLBACK_WINDOW)))
			{
				MixerPlus_ErrorBox(hWnd, TEXT("Cannot open mixer device."));
				return 0;
			}

			if(!MMERROR(mixerGetDevCaps((UINT) hMixer, &mxcaps, sizeof(mxcaps))))
			{
				if(SUCCEEDED(StringCchPrintf(szTitle,
												LENGTHOF(szTitle),
												TEXT("Mixer Plus [%s - %s]"),
												mxcaps.szPname,
												(pinfo->mode == MIXERPLUS_MODE_PLAYBACK) ? TEXT("Playback") : TEXT("Recording"))))
				{
					SetWindowText(hWnd, szTitle);
				}
			}

			/* Get mixer destination line info */
			mxlineDest.cbStruct = sizeof(mxlineDest);
			mxlineDest.dwComponentType = (pinfo->mode == MIXERPLUS_MODE_PLAYBACK) ?
											MIXERLINE_COMPONENTTYPE_DST_SPEAKERS :
											MIXERLINE_COMPONENTTYPE_DST_WAVEIN;

			if(MMERROR(mixerGetLineInfo((HMIXEROBJ) hMixer,
											&mxlineDest,
											MIXER_GETLINEINFOF_COMPONENTTYPE)))
			{
				mixerClose(hMixer);
				MixerPlus_ErrorBox(hWnd, TEXT("Cannot open mixer destination line."));
				return 0;
			}

			/* The output destination line also has volume and other controls, so
				we wish to treat it like a source line. We do not do this for the
				recording destination line */
			dwLines = mxlineDest.cConnections
						+ ((pinfo->mode == MIXERPLUS_MODE_PLAYBACK) ? 1 : 0);

			/* Allocate info block memory for destination line and its associated source lines */
			if(!(plinfo = HeapAlloc(pinfo->hHeap,
										HEAP_ZERO_MEMORY,	// This is necessary!
										dwLines * sizeof(MIXERPLUS_LINE_INFO))))
			{
				mixerClose(hMixer);
				MixerPlus_ErrorBox(hWnd, TEXT("Cannot allocate memory. Check available memory."));
				return -1;
			}

			/* Create crossfader */
			if(dwLines > 0)
			{
				hCFader = CreateDialog(pinfo->hInstance,
											MAKEINTRESOURCE(IDD_CROSSFADER),
											hWnd,
											(DLGPROC) MixerPlus_CFaderDlgProc);
			}

			if(pinfo->mode == MIXERPLUS_MODE_PLAYBACK)
			{
				/* Put output destination line info at beginning of array */
				i = 0;
				plinfo[i].mode = pinfo->mode;
				plinfo[i].hHeap = pinfo->hHeap;
				plinfo[i].hMixer = hMixer;
				plinfo[i].dwLineID = mxlineDest.dwLineID;
				plinfo[i].dwChannels = mxlineDest.cChannels;
				StringCchCopy(plinfo[i].szName,
								LENGTHOF(plinfo[i].szName),
								mxlineDest.szName);

				/* Add to crossfader lists */
				SendDlgItemMessage(hCFader,
									IDC_SOURCE,
									CB_ADDSTRING,
									0,
									(LPARAM) plinfo[i].szName);

				SendDlgItemMessage(hCFader,
									IDC_TARGET,
									CB_ADDSTRING,
									0,
									(LPARAM) plinfo[i].szName);

				/* Create its child window */
				if(plinfo[i].hCtrl = CreateDialogParam(pinfo->hInstance,
														MAKEINTRESOURCE(IDD_MIXERCTRL),
														hWnd,
														(DLGPROC) MixerPlus_CtrlDlgProc,
														(LPARAM) &plinfo[i]))
				{
					ShowWindow(plinfo[i].hCtrl, SW_SHOW);
				}
			}

			/* Get ahold of selection control for recording destination line */
			else
			{
				mxlctls.cbStruct = sizeof(mxlctls);
				mxlctls.cbmxctrl = sizeof(mxctl);
				mxlctls.dwLineID = mxlineDest.dwLineID;
				mxlctls.dwControlType = MIXERCONTROL_CONTROLTYPE_MUX;
				mxlctls.pamxctrl = &mxctl;

				if(!MMERROR(mixerGetLineControls((HMIXEROBJ) hMixer,
													&mxlctls,
													MIXER_GETLINECONTROLSF_ONEBYTYPE)))
				{
					feed.pmxcdtls_lt =
						(LPMIXERCONTROLDETAILS_LISTTEXT) HeapAlloc(pinfo->hHeap, 0,
							mxctl.cMultipleItems * sizeof(MIXERCONTROLDETAILS_LISTTEXT));

					feed.pmxcdtls_b =
						(LPMIXERCONTROLDETAILS_BOOLEAN) HeapAlloc(pinfo->hHeap, 0,
							mxctl.cMultipleItems * sizeof(MIXERCONTROLDETAILS_BOOLEAN));

					if(!feed.pmxcdtls_lt || !feed.pmxcdtls_b)
					{
						mixerClose(hMixer);
						MixerPlus_ErrorBox(hWnd, TEXT("Cannot allocate memory. Check available memory."));
						return -1;
					}

					dwControlFlags |= MIXERPLUS_LINE_CONTROL_FEED;
					feed.dwID = mxctl.dwControlID;
					feed.dwSources = mxctl.cMultipleItems;
				}
			}

			/* Get source line info and create child windows */
			for(i = 0; i < mxlineDest.cConnections; i++)
			{
				j = (pinfo->mode == MIXERPLUS_MODE_PLAYBACK) ? i + 1 : i;

				mxlineSrc.cbStruct = sizeof(mxlineSrc);
				mxlineSrc.dwDestination = mxlineDest.dwDestination;
				mxlineSrc.dwSource = i;
				mixerGetLineInfo((HMIXEROBJ) hMixer, &mxlineSrc, MIXER_GETLINEINFOF_SOURCE);

				plinfo[j].mode = pinfo->mode;
				plinfo[j].hHeap = pinfo->hHeap;
				plinfo[j].hMixer = hMixer;
				plinfo[j].dwLineID = mxlineSrc.dwLineID;
				plinfo[j].dwChannels = mxlineSrc.cChannels;
				StringCchCopy(plinfo[j].szName,
								LENGTHOF(plinfo[j].szName),
								mxlineSrc.szName);

				/* Add to crossfader lists */
				SendDlgItemMessage(hCFader,
									IDC_SOURCE,
									CB_ADDSTRING,
									0,
									(LPARAM) plinfo[j].szName);

				SendDlgItemMessage(hCFader,
									IDC_TARGET,
									CB_ADDSTRING,
									0,
									(LPARAM) plinfo[j].szName);

				if(plinfo[j].hCtrl = CreateDialogParam(pinfo->hInstance,
														MAKEINTRESOURCE(IDD_MIXERCTRL),
														hWnd,
														(DLGPROC) MixerPlus_CtrlDlgProc,
														(LPARAM) &plinfo[j]))
				{
					if(dwControlFlags & MIXERPLUS_LINE_CONTROL_FEED)
					{
						SetDlgItemText(plinfo[j].hCtrl, IDB_POWER, TEXT("Feed"));
						EnableWindow(GetDlgItem(plinfo[j].hCtrl, IDB_POWER), TRUE);
					}

					GetWindowRect(plinfo[j].hCtrl, &rcCtrl);
					MoveWindow(plinfo[j].hCtrl,
								j * (rcCtrl.right - rcCtrl.left), 0,
								rcCtrl.right - rcCtrl.left, rcCtrl.bottom - rcCtrl.top,
								FALSE);

					ShowWindow(plinfo[j].hCtrl, SW_SHOW);
				}
			}

			/* Adjust window */
			if(dwLines > 0 && hCFader)
			{
				/* Simulate feed control update if necessary */
				if(dwControlFlags & MIXERPLUS_LINE_CONTROL_FEED)
					SendMessage(hWnd,
								MM_MIXM_CONTROL_CHANGE,
								(WPARAM) hMixer,
								(LPARAM) feed.dwID);

				/* Initialize crossfader */
				SendDlgItemMessage(hCFader,
									IDC_SOURCE,
									CB_SETCURSEL,
									0, 0);

				SendDlgItemMessage(hCFader,
									IDC_TARGET,
									CB_SETCURSEL,
									0, 0);

				GetWindowRect(hCFader, &rcCFader);
				MoveWindow(hCFader,
							0, rcCtrl.bottom - rcCtrl.top,
							rcCFader.right - rcCFader.left, rcCFader.bottom - rcCFader.top,
							FALSE);

				ShowWindow(hCFader, SW_SHOW);

				/* Resize main window */
				rcWnd.left = 0;
				rcWnd.top = 0;
				rcWnd.right = MIXERPLUS_LINES_PER_VIEW * (rcCtrl.right - rcCtrl.left);
				rcWnd.bottom = (rcCtrl.bottom - rcCtrl.top) + (rcCFader.bottom - rcCFader.top);
				AdjustWindowRect(&rcWnd, WS_CAPTION, TRUE);
				rcWnd.bottom += GetSystemMetrics(SM_CYHSCROLL);

				SetWindowPos(hWnd,
								HWND_TOP,
								0, 0,
								rcWnd.right - rcWnd.left,
								rcWnd.bottom - rcWnd.top,
								SWP_NOMOVE);

				/* Set scroll range and position */
				si.cbSize = sizeof(si);
				si.fMask = SIF_RANGE | SIF_POS;
				si.nMin = 0;
				si.nMax = max(0, dwLines - MIXERPLUS_LINES_PER_VIEW);
				si.nPos = 0;
				SetScrollInfo(hWnd, SB_HORZ, &si, TRUE);
			}

			return 0;

		case WM_DESTROY:

			if(dwControlFlags & MIXERPLUS_LINE_CONTROL_FEED)
			{
				HeapFree(pinfo->hHeap, 0, feed.pmxcdtls_lt);
				HeapFree(pinfo->hHeap, 0, feed.pmxcdtls_b);
			}

			/* BUG FIX: intermittent access violation on exit.
				
				Do not free plinfo here, as the child windows
				reference it during their WM_DESTROY processing,
				occurs after this (see MSDN).
				
				This is not a huge leak, as the heap is destroyed
				immediately after the message loop.
			*/

			/*
			if(plinfo)
				HeapFree(pinfo->hHeap, 0, plinfo);
			*/

			if(hMixer)
				mixerClose(hMixer);

			/* Kill message loop */
			PostQuitMessage(0);
			return 0;
	}

	/* Pass message to default handler */
	return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
Example #8
0
BOOL CALLBACK MixerPlus_OptionsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	static PMIXERPLUS_INFO pinfo = NULL;

	UINT i;
	MIXERCAPS mxcaps;

	switch(uMsg)
	{
		case WM_COMMAND:

			switch(LOWORD(wParam))
			{
				case IDOK:

					pinfo->dwMixerID = (DWORD) SendDlgItemMessage(hDlg,
																	IDC_DEVICE,
																	CB_GETCURSEL, 0, 0);

					if(IsDlgButtonChecked(hDlg, IDC_MODE_PLAYBACK) == BST_CHECKED)
						pinfo->mode = MIXERPLUS_MODE_PLAYBACK;

					else pinfo->mode = MIXERPLUS_MODE_RECORDING;

					EndDialog(hDlg, IDOK);
					return TRUE;

				case IDCANCEL:

					EndDialog(hDlg, IDCANCEL);
					return TRUE;
			}

			break;

		case WM_INITDIALOG:

			pinfo = (PMIXERPLUS_INFO) lParam;

			for(i = 0; i < mixerGetNumDevs(); i++)
				if(!MMERROR(mixerGetDevCaps(i, &mxcaps, sizeof(mxcaps))))
				{
					SendDlgItemMessage(hDlg,
										IDC_DEVICE,
										CB_ADDSTRING,
										0,
										(LPARAM) mxcaps.szPname);
				}

			SendDlgItemMessage(hDlg,
								IDC_DEVICE,
								CB_SETCURSEL,
								pinfo->dwMixerID,
								0);

			if(pinfo->mode == MIXERPLUS_MODE_PLAYBACK)
				CheckDlgButton(hDlg, IDC_MODE_PLAYBACK, BST_CHECKED);

			else CheckDlgButton(hDlg, IDC_MODE_RECORDING, BST_CHECKED);

			return TRUE;
	}

	return FALSE;
}
Example #9
0
bool
TMXLoader::Private::processLayer(XMLElement &e)
{
	const char *l_name;
	float l_opacity = 1.f;
	int l_visible = 1;

	if ((!(l_name = e.Attribute("name")))) {
		MMWARNING("Layer element is missing one or more required attributes.");
		return(false);
	}

	MMIGNORE e.QueryFloatAttribute("opacity", &l_opacity);
	MMIGNORE e.QueryIntAttribute("visible", &l_visible);

	XMLElement *l_data = e.FirstChildElement(TMXLAYER_DATA_NODE);

	if (!l_data) {
		MMWARNING("Layer element is missing data element.");
		return(false);
	}

	const char *l_data_encoding;
	const char *l_data_compression;

	if (!(l_data_encoding = l_data->Attribute("encoding")) ||
	    !(l_data_compression = l_data->Attribute("compression"))) {
		MMWARNING("Layer data element is missing one or more required attributes.");
		return(false);
	}
	const char *l_data_raw = XMLUtil::SkipWhiteSpace(l_data->GetText());
	size_t l_data_raw_len = strlen(l_data_raw);

	/* right-side data trim */
	while (l_data_raw_len > 0 && isspace(l_data_raw[l_data_raw_len - 1]))
		--l_data_raw_len;

	if (!l_data_raw_len) {
		MMWARNING("Zero size layer data encountered.");
		return(false);
	}

	char *l_data_array = 0;

#define TMXDATA_ENCODING_BASE64 "base64"
	if (0 == strcmp(l_data_encoding, TMXDATA_ENCODING_BASE64)) {
		char *l_decoded_data;
		size_t l_decoded_data_size =
		    Core::Base64::Decode(l_data_raw, l_data_raw_len, &l_decoded_data);

#define TMXDATA_COMPRESSION_ZLIB "zlib"
		if (0 == strcmp(l_data_compression, TMXDATA_COMPRESSION_ZLIB)) {
			char *l_inflated_data;
			if (0 < Core::Zlib::Inflate(l_decoded_data, l_decoded_data_size,
			    static_cast<size_t>(map_size.width * map_size.height * 4), &l_inflated_data))
				l_data_array = l_inflated_data;
		}
#define TMXDATA_COMPRESSION_GZIP "gzip"
		else if (0 == strcmp(l_data_compression, TMXDATA_COMPRESSION_GZIP)) {
			char *l_inflated_data;
			if (0 < Core::Gzip::Inflate(l_decoded_data, l_decoded_data_size,
			    static_cast<size_t>(map_size.width * map_size.height * 4), &l_inflated_data))
				l_data_array = l_inflated_data;
		}

		delete[] l_decoded_data;
	}

#define TMXDATA_ENCODING_CSV "csv"
	else if (0 == strcmp(l_data_encoding, TMXDATA_ENCODING_CSV)) {
		// TODO(gamaral)
		assert(0 && "CSV data encoding is currently unimplemented");
		return(false);
	}

	if (!l_data_array)
		return(false);

	Game::TilemapSceneLayer *l_layer = new Game::TilemapSceneLayer(l_name, scene);
	l_layer->setData(reinterpret_cast<uint32_t *>(l_data_array));
	l_layer->setOpacity(l_opacity);
	l_layer->setSize(map_size);
	l_layer->setTileSize(tile_size);
	l_layer->setScale(scale);
	l_layer->setVisibility(1 == l_visible);

	/* process properties */
	XMLElement *l_properties = e.FirstChildElement(TMXPROPERTIES_NODE);
	XMLElement *l_property = l_properties ? l_properties->FirstChildElement(TMXPROPERTIES_PROPERTY_NODE) : 0;
	if (l_property)
	do {
		const char *l_pname = l_property->Attribute("name");
		const char *l_value = l_property->Attribute("value");
		if (!l_pname)
			continue;

		/* scale property */
		if (0 == strcmp(l_pname, "scale")) {
			if (!l_value) {
				MMWARNING("Skipping incomplete scale property.");
				continue;
			}

			Math::Size2f l_scale = l_layer->scale();
			if (0 == MMSTRCASECMP(l_value, "screen")) {
				const Math::Size2f &l_vsize = Graphics::Viewport::Size();
				const Math::Size2i &l_wsize = Graphics::Viewport::WindowSize();

				/*
				 * calculate pixels per viewport coordinate ratio
				 * scale ratio = vSize (vcoord)) / wSize (pixels)
				 */
				l_scale = l_vsize / l_wsize.cast<float>();
				l_layer->setScale(l_scale);

				continue;
			}
			else if (2 == sscanf(l_value, "%fx%f", &l_scale.width, &l_scale.height)) {
				l_layer->setScale(l_scale);
				continue;
			} else if (1 == sscanf(l_value, "%f", &l_scale.width)) {
				l_scale.height = l_scale.width;
				l_layer->setScale(l_scale);
				continue;
			}

			MMERROR("Invalid scale value encountered.");
			continue;
		}
		else l_layer->setProperty(l_name, l_value ? l_value : std::string());

	} while ((l_property = l_property->NextSiblingElement(TMXPROPERTIES_PROPERTY_NODE)));

	/* attach tilesets */
	TilesetCollection::iterator l_tileset_i;
	for (l_tileset_i = tilesets.begin(); l_tileset_i != tilesets.end(); ++l_tileset_i)
		l_layer->attachTileset(l_tileset_i->first, l_tileset_i->second);

	layers.push_back(l_layer);

	return(true);
}
Example #10
0
bool
TMXLoader::Private::processMap(XMLElement &m)
{
	if ((XML_SUCCESS != m.QueryIntAttribute("width", &map_size.width))
	 || (XML_SUCCESS != m.QueryIntAttribute("height", &map_size.height))
	 || (XML_SUCCESS != m.QueryIntAttribute("tilewidth", &tile_size.width))
	 || (XML_SUCCESS != m.QueryIntAttribute("tileheight", &tile_size.height))) {
		MMWARNING("Map element is missing one or more required attributes.");
		return(false);
	}

	/* default scale */
	scale.set(1.f, 1.f);

	/* process properties */
	XMLElement *l_properties = m.FirstChildElement(TMXPROPERTIES_NODE);
	XMLElement *l_property = l_properties ? l_properties->FirstChildElement(TMXPROPERTIES_PROPERTY_NODE) : 0;
	if (l_property)
	do {
		const char *l_pname = l_property->Attribute("name");
		if (!l_pname)
			continue;

		/* scale property */
		if (0 == MMSTRCASECMP(l_pname, "scale")) {
			const char *l_value = l_property->Attribute("value");
			if (!l_value) {
				MMWARNING("Skipping incomplete scale property.");
				continue;
			}

			if (0 == MMSTRCASECMP(l_value, "screen")) {
				const Math::Size2f &l_vsize = Graphics::Viewport::Size();
				const Math::Size2i &l_wsize = Graphics::Viewport::WindowSize();

				/*
				 * calculate pixels per viewport coordinate ratio
				 * scale ratio = vSize (vcoord)) / wSize (pixels)
				 */
				scale = l_vsize / l_wsize.cast<float>();

				continue;
			}
			else if (2 == sscanf(l_value, "%fx%f", &scale.width, &scale.height))
				continue;
			else if (1 == sscanf(l_value, "%f", &scale.width)) {
				scale.height = scale.width;
				continue;
			}

			MMERROR("Invalid scale value encountered.");
			continue;
		}

		/*
		 * Parse scene background color
		 */
		else if (0 == MMSTRCASECMP(l_pname, "bgcolor")) {
			const char *l_value = l_property->Attribute("value");
			if (!l_value) {
				MMWARNING("Skipping incomplete background color property.");
				continue;
			}

			/*
			 * Valid formats: #RRGGBB, RRGGBB.
			 */
			uint16_t l_pxl[3];
			if ((sscanf(l_value, "#%2hx%2hx%2hx",
			        &l_pxl[0], &l_pxl[1], &l_pxl[2]) != 3) &&
			    (sscanf(l_value,  "%2hx%2hx%2hx",
			        &l_pxl[0], &l_pxl[1], &l_pxl[2]) != 3)) {
				MMWARNING("Skipping invalid background color value.");
				continue;
			}

			/* set background color */
			Game::SceneBase &l_scene_base =
			    static_cast<Game::SceneBase &>(scene);
			l_scene_base.setBackground(PixelToColor(l_pxl));
			continue;
		}

	} while ((l_property = l_property->NextSiblingElement(TMXPROPERTIES_PROPERTY_NODE)));

	MMINFO("Map scale size (" << scale.width << "x" << scale.height << ")");

	/* calculate half-relative map size (used to offset coordinates) */
	hrmap_size.width = scale.width
	    * static_cast<float>(map_size.width  * tile_size.width);
	hrmap_size.height = scale.height
	    * static_cast<float>(map_size.height * tile_size.height);

	return(true);
}