本篇是创建游戏内核(3)【OO改良版】的续篇,关于该内核的细节说明请参阅创建游戏内核(4)。
接口:
/*************************************************************************
PURPOSE:
    Interface for data read and write from file.
*************************************************************************/
#ifndef _CORE_DATA_H_
#define _CORE_DATA_H_
typedef int BOOL;
typedef unsigned long ulong;
void* data_create(ulong size);
void data_destroy(void* data);
BOOL data_save(const char* filename, const void* data, ulong size);
BOOL data_load(const char* filename, void** data, ulong* size);
#endif
 
实现:
/*************************************************************************
PURPOSE:
    Implenents for data read and write from file.
*************************************************************************/
#include <stdio.h>
#include <malloc.h>
#include <memory.h>
#include "core_data.h"
#pragma warning(disable : 4996)
#define NULL    0
#define TRUE    1
#define FALSE   0
//-----------------------------------------------------------------------------
// Create data object.
//-----------------------------------------------------------------------------
void* data_create(ulong size)
{
    void* _data = malloc(size);
    
    if(_data)
        memset(_data, 0, size);
    return _data;
}
//-----------------------------------------------------------------------------
// Destroy data object
//-----------------------------------------------------------------------------
void data_destroy(void* data)
{
    if(data)
    {
        free(data);
        data = NULL;
    }    
}
//-----------------------------------------------------------------------------
// Write data into file.
//-----------------------------------------------------------------------------
BOOL data_save(const char* filename, const void* data, ulong size)
{
    FILE* _fp;
    if(data == NULL || size == 0)
        return FALSE;
    // open file, write size and data.
    if((_fp = fopen(filename, "wb")) == NULL)
        return FALSE;
    fwrite(&size, 1, 4, _fp);
    fwrite(data, 1, size, _fp);
    fclose(_fp);
    return TRUE;
}
//-----------------------------------------------------------------------------
// Load data from file.
//-----------------------------------------------------------------------------
BOOL data_load(const char* filename, void** data, ulong* size)
{
    FILE* _fp;
    if((_fp = fopen(filename, "rb")) == NULL)
        return FALSE;
    // read in size and data
    ulong _size;
    char* _data;
    fread(&_size, 1, 4, _fp);
    if((_data = (char*) malloc(_size)) == NULL)
        return FALSE;
    memset(_data, 0, sizeof(_size));
    fread(_data, 1, _size, _fp);
    fclose(_fp);
    *data = _data;
    // store size in return
    if(size != NULL)
        *size = _size;
    return TRUE;
}
测试代码:
/*****************************************************************************
PURPOSE:
    Test for data save and load.
*****************************************************************************/
#include "core_common.h"
#include "core_framework.h"
#include "core_data.h"
// a structure to contain a name
struct NAME
{
    char name[32];
};
class APP : public FRAMEWORK
{
public:       
    BOOL init()
    {
        const int _data_size = 64;
        // create the data package (w/64 bytes) and get the pointer, casting it to an NAME structure type.
        m_names = (NAME*) data_create(_data_size);
        // since there are 64 bytes total, and each name uses 32 bytes, then I can have 2 names stored.
        strcpy(m_names[0].name, "name1");
        strcpy(m_names[1].name, "name2");
        const char* _filename = "names.data";
        // save the names to disk
        data_save(_filename, m_names, _data_size);
        // destroy data
        data_destroy(m_names);
        
        DWORD _load_size;
        // load the names from disk, size will equal 64 when the load function returns.
        data_load(_filename, (void**) &m_names, &_load_size);    
        // display the names
        MessageBox(NULL, m_names[0].name, "1st name", MB_OK);
        MessageBox(NULL, m_names[1].name, "2nd name", MB_OK);
        
        data_destroy(m_names);        
        return TRUE;
    }
    
private:
    NAME* m_names;
};
//--------------------------------------------------------------------------------
// Main function, routine entry.
//--------------------------------------------------------------------------------
int WINAPI WinMain(HINSTANCE inst, HINSTANCE pre_inst, LPSTR cmd_line, int cmd_show)
{
    APP app;
    if(! build_window(inst, "MainClass", "MainWindow", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480))
        return -1;
    
    app.run();
    return 0;
}