Storing and Retrieving High Score Data


Before you learn about the specific Win32 API functions used to read and write files, let's go over exactly what happens to the array of high score integers when they are read from and written to a file. You've already learned that each number in the array of integers gets converted to five digits. However, I didn't mention that these digits aren't actually numbers , but instead are text characters . In other words, the number 1250 gets converted to "01250" before being written to a file. This process is known as streaming the high score data to a file because you are converting the numeric data into a stream of characters. Figure 24.1 shows what the streaming process looks like.

Figure 24.1. Streaming the high scores involves padding the numbers to five digits and converting them to a stream of characters.

graphics/24fig01.gif

As the figure reveals, the five high scores are converted to a stream of five-digit characters during the streaming process. Along with making it very straightforward to store the numbers to a file, streaming the numbers also makes it much easier to read them back in. More specifically , you just read five digits of characters at a time, and then convert the character string into an integer number.

I've talked about how to read and write files in general terms, but I haven't given you any specifics. All file input and output in Windows involves a small set of Win32 API functions. The most important of these functions is CreateFile() , which looks like this:

 HANDLE CreateFile(   LPCTSTR szFileName,   DWORD dwDesiredAccess,   DWORD dwShareMode,   LPSECURITY_ATTRIBUTES pSecurityAttributes,   DWORD dwCreationDisposition,   DWORD dwFlagsAndAttributes,   HANDLE hTemplateFile); 

The CreateFile() function is important because it is used to both open and close files. Although it takes quite a few arguments, not all of them apply to basic reading and writing; you don't need to worry about some of the arguments unless you're performing more advanced file input and output. Knowing this, I want to point out the arguments that are relevant to reading and writing high scores. The first argument, szFileName , is used to provide the name of the file to be created or opened. The second argument, dwDesiredAccess , determines what you want to do with the file, such as read from or write to it. The fifth argument, dwCreationDisposition , determines whether you want to open an existing file or create a new file. And finally, the sixth argument, dwFlagsAndAttributes , allows you to control various other aspects of opening or creating a file, such as whether you want to limit access to read only.

Rather than have you memorize the arguments to the CreateFile() function, I'd rather just show you how to use it to open and create files. Following is an example of using the CreateFile() function to create a new file ready for writing:

 HANDLE hFile = CreateFile(TEXT("HiScores.dat"), GENERIC_WRITE, 0, NULL,   CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 

In this example, the new file is called HiScores.dat, and it is created and ready to be written to using the file handle returned from the CreateFile() function. The hFile handle is what you'll use with a write function later to actually write data to the file. For now, let's take a quick look at how you open a file for reading:

 HANDLE hFile = CreateFile(TEXT("HiScores.dat"), GENERIC_READ, 0, NULL,   OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL); 

As you can see, the CreateFile() function is called in a similar manner as it is called for writing, with a few small changes. The second argument indicates that this is a read operation, whereas the fifth argument indicates that an existing file should be opened, as opposed to creating a new one. Finally, the sixth argument specifies that the file is read-only, which prevents you from writing to it using the provided file handle even if you wanted to.

Now that you have a file handle that can be used for reading or writing, depending on how you called the CreateFile() function, you're ready to find out how to write data to a file and then read it back. The Win32 API function used to write data to a file is called WriteFile() , and looks like this:

 BOOL WriteFile(   HANDLE hFile,   LPCVOID pBuffer,   DWORD dwNumberOfBytesToWrite,   LPDWORD pNumberOfBytesWritten,   LPOVERLAPPED pOverlapped); 

As with the CreateFile() function, not every argument to WriteFile() is critical for our purposes. You obviously need to provide the file handle in the first argument, as well as a data buffer from which the data is written. It's also important to specify the number of bytes to write, as well as a pointer to a DWORD that is to receive the number of bytes actually written. The last argument is the one that you don't need to worry about. To show you how easy it is to use the WriteFile() function, following is code to write a five-digit high score to a file:

 DWORD dwBytesWritten; WriteFile(hFile, &cData, 5, &dwBytesWritten, NULL); 

This code assumes that the high score has already been converted from an integer into a five-character string that is stored in the cData variable. Notice that the number of bytes to write is specified as 5 , which makes sense considering that the score consists of five digits.

Reading from a file is similar to writing to a file, except that it involves the ReadFile() function instead of WriteFile() . Following is the ReadFile() function as it is defined in the Win32 API:

 BOOL ReadFile(   HANDLE hFile,   LPVOID pBuffer,   DWORD dwNumberOfBytesToRead,   LPDWORD pNumberOfBytesRead,   LPOVERLAPPED pOverlapped); 

As you can see, the ReadFile() function actually takes the same arguments as the WriteFile() function. However, it uses the arguments a little differently because data is being read into the buffer instead of being written from it. Following is an example of reading an individual high score from a file using the ReadFile() function:

 char  cData[6]; DWORD dwBytesRead; ReadFile(hFile, &cData, 5, &dwBytesRead, NULL); 

It's important for the array of characters that holds each score to be null- terminated , which is why the cData variable is declared as being six characters long, instead of just five. In this code, the ReadFile() function reads five characters from the file and stores them in the cData variable.

When you're finished reading from or writing to a file, it's important to close the file. This is accomplished with the CloseHandle() Win32 function, which is called like this:

 CloseHandle(hFile); 

You now have the fundamental knowledge required to store and retrieve high score data to and from a file on disk, which is what you need to add a high score feature to the Space Out game.



Sams Teach Yourself Game Programming in 24 Hours
Sams Teach Yourself Game Programming in 24 Hours
ISBN: 067232461X
EAN: 2147483647
Year: 2002
Pages: 271

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net