Click here to Skip to main content
15,892,674 members
Articles / Multimedia / DirectX

A DirectX Game: Quadrino

Rate me:
Please Sign up or sign in to vote.
4.89/5 (41 votes)
16 Oct 2008CPOL26 min read 397.5K   6.2K   125  
An interpretation of a popular falling block game implemented with DirectX that attempts to avoid any copyright infringement.
/* DDUtil.cpp *****************************************************************
Author:		Paul Watt
Date:		5/6/2002
Purpose:	
******************************************************************************/
/* Include Files *************************************************************/
#include "stdafx.h"
#include "DDUtil.h"

#include <mmsystem.h>

/* Global Variables **********************************************************/
			//C: The number of ticks per second that are found in the high
			//   resolution performance timer.  This value is only used
			//   inside of the DDTimer_QPF function.
static LONGLONG	g_llQPFTicksPerSec		= 0;

			//C: Function pointer to the proper TimerProc to call.  This field
			//   is used internally in DDTimer.
typedef FLOAT (*TimerFunction)(TIMER_COMMAND);
static TimerFunction gc_DDTimerProc = NULL;

/* Forward Declarations ******************************************************/
FLOAT DDTimer_QPF (TIMER_COMMAND command);
FLOAT DDTimer_GT  (TIMER_COMMAND command);


/* Global *********************************************************************
Author:		Paul Watt
Date:		5/6/2002
Purpose:	Initializes the DDTimer for use.  The timer is not usable until this
			function has been called.
Parameters:	NONE
Return:		Returns if the timer is initialized.
******************************************************************************/
bool DDInitTimer ()
{
			//C: Initialize the timer
	if (NULL == gc_DDTimerProc)
	{
			//C: Use QueryPerformanceFrequency() to get frequency of timer.  If QPF is
			//   not supported, we will timeGetTime() which returns milliseconds.
        LARGE_INTEGER qwTicksPerSec;
        if(QueryPerformanceFrequency( &qwTicksPerSec ))
		{
			//C: A high performance timer exists, therefore initialize the QPF field.
            g_llQPFTicksPerSec = qwTicksPerSec.QuadPart;
			//C: Set the timer function to the high performance timer.
			gc_DDTimerProc = DDTimer_QPF;
		}
		else
		{
			//C: Set the timer function to the high performance timer.
			gc_DDTimerProc = DDTimer_GT;
		}
    }

	return NULL != gc_DDTimerProc;
}


/* Global *********************************************************************
Author:		Paul Watt
Date:		5/6/2002
Purpose:	Performs timer operations.
Parameters:	command[in]: The action to be performed on the timer.  Here are the
				valid parameters that can be used:

				TIMER_RESET           - to reset the timer
				TIMER_START           - to start the timer
				TIMER_STOP            - to stop (or pause) the timer
				TIMER_ADVANCE         - to advance the timer by 0.1 seconds
				TIMER_GETABSOLUTETIME - to get the absolute system time
				TIMER_GETAPPTIME      - to get the current time
				TIMER_GETELAPSEDTIME  - to get the time that elapsed between 
									  TIMER_GETELAPSEDTIME calls

Return:		A floating point value that is reported in seconds.
******************************************************************************/
FLOAT DDTimer (TIMER_COMMAND command)
{
			//C: Verify that the timer procedure has been properly initialized.
	ATLASSERT(gc_DDTimerProc);
	return gc_DDTimerProc(command);
}


/* Global *********************************************************************
Author:		Paul Watt
Date:		5/6/2002
Purpose:	Performs timer operations using the high performance timer.
Parameters:	command[in]: THe action to be performed on the timer.  Refer to 
				DDTimer for the full definition of the commands.
Return:		A floating pointer value that is reported in seconds.
******************************************************************************/
FLOAT DDTimer_QPF( TIMER_COMMAND command )
{
    static LONGLONG m_llStopTime        = 0;
    static LONGLONG m_llLastElapsedTime = 0;
    static LONGLONG m_llBaseTime        = 0;
    double fTime;
    double fElapsedTime;
    LARGE_INTEGER qwTime;
    
    // Get either the current time or the stop time, depending
    // on whether we're stopped and what command was sent
    if (m_llStopTime != 0 && command != TIMER_START && command != TIMER_GETABSOLUTETIME)
	{
        qwTime.QuadPart = m_llStopTime;
	}
    else
	{
        QueryPerformanceCounter (&qwTime);
	}

    // Return the elapsed time
    if (TIMER_GETELAPSEDTIME == command)
    {
        fElapsedTime = (double) ( qwTime.QuadPart - m_llLastElapsedTime ) / (double) g_llQPFTicksPerSec;
        m_llLastElapsedTime = qwTime.QuadPart;
        return (FLOAT) fElapsedTime;
    }

    // Return the current time
    if (TIMER_GETAPPTIME == command)
    {
        double fAppTime = (double) ( qwTime.QuadPart - m_llBaseTime ) / (double) g_llQPFTicksPerSec;
        return (FLOAT) fAppTime;
    }

    // Reset the timer
    if (TIMER_RESET == command)
    {
        m_llBaseTime        = qwTime.QuadPart;
        m_llLastElapsedTime = qwTime.QuadPart;
        return 0.0f;
    }

    // Start the timer
    if (TIMER_START == command)
    {
        m_llBaseTime += qwTime.QuadPart - m_llStopTime;
        m_llStopTime = 0;
        m_llLastElapsedTime = qwTime.QuadPart;
        return 0.0f;
    }

    // Stop the timer
    if (TIMER_STOP == command)
    {
        m_llStopTime = qwTime.QuadPart;
        m_llLastElapsedTime = qwTime.QuadPart;
        return 0.0f;
    }

    // Advance the timer by 1/10th second
    if (TIMER_ADVANCE == command)
    {
        m_llStopTime += g_llQPFTicksPerSec/10;
        return 0.0f;
    }

    if (TIMER_GETABSOLUTETIME == command)
    {
        fTime = qwTime.QuadPart / (double) g_llQPFTicksPerSec;
        return (FLOAT) fTime;
    }

    return -1.0f; // Invalid command specified
}


