static void
DrawDevice (COUNT device, COUNT pos, bool selected)
{
	RECT r;
	TEXT t;

	t.align = ALIGN_CENTER;
	t.baseline.x = DEVICE_COL_1;

	r.extent.width = DEVICE_SEL_WIDTH;
	r.extent.height = TEXT_SPACING_Y * 2;
	r.corner.x = DEVICE_SEL_ORG_X;

	// draw line background
	r.corner.y = DEVICE_ORG_Y + pos * DEVICE_SPACING_Y + NAME_OFS_Y;
	SetContextForeGroundColor (selected ?
			DEVICES_SELECTED_BACK_COLOR : DEVICES_BACK_COLOR);
	DrawFilledRectangle (&r);

	SetContextFont (TinyFont);

	// print device name
	SetContextForeGroundColor (selected ?
			DEVICES_SELECTED_NAME_COLOR : DEVICES_NAME_COLOR);
	t.baseline.y = r.corner.y + TEXT_BASELINE;
	t.pStr = GAME_STRING (device + DEVICE_STRING_BASE + 1);
	t.CharCount = utf8StringPos (t.pStr, ' ');
	font_DrawText (&t);
	t.baseline.y += TEXT_SPACING_Y;
	t.pStr = skipUTF8Chars (t.pStr, t.CharCount + 1);
	t.CharCount = (COUNT)~0;
	font_DrawText (&t);
}
示例#2
0
static int
ReadOneChar (joy_char_t *ch, const UNICODE *str)
{
	UNICODE *next = skipUTF8Chars (str, 1);
	int len = next - str;
	ch->len = len;
	memcpy (ch->enc, str, len);
	ch->enc[len] = '\0'; // string term

	return len;
}
示例#3
0
static void
DrawDevices (PMENU_STATE pMS, BYTE OldDevice, BYTE NewDevice)
{
#define MAX_VIS_DEVICES 5
	COORD y, cy;
	TEXT t;
	RECT r;
	PBYTE pDeviceMap;

	LockMutex (GraphicsLock);

	SetContext (StatusContext);
	SetContextFont (TinyFont);

	y = 41;
	t.baseline.x = 40;
	t.align = ALIGN_CENTER;
	t.CharCount = 3;

	pDeviceMap = (PBYTE)pMS->CurFrame;
	if (OldDevice > NUM_DEVICES
			|| (NewDevice < NUM_DEVICES
			&& (NewDevice < (BYTE)pMS->first_item.y
			|| NewDevice >= (BYTE)(pMS->first_item.y + MAX_VIS_DEVICES))))
	{
		STAMP s;

		r.corner.x = 2;
		r.extent.width = FIELD_WIDTH + 1;

		if (!(pMS->Initialized & 1))
		{
			++r.corner.x;
			r.extent.width -= 2;
			r.corner.y = 33;
			r.extent.height = 89;
			SetContextForeGroundColor (
					BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x14), 0x01));
			DrawFilledRectangle (&r);
		}
		else
		{
			TEXT ct;

			r.corner.y = 20;
			r.extent.height = 109;
			DrawStarConBox (&r, 1,
					BUILD_COLOR (MAKE_RGB15 (0x10, 0x10, 0x10), 0x19),
					BUILD_COLOR (MAKE_RGB15 (0x08, 0x08, 0x08), 0x1F),
					TRUE,
					BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x14), 0x01));

			SetContextFont (StarConFont);
			ct.baseline.x = (STATUS_WIDTH >> 1) - 1;
			ct.baseline.y = 27;
			ct.align = ALIGN_CENTER;
			ct.pStr = GAME_STRING (DEVICE_STRING_BASE);
			ct.CharCount = (COUNT)~0;
			SetContextForeGroundColor (
					BUILD_COLOR (MAKE_RGB15 (0x0A, 0x1F, 0x1F), 0x0B));
			font_DrawText (&ct);

			SetContextFont (TinyFont);
		}

		if (NewDevice < (BYTE)pMS->first_item.y)
			pMS->first_item.y = NewDevice;
		else if (NewDevice >= (BYTE)(pMS->first_item.y + MAX_VIS_DEVICES))
			pMS->first_item.y = NewDevice - (MAX_VIS_DEVICES - 1);

		s.origin.x = 4;
		s.origin.y = 34;
		cy = y;

		SetContextForeGroundColor (
				BUILD_COLOR (MAKE_RGB15 (0x00, 0x14, 0x14), 0x03));
		for (OldDevice = (BYTE)pMS->first_item.y;
				OldDevice < (BYTE)(pMS->first_item.y + MAX_VIS_DEVICES)
				&& OldDevice < (BYTE)pMS->first_item.x;
				++OldDevice)
		{
			s.frame = SetAbsFrameIndex (
					MiscDataFrame, 77 + pDeviceMap[OldDevice]);
			DrawStamp (&s);

			if (OldDevice != NewDevice)
			{
				t.baseline.y = cy;
				t.pStr = GAME_STRING (pDeviceMap[OldDevice] +
						DEVICE_STRING_BASE + 1);
				t.CharCount = utf8StringPos (t.pStr, ' ');
				font_DrawText (&t);
				t.baseline.y += 7;
				t.pStr = skipUTF8Chars (t.pStr, t.CharCount + 1);
				t.CharCount = (COUNT)~0;
				font_DrawText (&t);
			}

			cy += 18;
			s.origin.y += 18;
		}

		OldDevice = NewDevice;
	}
