1/***************************************************************************
2* KBlocks, a falling blocks game for KDE *
3* Copyright (C) 2010 Zhongjie Cai <squall.leonhart.cai@gmail.com> *
4* *
5* This program is free software; you can redistribute it and/or modify *
6* it under the terms of the GNU General Public License as published by *
7* the Free Software Foundation; either version 2 of the License, or *
8* (at your option) any later version. *
9***************************************************************************/
10#include "KBlocksGameReplayer.h"
11
12KBlocksGameReplayer::KBlocksGameReplayer(const char * fileName, bool isBinaryMode)
13{
14 for(int i = 0; i < RecordDataType_Max_Count; ++i)
15 {
16 mRTMap[ KBlocksRecordText[i] ] = i;
17 }
18 mRTMap[string("MaxCount")] = -1;
19
20 FILE * pFile = fopen(fileName, "r");
21
22 if (!pFile)
23 {
24 mGameCount = 0;
25 return;
26 }
27
28 if (isBinaryMode)
29 {
30 loadBinary(pFile);
31 }
32 else
33 {
34 loadText(pFile);
35 }
36
37 mGameCount = mReplayList.front().value;
38 mReplayList.pop_front();
39 mGameSeed = mReplayList.front().value;
40 mSameSeed = (mReplayList.front().index == 1);
41 mReplayList.pop_front();
42
43 mStepLength = 1;
44
45 fclose(pFile);
46}
47
48KBlocksGameReplayer::~KBlocksGameReplayer()
49{
50}
51
52int KBlocksGameReplayer::getGameCount()
53{
54 return mGameCount;
55}
56
57int KBlocksGameReplayer::getGameSeed()
58{
59 return mGameSeed;
60}
61
62bool KBlocksGameReplayer::isSameSeed()
63{
64 return mSameSeed;
65}
66
67void KBlocksGameReplayer::setStepLength(int stepLen)
68{
69 if (stepLen > 1)
70 {
71 mStepLength = stepLen;
72 }
73 else
74 {
75 mStepLength = 1;
76 }
77}
78
79bool KBlocksGameReplayer::getNextRecords(vector<KBlocksReplayData> * data)
80{
81 if (mReplayList.empty())
82 {
83 return false;
84 }
85
86 KBlocksReplayData tmpData;
87 int tmpLength = mStepLength;
88 while(tmpLength > 0)
89 {
90 tmpData = mReplayList.front();
91 tmpLength -= tmpData.time;
92 if (tmpLength > 0)
93 {
94 data->push_back(tmpData);
95 mReplayList.pop_front();
96 }
97 else
98 {
99 mReplayList.front().time = -tmpLength;
100 }
101 if (mReplayList.empty())
102 {
103 return true;
104 }
105 }
106
107 return true;
108}
109
110void KBlocksGameReplayer::loadText(FILE * pFile)
111{
112 int count = 0;
113 char tmpString[256];
114 KBlocksReplayData tmpData;
115 mReplayList.clear();
116 while(1)
117 {
118 count = fscanf(pFile, "%d %s %d %d", &(tmpData.time), tmpString, &(tmpData.index), &(tmpData.value));
119 tmpData.type = mRTMap[string(tmpString)];
120 if ((tmpData.type == -1) || (count != 4))
121 {
122 break;
123 }
124 mReplayList.push_back(tmpData);
125 }
126}
127
128void KBlocksGameReplayer::loadBinary(FILE * pFile)
129{
130 KBlocksReplayData tmpData;
131 mReplayList.clear();
132 tmpData.time = fgetc(pFile);
133 tmpData.type = fgetc(pFile);
134 tmpData.index = fgetc(pFile);
135 tmpData.value = fgetc(pFile);
136 while(tmpData.time != EOF)
137 {
138 if (tmpData.type == RecordDataType_Skipped)
139 {
140 int tmpTime = tmpData.time;
141 while(tmpData.type == RecordDataType_Skipped)
142 {
143 tmpData.time = fgetc(pFile);
144 tmpData.type = fgetc(pFile);
145 tmpData.index = fgetc(pFile);
146 tmpData.value = fgetc(pFile);
147
148 tmpTime += tmpData.time;
149 }
150 tmpData.time = tmpTime;
151 }
152 mReplayList.push_back(tmpData);
153 tmpData.time = fgetc(pFile);
154 tmpData.type = fgetc(pFile);
155 tmpData.index = fgetc(pFile);
156 tmpData.value = fgetc(pFile);
157 }
158}
159
160