// 处理所有按键
void HandleKeys(unsigned char Id, unsigned short Key) {
	char Pos;
	struct stUserInfo *pUser = GetUserInfo(Id);
	int OldTotalScore = GetIntValue(UD_TOTALSCORE+Id);
	int OldTotalBet = pUser->TotalBetScore;
	
	// 有押分
	if (Key & 0x1F) {
		if (IsBetting() && !IsPollingCoin(Id)) {
			OnBetAll(Id, Key&0x1F);
		}
	}
	Key &= ~0x1F;
	
	// 其它按键
	while (Key) {
		Pos = bsr32(Key);
		Key &= ~(1<<Pos);
		if (KeyDownHandler[Pos]) {
			KeyDownHandler[Pos](Id);		// 处理
		}		
	}
	
	// 设置标志
	if (	(OldTotalBet != pUser->TotalBetScore) 
		||	(OldTotalScore != GetIntValue(UD_TOTALSCORE+Id))	) {
		Set_Score(Id);
		Set_Sound(Id);
	}
}
// 接收按键处理
void Process_BetPadKey(unsigned char Id, unsigned char *Data) {
	unsigned short Key = (Data[0]|(Data[1]<<8));
	unsigned short Release;			// 已释放掉的键
	unsigned char BitIdx;
	int Tick;

	Key &= 0x0EFF;
	
	if (!RecvTick[Id]) {
		// 发送ID
		if (Id < COM_PLAYER_COUNT) {
			Send_ID(Id);
		}
		Set_Odds(Id);
		Set_LED(Id);
		Set_Score(Id);
	}
	RecvTick[Id] = GetTick() + 3000;	// 如果1.5秒内没有信息发过来就当掉线
	
	DownKey[Id] = Key & (Key ^ ConstDownKey[Id]);
	
	// 长按开始计数
	Release = DownKey[Id]&(~ConstDownKey[Id]);
	Tick = GetTick();
	while (Release & KeyPressFlag) {
		BitIdx = bsr32(Release);
		Release &= ~(1<<BitIdx);
		KeyCount[Id][BitIdx] = Tick + 200;
	}
	
	Release = (Key ^ DownKey[Id] ^ ConstDownKey[Id]);
	ConstDownKey[Id] = Key & (~Release);
}
Esempio n. 3
0
unsigned bitdelta32(unsigned *in, unsigned n, unsigned *out, unsigned start, unsigned inc) {
    #ifdef __SSE2__
  unsigned *ip,b,*op = out; 
  __m128i bv = _mm_setzero_si128(), sv = _mm_set1_epi32(start), cv = _mm_set1_epi32(inc), dv;
  for(ip = in; ip != in+(n&~(4-1)); ip += 4) { 
    __m128i iv = _mm_loadu_si128((__m128i *)ip); 
	bv = _mm_or_si128(bv, dv = _mm_sub_epi32(DELTA128_32(iv,sv),cv)); 
	sv = iv; 
	_mm_storeu_si128((__m128i *)op, dv); 
	op += 4; 
  }
  start = (unsigned)_mm_cvtsi128_si32(_mm_srli_si128(sv,12));
  HOR128_32(bv, b);
  while(ip < in+n) { unsigned x = *ip-start-inc; start = *ip++; b |= x; *op++ = x; }
    #else
  typeof(in[0]) b = 0,*op = out; BITDELTA(in, n, inc, start, b |= _x;*op++ = _x);
    #endif
  return bsr32(b);
}
Esempio n. 4
0
unsigned bitd32(unsigned *in, unsigned n, unsigned start) {
    #ifdef __SSE2__
  unsigned *ip,b; __m128i bv = _mm_setzero_si128(), sv = _mm_set1_epi32(start);
  for(ip = in; ip != in+(n&~(4-1)); ip += 4) { 
    __m128i iv = _mm_loadu_si128((__m128i *)ip); 
	bv = _mm_or_si128(bv, DELTA128_32(iv,sv)); 
	sv = iv; 
  }
  
  start = (unsigned)_mm_cvtsi128_si32(_mm_srli_si128(sv,12));
  HOR128_32(bv, b);
  while(ip < in+n) { 
    unsigned x = *ip-start; 
	start = *ip++; 
	b |= x; 
  }
    #else
  typeof(in[0]) b = 0; BITDELTA(in,n, 0, start, b |= _x);
    #endif
  return bsr32(b); 
}
void Process_PressKey()
{
	static int HeartBeatTick = 0;
	char Id;
	char Idx;
	unsigned short ValidConstKey = 0; 
	unsigned short Flag;
	// 一次
	for (Id = 0; Id < PLAYER_COUNT; Id++) {
		if (DownKey[Id] & KeyDownFlag) {
			HandleKeys(Id, DownKey[Id] & KeyDownFlag);
			DownKey[Id] = 0;
		}
	}
	
	// 心跳
	if (GetTick() > HeartBeatTick) {
		HeartBeatTick = GetTick() + 1000;
		ScoreFlag = ALLBITS;
	}
	
	// 常押
	for (Id = 0; Id < PLAYER_COUNT; Id++) {
		if (GetTick() > RecvTick[Id]) {
			RecvTick[Id] = 0;
			continue;
		}
			
		// 处理按键
		if (ConstDownKey[Id] & KeyPressFlag) {
			ValidConstKey = 0;
			Flag = ConstDownKey[Id] & KeyPressFlag;
			while (Flag) {
				Idx = bsr32(Flag);
				Flag &= ~(1<<Idx);
				if (GetTick() > KeyCount[Id][Idx]) {
					KeyCount[Id][Idx] = GetTick() + 100;
					ValidConstKey |= (1<<Idx);
				}
			}
			HandleKeys(Id, ValidConstKey);
		}
	}
	
	// 填充串口消息
	for (Id = 0; Id < COM_PLAYER_COUNT; Id++) {
		for (Idx = 0; Idx < sizeof(pMsgFlags)/sizeof(pMsgFlags[0]); Idx++) {
			if (ReturnWriteCount(Id) < 32) {
				break;
			}
			if (*pMsgFlags[Idx] & (1<<Id)) {
				*pMsgFlags[Idx] &= ~(1<<Id);
				CallBack_SendCom[Idx](Id);
			}
		}
	}
	// 填充USB消息
	for (Id = COM_PLAYER_COUNT; Id < PLAYER_COUNT; Id++) {
		if (!RecvTick[Id]) {
			continue;
		}
		for (Idx = 0; Idx < sizeof(usb_bits)/sizeof(*usb_bits); Idx++) {
			if (*pMsgFlags[Idx] & (1<<Id)) {
				*pMsgFlags[Idx] &= ~(1<<Id);
				SetUSBFlag(usb_bits[Idx], Id);
			}
		}
//		for (Idx = 0; Idx < sizeof(pMsgFlags)/sizeof(pMsgFlags[0]); Idx++) {
//			if (CallBack_SendUSB[Idx] && (*pMsgFlags[Idx] & (1<<Id))) {
//				*pMsgFlags[Idx] &= ~(1<<Id);
//				CallBack_SendUSB[Idx](Id);
//			}
//		}
	}
}
// 注册键位
void RegisterKeyDown(unsigned long Key, void (*CallBack)(char))
{
	KeyDownFlag |= Key;
	KeyDownHandler[bsr32(Key)] = CallBack;
}
void OnBetAll(char Id, unsigned long Key) {
	char BetIdx;
	char BetSwitch = GetCharValue(UD_BETSCORE_SWITCH + Id) + GetShortValue(UD_SWITCH_MIN);
	int BetScore = SwitchScore[BetSwitch];
	static short NewBetscores[EXTRA_COUNT];
	struct stUserInfo *pUser = GetUserInfo(Id);
	int Left,Right;
	int LeftTotalScore,CanBetScore;

	// 押分限制
	for (BetIdx = 0; BetIdx < EXTRA_COUNT; BetIdx++) {
		NewBetscores[BetIdx] = pUser->BetScore[BetIdx];
	}

	Key &= GetCanBetFlag();
	while (Key) {
		BetIdx = bsr32(Key);
		Key &= ~(1<<BetIdx);

		if (BetIdx == 4) {
			LeftTotalScore = GetIntValue(UD_TOTALSCORE + Id) - pUser->TotalBetScore;	// 剩余总分
			CanBetScore = MIN(LeftTotalScore, GetShortValue(UD_EXTRABET_MAX) - NewBetscores[BetIdx]);
		} else {
			Left = GetExtraSumBetScore(Id) + NewBetscores[4] - pUser->TotalBetScore;	// 总押分限制(不包含第4门)
			Right = GetShortValue(UD_EXTRABET_MAX) - NewBetscores[BetIdx];				// 单门押分限制
			LeftTotalScore = GetIntValue(UD_TOTALSCORE + Id) - pUser->TotalBetScore;	// 还剩余总分
			CanBetScore = MIN(MIN(Left, Right), LeftTotalScore);
		}
		
		// 分数不够
		if (CanBetScore <= 0)
		{
			continue;
		}
		
		// 第一次押分要取最小押注和押分板押注间的最大者
		if (!NewBetscores[BetIdx]) {
			if (GetShortValue(UD_EXTRABET_MIN) > BetScore) {
				BetScore = GetShortValue(UD_EXTRABET_MIN);
			}
		}
		
		// 可押分
		if (BetScore > CanBetScore) {
			BetScore = CanBetScore;
		}
		
		pUser->TotalBetScore -= pUser->BetScore[BetIdx];
		NewBetscores[BetIdx] += BetScore;
		
		// 是否可押成功
		for (char k = 0; k < BetIdx; k++) {
			pUser->BetScore[k] = NewBetscores[k];
		}
		CalculateLimit(Id+1, NewBetscores);
		NewBetscores[BetIdx] = pUser->BetScore[BetIdx];
		
		//  如果为负,则为0
		if (pUser->BetScore[BetIdx] < 0) {
//			SendUSB_Debug("ID(%d)->%d:%d", Id, BetIdx, pUser->BetScore[BetIdx]);
			pUser->BetScore[BetIdx] = 0;
		}
		
		pUser->TotalBetScore += pUser->BetScore[BetIdx];
	}
	
	// 重新计算押分和
	pUser->TotalBetScore = 0;
	for (BetIdx = 0; BetIdx < EXTRA_COUNT; BetIdx++) {
		pUser->TotalBetScore += pUser->BetScore[BetIdx];
	}
	
	// 总押分不能超过总分
	if (pUser->TotalBetScore > GetIntValue(UD_TOTALSCORE+Id)) {
//		SendUSB_Debug("ID(%d) bet>total %d:%d", Id, pUser->TotalBetScore, GetIntValue(UD_TOTALSCORE+Id));
		for (BetIdx = 0; BetIdx < EXTRA_COUNT; BetIdx++) {
			pUser->BetScore[BetIdx] = 0;
		}
		pUser->TotalBetScore = 0;
	}
}
Esempio n. 8
0
/// Add a new node to the tree. node->uncompressed_base and
/// node->compressed_base must have been set by the caller already.
static void
index_tree_append(index_tree *tree, index_tree_node *node)
{
	node->parent = tree->rightmost;
	node->left = NULL;
	node->right = NULL;

	++tree->count;

	// Handle the special case of adding the first node.
	if (tree->root == NULL) {
		tree->root = node;
		tree->leftmost = node;
		tree->rightmost = node;
		return;
	}

	// The tree is always filled sequentially.
	assert(tree->rightmost->uncompressed_base <= node->uncompressed_base);
	assert(tree->rightmost->compressed_base < node->compressed_base);

	// Add the new node after the rightmost node. It's the correct
	// place due to the reason above.
	tree->rightmost->right = node;
	tree->rightmost = node;

	// Balance the AVL-tree if needed. We don't need to keep the balance
	// factors in nodes, because we always fill the tree sequentially,
	// and thus know the state of the tree just by looking at the node
	// count. From the node count we can calculate how many steps to go
	// up in the tree to find the rotation root.
	uint32_t up = tree->count ^ (UINT32_C(1) << bsr32(tree->count));
	if (up != 0) {
		// Locate the root node for the rotation.
		up = ctz32(tree->count) + 2;
		do {
			node = node->parent;
		} while (--up > 0);

		// Rotate left using node as the rotation root.
		index_tree_node *pivot = node->right;

		if (node->parent == NULL) {
			tree->root = pivot;
		} else {
			assert(node->parent->right == node);
			node->parent->right = pivot;
		}

		pivot->parent = node->parent;

		node->right = pivot->left;
		if (node->right != NULL)
			node->right->parent = node;

		pivot->left = node;
		node->parent = pivot;
	}

	return;
}