コード例 #1
0
ファイル: auxiliary.cpp プロジェクト: 3vikasvicky/TOB-RSMT
	RGEdge* FindOverlapEdge(RGNode* Root,RGEdge* RE)
	{
		for(int i=0;i<Root->getNumEdge();i++)
		{	
			if(Root->getEdge(i) != RE && Root->getEdge(i) != RE->getDualEdge())
			{	
				if(IsOverlap(Root->getEdge(i),RE))
				{	return Root->getEdge(i);
				}
			}
		}

		return NULL;
	}
コード例 #2
0
ファイル: Game.cpp プロジェクト: howprice/sdl2-tetris
// return true if there was room to spawn
bool Game::SpawnTetronimo()
{
	m_activeTetromino.m_tetrominoType = (TetrominoType)( rand() % kNumTetrominoTypes );
	m_activeTetromino.m_rotation = 0;
	m_activeTetromino.m_pos.x = (m_field.width - 4) / 2;	// tetronimo block width approx = 4
	m_activeTetromino.m_pos.y = 0;

	if( IsOverlap( m_activeTetromino, m_field ) )
	{
		return false;
	}

	m_framesUntilFall = s_initialFramesPerFallStep;
	m_numUserDropsForThisTetronimo = 0;
	return true;
}
コード例 #3
0
ファイル: auxiliary.cpp プロジェクト: 3vikasvicky/TOB-RSMT
	RGEdge* FindOverlapEdge(RGEdge* RE) //be careful that do not return its dual edge
	{
		RGNode* FromNode = RE->getFromNode();
		//RGNode* ToNode = RE->getToNode();


		for(int i=0;i<FromNode->getNumEdge();i++)
		{	
			if(FromNode->getEdge(i) != RE && FromNode->getEdge(i) != RE->getDualEdge())
			{	
				if(IsOverlap(FromNode->getEdge(i),RE))
				{	return FromNode->getEdge(i);
				}
			}
		}

		return NULL;
	}