示例#4
0
BOOLEAN
DoTextEntry (PTEXTENTRY_STATE pTES)
{
	wchar_t ch;
	UNICODE *pStr;
	UNICODE *CacheInsPt;
	int CacheCursorPos;
	int len;
	BOOLEAN changed = FALSE;

	if (GLOBAL (CurrentActivity) & CHECK_ABORT)
		return (FALSE);

	if (!pTES->Initialized)
	{	// init basic vars
		int lwlen;

		pTES->InputFunc = DoTextEntry;
		pTES->Success = FALSE;
		pTES->Initialized = TRUE;
		pTES->JoystickMode = FALSE;
		pTES->UpperRegister = TRUE;
	
		// init insertion point
		if ((size_t)pTES->CursorPos > utf8StringCount (pTES->BaseStr))
			pTES->CursorPos = utf8StringCount (pTES->BaseStr);
		pTES->InsPt = skipUTF8Chars (pTES->BaseStr, pTES->CursorPos);

		// load joystick alphabet
		pTES->JoyAlphaString = CaptureStringTable (
				LoadStringTable (JOYSTICK_ALPHA_STRTAB));
		pTES->JoyAlpha = LoadJoystickAlpha (
				SetAbsStringTableIndex (pTES->JoyAlphaString, 0),
				&pTES->JoyAlphaLength);
		pTES->JoyUpper = LoadJoystickAlpha (
				SetAbsStringTableIndex (pTES->JoyAlphaString, 1),
				&pTES->JoyRegLength);
		pTES->JoyLower = LoadJoystickAlpha (
				SetAbsStringTableIndex (pTES->JoyAlphaString, 2),
				&lwlen);
		if (lwlen != pTES->JoyRegLength)
		{
			if (lwlen < pTES->JoyRegLength)
				pTES->JoyRegLength = lwlen;
			log_add (log_Warning, "Warning: Joystick upper-lower registers"
					" size mismatch; using the smallest subset (%d)",
					pTES->JoyRegLength);
		}

		pTES->CacheStr = HMalloc (pTES->MaxSize * sizeof (*pTES->CacheStr));
		
		DoInput (pTES, TRUE);

		if (pTES->CacheStr)
			HFree (pTES->CacheStr);
		if (pTES->JoyLower)
			HFree (pTES->JoyLower);
		if (pTES->JoyUpper)
			HFree (pTES->JoyUpper);
		if (pTES->JoyAlpha)
			HFree (pTES->JoyAlpha);
		DestroyStringTable ( ReleaseStringTable (pTES->JoyAlphaString));

		return pTES->Success;
	}

	pStr = pTES->InsPt;
	len = strlen (pStr);
	// save a copy of string
	CacheInsPt = pTES->InsPt;
	CacheCursorPos = pTES->CursorPos;
	memcpy (pTES->CacheStr, pTES->BaseStr, pTES->MaxSize);

	// process the pending character buffer
	ch = GetNextCharacter ();
	if (!ch && PulsedInputState.menu[KEY_MENU_ANY])
	{	// keyboard repeat, but only when buffer empty
		ch = GetLastCharacter ();
	}
	while (ch)
	{
		UNICODE chbuf[8];
		int chsize;

		pTES->JoystickMode = FALSE;

		chsize = getStringFromChar (chbuf, sizeof (chbuf), ch);
		if (isWidePrintChar (ch) && chsize > 0)
		{
			if (pStr + len - pTES->BaseStr + chsize < pTES->MaxSize)
			{	// insert character, when fits
				memmove (pStr + chsize, pStr, len + 1);
				memcpy (pStr, chbuf, chsize);
				pStr += chsize;
				++pTES->CursorPos;
				changed = TRUE;
			}
			else
			{	// does not fit
				PlayMenuSound (MENU_SOUND_FAILURE);
			}
		}
		ch = GetNextCharacter ();
	}

	if (PulsedInputState.menu[KEY_MENU_DELETE])
	{
		if (len)
		{
			joy_char_t ch;
			
			ReadOneChar (&ch, pStr);
			memmove (pStr, pStr + ch.len, len - ch.len + 1);
			len -= ch.len;
			changed = TRUE;
		}
	}
	else if (PulsedInputState.menu[KEY_MENU_BACKSPACE])
	{
		if (pStr > pTES->BaseStr)
		{
			UNICODE *prev = skipUTF8Chars (pTES->BaseStr,
					pTES->CursorPos - 1);
			
			memmove (prev, pStr, len + 1);
			pStr = prev;
			--pTES->CursorPos;
			changed = TRUE;
		}
	}
	else if (PulsedInputState.menu[KEY_MENU_LEFT])
	{
		if (pStr > pTES->BaseStr)
		{
			UNICODE *prev = skipUTF8Chars (pTES->BaseStr,
					pTES->CursorPos - 1);

			pStr = prev;
			len += (prev - pStr);
			--pTES->CursorPos;
			changed = TRUE;
		}
	}
	else if (PulsedInputState.menu[KEY_MENU_RIGHT])
	{
		if (len > 0)
		{
			joy_char_t ch;
			
			ReadOneChar (&ch, pStr);
			pStr += ch.len;
			len -= ch.len;
			++pTES->CursorPos;
			changed = TRUE;
		}
	}
	else if (PulsedInputState.menu[KEY_MENU_HOME])
	{
		if (pStr > pTES->BaseStr)
		{
			pStr = pTES->BaseStr;
			len = strlen (pStr);
			pTES->CursorPos = 0;
			changed = TRUE;
		}
	}
	else if (PulsedInputState.menu[KEY_MENU_END])
	{
		if (len > 0)
		{
			pTES->CursorPos += utf8StringCount (pStr);
			pStr += len;
			len = 0;
			changed = TRUE;
		}
	}
	
	if (pTES->JoyAlpha && (
			PulsedInputState.menu[KEY_MENU_UP] ||
			PulsedInputState.menu[KEY_MENU_DOWN] ||
			PulsedInputState.menu[KEY_MENU_PAGE_UP] ||
			PulsedInputState.menu[KEY_MENU_PAGE_DOWN]) )
	{	// do joystick text
		joy_char_t ch;
		joy_char_t newch;
		joy_char_t cmpch;
		int i;

		pTES->JoystickMode = TRUE;

		if (len)
			ReadOneChar (&ch, pStr);
		else
			ch = pTES->JoyAlpha[0];
		
		newch = ch;
		JoyCharToUpper (&cmpch, &ch, pTES);

		// find current char in the alphabet
		i = JoyCharFindIn (&cmpch, pTES->JoyAlpha, pTES->JoyAlphaLength);

		if (PulsedInputState.menu[KEY_MENU_UP])
		{
			--i;
			if (i < 0)
				i = pTES->JoyAlphaLength - 1;
			newch = pTES->JoyAlpha[i];
		}
		else if (PulsedInputState.menu[KEY_MENU_DOWN])
		{
			++i;
			if (i >= pTES->JoyAlphaLength)
				i = 0;
			newch = pTES->JoyAlpha[i];
		}

		if (PulsedInputState.menu[KEY_MENU_PAGE_UP] ||
				PulsedInputState.menu[KEY_MENU_PAGE_DOWN])
		{
			if (len)
			{	// single char change
				if (JoyCharIsLower (&newch, pTES))
					JoyCharToUpper (&newch, &newch, pTES);
				else
					JoyCharToLower (&newch, &newch, pTES);
			}
			else
			{	// register change
				pTES->UpperRegister = !pTES->UpperRegister;
			}
		}
		else
		{	// check register
			if (pTES->UpperRegister)
				JoyCharToUpper (&newch, &newch, pTES);
			else
				JoyCharToLower (&newch, &newch, pTES);
		}

		if (strcmp (newch.enc, ch.enc) != 0)
		{	// new char is different, put it in
			if (len)
			{	// change current -- this is messy with utf8
				int l = len - ch.len;
				if (pStr + l - pTES->BaseStr + newch.len < pTES->MaxSize)
				{
					// adjust other chars if necessary
					if (newch.len != ch.len)
						memmove (pStr + newch.len, pStr + ch.len, l + 1);

					memcpy (pStr, newch.enc, newch.len);
					len = l + newch.len;
					changed = TRUE;
				}
			}
			else
			{	// append
				if (pStr + len - pTES->BaseStr + newch.len < pTES->MaxSize)
				{
					memcpy (pStr, newch.enc, newch.len);
					pStr[newch.len] = '\0';
					len += newch.len;
					changed = TRUE;
				}
				else
				{	// does not fit
					PlayMenuSound (MENU_SOUND_FAILURE);
				}
			}
		}
	}
	
	if (PulsedInputState.menu[KEY_MENU_SELECT])
	{	// done entering
		pTES->Success = TRUE;
		return FALSE;
	}
	else if (PulsedInputState.menu[KEY_MENU_EDIT_CANCEL])
	{	// canceled entering
		pTES->Success = FALSE;
		return FALSE;
	}

	pTES->InsPt = pStr;

	if (changed && pTES->ChangeCallback)
	{
		if (!pTES->ChangeCallback (pTES))
		{	// changes not accepted - revert
			memcpy (pTES->BaseStr, pTES->CacheStr, pTES->MaxSize);
			pTES->InsPt = CacheInsPt;
			pTES->CursorPos = CacheCursorPos;

			PlayMenuSound (MENU_SOUND_FAILURE);
		}
	}
		
	if (pTES->FrameCallback)
		return pTES->FrameCallback (pTES);

	return TRUE;
}