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 "KBlocksDisplay.h"
11
12#include "AI/KBlocksAILog.h"
13
14#include <KLocale>
15#include <KStatusBar>
16#include <QPixmapCache>
17
18KBlocksDisplay::KBlocksDisplay(int gameCount, const string& serverIP, int localPort) : KMainWindow()
19{
20 //Use up to 3MB for global application pixmap cache
21 QPixmapCache::setCacheLimit(3*1024);
22
23 for (int i = 0; i < 8; ++i)
24 {
25 maScoreList[i] = 0;
26 }
27
28 mpNetClient = new KBlocksNetClient(serverIP.c_str(), localPort);
29 connect(mpNetClient, SIGNAL(dataArrived(int)), this, SLOT(updateGameDisplay(int)));
30
31 mGameCount = gameCount;
32 mpGameLogic = new KBlocksGameLogic(mGameCount);
33 mpGameLogic->setGameSeed(0);
34 mpGameLogic->setGamePunish(false);
35 mpGameLogic->setGameStandbyMode(true);
36 mpGameLogic->setInitInterval(0);
37 mpGameLogic->setLevelUpInterval(0);
38
39 mpGameScene = new KBlocksScene(mpGameLogic, mGameCount);
40 mpGameScene->setGameAnimEnabled(false);
41 mpGameScene->setWaitForAllUpdate(false);
42
43 mpGameView = new KBlocksView(mpGameScene, this);
44 mpGameView->show();
45 setCentralWidget(mpGameView);
46
47 mUpdateInterval = 1000;
48 mUpdateTimer.setInterval(mUpdateInterval);
49 connect(&mUpdateTimer, SIGNAL(timeout()), this, SLOT(updateEvent()));
50 mUpdateTimer.stop();
51
52 statusBar()->insertItem( i18n("Score List : 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0"), 0 );
53}
54
55KBlocksDisplay::~KBlocksDisplay()
56{
57 mpGameLogic->stopGame();
58 delete mpGameLogic;
59
60 delete mpGameView;
61 delete mpGameScene;
62
63 delete mpNetClient;
64}
65
66void KBlocksDisplay::setGamesPerLine(int count)
67{
68 mpGameScene->setGamesPerLine(count);
69}
70
71void KBlocksDisplay::setUpdateInterval(int interval)
72{
73 mUpdateInterval = interval;
74 mUpdateTimer.setInterval(mUpdateInterval);
75 mpGameScene->setUpdateInterval(interval);
76}
77
78void KBlocksDisplay::startDisplay()
79{
80 mpGameLogic->startGame(mGameCount);
81 for(int i = 0; i < mGameCount; i++)
82 {
83 mpGameLogic->getSingleGame(i)->stopGame();
84 }
85
86 mpGameScene->createGameItemGroups(mGameCount, true);
87 mpGameScene->startGame();
88
89 mUpdateTimer.start();
90}
91
92void KBlocksDisplay::stopDisplay()
93{
94 mUpdateTimer.stop();
95
96 mpGameScene->stopGame();
97 mpGameScene->deleteGameItemGroups();
98
99 mpGameLogic->stopGame();
100}
101
102int KBlocksDisplay::formIntFromByte(char * data)
103{
104 int value = 0;
105 value += ((int)data[0]) & 0x000000FF;
106 value += (((int)data[1]) << 8) & 0x0000FF00;
107 value += (((int)data[2]) << 16) & 0x00FF0000;
108 value += (((int)data[3]) << 24) & 0xFF000000;
109 return value;
110}
111
112void KBlocksDisplay::updateScore()
113{
114 statusBar()->changeItem( i18n("Score List : %1 - %2 - %3 - %4 - %5 - %6 - %7 - %8",
115 maScoreList[0], maScoreList[1], maScoreList[2], maScoreList[3],
116 maScoreList[4], maScoreList[5], maScoreList[6], maScoreList[7]), 0 );
117}
118
119void KBlocksDisplay::updateEvent()
120{
121 char tmpByteData[5] = {'|', 'r', 'g', '|', '\0'};
122 mpNetClient->sendData(5, tmpByteData);
123}
124
125void KBlocksDisplay::updateGameDisplay(int size)
126{
127 char* tmpByteData = new char[size];
128
129 int ret = mpNetClient->recvData(size, tmpByteData);
130 if (ret < size)
131 {
132 return;
133 }
134
135 int gameID = tmpByteData[0];
136
137 //int scorePoint = formIntFromByte(tmpByteData + 1);
138 //int lineCount = formIntFromByte(tmpByteData + 5);
139 //int gameLevel = formIntFromByte(tmpByteData + 9);
140 maScoreList[gameID] = formIntFromByte(tmpByteData + 5);
141
142 int tmpPieceCount = formIntFromByte(tmpByteData + 13);
143 for (int i = 0; i < tmpPieceCount; ++i)
144 {
145 mpGameLogic->getSingleGame(gameID)->getPiece(i)->decodeData((unsigned char*)tmpByteData + 17 + i * 4);
146 }
147
148 formIntFromByte(tmpByteData + 17 + tmpPieceCount * 4);
149 mpGameLogic->getSingleGame(gameID)->getField()->decodeData((unsigned char*)tmpByteData + 18 + tmpPieceCount * 4);
150
151 updateScore();
152
153 delete [] tmpByteData;
154}
155