/* Global *********************************************************************
Author:		Paul Watt
Date:		5/6/2002
Purpose:	Performs timer operations using the multimedia timer.
Parameters:	command[in]: THe action to be performed on the timer.  Refer to 
				DDTimer for the full definition of the commands.
Return:		A floating pointer value that is reported in seconds.
******************************************************************************/
FLOAT DDTimer_GT( TIMER_COMMAND command )
{
    // Get the time using timeGetTime()
    static double m_fLastElapsedTime  = 0.0;
    static double m_fBaseTime         = 0.0;
    static double m_fStopTime         = 0.0;
    double fTime;
    double fElapsedTime;
    
    // Get either the current time or the stop time, depending
    // on whether we're stopped and what command was sent
    if (m_fStopTime != 0.0 && command != TIMER_START && command != TIMER_GETABSOLUTETIME)
	{
        fTime = m_fStopTime;
	}
    else
	{
        fTime = timeGetTime() * 0.001;
	}

    // Return the elapsed time
    if (TIMER_GETELAPSEDTIME == command)
    {   
        fElapsedTime = (double) (fTime - m_fLastElapsedTime);
        m_fLastElapsedTime = fTime;
        return (FLOAT) fElapsedTime;
    }

    // Return the current time
    if (TIMER_GETAPPTIME == command)
    {
        return (FLOAT) (fTime - m_fBaseTime);
    }

    // Reset the timer
    if (TIMER_RESET == command)
    {
        m_fBaseTime         = fTime;
        m_fLastElapsedTime  = fTime;
        return 0.0f;
    }

    // Start the timer
    if (TIMER_START == command)
    {
        m_fBaseTime += fTime - m_fStopTime;
        m_fStopTime = 0.0f;
        m_fLastElapsedTime  = fTime;
        return 0.0f;
    }

    // Stop the timer
    if (TIMER_STOP == command)
    {
        m_fStopTime = fTime;
        return 0.0f;
    }

    // Advance the timer by 1/10th second
    if (TIMER_ADVANCE == command)
    {
        m_fStopTime += 0.1f;
        return 0.0f;
    }

    if (TIMER_GETABSOLUTETIME == command)
    {
        return (FLOAT) fTime;
    }

    return -1.0f; // Invalid command specified
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Engineer
United States United States
I am a software architect and I have been developing software for nearly two decades. Over the years I have learned to value maintainable solutions first. This has allowed me to adapt my projects to meet the challenges that inevitably appear during development. I use the most beneficial short-term achievements to drive the software I develop towards a long-term vision.

C++ is my strongest language. However, I have also used x86 ASM, ARM ASM, C, C#, JAVA, Python, and JavaScript to solve programming problems. I have worked in a variety of industries throughout my career, which include:
• Manufacturing
• Consumer Products
• Virtualization
• Computer Infrastructure Management
• DoD Contracting

My experience spans these hardware types and operating systems:
• Desktop
o Windows (Full-stack: GUI, Application, Service, Kernel Driver)
o Linux (Application, Daemon)
• Mobile Devices
o Windows CE / Windows Phone
o Linux
• Embedded Devices
o VxWorks (RTOS)
o Greenhills Linux
o Embedded Windows XP

I am a Mentor and frequent contributor to CodeProject.com with tutorial articles that teach others about the inner workings of the Windows APIs.

I am the creator of an open source project on GitHub called Alchemy[^], which is an open-source compile-time data serialization library.

I maintain my own repository and blog at CodeOfTheDamned.com/[^], because code maintenance does not have to be a living hell.

Comments and Discussions