コード例 #4
0
ファイル: ParMan.cpp プロジェクト: xfxf123444/japan
BOOL DLL_EXPORT	GetProtectSectors(BYTE					btHardDisk,
								  DWORD					dwStartSector,
								  CREATE_PAR_FLAG		flags,//indicate is logical or primary
								  DWORD					dwFlag,//create flags
								  PPARTITION_ENTRY		ppeParEntry,
								  PPROTECT_SECTOR		pProtect,//[out]
								  BOOL					bWriteToDisk,									
								  int					*pnError)
{
	DISK_GEOMETRY				dg;
	DRIVE_LAYOUT				DriveLayout;
	int							nErrorCode; 
	int							nIndex;
	LARGE_INTEGER				lnStartByte;
	BOOL						bDeleteSuccess;
	PARTITION_INFORMATION		pi,piExtend;
	BYTE						btPartitionType;
	BOOL						bExistExtend,bNeedResize,bResizeSuccess;
	LARGE_INTEGER				lnExtendStart,lnExtendEnd;
	//viriable need to get the protect sectors
	BOOL						bIsDeleteLogical;
	BOOL						bIsCreateLogical;
	DWORD						dwExtOriginalHead,dwExtFinalHead;
	DWORD						dwOriginalHead,dwOriginalEnd;
	DWORD						dwFinalHead,dwFinalEnd;
	DWORD						dwOriginalEmbr,dwFinalEmbr;

	//p//init protect logic viriables
	memset( pProtect, 0, sizeof(PROTECT_SECTOR));
	bIsDeleteLogical = FALSE;
	bIsCreateLogical = FALSE;
	dwExtOriginalHead = 0;
	dwExtFinalHead = 0;
	dwOriginalHead = 0;
	dwOriginalEnd = 0;
	dwFinalHead = 0;
	dwFinalEnd = 0;
	dwOriginalEmbr = 0;
	dwFinalEmbr = 0;

	btHardDisk &= 0x7f;	
	bDeleteSuccess = FALSE;
	// 102 indicate false
	*pnError = nErrorCode = ERR_PARMAN_PARAM;
	//Get disk geometry and layout information
	if ( GetDiskGeometry(btHardDisk,&dg))
		return FALSE;
	if ( GetDriveLayout(btHardDisk, &DriveLayout))
		return FALSE;

	/************************************************
		Delete partition
	************************************************/
	//look for the partition
	lnStartByte.QuadPart = (__int64)dg.BytesPerSector * dwStartSector;
	for( nIndex = DriveLayout.dli.PartitionCount -1 ; nIndex >=0 ; nIndex-- )
	{
		if(DriveLayout.dli.PartitionEntry[nIndex].StartingOffset.QuadPart 
			== lnStartByte.QuadPart)
			break;
	}
	//usb disk
	if( ( DriveLayout.dli.PartitionCount == 1 ) && ( nIndex == 0 ) )
	{
		//p//back up the partition information
		memcpy(&pi,
				&DriveLayout.dli.PartitionEntry[nIndex],
				sizeof(PARTITION_INFORMATION));

		//zero partition table
		memset(	DriveLayout.dli.PartitionEntry,
				0,
				4*sizeof(PARTITION_INFORMATION) );
		
		DriveLayout.dli.PartitionCount = 4;
		
		for( nIndex = 0 ; nIndex < 4 ; nIndex++ )
			DriveLayout.dli.PartitionEntry[nIndex].RewritePartition = TRUE;

		bDeleteSuccess = TRUE;
	}else
	{
		//if found do delete
		if(nIndex >= 0)
		{
			switch( GetPartitionType(&DriveLayout, nIndex) )
			{
			case DISKMAN_PAR_UNUSED:
				break;
			case DISKMAN_PAR_EXTENDED_MBR:
				if ( flags.Extended )
				{
					//delete first logical
					nIndex = 4;
					//p//back up the partition information
					memcpy(&pi,
							&DriveLayout.dli.PartitionEntry[nIndex],
							sizeof(PARTITION_INFORMATION));

					bDeleteSuccess = !DeleteLogical(&DriveLayout,nIndex);
					bIsDeleteLogical = TRUE;
					break;
				}
				//else consider as primary
			case DISKMAN_PAR_PRIMARY_MBR:
				//p//back up the partition information
				memcpy(&pi,
						&DriveLayout.dli.PartitionEntry[nIndex],
						sizeof(PARTITION_INFORMATION));

				bDeleteSuccess = !DeletePrimary(&DriveLayout,nIndex);
				break;
			case DISKMAN_PAR_EXTENDED_EMBR:
				nIndex +=3;
			case DISKMAN_PAR_LOGICAL_EMBR:
				//p//back up the partition information
				memcpy(&pi,
						&DriveLayout.dli.PartitionEntry[nIndex],
						sizeof(PARTITION_INFORMATION));

				bDeleteSuccess = !DeleteLogical(&DriveLayout,nIndex);
				bIsDeleteLogical = TRUE;
				break;
			}
		}//if nIndex >= 0;
	}
	//delete fail
	if( bDeleteSuccess )
	{
		//p//pi now store the original start and end
		dwOriginalHead = (DWORD)(pi.StartingOffset.QuadPart / dg.BytesPerSector);
		dwOriginalEnd = dwOriginalHead + (DWORD)(pi.PartitionLength.QuadPart / dg.BytesPerSector);
		if( bIsDeleteLogical )
			dwOriginalEmbr = dwOriginalHead - pi.HiddenSectors;//dwOriginalEmbr == embr
	}else
	{
		return FALSE;
	}
	/************************************************
		Create partition
	************************************************/
	//check if usb sigle partition
	if((DriveLayout.dli.PartitionCount % 4) != 0 )
		return FALSE;

	//translate to partition information
	memset(&pi,0,sizeof(PARTITION_INFORMATION));
	//bootable?
	pi.BootIndicator = ppeParEntry->BootFlag ? 1:0;
	//file system
	pi.PartitionType = ppeParEntry->SystemFlag;
	//start
	pi.StartingOffset.QuadPart = (__int64)ppeParEntry->StartSector 
											* dg.BytesPerSector;
	//length
	pi.PartitionLength.QuadPart = (__int64)ppeParEntry->SectorsInPartition
											* dg.BytesPerSector;
	
	//detect if exist extend partition
	bExistExtend = FALSE;
	for( nIndex = 0 ; nIndex < 4 ; nIndex++ )
	{
		if ( GetPartitionType( &DriveLayout,nIndex) == DISKMAN_PAR_EXTENDED_MBR )
		{
			bExistExtend = TRUE;
			memcpy(&piExtend,&DriveLayout.dli.PartitionEntry[nIndex],
					sizeof(PARTITION_INFORMATION));
			lnExtendStart.QuadPart = piExtend.StartingOffset.QuadPart;
			lnExtendEnd.QuadPart = piExtend.PartitionLength.QuadPart;
			lnExtendEnd.QuadPart += lnExtendStart.QuadPart - 1;
			//p//Get extend original start
			dwExtOriginalHead = (DWORD)(lnExtendStart.QuadPart / dg.BytesPerSector);
			break;
		}
	}
	//do alignment
	if ( dwFlag == LOGICAL )
	{
		LegalizePartition(&pi,&dg,DISKMAN_PAR_LOGICAL_EMBR);
	}else
		LegalizePartition(&pi,&dg,DISKMAN_PAR_PRIMARY_MBR);
	
	bNeedResize = FALSE;
	bResizeSuccess = TRUE;
	if( dwFlag == LOGICAL )
	{
		bIsCreateLogical = TRUE;
		if( bExistExtend )
		{
			//beyond the extend low boundary
			if(	pi.StartingOffset.QuadPart  
				<
				lnExtendStart.QuadPart )
			{
				//justify the extend head
				piExtend.StartingOffset.QuadPart = pi.StartingOffset.QuadPart;
				piExtend.PartitionLength.QuadPart = lnExtendEnd.QuadPart
													- piExtend.StartingOffset.QuadPart
													+ 1;
				bNeedResize = TRUE;
			}
			//beyond the extend high boundary
			if( pi.StartingOffset.QuadPart + pi.PartitionLength.QuadPart 
				> 
				lnExtendEnd.QuadPart + 1 )
			{
				//justify the extend end
				//piExtend.StartingOffset has modified;
				piExtend.PartitionLength.QuadPart = pi.StartingOffset.QuadPart
													+ pi.PartitionLength.QuadPart
													- piExtend.StartingOffset.QuadPart;
				bNeedResize = TRUE;
			}
			if ( bNeedResize )
			{
				nErrorCode = ResizePrimary(&DriveLayout,&piExtend,&dg,nIndex);
				bResizeSuccess = ! nErrorCode;
			}
			//resize success create logical
			if( bResizeSuccess )
			{
				//p//get extend final head
				dwExtFinalHead = (DWORD)(piExtend.StartingOffset.QuadPart / dg.BytesPerSector);
				nErrorCode = CreateLogical(&DriveLayout,&pi,&dg);
			}
		}else
		{
			//no extend partition, should create one
			//Backup partition type;
			btPartitionType = pi.PartitionType;
			pi.PartitionType = PARTITION_EXTENDED;
			nErrorCode = CreatePrimary(&DriveLayout,&pi,&dg);
			if( !nErrorCode ) 
			{
				pi.PartitionType = btPartitionType;
				nErrorCode = CreateLogical(&DriveLayout,&pi,&dg);
			}
		}
	}else
	{
		// if primary overlap the extend then resize extend partition
		if( bExistExtend )
		{
			if( IsOverlap(&piExtend,&pi))
			{
				//try to resize extend partition forward
				piExtend.PartitionLength.QuadPart = pi.StartingOffset.QuadPart
													- lnExtendStart.QuadPart;
				//if length < 0 then length = 0
				if( piExtend.PartitionLength.QuadPart < 0 )
					piExtend.PartitionLength.QuadPart = 0;
				//resize forward
				nErrorCode = ResizePrimary(&DriveLayout,&piExtend,&dg,nIndex);
				if( nErrorCode != 0 )
				{
					//try to resize backward
					piExtend.StartingOffset.QuadPart =  pi.StartingOffset.QuadPart
														+ pi.PartitionLength.QuadPart;
					piExtend.PartitionLength.QuadPart = lnExtendEnd.QuadPart
														- piExtend.StartingOffset.QuadPart
														+ 1;
					nErrorCode = ResizePrimary(&DriveLayout,&piExtend,&dg,nIndex);
					
					bResizeSuccess = ! nErrorCode;
				}
			}
		}

		if( bResizeSuccess )
		{
			//p//get extend final head
			dwExtFinalHead = (DWORD)(piExtend.StartingOffset.QuadPart / dg.BytesPerSector);
			nErrorCode = CreatePrimary(&DriveLayout,&pi,&dg);
		}
	}
	//get the protect sectors group
	if( !nErrorCode )
	{
		//pi now store the partition information created
		dwFinalHead = (DWORD)(pi.StartingOffset.QuadPart / dg.BytesPerSector);
		dwFinalEnd = dwFinalHead + (DWORD)(pi.PartitionLength.QuadPart / dg.BytesPerSector);
		if( bIsCreateLogical )
		{
			dwFinalEmbr = dwFinalHead;//dwFinalEmbr == embr
			dwFinalHead += dg.SectorsPerTrack;
		}
		if( dwExtOriginalHead >= dwFinalHead &&
			dwExtOriginalHead <= dwFinalEnd - 1 )
		{
			pProtect->bProtectReadOne = TRUE;
			pProtect->dwProtectReadOne = dwExtOriginalHead;
		}
		if( bIsCreateLogical ^ bIsDeleteLogical )
		{
			//delete primary, create logical or
			//delete logical, create primary
			if( dwExtFinalHead >= dwOriginalHead &&
				dwExtFinalHead <= dwOriginalEnd - 1 )
			{
				pProtect->bProtectWriteOne = TRUE;
				pProtect->dwProtectWriteOne = dwExtFinalHead;
			}
		}
		if(	bIsDeleteLogical )
		{
			if( dwOriginalEmbr >= dwFinalHead &&
				dwOriginalEmbr <= dwFinalEnd - 1 )
			{
				pProtect->bProtectReadTwo = TRUE;
				pProtect->dwProtectReadTwo = dwOriginalEmbr;
			}
			if( bIsCreateLogical )
			{
				//delete logical, create logical
				if( dwFinalEmbr >= dwOriginalHead &&
					dwFinalEmbr <= dwOriginalEnd - 1 )
				{
					pProtect->bProtectWriteTwo = TRUE;
					pProtect->dwProtectWriteTwo = dwFinalEmbr;
				}
			}
		}
	}
	//if write set drive layout
	if( !nErrorCode && bWriteToDisk )
		nErrorCode = SetDriveLayout(btHardDisk, &DriveLayout, TRUE);
	//return
	*pnError = nErrorCode;
	return( nErrorCode == 0 );
}
コード例 #5
0
ファイル: ParMan.cpp プロジェクト: xfxf123444/japan
BOOL DLL_EXPORT CreatePartition(PPARTITION_ENTRY ppeParEntry, 
								  BYTE btHardDisk, 
								  DWORD dwFlag,
								  BOOL blIsFormat, 
								  PBYTE pLabel, 
								  HWND hWnd,
								  PINT pnError)
{
	int						nErrorCode;
	PARTITION_INFORMATION	pi,piExtend;
	DRIVE_LAYOUT			DriveLayout;
	DISK_GEOMETRY			dg;
	int						nIndex;
	BYTE					btPartitionType;
	BOOL					bExistExtend;
	BOOL					bNeedResize,bResizeSuccess;
	LARGE_INTEGER			lnExtendStart,lnExtendEnd;
	char					chDriveLetter;
	char					szLabel[12];
//	int						nLogicalNumber;

	btHardDisk &= 0x7f;	
	//Get disk geomtry and layout information
	*pnError = nErrorCode = ERR_PARMAN_PARAM; // 102 indicate false
	if ( GetDiskGeometry(btHardDisk,&dg))
		return FALSE;
	if ( GetDriveLayout(btHardDisk, &DriveLayout))
		return FALSE;
	//check if usb sigle partition
	if((DriveLayout.dli.PartitionCount % 4) != 0 )
		return FALSE;

	//translate to partition information
	memset(&pi,0,sizeof(PARTITION_INFORMATION));
	pi.StartingOffset.QuadPart = (__int64)ppeParEntry->StartSector * dg.BytesPerSector;
	pi.PartitionLength.QuadPart = (__int64)ppeParEntry->SectorsInPartition * dg.BytesPerSector;
	pi.BootIndicator = ppeParEntry->BootFlag ? 1:0;
	pi.PartitionType = ppeParEntry->SystemFlag;
	
	*pnError = ERR_PARMAN_PARAM;
	//stat logical drive numbers
//	nLogicalNumber = 0;
//	for( nIndex = 4 ; nIndex < DriveLayout.dli.PartitionCount ; nIndex +=4 )
//	{
//		if ( GetPartitionType( &DriveLayout,nIndex) != DISKMAN_PAR_UNUSED )
//			nLogicalNumber++;
//	}
	//detect if exist extend partition
	bExistExtend = FALSE;
	for( nIndex = 0 ; nIndex < 4 ; nIndex++ )
	{
		if ( GetPartitionType( &DriveLayout,nIndex) == DISKMAN_PAR_EXTENDED_MBR )
		{
			bExistExtend = TRUE;
			memcpy(&piExtend,&DriveLayout.dli.PartitionEntry[nIndex],
					sizeof(PARTITION_INFORMATION));
			lnExtendStart.QuadPart = piExtend.StartingOffset.QuadPart;
			lnExtendEnd.QuadPart = piExtend.PartitionLength.QuadPart;
			lnExtendEnd.QuadPart += lnExtendStart.QuadPart - 1;
			break;
		}
	}
	//do alignment
	if ( dwFlag == LOGICAL )
	{
		LegalizePartition(&pi,&dg,DISKMAN_PAR_LOGICAL_EMBR);
	}else
		LegalizePartition(&pi,&dg,DISKMAN_PAR_PRIMARY_MBR);
	//create partition	
	bNeedResize = FALSE;
	bResizeSuccess = TRUE;
	if( dwFlag == LOGICAL )
	{
		if( bExistExtend )
		{
			//beyond the extend low boundary
			if(	pi.StartingOffset.QuadPart  
				<
				lnExtendStart.QuadPart )
			{
				//justify the extend head
				piExtend.StartingOffset.QuadPart = pi.StartingOffset.QuadPart;
				piExtend.PartitionLength.QuadPart = lnExtendEnd.QuadPart
													- piExtend.StartingOffset.QuadPart
													+ 1;
				bNeedResize = TRUE;
			}
			//beyond the extend high boundary
			if( pi.StartingOffset.QuadPart + pi.PartitionLength.QuadPart 
				> 
				lnExtendEnd.QuadPart + 1 )
			{
				//justify the extend end
				//piExtend.StartingOffset has modified;
				piExtend.PartitionLength.QuadPart = pi.StartingOffset.QuadPart
													+ pi.PartitionLength.QuadPart
													- piExtend.StartingOffset.QuadPart;
				bNeedResize = TRUE;
			}
			//if there existing only one logical drive is required to
			//move to the free space acrross a primary partition, parman
			//should move the extend with the logical
//			if( nLogicalNumber == 1 )
//			{
//				if(	pi.StartingOffset.QuadPart  
//					<
//					lnExtendStart.QuadPart )
//
//				if( pi.StartingOffset.QuadPart + pi.PartitionLength.QuadPart 
//				> 
//				lnExtendEnd.QuadPart + 1 )
//			}
			if ( bNeedResize )
			{
				nErrorCode = ResizePrimary(&DriveLayout,&piExtend,&dg,nIndex);
				bResizeSuccess = ! nErrorCode;
			}
			//resize success create logical
			if( bResizeSuccess )
				nErrorCode = CreateLogical(&DriveLayout,&pi,&dg);
		}else
		{
			//no extend partition, should create one
			//Backup partition type;
			btPartitionType = pi.PartitionType;
			pi.PartitionType = PARTITION_EXTENDED;
			nErrorCode = CreatePrimary(&DriveLayout,&pi,&dg);
			if( !nErrorCode ) 
			{
				pi.PartitionType = btPartitionType;
				nErrorCode = CreateLogical(&DriveLayout,&pi,&dg);
			}
		}
	}else
	{
		// if primary overlap the extend then resize extend partition
		if( bExistExtend )
		{
			if( IsOverlap(&piExtend,&pi) )
			{
				//try to resize extend partition forward
				piExtend.PartitionLength.QuadPart = pi.StartingOffset.QuadPart
													- lnExtendStart.QuadPart;
				//if length < 0 then length = 0
				if( piExtend.PartitionLength.QuadPart < 0 )
					piExtend.PartitionLength.QuadPart = 0;
				//resize forward
				nErrorCode = ResizePrimary(&DriveLayout,&piExtend,&dg,nIndex);
				if( nErrorCode != 0 )
				{
					//try to resize backward
					piExtend.StartingOffset.QuadPart =  pi.StartingOffset.QuadPart
														+ pi.PartitionLength.QuadPart;
					piExtend.PartitionLength.QuadPart = lnExtendEnd.QuadPart
														- piExtend.StartingOffset.QuadPart
														+ 1;
					nErrorCode = ResizePrimary(&DriveLayout,&piExtend,&dg,nIndex);
					
					bResizeSuccess = ! nErrorCode;
				}
			}
		}

		if( bResizeSuccess )
			nErrorCode = CreatePrimary(&DriveLayout,&pi,&dg);
	}
	//create success, write back
	if( !nErrorCode )
		nErrorCode = SetDriveLayout(btHardDisk,&DriveLayout);
	//format partition
	if(( blIsFormat )&&( !nErrorCode ))
	{
		for( nIndex = 0; nIndex < 100 ; nIndex++ )
		{
			Sleep(500);
			chDriveLetter = RetrieveDriveLttr(btHardDisk,
												dwFlag,
												(DWORD)
												(pi.StartingOffset.QuadPart
													/ dg.BytesPerSector));

			if( (BYTE)chDriveLetter != 0xff )
			{
				chDriveLetter += 0x40;
				break;
			}
		}
		if ( chDriveLetter >= 'A' && chDriveLetter <= 'Z' )
		{
			memcpy(szLabel,pLabel,11);
			szLabel[11] = '\0';
			//if no name
			if( !memcmp(szLabel,"NO NAME",7))
				szLabel[0] = '\0';
			switch( pi.PartitionType & 0x0f)
			{
			case 0x01://fat12
				FormatDrive(chDriveLetter, szLabel,FORMAT_FAT_16,hWnd);
				break;
			case 0x04://fat16(old)
			case 0x06://fat16(big dos)
			case 0x0e://fat16(eint13)
			case 0x0f://fat16(int13)
				FormatDrive(chDriveLetter, szLabel,FORMAT_FAT_16,hWnd)
					||(nErrorCode=ERR_PARMAN_FORMATDRIVE);
				break;
			case 0x07://ntfs
				FormatDrive(chDriveLetter, szLabel,FORMAT_NTFS,hWnd)
					||(nErrorCode=ERR_PARMAN_FORMATDRIVE);
				break;
			case 0x0b://fat32(int13)
			case 0x0c://fat32(eint13)
				FormatDrive(chDriveLetter, szLabel,FORMAT_FAT_32,hWnd)
					||(nErrorCode=ERR_PARMAN_FORMATDRIVE);
				break;
			default:
				//unknow type
				break;
			}
		}
	}
	*pnError = nErrorCode;
	return !nErrorCode;
}
コード例 #6
0
ファイル: Game.cpp プロジェクト: howprice/sdl2-tetris
void Game::UpdatePlaying( const GameInput& gameInput )
{
#ifdef _DEBUG
	if( gameInput.bDebugChangeTetromino )
	{
		m_activeTetromino.m_tetrominoType = (TetrominoType)( ( (unsigned int)m_activeTetromino.m_tetrominoType + 1 ) % (unsigned int)kNumTetrominoTypes );
	}
	if( gameInput.bDebugMoveLeft )
	{
		--m_activeTetromino.m_pos.x;
	}
	if( gameInput.bDebugMoveRight )
	{
		++m_activeTetromino.m_pos.x;
	}
	if( gameInput.bDebugMoveUp )
	{
		--m_activeTetromino.m_pos.y;
	}
	if( gameInput.bDebugMoveDown )
	{
		++m_activeTetromino.m_pos.y;
	}
#endif

	// move horizontally
	if( gameInput.bMoveLeft )
	{
		// try move
		TetrominoInstance testInstance = m_activeTetromino;
		--testInstance.m_pos.x;
		if( !IsOverlap(testInstance, m_field) )
			m_activeTetromino.m_pos.x = testInstance.m_pos.x;
	}
	if( gameInput.bMoveRight )
	{
		// try move
		TetrominoInstance testInstance = m_activeTetromino;
		++testInstance.m_pos.x;
		if( !IsOverlap( testInstance, m_field ) )
			m_activeTetromino.m_pos.x = testInstance.m_pos.x;
	}


	// rotate
	if( gameInput.bRotateClockwise )
	{
		TetrominoInstance testInstance = m_activeTetromino;
		if( testInstance.m_rotation == 0 )
		{
			testInstance.m_rotation = 3;
		}
		else
		{
			--testInstance.m_rotation;
		}

		// check for overlaps
		if( IsOverlap( testInstance, m_field ) )
		{
			// Simple wall kick, try 1 to the left and 1 to the right
			// TODO: Need special case for the stick, which may need to be bumped by +/-2
			testInstance.m_pos.x = m_activeTetromino.m_pos.x - 1;
			if( !IsOverlap( testInstance, m_field ) )
			{
				m_activeTetromino = testInstance;
			}
			else
			{
				testInstance.m_pos.x = m_activeTetromino.m_pos.x + 1;
				if( !IsOverlap( testInstance, m_field ) )
				{
					m_activeTetromino = testInstance;
				}
			}
		}
		else
		{
			// no overlap
			m_activeTetromino = testInstance;
		}
	}

	if( gameInput.bRotateAnticlockwise )
	{
		m_activeTetromino.m_rotation = ( m_activeTetromino.m_rotation + 1 ) % Tetromino::kNumRotations;
	}

	// fall
	m_framesUntilFall -= 1;
	if( m_framesUntilFall <= 0 )
	{
		m_framesUntilFall = m_framesPerFallStep;

		// try move
		TetrominoInstance testInstance = m_activeTetromino;
		testInstance.m_pos.y += 1;
		if( IsOverlap(testInstance, m_field) )
		{
			AddTetronimoToField( m_field, m_activeTetromino );
			if( !SpawnTetronimo() )
				m_gameState = kGameState_GameOver;
		}
		else
		{
			m_activeTetromino.m_pos.y = testInstance.m_pos.y;
		}
	}

	// soft drop
	if( gameInput.bSoftDrop )
	{
		// try move
		TetrominoInstance testInstance = m_activeTetromino;
		++testInstance.m_pos.y;
		if( !IsOverlap( testInstance, m_field ) )
		{
			m_activeTetromino.m_pos.y = testInstance.m_pos.y;
			++m_numUserDropsForThisTetronimo;
		}
	}

	// hard drop
	if( gameInput.bHardDrop )
	{
		TetrominoInstance testInstance = m_activeTetromino;
		while( !IsOverlap( testInstance, m_field ) )
		{
			++testInstance.m_pos.y;
			++m_numUserDropsForThisTetronimo;
		}
		--testInstance.m_pos.y;	// back up one
		--m_numUserDropsForThisTetronimo;
		AddTetronimoToField( m_field, testInstance );
		if( !SpawnTetronimo() )
			m_gameState = kGameState_GameOver;
	}

}