# HG changeset patch # User koda # Date 1390340586 -3600 # Node ID de822cd3df3a380e0634ae1ee2126edcf4488a7d # Parent 4feced261c68eaeb722eb16918a50a2104e3fef8 fixwhitespace and dos2unix diff -r 4feced261c68 -r de822cd3df3a QTfrontend/campaign.cpp --- a/QTfrontend/campaign.cpp Tue Jan 21 22:38:13 2014 +0100 +++ b/QTfrontend/campaign.cpp Tue Jan 21 22:43:06 2014 +0100 @@ -26,31 +26,31 @@ QList getCampMissionList(QString & campaignName, QString & teamName) { QList missionInfoList; - QSettings teamfile(cfgdir->absolutePath() + "/Teams/" + teamName + ".hwt", QSettings::IniFormat, 0); + QSettings teamfile(cfgdir->absolutePath() + "/Teams/" + teamName + ".hwt", QSettings::IniFormat, 0); teamfile.setIniCodec("UTF-8"); - + // if entry not found check if there is written without _ // if then is found rename it to use _ QString spaceCampName = campaignName; spaceCampName = spaceCampName.replace(QString("_"),QString(" ")); - if (!teamfile.childGroups().contains("Campaign " + campaignName) and - teamfile.childGroups().contains("Campaign " + spaceCampName)){ - teamfile.beginGroup("Campaign " + spaceCampName); - QStringList keys = teamfile.childKeys(); - teamfile.endGroup(); - for (int i=0;i=0 and unlockedMissions==0) { - for(unsigned int i=progress+1;i>0;i--) - { - MissionInfo missionInfo; - missionInfo.name = campfile.value(QString("Mission %1/Name").arg(i)).toString(); - QString script = campfile.value(QString("Mission %1/Script").arg(i)).toString(); + for(unsigned int i=progress+1;i>0;i--) + { + MissionInfo missionInfo; + missionInfo.name = campfile.value(QString("Mission %1/Name").arg(i)).toString(); + QString script = campfile.value(QString("Mission %1/Script").arg(i)).toString(); missionInfo.script = script; - missionInfo.description = m_info.value(campaignName+"-"+ script.replace(QString(".lua"),QString("")) + ".desc", + missionInfo.description = m_info.value(campaignName+"-"+ script.replace(QString(".lua"),QString("")) + ".desc", QObject::tr("No description available")).toString(); QString image = campfile.value(QString("Mission %1/Script").arg(i)).toString().replace(QString(".lua"),QString(".png")); missionInfo.image = ":/res/campaign/"+campaignName+"/"+image; if (!QFile::exists(missionInfo.image)) - missionInfo.image = ":/res/CampaignDefault.png"; - missionInfoList.append(missionInfo); - } - } - else if(unlockedMissions>0) - { - for(int i=1;i<=unlockedMissions;i++) - { - QString missionNum = QString("%1").arg(i); - int missionNumber = teamfile.value("Campaign " + campaignName + "/Mission"+missionNum, -1).toInt(); - MissionInfo missionInfo; - missionInfo.name = campfile.value(QString("Mission %1/Name").arg(missionNumber)).toString(); - QString script = campfile.value(QString("Mission %1/Script").arg(missionNumber)).toString(); + missionInfo.image = ":/res/CampaignDefault.png"; + missionInfoList.append(missionInfo); + } + } + else if(unlockedMissions>0) + { + for(int i=1;i<=unlockedMissions;i++) + { + QString missionNum = QString("%1").arg(i); + int missionNumber = teamfile.value("Campaign " + campaignName + "/Mission"+missionNum, -1).toInt(); + MissionInfo missionInfo; + missionInfo.name = campfile.value(QString("Mission %1/Name").arg(missionNumber)).toString(); + QString script = campfile.value(QString("Mission %1/Script").arg(missionNumber)).toString(); missionInfo.script = script; - missionInfo.description = m_info.value(campaignName+"-"+ script.replace(QString(".lua"),QString("")) + ".desc", + missionInfo.description = m_info.value(campaignName+"-"+ script.replace(QString(".lua"),QString("")) + ".desc", QObject::tr("No description available")).toString(); QString image = campfile.value(QString("Mission %1/Script").arg(missionNumber)).toString().replace(QString(".lua"),QString(".png")); missionInfo.image = ":/res/campaign/"+campaignName+"/"+image; if (!QFile::exists(missionInfo.image)) - missionInfo.image = ":/res/CampaignDefault.png"; - missionInfoList.append(missionInfo); - } - } - return missionInfoList; + missionInfo.image = ":/res/CampaignDefault.png"; + missionInfoList.append(missionInfo); + } + } + return missionInfoList; } diff -r 4feced261c68 -r de822cd3df3a QTfrontend/campaign.h --- a/QTfrontend/campaign.h Tue Jan 21 22:38:13 2014 +0100 +++ b/QTfrontend/campaign.h Tue Jan 21 22:43:06 2014 +0100 @@ -23,11 +23,11 @@ class MissionInfo { - public: - QString name; - QString description; - QString script; - QString image; + public: + QString name; + QString description; + QString script; + QString image; }; QList getCampMissionList(QString & campaignName, QString & teamName); diff -r 4feced261c68 -r de822cd3df3a QTfrontend/hwform.cpp --- a/QTfrontend/hwform.cpp Tue Jan 21 22:38:13 2014 +0100 +++ b/QTfrontend/hwform.cpp Tue Jan 21 22:43:06 2014 +0100 @@ -1903,15 +1903,15 @@ Q_UNUSED(index); HWTeam team(ui.pageCampaign->CBTeam->currentText()); QString campaignName = ui.pageCampaign->CBCampaign->currentText().replace(QString(" "),QString("_")); - QString tName = team.name(); - - campaignMissionInfo = getCampMissionList(campaignName,tName); - ui.pageCampaign->CBMission->clear(); - + QString tName = team.name(); + + campaignMissionInfo = getCampMissionList(campaignName,tName); + ui.pageCampaign->CBMission->clear(); + for(int i=0;iCBMission->addItem(QString(campaignMissionInfo[i].name), QString(campaignMissionInfo[i].name)); - } + } } void HWForm::UpdateCampaignPageMission(int index) @@ -1923,7 +1923,7 @@ if(index > -1 && index < campaignMissionInfo.count()) { ui.pageCampaign->lbltitle->setText("

"+ui.pageCampaign->CBMission->currentText()+"

"); ui.pageCampaign->lbldescription->setText(campaignMissionInfo[index].description); - ui.pageCampaign->btnPreview->setIcon(QIcon(campaignMissionInfo[index].image)); + ui.pageCampaign->btnPreview->setIcon(QIcon(campaignMissionInfo[index].image)); } } @@ -1935,12 +1935,12 @@ UpdateCampaignPage(0); for(int i=0;iCBMission->count();i++) { - if (ui.pageCampaign->CBMission->itemText(i)==missionTitle) - { - ui.pageCampaign->CBMission->setCurrentIndex(i); - break; - } - } + if (ui.pageCampaign->CBMission->itemText(i)==missionTitle) + { + ui.pageCampaign->CBMission->setCurrentIndex(i); + break; + } + } } // used for --set-everything [screen width] [screen height] [color dept] [volume] [enable music] [enable sounds] [language file] [full screen] [show FPS] [alternate damage] [timer value] [reduced quality] diff -r 4feced261c68 -r de822cd3df3a QTfrontend/hwform.h --- a/QTfrontend/hwform.h Tue Jan 21 22:38:13 2014 +0100 +++ b/QTfrontend/hwform.h Tue Jan 21 22:43:06 2014 +0100 @@ -196,7 +196,7 @@ AmmoSchemeModel * ammoSchemeModel; QStack PagesStack; QString previousCampaignName; - QString previousTeamName; + QString previousTeamName; QList campaignMissionInfo; QTime eggTimer; BGWidget * wBackground; diff -r 4feced261c68 -r de822cd3df3a QTfrontend/ui/page/pagegamestats.cpp --- a/QTfrontend/ui/page/pagegamestats.cpp Tue Jan 21 22:38:13 2014 +0100 +++ b/QTfrontend/ui/page/pagegamestats.cpp Tue Jan 21 22:43:06 2014 +0100 @@ -40,13 +40,13 @@ QLayout * PageGameStats::bodyLayoutDefinition() { - kindOfPoints = QString(""); - defaultGraphTitle = true; + kindOfPoints = QString(""); + defaultGraphTitle = true; QGridLayout * pageLayout = new QGridLayout(); pageLayout->setSpacing(20); pageLayout->setColumnStretch(0, 1); pageLayout->setColumnStretch(1, 1); - pageLayout->setRowStretch(0, 1); + pageLayout->setRowStretch(0, 1); pageLayout->setRowStretch(1, 20); //pageLayout->setRowStretch(1, -1); this should work but there is unnecessary empty space betwin lines if used pageLayout->setContentsMargins(7, 7, 7, 0); @@ -106,11 +106,11 @@ QLayout * PageGameStats::footerLayoutDefinition() { QHBoxLayout * bottomLayout = new QHBoxLayout(); - + mainNote = new QLabel(this); mainNote->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); mainNote->setWordWrap(true); - + bottomLayout->addWidget(mainNote, 0); bottomLayout->setStretch(0,1); @@ -159,41 +159,41 @@ void PageGameStats::renderStats() { - graphic->show(); - labelGraphTitle-> show(); - if(defaultGraphTitle) { - labelGraphTitle->setText("

" + PageGameStats::tr("Health graph") + "

"); - } else { - defaultGraphTitle = true; - } - // if not health data sent - if(healthPoints.size() == 0) { - labelGraphTitle->hide(); - graphic->hide(); - } else { - QGraphicsScene * scene = new QGraphicsScene(); + graphic->show(); + labelGraphTitle-> show(); + if(defaultGraphTitle) { + labelGraphTitle->setText("

" + PageGameStats::tr("Health graph") + "

"); + } else { + defaultGraphTitle = true; + } + // if not health data sent + if(healthPoints.size() == 0) { + labelGraphTitle->hide(); + graphic->hide(); + } else { + QGraphicsScene * scene = new QGraphicsScene(); - QMap >::const_iterator i = healthPoints.constBegin(); - while (i != healthPoints.constEnd()) - { - quint32 c = i.key(); - //QColor clanColor = QColor(qRgb((c >> 16) & 255, (c >> 8) & 255, c & 255)); - QVector hps = i.value(); + QMap >::const_iterator i = healthPoints.constBegin(); + while (i != healthPoints.constEnd()) + { + quint32 c = i.key(); + //QColor clanColor = QColor(qRgb((c >> 16) & 255, (c >> 8) & 255, c & 255)); + QVector hps = i.value(); - QPainterPath path; - if (hps.size()) - path.moveTo(0, hps[0]); + QPainterPath path; + if (hps.size()) + path.moveTo(0, hps[0]); - for(int t = 1; t < hps.size(); ++t) - path.lineTo(t, hps[t]); + for(int t = 1; t < hps.size(); ++t) + path.lineTo(t, hps[t]); - scene->addPath(path, QPen(c)); - ++i; - } + scene->addPath(path, QPen(c)); + ++i; + } - graphic->setScene(scene); - graphic->fitInView(graphic->sceneRect()); - } + graphic->setScene(scene); + graphic->fitInView(graphic->sceneRect()); + } } void PageGameStats::GameStats(char type, const QString & info) @@ -237,9 +237,9 @@ } case 'g' : { - // TODO: change default picture or add change pic capability - defaultGraphTitle = false; - labelGraphTitle->setText("

" + info + "

"); + // TODO: change default picture or add change pic capability + defaultGraphTitle = false; + labelGraphTitle->setText("

" + info + "

"); break; } case 'T': // local team stats @@ -257,7 +257,7 @@ } break; } - case 'p' : + case 'p' : { kindOfPoints = info; break; @@ -300,11 +300,11 @@ QString message; QString killstring; if(kindOfPoints.compare("") == 0) { - killstring = PageGameStats::tr("(%1 kill)", "", kills).arg(kills); - } else { - killstring = PageGameStats::tr("(%1 %2)", "", kills).arg(kills).arg(kindOfPoints); - kindOfPoints = QString(""); - } + killstring = PageGameStats::tr("(%1 kill)", "", kills).arg(kills); + } else { + killstring = PageGameStats::tr("(%1 %2)", "", kills).arg(kills).arg(kindOfPoints); + kindOfPoints = QString(""); + } message = QString("

%1 %2. %3 ").arg(image, QString::number(playerPosition), playername, clanColor.name()) + killstring + "

"; diff -r 4feced261c68 -r de822cd3df3a QTfrontend/ui/page/pagemain.cpp --- a/QTfrontend/ui/page/pagemain.cpp Tue Jan 21 22:38:13 2014 +0100 +++ b/QTfrontend/ui/page/pagemain.cpp Tue Jan 21 22:43:06 2014 +0100 @@ -209,7 +209,7 @@ file.close(); } - + if(Tips.length()) return Tips[QTime(0, 0, 0).secsTo(QTime::currentTime()) % Tips.length()]; else diff -r 4feced261c68 -r de822cd3df3a QTfrontend/ui/page/pagenetserver.cpp --- a/QTfrontend/ui/page/pagenetserver.cpp Tue Jan 21 22:38:13 2014 +0100 +++ b/QTfrontend/ui/page/pagenetserver.cpp Tue Jan 21 22:43:06 2014 +0100 @@ -124,7 +124,7 @@ // This function assumes that the user wants to share his server while connected to // the Internet and that he/she is using direct access (eg no NATs). To determine the -// IP we briefly connect to Hedgewars website and fallback to user intervention +// IP we briefly connect to Hedgewars website and fallback to user intervention // after 4 seconds of timeout. void PageNetServer::copyUrl() { diff -r 4feced261c68 -r de822cd3df3a QTfrontend/ui/page/pageoptions.cpp --- a/QTfrontend/ui/page/pageoptions.cpp Tue Jan 21 22:38:13 2014 +0100 +++ b/QTfrontend/ui/page/pageoptions.cpp Tue Jan 21 22:43:06 2014 +0100 @@ -397,7 +397,7 @@ tagsLayout->addWidget(CBHogTag, 0); tagsLayout->addWidget(CBHealthTag, 0); tagsLayout->addWidget(CBTagOpacity, 0); - tagsLayout->addStretch(1); + tagsLayout->addStretch(1); } { // group: frontend diff -r 4feced261c68 -r de822cd3df3a QTfrontend/util/FileEngine.h --- a/QTfrontend/util/FileEngine.h Tue Jan 21 22:38:13 2014 +0100 +++ b/QTfrontend/util/FileEngine.h Tue Jan 21 22:43:06 2014 +0100 @@ -1,93 +1,93 @@ -#ifndef _FileEngine_h -#define _FileEngine_h - -#include -#include -#include -#include - -#include "physfs.h" - - - -class FileEngine : public QAbstractFileEngine -{ - public: - FileEngine(const QString& filename); - - virtual ~FileEngine(); - - virtual bool open(QIODevice::OpenMode openMode); - virtual bool close(); - virtual bool flush(); - virtual qint64 size() const; - virtual qint64 pos() const; - virtual bool setSize(qint64 size); - virtual bool seek(qint64 pos); - virtual bool isSequential() const; - virtual bool remove(); - virtual bool mkdir(const QString &dirName, bool createParentDirectories) const; - virtual bool rmdir(const QString &dirName, bool recurseParentDirectories) const; - virtual bool caseSensitive() const; - virtual bool isRelativePath() const; - QAbstractFileEngineIterator *beginEntryList(QDir::Filters filters, const QStringList & filterNames); - virtual QStringList entryList(QDir::Filters filters, const QStringList &filterNames) const; - virtual FileFlags fileFlags(FileFlags type=FileInfoAll) const; - virtual QString fileName(FileName file=DefaultName) const; - virtual QDateTime fileTime(FileTime time) const; - virtual void setFileName(const QString &file); - bool atEnd() const; - - virtual qint64 read(char *data, qint64 maxlen); - virtual qint64 readLine(char *data, qint64 maxlen); - virtual qint64 write(const char *data, qint64 len); - - bool isOpened() const; - - QFile::FileError error() const; - QString errorString() const; - - virtual bool supportsExtension(Extension extension) const; - - private: - PHYSFS_file *m_handle; - qint64 m_size; - FileFlags m_flags; - QString m_fileName; - QDateTime m_date; - bool m_bufferSet; - bool m_readWrite; -}; - -class FileEngineHandler : public QAbstractFileEngineHandler -{ - public: - FileEngineHandler(char * argv0); - ~FileEngineHandler(); - - QAbstractFileEngine *create(const QString &filename) const; - - static void mount(const QString & path); - static void mount(const QString & path, const QString & mountPoint); - static void setWriteDir(const QString & path); - static void mountPacks(); - static QString errorStr(); - -// private: - static const QString scheme; -}; - -class FileEngineIterator : public QAbstractFileEngineIterator -{ -public: - FileEngineIterator(QDir::Filters filters, const QStringList & nameFilters, const QStringList & entries); - - bool hasNext() const; - QString next(); - QString currentFileName() const; -private: - QStringList m_entries; - int m_index; -}; - -#endif +#ifndef _FileEngine_h +#define _FileEngine_h + +#include +#include +#include +#include + +#include "physfs.h" + + + +class FileEngine : public QAbstractFileEngine +{ + public: + FileEngine(const QString& filename); + + virtual ~FileEngine(); + + virtual bool open(QIODevice::OpenMode openMode); + virtual bool close(); + virtual bool flush(); + virtual qint64 size() const; + virtual qint64 pos() const; + virtual bool setSize(qint64 size); + virtual bool seek(qint64 pos); + virtual bool isSequential() const; + virtual bool remove(); + virtual bool mkdir(const QString &dirName, bool createParentDirectories) const; + virtual bool rmdir(const QString &dirName, bool recurseParentDirectories) const; + virtual bool caseSensitive() const; + virtual bool isRelativePath() const; + QAbstractFileEngineIterator *beginEntryList(QDir::Filters filters, const QStringList & filterNames); + virtual QStringList entryList(QDir::Filters filters, const QStringList &filterNames) const; + virtual FileFlags fileFlags(FileFlags type=FileInfoAll) const; + virtual QString fileName(FileName file=DefaultName) const; + virtual QDateTime fileTime(FileTime time) const; + virtual void setFileName(const QString &file); + bool atEnd() const; + + virtual qint64 read(char *data, qint64 maxlen); + virtual qint64 readLine(char *data, qint64 maxlen); + virtual qint64 write(const char *data, qint64 len); + + bool isOpened() const; + + QFile::FileError error() const; + QString errorString() const; + + virtual bool supportsExtension(Extension extension) const; + + private: + PHYSFS_file *m_handle; + qint64 m_size; + FileFlags m_flags; + QString m_fileName; + QDateTime m_date; + bool m_bufferSet; + bool m_readWrite; +}; + +class FileEngineHandler : public QAbstractFileEngineHandler +{ + public: + FileEngineHandler(char * argv0); + ~FileEngineHandler(); + + QAbstractFileEngine *create(const QString &filename) const; + + static void mount(const QString & path); + static void mount(const QString & path, const QString & mountPoint); + static void setWriteDir(const QString & path); + static void mountPacks(); + static QString errorStr(); + +// private: + static const QString scheme; +}; + +class FileEngineIterator : public QAbstractFileEngineIterator +{ +public: + FileEngineIterator(QDir::Filters filters, const QStringList & nameFilters, const QStringList & entries); + + bool hasNext() const; + QString next(); + QString currentFileName() const; +private: + QStringList m_entries; + int m_index; +}; + +#endif diff -r 4feced261c68 -r de822cd3df3a gameServer/Actions.hs --- a/gameServer/Actions.hs Tue Jan 21 22:38:13 2014 +0100 +++ b/gameServer/Actions.hs Tue Jan 21 22:43:06 2014 +0100 @@ -327,11 +327,11 @@ thisRoomChans <- liftM (map sendChan) $ roomClientsS ri joinedMidGame <- liftM (filter isJoinedMidGame) $ roomClientsS ri answerRemovedTeams <- io $ - room'sM rnc (\r -> let gi = fromJust $ gameInfo r in - concatMap (\c -> + room'sM rnc (\r -> let gi = fromJust $ gameInfo r in + concatMap (\c -> (answerFullConfigParams c (mapParams r) (params r)) ++ - (map (\t -> AnswerClients [sendChan c] ["REMOVE_TEAM", t]) $ leftTeams gi) + (map (\t -> AnswerClients [sendChan c] ["REMOVE_TEAM", t]) $ leftTeams gi) ) joinedMidGame ) ri @@ -357,7 +357,7 @@ ModifyRoom (\r -> r{ gameInfo = liftM (\g -> g{ teamsInGameNumber = teamsInGameNumber g - 1 - , roundMsgs = (if isJust $ lastFilteredTimedMsg g then (:) (fromJust $ lastFilteredTimedMsg g) else id) + , roundMsgs = (if isJust $ lastFilteredTimedMsg g then (:) (fromJust $ lastFilteredTimedMsg g) else id) $ rmTeamMsg : roundMsgs g }) $ gameInfo r }) @@ -456,11 +456,11 @@ wp <- client's webPassword chan <- client's sendChan mapM_ processAction $ - if wp == p then + if wp == p then [ModifyClient $ \c -> c{logonPassed = True} , AnswerClients [chan] ["LOGONPASSED"] ] - else + else [ByeClient $ loc "Authentication failed"] playerLogin p a contr = do chan <- client's sendChan @@ -530,7 +530,7 @@ processAction (BanNick n seconds reason) = do currentTime <- io getCurrentTime - let msg = + let msg = if seconds > 60 * 60 * 24 * 365 then B.concat ["Permanent ban (", reason, ")"] else @@ -775,7 +775,7 @@ processAction Cleanup = do jm <- gets joinsMonitor - + io $ do t <- getCurrentTime cleanup jm t diff -r 4feced261c68 -r de822cd3df3a gameServer/EngineInteraction.hs --- a/gameServer/EngineInteraction.hs Tue Jan 21 22:38:13 2014 +0100 +++ b/gameServer/EngineInteraction.hs Tue Jan 21 22:43:06 2014 +0100 @@ -42,7 +42,7 @@ encode = B.pack . Base64.encode . BW.unpack . B.concat isLegal m = (B.length m > 1) && (flip Set.member legalMessages . B.head . B.tail $ m) lft = foldr l Nothing - l m n = let m' = B.head $ B.tail m; tst = flip Set.member in + l m n = let m' = B.head $ B.tail m; tst = flip Set.member in if not $ tst timedMessages m' then n else if '+' /= m' then Just Nothing else Just . Just . B.pack . Base64.encode . BW.unpack $ m isNonEmpty = (/=) '+' . B.head . B.tail diff -r 4feced261c68 -r de822cd3df3a gameServer/HWProtoInRoomState.hs --- a/gameServer/HWProtoInRoomState.hs Tue Jan 21 22:38:13 2014 +0100 +++ b/gameServer/HWProtoInRoomState.hs Tue Jan 21 22:43:06 2014 +0100 @@ -215,7 +215,7 @@ gs <- if (not $ isReady cl) && (isSpecial rm) && (unreadyClients == [cl]) then startGame else return [] - return $ + return $ ModifyRoom (\r -> r{readyPlayers = readyPlayers r + (if isReady cl then -1 else 1)}) : ModifyClient (\c -> c{isReady = not $ isReady cl}) : (AnswerClients chans $ if clientProto cl < 38 then @@ -236,7 +236,7 @@ if teamsInGame cl > 0 && (isJust $ gameInfo rm) && (not $ B.null legalMsgs) then return $ AnswerClients chans ["EM", legalMsgs] - : [ModifyRoom (\r -> r{gameInfo = liftM + : [ModifyRoom (\r -> r{gameInfo = liftM (\g -> g{ roundMsgs = if B.null nonEmptyMsgs then roundMsgs g else nonEmptyMsgs : roundMsgs g , lastFilteredTimedMsg = fromMaybe (lastFilteredTimedMsg g) lastFTMsg}) @@ -306,7 +306,7 @@ if not $ isMaster cl then [ProtocolError $ loc "Not room master"] else - if illegalName newName then + if illegalName newName then [Warning $ loc "Illegal room name"] else if isSpecial rm then diff -r 4feced261c68 -r de822cd3df3a gameServer/OfficialServer/checker.hs --- a/gameServer/OfficialServer/checker.hs Tue Jan 21 22:38:13 2014 +0100 +++ b/gameServer/OfficialServer/checker.hs Tue Jan 21 22:43:06 2014 +0100 @@ -28,7 +28,7 @@ readInt_ str = case B.readInt str of Just (i, t) | B.null t -> fromIntegral i - _ -> 0 + _ -> 0 data Message = Packet [B.ByteString] | CheckFailed B.ByteString diff -r 4feced261c68 -r de822cd3df3a gameServer/OfficialServer/extdbinterface.hs --- a/gameServer/OfficialServer/extdbinterface.hs Tue Jan 21 22:38:13 2014 +0100 +++ b/gameServer/OfficialServer/extdbinterface.hs Tue Jan 21 22:43:06 2014 +0100 @@ -18,7 +18,7 @@ dbQueryAccount = - "SELECT users.pass, \ + "SELECT users.pass, \ \ (SELECT COUNT(users_roles.rid) FROM users_roles WHERE users.uid = users_roles.uid AND users_roles.rid = 3), \ \ (SELECT COUNT(users_roles.rid) FROM users_roles WHERE users.uid = users_roles.uid AND users_roles.rid = 13) \ \ FROM users WHERE users.name = ?" @@ -71,7 +71,7 @@ SendStats clients rooms -> run dbConn dbQueryStats [SqlInt32 $ fromIntegral clients, SqlInt32 $ fromIntegral rooms] >> return () --StoreAchievements (B.pack fileName) (map toPair teams) info - StoreAchievements p fileName teams info -> + StoreAchievements p fileName teams info -> mapM_ (run dbConn dbQueryAchievement) $ (parseStats p fileName teams) info diff -r 4feced261c68 -r de822cd3df3a gameServer/ServerCore.hs --- a/gameServer/ServerCore.hs Tue Jan 21 22:38:13 2014 +0100 +++ b/gameServer/ServerCore.hs Tue Jan 21 22:43:06 2014 +0100 @@ -62,8 +62,8 @@ TimerAction tick -> mapM_ processAction $ - PingAll - : [StatsAction | even tick] + PingAll + : [StatsAction | even tick] ++ [Cleanup | tick `mod` 100 == 0] diff -r 4feced261c68 -r de822cd3df3a gameServer/Utils.hs --- a/gameServer/Utils.hs Tue Jan 21 22:38:13 2014 +0100 +++ b/gameServer/Utils.hs Tue Jan 21 22:43:06 2014 +0100 @@ -116,7 +116,7 @@ readInt_ str = case B.readInt str of Just (i, t) | B.null t -> fromIntegral i - _ -> 0 + _ -> 0 cutHost :: B.ByteString -> B.ByteString cutHost = B.intercalate "." . flip (++) ["*","*"] . List.take 2 . B.split '.' @@ -128,7 +128,7 @@ upperCase = UTF8.fromString . map Char.toUpper . UTF8.toString roomInfo :: Word16 -> B.ByteString -> RoomInfo -> [B.ByteString] -roomInfo p n r +roomInfo p n r | p < 46 = [ showB $ isJust $ gameInfo r, name r, diff -r 4feced261c68 -r de822cd3df3a hedgewars/hwLibrary.pas --- a/hedgewars/hwLibrary.pas Tue Jan 21 22:38:13 2014 +0100 +++ b/hedgewars/hwLibrary.pas Tue Jan 21 22:43:06 2014 +0100 @@ -106,12 +106,12 @@ procedure JNI_HW_GenLandPreview(env: PJNIEnv; c: JClass; port: JInt); cdecl; begin - GenLandPreview(port); + GenLandPreview(port); end; exports - JNI_HW_versionInfoNet name Java_Prefix+'HWversionInfoNetProto', - JNI_HW_versionInfoVersion name Java_Prefix+'HWversionInfoVersion', + JNI_HW_versionInfoNet name Java_Prefix+'HWversionInfoNetProto', + JNI_HW_versionInfoVersion name Java_Prefix+'HWversionInfoVersion', JNI_HW_GenLandPreview name Java_Prefix + 'HWGenLandPreview', HW_getNumberOfweapons name Java_Prefix + 'HWgetNumberOfWeapons', HW_getMaxNumberOfHogs name Java_Prefix + 'HWgetMaxNumberOfHogs', diff -r 4feced261c68 -r de822cd3df3a hedgewars/sdlmain/SDLMain.m --- a/hedgewars/sdlmain/SDLMain.m Tue Jan 21 22:38:13 2014 +0100 +++ b/hedgewars/sdlmain/SDLMain.m Tue Jan 21 22:43:06 2014 +0100 @@ -18,21 +18,21 @@ @end /* Use this flag to determine whether we use SDLMain.nib or not */ -#define SDL_USE_NIB_FILE 0 +#define SDL_USE_NIB_FILE 0 /* Use this flag to determine whether we use CPS (docking) or not */ -#define SDL_USE_CPS 1 +#define SDL_USE_CPS 1 #ifdef SDL_USE_CPS /* Portions of CPS.h */ typedef struct CPSProcessSerNum { - UInt32 lo; - UInt32 hi; + UInt32 lo; + UInt32 hi; } CPSProcessSerNum; -extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn); -extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5); -extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn); +extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn); +extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5); +extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn); #endif /* SDL_USE_CPS */ @@ -198,8 +198,8 @@ /* Replacement for NSApplicationMain */ static void CustomApplicationMain (int argc, char **argv) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - SDLMain *sdlMain; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + SDLMain *sdlMain; /* Ensure the application object is initialised */ [SDLApplication sharedApplication]; diff -r 4feced261c68 -r de822cd3df3a hedgewars/uAIActions.pas --- a/hedgewars/uAIActions.pas Tue Jan 21 22:38:13 2014 +0100 +++ b/hedgewars/uAIActions.pas Tue Jan 21 22:43:06 2014 +0100 @@ -45,7 +45,7 @@ aia_Put = $800A; aia_waitAngle = $800B; aia_waitAmmoXY = $800C; - + aim_push = $8000; aim_release = $8001; ai_specmask = $8000; @@ -55,7 +55,7 @@ X, Y, Param: LongInt; Time: Longword; end; - + TActions = record Count, Pos: Longword; actions: array[0..Pred(MAXACTIONS)] of TAction; @@ -109,7 +109,7 @@ WriteLnToConsole('AI action: '+SpecActionIdToStr[Action.Action]); if (Action.Action = aia_WaitXL) or (Action.Action = aia_WaitXR) then WriteLnToConsole('AI action Wait X = '+IntToStr(Action.Param)+', current X = '+IntToStr(hwRound(Me^.X))) - + else if (Action.Action = aia_AwareExpl) then WriteLnToConsole('Aware X = ' + IntToStr(Action.X) + ', Y = ' + IntToStr(Action.Y)); end @@ -165,10 +165,10 @@ {$ENDIF} if (Action and ai_specmask) <> 0 then case Action of - aia_Weapon: + aia_Weapon: SetWeapon(TAmmoType(Param)); - - aia_WaitXL: + + aia_WaitXL: if hwRound(Me^.X) = Param then begin Action:= aia_LookLeft; @@ -182,12 +182,12 @@ exit end else - begin + begin CheckHang(Me); exit end; - - aia_WaitXR: + + aia_WaitXR: if hwRound(Me^.X) = Param then begin Action:= aia_LookRight; @@ -201,7 +201,7 @@ exit end else - begin + begin CheckHang(Me); exit end; @@ -222,24 +222,24 @@ else ParseCommand('-right', true); aia_AwareExpl: AwareOfExplosion(X, Y, Param); - + aia_HJump: ParseCommand('hjump', true); - + aia_LJump: ParseCommand('ljump', true); - + aia_Skip: ParseCommand('skip', true); - + aia_Put: doPut(X, Y, true); - + aia_waitAngle: if LongInt(Me^.Angle) <> Abs(Param) then exit; aia_waitAmmoXY: - if (CurAmmoGear <> nil) and ((hwRound(CurAmmoGear^.X) <> X) or (hwRound(CurAmmoGear^.Y) <> Y)) then + if (CurAmmoGear <> nil) and ((hwRound(CurAmmoGear^.X) <> X) or (hwRound(CurAmmoGear^.Y) <> Y)) then exit; end else @@ -249,7 +249,7 @@ case Param of aim_push: s:= '+' + s; - + aim_release: s:= '-' + s; end diff -r 4feced261c68 -r de822cd3df3a hedgewars/uAILandMarks.pas --- a/hedgewars/uAILandMarks.pas Tue Jan 21 22:38:13 2014 +0100 +++ b/hedgewars/uAILandMarks.pas Tue Jan 21 22:43:06 2014 +0100 @@ -1,7 +1,7 @@ unit uAILandMarks; interface -const +const markWalkedHere = $01; markHJumped = $02; markLJumped = $04; @@ -35,13 +35,13 @@ function checkMark(X, Y: LongInt; mark: byte) : boolean; begin - checkMark:= ((X and LAND_WIDTH_MASK) = 0) - and ((Y and LAND_HEIGHT_MASK) = 0) + checkMark:= ((X and LAND_WIDTH_MASK) = 0) + and ((Y and LAND_HEIGHT_MASK) = 0) and ((marks[Y shr gr, X shr gr] and mark) <> 0) end; procedure clearAllMarks; -var +var Y, X: Longword; begin for Y:= 0 to Pred(HEIGHT) do @@ -50,7 +50,7 @@ end; procedure clearMarks(mark: byte); -var +var Y, X: Longword; begin for Y:= 0 to Pred(HEIGHT) do @@ -62,7 +62,7 @@ begin WIDTH:= LAND_WIDTH shr gr; HEIGHT:= LAND_HEIGHT shr gr; - + SetLength(marks, HEIGHT, WIDTH); end; diff -r 4feced261c68 -r de822cd3df3a hedgewars/uCommands.pas --- a/hedgewars/uCommands.pas Tue Jan 21 22:38:13 2014 +0100 +++ b/hedgewars/uCommands.pas Tue Jan 21 22:43:06 2014 +0100 @@ -106,7 +106,7 @@ begin if TrustedSource or t^.Trusted then begin - if t^.Rand and (not CheckNoTeamOrHH) then + if t^.Rand and (not CheckNoTeamOrHH) then CheckSum:= CheckSum xor LongWord(SDLNet_Read32(@CmdStr)) xor LongWord(s[0]) xor GameTicks; t^.Handler(s); end; @@ -139,7 +139,7 @@ if (Message and gmLeft) <> 0 then ParseCommand('/-left', true) else if (Message and gmRight) <> 0 then - ParseCommand('/-right', true) + ParseCommand('/-right', true) else if (Message and gmUp) <> 0 then ParseCommand('/-up', true) else if (Message and gmDown) <> 0 then diff -r 4feced261c68 -r de822cd3df3a hedgewars/uCursor.pas --- a/hedgewars/uCursor.pas Tue Jan 21 22:38:13 2014 +0100 +++ b/hedgewars/uCursor.pas Tue Jan 21 22:43:06 2014 +0100 @@ -25,7 +25,7 @@ var x, y: LongInt; begin SDL_GetMouseState(@x, @y); - + if(x <> cScreenWidth div 2) or (y <> cScreenHeight div 2) then begin handlePositionUpdate(x - cScreenWidth div 2, y - cScreenHeight div 2); diff -r 4feced261c68 -r de822cd3df3a hedgewars/uGearsHandlersRope.pas --- a/hedgewars/uGearsHandlersRope.pas Tue Jan 21 22:38:13 2014 +0100 +++ b/hedgewars/uGearsHandlersRope.pas Tue Jan 21 22:43:06 2014 +0100 @@ -29,13 +29,13 @@ uAmmos, uDebug, uUtils, uGearsHedgehog, uGearsRender; procedure doStepRopeAfterAttack(Gear: PGear); -var +var HHGear: PGear; tX: hwFloat; begin HHGear := Gear^.Hedgehog^.Gear; tX:= HHGear^.X; - if WorldWrap(HHGear) and (WorldEdge = weWrap) and + if WorldWrap(HHGear) and (WorldEdge = weWrap) and ((TestCollisionXwithGear(HHGear, 1) <> 0) or (TestCollisionXwithGear(HHGear, -1) <> 0)) then begin HHGear^.X:= tX; @@ -70,7 +70,7 @@ HHGear^.X := HHGear^.X + HHGear^.dX; HHGear^.Y := HHGear^.Y + HHGear^.dY; HHGear^.dY := HHGear^.dY + cGravity; - + if (GameFlags and gfMoreWind) <> 0 then HHGear^.dX := HHGear^.dX + cWindSpeed / HHGear^.Density; @@ -113,7 +113,7 @@ end; procedure doStepRopeWork(Gear: PGear); -var +var HHGear: PGear; len, tx, ty, nx, ny, ropeDx, ropeDy, mdX, mdY: hwFloat; lx, ly, cd: LongInt; @@ -126,7 +126,7 @@ HHGear := Gear^.Hedgehog^.Gear; tX:= HHGear^.X; - if WorldWrap(HHGear) and (WorldEdge = weWrap) and + if WorldWrap(HHGear) and (WorldEdge = weWrap) and ((TestCollisionXwithGear(HHGear, 1) <> 0) or (TestCollisionXwithGear(HHGear, -1) <> 0)) then begin PlaySound(sndRopeRelease); @@ -405,7 +405,7 @@ end; procedure doStepRopeAttach(Gear: PGear); -var +var HHGear: PGear; tx, ty, tt: hwFloat; begin diff -r 4feced261c68 -r de822cd3df3a hedgewars/uLand.pas --- a/hedgewars/uLand.pas Tue Jan 21 22:38:13 2014 +0100 +++ b/hedgewars/uLand.pas Tue Jan 21 22:43:06 2014 +0100 @@ -37,7 +37,7 @@ procedure ResizeLand(width, height: LongWord); var potW, potH: LongInt; -begin +begin potW:= toPowerOf2(width); potH:= toPowerOf2(height); if (potW <> LAND_WIDTH) or (potH <> LAND_HEIGHT) then @@ -120,7 +120,7 @@ // vertical s:= LAND_HEIGHT; - + for x:= 0 to LAND_WIDTH - 1 do for y:= 0 to LAND_HEIGHT - 1 do if Land[y, x] = 0 then @@ -129,7 +129,7 @@ for i:= max(s, y - 8) to y - 1 do begin if ((x + i) and 16) = 0 then c:= c1 else c:= c2; - + if (cReducedQuality and rqBlurryLand) = 0 then LandPixels[i, x]:= c else @@ -144,17 +144,17 @@ if s + 8 > y then begin if ((x + y) and 16) = 0 then c:= c1 else c:= c2; - + if (cReducedQuality and rqBlurryLand) = 0 then LandPixels[y, x]:= c else LandPixels[y div 2, x div 2]:= c - end; + end; end; - + // horizontal s:= LAND_WIDTH; - + for y:= 0 to LAND_HEIGHT - 1 do for x:= 0 to LAND_WIDTH - 1 do if Land[y, x] = 0 then @@ -163,7 +163,7 @@ for i:= max(s, x - 8) to x - 1 do begin if ((y + i) and 16) = 0 then c:= c1 else c:= c2; - + if (cReducedQuality and rqBlurryLand) = 0 then LandPixels[y, i]:= c else @@ -178,12 +178,12 @@ if s + 8 > x then begin if ((x + y) and 16) = 0 then c:= c1 else c:= c2; - + if (cReducedQuality and rqBlurryLand) = 0 then LandPixels[y, x]:= c else LandPixels[y div 2, x div 2]:= c - end; + end; end end; @@ -375,7 +375,7 @@ dec(l, TemplateCounts[cTemplateFilter]); until l < 0; end else getRandom(1); - + case cTemplateFilter of 0: OutError('Ask unC0Rr about what you did wrong', true); 1: SelectTemplate:= SmallTemplates[getrandom(TemplateCounts[cTemplateFilter])]; @@ -436,12 +436,12 @@ LandSurface2LandPixels(tmpsurf); SDL_FreeSurface(tmpsurf); - + if gameFlags and gfShoppaBorder <> 0 then DrawShoppaBorder; - + for x:= leftX+2 to rightX-2 do for y:= topY+2 to LAND_HEIGHT-3 do - if (Land[y, x] = 0) and + if (Land[y, x] = 0) and (((Land[y, x-1] = lfBasic) and ((Land[y+1,x] = lfBasic)) or (Land[y-1,x] = lfBasic)) or ((Land[y, x+1] = lfBasic) and ((Land[y-1,x] = lfBasic) or (Land[y+1,x] = lfBasic)))) then begin @@ -449,16 +449,16 @@ begin if (Land[y, x-1] = lfBasic) and (LandPixels[y, x-1] and AMask <> 0) then LandPixels[y, x]:= LandPixels[y, x-1] - + else if (Land[y, x+1] = lfBasic) and (LandPixels[y, x+1] and AMask <> 0) then LandPixels[y, x]:= LandPixels[y, x+1] - + else if (Land[y-1, x] = lfBasic) and (LandPixels[y-1, x] and AMask <> 0) then LandPixels[y, x]:= LandPixels[y-1, x] - + else if (Land[y+1, x] = lfBasic) and (LandPixels[y+1, x] and AMask <> 0) then LandPixels[y, x]:= LandPixels[y+1, x]; - + if (((LandPixels[y,x] and AMask) shr AShift) > 10) then LandPixels[y,x]:= (LandPixels[y,x] and (not AMask)) or (128 shl AShift) end; @@ -473,25 +473,25 @@ ((Land[y-1, x] = lfBasic) and (Land[y-1,x+1] = lfBasic) and (Land[y,x+2] = lfBasic)) or ((Land[y+1, x] = lfBasic) and (Land[y+1,x-1] = lfBasic) and (Land[y,x-2] = lfBasic)) or ((Land[y-1, x] = lfBasic) and (Land[y-1,x-1] = lfBasic) and (Land[y,x-2] = lfBasic))) then - + begin - + if (cReducedQuality and rqBlurryLand) = 0 then - + begin - + if (Land[y, x-1] = lfBasic) and (LandPixels[y,x-1] and AMask <> 0) then LandPixels[y, x]:= LandPixels[y, x-1] - + else if (Land[y, x+1] = lfBasic) and (LandPixels[y,x+1] and AMask <> 0) then LandPixels[y, x]:= LandPixels[y, x+1] - + else if (Land[y+1, x] = lfBasic) and (LandPixels[y+1,x] and AMask <> 0) then LandPixels[y, x]:= LandPixels[y+1, x] - + else if (Land[y-1, x] = lfBasic) and (LandPixels[y-1,x] and AMask <> 0) then LandPixels[y, x]:= LandPixels[y-1, x]; - + if (((LandPixels[y,x] and AMask) shr AShift) > 10) then LandPixels[y,x]:= (LandPixels[y,x] and (not AMask)) or (64 shl AShift) end; @@ -778,7 +778,7 @@ if (GameFlags and gfForts = 0) and (maskOnly or (cPathz[ptMapCurrent] = '')) then AddObjects - + else AddProgress(); @@ -834,7 +834,7 @@ rw:= rh*2; end; if rh < rw div 2 then rh:= rw * 2; - + ox:= (rw-LAND_WIDTH) div 2; oy:= rh-LAND_HEIGHT; @@ -850,7 +850,7 @@ cbit:= bit * 8; for yy:= y * lh to y * lh + 7 do for xx:= x * lw + cbit to x * lw + cbit + 7 do - if ((yy-oy) and LAND_HEIGHT_MASK = 0) and ((xx-ox) and LAND_WIDTH_MASK = 0) + if ((yy-oy) and LAND_HEIGHT_MASK = 0) and ((xx-ox) and LAND_WIDTH_MASK = 0) and (Land[yy-oy, xx-ox] <> 0) then inc(t); if t > 8 then diff -r 4feced261c68 -r de822cd3df3a hedgewars/uTextures.pas --- a/hedgewars/uTextures.pas Tue Jan 21 22:38:13 2014 +0100 +++ b/hedgewars/uTextures.pas Tue Jan 21 22:43:06 2014 +0100 @@ -107,11 +107,11 @@ fromP4:= Surf^.pixels; for y:= 0 to Pred(Surf^.h) do begin - for x:= 0 to Pred(Surf^.w) do + for x:= 0 to Pred(Surf^.w) do begin tw:= fromP4^[x]; - tw:= round((tw shr RShift and $FF) * RGB_LUMINANCE_RED + - (tw shr GShift and $FF) * RGB_LUMINANCE_GREEN + + tw:= round((tw shr RShift and $FF) * RGB_LUMINANCE_RED + + (tw shr GShift and $FF) * RGB_LUMINANCE_GREEN + (tw shr BShift and $FF) * RGB_LUMINANCE_BLUE); if tw > 255 then tw:= 255; tw:= (tw and $FF shl RShift) or (tw and $FF shl BShift) or (tw and $FF shl GShift) or (fromP4^[x] and AMask); @@ -242,7 +242,7 @@ begin if TextureList <> nil then WriteToConsole('FIXME FIXME FIXME. App shutdown without full cleanup of texture list; read game0.log and please report this problem'); - while TextureList <> nil do + while TextureList <> nil do begin AddFileLog('Texture not freed: width='+inttostr(LongInt(TextureList^.w))+' height='+inttostr(LongInt(TextureList^.h))+' priority='+inttostr(round(TextureList^.priority*1000))); FreeTexture(TextureList); diff -r 4feced261c68 -r de822cd3df3a misc/liblua/lapi.c --- a/misc/liblua/lapi.c Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/lapi.c Tue Jan 21 22:43:06 2014 +0100 @@ -38,9 +38,9 @@ -#define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base)) +#define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base)) -#define api_checkvalidindex(L, i) api_check(L, (i) != luaO_nilobject) +#define api_checkvalidindex(L, i) api_check(L, (i) != luaO_nilobject) #define api_incr_top(L) {api_check(L, L->top < L->ci->top); L->top++;} diff -r 4feced261c68 -r de822cd3df3a misc/liblua/lauxlib.h --- a/misc/liblua/lauxlib.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/lauxlib.h Tue Jan 21 22:43:06 2014 +0100 @@ -24,7 +24,7 @@ #endif #if defined(LUA_COMPAT_OPENLIB) -#define luaI_openlib luaL_openlib +#define luaI_openlib luaL_openlib #endif @@ -97,26 +97,26 @@ ** =============================================================== */ -#define luaL_argcheck(L, cond,numarg,extramsg) \ - ((void)((cond) || luaL_argerror(L, (numarg), (extramsg)))) -#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) -#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) -#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) -#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) -#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) -#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) +#define luaL_argcheck(L, cond,numarg,extramsg) \ + ((void)((cond) || luaL_argerror(L, (numarg), (extramsg)))) +#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) +#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) +#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) +#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) +#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) +#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) -#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i))) +#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i))) #define luaL_dofile(L, fn) \ - (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0)) + (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0)) #define luaL_dostring(L, s) \ - (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)) + (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)) -#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n))) +#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n))) -#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) +#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) /* ** {====================================================== @@ -127,7 +127,7 @@ typedef struct luaL_Buffer { - char *p; /* current position in buffer */ + char *p; /* current position in buffer */ int lvl; /* number of strings in the stack (level) */ lua_State *L; char buffer[LUAL_BUFFERSIZE]; @@ -138,9 +138,9 @@ (*(B)->p++ = (char)(c))) /* compatibility only */ -#define luaL_putchar(B,c) luaL_addchar(B,c) +#define luaL_putchar(B,c) luaL_addchar(B,c) -#define luaL_addsize(B,n) ((B)->p += (n)) +#define luaL_addsize(B,n) ((B)->p += (n)) LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B); LUALIB_API char *(luaL_prepbuffer) (luaL_Buffer *B); @@ -167,7 +167,7 @@ #define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref)) -#define luaL_reg luaL_Reg +#define luaL_reg luaL_Reg #endif diff -r 4feced261c68 -r de822cd3df3a misc/liblua/lbaselib.c --- a/misc/liblua/lbaselib.c Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/lbaselib.c Tue Jan 21 22:43:06 2014 +0100 @@ -479,10 +479,10 @@ ** ======================================================= */ -#define CO_RUN 0 /* running */ -#define CO_SUS 1 /* suspended */ -#define CO_NOR 2 /* 'normal' (it resumed another coroutine) */ -#define CO_DEAD 3 +#define CO_RUN 0 /* running */ +#define CO_SUS 1 /* suspended */ +#define CO_NOR 2 /* 'normal' (it resumed another coroutine) */ +#define CO_DEAD 3 static const char *const statnames[] = {"running", "suspended", "normal", "dead"}; diff -r 4feced261c68 -r de822cd3df3a misc/liblua/lcode.c --- a/misc/liblua/lcode.c Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/lcode.c Tue Jan 21 22:43:06 2014 +0100 @@ -24,7 +24,7 @@ #include "ltable.h" -#define hasjumps(e) ((e)->t != (e)->f) +#define hasjumps(e) ((e)->t != (e)->f) static int isnumeral(expdesc *e) { diff -r 4feced261c68 -r de822cd3df3a misc/liblua/lcode.h --- a/misc/liblua/lcode.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/lcode.h Tue Jan 21 22:43:06 2014 +0100 @@ -36,11 +36,11 @@ typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; -#define getcode(fs,e) ((fs)->f->code[(e)->u.s.info]) +#define getcode(fs,e) ((fs)->f->code[(e)->u.s.info]) -#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx) +#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx) -#define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET) +#define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET) LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C); diff -r 4feced261c68 -r de822cd3df3a misc/liblua/ldblib.c --- a/misc/liblua/ldblib.c Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/ldblib.c Tue Jan 21 22:43:06 2014 +0100 @@ -315,8 +315,8 @@ } -#define LEVELS1 12 /* size of the first part of the stack */ -#define LEVELS2 10 /* size of the second part of the stack */ +#define LEVELS1 12 /* size of the first part of the stack */ +#define LEVELS2 10 /* size of the second part of the stack */ static int db_errorfb (lua_State *L) { int level; diff -r 4feced261c68 -r de822cd3df3a misc/liblua/ldebug.c --- a/misc/liblua/ldebug.c Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/ldebug.c Tue Jan 21 22:43:06 2014 +0100 @@ -265,11 +265,11 @@ ** ======================================================= */ -#define check(x) if (!(x)) return 0; +#define check(x) if (!(x)) return 0; -#define checkjump(pt,pc) check(0 <= pc && pc < pt->sizecode) +#define checkjump(pt,pc) check(0 <= pc && pc < pt->sizecode) -#define checkreg(pt,reg) check((reg) < (pt)->maxstacksize) +#define checkreg(pt,reg) check((reg) < (pt)->maxstacksize) @@ -285,7 +285,7 @@ } -#define checkopenop(pt,pc) luaG_checkopenop((pt)->code[(pc)+1]) +#define checkopenop(pt,pc) luaG_checkopenop((pt)->code[(pc)+1]) int luaG_checkopenop (Instruction i) { switch (GET_OPCODE(i)) { diff -r 4feced261c68 -r de822cd3df3a misc/liblua/ldebug.h --- a/misc/liblua/ldebug.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/ldebug.h Tue Jan 21 22:43:06 2014 +0100 @@ -11,11 +11,11 @@ #include "lstate.h" -#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1) +#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1) -#define getline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0) +#define getline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0) -#define resethookcount(L) (L->hookcount = L->basehookcount) +#define resethookcount(L) (L->hookcount = L->basehookcount) LUAI_FUNC void luaG_typeerror (lua_State *L, const TValue *o, diff -r 4feced261c68 -r de822cd3df3a misc/liblua/ldo.h --- a/misc/liblua/ldo.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/ldo.h Tue Jan 21 22:43:06 2014 +0100 @@ -13,7 +13,7 @@ #include "lzio.h" -#define luaD_checkstack(L,n) \ +#define luaD_checkstack(L,n) \ if ((char *)L->stack_last - (char *)L->top <= (n)*(int)sizeof(TValue)) \ luaD_growstack(L, n); \ else condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); @@ -21,17 +21,17 @@ #define incr_top(L) {luaD_checkstack(L,1); L->top++;} -#define savestack(L,p) ((char *)(p) - (char *)L->stack) -#define restorestack(L,n) ((TValue *)((char *)L->stack + (n))) +#define savestack(L,p) ((char *)(p) - (char *)L->stack) +#define restorestack(L,n) ((TValue *)((char *)L->stack + (n))) -#define saveci(L,p) ((char *)(p) - (char *)L->base_ci) -#define restoreci(L,n) ((CallInfo *)((char *)L->base_ci + (n))) +#define saveci(L,p) ((char *)(p) - (char *)L->base_ci) +#define restoreci(L,n) ((CallInfo *)((char *)L->base_ci + (n))) /* results from luaD_precall */ -#define PCRLUA 0 /* initiated a call to a Lua function */ -#define PCRC 1 /* did a call to a C function */ -#define PCRYIELD 2 /* C funtion yielded */ +#define PCRLUA 0 /* initiated a call to a Lua function */ +#define PCRC 1 /* did a call to a C function */ +#define PCRYIELD 2 /* C funtion yielded */ /* type of protected functions, to be ran by `runprotected' */ diff -r 4feced261c68 -r de822cd3df3a misc/liblua/ldump.c --- a/misc/liblua/ldump.c Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/ldump.c Tue Jan 21 22:43:06 2014 +0100 @@ -23,8 +23,8 @@ int status; } DumpState; -#define DumpMem(b,n,size,D) DumpBlock(b,(n)*(size),D) -#define DumpVar(x,D) DumpMem(&x,1,sizeof(x),D) +#define DumpMem(b,n,size,D) DumpBlock(b,(n)*(size),D) +#define DumpVar(x,D) DumpMem(&x,1,sizeof(x),D) static void DumpBlock(const void* b, size_t size, DumpState* D) { @@ -67,13 +67,13 @@ } else { - size_t size=s->tsv.len+1; /* include trailing '\0' */ + size_t size=s->tsv.len+1; /* include trailing '\0' */ DumpVar(size,D); DumpBlock(getstr(s),size,D); } } -#define DumpCode(f,D) DumpVector(f->code,f->sizecode,sizeof(Instruction),D) +#define DumpCode(f,D) DumpVector(f->code,f->sizecode,sizeof(Instruction),D) static void DumpFunction(const Proto* f, const TString* p, DumpState* D); @@ -88,19 +88,19 @@ switch (ttype(o)) { case LUA_TNIL: - break; + break; case LUA_TBOOLEAN: - DumpChar(bvalue(o),D); - break; + DumpChar(bvalue(o),D); + break; case LUA_TNUMBER: - DumpNumber(nvalue(o),D); - break; + DumpNumber(nvalue(o),D); + break; case LUA_TSTRING: - DumpString(rawtsvalue(o),D); - break; + DumpString(rawtsvalue(o),D); + break; default: - lua_assert(0); /* cannot happen */ - break; + lua_assert(0); /* cannot happen */ + break; } } n=f->sizep; diff -r 4feced261c68 -r de822cd3df3a misc/liblua/lfunc.h --- a/misc/liblua/lfunc.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/lfunc.h Tue Jan 21 22:43:06 2014 +0100 @@ -11,10 +11,10 @@ #include "lobject.h" -#define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \ +#define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \ cast(int, sizeof(TValue)*((n)-1))) -#define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \ +#define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \ cast(int, sizeof(TValue *)*((n)-1))) diff -r 4feced261c68 -r de822cd3df3a misc/liblua/lgc.c --- a/misc/liblua/lgc.c Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/lgc.c Tue Jan 21 22:43:06 2014 +0100 @@ -23,25 +23,25 @@ #include "ltm.h" -#define GCSTEPSIZE 1024u -#define GCSWEEPMAX 40 -#define GCSWEEPCOST 10 -#define GCFINALIZECOST 100 +#define GCSTEPSIZE 1024u +#define GCSWEEPMAX 40 +#define GCSWEEPCOST 10 +#define GCFINALIZECOST 100 -#define maskmarks cast_byte(~(bitmask(BLACKBIT)|WHITEBITS)) +#define maskmarks cast_byte(~(bitmask(BLACKBIT)|WHITEBITS)) -#define makewhite(g,x) \ +#define makewhite(g,x) \ ((x)->gch.marked = cast_byte(((x)->gch.marked & maskmarks) | luaC_white(g))) -#define white2gray(x) reset2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT) -#define black2gray(x) resetbit((x)->gch.marked, BLACKBIT) +#define white2gray(x) reset2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT) +#define black2gray(x) resetbit((x)->gch.marked, BLACKBIT) -#define stringmark(s) reset2bits((s)->tsv.marked, WHITE0BIT, WHITE1BIT) +#define stringmark(s) reset2bits((s)->tsv.marked, WHITE0BIT, WHITE1BIT) -#define isfinalized(u) testbit((u)->marked, FINALIZEDBIT) -#define markfinalized(u) l_setbit((u)->marked, FINALIZEDBIT) +#define isfinalized(u) testbit((u)->marked, FINALIZEDBIT) +#define markfinalized(u) l_setbit((u)->marked, FINALIZEDBIT) #define KEYWEAK bitmask(KEYWEAKBIT) @@ -53,7 +53,7 @@ if (iscollectable(o) && iswhite(gcvalue(o))) reallymarkobject(g,gcvalue(o)); } #define markobject(g,t) { if (iswhite(obj2gco(t))) \ - reallymarkobject(g, obj2gco(t)); } + reallymarkobject(g, obj2gco(t)); } #define setthreshold(g) (g->GCthreshold = (g->estimate/100) * g->gcpause) @@ -401,7 +401,7 @@ -#define sweepwholelist(L,p) sweeplist(L,p,MAX_LUMEM) +#define sweepwholelist(L,p) sweeplist(L,p,MAX_LUMEM) static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { diff -r 4feced261c68 -r de822cd3df3a misc/liblua/lgc.h --- a/misc/liblua/lgc.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/lgc.h Tue Jan 21 22:43:06 2014 +0100 @@ -14,27 +14,27 @@ /* ** Possible states of the Garbage Collector */ -#define GCSpause 0 -#define GCSpropagate 1 -#define GCSsweepstring 2 -#define GCSsweep 3 -#define GCSfinalize 4 +#define GCSpause 0 +#define GCSpropagate 1 +#define GCSsweepstring 2 +#define GCSsweep 3 +#define GCSfinalize 4 /* ** some userful bit tricks */ -#define resetbits(x,m) ((x) &= cast(lu_byte, ~(m))) -#define setbits(x,m) ((x) |= (m)) -#define testbits(x,m) ((x) & (m)) -#define bitmask(b) (1<<(b)) -#define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2)) -#define l_setbit(x,b) setbits(x, bitmask(b)) -#define resetbit(x,b) resetbits(x, bitmask(b)) -#define testbit(x,b) testbits(x, bitmask(b)) -#define set2bits(x,b1,b2) setbits(x, (bit2mask(b1, b2))) -#define reset2bits(x,b1,b2) resetbits(x, (bit2mask(b1, b2))) -#define test2bits(x,b1,b2) testbits(x, (bit2mask(b1, b2))) +#define resetbits(x,m) ((x) &= cast(lu_byte, ~(m))) +#define setbits(x,m) ((x) |= (m)) +#define testbits(x,m) ((x) & (m)) +#define bitmask(b) (1<<(b)) +#define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2)) +#define l_setbit(x,b) setbits(x, bitmask(b)) +#define resetbit(x,b) resetbits(x, bitmask(b)) +#define testbit(x,b) testbits(x, bitmask(b)) +#define set2bits(x,b1,b2) setbits(x, (bit2mask(b1, b2))) +#define reset2bits(x,b1,b2) resetbits(x, (bit2mask(b1, b2))) +#define test2bits(x,b1,b2) testbits(x, (bit2mask(b1, b2))) @@ -51,47 +51,47 @@ */ -#define WHITE0BIT 0 -#define WHITE1BIT 1 -#define BLACKBIT 2 -#define FINALIZEDBIT 3 -#define KEYWEAKBIT 3 -#define VALUEWEAKBIT 4 -#define FIXEDBIT 5 -#define SFIXEDBIT 6 -#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) +#define WHITE0BIT 0 +#define WHITE1BIT 1 +#define BLACKBIT 2 +#define FINALIZEDBIT 3 +#define KEYWEAKBIT 3 +#define VALUEWEAKBIT 4 +#define FIXEDBIT 5 +#define SFIXEDBIT 6 +#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) #define iswhite(x) test2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT) #define isblack(x) testbit((x)->gch.marked, BLACKBIT) -#define isgray(x) (!isblack(x) && !iswhite(x)) +#define isgray(x) (!isblack(x) && !iswhite(x)) -#define otherwhite(g) (g->currentwhite ^ WHITEBITS) -#define isdead(g,v) ((v)->gch.marked & otherwhite(g) & WHITEBITS) +#define otherwhite(g) (g->currentwhite ^ WHITEBITS) +#define isdead(g,v) ((v)->gch.marked & otherwhite(g) & WHITEBITS) -#define changewhite(x) ((x)->gch.marked ^= WHITEBITS) -#define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT) +#define changewhite(x) ((x)->gch.marked ^= WHITEBITS) +#define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT) -#define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x))) +#define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x))) -#define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) +#define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) #define luaC_checkGC(L) { \ condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); \ if (G(L)->totalbytes >= G(L)->GCthreshold) \ - luaC_step(L); } + luaC_step(L); } #define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \ - luaC_barrierf(L,obj2gco(p),gcvalue(v)); } + luaC_barrierf(L,obj2gco(p),gcvalue(v)); } #define luaC_barriert(L,t,v) { if (valiswhite(v) && isblack(obj2gco(t))) \ - luaC_barrierback(L,t); } + luaC_barrierback(L,t); } #define luaC_objbarrier(L,p,o) \ - { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \ - luaC_barrierf(L,obj2gco(p),obj2gco(o)); } + { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \ + luaC_barrierf(L,obj2gco(p),obj2gco(o)); } #define luaC_objbarriert(L,t,o) \ { if (iswhite(obj2gco(o)) && isblack(obj2gco(t))) luaC_barrierback(L,t); } diff -r 4feced261c68 -r de822cd3df3a misc/liblua/liolib.c --- a/misc/liblua/liolib.c Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/liolib.c Tue Jan 21 22:43:06 2014 +0100 @@ -20,8 +20,8 @@ -#define IO_INPUT 1 -#define IO_OUTPUT 2 +#define IO_INPUT 1 +#define IO_OUTPUT 2 static const char *const fnames[] = {"input", "output"}; @@ -51,7 +51,7 @@ } -#define tofilep(L) ((FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE)) +#define tofilep(L) ((FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE)) static int io_type (lua_State *L) { diff -r 4feced261c68 -r de822cd3df3a misc/liblua/llex.c --- a/misc/liblua/llex.c Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/llex.c Tue Jan 21 22:43:06 2014 +0100 @@ -30,7 +30,7 @@ -#define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r') +#define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r') /* ORDER RESERVED */ diff -r 4feced261c68 -r de822cd3df3a misc/liblua/llex.h --- a/misc/liblua/llex.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/llex.h Tue Jan 21 22:43:06 2014 +0100 @@ -11,10 +11,10 @@ #include "lzio.h" -#define FIRST_RESERVED 257 +#define FIRST_RESERVED 257 /* maximum length of a reserved word */ -#define TOKEN_LEN (sizeof("function")/sizeof(char)) +#define TOKEN_LEN (sizeof("function")/sizeof(char)) /* @@ -33,7 +33,7 @@ }; /* number of reserved words */ -#define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1)) +#define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1)) /* array with token `names' */ diff -r 4feced261c68 -r de822cd3df3a misc/liblua/llimits.h --- a/misc/liblua/llimits.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/llimits.h Tue Jan 21 22:43:06 2014 +0100 @@ -27,9 +27,9 @@ typedef unsigned char lu_byte; -#define MAX_SIZET ((size_t)(~(size_t)0)-2) +#define MAX_SIZET ((size_t)(~(size_t)0)-2) -#define MAX_LUMEM ((lu_mem)(~(lu_mem)0)-2) +#define MAX_LUMEM ((lu_mem)(~(lu_mem)0)-2) #define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */ @@ -54,30 +54,30 @@ /* internal assertions for in-house debugging */ #ifdef lua_assert -#define check_exp(c,e) (lua_assert(c), (e)) -#define api_check(l,e) lua_assert(e) +#define check_exp(c,e) (lua_assert(c), (e)) +#define api_check(l,e) lua_assert(e) #else -#define lua_assert(c) ((void)0) -#define check_exp(c,e) (e) -#define api_check luai_apicheck +#define lua_assert(c) ((void)0) +#define check_exp(c,e) (e) +#define api_check luai_apicheck #endif #ifndef UNUSED -#define UNUSED(x) ((void)(x)) /* to avoid warnings */ +#define UNUSED(x) ((void)(x)) /* to avoid warnings */ #endif #ifndef cast -#define cast(t, exp) ((t)(exp)) +#define cast(t, exp) ((t)(exp)) #endif -#define cast_byte(i) cast(lu_byte, (i)) -#define cast_num(i) cast(lua_Number, (i)) -#define cast_int(i) cast(int, (i)) +#define cast_byte(i) cast(lu_byte, (i)) +#define cast_num(i) cast(lua_Number, (i)) +#define cast_int(i) cast(int, (i)) @@ -90,19 +90,19 @@ /* maximum stack for a Lua function */ -#define MAXSTACK 250 +#define MAXSTACK 250 /* minimum size for the string table (must be power of 2) */ #ifndef MINSTRTABSIZE -#define MINSTRTABSIZE 32 +#define MINSTRTABSIZE 32 #endif /* minimum size for string buffer */ #ifndef LUA_MINBUFFER -#define LUA_MINBUFFER 32 +#define LUA_MINBUFFER 32 #endif @@ -120,9 +120,9 @@ ** macro to control inclusion of some hard tests on stack reallocation */ #ifndef HARDSTACKTESTS -#define condhardstacktests(x) ((void)0) +#define condhardstacktests(x) ((void)0) #else -#define condhardstacktests(x) x +#define condhardstacktests(x) x #endif #endif diff -r 4feced261c68 -r de822cd3df3a misc/liblua/lmem.c --- a/misc/liblua/lmem.c Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/lmem.c Tue Jan 21 22:43:06 2014 +0100 @@ -40,7 +40,7 @@ -#define MINSIZEARRAY 4 +#define MINSIZEARRAY 4 void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems, diff -r 4feced261c68 -r de822cd3df3a misc/liblua/lmem.h --- a/misc/liblua/lmem.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/lmem.h Tue Jan 21 22:43:06 2014 +0100 @@ -13,22 +13,22 @@ #include "llimits.h" #include "lua.h" -#define MEMERRMSG "not enough memory" +#define MEMERRMSG "not enough memory" #define luaM_reallocv(L,b,on,n,e) \ - ((cast(size_t, (n)+1) <= MAX_SIZET/(e)) ? /* +1 to avoid warnings */ \ - luaM_realloc_(L, (b), (on)*(e), (n)*(e)) : \ - luaM_toobig(L)) + ((cast(size_t, (n)+1) <= MAX_SIZET/(e)) ? /* +1 to avoid warnings */ \ + luaM_realloc_(L, (b), (on)*(e), (n)*(e)) : \ + luaM_toobig(L)) -#define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0) -#define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0) +#define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0) +#define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0) #define luaM_freearray(L, b, n, t) luaM_reallocv(L, (b), n, 0, sizeof(t)) -#define luaM_malloc(L,t) luaM_realloc_(L, NULL, 0, (t)) -#define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t))) +#define luaM_malloc(L,t) luaM_realloc_(L, NULL, 0, (t)) +#define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t))) #define luaM_newvector(L,n,t) \ - cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t))) + cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t))) #define luaM_growvector(L,v,nelems,size,t,limit,e) \ if ((nelems)+1 > (size)) \ diff -r 4feced261c68 -r de822cd3df3a misc/liblua/loadlib.c --- a/misc/liblua/loadlib.c Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/loadlib.c Tue Jan 21 22:43:06 2014 +0100 @@ -23,23 +23,23 @@ /* prefix for open functions in C libraries */ -#define LUA_POF "luaopen_" +#define LUA_POF "luaopen_" /* separator for open functions in C libraries */ -#define LUA_OFSEP "_" +#define LUA_OFSEP "_" -#define LIBPREFIX "LOADLIB: " +#define LIBPREFIX "LOADLIB: " -#define POF LUA_POF -#define LIB_FAIL "open" +#define POF LUA_POF +#define LIB_FAIL "open" /* error codes for ll_loadfunc */ -#define ERRLIB 1 -#define ERRFUNC 2 +#define ERRLIB 1 +#define ERRFUNC 2 -#define setprogdir(L) ((void)0) +#define setprogdir(L) ((void)0) static void ll_unloadlib (void *lib); @@ -153,7 +153,7 @@ /* Mac appends a `_' before C function names */ #undef POF -#define POF "_" LUA_POF +#define POF "_" LUA_POF static void pusherror (lua_State *L) { @@ -230,10 +230,10 @@ */ #undef LIB_FAIL -#define LIB_FAIL "absent" +#define LIB_FAIL "absent" -#define DLMSG "dynamic libraries not enabled; check your Lua installation" +#define DLMSG "dynamic libraries not enabled; check your Lua installation" static void ll_unloadlib (void *lib) { @@ -445,7 +445,7 @@ static const int sentinel_ = 0; -#define sentinel ((void *)&sentinel_) +#define sentinel ((void *)&sentinel_) static int ll_require (lua_State *L) { @@ -587,7 +587,7 @@ /* auxiliary mark (for internal use) */ -#define AUXMARK "\1" +#define AUXMARK "\1" static void setpath (lua_State *L, const char *fieldname, const char *envname, const char *def) { diff -r 4feced261c68 -r de822cd3df3a misc/liblua/lobject.h --- a/misc/liblua/lobject.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/lobject.h Tue Jan 21 22:43:06 2014 +0100 @@ -17,17 +17,17 @@ /* tags for values visible from Lua */ -#define LAST_TAG LUA_TTHREAD +#define LAST_TAG LUA_TTHREAD -#define NUM_TAGS (LAST_TAG+1) +#define NUM_TAGS (LAST_TAG+1) /* ** Extra tags for non-values */ -#define LUA_TPROTO (LAST_TAG+1) -#define LUA_TUPVAL (LAST_TAG+2) -#define LUA_TDEADKEY (LAST_TAG+3) +#define LUA_TPROTO (LAST_TAG+1) +#define LUA_TUPVAL (LAST_TAG+2) +#define LUA_TDEADKEY (LAST_TAG+3) /* @@ -40,7 +40,7 @@ ** Common Header for all collectable objects (in macro form, to be ** included in other objects) */ -#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked +#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked /* @@ -68,7 +68,7 @@ ** Tagged Values */ -#define TValuefields Value value; int tt +#define TValuefields Value value; int tt typedef struct lua_TValue { TValuefields; @@ -76,31 +76,31 @@ /* Macros to test type */ -#define ttisnil(o) (ttype(o) == LUA_TNIL) -#define ttisnumber(o) (ttype(o) == LUA_TNUMBER) -#define ttisstring(o) (ttype(o) == LUA_TSTRING) -#define ttistable(o) (ttype(o) == LUA_TTABLE) -#define ttisfunction(o) (ttype(o) == LUA_TFUNCTION) -#define ttisboolean(o) (ttype(o) == LUA_TBOOLEAN) -#define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA) -#define ttisthread(o) (ttype(o) == LUA_TTHREAD) -#define ttislightuserdata(o) (ttype(o) == LUA_TLIGHTUSERDATA) +#define ttisnil(o) (ttype(o) == LUA_TNIL) +#define ttisnumber(o) (ttype(o) == LUA_TNUMBER) +#define ttisstring(o) (ttype(o) == LUA_TSTRING) +#define ttistable(o) (ttype(o) == LUA_TTABLE) +#define ttisfunction(o) (ttype(o) == LUA_TFUNCTION) +#define ttisboolean(o) (ttype(o) == LUA_TBOOLEAN) +#define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA) +#define ttisthread(o) (ttype(o) == LUA_TTHREAD) +#define ttislightuserdata(o) (ttype(o) == LUA_TLIGHTUSERDATA) /* Macros to access values */ -#define ttype(o) ((o)->tt) -#define gcvalue(o) check_exp(iscollectable(o), (o)->value.gc) -#define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p) -#define nvalue(o) check_exp(ttisnumber(o), (o)->value.n) -#define rawtsvalue(o) check_exp(ttisstring(o), &(o)->value.gc->ts) -#define tsvalue(o) (&rawtsvalue(o)->tsv) -#define rawuvalue(o) check_exp(ttisuserdata(o), &(o)->value.gc->u) -#define uvalue(o) (&rawuvalue(o)->uv) -#define clvalue(o) check_exp(ttisfunction(o), &(o)->value.gc->cl) -#define hvalue(o) check_exp(ttistable(o), &(o)->value.gc->h) -#define bvalue(o) check_exp(ttisboolean(o), (o)->value.b) -#define thvalue(o) check_exp(ttisthread(o), &(o)->value.gc->th) +#define ttype(o) ((o)->tt) +#define gcvalue(o) check_exp(iscollectable(o), (o)->value.gc) +#define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p) +#define nvalue(o) check_exp(ttisnumber(o), (o)->value.n) +#define rawtsvalue(o) check_exp(ttisstring(o), &(o)->value.gc->ts) +#define tsvalue(o) (&rawtsvalue(o)->tsv) +#define rawuvalue(o) check_exp(ttisuserdata(o), &(o)->value.gc->u) +#define uvalue(o) (&rawuvalue(o)->uv) +#define clvalue(o) check_exp(ttisfunction(o), &(o)->value.gc->cl) +#define hvalue(o) check_exp(ttistable(o), &(o)->value.gc->h) +#define bvalue(o) check_exp(ttisboolean(o), (o)->value.b) +#define thvalue(o) check_exp(ttisthread(o), &(o)->value.gc->th) -#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0)) +#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0)) /* ** for internal debug only @@ -169,24 +169,24 @@ */ /* from stack to (same) stack */ -#define setobjs2s setobj +#define setobjs2s setobj /* to stack (not from same stack) */ -#define setobj2s setobj -#define setsvalue2s setsvalue -#define sethvalue2s sethvalue -#define setptvalue2s setptvalue +#define setobj2s setobj +#define setsvalue2s setsvalue +#define sethvalue2s sethvalue +#define setptvalue2s setptvalue /* from table to same table */ -#define setobjt2t setobj +#define setobjt2t setobj /* to table */ -#define setobj2t setobj +#define setobj2t setobj /* to new object */ -#define setobj2n setobj -#define setsvalue2n setsvalue +#define setobj2n setobj +#define setsvalue2n setsvalue #define setttype(obj, tt) (ttype(obj) = (tt)) -#define iscollectable(o) (ttype(o) >= LUA_TSTRING) +#define iscollectable(o) (ttype(o) >= LUA_TSTRING) @@ -207,7 +207,7 @@ } TString; -#define getstr(ts) cast(const char *, (ts) + 1) +#define getstr(ts) cast(const char *, (ts) + 1) #define svalue(o) getstr(rawtsvalue(o)) @@ -254,9 +254,9 @@ /* masks for new-style vararg */ -#define VARARG_HASARG 1 -#define VARARG_ISVARARG 2 -#define VARARG_NEEDSARG 4 +#define VARARG_HASARG 1 +#define VARARG_ISVARARG 2 +#define VARARG_NEEDSARG 4 typedef struct LocVar { @@ -289,8 +289,8 @@ */ #define ClosureHeader \ - CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist; \ - struct Table *env + CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist; \ + struct Table *env typedef struct CClosure { ClosureHeader; @@ -312,8 +312,8 @@ } Closure; -#define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->c.isC) -#define isLfunction(o) (ttype(o) == LUA_TFUNCTION && !clvalue(o)->c.isC) +#define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->c.isC) +#define isLfunction(o) (ttype(o) == LUA_TFUNCTION && !clvalue(o)->c.isC) /* @@ -353,18 +353,18 @@ ** `module' operation for hashing (size is always a power of 2) */ #define lmod(s,size) \ - (check_exp((size&(size-1))==0, (cast(int, (s) & ((size)-1))))) + (check_exp((size&(size-1))==0, (cast(int, (s) & ((size)-1))))) -#define twoto(x) (1<<(x)) -#define sizenode(t) (twoto((t)->lsizenode)) +#define twoto(x) (1<<(x)) +#define sizenode(t) (twoto((t)->lsizenode)) -#define luaO_nilobject (&luaO_nilobject_) +#define luaO_nilobject (&luaO_nilobject_) LUAI_DATA const TValue luaO_nilobject_; -#define ceillog2(x) (luaO_log2((x)-1) + 1) +#define ceillog2(x) (luaO_log2((x)-1) + 1) LUAI_FUNC int luaO_log2 (unsigned int x); LUAI_FUNC int luaO_int2fb (unsigned int x); diff -r 4feced261c68 -r de822cd3df3a misc/liblua/lopcodes.c --- a/misc/liblua/lopcodes.c Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/lopcodes.c Tue Jan 21 22:43:06 2014 +0100 @@ -59,44 +59,44 @@ #define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m)) const lu_byte luaP_opmodes[NUM_OPCODES] = { -/* T A B C mode opcode */ - opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */ - ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */ - ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */ - ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LOADNIL */ - ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */ - ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_GETGLOBAL */ - ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */ - ,opmode(0, 0, OpArgK, OpArgN, iABx) /* OP_SETGLOBAL */ - ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */ - ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */ - ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */ - ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */ - ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */ - ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */ - ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */ - ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */ - ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */ - ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */ - ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */ - ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */ - ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */ - ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */ - ,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */ - ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */ - ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */ - ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */ - ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TEST */ - ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */ - ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */ - ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */ - ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */ - ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */ - ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */ - ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TFORLOOP */ - ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */ - ,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */ - ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */ - ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */ +/* T A B C mode opcode */ + opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */ + ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */ + ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */ + ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LOADNIL */ + ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */ + ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_GETGLOBAL */ + ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */ + ,opmode(0, 0, OpArgK, OpArgN, iABx) /* OP_SETGLOBAL */ + ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */ + ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */ + ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */ + ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */ + ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */ + ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */ + ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */ + ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */ + ,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */ + ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */ + ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */ + ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */ + ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TEST */ + ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */ + ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */ + ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */ + ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */ + ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */ + ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */ + ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TFORLOOP */ + ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */ + ,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */ + ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */ + ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */ }; diff -r 4feced261c68 -r de822cd3df3a misc/liblua/lopcodes.h --- a/misc/liblua/lopcodes.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/lopcodes.h Tue Jan 21 22:43:06 2014 +0100 @@ -14,11 +14,11 @@ We assume that instructions are unsigned numbers. All instructions have an opcode in the first 6 bits. Instructions can have the following fields: - `A' : 8 bits - `B' : 9 bits - `C' : 9 bits - `Bx' : 18 bits (`B' and `C' together) - `sBx' : signed Bx + `A' : 8 bits + `B' : 9 bits + `C' : 9 bits + `Bx' : 18 bits (`B' and `C' together) + `sBx' : signed Bx A signed argument is represented in excess K; that is, the number value is the unsigned value minus K. K is exactly the maximum value @@ -34,18 +34,18 @@ /* ** size and position of opcode arguments. */ -#define SIZE_C 9 -#define SIZE_B 9 -#define SIZE_Bx (SIZE_C + SIZE_B) -#define SIZE_A 8 +#define SIZE_C 9 +#define SIZE_B 9 +#define SIZE_Bx (SIZE_C + SIZE_B) +#define SIZE_A 8 -#define SIZE_OP 6 +#define SIZE_OP 6 -#define POS_OP 0 -#define POS_A (POS_OP + SIZE_OP) -#define POS_C (POS_A + SIZE_A) -#define POS_B (POS_C + SIZE_C) -#define POS_Bx POS_C +#define POS_OP 0 +#define POS_A (POS_OP + SIZE_OP) +#define POS_C (POS_A + SIZE_A) +#define POS_B (POS_C + SIZE_C) +#define POS_Bx POS_C /* @@ -68,47 +68,47 @@ /* creates a mask with `n' 1 bits at position `p' */ -#define MASK1(n,p) ((~((~(Instruction)0)<>POS_OP) & MASK1(SIZE_OP,0))) -#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \ - ((cast(Instruction, o)<>POS_OP) & MASK1(SIZE_OP,0))) +#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \ + ((cast(Instruction, o)<>POS_A) & MASK1(SIZE_A,0))) -#define SETARG_A(i,u) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \ - ((cast(Instruction, u)<>POS_A) & MASK1(SIZE_A,0))) +#define SETARG_A(i,u) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \ + ((cast(Instruction, u)<>POS_B) & MASK1(SIZE_B,0))) -#define SETARG_B(i,b) ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \ - ((cast(Instruction, b)<>POS_B) & MASK1(SIZE_B,0))) +#define SETARG_B(i,b) ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \ + ((cast(Instruction, b)<>POS_C) & MASK1(SIZE_C,0))) -#define SETARG_C(i,b) ((i) = (((i)&MASK0(SIZE_C,POS_C)) | \ - ((cast(Instruction, b)<>POS_C) & MASK1(SIZE_C,0))) +#define SETARG_C(i,b) ((i) = (((i)&MASK0(SIZE_C,POS_C)) | \ + ((cast(Instruction, b)<>POS_Bx) & MASK1(SIZE_Bx,0))) -#define SETARG_Bx(i,b) ((i) = (((i)&MASK0(SIZE_Bx,POS_Bx)) | \ - ((cast(Instruction, b)<>POS_Bx) & MASK1(SIZE_Bx,0))) +#define SETARG_Bx(i,b) ((i) = (((i)&MASK0(SIZE_Bx,POS_Bx)) | \ + ((cast(Instruction, b)< C) then pc++ */ -OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */ +OP_TEST,/* A C if not (R(A) <=> C) then pc++ */ +OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */ -OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */ -OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ -OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */ +OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */ +OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ +OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */ -OP_FORLOOP,/* A sBx R(A)+=R(A+2); - if R(A) =) R(A)*/ -OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */ +OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/ +OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */ -OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */ +OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */ } OpCode; -#define NUM_OPCODES (cast(int, OP_VARARG) + 1) +#define NUM_OPCODES (cast(int, OP_VARARG) + 1) @@ -251,18 +251,18 @@ LUAI_DATA const lu_byte luaP_opmodes[NUM_OPCODES]; -#define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3)) -#define getBMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3)) -#define getCMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3)) -#define testAMode(m) (luaP_opmodes[m] & (1 << 6)) -#define testTMode(m) (luaP_opmodes[m] & (1 << 7)) +#define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3)) +#define getBMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3)) +#define getCMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3)) +#define testAMode(m) (luaP_opmodes[m] & (1 << 6)) +#define testTMode(m) (luaP_opmodes[m] & (1 << 7)) LUAI_DATA const char *const luaP_opnames[NUM_OPCODES+1]; /* opcode names */ /* number of list items to accumulate before a SETLIST instruction */ -#define LFIELDS_PER_FLUSH 50 +#define LFIELDS_PER_FLUSH 50 #endif diff -r 4feced261c68 -r de822cd3df3a misc/liblua/lparser.c --- a/misc/liblua/lparser.c Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/lparser.c Tue Jan 21 22:43:06 2014 +0100 @@ -27,11 +27,11 @@ -#define hasmultret(k) ((k) == VCALL || (k) == VVARARG) +#define hasmultret(k) ((k) == VCALL || (k) == VVARARG) -#define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]]) +#define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]]) -#define luaY_checklimit(fs,v,l,m) if ((v)>(l)) errorlimit(fs,l,m) +#define luaY_checklimit(fs,v,l,m) if ((v)>(l)) errorlimit(fs,l,m) /* @@ -97,7 +97,7 @@ } -#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); } +#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); } @@ -275,11 +275,11 @@ static void enterlevel (LexState *ls) { if (++ls->L->nCcalls > LUAI_MAXCCALLS) - luaX_lexerror(ls, "chunk has too many syntax levels", 0); + luaX_lexerror(ls, "chunk has too many syntax levels", 0); } -#define leavelevel(ls) ((ls)->L->nCcalls--) +#define leavelevel(ls) ((ls)->L->nCcalls--) static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isbreakable) { @@ -818,7 +818,7 @@ {2, 2}, {1, 1} /* logical (and/or) */ }; -#define UNARY_PRIORITY 8 /* priority for unary operators */ +#define UNARY_PRIORITY 8 /* priority for unary operators */ /* diff -r 4feced261c68 -r de822cd3df3a misc/liblua/lparser.h --- a/misc/liblua/lparser.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/lparser.h Tue Jan 21 22:43:06 2014 +0100 @@ -17,21 +17,21 @@ */ typedef enum { - VVOID, /* no value */ + VVOID, /* no value */ VNIL, VTRUE, VFALSE, - VK, /* info = index of constant in `k' */ - VKNUM, /* nval = numerical value */ - VLOCAL, /* info = local register */ + VK, /* info = index of constant in `k' */ + VKNUM, /* nval = numerical value */ + VLOCAL, /* info = local register */ VUPVAL, /* info = index of upvalue in `upvalues' */ - VGLOBAL, /* info = index of table; aux = index of global name in `k' */ - VINDEXED, /* info = table register; aux = index register (or `k') */ - VJMP, /* info = instruction pc */ - VRELOCABLE, /* info = instruction pc */ - VNONRELOC, /* info = result register */ - VCALL, /* info = instruction pc */ - VVARARG /* info = instruction pc */ + VGLOBAL, /* info = index of table; aux = index of global name in `k' */ + VINDEXED, /* info = table register; aux = index register (or `k') */ + VJMP, /* info = instruction pc */ + VRELOCABLE, /* info = instruction pc */ + VNONRELOC, /* info = result register */ + VCALL, /* info = instruction pc */ + VVARARG /* info = instruction pc */ } expkind; typedef struct expdesc { diff -r 4feced261c68 -r de822cd3df3a misc/liblua/lstate.c --- a/misc/liblua/lstate.c Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/lstate.c Tue Jan 21 22:43:06 2014 +0100 @@ -24,8 +24,8 @@ #include "ltm.h" -#define state_size(x) (sizeof(x) + LUAI_EXTRASPACE) -#define fromstate(l) (cast(lu_byte *, (l)) - LUAI_EXTRASPACE) +#define state_size(x) (sizeof(x) + LUAI_EXTRASPACE) +#define fromstate(l) (cast(lu_byte *, (l)) - LUAI_EXTRASPACE) #define tostate(l) (cast(lua_State *, cast(lu_byte *, l) + LUAI_EXTRASPACE)) diff -r 4feced261c68 -r de822cd3df3a misc/liblua/lstate.h --- a/misc/liblua/lstate.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/lstate.h Tue Jan 21 22:43:06 2014 +0100 @@ -19,10 +19,10 @@ /* table of globals */ -#define gt(L) (&L->l_gt) +#define gt(L) (&L->l_gt) /* registry */ -#define registry(L) (&G(L)->l_registry) +#define registry(L) (&G(L)->l_registry) /* extra stack space to handle TM calls and some other extras */ @@ -48,7 +48,7 @@ typedef struct CallInfo { StkId base; /* base for this function */ StkId func; /* function index in the stack */ - StkId top; /* top for this function */ + StkId top; /* top for this function */ const Instruction *savedpc; int nresults; /* expected number of results from this function */ int tailcalls; /* number of tail calls lost under this entry */ @@ -56,10 +56,10 @@ -#define curr_func(L) (clvalue(L->ci->func)) -#define ci_func(ci) (clvalue((ci)->func)) -#define f_isLua(ci) (!ci_func(ci)->c.isC) -#define isLua(ci) (ttisfunction((ci)->func) && f_isLua(ci)) +#define curr_func(L) (clvalue(L->ci->func)) +#define ci_func(ci) (clvalue((ci)->func)) +#define f_isLua(ci) (!ci_func(ci)->c.isC) +#define isLua(ci) (ttisfunction((ci)->func) && f_isLua(ci)) /* @@ -127,7 +127,7 @@ }; -#define G(L) (L->l_G) +#define G(L) (L->l_G) /* @@ -146,20 +146,20 @@ /* macros to convert a GCObject into a specific value */ -#define rawgco2ts(o) check_exp((o)->gch.tt == LUA_TSTRING, &((o)->ts)) -#define gco2ts(o) (&rawgco2ts(o)->tsv) -#define rawgco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u)) -#define gco2u(o) (&rawgco2u(o)->uv) -#define gco2cl(o) check_exp((o)->gch.tt == LUA_TFUNCTION, &((o)->cl)) -#define gco2h(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h)) -#define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p)) -#define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv)) +#define rawgco2ts(o) check_exp((o)->gch.tt == LUA_TSTRING, &((o)->ts)) +#define gco2ts(o) (&rawgco2ts(o)->tsv) +#define rawgco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u)) +#define gco2u(o) (&rawgco2u(o)->uv) +#define gco2cl(o) check_exp((o)->gch.tt == LUA_TFUNCTION, &((o)->cl)) +#define gco2h(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h)) +#define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p)) +#define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv)) #define ngcotouv(o) \ - check_exp((o) == NULL || (o)->gch.tt == LUA_TUPVAL, &((o)->uv)) -#define gco2th(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th)) + check_exp((o) == NULL || (o)->gch.tt == LUA_TUPVAL, &((o)->uv)) +#define gco2th(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th)) /* macro to convert any Lua object into a GCObject */ -#define obj2gco(v) (cast(GCObject *, (v))) +#define obj2gco(v) (cast(GCObject *, (v))) LUAI_FUNC lua_State *luaE_newthread (lua_State *L); diff -r 4feced261c68 -r de822cd3df3a misc/liblua/lstring.h --- a/misc/liblua/lstring.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/lstring.h Tue Jan 21 22:43:06 2014 +0100 @@ -13,15 +13,15 @@ #include "lstate.h" -#define sizestring(s) (sizeof(union TString)+((s)->len+1)*sizeof(char)) +#define sizestring(s) (sizeof(union TString)+((s)->len+1)*sizeof(char)) -#define sizeudata(u) (sizeof(union Udata)+(u)->len) +#define sizeudata(u) (sizeof(union Udata)+(u)->len) -#define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s))) -#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ +#define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s))) +#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ (sizeof(s)/sizeof(char))-1)) -#define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT) +#define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT) LUAI_FUNC void luaS_resize (lua_State *L, int newsize); LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e); diff -r 4feced261c68 -r de822cd3df3a misc/liblua/lstrlib.c --- a/misc/liblua/lstrlib.c Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/lstrlib.c Tue Jan 21 22:43:06 2014 +0100 @@ -164,8 +164,8 @@ */ -#define CAP_UNFINISHED (-1) -#define CAP_POSITION (-2) +#define CAP_UNFINISHED (-1) +#define CAP_POSITION (-2) typedef struct MatchState { const char *src_init; /* init of source string */ @@ -179,8 +179,8 @@ } MatchState; -#define L_ESC '%' -#define SPECIALS "^$*+?.([%-" +#define L_ESC '%' +#define SPECIALS "^$*+?.([%-" static int check_capture (MatchState *ms, int l) { @@ -683,14 +683,14 @@ /* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */ -#define MAX_ITEM 512 +#define MAX_ITEM 512 /* valid flags in a format specification */ -#define FLAGS "-+ #0" +#define FLAGS "-+ #0" /* ** maximum size of each format specification (such as '%-099.99d') ** (+10 accounts for %99.99x plus margin of error) */ -#define MAX_FORMAT (sizeof(FLAGS) + sizeof(LUA_INTFRMLEN) + 10) +#define MAX_FORMAT (sizeof(FLAGS) + sizeof(LUA_INTFRMLEN) + 10) static void addquoted (lua_State *L, luaL_Buffer *b, int arg) { diff -r 4feced261c68 -r de822cd3df3a misc/liblua/ltable.c --- a/misc/liblua/ltable.c Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/ltable.c Tue Jan 21 22:43:06 2014 +0100 @@ -39,12 +39,12 @@ ** max size of array part is 2^MAXBITS */ #if LUAI_BITSINT > 26 -#define MAXBITS 26 +#define MAXBITS 26 #else -#define MAXBITS (LUAI_BITSINT-2) +#define MAXBITS (LUAI_BITSINT-2) #endif -#define MAXASIZE (1 << MAXBITS) +#define MAXASIZE (1 << MAXBITS) #define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t)))) @@ -57,20 +57,20 @@ ** for some types, it is better to avoid modulus by power of 2, as ** they tend to have many 2 factors. */ -#define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1)))) +#define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1)))) -#define hashpointer(t,p) hashmod(t, IntPoint(p)) +#define hashpointer(t,p) hashmod(t, IntPoint(p)) /* ** number of ints inside a lua_Number */ -#define numints cast_int(sizeof(lua_Number)/sizeof(int)) +#define numints cast_int(sizeof(lua_Number)/sizeof(int)) -#define dummynode (&dummynode_) +#define dummynode (&dummynode_) static const Node dummynode_ = { {{NULL}, LUA_TNIL}, /* value */ diff -r 4feced261c68 -r de822cd3df3a misc/liblua/ltable.h --- a/misc/liblua/ltable.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/ltable.h Tue Jan 21 22:43:06 2014 +0100 @@ -10,12 +10,12 @@ #include "lobject.h" -#define gnode(t,i) (&(t)->node[i]) -#define gkey(n) (&(n)->i_key.nk) -#define gval(n) (&(n)->i_val) -#define gnext(n) ((n)->i_key.nk.next) +#define gnode(t,i) (&(t)->node[i]) +#define gkey(n) (&(n)->i_key.nk) +#define gval(n) (&(n)->i_val) +#define gnext(n) ((n)->i_key.nk.next) -#define key2tval(n) (&(n)->i_key.tvk) +#define key2tval(n) (&(n)->i_key.tvk) LUAI_FUNC const TValue *luaH_getnum (Table *t, int key); diff -r 4feced261c68 -r de822cd3df3a misc/liblua/ltablib.c --- a/misc/liblua/ltablib.c Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/ltablib.c Tue Jan 21 22:43:06 2014 +0100 @@ -16,7 +16,7 @@ #include "lualib.h" -#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n)) +#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n)) static int foreachi (lua_State *L) { diff -r 4feced261c68 -r de822cd3df3a misc/liblua/ltm.h --- a/misc/liblua/ltm.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/ltm.h Tue Jan 21 22:43:06 2014 +0100 @@ -33,7 +33,7 @@ TM_LE, TM_CONCAT, TM_CALL, - TM_N /* number of elements in the enum */ + TM_N /* number of elements in the enum */ } TMS; @@ -41,7 +41,7 @@ #define gfasttm(g,et,e) ((et) == NULL ? NULL : \ ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e])) -#define fasttm(l,et,e) gfasttm(G(l), et, e) +#define fasttm(l,et,e) gfasttm(G(l), et, e) LUAI_DATA const char *const luaT_typenames[]; diff -r 4feced261c68 -r de822cd3df3a misc/liblua/lua.h --- a/misc/liblua/lua.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/lua.h Tue Jan 21 22:43:06 2014 +0100 @@ -16,35 +16,35 @@ #include "luaconf.h" -#define LUA_VERSION "Lua 5.1" -#define LUA_RELEASE "Lua 5.1.4" -#define LUA_VERSION_NUM 501 -#define LUA_COPYRIGHT "Copyright (C) 1994-2008 Lua.org, PUC-Rio" -#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes" +#define LUA_VERSION "Lua 5.1" +#define LUA_RELEASE "Lua 5.1.4" +#define LUA_VERSION_NUM 501 +#define LUA_COPYRIGHT "Copyright (C) 1994-2008 Lua.org, PUC-Rio" +#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes" /* mark for precompiled code (`Lua') */ -#define LUA_SIGNATURE "\033Lua" +#define LUA_SIGNATURE "\033Lua" /* option for multiple returns in `lua_pcall' and `lua_call' */ -#define LUA_MULTRET (-1) +#define LUA_MULTRET (-1) /* ** pseudo-indices */ -#define LUA_REGISTRYINDEX (-10000) -#define LUA_ENVIRONINDEX (-10001) -#define LUA_GLOBALSINDEX (-10002) -#define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i)) +#define LUA_REGISTRYINDEX (-10000) +#define LUA_ENVIRONINDEX (-10001) +#define LUA_GLOBALSINDEX (-10002) +#define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i)) /* thread status; 0 is OK */ -#define LUA_YIELD 1 -#define LUA_ERRRUN 2 -#define LUA_ERRSYNTAX 3 -#define LUA_ERRMEM 4 -#define LUA_ERRERR 5 +#define LUA_YIELD 1 +#define LUA_ERRRUN 2 +#define LUA_ERRSYNTAX 3 +#define LUA_ERRMEM 4 +#define LUA_ERRERR 5 typedef struct lua_State lua_State; @@ -69,22 +69,22 @@ /* ** basic types */ -#define LUA_TNONE (-1) +#define LUA_TNONE (-1) -#define LUA_TNIL 0 -#define LUA_TBOOLEAN 1 -#define LUA_TLIGHTUSERDATA 2 -#define LUA_TNUMBER 3 -#define LUA_TSTRING 4 -#define LUA_TTABLE 5 -#define LUA_TFUNCTION 6 -#define LUA_TUSERDATA 7 -#define LUA_TTHREAD 8 +#define LUA_TNIL 0 +#define LUA_TBOOLEAN 1 +#define LUA_TLIGHTUSERDATA 2 +#define LUA_TNUMBER 3 +#define LUA_TSTRING 4 +#define LUA_TTABLE 5 +#define LUA_TFUNCTION 6 +#define LUA_TUSERDATA 7 +#define LUA_TTHREAD 8 /* minimum Lua stack available to a C function */ -#define LUA_MINSTACK 20 +#define LUA_MINSTACK 20 /* @@ -149,7 +149,7 @@ LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len); LUA_API size_t (lua_objlen) (lua_State *L, int idx); LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx); -LUA_API void *(lua_touserdata) (lua_State *L, int idx); +LUA_API void *(lua_touserdata) (lua_State *L, int idx); LUA_API lua_State *(lua_tothread) (lua_State *L, int idx); LUA_API const void *(lua_topointer) (lua_State *L, int idx); @@ -218,14 +218,14 @@ ** garbage-collection function and options */ -#define LUA_GCSTOP 0 -#define LUA_GCRESTART 1 -#define LUA_GCCOLLECT 2 -#define LUA_GCCOUNT 3 -#define LUA_GCCOUNTB 4 -#define LUA_GCSTEP 5 -#define LUA_GCSETPAUSE 6 -#define LUA_GCSETSTEPMUL 7 +#define LUA_GCSTOP 0 +#define LUA_GCRESTART 1 +#define LUA_GCCOLLECT 2 +#define LUA_GCCOUNT 3 +#define LUA_GCCOUNTB 4 +#define LUA_GCSTEP 5 +#define LUA_GCSETPAUSE 6 +#define LUA_GCSETSTEPMUL 7 LUA_API int (lua_gc) (lua_State *L, int what, int data); @@ -251,32 +251,32 @@ ** =============================================================== */ -#define lua_pop(L,n) lua_settop(L, -(n)-1) +#define lua_pop(L,n) lua_settop(L, -(n)-1) -#define lua_newtable(L) lua_createtable(L, 0, 0) +#define lua_newtable(L) lua_createtable(L, 0, 0) #define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n))) -#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0) +#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0) -#define lua_strlen(L,i) lua_objlen(L, (i)) +#define lua_strlen(L,i) lua_objlen(L, (i)) -#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION) -#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE) -#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA) -#define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL) -#define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN) -#define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD) -#define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE) -#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0) +#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION) +#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE) +#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA) +#define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL) +#define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN) +#define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD) +#define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE) +#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0) -#define lua_pushliteral(L, s) \ - lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1) +#define lua_pushliteral(L, s) \ + lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1) -#define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, (s)) -#define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, (s)) +#define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, (s)) +#define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, (s)) -#define lua_tostring(L,i) lua_tolstring(L, (i), NULL) +#define lua_tostring(L,i) lua_tolstring(L, (i), NULL) @@ -284,18 +284,18 @@ ** compatibility macros and functions */ -#define lua_open() luaL_newstate() +#define lua_open() luaL_newstate() -#define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX) +#define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX) -#define lua_getgccount(L) lua_gc(L, LUA_GCCOUNT, 0) +#define lua_getgccount(L) lua_gc(L, LUA_GCCOUNT, 0) -#define lua_Chunkreader lua_Reader -#define lua_Chunkwriter lua_Writer +#define lua_Chunkreader lua_Reader +#define lua_Chunkwriter lua_Writer /* hack */ -LUA_API void lua_setlevel (lua_State *from, lua_State *to); +LUA_API void lua_setlevel (lua_State *from, lua_State *to); /* @@ -308,20 +308,20 @@ /* ** Event codes */ -#define LUA_HOOKCALL 0 -#define LUA_HOOKRET 1 -#define LUA_HOOKLINE 2 -#define LUA_HOOKCOUNT 3 +#define LUA_HOOKCALL 0 +#define LUA_HOOKRET 1 +#define LUA_HOOKLINE 2 +#define LUA_HOOKCOUNT 3 #define LUA_HOOKTAILRET 4 /* ** Event masks */ -#define LUA_MASKCALL (1 << LUA_HOOKCALL) -#define LUA_MASKRET (1 << LUA_HOOKRET) -#define LUA_MASKLINE (1 << LUA_HOOKLINE) -#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT) +#define LUA_MASKCALL (1 << LUA_HOOKCALL) +#define LUA_MASKRET (1 << LUA_HOOKRET) +#define LUA_MASKLINE (1 << LUA_HOOKLINE) +#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT) typedef struct lua_Debug lua_Debug; /* activation record */ @@ -345,14 +345,14 @@ struct lua_Debug { int event; - const char *name; /* (n) */ - const char *namewhat; /* (n) `global', `local', `field', `method' */ - const char *what; /* (S) `Lua', `C', `main', `tail' */ - const char *source; /* (S) */ - int currentline; /* (l) */ - int nups; /* (u) number of upvalues */ - int linedefined; /* (S) */ - int lastlinedefined; /* (S) */ + const char *name; /* (n) */ + const char *namewhat; /* (n) `global', `local', `field', `method' */ + const char *what; /* (S) `Lua', `C', `main', `tail' */ + const char *source; /* (S) */ + int currentline; /* (l) */ + int nups; /* (u) number of upvalues */ + int linedefined; /* (S) */ + int lastlinedefined; /* (S) */ char short_src[LUA_IDSIZE]; /* (S) */ /* private part */ int i_ci; /* active function */ diff -r 4feced261c68 -r de822cd3df3a misc/liblua/luaconf.h --- a/misc/liblua/luaconf.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/luaconf.h Tue Jan 21 22:43:06 2014 +0100 @@ -35,13 +35,13 @@ #if defined(LUA_USE_LINUX) #define LUA_USE_POSIX -#define LUA_USE_DLOPEN /* needs an extra library: -ldl */ -#define LUA_USE_READLINE /* needs some extra libraries */ +#define LUA_USE_DLOPEN /* needs an extra library: -ldl */ +#define LUA_USE_READLINE /* needs some extra libraries */ #endif #if defined(LUA_USE_MACOSX) #define LUA_USE_POSIX -#define LUA_DL_DYLD /* does not need extra library */ +#define LUA_DL_DYLD /* does not need extra library */ #endif @@ -68,7 +68,7 @@ */ #define LUA_PATH "LUA_PATH" #define LUA_CPATH "LUA_CPATH" -#define LUA_INIT "LUA_INIT" +#define LUA_INIT "LUA_INIT" /* @@ -85,23 +85,23 @@ ** In Windows, any exclamation mark ('!') in the path is replaced by the ** path of the directory of the executable file of the current process. */ -#define LUA_LDIR "!\\lua\\" -#define LUA_CDIR "!\\" +#define LUA_LDIR "!\\lua\\" +#define LUA_CDIR "!\\" #define LUA_PATH_DEFAULT \ - ".\\?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \ - LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua" + ".\\?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \ + LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua" #define LUA_CPATH_DEFAULT \ - ".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll" + ".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll" #else -#define LUA_ROOT "/usr/local/" -#define LUA_LDIR LUA_ROOT "share/lua/5.1/" -#define LUA_CDIR LUA_ROOT "lib/lua/5.1/" +#define LUA_ROOT "/usr/local/" +#define LUA_LDIR LUA_ROOT "share/lua/5.1/" +#define LUA_CDIR LUA_ROOT "lib/lua/5.1/" #define LUA_PATH_DEFAULT \ - "./?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \ - LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua" + "./?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \ + LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua" #define LUA_CPATH_DEFAULT \ - "./?.so;" LUA_CDIR"?.so;" LUA_CDIR"loadall.so" + "./?.so;" LUA_CDIR"?.so;" LUA_CDIR"loadall.so" #endif @@ -111,9 +111,9 @@ ** and is not Windows. (On Windows Lua automatically uses "\".) */ #if defined(_WIN32) -#define LUA_DIRSEP "\\" +#define LUA_DIRSEP "\\" #else -#define LUA_DIRSEP "/" +#define LUA_DIRSEP "/" #endif @@ -129,10 +129,10 @@ ** characters. (E.g., if one of those characters is a common character ** in file/directory names.) Probably you do not need to change them. */ -#define LUA_PATHSEP ";" -#define LUA_PATH_MARK "?" -#define LUA_EXECDIR "!" -#define LUA_IGMARK "-" +#define LUA_PATHSEP ";" +#define LUA_PATH_MARK "?" +#define LUA_EXECDIR "!" +#define LUA_IGMARK "-" /* @@ -140,7 +140,7 @@ ** CHANGE that if ptrdiff_t is not adequate on your machine. (On most ** machines, ptrdiff_t gives a good choice between int or long.) */ -#define LUA_INTEGER ptrdiff_t +#define LUA_INTEGER ptrdiff_t /* @@ -161,12 +161,12 @@ #else -#define LUA_API extern +#define LUA_API extern #endif /* more often than not the libs go together with the core */ -#define LUALIB_API LUA_API +#define LUALIB_API LUA_API /* @@ -179,17 +179,17 @@ ** when Lua is compiled as a shared library. */ #if defined(luaall_c) -#define LUAI_FUNC static -#define LUAI_DATA /* empty */ +#define LUAI_FUNC static +#define LUAI_DATA /* empty */ #elif defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \ defined(__ELF__) -#define LUAI_FUNC __attribute__((visibility("hidden"))) extern -#define LUAI_DATA LUAI_FUNC +#define LUAI_FUNC __attribute__((visibility("hidden"))) extern +#define LUAI_DATA LUAI_FUNC #else -#define LUAI_FUNC extern -#define LUAI_DATA extern +#define LUAI_FUNC extern +#define LUAI_DATA extern #endif @@ -198,8 +198,8 @@ @@ LUA_QL describes how error messages quote program elements. ** CHANGE it if you want a different appearance. */ -#define LUA_QL(x) "'" x "'" -#define LUA_QS LUA_QL("%s") +#define LUA_QL(x) "'" x "'" +#define LUA_QS LUA_QL("%s") /* @@ -207,7 +207,7 @@ @* of a function in debug information. ** CHANGE it if you want a different size. */ -#define LUA_IDSIZE 60 +#define LUA_IDSIZE 60 /* @@ -226,13 +226,13 @@ */ #if defined(LUA_USE_ISATTY) #include -#define lua_stdin_is_tty() isatty(0) +#define lua_stdin_is_tty() isatty(0) #elif defined(LUA_WIN) #include #include -#define lua_stdin_is_tty() _isatty(_fileno(stdin)) +#define lua_stdin_is_tty() _isatty(_fileno(stdin)) #else -#define lua_stdin_is_tty() 1 /* assume stdin is a tty */ +#define lua_stdin_is_tty() 1 /* assume stdin is a tty */ #endif @@ -242,8 +242,8 @@ ** CHANGE them if you want different prompts. (You can also change the ** prompts dynamically, assigning to globals _PROMPT/_PROMPT2.) */ -#define LUA_PROMPT "> " -#define LUA_PROMPT2 ">> " +#define LUA_PROMPT "> " +#define LUA_PROMPT2 ">> " /* @@ -251,7 +251,7 @@ ** CHANGE it if your stand-alone interpreter has a different name and ** your system is not able to detect that name automatically. */ -#define LUA_PROGNAME "lua" +#define LUA_PROGNAME "lua" /* @@ -259,7 +259,7 @@ @* stand-alone interpreter. ** CHANGE it if you need longer lines. */ -#define LUA_MAXINPUT 512 +#define LUA_MAXINPUT 512 /* @@ -274,17 +274,17 @@ #include #include #include -#define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL) +#define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL) #define lua_saveline(L,idx) \ - if (lua_strlen(L,idx) > 0) /* non-empty line? */ \ - add_history(lua_tostring(L, idx)); /* add it to history */ -#define lua_freeline(L,b) ((void)L, free(b)) + if (lua_strlen(L,idx) > 0) /* non-empty line? */ \ + add_history(lua_tostring(L, idx)); /* add it to history */ +#define lua_freeline(L,b) ((void)L, free(b)) #else -#define lua_readline(L,b,p) \ - ((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \ - fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */ -#define lua_saveline(L,idx) { (void)L; (void)idx; } -#define lua_freeline(L,b) { (void)L; (void)b; } +#define lua_readline(L,b,p) \ + ((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \ + fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */ +#define lua_saveline(L,idx) { (void)L; (void)idx; } +#define lua_freeline(L,b) { (void)L; (void)b; } #endif #endif @@ -299,7 +299,7 @@ ** mean larger pauses which mean slower collection.) You can also change ** this value dynamically. */ -#define LUAI_GCPAUSE 200 /* 200% (wait memory to double before next GC) */ +#define LUAI_GCPAUSE 200 /* 200% (wait memory to double before next GC) */ /* @@ -310,7 +310,7 @@ ** infinity, where each step performs a full collection.) You can also ** change this value dynamically. */ -#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */ +#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */ @@ -348,7 +348,7 @@ ** CHANGE it to 2 if you want the old behaviour, or undefine it to turn ** off the advisory error when nesting [[...]]. */ -#define LUA_COMPAT_LSTR 1 +#define LUA_COMPAT_LSTR 1 /* @@ LUA_COMPAT_GFIND controls compatibility with old 'string.gfind' name. @@ -376,9 +376,9 @@ */ #if defined(LUA_USE_APICHECK) #include -#define luai_apicheck(L,o) { (void)L; assert(o); } +#define luai_apicheck(L,o) { (void)L; assert(o); } #else -#define luai_apicheck(L,o) { (void)L; } +#define luai_apicheck(L,o) { (void)L; } #endif @@ -389,10 +389,10 @@ */ /* avoid overflows in comparison */ #if INT_MAX-20 < 32760 -#define LUAI_BITSINT 16 +#define LUAI_BITSINT 16 #elif INT_MAX > 2147483640L /* int has at least 32 bits */ -#define LUAI_BITSINT 32 +#define LUAI_BITSINT 32 #else #error "you must define LUA_BITSINT with number of bits in an integer" #endif @@ -411,18 +411,18 @@ ** longs.) Probably you do not need to change this. */ #if LUAI_BITSINT >= 32 -#define LUAI_UINT32 unsigned int -#define LUAI_INT32 int -#define LUAI_MAXINT32 INT_MAX -#define LUAI_UMEM size_t -#define LUAI_MEM ptrdiff_t +#define LUAI_UINT32 unsigned int +#define LUAI_INT32 int +#define LUAI_MAXINT32 INT_MAX +#define LUAI_UMEM size_t +#define LUAI_MEM ptrdiff_t #else /* 16-bit ints */ -#define LUAI_UINT32 unsigned long -#define LUAI_INT32 long -#define LUAI_MAXINT32 LONG_MAX -#define LUAI_UMEM unsigned long -#define LUAI_MEM long +#define LUAI_UINT32 unsigned long +#define LUAI_INT32 long +#define LUAI_MAXINT32 LONG_MAX +#define LUAI_UMEM unsigned long +#define LUAI_MEM long #endif @@ -432,7 +432,7 @@ ** arbitrary; its only purpose is to stop infinite recursion before ** exhausting memory. */ -#define LUAI_MAXCALLS 20000 +#define LUAI_MAXCALLS 20000 /* @@ -443,7 +443,7 @@ ** functions to consume unlimited stack space. (must be smaller than ** -LUA_REGISTRYINDEX) */ -#define LUAI_MAXCSTACK 8000 +#define LUAI_MAXCSTACK 8000 @@ -465,27 +465,27 @@ @@ LUAI_MAXCCALLS is the maximum depth for nested C calls (short) and @* syntactical nested non-terminals in a program. */ -#define LUAI_MAXCCALLS 200 +#define LUAI_MAXCCALLS 200 /* @@ LUAI_MAXVARS is the maximum number of local variables per function @* (must be smaller than 250). */ -#define LUAI_MAXVARS 200 +#define LUAI_MAXVARS 200 /* @@ LUAI_MAXUPVALUES is the maximum number of upvalues per function @* (must be smaller than 250). */ -#define LUAI_MAXUPVALUES 60 +#define LUAI_MAXUPVALUES 60 /* @@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system. */ -#define LUAL_BUFFERSIZE BUFSIZ +#define LUAL_BUFFERSIZE BUFSIZ /* }================================================================== */ @@ -502,13 +502,13 @@ */ #define LUA_NUMBER_DOUBLE -#define LUA_NUMBER double +#define LUA_NUMBER double /* @@ LUAI_UACNUMBER is the result of an 'usual argument conversion' @* over a number. */ -#define LUAI_UACNUMBER double +#define LUAI_UACNUMBER double /* @@ -518,11 +518,11 @@ @@ LUAI_MAXNUMBER2STR is maximum size of previous conversion. @@ lua_str2number converts a string to a number. */ -#define LUA_NUMBER_SCAN "%lf" -#define LUA_NUMBER_FMT "%.14g" -#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n)) -#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */ -#define lua_str2number(s,p) strtod((s), (p)) +#define LUA_NUMBER_SCAN "%lf" +#define LUA_NUMBER_FMT "%.14g" +#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n)) +#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */ +#define lua_str2number(s,p) strtod((s), (p)) /* @@ -530,17 +530,17 @@ */ #if defined(LUA_CORE) #include -#define luai_numadd(a,b) ((a)+(b)) -#define luai_numsub(a,b) ((a)-(b)) -#define luai_nummul(a,b) ((a)*(b)) -#define luai_numdiv(a,b) ((a)/(b)) -#define luai_nummod(a,b) ((a) - floor((a)/(b))*(b)) -#define luai_numpow(a,b) (pow(a,b)) -#define luai_numunm(a) (-(a)) -#define luai_numeq(a,b) ((a)==(b)) -#define luai_numlt(a,b) ((a)<(b)) -#define luai_numle(a,b) ((a)<=(b)) -#define luai_numisnan(a) (!luai_numeq((a), (a))) +#define luai_numadd(a,b) ((a)+(b)) +#define luai_numsub(a,b) ((a)-(b)) +#define luai_nummul(a,b) ((a)*(b)) +#define luai_numdiv(a,b) ((a)/(b)) +#define luai_nummod(a,b) ((a) - floor((a)/(b))*(b)) +#define luai_numpow(a,b) (pow(a,b)) +#define luai_numunm(a) (-(a)) +#define luai_numeq(a,b) ((a)==(b)) +#define luai_numlt(a,b) ((a)<(b)) +#define luai_numle(a,b) ((a)<=(b)) +#define luai_numisnan(a) (!luai_numeq((a), (a))) #endif @@ -561,7 +561,7 @@ #if defined(_MSC_VER) #define lua_number2int(i,d) __asm fld d __asm fistp i -#define lua_number2integer(i,n) lua_number2int(i, n) +#define lua_number2integer(i,n) lua_number2int(i, n) /* the next trick should work on any Pentium, but sometimes clashes with a DirectX idiosyncrasy */ @@ -570,15 +570,15 @@ union luai_Cast { double l_d; long l_l; }; #define lua_number2int(i,d) \ { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; } -#define lua_number2integer(i,n) lua_number2int(i, n) +#define lua_number2integer(i,n) lua_number2int(i, n) #endif /* this option always works, but may be slow */ #else -#define lua_number2int(i,d) ((i)=(int)(d)) -#define lua_number2integer(i,d) ((i)=(lua_Integer)(d)) +#define lua_number2int(i,d) ((i)=(int)(d)) +#define lua_number2integer(i,d) ((i)=(lua_Integer)(d)) #endif @@ -592,7 +592,7 @@ ** aligned in 16-byte boundaries, then you should add long double in the ** union.) Probably you do not need to change this. */ -#define LUAI_USER_ALIGNMENT_T union { double u; void *s; long l; } +#define LUAI_USER_ALIGNMENT_T union { double u; void *s; long l; } /* @@ -605,22 +605,22 @@ */ #if defined(__cplusplus) /* C++ exceptions */ -#define LUAI_THROW(L,c) throw(c) -#define LUAI_TRY(L,c,a) try { a } catch(...) \ - { if ((c)->status == 0) (c)->status = -1; } -#define luai_jmpbuf int /* dummy variable */ +#define LUAI_THROW(L,c) throw(c) +#define LUAI_TRY(L,c,a) try { a } catch(...) \ + { if ((c)->status == 0) (c)->status = -1; } +#define luai_jmpbuf int /* dummy variable */ #elif defined(LUA_USE_ULONGJMP) /* in Unix, try _longjmp/_setjmp (more efficient) */ -#define LUAI_THROW(L,c) _longjmp((c)->b, 1) -#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a } -#define luai_jmpbuf jmp_buf +#define LUAI_THROW(L,c) _longjmp((c)->b, 1) +#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a } +#define luai_jmpbuf jmp_buf #else /* default handling with long jumps */ -#define LUAI_THROW(L,c) longjmp((c)->b, 1) -#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a } -#define luai_jmpbuf jmp_buf +#define LUAI_THROW(L,c) longjmp((c)->b, 1) +#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a } +#define luai_jmpbuf jmp_buf #endif @@ -630,7 +630,7 @@ @* can do during pattern-matching. ** CHANGE it if you need more captures. This limit is arbitrary. */ -#define LUA_MAXCAPTURES 32 +#define LUA_MAXCAPTURES 32 /* @@ -645,16 +645,16 @@ #if defined(LUA_USE_MKSTEMP) #include -#define LUA_TMPNAMBUFSIZE 32 -#define lua_tmpnam(b,e) { \ - strcpy(b, "/tmp/lua_XXXXXX"); \ - e = mkstemp(b); \ - if (e != -1) close(e); \ - e = (e == -1); } +#define LUA_TMPNAMBUFSIZE 32 +#define lua_tmpnam(b,e) { \ + strcpy(b, "/tmp/lua_XXXXXX"); \ + e = mkstemp(b); \ + if (e != -1) close(e); \ + e = (e == -1); } #else -#define LUA_TMPNAMBUFSIZE L_tmpnam -#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); } +#define LUA_TMPNAMBUFSIZE L_tmpnam +#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); } #endif #endif @@ -667,19 +667,19 @@ */ #if defined(LUA_USE_POPEN) -#define lua_popen(L,c,m) ((void)L, fflush(NULL), popen(c,m)) -#define lua_pclose(L,file) ((void)L, (pclose(file) != -1)) +#define lua_popen(L,c,m) ((void)L, fflush(NULL), popen(c,m)) +#define lua_pclose(L,file) ((void)L, (pclose(file) != -1)) #elif defined(LUA_WIN) -#define lua_popen(L,c,m) ((void)L, _popen(c,m)) -#define lua_pclose(L,file) ((void)L, (_pclose(file) != -1)) +#define lua_popen(L,c,m) ((void)L, _popen(c,m)) +#define lua_pclose(L,file) ((void)L, (_pclose(file) != -1)) #else -#define lua_popen(L,c,m) ((void)((void)c, m), \ - luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0) -#define lua_pclose(L,file) ((void)((void)L, file), 0) +#define lua_popen(L,c,m) ((void)((void)c, m), \ + luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0) +#define lua_pclose(L,file) ((void)((void)L, file), 0) #endif @@ -712,7 +712,7 @@ ** CHANGE (define) this if you really need that. This value must be ** a multiple of the maximum alignment required for your machine. */ -#define LUAI_EXTRASPACE 0 +#define LUAI_EXTRASPACE 0 /* @@ -720,12 +720,12 @@ ** CHANGE them if you defined LUAI_EXTRASPACE and need to do something ** extra when a thread is created/deleted/resumed/yielded. */ -#define luai_userstateopen(L) ((void)L) -#define luai_userstateclose(L) ((void)L) -#define luai_userstatethread(L,L1) ((void)L) -#define luai_userstatefree(L) ((void)L) -#define luai_userstateresume(L,n) ((void)L) -#define luai_userstateyield(L,n) ((void)L) +#define luai_userstateopen(L) ((void)L) +#define luai_userstateclose(L) ((void)L) +#define luai_userstatethread(L,L1) ((void)L) +#define luai_userstatefree(L) ((void)L) +#define luai_userstateresume(L,n) ((void)L) +#define luai_userstateyield(L,n) ((void)L) /* @@ -738,13 +738,13 @@ #if defined(LUA_USELONGLONG) -#define LUA_INTFRMLEN "ll" -#define LUA_INTFRM_T long long +#define LUA_INTFRMLEN "ll" +#define LUA_INTFRM_T long long #else -#define LUA_INTFRMLEN "l" -#define LUA_INTFRM_T long +#define LUA_INTFRMLEN "l" +#define LUA_INTFRM_T long #endif diff -r 4feced261c68 -r de822cd3df3a misc/liblua/lualib.h --- a/misc/liblua/lualib.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/lualib.h Tue Jan 21 22:43:06 2014 +0100 @@ -12,31 +12,31 @@ /* Key to file-handle type */ -#define LUA_FILEHANDLE "FILE*" +#define LUA_FILEHANDLE "FILE*" -#define LUA_COLIBNAME "coroutine" +#define LUA_COLIBNAME "coroutine" LUALIB_API int (luaopen_base) (lua_State *L); -#define LUA_TABLIBNAME "table" +#define LUA_TABLIBNAME "table" LUALIB_API int (luaopen_table) (lua_State *L); -#define LUA_IOLIBNAME "io" +#define LUA_IOLIBNAME "io" LUALIB_API int (luaopen_io) (lua_State *L); -#define LUA_OSLIBNAME "os" +#define LUA_OSLIBNAME "os" LUALIB_API int (luaopen_os) (lua_State *L); -#define LUA_STRLIBNAME "string" +#define LUA_STRLIBNAME "string" LUALIB_API int (luaopen_string) (lua_State *L); -#define LUA_MATHLIBNAME "math" +#define LUA_MATHLIBNAME "math" LUALIB_API int (luaopen_math) (lua_State *L); -#define LUA_DBLIBNAME "debug" +#define LUA_DBLIBNAME "debug" LUALIB_API int (luaopen_debug) (lua_State *L); -#define LUA_LOADLIBNAME "package" +#define LUA_LOADLIBNAME "package" LUALIB_API int (luaopen_package) (lua_State *L); @@ -46,7 +46,7 @@ #ifndef lua_assert -#define lua_assert(x) ((void)0) +#define lua_assert(x) ((void)0) #endif diff -r 4feced261c68 -r de822cd3df3a misc/liblua/lundump.c --- a/misc/liblua/lundump.c Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/lundump.c Tue Jan 21 22:43:06 2014 +0100 @@ -31,7 +31,7 @@ #define IF(c,s) #define error(S,s) #else -#define IF(c,s) if (c) error(S,s) +#define IF(c,s) if (c) error(S,s) static void error(LoadState* S, const char* why) { @@ -40,10 +40,10 @@ } #endif -#define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size)) -#define LoadByte(S) (lu_byte)LoadChar(S) -#define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x)) -#define LoadVector(S,b,n,size) LoadMem(S,b,n,size) +#define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size)) +#define LoadByte(S) (lu_byte)LoadChar(S) +#define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x)) +#define LoadVector(S,b,n,size) LoadMem(S,b,n,size) static void LoadBlock(LoadState* S, void* b, size_t size) { @@ -83,7 +83,7 @@ { char* s=luaZ_openspace(S->L,S->b,size); LoadBlock(S,s,size); - return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */ + return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */ } } @@ -111,20 +111,20 @@ switch (t) { case LUA_TNIL: - setnilvalue(o); - break; + setnilvalue(o); + break; case LUA_TBOOLEAN: - setbvalue(o,LoadChar(S)!=0); - break; + setbvalue(o,LoadChar(S)!=0); + break; case LUA_TNUMBER: - setnvalue(o,LoadNumber(S)); - break; + setnvalue(o,LoadNumber(S)); + break; case LUA_TSTRING: - setsvalue2n(S->L,o,LoadString(S)); - break; + setsvalue2n(S->L,o,LoadString(S)); + break; default: - error(S,"bad constant"); - break; + error(S,"bad constant"); + break; } } n=LoadInt(S); @@ -218,10 +218,10 @@ h+=sizeof(LUA_SIGNATURE)-1; *h++=(char)LUAC_VERSION; *h++=(char)LUAC_FORMAT; - *h++=(char)*(char*)&x; /* endianness */ + *h++=(char)*(char*)&x; /* endianness */ *h++=(char)sizeof(int); *h++=(char)sizeof(size_t); *h++=(char)sizeof(Instruction); *h++=(char)sizeof(lua_Number); - *h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */ + *h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */ } diff -r 4feced261c68 -r de822cd3df3a misc/liblua/lundump.h --- a/misc/liblua/lundump.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/lundump.h Tue Jan 21 22:43:06 2014 +0100 @@ -25,12 +25,12 @@ #endif /* for header of binary files -- this is Lua 5.1 */ -#define LUAC_VERSION 0x51 +#define LUAC_VERSION 0x51 /* for header of binary files -- this is the official format */ -#define LUAC_FORMAT 0 +#define LUAC_FORMAT 0 /* size of header of binary files */ -#define LUAC_HEADERSIZE 12 +#define LUAC_HEADERSIZE 12 #endif diff -r 4feced261c68 -r de822cd3df3a misc/liblua/lvm.c --- a/misc/liblua/lvm.c Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/lvm.c Tue Jan 21 22:43:06 2014 +0100 @@ -29,7 +29,7 @@ /* limit for table tag-method chains (to avoid loops) */ -#define MAXTAGLOOP 100 +#define MAXTAGLOOP 100 const TValue *luaV_tonumber (const TValue *obj, TValue *n) { @@ -338,23 +338,23 @@ ** some macros for common tasks in `luaV_execute' */ -#define runtime_check(L, c) { if (!(c)) break; } +#define runtime_check(L, c) { if (!(c)) break; } -#define RA(i) (base+GETARG_A(i)) +#define RA(i) (base+GETARG_A(i)) /* to be used after possible stack reallocation */ -#define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i)) -#define RC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i)) -#define RKB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \ - ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i)) -#define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \ - ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i)) -#define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i)) +#define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i)) +#define RC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i)) +#define RKB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \ + ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i)) +#define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \ + ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i)) +#define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i)) -#define dojump(L,pc,i) {(pc) += (i); luai_threadyield(L);} +#define dojump(L,pc,i) {(pc) += (i); luai_threadyield(L);} -#define Protect(x) { L->savedpc = pc; {x;}; base = L->base; } +#define Protect(x) { L->savedpc = pc; {x;}; base = L->base; } #define arith_op(op,tm) { \ diff -r 4feced261c68 -r de822cd3df3a misc/liblua/lvm.h --- a/misc/liblua/lvm.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/lvm.h Tue Jan 21 22:43:06 2014 +0100 @@ -15,11 +15,11 @@ #define tostring(L,o) ((ttype(o) == LUA_TSTRING) || (luaV_tostring(L, o))) -#define tonumber(o,n) (ttype(o) == LUA_TNUMBER || \ +#define tonumber(o,n) (ttype(o) == LUA_TNUMBER || \ (((o) = luaV_tonumber(o,n)) != NULL)) #define equalobj(L,o1,o2) \ - (ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2)) + (ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2)) LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); diff -r 4feced261c68 -r de822cd3df3a misc/liblua/lzio.h --- a/misc/liblua/lzio.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/lzio.h Tue Jan 21 22:43:06 2014 +0100 @@ -13,11 +13,11 @@ #include "lmem.h" -#define EOZ (-1) /* end of stream */ +#define EOZ (-1) /* end of stream */ typedef struct Zio ZIO; -#define char2int(c) cast(int, cast(unsigned char, (c))) +#define char2int(c) cast(int, cast(unsigned char, (c))) #define zgetc(z) (((z)->n--)>0 ? char2int(*(z)->p++) : luaZ_fill(z)) @@ -29,24 +29,24 @@ #define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0) -#define luaZ_buffer(buff) ((buff)->buffer) -#define luaZ_sizebuffer(buff) ((buff)->buffsize) -#define luaZ_bufflen(buff) ((buff)->n) +#define luaZ_buffer(buff) ((buff)->buffer) +#define luaZ_sizebuffer(buff) ((buff)->buffsize) +#define luaZ_bufflen(buff) ((buff)->n) #define luaZ_resetbuffer(buff) ((buff)->n = 0) #define luaZ_resizebuffer(L, buff, size) \ - (luaM_reallocvector(L, (buff)->buffer, (buff)->buffsize, size, char), \ - (buff)->buffsize = size) + (luaM_reallocvector(L, (buff)->buffer, (buff)->buffsize, size, char), \ + (buff)->buffsize = size) -#define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) +#define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n); LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data); -LUAI_FUNC size_t luaZ_read (ZIO* z, void* b, size_t n); /* read next n bytes */ +LUAI_FUNC size_t luaZ_read (ZIO* z, void* b, size_t n); /* read next n bytes */ LUAI_FUNC int luaZ_lookahead (ZIO *z); @@ -54,11 +54,11 @@ /* --------- Private Part ------------------ */ struct Zio { - size_t n; /* bytes still unread */ - const char *p; /* current position in buffer */ + size_t n; /* bytes still unread */ + const char *p; /* current position in buffer */ lua_Reader reader; - void* data; /* additional data */ - lua_State *L; /* Lua state (for reader) */ + void* data; /* additional data */ + lua_State *L; /* Lua state (for reader) */ }; diff -r 4feced261c68 -r de822cd3df3a misc/liblua/print.c --- a/misc/liblua/print.c Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/liblua/print.c Tue Jan 21 22:43:06 2014 +0100 @@ -15,10 +15,10 @@ #include "lopcodes.h" #include "lundump.h" -#define PrintFunction luaU_print +#define PrintFunction luaU_print -#define Sizeof(x) ((int)sizeof(x)) -#define VOID(p) ((const void*)(p)) +#define Sizeof(x) ((int)sizeof(x)) +#define VOID(p) ((const void*)(p)) static void PrintString(const TString* ts) { @@ -39,10 +39,10 @@ case '\r': printf("\\r"); break; case '\t': printf("\\t"); break; case '\v': printf("\\v"); break; - default: if (isprint((unsigned char)c)) - putchar(c); - else - printf("\\%03u",(unsigned char)c); + default: if (isprint((unsigned char)c)) + putchar(c); + else + printf("\\%03u",(unsigned char)c); } } putchar('"'); @@ -54,20 +54,20 @@ switch (ttype(o)) { case LUA_TNIL: - printf("nil"); - break; + printf("nil"); + break; case LUA_TBOOLEAN: - printf(bvalue(o) ? "true" : "false"); - break; + printf(bvalue(o) ? "true" : "false"); + break; case LUA_TNUMBER: - printf(LUA_NUMBER_FMT,nvalue(o)); - break; + printf(LUA_NUMBER_FMT,nvalue(o)); + break; case LUA_TSTRING: - PrintString(rawtsvalue(o)); - break; - default: /* cannot happen */ - printf("? type=%d",ttype(o)); - break; + PrintString(rawtsvalue(o)); + break; + default: /* cannot happen */ + printf("? type=%d",ttype(o)); + break; } } @@ -155,8 +155,8 @@ } } -#define SS(x) (x==1)?"":"s" -#define S(x) x,SS(x) +#define SS(x) (x==1)?"":"s" +#define S(x) x,SS(x) static void PrintHeader(const Proto* f) { @@ -168,14 +168,14 @@ else s="(string)"; printf("\n%s <%s:%d,%d> (%d instruction%s, %d bytes at %p)\n", - (f->linedefined==0)?"main":"function",s, - f->linedefined,f->lastlinedefined, - S(f->sizecode),f->sizecode*Sizeof(Instruction),VOID(f)); + (f->linedefined==0)?"main":"function",s, + f->linedefined,f->lastlinedefined, + S(f->sizecode),f->sizecode*Sizeof(Instruction),VOID(f)); printf("%d%s param%s, %d slot%s, %d upvalue%s, ", - f->numparams,f->is_vararg?"+":"",SS(f->numparams), - S(f->maxstacksize),S(f->nups)); + f->numparams,f->is_vararg?"+":"",SS(f->numparams), + S(f->maxstacksize),S(f->nups)); printf("%d local%s, %d constant%s, %d function%s\n", - S(f->sizelocvars),S(f->sizek),S(f->sizep)); + S(f->sizelocvars),S(f->sizek),S(f->sizep)); } static void PrintConstants(const Proto* f) diff -r 4feced261c68 -r de822cd3df3a misc/libphysfs/archiver_unpacked.c --- a/misc/libphysfs/archiver_unpacked.c Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/libphysfs/archiver_unpacked.c Tue Jan 21 22:43:06 2014 +0100 @@ -200,7 +200,7 @@ rc = -1; else if (ch > '/') rc = 1; - else + else { if (stop_on_first_find) /* Just checking dir's existance? */ return middle; @@ -293,7 +293,7 @@ /* * This will find the UNPKentry associated with a path in platform-independent - * notation. Directories don't have UNPKentries associated with them, but + * notation. Directories don't have UNPKentries associated with them, but * (*isDir) will be set to non-zero if a dir was hit. */ static UNPKentry *findEntry(const UNPKinfo *info, const char *path, int *isDir) diff -r 4feced261c68 -r de822cd3df3a misc/libphysfs/archiver_wad.c --- a/misc/libphysfs/archiver_wad.c Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/libphysfs/archiver_wad.c Tue Jan 21 22:43:06 2014 +0100 @@ -1,7 +1,7 @@ /* * WAD support routines for PhysicsFS. * - * This driver handles DOOM engine archives ("wads"). + * This driver handles DOOM engine archives ("wads"). * This format (but not this driver) was designed by id Software for use * with the DOOM engine. * The specs of the format are from the unofficial doom specs v1.666 @@ -28,7 +28,7 @@ * (c) an 8-byte ASCII string, the name of the lump, padded with zeros. * For example, the "DEMO1" entry in hexadecimal would be * (44 45 4D 4F 31 00 00 00) - * + * * Note that there is no way to tell if an opened WAD archive is a * IWAD or PWAD with this archiver. * I couldn't think of a way to provide that information, without being too diff -r 4feced261c68 -r de822cd3df3a misc/libphysfs/archiver_zip.c --- a/misc/libphysfs/archiver_zip.c Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/libphysfs/archiver_zip.c Tue Jan 21 22:43:06 2014 +0100 @@ -488,7 +488,7 @@ (buf[i + 3] == 0x06) ) { found = 1; /* that's the signature! */ - break; + break; } /* if */ } /* for */ @@ -552,7 +552,7 @@ /* * This will find the ZIPentry associated with a path in platform-independent - * notation. Directories don't have ZIPentries associated with them, but + * notation. Directories don't have ZIPentries associated with them, but * (*isDir) will be set to non-zero if a dir was hit. */ static ZIPentry *zip_find_entry(const ZIPinfo *info, const char *path, @@ -724,7 +724,7 @@ path = (char *) __PHYSFS_smallAlloc(size + 1); BAIL_IF_MACRO(!path, PHYSFS_ERR_OUT_OF_MEMORY, 0); - + if (entry->compression_method == COMPMETH_NONE) rc = __PHYSFS_readAll(io, path, size); @@ -1445,7 +1445,7 @@ rc = -1; else if ('/' > ch) rc = 1; - else + else { if (stop_on_first_find) /* Just checking dir's existance? */ return middle; diff -r 4feced261c68 -r de822cd3df3a misc/libphysfs/physfs.c --- a/misc/libphysfs/physfs.c Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/libphysfs/physfs.c Tue Jan 21 22:43:06 2014 +0100 @@ -486,7 +486,7 @@ memcpy(retval, io, sizeof (PHYSFS_Io)); retval->opaque = newfh; return retval; - + handleIo_dupe_failed: if (newfh) { diff -r 4feced261c68 -r de822cd3df3a misc/libphysfs/physfs.h --- a/misc/libphysfs/physfs.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/libphysfs/physfs.h Tue Jan 21 22:43:06 2014 +0100 @@ -128,9 +128,9 @@ * * PhysicsFS is mostly thread safe. The error messages returned by * PHYSFS_getLastError() are unique by thread, and library-state-setting - * functions are mutex'd. For efficiency, individual file accesses are - * not locked, so you can not safely read/write/seek/close/etc the same - * file from two threads at the same time. Other race conditions are bugs + * functions are mutex'd. For efficiency, individual file accesses are + * not locked, so you can not safely read/write/seek/close/etc the same + * file from two threads at the same time. Other race conditions are bugs * that should be reported/patched. * * While you CAN use stdio/syscall file access in a program that has PHYSFS_* @@ -2604,10 +2604,10 @@ */ typedef enum PHYSFS_FileType { - PHYSFS_FILETYPE_REGULAR, /**< a normal file */ - PHYSFS_FILETYPE_DIRECTORY, /**< a directory */ - PHYSFS_FILETYPE_SYMLINK, /**< a symlink */ - PHYSFS_FILETYPE_OTHER /**< something completely different like a device */ + PHYSFS_FILETYPE_REGULAR, /**< a normal file */ + PHYSFS_FILETYPE_DIRECTORY, /**< a directory */ + PHYSFS_FILETYPE_SYMLINK, /**< a symlink */ + PHYSFS_FILETYPE_OTHER /**< something completely different like a device */ } PHYSFS_FileType; /** @@ -2628,12 +2628,12 @@ */ typedef struct PHYSFS_Stat { - PHYSFS_sint64 filesize; /**< size in bytes, -1 for non-files and unknown */ - PHYSFS_sint64 modtime; /**< last modification time */ - PHYSFS_sint64 createtime; /**< like modtime, but for file creation time */ - PHYSFS_sint64 accesstime; /**< like modtime, but for file access time */ - PHYSFS_FileType filetype; /**< File? Directory? Symlink? */ - int readonly; /**< non-zero if read only, zero if writable. */ + PHYSFS_sint64 filesize; /**< size in bytes, -1 for non-files and unknown */ + PHYSFS_sint64 modtime; /**< last modification time */ + PHYSFS_sint64 createtime; /**< like modtime, but for file creation time */ + PHYSFS_sint64 accesstime; /**< like modtime, but for file access time */ + PHYSFS_FileType filetype; /**< File? Directory? Symlink? */ + int readonly; /**< non-zero if read only, zero if writable. */ } PHYSFS_Stat; /** diff -r 4feced261c68 -r de822cd3df3a misc/libphysfs/physfs_internal.h --- a/misc/libphysfs/physfs_internal.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/libphysfs/physfs_internal.h Tue Jan 21 22:43:06 2014 +0100 @@ -726,12 +726,12 @@ /* * Grab possession of a platform-specific mutex. Mutexes should be recursive; * that is, the same thread should be able to call this function multiple - * times in a row without causing a deadlock. This function should block + * times in a row without causing a deadlock. This function should block * until a thread can gain possession of the mutex. * - * Return non-zero if the mutex was grabbed, zero if there was an - * unrecoverable problem grabbing it (this should not be a matter of - * timing out! We're talking major system errors; block until the mutex + * Return non-zero if the mutex was grabbed, zero if there was an + * unrecoverable problem grabbing it (this should not be a matter of + * timing out! We're talking major system errors; block until the mutex * is available otherwise.) * * _DO NOT_ call __PHYSFS_setError() in here! Since setError calls this @@ -741,7 +741,7 @@ int __PHYSFS_platformGrabMutex(void *mutex); /* - * Relinquish possession of the mutex when this method has been called + * Relinquish possession of the mutex when this method has been called * once for each time that platformGrabMutex was called. Once possession has * been released, the next thread in line to grab the mutex (if any) may * proceed. diff -r 4feced261c68 -r de822cd3df3a misc/libphysfs/physfs_miniz.h --- a/misc/libphysfs/physfs_miniz.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/libphysfs/physfs_miniz.h Tue Jan 21 22:43:06 2014 +0100 @@ -12,7 +12,7 @@ typedef PHYSFS_sint16 mz_int16; typedef PHYSFS_uint16 mz_uint16; typedef PHYSFS_uint32 mz_uint32; -typedef unsigned int mz_uint; +typedef unsigned int mz_uint; typedef PHYSFS_uint64 mz_uint64; /* For more compatibility with zlib, miniz.c uses unsigned long for some parameters/struct members. */ @@ -670,7 +670,7 @@ #endif /* #ifndef TINFL_HEADER_FILE_ONLY */ -/* +/* This is free and unencumbered software released into the public domain. Anyone is free to copy, modify, publish, use, compile, sell, or diff -r 4feced261c68 -r de822cd3df3a misc/libphysfs/platform_macosx.c --- a/misc/libphysfs/platform_macosx.c Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/libphysfs/platform_macosx.c Tue Jan 21 22:43:06 2014 +0100 @@ -38,7 +38,7 @@ doesn't work; once a symbol is marked as hidden, it stays that way. */ void __eprintf (const char *string, const char *expression, - unsigned int line, const char *filename) + unsigned int line, const char *filename) { fprintf(stderr, string, expression, line, filename); fflush(stderr); @@ -144,7 +144,7 @@ if (!IOObjectConformsTo(service, kIOMediaClass)) return 0; - + wholeMedia = IORegistryEntryCreateCFProperty(service, CFSTR(kIOMediaWholeKey), cfallocator, 0); @@ -180,7 +180,7 @@ rc = IORegistryEntryCreateIterator(service, kIOServicePlane, kIORegistryIterateRecursively | kIORegistryIterateParents, &iter); - + if (!iter) return 0; @@ -204,7 +204,7 @@ } /* if */ IOObjectRelease(service); } while ((service = IOIteratorNext(iter)) && (!retval)); - + IOObjectRelease(iter); IOObjectRelease(service); diff -r 4feced261c68 -r de822cd3df3a misc/libphysfs/platform_posix.c --- a/misc/libphysfs/platform_posix.c Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/libphysfs/platform_posix.c Tue Jan 21 22:43:06 2014 +0100 @@ -83,7 +83,7 @@ } /* if */ } /* if */ } /* if */ - + return retval; } /* getUserDirByUID */ diff -r 4feced261c68 -r de822cd3df3a misc/libphysfs/platform_windows.c --- a/misc/libphysfs/platform_windows.c Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/libphysfs/platform_windows.c Tue Jan 21 22:43:06 2014 +0100 @@ -171,7 +171,7 @@ stem(SEM_FAILCRITICALERRORS, &oldErrorMode); else oldErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS); - + /* Do detection. This may block if a disc is spinning up. */ for (i = 'A'; i <= 'Z'; i++) { @@ -443,7 +443,7 @@ * psize. Also note that the second parameter can't be * NULL or the function fails. */ - rc = pGetDir(accessToken, &dummy, &psize); + rc = pGetDir(accessToken, &dummy, &psize); assert(!rc); /* !!! FIXME: handle this gracefully. */ (void) rc; @@ -481,7 +481,7 @@ static int isSymlinkAttrs(const DWORD attr, const DWORD tag) { - return ( (attr & FILE_ATTRIBUTE_REPARSE_POINT) && + return ( (attr & FILE_ATTRIBUTE_REPARSE_POINT) && (tag == PHYSFS_IO_REPARSE_TAG_SYMLINK) ); } /* isSymlinkAttrs */ @@ -720,7 +720,7 @@ { BAIL_MACRO(errcodeFromWinApi(), 0); } /* if */ - + return 1; /* No error occured */ } /* __PHYSFS_platformSeek */ diff -r 4feced261c68 -r de822cd3df3a misc/libphyslayer/physfscompat.h --- a/misc/libphyslayer/physfscompat.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/libphyslayer/physfscompat.h Tue Jan 21 22:43:06 2014 +0100 @@ -34,20 +34,20 @@ typedef enum PHYSFS_FileType { - PHYSFS_FILETYPE_REGULAR, - PHYSFS_FILETYPE_DIRECTORY, - PHYSFS_FILETYPE_SYMLINK, - PHYSFS_FILETYPE_OTHER + PHYSFS_FILETYPE_REGULAR, + PHYSFS_FILETYPE_DIRECTORY, + PHYSFS_FILETYPE_SYMLINK, + PHYSFS_FILETYPE_OTHER } PHYSFS_FileType; typedef struct PHYSFS_Stat { - PHYSFS_sint64 filesize; - PHYSFS_sint64 modtime; - PHYSFS_sint64 createtime; - PHYSFS_sint64 accesstime; - PHYSFS_FileType filetype; - int readonly; + PHYSFS_sint64 filesize; + PHYSFS_sint64 modtime; + PHYSFS_sint64 createtime; + PHYSFS_sint64 accesstime; + PHYSFS_FileType filetype; + int readonly; } PHYSFS_Stat; PHYSFS_DECL int PHYSFS_stat(const char *fname, PHYSFS_Stat *stat); diff -r 4feced261c68 -r de822cd3df3a misc/libphyslayer/physfsrwops.c --- a/misc/libphyslayer/physfsrwops.c Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/libphyslayer/physfsrwops.c Tue Jan 21 22:43:06 2014 +0100 @@ -95,7 +95,7 @@ SDL_SetError("Attempt to seek past start of file."); return -1; } /* if */ - + if (!PHYSFS_seek(handle, (PHYSFS_uint64) pos)) { SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError()); diff -r 4feced261c68 -r de822cd3df3a misc/theme_editor.html --- a/misc/theme_editor.html Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/theme_editor.html Tue Jan 21 22:43:06 2014 +0100 @@ -7,113 +7,113 @@ var skyColor, waterTopColor, waterBottomColor; var elements = 7; var landArray; - + function landFunction(x){ return 384 - 192 * Math.sin(x * Math.PI/512); } - + function tryToDraw(){ if (--elements <= 0) { draw(); } } - + function load(){ var canvas = document.getElementById('preview'); if (canvas.getContext){ var ctx = canvas.getContext('2d'); - + ctx.fillStyle = '#0b294b'; ctx.fillRect(0, 0, 512, 384); - + ctx.font = "40pt Arial"; ctx.fillStyle = '#2b7bd5'; ctx.fillText('Loading Images...', 32, 212); } - + sky = new Image(); sky.onload = tryToDraw; sky.src = 'http://hedgewars.googlecode.com/hg/share/hedgewars/Data/Themes/Nature/Sky.png'; - + clouds = new Image(); clouds.onload = tryToDraw; clouds.src = 'http://hedgewars.googlecode.com/hg/share/hedgewars/Data/Graphics/Clouds.png'; - + horizont = new Image(); horizont.onload = tryToDraw; horizont.src = 'http://hedgewars.googlecode.com/hg/share/hedgewars/Data/Themes/Nature/horizont.png'; - + land = new Image(); land.onload = tryToDraw; land.src = 'http://hedgewars.googlecode.com/hg/share/hedgewars/Data/Themes/Nature/LandTex.png'; - + border = new Image(); border.onload = tryToDraw; border.src = 'http://hedgewars.googlecode.com/hg/share/hedgewars/Data/Themes/Nature/Border.png'; - + water = new Image(); water.onload = tryToDraw; water.src = 'http://hedgewars.googlecode.com/hg/share/hedgewars/Data/Graphics/BlueWater.png'; - + landArray = new Array(512); for (var x = 0; x < landArray.length; x++) landArray[x] = landFunction(x); - + skyColor = '#131252'; document.getElementById('skyColor').value = skyColor; - + waterTopColor = '#555C9D'; document.getElementById('waterTopColor').value = waterTopColor; - + waterBottomColor = '#343C7D'; document.getElementById('waterBottomColor').value = waterBottomColor; - + tryToDraw(); } - + function draw(){ var canvas = document.getElementById('preview'); if (canvas.getContext){ var ctx = canvas.getContext('2d'); - + ctx.fillStyle = skyColor; ctx.fillRect(0, 0, 512, 384); - + ctx.drawImage(sky, 0, 64, 512, 256); - + for (var i = 0; i < 4; i++) ctx.drawImage(clouds, 0, i * 128, 256, 128, i * 128, 64, 128, 64); - + ctx.drawImage(horizont, 0, 192, 512, 128); - + ctx.save(); - + ctx.beginPath(); ctx.moveTo(0, 384); for (var x = 0; x < landArray.length; x++) ctx.lineTo(x, landArray[x]); ctx.clip(); - + for (var i = 0; i < 2; i++) - for (var k = 0; k < 2; k++) - ctx.drawImage(land, i * 320, k * 240, 320, 240); - + for (var k = 0; k < 2; k++) + ctx.drawImage(land, i * 320, k * 240, 320, 240); + ctx.restore(); - + var k = 0; for (var x = 0; x < landArray.length; x++) { if (++k == 64) k = 0; ctx.drawImage(border, k, 0, 2, 16, x, landArray[x] - 4, 1, 8); } - - + + var gradient = ctx.createLinearGradient(0, 320, 0, 384); gradient.addColorStop(0, waterTopColor); gradient.addColorStop(1, waterBottomColor); ctx.fillStyle = gradient; ctx.fillRect(0, 320, 512, 384); - + for (var i = 0; i < 8; i++) ctx.drawImage(water, i * 64, 308, 64, 24); } diff -r 4feced261c68 -r de822cd3df3a misc/winutils/include/GL/glut.h --- a/misc/winutils/include/GL/glut.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/winutils/include/GL/glut.h Tue Jan 21 22:43:06 2014 +0100 @@ -1,716 +1,716 @@ -#ifndef __glut_h__ -#define __glut_h__ - -/* Copyright (c) Mark J. Kilgard, 1994, 1995, 1996, 1998. */ - -/* This program is freely distributable without licensing fees and is - provided without guarantee or warrantee expressed or implied. This - program is -not- in the public domain. */ - -#if defined(_WIN32) - -/* GLUT 3.7 now tries to avoid including - to avoid name space pollution, but Win32's - needs APIENTRY and WINGDIAPI defined properly. */ -# if 0 - /* This would put tons of macros and crap in our clean name space. */ -# define WIN32_LEAN_AND_MEAN -# include -# else - /* XXX This is from Win32's */ -# ifndef APIENTRY -# define GLUT_APIENTRY_DEFINED -# if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) || defined(__BORLANDC__) || defined(__LCC__) -# define APIENTRY __stdcall -# else -# define APIENTRY -# endif -# endif - /* XXX This is from Win32's */ -# ifndef CALLBACK -# if (defined(_M_MRX000) || defined(_M_IX86) || defined(_M_ALPHA) || defined(_M_PPC)) && !defined(MIDL_PASS) || defined(__LCC__) -# define CALLBACK __stdcall -# else -# define CALLBACK -# endif -# endif - /* XXX Hack for lcc compiler. It doesn't support __declspec(dllimport), just __stdcall. */ -# if defined( __LCC__ ) -# undef WINGDIAPI -# define WINGDIAPI __stdcall -# else - /* XXX This is from Win32's and */ -# ifndef WINGDIAPI -# define GLUT_WINGDIAPI_DEFINED -# define WINGDIAPI __declspec(dllimport) -# endif -# endif - /* XXX This is from Win32's */ -# ifndef _WCHAR_T_DEFINED -typedef unsigned short wchar_t; -# define _WCHAR_T_DEFINED -# endif -# endif - -/* To disable automatic library usage for GLUT, define GLUT_NO_LIB_PRAGMA - in your compile preprocessor options. */ -# if !defined(GLUT_BUILDING_LIB) && !defined(GLUT_NO_LIB_PRAGMA) -# pragma comment (lib, "winmm.lib") /* link with Windows MultiMedia lib */ -/* To enable automatic SGI OpenGL for Windows library usage for GLUT, - define GLUT_USE_SGI_OPENGL in your compile preprocessor options. */ -# ifdef GLUT_USE_SGI_OPENGL -# pragma comment (lib, "opengl.lib") /* link with SGI OpenGL for Windows lib */ -# pragma comment (lib, "glu.lib") /* link with SGI OpenGL Utility lib */ -# pragma comment (lib, "glut.lib") /* link with Win32 GLUT for SGI OpenGL lib */ -# else -# pragma comment (lib, "opengl32.lib") /* link with Microsoft OpenGL lib */ -# pragma comment (lib, "glu32.lib") /* link with Microsoft OpenGL Utility lib */ -# pragma comment (lib, "glut32.lib") /* link with Win32 GLUT lib */ -# endif -# endif - -/* To disable supression of annoying warnings about floats being promoted - to doubles, define GLUT_NO_WARNING_DISABLE in your compile preprocessor - options. */ -# ifndef GLUT_NO_WARNING_DISABLE -# pragma warning (disable:4244) /* Disable bogus VC++ 4.2 conversion warnings. */ -# pragma warning (disable:4305) /* VC++ 5.0 version of above warning. */ -# endif - -/* Win32 has an annoying issue where there are multiple C run-time - libraries (CRTs). If the executable is linked with a different CRT - from the GLUT DLL, the GLUT DLL will not share the same CRT static - data seen by the executable. In particular, atexit callbacks registered - in the executable will not be called if GLUT calls its (different) - exit routine). GLUT is typically built with the - "/MD" option (the CRT with multithreading DLL support), but the Visual - C++ linker default is "/ML" (the single threaded CRT). - - One workaround to this issue is requiring users to always link with - the same CRT as GLUT is compiled with. That requires users supply a - non-standard option. GLUT 3.7 has its own built-in workaround where - the executable's "exit" function pointer is covertly passed to GLUT. - GLUT then calls the executable's exit function pointer to ensure that - any "atexit" calls registered by the application are called if GLUT - needs to exit. - - Note that the __glut*WithExit routines should NEVER be called directly. - To avoid the atexit workaround, #define GLUT_DISABLE_ATEXIT_HACK. */ - -/* XXX This is from Win32's */ -# if !defined(_MSC_VER) && !defined(__cdecl) - /* Define __cdecl for non-Microsoft compilers. */ -# define __cdecl -# define GLUT_DEFINED___CDECL -# endif -# ifndef _CRTIMP -# ifdef _NTSDK - /* Definition compatible with NT SDK */ -# define _CRTIMP -# else - /* Current definition */ -# ifdef _DLL -# define _CRTIMP __declspec(dllimport) -# else -# define _CRTIMP -# endif -# endif -# define GLUT_DEFINED__CRTIMP -# endif - -/* GLUT API entry point declarations for Win32. */ -# ifdef GLUT_BUILDING_LIB -# define GLUTAPI __declspec(dllexport) -# else -# ifdef _DLL -# define GLUTAPI __declspec(dllimport) -# else -# define GLUTAPI extern -# endif -# endif - -/* GLUT callback calling convention for Win32. */ -# define GLUTCALLBACK __cdecl - -#endif /* _WIN32 */ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(_WIN32) -# ifndef GLUT_BUILDING_LIB -extern _CRTIMP void __cdecl exit(int); -# endif -#else -/* non-Win32 case. */ -/* Define APIENTRY and CALLBACK to nothing if we aren't on Win32. */ -# define APIENTRY -# define GLUT_APIENTRY_DEFINED -# define CALLBACK -/* Define GLUTAPI and GLUTCALLBACK as below if we aren't on Win32. */ -# define GLUTAPI extern -# define GLUTCALLBACK -/* Prototype exit for the non-Win32 case (see above). */ -extern void exit(int); -#endif - -/** - GLUT API revision history: - - GLUT_API_VERSION is updated to reflect incompatible GLUT - API changes (interface changes, semantic changes, deletions, - or additions). - - GLUT_API_VERSION=1 First public release of GLUT. 11/29/94 - - GLUT_API_VERSION=2 Added support for OpenGL/GLX multisampling, - extension. Supports new input devices like tablet, dial and button - box, and Spaceball. Easy to query OpenGL extensions. - - GLUT_API_VERSION=3 glutMenuStatus added. - - GLUT_API_VERSION=4 glutInitDisplayString, glutWarpPointer, - glutBitmapLength, glutStrokeLength, glutWindowStatusFunc, dynamic - video resize subAPI, glutPostWindowRedisplay, glutKeyboardUpFunc, - glutSpecialUpFunc, glutIgnoreKeyRepeat, glutSetKeyRepeat, - glutJoystickFunc, glutForceJoystickFunc (NOT FINALIZED!). -**/ -#ifndef GLUT_API_VERSION /* allow this to be overriden */ -#define GLUT_API_VERSION 3 -#endif - -/** - GLUT implementation revision history: - - GLUT_XLIB_IMPLEMENTATION is updated to reflect both GLUT - API revisions and implementation revisions (ie, bug fixes). - - GLUT_XLIB_IMPLEMENTATION=1 mjk's first public release of - GLUT Xlib-based implementation. 11/29/94 - - GLUT_XLIB_IMPLEMENTATION=2 mjk's second public release of - GLUT Xlib-based implementation providing GLUT version 2 - interfaces. - - GLUT_XLIB_IMPLEMENTATION=3 mjk's GLUT 2.2 images. 4/17/95 - - GLUT_XLIB_IMPLEMENTATION=4 mjk's GLUT 2.3 images. 6/?/95 - - GLUT_XLIB_IMPLEMENTATION=5 mjk's GLUT 3.0 images. 10/?/95 - - GLUT_XLIB_IMPLEMENTATION=7 mjk's GLUT 3.1+ with glutWarpPoitner. 7/24/96 - - GLUT_XLIB_IMPLEMENTATION=8 mjk's GLUT 3.1+ with glutWarpPoitner - and video resize. 1/3/97 - - GLUT_XLIB_IMPLEMENTATION=9 mjk's GLUT 3.4 release with early GLUT 4 routines. - - GLUT_XLIB_IMPLEMENTATION=11 Mesa 2.5's GLUT 3.6 release. - - GLUT_XLIB_IMPLEMENTATION=12 mjk's GLUT 3.6 release with early GLUT 4 routines + signal handling. - - GLUT_XLIB_IMPLEMENTATION=13 mjk's GLUT 3.7 beta with GameGLUT support. - - GLUT_XLIB_IMPLEMENTATION=14 mjk's GLUT 3.7 beta with f90gl friend interface. - - GLUT_XLIB_IMPLEMENTATION=15 mjk's GLUT 3.7 beta sync'ed with Mesa -**/ -#ifndef GLUT_XLIB_IMPLEMENTATION /* Allow this to be overriden. */ -#define GLUT_XLIB_IMPLEMENTATION 15 -#endif - -/* Display mode bit masks. */ -#define GLUT_RGB 0 -#define GLUT_RGBA GLUT_RGB -#define GLUT_INDEX 1 -#define GLUT_SINGLE 0 -#define GLUT_DOUBLE 2 -#define GLUT_ACCUM 4 -#define GLUT_ALPHA 8 -#define GLUT_DEPTH 16 -#define GLUT_STENCIL 32 -#if (GLUT_API_VERSION >= 2) -#define GLUT_MULTISAMPLE 128 -#define GLUT_STEREO 256 -#endif -#if (GLUT_API_VERSION >= 3) -#define GLUT_LUMINANCE 512 -#endif - -/* Mouse buttons. */ -#define GLUT_LEFT_BUTTON 0 -#define GLUT_MIDDLE_BUTTON 1 -#define GLUT_RIGHT_BUTTON 2 - -/* Mouse button state. */ -#define GLUT_DOWN 0 -#define GLUT_UP 1 - -#if (GLUT_API_VERSION >= 2) -/* function keys */ -#define GLUT_KEY_F1 1 -#define GLUT_KEY_F2 2 -#define GLUT_KEY_F3 3 -#define GLUT_KEY_F4 4 -#define GLUT_KEY_F5 5 -#define GLUT_KEY_F6 6 -#define GLUT_KEY_F7 7 -#define GLUT_KEY_F8 8 -#define GLUT_KEY_F9 9 -#define GLUT_KEY_F10 10 -#define GLUT_KEY_F11 11 -#define GLUT_KEY_F12 12 -/* directional keys */ -#define GLUT_KEY_LEFT 100 -#define GLUT_KEY_UP 101 -#define GLUT_KEY_RIGHT 102 -#define GLUT_KEY_DOWN 103 -#define GLUT_KEY_PAGE_UP 104 -#define GLUT_KEY_PAGE_DOWN 105 -#define GLUT_KEY_HOME 106 -#define GLUT_KEY_END 107 -#define GLUT_KEY_INSERT 108 -#endif - -/* Entry/exit state. */ -#define GLUT_LEFT 0 -#define GLUT_ENTERED 1 - -/* Menu usage state. */ -#define GLUT_MENU_NOT_IN_USE 0 -#define GLUT_MENU_IN_USE 1 - -/* Visibility state. */ -#define GLUT_NOT_VISIBLE 0 -#define GLUT_VISIBLE 1 - -/* Window status state. */ -#define GLUT_HIDDEN 0 -#define GLUT_FULLY_RETAINED 1 -#define GLUT_PARTIALLY_RETAINED 2 -#define GLUT_FULLY_COVERED 3 - -/* Color index component selection values. */ -#define GLUT_RED 0 -#define GLUT_GREEN 1 -#define GLUT_BLUE 2 - -#if defined(_WIN32) -/* Stroke font constants (use these in GLUT program). */ -#define GLUT_STROKE_ROMAN ((void*)0) -#define GLUT_STROKE_MONO_ROMAN ((void*)1) - -/* Bitmap font constants (use these in GLUT program). */ -#define GLUT_BITMAP_9_BY_15 ((void*)2) -#define GLUT_BITMAP_8_BY_13 ((void*)3) -#define GLUT_BITMAP_TIMES_ROMAN_10 ((void*)4) -#define GLUT_BITMAP_TIMES_ROMAN_24 ((void*)5) -#if (GLUT_API_VERSION >= 3) -#define GLUT_BITMAP_HELVETICA_10 ((void*)6) -#define GLUT_BITMAP_HELVETICA_12 ((void*)7) -#define GLUT_BITMAP_HELVETICA_18 ((void*)8) -#endif -#else -/* Stroke font opaque addresses (use constants instead in source code). */ -GLUTAPI void *glutStrokeRoman; -GLUTAPI void *glutStrokeMonoRoman; - -/* Stroke font constants (use these in GLUT program). */ -#define GLUT_STROKE_ROMAN (&glutStrokeRoman) -#define GLUT_STROKE_MONO_ROMAN (&glutStrokeMonoRoman) - -/* Bitmap font opaque addresses (use constants instead in source code). */ -GLUTAPI void *glutBitmap9By15; -GLUTAPI void *glutBitmap8By13; -GLUTAPI void *glutBitmapTimesRoman10; -GLUTAPI void *glutBitmapTimesRoman24; -GLUTAPI void *glutBitmapHelvetica10; -GLUTAPI void *glutBitmapHelvetica12; -GLUTAPI void *glutBitmapHelvetica18; - -/* Bitmap font constants (use these in GLUT program). */ -#define GLUT_BITMAP_9_BY_15 (&glutBitmap9By15) -#define GLUT_BITMAP_8_BY_13 (&glutBitmap8By13) -#define GLUT_BITMAP_TIMES_ROMAN_10 (&glutBitmapTimesRoman10) -#define GLUT_BITMAP_TIMES_ROMAN_24 (&glutBitmapTimesRoman24) -#if (GLUT_API_VERSION >= 3) -#define GLUT_BITMAP_HELVETICA_10 (&glutBitmapHelvetica10) -#define GLUT_BITMAP_HELVETICA_12 (&glutBitmapHelvetica12) -#define GLUT_BITMAP_HELVETICA_18 (&glutBitmapHelvetica18) -#endif -#endif - -/* glutGet parameters. */ -#define GLUT_WINDOW_X ((GLenum) 100) -#define GLUT_WINDOW_Y ((GLenum) 101) -#define GLUT_WINDOW_WIDTH ((GLenum) 102) -#define GLUT_WINDOW_HEIGHT ((GLenum) 103) -#define GLUT_WINDOW_BUFFER_SIZE ((GLenum) 104) -#define GLUT_WINDOW_STENCIL_SIZE ((GLenum) 105) -#define GLUT_WINDOW_DEPTH_SIZE ((GLenum) 106) -#define GLUT_WINDOW_RED_SIZE ((GLenum) 107) -#define GLUT_WINDOW_GREEN_SIZE ((GLenum) 108) -#define GLUT_WINDOW_BLUE_SIZE ((GLenum) 109) -#define GLUT_WINDOW_ALPHA_SIZE ((GLenum) 110) -#define GLUT_WINDOW_ACCUM_RED_SIZE ((GLenum) 111) -#define GLUT_WINDOW_ACCUM_GREEN_SIZE ((GLenum) 112) -#define GLUT_WINDOW_ACCUM_BLUE_SIZE ((GLenum) 113) -#define GLUT_WINDOW_ACCUM_ALPHA_SIZE ((GLenum) 114) -#define GLUT_WINDOW_DOUBLEBUFFER ((GLenum) 115) -#define GLUT_WINDOW_RGBA ((GLenum) 116) -#define GLUT_WINDOW_PARENT ((GLenum) 117) -#define GLUT_WINDOW_NUM_CHILDREN ((GLenum) 118) -#define GLUT_WINDOW_COLORMAP_SIZE ((GLenum) 119) -#if (GLUT_API_VERSION >= 2) -#define GLUT_WINDOW_NUM_SAMPLES ((GLenum) 120) -#define GLUT_WINDOW_STEREO ((GLenum) 121) -#endif -#if (GLUT_API_VERSION >= 3) -#define GLUT_WINDOW_CURSOR ((GLenum) 122) -#endif -#define GLUT_SCREEN_WIDTH ((GLenum) 200) -#define GLUT_SCREEN_HEIGHT ((GLenum) 201) -#define GLUT_SCREEN_WIDTH_MM ((GLenum) 202) -#define GLUT_SCREEN_HEIGHT_MM ((GLenum) 203) -#define GLUT_MENU_NUM_ITEMS ((GLenum) 300) -#define GLUT_DISPLAY_MODE_POSSIBLE ((GLenum) 400) -#define GLUT_INIT_WINDOW_X ((GLenum) 500) -#define GLUT_INIT_WINDOW_Y ((GLenum) 501) -#define GLUT_INIT_WINDOW_WIDTH ((GLenum) 502) -#define GLUT_INIT_WINDOW_HEIGHT ((GLenum) 503) -#define GLUT_INIT_DISPLAY_MODE ((GLenum) 504) -#if (GLUT_API_VERSION >= 2) -#define GLUT_ELAPSED_TIME ((GLenum) 700) -#endif -#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) -#define GLUT_WINDOW_FORMAT_ID ((GLenum) 123) -#endif - -#if (GLUT_API_VERSION >= 2) -/* glutDeviceGet parameters. */ -#define GLUT_HAS_KEYBOARD ((GLenum) 600) -#define GLUT_HAS_MOUSE ((GLenum) 601) -#define GLUT_HAS_SPACEBALL ((GLenum) 602) -#define GLUT_HAS_DIAL_AND_BUTTON_BOX ((GLenum) 603) -#define GLUT_HAS_TABLET ((GLenum) 604) -#define GLUT_NUM_MOUSE_BUTTONS ((GLenum) 605) -#define GLUT_NUM_SPACEBALL_BUTTONS ((GLenum) 606) -#define GLUT_NUM_BUTTON_BOX_BUTTONS ((GLenum) 607) -#define GLUT_NUM_DIALS ((GLenum) 608) -#define GLUT_NUM_TABLET_BUTTONS ((GLenum) 609) -#endif -#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) -#define GLUT_DEVICE_IGNORE_KEY_REPEAT ((GLenum) 610) -#define GLUT_DEVICE_KEY_REPEAT ((GLenum) 611) -#define GLUT_HAS_JOYSTICK ((GLenum) 612) -#define GLUT_OWNS_JOYSTICK ((GLenum) 613) -#define GLUT_JOYSTICK_BUTTONS ((GLenum) 614) -#define GLUT_JOYSTICK_AXES ((GLenum) 615) -#define GLUT_JOYSTICK_POLL_RATE ((GLenum) 616) -#endif - -#if (GLUT_API_VERSION >= 3) -/* glutLayerGet parameters. */ -#define GLUT_OVERLAY_POSSIBLE ((GLenum) 800) -#define GLUT_LAYER_IN_USE ((GLenum) 801) -#define GLUT_HAS_OVERLAY ((GLenum) 802) -#define GLUT_TRANSPARENT_INDEX ((GLenum) 803) -#define GLUT_NORMAL_DAMAGED ((GLenum) 804) -#define GLUT_OVERLAY_DAMAGED ((GLenum) 805) - -#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) -/* glutVideoResizeGet parameters. */ -#define GLUT_VIDEO_RESIZE_POSSIBLE ((GLenum) 900) -#define GLUT_VIDEO_RESIZE_IN_USE ((GLenum) 901) -#define GLUT_VIDEO_RESIZE_X_DELTA ((GLenum) 902) -#define GLUT_VIDEO_RESIZE_Y_DELTA ((GLenum) 903) -#define GLUT_VIDEO_RESIZE_WIDTH_DELTA ((GLenum) 904) -#define GLUT_VIDEO_RESIZE_HEIGHT_DELTA ((GLenum) 905) -#define GLUT_VIDEO_RESIZE_X ((GLenum) 906) -#define GLUT_VIDEO_RESIZE_Y ((GLenum) 907) -#define GLUT_VIDEO_RESIZE_WIDTH ((GLenum) 908) -#define GLUT_VIDEO_RESIZE_HEIGHT ((GLenum) 909) -#endif - -/* glutUseLayer parameters. */ -#define GLUT_NORMAL ((GLenum) 0) -#define GLUT_OVERLAY ((GLenum) 1) - -/* glutGetModifiers return mask. */ -#define GLUT_ACTIVE_SHIFT 1 -#define GLUT_ACTIVE_CTRL 2 -#define GLUT_ACTIVE_ALT 4 - -/* glutSetCursor parameters. */ -/* Basic arrows. */ -#define GLUT_CURSOR_RIGHT_ARROW 0 -#define GLUT_CURSOR_LEFT_ARROW 1 -/* Symbolic cursor shapes. */ -#define GLUT_CURSOR_INFO 2 -#define GLUT_CURSOR_DESTROY 3 -#define GLUT_CURSOR_HELP 4 -#define GLUT_CURSOR_CYCLE 5 -#define GLUT_CURSOR_SPRAY 6 -#define GLUT_CURSOR_WAIT 7 -#define GLUT_CURSOR_TEXT 8 -#define GLUT_CURSOR_CROSSHAIR 9 -/* Directional cursors. */ -#define GLUT_CURSOR_UP_DOWN 10 -#define GLUT_CURSOR_LEFT_RIGHT 11 -/* Sizing cursors. */ -#define GLUT_CURSOR_TOP_SIDE 12 -#define GLUT_CURSOR_BOTTOM_SIDE 13 -#define GLUT_CURSOR_LEFT_SIDE 14 -#define GLUT_CURSOR_RIGHT_SIDE 15 -#define GLUT_CURSOR_TOP_LEFT_CORNER 16 -#define GLUT_CURSOR_TOP_RIGHT_CORNER 17 -#define GLUT_CURSOR_BOTTOM_RIGHT_CORNER 18 -#define GLUT_CURSOR_BOTTOM_LEFT_CORNER 19 -/* Inherit from parent window. */ -#define GLUT_CURSOR_INHERIT 100 -/* Blank cursor. */ -#define GLUT_CURSOR_NONE 101 -/* Fullscreen crosshair (if available). */ -#define GLUT_CURSOR_FULL_CROSSHAIR 102 -#endif - -/* GLUT initialization sub-API. */ -GLUTAPI void APIENTRY glutInit(int *argcp, char **argv); -#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK) -GLUTAPI void APIENTRY __glutInitWithExit(int *argcp, char **argv, void (__cdecl *exitfunc)(int)); -#ifndef GLUT_BUILDING_LIB -static void APIENTRY glutInit_ATEXIT_HACK(int *argcp, char **argv) { __glutInitWithExit(argcp, argv, exit); } -#define glutInit glutInit_ATEXIT_HACK -#endif -#endif -GLUTAPI void APIENTRY glutInitDisplayMode(unsigned int mode); -#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) -GLUTAPI void APIENTRY glutInitDisplayString(const char *string); -#endif -GLUTAPI void APIENTRY glutInitWindowPosition(int x, int y); -GLUTAPI void APIENTRY glutInitWindowSize(int width, int height); -GLUTAPI void APIENTRY glutMainLoop(void); - -/* GLUT window sub-API. */ -GLUTAPI int APIENTRY glutCreateWindow(const char *title); -#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK) -GLUTAPI int APIENTRY __glutCreateWindowWithExit(const char *title, void (__cdecl *exitfunc)(int)); -#ifndef GLUT_BUILDING_LIB -static int APIENTRY glutCreateWindow_ATEXIT_HACK(const char *title) { return __glutCreateWindowWithExit(title, exit); } -#define glutCreateWindow glutCreateWindow_ATEXIT_HACK -#endif -#endif -GLUTAPI int APIENTRY glutCreateSubWindow(int win, int x, int y, int width, int height); -GLUTAPI void APIENTRY glutDestroyWindow(int win); -GLUTAPI void APIENTRY glutPostRedisplay(void); -#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 11) -GLUTAPI void APIENTRY glutPostWindowRedisplay(int win); -#endif -GLUTAPI void APIENTRY glutSwapBuffers(void); -GLUTAPI int APIENTRY glutGetWindow(void); -GLUTAPI void APIENTRY glutSetWindow(int win); -GLUTAPI void APIENTRY glutSetWindowTitle(const char *title); -GLUTAPI void APIENTRY glutSetIconTitle(const char *title); -GLUTAPI void APIENTRY glutPositionWindow(int x, int y); -GLUTAPI void APIENTRY glutReshapeWindow(int width, int height); -GLUTAPI void APIENTRY glutPopWindow(void); -GLUTAPI void APIENTRY glutPushWindow(void); -GLUTAPI void APIENTRY glutIconifyWindow(void); -GLUTAPI void APIENTRY glutShowWindow(void); -GLUTAPI void APIENTRY glutHideWindow(void); -#if (GLUT_API_VERSION >= 3) -GLUTAPI void APIENTRY glutFullScreen(void); -GLUTAPI void APIENTRY glutSetCursor(int cursor); -#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) -GLUTAPI void APIENTRY glutWarpPointer(int x, int y); -#endif - -/* GLUT overlay sub-API. */ -GLUTAPI void APIENTRY glutEstablishOverlay(void); -GLUTAPI void APIENTRY glutRemoveOverlay(void); -GLUTAPI void APIENTRY glutUseLayer(GLenum layer); -GLUTAPI void APIENTRY glutPostOverlayRedisplay(void); -#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 11) -GLUTAPI void APIENTRY glutPostWindowOverlayRedisplay(int win); -#endif -GLUTAPI void APIENTRY glutShowOverlay(void); -GLUTAPI void APIENTRY glutHideOverlay(void); -#endif - -/* GLUT menu sub-API. */ -GLUTAPI int APIENTRY glutCreateMenu(void (GLUTCALLBACK *func)(int)); -#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK) -GLUTAPI int APIENTRY __glutCreateMenuWithExit(void (GLUTCALLBACK *func)(int), void (__cdecl *exitfunc)(int)); -#ifndef GLUT_BUILDING_LIB -static int APIENTRY glutCreateMenu_ATEXIT_HACK(void (GLUTCALLBACK *func)(int)) { return __glutCreateMenuWithExit(func, exit); } -#define glutCreateMenu glutCreateMenu_ATEXIT_HACK -#endif -#endif -GLUTAPI void APIENTRY glutDestroyMenu(int menu); -GLUTAPI int APIENTRY glutGetMenu(void); -GLUTAPI void APIENTRY glutSetMenu(int menu); -GLUTAPI void APIENTRY glutAddMenuEntry(const char *label, int value); -GLUTAPI void APIENTRY glutAddSubMenu(const char *label, int submenu); -GLUTAPI void APIENTRY glutChangeToMenuEntry(int item, const char *label, int value); -GLUTAPI void APIENTRY glutChangeToSubMenu(int item, const char *label, int submenu); -GLUTAPI void APIENTRY glutRemoveMenuItem(int item); -GLUTAPI void APIENTRY glutAttachMenu(int button); -GLUTAPI void APIENTRY glutDetachMenu(int button); - -/* GLUT window callback sub-API. */ -GLUTAPI void APIENTRY glutDisplayFunc(void (GLUTCALLBACK *func)(void)); -GLUTAPI void APIENTRY glutReshapeFunc(void (GLUTCALLBACK *func)(int width, int height)); -GLUTAPI void APIENTRY glutKeyboardFunc(void (GLUTCALLBACK *func)(unsigned char key, int x, int y)); -GLUTAPI void APIENTRY glutMouseFunc(void (GLUTCALLBACK *func)(int button, int state, int x, int y)); -GLUTAPI void APIENTRY glutMotionFunc(void (GLUTCALLBACK *func)(int x, int y)); -GLUTAPI void APIENTRY glutPassiveMotionFunc(void (GLUTCALLBACK *func)(int x, int y)); -GLUTAPI void APIENTRY glutEntryFunc(void (GLUTCALLBACK *func)(int state)); -GLUTAPI void APIENTRY glutVisibilityFunc(void (GLUTCALLBACK *func)(int state)); -GLUTAPI void APIENTRY glutIdleFunc(void (GLUTCALLBACK *func)(void)); -GLUTAPI void APIENTRY glutTimerFunc(unsigned int millis, void (GLUTCALLBACK *func)(int value), int value); -GLUTAPI void APIENTRY glutMenuStateFunc(void (GLUTCALLBACK *func)(int state)); -#if (GLUT_API_VERSION >= 2) -GLUTAPI void APIENTRY glutSpecialFunc(void (GLUTCALLBACK *func)(int key, int x, int y)); -GLUTAPI void APIENTRY glutSpaceballMotionFunc(void (GLUTCALLBACK *func)(int x, int y, int z)); -GLUTAPI void APIENTRY glutSpaceballRotateFunc(void (GLUTCALLBACK *func)(int x, int y, int z)); -GLUTAPI void APIENTRY glutSpaceballButtonFunc(void (GLUTCALLBACK *func)(int button, int state)); -GLUTAPI void APIENTRY glutButtonBoxFunc(void (GLUTCALLBACK *func)(int button, int state)); -GLUTAPI void APIENTRY glutDialsFunc(void (GLUTCALLBACK *func)(int dial, int value)); -GLUTAPI void APIENTRY glutTabletMotionFunc(void (GLUTCALLBACK *func)(int x, int y)); -GLUTAPI void APIENTRY glutTabletButtonFunc(void (GLUTCALLBACK *func)(int button, int state, int x, int y)); -#if (GLUT_API_VERSION >= 3) -GLUTAPI void APIENTRY glutMenuStatusFunc(void (GLUTCALLBACK *func)(int status, int x, int y)); -GLUTAPI void APIENTRY glutOverlayDisplayFunc(void (GLUTCALLBACK *func)(void)); -#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) -GLUTAPI void APIENTRY glutWindowStatusFunc(void (GLUTCALLBACK *func)(int state)); -#endif -#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) -GLUTAPI void APIENTRY glutKeyboardUpFunc(void (GLUTCALLBACK *func)(unsigned char key, int x, int y)); -GLUTAPI void APIENTRY glutSpecialUpFunc(void (GLUTCALLBACK *func)(int key, int x, int y)); -GLUTAPI void APIENTRY glutJoystickFunc(void (GLUTCALLBACK *func)(unsigned int buttonMask, int x, int y, int z), int pollInterval); -#endif -#endif -#endif - -/* GLUT color index sub-API. */ -GLUTAPI void APIENTRY glutSetColor(int, GLfloat red, GLfloat green, GLfloat blue); -GLUTAPI GLfloat APIENTRY glutGetColor(int ndx, int component); -GLUTAPI void APIENTRY glutCopyColormap(int win); - -/* GLUT state retrieval sub-API. */ -GLUTAPI int APIENTRY glutGet(GLenum type); -GLUTAPI int APIENTRY glutDeviceGet(GLenum type); -#if (GLUT_API_VERSION >= 2) -/* GLUT extension support sub-API */ -GLUTAPI int APIENTRY glutExtensionSupported(const char *name); -#endif -#if (GLUT_API_VERSION >= 3) -GLUTAPI int APIENTRY glutGetModifiers(void); -GLUTAPI int APIENTRY glutLayerGet(GLenum type); -#endif - -/* GLUT font sub-API */ -GLUTAPI void APIENTRY glutBitmapCharacter(void *font, int character); -GLUTAPI int APIENTRY glutBitmapWidth(void *font, int character); -GLUTAPI void APIENTRY glutStrokeCharacter(void *font, int character); -GLUTAPI int APIENTRY glutStrokeWidth(void *font, int character); -#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) -GLUTAPI int APIENTRY glutBitmapLength(void *font, const unsigned char *string); -GLUTAPI int APIENTRY glutStrokeLength(void *font, const unsigned char *string); -#endif - -/* GLUT pre-built models sub-API */ -GLUTAPI void APIENTRY glutWireSphere(GLdouble radius, GLint slices, GLint stacks); -GLUTAPI void APIENTRY glutSolidSphere(GLdouble radius, GLint slices, GLint stacks); -GLUTAPI void APIENTRY glutWireCone(GLdouble base, GLdouble height, GLint slices, GLint stacks); -GLUTAPI void APIENTRY glutSolidCone(GLdouble base, GLdouble height, GLint slices, GLint stacks); -GLUTAPI void APIENTRY glutWireCube(GLdouble size); -GLUTAPI void APIENTRY glutSolidCube(GLdouble size); -GLUTAPI void APIENTRY glutWireTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings); -GLUTAPI void APIENTRY glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings); -GLUTAPI void APIENTRY glutWireDodecahedron(void); -GLUTAPI void APIENTRY glutSolidDodecahedron(void); -GLUTAPI void APIENTRY glutWireTeapot(GLdouble size); -GLUTAPI void APIENTRY glutSolidTeapot(GLdouble size); -GLUTAPI void APIENTRY glutWireOctahedron(void); -GLUTAPI void APIENTRY glutSolidOctahedron(void); -GLUTAPI void APIENTRY glutWireTetrahedron(void); -GLUTAPI void APIENTRY glutSolidTetrahedron(void); -GLUTAPI void APIENTRY glutWireIcosahedron(void); -GLUTAPI void APIENTRY glutSolidIcosahedron(void); - -#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) -/* GLUT video resize sub-API. */ -GLUTAPI int APIENTRY glutVideoResizeGet(GLenum param); -GLUTAPI void APIENTRY glutSetupVideoResizing(void); -GLUTAPI void APIENTRY glutStopVideoResizing(void); -GLUTAPI void APIENTRY glutVideoResize(int x, int y, int width, int height); -GLUTAPI void APIENTRY glutVideoPan(int x, int y, int width, int height); - -/* GLUT debugging sub-API. */ -GLUTAPI void APIENTRY glutReportErrors(void); -#endif - -#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) -/* GLUT device control sub-API. */ -/* glutSetKeyRepeat modes. */ -#define GLUT_KEY_REPEAT_OFF 0 -#define GLUT_KEY_REPEAT_ON 1 -#define GLUT_KEY_REPEAT_DEFAULT 2 - -/* Joystick button masks. */ -#define GLUT_JOYSTICK_BUTTON_A 1 -#define GLUT_JOYSTICK_BUTTON_B 2 -#define GLUT_JOYSTICK_BUTTON_C 4 -#define GLUT_JOYSTICK_BUTTON_D 8 - -GLUTAPI void APIENTRY glutIgnoreKeyRepeat(int ignore); -GLUTAPI void APIENTRY glutSetKeyRepeat(int repeatMode); -GLUTAPI void APIENTRY glutForceJoystickFunc(void); - -/* GLUT game mode sub-API. */ -/* glutGameModeGet. */ -#define GLUT_GAME_MODE_ACTIVE ((GLenum) 0) -#define GLUT_GAME_MODE_POSSIBLE ((GLenum) 1) -#define GLUT_GAME_MODE_WIDTH ((GLenum) 2) -#define GLUT_GAME_MODE_HEIGHT ((GLenum) 3) -#define GLUT_GAME_MODE_PIXEL_DEPTH ((GLenum) 4) -#define GLUT_GAME_MODE_REFRESH_RATE ((GLenum) 5) -#define GLUT_GAME_MODE_DISPLAY_CHANGED ((GLenum) 6) - -GLUTAPI void APIENTRY glutGameModeString(const char *string); -GLUTAPI int APIENTRY glutEnterGameMode(void); -GLUTAPI void APIENTRY glutLeaveGameMode(void); -GLUTAPI int APIENTRY glutGameModeGet(GLenum mode); -#endif - -#ifdef __cplusplus -} - -#endif - -#ifdef GLUT_APIENTRY_DEFINED -# undef GLUT_APIENTRY_DEFINED -# undef APIENTRY -#endif - -#ifdef GLUT_WINGDIAPI_DEFINED -# undef GLUT_WINGDIAPI_DEFINED -# undef WINGDIAPI -#endif - -#ifdef GLUT_DEFINED___CDECL -# undef GLUT_DEFINED___CDECL -# undef __cdecl -#endif - -#ifdef GLUT_DEFINED__CRTIMP -# undef GLUT_DEFINED__CRTIMP -# undef _CRTIMP -#endif - -#endif /* __glut_h__ */ +#ifndef __glut_h__ +#define __glut_h__ + +/* Copyright (c) Mark J. Kilgard, 1994, 1995, 1996, 1998. */ + +/* This program is freely distributable without licensing fees and is + provided without guarantee or warrantee expressed or implied. This + program is -not- in the public domain. */ + +#if defined(_WIN32) + +/* GLUT 3.7 now tries to avoid including + to avoid name space pollution, but Win32's + needs APIENTRY and WINGDIAPI defined properly. */ +# if 0 + /* This would put tons of macros and crap in our clean name space. */ +# define WIN32_LEAN_AND_MEAN +# include +# else + /* XXX This is from Win32's */ +# ifndef APIENTRY +# define GLUT_APIENTRY_DEFINED +# if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) || defined(__BORLANDC__) || defined(__LCC__) +# define APIENTRY __stdcall +# else +# define APIENTRY +# endif +# endif + /* XXX This is from Win32's */ +# ifndef CALLBACK +# if (defined(_M_MRX000) || defined(_M_IX86) || defined(_M_ALPHA) || defined(_M_PPC)) && !defined(MIDL_PASS) || defined(__LCC__) +# define CALLBACK __stdcall +# else +# define CALLBACK +# endif +# endif + /* XXX Hack for lcc compiler. It doesn't support __declspec(dllimport), just __stdcall. */ +# if defined( __LCC__ ) +# undef WINGDIAPI +# define WINGDIAPI __stdcall +# else + /* XXX This is from Win32's and */ +# ifndef WINGDIAPI +# define GLUT_WINGDIAPI_DEFINED +# define WINGDIAPI __declspec(dllimport) +# endif +# endif + /* XXX This is from Win32's */ +# ifndef _WCHAR_T_DEFINED +typedef unsigned short wchar_t; +# define _WCHAR_T_DEFINED +# endif +# endif + +/* To disable automatic library usage for GLUT, define GLUT_NO_LIB_PRAGMA + in your compile preprocessor options. */ +# if !defined(GLUT_BUILDING_LIB) && !defined(GLUT_NO_LIB_PRAGMA) +# pragma comment (lib, "winmm.lib") /* link with Windows MultiMedia lib */ +/* To enable automatic SGI OpenGL for Windows library usage for GLUT, + define GLUT_USE_SGI_OPENGL in your compile preprocessor options. */ +# ifdef GLUT_USE_SGI_OPENGL +# pragma comment (lib, "opengl.lib") /* link with SGI OpenGL for Windows lib */ +# pragma comment (lib, "glu.lib") /* link with SGI OpenGL Utility lib */ +# pragma comment (lib, "glut.lib") /* link with Win32 GLUT for SGI OpenGL lib */ +# else +# pragma comment (lib, "opengl32.lib") /* link with Microsoft OpenGL lib */ +# pragma comment (lib, "glu32.lib") /* link with Microsoft OpenGL Utility lib */ +# pragma comment (lib, "glut32.lib") /* link with Win32 GLUT lib */ +# endif +# endif + +/* To disable supression of annoying warnings about floats being promoted + to doubles, define GLUT_NO_WARNING_DISABLE in your compile preprocessor + options. */ +# ifndef GLUT_NO_WARNING_DISABLE +# pragma warning (disable:4244) /* Disable bogus VC++ 4.2 conversion warnings. */ +# pragma warning (disable:4305) /* VC++ 5.0 version of above warning. */ +# endif + +/* Win32 has an annoying issue where there are multiple C run-time + libraries (CRTs). If the executable is linked with a different CRT + from the GLUT DLL, the GLUT DLL will not share the same CRT static + data seen by the executable. In particular, atexit callbacks registered + in the executable will not be called if GLUT calls its (different) + exit routine). GLUT is typically built with the + "/MD" option (the CRT with multithreading DLL support), but the Visual + C++ linker default is "/ML" (the single threaded CRT). + + One workaround to this issue is requiring users to always link with + the same CRT as GLUT is compiled with. That requires users supply a + non-standard option. GLUT 3.7 has its own built-in workaround where + the executable's "exit" function pointer is covertly passed to GLUT. + GLUT then calls the executable's exit function pointer to ensure that + any "atexit" calls registered by the application are called if GLUT + needs to exit. + + Note that the __glut*WithExit routines should NEVER be called directly. + To avoid the atexit workaround, #define GLUT_DISABLE_ATEXIT_HACK. */ + +/* XXX This is from Win32's */ +# if !defined(_MSC_VER) && !defined(__cdecl) + /* Define __cdecl for non-Microsoft compilers. */ +# define __cdecl +# define GLUT_DEFINED___CDECL +# endif +# ifndef _CRTIMP +# ifdef _NTSDK + /* Definition compatible with NT SDK */ +# define _CRTIMP +# else + /* Current definition */ +# ifdef _DLL +# define _CRTIMP __declspec(dllimport) +# else +# define _CRTIMP +# endif +# endif +# define GLUT_DEFINED__CRTIMP +# endif + +/* GLUT API entry point declarations for Win32. */ +# ifdef GLUT_BUILDING_LIB +# define GLUTAPI __declspec(dllexport) +# else +# ifdef _DLL +# define GLUTAPI __declspec(dllimport) +# else +# define GLUTAPI extern +# endif +# endif + +/* GLUT callback calling convention for Win32. */ +# define GLUTCALLBACK __cdecl + +#endif /* _WIN32 */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(_WIN32) +# ifndef GLUT_BUILDING_LIB +extern _CRTIMP void __cdecl exit(int); +# endif +#else +/* non-Win32 case. */ +/* Define APIENTRY and CALLBACK to nothing if we aren't on Win32. */ +# define APIENTRY +# define GLUT_APIENTRY_DEFINED +# define CALLBACK +/* Define GLUTAPI and GLUTCALLBACK as below if we aren't on Win32. */ +# define GLUTAPI extern +# define GLUTCALLBACK +/* Prototype exit for the non-Win32 case (see above). */ +extern void exit(int); +#endif + +/** + GLUT API revision history: + + GLUT_API_VERSION is updated to reflect incompatible GLUT + API changes (interface changes, semantic changes, deletions, + or additions). + + GLUT_API_VERSION=1 First public release of GLUT. 11/29/94 + + GLUT_API_VERSION=2 Added support for OpenGL/GLX multisampling, + extension. Supports new input devices like tablet, dial and button + box, and Spaceball. Easy to query OpenGL extensions. + + GLUT_API_VERSION=3 glutMenuStatus added. + + GLUT_API_VERSION=4 glutInitDisplayString, glutWarpPointer, + glutBitmapLength, glutStrokeLength, glutWindowStatusFunc, dynamic + video resize subAPI, glutPostWindowRedisplay, glutKeyboardUpFunc, + glutSpecialUpFunc, glutIgnoreKeyRepeat, glutSetKeyRepeat, + glutJoystickFunc, glutForceJoystickFunc (NOT FINALIZED!). +**/ +#ifndef GLUT_API_VERSION /* allow this to be overriden */ +#define GLUT_API_VERSION 3 +#endif + +/** + GLUT implementation revision history: + + GLUT_XLIB_IMPLEMENTATION is updated to reflect both GLUT + API revisions and implementation revisions (ie, bug fixes). + + GLUT_XLIB_IMPLEMENTATION=1 mjk's first public release of + GLUT Xlib-based implementation. 11/29/94 + + GLUT_XLIB_IMPLEMENTATION=2 mjk's second public release of + GLUT Xlib-based implementation providing GLUT version 2 + interfaces. + + GLUT_XLIB_IMPLEMENTATION=3 mjk's GLUT 2.2 images. 4/17/95 + + GLUT_XLIB_IMPLEMENTATION=4 mjk's GLUT 2.3 images. 6/?/95 + + GLUT_XLIB_IMPLEMENTATION=5 mjk's GLUT 3.0 images. 10/?/95 + + GLUT_XLIB_IMPLEMENTATION=7 mjk's GLUT 3.1+ with glutWarpPoitner. 7/24/96 + + GLUT_XLIB_IMPLEMENTATION=8 mjk's GLUT 3.1+ with glutWarpPoitner + and video resize. 1/3/97 + + GLUT_XLIB_IMPLEMENTATION=9 mjk's GLUT 3.4 release with early GLUT 4 routines. + + GLUT_XLIB_IMPLEMENTATION=11 Mesa 2.5's GLUT 3.6 release. + + GLUT_XLIB_IMPLEMENTATION=12 mjk's GLUT 3.6 release with early GLUT 4 routines + signal handling. + + GLUT_XLIB_IMPLEMENTATION=13 mjk's GLUT 3.7 beta with GameGLUT support. + + GLUT_XLIB_IMPLEMENTATION=14 mjk's GLUT 3.7 beta with f90gl friend interface. + + GLUT_XLIB_IMPLEMENTATION=15 mjk's GLUT 3.7 beta sync'ed with Mesa +**/ +#ifndef GLUT_XLIB_IMPLEMENTATION /* Allow this to be overriden. */ +#define GLUT_XLIB_IMPLEMENTATION 15 +#endif + +/* Display mode bit masks. */ +#define GLUT_RGB 0 +#define GLUT_RGBA GLUT_RGB +#define GLUT_INDEX 1 +#define GLUT_SINGLE 0 +#define GLUT_DOUBLE 2 +#define GLUT_ACCUM 4 +#define GLUT_ALPHA 8 +#define GLUT_DEPTH 16 +#define GLUT_STENCIL 32 +#if (GLUT_API_VERSION >= 2) +#define GLUT_MULTISAMPLE 128 +#define GLUT_STEREO 256 +#endif +#if (GLUT_API_VERSION >= 3) +#define GLUT_LUMINANCE 512 +#endif + +/* Mouse buttons. */ +#define GLUT_LEFT_BUTTON 0 +#define GLUT_MIDDLE_BUTTON 1 +#define GLUT_RIGHT_BUTTON 2 + +/* Mouse button state. */ +#define GLUT_DOWN 0 +#define GLUT_UP 1 + +#if (GLUT_API_VERSION >= 2) +/* function keys */ +#define GLUT_KEY_F1 1 +#define GLUT_KEY_F2 2 +#define GLUT_KEY_F3 3 +#define GLUT_KEY_F4 4 +#define GLUT_KEY_F5 5 +#define GLUT_KEY_F6 6 +#define GLUT_KEY_F7 7 +#define GLUT_KEY_F8 8 +#define GLUT_KEY_F9 9 +#define GLUT_KEY_F10 10 +#define GLUT_KEY_F11 11 +#define GLUT_KEY_F12 12 +/* directional keys */ +#define GLUT_KEY_LEFT 100 +#define GLUT_KEY_UP 101 +#define GLUT_KEY_RIGHT 102 +#define GLUT_KEY_DOWN 103 +#define GLUT_KEY_PAGE_UP 104 +#define GLUT_KEY_PAGE_DOWN 105 +#define GLUT_KEY_HOME 106 +#define GLUT_KEY_END 107 +#define GLUT_KEY_INSERT 108 +#endif + +/* Entry/exit state. */ +#define GLUT_LEFT 0 +#define GLUT_ENTERED 1 + +/* Menu usage state. */ +#define GLUT_MENU_NOT_IN_USE 0 +#define GLUT_MENU_IN_USE 1 + +/* Visibility state. */ +#define GLUT_NOT_VISIBLE 0 +#define GLUT_VISIBLE 1 + +/* Window status state. */ +#define GLUT_HIDDEN 0 +#define GLUT_FULLY_RETAINED 1 +#define GLUT_PARTIALLY_RETAINED 2 +#define GLUT_FULLY_COVERED 3 + +/* Color index component selection values. */ +#define GLUT_RED 0 +#define GLUT_GREEN 1 +#define GLUT_BLUE 2 + +#if defined(_WIN32) +/* Stroke font constants (use these in GLUT program). */ +#define GLUT_STROKE_ROMAN ((void*)0) +#define GLUT_STROKE_MONO_ROMAN ((void*)1) + +/* Bitmap font constants (use these in GLUT program). */ +#define GLUT_BITMAP_9_BY_15 ((void*)2) +#define GLUT_BITMAP_8_BY_13 ((void*)3) +#define GLUT_BITMAP_TIMES_ROMAN_10 ((void*)4) +#define GLUT_BITMAP_TIMES_ROMAN_24 ((void*)5) +#if (GLUT_API_VERSION >= 3) +#define GLUT_BITMAP_HELVETICA_10 ((void*)6) +#define GLUT_BITMAP_HELVETICA_12 ((void*)7) +#define GLUT_BITMAP_HELVETICA_18 ((void*)8) +#endif +#else +/* Stroke font opaque addresses (use constants instead in source code). */ +GLUTAPI void *glutStrokeRoman; +GLUTAPI void *glutStrokeMonoRoman; + +/* Stroke font constants (use these in GLUT program). */ +#define GLUT_STROKE_ROMAN (&glutStrokeRoman) +#define GLUT_STROKE_MONO_ROMAN (&glutStrokeMonoRoman) + +/* Bitmap font opaque addresses (use constants instead in source code). */ +GLUTAPI void *glutBitmap9By15; +GLUTAPI void *glutBitmap8By13; +GLUTAPI void *glutBitmapTimesRoman10; +GLUTAPI void *glutBitmapTimesRoman24; +GLUTAPI void *glutBitmapHelvetica10; +GLUTAPI void *glutBitmapHelvetica12; +GLUTAPI void *glutBitmapHelvetica18; + +/* Bitmap font constants (use these in GLUT program). */ +#define GLUT_BITMAP_9_BY_15 (&glutBitmap9By15) +#define GLUT_BITMAP_8_BY_13 (&glutBitmap8By13) +#define GLUT_BITMAP_TIMES_ROMAN_10 (&glutBitmapTimesRoman10) +#define GLUT_BITMAP_TIMES_ROMAN_24 (&glutBitmapTimesRoman24) +#if (GLUT_API_VERSION >= 3) +#define GLUT_BITMAP_HELVETICA_10 (&glutBitmapHelvetica10) +#define GLUT_BITMAP_HELVETICA_12 (&glutBitmapHelvetica12) +#define GLUT_BITMAP_HELVETICA_18 (&glutBitmapHelvetica18) +#endif +#endif + +/* glutGet parameters. */ +#define GLUT_WINDOW_X ((GLenum) 100) +#define GLUT_WINDOW_Y ((GLenum) 101) +#define GLUT_WINDOW_WIDTH ((GLenum) 102) +#define GLUT_WINDOW_HEIGHT ((GLenum) 103) +#define GLUT_WINDOW_BUFFER_SIZE ((GLenum) 104) +#define GLUT_WINDOW_STENCIL_SIZE ((GLenum) 105) +#define GLUT_WINDOW_DEPTH_SIZE ((GLenum) 106) +#define GLUT_WINDOW_RED_SIZE ((GLenum) 107) +#define GLUT_WINDOW_GREEN_SIZE ((GLenum) 108) +#define GLUT_WINDOW_BLUE_SIZE ((GLenum) 109) +#define GLUT_WINDOW_ALPHA_SIZE ((GLenum) 110) +#define GLUT_WINDOW_ACCUM_RED_SIZE ((GLenum) 111) +#define GLUT_WINDOW_ACCUM_GREEN_SIZE ((GLenum) 112) +#define GLUT_WINDOW_ACCUM_BLUE_SIZE ((GLenum) 113) +#define GLUT_WINDOW_ACCUM_ALPHA_SIZE ((GLenum) 114) +#define GLUT_WINDOW_DOUBLEBUFFER ((GLenum) 115) +#define GLUT_WINDOW_RGBA ((GLenum) 116) +#define GLUT_WINDOW_PARENT ((GLenum) 117) +#define GLUT_WINDOW_NUM_CHILDREN ((GLenum) 118) +#define GLUT_WINDOW_COLORMAP_SIZE ((GLenum) 119) +#if (GLUT_API_VERSION >= 2) +#define GLUT_WINDOW_NUM_SAMPLES ((GLenum) 120) +#define GLUT_WINDOW_STEREO ((GLenum) 121) +#endif +#if (GLUT_API_VERSION >= 3) +#define GLUT_WINDOW_CURSOR ((GLenum) 122) +#endif +#define GLUT_SCREEN_WIDTH ((GLenum) 200) +#define GLUT_SCREEN_HEIGHT ((GLenum) 201) +#define GLUT_SCREEN_WIDTH_MM ((GLenum) 202) +#define GLUT_SCREEN_HEIGHT_MM ((GLenum) 203) +#define GLUT_MENU_NUM_ITEMS ((GLenum) 300) +#define GLUT_DISPLAY_MODE_POSSIBLE ((GLenum) 400) +#define GLUT_INIT_WINDOW_X ((GLenum) 500) +#define GLUT_INIT_WINDOW_Y ((GLenum) 501) +#define GLUT_INIT_WINDOW_WIDTH ((GLenum) 502) +#define GLUT_INIT_WINDOW_HEIGHT ((GLenum) 503) +#define GLUT_INIT_DISPLAY_MODE ((GLenum) 504) +#if (GLUT_API_VERSION >= 2) +#define GLUT_ELAPSED_TIME ((GLenum) 700) +#endif +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) +#define GLUT_WINDOW_FORMAT_ID ((GLenum) 123) +#endif + +#if (GLUT_API_VERSION >= 2) +/* glutDeviceGet parameters. */ +#define GLUT_HAS_KEYBOARD ((GLenum) 600) +#define GLUT_HAS_MOUSE ((GLenum) 601) +#define GLUT_HAS_SPACEBALL ((GLenum) 602) +#define GLUT_HAS_DIAL_AND_BUTTON_BOX ((GLenum) 603) +#define GLUT_HAS_TABLET ((GLenum) 604) +#define GLUT_NUM_MOUSE_BUTTONS ((GLenum) 605) +#define GLUT_NUM_SPACEBALL_BUTTONS ((GLenum) 606) +#define GLUT_NUM_BUTTON_BOX_BUTTONS ((GLenum) 607) +#define GLUT_NUM_DIALS ((GLenum) 608) +#define GLUT_NUM_TABLET_BUTTONS ((GLenum) 609) +#endif +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) +#define GLUT_DEVICE_IGNORE_KEY_REPEAT ((GLenum) 610) +#define GLUT_DEVICE_KEY_REPEAT ((GLenum) 611) +#define GLUT_HAS_JOYSTICK ((GLenum) 612) +#define GLUT_OWNS_JOYSTICK ((GLenum) 613) +#define GLUT_JOYSTICK_BUTTONS ((GLenum) 614) +#define GLUT_JOYSTICK_AXES ((GLenum) 615) +#define GLUT_JOYSTICK_POLL_RATE ((GLenum) 616) +#endif + +#if (GLUT_API_VERSION >= 3) +/* glutLayerGet parameters. */ +#define GLUT_OVERLAY_POSSIBLE ((GLenum) 800) +#define GLUT_LAYER_IN_USE ((GLenum) 801) +#define GLUT_HAS_OVERLAY ((GLenum) 802) +#define GLUT_TRANSPARENT_INDEX ((GLenum) 803) +#define GLUT_NORMAL_DAMAGED ((GLenum) 804) +#define GLUT_OVERLAY_DAMAGED ((GLenum) 805) + +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +/* glutVideoResizeGet parameters. */ +#define GLUT_VIDEO_RESIZE_POSSIBLE ((GLenum) 900) +#define GLUT_VIDEO_RESIZE_IN_USE ((GLenum) 901) +#define GLUT_VIDEO_RESIZE_X_DELTA ((GLenum) 902) +#define GLUT_VIDEO_RESIZE_Y_DELTA ((GLenum) 903) +#define GLUT_VIDEO_RESIZE_WIDTH_DELTA ((GLenum) 904) +#define GLUT_VIDEO_RESIZE_HEIGHT_DELTA ((GLenum) 905) +#define GLUT_VIDEO_RESIZE_X ((GLenum) 906) +#define GLUT_VIDEO_RESIZE_Y ((GLenum) 907) +#define GLUT_VIDEO_RESIZE_WIDTH ((GLenum) 908) +#define GLUT_VIDEO_RESIZE_HEIGHT ((GLenum) 909) +#endif + +/* glutUseLayer parameters. */ +#define GLUT_NORMAL ((GLenum) 0) +#define GLUT_OVERLAY ((GLenum) 1) + +/* glutGetModifiers return mask. */ +#define GLUT_ACTIVE_SHIFT 1 +#define GLUT_ACTIVE_CTRL 2 +#define GLUT_ACTIVE_ALT 4 + +/* glutSetCursor parameters. */ +/* Basic arrows. */ +#define GLUT_CURSOR_RIGHT_ARROW 0 +#define GLUT_CURSOR_LEFT_ARROW 1 +/* Symbolic cursor shapes. */ +#define GLUT_CURSOR_INFO 2 +#define GLUT_CURSOR_DESTROY 3 +#define GLUT_CURSOR_HELP 4 +#define GLUT_CURSOR_CYCLE 5 +#define GLUT_CURSOR_SPRAY 6 +#define GLUT_CURSOR_WAIT 7 +#define GLUT_CURSOR_TEXT 8 +#define GLUT_CURSOR_CROSSHAIR 9 +/* Directional cursors. */ +#define GLUT_CURSOR_UP_DOWN 10 +#define GLUT_CURSOR_LEFT_RIGHT 11 +/* Sizing cursors. */ +#define GLUT_CURSOR_TOP_SIDE 12 +#define GLUT_CURSOR_BOTTOM_SIDE 13 +#define GLUT_CURSOR_LEFT_SIDE 14 +#define GLUT_CURSOR_RIGHT_SIDE 15 +#define GLUT_CURSOR_TOP_LEFT_CORNER 16 +#define GLUT_CURSOR_TOP_RIGHT_CORNER 17 +#define GLUT_CURSOR_BOTTOM_RIGHT_CORNER 18 +#define GLUT_CURSOR_BOTTOM_LEFT_CORNER 19 +/* Inherit from parent window. */ +#define GLUT_CURSOR_INHERIT 100 +/* Blank cursor. */ +#define GLUT_CURSOR_NONE 101 +/* Fullscreen crosshair (if available). */ +#define GLUT_CURSOR_FULL_CROSSHAIR 102 +#endif + +/* GLUT initialization sub-API. */ +GLUTAPI void APIENTRY glutInit(int *argcp, char **argv); +#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK) +GLUTAPI void APIENTRY __glutInitWithExit(int *argcp, char **argv, void (__cdecl *exitfunc)(int)); +#ifndef GLUT_BUILDING_LIB +static void APIENTRY glutInit_ATEXIT_HACK(int *argcp, char **argv) { __glutInitWithExit(argcp, argv, exit); } +#define glutInit glutInit_ATEXIT_HACK +#endif +#endif +GLUTAPI void APIENTRY glutInitDisplayMode(unsigned int mode); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +GLUTAPI void APIENTRY glutInitDisplayString(const char *string); +#endif +GLUTAPI void APIENTRY glutInitWindowPosition(int x, int y); +GLUTAPI void APIENTRY glutInitWindowSize(int width, int height); +GLUTAPI void APIENTRY glutMainLoop(void); + +/* GLUT window sub-API. */ +GLUTAPI int APIENTRY glutCreateWindow(const char *title); +#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK) +GLUTAPI int APIENTRY __glutCreateWindowWithExit(const char *title, void (__cdecl *exitfunc)(int)); +#ifndef GLUT_BUILDING_LIB +static int APIENTRY glutCreateWindow_ATEXIT_HACK(const char *title) { return __glutCreateWindowWithExit(title, exit); } +#define glutCreateWindow glutCreateWindow_ATEXIT_HACK +#endif +#endif +GLUTAPI int APIENTRY glutCreateSubWindow(int win, int x, int y, int width, int height); +GLUTAPI void APIENTRY glutDestroyWindow(int win); +GLUTAPI void APIENTRY glutPostRedisplay(void); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 11) +GLUTAPI void APIENTRY glutPostWindowRedisplay(int win); +#endif +GLUTAPI void APIENTRY glutSwapBuffers(void); +GLUTAPI int APIENTRY glutGetWindow(void); +GLUTAPI void APIENTRY glutSetWindow(int win); +GLUTAPI void APIENTRY glutSetWindowTitle(const char *title); +GLUTAPI void APIENTRY glutSetIconTitle(const char *title); +GLUTAPI void APIENTRY glutPositionWindow(int x, int y); +GLUTAPI void APIENTRY glutReshapeWindow(int width, int height); +GLUTAPI void APIENTRY glutPopWindow(void); +GLUTAPI void APIENTRY glutPushWindow(void); +GLUTAPI void APIENTRY glutIconifyWindow(void); +GLUTAPI void APIENTRY glutShowWindow(void); +GLUTAPI void APIENTRY glutHideWindow(void); +#if (GLUT_API_VERSION >= 3) +GLUTAPI void APIENTRY glutFullScreen(void); +GLUTAPI void APIENTRY glutSetCursor(int cursor); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +GLUTAPI void APIENTRY glutWarpPointer(int x, int y); +#endif + +/* GLUT overlay sub-API. */ +GLUTAPI void APIENTRY glutEstablishOverlay(void); +GLUTAPI void APIENTRY glutRemoveOverlay(void); +GLUTAPI void APIENTRY glutUseLayer(GLenum layer); +GLUTAPI void APIENTRY glutPostOverlayRedisplay(void); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 11) +GLUTAPI void APIENTRY glutPostWindowOverlayRedisplay(int win); +#endif +GLUTAPI void APIENTRY glutShowOverlay(void); +GLUTAPI void APIENTRY glutHideOverlay(void); +#endif + +/* GLUT menu sub-API. */ +GLUTAPI int APIENTRY glutCreateMenu(void (GLUTCALLBACK *func)(int)); +#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK) +GLUTAPI int APIENTRY __glutCreateMenuWithExit(void (GLUTCALLBACK *func)(int), void (__cdecl *exitfunc)(int)); +#ifndef GLUT_BUILDING_LIB +static int APIENTRY glutCreateMenu_ATEXIT_HACK(void (GLUTCALLBACK *func)(int)) { return __glutCreateMenuWithExit(func, exit); } +#define glutCreateMenu glutCreateMenu_ATEXIT_HACK +#endif +#endif +GLUTAPI void APIENTRY glutDestroyMenu(int menu); +GLUTAPI int APIENTRY glutGetMenu(void); +GLUTAPI void APIENTRY glutSetMenu(int menu); +GLUTAPI void APIENTRY glutAddMenuEntry(const char *label, int value); +GLUTAPI void APIENTRY glutAddSubMenu(const char *label, int submenu); +GLUTAPI void APIENTRY glutChangeToMenuEntry(int item, const char *label, int value); +GLUTAPI void APIENTRY glutChangeToSubMenu(int item, const char *label, int submenu); +GLUTAPI void APIENTRY glutRemoveMenuItem(int item); +GLUTAPI void APIENTRY glutAttachMenu(int button); +GLUTAPI void APIENTRY glutDetachMenu(int button); + +/* GLUT window callback sub-API. */ +GLUTAPI void APIENTRY glutDisplayFunc(void (GLUTCALLBACK *func)(void)); +GLUTAPI void APIENTRY glutReshapeFunc(void (GLUTCALLBACK *func)(int width, int height)); +GLUTAPI void APIENTRY glutKeyboardFunc(void (GLUTCALLBACK *func)(unsigned char key, int x, int y)); +GLUTAPI void APIENTRY glutMouseFunc(void (GLUTCALLBACK *func)(int button, int state, int x, int y)); +GLUTAPI void APIENTRY glutMotionFunc(void (GLUTCALLBACK *func)(int x, int y)); +GLUTAPI void APIENTRY glutPassiveMotionFunc(void (GLUTCALLBACK *func)(int x, int y)); +GLUTAPI void APIENTRY glutEntryFunc(void (GLUTCALLBACK *func)(int state)); +GLUTAPI void APIENTRY glutVisibilityFunc(void (GLUTCALLBACK *func)(int state)); +GLUTAPI void APIENTRY glutIdleFunc(void (GLUTCALLBACK *func)(void)); +GLUTAPI void APIENTRY glutTimerFunc(unsigned int millis, void (GLUTCALLBACK *func)(int value), int value); +GLUTAPI void APIENTRY glutMenuStateFunc(void (GLUTCALLBACK *func)(int state)); +#if (GLUT_API_VERSION >= 2) +GLUTAPI void APIENTRY glutSpecialFunc(void (GLUTCALLBACK *func)(int key, int x, int y)); +GLUTAPI void APIENTRY glutSpaceballMotionFunc(void (GLUTCALLBACK *func)(int x, int y, int z)); +GLUTAPI void APIENTRY glutSpaceballRotateFunc(void (GLUTCALLBACK *func)(int x, int y, int z)); +GLUTAPI void APIENTRY glutSpaceballButtonFunc(void (GLUTCALLBACK *func)(int button, int state)); +GLUTAPI void APIENTRY glutButtonBoxFunc(void (GLUTCALLBACK *func)(int button, int state)); +GLUTAPI void APIENTRY glutDialsFunc(void (GLUTCALLBACK *func)(int dial, int value)); +GLUTAPI void APIENTRY glutTabletMotionFunc(void (GLUTCALLBACK *func)(int x, int y)); +GLUTAPI void APIENTRY glutTabletButtonFunc(void (GLUTCALLBACK *func)(int button, int state, int x, int y)); +#if (GLUT_API_VERSION >= 3) +GLUTAPI void APIENTRY glutMenuStatusFunc(void (GLUTCALLBACK *func)(int status, int x, int y)); +GLUTAPI void APIENTRY glutOverlayDisplayFunc(void (GLUTCALLBACK *func)(void)); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +GLUTAPI void APIENTRY glutWindowStatusFunc(void (GLUTCALLBACK *func)(int state)); +#endif +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) +GLUTAPI void APIENTRY glutKeyboardUpFunc(void (GLUTCALLBACK *func)(unsigned char key, int x, int y)); +GLUTAPI void APIENTRY glutSpecialUpFunc(void (GLUTCALLBACK *func)(int key, int x, int y)); +GLUTAPI void APIENTRY glutJoystickFunc(void (GLUTCALLBACK *func)(unsigned int buttonMask, int x, int y, int z), int pollInterval); +#endif +#endif +#endif + +/* GLUT color index sub-API. */ +GLUTAPI void APIENTRY glutSetColor(int, GLfloat red, GLfloat green, GLfloat blue); +GLUTAPI GLfloat APIENTRY glutGetColor(int ndx, int component); +GLUTAPI void APIENTRY glutCopyColormap(int win); + +/* GLUT state retrieval sub-API. */ +GLUTAPI int APIENTRY glutGet(GLenum type); +GLUTAPI int APIENTRY glutDeviceGet(GLenum type); +#if (GLUT_API_VERSION >= 2) +/* GLUT extension support sub-API */ +GLUTAPI int APIENTRY glutExtensionSupported(const char *name); +#endif +#if (GLUT_API_VERSION >= 3) +GLUTAPI int APIENTRY glutGetModifiers(void); +GLUTAPI int APIENTRY glutLayerGet(GLenum type); +#endif + +/* GLUT font sub-API */ +GLUTAPI void APIENTRY glutBitmapCharacter(void *font, int character); +GLUTAPI int APIENTRY glutBitmapWidth(void *font, int character); +GLUTAPI void APIENTRY glutStrokeCharacter(void *font, int character); +GLUTAPI int APIENTRY glutStrokeWidth(void *font, int character); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +GLUTAPI int APIENTRY glutBitmapLength(void *font, const unsigned char *string); +GLUTAPI int APIENTRY glutStrokeLength(void *font, const unsigned char *string); +#endif + +/* GLUT pre-built models sub-API */ +GLUTAPI void APIENTRY glutWireSphere(GLdouble radius, GLint slices, GLint stacks); +GLUTAPI void APIENTRY glutSolidSphere(GLdouble radius, GLint slices, GLint stacks); +GLUTAPI void APIENTRY glutWireCone(GLdouble base, GLdouble height, GLint slices, GLint stacks); +GLUTAPI void APIENTRY glutSolidCone(GLdouble base, GLdouble height, GLint slices, GLint stacks); +GLUTAPI void APIENTRY glutWireCube(GLdouble size); +GLUTAPI void APIENTRY glutSolidCube(GLdouble size); +GLUTAPI void APIENTRY glutWireTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings); +GLUTAPI void APIENTRY glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings); +GLUTAPI void APIENTRY glutWireDodecahedron(void); +GLUTAPI void APIENTRY glutSolidDodecahedron(void); +GLUTAPI void APIENTRY glutWireTeapot(GLdouble size); +GLUTAPI void APIENTRY glutSolidTeapot(GLdouble size); +GLUTAPI void APIENTRY glutWireOctahedron(void); +GLUTAPI void APIENTRY glutSolidOctahedron(void); +GLUTAPI void APIENTRY glutWireTetrahedron(void); +GLUTAPI void APIENTRY glutSolidTetrahedron(void); +GLUTAPI void APIENTRY glutWireIcosahedron(void); +GLUTAPI void APIENTRY glutSolidIcosahedron(void); + +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +/* GLUT video resize sub-API. */ +GLUTAPI int APIENTRY glutVideoResizeGet(GLenum param); +GLUTAPI void APIENTRY glutSetupVideoResizing(void); +GLUTAPI void APIENTRY glutStopVideoResizing(void); +GLUTAPI void APIENTRY glutVideoResize(int x, int y, int width, int height); +GLUTAPI void APIENTRY glutVideoPan(int x, int y, int width, int height); + +/* GLUT debugging sub-API. */ +GLUTAPI void APIENTRY glutReportErrors(void); +#endif + +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) +/* GLUT device control sub-API. */ +/* glutSetKeyRepeat modes. */ +#define GLUT_KEY_REPEAT_OFF 0 +#define GLUT_KEY_REPEAT_ON 1 +#define GLUT_KEY_REPEAT_DEFAULT 2 + +/* Joystick button masks. */ +#define GLUT_JOYSTICK_BUTTON_A 1 +#define GLUT_JOYSTICK_BUTTON_B 2 +#define GLUT_JOYSTICK_BUTTON_C 4 +#define GLUT_JOYSTICK_BUTTON_D 8 + +GLUTAPI void APIENTRY glutIgnoreKeyRepeat(int ignore); +GLUTAPI void APIENTRY glutSetKeyRepeat(int repeatMode); +GLUTAPI void APIENTRY glutForceJoystickFunc(void); + +/* GLUT game mode sub-API. */ +/* glutGameModeGet. */ +#define GLUT_GAME_MODE_ACTIVE ((GLenum) 0) +#define GLUT_GAME_MODE_POSSIBLE ((GLenum) 1) +#define GLUT_GAME_MODE_WIDTH ((GLenum) 2) +#define GLUT_GAME_MODE_HEIGHT ((GLenum) 3) +#define GLUT_GAME_MODE_PIXEL_DEPTH ((GLenum) 4) +#define GLUT_GAME_MODE_REFRESH_RATE ((GLenum) 5) +#define GLUT_GAME_MODE_DISPLAY_CHANGED ((GLenum) 6) + +GLUTAPI void APIENTRY glutGameModeString(const char *string); +GLUTAPI int APIENTRY glutEnterGameMode(void); +GLUTAPI void APIENTRY glutLeaveGameMode(void); +GLUTAPI int APIENTRY glutGameModeGet(GLenum mode); +#endif + +#ifdef __cplusplus +} + +#endif + +#ifdef GLUT_APIENTRY_DEFINED +# undef GLUT_APIENTRY_DEFINED +# undef APIENTRY +#endif + +#ifdef GLUT_WINGDIAPI_DEFINED +# undef GLUT_WINGDIAPI_DEFINED +# undef WINGDIAPI +#endif + +#ifdef GLUT_DEFINED___CDECL +# undef GLUT_DEFINED___CDECL +# undef __cdecl +#endif + +#ifdef GLUT_DEFINED__CRTIMP +# undef GLUT_DEFINED__CRTIMP +# undef _CRTIMP +#endif + +#endif /* __glut_h__ */ diff -r 4feced261c68 -r de822cd3df3a misc/winutils/include/SDL.h --- a/misc/winutils/include/SDL.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/winutils/include/SDL.h Tue Jan 21 22:43:06 2014 +0100 @@ -58,17 +58,17 @@ * specify the subsystems which you will be using in your application. */ /*@{*/ -#define SDL_INIT_TIMER 0x00000001 -#define SDL_INIT_AUDIO 0x00000010 -#define SDL_INIT_VIDEO 0x00000020 -#define SDL_INIT_CDROM 0x00000100 -#define SDL_INIT_JOYSTICK 0x00000200 -#define SDL_INIT_NOPARACHUTE 0x00100000 /**< Don't catch fatal signals */ -#define SDL_INIT_EVENTTHREAD 0x01000000 /**< Not supported on all OS's */ -#define SDL_INIT_EVERYTHING 0x0000FFFF +#define SDL_INIT_TIMER 0x00000001 +#define SDL_INIT_AUDIO 0x00000010 +#define SDL_INIT_VIDEO 0x00000020 +#define SDL_INIT_CDROM 0x00000100 +#define SDL_INIT_JOYSTICK 0x00000200 +#define SDL_INIT_NOPARACHUTE 0x00100000 /**< Don't catch fatal signals */ +#define SDL_INIT_EVENTTHREAD 0x01000000 /**< Not supported on all OS's */ +#define SDL_INIT_EVERYTHING 0x0000FFFF /*@}*/ -/** This function loads the SDL dynamically linked library and initializes +/** This function loads the SDL dynamically linked library and initializes * the subsystems specified by 'flags' (and those satisfying dependencies) * Unless the SDL_INIT_NOPARACHUTE flag is set, it will install cleanup * signal handlers for some commonly ignored fatal signals (like SIGSEGV) diff -r 4feced261c68 -r de822cd3df3a misc/winutils/include/SDL_active.h --- a/misc/winutils/include/SDL_active.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/winutils/include/SDL_active.h Tue Jan 21 22:43:06 2014 +0100 @@ -22,7 +22,7 @@ /** * @file SDL_active.h - * Include file for SDL application focus event handling + * Include file for SDL application focus event handling */ #ifndef _SDL_active_h @@ -39,13 +39,13 @@ /** @name The available application states */ /*@{*/ -#define SDL_APPMOUSEFOCUS 0x01 /**< The app has mouse coverage */ -#define SDL_APPINPUTFOCUS 0x02 /**< The app has input focus */ -#define SDL_APPACTIVE 0x04 /**< The application is active */ +#define SDL_APPMOUSEFOCUS 0x01 /**< The app has mouse coverage */ +#define SDL_APPINPUTFOCUS 0x02 /**< The app has input focus */ +#define SDL_APPACTIVE 0x04 /**< The application is active */ /*@}*/ /* Function prototypes */ -/** +/** * This function returns the current state of the application, which is a * bitwise combination of SDL_APPMOUSEFOCUS, SDL_APPINPUTFOCUS, and * SDL_APPACTIVE. If SDL_APPACTIVE is set, then the user is able to diff -r 4feced261c68 -r de822cd3df3a misc/winutils/include/SDL_audio.h --- a/misc/winutils/include/SDL_audio.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/winutils/include/SDL_audio.h Tue Jan 21 22:43:06 2014 +0100 @@ -72,24 +72,24 @@ * */ typedef struct SDL_AudioSpec { - int freq; /**< DSP frequency -- samples per second */ - Uint16 format; /**< Audio data format */ - Uint8 channels; /**< Number of channels: 1 mono, 2 stereo */ - Uint8 silence; /**< Audio buffer silence value (calculated) */ - Uint16 samples; /**< Audio buffer size in samples (power of 2) */ - Uint16 padding; /**< Necessary for some compile environments */ - Uint32 size; /**< Audio buffer size in bytes (calculated) */ - /** - * This function is called when the audio device needs more data. - * - * @param[out] stream A pointer to the audio data buffer - * @param[in] len The length of the audio buffer in bytes. - * - * Once the callback returns, the buffer will no longer be valid. - * Stereo samples are stored in a LRLRLR ordering. - */ - void (SDLCALL *callback)(void *userdata, Uint8 *stream, int len); - void *userdata; + int freq; /**< DSP frequency -- samples per second */ + Uint16 format; /**< Audio data format */ + Uint8 channels; /**< Number of channels: 1 mono, 2 stereo */ + Uint8 silence; /**< Audio buffer silence value (calculated) */ + Uint16 samples; /**< Audio buffer size in samples (power of 2) */ + Uint16 padding; /**< Necessary for some compile environments */ + Uint32 size; /**< Audio buffer size in bytes (calculated) */ + /** + * This function is called when the audio device needs more data. + * + * @param[out] stream A pointer to the audio data buffer + * @param[in] len The length of the audio buffer in bytes. + * + * Once the callback returns, the buffer will no longer be valid. + * Stereo samples are stored in a LRLRLR ordering. + */ + void (SDLCALL *callback)(void *userdata, Uint8 *stream, int len); + void *userdata; } SDL_AudioSpec; /** @@ -97,25 +97,25 @@ * defaults to LSB byte order */ /*@{*/ -#define AUDIO_U8 0x0008 /**< Unsigned 8-bit samples */ -#define AUDIO_S8 0x8008 /**< Signed 8-bit samples */ -#define AUDIO_U16LSB 0x0010 /**< Unsigned 16-bit samples */ -#define AUDIO_S16LSB 0x8010 /**< Signed 16-bit samples */ -#define AUDIO_U16MSB 0x1010 /**< As above, but big-endian byte order */ -#define AUDIO_S16MSB 0x9010 /**< As above, but big-endian byte order */ -#define AUDIO_U16 AUDIO_U16LSB -#define AUDIO_S16 AUDIO_S16LSB +#define AUDIO_U8 0x0008 /**< Unsigned 8-bit samples */ +#define AUDIO_S8 0x8008 /**< Signed 8-bit samples */ +#define AUDIO_U16LSB 0x0010 /**< Unsigned 16-bit samples */ +#define AUDIO_S16LSB 0x8010 /**< Signed 16-bit samples */ +#define AUDIO_U16MSB 0x1010 /**< As above, but big-endian byte order */ +#define AUDIO_S16MSB 0x9010 /**< As above, but big-endian byte order */ +#define AUDIO_U16 AUDIO_U16LSB +#define AUDIO_S16 AUDIO_S16LSB /** * @name Native audio byte ordering */ /*@{*/ #if SDL_BYTEORDER == SDL_LIL_ENDIAN -#define AUDIO_U16SYS AUDIO_U16LSB -#define AUDIO_S16SYS AUDIO_S16LSB +#define AUDIO_U16SYS AUDIO_U16LSB +#define AUDIO_S16SYS AUDIO_S16LSB #else -#define AUDIO_U16SYS AUDIO_U16MSB -#define AUDIO_S16SYS AUDIO_S16MSB +#define AUDIO_U16SYS AUDIO_U16MSB +#define AUDIO_S16SYS AUDIO_S16MSB #endif /*@}*/ @@ -124,17 +124,17 @@ /** A structure to hold a set of audio conversion filters and buffers */ typedef struct SDL_AudioCVT { - int needed; /**< Set to 1 if conversion possible */ - Uint16 src_format; /**< Source audio format */ - Uint16 dst_format; /**< Target audio format */ - double rate_incr; /**< Rate conversion increment */ - Uint8 *buf; /**< Buffer to hold entire audio data */ - int len; /**< Length of original audio buffer */ - int len_cvt; /**< Length of converted audio buffer */ - int len_mult; /**< buffer must be len*len_mult big */ - double len_ratio; /**< Given len, final size is len*len_ratio */ - void (SDLCALL *filters[10])(struct SDL_AudioCVT *cvt, Uint16 format); - int filter_index; /**< Current audio conversion function */ + int needed; /**< Set to 1 if conversion possible */ + Uint16 src_format; /**< Source audio format */ + Uint16 dst_format; /**< Target audio format */ + double rate_incr; /**< Rate conversion increment */ + Uint8 *buf; /**< Buffer to hold entire audio data */ + int len; /**< Length of original audio buffer */ + int len_cvt; /**< Length of converted audio buffer */ + int len_mult; /**< buffer must be len*len_mult big */ + double len_ratio; /**< Given len, final size is len*len_ratio */ + void (SDLCALL *filters[10])(struct SDL_AudioCVT *cvt, Uint16 format); + int filter_index; /**< Current audio conversion function */ } SDL_AudioCVT; @@ -164,7 +164,7 @@ * structure pointed to by 'obtained'. If 'obtained' is NULL, the audio * data passed to the callback function will be guaranteed to be in the * requested format, and will be automatically converted to the hardware - * audio format if necessary. This function returns -1 if it failed + * audio format if necessary. This function returns -1 if it failed * to open the audio device, or couldn't set up the audio thread. * * The audio device starts out playing silence when it's opened, and should @@ -178,9 +178,9 @@ extern DECLSPEC int SDLCALL SDL_OpenAudio(SDL_AudioSpec *desired, SDL_AudioSpec *obtained); typedef enum { - SDL_AUDIO_STOPPED = 0, - SDL_AUDIO_PLAYING, - SDL_AUDIO_PAUSED + SDL_AUDIO_STOPPED = 0, + SDL_AUDIO_PLAYING, + SDL_AUDIO_PAUSED } SDL_audiostatus; /** Get the current audio state */ @@ -199,24 +199,24 @@ * This function loads a WAVE from the data source, automatically freeing * that source if 'freesrc' is non-zero. For example, to load a WAVE file, * you could do: - * @code SDL_LoadWAV_RW(SDL_RWFromFile("sample.wav", "rb"), 1, ...); @endcode + * @code SDL_LoadWAV_RW(SDL_RWFromFile("sample.wav", "rb"), 1, ...); @endcode * * If this function succeeds, it returns the given SDL_AudioSpec, * filled with the audio data format of the wave data, and sets * 'audio_buf' to a malloc()'d buffer containing the audio data, * and sets 'audio_len' to the length of that audio buffer, in bytes. - * You need to free the audio buffer with SDL_FreeWAV() when you are + * You need to free the audio buffer with SDL_FreeWAV() when you are * done with it. * - * This function returns NULL and sets the SDL error message if the - * wave file cannot be opened, uses an unknown data format, or is + * This function returns NULL and sets the SDL error message if the + * wave file cannot be opened, uses an unknown data format, or is * corrupt. Currently raw and MS-ADPCM WAVE files are supported. */ extern DECLSPEC SDL_AudioSpec * SDLCALL SDL_LoadWAV_RW(SDL_RWops *src, int freesrc, SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len); /** Compatibility convenience function -- loads a WAV from a file */ #define SDL_LoadWAV(file, spec, audio_buf, audio_len) \ - SDL_LoadWAV_RW(SDL_RWFromFile(file, "rb"),1, spec,audio_buf,audio_len) + SDL_LoadWAV_RW(SDL_RWFromFile(file, "rb"),1, spec,audio_buf,audio_len) /** * This function frees data previously allocated with SDL_LoadWAV_RW() @@ -232,8 +232,8 @@ * @return This function returns 0, or -1 if there was an error. */ extern DECLSPEC int SDLCALL SDL_BuildAudioCVT(SDL_AudioCVT *cvt, - Uint16 src_format, Uint8 src_channels, int src_rate, - Uint16 dst_format, Uint8 dst_channels, int dst_rate); + Uint16 src_format, Uint8 src_channels, int src_rate, + Uint16 dst_format, Uint8 dst_channels, int dst_rate); /** * Once you have initialized the 'cvt' structure using SDL_BuildAudioCVT(), diff -r 4feced261c68 -r de822cd3df3a misc/winutils/include/SDL_cdrom.h --- a/misc/winutils/include/SDL_cdrom.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/winutils/include/SDL_cdrom.h Tue Jan 21 22:43:06 2014 +0100 @@ -45,47 +45,47 @@ */ /** The maximum number of CD-ROM tracks on a disk */ -#define SDL_MAX_TRACKS 99 +#define SDL_MAX_TRACKS 99 /** @name Track Types * The types of CD-ROM track possible */ /*@{*/ -#define SDL_AUDIO_TRACK 0x00 -#define SDL_DATA_TRACK 0x04 +#define SDL_AUDIO_TRACK 0x00 +#define SDL_DATA_TRACK 0x04 /*@}*/ /** The possible states which a CD-ROM drive can be in. */ typedef enum { - CD_TRAYEMPTY, - CD_STOPPED, - CD_PLAYING, - CD_PAUSED, - CD_ERROR = -1 + CD_TRAYEMPTY, + CD_STOPPED, + CD_PLAYING, + CD_PAUSED, + CD_ERROR = -1 } CDstatus; /** Given a status, returns true if there's a disk in the drive */ -#define CD_INDRIVE(status) ((int)(status) > 0) +#define CD_INDRIVE(status) ((int)(status) > 0) typedef struct SDL_CDtrack { - Uint8 id; /**< Track number */ - Uint8 type; /**< Data or audio track */ - Uint16 unused; - Uint32 length; /**< Length, in frames, of this track */ - Uint32 offset; /**< Offset, in frames, from start of disk */ + Uint8 id; /**< Track number */ + Uint8 type; /**< Data or audio track */ + Uint16 unused; + Uint32 length; /**< Length, in frames, of this track */ + Uint32 offset; /**< Offset, in frames, from start of disk */ } SDL_CDtrack; /** This structure is only current as of the last call to SDL_CDStatus() */ typedef struct SDL_CD { - int id; /**< Private drive identifier */ - CDstatus status; /**< Current drive status */ + int id; /**< Private drive identifier */ + CDstatus status; /**< Current drive status */ - /** The rest of this structure is only valid if there's a CD in drive */ + /** The rest of this structure is only valid if there's a CD in drive */ /*@{*/ - int numtracks; /**< Number of tracks on disk */ - int cur_track; /**< Current track position */ - int cur_frame; /**< Current frame offset within current track */ - SDL_CDtrack track[SDL_MAX_TRACKS+1]; + int numtracks; /**< Number of tracks on disk */ + int cur_track; /**< Current track position */ + int cur_frame; /**< Current frame offset within current track */ + SDL_CDtrack track[SDL_MAX_TRACKS+1]; /*@}*/ } SDL_CD; @@ -93,16 +93,16 @@ * Conversion functions from frames to Minute/Second/Frames and vice versa */ /*@{*/ -#define CD_FPS 75 -#define FRAMES_TO_MSF(f, M,S,F) { \ - int value = f; \ - *(F) = value%CD_FPS; \ - value /= CD_FPS; \ - *(S) = value%60; \ - value /= 60; \ - *(M) = value; \ +#define CD_FPS 75 +#define FRAMES_TO_MSF(f, M,S,F) { \ + int value = f; \ + *(F) = value%CD_FPS; \ + value /= CD_FPS; \ + *(S) = value%60; \ + value /= 60; \ + *(M) = value; \ } -#define MSF_TO_FRAMES(M, S, F) ((M)*60*CD_FPS+(S)*CD_FPS+(F)) +#define MSF_TO_FRAMES(M, S, F) ((M)*60*CD_FPS+(S)*CD_FPS+(F)) /*@}*/ /* CD-audio API functions: */ @@ -140,28 +140,28 @@ /** * Play the given CD starting at 'start_track' and 'start_frame' for 'ntracks' - * tracks and 'nframes' frames. If both 'ntrack' and 'nframe' are 0, play + * tracks and 'nframes' frames. If both 'ntrack' and 'nframe' are 0, play * until the end of the CD. This function will skip data tracks. - * This function should only be called after calling SDL_CDStatus() to + * This function should only be called after calling SDL_CDStatus() to * get track information about the CD. * For example: * @code - * // Play entire CD: - * if ( CD_INDRIVE(SDL_CDStatus(cdrom)) ) - * SDL_CDPlayTracks(cdrom, 0, 0, 0, 0); - * // Play last track: - * if ( CD_INDRIVE(SDL_CDStatus(cdrom)) ) { - * SDL_CDPlayTracks(cdrom, cdrom->numtracks-1, 0, 0, 0); - * } - * // Play first and second track and 10 seconds of third track: - * if ( CD_INDRIVE(SDL_CDStatus(cdrom)) ) - * SDL_CDPlayTracks(cdrom, 0, 0, 2, 10); + * // Play entire CD: + * if ( CD_INDRIVE(SDL_CDStatus(cdrom)) ) + * SDL_CDPlayTracks(cdrom, 0, 0, 0, 0); + * // Play last track: + * if ( CD_INDRIVE(SDL_CDStatus(cdrom)) ) { + * SDL_CDPlayTracks(cdrom, cdrom->numtracks-1, 0, 0, 0); + * } + * // Play first and second track and 10 seconds of third track: + * if ( CD_INDRIVE(SDL_CDStatus(cdrom)) ) + * SDL_CDPlayTracks(cdrom, 0, 0, 2, 10); * @endcode * * @return This function returns 0, or -1 if there was an error. */ extern DECLSPEC int SDLCALL SDL_CDPlayTracks(SDL_CD *cdrom, - int start_track, int start_frame, int ntracks, int nframes); + int start_track, int start_frame, int ntracks, int nframes); /** * Play the given CD starting at 'start' frame for 'length' frames. diff -r 4feced261c68 -r de822cd3df3a misc/winutils/include/SDL_config_win32.h --- a/misc/winutils/include/SDL_config_win32.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/winutils/include/SDL_config_win32.h Tue Jan 21 22:43:06 2014 +0100 @@ -28,16 +28,16 @@ /* This is a set of defines to configure the SDL features */ #if defined(__GNUC__) || defined(__DMC__) -#define HAVE_STDINT_H 1 +#define HAVE_STDINT_H 1 #elif defined(_MSC_VER) -typedef signed __int8 int8_t; -typedef unsigned __int8 uint8_t; -typedef signed __int16 int16_t; -typedef unsigned __int16 uint16_t; -typedef signed __int32 int32_t; -typedef unsigned __int32 uint32_t; -typedef signed __int64 int64_t; -typedef unsigned __int64 uint64_t; +typedef signed __int8 int8_t; +typedef unsigned __int8 uint8_t; +typedef signed __int16 int16_t; +typedef unsigned __int16 uint16_t; +typedef signed __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; #ifndef _UINTPTR_T_DEFINED #ifdef _WIN64 typedef unsigned __int64 uintptr_t; @@ -53,7 +53,7 @@ #if ((_MSC_VER <= 1200) && (!defined(LONG_PTR))) #define LONG_PTR LONG #endif -#else /* !__GNUC__ && !_MSC_VER */ +#else /* !__GNUC__ && !_MSC_VER */ typedef signed char int8_t; typedef unsigned char uint8_t; typedef signed short int16_t; @@ -68,10 +68,10 @@ #endif typedef unsigned int uintptr_t; #endif /* __GNUC__ || _MSC_VER */ -#define SDL_HAS_64BIT_TYPE 1 +#define SDL_HAS_64BIT_TYPE 1 /* Enabled for SDL 1.2 (binary compatibility) */ -#define HAVE_LIBC 1 +#define HAVE_LIBC 1 #ifdef HAVE_LIBC /* Useful headers */ #define HAVE_STDIO_H 1 @@ -117,67 +117,67 @@ #define HAVE__STRNICMP 1 #define HAVE_SSCANF 1 #else -#define HAVE_STDARG_H 1 -#define HAVE_STDDEF_H 1 +#define HAVE_STDARG_H 1 +#define HAVE_STDDEF_H 1 #endif /* Enable various audio drivers */ #ifndef _WIN32_WCE -#define SDL_AUDIO_DRIVER_DSOUND 1 +#define SDL_AUDIO_DRIVER_DSOUND 1 #endif -#define SDL_AUDIO_DRIVER_WAVEOUT 1 -#define SDL_AUDIO_DRIVER_DISK 1 -#define SDL_AUDIO_DRIVER_DUMMY 1 +#define SDL_AUDIO_DRIVER_WAVEOUT 1 +#define SDL_AUDIO_DRIVER_DISK 1 +#define SDL_AUDIO_DRIVER_DUMMY 1 /* Enable various cdrom drivers */ #ifdef _WIN32_WCE #define SDL_CDROM_DISABLED 1 #else -#define SDL_CDROM_WIN32 1 +#define SDL_CDROM_WIN32 1 #endif /* Enable various input drivers */ #ifdef _WIN32_WCE #define SDL_JOYSTICK_DISABLED 1 #else -#define SDL_JOYSTICK_WINMM 1 +#define SDL_JOYSTICK_WINMM 1 #endif /* Enable various shared object loading systems */ -#define SDL_LOADSO_WIN32 1 +#define SDL_LOADSO_WIN32 1 /* Enable various threading systems */ -#define SDL_THREAD_WIN32 1 +#define SDL_THREAD_WIN32 1 /* Enable various timer systems */ #ifdef _WIN32_WCE -#define SDL_TIMER_WINCE 1 +#define SDL_TIMER_WINCE 1 #else -#define SDL_TIMER_WIN32 1 +#define SDL_TIMER_WIN32 1 #endif /* Enable various video drivers */ #ifdef _WIN32_WCE -#define SDL_VIDEO_DRIVER_GAPI 1 +#define SDL_VIDEO_DRIVER_GAPI 1 #endif #ifndef _WIN32_WCE -#define SDL_VIDEO_DRIVER_DDRAW 1 +#define SDL_VIDEO_DRIVER_DDRAW 1 #endif -#define SDL_VIDEO_DRIVER_DUMMY 1 -#define SDL_VIDEO_DRIVER_WINDIB 1 +#define SDL_VIDEO_DRIVER_DUMMY 1 +#define SDL_VIDEO_DRIVER_WINDIB 1 /* Enable OpenGL support */ #ifndef _WIN32_WCE -#define SDL_VIDEO_OPENGL 1 -#define SDL_VIDEO_OPENGL_WGL 1 +#define SDL_VIDEO_OPENGL 1 +#define SDL_VIDEO_OPENGL_WGL 1 #endif /* Disable screensaver */ -#define SDL_VIDEO_DISABLE_SCREENSAVER 1 +#define SDL_VIDEO_DISABLE_SCREENSAVER 1 /* Enable assembly routines (Win64 doesn't have inline asm) */ #ifndef _WIN64 -#define SDL_ASSEMBLY_ROUTINES 1 +#define SDL_ASSEMBLY_ROUTINES 1 #endif #endif /* _SDL_config_win32_h */ diff -r 4feced261c68 -r de822cd3df3a misc/winutils/include/SDL_endian.h --- a/misc/winutils/include/SDL_endian.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/winutils/include/SDL_endian.h Tue Jan 21 22:43:06 2014 +0100 @@ -31,14 +31,14 @@ #include "SDL_stdinc.h" /** @name SDL_ENDIANs - * The two types of endianness + * The two types of endianness */ /*@{*/ -#define SDL_LIL_ENDIAN 1234 -#define SDL_BIG_ENDIAN 4321 +#define SDL_LIL_ENDIAN 1234 +#define SDL_BIG_ENDIAN 4321 /*@}*/ -#ifndef SDL_BYTEORDER /* Not defined in SDL_config.h? */ +#ifndef SDL_BYTEORDER /* Not defined in SDL_config.h? */ #ifdef __linux__ #include #define SDL_BYTEORDER __BYTE_ORDER @@ -48,9 +48,9 @@ (defined(__MIPS__) && defined(__MISPEB__)) || \ defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || \ defined(__sparc__) -#define SDL_BYTEORDER SDL_BIG_ENDIAN +#define SDL_BYTEORDER SDL_BIG_ENDIAN #else -#define SDL_BYTEORDER SDL_LIL_ENDIAN +#define SDL_BYTEORDER SDL_LIL_ENDIAN #endif #endif /* __linux __ */ #endif /* !SDL_BYTEORDER */ @@ -74,32 +74,32 @@ !(__GNUC__ == 2 && __GNUC_MINOR__ <= 95 /* broken gcc version */) static __inline__ Uint16 SDL_Swap16(Uint16 x) { - __asm__("xchgb %b0,%h0" : "=q" (x) : "0" (x)); - return x; + __asm__("xchgb %b0,%h0" : "=q" (x) : "0" (x)); + return x; } #elif defined(__GNUC__) && defined(__x86_64__) static __inline__ Uint16 SDL_Swap16(Uint16 x) { - __asm__("xchgb %b0,%h0" : "=Q" (x) : "0" (x)); - return x; + __asm__("xchgb %b0,%h0" : "=Q" (x) : "0" (x)); + return x; } #elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__)) static __inline__ Uint16 SDL_Swap16(Uint16 x) { - Uint16 result; + Uint16 result; - __asm__("rlwimi %0,%2,8,16,23" : "=&r" (result) : "0" (x >> 8), "r" (x)); - return result; + __asm__("rlwimi %0,%2,8,16,23" : "=&r" (result) : "0" (x >> 8), "r" (x)); + return result; } #elif defined(__GNUC__) && (defined(__m68k__) && !defined(__mcoldfire__)) static __inline__ Uint16 SDL_Swap16(Uint16 x) { - __asm__("rorw #8,%0" : "=d" (x) : "0" (x) : "cc"); - return x; + __asm__("rorw #8,%0" : "=d" (x) : "0" (x) : "cc"); + return x; } #else static __inline__ Uint16 SDL_Swap16(Uint16 x) { - return SDL_static_cast(Uint16, ((x<<8)|(x>>8))); + return SDL_static_cast(Uint16, ((x<<8)|(x>>8))); } #endif @@ -107,34 +107,34 @@ !(__GNUC__ == 2 && __GNUC_MINOR__ <= 95 /* broken gcc version */) static __inline__ Uint32 SDL_Swap32(Uint32 x) { - __asm__("bswap %0" : "=r" (x) : "0" (x)); - return x; + __asm__("bswap %0" : "=r" (x) : "0" (x)); + return x; } #elif defined(__GNUC__) && defined(__x86_64__) static __inline__ Uint32 SDL_Swap32(Uint32 x) { - __asm__("bswapl %0" : "=r" (x) : "0" (x)); - return x; + __asm__("bswapl %0" : "=r" (x) : "0" (x)); + return x; } #elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__)) static __inline__ Uint32 SDL_Swap32(Uint32 x) { - Uint32 result; + Uint32 result; - __asm__("rlwimi %0,%2,24,16,23" : "=&r" (result) : "0" (x>>24), "r" (x)); - __asm__("rlwimi %0,%2,8,8,15" : "=&r" (result) : "0" (result), "r" (x)); - __asm__("rlwimi %0,%2,24,0,7" : "=&r" (result) : "0" (result), "r" (x)); - return result; + __asm__("rlwimi %0,%2,24,16,23" : "=&r" (result) : "0" (x>>24), "r" (x)); + __asm__("rlwimi %0,%2,8,8,15" : "=&r" (result) : "0" (result), "r" (x)); + __asm__("rlwimi %0,%2,24,0,7" : "=&r" (result) : "0" (result), "r" (x)); + return result; } #elif defined(__GNUC__) && (defined(__m68k__) && !defined(__mcoldfire__)) static __inline__ Uint32 SDL_Swap32(Uint32 x) { - __asm__("rorw #8,%0\n\tswap %0\n\trorw #8,%0" : "=d" (x) : "0" (x) : "cc"); - return x; + __asm__("rorw #8,%0\n\tswap %0\n\trorw #8,%0" : "=d" (x) : "0" (x) : "cc"); + return x; } #else static __inline__ Uint32 SDL_Swap32(Uint32 x) { - return SDL_static_cast(Uint32, ((x<<24)|((x<<8)&0x00FF0000)|((x>>8)&0x0000FF00)|(x>>24))); + return SDL_static_cast(Uint32, ((x<<24)|((x<<8)&0x00FF0000)|((x>>8)&0x0000FF00)|(x>>24))); } #endif @@ -143,35 +143,35 @@ !(__GNUC__ == 2 && __GNUC_MINOR__ <= 95 /* broken gcc version */) static __inline__ Uint64 SDL_Swap64(Uint64 x) { - union { - struct { Uint32 a,b; } s; - Uint64 u; - } v; - v.u = x; - __asm__("bswapl %0 ; bswapl %1 ; xchgl %0,%1" - : "=r" (v.s.a), "=r" (v.s.b) - : "0" (v.s.a), "1" (v.s.b)); - return v.u; + union { + struct { Uint32 a,b; } s; + Uint64 u; + } v; + v.u = x; + __asm__("bswapl %0 ; bswapl %1 ; xchgl %0,%1" + : "=r" (v.s.a), "=r" (v.s.b) + : "0" (v.s.a), "1" (v.s.b)); + return v.u; } #elif defined(__GNUC__) && defined(__x86_64__) static __inline__ Uint64 SDL_Swap64(Uint64 x) { - __asm__("bswapq %0" : "=r" (x) : "0" (x)); - return x; + __asm__("bswapq %0" : "=r" (x) : "0" (x)); + return x; } #else static __inline__ Uint64 SDL_Swap64(Uint64 x) { - Uint32 hi, lo; + Uint32 hi, lo; - /* Separate into high and low 32-bit values and swap them */ - lo = SDL_static_cast(Uint32, x & 0xFFFFFFFF); - x >>= 32; - hi = SDL_static_cast(Uint32, x & 0xFFFFFFFF); - x = SDL_Swap32(lo); - x <<= 32; - x |= SDL_Swap32(hi); - return (x); + /* Separate into high and low 32-bit values and swap them */ + lo = SDL_static_cast(Uint32, x & 0xFFFFFFFF); + x >>= 32; + hi = SDL_static_cast(Uint32, x & 0xFFFFFFFF); + x = SDL_Swap32(lo); + x <<= 32; + x |= SDL_Swap32(hi); + return (x); } #endif #else @@ -179,7 +179,7 @@ * If there is no real 64-bit datatype, then compilers will complain about * the fake 64-bit datatype that SDL provides when it compiles user code. */ -#define SDL_Swap64(X) (X) +#define SDL_Swap64(X) (X) #endif /* SDL_HAS_64BIT_TYPE */ /*@}*/ @@ -189,19 +189,19 @@ */ /*@{*/ #if SDL_BYTEORDER == SDL_LIL_ENDIAN -#define SDL_SwapLE16(X) (X) -#define SDL_SwapLE32(X) (X) -#define SDL_SwapLE64(X) (X) -#define SDL_SwapBE16(X) SDL_Swap16(X) -#define SDL_SwapBE32(X) SDL_Swap32(X) -#define SDL_SwapBE64(X) SDL_Swap64(X) +#define SDL_SwapLE16(X) (X) +#define SDL_SwapLE32(X) (X) +#define SDL_SwapLE64(X) (X) +#define SDL_SwapBE16(X) SDL_Swap16(X) +#define SDL_SwapBE32(X) SDL_Swap32(X) +#define SDL_SwapBE64(X) SDL_Swap64(X) #else -#define SDL_SwapLE16(X) SDL_Swap16(X) -#define SDL_SwapLE32(X) SDL_Swap32(X) -#define SDL_SwapLE64(X) SDL_Swap64(X) -#define SDL_SwapBE16(X) (X) -#define SDL_SwapBE32(X) (X) -#define SDL_SwapBE64(X) (X) +#define SDL_SwapLE16(X) SDL_Swap16(X) +#define SDL_SwapLE32(X) SDL_Swap32(X) +#define SDL_SwapLE64(X) SDL_Swap64(X) +#define SDL_SwapBE16(X) (X) +#define SDL_SwapBE32(X) (X) +#define SDL_SwapBE64(X) (X) #endif /*@}*/ diff -r 4feced261c68 -r de822cd3df3a misc/winutils/include/SDL_error.h --- a/misc/winutils/include/SDL_error.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/winutils/include/SDL_error.h Tue Jan 21 22:43:06 2014 +0100 @@ -36,7 +36,7 @@ extern "C" { #endif -/** +/** * @name Public functions */ /*@{*/ @@ -50,15 +50,15 @@ * @internal Private error message function - used internally */ /*@{*/ -#define SDL_OutOfMemory() SDL_Error(SDL_ENOMEM) -#define SDL_Unsupported() SDL_Error(SDL_UNSUPPORTED) +#define SDL_OutOfMemory() SDL_Error(SDL_ENOMEM) +#define SDL_Unsupported() SDL_Error(SDL_UNSUPPORTED) typedef enum { - SDL_ENOMEM, - SDL_EFREAD, - SDL_EFWRITE, - SDL_EFSEEK, - SDL_UNSUPPORTED, - SDL_LASTERROR + SDL_ENOMEM, + SDL_EFREAD, + SDL_EFWRITE, + SDL_EFSEEK, + SDL_UNSUPPORTED, + SDL_LASTERROR } SDL_errorcode; extern DECLSPEC void SDLCALL SDL_Error(SDL_errorcode code); /*@}*/ diff -r 4feced261c68 -r de822cd3df3a misc/winutils/include/SDL_events.h --- a/misc/winutils/include/SDL_events.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/winutils/include/SDL_events.h Tue Jan 21 22:43:06 2014 +0100 @@ -44,147 +44,147 @@ /** @name General keyboard/mouse state definitions */ /*@{*/ -#define SDL_RELEASED 0 -#define SDL_PRESSED 1 +#define SDL_RELEASED 0 +#define SDL_PRESSED 1 /*@}*/ /** Event enumerations */ typedef enum { - SDL_NOEVENT = 0, /**< Unused (do not remove) */ - SDL_ACTIVEEVENT, /**< Application loses/gains visibility */ - SDL_KEYDOWN, /**< Keys pressed */ - SDL_KEYUP, /**< Keys released */ - SDL_MOUSEMOTION, /**< Mouse moved */ - SDL_MOUSEBUTTONDOWN, /**< Mouse button pressed */ - SDL_MOUSEBUTTONUP, /**< Mouse button released */ - SDL_JOYAXISMOTION, /**< Joystick axis motion */ - SDL_JOYBALLMOTION, /**< Joystick trackball motion */ - SDL_JOYHATMOTION, /**< Joystick hat position change */ - SDL_JOYBUTTONDOWN, /**< Joystick button pressed */ - SDL_JOYBUTTONUP, /**< Joystick button released */ - SDL_QUIT, /**< User-requested quit */ - SDL_SYSWMEVENT, /**< System specific event */ - SDL_EVENT_RESERVEDA, /**< Reserved for future use.. */ - SDL_EVENT_RESERVEDB, /**< Reserved for future use.. */ - SDL_VIDEORESIZE, /**< User resized video mode */ - SDL_VIDEOEXPOSE, /**< Screen needs to be redrawn */ - SDL_EVENT_RESERVED2, /**< Reserved for future use.. */ - SDL_EVENT_RESERVED3, /**< Reserved for future use.. */ - SDL_EVENT_RESERVED4, /**< Reserved for future use.. */ - SDL_EVENT_RESERVED5, /**< Reserved for future use.. */ - SDL_EVENT_RESERVED6, /**< Reserved for future use.. */ - SDL_EVENT_RESERVED7, /**< Reserved for future use.. */ + SDL_NOEVENT = 0, /**< Unused (do not remove) */ + SDL_ACTIVEEVENT, /**< Application loses/gains visibility */ + SDL_KEYDOWN, /**< Keys pressed */ + SDL_KEYUP, /**< Keys released */ + SDL_MOUSEMOTION, /**< Mouse moved */ + SDL_MOUSEBUTTONDOWN, /**< Mouse button pressed */ + SDL_MOUSEBUTTONUP, /**< Mouse button released */ + SDL_JOYAXISMOTION, /**< Joystick axis motion */ + SDL_JOYBALLMOTION, /**< Joystick trackball motion */ + SDL_JOYHATMOTION, /**< Joystick hat position change */ + SDL_JOYBUTTONDOWN, /**< Joystick button pressed */ + SDL_JOYBUTTONUP, /**< Joystick button released */ + SDL_QUIT, /**< User-requested quit */ + SDL_SYSWMEVENT, /**< System specific event */ + SDL_EVENT_RESERVEDA, /**< Reserved for future use.. */ + SDL_EVENT_RESERVEDB, /**< Reserved for future use.. */ + SDL_VIDEORESIZE, /**< User resized video mode */ + SDL_VIDEOEXPOSE, /**< Screen needs to be redrawn */ + SDL_EVENT_RESERVED2, /**< Reserved for future use.. */ + SDL_EVENT_RESERVED3, /**< Reserved for future use.. */ + SDL_EVENT_RESERVED4, /**< Reserved for future use.. */ + SDL_EVENT_RESERVED5, /**< Reserved for future use.. */ + SDL_EVENT_RESERVED6, /**< Reserved for future use.. */ + SDL_EVENT_RESERVED7, /**< Reserved for future use.. */ /** Events SDL_USEREVENT through SDL_MAXEVENTS-1 are for your use */ SDL_USEREVENT = 24, /** This last event is only for bounding internal arrays - * It is the number of bits in the event mask datatype -- Uint32 + * It is the number of bits in the event mask datatype -- Uint32 */ SDL_NUMEVENTS = 32 } SDL_EventType; /** @name Predefined event masks */ /*@{*/ -#define SDL_EVENTMASK(X) (1<<(X)) +#define SDL_EVENTMASK(X) (1<<(X)) typedef enum { - SDL_ACTIVEEVENTMASK = SDL_EVENTMASK(SDL_ACTIVEEVENT), - SDL_KEYDOWNMASK = SDL_EVENTMASK(SDL_KEYDOWN), - SDL_KEYUPMASK = SDL_EVENTMASK(SDL_KEYUP), - SDL_KEYEVENTMASK = SDL_EVENTMASK(SDL_KEYDOWN)| - SDL_EVENTMASK(SDL_KEYUP), - SDL_MOUSEMOTIONMASK = SDL_EVENTMASK(SDL_MOUSEMOTION), - SDL_MOUSEBUTTONDOWNMASK = SDL_EVENTMASK(SDL_MOUSEBUTTONDOWN), - SDL_MOUSEBUTTONUPMASK = SDL_EVENTMASK(SDL_MOUSEBUTTONUP), - SDL_MOUSEEVENTMASK = SDL_EVENTMASK(SDL_MOUSEMOTION)| - SDL_EVENTMASK(SDL_MOUSEBUTTONDOWN)| - SDL_EVENTMASK(SDL_MOUSEBUTTONUP), - SDL_JOYAXISMOTIONMASK = SDL_EVENTMASK(SDL_JOYAXISMOTION), - SDL_JOYBALLMOTIONMASK = SDL_EVENTMASK(SDL_JOYBALLMOTION), - SDL_JOYHATMOTIONMASK = SDL_EVENTMASK(SDL_JOYHATMOTION), - SDL_JOYBUTTONDOWNMASK = SDL_EVENTMASK(SDL_JOYBUTTONDOWN), - SDL_JOYBUTTONUPMASK = SDL_EVENTMASK(SDL_JOYBUTTONUP), - SDL_JOYEVENTMASK = SDL_EVENTMASK(SDL_JOYAXISMOTION)| - SDL_EVENTMASK(SDL_JOYBALLMOTION)| - SDL_EVENTMASK(SDL_JOYHATMOTION)| - SDL_EVENTMASK(SDL_JOYBUTTONDOWN)| - SDL_EVENTMASK(SDL_JOYBUTTONUP), - SDL_VIDEORESIZEMASK = SDL_EVENTMASK(SDL_VIDEORESIZE), - SDL_VIDEOEXPOSEMASK = SDL_EVENTMASK(SDL_VIDEOEXPOSE), - SDL_QUITMASK = SDL_EVENTMASK(SDL_QUIT), - SDL_SYSWMEVENTMASK = SDL_EVENTMASK(SDL_SYSWMEVENT) + SDL_ACTIVEEVENTMASK = SDL_EVENTMASK(SDL_ACTIVEEVENT), + SDL_KEYDOWNMASK = SDL_EVENTMASK(SDL_KEYDOWN), + SDL_KEYUPMASK = SDL_EVENTMASK(SDL_KEYUP), + SDL_KEYEVENTMASK = SDL_EVENTMASK(SDL_KEYDOWN)| + SDL_EVENTMASK(SDL_KEYUP), + SDL_MOUSEMOTIONMASK = SDL_EVENTMASK(SDL_MOUSEMOTION), + SDL_MOUSEBUTTONDOWNMASK = SDL_EVENTMASK(SDL_MOUSEBUTTONDOWN), + SDL_MOUSEBUTTONUPMASK = SDL_EVENTMASK(SDL_MOUSEBUTTONUP), + SDL_MOUSEEVENTMASK = SDL_EVENTMASK(SDL_MOUSEMOTION)| + SDL_EVENTMASK(SDL_MOUSEBUTTONDOWN)| + SDL_EVENTMASK(SDL_MOUSEBUTTONUP), + SDL_JOYAXISMOTIONMASK = SDL_EVENTMASK(SDL_JOYAXISMOTION), + SDL_JOYBALLMOTIONMASK = SDL_EVENTMASK(SDL_JOYBALLMOTION), + SDL_JOYHATMOTIONMASK = SDL_EVENTMASK(SDL_JOYHATMOTION), + SDL_JOYBUTTONDOWNMASK = SDL_EVENTMASK(SDL_JOYBUTTONDOWN), + SDL_JOYBUTTONUPMASK = SDL_EVENTMASK(SDL_JOYBUTTONUP), + SDL_JOYEVENTMASK = SDL_EVENTMASK(SDL_JOYAXISMOTION)| + SDL_EVENTMASK(SDL_JOYBALLMOTION)| + SDL_EVENTMASK(SDL_JOYHATMOTION)| + SDL_EVENTMASK(SDL_JOYBUTTONDOWN)| + SDL_EVENTMASK(SDL_JOYBUTTONUP), + SDL_VIDEORESIZEMASK = SDL_EVENTMASK(SDL_VIDEORESIZE), + SDL_VIDEOEXPOSEMASK = SDL_EVENTMASK(SDL_VIDEOEXPOSE), + SDL_QUITMASK = SDL_EVENTMASK(SDL_QUIT), + SDL_SYSWMEVENTMASK = SDL_EVENTMASK(SDL_SYSWMEVENT) } SDL_EventMask ; -#define SDL_ALLEVENTS 0xFFFFFFFF +#define SDL_ALLEVENTS 0xFFFFFFFF /*@}*/ /** Application visibility event structure */ typedef struct SDL_ActiveEvent { - Uint8 type; /**< SDL_ACTIVEEVENT */ - Uint8 gain; /**< Whether given states were gained or lost (1/0) */ - Uint8 state; /**< A mask of the focus states */ + Uint8 type; /**< SDL_ACTIVEEVENT */ + Uint8 gain; /**< Whether given states were gained or lost (1/0) */ + Uint8 state; /**< A mask of the focus states */ } SDL_ActiveEvent; /** Keyboard event structure */ typedef struct SDL_KeyboardEvent { - Uint8 type; /**< SDL_KEYDOWN or SDL_KEYUP */ - Uint8 which; /**< The keyboard device index */ - Uint8 state; /**< SDL_PRESSED or SDL_RELEASED */ - SDL_keysym keysym; + Uint8 type; /**< SDL_KEYDOWN or SDL_KEYUP */ + Uint8 which; /**< The keyboard device index */ + Uint8 state; /**< SDL_PRESSED or SDL_RELEASED */ + SDL_keysym keysym; } SDL_KeyboardEvent; /** Mouse motion event structure */ typedef struct SDL_MouseMotionEvent { - Uint8 type; /**< SDL_MOUSEMOTION */ - Uint8 which; /**< The mouse device index */ - Uint8 state; /**< The current button state */ - Uint16 x, y; /**< The X/Y coordinates of the mouse */ - Sint16 xrel; /**< The relative motion in the X direction */ - Sint16 yrel; /**< The relative motion in the Y direction */ + Uint8 type; /**< SDL_MOUSEMOTION */ + Uint8 which; /**< The mouse device index */ + Uint8 state; /**< The current button state */ + Uint16 x, y; /**< The X/Y coordinates of the mouse */ + Sint16 xrel; /**< The relative motion in the X direction */ + Sint16 yrel; /**< The relative motion in the Y direction */ } SDL_MouseMotionEvent; /** Mouse button event structure */ typedef struct SDL_MouseButtonEvent { - Uint8 type; /**< SDL_MOUSEBUTTONDOWN or SDL_MOUSEBUTTONUP */ - Uint8 which; /**< The mouse device index */ - Uint8 button; /**< The mouse button index */ - Uint8 state; /**< SDL_PRESSED or SDL_RELEASED */ - Uint16 x, y; /**< The X/Y coordinates of the mouse at press time */ + Uint8 type; /**< SDL_MOUSEBUTTONDOWN or SDL_MOUSEBUTTONUP */ + Uint8 which; /**< The mouse device index */ + Uint8 button; /**< The mouse button index */ + Uint8 state; /**< SDL_PRESSED or SDL_RELEASED */ + Uint16 x, y; /**< The X/Y coordinates of the mouse at press time */ } SDL_MouseButtonEvent; /** Joystick axis motion event structure */ typedef struct SDL_JoyAxisEvent { - Uint8 type; /**< SDL_JOYAXISMOTION */ - Uint8 which; /**< The joystick device index */ - Uint8 axis; /**< The joystick axis index */ - Sint16 value; /**< The axis value (range: -32768 to 32767) */ + Uint8 type; /**< SDL_JOYAXISMOTION */ + Uint8 which; /**< The joystick device index */ + Uint8 axis; /**< The joystick axis index */ + Sint16 value; /**< The axis value (range: -32768 to 32767) */ } SDL_JoyAxisEvent; /** Joystick trackball motion event structure */ typedef struct SDL_JoyBallEvent { - Uint8 type; /**< SDL_JOYBALLMOTION */ - Uint8 which; /**< The joystick device index */ - Uint8 ball; /**< The joystick trackball index */ - Sint16 xrel; /**< The relative motion in the X direction */ - Sint16 yrel; /**< The relative motion in the Y direction */ + Uint8 type; /**< SDL_JOYBALLMOTION */ + Uint8 which; /**< The joystick device index */ + Uint8 ball; /**< The joystick trackball index */ + Sint16 xrel; /**< The relative motion in the X direction */ + Sint16 yrel; /**< The relative motion in the Y direction */ } SDL_JoyBallEvent; /** Joystick hat position change event structure */ typedef struct SDL_JoyHatEvent { - Uint8 type; /**< SDL_JOYHATMOTION */ - Uint8 which; /**< The joystick device index */ - Uint8 hat; /**< The joystick hat index */ - Uint8 value; /**< The hat position value: - * SDL_HAT_LEFTUP SDL_HAT_UP SDL_HAT_RIGHTUP - * SDL_HAT_LEFT SDL_HAT_CENTERED SDL_HAT_RIGHT - * SDL_HAT_LEFTDOWN SDL_HAT_DOWN SDL_HAT_RIGHTDOWN - * Note that zero means the POV is centered. - */ + Uint8 type; /**< SDL_JOYHATMOTION */ + Uint8 which; /**< The joystick device index */ + Uint8 hat; /**< The joystick hat index */ + Uint8 value; /**< The hat position value: + * SDL_HAT_LEFTUP SDL_HAT_UP SDL_HAT_RIGHTUP + * SDL_HAT_LEFT SDL_HAT_CENTERED SDL_HAT_RIGHT + * SDL_HAT_LEFTDOWN SDL_HAT_DOWN SDL_HAT_RIGHTDOWN + * Note that zero means the POV is centered. + */ } SDL_JoyHatEvent; /** Joystick button event structure */ typedef struct SDL_JoyButtonEvent { - Uint8 type; /**< SDL_JOYBUTTONDOWN or SDL_JOYBUTTONUP */ - Uint8 which; /**< The joystick device index */ - Uint8 button; /**< The joystick button index */ - Uint8 state; /**< SDL_PRESSED or SDL_RELEASED */ + Uint8 type; /**< SDL_JOYBUTTONDOWN or SDL_JOYBUTTONUP */ + Uint8 which; /**< The joystick device index */ + Uint8 button; /**< The joystick button index */ + Uint8 state; /**< SDL_PRESSED or SDL_RELEASED */ } SDL_JoyButtonEvent; /** The "window resized" event @@ -192,53 +192,53 @@ * mode with the new width and height. */ typedef struct SDL_ResizeEvent { - Uint8 type; /**< SDL_VIDEORESIZE */ - int w; /**< New width */ - int h; /**< New height */ + Uint8 type; /**< SDL_VIDEORESIZE */ + int w; /**< New width */ + int h; /**< New height */ } SDL_ResizeEvent; /** The "screen redraw" event */ typedef struct SDL_ExposeEvent { - Uint8 type; /**< SDL_VIDEOEXPOSE */ + Uint8 type; /**< SDL_VIDEOEXPOSE */ } SDL_ExposeEvent; /** The "quit requested" event */ typedef struct SDL_QuitEvent { - Uint8 type; /**< SDL_QUIT */ + Uint8 type; /**< SDL_QUIT */ } SDL_QuitEvent; /** A user-defined event type */ typedef struct SDL_UserEvent { - Uint8 type; /**< SDL_USEREVENT through SDL_NUMEVENTS-1 */ - int code; /**< User defined event code */ - void *data1; /**< User defined data pointer */ - void *data2; /**< User defined data pointer */ + Uint8 type; /**< SDL_USEREVENT through SDL_NUMEVENTS-1 */ + int code; /**< User defined event code */ + void *data1; /**< User defined data pointer */ + void *data2; /**< User defined data pointer */ } SDL_UserEvent; /** If you want to use this event, you should include SDL_syswm.h */ struct SDL_SysWMmsg; typedef struct SDL_SysWMmsg SDL_SysWMmsg; typedef struct SDL_SysWMEvent { - Uint8 type; - SDL_SysWMmsg *msg; + Uint8 type; + SDL_SysWMmsg *msg; } SDL_SysWMEvent; /** General event structure */ typedef union SDL_Event { - Uint8 type; - SDL_ActiveEvent active; - SDL_KeyboardEvent key; - SDL_MouseMotionEvent motion; - SDL_MouseButtonEvent button; - SDL_JoyAxisEvent jaxis; - SDL_JoyBallEvent jball; - SDL_JoyHatEvent jhat; - SDL_JoyButtonEvent jbutton; - SDL_ResizeEvent resize; - SDL_ExposeEvent expose; - SDL_QuitEvent quit; - SDL_UserEvent user; - SDL_SysWMEvent syswm; + Uint8 type; + SDL_ActiveEvent active; + SDL_KeyboardEvent key; + SDL_MouseMotionEvent motion; + SDL_MouseButtonEvent button; + SDL_JoyAxisEvent jaxis; + SDL_JoyBallEvent jball; + SDL_JoyHatEvent jhat; + SDL_JoyButtonEvent jbutton; + SDL_ResizeEvent resize; + SDL_ExposeEvent expose; + SDL_QuitEvent quit; + SDL_UserEvent user; + SDL_SysWMEvent syswm; } SDL_Event; @@ -251,9 +251,9 @@ extern DECLSPEC void SDLCALL SDL_PumpEvents(void); typedef enum { - SDL_ADDEVENT, - SDL_PEEKEVENT, - SDL_GETEVENT + SDL_ADDEVENT, + SDL_PEEKEVENT, + SDL_GETEVENT } SDL_eventaction; /** @@ -264,7 +264,7 @@ * If 'action' is SDL_PEEKEVENT, up to 'numevents' events at the front * of the event queue, matching 'mask', will be returned and will not * be removed from the queue. - * If 'action' is SDL_GETEVENT, up to 'numevents' events at the front + * If 'action' is SDL_GETEVENT, up to 'numevents' events at the front * of the event queue, matching 'mask', will be returned and will be * removed from the queue. * @@ -275,7 +275,7 @@ * This function is thread-safe. */ extern DECLSPEC int SDLCALL SDL_PeepEvents(SDL_Event *events, int numevents, - SDL_eventaction action, Uint32 mask); + SDL_eventaction action, Uint32 mask); /** Polls for currently pending events, and returns 1 if there are any pending * events, or 0 if there are none available. If 'event' is not NULL, the next @@ -306,11 +306,11 @@ * @code typedef int (SDLCALL *SDL_EventFilter)(const SDL_Event *event); @endcode * * If the filter returns 1, then the event will be added to the internal queue. - * If it returns 0, then the event will be dropped from the queue, but the + * If it returns 0, then the event will be dropped from the queue, but the * internal state will still be updated. This allows selective filtering of * dynamically arriving events. * - * @warning Be very careful of what you do in the event filter function, as + * @warning Be very careful of what you do in the event filter function, as * it may run in a different thread! * * There is one caveat when dealing with the SDL_QUITEVENT event type. The @@ -331,10 +331,10 @@ /** @name Event State */ /*@{*/ -#define SDL_QUERY -1 -#define SDL_IGNORE 0 -#define SDL_DISABLE 0 -#define SDL_ENABLE 1 +#define SDL_QUERY -1 +#define SDL_IGNORE 0 +#define SDL_DISABLE 0 +#define SDL_ENABLE 1 /*@}*/ /** @@ -342,7 +342,7 @@ * If 'state' is set to SDL_IGNORE, that event will be automatically dropped * from the event queue and will not event be filtered. * If 'state' is set to SDL_ENABLE, that event will be processed normally. -* If 'state' is set to SDL_QUERY, SDL_EventState() will return the +* If 'state' is set to SDL_QUERY, SDL_EventState() will return the * current processing state of the specified event. */ extern DECLSPEC Uint8 SDLCALL SDL_EventState(Uint8 type, int state); diff -r 4feced261c68 -r de822cd3df3a misc/winutils/include/SDL_joystick.h --- a/misc/winutils/include/SDL_joystick.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/winutils/include/SDL_joystick.h Tue Jan 21 22:43:06 2014 +0100 @@ -138,18 +138,18 @@ * The return value of SDL_JoystickGetHat() is one of the following positions: */ /*@{*/ -#define SDL_HAT_CENTERED 0x00 -#define SDL_HAT_UP 0x01 -#define SDL_HAT_RIGHT 0x02 -#define SDL_HAT_DOWN 0x04 -#define SDL_HAT_LEFT 0x08 -#define SDL_HAT_RIGHTUP (SDL_HAT_RIGHT|SDL_HAT_UP) -#define SDL_HAT_RIGHTDOWN (SDL_HAT_RIGHT|SDL_HAT_DOWN) -#define SDL_HAT_LEFTUP (SDL_HAT_LEFT|SDL_HAT_UP) -#define SDL_HAT_LEFTDOWN (SDL_HAT_LEFT|SDL_HAT_DOWN) +#define SDL_HAT_CENTERED 0x00 +#define SDL_HAT_UP 0x01 +#define SDL_HAT_RIGHT 0x02 +#define SDL_HAT_DOWN 0x04 +#define SDL_HAT_LEFT 0x08 +#define SDL_HAT_RIGHTUP (SDL_HAT_RIGHT|SDL_HAT_UP) +#define SDL_HAT_RIGHTDOWN (SDL_HAT_RIGHT|SDL_HAT_DOWN) +#define SDL_HAT_LEFTUP (SDL_HAT_LEFT|SDL_HAT_UP) +#define SDL_HAT_LEFTDOWN (SDL_HAT_LEFT|SDL_HAT_DOWN) /*@}*/ -/** +/** * Get the current state of a POV hat on a joystick * * @param[in] hat The hat indices start at index 0. diff -r 4feced261c68 -r de822cd3df3a misc/winutils/include/SDL_keyboard.h --- a/misc/winutils/include/SDL_keyboard.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/winutils/include/SDL_keyboard.h Tue Jan 21 22:43:06 2014 +0100 @@ -48,23 +48,23 @@ * high 9 bits of the character are 0, then this maps to the equivalent * ASCII character: * @code - * char ch; - * if ( (keysym.unicode & 0xFF80) == 0 ) { - * ch = keysym.unicode & 0x7F; - * } else { - * An international character.. - * } + * char ch; + * if ( (keysym.unicode & 0xFF80) == 0 ) { + * ch = keysym.unicode & 0x7F; + * } else { + * An international character.. + * } * @endcode */ typedef struct SDL_keysym { - Uint8 scancode; /**< hardware specific scancode */ - SDLKey sym; /**< SDL virtual keysym */ - SDLMod mod; /**< current key modifiers */ - Uint16 unicode; /**< translated character */ + Uint8 scancode; /**< hardware specific scancode */ + SDLKey sym; /**< SDL virtual keysym */ + SDLMod mod; /**< current key modifiers */ + Uint16 unicode; /**< translated character */ } SDL_keysym; /** This is the mask which refers to all hotkey bindings */ -#define SDL_ALL_HOTKEYS 0xFFFFFFFF +#define SDL_ALL_HOTKEYS 0xFFFFFFFF /* Function prototypes */ /** @@ -81,8 +81,8 @@ */ extern DECLSPEC int SDLCALL SDL_EnableUNICODE(int enable); -#define SDL_DEFAULT_REPEAT_DELAY 500 -#define SDL_DEFAULT_REPEAT_INTERVAL 30 +#define SDL_DEFAULT_REPEAT_DELAY 500 +#define SDL_DEFAULT_REPEAT_INTERVAL 30 /** * Enable/Disable keyboard repeat. Keyboard repeat defaults to off. * @@ -102,10 +102,10 @@ * Get a snapshot of the current state of the keyboard. * Returns an array of keystates, indexed by the SDLK_* syms. * Usage: - * @code - * Uint8 *keystate = SDL_GetKeyState(NULL); - * if ( keystate[SDLK_RETURN] ) //... \ is pressed. - * @endcode + * @code + * Uint8 *keystate = SDL_GetKeyState(NULL); + * if ( keystate[SDLK_RETURN] ) //... \ is pressed. + * @endcode */ extern DECLSPEC Uint8 * SDLCALL SDL_GetKeyState(int *numkeys); diff -r 4feced261c68 -r de822cd3df3a misc/winutils/include/SDL_keysym.h --- a/misc/winutils/include/SDL_keysym.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/winutils/include/SDL_keysym.h Tue Jan 21 22:43:06 2014 +0100 @@ -33,294 +33,294 @@ * The keyboard syms have been cleverly chosen to map to ASCII */ /*@{*/ - SDLK_UNKNOWN = 0, - SDLK_FIRST = 0, - SDLK_BACKSPACE = 8, - SDLK_TAB = 9, - SDLK_CLEAR = 12, - SDLK_RETURN = 13, - SDLK_PAUSE = 19, - SDLK_ESCAPE = 27, - SDLK_SPACE = 32, - SDLK_EXCLAIM = 33, - SDLK_QUOTEDBL = 34, - SDLK_HASH = 35, - SDLK_DOLLAR = 36, - SDLK_AMPERSAND = 38, - SDLK_QUOTE = 39, - SDLK_LEFTPAREN = 40, - SDLK_RIGHTPAREN = 41, - SDLK_ASTERISK = 42, - SDLK_PLUS = 43, - SDLK_COMMA = 44, - SDLK_MINUS = 45, - SDLK_PERIOD = 46, - SDLK_SLASH = 47, - SDLK_0 = 48, - SDLK_1 = 49, - SDLK_2 = 50, - SDLK_3 = 51, - SDLK_4 = 52, - SDLK_5 = 53, - SDLK_6 = 54, - SDLK_7 = 55, - SDLK_8 = 56, - SDLK_9 = 57, - SDLK_COLON = 58, - SDLK_SEMICOLON = 59, - SDLK_LESS = 60, - SDLK_EQUALS = 61, - SDLK_GREATER = 62, - SDLK_QUESTION = 63, - SDLK_AT = 64, - /* - Skip uppercase letters - */ - SDLK_LEFTBRACKET = 91, - SDLK_BACKSLASH = 92, - SDLK_RIGHTBRACKET = 93, - SDLK_CARET = 94, - SDLK_UNDERSCORE = 95, - SDLK_BACKQUOTE = 96, - SDLK_a = 97, - SDLK_b = 98, - SDLK_c = 99, - SDLK_d = 100, - SDLK_e = 101, - SDLK_f = 102, - SDLK_g = 103, - SDLK_h = 104, - SDLK_i = 105, - SDLK_j = 106, - SDLK_k = 107, - SDLK_l = 108, - SDLK_m = 109, - SDLK_n = 110, - SDLK_o = 111, - SDLK_p = 112, - SDLK_q = 113, - SDLK_r = 114, - SDLK_s = 115, - SDLK_t = 116, - SDLK_u = 117, - SDLK_v = 118, - SDLK_w = 119, - SDLK_x = 120, - SDLK_y = 121, - SDLK_z = 122, - SDLK_DELETE = 127, - /* End of ASCII mapped keysyms */ + SDLK_UNKNOWN = 0, + SDLK_FIRST = 0, + SDLK_BACKSPACE = 8, + SDLK_TAB = 9, + SDLK_CLEAR = 12, + SDLK_RETURN = 13, + SDLK_PAUSE = 19, + SDLK_ESCAPE = 27, + SDLK_SPACE = 32, + SDLK_EXCLAIM = 33, + SDLK_QUOTEDBL = 34, + SDLK_HASH = 35, + SDLK_DOLLAR = 36, + SDLK_AMPERSAND = 38, + SDLK_QUOTE = 39, + SDLK_LEFTPAREN = 40, + SDLK_RIGHTPAREN = 41, + SDLK_ASTERISK = 42, + SDLK_PLUS = 43, + SDLK_COMMA = 44, + SDLK_MINUS = 45, + SDLK_PERIOD = 46, + SDLK_SLASH = 47, + SDLK_0 = 48, + SDLK_1 = 49, + SDLK_2 = 50, + SDLK_3 = 51, + SDLK_4 = 52, + SDLK_5 = 53, + SDLK_6 = 54, + SDLK_7 = 55, + SDLK_8 = 56, + SDLK_9 = 57, + SDLK_COLON = 58, + SDLK_SEMICOLON = 59, + SDLK_LESS = 60, + SDLK_EQUALS = 61, + SDLK_GREATER = 62, + SDLK_QUESTION = 63, + SDLK_AT = 64, + /* + Skip uppercase letters + */ + SDLK_LEFTBRACKET = 91, + SDLK_BACKSLASH = 92, + SDLK_RIGHTBRACKET = 93, + SDLK_CARET = 94, + SDLK_UNDERSCORE = 95, + SDLK_BACKQUOTE = 96, + SDLK_a = 97, + SDLK_b = 98, + SDLK_c = 99, + SDLK_d = 100, + SDLK_e = 101, + SDLK_f = 102, + SDLK_g = 103, + SDLK_h = 104, + SDLK_i = 105, + SDLK_j = 106, + SDLK_k = 107, + SDLK_l = 108, + SDLK_m = 109, + SDLK_n = 110, + SDLK_o = 111, + SDLK_p = 112, + SDLK_q = 113, + SDLK_r = 114, + SDLK_s = 115, + SDLK_t = 116, + SDLK_u = 117, + SDLK_v = 118, + SDLK_w = 119, + SDLK_x = 120, + SDLK_y = 121, + SDLK_z = 122, + SDLK_DELETE = 127, + /* End of ASCII mapped keysyms */ /*@}*/ - /** @name International keyboard syms */ + /** @name International keyboard syms */ /*@{*/ - SDLK_WORLD_0 = 160, /* 0xA0 */ - SDLK_WORLD_1 = 161, - SDLK_WORLD_2 = 162, - SDLK_WORLD_3 = 163, - SDLK_WORLD_4 = 164, - SDLK_WORLD_5 = 165, - SDLK_WORLD_6 = 166, - SDLK_WORLD_7 = 167, - SDLK_WORLD_8 = 168, - SDLK_WORLD_9 = 169, - SDLK_WORLD_10 = 170, - SDLK_WORLD_11 = 171, - SDLK_WORLD_12 = 172, - SDLK_WORLD_13 = 173, - SDLK_WORLD_14 = 174, - SDLK_WORLD_15 = 175, - SDLK_WORLD_16 = 176, - SDLK_WORLD_17 = 177, - SDLK_WORLD_18 = 178, - SDLK_WORLD_19 = 179, - SDLK_WORLD_20 = 180, - SDLK_WORLD_21 = 181, - SDLK_WORLD_22 = 182, - SDLK_WORLD_23 = 183, - SDLK_WORLD_24 = 184, - SDLK_WORLD_25 = 185, - SDLK_WORLD_26 = 186, - SDLK_WORLD_27 = 187, - SDLK_WORLD_28 = 188, - SDLK_WORLD_29 = 189, - SDLK_WORLD_30 = 190, - SDLK_WORLD_31 = 191, - SDLK_WORLD_32 = 192, - SDLK_WORLD_33 = 193, - SDLK_WORLD_34 = 194, - SDLK_WORLD_35 = 195, - SDLK_WORLD_36 = 196, - SDLK_WORLD_37 = 197, - SDLK_WORLD_38 = 198, - SDLK_WORLD_39 = 199, - SDLK_WORLD_40 = 200, - SDLK_WORLD_41 = 201, - SDLK_WORLD_42 = 202, - SDLK_WORLD_43 = 203, - SDLK_WORLD_44 = 204, - SDLK_WORLD_45 = 205, - SDLK_WORLD_46 = 206, - SDLK_WORLD_47 = 207, - SDLK_WORLD_48 = 208, - SDLK_WORLD_49 = 209, - SDLK_WORLD_50 = 210, - SDLK_WORLD_51 = 211, - SDLK_WORLD_52 = 212, - SDLK_WORLD_53 = 213, - SDLK_WORLD_54 = 214, - SDLK_WORLD_55 = 215, - SDLK_WORLD_56 = 216, - SDLK_WORLD_57 = 217, - SDLK_WORLD_58 = 218, - SDLK_WORLD_59 = 219, - SDLK_WORLD_60 = 220, - SDLK_WORLD_61 = 221, - SDLK_WORLD_62 = 222, - SDLK_WORLD_63 = 223, - SDLK_WORLD_64 = 224, - SDLK_WORLD_65 = 225, - SDLK_WORLD_66 = 226, - SDLK_WORLD_67 = 227, - SDLK_WORLD_68 = 228, - SDLK_WORLD_69 = 229, - SDLK_WORLD_70 = 230, - SDLK_WORLD_71 = 231, - SDLK_WORLD_72 = 232, - SDLK_WORLD_73 = 233, - SDLK_WORLD_74 = 234, - SDLK_WORLD_75 = 235, - SDLK_WORLD_76 = 236, - SDLK_WORLD_77 = 237, - SDLK_WORLD_78 = 238, - SDLK_WORLD_79 = 239, - SDLK_WORLD_80 = 240, - SDLK_WORLD_81 = 241, - SDLK_WORLD_82 = 242, - SDLK_WORLD_83 = 243, - SDLK_WORLD_84 = 244, - SDLK_WORLD_85 = 245, - SDLK_WORLD_86 = 246, - SDLK_WORLD_87 = 247, - SDLK_WORLD_88 = 248, - SDLK_WORLD_89 = 249, - SDLK_WORLD_90 = 250, - SDLK_WORLD_91 = 251, - SDLK_WORLD_92 = 252, - SDLK_WORLD_93 = 253, - SDLK_WORLD_94 = 254, - SDLK_WORLD_95 = 255, /* 0xFF */ + SDLK_WORLD_0 = 160, /* 0xA0 */ + SDLK_WORLD_1 = 161, + SDLK_WORLD_2 = 162, + SDLK_WORLD_3 = 163, + SDLK_WORLD_4 = 164, + SDLK_WORLD_5 = 165, + SDLK_WORLD_6 = 166, + SDLK_WORLD_7 = 167, + SDLK_WORLD_8 = 168, + SDLK_WORLD_9 = 169, + SDLK_WORLD_10 = 170, + SDLK_WORLD_11 = 171, + SDLK_WORLD_12 = 172, + SDLK_WORLD_13 = 173, + SDLK_WORLD_14 = 174, + SDLK_WORLD_15 = 175, + SDLK_WORLD_16 = 176, + SDLK_WORLD_17 = 177, + SDLK_WORLD_18 = 178, + SDLK_WORLD_19 = 179, + SDLK_WORLD_20 = 180, + SDLK_WORLD_21 = 181, + SDLK_WORLD_22 = 182, + SDLK_WORLD_23 = 183, + SDLK_WORLD_24 = 184, + SDLK_WORLD_25 = 185, + SDLK_WORLD_26 = 186, + SDLK_WORLD_27 = 187, + SDLK_WORLD_28 = 188, + SDLK_WORLD_29 = 189, + SDLK_WORLD_30 = 190, + SDLK_WORLD_31 = 191, + SDLK_WORLD_32 = 192, + SDLK_WORLD_33 = 193, + SDLK_WORLD_34 = 194, + SDLK_WORLD_35 = 195, + SDLK_WORLD_36 = 196, + SDLK_WORLD_37 = 197, + SDLK_WORLD_38 = 198, + SDLK_WORLD_39 = 199, + SDLK_WORLD_40 = 200, + SDLK_WORLD_41 = 201, + SDLK_WORLD_42 = 202, + SDLK_WORLD_43 = 203, + SDLK_WORLD_44 = 204, + SDLK_WORLD_45 = 205, + SDLK_WORLD_46 = 206, + SDLK_WORLD_47 = 207, + SDLK_WORLD_48 = 208, + SDLK_WORLD_49 = 209, + SDLK_WORLD_50 = 210, + SDLK_WORLD_51 = 211, + SDLK_WORLD_52 = 212, + SDLK_WORLD_53 = 213, + SDLK_WORLD_54 = 214, + SDLK_WORLD_55 = 215, + SDLK_WORLD_56 = 216, + SDLK_WORLD_57 = 217, + SDLK_WORLD_58 = 218, + SDLK_WORLD_59 = 219, + SDLK_WORLD_60 = 220, + SDLK_WORLD_61 = 221, + SDLK_WORLD_62 = 222, + SDLK_WORLD_63 = 223, + SDLK_WORLD_64 = 224, + SDLK_WORLD_65 = 225, + SDLK_WORLD_66 = 226, + SDLK_WORLD_67 = 227, + SDLK_WORLD_68 = 228, + SDLK_WORLD_69 = 229, + SDLK_WORLD_70 = 230, + SDLK_WORLD_71 = 231, + SDLK_WORLD_72 = 232, + SDLK_WORLD_73 = 233, + SDLK_WORLD_74 = 234, + SDLK_WORLD_75 = 235, + SDLK_WORLD_76 = 236, + SDLK_WORLD_77 = 237, + SDLK_WORLD_78 = 238, + SDLK_WORLD_79 = 239, + SDLK_WORLD_80 = 240, + SDLK_WORLD_81 = 241, + SDLK_WORLD_82 = 242, + SDLK_WORLD_83 = 243, + SDLK_WORLD_84 = 244, + SDLK_WORLD_85 = 245, + SDLK_WORLD_86 = 246, + SDLK_WORLD_87 = 247, + SDLK_WORLD_88 = 248, + SDLK_WORLD_89 = 249, + SDLK_WORLD_90 = 250, + SDLK_WORLD_91 = 251, + SDLK_WORLD_92 = 252, + SDLK_WORLD_93 = 253, + SDLK_WORLD_94 = 254, + SDLK_WORLD_95 = 255, /* 0xFF */ /*@}*/ - /** @name Numeric keypad */ + /** @name Numeric keypad */ /*@{*/ - SDLK_KP0 = 256, - SDLK_KP1 = 257, - SDLK_KP2 = 258, - SDLK_KP3 = 259, - SDLK_KP4 = 260, - SDLK_KP5 = 261, - SDLK_KP6 = 262, - SDLK_KP7 = 263, - SDLK_KP8 = 264, - SDLK_KP9 = 265, - SDLK_KP_PERIOD = 266, - SDLK_KP_DIVIDE = 267, - SDLK_KP_MULTIPLY = 268, - SDLK_KP_MINUS = 269, - SDLK_KP_PLUS = 270, - SDLK_KP_ENTER = 271, - SDLK_KP_EQUALS = 272, + SDLK_KP0 = 256, + SDLK_KP1 = 257, + SDLK_KP2 = 258, + SDLK_KP3 = 259, + SDLK_KP4 = 260, + SDLK_KP5 = 261, + SDLK_KP6 = 262, + SDLK_KP7 = 263, + SDLK_KP8 = 264, + SDLK_KP9 = 265, + SDLK_KP_PERIOD = 266, + SDLK_KP_DIVIDE = 267, + SDLK_KP_MULTIPLY = 268, + SDLK_KP_MINUS = 269, + SDLK_KP_PLUS = 270, + SDLK_KP_ENTER = 271, + SDLK_KP_EQUALS = 272, /*@}*/ - /** @name Arrows + Home/End pad */ + /** @name Arrows + Home/End pad */ /*@{*/ - SDLK_UP = 273, - SDLK_DOWN = 274, - SDLK_RIGHT = 275, - SDLK_LEFT = 276, - SDLK_INSERT = 277, - SDLK_HOME = 278, - SDLK_END = 279, - SDLK_PAGEUP = 280, - SDLK_PAGEDOWN = 281, + SDLK_UP = 273, + SDLK_DOWN = 274, + SDLK_RIGHT = 275, + SDLK_LEFT = 276, + SDLK_INSERT = 277, + SDLK_HOME = 278, + SDLK_END = 279, + SDLK_PAGEUP = 280, + SDLK_PAGEDOWN = 281, /*@}*/ - /** @name Function keys */ + /** @name Function keys */ /*@{*/ - SDLK_F1 = 282, - SDLK_F2 = 283, - SDLK_F3 = 284, - SDLK_F4 = 285, - SDLK_F5 = 286, - SDLK_F6 = 287, - SDLK_F7 = 288, - SDLK_F8 = 289, - SDLK_F9 = 290, - SDLK_F10 = 291, - SDLK_F11 = 292, - SDLK_F12 = 293, - SDLK_F13 = 294, - SDLK_F14 = 295, - SDLK_F15 = 296, + SDLK_F1 = 282, + SDLK_F2 = 283, + SDLK_F3 = 284, + SDLK_F4 = 285, + SDLK_F5 = 286, + SDLK_F6 = 287, + SDLK_F7 = 288, + SDLK_F8 = 289, + SDLK_F9 = 290, + SDLK_F10 = 291, + SDLK_F11 = 292, + SDLK_F12 = 293, + SDLK_F13 = 294, + SDLK_F14 = 295, + SDLK_F15 = 296, /*@}*/ - /** @name Key state modifier keys */ + /** @name Key state modifier keys */ /*@{*/ - SDLK_NUMLOCK = 300, - SDLK_CAPSLOCK = 301, - SDLK_SCROLLOCK = 302, - SDLK_RSHIFT = 303, - SDLK_LSHIFT = 304, - SDLK_RCTRL = 305, - SDLK_LCTRL = 306, - SDLK_RALT = 307, - SDLK_LALT = 308, - SDLK_RMETA = 309, - SDLK_LMETA = 310, - SDLK_LSUPER = 311, /**< Left "Windows" key */ - SDLK_RSUPER = 312, /**< Right "Windows" key */ - SDLK_MODE = 313, /**< "Alt Gr" key */ - SDLK_COMPOSE = 314, /**< Multi-key compose key */ + SDLK_NUMLOCK = 300, + SDLK_CAPSLOCK = 301, + SDLK_SCROLLOCK = 302, + SDLK_RSHIFT = 303, + SDLK_LSHIFT = 304, + SDLK_RCTRL = 305, + SDLK_LCTRL = 306, + SDLK_RALT = 307, + SDLK_LALT = 308, + SDLK_RMETA = 309, + SDLK_LMETA = 310, + SDLK_LSUPER = 311, /**< Left "Windows" key */ + SDLK_RSUPER = 312, /**< Right "Windows" key */ + SDLK_MODE = 313, /**< "Alt Gr" key */ + SDLK_COMPOSE = 314, /**< Multi-key compose key */ /*@}*/ - /** @name Miscellaneous function keys */ + /** @name Miscellaneous function keys */ /*@{*/ - SDLK_HELP = 315, - SDLK_PRINT = 316, - SDLK_SYSREQ = 317, - SDLK_BREAK = 318, - SDLK_MENU = 319, - SDLK_POWER = 320, /**< Power Macintosh power key */ - SDLK_EURO = 321, /**< Some european keyboards */ - SDLK_UNDO = 322, /**< Atari keyboard has Undo */ + SDLK_HELP = 315, + SDLK_PRINT = 316, + SDLK_SYSREQ = 317, + SDLK_BREAK = 318, + SDLK_MENU = 319, + SDLK_POWER = 320, /**< Power Macintosh power key */ + SDLK_EURO = 321, /**< Some european keyboards */ + SDLK_UNDO = 322, /**< Atari keyboard has Undo */ /*@}*/ - /* Add any other keys here */ + /* Add any other keys here */ - SDLK_LAST + SDLK_LAST } SDLKey; /** Enumeration of valid key mods (possibly OR'd together) */ typedef enum { - KMOD_NONE = 0x0000, - KMOD_LSHIFT= 0x0001, - KMOD_RSHIFT= 0x0002, - KMOD_LCTRL = 0x0040, - KMOD_RCTRL = 0x0080, - KMOD_LALT = 0x0100, - KMOD_RALT = 0x0200, - KMOD_LMETA = 0x0400, - KMOD_RMETA = 0x0800, - KMOD_NUM = 0x1000, - KMOD_CAPS = 0x2000, - KMOD_MODE = 0x4000, - KMOD_RESERVED = 0x8000 + KMOD_NONE = 0x0000, + KMOD_LSHIFT= 0x0001, + KMOD_RSHIFT= 0x0002, + KMOD_LCTRL = 0x0040, + KMOD_RCTRL = 0x0080, + KMOD_LALT = 0x0100, + KMOD_RALT = 0x0200, + KMOD_LMETA = 0x0400, + KMOD_RMETA = 0x0800, + KMOD_NUM = 0x1000, + KMOD_CAPS = 0x2000, + KMOD_MODE = 0x4000, + KMOD_RESERVED = 0x8000 } SDLMod; -#define KMOD_CTRL (KMOD_LCTRL|KMOD_RCTRL) -#define KMOD_SHIFT (KMOD_LSHIFT|KMOD_RSHIFT) -#define KMOD_ALT (KMOD_LALT|KMOD_RALT) -#define KMOD_META (KMOD_LMETA|KMOD_RMETA) +#define KMOD_CTRL (KMOD_LCTRL|KMOD_RCTRL) +#define KMOD_SHIFT (KMOD_LSHIFT|KMOD_RSHIFT) +#define KMOD_ALT (KMOD_LALT|KMOD_RALT) +#define KMOD_META (KMOD_LMETA|KMOD_RMETA) #endif /* _SDL_keysym_h */ diff -r 4feced261c68 -r de822cd3df3a misc/winutils/include/SDL_loadso.h --- a/misc/winutils/include/SDL_loadso.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/winutils/include/SDL_loadso.h Tue Jan 21 22:43:06 2014 +0100 @@ -25,7 +25,7 @@ */ /** @file SDL_loadso.h - * Some things to keep in mind: + * Some things to keep in mind: * - These functions only work on C function names. Other languages may * have name mangling and intrinsic language support that varies from * compiler to compiler. diff -r 4feced261c68 -r de822cd3df3a misc/winutils/include/SDL_main.h --- a/misc/winutils/include/SDL_main.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/winutils/include/SDL_main.h Tue Jan 21 22:43:06 2014 +0100 @@ -35,7 +35,7 @@ defined(__SYMBIAN32__) || defined(QWS) #ifdef __cplusplus -#define C_LINKAGE "C" +#define C_LINKAGE "C" #else #define C_LINKAGE #endif /* __cplusplus */ @@ -46,12 +46,12 @@ * #ifdef __cplusplus * extern "C" * #endif - * int main(int argc, char *argv[]) - * { - * } + * int main(int argc, char *argv[]) + * { + * } * @endcode */ -#define main SDL_main +#define main SDL_main /** The prototype for the application's main() function */ extern C_LINKAGE int SDL_main(int argc, char *argv[]); diff -r 4feced261c68 -r de822cd3df3a misc/winutils/include/SDL_mixer.h --- a/misc/winutils/include/SDL_mixer.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/winutils/include/SDL_mixer.h Tue Jan 21 22:43:06 2014 +0100 @@ -38,25 +38,25 @@ /* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL */ -#define SDL_MIXER_MAJOR_VERSION 1 -#define SDL_MIXER_MINOR_VERSION 2 +#define SDL_MIXER_MAJOR_VERSION 1 +#define SDL_MIXER_MINOR_VERSION 2 #define SDL_MIXER_PATCHLEVEL 12 /* This macro can be used to fill a version structure with the compile-time * version of the SDL_mixer library. */ -#define SDL_MIXER_VERSION(X) \ -{ \ - (X)->major = SDL_MIXER_MAJOR_VERSION; \ - (X)->minor = SDL_MIXER_MINOR_VERSION; \ - (X)->patch = SDL_MIXER_PATCHLEVEL; \ +#define SDL_MIXER_VERSION(X) \ +{ \ + (X)->major = SDL_MIXER_MAJOR_VERSION; \ + (X)->minor = SDL_MIXER_MINOR_VERSION; \ + (X)->patch = SDL_MIXER_PATCHLEVEL; \ } /* Backwards compatibility */ -#define MIX_MAJOR_VERSION SDL_MIXER_MAJOR_VERSION -#define MIX_MINOR_VERSION SDL_MIXER_MINOR_VERSION -#define MIX_PATCHLEVEL SDL_MIXER_PATCHLEVEL -#define MIX_VERSION(X) SDL_MIXER_VERSION(X) +#define MIX_MAJOR_VERSION SDL_MIXER_MAJOR_VERSION +#define MIX_MINOR_VERSION SDL_MIXER_MINOR_VERSION +#define MIX_PATCHLEVEL SDL_MIXER_PATCHLEVEL +#define MIX_VERSION(X) SDL_MIXER_VERSION(X) /* This function gets the version of the dynamically linked SDL_mixer library. it should NOT be used to fill a version structure, instead you should @@ -85,45 +85,45 @@ /* The default mixer has 8 simultaneous mixing channels */ #ifndef MIX_CHANNELS -#define MIX_CHANNELS 8 +#define MIX_CHANNELS 8 #endif /* Good default values for a PC soundcard */ -#define MIX_DEFAULT_FREQUENCY 22050 +#define MIX_DEFAULT_FREQUENCY 22050 #if SDL_BYTEORDER == SDL_LIL_ENDIAN -#define MIX_DEFAULT_FORMAT AUDIO_S16LSB +#define MIX_DEFAULT_FORMAT AUDIO_S16LSB #else -#define MIX_DEFAULT_FORMAT AUDIO_S16MSB +#define MIX_DEFAULT_FORMAT AUDIO_S16MSB #endif -#define MIX_DEFAULT_CHANNELS 2 -#define MIX_MAX_VOLUME 128 /* Volume of a chunk */ +#define MIX_DEFAULT_CHANNELS 2 +#define MIX_MAX_VOLUME 128 /* Volume of a chunk */ /* The internal format for an audio chunk */ typedef struct Mix_Chunk { - int allocated; - Uint8 *abuf; - Uint32 alen; - Uint8 volume; /* Per-sample volume, 0-128 */ + int allocated; + Uint8 *abuf; + Uint32 alen; + Uint8 volume; /* Per-sample volume, 0-128 */ } Mix_Chunk; /* The different fading types supported */ typedef enum { - MIX_NO_FADING, - MIX_FADING_OUT, - MIX_FADING_IN + MIX_NO_FADING, + MIX_FADING_OUT, + MIX_FADING_IN } Mix_Fading; typedef enum { - MUS_NONE, - MUS_CMD, - MUS_WAV, - MUS_MOD, - MUS_MID, - MUS_OGG, - MUS_MP3, - MUS_MP3_MAD, - MUS_FLAC, - MUS_MODPLUG + MUS_NONE, + MUS_CMD, + MUS_WAV, + MUS_MOD, + MUS_MID, + MUS_OGG, + MUS_MP3, + MUS_MP3_MAD, + MUS_FLAC, + MUS_MODPLUG } Mix_MusicType; /* The internal format for a music chunk interpreted via mikmod */ @@ -131,7 +131,7 @@ /* Open the mixer with a certain audio format */ extern DECLSPEC int SDLCALL Mix_OpenAudio(int frequency, Uint16 format, int channels, - int chunksize); + int chunksize); /* Dynamically change the number of channels managed by the mixer. If decreasing the number of channels, the upper channels are @@ -147,7 +147,7 @@ /* Load a wave file or a music (.mod .s3m .it .xm) file */ extern DECLSPEC Mix_Chunk * SDLCALL Mix_LoadWAV_RW(SDL_RWops *src, int freesrc); -#define Mix_LoadWAV(file) Mix_LoadWAV_RW(SDL_RWFromFile(file, "rb"), 1) +#define Mix_LoadWAV(file) Mix_LoadWAV_RW(SDL_RWFromFile(file, "rb"), 1) extern DECLSPEC Mix_Music * SDLCALL Mix_LoadMUS(const char *file); /* Load a music file from an SDL_RWop object (Ogg and MikMod specific currently) @@ -219,9 +219,9 @@ /* * Add your own callback when a channel has finished playing. NULL - * to disable callback. The callback may be called from the mixer's audio + * to disable callback. The callback may be called from the mixer's audio * callback or it could be called as a result of Mix_HaltChannel(), etc. - * do not call SDL_LockAudio() from this callback; you will either be + * do not call SDL_LockAudio() from this callback; you will either be * inside the audio callback, or SDL_mixer will explicitly lock the audio * before calling your callback. */ @@ -302,7 +302,7 @@ * * After all these effects have finished processing, the callback registered * through Mix_SetPostMix() runs, and then the stream goes to the audio - * device. + * device. * * DO NOT EVER call SDL_LockAudio() from your callback function! * @@ -310,7 +310,7 @@ * Error messages can be retrieved from Mix_GetError(). */ extern DECLSPEC int SDLCALL Mix_RegisterEffect(int chan, Mix_EffectFunc_t f, - Mix_EffectDone_t d, void *arg); + Mix_EffectDone_t d, void *arg); /* You may not need to call this explicitly, unless you need to stop an @@ -590,7 +590,7 @@ /* Set the current position in the music stream. This returns 0 if successful, or -1 if it failed or isn't implemented. This function is only implemented for MOD music formats (set pattern - order number) and for OGG, FLAC, MP3_MAD, and MODPLUG music (set + order number) and for OGG, FLAC, MP3_MAD, and MODPLUG music (set position in seconds), at the moment. */ extern DECLSPEC int SDLCALL Mix_SetMusicPosition(double position); @@ -622,8 +622,8 @@ extern DECLSPEC void SDLCALL Mix_CloseAudio(void); /* We'll use SDL for reporting errors */ -#define Mix_SetError SDL_SetError -#define Mix_GetError SDL_GetError +#define Mix_SetError SDL_SetError +#define Mix_GetError SDL_GetError /* Ends C function definitions when using C++ */ #ifdef __cplusplus diff -r 4feced261c68 -r de822cd3df3a misc/winutils/include/SDL_mouse.h --- a/misc/winutils/include/SDL_mouse.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/winutils/include/SDL_mouse.h Tue Jan 21 22:43:06 2014 +0100 @@ -37,14 +37,14 @@ extern "C" { #endif -typedef struct WMcursor WMcursor; /**< Implementation dependent */ +typedef struct WMcursor WMcursor; /**< Implementation dependent */ typedef struct SDL_Cursor { - SDL_Rect area; /**< The area of the mouse cursor */ - Sint16 hot_x, hot_y; /**< The "tip" of the cursor */ - Uint8 *data; /**< B/W cursor data */ - Uint8 *mask; /**< B/W cursor mask */ - Uint8 *save[2]; /**< Place to save cursor area */ - WMcursor *wm_cursor; /**< Window-manager cursor */ + SDL_Rect area; /**< The area of the mouse cursor */ + Sint16 hot_x, hot_y; /**< The "tip" of the cursor */ + Uint8 *data; /**< B/W cursor data */ + Uint8 *mask; /**< B/W cursor mask */ + Uint8 *save[2]; /**< Place to save cursor area */ + WMcursor *wm_cursor; /**< Window-manager cursor */ } SDL_Cursor; /* Function prototypes */ @@ -83,11 +83,11 @@ * Cursors created with this function must be freed with SDL_FreeCursor(). */ extern DECLSPEC SDL_Cursor * SDLCALL SDL_CreateCursor - (Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y); + (Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y); /** * Set the currently active cursor to the specified one. - * If the cursor is currently visible, the change will be immediately + * If the cursor is currently visible, the change will be immediately * represented on the display. */ extern DECLSPEC void SDLCALL SDL_SetCursor(SDL_Cursor *cursor); @@ -113,25 +113,25 @@ /*@{*/ /** Used as a mask when testing buttons in buttonstate - * Button 1: Left mouse button - * Button 2: Middle mouse button - * Button 3: Right mouse button - * Button 4: Mouse wheel up (may also be a real button) - * Button 5: Mouse wheel down (may also be a real button) + * Button 1: Left mouse button + * Button 2: Middle mouse button + * Button 3: Right mouse button + * Button 4: Mouse wheel up (may also be a real button) + * Button 5: Mouse wheel down (may also be a real button) */ -#define SDL_BUTTON(X) (1 << ((X)-1)) -#define SDL_BUTTON_LEFT 1 -#define SDL_BUTTON_MIDDLE 2 -#define SDL_BUTTON_RIGHT 3 -#define SDL_BUTTON_WHEELUP 4 -#define SDL_BUTTON_WHEELDOWN 5 -#define SDL_BUTTON_X1 6 -#define SDL_BUTTON_X2 7 -#define SDL_BUTTON_LMASK SDL_BUTTON(SDL_BUTTON_LEFT) -#define SDL_BUTTON_MMASK SDL_BUTTON(SDL_BUTTON_MIDDLE) -#define SDL_BUTTON_RMASK SDL_BUTTON(SDL_BUTTON_RIGHT) -#define SDL_BUTTON_X1MASK SDL_BUTTON(SDL_BUTTON_X1) -#define SDL_BUTTON_X2MASK SDL_BUTTON(SDL_BUTTON_X2) +#define SDL_BUTTON(X) (1 << ((X)-1)) +#define SDL_BUTTON_LEFT 1 +#define SDL_BUTTON_MIDDLE 2 +#define SDL_BUTTON_RIGHT 3 +#define SDL_BUTTON_WHEELUP 4 +#define SDL_BUTTON_WHEELDOWN 5 +#define SDL_BUTTON_X1 6 +#define SDL_BUTTON_X2 7 +#define SDL_BUTTON_LMASK SDL_BUTTON(SDL_BUTTON_LEFT) +#define SDL_BUTTON_MMASK SDL_BUTTON(SDL_BUTTON_MIDDLE) +#define SDL_BUTTON_RMASK SDL_BUTTON(SDL_BUTTON_RIGHT) +#define SDL_BUTTON_X1MASK SDL_BUTTON(SDL_BUTTON_X1) +#define SDL_BUTTON_X2MASK SDL_BUTTON(SDL_BUTTON_X2) /*@}*/ /* Ends C function definitions when using C++ */ diff -r 4feced261c68 -r de822cd3df3a misc/winutils/include/SDL_mutex.h --- a/misc/winutils/include/SDL_mutex.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/winutils/include/SDL_mutex.h Tue Jan 21 22:43:06 2014 +0100 @@ -41,10 +41,10 @@ /** Synchronization functions which can time out return this value * if they time out. */ -#define SDL_MUTEX_TIMEDOUT 1 +#define SDL_MUTEX_TIMEDOUT 1 /** This is the timeout value which corresponds to never time out */ -#define SDL_MUTEX_MAXWAIT (~(Uint32)0) +#define SDL_MUTEX_MAXWAIT (~(Uint32)0) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ @@ -58,13 +58,13 @@ /** Create a mutex, initialized unlocked */ extern DECLSPEC SDL_mutex * SDLCALL SDL_CreateMutex(void); -#define SDL_LockMutex(m) SDL_mutexP(m) +#define SDL_LockMutex(m) SDL_mutexP(m) /** Lock the mutex * @return 0, or -1 on error */ extern DECLSPEC int SDLCALL SDL_mutexP(SDL_mutex *mutex); -#define SDL_UnlockMutex(m) SDL_mutexV(m) +#define SDL_UnlockMutex(m) SDL_mutexV(m) /** Unlock the mutex * @return 0, or -1 on error * @@ -93,7 +93,7 @@ extern DECLSPEC void SDLCALL SDL_DestroySemaphore(SDL_sem *sem); /** - * This function suspends the calling thread until the semaphore pointed + * This function suspends the calling thread until the semaphore pointed * to by sem has a positive count. It then atomically decreases the semaphore * count. */ diff -r 4feced261c68 -r de822cd3df3a misc/winutils/include/SDL_name.h --- a/misc/winutils/include/SDL_name.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/winutils/include/SDL_name.h Tue Jan 21 22:43:06 2014 +0100 @@ -6,6 +6,6 @@ #define NeedFunctionPrototypes 1 #endif -#define SDL_NAME(X) SDL_##X +#define SDL_NAME(X) SDL_##X #endif /* _SDLname_h_ */ diff -r 4feced261c68 -r de822cd3df3a misc/winutils/include/SDL_net.h --- a/misc/winutils/include/SDL_net.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/winutils/include/SDL_net.h Tue Jan 21 22:43:06 2014 +0100 @@ -38,18 +38,18 @@ /* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL */ -#define SDL_NET_MAJOR_VERSION 1 -#define SDL_NET_MINOR_VERSION 2 -#define SDL_NET_PATCHLEVEL 8 +#define SDL_NET_MAJOR_VERSION 1 +#define SDL_NET_MINOR_VERSION 2 +#define SDL_NET_PATCHLEVEL 8 /* This macro can be used to fill a version structure with the compile-time * version of the SDL_net library. */ -#define SDL_NET_VERSION(X) \ -{ \ - (X)->major = SDL_NET_MAJOR_VERSION; \ - (X)->minor = SDL_NET_MINOR_VERSION; \ - (X)->patch = SDL_NET_PATCHLEVEL; \ +#define SDL_NET_VERSION(X) \ +{ \ + (X)->major = SDL_NET_MAJOR_VERSION; \ + (X)->minor = SDL_NET_MINOR_VERSION; \ + (X)->patch = SDL_NET_PATCHLEVEL; \ } /* This function gets the version of the dynamically linked SDL_net library. @@ -70,8 +70,8 @@ /***********************************************************************/ typedef struct { - Uint32 host; /* 32-bit IPv4 host address */ - Uint16 port; /* 16-bit protocol port */ + Uint32 host; /* 32-bit IPv4 host address */ + Uint16 port; /* 16-bit protocol port */ } IPaddress; /* Resolve a host name and port to an IP address in network form. @@ -81,13 +81,13 @@ If 'host' is NULL, the resolved host will be set to INADDR_ANY. */ #ifndef INADDR_ANY -#define INADDR_ANY 0x00000000 +#define INADDR_ANY 0x00000000 #endif #ifndef INADDR_NONE -#define INADDR_NONE 0xFFFFFFFF +#define INADDR_NONE 0xFFFFFFFF #endif #ifndef INADDR_BROADCAST -#define INADDR_BROADCAST 0xFFFFFFFF +#define INADDR_BROADCAST 0xFFFFFFFF #endif extern DECLSPEC int SDLCALL SDLNet_ResolveHost(IPaddress *address, const char *host, Uint16 port); @@ -113,7 +113,7 @@ If ip.host is INADDR_NONE or INADDR_ANY, this creates a local server socket on the given port, otherwise a TCP connection to the remote host and port is attempted. The address passed in should already be - swapped to network byte order (addresses returned from + swapped to network byte order (addresses returned from SDLNet_ResolveHost() are already in the correct form). The newly created socket is returned, or NULL if there was an error. */ @@ -135,7 +135,7 @@ closed, or an unknown socket error occurred. */ extern DECLSPEC int SDLCALL SDLNet_TCP_Send(TCPsocket sock, const void *data, - int len); + int len); /* Receive up to 'maxlen' bytes of data over the non-server socket 'sock', and store them in the buffer pointed to by 'data'. @@ -154,18 +154,18 @@ /***********************************************************************/ /* The maximum channels on a a UDP socket */ -#define SDLNET_MAX_UDPCHANNELS 32 +#define SDLNET_MAX_UDPCHANNELS 32 /* The maximum addresses bound to a single UDP socket channel */ -#define SDLNET_MAX_UDPADDRESSES 4 +#define SDLNET_MAX_UDPADDRESSES 4 typedef struct _UDPsocket *UDPsocket; typedef struct { - int channel; /* The src/dst channel of the packet */ - Uint8 *data; /* The packet data */ - int len; /* The length of the packet data */ - int maxlen; /* The size of the data buffer */ - int status; /* packet status after sending */ - IPaddress address; /* The source/dest address of an incoming/outgoing packet */ + int channel; /* The src/dst channel of the packet */ + Uint8 *data; /* The packet data */ + int len; /* The length of the packet data */ + int maxlen; /* The size of the data buffer */ + int status; /* packet status after sending */ + IPaddress address; /* The source/dest address of an incoming/outgoing packet */ } UDPpacket; /* Allocate/resize/free a single UDP packet 'size' bytes long. @@ -210,7 +210,7 @@ /* Unbind all addresses from the given channel */ extern DECLSPEC void SDLCALL SDLNet_UDP_Unbind(UDPsocket sock, int channel); -/* Get the primary IP address of the remote system associated with the +/* Get the primary IP address of the remote system associated with the socket and channel. If the channel is -1, then the primary IP port of the UDP socket is returned -- this is only meaningful for sockets opened with a specific port. @@ -221,7 +221,7 @@ /* Send a vector of packets to the the channels specified within the packet. If the channel specified in the packet is -1, the packet will be sent to the address in the 'src' member of the packet. - Each packet will be updated with the status of the packet after it has + Each packet will be updated with the status of the packet after it has been sent, -1 if the packet send failed. This function returns the number of packets sent. */ @@ -277,7 +277,7 @@ /* Any network socket can be safely cast to this socket type */ typedef struct _SDLNet_GenericSocket { - int ready; + int ready; } *SDLNet_GenericSocket; /* Allocate a socket set for use with SDLNet_CheckSockets() @@ -288,23 +288,23 @@ /* Add a socket to a set of sockets to be checked for available data */ #define SDLNet_TCP_AddSocket(set, sock) \ - SDLNet_AddSocket(set, SDL_reinterpret_cast(SDLNet_GenericSocket, sock)) + SDLNet_AddSocket(set, SDL_reinterpret_cast(SDLNet_GenericSocket, sock)) #define SDLNet_UDP_AddSocket(set, sock) \ - SDLNet_AddSocket(set, SDL_reinterpret_cast(SDLNet_GenericSocket, sock)) + SDLNet_AddSocket(set, SDL_reinterpret_cast(SDLNet_GenericSocket, sock)) extern DECLSPEC int SDLCALL SDLNet_AddSocket(SDLNet_SocketSet set, SDLNet_GenericSocket sock); /* Remove a socket from a set of sockets to be checked for available data */ #define SDLNet_TCP_DelSocket(set, sock) \ - SDLNet_DelSocket(set, SDL_reinterpret_cast(SDLNet_GenericSocket, sock)) + SDLNet_DelSocket(set, SDL_reinterpret_cast(SDLNet_GenericSocket, sock)) #define SDLNet_UDP_DelSocket(set, sock) \ - SDLNet_DelSocket(set, SDL_reinterpret_cast(SDLNet_GenericSocket, sock)) + SDLNet_DelSocket(set, SDL_reinterpret_cast(SDLNet_GenericSocket, sock)) extern DECLSPEC int SDLCALL SDLNet_DelSocket(SDLNet_SocketSet set, SDLNet_GenericSocket sock); /* This function checks to see if data is available for reading on the given set of sockets. If 'timeout' is 0, it performs a quick poll, otherwise the function returns when either data is available for reading, or the timeout in milliseconds has elapsed, which ever occurs - first. This function returns the number of sockets ready for reading, + first. This function returns the number of sockets ready for reading, or -1 if there was an error with the select() system call. */ extern DECLSPEC int SDLCALL SDLNet_CheckSockets(SDLNet_SocketSet set, Uint32 timeout); @@ -314,7 +314,7 @@ for reading. */ #define SDLNet_SocketReady(sock) \ - ((sock != NULL) && SDL_reinterpret_cast(SDLNet_GenericSocket, sock)->ready) + ((sock != NULL) && SDL_reinterpret_cast(SDLNet_GenericSocket, sock)->ready) /* Free a set of sockets allocated by SDL_NetAllocSocketSet() */ extern DECLSPEC void SDLCALL SDLNet_FreeSocketSet(SDLNet_SocketSet set); @@ -337,8 +337,8 @@ /***********************************************************************/ /* We'll use SDL's functions for error reporting */ -#define SDLNet_SetError SDL_SetError -#define SDLNet_GetError SDL_GetError +#define SDLNet_SetError SDL_SetError +#define SDLNet_GetError SDL_GetError /* I'm eventually going to try to disentangle SDL_net from SDL, thus making SDL_net an independent X-platform networking toolkit. Not today though.... @@ -352,91 +352,91 @@ /* Warning, some systems have data access alignment restrictions */ #if defined(sparc) || defined(mips) -#define SDL_DATA_ALIGNED 1 +#define SDL_DATA_ALIGNED 1 #endif #ifndef SDL_DATA_ALIGNED -#define SDL_DATA_ALIGNED 0 +#define SDL_DATA_ALIGNED 0 #endif /* Write a 16 bit value to network packet buffer */ #if !SDL_DATA_ALIGNED -#define SDLNet_Write16(value, areap) \ - (*SDL_reinterpret_cast(Uint16 *, areap) = SDL_SwapBE16(value)) +#define SDLNet_Write16(value, areap) \ + (*SDL_reinterpret_cast(Uint16 *, areap) = SDL_SwapBE16(value)) #else #if SDL_BYTEORDER == SDL_BIG_ENDIAN -#define SDLNet_Write16(value, areap) \ -do \ -{ \ - Uint8 *area = SDL_reinterpret_cast(Uint8 *, areap); \ - area[0] = (value >> 8) & 0xFF; \ - area[1] = value & 0xFF; \ +#define SDLNet_Write16(value, areap) \ +do \ +{ \ + Uint8 *area = SDL_reinterpret_cast(Uint8 *, areap); \ + area[0] = (value >> 8) & 0xFF; \ + area[1] = value & 0xFF; \ } while ( 0 ) #else -#define SDLNet_Write16(value, areap) \ -do \ -{ \ - Uint8 *area = SDL_reinterpret_cast(Uint8 *, areap); \ - area[1] = (value >> 8) & 0xFF; \ - area[0] = value & 0xFF; \ +#define SDLNet_Write16(value, areap) \ +do \ +{ \ + Uint8 *area = SDL_reinterpret_cast(Uint8 *, areap); \ + area[1] = (value >> 8) & 0xFF; \ + area[0] = value & 0xFF; \ } while ( 0 ) #endif #endif /* !SDL_DATA_ALIGNED */ /* Write a 32 bit value to network packet buffer */ #if !SDL_DATA_ALIGNED -#define SDLNet_Write32(value, areap) \ - *SDL_reinterpret_cast(Uint32 *, areap) = SDL_SwapBE32(value); +#define SDLNet_Write32(value, areap) \ + *SDL_reinterpret_cast(Uint32 *, areap) = SDL_SwapBE32(value); #else #if SDL_BYTEORDER == SDL_BIG_ENDIAN -#define SDLNet_Write32(value, areap) \ -do \ -{ \ - Uint8 *area = SDL_reinterpret_cast(Uint8 *, areap); \ - area[0] = (value >> 24) & 0xFF; \ - area[1] = (value >> 16) & 0xFF; \ - area[2] = (value >> 8) & 0xFF; \ - area[3] = value & 0xFF; \ +#define SDLNet_Write32(value, areap) \ +do \ +{ \ + Uint8 *area = SDL_reinterpret_cast(Uint8 *, areap); \ + area[0] = (value >> 24) & 0xFF; \ + area[1] = (value >> 16) & 0xFF; \ + area[2] = (value >> 8) & 0xFF; \ + area[3] = value & 0xFF; \ } while ( 0 ) #else -#define SDLNet_Write32(value, areap) \ -do \ -{ \ - Uint8 *area = SDL_reinterpret_cast(Uint8 *, areap); \ - area[3] = (value >> 24) & 0xFF; \ - area[2] = (value >> 16) & 0xFF; \ - area[1] = (value >> 8) & 0xFF; \ - area[0] = value & 0xFF; \ +#define SDLNet_Write32(value, areap) \ +do \ +{ \ + Uint8 *area = SDL_reinterpret_cast(Uint8 *, areap); \ + area[3] = (value >> 24) & 0xFF; \ + area[2] = (value >> 16) & 0xFF; \ + area[1] = (value >> 8) & 0xFF; \ + area[0] = value & 0xFF; \ } while ( 0 ) #endif #endif /* !SDL_DATA_ALIGNED */ /* Read a 16 bit value from network packet buffer */ #if !SDL_DATA_ALIGNED -#define SDLNet_Read16(areap) \ - (SDL_SwapBE16(*SDL_reinterpret_cast(Uint16 *, areap))) +#define SDLNet_Read16(areap) \ + (SDL_SwapBE16(*SDL_reinterpret_cast(Uint16 *, areap))) #else #if SDL_BYTEORDER == SDL_BIG_ENDIAN -#define SDLNet_Read16(areap) \ - (((SDL_reinterpret_cast(Uint8 *, areap))[0] << 8) | (SDL_reinterpret_cast(Uint8 *, areap))[1] << 0) +#define SDLNet_Read16(areap) \ + (((SDL_reinterpret_cast(Uint8 *, areap))[0] << 8) | (SDL_reinterpret_cast(Uint8 *, areap))[1] << 0) #else -#define SDLNet_Read16(areap) \ - (((SDL_reinterpret_cast(Uint8 *, areap))[1] << 8) | (SDL_reinterpret_cast(Uint8 *, areap))[0] << 0) +#define SDLNet_Read16(areap) \ + (((SDL_reinterpret_cast(Uint8 *, areap))[1] << 8) | (SDL_reinterpret_cast(Uint8 *, areap))[0] << 0) #endif #endif /* !SDL_DATA_ALIGNED */ /* Read a 32 bit value from network packet buffer */ #if !SDL_DATA_ALIGNED -#define SDLNet_Read32(areap) \ - (SDL_SwapBE32(*SDL_reinterpret_cast(Uint32 *, areap))) +#define SDLNet_Read32(areap) \ + (SDL_SwapBE32(*SDL_reinterpret_cast(Uint32 *, areap))) #else #if SDL_BYTEORDER == SDL_BIG_ENDIAN -#define SDLNet_Read32(areap) \ - (((SDL_reinterpret_cast(Uint8 *, areap))[0] << 24) | ((SDL_reinterpret_cast(Uint8 *, areap))[1] << 16) | \ - ((SDL_reinterpret_cast(Uint8 *, areap))[2] << 8) | (SDL_reinterpret_cast(Uint8 *, areap))[3] << 0) +#define SDLNet_Read32(areap) \ + (((SDL_reinterpret_cast(Uint8 *, areap))[0] << 24) | ((SDL_reinterpret_cast(Uint8 *, areap))[1] << 16) | \ + ((SDL_reinterpret_cast(Uint8 *, areap))[2] << 8) | (SDL_reinterpret_cast(Uint8 *, areap))[3] << 0) #else -#define SDLNet_Read32(areap) \ - (((SDL_reinterpret_cast(Uint8 *, areap))[3] << 24) | ((SDL_reinterpret_cast(Uint8 *, areap))[2] << 16) | \ - ((SDL_reinterpret_cast(Uint8 *, areap))[1] << 8) | (SDL_reinterpret_cast(Uint8 *, areap))[0] << 0) +#define SDLNet_Read32(areap) \ + (((SDL_reinterpret_cast(Uint8 *, areap))[3] << 24) | ((SDL_reinterpret_cast(Uint8 *, areap))[2] << 16) | \ + ((SDL_reinterpret_cast(Uint8 *, areap))[1] << 8) | (SDL_reinterpret_cast(Uint8 *, areap))[0] << 0) #endif #endif /* !SDL_DATA_ALIGNED */ diff -r 4feced261c68 -r de822cd3df3a misc/winutils/include/SDL_opengl.h --- a/misc/winutils/include/SDL_opengl.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/winutils/include/SDL_opengl.h Tue Jan 21 22:43:06 2014 +0100 @@ -29,7 +29,7 @@ #ifdef __WIN32__ #define WIN32_LEAN_AND_MEAN #ifndef NOMINMAX -#define NOMINMAX /* Don't defined min() and max() */ +#define NOMINMAX /* Don't defined min() and max() */ #endif #include #endif @@ -37,14 +37,14 @@ #define __glext_h_ /* Don't let gl.h include glext.h */ #endif #if defined(__MACOSX__) -#include /* Header File For The OpenGL Library */ -#include /* Header File For The GLU Library */ +#include /* Header File For The OpenGL Library */ +#include /* Header File For The GLU Library */ #elif defined(__MACOS__) -#include /* Header File For The OpenGL Library */ -#include /* Header File For The GLU Library */ +#include /* Header File For The OpenGL Library */ +#include /* Header File For The GLU Library */ #else -#include /* Header File For The OpenGL Library */ -#include /* Header File For The GLU Library */ +#include /* Header File For The OpenGL Library */ +#include /* Header File For The GLU Library */ #endif #ifndef NO_SDL_GLEXT #undef __glext_h_ @@ -72,21 +72,21 @@ ** this file except in compliance with the License. You may obtain a copy ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: -** +** ** http://oss.sgi.com/projects/FreeB -** +** ** Note that, as provided in the License, the Software is distributed on an ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. -** +** ** Original Code. The Original Code is: OpenGL Sample Implementation, ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, ** Inc. The Original Code is Copyright (c) 1991-2004 Silicon Graphics, Inc. ** Copyright in any portions created by third parties is as indicated ** elsewhere herein. All Rights Reserved. -** +** ** Additional Notice Provisions: This software was created using the ** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has ** not been independently verified as being compliant with the OpenGL(R) @@ -3103,7 +3103,7 @@ #include #ifndef GL_VERSION_2_0 /* GL type for program/shader text */ -typedef char GLchar; /* native character */ +typedef char GLchar; /* native character */ #endif #ifndef GL_VERSION_1_5 @@ -3130,11 +3130,11 @@ #ifndef GL_ARB_shader_objects /* GL types for handling shader object handles and program/shader text */ -typedef char GLcharARB; /* native character */ +typedef char GLcharARB; /* native character */ #if defined(__APPLE__) -typedef void *GLhandleARB; /* shader object handle */ +typedef void *GLhandleARB; /* shader object handle */ #else -typedef unsigned int GLhandleARB; /* shader object handle */ +typedef unsigned int GLhandleARB; /* shader object handle */ #endif #endif diff -r 4feced261c68 -r de822cd3df3a misc/winutils/include/SDL_platform.h --- a/misc/winutils/include/SDL_platform.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/winutils/include/SDL_platform.h Tue Jan 21 22:43:06 2014 +0100 @@ -29,11 +29,11 @@ #if defined(_AIX) #undef __AIX__ -#define __AIX__ 1 +#define __AIX__ 1 #endif #if defined(__BEOS__) #undef __BEOS__ -#define __BEOS__ 1 +#define __BEOS__ 1 #endif #if defined(__HAIKU__) #undef __HAIKU__ @@ -41,70 +41,70 @@ #endif #if defined(bsdi) || defined(__bsdi) || defined(__bsdi__) #undef __BSDI__ -#define __BSDI__ 1 +#define __BSDI__ 1 #endif #if defined(_arch_dreamcast) #undef __DREAMCAST__ -#define __DREAMCAST__ 1 +#define __DREAMCAST__ 1 #endif #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) #undef __FREEBSD__ -#define __FREEBSD__ 1 +#define __FREEBSD__ 1 #endif #if defined(__HAIKU__) #undef __HAIKU__ -#define __HAIKU__ 1 +#define __HAIKU__ 1 #endif #if defined(hpux) || defined(__hpux) || defined(__hpux__) #undef __HPUX__ -#define __HPUX__ 1 +#define __HPUX__ 1 #endif #if defined(sgi) || defined(__sgi) || defined(__sgi__) || defined(_SGI_SOURCE) #undef __IRIX__ -#define __IRIX__ 1 +#define __IRIX__ 1 #endif #if defined(linux) || defined(__linux) || defined(__linux__) #undef __LINUX__ -#define __LINUX__ 1 +#define __LINUX__ 1 #endif #if defined(__APPLE__) #undef __MACOSX__ -#define __MACOSX__ 1 +#define __MACOSX__ 1 #elif defined(macintosh) #undef __MACOS__ -#define __MACOS__ 1 +#define __MACOS__ 1 #endif #if defined(__NetBSD__) #undef __NETBSD__ -#define __NETBSD__ 1 +#define __NETBSD__ 1 #endif #if defined(__OpenBSD__) #undef __OPENBSD__ -#define __OPENBSD__ 1 +#define __OPENBSD__ 1 #endif #if defined(__OS2__) #undef __OS2__ -#define __OS2__ 1 +#define __OS2__ 1 #endif #if defined(osf) || defined(__osf) || defined(__osf__) || defined(_OSF_SOURCE) #undef __OSF__ -#define __OSF__ 1 +#define __OSF__ 1 #endif #if defined(__QNXNTO__) #undef __QNXNTO__ -#define __QNXNTO__ 1 +#define __QNXNTO__ 1 #endif #if defined(riscos) || defined(__riscos) || defined(__riscos__) #undef __RISCOS__ -#define __RISCOS__ 1 +#define __RISCOS__ 1 #endif #if defined(__SVR4) #undef __SOLARIS__ -#define __SOLARIS__ 1 +#define __SOLARIS__ 1 #endif #if defined(WIN32) || defined(_WIN32) #undef __WIN32__ -#define __WIN32__ 1 +#define __WIN32__ 1 #endif #endif /* _SDL_platform_h */ diff -r 4feced261c68 -r de822cd3df3a misc/winutils/include/SDL_quit.h --- a/misc/winutils/include/SDL_quit.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/winutils/include/SDL_quit.h Tue Jan 21 22:43:06 2014 +0100 @@ -34,7 +34,7 @@ * An SDL_QUITEVENT is generated when the user tries to close the application * window. If it is ignored or filtered out, the window will remain open. * If it is not ignored or filtered, it is queued normally and the window - * is allowed to close. When the window is closed, screen updates will + * is allowed to close. When the window is closed, screen updates will * complete, but have no effect. * * SDL_Init() installs signal handlers for SIGINT (keyboard interrupt) @@ -46,7 +46,7 @@ */ /** @file SDL_quit.h - * There are no functions directly affecting the quit event + * There are no functions directly affecting the quit event */ #define SDL_QuitRequested() \ diff -r 4feced261c68 -r de822cd3df3a misc/winutils/include/SDL_rwops.h --- a/misc/winutils/include/SDL_rwops.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/winutils/include/SDL_rwops.h Tue Jan 21 22:43:06 2014 +0100 @@ -40,55 +40,55 @@ /** This is the read/write operation structure -- very basic */ typedef struct SDL_RWops { - /** Seek to 'offset' relative to whence, one of stdio's whence values: - * SEEK_SET, SEEK_CUR, SEEK_END - * Returns the final offset in the data source. - */ - int (SDLCALL *seek)(struct SDL_RWops *context, int offset, int whence); + /** Seek to 'offset' relative to whence, one of stdio's whence values: + * SEEK_SET, SEEK_CUR, SEEK_END + * Returns the final offset in the data source. + */ + int (SDLCALL *seek)(struct SDL_RWops *context, int offset, int whence); - /** Read up to 'maxnum' objects each of size 'size' from the data - * source to the area pointed at by 'ptr'. - * Returns the number of objects read, or -1 if the read failed. - */ - int (SDLCALL *read)(struct SDL_RWops *context, void *ptr, int size, int maxnum); + /** Read up to 'maxnum' objects each of size 'size' from the data + * source to the area pointed at by 'ptr'. + * Returns the number of objects read, or -1 if the read failed. + */ + int (SDLCALL *read)(struct SDL_RWops *context, void *ptr, int size, int maxnum); - /** Write exactly 'num' objects each of size 'objsize' from the area - * pointed at by 'ptr' to data source. - * Returns 'num', or -1 if the write failed. - */ - int (SDLCALL *write)(struct SDL_RWops *context, const void *ptr, int size, int num); + /** Write exactly 'num' objects each of size 'objsize' from the area + * pointed at by 'ptr' to data source. + * Returns 'num', or -1 if the write failed. + */ + int (SDLCALL *write)(struct SDL_RWops *context, const void *ptr, int size, int num); - /** Close and free an allocated SDL_FSops structure */ - int (SDLCALL *close)(struct SDL_RWops *context); + /** Close and free an allocated SDL_FSops structure */ + int (SDLCALL *close)(struct SDL_RWops *context); - Uint32 type; - union { + Uint32 type; + union { #if defined(__WIN32__) && !defined(__SYMBIAN32__) - struct { - int append; - void *h; - struct { - void *data; - int size; - int left; - } buffer; - } win32io; + struct { + int append; + void *h; + struct { + void *data; + int size; + int left; + } buffer; + } win32io; #endif -#ifdef HAVE_STDIO_H - struct { - int autoclose; - FILE *fp; - } stdio; +#ifdef HAVE_STDIO_H + struct { + int autoclose; + FILE *fp; + } stdio; #endif - struct { - Uint8 *base; - Uint8 *here; - Uint8 *stop; - } mem; - struct { - void *data1; - } unknown; - } hidden; + struct { + Uint8 *base; + Uint8 *here; + Uint8 *stop; + } mem; + struct { + void *data1; + } unknown; + } hidden; } SDL_RWops; @@ -112,18 +112,18 @@ /** @name Seek Reference Points */ /*@{*/ -#define RW_SEEK_SET 0 /**< Seek from the beginning of data */ -#define RW_SEEK_CUR 1 /**< Seek relative to current read point */ -#define RW_SEEK_END 2 /**< Seek relative to the end of data */ +#define RW_SEEK_SET 0 /**< Seek from the beginning of data */ +#define RW_SEEK_CUR 1 /**< Seek relative to current read point */ +#define RW_SEEK_END 2 /**< Seek relative to the end of data */ /*@}*/ /** @name Macros to easily read and write from an SDL_RWops structure */ /*@{*/ -#define SDL_RWseek(ctx, offset, whence) (ctx)->seek(ctx, offset, whence) -#define SDL_RWtell(ctx) (ctx)->seek(ctx, 0, RW_SEEK_CUR) -#define SDL_RWread(ctx, ptr, size, n) (ctx)->read(ctx, ptr, size, n) -#define SDL_RWwrite(ctx, ptr, size, n) (ctx)->write(ctx, ptr, size, n) -#define SDL_RWclose(ctx) (ctx)->close(ctx) +#define SDL_RWseek(ctx, offset, whence) (ctx)->seek(ctx, offset, whence) +#define SDL_RWtell(ctx) (ctx)->seek(ctx, 0, RW_SEEK_CUR) +#define SDL_RWread(ctx, ptr, size, n) (ctx)->read(ctx, ptr, size, n) +#define SDL_RWwrite(ctx, ptr, size, n) (ctx)->write(ctx, ptr, size, n) +#define SDL_RWclose(ctx) (ctx)->close(ctx) /*@}*/ /** @name Read an item of the specified endianness and return in native format */ diff -r 4feced261c68 -r de822cd3df3a misc/winutils/include/SDL_stdinc.h --- a/misc/winutils/include/SDL_stdinc.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/winutils/include/SDL_stdinc.h Tue Jan 21 22:43:06 2014 +0100 @@ -75,8 +75,8 @@ #endif /** The number of elements in an array */ -#define SDL_arraysize(array) (sizeof(array)/sizeof(array[0])) -#define SDL_TABLESIZE(table) SDL_arraysize(table) +#define SDL_arraysize(array) (sizeof(array)/sizeof(array[0])) +#define SDL_TABLESIZE(table) SDL_arraysize(table) /* Use proper C++ casts when compiled as C++ to be compatible with the option -Wold-style-cast of GCC (and -Werror=old-style-cast in GCC 4.2 and above. */ @@ -91,27 +91,27 @@ /** @name Basic data types */ /*@{*/ typedef enum { - SDL_FALSE = 0, - SDL_TRUE = 1 + SDL_FALSE = 0, + SDL_TRUE = 1 } SDL_bool; -typedef int8_t Sint8; -typedef uint8_t Uint8; -typedef int16_t Sint16; -typedef uint16_t Uint16; -typedef int32_t Sint32; -typedef uint32_t Uint32; +typedef int8_t Sint8; +typedef uint8_t Uint8; +typedef int16_t Sint16; +typedef uint16_t Uint16; +typedef int32_t Sint32; +typedef uint32_t Uint32; #ifdef SDL_HAS_64BIT_TYPE -typedef int64_t Sint64; +typedef int64_t Sint64; #ifndef SYMBIAN32_GCCE -typedef uint64_t Uint64; +typedef uint64_t Uint64; #endif #else /* This is really just a hack to prevent the compiler from complaining */ typedef struct { - Uint32 hi; - Uint32 lo; + Uint32 hi; + Uint32 lo; } Uint64, Sint64; #endif @@ -144,7 +144,7 @@ #endif typedef enum { - DUMMY_ENUM_VALUE + DUMMY_ENUM_VALUE } SDL_DUMMY_ENUM; #ifndef __NDS__ @@ -159,25 +159,25 @@ #endif #ifdef HAVE_MALLOC -#define SDL_malloc malloc +#define SDL_malloc malloc #else extern DECLSPEC void * SDLCALL SDL_malloc(size_t size); #endif #ifdef HAVE_CALLOC -#define SDL_calloc calloc +#define SDL_calloc calloc #else extern DECLSPEC void * SDLCALL SDL_calloc(size_t nmemb, size_t size); #endif #ifdef HAVE_REALLOC -#define SDL_realloc realloc +#define SDL_realloc realloc #else extern DECLSPEC void * SDLCALL SDL_realloc(void *mem, size_t size); #endif #ifdef HAVE_FREE -#define SDL_free free +#define SDL_free free #else extern DECLSPEC void SDLCALL SDL_free(void *mem); #endif @@ -213,32 +213,32 @@ #endif #ifdef HAVE_GETENV -#define SDL_getenv getenv +#define SDL_getenv getenv #else extern DECLSPEC char * SDLCALL SDL_getenv(const char *name); #endif #ifdef HAVE_PUTENV -#define SDL_putenv putenv +#define SDL_putenv putenv #else extern DECLSPEC int SDLCALL SDL_putenv(const char *variable); #endif #ifdef HAVE_QSORT -#define SDL_qsort qsort +#define SDL_qsort qsort #else extern DECLSPEC void SDLCALL SDL_qsort(void *base, size_t nmemb, size_t size, int (*compare)(const void *, const void *)); #endif #ifdef HAVE_ABS -#define SDL_abs abs +#define SDL_abs abs #else -#define SDL_abs(X) ((X) < 0 ? -(X) : (X)) +#define SDL_abs(X) ((X) < 0 ? -(X) : (X)) #endif -#define SDL_min(x, y) (((x) < (y)) ? (x) : (y)) -#define SDL_max(x, y) (((x) > (y)) ? (x) : (y)) +#define SDL_min(x, y) (((x) < (y)) ? (x) : (y)) +#define SDL_max(x, y) (((x) > (y)) ? (x) : (y)) #ifdef HAVE_CTYPE_H #define SDL_isdigit(X) isdigit(X) @@ -259,32 +259,32 @@ #endif #if defined(__GNUC__) && defined(i386) -#define SDL_memset4(dst, val, len) \ -do { \ - int u0, u1, u2; \ - __asm__ __volatile__ ( \ - "cld\n\t" \ - "rep ; stosl\n\t" \ - : "=&D" (u0), "=&a" (u1), "=&c" (u2) \ - : "0" (dst), "1" (val), "2" (SDL_static_cast(Uint32, len)) \ - : "memory" ); \ +#define SDL_memset4(dst, val, len) \ +do { \ + int u0, u1, u2; \ + __asm__ __volatile__ ( \ + "cld\n\t" \ + "rep ; stosl\n\t" \ + : "=&D" (u0), "=&a" (u1), "=&c" (u2) \ + : "0" (dst), "1" (val), "2" (SDL_static_cast(Uint32, len)) \ + : "memory" ); \ } while(0) #endif #ifndef SDL_memset4 -#define SDL_memset4(dst, val, len) \ -do { \ - unsigned _count = (len); \ - unsigned _n = (_count + 3) / 4; \ - Uint32 *_p = SDL_static_cast(Uint32 *, dst); \ - Uint32 _val = (val); \ - if (len == 0) break; \ - switch (_count % 4) { \ - case 0: do { *_p++ = _val; \ - case 3: *_p++ = _val; \ - case 2: *_p++ = _val; \ - case 1: *_p++ = _val; \ - } while ( --_n ); \ - } \ +#define SDL_memset4(dst, val, len) \ +do { \ + unsigned _count = (len); \ + unsigned _n = (_count + 3) / 4; \ + Uint32 *_p = SDL_static_cast(Uint32 *, dst); \ + Uint32 _val = (val); \ + if (len == 0) break; \ + switch (_count % 4) { \ + case 0: do { *_p++ = _val; \ + case 3: *_p++ = _val; \ + case 2: *_p++ = _val; \ + case 1: *_p++ = _val; \ + } while ( --_n ); \ + } \ } while(0) #endif @@ -292,29 +292,29 @@ #if defined(__MACH__) && defined(__APPLE__) #define SDL_memcpy(dst, src, len) memcpy(dst, src, len) #elif defined(__GNUC__) && defined(i386) -#define SDL_memcpy(dst, src, len) \ -do { \ - int u0, u1, u2; \ - __asm__ __volatile__ ( \ - "cld\n\t" \ - "rep ; movsl\n\t" \ - "testb $2,%b4\n\t" \ - "je 1f\n\t" \ - "movsw\n" \ - "1:\ttestb $1,%b4\n\t" \ - "je 2f\n\t" \ - "movsb\n" \ - "2:" \ - : "=&c" (u0), "=&D" (u1), "=&S" (u2) \ - : "0" (SDL_static_cast(unsigned, len)/4), "q" (len), "1" (dst),"2" (src) \ - : "memory" ); \ +#define SDL_memcpy(dst, src, len) \ +do { \ + int u0, u1, u2; \ + __asm__ __volatile__ ( \ + "cld\n\t" \ + "rep ; movsl\n\t" \ + "testb $2,%b4\n\t" \ + "je 1f\n\t" \ + "movsw\n" \ + "1:\ttestb $1,%b4\n\t" \ + "je 2f\n\t" \ + "movsb\n" \ + "2:" \ + : "=&c" (u0), "=&D" (u1), "=&S" (u2) \ + : "0" (SDL_static_cast(unsigned, len)/4), "q" (len), "1" (dst),"2" (src) \ + : "memory" ); \ } while(0) #endif #ifndef SDL_memcpy #ifdef HAVE_MEMCPY #define SDL_memcpy memcpy #elif defined(HAVE_BCOPY) -#define SDL_memcpy(d, s, n) bcopy((s), (d), (n)) +#define SDL_memcpy(d, s, n) bcopy((s), (d), (n)) #else extern DECLSPEC void * SDLCALL SDL_memcpy(void *dst, const void *src, size_t len); #endif @@ -324,46 +324,46 @@ #if defined(__MACH__) && defined(__APPLE__) #define SDL_memcpy4(dst, src, len) memcpy(dst, src, (len)*4) #elif defined(__GNUC__) && defined(i386) -#define SDL_memcpy4(dst, src, len) \ -do { \ - int ecx, edi, esi; \ - __asm__ __volatile__ ( \ - "cld\n\t" \ - "rep ; movsl" \ - : "=&c" (ecx), "=&D" (edi), "=&S" (esi) \ - : "0" (SDL_static_cast(unsigned, len)), "1" (dst), "2" (src) \ - : "memory" ); \ +#define SDL_memcpy4(dst, src, len) \ +do { \ + int ecx, edi, esi; \ + __asm__ __volatile__ ( \ + "cld\n\t" \ + "rep ; movsl" \ + : "=&c" (ecx), "=&D" (edi), "=&S" (esi) \ + : "0" (SDL_static_cast(unsigned, len)), "1" (dst), "2" (src) \ + : "memory" ); \ } while(0) #endif #ifndef SDL_memcpy4 -#define SDL_memcpy4(dst, src, len) SDL_memcpy(dst, src, (len) << 2) +#define SDL_memcpy4(dst, src, len) SDL_memcpy(dst, src, (len) << 2) #endif #if defined(__GNUC__) && defined(i386) -#define SDL_revcpy(dst, src, len) \ -do { \ - int u0, u1, u2; \ - char *dstp = SDL_static_cast(char *, dst); \ - char *srcp = SDL_static_cast(char *, src); \ - int n = (len); \ - if ( n >= 4 ) { \ - __asm__ __volatile__ ( \ - "std\n\t" \ - "rep ; movsl\n\t" \ - "cld\n\t" \ - : "=&c" (u0), "=&D" (u1), "=&S" (u2) \ - : "0" (n >> 2), \ - "1" (dstp+(n-4)), "2" (srcp+(n-4)) \ - : "memory" ); \ - } \ - switch (n & 3) { \ - case 3: dstp[2] = srcp[2]; \ - case 2: dstp[1] = srcp[1]; \ - case 1: dstp[0] = srcp[0]; \ - break; \ - default: \ - break; \ - } \ +#define SDL_revcpy(dst, src, len) \ +do { \ + int u0, u1, u2; \ + char *dstp = SDL_static_cast(char *, dst); \ + char *srcp = SDL_static_cast(char *, src); \ + int n = (len); \ + if ( n >= 4 ) { \ + __asm__ __volatile__ ( \ + "std\n\t" \ + "rep ; movsl\n\t" \ + "cld\n\t" \ + : "=&c" (u0), "=&D" (u1), "=&S" (u2) \ + : "0" (n >> 2), \ + "1" (dstp+(n-4)), "2" (srcp+(n-4)) \ + : "memory" ); \ + } \ + switch (n & 3) { \ + case 3: dstp[2] = srcp[2]; \ + case 2: dstp[1] = srcp[1]; \ + case 1: dstp[0] = srcp[0]; \ + break; \ + default: \ + break; \ + } \ } while(0) #endif #ifndef SDL_revcpy @@ -373,15 +373,15 @@ #ifdef HAVE_MEMMOVE #define SDL_memmove memmove #elif defined(HAVE_BCOPY) -#define SDL_memmove(d, s, n) bcopy((s), (d), (n)) +#define SDL_memmove(d, s, n) bcopy((s), (d), (n)) #else -#define SDL_memmove(dst, src, len) \ -do { \ - if ( dst < src ) { \ - SDL_memcpy(dst, src, len); \ - } else { \ - SDL_revcpy(dst, src, len); \ - } \ +#define SDL_memmove(dst, src, len) \ +do { \ + if ( dst < src ) { \ + SDL_memcpy(dst, src, len); \ + } else { \ + SDL_revcpy(dst, src, len); \ + } \ } while(0) #endif @@ -458,7 +458,7 @@ #ifdef HAVE_ITOA #define SDL_itoa itoa #else -#define SDL_itoa(value, string, radix) SDL_ltoa((long)value, string, radix) +#define SDL_itoa(value, string, radix) SDL_ltoa((long)value, string, radix) #endif #ifdef HAVE__LTOA @@ -470,7 +470,7 @@ #ifdef HAVE__UITOA #define SDL_uitoa _uitoa #else -#define SDL_uitoa(value, string, radix) SDL_ultoa((long)value, string, radix) +#define SDL_uitoa(value, string, radix) SDL_ultoa((long)value, string, radix) #endif #ifdef HAVE__ULTOA @@ -584,13 +584,13 @@ #endif /** @name SDL_ICONV Error Codes - * The SDL implementation of iconv() returns these error codes + * The SDL implementation of iconv() returns these error codes */ /*@{*/ -#define SDL_ICONV_ERROR (size_t)-1 -#define SDL_ICONV_E2BIG (size_t)-2 -#define SDL_ICONV_EILSEQ (size_t)-3 -#define SDL_ICONV_EINVAL (size_t)-4 +#define SDL_ICONV_ERROR (size_t)-1 +#define SDL_ICONV_E2BIG (size_t)-2 +#define SDL_ICONV_EILSEQ (size_t)-3 +#define SDL_ICONV_EINVAL (size_t)-4 /*@}*/ #if defined(HAVE_ICONV) && defined(HAVE_ICONV_H) @@ -607,9 +607,9 @@ * string that must be freed with SDL_free() or NULL on error. */ extern DECLSPEC char * SDLCALL SDL_iconv_string(const char *tocode, const char *fromcode, const char *inbuf, size_t inbytesleft); -#define SDL_iconv_utf8_locale(S) SDL_iconv_string("", "UTF-8", S, SDL_strlen(S)+1) -#define SDL_iconv_utf8_ucs2(S) (Uint16 *)SDL_iconv_string("UCS-2", "UTF-8", S, SDL_strlen(S)+1) -#define SDL_iconv_utf8_ucs4(S) (Uint32 *)SDL_iconv_string("UCS-4", "UTF-8", S, SDL_strlen(S)+1) +#define SDL_iconv_utf8_locale(S) SDL_iconv_string("", "UTF-8", S, SDL_strlen(S)+1) +#define SDL_iconv_utf8_ucs2(S) (Uint16 *)SDL_iconv_string("UCS-2", "UTF-8", S, SDL_strlen(S)+1) +#define SDL_iconv_utf8_ucs4(S) (Uint32 *)SDL_iconv_string("UCS-4", "UTF-8", S, SDL_strlen(S)+1) /* Ends C function definitions when using C++ */ #ifdef __cplusplus diff -r 4feced261c68 -r de822cd3df3a misc/winutils/include/SDL_syswm.h --- a/misc/winutils/include/SDL_syswm.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/winutils/include/SDL_syswm.h Tue Jan 21 22:43:06 2014 +0100 @@ -65,16 +65,16 @@ /** These are the various supported subsystems under UNIX */ typedef enum { - SDL_SYSWM_X11 + SDL_SYSWM_X11 } SDL_SYSWM_TYPE; /** The UNIX custom event structure */ struct SDL_SysWMmsg { - SDL_version version; - SDL_SYSWM_TYPE subsystem; - union { - XEvent xevent; - } event; + SDL_version version; + SDL_SYSWM_TYPE subsystem; + union { + XEvent xevent; + } event; }; /** The UNIX custom window manager information structure. @@ -82,35 +82,35 @@ * low level system it is using, and will be one of SDL_SYSWM_TYPE. */ typedef struct SDL_SysWMinfo { - SDL_version version; - SDL_SYSWM_TYPE subsystem; - union { - struct { - Display *display; /**< The X11 display */ - Window window; /**< The X11 display window */ - /** These locking functions should be called around - * any X11 functions using the display variable, + SDL_version version; + SDL_SYSWM_TYPE subsystem; + union { + struct { + Display *display; /**< The X11 display */ + Window window; /**< The X11 display window */ + /** These locking functions should be called around + * any X11 functions using the display variable, * but not the gfxdisplay variable. * They lock the event thread, so should not be - * called around event functions or from event filters. - */ + * called around event functions or from event filters. + */ /*@{*/ - void (*lock_func)(void); - void (*unlock_func)(void); + void (*lock_func)(void); + void (*unlock_func)(void); /*@}*/ - /** @name Introduced in SDL 1.0.2 */ + /** @name Introduced in SDL 1.0.2 */ /*@{*/ - Window fswindow; /**< The X11 fullscreen window */ - Window wmwindow; /**< The X11 managed input window */ + Window fswindow; /**< The X11 fullscreen window */ + Window wmwindow; /**< The X11 managed input window */ /*@}*/ - /** @name Introduced in SDL 1.2.12 */ + /** @name Introduced in SDL 1.2.12 */ /*@{*/ - Display *gfxdisplay; /**< The X11 display to which rendering is done */ + Display *gfxdisplay; /**< The X11 display to which rendering is done */ /*@}*/ - } x11; - } info; + } x11; + } info; } SDL_SysWMinfo; #elif defined(SDL_VIDEO_DRIVER_NANOX) @@ -118,14 +118,14 @@ /** The generic custom event structure */ struct SDL_SysWMmsg { - SDL_version version; - int data; + SDL_version version; + int data; }; /** The windows custom window manager information structure */ typedef struct SDL_SysWMinfo { - SDL_version version ; - GR_WINDOW_ID window ; /* The display window */ + SDL_version version ; + GR_WINDOW_ID window ; /* The display window */ } SDL_SysWMinfo; #elif defined(SDL_VIDEO_DRIVER_WINDIB) || defined(SDL_VIDEO_DRIVER_DDRAW) || defined(SDL_VIDEO_DRIVER_GAPI) @@ -134,35 +134,35 @@ /** The windows custom event structure */ struct SDL_SysWMmsg { - SDL_version version; - HWND hwnd; /**< The window for the message */ - UINT msg; /**< The type of message */ - WPARAM wParam; /**< WORD message parameter */ - LPARAM lParam; /**< LONG message parameter */ + SDL_version version; + HWND hwnd; /**< The window for the message */ + UINT msg; /**< The type of message */ + WPARAM wParam; /**< WORD message parameter */ + LPARAM lParam; /**< LONG message parameter */ }; /** The windows custom window manager information structure */ typedef struct SDL_SysWMinfo { - SDL_version version; - HWND window; /**< The Win32 display window */ - HGLRC hglrc; /**< The OpenGL context, if any */ + SDL_version version; + HWND window; /**< The Win32 display window */ + HGLRC hglrc; /**< The OpenGL context, if any */ } SDL_SysWMinfo; #elif defined(SDL_VIDEO_DRIVER_RISCOS) /** RISC OS custom event structure */ struct SDL_SysWMmsg { - SDL_version version; - int eventCode; /**< The window for the message */ - int pollBlock[64]; + SDL_version version; + int eventCode; /**< The window for the message */ + int pollBlock[64]; }; /** The RISC OS custom window manager information structure */ typedef struct SDL_SysWMinfo { - SDL_version version; - int wimpVersion; /**< Wimp version running under */ - int taskHandle; /**< The RISC OS task handle */ - int window; /**< The RISC OS display window */ + SDL_version version; + int wimpVersion; /**< Wimp version running under */ + int taskHandle; /**< The RISC OS task handle */ + int window; /**< The RISC OS display window */ } SDL_SysWMinfo; #elif defined(SDL_VIDEO_DRIVER_PHOTON) @@ -171,28 +171,28 @@ /** The QNX custom event structure */ struct SDL_SysWMmsg { - SDL_version version; - int data; + SDL_version version; + int data; }; /** The QNX custom window manager information structure */ typedef struct SDL_SysWMinfo { - SDL_version version; - int data; + SDL_version version; + int data; } SDL_SysWMinfo; #else /** The generic custom event structure */ struct SDL_SysWMmsg { - SDL_version version; - int data; + SDL_version version; + int data; }; /** The generic custom window manager information structure */ typedef struct SDL_SysWMinfo { - SDL_version version; - int data; + SDL_version version; + int data; } SDL_SysWMinfo; #endif /* video driver type */ @@ -203,7 +203,7 @@ /** * This function gives you custom hooks into the window manager information. * It fills the structure pointed to by 'info' with custom information and - * returns 0 if the function is not implemented, 1 if the function is + * returns 0 if the function is not implemented, 1 if the function is * implemented and no error occurred, and -1 if the version member of * the 'info' structure is not filled in or not supported. * diff -r 4feced261c68 -r de822cd3df3a misc/winutils/include/SDL_thread.h --- a/misc/winutils/include/SDL_thread.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/winutils/include/SDL_thread.h Tue Jan 21 22:43:06 2014 +0100 @@ -24,7 +24,7 @@ #define _SDL_thread_h /** @file SDL_thread.h - * Header for the SDL thread management routines + * Header for the SDL thread management routines * * @note These are independent of the other SDL routines. */ @@ -66,11 +66,11 @@ #endif #ifdef __OS2__ -typedef int (*pfnSDL_CurrentBeginThread)(void (*func)(void *), void *, unsigned, void *arg); +typedef int (*pfnSDL_CurrentBeginThread)(void (*func)(void *), void *, unsigned, void *arg); typedef void (*pfnSDL_CurrentEndThread)(void); #else typedef uintptr_t (__cdecl *pfnSDL_CurrentBeginThread) (void *, unsigned, - unsigned (__stdcall *func)(void *), void *arg, + unsigned (__stdcall *func)(void *), void *arg, unsigned, unsigned *threadID); typedef void (__cdecl *pfnSDL_CurrentEndThread)(unsigned code); #endif diff -r 4feced261c68 -r de822cd3df3a misc/winutils/include/SDL_timer.h --- a/misc/winutils/include/SDL_timer.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/winutils/include/SDL_timer.h Tue Jan 21 22:43:06 2014 +0100 @@ -37,15 +37,15 @@ #endif /** This is the OS scheduler timeslice, in milliseconds */ -#define SDL_TIMESLICE 10 +#define SDL_TIMESLICE 10 /** This is the maximum resolution of the SDL timer on all platforms */ -#define TIMER_RESOLUTION 10 /**< Experimentally determined */ +#define TIMER_RESOLUTION 10 /**< Experimentally determined */ /** * Get the number of milliseconds since the SDL library initialization. * Note that this value wraps if the program runs for more than ~49 days. - */ + */ extern DECLSPEC Uint32 SDLCALL SDL_GetTicks(void); /** Wait a specified number of milliseconds before returning */ @@ -57,7 +57,7 @@ /** * Set a callback to run after the specified number of milliseconds has * elapsed. The callback function is passed the current timer interval - * and returns the next timer interval. If the returned value is the + * and returns the next timer interval. If the returned value is the * same as the one passed in, the periodic alarm continues, otherwise a * new alarm is scheduled. If the callback returns 0, the periodic alarm * is cancelled. @@ -70,7 +70,7 @@ * The maximum resolution of this timer is 10 ms, which means that if * you request a 16 ms timer, your callback will run approximately 20 ms * later on an unloaded system. If you wanted to set a flag signaling - * a frame update at 30 frames per second (every 33 ms), you might set a + * a frame update at 30 frames per second (every 33 ms), you might set a * timer for 30 ms: * @code SDL_SetTimer((33/10)*10, flag_update); @endcode * diff -r 4feced261c68 -r de822cd3df3a misc/winutils/include/SDL_version.h --- a/misc/winutils/include/SDL_version.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/winutils/include/SDL_version.h Tue Jan 21 22:43:06 2014 +0100 @@ -39,42 +39,42 @@ * Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL */ /*@{*/ -#define SDL_MAJOR_VERSION 1 -#define SDL_MINOR_VERSION 2 -#define SDL_PATCHLEVEL 15 +#define SDL_MAJOR_VERSION 1 +#define SDL_MINOR_VERSION 2 +#define SDL_PATCHLEVEL 15 /*@}*/ typedef struct SDL_version { - Uint8 major; - Uint8 minor; - Uint8 patch; + Uint8 major; + Uint8 minor; + Uint8 patch; } SDL_version; /** * This macro can be used to fill a version structure with the compile-time * version of the SDL library. */ -#define SDL_VERSION(X) \ -{ \ - (X)->major = SDL_MAJOR_VERSION; \ - (X)->minor = SDL_MINOR_VERSION; \ - (X)->patch = SDL_PATCHLEVEL; \ +#define SDL_VERSION(X) \ +{ \ + (X)->major = SDL_MAJOR_VERSION; \ + (X)->minor = SDL_MINOR_VERSION; \ + (X)->patch = SDL_PATCHLEVEL; \ } /** This macro turns the version numbers into a numeric value: * (1,2,3) -> (1203) * This assumes that there will never be more than 100 patchlevels */ -#define SDL_VERSIONNUM(X, Y, Z) \ - ((X)*1000 + (Y)*100 + (Z)) +#define SDL_VERSIONNUM(X, Y, Z) \ + ((X)*1000 + (Y)*100 + (Z)) /** This is the version number macro for the current SDL version */ #define SDL_COMPILEDVERSION \ - SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) + SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) /** This macro will evaluate to true if compiled with SDL at least X.Y.Z */ #define SDL_VERSION_ATLEAST(X, Y, Z) \ - (SDL_COMPILEDVERSION >= SDL_VERSIONNUM(X, Y, Z)) + (SDL_COMPILEDVERSION >= SDL_VERSIONNUM(X, Y, Z)) /** This function gets the version of the dynamically linked SDL library. * it should NOT be used to fill a version structure, instead you should diff -r 4feced261c68 -r de822cd3df3a misc/winutils/include/SDL_video.h --- a/misc/winutils/include/SDL_video.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/winutils/include/SDL_video.h Tue Jan 21 22:43:06 2014 +0100 @@ -48,77 +48,77 @@ /** @name Useful data types */ /*@{*/ typedef struct SDL_Rect { - Sint16 x, y; - Uint16 w, h; + Sint16 x, y; + Uint16 w, h; } SDL_Rect; typedef struct SDL_Color { - Uint8 r; - Uint8 g; - Uint8 b; - Uint8 unused; + Uint8 r; + Uint8 g; + Uint8 b; + Uint8 unused; } SDL_Color; #define SDL_Colour SDL_Color typedef struct SDL_Palette { - int ncolors; - SDL_Color *colors; + int ncolors; + SDL_Color *colors; } SDL_Palette; /*@}*/ /** Everything in the pixel format structure is read-only */ typedef struct SDL_PixelFormat { - SDL_Palette *palette; - Uint8 BitsPerPixel; - Uint8 BytesPerPixel; - Uint8 Rloss; - Uint8 Gloss; - Uint8 Bloss; - Uint8 Aloss; - Uint8 Rshift; - Uint8 Gshift; - Uint8 Bshift; - Uint8 Ashift; - Uint32 Rmask; - Uint32 Gmask; - Uint32 Bmask; - Uint32 Amask; + SDL_Palette *palette; + Uint8 BitsPerPixel; + Uint8 BytesPerPixel; + Uint8 Rloss; + Uint8 Gloss; + Uint8 Bloss; + Uint8 Aloss; + Uint8 Rshift; + Uint8 Gshift; + Uint8 Bshift; + Uint8 Ashift; + Uint32 Rmask; + Uint32 Gmask; + Uint32 Bmask; + Uint32 Amask; - /** RGB color key information */ - Uint32 colorkey; - /** Alpha value information (per-surface alpha) */ - Uint8 alpha; + /** RGB color key information */ + Uint32 colorkey; + /** Alpha value information (per-surface alpha) */ + Uint8 alpha; } SDL_PixelFormat; /** This structure should be treated as read-only, except for 'pixels', * which, if not NULL, contains the raw pixel data for the surface. */ typedef struct SDL_Surface { - Uint32 flags; /**< Read-only */ - SDL_PixelFormat *format; /**< Read-only */ - int w, h; /**< Read-only */ - Uint16 pitch; /**< Read-only */ - void *pixels; /**< Read-write */ - int offset; /**< Private */ + Uint32 flags; /**< Read-only */ + SDL_PixelFormat *format; /**< Read-only */ + int w, h; /**< Read-only */ + Uint16 pitch; /**< Read-only */ + void *pixels; /**< Read-write */ + int offset; /**< Private */ - /** Hardware-specific surface info */ - struct private_hwdata *hwdata; + /** Hardware-specific surface info */ + struct private_hwdata *hwdata; - /** clipping information */ - SDL_Rect clip_rect; /**< Read-only */ - Uint32 unused1; /**< for binary compatibility */ + /** clipping information */ + SDL_Rect clip_rect; /**< Read-only */ + Uint32 unused1; /**< for binary compatibility */ - /** Allow recursive locks */ - Uint32 locked; /**< Private */ + /** Allow recursive locks */ + Uint32 locked; /**< Private */ - /** info for fast blit mapping to other surfaces */ - struct SDL_BlitMap *map; /**< Private */ + /** info for fast blit mapping to other surfaces */ + struct SDL_BlitMap *map; /**< Private */ - /** format version, bumped at every change to invalidate blit maps */ - unsigned int format_version; /**< Private */ + /** format version, bumped at every change to invalidate blit maps */ + unsigned int format_version; /**< Private */ - /** Reference count -- used when freeing surface */ - int refcount; /**< Read-mostly */ + /** Reference count -- used when freeing surface */ + int refcount; /**< Read-mostly */ } SDL_Surface; /** @name SDL_Surface Flags @@ -128,100 +128,100 @@ /** Available for SDL_CreateRGBSurface() or SDL_SetVideoMode() */ /*@{*/ -#define SDL_SWSURFACE 0x00000000 /**< Surface is in system memory */ -#define SDL_HWSURFACE 0x00000001 /**< Surface is in video memory */ -#define SDL_ASYNCBLIT 0x00000004 /**< Use asynchronous blits if possible */ +#define SDL_SWSURFACE 0x00000000 /**< Surface is in system memory */ +#define SDL_HWSURFACE 0x00000001 /**< Surface is in video memory */ +#define SDL_ASYNCBLIT 0x00000004 /**< Use asynchronous blits if possible */ /*@}*/ /** Available for SDL_SetVideoMode() */ /*@{*/ -#define SDL_ANYFORMAT 0x10000000 /**< Allow any video depth/pixel-format */ -#define SDL_HWPALETTE 0x20000000 /**< Surface has exclusive palette */ -#define SDL_DOUBLEBUF 0x40000000 /**< Set up double-buffered video mode */ -#define SDL_FULLSCREEN 0x80000000 /**< Surface is a full screen display */ +#define SDL_ANYFORMAT 0x10000000 /**< Allow any video depth/pixel-format */ +#define SDL_HWPALETTE 0x20000000 /**< Surface has exclusive palette */ +#define SDL_DOUBLEBUF 0x40000000 /**< Set up double-buffered video mode */ +#define SDL_FULLSCREEN 0x80000000 /**< Surface is a full screen display */ #define SDL_OPENGL 0x00000002 /**< Create an OpenGL rendering context */ -#define SDL_OPENGLBLIT 0x0000000A /**< Create an OpenGL rendering context and use it for blitting */ -#define SDL_RESIZABLE 0x00000010 /**< This video mode may be resized */ -#define SDL_NOFRAME 0x00000020 /**< No window caption or edge frame */ +#define SDL_OPENGLBLIT 0x0000000A /**< Create an OpenGL rendering context and use it for blitting */ +#define SDL_RESIZABLE 0x00000010 /**< This video mode may be resized */ +#define SDL_NOFRAME 0x00000020 /**< No window caption or edge frame */ /*@}*/ /** Used internally (read-only) */ /*@{*/ -#define SDL_HWACCEL 0x00000100 /**< Blit uses hardware acceleration */ -#define SDL_SRCCOLORKEY 0x00001000 /**< Blit uses a source color key */ -#define SDL_RLEACCELOK 0x00002000 /**< Private flag */ -#define SDL_RLEACCEL 0x00004000 /**< Surface is RLE encoded */ -#define SDL_SRCALPHA 0x00010000 /**< Blit uses source alpha blending */ -#define SDL_PREALLOC 0x01000000 /**< Surface uses preallocated memory */ +#define SDL_HWACCEL 0x00000100 /**< Blit uses hardware acceleration */ +#define SDL_SRCCOLORKEY 0x00001000 /**< Blit uses a source color key */ +#define SDL_RLEACCELOK 0x00002000 /**< Private flag */ +#define SDL_RLEACCEL 0x00004000 /**< Surface is RLE encoded */ +#define SDL_SRCALPHA 0x00010000 /**< Blit uses source alpha blending */ +#define SDL_PREALLOC 0x01000000 /**< Surface uses preallocated memory */ /*@}*/ /*@}*/ /** Evaluates to true if the surface needs to be locked before access */ -#define SDL_MUSTLOCK(surface) \ - (surface->offset || \ +#define SDL_MUSTLOCK(surface) \ + (surface->offset || \ ((surface->flags & (SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_RLEACCEL)) != 0)) /** typedef for private surface blitting functions */ typedef int (*SDL_blit)(struct SDL_Surface *src, SDL_Rect *srcrect, - struct SDL_Surface *dst, SDL_Rect *dstrect); + struct SDL_Surface *dst, SDL_Rect *dstrect); /** Useful for determining the video hardware capabilities */ typedef struct SDL_VideoInfo { - Uint32 hw_available :1; /**< Flag: Can you create hardware surfaces? */ - Uint32 wm_available :1; /**< Flag: Can you talk to a window manager? */ - Uint32 UnusedBits1 :6; - Uint32 UnusedBits2 :1; - Uint32 blit_hw :1; /**< Flag: Accelerated blits HW --> HW */ - Uint32 blit_hw_CC :1; /**< Flag: Accelerated blits with Colorkey */ - Uint32 blit_hw_A :1; /**< Flag: Accelerated blits with Alpha */ - Uint32 blit_sw :1; /**< Flag: Accelerated blits SW --> HW */ - Uint32 blit_sw_CC :1; /**< Flag: Accelerated blits with Colorkey */ - Uint32 blit_sw_A :1; /**< Flag: Accelerated blits with Alpha */ - Uint32 blit_fill :1; /**< Flag: Accelerated color fill */ - Uint32 UnusedBits3 :16; - Uint32 video_mem; /**< The total amount of video memory (in K) */ - SDL_PixelFormat *vfmt; /**< Value: The format of the video surface */ - int current_w; /**< Value: The current video mode width */ - int current_h; /**< Value: The current video mode height */ + Uint32 hw_available :1; /**< Flag: Can you create hardware surfaces? */ + Uint32 wm_available :1; /**< Flag: Can you talk to a window manager? */ + Uint32 UnusedBits1 :6; + Uint32 UnusedBits2 :1; + Uint32 blit_hw :1; /**< Flag: Accelerated blits HW --> HW */ + Uint32 blit_hw_CC :1; /**< Flag: Accelerated blits with Colorkey */ + Uint32 blit_hw_A :1; /**< Flag: Accelerated blits with Alpha */ + Uint32 blit_sw :1; /**< Flag: Accelerated blits SW --> HW */ + Uint32 blit_sw_CC :1; /**< Flag: Accelerated blits with Colorkey */ + Uint32 blit_sw_A :1; /**< Flag: Accelerated blits with Alpha */ + Uint32 blit_fill :1; /**< Flag: Accelerated color fill */ + Uint32 UnusedBits3 :16; + Uint32 video_mem; /**< The total amount of video memory (in K) */ + SDL_PixelFormat *vfmt; /**< Value: The format of the video surface */ + int current_w; /**< Value: The current video mode width */ + int current_h; /**< Value: The current video mode height */ } SDL_VideoInfo; /** @name Overlay Formats * The most common video overlay formats. * For an explanation of these pixel formats, see: - * http://www.webartz.com/fourcc/indexyuv.htm + * http://www.webartz.com/fourcc/indexyuv.htm * * For information on the relationship between color spaces, see: * http://www.neuro.sfc.keio.ac.jp/~aly/polygon/info/color-space-faq.html */ /*@{*/ -#define SDL_YV12_OVERLAY 0x32315659 /**< Planar mode: Y + V + U (3 planes) */ -#define SDL_IYUV_OVERLAY 0x56555949 /**< Planar mode: Y + U + V (3 planes) */ -#define SDL_YUY2_OVERLAY 0x32595559 /**< Packed mode: Y0+U0+Y1+V0 (1 plane) */ -#define SDL_UYVY_OVERLAY 0x59565955 /**< Packed mode: U0+Y0+V0+Y1 (1 plane) */ -#define SDL_YVYU_OVERLAY 0x55595659 /**< Packed mode: Y0+V0+Y1+U0 (1 plane) */ +#define SDL_YV12_OVERLAY 0x32315659 /**< Planar mode: Y + V + U (3 planes) */ +#define SDL_IYUV_OVERLAY 0x56555949 /**< Planar mode: Y + U + V (3 planes) */ +#define SDL_YUY2_OVERLAY 0x32595559 /**< Packed mode: Y0+U0+Y1+V0 (1 plane) */ +#define SDL_UYVY_OVERLAY 0x59565955 /**< Packed mode: U0+Y0+V0+Y1 (1 plane) */ +#define SDL_YVYU_OVERLAY 0x55595659 /**< Packed mode: Y0+V0+Y1+U0 (1 plane) */ /*@}*/ /** The YUV hardware video overlay */ typedef struct SDL_Overlay { - Uint32 format; /**< Read-only */ - int w, h; /**< Read-only */ - int planes; /**< Read-only */ - Uint16 *pitches; /**< Read-only */ - Uint8 **pixels; /**< Read-write */ + Uint32 format; /**< Read-only */ + int w, h; /**< Read-only */ + int planes; /**< Read-only */ + Uint16 *pitches; /**< Read-only */ + Uint8 **pixels; /**< Read-write */ - /** @name Hardware-specific surface info */ + /** @name Hardware-specific surface info */ /*@{*/ - struct private_yuvhwfuncs *hwfuncs; - struct private_yuvhwdata *hwdata; + struct private_yuvhwfuncs *hwfuncs; + struct private_yuvhwdata *hwdata; /*@{*/ - /** @name Special flags */ + /** @name Special flags */ /*@{*/ - Uint32 hw_overlay :1; /**< Flag: This overlay hardware accelerated? */ - Uint32 UnusedBits :31; + Uint32 hw_overlay :1; /**< Flag: This overlay hardware accelerated? */ + Uint32 UnusedBits :31; /*@}*/ } SDL_Overlay; @@ -314,11 +314,11 @@ /** * Return a pointer to an array of available screen dimensions for the - * given format and video flags, sorted largest to smallest. Returns - * NULL if there are no dimensions available for a particular format, + * given format and video flags, sorted largest to smallest. Returns + * NULL if there are no dimensions available for a particular format, * or (SDL_Rect **)-1 if any dimension is okay for the given format. * - * If 'format' is NULL, the mode list will be for the format given + * If 'format' is NULL, the mode list will be for the format given * by SDL_GetVideoInfo()->vfmt */ extern DECLSPEC SDL_Rect ** SDLCALL SDL_ListModes(SDL_PixelFormat *format, Uint32 flags); @@ -347,21 +347,21 @@ * Otherwise, in 8-bit mode, SDL_SetColors() may not be able to set all * of the colors exactly the way they are requested, and you should look * at the video surface structure to determine the actual palette. - * If SDL cannot guarantee that the colors you request can be set, + * If SDL cannot guarantee that the colors you request can be set, * i.e. if the colormap is shared, then the video surface may be created * under emulation in system memory, overriding the SDL_HWSURFACE flag. * * If SDL_FULLSCREEN is set in 'flags', the SDL library will try to set * a fullscreen video mode. The default is to create a windowed mode * if the current graphics system has a window manager. - * If the SDL library is able to set a fullscreen video mode, this flag + * If the SDL library is able to set a fullscreen video mode, this flag * will be set in the surface that is returned. * * If SDL_DOUBLEBUF is set in 'flags', the SDL library will try to set up - * two surfaces in video memory and swap between them when you call + * two surfaces in video memory and swap between them when you call * SDL_Flip(). This is usually slower than the normal single-buffering - * scheme, but prevents "tearing" artifacts caused by modifying video - * memory while the monitor is refreshing. It should only be used by + * scheme, but prevents "tearing" artifacts caused by modifying video + * memory while the monitor is refreshing. It should only be used by * applications that redraw the entire screen on every update. * * If SDL_RESIZABLE is set in 'flags', the SDL library will allow the @@ -382,7 +382,7 @@ * are not available. */ extern DECLSPEC SDL_Surface * SDLCALL SDL_SetVideoMode - (int width, int height, int bpp, Uint32 flags); + (int width, int height, int bpp, Uint32 flags); /** @name SDL_Update Functions * These functions should not be called while 'screen' is locked. @@ -392,13 +392,13 @@ * Makes sure the given list of rectangles is updated on the given screen. */ extern DECLSPEC void SDLCALL SDL_UpdateRects - (SDL_Surface *screen, int numrects, SDL_Rect *rects); + (SDL_Surface *screen, int numrects, SDL_Rect *rects); /** * If 'x', 'y', 'w' and 'h' are all 0, SDL_UpdateRect will update the entire * screen. */ extern DECLSPEC void SDLCALL SDL_UpdateRect - (SDL_Surface *screen, Sint32 x, Sint32 y, Uint32 w, Uint32 h); + (SDL_Surface *screen, Sint32 x, Sint32 y, Uint32 w, Uint32 h); /*@}*/ /** @@ -416,7 +416,7 @@ /** * Set the gamma correction for each of the color channels. * The gamma values range (approximately) between 0.1 and 10.0 - * + * * If this function isn't supported directly by the hardware, it will * be emulated using gamma ramps, if available. If successful, this * function returns 0, otherwise it returns -1. @@ -429,7 +429,7 @@ * representing a mapping between the input and output for that channel. * The input is the index into the array, and the output is the 16-bit * gamma value at that index, scaled to the output color precision. - * + * * You may pass NULL for any of the channels to leave it unchanged. * If the call succeeds, it will return 0. If the display driver or * hardware does not support gamma translation, or otherwise fails, @@ -439,7 +439,7 @@ /** * Retrieve the current values of the gamma translation tables. - * + * * You must pass in valid pointers to arrays of 256 16-bit quantities. * Any of the pointers may be NULL to ignore that channel. * If the call succeeds, it will return 0. If the display driver or @@ -457,14 +457,14 @@ * determine the actual color palette. * * When 'surface' is the surface associated with the current display, the - * display colormap will be updated with the requested colors. If + * display colormap will be updated with the requested colors. If * SDL_HWPALETTE was set in SDL_SetVideoMode() flags, SDL_SetColors() * will always return 1, and the palette is guaranteed to be set the way * you desire, even if the window colormap has to be warped or run under * emulation. */ -extern DECLSPEC int SDLCALL SDL_SetColors(SDL_Surface *surface, - SDL_Color *colors, int firstcolor, int ncolors); +extern DECLSPEC int SDLCALL SDL_SetColors(SDL_Surface *surface, + SDL_Color *colors, int firstcolor, int ncolors); /** * Sets a portion of the colormap for a given 8-bit surface. @@ -483,8 +483,8 @@ * flags = (SDL_LOGPAL|SDL_PHYSPAL). */ extern DECLSPEC int SDLCALL SDL_SetPalette(SDL_Surface *surface, int flags, - SDL_Color *colors, int firstcolor, - int ncolors); + SDL_Color *colors, int firstcolor, + int ncolors); /** * Maps an RGB triple to an opaque pixel value for a given pixel format @@ -504,15 +504,15 @@ * Maps a pixel value into the RGB components for a given pixel format */ extern DECLSPEC void SDLCALL SDL_GetRGB(Uint32 pixel, - const SDL_PixelFormat * const fmt, - Uint8 *r, Uint8 *g, Uint8 *b); + const SDL_PixelFormat * const fmt, + Uint8 *r, Uint8 *g, Uint8 *b); /** * Maps a pixel value into the RGBA components for a given pixel format */ extern DECLSPEC void SDLCALL SDL_GetRGBA(Uint32 pixel, - const SDL_PixelFormat * const fmt, - Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a); + const SDL_PixelFormat * const fmt, + Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a); /** @sa SDL_CreateRGBSurface */ #define SDL_AllocSurface SDL_CreateRGBSurface @@ -537,7 +537,7 @@ * two surfaces in video memory, SDL will try to place the surface in * video memory. If this isn't possible or if there is no hardware * acceleration available, the surface will be placed in system memory. - * SDL_SRCALPHA means that the surface will be used for alpha blits and + * SDL_SRCALPHA means that the surface will be used for alpha blits and * if the hardware supports hardware acceleration of alpha blits between * two surfaces in video memory, to place the surface in video memory * if possible, otherwise it will be placed in system memory. @@ -551,19 +551,19 @@ * the SDL_HWSURFACE flag set, and will be created in system memory instead. */ extern DECLSPEC SDL_Surface * SDLCALL SDL_CreateRGBSurface - (Uint32 flags, int width, int height, int depth, - Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask); + (Uint32 flags, int width, int height, int depth, + Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask); /** @sa SDL_CreateRGBSurface */ extern DECLSPEC SDL_Surface * SDLCALL SDL_CreateRGBSurfaceFrom(void *pixels, - int width, int height, int depth, int pitch, - Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask); + int width, int height, int depth, int pitch, + Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask); extern DECLSPEC void SDLCALL SDL_FreeSurface(SDL_Surface *surface); /** * SDL_LockSurface() sets up a surface for directly accessing the pixels. * Between calls to SDL_LockSurface()/SDL_UnlockSurface(), you can write - * to and read from 'surface->pixels', using the pixel format stored in - * 'surface->format'. Once you are done accessing the surface, you should + * to and read from 'surface->pixels', using the pixel format stored in + * 'surface->format'. Once you are done accessing the surface, you should * use SDL_UnlockSurface() to release it. * * Not all surfaces require locking. If SDL_MUSTLOCK(surface) evaluates @@ -571,7 +571,7 @@ * pixel format of the surface will not change. In particular, if the * SDL_HWSURFACE flag is not given when calling SDL_SetVideoMode(), you * will not need to lock the display surface before accessing it. - * + * * No operating system or library calls should be made between lock/unlock * pairs, as critical system locks may be held during this time. * @@ -589,7 +589,7 @@ extern DECLSPEC SDL_Surface * SDLCALL SDL_LoadBMP_RW(SDL_RWops *src, int freesrc); /** Convenience macro -- load a surface from a file */ -#define SDL_LoadBMP(file) SDL_LoadBMP_RW(SDL_RWFromFile(file, "rb"), 1) +#define SDL_LoadBMP(file) SDL_LoadBMP_RW(SDL_RWFromFile(file, "rb"), 1) /** * Save a surface to a seekable SDL data source (memory or file.) @@ -597,15 +597,15 @@ * Returns 0 if successful or -1 if there was an error. */ extern DECLSPEC int SDLCALL SDL_SaveBMP_RW - (SDL_Surface *surface, SDL_RWops *dst, int freedst); + (SDL_Surface *surface, SDL_RWops *dst, int freedst); /** Convenience macro -- save a surface to a file */ #define SDL_SaveBMP(surface, file) \ - SDL_SaveBMP_RW(surface, SDL_RWFromFile(file, "wb"), 1) + SDL_SaveBMP_RW(surface, SDL_RWFromFile(file, "wb"), 1) /** * Sets the color key (transparent pixel) in a blittable surface. - * If 'flag' is SDL_SRCCOLORKEY (optionally OR'd with SDL_RLEACCEL), + * If 'flag' is SDL_SRCCOLORKEY (optionally OR'd with SDL_RLEACCEL), * 'key' will be the transparent pixel in the source image of a blit. * SDL_RLEACCEL requests RLE acceleration for the surface if present, * and removes RLE acceleration if absent. @@ -613,7 +613,7 @@ * This function returns 0, or -1 if there was an error. */ extern DECLSPEC int SDLCALL SDL_SetColorKey - (SDL_Surface *surface, Uint32 flag, Uint32 key); + (SDL_Surface *surface, Uint32 flag, Uint32 key); /** * This function sets the alpha value for the entire surface, as opposed to @@ -654,11 +654,11 @@ extern DECLSPEC void SDLCALL SDL_GetClipRect(SDL_Surface *surface, SDL_Rect *rect); /** - * Creates a new surface of the specified format, and then copies and maps - * the given surface to it so the blit of the converted surface will be as + * Creates a new surface of the specified format, and then copies and maps + * the given surface to it so the blit of the converted surface will be as * fast as possible. If this function fails, it returns NULL. * - * The 'flags' parameter is passed to SDL_CreateRGBSurface() and has those + * The 'flags' parameter is passed to SDL_CreateRGBSurface() and has those * semantics. You can also pass SDL_RLEACCEL in the flags parameter and * SDL will try to RLE accelerate colorkey and alpha blits in the resulting * surface. @@ -666,7 +666,7 @@ * This function is used internally by SDL_DisplayFormat(). */ extern DECLSPEC SDL_Surface * SDLCALL SDL_ConvertSurface - (SDL_Surface *src, SDL_PixelFormat *fmt, Uint32 flags); + (SDL_Surface *src, SDL_PixelFormat *fmt, Uint32 flags); /** * This performs a fast blit from the source surface to the destination @@ -683,54 +683,54 @@ * * RGBA->RGB: * SDL_SRCALPHA set: - * alpha-blend (using alpha-channel). - * SDL_SRCCOLORKEY ignored. + * alpha-blend (using alpha-channel). + * SDL_SRCCOLORKEY ignored. * SDL_SRCALPHA not set: - * copy RGB. - * if SDL_SRCCOLORKEY set, only copy the pixels matching the - * RGB values of the source colour key, ignoring alpha in the - * comparison. - * + * copy RGB. + * if SDL_SRCCOLORKEY set, only copy the pixels matching the + * RGB values of the source colour key, ignoring alpha in the + * comparison. + * * RGB->RGBA: * SDL_SRCALPHA set: - * alpha-blend (using the source per-surface alpha value); - * set destination alpha to opaque. + * alpha-blend (using the source per-surface alpha value); + * set destination alpha to opaque. * SDL_SRCALPHA not set: - * copy RGB, set destination alpha to source per-surface alpha value. + * copy RGB, set destination alpha to source per-surface alpha value. * both: - * if SDL_SRCCOLORKEY set, only copy the pixels matching the - * source colour key. - * + * if SDL_SRCCOLORKEY set, only copy the pixels matching the + * source colour key. + * * RGBA->RGBA: * SDL_SRCALPHA set: - * alpha-blend (using the source alpha channel) the RGB values; - * leave destination alpha untouched. [Note: is this correct?] - * SDL_SRCCOLORKEY ignored. + * alpha-blend (using the source alpha channel) the RGB values; + * leave destination alpha untouched. [Note: is this correct?] + * SDL_SRCCOLORKEY ignored. * SDL_SRCALPHA not set: - * copy all of RGBA to the destination. - * if SDL_SRCCOLORKEY set, only copy the pixels matching the - * RGB values of the source colour key, ignoring alpha in the - * comparison. - * - * RGB->RGB: + * copy all of RGBA to the destination. + * if SDL_SRCCOLORKEY set, only copy the pixels matching the + * RGB values of the source colour key, ignoring alpha in the + * comparison. + * + * RGB->RGB: * SDL_SRCALPHA set: - * alpha-blend (using the source per-surface alpha value). + * alpha-blend (using the source per-surface alpha value). * SDL_SRCALPHA not set: - * copy RGB. + * copy RGB. * both: - * if SDL_SRCCOLORKEY set, only copy the pixels matching the - * source colour key. + * if SDL_SRCCOLORKEY set, only copy the pixels matching the + * source colour key. * * If either of the surfaces were in video memory, and the blit returns -2, - * the video memory was lost, so it should be reloaded with artwork and + * the video memory was lost, so it should be reloaded with artwork and * re-blitted: * @code - * while ( SDL_BlitSurface(image, imgrect, screen, dstrect) == -2 ) { - * while ( SDL_LockSurface(image) < 0 ) - * Sleep(10); - * -- Write image pixels to image->pixels -- - * SDL_UnlockSurface(image); - * } + * while ( SDL_BlitSurface(image, imgrect, screen, dstrect) == -2 ) { + * while ( SDL_LockSurface(image) < 0 ) + * Sleep(10); + * -- Write image pixels to image->pixels -- + * SDL_UnlockSurface(image); + * } * @endcode * * This happens under DirectX 5.0 when the system switches away from your @@ -746,26 +746,26 @@ * rectangle validation and clipping before passing it to SDL_LowerBlit() */ extern DECLSPEC int SDLCALL SDL_UpperBlit - (SDL_Surface *src, SDL_Rect *srcrect, - SDL_Surface *dst, SDL_Rect *dstrect); + (SDL_Surface *src, SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect); /** This is a semi-private blit function and it performs low-level surface * blitting only. */ extern DECLSPEC int SDLCALL SDL_LowerBlit - (SDL_Surface *src, SDL_Rect *srcrect, - SDL_Surface *dst, SDL_Rect *dstrect); + (SDL_Surface *src, SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect); /** * This function performs a fast fill of the given rectangle with 'color' * The given rectangle is clipped to the destination surface clip area * and the final fill rectangle is saved in the passed in pointer. * If 'dstrect' is NULL, the whole surface will be filled with 'color' - * The color should be a pixel of the format used by the surface, and + * The color should be a pixel of the format used by the surface, and * can be generated by the SDL_MapRGB() function. * This function returns 0 on success, or -1 on error. */ extern DECLSPEC int SDLCALL SDL_FillRect - (SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color); + (SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color); /** * This function takes a surface and copies it to a new surface of the @@ -805,7 +805,7 @@ * is shown is undefined - it may be overwritten with the converted YUV data. */ extern DECLSPEC SDL_Overlay * SDLCALL SDL_CreateYUVOverlay(int width, int height, - Uint32 format, SDL_Surface *display); + Uint32 format, SDL_Surface *display); /** Lock an overlay for direct access, and unlock it when you are done */ extern DECLSPEC int SDLCALL SDL_LockYUVOverlay(SDL_Overlay *overlay); @@ -813,7 +813,7 @@ /** Blit a video overlay to the display surface. * The contents of the video surface underneath the blit destination are - * not defined. + * not defined. * The width and height of the destination rectangle may be different from * that of the overlay, but currently only 2x scaling is supported. */ @@ -908,7 +908,7 @@ * If the display surface does not require locking before accessing * the pixel information, then the memory pointers will not change. * - * If this function was able to toggle fullscreen mode (change from + * If this function was able to toggle fullscreen mode (change from * running in a window to fullscreen, or vice-versa), it will return 1. * If it is not implemented, or fails, it returns 0. * @@ -921,10 +921,10 @@ extern DECLSPEC int SDLCALL SDL_WM_ToggleFullScreen(SDL_Surface *surface); typedef enum { - SDL_GRAB_QUERY = -1, - SDL_GRAB_OFF = 0, - SDL_GRAB_ON = 1, - SDL_GRAB_FULLSCREEN /**< Used internally */ + SDL_GRAB_QUERY = -1, + SDL_GRAB_OFF = 0, + SDL_GRAB_ON = 1, + SDL_GRAB_FULLSCREEN /**< Used internally */ } SDL_GrabMode; /** * This function allows you to set and query the input grab state of @@ -941,7 +941,7 @@ /** @internal Not in public API at the moment - do not use! */ extern DECLSPEC int SDLCALL SDL_SoftStretch(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect); - + /* Ends C function definitions when using C++ */ #ifdef __cplusplus } diff -r 4feced261c68 -r de822cd3df3a misc/winutils/include/begin_code.h --- a/misc/winutils/include/begin_code.h Tue Jan 21 22:38:13 2014 +0100 +++ b/misc/winutils/include/begin_code.h Tue Jan 21 22:43:06 2014 +0100 @@ -20,14 +20,14 @@ slouken@libsdl.org */ -/** +/** * @file begin_code.h * This file sets things up for C dynamic library function definitions, * static inlined functions, and structures aligned at 4-byte alignment. * If you don't like ugly C preprocessor code, don't look at this file. :) */ -/** +/** * @file begin_code.h * This shouldn't be nested -- included it around code only. */ @@ -36,7 +36,7 @@ #endif #define _begin_code_h -/** +/** * @def DECLSPEC * Some compilers use a special export keyword */ @@ -45,22 +45,22 @@ # if defined(__GNUC__) # define DECLSPEC # else -# define DECLSPEC __declspec(export) +# define DECLSPEC __declspec(export) # endif # elif defined(__WIN32__) # ifdef __BORLANDC__ # ifdef BUILD_SDL -# define DECLSPEC +# define DECLSPEC # else -# define DECLSPEC __declspec(dllimport) +# define DECLSPEC __declspec(dllimport) # endif # else -# define DECLSPEC __declspec(dllexport) +# define DECLSPEC __declspec(dllexport) # endif # elif defined(__OS2__) # ifdef __WATCOMC__ # ifdef BUILD_SDL -# define DECLSPEC __declspec(dllexport) +# define DECLSPEC __declspec(dllexport) # else # define DECLSPEC # endif @@ -78,14 +78,14 @@ # endif # else # if defined(__GNUC__) && __GNUC__ >= 4 -# define DECLSPEC __attribute__ ((visibility("default"))) +# define DECLSPEC __attribute__ ((visibility("default"))) # else # define DECLSPEC # endif # endif #endif -/** +/** * @def SDLCALL * By default SDL uses the C calling convention */ @@ -108,8 +108,8 @@ # endif #endif /* SDLCALL */ -#ifdef __SYMBIAN32__ -#ifndef EKA2 +#ifdef __SYMBIAN32__ +#ifndef EKA2 #undef DECLSPEC #define DECLSPEC #elif !defined(__WINS__) @@ -123,7 +123,7 @@ * Force structure packing at 4 byte alignment. * This is necessary if the header is included in code which has structure * packing set to an alternate value, say for loading structures from disk. - * The packing is reset to the previous value in close_code.h + * The packing is reset to the previous value in close_code.h */ #if defined(_MSC_VER) || defined(__MWERKS__) || defined(__BORLANDC__) #ifdef _MSC_VER @@ -157,7 +157,7 @@ defined(__WATCOMC__) || defined(__LCC__) || \ defined(__DECC) || defined(__EABI__) #ifndef __inline__ -#define __inline__ __inline +#define __inline__ __inline #endif #define SDL_INLINE_OKAY #else diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/AndroidManifest.xml --- a/project_files/Android-build/SDL-android-project/AndroidManifest.xml Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/AndroidManifest.xml Tue Jan 21 22:43:06 2014 +0100 @@ -46,7 +46,7 @@ android:theme="@android:style/Theme.NoTitleBar.Fullscreen" /> - + GetStaticMethodID(mActivityClass, "flipBuffers","()V"); - midAudioInit = mEnv->GetStaticMethodID(mActivityClass, + midAudioInit = mEnv->GetStaticMethodID(mActivityClass, "audioInit", "(IZZI)Ljava/lang/Object;"); midAudioWriteShortBuffer = mEnv->GetStaticMethodID(mActivityClass, "audioWriteShortBuffer", "([S)V"); @@ -165,7 +165,7 @@ // Quit extern "C" void Java_org_hedgewars_hedgeroid_SDLActivity_nativeQuit( JNIEnv* env, jclass cls) -{ +{ // Inject a SDL_QUIT event SDL_SendQuit(); } @@ -214,7 +214,7 @@ extern "C" void Android_JNI_SwapWindow() { - mEnv->CallStaticVoidMethod(mActivityClass, midFlipBuffers); + mEnv->CallStaticVoidMethod(mActivityClass, midFlipBuffers); } extern "C" void Android_JNI_SetActivityTitle(const char *title) @@ -257,7 +257,7 @@ int status; JNIEnv *env; - static bool isAttached = false; + static bool isAttached = false; status = mJavaVM->GetEnv((void **) &env, JNI_VERSION_1_4); if(status < 0) { LOGE("callback_handler: failed to get JNI environment, assuming native thread"); @@ -269,7 +269,7 @@ isAttached = true; } - + __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device"); audioBuffer16Bit = is16Bit; audioBufferStereo = channelCount > 1; @@ -293,7 +293,7 @@ if (audioBufferStereo) { audioBufferFrames /= 2; } - + if (isAttached) { mJavaVM->DetachCurrentThread(); } @@ -323,7 +323,7 @@ { int status; JNIEnv *env; - static bool isAttached = false; + static bool isAttached = false; status = mJavaVM->GetEnv((void **) &env, JNI_VERSION_1_4); if(status < 0) { LOGE("callback_handler: failed to get JNI environment, assuming native thread"); @@ -335,7 +335,7 @@ isAttached = true; } - env->CallStaticVoidMethod(mActivityClass, midAudioQuit); + env->CallStaticVoidMethod(mActivityClass, midAudioQuit); if (audioBuffer) { env->DeleteGlobalRef(audioBuffer); diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/jni/SDL/src/file/SDL_rwops.c --- a/project_files/Android-build/SDL-android-project/jni/SDL/src/file/SDL_rwops.c Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/jni/SDL/src/file/SDL_rwops.c Tue Jan 21 22:43:06 2014 +0100 @@ -45,7 +45,7 @@ /* Functions to read/write Win32 API file pointers */ /* Will not use it on WinCE because stdio is buffered, it means - faster, and all stdio functions anyway are embedded in coredll.dll - + faster, and all stdio functions anyway are embedded in coredll.dll - the main wince dll*/ #include "../core/windows/SDL_windows.h" @@ -54,7 +54,7 @@ #define INVALID_SET_FILE_POINTER 0xFFFFFFFF #endif -#define READAHEAD_BUFFER_SIZE 1024 +#define READAHEAD_BUFFER_SIZE 1024 static int SDLCALL windows_file_open(SDL_RWops * context, const char *filename, const char *mode) @@ -473,12 +473,12 @@ rwops->close = windows_file_close; #elif HAVE_STDIO_H - #ifdef __APPLE__ - fp = SDL_OpenFPFromBundleOrFallback(file, mode); + #ifdef __APPLE__ + fp = SDL_OpenFPFromBundleOrFallback(file, mode); #else - fp = fopen(file, mode); - #endif - if (fp == NULL) { + fp = fopen(file, mode); + #endif + if (fp == NULL) { SDL_SetError("Couldn't open %s", file); } else { rwops = SDL_RWFromFP(fp, 1); diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/jni/SDL/src/main/android/SDL_android_main.cpp --- a/project_files/Android-build/SDL-android-project/jni/SDL/src/main/android/SDL_android_main.cpp Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/jni/SDL/src/main/android/SDL_android_main.cpp Tue Jan 21 22:43:06 2014 +0100 @@ -27,19 +27,19 @@ char *argv[argc]; jstring jstringArgv[argc]; for(int i = 0; i < argc; i++){ - jstringArgv[i] = (jstring)env->GetObjectArrayElement(strArray, i); //get the element - argv[i] = (char*)malloc(env->GetStringUTFLength(jstringArgv[i]) + 1); - const char *str = env->GetStringUTFChars(jstringArgv[i], NULL); - strcpy(argv[i], str); //copy it to a mutable location - env->ReleaseStringUTFChars(jstringArgv[i], str); + jstringArgv[i] = (jstring)env->GetObjectArrayElement(strArray, i); //get the element + argv[i] = (char*)malloc(env->GetStringUTFLength(jstringArgv[i]) + 1); + const char *str = env->GetStringUTFChars(jstringArgv[i], NULL); + strcpy(argv[i], str); //copy it to a mutable location + env->ReleaseStringUTFChars(jstringArgv[i], str); } - + /* Run the application code! */ int status = SDL_main(argc, argv); //Clean up argv for(int i = 0; i < argc; i++){ - free(argv[i]); + free(argv[i]); } } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/jni/SDL_mixer/Android.mk --- a/project_files/Android-build/SDL-android-project/jni/SDL_mixer/Android.mk Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/jni/SDL_mixer/Android.mk Tue Jan 21 22:43:06 2014 +0100 @@ -5,9 +5,9 @@ LOCAL_MODULE := SDL_mixer LOCAL_C_INCLUDES := \ - $(LOCAL_PATH)/.. \ - $(LOCAL_PATH)/../SDL/include \ - $(LOCAL_PATH)/../mikmod/include \ + $(LOCAL_PATH)/.. \ + $(LOCAL_PATH)/../SDL/include \ + $(LOCAL_PATH)/../mikmod/include \ LOCAL_CFLAGS := -DWAV_MUSIC -DOGG_MUSIC -DOGG_USE_TREMOR -DMOD_MUSIC diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/jni/jnidispatch/Android.mk --- a/project_files/Android-build/SDL-android-project/jni/jnidispatch/Android.mk Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/jni/jnidispatch/Android.mk Tue Jan 21 22:43:06 2014 +0100 @@ -1,6 +1,6 @@ -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) -LOCAL_MODULE := libjnidispatch -LOCAL_SRC_FILES := libjnidispatch.so +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) +LOCAL_MODULE := libjnidispatch +LOCAL_SRC_FILES := libjnidispatch.so include $(PREBUILT_SHARED_LIBRARY) \ No newline at end of file diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/jni/src/Android.mk --- a/project_files/Android-build/SDL-android-project/jni/src/Android.mk Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/jni/src/Android.mk Tue Jan 21 22:43:06 2014 +0100 @@ -7,7 +7,7 @@ LOCAL_C_INCLUDES := $(LOCAL_PATH)/../SDL/include # Add your application source files here... -LOCAL_SRC_FILES := ../SDL/src/main/android/SDL_android_main.cpp hedgewars_main.c +LOCAL_SRC_FILES := ../SDL/src/main/android/SDL_android_main.cpp hedgewars_main.c LOCAL_SHARED_LIBRARIES := SDL diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/jni/src/hedgewars_main.c --- a/project_files/Android-build/SDL-android-project/jni/src/hedgewars_main.c Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/jni/src/hedgewars_main.c Tue Jan 21 22:43:06 2014 +0100 @@ -10,32 +10,32 @@ typedef (*HWEngine_Game)(int32_t argc, char** argv); main(int argc, char *argv[]){ - void *handle; - char *error; - HWEngine_Game Game; - + void *handle; + char *error; + HWEngine_Game Game; + __android_log_print(ANDROID_LOG_INFO, TAG, "HWEngine being loaded"); - handle = dlopen("libhwengine.so", RTLD_NOW|RTLD_GLOBAL); - if(!handle){ - __android_log_print(ANDROID_LOG_INFO, TAG, dlerror()); - __android_log_print(ANDROID_LOG_INFO, TAG, "error dlopen"); - exit(EXIT_FAILURE); - } - dlerror(); + handle = dlopen("libhwengine.so", RTLD_NOW|RTLD_GLOBAL); + if(!handle){ + __android_log_print(ANDROID_LOG_INFO, TAG, dlerror()); + __android_log_print(ANDROID_LOG_INFO, TAG, "error dlopen"); + exit(EXIT_FAILURE); + } + dlerror(); __android_log_print(ANDROID_LOG_INFO, TAG, "HWEngine successfully loaded.."); - Game = (HWEngine_Game) dlsym(handle,"Game"); - if((error = dlerror()) != NULL){ - __android_log_print(ANDROID_LOG_INFO, TAG, error); - __android_log_print(ANDROID_LOG_INFO, TAG, "error dlsym"); - exit(EXIT_FAILURE); - } - __android_log_print(ANDROID_LOG_INFO, TAG, "dlsym succeeded"); - Game(argc, argv); - __android_log_print(ANDROID_LOG_INFO, TAG, "Game() ended"); + Game = (HWEngine_Game) dlsym(handle,"Game"); + if((error = dlerror()) != NULL){ + __android_log_print(ANDROID_LOG_INFO, TAG, error); + __android_log_print(ANDROID_LOG_INFO, TAG, "error dlsym"); + exit(EXIT_FAILURE); + } + __android_log_print(ANDROID_LOG_INFO, TAG, "dlsym succeeded"); + Game(argc, argv); + __android_log_print(ANDROID_LOG_INFO, TAG, "Game() ended"); - dlclose(handle); + dlclose(handle); } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/res/raw/team_one.hwt --- a/project_files/Android-build/SDL-android-project/res/raw/team_one.hwt Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/res/raw/team_one.hwt Tue Jan 21 22:43:06 2014 +0100 @@ -1,74 +1,74 @@ -[Team] -Name=Team 1 -Grave=Bone -Fort=Lego -Voicepack=Classic -Flag=hedgewars -Difficulty=0 -Rounds=0 -Wins=0 -CampaignProgress=0 - -[Hedgehog0] -Name=Leonidas -Hat=NoHat -Rounds=0 -Kills=0 -Deaths=0 -Suicides=0 - -[Hedgehog1] -Name=Pipo -Hat=NoHat -Rounds=0 -Kills=0 -Deaths=0 -Suicides=0 - -[Hedgehog2] -Name=Sonic -Hat=NoHat -Rounds=0 -Kills=0 -Deaths=0 -Suicides=0 - -[Hedgehog3] -Name=Xin -Hat=NoHat -Rounds=0 -Kills=0 -Deaths=0 -Suicides=0 - -[Hedgehog4] -Name=Arnold -Hat=NoHat -Rounds=0 -Kills=0 -Deaths=0 -Suicides=0 - -[Hedgehog5] -Name=Jack -Hat=NoHat -Rounds=0 -Kills=0 -Deaths=0 -Suicides=0 - -[Hedgehog6] -Name=Tom -Hat=NoHat -Rounds=0 -Kills=0 -Deaths=0 -Suicides=0 - -[Hedgehog7] -Name=Goldie -Hat=NoHat -Rounds=0 -Kills=0 -Deaths=0 -Suicides=0 +[Team] +Name=Team 1 +Grave=Bone +Fort=Lego +Voicepack=Classic +Flag=hedgewars +Difficulty=0 +Rounds=0 +Wins=0 +CampaignProgress=0 + +[Hedgehog0] +Name=Leonidas +Hat=NoHat +Rounds=0 +Kills=0 +Deaths=0 +Suicides=0 + +[Hedgehog1] +Name=Pipo +Hat=NoHat +Rounds=0 +Kills=0 +Deaths=0 +Suicides=0 + +[Hedgehog2] +Name=Sonic +Hat=NoHat +Rounds=0 +Kills=0 +Deaths=0 +Suicides=0 + +[Hedgehog3] +Name=Xin +Hat=NoHat +Rounds=0 +Kills=0 +Deaths=0 +Suicides=0 + +[Hedgehog4] +Name=Arnold +Hat=NoHat +Rounds=0 +Kills=0 +Deaths=0 +Suicides=0 + +[Hedgehog5] +Name=Jack +Hat=NoHat +Rounds=0 +Kills=0 +Deaths=0 +Suicides=0 + +[Hedgehog6] +Name=Tom +Hat=NoHat +Rounds=0 +Kills=0 +Deaths=0 +Suicides=0 + +[Hedgehog7] +Name=Goldie +Hat=NoHat +Rounds=0 +Kills=0 +Deaths=0 +Suicides=0 diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/res/raw/team_two.hwt --- a/project_files/Android-build/SDL-android-project/res/raw/team_two.hwt Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/res/raw/team_two.hwt Tue Jan 21 22:43:06 2014 +0100 @@ -1,74 +1,74 @@ -[Team] -Name=Team 2 -Grave=Bone -Fort=Lego -Voicepack=Classic -Flag=cm_binary -Difficulty=2 -Rounds=0 -Wins=0 -CampaignProgress=0 - -[Hedgehog0] -Name=Paris -Hat=NoHat -Rounds=0 -Kills=0 -Deaths=0 -Suicides=0 - -[Hedgehog1] -Name=Knut -Hat=NoHat -Rounds=0 -Kills=0 -Deaths=0 -Suicides=0 - -[Hedgehog2] -Name=Ash -Hat=NoHat -Rounds=0 -Kills=0 -Deaths=0 -Suicides=0 - -[Hedgehog3] -Name=Woad -Hat=NoHat -Rounds=0 -Kills=0 -Deaths=0 -Suicides=0 - -[Hedgehog4] -Name=Bob -Hat=NoHat -Rounds=0 -Kills=0 -Deaths=0 -Suicides=0 - -[Hedgehog5] -Name=Corky -Hat=NoHat -Rounds=0 -Kills=0 -Deaths=0 -Suicides=0 - -[Hedgehog6] -Name=Bea -Hat=NoHat -Rounds=0 -Kills=0 -Deaths=0 -Suicides=0 - -[Hedgehog7] -Name=Silvia -Hat=NoHat -Rounds=0 -Kills=0 -Deaths=0 -Suicides=0 +[Team] +Name=Team 2 +Grave=Bone +Fort=Lego +Voicepack=Classic +Flag=cm_binary +Difficulty=2 +Rounds=0 +Wins=0 +CampaignProgress=0 + +[Hedgehog0] +Name=Paris +Hat=NoHat +Rounds=0 +Kills=0 +Deaths=0 +Suicides=0 + +[Hedgehog1] +Name=Knut +Hat=NoHat +Rounds=0 +Kills=0 +Deaths=0 +Suicides=0 + +[Hedgehog2] +Name=Ash +Hat=NoHat +Rounds=0 +Kills=0 +Deaths=0 +Suicides=0 + +[Hedgehog3] +Name=Woad +Hat=NoHat +Rounds=0 +Kills=0 +Deaths=0 +Suicides=0 + +[Hedgehog4] +Name=Bob +Hat=NoHat +Rounds=0 +Kills=0 +Deaths=0 +Suicides=0 + +[Hedgehog5] +Name=Corky +Hat=NoHat +Rounds=0 +Kills=0 +Deaths=0 +Suicides=0 + +[Hedgehog6] +Name=Bea +Hat=NoHat +Rounds=0 +Kills=0 +Deaths=0 +Suicides=0 + +[Hedgehog7] +Name=Silvia +Hat=NoHat +Rounds=0 +Kills=0 +Deaths=0 +Suicides=0 diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/res/raw/weapons_builtin.ini --- a/project_files/Android-build/SDL-android-project/res/raw/weapons_builtin.ini Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/res/raw/weapons_builtin.ini Tue Jan 21 22:43:06 2014 +0100 @@ -1,8 +1,8 @@ -[General] -%44efault=9391929422199121032235111001201000000211110101011111011040504054160065554655446477657666666615551010111541101100000000000002055000000400070040000000002200000006000001311110312111111123114111111111111111211111101111111010 -%43razy=9999999999999999992999999999999999299999999909999992099111111011111111111111111111111111111111111110111111101100000000000000000000000000000000000000000000000000000001311110312111111123114111111111111111211110101111111011 -%50ro%20%4dode=9090009000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002055000000400070040000000002000000000000001111111111111111111111111111111111111111100101111111011 -%53hoppa=0000009900000000000000000000000000000000000000000000000444441004424440221011212122242200000000200040001001100000000000000000000000000000000000000000000000000000000001111111111111111111111111111111111111111101101111111001 -%43lean%20%53late=1010009000010000011000000000000000000000000000001000000040504054160065554655446477657666666615551010111541101100000000000000000000000000000000000000000000000000000001311110312111111123114111111111111111211111101111111011 -%4dinefield=0000009900090000000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002055000000400070040000000002000000006000001111111111111111111111111111111111111111111101111111011 -%54hinking%20with%20%50ortals=9000009002000000002100000000000000110000090000000000000040504054160065554655446477657666666615551010111541101100000000000002055000000400070040000000002000000006000001311110312111111123114111111111111111211111101111111011 +[General] +%44efault=9391929422199121032235111001201000000211110101011111011040504054160065554655446477657666666615551010111541101100000000000002055000000400070040000000002200000006000001311110312111111123114111111111111111211111101111111010 +%43razy=9999999999999999992999999999999999299999999909999992099111111011111111111111111111111111111111111110111111101100000000000000000000000000000000000000000000000000000001311110312111111123114111111111111111211110101111111011 +%50ro%20%4dode=9090009000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002055000000400070040000000002000000000000001111111111111111111111111111111111111111100101111111011 +%53hoppa=0000009900000000000000000000000000000000000000000000000444441004424440221011212122242200000000200040001001100000000000000000000000000000000000000000000000000000000001111111111111111111111111111111111111111101101111111001 +%43lean%20%53late=1010009000010000011000000000000000000000000000001000000040504054160065554655446477657666666615551010111541101100000000000000000000000000000000000000000000000000000001311110312111111123114111111111111111211111101111111011 +%4dinefield=0000009900090000000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002055000000400070040000000002000000006000001111111111111111111111111111111111111111111101111111011 +%54hinking%20with%20%50ortals=9000009002000000002100000000000000110000090000000000000040504054160065554655446477657666666615551010111541101100000000000002055000000400070040000000002000000006000001311110312111111123114111111111111111211111101111111011 diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/BasicRoomState.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/BasicRoomState.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/BasicRoomState.java Tue Jan 21 22:43:06 2014 +0100 @@ -37,125 +37,125 @@ * Common base implementation for a roomstate that will call listeners on every * change. The derived classes have to coordinate how state is changed to * complete the implementation of the RoomStateManager interface. - * + * * See {@link RoomStateManager} for a description of what this is for. */ public abstract class BasicRoomState implements RoomStateManager { - private final List observers = new LinkedList(); - - private boolean chief; - private String gameStyle; - private Scheme scheme; - private MapRecipe map; - private Weaponset weaponset; - private Map teams = Collections.emptyMap(); - - public final MapRecipe getMapRecipe() { - return map; - } + private final List observers = new LinkedList(); + + private boolean chief; + private String gameStyle; + private Scheme scheme; + private MapRecipe map; + private Weaponset weaponset; + private Map teams = Collections.emptyMap(); + + public final MapRecipe getMapRecipe() { + return map; + } + + public final boolean getChiefStatus() { + return chief; + } + + public final Scheme getScheme() { + return scheme; + } + + public final String getGameStyle() { + return gameStyle; + } - public final boolean getChiefStatus() { - return chief; - } + public final Weaponset getWeaponset() { + return weaponset; + } + + public final Map getTeams() { + return teams; + } - public final Scheme getScheme() { - return scheme; - } + public final void setWeaponset(Weaponset weaponset) { + if(!equal(weaponset, this.weaponset)) { + this.weaponset = weaponset; + for(RoomStateManager.Listener observer : observers) { + observer.onWeaponsetChanged(weaponset); + } + } + } - public final String getGameStyle() { - return gameStyle; - } + public final void setMapRecipe(MapRecipe map) { + if(!equal(map, this.map)) { + this.map = map; + for(RoomStateManager.Listener observer : observers) { + observer.onMapChanged(map); + } + } + } - public final Weaponset getWeaponset() { - return weaponset; - } - - public final Map getTeams() { - return teams; - } - - public final void setWeaponset(Weaponset weaponset) { - if(!equal(weaponset, this.weaponset)) { - this.weaponset = weaponset; - for(RoomStateManager.Listener observer : observers) { - observer.onWeaponsetChanged(weaponset); - } - } - } - - public final void setMapRecipe(MapRecipe map) { - if(!equal(map, this.map)) { - this.map = map; - for(RoomStateManager.Listener observer : observers) { - observer.onMapChanged(map); - } - } - } - - public final void setGameStyle(String gameStyle) { - if(!equal(gameStyle, this.gameStyle)) { - this.gameStyle = gameStyle; - for(RoomStateManager.Listener observer : observers) { - observer.onGameStyleChanged(gameStyle); - } - } - } - - public final void setScheme(Scheme scheme) { - if(!equal(scheme, this.scheme)) { - this.scheme = scheme; - for(RoomStateManager.Listener observer : observers) { - observer.onSchemeChanged(scheme); - } - } - } - - public final void setChief(boolean chief) { - if(chief != this.chief) { - this.chief = chief; - for(RoomStateManager.Listener observer : observers) { - observer.onChiefStatusChanged(chief); - } - } - } - - public final void putTeam(TeamInGame team) { - TeamInGame oldEntry = teams.get(team.team.name); - if(!equal(team, oldEntry)) { - Map changedMap = new TreeMap(teams); - changedMap.put(team.team.name, team); - teams = Collections.unmodifiableMap(changedMap); - for(RoomStateManager.Listener observer : observers) { - observer.onTeamsChanged(teams); - } - } - } - - public final void removeTeam(String teamname) { - if(teams.containsKey(teamname)) { - Map changedMap = new TreeMap(teams); - changedMap.remove(teamname); - teams = Collections.unmodifiableMap(changedMap); - for(RoomStateManager.Listener observer : observers) { - observer.onTeamsChanged(teams); - } - } - } - - public final void setTeams(Map newTeams) { - if(!newTeams.equals(teams)) { - teams = Collections.unmodifiableMap(new TreeMap(newTeams)); - for(RoomStateManager.Listener observer : observers) { - observer.onTeamsChanged(teams); - } - } - } - - public final void addListener(Listener observer) { - observers.add(observer); - } + public final void setGameStyle(String gameStyle) { + if(!equal(gameStyle, this.gameStyle)) { + this.gameStyle = gameStyle; + for(RoomStateManager.Listener observer : observers) { + observer.onGameStyleChanged(gameStyle); + } + } + } + + public final void setScheme(Scheme scheme) { + if(!equal(scheme, this.scheme)) { + this.scheme = scheme; + for(RoomStateManager.Listener observer : observers) { + observer.onSchemeChanged(scheme); + } + } + } + + public final void setChief(boolean chief) { + if(chief != this.chief) { + this.chief = chief; + for(RoomStateManager.Listener observer : observers) { + observer.onChiefStatusChanged(chief); + } + } + } - public final void removeListener(Listener observer) { - observers.remove(observer); - } + public final void putTeam(TeamInGame team) { + TeamInGame oldEntry = teams.get(team.team.name); + if(!equal(team, oldEntry)) { + Map changedMap = new TreeMap(teams); + changedMap.put(team.team.name, team); + teams = Collections.unmodifiableMap(changedMap); + for(RoomStateManager.Listener observer : observers) { + observer.onTeamsChanged(teams); + } + } + } + + public final void removeTeam(String teamname) { + if(teams.containsKey(teamname)) { + Map changedMap = new TreeMap(teams); + changedMap.remove(teamname); + teams = Collections.unmodifiableMap(changedMap); + for(RoomStateManager.Listener observer : observers) { + observer.onTeamsChanged(teams); + } + } + } + + public final void setTeams(Map newTeams) { + if(!newTeams.equals(teams)) { + teams = Collections.unmodifiableMap(new TreeMap(newTeams)); + for(RoomStateManager.Listener observer : observers) { + observer.onTeamsChanged(teams); + } + } + } + + public final void addListener(Listener observer) { + observers.add(observer); + } + + public final void removeListener(Listener observer) { + observers.remove(observer); + } } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/ChatFragment.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/ChatFragment.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/ChatFragment.java Tue Jan 21 22:43:06 2014 +0100 @@ -39,61 +39,61 @@ * the lobby or a room. */ public class ChatFragment extends Fragment { - private ChatlogAdapter adapter; - private Netplay netplay; - private MessageLog messageLog; - private boolean inRoom; - - public void setInRoom(boolean inRoom) { - this.inRoom = inRoom; - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - netplay = Netplay.getAppInstance(getActivity().getApplicationContext()); - adapter = new ChatlogAdapter(getActivity()); - } - - @Override - public void onStart() { - super.onStart(); - messageLog = inRoom ? netplay.roomChatlog : netplay.lobbyChatlog; - adapter.setLog(messageLog.getLog()); - messageLog.addListener(adapter); - } - - @Override - public void onStop() { - super.onStop(); - messageLog.removeListener(adapter); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.fragment_chat, container, false); - - ListView listView = (ListView) view.findViewById(R.id.chatConsole); - listView.setAdapter(adapter); - listView.setDivider(null); - listView.setDividerHeight(0); - listView.setVerticalFadingEdgeEnabled(true); - - EditText editText = (EditText) view.findViewById(R.id.chatInput); + private ChatlogAdapter adapter; + private Netplay netplay; + private MessageLog messageLog; + private boolean inRoom; + + public void setInRoom(boolean inRoom) { + this.inRoom = inRoom; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + netplay = Netplay.getAppInstance(getActivity().getApplicationContext()); + adapter = new ChatlogAdapter(getActivity()); + } + + @Override + public void onStart() { + super.onStart(); + messageLog = inRoom ? netplay.roomChatlog : netplay.lobbyChatlog; + adapter.setLog(messageLog.getLog()); + messageLog.addListener(adapter); + } + + @Override + public void onStop() { + super.onStop(); + messageLog.removeListener(adapter); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_chat, container, false); + + ListView listView = (ListView) view.findViewById(R.id.chatConsole); + listView.setAdapter(adapter); + listView.setDivider(null); + listView.setDividerHeight(0); + listView.setVerticalFadingEdgeEnabled(true); + + EditText editText = (EditText) view.findViewById(R.id.chatInput); editText.setOnEditorActionListener(new ChatSendListener()); - - return view; - } - - private final class ChatSendListener implements OnEditorActionListener { - public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { - String text = v.getText().toString(); - if(text.length()>0) { - v.setText(""); - netplay.sendChat(text); - } - return true; - } - } + + return view; + } + + private final class ChatSendListener implements OnEditorActionListener { + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + String text = v.getText().toString(); + if(text.length()>0) { + v.setText(""); + netplay.sendChat(text); + } + return true; + } + } } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/ChatlogAdapter.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/ChatlogAdapter.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/ChatlogAdapter.java Tue Jan 21 22:43:06 2014 +0100 @@ -39,14 +39,14 @@ * Since lines with a given ID never change in our chatlog, we can avoid the effort * of TextView.setText in many cases by checking if the view is already set up for the * line with the right ID - but to do that, the view needs to remember the ID it's - * holding the text for. That's what the LoglineView does. + * holding the text for. That's what the LoglineView does. */ class LoglineView extends TextView { - long chatlogId = -1; - - public LoglineView(Context context) { - super(context); - } + long chatlogId = -1; + + public LoglineView(Context context) { + super(context); + } } /** @@ -57,65 +57,65 @@ * the textviews from a messagelog in an efficient way. */ public class ChatlogAdapter extends BaseAdapter implements MessageLog.Listener { - long idOffset = 0; - private List log = new ArrayList(); - private Context context; - - public ChatlogAdapter(Context context) { - this.context = context; - } - - public int getCount() { - return log.size(); - } + long idOffset = 0; + private List log = new ArrayList(); + private Context context; + + public ChatlogAdapter(Context context) { + this.context = context; + } + + public int getCount() { + return log.size(); + } - public Object getItem(int position) { - return log.get(position); - } + public Object getItem(int position) { + return log.get(position); + } + + public long getItemId(int position) { + return position+idOffset; + } - public long getItemId(int position) { - return position+idOffset; - } + public boolean hasStableIds() { + return true; + } - public boolean hasStableIds() { - return true; - } + public void clear() { + idOffset += log.size(); + log.clear(); + notifyDataSetChanged(); + } - public void clear() { - idOffset += log.size(); - log.clear(); - notifyDataSetChanged(); - } - - public void lineAdded(CharSequence text) { - log.add(text); - notifyDataSetChanged(); - } - - public void lineRemoved() { - log.remove(0); - idOffset += 1; - notifyDataSetChanged(); - } - - public void setLog(Collection log) { - idOffset += log.size(); - this.log = new ArrayList(log); - notifyDataSetChanged(); - } - - public View getView(int position, View convertView, ViewGroup parent) { - LoglineView v = (LoglineView)convertView; - if (v == null) { - v = new LoglineView(context); - v.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT)); - v.setMovementMethod(LinkMovementMethod.getInstance()); - } - long id = getItemId(position); - if(id != v.chatlogId) { - v.setText(log.get(position)); - v.chatlogId = id; - } - return v; - } + public void lineAdded(CharSequence text) { + log.add(text); + notifyDataSetChanged(); + } + + public void lineRemoved() { + log.remove(0); + idOffset += 1; + notifyDataSetChanged(); + } + + public void setLog(Collection log) { + idOffset += log.size(); + this.log = new ArrayList(log); + notifyDataSetChanged(); + } + + public View getView(int position, View convertView, ViewGroup parent) { + LoglineView v = (LoglineView)convertView; + if (v == null) { + v = new LoglineView(context); + v.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT)); + v.setMovementMethod(LinkMovementMethod.getInstance()); + } + long id = getItemId(position); + if(id != v.chatlogId) { + v.setText(log.get(position)); + v.chatlogId = id; + } + return v; + } } \ No newline at end of file diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/ConnectingDialog.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/ConnectingDialog.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/ConnectingDialog.java Tue Jan 21 22:43:06 2014 +0100 @@ -37,58 +37,58 @@ * Indeterminate progress dialog that is shown in the MainActivity while trying * to connect to the server. If the connection fails (disconnect before we reach * lobby state), an error toast with the disconnect message is shown. - * + * */ public class ConnectingDialog extends ConnectionDependendDialogFragment { - @Override - public void onStart() { - super.onStart(); - LocalBroadcastManager.getInstance(getActivity().getApplicationContext()).registerReceiver(connectedReceiver, new IntentFilter(Netplay.ACTION_CONNECTED)); - LocalBroadcastManager.getInstance(getActivity().getApplicationContext()).registerReceiver(disconnectedReceiver, new IntentFilter(Netplay.ACTION_DISCONNECTED)); - - if(Netplay.getAppInstance(getActivity().getApplicationContext()).getState() != State.CONNECTING) { - dismiss(); - } - } - - @Override - public void onStop() { - super.onStop(); - LocalBroadcastManager.getInstance(getActivity().getApplicationContext()).unregisterReceiver(connectedReceiver); - LocalBroadcastManager.getInstance(getActivity().getApplicationContext()).unregisterReceiver(disconnectedReceiver); - } - - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - ProgressDialog dialog = new ProgressDialog(getActivity()); - dialog.setIndeterminate(true); - dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); - dialog.setTitle(R.string.dialog_connecting_title); - dialog.setMessage(getString(R.string.dialog_connecting_message)); - return dialog; - } - - private BroadcastReceiver connectedReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - Dialog dialog = getDialog(); - if(dialog != null) { - dialog.dismiss(); - } else { - dismiss(); - } - } - }; - - private BroadcastReceiver disconnectedReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - Toast.makeText(getActivity(), intent.getExtras().getString(Netplay.EXTRA_MESSAGE), Toast.LENGTH_LONG).show(); - } - }; - - public void onCancel(DialogInterface dialog) { - super.onCancel(dialog); - Netplay.getAppInstance(getActivity().getApplicationContext()).disconnect(); - }; + @Override + public void onStart() { + super.onStart(); + LocalBroadcastManager.getInstance(getActivity().getApplicationContext()).registerReceiver(connectedReceiver, new IntentFilter(Netplay.ACTION_CONNECTED)); + LocalBroadcastManager.getInstance(getActivity().getApplicationContext()).registerReceiver(disconnectedReceiver, new IntentFilter(Netplay.ACTION_DISCONNECTED)); + + if(Netplay.getAppInstance(getActivity().getApplicationContext()).getState() != State.CONNECTING) { + dismiss(); + } + } + + @Override + public void onStop() { + super.onStop(); + LocalBroadcastManager.getInstance(getActivity().getApplicationContext()).unregisterReceiver(connectedReceiver); + LocalBroadcastManager.getInstance(getActivity().getApplicationContext()).unregisterReceiver(disconnectedReceiver); + } + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + ProgressDialog dialog = new ProgressDialog(getActivity()); + dialog.setIndeterminate(true); + dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); + dialog.setTitle(R.string.dialog_connecting_title); + dialog.setMessage(getString(R.string.dialog_connecting_message)); + return dialog; + } + + private BroadcastReceiver connectedReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + Dialog dialog = getDialog(); + if(dialog != null) { + dialog.dismiss(); + } else { + dismiss(); + } + } + }; + + private BroadcastReceiver disconnectedReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + Toast.makeText(getActivity(), intent.getExtras().getString(Netplay.EXTRA_MESSAGE), Toast.LENGTH_LONG).show(); + } + }; + + public void onCancel(DialogInterface dialog) { + super.onCancel(dialog); + Netplay.getAppInstance(getActivity().getApplicationContext()).disconnect(); + }; } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/ConnectionDependendDialogFragment.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/ConnectionDependendDialogFragment.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/ConnectionDependendDialogFragment.java Tue Jan 21 22:43:06 2014 +0100 @@ -36,30 +36,30 @@ * appear during connecting (e.g. username input) */ public class ConnectionDependendDialogFragment extends DialogFragment { - @Override - public void onStart() { - super.onStart(); - LocalBroadcastManager.getInstance(getActivity().getApplicationContext()).registerReceiver(dismissReceiver, new IntentFilter(Netplay.ACTION_DISCONNECTED)); - if(Netplay.getAppInstance(getActivity().getApplicationContext()).getState() == State.NOT_CONNECTED) { - dismiss(); - } - } - - @Override - public void onStop() { - super.onStop(); - LocalBroadcastManager.getInstance(getActivity().getApplicationContext()).unregisterReceiver(dismissReceiver); - } - - private BroadcastReceiver dismissReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - Dialog dialog = getDialog(); - if(dialog != null) { - dialog.dismiss(); - } else { - dismiss(); - } - } - }; + @Override + public void onStart() { + super.onStart(); + LocalBroadcastManager.getInstance(getActivity().getApplicationContext()).registerReceiver(dismissReceiver, new IntentFilter(Netplay.ACTION_DISCONNECTED)); + if(Netplay.getAppInstance(getActivity().getApplicationContext()).getState() == State.NOT_CONNECTED) { + dismiss(); + } + } + + @Override + public void onStop() { + super.onStop(); + LocalBroadcastManager.getInstance(getActivity().getApplicationContext()).unregisterReceiver(dismissReceiver); + } + + private BroadcastReceiver dismissReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + Dialog dialog = getDialog(); + if(dialog != null) { + dialog.dismiss(); + } else { + dismiss(); + } + } + }; } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadAssets.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadAssets.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadAssets.java Tue Jan 21 22:43:06 2014 +0100 @@ -36,48 +36,48 @@ import android.util.Log; public class DownloadAssets extends AsyncTask { - private static final String VERSION_FILENAME = "assetsversion.txt"; - private final MainActivity act; - - public DownloadAssets(MainActivity act){ - this.act = act; - } - - private void copyFileOrDir(AssetManager assetManager, File target, String assetPath) throws IOException { - try { - FileUtils.writeStreamToFile(assetManager.open(assetPath), target); - } catch(FileNotFoundException e) { - /* - * I can't find a better way to figure out whether an asset entry is - * a file or a directory. Checking if assetManager.list(assetPath) - * is empty is a bit cleaner, but SLOW. - */ - if (!target.isDirectory() && !target.mkdir()) { - throw new IOException("Unable to create directory "+target); - } - for (String asset : assetManager.list(assetPath)) { - copyFileOrDir(assetManager, new File(target, asset), assetPath + "/" + asset); - } - } - } - - @Override - protected Boolean doInBackground(Object... params) { - try { - FileUtils.writeStreamToFile(act.getResources().openRawResource(R.raw.schemes_builtin), Schemes.getBuiltinSchemesFile(act)); - FileUtils.writeStreamToFile(act.getResources().openRawResource(R.raw.weapons_builtin), Weaponsets.getBuiltinWeaponsetsFile(act)); - FileUtils.resRawToFilesDir(act, R.array.teams, R.array.teamFilenames, Team.DIRECTORY_TEAMS); - copyFileOrDir(act.getAssets(), FileUtils.getDataPathFile(act), "Data"); - copyFileOrDir(act.getAssets(), new File(FileUtils.getCachePath(act), VERSION_FILENAME), VERSION_FILENAME); - return Boolean.TRUE; - } catch(IOException e) { - Log.e("DownloadAssets", e.getMessage(), e); - return Boolean.FALSE; - } - } - - @Override - protected void onPostExecute(Boolean result){ - act.onAssetsDownloaded(result); - } + private static final String VERSION_FILENAME = "assetsversion.txt"; + private final MainActivity act; + + public DownloadAssets(MainActivity act){ + this.act = act; + } + + private void copyFileOrDir(AssetManager assetManager, File target, String assetPath) throws IOException { + try { + FileUtils.writeStreamToFile(assetManager.open(assetPath), target); + } catch(FileNotFoundException e) { + /* + * I can't find a better way to figure out whether an asset entry is + * a file or a directory. Checking if assetManager.list(assetPath) + * is empty is a bit cleaner, but SLOW. + */ + if (!target.isDirectory() && !target.mkdir()) { + throw new IOException("Unable to create directory "+target); + } + for (String asset : assetManager.list(assetPath)) { + copyFileOrDir(assetManager, new File(target, asset), assetPath + "/" + asset); + } + } + } + + @Override + protected Boolean doInBackground(Object... params) { + try { + FileUtils.writeStreamToFile(act.getResources().openRawResource(R.raw.schemes_builtin), Schemes.getBuiltinSchemesFile(act)); + FileUtils.writeStreamToFile(act.getResources().openRawResource(R.raw.weapons_builtin), Weaponsets.getBuiltinWeaponsetsFile(act)); + FileUtils.resRawToFilesDir(act, R.array.teams, R.array.teamFilenames, Team.DIRECTORY_TEAMS); + copyFileOrDir(act.getAssets(), FileUtils.getDataPathFile(act), "Data"); + copyFileOrDir(act.getAssets(), new File(FileUtils.getCachePath(act), VERSION_FILENAME), VERSION_FILENAME); + return Boolean.TRUE; + } catch(IOException e) { + Log.e("DownloadAssets", e.getMessage(), e); + return Boolean.FALSE; + } + } + + @Override + protected void onPostExecute(Boolean result){ + act.onAssetsDownloaded(result); + } } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadAsyncTask.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadAsyncTask.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadAsyncTask.java Tue Jan 21 22:43:06 2014 +0100 @@ -37,188 +37,188 @@ import android.os.AsyncTask; /** * This is an AsyncTask which will download a zip from an URL and unzip it to a specified path - * + * * a typical call to start the task would be new DownloadAsyncTask().execute(getExternalStorage(), "www.hedgewars.org/data.zip"); * @author Xeli * */ public class DownloadAsyncTask extends AsyncTask { - //private final static String URL_WITHOUT_SUFFIX = "http://www.xelification.com/tmp/firebutton."; - private final static String URL_ZIP_SUFFIX = ".zip"; - private final static String URL_HASH_SUFFIX = ".hash"; + //private final static String URL_WITHOUT_SUFFIX = "http://www.xelification.com/tmp/firebutton."; + private final static String URL_ZIP_SUFFIX = ".zip"; + private final static String URL_HASH_SUFFIX = ".hash"; - public static final int EXIT_SUCCESS = 0; - public static final int EXIT_URLFAIL = 1; - public static final int EXIT_CONNERROR = 2; - public static final int EXIT_FNF = 3; - public static final int EXIT_MD5 = 4; - public static final int EXIT_CANCELLED = 5; + public static final int EXIT_SUCCESS = 0; + public static final int EXIT_URLFAIL = 1; + public static final int EXIT_CONNERROR = 2; + public static final int EXIT_FNF = 3; + public static final int EXIT_MD5 = 4; + public static final int EXIT_CANCELLED = 5; - private DownloadTask task; - private long lastUpdateMillis = 0; + private DownloadTask task; + private long lastUpdateMillis = 0; - public DownloadAsyncTask(DownloadTask _task){ - task = _task; - } + public DownloadAsyncTask(DownloadTask _task){ + task = _task; + } - /** - * - * @param params - A {@link}DownloadTask which gives information about where to download from and store the files to - */ - protected Integer doInBackground(DownloadPackage...packages) { - DownloadPackage pack = packages[0];//just use one task per execute call for now + /** + * + * @param params - A {@link}DownloadTask which gives information about where to download from and store the files to + */ + protected Integer doInBackground(DownloadPackage...packages) { + DownloadPackage pack = packages[0];//just use one task per execute call for now - HttpURLConnection conn = null; - MessageDigest digester = null; - String rootZipDest = pack.getPathToStore(); + HttpURLConnection conn = null; + MessageDigest digester = null; + String rootZipDest = pack.getPathToStore(); - File rootDest = new File(rootZipDest);//TODO check for nullpointer, it hints to the absence of an sdcard - rootDest.mkdirs(); + File rootDest = new File(rootZipDest);//TODO check for nullpointer, it hints to the absence of an sdcard + rootDest.mkdirs(); - try { - URL url = new URL(pack.getURL() + URL_ZIP_SUFFIX); - conn = (HttpURLConnection)url.openConnection(); - } catch (IOException e) { - e.printStackTrace(); - return EXIT_URLFAIL; - } + try { + URL url = new URL(pack.getURL() + URL_ZIP_SUFFIX); + conn = (HttpURLConnection)url.openConnection(); + } catch (IOException e) { + e.printStackTrace(); + return EXIT_URLFAIL; + } - String contentType = conn.getContentType(); + String contentType = conn.getContentType(); - if(contentType == null || contentType.contains("zip")){ //Seeing as we provide the url if the contentType is unknown lets assume zips - int bytesDecompressed = 0; - ZipEntry entry = null; - ZipInputStream input = null; - FileOutputStream output = null; - int kbytesToProcess = conn.getContentLength()/1024; + if(contentType == null || contentType.contains("zip")){ //Seeing as we provide the url if the contentType is unknown lets assume zips + int bytesDecompressed = 0; + ZipEntry entry = null; + ZipInputStream input = null; + FileOutputStream output = null; + int kbytesToProcess = conn.getContentLength()/1024; - byte[] buffer = new byte[1024]; - task.start(kbytesToProcess); + byte[] buffer = new byte[1024]; + task.start(kbytesToProcess); - try { - digester = MessageDigest.getInstance("MD5"); + try { + digester = MessageDigest.getInstance("MD5"); - } catch (NoSuchAlgorithmException e1) { - e1.printStackTrace(); - } + } catch (NoSuchAlgorithmException e1) { + e1.printStackTrace(); + } - try{ - input = new ZipInputStream(conn.getInputStream()); - entry = input.getNextEntry(); - }catch(IOException e){ - e.printStackTrace(); - conn.disconnect(); - return EXIT_CONNERROR; - } + try{ + input = new ZipInputStream(conn.getInputStream()); + entry = input.getNextEntry(); + }catch(IOException e){ + e.printStackTrace(); + conn.disconnect(); + return EXIT_CONNERROR; + } - while(entry != null){ + while(entry != null){ - if(isCancelled()) break; + if(isCancelled()) break; - try { - String fileName = entry.getName(); - File f = new File(rootZipDest + fileName); - bytesDecompressed += entry.getCompressedSize(); + try { + String fileName = entry.getName(); + File f = new File(rootZipDest + fileName); + bytesDecompressed += entry.getCompressedSize(); - if(entry.isDirectory()){ - f.mkdir(); - }else{ - if(f.exists()){ - f.delete(); - } - f.createNewFile(); - output = new FileOutputStream(f); + if(entry.isDirectory()){ + f.mkdir(); + }else{ + if(f.exists()){ + f.delete(); + } + f.createNewFile(); + output = new FileOutputStream(f); - int count = 0; - while((count = input.read(buffer)) != -1){ - output.write(buffer, 0, count); - digester.update(buffer, 0, count); - if(System.currentTimeMillis() - lastUpdateMillis > 1000){ - lastUpdateMillis = System.currentTimeMillis(); - publishProgress(bytesDecompressed, kbytesToProcess, fileName); - } - } - output.flush(); - input.closeEntry(); - }//if isDir - entry = input.getNextEntry(); - } catch (FileNotFoundException e) { - e.printStackTrace(); - if(conn != null) conn.disconnect(); - return EXIT_FNF; - } catch (IOException e) { - e.printStackTrace(); - if(conn != null) conn.disconnect(); - return EXIT_CONNERROR; - }finally{ - try { - if( output != null) output.close(); + int count = 0; + while((count = input.read(buffer)) != -1){ + output.write(buffer, 0, count); + digester.update(buffer, 0, count); + if(System.currentTimeMillis() - lastUpdateMillis > 1000){ + lastUpdateMillis = System.currentTimeMillis(); + publishProgress(bytesDecompressed, kbytesToProcess, fileName); + } + } + output.flush(); + input.closeEntry(); + }//if isDir + entry = input.getNextEntry(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + if(conn != null) conn.disconnect(); + return EXIT_FNF; + } catch (IOException e) { + e.printStackTrace(); + if(conn != null) conn.disconnect(); + return EXIT_CONNERROR; + }finally{ + try { + if( output != null) output.close(); - } catch (IOException e) {} - } - }//end while(entry != null) - if( input != null) - try { - input.close(); - } catch (IOException e) {} - }else{//end if contentType == "zip" - return EXIT_URLFAIL; - } - if(conn != null) conn.disconnect(); + } catch (IOException e) {} + } + }//end while(entry != null) + if( input != null) + try { + input.close(); + } catch (IOException e) {} + }else{//end if contentType == "zip" + return EXIT_URLFAIL; + } + if(conn != null) conn.disconnect(); - if(checkMD5(digester, pack))return EXIT_SUCCESS; - else return EXIT_MD5; - } + if(checkMD5(digester, pack))return EXIT_SUCCESS; + else return EXIT_MD5; + } - //TODO proper result handling - protected void onPostExecute(Integer result){ - task.done(result); - } + //TODO proper result handling + protected void onPostExecute(Integer result){ + task.done(result); + } - protected void onProgressUpdate(Object...objects){ - task.update((Integer)objects[0], (Integer)objects[1], (String)objects[2]); - } + protected void onProgressUpdate(Object...objects){ + task.update((Integer)objects[0], (Integer)objects[1], (String)objects[2]); + } - protected void onCancelled(){ - onPostExecute(EXIT_CANCELLED); - } + protected void onCancelled(){ + onPostExecute(EXIT_CANCELLED); + } - private boolean checkMD5(MessageDigest digester, DownloadPackage task){ - if(digester != null) { - byte[] messageDigest = digester.digest(); + private boolean checkMD5(MessageDigest digester, DownloadPackage task){ + if(digester != null) { + byte[] messageDigest = digester.digest(); - try { - URL url = new URL(task.getURL() + URL_HASH_SUFFIX); - HttpURLConnection conn = (HttpURLConnection)url.openConnection(); + try { + URL url = new URL(task.getURL() + URL_HASH_SUFFIX); + HttpURLConnection conn = (HttpURLConnection)url.openConnection(); - byte[] buffer = new byte[1024];//size is large enough to hold the entire hash - BufferedInputStream bis = new BufferedInputStream(conn.getInputStream()); - int bytesRead = bis.read(buffer); - String hash = null; - if(bytesRead > -1){ - hash = new String(buffer, 0, bytesRead); - } - StringBuffer sb = new StringBuffer(); - Integer tmp = 0; - for(int i = 0; i < messageDigest.length; i++){ - tmp = 0xFF & messageDigest[i]; - if(tmp < 0xF) sb.append('0'); - sb.append(Integer.toHexString(tmp)); - } - sb.append('\n');//add newline to become identical with the hash file + byte[] buffer = new byte[1024];//size is large enough to hold the entire hash + BufferedInputStream bis = new BufferedInputStream(conn.getInputStream()); + int bytesRead = bis.read(buffer); + String hash = null; + if(bytesRead > -1){ + hash = new String(buffer, 0, bytesRead); + } + StringBuffer sb = new StringBuffer(); + Integer tmp = 0; + for(int i = 0; i < messageDigest.length; i++){ + tmp = 0xFF & messageDigest[i]; + if(tmp < 0xF) sb.append('0'); + sb.append(Integer.toHexString(tmp)); + } + sb.append('\n');//add newline to become identical with the hash file - return hash.equals(sb.toString()); - } catch (IOException e) { - e.printStackTrace(); - return true; - } - }else{ - return true; - } + return hash.equals(sb.toString()); + } catch (IOException e) { + e.printStackTrace(); + return true; + } + }else{ + return true; + } - } + } } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadDialogFragment.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadDialogFragment.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadDialogFragment.java Tue Jan 21 22:43:06 2014 +0100 @@ -32,57 +32,57 @@ public class DownloadDialogFragment extends DialogFragment { - public static final int NUM_ALREADYDOWNLOADED = 0; - public static final int NUM_AREYOUSURE = 1; + public static final int NUM_ALREADYDOWNLOADED = 0; + public static final int NUM_AREYOUSURE = 1; - private final static String BUNDLE_TASK = "task"; + private final static String BUNDLE_TASK = "task"; - static DownloadDialogFragment newInstance(DownloadPackage task){ - DownloadDialogFragment dialog = new DownloadDialogFragment(); + static DownloadDialogFragment newInstance(DownloadPackage task){ + DownloadDialogFragment dialog = new DownloadDialogFragment(); - Bundle args = new Bundle(); - args.putParcelable(DownloadDialogFragment.BUNDLE_TASK, task); - dialog.setArguments(args); + Bundle args = new Bundle(); + args.putParcelable(DownloadDialogFragment.BUNDLE_TASK, task); + dialog.setArguments(args); - return dialog; - } + return dialog; + } - public Dialog onCreateDialog(Bundle savedInstanceState){ - DownloadPackage task = (DownloadPackage)getArguments().getParcelable(DownloadDialogFragment.BUNDLE_TASK); + public Dialog onCreateDialog(Bundle savedInstanceState){ + DownloadPackage task = (DownloadPackage)getArguments().getParcelable(DownloadDialogFragment.BUNDLE_TASK); - Builder builder = new AlertDialog.Builder(getActivity()); + Builder builder = new AlertDialog.Builder(getActivity()); - switch(task.getStatus()){ - case CURRENTVERSION: - case NEWERVERSION: - builder.setMessage(R.string.download_areyousure); - break; - case OLDERVERSION: - builder.setMessage(R.string.download_alreadydownloaded); - break; - } + switch(task.getStatus()){ + case CURRENTVERSION: + case NEWERVERSION: + builder.setMessage(R.string.download_areyousure); + break; + case OLDERVERSION: + builder.setMessage(R.string.download_alreadydownloaded); + break; + } - DownloadClicker clicker = new DownloadClicker(task); - builder.setPositiveButton(android.R.string.yes, clicker); - builder.setNegativeButton(android.R.string.no, clicker); + DownloadClicker clicker = new DownloadClicker(task); + builder.setPositiveButton(android.R.string.yes, clicker); + builder.setNegativeButton(android.R.string.no, clicker); - return builder.create(); - } + return builder.create(); + } - class DownloadClicker implements OnClickListener{ + class DownloadClicker implements OnClickListener{ - DownloadPackage task = null; + DownloadPackage task = null; - public DownloadClicker(DownloadPackage _task){ - task = _task; - } + public DownloadClicker(DownloadPackage _task){ + task = _task; + } - public void onClick(DialogInterface dialog, int which) { - if(which == Dialog.BUTTON_POSITIVE){ - Intent i = new Intent(getActivity(), DownloadListActivity.class); - i.putExtra(DownloadFragment.EXTRA_TASK, task); - getActivity().startActivity(i); - } - } - } + public void onClick(DialogInterface dialog, int which) { + if(which == Dialog.BUTTON_POSITIVE){ + Intent i = new Intent(getActivity(), DownloadListActivity.class); + i.putExtra(DownloadFragment.EXTRA_TASK, task); + getActivity().startActivity(i); + } + } + } } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadFragment.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadFragment.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadFragment.java Tue Jan 21 22:43:06 2014 +0100 @@ -41,177 +41,177 @@ import android.widget.TextView; public class DownloadFragment extends Fragment{ - public static final String EXTRA_TASK = "task"; + public static final String EXTRA_TASK = "task"; - public static final int MSG_START = 0; - public static final int MSG_UPDATE = 1; - public static final int MSG_DONE = 2; - public static final int MSG_FAILED = 3; + public static final int MSG_START = 0; + public static final int MSG_UPDATE = 1; + public static final int MSG_DONE = 2; + public static final int MSG_FAILED = 3; - private boolean boundToService = false; + private boolean boundToService = false; - private TextView progress_sub; - private ProgressBar progress; - private Button /*positive,*/ negative; + private TextView progress_sub; + private ProgressBar progress; + private Button /*positive,*/ negative; - private DownloadPackage pack; + private DownloadPackage pack; - private Handler messageHandler; - private Messenger messenger, messengerService; + private Handler messageHandler; + private Messenger messenger, messengerService; - public static DownloadFragment getInstance(DownloadPackage task){ - DownloadFragment df = new DownloadFragment(); - Bundle args = new Bundle(); - args.putParcelable(DownloadFragment.EXTRA_TASK, task); + public static DownloadFragment getInstance(DownloadPackage task){ + DownloadFragment df = new DownloadFragment(); + Bundle args = new Bundle(); + args.putParcelable(DownloadFragment.EXTRA_TASK, task); - df.setArguments(args); + df.setArguments(args); - return df; - } + return df; + } - public void onActivityCreated(Bundle savedInstanceState){ - super.onActivityCreated(savedInstanceState); + public void onActivityCreated(Bundle savedInstanceState){ + super.onActivityCreated(savedInstanceState); - messageHandler = new Handler(messageCallback); - messenger = new Messenger(messageHandler); - Intent i = new Intent(getActivity().getApplicationContext(), DownloadService.class); - getActivity().startService(i); - getActivity().bindService(new Intent(getActivity().getApplicationContext(), DownloadService.class), connection, Context.BIND_AUTO_CREATE); - } + messageHandler = new Handler(messageCallback); + messenger = new Messenger(messageHandler); + Intent i = new Intent(getActivity().getApplicationContext(), DownloadService.class); + getActivity().startService(i); + getActivity().bindService(new Intent(getActivity().getApplicationContext(), DownloadService.class), connection, Context.BIND_AUTO_CREATE); + } - public View onCreateView(LayoutInflater inflater, ViewGroup viewgroup, Bundle savedInstanceState){ - View v = inflater.inflate(R.layout.download_progress, viewgroup, false); - progress_sub = (TextView)v.findViewById(R.id.progressbar_sub); - progress = (ProgressBar)v.findViewById(R.id.progressbar); + public View onCreateView(LayoutInflater inflater, ViewGroup viewgroup, Bundle savedInstanceState){ + View v = inflater.inflate(R.layout.download_progress, viewgroup, false); + progress_sub = (TextView)v.findViewById(R.id.progressbar_sub); + progress = (ProgressBar)v.findViewById(R.id.progressbar); - //positive = (Button) v.findViewById(R.id.background); - negative = (Button) v.findViewById(R.id.cancelDownload); - //positive.setOnClickListener(backgroundClicker); - negative.setOnClickListener(cancelClicker); + //positive = (Button) v.findViewById(R.id.background); + negative = (Button) v.findViewById(R.id.cancelDownload); + //positive.setOnClickListener(backgroundClicker); + negative.setOnClickListener(cancelClicker); - pack = getArguments().getParcelable(DownloadFragment.EXTRA_TASK); + pack = getArguments().getParcelable(DownloadFragment.EXTRA_TASK); - return v; - } + return v; + } - private OnClickListener backgroundClicker = new OnClickListener(){ - public void onClick(View v){ - getActivity().finish(); - } - }; - private OnClickListener cancelClicker = new OnClickListener(){ - public void onClick(View v){ - if(messengerService != null){ - Message message = Message.obtain(messageHandler, DownloadService.MSG_CANCEL, pack); - try { - messengerService.send(message); - } catch (RemoteException e) {} - } - //getActivity().finish(); - } - }; - private OnClickListener doneClicker = new OnClickListener(){ - public void onClick(View v){ - getActivity().finish(); - } - }; + private OnClickListener backgroundClicker = new OnClickListener(){ + public void onClick(View v){ + getActivity().finish(); + } + }; + private OnClickListener cancelClicker = new OnClickListener(){ + public void onClick(View v){ + if(messengerService != null){ + Message message = Message.obtain(messageHandler, DownloadService.MSG_CANCEL, pack); + try { + messengerService.send(message); + } catch (RemoteException e) {} + } + //getActivity().finish(); + } + }; + private OnClickListener doneClicker = new OnClickListener(){ + public void onClick(View v){ + getActivity().finish(); + } + }; - private OnClickListener tryAgainClicker = new OnClickListener(){ - public void onClick(View v){ - if(messengerService != null){ - Message message = Message.obtain(messageHandler, DownloadService.MSG_ADDTASK, pack); - message.replyTo = messenger; - try { - messengerService.send(message); - } catch (RemoteException e) { - e.printStackTrace(); - } - } - } - }; + private OnClickListener tryAgainClicker = new OnClickListener(){ + public void onClick(View v){ + if(messengerService != null){ + Message message = Message.obtain(messageHandler, DownloadService.MSG_ADDTASK, pack); + message.replyTo = messenger; + try { + messengerService.send(message); + } catch (RemoteException e) { + e.printStackTrace(); + } + } + } + }; - public void onDestroy(){ - unBindFromService(); - super.onDestroy(); - } + public void onDestroy(){ + unBindFromService(); + super.onDestroy(); + } - private ServiceConnection connection = new ServiceConnection(){ + private ServiceConnection connection = new ServiceConnection(){ - public void onServiceConnected(ComponentName name, IBinder service) { - messengerService = new Messenger(service); + public void onServiceConnected(ComponentName name, IBinder service) { + messengerService = new Messenger(service); - try{ - //give the service a task - if(messengerService != null){ - Message message = Message.obtain(messageHandler, DownloadService.MSG_ADDTASK, pack); - message.replyTo = messenger; - messengerService.send(message); - } + try{ + //give the service a task + if(messengerService != null){ + Message message = Message.obtain(messageHandler, DownloadService.MSG_ADDTASK, pack); + message.replyTo = messenger; + messengerService.send(message); + } - }catch (RemoteException e){} - } + }catch (RemoteException e){} + } - public void onServiceDisconnected(ComponentName name) { - messengerService = null; - } + public void onServiceDisconnected(ComponentName name) { + messengerService = null; + } - }; + }; - public void unBindFromService(){ - if(messengerService != null){ - try { - Message message = Message.obtain(messageHandler, DownloadService.MSG_UNREGISTER_CLIENT, pack); - message.replyTo = messenger; - messengerService.send(message); - } catch (RemoteException e) { - e.printStackTrace(); - } - } + public void unBindFromService(){ + if(messengerService != null){ + try { + Message message = Message.obtain(messageHandler, DownloadService.MSG_UNREGISTER_CLIENT, pack); + message.replyTo = messenger; + messengerService.send(message); + } catch (RemoteException e) { + e.printStackTrace(); + } + } - getActivity().unbindService(connection); - } + getActivity().unbindService(connection); + } - private Handler.Callback messageCallback = new Handler.Callback() { + private Handler.Callback messageCallback = new Handler.Callback() { - public boolean handleMessage(Message msg) { - switch(msg.what){ - case MSG_START: - progress.setMax(msg.arg1); - progress_sub.setText(String.format("%dkb/%dkb\n%s", 0, msg.arg1, "")); - //positive.setText(R.string.download_background); - //positive.setOnClickListener(backgroundClicker); - negative.setText(R.string.download_cancel); - negative.setOnClickListener(cancelClicker); - break; - case MSG_UPDATE: - progress_sub.setText(String.format("%d%% - %dkb/%dkb\n%s",(msg.arg1*100)/msg.arg2, msg.arg1, msg.arg2, msg.obj)); - progress.setProgress(msg.arg1); - break; - case MSG_DONE: - progress.setProgress(progress.getMax()); - progress_sub.setText(R.string.download_done); + public boolean handleMessage(Message msg) { + switch(msg.what){ + case MSG_START: + progress.setMax(msg.arg1); + progress_sub.setText(String.format("%dkb/%dkb\n%s", 0, msg.arg1, "")); + //positive.setText(R.string.download_background); + //positive.setOnClickListener(backgroundClicker); + negative.setText(R.string.download_cancel); + negative.setOnClickListener(cancelClicker); + break; + case MSG_UPDATE: + progress_sub.setText(String.format("%d%% - %dkb/%dkb\n%s",(msg.arg1*100)/msg.arg2, msg.arg1, msg.arg2, msg.obj)); + progress.setProgress(msg.arg1); + break; + case MSG_DONE: + progress.setProgress(progress.getMax()); + progress_sub.setText(R.string.download_done); - // positive.setText(R.string.download_back); - // positive.setOnClickListener(doneClicker); + // positive.setText(R.string.download_back); + // positive.setOnClickListener(doneClicker); + + negative.setVisibility(View.INVISIBLE); + break; + case MSG_FAILED: + progress.setProgress(progress.getMax()); - negative.setVisibility(View.INVISIBLE); - break; - case MSG_FAILED: - progress.setProgress(progress.getMax()); - - String errorMsg = getString(R.string.download_failed); - switch(msg.arg1){ - case DownloadAsyncTask.EXIT_CONNERROR: progress_sub.setText(errorMsg + " " + "Connection error"); break; - case DownloadAsyncTask.EXIT_FNF: progress_sub.setText(errorMsg + " " + "File not found"); break; - case DownloadAsyncTask.EXIT_MD5: progress_sub.setText(errorMsg + " " + "MD5 check failed"); break; - case DownloadAsyncTask.EXIT_URLFAIL: progress_sub.setText(errorMsg + " " + "Invalid url"); break; - } - negative.setText(R.string.download_tryagain); - negative.setOnClickListener(tryAgainClicker); - break; - } - return false; - } - }; + String errorMsg = getString(R.string.download_failed); + switch(msg.arg1){ + case DownloadAsyncTask.EXIT_CONNERROR: progress_sub.setText(errorMsg + " " + "Connection error"); break; + case DownloadAsyncTask.EXIT_FNF: progress_sub.setText(errorMsg + " " + "File not found"); break; + case DownloadAsyncTask.EXIT_MD5: progress_sub.setText(errorMsg + " " + "MD5 check failed"); break; + case DownloadAsyncTask.EXIT_URLFAIL: progress_sub.setText(errorMsg + " " + "Invalid url"); break; + } + negative.setText(R.string.download_tryagain); + negative.setOnClickListener(tryAgainClicker); + break; + } + return false; + } + }; } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadListActivity.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadListActivity.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadListActivity.java Tue Jan 21 22:43:06 2014 +0100 @@ -35,99 +35,99 @@ public class DownloadListActivity extends FragmentActivity implements OnItemMovementListener{ - private FrameLayout layout = null; - private LinearLayout downloadQueueContainer = null; - private View infoView = null; - private ImageView arrow = null; - private int halfSize = 0; - private DownloadPackage task = null; + private FrameLayout layout = null; + private LinearLayout downloadQueueContainer = null; + private View infoView = null; + private ImageView arrow = null; + private int halfSize = 0; + private DownloadPackage task = null; + + public void onCreate(Bundle savedInstanceState){ + super.onCreate(savedInstanceState); - public void onCreate(Bundle savedInstanceState){ - super.onCreate(savedInstanceState); + setContentView(R.layout.download_listactivity); + //FragmentManager fm = this.getSupportFragmentManager(); + //if(fm.findFragmentById(android.R.id.content) == null){ + // DownloadListFragment listfrag = new DownloadListFragment(); + // fm.beginTransaction().add(android.R.id.content, listfrag).commit(); + //} - setContentView(R.layout.download_listactivity); - //FragmentManager fm = this.getSupportFragmentManager(); - //if(fm.findFragmentById(android.R.id.content) == null){ - // DownloadListFragment listfrag = new DownloadListFragment(); - // fm.beginTransaction().add(android.R.id.content, listfrag).commit(); - //} + layout = (FrameLayout)findViewById(R.id.downloadFrameLayout); + downloadQueueContainer = (LinearLayout) findViewById(R.id.downloadQueueContainer); + } - layout = (FrameLayout)findViewById(R.id.downloadFrameLayout); - downloadQueueContainer = (LinearLayout) findViewById(R.id.downloadQueueContainer); - } - - public void onNewItemSelected(DownloadPackage _task, int x, int minX, int maxX, int size) { - if(layout != null){ - if(!_task.equals(task)){//if it's a new task refresh the whole thing - task = _task; - layout.removeView(infoView); - infoView = null; - } - - if(infoView == null){//build iv if it hasn't been created yet - infoView = this.getLayoutInflater().inflate(R.layout.download_info, layout, false); - FrameLayout.LayoutParams params = (android.widget.FrameLayout.LayoutParams) infoView.getLayoutParams(); - params.gravity = Gravity.NO_GRAVITY; - params.height = size; - arrow = (ImageView)infoView.findViewById(R.id.arrow); - arrow.setVisibility(View.INVISIBLE); - halfSize = size/2; - - Button yes = (Button)infoView.findViewById(R.id.download); - Button no = (Button)infoView.findViewById(R.id.cancel); - yes.setOnClickListener(yesClicker); - no.setOnClickListener(noClicker); - - layout.addView(infoView, params); - } - } - } + public void onNewItemSelected(DownloadPackage _task, int x, int minX, int maxX, int size) { + if(layout != null){ + if(!_task.equals(task)){//if it's a new task refresh the whole thing + task = _task; + layout.removeView(infoView); + infoView = null; + } + + if(infoView == null){//build iv if it hasn't been created yet + infoView = this.getLayoutInflater().inflate(R.layout.download_info, layout, false); + FrameLayout.LayoutParams params = (android.widget.FrameLayout.LayoutParams) infoView.getLayoutParams(); + params.gravity = Gravity.NO_GRAVITY; + params.height = size; + arrow = (ImageView)infoView.findViewById(R.id.arrow); + arrow.setVisibility(View.INVISIBLE); + halfSize = size/2; + + Button yes = (Button)infoView.findViewById(R.id.download); + Button no = (Button)infoView.findViewById(R.id.cancel); + yes.setOnClickListener(yesClicker); + no.setOnClickListener(noClicker); + + layout.addView(infoView, params); + } + } + } - public void onViewMoved(int x, int minX, int maxX) { - if(halfSize == -1){ - if(infoView.getHeight() != 0){ - halfSize = infoView.getHeight()/2; - } - } - if(layout != null && infoView != null){ - FrameLayout.LayoutParams params = ((FrameLayout.LayoutParams)infoView.getLayoutParams()); - if(x - halfSize < minX){ - params.topMargin = 0; - arrow.setVisibility(View.INVISIBLE); - params.gravity = Gravity.TOP; - }else if (x + halfSize >= maxX){ - params.topMargin = 0; - arrow.setVisibility(View.INVISIBLE); - params.gravity = Gravity.BOTTOM; - }else{ - params.topMargin = x - halfSize; - params.gravity = Gravity.NO_GRAVITY; - arrow.setVisibility(View.VISIBLE); - } - - infoView.requestLayout(); - - } - } - - private OnClickListener yesClicker = new OnClickListener(){ - public void onClick(View v){ - FragmentManager fm = getSupportFragmentManager(); - FragmentTransaction ft= fm.beginTransaction(); - DownloadFragment df = DownloadFragment.getInstance(task); - - ft.add(R.id.downloadQueueContainer, df).commit(); - //ft.show(new DownloadFragment()); - - task = null; - layout.removeView(infoView); - } - }; - - private OnClickListener noClicker = new OnClickListener(){ - public void onClick(View v){ - task = null; - layout.removeView(infoView); - } - }; + public void onViewMoved(int x, int minX, int maxX) { + if(halfSize == -1){ + if(infoView.getHeight() != 0){ + halfSize = infoView.getHeight()/2; + } + } + if(layout != null && infoView != null){ + FrameLayout.LayoutParams params = ((FrameLayout.LayoutParams)infoView.getLayoutParams()); + if(x - halfSize < minX){ + params.topMargin = 0; + arrow.setVisibility(View.INVISIBLE); + params.gravity = Gravity.TOP; + }else if (x + halfSize >= maxX){ + params.topMargin = 0; + arrow.setVisibility(View.INVISIBLE); + params.gravity = Gravity.BOTTOM; + }else{ + params.topMargin = x - halfSize; + params.gravity = Gravity.NO_GRAVITY; + arrow.setVisibility(View.VISIBLE); + } + + infoView.requestLayout(); + + } + } + + private OnClickListener yesClicker = new OnClickListener(){ + public void onClick(View v){ + FragmentManager fm = getSupportFragmentManager(); + FragmentTransaction ft= fm.beginTransaction(); + DownloadFragment df = DownloadFragment.getInstance(task); + + ft.add(R.id.downloadQueueContainer, df).commit(); + //ft.show(new DownloadFragment()); + + task = null; + layout.removeView(infoView); + } + }; + + private OnClickListener noClicker = new OnClickListener(){ + public void onClick(View v){ + task = null; + layout.removeView(infoView); + } + }; } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadListFragment.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadListFragment.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadListFragment.java Tue Jan 21 22:43:06 2014 +0100 @@ -43,172 +43,172 @@ public class DownloadListFragment extends ListFragment implements OnItemClickListener, OnScrollListener, Runnable{ - private View targetView = null; - private ArrayList listeners = new ArrayList(); + private View targetView = null; + private ArrayList listeners = new ArrayList(); - public void onActivityCreated(Bundle savedInstanceState){ - super.onActivityCreated(savedInstanceState); + public void onActivityCreated(Bundle savedInstanceState){ + super.onActivityCreated(savedInstanceState); - ArrayList tasks = new ArrayList(); + ArrayList tasks = new ArrayList(); - ArrayAdapter adapter = new ArrayAdapter(getActivity().getApplicationContext(), android.R.layout.simple_list_item_1, tasks); - setListAdapter(adapter); - getListView().setOnItemClickListener(this); - getListView().setOnScrollListener(this); + ArrayAdapter adapter = new ArrayAdapter(getActivity().getApplicationContext(), android.R.layout.simple_list_item_1, tasks); + setListAdapter(adapter); + getListView().setOnItemClickListener(this); + getListView().setOnScrollListener(this); - if(getActivity() instanceof OnItemMovementListener){ - listeners.add((OnItemMovementListener)getActivity()); - } + if(getActivity() instanceof OnItemMovementListener){ + listeners.add((OnItemMovementListener)getActivity()); + } + + getListView().setCacheColorHint(Color.TRANSPARENT);//To prevent a blackish background while scrolling + - getListView().setCacheColorHint(Color.TRANSPARENT);//To prevent a blackish background while scrolling - - - Thread t = new Thread(this, "DownloadListParser"); - t.start(); - } + Thread t = new Thread(this, "DownloadListParser"); + t.start(); + } - public void run(){ - XmlPullParserFactory xmlPullFactory; - try { - xmlPullFactory = XmlPullParserFactory.newInstance(); - XmlPullParser xmlPuller = xmlPullFactory.newPullParser(); + public void run(){ + XmlPullParserFactory xmlPullFactory; + try { + xmlPullFactory = XmlPullParserFactory.newInstance(); + XmlPullParser xmlPuller = xmlPullFactory.newPullParser(); - URL url = new URL("http://www.xelification.com/tmp/downloads.xml"); - HttpURLConnection conn = (HttpURLConnection)url.openConnection(); + URL url = new URL("http://www.xelification.com/tmp/downloads.xml"); + HttpURLConnection conn = (HttpURLConnection)url.openConnection(); + + BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()), 1024); + xmlPuller.setInput(br); - BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()), 1024); - xmlPuller.setInput(br); + final ArrayAdapter adapter = (ArrayAdapter) getListAdapter(); + + int eventType = xmlPuller.getEventType(); + while(eventType != XmlPullParser.END_DOCUMENT){ + + if(eventType == XmlPullParser.START_TAG){ + if(xmlPuller.getName().toLowerCase().equals("task")){ + final DownloadPackage task = DownloadPackage.getTaskFromXML(getActivity(), xmlPuller); - final ArrayAdapter adapter = (ArrayAdapter) getListAdapter(); - - int eventType = xmlPuller.getEventType(); - while(eventType != XmlPullParser.END_DOCUMENT){ - - if(eventType == XmlPullParser.START_TAG){ - if(xmlPuller.getName().toLowerCase().equals("task")){ - final DownloadPackage task = DownloadPackage.getTaskFromXML(getActivity(), xmlPuller); - - getActivity().runOnUiThread(new Runnable(){ - public void run() { - adapter.add(task); - } - }); - } - } - eventType = getEventType(xmlPuller); - } - - - } catch (XmlPullParserException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - } - + getActivity().runOnUiThread(new Runnable(){ + public void run() { + adapter.add(task); + } + }); + } + } + eventType = getEventType(xmlPuller); + } + + + } catch (XmlPullParserException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + - /** - * Skips whitespaces.. - */ - private static int getEventType(XmlPullParser xmlPuller)throws XmlPullParserException, IOException{ - int eventType = xmlPuller.next(); - while(eventType == XmlPullParser.TEXT && xmlPuller.isWhitespace()){ - eventType = xmlPuller.next(); - } - return eventType; - } + /** + * Skips whitespaces.. + */ + private static int getEventType(XmlPullParser xmlPuller)throws XmlPullParserException, IOException{ + int eventType = xmlPuller.next(); + while(eventType == XmlPullParser.TEXT && xmlPuller.isWhitespace()){ + eventType = xmlPuller.next(); + } + return eventType; + } - public void onItemClick(AdapterView arg0, View arg1, int position, long arg3) { - DownloadPackage task = (DownloadPackage)arg0.getAdapter().getItem(position); - /* - FragmentTransaction ft = getFragmentManager().beginTransaction(); - Fragment prev = getFragmentManager().findFragmentByTag("dialog"); + public void onItemClick(AdapterView arg0, View arg1, int position, long arg3) { + DownloadPackage task = (DownloadPackage)arg0.getAdapter().getItem(position); + /* + FragmentTransaction ft = getFragmentManager().beginTransaction(); + Fragment prev = getFragmentManager().findFragmentByTag("dialog"); - //remove any old dialogs - if(prev != null) ft.remove(prev); - ft.addToBackStack(null); + //remove any old dialogs + if(prev != null) ft.remove(prev); + ft.addToBackStack(null); - //create a new dialog based on this task - - DialogFragment newFragment = DownloadDialogFragment.newInstance(task); + //create a new dialog based on this task + + DialogFragment newFragment = DownloadDialogFragment.newInstance(task); - //show it - newFragment.show(ft, "dialog"); - */ - targetView = arg1; + //show it + newFragment.show(ft, "dialog"); + */ + targetView = arg1; - //determine state - int min = arg0.getTop(); - int max = arg0.getBottom(); - int top = targetView.getTop(); + //determine state + int min = arg0.getTop(); + int max = arg0.getBottom(); + int top = targetView.getTop(); - previousXCoord = top; - for(OnItemMovementListener listener : listeners){ - listener.onNewItemSelected(task, top, min, max, targetView.getHeight()*2); - } - } + previousXCoord = top; + for(OnItemMovementListener listener : listeners){ + listener.onNewItemSelected(task, top, min, max, targetView.getHeight()*2); + } + } - private int previousXCoord = 0; + private int previousXCoord = 0; - /* - * (non-Javadoc) - * @see android.widget.AbsListView.OnScrollListener#onScroll(android.widget.AbsListView, int, int, int) - * - * Android renews the Items used in the view, so when a user scroll down the list, - * as soon as the item has dissapeard from the list it gets reused at the bottom. - * - * For this reason we cannot just keep sending the targetView.getTop() but we must - * remember if the view is supposed to be at the top or bottom of the list. We - * remember this with int state, - * - 0 means we've got accurate reading from getTop() - * - -1 means it's somewhere at the top of the list - * - 1 means it's at the bottom somewhere - */ - public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { - if(targetView != null){ - int top = targetView.getTop() + (targetView.getHeight()/2); - int min = view.getTop(); - int max = view.getBottom(); + /* + * (non-Javadoc) + * @see android.widget.AbsListView.OnScrollListener#onScroll(android.widget.AbsListView, int, int, int) + * + * Android renews the Items used in the view, so when a user scroll down the list, + * as soon as the item has dissapeard from the list it gets reused at the bottom. + * + * For this reason we cannot just keep sending the targetView.getTop() but we must + * remember if the view is supposed to be at the top or bottom of the list. We + * remember this with int state, + * - 0 means we've got accurate reading from getTop() + * - -1 means it's somewhere at the top of the list + * - 1 means it's at the bottom somewhere + */ + public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { + if(targetView != null){ + int top = targetView.getTop() + (targetView.getHeight()/2); + int min = view.getTop(); + int max = view.getBottom(); - if(Math.abs(previousXCoord - top) > targetView.getHeight()*2 ){ - top = previousXCoord; - } + if(Math.abs(previousXCoord - top) > targetView.getHeight()*2 ){ + top = previousXCoord; + } - for(OnItemMovementListener listener : listeners){ - listener.onViewMoved(top, min, max); - } + for(OnItemMovementListener listener : listeners){ + listener.onViewMoved(top, min, max); + } - previousXCoord = top; - } - } + previousXCoord = top; + } + } - public void onScrollStateChanged(AbsListView view, int scrollState) { - switch(scrollState){ - case OnScrollListener.SCROLL_STATE_FLING: Log.d("tag", "fling"); break; - case OnScrollListener.SCROLL_STATE_IDLE:Log.d("tag", "idle"); break; - case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:Log.d("tag", "scroll"); break; + public void onScrollStateChanged(AbsListView view, int scrollState) { + switch(scrollState){ + case OnScrollListener.SCROLL_STATE_FLING: Log.d("tag", "fling"); break; + case OnScrollListener.SCROLL_STATE_IDLE:Log.d("tag", "idle"); break; + case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:Log.d("tag", "scroll"); break; - } + } - } + } } interface OnItemMovementListener{ - /** - * When I new item has been selected this method will be called - * @param task The task which goes with this item - * @param x The middle of this item - * @param minX The top of the parent of this item - * @param maxX The bottom of the parent of this item - */ - void onNewItemSelected(DownloadPackage task, int x, int minX, int maxX, int size); + /** + * When I new item has been selected this method will be called + * @param task The task which goes with this item + * @param x The middle of this item + * @param minX The top of the parent of this item + * @param maxX The bottom of the parent of this item + */ + void onNewItemSelected(DownloadPackage task, int x, int minX, int maxX, int size); - /** - * When the item has been moved this method is called - * @param x The middle of this item - * @param minX The top of the parent of this item - * @param maxX The bottom of the parent of this item - */ - void onViewMoved(int x, int minX, int maxX); + /** + * When the item has been moved this method is called + * @param x The middle of this item + * @param minX The top of the parent of this item + * @param maxX The bottom of the parent of this item + */ + void onViewMoved(int x, int minX, int maxX); } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadPackage.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadPackage.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadPackage.java Tue Jan 21 22:43:06 2014 +0100 @@ -32,155 +32,155 @@ import android.preference.PreferenceManager; public class DownloadPackage implements Parcelable{ - private String url_without_suffix; - private String pathToStore; - private String representation; - private String description; - private int versionNumber; - private final Status status; - private int uniqueId; + private String url_without_suffix; + private String pathToStore; + private String representation; + private String description; + private int versionNumber; + private final Status status; + private int uniqueId; - public DownloadPackage(Parcel src){ - url_without_suffix = src.readString(); - pathToStore = src.readString(); - representation = src.readString(); - versionNumber = src.readInt(); - status = Status.values()[src.readInt()]; - description = src.readString(); - uniqueId = src.readInt(); - } + public DownloadPackage(Parcel src){ + url_without_suffix = src.readString(); + pathToStore = src.readString(); + representation = src.readString(); + versionNumber = src.readInt(); + status = Status.values()[src.readInt()]; + description = src.readString(); + uniqueId = src.readInt(); + } - public DownloadPackage(Context c, String _url_without_suffix, String path, int version, String _representation, String _description, int _uniqueId){ - url_without_suffix = _url_without_suffix; - pathToStore = path; - representation = _representation; - versionNumber = version; - description = _description; - uniqueId = _uniqueId; + public DownloadPackage(Context c, String _url_without_suffix, String path, int version, String _representation, String _description, int _uniqueId){ + url_without_suffix = _url_without_suffix; + pathToStore = path; + representation = _representation; + versionNumber = version; + description = _description; + uniqueId = _uniqueId; - //determine if the user has already downloaded this version - SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(c); - int currentVersion = sharedPref.getInt(representation, -1); - if(currentVersion == versionNumber) status = Status.CURRENTVERSION; - else if (currentVersion < versionNumber) status = Status.NEWERVERSION; - else status = Status.OLDERVERSION; - } + //determine if the user has already downloaded this version + SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(c); + int currentVersion = sharedPref.getInt(representation, -1); + if(currentVersion == versionNumber) status = Status.CURRENTVERSION; + else if (currentVersion < versionNumber) status = Status.NEWERVERSION; + else status = Status.OLDERVERSION; + } - public Status getStatus(){ - return status; - } + public Status getStatus(){ + return status; + } - public String getURL(){ - return url_without_suffix; - } + public String getURL(){ + return url_without_suffix; + } - public String getPathToStore(){ - return pathToStore; - } + public String getPathToStore(){ + return pathToStore; + } - public String toString(){ - return representation; - } + public String toString(){ + return representation; + } - public int describeContents() { - return 0; - } - public int getId(){ - return uniqueId; - } + public int describeContents() { + return 0; + } + public int getId(){ + return uniqueId; + } - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(url_without_suffix); - dest.writeString(pathToStore); - dest.writeString(representation); - dest.writeInt(versionNumber); - dest.writeInt(status.ordinal()); - dest.writeString(description); - } + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(url_without_suffix); + dest.writeString(pathToStore); + dest.writeString(representation); + dest.writeInt(versionNumber); + dest.writeInt(status.ordinal()); + dest.writeString(description); + } - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - public DownloadPackage createFromParcel(Parcel source) { - return new DownloadPackage(source); - } - public DownloadPackage[] newArray(int size) { - return new DownloadPackage[size]; - } - }; + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + public DownloadPackage createFromParcel(Parcel source) { + return new DownloadPackage(source); + } + public DownloadPackage[] newArray(int size) { + return new DownloadPackage[size]; + } + }; - /* - * We enter with a XmlPullParser.Start_tag with name "task" - */ - public static DownloadPackage getTaskFromXML(Context c, XmlPullParser xmlPuller) throws XmlPullParserException, IOException{ - String url = null; - String path = null; - String representation = null; - String description = null; - int uniqueId = -1; - int version = -1; + /* + * We enter with a XmlPullParser.Start_tag with name "task" + */ + public static DownloadPackage getTaskFromXML(Context c, XmlPullParser xmlPuller) throws XmlPullParserException, IOException{ + String url = null; + String path = null; + String representation = null; + String description = null; + int uniqueId = -1; + int version = -1; - int eventType = DownloadPackage.getEventType(xmlPuller);//get the next token, should be a start tag - while(eventType != XmlPullParser.END_DOCUMENT){ - switch(eventType){ - case XmlPullParser.START_TAG: - String name = xmlPuller.getName().toLowerCase(); - if(DownloadPackage.getEventType(xmlPuller) == XmlPullParser.TEXT){ - String text = xmlPuller.getText().trim(); - if(name.equals("url")){ - url = text; - }else if(name.equals("version")){ - try{ - version = Integer.parseInt(text); - }catch (NumberFormatException e){ - e.printStackTrace(); - version = -1; - } - }else if(name.equals("path")){ - path = FileUtils.getDataPathFile(c, text).getAbsolutePath(); - }else if(name.equals("representation")){ - representation = text; - }else if(name.equals("description")){ - description = text; - }else if(name.equals("uniqueid")){ - try{ - uniqueId = Integer.parseInt(text); - }catch (NumberFormatException e){ - e.printStackTrace(); - version = -1; - } - } - } - DownloadPackage.getEventType(xmlPuller);//endtag - break; - case XmlPullParser.END_TAG: - if(xmlPuller.getName().toLowerCase().equals("task") && url != null && path != null && version != -1 && representation != null){ - return new DownloadPackage(c, url, path, version, representation, description, uniqueId); - }else{ - throw new XmlPullParserException("XML download parsing: missing tags"); - } - case XmlPullParser.TEXT: - throw new XmlPullParserException("Wrong tag recieved got TEXT : " + xmlPuller.getText()); - default: - throw new XmlPullParserException("Wrong tag recieved got: " + eventType); - } - eventType = DownloadPackage.getEventType(xmlPuller); - } - throw new XmlPullParserException("Xml: unexpected endofdocument tag"); - } + int eventType = DownloadPackage.getEventType(xmlPuller);//get the next token, should be a start tag + while(eventType != XmlPullParser.END_DOCUMENT){ + switch(eventType){ + case XmlPullParser.START_TAG: + String name = xmlPuller.getName().toLowerCase(); + if(DownloadPackage.getEventType(xmlPuller) == XmlPullParser.TEXT){ + String text = xmlPuller.getText().trim(); + if(name.equals("url")){ + url = text; + }else if(name.equals("version")){ + try{ + version = Integer.parseInt(text); + }catch (NumberFormatException e){ + e.printStackTrace(); + version = -1; + } + }else if(name.equals("path")){ + path = FileUtils.getDataPathFile(c, text).getAbsolutePath(); + }else if(name.equals("representation")){ + representation = text; + }else if(name.equals("description")){ + description = text; + }else if(name.equals("uniqueid")){ + try{ + uniqueId = Integer.parseInt(text); + }catch (NumberFormatException e){ + e.printStackTrace(); + version = -1; + } + } + } + DownloadPackage.getEventType(xmlPuller);//endtag + break; + case XmlPullParser.END_TAG: + if(xmlPuller.getName().toLowerCase().equals("task") && url != null && path != null && version != -1 && representation != null){ + return new DownloadPackage(c, url, path, version, representation, description, uniqueId); + }else{ + throw new XmlPullParserException("XML download parsing: missing tags"); + } + case XmlPullParser.TEXT: + throw new XmlPullParserException("Wrong tag recieved got TEXT : " + xmlPuller.getText()); + default: + throw new XmlPullParserException("Wrong tag recieved got: " + eventType); + } + eventType = DownloadPackage.getEventType(xmlPuller); + } + throw new XmlPullParserException("Xml: unexpected endofdocument tag"); + } - /** - * Skips whitespaces.. - */ - private static int getEventType(XmlPullParser xmlPuller)throws XmlPullParserException, IOException{ - int eventType = xmlPuller.next(); - while(eventType == XmlPullParser.TEXT && xmlPuller.isWhitespace()){ - eventType = xmlPuller.next(); - } - return eventType; - } + /** + * Skips whitespaces.. + */ + private static int getEventType(XmlPullParser xmlPuller)throws XmlPullParserException, IOException{ + int eventType = xmlPuller.next(); + while(eventType == XmlPullParser.TEXT && xmlPuller.isWhitespace()){ + eventType = xmlPuller.next(); + } + return eventType; + } } enum Status{ - CURRENTVERSION, NEWERVERSION, OLDERVERSION; + CURRENTVERSION, NEWERVERSION, OLDERVERSION; } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadService.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadService.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadService.java Tue Jan 21 22:43:06 2014 +0100 @@ -37,194 +37,194 @@ import android.widget.RemoteViews; public class DownloadService extends Service { - public final static String INTENT_TASKID = "taskId"; - public final static String INTENT_TASK = "task"; + public final static String INTENT_TASKID = "taskId"; + public final static String INTENT_TASK = "task"; - public static final String PREF_DOWNLOADED = "downloaded"; - public static final int MSG_CANCEL = 0; - public static final int MSG_UNREGISTER_CLIENT = 2; - public final static int MSG_ADDTASK = 4; + public static final String PREF_DOWNLOADED = "downloaded"; + public static final int MSG_CANCEL = 0; + public static final int MSG_UNREGISTER_CLIENT = 2; + public final static int MSG_ADDTASK = 4; - public static final int NOTIFICATION_PROCESSING = 0; - public static final int NOTIFICATION_DONE = 1; + public static final int NOTIFICATION_PROCESSING = 0; + public static final int NOTIFICATION_DONE = 1; - private DownloadAsyncTask asyncExecutor; + private DownloadAsyncTask asyncExecutor; - private DownloadHandler handler = new DownloadHandler(); - private final Messenger messenger = new Messenger(handler); + private DownloadHandler handler = new DownloadHandler(); + private final Messenger messenger = new Messenger(handler); - private NotificationManager nM; - private RemoteViews contentView; + private NotificationManager nM; + private RemoteViews contentView; - private LinkedList downloadTasks = new LinkedList(); - private DownloadTask currentTask = null; + private LinkedList downloadTasks = new LinkedList(); + private DownloadTask currentTask = null; - public class DownloadHandler extends Handler{ + public class DownloadHandler extends Handler{ - public void handleMessage(Message msg){ - if(msg.obj != null){ - DownloadPackage pack = (DownloadPackage) msg.obj; - DownloadTask task = null; - Messenger replyToMessenger = msg.replyTo; - for(DownloadTask _task : downloadTasks){ - if(_task.getPackage().equals(pack)){ - task = _task; - break; - } - } + public void handleMessage(Message msg){ + if(msg.obj != null){ + DownloadPackage pack = (DownloadPackage) msg.obj; + DownloadTask task = null; + Messenger replyToMessenger = msg.replyTo; + for(DownloadTask _task : downloadTasks){ + if(_task.getPackage().equals(pack)){ + task = _task; + break; + } + } - switch(msg.what){ - case MSG_ADDTASK: - if(task == null){ - task = new DownloadTask(pack); - downloadTasks.add(task); - } + switch(msg.what){ + case MSG_ADDTASK: + if(task == null){ + task = new DownloadTask(pack); + downloadTasks.add(task); + } - task.addClient(replyToMessenger); - runNextTask(); - return; - case MSG_CANCEL: - if(task != null && task.getPackage().equals(pack) && task.getStatus() == TASK_STATE.PENDING){ - downloadTasks.remove(task); - } - if(currentTask != null && currentTask.getPackage().equals(pack)){//TODO synchronization problem? - asyncExecutor.cancel(false); - } - return; - case MSG_UNREGISTER_CLIENT: - if(task != null){ - task.removeClient(replyToMessenger); - } - return; - } - } - } - } + task.addClient(replyToMessenger); + runNextTask(); + return; + case MSG_CANCEL: + if(task != null && task.getPackage().equals(pack) && task.getStatus() == TASK_STATE.PENDING){ + downloadTasks.remove(task); + } + if(currentTask != null && currentTask.getPackage().equals(pack)){//TODO synchronization problem? + asyncExecutor.cancel(false); + } + return; + case MSG_UNREGISTER_CLIENT: + if(task != null){ + task.removeClient(replyToMessenger); + } + return; + } + } + } + } - public void onCreate(){ - super.onCreate(); - nM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); - } - public IBinder onBind(Intent intent) { - return messenger.getBinder(); - } + public void onCreate(){ + super.onCreate(); + nM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); + } + public IBinder onBind(Intent intent) { + return messenger.getBinder(); + } - private void runNextTask(){ - if(asyncExecutor == null){//if (task isnt running right now) ... - currentTask = downloadTasks.poll(); - if(currentTask != null){ - asyncExecutor = new DownloadAsyncTask(currentTask); - asyncExecutor.execute(currentTask.getPackage()); - } - } - } + private void runNextTask(){ + if(asyncExecutor == null){//if (task isnt running right now) ... + currentTask = downloadTasks.poll(); + if(currentTask != null){ + asyncExecutor = new DownloadAsyncTask(currentTask); + asyncExecutor.execute(currentTask.getPackage()); + } + } + } - public void onDestroy(){ - super.onDestroy(); - asyncExecutor.cancel(false); - } + public void onDestroy(){ + super.onDestroy(); + asyncExecutor.cancel(false); + } - class DownloadTask { - private final DownloadPackage pack; - private TASK_STATE status = TASK_STATE.PENDING; - private Notification progressNotification, doneNotification; + class DownloadTask { + private final DownloadPackage pack; + private TASK_STATE status = TASK_STATE.PENDING; + private Notification progressNotification, doneNotification; - //I expect little to no removeClient calls that's why we go for a list rather than a map - private final List clients; + //I expect little to no removeClient calls that's why we go for a list rather than a map + private final List clients; - public DownloadTask(DownloadPackage _pack){ - pack = _pack; - clients = new LinkedList(); - } + public DownloadTask(DownloadPackage _pack){ + pack = _pack; + clients = new LinkedList(); + } - public void addClient(Messenger messenger){ - clients.add(messenger); - } - public void removeClient(Messenger messenger){ - clients.remove(messenger); - } + public void addClient(Messenger messenger){ + clients.add(messenger); + } + public void removeClient(Messenger messenger){ + clients.remove(messenger); + } - public DownloadPackage getPackage(){ - return pack; - } + public DownloadPackage getPackage(){ + return pack; + } - public TASK_STATE getStatus(){ - return status; - } + public TASK_STATE getStatus(){ + return status; + } - public void sendMessageToClients(Message msg){ - for(Messenger messenger : clients){ - try { - messenger.send(msg); - } catch (RemoteException e) { - e.printStackTrace(); - } - } - } + public void sendMessageToClients(Message msg){ + for(Messenger messenger : clients){ + try { + messenger.send(msg); + } catch (RemoteException e) { + e.printStackTrace(); + } + } + } - /* - * Callbacks called from the async tasks - */ + /* + * Callbacks called from the async tasks + */ - //Thread safe method to let clients know the processing is starting and will process int max kbytes - public void start(int max){ - progressNotification = new Notification(R.drawable.statusbar, getString(R.string.notification_title), System.currentTimeMillis()); - progressNotification.flags |= Notification.FLAG_ONGOING_EVENT; + //Thread safe method to let clients know the processing is starting and will process int max kbytes + public void start(int max){ + progressNotification = new Notification(R.drawable.statusbar, getString(R.string.notification_title), System.currentTimeMillis()); + progressNotification.flags |= Notification.FLAG_ONGOING_EVENT; - contentView = new RemoteViews(getPackageName(), R.layout.notification); - contentView.setProgressBar(R.id.notification_progress, 100, 34, false); - progressNotification.contentView = contentView; + contentView = new RemoteViews(getPackageName(), R.layout.notification); + contentView.setProgressBar(R.id.notification_progress, 100, 34, false); + progressNotification.contentView = contentView; - PendingIntent contentIntent = PendingIntent.getActivity(DownloadService.this, 0, new Intent(DownloadService.this, DownloadListActivity.class), Intent.FLAG_ACTIVITY_NEW_TASK); - progressNotification.contentIntent = contentIntent; + PendingIntent contentIntent = PendingIntent.getActivity(DownloadService.this, 0, new Intent(DownloadService.this, DownloadListActivity.class), Intent.FLAG_ACTIVITY_NEW_TASK); + progressNotification.contentIntent = contentIntent; - startForeground(NOTIFICATION_PROCESSING, progressNotification); + startForeground(NOTIFICATION_PROCESSING, progressNotification); - Message msg = Message.obtain(null, DownloadFragment.MSG_START, max, 0); - sendMessageToClients(msg); - } + Message msg = Message.obtain(null, DownloadFragment.MSG_START, max, 0); + sendMessageToClients(msg); + } - //periodically gets called by the ASyncTask, we can't tell for sure when it's called - public void update(int progress, int max, String fileName){ - progress = (progress/1024); + //periodically gets called by the ASyncTask, we can't tell for sure when it's called + public void update(int progress, int max, String fileName){ + progress = (progress/1024); - contentView.setProgressBar(R.id.notification_progress, max, progress, false); - contentView.setTextViewText(R.id.progressbar_sub, String.format("%dkb/%dkb (Compressed sizes)", progress, max)); - nM.notify(NOTIFICATION_PROCESSING, progressNotification); + contentView.setProgressBar(R.id.notification_progress, max, progress, false); + contentView.setTextViewText(R.id.progressbar_sub, String.format("%dkb/%dkb (Compressed sizes)", progress, max)); + nM.notify(NOTIFICATION_PROCESSING, progressNotification); - sendMessageToClients(Message.obtain(handler, DownloadFragment.MSG_UPDATE, progress, max, fileName)); - } + sendMessageToClients(Message.obtain(handler, DownloadFragment.MSG_UPDATE, progress, max, fileName)); + } - //Call back from the ASync task when the task has either run into an error or finished otherwise - public void done(int result){ - switch(result){ - case DownloadAsyncTask.EXIT_SUCCESS: sendMessageToClients(Message.obtain(handler, DownloadFragment.MSG_DONE)); break; - case DownloadAsyncTask.EXIT_CONNERROR: sendMessageToClients(Message.obtain(handler, DownloadFragment.MSG_FAILED, DownloadAsyncTask.EXIT_CONNERROR, 0)); break; - case DownloadAsyncTask.EXIT_FNF: sendMessageToClients(Message.obtain(handler, DownloadFragment.MSG_FAILED, DownloadAsyncTask.EXIT_FNF, 0)); break; - case DownloadAsyncTask.EXIT_MD5: sendMessageToClients(Message.obtain(handler, DownloadFragment.MSG_FAILED, DownloadAsyncTask.EXIT_MD5, 0)); break; - case DownloadAsyncTask.EXIT_URLFAIL: sendMessageToClients(Message.obtain(handler, DownloadFragment.MSG_FAILED, DownloadAsyncTask.EXIT_URLFAIL, 0)); break; - case DownloadAsyncTask.EXIT_CANCELLED: sendMessageToClients(Message.obtain(handler, DownloadFragment.MSG_DONE)); break; - } - - stopForeground(true); - nM.cancel(NOTIFICATION_PROCESSING); + //Call back from the ASync task when the task has either run into an error or finished otherwise + public void done(int result){ + switch(result){ + case DownloadAsyncTask.EXIT_SUCCESS: sendMessageToClients(Message.obtain(handler, DownloadFragment.MSG_DONE)); break; + case DownloadAsyncTask.EXIT_CONNERROR: sendMessageToClients(Message.obtain(handler, DownloadFragment.MSG_FAILED, DownloadAsyncTask.EXIT_CONNERROR, 0)); break; + case DownloadAsyncTask.EXIT_FNF: sendMessageToClients(Message.obtain(handler, DownloadFragment.MSG_FAILED, DownloadAsyncTask.EXIT_FNF, 0)); break; + case DownloadAsyncTask.EXIT_MD5: sendMessageToClients(Message.obtain(handler, DownloadFragment.MSG_FAILED, DownloadAsyncTask.EXIT_MD5, 0)); break; + case DownloadAsyncTask.EXIT_URLFAIL: sendMessageToClients(Message.obtain(handler, DownloadFragment.MSG_FAILED, DownloadAsyncTask.EXIT_URLFAIL, 0)); break; + case DownloadAsyncTask.EXIT_CANCELLED: sendMessageToClients(Message.obtain(handler, DownloadFragment.MSG_DONE)); break; + } - String title = getString(R.string.notification_title); + stopForeground(true); + nM.cancel(NOTIFICATION_PROCESSING); + + String title = getString(R.string.notification_title); - doneNotification = new Notification(R.drawable.icon, title, System.currentTimeMillis()); - doneNotification.flags |= Notification.FLAG_AUTO_CANCEL; - PendingIntent contentIntent = PendingIntent.getActivity(DownloadService.this, 0, new Intent(DownloadService.this, DownloadListActivity.class), Intent.FLAG_ACTIVITY_NEW_TASK); - doneNotification.setLatestEventInfo(DownloadService.this, title, getString(R.string.notification_done) + pack, contentIntent); - nM.notify(pack.getId(), doneNotification); + doneNotification = new Notification(R.drawable.icon, title, System.currentTimeMillis()); + doneNotification.flags |= Notification.FLAG_AUTO_CANCEL; + PendingIntent contentIntent = PendingIntent.getActivity(DownloadService.this, 0, new Intent(DownloadService.this, DownloadListActivity.class), Intent.FLAG_ACTIVITY_NEW_TASK); + doneNotification.setLatestEventInfo(DownloadService.this, title, getString(R.string.notification_done) + pack, contentIntent); + nM.notify(pack.getId(), doneNotification); - asyncExecutor = null; - runNextTask();//see if there are more tasks - } + asyncExecutor = null; + runNextTask();//see if there are more tasks + } - } + } - enum TASK_STATE{ - RUNNING, FINISHED, PENDING; - } + enum TASK_STATE{ + RUNNING, FINISHED, PENDING; + } } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/PascalExports.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/PascalExports.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/PascalExports.java Tue Jan 21 22:43:06 2014 +0100 @@ -21,28 +21,28 @@ package org.hedgewars.hedgeroid.EngineProtocol; public class PascalExports { - public static Object engineMutex = new Object(); + public static Object engineMutex = new Object(); - static{ - System.loadLibrary("SDL"); - System.loadLibrary("SDL_image"); - System.loadLibrary("mikmod"); - System.loadLibrary("SDL_net"); - System.loadLibrary("SDL_mixer"); - System.loadLibrary("SDL_ttf"); - System.loadLibrary("lua5.1"); - System.loadLibrary("physfs"); - System.loadLibrary("physlayer"); - System.loadLibrary("hwengine"); - } - - public static native int HWgetMaxNumberOfTeams(); + static{ + System.loadLibrary("SDL"); + System.loadLibrary("SDL_image"); + System.loadLibrary("mikmod"); + System.loadLibrary("SDL_net"); + System.loadLibrary("SDL_mixer"); + System.loadLibrary("SDL_ttf"); + System.loadLibrary("lua5.1"); + System.loadLibrary("physfs"); + System.loadLibrary("physlayer"); + System.loadLibrary("hwengine"); + } + + public static native int HWgetMaxNumberOfTeams(); private static native void HWGenLandPreview(int port); public static void synchronizedGenLandPreview(int port) { - synchronized(engineMutex) { - HWGenLandPreview(port); - } + synchronized(engineMutex) { + HWGenLandPreview(port); + } } - + } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/GameConnection.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/GameConnection.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/GameConnection.java Tue Jan 21 22:43:06 2014 +0100 @@ -48,175 +48,175 @@ * This class handles both talking to the engine (IPC) for running a game, and * coordinating with the netconn if it is a netgame, using the frontlib for the * actual IPC networking communication. - * + * * After creating the GameConnection object, it will communicate with the engine * on its own thread. It shuts itself down as soon as the connection to the engine * is lost. */ public final class GameConnection { - private static final Handler mainHandler = new Handler(Looper.getMainLooper()); - - public final int port; - private final HandlerThread thread; - private final Handler handler; - private TickHandler tickHandler; - private final Netplay netplay; // ==null if not a netgame - private GameconnPtr conn; - - private GameConnection(GameconnPtr conn, Netplay netplay) { - this.conn = conn; - this.port = Flib.INSTANCE.flib_gameconn_getport(conn); - this.netplay = netplay; - this.thread = new HandlerThread("IPCThread"); - thread.start(); - this.handler = new Handler(thread.getLooper()); - } - - private void setupConnection() { - tickHandler = new TickHandler(thread.getLooper(), 50, tickCb); - tickHandler.start(); - - if(netplay != null) { - mainHandler.post(new Runnable() { - public void run() { - netplay.registerGameMessageListener(gameMessageListener); - } - }); - Flib.INSTANCE.flib_gameconn_onChat(conn, chatCb, null); - Flib.INSTANCE.flib_gameconn_onEngineMessage(conn, engineMessageCb, null); - } - Flib.INSTANCE.flib_gameconn_onConnect(conn, connectCb, null); - Flib.INSTANCE.flib_gameconn_onDisconnect(conn, disconnectCb, null); - Flib.INSTANCE.flib_gameconn_onErrorMessage(conn, errorMessageCb, null); - } - - /** - * Start a new IPC server to communicate with the engine. - * Performs networking operations, don't run on the UI thread. - * @throws ConnectException if we can't set up the IPC server - */ - public static GameConnection forNetgame(final GameConfig config, Netplay netplay) throws ConnectException { - final String playerName = netplay.getPlayerName(); - GameconnPtr conn = Flib.INSTANCE.flib_gameconn_create(playerName, GameSetupPtr.createJavaOwned(config), true); - if(conn == null) { - throw new ConnectException(); - } - GameConnection result = new GameConnection(conn, netplay); - result.setupConnection(); - return result; - } - - /** - * Start a new IPC server to communicate with the engine. - * Performs networking operations, don't run on the UI thread. - * @throws ConnectException if we can't set up the IPC server - */ - public static GameConnection forLocalGame(final GameConfig config) throws ConnectException { - GameconnPtr conn = Flib.INSTANCE.flib_gameconn_create("Player", GameSetupPtr.createJavaOwned(config), false); - if(conn == null) { - throw new ConnectException(); - } - GameConnection result = new GameConnection(conn, null); - result.setupConnection(); - return result; - } - - private final Runnable tickCb = new Runnable() { - public void run() { - Flib.INSTANCE.flib_gameconn_tick(conn); - } - }; - - // runs on the IPCThread - private void shutdown() { - tickHandler.stop(); - thread.quit(); - Flib.INSTANCE.flib_gameconn_destroy(conn); - conn = null; - if(netplay != null) { - mainHandler.post(new Runnable() { - public void run() { - netplay.unregisterGameMessageListener(gameMessageListener); - } - }); - } - } - - // runs on the IPCThread - private final StrBoolCallback chatCb = new StrBoolCallback() { - public void callback(Pointer context, String message, boolean teamChat) { - if(teamChat) { - netplay.sendTeamChat(message); - } else { - netplay.sendChat(message); - } - } - }; - - // runs on the IPCThread - private final VoidCallback connectCb = new VoidCallback() { - public void callback(Pointer context) { - Log.i("GameConnection", "Connected"); - } - }; - - // runs on the IPCThread - private final IntCallback disconnectCb = new IntCallback() { - public void callback(Pointer context, int reason) { - if(netplay != null) { - netplay.sendRoundFinished(reason==Frontlib.GAME_END_FINISHED); - } - shutdown(); - } - }; - - // runs on the IPCThread - private final BytesCallback engineMessageCb = new BytesCallback() { - public void callback(Pointer context, ByteArrayPtr buffer, NativeSizeT size) { - netplay.sendEngineMessage(buffer.deref(size.intValue())); - } - }; - - // runs on the IPCThread - private final StrCallback errorMessageCb = new StrCallback() { - public void callback(Pointer context, String message) { - Log.e("GameConnection", message); - } - }; - - // runs on any thread - private final GameMessageListener gameMessageListener = new GameMessageListener() { - public void onNetDisconnected() { - handler.post(new Runnable() { - public void run() { - Flib.INSTANCE.flib_gameconn_send_quit(conn); - } - }); - } - - public void onMessage(final int type, final String message) { - handler.post(new Runnable() { - public void run() { - Flib.INSTANCE.flib_gameconn_send_textmsg(conn, type, message); - } - }); - } - - public void onEngineMessage(final byte[] em) { - handler.post(new Runnable() { - public void run() { - ByteArrayPtr ptr = ByteArrayPtr.createJavaOwned(em); - Flib.INSTANCE.flib_gameconn_send_enginemsg(conn, ptr, NativeSizeT.valueOf(em.length)); - } - }); - } - - public void onChatMessage(final String nick, final String message) { - handler.post(new Runnable() { - public void run() { - Flib.INSTANCE.flib_gameconn_send_chatmsg(conn, nick, message); - } - }); - } - }; + private static final Handler mainHandler = new Handler(Looper.getMainLooper()); + + public final int port; + private final HandlerThread thread; + private final Handler handler; + private TickHandler tickHandler; + private final Netplay netplay; // ==null if not a netgame + private GameconnPtr conn; + + private GameConnection(GameconnPtr conn, Netplay netplay) { + this.conn = conn; + this.port = Flib.INSTANCE.flib_gameconn_getport(conn); + this.netplay = netplay; + this.thread = new HandlerThread("IPCThread"); + thread.start(); + this.handler = new Handler(thread.getLooper()); + } + + private void setupConnection() { + tickHandler = new TickHandler(thread.getLooper(), 50, tickCb); + tickHandler.start(); + + if(netplay != null) { + mainHandler.post(new Runnable() { + public void run() { + netplay.registerGameMessageListener(gameMessageListener); + } + }); + Flib.INSTANCE.flib_gameconn_onChat(conn, chatCb, null); + Flib.INSTANCE.flib_gameconn_onEngineMessage(conn, engineMessageCb, null); + } + Flib.INSTANCE.flib_gameconn_onConnect(conn, connectCb, null); + Flib.INSTANCE.flib_gameconn_onDisconnect(conn, disconnectCb, null); + Flib.INSTANCE.flib_gameconn_onErrorMessage(conn, errorMessageCb, null); + } + + /** + * Start a new IPC server to communicate with the engine. + * Performs networking operations, don't run on the UI thread. + * @throws ConnectException if we can't set up the IPC server + */ + public static GameConnection forNetgame(final GameConfig config, Netplay netplay) throws ConnectException { + final String playerName = netplay.getPlayerName(); + GameconnPtr conn = Flib.INSTANCE.flib_gameconn_create(playerName, GameSetupPtr.createJavaOwned(config), true); + if(conn == null) { + throw new ConnectException(); + } + GameConnection result = new GameConnection(conn, netplay); + result.setupConnection(); + return result; + } + + /** + * Start a new IPC server to communicate with the engine. + * Performs networking operations, don't run on the UI thread. + * @throws ConnectException if we can't set up the IPC server + */ + public static GameConnection forLocalGame(final GameConfig config) throws ConnectException { + GameconnPtr conn = Flib.INSTANCE.flib_gameconn_create("Player", GameSetupPtr.createJavaOwned(config), false); + if(conn == null) { + throw new ConnectException(); + } + GameConnection result = new GameConnection(conn, null); + result.setupConnection(); + return result; + } + + private final Runnable tickCb = new Runnable() { + public void run() { + Flib.INSTANCE.flib_gameconn_tick(conn); + } + }; + + // runs on the IPCThread + private void shutdown() { + tickHandler.stop(); + thread.quit(); + Flib.INSTANCE.flib_gameconn_destroy(conn); + conn = null; + if(netplay != null) { + mainHandler.post(new Runnable() { + public void run() { + netplay.unregisterGameMessageListener(gameMessageListener); + } + }); + } + } + + // runs on the IPCThread + private final StrBoolCallback chatCb = new StrBoolCallback() { + public void callback(Pointer context, String message, boolean teamChat) { + if(teamChat) { + netplay.sendTeamChat(message); + } else { + netplay.sendChat(message); + } + } + }; + + // runs on the IPCThread + private final VoidCallback connectCb = new VoidCallback() { + public void callback(Pointer context) { + Log.i("GameConnection", "Connected"); + } + }; + + // runs on the IPCThread + private final IntCallback disconnectCb = new IntCallback() { + public void callback(Pointer context, int reason) { + if(netplay != null) { + netplay.sendRoundFinished(reason==Frontlib.GAME_END_FINISHED); + } + shutdown(); + } + }; + + // runs on the IPCThread + private final BytesCallback engineMessageCb = new BytesCallback() { + public void callback(Pointer context, ByteArrayPtr buffer, NativeSizeT size) { + netplay.sendEngineMessage(buffer.deref(size.intValue())); + } + }; + + // runs on the IPCThread + private final StrCallback errorMessageCb = new StrCallback() { + public void callback(Pointer context, String message) { + Log.e("GameConnection", message); + } + }; + + // runs on any thread + private final GameMessageListener gameMessageListener = new GameMessageListener() { + public void onNetDisconnected() { + handler.post(new Runnable() { + public void run() { + Flib.INSTANCE.flib_gameconn_send_quit(conn); + } + }); + } + + public void onMessage(final int type, final String message) { + handler.post(new Runnable() { + public void run() { + Flib.INSTANCE.flib_gameconn_send_textmsg(conn, type, message); + } + }); + } + + public void onEngineMessage(final byte[] em) { + handler.post(new Runnable() { + public void run() { + ByteArrayPtr ptr = ByteArrayPtr.createJavaOwned(em); + Flib.INSTANCE.flib_gameconn_send_enginemsg(conn, ptr, NativeSizeT.valueOf(em.length)); + } + }); + } + + public void onChatMessage(final String nick, final String message) { + handler.post(new Runnable() { + public void run() { + Flib.INSTANCE.flib_gameconn_send_chatmsg(conn, nick, message); + } + }); + } + }; } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/LobbyActivity.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/LobbyActivity.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/LobbyActivity.java Tue Jan 21 22:43:06 2014 +0100 @@ -38,103 +38,103 @@ /** * Activity for the server lobby of a hedgewars server. Allows you to chat, join * and create rooms and interact with a list of players. - * + * * Most of the functionality is handled by various fragments. */ public class LobbyActivity extends FragmentActivity implements TextInputDialogListener, NetplayStateListener { - private static final int DIALOG_CREATE_ROOM = 0; - + private static final int DIALOG_CREATE_ROOM = 0; + private TabHost tabHost; private Netplay netplay; - + @Override protected void onCreate(Bundle icicle) { super.onCreate(icicle); - + setContentView(R.layout.activity_lobby); ChatFragment chatFragment = (ChatFragment)getSupportFragmentManager().findFragmentById(R.id.chatFragment); chatFragment.setInRoom(false); - + FragmentTransaction trans = getSupportFragmentManager().beginTransaction(); trans.add(new NetplayStateFragment(), "netplayFragment"); trans.commit(); - + netplay = Netplay.getAppInstance(getApplicationContext()); - + // Set up a tabbed UI for medium and small screens tabHost = (TabHost)findViewById(android.R.id.tabhost); if(tabHost != null) { - tabHost.setup(); - tabHost.getTabWidget().setOrientation(LinearLayout.VERTICAL); + tabHost.setup(); + tabHost.getTabWidget().setOrientation(LinearLayout.VERTICAL); - tabHost.addTab(tabHost.newTabSpec("rooms").setIndicator(UiUtils.createVerticalTabIndicator(tabHost, R.string.lobby_tab_rooms, R.drawable.roomlist_ingame)).setContent(R.id.roomListFragment)); - tabHost.addTab(tabHost.newTabSpec("chat").setIndicator(UiUtils.createVerticalTabIndicator(tabHost, R.string.lobby_tab_chat, R.drawable.edit)).setContent(R.id.chatFragment)); - tabHost.addTab(tabHost.newTabSpec("players").setIndicator(UiUtils.createVerticalTabIndicator(tabHost, R.string.lobby_tab_players, R.drawable.human)).setContent(R.id.playerListFragment)); - - if (icicle != null) { - tabHost.setCurrentTabByTag(icicle.getString("currentTab")); - } + tabHost.addTab(tabHost.newTabSpec("rooms").setIndicator(UiUtils.createVerticalTabIndicator(tabHost, R.string.lobby_tab_rooms, R.drawable.roomlist_ingame)).setContent(R.id.roomListFragment)); + tabHost.addTab(tabHost.newTabSpec("chat").setIndicator(UiUtils.createVerticalTabIndicator(tabHost, R.string.lobby_tab_chat, R.drawable.edit)).setContent(R.id.chatFragment)); + tabHost.addTab(tabHost.newTabSpec("players").setIndicator(UiUtils.createVerticalTabIndicator(tabHost, R.string.lobby_tab_players, R.drawable.human)).setContent(R.id.playerListFragment)); + + if (icicle != null) { + tabHost.setCurrentTabByTag(icicle.getString("currentTab")); + } } } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - super.onCreateOptionsMenu(menu); - getMenuInflater().inflate(R.menu.lobby_options, menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch(item.getItemId()) { - case R.id.room_create: - TextInputDialog dialog = new TextInputDialog(DIALOG_CREATE_ROOM, R.string.dialog_create_room_title, 0, R.string.dialog_create_room_hint); - dialog.show(getSupportFragmentManager(), "create_room_dialog"); - return true; - case R.id.disconnect: - netplay.disconnect(); - return true; - default: - return super.onOptionsItemSelected(item); - } - } - - @Override - public void onBackPressed() { - netplay.disconnect(); - } - + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + super.onCreateOptionsMenu(menu); + getMenuInflater().inflate(R.menu.lobby_options, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch(item.getItemId()) { + case R.id.room_create: + TextInputDialog dialog = new TextInputDialog(DIALOG_CREATE_ROOM, R.string.dialog_create_room_title, 0, R.string.dialog_create_room_hint); + dialog.show(getSupportFragmentManager(), "create_room_dialog"); + return true; + case R.id.disconnect: + netplay.disconnect(); + return true; + default: + return super.onOptionsItemSelected(item); + } + } + + @Override + public void onBackPressed() { + netplay.disconnect(); + } + @Override protected void onSaveInstanceState(Bundle icicle) { super.onSaveInstanceState(icicle); if(tabHost != null) { - icicle.putString("currentTab", tabHost.getCurrentTabTag()); + icicle.putString("currentTab", tabHost.getCurrentTabTag()); } } - + public void onTextInputDialogSubmitted(int dialogId, String text) { - if(text != null && text.length()>0) { - netplay.sendCreateRoom(text); - } + if(text != null && text.length()>0) { + netplay.sendCreateRoom(text); + } } - + public void onTextInputDialogCancelled(int dialogId) { } - + public void onNetplayStateChanged(State newState) { - switch(newState) { - case CONNECTING: - case NOT_CONNECTED: - finish(); - break; - case ROOM: - startActivity(new Intent(getApplicationContext(), NetRoomActivity.class)); - break; - case LOBBY: - // Do nothing - break; - default: - throw new IllegalStateException("Unknown connection state: "+newState); - } + switch(newState) { + case CONNECTING: + case NOT_CONNECTED: + finish(); + break; + case ROOM: + startActivity(new Intent(getApplicationContext(), NetRoomActivity.class)); + break; + case LOBBY: + // Do nothing + break; + default: + throw new IllegalStateException("Unknown connection state: "+newState); + } } } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/LobbyPlayerlistAdapter.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/LobbyPlayerlistAdapter.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/LobbyPlayerlistAdapter.java Tue Jan 21 22:43:06 2014 +0100 @@ -41,28 +41,28 @@ * Simple adapter for displaying the list of players in the lobby. */ public class LobbyPlayerlistAdapter extends ObservableTreeMapAdapter { - @Override - protected Comparator getEntryOrder() { - return Player.ADMIN_NAME_ORDER; - } + @Override + protected Comparator getEntryOrder() { + return Player.ADMIN_NAME_ORDER; + } - public View getView(int position, View convertView, ViewGroup parent) { - View v = convertView; - if (v == null) { - LayoutInflater vi = LayoutInflater.from(parent.getContext()); - v = vi.inflate(R.layout.listview_player, null); - } + public View getView(int position, View convertView, ViewGroup parent) { + View v = convertView; + if (v == null) { + LayoutInflater vi = LayoutInflater.from(parent.getContext()); + v = vi.inflate(R.layout.listview_player, null); + } - Player player = getItem(position); - TextView username = (TextView) v.findViewById(android.R.id.text1); - Spannable spannable = new SpannableString(player.name); - if(player.registered) { - spannable.setSpan(new StyleSpan(Typeface.BOLD), 0, spannable.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - } - if(player.admin) { - spannable.setSpan(new ForegroundColorSpan(Color.YELLOW), 0, spannable.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - } - username.setText(spannable); - return v; - } + Player player = getItem(position); + TextView username = (TextView) v.findViewById(android.R.id.text1); + Spannable spannable = new SpannableString(player.name); + if(player.registered) { + spannable.setSpan(new StyleSpan(Typeface.BOLD), 0, spannable.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + } + if(player.admin) { + spannable.setSpan(new ForegroundColorSpan(Color.YELLOW), 0, spannable.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + } + username.setText(spannable); + return v; + } } \ No newline at end of file diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/LobbyPlayerlistFragment.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/LobbyPlayerlistFragment.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/LobbyPlayerlistFragment.java Tue Jan 21 22:43:06 2014 +0100 @@ -39,60 +39,60 @@ * over the context menu. */ public class LobbyPlayerlistFragment extends ListFragment { - private Netplay netplay; - private LobbyPlayerlistAdapter adapter; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - netplay = Netplay.getAppInstance(getActivity().getApplicationContext()); - adapter = new LobbyPlayerlistAdapter(); - adapter.setSource(netplay.lobbyPlayerlist); - setListAdapter(adapter); - } + private Netplay netplay; + private LobbyPlayerlistAdapter adapter; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + netplay = Netplay.getAppInstance(getActivity().getApplicationContext()); + adapter = new LobbyPlayerlistAdapter(); + adapter.setSource(netplay.lobbyPlayerlist); + setListAdapter(adapter); + } - @Override - public void onDestroy() { - super.onDestroy(); - adapter.invalidate(); - } - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - registerForContextMenu(getListView()); - } + @Override + public void onDestroy() { + super.onDestroy(); + adapter.invalidate(); + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + registerForContextMenu(getListView()); + } - @Override - public void onCreateContextMenu(ContextMenu menu, View v, - ContextMenuInfo menuInfo) { - super.onCreateContextMenu(menu, v, menuInfo); - AdapterContextMenuInfo info = (AdapterContextMenuInfo)menuInfo; - MenuInflater inflater = getActivity().getMenuInflater(); - inflater.inflate(R.menu.lobby_playerlist_context, menu); - menu.setHeaderIcon(R.drawable.human); - menu.setHeaderTitle(adapter.getItem(info.position).name); - } - - @Override - public boolean onContextItemSelected(MenuItem item) { - AdapterContextMenuInfo info = (AdapterContextMenuInfo)item.getMenuInfo(); - Player player = adapter.getItem(info.position); - switch(item.getItemId()) { - case R.id.player_info: - netplay.sendPlayerInfoQuery(player.name); - return true; - case R.id.player_follow: - netplay.sendFollowPlayer(player.name); - return true; - default: - return super.onContextItemSelected(item); - } - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - return inflater.inflate(R.layout.fragment_playerlist, container, false); - } + @Override + public void onCreateContextMenu(ContextMenu menu, View v, + ContextMenuInfo menuInfo) { + super.onCreateContextMenu(menu, v, menuInfo); + AdapterContextMenuInfo info = (AdapterContextMenuInfo)menuInfo; + MenuInflater inflater = getActivity().getMenuInflater(); + inflater.inflate(R.menu.lobby_playerlist_context, menu); + menu.setHeaderIcon(R.drawable.human); + menu.setHeaderTitle(adapter.getItem(info.position).name); + } + + @Override + public boolean onContextItemSelected(MenuItem item) { + AdapterContextMenuInfo info = (AdapterContextMenuInfo)item.getMenuInfo(); + Player player = adapter.getItem(info.position); + switch(item.getItemId()) { + case R.id.player_info: + netplay.sendPlayerInfoQuery(player.name); + return true; + case R.id.player_follow: + netplay.sendFollowPlayer(player.name); + return true; + default: + return super.onContextItemSelected(item); + } + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_playerlist, container, false); + } } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/LocalRoomActivity.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/LocalRoomActivity.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/LocalRoomActivity.java Tue Jan 21 22:43:06 2014 +0100 @@ -44,78 +44,78 @@ * This activity is used to set up and start a local game. */ public class LocalRoomActivity extends FragmentActivity implements RoomStateManager.Provider, TeamAddDialog.Listener { - private TabHost tabHost; - private RoomStateManager stateManager; - private Button startButton; - + private TabHost tabHost; + private RoomStateManager stateManager; + private Button startButton; + @Override protected void onCreate(Bundle icicle) { super.onCreate(icicle); // TODO find a better central location / way to set up the default scheme and weaponset Netplay netplay = Netplay.getAppInstance(getApplicationContext()); stateManager = new LocalRoomStateManager(netplay.defaultScheme, netplay.defaultWeaponset); - + setContentView(R.layout.activity_localroom); startButton = (Button)findViewById(R.id.startGame); - + startButton.setOnClickListener(startButtonClickListener); - + // Set up a tabbed UI for medium and small screens tabHost = (TabHost)findViewById(android.R.id.tabhost); if(tabHost != null) { - tabHost.setup(); - tabHost.getTabWidget().setOrientation(LinearLayout.VERTICAL); + tabHost.setup(); + tabHost.getTabWidget().setOrientation(LinearLayout.VERTICAL); - tabHost.addTab(tabHost.newTabSpec("map").setIndicator(UiUtils.createVerticalTabIndicator(tabHost, R.string.room_tab_map, 0)).setContent(R.id.mapFragment)); - tabHost.addTab(tabHost.newTabSpec("settings").setIndicator(UiUtils.createVerticalTabIndicator(tabHost, R.string.room_tab_settings, 0)).setContent(R.id.settingsFragment)); - tabHost.addTab(tabHost.newTabSpec("teams").setIndicator(UiUtils.createVerticalTabIndicator(tabHost, R.string.room_tab_teams, 0)).setContent(R.id.teamlistContainer)); - - if (icicle != null) { - tabHost.setCurrentTabByTag(icicle.getString("currentTab")); - } + tabHost.addTab(tabHost.newTabSpec("map").setIndicator(UiUtils.createVerticalTabIndicator(tabHost, R.string.room_tab_map, 0)).setContent(R.id.mapFragment)); + tabHost.addTab(tabHost.newTabSpec("settings").setIndicator(UiUtils.createVerticalTabIndicator(tabHost, R.string.room_tab_settings, 0)).setContent(R.id.settingsFragment)); + tabHost.addTab(tabHost.newTabSpec("teams").setIndicator(UiUtils.createVerticalTabIndicator(tabHost, R.string.room_tab_teams, 0)).setContent(R.id.teamlistContainer)); + + if (icicle != null) { + tabHost.setCurrentTabByTag(icicle.getString("currentTab")); + } } } - + @Override protected void onSaveInstanceState(Bundle icicle) { super.onSaveInstanceState(icicle); if(tabHost != null) { - icicle.putString("currentTab", tabHost.getCurrentTabTag()); + icicle.putString("currentTab", tabHost.getCurrentTabTag()); } } - - public void onTeamAddDialogSubmitted(Team newTeam) { - stateManager.requestAddTeam(newTeam, TeamInGame.getUnusedOrRandomColorIndex(stateManager.getTeams().values())); - } - - public RoomStateManager getRoomStateManager() { - return stateManager; - } + + public void onTeamAddDialogSubmitted(Team newTeam) { + stateManager.requestAddTeam(newTeam, TeamInGame.getUnusedOrRandomColorIndex(stateManager.getTeams().values())); + } + + public RoomStateManager getRoomStateManager() { + return stateManager; + } - private final OnClickListener startButtonClickListener = new OnClickListener() { - public void onClick(View v) { - Map teams = stateManager.getTeams(); - Set clanColors = new TreeSet(); - for(TeamInGame t : teams.values()) { - clanColors.add(t.ingameAttribs.colorIndex); - } - if(clanColors.size()<2) { - if(tabHost != null) { - tabHost.setCurrentTabByTag("teams"); - } - int errortext = teams.size()<2 ? R.string.not_enough_teams : R.string.not_enough_clans; - Toast.makeText(getApplicationContext(), errortext, Toast.LENGTH_SHORT).show(); - return; - } - - SDLActivity.startNetgame = false; - SDLActivity.startConfig = new GameConfig( - stateManager.getGameStyle(), - stateManager.getScheme(), - stateManager.getMapRecipe(), - new ArrayList(stateManager.getTeams().values()), - stateManager.getWeaponset()); - startActivity(new Intent(LocalRoomActivity.this, SDLActivity.class)); - } - }; + private final OnClickListener startButtonClickListener = new OnClickListener() { + public void onClick(View v) { + Map teams = stateManager.getTeams(); + Set clanColors = new TreeSet(); + for(TeamInGame t : teams.values()) { + clanColors.add(t.ingameAttribs.colorIndex); + } + if(clanColors.size()<2) { + if(tabHost != null) { + tabHost.setCurrentTabByTag("teams"); + } + int errortext = teams.size()<2 ? R.string.not_enough_teams : R.string.not_enough_clans; + Toast.makeText(getApplicationContext(), errortext, Toast.LENGTH_SHORT).show(); + return; + } + + SDLActivity.startNetgame = false; + SDLActivity.startConfig = new GameConfig( + stateManager.getGameStyle(), + stateManager.getScheme(), + stateManager.getMapRecipe(), + new ArrayList(stateManager.getTeams().values()), + stateManager.getWeaponset()); + startActivity(new Intent(LocalRoomActivity.this, SDLActivity.class)); + } + }; } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/LocalRoomStateManager.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/LocalRoomStateManager.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/LocalRoomStateManager.java Tue Jan 21 22:43:06 2014 +0100 @@ -35,80 +35,80 @@ * state. */ public class LocalRoomStateManager extends BasicRoomState { - private static final String TAG = LocalRoomStateManager.class.getSimpleName(); + private static final String TAG = LocalRoomStateManager.class.getSimpleName(); - public LocalRoomStateManager(Scheme defaultScheme, Weaponset defaultWeaponset) { - setChief(true); - setGameStyle(GameConfig.DEFAULT_STYLE); - setMapRecipe(MapRecipe.makeRandomMap(0, MapRecipe.makeRandomSeed(), GameConfig.DEFAULT_THEME)); - setScheme(defaultScheme); - setWeaponset(defaultWeaponset); - } - - public void changeMapRecipe(MapRecipe map) { - setMapRecipe(map); - } + public LocalRoomStateManager(Scheme defaultScheme, Weaponset defaultWeaponset) { + setChief(true); + setGameStyle(GameConfig.DEFAULT_STYLE); + setMapRecipe(MapRecipe.makeRandomMap(0, MapRecipe.makeRandomSeed(), GameConfig.DEFAULT_THEME)); + setScheme(defaultScheme); + setWeaponset(defaultWeaponset); + } - public void changeMapTheme(String theme) { - setMapRecipe(getMapRecipe().withTheme(theme)); - } + public void changeMapRecipe(MapRecipe map) { + setMapRecipe(map); + } + + public void changeMapTheme(String theme) { + setMapRecipe(getMapRecipe().withTheme(theme)); + } - public void changeMapNameAndGenerator(String mapName) { - int newGenerator = MapRecipe.generatorForMapname(mapName); - setMapRecipe(getMapRecipe().withName(mapName).withMapgen(newGenerator)); - } + public void changeMapNameAndGenerator(String mapName) { + int newGenerator = MapRecipe.generatorForMapname(mapName); + setMapRecipe(getMapRecipe().withName(mapName).withMapgen(newGenerator)); + } - public void changeMapTemplate(int template) { - setMapRecipe(getMapRecipe().withTemplateFilter(template)); - } + public void changeMapTemplate(int template) { + setMapRecipe(getMapRecipe().withTemplateFilter(template)); + } - public void changeMazeSize(int mazeSize) { - setMapRecipe(getMapRecipe().withMazeSize(mazeSize)); - } + public void changeMazeSize(int mazeSize) { + setMapRecipe(getMapRecipe().withMazeSize(mazeSize)); + } - public void changeMapSeed(String seed) { - setMapRecipe(getMapRecipe().withSeed(seed)); - } + public void changeMapSeed(String seed) { + setMapRecipe(getMapRecipe().withSeed(seed)); + } - public void changeMapDrawdata(byte[] drawdata) { - setMapRecipe(getMapRecipe().withDrawData(drawdata)); - } + public void changeMapDrawdata(byte[] drawdata) { + setMapRecipe(getMapRecipe().withDrawData(drawdata)); + } - public void changeScheme(Scheme scheme) { - setScheme(scheme); - } + public void changeScheme(Scheme scheme) { + setScheme(scheme); + } - public void changeGameStyle(String style) { - setGameStyle(style); - } + public void changeGameStyle(String style) { + setGameStyle(style); + } - public void changeWeaponset(Weaponset weaponset) { - setWeaponset(weaponset); - } + public void changeWeaponset(Weaponset weaponset) { + setWeaponset(weaponset); + } - public void requestAddTeam(Team team, int colorIndex) { - putTeam(new TeamInGame(team, new TeamIngameAttributes("Player", colorIndex, TeamIngameAttributes.DEFAULT_HOG_COUNT, false))); - } + public void requestAddTeam(Team team, int colorIndex) { + putTeam(new TeamInGame(team, new TeamIngameAttributes("Player", colorIndex, TeamIngameAttributes.DEFAULT_HOG_COUNT, false))); + } - public void requestRemoveTeam(String teamname) { - removeTeam(teamname); - } + public void requestRemoveTeam(String teamname) { + removeTeam(teamname); + } - public void changeTeamColorIndex(String teamname, int colorIndex) { - TeamInGame oldTeam = getTeams().get(teamname); - if(oldTeam != null) { - putTeam(oldTeam.withAttribs(oldTeam.ingameAttribs.withColorIndex(colorIndex))); - } else { - Log.e(TAG, "Requested color change for unknown team "+ teamname); - } - } + public void changeTeamColorIndex(String teamname, int colorIndex) { + TeamInGame oldTeam = getTeams().get(teamname); + if(oldTeam != null) { + putTeam(oldTeam.withAttribs(oldTeam.ingameAttribs.withColorIndex(colorIndex))); + } else { + Log.e(TAG, "Requested color change for unknown team "+ teamname); + } + } - public void changeTeamHogCount(String teamname, int hogcount) { - TeamInGame oldTeam = getTeams().get(teamname); - if(oldTeam != null) { - putTeam(oldTeam.withAttribs(oldTeam.ingameAttribs.withHogCount(hogcount))); - } else { - Log.e(TAG, "Requested hog count change for unknown team "+ teamname); - } - } + public void changeTeamHogCount(String teamname, int hogcount) { + TeamInGame oldTeam = getTeams().get(teamname); + if(oldTeam != null) { + putTeam(oldTeam.withAttribs(oldTeam.ingameAttribs.withHogCount(hogcount))); + } else { + Log.e(TAG, "Requested hog count change for unknown team "+ teamname); + } + } } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/MainActivity.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/MainActivity.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/MainActivity.java Tue Jan 21 22:43:06 2014 +0100 @@ -49,175 +49,175 @@ import android.widget.Toast; public class MainActivity extends FragmentActivity { - private static final int DIALOG_NO_SDCARD = 0; - - private LocalBroadcastManager broadcastManager; - private ProgressDialog assetsDialog; + private static final int DIALOG_NO_SDCARD = 0; + + private LocalBroadcastManager broadcastManager; + private ProgressDialog assetsDialog; + + public void onCreate(Bundle sis){ + super.onCreate(sis); + setContentView(R.layout.activity_main); + + broadcastManager = LocalBroadcastManager.getInstance(getApplicationContext()); + Button startLocalGame = (Button)findViewById(R.id.startGame); + Button startNetGame = (Button)findViewById(R.id.joinLobby); + + startLocalGame.setOnClickListener(startGameListener); + startNetGame.setOnClickListener(startNetGameListener); - public void onCreate(Bundle sis){ - super.onCreate(sis); - setContentView(R.layout.activity_main); + if(!FileUtils.isDataPathAvailable()){ + showDialog(DIALOG_NO_SDCARD); + } else { + String existingVersion = ""; + try { + File versionFile = new File(FileUtils.getCachePath(this), "assetsversion.txt"); + existingVersion = FileUtils.readToString(new FileInputStream(versionFile)); + } catch(IOException e) { + } - broadcastManager = LocalBroadcastManager.getInstance(getApplicationContext()); - Button startLocalGame = (Button)findViewById(R.id.startGame); - Button startNetGame = (Button)findViewById(R.id.joinLobby); - - startLocalGame.setOnClickListener(startGameListener); - startNetGame.setOnClickListener(startNetGameListener); + String newVersion = ""; + try { + newVersion = FileUtils.readToString(getAssets().open("assetsversion.txt")); + } catch(IOException e) { + } - if(!FileUtils.isDataPathAvailable()){ - showDialog(DIALOG_NO_SDCARD); - } else { - String existingVersion = ""; - try { - File versionFile = new File(FileUtils.getCachePath(this), "assetsversion.txt"); - existingVersion = FileUtils.readToString(new FileInputStream(versionFile)); - } catch(IOException e) { - } - - String newVersion = ""; - try { - newVersion = FileUtils.readToString(getAssets().open("assetsversion.txt")); - } catch(IOException e) { - } - - if(!existingVersion.equals(newVersion)) { - DownloadAssets assetsAsyncTask = new DownloadAssets(this); - assetsDialog = ProgressDialog.show(this, "Please wait a moment", "Moving assets to SD card..."); - assetsAsyncTask.execute(); - } - } - } + if(!existingVersion.equals(newVersion)) { + DownloadAssets assetsAsyncTask = new DownloadAssets(this); + assetsDialog = ProgressDialog.show(this, "Please wait a moment", "Moving assets to SD card..."); + assetsAsyncTask.execute(); + } + } + } + + @Override + protected void onResume() { + super.onResume(); + broadcastManager.registerReceiver(connectedReceiver, new IntentFilter(Netplay.ACTION_CONNECTED)); + broadcastManager.registerReceiver(connectionFailedReceiver, new IntentFilter(Netplay.ACTION_DISCONNECTED)); + broadcastManager.registerReceiver(passwordRequestedReceiver, new IntentFilter(Netplay.ACTION_PASSWORD_REQUESTED)); + } + + @Override + protected void onPause() { + super.onPause(); + broadcastManager.unregisterReceiver(connectedReceiver); + broadcastManager.unregisterReceiver(connectionFailedReceiver); + broadcastManager.unregisterReceiver(passwordRequestedReceiver); + Netplay netplay = Netplay.getAppInstance(getApplicationContext()); + if(netplay.getState() == State.CONNECTING) { + netplay.disconnect(); + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + super.onCreateOptionsMenu(menu); + getMenuInflater().inflate(R.menu.main_options, menu); + return true; + } - @Override - protected void onResume() { - super.onResume(); - broadcastManager.registerReceiver(connectedReceiver, new IntentFilter(Netplay.ACTION_CONNECTED)); - broadcastManager.registerReceiver(connectionFailedReceiver, new IntentFilter(Netplay.ACTION_DISCONNECTED)); - broadcastManager.registerReceiver(passwordRequestedReceiver, new IntentFilter(Netplay.ACTION_PASSWORD_REQUESTED)); - } - - @Override - protected void onPause() { - super.onPause(); - broadcastManager.unregisterReceiver(connectedReceiver); - broadcastManager.unregisterReceiver(connectionFailedReceiver); - broadcastManager.unregisterReceiver(passwordRequestedReceiver); - Netplay netplay = Netplay.getAppInstance(getApplicationContext()); - if(netplay.getState() == State.CONNECTING) { - netplay.disconnect(); - } - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - super.onCreateOptionsMenu(menu); - getMenuInflater().inflate(R.menu.main_options, menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch(item.getItemId()) { - case R.id.download: - startActivityForResult(new Intent(this, DownloadListActivity.class), 0); - return true; - case R.id.preferences: - Toast.makeText(this, R.string.not_implemented_yet, Toast.LENGTH_SHORT).show(); - return true; - case R.id.edit_weaponsets: - startActivity(new Intent(this, WeaponsetListActivity.class)); - return true; - case R.id.edit_teams: - startActivity(new Intent(this, TeamListActivity.class)); - return true; - default: - return super.onOptionsItemSelected(item); - } - } - - public Dialog onCreateDialog(int id, Bundle args){ - switch(id) { - case DIALOG_NO_SDCARD: - return createNoSdcardDialog(); - default: - throw new IndexOutOfBoundsException(); - } - } + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch(item.getItemId()) { + case R.id.download: + startActivityForResult(new Intent(this, DownloadListActivity.class), 0); + return true; + case R.id.preferences: + Toast.makeText(this, R.string.not_implemented_yet, Toast.LENGTH_SHORT).show(); + return true; + case R.id.edit_weaponsets: + startActivity(new Intent(this, WeaponsetListActivity.class)); + return true; + case R.id.edit_teams: + startActivity(new Intent(this, TeamListActivity.class)); + return true; + default: + return super.onOptionsItemSelected(item); + } + } + + public Dialog onCreateDialog(int id, Bundle args){ + switch(id) { + case DIALOG_NO_SDCARD: + return createNoSdcardDialog(); + default: + throw new IndexOutOfBoundsException(); + } + } + + private Dialog createNoSdcardDialog() { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(R.string.sdcard_not_mounted_title); + builder.setMessage(R.string.sdcard_not_mounted); + builder.setNegativeButton(android.R.string.ok, new DialogInterface.OnClickListener(){ + public void onClick(DialogInterface dialog, int which) { + finish(); + } + }); + + return builder.create(); + } + + public void onAssetsDownloaded(boolean result){ + if(!result){ + Toast.makeText(this, R.string.download_failed, Toast.LENGTH_LONG).show(); + } + assetsDialog.dismiss(); + } - private Dialog createNoSdcardDialog() { - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle(R.string.sdcard_not_mounted_title); - builder.setMessage(R.string.sdcard_not_mounted); - builder.setNegativeButton(android.R.string.ok, new DialogInterface.OnClickListener(){ - public void onClick(DialogInterface dialog, int which) { - finish(); - } - }); + private final OnClickListener startGameListener = new OnClickListener(){ + public void onClick(View v){ + startActivity(new Intent(getApplicationContext(), LocalRoomActivity.class)); + } + }; - return builder.create(); - } - - public void onAssetsDownloaded(boolean result){ - if(!result){ - Toast.makeText(this, R.string.download_failed, Toast.LENGTH_LONG).show(); - } - assetsDialog.dismiss(); - } + private final OnClickListener startNetGameListener = new OnClickListener() { + public void onClick(View v) { + State state = Netplay.getAppInstance(getApplicationContext()).getState(); + switch(state) { + case NOT_CONNECTED: + FragmentManager fm = getSupportFragmentManager(); + StartNetgameDialog startNetgameDialog = new StartNetgameDialog(); + startNetgameDialog.show(fm, "start_netgame_dialog"); + break; + case CONNECTING: + onNetConnectingStarted(); + break; + default: + startActivity(new Intent(getApplicationContext(), LobbyActivity.class)); + break; + } + } + }; - private final OnClickListener startGameListener = new OnClickListener(){ - public void onClick(View v){ - startActivity(new Intent(getApplicationContext(), LocalRoomActivity.class)); - } - }; - - private final OnClickListener startNetGameListener = new OnClickListener() { - public void onClick(View v) { - State state = Netplay.getAppInstance(getApplicationContext()).getState(); - switch(state) { - case NOT_CONNECTED: - FragmentManager fm = getSupportFragmentManager(); - StartNetgameDialog startNetgameDialog = new StartNetgameDialog(); - startNetgameDialog.show(fm, "start_netgame_dialog"); - break; - case CONNECTING: - onNetConnectingStarted(); - break; - default: - startActivity(new Intent(getApplicationContext(), LobbyActivity.class)); - break; - } - } - }; - - private BroadcastReceiver connectedReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - startActivity(new Intent(getApplicationContext(), LobbyActivity.class)); - } - }; - - private BroadcastReceiver connectionFailedReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if(intent.getBooleanExtra(Netplay.EXTRA_HAS_ERROR, true)) { - Toast.makeText(getApplicationContext(), intent.getStringExtra(Netplay.EXTRA_MESSAGE), Toast.LENGTH_LONG).show(); - } - } - }; - - private BroadcastReceiver passwordRequestedReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - FragmentManager fm = getSupportFragmentManager(); - PasswordDialog passwordDialog = new PasswordDialog(intent.getStringExtra(Netplay.EXTRA_PLAYERNAME)); - passwordDialog.show(fm, "fragment_password_dialog"); - } - }; + private BroadcastReceiver connectedReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + startActivity(new Intent(getApplicationContext(), LobbyActivity.class)); + } + }; - public void onNetConnectingStarted() { + private BroadcastReceiver connectionFailedReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if(intent.getBooleanExtra(Netplay.EXTRA_HAS_ERROR, true)) { + Toast.makeText(getApplicationContext(), intent.getStringExtra(Netplay.EXTRA_MESSAGE), Toast.LENGTH_LONG).show(); + } + } + }; + + private BroadcastReceiver passwordRequestedReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + FragmentManager fm = getSupportFragmentManager(); + PasswordDialog passwordDialog = new PasswordDialog(intent.getStringExtra(Netplay.EXTRA_PLAYERNAME)); + passwordDialog.show(fm, "fragment_password_dialog"); + } + }; + + public void onNetConnectingStarted() { FragmentManager fm = getSupportFragmentManager(); ConnectingDialog connectingDialog = new ConnectingDialog(); connectingDialog.show(fm, "fragment_connecting_dialog"); - } + } } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/MapFragment.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/MapFragment.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/MapFragment.java Tue Jan 21 22:43:06 2014 +0100 @@ -50,225 +50,225 @@ /** * Display a map preview, and configuration options for the map. - * + * * Mostly for layout reasons, this does not include the theme setting, which * (arguably) is more a map setting than a general game setting. */ public class MapFragment extends Fragment { - private Spinner mapTypeSpinner, mapNameSpinner, templateSpinner, mazeSizeSpinner; - private TableRow nameRow, templateRow, mazeSizeRow; - private ImageView mapPreview; - - private List mapFiles; - private RoomStateManager stateManager; - private Random random = new Random(); - private CalmDownHandler mapPreviewHandler; - - /* - * Rendering the preview can take a few seconds on Android, so we want to prevent preview - * requests from queueing up if maps are changed quickly. So if there is already a preview - * being generated, we store our latest request in the newPreviewRequest variable instead. - * Once the current preview is finished generating it will start on that one. - */ - private boolean previewGenerationInProgress; - private MapRecipe newPreviewRequest; - private MapRecipe currentMap; // kept for reference on every change to find out what changed - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View v = inflater.inflate(R.layout.fragment_map, container, false); - final Context appContext = getActivity().getApplicationContext(); + private Spinner mapTypeSpinner, mapNameSpinner, templateSpinner, mazeSizeSpinner; + private TableRow nameRow, templateRow, mazeSizeRow; + private ImageView mapPreview; + + private List mapFiles; + private RoomStateManager stateManager; + private Random random = new Random(); + private CalmDownHandler mapPreviewHandler; + + /* + * Rendering the preview can take a few seconds on Android, so we want to prevent preview + * requests from queueing up if maps are changed quickly. So if there is already a preview + * being generated, we store our latest request in the newPreviewRequest variable instead. + * Once the current preview is finished generating it will start on that one. + */ + private boolean previewGenerationInProgress; + private MapRecipe newPreviewRequest; + private MapRecipe currentMap; // kept for reference on every change to find out what changed + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View v = inflater.inflate(R.layout.fragment_map, container, false); + final Context appContext = getActivity().getApplicationContext(); + + /* + * This handler will start the map preview after none of the map settings + * have been updated for a short time. + */ + mapPreviewHandler = new CalmDownHandler(getActivity().getMainLooper(), new Runnable() { + public void run() { + if(!previewGenerationInProgress) { + mapPreview.setImageResource(R.drawable.roomlist_preparing); + MapPreviewGenerator.startPreviewGeneration(appContext, stateManager.getMapRecipe(), mapPreviewListener); + previewGenerationInProgress = true; + } else { + newPreviewRequest = stateManager.getMapRecipe(); + } + } + }, 250); + + nameRow = (TableRow) v.findViewById(R.id.rowMapName); + templateRow = (TableRow) v.findViewById(R.id.rowTemplateFilter); + mazeSizeRow = (TableRow) v.findViewById(R.id.rowMazeSize); + mapPreview = (ImageView) v.findViewById(R.id.mapPreview); + mapPreview.setImageDrawable(null);; + mapPreview.setOnClickListener(mapClickListener); - /* - * This handler will start the map preview after none of the map settings - * have been updated for a short time. - */ - mapPreviewHandler = new CalmDownHandler(getActivity().getMainLooper(), new Runnable() { - public void run() { - if(!previewGenerationInProgress) { - mapPreview.setImageResource(R.drawable.roomlist_preparing); - MapPreviewGenerator.startPreviewGeneration(appContext, stateManager.getMapRecipe(), mapPreviewListener); - previewGenerationInProgress = true; - } else { - newPreviewRequest = stateManager.getMapRecipe(); - } - } - }, 250); - - nameRow = (TableRow) v.findViewById(R.id.rowMapName); - templateRow = (TableRow) v.findViewById(R.id.rowTemplateFilter); - mazeSizeRow = (TableRow) v.findViewById(R.id.rowMazeSize); - mapPreview = (ImageView) v.findViewById(R.id.mapPreview); - mapPreview.setImageDrawable(null);; - mapPreview.setOnClickListener(mapClickListener); - - try { - mapFiles = FrontendDataUtils.getMaps(getActivity()); - } catch (IOException e) { - Toast.makeText(getActivity().getApplicationContext(), R.string.error_missing_sdcard_or_files, Toast.LENGTH_LONG).show(); - getActivity().finish(); - return null; - } - Collections.sort(mapFiles, MapFile.MISSIONS_FIRST_NAME_ORDER); - - List mapNames = MapFile.toDisplayNameList(mapFiles, getResources()); - mapTypeSpinner = prepareSpinner(v, R.id.spinMapType, Arrays.asList(getResources().getStringArray(R.array.map_types)), mapTypeSelectedListener); - mapNameSpinner = prepareSpinner(v, R.id.spinMapName, mapNames, mapNameSelectedListener); - templateSpinner = prepareSpinner(v, R.id.spinTemplateFilter, Arrays.asList(getResources().getStringArray(R.array.map_templates)), mapTemplateSelectedListener); - mazeSizeSpinner = prepareSpinner(v, R.id.spinMazeSize, Arrays.asList(getResources().getStringArray(R.array.map_maze_sizes)), mazeSizeSelectedListener); + try { + mapFiles = FrontendDataUtils.getMaps(getActivity()); + } catch (IOException e) { + Toast.makeText(getActivity().getApplicationContext(), R.string.error_missing_sdcard_or_files, Toast.LENGTH_LONG).show(); + getActivity().finish(); + return null; + } + Collections.sort(mapFiles, MapFile.MISSIONS_FIRST_NAME_ORDER); + + List mapNames = MapFile.toDisplayNameList(mapFiles, getResources()); + mapTypeSpinner = prepareSpinner(v, R.id.spinMapType, Arrays.asList(getResources().getStringArray(R.array.map_types)), mapTypeSelectedListener); + mapNameSpinner = prepareSpinner(v, R.id.spinMapName, mapNames, mapNameSelectedListener); + templateSpinner = prepareSpinner(v, R.id.spinTemplateFilter, Arrays.asList(getResources().getStringArray(R.array.map_templates)), mapTemplateSelectedListener); + mazeSizeSpinner = prepareSpinner(v, R.id.spinMazeSize, Arrays.asList(getResources().getStringArray(R.array.map_maze_sizes)), mazeSizeSelectedListener); + + stateManager.addListener(roomStateChangeListener); + currentMap = stateManager.getMapRecipe(); + if(currentMap != null) { + updateDisplay(currentMap); + } + setChiefState(stateManager.getChiefStatus()); + mapPreviewHandler.activity(); + return v; + } + + private static Spinner prepareSpinner(View v, int id, List items, OnItemSelectedListener itemSelectedListener) { + Spinner spinner = (Spinner)v.findViewById(id); + ArrayAdapter adapter = new ArrayAdapter(v.getContext(), R.layout.listview_item, items); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + spinner.setAdapter(adapter); + spinner.setOnItemSelectedListener(itemSelectedListener); + return spinner; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + try { + stateManager = ((RoomStateManager.Provider)getActivity()).getRoomStateManager(); + } catch(ClassCastException e) { + throw new RuntimeException("Hosting activity must implement RoomStateManager.Provider.", e); + } + } + + @Override + public void onDestroy() { + super.onDestroy(); + mapPreviewHandler.stop(); + newPreviewRequest = null; + + stateManager.removeListener(roomStateChangeListener); + } + + private void setChiefState(boolean chiefState) { + mapTypeSpinner.setEnabled(chiefState); + mapNameSpinner.setEnabled(chiefState); + templateSpinner.setEnabled(chiefState); + mazeSizeSpinner.setEnabled(chiefState); + mapPreview.setEnabled(chiefState); - stateManager.addListener(roomStateChangeListener); - currentMap = stateManager.getMapRecipe(); - if(currentMap != null) { - updateDisplay(currentMap); - } - setChiefState(stateManager.getChiefStatus()); - mapPreviewHandler.activity(); - return v; - } - - private static Spinner prepareSpinner(View v, int id, List items, OnItemSelectedListener itemSelectedListener) { - Spinner spinner = (Spinner)v.findViewById(id); - ArrayAdapter adapter = new ArrayAdapter(v.getContext(), R.layout.listview_item, items); - adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - spinner.setAdapter(adapter); - spinner.setOnItemSelectedListener(itemSelectedListener); - return spinner; - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - try { - stateManager = ((RoomStateManager.Provider)getActivity()).getRoomStateManager(); - } catch(ClassCastException e) { - throw new RuntimeException("Hosting activity must implement RoomStateManager.Provider.", e); - } - } - - @Override - public void onDestroy() { - super.onDestroy(); - mapPreviewHandler.stop(); - newPreviewRequest = null; - - stateManager.removeListener(roomStateChangeListener); - } - - private void setChiefState(boolean chiefState) { - mapTypeSpinner.setEnabled(chiefState); - mapNameSpinner.setEnabled(chiefState); - templateSpinner.setEnabled(chiefState); - mazeSizeSpinner.setEnabled(chiefState); - mapPreview.setEnabled(chiefState); - - if(chiefState) { - sendMapnameAndGenerator(); - stateManager.changeMapTemplate(templateSpinner.getSelectedItemPosition()); - stateManager.changeMazeSize(mazeSizeSpinner.getSelectedItemPosition()); - } - } - - private void updateDisplay(MapRecipe map) { - nameRow.setVisibility(map.mapgen == Frontlib.MAPGEN_NAMED ? View.VISIBLE : View.GONE); - templateRow.setVisibility(map.mapgen == Frontlib.MAPGEN_REGULAR ? View.VISIBLE : View.GONE); - mazeSizeRow.setVisibility(map.mapgen == Frontlib.MAPGEN_MAZE ? View.VISIBLE : View.GONE); - - mapTypeSpinner.setSelection(map.mapgen); - int mapPosition = findMapPosition(mapFiles, map.name); - if(mapPosition >= 0) { - mapNameSpinner.setSelection(mapPosition); - } - templateSpinner.setSelection(map.templateFilter); - mazeSizeSpinner.setSelection(map.mazeSize); - } - - private static int findMapPosition(List mapFiles, String mapName) { - for(int i=0; i adapter, View v, int position, long arg3) { - sendMapnameAndGenerator(); - } - public void onNothingSelected(AdapterView arg0) {} - }; - - private final OnItemSelectedListener mapNameSelectedListener = new OnItemSelectedListener() { - public void onItemSelected(AdapterView adapter, View v, int position, long arg3) { - sendMapnameAndGenerator(); - } - public void onNothingSelected(AdapterView arg0) {} - }; - - private final OnItemSelectedListener mapTemplateSelectedListener = new OnItemSelectedListener() { - public void onItemSelected(AdapterView adapter, View v, int position, long arg3) { - stateManager.changeMapTemplate(position); - } - public void onNothingSelected(AdapterView arg0) {} - }; - - private final OnItemSelectedListener mazeSizeSelectedListener = new OnItemSelectedListener() { - public void onItemSelected(AdapterView adapter, View v, int position, long arg3) { - stateManager.changeMazeSize(position); - } - public void onNothingSelected(AdapterView arg0) {} - }; - - private final OnClickListener mapClickListener = new OnClickListener() { - public void onClick(View v) { - stateManager.changeMapSeed(MapRecipe.makeRandomSeed()); - if(mapTypeSpinner.getSelectedItemPosition() == Frontlib.MAPGEN_NAMED) { - mapNameSpinner.setSelection(random.nextInt(mapNameSpinner.getCount())); - } - } - }; - - private final RoomStateManager.Listener roomStateChangeListener = new RoomStateManager.ListenerAdapter() { - @Override - public void onChiefStatusChanged(boolean isChief) { - setChiefState(isChief); - }; - - @Override - public void onMapChanged(MapRecipe recipe) { - // Only trigger a preview update if a relevant field changed (not theme) - if(currentMap==null - || currentMap.mapgen != recipe.mapgen - || currentMap.mazeSize != recipe.mazeSize - || !currentMap.name.equals(recipe.name) - || !currentMap.seed.equals(recipe.seed) - || currentMap.templateFilter != recipe.templateFilter - || !Arrays.equals(currentMap.getDrawData(), recipe.getDrawData())) { - mapPreviewHandler.activity(); - } - updateDisplay(recipe); - currentMap = recipe; - }; - }; - - private MapPreviewGenerator.Listener mapPreviewListener = new MapPreviewGenerator.Listener() { - public void onMapPreviewResult(Drawable preview) { - if(newPreviewRequest != null) { - MapPreviewGenerator.startPreviewGeneration(getActivity().getApplicationContext(), newPreviewRequest, mapPreviewListener); - newPreviewRequest = null; - } else { - if(mapPreview != null) { - mapPreview.setImageDrawable(preview); - } - previewGenerationInProgress = false; - } - } - }; + if(chiefState) { + sendMapnameAndGenerator(); + stateManager.changeMapTemplate(templateSpinner.getSelectedItemPosition()); + stateManager.changeMazeSize(mazeSizeSpinner.getSelectedItemPosition()); + } + } + + private void updateDisplay(MapRecipe map) { + nameRow.setVisibility(map.mapgen == Frontlib.MAPGEN_NAMED ? View.VISIBLE : View.GONE); + templateRow.setVisibility(map.mapgen == Frontlib.MAPGEN_REGULAR ? View.VISIBLE : View.GONE); + mazeSizeRow.setVisibility(map.mapgen == Frontlib.MAPGEN_MAZE ? View.VISIBLE : View.GONE); + + mapTypeSpinner.setSelection(map.mapgen); + int mapPosition = findMapPosition(mapFiles, map.name); + if(mapPosition >= 0) { + mapNameSpinner.setSelection(mapPosition); + } + templateSpinner.setSelection(map.templateFilter); + mazeSizeSpinner.setSelection(map.mazeSize); + } + + private static int findMapPosition(List mapFiles, String mapName) { + for(int i=0; i adapter, View v, int position, long arg3) { + sendMapnameAndGenerator(); + } + public void onNothingSelected(AdapterView arg0) {} + }; + + private final OnItemSelectedListener mapNameSelectedListener = new OnItemSelectedListener() { + public void onItemSelected(AdapterView adapter, View v, int position, long arg3) { + sendMapnameAndGenerator(); + } + public void onNothingSelected(AdapterView arg0) {} + }; + + private final OnItemSelectedListener mapTemplateSelectedListener = new OnItemSelectedListener() { + public void onItemSelected(AdapterView adapter, View v, int position, long arg3) { + stateManager.changeMapTemplate(position); + } + public void onNothingSelected(AdapterView arg0) {} + }; + + private final OnItemSelectedListener mazeSizeSelectedListener = new OnItemSelectedListener() { + public void onItemSelected(AdapterView adapter, View v, int position, long arg3) { + stateManager.changeMazeSize(position); + } + public void onNothingSelected(AdapterView arg0) {} + }; + + private final OnClickListener mapClickListener = new OnClickListener() { + public void onClick(View v) { + stateManager.changeMapSeed(MapRecipe.makeRandomSeed()); + if(mapTypeSpinner.getSelectedItemPosition() == Frontlib.MAPGEN_NAMED) { + mapNameSpinner.setSelection(random.nextInt(mapNameSpinner.getCount())); + } + } + }; + + private final RoomStateManager.Listener roomStateChangeListener = new RoomStateManager.ListenerAdapter() { + @Override + public void onChiefStatusChanged(boolean isChief) { + setChiefState(isChief); + }; + + @Override + public void onMapChanged(MapRecipe recipe) { + // Only trigger a preview update if a relevant field changed (not theme) + if(currentMap==null + || currentMap.mapgen != recipe.mapgen + || currentMap.mazeSize != recipe.mazeSize + || !currentMap.name.equals(recipe.name) + || !currentMap.seed.equals(recipe.seed) + || currentMap.templateFilter != recipe.templateFilter + || !Arrays.equals(currentMap.getDrawData(), recipe.getDrawData())) { + mapPreviewHandler.activity(); + } + updateDisplay(recipe); + currentMap = recipe; + }; + }; + + private MapPreviewGenerator.Listener mapPreviewListener = new MapPreviewGenerator.Listener() { + public void onMapPreviewResult(Drawable preview) { + if(newPreviewRequest != null) { + MapPreviewGenerator.startPreviewGeneration(getActivity().getApplicationContext(), newPreviewRequest, mapPreviewListener); + newPreviewRequest = null; + } else { + if(mapPreview != null) { + mapPreview.setImageDrawable(preview); + } + previewGenerationInProgress = false; + } + } + }; } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/MapPreviewGenerator.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/MapPreviewGenerator.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/MapPreviewGenerator.java Tue Jan 21 22:43:06 2014 +0100 @@ -48,176 +48,176 @@ /** * A class that asynchronously generates a map preview from a MapRecipe. - * + * * For named maps, this will load the preview image from the filesystem. For others, * it will call the Hedgewars engine to generate a preview image. The result is sent * back to a listener on the UI thread. */ public final class MapPreviewGenerator implements Runnable { - private static final String TAG = MapPreviewGenerator.class.getSimpleName(); - private static final Handler mainHandler = new Handler(Looper.getMainLooper()); - private static final long TIMEOUT_NS = 20l * 1000 * 1000 * 1000; + private static final String TAG = MapPreviewGenerator.class.getSimpleName(); + private static final Handler mainHandler = new Handler(Looper.getMainLooper()); + private static final long TIMEOUT_NS = 20l * 1000 * 1000 * 1000; + + private final Context appContext; + private final MapRecipe map; + private final Listener listener; + + private boolean resultAvailable; + private Drawable result; + + public static interface Listener { + /** + * This is called on the UI thread once the preview is ready or failed. + * In case of failure, null is passed. + */ + void onMapPreviewResult(Drawable preview); + } + + private MapPreviewGenerator(Context appContext, MapRecipe map, Listener listener) { + this.appContext = appContext; + this.map = map; + this.listener = listener; + } - private final Context appContext; - private final MapRecipe map; - private final Listener listener; - - private boolean resultAvailable; - private Drawable result; - - public static interface Listener { - /** - * This is called on the UI thread once the preview is ready or failed. - * In case of failure, null is passed. - */ - void onMapPreviewResult(Drawable preview); - } + public void run() { + if (map.mapgen == Frontlib.MAPGEN_NAMED) { + postToListener(loadPreviewFromFile(appContext, map.name)); + } else { + resultAvailable = false; + result = null; + MapconnPtr conn = Flib.INSTANCE.flib_mapconn_create(MapRecipePtr.createJavaOwned(map)); + if (conn == null) { + postToListener(null); + return; + } + try { + int port = Flib.INSTANCE.flib_mapconn_getport(conn); + Flib.INSTANCE.flib_mapconn_onSuccess(conn, successCb, null); + Flib.INSTANCE.flib_mapconn_onFailure(conn, failureCb, null); + + String configPath; + try { + configPath = FileUtils.getCachePath(appContext).getAbsolutePath(); + } catch(FileNotFoundException e) { + return; + } + + startEngine(configPath, port); + long startTime = System.nanoTime(); + do { + Flib.INSTANCE.flib_mapconn_tick(conn); + try { + Thread.sleep(50); + } catch (InterruptedException e) { + // ignore + } + if(System.nanoTime()-startTime > TIMEOUT_NS) { + Log.w(TAG, "Error generating map preview: timeout"); + resultAvailable = true; + } + } while(!resultAvailable); + } finally { + Flib.INSTANCE.flib_mapconn_destroy(conn); + postToListener(result); + } + } + } + + public static void startPreviewGeneration(Context appContext, MapRecipe map, Listener listener) { + new Thread(new MapPreviewGenerator(appContext, map, listener)).start(); + } - private MapPreviewGenerator(Context appContext, MapRecipe map, Listener listener) { - this.appContext = appContext; - this.map = map; - this.listener = listener; - } - - public void run() { - if (map.mapgen == Frontlib.MAPGEN_NAMED) { - postToListener(loadPreviewFromFile(appContext, map.name)); - } else { - resultAvailable = false; - result = null; - MapconnPtr conn = Flib.INSTANCE.flib_mapconn_create(MapRecipePtr.createJavaOwned(map)); - if (conn == null) { - postToListener(null); - return; - } - try { - int port = Flib.INSTANCE.flib_mapconn_getport(conn); - Flib.INSTANCE.flib_mapconn_onSuccess(conn, successCb, null); - Flib.INSTANCE.flib_mapconn_onFailure(conn, failureCb, null); - - String configPath; - try { - configPath = FileUtils.getCachePath(appContext).getAbsolutePath(); - } catch(FileNotFoundException e) { - return; - } - - startEngine(configPath, port); - long startTime = System.nanoTime(); - do { - Flib.INSTANCE.flib_mapconn_tick(conn); - try { - Thread.sleep(50); - } catch (InterruptedException e) { - // ignore - } - if(System.nanoTime()-startTime > TIMEOUT_NS) { - Log.w(TAG, "Error generating map preview: timeout"); - resultAvailable = true; - } - } while(!resultAvailable); - } finally { - Flib.INSTANCE.flib_mapconn_destroy(conn); - postToListener(result); - } - } - } - - public static void startPreviewGeneration(Context appContext, MapRecipe map, Listener listener) { - new Thread(new MapPreviewGenerator(appContext, map, listener)).start(); - } - - private static Drawable loadPreviewFromFile(Context appContext, String mapName) { - if(!mapName.startsWith("+")) { - try { - File previewFile = MapFile.getPreviewFile(appContext, mapName); - return Drawable.createFromPath(previewFile.getAbsolutePath()); - } catch (FileNotFoundException e) { - Log.w("MapPreviewGenerator", "Preview for map "+mapName+" not found."); - } - } - return null; - } - - private static void startEngine(final String configPath, final int port) { - new Thread(new Runnable() { - public void run() { - Log.d(TAG, "Starting engine "+port); - PascalExports.synchronizedGenLandPreview(port); - Log.d(TAG, "Engine finished"); - } - }).start(); - } - - private void postToListener(final Drawable result) { - mainHandler.post(new Runnable() { - public void run() { - listener.onMapPreviewResult(result); - } - }); - } - - /** - * Let's be extra nice here and clip off the left and right sides, so the preview is centered... - * Since the image is present in bytes, we can save some effort by checking entire byte-columns first. - */ - private final MapimageCallback successCb = new MapimageCallback() { - public void callback(Pointer context, ByteArrayPtr buffer, int hedgehogCount) { - byte[] mapdata = buffer.deref(Frontlib.MAPIMAGE_BYTES); - - int leftmostPixel = Frontlib.MAPIMAGE_WIDTH; - int rightmostPixel = -1; - int bytesPerLine = Frontlib.MAPIMAGE_WIDTH/8; - - // Find the leftmost pixel - for(int xbyte=0; xbyte=0; xbyte--) { - for(int y=0; y use default width - if(rightmostPixel==-1) { - leftmostPixel = 0; - rightmostPixel = Frontlib.MAPIMAGE_WIDTH-1; - } - - Bitmap bitmap = Bitmap.createBitmap(rightmostPixel-leftmostPixel+1, Frontlib.MAPIMAGE_HEIGHT, Config.ARGB_8888); - for(int y=0; y>3] & (128>>(pixelnum&7))) != 0; - } - - private final StrCallback failureCb = new StrCallback() { - public void callback(Pointer context, String reason) { - Log.w(TAG, "Error generating map preview: "+reason); - result = null; - resultAvailable = true; - } - }; + private static Drawable loadPreviewFromFile(Context appContext, String mapName) { + if(!mapName.startsWith("+")) { + try { + File previewFile = MapFile.getPreviewFile(appContext, mapName); + return Drawable.createFromPath(previewFile.getAbsolutePath()); + } catch (FileNotFoundException e) { + Log.w("MapPreviewGenerator", "Preview for map "+mapName+" not found."); + } + } + return null; + } + + private static void startEngine(final String configPath, final int port) { + new Thread(new Runnable() { + public void run() { + Log.d(TAG, "Starting engine "+port); + PascalExports.synchronizedGenLandPreview(port); + Log.d(TAG, "Engine finished"); + } + }).start(); + } + + private void postToListener(final Drawable result) { + mainHandler.post(new Runnable() { + public void run() { + listener.onMapPreviewResult(result); + } + }); + } + + /** + * Let's be extra nice here and clip off the left and right sides, so the preview is centered... + * Since the image is present in bytes, we can save some effort by checking entire byte-columns first. + */ + private final MapimageCallback successCb = new MapimageCallback() { + public void callback(Pointer context, ByteArrayPtr buffer, int hedgehogCount) { + byte[] mapdata = buffer.deref(Frontlib.MAPIMAGE_BYTES); + + int leftmostPixel = Frontlib.MAPIMAGE_WIDTH; + int rightmostPixel = -1; + int bytesPerLine = Frontlib.MAPIMAGE_WIDTH/8; + + // Find the leftmost pixel + for(int xbyte=0; xbyte=0; xbyte--) { + for(int y=0; y use default width + if(rightmostPixel==-1) { + leftmostPixel = 0; + rightmostPixel = Frontlib.MAPIMAGE_WIDTH-1; + } + + Bitmap bitmap = Bitmap.createBitmap(rightmostPixel-leftmostPixel+1, Frontlib.MAPIMAGE_HEIGHT, Config.ARGB_8888); + for(int y=0; y>3] & (128>>(pixelnum&7))) != 0; + } + + private final StrCallback failureCb = new StrCallback() { + public void callback(Pointer context, String reason) { + Log.w(TAG, "Error generating map preview: "+reason); + result = null; + resultAvailable = true; + } + }; } \ No newline at end of file diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/NetRoomActivity.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/NetRoomActivity.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/NetRoomActivity.java Tue Jan 21 22:43:06 2014 +0100 @@ -43,11 +43,11 @@ * This activity is used to set up and start a game on the server. */ public class NetRoomActivity extends FragmentActivity implements NetplayStateListener, TeamAddDialog.Listener, RoomStateManager.Provider, RunGameListener { - private TabHost tabHost; - private Netplay netplay; - private RoomStateManager stateManager; - private Button startButton; - + private TabHost tabHost; + private Netplay netplay; + private RoomStateManager stateManager; + private Button startButton; + @Override protected void onCreate(Bundle icicle) { super.onCreate(icicle); @@ -55,97 +55,97 @@ netplay.registerRunGameListener(this); stateManager = netplay.getRoomStateManager(); stateManager.addListener(roomStateChangeListener); - + setContentView(R.layout.activity_netroom); startButton = (Button)findViewById(R.id.startGame); - + ChatFragment chatFragment = (ChatFragment)getSupportFragmentManager().findFragmentById(R.id.chatFragment); chatFragment.setInRoom(true); - + FragmentTransaction trans = getSupportFragmentManager().beginTransaction(); trans.add(new NetplayStateFragment(), "netplayFragment"); trans.commit(); - + startButton.setVisibility(netplay.isChief() ? View.VISIBLE : View.GONE); startButton.setOnClickListener(startButtonClickListener); - + // Set up a tabbed UI for medium and small screens tabHost = (TabHost)findViewById(android.R.id.tabhost); if(tabHost != null) { - tabHost.setup(); - tabHost.getTabWidget().setOrientation(LinearLayout.VERTICAL); + tabHost.setup(); + tabHost.getTabWidget().setOrientation(LinearLayout.VERTICAL); - tabHost.addTab(tabHost.newTabSpec("map").setIndicator(UiUtils.createVerticalTabIndicator(tabHost, R.string.room_tab_map, 0)).setContent(R.id.mapFragment)); - tabHost.addTab(tabHost.newTabSpec("settings").setIndicator(UiUtils.createVerticalTabIndicator(tabHost, R.string.room_tab_settings, 0)).setContent(R.id.settingsFragment)); - tabHost.addTab(tabHost.newTabSpec("teams").setIndicator(UiUtils.createVerticalTabIndicator(tabHost, R.string.room_tab_teams, 0)).setContent(R.id.teamlistFragment)); - tabHost.addTab(tabHost.newTabSpec("chat").setIndicator(UiUtils.createVerticalTabIndicator(tabHost, R.string.room_tab_chat, 0)).setContent(R.id.chatFragment)); - tabHost.addTab(tabHost.newTabSpec("players").setIndicator(UiUtils.createVerticalTabIndicator(tabHost, R.string.room_tab_players, 0)).setContent(R.id.playerListContainer)); - - if (icicle != null) { - tabHost.setCurrentTabByTag(icicle.getString("currentTab")); - } + tabHost.addTab(tabHost.newTabSpec("map").setIndicator(UiUtils.createVerticalTabIndicator(tabHost, R.string.room_tab_map, 0)).setContent(R.id.mapFragment)); + tabHost.addTab(tabHost.newTabSpec("settings").setIndicator(UiUtils.createVerticalTabIndicator(tabHost, R.string.room_tab_settings, 0)).setContent(R.id.settingsFragment)); + tabHost.addTab(tabHost.newTabSpec("teams").setIndicator(UiUtils.createVerticalTabIndicator(tabHost, R.string.room_tab_teams, 0)).setContent(R.id.teamlistFragment)); + tabHost.addTab(tabHost.newTabSpec("chat").setIndicator(UiUtils.createVerticalTabIndicator(tabHost, R.string.room_tab_chat, 0)).setContent(R.id.chatFragment)); + tabHost.addTab(tabHost.newTabSpec("players").setIndicator(UiUtils.createVerticalTabIndicator(tabHost, R.string.room_tab_players, 0)).setContent(R.id.playerListContainer)); + + if (icicle != null) { + tabHost.setCurrentTabByTag(icicle.getString("currentTab")); + } } } @Override protected void onDestroy() { - super.onDestroy(); - stateManager.removeListener(roomStateChangeListener); - netplay.unregisterRunGameListener(this); + super.onDestroy(); + stateManager.removeListener(roomStateChangeListener); + netplay.unregisterRunGameListener(this); } - - @Override - public void onBackPressed() { - netplay.sendLeaveRoom(null); - } - + + @Override + public void onBackPressed() { + netplay.sendLeaveRoom(null); + } + @Override protected void onSaveInstanceState(Bundle icicle) { super.onSaveInstanceState(icicle); if(tabHost != null) { - icicle.putString("currentTab", tabHost.getCurrentTabTag()); + icicle.putString("currentTab", tabHost.getCurrentTabTag()); + } + } + + public void onNetplayStateChanged(State newState) { + switch(newState) { + case NOT_CONNECTED: + case CONNECTING: + case LOBBY: + finish(); + break; + case ROOM: + // Do nothing + break; + default: + throw new IllegalStateException("Unknown connection state: "+newState); } } - - public void onNetplayStateChanged(State newState) { - switch(newState) { - case NOT_CONNECTED: - case CONNECTING: - case LOBBY: - finish(); - break; - case ROOM: - // Do nothing - break; - default: - throw new IllegalStateException("Unknown connection state: "+newState); - } + + public void onTeamAddDialogSubmitted(Team newTeam) { + stateManager.requestAddTeam(newTeam, TeamInGame.getUnusedOrRandomColorIndex(stateManager.getTeams().values())); + } + + public RoomStateManager getRoomStateManager() { + return stateManager; } - - public void onTeamAddDialogSubmitted(Team newTeam) { - stateManager.requestAddTeam(newTeam, TeamInGame.getUnusedOrRandomColorIndex(stateManager.getTeams().values())); - } - - public RoomStateManager getRoomStateManager() { - return stateManager; - } + + private final OnClickListener startButtonClickListener = new OnClickListener() { + public void onClick(View v) { + netplay.sendStartGame(); + } + }; - private final OnClickListener startButtonClickListener = new OnClickListener() { - public void onClick(View v) { - netplay.sendStartGame(); - } - }; - - private final RoomStateManager.Listener roomStateChangeListener = new RoomStateManager.ListenerAdapter() { - @Override - public void onChiefStatusChanged(boolean isChief) { - startButton.setVisibility(isChief ? View.VISIBLE : View.GONE); - } - }; - - public void runGame(GameConfig config) { - SDLActivity.startConfig = config; - SDLActivity.startNetgame = true; - startActivity(new Intent(this, SDLActivity.class)); - } + private final RoomStateManager.Listener roomStateChangeListener = new RoomStateManager.ListenerAdapter() { + @Override + public void onChiefStatusChanged(boolean isChief) { + startButton.setVisibility(isChief ? View.VISIBLE : View.GONE); + } + }; + + public void runGame(GameConfig config) { + SDLActivity.startConfig = config; + SDLActivity.startNetgame = true; + startActivity(new Intent(this, SDLActivity.class)); + } } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/NetplayStateFragment.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/NetplayStateFragment.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/NetplayStateFragment.java Tue Jan 21 22:43:06 2014 +0100 @@ -37,7 +37,7 @@ /** * Fragment for use by an activity that depends on the state of the network * connection. The activity must implement the NetplayStateListener interface. - * + * * This fragment manages reacting to changes in the networking state by calling * a callback method on the activity. */ @@ -47,91 +47,91 @@ private LocalBroadcastManager broadcastManager; private NetplayStateListener listener; private State knownState; - + interface NetplayStateListener { - /** - * This is called while the activity is running, and every time during resume, if - * a change in the networking state is detected. It is also called once - * with the initial state (which could be called a change from the "unknown" state). - */ - void onNetplayStateChanged(State newState); - } - + /** + * This is called while the activity is running, and every time during resume, if + * a change in the networking state is detected. It is also called once + * with the initial state (which could be called a change from the "unknown" state). + */ + void onNetplayStateChanged(State newState); + } + @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - try { - listener = (NetplayStateListener) activity; - } catch(ClassCastException e) { - throw new ClassCastException("Activity " + activity + " must implement NetplayStateListener to use NetplayStateFragment."); - } - } - - @Override - public void onDetach() { - super.onDetach(); - listener = null; - } - + public void onAttach(Activity activity) { + super.onAttach(activity); + try { + listener = (NetplayStateListener) activity; + } catch(ClassCastException e) { + throw new ClassCastException("Activity " + activity + " must implement NetplayStateListener to use NetplayStateFragment."); + } + } + + @Override + public void onDetach() { + super.onDetach(); + listener = null; + } + @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); appContext = getActivity().getApplicationContext(); broadcastManager = LocalBroadcastManager.getInstance(appContext); netplay = Netplay.getAppInstance(appContext); - } + } @Override public void onResume() { - super.onResume(); - broadcastManager.registerReceiver(disconnectReceiver, new IntentFilter(Netplay.ACTION_DISCONNECTED)); - broadcastManager.registerReceiver(leaveRoomReceiver, new IntentFilter(Netplay.ACTION_LEFT_ROOM)); - broadcastManager.registerReceiver(stateChangeReceiver, new IntentFilter(Netplay.ACTION_STATE_CHANGED)); - - State newState = netplay.getState(); - if(knownState != newState) { - listener.onNetplayStateChanged(newState); - knownState = newState; - } + super.onResume(); + broadcastManager.registerReceiver(disconnectReceiver, new IntentFilter(Netplay.ACTION_DISCONNECTED)); + broadcastManager.registerReceiver(leaveRoomReceiver, new IntentFilter(Netplay.ACTION_LEFT_ROOM)); + broadcastManager.registerReceiver(stateChangeReceiver, new IntentFilter(Netplay.ACTION_STATE_CHANGED)); + + State newState = netplay.getState(); + if(knownState != newState) { + listener.onNetplayStateChanged(newState); + knownState = newState; + } } - + @Override public void onPause() { - super.onPause(); - broadcastManager.unregisterReceiver(disconnectReceiver); - broadcastManager.unregisterReceiver(leaveRoomReceiver); - broadcastManager.unregisterReceiver(stateChangeReceiver); + super.onPause(); + broadcastManager.unregisterReceiver(disconnectReceiver); + broadcastManager.unregisterReceiver(leaveRoomReceiver); + broadcastManager.unregisterReceiver(stateChangeReceiver); } - private final BroadcastReceiver disconnectReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if(intent.getBooleanExtra(Netplay.EXTRA_HAS_ERROR, true)) { - String message = intent.getStringExtra(Netplay.EXTRA_MESSAGE); - String toastText = getString(R.string.toast_disconnected, message); - Toast.makeText(appContext, toastText, Toast.LENGTH_LONG).show(); - } - } - }; - - private final BroadcastReceiver leaveRoomReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - int reason = intent.getIntExtra(Netplay.EXTRA_REASON, -1); - if(reason == Frontlib.NETCONN_ROOMLEAVE_ABANDONED) { - Toast.makeText(appContext, R.string.toast_room_abandoned, Toast.LENGTH_LONG).show(); - } else if(reason == Frontlib.NETCONN_ROOMLEAVE_KICKED) { - Toast.makeText(appContext, R.string.toast_kicked, Toast.LENGTH_LONG).show(); - } - } - }; - - private final BroadcastReceiver stateChangeReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - State newState = netplay.getState(); - listener.onNetplayStateChanged(newState); - knownState = newState; - } - }; + private final BroadcastReceiver disconnectReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if(intent.getBooleanExtra(Netplay.EXTRA_HAS_ERROR, true)) { + String message = intent.getStringExtra(Netplay.EXTRA_MESSAGE); + String toastText = getString(R.string.toast_disconnected, message); + Toast.makeText(appContext, toastText, Toast.LENGTH_LONG).show(); + } + } + }; + + private final BroadcastReceiver leaveRoomReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + int reason = intent.getIntExtra(Netplay.EXTRA_REASON, -1); + if(reason == Frontlib.NETCONN_ROOMLEAVE_ABANDONED) { + Toast.makeText(appContext, R.string.toast_room_abandoned, Toast.LENGTH_LONG).show(); + } else if(reason == Frontlib.NETCONN_ROOMLEAVE_KICKED) { + Toast.makeText(appContext, R.string.toast_kicked, Toast.LENGTH_LONG).show(); + } + } + }; + + private final BroadcastReceiver stateChangeReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + State newState = netplay.getState(); + listener.onNetplayStateChanged(newState); + knownState = newState; + } + }; } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/PasswordDialog.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/PasswordDialog.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/PasswordDialog.java Tue Jan 21 22:43:06 2014 +0100 @@ -33,50 +33,50 @@ * Shown when connecting to the server, and the server requests a password. */ public class PasswordDialog extends ConnectionDependendDialogFragment { - String username; - - public PasswordDialog() { - } - - public PasswordDialog(String username) { - this.username = username; - } - - @Override - public void onSaveInstanceState(Bundle icicle) { - super.onSaveInstanceState(icicle); - icicle.putString("username", username); - } - - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - if(savedInstanceState != null) { - username = savedInstanceState.getString("username"); - } - final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - final EditText editText = new EditText(getActivity()); - final Netplay netplay = Netplay.getAppInstance(getActivity().getApplicationContext()); - - editText.setHint(R.string.dialog_password_hint); - editText.setId(android.R.id.text1); - editText.setInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD); - editText.setTransformationMethod(PasswordTransformationMethod.getInstance()); - builder.setView(editText); - builder.setTitle(R.string.dialog_password_title); - builder.setMessage(getString(R.string.dialog_password_message, username)); - builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - String password = editText.getText().toString(); - editText.setText(""); - netplay.sendPassword(password); - } - }); - return builder.create(); - } - - @Override - public void onCancel(DialogInterface dialog) { - super.onCancel(dialog); - Netplay.getAppInstance(getActivity().getApplicationContext()).disconnect(); - } + String username; + + public PasswordDialog() { + } + + public PasswordDialog(String username) { + this.username = username; + } + + @Override + public void onSaveInstanceState(Bundle icicle) { + super.onSaveInstanceState(icicle); + icicle.putString("username", username); + } + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + if(savedInstanceState != null) { + username = savedInstanceState.getString("username"); + } + final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + final EditText editText = new EditText(getActivity()); + final Netplay netplay = Netplay.getAppInstance(getActivity().getApplicationContext()); + + editText.setHint(R.string.dialog_password_hint); + editText.setId(android.R.id.text1); + editText.setInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD); + editText.setTransformationMethod(PasswordTransformationMethod.getInstance()); + builder.setView(editText); + builder.setTitle(R.string.dialog_password_title); + builder.setMessage(getString(R.string.dialog_password_message, username)); + builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + String password = editText.getText().toString(); + editText.setText(""); + netplay.sendPassword(password); + } + }); + return builder.create(); + } + + @Override + public void onCancel(DialogInterface dialog) { + super.onCancel(dialog); + Netplay.getAppInstance(getActivity().getApplicationContext()).disconnect(); + } } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/RoomPlayerlistAdapter.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/RoomPlayerlistAdapter.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/RoomPlayerlistAdapter.java Tue Jan 21 22:43:06 2014 +0100 @@ -31,30 +31,30 @@ import android.widget.TextView; public class RoomPlayerlistAdapter extends ObservableTreeMapAdapter { - @Override - protected Comparator getEntryOrder() { - return AlphabeticalOrderComparator.INSTANCE; - } + @Override + protected Comparator getEntryOrder() { + return AlphabeticalOrderComparator.INSTANCE; + } - public View getView(int position, View convertView, ViewGroup parent) { - View v = convertView; - if (v == null) { - LayoutInflater vi = LayoutInflater.from(parent.getContext()); - v = vi.inflate(R.layout.listview_player, null); - } + public View getView(int position, View convertView, ViewGroup parent) { + View v = convertView; + if (v == null) { + LayoutInflater vi = LayoutInflater.from(parent.getContext()); + v = vi.inflate(R.layout.listview_player, null); + } - PlayerInRoom player = getItem(position); - TextView username = (TextView) v.findViewById(android.R.id.text1); - username.setText(player.player.name); - int readyDrawable = player.ready ? R.drawable.lightbulb_on : R.drawable.lightbulb_off; - username.setCompoundDrawablesWithIntrinsicBounds(readyDrawable, 0, 0, 0); - return v; - } - - private static final class AlphabeticalOrderComparator implements Comparator { - public static final AlphabeticalOrderComparator INSTANCE = new AlphabeticalOrderComparator(); - public int compare(PlayerInRoom lhs, PlayerInRoom rhs) { - return lhs.player.name.compareToIgnoreCase(rhs.player.name); - }; - } + PlayerInRoom player = getItem(position); + TextView username = (TextView) v.findViewById(android.R.id.text1); + username.setText(player.player.name); + int readyDrawable = player.ready ? R.drawable.lightbulb_on : R.drawable.lightbulb_off; + username.setCompoundDrawablesWithIntrinsicBounds(readyDrawable, 0, 0, 0); + return v; + } + + private static final class AlphabeticalOrderComparator implements Comparator { + public static final AlphabeticalOrderComparator INSTANCE = new AlphabeticalOrderComparator(); + public int compare(PlayerInRoom lhs, PlayerInRoom rhs) { + return lhs.player.name.compareToIgnoreCase(rhs.player.name); + }; + } } \ No newline at end of file diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/RoomPlayerlistFragment.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/RoomPlayerlistFragment.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/RoomPlayerlistFragment.java Tue Jan 21 22:43:06 2014 +0100 @@ -38,73 +38,73 @@ import android.widget.AdapterView.OnItemClickListener; public class RoomPlayerlistFragment extends ListFragment implements OnItemClickListener { - private Netplay netplay; - private RoomPlayerlistAdapter adapter; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - netplay = Netplay.getAppInstance(getActivity().getApplicationContext()); - adapter = new RoomPlayerlistAdapter(); - adapter.setSource(netplay.roomPlayerlist); - setListAdapter(adapter); - } + private Netplay netplay; + private RoomPlayerlistAdapter adapter; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + netplay = Netplay.getAppInstance(getActivity().getApplicationContext()); + adapter = new RoomPlayerlistAdapter(); + adapter.setSource(netplay.roomPlayerlist); + setListAdapter(adapter); + } - @Override - public void onDestroy() { - super.onDestroy(); - adapter.invalidate(); - } - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - registerForContextMenu(getListView()); - getListView().setOnItemClickListener(this); - } + @Override + public void onDestroy() { + super.onDestroy(); + adapter.invalidate(); + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + registerForContextMenu(getListView()); + getListView().setOnItemClickListener(this); + } + + @Override + public void onCreateContextMenu(ContextMenu menu, View v, + ContextMenuInfo menuInfo) { + super.onCreateContextMenu(menu, v, menuInfo); + AdapterContextMenuInfo info = (AdapterContextMenuInfo)menuInfo; + String playerName = adapter.getItem(info.position).player.name; - @Override - public void onCreateContextMenu(ContextMenu menu, View v, - ContextMenuInfo menuInfo) { - super.onCreateContextMenu(menu, v, menuInfo); - AdapterContextMenuInfo info = (AdapterContextMenuInfo)menuInfo; - String playerName = adapter.getItem(info.position).player.name; - - MenuInflater inflater = getActivity().getMenuInflater(); - inflater.inflate(R.menu.room_playerlist_context, menu); - if(netplay.isChief() && !playerName.equals(netplay.getPlayerName())) { - inflater.inflate(R.menu.room_playerlist_chief_context, menu); - } - menu.setHeaderIcon(R.drawable.human); - menu.setHeaderTitle(playerName); - } - - @Override - public boolean onContextItemSelected(MenuItem item) { - AdapterContextMenuInfo info = (AdapterContextMenuInfo)item.getMenuInfo(); - PlayerInRoom player = adapter.getItem(info.position); - switch(item.getItemId()) { - case R.id.player_info: - netplay.sendPlayerInfoQuery(player.player.name); - return true; - case R.id.player_kick: - netplay.sendKick(player.player.name); - return true; - default: - return super.onContextItemSelected(item); - } - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - return inflater.inflate(R.layout.fragment_playerlist, container, false); - } - - public void onItemClick(AdapterView parent, View view, int position, long id) { - Player player = adapter.getItem(position).player; - if(player.name.equals(netplay.getPlayerName())) { - netplay.sendToggleReady(); - } - } + MenuInflater inflater = getActivity().getMenuInflater(); + inflater.inflate(R.menu.room_playerlist_context, menu); + if(netplay.isChief() && !playerName.equals(netplay.getPlayerName())) { + inflater.inflate(R.menu.room_playerlist_chief_context, menu); + } + menu.setHeaderIcon(R.drawable.human); + menu.setHeaderTitle(playerName); + } + + @Override + public boolean onContextItemSelected(MenuItem item) { + AdapterContextMenuInfo info = (AdapterContextMenuInfo)item.getMenuInfo(); + PlayerInRoom player = adapter.getItem(info.position); + switch(item.getItemId()) { + case R.id.player_info: + netplay.sendPlayerInfoQuery(player.player.name); + return true; + case R.id.player_kick: + netplay.sendKick(player.player.name); + return true; + default: + return super.onContextItemSelected(item); + } + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_playerlist, container, false); + } + + public void onItemClick(AdapterView parent, View view, int position, long id) { + Player player = adapter.getItem(position).player; + if(player.name.equals(netplay.getPlayerName())) { + netplay.sendToggleReady(); + } + } } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/RoomStateManager.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/RoomStateManager.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/RoomStateManager.java Tue Jan 21 22:43:06 2014 +0100 @@ -33,78 +33,78 @@ * using these fragments both for setting up networked and local games, despite * the fact that for local games the settings can be changed immediately in * memory, while they have to be sent out to the server for networked games. - * + * * If/when the state changes as result of calling one of the "changeX" or * "requestX" functions, that will also trigger the corresponding change * listener method. There is no guarantee that calling a changeX method will * actually change the setting (e.g. if you're not room chief). - * + * * For local games, getChiefStatus is always true. - * + * * Implementations of this interface are probably not thread safe and should * only be used on the UI thread. */ public interface RoomStateManager { - // Query current state - MapRecipe getMapRecipe(); - boolean getChiefStatus(); - Scheme getScheme(); - String getGameStyle(); - Weaponset getWeaponset(); - Map getTeams(); - - // Manipulate state - void changeMapRecipe(MapRecipe map); - void changeMapTheme(String theme); + // Query current state + MapRecipe getMapRecipe(); + boolean getChiefStatus(); + Scheme getScheme(); + String getGameStyle(); + Weaponset getWeaponset(); + Map getTeams(); + + // Manipulate state + void changeMapRecipe(MapRecipe map); + void changeMapTheme(String theme); + + /** + * This function sets both the map's name and generator. There is no function + * to change them independendly since e.g. the QtFrontend relies on them being + * consistent. + * + * If the name parameter is equal to one of the MapRecipe.MAPNAME_REGULAR, MAPNAME_MAZE + * or MAPNAME_DRAWN constants, the map generator is set accordingly. Otherwise, the + * map generator is set to represent a mapfile. The map's name is always set to + * the parameter. + */ + void changeMapNameAndGenerator(String mapName); + void changeMapTemplate(int template); + void changeMazeSize(int mazeSize); + void changeMapSeed(String seed); + void changeMapDrawdata(byte[] drawdata); + + void changeScheme(Scheme scheme); + void changeGameStyle(String style); + void changeWeaponset(Weaponset weaponset); - /** - * This function sets both the map's name and generator. There is no function - * to change them independendly since e.g. the QtFrontend relies on them being - * consistent. - * - * If the name parameter is equal to one of the MapRecipe.MAPNAME_REGULAR, MAPNAME_MAZE - * or MAPNAME_DRAWN constants, the map generator is set accordingly. Otherwise, the - * map generator is set to represent a mapfile. The map's name is always set to - * the parameter. - */ - void changeMapNameAndGenerator(String mapName); - void changeMapTemplate(int template); - void changeMazeSize(int mazeSize); - void changeMapSeed(String seed); - void changeMapDrawdata(byte[] drawdata); - - void changeScheme(Scheme scheme); - void changeGameStyle(String style); - void changeWeaponset(Weaponset weaponset); - - void requestAddTeam(Team team, int colorIndex); - void requestRemoveTeam(String teamname); - void changeTeamColorIndex(String teamname, int colorIndex); - void changeTeamHogCount(String teamname, int hogcount); - - // Observe changes - void addListener(Listener observer); - void removeListener(Listener observer); - - public interface Listener { - void onMapChanged(MapRecipe recipe); - void onChiefStatusChanged(boolean isChief); - void onSchemeChanged(Scheme scheme); - void onGameStyleChanged(String gameStyle); - void onWeaponsetChanged(Weaponset weaponset); - void onTeamsChanged(Map teams); - } - - public static class ListenerAdapter implements Listener { - public void onMapChanged(MapRecipe recipe) {} - public void onChiefStatusChanged(boolean isChief) {} - public void onSchemeChanged(Scheme scheme) {} - public void onGameStyleChanged(String gameStyle) {} - public void onWeaponsetChanged(Weaponset weaponset) {} - public void onTeamsChanged(Map teams) {} - } - - public interface Provider { - RoomStateManager getRoomStateManager(); - } + void requestAddTeam(Team team, int colorIndex); + void requestRemoveTeam(String teamname); + void changeTeamColorIndex(String teamname, int colorIndex); + void changeTeamHogCount(String teamname, int hogcount); + + // Observe changes + void addListener(Listener observer); + void removeListener(Listener observer); + + public interface Listener { + void onMapChanged(MapRecipe recipe); + void onChiefStatusChanged(boolean isChief); + void onSchemeChanged(Scheme scheme); + void onGameStyleChanged(String gameStyle); + void onWeaponsetChanged(Weaponset weaponset); + void onTeamsChanged(Map teams); + } + + public static class ListenerAdapter implements Listener { + public void onMapChanged(MapRecipe recipe) {} + public void onChiefStatusChanged(boolean isChief) {} + public void onSchemeChanged(Scheme scheme) {} + public void onGameStyleChanged(String gameStyle) {} + public void onWeaponsetChanged(Weaponset weaponset) {} + public void onTeamsChanged(Map teams) {} + } + + public interface Provider { + RoomStateManager getRoomStateManager(); + } } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/RoomlistAdapter.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/RoomlistAdapter.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/RoomlistAdapter.java Tue Jan 21 22:43:06 2014 +0100 @@ -37,77 +37,77 @@ * Displays the list of all rooms in the lobby */ public class RoomlistAdapter extends ObservableTreeMapAdapter { - private Context context; - - public RoomlistAdapter(Context context) { - this.context = context; - } - - @Override - protected Comparator getEntryOrder() { - return RoomWithId.NEWEST_FIRST_ORDER; - } - - @Override - public long getItemId(int position) { - return getItem(position).id; - } - - @Override - public boolean hasStableIds() { - return true; - } - - private static CharSequence formatExtra(Resources res, Room room) { - String ownermsg = res.getString(R.string.roomlist_owner, room.owner); - String mapmsg = res.getString(R.string.roomlist_map, room.formatMapName(res)); - String scheme = room.scheme.equals(room.weapons) ? room.scheme : room.scheme + " / " + room.weapons; - String schememsg = res.getString(R.string.roomlist_scheme, scheme); - return ownermsg + ". " + mapmsg + ", " + schememsg; - } - - public View getView(int position, View convertView, ViewGroup parent) { - View v = convertView; - if (v == null) { - LayoutInflater vi = LayoutInflater.from(context); - v = vi.inflate(R.layout.listview_room, null); - } - - Room room = getItem(position).room; - int iconRes = room.inProgress ? R.drawable.roomlist_ingame : R.drawable.roomlist_preparing; - - if(v.findViewById(android.R.id.text1) == null) { - // Tabular room list - TextView roomnameView = (TextView)v.findViewById(R.id.roomname); - TextView playerCountView = (TextView)v.findViewById(R.id.playercount); - TextView teamCountView = (TextView)v.findViewById(R.id.teamcount); - TextView ownerView = (TextView)v.findViewById(R.id.owner); - TextView mapView = (TextView)v.findViewById(R.id.map); - TextView schemeView = (TextView)v.findViewById(R.id.scheme); - TextView weaponView = (TextView)v.findViewById(R.id.weapons); - - roomnameView.setCompoundDrawablesWithIntrinsicBounds(iconRes, 0, 0, 0); - roomnameView.setText(room.name); - if(playerCountView != null) { - playerCountView.setText(String.valueOf(room.playerCount)); - } - if(teamCountView != null) { - teamCountView.setText(String.valueOf(room.teamCount)); - } - ownerView.setText(room.owner); - mapView.setText(room.formatMapName(context.getResources())); - schemeView.setText(room.scheme); - weaponView.setText(room.weapons); - } else { - // Small room list - TextView v1 = (TextView)v.findViewById(android.R.id.text1); - TextView v2 = (TextView)v.findViewById(android.R.id.text2); - - v1.setCompoundDrawablesWithIntrinsicBounds(iconRes, 0, 0, 0); - v1.setText(room.name); - v2.setText(formatExtra(context.getResources(), room)); - } - - return v; - } + private Context context; + + public RoomlistAdapter(Context context) { + this.context = context; + } + + @Override + protected Comparator getEntryOrder() { + return RoomWithId.NEWEST_FIRST_ORDER; + } + + @Override + public long getItemId(int position) { + return getItem(position).id; + } + + @Override + public boolean hasStableIds() { + return true; + } + + private static CharSequence formatExtra(Resources res, Room room) { + String ownermsg = res.getString(R.string.roomlist_owner, room.owner); + String mapmsg = res.getString(R.string.roomlist_map, room.formatMapName(res)); + String scheme = room.scheme.equals(room.weapons) ? room.scheme : room.scheme + " / " + room.weapons; + String schememsg = res.getString(R.string.roomlist_scheme, scheme); + return ownermsg + ". " + mapmsg + ", " + schememsg; + } + + public View getView(int position, View convertView, ViewGroup parent) { + View v = convertView; + if (v == null) { + LayoutInflater vi = LayoutInflater.from(context); + v = vi.inflate(R.layout.listview_room, null); + } + + Room room = getItem(position).room; + int iconRes = room.inProgress ? R.drawable.roomlist_ingame : R.drawable.roomlist_preparing; + + if(v.findViewById(android.R.id.text1) == null) { + // Tabular room list + TextView roomnameView = (TextView)v.findViewById(R.id.roomname); + TextView playerCountView = (TextView)v.findViewById(R.id.playercount); + TextView teamCountView = (TextView)v.findViewById(R.id.teamcount); + TextView ownerView = (TextView)v.findViewById(R.id.owner); + TextView mapView = (TextView)v.findViewById(R.id.map); + TextView schemeView = (TextView)v.findViewById(R.id.scheme); + TextView weaponView = (TextView)v.findViewById(R.id.weapons); + + roomnameView.setCompoundDrawablesWithIntrinsicBounds(iconRes, 0, 0, 0); + roomnameView.setText(room.name); + if(playerCountView != null) { + playerCountView.setText(String.valueOf(room.playerCount)); + } + if(teamCountView != null) { + teamCountView.setText(String.valueOf(room.teamCount)); + } + ownerView.setText(room.owner); + mapView.setText(room.formatMapName(context.getResources())); + schemeView.setText(room.scheme); + weaponView.setText(room.weapons); + } else { + // Small room list + TextView v1 = (TextView)v.findViewById(android.R.id.text1); + TextView v2 = (TextView)v.findViewById(android.R.id.text2); + + v1.setCompoundDrawablesWithIntrinsicBounds(iconRes, 0, 0, 0); + v1.setText(room.name); + v2.setText(formatExtra(context.getResources(), room)); + } + + return v; + } } \ No newline at end of file diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/RoomlistFragment.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/RoomlistFragment.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/RoomlistFragment.java Tue Jan 21 22:43:06 2014 +0100 @@ -35,60 +35,60 @@ * Displays the list of all rooms in the lobby */ public class RoomlistFragment extends ListFragment implements OnItemClickListener { - private static final int AUTO_REFRESH_INTERVAL_MS = 15000; - - private Netplay netplay; - private RoomlistAdapter adapter; - private CountDownTimer autoRefreshTimer = new CountDownTimer(Long.MAX_VALUE, AUTO_REFRESH_INTERVAL_MS) { - @Override - public void onTick(long millisUntilFinished) { - netplay.sendRoomlistRequest(); - } - - @Override - public void onFinish() { } - }; + private static final int AUTO_REFRESH_INTERVAL_MS = 15000; + + private Netplay netplay; + private RoomlistAdapter adapter; + private CountDownTimer autoRefreshTimer = new CountDownTimer(Long.MAX_VALUE, AUTO_REFRESH_INTERVAL_MS) { + @Override + public void onTick(long millisUntilFinished) { + netplay.sendRoomlistRequest(); + } + + @Override + public void onFinish() { } + }; - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - netplay = Netplay.getAppInstance(getActivity().getApplicationContext()); - adapter = new RoomlistAdapter(getActivity()); - adapter.setSource(netplay.roomList); - setListAdapter(adapter); - } + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + netplay = Netplay.getAppInstance(getActivity().getApplicationContext()); + adapter = new RoomlistAdapter(getActivity()); + adapter.setSource(netplay.roomList); + setListAdapter(adapter); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_roomlist, container, false); + } - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - return inflater.inflate(R.layout.fragment_roomlist, container, false); - } - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - getListView().setOnItemClickListener(this); - } - - @Override - public void onResume() { - super.onResume(); - autoRefreshTimer.start(); - } - - @Override - public void onPause() { - super.onPause(); - autoRefreshTimer.cancel(); - } - - @Override - public void onDestroy() { - super.onDestroy(); - adapter.invalidate(); - } - - public void onItemClick(AdapterView parent, View view, int position, long id) { - netplay.sendJoinRoom(adapter.getItem(position).room.name); - } + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + getListView().setOnItemClickListener(this); + } + + @Override + public void onResume() { + super.onResume(); + autoRefreshTimer.start(); + } + + @Override + public void onPause() { + super.onPause(); + autoRefreshTimer.cancel(); + } + + @Override + public void onDestroy() { + super.onDestroy(); + adapter.invalidate(); + } + + public void onItemClick(AdapterView parent, View view, int position, long id) { + netplay.sendJoinRoom(adapter.getItem(position).room.name); + } } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/SDLActivity.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/SDLActivity.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/SDLActivity.java Tue Jan 21 22:43:06 2014 +0100 @@ -62,358 +62,358 @@ SDL Activity */ public class SDLActivity extends Activity { - /** - * Set startConfig to the desired config when starting this activity. This avoids having to parcel all - * the config objects into the Intent. Not particularly elegant, but it's actually a recommended - * way to do this (http://developer.android.com/guide/faq/framework.html#3) - */ - public static volatile GameConfig startConfig; - public static volatile boolean startNetgame; - - // Main components - public static SDLActivity mSingleton; - private static SDLSurface mSurface; - private static Thread mSDLThread; + /** + * Set startConfig to the desired config when starting this activity. This avoids having to parcel all + * the config objects into the Intent. Not particularly elegant, but it's actually a recommended + * way to do this (http://developer.android.com/guide/faq/framework.html#3) + */ + public static volatile GameConfig startConfig; + public static volatile boolean startNetgame; - // Audio - private static Thread mAudioThread; - private static AudioTrack mAudioTrack; + // Main components + public static SDLActivity mSingleton; + private static SDLSurface mSurface; + private static Thread mSDLThread; - // EGL private objects - private static EGLContext mEGLContext; - private static EGLSurface mEGLSurface; - private static EGLDisplay mEGLDisplay; - private static EGLConfig mEGLConfig; - private static int mGLMajor, mGLMinor; + // Audio + private static Thread mAudioThread; + private static AudioTrack mAudioTrack; + + // EGL private objects + private static EGLContext mEGLContext; + private static EGLSurface mEGLSurface; + private static EGLDisplay mEGLDisplay; + private static EGLConfig mEGLConfig; + private static int mGLMajor, mGLMinor; - // Load the .so - static { - System.loadLibrary("SDL"); - System.loadLibrary("main"); - } + // Load the .so + static { + System.loadLibrary("SDL"); + System.loadLibrary("main"); + } - // Setup - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); + // Setup + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); - // So we can call stuff from static callbacks - mSingleton = this; + // So we can call stuff from static callbacks + mSingleton = this; - // Set up the surface - mSurface = new SDLSurface(getApplication(), startConfig, startNetgame); - startConfig = null; - setContentView(mSurface); - } + // Set up the surface + mSurface = new SDLSurface(getApplication(), startConfig, startNetgame); + startConfig = null; + setContentView(mSurface); + } - // Events - protected void onPause() { - Log.v("SDL", "onPause()"); - super.onPause(); + // Events + protected void onPause() { + Log.v("SDL", "onPause()"); + super.onPause(); - if(mEGLDisplay != null && mEGLContext != null){ - EGL10 egl = (EGL10)EGLContext.getEGL(); - egl.eglDestroyContext(mEGLDisplay, mEGLContext); - mEGLDisplay = null; - mEGLContext = null; - } + if(mEGLDisplay != null && mEGLContext != null){ + EGL10 egl = (EGL10)EGLContext.getEGL(); + egl.eglDestroyContext(mEGLDisplay, mEGLContext); + mEGLDisplay = null; + mEGLContext = null; + } - SDLActivity.nativePause(); - } + SDLActivity.nativePause(); + } - protected void onResume() { - Log.v("SDL", "onResume()"); - super.onResume(); - } + protected void onResume() { + Log.v("SDL", "onResume()"); + super.onResume(); + } - protected void onDestroy() { - super.onDestroy(); - Log.v("SDL", "onDestroy()"); - // Send a quit message to the application - SDLActivity.nativeQuit(); - // Now wait for the SDL thread to quit - if (mSDLThread != null) { - try { - mSDLThread.join(); - } catch(Exception e) { - Log.w("SDL", "Problem stopping thread: " + e); - } - mSDLThread = null; - } - mSingleton = null; - } - - public static void synchronizedNativeInit(String...args) { - synchronized(PascalExports.engineMutex) { - nativeInit(args); - } - } - - // C functions we call - private static native void nativeInit(String...args); - public static native void nativeQuit(); - public static native void nativePause(); - public static native void nativeResume(); - public static native void onNativeResize(int x, int y, int format); - public static native void onNativeKeyDown(int keycode); - public static native void onNativeKeyUp(int keycode); - public static native void onNativeTouch(int touchDevId, int pointerFingerId, - int action, float x, - float y, float p); - public static native void onNativeAccel(float x, float y, float z); - public static native void nativeRunAudioThread(); + protected void onDestroy() { + super.onDestroy(); + Log.v("SDL", "onDestroy()"); + // Send a quit message to the application + SDLActivity.nativeQuit(); + // Now wait for the SDL thread to quit + if (mSDLThread != null) { + try { + mSDLThread.join(); + } catch(Exception e) { + Log.w("SDL", "Problem stopping thread: " + e); + } + mSDLThread = null; + } + mSingleton = null; + } + + public static void synchronizedNativeInit(String...args) { + synchronized(PascalExports.engineMutex) { + nativeInit(args); + } + } + + // C functions we call + private static native void nativeInit(String...args); + public static native void nativeQuit(); + public static native void nativePause(); + public static native void nativeResume(); + public static native void onNativeResize(int x, int y, int format); + public static native void onNativeKeyDown(int keycode); + public static native void onNativeKeyUp(int keycode); + public static native void onNativeTouch(int touchDevId, int pointerFingerId, + int action, float x, + float y, float p); + public static native void onNativeAccel(float x, float y, float z); + public static native void nativeRunAudioThread(); - // Java functions called from C + // Java functions called from C - public static boolean createGLContext(int majorVersion, int minorVersion) { - return initEGL(majorVersion, minorVersion); - } + public static boolean createGLContext(int majorVersion, int minorVersion) { + return initEGL(majorVersion, minorVersion); + } - public static void flipBuffers() { - flipEGL(); - } + public static void flipBuffers() { + flipEGL(); + } - public static void setActivityTitle(final String title) { - // Called from SDLMain() thread and can't directly affect the view - mSingleton.runOnUiThread(new Runnable() { - public void run() { - mSingleton.setTitle(title); - } - }); - } + public static void setActivityTitle(final String title) { + // Called from SDLMain() thread and can't directly affect the view + mSingleton.runOnUiThread(new Runnable() { + public void run() { + mSingleton.setTitle(title); + } + }); + } - public static Context getContext() { - return mSingleton; - } + public static Context getContext() { + return mSingleton; + } - public static void startApp(final int width, final int height, GameConfig config, boolean netgame) { - // Start up the C app thread - if (mSDLThread == null) { - mSDLThread = new Thread(new SDLMain(width, height, config, netgame)); - mSDLThread.start(); - } else { - SDLActivity.nativeResume(); - } - } + public static void startApp(final int width, final int height, GameConfig config, boolean netgame) { + // Start up the C app thread + if (mSDLThread == null) { + mSDLThread = new Thread(new SDLMain(width, height, config, netgame)); + mSDLThread.start(); + } else { + SDLActivity.nativeResume(); + } + } - // EGL functions - public static boolean initEGL(int majorVersion, int minorVersion) { - if (SDLActivity.mEGLDisplay == null) { - try { - EGL10 egl = (EGL10)EGLContext.getEGL(); + // EGL functions + public static boolean initEGL(int majorVersion, int minorVersion) { + if (SDLActivity.mEGLDisplay == null) { + try { + EGL10 egl = (EGL10)EGLContext.getEGL(); - EGLDisplay dpy = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); + EGLDisplay dpy = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); - int[] version = new int[2]; - egl.eglInitialize(dpy, version); + int[] version = new int[2]; + egl.eglInitialize(dpy, version); - int EGL_OPENGL_ES_BIT = 1; - int EGL_OPENGL_ES2_BIT = 4; - int renderableType = 0; - if (majorVersion == 2) { - renderableType = EGL_OPENGL_ES2_BIT; - } else if (majorVersion == 1) { - renderableType = EGL_OPENGL_ES_BIT; - } - int[] configSpec = { - EGL10.EGL_RENDERABLE_TYPE, renderableType, - EGL10.EGL_NONE - }; - EGLConfig[] configs = new EGLConfig[1]; - int[] num_config = new int[1]; - if (!egl.eglChooseConfig(dpy, configSpec, configs, 1, num_config) || num_config[0] == 0) { - Log.e("SDL", "No EGL config available"); - return false; - } - EGLConfig config = configs[0]; + int EGL_OPENGL_ES_BIT = 1; + int EGL_OPENGL_ES2_BIT = 4; + int renderableType = 0; + if (majorVersion == 2) { + renderableType = EGL_OPENGL_ES2_BIT; + } else if (majorVersion == 1) { + renderableType = EGL_OPENGL_ES_BIT; + } + int[] configSpec = { + EGL10.EGL_RENDERABLE_TYPE, renderableType, + EGL10.EGL_NONE + }; + EGLConfig[] configs = new EGLConfig[1]; + int[] num_config = new int[1]; + if (!egl.eglChooseConfig(dpy, configSpec, configs, 1, num_config) || num_config[0] == 0) { + Log.e("SDL", "No EGL config available"); + return false; + } + EGLConfig config = configs[0]; - SDLActivity.mEGLDisplay = dpy; - SDLActivity.mEGLConfig = config; - SDLActivity.mGLMajor = majorVersion; - SDLActivity.mGLMinor = minorVersion; + SDLActivity.mEGLDisplay = dpy; + SDLActivity.mEGLConfig = config; + SDLActivity.mGLMajor = majorVersion; + SDLActivity.mGLMinor = minorVersion; - SDLActivity.createEGLSurface(); - } catch(Exception e) { - Log.v("SDL", e + ""); - for (StackTraceElement s : e.getStackTrace()) { - Log.v("SDL", s.toString()); - } - } - } - else SDLActivity.createEGLSurface(); + SDLActivity.createEGLSurface(); + } catch(Exception e) { + Log.v("SDL", e + ""); + for (StackTraceElement s : e.getStackTrace()) { + Log.v("SDL", s.toString()); + } + } + } + else SDLActivity.createEGLSurface(); - return true; - } + return true; + } - public static boolean createEGLContext() { - EGL10 egl = (EGL10)EGLContext.getEGL(); - int EGL_CONTEXT_CLIENT_VERSION=0x3098; - int contextAttrs[] = new int[] { EGL_CONTEXT_CLIENT_VERSION, SDLActivity.mGLMajor, EGL10.EGL_NONE }; - SDLActivity.mEGLContext = egl.eglCreateContext(SDLActivity.mEGLDisplay, SDLActivity.mEGLConfig, EGL10.EGL_NO_CONTEXT, contextAttrs); - if (SDLActivity.mEGLContext == EGL10.EGL_NO_CONTEXT) { - Log.e("SDL", "Couldn't create context"); - return false; - } - return true; - } + public static boolean createEGLContext() { + EGL10 egl = (EGL10)EGLContext.getEGL(); + int EGL_CONTEXT_CLIENT_VERSION=0x3098; + int contextAttrs[] = new int[] { EGL_CONTEXT_CLIENT_VERSION, SDLActivity.mGLMajor, EGL10.EGL_NONE }; + SDLActivity.mEGLContext = egl.eglCreateContext(SDLActivity.mEGLDisplay, SDLActivity.mEGLConfig, EGL10.EGL_NO_CONTEXT, contextAttrs); + if (SDLActivity.mEGLContext == EGL10.EGL_NO_CONTEXT) { + Log.e("SDL", "Couldn't create context"); + return false; + } + return true; + } - public static boolean createEGLSurface() { - if (SDLActivity.mEGLDisplay != null && SDLActivity.mEGLConfig != null) { - EGL10 egl = (EGL10)EGLContext.getEGL(); - if (SDLActivity.mEGLContext == null) createEGLContext(); + public static boolean createEGLSurface() { + if (SDLActivity.mEGLDisplay != null && SDLActivity.mEGLConfig != null) { + EGL10 egl = (EGL10)EGLContext.getEGL(); + if (SDLActivity.mEGLContext == null) createEGLContext(); - Log.v("SDL", "Creating new EGL Surface"); - EGLSurface surface = egl.eglCreateWindowSurface(SDLActivity.mEGLDisplay, SDLActivity.mEGLConfig, SDLActivity.mSurface, null); - if (surface == EGL10.EGL_NO_SURFACE) { - Log.e("SDL", "Couldn't create surface"); - return false; - } + Log.v("SDL", "Creating new EGL Surface"); + EGLSurface surface = egl.eglCreateWindowSurface(SDLActivity.mEGLDisplay, SDLActivity.mEGLConfig, SDLActivity.mSurface, null); + if (surface == EGL10.EGL_NO_SURFACE) { + Log.e("SDL", "Couldn't create surface"); + return false; + } - if (!egl.eglMakeCurrent(SDLActivity.mEGLDisplay, surface, surface, SDLActivity.mEGLContext)) { - Log.e("SDL", "Old EGL Context doesnt work, trying with a new one"); - createEGLContext(); - if (!egl.eglMakeCurrent(SDLActivity.mEGLDisplay, surface, surface, SDLActivity.mEGLContext)) { - Log.e("SDL", "Failed making EGL Context current"); - return false; - } - } - SDLActivity.mEGLSurface = surface; - return true; - } - return false; - } + if (!egl.eglMakeCurrent(SDLActivity.mEGLDisplay, surface, surface, SDLActivity.mEGLContext)) { + Log.e("SDL", "Old EGL Context doesnt work, trying with a new one"); + createEGLContext(); + if (!egl.eglMakeCurrent(SDLActivity.mEGLDisplay, surface, surface, SDLActivity.mEGLContext)) { + Log.e("SDL", "Failed making EGL Context current"); + return false; + } + } + SDLActivity.mEGLSurface = surface; + return true; + } + return false; + } - // EGL buffer flip - public static void flipEGL() { - try { - EGL10 egl = (EGL10)EGLContext.getEGL(); + // EGL buffer flip + public static void flipEGL() { + try { + EGL10 egl = (EGL10)EGLContext.getEGL(); - egl.eglWaitNative(EGL10.EGL_CORE_NATIVE_ENGINE, null); + egl.eglWaitNative(EGL10.EGL_CORE_NATIVE_ENGINE, null); - // drawing here + // drawing here - egl.eglWaitGL(); + egl.eglWaitGL(); - egl.eglSwapBuffers(SDLActivity.mEGLDisplay, SDLActivity.mEGLSurface); + egl.eglSwapBuffers(SDLActivity.mEGLDisplay, SDLActivity.mEGLSurface); - } catch(Exception e) { - Log.v("SDL", "flipEGL(): " + e); - for (StackTraceElement s : e.getStackTrace()) { - Log.v("SDL", s.toString()); - } - } - } + } catch(Exception e) { + Log.v("SDL", "flipEGL(): " + e); + for (StackTraceElement s : e.getStackTrace()) { + Log.v("SDL", s.toString()); + } + } + } - // Audio - private static Object buf; + // Audio + private static Object buf; - public static Object audioInit(int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames) { - int channelConfig = isStereo ? AudioFormat.CHANNEL_CONFIGURATION_STEREO : AudioFormat.CHANNEL_CONFIGURATION_MONO; - int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT : AudioFormat.ENCODING_PCM_8BIT; - int frameSize = (isStereo ? 2 : 1) * (is16Bit ? 2 : 1); + public static Object audioInit(int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames) { + int channelConfig = isStereo ? AudioFormat.CHANNEL_CONFIGURATION_STEREO : AudioFormat.CHANNEL_CONFIGURATION_MONO; + int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT : AudioFormat.ENCODING_PCM_8BIT; + int frameSize = (isStereo ? 2 : 1) * (is16Bit ? 2 : 1); - Log.v("SDL", "SDL audio: wanted " + (isStereo ? "stereo" : "mono") + " " + (is16Bit ? "16-bit" : "8-bit") + " " + ((float)sampleRate / 1000f) + "kHz, " + desiredFrames + " frames buffer"); + Log.v("SDL", "SDL audio: wanted " + (isStereo ? "stereo" : "mono") + " " + (is16Bit ? "16-bit" : "8-bit") + " " + ((float)sampleRate / 1000f) + "kHz, " + desiredFrames + " frames buffer"); - // Let the user pick a larger buffer if they really want -- but ye - // gods they probably shouldn't, the minimums are horrifyingly high - // latency already - desiredFrames = Math.max(desiredFrames, (AudioTrack.getMinBufferSize(sampleRate, channelConfig, audioFormat) + frameSize - 1) / frameSize); + // Let the user pick a larger buffer if they really want -- but ye + // gods they probably shouldn't, the minimums are horrifyingly high + // latency already + desiredFrames = Math.max(desiredFrames, (AudioTrack.getMinBufferSize(sampleRate, channelConfig, audioFormat) + frameSize - 1) / frameSize); - mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, - channelConfig, audioFormat, desiredFrames * frameSize, AudioTrack.MODE_STREAM); + mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, + channelConfig, audioFormat, desiredFrames * frameSize, AudioTrack.MODE_STREAM); - audioStartThread(); + audioStartThread(); - Log.v("SDL", "SDL audio: got " + ((mAudioTrack.getChannelCount() >= 2) ? "stereo" : "mono") + " " + ((mAudioTrack.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT) ? "16-bit" : "8-bit") + " " + ((float)mAudioTrack.getSampleRate() / 1000f) + "kHz, " + desiredFrames + " frames buffer"); + Log.v("SDL", "SDL audio: got " + ((mAudioTrack.getChannelCount() >= 2) ? "stereo" : "mono") + " " + ((mAudioTrack.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT) ? "16-bit" : "8-bit") + " " + ((float)mAudioTrack.getSampleRate() / 1000f) + "kHz, " + desiredFrames + " frames buffer"); - if (is16Bit) { - buf = new short[desiredFrames * (isStereo ? 2 : 1)]; - } else { - buf = new byte[desiredFrames * (isStereo ? 2 : 1)]; - } - return buf; - } + if (is16Bit) { + buf = new short[desiredFrames * (isStereo ? 2 : 1)]; + } else { + buf = new byte[desiredFrames * (isStereo ? 2 : 1)]; + } + return buf; + } - public static void audioStartThread() { - mAudioThread = new Thread(new Runnable() { - public void run() { - mAudioTrack.play(); - nativeRunAudioThread(); - } - }); + public static void audioStartThread() { + mAudioThread = new Thread(new Runnable() { + public void run() { + mAudioTrack.play(); + nativeRunAudioThread(); + } + }); - // I'd take REALTIME if I could get it! - mAudioThread.setPriority(Thread.MAX_PRIORITY); - mAudioThread.start(); - } + // I'd take REALTIME if I could get it! + mAudioThread.setPriority(Thread.MAX_PRIORITY); + mAudioThread.start(); + } - public static void audioWriteShortBuffer(short[] buffer) { - for (int i = 0; i < buffer.length; ) { - int result = mAudioTrack.write(buffer, i, buffer.length - i); - if (result > 0) { - i += result; - } else if (result == 0) { - try { - Thread.sleep(1); - } catch(InterruptedException e) { - // Nom nom - } - } else { - Log.w("SDL", "SDL audio: error return from write(short)"); - return; - } - } - } + public static void audioWriteShortBuffer(short[] buffer) { + for (int i = 0; i < buffer.length; ) { + int result = mAudioTrack.write(buffer, i, buffer.length - i); + if (result > 0) { + i += result; + } else if (result == 0) { + try { + Thread.sleep(1); + } catch(InterruptedException e) { + // Nom nom + } + } else { + Log.w("SDL", "SDL audio: error return from write(short)"); + return; + } + } + } - public static void audioWriteByteBuffer(byte[] buffer) { - for (int i = 0; i < buffer.length; ) { - int result = mAudioTrack.write(buffer, i, buffer.length - i); - if (result > 0) { - i += result; - } else if (result == 0) { - try { - Thread.sleep(1); - } catch(InterruptedException e) { - // Nom nom - } - } else { - Log.w("SDL", "SDL audio: error return from write(short)"); - return; - } - } - } + public static void audioWriteByteBuffer(byte[] buffer) { + for (int i = 0; i < buffer.length; ) { + int result = mAudioTrack.write(buffer, i, buffer.length - i); + if (result > 0) { + i += result; + } else if (result == 0) { + try { + Thread.sleep(1); + } catch(InterruptedException e) { + // Nom nom + } + } else { + Log.w("SDL", "SDL audio: error return from write(short)"); + return; + } + } + } - public static void audioQuit() { - if (mAudioThread != null) { - try { - mAudioThread.join(); - } catch(Exception e) { - Log.v("SDL", "Problem stopping audio thread: " + e); - } - mAudioThread = null; + public static void audioQuit() { + if (mAudioThread != null) { + try { + mAudioThread.join(); + } catch(Exception e) { + Log.v("SDL", "Problem stopping audio thread: " + e); + } + mAudioThread = null; - //Log.v("SDL", "Finished waiting for audio thread"); - } + //Log.v("SDL", "Finished waiting for audio thread"); + } - if (mAudioTrack != null) { - mAudioTrack.stop(); - mAudioTrack = null; - } - } - - public static int getDensity(){ - DisplayMetrics dm = SDLActivity.getContext().getResources().getDisplayMetrics(); - return dm.densityDpi; - } + if (mAudioTrack != null) { + mAudioTrack.stop(); + mAudioTrack = null; + } + } + + public static int getDensity(){ + DisplayMetrics dm = SDLActivity.getContext().getResources().getDisplayMetrics(); + return dm.densityDpi; + } } /** Simple nativeInit() runnable */ class SDLMain implements Runnable { - public static final String TAG = "SDLMain"; - + public static final String TAG = "SDLMain"; + public static final int RQ_LOWRES = 0x00000001; // use half land array public static final int RQ_BLURRY_LAND = 0x00000002; // downscaled terrain public static final int RQ_NO_BACKGROUND = 0x00000004; // don't draw background @@ -426,246 +426,246 @@ public static final int RQ_NO_CLAMPING = 0x00000200; // don't clamp textures public static final int RQ_NO_TOOLTIPS = 0x00000400; // tooltips are not drawn public static final int RQ_NO_VSYNC = 0x00000800; // don't sync on vblank - - private final int surfaceWidth, surfaceHeight; - private final String playerName; - private final GameConfig config; - private final boolean netgame; - - public SDLMain(int width, int height, GameConfig config, boolean netgame) { - surfaceWidth = width; - surfaceHeight = height; - if(netgame) { - playerName = Netplay.getAppInstance(SDLActivity.getContext().getApplicationContext()).getPlayerName(); - } else { - playerName = "Player"; - } - this.config = config; - this.netgame = netgame; - } + + private final int surfaceWidth, surfaceHeight; + private final String playerName; + private final GameConfig config; + private final boolean netgame; + + public SDLMain(int width, int height, GameConfig config, boolean netgame) { + surfaceWidth = width; + surfaceHeight = height; + if(netgame) { + playerName = Netplay.getAppInstance(SDLActivity.getContext().getApplicationContext()).getPlayerName(); + } else { + playerName = "Player"; + } + this.config = config; + this.netgame = netgame; + } - public void run() { - //Set up the IPC socket server to communicate with the engine - GameConnection gameConn; - String path; - try { - if(netgame) { - Netplay netplay = Netplay.getAppInstance(SDLActivity.mSingleton.getApplicationContext()); - gameConn = GameConnection.forNetgame(config, netplay); - } else { - gameConn = GameConnection.forLocalGame(config); - } - - path = FileUtils.getDataPathFile(SDLActivity.mSingleton).getAbsolutePath(); - Log.d(TAG, "Starting engine"); - // Runs SDL_main() with added parameters - try { - String pPort = String.valueOf(gameConn.port); - String pWidth = String.valueOf(surfaceWidth); - String pHeight = String.valueOf(surfaceHeight); - String pQuality = Integer.toString(RQ_NO_FLAKES|RQ_NO_DROPLETS|RQ_SIMPLE_EXPLOSIONS); - String pPlayerName = Base64.encodeToString(playerName.getBytes("UTF-8"), 0); - SDLActivity.synchronizedNativeInit(new String[] { pPort, pWidth, pHeight, pQuality, "en.txt", pPlayerName, "1", "1", "1", path, "" }); - } catch (UnsupportedEncodingException e) { - throw new AssertionError(e); // never happens - } - Log.d(TAG, "Engine stopped"); - } catch(ConnectException e) { - Log.e(TAG, "Error starting IPC connection"); - } catch (IOException e) { - Log.e(TAG, "Missing SDCard"); - } - SDLActivity.mSingleton.runOnUiThread(new Runnable() { public void run() { - if(SDLActivity.mSingleton != null) { - SDLActivity.mSingleton.finish(); - } - }}); - } + public void run() { + //Set up the IPC socket server to communicate with the engine + GameConnection gameConn; + String path; + try { + if(netgame) { + Netplay netplay = Netplay.getAppInstance(SDLActivity.mSingleton.getApplicationContext()); + gameConn = GameConnection.forNetgame(config, netplay); + } else { + gameConn = GameConnection.forLocalGame(config); + } + + path = FileUtils.getDataPathFile(SDLActivity.mSingleton).getAbsolutePath(); + Log.d(TAG, "Starting engine"); + // Runs SDL_main() with added parameters + try { + String pPort = String.valueOf(gameConn.port); + String pWidth = String.valueOf(surfaceWidth); + String pHeight = String.valueOf(surfaceHeight); + String pQuality = Integer.toString(RQ_NO_FLAKES|RQ_NO_DROPLETS|RQ_SIMPLE_EXPLOSIONS); + String pPlayerName = Base64.encodeToString(playerName.getBytes("UTF-8"), 0); + SDLActivity.synchronizedNativeInit(new String[] { pPort, pWidth, pHeight, pQuality, "en.txt", pPlayerName, "1", "1", "1", path, "" }); + } catch (UnsupportedEncodingException e) { + throw new AssertionError(e); // never happens + } + Log.d(TAG, "Engine stopped"); + } catch(ConnectException e) { + Log.e(TAG, "Error starting IPC connection"); + } catch (IOException e) { + Log.e(TAG, "Missing SDCard"); + } + SDLActivity.mSingleton.runOnUiThread(new Runnable() { public void run() { + if(SDLActivity.mSingleton != null) { + SDLActivity.mSingleton.finish(); + } + }}); + } } /** SDLSurface. This is what we draw on, so we need to know when it's created - in order to do anything useful. + in order to do anything useful. Because of this, that's where we set up the SDL thread */ -class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, +class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, View.OnKeyListener, View.OnTouchListener, SensorEventListener { - private GameConfig config; - private boolean netgame; - - // Sensors - private static SensorManager mSensorManager; + private GameConfig config; + private boolean netgame; + + // Sensors + private static SensorManager mSensorManager; - // Startup - public SDLSurface(Context context, GameConfig _config, boolean netgame) { - super(context); - getHolder().addCallback(this); + // Startup + public SDLSurface(Context context, GameConfig _config, boolean netgame) { + super(context); + getHolder().addCallback(this); - setFocusable(true); - setFocusableInTouchMode(true); - requestFocus(); - setOnKeyListener(this); - setOnTouchListener(this); + setFocusable(true); + setFocusableInTouchMode(true); + requestFocus(); + setOnKeyListener(this); + setOnTouchListener(this); - mSensorManager = (SensorManager)context.getSystemService("sensor"); - config = _config; - this.netgame = netgame; - } + mSensorManager = (SensorManager)context.getSystemService("sensor"); + config = _config; + this.netgame = netgame; + } - // Called when we have a valid drawing surface - public void surfaceCreated(SurfaceHolder holder) { - Log.v("SDL", "surfaceCreated()"); - holder.setType(SurfaceHolder.SURFACE_TYPE_GPU); - SDLActivity.createEGLSurface(); - // enableSensor(Sensor.TYPE_ACCELEROMETER, true); - } + // Called when we have a valid drawing surface + public void surfaceCreated(SurfaceHolder holder) { + Log.v("SDL", "surfaceCreated()"); + holder.setType(SurfaceHolder.SURFACE_TYPE_GPU); + SDLActivity.createEGLSurface(); + // enableSensor(Sensor.TYPE_ACCELEROMETER, true); + } - // Called when we lose the surface - public void surfaceDestroyed(SurfaceHolder holder) { - Log.v("SDL", "surfaceDestroyed()"); - SDLActivity.nativePause(); - // enableSensor(Sensor.TYPE_ACCELEROMETER, false); - } + // Called when we lose the surface + public void surfaceDestroyed(SurfaceHolder holder) { + Log.v("SDL", "surfaceDestroyed()"); + SDLActivity.nativePause(); + // enableSensor(Sensor.TYPE_ACCELEROMETER, false); + } - // Called when the surface is resized - public void surfaceChanged(SurfaceHolder holder, - int format, int width, int height) { - Log.v("SDL", "surfaceChanged()"); + // Called when the surface is resized + public void surfaceChanged(SurfaceHolder holder, + int format, int width, int height) { + Log.v("SDL", "surfaceChanged()"); - int sdlFormat = 0x85151002; // SDL_PIXELFORMAT_RGB565 by default - switch (format) { - case PixelFormat.A_8: - Log.v("SDL", "pixel format A_8"); - break; - case PixelFormat.LA_88: - Log.v("SDL", "pixel format LA_88"); - break; - case PixelFormat.L_8: - Log.v("SDL", "pixel format L_8"); - break; - case PixelFormat.RGBA_4444: - Log.v("SDL", "pixel format RGBA_4444"); - sdlFormat = 0x85421002; // SDL_PIXELFORMAT_RGBA4444 - break; - case PixelFormat.RGBA_5551: - Log.v("SDL", "pixel format RGBA_5551"); - sdlFormat = 0x85441002; // SDL_PIXELFORMAT_RGBA5551 - break; - case PixelFormat.RGBA_8888: - Log.v("SDL", "pixel format RGBA_8888"); - sdlFormat = 0x86462004; // SDL_PIXELFORMAT_RGBA8888 - break; - case PixelFormat.RGBX_8888: - Log.v("SDL", "pixel format RGBX_8888"); - sdlFormat = 0x86262004; // SDL_PIXELFORMAT_RGBX8888 - break; - case PixelFormat.RGB_332: - Log.v("SDL", "pixel format RGB_332"); - sdlFormat = 0x84110801; // SDL_PIXELFORMAT_RGB332 - break; - case PixelFormat.RGB_565: - Log.v("SDL", "pixel format RGB_565"); - sdlFormat = 0x85151002; // SDL_PIXELFORMAT_RGB565 - break; - case PixelFormat.RGB_888: - Log.v("SDL", "pixel format RGB_888"); - // Not sure this is right, maybe SDL_PIXELFORMAT_RGB24 instead? - sdlFormat = 0x86161804; // SDL_PIXELFORMAT_RGB888 - break; - default: - Log.v("SDL", "pixel format unknown " + format); - break; - } - SDLActivity.onNativeResize(width, height, sdlFormat); - Log.v("SDL", "Window size:" + width + "x"+height); + int sdlFormat = 0x85151002; // SDL_PIXELFORMAT_RGB565 by default + switch (format) { + case PixelFormat.A_8: + Log.v("SDL", "pixel format A_8"); + break; + case PixelFormat.LA_88: + Log.v("SDL", "pixel format LA_88"); + break; + case PixelFormat.L_8: + Log.v("SDL", "pixel format L_8"); + break; + case PixelFormat.RGBA_4444: + Log.v("SDL", "pixel format RGBA_4444"); + sdlFormat = 0x85421002; // SDL_PIXELFORMAT_RGBA4444 + break; + case PixelFormat.RGBA_5551: + Log.v("SDL", "pixel format RGBA_5551"); + sdlFormat = 0x85441002; // SDL_PIXELFORMAT_RGBA5551 + break; + case PixelFormat.RGBA_8888: + Log.v("SDL", "pixel format RGBA_8888"); + sdlFormat = 0x86462004; // SDL_PIXELFORMAT_RGBA8888 + break; + case PixelFormat.RGBX_8888: + Log.v("SDL", "pixel format RGBX_8888"); + sdlFormat = 0x86262004; // SDL_PIXELFORMAT_RGBX8888 + break; + case PixelFormat.RGB_332: + Log.v("SDL", "pixel format RGB_332"); + sdlFormat = 0x84110801; // SDL_PIXELFORMAT_RGB332 + break; + case PixelFormat.RGB_565: + Log.v("SDL", "pixel format RGB_565"); + sdlFormat = 0x85151002; // SDL_PIXELFORMAT_RGB565 + break; + case PixelFormat.RGB_888: + Log.v("SDL", "pixel format RGB_888"); + // Not sure this is right, maybe SDL_PIXELFORMAT_RGB24 instead? + sdlFormat = 0x86161804; // SDL_PIXELFORMAT_RGB888 + break; + default: + Log.v("SDL", "pixel format unknown " + format); + break; + } + SDLActivity.onNativeResize(width, height, sdlFormat); + Log.v("SDL", "Window size:" + width + "x"+height); - SDLActivity.startApp(width, height, config, netgame); - } + SDLActivity.startApp(width, height, config, netgame); + } - // unused - public void onDraw(Canvas canvas) {} + // unused + public void onDraw(Canvas canvas) {} - // Key events - public boolean onKey(View v, int keyCode, KeyEvent event) { - switch(keyCode){ - case KeyEvent.KEYCODE_BACK: - Log.d("SDL", "KEYCODE_BACK"); - SDLActivity.nativeQuit(); + // Key events + public boolean onKey(View v, int keyCode, KeyEvent event) { + switch(keyCode){ + case KeyEvent.KEYCODE_BACK: + Log.d("SDL", "KEYCODE_BACK"); + SDLActivity.nativeQuit(); return true; - case KeyEvent.KEYCODE_VOLUME_DOWN: - case KeyEvent.KEYCODE_VOLUME_UP: - case KeyEvent.KEYCODE_VOLUME_MUTE: - return false; - } - if (event.getAction() == KeyEvent.ACTION_DOWN) { - //Log.v("SDL", "key down: " + keyCode); - SDLActivity.onNativeKeyDown(keyCode); - return true; - } - else if (event.getAction() == KeyEvent.ACTION_UP) { - //Log.v("SDL", "key up: " + keyCode); - SDLActivity.onNativeKeyUp(keyCode); - return true; - } + case KeyEvent.KEYCODE_VOLUME_DOWN: + case KeyEvent.KEYCODE_VOLUME_UP: + case KeyEvent.KEYCODE_VOLUME_MUTE: + return false; + } + if (event.getAction() == KeyEvent.ACTION_DOWN) { + //Log.v("SDL", "key down: " + keyCode); + SDLActivity.onNativeKeyDown(keyCode); + return true; + } + else if (event.getAction() == KeyEvent.ACTION_UP) { + //Log.v("SDL", "key up: " + keyCode); + SDLActivity.onNativeKeyUp(keyCode); + return true; + } - return false; - } + return false; + } - // Touch events - public boolean onTouch(View v, MotionEvent event) { - final int action = event.getAction() & MotionEvent.ACTION_MASK; - final int actionPointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; + // Touch events + public boolean onTouch(View v, MotionEvent event) { + final int action = event.getAction() & MotionEvent.ACTION_MASK; + final int actionPointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; - if (action == MotionEvent.ACTION_MOVE) { - // TODO send motion to every pointer if its position has - // changed since prev event. - for (int i = 0; i < event.getPointerCount(); i++) { - sendNativeTouch(event, action, i); - } - } else { - sendNativeTouch(event, action, actionPointerIndex); - } - return true; - } - - private static void sendNativeTouch(MotionEvent event, int action, int pointerIndex) { - int touchDevId = event.getDeviceId(); - int pointerFingerId = event.getPointerId(pointerIndex); - float x = event.getX(pointerIndex); - float y = event.getY(pointerIndex); - float pressure = event.getPressure(pointerIndex); - SDLActivity.onNativeTouch(touchDevId, pointerFingerId, action, x, y, pressure); - } + if (action == MotionEvent.ACTION_MOVE) { + // TODO send motion to every pointer if its position has + // changed since prev event. + for (int i = 0; i < event.getPointerCount(); i++) { + sendNativeTouch(event, action, i); + } + } else { + sendNativeTouch(event, action, actionPointerIndex); + } + return true; + } + + private static void sendNativeTouch(MotionEvent event, int action, int pointerIndex) { + int touchDevId = event.getDeviceId(); + int pointerFingerId = event.getPointerId(pointerIndex); + float x = event.getX(pointerIndex); + float y = event.getY(pointerIndex); + float pressure = event.getPressure(pointerIndex); + SDLActivity.onNativeTouch(touchDevId, pointerFingerId, action, x, y, pressure); + } - // Sensor events - public void enableSensor(int sensortype, boolean enabled) { - // TODO: This uses getDefaultSensor - what if we have >1 accels? - if (enabled) { - mSensorManager.registerListener(this, - mSensorManager.getDefaultSensor(sensortype), - SensorManager.SENSOR_DELAY_GAME, null); - } else { - mSensorManager.unregisterListener(this, - mSensorManager.getDefaultSensor(sensortype)); - } - } + // Sensor events + public void enableSensor(int sensortype, boolean enabled) { + // TODO: This uses getDefaultSensor - what if we have >1 accels? + if (enabled) { + mSensorManager.registerListener(this, + mSensorManager.getDefaultSensor(sensortype), + SensorManager.SENSOR_DELAY_GAME, null); + } else { + mSensorManager.unregisterListener(this, + mSensorManager.getDefaultSensor(sensortype)); + } + } - public void onAccuracyChanged(Sensor sensor, int accuracy) { - // TODO - } + public void onAccuracyChanged(Sensor sensor, int accuracy) { + // TODO + } - public void onSensorChanged(SensorEvent event) { - if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { - SDLActivity.onNativeAccel(event.values[0] / SensorManager.GRAVITY_EARTH, - event.values[1] / SensorManager.GRAVITY_EARTH, - event.values[2] / SensorManager.GRAVITY_EARTH); - } - } + public void onSensorChanged(SensorEvent event) { + if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { + SDLActivity.onNativeAccel(event.values[0] / SensorManager.GRAVITY_EARTH, + event.values[1] / SensorManager.GRAVITY_EARTH, + event.values[2] / SensorManager.GRAVITY_EARTH); + } + } } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/SettingsFragment.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/SettingsFragment.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/SettingsFragment.java Tue Jan 21 22:43:06 2014 +0100 @@ -51,177 +51,177 @@ import android.widget.Toast; public class SettingsFragment extends Fragment { - private Spinner styleSpinner, schemeSpinner, weaponsetSpinner, themeSpinner; - private ImageView themeIcon; - - private List styles; - private List schemes; - private List weaponsets; - private List themes; - - private RoomStateManager stateManager; + private Spinner styleSpinner, schemeSpinner, weaponsetSpinner, themeSpinner; + private ImageView themeIcon; + + private List styles; + private List schemes; + private List weaponsets; + private List themes; + + private RoomStateManager stateManager; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View v = inflater.inflate(R.layout.fragment_settings, container, false); + themeIcon = (ImageView)v.findViewById(R.id.imgTheme); + + try { + styles = FrontendDataUtils.getGameStyles(getActivity()); + schemes = Schemes.loadAllSchemes(getActivity()); + weaponsets = Weaponsets.loadAllWeaponsets(getActivity()); + themes = FrontendDataUtils.getThemes(getActivity()); + } catch (IOException e) { + Toast.makeText(getActivity().getApplicationContext(), R.string.error_missing_sdcard_or_files, Toast.LENGTH_LONG).show(); + getActivity().finish(); + return null; + } + + Collections.sort(styles, String.CASE_INSENSITIVE_ORDER); + Collections.sort(schemes, Scheme.NAME_ORDER); + Collections.sort(weaponsets, Weaponset.NAME_ORDER); + Collections.sort(themes, String.CASE_INSENSITIVE_ORDER); + + styleSpinner = prepareSpinner(v, R.id.spinGameplay, styles, styleSelectedListener); + schemeSpinner = prepareSpinner(v, R.id.spinGamescheme, Schemes.toNameList(schemes), schemeSelectedListener); + weaponsetSpinner = prepareSpinner(v, R.id.spinweapons, Weaponsets.toNameList(weaponsets), weaponsetSelectedListener); + themeSpinner = prepareSpinner(v, R.id.spinTheme, themes, themeSelectedListener); + + stateManager.addListener(roomStateChangeListener); - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View v = inflater.inflate(R.layout.fragment_settings, container, false); - themeIcon = (ImageView)v.findViewById(R.id.imgTheme); - - try { - styles = FrontendDataUtils.getGameStyles(getActivity()); - schemes = Schemes.loadAllSchemes(getActivity()); - weaponsets = Weaponsets.loadAllWeaponsets(getActivity()); - themes = FrontendDataUtils.getThemes(getActivity()); - } catch (IOException e) { - Toast.makeText(getActivity().getApplicationContext(), R.string.error_missing_sdcard_or_files, Toast.LENGTH_LONG).show(); - getActivity().finish(); - return null; - } - - Collections.sort(styles, String.CASE_INSENSITIVE_ORDER); - Collections.sort(schemes, Scheme.NAME_ORDER); - Collections.sort(weaponsets, Weaponset.NAME_ORDER); - Collections.sort(themes, String.CASE_INSENSITIVE_ORDER); - - styleSpinner = prepareSpinner(v, R.id.spinGameplay, styles, styleSelectedListener); - schemeSpinner = prepareSpinner(v, R.id.spinGamescheme, Schemes.toNameList(schemes), schemeSelectedListener); - weaponsetSpinner = prepareSpinner(v, R.id.spinweapons, Weaponsets.toNameList(weaponsets), weaponsetSelectedListener); - themeSpinner = prepareSpinner(v, R.id.spinTheme, themes, themeSelectedListener); - - stateManager.addListener(roomStateChangeListener); + if(stateManager.getGameStyle() != null) { + styleSpinner.setSelection(styles.indexOf(stateManager.getGameStyle()), false); + } + if(stateManager.getScheme() != null) { + schemeSpinner.setSelection(getSchemePosition(schemes, stateManager.getScheme().name), false); + } + if(stateManager.getWeaponset() != null) { + weaponsetSpinner.setSelection(getWeaponsetPosition(weaponsets, stateManager.getWeaponset().name), false); + } + if(stateManager.getMapRecipe() != null) { + themeSpinner.setSelection(themes.indexOf(stateManager.getMapRecipe().theme), false); + } + + setChiefState(stateManager.getChiefStatus()); + + return v; + } + + private static Spinner prepareSpinner(View v, int id, List items, OnItemSelectedListener itemSelectedListener) { + Spinner spinner = (Spinner)v.findViewById(id); + ArrayAdapter adapter = new ArrayAdapter(v.getContext(), R.layout.listview_item, items); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + spinner.setAdapter(adapter); + spinner.setOnItemSelectedListener(itemSelectedListener); + return spinner; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + try { + stateManager = ((RoomStateManager.Provider)getActivity()).getRoomStateManager(); + } catch(ClassCastException e) { + throw new RuntimeException("Hosting activity must implement RoomStateManager.Provider.", e); + } + } + + @Override + public void onDestroy() { + super.onDestroy(); + stateManager.removeListener(roomStateChangeListener); + } - if(stateManager.getGameStyle() != null) { - styleSpinner.setSelection(styles.indexOf(stateManager.getGameStyle()), false); - } - if(stateManager.getScheme() != null) { - schemeSpinner.setSelection(getSchemePosition(schemes, stateManager.getScheme().name), false); - } - if(stateManager.getWeaponset() != null) { - weaponsetSpinner.setSelection(getWeaponsetPosition(weaponsets, stateManager.getWeaponset().name), false); - } - if(stateManager.getMapRecipe() != null) { - themeSpinner.setSelection(themes.indexOf(stateManager.getMapRecipe().theme), false); - } - - setChiefState(stateManager.getChiefStatus()); - - return v; - } - - private static Spinner prepareSpinner(View v, int id, List items, OnItemSelectedListener itemSelectedListener) { - Spinner spinner = (Spinner)v.findViewById(id); - ArrayAdapter adapter = new ArrayAdapter(v.getContext(), R.layout.listview_item, items); - adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - spinner.setAdapter(adapter); - spinner.setOnItemSelectedListener(itemSelectedListener); - return spinner; - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - try { - stateManager = ((RoomStateManager.Provider)getActivity()).getRoomStateManager(); - } catch(ClassCastException e) { - throw new RuntimeException("Hosting activity must implement RoomStateManager.Provider.", e); - } - } - - @Override - public void onDestroy() { - super.onDestroy(); - stateManager.removeListener(roomStateChangeListener); - } - - private static int getSchemePosition(List schemes, String scheme) { - for(int i=0; i weaponsets, String weaponset) { - for(int i=0; i adapter, View v, int position, long arg3) { - stateManager.changeGameStyle(styles.get(position)); - } - public void onNothingSelected(AdapterView arg0) {} - }; - - private final OnItemSelectedListener schemeSelectedListener = new OnItemSelectedListener() { - public void onItemSelected(AdapterView adapter, View v, int position, long arg3) { - stateManager.changeScheme(schemes.get(position)); - } - public void onNothingSelected(AdapterView arg0) {} - }; - - private final OnItemSelectedListener weaponsetSelectedListener = new OnItemSelectedListener() { - public void onItemSelected(AdapterView adapter, View v, int position, long arg3) { - stateManager.changeWeaponset(weaponsets.get(position)); - } - public void onNothingSelected(AdapterView arg0) {} - }; - - private final OnItemSelectedListener themeSelectedListener = new OnItemSelectedListener() { - public void onItemSelected(AdapterView adapter, View v, int position, long arg3) { - stateManager.changeMapTheme(themes.get(position)); - String theme = themes.get(position); - try { - File iconFile = FileUtils.getDataPathFile(getActivity(), "Themes", theme, "icon@2X.png"); - Drawable themeIconDrawable = Drawable.createFromPath(iconFile.getAbsolutePath()); - themeIcon.setImageDrawable(themeIconDrawable); - } catch (FileNotFoundException e) { - Log.e("SettingsFragment", "Unable to find preview for theme "+theme, e); - } - }; - public void onNothingSelected(AdapterView arg0) {}; - }; - - private final RoomStateManager.Listener roomStateChangeListener = new RoomStateManager.Listener() { - public void onWeaponsetChanged(Weaponset weaponset) { - weaponsetSpinner.setSelection(getWeaponsetPosition(weaponsets, weaponset.name)); - } - - public void onTeamsChanged(Map teams) {} - - public void onSchemeChanged(Scheme scheme) { - schemeSpinner.setSelection(getSchemePosition(schemes, scheme.name)); - } - - public void onMapChanged(MapRecipe recipe) { - themeSpinner.setSelection(themes.indexOf(recipe.theme)); - } - - public void onGameStyleChanged(String gameStyle) { - styleSpinner.setSelection(styles.indexOf(gameStyle)); - } - - public void onChiefStatusChanged(boolean isChief) { - setChiefState(isChief); - } - }; + private static int getSchemePosition(List schemes, String scheme) { + for(int i=0; i weaponsets, String weaponset) { + for(int i=0; i adapter, View v, int position, long arg3) { + stateManager.changeGameStyle(styles.get(position)); + } + public void onNothingSelected(AdapterView arg0) {} + }; + + private final OnItemSelectedListener schemeSelectedListener = new OnItemSelectedListener() { + public void onItemSelected(AdapterView adapter, View v, int position, long arg3) { + stateManager.changeScheme(schemes.get(position)); + } + public void onNothingSelected(AdapterView arg0) {} + }; + + private final OnItemSelectedListener weaponsetSelectedListener = new OnItemSelectedListener() { + public void onItemSelected(AdapterView adapter, View v, int position, long arg3) { + stateManager.changeWeaponset(weaponsets.get(position)); + } + public void onNothingSelected(AdapterView arg0) {} + }; + + private final OnItemSelectedListener themeSelectedListener = new OnItemSelectedListener() { + public void onItemSelected(AdapterView adapter, View v, int position, long arg3) { + stateManager.changeMapTheme(themes.get(position)); + String theme = themes.get(position); + try { + File iconFile = FileUtils.getDataPathFile(getActivity(), "Themes", theme, "icon@2X.png"); + Drawable themeIconDrawable = Drawable.createFromPath(iconFile.getAbsolutePath()); + themeIcon.setImageDrawable(themeIconDrawable); + } catch (FileNotFoundException e) { + Log.e("SettingsFragment", "Unable to find preview for theme "+theme, e); + } + }; + public void onNothingSelected(AdapterView arg0) {}; + }; + + private final RoomStateManager.Listener roomStateChangeListener = new RoomStateManager.Listener() { + public void onWeaponsetChanged(Weaponset weaponset) { + weaponsetSpinner.setSelection(getWeaponsetPosition(weaponsets, weaponset.name)); + } + + public void onTeamsChanged(Map teams) {} + + public void onSchemeChanged(Scheme scheme) { + schemeSpinner.setSelection(getSchemePosition(schemes, scheme.name)); + } + + public void onMapChanged(MapRecipe recipe) { + themeSpinner.setSelection(themes.indexOf(recipe.theme)); + } + + public void onGameStyleChanged(String gameStyle) { + styleSpinner.setSelection(styles.indexOf(gameStyle)); + } + + public void onChiefStatusChanged(boolean isChief) { + setChiefState(isChief); + } + }; } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/StartNetgameDialog.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/StartNetgameDialog.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/StartNetgameDialog.java Tue Jan 21 22:43:06 2014 +0100 @@ -36,60 +36,60 @@ import android.widget.TextView.OnEditorActionListener; public class StartNetgameDialog extends DialogFragment { - private static final String PREF_PLAYERNAME = "playerName"; - - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - SharedPreferences prefs = getActivity().getSharedPreferences("settings", Context.MODE_PRIVATE); - final String playerName = prefs.getString(PREF_PLAYERNAME, "Player"); - final EditText editText = new EditText(getActivity()); - final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - - editText.setText(playerName); - editText.setHint(R.string.start_netgame_dialog_playername_hint); - editText.setId(android.R.id.text1); - editText.setImeOptions(EditorInfo.IME_ACTION_DONE); - editText.setSingleLine(); + private static final String PREF_PLAYERNAME = "playerName"; + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + SharedPreferences prefs = getActivity().getSharedPreferences("settings", Context.MODE_PRIVATE); + final String playerName = prefs.getString(PREF_PLAYERNAME, "Player"); + final EditText editText = new EditText(getActivity()); + final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + + editText.setText(playerName); + editText.setHint(R.string.start_netgame_dialog_playername_hint); + editText.setId(android.R.id.text1); + editText.setImeOptions(EditorInfo.IME_ACTION_DONE); + editText.setSingleLine(); + + builder.setTitle(R.string.start_netgame_dialog_title); + builder.setMessage(R.string.start_netgame_dialog_message); + builder.setView(editText); + builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + editText.setText(playerName); + } + }); - builder.setTitle(R.string.start_netgame_dialog_title); - builder.setMessage(R.string.start_netgame_dialog_message); - builder.setView(editText); - builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - editText.setText(playerName); - } - }); - - editText.setOnEditorActionListener(new OnEditorActionListener() { - public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { - boolean handled = false; - if(actionId == EditorInfo.IME_ACTION_DONE) { - startConnection(v.getText().toString()); - handled = true; - } - return handled; - } - }); - - builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - startConnection(editText.getText().toString()); - } - }); + editText.setOnEditorActionListener(new OnEditorActionListener() { + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + boolean handled = false; + if(actionId == EditorInfo.IME_ACTION_DONE) { + startConnection(v.getText().toString()); + handled = true; + } + return handled; + } + }); + + builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + startConnection(editText.getText().toString()); + } + }); - return builder.create(); - } - - private void startConnection(String username) { - if(username.length() > 0) { - SharedPreferences prefs = getActivity().getSharedPreferences("settings", Context.MODE_PRIVATE); - Editor edit = prefs.edit(); - edit.putString(PREF_PLAYERNAME, username); - edit.commit(); - - Netplay.getAppInstance(getActivity().getApplicationContext()).connectToDefaultServer(username); - getDialog().dismiss(); - ((MainActivity)getActivity()).onNetConnectingStarted(); - } - } + return builder.create(); + } + + private void startConnection(String username) { + if(username.length() > 0) { + SharedPreferences prefs = getActivity().getSharedPreferences("settings", Context.MODE_PRIVATE); + Editor edit = prefs.edit(); + edit.putString(PREF_PLAYERNAME, username); + edit.commit(); + + Netplay.getAppInstance(getActivity().getApplicationContext()).connectToDefaultServer(username); + getDialog().dismiss(); + ((MainActivity)getActivity()).onNetConnectingStarted(); + } + } } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamAddDialog.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamAddDialog.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamAddDialog.java Tue Jan 21 22:43:06 2014 +0100 @@ -37,76 +37,76 @@ import android.support.v4.app.DialogFragment; public class TeamAddDialog extends DialogFragment { - private static final String STATE_TEAMS_ALREADY_IN_GAME = "teamAlreadyInGame"; - private ArrayList teamsAlreadyInGame; - private List availableTeams; - private Listener listener; - - public static interface Listener { - void onTeamAddDialogSubmitted(Team newTeam); - } - - public TeamAddDialog() { - // Only for reflection-based instantiation by the framework - } - - TeamAddDialog(Collection teamsAlreadyInGame) { - this.teamsAlreadyInGame = new ArrayList(teamsAlreadyInGame); - } - - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - try { - listener = (Listener) activity; - } catch(ClassCastException e) { - throw new ClassCastException("Activity " + activity + " must implement TeamAddDialog.Listener to use TeamAddDialog."); - } - } - - @Override - public void onDetach() { - super.onDetach(); - listener = null; - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - if(savedInstanceState != null) { - teamsAlreadyInGame = savedInstanceState.getStringArrayList(STATE_TEAMS_ALREADY_IN_GAME); - } - availableTeams = new ArrayList(); - List teams = FrontendDataUtils.getTeams(getActivity()); - for(Team team : teams) { - if(!teamsAlreadyInGame.contains(team.name)) { - availableTeams.add(team); - } - } - Collections.sort(availableTeams, Team.NAME_ORDER); - } - - // TODO use icons for the teams (corresponding to botlevel) - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - builder.setTitle(R.string.dialog_addteam_title); - builder.setIcon(R.drawable.human); - String[] teamNames = new String[availableTeams.size()]; - for(int i=0; i teamsAlreadyInGame; + private List availableTeams; + private Listener listener; + + public static interface Listener { + void onTeamAddDialogSubmitted(Team newTeam); + } + + public TeamAddDialog() { + // Only for reflection-based instantiation by the framework + } + + TeamAddDialog(Collection teamsAlreadyInGame) { + this.teamsAlreadyInGame = new ArrayList(teamsAlreadyInGame); + } + + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + try { + listener = (Listener) activity; + } catch(ClassCastException e) { + throw new ClassCastException("Activity " + activity + " must implement TeamAddDialog.Listener to use TeamAddDialog."); + } + } + + @Override + public void onDetach() { + super.onDetach(); + listener = null; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if(savedInstanceState != null) { + teamsAlreadyInGame = savedInstanceState.getStringArrayList(STATE_TEAMS_ALREADY_IN_GAME); + } + availableTeams = new ArrayList(); + List teams = FrontendDataUtils.getTeams(getActivity()); + for(Team team : teams) { + if(!teamsAlreadyInGame.contains(team.name)) { + availableTeams.add(team); + } + } + Collections.sort(availableTeams, Team.NAME_ORDER); + } + + // TODO use icons for the teams (corresponding to botlevel) + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + builder.setTitle(R.string.dialog_addteam_title); + builder.setIcon(R.drawable.human); + String[] teamNames = new String[availableTeams.size()]; + for(int i=0; i hogDice = new ArrayList(); - private ArrayList hogHat = new ArrayList(); - private ArrayList hogName = new ArrayList(); - private ImageButton voiceButton; - private ScrollView scroller; - private MediaPlayer mp = null; - private boolean initComplete = false; - - private String existingTeamName = null; + public static final String PARAMETER_EXISTING_TEAMNAME = "existingTeamName"; + private static final String TAG = TeamCreatorActivity.class.getSimpleName(); + + private TextView name; + private Spinner difficulty, grave, flag, voice, fort; + private ImageView imgFort; + private ArrayList hogDice = new ArrayList(); + private ArrayList hogHat = new ArrayList(); + private ArrayList hogName = new ArrayList(); + private ImageButton voiceButton; + private ScrollView scroller; + private MediaPlayer mp = null; + private boolean initComplete = false; + + private String existingTeamName = null; - private final List> flagsData = new ArrayList>(); - private final List> typesData = new ArrayList>(); - private final List> gravesData = new ArrayList>(); - private final List> hatsData = new ArrayList>(); - private final List voicesData = new ArrayList(); - private final List fortsData = new ArrayList(); + private final List> flagsData = new ArrayList>(); + private final List> typesData = new ArrayList>(); + private final List> gravesData = new ArrayList>(); + private final List> hatsData = new ArrayList>(); + private final List voicesData = new ArrayList(); + private final List fortsData = new ArrayList(); + + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + initComplete = false; + + // Restore state and read parameters + if(savedInstanceState != null) { + existingTeamName = savedInstanceState.getString(PARAMETER_EXISTING_TEAMNAME); + } else { + existingTeamName = getIntent().getStringExtra(PARAMETER_EXISTING_TEAMNAME); + } - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - initComplete = false; - - // Restore state and read parameters - if(savedInstanceState != null) { - existingTeamName = savedInstanceState.getString(PARAMETER_EXISTING_TEAMNAME); - } else { - existingTeamName = getIntent().getStringExtra(PARAMETER_EXISTING_TEAMNAME); - } - - // Set up view - setContentView(R.layout.team_creation); + // Set up view + setContentView(R.layout.team_creation); - name = (TextView) findViewById(R.id.txtName); - difficulty = (Spinner) findViewById(R.id.spinType); - grave = (Spinner) findViewById(R.id.spinGrave); - flag = (Spinner) findViewById(R.id.spinFlag); - voice = (Spinner) findViewById(R.id.spinVoice); - fort = (Spinner) findViewById(R.id.spinFort); + name = (TextView) findViewById(R.id.txtName); + difficulty = (Spinner) findViewById(R.id.spinType); + grave = (Spinner) findViewById(R.id.spinGrave); + flag = (Spinner) findViewById(R.id.spinFlag); + voice = (Spinner) findViewById(R.id.spinVoice); + fort = (Spinner) findViewById(R.id.spinFort); - imgFort = (ImageView) findViewById(R.id.imgFort); + imgFort = (ImageView) findViewById(R.id.imgFort); + + voiceButton = (ImageButton) findViewById(R.id.btnPlay); + + scroller = (ScrollView) findViewById(R.id.scroller); - voiceButton = (ImageButton) findViewById(R.id.btnPlay); - - scroller = (ScrollView) findViewById(R.id.scroller); - - // Wire view elements - LinearLayout ll = (LinearLayout) findViewById(R.id.HogsContainer); - for (int i = 0; i < ll.getChildCount(); i++) { - RelativeLayout team_creation_entry = (RelativeLayout) ll.getChildAt(i); + // Wire view elements + LinearLayout ll = (LinearLayout) findViewById(R.id.HogsContainer); + for (int i = 0; i < ll.getChildCount(); i++) { + RelativeLayout team_creation_entry = (RelativeLayout) ll.getChildAt(i); - hogHat.add((Spinner) team_creation_entry - .findViewById(R.id.spinTeam1)); - hogDice.add((ImageButton) team_creation_entry - .findViewById(R.id.btnTeam1)); - hogName.add((EditText) team_creation_entry - .findViewById(R.id.txtTeam1)); - } + hogHat.add((Spinner) team_creation_entry + .findViewById(R.id.spinTeam1)); + hogDice.add((ImageButton) team_creation_entry + .findViewById(R.id.btnTeam1)); + hogName.add((EditText) team_creation_entry + .findViewById(R.id.txtTeam1)); + } - grave.setAdapter(createMapSpinnerAdapter(gravesData)); - flag.setAdapter(createMapSpinnerAdapter(flagsData)); - difficulty.setAdapter(createMapSpinnerAdapter(typesData)); - SpinnerAdapter hatAdapter = createMapSpinnerAdapter(hatsData); - for (Spinner spin : hogHat) { - spin.setAdapter(hatAdapter); - } + grave.setAdapter(createMapSpinnerAdapter(gravesData)); + flag.setAdapter(createMapSpinnerAdapter(flagsData)); + difficulty.setAdapter(createMapSpinnerAdapter(typesData)); + SpinnerAdapter hatAdapter = createMapSpinnerAdapter(hatsData); + for (Spinner spin : hogHat) { + spin.setAdapter(hatAdapter); + } - voice.setAdapter(createListSpinnerAdapter(voicesData)); - voiceButton.setOnClickListener(voiceClicker); + voice.setAdapter(createListSpinnerAdapter(voicesData)); + voiceButton.setOnClickListener(voiceClicker); + + fort.setAdapter(createListSpinnerAdapter(fortsData)); + fort.setOnItemSelectedListener(fortSelector); + + new Thread(this).start(); + } + + private SpinnerAdapter createMapSpinnerAdapter(List> data) { + SimpleAdapter sa = new SimpleAdapter(this, data, + R.layout.spinner_textimg_entry, new String[] { "txt", "img" }, + new int[] { R.id.spinner_txt, R.id.spinner_img }); + sa.setDropDownViewResource(R.layout.spinner_textimg_dropdown_entry); + sa.setViewBinder(viewBinder); + return sa; + } + + private SpinnerAdapter createListSpinnerAdapter(List data) { + ArrayAdapter adapter = new ArrayAdapter(this, R.layout.listview_item, data); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + return adapter; + } - fort.setAdapter(createListSpinnerAdapter(fortsData)); - fort.setOnItemSelectedListener(fortSelector); + public void run(){ + try { + final List> gravesDataNew = FrontendDataUtils.getGraves(this); + runOnUiThread(new Runnable(){ + public void run() { + gravesData.addAll(gravesDataNew); + ((SimpleAdapter)grave.getAdapter()).notifyDataSetChanged(); + } + }); - new Thread(this).start(); - } + final List> flagsDataNew = FrontendDataUtils.getFlags(this); + runOnUiThread(new Runnable(){ + public void run() { + flagsData.addAll(flagsDataNew); + ((SimpleAdapter)flag.getAdapter()).notifyDataSetChanged(); + } + }); + + final List> typesDataNew = FrontendDataUtils.getTypes(this); + runOnUiThread(new Runnable(){ + public void run() { + typesData.addAll(typesDataNew); + ((SimpleAdapter)difficulty.getAdapter()).notifyDataSetChanged(); + } + }); + + final List> hatsDataNew = FrontendDataUtils.getHats(this); + runOnUiThread(new Runnable(){ + public void run() { + hatsData.addAll(hatsDataNew); + ((SimpleAdapter)hogHat.get(0).getAdapter()).notifyDataSetChanged(); + } + }); - private SpinnerAdapter createMapSpinnerAdapter(List> data) { - SimpleAdapter sa = new SimpleAdapter(this, data, - R.layout.spinner_textimg_entry, new String[] { "txt", "img" }, - new int[] { R.id.spinner_txt, R.id.spinner_img }); - sa.setDropDownViewResource(R.layout.spinner_textimg_dropdown_entry); - sa.setViewBinder(viewBinder); - return sa; - } - - private SpinnerAdapter createListSpinnerAdapter(List data) { - ArrayAdapter adapter = new ArrayAdapter(this, R.layout.listview_item, data); - adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - return adapter; - } - - public void run(){ - try { - final List> gravesDataNew = FrontendDataUtils.getGraves(this); - runOnUiThread(new Runnable(){ - public void run() { - gravesData.addAll(gravesDataNew); - ((SimpleAdapter)grave.getAdapter()).notifyDataSetChanged(); - } - }); - - final List> flagsDataNew = FrontendDataUtils.getFlags(this); - runOnUiThread(new Runnable(){ - public void run() { - flagsData.addAll(flagsDataNew); - ((SimpleAdapter)flag.getAdapter()).notifyDataSetChanged(); - } - }); - - final List> typesDataNew = FrontendDataUtils.getTypes(this); - runOnUiThread(new Runnable(){ - public void run() { - typesData.addAll(typesDataNew); - ((SimpleAdapter)difficulty.getAdapter()).notifyDataSetChanged(); - } - }); - - final List> hatsDataNew = FrontendDataUtils.getHats(this); - runOnUiThread(new Runnable(){ - public void run() { - hatsData.addAll(hatsDataNew); - ((SimpleAdapter)hogHat.get(0).getAdapter()).notifyDataSetChanged(); - } - }); - - final List voicesDataNew = FrontendDataUtils.getVoices(this); - runOnUiThread(new Runnable(){ - public void run() { - voicesData.addAll(voicesDataNew); - ((ArrayAdapter)voice.getAdapter()).notifyDataSetChanged(); - } - }); - - final List fortsDataNew = FrontendDataUtils.getForts(this); - runOnUiThread(new Runnable(){ - public void run() { - fortsData.addAll(fortsDataNew); - ((ArrayAdapter)fort.getAdapter()).notifyDataSetChanged(); - } - }); - - if(existingTeamName!=null) { - final Team loadedTeam = Team.load(Team.getTeamfileByName(getApplicationContext(), existingTeamName)); - if(loadedTeam==null) { - existingTeamName = null; - } else { - runOnUiThread(new Runnable(){ - public void run() { - setTeamValues(loadedTeam); - } - }); - } - } - runOnUiThread(new Runnable(){ - public void run() { - initComplete = true; - } - }); - } catch(FileNotFoundException e) { - this.runOnUiThread(new Runnable(){ - public void run() { - Toast.makeText(getApplicationContext(), R.string.error_missing_sdcard_or_files, Toast.LENGTH_LONG).show(); - finish(); - } - }); - } - } - - public void onDestroy() { - super.onDestroy(); - if (mp != null) { - mp.release(); - mp = null; - } - } + final List voicesDataNew = FrontendDataUtils.getVoices(this); + runOnUiThread(new Runnable(){ + public void run() { + voicesData.addAll(voicesDataNew); + ((ArrayAdapter)voice.getAdapter()).notifyDataSetChanged(); + } + }); + + final List fortsDataNew = FrontendDataUtils.getForts(this); + runOnUiThread(new Runnable(){ + public void run() { + fortsData.addAll(fortsDataNew); + ((ArrayAdapter)fort.getAdapter()).notifyDataSetChanged(); + } + }); - @Override - protected void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - outState.putString(PARAMETER_EXISTING_TEAMNAME, existingTeamName); - } + if(existingTeamName!=null) { + final Team loadedTeam = Team.load(Team.getTeamfileByName(getApplicationContext(), existingTeamName)); + if(loadedTeam==null) { + existingTeamName = null; + } else { + runOnUiThread(new Runnable(){ + public void run() { + setTeamValues(loadedTeam); + } + }); + } + } + runOnUiThread(new Runnable(){ + public void run() { + initComplete = true; + } + }); + } catch(FileNotFoundException e) { + this.runOnUiThread(new Runnable(){ + public void run() { + Toast.makeText(getApplicationContext(), R.string.error_missing_sdcard_or_files, Toast.LENGTH_LONG).show(); + finish(); + } + }); + } + } - public void onBackPressed() { - if(initComplete) { - saveTeam(); - } - setResult(RESULT_OK); - super.onBackPressed(); - } + public void onDestroy() { + super.onDestroy(); + if (mp != null) { + mp.release(); + mp = null; + } + } + + @Override + protected void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + outState.putString(PARAMETER_EXISTING_TEAMNAME, existingTeamName); + } + + public void onBackPressed() { + if(initComplete) { + saveTeam(); + } + setResult(RESULT_OK); + super.onBackPressed(); + } + + private void saveTeam() { + String teamName = name.getText().toString(); + String teamFlag = (String)((Map) flag.getSelectedItem()).get("txt"); + String teamFort = fort.getSelectedItem().toString(); + String teamGrave = (String)((Map) grave.getSelectedItem()).get("txt"); + String teamVoice = voice.getSelectedItem().toString(); + int levelInt = (Integer)((Map) difficulty.getSelectedItem()).get("level"); - private void saveTeam() { - String teamName = name.getText().toString(); - String teamFlag = (String)((Map) flag.getSelectedItem()).get("txt"); - String teamFort = fort.getSelectedItem().toString(); - String teamGrave = (String)((Map) grave.getSelectedItem()).get("txt"); - String teamVoice = voice.getSelectedItem().toString(); - int levelInt = (Integer)((Map) difficulty.getSelectedItem()).get("level"); - - List hogs = new ArrayList(); - for (int i = 0; i < hogName.size(); i++) { - String name = hogName.get(i).getText().toString(); - String hat = ((Map) hogHat.get(i).getSelectedItem()).get("txt").toString(); - hogs.add(new Hog(name, hat, levelInt)); - } - - Team team = new Team(teamName, teamGrave, teamFlag, teamVoice, teamFort, hogs); - File teamsDir = new File(getFilesDir(), Team.DIRECTORY_TEAMS); - if (!teamsDir.exists()) teamsDir.mkdir(); - - File newFile = Team.getTeamfileByName(this, teamName); - File oldFile = null; - if(existingTeamName != null) { - oldFile = Team.getTeamfileByName(this, existingTeamName); - } - try { - team.save(newFile); - // If the team was renamed, delete the old file. - if(oldFile != null && oldFile.isFile() && !oldFile.equals(newFile)) { - oldFile.delete(); - } - existingTeamName = teamName; - } catch(IOException e) { - Toast.makeText(getApplicationContext(), R.string.error_save_failed, Toast.LENGTH_SHORT).show(); - } - }; + List hogs = new ArrayList(); + for (int i = 0; i < hogName.size(); i++) { + String name = hogName.get(i).getText().toString(); + String hat = ((Map) hogHat.get(i).getSelectedItem()).get("txt").toString(); + hogs.add(new Hog(name, hat, levelInt)); + } + + Team team = new Team(teamName, teamGrave, teamFlag, teamVoice, teamFort, hogs); + File teamsDir = new File(getFilesDir(), Team.DIRECTORY_TEAMS); + if (!teamsDir.exists()) teamsDir.mkdir(); + + File newFile = Team.getTeamfileByName(this, teamName); + File oldFile = null; + if(existingTeamName != null) { + oldFile = Team.getTeamfileByName(this, existingTeamName); + } + try { + team.save(newFile); + // If the team was renamed, delete the old file. + if(oldFile != null && oldFile.isFile() && !oldFile.equals(newFile)) { + oldFile.delete(); + } + existingTeamName = teamName; + } catch(IOException e) { + Toast.makeText(getApplicationContext(), R.string.error_save_failed, Toast.LENGTH_SHORT).show(); + } + }; - private OnItemSelectedListener fortSelector = new OnItemSelectedListener() { - public void onItemSelected(AdapterView arg0, View arg1, - int position, long arg3) { - String fortName = (String) arg0.getAdapter().getItem(position); - try { - File fortImage = FileUtils.getDataPathFile(TeamCreatorActivity.this, "Forts", fortName, "L.png"); - Drawable fortIconDrawable = Drawable.createFromPath(fortImage.getAbsolutePath()); - imgFort.setImageDrawable(fortIconDrawable); - } catch(IOException e) { - Log.e(TAG, "Unable to show fort image", e); - } - scroller.fullScroll(ScrollView.FOCUS_DOWN);// Scroll the scrollview - // to the bottom, work - // around for scrollview - // invalidation (scrolls - // back to top) - } + private OnItemSelectedListener fortSelector = new OnItemSelectedListener() { + public void onItemSelected(AdapterView arg0, View arg1, + int position, long arg3) { + String fortName = (String) arg0.getAdapter().getItem(position); + try { + File fortImage = FileUtils.getDataPathFile(TeamCreatorActivity.this, "Forts", fortName, "L.png"); + Drawable fortIconDrawable = Drawable.createFromPath(fortImage.getAbsolutePath()); + imgFort.setImageDrawable(fortIconDrawable); + } catch(IOException e) { + Log.e(TAG, "Unable to show fort image", e); + } + scroller.fullScroll(ScrollView.FOCUS_DOWN);// Scroll the scrollview + // to the bottom, work + // around for scrollview + // invalidation (scrolls + // back to top) + } - public void onNothingSelected(AdapterView arg0) { - } + public void onNothingSelected(AdapterView arg0) { + } - }; + }; - private OnClickListener voiceClicker = new OnClickListener() { - public void onClick(View v) { - try { - File dir = FileUtils.getDataPathFile(TeamCreatorActivity.this, "Sounds", "voices", (String)voice.getSelectedItem()); - String file = ""; - File[] dirs = dir.listFiles(); - File f = dirs[(int) Math.round(Math.random() * dirs.length)]; - if (f.getName().endsWith(".ogg")) - file = f.getAbsolutePath(); + private OnClickListener voiceClicker = new OnClickListener() { + public void onClick(View v) { + try { + File dir = FileUtils.getDataPathFile(TeamCreatorActivity.this, "Sounds", "voices", (String)voice.getSelectedItem()); + String file = ""; + File[] dirs = dir.listFiles(); + File f = dirs[(int) Math.round(Math.random() * dirs.length)]; + if (f.getName().endsWith(".ogg")) + file = f.getAbsolutePath(); - if (mp == null) - mp = new MediaPlayer(); - else - mp.reset(); - mp.setDataSource(file); - mp.prepare(); - mp.start(); - } catch (IllegalArgumentException e) { - Log.e(TAG, "Unable to play voice sample", e); - } catch (IllegalStateException e) { - Log.e(TAG, "Unable to play voice sample", e); - } catch (IOException e) { - Log.e(TAG, "Unable to play voice sample", e); - } - } - }; + if (mp == null) + mp = new MediaPlayer(); + else + mp.reset(); + mp.setDataSource(file); + mp.prepare(); + mp.start(); + } catch (IllegalArgumentException e) { + Log.e(TAG, "Unable to play voice sample", e); + } catch (IllegalStateException e) { + Log.e(TAG, "Unable to play voice sample", e); + } catch (IOException e) { + Log.e(TAG, "Unable to play voice sample", e); + } + } + }; + + @SuppressWarnings("unchecked") + private void setTeamValues(Team t){ + if (t == null) { + return; + } + + try { + name.setText(t.name); + voice.setSelection(findPosition((ArrayAdapter) voice.getAdapter(), t.voice)); + fort.setSelection(findPosition((ArrayAdapter) fort.getAdapter(), t.fort)); + difficulty.setSelection(findPosition(typesData, "level", Integer.valueOf(t.hogs.get(0).level))); + grave.setSelection(findPosition(gravesData, "txt", t.grave)); + flag.setSelection(findPosition(flagsData, "txt", t.flag)); - @SuppressWarnings("unchecked") - private void setTeamValues(Team t){ - if (t == null) { - return; - } - - try { - name.setText(t.name); - voice.setSelection(findPosition((ArrayAdapter) voice.getAdapter(), t.voice)); - fort.setSelection(findPosition((ArrayAdapter) fort.getAdapter(), t.fort)); - difficulty.setSelection(findPosition(typesData, "level", Integer.valueOf(t.hogs.get(0).level))); - grave.setSelection(findPosition(gravesData, "txt", t.grave)); - flag.setSelection(findPosition(flagsData, "txt", t.flag)); - - for (int i = 0; i < Team.HEDGEHOGS_PER_TEAM; i++) { - hogHat.get(i).setSelection(findPosition(hatsData, "txt", t.hogs.get(i).hat)); - hogName.get(i).setText(t.hogs.get(i).name); - } - } catch(NoSuchElementException e) { - Toast.makeText(getApplicationContext(), R.string.error_team_attribute_not_found, Toast.LENGTH_LONG).show(); - finish(); - } - } + for (int i = 0; i < Team.HEDGEHOGS_PER_TEAM; i++) { + hogHat.get(i).setSelection(findPosition(hatsData, "txt", t.hogs.get(i).hat)); + hogName.get(i).setText(t.hogs.get(i).name); + } + } catch(NoSuchElementException e) { + Toast.makeText(getApplicationContext(), R.string.error_team_attribute_not_found, Toast.LENGTH_LONG).show(); + finish(); + } + } + + int findPosition(ArrayAdapter adapter, String value) throws NoSuchElementException { + int position = adapter.getPosition(value); + if(position<0) { + throw new NoSuchElementException(); + } + return position; + } - int findPosition(ArrayAdapter adapter, String value) throws NoSuchElementException { - int position = adapter.getPosition(value); - if(position<0) { - throw new NoSuchElementException(); - } - return position; - } - - int findPosition(List> data, String key, Object value) throws NoSuchElementException { - int position = 0; - for (Map map : data) { - if (map.get(key).equals(value)) { - return position; - } - position++; - } - throw new NoSuchElementException(); - } + int findPosition(List> data, String key, Object value) throws NoSuchElementException { + int position = 0; + for (Map map : data) { + if (map.get(key).equals(value)) { + return position; + } + position++; + } + throw new NoSuchElementException(); + } + + private SimpleAdapter.ViewBinder viewBinder = new SimpleAdapter.ViewBinder() { - private SimpleAdapter.ViewBinder viewBinder = new SimpleAdapter.ViewBinder() { - - public boolean setViewValue(View view, Object data, - String textRepresentation) { - if (view instanceof ImageView && data instanceof Bitmap) { - ImageView v = (ImageView) view; - v.setImageBitmap((Bitmap) data); - return true; - } else { - return false; - } - } - }; + public boolean setViewValue(View view, Object data, + String textRepresentation) { + if (view instanceof ImageView && data instanceof Bitmap) { + ImageView v = (ImageView) view; + v.setImageBitmap((Bitmap) data); + return true; + } else { + return false; + } + } + }; } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamListActivity.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamListActivity.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamListActivity.java Tue Jan 21 22:43:06 2014 +0100 @@ -43,87 +43,87 @@ import android.widget.SimpleAdapter; public class TeamListActivity extends ListActivity implements OnItemClickListener { - private List teams; - private ImageButton addButton; + private List teams; + private ImageButton addButton; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_teamlist); + addButton = (ImageButton)findViewById(R.id.btnAdd); + addButton.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + editTeam(null); + } + }); + } + + @Override + public void onResume() { + super.onResume(); + updateList(); + getListView().setOnItemClickListener(this); + registerForContextMenu(getListView()); + } + + public void onItemClick(AdapterView adapterView, View v, int position, long arg3) { + editTeam(teams.get(position).name); + } + + @Override + public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuinfo){ + menu.add(ContextMenu.NONE, 0, ContextMenu.NONE, R.string.edit); + menu.add(ContextMenu.NONE, 1, ContextMenu.NONE, R.string.delete); + } - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_teamlist); - addButton = (ImageButton)findViewById(R.id.btnAdd); - addButton.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - editTeam(null); - } - }); - } - - @Override - public void onResume() { - super.onResume(); - updateList(); - getListView().setOnItemClickListener(this); - registerForContextMenu(getListView()); - } - - public void onItemClick(AdapterView adapterView, View v, int position, long arg3) { - editTeam(teams.get(position).name); - } - - @Override - public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuinfo){ - menu.add(ContextMenu.NONE, 0, ContextMenu.NONE, R.string.edit); - menu.add(ContextMenu.NONE, 1, ContextMenu.NONE, R.string.delete); - } - - @Override - public boolean onContextItemSelected(MenuItem item){ - AdapterView.AdapterContextMenuInfo menuInfo = (AdapterContextMenuInfo) item.getMenuInfo(); - int position = menuInfo.position; - Team team = teams.get(position); - switch(item.getItemId()){ - case 0: - editTeam(team.name); - return true; - case 1: - Team.getTeamfileByName(getApplicationContext(), team.name).delete(); - updateList(); - return true; - } - return false; - } - - private void updateList() { - teams = FrontendDataUtils.getTeams(getApplicationContext()); - Collections.sort(teams, Team.NAME_ORDER); - SimpleAdapter adapter = new SimpleAdapter(this, teamsToMaps(teams), R.layout.team_selection_entry_simple, new String[]{"txt", "img"}, new int[]{R.id.txtName, R.id.imgDifficulty}); - setListAdapter(adapter); - } - - private void editTeam(String teamName) { - Intent i = new Intent(this, TeamCreatorActivity.class); - i.putExtra(TeamCreatorActivity.PARAMETER_EXISTING_TEAMNAME, teamName); - startActivity(i); - } + @Override + public boolean onContextItemSelected(MenuItem item){ + AdapterView.AdapterContextMenuInfo menuInfo = (AdapterContextMenuInfo) item.getMenuInfo(); + int position = menuInfo.position; + Team team = teams.get(position); + switch(item.getItemId()){ + case 0: + editTeam(team.name); + return true; + case 1: + Team.getTeamfileByName(getApplicationContext(), team.name).delete(); + updateList(); + return true; + } + return false; + } + + private void updateList() { + teams = FrontendDataUtils.getTeams(getApplicationContext()); + Collections.sort(teams, Team.NAME_ORDER); + SimpleAdapter adapter = new SimpleAdapter(this, teamsToMaps(teams), R.layout.team_selection_entry_simple, new String[]{"txt", "img"}, new int[]{R.id.txtName, R.id.imgDifficulty}); + setListAdapter(adapter); + } - private static final int[] botlevelDrawables = new int[] { - R.drawable.human, R.drawable.bot5, R.drawable.bot4, R.drawable.bot3, R.drawable.bot2, R.drawable.bot1 - }; - - private List> teamsToMaps(List teams) { - List> result = new ArrayList>(); - for(Team t : teams) { - HashMap map = new HashMap(); - map.put("team", t); - map.put("txt", t.name); - int botlevel = t.hogs.get(0).level; - if(botlevel<0 || botlevel>=botlevelDrawables.length) { - map.put("img", R.drawable.bot1); - } else { - map.put("img", botlevelDrawables[botlevel]); - } - result.add(map); - } - return result; - } + private void editTeam(String teamName) { + Intent i = new Intent(this, TeamCreatorActivity.class); + i.putExtra(TeamCreatorActivity.PARAMETER_EXISTING_TEAMNAME, teamName); + startActivity(i); + } + + private static final int[] botlevelDrawables = new int[] { + R.drawable.human, R.drawable.bot5, R.drawable.bot4, R.drawable.bot3, R.drawable.bot2, R.drawable.bot1 + }; + + private List> teamsToMaps(List teams) { + List> result = new ArrayList>(); + for(Team t : teams) { + HashMap map = new HashMap(); + map.put("team", t); + map.put("txt", t.name); + int botlevel = t.hogs.get(0).level; + if(botlevel<0 || botlevel>=botlevelDrawables.length) { + map.put("img", R.drawable.bot1); + } else { + map.put("img", botlevelDrawables[botlevel]); + } + result.add(map); + } + return result; + } } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamlistAdapter.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamlistAdapter.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamlistAdapter.java Tue Jan 21 22:43:06 2014 +0100 @@ -39,116 +39,116 @@ import android.widget.TextView; public class TeamlistAdapter extends BaseAdapter { - private boolean colorHogcountEnabled = false; - private Listener listener; - private List teams = new ArrayList(); - - public void setColorHogcountEnabled(boolean colorHogcountEnabled) { - this.colorHogcountEnabled = colorHogcountEnabled; - notifyDataSetChanged(); - } - - public void setListener(Listener listener) { - this.listener = listener; - } - - public int getCount() { - return teams.size(); - } - - public TeamInGame getItem(int position) { - return teams.get(position); - } - - public long getItemId(int position) { - return position; - } - - @Override - public boolean hasStableIds() { - return false; - } - - public void updateTeamlist(Collection newTeams) { - teams.clear(); - teams.addAll(newTeams); - Collections.sort(teams, TeamInGame.NAME_ORDER); - notifyDataSetChanged(); - } - - public View getView(int position, View convertView, ViewGroup parent) { - View v = convertView; - if (v == null) { - LayoutInflater vi = LayoutInflater.from(parent.getContext()); - v = vi.inflate(R.layout.listview_team, null); - } + private boolean colorHogcountEnabled = false; + private Listener listener; + private List teams = new ArrayList(); + + public void setColorHogcountEnabled(boolean colorHogcountEnabled) { + this.colorHogcountEnabled = colorHogcountEnabled; + notifyDataSetChanged(); + } + + public void setListener(Listener listener) { + this.listener = listener; + } + + public int getCount() { + return teams.size(); + } + + public TeamInGame getItem(int position) { + return teams.get(position); + } + + public long getItemId(int position) { + return position; + } + + @Override + public boolean hasStableIds() { + return false; + } + + public void updateTeamlist(Collection newTeams) { + teams.clear(); + teams.addAll(newTeams); + Collections.sort(teams, TeamInGame.NAME_ORDER); + notifyDataSetChanged(); + } + + public View getView(int position, View convertView, ViewGroup parent) { + View v = convertView; + if (v == null) { + LayoutInflater vi = LayoutInflater.from(parent.getContext()); + v = vi.inflate(R.layout.listview_team, null); + } + + TeamInGame team = getItem(position); + TextView teamNameView = (TextView) v.findViewById(android.R.id.text1); + ImageButton colorButton = (ImageButton) v.findViewById(R.id.colorButton); + ImageButton hogCountButton = (ImageButton) v.findViewById(R.id.hogCountButton); + + teamNameView.setText(team.team.name); + int teamImage; + if(team.ingameAttribs.remoteDriven) { + teamImage = R.drawable.team_net_by_level; + } else { + teamImage = R.drawable.team_local_by_level; + } - TeamInGame team = getItem(position); - TextView teamNameView = (TextView) v.findViewById(android.R.id.text1); - ImageButton colorButton = (ImageButton) v.findViewById(R.id.colorButton); - ImageButton hogCountButton = (ImageButton) v.findViewById(R.id.hogCountButton); - - teamNameView.setText(team.team.name); - int teamImage; - if(team.ingameAttribs.remoteDriven) { - teamImage = R.drawable.team_net_by_level; - } else { - teamImage = R.drawable.team_local_by_level; - } - - Drawable d = parent.getContext().getResources().getDrawable(teamImage).mutate(); - d.setLevel(team.team.hogs.get(0).level); - teamNameView.setCompoundDrawablesWithIntrinsicBounds(d, null, null, null); - hogCountButton.getDrawable().setLevel(team.ingameAttribs.hogCount); - colorButton.setImageDrawable(new ColorDrawable(TeamIngameAttributes.TEAM_COLORS[team.ingameAttribs.colorIndex])); - - colorButton.setEnabled(colorHogcountEnabled); - hogCountButton.setEnabled(colorHogcountEnabled); - - colorButton.setOnClickListener(new ButtonClickListener(team, Type.COLOR_BUTTON)); - hogCountButton.setOnClickListener(new ButtonClickListener(team, Type.HOGCOUNT_BUTTON)); - - if(team.ingameAttribs.remoteDriven) { - teamNameView.setClickable(false); - } else { - teamNameView.setOnClickListener(new ButtonClickListener(team, Type.TEAM_VIEW)); - } - - return v; - } - - private static enum Type {COLOR_BUTTON, HOGCOUNT_BUTTON, TEAM_VIEW} - private final class ButtonClickListener implements OnClickListener { - private final TeamInGame team; - private final Type type; - - public ButtonClickListener(TeamInGame team, Type type) { - this.team = team; - this.type = type; - } - - public void onClick(View v) { - if(listener != null) { - switch(type) { - case COLOR_BUTTON: - listener.onColorClicked(team); - break; - case HOGCOUNT_BUTTON: - listener.onHogcountClicked(team); - break; - case TEAM_VIEW: - listener.onTeamClicked(team); - break; - default: - throw new IllegalStateException(); - } - } - } - } - - public interface Listener { - void onTeamClicked(TeamInGame team); - void onColorClicked(TeamInGame team); - void onHogcountClicked(TeamInGame team); - } + Drawable d = parent.getContext().getResources().getDrawable(teamImage).mutate(); + d.setLevel(team.team.hogs.get(0).level); + teamNameView.setCompoundDrawablesWithIntrinsicBounds(d, null, null, null); + hogCountButton.getDrawable().setLevel(team.ingameAttribs.hogCount); + colorButton.setImageDrawable(new ColorDrawable(TeamIngameAttributes.TEAM_COLORS[team.ingameAttribs.colorIndex])); + + colorButton.setEnabled(colorHogcountEnabled); + hogCountButton.setEnabled(colorHogcountEnabled); + + colorButton.setOnClickListener(new ButtonClickListener(team, Type.COLOR_BUTTON)); + hogCountButton.setOnClickListener(new ButtonClickListener(team, Type.HOGCOUNT_BUTTON)); + + if(team.ingameAttribs.remoteDriven) { + teamNameView.setClickable(false); + } else { + teamNameView.setOnClickListener(new ButtonClickListener(team, Type.TEAM_VIEW)); + } + + return v; + } + + private static enum Type {COLOR_BUTTON, HOGCOUNT_BUTTON, TEAM_VIEW} + private final class ButtonClickListener implements OnClickListener { + private final TeamInGame team; + private final Type type; + + public ButtonClickListener(TeamInGame team, Type type) { + this.team = team; + this.type = type; + } + + public void onClick(View v) { + if(listener != null) { + switch(type) { + case COLOR_BUTTON: + listener.onColorClicked(team); + break; + case HOGCOUNT_BUTTON: + listener.onHogcountClicked(team); + break; + case TEAM_VIEW: + listener.onTeamClicked(team); + break; + default: + throw new IllegalStateException(); + } + } + } + } + + public interface Listener { + void onTeamClicked(TeamInGame team); + void onColorClicked(TeamInGame team); + void onHogcountClicked(TeamInGame team); + } } \ No newline at end of file diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamlistFragment.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamlistFragment.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamlistFragment.java Tue Jan 21 22:43:06 2014 +0100 @@ -37,83 +37,83 @@ import android.widget.Button; public class TeamlistFragment extends ListFragment implements TeamlistAdapter.Listener { - private TeamlistAdapter adapter; - private Button addTeamButton; - private RoomStateManager stateManager; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - try { - stateManager = ((RoomStateManager.Provider)getActivity()).getRoomStateManager(); - } catch(ClassCastException e) { - throw new RuntimeException("Hosting activity must implement RoomStateManager.Provider.", e); - } - adapter = new TeamlistAdapter(); - adapter.updateTeamlist(stateManager.getTeams().values()); - adapter.setColorHogcountEnabled(stateManager.getChiefStatus()); - adapter.setListener(this); - setListAdapter(adapter); - stateManager.addListener(roomStateChangeListener); - } + private TeamlistAdapter adapter; + private Button addTeamButton; + private RoomStateManager stateManager; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + try { + stateManager = ((RoomStateManager.Provider)getActivity()).getRoomStateManager(); + } catch(ClassCastException e) { + throw new RuntimeException("Hosting activity must implement RoomStateManager.Provider.", e); + } + adapter = new TeamlistAdapter(); + adapter.updateTeamlist(stateManager.getTeams().values()); + adapter.setColorHogcountEnabled(stateManager.getChiefStatus()); + adapter.setListener(this); + setListAdapter(adapter); + stateManager.addListener(roomStateChangeListener); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View v = inflater.inflate(R.layout.fragment_teamlist, container, false); + addTeamButton = (Button)v.findViewById(R.id.addTeamButton); + addTeamButton.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + new TeamAddDialog(getCurrentTeamNames()).show(getFragmentManager(), "team_add_dialog"); + } + }); + + addTeamButton.setEnabled(stateManager.getTeams().size() < Team.maxNumberOfTeams); + + return v; + } - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View v = inflater.inflate(R.layout.fragment_teamlist, container, false); - addTeamButton = (Button)v.findViewById(R.id.addTeamButton); - addTeamButton.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - new TeamAddDialog(getCurrentTeamNames()).show(getFragmentManager(), "team_add_dialog"); - } - }); - - addTeamButton.setEnabled(stateManager.getTeams().size() < Team.maxNumberOfTeams); - - return v; - } - - @Override - public void onDestroy() { - super.onDestroy(); - adapter.setListener(null); - stateManager.removeListener(roomStateChangeListener); - } + @Override + public void onDestroy() { + super.onDestroy(); + adapter.setListener(null); + stateManager.removeListener(roomStateChangeListener); + } + + private Collection getCurrentTeamNames() { + List names = new ArrayList(); + for(TeamInGame team : stateManager.getTeams().values()) { + names.add(team.team.name); + } + return names; + } + + public void onColorClicked(TeamInGame team) { + stateManager.changeTeamColorIndex(team.team.name, (team.ingameAttribs.colorIndex+1)%TeamIngameAttributes.TEAM_COLORS.length); + } - private Collection getCurrentTeamNames() { - List names = new ArrayList(); - for(TeamInGame team : stateManager.getTeams().values()) { - names.add(team.team.name); - } - return names; - } - - public void onColorClicked(TeamInGame team) { - stateManager.changeTeamColorIndex(team.team.name, (team.ingameAttribs.colorIndex+1)%TeamIngameAttributes.TEAM_COLORS.length); - } - - public void onHogcountClicked(TeamInGame team) { - int newHogCount = team.ingameAttribs.hogCount+1; - if(newHogCount>Team.HEDGEHOGS_PER_TEAM) { - newHogCount = 1; - } - stateManager.changeTeamHogCount(team.team.name, newHogCount); - } - - public void onTeamClicked(TeamInGame team) { - stateManager.requestRemoveTeam(team.team.name); - } - - private final RoomStateManager.Listener roomStateChangeListener = new RoomStateManager.ListenerAdapter() { - @Override - public void onChiefStatusChanged(boolean isChief) { - adapter.setColorHogcountEnabled(isChief); - }; - - @Override - public void onTeamsChanged(Map teams) { - adapter.updateTeamlist(teams.values()); - addTeamButton.setEnabled(teams.size() < Team.maxNumberOfTeams); - }; - }; + public void onHogcountClicked(TeamInGame team) { + int newHogCount = team.ingameAttribs.hogCount+1; + if(newHogCount>Team.HEDGEHOGS_PER_TEAM) { + newHogCount = 1; + } + stateManager.changeTeamHogCount(team.team.name, newHogCount); + } + + public void onTeamClicked(TeamInGame team) { + stateManager.requestRemoveTeam(team.team.name); + } + + private final RoomStateManager.Listener roomStateChangeListener = new RoomStateManager.ListenerAdapter() { + @Override + public void onChiefStatusChanged(boolean isChief) { + adapter.setColorHogcountEnabled(isChief); + }; + + @Override + public void onTeamsChanged(Map teams) { + adapter.updateTeamlist(teams.values()); + addTeamButton.setEnabled(teams.size() < Team.maxNumberOfTeams); + }; + }; } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TextImageAdapter.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TextImageAdapter.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TextImageAdapter.java Tue Jan 21 22:43:06 2014 +0100 @@ -35,40 +35,40 @@ public class TextImageAdapter extends SimpleAdapter { - private Context context; - private ArrayList> data; - - public TextImageAdapter(Context _context, ArrayList> _data, int resource, String[] from, int[] to) { - super(_context, _data, resource, from, to); - context = _context; - data = _data; - } - - public static TextImageAdapter createAdapter(Context c, String[] txt, String[] img, String[] from, int[] to){ - if(txt.length != img.length) throw new IllegalArgumentException("txt and img parameters not equal"); - - ArrayList> data = new ArrayList>(txt.length); - - for(int i = 0; i < txt.length; i++){ - HashMap map = new HashMap(); - map.put("txt", txt[i]); - map.put("img", BitmapFactory.decodeFile(img[i])); - data.add(map); - } - return new TextImageAdapter(c, data, R.layout.spinner_textimg_entry, from, to); - } + private Context context; + private ArrayList> data; + + public TextImageAdapter(Context _context, ArrayList> _data, int resource, String[] from, int[] to) { + super(_context, _data, resource, from, to); + context = _context; + data = _data; + } + + public static TextImageAdapter createAdapter(Context c, String[] txt, String[] img, String[] from, int[] to){ + if(txt.length != img.length) throw new IllegalArgumentException("txt and img parameters not equal"); + + ArrayList> data = new ArrayList>(txt.length); - public View getView(int position, View convertView, ViewGroup parent){ - if(convertView == null){ - LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - convertView = inflater.inflate(R.layout.spinner_textimg_entry, parent); - } - TextView tv = (TextView) convertView.findViewById(R.id.spinner_txt); - ImageView img = (ImageView) convertView.findViewById(R.id.spinner_img); - - tv.setText((String)data.get(position).get("txt")); - img.setImageBitmap((Bitmap)data.get(position).get("img")); - - return convertView; - } + for(int i = 0; i < txt.length; i++){ + HashMap map = new HashMap(); + map.put("txt", txt[i]); + map.put("img", BitmapFactory.decodeFile(img[i])); + data.add(map); + } + return new TextImageAdapter(c, data, R.layout.spinner_textimg_entry, from, to); + } + + public View getView(int position, View convertView, ViewGroup parent){ + if(convertView == null){ + LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + convertView = inflater.inflate(R.layout.spinner_textimg_entry, parent); + } + TextView tv = (TextView) convertView.findViewById(R.id.spinner_txt); + ImageView img = (ImageView) convertView.findViewById(R.id.spinner_img); + + tv.setText((String)data.get(position).get("txt")); + img.setImageBitmap((Bitmap)data.get(position).get("img")); + + return convertView; + } } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/UserInput/TouchInterface.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/UserInput/TouchInterface.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/UserInput/TouchInterface.java Tue Jan 21 22:43:06 2014 +0100 @@ -28,63 +28,63 @@ public class TouchInterface{ - public static OnTouchListener getTouchInterface(){ - OnTouchListener toucher; - if(Build.VERSION.SDK_INT < 5){//8 == Build.VERSION_CODES.FROYO - toucher = new TouchInterfaceST(); - }else{ - toucher = new TouchInterfaceMT(); - } + public static OnTouchListener getTouchInterface(){ + OnTouchListener toucher; + if(Build.VERSION.SDK_INT < 5){//8 == Build.VERSION_CODES.FROYO + toucher = new TouchInterfaceST(); + }else{ + toucher = new TouchInterfaceMT(); + } - return toucher; - } + return toucher; + } } /** * Touch interface with multitouch */ class TouchInterfaceMT implements OnTouchListener { - - private boolean firstEvent = true; - - public boolean onTouch(View v, MotionEvent event) { - //dumpEvent(event); - - int action = event.getAction(); - int actionCode = action & MotionEvent.ACTION_MASK; - - for (int i = 0; i < event.getPointerCount(); i++) { - SDLActivity.onNativeTouch(event.getDeviceId(), event.getPointerId(i), actionCode, (int)event.getX(i), (int)event.getY(i), event.getPressure(i)); -// Log.d("Android", String.format("x=%f, y=%f, pntr=%d", event.getX(i), event.getY(i), event.getPointerId(i))); - } - return true; - } + + private boolean firstEvent = true; + + public boolean onTouch(View v, MotionEvent event) { + //dumpEvent(event); + + int action = event.getAction(); + int actionCode = action & MotionEvent.ACTION_MASK; + + for (int i = 0; i < event.getPointerCount(); i++) { + SDLActivity.onNativeTouch(event.getDeviceId(), event.getPointerId(i), actionCode, (int)event.getX(i), (int)event.getY(i), event.getPressure(i)); +// Log.d("Android", String.format("x=%f, y=%f, pntr=%d", event.getX(i), event.getY(i), event.getPointerId(i))); + } + return true; + } - /** Show an event in the LogCat view, for debugging */ - private void dumpEvent(MotionEvent event) { - String names[] = { "DOWN" , "UP" , "MOVE" , "CANCEL" , "OUTSIDE" , - "POINTER_DOWN" , "POINTER_UP" , "7?" , "8?" , "9?" }; - StringBuilder sb = new StringBuilder(); - int action = event.getAction(); - int actionCode = action & MotionEvent.ACTION_MASK; - sb.append("event ACTION_" ).append(names[actionCode]); - if (actionCode == MotionEvent.ACTION_POINTER_DOWN - || actionCode == MotionEvent.ACTION_POINTER_UP) { - sb.append("(pid " ).append( - action >> MotionEvent.ACTION_POINTER_ID_SHIFT); - sb.append(")" ); - } - sb.append("[" ); - for (int i = 0; i < event.getPointerCount(); i++) { - sb.append("#" ).append(i); - sb.append("(pid " ).append(event.getPointerId(i)); - sb.append(")=" ).append((int) event.getX(i)); - sb.append("," ).append((int) event.getY(i)); - if (i + 1 < event.getPointerCount()) - sb.append(";" ); - } - sb.append("]" ); - Log.d("HW_APP_TOUCH", sb.toString()); - } + /** Show an event in the LogCat view, for debugging */ + private void dumpEvent(MotionEvent event) { + String names[] = { "DOWN" , "UP" , "MOVE" , "CANCEL" , "OUTSIDE" , + "POINTER_DOWN" , "POINTER_UP" , "7?" , "8?" , "9?" }; + StringBuilder sb = new StringBuilder(); + int action = event.getAction(); + int actionCode = action & MotionEvent.ACTION_MASK; + sb.append("event ACTION_" ).append(names[actionCode]); + if (actionCode == MotionEvent.ACTION_POINTER_DOWN + || actionCode == MotionEvent.ACTION_POINTER_UP) { + sb.append("(pid " ).append( + action >> MotionEvent.ACTION_POINTER_ID_SHIFT); + sb.append(")" ); + } + sb.append("[" ); + for (int i = 0; i < event.getPointerCount(); i++) { + sb.append("#" ).append(i); + sb.append("(pid " ).append(event.getPointerId(i)); + sb.append(")=" ).append((int) event.getX(i)); + sb.append("," ).append((int) event.getY(i)); + if (i + 1 < event.getPointerCount()) + sb.append(";" ); + } + sb.append("]" ); + Log.d("HW_APP_TOUCH", sb.toString()); + } } @@ -93,9 +93,9 @@ */ class TouchInterfaceST implements OnTouchListener { - public boolean onTouch(View v, MotionEvent event) { - return false; - } + public boolean onTouch(View v, MotionEvent event) { + return false; + } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/WeaponsetCreatorActivity.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/WeaponsetCreatorActivity.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/WeaponsetCreatorActivity.java Tue Jan 21 22:43:06 2014 +0100 @@ -4,5 +4,5 @@ // TODO public class WeaponsetCreatorActivity extends FragmentActivity { - public static final String PARAMETER_EXISTING_WEAPONSETNAME="existingWeaponsetName"; + public static final String PARAMETER_EXISTING_WEAPONSETNAME="existingWeaponsetName"; } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/WeaponsetListActivity.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/WeaponsetListActivity.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/WeaponsetListActivity.java Tue Jan 21 22:43:06 2014 +0100 @@ -44,83 +44,83 @@ import android.widget.Toast; public class WeaponsetListActivity extends ListActivity implements OnItemClickListener { - private List userWeaponsets; - private Button addButton; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_weaponsetlist); - addButton = (Button)findViewById(R.id.addButton); - addButton.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - editWeaponset(null); - } - }); - } - - @Override - public void onResume() { - super.onResume(); - updateList(); - getListView().setOnItemClickListener(this); - registerForContextMenu(getListView()); - } - - private List> weaponsetsToMap(List weaponsets) { - List> result = new ArrayList>(); - for(Weaponset weaponset : weaponsets) { - result.add(Collections.singletonMap("txt", weaponset.name)); - } - return result; - } - - public void onItemClick(AdapterView adapterView, View v, int position, long arg3) { - editWeaponset(userWeaponsets.get(position).name); - } - - @Override - public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuinfo){ - menu.add(ContextMenu.NONE, 0, ContextMenu.NONE, R.string.edit); - menu.add(ContextMenu.NONE, 1, ContextMenu.NONE, R.string.delete); - } - - @Override - public boolean onContextItemSelected(MenuItem item){ - AdapterView.AdapterContextMenuInfo menuInfo = (AdapterContextMenuInfo) item.getMenuInfo(); - int position = menuInfo.position; - Weaponset weaponset = userWeaponsets.get(position); - switch(item.getItemId()){ - case 0: - editWeaponset(weaponset.name); - return true; - case 1: - try { - Weaponsets.deleteUserWeaponset(this, weaponset.name); - } catch (IOException e) { - Toast.makeText(this.getApplicationContext(), R.string.error_missing_sdcard_or_files, Toast.LENGTH_SHORT).show(); - } - updateList(); - return true; - } - return false; - } - - private void updateList() { - try { - userWeaponsets = Weaponsets.loadUserWeaponsets(this); - } catch (IOException e) { - Toast.makeText(this, R.string.error_missing_sdcard_or_files, Toast.LENGTH_LONG).show(); - finish(); - } - Collections.sort(userWeaponsets, Weaponset.NAME_ORDER); - ListAdapter adapter = new SimpleAdapter(this, weaponsetsToMap(userWeaponsets), android.R.layout.simple_list_item_1, new String[]{"txt"}, new int[]{android.R.id.text1}); - setListAdapter(adapter); - } - - private void editWeaponset(String weaponsetName) { - Intent i = new Intent(this, WeaponsetCreatorActivity.class); - i.putExtra(WeaponsetCreatorActivity.PARAMETER_EXISTING_WEAPONSETNAME, weaponsetName); - startActivity(i); - } + private List userWeaponsets; + private Button addButton; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_weaponsetlist); + addButton = (Button)findViewById(R.id.addButton); + addButton.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + editWeaponset(null); + } + }); + } + + @Override + public void onResume() { + super.onResume(); + updateList(); + getListView().setOnItemClickListener(this); + registerForContextMenu(getListView()); + } + + private List> weaponsetsToMap(List weaponsets) { + List> result = new ArrayList>(); + for(Weaponset weaponset : weaponsets) { + result.add(Collections.singletonMap("txt", weaponset.name)); + } + return result; + } + + public void onItemClick(AdapterView adapterView, View v, int position, long arg3) { + editWeaponset(userWeaponsets.get(position).name); + } + + @Override + public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuinfo){ + menu.add(ContextMenu.NONE, 0, ContextMenu.NONE, R.string.edit); + menu.add(ContextMenu.NONE, 1, ContextMenu.NONE, R.string.delete); + } + + @Override + public boolean onContextItemSelected(MenuItem item){ + AdapterView.AdapterContextMenuInfo menuInfo = (AdapterContextMenuInfo) item.getMenuInfo(); + int position = menuInfo.position; + Weaponset weaponset = userWeaponsets.get(position); + switch(item.getItemId()){ + case 0: + editWeaponset(weaponset.name); + return true; + case 1: + try { + Weaponsets.deleteUserWeaponset(this, weaponset.name); + } catch (IOException e) { + Toast.makeText(this.getApplicationContext(), R.string.error_missing_sdcard_or_files, Toast.LENGTH_SHORT).show(); + } + updateList(); + return true; + } + return false; + } + + private void updateList() { + try { + userWeaponsets = Weaponsets.loadUserWeaponsets(this); + } catch (IOException e) { + Toast.makeText(this, R.string.error_missing_sdcard_or_files, Toast.LENGTH_LONG).show(); + finish(); + } + Collections.sort(userWeaponsets, Weaponset.NAME_ORDER); + ListAdapter adapter = new SimpleAdapter(this, weaponsetsToMap(userWeaponsets), android.R.layout.simple_list_item_1, new String[]{"txt"}, new int[]{android.R.id.text1}); + setListAdapter(adapter); + } + + private void editWeaponset(String weaponsetName) { + Intent i = new Intent(this, WeaponsetCreatorActivity.class); + i.putExtra(WeaponsetCreatorActivity.PARAMETER_EXISTING_WEAPONSETNAME, weaponsetName); + startActivity(i); + } } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/frontlib/AndroidTypeMapper.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/frontlib/AndroidTypeMapper.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/frontlib/AndroidTypeMapper.java Tue Jan 21 22:43:06 2014 +0100 @@ -1,63 +1,63 @@ -/* - * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -package org.hedgewars.hedgeroid.frontlib; - -import com.sun.jna.DefaultTypeMapper; -import com.sun.jna.FromNativeContext; -import com.sun.jna.ToNativeContext; -import com.sun.jna.TypeConverter; -import com.sun.jna.TypeMapper; - -class AndroidTypeMapper extends DefaultTypeMapper { - static final int NATIVE_INT_SIZE = 4; - static final int NATIVE_SIZE_T_SIZE = 4; - static final int NATIVE_BOOL_SIZE = 1; - public static final TypeMapper INSTANCE = new AndroidTypeMapper(); - - protected AndroidTypeMapper() { - addTypeConverter(Boolean.class, new BooleanConverter()); - addTypeConverter(NativeSizeT.class, new SizeTConverter()); - } - - private static final class BooleanConverter implements TypeConverter { - public Class nativeType() { - return Byte.class; - } - public Object fromNative(Object value, FromNativeContext context) { - return ((Byte)value).intValue() != 0 ? Boolean.TRUE : Boolean.FALSE; - } - public Object toNative(Object value, ToNativeContext context) { - return Byte.valueOf((byte)(Boolean.TRUE.equals(value) ? 1 : 0)); - } - } - - private static final class SizeTConverter implements TypeConverter { - public Class nativeType() { - return Integer.class; - } - public Object fromNative(Object value, FromNativeContext context) { - return NativeSizeT.valueOf((Integer)value); - } - public Object toNative(Object value, ToNativeContext context) { - return Integer.valueOf(value==null ? 0 : ((NativeSizeT)value).intValue()); - } - } -} - +/* + * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package org.hedgewars.hedgeroid.frontlib; + +import com.sun.jna.DefaultTypeMapper; +import com.sun.jna.FromNativeContext; +import com.sun.jna.ToNativeContext; +import com.sun.jna.TypeConverter; +import com.sun.jna.TypeMapper; + +class AndroidTypeMapper extends DefaultTypeMapper { + static final int NATIVE_INT_SIZE = 4; + static final int NATIVE_SIZE_T_SIZE = 4; + static final int NATIVE_BOOL_SIZE = 1; + public static final TypeMapper INSTANCE = new AndroidTypeMapper(); + + protected AndroidTypeMapper() { + addTypeConverter(Boolean.class, new BooleanConverter()); + addTypeConverter(NativeSizeT.class, new SizeTConverter()); + } + + private static final class BooleanConverter implements TypeConverter { + public Class nativeType() { + return Byte.class; + } + public Object fromNative(Object value, FromNativeContext context) { + return ((Byte)value).intValue() != 0 ? Boolean.TRUE : Boolean.FALSE; + } + public Object toNative(Object value, ToNativeContext context) { + return Byte.valueOf((byte)(Boolean.TRUE.equals(value) ? 1 : 0)); + } + } + + private static final class SizeTConverter implements TypeConverter { + public Class nativeType() { + return Integer.class; + } + public Object fromNative(Object value, FromNativeContext context) { + return NativeSizeT.valueOf((Integer)value); + } + public Object toNative(Object value, ToNativeContext context) { + return Integer.valueOf(value==null ? 0 : ((NativeSizeT)value).intValue()); + } + } +} + diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/frontlib/Flib.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/frontlib/Flib.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/frontlib/Flib.java Tue Jan 21 22:43:06 2014 +0100 @@ -27,36 +27,36 @@ import com.sun.jna.Native; public class Flib { - static { - System.loadLibrary("SDL"); - System.loadLibrary("SDL_net"); - System.setProperty("jna.encoding", "UTF8"); // Ugly global setting, but it seems JNA doesn't allow setting this per-library... - } - public static final Frontlib INSTANCE = (Frontlib)Native.loadLibrary("frontlib", Frontlib.class, Collections.singletonMap(Library.OPTION_TYPE_MAPPER, AndroidTypeMapper.INSTANCE)); - - static { - // We'll just do it here and never quit it again... - if(Flib.INSTANCE.flib_init() != 0) { - throw new RuntimeException("Unable to initialize frontlib"); - } - } - - // Hook frontlib logging into Android logging - private static final Frontlib.LogCallback logCb = new Frontlib.LogCallback() { - public void callback(int level, String message) { - if(level >= Frontlib.FLIB_LOGLEVEL_ERROR) { - Log.e("Frontlib", message); - } else if(level == Frontlib.FLIB_LOGLEVEL_WARNING){ - Log.w("Frontlib", message); - } else if(level == Frontlib.FLIB_LOGLEVEL_INFO){ - Log.i("Frontlib", message); - } else if(level <= Frontlib.FLIB_LOGLEVEL_DEBUG){ - Log.d("Frontlib", message); - } - } - }; - static { - INSTANCE.flib_log_setLevel(Frontlib.FLIB_LOGLEVEL_INFO); - INSTANCE.flib_log_setCallback(logCb); - } + static { + System.loadLibrary("SDL"); + System.loadLibrary("SDL_net"); + System.setProperty("jna.encoding", "UTF8"); // Ugly global setting, but it seems JNA doesn't allow setting this per-library... + } + public static final Frontlib INSTANCE = (Frontlib)Native.loadLibrary("frontlib", Frontlib.class, Collections.singletonMap(Library.OPTION_TYPE_MAPPER, AndroidTypeMapper.INSTANCE)); + + static { + // We'll just do it here and never quit it again... + if(Flib.INSTANCE.flib_init() != 0) { + throw new RuntimeException("Unable to initialize frontlib"); + } + } + + // Hook frontlib logging into Android logging + private static final Frontlib.LogCallback logCb = new Frontlib.LogCallback() { + public void callback(int level, String message) { + if(level >= Frontlib.FLIB_LOGLEVEL_ERROR) { + Log.e("Frontlib", message); + } else if(level == Frontlib.FLIB_LOGLEVEL_WARNING){ + Log.w("Frontlib", message); + } else if(level == Frontlib.FLIB_LOGLEVEL_INFO){ + Log.i("Frontlib", message); + } else if(level <= Frontlib.FLIB_LOGLEVEL_DEBUG){ + Log.d("Frontlib", message); + } + } + }; + static { + INSTANCE.flib_log_setLevel(Frontlib.FLIB_LOGLEVEL_INFO); + INSTANCE.flib_log_setCallback(logCb); + } } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/frontlib/Frontlib.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/frontlib/Frontlib.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/frontlib/Frontlib.java Tue Jan 21 22:43:06 2014 +0100 @@ -1,1263 +1,1263 @@ -/* - * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - - -package org.hedgewars.hedgeroid.frontlib; -import java.io.UnsupportedEncodingException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.hedgewars.hedgeroid.Datastructures.Hog; -import org.hedgewars.hedgeroid.Datastructures.MapRecipe; -import org.hedgewars.hedgeroid.Datastructures.MetaScheme; -import org.hedgewars.hedgeroid.Datastructures.MetaScheme.Mod; -import org.hedgewars.hedgeroid.Datastructures.MetaScheme.Setting; -import org.hedgewars.hedgeroid.Datastructures.GameConfig; -import org.hedgewars.hedgeroid.Datastructures.Room; -import org.hedgewars.hedgeroid.Datastructures.Scheme; -import org.hedgewars.hedgeroid.Datastructures.Team; -import org.hedgewars.hedgeroid.Datastructures.TeamInGame; -import org.hedgewars.hedgeroid.Datastructures.TeamIngameAttributes; -import org.hedgewars.hedgeroid.Datastructures.Weaponset; - -import com.sun.jna.Callback; -import com.sun.jna.Library; -import com.sun.jna.Memory; -import com.sun.jna.Pointer; -import com.sun.jna.PointerType; -import com.sun.jna.Structure; - -/** - * Here is an introduction to the most important aspects of the JNA code. - * - * This interface permits access to the Hedgewars frontend library (frontlib) - * from Java. Each function directly contained in the Frontlib interface - * represents a mapped C function. The Structure classes (ending in -Struct) are - * mappings of C structs, and the PointerType classes (ending in -Ptr) represent - * pointers to structs. - * - * Quick notes for USING these classes from outside this package: - * - * Usage should be fairly straightforward, but there are a few surprising - * gotchas. First, when you implement callbacks, YOU are responsible for - * ensuring that the callback objects are not garbage-collected while they might - * still be called! So make sure you keep them in member variables or similar, - * because Java will not know if there are still native references to them. - * - * When using Frontlib from outside its package, you only interact with structs - * via the PointerType classes. They allow you to get at the data of the struct - * with a function called deref(), which creates a plain normal Java object - * representing the data (e.g. SchemePtr.deref() will give you a Scheme object). - * - * Remember that you usually have to destroy structs that you receive from the - * library, because they are owned by the native code, not Java. The recommended - * pattern for most cases is to call deref() on the pointer to get a Java object - * (that you can keep as long as you like), and then immediately destroy the - * struct if it needs destroying. To find out whether and how the struct needs - * to be destroyed, see the library's documentation of the function that you got - * the struct from. - * - * To pass new structs to the library, you can use the static createJavaOwned() - * function in each PointerType, which creates a new struct from the Java object - * you provide, and returns a pointer to that struct that you can pass to - * library functions. This new structure's memory is owned and managed by Java - * code, so do not destroy it with frontlib functions! - * - * There is a slight mismatch between the data model for the game setup. The - * frontlib supports setting initial health and weaponset per-hog, because the - * engine allows for that, but currently neither the networking protocol nor the - * PC frontend support this feature, so the Android version does not take - * advantage of it either and treats both as per-game settings. The initial - * health is contained in the game scheme, the weaponset is explicitly part of - * the GameConfig. When converting GameConfig to a native flib_gamesetup, both - * are automatically copied to all hogs in the game, and for the reverse - * conversion the weaponset of the first hog of the first team is used as the - * GameConfig weaponset. This means that GameConfig.weaponset will be null if - * there are no teams in the game. - * - * When starting a network game, you only need to query the GameSetupPtr from - * the netconn and use it to create the gameconn - this is preferable to using - * your own recreation of the game setup, because that way the same piece of - * code is used to determine the game setup on all platforms. - * - * The "context" parameter of the callbacks is never needed here because JNA - * generates function code for each callback object. Don't worry about it, just - * pass null for context and ignore the context parameter in the callbacks. - * - * Finally, the library functions are documented in the actual library, not - * here, so check the docs there to find out what exactly each function does! - * - * Notes about the structure of this class (for the next one who has to touch - * this...): - * - * Java/C interop is quite fiddly and error-prone, so as long as things work, - * try to stick to the established patterns. - * - * Structure types should always be hidden from the outside world, because they - * can be misused too easily. For example, if you get a Structure from the - * library, change a String value in there and pass it back, JNA will re-write - * that string using Java-owned memory without freeing the old native-owned - * string, which causes a memory leak and possibly a double-free or other Bad - * Things (tm). To avoid problems like this, Structure types are only used - * internally, to map existing structures to Java types (without modifying them) - * or to create brand-new, Java-owned structures. Both operations are exposed to - * the outside through the PointerType classes corresponding to the structures - * in question. - * - * Since all of the struct mapping happens in Java, it is never checked against - * the actual struct declarations in the library. That means strange things can - * start happening at runtime if the frontlib structs are modified without - * changing the mappings here to match. This also applies to the function - * signatures: JNA checks whether the functions actually exist when loading the - * library, but it has no way of knowing whether the signatures are correct. If - * the signatures here deviate from those in the frontlib, you might get stack - * corruption. - * - * In order to check at least the function signatures, take a look at the file - * extra/jnacontrol.c in the frontlib sources. You can validate whether the - * function signatures are still correct by copy-pasting them into jnaControl.c - * and compiling it against the frontlib headers. The typedefs and #defines in - * that file will make the compiler see the Java method signatures as C function - * declarations. Since the same functions are already declared in the frontlib - * headers, the compiler will give you errors if the signatures don't match. - */ -public interface Frontlib extends Library { - public static class NetconnPtr extends PointerType { } - public static class MapconnPtr extends PointerType { } - public static class GameconnPtr extends PointerType { } - - public static class MetaschemePtr extends PointerType { - public MetaScheme deref() { - return deref(getPointer()); - } - - public static MetaScheme deref(Pointer p) { - MetaschemeStruct struct = new MetaschemeStruct(p); - struct.read(); - return struct.toMetaScheme(); - } - } - - public static class RoomArrayPtr extends PointerType { - public Room[] getRooms(int count) { - Pointer ptr = getPointer(); - if(ptr == null) { - return new Room[0]; - } - Pointer[] untypedPtrs = ptr.getPointerArray(0, count); - Room[] result = new Room[count]; - for(int i=0; i deref() { - WeaponsetListStruct struct = new WeaponsetListStruct(getPointer()); - struct.read(); - return struct.toWeaponsetList(); - } - - public static WeaponsetListPtr createJavaOwned(List list) { - WeaponsetListPtr result = new WeaponsetListPtr(); - result.javaOwnedInstance = new WeaponsetListStruct(); - result.javaOwnedInstance.fillFrom(list); - result.javaOwnedInstance.autoWrite(); - result.setPointer(result.javaOwnedInstance.getPointer()); - return result; - } - } - - public static class MapRecipePtr extends PointerType { - private MapRecipeStruct javaOwnedInstance; - - public MapRecipe deref() { - MapRecipeStruct struct = new MapRecipeStruct(getPointer()); - struct.read(); - return struct.toMapRecipe(); - } - - public static MapRecipePtr createJavaOwned(MapRecipe recipe) { - MapRecipePtr result = new MapRecipePtr(); - result.javaOwnedInstance = new MapRecipeStruct(); - result.javaOwnedInstance.fillFrom(recipe); - result.javaOwnedInstance.autoWrite(); - result.setPointer(result.javaOwnedInstance.getPointer()); - return result; - } - } - - public static class SchemePtr extends PointerType { - private SchemeStruct javaOwnedInstance; - - public Scheme deref() { - SchemeStruct struct = new SchemeStruct(getPointer()); - struct.read(); - return struct.toScheme(); - } - - public static SchemePtr createJavaOwned(Scheme scheme) { - SchemePtr result = new SchemePtr(); - result.javaOwnedInstance = new SchemeStruct(); - result.javaOwnedInstance.fillFrom(scheme); - result.javaOwnedInstance.autoWrite(); - result.setPointer(result.javaOwnedInstance.getPointer()); - return result; - } - } - - public static class SchemelistPtr extends PointerType { - private SchemelistStruct javaOwnedInstance; - - public List deref() { - SchemelistStruct struct = new SchemelistStruct(getPointer()); - struct.read(); - return struct.toSchemeList(); - } - - public static SchemelistPtr createJavaOwned(List schemes) { - SchemelistPtr result = new SchemelistPtr(); - result.javaOwnedInstance = new SchemelistStruct(); - result.javaOwnedInstance.fillFrom(schemes); - result.javaOwnedInstance.autoWrite(); - result.setPointer(result.javaOwnedInstance.getPointer()); - return result; - } - } - - public static class GameSetupPtr extends PointerType { - private GameSetupStruct javaOwnedInstance; - - public GameConfig deref() { - GameSetupStruct struct = new GameSetupStruct(getPointer()); - struct.read(); - return struct.toGameConfig(); - } - - public static GameSetupPtr createJavaOwned(GameConfig conf) { - GameSetupPtr result = new GameSetupPtr(); - result.javaOwnedInstance = new GameSetupStruct(); - result.javaOwnedInstance.fillFrom(conf); - result.javaOwnedInstance.autoWrite(); - result.setPointer(result.javaOwnedInstance.getPointer()); - return result; - } - } - - public static class ByteArrayPtr extends PointerType { - public byte[] deref(int size) { - return getPointer().getByteArray(0, size); - } - - public static byte[] deref(ByteArrayPtr ptr, int size) { - if(ptr==null && size==0) { - return null; - } else { - return ptr.deref(size); - } - } - - public static ByteArrayPtr createJavaOwned(byte[] buffer) { - if(buffer == null || buffer.length == 0) { - return null; - } - // no need for javaOwnedInstance here because PointerType - // remembers the memory as its Pointer - Pointer ptr = new Memory(buffer.length); - ptr.write(0, buffer, 0, buffer.length); - ByteArrayPtr result = new ByteArrayPtr(); - result.setPointer(ptr); - return result; - } - } - - static class HogStruct extends Structure { - public static class ByVal extends HogStruct implements Structure.ByValue {} - public static class ByRef extends HogStruct implements Structure.ByReference {} - - public HogStruct() { super(); } - public HogStruct(Pointer ptr) { super(ptr); } - - @Override - protected List getFieldOrder() { - return Arrays.asList("name", "hat", "rounds", "kills", "deaths", "suicides", "difficulty", "initialHealth", "weaponset"); - } - - public void fillFrom(Hog hog) { - difficulty = hog.level; - hat = hog.hat; - name = hog.name; - } - - public Hog toHog() { - return new Hog(name, hat, difficulty); - } - - public String name; - public String hat; - - public int rounds; - public int kills; - public int deaths; - public int suicides; - - public int difficulty; - - public int initialHealth; - public WeaponsetStruct.ByRef weaponset; - } - - static class TeamStruct extends Structure { - public static class ByVal extends TeamStruct implements Structure.ByValue {} - public static class ByRef extends TeamStruct implements Structure.ByReference {} - - public TeamStruct() { super(); } - public TeamStruct(Pointer ptr) { super(ptr); } - - @Override - protected List getFieldOrder() { - return Arrays.asList("hogs", "name", "grave", "fort", "voicepack", "flag", "bindings", "bindingCount", "rounds", "wins", "campaignProgress", "colorIndex", "hogsInGame", "remoteDriven", "ownerName"); - } - - public void fillFrom(Team team, TeamIngameAttributes attrs) { - if(team != null) { - name = team.name; - grave = team.grave; - flag = team.flag; - voicepack = team.voice; - fort = team.fort; - if(team.hogs.size() != Team.HEDGEHOGS_PER_TEAM) { - throw new IllegalArgumentException(); - } - for(int i=0; i hogList = new ArrayList(); - for(int i=0; i getFieldOrder() { - return Arrays.asList("loadout", "crateprob", "crateammo", "delay", "name"); - } - - public void fillFrom(Weaponset weaponset) { - fillWeaponInfo(loadout, weaponset.loadout); - fillWeaponInfo(crateprob, weaponset.crateProb); - fillWeaponInfo(crateammo, weaponset.crateAmmo); - fillWeaponInfo(delay, weaponset.delay); - name = weaponset.name; - } - - private static void fillWeaponInfo(byte[] array, String str) { - for(int i=0; i getFieldOrder() { - return Arrays.asList("weaponset"); - } - - public WeaponsetStruct.ByRef weaponset; - } - - static class WeaponsetListStruct extends Structure { - public static class ByVal extends WeaponsetListStruct implements Structure.ByValue {} - public static class ByRef extends WeaponsetListStruct implements Structure.ByReference {} - - public WeaponsetListStruct() { super(); } - public WeaponsetListStruct(Pointer ptr) { super(ptr); } - - @Override - protected List getFieldOrder() { - return Arrays.asList("weaponsetCount", "weaponsets"); - } - - public void fillFrom(List list) { - weaponsetCount = list.size(); - if(weaponsetCount<=0) { - weaponsets = null; - } else { - weaponsets = new WeaponsetPointerByReference(); - Structure[] structs = weaponsets.toArray(weaponsetCount); - - for(int i=0; i toWeaponsetList() { - if(weaponsetCount<=0) { - return new ArrayList(); - } else { - List list = new ArrayList(weaponsetCount); - Structure[] structs = weaponsets.toArray(weaponsetCount); - - for(int i=0; i getFieldOrder() { - return Arrays.asList("inProgress", "name", "playerCount", "teamCount", "owner", "map", "scheme", "weapons"); - } - - public Room toRoomlistRoom() { - return new Room(name, map, scheme, weapons, owner, playerCount, teamCount, inProgress); - } - - public boolean inProgress; - public String name; - public int playerCount; - public int teamCount; - public String owner; - public String map; - public String scheme; - public String weapons; - } - - static class MapRecipeStruct extends Structure { - public static class ByVal extends MapRecipeStruct implements Structure.ByValue {} - public static class ByRef extends MapRecipeStruct implements Structure.ByReference {} - - public MapRecipeStruct() { super(); } - public MapRecipeStruct(Pointer ptr) { super(ptr); } - - @Override - protected List getFieldOrder() { - return Arrays.asList("mapgen", "name", "seed", "theme", "drawData", "drawDataSize", "templateFilter", "mazeSize"); - } - - public void fillFrom(MapRecipe map) { - mapgen = map.mapgen; - name = map.name; - seed = map.seed; - theme = map.theme; - byte[] buf = map.getDrawData(); - drawData = ByteArrayPtr.createJavaOwned(buf); - drawDataSize = NativeSizeT.valueOf(buf==null ? 0 : buf.length); - templateFilter = map.templateFilter; - mazeSize = map.mazeSize; - } - - public MapRecipe toMapRecipe() { - byte[] buf = ByteArrayPtr.deref(drawData, drawDataSize.intValue()); - return new MapRecipe(mapgen, templateFilter, mazeSize, name, seed, theme, buf); - } - - public int mapgen; - public String name; - public String seed; - public String theme; - public ByteArrayPtr drawData; - public NativeSizeT drawDataSize; - public int templateFilter; - public int mazeSize; - } - - static class MetaschemeSettingStruct extends Structure { - public static class ByVal extends MetaschemeSettingStruct implements Structure.ByValue {} - public static class ByRef extends MetaschemeSettingStruct implements Structure.ByReference {} - - public MetaschemeSettingStruct() { super(); } - public MetaschemeSettingStruct(Pointer ptr) { super(ptr); } - - @Override - protected List getFieldOrder() { - return Arrays.asList("name", "engineCommand", "maxMeansInfinity", "times1000", "min", "max", "def"); - } - - public void fillFrom(Setting setting) { - name = setting.name; - engineCommand = setting.engineCommand; - maxMeansInfinity = setting.maxMeansInfinity; - times1000 = setting.times1000; - min = setting.min; - max = setting.max; - def = setting.def; - } - - public MetaScheme.Setting toMetaSchemeSetting() { - return new MetaScheme.Setting(name, engineCommand, maxMeansInfinity, times1000, min, max, def); - } - - public String name; - public String engineCommand; - public boolean maxMeansInfinity; - public boolean times1000; - public int min; - public int max; - public int def; - } - - static class MetaschemeModStruct extends Structure { - public static class ByVal extends MetaschemeModStruct implements Structure.ByValue {} - public static class ByRef extends MetaschemeModStruct implements Structure.ByReference {} - - public MetaschemeModStruct() { super(); } - public MetaschemeModStruct(Pointer ptr) { super(ptr); } - - @Override - protected List getFieldOrder() { - return Arrays.asList("name", "bitmaskIndex"); - } - - public void fillFrom(Mod mod) { - name = mod.name; - bitmaskIndex = mod.bitmaskIndex; - } - - public MetaScheme.Mod toMetaSchemeMod() { - return new MetaScheme.Mod(name, bitmaskIndex); - } - - public String name; - public int bitmaskIndex; - - } - - static class MetaschemeStruct extends Structure { - public static class ByVal extends MetaschemeStruct implements Structure.ByValue {} - public static class ByRef extends MetaschemeStruct implements Structure.ByReference {} - - public MetaschemeStruct() { super(); } - public MetaschemeStruct(Pointer ptr) { super(ptr); } - - @Override - protected List getFieldOrder() { - return Arrays.asList("settingCount", "modCount", "settings", "mods"); - } - - /** - * Only use on native-owned structs! - * Calling this method on a Java-owned struct could cause garbage collection of referenced - * structures. - */ - public MetaScheme toMetaScheme() { - List settingList = new ArrayList(settingCount); - List modList = new ArrayList(modCount); - - Structure[] settingStructs = settings.toArray(settingCount); - Structure[] modStructs = mods.toArray(modCount); - - for(int i=0; i getFieldOrder() { - return Arrays.asList("name", "settings", "mods"); - } - - public void fillFrom(Scheme scheme) { - MetaScheme meta = MetaScheme.INSTANCE; - name = scheme.name; - settings = new Memory(AndroidTypeMapper.NATIVE_INT_SIZE * meta.settings.size()); - for(int i=0; i settingsMap = new HashMap(); - MetaScheme meta = MetaScheme.INSTANCE; - for(int i=0; i modsMap = new HashMap(); - for(int i=0; i getFieldOrder() { - return Arrays.asList("scheme"); - } - - public SchemeStruct.ByRef scheme; - } - - static class SchemelistStruct extends Structure { - public static class ByVal extends SchemelistStruct implements Structure.ByValue {} - public static class ByRef extends SchemelistStruct implements Structure.ByReference {} - - public SchemelistStruct() { super(); } - public SchemelistStruct(Pointer ptr) { super(ptr); } - - @Override - protected List getFieldOrder() { - return Arrays.asList("schemeCount", "schemes"); - } - - public void fillFrom(List schemeList) { - schemeCount = schemeList.size(); - if(schemeCount<=0) { - schemes = null; - } else { - schemes = new SchemePointerByReference(); - Structure[] schemePtrStructs = schemes.toArray(schemeCount); - - for(int i=0; i toSchemeList() { - if(schemeCount<=0) { - return new ArrayList(); - } else { - List schemeList = new ArrayList(schemeCount); - - Structure[] schemePtrStructs = schemes.toArray(schemeCount); - - for(int i=0; i getFieldOrder() { - return Arrays.asList("team"); - } - - public TeamStruct.ByRef team; - } - - static class TeamlistStruct extends Structure { - public static class ByVal extends TeamlistStruct implements Structure.ByValue {} - public static class ByRef extends TeamlistStruct implements Structure.ByReference {} - - public TeamlistStruct() { super(); } - public TeamlistStruct(Pointer ptr) { super(ptr); } - - @Override - protected List getFieldOrder() { - return Arrays.asList("teamCount", "teams"); - } - - public void fillFrom(List teamList, WeaponsetStruct.ByRef weaponset, int initialHealth) { - teamCount = teamList.size(); - if(teamCount <= 0) { - teams = null; - } else { - teams = new TeamPointerByReference(); - Structure[] teamPtrStructs = teams.toArray(teamCount); - - for(int i=0; i toTeamInGameList() { - if(teamCount<=0) { - return new ArrayList(); - } else { - List result = new ArrayList(teamCount); - Structure[] structs = teams.toArray(teamCount); - - for(int i=0; i getFieldOrder() { - return Arrays.asList("script", "gamescheme", "map", "teamlist"); - } - - public void fillFrom(GameConfig conf) { - script = conf.style; - gamescheme = new SchemeStruct.ByRef(); - gamescheme.fillFrom(conf.scheme); - map = new MapRecipeStruct.ByRef(); - map.fillFrom(conf.map); - - /* - * At this point we deviate from the usual copying pattern because the frontlib - * expects per-hog weapons and initial health, but the UI models them as per- - * game, so we extract them from the config here and pass them on to be included - * in each hog. - */ - WeaponsetStruct.ByRef wss = new WeaponsetStruct.ByRef(); - wss.fillFrom(conf.weaponset); - int initialHealth = conf.scheme.getHealth(); - - teamlist = new TeamlistStruct.ByRef(); - teamlist.fillFrom(conf.teams, wss, initialHealth); - } - - public GameConfig toGameConfig() { - Scheme scheme = gamescheme != null ? gamescheme.toScheme() : null; - MapRecipe mapRecipe = map != null ? map.toMapRecipe() : null; - List teams = teamlist != null ? teamlist.toTeamInGameList() : null; - - WeaponsetStruct weaponsetStruct = teamlist != null && teamlist.teamCount>0 ? teamlist.teams.team.hogs[0].weaponset : null; - Weaponset weaponset = weaponsetStruct != null ? weaponsetStruct.toWeaponset() : null; - return new GameConfig(script, scheme, mapRecipe, teams, weaponset); - } - - public String script; - public SchemeStruct.ByRef gamescheme; - public MapRecipeStruct.ByRef map; - public TeamlistStruct.ByRef teamlist; - } - - /* - * Callback interfaces. The context parameter is never needed here and - * should always be ignored. Be sure to keep a reference to each callback - * for as long as they might be called by native code, to avoid premature - * garbage collection. - */ - public static interface VoidCallback extends Callback { - void callback(Pointer context); - } - - public static interface StrCallback extends Callback { - void callback(Pointer context, String arg1); - } - - public static interface IntCallback extends Callback { - void callback(Pointer context, int arg1); - } - - public static interface IntStrCallback extends Callback { - void callback(Pointer context, int arg1, String arg2); - } - - public static interface StrIntCallback extends Callback { - void callback(Pointer context, String arg1, int arg2); - } - - public static interface StrStrCallback extends Callback { - void callback(Pointer context, String arg1, String arg2); - } - - public static interface StrStrBoolCallback extends Callback { - void callback(Pointer context, String arg1, String arg2, boolean arg3); - } - - public static interface RoomCallback extends Callback { - void callback(Pointer context, RoomPtr arg1); - } - - public static interface RoomListCallback extends Callback { - void callback(Pointer context, RoomArrayPtr arg1, int count); - } - - public static interface StrRoomCallback extends Callback { - void callback(Pointer context, String arg1, RoomPtr arg2); - } - - public static interface BoolCallback extends Callback { - void callback(Pointer context, boolean arg1); - } - - public static interface StrBoolCallback extends Callback { - void callback(Pointer context, String arg1, boolean arg2); - } - - public static interface TeamCallback extends Callback { - void callback(Pointer context, TeamPtr arg1); - } - - public static interface BytesCallback extends Callback { - void callback(Pointer context, ByteArrayPtr buffer, NativeSizeT size); - } - - public static interface BytesBoolCallback extends Callback { - void callback(Pointer context, ByteArrayPtr buffer, NativeSizeT size, boolean arg3); - } - - public static interface SchemeCallback extends Callback { - void callback(Pointer context, SchemePtr arg1); - } - - public static interface MapIntCallback extends Callback { - void callback(Pointer context, MapRecipePtr arg1, int arg2); - } - - public static interface WeaponsetCallback extends Callback { - void callback(Pointer context, WeaponsetPtr arg1); - } - - public static interface MapimageCallback extends Callback { - void callback(Pointer context, ByteArrayPtr buffer, int hedgehogCount); - } - - public static interface LogCallback extends Callback { - void callback(int level, String logMessage); - } - - // frontlib.h - int flib_init(); - void flib_quit(); - - // hwconsts.h - int flib_get_teamcolor(int colorIndex); - int flib_get_teamcolor_count(); - int flib_get_hedgehogs_per_team(); - int flib_get_weapons_count(); - MetaschemePtr flib_get_metascheme(); - - // net/netconn.h - static final int NETCONN_STATE_CONNECTING = 0; - static final int NETCONN_STATE_LOBBY = 1; - static final int NETCONN_STATE_ROOM = 2; - static final int NETCONN_STATE_DISCONNECTED = 10; - - static final int NETCONN_DISCONNECT_NORMAL = 0; - static final int NETCONN_DISCONNECT_SERVER_TOO_OLD = 1; - static final int NETCONN_DISCONNECT_AUTH_FAILED = 2; - static final int NETCONN_DISCONNECT_CONNLOST = 3; - static final int NETCONN_DISCONNECT_INTERNAL_ERROR = 100; - - static final int NETCONN_ROOMLEAVE_ABANDONED = 0; - static final int NETCONN_ROOMLEAVE_KICKED = 1; - - static final int NETCONN_MSG_TYPE_PLAYERINFO = 0; - static final int NETCONN_MSG_TYPE_SERVERMESSAGE = 1; - static final int NETCONN_MSG_TYPE_WARNING = 2; - static final int NETCONN_MSG_TYPE_ERROR = 3; - - static final int NETCONN_MAPCHANGE_FULL = 0; - static final int NETCONN_MAPCHANGE_MAP = 1; - static final int NETCONN_MAPCHANGE_MAPGEN = 2; - static final int NETCONN_MAPCHANGE_DRAWNMAP = 3; - static final int NETCONN_MAPCHANGE_MAZE_SIZE = 4; - static final int NETCONN_MAPCHANGE_TEMPLATE = 5; - static final int NETCONN_MAPCHANGE_THEME = 6; - static final int NETCONN_MAPCHANGE_SEED = 7; - - NetconnPtr flib_netconn_create(String playerName, String dataDirPath, String host, int port); - void flib_netconn_destroy(NetconnPtr conn); - - void flib_netconn_tick(NetconnPtr conn); - boolean flib_netconn_is_chief(NetconnPtr conn); - String flib_netconn_get_playername(NetconnPtr conn); - GameSetupPtr flib_netconn_create_gamesetup(NetconnPtr conn); - int flib_netconn_send_quit(NetconnPtr conn, String quitmsg); - int flib_netconn_send_chat(NetconnPtr conn, String chat); - int flib_netconn_send_teamchat(NetconnPtr conn, String msg); - int flib_netconn_send_password(NetconnPtr conn, String passwd); - int flib_netconn_send_nick(NetconnPtr conn, String nick); - int flib_netconn_send_request_roomlist(NetconnPtr conn); - int flib_netconn_send_joinRoom(NetconnPtr conn, String room); - int flib_netconn_send_createRoom(NetconnPtr conn, String room); - int flib_netconn_send_renameRoom(NetconnPtr conn, String roomName); - int flib_netconn_send_leaveRoom(NetconnPtr conn, String msg); - int flib_netconn_send_toggleReady(NetconnPtr conn); - int flib_netconn_send_addTeam(NetconnPtr conn, TeamPtr team); - int flib_netconn_send_removeTeam(NetconnPtr conn, String teamname); - int flib_netconn_send_engineMessage(NetconnPtr conn, ByteArrayPtr message, NativeSizeT size); - int flib_netconn_send_teamHogCount(NetconnPtr conn, String teamname, int hogcount); - int flib_netconn_send_teamColor(NetconnPtr conn, String teamname, int colorIndex); - int flib_netconn_send_weaponset(NetconnPtr conn, WeaponsetPtr weaponset); - int flib_netconn_send_map(NetconnPtr conn, MapRecipePtr map); - int flib_netconn_send_mapName(NetconnPtr conn, String mapName); - int flib_netconn_send_mapGen(NetconnPtr conn, int mapGen); - int flib_netconn_send_mapTemplate(NetconnPtr conn, int templateFilter); - int flib_netconn_send_mapMazeSize(NetconnPtr conn, int mazeSize); - int flib_netconn_send_mapSeed(NetconnPtr conn, String seed); - int flib_netconn_send_mapTheme(NetconnPtr conn, String theme); - int flib_netconn_send_mapDrawdata(NetconnPtr conn, ByteArrayPtr drawData, NativeSizeT size); - int flib_netconn_send_script(NetconnPtr conn, String scriptName); - int flib_netconn_send_scheme(NetconnPtr conn, SchemePtr scheme); - int flib_netconn_send_roundfinished(NetconnPtr conn, boolean withoutError); - int flib_netconn_send_ban(NetconnPtr conn, String playerName); - int flib_netconn_send_kick(NetconnPtr conn, String playerName); - int flib_netconn_send_playerInfo(NetconnPtr conn, String playerName); - int flib_netconn_send_playerFollow(NetconnPtr conn, String playerName); - int flib_netconn_send_startGame(NetconnPtr conn); - int flib_netconn_send_toggleRestrictJoins(NetconnPtr conn); - int flib_netconn_send_toggleRestrictTeams(NetconnPtr conn); - int flib_netconn_send_clearAccountsCache(NetconnPtr conn); - int flib_netconn_send_setServerVar(NetconnPtr conn, String name, String value); - int flib_netconn_send_getServerVars(NetconnPtr conn); - - void flib_netconn_onMessage(NetconnPtr conn, IntStrCallback callback, Pointer context); - void flib_netconn_onClientFlags(NetconnPtr conn, StrStrBoolCallback callback, Pointer context); - void flib_netconn_onChat(NetconnPtr conn, StrStrCallback callback, Pointer context); - void flib_netconn_onConnected(NetconnPtr conn, VoidCallback callback, Pointer context); - void flib_netconn_onDisconnected(NetconnPtr conn, IntStrCallback callback, Pointer context); - void flib_netconn_onRoomlist(NetconnPtr conn, RoomListCallback callback, Pointer context); - void flib_netconn_onRoomAdd(NetconnPtr conn, RoomCallback callback, Pointer context); - void flib_netconn_onRoomDelete(NetconnPtr conn, StrCallback callback, Pointer context); - void flib_netconn_onRoomUpdate(NetconnPtr conn, StrRoomCallback callback, Pointer context); - void flib_netconn_onLobbyJoin(NetconnPtr conn, StrCallback callback, Pointer context); - void flib_netconn_onLobbyLeave(NetconnPtr conn, StrStrCallback callback, Pointer context); - void flib_netconn_onNickTaken(NetconnPtr conn, StrCallback callback, Pointer context); - void flib_netconn_onPasswordRequest(NetconnPtr conn, StrCallback callback, Pointer context); - void flib_netconn_onEnterRoom(NetconnPtr conn, BoolCallback callback, Pointer context); - void flib_netconn_onLeaveRoom(NetconnPtr conn, IntStrCallback callback, Pointer context); - void flib_netconn_onTeamAdd(NetconnPtr conn, TeamCallback callback, Pointer context); - void flib_netconn_onTeamDelete(NetconnPtr conn, StrCallback callback, Pointer context); - void flib_netconn_onRoomJoin(NetconnPtr conn, StrCallback callback, Pointer context); - void flib_netconn_onRoomLeave(NetconnPtr conn, StrStrCallback callback, Pointer context); - void flib_netconn_onRunGame(NetconnPtr conn, VoidCallback callback, Pointer context); - void flib_netconn_onTeamAccepted(NetconnPtr conn, StrCallback callback, Pointer context); - void flib_netconn_onHogCountChanged(NetconnPtr conn, StrIntCallback callback, Pointer context); - void flib_netconn_onTeamColorChanged(NetconnPtr conn, StrIntCallback callback, Pointer context); - void flib_netconn_onEngineMessage(NetconnPtr conn, BytesCallback callback, Pointer context); - void flib_netconn_onSchemeChanged(NetconnPtr conn, SchemeCallback callback, Pointer context); - void flib_netconn_onMapChanged(NetconnPtr conn, MapIntCallback callback, Pointer context); - void flib_netconn_onScriptChanged(NetconnPtr conn, StrCallback callback, Pointer context); - void flib_netconn_onWeaponsetChanged(NetconnPtr conn, WeaponsetCallback callback, Pointer context); - void flib_netconn_onServerVar(NetconnPtr conn, StrStrCallback callback, Pointer context); - - // ipc/gameconn.h - static final int GAME_END_FINISHED = 0; - static final int GAME_END_INTERRUPTED = 1; - static final int GAME_END_HALTED = 2; - static final int GAME_END_ERROR = 3; - - GameconnPtr flib_gameconn_create(String playerName, GameSetupPtr setup, boolean netgame); - GameconnPtr flib_gameconn_create_playdemo(ByteArrayPtr demo, NativeSizeT size); - GameconnPtr flib_gameconn_create_loadgame(String playerName, ByteArrayPtr save, NativeSizeT size); - GameconnPtr flib_gameconn_create_campaign(String playerName, String seed, String script); - - void flib_gameconn_destroy(GameconnPtr conn); - int flib_gameconn_getport(GameconnPtr conn); - void flib_gameconn_tick(GameconnPtr conn); - - int flib_gameconn_send_enginemsg(GameconnPtr conn, ByteArrayPtr data, NativeSizeT len); - int flib_gameconn_send_textmsg(GameconnPtr conn, int msgtype, String msg); - int flib_gameconn_send_chatmsg(GameconnPtr conn, String playername, String msg); - int flib_gameconn_send_quit(GameconnPtr conn); - int flib_gameconn_send_cmd(GameconnPtr conn, String cmdString); - - void flib_gameconn_onConnect(GameconnPtr conn, VoidCallback callback, Pointer context); - void flib_gameconn_onDisconnect(GameconnPtr conn, IntCallback callback, Pointer context); - void flib_gameconn_onErrorMessage(GameconnPtr conn, StrCallback callback, Pointer context); - void flib_gameconn_onChat(GameconnPtr conn, StrBoolCallback callback, Pointer context); - void flib_gameconn_onGameRecorded(GameconnPtr conn, BytesBoolCallback callback, Pointer context); - void flib_gameconn_onEngineMessage(GameconnPtr conn, BytesCallback callback, Pointer context); - - // ipc/mapconn.h - public static final int MAPIMAGE_WIDTH = 256; - public static final int MAPIMAGE_HEIGHT = 128; - public static final int MAPIMAGE_BYTES = (MAPIMAGE_WIDTH/8*MAPIMAGE_HEIGHT); - - MapconnPtr flib_mapconn_create(MapRecipePtr mapdesc); - void flib_mapconn_destroy(MapconnPtr conn); - int flib_mapconn_getport(MapconnPtr conn); - void flib_mapconn_onSuccess(MapconnPtr conn, MapimageCallback callback, Pointer context); - void flib_mapconn_onFailure(MapconnPtr conn, StrCallback callback, Pointer context); - void flib_mapconn_tick(MapconnPtr conn); - - // model/map.h - public static final int MAPGEN_REGULAR = 0; - public static final int MAPGEN_MAZE = 1; - public static final int MAPGEN_DRAWN = 2; - public static final int MAPGEN_NAMED = 3; - - public static final int TEMPLATEFILTER_ALL = 0; - public static final int TEMPLATEFILTER_SMALL = 1; - public static final int TEMPLATEFILTER_MEDIUM = 2; - public static final int TEMPLATEFILTER_LARGE = 3; - public static final int TEMPLATEFILTER_CAVERN = 4; - public static final int TEMPLATEFILTER_WACKY = 5; - - public static final int MAZE_SIZE_SMALL_TUNNELS = 0; - public static final int MAZE_SIZE_MEDIUM_TUNNELS = 1; - public static final int MAZE_SIZE_LARGE_TUNNELS = 2; - public static final int MAZE_SIZE_SMALL_ISLANDS = 3; - public static final int MAZE_SIZE_MEDIUM_ISLANDS = 4; - public static final int MAZE_SIZE_LARGE_ISLANDS = 5; - - // model/schemelist.h - SchemelistPtr flib_schemelist_from_ini(String filename); - int flib_schemelist_to_ini(String filename, SchemelistPtr list); - void flib_schemelist_destroy(SchemelistPtr list); - - // model/team.h - TeamPtr flib_team_from_ini(String filename); - int flib_team_to_ini(String filename, TeamPtr team); - void flib_team_destroy(TeamPtr team); - - // model/weapon.h - WeaponsetListPtr flib_weaponsetlist_from_ini(String filename); - int flib_weaponsetlist_to_ini(String filename, WeaponsetListPtr weaponsets); - void flib_weaponsetlist_destroy(WeaponsetListPtr list); - - // model/gamesetup.h - void flib_gamesetup_destroy(GameSetupPtr gamesetup); - - // util/logging.h - public static final int FLIB_LOGLEVEL_ALL = -100; - public static final int FLIB_LOGLEVEL_DEBUG = -1; - public static final int FLIB_LOGLEVEL_INFO = 0; - public static final int FLIB_LOGLEVEL_WARNING = 1; - public static final int FLIB_LOGLEVEL_ERROR = 2; - public static final int FLIB_LOGLEVEL_NONE = 100; - - void flib_log_setLevel(int level); - void flib_log_setCallback(LogCallback callback); +/* + * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +package org.hedgewars.hedgeroid.frontlib; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.hedgewars.hedgeroid.Datastructures.Hog; +import org.hedgewars.hedgeroid.Datastructures.MapRecipe; +import org.hedgewars.hedgeroid.Datastructures.MetaScheme; +import org.hedgewars.hedgeroid.Datastructures.MetaScheme.Mod; +import org.hedgewars.hedgeroid.Datastructures.MetaScheme.Setting; +import org.hedgewars.hedgeroid.Datastructures.GameConfig; +import org.hedgewars.hedgeroid.Datastructures.Room; +import org.hedgewars.hedgeroid.Datastructures.Scheme; +import org.hedgewars.hedgeroid.Datastructures.Team; +import org.hedgewars.hedgeroid.Datastructures.TeamInGame; +import org.hedgewars.hedgeroid.Datastructures.TeamIngameAttributes; +import org.hedgewars.hedgeroid.Datastructures.Weaponset; + +import com.sun.jna.Callback; +import com.sun.jna.Library; +import com.sun.jna.Memory; +import com.sun.jna.Pointer; +import com.sun.jna.PointerType; +import com.sun.jna.Structure; + +/** + * Here is an introduction to the most important aspects of the JNA code. + * + * This interface permits access to the Hedgewars frontend library (frontlib) + * from Java. Each function directly contained in the Frontlib interface + * represents a mapped C function. The Structure classes (ending in -Struct) are + * mappings of C structs, and the PointerType classes (ending in -Ptr) represent + * pointers to structs. + * + * Quick notes for USING these classes from outside this package: + * + * Usage should be fairly straightforward, but there are a few surprising + * gotchas. First, when you implement callbacks, YOU are responsible for + * ensuring that the callback objects are not garbage-collected while they might + * still be called! So make sure you keep them in member variables or similar, + * because Java will not know if there are still native references to them. + * + * When using Frontlib from outside its package, you only interact with structs + * via the PointerType classes. They allow you to get at the data of the struct + * with a function called deref(), which creates a plain normal Java object + * representing the data (e.g. SchemePtr.deref() will give you a Scheme object). + * + * Remember that you usually have to destroy structs that you receive from the + * library, because they are owned by the native code, not Java. The recommended + * pattern for most cases is to call deref() on the pointer to get a Java object + * (that you can keep as long as you like), and then immediately destroy the + * struct if it needs destroying. To find out whether and how the struct needs + * to be destroyed, see the library's documentation of the function that you got + * the struct from. + * + * To pass new structs to the library, you can use the static createJavaOwned() + * function in each PointerType, which creates a new struct from the Java object + * you provide, and returns a pointer to that struct that you can pass to + * library functions. This new structure's memory is owned and managed by Java + * code, so do not destroy it with frontlib functions! + * + * There is a slight mismatch between the data model for the game setup. The + * frontlib supports setting initial health and weaponset per-hog, because the + * engine allows for that, but currently neither the networking protocol nor the + * PC frontend support this feature, so the Android version does not take + * advantage of it either and treats both as per-game settings. The initial + * health is contained in the game scheme, the weaponset is explicitly part of + * the GameConfig. When converting GameConfig to a native flib_gamesetup, both + * are automatically copied to all hogs in the game, and for the reverse + * conversion the weaponset of the first hog of the first team is used as the + * GameConfig weaponset. This means that GameConfig.weaponset will be null if + * there are no teams in the game. + * + * When starting a network game, you only need to query the GameSetupPtr from + * the netconn and use it to create the gameconn - this is preferable to using + * your own recreation of the game setup, because that way the same piece of + * code is used to determine the game setup on all platforms. + * + * The "context" parameter of the callbacks is never needed here because JNA + * generates function code for each callback object. Don't worry about it, just + * pass null for context and ignore the context parameter in the callbacks. + * + * Finally, the library functions are documented in the actual library, not + * here, so check the docs there to find out what exactly each function does! + * + * Notes about the structure of this class (for the next one who has to touch + * this...): + * + * Java/C interop is quite fiddly and error-prone, so as long as things work, + * try to stick to the established patterns. + * + * Structure types should always be hidden from the outside world, because they + * can be misused too easily. For example, if you get a Structure from the + * library, change a String value in there and pass it back, JNA will re-write + * that string using Java-owned memory without freeing the old native-owned + * string, which causes a memory leak and possibly a double-free or other Bad + * Things (tm). To avoid problems like this, Structure types are only used + * internally, to map existing structures to Java types (without modifying them) + * or to create brand-new, Java-owned structures. Both operations are exposed to + * the outside through the PointerType classes corresponding to the structures + * in question. + * + * Since all of the struct mapping happens in Java, it is never checked against + * the actual struct declarations in the library. That means strange things can + * start happening at runtime if the frontlib structs are modified without + * changing the mappings here to match. This also applies to the function + * signatures: JNA checks whether the functions actually exist when loading the + * library, but it has no way of knowing whether the signatures are correct. If + * the signatures here deviate from those in the frontlib, you might get stack + * corruption. + * + * In order to check at least the function signatures, take a look at the file + * extra/jnacontrol.c in the frontlib sources. You can validate whether the + * function signatures are still correct by copy-pasting them into jnaControl.c + * and compiling it against the frontlib headers. The typedefs and #defines in + * that file will make the compiler see the Java method signatures as C function + * declarations. Since the same functions are already declared in the frontlib + * headers, the compiler will give you errors if the signatures don't match. + */ +public interface Frontlib extends Library { + public static class NetconnPtr extends PointerType { } + public static class MapconnPtr extends PointerType { } + public static class GameconnPtr extends PointerType { } + + public static class MetaschemePtr extends PointerType { + public MetaScheme deref() { + return deref(getPointer()); + } + + public static MetaScheme deref(Pointer p) { + MetaschemeStruct struct = new MetaschemeStruct(p); + struct.read(); + return struct.toMetaScheme(); + } + } + + public static class RoomArrayPtr extends PointerType { + public Room[] getRooms(int count) { + Pointer ptr = getPointer(); + if(ptr == null) { + return new Room[0]; + } + Pointer[] untypedPtrs = ptr.getPointerArray(0, count); + Room[] result = new Room[count]; + for(int i=0; i deref() { + WeaponsetListStruct struct = new WeaponsetListStruct(getPointer()); + struct.read(); + return struct.toWeaponsetList(); + } + + public static WeaponsetListPtr createJavaOwned(List list) { + WeaponsetListPtr result = new WeaponsetListPtr(); + result.javaOwnedInstance = new WeaponsetListStruct(); + result.javaOwnedInstance.fillFrom(list); + result.javaOwnedInstance.autoWrite(); + result.setPointer(result.javaOwnedInstance.getPointer()); + return result; + } + } + + public static class MapRecipePtr extends PointerType { + private MapRecipeStruct javaOwnedInstance; + + public MapRecipe deref() { + MapRecipeStruct struct = new MapRecipeStruct(getPointer()); + struct.read(); + return struct.toMapRecipe(); + } + + public static MapRecipePtr createJavaOwned(MapRecipe recipe) { + MapRecipePtr result = new MapRecipePtr(); + result.javaOwnedInstance = new MapRecipeStruct(); + result.javaOwnedInstance.fillFrom(recipe); + result.javaOwnedInstance.autoWrite(); + result.setPointer(result.javaOwnedInstance.getPointer()); + return result; + } + } + + public static class SchemePtr extends PointerType { + private SchemeStruct javaOwnedInstance; + + public Scheme deref() { + SchemeStruct struct = new SchemeStruct(getPointer()); + struct.read(); + return struct.toScheme(); + } + + public static SchemePtr createJavaOwned(Scheme scheme) { + SchemePtr result = new SchemePtr(); + result.javaOwnedInstance = new SchemeStruct(); + result.javaOwnedInstance.fillFrom(scheme); + result.javaOwnedInstance.autoWrite(); + result.setPointer(result.javaOwnedInstance.getPointer()); + return result; + } + } + + public static class SchemelistPtr extends PointerType { + private SchemelistStruct javaOwnedInstance; + + public List deref() { + SchemelistStruct struct = new SchemelistStruct(getPointer()); + struct.read(); + return struct.toSchemeList(); + } + + public static SchemelistPtr createJavaOwned(List schemes) { + SchemelistPtr result = new SchemelistPtr(); + result.javaOwnedInstance = new SchemelistStruct(); + result.javaOwnedInstance.fillFrom(schemes); + result.javaOwnedInstance.autoWrite(); + result.setPointer(result.javaOwnedInstance.getPointer()); + return result; + } + } + + public static class GameSetupPtr extends PointerType { + private GameSetupStruct javaOwnedInstance; + + public GameConfig deref() { + GameSetupStruct struct = new GameSetupStruct(getPointer()); + struct.read(); + return struct.toGameConfig(); + } + + public static GameSetupPtr createJavaOwned(GameConfig conf) { + GameSetupPtr result = new GameSetupPtr(); + result.javaOwnedInstance = new GameSetupStruct(); + result.javaOwnedInstance.fillFrom(conf); + result.javaOwnedInstance.autoWrite(); + result.setPointer(result.javaOwnedInstance.getPointer()); + return result; + } + } + + public static class ByteArrayPtr extends PointerType { + public byte[] deref(int size) { + return getPointer().getByteArray(0, size); + } + + public static byte[] deref(ByteArrayPtr ptr, int size) { + if(ptr==null && size==0) { + return null; + } else { + return ptr.deref(size); + } + } + + public static ByteArrayPtr createJavaOwned(byte[] buffer) { + if(buffer == null || buffer.length == 0) { + return null; + } + // no need for javaOwnedInstance here because PointerType + // remembers the memory as its Pointer + Pointer ptr = new Memory(buffer.length); + ptr.write(0, buffer, 0, buffer.length); + ByteArrayPtr result = new ByteArrayPtr(); + result.setPointer(ptr); + return result; + } + } + + static class HogStruct extends Structure { + public static class ByVal extends HogStruct implements Structure.ByValue {} + public static class ByRef extends HogStruct implements Structure.ByReference {} + + public HogStruct() { super(); } + public HogStruct(Pointer ptr) { super(ptr); } + + @Override + protected List getFieldOrder() { + return Arrays.asList("name", "hat", "rounds", "kills", "deaths", "suicides", "difficulty", "initialHealth", "weaponset"); + } + + public void fillFrom(Hog hog) { + difficulty = hog.level; + hat = hog.hat; + name = hog.name; + } + + public Hog toHog() { + return new Hog(name, hat, difficulty); + } + + public String name; + public String hat; + + public int rounds; + public int kills; + public int deaths; + public int suicides; + + public int difficulty; + + public int initialHealth; + public WeaponsetStruct.ByRef weaponset; + } + + static class TeamStruct extends Structure { + public static class ByVal extends TeamStruct implements Structure.ByValue {} + public static class ByRef extends TeamStruct implements Structure.ByReference {} + + public TeamStruct() { super(); } + public TeamStruct(Pointer ptr) { super(ptr); } + + @Override + protected List getFieldOrder() { + return Arrays.asList("hogs", "name", "grave", "fort", "voicepack", "flag", "bindings", "bindingCount", "rounds", "wins", "campaignProgress", "colorIndex", "hogsInGame", "remoteDriven", "ownerName"); + } + + public void fillFrom(Team team, TeamIngameAttributes attrs) { + if(team != null) { + name = team.name; + grave = team.grave; + flag = team.flag; + voicepack = team.voice; + fort = team.fort; + if(team.hogs.size() != Team.HEDGEHOGS_PER_TEAM) { + throw new IllegalArgumentException(); + } + for(int i=0; i hogList = new ArrayList(); + for(int i=0; i getFieldOrder() { + return Arrays.asList("loadout", "crateprob", "crateammo", "delay", "name"); + } + + public void fillFrom(Weaponset weaponset) { + fillWeaponInfo(loadout, weaponset.loadout); + fillWeaponInfo(crateprob, weaponset.crateProb); + fillWeaponInfo(crateammo, weaponset.crateAmmo); + fillWeaponInfo(delay, weaponset.delay); + name = weaponset.name; + } + + private static void fillWeaponInfo(byte[] array, String str) { + for(int i=0; i getFieldOrder() { + return Arrays.asList("weaponset"); + } + + public WeaponsetStruct.ByRef weaponset; + } + + static class WeaponsetListStruct extends Structure { + public static class ByVal extends WeaponsetListStruct implements Structure.ByValue {} + public static class ByRef extends WeaponsetListStruct implements Structure.ByReference {} + + public WeaponsetListStruct() { super(); } + public WeaponsetListStruct(Pointer ptr) { super(ptr); } + + @Override + protected List getFieldOrder() { + return Arrays.asList("weaponsetCount", "weaponsets"); + } + + public void fillFrom(List list) { + weaponsetCount = list.size(); + if(weaponsetCount<=0) { + weaponsets = null; + } else { + weaponsets = new WeaponsetPointerByReference(); + Structure[] structs = weaponsets.toArray(weaponsetCount); + + for(int i=0; i toWeaponsetList() { + if(weaponsetCount<=0) { + return new ArrayList(); + } else { + List list = new ArrayList(weaponsetCount); + Structure[] structs = weaponsets.toArray(weaponsetCount); + + for(int i=0; i getFieldOrder() { + return Arrays.asList("inProgress", "name", "playerCount", "teamCount", "owner", "map", "scheme", "weapons"); + } + + public Room toRoomlistRoom() { + return new Room(name, map, scheme, weapons, owner, playerCount, teamCount, inProgress); + } + + public boolean inProgress; + public String name; + public int playerCount; + public int teamCount; + public String owner; + public String map; + public String scheme; + public String weapons; + } + + static class MapRecipeStruct extends Structure { + public static class ByVal extends MapRecipeStruct implements Structure.ByValue {} + public static class ByRef extends MapRecipeStruct implements Structure.ByReference {} + + public MapRecipeStruct() { super(); } + public MapRecipeStruct(Pointer ptr) { super(ptr); } + + @Override + protected List getFieldOrder() { + return Arrays.asList("mapgen", "name", "seed", "theme", "drawData", "drawDataSize", "templateFilter", "mazeSize"); + } + + public void fillFrom(MapRecipe map) { + mapgen = map.mapgen; + name = map.name; + seed = map.seed; + theme = map.theme; + byte[] buf = map.getDrawData(); + drawData = ByteArrayPtr.createJavaOwned(buf); + drawDataSize = NativeSizeT.valueOf(buf==null ? 0 : buf.length); + templateFilter = map.templateFilter; + mazeSize = map.mazeSize; + } + + public MapRecipe toMapRecipe() { + byte[] buf = ByteArrayPtr.deref(drawData, drawDataSize.intValue()); + return new MapRecipe(mapgen, templateFilter, mazeSize, name, seed, theme, buf); + } + + public int mapgen; + public String name; + public String seed; + public String theme; + public ByteArrayPtr drawData; + public NativeSizeT drawDataSize; + public int templateFilter; + public int mazeSize; + } + + static class MetaschemeSettingStruct extends Structure { + public static class ByVal extends MetaschemeSettingStruct implements Structure.ByValue {} + public static class ByRef extends MetaschemeSettingStruct implements Structure.ByReference {} + + public MetaschemeSettingStruct() { super(); } + public MetaschemeSettingStruct(Pointer ptr) { super(ptr); } + + @Override + protected List getFieldOrder() { + return Arrays.asList("name", "engineCommand", "maxMeansInfinity", "times1000", "min", "max", "def"); + } + + public void fillFrom(Setting setting) { + name = setting.name; + engineCommand = setting.engineCommand; + maxMeansInfinity = setting.maxMeansInfinity; + times1000 = setting.times1000; + min = setting.min; + max = setting.max; + def = setting.def; + } + + public MetaScheme.Setting toMetaSchemeSetting() { + return new MetaScheme.Setting(name, engineCommand, maxMeansInfinity, times1000, min, max, def); + } + + public String name; + public String engineCommand; + public boolean maxMeansInfinity; + public boolean times1000; + public int min; + public int max; + public int def; + } + + static class MetaschemeModStruct extends Structure { + public static class ByVal extends MetaschemeModStruct implements Structure.ByValue {} + public static class ByRef extends MetaschemeModStruct implements Structure.ByReference {} + + public MetaschemeModStruct() { super(); } + public MetaschemeModStruct(Pointer ptr) { super(ptr); } + + @Override + protected List getFieldOrder() { + return Arrays.asList("name", "bitmaskIndex"); + } + + public void fillFrom(Mod mod) { + name = mod.name; + bitmaskIndex = mod.bitmaskIndex; + } + + public MetaScheme.Mod toMetaSchemeMod() { + return new MetaScheme.Mod(name, bitmaskIndex); + } + + public String name; + public int bitmaskIndex; + + } + + static class MetaschemeStruct extends Structure { + public static class ByVal extends MetaschemeStruct implements Structure.ByValue {} + public static class ByRef extends MetaschemeStruct implements Structure.ByReference {} + + public MetaschemeStruct() { super(); } + public MetaschemeStruct(Pointer ptr) { super(ptr); } + + @Override + protected List getFieldOrder() { + return Arrays.asList("settingCount", "modCount", "settings", "mods"); + } + + /** + * Only use on native-owned structs! + * Calling this method on a Java-owned struct could cause garbage collection of referenced + * structures. + */ + public MetaScheme toMetaScheme() { + List settingList = new ArrayList(settingCount); + List modList = new ArrayList(modCount); + + Structure[] settingStructs = settings.toArray(settingCount); + Structure[] modStructs = mods.toArray(modCount); + + for(int i=0; i getFieldOrder() { + return Arrays.asList("name", "settings", "mods"); + } + + public void fillFrom(Scheme scheme) { + MetaScheme meta = MetaScheme.INSTANCE; + name = scheme.name; + settings = new Memory(AndroidTypeMapper.NATIVE_INT_SIZE * meta.settings.size()); + for(int i=0; i settingsMap = new HashMap(); + MetaScheme meta = MetaScheme.INSTANCE; + for(int i=0; i modsMap = new HashMap(); + for(int i=0; i getFieldOrder() { + return Arrays.asList("scheme"); + } + + public SchemeStruct.ByRef scheme; + } + + static class SchemelistStruct extends Structure { + public static class ByVal extends SchemelistStruct implements Structure.ByValue {} + public static class ByRef extends SchemelistStruct implements Structure.ByReference {} + + public SchemelistStruct() { super(); } + public SchemelistStruct(Pointer ptr) { super(ptr); } + + @Override + protected List getFieldOrder() { + return Arrays.asList("schemeCount", "schemes"); + } + + public void fillFrom(List schemeList) { + schemeCount = schemeList.size(); + if(schemeCount<=0) { + schemes = null; + } else { + schemes = new SchemePointerByReference(); + Structure[] schemePtrStructs = schemes.toArray(schemeCount); + + for(int i=0; i toSchemeList() { + if(schemeCount<=0) { + return new ArrayList(); + } else { + List schemeList = new ArrayList(schemeCount); + + Structure[] schemePtrStructs = schemes.toArray(schemeCount); + + for(int i=0; i getFieldOrder() { + return Arrays.asList("team"); + } + + public TeamStruct.ByRef team; + } + + static class TeamlistStruct extends Structure { + public static class ByVal extends TeamlistStruct implements Structure.ByValue {} + public static class ByRef extends TeamlistStruct implements Structure.ByReference {} + + public TeamlistStruct() { super(); } + public TeamlistStruct(Pointer ptr) { super(ptr); } + + @Override + protected List getFieldOrder() { + return Arrays.asList("teamCount", "teams"); + } + + public void fillFrom(List teamList, WeaponsetStruct.ByRef weaponset, int initialHealth) { + teamCount = teamList.size(); + if(teamCount <= 0) { + teams = null; + } else { + teams = new TeamPointerByReference(); + Structure[] teamPtrStructs = teams.toArray(teamCount); + + for(int i=0; i toTeamInGameList() { + if(teamCount<=0) { + return new ArrayList(); + } else { + List result = new ArrayList(teamCount); + Structure[] structs = teams.toArray(teamCount); + + for(int i=0; i getFieldOrder() { + return Arrays.asList("script", "gamescheme", "map", "teamlist"); + } + + public void fillFrom(GameConfig conf) { + script = conf.style; + gamescheme = new SchemeStruct.ByRef(); + gamescheme.fillFrom(conf.scheme); + map = new MapRecipeStruct.ByRef(); + map.fillFrom(conf.map); + + /* + * At this point we deviate from the usual copying pattern because the frontlib + * expects per-hog weapons and initial health, but the UI models them as per- + * game, so we extract them from the config here and pass them on to be included + * in each hog. + */ + WeaponsetStruct.ByRef wss = new WeaponsetStruct.ByRef(); + wss.fillFrom(conf.weaponset); + int initialHealth = conf.scheme.getHealth(); + + teamlist = new TeamlistStruct.ByRef(); + teamlist.fillFrom(conf.teams, wss, initialHealth); + } + + public GameConfig toGameConfig() { + Scheme scheme = gamescheme != null ? gamescheme.toScheme() : null; + MapRecipe mapRecipe = map != null ? map.toMapRecipe() : null; + List teams = teamlist != null ? teamlist.toTeamInGameList() : null; + + WeaponsetStruct weaponsetStruct = teamlist != null && teamlist.teamCount>0 ? teamlist.teams.team.hogs[0].weaponset : null; + Weaponset weaponset = weaponsetStruct != null ? weaponsetStruct.toWeaponset() : null; + return new GameConfig(script, scheme, mapRecipe, teams, weaponset); + } + + public String script; + public SchemeStruct.ByRef gamescheme; + public MapRecipeStruct.ByRef map; + public TeamlistStruct.ByRef teamlist; + } + + /* + * Callback interfaces. The context parameter is never needed here and + * should always be ignored. Be sure to keep a reference to each callback + * for as long as they might be called by native code, to avoid premature + * garbage collection. + */ + public static interface VoidCallback extends Callback { + void callback(Pointer context); + } + + public static interface StrCallback extends Callback { + void callback(Pointer context, String arg1); + } + + public static interface IntCallback extends Callback { + void callback(Pointer context, int arg1); + } + + public static interface IntStrCallback extends Callback { + void callback(Pointer context, int arg1, String arg2); + } + + public static interface StrIntCallback extends Callback { + void callback(Pointer context, String arg1, int arg2); + } + + public static interface StrStrCallback extends Callback { + void callback(Pointer context, String arg1, String arg2); + } + + public static interface StrStrBoolCallback extends Callback { + void callback(Pointer context, String arg1, String arg2, boolean arg3); + } + + public static interface RoomCallback extends Callback { + void callback(Pointer context, RoomPtr arg1); + } + + public static interface RoomListCallback extends Callback { + void callback(Pointer context, RoomArrayPtr arg1, int count); + } + + public static interface StrRoomCallback extends Callback { + void callback(Pointer context, String arg1, RoomPtr arg2); + } + + public static interface BoolCallback extends Callback { + void callback(Pointer context, boolean arg1); + } + + public static interface StrBoolCallback extends Callback { + void callback(Pointer context, String arg1, boolean arg2); + } + + public static interface TeamCallback extends Callback { + void callback(Pointer context, TeamPtr arg1); + } + + public static interface BytesCallback extends Callback { + void callback(Pointer context, ByteArrayPtr buffer, NativeSizeT size); + } + + public static interface BytesBoolCallback extends Callback { + void callback(Pointer context, ByteArrayPtr buffer, NativeSizeT size, boolean arg3); + } + + public static interface SchemeCallback extends Callback { + void callback(Pointer context, SchemePtr arg1); + } + + public static interface MapIntCallback extends Callback { + void callback(Pointer context, MapRecipePtr arg1, int arg2); + } + + public static interface WeaponsetCallback extends Callback { + void callback(Pointer context, WeaponsetPtr arg1); + } + + public static interface MapimageCallback extends Callback { + void callback(Pointer context, ByteArrayPtr buffer, int hedgehogCount); + } + + public static interface LogCallback extends Callback { + void callback(int level, String logMessage); + } + + // frontlib.h + int flib_init(); + void flib_quit(); + + // hwconsts.h + int flib_get_teamcolor(int colorIndex); + int flib_get_teamcolor_count(); + int flib_get_hedgehogs_per_team(); + int flib_get_weapons_count(); + MetaschemePtr flib_get_metascheme(); + + // net/netconn.h + static final int NETCONN_STATE_CONNECTING = 0; + static final int NETCONN_STATE_LOBBY = 1; + static final int NETCONN_STATE_ROOM = 2; + static final int NETCONN_STATE_DISCONNECTED = 10; + + static final int NETCONN_DISCONNECT_NORMAL = 0; + static final int NETCONN_DISCONNECT_SERVER_TOO_OLD = 1; + static final int NETCONN_DISCONNECT_AUTH_FAILED = 2; + static final int NETCONN_DISCONNECT_CONNLOST = 3; + static final int NETCONN_DISCONNECT_INTERNAL_ERROR = 100; + + static final int NETCONN_ROOMLEAVE_ABANDONED = 0; + static final int NETCONN_ROOMLEAVE_KICKED = 1; + + static final int NETCONN_MSG_TYPE_PLAYERINFO = 0; + static final int NETCONN_MSG_TYPE_SERVERMESSAGE = 1; + static final int NETCONN_MSG_TYPE_WARNING = 2; + static final int NETCONN_MSG_TYPE_ERROR = 3; + + static final int NETCONN_MAPCHANGE_FULL = 0; + static final int NETCONN_MAPCHANGE_MAP = 1; + static final int NETCONN_MAPCHANGE_MAPGEN = 2; + static final int NETCONN_MAPCHANGE_DRAWNMAP = 3; + static final int NETCONN_MAPCHANGE_MAZE_SIZE = 4; + static final int NETCONN_MAPCHANGE_TEMPLATE = 5; + static final int NETCONN_MAPCHANGE_THEME = 6; + static final int NETCONN_MAPCHANGE_SEED = 7; + + NetconnPtr flib_netconn_create(String playerName, String dataDirPath, String host, int port); + void flib_netconn_destroy(NetconnPtr conn); + + void flib_netconn_tick(NetconnPtr conn); + boolean flib_netconn_is_chief(NetconnPtr conn); + String flib_netconn_get_playername(NetconnPtr conn); + GameSetupPtr flib_netconn_create_gamesetup(NetconnPtr conn); + int flib_netconn_send_quit(NetconnPtr conn, String quitmsg); + int flib_netconn_send_chat(NetconnPtr conn, String chat); + int flib_netconn_send_teamchat(NetconnPtr conn, String msg); + int flib_netconn_send_password(NetconnPtr conn, String passwd); + int flib_netconn_send_nick(NetconnPtr conn, String nick); + int flib_netconn_send_request_roomlist(NetconnPtr conn); + int flib_netconn_send_joinRoom(NetconnPtr conn, String room); + int flib_netconn_send_createRoom(NetconnPtr conn, String room); + int flib_netconn_send_renameRoom(NetconnPtr conn, String roomName); + int flib_netconn_send_leaveRoom(NetconnPtr conn, String msg); + int flib_netconn_send_toggleReady(NetconnPtr conn); + int flib_netconn_send_addTeam(NetconnPtr conn, TeamPtr team); + int flib_netconn_send_removeTeam(NetconnPtr conn, String teamname); + int flib_netconn_send_engineMessage(NetconnPtr conn, ByteArrayPtr message, NativeSizeT size); + int flib_netconn_send_teamHogCount(NetconnPtr conn, String teamname, int hogcount); + int flib_netconn_send_teamColor(NetconnPtr conn, String teamname, int colorIndex); + int flib_netconn_send_weaponset(NetconnPtr conn, WeaponsetPtr weaponset); + int flib_netconn_send_map(NetconnPtr conn, MapRecipePtr map); + int flib_netconn_send_mapName(NetconnPtr conn, String mapName); + int flib_netconn_send_mapGen(NetconnPtr conn, int mapGen); + int flib_netconn_send_mapTemplate(NetconnPtr conn, int templateFilter); + int flib_netconn_send_mapMazeSize(NetconnPtr conn, int mazeSize); + int flib_netconn_send_mapSeed(NetconnPtr conn, String seed); + int flib_netconn_send_mapTheme(NetconnPtr conn, String theme); + int flib_netconn_send_mapDrawdata(NetconnPtr conn, ByteArrayPtr drawData, NativeSizeT size); + int flib_netconn_send_script(NetconnPtr conn, String scriptName); + int flib_netconn_send_scheme(NetconnPtr conn, SchemePtr scheme); + int flib_netconn_send_roundfinished(NetconnPtr conn, boolean withoutError); + int flib_netconn_send_ban(NetconnPtr conn, String playerName); + int flib_netconn_send_kick(NetconnPtr conn, String playerName); + int flib_netconn_send_playerInfo(NetconnPtr conn, String playerName); + int flib_netconn_send_playerFollow(NetconnPtr conn, String playerName); + int flib_netconn_send_startGame(NetconnPtr conn); + int flib_netconn_send_toggleRestrictJoins(NetconnPtr conn); + int flib_netconn_send_toggleRestrictTeams(NetconnPtr conn); + int flib_netconn_send_clearAccountsCache(NetconnPtr conn); + int flib_netconn_send_setServerVar(NetconnPtr conn, String name, String value); + int flib_netconn_send_getServerVars(NetconnPtr conn); + + void flib_netconn_onMessage(NetconnPtr conn, IntStrCallback callback, Pointer context); + void flib_netconn_onClientFlags(NetconnPtr conn, StrStrBoolCallback callback, Pointer context); + void flib_netconn_onChat(NetconnPtr conn, StrStrCallback callback, Pointer context); + void flib_netconn_onConnected(NetconnPtr conn, VoidCallback callback, Pointer context); + void flib_netconn_onDisconnected(NetconnPtr conn, IntStrCallback callback, Pointer context); + void flib_netconn_onRoomlist(NetconnPtr conn, RoomListCallback callback, Pointer context); + void flib_netconn_onRoomAdd(NetconnPtr conn, RoomCallback callback, Pointer context); + void flib_netconn_onRoomDelete(NetconnPtr conn, StrCallback callback, Pointer context); + void flib_netconn_onRoomUpdate(NetconnPtr conn, StrRoomCallback callback, Pointer context); + void flib_netconn_onLobbyJoin(NetconnPtr conn, StrCallback callback, Pointer context); + void flib_netconn_onLobbyLeave(NetconnPtr conn, StrStrCallback callback, Pointer context); + void flib_netconn_onNickTaken(NetconnPtr conn, StrCallback callback, Pointer context); + void flib_netconn_onPasswordRequest(NetconnPtr conn, StrCallback callback, Pointer context); + void flib_netconn_onEnterRoom(NetconnPtr conn, BoolCallback callback, Pointer context); + void flib_netconn_onLeaveRoom(NetconnPtr conn, IntStrCallback callback, Pointer context); + void flib_netconn_onTeamAdd(NetconnPtr conn, TeamCallback callback, Pointer context); + void flib_netconn_onTeamDelete(NetconnPtr conn, StrCallback callback, Pointer context); + void flib_netconn_onRoomJoin(NetconnPtr conn, StrCallback callback, Pointer context); + void flib_netconn_onRoomLeave(NetconnPtr conn, StrStrCallback callback, Pointer context); + void flib_netconn_onRunGame(NetconnPtr conn, VoidCallback callback, Pointer context); + void flib_netconn_onTeamAccepted(NetconnPtr conn, StrCallback callback, Pointer context); + void flib_netconn_onHogCountChanged(NetconnPtr conn, StrIntCallback callback, Pointer context); + void flib_netconn_onTeamColorChanged(NetconnPtr conn, StrIntCallback callback, Pointer context); + void flib_netconn_onEngineMessage(NetconnPtr conn, BytesCallback callback, Pointer context); + void flib_netconn_onSchemeChanged(NetconnPtr conn, SchemeCallback callback, Pointer context); + void flib_netconn_onMapChanged(NetconnPtr conn, MapIntCallback callback, Pointer context); + void flib_netconn_onScriptChanged(NetconnPtr conn, StrCallback callback, Pointer context); + void flib_netconn_onWeaponsetChanged(NetconnPtr conn, WeaponsetCallback callback, Pointer context); + void flib_netconn_onServerVar(NetconnPtr conn, StrStrCallback callback, Pointer context); + + // ipc/gameconn.h + static final int GAME_END_FINISHED = 0; + static final int GAME_END_INTERRUPTED = 1; + static final int GAME_END_HALTED = 2; + static final int GAME_END_ERROR = 3; + + GameconnPtr flib_gameconn_create(String playerName, GameSetupPtr setup, boolean netgame); + GameconnPtr flib_gameconn_create_playdemo(ByteArrayPtr demo, NativeSizeT size); + GameconnPtr flib_gameconn_create_loadgame(String playerName, ByteArrayPtr save, NativeSizeT size); + GameconnPtr flib_gameconn_create_campaign(String playerName, String seed, String script); + + void flib_gameconn_destroy(GameconnPtr conn); + int flib_gameconn_getport(GameconnPtr conn); + void flib_gameconn_tick(GameconnPtr conn); + + int flib_gameconn_send_enginemsg(GameconnPtr conn, ByteArrayPtr data, NativeSizeT len); + int flib_gameconn_send_textmsg(GameconnPtr conn, int msgtype, String msg); + int flib_gameconn_send_chatmsg(GameconnPtr conn, String playername, String msg); + int flib_gameconn_send_quit(GameconnPtr conn); + int flib_gameconn_send_cmd(GameconnPtr conn, String cmdString); + + void flib_gameconn_onConnect(GameconnPtr conn, VoidCallback callback, Pointer context); + void flib_gameconn_onDisconnect(GameconnPtr conn, IntCallback callback, Pointer context); + void flib_gameconn_onErrorMessage(GameconnPtr conn, StrCallback callback, Pointer context); + void flib_gameconn_onChat(GameconnPtr conn, StrBoolCallback callback, Pointer context); + void flib_gameconn_onGameRecorded(GameconnPtr conn, BytesBoolCallback callback, Pointer context); + void flib_gameconn_onEngineMessage(GameconnPtr conn, BytesCallback callback, Pointer context); + + // ipc/mapconn.h + public static final int MAPIMAGE_WIDTH = 256; + public static final int MAPIMAGE_HEIGHT = 128; + public static final int MAPIMAGE_BYTES = (MAPIMAGE_WIDTH/8*MAPIMAGE_HEIGHT); + + MapconnPtr flib_mapconn_create(MapRecipePtr mapdesc); + void flib_mapconn_destroy(MapconnPtr conn); + int flib_mapconn_getport(MapconnPtr conn); + void flib_mapconn_onSuccess(MapconnPtr conn, MapimageCallback callback, Pointer context); + void flib_mapconn_onFailure(MapconnPtr conn, StrCallback callback, Pointer context); + void flib_mapconn_tick(MapconnPtr conn); + + // model/map.h + public static final int MAPGEN_REGULAR = 0; + public static final int MAPGEN_MAZE = 1; + public static final int MAPGEN_DRAWN = 2; + public static final int MAPGEN_NAMED = 3; + + public static final int TEMPLATEFILTER_ALL = 0; + public static final int TEMPLATEFILTER_SMALL = 1; + public static final int TEMPLATEFILTER_MEDIUM = 2; + public static final int TEMPLATEFILTER_LARGE = 3; + public static final int TEMPLATEFILTER_CAVERN = 4; + public static final int TEMPLATEFILTER_WACKY = 5; + + public static final int MAZE_SIZE_SMALL_TUNNELS = 0; + public static final int MAZE_SIZE_MEDIUM_TUNNELS = 1; + public static final int MAZE_SIZE_LARGE_TUNNELS = 2; + public static final int MAZE_SIZE_SMALL_ISLANDS = 3; + public static final int MAZE_SIZE_MEDIUM_ISLANDS = 4; + public static final int MAZE_SIZE_LARGE_ISLANDS = 5; + + // model/schemelist.h + SchemelistPtr flib_schemelist_from_ini(String filename); + int flib_schemelist_to_ini(String filename, SchemelistPtr list); + void flib_schemelist_destroy(SchemelistPtr list); + + // model/team.h + TeamPtr flib_team_from_ini(String filename); + int flib_team_to_ini(String filename, TeamPtr team); + void flib_team_destroy(TeamPtr team); + + // model/weapon.h + WeaponsetListPtr flib_weaponsetlist_from_ini(String filename); + int flib_weaponsetlist_to_ini(String filename, WeaponsetListPtr weaponsets); + void flib_weaponsetlist_destroy(WeaponsetListPtr list); + + // model/gamesetup.h + void flib_gamesetup_destroy(GameSetupPtr gamesetup); + + // util/logging.h + public static final int FLIB_LOGLEVEL_ALL = -100; + public static final int FLIB_LOGLEVEL_DEBUG = -1; + public static final int FLIB_LOGLEVEL_INFO = 0; + public static final int FLIB_LOGLEVEL_WARNING = 1; + public static final int FLIB_LOGLEVEL_ERROR = 2; + public static final int FLIB_LOGLEVEL_NONE = 100; + + void flib_log_setLevel(int level); + void flib_log_setCallback(LogCallback callback); } \ No newline at end of file diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/frontlib/NativeSizeT.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/frontlib/NativeSizeT.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/frontlib/NativeSizeT.java Tue Jan 21 22:43:06 2014 +0100 @@ -22,37 +22,37 @@ /** * This class represents the native C type size_t. On Android, this type could be mapped with int, * but we use a separate type to make it easier to adapt for other platforms if anyone wants to use - * the mappings elsewhere. + * the mappings elsewhere. */ public final class NativeSizeT extends Number { - private static final long serialVersionUID = 1L; - private final long value; - - private NativeSizeT(long value) { - this.value = value; - } - - public static NativeSizeT valueOf(long l) { - return new NativeSizeT(l); - } - - @Override - public int intValue() { - return (int)value; - } - - @Override - public long longValue() { - return value; - } + private static final long serialVersionUID = 1L; + private final long value; + + private NativeSizeT(long value) { + this.value = value; + } + + public static NativeSizeT valueOf(long l) { + return new NativeSizeT(l); + } + + @Override + public int intValue() { + return (int)value; + } - @Override - public double doubleValue() { - return value; - } + @Override + public long longValue() { + return value; + } - @Override - public float floatValue() { - return value; - } + @Override + public double doubleValue() { + return value; + } + + @Override + public float floatValue() { + return value; + } } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/ClientFlagsUpdate.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/ClientFlagsUpdate.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/ClientFlagsUpdate.java Tue Jan 21 22:43:06 2014 +0100 @@ -4,45 +4,45 @@ import org.hedgewars.hedgeroid.Datastructures.PlayerInRoom; final class ClientFlagsUpdate { - public static final char FLAG_ADMIN = 'a'; - public static final char FLAG_CHIEF = 'h'; - public static final char FLAG_READY = 'r'; - public static final char FLAG_REGISTERED = 'u'; - - public final String nick, flags; - public final boolean newFlagState; - - public ClientFlagsUpdate(String nick, String flags, boolean newFlagState) { - this.nick = nick; - this.flags = flags; - this.newFlagState = newFlagState; - } + public static final char FLAG_ADMIN = 'a'; + public static final char FLAG_CHIEF = 'h'; + public static final char FLAG_READY = 'r'; + public static final char FLAG_REGISTERED = 'u'; + + public final String nick, flags; + public final boolean newFlagState; + + public ClientFlagsUpdate(String nick, String flags, boolean newFlagState) { + this.nick = nick; + this.flags = flags; + this.newFlagState = newFlagState; + } + + public Player applyTo(Player p) { + return new Player( + p.name, + updatedFlag(FLAG_REGISTERED, p.registered), + updatedFlag(FLAG_ADMIN, p.admin)); + } - public Player applyTo(Player p) { - return new Player( - p.name, - updatedFlag(FLAG_REGISTERED, p.registered), - updatedFlag(FLAG_ADMIN, p.admin)); - } - - public PlayerInRoom applyTo(PlayerInRoom p) { - return new PlayerInRoom( - this.applyTo(p.player), - updatedFlag(FLAG_READY, p.ready), - updatedFlag(FLAG_CHIEF, p.roomChief)); - } - - public boolean appliesTo(char flag) { - return flags.indexOf(flag) != -1; - } - - private boolean updatedFlag(char flag, boolean oldValue) { - return appliesTo(flag) ? newFlagState : oldValue; - } - - @Override - public String toString() { - return "ClientFlagsUpdate [nick=" + nick + ", flags=" + flags - + ", newFlagState=" + newFlagState + "]"; - } + public PlayerInRoom applyTo(PlayerInRoom p) { + return new PlayerInRoom( + this.applyTo(p.player), + updatedFlag(FLAG_READY, p.ready), + updatedFlag(FLAG_CHIEF, p.roomChief)); + } + + public boolean appliesTo(char flag) { + return flags.indexOf(flag) != -1; + } + + private boolean updatedFlag(char flag, boolean oldValue) { + return appliesTo(flag) ? newFlagState : oldValue; + } + + @Override + public String toString() { + return "ClientFlagsUpdate [nick=" + nick + ", flags=" + flags + + ", newFlagState=" + newFlagState + "]"; + } } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/GameMessageListener.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/GameMessageListener.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/GameMessageListener.java Tue Jan 21 22:43:06 2014 +0100 @@ -23,12 +23,12 @@ * Interface with several event callbacks that represent network messages which are interesting * for a running game, e.g. because they concern the lifecycle of the game or because they contain * data that needs to be passed on. - * + * * These functions might be called on any thread. */ public interface GameMessageListener { - void onChatMessage(String nick, String message); - void onEngineMessage(byte[] em); - void onMessage(int type, String message); - void onNetDisconnected(); + void onChatMessage(String nick, String message); + void onEngineMessage(byte[] em); + void onMessage(int type, String message); + void onNetDisconnected(); } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/MessageLog.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/MessageLog.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/MessageLog.java Tue Jan 21 22:43:06 2014 +0100 @@ -44,126 +44,126 @@ import android.util.Log; public class MessageLog { - private static final int BACKLOG_LINES = 200; - - private static final int INFO_COLOR = Color.GRAY; - private static final int PLAYERINFO_COLOR = Color.GREEN; - private static final int CHAT_COLOR = Color.GREEN; - private static final int MECHAT_COLOR = Color.CYAN; - private static final int WARN_COLOR = Color.RED; - private static final int ERROR_COLOR = Color.RED; - - private final Context context; - private List observers = new LinkedList(); - private List log = new LinkedList(); - - public MessageLog(Context context) { - this.context = context; - } - - private Spanned makeLogTime() { - String time = DateFormat.getTimeFormat(context).format(new Date()); - return withColor("[" + time + "] ", INFO_COLOR); - } - - private static Spanned span(CharSequence s, Object o) { - Spannable spannable = new SpannableString(s); - spannable.setSpan(o, 0, s.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - return spannable; - } - - private static Spanned withColor(CharSequence s, int color) { - return span(s, new ForegroundColorSpan(color)); - } - - private static Spanned bold(CharSequence s) { - return span(s, new StyleSpan(Typeface.BOLD)); - } - - private void append(CharSequence msg) { - SpannableStringBuilder ssb = new SpannableStringBuilder(); - ssb.append(makeLogTime()).append(msg); - appendRaw(ssb); - } - - private void appendRaw(CharSequence msg) { - if(log.size() > BACKLOG_LINES) { - log.remove(0); - for(Listener o : observers) { - o.lineRemoved(); - } - } - log.add(msg); - for(Listener o : observers) { - o.lineAdded(msg); - } - } - - void appendPlayerJoin(String playername) { - append(withColor("***" + context.getResources().getString(R.string.log_player_join, playername), INFO_COLOR)); - } - - void appendPlayerLeave(String playername, String partMsg) { - String msg = "***"; - if(partMsg != null) { - msg += context.getResources().getString(R.string.log_player_leave_with_msg, playername, partMsg); - } else { - msg += context.getResources().getString(R.string.log_player_leave, playername); - } - append(withColor(msg, INFO_COLOR)); - } - - void appendChat(String playerName, String msg) { - if(msg.startsWith("/me ")) { - append(withColor("*"+playerName+" "+msg.substring(4), MECHAT_COLOR)); - } else { - Spanned name = bold(playerName+": "); - Spanned fullMessage = withColor(TextUtils.concat(name, msg), CHAT_COLOR); - append(fullMessage); - } - } - - void appendMessage(int type, String msg) { - switch(type) { - case Frontlib.NETCONN_MSG_TYPE_ERROR: - append(withColor("***"+msg, ERROR_COLOR)); - break; - case Frontlib.NETCONN_MSG_TYPE_WARNING: - append(withColor("***"+msg, WARN_COLOR)); - break; - case Frontlib.NETCONN_MSG_TYPE_PLAYERINFO: - append(withColor(msg.replace("\n", " "), PLAYERINFO_COLOR)); - break; - case Frontlib.NETCONN_MSG_TYPE_SERVERMESSAGE: - appendRaw(span(TextUtils.concat("\n", Html.fromHtml(msg), "\n"), new RelativeSizeSpan(1.5f))); - break; - default: - Log.e("MessageLog", "Unknown messagetype "+type); - } - } - - void clear() { - for(Listener o : observers) { - o.clear(); - } - log.clear(); - } - - public void addListener(Listener o) { - observers.add(o); - } - - public void removeListener(Listener o) { - observers.remove(o); - } - - public static interface Listener { - void lineAdded(CharSequence text); - void lineRemoved(); - void clear(); - } + private static final int BACKLOG_LINES = 200; + + private static final int INFO_COLOR = Color.GRAY; + private static final int PLAYERINFO_COLOR = Color.GREEN; + private static final int CHAT_COLOR = Color.GREEN; + private static final int MECHAT_COLOR = Color.CYAN; + private static final int WARN_COLOR = Color.RED; + private static final int ERROR_COLOR = Color.RED; + + private final Context context; + private List observers = new LinkedList(); + private List log = new LinkedList(); + + public MessageLog(Context context) { + this.context = context; + } + + private Spanned makeLogTime() { + String time = DateFormat.getTimeFormat(context).format(new Date()); + return withColor("[" + time + "] ", INFO_COLOR); + } + + private static Spanned span(CharSequence s, Object o) { + Spannable spannable = new SpannableString(s); + spannable.setSpan(o, 0, s.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + return spannable; + } + + private static Spanned withColor(CharSequence s, int color) { + return span(s, new ForegroundColorSpan(color)); + } + + private static Spanned bold(CharSequence s) { + return span(s, new StyleSpan(Typeface.BOLD)); + } + + private void append(CharSequence msg) { + SpannableStringBuilder ssb = new SpannableStringBuilder(); + ssb.append(makeLogTime()).append(msg); + appendRaw(ssb); + } + + private void appendRaw(CharSequence msg) { + if(log.size() > BACKLOG_LINES) { + log.remove(0); + for(Listener o : observers) { + o.lineRemoved(); + } + } + log.add(msg); + for(Listener o : observers) { + o.lineAdded(msg); + } + } + + void appendPlayerJoin(String playername) { + append(withColor("***" + context.getResources().getString(R.string.log_player_join, playername), INFO_COLOR)); + } - public Collection getLog() { - return Collections.unmodifiableList(log); - } + void appendPlayerLeave(String playername, String partMsg) { + String msg = "***"; + if(partMsg != null) { + msg += context.getResources().getString(R.string.log_player_leave_with_msg, playername, partMsg); + } else { + msg += context.getResources().getString(R.string.log_player_leave, playername); + } + append(withColor(msg, INFO_COLOR)); + } + + void appendChat(String playerName, String msg) { + if(msg.startsWith("/me ")) { + append(withColor("*"+playerName+" "+msg.substring(4), MECHAT_COLOR)); + } else { + Spanned name = bold(playerName+": "); + Spanned fullMessage = withColor(TextUtils.concat(name, msg), CHAT_COLOR); + append(fullMessage); + } + } + + void appendMessage(int type, String msg) { + switch(type) { + case Frontlib.NETCONN_MSG_TYPE_ERROR: + append(withColor("***"+msg, ERROR_COLOR)); + break; + case Frontlib.NETCONN_MSG_TYPE_WARNING: + append(withColor("***"+msg, WARN_COLOR)); + break; + case Frontlib.NETCONN_MSG_TYPE_PLAYERINFO: + append(withColor(msg.replace("\n", " "), PLAYERINFO_COLOR)); + break; + case Frontlib.NETCONN_MSG_TYPE_SERVERMESSAGE: + appendRaw(span(TextUtils.concat("\n", Html.fromHtml(msg), "\n"), new RelativeSizeSpan(1.5f))); + break; + default: + Log.e("MessageLog", "Unknown messagetype "+type); + } + } + + void clear() { + for(Listener o : observers) { + o.clear(); + } + log.clear(); + } + + public void addListener(Listener o) { + observers.add(o); + } + + public void removeListener(Listener o) { + observers.remove(o); + } + + public static interface Listener { + void lineAdded(CharSequence text); + void lineRemoved(); + void clear(); + } + + public Collection getLog() { + return Collections.unmodifiableList(log); + } } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/NetRoomState.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/NetRoomState.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/NetRoomState.java Tue Jan 21 22:43:06 2014 +0100 @@ -41,145 +41,145 @@ * This class manages the room state in a network game. */ class NetRoomState extends BasicRoomState { - final Map requestedTeams = new TreeMap(); - private Netplay netplay; - - public NetRoomState(Netplay netplay) { - this.netplay = netplay; - initRoomState(false); - } + final Map requestedTeams = new TreeMap(); + private Netplay netplay; + + public NetRoomState(Netplay netplay) { + this.netplay = netplay; + initRoomState(false); + } + + public void changeWeaponset(Weaponset weaponset) { + if(getChiefStatus() && !equal(weaponset, getWeaponset())) { + sendToNet(MSG_SEND_WEAPONSET, weaponset); + setWeaponset(weaponset); + } + } + + public void changeMapRecipe(MapRecipe mapRecipe) { + if(getChiefStatus() && !equal(mapRecipe, getMapRecipe())) { + sendToNet(MSG_SEND_MAP, mapRecipe); + setMapRecipe(mapRecipe); + } + } + + public void changeMapNameAndGenerator(String mapName) { + if(getChiefStatus() && !equal(mapName, getMapRecipe().name)) { + int newGenerator = MapRecipe.generatorForMapname(mapName); + if(newGenerator != getMapRecipe().mapgen) { + sendToNet(MSG_SEND_MAP_GENERATOR, newGenerator, null); + } + sendToNet(MSG_SEND_MAP_NAME, mapName); + setMapRecipe(getMapRecipe().withName(mapName).withMapgen(newGenerator)); + } + } + + public void changeMapTemplate(int template) { + if(getChiefStatus() && template != getMapRecipe().templateFilter) { + sendToNet(MSG_SEND_MAP_TEMPLATE, template, null); + setMapRecipe(getMapRecipe().withTemplateFilter(template)); + } + } + + public void changeMazeSize(int mazeSize) { + if(getChiefStatus() && mazeSize != getMapRecipe().mazeSize) { + sendToNet(MSG_SEND_MAZE_SIZE, mazeSize, 0); + setMapRecipe(getMapRecipe().withMazeSize(mazeSize)); + } + } + + public void changeMapSeed(String seed) { + if(getChiefStatus() && !equal(seed, getMapRecipe().seed)) { + sendToNet(MSG_SEND_MAP_SEED, seed); + setMapRecipe(getMapRecipe().withSeed(seed)); + } + } + + public void changeMapTheme(String theme) { + if(getChiefStatus() && !equal(theme, getMapRecipe().theme)) { + sendToNet(MSG_SEND_MAP_THEME, theme); + setMapRecipe(getMapRecipe().withTheme(theme)); + } + } + + public void changeMapDrawdata(byte[] drawdata) { + if(getChiefStatus() && !Arrays.equals(drawdata, getMapRecipe().getDrawData())) { + sendToNet(MSG_SEND_MAP_DRAWDATA, drawdata); + setMapRecipe(getMapRecipe().withDrawData(drawdata)); + } + } - public void changeWeaponset(Weaponset weaponset) { - if(getChiefStatus() && !equal(weaponset, getWeaponset())) { - sendToNet(MSG_SEND_WEAPONSET, weaponset); - setWeaponset(weaponset); - } - } - - public void changeMapRecipe(MapRecipe mapRecipe) { - if(getChiefStatus() && !equal(mapRecipe, getMapRecipe())) { - sendToNet(MSG_SEND_MAP, mapRecipe); - setMapRecipe(mapRecipe); - } - } - - public void changeMapNameAndGenerator(String mapName) { - if(getChiefStatus() && !equal(mapName, getMapRecipe().name)) { - int newGenerator = MapRecipe.generatorForMapname(mapName); - if(newGenerator != getMapRecipe().mapgen) { - sendToNet(MSG_SEND_MAP_GENERATOR, newGenerator, null); - } - sendToNet(MSG_SEND_MAP_NAME, mapName); - setMapRecipe(getMapRecipe().withName(mapName).withMapgen(newGenerator)); - } - } - - public void changeMapTemplate(int template) { - if(getChiefStatus() && template != getMapRecipe().templateFilter) { - sendToNet(MSG_SEND_MAP_TEMPLATE, template, null); - setMapRecipe(getMapRecipe().withTemplateFilter(template)); - } - } - - public void changeMazeSize(int mazeSize) { - if(getChiefStatus() && mazeSize != getMapRecipe().mazeSize) { - sendToNet(MSG_SEND_MAZE_SIZE, mazeSize, 0); - setMapRecipe(getMapRecipe().withMazeSize(mazeSize)); - } - } - - public void changeMapSeed(String seed) { - if(getChiefStatus() && !equal(seed, getMapRecipe().seed)) { - sendToNet(MSG_SEND_MAP_SEED, seed); - setMapRecipe(getMapRecipe().withSeed(seed)); - } - } - - public void changeMapTheme(String theme) { - if(getChiefStatus() && !equal(theme, getMapRecipe().theme)) { - sendToNet(MSG_SEND_MAP_THEME, theme); - setMapRecipe(getMapRecipe().withTheme(theme)); - } - } - - public void changeMapDrawdata(byte[] drawdata) { - if(getChiefStatus() && !Arrays.equals(drawdata, getMapRecipe().getDrawData())) { - sendToNet(MSG_SEND_MAP_DRAWDATA, drawdata); - setMapRecipe(getMapRecipe().withDrawData(drawdata)); - } - } - - public void changeGameStyle(String gameStyle) { - if(getChiefStatus() && !equal(gameStyle, getGameStyle())) { - sendToNet(MSG_SEND_GAMESTYLE, gameStyle); - setGameStyle(gameStyle); - } - } - - public void changeScheme(Scheme scheme) { - if(getChiefStatus() && !equal(scheme, getScheme())) { - sendToNet(MSG_SEND_SCHEME, scheme); - setScheme(scheme); - } - } - - void initRoomState(boolean chief) { - setTeams(Collections.emptyMap()); - requestedTeams.clear(); - - setChief(chief); - setGameStyle(GameConfig.DEFAULT_STYLE); - setMapRecipe(MapRecipe.makeRandomMap(0, "seed", GameConfig.DEFAULT_THEME)); - setScheme(netplay.defaultScheme); - setWeaponset(netplay.defaultWeaponset); - sendFullConfig(); - } - - void sendFullConfig() { - if(getChiefStatus()) { - sendToNet(MSG_SEND_GAMESTYLE, getGameStyle()); - sendToNet(MSG_SEND_SCHEME, getScheme()); - sendToNet(MSG_SEND_WEAPONSET, getWeaponset()); - sendToNet(MSG_SEND_MAP, getMapRecipe()); - } - } - - private boolean sendToNet(ToNetMsgType what, Object obj) { - return netplay.sendToNet(what, 0, obj); - } - - private boolean sendToNet(ToNetMsgType what, int arg1, Object obj) { - return netplay.sendToNet(what, arg1, obj); - } + public void changeGameStyle(String gameStyle) { + if(getChiefStatus() && !equal(gameStyle, getGameStyle())) { + sendToNet(MSG_SEND_GAMESTYLE, gameStyle); + setGameStyle(gameStyle); + } + } + + public void changeScheme(Scheme scheme) { + if(getChiefStatus() && !equal(scheme, getScheme())) { + sendToNet(MSG_SEND_SCHEME, scheme); + setScheme(scheme); + } + } + + void initRoomState(boolean chief) { + setTeams(Collections.emptyMap()); + requestedTeams.clear(); + + setChief(chief); + setGameStyle(GameConfig.DEFAULT_STYLE); + setMapRecipe(MapRecipe.makeRandomMap(0, "seed", GameConfig.DEFAULT_THEME)); + setScheme(netplay.defaultScheme); + setWeaponset(netplay.defaultWeaponset); + sendFullConfig(); + } + + void sendFullConfig() { + if(getChiefStatus()) { + sendToNet(MSG_SEND_GAMESTYLE, getGameStyle()); + sendToNet(MSG_SEND_SCHEME, getScheme()); + sendToNet(MSG_SEND_WEAPONSET, getWeaponset()); + sendToNet(MSG_SEND_MAP, getMapRecipe()); + } + } - public void requestAddTeam(Team team, int colorIndex) { - TeamIngameAttributes tia = new TeamIngameAttributes(netplay.getPlayerName(), colorIndex, TeamIngameAttributes.DEFAULT_HOG_COUNT, false); - TeamInGame newTeamInGame = new TeamInGame(team, tia); - requestedTeams.put(team.name, newTeamInGame); - sendToNet(MSG_SEND_ADD_TEAM, newTeamInGame); - } + private boolean sendToNet(ToNetMsgType what, Object obj) { + return netplay.sendToNet(what, 0, obj); + } + + private boolean sendToNet(ToNetMsgType what, int arg1, Object obj) { + return netplay.sendToNet(what, arg1, obj); + } - public void requestRemoveTeam(String teamname) { - sendToNet(MSG_SEND_REMOVE_TEAM, teamname); - } + public void requestAddTeam(Team team, int colorIndex) { + TeamIngameAttributes tia = new TeamIngameAttributes(netplay.getPlayerName(), colorIndex, TeamIngameAttributes.DEFAULT_HOG_COUNT, false); + TeamInGame newTeamInGame = new TeamInGame(team, tia); + requestedTeams.put(team.name, newTeamInGame); + sendToNet(MSG_SEND_ADD_TEAM, newTeamInGame); + } + + public void requestRemoveTeam(String teamname) { + sendToNet(MSG_SEND_REMOVE_TEAM, teamname); + } - public void changeTeamColorIndex(String teamname, int colorIndex) { - if(getChiefStatus()) { - TeamInGame team = getTeams().get(teamname); - if(team.ingameAttribs.colorIndex != colorIndex) { - sendToNet(MSG_SEND_TEAM_COLOR_INDEX, colorIndex, teamname); - putTeam(team.withAttribs(team.ingameAttribs.withColorIndex(colorIndex))); - } - } - } + public void changeTeamColorIndex(String teamname, int colorIndex) { + if(getChiefStatus()) { + TeamInGame team = getTeams().get(teamname); + if(team.ingameAttribs.colorIndex != colorIndex) { + sendToNet(MSG_SEND_TEAM_COLOR_INDEX, colorIndex, teamname); + putTeam(team.withAttribs(team.ingameAttribs.withColorIndex(colorIndex))); + } + } + } - public void changeTeamHogCount(String teamname, int hogcount) { - if(getChiefStatus()) { - TeamInGame team = getTeams().get(teamname); - if(team.ingameAttribs.hogCount != hogcount) { - sendToNet(MSG_SEND_TEAM_HOG_COUNT, hogcount, teamname); - putTeam(team.withAttribs(team.ingameAttribs.withHogCount(hogcount))); - } - } - } + public void changeTeamHogCount(String teamname, int hogcount) { + if(getChiefStatus()) { + TeamInGame team = getTeams().get(teamname); + if(team.ingameAttribs.hogCount != hogcount) { + sendToNet(MSG_SEND_TEAM_HOG_COUNT, hogcount, teamname); + putTeam(team.withAttribs(team.ingameAttribs.withHogCount(hogcount))); + } + } + } } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/Netplay.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/Netplay.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/Netplay.java Tue Jan 21 22:43:06 2014 +0100 @@ -1,535 +1,535 @@ -/* - * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -package org.hedgewars.hedgeroid.netplay; - -import static org.hedgewars.hedgeroid.netplay.ThreadedNetConnection.ToNetMsgType.*; - -import java.io.IOException; -import java.util.Arrays; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; - -import org.hedgewars.hedgeroid.RoomStateManager; -import org.hedgewars.hedgeroid.Datastructures.GameConfig; -import org.hedgewars.hedgeroid.Datastructures.MapRecipe; -import org.hedgewars.hedgeroid.Datastructures.Player; -import org.hedgewars.hedgeroid.Datastructures.PlayerInRoom; -import org.hedgewars.hedgeroid.Datastructures.Room; -import org.hedgewars.hedgeroid.Datastructures.Scheme; -import org.hedgewars.hedgeroid.Datastructures.Schemes; -import org.hedgewars.hedgeroid.Datastructures.TeamInGame; -import org.hedgewars.hedgeroid.Datastructures.TeamIngameAttributes; -import org.hedgewars.hedgeroid.Datastructures.Weaponset; -import org.hedgewars.hedgeroid.Datastructures.Weaponsets; -import org.hedgewars.hedgeroid.netplay.ThreadedNetConnection.ToNetMsgType; -import org.hedgewars.hedgeroid.util.ObservableTreeMap; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.content.Intent; -import android.os.Handler; -import android.os.Looper; -import android.os.Message; -import android.support.v4.content.LocalBroadcastManager; -import android.util.Log; -import android.util.Pair; - - -/** - * This class manages the application's networking state. - */ -public class Netplay { - public static enum State { NOT_CONNECTED, CONNECTING, LOBBY, ROOM } - - // Extras in broadcasts - public static final String EXTRA_PLAYERNAME = "playerName"; - public static final String EXTRA_MESSAGE = "message"; - public static final String EXTRA_HAS_ERROR = "hasError"; - public static final String EXTRA_REASON = "reason"; - - private static final String ACTIONPREFIX = "org.hedgewars.hedgeroid.netconn."; - public static final String ACTION_DISCONNECTED = ACTIONPREFIX+"DISCONNECTED"; - public static final String ACTION_CONNECTED = ACTIONPREFIX+"CONNECTED"; - public static final String ACTION_PASSWORD_REQUESTED = ACTIONPREFIX+"PASSWORD_REQUESTED"; - public static final String ACTION_ENTERED_ROOM_FROM_LOBBY = ACTIONPREFIX+"ENTERED_ROOM"; - public static final String ACTION_LEFT_ROOM = ACTIONPREFIX+"LEFT_ROOM"; - public static final String ACTION_STATE_CHANGED = ACTIONPREFIX+"STATE_CHANGED"; - - public static final String DEFAULT_SERVER = "netserver.hedgewars.org"; - public static final int DEFAULT_PORT = 46631; - - private final Context appContext; - private final LocalBroadcastManager broadcastManager; - private final FromNetHandler fromNetHandler = new FromNetHandler(); - public final Scheme defaultScheme; - public final Weaponset defaultWeaponset; - - private State state = State.NOT_CONNECTED; - private String playerName; - - // null or stale if not in room state - private final NetRoomState netRoomState = new NetRoomState(this); - - // null if there is no running connection (==state is NOT_CONNECTED) - private ThreadedNetConnection connection; - - public final ObservableTreeMap lobbyPlayerlist = new ObservableTreeMap(); - public final ObservableTreeMap roomPlayerlist = new ObservableTreeMap(); - public final Roomlist roomList = new Roomlist(); - public final MessageLog lobbyChatlog; - public final MessageLog roomChatlog; - - private final List gameMessageListeners = new LinkedList(); - private final List runGameListeners = new LinkedList(); - - public Netplay(Context appContext, Scheme defaultScheme, Weaponset defaultWeaponset) { - this.appContext = appContext; - broadcastManager = LocalBroadcastManager.getInstance(appContext); - lobbyChatlog = new MessageLog(appContext); - roomChatlog = new MessageLog(appContext); - this.defaultScheme = defaultScheme; - this.defaultWeaponset = defaultWeaponset; - } - - public RoomStateManager getRoomStateManager() { - return netRoomState; - } - - private void clearLobbyState() { - lobbyPlayerlist.clear(); - roomList.clear(); - lobbyChatlog.clear(); - } - - private void initRoomState(boolean chief) { - roomChatlog.clear(); - roomPlayerlist.clear(); - netRoomState.initRoomState(chief); - } - - public void registerGameMessageListener(GameMessageListener listener) { - gameMessageListeners.add(listener); - } - - public void unregisterGameMessageListener(GameMessageListener listener) { - gameMessageListeners.remove(listener); - } - - public void registerRunGameListener(RunGameListener listener) { - runGameListeners.add(listener); - } - - public void unregisterRunGameListener(RunGameListener listener) { - runGameListeners.remove(listener); - } - - public void connectToDefaultServer(String playerName) { - connect(playerName, DEFAULT_SERVER, DEFAULT_PORT); - } - - /** - * Establish a new connection. Only call if the current state is NOT_CONNECTED. - * - * The state will switch to CONNECTING immediately. After that, it can asynchronously change to any other state. - * State changes are indicated by broadcasts. In particular, if an error occurs while trying to connect, the state - * will change back to NOT_CONNECTED and an ACTION_DISCONNECTED broadcast is sent. - */ - public void connect(String name, String host, int port) { - playerName = name; - if(state != State.NOT_CONNECTED) { - throw new IllegalStateException("Attempt to start a new connection while the old one was still running."); - } - - clearLobbyState(); - changeState(State.CONNECTING); - connection = ThreadedNetConnection.startConnection(appContext, fromNetHandler, name, host, port); - connection.setFastTickRate(true); - } - - public void sendNick(String nick) { - playerName = nick; - sendToNet(MSG_SEND_NICK, nick); - } - public void sendPassword(String password) { sendToNet(MSG_SEND_PASSWORD, password); } - public void sendQuit(String message) { sendToNet(MSG_SEND_QUIT, message); } - public void sendRoomlistRequest() { sendToNet(MSG_SEND_ROOMLIST_REQUEST); } - public void sendPlayerInfoQuery(String name) { sendToNet(MSG_SEND_PLAYER_INFO_REQUEST, name); } - public void sendChat(String s) { sendToNet(MSG_SEND_CHAT, s); } - public void sendTeamChat(String s) { sendToNet(MSG_SEND_TEAMCHAT, s); } - public void sendFollowPlayer(String nick) { sendToNet(MSG_SEND_FOLLOW_PLAYER, nick); } - public void sendJoinRoom(String name) { sendToNet(MSG_SEND_JOIN_ROOM, name); } - public void sendCreateRoom(String name) { sendToNet(MSG_SEND_CREATE_ROOM, name); } - public void sendLeaveRoom(String message) { sendToNet(MSG_SEND_LEAVE_ROOM, message); } - public void sendKick(String player) { sendToNet(MSG_SEND_KICK, player); } - public void sendEngineMessage(byte[] engineMessage) { sendToNet(MSG_SEND_ENGINE_MESSAGE, engineMessage); } - public void sendRoundFinished(boolean withoutError) { sendToNet(MSG_SEND_ROUND_FINISHED, Boolean.valueOf(withoutError)); } - public void sendToggleReady() { sendToNet(MSG_SEND_TOGGLE_READY); } - public void sendStartGame() { sendToNet(MSG_SEND_START_GAME); } - - public void disconnect() { sendToNet(MSG_DISCONNECT, "User Quit"); } - - private static Netplay instance; - - /** - * Retrieve the single app-wide instance of the netplay interface, creating it if it - * does not exist yet. - * - * @param applicationContext - * @return - */ - public static Netplay getAppInstance(Context applicationContext) { - if(instance == null) { - // We will need some default values for rooms, best load them here - Scheme defaultScheme = null; - Weaponset defaultWeaponset = null; - try { - List schemes = Schemes.loadBuiltinSchemes(applicationContext); - for(Scheme scheme : schemes) { - if(scheme.name.equals(GameConfig.DEFAULT_SCHEME)) { - defaultScheme = scheme; - } - } - List weaponsets = Weaponsets.loadBuiltinWeaponsets(applicationContext); - for(Weaponset weaponset : weaponsets) { - if(weaponset.name.equals(GameConfig.DEFAULT_WEAPONSET)) { - defaultWeaponset = weaponset; - } - } - } catch(IOException e) { - throw new RuntimeException(e); - } - - if(defaultScheme==null || defaultWeaponset==null) { - throw new RuntimeException("Unable to load default scheme or weaponset"); - } - - instance = new Netplay(applicationContext, defaultScheme, defaultWeaponset); - } - return instance; - } - - public State getState() { - return state; - } - - private void changeState(State newState) { - if(newState != state) { - state = newState; - broadcastManager.sendBroadcastSync(new Intent(ACTION_STATE_CHANGED)); - } - } - - public boolean isChief() { - if(netRoomState != null) { - return netRoomState.getChiefStatus(); - } else { - return false; - } - } - - public String getPlayerName() { - return playerName; - } - - boolean sendToNet(ToNetMsgType what) { - return sendToNet(what, 0, null); - } - - boolean sendToNet(ToNetMsgType what, Object obj) { - return sendToNet(what, 0, obj); - } - - boolean sendToNet(ToNetMsgType what, int arg1, Object obj) { - if(connection != null) { - Handler handler = connection.toNetHandler; - return handler.sendMessage(handler.obtainMessage(what.ordinal(), arg1, 0, obj)); - } else { - return false; - } - } - - private MessageLog getCurrentLog() { - if(state == State.ROOM) { - return roomChatlog; - } else { - return lobbyChatlog; - } - } - - public static enum FromNetMsgType { - MSG_LOBBY_JOIN, - MSG_LOBBY_LEAVE, - MSG_ROOM_JOIN, - MSG_ROOM_LEAVE, - MSG_CLIENT_FLAGS, - MSG_CHAT, - MSG_MESSAGE, - MSG_ROOM_ADD, - MSG_ROOM_UPDATE, - MSG_ROOM_DELETE, - MSG_ROOMLIST, - MSG_CONNECTED, - MSG_DISCONNECTED, - MSG_PASSWORD_REQUEST, - MSG_ENTER_ROOM_FROM_LOBBY, - MSG_LEAVE_ROOM, - MSG_TEAM_ADDED, - MSG_TEAM_DELETED, - MSG_TEAM_ACCEPTED, - MSG_TEAM_COLOR_CHANGED, - MSG_HOG_COUNT_CHANGED, - MSG_ENGINE_MESSAGE, - MSG_RUN_GAME, - MSG_SCHEME_CHANGED, - MSG_MAP_CHANGED, - MSG_SCRIPT_CHANGED, - MSG_WEAPONSET_CHANGED; - - static final List values = Collections.unmodifiableList(Arrays.asList(FromNetMsgType.values())); - } - - /** - * Processes messages from the networking system. Always runs on the main thread. - */ - @SuppressLint("HandlerLeak") - final class FromNetHandler extends Handler { - public FromNetHandler() { - super(Looper.getMainLooper()); - } - - @SuppressWarnings("unchecked") - @Override - public void handleMessage(Message msg) { - switch(FromNetMsgType.values.get(msg.what)) { - case MSG_LOBBY_JOIN: { - String name = (String)msg.obj; - lobbyPlayerlist.put(name, new Player(name, false, false)); - lobbyChatlog.appendPlayerJoin(name); - break; - } - case MSG_LOBBY_LEAVE: { - Pair args = (Pair)msg.obj; - lobbyPlayerlist.remove(args.first); - lobbyChatlog.appendPlayerLeave(args.first, args.second); - break; - } - case MSG_ROOM_JOIN: { - String name = (String)msg.obj; - Player p = lobbyPlayerlist.get(name); - if(p==null) { - Log.w("Netplay", "Unknown player joined room: "+name); - p = new Player(name, false, false); - } - roomPlayerlist.put(name, new PlayerInRoom(p, false, false)); - roomChatlog.appendPlayerJoin(name); - break; - } - case MSG_ROOM_LEAVE: { - Pair args = (Pair)msg.obj; - roomPlayerlist.remove(args.first); - roomChatlog.appendPlayerLeave(args.first, args.second); - break; - } - case MSG_CLIENT_FLAGS: { - ClientFlagsUpdate upd = (ClientFlagsUpdate)msg.obj; - PlayerInRoom pir = roomPlayerlist.get(upd.nick); - if(pir != null) { - roomPlayerlist.put(upd.nick, upd.applyTo(pir)); - } - Player p = lobbyPlayerlist.get(upd.nick); - if(p != null) { - lobbyPlayerlist.put(upd.nick, upd.applyTo(p)); - } else { - Log.w("Netplay", "Received client flags for unknown player "+upd.nick); - } - if(playerName.equals(upd.nick) && upd.appliesTo(ClientFlagsUpdate.FLAG_CHIEF)) { - netRoomState.setChief(upd.newFlagState); - } - break; - } - case MSG_CHAT: { - Pair args = (Pair)msg.obj; - getCurrentLog().appendChat(args.first, args.second); - for(GameMessageListener listener : gameMessageListeners) { - listener.onChatMessage(args.first, args.second); - } - break; - } - case MSG_MESSAGE: { - getCurrentLog().appendMessage(msg.arg1, (String)msg.obj); - for(GameMessageListener listener : gameMessageListeners) { - listener.onMessage(1, (String)msg.obj); - } - break; - } - case MSG_ROOM_ADD: { - Room room = (Room)msg.obj; - roomList.addRoomWithNewId(room); - break; - } - case MSG_ROOM_UPDATE: { - Pair args = (Pair)msg.obj; - roomList.updateRoom(args.first, args.second); - break; - } - case MSG_ROOM_DELETE: { - roomList.remove((String)msg.obj); - break; - } - case MSG_ROOMLIST: { - Room[] rooms = (Room[])msg.obj; - roomList.updateList(rooms); - break; - } - case MSG_CONNECTED: { - playerName = (String)msg.obj; - changeState(State.LOBBY); - broadcastManager.sendBroadcast(new Intent(ACTION_CONNECTED)); - break; - } - case MSG_DISCONNECTED: { - Pair args = (Pair)msg.obj; - for(GameMessageListener listener : gameMessageListeners) { - listener.onNetDisconnected(); - } - changeState(State.NOT_CONNECTED); - connection = null; - Intent intent = new Intent(ACTION_DISCONNECTED); - intent.putExtra(EXTRA_HAS_ERROR, args.first); - intent.putExtra(EXTRA_MESSAGE, args.second); - broadcastManager.sendBroadcastSync(intent); - break; - } - case MSG_PASSWORD_REQUEST: { - Intent intent = new Intent(ACTION_PASSWORD_REQUESTED); - intent.putExtra(EXTRA_PLAYERNAME, (String)msg.obj); - broadcastManager.sendBroadcast(intent); - break; - } - case MSG_ENTER_ROOM_FROM_LOBBY: { - initRoomState((Boolean)msg.obj); - changeState(State.ROOM); - Intent intent = new Intent(ACTION_ENTERED_ROOM_FROM_LOBBY); - broadcastManager.sendBroadcastSync(intent); - break; - } - case MSG_LEAVE_ROOM: { - changeState(State.LOBBY); - Intent intent = new Intent(ACTION_LEFT_ROOM); - intent.putExtra(EXTRA_MESSAGE, (String)msg.obj); - intent.putExtra(EXTRA_REASON, msg.arg1); - broadcastManager.sendBroadcastSync(intent); - break; - } - case MSG_TEAM_ADDED: { - TeamInGame newTeam = (TeamInGame)msg.obj; - if(isChief()) { - int freeColor = TeamInGame.getUnusedOrRandomColorIndex(netRoomState.getTeams().values()); - sendToNet(MSG_SEND_TEAM_HOG_COUNT, newTeam.ingameAttribs.hogCount, newTeam.team.name); - sendToNet(MSG_SEND_TEAM_COLOR_INDEX, freeColor, newTeam.team.name); - newTeam = newTeam.withAttribs(newTeam.ingameAttribs.withColorIndex(freeColor)); - } - netRoomState.putTeam(newTeam); - break; - } - case MSG_TEAM_DELETED: { - netRoomState.removeTeam((String)msg.obj); - break; - } - case MSG_TEAM_ACCEPTED: { - TeamInGame requestedTeam = netRoomState.requestedTeams.remove(msg.obj); - if(requestedTeam!=null) { - netRoomState.putTeam(requestedTeam); - if(isChief()) { - // Not strictly necessary, but QtFrontend does it... - sendToNet(MSG_SEND_TEAM_HOG_COUNT, requestedTeam.ingameAttribs.hogCount, requestedTeam.team.name); - } - } else { - Log.e("Netplay", "Got accepted message for team that was never requested."); - } - break; - } - case MSG_TEAM_COLOR_CHANGED: { - TeamInGame oldEntry = netRoomState.getTeams().get((String)msg.obj); - if(oldEntry != null) { - /* - * If we are chief, we ignore colors from the outside. They only come from the server - * when someone adds a team then, and we override that choice anyway. - * Worse, that color message arrives *after* we have overridden the color, so it would - * re-override it right back. - */ - if(!isChief()) { - TeamIngameAttributes newAttribs = oldEntry.ingameAttribs.withColorIndex(msg.arg1); - netRoomState.putTeam(oldEntry.withAttribs(newAttribs)); - } - } else { - Log.e("Netplay", "Color update for unknown team "+msg.obj); - } - break; - } - case MSG_HOG_COUNT_CHANGED: { - TeamInGame oldEntry = netRoomState.getTeams().get((String)msg.obj); - if(oldEntry != null) { - TeamIngameAttributes newAttribs = oldEntry.ingameAttribs.withHogCount(msg.arg1); - netRoomState.putTeam(oldEntry.withAttribs(newAttribs)); - } else { - Log.e("Netplay", "Hog count update for unknown team "+msg.obj); - } - break; - } - case MSG_ENGINE_MESSAGE: { - byte[] em = (byte[])msg.obj; - for(GameMessageListener listener : gameMessageListeners) { - listener.onEngineMessage(em); - } - break; - } - case MSG_RUN_GAME: { - GameConfig config = (GameConfig)msg.obj; - for(RunGameListener listener : runGameListeners) { - listener.runGame(config); - } - break; - } - case MSG_MAP_CHANGED: { - netRoomState.setMapRecipe((MapRecipe)msg.obj); - break; - } - case MSG_SCHEME_CHANGED: { - netRoomState.setScheme((Scheme)msg.obj); - break; - } - case MSG_SCRIPT_CHANGED: { - netRoomState.setGameStyle((String)msg.obj); - break; - } - case MSG_WEAPONSET_CHANGED: { - netRoomState.setWeaponset((Weaponset)msg.obj); - break; - } - default: { - Log.e("FromNetHandler", "Unknown message type: "+msg.what); - break; - } - } - } - } -} +/* + * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package org.hedgewars.hedgeroid.netplay; + +import static org.hedgewars.hedgeroid.netplay.ThreadedNetConnection.ToNetMsgType.*; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +import org.hedgewars.hedgeroid.RoomStateManager; +import org.hedgewars.hedgeroid.Datastructures.GameConfig; +import org.hedgewars.hedgeroid.Datastructures.MapRecipe; +import org.hedgewars.hedgeroid.Datastructures.Player; +import org.hedgewars.hedgeroid.Datastructures.PlayerInRoom; +import org.hedgewars.hedgeroid.Datastructures.Room; +import org.hedgewars.hedgeroid.Datastructures.Scheme; +import org.hedgewars.hedgeroid.Datastructures.Schemes; +import org.hedgewars.hedgeroid.Datastructures.TeamInGame; +import org.hedgewars.hedgeroid.Datastructures.TeamIngameAttributes; +import org.hedgewars.hedgeroid.Datastructures.Weaponset; +import org.hedgewars.hedgeroid.Datastructures.Weaponsets; +import org.hedgewars.hedgeroid.netplay.ThreadedNetConnection.ToNetMsgType; +import org.hedgewars.hedgeroid.util.ObservableTreeMap; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.support.v4.content.LocalBroadcastManager; +import android.util.Log; +import android.util.Pair; + + +/** + * This class manages the application's networking state. + */ +public class Netplay { + public static enum State { NOT_CONNECTED, CONNECTING, LOBBY, ROOM } + + // Extras in broadcasts + public static final String EXTRA_PLAYERNAME = "playerName"; + public static final String EXTRA_MESSAGE = "message"; + public static final String EXTRA_HAS_ERROR = "hasError"; + public static final String EXTRA_REASON = "reason"; + + private static final String ACTIONPREFIX = "org.hedgewars.hedgeroid.netconn."; + public static final String ACTION_DISCONNECTED = ACTIONPREFIX+"DISCONNECTED"; + public static final String ACTION_CONNECTED = ACTIONPREFIX+"CONNECTED"; + public static final String ACTION_PASSWORD_REQUESTED = ACTIONPREFIX+"PASSWORD_REQUESTED"; + public static final String ACTION_ENTERED_ROOM_FROM_LOBBY = ACTIONPREFIX+"ENTERED_ROOM"; + public static final String ACTION_LEFT_ROOM = ACTIONPREFIX+"LEFT_ROOM"; + public static final String ACTION_STATE_CHANGED = ACTIONPREFIX+"STATE_CHANGED"; + + public static final String DEFAULT_SERVER = "netserver.hedgewars.org"; + public static final int DEFAULT_PORT = 46631; + + private final Context appContext; + private final LocalBroadcastManager broadcastManager; + private final FromNetHandler fromNetHandler = new FromNetHandler(); + public final Scheme defaultScheme; + public final Weaponset defaultWeaponset; + + private State state = State.NOT_CONNECTED; + private String playerName; + + // null or stale if not in room state + private final NetRoomState netRoomState = new NetRoomState(this); + + // null if there is no running connection (==state is NOT_CONNECTED) + private ThreadedNetConnection connection; + + public final ObservableTreeMap lobbyPlayerlist = new ObservableTreeMap(); + public final ObservableTreeMap roomPlayerlist = new ObservableTreeMap(); + public final Roomlist roomList = new Roomlist(); + public final MessageLog lobbyChatlog; + public final MessageLog roomChatlog; + + private final List gameMessageListeners = new LinkedList(); + private final List runGameListeners = new LinkedList(); + + public Netplay(Context appContext, Scheme defaultScheme, Weaponset defaultWeaponset) { + this.appContext = appContext; + broadcastManager = LocalBroadcastManager.getInstance(appContext); + lobbyChatlog = new MessageLog(appContext); + roomChatlog = new MessageLog(appContext); + this.defaultScheme = defaultScheme; + this.defaultWeaponset = defaultWeaponset; + } + + public RoomStateManager getRoomStateManager() { + return netRoomState; + } + + private void clearLobbyState() { + lobbyPlayerlist.clear(); + roomList.clear(); + lobbyChatlog.clear(); + } + + private void initRoomState(boolean chief) { + roomChatlog.clear(); + roomPlayerlist.clear(); + netRoomState.initRoomState(chief); + } + + public void registerGameMessageListener(GameMessageListener listener) { + gameMessageListeners.add(listener); + } + + public void unregisterGameMessageListener(GameMessageListener listener) { + gameMessageListeners.remove(listener); + } + + public void registerRunGameListener(RunGameListener listener) { + runGameListeners.add(listener); + } + + public void unregisterRunGameListener(RunGameListener listener) { + runGameListeners.remove(listener); + } + + public void connectToDefaultServer(String playerName) { + connect(playerName, DEFAULT_SERVER, DEFAULT_PORT); + } + + /** + * Establish a new connection. Only call if the current state is NOT_CONNECTED. + * + * The state will switch to CONNECTING immediately. After that, it can asynchronously change to any other state. + * State changes are indicated by broadcasts. In particular, if an error occurs while trying to connect, the state + * will change back to NOT_CONNECTED and an ACTION_DISCONNECTED broadcast is sent. + */ + public void connect(String name, String host, int port) { + playerName = name; + if(state != State.NOT_CONNECTED) { + throw new IllegalStateException("Attempt to start a new connection while the old one was still running."); + } + + clearLobbyState(); + changeState(State.CONNECTING); + connection = ThreadedNetConnection.startConnection(appContext, fromNetHandler, name, host, port); + connection.setFastTickRate(true); + } + + public void sendNick(String nick) { + playerName = nick; + sendToNet(MSG_SEND_NICK, nick); + } + public void sendPassword(String password) { sendToNet(MSG_SEND_PASSWORD, password); } + public void sendQuit(String message) { sendToNet(MSG_SEND_QUIT, message); } + public void sendRoomlistRequest() { sendToNet(MSG_SEND_ROOMLIST_REQUEST); } + public void sendPlayerInfoQuery(String name) { sendToNet(MSG_SEND_PLAYER_INFO_REQUEST, name); } + public void sendChat(String s) { sendToNet(MSG_SEND_CHAT, s); } + public void sendTeamChat(String s) { sendToNet(MSG_SEND_TEAMCHAT, s); } + public void sendFollowPlayer(String nick) { sendToNet(MSG_SEND_FOLLOW_PLAYER, nick); } + public void sendJoinRoom(String name) { sendToNet(MSG_SEND_JOIN_ROOM, name); } + public void sendCreateRoom(String name) { sendToNet(MSG_SEND_CREATE_ROOM, name); } + public void sendLeaveRoom(String message) { sendToNet(MSG_SEND_LEAVE_ROOM, message); } + public void sendKick(String player) { sendToNet(MSG_SEND_KICK, player); } + public void sendEngineMessage(byte[] engineMessage) { sendToNet(MSG_SEND_ENGINE_MESSAGE, engineMessage); } + public void sendRoundFinished(boolean withoutError) { sendToNet(MSG_SEND_ROUND_FINISHED, Boolean.valueOf(withoutError)); } + public void sendToggleReady() { sendToNet(MSG_SEND_TOGGLE_READY); } + public void sendStartGame() { sendToNet(MSG_SEND_START_GAME); } + + public void disconnect() { sendToNet(MSG_DISCONNECT, "User Quit"); } + + private static Netplay instance; + + /** + * Retrieve the single app-wide instance of the netplay interface, creating it if it + * does not exist yet. + * + * @param applicationContext + * @return + */ + public static Netplay getAppInstance(Context applicationContext) { + if(instance == null) { + // We will need some default values for rooms, best load them here + Scheme defaultScheme = null; + Weaponset defaultWeaponset = null; + try { + List schemes = Schemes.loadBuiltinSchemes(applicationContext); + for(Scheme scheme : schemes) { + if(scheme.name.equals(GameConfig.DEFAULT_SCHEME)) { + defaultScheme = scheme; + } + } + List weaponsets = Weaponsets.loadBuiltinWeaponsets(applicationContext); + for(Weaponset weaponset : weaponsets) { + if(weaponset.name.equals(GameConfig.DEFAULT_WEAPONSET)) { + defaultWeaponset = weaponset; + } + } + } catch(IOException e) { + throw new RuntimeException(e); + } + + if(defaultScheme==null || defaultWeaponset==null) { + throw new RuntimeException("Unable to load default scheme or weaponset"); + } + + instance = new Netplay(applicationContext, defaultScheme, defaultWeaponset); + } + return instance; + } + + public State getState() { + return state; + } + + private void changeState(State newState) { + if(newState != state) { + state = newState; + broadcastManager.sendBroadcastSync(new Intent(ACTION_STATE_CHANGED)); + } + } + + public boolean isChief() { + if(netRoomState != null) { + return netRoomState.getChiefStatus(); + } else { + return false; + } + } + + public String getPlayerName() { + return playerName; + } + + boolean sendToNet(ToNetMsgType what) { + return sendToNet(what, 0, null); + } + + boolean sendToNet(ToNetMsgType what, Object obj) { + return sendToNet(what, 0, obj); + } + + boolean sendToNet(ToNetMsgType what, int arg1, Object obj) { + if(connection != null) { + Handler handler = connection.toNetHandler; + return handler.sendMessage(handler.obtainMessage(what.ordinal(), arg1, 0, obj)); + } else { + return false; + } + } + + private MessageLog getCurrentLog() { + if(state == State.ROOM) { + return roomChatlog; + } else { + return lobbyChatlog; + } + } + + public static enum FromNetMsgType { + MSG_LOBBY_JOIN, + MSG_LOBBY_LEAVE, + MSG_ROOM_JOIN, + MSG_ROOM_LEAVE, + MSG_CLIENT_FLAGS, + MSG_CHAT, + MSG_MESSAGE, + MSG_ROOM_ADD, + MSG_ROOM_UPDATE, + MSG_ROOM_DELETE, + MSG_ROOMLIST, + MSG_CONNECTED, + MSG_DISCONNECTED, + MSG_PASSWORD_REQUEST, + MSG_ENTER_ROOM_FROM_LOBBY, + MSG_LEAVE_ROOM, + MSG_TEAM_ADDED, + MSG_TEAM_DELETED, + MSG_TEAM_ACCEPTED, + MSG_TEAM_COLOR_CHANGED, + MSG_HOG_COUNT_CHANGED, + MSG_ENGINE_MESSAGE, + MSG_RUN_GAME, + MSG_SCHEME_CHANGED, + MSG_MAP_CHANGED, + MSG_SCRIPT_CHANGED, + MSG_WEAPONSET_CHANGED; + + static final List values = Collections.unmodifiableList(Arrays.asList(FromNetMsgType.values())); + } + + /** + * Processes messages from the networking system. Always runs on the main thread. + */ + @SuppressLint("HandlerLeak") + final class FromNetHandler extends Handler { + public FromNetHandler() { + super(Looper.getMainLooper()); + } + + @SuppressWarnings("unchecked") + @Override + public void handleMessage(Message msg) { + switch(FromNetMsgType.values.get(msg.what)) { + case MSG_LOBBY_JOIN: { + String name = (String)msg.obj; + lobbyPlayerlist.put(name, new Player(name, false, false)); + lobbyChatlog.appendPlayerJoin(name); + break; + } + case MSG_LOBBY_LEAVE: { + Pair args = (Pair)msg.obj; + lobbyPlayerlist.remove(args.first); + lobbyChatlog.appendPlayerLeave(args.first, args.second); + break; + } + case MSG_ROOM_JOIN: { + String name = (String)msg.obj; + Player p = lobbyPlayerlist.get(name); + if(p==null) { + Log.w("Netplay", "Unknown player joined room: "+name); + p = new Player(name, false, false); + } + roomPlayerlist.put(name, new PlayerInRoom(p, false, false)); + roomChatlog.appendPlayerJoin(name); + break; + } + case MSG_ROOM_LEAVE: { + Pair args = (Pair)msg.obj; + roomPlayerlist.remove(args.first); + roomChatlog.appendPlayerLeave(args.first, args.second); + break; + } + case MSG_CLIENT_FLAGS: { + ClientFlagsUpdate upd = (ClientFlagsUpdate)msg.obj; + PlayerInRoom pir = roomPlayerlist.get(upd.nick); + if(pir != null) { + roomPlayerlist.put(upd.nick, upd.applyTo(pir)); + } + Player p = lobbyPlayerlist.get(upd.nick); + if(p != null) { + lobbyPlayerlist.put(upd.nick, upd.applyTo(p)); + } else { + Log.w("Netplay", "Received client flags for unknown player "+upd.nick); + } + if(playerName.equals(upd.nick) && upd.appliesTo(ClientFlagsUpdate.FLAG_CHIEF)) { + netRoomState.setChief(upd.newFlagState); + } + break; + } + case MSG_CHAT: { + Pair args = (Pair)msg.obj; + getCurrentLog().appendChat(args.first, args.second); + for(GameMessageListener listener : gameMessageListeners) { + listener.onChatMessage(args.first, args.second); + } + break; + } + case MSG_MESSAGE: { + getCurrentLog().appendMessage(msg.arg1, (String)msg.obj); + for(GameMessageListener listener : gameMessageListeners) { + listener.onMessage(1, (String)msg.obj); + } + break; + } + case MSG_ROOM_ADD: { + Room room = (Room)msg.obj; + roomList.addRoomWithNewId(room); + break; + } + case MSG_ROOM_UPDATE: { + Pair args = (Pair)msg.obj; + roomList.updateRoom(args.first, args.second); + break; + } + case MSG_ROOM_DELETE: { + roomList.remove((String)msg.obj); + break; + } + case MSG_ROOMLIST: { + Room[] rooms = (Room[])msg.obj; + roomList.updateList(rooms); + break; + } + case MSG_CONNECTED: { + playerName = (String)msg.obj; + changeState(State.LOBBY); + broadcastManager.sendBroadcast(new Intent(ACTION_CONNECTED)); + break; + } + case MSG_DISCONNECTED: { + Pair args = (Pair)msg.obj; + for(GameMessageListener listener : gameMessageListeners) { + listener.onNetDisconnected(); + } + changeState(State.NOT_CONNECTED); + connection = null; + Intent intent = new Intent(ACTION_DISCONNECTED); + intent.putExtra(EXTRA_HAS_ERROR, args.first); + intent.putExtra(EXTRA_MESSAGE, args.second); + broadcastManager.sendBroadcastSync(intent); + break; + } + case MSG_PASSWORD_REQUEST: { + Intent intent = new Intent(ACTION_PASSWORD_REQUESTED); + intent.putExtra(EXTRA_PLAYERNAME, (String)msg.obj); + broadcastManager.sendBroadcast(intent); + break; + } + case MSG_ENTER_ROOM_FROM_LOBBY: { + initRoomState((Boolean)msg.obj); + changeState(State.ROOM); + Intent intent = new Intent(ACTION_ENTERED_ROOM_FROM_LOBBY); + broadcastManager.sendBroadcastSync(intent); + break; + } + case MSG_LEAVE_ROOM: { + changeState(State.LOBBY); + Intent intent = new Intent(ACTION_LEFT_ROOM); + intent.putExtra(EXTRA_MESSAGE, (String)msg.obj); + intent.putExtra(EXTRA_REASON, msg.arg1); + broadcastManager.sendBroadcastSync(intent); + break; + } + case MSG_TEAM_ADDED: { + TeamInGame newTeam = (TeamInGame)msg.obj; + if(isChief()) { + int freeColor = TeamInGame.getUnusedOrRandomColorIndex(netRoomState.getTeams().values()); + sendToNet(MSG_SEND_TEAM_HOG_COUNT, newTeam.ingameAttribs.hogCount, newTeam.team.name); + sendToNet(MSG_SEND_TEAM_COLOR_INDEX, freeColor, newTeam.team.name); + newTeam = newTeam.withAttribs(newTeam.ingameAttribs.withColorIndex(freeColor)); + } + netRoomState.putTeam(newTeam); + break; + } + case MSG_TEAM_DELETED: { + netRoomState.removeTeam((String)msg.obj); + break; + } + case MSG_TEAM_ACCEPTED: { + TeamInGame requestedTeam = netRoomState.requestedTeams.remove(msg.obj); + if(requestedTeam!=null) { + netRoomState.putTeam(requestedTeam); + if(isChief()) { + // Not strictly necessary, but QtFrontend does it... + sendToNet(MSG_SEND_TEAM_HOG_COUNT, requestedTeam.ingameAttribs.hogCount, requestedTeam.team.name); + } + } else { + Log.e("Netplay", "Got accepted message for team that was never requested."); + } + break; + } + case MSG_TEAM_COLOR_CHANGED: { + TeamInGame oldEntry = netRoomState.getTeams().get((String)msg.obj); + if(oldEntry != null) { + /* + * If we are chief, we ignore colors from the outside. They only come from the server + * when someone adds a team then, and we override that choice anyway. + * Worse, that color message arrives *after* we have overridden the color, so it would + * re-override it right back. + */ + if(!isChief()) { + TeamIngameAttributes newAttribs = oldEntry.ingameAttribs.withColorIndex(msg.arg1); + netRoomState.putTeam(oldEntry.withAttribs(newAttribs)); + } + } else { + Log.e("Netplay", "Color update for unknown team "+msg.obj); + } + break; + } + case MSG_HOG_COUNT_CHANGED: { + TeamInGame oldEntry = netRoomState.getTeams().get((String)msg.obj); + if(oldEntry != null) { + TeamIngameAttributes newAttribs = oldEntry.ingameAttribs.withHogCount(msg.arg1); + netRoomState.putTeam(oldEntry.withAttribs(newAttribs)); + } else { + Log.e("Netplay", "Hog count update for unknown team "+msg.obj); + } + break; + } + case MSG_ENGINE_MESSAGE: { + byte[] em = (byte[])msg.obj; + for(GameMessageListener listener : gameMessageListeners) { + listener.onEngineMessage(em); + } + break; + } + case MSG_RUN_GAME: { + GameConfig config = (GameConfig)msg.obj; + for(RunGameListener listener : runGameListeners) { + listener.runGame(config); + } + break; + } + case MSG_MAP_CHANGED: { + netRoomState.setMapRecipe((MapRecipe)msg.obj); + break; + } + case MSG_SCHEME_CHANGED: { + netRoomState.setScheme((Scheme)msg.obj); + break; + } + case MSG_SCRIPT_CHANGED: { + netRoomState.setGameStyle((String)msg.obj); + break; + } + case MSG_WEAPONSET_CHANGED: { + netRoomState.setWeaponset((Weaponset)msg.obj); + break; + } + default: { + Log.e("FromNetHandler", "Unknown message type: "+msg.what); + break; + } + } + } + } +} diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/Roomlist.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/Roomlist.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/Roomlist.java Tue Jan 21 22:43:06 2014 +0100 @@ -27,32 +27,32 @@ import org.hedgewars.hedgeroid.util.ObservableTreeMap; public class Roomlist extends ObservableTreeMap { - private long nextId = 1; - - public void updateList(Room[] newRooms) { - Map newMap = new TreeMap(); - for(Room room : newRooms) { - RoomWithId oldEntry = get(room.name); - if(oldEntry == null) { - newMap.put(room.name, new RoomWithId(room, nextId++)); - } else { - newMap.put(room.name, new RoomWithId(room, oldEntry.id)); - } - } - replaceContent(newMap); - } - - public void addRoomWithNewId(Room room) { - put(room.name, new RoomWithId(room, nextId++)); - } - - public void updateRoom(String name, Room room) { - RoomWithId oldEntry = get(name); - if(oldEntry == null) { - addRoomWithNewId(room); - } else { - remove(name); - put(room.name, new RoomWithId(room, oldEntry.id)); - } - } + private long nextId = 1; + + public void updateList(Room[] newRooms) { + Map newMap = new TreeMap(); + for(Room room : newRooms) { + RoomWithId oldEntry = get(room.name); + if(oldEntry == null) { + newMap.put(room.name, new RoomWithId(room, nextId++)); + } else { + newMap.put(room.name, new RoomWithId(room, oldEntry.id)); + } + } + replaceContent(newMap); + } + + public void addRoomWithNewId(Room room) { + put(room.name, new RoomWithId(room, nextId++)); + } + + public void updateRoom(String name, Room room) { + RoomWithId oldEntry = get(name); + if(oldEntry == null) { + addRoomWithNewId(room); + } else { + remove(name); + put(room.name, new RoomWithId(room, oldEntry.id)); + } + } } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/RunGameListener.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/RunGameListener.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/RunGameListener.java Tue Jan 21 22:43:06 2014 +0100 @@ -22,5 +22,5 @@ import org.hedgewars.hedgeroid.Datastructures.GameConfig; public interface RunGameListener { - void runGame(GameConfig config); + void runGame(GameConfig config); } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/ThreadedNetConnection.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/ThreadedNetConnection.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/ThreadedNetConnection.java Tue Jan 21 22:43:06 2014 +0100 @@ -78,501 +78,501 @@ /** * This class handles the actual communication with the networking library, running on a separate thread. - * + * * In order to process net messages, this class regularly runs a tick() function on the frontlib. This * usually happens several times per second, but it can be slowed down a lot if no fast reaction to * events is required (e.g. to conserve battery if the application is in the background). */ class ThreadedNetConnection { - private static final long TICK_INTERVAL_FAST = 100; - private static final long TICK_INTERVAL_SLOW = 5000; - private static final Frontlib FLIB = Flib.INSTANCE; - - public final ToNetHandler toNetHandler; - - private final Context appContext; - private final FromNetHandler fromNetHandler; - private final TickHandler tickHandler; + private static final long TICK_INTERVAL_FAST = 100; + private static final long TICK_INTERVAL_SLOW = 5000; + private static final Frontlib FLIB = Flib.INSTANCE; + + public final ToNetHandler toNetHandler; + + private final Context appContext; + private final FromNetHandler fromNetHandler; + private final TickHandler tickHandler; + + /** + * conn can only be null while connecting (the first thing in the thread), and directly after disconnecting, + * in the same message (the looper is shut down on disconnect, so there will be no messages after that). + */ + private NetconnPtr conn; + private String playerName; + + private ThreadedNetConnection(Context appContext, FromNetHandler fromNetHandler) { + this.appContext = appContext; + this.fromNetHandler = fromNetHandler; + + HandlerThread thread = new HandlerThread("NetThread"); + thread.start(); + toNetHandler = new ToNetHandler(thread.getLooper()); + tickHandler = new TickHandler(thread.getLooper(), TICK_INTERVAL_FAST, tickCb); + } + + private void connect(final String name, final String host, final int port) { + toNetHandler.post(new Runnable() { + public void run() { + playerName = name == null ? "Player" : name; + File dataPath; + try { + dataPath = FileUtils.getDataPathFile(appContext); + } catch (FileNotFoundException e) { + shutdown(true, appContext.getString(R.string.sdcard_not_mounted)); + return; + } + conn = FLIB.flib_netconn_create(playerName, dataPath.getAbsolutePath()+"/", host, port); + if(conn == null) { + shutdown(true, appContext.getString(R.string.error_connection_failed)); + return; + } + + FLIB.flib_netconn_onSchemeChanged(conn, cfgSchemeCb, null); + FLIB.flib_netconn_onClientFlags(conn, clientFlagsCb, null); + FLIB.flib_netconn_onChat(conn, chatCb, null); + FLIB.flib_netconn_onConnected(conn, connectedCb, null); + FLIB.flib_netconn_onDisconnected(conn, disconnectCb, null); + FLIB.flib_netconn_onEngineMessage(conn, engineMessageCb, null); + FLIB.flib_netconn_onEnterRoom(conn, enterRoomCb, null); + FLIB.flib_netconn_onHogCountChanged(conn, hogCountChangedCb, null); + FLIB.flib_netconn_onLeaveRoom(conn, leaveRoomCb, null); + FLIB.flib_netconn_onLobbyJoin(conn, lobbyJoinCb, null); + FLIB.flib_netconn_onLobbyLeave(conn, lobbyLeaveCb, null); + FLIB.flib_netconn_onMapChanged(conn, mapChangedCb, null); + FLIB.flib_netconn_onMessage(conn, messageCb, null); + FLIB.flib_netconn_onPasswordRequest(conn, passwordRequestCb, null); + FLIB.flib_netconn_onRoomAdd(conn, roomAddCb, null); + FLIB.flib_netconn_onRoomDelete(conn, roomDeleteCb, null); + FLIB.flib_netconn_onRoomJoin(conn, roomJoinCb, null); + FLIB.flib_netconn_onRoomLeave(conn, roomLeaveCb, null); + FLIB.flib_netconn_onRoomlist(conn, roomlistCb, null); + FLIB.flib_netconn_onRoomUpdate(conn, roomUpdateCb, null); + FLIB.flib_netconn_onRunGame(conn, runGameCb, null); + FLIB.flib_netconn_onScriptChanged(conn, scriptChangedCb, null); + // FLIB.flib_netconn_onServerVar(conn, serverVarCb, null); + FLIB.flib_netconn_onTeamAccepted(conn, teamAcceptedCb, null); + FLIB.flib_netconn_onTeamAdd(conn, teamAddedCb, null); + FLIB.flib_netconn_onTeamColorChanged(conn, teamColorChangedCb, null); + FLIB.flib_netconn_onTeamDelete(conn, teamDeletedCb, null); + FLIB.flib_netconn_onWeaponsetChanged(conn, weaponsetChangedCb, null); + + tickHandler.start(); + } + }); + } + + public static ThreadedNetConnection startConnection(Context appContext, FromNetHandler fromNetHandler, String playerName, String host, int port) { + ThreadedNetConnection result = new ThreadedNetConnection(appContext, fromNetHandler); + result.connect(playerName, host, port); + return result; + } + + public void setFastTickRate(boolean fastTickRate) { + tickHandler.setInterval(fastTickRate ? TICK_INTERVAL_FAST : TICK_INTERVAL_SLOW); + } + + private final Runnable tickCb = new Runnable() { + public void run() { + FLIB.flib_netconn_tick(conn); + } + }; + + private final SchemeCallback cfgSchemeCb = new SchemeCallback() { + public void callback(Pointer context, SchemePtr schemePtr) { + sendFromNet(MSG_SCHEME_CHANGED, schemePtr.deref()); + } + }; + + private final MapIntCallback mapChangedCb = new MapIntCallback() { + public void callback(Pointer context, MapRecipePtr mapPtr, int updateType) { + sendFromNet(MSG_MAP_CHANGED, updateType, mapPtr.deref()); + } + }; + + private final StrCallback scriptChangedCb = new StrCallback() { + public void callback(Pointer context, String script) { + sendFromNet(MSG_SCRIPT_CHANGED, script); + } + }; + + private final WeaponsetCallback weaponsetChangedCb = new WeaponsetCallback() { + public void callback(Pointer context, WeaponsetPtr weaponsetPtr) { + sendFromNet(MSG_WEAPONSET_CHANGED, weaponsetPtr.deref()); + } + }; - /** - * conn can only be null while connecting (the first thing in the thread), and directly after disconnecting, - * in the same message (the looper is shut down on disconnect, so there will be no messages after that). - */ - private NetconnPtr conn; - private String playerName; - - private ThreadedNetConnection(Context appContext, FromNetHandler fromNetHandler) { - this.appContext = appContext; - this.fromNetHandler = fromNetHandler; - - HandlerThread thread = new HandlerThread("NetThread"); - thread.start(); - toNetHandler = new ToNetHandler(thread.getLooper()); - tickHandler = new TickHandler(thread.getLooper(), TICK_INTERVAL_FAST, tickCb); - } - - private void connect(final String name, final String host, final int port) { - toNetHandler.post(new Runnable() { - public void run() { - playerName = name == null ? "Player" : name; - File dataPath; - try { - dataPath = FileUtils.getDataPathFile(appContext); - } catch (FileNotFoundException e) { - shutdown(true, appContext.getString(R.string.sdcard_not_mounted)); - return; - } - conn = FLIB.flib_netconn_create(playerName, dataPath.getAbsolutePath()+"/", host, port); - if(conn == null) { - shutdown(true, appContext.getString(R.string.error_connection_failed)); - return; - } + private final StrCallback lobbyJoinCb = new StrCallback() { + public void callback(Pointer context, String name) { + sendFromNet(MSG_LOBBY_JOIN, name); + } + }; + + private final StrStrCallback lobbyLeaveCb = new StrStrCallback() { + public void callback(Pointer context, String name, String msg) { + sendFromNet(MSG_LOBBY_LEAVE, Pair.create(name, msg)); + } + }; + + private final StrCallback roomJoinCb = new StrCallback() { + public void callback(Pointer context, String name) { + sendFromNet(MSG_ROOM_JOIN, name); + } + }; + + private final StrStrCallback roomLeaveCb = new StrStrCallback() { + public void callback(Pointer context, String name, String message) { + sendFromNet(MSG_ROOM_LEAVE, Pair.create(name, message)); + } + }; + + private final StrStrBoolCallback clientFlagsCb = new StrStrBoolCallback() { + public void callback(Pointer context, String nick, String flags, boolean newFlagsState) { + sendFromNet(MSG_CLIENT_FLAGS, new ClientFlagsUpdate(nick, flags, newFlagsState)); + } + }; + + private final StrStrCallback chatCb = new StrStrCallback() { + public void callback(Pointer context, String name, String msg) { + sendFromNet(MSG_CHAT, Pair.create(name, msg)); + } + }; + + private final IntStrCallback messageCb = new IntStrCallback() { + public void callback(Pointer context, int type, String msg) { + sendFromNet(MSG_MESSAGE, type, msg); + } + }; + + private final RoomCallback roomAddCb = new RoomCallback() { + public void callback(Pointer context, RoomPtr roomPtr) { + sendFromNet(MSG_ROOM_ADD, roomPtr.deref()); + } + }; + + private final StrRoomCallback roomUpdateCb = new StrRoomCallback() { + public void callback(Pointer context, String name, RoomPtr roomPtr) { + sendFromNet(MSG_ROOM_UPDATE, Pair.create(name, roomPtr.deref())); + } + }; + + private final StrCallback roomDeleteCb = new StrCallback() { + public void callback(Pointer context, final String name) { + sendFromNet(MSG_ROOM_DELETE, name); + } + }; + + private final RoomListCallback roomlistCb = new RoomListCallback() { + public void callback(Pointer context, RoomArrayPtr arg1, int count) { + sendFromNet(MSG_ROOMLIST, arg1.getRooms(count)); + } + }; + + private final VoidCallback connectedCb = new VoidCallback() { + public void callback(Pointer context) { + FLIB.flib_netconn_send_request_roomlist(conn); + playerName = FLIB.flib_netconn_get_playername(conn); + sendFromNet(MSG_CONNECTED, playerName); + } + }; + + private final StrCallback passwordRequestCb = new StrCallback() { + public void callback(Pointer context, String nickname) { + sendFromNet(MSG_PASSWORD_REQUEST, playerName); + } + }; + + private final BoolCallback enterRoomCb = new BoolCallback() { + public void callback(Pointer context, boolean isChief) { + sendFromNet(MSG_ENTER_ROOM_FROM_LOBBY, isChief); + } + }; + + private final IntStrCallback leaveRoomCb = new IntStrCallback() { + public void callback(Pointer context, int reason, String message) { + sendFromNet(MSG_LEAVE_ROOM, reason, message); + } + }; + + private final TeamCallback teamAddedCb = new TeamCallback() { + public void callback(Pointer context, TeamPtr team) { + sendFromNet(MSG_TEAM_ADDED, team.deref()); + } + }; + + private final StrCallback teamDeletedCb = new StrCallback() { + public void callback(Pointer context, String teamName) { + sendFromNet(MSG_TEAM_DELETED, teamName); + } + }; + + private final StrCallback teamAcceptedCb = new StrCallback() { + public void callback(Pointer context, String teamName) { + sendFromNet(MSG_TEAM_ACCEPTED, teamName); + } + }; + + private final StrIntCallback teamColorChangedCb = new StrIntCallback() { + public void callback(Pointer context, String teamName, int colorIndex) { + sendFromNet(MSG_TEAM_COLOR_CHANGED, colorIndex, teamName); + } + }; + + private final StrIntCallback hogCountChangedCb = new StrIntCallback() { + public void callback(Pointer context, String teamName, int hogCount) { + sendFromNet(MSG_HOG_COUNT_CHANGED, hogCount, teamName); + } + }; + + private final BytesCallback engineMessageCb = new BytesCallback() { + public void callback(Pointer context, ByteArrayPtr buffer, NativeSizeT size) { + sendFromNet(MSG_ENGINE_MESSAGE, buffer.deref(size.intValue())); + } + }; - FLIB.flib_netconn_onSchemeChanged(conn, cfgSchemeCb, null); - FLIB.flib_netconn_onClientFlags(conn, clientFlagsCb, null); - FLIB.flib_netconn_onChat(conn, chatCb, null); - FLIB.flib_netconn_onConnected(conn, connectedCb, null); - FLIB.flib_netconn_onDisconnected(conn, disconnectCb, null); - FLIB.flib_netconn_onEngineMessage(conn, engineMessageCb, null); - FLIB.flib_netconn_onEnterRoom(conn, enterRoomCb, null); - FLIB.flib_netconn_onHogCountChanged(conn, hogCountChangedCb, null); - FLIB.flib_netconn_onLeaveRoom(conn, leaveRoomCb, null); - FLIB.flib_netconn_onLobbyJoin(conn, lobbyJoinCb, null); - FLIB.flib_netconn_onLobbyLeave(conn, lobbyLeaveCb, null); - FLIB.flib_netconn_onMapChanged(conn, mapChangedCb, null); - FLIB.flib_netconn_onMessage(conn, messageCb, null); - FLIB.flib_netconn_onPasswordRequest(conn, passwordRequestCb, null); - FLIB.flib_netconn_onRoomAdd(conn, roomAddCb, null); - FLIB.flib_netconn_onRoomDelete(conn, roomDeleteCb, null); - FLIB.flib_netconn_onRoomJoin(conn, roomJoinCb, null); - FLIB.flib_netconn_onRoomLeave(conn, roomLeaveCb, null); - FLIB.flib_netconn_onRoomlist(conn, roomlistCb, null); - FLIB.flib_netconn_onRoomUpdate(conn, roomUpdateCb, null); - FLIB.flib_netconn_onRunGame(conn, runGameCb, null); - FLIB.flib_netconn_onScriptChanged(conn, scriptChangedCb, null); - // FLIB.flib_netconn_onServerVar(conn, serverVarCb, null); - FLIB.flib_netconn_onTeamAccepted(conn, teamAcceptedCb, null); - FLIB.flib_netconn_onTeamAdd(conn, teamAddedCb, null); - FLIB.flib_netconn_onTeamColorChanged(conn, teamColorChangedCb, null); - FLIB.flib_netconn_onTeamDelete(conn, teamDeletedCb, null); - FLIB.flib_netconn_onWeaponsetChanged(conn, weaponsetChangedCb, null); - - tickHandler.start(); - } - }); - } - - public static ThreadedNetConnection startConnection(Context appContext, FromNetHandler fromNetHandler, String playerName, String host, int port) { - ThreadedNetConnection result = new ThreadedNetConnection(appContext, fromNetHandler); - result.connect(playerName, host, port); - return result; - } - - public void setFastTickRate(boolean fastTickRate) { - tickHandler.setInterval(fastTickRate ? TICK_INTERVAL_FAST : TICK_INTERVAL_SLOW); - } - - private final Runnable tickCb = new Runnable() { - public void run() { - FLIB.flib_netconn_tick(conn); - } - }; - - private final SchemeCallback cfgSchemeCb = new SchemeCallback() { - public void callback(Pointer context, SchemePtr schemePtr) { - sendFromNet(MSG_SCHEME_CHANGED, schemePtr.deref()); - } - }; - - private final MapIntCallback mapChangedCb = new MapIntCallback() { - public void callback(Pointer context, MapRecipePtr mapPtr, int updateType) { - sendFromNet(MSG_MAP_CHANGED, updateType, mapPtr.deref()); - } - }; - - private final StrCallback scriptChangedCb = new StrCallback() { - public void callback(Pointer context, String script) { - sendFromNet(MSG_SCRIPT_CHANGED, script); - } - }; - - private final WeaponsetCallback weaponsetChangedCb = new WeaponsetCallback() { - public void callback(Pointer context, WeaponsetPtr weaponsetPtr) { - sendFromNet(MSG_WEAPONSET_CHANGED, weaponsetPtr.deref()); - } - }; - - private final StrCallback lobbyJoinCb = new StrCallback() { - public void callback(Pointer context, String name) { - sendFromNet(MSG_LOBBY_JOIN, name); - } - }; - - private final StrStrCallback lobbyLeaveCb = new StrStrCallback() { - public void callback(Pointer context, String name, String msg) { - sendFromNet(MSG_LOBBY_LEAVE, Pair.create(name, msg)); - } - }; - - private final StrCallback roomJoinCb = new StrCallback() { - public void callback(Pointer context, String name) { - sendFromNet(MSG_ROOM_JOIN, name); - } - }; - - private final StrStrCallback roomLeaveCb = new StrStrCallback() { - public void callback(Pointer context, String name, String message) { - sendFromNet(MSG_ROOM_LEAVE, Pair.create(name, message)); - } - }; - - private final StrStrBoolCallback clientFlagsCb = new StrStrBoolCallback() { - public void callback(Pointer context, String nick, String flags, boolean newFlagsState) { - sendFromNet(MSG_CLIENT_FLAGS, new ClientFlagsUpdate(nick, flags, newFlagsState)); - } - }; - - private final StrStrCallback chatCb = new StrStrCallback() { - public void callback(Pointer context, String name, String msg) { - sendFromNet(MSG_CHAT, Pair.create(name, msg)); - } - }; - - private final IntStrCallback messageCb = new IntStrCallback() { - public void callback(Pointer context, int type, String msg) { - sendFromNet(MSG_MESSAGE, type, msg); - } - }; - - private final RoomCallback roomAddCb = new RoomCallback() { - public void callback(Pointer context, RoomPtr roomPtr) { - sendFromNet(MSG_ROOM_ADD, roomPtr.deref()); - } - }; - - private final StrRoomCallback roomUpdateCb = new StrRoomCallback() { - public void callback(Pointer context, String name, RoomPtr roomPtr) { - sendFromNet(MSG_ROOM_UPDATE, Pair.create(name, roomPtr.deref())); - } - }; - - private final StrCallback roomDeleteCb = new StrCallback() { - public void callback(Pointer context, final String name) { - sendFromNet(MSG_ROOM_DELETE, name); - } - }; - - private final RoomListCallback roomlistCb = new RoomListCallback() { - public void callback(Pointer context, RoomArrayPtr arg1, int count) { - sendFromNet(MSG_ROOMLIST, arg1.getRooms(count)); - } - }; - - private final VoidCallback connectedCb = new VoidCallback() { - public void callback(Pointer context) { - FLIB.flib_netconn_send_request_roomlist(conn); - playerName = FLIB.flib_netconn_get_playername(conn); - sendFromNet(MSG_CONNECTED, playerName); - } - }; - - private final StrCallback passwordRequestCb = new StrCallback() { - public void callback(Pointer context, String nickname) { - sendFromNet(MSG_PASSWORD_REQUEST, playerName); - } - }; - - private final BoolCallback enterRoomCb = new BoolCallback() { - public void callback(Pointer context, boolean isChief) { - sendFromNet(MSG_ENTER_ROOM_FROM_LOBBY, isChief); - } - }; - - private final IntStrCallback leaveRoomCb = new IntStrCallback() { - public void callback(Pointer context, int reason, String message) { - sendFromNet(MSG_LEAVE_ROOM, reason, message); - } - }; - - private final TeamCallback teamAddedCb = new TeamCallback() { - public void callback(Pointer context, TeamPtr team) { - sendFromNet(MSG_TEAM_ADDED, team.deref()); - } - }; - - private final StrCallback teamDeletedCb = new StrCallback() { - public void callback(Pointer context, String teamName) { - sendFromNet(MSG_TEAM_DELETED, teamName); - } - }; - - private final StrCallback teamAcceptedCb = new StrCallback() { - public void callback(Pointer context, String teamName) { - sendFromNet(MSG_TEAM_ACCEPTED, teamName); - } - }; - - private final StrIntCallback teamColorChangedCb = new StrIntCallback() { - public void callback(Pointer context, String teamName, int colorIndex) { - sendFromNet(MSG_TEAM_COLOR_CHANGED, colorIndex, teamName); - } - }; - - private final StrIntCallback hogCountChangedCb = new StrIntCallback() { - public void callback(Pointer context, String teamName, int hogCount) { - sendFromNet(MSG_HOG_COUNT_CHANGED, hogCount, teamName); - } - }; - - private final BytesCallback engineMessageCb = new BytesCallback() { - public void callback(Pointer context, ByteArrayPtr buffer, NativeSizeT size) { - sendFromNet(MSG_ENGINE_MESSAGE, buffer.deref(size.intValue())); - } - }; - - private final VoidCallback runGameCb = new VoidCallback() { - public void callback(Pointer context) { - GameSetupPtr configPtr = FLIB.flib_netconn_create_gamesetup(conn); - sendFromNet(MSG_RUN_GAME, configPtr.deref()); - FLIB.flib_gamesetup_destroy(configPtr); - } - }; - - private void shutdown(boolean error, String message) { - if(conn != null) { - FLIB.flib_netconn_destroy(conn); - conn = null; - } - tickHandler.stop(); - toNetHandler.getLooper().quit(); - sendFromNet(MSG_DISCONNECTED, Pair.create(error, message)); - } - - private final IntStrCallback disconnectCb = new IntStrCallback() { - public void callback(Pointer context, int reason, String message) { - Boolean error = reason != Frontlib.NETCONN_DISCONNECT_NORMAL; - String messageForUser = createDisconnectUserMessage(appContext.getResources(), reason, message); - shutdown(error, messageForUser); - } - }; - - private static String createDisconnectUserMessage(Resources res, int reason, String message) { - switch(reason) { - case Frontlib.NETCONN_DISCONNECT_AUTH_FAILED: - return res.getString(R.string.error_auth_failed); - case Frontlib.NETCONN_DISCONNECT_CONNLOST: - return res.getString(R.string.error_connection_lost); - case Frontlib.NETCONN_DISCONNECT_INTERNAL_ERROR: - return res.getString(R.string.error_unexpected, message); - case Frontlib.NETCONN_DISCONNECT_SERVER_TOO_OLD: - return res.getString(R.string.error_server_too_old); - default: - return message; - } - } - - private boolean sendFromNet(FromNetMsgType what, Object obj) { - return fromNetHandler.sendMessage(fromNetHandler.obtainMessage(what.ordinal(), obj)); - } - - private boolean sendFromNet(FromNetMsgType what, int arg1, Object obj) { - return fromNetHandler.sendMessage(fromNetHandler.obtainMessage(what.ordinal(), arg1, 0, obj)); - } - - static enum ToNetMsgType { - MSG_SEND_NICK, - MSG_SEND_PASSWORD, - MSG_SEND_QUIT, - MSG_SEND_ROOMLIST_REQUEST, - MSG_SEND_PLAYER_INFO_REQUEST, - MSG_SEND_CHAT, - MSG_SEND_TEAMCHAT, - MSG_SEND_FOLLOW_PLAYER, - MSG_SEND_JOIN_ROOM, - MSG_SEND_CREATE_ROOM, - MSG_SEND_LEAVE_ROOM, - MSG_SEND_KICK, - MSG_SEND_ADD_TEAM, - MSG_SEND_REMOVE_TEAM, - MSG_DISCONNECT, - MSG_SEND_TEAM_COLOR_INDEX, - MSG_SEND_TEAM_HOG_COUNT, - MSG_SEND_ENGINE_MESSAGE, - MSG_SEND_ROUND_FINISHED, - MSG_SEND_TOGGLE_READY, - MSG_SEND_START_GAME, - MSG_SEND_WEAPONSET, - MSG_SEND_MAP, - MSG_SEND_MAP_NAME, - MSG_SEND_MAP_GENERATOR, - MSG_SEND_MAP_TEMPLATE, - MSG_SEND_MAZE_SIZE, - MSG_SEND_MAP_SEED, - MSG_SEND_MAP_THEME, - MSG_SEND_MAP_DRAWDATA, - MSG_SEND_GAMESTYLE, - MSG_SEND_SCHEME; - - static final List values = Collections.unmodifiableList(Arrays.asList(ToNetMsgType.values())); - } - - /** - * Processes messages to the networking system. Runs on a non-main thread. - */ - @SuppressLint("HandlerLeak") - public final class ToNetHandler extends Handler { - - public ToNetHandler(Looper looper) { - super(looper); - } - - @Override - public void handleMessage(Message msg) { - switch(ToNetMsgType.values.get(msg.what)) { - case MSG_SEND_NICK: { - FLIB.flib_netconn_send_nick(conn, (String)msg.obj); - break; - } - case MSG_SEND_PASSWORD: { - FLIB.flib_netconn_send_password(conn, (String)msg.obj); - break; - } - case MSG_SEND_QUIT: { - FLIB.flib_netconn_send_quit(conn, (String)msg.obj); - break; - } - case MSG_SEND_ROOMLIST_REQUEST: { - FLIB.flib_netconn_send_request_roomlist(conn); - break; - } - case MSG_SEND_PLAYER_INFO_REQUEST: { - FLIB.flib_netconn_send_playerInfo(conn, (String)msg.obj); - break; - } - case MSG_SEND_CHAT: { - if(FLIB.flib_netconn_send_chat(conn, (String)msg.obj) == 0) { - sendFromNet(MSG_CHAT, Pair.create(playerName, (String)msg.obj)); - } - break; - } - case MSG_SEND_TEAMCHAT: { - FLIB.flib_netconn_send_teamchat(conn, (String)msg.obj); - break; - } - case MSG_SEND_FOLLOW_PLAYER: { - FLIB.flib_netconn_send_playerFollow(conn, (String)msg.obj); - break; - } - case MSG_SEND_JOIN_ROOM: { - FLIB.flib_netconn_send_joinRoom(conn, (String)msg.obj); - break; - } - case MSG_SEND_CREATE_ROOM: { - FLIB.flib_netconn_send_createRoom(conn, (String)msg.obj); - break; - } - case MSG_SEND_LEAVE_ROOM: { - if(FLIB.flib_netconn_send_leaveRoom(conn, (String)msg.obj) == 0) { - sendFromNet(MSG_LEAVE_ROOM, -1, ""); - } - break; - } - case MSG_SEND_KICK: { - FLIB.flib_netconn_send_kick(conn, (String)msg.obj); - break; - } - case MSG_SEND_ADD_TEAM: { - FLIB.flib_netconn_send_addTeam(conn, TeamPtr.createJavaOwned((TeamInGame)msg.obj)); - break; - } - case MSG_SEND_REMOVE_TEAM: { - if(FLIB.flib_netconn_send_removeTeam(conn, (String)msg.obj)==0) { - sendFromNet(MSG_TEAM_DELETED, msg.obj); - } - break; - } - case MSG_DISCONNECT: { - FLIB.flib_netconn_send_quit(conn, (String)msg.obj); - shutdown(false, "User quit"); - break; - } - case MSG_SEND_TEAM_COLOR_INDEX: { - FLIB.flib_netconn_send_teamColor(conn, (String)msg.obj, msg.arg1); - break; - } - case MSG_SEND_TEAM_HOG_COUNT: { - FLIB.flib_netconn_send_teamHogCount(conn, (String)msg.obj, msg.arg1); - break; - } - case MSG_SEND_ENGINE_MESSAGE: { - byte[] message = (byte[])msg.obj; - ByteArrayPtr ptr = ByteArrayPtr.createJavaOwned(message); - FLIB.flib_netconn_send_engineMessage(conn, ptr, NativeSizeT.valueOf(message.length)); - break; - } - case MSG_SEND_ROUND_FINISHED: { - FLIB.flib_netconn_send_roundfinished(conn, (Boolean)msg.obj); - break; - } - case MSG_SEND_TOGGLE_READY: { - FLIB.flib_netconn_send_toggleReady(conn); - break; - } - case MSG_SEND_START_GAME: { - FLIB.flib_netconn_send_startGame(conn); - break; - } - case MSG_SEND_WEAPONSET: { - FLIB.flib_netconn_send_weaponset(conn, WeaponsetPtr.createJavaOwned((Weaponset)msg.obj)); - break; - } - case MSG_SEND_MAP: { - FLIB.flib_netconn_send_map(conn, MapRecipePtr.createJavaOwned((MapRecipe)msg.obj)); - break; - } - case MSG_SEND_MAP_NAME: { - FLIB.flib_netconn_send_mapName(conn, (String)msg.obj); - break; - } - case MSG_SEND_MAP_GENERATOR: { - FLIB.flib_netconn_send_mapGen(conn, msg.arg1); - break; - } - case MSG_SEND_MAP_TEMPLATE: { - FLIB.flib_netconn_send_mapTemplate(conn, msg.arg1); - break; - } - case MSG_SEND_MAZE_SIZE: { - FLIB.flib_netconn_send_mapMazeSize(conn, msg.arg1); - break; - } - case MSG_SEND_MAP_SEED: { - FLIB.flib_netconn_send_mapSeed(conn, (String) msg.obj); - break; - } - case MSG_SEND_MAP_THEME: { - FLIB.flib_netconn_send_mapTheme(conn, (String) msg.obj); - break; - } - case MSG_SEND_MAP_DRAWDATA: { - byte[] message = (byte[])msg.obj; - ByteArrayPtr ptr = ByteArrayPtr.createJavaOwned(message); - FLIB.flib_netconn_send_mapDrawdata(conn, ptr, NativeSizeT.valueOf(message.length)); - break; - } - case MSG_SEND_GAMESTYLE: { - FLIB.flib_netconn_send_script(conn, (String) msg.obj); - break; - } - case MSG_SEND_SCHEME: { - FLIB.flib_netconn_send_scheme(conn, SchemePtr.createJavaOwned((Scheme) msg.obj)); - break; - } - default: { - Log.e("ToNetHandler", "Unknown message type: "+msg.what); - break; - } - } - } - } + private final VoidCallback runGameCb = new VoidCallback() { + public void callback(Pointer context) { + GameSetupPtr configPtr = FLIB.flib_netconn_create_gamesetup(conn); + sendFromNet(MSG_RUN_GAME, configPtr.deref()); + FLIB.flib_gamesetup_destroy(configPtr); + } + }; + + private void shutdown(boolean error, String message) { + if(conn != null) { + FLIB.flib_netconn_destroy(conn); + conn = null; + } + tickHandler.stop(); + toNetHandler.getLooper().quit(); + sendFromNet(MSG_DISCONNECTED, Pair.create(error, message)); + } + + private final IntStrCallback disconnectCb = new IntStrCallback() { + public void callback(Pointer context, int reason, String message) { + Boolean error = reason != Frontlib.NETCONN_DISCONNECT_NORMAL; + String messageForUser = createDisconnectUserMessage(appContext.getResources(), reason, message); + shutdown(error, messageForUser); + } + }; + + private static String createDisconnectUserMessage(Resources res, int reason, String message) { + switch(reason) { + case Frontlib.NETCONN_DISCONNECT_AUTH_FAILED: + return res.getString(R.string.error_auth_failed); + case Frontlib.NETCONN_DISCONNECT_CONNLOST: + return res.getString(R.string.error_connection_lost); + case Frontlib.NETCONN_DISCONNECT_INTERNAL_ERROR: + return res.getString(R.string.error_unexpected, message); + case Frontlib.NETCONN_DISCONNECT_SERVER_TOO_OLD: + return res.getString(R.string.error_server_too_old); + default: + return message; + } + } + + private boolean sendFromNet(FromNetMsgType what, Object obj) { + return fromNetHandler.sendMessage(fromNetHandler.obtainMessage(what.ordinal(), obj)); + } + + private boolean sendFromNet(FromNetMsgType what, int arg1, Object obj) { + return fromNetHandler.sendMessage(fromNetHandler.obtainMessage(what.ordinal(), arg1, 0, obj)); + } + + static enum ToNetMsgType { + MSG_SEND_NICK, + MSG_SEND_PASSWORD, + MSG_SEND_QUIT, + MSG_SEND_ROOMLIST_REQUEST, + MSG_SEND_PLAYER_INFO_REQUEST, + MSG_SEND_CHAT, + MSG_SEND_TEAMCHAT, + MSG_SEND_FOLLOW_PLAYER, + MSG_SEND_JOIN_ROOM, + MSG_SEND_CREATE_ROOM, + MSG_SEND_LEAVE_ROOM, + MSG_SEND_KICK, + MSG_SEND_ADD_TEAM, + MSG_SEND_REMOVE_TEAM, + MSG_DISCONNECT, + MSG_SEND_TEAM_COLOR_INDEX, + MSG_SEND_TEAM_HOG_COUNT, + MSG_SEND_ENGINE_MESSAGE, + MSG_SEND_ROUND_FINISHED, + MSG_SEND_TOGGLE_READY, + MSG_SEND_START_GAME, + MSG_SEND_WEAPONSET, + MSG_SEND_MAP, + MSG_SEND_MAP_NAME, + MSG_SEND_MAP_GENERATOR, + MSG_SEND_MAP_TEMPLATE, + MSG_SEND_MAZE_SIZE, + MSG_SEND_MAP_SEED, + MSG_SEND_MAP_THEME, + MSG_SEND_MAP_DRAWDATA, + MSG_SEND_GAMESTYLE, + MSG_SEND_SCHEME; + + static final List values = Collections.unmodifiableList(Arrays.asList(ToNetMsgType.values())); + } + + /** + * Processes messages to the networking system. Runs on a non-main thread. + */ + @SuppressLint("HandlerLeak") + public final class ToNetHandler extends Handler { + + public ToNetHandler(Looper looper) { + super(looper); + } + + @Override + public void handleMessage(Message msg) { + switch(ToNetMsgType.values.get(msg.what)) { + case MSG_SEND_NICK: { + FLIB.flib_netconn_send_nick(conn, (String)msg.obj); + break; + } + case MSG_SEND_PASSWORD: { + FLIB.flib_netconn_send_password(conn, (String)msg.obj); + break; + } + case MSG_SEND_QUIT: { + FLIB.flib_netconn_send_quit(conn, (String)msg.obj); + break; + } + case MSG_SEND_ROOMLIST_REQUEST: { + FLIB.flib_netconn_send_request_roomlist(conn); + break; + } + case MSG_SEND_PLAYER_INFO_REQUEST: { + FLIB.flib_netconn_send_playerInfo(conn, (String)msg.obj); + break; + } + case MSG_SEND_CHAT: { + if(FLIB.flib_netconn_send_chat(conn, (String)msg.obj) == 0) { + sendFromNet(MSG_CHAT, Pair.create(playerName, (String)msg.obj)); + } + break; + } + case MSG_SEND_TEAMCHAT: { + FLIB.flib_netconn_send_teamchat(conn, (String)msg.obj); + break; + } + case MSG_SEND_FOLLOW_PLAYER: { + FLIB.flib_netconn_send_playerFollow(conn, (String)msg.obj); + break; + } + case MSG_SEND_JOIN_ROOM: { + FLIB.flib_netconn_send_joinRoom(conn, (String)msg.obj); + break; + } + case MSG_SEND_CREATE_ROOM: { + FLIB.flib_netconn_send_createRoom(conn, (String)msg.obj); + break; + } + case MSG_SEND_LEAVE_ROOM: { + if(FLIB.flib_netconn_send_leaveRoom(conn, (String)msg.obj) == 0) { + sendFromNet(MSG_LEAVE_ROOM, -1, ""); + } + break; + } + case MSG_SEND_KICK: { + FLIB.flib_netconn_send_kick(conn, (String)msg.obj); + break; + } + case MSG_SEND_ADD_TEAM: { + FLIB.flib_netconn_send_addTeam(conn, TeamPtr.createJavaOwned((TeamInGame)msg.obj)); + break; + } + case MSG_SEND_REMOVE_TEAM: { + if(FLIB.flib_netconn_send_removeTeam(conn, (String)msg.obj)==0) { + sendFromNet(MSG_TEAM_DELETED, msg.obj); + } + break; + } + case MSG_DISCONNECT: { + FLIB.flib_netconn_send_quit(conn, (String)msg.obj); + shutdown(false, "User quit"); + break; + } + case MSG_SEND_TEAM_COLOR_INDEX: { + FLIB.flib_netconn_send_teamColor(conn, (String)msg.obj, msg.arg1); + break; + } + case MSG_SEND_TEAM_HOG_COUNT: { + FLIB.flib_netconn_send_teamHogCount(conn, (String)msg.obj, msg.arg1); + break; + } + case MSG_SEND_ENGINE_MESSAGE: { + byte[] message = (byte[])msg.obj; + ByteArrayPtr ptr = ByteArrayPtr.createJavaOwned(message); + FLIB.flib_netconn_send_engineMessage(conn, ptr, NativeSizeT.valueOf(message.length)); + break; + } + case MSG_SEND_ROUND_FINISHED: { + FLIB.flib_netconn_send_roundfinished(conn, (Boolean)msg.obj); + break; + } + case MSG_SEND_TOGGLE_READY: { + FLIB.flib_netconn_send_toggleReady(conn); + break; + } + case MSG_SEND_START_GAME: { + FLIB.flib_netconn_send_startGame(conn); + break; + } + case MSG_SEND_WEAPONSET: { + FLIB.flib_netconn_send_weaponset(conn, WeaponsetPtr.createJavaOwned((Weaponset)msg.obj)); + break; + } + case MSG_SEND_MAP: { + FLIB.flib_netconn_send_map(conn, MapRecipePtr.createJavaOwned((MapRecipe)msg.obj)); + break; + } + case MSG_SEND_MAP_NAME: { + FLIB.flib_netconn_send_mapName(conn, (String)msg.obj); + break; + } + case MSG_SEND_MAP_GENERATOR: { + FLIB.flib_netconn_send_mapGen(conn, msg.arg1); + break; + } + case MSG_SEND_MAP_TEMPLATE: { + FLIB.flib_netconn_send_mapTemplate(conn, msg.arg1); + break; + } + case MSG_SEND_MAZE_SIZE: { + FLIB.flib_netconn_send_mapMazeSize(conn, msg.arg1); + break; + } + case MSG_SEND_MAP_SEED: { + FLIB.flib_netconn_send_mapSeed(conn, (String) msg.obj); + break; + } + case MSG_SEND_MAP_THEME: { + FLIB.flib_netconn_send_mapTheme(conn, (String) msg.obj); + break; + } + case MSG_SEND_MAP_DRAWDATA: { + byte[] message = (byte[])msg.obj; + ByteArrayPtr ptr = ByteArrayPtr.createJavaOwned(message); + FLIB.flib_netconn_send_mapDrawdata(conn, ptr, NativeSizeT.valueOf(message.length)); + break; + } + case MSG_SEND_GAMESTYLE: { + FLIB.flib_netconn_send_script(conn, (String) msg.obj); + break; + } + case MSG_SEND_SCHEME: { + FLIB.flib_netconn_send_scheme(conn, SchemePtr.createJavaOwned((Scheme) msg.obj)); + break; + } + default: { + Log.e("ToNetHandler", "Unknown message type: "+msg.what); + break; + } + } + } + } } \ No newline at end of file diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/CalmDownHandler.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/CalmDownHandler.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/CalmDownHandler.java Tue Jan 21 22:43:06 2014 +0100 @@ -32,31 +32,31 @@ * information change. */ public final class CalmDownHandler extends Handler { - int runningMessagesCounter = 0; - final Runnable inactivityRunnable; - final long inactivityMs; - boolean stopped; + int runningMessagesCounter = 0; + final Runnable inactivityRunnable; + final long inactivityMs; + boolean stopped; + + public CalmDownHandler(Looper looper, Runnable runnable, long inactivityMs) { + super(looper); + this.inactivityRunnable = runnable; + this.inactivityMs = inactivityMs; + } - public CalmDownHandler(Looper looper, Runnable runnable, long inactivityMs) { - super(looper); - this.inactivityRunnable = runnable; - this.inactivityMs = inactivityMs; - } - - public void activity() { - runningMessagesCounter++; - sendMessageDelayed(obtainMessage(), inactivityMs); - } - - @Override - public void handleMessage(Message msg) { - runningMessagesCounter--; - if(runningMessagesCounter==0 && !stopped) { - inactivityRunnable.run(); - } - } - - public void stop() { - stopped = true; - } + public void activity() { + runningMessagesCounter++; + sendMessageDelayed(obtainMessage(), inactivityMs); + } + + @Override + public void handleMessage(Message msg) { + runningMessagesCounter--; + if(runningMessagesCounter==0 && !stopped) { + inactivityRunnable.run(); + } + } + + public void stop() { + stopped = true; + } } \ No newline at end of file diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/FileUtils.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/FileUtils.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/FileUtils.java Tue Jan 21 22:43:06 2014 +0100 @@ -40,220 +40,220 @@ import android.util.Log; public class FileUtils { - private static final String ROOT_DIR = "Data"; - private static final String TAG = FileUtils.class.getSimpleName(); + private static final String ROOT_DIR = "Data"; + private static final String TAG = FileUtils.class.getSimpleName(); + + /** + * @return true if the data path is currently available. However, it can vanish at any time so + * normally you should just try to use it and rely on the exceptions. + */ + public static boolean isDataPathAvailable() { + return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()); + } - /** - * @return true if the data path is currently available. However, it can vanish at any time so - * normally you should just try to use it and rely on the exceptions. - */ - public static boolean isDataPathAvailable() { - return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()); - } - - /** - * get the path to which we should download all the data files - * @param c context - * @return The directory - * @throws FileNotFoundException if external storage is not available at the moment - */ - public static File getCachePath(Context c) throws FileNotFoundException { - File cachePath = null; - if(Build.VERSION.SDK_INT < 8){//8 == Build.VERSION_CODES.FROYO - cachePath = PreFroyoSDCardDir.getDownloadPath(c); - } else { - cachePath = FroyoSDCardDir.getDownloadPath(c); - } - if(cachePath==null) { - throw new FileNotFoundException("External storage is currently unavailable"); - } else { - return cachePath; - } - } + /** + * get the path to which we should download all the data files + * @param c context + * @return The directory + * @throws FileNotFoundException if external storage is not available at the moment + */ + public static File getCachePath(Context c) throws FileNotFoundException { + File cachePath = null; + if(Build.VERSION.SDK_INT < 8){//8 == Build.VERSION_CODES.FROYO + cachePath = PreFroyoSDCardDir.getDownloadPath(c); + } else { + cachePath = FroyoSDCardDir.getDownloadPath(c); + } + if(cachePath==null) { + throw new FileNotFoundException("External storage is currently unavailable"); + } else { + return cachePath; + } + } - public static File getDataPathFile(Context c, String...subpath) throws FileNotFoundException { - File file = new File(getCachePath(c), ROOT_DIR); - for(String pathcomponent : subpath) { - file = new File(file, pathcomponent); - } - return file; - } - - @TargetApi(8) - private static class FroyoSDCardDir{ - public static File getDownloadPath(Context c){ - return c.getExternalCacheDir(); - } - } + public static File getDataPathFile(Context c, String...subpath) throws FileNotFoundException { + File file = new File(getCachePath(c), ROOT_DIR); + for(String pathcomponent : subpath) { + file = new File(file, pathcomponent); + } + return file; + } + + @TargetApi(8) + private static class FroyoSDCardDir{ + public static File getDownloadPath(Context c){ + return c.getExternalCacheDir(); + } + } - private static class PreFroyoSDCardDir{ - public static File getDownloadPath(Context c){ - if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ - File extStorageDir = Environment.getExternalStorageDirectory(); - if(extStorageDir != null) { - return new File(extStorageDir, "Hedgewars"); - } - } - return null; - } - } + private static class PreFroyoSDCardDir{ + public static File getDownloadPath(Context c){ + if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ + File extStorageDir = Environment.getExternalStorageDirectory(); + if(extStorageDir != null) { + return new File(extStorageDir, "Hedgewars"); + } + } + return null; + } + } - /** - * Return a File array with all the files from dirName - * @param c - * @param dirName - * @return - * @throws FileNotFoundException If the sdcard is not available or the subdirectory "dirName" does not exist - */ - public static File[] getFilesFromRelativeDir(Context c, String dirName) throws FileNotFoundException { - File f = getDataPathFile(c, dirName); + /** + * Return a File array with all the files from dirName + * @param c + * @param dirName + * @return + * @throws FileNotFoundException If the sdcard is not available or the subdirectory "dirName" does not exist + */ + public static File[] getFilesFromRelativeDir(Context c, String dirName) throws FileNotFoundException { + File f = getDataPathFile(c, dirName); - if(f.isDirectory()) { - return f.listFiles(); - } else { - throw new FileNotFoundException("Directory "+dirName+" does not exist."); - } - } + if(f.isDirectory()) { + return f.listFiles(); + } else { + throw new FileNotFoundException("Directory "+dirName+" does not exist."); + } + } - /** - * Checks if this directory has a file with suffix suffix - * @param f - directory - * @return - */ - public static boolean hasFileWithSuffix(File f, String suffix){ - if(f.isDirectory()){ - for(String s : f.list()){ - if(s.endsWith(suffix)) return true; - } - return false; - }else{ - return false; - } - } + /** + * Checks if this directory has a file with suffix suffix + * @param f - directory + * @return + */ + public static boolean hasFileWithSuffix(File f, String suffix){ + if(f.isDirectory()){ + for(String s : f.list()){ + if(s.endsWith(suffix)) return true; + } + return false; + }else{ + return false; + } + } - /** - * Gives back all dirs which contain a file with suffix fileSuffix - * @param c - * @param path - * @param fileSuffix - * @return - * @throws FileNotFoundException If the sdcard is not available or the subdirectory "path" does not exist - */ - public static List getDirsWithFileSuffix(Context c, String path, String fileSuffix) throws FileNotFoundException{ - File[] files = getFilesFromRelativeDir(c,path); - ArrayList ret = new ArrayList(); + /** + * Gives back all dirs which contain a file with suffix fileSuffix + * @param c + * @param path + * @param fileSuffix + * @return + * @throws FileNotFoundException If the sdcard is not available or the subdirectory "path" does not exist + */ + public static List getDirsWithFileSuffix(Context c, String path, String fileSuffix) throws FileNotFoundException{ + File[] files = getFilesFromRelativeDir(c,path); + ArrayList ret = new ArrayList(); - for(File f : files){ - if(hasFileWithSuffix(f, fileSuffix)) ret.add(f.getName()); - } - return ret; - } + for(File f : files){ + if(hasFileWithSuffix(f, fileSuffix)) ret.add(f.getName()); + } + return ret; + } - /** - * Get all files from directory dir which have the given suffix - * @throws FileNotFoundException If the sdcard is not available or the subdirectory "dir" does not exist - */ - public static List getFileNamesFromDirWithSuffix(Context c, String dir, String suffix, boolean removeSuffix) throws FileNotFoundException{ - File[] files = FileUtils.getFilesFromRelativeDir(c, dir); - List ret = new ArrayList(); - for(File file : files){ - String s = file.getName(); - if(s.endsWith(suffix)){ - if(removeSuffix) ret.add(s.substring(0, s.length()-suffix.length())); - else ret.add(s); - } - } - return ret; - } + /** + * Get all files from directory dir which have the given suffix + * @throws FileNotFoundException If the sdcard is not available or the subdirectory "dir" does not exist + */ + public static List getFileNamesFromDirWithSuffix(Context c, String dir, String suffix, boolean removeSuffix) throws FileNotFoundException{ + File[] files = FileUtils.getFilesFromRelativeDir(c, dir); + List ret = new ArrayList(); + for(File file : files){ + String s = file.getName(); + if(s.endsWith(suffix)){ + if(removeSuffix) ret.add(s.substring(0, s.length()-suffix.length())); + else ret.add(s); + } + } + return ret; + } + + /** + * Close a resource (possibly null), ignoring any IOException. + */ + public static void closeQuietly(Closeable c) { + if(c!=null) { + try { + c.close(); + } catch(IOException e) { + Log.w(TAG, e); + } + } + } + + /** + * Write all data from the input stream to the file, creating or overwriting it. + * The input stream will be closed. + * + * @throws IOException + */ + public static void writeStreamToFile(InputStream is, File file) throws IOException { + OutputStream os = null; + byte[] buffer = new byte[8192]; + try { + os = new FileOutputStream(file); + int size; + while((size=is.read(buffer)) != -1) { + os.write(buffer, 0, size); + } + os.close(); // Important to close this non-quietly, in case of exceptions when flushing + } finally { + FileUtils.closeQuietly(is); + FileUtils.closeQuietly(os); + } + } - /** - * Close a resource (possibly null), ignoring any IOException. - */ - public static void closeQuietly(Closeable c) { - if(c!=null) { - try { - c.close(); - } catch(IOException e) { - Log.w(TAG, e); - } - } - } - - /** - * Write all data from the input stream to the file, creating or overwriting it. - * The input stream will be closed. - * - * @throws IOException - */ - public static void writeStreamToFile(InputStream is, File file) throws IOException { - OutputStream os = null; - byte[] buffer = new byte[8192]; - try { - os = new FileOutputStream(file); - int size; - while((size=is.read(buffer)) != -1) { - os.write(buffer, 0, size); - } - os.close(); // Important to close this non-quietly, in case of exceptions when flushing - } finally { - FileUtils.closeQuietly(is); - FileUtils.closeQuietly(os); - } - } - - /** - * Moves resources pointed to by sourceResId (from @res/raw/) to the app's private data directory - * @param c - * @param sourceResId - * @param directory - */ - public static void resRawToFilesDir(Context c, int sourceResId, int targetFilenames, String directory) throws IOException { - File targetDir = new File(c.getFilesDir(), directory); - targetDir.mkdirs(); + /** + * Moves resources pointed to by sourceResId (from @res/raw/) to the app's private data directory + * @param c + * @param sourceResId + * @param directory + */ + public static void resRawToFilesDir(Context c, int sourceResId, int targetFilenames, String directory) throws IOException { + File targetDir = new File(c.getFilesDir(), directory); + targetDir.mkdirs(); + + //Get an array with the resource files ID + Resources resources = c.getResources(); + TypedArray ta = resources.obtainTypedArray(sourceResId); + TypedArray filenames = resources.obtainTypedArray(targetFilenames); + for(int i = 0; i < ta.length(); i++){ + int resId = ta.getResourceId(i, 0); + String fileName = filenames.getString(i); + File f = new File(targetDir, fileName); + writeStreamToFile(resources.openRawResource(resId), f); + } + } - //Get an array with the resource files ID - Resources resources = c.getResources(); - TypedArray ta = resources.obtainTypedArray(sourceResId); - TypedArray filenames = resources.obtainTypedArray(targetFilenames); - for(int i = 0; i < ta.length(); i++){ - int resId = ta.getResourceId(i, 0); - String fileName = filenames.getString(i); - File f = new File(targetDir, fileName); - writeStreamToFile(resources.openRawResource(resId), f); - } - } + public static String readToString(InputStream is) throws IOException { + try { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + byte[] buffer = new byte[8192]; + int size; + while((size=is.read(buffer)) != -1) { + os.write(buffer, 0, size); + } + return new String(os.toByteArray()); + } finally { + closeQuietly(is); + } + } + + private static final char[] badFilenameChars = new char[] { '/', '\\', ':', '*', '?', '\"', '<', '>', '|', '.', '\0' }; - public static String readToString(InputStream is) throws IOException { - try { - ByteArrayOutputStream os = new ByteArrayOutputStream(); - byte[] buffer = new byte[8192]; - int size; - while((size=is.read(buffer)) != -1) { - os.write(buffer, 0, size); - } - return new String(os.toByteArray()); - } finally { - closeQuietly(is); - } - } - - private static final char[] badFilenameChars = new char[] { '/', '\\', ':', '*', '?', '\"', '<', '>', '|', '.', '\0' }; - - /** - * Modify the given String so that it can be used as part of a filename - * without causing problems from illegal/special characters. - * - * The result should be similar to the input, but isn't necessarily - * reversible. - */ - public static String replaceBadChars(String name) { - if (name == null || name.trim().length()==0) { - return "_"; - } - name = name.trim(); - for (char badChar : badFilenameChars) { - name = name.replace(badChar, '_'); - } - return name; - } + /** + * Modify the given String so that it can be used as part of a filename + * without causing problems from illegal/special characters. + * + * The result should be similar to the input, but isn't necessarily + * reversible. + */ + public static String replaceBadChars(String name) { + if (name == null || name.trim().length()==0) { + return "_"; + } + name = name.trim(); + for (char badChar : badFilenameChars) { + name = name.replace(badChar, '_'); + } + return name; + } } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/ObjectUtils.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/ObjectUtils.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/ObjectUtils.java Tue Jan 21 22:43:06 2014 +0100 @@ -20,13 +20,13 @@ package org.hedgewars.hedgeroid.util; public final class ObjectUtils { - public static boolean equal(Object o1, Object o2) { - if(o1==o2) { - return true; - } else if(o1==null || o2 == null) { - return false; - } else { - return o1.equals(o2); - } - } + public static boolean equal(Object o1, Object o2) { + if(o1==o2) { + return true; + } else if(o1==null || o2 == null) { + return false; + } else { + return o1.equals(o2); + } + } } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/ObservableTreeMap.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/ObservableTreeMap.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/ObservableTreeMap.java Tue Jan 21 22:43:06 2014 +0100 @@ -26,37 +26,37 @@ import android.database.DataSetObservable; public class ObservableTreeMap extends DataSetObservable { - private final Map map = new TreeMap(); - - public void replaceContent(Map newMap) { - map.clear(); - map.putAll(newMap); - notifyChanged(); - } - - public void put(K key, V value) { - map.put(key, value); - notifyChanged(); - } - - public V get(K key) { - return map.get(key); - } - - public void remove(K key) { - if(map.remove(key) != null) { - notifyChanged(); - } - } - - public void clear() { - if(!map.isEmpty()) { - map.clear(); - notifyChanged(); - } - } - - public Map getMap() { - return Collections.unmodifiableMap(map); - } + private final Map map = new TreeMap(); + + public void replaceContent(Map newMap) { + map.clear(); + map.putAll(newMap); + notifyChanged(); + } + + public void put(K key, V value) { + map.put(key, value); + notifyChanged(); + } + + public V get(K key) { + return map.get(key); + } + + public void remove(K key) { + if(map.remove(key) != null) { + notifyChanged(); + } + } + + public void clear() { + if(!map.isEmpty()) { + map.clear(); + notifyChanged(); + } + } + + public Map getMap() { + return Collections.unmodifiableMap(map); + } } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/ObservableTreeMapAdapter.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/ObservableTreeMapAdapter.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/ObservableTreeMapAdapter.java Tue Jan 21 22:43:06 2014 +0100 @@ -28,67 +28,67 @@ import android.widget.BaseAdapter; public abstract class ObservableTreeMapAdapter extends BaseAdapter { - private boolean sourceChanged = true; - private List entries = new ArrayList(); - private ObservableTreeMap source; - - private DataSetObserver observer = new DataSetObserver() { - @Override - public void onChanged() { - sourceChanged = true; - notifyDataSetChanged(); - } - - @Override - public void onInvalidated() { - invalidate(); - } - }; - - abstract protected Comparator getEntryOrder(); - - protected List getEntries() { - if(sourceChanged) { - entries.clear(); - entries.addAll(source.getMap().values()); - Collections.sort(entries, getEntryOrder()); - sourceChanged = false; - } - return entries; - } - - public int getCount() { - return getEntries().size(); - } + private boolean sourceChanged = true; + private List entries = new ArrayList(); + private ObservableTreeMap source; + + private DataSetObserver observer = new DataSetObserver() { + @Override + public void onChanged() { + sourceChanged = true; + notifyDataSetChanged(); + } + + @Override + public void onInvalidated() { + invalidate(); + } + }; + + abstract protected Comparator getEntryOrder(); + + protected List getEntries() { + if(sourceChanged) { + entries.clear(); + entries.addAll(source.getMap().values()); + Collections.sort(entries, getEntryOrder()); + sourceChanged = false; + } + return entries; + } - public V getItem(int position) { - return getEntries().get(position); - } - - public long getItemId(int position) { - return position; - } - - @Override - public boolean hasStableIds() { - return false; - } - - public void setSource(ObservableTreeMap source) { - if(this.source != null) { - this.source.unregisterObserver(observer); - } - this.source = source; - this.source.registerObserver(observer); - sourceChanged = true; - notifyDataSetChanged(); - } - - public void invalidate() { - if(source != null) { - source.unregisterObserver(observer); - } - source = null; - notifyDataSetInvalidated(); - } + public int getCount() { + return getEntries().size(); + } + + public V getItem(int position) { + return getEntries().get(position); + } + + public long getItemId(int position) { + return position; + } + + @Override + public boolean hasStableIds() { + return false; + } + + public void setSource(ObservableTreeMap source) { + if(this.source != null) { + this.source.unregisterObserver(observer); + } + this.source = source; + this.source.registerObserver(observer); + sourceChanged = true; + notifyDataSetChanged(); + } + + public void invalidate() { + if(source != null) { + source.unregisterObserver(observer); + } + source = null; + notifyDataSetInvalidated(); + } } \ No newline at end of file diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/TextInputDialog.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/TextInputDialog.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/TextInputDialog.java Tue Jan 21 22:43:06 2014 +0100 @@ -36,113 +36,113 @@ * interface TextInputDialogListener, which will be called by the dialog if it is submitted or cancelled. */ public class TextInputDialog extends DialogFragment { - private static final String BUNDLE_DIALOG_ID = "dialogId"; - private static final String BUNDLE_TITLE_TEXT = "title"; - private static final String BUNDLE_MESSAGE_TEXT = "message"; - private static final String BUNDLE_HINT_TEXT = "hint"; - - private int dialogId, titleText, messageText, hintText; - private TextInputDialogListener listener; - - public interface TextInputDialogListener { - void onTextInputDialogSubmitted(int dialogId, String text); - void onTextInputDialogCancelled(int dialogId); - } - - /** - * The dialogId is only used for passing back to the callback on the activity, the - * other parameters are text resource IDs. Pass 0 for any of them to not use this - * text. - */ - public TextInputDialog(int dialogId, int titleText, int messageText, int hintText) { - this.dialogId = dialogId; - this.titleText = titleText; - this.messageText = messageText; - this.hintText = hintText; - } - - public TextInputDialog() { - // Only for reflection-based instantiation by the framework - } - - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - try { - listener = (TextInputDialogListener) activity; - } catch(ClassCastException e) { - throw new ClassCastException("Activity " + activity + " must implement TextInputDialogListener to use TextInputDialog."); - } - } - - @Override - public void onDetach() { - super.onDetach(); - listener = null; - } - - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - if(savedInstanceState != null) { - dialogId = savedInstanceState.getInt(BUNDLE_DIALOG_ID, dialogId); - titleText = savedInstanceState.getInt(BUNDLE_TITLE_TEXT, titleText); - messageText = savedInstanceState.getInt(BUNDLE_MESSAGE_TEXT, messageText); - hintText = savedInstanceState.getInt(BUNDLE_HINT_TEXT, hintText); - } - - final EditText editText = new EditText(getActivity()); - AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - - if(titleText != 0) { - builder.setTitle(titleText); - } - if(messageText != 0) { - builder.setTitle(messageText); - } - if(hintText != 0) { - editText.setHint(hintText); - } - - editText.setId(android.R.id.text1); - editText.setImeOptions(EditorInfo.IME_ACTION_DONE); - editText.setSingleLine(); + private static final String BUNDLE_DIALOG_ID = "dialogId"; + private static final String BUNDLE_TITLE_TEXT = "title"; + private static final String BUNDLE_MESSAGE_TEXT = "message"; + private static final String BUNDLE_HINT_TEXT = "hint"; + + private int dialogId, titleText, messageText, hintText; + private TextInputDialogListener listener; + + public interface TextInputDialogListener { + void onTextInputDialogSubmitted(int dialogId, String text); + void onTextInputDialogCancelled(int dialogId); + } + + /** + * The dialogId is only used for passing back to the callback on the activity, the + * other parameters are text resource IDs. Pass 0 for any of them to not use this + * text. + */ + public TextInputDialog(int dialogId, int titleText, int messageText, int hintText) { + this.dialogId = dialogId; + this.titleText = titleText; + this.messageText = messageText; + this.hintText = hintText; + } + + public TextInputDialog() { + // Only for reflection-based instantiation by the framework + } + + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + try { + listener = (TextInputDialogListener) activity; + } catch(ClassCastException e) { + throw new ClassCastException("Activity " + activity + " must implement TextInputDialogListener to use TextInputDialog."); + } + } + + @Override + public void onDetach() { + super.onDetach(); + listener = null; + } + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + if(savedInstanceState != null) { + dialogId = savedInstanceState.getInt(BUNDLE_DIALOG_ID, dialogId); + titleText = savedInstanceState.getInt(BUNDLE_TITLE_TEXT, titleText); + messageText = savedInstanceState.getInt(BUNDLE_MESSAGE_TEXT, messageText); + hintText = savedInstanceState.getInt(BUNDLE_HINT_TEXT, hintText); + } - builder.setView(editText); - builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - dialog.cancel(); - } - }); - - editText.setOnEditorActionListener(new OnEditorActionListener() { - public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { - listener.onTextInputDialogSubmitted(dialogId, v.getText().toString()); - dismiss(); - return true; - } - }); - - builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - listener.onTextInputDialogSubmitted(dialogId, editText.getText().toString()); - } - }); + final EditText editText = new EditText(getActivity()); + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + + if(titleText != 0) { + builder.setTitle(titleText); + } + if(messageText != 0) { + builder.setTitle(messageText); + } + if(hintText != 0) { + editText.setHint(hintText); + } + + editText.setId(android.R.id.text1); + editText.setImeOptions(EditorInfo.IME_ACTION_DONE); + editText.setSingleLine(); + + builder.setView(editText); + builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + dialog.cancel(); + } + }); - return builder.create(); - } - - @Override - public void onSaveInstanceState(Bundle icicle) { - super.onSaveInstanceState(icicle); - icicle.putInt(BUNDLE_DIALOG_ID, dialogId); - icicle.putInt(BUNDLE_TITLE_TEXT, titleText); - icicle.putInt(BUNDLE_MESSAGE_TEXT, messageText); - icicle.putInt(BUNDLE_HINT_TEXT, hintText); - } - - @Override - public void onCancel(DialogInterface dialog) { - super.onCancel(dialog); - listener.onTextInputDialogCancelled(dialogId); - } + editText.setOnEditorActionListener(new OnEditorActionListener() { + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + listener.onTextInputDialogSubmitted(dialogId, v.getText().toString()); + dismiss(); + return true; + } + }); + + builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + listener.onTextInputDialogSubmitted(dialogId, editText.getText().toString()); + } + }); + + return builder.create(); + } + + @Override + public void onSaveInstanceState(Bundle icicle) { + super.onSaveInstanceState(icicle); + icicle.putInt(BUNDLE_DIALOG_ID, dialogId); + icicle.putInt(BUNDLE_TITLE_TEXT, titleText); + icicle.putInt(BUNDLE_MESSAGE_TEXT, messageText); + icicle.putInt(BUNDLE_HINT_TEXT, hintText); + } + + @Override + public void onCancel(DialogInterface dialog) { + super.onCancel(dialog); + listener.onTextInputDialogCancelled(dialogId); + } } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/TickHandler.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/TickHandler.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/TickHandler.java Tue Jan 21 22:43:06 2014 +0100 @@ -32,42 +32,42 @@ * an immediate execution of the runnable again. */ public class TickHandler extends Handler { - private final Runnable callback; - private int messageId; - private long interval; - private boolean running; - - public TickHandler(Looper looper, long interval, Runnable callback) { - super(looper); - this.callback = callback; - this.interval = interval; - } - - public synchronized void stop() { - messageId++; - running = false; - } - - public synchronized void start() { - messageId++; - sendMessage(obtainMessage(messageId)); - running = true; - } - - public synchronized void setInterval(long interval) { - this.interval = interval; - if(running) { - start(); - } - } - - @Override - public synchronized void handleMessage(Message msg) { - if(msg.what == messageId) { - callback.run(); - } - if(msg.what == messageId) { - sendMessageDelayed(obtainMessage(messageId), interval); - } - } + private final Runnable callback; + private int messageId; + private long interval; + private boolean running; + + public TickHandler(Looper looper, long interval, Runnable callback) { + super(looper); + this.callback = callback; + this.interval = interval; + } + + public synchronized void stop() { + messageId++; + running = false; + } + + public synchronized void start() { + messageId++; + sendMessage(obtainMessage(messageId)); + running = true; + } + + public synchronized void setInterval(long interval) { + this.interval = interval; + if(running) { + start(); + } + } + + @Override + public synchronized void handleMessage(Message msg) { + if(msg.what == messageId) { + callback.run(); + } + if(msg.what == messageId) { + sendMessageDelayed(obtainMessage(messageId), interval); + } + } } \ No newline at end of file diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/UiUtils.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/UiUtils.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/UiUtils.java Tue Jan 21 22:43:06 2014 +0100 @@ -29,25 +29,25 @@ import android.widget.TextView; public final class UiUtils { - private UiUtils() { - throw new AssertionError("This class is not meant to be instantiated"); - } + private UiUtils() { + throw new AssertionError("This class is not meant to be instantiated"); + } - public static View createVerticalTabIndicator(TabHost tabHost, int label, int icon) { - LayoutInflater inflater = (LayoutInflater) tabHost.getContext() - .getSystemService(Context.LAYOUT_INFLATER_SERVICE); + public static View createVerticalTabIndicator(TabHost tabHost, int label, int icon) { + LayoutInflater inflater = (LayoutInflater) tabHost.getContext() + .getSystemService(Context.LAYOUT_INFLATER_SERVICE); - View view = inflater.inflate(R.layout.tab_indicator_vertical, - tabHost.getTabWidget(), false); + View view = inflater.inflate(R.layout.tab_indicator_vertical, + tabHost.getTabWidget(), false); - final TextView tv = (TextView) view.findViewById(R.id.title); - tv.setText(label); + final TextView tv = (TextView) view.findViewById(R.id.title); + tv.setText(label); - if (icon != 0) { - ImageView iconView = (ImageView) view.findViewById(R.id.icon); - iconView.setImageResource(icon); - } + if (icon != 0) { + ImageView iconView = (ImageView) view.findViewById(R.id.icon); + iconView.setImageResource(icon); + } - return view; - } + return view; + } } diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/jni.pas --- a/project_files/Android-build/jni.pas Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/jni.pas Tue Jan 21 22:43:06 2014 +0100 @@ -513,7 +513,7 @@ const curVM:PJavaVM=nil; curEnv:PJNIEnv=nil; - + (* function JNI_OnLoad(vm:PJavaVM;reserved:pointer):jint;{$ifdef mswindows}stdcall;{$else}cdecl;{$endif} procedure JNI_OnUnload(vm:PJavaVM;reserved:pointer);{$ifdef mswindows}stdcall;{$else}cdecl;{$endif} diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/log.pas --- a/project_files/Android-build/log.pas Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/log.pas Tue Jan 21 22:43:06 2014 +0100 @@ -22,7 +22,7 @@ function __android_log_write(prio:longint;tag,text:pchar):longint; cdecl; external libname name '__android_log_write'; //function __android_log_print(prio:longint;tag,print:pchar;params:array of pchar):longint; cdecl; external libname name '__android_log_print'; - + implementation end. diff -r 4feced261c68 -r de822cd3df3a project_files/HedgewarsMobile/Locale/Japanese.lproj/About.strings --- a/project_files/HedgewarsMobile/Locale/Japanese.lproj/About.strings Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/HedgewarsMobile/Locale/Japanese.lproj/About.strings Tue Jan 21 22:43:06 2014 +0100 @@ -1,44 +1,44 @@ -/* code credit */ -"Engine, frontend, net server" = "エンジン、フロントエンド、ネットサーバー"; -"Many desktop frontend improvements" = "多くのデスクトップフロントエンドの改善"; -"Many engine and desktop frontend improvements" = "多くのエンジンとデスクトップフロントエンドの改善"; -"Drillrocket, Ballgun, RC Plane weapons" = "ドリルロケット、ボールガン、ラジコン武器"; -"Mine number and time game settings" = "地雷番号とタイムゲーム設定"; -"Desktop frontend improvements" = "デスクトップフロントエンドの改善"; -"Desktop frontend improvements" = "デスクトップフロントエンドの改善"; -"Mac OS X and iPhone version" = "Mac OS X と iPhone バージョン"; -"Many engine and desktop frontend improvements" = "多くのエンジンとデスクトップフロントエンドの改善"; -"Gamepad and Lua integration" = "ゲームパッドとLuaの統合化"; -"Many engine improvements and graphics" = "多くのエンジン改善とグラフィック"; -"Maze maps" = "迷路地図"; -"Engine and desktop frontend improvements" = "エンジンとデスクトップフロントエンドの改善"; -"Lua game modes and missions" = "Lua ゲームモードとミッション"; -"Desktop frontend improvements" = "デスクトップフロントエンドの改善"; -"Android port" = "アンドロイドポート"; - -/* art credit */ -"Main graphics" = "メイングラフィック"; -"Some hats" = "帽子"; -"Hedgehogs voice" = "ハリネズミの声"; - -/* translation credit */ -"Brazilian Portuguese" = "ポルトガル語(ブラジル)"; -"Bulgarian" = "ブルガリア語"; -"Czech" = "チェコ語"; -"Chinese" = "中国語"; -"English" = "英語"; -"Finnish" = "フィンランド語"; -"French" = "フランス語"; -"German" = "ドイツ語"; -"Greek" = "ギリシャ語"; -"Italian" = "イタリア語"; -"Japanese" = "日本語"; -"Korean" = "韓国語"; -"Lithuanian" = "リトアニア語"; -"Polish" = "ポーランド語"; -"Portuguese" = "ポルトガル語"; -"Russian" = "ロシア語"; -"Slovak" = "スロバキア語"; -"Spanish" = "スペイン語"; -"Swedish" = "スウェーデン語"; -"Ukrainian" = "ウクライナ語"; +/* code credit */ +"Engine, frontend, net server" = "エンジン、フロントエンド、ネットサーバー"; +"Many desktop frontend improvements" = "多くのデスクトップフロントエンドの改善"; +"Many engine and desktop frontend improvements" = "多くのエンジンとデスクトップフロントエンドの改善"; +"Drillrocket, Ballgun, RC Plane weapons" = "ドリルロケット、ボールガン、ラジコン武器"; +"Mine number and time game settings" = "地雷番号とタイムゲーム設定"; +"Desktop frontend improvements" = "デスクトップフロントエンドの改善"; +"Desktop frontend improvements" = "デスクトップフロントエンドの改善"; +"Mac OS X and iPhone version" = "Mac OS X と iPhone バージョン"; +"Many engine and desktop frontend improvements" = "多くのエンジンとデスクトップフロントエンドの改善"; +"Gamepad and Lua integration" = "ゲームパッドとLuaの統合化"; +"Many engine improvements and graphics" = "多くのエンジン改善とグラフィック"; +"Maze maps" = "迷路地図"; +"Engine and desktop frontend improvements" = "エンジンとデスクトップフロントエンドの改善"; +"Lua game modes and missions" = "Lua ゲームモードとミッション"; +"Desktop frontend improvements" = "デスクトップフロントエンドの改善"; +"Android port" = "アンドロイドポート"; + +/* art credit */ +"Main graphics" = "メイングラフィック"; +"Some hats" = "帽子"; +"Hedgehogs voice" = "ハリネズミの声"; + +/* translation credit */ +"Brazilian Portuguese" = "ポルトガル語(ブラジル)"; +"Bulgarian" = "ブルガリア語"; +"Czech" = "チェコ語"; +"Chinese" = "中国語"; +"English" = "英語"; +"Finnish" = "フィンランド語"; +"French" = "フランス語"; +"German" = "ドイツ語"; +"Greek" = "ギリシャ語"; +"Italian" = "イタリア語"; +"Japanese" = "日本語"; +"Korean" = "韓国語"; +"Lithuanian" = "リトアニア語"; +"Polish" = "ポーランド語"; +"Portuguese" = "ポルトガル語"; +"Russian" = "ロシア語"; +"Slovak" = "スロバキア語"; +"Spanish" = "スペイン語"; +"Swedish" = "スウェーデン語"; +"Ukrainian" = "ウクライナ語"; diff -r 4feced261c68 -r de822cd3df3a project_files/HedgewarsMobile/Locale/Japanese.lproj/Localizable.strings --- a/project_files/HedgewarsMobile/Locale/Japanese.lproj/Localizable.strings Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/HedgewarsMobile/Locale/Japanese.lproj/Localizable.strings Tue Jan 21 22:43:06 2014 +0100 @@ -1,380 +1,380 @@ -/* No comment provided by engineer. */ -"A monitor has been disconnected while playing and this has ended the match! You need to restart the game if you wish to use the second display again." = "モニターの接続が切断され、マッチを終了してしまいました!二番目のディスプレーをまた使用したい場合はゲームをリスタートしなければいけません。"; - -/* from the scheme panel - from the team panel */ -"Add" = "追加"; - -/* No comment provided by engineer. */ -"Aggressive" = "積極的"; - -/* No comment provided by engineer. */ -"All" = "全て"; - -/* from the settings table */ -"Alternate Damage" = "代わりのダメージ"; - -/* No comment provided by engineer. */ -"Are you reeeeeally sure?" = "本当にいいですか?"; - -/* from the settings table */ -"Audio Preferences" = "オーディオ設定"; - -/* No comment provided by engineer. */ -"Available Teams" = "利用可能なチーム"; - -/* No comment provided by engineer. */ -"Average" = "平均"; - -/* No comment provided by engineer. */ -"Backup" = "バックアップ"; - -/* No comment provided by engineer. */ -"Before playing the preview needs to be generated" = "プレーする前にプレビューを生成する必要があります"; - -/* No comment provided by engineer. */ -"Before returning the preview needs to be generated" = "戻る前にプレビューを生成する必要があります"; - -/* No comment provided by engineer. */ -"Brutal" = "残忍"; - -/* No comment provided by engineer. */ -"Bully" = "いじめっ子"; - -/* No comment provided by engineer. */ -"Cancel" = "キャンセル"; - -/* No comment provided by engineer. */ -"Cavern" = "洞窟"; - -/* No comment provided by engineer. */ -"Change hedgehogs' hat" = "ハリネズミの帽子を変える"; - -/* No comment provided by engineer. */ -"Chat with the devs in IRC" = "IRC でデベロッパ達とチャットする"; - -/* No comment provided by engineer. */ -"Choose a charismatic symbol for your team" = "チームのためのカリスマ的なシンボルを選択する"; - -/* No comment provided by engineer. */ -"Choose hedgehog graves" = "ハリネズミの墓を選択する"; - -/* No comment provided by engineer. */ -"Choose team fort" = "チームの砦を選択する"; - -/* from the settings table */ -"Choosing a Scheme will select its associated Weapon" = "スキームを選択すると関連した武器を選択します。"; - -/* No comment provided by engineer. */ -"Classic Ammo Menu" = "クラシックな弾薬メニュー"; - -/* No comment provided by engineer. */ -"Community" = "コミュニティー"; - -/* from the settings table */ -"Damage popups will notify you on every single hit" = "ダメージポップアップはすべてのヒットを通知してくれます。"; - -/* from the scheme panel - from the team panel */ -"Done" = "終了"; - -/* from the scheme panel - from the team panel */ -"Edit" = "編集"; - -/* No comment provided by engineer. */ -"Edit scheme preferences" = "スキーム設定を編集"; - -/* No comment provided by engineer. */ -"Edit team settings" = "チーム設定を編集"; - -/* No comment provided by engineer. */ -"Edit weapons preferences" = "武器設定を編集"; - -/* No comment provided by engineer. */ -"End Game" = "ゲームを終了する"; - -/* No comment provided by engineer. */ -"Flag" = "フラグ"; - -/* No comment provided by engineer. */ -"Follow us on Twitter" = "ツイッターでフォローする"; - -/* No comment provided by engineer. */ -"Fort" = "砦"; - -/* No comment provided by engineer. */ -"Game Modifiers" = "ゲームの変更"; - -/* No comment provided by engineer. */ -"Game Settings" = "ゲームの設定"; - -/* No comment provided by engineer. */ -"General" = "一般"; - -/* No comment provided by engineer. */ -"Grave" = "墓"; - -/* No comment provided by engineer. */ -"Hedgewars supports multi-monitor configurations, but the screen has to be connected before launching the game." = "Hedgewarsはマルチモニター設定をサポートしていますが、スクリーンはゲームをスタートする前に接続されていなければいけません。"; - -/* No comment provided by engineer. */ -"Hogs controlled by AI" = "AIにコントロールされたハリネズミ"; - -/* No comment provided by engineer. */ -"Hold your finger on a weapon to see what it does.\nTap anywhere to dismiss." = "武器の上でホールドして何をするか見る。\nほかの部分をタップして閉じる。"; - -/* No comment provided by engineer. */ -"Hold your finger on a weapon to see what it does.\nYou can move this window anywhere on the screen." = "武器の上でホールドして何をするか見る。\nこのウィンドウはスクリーンのどこにでも動かすことができます。"; - -/* ammo selection */ -"Initial quantity " = "初期量"; - -/* from the settings table */ -"Insert your password" = "パスワードを入力"; - -/* from the settings table */ -"Insert your username (if you have one)" = "ユーザーネームを入力 (持っていた場合)"; - -/* No comment provided by engineer. */ -"Join us on Facebook" = "Facebookで参加する"; - -/* No comment provided by engineer. */ -"Large" = "大きな"; - -/* No comment provided by engineer. */ -"Large Floating Islands" = "大きな浮き島"; - -/* No comment provided by engineer. */ -"Large Tunnels" = "大きなトンネル"; - -/* No comment provided by engineer. */ -"Leave a positive review on iTunes!" = "iTunesでポジティブなレビューを残す!"; - -/* No comment provided by engineer. */ -"Level" = "レベル"; - -/* No comment provided by engineer. */ -"Loading..." = "ロード中..."; - -/* from the settings table */ -"Main Configuration" = "メイン設定"; - -/* No comment provided by engineer. */ -"Mark the death of your fallen warriors" = "あなたの倒れた戦士の死をマーク"; - -/* No comment provided by engineer. */ -"Max Hogs:" = "ハリネズミの最大数:"; - -/* No comment provided by engineer. */ -"Medium" = "中くらい"; - -/* No comment provided by engineer. */ -"Medium Floating Islands" = "中くらいの浮き島"; - -/* No comment provided by engineer. */ -"Medium Tunnels" = "中くらいのトンネル"; - -/* No comment provided by engineer. */ -"Missing detail" = "詳細が抜けています"; - -/* No comment provided by engineer. */ -"Missions don't need further configuration" = "ミッションはこれ以上の設定を必要としません"; - -/* from the settings table */ -"Music" = "音楽"; - -/* No comment provided by engineer. */ -"Names and Hats" = "ネームと帽子"; - -/* from the settings table */ -"Nickname" = "ニックネーム"; - -/* No comment provided by engineer. */ -"No filter" = "フィルターなし"; - -/* No comment provided by engineer. */ -"No thanks" = "遠慮します"; - -/* ammo selection */ -"Number of turns before you can use this weapon " = "この武器を使えるようになるまでのターン数"; - -/* Short for 'Never' */ -"Nvr" = "絶対にない"; - -/* No comment provided by engineer. */ -"Of course!" = "もちろん!"; - -/* No comment provided by engineer. */ -"Ok, got it" = "Ok, わかった"; - -/* No comment provided by engineer. */ -"Opt for controlling the team or let the AI lead" = "チームをコントロールするかAIをリードさせる"; - -/* from the settings table */ -"Other Settings" = "ほかの設定"; - -/* from the settings table */ -"Password" = "パスワード"; - -/* No comment provided by engineer. */ -"Pick a slang your hogs will speak" = "あなたのハリネズミが話すスラングを選択"; - -/* No comment provided by engineer. */ -"Playing Teams" = "プレー中のチーム"; - -/* ammo selection */ -"Presence probability in crates " = "クレートの中の存在確率"; - -/* No comment provided by engineer. */ -"Press to resume playing or swipe to delete the save file." = "押してプレーを再開するか、スワイプしてセーブファイルを削除。"; - -/* No comment provided by engineer. */ -"Preview not available" = "プレビューが利用できません"; - -/* ammo selection */ -"Quantity that you will find in a crate " = "クレーとの中で見つかる量"; - -/* No comment provided by engineer. */ -"Remind me later" = "後で連絡"; - -/* Short for 'Random' */ -"Rnd" = "ランダム"; - -/* No comment provided by engineer. */ -"Save" = "保存"; - -/* No comment provided by engineer. */ -"Scheme" = "スキーム"; - -/* No comment provided by engineer. */ -"Scheme mismatch" = "スキームミスマッチ"; - -/* No comment provided by engineer. */ -"Scheme Name" = "スキーム名"; - -/* No comment provided by engineer. */ -"Schemes" = "スキーム"; - -/* No comment provided by engineer. */ -"Select at least two teams to play a game" = "ゲームをプレーするには最低二チーム選択してください。"; - -/* No comment provided by engineer. */ -"Select one Scheme and one Weapon for this game" = "このゲームのためにスキームと武器を一つずつ選択してください。"; - -/* No comment provided by engineer. */ -"Select the team invincible fortress (only valid for fort games)" = "無敵砦のチームを選択する (砦ゲームのみ有効)"; - -/* from the settings table */ -"Select which style of ammo menu you prefer" = "弾薬メニューのスタイルを選択してください"; - -/* No comment provided by engineer. */ -"Set difficulty level" = "難易度レベルをセットする"; - -/* No comment provided by engineer. */ -"Set hedgehog voices" = "ハリネズミの声をセットする"; - -/* No comment provided by engineer. */ -"Set team flag" = "チームフラグをセットする"; - -/* on the overlay */ -"Set!" = "セット!"; - -/* No comment provided by engineer. */ -"Show Help" = "ヘルプを表示する"; - -/* No comment provided by engineer. */ -"Small" = "小さい"; - -/* No comment provided by engineer. */ -"Small Floating Islands" = "小さな浮き島"; - -/* No comment provided by engineer. */ -"Small Tunnels" = "小さなトンネル"; - -/* from the settings table */ -"Sound" = "サウンド"; - -/* No comment provided by engineer. */ -"Style" = "スタイル"; - -/* No comment provided by engineer. */ -"Support" = "サポート"; - -/* No comment provided by engineer. */ -"Sync Schemes and Weapons" = "スキームと武器を同期する"; - -/* No comment provided by engineer. */ -"Tag" = "タグ"; - -/* No comment provided by engineer. */ -"Tap to add hogs or change color, touch and hold to remove a team." = "ハリネズミを追加するか色を変更するにはタップ、チームを取り除くにはタッチしてホールドしてください。"; - -/* No comment provided by engineer. */ -"Team Name" = "チーム名"; - -/* No comment provided by engineer. */ -"Team Preferences" = "チーム設定"; - -/* No comment provided by engineer. */ -"Teams" = "チーム"; - -/* No comment provided by engineer. */ -"The map is too small for that many hogs" = "このマップはこれだけのハリネズミには小さすぎます。"; - -/* No comment provided by engineer. */ -"The robot badge indicates an AI-controlled team." = "ロボットバッジはAIがコントロールするチームを指します。"; - -/* No comment provided by engineer. */ -"The scheme you selected allows only for two teams" = "選択したスキームは二チーム用です。"; - -/* No comment provided by engineer. */ -"This weapon is locked" = "この武器はロックされています"; - -/* No comment provided by engineer. */ -"Too few teams playing" = "プレーしているチームが少なすぎます"; - -/* No comment provided by engineer. */ -"Too many hogs" = "ハリネズミが多すぎます"; - -/* No comment provided by engineer. */ -"Too many teams" = "チームが多すぎます"; - -/* No comment provided by engineer. */ -"Visit our website" = "ウェブサイトを見る"; - -/* No comment provided by engineer. */ -"Voice" = "音量"; - -/* No comment provided by engineer. */ -"Wacky" = "奇抜"; - -/* No comment provided by engineer. */ -"Wait for the Preview" = "プレビューを待つ"; - -/* No comment provided by engineer. */ -"Weaky" = "弱い者"; - -/* No comment provided by engineer. */ -"Weapon" = "武器"; - -/* No comment provided by engineer. */ -"Weapon Ammuntions" = "武器弾薬"; - -/* No comment provided by engineer. */ -"Weapons" = "武器"; - -/* No comment provided by engineer. */ -"Weaponset Name" = "武器セット名"; - -/* No comment provided by engineer. */ -"Well, maybe not..." = "まあ、そうでないかもしれません..."; - -/* No comment provided by engineer. */ -"Worldwide" = "ワールドワイド"; - -/* No comment provided by engineer. */ -"You can add a description if you wish" = "お望みなら説明を追加することができます。"; - -/* No comment provided by engineer. */ +/* No comment provided by engineer. */ +"A monitor has been disconnected while playing and this has ended the match! You need to restart the game if you wish to use the second display again." = "モニターの接続が切断され、マッチを終了してしまいました!二番目のディスプレーをまた使用したい場合はゲームをリスタートしなければいけません。"; + +/* from the scheme panel + from the team panel */ +"Add" = "追加"; + +/* No comment provided by engineer. */ +"Aggressive" = "積極的"; + +/* No comment provided by engineer. */ +"All" = "全て"; + +/* from the settings table */ +"Alternate Damage" = "代わりのダメージ"; + +/* No comment provided by engineer. */ +"Are you reeeeeally sure?" = "本当にいいですか?"; + +/* from the settings table */ +"Audio Preferences" = "オーディオ設定"; + +/* No comment provided by engineer. */ +"Available Teams" = "利用可能なチーム"; + +/* No comment provided by engineer. */ +"Average" = "平均"; + +/* No comment provided by engineer. */ +"Backup" = "バックアップ"; + +/* No comment provided by engineer. */ +"Before playing the preview needs to be generated" = "プレーする前にプレビューを生成する必要があります"; + +/* No comment provided by engineer. */ +"Before returning the preview needs to be generated" = "戻る前にプレビューを生成する必要があります"; + +/* No comment provided by engineer. */ +"Brutal" = "残忍"; + +/* No comment provided by engineer. */ +"Bully" = "いじめっ子"; + +/* No comment provided by engineer. */ +"Cancel" = "キャンセル"; + +/* No comment provided by engineer. */ +"Cavern" = "洞窟"; + +/* No comment provided by engineer. */ +"Change hedgehogs' hat" = "ハリネズミの帽子を変える"; + +/* No comment provided by engineer. */ +"Chat with the devs in IRC" = "IRC でデベロッパ達とチャットする"; + +/* No comment provided by engineer. */ +"Choose a charismatic symbol for your team" = "チームのためのカリスマ的なシンボルを選択する"; + +/* No comment provided by engineer. */ +"Choose hedgehog graves" = "ハリネズミの墓を選択する"; + +/* No comment provided by engineer. */ +"Choose team fort" = "チームの砦を選択する"; + +/* from the settings table */ +"Choosing a Scheme will select its associated Weapon" = "スキームを選択すると関連した武器を選択します。"; + +/* No comment provided by engineer. */ +"Classic Ammo Menu" = "クラシックな弾薬メニュー"; + +/* No comment provided by engineer. */ +"Community" = "コミュニティー"; + +/* from the settings table */ +"Damage popups will notify you on every single hit" = "ダメージポップアップはすべてのヒットを通知してくれます。"; + +/* from the scheme panel + from the team panel */ +"Done" = "終了"; + +/* from the scheme panel + from the team panel */ +"Edit" = "編集"; + +/* No comment provided by engineer. */ +"Edit scheme preferences" = "スキーム設定を編集"; + +/* No comment provided by engineer. */ +"Edit team settings" = "チーム設定を編集"; + +/* No comment provided by engineer. */ +"Edit weapons preferences" = "武器設定を編集"; + +/* No comment provided by engineer. */ +"End Game" = "ゲームを終了する"; + +/* No comment provided by engineer. */ +"Flag" = "フラグ"; + +/* No comment provided by engineer. */ +"Follow us on Twitter" = "ツイッターでフォローする"; + +/* No comment provided by engineer. */ +"Fort" = "砦"; + +/* No comment provided by engineer. */ +"Game Modifiers" = "ゲームの変更"; + +/* No comment provided by engineer. */ +"Game Settings" = "ゲームの設定"; + +/* No comment provided by engineer. */ +"General" = "一般"; + +/* No comment provided by engineer. */ +"Grave" = "墓"; + +/* No comment provided by engineer. */ +"Hedgewars supports multi-monitor configurations, but the screen has to be connected before launching the game." = "Hedgewarsはマルチモニター設定をサポートしていますが、スクリーンはゲームをスタートする前に接続されていなければいけません。"; + +/* No comment provided by engineer. */ +"Hogs controlled by AI" = "AIにコントロールされたハリネズミ"; + +/* No comment provided by engineer. */ +"Hold your finger on a weapon to see what it does.\nTap anywhere to dismiss." = "武器の上でホールドして何をするか見る。\nほかの部分をタップして閉じる。"; + +/* No comment provided by engineer. */ +"Hold your finger on a weapon to see what it does.\nYou can move this window anywhere on the screen." = "武器の上でホールドして何をするか見る。\nこのウィンドウはスクリーンのどこにでも動かすことができます。"; + +/* ammo selection */ +"Initial quantity " = "初期量"; + +/* from the settings table */ +"Insert your password" = "パスワードを入力"; + +/* from the settings table */ +"Insert your username (if you have one)" = "ユーザーネームを入力 (持っていた場合)"; + +/* No comment provided by engineer. */ +"Join us on Facebook" = "Facebookで参加する"; + +/* No comment provided by engineer. */ +"Large" = "大きな"; + +/* No comment provided by engineer. */ +"Large Floating Islands" = "大きな浮き島"; + +/* No comment provided by engineer. */ +"Large Tunnels" = "大きなトンネル"; + +/* No comment provided by engineer. */ +"Leave a positive review on iTunes!" = "iTunesでポジティブなレビューを残す!"; + +/* No comment provided by engineer. */ +"Level" = "レベル"; + +/* No comment provided by engineer. */ +"Loading..." = "ロード中..."; + +/* from the settings table */ +"Main Configuration" = "メイン設定"; + +/* No comment provided by engineer. */ +"Mark the death of your fallen warriors" = "あなたの倒れた戦士の死をマーク"; + +/* No comment provided by engineer. */ +"Max Hogs:" = "ハリネズミの最大数:"; + +/* No comment provided by engineer. */ +"Medium" = "中くらい"; + +/* No comment provided by engineer. */ +"Medium Floating Islands" = "中くらいの浮き島"; + +/* No comment provided by engineer. */ +"Medium Tunnels" = "中くらいのトンネル"; + +/* No comment provided by engineer. */ +"Missing detail" = "詳細が抜けています"; + +/* No comment provided by engineer. */ +"Missions don't need further configuration" = "ミッションはこれ以上の設定を必要としません"; + +/* from the settings table */ +"Music" = "音楽"; + +/* No comment provided by engineer. */ +"Names and Hats" = "ネームと帽子"; + +/* from the settings table */ +"Nickname" = "ニックネーム"; + +/* No comment provided by engineer. */ +"No filter" = "フィルターなし"; + +/* No comment provided by engineer. */ +"No thanks" = "遠慮します"; + +/* ammo selection */ +"Number of turns before you can use this weapon " = "この武器を使えるようになるまでのターン数"; + +/* Short for 'Never' */ +"Nvr" = "絶対にない"; + +/* No comment provided by engineer. */ +"Of course!" = "もちろん!"; + +/* No comment provided by engineer. */ +"Ok, got it" = "Ok, わかった"; + +/* No comment provided by engineer. */ +"Opt for controlling the team or let the AI lead" = "チームをコントロールするかAIをリードさせる"; + +/* from the settings table */ +"Other Settings" = "ほかの設定"; + +/* from the settings table */ +"Password" = "パスワード"; + +/* No comment provided by engineer. */ +"Pick a slang your hogs will speak" = "あなたのハリネズミが話すスラングを選択"; + +/* No comment provided by engineer. */ +"Playing Teams" = "プレー中のチーム"; + +/* ammo selection */ +"Presence probability in crates " = "クレートの中の存在確率"; + +/* No comment provided by engineer. */ +"Press to resume playing or swipe to delete the save file." = "押してプレーを再開するか、スワイプしてセーブファイルを削除。"; + +/* No comment provided by engineer. */ +"Preview not available" = "プレビューが利用できません"; + +/* ammo selection */ +"Quantity that you will find in a crate " = "クレーとの中で見つかる量"; + +/* No comment provided by engineer. */ +"Remind me later" = "後で連絡"; + +/* Short for 'Random' */ +"Rnd" = "ランダム"; + +/* No comment provided by engineer. */ +"Save" = "保存"; + +/* No comment provided by engineer. */ +"Scheme" = "スキーム"; + +/* No comment provided by engineer. */ +"Scheme mismatch" = "スキームミスマッチ"; + +/* No comment provided by engineer. */ +"Scheme Name" = "スキーム名"; + +/* No comment provided by engineer. */ +"Schemes" = "スキーム"; + +/* No comment provided by engineer. */ +"Select at least two teams to play a game" = "ゲームをプレーするには最低二チーム選択してください。"; + +/* No comment provided by engineer. */ +"Select one Scheme and one Weapon for this game" = "このゲームのためにスキームと武器を一つずつ選択してください。"; + +/* No comment provided by engineer. */ +"Select the team invincible fortress (only valid for fort games)" = "無敵砦のチームを選択する (砦ゲームのみ有効)"; + +/* from the settings table */ +"Select which style of ammo menu you prefer" = "弾薬メニューのスタイルを選択してください"; + +/* No comment provided by engineer. */ +"Set difficulty level" = "難易度レベルをセットする"; + +/* No comment provided by engineer. */ +"Set hedgehog voices" = "ハリネズミの声をセットする"; + +/* No comment provided by engineer. */ +"Set team flag" = "チームフラグをセットする"; + +/* on the overlay */ +"Set!" = "セット!"; + +/* No comment provided by engineer. */ +"Show Help" = "ヘルプを表示する"; + +/* No comment provided by engineer. */ +"Small" = "小さい"; + +/* No comment provided by engineer. */ +"Small Floating Islands" = "小さな浮き島"; + +/* No comment provided by engineer. */ +"Small Tunnels" = "小さなトンネル"; + +/* from the settings table */ +"Sound" = "サウンド"; + +/* No comment provided by engineer. */ +"Style" = "スタイル"; + +/* No comment provided by engineer. */ +"Support" = "サポート"; + +/* No comment provided by engineer. */ +"Sync Schemes and Weapons" = "スキームと武器を同期する"; + +/* No comment provided by engineer. */ +"Tag" = "タグ"; + +/* No comment provided by engineer. */ +"Tap to add hogs or change color, touch and hold to remove a team." = "ハリネズミを追加するか色を変更するにはタップ、チームを取り除くにはタッチしてホールドしてください。"; + +/* No comment provided by engineer. */ +"Team Name" = "チーム名"; + +/* No comment provided by engineer. */ +"Team Preferences" = "チーム設定"; + +/* No comment provided by engineer. */ +"Teams" = "チーム"; + +/* No comment provided by engineer. */ +"The map is too small for that many hogs" = "このマップはこれだけのハリネズミには小さすぎます。"; + +/* No comment provided by engineer. */ +"The robot badge indicates an AI-controlled team." = "ロボットバッジはAIがコントロールするチームを指します。"; + +/* No comment provided by engineer. */ +"The scheme you selected allows only for two teams" = "選択したスキームは二チーム用です。"; + +/* No comment provided by engineer. */ +"This weapon is locked" = "この武器はロックされています"; + +/* No comment provided by engineer. */ +"Too few teams playing" = "プレーしているチームが少なすぎます"; + +/* No comment provided by engineer. */ +"Too many hogs" = "ハリネズミが多すぎます"; + +/* No comment provided by engineer. */ +"Too many teams" = "チームが多すぎます"; + +/* No comment provided by engineer. */ +"Visit our website" = "ウェブサイトを見る"; + +/* No comment provided by engineer. */ +"Voice" = "音量"; + +/* No comment provided by engineer. */ +"Wacky" = "奇抜"; + +/* No comment provided by engineer. */ +"Wait for the Preview" = "プレビューを待つ"; + +/* No comment provided by engineer. */ +"Weaky" = "弱い者"; + +/* No comment provided by engineer. */ +"Weapon" = "武器"; + +/* No comment provided by engineer. */ +"Weapon Ammuntions" = "武器弾薬"; + +/* No comment provided by engineer. */ +"Weapons" = "武器"; + +/* No comment provided by engineer. */ +"Weaponset Name" = "武器セット名"; + +/* No comment provided by engineer. */ +"Well, maybe not..." = "まあ、そうでないかもしれません..."; + +/* No comment provided by engineer. */ +"Worldwide" = "ワールドワイド"; + +/* No comment provided by engineer. */ +"You can add a description if you wish" = "お望みなら説明を追加することができます。"; + +/* No comment provided by engineer. */ "You exceeded the maximum number of tems allowed in a game" = "ゲームで許可されているチームの最大数を超しました。"; \ No newline at end of file diff -r 4feced261c68 -r de822cd3df3a project_files/HedgewarsMobile/Locale/Japanese.lproj/Scheme.strings --- a/project_files/HedgewarsMobile/Locale/Japanese.lproj/Scheme.strings Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/HedgewarsMobile/Locale/Japanese.lproj/Scheme.strings Tue Jan 21 22:43:06 2014 +0100 @@ -1,194 +1,194 @@ -/* game mod description */ -"Land can not be destroyed" = "土地は破壊することができません"; - -/* game mod title */ -"Solid Land" = "固形の土地"; - -/* game mod description */ -"Add an indestructable border around the terrain" = "地形の周りに破壊できないボーダーを追加する"; - -/* game mod title */ -"Add Border" = "ボーダーを追加する"; - -/* game mod description */ -"Teams will start on opposite sides of the terrain" = "チームは地形の反対側からスタート思案す"; - -/* game mod title */ -"Divide Team (max 2 teams)" = "チームを分ける (最大二チーム)"; - -/* game mod description */ -"Lower gravity" = "低い重力"; - -/* game mod title */ -"Low Gravity" = "低重力"; - -/* game mod description */ -"Assisted aiming with laser sight" = "レーザーサイトで狙いの補助"; - -/* game mod title */ -"Laser Sight" = "レーザーサイト"; - -/* game mod description */ -"All hogs have a personal forcefield" = "全てのハリネズミは自分の力場を持っています"; - -/* game mod title */ -"Invulnerable" = "無敵"; - -/* game mod description */ -"All (living) hedgehogs are fully restored at the end of turn" = "全ての (生きている) ハリネズミの体力はターン終了時に完全に復元されます"; - -/* game mod title */ -"Reset Health" = "体力をリセット"; - -/* game mod description */ -"Gain 80% of the damage you do back in health" = "ダメージの80% を体力としてもらう"; - -/* game mod title */ -"Vampirism Mode" = "吸血モード"; - -/* game mod description */ -"Share your opponents pain, share their damage" = "相手の痛みを共有し、 ダメージを共有する"; - -/* game mod title */ -"Karma Mode" = "カルマモード"; - -/* game mod description */ -"Your hogs are unable to move, test your aim" = "あなたのハリネズミは動けない, 狙いを試せ"; - -/* game mod title */ -"Artillery Mode" = "砲兵モード"; - -/* game mod description */ -"Defend your fort and destroy the opponents" = "砦を守って相手を潰せ"; - -/* game mod title */ -"Fort Mode" = "砦モード"; - -/* game mod description */ -"Order of play is random instead of in room order" = "プレー順はルーム順ではなくランダムです"; - -/* game mod title */ -"Random Order" = "ランダムオーダー"; - -/* game mod description */ -"Play with a King; when he dies, your side loses" = "キングとプレーする; キングが死ぬと、あなたの負けです"; - -/* game mod title */ -"King Mode" = "キングモード"; - -/* game mod description */ -"Take turns placing your hedgehogs pre-game" = "ゲームの前にターンを取ってハリネズミを置く"; - -/* game mod title */ -"Place Hedgehogs" = "ハリネズミを置く"; - -/* game mod description */ -"Ammo is shared between all clan teams" = "弾薬は全ての一族チームの間で共有されます"; - -/* game mod title */ -"Clan Shares Ammo" = "一族は弾薬を共有します"; - -/* game mod description */ -"Disable girders when generating random maps" = "ランダムマップを作成するときはガードを無効にする"; - -/* game mod title */ -"Disable Girders" = "ガードを無効にする"; - -/* game mod description */ -"Disable land objects when generating maps" = "マップ作成中は土地のオブジェクトを無効にする"; - -/* game mod title */ -"Disable Land Objects" = "土地のオブジェクトを無効にする"; - -/* game mod description */ -"AI-controlled hogs respawn on death" = "AIがコントロールするハリネズミは死ぬと再出現します"; - -/* game mod title */ -"AI Survival Mode" = "AI サバイバルモード"; - -/* game mod description */ -"Attacking does not end your turn" = "攻撃してもターンは終了しません"; - -/* game mod title */ -"Unlimited Attacks" = "無限攻撃"; - -/* game mod description */ -"Weapons are reset to starting values each turn" = "武器は毎ターン初期値にリセットされます"; - -/* game mod title */ -"Reset Weapons" = "武器をリセット"; - -/* game mod description */ -"Each hedgehog has its own ammo" = "各ハリネズミが自分の弾薬を持っています"; - -/* game mod title */ -"Per Hedgehog Ammo" = "ハリネズミあたりの弾薬"; - -/* game mod description */ -"You will not have to worry about wind any more" = "風のことは気にせずに良くなります"; - -/* game mod title */ -"Disable Wind" = "風を無効にする"; - -/* game mod description */ -"Wind will affect almost everything" = "風はほとんどのものに影響します"; - -/* game mod title */ -"More Wind" = "より強い風"; - -/* game mod description */ -"Clan teams take turns sharing their time" = "一族のチームはタイムを共有してターンを取ります"; - -/* game mod title */ -"Tag Team" = "タッグチーム"; - -/* game mod description */ -"Add an indestructible border along the bottom" = "破壊できないボーダーを下に追加する"; - -/* game mod title */ -"Bottom Border" = "ボトムボーダー"; - - -/* flag description */ -"Initial Health" = "初期体力"; - -/* flag description */ -"Damage Modifier" = "ダメージ変更"; - -/* flag description */ -"Turn Time" = "ターンタイム"; -/* flag description */ -"Sudden Death Timeout" = "サデン・デス タイムアウト"; - -/* flag description */ -"Water Rise Amount" = "水位上昇量"; - -/* flag description */ -"Health Decrease" = "体力の減少"; - -/* flag description */ -"Rope Length (%)" = "ロープの長さ (%)"; - -/* flag description */ -"Crate Drop Turns" = "クレートドロップターン"; - -/* flag description */ -"Health Kit Probability (%)" = "体力キットの確率 (%)"; - -/* flag description */ -"Health Amount in Kit" = "キットの体力量"; - -/* flag description */ -"Mines Time" = "地雷タイム"; - -/* flag description */ -"Mines Number" = "地雷ナンバー"; - -/* flag description */ -"Dud Mines Probability (%)" = "不発地雷の確率(%)"; - -/* flag description */ -"Explosives" = "爆発物"; - -/* flag description */ +/* game mod description */ +"Land can not be destroyed" = "土地は破壊することができません"; + +/* game mod title */ +"Solid Land" = "固形の土地"; + +/* game mod description */ +"Add an indestructable border around the terrain" = "地形の周りに破壊できないボーダーを追加する"; + +/* game mod title */ +"Add Border" = "ボーダーを追加する"; + +/* game mod description */ +"Teams will start on opposite sides of the terrain" = "チームは地形の反対側からスタート思案す"; + +/* game mod title */ +"Divide Team (max 2 teams)" = "チームを分ける (最大二チーム)"; + +/* game mod description */ +"Lower gravity" = "低い重力"; + +/* game mod title */ +"Low Gravity" = "低重力"; + +/* game mod description */ +"Assisted aiming with laser sight" = "レーザーサイトで狙いの補助"; + +/* game mod title */ +"Laser Sight" = "レーザーサイト"; + +/* game mod description */ +"All hogs have a personal forcefield" = "全てのハリネズミは自分の力場を持っています"; + +/* game mod title */ +"Invulnerable" = "無敵"; + +/* game mod description */ +"All (living) hedgehogs are fully restored at the end of turn" = "全ての (生きている) ハリネズミの体力はターン終了時に完全に復元されます"; + +/* game mod title */ +"Reset Health" = "体力をリセット"; + +/* game mod description */ +"Gain 80% of the damage you do back in health" = "ダメージの80% を体力としてもらう"; + +/* game mod title */ +"Vampirism Mode" = "吸血モード"; + +/* game mod description */ +"Share your opponents pain, share their damage" = "相手の痛みを共有し、 ダメージを共有する"; + +/* game mod title */ +"Karma Mode" = "カルマモード"; + +/* game mod description */ +"Your hogs are unable to move, test your aim" = "あなたのハリネズミは動けない, 狙いを試せ"; + +/* game mod title */ +"Artillery Mode" = "砲兵モード"; + +/* game mod description */ +"Defend your fort and destroy the opponents" = "砦を守って相手を潰せ"; + +/* game mod title */ +"Fort Mode" = "砦モード"; + +/* game mod description */ +"Order of play is random instead of in room order" = "プレー順はルーム順ではなくランダムです"; + +/* game mod title */ +"Random Order" = "ランダムオーダー"; + +/* game mod description */ +"Play with a King; when he dies, your side loses" = "キングとプレーする; キングが死ぬと、あなたの負けです"; + +/* game mod title */ +"King Mode" = "キングモード"; + +/* game mod description */ +"Take turns placing your hedgehogs pre-game" = "ゲームの前にターンを取ってハリネズミを置く"; + +/* game mod title */ +"Place Hedgehogs" = "ハリネズミを置く"; + +/* game mod description */ +"Ammo is shared between all clan teams" = "弾薬は全ての一族チームの間で共有されます"; + +/* game mod title */ +"Clan Shares Ammo" = "一族は弾薬を共有します"; + +/* game mod description */ +"Disable girders when generating random maps" = "ランダムマップを作成するときはガードを無効にする"; + +/* game mod title */ +"Disable Girders" = "ガードを無効にする"; + +/* game mod description */ +"Disable land objects when generating maps" = "マップ作成中は土地のオブジェクトを無効にする"; + +/* game mod title */ +"Disable Land Objects" = "土地のオブジェクトを無効にする"; + +/* game mod description */ +"AI-controlled hogs respawn on death" = "AIがコントロールするハリネズミは死ぬと再出現します"; + +/* game mod title */ +"AI Survival Mode" = "AI サバイバルモード"; + +/* game mod description */ +"Attacking does not end your turn" = "攻撃してもターンは終了しません"; + +/* game mod title */ +"Unlimited Attacks" = "無限攻撃"; + +/* game mod description */ +"Weapons are reset to starting values each turn" = "武器は毎ターン初期値にリセットされます"; + +/* game mod title */ +"Reset Weapons" = "武器をリセット"; + +/* game mod description */ +"Each hedgehog has its own ammo" = "各ハリネズミが自分の弾薬を持っています"; + +/* game mod title */ +"Per Hedgehog Ammo" = "ハリネズミあたりの弾薬"; + +/* game mod description */ +"You will not have to worry about wind any more" = "風のことは気にせずに良くなります"; + +/* game mod title */ +"Disable Wind" = "風を無効にする"; + +/* game mod description */ +"Wind will affect almost everything" = "風はほとんどのものに影響します"; + +/* game mod title */ +"More Wind" = "より強い風"; + +/* game mod description */ +"Clan teams take turns sharing their time" = "一族のチームはタイムを共有してターンを取ります"; + +/* game mod title */ +"Tag Team" = "タッグチーム"; + +/* game mod description */ +"Add an indestructible border along the bottom" = "破壊できないボーダーを下に追加する"; + +/* game mod title */ +"Bottom Border" = "ボトムボーダー"; + + +/* flag description */ +"Initial Health" = "初期体力"; + +/* flag description */ +"Damage Modifier" = "ダメージ変更"; + +/* flag description */ +"Turn Time" = "ターンタイム"; +/* flag description */ +"Sudden Death Timeout" = "サデン・デス タイムアウト"; + +/* flag description */ +"Water Rise Amount" = "水位上昇量"; + +/* flag description */ +"Health Decrease" = "体力の減少"; + +/* flag description */ +"Rope Length (%)" = "ロープの長さ (%)"; + +/* flag description */ +"Crate Drop Turns" = "クレートドロップターン"; + +/* flag description */ +"Health Kit Probability (%)" = "体力キットの確率 (%)"; + +/* flag description */ +"Health Amount in Kit" = "キットの体力量"; + +/* flag description */ +"Mines Time" = "地雷タイム"; + +/* flag description */ +"Mines Number" = "地雷ナンバー"; + +/* flag description */ +"Dud Mines Probability (%)" = "不発地雷の確率(%)"; + +/* flag description */ +"Explosives" = "爆発物"; + +/* flag description */ "Get Away Time (%)" = "脱出タイム (%)"; \ No newline at end of file diff -r 4feced261c68 -r de822cd3df3a project_files/HedgewarsMobile/Locale/hw-desc_ja.txt --- a/project_files/HedgewarsMobile/Locale/hw-desc_ja.txt Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/HedgewarsMobile/Locale/hw-desc_ja.txt Tue Jan 21 22:43:06 2014 +0100 @@ -1,28 +1,28 @@ - -Hedgewars, ブラストだ! - -Hedgewars が Mac アップストアに登場! Mac で Hedgewars を検索して無料コピーを今すぐダウンロードしよう! - -iOS ポートはいくつかの限定フィーチャーがあります。例えば: -* iPad VGA アウト: 外部ディスプレイを接続してフル解像度でプレー -* Retina ディスrプレイサポート: ゲームの全てを高い解像度でプレー; -* マルチタスキング: いつでもゲームをポーズ; -* ゲームリストア: あなたは何が何でもマッチを完成させることができます。 - -説明: -これはあなたが遊ぶ一番面白くて依存症のあるゲームです - いつでも、どこでも楽しめる陽気な楽しみ。 Hedgewars はターン制ストラテジーゲームですが、本当の楽しみはあの厄介なハリネズミがすばらしい武器を使って起こす破壊を見ることです - 悪い態度の小さな厄介者! - -言い換えれば、 Hedgewars はターン製ストラテジー、砲兵、アクションとコメディゲームで、地獄から宇宙まで 悪ふざけをするピンクのハリネズミが特色です。 - -司令官としてのあなたの役目はハリネズミ兵のチームを編成し、敵に戦争を持ってゆくことです。 - -プレイヤーはそれぞれ複数のハリネズミをコントロールします。ゲーム中は、ハリネズミの一つを使って交代します。利用可能な武器や道具を使って敵のハリネズミを攻撃して殺し、勝利を取ります。 -Hedgehogs は地形をさまざまな方法で動き回ります。普段は歩いたりジャンプしたりしますが、"ロープ"や"パラシュート"などの特定の道具を使って本来なら届かないエリアに移動することができます。ターンはプレイヤーが動いたいり考えたりする時間をとり過ぎないようにタイムリミットがかかっています。ゲーム中はさまざまな道具や武器が使えます:手榴弾、クラスター爆弾、UFO、ショットガン、デザートイーグル、ファイアーパンチ、野球バット、ダイナマイト、地雷、ロープ、ニューマチックピックやパラシュートです。ほとんどの武器は、使用時に、地形を変える爆発を起こします。地形は水の上に浮かんでいる島か、下に水がある洞窟です。ハリネズミは水の中に入るか(島から落ちるか、穴を通って)、アリーナの横から落とされるか、爆発などで体力がゼロに減ると(プレーヤーやCPUのターンのダメージは全ての動きが止まった後表示されます)死んでしまいます。 - -* 六人までの陽気と壊滅的なターン制コンバット -* AIも追加可能なローカルとネットワーク上のマルチプレーヤー -* ランダムで作成された無限のマップと二十以上の環境の中で戦おう -* 48(上昇中)の圧倒的な武器を使おう!ピアノストライクと爆発的なロボットケーキも含みます。 -* 二十種類以上のゲーム修飾法で戦いのほとんどの部分を微調整して自分のやり方でプレーしよう -* 120以上のコスチューム、30以上の墓、12以上の砦、100以上のフラグやユニークなボイスパックでチームをカスタマイズ + +Hedgewars, ブラストだ! + +Hedgewars が Mac アップストアに登場! Mac で Hedgewars を検索して無料コピーを今すぐダウンロードしよう! + +iOS ポートはいくつかの限定フィーチャーがあります。例えば: +* iPad VGA アウト: 外部ディスプレイを接続してフル解像度でプレー +* Retina ディスrプレイサポート: ゲームの全てを高い解像度でプレー; +* マルチタスキング: いつでもゲームをポーズ; +* ゲームリストア: あなたは何が何でもマッチを完成させることができます。 + +説明: +これはあなたが遊ぶ一番面白くて依存症のあるゲームです - いつでも、どこでも楽しめる陽気な楽しみ。 Hedgewars はターン制ストラテジーゲームですが、本当の楽しみはあの厄介なハリネズミがすばらしい武器を使って起こす破壊を見ることです - 悪い態度の小さな厄介者! + +言い換えれば、 Hedgewars はターン製ストラテジー、砲兵、アクションとコメディゲームで、地獄から宇宙まで 悪ふざけをするピンクのハリネズミが特色です。 + +司令官としてのあなたの役目はハリネズミ兵のチームを編成し、敵に戦争を持ってゆくことです。 + +プレイヤーはそれぞれ複数のハリネズミをコントロールします。ゲーム中は、ハリネズミの一つを使って交代します。利用可能な武器や道具を使って敵のハリネズミを攻撃して殺し、勝利を取ります。 +Hedgehogs は地形をさまざまな方法で動き回ります。普段は歩いたりジャンプしたりしますが、"ロープ"や"パラシュート"などの特定の道具を使って本来なら届かないエリアに移動することができます。ターンはプレイヤーが動いたいり考えたりする時間をとり過ぎないようにタイムリミットがかかっています。ゲーム中はさまざまな道具や武器が使えます:手榴弾、クラスター爆弾、UFO、ショットガン、デザートイーグル、ファイアーパンチ、野球バット、ダイナマイト、地雷、ロープ、ニューマチックピックやパラシュートです。ほとんどの武器は、使用時に、地形を変える爆発を起こします。地形は水の上に浮かんでいる島か、下に水がある洞窟です。ハリネズミは水の中に入るか(島から落ちるか、穴を通って)、アリーナの横から落とされるか、爆発などで体力がゼロに減ると(プレーヤーやCPUのターンのダメージは全ての動きが止まった後表示されます)死んでしまいます。 + +* 六人までの陽気と壊滅的なターン制コンバット +* AIも追加可能なローカルとネットワーク上のマルチプレーヤー +* ランダムで作成された無限のマップと二十以上の環境の中で戦おう +* 48(上昇中)の圧倒的な武器を使おう!ピアノストライクと爆発的なロボットケーキも含みます。 +* 二十種類以上のゲーム修飾法で戦いのほとんどの部分を微調整して自分のやり方でプレーしよう +* 120以上のコスチューム、30以上の墓、12以上の砦、100以上のフラグやユニークなボイスパックでチームをカスタマイズ * 64体までの広大な戦い \ No newline at end of file diff -r 4feced261c68 -r de822cd3df3a project_files/cmdlineClient/cmdlineClient.c --- a/project_files/cmdlineClient/cmdlineClient.c Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/cmdlineClient/cmdlineClient.c Tue Jan 21 22:43:06 2014 +0100 @@ -1,475 +1,475 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#define ENGINE_DIR ".\\" -#define CONFIG_DIR "..\\share\\hedgewars" -#define DATA_DIR CONFIG_DIR"\\Data" - -static flib_netconn *netconn; -static flib_gameconn *gameconn; -static flib_mapconn *mapconn; -static char nickname[128]; -static flib_metascheme *metacfg; -static bool netConnected = false; - -// Callback function that will be called when the map is rendered -static void handleMapGenerated(void *context, const uint8_t *bitmap, int numHedgehogs) { - printf("Drawing map for %i brave little hogs...", numHedgehogs); - - // Draw the map as ASCII art - for(int y=0; y>3] & (1<<(7-(pixelnum&7))); - printf(pixel ? "#" : " "); - } - printf("\n"); - } - - flib_mapconn_destroy(mapconn); - mapconn = NULL; -} - -static void onGameDisconnect(void *context, int reason) { - flib_log_i("Connection closed. Reason: %i", reason); - flib_gameconn_destroy(gameconn); - gameconn = NULL; - if(netconn) { - flib_netconn_send_roundfinished(netconn, reason==GAME_END_FINISHED); - } -} - -// Callback function that will be called on error -static void handleMapFailure(void *context, const char *errormessage) { - flib_log_e("Map rendering failed: %s", errormessage); - flib_mapconn_destroy(mapconn); - mapconn = NULL; -} - -static void startEngineMap(int port) { - char cmdbuffer[255]; - char argbuffer[255]; - snprintf(cmdbuffer, 255, "%shwengine.exe", ENGINE_DIR); - snprintf(argbuffer, 255, "%s %i landpreview", CONFIG_DIR, port); - ShellExecute(NULL, NULL, cmdbuffer, argbuffer, NULL, SW_HIDE); -} - -static void startEngineGame(int port) { - char cmdbuffer[255]; - char argbuffer[255]; - char base64PlayerName[255]; - base64_encode(nickname, strlen(nickname), base64PlayerName, sizeof(base64PlayerName)); - snprintf(cmdbuffer, 255, "%shwengine.exe", ENGINE_DIR); - snprintf(argbuffer, 255, "%s 1024 768 32 %i 0 0 0 10 10 %s 0 0 %s 0 0 en.txt", CONFIG_DIR, port, DATA_DIR, base64PlayerName); - ShellExecute(NULL, NULL, cmdbuffer, argbuffer, NULL, SW_HIDE); -} - -void handleNetDisconnect(void *context, int reason, const char *message) { - printf("Disconnected: %s", message); - flib_netconn_destroy(netconn); - netconn = NULL; -} - -/*void printRoomList() { - const flib_roomlist *roomlist = flib_netconn_get_roomlist(netconn); - if(roomlist) { - if(roomlist->roomCount>0) { - for(int i=0; iroomCount; i++) { - if(i>0) { - printf(", "); - } - flib_room *room = roomlist->rooms[i]; - printf("%s", room->name); - } - } else { - puts("Unfortunately, there are no rooms at the moment."); - } - } else { - puts("Sorry, due to an error the room list is not available."); - } - puts("\n"); -}*/ - -void printTeamList() { - flib_gamesetup *setup = flib_netconn_create_gamesetup(netconn); - if(setup) { - puts("The following teams are in this room:"); - for(int i=0; iteamlist->teamCount; i++) { - if(i>0) { - printf(", "); - } - printf("%s", setup->teamlist->teams[i]->name); - } - puts("\n"); - } else { - puts("Sorry, due to an error the team list is not available."); - } - flib_gamesetup_destroy(setup); -} - -void handleNetConnected(void *context) { - printf("You enter the lobby of a strange house inhabited by hedgehogs. Looking around, you see hallways branching off to these rooms:\n"); - //printRoomList(); - printf("\n\nNow, you can chat by just entering text, or join a room with /join ."); - printf(" You can also /quit or let me /describe . Once in a room, you can /add and set yourself /ready. You can also /list the available rooms (in the lobby) or the teams (in a room).\n"); - netConnected = true; -} - -void handleChat(void *context, const char *nick, const char *msg) { - if(gameconn) { - flib_gameconn_send_chatmsg(gameconn, nick, msg); - } - printf("%s: %s\n", nick, msg); -} - -void handleEnterRoom(void *context, bool isChief) { - puts("You have entered the room."); -} - -void handleRoomJoin(void *context, const char *nick) { - if(strcmp(nick, nickname)) { - printf("%s is here.\n", nick); - } -} - -void handleRoomLeave(void *context, const char *nick, const char *partmsg) { - if(strcmp(nick, nickname)) { - printf("%s leaves.\n", nick); - } -} - -void handleReady(void *context, const char *nick, bool ready) { - if(strcmp(nick, nickname)) { - if(ready) { - printf("%s is ready to go.\n", nick); - } else { - printf("%s is not ready.\n", nick); - } - } else { - if(ready) { - printf("You are ready to go.\n"); - } else { - printf("You are not ready.\n"); - } - } -} - -void handleEmFromNet(void *context, const uint8_t *em, size_t size) { - if(gameconn) { - flib_gameconn_send_enginemsg(gameconn, em, size); - } -} - -void handleEmFromEngine(void *context, const uint8_t *em, size_t size) { - if(netconn) { - flib_netconn_send_engineMessage(netconn, em, size); - } -} - -void handleChatFromGame(void *context, const char *message, bool teamchat) { - if(netconn) { - if(teamchat) { - flib_netconn_send_teamchat(netconn, message); - } else { - flib_netconn_send_chat(netconn, message); - } - } -} - -void handleRunGame(void *context) { - flib_gamesetup *gamesetup = flib_netconn_create_gamesetup(netconn); - if(gameconn) { - flib_log_e("Request to start game, but a game is already running."); - } else if(gamesetup) { - gameconn = flib_gameconn_create(nickname, gamesetup, true); - flib_gameconn_onEngineMessage(gameconn, handleEmFromEngine, NULL); - flib_gameconn_onDisconnect(gameconn, onGameDisconnect, NULL); - flib_gameconn_onChat(gameconn, handleChatFromGame, NULL); - startEngineGame(flib_gameconn_getport(gameconn)); - } - flib_gamesetup_destroy(gamesetup); -} - -void handleNickTaken(void *context, const char *nick) { - printf("The nickname %s is already in use, please choose a different one:\n", nick); - flib_gets(nickname, sizeof(nickname)); - flib_netconn_send_nick(netconn, nickname); -} - -void handlePwRequest(void *context, const char *nick) { - printf("A password is required to log in as %s, please enter (warning: shown in cleartext):\n", nick); - char password[256]; - flib_gets(password, sizeof(password)); - flib_netconn_send_password(netconn, password); -} - -void handleMessage(void *context, int type, const char *msg) { - if(gameconn) { - flib_gameconn_send_textmsg(gameconn, 1, msg); - } - printf("*** %s\n", msg); -} - -void handleTeamAccepted(void *context, const char *teamname) { - printf("The team %s has been accepted.\n", teamname); -} - -void handleMapChanged(void *context, const flib_map *map, int changetype) { - if(map->mapgen != MAPGEN_NAMED && changetype != NETCONN_MAPCHANGE_THEME) { - if(mapconn) { - flib_mapconn_destroy(mapconn); - mapconn = NULL; - } - mapconn = flib_mapconn_create(map); - if(mapconn) { - flib_mapconn_onSuccess(mapconn, handleMapGenerated, NULL); - flib_mapconn_onFailure(mapconn, handleMapFailure, NULL); - startEngineMap(flib_mapconn_getport(mapconn)); - } - } else if(map->mapgen == MAPGEN_NAMED) { - printf("The map %s has been selected.\n", map->name); - } -} - -void handleLeaveRoom(void *context, int reason, const char *msg) { - if(reason == NETCONN_ROOMLEAVE_ABANDONED) { - printf("The chief has abandoned the room."); - } else if(reason == NETCONN_ROOMLEAVE_KICKED) { - printf("You have been kicked from the room."); - } - if(msg) { - printf(" (%s)", msg); - } - puts(" You are back in the lobby."); -} - -void handleSchemeChanged(void *context, const flib_scheme *scheme) { - printf("Game scheme: %s.\n", scheme->name); -} - -void handleWeaponsetChanged(void *context, const flib_weaponset *weaponset) { - printf("Weaponset: %s.\n", weaponset->name); -} - -void handleHogcountChanged(void *context, const char *team, int count) { - printf("Team %s will send %i hogs into the fight.\n", team, count); -} - -void handleRoomAdd(void *context, const flib_room *room) { - printf("%s created a new room called %s.\n", room->owner, room->name); -} - -void handleRoomDelete(void *context, const char *roomName) { - printf("The room %s has collapsed.\n", roomName); -} - -void handleScriptChanged(void *context, const char *script) { - printf("Game Type: %s\n", script); -} - -void handleTeamAdd(void *context, const flib_team *team) { - printf("%s puts the team %s to the planning board.\n", team->ownerName, team->name); -} - -void handleTeamDelete(void *context, const char *teamName) { - printf("The team %s decided not to fight this battle after all.\n", teamName); -} - -void handleTeamColorChanged(void *context, const char *name, int colorIndex) { - static const char* colorNames[] = {"red", "blue", "teal", "purple", "pink", "green", "orange", "brown", "yellow"}; - const char *colorName = "strange"; - if(colorIndex>=0 && colorIndex < 9) { - colorName = colorNames[colorIndex]; - } - printf("The team %s will wear %s uniforms today.\n", name, colorName); -} - -void tick() { - if(gameconn) { - flib_gameconn_tick(gameconn); - } - if(netconn) { - flib_netconn_tick(netconn); - } - if(mapconn) { - flib_mapconn_tick(mapconn); - } -} - -static HANDLE hStdin; - -static int init() { - hStdin = GetStdHandle(STD_INPUT_HANDLE); - if(hStdin == INVALID_HANDLE_VALUE) { - flib_log_e("Unable to get stdin handle"); - return 1; - } - if(!flib_init(0)) { - flib_log_setLevel(FLIB_LOGLEVEL_WARNING); - freopen( "CON", "w", stdout ); - freopen( "CON", "w", stderr ); - metacfg = flib_metascheme_from_ini("metasettings.ini"); - if(!metacfg) { - flib_quit(); - return -1; - } else { - return 0; - } - } - return -1; -} - -int main(int argc, char *argv[]) { - if(init()) { - return -1; - } - - puts("Please enter a nickname:"); - flib_gets(nickname, sizeof(nickname)); - - netconn = flib_netconn_create(nickname, metacfg, DATA_DIR"\\", "140.247.62.101", 46631); - if(!netconn) { - flib_quit(); - return -1; - } - - flib_netconn_onConnected(netconn, handleNetConnected, NULL); - flib_netconn_onDisconnected(netconn, handleNetDisconnect, NULL); - flib_netconn_onChat(netconn, handleChat, NULL); - flib_netconn_onEnterRoom(netconn, handleEnterRoom, NULL); - flib_netconn_onRunGame(netconn, handleRunGame, NULL); - flib_netconn_onEngineMessage(netconn, handleEmFromNet, NULL); - flib_netconn_onRoomJoin(netconn, handleRoomJoin, NULL); - flib_netconn_onRoomLeave(netconn, handleRoomLeave, NULL); - flib_netconn_onReadyState(netconn, handleReady, NULL); - flib_netconn_onNickTaken(netconn, handleNickTaken, NULL); - flib_netconn_onPasswordRequest(netconn, handlePwRequest, NULL); - flib_netconn_onMessage(netconn, handleMessage, NULL); - flib_netconn_onTeamAccepted(netconn, handleTeamAccepted, NULL); - flib_netconn_onMapChanged(netconn, handleMapChanged, NULL); - flib_netconn_onLeaveRoom(netconn, handleLeaveRoom, NULL); - flib_netconn_onCfgScheme(netconn, handleSchemeChanged, NULL); - flib_netconn_onWeaponsetChanged(netconn, handleWeaponsetChanged, NULL); - flib_netconn_onHogCountChanged(netconn, handleHogcountChanged, NULL); - flib_netconn_onRoomAdd(netconn, handleRoomAdd, NULL); - flib_netconn_onRoomDelete(netconn, handleRoomDelete, NULL); - flib_netconn_onScriptChanged(netconn, handleScriptChanged, NULL); - flib_netconn_onTeamAdd(netconn, handleTeamAdd, NULL); - flib_netconn_onTeamDelete(netconn, handleTeamDelete, NULL); - flib_netconn_onTeamColorChanged(netconn, handleTeamColorChanged, NULL); - - INPUT_RECORD inputRecord; - DWORD eventCount = 0; - - while(netconn || gameconn) { - tick(); - if(netconn && netConnected) { - while(PeekConsoleInput(hStdin, &inputRecord, 1, &eventCount) && eventCount>0) { - if(inputRecord.EventType != KEY_EVENT) { - ReadConsoleInput(hStdin, &inputRecord, 1, &eventCount); - } else { - printf("%s: ", nickname); - char input[256]; - if(!flib_gets(input, sizeof(input))) { - if(!memcmp("/quit", input, strlen("/quit"))) { - flib_netconn_send_quit(netconn, "Player quit."); - } else if(!memcmp("/describe ", input, strlen("/describe "))) { - const char *roomname = input+strlen("/describe "); - /*const flib_roomlist *roomlist = flib_netconn_get_roomlist(netconn); - flib_room *room = flib_roomlist_find(roomlist, roomname); - if(!room) { - puts("Unknown room."); - } else { - char *text = flib_asprintf( - "%s is a room created by %s, where %i players (%i teams) are %s on %s%s, using the %s scheme and %s weaponset.", - room->name, - room->owner, - room->playerCount, - room->teamCount, - room->inProgress ? "fighting" : "preparing to fight", - room->map[0]=='+' ? "" : "the map ", - !strcmp("+rnd+", room->map) ? "a random map" : - !strcmp("+maze+", room->map) ? "a random maze" : - !strcmp("+drawn+", room->map) ? "a hand-drawn map" : - room->map, - room->scheme, - room->weapons); - if(text) { - puts(text); - } - free(text); - }*/ - } else if(!memcmp("/join ", input, strlen("/join "))) { - const char *roomname = input+strlen("/join "); - flib_netconn_send_joinRoom(netconn, roomname); - } else if(!memcmp("/ready", input, strlen("/ready"))) { - flib_netconn_send_toggleReady(netconn); - } else if(!memcmp("/loglevel ", input, strlen("/loglevel "))) { - int loglevel = atoi(input+strlen("/loglevel ")); - flib_log_setLevel(loglevel); - } else if(!memcmp("/list", input, strlen("/list"))) { - if(flib_netconn_is_in_room_context(netconn)) { - printTeamList(); - } else { - puts("From this big and expansive lobby, hallways branch off to these rooms:"); - //printRoomList(); - } - } else if(!memcmp("/addteam ", input, strlen("/addteam "))) { - const char *teamname = input+strlen("/addteam "); - if(!flib_contains_dir_separator(teamname)) { - char *teamfilename = flib_asprintf("%s.hwt", teamname); - if(teamfilename) { - flib_team *team = flib_team_from_ini(teamfilename); - if(team) { - flib_netconn_send_addTeam(netconn, team); - } else { - printf("Teamfile %s not found.\n", teamfilename); - } - flib_team_destroy(team); - } - free(teamfilename); - } - } else if(strlen(input)>0) { - flib_netconn_send_chat(netconn, input); - } - } - } - } - } - fflush(stdout); - Sleep(10); - } - - - flib_metascheme_release(metacfg); - return 0; -} +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#define ENGINE_DIR ".\\" +#define CONFIG_DIR "..\\share\\hedgewars" +#define DATA_DIR CONFIG_DIR"\\Data" + +static flib_netconn *netconn; +static flib_gameconn *gameconn; +static flib_mapconn *mapconn; +static char nickname[128]; +static flib_metascheme *metacfg; +static bool netConnected = false; + +// Callback function that will be called when the map is rendered +static void handleMapGenerated(void *context, const uint8_t *bitmap, int numHedgehogs) { + printf("Drawing map for %i brave little hogs...", numHedgehogs); + + // Draw the map as ASCII art + for(int y=0; y>3] & (1<<(7-(pixelnum&7))); + printf(pixel ? "#" : " "); + } + printf("\n"); + } + + flib_mapconn_destroy(mapconn); + mapconn = NULL; +} + +static void onGameDisconnect(void *context, int reason) { + flib_log_i("Connection closed. Reason: %i", reason); + flib_gameconn_destroy(gameconn); + gameconn = NULL; + if(netconn) { + flib_netconn_send_roundfinished(netconn, reason==GAME_END_FINISHED); + } +} + +// Callback function that will be called on error +static void handleMapFailure(void *context, const char *errormessage) { + flib_log_e("Map rendering failed: %s", errormessage); + flib_mapconn_destroy(mapconn); + mapconn = NULL; +} + +static void startEngineMap(int port) { + char cmdbuffer[255]; + char argbuffer[255]; + snprintf(cmdbuffer, 255, "%shwengine.exe", ENGINE_DIR); + snprintf(argbuffer, 255, "%s %i landpreview", CONFIG_DIR, port); + ShellExecute(NULL, NULL, cmdbuffer, argbuffer, NULL, SW_HIDE); +} + +static void startEngineGame(int port) { + char cmdbuffer[255]; + char argbuffer[255]; + char base64PlayerName[255]; + base64_encode(nickname, strlen(nickname), base64PlayerName, sizeof(base64PlayerName)); + snprintf(cmdbuffer, 255, "%shwengine.exe", ENGINE_DIR); + snprintf(argbuffer, 255, "%s 1024 768 32 %i 0 0 0 10 10 %s 0 0 %s 0 0 en.txt", CONFIG_DIR, port, DATA_DIR, base64PlayerName); + ShellExecute(NULL, NULL, cmdbuffer, argbuffer, NULL, SW_HIDE); +} + +void handleNetDisconnect(void *context, int reason, const char *message) { + printf("Disconnected: %s", message); + flib_netconn_destroy(netconn); + netconn = NULL; +} + +/*void printRoomList() { + const flib_roomlist *roomlist = flib_netconn_get_roomlist(netconn); + if(roomlist) { + if(roomlist->roomCount>0) { + for(int i=0; iroomCount; i++) { + if(i>0) { + printf(", "); + } + flib_room *room = roomlist->rooms[i]; + printf("%s", room->name); + } + } else { + puts("Unfortunately, there are no rooms at the moment."); + } + } else { + puts("Sorry, due to an error the room list is not available."); + } + puts("\n"); +}*/ + +void printTeamList() { + flib_gamesetup *setup = flib_netconn_create_gamesetup(netconn); + if(setup) { + puts("The following teams are in this room:"); + for(int i=0; iteamlist->teamCount; i++) { + if(i>0) { + printf(", "); + } + printf("%s", setup->teamlist->teams[i]->name); + } + puts("\n"); + } else { + puts("Sorry, due to an error the team list is not available."); + } + flib_gamesetup_destroy(setup); +} + +void handleNetConnected(void *context) { + printf("You enter the lobby of a strange house inhabited by hedgehogs. Looking around, you see hallways branching off to these rooms:\n"); + //printRoomList(); + printf("\n\nNow, you can chat by just entering text, or join a room with /join ."); + printf(" You can also /quit or let me /describe . Once in a room, you can /add and set yourself /ready. You can also /list the available rooms (in the lobby) or the teams (in a room).\n"); + netConnected = true; +} + +void handleChat(void *context, const char *nick, const char *msg) { + if(gameconn) { + flib_gameconn_send_chatmsg(gameconn, nick, msg); + } + printf("%s: %s\n", nick, msg); +} + +void handleEnterRoom(void *context, bool isChief) { + puts("You have entered the room."); +} + +void handleRoomJoin(void *context, const char *nick) { + if(strcmp(nick, nickname)) { + printf("%s is here.\n", nick); + } +} + +void handleRoomLeave(void *context, const char *nick, const char *partmsg) { + if(strcmp(nick, nickname)) { + printf("%s leaves.\n", nick); + } +} + +void handleReady(void *context, const char *nick, bool ready) { + if(strcmp(nick, nickname)) { + if(ready) { + printf("%s is ready to go.\n", nick); + } else { + printf("%s is not ready.\n", nick); + } + } else { + if(ready) { + printf("You are ready to go.\n"); + } else { + printf("You are not ready.\n"); + } + } +} + +void handleEmFromNet(void *context, const uint8_t *em, size_t size) { + if(gameconn) { + flib_gameconn_send_enginemsg(gameconn, em, size); + } +} + +void handleEmFromEngine(void *context, const uint8_t *em, size_t size) { + if(netconn) { + flib_netconn_send_engineMessage(netconn, em, size); + } +} + +void handleChatFromGame(void *context, const char *message, bool teamchat) { + if(netconn) { + if(teamchat) { + flib_netconn_send_teamchat(netconn, message); + } else { + flib_netconn_send_chat(netconn, message); + } + } +} + +void handleRunGame(void *context) { + flib_gamesetup *gamesetup = flib_netconn_create_gamesetup(netconn); + if(gameconn) { + flib_log_e("Request to start game, but a game is already running."); + } else if(gamesetup) { + gameconn = flib_gameconn_create(nickname, gamesetup, true); + flib_gameconn_onEngineMessage(gameconn, handleEmFromEngine, NULL); + flib_gameconn_onDisconnect(gameconn, onGameDisconnect, NULL); + flib_gameconn_onChat(gameconn, handleChatFromGame, NULL); + startEngineGame(flib_gameconn_getport(gameconn)); + } + flib_gamesetup_destroy(gamesetup); +} + +void handleNickTaken(void *context, const char *nick) { + printf("The nickname %s is already in use, please choose a different one:\n", nick); + flib_gets(nickname, sizeof(nickname)); + flib_netconn_send_nick(netconn, nickname); +} + +void handlePwRequest(void *context, const char *nick) { + printf("A password is required to log in as %s, please enter (warning: shown in cleartext):\n", nick); + char password[256]; + flib_gets(password, sizeof(password)); + flib_netconn_send_password(netconn, password); +} + +void handleMessage(void *context, int type, const char *msg) { + if(gameconn) { + flib_gameconn_send_textmsg(gameconn, 1, msg); + } + printf("*** %s\n", msg); +} + +void handleTeamAccepted(void *context, const char *teamname) { + printf("The team %s has been accepted.\n", teamname); +} + +void handleMapChanged(void *context, const flib_map *map, int changetype) { + if(map->mapgen != MAPGEN_NAMED && changetype != NETCONN_MAPCHANGE_THEME) { + if(mapconn) { + flib_mapconn_destroy(mapconn); + mapconn = NULL; + } + mapconn = flib_mapconn_create(map); + if(mapconn) { + flib_mapconn_onSuccess(mapconn, handleMapGenerated, NULL); + flib_mapconn_onFailure(mapconn, handleMapFailure, NULL); + startEngineMap(flib_mapconn_getport(mapconn)); + } + } else if(map->mapgen == MAPGEN_NAMED) { + printf("The map %s has been selected.\n", map->name); + } +} + +void handleLeaveRoom(void *context, int reason, const char *msg) { + if(reason == NETCONN_ROOMLEAVE_ABANDONED) { + printf("The chief has abandoned the room."); + } else if(reason == NETCONN_ROOMLEAVE_KICKED) { + printf("You have been kicked from the room."); + } + if(msg) { + printf(" (%s)", msg); + } + puts(" You are back in the lobby."); +} + +void handleSchemeChanged(void *context, const flib_scheme *scheme) { + printf("Game scheme: %s.\n", scheme->name); +} + +void handleWeaponsetChanged(void *context, const flib_weaponset *weaponset) { + printf("Weaponset: %s.\n", weaponset->name); +} + +void handleHogcountChanged(void *context, const char *team, int count) { + printf("Team %s will send %i hogs into the fight.\n", team, count); +} + +void handleRoomAdd(void *context, const flib_room *room) { + printf("%s created a new room called %s.\n", room->owner, room->name); +} + +void handleRoomDelete(void *context, const char *roomName) { + printf("The room %s has collapsed.\n", roomName); +} + +void handleScriptChanged(void *context, const char *script) { + printf("Game Type: %s\n", script); +} + +void handleTeamAdd(void *context, const flib_team *team) { + printf("%s puts the team %s to the planning board.\n", team->ownerName, team->name); +} + +void handleTeamDelete(void *context, const char *teamName) { + printf("The team %s decided not to fight this battle after all.\n", teamName); +} + +void handleTeamColorChanged(void *context, const char *name, int colorIndex) { + static const char* colorNames[] = {"red", "blue", "teal", "purple", "pink", "green", "orange", "brown", "yellow"}; + const char *colorName = "strange"; + if(colorIndex>=0 && colorIndex < 9) { + colorName = colorNames[colorIndex]; + } + printf("The team %s will wear %s uniforms today.\n", name, colorName); +} + +void tick() { + if(gameconn) { + flib_gameconn_tick(gameconn); + } + if(netconn) { + flib_netconn_tick(netconn); + } + if(mapconn) { + flib_mapconn_tick(mapconn); + } +} + +static HANDLE hStdin; + +static int init() { + hStdin = GetStdHandle(STD_INPUT_HANDLE); + if(hStdin == INVALID_HANDLE_VALUE) { + flib_log_e("Unable to get stdin handle"); + return 1; + } + if(!flib_init(0)) { + flib_log_setLevel(FLIB_LOGLEVEL_WARNING); + freopen( "CON", "w", stdout ); + freopen( "CON", "w", stderr ); + metacfg = flib_metascheme_from_ini("metasettings.ini"); + if(!metacfg) { + flib_quit(); + return -1; + } else { + return 0; + } + } + return -1; +} + +int main(int argc, char *argv[]) { + if(init()) { + return -1; + } + + puts("Please enter a nickname:"); + flib_gets(nickname, sizeof(nickname)); + + netconn = flib_netconn_create(nickname, metacfg, DATA_DIR"\\", "140.247.62.101", 46631); + if(!netconn) { + flib_quit(); + return -1; + } + + flib_netconn_onConnected(netconn, handleNetConnected, NULL); + flib_netconn_onDisconnected(netconn, handleNetDisconnect, NULL); + flib_netconn_onChat(netconn, handleChat, NULL); + flib_netconn_onEnterRoom(netconn, handleEnterRoom, NULL); + flib_netconn_onRunGame(netconn, handleRunGame, NULL); + flib_netconn_onEngineMessage(netconn, handleEmFromNet, NULL); + flib_netconn_onRoomJoin(netconn, handleRoomJoin, NULL); + flib_netconn_onRoomLeave(netconn, handleRoomLeave, NULL); + flib_netconn_onReadyState(netconn, handleReady, NULL); + flib_netconn_onNickTaken(netconn, handleNickTaken, NULL); + flib_netconn_onPasswordRequest(netconn, handlePwRequest, NULL); + flib_netconn_onMessage(netconn, handleMessage, NULL); + flib_netconn_onTeamAccepted(netconn, handleTeamAccepted, NULL); + flib_netconn_onMapChanged(netconn, handleMapChanged, NULL); + flib_netconn_onLeaveRoom(netconn, handleLeaveRoom, NULL); + flib_netconn_onCfgScheme(netconn, handleSchemeChanged, NULL); + flib_netconn_onWeaponsetChanged(netconn, handleWeaponsetChanged, NULL); + flib_netconn_onHogCountChanged(netconn, handleHogcountChanged, NULL); + flib_netconn_onRoomAdd(netconn, handleRoomAdd, NULL); + flib_netconn_onRoomDelete(netconn, handleRoomDelete, NULL); + flib_netconn_onScriptChanged(netconn, handleScriptChanged, NULL); + flib_netconn_onTeamAdd(netconn, handleTeamAdd, NULL); + flib_netconn_onTeamDelete(netconn, handleTeamDelete, NULL); + flib_netconn_onTeamColorChanged(netconn, handleTeamColorChanged, NULL); + + INPUT_RECORD inputRecord; + DWORD eventCount = 0; + + while(netconn || gameconn) { + tick(); + if(netconn && netConnected) { + while(PeekConsoleInput(hStdin, &inputRecord, 1, &eventCount) && eventCount>0) { + if(inputRecord.EventType != KEY_EVENT) { + ReadConsoleInput(hStdin, &inputRecord, 1, &eventCount); + } else { + printf("%s: ", nickname); + char input[256]; + if(!flib_gets(input, sizeof(input))) { + if(!memcmp("/quit", input, strlen("/quit"))) { + flib_netconn_send_quit(netconn, "Player quit."); + } else if(!memcmp("/describe ", input, strlen("/describe "))) { + const char *roomname = input+strlen("/describe "); + /*const flib_roomlist *roomlist = flib_netconn_get_roomlist(netconn); + flib_room *room = flib_roomlist_find(roomlist, roomname); + if(!room) { + puts("Unknown room."); + } else { + char *text = flib_asprintf( + "%s is a room created by %s, where %i players (%i teams) are %s on %s%s, using the %s scheme and %s weaponset.", + room->name, + room->owner, + room->playerCount, + room->teamCount, + room->inProgress ? "fighting" : "preparing to fight", + room->map[0]=='+' ? "" : "the map ", + !strcmp("+rnd+", room->map) ? "a random map" : + !strcmp("+maze+", room->map) ? "a random maze" : + !strcmp("+drawn+", room->map) ? "a hand-drawn map" : + room->map, + room->scheme, + room->weapons); + if(text) { + puts(text); + } + free(text); + }*/ + } else if(!memcmp("/join ", input, strlen("/join "))) { + const char *roomname = input+strlen("/join "); + flib_netconn_send_joinRoom(netconn, roomname); + } else if(!memcmp("/ready", input, strlen("/ready"))) { + flib_netconn_send_toggleReady(netconn); + } else if(!memcmp("/loglevel ", input, strlen("/loglevel "))) { + int loglevel = atoi(input+strlen("/loglevel ")); + flib_log_setLevel(loglevel); + } else if(!memcmp("/list", input, strlen("/list"))) { + if(flib_netconn_is_in_room_context(netconn)) { + printTeamList(); + } else { + puts("From this big and expansive lobby, hallways branch off to these rooms:"); + //printRoomList(); + } + } else if(!memcmp("/addteam ", input, strlen("/addteam "))) { + const char *teamname = input+strlen("/addteam "); + if(!flib_contains_dir_separator(teamname)) { + char *teamfilename = flib_asprintf("%s.hwt", teamname); + if(teamfilename) { + flib_team *team = flib_team_from_ini(teamfilename); + if(team) { + flib_netconn_send_addTeam(netconn, team); + } else { + printf("Teamfile %s not found.\n", teamfilename); + } + flib_team_destroy(team); + } + free(teamfilename); + } + } else if(strlen(input)>0) { + flib_netconn_send_chat(netconn, input); + } + } + } + } + } + fflush(stdout); + Sleep(10); + } + + + flib_metascheme_release(metacfg); + return 0; +} diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/Android.mk --- a/project_files/frontlib/Android.mk Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/Android.mk Tue Jan 21 22:43:06 2014 +0100 @@ -4,17 +4,17 @@ LOCAL_MODULE := frontlib -LOCAL_CFLAGS := -I$(LOCAL_PATH)/../Android-build/SDL-android-project/jni/SDL_net -std=c99 -I$(LOCAL_PATH)/../Android-build/SDL-android-project/jni/SDL/include +LOCAL_CFLAGS := -I$(LOCAL_PATH)/../Android-build/SDL-android-project/jni/SDL_net -std=c99 -I$(LOCAL_PATH)/../Android-build/SDL-android-project/jni/SDL/include LOCAL_SRC_FILES := base64/base64.c iniparser/iniparser.c \ - iniparser/dictionary.c ipc/gameconn.c ipc/ipcbase.c \ - ipc/ipcprotocol.c ipc/mapconn.c md5/md5.c model/scheme.c \ - model/gamesetup.c model/map.c model/mapcfg.c model/room.c \ - model/schemelist.c model/team.c model/teamlist.c model/weapon.c \ - net/netbase.c net/netconn_callbacks.c net/netconn_send.c \ - net/netconn.c net/netprotocol.c util/buffer.c util/inihelper.c \ - util/logging.c util/util.c frontlib.c hwconsts.c socket.c \ - extra/jnacontrol.c + iniparser/dictionary.c ipc/gameconn.c ipc/ipcbase.c \ + ipc/ipcprotocol.c ipc/mapconn.c md5/md5.c model/scheme.c \ + model/gamesetup.c model/map.c model/mapcfg.c model/room.c \ + model/schemelist.c model/team.c model/teamlist.c model/weapon.c \ + net/netbase.c net/netconn_callbacks.c net/netconn_send.c \ + net/netconn.c net/netprotocol.c util/buffer.c util/inihelper.c \ + util/logging.c util/util.c frontlib.c hwconsts.c socket.c \ + extra/jnacontrol.c LOCAL_SHARED_LIBRARIES += SDL SDL_net LOCAL_LDLIBS += -lz diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/extra/jnacontrol.c --- a/project_files/frontlib/extra/jnacontrol.c Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/extra/jnacontrol.c Tue Jan 21 22:43:06 2014 +0100 @@ -1,240 +1,240 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/* - * This file is not directly part of the frontlib and is not required to build it. - * However, it is recommended to include it in compilation when building for Android. The purpose of this file - * is to ensure consistency between the function signatures of the JNA Java bindings of the Android port and the - * frontlib functions. - * - * This file, in essence, consists only of function declarations. They are duplicates of function declarations - * from the frontlib headers that are referenced from JNA bindings. If the signature of one of these functions - * changes in the frontlib, it will no longer match the signature in this file, and the compiler will show an error. - * If that happens, you need to update the JNA bindings in Hedgeroid to match the new function signature, and then - * update this file. - * - * The reason for all this is that JNA does not actually know the function signatures of the functions it binds, - * it derives them from Java method declarations. If those do not match the actual function signatures, you will - * only notice when you suddenly get strange (and possibly hard to track down) problems at runtime. This file is - * an attempt to detect these problems at compile time instead. Notice that it will NOT detect changes to structs - * or constants though, which also require updates to the JNA bindings. - */ - -/* - * Before we include the frontlib headers, we define away the const keyword. This is necessary because there is no - * distinction between const and non-const types on the JNA side, and we don't want the compiler to complain because - * of bad constness. - * - * This is so evil, but it works... - */ -#define const - -#include "../frontlib.h" - -/* - * Now we map the Java types to the corresponding C types... - */ -typedef flib_netconn *NetconnPtr; -typedef flib_gameconn *GameconnPtr; -typedef flib_mapconn *MapconnPtr; -typedef flib_metascheme *MetaschemePtr; -typedef flib_room **RoomArrayPtr; -typedef flib_weaponset *WeaponsetPtr; -typedef flib_weaponsetlist *WeaponsetListPtr; -typedef flib_map *MapRecipePtr; -typedef flib_scheme *SchemePtr; -typedef flib_schemelist *SchemelistPtr; - -typedef flib_room *RoomPtr; -typedef flib_team *TeamPtr; -typedef flib_gamesetup *GameSetupPtr; -typedef bool boolean; -typedef size_t NativeSizeT; -typedef void *Pointer; -typedef uint8_t *ByteArrayPtr; -typedef char *String; - -/* - * Mapping callback types - */ -typedef void (*VoidCallback)(Pointer context); -typedef void (*StrCallback)(Pointer context, String arg1); -typedef void (*IntCallback)(Pointer context, int arg1); -typedef void (*IntStrCallback)(Pointer context, int arg1, String arg2); -typedef void (*StrIntCallback)(Pointer context, String arg1, int arg2); -typedef void (*StrStrCallback)(Pointer context, String arg1, String arg2); -typedef void (*StrStrBoolCallback)(Pointer context, String arg1, String arg2, boolean arg3); -typedef void (*RoomCallback)(Pointer context, RoomPtr arg1); -typedef void (*RoomListCallback)(Pointer context, RoomArrayPtr arg1, int arg2); -typedef void (*StrRoomCallback)(Pointer context, String arg1, RoomPtr arg2); -typedef void (*BoolCallback)(Pointer context, boolean arg1); -typedef void (*StrBoolCallback)(Pointer context, String arg1, boolean arg2); -typedef void (*TeamCallback)(Pointer context, TeamPtr arg1); -typedef void (*BytesCallback)(Pointer context, const uint8_t *buffer, NativeSizeT size); -typedef void (*BytesBoolCallback)(Pointer context, const uint8_t *buffer, NativeSizeT size, boolean arg3); -typedef void (*SchemeCallback)(Pointer context, SchemePtr arg1); -typedef void (*MapIntCallback)(Pointer context, MapRecipePtr arg1, int arg2); -typedef void (*WeaponsetCallback)(Pointer context, WeaponsetPtr arg1); -typedef void (*MapimageCallback)(Pointer context, const uint8_t *mapimage, int hogs); -typedef void (*LogCallback)(int arg1, String arg2); - -/* - * Below here are the copypasted method declarations from the JNA bindings - */ - - // frontlib.h - int flib_init(); - void flib_quit(); - - // hwconsts.h - int flib_get_teamcolor_count(); - int flib_get_hedgehogs_per_team(); - int flib_get_weapons_count(); - MetaschemePtr flib_get_metascheme(); - - // net/netconn.h - NetconnPtr flib_netconn_create(String playerName, String dataDirPath, String host, int port); - void flib_netconn_destroy(NetconnPtr conn); - - void flib_netconn_tick(NetconnPtr conn); - boolean flib_netconn_is_chief(NetconnPtr conn); - String flib_netconn_get_playername(NetconnPtr conn); - GameSetupPtr flib_netconn_create_gamesetup(NetconnPtr conn); - int flib_netconn_send_quit(NetconnPtr conn, String quitmsg); - int flib_netconn_send_chat(NetconnPtr conn, String chat); - int flib_netconn_send_teamchat(NetconnPtr conn, String msg); - int flib_netconn_send_password(NetconnPtr conn, String passwd); - int flib_netconn_send_nick(NetconnPtr conn, String nick); - int flib_netconn_send_request_roomlist(NetconnPtr conn); - int flib_netconn_send_joinRoom(NetconnPtr conn, String room); - int flib_netconn_send_createRoom(NetconnPtr conn, String room); - int flib_netconn_send_renameRoom(NetconnPtr conn, String roomName); - int flib_netconn_send_leaveRoom(NetconnPtr conn, String msg); - int flib_netconn_send_toggleReady(NetconnPtr conn); - int flib_netconn_send_addTeam(NetconnPtr conn, TeamPtr team); - int flib_netconn_send_removeTeam(NetconnPtr conn, String teamname); - int flib_netconn_send_engineMessage(NetconnPtr conn, ByteArrayPtr message, NativeSizeT size); - int flib_netconn_send_teamHogCount(NetconnPtr conn, String teamname, int hogcount); - int flib_netconn_send_teamColor(NetconnPtr conn, String teamname, int colorIndex); - int flib_netconn_send_weaponset(NetconnPtr conn, WeaponsetPtr weaponset); - int flib_netconn_send_map(NetconnPtr conn, MapRecipePtr map); - int flib_netconn_send_mapName(NetconnPtr conn, String mapName); - int flib_netconn_send_mapGen(NetconnPtr conn, int mapGen); - int flib_netconn_send_mapTemplate(NetconnPtr conn, int templateFilter); - int flib_netconn_send_mapMazeSize(NetconnPtr conn, int mazeSize); - int flib_netconn_send_mapSeed(NetconnPtr conn, String seed); - int flib_netconn_send_mapTheme(NetconnPtr conn, String theme); - int flib_netconn_send_mapDrawdata(NetconnPtr conn, ByteArrayPtr drawData, NativeSizeT size); - int flib_netconn_send_script(NetconnPtr conn, String scriptName); - int flib_netconn_send_scheme(NetconnPtr conn, SchemePtr scheme); - int flib_netconn_send_roundfinished(NetconnPtr conn, boolean withoutError); - int flib_netconn_send_ban(NetconnPtr conn, String playerName); - int flib_netconn_send_kick(NetconnPtr conn, String playerName); - int flib_netconn_send_playerInfo(NetconnPtr conn, String playerName); - int flib_netconn_send_playerFollow(NetconnPtr conn, String playerName); - int flib_netconn_send_startGame(NetconnPtr conn); - int flib_netconn_send_toggleRestrictJoins(NetconnPtr conn); - int flib_netconn_send_toggleRestrictTeams(NetconnPtr conn); - int flib_netconn_send_clearAccountsCache(NetconnPtr conn); - int flib_netconn_send_setServerVar(NetconnPtr conn, String name, String value); - int flib_netconn_send_getServerVars(NetconnPtr conn); - - void flib_netconn_onMessage(NetconnPtr conn, IntStrCallback callback, Pointer context); - void flib_netconn_onClientFlags(NetconnPtr conn, StrStrBoolCallback callback, Pointer context); - void flib_netconn_onChat(NetconnPtr conn, StrStrCallback callback, Pointer context); - void flib_netconn_onConnected(NetconnPtr conn, VoidCallback callback, Pointer context); - void flib_netconn_onDisconnected(NetconnPtr conn, IntStrCallback callback, Pointer context); - void flib_netconn_onRoomlist(NetconnPtr conn, RoomListCallback callback, Pointer context); - void flib_netconn_onRoomAdd(NetconnPtr conn, RoomCallback callback, Pointer context); - void flib_netconn_onRoomDelete(NetconnPtr conn, StrCallback callback, Pointer context); - void flib_netconn_onRoomUpdate(NetconnPtr conn, StrRoomCallback callback, Pointer context); - void flib_netconn_onLobbyJoin(NetconnPtr conn, StrCallback callback, Pointer context); - void flib_netconn_onLobbyLeave(NetconnPtr conn, StrStrCallback callback, Pointer context); - void flib_netconn_onNickTaken(NetconnPtr conn, StrCallback callback, Pointer context); - void flib_netconn_onPasswordRequest(NetconnPtr conn, StrCallback callback, Pointer context); - void flib_netconn_onEnterRoom(NetconnPtr conn, BoolCallback callback, Pointer context); - void flib_netconn_onLeaveRoom(NetconnPtr conn, IntStrCallback callback, Pointer context); - void flib_netconn_onTeamAdd(NetconnPtr conn, TeamCallback callback, Pointer context); - void flib_netconn_onTeamDelete(NetconnPtr conn, StrCallback callback, Pointer context); - void flib_netconn_onRoomJoin(NetconnPtr conn, StrCallback callback, Pointer context); - void flib_netconn_onRoomLeave(NetconnPtr conn, StrStrCallback callback, Pointer context); - void flib_netconn_onRunGame(NetconnPtr conn, VoidCallback callback, Pointer context); - void flib_netconn_onTeamAccepted(NetconnPtr conn, StrCallback callback, Pointer context); - void flib_netconn_onHogCountChanged(NetconnPtr conn, StrIntCallback callback, Pointer context); - void flib_netconn_onTeamColorChanged(NetconnPtr conn, StrIntCallback callback, Pointer context); - void flib_netconn_onEngineMessage(NetconnPtr conn, BytesCallback callback, Pointer context); - void flib_netconn_onSchemeChanged(NetconnPtr conn, SchemeCallback callback, Pointer context); - void flib_netconn_onMapChanged(NetconnPtr conn, MapIntCallback callback, Pointer context); - void flib_netconn_onScriptChanged(NetconnPtr conn, StrCallback callback, Pointer context); - void flib_netconn_onWeaponsetChanged(NetconnPtr conn, WeaponsetCallback callback, Pointer context); - void flib_netconn_onServerVar(NetconnPtr conn, StrStrCallback callback, Pointer context); - - // ipc/gameconn.h - - GameconnPtr flib_gameconn_create(String playerName, GameSetupPtr setup, boolean netgame); - GameconnPtr flib_gameconn_create_playdemo(ByteArrayPtr demo, NativeSizeT size); - GameconnPtr flib_gameconn_create_loadgame(String playerName, ByteArrayPtr save, NativeSizeT size); - GameconnPtr flib_gameconn_create_campaign(String playerName, String seed, String script); - - void flib_gameconn_destroy(GameconnPtr conn); - int flib_gameconn_getport(GameconnPtr conn); - void flib_gameconn_tick(GameconnPtr conn); - - int flib_gameconn_send_enginemsg(GameconnPtr conn, ByteArrayPtr data, NativeSizeT len); - int flib_gameconn_send_textmsg(GameconnPtr conn, int msgtype, String msg); - int flib_gameconn_send_chatmsg(GameconnPtr conn, String playername, String msg); - int flib_gameconn_send_quit(GameconnPtr conn); - int flib_gameconn_send_cmd(GameconnPtr conn, String cmdString); - - void flib_gameconn_onConnect(GameconnPtr conn, VoidCallback callback, Pointer context); - void flib_gameconn_onDisconnect(GameconnPtr conn, IntCallback callback, Pointer context); - void flib_gameconn_onErrorMessage(GameconnPtr conn, StrCallback callback, Pointer context); - void flib_gameconn_onChat(GameconnPtr conn, StrBoolCallback callback, Pointer context); - void flib_gameconn_onGameRecorded(GameconnPtr conn, BytesBoolCallback callback, Pointer context); - void flib_gameconn_onEngineMessage(GameconnPtr conn, BytesCallback callback, Pointer context); - - // ipc/mapconn.h - MapconnPtr flib_mapconn_create(MapRecipePtr mapdesc); - void flib_mapconn_destroy(MapconnPtr conn); - int flib_mapconn_getport(MapconnPtr conn); - void flib_mapconn_onSuccess(MapconnPtr conn, MapimageCallback callback, Pointer context); - void flib_mapconn_onFailure(MapconnPtr conn, StrCallback callback, Pointer context); - void flib_mapconn_tick(MapconnPtr conn); - - // model/schemelist.h - SchemelistPtr flib_schemelist_from_ini(String filename); - int flib_schemelist_to_ini(String filename, SchemelistPtr list); - void flib_schemelist_destroy(SchemelistPtr list); - - // model/team.h - TeamPtr flib_team_from_ini(String filename); - int flib_team_to_ini(String filename, TeamPtr team); - void flib_team_destroy(TeamPtr team); - - // model/weapon.h - WeaponsetListPtr flib_weaponsetlist_from_ini(String filename); - int flib_weaponsetlist_to_ini(String filename, WeaponsetListPtr weaponsets); - void flib_weaponsetlist_destroy(WeaponsetListPtr list); - - // model/gamesetup.h - void flib_gamesetup_destroy(GameSetupPtr gamesetup); - - // util/logging.h - void flib_log_setLevel(int level); - void flib_log_setCallback(LogCallback callback); +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * This file is not directly part of the frontlib and is not required to build it. + * However, it is recommended to include it in compilation when building for Android. The purpose of this file + * is to ensure consistency between the function signatures of the JNA Java bindings of the Android port and the + * frontlib functions. + * + * This file, in essence, consists only of function declarations. They are duplicates of function declarations + * from the frontlib headers that are referenced from JNA bindings. If the signature of one of these functions + * changes in the frontlib, it will no longer match the signature in this file, and the compiler will show an error. + * If that happens, you need to update the JNA bindings in Hedgeroid to match the new function signature, and then + * update this file. + * + * The reason for all this is that JNA does not actually know the function signatures of the functions it binds, + * it derives them from Java method declarations. If those do not match the actual function signatures, you will + * only notice when you suddenly get strange (and possibly hard to track down) problems at runtime. This file is + * an attempt to detect these problems at compile time instead. Notice that it will NOT detect changes to structs + * or constants though, which also require updates to the JNA bindings. + */ + +/* + * Before we include the frontlib headers, we define away the const keyword. This is necessary because there is no + * distinction between const and non-const types on the JNA side, and we don't want the compiler to complain because + * of bad constness. + * + * This is so evil, but it works... + */ +#define const + +#include "../frontlib.h" + +/* + * Now we map the Java types to the corresponding C types... + */ +typedef flib_netconn *NetconnPtr; +typedef flib_gameconn *GameconnPtr; +typedef flib_mapconn *MapconnPtr; +typedef flib_metascheme *MetaschemePtr; +typedef flib_room **RoomArrayPtr; +typedef flib_weaponset *WeaponsetPtr; +typedef flib_weaponsetlist *WeaponsetListPtr; +typedef flib_map *MapRecipePtr; +typedef flib_scheme *SchemePtr; +typedef flib_schemelist *SchemelistPtr; + +typedef flib_room *RoomPtr; +typedef flib_team *TeamPtr; +typedef flib_gamesetup *GameSetupPtr; +typedef bool boolean; +typedef size_t NativeSizeT; +typedef void *Pointer; +typedef uint8_t *ByteArrayPtr; +typedef char *String; + +/* + * Mapping callback types + */ +typedef void (*VoidCallback)(Pointer context); +typedef void (*StrCallback)(Pointer context, String arg1); +typedef void (*IntCallback)(Pointer context, int arg1); +typedef void (*IntStrCallback)(Pointer context, int arg1, String arg2); +typedef void (*StrIntCallback)(Pointer context, String arg1, int arg2); +typedef void (*StrStrCallback)(Pointer context, String arg1, String arg2); +typedef void (*StrStrBoolCallback)(Pointer context, String arg1, String arg2, boolean arg3); +typedef void (*RoomCallback)(Pointer context, RoomPtr arg1); +typedef void (*RoomListCallback)(Pointer context, RoomArrayPtr arg1, int arg2); +typedef void (*StrRoomCallback)(Pointer context, String arg1, RoomPtr arg2); +typedef void (*BoolCallback)(Pointer context, boolean arg1); +typedef void (*StrBoolCallback)(Pointer context, String arg1, boolean arg2); +typedef void (*TeamCallback)(Pointer context, TeamPtr arg1); +typedef void (*BytesCallback)(Pointer context, const uint8_t *buffer, NativeSizeT size); +typedef void (*BytesBoolCallback)(Pointer context, const uint8_t *buffer, NativeSizeT size, boolean arg3); +typedef void (*SchemeCallback)(Pointer context, SchemePtr arg1); +typedef void (*MapIntCallback)(Pointer context, MapRecipePtr arg1, int arg2); +typedef void (*WeaponsetCallback)(Pointer context, WeaponsetPtr arg1); +typedef void (*MapimageCallback)(Pointer context, const uint8_t *mapimage, int hogs); +typedef void (*LogCallback)(int arg1, String arg2); + +/* + * Below here are the copypasted method declarations from the JNA bindings + */ + + // frontlib.h + int flib_init(); + void flib_quit(); + + // hwconsts.h + int flib_get_teamcolor_count(); + int flib_get_hedgehogs_per_team(); + int flib_get_weapons_count(); + MetaschemePtr flib_get_metascheme(); + + // net/netconn.h + NetconnPtr flib_netconn_create(String playerName, String dataDirPath, String host, int port); + void flib_netconn_destroy(NetconnPtr conn); + + void flib_netconn_tick(NetconnPtr conn); + boolean flib_netconn_is_chief(NetconnPtr conn); + String flib_netconn_get_playername(NetconnPtr conn); + GameSetupPtr flib_netconn_create_gamesetup(NetconnPtr conn); + int flib_netconn_send_quit(NetconnPtr conn, String quitmsg); + int flib_netconn_send_chat(NetconnPtr conn, String chat); + int flib_netconn_send_teamchat(NetconnPtr conn, String msg); + int flib_netconn_send_password(NetconnPtr conn, String passwd); + int flib_netconn_send_nick(NetconnPtr conn, String nick); + int flib_netconn_send_request_roomlist(NetconnPtr conn); + int flib_netconn_send_joinRoom(NetconnPtr conn, String room); + int flib_netconn_send_createRoom(NetconnPtr conn, String room); + int flib_netconn_send_renameRoom(NetconnPtr conn, String roomName); + int flib_netconn_send_leaveRoom(NetconnPtr conn, String msg); + int flib_netconn_send_toggleReady(NetconnPtr conn); + int flib_netconn_send_addTeam(NetconnPtr conn, TeamPtr team); + int flib_netconn_send_removeTeam(NetconnPtr conn, String teamname); + int flib_netconn_send_engineMessage(NetconnPtr conn, ByteArrayPtr message, NativeSizeT size); + int flib_netconn_send_teamHogCount(NetconnPtr conn, String teamname, int hogcount); + int flib_netconn_send_teamColor(NetconnPtr conn, String teamname, int colorIndex); + int flib_netconn_send_weaponset(NetconnPtr conn, WeaponsetPtr weaponset); + int flib_netconn_send_map(NetconnPtr conn, MapRecipePtr map); + int flib_netconn_send_mapName(NetconnPtr conn, String mapName); + int flib_netconn_send_mapGen(NetconnPtr conn, int mapGen); + int flib_netconn_send_mapTemplate(NetconnPtr conn, int templateFilter); + int flib_netconn_send_mapMazeSize(NetconnPtr conn, int mazeSize); + int flib_netconn_send_mapSeed(NetconnPtr conn, String seed); + int flib_netconn_send_mapTheme(NetconnPtr conn, String theme); + int flib_netconn_send_mapDrawdata(NetconnPtr conn, ByteArrayPtr drawData, NativeSizeT size); + int flib_netconn_send_script(NetconnPtr conn, String scriptName); + int flib_netconn_send_scheme(NetconnPtr conn, SchemePtr scheme); + int flib_netconn_send_roundfinished(NetconnPtr conn, boolean withoutError); + int flib_netconn_send_ban(NetconnPtr conn, String playerName); + int flib_netconn_send_kick(NetconnPtr conn, String playerName); + int flib_netconn_send_playerInfo(NetconnPtr conn, String playerName); + int flib_netconn_send_playerFollow(NetconnPtr conn, String playerName); + int flib_netconn_send_startGame(NetconnPtr conn); + int flib_netconn_send_toggleRestrictJoins(NetconnPtr conn); + int flib_netconn_send_toggleRestrictTeams(NetconnPtr conn); + int flib_netconn_send_clearAccountsCache(NetconnPtr conn); + int flib_netconn_send_setServerVar(NetconnPtr conn, String name, String value); + int flib_netconn_send_getServerVars(NetconnPtr conn); + + void flib_netconn_onMessage(NetconnPtr conn, IntStrCallback callback, Pointer context); + void flib_netconn_onClientFlags(NetconnPtr conn, StrStrBoolCallback callback, Pointer context); + void flib_netconn_onChat(NetconnPtr conn, StrStrCallback callback, Pointer context); + void flib_netconn_onConnected(NetconnPtr conn, VoidCallback callback, Pointer context); + void flib_netconn_onDisconnected(NetconnPtr conn, IntStrCallback callback, Pointer context); + void flib_netconn_onRoomlist(NetconnPtr conn, RoomListCallback callback, Pointer context); + void flib_netconn_onRoomAdd(NetconnPtr conn, RoomCallback callback, Pointer context); + void flib_netconn_onRoomDelete(NetconnPtr conn, StrCallback callback, Pointer context); + void flib_netconn_onRoomUpdate(NetconnPtr conn, StrRoomCallback callback, Pointer context); + void flib_netconn_onLobbyJoin(NetconnPtr conn, StrCallback callback, Pointer context); + void flib_netconn_onLobbyLeave(NetconnPtr conn, StrStrCallback callback, Pointer context); + void flib_netconn_onNickTaken(NetconnPtr conn, StrCallback callback, Pointer context); + void flib_netconn_onPasswordRequest(NetconnPtr conn, StrCallback callback, Pointer context); + void flib_netconn_onEnterRoom(NetconnPtr conn, BoolCallback callback, Pointer context); + void flib_netconn_onLeaveRoom(NetconnPtr conn, IntStrCallback callback, Pointer context); + void flib_netconn_onTeamAdd(NetconnPtr conn, TeamCallback callback, Pointer context); + void flib_netconn_onTeamDelete(NetconnPtr conn, StrCallback callback, Pointer context); + void flib_netconn_onRoomJoin(NetconnPtr conn, StrCallback callback, Pointer context); + void flib_netconn_onRoomLeave(NetconnPtr conn, StrStrCallback callback, Pointer context); + void flib_netconn_onRunGame(NetconnPtr conn, VoidCallback callback, Pointer context); + void flib_netconn_onTeamAccepted(NetconnPtr conn, StrCallback callback, Pointer context); + void flib_netconn_onHogCountChanged(NetconnPtr conn, StrIntCallback callback, Pointer context); + void flib_netconn_onTeamColorChanged(NetconnPtr conn, StrIntCallback callback, Pointer context); + void flib_netconn_onEngineMessage(NetconnPtr conn, BytesCallback callback, Pointer context); + void flib_netconn_onSchemeChanged(NetconnPtr conn, SchemeCallback callback, Pointer context); + void flib_netconn_onMapChanged(NetconnPtr conn, MapIntCallback callback, Pointer context); + void flib_netconn_onScriptChanged(NetconnPtr conn, StrCallback callback, Pointer context); + void flib_netconn_onWeaponsetChanged(NetconnPtr conn, WeaponsetCallback callback, Pointer context); + void flib_netconn_onServerVar(NetconnPtr conn, StrStrCallback callback, Pointer context); + + // ipc/gameconn.h + + GameconnPtr flib_gameconn_create(String playerName, GameSetupPtr setup, boolean netgame); + GameconnPtr flib_gameconn_create_playdemo(ByteArrayPtr demo, NativeSizeT size); + GameconnPtr flib_gameconn_create_loadgame(String playerName, ByteArrayPtr save, NativeSizeT size); + GameconnPtr flib_gameconn_create_campaign(String playerName, String seed, String script); + + void flib_gameconn_destroy(GameconnPtr conn); + int flib_gameconn_getport(GameconnPtr conn); + void flib_gameconn_tick(GameconnPtr conn); + + int flib_gameconn_send_enginemsg(GameconnPtr conn, ByteArrayPtr data, NativeSizeT len); + int flib_gameconn_send_textmsg(GameconnPtr conn, int msgtype, String msg); + int flib_gameconn_send_chatmsg(GameconnPtr conn, String playername, String msg); + int flib_gameconn_send_quit(GameconnPtr conn); + int flib_gameconn_send_cmd(GameconnPtr conn, String cmdString); + + void flib_gameconn_onConnect(GameconnPtr conn, VoidCallback callback, Pointer context); + void flib_gameconn_onDisconnect(GameconnPtr conn, IntCallback callback, Pointer context); + void flib_gameconn_onErrorMessage(GameconnPtr conn, StrCallback callback, Pointer context); + void flib_gameconn_onChat(GameconnPtr conn, StrBoolCallback callback, Pointer context); + void flib_gameconn_onGameRecorded(GameconnPtr conn, BytesBoolCallback callback, Pointer context); + void flib_gameconn_onEngineMessage(GameconnPtr conn, BytesCallback callback, Pointer context); + + // ipc/mapconn.h + MapconnPtr flib_mapconn_create(MapRecipePtr mapdesc); + void flib_mapconn_destroy(MapconnPtr conn); + int flib_mapconn_getport(MapconnPtr conn); + void flib_mapconn_onSuccess(MapconnPtr conn, MapimageCallback callback, Pointer context); + void flib_mapconn_onFailure(MapconnPtr conn, StrCallback callback, Pointer context); + void flib_mapconn_tick(MapconnPtr conn); + + // model/schemelist.h + SchemelistPtr flib_schemelist_from_ini(String filename); + int flib_schemelist_to_ini(String filename, SchemelistPtr list); + void flib_schemelist_destroy(SchemelistPtr list); + + // model/team.h + TeamPtr flib_team_from_ini(String filename); + int flib_team_to_ini(String filename, TeamPtr team); + void flib_team_destroy(TeamPtr team); + + // model/weapon.h + WeaponsetListPtr flib_weaponsetlist_from_ini(String filename); + int flib_weaponsetlist_to_ini(String filename, WeaponsetListPtr weaponsets); + void flib_weaponsetlist_destroy(WeaponsetListPtr list); + + // model/gamesetup.h + void flib_gamesetup_destroy(GameSetupPtr gamesetup); + + // util/logging.h + void flib_log_setLevel(int level); + void flib_log_setCallback(LogCallback callback); diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/frontlib.c --- a/project_files/frontlib/frontlib.c Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/frontlib.c Tue Jan 21 22:43:06 2014 +0100 @@ -1,37 +1,37 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "frontlib.h" -#include "util/logging.h" -#include - -int flib_init() { - flib_log_d("Initializing frontlib"); - if(SDLNet_Init()==-1) { - flib_log_e("Error in SDLNet_Init: %s", SDLNet_GetError()); - return -1; - } - - return 0; -} - -void flib_quit() { - flib_log_d("Shutting down frontlib"); - SDLNet_Quit(); -} +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "frontlib.h" +#include "util/logging.h" +#include + +int flib_init() { + flib_log_d("Initializing frontlib"); + if(SDLNet_Init()==-1) { + flib_log_e("Error in SDLNet_Init: %s", SDLNet_GetError()); + return -1; + } + + return 0; +} + +void flib_quit() { + flib_log_d("Shutting down frontlib"); + SDLNet_Quit(); +} diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/frontlib.h --- a/project_files/frontlib/frontlib.h Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/frontlib.h Tue Jan 21 22:43:06 2014 +0100 @@ -1,48 +1,48 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/* - * Public header file for the hedgewars frontent networking library. - * - * This is the only header you should need to include from frontend code. - */ - -#ifndef FRONTLIB_H_ -#define FRONTLIB_H_ - -#include "ipc/gameconn.h" -#include "ipc/mapconn.h" -#include "net/netconn.h" -#include "util/logging.h" -#include "model/schemelist.h" - -/** - * Call this function before anything else in this library. - * Returns 0 on success, -1 on error. - */ -int flib_init(); - -/** - * Free resources associated with the library. Call this function once - * the library is no longer needed. You can re-initialize the library by calling - * flib_init again. - */ -void flib_quit(); - -#endif /* FRONTLIB_H_ */ +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * Public header file for the hedgewars frontent networking library. + * + * This is the only header you should need to include from frontend code. + */ + +#ifndef FRONTLIB_H_ +#define FRONTLIB_H_ + +#include "ipc/gameconn.h" +#include "ipc/mapconn.h" +#include "net/netconn.h" +#include "util/logging.h" +#include "model/schemelist.h" + +/** + * Call this function before anything else in this library. + * Returns 0 on success, -1 on error. + */ +int flib_init(); + +/** + * Free resources associated with the library. Call this function once + * the library is no longer needed. You can re-initialize the library by calling + * flib_init again. + */ +void flib_quit(); + +#endif /* FRONTLIB_H_ */ diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/hwconsts.c --- a/project_files/frontlib/hwconsts.c Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/hwconsts.c Tue Jan 21 22:43:06 2014 +0100 @@ -1,100 +1,100 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "hwconsts.h" - -const uint32_t flib_teamcolors[] = HW_TEAMCOLOR_ARRAY; -const size_t flib_teamcolor_count = sizeof(flib_teamcolors)/sizeof(uint32_t)-1; - -static const flib_metascheme_setting metaSchemeSettings[] = { - { .name = "damagefactor", .times1000 = false, .engineCommand = "e$damagepct", .maxMeansInfinity = false, .min = 10, .max = 300, .def = 100 }, - { .name = "turntime", .times1000 = true, .engineCommand = "e$turntime", .maxMeansInfinity = true, .min = 1, .max = 9999, .def = 45 }, - { .name = "health", .times1000 = false, .engineCommand = NULL, .maxMeansInfinity = false, .min = 50, .max = 200, .def = 100 }, - { .name = "suddendeath", .times1000 = false, .engineCommand = "e$sd_turns", .maxMeansInfinity = true, .min = 0, .max = 50, .def = 15 }, - { .name = "caseprobability", .times1000 = false, .engineCommand = "e$casefreq", .maxMeansInfinity = false, .min = 0, .max = 9, .def = 5 }, - { .name = "minestime", .times1000 = true, .engineCommand = "e$minestime", .maxMeansInfinity = false, .min = -1, .max = 5, .def = 3 }, - { .name = "minesnum", .times1000 = false, .engineCommand = "e$minesnum", .maxMeansInfinity = false, .min = 0, .max = 80, .def = 4 }, - { .name = "minedudpct", .times1000 = false, .engineCommand = "e$minedudpct", .maxMeansInfinity = false, .min = 0, .max = 100, .def = 0 }, - { .name = "explosives", .times1000 = false, .engineCommand = "e$explosives", .maxMeansInfinity = false, .min = 0, .max = 40, .def = 2 }, - { .name = "healthprobability", .times1000 = false, .engineCommand = "e$healthprob", .maxMeansInfinity = false, .min = 0, .max = 100, .def = 35 }, - { .name = "healthcaseamount", .times1000 = false, .engineCommand = "e$hcaseamount", .maxMeansInfinity = false, .min = 0, .max = 200, .def = 25 }, - { .name = "waterrise", .times1000 = false, .engineCommand = "e$waterrise", .maxMeansInfinity = false, .min = 0, .max = 100, .def = 47 }, - { .name = "healthdecrease", .times1000 = false, .engineCommand = "e$healthdec", .maxMeansInfinity = false, .min = 0, .max = 100, .def = 5 }, - { .name = "ropepct", .times1000 = false, .engineCommand = "e$ropepct", .maxMeansInfinity = false, .min = 25, .max = 999, .def = 100 }, - { .name = "getawaytime", .times1000 = false, .engineCommand = "e$getawaytime", .maxMeansInfinity = false, .min = 0, .max = 999, .def = 100 } -}; - -static const flib_metascheme_mod metaSchemeMods[] = { - { .name = "fortsmode", .bitmaskIndex = 12 }, - { .name = "divteams", .bitmaskIndex = 4 }, - { .name = "solidland", .bitmaskIndex = 2 }, - { .name = "border", .bitmaskIndex = 3 }, - { .name = "lowgrav", .bitmaskIndex = 5 }, - { .name = "laser", .bitmaskIndex = 6 }, - { .name = "invulnerability", .bitmaskIndex = 7 }, - { .name = "resethealth", .bitmaskIndex = 8 }, - { .name = "vampiric", .bitmaskIndex = 9 }, - { .name = "karma", .bitmaskIndex = 10 }, - { .name = "artillery", .bitmaskIndex = 11 }, - { .name = "randomorder", .bitmaskIndex = 13 }, - { .name = "king", .bitmaskIndex = 14 }, - { .name = "placehog", .bitmaskIndex = 15 }, - { .name = "sharedammo", .bitmaskIndex = 16 }, - { .name = "disablegirders", .bitmaskIndex = 17 }, - { .name = "disablelandobjects", .bitmaskIndex = 18 }, - { .name = "aisurvival", .bitmaskIndex = 19 }, - { .name = "infattack", .bitmaskIndex = 20 }, - { .name = "resetweps", .bitmaskIndex = 21 }, - { .name = "perhogammo", .bitmaskIndex = 22 }, - { .name = "disablewind", .bitmaskIndex = 23 }, - { .name = "morewind", .bitmaskIndex = 24 }, - { .name = "tagteam", .bitmaskIndex = 25 }, - { .name = "bottomborder", .bitmaskIndex = 26 } -}; - -const flib_metascheme flib_meta = { - .settingCount = sizeof(metaSchemeSettings)/sizeof(flib_metascheme_setting), - .modCount = sizeof(metaSchemeMods)/sizeof(flib_metascheme_mod), - .settings = metaSchemeSettings, - .mods = metaSchemeMods -}; - -uint32_t flib_get_teamcolor(int colorIndex) { - if(colorIndex>=0 && colorIndex < flib_teamcolor_count) { - return flib_teamcolors[colorIndex]; - } else { - return 0; - } -} - -int flib_get_teamcolor_count() { - return flib_teamcolor_count; -} - -int flib_get_hedgehogs_per_team() { - return HEDGEHOGS_PER_TEAM; -} - -int flib_get_weapons_count() { - return WEAPONS_COUNT; -} - -const flib_metascheme *flib_get_metascheme() { - return &flib_meta; -} +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "hwconsts.h" + +const uint32_t flib_teamcolors[] = HW_TEAMCOLOR_ARRAY; +const size_t flib_teamcolor_count = sizeof(flib_teamcolors)/sizeof(uint32_t)-1; + +static const flib_metascheme_setting metaSchemeSettings[] = { + { .name = "damagefactor", .times1000 = false, .engineCommand = "e$damagepct", .maxMeansInfinity = false, .min = 10, .max = 300, .def = 100 }, + { .name = "turntime", .times1000 = true, .engineCommand = "e$turntime", .maxMeansInfinity = true, .min = 1, .max = 9999, .def = 45 }, + { .name = "health", .times1000 = false, .engineCommand = NULL, .maxMeansInfinity = false, .min = 50, .max = 200, .def = 100 }, + { .name = "suddendeath", .times1000 = false, .engineCommand = "e$sd_turns", .maxMeansInfinity = true, .min = 0, .max = 50, .def = 15 }, + { .name = "caseprobability", .times1000 = false, .engineCommand = "e$casefreq", .maxMeansInfinity = false, .min = 0, .max = 9, .def = 5 }, + { .name = "minestime", .times1000 = true, .engineCommand = "e$minestime", .maxMeansInfinity = false, .min = -1, .max = 5, .def = 3 }, + { .name = "minesnum", .times1000 = false, .engineCommand = "e$minesnum", .maxMeansInfinity = false, .min = 0, .max = 80, .def = 4 }, + { .name = "minedudpct", .times1000 = false, .engineCommand = "e$minedudpct", .maxMeansInfinity = false, .min = 0, .max = 100, .def = 0 }, + { .name = "explosives", .times1000 = false, .engineCommand = "e$explosives", .maxMeansInfinity = false, .min = 0, .max = 40, .def = 2 }, + { .name = "healthprobability", .times1000 = false, .engineCommand = "e$healthprob", .maxMeansInfinity = false, .min = 0, .max = 100, .def = 35 }, + { .name = "healthcaseamount", .times1000 = false, .engineCommand = "e$hcaseamount", .maxMeansInfinity = false, .min = 0, .max = 200, .def = 25 }, + { .name = "waterrise", .times1000 = false, .engineCommand = "e$waterrise", .maxMeansInfinity = false, .min = 0, .max = 100, .def = 47 }, + { .name = "healthdecrease", .times1000 = false, .engineCommand = "e$healthdec", .maxMeansInfinity = false, .min = 0, .max = 100, .def = 5 }, + { .name = "ropepct", .times1000 = false, .engineCommand = "e$ropepct", .maxMeansInfinity = false, .min = 25, .max = 999, .def = 100 }, + { .name = "getawaytime", .times1000 = false, .engineCommand = "e$getawaytime", .maxMeansInfinity = false, .min = 0, .max = 999, .def = 100 } +}; + +static const flib_metascheme_mod metaSchemeMods[] = { + { .name = "fortsmode", .bitmaskIndex = 12 }, + { .name = "divteams", .bitmaskIndex = 4 }, + { .name = "solidland", .bitmaskIndex = 2 }, + { .name = "border", .bitmaskIndex = 3 }, + { .name = "lowgrav", .bitmaskIndex = 5 }, + { .name = "laser", .bitmaskIndex = 6 }, + { .name = "invulnerability", .bitmaskIndex = 7 }, + { .name = "resethealth", .bitmaskIndex = 8 }, + { .name = "vampiric", .bitmaskIndex = 9 }, + { .name = "karma", .bitmaskIndex = 10 }, + { .name = "artillery", .bitmaskIndex = 11 }, + { .name = "randomorder", .bitmaskIndex = 13 }, + { .name = "king", .bitmaskIndex = 14 }, + { .name = "placehog", .bitmaskIndex = 15 }, + { .name = "sharedammo", .bitmaskIndex = 16 }, + { .name = "disablegirders", .bitmaskIndex = 17 }, + { .name = "disablelandobjects", .bitmaskIndex = 18 }, + { .name = "aisurvival", .bitmaskIndex = 19 }, + { .name = "infattack", .bitmaskIndex = 20 }, + { .name = "resetweps", .bitmaskIndex = 21 }, + { .name = "perhogammo", .bitmaskIndex = 22 }, + { .name = "disablewind", .bitmaskIndex = 23 }, + { .name = "morewind", .bitmaskIndex = 24 }, + { .name = "tagteam", .bitmaskIndex = 25 }, + { .name = "bottomborder", .bitmaskIndex = 26 } +}; + +const flib_metascheme flib_meta = { + .settingCount = sizeof(metaSchemeSettings)/sizeof(flib_metascheme_setting), + .modCount = sizeof(metaSchemeMods)/sizeof(flib_metascheme_mod), + .settings = metaSchemeSettings, + .mods = metaSchemeMods +}; + +uint32_t flib_get_teamcolor(int colorIndex) { + if(colorIndex>=0 && colorIndex < flib_teamcolor_count) { + return flib_teamcolors[colorIndex]; + } else { + return 0; + } +} + +int flib_get_teamcolor_count() { + return flib_teamcolor_count; +} + +int flib_get_hedgehogs_per_team() { + return HEDGEHOGS_PER_TEAM; +} + +int flib_get_weapons_count() { + return WEAPONS_COUNT; +} + +const flib_metascheme *flib_get_metascheme() { + return &flib_meta; +} diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/hwconsts.h --- a/project_files/frontlib/hwconsts.h Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/hwconsts.h Tue Jan 21 22:43:06 2014 +0100 @@ -1,118 +1,118 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (c) 2004-2014 Andrey Korotaev - * Copyright (c) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -/** - * This file contains important constants which might need to be changed to adapt to - * changes in the engine or protocols. - * - * It also contains getter functions for some constants (in particular for constants - * that are important for the layout of data structures), so that client code can - * query the constants that the library was built with. - */ - -#ifndef HWCONSTS_H_ -#define HWCONSTS_H_ - -#include -#include -#include - -#define HEDGEHOGS_PER_TEAM 8 -#define DEFAULT_HEDGEHOG_COUNT 4 -#define DEFAULT_COLOR_INDEX 0 - -#define NETGAME_DEFAULT_PORT 46631 -#define PROTOCOL_VERSION 42 -#define MIN_SERVER_VERSION 1 - -//! Used for sending scripts to the engine -#define MULTIPLAYER_SCRIPT_PATH "Scripts/Multiplayer/" - -#define WEAPONS_COUNT 56 - -// TODO allow frontend to override these? -/*! A merge of mikade/bugq colours w/ a bit of channel feedback */ -#define HW_TEAMCOLOR_ARRAY { UINT32_C(0xffff0204), /*! red */ \ - UINT32_C(0xff4980c1), /*! blue */ \ - UINT32_C(0xff1de6ba), /*! teal */ \ - UINT32_C(0xffb541ef), /*! purple */ \ - UINT32_C(0xffe55bb0), /*! pink */ \ - UINT32_C(0xff20bf00), /*! green */ \ - UINT32_C(0xfffe8b0e), /*! orange */ \ - UINT32_C(0xff5f3605), /*! brown */ \ - UINT32_C(0xffffff01), /*! yellow */ \ - /*! add new colors here */ \ - 0 } /*! Keep this 0 at the end */ - -extern const size_t flib_teamcolor_count; -extern const uint32_t flib_teamcolors[]; - -/** - * Returns the team color (ARGB) corresponding to the color index (0 if index out of bounds) - */ -uint32_t flib_get_teamcolor(int colorIndex); - -/** - * Returns the number of team colors (i.e. the length of the flib_teamcolors array) - */ -int flib_get_teamcolor_count(); - -/** - * Returns the HEDGEHOGS_PER_TEAM constant - */ -int flib_get_hedgehogs_per_team(); - -/** - * Returns the WEAPONS_COUNT constant - */ -int flib_get_weapons_count(); - -/*! - * These structs define the meaning of values in the flib_scheme struct, i.e. their correspondence to - * ini settings, engine commands and positions in the network protocol (the last is encoded in the - * order of settings/mods). - */ -typedef struct { - const char *name; //!< A name identifying this setting (used as key in the schemes file) - const char *engineCommand; //!< The command needed to send the setting to the engine. May be null if the setting is not sent to the engine (for the "health" setting) - const bool maxMeansInfinity; //!< If true, send a very high number to the engine if the setting is equal to its maximum - const bool times1000; //!< If true (for time-based settings), multiply the setting by 1000 before sending it to the engine. - const int min; //!< The smallest allowed value - const int max; //!< The highest allowed value - const int def; //!< The default value -} flib_metascheme_setting; - -typedef struct { - const char *name; //!< A name identifying this mod (used as key in the schemes file) - const int bitmaskIndex; //!< Mods are sent to the engine in a single integer, this field describes which bit of that integer is used - //! for this particular mod. -} flib_metascheme_mod; - -typedef struct { - const int settingCount; - const int modCount; - const flib_metascheme_setting *settings; - const flib_metascheme_mod *mods; -} flib_metascheme; - -extern const flib_metascheme flib_meta; - -const flib_metascheme *flib_get_metascheme(); - -#endif +/* + * Hedgewars, a free turn based strategy game + * Copyright (c) 2004-2014 Andrey Korotaev + * Copyright (c) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +/** + * This file contains important constants which might need to be changed to adapt to + * changes in the engine or protocols. + * + * It also contains getter functions for some constants (in particular for constants + * that are important for the layout of data structures), so that client code can + * query the constants that the library was built with. + */ + +#ifndef HWCONSTS_H_ +#define HWCONSTS_H_ + +#include +#include +#include + +#define HEDGEHOGS_PER_TEAM 8 +#define DEFAULT_HEDGEHOG_COUNT 4 +#define DEFAULT_COLOR_INDEX 0 + +#define NETGAME_DEFAULT_PORT 46631 +#define PROTOCOL_VERSION 42 +#define MIN_SERVER_VERSION 1 + +//! Used for sending scripts to the engine +#define MULTIPLAYER_SCRIPT_PATH "Scripts/Multiplayer/" + +#define WEAPONS_COUNT 56 + +// TODO allow frontend to override these? +/*! A merge of mikade/bugq colours w/ a bit of channel feedback */ +#define HW_TEAMCOLOR_ARRAY { UINT32_C(0xffff0204), /*! red */ \ + UINT32_C(0xff4980c1), /*! blue */ \ + UINT32_C(0xff1de6ba), /*! teal */ \ + UINT32_C(0xffb541ef), /*! purple */ \ + UINT32_C(0xffe55bb0), /*! pink */ \ + UINT32_C(0xff20bf00), /*! green */ \ + UINT32_C(0xfffe8b0e), /*! orange */ \ + UINT32_C(0xff5f3605), /*! brown */ \ + UINT32_C(0xffffff01), /*! yellow */ \ + /*! add new colors here */ \ + 0 } /*! Keep this 0 at the end */ + +extern const size_t flib_teamcolor_count; +extern const uint32_t flib_teamcolors[]; + +/** + * Returns the team color (ARGB) corresponding to the color index (0 if index out of bounds) + */ +uint32_t flib_get_teamcolor(int colorIndex); + +/** + * Returns the number of team colors (i.e. the length of the flib_teamcolors array) + */ +int flib_get_teamcolor_count(); + +/** + * Returns the HEDGEHOGS_PER_TEAM constant + */ +int flib_get_hedgehogs_per_team(); + +/** + * Returns the WEAPONS_COUNT constant + */ +int flib_get_weapons_count(); + +/*! + * These structs define the meaning of values in the flib_scheme struct, i.e. their correspondence to + * ini settings, engine commands and positions in the network protocol (the last is encoded in the + * order of settings/mods). + */ +typedef struct { + const char *name; //!< A name identifying this setting (used as key in the schemes file) + const char *engineCommand; //!< The command needed to send the setting to the engine. May be null if the setting is not sent to the engine (for the "health" setting) + const bool maxMeansInfinity; //!< If true, send a very high number to the engine if the setting is equal to its maximum + const bool times1000; //!< If true (for time-based settings), multiply the setting by 1000 before sending it to the engine. + const int min; //!< The smallest allowed value + const int max; //!< The highest allowed value + const int def; //!< The default value +} flib_metascheme_setting; + +typedef struct { + const char *name; //!< A name identifying this mod (used as key in the schemes file) + const int bitmaskIndex; //!< Mods are sent to the engine in a single integer, this field describes which bit of that integer is used + //! for this particular mod. +} flib_metascheme_mod; + +typedef struct { + const int settingCount; + const int modCount; + const flib_metascheme_setting *settings; + const flib_metascheme_mod *mods; +} flib_metascheme; + +extern const flib_metascheme flib_meta; + +const flib_metascheme *flib_get_metascheme(); + +#endif diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/iniparser/LICENSE --- a/project_files/frontlib/iniparser/LICENSE Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/iniparser/LICENSE Tue Jan 21 22:43:06 2014 +0100 @@ -1,23 +1,23 @@ -Copyright (c) 2000-2012 by Nicolas Devillard. -MIT License - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +Copyright (c) 2000-2012 by Nicolas Devillard. +MIT License + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/iniparser/VERSION --- a/project_files/frontlib/iniparser/VERSION Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/iniparser/VERSION Tue Jan 21 22:43:06 2014 +0100 @@ -1,2 +1,2 @@ -This is version 3.1 of the iniparser library developed by N. Devillard. +This is version 3.1 of the iniparser library developed by N. Devillard. See http://ndevilla.free.fr/iniparser/ for details and new versions. \ No newline at end of file diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/iniparser/dictionary.c --- a/project_files/frontlib/iniparser/dictionary.c Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/iniparser/dictionary.c Tue Jan 21 22:43:06 2014 +0100 @@ -38,7 +38,7 @@ static void * mem_double(void * ptr, int size) { void * newptr ; - + newptr = calloc(2*size, 1); if (newptr==NULL) { return NULL ; @@ -224,7 +224,7 @@ unsigned hash ; if (d==NULL || key==NULL) return -1 ; - + /* Compute hash for this key */ hash = dictionary_hash(key) ; /* Find if value is already in dictionary */ @@ -367,7 +367,7 @@ /* Allocate dictionary */ printf("allocating...\n"); d = dictionary_new(0); - + /* Set values in dictionary */ printf("setting %d values...\n", NVALS); for (i=0 ; isize ; j++) { if (d->key[j]==NULL) continue ; - if (!strncmp(d->key[j], keym, seclen+1)) + if (!strncmp(d->key[j], keym, seclen+1)) nkeys++; } @@ -310,7 +310,7 @@ This function queries a dictionary and finds all keys in a given section. Each pointer in the returned char pointer-to-pointer is pointing to a string allocated in the dictionary; do not free or modify them. - + This function returns NULL in case of error. */ /*--------------------------------------------------------------------------*/ @@ -334,7 +334,7 @@ seclen = (int)strlen(s); sprintf(keym, "%s:", s); - + i = 0; for (j=0 ; jsize ; j++) { @@ -557,7 +557,7 @@ char * section, char * key, char * value) -{ +{ line_status sta ; char line[ASCIILINESZ+1]; int len ; @@ -571,7 +571,7 @@ sta = LINE_EMPTY ; } else if (line[0]=='#' || line[0]==';') { /* Comment line */ - sta = LINE_COMMENT ; + sta = LINE_COMMENT ; } else if (line[0]=='[' && line[len-1]==']') { /* Section name */ sscanf(line, "[%[^]]", section); diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/ipc/gameconn.c --- a/project_files/frontlib/ipc/gameconn.c Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/ipc/gameconn.c Tue Jan 21 22:43:06 2014 +0100 @@ -1,452 +1,452 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "gameconn.h" -#include "ipcbase.h" -#include "ipcprotocol.h" -#include "../util/logging.h" -#include "../util/util.h" -#include "../hwconsts.h" -#include -#include -#include - -typedef enum { - AWAIT_CONNECTION, - CONNECTED, - FINISHED -} gameconn_state; - -struct _flib_gameconn { - flib_ipcbase *ipcBase; - flib_vector *configBuffer; - flib_vector *demoBuffer; - char *playerName; - - gameconn_state state; - bool netgame; - int disconnectReason; - - void (*onConnectCb)(void* context); - void *onConnectCtx; - - void (*onDisconnectCb)(void* context, int reason); - void *onDisconnectCtx; - - void (*onErrorMessageCb)(void* context, const char *msg); - void *onErrorMessageCtx; - - void (*onChatCb)(void* context, const char *msg, bool teamchat); - void *onChatCtx; - - void (*onGameRecordedCb)(void *context, const uint8_t *record, size_t size, bool isSavegame); - void *onGameRecordedCtx; - - void (*onEngineMessageCb)(void *context, const uint8_t *em, size_t size); - void *onEngineMessageCtx; - - bool running; - bool destroyRequested; -}; - -static void defaultCallback_onErrorMessage(void* context, const char *msg) { - flib_log_w("Error from engine (no callback set): %s", msg); -} - -static void clearCallbacks(flib_gameconn *conn) { - flib_gameconn_onConnect(conn, NULL, NULL); - flib_gameconn_onDisconnect(conn, NULL, NULL); - flib_gameconn_onErrorMessage(conn, NULL, NULL); - flib_gameconn_onChat(conn, NULL, NULL); - flib_gameconn_onGameRecorded(conn, NULL, NULL); - flib_gameconn_onEngineMessage(conn, NULL, NULL); -} - -static flib_gameconn *flib_gameconn_create_partial(bool record, const char *playerName, bool netGame) { - flib_gameconn *result = NULL; - flib_gameconn *tempConn = flib_calloc(1, sizeof(flib_gameconn)); - if(tempConn) { - tempConn->ipcBase = flib_ipcbase_create(); - tempConn->configBuffer = flib_vector_create(); - tempConn->playerName = flib_strdupnull(playerName); - if(tempConn->ipcBase && tempConn->configBuffer && tempConn->playerName) { - if(record) { - tempConn->demoBuffer = flib_vector_create(); - } - tempConn->state = AWAIT_CONNECTION; - tempConn->netgame = netGame; - tempConn->disconnectReason = GAME_END_ERROR; - clearCallbacks(tempConn); - result = tempConn; - tempConn = NULL; - } - } - flib_gameconn_destroy(tempConn); - return result; -} - -flib_gameconn *flib_gameconn_create(const char *playerName, const flib_gamesetup *setup, bool netgame) { - if(log_badargs_if2(playerName==NULL, setup==NULL)) { - return NULL; - } - flib_gameconn *result = NULL; - flib_gameconn *tempConn = flib_gameconn_create_partial(true, playerName, netgame); - if(tempConn) { - if(flib_ipc_append_fullconfig(tempConn->configBuffer, setup, netgame)) { - flib_log_e("Error generating full game configuration for the engine."); - } else { - result = tempConn; - tempConn = NULL; - } - } - flib_gameconn_destroy(tempConn); - return result; -} - -flib_gameconn *flib_gameconn_create_playdemo(const uint8_t *demoFileContent, size_t size) { - if(log_badargs_if(demoFileContent==NULL && size>0)) { - return NULL; - } - flib_gameconn *result = NULL; - flib_gameconn *tempConn = flib_gameconn_create_partial(false, "Player", false); - if(tempConn) { - if(!flib_vector_append(tempConn->configBuffer, demoFileContent, size)) { - result = tempConn; - tempConn = NULL; - } - } - flib_gameconn_destroy(tempConn); - return result; -} - -flib_gameconn *flib_gameconn_create_loadgame(const char *playerName, const uint8_t *saveFileContent, size_t size) { - if(log_badargs_if(saveFileContent==NULL && size>0)) { - return NULL; - } - flib_gameconn *result = NULL; - flib_gameconn *tempConn = flib_gameconn_create_partial(true, playerName, false); - if(tempConn) { - if(!flib_vector_append(tempConn->configBuffer, saveFileContent, size)) { - result = tempConn; - tempConn = NULL; - } - } - flib_gameconn_destroy(tempConn); - return result; -} - -flib_gameconn *flib_gameconn_create_campaign(const char *playerName, const char *seed, const char *script) { - if(log_badargs_if3(playerName==NULL, seed==NULL, script==NULL)) { - return NULL; - } - flib_gameconn *result = NULL; - flib_gameconn *tempConn = flib_gameconn_create_partial(true, playerName, false); - if(tempConn) { - if(!flib_ipc_append_message(tempConn->configBuffer, "TL") - && !flib_ipc_append_seed(tempConn->configBuffer, seed) - && !flib_ipc_append_script(tempConn->configBuffer, script) - && !flib_ipc_append_message(tempConn->configBuffer, "!")) { - result = tempConn; - tempConn = NULL; - } - } - flib_gameconn_destroy(tempConn); - return result; -} - -void flib_gameconn_destroy(flib_gameconn *conn) { - if(conn) { - if(conn->running) { - /* - * The function was called from a callback, so the tick function is still running - * and we delay the actual destruction. We ensure no further callbacks will be - * sent to prevent surprises. - */ - clearCallbacks(conn); - conn->destroyRequested = true; - } else { - flib_ipcbase_destroy(conn->ipcBase); - flib_vector_destroy(conn->configBuffer); - flib_vector_destroy(conn->demoBuffer); - free(conn->playerName); - free(conn); - } - } -} - -int flib_gameconn_getport(flib_gameconn *conn) { - if(log_badargs_if(conn==NULL)) { - return 0; - } - return flib_ipcbase_port(conn->ipcBase); -} - -static void demo_append(flib_gameconn *conn, const void *data, size_t len) { - if(conn->demoBuffer) { - if(flib_vector_append(conn->demoBuffer, data, len)) { - flib_log_e("Error recording demo: Out of memory."); - flib_vector_destroy(conn->demoBuffer); - conn->demoBuffer = NULL; - } - } -} - -static int format_chatmessage(uint8_t buffer[257], const char *playerName, const char *message) { - size_t msglen = strlen(message); - - // If the message starts with /me, it will be displayed differently. - bool meMessage = msglen >= 4 && !memcmp(message, "/me ", 4); - const char *template = meMessage ? "s\x02* %s %s " : "s\x01%s: %s "; - int size = snprintf((char*)buffer+1, 256, template, playerName, meMessage ? message+4 : message); - if(log_e_if(size<=0, "printf error")) { - return -1; - } else { - buffer[0] = size>255 ? 255 : size; - return 0; - } -} - -static void demo_append_chatmessage(flib_gameconn *conn, const char *message) { - // Chat messages are reformatted to make them look as if they were received, not sent. - uint8_t converted[257]; - if(!format_chatmessage(converted, conn->playerName, message)) { - demo_append(conn, converted, converted[0]+1); - } -} - -static void demo_replace_gamemode(flib_buffer buf, char gamemode) { - size_t msgStart = 0; - uint8_t *data = (uint8_t*)buf.data; - while(msgStart+2 < buf.size) { - if(!memcmp(data+msgStart, "\x02T", 2)) { - data[msgStart+2] = gamemode; - } - msgStart += (uint8_t)data[msgStart]+1; - } -} - -int flib_gameconn_send_enginemsg(flib_gameconn *conn, const uint8_t *data, size_t len) { - if(log_badargs_if2(conn==NULL, data==NULL && len>0)) { - return -1; - } - int result = flib_ipcbase_send_raw(conn->ipcBase, data, len); - if(!result) { - demo_append(conn, data, len); - } - return result; -} - -int flib_gameconn_send_textmsg(flib_gameconn *conn, int msgtype, const char *msg) { - if(log_badargs_if2(conn==NULL, msg==NULL)) { - return -1; - } - int result = -1; - uint8_t converted[257]; - int size = snprintf((char*)converted+1, 256, "s%c%s", (char)msgtype, msg); - if(size>0) { - converted[0] = size>255 ? 255 : size; - if(!flib_ipcbase_send_raw(conn->ipcBase, converted, converted[0]+1)) { - demo_append(conn, converted, converted[0]+1); - result = 0; - } - } - return result; -} - -int flib_gameconn_send_chatmsg(flib_gameconn *conn, const char *playername, const char *msg) { - if(log_badargs_if3(conn==NULL, playername==NULL, msg==NULL)) { - return -1; - } - uint8_t converted[257]; - if(!format_chatmessage(converted, playername, msg) - && !flib_ipcbase_send_raw(conn->ipcBase, converted, converted[0]+1)) { - demo_append(conn, converted, converted[0]+1); - return 0; - } - return -1; -} - -int flib_gameconn_send_quit(flib_gameconn *conn) { - return flib_gameconn_send_cmd(conn, "efinish"); -} - -int flib_gameconn_send_cmd(flib_gameconn *conn, const char *cmdString) { - if(log_badargs_if2(conn==NULL, cmdString==NULL)) { - return -1; - } - int result = -1; - uint8_t converted[256]; - size_t msglen = strlen(cmdString); - if(!log_e_if(msglen>255, "Message too long: %s", cmdString)) { - strcpy((char*)converted+1, cmdString); - converted[0] = msglen; - if(!flib_ipcbase_send_raw(conn->ipcBase, converted, msglen+1)) { - demo_append(conn, converted, msglen+1); - result = 0; - } - } - return result; -} - -/** - * This macro generates a callback setter function. It uses the name of the callback to - * automatically generate the function name and the fields to set, so a consistent naming - * convention needs to be enforced (not that that is a bad thing). If null is passed as - * callback to the generated function, the defaultCb will be set instead (with conn - * as the context). - */ -#define GENERATE_CB_SETTER(cbName, cbParameterTypes, defaultCb) \ - void flib_gameconn_##cbName(flib_gameconn *conn, void (*callback)cbParameterTypes, void *context) { \ - if(!log_badargs_if(conn==NULL)) { \ - conn->cbName##Cb = callback ? callback : &defaultCb; \ - conn->cbName##Ctx = callback ? context : conn; \ - } \ - } - -/** - * Generate a callback setter function like GENERATE_CB_SETTER, and automatically generate a - * no-op callback function as well that is used as default. - */ -#define GENERATE_CB_SETTER_AND_DEFAULT(cbName, cbParameterTypes) \ - static void _noop_callback_##cbName cbParameterTypes {} \ - GENERATE_CB_SETTER(cbName, cbParameterTypes, _noop_callback_##cbName) - -GENERATE_CB_SETTER_AND_DEFAULT(onConnect, (void *context)); -GENERATE_CB_SETTER_AND_DEFAULT(onDisconnect, (void* context, int reason)); -GENERATE_CB_SETTER(onErrorMessage, (void* context, const char *msg), defaultCallback_onErrorMessage); -GENERATE_CB_SETTER_AND_DEFAULT(onChat, (void* context, const char *msg, bool teamchat)); -GENERATE_CB_SETTER_AND_DEFAULT(onGameRecorded, (void *context, const uint8_t *record, size_t size, bool isSavegame)); -GENERATE_CB_SETTER_AND_DEFAULT(onEngineMessage, (void *context, const uint8_t *em, size_t size)); - -#undef GENERATE_CB_SETTER_AND_DEFAULT -#undef GENERATE_CB_SETTER - -static void flib_gameconn_wrappedtick(flib_gameconn *conn) { - if(conn->state == AWAIT_CONNECTION) { - flib_ipcbase_accept(conn->ipcBase); - switch(flib_ipcbase_state(conn->ipcBase)) { - case IPC_CONNECTED: - { - flib_constbuffer configBuffer = flib_vector_as_constbuffer(conn->configBuffer); - if(flib_ipcbase_send_raw(conn->ipcBase, configBuffer.data, configBuffer.size)) { - conn->state = FINISHED; - conn->onDisconnectCb(conn->onDisconnectCtx, GAME_END_ERROR); - return; - } else { - demo_append(conn, configBuffer.data, configBuffer.size); - conn->state = CONNECTED; - conn->onConnectCb(conn->onConnectCtx); - if(conn->destroyRequested) { - return; - } - } - } - break; - case IPC_NOT_CONNECTED: - conn->state = FINISHED; - conn->onDisconnectCb(conn->onDisconnectCtx, GAME_END_ERROR); - return; - default: - break; - } - } - - if(conn->state == CONNECTED) { - uint8_t msgbuffer[257]; - int len; - while(!conn->destroyRequested && (len = flib_ipcbase_recv_message(conn->ipcBase, msgbuffer))>=0) { - if(len<2) { - flib_log_w("Received short message from IPC (<2 bytes)"); - continue; - } - switch(msgbuffer[1]) { - case '?': // Ping - // The pong is already part of the config message - break; - case 'C': // Config query - // And we already send the config message on connecting. - break; - case 'E': // Error message - if(len>=3) { - msgbuffer[len-2] = 0; - conn->onErrorMessageCb(conn->onErrorMessageCtx, (char*)msgbuffer+2); - } - break; - case 'i': // Statistics - // TODO stats - break; - case 'Q': // Game interrupted - case 'H': // Game halted - case 'q': // game finished - { - int reason = msgbuffer[1]=='Q' ? GAME_END_INTERRUPTED : msgbuffer[1]=='H' ? GAME_END_HALTED : GAME_END_FINISHED; - conn->disconnectReason = reason; - bool savegame = (reason != GAME_END_FINISHED) && !conn->netgame; - if(conn->demoBuffer) { - flib_buffer demoBuffer = flib_vector_as_buffer(conn->demoBuffer); - demo_replace_gamemode(demoBuffer, savegame ? 'S' : 'D'); - conn->onGameRecordedCb(conn->onGameRecordedCtx, demoBuffer.data, demoBuffer.size, savegame); - if(conn->destroyRequested) { - return; - } - } - return; - } - case 's': // Chat message - if(len>=3) { - msgbuffer[len-2] = 0; - demo_append_chatmessage(conn, (char*)msgbuffer+2); - - conn->onChatCb(conn->onChatCtx, (char*)msgbuffer+2, false); - } - break; - case 'b': // Teamchat message - if(len>=3) { - msgbuffer[len-2] = 0; - conn->onChatCb(conn->onChatCtx, (char*)msgbuffer+2, true); - } - break; - default: // Engine message - demo_append(conn, msgbuffer, len); - - conn->onEngineMessageCb(conn->onEngineMessageCtx, msgbuffer, len); - break; - } - } - } - - if(flib_ipcbase_state(conn->ipcBase) == IPC_NOT_CONNECTED) { - conn->state = FINISHED; - conn->onDisconnectCb(conn->onDisconnectCtx, conn->disconnectReason); - } -} - -void flib_gameconn_tick(flib_gameconn *conn) { - if(!log_badargs_if(conn == NULL) - && !log_w_if(conn->running, "Call to flib_gameconn_tick from a callback") - && !log_w_if(conn->state == FINISHED, "We are already done.")) { - conn->running = true; - flib_gameconn_wrappedtick(conn); - conn->running = false; - - if(conn->destroyRequested) { - flib_gameconn_destroy(conn); - } - } -} +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "gameconn.h" +#include "ipcbase.h" +#include "ipcprotocol.h" +#include "../util/logging.h" +#include "../util/util.h" +#include "../hwconsts.h" +#include +#include +#include + +typedef enum { + AWAIT_CONNECTION, + CONNECTED, + FINISHED +} gameconn_state; + +struct _flib_gameconn { + flib_ipcbase *ipcBase; + flib_vector *configBuffer; + flib_vector *demoBuffer; + char *playerName; + + gameconn_state state; + bool netgame; + int disconnectReason; + + void (*onConnectCb)(void* context); + void *onConnectCtx; + + void (*onDisconnectCb)(void* context, int reason); + void *onDisconnectCtx; + + void (*onErrorMessageCb)(void* context, const char *msg); + void *onErrorMessageCtx; + + void (*onChatCb)(void* context, const char *msg, bool teamchat); + void *onChatCtx; + + void (*onGameRecordedCb)(void *context, const uint8_t *record, size_t size, bool isSavegame); + void *onGameRecordedCtx; + + void (*onEngineMessageCb)(void *context, const uint8_t *em, size_t size); + void *onEngineMessageCtx; + + bool running; + bool destroyRequested; +}; + +static void defaultCallback_onErrorMessage(void* context, const char *msg) { + flib_log_w("Error from engine (no callback set): %s", msg); +} + +static void clearCallbacks(flib_gameconn *conn) { + flib_gameconn_onConnect(conn, NULL, NULL); + flib_gameconn_onDisconnect(conn, NULL, NULL); + flib_gameconn_onErrorMessage(conn, NULL, NULL); + flib_gameconn_onChat(conn, NULL, NULL); + flib_gameconn_onGameRecorded(conn, NULL, NULL); + flib_gameconn_onEngineMessage(conn, NULL, NULL); +} + +static flib_gameconn *flib_gameconn_create_partial(bool record, const char *playerName, bool netGame) { + flib_gameconn *result = NULL; + flib_gameconn *tempConn = flib_calloc(1, sizeof(flib_gameconn)); + if(tempConn) { + tempConn->ipcBase = flib_ipcbase_create(); + tempConn->configBuffer = flib_vector_create(); + tempConn->playerName = flib_strdupnull(playerName); + if(tempConn->ipcBase && tempConn->configBuffer && tempConn->playerName) { + if(record) { + tempConn->demoBuffer = flib_vector_create(); + } + tempConn->state = AWAIT_CONNECTION; + tempConn->netgame = netGame; + tempConn->disconnectReason = GAME_END_ERROR; + clearCallbacks(tempConn); + result = tempConn; + tempConn = NULL; + } + } + flib_gameconn_destroy(tempConn); + return result; +} + +flib_gameconn *flib_gameconn_create(const char *playerName, const flib_gamesetup *setup, bool netgame) { + if(log_badargs_if2(playerName==NULL, setup==NULL)) { + return NULL; + } + flib_gameconn *result = NULL; + flib_gameconn *tempConn = flib_gameconn_create_partial(true, playerName, netgame); + if(tempConn) { + if(flib_ipc_append_fullconfig(tempConn->configBuffer, setup, netgame)) { + flib_log_e("Error generating full game configuration for the engine."); + } else { + result = tempConn; + tempConn = NULL; + } + } + flib_gameconn_destroy(tempConn); + return result; +} + +flib_gameconn *flib_gameconn_create_playdemo(const uint8_t *demoFileContent, size_t size) { + if(log_badargs_if(demoFileContent==NULL && size>0)) { + return NULL; + } + flib_gameconn *result = NULL; + flib_gameconn *tempConn = flib_gameconn_create_partial(false, "Player", false); + if(tempConn) { + if(!flib_vector_append(tempConn->configBuffer, demoFileContent, size)) { + result = tempConn; + tempConn = NULL; + } + } + flib_gameconn_destroy(tempConn); + return result; +} + +flib_gameconn *flib_gameconn_create_loadgame(const char *playerName, const uint8_t *saveFileContent, size_t size) { + if(log_badargs_if(saveFileContent==NULL && size>0)) { + return NULL; + } + flib_gameconn *result = NULL; + flib_gameconn *tempConn = flib_gameconn_create_partial(true, playerName, false); + if(tempConn) { + if(!flib_vector_append(tempConn->configBuffer, saveFileContent, size)) { + result = tempConn; + tempConn = NULL; + } + } + flib_gameconn_destroy(tempConn); + return result; +} + +flib_gameconn *flib_gameconn_create_campaign(const char *playerName, const char *seed, const char *script) { + if(log_badargs_if3(playerName==NULL, seed==NULL, script==NULL)) { + return NULL; + } + flib_gameconn *result = NULL; + flib_gameconn *tempConn = flib_gameconn_create_partial(true, playerName, false); + if(tempConn) { + if(!flib_ipc_append_message(tempConn->configBuffer, "TL") + && !flib_ipc_append_seed(tempConn->configBuffer, seed) + && !flib_ipc_append_script(tempConn->configBuffer, script) + && !flib_ipc_append_message(tempConn->configBuffer, "!")) { + result = tempConn; + tempConn = NULL; + } + } + flib_gameconn_destroy(tempConn); + return result; +} + +void flib_gameconn_destroy(flib_gameconn *conn) { + if(conn) { + if(conn->running) { + /* + * The function was called from a callback, so the tick function is still running + * and we delay the actual destruction. We ensure no further callbacks will be + * sent to prevent surprises. + */ + clearCallbacks(conn); + conn->destroyRequested = true; + } else { + flib_ipcbase_destroy(conn->ipcBase); + flib_vector_destroy(conn->configBuffer); + flib_vector_destroy(conn->demoBuffer); + free(conn->playerName); + free(conn); + } + } +} + +int flib_gameconn_getport(flib_gameconn *conn) { + if(log_badargs_if(conn==NULL)) { + return 0; + } + return flib_ipcbase_port(conn->ipcBase); +} + +static void demo_append(flib_gameconn *conn, const void *data, size_t len) { + if(conn->demoBuffer) { + if(flib_vector_append(conn->demoBuffer, data, len)) { + flib_log_e("Error recording demo: Out of memory."); + flib_vector_destroy(conn->demoBuffer); + conn->demoBuffer = NULL; + } + } +} + +static int format_chatmessage(uint8_t buffer[257], const char *playerName, const char *message) { + size_t msglen = strlen(message); + + // If the message starts with /me, it will be displayed differently. + bool meMessage = msglen >= 4 && !memcmp(message, "/me ", 4); + const char *template = meMessage ? "s\x02* %s %s " : "s\x01%s: %s "; + int size = snprintf((char*)buffer+1, 256, template, playerName, meMessage ? message+4 : message); + if(log_e_if(size<=0, "printf error")) { + return -1; + } else { + buffer[0] = size>255 ? 255 : size; + return 0; + } +} + +static void demo_append_chatmessage(flib_gameconn *conn, const char *message) { + // Chat messages are reformatted to make them look as if they were received, not sent. + uint8_t converted[257]; + if(!format_chatmessage(converted, conn->playerName, message)) { + demo_append(conn, converted, converted[0]+1); + } +} + +static void demo_replace_gamemode(flib_buffer buf, char gamemode) { + size_t msgStart = 0; + uint8_t *data = (uint8_t*)buf.data; + while(msgStart+2 < buf.size) { + if(!memcmp(data+msgStart, "\x02T", 2)) { + data[msgStart+2] = gamemode; + } + msgStart += (uint8_t)data[msgStart]+1; + } +} + +int flib_gameconn_send_enginemsg(flib_gameconn *conn, const uint8_t *data, size_t len) { + if(log_badargs_if2(conn==NULL, data==NULL && len>0)) { + return -1; + } + int result = flib_ipcbase_send_raw(conn->ipcBase, data, len); + if(!result) { + demo_append(conn, data, len); + } + return result; +} + +int flib_gameconn_send_textmsg(flib_gameconn *conn, int msgtype, const char *msg) { + if(log_badargs_if2(conn==NULL, msg==NULL)) { + return -1; + } + int result = -1; + uint8_t converted[257]; + int size = snprintf((char*)converted+1, 256, "s%c%s", (char)msgtype, msg); + if(size>0) { + converted[0] = size>255 ? 255 : size; + if(!flib_ipcbase_send_raw(conn->ipcBase, converted, converted[0]+1)) { + demo_append(conn, converted, converted[0]+1); + result = 0; + } + } + return result; +} + +int flib_gameconn_send_chatmsg(flib_gameconn *conn, const char *playername, const char *msg) { + if(log_badargs_if3(conn==NULL, playername==NULL, msg==NULL)) { + return -1; + } + uint8_t converted[257]; + if(!format_chatmessage(converted, playername, msg) + && !flib_ipcbase_send_raw(conn->ipcBase, converted, converted[0]+1)) { + demo_append(conn, converted, converted[0]+1); + return 0; + } + return -1; +} + +int flib_gameconn_send_quit(flib_gameconn *conn) { + return flib_gameconn_send_cmd(conn, "efinish"); +} + +int flib_gameconn_send_cmd(flib_gameconn *conn, const char *cmdString) { + if(log_badargs_if2(conn==NULL, cmdString==NULL)) { + return -1; + } + int result = -1; + uint8_t converted[256]; + size_t msglen = strlen(cmdString); + if(!log_e_if(msglen>255, "Message too long: %s", cmdString)) { + strcpy((char*)converted+1, cmdString); + converted[0] = msglen; + if(!flib_ipcbase_send_raw(conn->ipcBase, converted, msglen+1)) { + demo_append(conn, converted, msglen+1); + result = 0; + } + } + return result; +} + +/** + * This macro generates a callback setter function. It uses the name of the callback to + * automatically generate the function name and the fields to set, so a consistent naming + * convention needs to be enforced (not that that is a bad thing). If null is passed as + * callback to the generated function, the defaultCb will be set instead (with conn + * as the context). + */ +#define GENERATE_CB_SETTER(cbName, cbParameterTypes, defaultCb) \ + void flib_gameconn_##cbName(flib_gameconn *conn, void (*callback)cbParameterTypes, void *context) { \ + if(!log_badargs_if(conn==NULL)) { \ + conn->cbName##Cb = callback ? callback : &defaultCb; \ + conn->cbName##Ctx = callback ? context : conn; \ + } \ + } + +/** + * Generate a callback setter function like GENERATE_CB_SETTER, and automatically generate a + * no-op callback function as well that is used as default. + */ +#define GENERATE_CB_SETTER_AND_DEFAULT(cbName, cbParameterTypes) \ + static void _noop_callback_##cbName cbParameterTypes {} \ + GENERATE_CB_SETTER(cbName, cbParameterTypes, _noop_callback_##cbName) + +GENERATE_CB_SETTER_AND_DEFAULT(onConnect, (void *context)); +GENERATE_CB_SETTER_AND_DEFAULT(onDisconnect, (void* context, int reason)); +GENERATE_CB_SETTER(onErrorMessage, (void* context, const char *msg), defaultCallback_onErrorMessage); +GENERATE_CB_SETTER_AND_DEFAULT(onChat, (void* context, const char *msg, bool teamchat)); +GENERATE_CB_SETTER_AND_DEFAULT(onGameRecorded, (void *context, const uint8_t *record, size_t size, bool isSavegame)); +GENERATE_CB_SETTER_AND_DEFAULT(onEngineMessage, (void *context, const uint8_t *em, size_t size)); + +#undef GENERATE_CB_SETTER_AND_DEFAULT +#undef GENERATE_CB_SETTER + +static void flib_gameconn_wrappedtick(flib_gameconn *conn) { + if(conn->state == AWAIT_CONNECTION) { + flib_ipcbase_accept(conn->ipcBase); + switch(flib_ipcbase_state(conn->ipcBase)) { + case IPC_CONNECTED: + { + flib_constbuffer configBuffer = flib_vector_as_constbuffer(conn->configBuffer); + if(flib_ipcbase_send_raw(conn->ipcBase, configBuffer.data, configBuffer.size)) { + conn->state = FINISHED; + conn->onDisconnectCb(conn->onDisconnectCtx, GAME_END_ERROR); + return; + } else { + demo_append(conn, configBuffer.data, configBuffer.size); + conn->state = CONNECTED; + conn->onConnectCb(conn->onConnectCtx); + if(conn->destroyRequested) { + return; + } + } + } + break; + case IPC_NOT_CONNECTED: + conn->state = FINISHED; + conn->onDisconnectCb(conn->onDisconnectCtx, GAME_END_ERROR); + return; + default: + break; + } + } + + if(conn->state == CONNECTED) { + uint8_t msgbuffer[257]; + int len; + while(!conn->destroyRequested && (len = flib_ipcbase_recv_message(conn->ipcBase, msgbuffer))>=0) { + if(len<2) { + flib_log_w("Received short message from IPC (<2 bytes)"); + continue; + } + switch(msgbuffer[1]) { + case '?': // Ping + // The pong is already part of the config message + break; + case 'C': // Config query + // And we already send the config message on connecting. + break; + case 'E': // Error message + if(len>=3) { + msgbuffer[len-2] = 0; + conn->onErrorMessageCb(conn->onErrorMessageCtx, (char*)msgbuffer+2); + } + break; + case 'i': // Statistics + // TODO stats + break; + case 'Q': // Game interrupted + case 'H': // Game halted + case 'q': // game finished + { + int reason = msgbuffer[1]=='Q' ? GAME_END_INTERRUPTED : msgbuffer[1]=='H' ? GAME_END_HALTED : GAME_END_FINISHED; + conn->disconnectReason = reason; + bool savegame = (reason != GAME_END_FINISHED) && !conn->netgame; + if(conn->demoBuffer) { + flib_buffer demoBuffer = flib_vector_as_buffer(conn->demoBuffer); + demo_replace_gamemode(demoBuffer, savegame ? 'S' : 'D'); + conn->onGameRecordedCb(conn->onGameRecordedCtx, demoBuffer.data, demoBuffer.size, savegame); + if(conn->destroyRequested) { + return; + } + } + return; + } + case 's': // Chat message + if(len>=3) { + msgbuffer[len-2] = 0; + demo_append_chatmessage(conn, (char*)msgbuffer+2); + + conn->onChatCb(conn->onChatCtx, (char*)msgbuffer+2, false); + } + break; + case 'b': // Teamchat message + if(len>=3) { + msgbuffer[len-2] = 0; + conn->onChatCb(conn->onChatCtx, (char*)msgbuffer+2, true); + } + break; + default: // Engine message + demo_append(conn, msgbuffer, len); + + conn->onEngineMessageCb(conn->onEngineMessageCtx, msgbuffer, len); + break; + } + } + } + + if(flib_ipcbase_state(conn->ipcBase) == IPC_NOT_CONNECTED) { + conn->state = FINISHED; + conn->onDisconnectCb(conn->onDisconnectCtx, conn->disconnectReason); + } +} + +void flib_gameconn_tick(flib_gameconn *conn) { + if(!log_badargs_if(conn == NULL) + && !log_w_if(conn->running, "Call to flib_gameconn_tick from a callback") + && !log_w_if(conn->state == FINISHED, "We are already done.")) { + conn->running = true; + flib_gameconn_wrappedtick(conn); + conn->running = false; + + if(conn->destroyRequested) { + flib_gameconn_destroy(conn); + } + } +} diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/ipc/gameconn.h --- a/project_files/frontlib/ipc/gameconn.h Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/ipc/gameconn.h Tue Jan 21 22:43:06 2014 +0100 @@ -1,179 +1,179 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * This file contains functions for starting and interacting with a game run by the engine. - * The general usage is to first create a gameconn object by calling one of the flib_gameconn_create - * functions. That will cause the frontlib to listen on a random port which can be queried using - * flib_gameconn_getport(). You should also register your callback functions right at the start - * to ensure you don't miss any callbacks. - * - * Next, start the engine (that part is up to you) with the appropriate command line arguments - * for starting a game. - * - * In order to allow the gameconn to run, you should regularly call flib_gameconn_tick(), which - * performs network I/O and calls your callbacks on interesting events. - * - * Once the engine connects, the gameconn will send it the required commands for starting the - * game you requested in your flib_gameconn_create call. - * - * When the game is finished (or the connection is lost), you will receive the onDisconnect - * message. This is the signal to destroy the gameconn and stop calling tick(). - */ - -#ifndef GAMECONN_H_ -#define GAMECONN_H_ - -#include "../model/gamesetup.h" - -#include -#include -#include - -/* - * Different reasons for a disconnect. Only GAME_END_FINISHED signals a correctly completed game. - */ -#define GAME_END_FINISHED 0 -#define GAME_END_INTERRUPTED 1 -#define GAME_END_HALTED 2 -#define GAME_END_ERROR 3 - -typedef struct _flib_gameconn flib_gameconn; - -/** - * Create a gameconn that will start a local or network game with the indicated configuration. - */ -flib_gameconn *flib_gameconn_create(const char *playerName, const flib_gamesetup *setup, bool netgame); - -/** - * Create a gameconn that will play back a demo. - */ -flib_gameconn *flib_gameconn_create_playdemo(const uint8_t *demoFileContent, size_t size); - -/** - * Create a gameconn that will continue from a saved game. - */ -flib_gameconn *flib_gameconn_create_loadgame(const char *playerName, const uint8_t *saveFileContent, size_t size); - -/** - * Create a gameconn that will start a campaign or training mission with the indicated script. - * seed is the random seed to use as entropy source (any string). - * script is the path and filename of a Campaign or Training script, relative to the Data directory - * (e.g. "Missions/Training/Basic_Training_-_Bazooka.lua") - */ -flib_gameconn *flib_gameconn_create_campaign(const char *playerName, const char *seed, const char *script); - -/** - * Release all resources of this gameconn, including the network connection, and free its memory. - * It is safe to call this function from a callback. - */ -void flib_gameconn_destroy(flib_gameconn *conn); - -/** - * Returns the port on which the gameconn is listening. Only fails if you - * pass NULL (not allowed), in that case 0 is returned. - */ -int flib_gameconn_getport(flib_gameconn *conn); - -/** - * Perform I/O operations and call callbacks if something interesting happens. - * Should be called regularly. - */ -void flib_gameconn_tick(flib_gameconn *conn); - -/** - * Send an engine message to the engine. Only needed in net games, where you receive engine - * messages from the server and have to pass them here. - */ -int flib_gameconn_send_enginemsg(flib_gameconn *conn, const uint8_t *data, size_t len); - -/** - * Send an info message to the engine that will be displayed in the game's chatlog. - * The msgtype determines the color of the message; in the QTFrontend, info messages and - * normal chat messages use 1, emote-messages (those starting with /me) use 2, and - * join/leave messages use 3. You should use flib_gameconn_send_chatmsg for chat messages - * though because it automatically formats /me messages. - * - * Generally only needed in net games. - */ -int flib_gameconn_send_textmsg(flib_gameconn *conn, int msgtype, const char *msg); - -/** - * Send a chat message to be displayed in the game's chatlog. Messages starting with /me are - * automatically formatted correctly. - * - * Generally only needed in net games. - */ -int flib_gameconn_send_chatmsg(flib_gameconn *conn, const char *playername, const char *msg); - -/** - * Request the engine to stop the game (efinish). - * You can use this to shut down a game early without directly killing the engine process. - */ -int flib_gameconn_send_quit(flib_gameconn *conn); - -/** - * Send an arbitrary command to the engine, e.g. "eforcequit" to shut down the engine - * quickly. Commands prefixed with "e" will be processed by the engine's ProcessCommand - * method (with the e removed, so e.g. efinish will be parsed as finish). - */ -int flib_gameconn_send_cmd(flib_gameconn *conn, const char *cmdString); - -/** - * Expected callback signature: void handleConnect(void *context) - * The engine has successfully connected. You don't have to react to this in any way. - */ -void flib_gameconn_onConnect(flib_gameconn *conn, void (*callback)(void* context), void* context); - -/** - * Expected callback signature: void handleDisconnect(void *context, int reason) - * The connection to the engine was closed, either because the game has ended normally, or - * because it was interrupted/halted, or because of an error. The reason is provided as one - * of the GAME_END_xxx constants. - * - * You should destroy the gameconn and - in a netgame - notify the server that the game has ended. - */ -void flib_gameconn_onDisconnect(flib_gameconn *conn, void (*callback)(void* context, int reason), void* context); - -/** - * Expected callback signature: void handleErrorMessage(void* context, const char *msg) - * The engine sent an error message, you should probably display it to the user or at least log it. - */ -void flib_gameconn_onErrorMessage(flib_gameconn *conn, void (*callback)(void* context, const char *msg), void* context); - -/** - * Expected callback signature: void handleChat(void* context, const char *msg, bool teamchat) - * The player entered a chat or teamchat message. In a netgame, you should send it on to the server. - */ -void flib_gameconn_onChat(flib_gameconn *conn, void (*callback)(void* context, const char *msg, bool teamchat), void* context); - -/** - * Expected callback signature: void handleGameRecorded(void *context, const uint8_t *record, size_t size, bool isSavegame) - * The game has stopped, and a demo or savegame is available. You can store it in a file and later pass it back - * to the engine to either watch a replay (if it's a demo) or to continue playing (if it's a savegame). - */ -void flib_gameconn_onGameRecorded(flib_gameconn *conn, void (*callback)(void *context, const uint8_t *record, size_t size, bool isSavegame), void* context); - -/** - * Expected callback signature: void handleEngineMessage(void *context, const uint8_t *em, size_t size) - * The engine has generated a message with player input. In a netgame, you should send it on to the server. - */ -void flib_gameconn_onEngineMessage(flib_gameconn *conn, void (*callback)(void *context, const uint8_t *em, size_t size), void* context); - -#endif +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * This file contains functions for starting and interacting with a game run by the engine. + * The general usage is to first create a gameconn object by calling one of the flib_gameconn_create + * functions. That will cause the frontlib to listen on a random port which can be queried using + * flib_gameconn_getport(). You should also register your callback functions right at the start + * to ensure you don't miss any callbacks. + * + * Next, start the engine (that part is up to you) with the appropriate command line arguments + * for starting a game. + * + * In order to allow the gameconn to run, you should regularly call flib_gameconn_tick(), which + * performs network I/O and calls your callbacks on interesting events. + * + * Once the engine connects, the gameconn will send it the required commands for starting the + * game you requested in your flib_gameconn_create call. + * + * When the game is finished (or the connection is lost), you will receive the onDisconnect + * message. This is the signal to destroy the gameconn and stop calling tick(). + */ + +#ifndef GAMECONN_H_ +#define GAMECONN_H_ + +#include "../model/gamesetup.h" + +#include +#include +#include + +/* + * Different reasons for a disconnect. Only GAME_END_FINISHED signals a correctly completed game. + */ +#define GAME_END_FINISHED 0 +#define GAME_END_INTERRUPTED 1 +#define GAME_END_HALTED 2 +#define GAME_END_ERROR 3 + +typedef struct _flib_gameconn flib_gameconn; + +/** + * Create a gameconn that will start a local or network game with the indicated configuration. + */ +flib_gameconn *flib_gameconn_create(const char *playerName, const flib_gamesetup *setup, bool netgame); + +/** + * Create a gameconn that will play back a demo. + */ +flib_gameconn *flib_gameconn_create_playdemo(const uint8_t *demoFileContent, size_t size); + +/** + * Create a gameconn that will continue from a saved game. + */ +flib_gameconn *flib_gameconn_create_loadgame(const char *playerName, const uint8_t *saveFileContent, size_t size); + +/** + * Create a gameconn that will start a campaign or training mission with the indicated script. + * seed is the random seed to use as entropy source (any string). + * script is the path and filename of a Campaign or Training script, relative to the Data directory + * (e.g. "Missions/Training/Basic_Training_-_Bazooka.lua") + */ +flib_gameconn *flib_gameconn_create_campaign(const char *playerName, const char *seed, const char *script); + +/** + * Release all resources of this gameconn, including the network connection, and free its memory. + * It is safe to call this function from a callback. + */ +void flib_gameconn_destroy(flib_gameconn *conn); + +/** + * Returns the port on which the gameconn is listening. Only fails if you + * pass NULL (not allowed), in that case 0 is returned. + */ +int flib_gameconn_getport(flib_gameconn *conn); + +/** + * Perform I/O operations and call callbacks if something interesting happens. + * Should be called regularly. + */ +void flib_gameconn_tick(flib_gameconn *conn); + +/** + * Send an engine message to the engine. Only needed in net games, where you receive engine + * messages from the server and have to pass them here. + */ +int flib_gameconn_send_enginemsg(flib_gameconn *conn, const uint8_t *data, size_t len); + +/** + * Send an info message to the engine that will be displayed in the game's chatlog. + * The msgtype determines the color of the message; in the QTFrontend, info messages and + * normal chat messages use 1, emote-messages (those starting with /me) use 2, and + * join/leave messages use 3. You should use flib_gameconn_send_chatmsg for chat messages + * though because it automatically formats /me messages. + * + * Generally only needed in net games. + */ +int flib_gameconn_send_textmsg(flib_gameconn *conn, int msgtype, const char *msg); + +/** + * Send a chat message to be displayed in the game's chatlog. Messages starting with /me are + * automatically formatted correctly. + * + * Generally only needed in net games. + */ +int flib_gameconn_send_chatmsg(flib_gameconn *conn, const char *playername, const char *msg); + +/** + * Request the engine to stop the game (efinish). + * You can use this to shut down a game early without directly killing the engine process. + */ +int flib_gameconn_send_quit(flib_gameconn *conn); + +/** + * Send an arbitrary command to the engine, e.g. "eforcequit" to shut down the engine + * quickly. Commands prefixed with "e" will be processed by the engine's ProcessCommand + * method (with the e removed, so e.g. efinish will be parsed as finish). + */ +int flib_gameconn_send_cmd(flib_gameconn *conn, const char *cmdString); + +/** + * Expected callback signature: void handleConnect(void *context) + * The engine has successfully connected. You don't have to react to this in any way. + */ +void flib_gameconn_onConnect(flib_gameconn *conn, void (*callback)(void* context), void* context); + +/** + * Expected callback signature: void handleDisconnect(void *context, int reason) + * The connection to the engine was closed, either because the game has ended normally, or + * because it was interrupted/halted, or because of an error. The reason is provided as one + * of the GAME_END_xxx constants. + * + * You should destroy the gameconn and - in a netgame - notify the server that the game has ended. + */ +void flib_gameconn_onDisconnect(flib_gameconn *conn, void (*callback)(void* context, int reason), void* context); + +/** + * Expected callback signature: void handleErrorMessage(void* context, const char *msg) + * The engine sent an error message, you should probably display it to the user or at least log it. + */ +void flib_gameconn_onErrorMessage(flib_gameconn *conn, void (*callback)(void* context, const char *msg), void* context); + +/** + * Expected callback signature: void handleChat(void* context, const char *msg, bool teamchat) + * The player entered a chat or teamchat message. In a netgame, you should send it on to the server. + */ +void flib_gameconn_onChat(flib_gameconn *conn, void (*callback)(void* context, const char *msg, bool teamchat), void* context); + +/** + * Expected callback signature: void handleGameRecorded(void *context, const uint8_t *record, size_t size, bool isSavegame) + * The game has stopped, and a demo or savegame is available. You can store it in a file and later pass it back + * to the engine to either watch a replay (if it's a demo) or to continue playing (if it's a savegame). + */ +void flib_gameconn_onGameRecorded(flib_gameconn *conn, void (*callback)(void *context, const uint8_t *record, size_t size, bool isSavegame), void* context); + +/** + * Expected callback signature: void handleEngineMessage(void *context, const uint8_t *em, size_t size) + * The engine has generated a message with player input. In a netgame, you should send it on to the server. + */ +void flib_gameconn_onEngineMessage(flib_gameconn *conn, void (*callback)(void *context, const uint8_t *em, size_t size), void* context); + +#endif diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/ipc/ipcbase.c --- a/project_files/frontlib/ipc/ipcbase.c Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/ipc/ipcbase.c Tue Jan 21 22:43:06 2014 +0100 @@ -1,216 +1,216 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "ipcbase.h" -#include "../util/logging.h" -#include "../util/util.h" -#include "../socket.h" - -#include -#include -#include -#include - -/* - * The receive buffer has to be able to hold any message that might be received. Normally - * the messages are at most 256 bytes, but the map preview contains 4097 bytes (4096 for a - * bitmap, 1 for the number of hogs which fit on the map). - * - * We don't need to worry about wasting a few kb though, and I like powers of two... - */ -struct _flib_ipcbase { - uint8_t readBuffer[8192]; - int readBufferSize; - - flib_acceptor *acceptor; - uint16_t port; - - flib_tcpsocket *sock; -}; - -flib_ipcbase *flib_ipcbase_create() { - flib_ipcbase *result = flib_calloc(1, sizeof(flib_ipcbase)); - flib_acceptor *acceptor = flib_acceptor_create(0); - - if(!result || !acceptor) { - free(result); - flib_acceptor_close(acceptor); - return NULL; - } - - result->acceptor = acceptor; - result->sock = NULL; - result->readBufferSize = 0; - result->port = flib_acceptor_listenport(acceptor); - - flib_log_i("Started listening for IPC connections on port %u", (unsigned)result->port); - return result; -} - -uint16_t flib_ipcbase_port(flib_ipcbase *ipc) { - if(log_badargs_if(ipc==NULL)) { - return 0; - } - return ipc->port; -} - -void flib_ipcbase_destroy(flib_ipcbase *ipc) { - if(ipc) { - flib_acceptor_close(ipc->acceptor); - flib_socket_close(ipc->sock); - if(ipc->sock) { - flib_log_d("IPC connection closed."); - } - free(ipc); - } -} - -IpcState flib_ipcbase_state(flib_ipcbase *ipc) { - if(log_badargs_if(ipc==NULL)) { - return IPC_NOT_CONNECTED; - } else if(ipc->sock) { - return IPC_CONNECTED; - } else if(ipc->acceptor) { - return IPC_LISTENING; - } else { - return IPC_NOT_CONNECTED; - } -} - -static void receiveToBuffer(flib_ipcbase *ipc) { - if(ipc->sock) { - int size = flib_socket_nbrecv(ipc->sock, ipc->readBuffer+ipc->readBufferSize, sizeof(ipc->readBuffer)-ipc->readBufferSize); - if(size>=0) { - ipc->readBufferSize += size; - } else { - flib_log_d("IPC connection lost."); - flib_socket_close(ipc->sock); - ipc->sock = NULL; - } - } -} - -static bool isMessageReady(flib_ipcbase *ipc) { - return ipc->readBufferSize >= ipc->readBuffer[0]+1; -} - -static void logSentMsg(const uint8_t *data, size_t len) { - if(flib_log_isActive(FLIB_LOGLEVEL_DEBUG)) { - size_t msgStart = 0; - while(msgStart < len) { - uint8_t msglen = data[msgStart]; - if(msgStart+msglen < len) { - flib_log_d("[IPC OUT][%03u]%*.*s",(unsigned)msglen, (unsigned)msglen, (unsigned)msglen, data+msgStart+1); - } else { - uint8_t msglen2 = len-msgStart-1; - flib_log_d("[IPC OUT][%03u/%03u]%*.*s",(unsigned)msglen2, (unsigned)msglen, (unsigned)msglen2, (unsigned)msglen2, data+msgStart+1); - } - msgStart += (uint8_t)data[msgStart]+1; - } - } -} - -static void logRecvMsg(const uint8_t *data) { - if(flib_log_isActive(FLIB_LOGLEVEL_DEBUG)) { - uint8_t msglen = data[0]; - flib_log_d("[IPC IN][%03u]%*.*s",(unsigned)msglen, (unsigned)msglen, (unsigned)msglen, data+1); - } -} - -static void popFromReadBuffer(flib_ipcbase *ipc, uint8_t *outbuf, size_t size) { - memcpy(outbuf, ipc->readBuffer, size); - memmove(ipc->readBuffer, ipc->readBuffer+size, ipc->readBufferSize-size); - ipc->readBufferSize -= size; -} - -int flib_ipcbase_recv_message(flib_ipcbase *ipc, void *data) { - if(log_badargs_if2(ipc==NULL, data==NULL)) { - return -1; - } - - if(!isMessageReady(ipc)) { - receiveToBuffer(ipc); - } - - if(isMessageReady(ipc)) { - int msgsize = ipc->readBuffer[0]+1; - popFromReadBuffer(ipc, data, msgsize); - logRecvMsg(data); - return msgsize; - } else if(!ipc->sock && ipc->readBufferSize>0) { - flib_log_w("Last message from engine data stream is incomplete (received %u of %u bytes)", (unsigned)ipc->readBufferSize, (unsigned)(ipc->readBuffer[0])+1); - ipc->readBufferSize = 0; - return -1; - } else { - return -1; - } -} - -int flib_ipcbase_recv_map(flib_ipcbase *ipc, void *data) { - if(log_badargs_if2(ipc==NULL, data==NULL)) { - return -1; - } - - receiveToBuffer(ipc); - - if(ipc->readBufferSize >= IPCBASE_MAPMSG_BYTES) { - popFromReadBuffer(ipc, data, IPCBASE_MAPMSG_BYTES); - return IPCBASE_MAPMSG_BYTES; - } else { - return -1; - } -} - -int flib_ipcbase_send_raw(flib_ipcbase *ipc, const void *data, size_t len) { - if(log_badargs_if2(ipc==NULL, data==NULL && len>0) - || log_w_if(!ipc->sock, "flib_ipcbase_send_raw: Not connected.")) { - return -1; - } - if(flib_socket_send(ipc->sock, data, len) == len) { - logSentMsg(data, len); - return 0; - } else { - flib_log_w("Failed or incomplete IPC write: engine connection lost."); - flib_socket_close(ipc->sock); - ipc->sock = NULL; - return -1; - } -} - -int flib_ipcbase_send_message(flib_ipcbase *ipc, void *data, size_t len) { - if(log_badargs_if3(ipc==NULL, data==NULL && len>0, len>255)) { - return -1; - } - - uint8_t sendbuf[256]; - sendbuf[0] = len; - memcpy(sendbuf+1, data, len); - return flib_ipcbase_send_raw(ipc, sendbuf, len+1); -} - -void flib_ipcbase_accept(flib_ipcbase *ipc) { - if(!log_badargs_if(ipc==NULL) && !ipc->sock && ipc->acceptor) { - ipc->sock = flib_socket_accept(ipc->acceptor, true); - if(ipc->sock) { - flib_log_d("IPC connection accepted."); - flib_acceptor_close(ipc->acceptor); - ipc->acceptor = NULL; - } - } -} +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "ipcbase.h" +#include "../util/logging.h" +#include "../util/util.h" +#include "../socket.h" + +#include +#include +#include +#include + +/* + * The receive buffer has to be able to hold any message that might be received. Normally + * the messages are at most 256 bytes, but the map preview contains 4097 bytes (4096 for a + * bitmap, 1 for the number of hogs which fit on the map). + * + * We don't need to worry about wasting a few kb though, and I like powers of two... + */ +struct _flib_ipcbase { + uint8_t readBuffer[8192]; + int readBufferSize; + + flib_acceptor *acceptor; + uint16_t port; + + flib_tcpsocket *sock; +}; + +flib_ipcbase *flib_ipcbase_create() { + flib_ipcbase *result = flib_calloc(1, sizeof(flib_ipcbase)); + flib_acceptor *acceptor = flib_acceptor_create(0); + + if(!result || !acceptor) { + free(result); + flib_acceptor_close(acceptor); + return NULL; + } + + result->acceptor = acceptor; + result->sock = NULL; + result->readBufferSize = 0; + result->port = flib_acceptor_listenport(acceptor); + + flib_log_i("Started listening for IPC connections on port %u", (unsigned)result->port); + return result; +} + +uint16_t flib_ipcbase_port(flib_ipcbase *ipc) { + if(log_badargs_if(ipc==NULL)) { + return 0; + } + return ipc->port; +} + +void flib_ipcbase_destroy(flib_ipcbase *ipc) { + if(ipc) { + flib_acceptor_close(ipc->acceptor); + flib_socket_close(ipc->sock); + if(ipc->sock) { + flib_log_d("IPC connection closed."); + } + free(ipc); + } +} + +IpcState flib_ipcbase_state(flib_ipcbase *ipc) { + if(log_badargs_if(ipc==NULL)) { + return IPC_NOT_CONNECTED; + } else if(ipc->sock) { + return IPC_CONNECTED; + } else if(ipc->acceptor) { + return IPC_LISTENING; + } else { + return IPC_NOT_CONNECTED; + } +} + +static void receiveToBuffer(flib_ipcbase *ipc) { + if(ipc->sock) { + int size = flib_socket_nbrecv(ipc->sock, ipc->readBuffer+ipc->readBufferSize, sizeof(ipc->readBuffer)-ipc->readBufferSize); + if(size>=0) { + ipc->readBufferSize += size; + } else { + flib_log_d("IPC connection lost."); + flib_socket_close(ipc->sock); + ipc->sock = NULL; + } + } +} + +static bool isMessageReady(flib_ipcbase *ipc) { + return ipc->readBufferSize >= ipc->readBuffer[0]+1; +} + +static void logSentMsg(const uint8_t *data, size_t len) { + if(flib_log_isActive(FLIB_LOGLEVEL_DEBUG)) { + size_t msgStart = 0; + while(msgStart < len) { + uint8_t msglen = data[msgStart]; + if(msgStart+msglen < len) { + flib_log_d("[IPC OUT][%03u]%*.*s",(unsigned)msglen, (unsigned)msglen, (unsigned)msglen, data+msgStart+1); + } else { + uint8_t msglen2 = len-msgStart-1; + flib_log_d("[IPC OUT][%03u/%03u]%*.*s",(unsigned)msglen2, (unsigned)msglen, (unsigned)msglen2, (unsigned)msglen2, data+msgStart+1); + } + msgStart += (uint8_t)data[msgStart]+1; + } + } +} + +static void logRecvMsg(const uint8_t *data) { + if(flib_log_isActive(FLIB_LOGLEVEL_DEBUG)) { + uint8_t msglen = data[0]; + flib_log_d("[IPC IN][%03u]%*.*s",(unsigned)msglen, (unsigned)msglen, (unsigned)msglen, data+1); + } +} + +static void popFromReadBuffer(flib_ipcbase *ipc, uint8_t *outbuf, size_t size) { + memcpy(outbuf, ipc->readBuffer, size); + memmove(ipc->readBuffer, ipc->readBuffer+size, ipc->readBufferSize-size); + ipc->readBufferSize -= size; +} + +int flib_ipcbase_recv_message(flib_ipcbase *ipc, void *data) { + if(log_badargs_if2(ipc==NULL, data==NULL)) { + return -1; + } + + if(!isMessageReady(ipc)) { + receiveToBuffer(ipc); + } + + if(isMessageReady(ipc)) { + int msgsize = ipc->readBuffer[0]+1; + popFromReadBuffer(ipc, data, msgsize); + logRecvMsg(data); + return msgsize; + } else if(!ipc->sock && ipc->readBufferSize>0) { + flib_log_w("Last message from engine data stream is incomplete (received %u of %u bytes)", (unsigned)ipc->readBufferSize, (unsigned)(ipc->readBuffer[0])+1); + ipc->readBufferSize = 0; + return -1; + } else { + return -1; + } +} + +int flib_ipcbase_recv_map(flib_ipcbase *ipc, void *data) { + if(log_badargs_if2(ipc==NULL, data==NULL)) { + return -1; + } + + receiveToBuffer(ipc); + + if(ipc->readBufferSize >= IPCBASE_MAPMSG_BYTES) { + popFromReadBuffer(ipc, data, IPCBASE_MAPMSG_BYTES); + return IPCBASE_MAPMSG_BYTES; + } else { + return -1; + } +} + +int flib_ipcbase_send_raw(flib_ipcbase *ipc, const void *data, size_t len) { + if(log_badargs_if2(ipc==NULL, data==NULL && len>0) + || log_w_if(!ipc->sock, "flib_ipcbase_send_raw: Not connected.")) { + return -1; + } + if(flib_socket_send(ipc->sock, data, len) == len) { + logSentMsg(data, len); + return 0; + } else { + flib_log_w("Failed or incomplete IPC write: engine connection lost."); + flib_socket_close(ipc->sock); + ipc->sock = NULL; + return -1; + } +} + +int flib_ipcbase_send_message(flib_ipcbase *ipc, void *data, size_t len) { + if(log_badargs_if3(ipc==NULL, data==NULL && len>0, len>255)) { + return -1; + } + + uint8_t sendbuf[256]; + sendbuf[0] = len; + memcpy(sendbuf+1, data, len); + return flib_ipcbase_send_raw(ipc, sendbuf, len+1); +} + +void flib_ipcbase_accept(flib_ipcbase *ipc) { + if(!log_badargs_if(ipc==NULL) && !ipc->sock && ipc->acceptor) { + ipc->sock = flib_socket_accept(ipc->acceptor, true); + if(ipc->sock) { + flib_log_d("IPC connection accepted."); + flib_acceptor_close(ipc->acceptor); + ipc->acceptor = NULL; + } + } +} diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/ipc/ipcbase.h --- a/project_files/frontlib/ipc/ipcbase.h Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/ipc/ipcbase.h Tue Jan 21 22:43:06 2014 +0100 @@ -1,105 +1,105 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/* - * Low-level protocol support for the IPC connection to the engine. - */ -#ifndef IPCBASE_H_ -#define IPCBASE_H_ - -#include -#include -#include - -#define IPCBASE_MAPMSG_BYTES 4097 - -typedef enum {IPC_NOT_CONNECTED, IPC_LISTENING, IPC_CONNECTED} IpcState; - -typedef struct _flib_ipcbase flib_ipcbase; - -/** - * Start an engine connection by listening on a random port. The selected port can - * be queried with flib_ipcbase_port and has to be passed to the engine. - * - * Returns NULL on error. Destroy the created object with flib_ipcbase_destroy. - * - * We stop accepting new connections once a connection has been established, so you - * need to create a new ipcbase in order to start a new connection. - */ -flib_ipcbase *flib_ipcbase_create(); - -/** - * Return the listening port - */ -uint16_t flib_ipcbase_port(flib_ipcbase *ipc); - -/** - * Free resources and close sockets. NULL safe. - */ -void flib_ipcbase_destroy(flib_ipcbase *ipc); - -/** - * Determine the current connection state - */ -IpcState flib_ipcbase_state(flib_ipcbase *ipc); - -/** - * Receive a single message (up to 256 bytes) and copy it into the data buffer. - * Returns the length of the received message, a negative value if no message could - * be read. - * - * The first byte of a message is its content length, which is one less than the returned - * value. - * - * Note: When a connection is closed, you probably want to call this function until - * no further message is returned, to ensure you see all messages that were sent - * before the connection closed. - */ -int flib_ipcbase_recv_message(flib_ipcbase *ipc, void *data); - -/** - * Try to receive 4097 bytes. This is the size of the reply the engine sends - * when successfully queried for map data. The first 4096 bytes are a bit-packed - * twocolor image of the map (256x128), the last byte is the number of hogs that - * fit on the map. - */ -int flib_ipcbase_recv_map(flib_ipcbase *ipc, void *data); - -/** - * Blocking send bytes over the socket. No message framing will be added. - * Returns 0 on success. - */ -int flib_ipcbase_send_raw(flib_ipcbase *ipc, const void *data, size_t len); - -/** - * Write a single message (up to 255 bytes) to the engine. This call blocks until the - * message is completely written or the connection is closed or an error occurs. - * - * Calling this function in a state other than IPC_CONNECTED will fail immediately. - * Returns 0 on success. - */ -int flib_ipcbase_send_message(flib_ipcbase *ipc, void *data, size_t len); - -/** - * Try to accept a connection. Only has an effect in state IPC_LISTENING. - */ -void flib_ipcbase_accept(flib_ipcbase *ipc); - -#endif /* IPCBASE_H_ */ - +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * Low-level protocol support for the IPC connection to the engine. + */ +#ifndef IPCBASE_H_ +#define IPCBASE_H_ + +#include +#include +#include + +#define IPCBASE_MAPMSG_BYTES 4097 + +typedef enum {IPC_NOT_CONNECTED, IPC_LISTENING, IPC_CONNECTED} IpcState; + +typedef struct _flib_ipcbase flib_ipcbase; + +/** + * Start an engine connection by listening on a random port. The selected port can + * be queried with flib_ipcbase_port and has to be passed to the engine. + * + * Returns NULL on error. Destroy the created object with flib_ipcbase_destroy. + * + * We stop accepting new connections once a connection has been established, so you + * need to create a new ipcbase in order to start a new connection. + */ +flib_ipcbase *flib_ipcbase_create(); + +/** + * Return the listening port + */ +uint16_t flib_ipcbase_port(flib_ipcbase *ipc); + +/** + * Free resources and close sockets. NULL safe. + */ +void flib_ipcbase_destroy(flib_ipcbase *ipc); + +/** + * Determine the current connection state + */ +IpcState flib_ipcbase_state(flib_ipcbase *ipc); + +/** + * Receive a single message (up to 256 bytes) and copy it into the data buffer. + * Returns the length of the received message, a negative value if no message could + * be read. + * + * The first byte of a message is its content length, which is one less than the returned + * value. + * + * Note: When a connection is closed, you probably want to call this function until + * no further message is returned, to ensure you see all messages that were sent + * before the connection closed. + */ +int flib_ipcbase_recv_message(flib_ipcbase *ipc, void *data); + +/** + * Try to receive 4097 bytes. This is the size of the reply the engine sends + * when successfully queried for map data. The first 4096 bytes are a bit-packed + * twocolor image of the map (256x128), the last byte is the number of hogs that + * fit on the map. + */ +int flib_ipcbase_recv_map(flib_ipcbase *ipc, void *data); + +/** + * Blocking send bytes over the socket. No message framing will be added. + * Returns 0 on success. + */ +int flib_ipcbase_send_raw(flib_ipcbase *ipc, const void *data, size_t len); + +/** + * Write a single message (up to 255 bytes) to the engine. This call blocks until the + * message is completely written or the connection is closed or an error occurs. + * + * Calling this function in a state other than IPC_CONNECTED will fail immediately. + * Returns 0 on success. + */ +int flib_ipcbase_send_message(flib_ipcbase *ipc, void *data, size_t len); + +/** + * Try to accept a connection. Only has an effect in state IPC_LISTENING. + */ +void flib_ipcbase_accept(flib_ipcbase *ipc); + +#endif /* IPCBASE_H_ */ + diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/ipc/ipcprotocol.c --- a/project_files/frontlib/ipc/ipcprotocol.c Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/ipc/ipcprotocol.c Tue Jan 21 22:43:06 2014 +0100 @@ -1,316 +1,316 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "ipcprotocol.h" -#include "../util/util.h" -#include "../util/logging.h" -#include "../md5/md5.h" - -#include -#include -#include -#include -#include - -int flib_ipc_append_message(flib_vector *vec, const char *fmt, ...) { - int result = -1; - if(!log_badargs_if2(vec==NULL, fmt==NULL)) { - // 1 byte size prefix, 255 bytes max message length, 1 0-byte for vsnprintf - char msgbuffer[257]; - - // Format the message, leaving one byte at the start for the length - va_list argp; - va_start(argp, fmt); - int msgSize = vsnprintf(msgbuffer+1, 256, fmt, argp); - va_end(argp); - - if(!log_e_if(msgSize > 255, "Message too long (%u bytes)", (unsigned)msgSize) - && !log_e_if(msgSize < 0, "printf error")) { - // Add the length prefix - ((uint8_t*)msgbuffer)[0] = msgSize; - - // Append it to the vector - result = flib_vector_append(vec, msgbuffer, msgSize+1); - } - } - return result; -} - -int flib_ipc_append_mapconf(flib_vector *vec, const flib_map *map, bool mappreview) { - int result = -1; - flib_vector *tempvector = flib_vector_create(); - if(!log_badargs_if2(vec==NULL, map==NULL)) { - bool error = false; - - if(map->mapgen == MAPGEN_NAMED) { - error |= log_e_if(!map->name, "Missing map name") - || flib_ipc_append_message(tempvector, "emap %s", map->name); - } - if(!mappreview) { - error |= log_e_if(!map->theme, "Missing map theme") - || flib_ipc_append_message(tempvector, "etheme %s", map->theme); - } - error |= flib_ipc_append_seed(tempvector, map->seed); - error |= flib_ipc_append_message(tempvector, "e$template_filter %i", map->templateFilter); - error |= flib_ipc_append_message(tempvector, "e$mapgen %i", map->mapgen); - - if(map->mapgen == MAPGEN_MAZE) { - error |= flib_ipc_append_message(tempvector, "e$maze_size %i", map->mazeSize); - } - if(map->mapgen == MAPGEN_DRAWN) { - /* - * We have to split the drawn map data into several edraw messages here because - * it can be longer than the maximum message size. - */ - const char *edraw = "edraw "; - int edrawlen = strlen(edraw); - for(size_t offset=0; offsetdrawDataSize; offset+=200) { - size_t bytesRemaining = map->drawDataSize-offset; - int fragmentsize = bytesRemaining < 200 ? bytesRemaining : 200; - uint8_t messagesize = edrawlen + fragmentsize; - error |= flib_vector_append(tempvector, &messagesize, 1); - error |= flib_vector_append(tempvector, edraw, edrawlen); - error |= flib_vector_append(tempvector, map->drawData+offset, fragmentsize); - } - } - - if(!log_e_if(error, "Error generating map config")) { - // Message created, now we can copy everything. - flib_constbuffer constbuf = flib_vector_as_constbuffer(tempvector); - if(!flib_vector_append(vec, constbuf.data, constbuf.size)) { - result = 0; - } - } - } - flib_vector_destroy(tempvector); - return result; -} - -int flib_ipc_append_seed(flib_vector *vec, const char *seed) { - if(log_badargs_if2(vec==NULL, seed==NULL)) { - return -1; - } - return flib_ipc_append_message(vec, "eseed %s", seed); -} - -int flib_ipc_append_script(flib_vector *vec, const char *script) { - int result = -1; - if(!log_badargs_if2(vec==NULL, script==NULL)) { - result = flib_ipc_append_message(vec, "escript %s", script); - } - return result; -} - -int flib_ipc_append_style(flib_vector *vec, const char *style) { - int result = -1; - char *copy = flib_strdupnull(style); - if(!log_badargs_if(vec==NULL) && copy) { - if(!strcmp("Normal", copy)) { - // "Normal" means no gametype script - // TODO if an empty script called "Normal" is added to the scripts directory this can be removed - result = 0; - } else { - size_t len = strlen(copy); - for(size_t i=0; imods[i]) { - int bitmaskIndex = flib_meta.mods[i].bitmaskIndex; - result |= (UINT32_C(1) << bitmaskIndex); - } - } - return result; -} - -int flib_ipc_append_gamescheme(flib_vector *vec, const flib_scheme *scheme) { - int result = -1; - flib_vector *tempvector = flib_vector_create(); - if(!log_badargs_if2(vec==NULL, scheme==NULL) && tempvector) { - bool error = false; - error |= flib_ipc_append_message(tempvector, "e$gmflags %"PRIu32, buildModFlags(scheme)); - for(int i=0; isettings[i]; - if(flib_meta.settings[i].maxMeansInfinity) { - value = value>=flib_meta.settings[i].max ? 9999 : value; - } - if(flib_meta.settings[i].times1000) { - value *= 1000; - } - error |= flib_ipc_append_message(tempvector, "%s %i", flib_meta.settings[i].engineCommand, value); - } - } - - if(!error) { - // Message created, now we can copy everything. - flib_constbuffer constbuf = flib_vector_as_constbuffer(tempvector); - if(!flib_vector_append(vec, constbuf.data, constbuf.size)) { - result = 0; - } - } - } - flib_vector_destroy(tempvector); - return result; -} - -static int appendWeaponSet(flib_vector *vec, flib_weaponset *set) { - return flib_ipc_append_message(vec, "eammloadt %s", set->loadout) - || flib_ipc_append_message(vec, "eammprob %s", set->crateprob) - || flib_ipc_append_message(vec, "eammdelay %s", set->delay) - || flib_ipc_append_message(vec, "eammreinf %s", set->crateammo); -} - -static void calculateMd5Hex(const char *in, char out[33]) { - md5_state_t md5state; - uint8_t md5bytes[16]; - md5_init(&md5state); - md5_append(&md5state, (unsigned char*)in, strlen(in)); - md5_finish(&md5state, md5bytes); - for(int i=0;ihogs[0].weaponset) - || flib_ipc_append_message(tempvector, "eammstore"); - } - - char md5Hex[33]; - calculateMd5Hex(team->ownerName ? team->ownerName : "", md5Hex); - if(team->colorIndex<0 || team->colorIndex>=flib_teamcolor_count) { - flib_log_e("Color index out of bounds for team %s: %i", team->name, team->colorIndex); - error = true; - } else { - error |= flib_ipc_append_message(tempvector, "eaddteam %s %"PRIu32" %s", md5Hex, flib_teamcolors[team->colorIndex], team->name); - } - - if(team->remoteDriven) { - error |= flib_ipc_append_message(tempvector, "erdriven"); - } - - error |= flib_ipc_append_message(tempvector, "egrave %s", team->grave); - error |= flib_ipc_append_message(tempvector, "efort %s", team->fort); - error |= flib_ipc_append_message(tempvector, "evoicepack %s", team->voicepack); - error |= flib_ipc_append_message(tempvector, "eflag %s", team->flag); - - for(int i=0; ibindingCount; i++) { - error |= flib_ipc_append_message(tempvector, "ebind %s %s", team->bindings[i].binding, team->bindings[i].action); - } - - for(int i=0; ihogsInGame; i++) { - if(perHogAmmo && !noAmmoStore) { - error |= appendWeaponSet(tempvector, team->hogs[i].weaponset); - } - error |= flib_ipc_append_message(tempvector, "eaddhh %i %i %s", team->hogs[i].difficulty, team->hogs[i].initialHealth, team->hogs[i].name); - error |= flib_ipc_append_message(tempvector, "ehat %s", team->hogs[i].hat); - } - - if(!error) { - // Message created, now we can copy everything. - flib_constbuffer constbuf = flib_vector_as_constbuffer(tempvector); - if(!flib_vector_append(vec, constbuf.data, constbuf.size)) { - result = 0; - } - } - } - flib_vector_destroy(tempvector); - return result; -} - -int flib_ipc_append_fullconfig(flib_vector *vec, const flib_gamesetup *setup, bool netgame) { - int result = -1; - flib_vector *tempvector = flib_vector_create(); - if(!log_badargs_if2(vec==NULL, setup==NULL) && tempvector) { - bool error = false; - bool perHogAmmo = false; - bool sharedAmmo = false; - - error |= flib_ipc_append_message(vec, netgame ? "TN" : "TL"); - if(setup->map) { - error |= flib_ipc_append_mapconf(tempvector, setup->map, false); - } - if(setup->style) { - error |= flib_ipc_append_style(tempvector, setup->style); - } - if(setup->gamescheme) { - error |= flib_ipc_append_gamescheme(tempvector, setup->gamescheme); - sharedAmmo = flib_scheme_get_mod(setup->gamescheme, "sharedammo"); - // Shared ammo has priority over per-hog ammo - perHogAmmo = !sharedAmmo && flib_scheme_get_mod(setup->gamescheme, "perhogammo"); - } - if(setup->teamlist->teams && setup->teamlist->teamCount>0) { - int *clanColors = flib_calloc(setup->teamlist->teamCount, sizeof(int)); - if(!clanColors) { - error = true; - } else { - int clanCount = 0; - for(int i=0; !error && iteamlist->teamCount; i++) { - flib_team *team = setup->teamlist->teams[i]; - // Find the clan index of this team (clans are identified by color). - bool newClan = false; - int clan = 0; - while(clancolorIndex) { - clan++; - } - if(clan==clanCount) { - newClan = true; - clanCount++; - clanColors[clan] = team->colorIndex; - } - - // If shared ammo is active, only add an ammo store for the first team in each clan. - bool noAmmoStore = sharedAmmo&&!newClan; - error |= flib_ipc_append_addteam(tempvector, setup->teamlist->teams[i], perHogAmmo, noAmmoStore); - } - } - free(clanColors); - } - error |= flib_ipc_append_message(tempvector, "!"); - - if(!error) { - // Message created, now we can copy everything. - flib_constbuffer constbuf = flib_vector_as_constbuffer(tempvector); - if(!flib_vector_append(vec, constbuf.data, constbuf.size)) { - result = 0; - } - } - } - return result; -} +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "ipcprotocol.h" +#include "../util/util.h" +#include "../util/logging.h" +#include "../md5/md5.h" + +#include +#include +#include +#include +#include + +int flib_ipc_append_message(flib_vector *vec, const char *fmt, ...) { + int result = -1; + if(!log_badargs_if2(vec==NULL, fmt==NULL)) { + // 1 byte size prefix, 255 bytes max message length, 1 0-byte for vsnprintf + char msgbuffer[257]; + + // Format the message, leaving one byte at the start for the length + va_list argp; + va_start(argp, fmt); + int msgSize = vsnprintf(msgbuffer+1, 256, fmt, argp); + va_end(argp); + + if(!log_e_if(msgSize > 255, "Message too long (%u bytes)", (unsigned)msgSize) + && !log_e_if(msgSize < 0, "printf error")) { + // Add the length prefix + ((uint8_t*)msgbuffer)[0] = msgSize; + + // Append it to the vector + result = flib_vector_append(vec, msgbuffer, msgSize+1); + } + } + return result; +} + +int flib_ipc_append_mapconf(flib_vector *vec, const flib_map *map, bool mappreview) { + int result = -1; + flib_vector *tempvector = flib_vector_create(); + if(!log_badargs_if2(vec==NULL, map==NULL)) { + bool error = false; + + if(map->mapgen == MAPGEN_NAMED) { + error |= log_e_if(!map->name, "Missing map name") + || flib_ipc_append_message(tempvector, "emap %s", map->name); + } + if(!mappreview) { + error |= log_e_if(!map->theme, "Missing map theme") + || flib_ipc_append_message(tempvector, "etheme %s", map->theme); + } + error |= flib_ipc_append_seed(tempvector, map->seed); + error |= flib_ipc_append_message(tempvector, "e$template_filter %i", map->templateFilter); + error |= flib_ipc_append_message(tempvector, "e$mapgen %i", map->mapgen); + + if(map->mapgen == MAPGEN_MAZE) { + error |= flib_ipc_append_message(tempvector, "e$maze_size %i", map->mazeSize); + } + if(map->mapgen == MAPGEN_DRAWN) { + /* + * We have to split the drawn map data into several edraw messages here because + * it can be longer than the maximum message size. + */ + const char *edraw = "edraw "; + int edrawlen = strlen(edraw); + for(size_t offset=0; offsetdrawDataSize; offset+=200) { + size_t bytesRemaining = map->drawDataSize-offset; + int fragmentsize = bytesRemaining < 200 ? bytesRemaining : 200; + uint8_t messagesize = edrawlen + fragmentsize; + error |= flib_vector_append(tempvector, &messagesize, 1); + error |= flib_vector_append(tempvector, edraw, edrawlen); + error |= flib_vector_append(tempvector, map->drawData+offset, fragmentsize); + } + } + + if(!log_e_if(error, "Error generating map config")) { + // Message created, now we can copy everything. + flib_constbuffer constbuf = flib_vector_as_constbuffer(tempvector); + if(!flib_vector_append(vec, constbuf.data, constbuf.size)) { + result = 0; + } + } + } + flib_vector_destroy(tempvector); + return result; +} + +int flib_ipc_append_seed(flib_vector *vec, const char *seed) { + if(log_badargs_if2(vec==NULL, seed==NULL)) { + return -1; + } + return flib_ipc_append_message(vec, "eseed %s", seed); +} + +int flib_ipc_append_script(flib_vector *vec, const char *script) { + int result = -1; + if(!log_badargs_if2(vec==NULL, script==NULL)) { + result = flib_ipc_append_message(vec, "escript %s", script); + } + return result; +} + +int flib_ipc_append_style(flib_vector *vec, const char *style) { + int result = -1; + char *copy = flib_strdupnull(style); + if(!log_badargs_if(vec==NULL) && copy) { + if(!strcmp("Normal", copy)) { + // "Normal" means no gametype script + // TODO if an empty script called "Normal" is added to the scripts directory this can be removed + result = 0; + } else { + size_t len = strlen(copy); + for(size_t i=0; imods[i]) { + int bitmaskIndex = flib_meta.mods[i].bitmaskIndex; + result |= (UINT32_C(1) << bitmaskIndex); + } + } + return result; +} + +int flib_ipc_append_gamescheme(flib_vector *vec, const flib_scheme *scheme) { + int result = -1; + flib_vector *tempvector = flib_vector_create(); + if(!log_badargs_if2(vec==NULL, scheme==NULL) && tempvector) { + bool error = false; + error |= flib_ipc_append_message(tempvector, "e$gmflags %"PRIu32, buildModFlags(scheme)); + for(int i=0; isettings[i]; + if(flib_meta.settings[i].maxMeansInfinity) { + value = value>=flib_meta.settings[i].max ? 9999 : value; + } + if(flib_meta.settings[i].times1000) { + value *= 1000; + } + error |= flib_ipc_append_message(tempvector, "%s %i", flib_meta.settings[i].engineCommand, value); + } + } + + if(!error) { + // Message created, now we can copy everything. + flib_constbuffer constbuf = flib_vector_as_constbuffer(tempvector); + if(!flib_vector_append(vec, constbuf.data, constbuf.size)) { + result = 0; + } + } + } + flib_vector_destroy(tempvector); + return result; +} + +static int appendWeaponSet(flib_vector *vec, flib_weaponset *set) { + return flib_ipc_append_message(vec, "eammloadt %s", set->loadout) + || flib_ipc_append_message(vec, "eammprob %s", set->crateprob) + || flib_ipc_append_message(vec, "eammdelay %s", set->delay) + || flib_ipc_append_message(vec, "eammreinf %s", set->crateammo); +} + +static void calculateMd5Hex(const char *in, char out[33]) { + md5_state_t md5state; + uint8_t md5bytes[16]; + md5_init(&md5state); + md5_append(&md5state, (unsigned char*)in, strlen(in)); + md5_finish(&md5state, md5bytes); + for(int i=0;ihogs[0].weaponset) + || flib_ipc_append_message(tempvector, "eammstore"); + } + + char md5Hex[33]; + calculateMd5Hex(team->ownerName ? team->ownerName : "", md5Hex); + if(team->colorIndex<0 || team->colorIndex>=flib_teamcolor_count) { + flib_log_e("Color index out of bounds for team %s: %i", team->name, team->colorIndex); + error = true; + } else { + error |= flib_ipc_append_message(tempvector, "eaddteam %s %"PRIu32" %s", md5Hex, flib_teamcolors[team->colorIndex], team->name); + } + + if(team->remoteDriven) { + error |= flib_ipc_append_message(tempvector, "erdriven"); + } + + error |= flib_ipc_append_message(tempvector, "egrave %s", team->grave); + error |= flib_ipc_append_message(tempvector, "efort %s", team->fort); + error |= flib_ipc_append_message(tempvector, "evoicepack %s", team->voicepack); + error |= flib_ipc_append_message(tempvector, "eflag %s", team->flag); + + for(int i=0; ibindingCount; i++) { + error |= flib_ipc_append_message(tempvector, "ebind %s %s", team->bindings[i].binding, team->bindings[i].action); + } + + for(int i=0; ihogsInGame; i++) { + if(perHogAmmo && !noAmmoStore) { + error |= appendWeaponSet(tempvector, team->hogs[i].weaponset); + } + error |= flib_ipc_append_message(tempvector, "eaddhh %i %i %s", team->hogs[i].difficulty, team->hogs[i].initialHealth, team->hogs[i].name); + error |= flib_ipc_append_message(tempvector, "ehat %s", team->hogs[i].hat); + } + + if(!error) { + // Message created, now we can copy everything. + flib_constbuffer constbuf = flib_vector_as_constbuffer(tempvector); + if(!flib_vector_append(vec, constbuf.data, constbuf.size)) { + result = 0; + } + } + } + flib_vector_destroy(tempvector); + return result; +} + +int flib_ipc_append_fullconfig(flib_vector *vec, const flib_gamesetup *setup, bool netgame) { + int result = -1; + flib_vector *tempvector = flib_vector_create(); + if(!log_badargs_if2(vec==NULL, setup==NULL) && tempvector) { + bool error = false; + bool perHogAmmo = false; + bool sharedAmmo = false; + + error |= flib_ipc_append_message(vec, netgame ? "TN" : "TL"); + if(setup->map) { + error |= flib_ipc_append_mapconf(tempvector, setup->map, false); + } + if(setup->style) { + error |= flib_ipc_append_style(tempvector, setup->style); + } + if(setup->gamescheme) { + error |= flib_ipc_append_gamescheme(tempvector, setup->gamescheme); + sharedAmmo = flib_scheme_get_mod(setup->gamescheme, "sharedammo"); + // Shared ammo has priority over per-hog ammo + perHogAmmo = !sharedAmmo && flib_scheme_get_mod(setup->gamescheme, "perhogammo"); + } + if(setup->teamlist->teams && setup->teamlist->teamCount>0) { + int *clanColors = flib_calloc(setup->teamlist->teamCount, sizeof(int)); + if(!clanColors) { + error = true; + } else { + int clanCount = 0; + for(int i=0; !error && iteamlist->teamCount; i++) { + flib_team *team = setup->teamlist->teams[i]; + // Find the clan index of this team (clans are identified by color). + bool newClan = false; + int clan = 0; + while(clancolorIndex) { + clan++; + } + if(clan==clanCount) { + newClan = true; + clanCount++; + clanColors[clan] = team->colorIndex; + } + + // If shared ammo is active, only add an ammo store for the first team in each clan. + bool noAmmoStore = sharedAmmo&&!newClan; + error |= flib_ipc_append_addteam(tempvector, setup->teamlist->teams[i], perHogAmmo, noAmmoStore); + } + } + free(clanColors); + } + error |= flib_ipc_append_message(tempvector, "!"); + + if(!error) { + // Message created, now we can copy everything. + flib_constbuffer constbuf = flib_vector_as_constbuffer(tempvector); + if(!flib_vector_append(vec, constbuf.data, constbuf.size)) { + result = 0; + } + } + } + return result; +} diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/ipc/ipcprotocol.h --- a/project_files/frontlib/ipc/ipcprotocol.h Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/ipc/ipcprotocol.h Tue Jan 21 22:43:06 2014 +0100 @@ -1,93 +1,93 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef IPCPROTOCOL_H_ -#define IPCPROTOCOL_H_ - -#include "../util/buffer.h" -#include "../model/map.h" -#include "../model/team.h" -#include "../model/scheme.h" -#include "../model/gamesetup.h" - -#include - -/** - * Create a message in the IPC protocol format and add it to - * the vector. Use a format string and extra parameters as with printf. - * - * Returns nonzero if something goes wrong. In that case the buffer - * contents are unaffected. - */ -int flib_ipc_append_message(flib_vector *vec, const char *fmt, ...); - -/** - * Append IPC messages to the buffer that configure the engine for - * this map. - * - * Unfortunately the engine needs a slightly different configuration - * for generating a map preview. - * - * Returns nonzero if something goes wrong. In that case the buffer - * contents are unaffected. - */ -int flib_ipc_append_mapconf(flib_vector *vec, const flib_map *map, bool mappreview); - -/** - * Append a seed message to the buffer. - * - * Returns nonzero if something goes wrong. In that case the buffer - * contents are unaffected. - */ -int flib_ipc_append_seed(flib_vector *vec, const char *seed); - -/** - * Append a script to the buffer (e.g. "Missions/Training/Basic_Training_-_Bazooka.lua") - * - * Returns nonzero if something goes wrong. In that case the buffer - * contents are unaffected. - */ -int flib_ipc_append_script(flib_vector *vec, const char *script); - -/** - * Append a game style to the buffer. (e.g. "Capture the Flag") - * - * Returns nonzero if something goes wrong. In that case the buffer - * contents are unaffected. - */ -int flib_ipc_append_style(flib_vector *vec, const char *style); - -/** - * Append the game scheme to the buffer. - * - * Returns nonzero if something goes wrong. In that case the buffer - * contents are unaffected. - */ -int flib_ipc_append_gamescheme(flib_vector *vec, const flib_scheme *scheme); - -/** - * Append the entire game config to the buffer (including the final "!" that marks the - * end of configuration data for the engine) - * - * Returns nonzero if something goes wrong. In that case the buffer - * contents are unaffected. - */ -int flib_ipc_append_fullconfig(flib_vector *vec, const flib_gamesetup *setup, bool netgame); - -#endif /* IPCPROTOCOL_H_ */ +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef IPCPROTOCOL_H_ +#define IPCPROTOCOL_H_ + +#include "../util/buffer.h" +#include "../model/map.h" +#include "../model/team.h" +#include "../model/scheme.h" +#include "../model/gamesetup.h" + +#include + +/** + * Create a message in the IPC protocol format and add it to + * the vector. Use a format string and extra parameters as with printf. + * + * Returns nonzero if something goes wrong. In that case the buffer + * contents are unaffected. + */ +int flib_ipc_append_message(flib_vector *vec, const char *fmt, ...); + +/** + * Append IPC messages to the buffer that configure the engine for + * this map. + * + * Unfortunately the engine needs a slightly different configuration + * for generating a map preview. + * + * Returns nonzero if something goes wrong. In that case the buffer + * contents are unaffected. + */ +int flib_ipc_append_mapconf(flib_vector *vec, const flib_map *map, bool mappreview); + +/** + * Append a seed message to the buffer. + * + * Returns nonzero if something goes wrong. In that case the buffer + * contents are unaffected. + */ +int flib_ipc_append_seed(flib_vector *vec, const char *seed); + +/** + * Append a script to the buffer (e.g. "Missions/Training/Basic_Training_-_Bazooka.lua") + * + * Returns nonzero if something goes wrong. In that case the buffer + * contents are unaffected. + */ +int flib_ipc_append_script(flib_vector *vec, const char *script); + +/** + * Append a game style to the buffer. (e.g. "Capture the Flag") + * + * Returns nonzero if something goes wrong. In that case the buffer + * contents are unaffected. + */ +int flib_ipc_append_style(flib_vector *vec, const char *style); + +/** + * Append the game scheme to the buffer. + * + * Returns nonzero if something goes wrong. In that case the buffer + * contents are unaffected. + */ +int flib_ipc_append_gamescheme(flib_vector *vec, const flib_scheme *scheme); + +/** + * Append the entire game config to the buffer (including the final "!" that marks the + * end of configuration data for the engine) + * + * Returns nonzero if something goes wrong. In that case the buffer + * contents are unaffected. + */ +int flib_ipc_append_fullconfig(flib_vector *vec, const flib_gamesetup *setup, bool netgame); + +#endif /* IPCPROTOCOL_H_ */ diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/ipc/mapconn.c --- a/project_files/frontlib/ipc/mapconn.c Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/ipc/mapconn.c Tue Jan 21 22:43:06 2014 +0100 @@ -1,196 +1,196 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "mapconn.h" -#include "ipcbase.h" -#include "ipcprotocol.h" - -#include "../util/logging.h" -#include "../util/buffer.h" -#include "../util/util.h" - -#include - -typedef enum { - AWAIT_CONNECTION, - AWAIT_REPLY, - AWAIT_CLOSE, - FINISHED -} mapconn_state; - -struct _flib_mapconn { - uint8_t mapBuffer[IPCBASE_MAPMSG_BYTES]; - flib_ipcbase *ipcBase; - flib_vector *configBuffer; - - mapconn_state progress; - - void (*onSuccessCb)(void*, const uint8_t*, int); - void *onSuccessCtx; - - void (*onFailureCb)(void*, const char*); - void *onFailureCtx; - - bool running; - bool destroyRequested; -}; - -static void noop_handleSuccess(void *context, const uint8_t *bitmap, int numHedgehogs) {} -static void noop_handleFailure(void *context, const char *errormessage) {} - -static void clearCallbacks(flib_mapconn *conn) { - conn->onSuccessCb = &noop_handleSuccess; - conn->onFailureCb = &noop_handleFailure; -} - -static flib_vector *createConfigBuffer(const flib_map *mapdesc) { - flib_vector *result = NULL; - flib_vector *tempbuffer = flib_vector_create(); - if(tempbuffer) { - bool error = false; - error |= flib_ipc_append_mapconf(tempbuffer, mapdesc, true); - error |= flib_ipc_append_message(tempbuffer, "!"); - if(!error) { - result = tempbuffer; - tempbuffer = NULL; - } - } - flib_vector_destroy(tempbuffer); - return result; -} - -flib_mapconn *flib_mapconn_create(const flib_map *mapdesc) { - if(log_badargs_if(mapdesc==NULL)) { - return NULL; - } - flib_mapconn *result = NULL; - flib_mapconn *tempConn = flib_calloc(1, sizeof(flib_mapconn)); - if(tempConn) { - tempConn->ipcBase = flib_ipcbase_create(); - tempConn->configBuffer = createConfigBuffer(mapdesc); - if(tempConn->ipcBase && tempConn->configBuffer) { - tempConn->progress = AWAIT_CONNECTION; - clearCallbacks(tempConn); - result = tempConn; - tempConn = NULL; - } - } - flib_mapconn_destroy(tempConn); - return result; -} - -void flib_mapconn_destroy(flib_mapconn *conn) { - if(conn) { - if(conn->running) { - /* - * The function was called from a callback, so the tick function is still running - * and we delay the actual destruction. We ensure no further callbacks will be - * sent to prevent surprises. - */ - clearCallbacks(conn); - conn->destroyRequested = true; - } else { - flib_ipcbase_destroy(conn->ipcBase); - flib_vector_destroy(conn->configBuffer); - free(conn); - } - } -} - -int flib_mapconn_getport(flib_mapconn *conn) { - if(log_badargs_if(conn==NULL)) { - return 0; - } - return flib_ipcbase_port(conn->ipcBase); -} - -void flib_mapconn_onSuccess(flib_mapconn *conn, void (*callback)(void* context, const uint8_t *bitmap, int numHedgehogs), void *context) { - if(!log_badargs_if(conn==NULL)) { - conn->onSuccessCb = callback ? callback : &noop_handleSuccess; - conn->onSuccessCtx = context; - } -} - -void flib_mapconn_onFailure(flib_mapconn *conn, void (*callback)(void* context, const char *errormessage), void *context) { - if(!log_badargs_if(conn==NULL)) { - conn->onFailureCb = callback ? callback : &noop_handleFailure; - conn->onFailureCtx = context; - } -} - -static void flib_mapconn_wrappedtick(flib_mapconn *conn) { - if(conn->progress == AWAIT_CONNECTION) { - flib_ipcbase_accept(conn->ipcBase); - switch(flib_ipcbase_state(conn->ipcBase)) { - case IPC_CONNECTED: - { - flib_constbuffer configBuffer = flib_vector_as_constbuffer(conn->configBuffer); - if(flib_ipcbase_send_raw(conn->ipcBase, configBuffer.data, configBuffer.size)) { - conn->progress = FINISHED; - conn->onFailureCb(conn->onFailureCtx, "Error sending map information to the engine."); - return; - } else { - conn->progress = AWAIT_REPLY; - } - } - break; - case IPC_NOT_CONNECTED: - conn->progress = FINISHED; - conn->onFailureCb(conn->onFailureCtx, "Engine connection closed unexpectedly."); - return; - default: - break; - } - } - - if(conn->progress == AWAIT_REPLY) { - if(flib_ipcbase_recv_map(conn->ipcBase, conn->mapBuffer) >= 0) { - conn->progress = AWAIT_CLOSE; - } else if(flib_ipcbase_state(conn->ipcBase) != IPC_CONNECTED) { - conn->progress = FINISHED; - conn->onFailureCb(conn->onSuccessCtx, "Engine connection closed unexpectedly."); - return; - } - } - - if(conn->progress == AWAIT_CLOSE) { - // Just do throwaway reads so we find out when the engine disconnects - uint8_t buf[256]; - flib_ipcbase_recv_message(conn->ipcBase, buf); - if(flib_ipcbase_state(conn->ipcBase) != IPC_CONNECTED) { - conn->progress = FINISHED; - conn->onSuccessCb(conn->onSuccessCtx, conn->mapBuffer, conn->mapBuffer[IPCBASE_MAPMSG_BYTES-1]); - return; - } - } -} - -void flib_mapconn_tick(flib_mapconn *conn) { - if(!log_badargs_if(conn==NULL) - && !log_w_if(conn->running, "Call to flib_mapconn_tick from a callback") - && !log_w_if(conn->progress == FINISHED, "We are already done.")) { - conn->running = true; - flib_mapconn_wrappedtick(conn); - conn->running = false; - - if(conn->destroyRequested) { - flib_mapconn_destroy(conn); - } - } -} +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mapconn.h" +#include "ipcbase.h" +#include "ipcprotocol.h" + +#include "../util/logging.h" +#include "../util/buffer.h" +#include "../util/util.h" + +#include + +typedef enum { + AWAIT_CONNECTION, + AWAIT_REPLY, + AWAIT_CLOSE, + FINISHED +} mapconn_state; + +struct _flib_mapconn { + uint8_t mapBuffer[IPCBASE_MAPMSG_BYTES]; + flib_ipcbase *ipcBase; + flib_vector *configBuffer; + + mapconn_state progress; + + void (*onSuccessCb)(void*, const uint8_t*, int); + void *onSuccessCtx; + + void (*onFailureCb)(void*, const char*); + void *onFailureCtx; + + bool running; + bool destroyRequested; +}; + +static void noop_handleSuccess(void *context, const uint8_t *bitmap, int numHedgehogs) {} +static void noop_handleFailure(void *context, const char *errormessage) {} + +static void clearCallbacks(flib_mapconn *conn) { + conn->onSuccessCb = &noop_handleSuccess; + conn->onFailureCb = &noop_handleFailure; +} + +static flib_vector *createConfigBuffer(const flib_map *mapdesc) { + flib_vector *result = NULL; + flib_vector *tempbuffer = flib_vector_create(); + if(tempbuffer) { + bool error = false; + error |= flib_ipc_append_mapconf(tempbuffer, mapdesc, true); + error |= flib_ipc_append_message(tempbuffer, "!"); + if(!error) { + result = tempbuffer; + tempbuffer = NULL; + } + } + flib_vector_destroy(tempbuffer); + return result; +} + +flib_mapconn *flib_mapconn_create(const flib_map *mapdesc) { + if(log_badargs_if(mapdesc==NULL)) { + return NULL; + } + flib_mapconn *result = NULL; + flib_mapconn *tempConn = flib_calloc(1, sizeof(flib_mapconn)); + if(tempConn) { + tempConn->ipcBase = flib_ipcbase_create(); + tempConn->configBuffer = createConfigBuffer(mapdesc); + if(tempConn->ipcBase && tempConn->configBuffer) { + tempConn->progress = AWAIT_CONNECTION; + clearCallbacks(tempConn); + result = tempConn; + tempConn = NULL; + } + } + flib_mapconn_destroy(tempConn); + return result; +} + +void flib_mapconn_destroy(flib_mapconn *conn) { + if(conn) { + if(conn->running) { + /* + * The function was called from a callback, so the tick function is still running + * and we delay the actual destruction. We ensure no further callbacks will be + * sent to prevent surprises. + */ + clearCallbacks(conn); + conn->destroyRequested = true; + } else { + flib_ipcbase_destroy(conn->ipcBase); + flib_vector_destroy(conn->configBuffer); + free(conn); + } + } +} + +int flib_mapconn_getport(flib_mapconn *conn) { + if(log_badargs_if(conn==NULL)) { + return 0; + } + return flib_ipcbase_port(conn->ipcBase); +} + +void flib_mapconn_onSuccess(flib_mapconn *conn, void (*callback)(void* context, const uint8_t *bitmap, int numHedgehogs), void *context) { + if(!log_badargs_if(conn==NULL)) { + conn->onSuccessCb = callback ? callback : &noop_handleSuccess; + conn->onSuccessCtx = context; + } +} + +void flib_mapconn_onFailure(flib_mapconn *conn, void (*callback)(void* context, const char *errormessage), void *context) { + if(!log_badargs_if(conn==NULL)) { + conn->onFailureCb = callback ? callback : &noop_handleFailure; + conn->onFailureCtx = context; + } +} + +static void flib_mapconn_wrappedtick(flib_mapconn *conn) { + if(conn->progress == AWAIT_CONNECTION) { + flib_ipcbase_accept(conn->ipcBase); + switch(flib_ipcbase_state(conn->ipcBase)) { + case IPC_CONNECTED: + { + flib_constbuffer configBuffer = flib_vector_as_constbuffer(conn->configBuffer); + if(flib_ipcbase_send_raw(conn->ipcBase, configBuffer.data, configBuffer.size)) { + conn->progress = FINISHED; + conn->onFailureCb(conn->onFailureCtx, "Error sending map information to the engine."); + return; + } else { + conn->progress = AWAIT_REPLY; + } + } + break; + case IPC_NOT_CONNECTED: + conn->progress = FINISHED; + conn->onFailureCb(conn->onFailureCtx, "Engine connection closed unexpectedly."); + return; + default: + break; + } + } + + if(conn->progress == AWAIT_REPLY) { + if(flib_ipcbase_recv_map(conn->ipcBase, conn->mapBuffer) >= 0) { + conn->progress = AWAIT_CLOSE; + } else if(flib_ipcbase_state(conn->ipcBase) != IPC_CONNECTED) { + conn->progress = FINISHED; + conn->onFailureCb(conn->onSuccessCtx, "Engine connection closed unexpectedly."); + return; + } + } + + if(conn->progress == AWAIT_CLOSE) { + // Just do throwaway reads so we find out when the engine disconnects + uint8_t buf[256]; + flib_ipcbase_recv_message(conn->ipcBase, buf); + if(flib_ipcbase_state(conn->ipcBase) != IPC_CONNECTED) { + conn->progress = FINISHED; + conn->onSuccessCb(conn->onSuccessCtx, conn->mapBuffer, conn->mapBuffer[IPCBASE_MAPMSG_BYTES-1]); + return; + } + } +} + +void flib_mapconn_tick(flib_mapconn *conn) { + if(!log_badargs_if(conn==NULL) + && !log_w_if(conn->running, "Call to flib_mapconn_tick from a callback") + && !log_w_if(conn->progress == FINISHED, "We are already done.")) { + conn->running = true; + flib_mapconn_wrappedtick(conn); + conn->running = false; + + if(conn->destroyRequested) { + flib_mapconn_destroy(conn); + } + } +} diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/ipc/mapconn.h --- a/project_files/frontlib/ipc/mapconn.h Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/ipc/mapconn.h Tue Jan 21 22:43:06 2014 +0100 @@ -1,116 +1,116 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * Functions for querying a map preview from the engine, which includes both a two-color image - * and the number of hogs this map is suitable for. - * - * The general usage is to first create a mapconn object by calling flib_mapconn_create. - * That will cause the frontlib to listen on a random port which can be queried using - * flib_mapconn_getport(). You should also register your callback functions right at the start - * to ensure you don't miss any callbacks. - * - * Next, start the engine (that part is up to you) with the appropriate command line arguments - * for a map preview request. - * - * In order to allow the mapconn to run, you should regularly call flib_mapconn_tick(), which - * performs network I/O and calls your callbacks if the map has been generated or an error - * has occurred. Once either the onSuccess or onFailure callback is called, you should destroy - * the mapconn and stop calling tick(). - */ - -#ifndef IPC_MAPCONN_H_ -#define IPC_MAPCONN_H_ - -#include "../model/map.h" - -#include - -#define MAPIMAGE_WIDTH 256 -#define MAPIMAGE_HEIGHT 128 -#define MAPIMAGE_BYTES (MAPIMAGE_WIDTH/8*MAPIMAGE_HEIGHT) - -typedef struct _flib_mapconn flib_mapconn; - -/** - * Start a new map rendering connection (mapconn). This means a listening socket - * will be started on a random unused port, waiting for a connection from the - * engine process. Once this connection is established, the required information - * will be sent to the engine, and the reply is read. - * - * The map must be a regular, maze or drawn map - for a preview of a named map, - * use the preview images in the map's directory, and for the hog count read the - * map information (e.g. using flib_mapcfg_read). - * - * No NULL parameters allowed, returns NULL on failure. - * Use flib_mapconn_destroy to free the returned object. - */ -flib_mapconn *flib_mapconn_create(const flib_map *mapdesc); - -/** - * Destroy the mapconn object. Passing NULL is allowed and does nothing. - * flib_mapconn_destroy may be called from inside a callback function. - */ -void flib_mapconn_destroy(flib_mapconn *conn); - -/** - * Returns the port on which the mapconn is listening. Only fails if you - * pass NULL (not allowed), in that case 0 is returned. - */ -int flib_mapconn_getport(flib_mapconn *conn); - -/** - * Set a callback which will receive the rendered map if the rendering succeeds. - * - * Expected callback signature: - * void handleSuccess(void *context, const uint8_t *bitmap, int numHedgehogs) - * - * The context passed to the callback is the same pointer you provided when - * registering the callback. bitmap is a pointer to a buffer of size MAPIMAGE_BYTES - * containing a bit-packed image of size MAPIMAGE_WIDTH * MAPIMAGE_HEIGHT. - * numHedgehogs is the number of hogs that fit on this map. - * - * The bitmap pointer passed to the callback belongs to the caller, - * so it should not be stored elsewhere. Note that it remains valid - * inside the callback method even if flib_mapconn_destroy is called. - */ -void flib_mapconn_onSuccess(flib_mapconn *conn, void (*callback)(void* context, const uint8_t *bitmap, int numHedgehogs), void *context); - -/** - * Set a callback which will receive an error message if rendering fails. - * - * Expected callback signature: - * void handleFailure(void *context, const char *errormessage) - * - * The context passed to the callback is the same pointer you provided when - * registering the callback. - * - * The error message passed to the callback belongs to the caller, - * so it should not be stored elsewhere. Note that it remains valid - * inside the callback method even if flib_mapconn_destroy is called. - */ -void flib_mapconn_onFailure(flib_mapconn *conn, void (*callback)(void* context, const char *errormessage), void *context); - -/** - * Perform I/O operations and call callbacks if something interesting happens. - * Should be called regularly. - */ -void flib_mapconn_tick(flib_mapconn *conn); - -#endif +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * Functions for querying a map preview from the engine, which includes both a two-color image + * and the number of hogs this map is suitable for. + * + * The general usage is to first create a mapconn object by calling flib_mapconn_create. + * That will cause the frontlib to listen on a random port which can be queried using + * flib_mapconn_getport(). You should also register your callback functions right at the start + * to ensure you don't miss any callbacks. + * + * Next, start the engine (that part is up to you) with the appropriate command line arguments + * for a map preview request. + * + * In order to allow the mapconn to run, you should regularly call flib_mapconn_tick(), which + * performs network I/O and calls your callbacks if the map has been generated or an error + * has occurred. Once either the onSuccess or onFailure callback is called, you should destroy + * the mapconn and stop calling tick(). + */ + +#ifndef IPC_MAPCONN_H_ +#define IPC_MAPCONN_H_ + +#include "../model/map.h" + +#include + +#define MAPIMAGE_WIDTH 256 +#define MAPIMAGE_HEIGHT 128 +#define MAPIMAGE_BYTES (MAPIMAGE_WIDTH/8*MAPIMAGE_HEIGHT) + +typedef struct _flib_mapconn flib_mapconn; + +/** + * Start a new map rendering connection (mapconn). This means a listening socket + * will be started on a random unused port, waiting for a connection from the + * engine process. Once this connection is established, the required information + * will be sent to the engine, and the reply is read. + * + * The map must be a regular, maze or drawn map - for a preview of a named map, + * use the preview images in the map's directory, and for the hog count read the + * map information (e.g. using flib_mapcfg_read). + * + * No NULL parameters allowed, returns NULL on failure. + * Use flib_mapconn_destroy to free the returned object. + */ +flib_mapconn *flib_mapconn_create(const flib_map *mapdesc); + +/** + * Destroy the mapconn object. Passing NULL is allowed and does nothing. + * flib_mapconn_destroy may be called from inside a callback function. + */ +void flib_mapconn_destroy(flib_mapconn *conn); + +/** + * Returns the port on which the mapconn is listening. Only fails if you + * pass NULL (not allowed), in that case 0 is returned. + */ +int flib_mapconn_getport(flib_mapconn *conn); + +/** + * Set a callback which will receive the rendered map if the rendering succeeds. + * + * Expected callback signature: + * void handleSuccess(void *context, const uint8_t *bitmap, int numHedgehogs) + * + * The context passed to the callback is the same pointer you provided when + * registering the callback. bitmap is a pointer to a buffer of size MAPIMAGE_BYTES + * containing a bit-packed image of size MAPIMAGE_WIDTH * MAPIMAGE_HEIGHT. + * numHedgehogs is the number of hogs that fit on this map. + * + * The bitmap pointer passed to the callback belongs to the caller, + * so it should not be stored elsewhere. Note that it remains valid + * inside the callback method even if flib_mapconn_destroy is called. + */ +void flib_mapconn_onSuccess(flib_mapconn *conn, void (*callback)(void* context, const uint8_t *bitmap, int numHedgehogs), void *context); + +/** + * Set a callback which will receive an error message if rendering fails. + * + * Expected callback signature: + * void handleFailure(void *context, const char *errormessage) + * + * The context passed to the callback is the same pointer you provided when + * registering the callback. + * + * The error message passed to the callback belongs to the caller, + * so it should not be stored elsewhere. Note that it remains valid + * inside the callback method even if flib_mapconn_destroy is called. + */ +void flib_mapconn_onFailure(flib_mapconn *conn, void (*callback)(void* context, const char *errormessage), void *context); + +/** + * Perform I/O operations and call callbacks if something interesting happens. + * Should be called regularly. + */ +void flib_mapconn_tick(flib_mapconn *conn); + +#endif diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/md5/md5.c --- a/project_files/frontlib/md5/md5.c Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/md5/md5.c Tue Jan 21 22:43:06 2014 +0100 @@ -27,7 +27,7 @@ This code implements the MD5 Algorithm defined in RFC 1321, whose text is available at - http://www.ietf.org/rfc/rfc1321.txt + http://www.ietf.org/rfc/rfc1321.txt The code is derived from the text of the RFC, including the test suite (section A.5) but excluding the rest of Appendix A. It does not include any code or documentation that is identified in the RFC as being @@ -38,14 +38,14 @@ that follows (in reverse chronological order): 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order - either statically or dynamically; added missing #include - in library. + either statically or dynamically; added missing #include + in library. 2002-03-11 lpd Corrected argument list for main(), and added int return - type, in test program and T value program. + type, in test program and T value program. 2002-02-21 lpd Added missing #include in test program. 2000-07-03 lpd Patched to eliminate warnings about "constant is - unsigned in ANSI C, signed in traditional"; made test program - self-checking. + unsigned in ANSI C, signed in traditional"; made test program + self-checking. 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). 1999-05-03 lpd Original version. @@ -54,7 +54,7 @@ #include "md5.h" #include -#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */ +#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */ #ifdef ARCH_IS_BIG_ENDIAN # define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1) #else @@ -132,8 +132,8 @@ md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/) { md5_word_t - a = pms->abcd[0], b = pms->abcd[1], - c = pms->abcd[2], d = pms->abcd[3]; + a = pms->abcd[0], b = pms->abcd[1], + c = pms->abcd[2], d = pms->abcd[3]; md5_word_t t; #if BYTE_ORDER > 0 /* Define storage only for big-endian CPUs. */ @@ -146,51 +146,51 @@ { #if BYTE_ORDER == 0 - /* - * Determine dynamically whether this is a big-endian or - * little-endian machine, since we can use a more efficient - * algorithm on the latter. - */ - static const int w = 1; + /* + * Determine dynamically whether this is a big-endian or + * little-endian machine, since we can use a more efficient + * algorithm on the latter. + */ + static const int w = 1; - if (*((const md5_byte_t *)&w)) /* dynamic little-endian */ + if (*((const md5_byte_t *)&w)) /* dynamic little-endian */ #endif -#if BYTE_ORDER <= 0 /* little-endian */ - { - /* - * On little-endian machines, we can process properly aligned - * data without copying it. - */ - if (!((data - (const md5_byte_t *)0) & 3)) { - /* data are properly aligned */ - X = (const md5_word_t *)data; - } else { - /* not aligned */ - memcpy(xbuf, data, 64); - X = xbuf; - } - } +#if BYTE_ORDER <= 0 /* little-endian */ + { + /* + * On little-endian machines, we can process properly aligned + * data without copying it. + */ + if (!((data - (const md5_byte_t *)0) & 3)) { + /* data are properly aligned */ + X = (const md5_word_t *)data; + } else { + /* not aligned */ + memcpy(xbuf, data, 64); + X = xbuf; + } + } #endif #if BYTE_ORDER == 0 - else /* dynamic big-endian */ + else /* dynamic big-endian */ #endif -#if BYTE_ORDER >= 0 /* big-endian */ - { - /* - * On big-endian machines, we must arrange the bytes in the - * right order. - */ - const md5_byte_t *xp = data; - int i; +#if BYTE_ORDER >= 0 /* big-endian */ + { + /* + * On big-endian machines, we must arrange the bytes in the + * right order. + */ + const md5_byte_t *xp = data; + int i; # if BYTE_ORDER == 0 - X = xbuf; /* (dynamic only) */ + X = xbuf; /* (dynamic only) */ # else -# define xbuf X /* (static only) */ +# define xbuf X /* (static only) */ # endif - for (i = 0; i < 16; ++i, xp += 4) - xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); - } + for (i = 0; i < 16; ++i, xp += 4) + xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); + } #endif } @@ -328,54 +328,54 @@ md5_word_t nbits = (md5_word_t)(nbytes << 3); if (nbytes <= 0) - return; + return; /* Update the message length. */ pms->count[1] += nbytes >> 29; pms->count[0] += nbits; if (pms->count[0] < nbits) - pms->count[1]++; + pms->count[1]++; /* Process an initial partial block. */ if (offset) { - int copy = (offset + nbytes > 64 ? 64 - offset : nbytes); + int copy = (offset + nbytes > 64 ? 64 - offset : nbytes); - memcpy(pms->buf + offset, p, copy); - if (offset + copy < 64) - return; - p += copy; - left -= copy; - md5_process(pms, pms->buf); + memcpy(pms->buf + offset, p, copy); + if (offset + copy < 64) + return; + p += copy; + left -= copy; + md5_process(pms, pms->buf); } /* Process full blocks. */ for (; left >= 64; p += 64, left -= 64) - md5_process(pms, p); + md5_process(pms, p); /* Process a final partial block. */ if (left) - memcpy(pms->buf, p, left); + memcpy(pms->buf, p, left); } void md5_finish(md5_state_t *pms, md5_byte_t digest[16]) { static const md5_byte_t pad[64] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; md5_byte_t data[8]; int i; /* Save the length before padding. */ for (i = 0; i < 8; ++i) - data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); + data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); /* Pad to 56 bytes mod 64. */ md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); /* Append the length. */ md5_append(pms, data, 8); for (i = 0; i < 16; ++i) - digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); + digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); } diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/md5/md5.h --- a/project_files/frontlib/md5/md5.h Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/md5/md5.h Tue Jan 21 22:43:06 2014 +0100 @@ -27,7 +27,7 @@ This code implements the MD5 Algorithm defined in RFC 1321, whose text is available at - http://www.ietf.org/rfc/rfc1321.txt + http://www.ietf.org/rfc/rfc1321.txt The code is derived from the text of the RFC, including the test suite (section A.5) but excluding the rest of Appendix A. It does not include any code or documentation that is identified in the RFC as being @@ -38,12 +38,12 @@ that follows (in reverse chronological order): 2002-04-13 lpd Removed support for non-ANSI compilers; removed - references to Ghostscript; clarified derivation from RFC 1321; - now handles byte order either statically or dynamically. + references to Ghostscript; clarified derivation from RFC 1321; + now handles byte order either statically or dynamically. 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5); - added conditionalization for C++ compilation from Martin - Purschke . + added conditionalization for C++ compilation from Martin + Purschke . 1999-05-03 lpd Original version. */ @@ -65,13 +65,13 @@ /*! Define the state of the MD5 Algorithm. */ typedef struct md5_state_s { - md5_word_t count[2]; /*! message length in bits, lsw first */ - md5_word_t abcd[4]; /*! digest buffer */ - md5_byte_t buf[64]; /*! accumulate block */ + md5_word_t count[2]; /*! message length in bits, lsw first */ + md5_word_t abcd[4]; /*! digest buffer */ + md5_byte_t buf[64]; /*! accumulate block */ } md5_state_t; #ifdef __cplusplus -extern "C" +extern "C" { #endif diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/model/gamesetup.c --- a/project_files/frontlib/model/gamesetup.c Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/model/gamesetup.c Tue Jan 21 22:43:06 2014 +0100 @@ -1,55 +1,55 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "gamesetup.h" -#include "../util/util.h" - -#include - -void flib_gamesetup_destroy(flib_gamesetup *gamesetup) { - if(gamesetup) { - free(gamesetup->style); - flib_scheme_destroy(gamesetup->gamescheme); - flib_map_destroy(gamesetup->map); - flib_teamlist_destroy(gamesetup->teamlist); - free(gamesetup); - } -} - -flib_gamesetup *flib_gamesetup_copy(const flib_gamesetup *setup) { - if(!setup) { - return NULL; - } - - flib_gamesetup *result = flib_calloc(1, sizeof(flib_gamesetup)); - if(result) { - result->style = flib_strdupnull(setup->style); - result->gamescheme = flib_scheme_copy(setup->gamescheme); - result->map = flib_map_copy(setup->map); - result->teamlist = flib_teamlist_copy(setup->teamlist); - if((setup->style && !result->style) - || (setup->gamescheme && !result->gamescheme) - || (setup->map && !result->map) - || (setup->teamlist && !result->teamlist)) { - flib_gamesetup_destroy(result); - result = NULL; - } - } - return result; -} +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "gamesetup.h" +#include "../util/util.h" + +#include + +void flib_gamesetup_destroy(flib_gamesetup *gamesetup) { + if(gamesetup) { + free(gamesetup->style); + flib_scheme_destroy(gamesetup->gamescheme); + flib_map_destroy(gamesetup->map); + flib_teamlist_destroy(gamesetup->teamlist); + free(gamesetup); + } +} + +flib_gamesetup *flib_gamesetup_copy(const flib_gamesetup *setup) { + if(!setup) { + return NULL; + } + + flib_gamesetup *result = flib_calloc(1, sizeof(flib_gamesetup)); + if(result) { + result->style = flib_strdupnull(setup->style); + result->gamescheme = flib_scheme_copy(setup->gamescheme); + result->map = flib_map_copy(setup->map); + result->teamlist = flib_teamlist_copy(setup->teamlist); + if((setup->style && !result->style) + || (setup->gamescheme && !result->gamescheme) + || (setup->map && !result->map) + || (setup->teamlist && !result->teamlist)) { + flib_gamesetup_destroy(result); + result = NULL; + } + } + return result; +} diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/model/gamesetup.h --- a/project_files/frontlib/model/gamesetup.h Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/model/gamesetup.h Tue Jan 21 22:43:06 2014 +0100 @@ -1,47 +1,47 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * A complete game configuration that contains all settings the engine needs to start a - * local or networked game. - */ - -#ifndef MODEL_GAMESETUP_H_ -#define MODEL_GAMESETUP_H_ - -#include "scheme.h" -#include "weapon.h" -#include "map.h" -#include "teamlist.h" - -typedef struct { - char *style; //!< e.g. "Capture the Flag" - flib_scheme *gamescheme; - flib_map *map; - flib_teamlist *teamlist; -} flib_gamesetup; - -void flib_gamesetup_destroy(flib_gamesetup *gamesetup); - -/** - * Deep-copy of the flib_gamesetup. - */ -flib_gamesetup *flib_gamesetup_copy(const flib_gamesetup *gamesetup); - -#endif +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * A complete game configuration that contains all settings the engine needs to start a + * local or networked game. + */ + +#ifndef MODEL_GAMESETUP_H_ +#define MODEL_GAMESETUP_H_ + +#include "scheme.h" +#include "weapon.h" +#include "map.h" +#include "teamlist.h" + +typedef struct { + char *style; //!< e.g. "Capture the Flag" + flib_scheme *gamescheme; + flib_map *map; + flib_teamlist *teamlist; +} flib_gamesetup; + +void flib_gamesetup_destroy(flib_gamesetup *gamesetup); + +/** + * Deep-copy of the flib_gamesetup. + */ +flib_gamesetup *flib_gamesetup_copy(const flib_gamesetup *gamesetup); + +#endif diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/model/map.c --- a/project_files/frontlib/model/map.c Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/model/map.c Tue Jan 21 22:43:06 2014 +0100 @@ -1,110 +1,110 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "map.h" - -#include "../util/inihelper.h" -#include "../util/util.h" -#include "../util/logging.h" - -#include - -flib_map *flib_map_create_regular(const char *seed, const char *theme, int templateFilter) { - if(log_badargs_if2(seed==NULL, theme==NULL)) { - return NULL; - } - flib_map newmap = {0}; - newmap.mapgen = MAPGEN_REGULAR; - newmap.name = "+rnd+"; - newmap.seed = (char*)seed; - newmap.theme = (char*)theme; - newmap.templateFilter = templateFilter; - return flib_map_copy(&newmap); -} - -flib_map *flib_map_create_maze(const char *seed, const char *theme, int mazeSize) { - if(log_badargs_if2(seed==NULL, theme==NULL)) { - return NULL; - } - flib_map newmap = {0}; - newmap.mapgen = MAPGEN_MAZE; - newmap.name = "+maze+"; - newmap.seed = (char*)seed; - newmap.theme = (char*)theme; - newmap.mazeSize = mazeSize; - return flib_map_copy(&newmap); -} - -flib_map *flib_map_create_named(const char *seed, const char *name) { - if(log_badargs_if2(seed==NULL, name==NULL)) { - return NULL; - } - flib_map newmap = {0}; - newmap.mapgen = MAPGEN_NAMED; - newmap.name = (char*)name; - newmap.seed = (char*)seed; - return flib_map_copy(&newmap); -} - -flib_map *flib_map_create_drawn(const char *seed, const char *theme, const uint8_t *drawData, size_t drawDataSize) { - if(log_badargs_if3(seed==NULL, theme==NULL, drawData==NULL)) { - return NULL; - } - flib_map newmap = {0}; - newmap.mapgen = MAPGEN_DRAWN; - newmap.name = "+drawn+"; - newmap.seed = (char*)seed; - newmap.theme = (char*)theme; - newmap.drawData = (uint8_t*) drawData; - newmap.drawDataSize = drawDataSize; - return flib_map_copy(&newmap); -} - -flib_map *flib_map_copy(const flib_map *map) { - flib_map *result = NULL; - if(map) { - flib_map *newmap = flib_calloc(1, sizeof(flib_map)); - if(newmap) { - newmap->mapgen = map->mapgen; - newmap->drawDataSize = map->drawDataSize; - newmap->drawData = flib_bufdupnull(map->drawData, map->drawDataSize); - newmap->mazeSize = map->mazeSize; - newmap->name = flib_strdupnull(map->name); - newmap->seed = flib_strdupnull(map->seed); - newmap->templateFilter = map->templateFilter; - newmap->theme = flib_strdupnull(map->theme); - if((newmap->drawData || !map->drawData) && (newmap->name || !map->name) && (newmap->seed || !map->seed) && (newmap->theme || !map->theme)) { - result = newmap; - newmap = NULL; - } - } - flib_map_destroy(newmap); - } - return result; -} - -void flib_map_destroy(flib_map *map) { - if(map) { - free(map->seed); - free(map->drawData); - free(map->name); - free(map->theme); - free(map); - } -} +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "map.h" + +#include "../util/inihelper.h" +#include "../util/util.h" +#include "../util/logging.h" + +#include + +flib_map *flib_map_create_regular(const char *seed, const char *theme, int templateFilter) { + if(log_badargs_if2(seed==NULL, theme==NULL)) { + return NULL; + } + flib_map newmap = {0}; + newmap.mapgen = MAPGEN_REGULAR; + newmap.name = "+rnd+"; + newmap.seed = (char*)seed; + newmap.theme = (char*)theme; + newmap.templateFilter = templateFilter; + return flib_map_copy(&newmap); +} + +flib_map *flib_map_create_maze(const char *seed, const char *theme, int mazeSize) { + if(log_badargs_if2(seed==NULL, theme==NULL)) { + return NULL; + } + flib_map newmap = {0}; + newmap.mapgen = MAPGEN_MAZE; + newmap.name = "+maze+"; + newmap.seed = (char*)seed; + newmap.theme = (char*)theme; + newmap.mazeSize = mazeSize; + return flib_map_copy(&newmap); +} + +flib_map *flib_map_create_named(const char *seed, const char *name) { + if(log_badargs_if2(seed==NULL, name==NULL)) { + return NULL; + } + flib_map newmap = {0}; + newmap.mapgen = MAPGEN_NAMED; + newmap.name = (char*)name; + newmap.seed = (char*)seed; + return flib_map_copy(&newmap); +} + +flib_map *flib_map_create_drawn(const char *seed, const char *theme, const uint8_t *drawData, size_t drawDataSize) { + if(log_badargs_if3(seed==NULL, theme==NULL, drawData==NULL)) { + return NULL; + } + flib_map newmap = {0}; + newmap.mapgen = MAPGEN_DRAWN; + newmap.name = "+drawn+"; + newmap.seed = (char*)seed; + newmap.theme = (char*)theme; + newmap.drawData = (uint8_t*) drawData; + newmap.drawDataSize = drawDataSize; + return flib_map_copy(&newmap); +} + +flib_map *flib_map_copy(const flib_map *map) { + flib_map *result = NULL; + if(map) { + flib_map *newmap = flib_calloc(1, sizeof(flib_map)); + if(newmap) { + newmap->mapgen = map->mapgen; + newmap->drawDataSize = map->drawDataSize; + newmap->drawData = flib_bufdupnull(map->drawData, map->drawDataSize); + newmap->mazeSize = map->mazeSize; + newmap->name = flib_strdupnull(map->name); + newmap->seed = flib_strdupnull(map->seed); + newmap->templateFilter = map->templateFilter; + newmap->theme = flib_strdupnull(map->theme); + if((newmap->drawData || !map->drawData) && (newmap->name || !map->name) && (newmap->seed || !map->seed) && (newmap->theme || !map->theme)) { + result = newmap; + newmap = NULL; + } + } + flib_map_destroy(newmap); + } + return result; +} + +void flib_map_destroy(flib_map *map) { + if(map) { + free(map->seed); + free(map->drawData); + free(map->name); + free(map->theme); + free(map); + } +} diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/model/map.h --- a/project_files/frontlib/model/map.h Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/model/map.h Tue Jan 21 22:43:06 2014 +0100 @@ -1,114 +1,114 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef MODEL_MAP_H_ -#define MODEL_MAP_H_ - -#include -#include -#include - -#define MAPGEN_REGULAR 0 -#define MAPGEN_MAZE 1 -#define MAPGEN_DRAWN 2 -#define MAPGEN_NAMED 3 - -#define TEMPLATEFILTER_ALL 0 -#define TEMPLATEFILTER_SMALL 1 -#define TEMPLATEFILTER_MEDIUM 2 -#define TEMPLATEFILTER_LARGE 3 -#define TEMPLATEFILTER_CAVERN 4 -#define TEMPLATEFILTER_WACKY 5 - -#define MAZE_SIZE_SMALL_TUNNELS 0 -#define MAZE_SIZE_MEDIUM_TUNNELS 1 -#define MAZE_SIZE_LARGE_TUNNELS 2 -#define MAZE_SIZE_SMALL_ISLANDS 3 -#define MAZE_SIZE_MEDIUM_ISLANDS 4 -#define MAZE_SIZE_LARGE_ISLANDS 5 - -/** - * Data structure for defining a map. This contains the whole recipe to - * exactly recreate a particular map. - * - * The required fields depend on the map generator, see the comments - * at the struct for details. - */ -typedef struct { - int mapgen; //!< Always one of the MAPGEN_ constants - char *name; //!< The name of the map for MAPGEN_NAMED (e.g. "Cogs"), otherwise one of "+rnd+", "+maze+" or "+drawn+". - char *seed; //!< Used for all maps. This is a random seed for all (non-AI) entropy in the round. Typically a random UUID, but can be any string. - char *theme; //!< Used for all maps. This is the name of a directory in Data/Themes (e.g. "Beach") - uint8_t *drawData; //!< Used for MAPGEN_DRAWN - size_t drawDataSize; //!< Used for MAPGEN_DRAWN - int templateFilter; //!< Used for MAPGEN_REGULAR. One of the TEMPLATEFILTER_xxx constants. - int mazeSize; //!< Used for MAPGEN_MAZE. One of the MAZE_SIZE_xxx constants. -} flib_map; - -/** - * Create a generated map. theme should be the name of a - * directory in "Themes" and templateFilter should be one of the - * TEMPLATEFILTER_* constants, but this is not checked before - * passing it to the engine. - * - * Use flib_map_destroy to free the returned object. - * No NULL parameters allowed, returns NULL on failure. - */ -flib_map *flib_map_create_regular(const char *seed, const char *theme, int templateFilter); - -/** - * Create a generated maze-type map. theme should be the name of a - * directory in "Themes" and mazeSize should be one of the - * MAZE_SIZE_* constants, but this is not checked before - * passing it to the engine. - * - * Use flib_map_destroy to free the returned object. - * No NULL parameters allowed, returns NULL on failure. - */ -flib_map *flib_map_create_maze(const char *seed, const char *theme, int mazeSize); - -/** - * Create a map from the Maps-Directory. name should be the name of a - * directory in "Maps", but this is not checked before - * passing it to the engine. If this is a mission, the corresponding - * script is used automatically. - * - * Use flib_map_destroy to free the returned object. - * No NULL parameters allowed, returns NULL on failure. - */ -flib_map *flib_map_create_named(const char *seed, const char *name); - -/** - * Create a hand-drawn map. Use flib_map_destroy to free the returned object. - * No NULL parameters allowed, returns NULL on failure. - */ -flib_map *flib_map_create_drawn(const char *seed, const char *theme, const uint8_t *drawData, size_t drawDataSize); - -/** - * Create a deep copy of the map. Returns NULL on failure or if NULL was passed. - */ -flib_map *flib_map_copy(const flib_map *map); - -/** - * Decrease the reference count of the object and free it if this was the last reference. - */ -void flib_map_destroy(flib_map *map); - - -#endif +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef MODEL_MAP_H_ +#define MODEL_MAP_H_ + +#include +#include +#include + +#define MAPGEN_REGULAR 0 +#define MAPGEN_MAZE 1 +#define MAPGEN_DRAWN 2 +#define MAPGEN_NAMED 3 + +#define TEMPLATEFILTER_ALL 0 +#define TEMPLATEFILTER_SMALL 1 +#define TEMPLATEFILTER_MEDIUM 2 +#define TEMPLATEFILTER_LARGE 3 +#define TEMPLATEFILTER_CAVERN 4 +#define TEMPLATEFILTER_WACKY 5 + +#define MAZE_SIZE_SMALL_TUNNELS 0 +#define MAZE_SIZE_MEDIUM_TUNNELS 1 +#define MAZE_SIZE_LARGE_TUNNELS 2 +#define MAZE_SIZE_SMALL_ISLANDS 3 +#define MAZE_SIZE_MEDIUM_ISLANDS 4 +#define MAZE_SIZE_LARGE_ISLANDS 5 + +/** + * Data structure for defining a map. This contains the whole recipe to + * exactly recreate a particular map. + * + * The required fields depend on the map generator, see the comments + * at the struct for details. + */ +typedef struct { + int mapgen; //!< Always one of the MAPGEN_ constants + char *name; //!< The name of the map for MAPGEN_NAMED (e.g. "Cogs"), otherwise one of "+rnd+", "+maze+" or "+drawn+". + char *seed; //!< Used for all maps. This is a random seed for all (non-AI) entropy in the round. Typically a random UUID, but can be any string. + char *theme; //!< Used for all maps. This is the name of a directory in Data/Themes (e.g. "Beach") + uint8_t *drawData; //!< Used for MAPGEN_DRAWN + size_t drawDataSize; //!< Used for MAPGEN_DRAWN + int templateFilter; //!< Used for MAPGEN_REGULAR. One of the TEMPLATEFILTER_xxx constants. + int mazeSize; //!< Used for MAPGEN_MAZE. One of the MAZE_SIZE_xxx constants. +} flib_map; + +/** + * Create a generated map. theme should be the name of a + * directory in "Themes" and templateFilter should be one of the + * TEMPLATEFILTER_* constants, but this is not checked before + * passing it to the engine. + * + * Use flib_map_destroy to free the returned object. + * No NULL parameters allowed, returns NULL on failure. + */ +flib_map *flib_map_create_regular(const char *seed, const char *theme, int templateFilter); + +/** + * Create a generated maze-type map. theme should be the name of a + * directory in "Themes" and mazeSize should be one of the + * MAZE_SIZE_* constants, but this is not checked before + * passing it to the engine. + * + * Use flib_map_destroy to free the returned object. + * No NULL parameters allowed, returns NULL on failure. + */ +flib_map *flib_map_create_maze(const char *seed, const char *theme, int mazeSize); + +/** + * Create a map from the Maps-Directory. name should be the name of a + * directory in "Maps", but this is not checked before + * passing it to the engine. If this is a mission, the corresponding + * script is used automatically. + * + * Use flib_map_destroy to free the returned object. + * No NULL parameters allowed, returns NULL on failure. + */ +flib_map *flib_map_create_named(const char *seed, const char *name); + +/** + * Create a hand-drawn map. Use flib_map_destroy to free the returned object. + * No NULL parameters allowed, returns NULL on failure. + */ +flib_map *flib_map_create_drawn(const char *seed, const char *theme, const uint8_t *drawData, size_t drawDataSize); + +/** + * Create a deep copy of the map. Returns NULL on failure or if NULL was passed. + */ +flib_map *flib_map_copy(const flib_map *map); + +/** + * Decrease the reference count of the object and free it if this was the last reference. + */ +void flib_map_destroy(flib_map *map); + + +#endif diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/model/mapcfg.c --- a/project_files/frontlib/model/mapcfg.c Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/model/mapcfg.c Tue Jan 21 22:43:06 2014 +0100 @@ -1,64 +1,64 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "mapcfg.h" - -#include "../util/util.h" -#include "../util/logging.h" - -#include -#include -#include -#include - -void removeNewline(char *str) { - for(;*str;str++) { - if(*str=='\n' || *str=='\r') { - *str = 0; - return; - } - } -} - -int flib_mapcfg_read(const char *dataDirPath, const char *mapname, flib_mapcfg *out) { - int result = -1; - if(!log_badargs_if4(dataDirPath==NULL, mapname==NULL, out==NULL, flib_contains_dir_separator(mapname))) { - char *path = flib_asprintf("%sMaps/%s/map.cfg", dataDirPath, mapname); - if(path) { - FILE *file = fopen(path, "rb"); - if(!log_e_if(!file, "Unable to open map config file %s", path)) { - if(!log_e_if(!fgets(out->theme, sizeof(out->theme), file), "Error reading theme from %s", path)) { - removeNewline(out->theme); - char buf[64]; - if(fgets(buf, sizeof(buf), file)) { - removeNewline(buf); - errno = 0; - out->hogLimit = strtol(buf, NULL, 10); - result = !log_e_if(errno, "Invalid hoglimit in %s: %i", path, buf); - } else { - result = 0; - } - } - fclose(file); - } - } - free(path); - } - return result; -} +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mapcfg.h" + +#include "../util/util.h" +#include "../util/logging.h" + +#include +#include +#include +#include + +void removeNewline(char *str) { + for(;*str;str++) { + if(*str=='\n' || *str=='\r') { + *str = 0; + return; + } + } +} + +int flib_mapcfg_read(const char *dataDirPath, const char *mapname, flib_mapcfg *out) { + int result = -1; + if(!log_badargs_if4(dataDirPath==NULL, mapname==NULL, out==NULL, flib_contains_dir_separator(mapname))) { + char *path = flib_asprintf("%sMaps/%s/map.cfg", dataDirPath, mapname); + if(path) { + FILE *file = fopen(path, "rb"); + if(!log_e_if(!file, "Unable to open map config file %s", path)) { + if(!log_e_if(!fgets(out->theme, sizeof(out->theme), file), "Error reading theme from %s", path)) { + removeNewline(out->theme); + char buf[64]; + if(fgets(buf, sizeof(buf), file)) { + removeNewline(buf); + errno = 0; + out->hogLimit = strtol(buf, NULL, 10); + result = !log_e_if(errno, "Invalid hoglimit in %s: %i", path, buf); + } else { + result = 0; + } + } + fclose(file); + } + } + free(path); + } + return result; +} diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/model/mapcfg.h --- a/project_files/frontlib/model/mapcfg.h Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/model/mapcfg.h Tue Jan 21 22:43:06 2014 +0100 @@ -1,38 +1,38 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/*! - * Data structure and functions for accessing the map.cfg of named maps. - */ - -#ifndef MAPCFG_H_ -#define MAPCFG_H_ - -typedef struct { - char theme[256]; - int hogLimit; -} flib_mapcfg; - -/** - * Read the map configuration for the map with this name. - * The dataDirPath must end in a path separator. - */ -int flib_mapcfg_read(const char *dataDirPath, const char *mapname, flib_mapcfg *out); - -#endif /* MAPCFG_H_ */ +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/*! + * Data structure and functions for accessing the map.cfg of named maps. + */ + +#ifndef MAPCFG_H_ +#define MAPCFG_H_ + +typedef struct { + char theme[256]; + int hogLimit; +} flib_mapcfg; + +/** + * Read the map configuration for the map with this name. + * The dataDirPath must end in a path separator. + */ +int flib_mapcfg_read(const char *dataDirPath, const char *mapname, flib_mapcfg *out); + +#endif /* MAPCFG_H_ */ diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/model/room.c --- a/project_files/frontlib/model/room.c Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/model/room.c Tue Jan 21 22:43:06 2014 +0100 @@ -1,34 +1,34 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "room.h" -#include "../util/logging.h" - -#include - -void flib_room_destroy(flib_room *room) { - if(room) { - free(room->map); - free(room->name); - free(room->owner); - free(room->scheme); - free(room->weapons); - free(room); - } -} +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "room.h" +#include "../util/logging.h" + +#include + +void flib_room_destroy(flib_room *room) { + if(room) { + free(room->map); + free(room->name); + free(room->owner); + free(room->scheme); + free(room->weapons); + free(room); + } +} diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/model/room.h --- a/project_files/frontlib/model/room.h Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/model/room.h Tue Jan 21 22:43:06 2014 +0100 @@ -1,42 +1,42 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * Models the room information for the lobby roomlist. - */ - -#ifndef ROOM_H_ -#define ROOM_H_ - -#include - -typedef struct { - bool inProgress; //!< true if the game is running - char *name; - int playerCount; - int teamCount; - char *owner; - char *map; //!< This is either a map name, or one of +rnd+, +maze+ or +drawn+. - char *scheme; - char *weapons; -} flib_room; - -void flib_room_destroy(); - -#endif +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * Models the room information for the lobby roomlist. + */ + +#ifndef ROOM_H_ +#define ROOM_H_ + +#include + +typedef struct { + bool inProgress; //!< true if the game is running + char *name; + int playerCount; + int teamCount; + char *owner; + char *map; //!< This is either a map name, or one of +rnd+, +maze+ or +drawn+. + char *scheme; + char *weapons; +} flib_room; + +void flib_room_destroy(); + +#endif diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/model/scheme.c --- a/project_files/frontlib/model/scheme.c Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/model/scheme.c Tue Jan 21 22:43:06 2014 +0100 @@ -1,95 +1,95 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "scheme.h" - -#include "../util/inihelper.h" -#include "../util/logging.h" -#include "../util/util.h" - -#include -#include -#include -#include - -flib_scheme *flib_scheme_create(const char *schemeName) { - flib_scheme *result = flib_calloc(1, sizeof(flib_scheme)); - if(log_badargs_if(schemeName==NULL) || result==NULL) { - return NULL; - } - - result->name = flib_strdupnull(schemeName); - result->mods = flib_calloc(flib_meta.modCount, sizeof(*result->mods)); - result->settings = flib_calloc(flib_meta.settingCount, sizeof(*result->settings)); - - if(!result->mods || !result->settings || !result->name) { - flib_scheme_destroy(result); - return NULL; - } - - for(int i=0; isettings[i] = flib_meta.settings[i].def; - } - return result; -} - -flib_scheme *flib_scheme_copy(const flib_scheme *scheme) { - flib_scheme *result = NULL; - if(scheme) { - result = flib_scheme_create(scheme->name); - if(result) { - memcpy(result->mods, scheme->mods, flib_meta.modCount * sizeof(*scheme->mods)); - memcpy(result->settings, scheme->settings, flib_meta.settingCount * sizeof(*scheme->settings)); - } - } - return result; -} - -void flib_scheme_destroy(flib_scheme* scheme) { - if(scheme) { - free(scheme->mods); - free(scheme->settings); - free(scheme->name); - free(scheme); - } -} - -bool flib_scheme_get_mod(const flib_scheme *scheme, const char *name) { - if(!log_badargs_if2(scheme==NULL, name==NULL)) { - for(int i=0; imods[i]; - } - } - flib_log_e("Unable to find game mod %s", name); - } - return false; -} - -int flib_scheme_get_setting(const flib_scheme *scheme, const char *name, int def) { - if(!log_badargs_if2(scheme==NULL, name==NULL)) { - for(int i=0; isettings[i]; - } - } - flib_log_e("Unable to find game setting %s", name); - } - return def; -} +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "scheme.h" + +#include "../util/inihelper.h" +#include "../util/logging.h" +#include "../util/util.h" + +#include +#include +#include +#include + +flib_scheme *flib_scheme_create(const char *schemeName) { + flib_scheme *result = flib_calloc(1, sizeof(flib_scheme)); + if(log_badargs_if(schemeName==NULL) || result==NULL) { + return NULL; + } + + result->name = flib_strdupnull(schemeName); + result->mods = flib_calloc(flib_meta.modCount, sizeof(*result->mods)); + result->settings = flib_calloc(flib_meta.settingCount, sizeof(*result->settings)); + + if(!result->mods || !result->settings || !result->name) { + flib_scheme_destroy(result); + return NULL; + } + + for(int i=0; isettings[i] = flib_meta.settings[i].def; + } + return result; +} + +flib_scheme *flib_scheme_copy(const flib_scheme *scheme) { + flib_scheme *result = NULL; + if(scheme) { + result = flib_scheme_create(scheme->name); + if(result) { + memcpy(result->mods, scheme->mods, flib_meta.modCount * sizeof(*scheme->mods)); + memcpy(result->settings, scheme->settings, flib_meta.settingCount * sizeof(*scheme->settings)); + } + } + return result; +} + +void flib_scheme_destroy(flib_scheme* scheme) { + if(scheme) { + free(scheme->mods); + free(scheme->settings); + free(scheme->name); + free(scheme); + } +} + +bool flib_scheme_get_mod(const flib_scheme *scheme, const char *name) { + if(!log_badargs_if2(scheme==NULL, name==NULL)) { + for(int i=0; imods[i]; + } + } + flib_log_e("Unable to find game mod %s", name); + } + return false; +} + +int flib_scheme_get_setting(const flib_scheme *scheme, const char *name, int def) { + if(!log_badargs_if2(scheme==NULL, name==NULL)) { + for(int i=0; isettings[i]; + } + } + flib_log_e("Unable to find game setting %s", name); + } + return def; +} diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/model/scheme.h --- a/project_files/frontlib/model/scheme.h Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/model/scheme.h Tue Jan 21 22:43:06 2014 +0100 @@ -1,72 +1,72 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * Data structures for game scheme information. - * - * The scheme consists of settings (integers) and mods (booleans). These are not fixed, but - * described in a "metascheme", which describes how each setting and mod is sent to the - * engine, and in which order they appear in the network protocol. The metascheme is defined - * in hwconsts.h - */ - -#ifndef SCHEME_H_ -#define SCHEME_H_ - -#include -#include -#include "../hwconsts.h" - -/** - * The settings and mods arrays have the same number and order of elements - * as the corresponding arrays in the metascheme. - */ -typedef struct { - char *name; - int *settings; - bool *mods; -} flib_scheme; - -/** - * Create a new configuration with everything set to default or false - * Returns NULL on error. - */ -flib_scheme *flib_scheme_create(const char *schemeName); - -/** - * Create a copy of the scheme. Returns NULL on error or if NULL was passed. - */ -flib_scheme *flib_scheme_copy(const flib_scheme *scheme); - -/** - * Decrease the reference count of the object and free it if this was the last reference. - */ -void flib_scheme_destroy(flib_scheme* scheme); - -/** - * Retrieve a mod setting by its name. If the mod is not found, logs an error and returns false. - */ -bool flib_scheme_get_mod(const flib_scheme *scheme, const char *name); - -/** - * Retrieve a game setting by its name. If the setting is not found, logs an error and returns def. - */ -int flib_scheme_get_setting(const flib_scheme *scheme, const char *name, int def); - -#endif /* SCHEME_H_ */ +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * Data structures for game scheme information. + * + * The scheme consists of settings (integers) and mods (booleans). These are not fixed, but + * described in a "metascheme", which describes how each setting and mod is sent to the + * engine, and in which order they appear in the network protocol. The metascheme is defined + * in hwconsts.h + */ + +#ifndef SCHEME_H_ +#define SCHEME_H_ + +#include +#include +#include "../hwconsts.h" + +/** + * The settings and mods arrays have the same number and order of elements + * as the corresponding arrays in the metascheme. + */ +typedef struct { + char *name; + int *settings; + bool *mods; +} flib_scheme; + +/** + * Create a new configuration with everything set to default or false + * Returns NULL on error. + */ +flib_scheme *flib_scheme_create(const char *schemeName); + +/** + * Create a copy of the scheme. Returns NULL on error or if NULL was passed. + */ +flib_scheme *flib_scheme_copy(const flib_scheme *scheme); + +/** + * Decrease the reference count of the object and free it if this was the last reference. + */ +void flib_scheme_destroy(flib_scheme* scheme); + +/** + * Retrieve a mod setting by its name. If the mod is not found, logs an error and returns false. + */ +bool flib_scheme_get_mod(const flib_scheme *scheme, const char *name); + +/** + * Retrieve a game setting by its name. If the setting is not found, logs an error and returns def. + */ +int flib_scheme_get_setting(const flib_scheme *scheme, const char *name, int def); + +#endif /* SCHEME_H_ */ diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/model/schemelist.c --- a/project_files/frontlib/model/schemelist.c Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/model/schemelist.c Tue Jan 21 22:43:06 2014 +0100 @@ -1,216 +1,216 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "schemelist.h" - -#include "../util/inihelper.h" -#include "../util/logging.h" -#include "../util/util.h" -#include "../util/list.h" - -#include -#include -#include -#include - -static char *makePrefixedName(int schemeIndex, const char *settingName) { - return flib_asprintf("%i\\%s", schemeIndex, settingName); -} - -static int readSettingsFromIni(flib_ini *ini, flib_scheme *scheme, int index) { - bool error = false; - for(int i=0; isettings[i], key, flib_meta.settings[i].def)) { - flib_log_e("Error reading setting %s in schemes file.", key); - error = true; - } - free(key); - } - return error; -} - -static int readModsFromIni(flib_ini *ini, flib_scheme *scheme, int index) { - bool error = false; - for(int i=0; imods[i], key, false)) { - flib_log_e("Error reading mod %s in schemes file.", key); - error = true; - } - free(key); - } - return error; -} - -static flib_scheme *readSchemeFromIni(flib_ini *ini, int index) { - flib_scheme *result = NULL; - char *schemeNameKey = makePrefixedName(index+1, "name"); - if(schemeNameKey) { - char *schemeName = NULL; - if(!flib_ini_get_str_opt(ini, &schemeName, schemeNameKey, "Unnamed")) { - flib_scheme *tmpScheme = flib_scheme_create(schemeName); - if(tmpScheme) { - if(!readSettingsFromIni(ini, tmpScheme, index) && !readModsFromIni(ini, tmpScheme, index)) { - result = tmpScheme; - tmpScheme = NULL; - } - } - flib_scheme_destroy(tmpScheme); - } - free(schemeName); - } - free(schemeNameKey); - return result; -} - -static flib_schemelist *fromIniHandleError(flib_schemelist *result, flib_ini *ini) { - flib_ini_destroy(ini); - flib_schemelist_destroy(result); - return NULL; -} - -flib_schemelist *flib_schemelist_from_ini(const char *filename) { - if(log_badargs_if(filename==NULL)) { - return NULL; - } - - flib_schemelist *list = NULL; - flib_ini *ini = flib_ini_load(filename); - if(!ini || flib_ini_enter_section(ini, "schemes")) { - flib_log_e("Missing file or missing section \"schemes\" in file %s.", filename); - return fromIniHandleError(list, ini); - } - - list = flib_schemelist_create(); - if(!list) { - return fromIniHandleError(list, ini); - } - - int schemeCount = 0; - if(flib_ini_get_int(ini, &schemeCount, "size")) { - flib_log_e("Missing or malformed scheme count in config file %s.", filename); - return fromIniHandleError(list, ini); - } - - for(int i=0; iname); - free(key); - - for(int i=0; imods[i]); - free(key); - } - - for(int i=0; isettings[i]); - free(key); - } - return error; -} - -int flib_schemelist_to_ini(const char *filename, const flib_schemelist *schemes) { - int result = -1; - if(!log_badargs_if2(filename==NULL, schemes==NULL)) { - flib_ini *ini = flib_ini_create(NULL); - if(ini && !flib_ini_create_section(ini, "schemes")) { - bool error = false; - error |= flib_ini_set_int(ini, "size", schemes->schemeCount); - for(int i=0; ischemeCount && !error; i++) { - error |= writeSchemeToIni(schemes->schemes[i], ini, i); - } - - if(!error) { - result = flib_ini_save(ini, filename); - } - } - flib_ini_destroy(ini); - } - return result; -} - -flib_schemelist *flib_schemelist_create() { - return flib_calloc(1, sizeof(flib_schemelist)); -} - -void flib_schemelist_destroy(flib_schemelist *list) { - if(list) { - for(int i=0; ischemeCount; i++) { - flib_scheme_destroy(list->schemes[i]); - } - free(list->schemes); - free(list); - } -} - -flib_scheme *flib_schemelist_find(flib_schemelist *list, const char *name) { - if(!log_badargs_if2(list==NULL, name==NULL)) { - for(int i=0; ischemeCount; i++) { - if(!strcmp(name, list->schemes[i]->name)) { - return list->schemes[i]; - } - } - } - return NULL; -} - -GENERATE_STATIC_LIST_INSERT(insertScheme, flib_scheme*) -GENERATE_STATIC_LIST_DELETE(deleteScheme, flib_scheme*) - -int flib_schemelist_insert(flib_schemelist *list, flib_scheme *cfg, int pos) { - if(!log_badargs_if2(list==NULL, cfg==NULL) - && !insertScheme(&list->schemes, &list->schemeCount, cfg, pos)) { - return 0; - } - return -1; -} - -int flib_schemelist_delete(flib_schemelist *list, int pos) { - if(!log_badargs_if(list==NULL)) { - flib_scheme *elem = list->schemes[pos]; - if(!deleteScheme(&list->schemes, &list->schemeCount, pos)) { - flib_scheme_destroy(elem); - return 0; - } - } - return -1; -} +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "schemelist.h" + +#include "../util/inihelper.h" +#include "../util/logging.h" +#include "../util/util.h" +#include "../util/list.h" + +#include +#include +#include +#include + +static char *makePrefixedName(int schemeIndex, const char *settingName) { + return flib_asprintf("%i\\%s", schemeIndex, settingName); +} + +static int readSettingsFromIni(flib_ini *ini, flib_scheme *scheme, int index) { + bool error = false; + for(int i=0; isettings[i], key, flib_meta.settings[i].def)) { + flib_log_e("Error reading setting %s in schemes file.", key); + error = true; + } + free(key); + } + return error; +} + +static int readModsFromIni(flib_ini *ini, flib_scheme *scheme, int index) { + bool error = false; + for(int i=0; imods[i], key, false)) { + flib_log_e("Error reading mod %s in schemes file.", key); + error = true; + } + free(key); + } + return error; +} + +static flib_scheme *readSchemeFromIni(flib_ini *ini, int index) { + flib_scheme *result = NULL; + char *schemeNameKey = makePrefixedName(index+1, "name"); + if(schemeNameKey) { + char *schemeName = NULL; + if(!flib_ini_get_str_opt(ini, &schemeName, schemeNameKey, "Unnamed")) { + flib_scheme *tmpScheme = flib_scheme_create(schemeName); + if(tmpScheme) { + if(!readSettingsFromIni(ini, tmpScheme, index) && !readModsFromIni(ini, tmpScheme, index)) { + result = tmpScheme; + tmpScheme = NULL; + } + } + flib_scheme_destroy(tmpScheme); + } + free(schemeName); + } + free(schemeNameKey); + return result; +} + +static flib_schemelist *fromIniHandleError(flib_schemelist *result, flib_ini *ini) { + flib_ini_destroy(ini); + flib_schemelist_destroy(result); + return NULL; +} + +flib_schemelist *flib_schemelist_from_ini(const char *filename) { + if(log_badargs_if(filename==NULL)) { + return NULL; + } + + flib_schemelist *list = NULL; + flib_ini *ini = flib_ini_load(filename); + if(!ini || flib_ini_enter_section(ini, "schemes")) { + flib_log_e("Missing file or missing section \"schemes\" in file %s.", filename); + return fromIniHandleError(list, ini); + } + + list = flib_schemelist_create(); + if(!list) { + return fromIniHandleError(list, ini); + } + + int schemeCount = 0; + if(flib_ini_get_int(ini, &schemeCount, "size")) { + flib_log_e("Missing or malformed scheme count in config file %s.", filename); + return fromIniHandleError(list, ini); + } + + for(int i=0; iname); + free(key); + + for(int i=0; imods[i]); + free(key); + } + + for(int i=0; isettings[i]); + free(key); + } + return error; +} + +int flib_schemelist_to_ini(const char *filename, const flib_schemelist *schemes) { + int result = -1; + if(!log_badargs_if2(filename==NULL, schemes==NULL)) { + flib_ini *ini = flib_ini_create(NULL); + if(ini && !flib_ini_create_section(ini, "schemes")) { + bool error = false; + error |= flib_ini_set_int(ini, "size", schemes->schemeCount); + for(int i=0; ischemeCount && !error; i++) { + error |= writeSchemeToIni(schemes->schemes[i], ini, i); + } + + if(!error) { + result = flib_ini_save(ini, filename); + } + } + flib_ini_destroy(ini); + } + return result; +} + +flib_schemelist *flib_schemelist_create() { + return flib_calloc(1, sizeof(flib_schemelist)); +} + +void flib_schemelist_destroy(flib_schemelist *list) { + if(list) { + for(int i=0; ischemeCount; i++) { + flib_scheme_destroy(list->schemes[i]); + } + free(list->schemes); + free(list); + } +} + +flib_scheme *flib_schemelist_find(flib_schemelist *list, const char *name) { + if(!log_badargs_if2(list==NULL, name==NULL)) { + for(int i=0; ischemeCount; i++) { + if(!strcmp(name, list->schemes[i]->name)) { + return list->schemes[i]; + } + } + } + return NULL; +} + +GENERATE_STATIC_LIST_INSERT(insertScheme, flib_scheme*) +GENERATE_STATIC_LIST_DELETE(deleteScheme, flib_scheme*) + +int flib_schemelist_insert(flib_schemelist *list, flib_scheme *cfg, int pos) { + if(!log_badargs_if2(list==NULL, cfg==NULL) + && !insertScheme(&list->schemes, &list->schemeCount, cfg, pos)) { + return 0; + } + return -1; +} + +int flib_schemelist_delete(flib_schemelist *list, int pos) { + if(!log_badargs_if(list==NULL)) { + flib_scheme *elem = list->schemes[pos]; + if(!deleteScheme(&list->schemes, &list->schemeCount, pos)) { + flib_scheme_destroy(elem); + return 0; + } + } + return -1; +} diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/model/schemelist.h --- a/project_files/frontlib/model/schemelist.h Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/model/schemelist.h Tue Jan 21 22:43:06 2014 +0100 @@ -1,79 +1,79 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * Functions for managing a list of schemes. - * This is in here because the scheme config file of the QtFrontend (which we are staying compatible with) contains - * all the schemes at once, so we need functions to work with a list like that. - */ - -#ifndef SCHEMELIST_H_ -#define SCHEMELIST_H_ - -#include "scheme.h" - -typedef struct { - int schemeCount; - flib_scheme **schemes; -} flib_schemelist; - -/** - * Load a list of configurations from the ini file. - * Returns NULL on error. - */ -flib_schemelist *flib_schemelist_from_ini(const char *filename); - -/** - * Store the list of configurations to an ini file. - * Returns NULL on error. - */ -int flib_schemelist_to_ini(const char *filename, const flib_schemelist *config); - -/** - * Create an empty scheme list. Returns NULL on error. - */ -flib_schemelist *flib_schemelist_create(); - -/** - * Insert a new scheme into the list at position pos, moving all higher schemes to make place. - * pos must be at least 0 (insert at the start) and at most list->schemeCount (insert at the end). - * Ownership of the scheme is transferred to the list. - * Returns 0 on success. - */ -int flib_schemelist_insert(flib_schemelist *list, flib_scheme *cfg, int pos); - -/** - * Delete a scheme from the list at position pos, moving down all higher schemes. - * The scheme is destroyed. - * Returns 0 on success. - */ -int flib_schemelist_delete(flib_schemelist *list, int pos); - -/** - * Find the scheme with a specific name - */ -flib_scheme *flib_schemelist_find(flib_schemelist *list, const char *name); - -/** - * Free this schemelist and all contained schemes - */ -void flib_schemelist_destroy(flib_schemelist *list); - - -#endif /* SCHEMELIST_H_ */ +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * Functions for managing a list of schemes. + * This is in here because the scheme config file of the QtFrontend (which we are staying compatible with) contains + * all the schemes at once, so we need functions to work with a list like that. + */ + +#ifndef SCHEMELIST_H_ +#define SCHEMELIST_H_ + +#include "scheme.h" + +typedef struct { + int schemeCount; + flib_scheme **schemes; +} flib_schemelist; + +/** + * Load a list of configurations from the ini file. + * Returns NULL on error. + */ +flib_schemelist *flib_schemelist_from_ini(const char *filename); + +/** + * Store the list of configurations to an ini file. + * Returns NULL on error. + */ +int flib_schemelist_to_ini(const char *filename, const flib_schemelist *config); + +/** + * Create an empty scheme list. Returns NULL on error. + */ +flib_schemelist *flib_schemelist_create(); + +/** + * Insert a new scheme into the list at position pos, moving all higher schemes to make place. + * pos must be at least 0 (insert at the start) and at most list->schemeCount (insert at the end). + * Ownership of the scheme is transferred to the list. + * Returns 0 on success. + */ +int flib_schemelist_insert(flib_schemelist *list, flib_scheme *cfg, int pos); + +/** + * Delete a scheme from the list at position pos, moving down all higher schemes. + * The scheme is destroyed. + * Returns 0 on success. + */ +int flib_schemelist_delete(flib_schemelist *list, int pos); + +/** + * Find the scheme with a specific name + */ +flib_scheme *flib_schemelist_find(flib_schemelist *list, const char *name); + +/** + * Free this schemelist and all contained schemes + */ +void flib_schemelist_destroy(flib_schemelist *list); + + +#endif /* SCHEMELIST_H_ */ diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/model/team.c --- a/project_files/frontlib/model/team.c Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/model/team.c Tue Jan 21 22:43:06 2014 +0100 @@ -1,323 +1,323 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "team.h" - -#include "../util/inihelper.h" -#include "../util/util.h" -#include "../util/logging.h" - -#include -#include - -static flib_team *from_ini_handleError(flib_team *result, flib_ini *settingfile) { - flib_ini_destroy(settingfile); - flib_team_destroy(result); - return NULL; -} - -flib_team *flib_team_from_ini(const char *filename) { - if(log_badargs_if(filename==NULL)) { - return NULL; - } - - flib_team *result = flib_calloc(1, sizeof(flib_team)); - flib_ini *ini = NULL; - - if(!result) { - return from_ini_handleError(result, ini); - } - - ini = flib_ini_load(filename); - if(!ini) { - flib_log_e("Error loading team file %s", filename); - return from_ini_handleError(result, ini); - } - - if(flib_ini_enter_section(ini, "team")) { - flib_log_e("Missing section \"Team\" in team file %s", filename); - return from_ini_handleError(result, ini); - } - bool error = false; - error |= flib_ini_get_str(ini, &result->name, "name"); - error |= flib_ini_get_str(ini, &result->grave, "grave"); - error |= flib_ini_get_str(ini, &result->fort, "fort"); - error |= flib_ini_get_str(ini, &result->voicepack, "voicepack"); - error |= flib_ini_get_str(ini, &result->flag, "flag"); - error |= flib_ini_get_int(ini, &result->rounds, "rounds"); - error |= flib_ini_get_int(ini, &result->wins, "wins"); - error |= flib_ini_get_int(ini, &result->campaignProgress, "campaignprogress"); - - int difficulty = 0; - error |= flib_ini_get_int(ini, &difficulty, "difficulty"); - - if(error) { - flib_log_e("Missing or malformed entry in section \"Team\" in file %s", filename); - return from_ini_handleError(result, ini); - } - - for(int i=0; ihogs[i]; - error |= flib_ini_get_str(ini, &hog->name, "name"); - error |= flib_ini_get_str(ini, &hog->hat, "hat"); - error |= flib_ini_get_int(ini, &hog->rounds, "rounds"); - error |= flib_ini_get_int(ini, &hog->kills, "kills"); - error |= flib_ini_get_int(ini, &hog->deaths, "deaths"); - error |= flib_ini_get_int(ini, &hog->suicides, "suicides"); - result->hogs[i].difficulty = difficulty; - result->hogs[i].initialHealth = TEAM_DEFAULT_HEALTH; - - if(error) { - flib_log_e("Missing or malformed entry in section \"%s\" in file %s", sectionName, filename); - return from_ini_handleError(result, ini); - } - } - - if(!flib_ini_enter_section(ini, "binds")) { - result->bindingCount = flib_ini_get_keycount(ini); - if(result->bindingCount<0) { - flib_log_e("Error reading bindings from file %s", filename); - result->bindingCount = 0; - } - result->bindings = flib_calloc(result->bindingCount, sizeof(flib_binding)); - if(!result->bindings) { - return from_ini_handleError(result, ini); - } - for(int i=0; ibindingCount; i++) { - char *keyname = flib_ini_get_keyname(ini, i); - if(!keyname) { - error = true; - } else { - result->bindings[i].action = flib_urldecode(keyname); - error |= !result->bindings[i].action; - error |= flib_ini_get_str(ini, &result->bindings[i].binding, keyname); - } - free(keyname); - } - } - - if(error) { - flib_log_e("Error reading team file %s", filename); - return from_ini_handleError(result, ini); - } - - flib_ini_destroy(ini); - return result; -} - -void flib_team_destroy(flib_team *team) { - if(team) { - for(int i=0; ihogs[i].name); - free(team->hogs[i].hat); - flib_weaponset_destroy(team->hogs[i].weaponset); - } - free(team->name); - free(team->grave); - free(team->fort); - free(team->voicepack); - free(team->flag); - if(team->bindings) { - for(int i=0; ibindingCount; i++) { - free(team->bindings[i].action); - free(team->bindings[i].binding); - } - } - free(team->bindings); - free(team->ownerName); - free(team); - } -} - -static int writeTeamSection(const flib_team *team, flib_ini *ini) { - if(flib_ini_create_section(ini, "team")) { - return -1; - } - bool error = false; - error |= flib_ini_set_str(ini, "name", team->name); - error |= flib_ini_set_str(ini, "grave", team->grave); - error |= flib_ini_set_str(ini, "fort", team->fort); - error |= flib_ini_set_str(ini, "voicepack", team->voicepack); - error |= flib_ini_set_str(ini, "flag", team->flag); - error |= flib_ini_set_int(ini, "rounds", team->rounds); - error |= flib_ini_set_int(ini, "wins", team->wins); - error |= flib_ini_set_int(ini, "campaignprogress", team->campaignProgress); - error |= flib_ini_set_int(ini, "difficulty", team->hogs[0].difficulty); - return error; -} - -static int writeHogSections(const flib_team *team, flib_ini *ini) { - for(int i=0; ihogs[i]; - char sectionName[32]; - if(snprintf(sectionName, sizeof(sectionName), "hedgehog%i", i) <= 0) { - return -1; - } - if(flib_ini_create_section(ini, sectionName)) { - return -1; - } - bool error = false; - error |= flib_ini_set_str(ini, "name", hog->name); - error |= flib_ini_set_str(ini, "hat", hog->hat); - error |= flib_ini_set_int(ini, "rounds", hog->rounds); - error |= flib_ini_set_int(ini, "kills", hog->kills); - error |= flib_ini_set_int(ini, "deaths", hog->deaths); - error |= flib_ini_set_int(ini, "suicides", hog->suicides); - if(error) { - return error; - } - } - return 0; -} - -static int writeBindingSection(const flib_team *team, flib_ini *ini) { - if(team->bindingCount == 0) { - return 0; - } - if(flib_ini_create_section(ini, "binds")) { - return -1; - } - for(int i=0; ibindingCount; i++) { - bool error = false; - char *action = flib_urlencode(team->bindings[i].action); - if(action) { - error |= flib_ini_set_str(ini, action, team->bindings[i].binding); - free(action); - } else { - error = true; - } - if(error) { - return error; - } - } - return 0; -} - -int flib_team_to_ini(const char *filename, const flib_team *team) { - int result = -1; - if(!log_badargs_if2(filename==NULL, team==NULL)) { - flib_ini *ini = flib_ini_create(filename); - bool error = false; - error |= writeTeamSection(team, ini); - error |= writeHogSections(team, ini); - error |= writeBindingSection(team, ini); - if(!error) { - result = flib_ini_save(ini, filename); - } - flib_ini_destroy(ini); - } - return result; -} - -int flib_team_set_weaponset(flib_team *team, const flib_weaponset *set) { - if(team) { - for(int i=0; ihogs[i].weaponset); - team->hogs[i].weaponset = flib_weaponset_copy(set); - if(set && !team->hogs[i].weaponset) { - return -1; - } - } - } - return 0; -} - -void flib_team_set_health(flib_team *team, int health) { - if(team) { - for(int i=0; ihogs[i].initialHealth = health; - } - } -} - -static char *strdupWithError(const char *in, bool *error) { - char *out = flib_strdupnull(in); - if(in && !out) { - *error = true; - } - return out; -} - -flib_team *flib_team_copy(const flib_team *team) { - flib_team *result = NULL; - if(team) { - flib_team *tmpTeam = flib_calloc(1, sizeof(flib_team)); - if(tmpTeam) { - bool error = false; - - for(int i=0; ihogs[i].name = strdupWithError(team->hogs[i].name, &error); - tmpTeam->hogs[i].hat = strdupWithError(team->hogs[i].hat, &error); - tmpTeam->hogs[i].rounds = team->hogs[i].rounds; - tmpTeam->hogs[i].kills = team->hogs[i].kills; - tmpTeam->hogs[i].deaths = team->hogs[i].deaths; - tmpTeam->hogs[i].suicides = team->hogs[i].suicides; - tmpTeam->hogs[i].difficulty = team->hogs[i].difficulty; - tmpTeam->hogs[i].initialHealth = team->hogs[i].initialHealth; - tmpTeam->hogs[i].weaponset = flib_weaponset_copy(team->hogs[i].weaponset); - if(team->hogs[i].weaponset && !tmpTeam->hogs[i].weaponset) { - error = true; - } - } - - tmpTeam->name = strdupWithError(team->name, &error); - tmpTeam->grave = strdupWithError(team->grave, &error); - tmpTeam->fort = strdupWithError(team->fort, &error); - tmpTeam->voicepack = strdupWithError(team->voicepack, &error); - tmpTeam->flag = strdupWithError(team->flag, &error); - tmpTeam->ownerName = strdupWithError(team->ownerName, &error); - - tmpTeam->bindingCount = team->bindingCount; - if(team->bindings) { - tmpTeam->bindings = flib_calloc(team->bindingCount, sizeof(flib_binding)); - if(tmpTeam->bindings) { - for(int i=0; ibindingCount; i++) { - tmpTeam->bindings[i].action = strdupWithError(team->bindings[i].action, &error); - tmpTeam->bindings[i].binding = strdupWithError(team->bindings[i].binding, &error); - } - } else { - error = true; - } - } - - tmpTeam->rounds = team->rounds; - tmpTeam->wins = team->wins; - tmpTeam->campaignProgress = team->campaignProgress; - - tmpTeam->colorIndex = team->colorIndex; - tmpTeam->hogsInGame = team->hogsInGame; - tmpTeam->remoteDriven = team->remoteDriven; - - if(!error) { - result = tmpTeam; - tmpTeam = 0; - } - } - flib_team_destroy(tmpTeam); - } - return result; -} +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "team.h" + +#include "../util/inihelper.h" +#include "../util/util.h" +#include "../util/logging.h" + +#include +#include + +static flib_team *from_ini_handleError(flib_team *result, flib_ini *settingfile) { + flib_ini_destroy(settingfile); + flib_team_destroy(result); + return NULL; +} + +flib_team *flib_team_from_ini(const char *filename) { + if(log_badargs_if(filename==NULL)) { + return NULL; + } + + flib_team *result = flib_calloc(1, sizeof(flib_team)); + flib_ini *ini = NULL; + + if(!result) { + return from_ini_handleError(result, ini); + } + + ini = flib_ini_load(filename); + if(!ini) { + flib_log_e("Error loading team file %s", filename); + return from_ini_handleError(result, ini); + } + + if(flib_ini_enter_section(ini, "team")) { + flib_log_e("Missing section \"Team\" in team file %s", filename); + return from_ini_handleError(result, ini); + } + bool error = false; + error |= flib_ini_get_str(ini, &result->name, "name"); + error |= flib_ini_get_str(ini, &result->grave, "grave"); + error |= flib_ini_get_str(ini, &result->fort, "fort"); + error |= flib_ini_get_str(ini, &result->voicepack, "voicepack"); + error |= flib_ini_get_str(ini, &result->flag, "flag"); + error |= flib_ini_get_int(ini, &result->rounds, "rounds"); + error |= flib_ini_get_int(ini, &result->wins, "wins"); + error |= flib_ini_get_int(ini, &result->campaignProgress, "campaignprogress"); + + int difficulty = 0; + error |= flib_ini_get_int(ini, &difficulty, "difficulty"); + + if(error) { + flib_log_e("Missing or malformed entry in section \"Team\" in file %s", filename); + return from_ini_handleError(result, ini); + } + + for(int i=0; ihogs[i]; + error |= flib_ini_get_str(ini, &hog->name, "name"); + error |= flib_ini_get_str(ini, &hog->hat, "hat"); + error |= flib_ini_get_int(ini, &hog->rounds, "rounds"); + error |= flib_ini_get_int(ini, &hog->kills, "kills"); + error |= flib_ini_get_int(ini, &hog->deaths, "deaths"); + error |= flib_ini_get_int(ini, &hog->suicides, "suicides"); + result->hogs[i].difficulty = difficulty; + result->hogs[i].initialHealth = TEAM_DEFAULT_HEALTH; + + if(error) { + flib_log_e("Missing or malformed entry in section \"%s\" in file %s", sectionName, filename); + return from_ini_handleError(result, ini); + } + } + + if(!flib_ini_enter_section(ini, "binds")) { + result->bindingCount = flib_ini_get_keycount(ini); + if(result->bindingCount<0) { + flib_log_e("Error reading bindings from file %s", filename); + result->bindingCount = 0; + } + result->bindings = flib_calloc(result->bindingCount, sizeof(flib_binding)); + if(!result->bindings) { + return from_ini_handleError(result, ini); + } + for(int i=0; ibindingCount; i++) { + char *keyname = flib_ini_get_keyname(ini, i); + if(!keyname) { + error = true; + } else { + result->bindings[i].action = flib_urldecode(keyname); + error |= !result->bindings[i].action; + error |= flib_ini_get_str(ini, &result->bindings[i].binding, keyname); + } + free(keyname); + } + } + + if(error) { + flib_log_e("Error reading team file %s", filename); + return from_ini_handleError(result, ini); + } + + flib_ini_destroy(ini); + return result; +} + +void flib_team_destroy(flib_team *team) { + if(team) { + for(int i=0; ihogs[i].name); + free(team->hogs[i].hat); + flib_weaponset_destroy(team->hogs[i].weaponset); + } + free(team->name); + free(team->grave); + free(team->fort); + free(team->voicepack); + free(team->flag); + if(team->bindings) { + for(int i=0; ibindingCount; i++) { + free(team->bindings[i].action); + free(team->bindings[i].binding); + } + } + free(team->bindings); + free(team->ownerName); + free(team); + } +} + +static int writeTeamSection(const flib_team *team, flib_ini *ini) { + if(flib_ini_create_section(ini, "team")) { + return -1; + } + bool error = false; + error |= flib_ini_set_str(ini, "name", team->name); + error |= flib_ini_set_str(ini, "grave", team->grave); + error |= flib_ini_set_str(ini, "fort", team->fort); + error |= flib_ini_set_str(ini, "voicepack", team->voicepack); + error |= flib_ini_set_str(ini, "flag", team->flag); + error |= flib_ini_set_int(ini, "rounds", team->rounds); + error |= flib_ini_set_int(ini, "wins", team->wins); + error |= flib_ini_set_int(ini, "campaignprogress", team->campaignProgress); + error |= flib_ini_set_int(ini, "difficulty", team->hogs[0].difficulty); + return error; +} + +static int writeHogSections(const flib_team *team, flib_ini *ini) { + for(int i=0; ihogs[i]; + char sectionName[32]; + if(snprintf(sectionName, sizeof(sectionName), "hedgehog%i", i) <= 0) { + return -1; + } + if(flib_ini_create_section(ini, sectionName)) { + return -1; + } + bool error = false; + error |= flib_ini_set_str(ini, "name", hog->name); + error |= flib_ini_set_str(ini, "hat", hog->hat); + error |= flib_ini_set_int(ini, "rounds", hog->rounds); + error |= flib_ini_set_int(ini, "kills", hog->kills); + error |= flib_ini_set_int(ini, "deaths", hog->deaths); + error |= flib_ini_set_int(ini, "suicides", hog->suicides); + if(error) { + return error; + } + } + return 0; +} + +static int writeBindingSection(const flib_team *team, flib_ini *ini) { + if(team->bindingCount == 0) { + return 0; + } + if(flib_ini_create_section(ini, "binds")) { + return -1; + } + for(int i=0; ibindingCount; i++) { + bool error = false; + char *action = flib_urlencode(team->bindings[i].action); + if(action) { + error |= flib_ini_set_str(ini, action, team->bindings[i].binding); + free(action); + } else { + error = true; + } + if(error) { + return error; + } + } + return 0; +} + +int flib_team_to_ini(const char *filename, const flib_team *team) { + int result = -1; + if(!log_badargs_if2(filename==NULL, team==NULL)) { + flib_ini *ini = flib_ini_create(filename); + bool error = false; + error |= writeTeamSection(team, ini); + error |= writeHogSections(team, ini); + error |= writeBindingSection(team, ini); + if(!error) { + result = flib_ini_save(ini, filename); + } + flib_ini_destroy(ini); + } + return result; +} + +int flib_team_set_weaponset(flib_team *team, const flib_weaponset *set) { + if(team) { + for(int i=0; ihogs[i].weaponset); + team->hogs[i].weaponset = flib_weaponset_copy(set); + if(set && !team->hogs[i].weaponset) { + return -1; + } + } + } + return 0; +} + +void flib_team_set_health(flib_team *team, int health) { + if(team) { + for(int i=0; ihogs[i].initialHealth = health; + } + } +} + +static char *strdupWithError(const char *in, bool *error) { + char *out = flib_strdupnull(in); + if(in && !out) { + *error = true; + } + return out; +} + +flib_team *flib_team_copy(const flib_team *team) { + flib_team *result = NULL; + if(team) { + flib_team *tmpTeam = flib_calloc(1, sizeof(flib_team)); + if(tmpTeam) { + bool error = false; + + for(int i=0; ihogs[i].name = strdupWithError(team->hogs[i].name, &error); + tmpTeam->hogs[i].hat = strdupWithError(team->hogs[i].hat, &error); + tmpTeam->hogs[i].rounds = team->hogs[i].rounds; + tmpTeam->hogs[i].kills = team->hogs[i].kills; + tmpTeam->hogs[i].deaths = team->hogs[i].deaths; + tmpTeam->hogs[i].suicides = team->hogs[i].suicides; + tmpTeam->hogs[i].difficulty = team->hogs[i].difficulty; + tmpTeam->hogs[i].initialHealth = team->hogs[i].initialHealth; + tmpTeam->hogs[i].weaponset = flib_weaponset_copy(team->hogs[i].weaponset); + if(team->hogs[i].weaponset && !tmpTeam->hogs[i].weaponset) { + error = true; + } + } + + tmpTeam->name = strdupWithError(team->name, &error); + tmpTeam->grave = strdupWithError(team->grave, &error); + tmpTeam->fort = strdupWithError(team->fort, &error); + tmpTeam->voicepack = strdupWithError(team->voicepack, &error); + tmpTeam->flag = strdupWithError(team->flag, &error); + tmpTeam->ownerName = strdupWithError(team->ownerName, &error); + + tmpTeam->bindingCount = team->bindingCount; + if(team->bindings) { + tmpTeam->bindings = flib_calloc(team->bindingCount, sizeof(flib_binding)); + if(tmpTeam->bindings) { + for(int i=0; ibindingCount; i++) { + tmpTeam->bindings[i].action = strdupWithError(team->bindings[i].action, &error); + tmpTeam->bindings[i].binding = strdupWithError(team->bindings[i].binding, &error); + } + } else { + error = true; + } + } + + tmpTeam->rounds = team->rounds; + tmpTeam->wins = team->wins; + tmpTeam->campaignProgress = team->campaignProgress; + + tmpTeam->colorIndex = team->colorIndex; + tmpTeam->hogsInGame = team->hogsInGame; + tmpTeam->remoteDriven = team->remoteDriven; + + if(!error) { + result = tmpTeam; + tmpTeam = 0; + } + } + flib_team_destroy(tmpTeam); + } + return result; +} diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/model/team.h --- a/project_files/frontlib/model/team.h Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/model/team.h Tue Jan 21 22:43:06 2014 +0100 @@ -1,130 +1,130 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * This file defines a data structure for a hedgewars team. - * - * Teams are used in several different contexts in Hedgewars, and some of these require - * extra information about teams. For example, the weaponset is important - * to the engine, but not for ini reading/writing, and with the team statistics it is the - * other way around. To keep things simple, the data structure can hold all information - * used in any context. On the downside, that means we can't use static typing to ensure - * that team information is "complete" for a particular purpose. - */ -#ifndef TEAM_H_ -#define TEAM_H_ - - -#include "weapon.h" -#include "../hwconsts.h" - -#include -#include - -#define TEAM_DEFAULT_HEALTH 100 - -/** - * Struct representing a single keybinding. - */ -typedef struct { - char *action; - char *binding; -} flib_binding; - -typedef struct { - char *name; - char *hat; //!< e.g. hair_yellow; References a .png file in Data/Graphics/Hats - - //! Statistics. They are irrelevant for the engine or server, - //! but provided for ini reading/writing by the frontend. - int rounds; - int kills; - int deaths; - int suicides; - - int difficulty; //!< 0 = human, 1 = most difficult bot ... 5 = least difficult bot (somewhat counterintuitive) - - //! Transient setting used in game setup - int initialHealth; - flib_weaponset *weaponset; -} flib_hog; - -typedef struct { - flib_hog hogs[HEDGEHOGS_PER_TEAM]; - char *name; - char *grave; //!< e.g. "Bone"; References a .png file in Data/Graphics/Graves - char *fort; //!< e.g. "Castle"; References a series of files in Data/Forts - char *voicepack; //!< e.g. "Classic"; References a directory in Data/Sounds/voices - char *flag; //!< e.g. "hedgewars"; References a .png file in Data/Graphics/Flags - - flib_binding *bindings; - int bindingCount; - - //! Statistics. They are irrelevant for the engine or server, - //! but provided for ini reading/writing by the frontend. - int rounds; - int wins; - int campaignProgress; - - //! Transient settings used in game setup - int colorIndex; //!< Index into a color table - int hogsInGame; //!< The number of hogs that will actually play - bool remoteDriven; //!< true for non-local teams in a network game - char *ownerName; //!< Username of the owner of a team in a network game -} flib_team; - -/** - * Free all memory associated with the team - */ -void flib_team_destroy(flib_team *team); - -/** - * Loads a team, returns NULL on error. Destroy this team using flib_team_destroy. - * This will not fill in the fields marked as "transient" in the structs above. - */ -flib_team *flib_team_from_ini(const char *filename); - -/** - * Write the team to an ini file. Attempts to retain extra ini settings - * that were already present. Note that not all fields of a team struct - * are stored in the ini, some are only used intermittently to store - * information about a team in the context of a game. - * - * The flib_team can handle "difficulty" on a per-hog basis, but it - * is only written per-team in the team file. The difficulty of the - * first hog is used for the entire team when writing. - */ -int flib_team_to_ini(const char *filename, const flib_team *team); - -/** - * Set the same weaponset for every hog in the team - */ -int flib_team_set_weaponset(flib_team *team, const flib_weaponset *set); - -/** - * Set the same initial health for every hog. - */ -void flib_team_set_health(flib_team *team, int health); - -/** - * Create a deep copy of a team. Returns NULL on failure. - */ -flib_team *flib_team_copy(const flib_team *team); - -#endif /* TEAM_H_ */ +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * This file defines a data structure for a hedgewars team. + * + * Teams are used in several different contexts in Hedgewars, and some of these require + * extra information about teams. For example, the weaponset is important + * to the engine, but not for ini reading/writing, and with the team statistics it is the + * other way around. To keep things simple, the data structure can hold all information + * used in any context. On the downside, that means we can't use static typing to ensure + * that team information is "complete" for a particular purpose. + */ +#ifndef TEAM_H_ +#define TEAM_H_ + + +#include "weapon.h" +#include "../hwconsts.h" + +#include +#include + +#define TEAM_DEFAULT_HEALTH 100 + +/** + * Struct representing a single keybinding. + */ +typedef struct { + char *action; + char *binding; +} flib_binding; + +typedef struct { + char *name; + char *hat; //!< e.g. hair_yellow; References a .png file in Data/Graphics/Hats + + //! Statistics. They are irrelevant for the engine or server, + //! but provided for ini reading/writing by the frontend. + int rounds; + int kills; + int deaths; + int suicides; + + int difficulty; //!< 0 = human, 1 = most difficult bot ... 5 = least difficult bot (somewhat counterintuitive) + + //! Transient setting used in game setup + int initialHealth; + flib_weaponset *weaponset; +} flib_hog; + +typedef struct { + flib_hog hogs[HEDGEHOGS_PER_TEAM]; + char *name; + char *grave; //!< e.g. "Bone"; References a .png file in Data/Graphics/Graves + char *fort; //!< e.g. "Castle"; References a series of files in Data/Forts + char *voicepack; //!< e.g. "Classic"; References a directory in Data/Sounds/voices + char *flag; //!< e.g. "hedgewars"; References a .png file in Data/Graphics/Flags + + flib_binding *bindings; + int bindingCount; + + //! Statistics. They are irrelevant for the engine or server, + //! but provided for ini reading/writing by the frontend. + int rounds; + int wins; + int campaignProgress; + + //! Transient settings used in game setup + int colorIndex; //!< Index into a color table + int hogsInGame; //!< The number of hogs that will actually play + bool remoteDriven; //!< true for non-local teams in a network game + char *ownerName; //!< Username of the owner of a team in a network game +} flib_team; + +/** + * Free all memory associated with the team + */ +void flib_team_destroy(flib_team *team); + +/** + * Loads a team, returns NULL on error. Destroy this team using flib_team_destroy. + * This will not fill in the fields marked as "transient" in the structs above. + */ +flib_team *flib_team_from_ini(const char *filename); + +/** + * Write the team to an ini file. Attempts to retain extra ini settings + * that were already present. Note that not all fields of a team struct + * are stored in the ini, some are only used intermittently to store + * information about a team in the context of a game. + * + * The flib_team can handle "difficulty" on a per-hog basis, but it + * is only written per-team in the team file. The difficulty of the + * first hog is used for the entire team when writing. + */ +int flib_team_to_ini(const char *filename, const flib_team *team); + +/** + * Set the same weaponset for every hog in the team + */ +int flib_team_set_weaponset(flib_team *team, const flib_weaponset *set); + +/** + * Set the same initial health for every hog. + */ +void flib_team_set_health(flib_team *team, int health); + +/** + * Create a deep copy of a team. Returns NULL on failure. + */ +flib_team *flib_team_copy(const flib_team *team); + +#endif /* TEAM_H_ */ diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/model/teamlist.c --- a/project_files/frontlib/model/teamlist.c Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/model/teamlist.c Tue Jan 21 22:43:06 2014 +0100 @@ -1,120 +1,120 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "teamlist.h" - -#include "../util/util.h" -#include "../util/list.h" -#include "../util/logging.h" - -#include -#include - -flib_teamlist *flib_teamlist_create() { - return flib_calloc(1, sizeof(flib_teamlist)); -} - -void flib_teamlist_destroy(flib_teamlist *list) { - if(list) { - for(int i=0; iteamCount; i++) { - flib_team_destroy(list->teams[i]); - } - free(list->teams); - free(list); - } -} - -GENERATE_STATIC_LIST_INSERT(insertTeam, flib_team*) -GENERATE_STATIC_LIST_DELETE(deleteTeam, flib_team*) - -static int findTeam(const flib_teamlist *list, const char *name) { - for(int i=0; iteamCount; i++) { - if(!strcmp(name, list->teams[i]->name)) { - return i; - } - } - return -1; -} - -int flib_teamlist_insert(flib_teamlist *list, flib_team *team, int pos) { - if(!log_badargs_if2(list==NULL, team==NULL) - && !insertTeam(&list->teams, &list->teamCount, team, pos)) { - return 0; - } - return -1; -} - -int flib_teamlist_delete(flib_teamlist *list, const char *name) { - int result = -1; - if(!log_badargs_if2(list==NULL, name==NULL)) { - int itemid = findTeam(list, name); - if(itemid>=0) { - flib_team *team = list->teams[itemid]; - if(!deleteTeam(&list->teams, &list->teamCount, itemid)) { - flib_team_destroy(team); - result = 0; - } - } - } - return result; -} - -flib_team *flib_teamlist_find(const flib_teamlist *list, const char *name) { - flib_team *result = NULL; - if(!log_badargs_if2(list==NULL, name==NULL)) { - int itemid = findTeam(list, name); - if(itemid>=0) { - result = list->teams[itemid]; - } - } - return result; -} - -void flib_teamlist_clear(flib_teamlist *list) { - if(!log_badargs_if(list==NULL)) { - for(int i=0; iteamCount; i++) { - flib_team_destroy(list->teams[i]); - } - free(list->teams); - list->teams = NULL; - list->teamCount = 0; - } -} - -flib_teamlist *flib_teamlist_copy(flib_teamlist *list) { - if(!list) { - return NULL; - } - flib_teamlist *result = flib_teamlist_create(); - if(result) { - bool error = false; - for(int i=0; !error && iteamCount; i++) { - flib_team *teamcopy = flib_team_copy(list->teams[i]); - if(!teamcopy || flib_teamlist_insert(result, teamcopy, i)) { - flib_team_destroy(teamcopy); - error = true; - } - } - if(error) { - flib_teamlist_destroy(result); - result = NULL; - } - } - return result; -} +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "teamlist.h" + +#include "../util/util.h" +#include "../util/list.h" +#include "../util/logging.h" + +#include +#include + +flib_teamlist *flib_teamlist_create() { + return flib_calloc(1, sizeof(flib_teamlist)); +} + +void flib_teamlist_destroy(flib_teamlist *list) { + if(list) { + for(int i=0; iteamCount; i++) { + flib_team_destroy(list->teams[i]); + } + free(list->teams); + free(list); + } +} + +GENERATE_STATIC_LIST_INSERT(insertTeam, flib_team*) +GENERATE_STATIC_LIST_DELETE(deleteTeam, flib_team*) + +static int findTeam(const flib_teamlist *list, const char *name) { + for(int i=0; iteamCount; i++) { + if(!strcmp(name, list->teams[i]->name)) { + return i; + } + } + return -1; +} + +int flib_teamlist_insert(flib_teamlist *list, flib_team *team, int pos) { + if(!log_badargs_if2(list==NULL, team==NULL) + && !insertTeam(&list->teams, &list->teamCount, team, pos)) { + return 0; + } + return -1; +} + +int flib_teamlist_delete(flib_teamlist *list, const char *name) { + int result = -1; + if(!log_badargs_if2(list==NULL, name==NULL)) { + int itemid = findTeam(list, name); + if(itemid>=0) { + flib_team *team = list->teams[itemid]; + if(!deleteTeam(&list->teams, &list->teamCount, itemid)) { + flib_team_destroy(team); + result = 0; + } + } + } + return result; +} + +flib_team *flib_teamlist_find(const flib_teamlist *list, const char *name) { + flib_team *result = NULL; + if(!log_badargs_if2(list==NULL, name==NULL)) { + int itemid = findTeam(list, name); + if(itemid>=0) { + result = list->teams[itemid]; + } + } + return result; +} + +void flib_teamlist_clear(flib_teamlist *list) { + if(!log_badargs_if(list==NULL)) { + for(int i=0; iteamCount; i++) { + flib_team_destroy(list->teams[i]); + } + free(list->teams); + list->teams = NULL; + list->teamCount = 0; + } +} + +flib_teamlist *flib_teamlist_copy(flib_teamlist *list) { + if(!list) { + return NULL; + } + flib_teamlist *result = flib_teamlist_create(); + if(result) { + bool error = false; + for(int i=0; !error && iteamCount; i++) { + flib_team *teamcopy = flib_team_copy(list->teams[i]); + if(!teamcopy || flib_teamlist_insert(result, teamcopy, i)) { + flib_team_destroy(teamcopy); + error = true; + } + } + if(error) { + flib_teamlist_destroy(result); + result = NULL; + } + } + return result; +} diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/model/teamlist.h --- a/project_files/frontlib/model/teamlist.h Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/model/teamlist.h Tue Jan 21 22:43:06 2014 +0100 @@ -1,61 +1,61 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef TEAMLIST_H_ -#define TEAMLIST_H_ - -#include "team.h" - -typedef struct { - int teamCount; - flib_team **teams; -} flib_teamlist; - -flib_teamlist *flib_teamlist_create(); - -void flib_teamlist_destroy(flib_teamlist *list); - -/** - * Insert a team into the list. The list takes ownership of the team. Returns 0 on success. - */ -int flib_teamlist_insert(flib_teamlist *list, flib_team *team, int pos); - -/** - * Delete the team with the name [name] from the list and destroys it. - * Returns 0 on success. - */ -int flib_teamlist_delete(flib_teamlist *list, const char *name); - -/** - * Returns the team with the name [name] from the list if it exists, NULL otherwise - */ -flib_team *flib_teamlist_find(const flib_teamlist *list, const char *name); - -/** - * Removes all items from the list and destroys them. - */ -void flib_teamlist_clear(flib_teamlist *list); - -/** - * Create a copy of the list and all the teams it contains. Weaponsets are not copied, but - * kept as references - */ -flib_teamlist *flib_teamlist_copy(flib_teamlist *list); - -#endif +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef TEAMLIST_H_ +#define TEAMLIST_H_ + +#include "team.h" + +typedef struct { + int teamCount; + flib_team **teams; +} flib_teamlist; + +flib_teamlist *flib_teamlist_create(); + +void flib_teamlist_destroy(flib_teamlist *list); + +/** + * Insert a team into the list. The list takes ownership of the team. Returns 0 on success. + */ +int flib_teamlist_insert(flib_teamlist *list, flib_team *team, int pos); + +/** + * Delete the team with the name [name] from the list and destroys it. + * Returns 0 on success. + */ +int flib_teamlist_delete(flib_teamlist *list, const char *name); + +/** + * Returns the team with the name [name] from the list if it exists, NULL otherwise + */ +flib_team *flib_teamlist_find(const flib_teamlist *list, const char *name); + +/** + * Removes all items from the list and destroys them. + */ +void flib_teamlist_clear(flib_teamlist *list); + +/** + * Create a copy of the list and all the teams it contains. Weaponsets are not copied, but + * kept as references + */ +flib_teamlist *flib_teamlist_copy(flib_teamlist *list); + +#endif diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/model/weapon.c --- a/project_files/frontlib/model/weapon.c Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/model/weapon.c Tue Jan 21 22:43:06 2014 +0100 @@ -1,234 +1,234 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "weapon.h" - -#include "../util/inihelper.h" -#include "../util/logging.h" -#include "../util/util.h" -#include "../util/list.h" - -#include -#include -#include - -static void setField(char field[WEAPONS_COUNT+1], const char *line, int lineLen, bool no9) { - if(lineLen>WEAPONS_COUNT) { - lineLen = WEAPONS_COUNT; - } - - char min = '0'; - char max = no9 ? '8' : '9'; - for(int i=0; i= min && line[i] <= max) { - field[i] = line[i]; - } else { - flib_log_w("Invalid character in weapon config string \"%.*s\", position %i", lineLen, line, i); - field[i] = '0'; - } - } - for(int i=lineLen; iname = flib_strdupnull(name); - if(newSet->name) { - setField(newSet->loadout, "", 0, false); - setField(newSet->crateprob, "", 0, false); - setField(newSet->crateammo, "", 0, false); - setField(newSet->delay, "", 0, false); - result = newSet; - newSet = NULL; - } - } - flib_weaponset_destroy(newSet); - } - return result; -} - -void flib_weaponset_destroy(flib_weaponset *cfg) { - if(cfg) { - free(cfg->name); - free(cfg); - } -} - -flib_weaponset *flib_weaponset_copy(const flib_weaponset *weaponset) { - if(!weaponset) { - return NULL; - } - - flib_weaponset *result = flib_weaponset_create(weaponset->name); - if(result) { - memcpy(result->loadout, weaponset->loadout, WEAPONS_COUNT+1); - memcpy(result->crateprob, weaponset->crateprob, WEAPONS_COUNT+1); - memcpy(result->delay, weaponset->delay, WEAPONS_COUNT+1); - memcpy(result->crateammo, weaponset->crateammo, WEAPONS_COUNT+1); - } - - return result; -} - -void flib_weaponsetlist_destroy(flib_weaponsetlist *list) { - if(list) { - for(int i=0; iweaponsetCount; i++) { - flib_weaponset_destroy(list->weaponsets[i]); - } - free(list->weaponsets); - free(list); - } -} - -flib_weaponset *flib_weaponset_from_ammostring(const char *name, const char *ammostring) { - flib_weaponset *result = NULL; - if(!log_badargs_if2(name==NULL, ammostring==NULL)) { - result = flib_weaponset_create(name); - if(result) { - int fieldlen = strlen(ammostring)/4; - setField(result->loadout, ammostring, fieldlen, false); - setField(result->crateprob, ammostring + fieldlen, fieldlen, true); - setField(result->delay, ammostring + 2*fieldlen, fieldlen, true); - setField(result->crateammo, ammostring + 3*fieldlen, fieldlen, true); - } - } - return result; -} - -static int fillWeaponsetFromIni(flib_weaponsetlist *list, flib_ini *ini, int index) { - int result = -1; - char *keyname = flib_ini_get_keyname(ini, index); - char *decodedKeyname = flib_urldecode(keyname); - char *ammostring = NULL; - if(decodedKeyname && !flib_ini_get_str(ini, &ammostring, keyname)) { - flib_weaponset *set = flib_weaponset_from_ammostring(decodedKeyname, ammostring); - if(set) { - result = flib_weaponsetlist_insert(list, set, list->weaponsetCount); - if(result) { - flib_weaponset_destroy(set); - } - } - } - free(ammostring); - free(decodedKeyname); - free(keyname); - return result; -} - -static int fillWeaponsetsFromIni(flib_weaponsetlist *list, flib_ini *ini) { - bool error = false; - int weaponsets = flib_ini_get_keycount(ini); - - for(int i=0; i='0' && c<='9') || (c>='a' && c <='z')); -} +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "weapon.h" + +#include "../util/inihelper.h" +#include "../util/logging.h" +#include "../util/util.h" +#include "../util/list.h" + +#include +#include +#include + +static void setField(char field[WEAPONS_COUNT+1], const char *line, int lineLen, bool no9) { + if(lineLen>WEAPONS_COUNT) { + lineLen = WEAPONS_COUNT; + } + + char min = '0'; + char max = no9 ? '8' : '9'; + for(int i=0; i= min && line[i] <= max) { + field[i] = line[i]; + } else { + flib_log_w("Invalid character in weapon config string \"%.*s\", position %i", lineLen, line, i); + field[i] = '0'; + } + } + for(int i=lineLen; iname = flib_strdupnull(name); + if(newSet->name) { + setField(newSet->loadout, "", 0, false); + setField(newSet->crateprob, "", 0, false); + setField(newSet->crateammo, "", 0, false); + setField(newSet->delay, "", 0, false); + result = newSet; + newSet = NULL; + } + } + flib_weaponset_destroy(newSet); + } + return result; +} + +void flib_weaponset_destroy(flib_weaponset *cfg) { + if(cfg) { + free(cfg->name); + free(cfg); + } +} + +flib_weaponset *flib_weaponset_copy(const flib_weaponset *weaponset) { + if(!weaponset) { + return NULL; + } + + flib_weaponset *result = flib_weaponset_create(weaponset->name); + if(result) { + memcpy(result->loadout, weaponset->loadout, WEAPONS_COUNT+1); + memcpy(result->crateprob, weaponset->crateprob, WEAPONS_COUNT+1); + memcpy(result->delay, weaponset->delay, WEAPONS_COUNT+1); + memcpy(result->crateammo, weaponset->crateammo, WEAPONS_COUNT+1); + } + + return result; +} + +void flib_weaponsetlist_destroy(flib_weaponsetlist *list) { + if(list) { + for(int i=0; iweaponsetCount; i++) { + flib_weaponset_destroy(list->weaponsets[i]); + } + free(list->weaponsets); + free(list); + } +} -static int writeWeaponsetToIni(flib_ini *ini, flib_weaponset *set) { - int result = -1; - char weaponstring[WEAPONS_COUNT*4+1]; - strcpy(weaponstring, set->loadout); - strcat(weaponstring, set->crateprob); - strcat(weaponstring, set->delay); - strcat(weaponstring, set->crateammo); - - char *escapedname = flib_urlencode_pred(set->name, needsEscape); - if(escapedname) { - result = flib_ini_set_str(ini, escapedname, weaponstring); - } - free(escapedname); - return result; -} - -int flib_weaponsetlist_to_ini(const char *filename, const flib_weaponsetlist *list) { - int result = -1; - if(!log_badargs_if2(filename==NULL, list==NULL)) { - flib_ini *ini = flib_ini_create(NULL); - if(ini && !flib_ini_create_section(ini, "General")) { - bool error = false; - for(int i=0; iweaponsetCount && !error; i++) { - error |= writeWeaponsetToIni(ini, list->weaponsets[i]); - } - - if(!error) { - result = flib_ini_save(ini, filename); - } - } - flib_ini_destroy(ini); - } - return result; -} - -flib_weaponsetlist *flib_weaponsetlist_create() { - return flib_calloc(1, sizeof(flib_weaponsetlist)); -} - -GENERATE_STATIC_LIST_INSERT(insertWeaponset, flib_weaponset*) -GENERATE_STATIC_LIST_DELETE(deleteWeaponset, flib_weaponset*) - -int flib_weaponsetlist_insert(flib_weaponsetlist *list, flib_weaponset *set, int pos) { - if(!log_badargs_if2(list==NULL, set==NULL) - && !insertWeaponset(&list->weaponsets, &list->weaponsetCount, set, pos)) { - return 0; - } - return -1; -} - -int flib_weaponsetlist_delete(flib_weaponsetlist *list, int pos) { - if(!log_badargs_if(list==NULL)) { - flib_weaponset *elem = list->weaponsets[pos]; - if(!deleteWeaponset(&list->weaponsets, &list->weaponsetCount, pos)) { - flib_weaponset_destroy(elem); - return 0; - } - } - return -1; -} +flib_weaponset *flib_weaponset_from_ammostring(const char *name, const char *ammostring) { + flib_weaponset *result = NULL; + if(!log_badargs_if2(name==NULL, ammostring==NULL)) { + result = flib_weaponset_create(name); + if(result) { + int fieldlen = strlen(ammostring)/4; + setField(result->loadout, ammostring, fieldlen, false); + setField(result->crateprob, ammostring + fieldlen, fieldlen, true); + setField(result->delay, ammostring + 2*fieldlen, fieldlen, true); + setField(result->crateammo, ammostring + 3*fieldlen, fieldlen, true); + } + } + return result; +} + +static int fillWeaponsetFromIni(flib_weaponsetlist *list, flib_ini *ini, int index) { + int result = -1; + char *keyname = flib_ini_get_keyname(ini, index); + char *decodedKeyname = flib_urldecode(keyname); + char *ammostring = NULL; + if(decodedKeyname && !flib_ini_get_str(ini, &ammostring, keyname)) { + flib_weaponset *set = flib_weaponset_from_ammostring(decodedKeyname, ammostring); + if(set) { + result = flib_weaponsetlist_insert(list, set, list->weaponsetCount); + if(result) { + flib_weaponset_destroy(set); + } + } + } + free(ammostring); + free(decodedKeyname); + free(keyname); + return result; +} + +static int fillWeaponsetsFromIni(flib_weaponsetlist *list, flib_ini *ini) { + bool error = false; + int weaponsets = flib_ini_get_keycount(ini); + + for(int i=0; i='0' && c<='9') || (c>='a' && c <='z')); +} + +static int writeWeaponsetToIni(flib_ini *ini, flib_weaponset *set) { + int result = -1; + char weaponstring[WEAPONS_COUNT*4+1]; + strcpy(weaponstring, set->loadout); + strcat(weaponstring, set->crateprob); + strcat(weaponstring, set->delay); + strcat(weaponstring, set->crateammo); + + char *escapedname = flib_urlencode_pred(set->name, needsEscape); + if(escapedname) { + result = flib_ini_set_str(ini, escapedname, weaponstring); + } + free(escapedname); + return result; +} + +int flib_weaponsetlist_to_ini(const char *filename, const flib_weaponsetlist *list) { + int result = -1; + if(!log_badargs_if2(filename==NULL, list==NULL)) { + flib_ini *ini = flib_ini_create(NULL); + if(ini && !flib_ini_create_section(ini, "General")) { + bool error = false; + for(int i=0; iweaponsetCount && !error; i++) { + error |= writeWeaponsetToIni(ini, list->weaponsets[i]); + } + + if(!error) { + result = flib_ini_save(ini, filename); + } + } + flib_ini_destroy(ini); + } + return result; +} + +flib_weaponsetlist *flib_weaponsetlist_create() { + return flib_calloc(1, sizeof(flib_weaponsetlist)); +} + +GENERATE_STATIC_LIST_INSERT(insertWeaponset, flib_weaponset*) +GENERATE_STATIC_LIST_DELETE(deleteWeaponset, flib_weaponset*) + +int flib_weaponsetlist_insert(flib_weaponsetlist *list, flib_weaponset *set, int pos) { + if(!log_badargs_if2(list==NULL, set==NULL) + && !insertWeaponset(&list->weaponsets, &list->weaponsetCount, set, pos)) { + return 0; + } + return -1; +} + +int flib_weaponsetlist_delete(flib_weaponsetlist *list, int pos) { + if(!log_badargs_if(list==NULL)) { + flib_weaponset *elem = list->weaponsets[pos]; + if(!deleteWeaponset(&list->weaponsets, &list->weaponsetCount, pos)) { + flib_weaponset_destroy(elem); + return 0; + } + } + return -1; +} diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/model/weapon.h --- a/project_files/frontlib/model/weapon.h Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/model/weapon.h Tue Jan 21 22:43:06 2014 +0100 @@ -1,104 +1,104 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef MODEL_WEAPON_H_ -#define MODEL_WEAPON_H_ - -#include "../hwconsts.h" - -/** - * These values are all ASCII characters in the range '0'..'9' - * The fields are zero-terminated so they can easily be used as strings. - * - * For loadout, 9 means inifinite ammo. - * For the other setting, 9 is invalid. - */ -typedef struct { - char loadout[WEAPONS_COUNT+1]; - char crateprob[WEAPONS_COUNT+1]; - char crateammo[WEAPONS_COUNT+1]; - char delay[WEAPONS_COUNT+1]; - char *name; -} flib_weaponset; - -typedef struct { - int weaponsetCount; - flib_weaponset **weaponsets; -} flib_weaponsetlist; - -/** - * Returns a new weapon set, or NULL on error. - * name must not be NULL. - * - * The new weapon set is pre-filled with default - * settings (see hwconsts.h) - */ -flib_weaponset *flib_weaponset_create(const char *name); - -/** - * Free the memory used by this weaponset - */ -void flib_weaponset_destroy(flib_weaponset *weaponset); - -flib_weaponset *flib_weaponset_copy(const flib_weaponset *weaponset); - -/** - * Create a weaponset from an ammostring. This format is used both in the ini files - * and in the net protocol. - */ -flib_weaponset *flib_weaponset_from_ammostring(const char *name, const char *ammostring); - -/** - * Load a list of weaponsets from the ini file. - * Returns NULL on error. - */ -flib_weaponsetlist *flib_weaponsetlist_from_ini(const char *filename); - -/** - * Store the list of weaponsets to an ini file. - * Returns NULL on error. - */ -int flib_weaponsetlist_to_ini(const char *filename, const flib_weaponsetlist *weaponsets); - -/** - * Create an empty weaponset list. Returns NULL on error. - */ -flib_weaponsetlist *flib_weaponsetlist_create(); - -/** - * Release all memory associated with the weaponsetlist and release all contained weaponsets - */ -void flib_weaponsetlist_destroy(flib_weaponsetlist *list); - -/** - * Insert a new weaponset into the list at position pos, moving all higher weaponsets to make place. - * pos must be at least 0 (insert at the start) and at most list->weaponsetCount (insert at the end). - * Ownership of the weaponset is transferred to the list. - * Returns 0 on success. - */ -int flib_weaponsetlist_insert(flib_weaponsetlist *list, flib_weaponset *weaponset, int pos); - -/** - * Delete a weaponset from the list at position pos, moving down all higher weaponsets. - * The weaponset is destroyed. - * Returns 0 on success. - */ -int flib_weaponsetlist_delete(flib_weaponsetlist *list, int pos); - -#endif +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef MODEL_WEAPON_H_ +#define MODEL_WEAPON_H_ + +#include "../hwconsts.h" + +/** + * These values are all ASCII characters in the range '0'..'9' + * The fields are zero-terminated so they can easily be used as strings. + * + * For loadout, 9 means inifinite ammo. + * For the other setting, 9 is invalid. + */ +typedef struct { + char loadout[WEAPONS_COUNT+1]; + char crateprob[WEAPONS_COUNT+1]; + char crateammo[WEAPONS_COUNT+1]; + char delay[WEAPONS_COUNT+1]; + char *name; +} flib_weaponset; + +typedef struct { + int weaponsetCount; + flib_weaponset **weaponsets; +} flib_weaponsetlist; + +/** + * Returns a new weapon set, or NULL on error. + * name must not be NULL. + * + * The new weapon set is pre-filled with default + * settings (see hwconsts.h) + */ +flib_weaponset *flib_weaponset_create(const char *name); + +/** + * Free the memory used by this weaponset + */ +void flib_weaponset_destroy(flib_weaponset *weaponset); + +flib_weaponset *flib_weaponset_copy(const flib_weaponset *weaponset); + +/** + * Create a weaponset from an ammostring. This format is used both in the ini files + * and in the net protocol. + */ +flib_weaponset *flib_weaponset_from_ammostring(const char *name, const char *ammostring); + +/** + * Load a list of weaponsets from the ini file. + * Returns NULL on error. + */ +flib_weaponsetlist *flib_weaponsetlist_from_ini(const char *filename); + +/** + * Store the list of weaponsets to an ini file. + * Returns NULL on error. + */ +int flib_weaponsetlist_to_ini(const char *filename, const flib_weaponsetlist *weaponsets); + +/** + * Create an empty weaponset list. Returns NULL on error. + */ +flib_weaponsetlist *flib_weaponsetlist_create(); + +/** + * Release all memory associated with the weaponsetlist and release all contained weaponsets + */ +void flib_weaponsetlist_destroy(flib_weaponsetlist *list); + +/** + * Insert a new weaponset into the list at position pos, moving all higher weaponsets to make place. + * pos must be at least 0 (insert at the start) and at most list->weaponsetCount (insert at the end). + * Ownership of the weaponset is transferred to the list. + * Returns 0 on success. + */ +int flib_weaponsetlist_insert(flib_weaponsetlist *list, flib_weaponset *weaponset, int pos); + +/** + * Delete a weaponset from the list at position pos, moving down all higher weaponsets. + * The weaponset is destroyed. + * Returns 0 on success. + */ +int flib_weaponsetlist_delete(flib_weaponsetlist *list, int pos); + +#endif diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/net/netbase.c --- a/project_files/frontlib/net/netbase.c Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/net/netbase.c Tue Jan 21 22:43:06 2014 +0100 @@ -1,259 +1,259 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "netbase.h" -#include "../util/buffer.h" -#include "../util/logging.h" -#include "../util/util.h" -#include "../socket.h" - -#include -#include -#include -#include - -#define NET_READBUFFER_LIMIT (1024*1024) - -struct _flib_netbase { - flib_vector *readBuffer; - flib_tcpsocket *sock; -}; - -flib_netbase *flib_netbase_create(const char *server, uint16_t port) { - if(log_badargs_if2(server==NULL, port==0)) { - return NULL; - } - - flib_netbase *result = NULL; - flib_netbase *newNet = flib_calloc(1, sizeof(flib_netbase)); - - if(newNet) { - newNet->readBuffer = flib_vector_create(); - newNet->sock = flib_socket_connect(server, port); - if(newNet->readBuffer && newNet->sock) { - flib_log_i("Connected to server %s:%u", server, (unsigned)port); - result = newNet; - newNet = NULL; - } - } - flib_netbase_destroy(newNet); - - return result; -} - -void flib_netbase_destroy(flib_netbase *net) { - if(net) { - flib_socket_close(net->sock); - flib_vector_destroy(net->readBuffer); - free(net); - } -} - -bool flib_netbase_connected(flib_netbase *net) { - if(!log_badargs_if(net==NULL) && net->sock) { - return true; - } - return false; -} - -/** - * Parses and returns a message, and removes it from the vector. - */ -static flib_netmsg *parseMessage(flib_vector *vec) { - const uint8_t *partStart = flib_vector_data(vec); - const uint8_t *end = partStart+flib_vector_size(vec); - flib_netmsg *result = flib_netmsg_create(); - if(!result) { - return NULL; - } - - while(1) { - const uint8_t *partEnd = memchr(partStart, '\n', end-partStart); - if(!partEnd) { - // message incomplete - flib_netmsg_destroy(result); - return NULL; - } else if(partEnd-partStart == 0) { - // Zero-length part, message end marker. Remove the message from the vector. - uint8_t *vectorStart = flib_vector_data(vec); - size_t msgLen = partEnd+1-vectorStart; - memmove(vectorStart, partEnd+1, flib_vector_size(vec)-msgLen); - flib_vector_resize(vec, flib_vector_size(vec)-msgLen); - return result; - } else { - if(flib_netmsg_append_part(result, partStart, partEnd-partStart)) { - flib_netmsg_destroy(result); - return NULL; - } - partStart = partEnd+1; // Skip the '\n' - } - } - return NULL; // Never reached -} - -/** - * Receive some bytes and add them to the buffer. - * Returns the number of bytes received. - * Automatically closes the socket if an error occurs - * and sets sock=NULL. - */ -static int receiveToBuffer(flib_netbase *net) { - uint8_t buffer[256]; - if(!net->sock) { - return 0; - } else if(flib_vector_size(net->readBuffer) > NET_READBUFFER_LIMIT) { - flib_log_e("Net connection closed: Net message too big"); - flib_socket_close(net->sock); - net->sock = NULL; - return 0; - } else { - int size = flib_socket_nbrecv(net->sock, buffer, sizeof(buffer)); - if(size>=0 && !flib_vector_append(net->readBuffer, buffer, size)) { - return size; - } else { - flib_socket_close(net->sock); - net->sock = NULL; - return 0; - } - } -} - -flib_netmsg *flib_netbase_recv_message(flib_netbase *net) { - if(log_badargs_if(net==NULL)) { - return NULL; - } - - flib_netmsg *msg; - while(!(msg=parseMessage(net->readBuffer)) - && receiveToBuffer(net)) {} - - if(msg) { - return msg; - } else if(!net->sock && flib_vector_size(net->readBuffer)>0) { - // Connection is down and we didn't get a complete message, just flush the rest. - flib_vector_resize(net->readBuffer, 0); - } - return NULL; -} - -static void logSentMsg(const uint8_t *data, size_t len) { - if(flib_log_isActive(FLIB_LOGLEVEL_DEBUG)) { - flib_log_d("[NET OUT][%03u]%*.*s",(unsigned)len, (unsigned)len, (unsigned)len, data); - } -} - -int flib_netbase_send_raw(flib_netbase *net, const void *data, size_t len) { - if(log_badargs_if2(net==NULL, data==NULL && len>0)) { - return -1; - } - if(!net->sock) { - flib_log_w("flib_netbase_send_raw: Not connected."); - return -1; - } - - if(flib_socket_send(net->sock, data, len) == len) { - logSentMsg(data, len); - return 0; - } else { - flib_log_w("Failed or incomplete write: net connection lost."); - flib_socket_close(net->sock); - net->sock = NULL; - return -1; - } -} - -int flib_netbase_send_message(flib_netbase *net, const flib_netmsg *msg) { - if(log_badargs_if2(net==NULL, msg==NULL)) { - return -1; - } - - size_t totalSize = 0; - for(int i=0; ipartCount; i++) { - totalSize += strlen(msg->parts[i]) + 1; - } - totalSize++; // Last part ends in two '\n' instead of one - - uint8_t *buffer = flib_malloc(totalSize); - if(!buffer) { - return -1; - } - size_t pos = 0; - for(int i=0; ipartCount; i++) { - size_t partsize = strlen(msg->parts[i]); - memcpy(buffer+pos, msg->parts[i], partsize); - pos += partsize; - buffer[pos++] = '\n'; - } - buffer[pos++] = '\n'; - return flib_netbase_send_raw(net, buffer, pos); -} - -int flib_netbase_sendf(flib_netbase *net, const char *format, ...) { - int result = -1; - if(!log_badargs_if2(net==NULL, format==NULL)) { - va_list argp; - va_start(argp, format); - char *buffer = flib_vasprintf(format, argp); - if(buffer) { - result = flib_netbase_send_raw(net, buffer, strlen(buffer)); - } - free(buffer); - va_end(argp); - } - return result; -} - -flib_netmsg *flib_netmsg_create() { - flib_netmsg *result = flib_calloc(1, sizeof(flib_netmsg)); - if(result) { - result->partCount = 0; - result->parts = NULL; - return result; - } else { - return NULL; - } -} - -void flib_netmsg_destroy(flib_netmsg *msg) { - if(msg) { - for(int i=0; ipartCount; i++) { - free(msg->parts[i]); - } - free(msg->parts); - free(msg); - } -} - -int flib_netmsg_append_part(flib_netmsg *msg, const void *part, size_t partlen) { - int result = -1; - if(!log_badargs_if2(msg==NULL, part==NULL && partlen>0)) { - char **newParts = realloc(msg->parts, (msg->partCount+1)*sizeof(*msg->parts)); - if(newParts) { - msg->parts = newParts; - msg->parts[msg->partCount] = flib_malloc(partlen+1); - if(msg->parts[msg->partCount]) { - memcpy(msg->parts[msg->partCount], part, partlen); - msg->parts[msg->partCount][partlen] = 0; - msg->partCount++; - result = 0; - } - } - } - return result; -} +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "netbase.h" +#include "../util/buffer.h" +#include "../util/logging.h" +#include "../util/util.h" +#include "../socket.h" + +#include +#include +#include +#include + +#define NET_READBUFFER_LIMIT (1024*1024) + +struct _flib_netbase { + flib_vector *readBuffer; + flib_tcpsocket *sock; +}; + +flib_netbase *flib_netbase_create(const char *server, uint16_t port) { + if(log_badargs_if2(server==NULL, port==0)) { + return NULL; + } + + flib_netbase *result = NULL; + flib_netbase *newNet = flib_calloc(1, sizeof(flib_netbase)); + + if(newNet) { + newNet->readBuffer = flib_vector_create(); + newNet->sock = flib_socket_connect(server, port); + if(newNet->readBuffer && newNet->sock) { + flib_log_i("Connected to server %s:%u", server, (unsigned)port); + result = newNet; + newNet = NULL; + } + } + flib_netbase_destroy(newNet); + + return result; +} + +void flib_netbase_destroy(flib_netbase *net) { + if(net) { + flib_socket_close(net->sock); + flib_vector_destroy(net->readBuffer); + free(net); + } +} + +bool flib_netbase_connected(flib_netbase *net) { + if(!log_badargs_if(net==NULL) && net->sock) { + return true; + } + return false; +} + +/** + * Parses and returns a message, and removes it from the vector. + */ +static flib_netmsg *parseMessage(flib_vector *vec) { + const uint8_t *partStart = flib_vector_data(vec); + const uint8_t *end = partStart+flib_vector_size(vec); + flib_netmsg *result = flib_netmsg_create(); + if(!result) { + return NULL; + } + + while(1) { + const uint8_t *partEnd = memchr(partStart, '\n', end-partStart); + if(!partEnd) { + // message incomplete + flib_netmsg_destroy(result); + return NULL; + } else if(partEnd-partStart == 0) { + // Zero-length part, message end marker. Remove the message from the vector. + uint8_t *vectorStart = flib_vector_data(vec); + size_t msgLen = partEnd+1-vectorStart; + memmove(vectorStart, partEnd+1, flib_vector_size(vec)-msgLen); + flib_vector_resize(vec, flib_vector_size(vec)-msgLen); + return result; + } else { + if(flib_netmsg_append_part(result, partStart, partEnd-partStart)) { + flib_netmsg_destroy(result); + return NULL; + } + partStart = partEnd+1; // Skip the '\n' + } + } + return NULL; // Never reached +} + +/** + * Receive some bytes and add them to the buffer. + * Returns the number of bytes received. + * Automatically closes the socket if an error occurs + * and sets sock=NULL. + */ +static int receiveToBuffer(flib_netbase *net) { + uint8_t buffer[256]; + if(!net->sock) { + return 0; + } else if(flib_vector_size(net->readBuffer) > NET_READBUFFER_LIMIT) { + flib_log_e("Net connection closed: Net message too big"); + flib_socket_close(net->sock); + net->sock = NULL; + return 0; + } else { + int size = flib_socket_nbrecv(net->sock, buffer, sizeof(buffer)); + if(size>=0 && !flib_vector_append(net->readBuffer, buffer, size)) { + return size; + } else { + flib_socket_close(net->sock); + net->sock = NULL; + return 0; + } + } +} + +flib_netmsg *flib_netbase_recv_message(flib_netbase *net) { + if(log_badargs_if(net==NULL)) { + return NULL; + } + + flib_netmsg *msg; + while(!(msg=parseMessage(net->readBuffer)) + && receiveToBuffer(net)) {} + + if(msg) { + return msg; + } else if(!net->sock && flib_vector_size(net->readBuffer)>0) { + // Connection is down and we didn't get a complete message, just flush the rest. + flib_vector_resize(net->readBuffer, 0); + } + return NULL; +} + +static void logSentMsg(const uint8_t *data, size_t len) { + if(flib_log_isActive(FLIB_LOGLEVEL_DEBUG)) { + flib_log_d("[NET OUT][%03u]%*.*s",(unsigned)len, (unsigned)len, (unsigned)len, data); + } +} + +int flib_netbase_send_raw(flib_netbase *net, const void *data, size_t len) { + if(log_badargs_if2(net==NULL, data==NULL && len>0)) { + return -1; + } + if(!net->sock) { + flib_log_w("flib_netbase_send_raw: Not connected."); + return -1; + } + + if(flib_socket_send(net->sock, data, len) == len) { + logSentMsg(data, len); + return 0; + } else { + flib_log_w("Failed or incomplete write: net connection lost."); + flib_socket_close(net->sock); + net->sock = NULL; + return -1; + } +} + +int flib_netbase_send_message(flib_netbase *net, const flib_netmsg *msg) { + if(log_badargs_if2(net==NULL, msg==NULL)) { + return -1; + } + + size_t totalSize = 0; + for(int i=0; ipartCount; i++) { + totalSize += strlen(msg->parts[i]) + 1; + } + totalSize++; // Last part ends in two '\n' instead of one + + uint8_t *buffer = flib_malloc(totalSize); + if(!buffer) { + return -1; + } + size_t pos = 0; + for(int i=0; ipartCount; i++) { + size_t partsize = strlen(msg->parts[i]); + memcpy(buffer+pos, msg->parts[i], partsize); + pos += partsize; + buffer[pos++] = '\n'; + } + buffer[pos++] = '\n'; + return flib_netbase_send_raw(net, buffer, pos); +} + +int flib_netbase_sendf(flib_netbase *net, const char *format, ...) { + int result = -1; + if(!log_badargs_if2(net==NULL, format==NULL)) { + va_list argp; + va_start(argp, format); + char *buffer = flib_vasprintf(format, argp); + if(buffer) { + result = flib_netbase_send_raw(net, buffer, strlen(buffer)); + } + free(buffer); + va_end(argp); + } + return result; +} + +flib_netmsg *flib_netmsg_create() { + flib_netmsg *result = flib_calloc(1, sizeof(flib_netmsg)); + if(result) { + result->partCount = 0; + result->parts = NULL; + return result; + } else { + return NULL; + } +} + +void flib_netmsg_destroy(flib_netmsg *msg) { + if(msg) { + for(int i=0; ipartCount; i++) { + free(msg->parts[i]); + } + free(msg->parts); + free(msg); + } +} + +int flib_netmsg_append_part(flib_netmsg *msg, const void *part, size_t partlen) { + int result = -1; + if(!log_badargs_if2(msg==NULL, part==NULL && partlen>0)) { + char **newParts = realloc(msg->parts, (msg->partCount+1)*sizeof(*msg->parts)); + if(newParts) { + msg->parts = newParts; + msg->parts[msg->partCount] = flib_malloc(partlen+1); + if(msg->parts[msg->partCount]) { + memcpy(msg->parts[msg->partCount], part, partlen); + msg->parts[msg->partCount][partlen] = 0; + msg->partCount++; + result = 0; + } + } + } + return result; +} diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/net/netbase.h --- a/project_files/frontlib/net/netbase.h Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/net/netbase.h Tue Jan 21 22:43:06 2014 +0100 @@ -1,91 +1,91 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/* - * Low-level protocol support for the network connection - */ - -#ifndef NETBASE_H_ -#define NETBASE_H_ - -#include -#include -#include - -struct _flib_netbase; -typedef struct _flib_netbase flib_netbase; - -typedef struct { - int partCount; - char **parts; -} flib_netmsg; - -/** - * Start a connection to the specified Hedgewars server. - * - * Returns NULL on error. Destroy the created object with flib_netconn_destroy. - */ -flib_netbase *flib_netbase_create(const char *server, uint16_t port); - -/** - * Free resources and close sockets. - */ -void flib_netbase_destroy(flib_netbase *net); - -/** - * Determine the current connection state. Starts out true, and turns to - * false when we are disconnected from the server. - */ -bool flib_netbase_connected(flib_netbase *net); - -/** - * Receive a new message and return it as a flib_netmsg. The netmsg has to be - * destroyed with flib_netmsg_destroy after use. - * Returns NULL if no message is available. - * - * Note: When a connection is closed, you probably want to call this function until - * no further message is returned, to ensure you see all messages that were sent - * before the connection closed. - */ -flib_netmsg *flib_netbase_recv_message(flib_netbase *net); - -int flib_netbase_send_raw(flib_netbase *net, const void *data, size_t len); - -/** - * Write a single message to the server. This call blocks until the - * message is completely written or the connection is closed or an error occurs. - * - * Returns a negative value on failure. - */ -int flib_netbase_send_message(flib_netbase *net, const flib_netmsg *msg); - -/** - * Send a message printf-style. - * - * flib_netbase_sendf(net, "%s\n\n", "TOGGLE_READY"); - * flib_netbase_sendf(net, "%s\n%s\n%i\n\n", "CFG", "MAPGEN", MAPGEN_MAZE); - */ -int flib_netbase_sendf(flib_netbase *net, const char *format, ...); - -flib_netmsg *flib_netmsg_create(); -void flib_netmsg_destroy(flib_netmsg *msg); -int flib_netmsg_append_part(flib_netmsg *msg, const void *param, size_t len); - -#endif /* NETBASE_H_ */ - +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * Low-level protocol support for the network connection + */ + +#ifndef NETBASE_H_ +#define NETBASE_H_ + +#include +#include +#include + +struct _flib_netbase; +typedef struct _flib_netbase flib_netbase; + +typedef struct { + int partCount; + char **parts; +} flib_netmsg; + +/** + * Start a connection to the specified Hedgewars server. + * + * Returns NULL on error. Destroy the created object with flib_netconn_destroy. + */ +flib_netbase *flib_netbase_create(const char *server, uint16_t port); + +/** + * Free resources and close sockets. + */ +void flib_netbase_destroy(flib_netbase *net); + +/** + * Determine the current connection state. Starts out true, and turns to + * false when we are disconnected from the server. + */ +bool flib_netbase_connected(flib_netbase *net); + +/** + * Receive a new message and return it as a flib_netmsg. The netmsg has to be + * destroyed with flib_netmsg_destroy after use. + * Returns NULL if no message is available. + * + * Note: When a connection is closed, you probably want to call this function until + * no further message is returned, to ensure you see all messages that were sent + * before the connection closed. + */ +flib_netmsg *flib_netbase_recv_message(flib_netbase *net); + +int flib_netbase_send_raw(flib_netbase *net, const void *data, size_t len); + +/** + * Write a single message to the server. This call blocks until the + * message is completely written or the connection is closed or an error occurs. + * + * Returns a negative value on failure. + */ +int flib_netbase_send_message(flib_netbase *net, const flib_netmsg *msg); + +/** + * Send a message printf-style. + * + * flib_netbase_sendf(net, "%s\n\n", "TOGGLE_READY"); + * flib_netbase_sendf(net, "%s\n%s\n%i\n\n", "CFG", "MAPGEN", MAPGEN_MAZE); + */ +int flib_netbase_sendf(flib_netbase *net, const char *format, ...); + +flib_netmsg *flib_netmsg_create(); +void flib_netmsg_destroy(flib_netmsg *msg); +int flib_netmsg_append_part(flib_netmsg *msg, const void *param, size_t len); + +#endif /* NETBASE_H_ */ + diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/net/netconn.c --- a/project_files/frontlib/net/netconn.c Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/net/netconn.c Tue Jan 21 22:43:06 2014 +0100 @@ -1,613 +1,613 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2008 Igor Ulyanov - * Copyright (c) 2004-2014 Andrey Korotaev - * Copyright (c) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include "netconn_internal.h" -#include "netprotocol.h" -#include "../util/logging.h" -#include "../util/util.h" -#include "../md5/md5.h" -#include "../base64/base64.h" -#include "../model/mapcfg.h" - -#include -#include -#include -#include - -flib_netconn *flib_netconn_create(const char *playerName, const char *dataDirPath, const char *host, int port) { - flib_netconn *result = NULL; - if(!log_badargs_if4(playerName==NULL, host==NULL, port<1, port>65535)) { - flib_netconn *newConn = flib_calloc(1, sizeof(flib_netconn)); - if(newConn) { - newConn->netBase = flib_netbase_create(host, port); - newConn->playerName = flib_strdupnull(playerName); - newConn->dataDirPath = flib_strdupnull(dataDirPath); - - newConn->netconnState = NETCONN_STATE_CONNECTING; - - newConn->isChief = false; - newConn->map = flib_map_create_named("", "NoSuchMap"); - newConn->pendingTeamlist.teamCount = 0; - newConn->pendingTeamlist.teams = NULL; - newConn->teamlist.teamCount = 0; - newConn->teamlist.teams = NULL; - newConn->scheme = NULL; - newConn->style = NULL; - newConn->weaponset = NULL; - - newConn->running = false; - newConn->destroyRequested = false; - netconn_clearCallbacks(newConn); - if(newConn->netBase && newConn->playerName && newConn->dataDirPath && newConn->map) { - result = newConn; - newConn = NULL; - } - } - flib_netconn_destroy(newConn); - } - return result; -} - -void flib_netconn_destroy(flib_netconn *conn) { - if(conn) { - if(conn->running) { - /* - * The function was called from a callback, so the tick function is still running - * and we delay the actual destruction. We ensure no further callbacks will be - * sent to prevent surprises. - */ - netconn_clearCallbacks(conn); - conn->destroyRequested = true; - } else { - flib_netbase_destroy(conn->netBase); - free(conn->playerName); - free(conn->dataDirPath); - - flib_map_destroy(conn->map); - flib_teamlist_clear(&conn->pendingTeamlist); - flib_teamlist_clear(&conn->teamlist); - flib_scheme_destroy(conn->scheme); - free(conn->style); - flib_weaponset_destroy(conn->weaponset); - - free(conn); - } - } -} - -bool flib_netconn_is_chief(flib_netconn *conn) { - if(!log_badargs_if(conn==NULL) && conn->netconnState==NETCONN_STATE_ROOM) { - return conn->isChief; - } - return false; -} - -const char *flib_netconn_get_playername(flib_netconn *conn) { - if(!log_badargs_if(conn==NULL)) { - return conn->playerName; - } - return NULL; -} - -void netconn_leaveRoom(flib_netconn *conn) { - conn->netconnState = NETCONN_STATE_LOBBY; - conn->isChief = false; - flib_map_destroy(conn->map); - conn->map = flib_map_create_named("", "NoSuchMap"); - flib_teamlist_clear(&conn->pendingTeamlist); - flib_teamlist_clear(&conn->teamlist); - flib_scheme_destroy(conn->scheme); - conn->scheme = NULL; - free(conn->style); - conn->style = NULL; - flib_weaponset_destroy(conn->weaponset); - conn->weaponset = NULL; -} - -void netconn_setMap(flib_netconn *conn, const flib_map *map) { - flib_map *copy = flib_map_copy(map); - if(copy) { - flib_map_destroy(conn->map); - conn->map = copy; - } -} - -void netconn_setWeaponset(flib_netconn *conn, const flib_weaponset *weaponset) { - flib_weaponset *copy = flib_weaponset_copy(weaponset); - if(copy) { - flib_weaponset_destroy(conn->weaponset); - conn->weaponset = copy; - } -} - -void netconn_setScript(flib_netconn *conn, const char *script) { - char *copy = flib_strdupnull(script); - if(copy) { - free(conn->style); - conn->style = copy; - } -} - -void netconn_setScheme(flib_netconn *conn, const flib_scheme *scheme) { - flib_scheme *copy = flib_scheme_copy(scheme); - if(copy) { - flib_scheme_destroy(conn->scheme); - conn->scheme = copy; - } -} - -flib_gamesetup *flib_netconn_create_gamesetup(flib_netconn *conn) { - flib_gamesetup *result = NULL; - if(!log_badargs_if(conn==NULL)) { - if(conn->teamlist.teamCount==0 || !conn->scheme || !conn->weaponset) { - flib_log_e("Incomplete room state"); - } else { - flib_gamesetup stackSetup = {0}; - stackSetup.gamescheme = conn->scheme; - stackSetup.map = conn->map; - stackSetup.style = conn->style; - stackSetup.teamlist = &conn->teamlist; - result = flib_gamesetup_copy(&stackSetup); - if(result) { - bool error = false; - for(int i=0; iteamlist->teamCount; i++) { - if(flib_team_set_weaponset(result->teamlist->teams[i], conn->weaponset)) { - error = true; - } - flib_team_set_health(result->teamlist->teams[i], flib_scheme_get_setting(conn->scheme, "health", 100)); - } - if(result->map->mapgen == MAPGEN_NAMED && result->map->name) { - flib_mapcfg mapcfg; - if(!flib_mapcfg_read(conn->dataDirPath, result->map->name, &mapcfg)) { - free(result->map->theme); - result->map->theme = flib_strdupnull(mapcfg.theme); - if(!result->map->theme) { - error = true; - } - } else { - flib_log_e("Unable to read map config for map %s", result->map->name); - } - } - if(error) { - flib_gamesetup_destroy(result); - result = NULL; - } - } - } - } - return result; -} - -static void flib_netconn_wrappedtick(flib_netconn *conn) { - flib_netmsg *netmsg; - flib_netbase *net = conn->netBase; - bool exit = false; - - while(!exit && !conn->destroyRequested && (netmsg=flib_netbase_recv_message(conn->netBase))) { - if(netmsg->partCount==0) { - flib_log_w("Empty server message"); - continue; - } - - if(flib_log_isActive(FLIB_LOGLEVEL_DEBUG)) { - char *buf = flib_join(netmsg->parts, netmsg->partCount, "|"); - if(buf) { - flib_log_d("[Net In]%s", buf); - } - free(buf); - } - - const char *cmd = netmsg->parts[0]; - - if (!strcmp(cmd, "NICK") && netmsg->partCount>=2) { - if(netmsg->partCount<2) { - flib_log_w("Net: Malformed NICK message"); - } else { - char *nick = flib_strdupnull(netmsg->parts[1]); - if(nick) { - free(conn->playerName); - conn->playerName = nick; - } else { - conn->netconnState = NETCONN_STATE_DISCONNECTED; - conn->onDisconnectedCb(conn->onDisconnectedCtx, NETCONN_DISCONNECT_INTERNAL_ERROR, "Out of memory"); - exit = true; - } - } - } else if (!strcmp(cmd, "PROTO")) { - // The server just echoes this back apparently - } else if (!strcmp(cmd, "ERROR")) { - if (netmsg->partCount >= 2) { - conn->onMessageCb(conn->onMessageCtx, NETCONN_MSG_TYPE_ERROR, netmsg->parts[1]); - } else { - conn->onMessageCb(conn->onMessageCtx, NETCONN_MSG_TYPE_ERROR, "Unknown Error"); - } - } else if(!strcmp(cmd, "WARNING")) { - if (netmsg->partCount >= 2) { - conn->onMessageCb(conn->onMessageCtx, NETCONN_MSG_TYPE_WARNING, netmsg->parts[1]); - } else { - conn->onMessageCb(conn->onMessageCtx, NETCONN_MSG_TYPE_WARNING, "Unknown Warning"); - } - } else if(!strcmp(cmd, "CONNECTED")) { - if(netmsg->partCount<3 || atol(netmsg->parts[2])netconnState = NETCONN_STATE_DISCONNECTED; - conn->onDisconnectedCb(conn->onDisconnectedCtx, NETCONN_DISCONNECT_SERVER_TOO_OLD, "Server too old"); - exit = true; - } else { - flib_netbase_sendf(net, "%s\n%s\n\n", "NICK", conn->playerName); - flib_netbase_sendf(net, "%s\n%i\n\n", "PROTO", (int)PROTOCOL_VERSION); - } - } else if(!strcmp(cmd, "PING")) { - if (netmsg->partCount > 1) { - flib_netbase_sendf(net, "%s\n%s\n\n", "PONG", netmsg->parts[1]); - } else { - flib_netbase_sendf(net, "%s\n\n", "PONG"); - } - } else if(!strcmp(cmd, "ROOMS")) { - if(netmsg->partCount % 8 != 1) { - flib_log_w("Net: Malformed ROOMS message"); - } else { - int roomCount = netmsg->partCount/8; - flib_room **rooms = flib_room_array_from_netmsg(netmsg->parts+1, roomCount); - if(rooms) { - conn->onRoomlistCb(conn->onRoomlistCtx, (const flib_room**)rooms, roomCount); - for(int i=0; ipartCount < 2) { - flib_log_w("Net: Empty SERVERMESSAGE message"); - } else { - conn->onMessageCb(conn->onMessageCtx, NETCONN_MSG_TYPE_SERVERMESSAGE, netmsg->parts[1]); - } - } else if (!strcmp(cmd, "CHAT")) { - if(netmsg->partCount < 3) { - flib_log_w("Net: Empty CHAT message"); - } else { - conn->onChatCb(conn->onChatCtx, netmsg->parts[1], netmsg->parts[2]); - } - } else if (!strcmp(cmd, "INFO")) { - if(netmsg->partCount < 5) { - flib_log_w("Net: Malformed INFO message"); - } else { - char *joined = flib_join(netmsg->parts+1, netmsg->partCount-1, "\n"); - if(joined) { - conn->onMessageCb(conn->onMessageCtx, NETCONN_MSG_TYPE_PLAYERINFO, joined); - } - free(joined); - } - } else if(!strcmp(cmd, "SERVER_VARS")) { - for(int offset=1; offset+2partCount; offset+=2) { - conn->onServerVarCb(conn->onServerVarCtx, netmsg->parts[offset], netmsg->parts[offset+1]); - } - } else if (!strcmp(cmd, "CLIENT_FLAGS")) { - if(netmsg->partCount < 3 || strlen(netmsg->parts[1]) < 2) { - flib_log_w("Net: Malformed CLIENT_FLAGS message"); - } else { - const char *flags = netmsg->parts[1]; - bool setFlag = flags[0] == '+'; - - for(int j = 2; j < netmsg->partCount; ++j) { - bool isSelf = !strcmp(conn->playerName, netmsg->parts[j]); - if(isSelf && strchr(flags, 'h')) { - conn->isChief = setFlag; - } - conn->onClientFlagsCb(conn->onClientFlagsCtx, netmsg->parts[j], flags+1, setFlag); - } - } - } else if (!strcmp(cmd, "ADD_TEAM")) { - if(netmsg->partCount != 24 || conn->netconnState!=NETCONN_STATE_ROOM) { - flib_log_w("Net: Bad ADD_TEAM message"); - } else { - flib_team *team = flib_team_from_netmsg(netmsg->parts+1); - if(!team || flib_teamlist_insert(&conn->teamlist, team, conn->teamlist.teamCount)) { - flib_team_destroy(team); - conn->netconnState = NETCONN_STATE_DISCONNECTED; - conn->onDisconnectedCb(conn->onDisconnectedCtx, NETCONN_DISCONNECT_INTERNAL_ERROR, "Internal error"); - exit = true; - } else { - conn->onTeamAddCb(conn->onTeamAddCtx, team); - } - } - } else if (!strcmp(cmd, "REMOVE_TEAM")) { - if(netmsg->partCount != 2 || conn->netconnState!=NETCONN_STATE_ROOM) { - flib_log_w("Net: Bad REMOVETEAM message"); - } else { - flib_teamlist_delete(&conn->teamlist, netmsg->parts[1]); - conn->onTeamDeleteCb(conn->onTeamDeleteCtx, netmsg->parts[1]); - } - } else if(!strcmp(cmd, "ROOMABANDONED")) { - netconn_leaveRoom(conn); - conn->onLeaveRoomCb(conn->onLeaveRoomCtx, NETCONN_ROOMLEAVE_ABANDONED, "Room destroyed"); - } else if(!strcmp(cmd, "KICKED")) { - netconn_leaveRoom(conn); - conn->onLeaveRoomCb(conn->onLeaveRoomCtx, NETCONN_ROOMLEAVE_KICKED, "You got kicked"); - } else if(!strcmp(cmd, "JOINED")) { - if(netmsg->partCount < 2) { - flib_log_w("Net: Bad JOINED message"); - } else { - for(int i = 1; i < netmsg->partCount; ++i) - { - bool isMe = !strcmp(conn->playerName, netmsg->parts[i]); - if (isMe) { - conn->netconnState = NETCONN_STATE_ROOM; - conn->onEnterRoomCb(conn->onEnterRoomCtx, conn->isChief); - } - - conn->onRoomJoinCb(conn->onRoomJoinCtx, netmsg->parts[i]); - } - } - } else if(!strcmp(cmd, "LOBBY:JOINED")) { - if(netmsg->partCount < 2) { - flib_log_w("Net: Bad JOINED message"); - } else { - for(int i = 1; i < netmsg->partCount; ++i) - { - bool isMe = !strcmp(conn->playerName, netmsg->parts[i]); - if (isMe && conn->netconnState == NETCONN_STATE_CONNECTING) { - conn->onConnectedCb(conn->onConnectedCtx); - conn->netconnState = NETCONN_STATE_LOBBY; - } - conn->onLobbyJoinCb(conn->onLobbyJoinCtx, netmsg->parts[i]); - } - } - } else if(!strcmp(cmd, "LEFT")) { - if(netmsg->partCount < 2) { - flib_log_w("Net: Bad LEFT message"); - } else { - conn->onRoomLeaveCb(conn->onRoomLeaveCtx, netmsg->parts[1], netmsg->partCount>2 ? netmsg->parts[2] : NULL); - } - } else if(!strcmp(cmd, "ROOM") && netmsg->partCount >= 2) { - const char *subcmd = netmsg->parts[1]; - if(!strcmp(subcmd, "ADD") && netmsg->partCount == 10) { - flib_room *room = flib_room_from_netmsg(netmsg->parts+2); - if(room) { - conn->onRoomAddCb(conn->onRoomAddCtx, room); - } - flib_room_destroy(room); - } else if(!strcmp(subcmd, "UPD") && netmsg->partCount == 11) { - flib_room *room = flib_room_from_netmsg(netmsg->parts+3); - if(room) { - conn->onRoomUpdateCb(conn->onRoomUpdateCtx, netmsg->parts[2], room); - } - flib_room_destroy(room); - } else if(!strcmp(subcmd, "DEL") && netmsg->partCount == 3) { - conn->onRoomDeleteCb(conn->onRoomDeleteCtx, netmsg->parts[2]); - } else { - flib_log_w("Net: Unknown or malformed ROOM subcommand: %s", subcmd); - } - } else if(!strcmp(cmd, "LOBBY:LEFT")) { - if(netmsg->partCount < 2) { - flib_log_w("Net: Bad LOBBY:LEFT message"); - } else { - conn->onLobbyLeaveCb(conn->onLobbyLeaveCtx, netmsg->parts[1], netmsg->partCount>2 ? netmsg->parts[2] : NULL); - } - } else if (!strcmp(cmd, "RUN_GAME")) { - conn->onRunGameCb(conn->onRunGameCtx); - } else if (!strcmp(cmd, "ASKPASSWORD")) { - conn->onPasswordRequestCb(conn->onPasswordRequestCtx, conn->playerName); - } else if (!strcmp(cmd, "NOTICE")) { - if(netmsg->partCount < 2) { - flib_log_w("Net: Bad NOTICE message"); - } else { - errno = 0; - long n = strtol(netmsg->parts[1], NULL, 10); - if(errno) { - flib_log_w("Net: Bad NOTICE message"); - } else if(n==0) { - conn->onNickTakenCb(conn->onNickTakenCtx, conn->playerName); - } else { - flib_log_w("Net: Unknown NOTICE message: %l", n); - } - } - } else if (!strcmp(cmd, "TEAM_ACCEPTED")) { - if (netmsg->partCount != 2 || conn->netconnState!=NETCONN_STATE_ROOM) { - flib_log_w("Net: Bad TEAM_ACCEPTED message"); - } else { - flib_team *team = flib_team_copy(flib_teamlist_find(&conn->pendingTeamlist, netmsg->parts[1])); - if(team) { - flib_teamlist_insert(&conn->teamlist, team, conn->teamlist.teamCount); - flib_teamlist_delete(&conn->pendingTeamlist, netmsg->parts[1]); - } else { - flib_log_e("Team accepted that was not requested: %s", netmsg->parts[1]); - } - conn->onTeamAcceptedCb(conn->onTeamAcceptedCtx, netmsg->parts[1]); - } - } else if (!strcmp(cmd, "CFG")) { - if(netmsg->partCount < 3 || conn->netconnState!=NETCONN_STATE_ROOM) { - flib_log_w("Net: Bad CFG message"); - } else { - const char *subcmd = netmsg->parts[1]; - if(!strcmp(subcmd, "SCHEME") && netmsg->partCount == flib_meta.modCount + flib_meta.settingCount + 3) { - flib_scheme *cfg = flib_scheme_from_netmsg(netmsg->parts+2); - if(cfg) { - flib_scheme_destroy(conn->scheme); - conn->scheme = cfg; - conn->onSchemeChangedCb(conn->onSchemeChangedCtx, cfg); - } else { - flib_log_e("Error processing CFG SCHEME message"); - } - } else if(!strcmp(subcmd, "FULLMAPCONFIG") && netmsg->partCount == 7) { - flib_map *map = flib_map_from_netmsg(netmsg->parts+2); - if(map) { - flib_map_destroy(conn->map); - conn->map = map; - conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_FULL); - } else { - flib_log_e("Error processing CFG FULLMAPCONFIG message"); - } - } else if(!strcmp(subcmd, "MAP") && netmsg->partCount == 3) { - char *mapname = flib_strdupnull(netmsg->parts[2]); - if(mapname) { - free(conn->map->name); - conn->map->name = mapname; - conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_MAP); - } else { - flib_log_e("Error processing CFG MAP message"); - } - } else if(!strcmp(subcmd, "THEME") && netmsg->partCount == 3) { - char *themename = flib_strdupnull(netmsg->parts[2]); - if(themename) { - free(conn->map->theme); - conn->map->theme = themename; - conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_THEME); - } else { - flib_log_e("Error processing CFG THEME message"); - } - } else if(!strcmp(subcmd, "SEED") && netmsg->partCount == 3) { - char *seed = flib_strdupnull(netmsg->parts[2]); - if(seed) { - free(conn->map->seed); - conn->map->seed = seed; - conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_SEED); - } else { - flib_log_e("Error processing CFG SEED message"); - } - } else if(!strcmp(subcmd, "TEMPLATE") && netmsg->partCount == 3) { - conn->map->templateFilter = atoi(netmsg->parts[2]); - conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_TEMPLATE); - } else if(!strcmp(subcmd, "MAPGEN") && netmsg->partCount == 3) { - conn->map->mapgen = atoi(netmsg->parts[2]); - conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_MAPGEN); - } else if(!strcmp(subcmd, "MAZE_SIZE") && netmsg->partCount == 3) { - conn->map->mazeSize = atoi(netmsg->parts[2]); - conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_MAZE_SIZE); - } else if(!strcmp(subcmd, "DRAWNMAP") && netmsg->partCount == 3) { - size_t drawnMapSize = 0; - uint8_t *drawnMapData = NULL; - if(!flib_drawnmapdata_from_netmsg(netmsg->parts[2], &drawnMapData, &drawnMapSize)) { - free(conn->map->drawData); - conn->map->drawData = drawnMapData; - conn->map->drawDataSize = drawnMapSize; - conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_DRAWNMAP); - } else { - flib_log_e("Error processing CFG DRAWNMAP message"); - } - } else if(!strcmp(subcmd, "SCRIPT") && netmsg->partCount == 3) { - netconn_setScript(conn, netmsg->parts[2]); - conn->onScriptChangedCb(conn->onScriptChangedCtx, netmsg->parts[2]); - } else if(!strcmp(subcmd, "AMMO") && netmsg->partCount == 4) { - flib_weaponset *weapons = flib_weaponset_from_ammostring(netmsg->parts[2], netmsg->parts[3]); - if(weapons) { - flib_weaponset_destroy(conn->weaponset); - conn->weaponset = weapons; - conn->onWeaponsetChangedCb(conn->onWeaponsetChangedCtx, weapons); - } else { - flib_log_e("Error processing CFG AMMO message"); - } - } else { - flib_log_w("Net: Unknown or malformed CFG subcommand: %s", subcmd); - } - } - } else if (!strcmp(cmd, "HH_NUM")) { - if (netmsg->partCount != 3 || conn->netconnState!=NETCONN_STATE_ROOM) { - flib_log_w("Net: Bad HH_NUM message"); - } else { - int hogs = atoi(netmsg->parts[2]); - if(hogs<=0 || hogs>HEDGEHOGS_PER_TEAM) { - flib_log_w("Net: Bad HH_NUM message: %s hogs", netmsg->parts[2]); - } else { - flib_team *team = flib_teamlist_find(&conn->teamlist, netmsg->parts[1]); - if(team) { - team->hogsInGame = hogs; - } else { - flib_log_e("HH_NUM message for unknown team %s", netmsg->parts[1]); - } - conn->onHogCountChangedCb(conn->onHogCountChangedCtx, netmsg->parts[1], hogs); - } - } - } else if (!strcmp(cmd, "TEAM_COLOR")) { - if (netmsg->partCount != 3 || conn->netconnState!=NETCONN_STATE_ROOM) { - flib_log_w("Net: Bad TEAM_COLOR message"); - } else { - long color; - if(sscanf(netmsg->parts[2], "%lu", &color) && color>=0 && colorteamlist, netmsg->parts[1]); - if(team) { - team->colorIndex = color; - } else { - flib_log_e("TEAM_COLOR message for unknown team %s", netmsg->parts[1]); - } - conn->onTeamColorChangedCb(conn->onTeamColorChangedCtx, netmsg->parts[1], color); - } else { - flib_log_w("Net: Bad TEAM_COLOR message: Color %s", netmsg->parts[2]); - } - } - } else if (!strcmp(cmd, "EM")) { - if(netmsg->partCount < 2) { - flib_log_w("Net: Bad EM message"); - } else { - for(int i = 1; i < netmsg->partCount; ++i) { - char *out = NULL; - size_t outlen; - bool ok = base64_decode_alloc(netmsg->parts[i], strlen(netmsg->parts[i]), &out, &outlen); - if(ok && outlen) { - conn->onEngineMessageCb(conn->onEngineMessageCtx, (uint8_t*)out, outlen); - } else { - flib_log_e("Net: Malformed engine message: %s", netmsg->parts[i]); - } - free(out); - } - } - } else if (!strcmp(cmd, "BYE")) { - if (netmsg->partCount < 2) { - flib_log_w("Net: Bad BYE message"); - } else { - conn->netconnState = NETCONN_STATE_DISCONNECTED; - if (!strcmp(netmsg->parts[1], "Authentication failed")) { - conn->onDisconnectedCb(conn->onDisconnectedCtx, NETCONN_DISCONNECT_AUTH_FAILED, netmsg->parts[1]); - } else { - conn->onDisconnectedCb(conn->onDisconnectedCtx, NETCONN_DISCONNECT_NORMAL, netmsg->parts[1]); - } - exit = true; - } - } else if (!strcmp(cmd, "ADMIN_ACCESS")) { - // deprecated - } else if (!strcmp(cmd, "ROOM_CONTROL_ACCESS")) { - // deprecated - } else { - flib_log_w("Unknown server command: %s", cmd); - } - flib_netmsg_destroy(netmsg); - } - - if(!exit && !conn->destroyRequested && !flib_netbase_connected(net)) { - conn->netconnState = NETCONN_STATE_DISCONNECTED; - conn->onDisconnectedCb(conn->onDisconnectedCtx, NETCONN_DISCONNECT_CONNLOST, "Connection lost"); - } -} - -void flib_netconn_tick(flib_netconn *conn) { - if(!log_badargs_if(conn==NULL) - && !log_w_if(conn->running, "Call to flib_netconn_tick from a callback") - && !log_w_if(conn->netconnState == NETCONN_STATE_DISCONNECTED, "We are already done.")) { - conn->running = true; - flib_netconn_wrappedtick(conn); - conn->running = false; - - if(conn->destroyRequested) { - flib_netconn_destroy(conn); - } - } -} +/* + * Hedgewars, a free turn based strategy game + * Copyright (c) 2006-2008 Igor Ulyanov + * Copyright (c) 2004-2014 Andrey Korotaev + * Copyright (c) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "netconn_internal.h" +#include "netprotocol.h" +#include "../util/logging.h" +#include "../util/util.h" +#include "../md5/md5.h" +#include "../base64/base64.h" +#include "../model/mapcfg.h" + +#include +#include +#include +#include + +flib_netconn *flib_netconn_create(const char *playerName, const char *dataDirPath, const char *host, int port) { + flib_netconn *result = NULL; + if(!log_badargs_if4(playerName==NULL, host==NULL, port<1, port>65535)) { + flib_netconn *newConn = flib_calloc(1, sizeof(flib_netconn)); + if(newConn) { + newConn->netBase = flib_netbase_create(host, port); + newConn->playerName = flib_strdupnull(playerName); + newConn->dataDirPath = flib_strdupnull(dataDirPath); + + newConn->netconnState = NETCONN_STATE_CONNECTING; + + newConn->isChief = false; + newConn->map = flib_map_create_named("", "NoSuchMap"); + newConn->pendingTeamlist.teamCount = 0; + newConn->pendingTeamlist.teams = NULL; + newConn->teamlist.teamCount = 0; + newConn->teamlist.teams = NULL; + newConn->scheme = NULL; + newConn->style = NULL; + newConn->weaponset = NULL; + + newConn->running = false; + newConn->destroyRequested = false; + netconn_clearCallbacks(newConn); + if(newConn->netBase && newConn->playerName && newConn->dataDirPath && newConn->map) { + result = newConn; + newConn = NULL; + } + } + flib_netconn_destroy(newConn); + } + return result; +} + +void flib_netconn_destroy(flib_netconn *conn) { + if(conn) { + if(conn->running) { + /* + * The function was called from a callback, so the tick function is still running + * and we delay the actual destruction. We ensure no further callbacks will be + * sent to prevent surprises. + */ + netconn_clearCallbacks(conn); + conn->destroyRequested = true; + } else { + flib_netbase_destroy(conn->netBase); + free(conn->playerName); + free(conn->dataDirPath); + + flib_map_destroy(conn->map); + flib_teamlist_clear(&conn->pendingTeamlist); + flib_teamlist_clear(&conn->teamlist); + flib_scheme_destroy(conn->scheme); + free(conn->style); + flib_weaponset_destroy(conn->weaponset); + + free(conn); + } + } +} + +bool flib_netconn_is_chief(flib_netconn *conn) { + if(!log_badargs_if(conn==NULL) && conn->netconnState==NETCONN_STATE_ROOM) { + return conn->isChief; + } + return false; +} + +const char *flib_netconn_get_playername(flib_netconn *conn) { + if(!log_badargs_if(conn==NULL)) { + return conn->playerName; + } + return NULL; +} + +void netconn_leaveRoom(flib_netconn *conn) { + conn->netconnState = NETCONN_STATE_LOBBY; + conn->isChief = false; + flib_map_destroy(conn->map); + conn->map = flib_map_create_named("", "NoSuchMap"); + flib_teamlist_clear(&conn->pendingTeamlist); + flib_teamlist_clear(&conn->teamlist); + flib_scheme_destroy(conn->scheme); + conn->scheme = NULL; + free(conn->style); + conn->style = NULL; + flib_weaponset_destroy(conn->weaponset); + conn->weaponset = NULL; +} + +void netconn_setMap(flib_netconn *conn, const flib_map *map) { + flib_map *copy = flib_map_copy(map); + if(copy) { + flib_map_destroy(conn->map); + conn->map = copy; + } +} + +void netconn_setWeaponset(flib_netconn *conn, const flib_weaponset *weaponset) { + flib_weaponset *copy = flib_weaponset_copy(weaponset); + if(copy) { + flib_weaponset_destroy(conn->weaponset); + conn->weaponset = copy; + } +} + +void netconn_setScript(flib_netconn *conn, const char *script) { + char *copy = flib_strdupnull(script); + if(copy) { + free(conn->style); + conn->style = copy; + } +} + +void netconn_setScheme(flib_netconn *conn, const flib_scheme *scheme) { + flib_scheme *copy = flib_scheme_copy(scheme); + if(copy) { + flib_scheme_destroy(conn->scheme); + conn->scheme = copy; + } +} + +flib_gamesetup *flib_netconn_create_gamesetup(flib_netconn *conn) { + flib_gamesetup *result = NULL; + if(!log_badargs_if(conn==NULL)) { + if(conn->teamlist.teamCount==0 || !conn->scheme || !conn->weaponset) { + flib_log_e("Incomplete room state"); + } else { + flib_gamesetup stackSetup = {0}; + stackSetup.gamescheme = conn->scheme; + stackSetup.map = conn->map; + stackSetup.style = conn->style; + stackSetup.teamlist = &conn->teamlist; + result = flib_gamesetup_copy(&stackSetup); + if(result) { + bool error = false; + for(int i=0; iteamlist->teamCount; i++) { + if(flib_team_set_weaponset(result->teamlist->teams[i], conn->weaponset)) { + error = true; + } + flib_team_set_health(result->teamlist->teams[i], flib_scheme_get_setting(conn->scheme, "health", 100)); + } + if(result->map->mapgen == MAPGEN_NAMED && result->map->name) { + flib_mapcfg mapcfg; + if(!flib_mapcfg_read(conn->dataDirPath, result->map->name, &mapcfg)) { + free(result->map->theme); + result->map->theme = flib_strdupnull(mapcfg.theme); + if(!result->map->theme) { + error = true; + } + } else { + flib_log_e("Unable to read map config for map %s", result->map->name); + } + } + if(error) { + flib_gamesetup_destroy(result); + result = NULL; + } + } + } + } + return result; +} + +static void flib_netconn_wrappedtick(flib_netconn *conn) { + flib_netmsg *netmsg; + flib_netbase *net = conn->netBase; + bool exit = false; + + while(!exit && !conn->destroyRequested && (netmsg=flib_netbase_recv_message(conn->netBase))) { + if(netmsg->partCount==0) { + flib_log_w("Empty server message"); + continue; + } + + if(flib_log_isActive(FLIB_LOGLEVEL_DEBUG)) { + char *buf = flib_join(netmsg->parts, netmsg->partCount, "|"); + if(buf) { + flib_log_d("[Net In]%s", buf); + } + free(buf); + } + + const char *cmd = netmsg->parts[0]; + + if (!strcmp(cmd, "NICK") && netmsg->partCount>=2) { + if(netmsg->partCount<2) { + flib_log_w("Net: Malformed NICK message"); + } else { + char *nick = flib_strdupnull(netmsg->parts[1]); + if(nick) { + free(conn->playerName); + conn->playerName = nick; + } else { + conn->netconnState = NETCONN_STATE_DISCONNECTED; + conn->onDisconnectedCb(conn->onDisconnectedCtx, NETCONN_DISCONNECT_INTERNAL_ERROR, "Out of memory"); + exit = true; + } + } + } else if (!strcmp(cmd, "PROTO")) { + // The server just echoes this back apparently + } else if (!strcmp(cmd, "ERROR")) { + if (netmsg->partCount >= 2) { + conn->onMessageCb(conn->onMessageCtx, NETCONN_MSG_TYPE_ERROR, netmsg->parts[1]); + } else { + conn->onMessageCb(conn->onMessageCtx, NETCONN_MSG_TYPE_ERROR, "Unknown Error"); + } + } else if(!strcmp(cmd, "WARNING")) { + if (netmsg->partCount >= 2) { + conn->onMessageCb(conn->onMessageCtx, NETCONN_MSG_TYPE_WARNING, netmsg->parts[1]); + } else { + conn->onMessageCb(conn->onMessageCtx, NETCONN_MSG_TYPE_WARNING, "Unknown Warning"); + } + } else if(!strcmp(cmd, "CONNECTED")) { + if(netmsg->partCount<3 || atol(netmsg->parts[2])netconnState = NETCONN_STATE_DISCONNECTED; + conn->onDisconnectedCb(conn->onDisconnectedCtx, NETCONN_DISCONNECT_SERVER_TOO_OLD, "Server too old"); + exit = true; + } else { + flib_netbase_sendf(net, "%s\n%s\n\n", "NICK", conn->playerName); + flib_netbase_sendf(net, "%s\n%i\n\n", "PROTO", (int)PROTOCOL_VERSION); + } + } else if(!strcmp(cmd, "PING")) { + if (netmsg->partCount > 1) { + flib_netbase_sendf(net, "%s\n%s\n\n", "PONG", netmsg->parts[1]); + } else { + flib_netbase_sendf(net, "%s\n\n", "PONG"); + } + } else if(!strcmp(cmd, "ROOMS")) { + if(netmsg->partCount % 8 != 1) { + flib_log_w("Net: Malformed ROOMS message"); + } else { + int roomCount = netmsg->partCount/8; + flib_room **rooms = flib_room_array_from_netmsg(netmsg->parts+1, roomCount); + if(rooms) { + conn->onRoomlistCb(conn->onRoomlistCtx, (const flib_room**)rooms, roomCount); + for(int i=0; ipartCount < 2) { + flib_log_w("Net: Empty SERVERMESSAGE message"); + } else { + conn->onMessageCb(conn->onMessageCtx, NETCONN_MSG_TYPE_SERVERMESSAGE, netmsg->parts[1]); + } + } else if (!strcmp(cmd, "CHAT")) { + if(netmsg->partCount < 3) { + flib_log_w("Net: Empty CHAT message"); + } else { + conn->onChatCb(conn->onChatCtx, netmsg->parts[1], netmsg->parts[2]); + } + } else if (!strcmp(cmd, "INFO")) { + if(netmsg->partCount < 5) { + flib_log_w("Net: Malformed INFO message"); + } else { + char *joined = flib_join(netmsg->parts+1, netmsg->partCount-1, "\n"); + if(joined) { + conn->onMessageCb(conn->onMessageCtx, NETCONN_MSG_TYPE_PLAYERINFO, joined); + } + free(joined); + } + } else if(!strcmp(cmd, "SERVER_VARS")) { + for(int offset=1; offset+2partCount; offset+=2) { + conn->onServerVarCb(conn->onServerVarCtx, netmsg->parts[offset], netmsg->parts[offset+1]); + } + } else if (!strcmp(cmd, "CLIENT_FLAGS")) { + if(netmsg->partCount < 3 || strlen(netmsg->parts[1]) < 2) { + flib_log_w("Net: Malformed CLIENT_FLAGS message"); + } else { + const char *flags = netmsg->parts[1]; + bool setFlag = flags[0] == '+'; + + for(int j = 2; j < netmsg->partCount; ++j) { + bool isSelf = !strcmp(conn->playerName, netmsg->parts[j]); + if(isSelf && strchr(flags, 'h')) { + conn->isChief = setFlag; + } + conn->onClientFlagsCb(conn->onClientFlagsCtx, netmsg->parts[j], flags+1, setFlag); + } + } + } else if (!strcmp(cmd, "ADD_TEAM")) { + if(netmsg->partCount != 24 || conn->netconnState!=NETCONN_STATE_ROOM) { + flib_log_w("Net: Bad ADD_TEAM message"); + } else { + flib_team *team = flib_team_from_netmsg(netmsg->parts+1); + if(!team || flib_teamlist_insert(&conn->teamlist, team, conn->teamlist.teamCount)) { + flib_team_destroy(team); + conn->netconnState = NETCONN_STATE_DISCONNECTED; + conn->onDisconnectedCb(conn->onDisconnectedCtx, NETCONN_DISCONNECT_INTERNAL_ERROR, "Internal error"); + exit = true; + } else { + conn->onTeamAddCb(conn->onTeamAddCtx, team); + } + } + } else if (!strcmp(cmd, "REMOVE_TEAM")) { + if(netmsg->partCount != 2 || conn->netconnState!=NETCONN_STATE_ROOM) { + flib_log_w("Net: Bad REMOVETEAM message"); + } else { + flib_teamlist_delete(&conn->teamlist, netmsg->parts[1]); + conn->onTeamDeleteCb(conn->onTeamDeleteCtx, netmsg->parts[1]); + } + } else if(!strcmp(cmd, "ROOMABANDONED")) { + netconn_leaveRoom(conn); + conn->onLeaveRoomCb(conn->onLeaveRoomCtx, NETCONN_ROOMLEAVE_ABANDONED, "Room destroyed"); + } else if(!strcmp(cmd, "KICKED")) { + netconn_leaveRoom(conn); + conn->onLeaveRoomCb(conn->onLeaveRoomCtx, NETCONN_ROOMLEAVE_KICKED, "You got kicked"); + } else if(!strcmp(cmd, "JOINED")) { + if(netmsg->partCount < 2) { + flib_log_w("Net: Bad JOINED message"); + } else { + for(int i = 1; i < netmsg->partCount; ++i) + { + bool isMe = !strcmp(conn->playerName, netmsg->parts[i]); + if (isMe) { + conn->netconnState = NETCONN_STATE_ROOM; + conn->onEnterRoomCb(conn->onEnterRoomCtx, conn->isChief); + } + + conn->onRoomJoinCb(conn->onRoomJoinCtx, netmsg->parts[i]); + } + } + } else if(!strcmp(cmd, "LOBBY:JOINED")) { + if(netmsg->partCount < 2) { + flib_log_w("Net: Bad JOINED message"); + } else { + for(int i = 1; i < netmsg->partCount; ++i) + { + bool isMe = !strcmp(conn->playerName, netmsg->parts[i]); + if (isMe && conn->netconnState == NETCONN_STATE_CONNECTING) { + conn->onConnectedCb(conn->onConnectedCtx); + conn->netconnState = NETCONN_STATE_LOBBY; + } + conn->onLobbyJoinCb(conn->onLobbyJoinCtx, netmsg->parts[i]); + } + } + } else if(!strcmp(cmd, "LEFT")) { + if(netmsg->partCount < 2) { + flib_log_w("Net: Bad LEFT message"); + } else { + conn->onRoomLeaveCb(conn->onRoomLeaveCtx, netmsg->parts[1], netmsg->partCount>2 ? netmsg->parts[2] : NULL); + } + } else if(!strcmp(cmd, "ROOM") && netmsg->partCount >= 2) { + const char *subcmd = netmsg->parts[1]; + if(!strcmp(subcmd, "ADD") && netmsg->partCount == 10) { + flib_room *room = flib_room_from_netmsg(netmsg->parts+2); + if(room) { + conn->onRoomAddCb(conn->onRoomAddCtx, room); + } + flib_room_destroy(room); + } else if(!strcmp(subcmd, "UPD") && netmsg->partCount == 11) { + flib_room *room = flib_room_from_netmsg(netmsg->parts+3); + if(room) { + conn->onRoomUpdateCb(conn->onRoomUpdateCtx, netmsg->parts[2], room); + } + flib_room_destroy(room); + } else if(!strcmp(subcmd, "DEL") && netmsg->partCount == 3) { + conn->onRoomDeleteCb(conn->onRoomDeleteCtx, netmsg->parts[2]); + } else { + flib_log_w("Net: Unknown or malformed ROOM subcommand: %s", subcmd); + } + } else if(!strcmp(cmd, "LOBBY:LEFT")) { + if(netmsg->partCount < 2) { + flib_log_w("Net: Bad LOBBY:LEFT message"); + } else { + conn->onLobbyLeaveCb(conn->onLobbyLeaveCtx, netmsg->parts[1], netmsg->partCount>2 ? netmsg->parts[2] : NULL); + } + } else if (!strcmp(cmd, "RUN_GAME")) { + conn->onRunGameCb(conn->onRunGameCtx); + } else if (!strcmp(cmd, "ASKPASSWORD")) { + conn->onPasswordRequestCb(conn->onPasswordRequestCtx, conn->playerName); + } else if (!strcmp(cmd, "NOTICE")) { + if(netmsg->partCount < 2) { + flib_log_w("Net: Bad NOTICE message"); + } else { + errno = 0; + long n = strtol(netmsg->parts[1], NULL, 10); + if(errno) { + flib_log_w("Net: Bad NOTICE message"); + } else if(n==0) { + conn->onNickTakenCb(conn->onNickTakenCtx, conn->playerName); + } else { + flib_log_w("Net: Unknown NOTICE message: %l", n); + } + } + } else if (!strcmp(cmd, "TEAM_ACCEPTED")) { + if (netmsg->partCount != 2 || conn->netconnState!=NETCONN_STATE_ROOM) { + flib_log_w("Net: Bad TEAM_ACCEPTED message"); + } else { + flib_team *team = flib_team_copy(flib_teamlist_find(&conn->pendingTeamlist, netmsg->parts[1])); + if(team) { + flib_teamlist_insert(&conn->teamlist, team, conn->teamlist.teamCount); + flib_teamlist_delete(&conn->pendingTeamlist, netmsg->parts[1]); + } else { + flib_log_e("Team accepted that was not requested: %s", netmsg->parts[1]); + } + conn->onTeamAcceptedCb(conn->onTeamAcceptedCtx, netmsg->parts[1]); + } + } else if (!strcmp(cmd, "CFG")) { + if(netmsg->partCount < 3 || conn->netconnState!=NETCONN_STATE_ROOM) { + flib_log_w("Net: Bad CFG message"); + } else { + const char *subcmd = netmsg->parts[1]; + if(!strcmp(subcmd, "SCHEME") && netmsg->partCount == flib_meta.modCount + flib_meta.settingCount + 3) { + flib_scheme *cfg = flib_scheme_from_netmsg(netmsg->parts+2); + if(cfg) { + flib_scheme_destroy(conn->scheme); + conn->scheme = cfg; + conn->onSchemeChangedCb(conn->onSchemeChangedCtx, cfg); + } else { + flib_log_e("Error processing CFG SCHEME message"); + } + } else if(!strcmp(subcmd, "FULLMAPCONFIG") && netmsg->partCount == 7) { + flib_map *map = flib_map_from_netmsg(netmsg->parts+2); + if(map) { + flib_map_destroy(conn->map); + conn->map = map; + conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_FULL); + } else { + flib_log_e("Error processing CFG FULLMAPCONFIG message"); + } + } else if(!strcmp(subcmd, "MAP") && netmsg->partCount == 3) { + char *mapname = flib_strdupnull(netmsg->parts[2]); + if(mapname) { + free(conn->map->name); + conn->map->name = mapname; + conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_MAP); + } else { + flib_log_e("Error processing CFG MAP message"); + } + } else if(!strcmp(subcmd, "THEME") && netmsg->partCount == 3) { + char *themename = flib_strdupnull(netmsg->parts[2]); + if(themename) { + free(conn->map->theme); + conn->map->theme = themename; + conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_THEME); + } else { + flib_log_e("Error processing CFG THEME message"); + } + } else if(!strcmp(subcmd, "SEED") && netmsg->partCount == 3) { + char *seed = flib_strdupnull(netmsg->parts[2]); + if(seed) { + free(conn->map->seed); + conn->map->seed = seed; + conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_SEED); + } else { + flib_log_e("Error processing CFG SEED message"); + } + } else if(!strcmp(subcmd, "TEMPLATE") && netmsg->partCount == 3) { + conn->map->templateFilter = atoi(netmsg->parts[2]); + conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_TEMPLATE); + } else if(!strcmp(subcmd, "MAPGEN") && netmsg->partCount == 3) { + conn->map->mapgen = atoi(netmsg->parts[2]); + conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_MAPGEN); + } else if(!strcmp(subcmd, "MAZE_SIZE") && netmsg->partCount == 3) { + conn->map->mazeSize = atoi(netmsg->parts[2]); + conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_MAZE_SIZE); + } else if(!strcmp(subcmd, "DRAWNMAP") && netmsg->partCount == 3) { + size_t drawnMapSize = 0; + uint8_t *drawnMapData = NULL; + if(!flib_drawnmapdata_from_netmsg(netmsg->parts[2], &drawnMapData, &drawnMapSize)) { + free(conn->map->drawData); + conn->map->drawData = drawnMapData; + conn->map->drawDataSize = drawnMapSize; + conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_DRAWNMAP); + } else { + flib_log_e("Error processing CFG DRAWNMAP message"); + } + } else if(!strcmp(subcmd, "SCRIPT") && netmsg->partCount == 3) { + netconn_setScript(conn, netmsg->parts[2]); + conn->onScriptChangedCb(conn->onScriptChangedCtx, netmsg->parts[2]); + } else if(!strcmp(subcmd, "AMMO") && netmsg->partCount == 4) { + flib_weaponset *weapons = flib_weaponset_from_ammostring(netmsg->parts[2], netmsg->parts[3]); + if(weapons) { + flib_weaponset_destroy(conn->weaponset); + conn->weaponset = weapons; + conn->onWeaponsetChangedCb(conn->onWeaponsetChangedCtx, weapons); + } else { + flib_log_e("Error processing CFG AMMO message"); + } + } else { + flib_log_w("Net: Unknown or malformed CFG subcommand: %s", subcmd); + } + } + } else if (!strcmp(cmd, "HH_NUM")) { + if (netmsg->partCount != 3 || conn->netconnState!=NETCONN_STATE_ROOM) { + flib_log_w("Net: Bad HH_NUM message"); + } else { + int hogs = atoi(netmsg->parts[2]); + if(hogs<=0 || hogs>HEDGEHOGS_PER_TEAM) { + flib_log_w("Net: Bad HH_NUM message: %s hogs", netmsg->parts[2]); + } else { + flib_team *team = flib_teamlist_find(&conn->teamlist, netmsg->parts[1]); + if(team) { + team->hogsInGame = hogs; + } else { + flib_log_e("HH_NUM message for unknown team %s", netmsg->parts[1]); + } + conn->onHogCountChangedCb(conn->onHogCountChangedCtx, netmsg->parts[1], hogs); + } + } + } else if (!strcmp(cmd, "TEAM_COLOR")) { + if (netmsg->partCount != 3 || conn->netconnState!=NETCONN_STATE_ROOM) { + flib_log_w("Net: Bad TEAM_COLOR message"); + } else { + long color; + if(sscanf(netmsg->parts[2], "%lu", &color) && color>=0 && colorteamlist, netmsg->parts[1]); + if(team) { + team->colorIndex = color; + } else { + flib_log_e("TEAM_COLOR message for unknown team %s", netmsg->parts[1]); + } + conn->onTeamColorChangedCb(conn->onTeamColorChangedCtx, netmsg->parts[1], color); + } else { + flib_log_w("Net: Bad TEAM_COLOR message: Color %s", netmsg->parts[2]); + } + } + } else if (!strcmp(cmd, "EM")) { + if(netmsg->partCount < 2) { + flib_log_w("Net: Bad EM message"); + } else { + for(int i = 1; i < netmsg->partCount; ++i) { + char *out = NULL; + size_t outlen; + bool ok = base64_decode_alloc(netmsg->parts[i], strlen(netmsg->parts[i]), &out, &outlen); + if(ok && outlen) { + conn->onEngineMessageCb(conn->onEngineMessageCtx, (uint8_t*)out, outlen); + } else { + flib_log_e("Net: Malformed engine message: %s", netmsg->parts[i]); + } + free(out); + } + } + } else if (!strcmp(cmd, "BYE")) { + if (netmsg->partCount < 2) { + flib_log_w("Net: Bad BYE message"); + } else { + conn->netconnState = NETCONN_STATE_DISCONNECTED; + if (!strcmp(netmsg->parts[1], "Authentication failed")) { + conn->onDisconnectedCb(conn->onDisconnectedCtx, NETCONN_DISCONNECT_AUTH_FAILED, netmsg->parts[1]); + } else { + conn->onDisconnectedCb(conn->onDisconnectedCtx, NETCONN_DISCONNECT_NORMAL, netmsg->parts[1]); + } + exit = true; + } + } else if (!strcmp(cmd, "ADMIN_ACCESS")) { + // deprecated + } else if (!strcmp(cmd, "ROOM_CONTROL_ACCESS")) { + // deprecated + } else { + flib_log_w("Unknown server command: %s", cmd); + } + flib_netmsg_destroy(netmsg); + } + + if(!exit && !conn->destroyRequested && !flib_netbase_connected(net)) { + conn->netconnState = NETCONN_STATE_DISCONNECTED; + conn->onDisconnectedCb(conn->onDisconnectedCtx, NETCONN_DISCONNECT_CONNLOST, "Connection lost"); + } +} + +void flib_netconn_tick(flib_netconn *conn) { + if(!log_badargs_if(conn==NULL) + && !log_w_if(conn->running, "Call to flib_netconn_tick from a callback") + && !log_w_if(conn->netconnState == NETCONN_STATE_DISCONNECTED, "We are already done.")) { + conn->running = true; + flib_netconn_wrappedtick(conn); + conn->running = false; + + if(conn->destroyRequested) { + flib_netconn_destroy(conn); + } + } +} diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/net/netconn.h --- a/project_files/frontlib/net/netconn.h Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/net/netconn.h Tue Jan 21 22:43:06 2014 +0100 @@ -1,654 +1,654 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * This file contains functions for communicating with a Hedgewars server to chat, prepare and play - * rounds of Hedgewars. - * - * To use this, first create a netconn object by calling flib_netconn_create. This will start the - * connection to the game server (which might fail right away, the function returns null then). You - * should also register your callback functions right at the start to ensure you don't miss any - * callbacks. - * - * In order to allow the netconn to run, you should regularly call flib_netconn_tick(), which - * performs network I/O and calls your callbacks on interesting events. - * - * When the connection is closed, you will receive the onDisconnect callback. This is the signal to - * destroy the netconn and stop calling tick(). - * - * The connection process lasts from the time you create the netconn until you receive the - * onConnected callback (or onDisconnected in case something goes wrong). During that time, you - * might receive the onNickTaken and onPasswordRequest callbacks; see their description for more - * information on how to handle them. You could also receive other callbacks during connecting (e.g. - * about the room list), but it should be safe to ignore them. - * - * Once you are connected, you are in the lobby, and you can enter rooms and leave them again. The - * room and lobby states have different protocols, so many commands only work in either one or the - * other. If you are in a room you might also be in a game, but most of the functions behave the - * same ingame as in a room. - * - * The state changes from lobby to room when the server tells you that you just entered one, which - * will also trigger the onEnterRoom callback. This usually happens in reply to either a joinRoom, - * createRoom or playerFollow command. - * - * The state changes back to lobby when the room is dissolved, when you are kicked from the room, or - * when you actively leave the room using flib_netconn_send_leaveRoom. The first two events will - * trigger the onLeaveRoom callback. - */ - -#ifndef NETCONN_H_ -#define NETCONN_H_ - -#include "../model/gamesetup.h" -#include "../model/scheme.h" -#include "../model/room.h" - -#include -#include -#include - -#define NETCONN_STATE_CONNECTING 0 -#define NETCONN_STATE_LOBBY 1 -#define NETCONN_STATE_ROOM 2 -#define NETCONN_STATE_DISCONNECTED 10 - -#define NETCONN_DISCONNECT_NORMAL 0 //!< The connection was closed normally -#define NETCONN_DISCONNECT_SERVER_TOO_OLD 1 //!< The server has a lower protocol version than we do -#define NETCONN_DISCONNECT_AUTH_FAILED 2 //!< You sent a password with flib_netconn_send_password that was not accepted -#define NETCONN_DISCONNECT_CONNLOST 3 //!< The network connection was lost -#define NETCONN_DISCONNECT_INTERNAL_ERROR 100 //!< Something went wrong in frontlib itself - -#define NETCONN_ROOMLEAVE_ABANDONED 0 //!< The room was closed because the chief left -#define NETCONN_ROOMLEAVE_KICKED 1 //!< You have been kicked from the room - -#define NETCONN_MSG_TYPE_PLAYERINFO 0 //!< A response to flib_netconn_send_playerInfo -#define NETCONN_MSG_TYPE_SERVERMESSAGE 1 //!< The welcome message when connecting to the lobby -#define NETCONN_MSG_TYPE_WARNING 2 //!< A general warning message -#define NETCONN_MSG_TYPE_ERROR 3 //!< A general error message - -#define NETCONN_MAPCHANGE_FULL 0 -#define NETCONN_MAPCHANGE_MAP 1 -#define NETCONN_MAPCHANGE_MAPGEN 2 -#define NETCONN_MAPCHANGE_DRAWNMAP 3 -#define NETCONN_MAPCHANGE_MAZE_SIZE 4 -#define NETCONN_MAPCHANGE_TEMPLATE 5 -#define NETCONN_MAPCHANGE_THEME 6 -#define NETCONN_MAPCHANGE_SEED 7 - -typedef struct _flib_netconn flib_netconn; - -/** - * Create a new netplay connection with these parameters. - * The path to the data directory must end with a path delimiter (e.g. C:\Games\Hedgewars\Data\) - */ -flib_netconn *flib_netconn_create(const char *playerName, const char *dataDirPath, const char *host, int port); -void flib_netconn_destroy(flib_netconn *conn); - -/** - * Perform I/O operations and call callbacks if something interesting happens. - * Should be called regularly. - */ -void flib_netconn_tick(flib_netconn *conn); - -/** - * Are you currently the owner of this room? The return value only makes sense in - * NETCONN_STATE_ROOM and NETCONN_STATE_INGAME states. - */ -bool flib_netconn_is_chief(flib_netconn *conn); - -/** - * Returns the playername. This is *probably* the one provided on creation, but if that name was - * already taken, a different one could have been set by the onNickTaken callback or its default - * implementation. - */ -const char *flib_netconn_get_playername(flib_netconn *conn); - -/** - * Generate a game setup from the current room state. - * Returns NULL if the room state does not contain enough information for a complete game setup, - * or if an error occurs. - * - * The new gamesetup must be destroyed with flib_gamesetup_destroy(). - */ -flib_gamesetup *flib_netconn_create_gamesetup(flib_netconn *conn); - - - - -// Send functions needed when connecting and disconnecting - - /** - * Request a different nickname. - * This function only makes sense in reaction to an onNickTaken callback, because the netconn - * automatically requests the nickname you provide on creation, and once the server accepts the - * nickname it can no longer be changed. - */ - int flib_netconn_send_nick(flib_netconn *conn, const char *nick); - - /** - * Send the password in reply to a password request. - * If the server does not accept the password, you will be disconnected - * (NETCONN_DISCONNECT_AUTH_FAILED) - */ - int flib_netconn_send_password(flib_netconn *conn, const char *passwd); - - /** - * Tell the server that you want to leave. If successful, the server will disconnect you. - */ - int flib_netconn_send_quit(flib_netconn *conn, const char *quitmsg); - - -// Send functions that make sense both in the lobby and in rooms - - /** - * Send a chat message. This message is either sent to the lobby or the room, depending on - * whether you are in a room at the moment. The message is not echoed back to you. - */ - int flib_netconn_send_chat(flib_netconn *conn, const char *chat); - - /** - * Kick a player. This has different meanings in the lobby and in a room; - * In the lobby, it will kick the player from the server, and you need to be a server admin to - * do it. In a room, it will kick the player from the room, and you need to be room chief. - */ - int flib_netconn_send_kick(flib_netconn *conn, const char *playerName); - - /** - * Request information about a player (e.g. current room, version, partial IP). If the action - * succeeds, you will receive an onMessage callback with NETCONN_MSG_TYPE_PLAYERINFO containing - * the requested information. - */ - int flib_netconn_send_playerInfo(flib_netconn *conn, const char *playerName); - - -// Send functions that only make sense in the lobby - - /** - * Request an update of the room list. Only makes sense when in lobby state. - * If the action succeeds, you will receive an onRoomlist callback containing the current room - * data. - */ - int flib_netconn_send_request_roomlist(flib_netconn *conn); - - /** - * Join a room as guest (not chief). Only makes sense when in lobby state. If the action - * succeeds, you will receive an onEnterRoom callback with chief=false followed by other - * callbacks with current room information. - */ - int flib_netconn_send_joinRoom(flib_netconn *conn, const char *room); - - /** - * Follow a player. Only valid in the lobby. If the player is in a room (or in a game), this - * command is analogous to calling flib_netconn_send_joinRoom with that room. - */ - int flib_netconn_send_playerFollow(flib_netconn *conn, const char *playerName); - - /** - * Create and join a new room. Only makes sense when in lobby state. If the action succeeds, - * you will receive an onEnterRoom callback with chief=true. - */ - int flib_netconn_send_createRoom(flib_netconn *conn, const char *room); - - /** - * Ban a player. The scope of this ban depends on whether you are in a room or in the lobby. - * In a room, you need to be the room chief, and the ban will apply to the room only. In the - * lobby, you need to be server admin to ban someone, and the ban applies to the entire server. - */ - int flib_netconn_send_ban(flib_netconn *conn, const char *playerName); - - /** - * Does something administrator-y. At any rate you need to be an administrator and in the lobby - * to use this command. - */ - int flib_netconn_send_clearAccountsCache(flib_netconn *conn); - - /** - * Sets a server variable to the indicated value. Only makes sense if you are server admin and - * in the lobby. Known variables are MOTD_NEW, MOTD_OLD and LATEST_PROTO. MOTD_OLD is shown to - * players with older protocol versions, to inform them that they might want to update. - */ - int flib_netconn_send_setServerVar(flib_netconn *conn, const char *name, const char *value); - - /** - * Queries all server variables. Only makes sense if you are server admin and in the lobby. - * If the action succeeds, you will receive several onServerVar callbacks with the - * current values of all server variables. - */ - int flib_netconn_send_getServerVars(flib_netconn *conn); - - -// Send functions that only make sense in a room - - /** - * Leave the room for the lobby. Only makes sense in room state. msg can be NULL if you don't - * want to send a message. The server always accepts a part command, so once you send it off, - * you can just assume that you are back in the lobby. - */ - int flib_netconn_send_leaveRoom(flib_netconn *conn, const char *msg); - - /** - * Change your "ready" status in the room. Only makes sense when in room state. If the action - * succeeds, you will receive an onClientFlags callback containing the change. - */ - int flib_netconn_send_toggleReady(flib_netconn *conn); - - /** - * Add a team to the current room. Apart from the "fixed" team information, this also includes - * the color, but not the number of hogs. Only makes sense when in room state. If the action - * succeeds, you will receive an onTeamAccepted callback with the name of the team. - * - * Notes: Technically, sending a color here is the only way for a non-chief to set the color of - * her own team. The server remembers this color and even generates a separate teamColor message - * to inform everyone of it. However, at the moment the frontends generally override this color - * with one they choose themselves in order to deal with unfortunate behavior of the QtFrontend, - * which always sends color index 0 when adding a team but thinks that the team has a random - * color. The chief always sends a new color in order to bring the QtFrontend back into sync. - */ - int flib_netconn_send_addTeam(flib_netconn *conn, const flib_team *team); - - /** - * Remove the team with the name teamname. Only makes sense when in room state. - * The server does not send a reply on success. - */ - int flib_netconn_send_removeTeam(flib_netconn *conn, const char *teamname); - - -// Send functions that only make sense in a room and if you are room chief - - /** - * Rename the current room. Only makes sense in room state and if you are chief. If the action - * succeeds, you (and everyone else on the server) will receive an onRoomUpdate message - * containing the change. - */ - int flib_netconn_send_renameRoom(flib_netconn *conn, const char *roomName); - - /** - * Set the number of hogs for a team. Only makes sense in room state and if you are chief. - * The server does not send a reply. - */ - int flib_netconn_send_teamHogCount(flib_netconn *conn, const char *teamname, int hogcount); - - /** - * Set the teamcolor of a team. Only makes sense in room state and if you are chief. - * The server does not send a reply. - */ - int flib_netconn_send_teamColor(flib_netconn *conn, const char *teamname, int colorIndex); - - /** - * Set the weaponset for the room. Only makes sense in room state and if you are chief. - * The server does not send a reply. - */ - int flib_netconn_send_weaponset(flib_netconn *conn, const flib_weaponset *weaponset); - - /** - * Set the map for the room. Only makes sense in room state and if you are chief. - * The server does not send a reply. - */ - int flib_netconn_send_map(flib_netconn *conn, const flib_map *map); - - /** - * Set the mapname. Only makes sense in room state and if you are chief. - * The server does not send a reply. - */ - int flib_netconn_send_mapName(flib_netconn *conn, const char *mapName); - - /** - * Set the map generator (regular, maze, drawn, named). Only makes sense in room state and if - * you are chief. - * The server does not send a reply. - */ - int flib_netconn_send_mapGen(flib_netconn *conn, int mapGen); - - /** - * Set the map template for regular maps. Only makes sense in room state and if you are chief. - * The server does not send a reply. - */ - int flib_netconn_send_mapTemplate(flib_netconn *conn, int templateFilter); - - /** - * Set the maze template (maze size) for mazes. Only makes sense in room state and if you are - * chief. The server does not send a reply. - */ - int flib_netconn_send_mapMazeSize(flib_netconn *conn, int mazeSize); - - /** - * Set the seed for the map. Only makes sense in room state and if you are chief. - * The server does not send a reply. - */ - int flib_netconn_send_mapSeed(flib_netconn *conn, const char *seed); - - /** - * Set the theme for the map. Only makes sense in room state and if you are chief. - * The server does not send a reply. - */ - int flib_netconn_send_mapTheme(flib_netconn *conn, const char *theme); - - /** - * Set the draw data for the drawn map. Only makes sense in room state and if you are chief. - * The server does not send a reply. - */ - int flib_netconn_send_mapDrawdata(flib_netconn *conn, const uint8_t *drawData, size_t size); - - /** - * Set the script (game style). Only makes sense in room state and if you are chief. - * The server does not send a reply. - */ - int flib_netconn_send_script(flib_netconn *conn, const char *scriptName); - - /** - * Set the scheme. Only makes sense in room state and if you are chief. - * The server does not send a reply. - */ - int flib_netconn_send_scheme(flib_netconn *conn, const flib_scheme *scheme); - - /** - * Signal that you want to start the game. Only makes sense in room state and if you are chief. - * The server will check whether all players are ready and whether it believes the setup makes - * sense (e.g. more than one clan). If the server is satisfied, you will receive an onRunGame - * callback (all other clients in the room are notified the same way). Otherwise the server - * might answer with a warning, or might not answer at all. - */ - int flib_netconn_send_startGame(flib_netconn *conn); - - /** - * Allow/forbid players to join the room. Only makes sense in room state and if you are chief. - * The server does not send a reply. - */ - int flib_netconn_send_toggleRestrictJoins(flib_netconn *conn); - - /** - * Allow/forbid adding teams to the room. Only makes sense in room state and if you are chief. - * The server does not send a reply. - */ - int flib_netconn_send_toggleRestrictTeams(flib_netconn *conn); - - -// Send functions that are only needed for running a game - - /** - * Send a teamchat message, forwarded from the engine. Only makes sense ingame. - * The server does not send a reply. In contrast to a Chat message, the server - * automatically converts this into an engine message and passes it on to the other - * clients. - */ - int flib_netconn_send_teamchat(flib_netconn *conn, const char *msg); - - /** - * Send an engine message. Only makes sense when ingame. In a networked game, you have to pass - * all the engine messages from the engine here, and they will be spread to all other clients - * in the game to keep the game in sync. - */ - int flib_netconn_send_engineMessage(flib_netconn *conn, const uint8_t *message, size_t size); - - /** - * Inform the server that the round has ended. Call this when the engine has disconnected, - * passing 1 if the round ended normally, 0 otherwise. - */ - int flib_netconn_send_roundfinished(flib_netconn *conn, bool withoutError); - - - - - -// Callbacks that are important for connecting/disconnecting - - /** - * onNickTaken is called when connecting to the server, if it turns out that there is already a - * player with the same nick. - * In order to proceed, a new nickname needs to be sent to the server using - * flib_netconn_send_nick() (or of course you can bail out and send a QUIT). - * If you don't set a callback, the netconn will automatically react by generating a new name. - */ - void flib_netconn_onNickTaken(flib_netconn *conn, void (*callback)(void *context, const char *nick), void* context); - - /** - * When connecting with a registered nickname, the server will ask for a password before - * admitting you in. This callback is called when that happens. As a reaction, you can send the - * password using flib_netconn_send_password. If you don't register a callback, the default - * behavior is to just quit in a way that will cause a disconnect with - * NETCONN_DISCONNECT_AUTH_FAILED. - * - * You can't just choose a new nickname when you receive this callback, because at that point - * the server has already accepted your nick. - */ - void flib_netconn_onPasswordRequest(flib_netconn *conn, void (*callback)(void *context, const char *nick), void* context); - - /** - * This is called when the server has accepted our nickname (and possibly password) and we have - * entered the lobby. - */ - void flib_netconn_onConnected(flib_netconn *conn, void (*callback)(void *context), void* context); - - /** - * This is always the last callback (unless the netconn is destroyed early), and the netconn - * should be destroyed when it is received. The reason for the disconnect is passed as one of - * the NETCONN_DISCONNECT_ constants. Sometimes a message is included as well, but that - * parameter might also be NULL. - */ - void flib_netconn_onDisconnected(flib_netconn *conn, void (*callback)(void *context, int reason, const char *message), void* context); - - -// Callbacks that make sense in most situations - - /** - * Callback for several informational messages that should be displayed to the user - * (e.g. in the chat window), but do not require a reaction. If a game is running, you might - * want to redirect some of these messages to the engine as well so the user will see them. - */ - void flib_netconn_onMessage(flib_netconn *conn, void (*callback)(void *context, int msgtype, const char *msg), void* context); - - /** - * We received a chat message. Where this message belongs depends on the current state - * (lobby/room). If a game is running the message should be passed to the engine. - */ - void flib_netconn_onChat(flib_netconn *conn, void (*callback)(void *context, const char *nick, const char *msg), void* context); - - /** - * Callbacks for incremental room list updates. They will fire whenever these events occur, - * even before you first query the actual roomlist - so be sure not to blindly reference your - * room list in these callbacks. The server currently only sends updates when a room changes - * its name, so in order to update other room information you need to query the roomlist again - * (see send_request_roomlist / onRoomlist). - */ - void flib_netconn_onRoomAdd(flib_netconn *conn, void (*callback)(void *context, const flib_room *room), void* context); - void flib_netconn_onRoomDelete(flib_netconn *conn, void (*callback)(void *context, const char *name), void* context); - void flib_netconn_onRoomUpdate(flib_netconn *conn, void (*callback)(void *context, const char *oldName, const flib_room *room), void* context); - - /** - * Callbacks for players joining or leaving the lobby. In contrast to the roomlist updates, you - * will get a JOIN callback for every player already on the server when you join (and there is - * no direct way to query the current playerlist) - * - * NOTE: partMessage may be NULL. - */ - void flib_netconn_onLobbyJoin(flib_netconn *conn, void (*callback)(void *context, const char *nick), void* context); - void flib_netconn_onLobbyLeave(flib_netconn *conn, void (*callback)(void *context, const char *nick, const char *partMessage), void* context); - - /** - * This is called when the server informs us that one or more flags associated with a - * player/client have changed. - * - * nick is the name of the player, flags is a string containing one character for each modified - * flag (see below), and newFlagState signals whether the flags should be set to true or false. - * - * Some of these flags are important for protocol purposes (especially if they are set for you) - * while others are just informational. Also, some flags are only relevant for players who are - * in the same room as you, and the server will not inform you if they change for others. - * - * These are the currently known/used flags: - * a: Server admin. Always updated. - * h: Room chief. Updated when in the same room. - * r: Ready to play. Updated when in the same room. - * u: Registered user. Always updated. - * - * The server tells us the 'a' and 'u' flags for all players when we first join the lobby, and - * also tells us the 'r' and 'h' flags when we join or create a room. It assumes that all flags - * are initially false, so it will typically only tell you to set certain flags to true when - * transmitting the initial states. Reset the 'h' and 'r' flags to false when leaving a room, - * or when entering room state, to arrive at the right state for each player. - * - * The room chief state of yourself is particularly important because it determines whether you - * can modify settings of the current room. Generally, when you create a room you start out - * being room chief, and when you join an existing room you are not. However, if the original - * chief leaves a room, the server can choose a new chief, and if that happens the chief flag - * will be transferred to someone else. - */ - void flib_netconn_onClientFlags(flib_netconn *conn, void (*callback)(void *context, const char *nick, const char *flags, bool newFlagState), void *context); - -// Callbacks that happen only in response to specific requests - - /** - * Response to flib_netconn_send_request_roomlist(). - * The rooms array contains the current state of all rooms on the server. - */ - void flib_netconn_onRoomlist(flib_netconn *conn, void (*callback)(void *context, const flib_room **rooms, int roomCount), void* context); - - /** - * Response to flib_netconn_send_joinRoom, flib_netconn_send_playerFollow or - * flib_netconn_send_createRoom. - * - * You just left the lobby and entered a room. - * If chief is true, you can and should send a full configuration for the room now. This - * consists of ammo, scheme, script and map, where map apparently has to come last. - */ - void flib_netconn_onEnterRoom(flib_netconn *conn, void (*callback)(void *context, bool chief), void *context); - - /** - * Response to flib_netconn_send_addTeam. - * The server might reject your team for several reasons, e.g. because it has the same name as - * an existing team, or because the room chief restricted adding new teams. If the team is - * accepted by the server, this callback is fired. - * - * If you are the room chief, you are expected to provide the hog count for your own team now - * using flib_netconn_send_teamHogCount. The color of the team is already set to the one you - * provided in addTeam. - */ - void flib_netconn_onTeamAccepted(flib_netconn *conn, void (*callback)(void *context, const char *team), void *context); - - /** - * When you query the server vars with flib_netconn_send_getServerVars (only works as admin), - * the server replies with a list of them. This callback is called for each entry in that list. - */ - void flib_netconn_onServerVar(flib_netconn *conn, void (*callback)(void *context, const char *name, const char *value), void *context); - - -// Callbacks that are only relevant in a room - - /** - * You just left a room and entered the lobby again. - * reason is one of the NETCONN_ROOMLEAVE_ constants (usually a kick). - * This will not be called when you actively leave a room using PART. - * Don't confuse with onRoomLeave, which indicates that *someone else* left the room. - */ - void flib_netconn_onLeaveRoom(flib_netconn *conn, void (*callback)(void *context, int reason, const char *message), void *context); - - /** - * Someone joined or left the room you are currently in. - * Analogous to onLobbyJoin/leave, you will receive the join callback for all players that are - * already in the room when you join, including for yourself (this is actually how it is - * determined that you joined a room). - * - * However, you will *not* receive onRoomLeave messages for everyone when you leave the room. - */ - void flib_netconn_onRoomJoin(flib_netconn *conn, void (*callback)(void *context, const char *nick), void* context); - void flib_netconn_onRoomLeave(flib_netconn *conn, void (*callback)(void *context, const char *nick, const char *partMessage), void* context); - - /** - * A new team was added to the room. The person who adds a team does NOT receive this callback - * (he gets onTeamAccepted instead). - * - * The team does not contain bindings, stats, weaponset, color or the number of hogs (but it is - * assumed to be the default of 4). - * - * If you receive this message and you are the room chief, you may want to send a color and hog - * count for this team using flib_netconn_send_teamHogCount / teamColor for QtFrontend - * compatibility. - * - * The server currently sends another message with the color of the team to the same recipients - * as this teamAdd message, which will trigger an onTeamColorChanged callback. See the - * description of flib_netconn_send_addTeam for more information. - */ - void flib_netconn_onTeamAdd(flib_netconn *conn, void (*callback)(void *context, const flib_team *team), void *context); - - /** - * A team was removed from the room. The person who removed the team will not receive this - * callback. - */ - void flib_netconn_onTeamDelete(flib_netconn *conn, void (*callback)(void *context, const char *teamname), void *context); - - /** - * The number of hogs in a team has been changed by the room chief. If you are the chief and - * change the number of hogs yourself, you will not receive this callback. - */ - void flib_netconn_onHogCountChanged(flib_netconn *conn, void (*callback)(void *context, const char *teamName, int hogs), void *context); - - /** - * The color of a team has been set or changed. The client who set or changed the color will - * not receive this callback. - * - * Normally, only the chief can change the color of a team. However, this message is also - * generated when a team is added, so you can receive it even as chief. - */ - void flib_netconn_onTeamColorChanged(flib_netconn *conn, void (*callback)(void *context, const char *teamName, int colorIndex), void *context); - - /** - * The room chief has changed the game scheme (or you just joined a room). - * You will not receive this callback if you changed the scheme yourself. - */ - void flib_netconn_onSchemeChanged(flib_netconn *conn, void (*callback)(void *context, const flib_scheme *scheme), void *context); - - /** - * The room chief has changed the map (or you just joined a room). Only non-chiefs receive these - * messages. - * - * To reduce the number of callback functions, the netconn keeps track of the current map - * settings and always passes the entire current map config, but informs the callee about what - * has changed (see the NETCONN_MAPCHANGE_ constants). - * - * Caution: Due to the way the protocol works, the map might not be complete at this point if it - * is a hand-drawn map, because the "full" map config does not include the drawn map data. - */ - void flib_netconn_onMapChanged(flib_netconn *conn, void (*callback)(void *context, const flib_map *map, int changetype), void *context); - - /** - * The room chief has changed the game style (or you just joined a room). If you are the chief - * and change the style yourself, you will not receive this callback. - */ - void flib_netconn_onScriptChanged(flib_netconn *conn, void (*callback)(void *context, const char *script), void *context); - - /** - * The room chief has changed the weaponset (or you just joined a room). If you are the chief - * and change the weaponset yourself, you will not receive this callback. - */ - void flib_netconn_onWeaponsetChanged(flib_netconn *conn, void (*callback)(void *context, const flib_weaponset *weaponset), void *context); - - /** - * The game is starting. Fire up the engine and join in! - * You can let the netconn generate the right game setup using flib_netconn_create_gamesetup - */ - void flib_netconn_onRunGame(flib_netconn *conn, void (*callback)(void *context), void *context); - - /** - * You are in a room, a game is in progress, and the server is sending you the new input for the - * engine to keep up to date with the current happenings. Pass it on to the engine using - * flib_gameconn_send_enginemsg. - */ - void flib_netconn_onEngineMessage(flib_netconn *conn, void (*callback)(void *context, const uint8_t *message, size_t size), void *context); - -#endif +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * This file contains functions for communicating with a Hedgewars server to chat, prepare and play + * rounds of Hedgewars. + * + * To use this, first create a netconn object by calling flib_netconn_create. This will start the + * connection to the game server (which might fail right away, the function returns null then). You + * should also register your callback functions right at the start to ensure you don't miss any + * callbacks. + * + * In order to allow the netconn to run, you should regularly call flib_netconn_tick(), which + * performs network I/O and calls your callbacks on interesting events. + * + * When the connection is closed, you will receive the onDisconnect callback. This is the signal to + * destroy the netconn and stop calling tick(). + * + * The connection process lasts from the time you create the netconn until you receive the + * onConnected callback (or onDisconnected in case something goes wrong). During that time, you + * might receive the onNickTaken and onPasswordRequest callbacks; see their description for more + * information on how to handle them. You could also receive other callbacks during connecting (e.g. + * about the room list), but it should be safe to ignore them. + * + * Once you are connected, you are in the lobby, and you can enter rooms and leave them again. The + * room and lobby states have different protocols, so many commands only work in either one or the + * other. If you are in a room you might also be in a game, but most of the functions behave the + * same ingame as in a room. + * + * The state changes from lobby to room when the server tells you that you just entered one, which + * will also trigger the onEnterRoom callback. This usually happens in reply to either a joinRoom, + * createRoom or playerFollow command. + * + * The state changes back to lobby when the room is dissolved, when you are kicked from the room, or + * when you actively leave the room using flib_netconn_send_leaveRoom. The first two events will + * trigger the onLeaveRoom callback. + */ + +#ifndef NETCONN_H_ +#define NETCONN_H_ + +#include "../model/gamesetup.h" +#include "../model/scheme.h" +#include "../model/room.h" + +#include +#include +#include + +#define NETCONN_STATE_CONNECTING 0 +#define NETCONN_STATE_LOBBY 1 +#define NETCONN_STATE_ROOM 2 +#define NETCONN_STATE_DISCONNECTED 10 + +#define NETCONN_DISCONNECT_NORMAL 0 //!< The connection was closed normally +#define NETCONN_DISCONNECT_SERVER_TOO_OLD 1 //!< The server has a lower protocol version than we do +#define NETCONN_DISCONNECT_AUTH_FAILED 2 //!< You sent a password with flib_netconn_send_password that was not accepted +#define NETCONN_DISCONNECT_CONNLOST 3 //!< The network connection was lost +#define NETCONN_DISCONNECT_INTERNAL_ERROR 100 //!< Something went wrong in frontlib itself + +#define NETCONN_ROOMLEAVE_ABANDONED 0 //!< The room was closed because the chief left +#define NETCONN_ROOMLEAVE_KICKED 1 //!< You have been kicked from the room + +#define NETCONN_MSG_TYPE_PLAYERINFO 0 //!< A response to flib_netconn_send_playerInfo +#define NETCONN_MSG_TYPE_SERVERMESSAGE 1 //!< The welcome message when connecting to the lobby +#define NETCONN_MSG_TYPE_WARNING 2 //!< A general warning message +#define NETCONN_MSG_TYPE_ERROR 3 //!< A general error message + +#define NETCONN_MAPCHANGE_FULL 0 +#define NETCONN_MAPCHANGE_MAP 1 +#define NETCONN_MAPCHANGE_MAPGEN 2 +#define NETCONN_MAPCHANGE_DRAWNMAP 3 +#define NETCONN_MAPCHANGE_MAZE_SIZE 4 +#define NETCONN_MAPCHANGE_TEMPLATE 5 +#define NETCONN_MAPCHANGE_THEME 6 +#define NETCONN_MAPCHANGE_SEED 7 + +typedef struct _flib_netconn flib_netconn; + +/** + * Create a new netplay connection with these parameters. + * The path to the data directory must end with a path delimiter (e.g. C:\Games\Hedgewars\Data\) + */ +flib_netconn *flib_netconn_create(const char *playerName, const char *dataDirPath, const char *host, int port); +void flib_netconn_destroy(flib_netconn *conn); + +/** + * Perform I/O operations and call callbacks if something interesting happens. + * Should be called regularly. + */ +void flib_netconn_tick(flib_netconn *conn); + +/** + * Are you currently the owner of this room? The return value only makes sense in + * NETCONN_STATE_ROOM and NETCONN_STATE_INGAME states. + */ +bool flib_netconn_is_chief(flib_netconn *conn); + +/** + * Returns the playername. This is *probably* the one provided on creation, but if that name was + * already taken, a different one could have been set by the onNickTaken callback or its default + * implementation. + */ +const char *flib_netconn_get_playername(flib_netconn *conn); + +/** + * Generate a game setup from the current room state. + * Returns NULL if the room state does not contain enough information for a complete game setup, + * or if an error occurs. + * + * The new gamesetup must be destroyed with flib_gamesetup_destroy(). + */ +flib_gamesetup *flib_netconn_create_gamesetup(flib_netconn *conn); + + + + +// Send functions needed when connecting and disconnecting + + /** + * Request a different nickname. + * This function only makes sense in reaction to an onNickTaken callback, because the netconn + * automatically requests the nickname you provide on creation, and once the server accepts the + * nickname it can no longer be changed. + */ + int flib_netconn_send_nick(flib_netconn *conn, const char *nick); + + /** + * Send the password in reply to a password request. + * If the server does not accept the password, you will be disconnected + * (NETCONN_DISCONNECT_AUTH_FAILED) + */ + int flib_netconn_send_password(flib_netconn *conn, const char *passwd); + + /** + * Tell the server that you want to leave. If successful, the server will disconnect you. + */ + int flib_netconn_send_quit(flib_netconn *conn, const char *quitmsg); + + +// Send functions that make sense both in the lobby and in rooms + + /** + * Send a chat message. This message is either sent to the lobby or the room, depending on + * whether you are in a room at the moment. The message is not echoed back to you. + */ + int flib_netconn_send_chat(flib_netconn *conn, const char *chat); + + /** + * Kick a player. This has different meanings in the lobby and in a room; + * In the lobby, it will kick the player from the server, and you need to be a server admin to + * do it. In a room, it will kick the player from the room, and you need to be room chief. + */ + int flib_netconn_send_kick(flib_netconn *conn, const char *playerName); + + /** + * Request information about a player (e.g. current room, version, partial IP). If the action + * succeeds, you will receive an onMessage callback with NETCONN_MSG_TYPE_PLAYERINFO containing + * the requested information. + */ + int flib_netconn_send_playerInfo(flib_netconn *conn, const char *playerName); + + +// Send functions that only make sense in the lobby + + /** + * Request an update of the room list. Only makes sense when in lobby state. + * If the action succeeds, you will receive an onRoomlist callback containing the current room + * data. + */ + int flib_netconn_send_request_roomlist(flib_netconn *conn); + + /** + * Join a room as guest (not chief). Only makes sense when in lobby state. If the action + * succeeds, you will receive an onEnterRoom callback with chief=false followed by other + * callbacks with current room information. + */ + int flib_netconn_send_joinRoom(flib_netconn *conn, const char *room); + + /** + * Follow a player. Only valid in the lobby. If the player is in a room (or in a game), this + * command is analogous to calling flib_netconn_send_joinRoom with that room. + */ + int flib_netconn_send_playerFollow(flib_netconn *conn, const char *playerName); + + /** + * Create and join a new room. Only makes sense when in lobby state. If the action succeeds, + * you will receive an onEnterRoom callback with chief=true. + */ + int flib_netconn_send_createRoom(flib_netconn *conn, const char *room); + + /** + * Ban a player. The scope of this ban depends on whether you are in a room or in the lobby. + * In a room, you need to be the room chief, and the ban will apply to the room only. In the + * lobby, you need to be server admin to ban someone, and the ban applies to the entire server. + */ + int flib_netconn_send_ban(flib_netconn *conn, const char *playerName); + + /** + * Does something administrator-y. At any rate you need to be an administrator and in the lobby + * to use this command. + */ + int flib_netconn_send_clearAccountsCache(flib_netconn *conn); + + /** + * Sets a server variable to the indicated value. Only makes sense if you are server admin and + * in the lobby. Known variables are MOTD_NEW, MOTD_OLD and LATEST_PROTO. MOTD_OLD is shown to + * players with older protocol versions, to inform them that they might want to update. + */ + int flib_netconn_send_setServerVar(flib_netconn *conn, const char *name, const char *value); + + /** + * Queries all server variables. Only makes sense if you are server admin and in the lobby. + * If the action succeeds, you will receive several onServerVar callbacks with the + * current values of all server variables. + */ + int flib_netconn_send_getServerVars(flib_netconn *conn); + + +// Send functions that only make sense in a room + + /** + * Leave the room for the lobby. Only makes sense in room state. msg can be NULL if you don't + * want to send a message. The server always accepts a part command, so once you send it off, + * you can just assume that you are back in the lobby. + */ + int flib_netconn_send_leaveRoom(flib_netconn *conn, const char *msg); + + /** + * Change your "ready" status in the room. Only makes sense when in room state. If the action + * succeeds, you will receive an onClientFlags callback containing the change. + */ + int flib_netconn_send_toggleReady(flib_netconn *conn); + + /** + * Add a team to the current room. Apart from the "fixed" team information, this also includes + * the color, but not the number of hogs. Only makes sense when in room state. If the action + * succeeds, you will receive an onTeamAccepted callback with the name of the team. + * + * Notes: Technically, sending a color here is the only way for a non-chief to set the color of + * her own team. The server remembers this color and even generates a separate teamColor message + * to inform everyone of it. However, at the moment the frontends generally override this color + * with one they choose themselves in order to deal with unfortunate behavior of the QtFrontend, + * which always sends color index 0 when adding a team but thinks that the team has a random + * color. The chief always sends a new color in order to bring the QtFrontend back into sync. + */ + int flib_netconn_send_addTeam(flib_netconn *conn, const flib_team *team); + + /** + * Remove the team with the name teamname. Only makes sense when in room state. + * The server does not send a reply on success. + */ + int flib_netconn_send_removeTeam(flib_netconn *conn, const char *teamname); + + +// Send functions that only make sense in a room and if you are room chief + + /** + * Rename the current room. Only makes sense in room state and if you are chief. If the action + * succeeds, you (and everyone else on the server) will receive an onRoomUpdate message + * containing the change. + */ + int flib_netconn_send_renameRoom(flib_netconn *conn, const char *roomName); + + /** + * Set the number of hogs for a team. Only makes sense in room state and if you are chief. + * The server does not send a reply. + */ + int flib_netconn_send_teamHogCount(flib_netconn *conn, const char *teamname, int hogcount); + + /** + * Set the teamcolor of a team. Only makes sense in room state and if you are chief. + * The server does not send a reply. + */ + int flib_netconn_send_teamColor(flib_netconn *conn, const char *teamname, int colorIndex); + + /** + * Set the weaponset for the room. Only makes sense in room state and if you are chief. + * The server does not send a reply. + */ + int flib_netconn_send_weaponset(flib_netconn *conn, const flib_weaponset *weaponset); + + /** + * Set the map for the room. Only makes sense in room state and if you are chief. + * The server does not send a reply. + */ + int flib_netconn_send_map(flib_netconn *conn, const flib_map *map); + + /** + * Set the mapname. Only makes sense in room state and if you are chief. + * The server does not send a reply. + */ + int flib_netconn_send_mapName(flib_netconn *conn, const char *mapName); + + /** + * Set the map generator (regular, maze, drawn, named). Only makes sense in room state and if + * you are chief. + * The server does not send a reply. + */ + int flib_netconn_send_mapGen(flib_netconn *conn, int mapGen); + + /** + * Set the map template for regular maps. Only makes sense in room state and if you are chief. + * The server does not send a reply. + */ + int flib_netconn_send_mapTemplate(flib_netconn *conn, int templateFilter); + + /** + * Set the maze template (maze size) for mazes. Only makes sense in room state and if you are + * chief. The server does not send a reply. + */ + int flib_netconn_send_mapMazeSize(flib_netconn *conn, int mazeSize); + + /** + * Set the seed for the map. Only makes sense in room state and if you are chief. + * The server does not send a reply. + */ + int flib_netconn_send_mapSeed(flib_netconn *conn, const char *seed); + + /** + * Set the theme for the map. Only makes sense in room state and if you are chief. + * The server does not send a reply. + */ + int flib_netconn_send_mapTheme(flib_netconn *conn, const char *theme); + + /** + * Set the draw data for the drawn map. Only makes sense in room state and if you are chief. + * The server does not send a reply. + */ + int flib_netconn_send_mapDrawdata(flib_netconn *conn, const uint8_t *drawData, size_t size); + + /** + * Set the script (game style). Only makes sense in room state and if you are chief. + * The server does not send a reply. + */ + int flib_netconn_send_script(flib_netconn *conn, const char *scriptName); + + /** + * Set the scheme. Only makes sense in room state and if you are chief. + * The server does not send a reply. + */ + int flib_netconn_send_scheme(flib_netconn *conn, const flib_scheme *scheme); + + /** + * Signal that you want to start the game. Only makes sense in room state and if you are chief. + * The server will check whether all players are ready and whether it believes the setup makes + * sense (e.g. more than one clan). If the server is satisfied, you will receive an onRunGame + * callback (all other clients in the room are notified the same way). Otherwise the server + * might answer with a warning, or might not answer at all. + */ + int flib_netconn_send_startGame(flib_netconn *conn); + + /** + * Allow/forbid players to join the room. Only makes sense in room state and if you are chief. + * The server does not send a reply. + */ + int flib_netconn_send_toggleRestrictJoins(flib_netconn *conn); + + /** + * Allow/forbid adding teams to the room. Only makes sense in room state and if you are chief. + * The server does not send a reply. + */ + int flib_netconn_send_toggleRestrictTeams(flib_netconn *conn); + + +// Send functions that are only needed for running a game + + /** + * Send a teamchat message, forwarded from the engine. Only makes sense ingame. + * The server does not send a reply. In contrast to a Chat message, the server + * automatically converts this into an engine message and passes it on to the other + * clients. + */ + int flib_netconn_send_teamchat(flib_netconn *conn, const char *msg); + + /** + * Send an engine message. Only makes sense when ingame. In a networked game, you have to pass + * all the engine messages from the engine here, and they will be spread to all other clients + * in the game to keep the game in sync. + */ + int flib_netconn_send_engineMessage(flib_netconn *conn, const uint8_t *message, size_t size); + + /** + * Inform the server that the round has ended. Call this when the engine has disconnected, + * passing 1 if the round ended normally, 0 otherwise. + */ + int flib_netconn_send_roundfinished(flib_netconn *conn, bool withoutError); + + + + + +// Callbacks that are important for connecting/disconnecting + + /** + * onNickTaken is called when connecting to the server, if it turns out that there is already a + * player with the same nick. + * In order to proceed, a new nickname needs to be sent to the server using + * flib_netconn_send_nick() (or of course you can bail out and send a QUIT). + * If you don't set a callback, the netconn will automatically react by generating a new name. + */ + void flib_netconn_onNickTaken(flib_netconn *conn, void (*callback)(void *context, const char *nick), void* context); + + /** + * When connecting with a registered nickname, the server will ask for a password before + * admitting you in. This callback is called when that happens. As a reaction, you can send the + * password using flib_netconn_send_password. If you don't register a callback, the default + * behavior is to just quit in a way that will cause a disconnect with + * NETCONN_DISCONNECT_AUTH_FAILED. + * + * You can't just choose a new nickname when you receive this callback, because at that point + * the server has already accepted your nick. + */ + void flib_netconn_onPasswordRequest(flib_netconn *conn, void (*callback)(void *context, const char *nick), void* context); + + /** + * This is called when the server has accepted our nickname (and possibly password) and we have + * entered the lobby. + */ + void flib_netconn_onConnected(flib_netconn *conn, void (*callback)(void *context), void* context); + + /** + * This is always the last callback (unless the netconn is destroyed early), and the netconn + * should be destroyed when it is received. The reason for the disconnect is passed as one of + * the NETCONN_DISCONNECT_ constants. Sometimes a message is included as well, but that + * parameter might also be NULL. + */ + void flib_netconn_onDisconnected(flib_netconn *conn, void (*callback)(void *context, int reason, const char *message), void* context); + + +// Callbacks that make sense in most situations + + /** + * Callback for several informational messages that should be displayed to the user + * (e.g. in the chat window), but do not require a reaction. If a game is running, you might + * want to redirect some of these messages to the engine as well so the user will see them. + */ + void flib_netconn_onMessage(flib_netconn *conn, void (*callback)(void *context, int msgtype, const char *msg), void* context); + + /** + * We received a chat message. Where this message belongs depends on the current state + * (lobby/room). If a game is running the message should be passed to the engine. + */ + void flib_netconn_onChat(flib_netconn *conn, void (*callback)(void *context, const char *nick, const char *msg), void* context); + + /** + * Callbacks for incremental room list updates. They will fire whenever these events occur, + * even before you first query the actual roomlist - so be sure not to blindly reference your + * room list in these callbacks. The server currently only sends updates when a room changes + * its name, so in order to update other room information you need to query the roomlist again + * (see send_request_roomlist / onRoomlist). + */ + void flib_netconn_onRoomAdd(flib_netconn *conn, void (*callback)(void *context, const flib_room *room), void* context); + void flib_netconn_onRoomDelete(flib_netconn *conn, void (*callback)(void *context, const char *name), void* context); + void flib_netconn_onRoomUpdate(flib_netconn *conn, void (*callback)(void *context, const char *oldName, const flib_room *room), void* context); + + /** + * Callbacks for players joining or leaving the lobby. In contrast to the roomlist updates, you + * will get a JOIN callback for every player already on the server when you join (and there is + * no direct way to query the current playerlist) + * + * NOTE: partMessage may be NULL. + */ + void flib_netconn_onLobbyJoin(flib_netconn *conn, void (*callback)(void *context, const char *nick), void* context); + void flib_netconn_onLobbyLeave(flib_netconn *conn, void (*callback)(void *context, const char *nick, const char *partMessage), void* context); + + /** + * This is called when the server informs us that one or more flags associated with a + * player/client have changed. + * + * nick is the name of the player, flags is a string containing one character for each modified + * flag (see below), and newFlagState signals whether the flags should be set to true or false. + * + * Some of these flags are important for protocol purposes (especially if they are set for you) + * while others are just informational. Also, some flags are only relevant for players who are + * in the same room as you, and the server will not inform you if they change for others. + * + * These are the currently known/used flags: + * a: Server admin. Always updated. + * h: Room chief. Updated when in the same room. + * r: Ready to play. Updated when in the same room. + * u: Registered user. Always updated. + * + * The server tells us the 'a' and 'u' flags for all players when we first join the lobby, and + * also tells us the 'r' and 'h' flags when we join or create a room. It assumes that all flags + * are initially false, so it will typically only tell you to set certain flags to true when + * transmitting the initial states. Reset the 'h' and 'r' flags to false when leaving a room, + * or when entering room state, to arrive at the right state for each player. + * + * The room chief state of yourself is particularly important because it determines whether you + * can modify settings of the current room. Generally, when you create a room you start out + * being room chief, and when you join an existing room you are not. However, if the original + * chief leaves a room, the server can choose a new chief, and if that happens the chief flag + * will be transferred to someone else. + */ + void flib_netconn_onClientFlags(flib_netconn *conn, void (*callback)(void *context, const char *nick, const char *flags, bool newFlagState), void *context); + +// Callbacks that happen only in response to specific requests + + /** + * Response to flib_netconn_send_request_roomlist(). + * The rooms array contains the current state of all rooms on the server. + */ + void flib_netconn_onRoomlist(flib_netconn *conn, void (*callback)(void *context, const flib_room **rooms, int roomCount), void* context); + + /** + * Response to flib_netconn_send_joinRoom, flib_netconn_send_playerFollow or + * flib_netconn_send_createRoom. + * + * You just left the lobby and entered a room. + * If chief is true, you can and should send a full configuration for the room now. This + * consists of ammo, scheme, script and map, where map apparently has to come last. + */ + void flib_netconn_onEnterRoom(flib_netconn *conn, void (*callback)(void *context, bool chief), void *context); + + /** + * Response to flib_netconn_send_addTeam. + * The server might reject your team for several reasons, e.g. because it has the same name as + * an existing team, or because the room chief restricted adding new teams. If the team is + * accepted by the server, this callback is fired. + * + * If you are the room chief, you are expected to provide the hog count for your own team now + * using flib_netconn_send_teamHogCount. The color of the team is already set to the one you + * provided in addTeam. + */ + void flib_netconn_onTeamAccepted(flib_netconn *conn, void (*callback)(void *context, const char *team), void *context); + + /** + * When you query the server vars with flib_netconn_send_getServerVars (only works as admin), + * the server replies with a list of them. This callback is called for each entry in that list. + */ + void flib_netconn_onServerVar(flib_netconn *conn, void (*callback)(void *context, const char *name, const char *value), void *context); + + +// Callbacks that are only relevant in a room + + /** + * You just left a room and entered the lobby again. + * reason is one of the NETCONN_ROOMLEAVE_ constants (usually a kick). + * This will not be called when you actively leave a room using PART. + * Don't confuse with onRoomLeave, which indicates that *someone else* left the room. + */ + void flib_netconn_onLeaveRoom(flib_netconn *conn, void (*callback)(void *context, int reason, const char *message), void *context); + + /** + * Someone joined or left the room you are currently in. + * Analogous to onLobbyJoin/leave, you will receive the join callback for all players that are + * already in the room when you join, including for yourself (this is actually how it is + * determined that you joined a room). + * + * However, you will *not* receive onRoomLeave messages for everyone when you leave the room. + */ + void flib_netconn_onRoomJoin(flib_netconn *conn, void (*callback)(void *context, const char *nick), void* context); + void flib_netconn_onRoomLeave(flib_netconn *conn, void (*callback)(void *context, const char *nick, const char *partMessage), void* context); + + /** + * A new team was added to the room. The person who adds a team does NOT receive this callback + * (he gets onTeamAccepted instead). + * + * The team does not contain bindings, stats, weaponset, color or the number of hogs (but it is + * assumed to be the default of 4). + * + * If you receive this message and you are the room chief, you may want to send a color and hog + * count for this team using flib_netconn_send_teamHogCount / teamColor for QtFrontend + * compatibility. + * + * The server currently sends another message with the color of the team to the same recipients + * as this teamAdd message, which will trigger an onTeamColorChanged callback. See the + * description of flib_netconn_send_addTeam for more information. + */ + void flib_netconn_onTeamAdd(flib_netconn *conn, void (*callback)(void *context, const flib_team *team), void *context); + + /** + * A team was removed from the room. The person who removed the team will not receive this + * callback. + */ + void flib_netconn_onTeamDelete(flib_netconn *conn, void (*callback)(void *context, const char *teamname), void *context); + + /** + * The number of hogs in a team has been changed by the room chief. If you are the chief and + * change the number of hogs yourself, you will not receive this callback. + */ + void flib_netconn_onHogCountChanged(flib_netconn *conn, void (*callback)(void *context, const char *teamName, int hogs), void *context); + + /** + * The color of a team has been set or changed. The client who set or changed the color will + * not receive this callback. + * + * Normally, only the chief can change the color of a team. However, this message is also + * generated when a team is added, so you can receive it even as chief. + */ + void flib_netconn_onTeamColorChanged(flib_netconn *conn, void (*callback)(void *context, const char *teamName, int colorIndex), void *context); + + /** + * The room chief has changed the game scheme (or you just joined a room). + * You will not receive this callback if you changed the scheme yourself. + */ + void flib_netconn_onSchemeChanged(flib_netconn *conn, void (*callback)(void *context, const flib_scheme *scheme), void *context); + + /** + * The room chief has changed the map (or you just joined a room). Only non-chiefs receive these + * messages. + * + * To reduce the number of callback functions, the netconn keeps track of the current map + * settings and always passes the entire current map config, but informs the callee about what + * has changed (see the NETCONN_MAPCHANGE_ constants). + * + * Caution: Due to the way the protocol works, the map might not be complete at this point if it + * is a hand-drawn map, because the "full" map config does not include the drawn map data. + */ + void flib_netconn_onMapChanged(flib_netconn *conn, void (*callback)(void *context, const flib_map *map, int changetype), void *context); + + /** + * The room chief has changed the game style (or you just joined a room). If you are the chief + * and change the style yourself, you will not receive this callback. + */ + void flib_netconn_onScriptChanged(flib_netconn *conn, void (*callback)(void *context, const char *script), void *context); + + /** + * The room chief has changed the weaponset (or you just joined a room). If you are the chief + * and change the weaponset yourself, you will not receive this callback. + */ + void flib_netconn_onWeaponsetChanged(flib_netconn *conn, void (*callback)(void *context, const flib_weaponset *weaponset), void *context); + + /** + * The game is starting. Fire up the engine and join in! + * You can let the netconn generate the right game setup using flib_netconn_create_gamesetup + */ + void flib_netconn_onRunGame(flib_netconn *conn, void (*callback)(void *context), void *context); + + /** + * You are in a room, a game is in progress, and the server is sending you the new input for the + * engine to keep up to date with the current happenings. Pass it on to the engine using + * flib_gameconn_send_enginemsg. + */ + void flib_netconn_onEngineMessage(flib_netconn *conn, void (*callback)(void *context, const uint8_t *message, size_t size), void *context); + +#endif diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/net/netconn_callbacks.c --- a/project_files/frontlib/net/netconn_callbacks.c Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/net/netconn_callbacks.c Tue Jan 21 22:43:06 2014 +0100 @@ -1,149 +1,149 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "netconn_internal.h" - -#include "../util/logging.h" -#include "../util/util.h" - -#include -#include -#include - -static void defaultCallback_onMessage(void *context, int msgtype, const char *msg) { - flib_log_i("Net: [%i] %s", msgtype, msg); -} - -static void defaultCallback_onChat(void *context, const char *nick, const char *msg) { - flib_log_i("%s: %s", nick, msg); -} - -// Change the name by suffixing it with a number. If it already ends in a number, increase that number by 1. -static void defaultCallback_onNickTaken(void *context, const char *requestedNick) { - flib_netconn *conn = context; - size_t namelen = strlen(requestedNick); - int digits = 0; - while(digits0) { - suffix = atol(requestedNick+namelen-digits)+1; - } - char *newPlayerName = flib_asprintf("%.*s%li", namelen-digits, requestedNick, suffix); - if(newPlayerName) { - flib_netconn_send_nick(conn, newPlayerName); - } else { - flib_netconn_send_quit(conn, "Nick already taken."); - } - free(newPlayerName); -} - -// Default behavior: Quit -static void defaultCallback_onPasswordRequest(void *context, const char *requestedNick) { - flib_netconn_send_quit((flib_netconn*)context, "Authentication failed"); -} - -void netconn_clearCallbacks(flib_netconn *conn) { - flib_netconn_onMessage(conn, NULL, NULL); - flib_netconn_onConnected(conn, NULL, NULL); - flib_netconn_onDisconnected(conn, NULL, NULL); - flib_netconn_onRoomlist(conn, NULL, NULL); - flib_netconn_onRoomAdd(conn, NULL, NULL); - flib_netconn_onRoomDelete(conn, NULL, NULL); - flib_netconn_onRoomUpdate(conn, NULL, NULL); - flib_netconn_onClientFlags(conn, NULL, NULL); - flib_netconn_onChat(conn, NULL, NULL); - flib_netconn_onLobbyJoin(conn, NULL, NULL); - flib_netconn_onLobbyLeave(conn, NULL, NULL); - flib_netconn_onRoomJoin(conn, NULL, NULL); - flib_netconn_onRoomLeave(conn, NULL, NULL); - flib_netconn_onNickTaken(conn, NULL, NULL); - flib_netconn_onPasswordRequest(conn, NULL, NULL); - flib_netconn_onEnterRoom(conn, NULL, NULL); - flib_netconn_onLeaveRoom(conn, NULL, NULL); - flib_netconn_onTeamAdd(conn, NULL, NULL); - flib_netconn_onTeamDelete(conn, NULL, NULL); - flib_netconn_onRunGame(conn, NULL, NULL); - flib_netconn_onTeamAccepted(conn, NULL, NULL); - flib_netconn_onHogCountChanged(conn, NULL, NULL); - flib_netconn_onTeamColorChanged(conn, NULL, NULL); - flib_netconn_onEngineMessage(conn, NULL, NULL); - flib_netconn_onSchemeChanged(conn, NULL, NULL); - flib_netconn_onMapChanged(conn, NULL, NULL); - flib_netconn_onScriptChanged(conn, NULL, NULL); - flib_netconn_onWeaponsetChanged(conn, NULL, NULL); - flib_netconn_onServerVar(conn, NULL, NULL); -} - -/** - * This macro generates a callback setter function. It uses the name of the callback to - * automatically generate the function name and the fields to set, so a consistent naming - * convention needs to be enforced (not that that is a bad thing). If null is passed as - * callback to the generated function, the defaultCb will be set instead (with conn - * as the context). - */ -#define GENERATE_CB_SETTER(cbName, cbParameterTypes, defaultCb) \ - void flib_netconn_##cbName(flib_netconn *conn, void (*callback)cbParameterTypes, void *context) { \ - if(!log_badargs_if(conn==NULL)) { \ - conn->cbName##Cb = callback ? callback : &defaultCb; \ - conn->cbName##Ctx = callback ? context : conn; \ - } \ - } - -/** - * Generate a callback setter function like GENERATE_CB_SETTER, and automatically generate a - * no-op callback function as well that is used as default. - */ -#define GENERATE_CB_SETTER_AND_DEFAULT(cbName, cbParameterTypes) \ - static void _noop_callback_##cbName cbParameterTypes {} \ - GENERATE_CB_SETTER(cbName, cbParameterTypes, _noop_callback_##cbName) - -GENERATE_CB_SETTER(onMessage, (void *context, int msgtype, const char *msg), defaultCallback_onMessage); -GENERATE_CB_SETTER_AND_DEFAULT(onConnected, (void *context)); -GENERATE_CB_SETTER_AND_DEFAULT(onDisconnected, (void *context, int reason, const char *message)); -GENERATE_CB_SETTER_AND_DEFAULT(onRoomlist, (void *context, const flib_room **rooms, int roomCount)); -GENERATE_CB_SETTER_AND_DEFAULT(onRoomAdd, (void *context, const flib_room *room)); -GENERATE_CB_SETTER_AND_DEFAULT(onRoomDelete, (void *context, const char *name)); -GENERATE_CB_SETTER_AND_DEFAULT(onRoomUpdate, (void *context, const char *oldName, const flib_room *room)); -GENERATE_CB_SETTER_AND_DEFAULT(onClientFlags, (void *context, const char *nick, const char *flags, bool newFlagState)); -GENERATE_CB_SETTER(onChat, (void *context, const char *nick, const char *msg), defaultCallback_onChat); -GENERATE_CB_SETTER_AND_DEFAULT(onLobbyJoin, (void *context, const char *nick)); -GENERATE_CB_SETTER_AND_DEFAULT(onLobbyLeave, (void *context, const char *nick, const char *partMsg)); -GENERATE_CB_SETTER_AND_DEFAULT(onRoomJoin, (void *context, const char *nick)); -GENERATE_CB_SETTER_AND_DEFAULT(onRoomLeave, (void *context, const char *nick, const char *partMessage)); -GENERATE_CB_SETTER(onNickTaken, (void *context, const char *nick), defaultCallback_onNickTaken); -GENERATE_CB_SETTER(onPasswordRequest, (void *context, const char *nick), defaultCallback_onPasswordRequest); -GENERATE_CB_SETTER_AND_DEFAULT(onEnterRoom, (void *context, bool chief)); -GENERATE_CB_SETTER_AND_DEFAULT(onLeaveRoom, (void *context, int reason, const char *message)); -GENERATE_CB_SETTER_AND_DEFAULT(onTeamAdd, (void *context, const flib_team *team)); -GENERATE_CB_SETTER_AND_DEFAULT(onTeamDelete, (void *context, const char *teamname)); -GENERATE_CB_SETTER_AND_DEFAULT(onRunGame, (void *context)); -GENERATE_CB_SETTER_AND_DEFAULT(onTeamAccepted, (void *context, const char *teamName)); -GENERATE_CB_SETTER_AND_DEFAULT(onHogCountChanged, (void *context, const char *teamName, int hogs)); -GENERATE_CB_SETTER_AND_DEFAULT(onTeamColorChanged, (void *context, const char *teamName, int colorIndex)); -GENERATE_CB_SETTER_AND_DEFAULT(onEngineMessage, (void *context, const uint8_t *message, size_t size)); -GENERATE_CB_SETTER_AND_DEFAULT(onSchemeChanged, (void *context, const flib_scheme *scheme)); -GENERATE_CB_SETTER_AND_DEFAULT(onMapChanged, (void *context, const flib_map *map, int changetype)); -GENERATE_CB_SETTER_AND_DEFAULT(onScriptChanged, (void *context, const char *script)); -GENERATE_CB_SETTER_AND_DEFAULT(onWeaponsetChanged, (void *context, const flib_weaponset *weaponset)); -GENERATE_CB_SETTER_AND_DEFAULT(onServerVar, (void *context, const char *name, const char *value)); - -#undef GENERATE_CB_SETTER_AND_DEFAULT -#undef GENERATE_CB_SETTER +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "netconn_internal.h" + +#include "../util/logging.h" +#include "../util/util.h" + +#include +#include +#include + +static void defaultCallback_onMessage(void *context, int msgtype, const char *msg) { + flib_log_i("Net: [%i] %s", msgtype, msg); +} + +static void defaultCallback_onChat(void *context, const char *nick, const char *msg) { + flib_log_i("%s: %s", nick, msg); +} + +// Change the name by suffixing it with a number. If it already ends in a number, increase that number by 1. +static void defaultCallback_onNickTaken(void *context, const char *requestedNick) { + flib_netconn *conn = context; + size_t namelen = strlen(requestedNick); + int digits = 0; + while(digits0) { + suffix = atol(requestedNick+namelen-digits)+1; + } + char *newPlayerName = flib_asprintf("%.*s%li", namelen-digits, requestedNick, suffix); + if(newPlayerName) { + flib_netconn_send_nick(conn, newPlayerName); + } else { + flib_netconn_send_quit(conn, "Nick already taken."); + } + free(newPlayerName); +} + +// Default behavior: Quit +static void defaultCallback_onPasswordRequest(void *context, const char *requestedNick) { + flib_netconn_send_quit((flib_netconn*)context, "Authentication failed"); +} + +void netconn_clearCallbacks(flib_netconn *conn) { + flib_netconn_onMessage(conn, NULL, NULL); + flib_netconn_onConnected(conn, NULL, NULL); + flib_netconn_onDisconnected(conn, NULL, NULL); + flib_netconn_onRoomlist(conn, NULL, NULL); + flib_netconn_onRoomAdd(conn, NULL, NULL); + flib_netconn_onRoomDelete(conn, NULL, NULL); + flib_netconn_onRoomUpdate(conn, NULL, NULL); + flib_netconn_onClientFlags(conn, NULL, NULL); + flib_netconn_onChat(conn, NULL, NULL); + flib_netconn_onLobbyJoin(conn, NULL, NULL); + flib_netconn_onLobbyLeave(conn, NULL, NULL); + flib_netconn_onRoomJoin(conn, NULL, NULL); + flib_netconn_onRoomLeave(conn, NULL, NULL); + flib_netconn_onNickTaken(conn, NULL, NULL); + flib_netconn_onPasswordRequest(conn, NULL, NULL); + flib_netconn_onEnterRoom(conn, NULL, NULL); + flib_netconn_onLeaveRoom(conn, NULL, NULL); + flib_netconn_onTeamAdd(conn, NULL, NULL); + flib_netconn_onTeamDelete(conn, NULL, NULL); + flib_netconn_onRunGame(conn, NULL, NULL); + flib_netconn_onTeamAccepted(conn, NULL, NULL); + flib_netconn_onHogCountChanged(conn, NULL, NULL); + flib_netconn_onTeamColorChanged(conn, NULL, NULL); + flib_netconn_onEngineMessage(conn, NULL, NULL); + flib_netconn_onSchemeChanged(conn, NULL, NULL); + flib_netconn_onMapChanged(conn, NULL, NULL); + flib_netconn_onScriptChanged(conn, NULL, NULL); + flib_netconn_onWeaponsetChanged(conn, NULL, NULL); + flib_netconn_onServerVar(conn, NULL, NULL); +} + +/** + * This macro generates a callback setter function. It uses the name of the callback to + * automatically generate the function name and the fields to set, so a consistent naming + * convention needs to be enforced (not that that is a bad thing). If null is passed as + * callback to the generated function, the defaultCb will be set instead (with conn + * as the context). + */ +#define GENERATE_CB_SETTER(cbName, cbParameterTypes, defaultCb) \ + void flib_netconn_##cbName(flib_netconn *conn, void (*callback)cbParameterTypes, void *context) { \ + if(!log_badargs_if(conn==NULL)) { \ + conn->cbName##Cb = callback ? callback : &defaultCb; \ + conn->cbName##Ctx = callback ? context : conn; \ + } \ + } + +/** + * Generate a callback setter function like GENERATE_CB_SETTER, and automatically generate a + * no-op callback function as well that is used as default. + */ +#define GENERATE_CB_SETTER_AND_DEFAULT(cbName, cbParameterTypes) \ + static void _noop_callback_##cbName cbParameterTypes {} \ + GENERATE_CB_SETTER(cbName, cbParameterTypes, _noop_callback_##cbName) + +GENERATE_CB_SETTER(onMessage, (void *context, int msgtype, const char *msg), defaultCallback_onMessage); +GENERATE_CB_SETTER_AND_DEFAULT(onConnected, (void *context)); +GENERATE_CB_SETTER_AND_DEFAULT(onDisconnected, (void *context, int reason, const char *message)); +GENERATE_CB_SETTER_AND_DEFAULT(onRoomlist, (void *context, const flib_room **rooms, int roomCount)); +GENERATE_CB_SETTER_AND_DEFAULT(onRoomAdd, (void *context, const flib_room *room)); +GENERATE_CB_SETTER_AND_DEFAULT(onRoomDelete, (void *context, const char *name)); +GENERATE_CB_SETTER_AND_DEFAULT(onRoomUpdate, (void *context, const char *oldName, const flib_room *room)); +GENERATE_CB_SETTER_AND_DEFAULT(onClientFlags, (void *context, const char *nick, const char *flags, bool newFlagState)); +GENERATE_CB_SETTER(onChat, (void *context, const char *nick, const char *msg), defaultCallback_onChat); +GENERATE_CB_SETTER_AND_DEFAULT(onLobbyJoin, (void *context, const char *nick)); +GENERATE_CB_SETTER_AND_DEFAULT(onLobbyLeave, (void *context, const char *nick, const char *partMsg)); +GENERATE_CB_SETTER_AND_DEFAULT(onRoomJoin, (void *context, const char *nick)); +GENERATE_CB_SETTER_AND_DEFAULT(onRoomLeave, (void *context, const char *nick, const char *partMessage)); +GENERATE_CB_SETTER(onNickTaken, (void *context, const char *nick), defaultCallback_onNickTaken); +GENERATE_CB_SETTER(onPasswordRequest, (void *context, const char *nick), defaultCallback_onPasswordRequest); +GENERATE_CB_SETTER_AND_DEFAULT(onEnterRoom, (void *context, bool chief)); +GENERATE_CB_SETTER_AND_DEFAULT(onLeaveRoom, (void *context, int reason, const char *message)); +GENERATE_CB_SETTER_AND_DEFAULT(onTeamAdd, (void *context, const flib_team *team)); +GENERATE_CB_SETTER_AND_DEFAULT(onTeamDelete, (void *context, const char *teamname)); +GENERATE_CB_SETTER_AND_DEFAULT(onRunGame, (void *context)); +GENERATE_CB_SETTER_AND_DEFAULT(onTeamAccepted, (void *context, const char *teamName)); +GENERATE_CB_SETTER_AND_DEFAULT(onHogCountChanged, (void *context, const char *teamName, int hogs)); +GENERATE_CB_SETTER_AND_DEFAULT(onTeamColorChanged, (void *context, const char *teamName, int colorIndex)); +GENERATE_CB_SETTER_AND_DEFAULT(onEngineMessage, (void *context, const uint8_t *message, size_t size)); +GENERATE_CB_SETTER_AND_DEFAULT(onSchemeChanged, (void *context, const flib_scheme *scheme)); +GENERATE_CB_SETTER_AND_DEFAULT(onMapChanged, (void *context, const flib_map *map, int changetype)); +GENERATE_CB_SETTER_AND_DEFAULT(onScriptChanged, (void *context, const char *script)); +GENERATE_CB_SETTER_AND_DEFAULT(onWeaponsetChanged, (void *context, const flib_weaponset *weaponset)); +GENERATE_CB_SETTER_AND_DEFAULT(onServerVar, (void *context, const char *name, const char *value)); + +#undef GENERATE_CB_SETTER_AND_DEFAULT +#undef GENERATE_CB_SETTER diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/net/netconn_internal.h --- a/project_files/frontlib/net/netconn_internal.h Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/net/netconn_internal.h Tue Jan 21 22:43:06 2014 +0100 @@ -1,151 +1,151 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * Common definitions needed by netconn functions, to allow splitting them into several files. - */ - -#ifndef NETCONN_INTERNAL_H_ -#define NETCONN_INTERNAL_H_ - -#include "netconn.h" -#include "netbase.h" -#include "../model/map.h" -#include "../model/team.h" -#include "../model/weapon.h" -#include "../model/room.h" - -#include -#include -#include - -struct _flib_netconn { - flib_netbase *netBase; - char *playerName; - char *dataDirPath; - - int netconnState; //!< One of the NETCONN_STATE constants - - bool isChief; //!< Player can modify the current room - flib_map *map; - flib_teamlist pendingTeamlist; - flib_teamlist teamlist; - flib_scheme *scheme; - char *style; - flib_weaponset *weaponset; - - void (*onMessageCb)(void *context, int msgtype, const char *msg); - void *onMessageCtx; - - void (*onConnectedCb)(void *context); - void *onConnectedCtx; - - void (*onDisconnectedCb)(void *context, int reason, const char *message); - void *onDisconnectedCtx; - - void (*onRoomlistCb)(void *context, const flib_room **rooms, int roomCount); - void *onRoomlistCtx; - - void (*onRoomAddCb)(void *context, const flib_room *room); - void *onRoomAddCtx; - - void (*onRoomDeleteCb)(void *context, const char *name); - void *onRoomDeleteCtx; - - void (*onRoomUpdateCb)(void *context, const char *oldName, const flib_room *room); - void *onRoomUpdateCtx; - - void (*onClientFlagsCb)(void *context, const char *nick, const char *flags, bool newFlagState); - void *onClientFlagsCtx; - - void (*onChatCb)(void *context, const char *nick, const char *msg); - void *onChatCtx; - - void (*onLobbyJoinCb)(void *context, const char *nick); - void *onLobbyJoinCtx; - - void (*onLobbyLeaveCb)(void *context, const char *nick, const char *partMessage); - void *onLobbyLeaveCtx; - - void (*onRoomJoinCb)(void *context, const char *nick); - void *onRoomJoinCtx; - - void (*onRoomLeaveCb)(void *context, const char *nick, const char *partMessage); - void *onRoomLeaveCtx; - - void (*onNickTakenCb)(void *context, const char *nick); - void *onNickTakenCtx; - - void (*onPasswordRequestCb)(void *context, const char *nick); - void *onPasswordRequestCtx; - - void (*onEnterRoomCb)(void *context, bool chief); - void *onEnterRoomCtx; - - void (*onLeaveRoomCb)(void *context, int reason, const char *message); - void *onLeaveRoomCtx; - - void (*onTeamAddCb)(void *context, const flib_team *team); - void *onTeamAddCtx; - - void (*onTeamDeleteCb)(void *context, const char *teamname); - void *onTeamDeleteCtx; - - void (*onRunGameCb)(void *context); - void *onRunGameCtx; - - void (*onTeamAcceptedCb)(void *context, const char *teamName); - void *onTeamAcceptedCtx; - - void (*onHogCountChangedCb)(void *context, const char *teamName, int hogs); - void *onHogCountChangedCtx; - - void (*onTeamColorChangedCb)(void *context, const char *teamName, int colorIndex); - void *onTeamColorChangedCtx; - - void (*onEngineMessageCb)(void *context, const uint8_t *message, size_t size); - void *onEngineMessageCtx; - - void (*onSchemeChangedCb)(void *context, const flib_scheme *scheme); - void *onSchemeChangedCtx; - - void (*onMapChangedCb)(void *context, const flib_map *map, int changetype); - void *onMapChangedCtx; - - void (*onScriptChangedCb)(void *context, const char *script); - void *onScriptChangedCtx; - - void (*onWeaponsetChangedCb)(void *context, const flib_weaponset *weaponset); - void *onWeaponsetChangedCtx; - - void (*onServerVarCb)(void *context, const char *name, const char *value); - void *onServerVarCtx; - - bool running; - bool destroyRequested; -}; - -void netconn_clearCallbacks(flib_netconn *conn); -void netconn_leaveRoom(flib_netconn *conn); -void netconn_setMap(flib_netconn *conn, const flib_map *map); -void netconn_setWeaponset(flib_netconn *conn, const flib_weaponset *weaponset); -void netconn_setScript(flib_netconn *conn, const char *script); -void netconn_setScheme(flib_netconn *conn, const flib_scheme *scheme); - -#endif +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * Common definitions needed by netconn functions, to allow splitting them into several files. + */ + +#ifndef NETCONN_INTERNAL_H_ +#define NETCONN_INTERNAL_H_ + +#include "netconn.h" +#include "netbase.h" +#include "../model/map.h" +#include "../model/team.h" +#include "../model/weapon.h" +#include "../model/room.h" + +#include +#include +#include + +struct _flib_netconn { + flib_netbase *netBase; + char *playerName; + char *dataDirPath; + + int netconnState; //!< One of the NETCONN_STATE constants + + bool isChief; //!< Player can modify the current room + flib_map *map; + flib_teamlist pendingTeamlist; + flib_teamlist teamlist; + flib_scheme *scheme; + char *style; + flib_weaponset *weaponset; + + void (*onMessageCb)(void *context, int msgtype, const char *msg); + void *onMessageCtx; + + void (*onConnectedCb)(void *context); + void *onConnectedCtx; + + void (*onDisconnectedCb)(void *context, int reason, const char *message); + void *onDisconnectedCtx; + + void (*onRoomlistCb)(void *context, const flib_room **rooms, int roomCount); + void *onRoomlistCtx; + + void (*onRoomAddCb)(void *context, const flib_room *room); + void *onRoomAddCtx; + + void (*onRoomDeleteCb)(void *context, const char *name); + void *onRoomDeleteCtx; + + void (*onRoomUpdateCb)(void *context, const char *oldName, const flib_room *room); + void *onRoomUpdateCtx; + + void (*onClientFlagsCb)(void *context, const char *nick, const char *flags, bool newFlagState); + void *onClientFlagsCtx; + + void (*onChatCb)(void *context, const char *nick, const char *msg); + void *onChatCtx; + + void (*onLobbyJoinCb)(void *context, const char *nick); + void *onLobbyJoinCtx; + + void (*onLobbyLeaveCb)(void *context, const char *nick, const char *partMessage); + void *onLobbyLeaveCtx; + + void (*onRoomJoinCb)(void *context, const char *nick); + void *onRoomJoinCtx; + + void (*onRoomLeaveCb)(void *context, const char *nick, const char *partMessage); + void *onRoomLeaveCtx; + + void (*onNickTakenCb)(void *context, const char *nick); + void *onNickTakenCtx; + + void (*onPasswordRequestCb)(void *context, const char *nick); + void *onPasswordRequestCtx; + + void (*onEnterRoomCb)(void *context, bool chief); + void *onEnterRoomCtx; + + void (*onLeaveRoomCb)(void *context, int reason, const char *message); + void *onLeaveRoomCtx; + + void (*onTeamAddCb)(void *context, const flib_team *team); + void *onTeamAddCtx; + + void (*onTeamDeleteCb)(void *context, const char *teamname); + void *onTeamDeleteCtx; + + void (*onRunGameCb)(void *context); + void *onRunGameCtx; + + void (*onTeamAcceptedCb)(void *context, const char *teamName); + void *onTeamAcceptedCtx; + + void (*onHogCountChangedCb)(void *context, const char *teamName, int hogs); + void *onHogCountChangedCtx; + + void (*onTeamColorChangedCb)(void *context, const char *teamName, int colorIndex); + void *onTeamColorChangedCtx; + + void (*onEngineMessageCb)(void *context, const uint8_t *message, size_t size); + void *onEngineMessageCtx; + + void (*onSchemeChangedCb)(void *context, const flib_scheme *scheme); + void *onSchemeChangedCtx; + + void (*onMapChangedCb)(void *context, const flib_map *map, int changetype); + void *onMapChangedCtx; + + void (*onScriptChangedCb)(void *context, const char *script); + void *onScriptChangedCtx; + + void (*onWeaponsetChangedCb)(void *context, const flib_weaponset *weaponset); + void *onWeaponsetChangedCtx; + + void (*onServerVarCb)(void *context, const char *name, const char *value); + void *onServerVarCtx; + + bool running; + bool destroyRequested; +}; + +void netconn_clearCallbacks(flib_netconn *conn); +void netconn_leaveRoom(flib_netconn *conn); +void netconn_setMap(flib_netconn *conn, const flib_map *map); +void netconn_setWeaponset(flib_netconn *conn, const flib_weaponset *weaponset); +void netconn_setScript(flib_netconn *conn, const char *script); +void netconn_setScheme(flib_netconn *conn, const flib_scheme *scheme); + +#endif diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/net/netconn_send.c --- a/project_files/frontlib/net/netconn_send.c Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/net/netconn_send.c Tue Jan 21 22:43:06 2014 +0100 @@ -1,495 +1,495 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "netconn_internal.h" - -#include "../util/logging.h" -#include "../util/util.h" -#include "../util/buffer.h" -#include "../md5/md5.h" -#include "../base64/base64.h" - -#include - -#include -#include -#include - -// cmdname is always given as literal from functions in this file, so it is never null. -static int sendVoid(flib_netconn *conn, const char *cmdname) { - if(log_e_if(!conn, "Invalid parameter sending %s command", cmdname)) { - return -1; - } - return flib_netbase_sendf(conn->netBase, "%s\n\n", cmdname); -} - -// Testing for !*str prevents sending 0-length parameters (they trip up the protocol) -static int sendStr(flib_netconn *conn, const char *cmdname, const char *str) { - if(log_e_if(!conn || flib_strempty(str), "Invalid parameter sending %s command", cmdname)) { - return -1; - } - return flib_netbase_sendf(conn->netBase, "%s\n%s\n\n", cmdname, str); -} - -static int sendInt(flib_netconn *conn, const char *cmdname, int param) { - if(log_e_if(!conn, "Invalid parameter sending %s command", cmdname)) { - return -1; - } - return flib_netbase_sendf(conn->netBase, "%s\n%i\n\n", cmdname, param); -} - -int flib_netconn_send_nick(flib_netconn *conn, const char *nick) { - int result = -1; - if(!log_badargs_if2(conn==NULL, flib_strempty(nick))) { - char *tmpName = flib_strdupnull(nick); - if(tmpName) { - if(!flib_netbase_sendf(conn->netBase, "%s\n%s\n\n", "NICK", nick)) { - free(conn->playerName); - conn->playerName = tmpName; - tmpName = NULL; - result = 0; - } - } - free(tmpName); - } - return result; -} - -int flib_netconn_send_password(flib_netconn *conn, const char *passwd) { - int result = -1; - if(!log_badargs_if2(conn==NULL, passwd==NULL)) { - md5_state_t md5state; - uint8_t md5bytes[16]; - char md5hex[33]; - md5_init(&md5state); - md5_append(&md5state, (unsigned char*)passwd, strlen(passwd)); - md5_finish(&md5state, md5bytes); - for(int i=0;inetBase, "%s\n%s\n\n", "PASSWORD", md5hex); - } - return result; -} - -int flib_netconn_send_quit(flib_netconn *conn, const char *quitmsg) { - return sendStr(conn, "QUIT", (quitmsg && *quitmsg) ? quitmsg : "User quit"); -} - -int flib_netconn_send_chat(flib_netconn *conn, const char *chat) { - if(!flib_strempty(chat)) { - return sendStr(conn, "CHAT", chat); - } - return 0; -} - -int flib_netconn_send_kick(flib_netconn *conn, const char *playerName) { - return sendStr(conn, "KICK", playerName); -} - -int flib_netconn_send_playerInfo(flib_netconn *conn, const char *playerName) { - return sendStr(conn, "INFO", playerName); -} - -int flib_netconn_send_request_roomlist(flib_netconn *conn) { - return sendVoid(conn, "LIST"); -} - -int flib_netconn_send_joinRoom(flib_netconn *conn, const char *room) { - if(!sendStr(conn, "JOIN_ROOM", room)) { - conn->isChief = false; - return 0; - } - return -1; -} - -int flib_netconn_send_playerFollow(flib_netconn *conn, const char *playerName) { - return sendStr(conn, "FOLLOW", playerName); -} - -int flib_netconn_send_createRoom(flib_netconn *conn, const char *room) { - if(!sendStr(conn, "CREATE_ROOM", room)) { - conn->isChief = true; - return 0; - } - return -1; -} - -int flib_netconn_send_ban(flib_netconn *conn, const char *playerName) { - return sendStr(conn, "BAN", playerName); -} - -int flib_netconn_send_clearAccountsCache(flib_netconn *conn) { - return sendVoid(conn, "CLEAR_ACCOUNTS_CACHE"); -} - -int flib_netconn_send_setServerVar(flib_netconn *conn, const char *name, const char *value) { - if(log_badargs_if3(conn==NULL, flib_strempty(name), flib_strempty(value))) { - return -1; - } - return flib_netbase_sendf(conn->netBase, "%s\n%s\n%s\n\n", "SET_SERVER_VAR", name, value); -} - -int flib_netconn_send_getServerVars(flib_netconn *conn) { - return sendVoid(conn, "GET_SERVER_VAR"); -} -int flib_netconn_send_leaveRoom(flib_netconn *conn, const char *str) { - int result = -1; - if(conn->netconnState==NETCONN_STATE_ROOM) { - result = (str && *str) ? sendStr(conn, "PART", str) : sendVoid(conn, "PART"); - if(!result) { - netconn_leaveRoom(conn); - } - } - return result; -} - -int flib_netconn_send_toggleReady(flib_netconn *conn) { - return sendVoid(conn, "TOGGLE_READY"); -} - -static void addTeamToPendingList(flib_netconn *conn, const flib_team *team) { - flib_team *teamcopy = flib_team_copy(team); - if(teamcopy) { - teamcopy->remoteDriven = false; - free(teamcopy->ownerName); - teamcopy->ownerName = flib_strdupnull(conn->playerName); - if(teamcopy->ownerName) { - flib_teamlist_delete(&conn->pendingTeamlist, team->name); - if(!flib_teamlist_insert(&conn->pendingTeamlist, teamcopy, 0)) { - teamcopy = NULL; - } - } - } - flib_team_destroy(teamcopy); -} - -int flib_netconn_send_addTeam(flib_netconn *conn, const flib_team *team) { - int result = -1; - if(!log_badargs_if2(conn==NULL, team==NULL)) { - bool missingInfo = flib_strempty(team->name) || flib_strempty(team->grave) || flib_strempty(team->fort) || flib_strempty(team->voicepack) || flib_strempty(team->flag); - for(int i=0; ihogs[i].name) || flib_strempty(team->hogs[i].hat); - } - if(!log_e_if(missingInfo, "Incomplete team definition")) { - flib_vector *vec = flib_vector_create(); - if(vec) { - bool error = false; - error |= flib_vector_appendf(vec, "ADD_TEAM\n%s\n%i\n%s\n%s\n%s\n%s\n%i\n", team->name, team->colorIndex, team->grave, team->fort, team->voicepack, team->flag, team->hogs[0].difficulty); - for(int i=0; ihogs[i].name, team->hogs[i].hat); - } - error |= flib_vector_appendf(vec, "\n"); - if(!error && !flib_netbase_send_raw(conn->netBase, flib_vector_data(vec), flib_vector_size(vec))) { - addTeamToPendingList(conn, team); - result = 0; - } - } - flib_vector_destroy(vec); - } - } - return result; -} - -int flib_netconn_send_removeTeam(flib_netconn *conn, const char *teamname) { - flib_team *team = flib_teamlist_find(&conn->teamlist, teamname); - if(team && !team->remoteDriven && !sendStr(conn, "REMOVE_TEAM", teamname)) { - flib_teamlist_delete(&conn->teamlist, teamname); - return 0; - } - return -1; -} - -int flib_netconn_send_renameRoom(flib_netconn *conn, const char *roomName) { - return sendStr(conn, "ROOM_NAME", roomName); -} - -int flib_netconn_send_teamHogCount(flib_netconn *conn, const char *teamname, int hogcount) { - if(!log_badargs_if5(conn==NULL, flib_strempty(teamname), hogcount<1, hogcount>HEDGEHOGS_PER_TEAM, !conn->isChief) - && !flib_netbase_sendf(conn->netBase, "HH_NUM\n%s\n%i\n\n", teamname, hogcount)) { - flib_team *team = flib_teamlist_find(&conn->teamlist, teamname); - if(team) { - team->hogsInGame = hogcount; - } - return 0; - } - return -1; -} - -int flib_netconn_send_teamColor(flib_netconn *conn, const char *teamname, int colorIndex) { - if(!log_badargs_if3(conn==NULL, flib_strempty(teamname), !conn->isChief) - && !flib_netbase_sendf(conn->netBase, "TEAM_COLOR\n%s\n%i\n\n", teamname, colorIndex)) { - flib_team *team = flib_teamlist_find(&conn->teamlist, teamname); - if(team) { - team->colorIndex = colorIndex; - } - return 0; - } - return -1; -} - -int flib_netconn_send_weaponset(flib_netconn *conn, const flib_weaponset *weaponset) { - if(!log_badargs_if3(conn==NULL, weaponset==NULL, flib_strempty(weaponset->name))) { - char ammostring[WEAPONS_COUNT*4+1]; - strcpy(ammostring, weaponset->loadout); - strcat(ammostring, weaponset->crateprob); - strcat(ammostring, weaponset->delay); - strcat(ammostring, weaponset->crateammo); - if(conn->isChief) { - if(!flib_netbase_sendf(conn->netBase, "CFG\nAMMO\n%s\n%s\n\n", weaponset->name, ammostring)) { - netconn_setWeaponset(conn, weaponset); - return 0; - } - } - } - return -1; -} - -int flib_netconn_send_map(flib_netconn *conn, const flib_map *map) { - if(log_badargs_if2(conn==NULL, map==NULL)) { - return -1; - } - bool error = false; - - if(map->seed) { - error |= flib_netconn_send_mapSeed(conn, map->seed); - } - error |= flib_netconn_send_mapTemplate(conn, map->templateFilter); - if(map->theme) { - error |= flib_netconn_send_mapTheme(conn, map->theme); - } - error |= flib_netconn_send_mapGen(conn, map->mapgen); - error |= flib_netconn_send_mapMazeSize(conn, map->mazeSize); - if(map->drawData && map->drawDataSize>0) { - error |= flib_netconn_send_mapDrawdata(conn, map->drawData, map->drawDataSize); - } - // Name is sent last, because the QtFrontend uses this to update its preview, and to show/hide - // certain fields - if(map->name) { - error |= flib_netconn_send_mapName(conn, map->name); - } - return error; -} - -int flib_netconn_send_mapName(flib_netconn *conn, const char *mapName) { - if(log_badargs_if2(conn==NULL, mapName==NULL)) { - return -1; - } - if(conn->isChief) { - if(!sendStr(conn, "CFG\nMAP", mapName)) { - char *copy = flib_strdupnull(mapName); - if(copy) { - free(conn->map->name); - conn->map->name = copy; - return 0; - } - } - } - return -1; -} - -int flib_netconn_send_mapGen(flib_netconn *conn, int mapGen) { - if(log_badargs_if(conn==NULL)) { - return -1; - } - if(conn->isChief) { - if(!sendInt(conn, "CFG\nMAPGEN", mapGen)) { - conn->map->mapgen = mapGen; - return 0; - } - } - return -1; -} - -int flib_netconn_send_mapTemplate(flib_netconn *conn, int templateFilter) { - if(log_badargs_if(conn==NULL)) { - return -1; - } - if(conn->isChief) { - if(!sendInt(conn, "CFG\nTEMPLATE", templateFilter)) { - conn->map->templateFilter = templateFilter; - return 0; - } - } - return -1; -} - -int flib_netconn_send_mapMazeSize(flib_netconn *conn, int mazeSize) { - if(log_badargs_if(conn==NULL)) { - return -1; - } - if(conn->isChief) { - if(!sendInt(conn, "CFG\nMAZE_SIZE", mazeSize)) { - conn->map->mazeSize = mazeSize; - return 0; - } - } - return -1; -} - -int flib_netconn_send_mapSeed(flib_netconn *conn, const char *seed) { - if(log_badargs_if2(conn==NULL, seed==NULL)) { - return -1; - } - if(conn->isChief) { - if(!sendStr(conn, "CFG\nSEED", seed)) { - char *copy = flib_strdupnull(seed); - if(copy) { - free(conn->map->seed); - conn->map->seed = copy; - return 0; - } - } - } - return -1; -} - -int flib_netconn_send_mapTheme(flib_netconn *conn, const char *theme) { - if(log_badargs_if2(conn==NULL, theme==NULL)) { - return -1; - } - if(conn->isChief) { - if(!sendStr(conn, "CFG\nTHEME", theme)) { - char *copy = flib_strdupnull(theme); - if(copy) { - free(conn->map->theme); - conn->map->theme = copy; - return 0; - } - } - } - return -1; -} - -int flib_netconn_send_mapDrawdata(flib_netconn *conn, const uint8_t *drawData, size_t size) { - int result = -1; - if(!log_badargs_if3(conn==NULL, drawData==NULL && size>0, size>SIZE_MAX/2) && conn->isChief) { - uLongf zippedSize = compressBound(size); - uint8_t *zipped = flib_malloc(zippedSize+4); // 4 extra bytes for header - if(zipped) { - // Create the QCompress size header (uint32 big endian) - zipped[0] = (size>>24) & 0xff; - zipped[1] = (size>>16) & 0xff; - zipped[2] = (size>>8) & 0xff; - zipped[3] = (size) & 0xff; - - if(compress(zipped+4, &zippedSize, drawData, size) != Z_OK) { - flib_log_e("Error compressing drawn map data."); - } else { - char *base64encout = NULL; - base64_encode_alloc((const char*)zipped, zippedSize+4, &base64encout); - if(!base64encout) { - flib_log_e("Error base64-encoding drawn map data."); - } else { - result = flib_netbase_sendf(conn->netBase, "CFG\nDRAWNMAP\n%s\n\n", base64encout); - } - free(base64encout); - } - } - free(zipped); - } - - if(!result) { - uint8_t *copy = flib_bufdupnull(drawData, size); - if(copy) { - free(conn->map->drawData); - conn->map->drawData = copy; - conn->map->drawDataSize = size; - } - } - return result; -} - -int flib_netconn_send_script(flib_netconn *conn, const char *scriptName) { - if(log_badargs_if2(conn==NULL, scriptName==NULL)) { - return -1; - } - if(conn->isChief) { - if(!sendStr(conn, "CFG\nSCRIPT", scriptName)) { - netconn_setScript(conn, scriptName); - return 0; - } - } - return -1; -} - -int flib_netconn_send_scheme(flib_netconn *conn, const flib_scheme *scheme) { - int result = -1; - if(!log_badargs_if3(conn==NULL, scheme==NULL, flib_strempty(scheme->name)) && conn->isChief) { - flib_vector *vec = flib_vector_create(); - if(vec) { - bool error = false; - error |= flib_vector_appendf(vec, "CFG\nSCHEME\n%s\n", scheme->name); - for(int i=0; imods[i] ? "true" : "false"); - } - for(int i=0; isettings[i]); - } - error |= flib_vector_appendf(vec, "\n"); - if(!error) { - result = flib_netbase_send_raw(conn->netBase, flib_vector_data(vec), flib_vector_size(vec)); - } - } - flib_vector_destroy(vec); - } - - if(!result) { - netconn_setScheme(conn, scheme); - } - return result; -} - -int flib_netconn_send_startGame(flib_netconn *conn) { - return sendVoid(conn, "START_GAME"); -} - -int flib_netconn_send_toggleRestrictJoins(flib_netconn *conn) { - return sendVoid(conn, "TOGGLE_RESTRICT_JOINS"); -} - -int flib_netconn_send_toggleRestrictTeams(flib_netconn *conn) { - return sendVoid(conn, "TOGGLE_RESTRICT_TEAMS"); -} - -int flib_netconn_send_teamchat(flib_netconn *conn, const char *chat) { - if(!flib_strempty(chat)) { - return sendStr(conn, "TEAMCHAT", chat); - } - return 0; -} - -int flib_netconn_send_engineMessage(flib_netconn *conn, const uint8_t *message, size_t size) { - int result = -1; - if(!log_badargs_if2(conn==NULL, message==NULL && size>0)) { - char *base64encout = NULL; - base64_encode_alloc((const char*)message, size, &base64encout); - if(base64encout) { - result = flib_netbase_sendf(conn->netBase, "EM\n%s\n\n", base64encout); - } - free(base64encout); - } - return result; -} - -int flib_netconn_send_roundfinished(flib_netconn *conn, bool withoutError) { - return sendInt(conn, "ROUNDFINISHED", withoutError ? 1 : 0); -} - +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "netconn_internal.h" + +#include "../util/logging.h" +#include "../util/util.h" +#include "../util/buffer.h" +#include "../md5/md5.h" +#include "../base64/base64.h" + +#include + +#include +#include +#include + +// cmdname is always given as literal from functions in this file, so it is never null. +static int sendVoid(flib_netconn *conn, const char *cmdname) { + if(log_e_if(!conn, "Invalid parameter sending %s command", cmdname)) { + return -1; + } + return flib_netbase_sendf(conn->netBase, "%s\n\n", cmdname); +} + +// Testing for !*str prevents sending 0-length parameters (they trip up the protocol) +static int sendStr(flib_netconn *conn, const char *cmdname, const char *str) { + if(log_e_if(!conn || flib_strempty(str), "Invalid parameter sending %s command", cmdname)) { + return -1; + } + return flib_netbase_sendf(conn->netBase, "%s\n%s\n\n", cmdname, str); +} + +static int sendInt(flib_netconn *conn, const char *cmdname, int param) { + if(log_e_if(!conn, "Invalid parameter sending %s command", cmdname)) { + return -1; + } + return flib_netbase_sendf(conn->netBase, "%s\n%i\n\n", cmdname, param); +} + +int flib_netconn_send_nick(flib_netconn *conn, const char *nick) { + int result = -1; + if(!log_badargs_if2(conn==NULL, flib_strempty(nick))) { + char *tmpName = flib_strdupnull(nick); + if(tmpName) { + if(!flib_netbase_sendf(conn->netBase, "%s\n%s\n\n", "NICK", nick)) { + free(conn->playerName); + conn->playerName = tmpName; + tmpName = NULL; + result = 0; + } + } + free(tmpName); + } + return result; +} + +int flib_netconn_send_password(flib_netconn *conn, const char *passwd) { + int result = -1; + if(!log_badargs_if2(conn==NULL, passwd==NULL)) { + md5_state_t md5state; + uint8_t md5bytes[16]; + char md5hex[33]; + md5_init(&md5state); + md5_append(&md5state, (unsigned char*)passwd, strlen(passwd)); + md5_finish(&md5state, md5bytes); + for(int i=0;inetBase, "%s\n%s\n\n", "PASSWORD", md5hex); + } + return result; +} + +int flib_netconn_send_quit(flib_netconn *conn, const char *quitmsg) { + return sendStr(conn, "QUIT", (quitmsg && *quitmsg) ? quitmsg : "User quit"); +} + +int flib_netconn_send_chat(flib_netconn *conn, const char *chat) { + if(!flib_strempty(chat)) { + return sendStr(conn, "CHAT", chat); + } + return 0; +} + +int flib_netconn_send_kick(flib_netconn *conn, const char *playerName) { + return sendStr(conn, "KICK", playerName); +} + +int flib_netconn_send_playerInfo(flib_netconn *conn, const char *playerName) { + return sendStr(conn, "INFO", playerName); +} + +int flib_netconn_send_request_roomlist(flib_netconn *conn) { + return sendVoid(conn, "LIST"); +} + +int flib_netconn_send_joinRoom(flib_netconn *conn, const char *room) { + if(!sendStr(conn, "JOIN_ROOM", room)) { + conn->isChief = false; + return 0; + } + return -1; +} + +int flib_netconn_send_playerFollow(flib_netconn *conn, const char *playerName) { + return sendStr(conn, "FOLLOW", playerName); +} + +int flib_netconn_send_createRoom(flib_netconn *conn, const char *room) { + if(!sendStr(conn, "CREATE_ROOM", room)) { + conn->isChief = true; + return 0; + } + return -1; +} + +int flib_netconn_send_ban(flib_netconn *conn, const char *playerName) { + return sendStr(conn, "BAN", playerName); +} + +int flib_netconn_send_clearAccountsCache(flib_netconn *conn) { + return sendVoid(conn, "CLEAR_ACCOUNTS_CACHE"); +} + +int flib_netconn_send_setServerVar(flib_netconn *conn, const char *name, const char *value) { + if(log_badargs_if3(conn==NULL, flib_strempty(name), flib_strempty(value))) { + return -1; + } + return flib_netbase_sendf(conn->netBase, "%s\n%s\n%s\n\n", "SET_SERVER_VAR", name, value); +} + +int flib_netconn_send_getServerVars(flib_netconn *conn) { + return sendVoid(conn, "GET_SERVER_VAR"); +} +int flib_netconn_send_leaveRoom(flib_netconn *conn, const char *str) { + int result = -1; + if(conn->netconnState==NETCONN_STATE_ROOM) { + result = (str && *str) ? sendStr(conn, "PART", str) : sendVoid(conn, "PART"); + if(!result) { + netconn_leaveRoom(conn); + } + } + return result; +} + +int flib_netconn_send_toggleReady(flib_netconn *conn) { + return sendVoid(conn, "TOGGLE_READY"); +} + +static void addTeamToPendingList(flib_netconn *conn, const flib_team *team) { + flib_team *teamcopy = flib_team_copy(team); + if(teamcopy) { + teamcopy->remoteDriven = false; + free(teamcopy->ownerName); + teamcopy->ownerName = flib_strdupnull(conn->playerName); + if(teamcopy->ownerName) { + flib_teamlist_delete(&conn->pendingTeamlist, team->name); + if(!flib_teamlist_insert(&conn->pendingTeamlist, teamcopy, 0)) { + teamcopy = NULL; + } + } + } + flib_team_destroy(teamcopy); +} + +int flib_netconn_send_addTeam(flib_netconn *conn, const flib_team *team) { + int result = -1; + if(!log_badargs_if2(conn==NULL, team==NULL)) { + bool missingInfo = flib_strempty(team->name) || flib_strempty(team->grave) || flib_strempty(team->fort) || flib_strempty(team->voicepack) || flib_strempty(team->flag); + for(int i=0; ihogs[i].name) || flib_strempty(team->hogs[i].hat); + } + if(!log_e_if(missingInfo, "Incomplete team definition")) { + flib_vector *vec = flib_vector_create(); + if(vec) { + bool error = false; + error |= flib_vector_appendf(vec, "ADD_TEAM\n%s\n%i\n%s\n%s\n%s\n%s\n%i\n", team->name, team->colorIndex, team->grave, team->fort, team->voicepack, team->flag, team->hogs[0].difficulty); + for(int i=0; ihogs[i].name, team->hogs[i].hat); + } + error |= flib_vector_appendf(vec, "\n"); + if(!error && !flib_netbase_send_raw(conn->netBase, flib_vector_data(vec), flib_vector_size(vec))) { + addTeamToPendingList(conn, team); + result = 0; + } + } + flib_vector_destroy(vec); + } + } + return result; +} + +int flib_netconn_send_removeTeam(flib_netconn *conn, const char *teamname) { + flib_team *team = flib_teamlist_find(&conn->teamlist, teamname); + if(team && !team->remoteDriven && !sendStr(conn, "REMOVE_TEAM", teamname)) { + flib_teamlist_delete(&conn->teamlist, teamname); + return 0; + } + return -1; +} + +int flib_netconn_send_renameRoom(flib_netconn *conn, const char *roomName) { + return sendStr(conn, "ROOM_NAME", roomName); +} + +int flib_netconn_send_teamHogCount(flib_netconn *conn, const char *teamname, int hogcount) { + if(!log_badargs_if5(conn==NULL, flib_strempty(teamname), hogcount<1, hogcount>HEDGEHOGS_PER_TEAM, !conn->isChief) + && !flib_netbase_sendf(conn->netBase, "HH_NUM\n%s\n%i\n\n", teamname, hogcount)) { + flib_team *team = flib_teamlist_find(&conn->teamlist, teamname); + if(team) { + team->hogsInGame = hogcount; + } + return 0; + } + return -1; +} + +int flib_netconn_send_teamColor(flib_netconn *conn, const char *teamname, int colorIndex) { + if(!log_badargs_if3(conn==NULL, flib_strempty(teamname), !conn->isChief) + && !flib_netbase_sendf(conn->netBase, "TEAM_COLOR\n%s\n%i\n\n", teamname, colorIndex)) { + flib_team *team = flib_teamlist_find(&conn->teamlist, teamname); + if(team) { + team->colorIndex = colorIndex; + } + return 0; + } + return -1; +} + +int flib_netconn_send_weaponset(flib_netconn *conn, const flib_weaponset *weaponset) { + if(!log_badargs_if3(conn==NULL, weaponset==NULL, flib_strempty(weaponset->name))) { + char ammostring[WEAPONS_COUNT*4+1]; + strcpy(ammostring, weaponset->loadout); + strcat(ammostring, weaponset->crateprob); + strcat(ammostring, weaponset->delay); + strcat(ammostring, weaponset->crateammo); + if(conn->isChief) { + if(!flib_netbase_sendf(conn->netBase, "CFG\nAMMO\n%s\n%s\n\n", weaponset->name, ammostring)) { + netconn_setWeaponset(conn, weaponset); + return 0; + } + } + } + return -1; +} + +int flib_netconn_send_map(flib_netconn *conn, const flib_map *map) { + if(log_badargs_if2(conn==NULL, map==NULL)) { + return -1; + } + bool error = false; + + if(map->seed) { + error |= flib_netconn_send_mapSeed(conn, map->seed); + } + error |= flib_netconn_send_mapTemplate(conn, map->templateFilter); + if(map->theme) { + error |= flib_netconn_send_mapTheme(conn, map->theme); + } + error |= flib_netconn_send_mapGen(conn, map->mapgen); + error |= flib_netconn_send_mapMazeSize(conn, map->mazeSize); + if(map->drawData && map->drawDataSize>0) { + error |= flib_netconn_send_mapDrawdata(conn, map->drawData, map->drawDataSize); + } + // Name is sent last, because the QtFrontend uses this to update its preview, and to show/hide + // certain fields + if(map->name) { + error |= flib_netconn_send_mapName(conn, map->name); + } + return error; +} + +int flib_netconn_send_mapName(flib_netconn *conn, const char *mapName) { + if(log_badargs_if2(conn==NULL, mapName==NULL)) { + return -1; + } + if(conn->isChief) { + if(!sendStr(conn, "CFG\nMAP", mapName)) { + char *copy = flib_strdupnull(mapName); + if(copy) { + free(conn->map->name); + conn->map->name = copy; + return 0; + } + } + } + return -1; +} + +int flib_netconn_send_mapGen(flib_netconn *conn, int mapGen) { + if(log_badargs_if(conn==NULL)) { + return -1; + } + if(conn->isChief) { + if(!sendInt(conn, "CFG\nMAPGEN", mapGen)) { + conn->map->mapgen = mapGen; + return 0; + } + } + return -1; +} + +int flib_netconn_send_mapTemplate(flib_netconn *conn, int templateFilter) { + if(log_badargs_if(conn==NULL)) { + return -1; + } + if(conn->isChief) { + if(!sendInt(conn, "CFG\nTEMPLATE", templateFilter)) { + conn->map->templateFilter = templateFilter; + return 0; + } + } + return -1; +} + +int flib_netconn_send_mapMazeSize(flib_netconn *conn, int mazeSize) { + if(log_badargs_if(conn==NULL)) { + return -1; + } + if(conn->isChief) { + if(!sendInt(conn, "CFG\nMAZE_SIZE", mazeSize)) { + conn->map->mazeSize = mazeSize; + return 0; + } + } + return -1; +} + +int flib_netconn_send_mapSeed(flib_netconn *conn, const char *seed) { + if(log_badargs_if2(conn==NULL, seed==NULL)) { + return -1; + } + if(conn->isChief) { + if(!sendStr(conn, "CFG\nSEED", seed)) { + char *copy = flib_strdupnull(seed); + if(copy) { + free(conn->map->seed); + conn->map->seed = copy; + return 0; + } + } + } + return -1; +} + +int flib_netconn_send_mapTheme(flib_netconn *conn, const char *theme) { + if(log_badargs_if2(conn==NULL, theme==NULL)) { + return -1; + } + if(conn->isChief) { + if(!sendStr(conn, "CFG\nTHEME", theme)) { + char *copy = flib_strdupnull(theme); + if(copy) { + free(conn->map->theme); + conn->map->theme = copy; + return 0; + } + } + } + return -1; +} + +int flib_netconn_send_mapDrawdata(flib_netconn *conn, const uint8_t *drawData, size_t size) { + int result = -1; + if(!log_badargs_if3(conn==NULL, drawData==NULL && size>0, size>SIZE_MAX/2) && conn->isChief) { + uLongf zippedSize = compressBound(size); + uint8_t *zipped = flib_malloc(zippedSize+4); // 4 extra bytes for header + if(zipped) { + // Create the QCompress size header (uint32 big endian) + zipped[0] = (size>>24) & 0xff; + zipped[1] = (size>>16) & 0xff; + zipped[2] = (size>>8) & 0xff; + zipped[3] = (size) & 0xff; + + if(compress(zipped+4, &zippedSize, drawData, size) != Z_OK) { + flib_log_e("Error compressing drawn map data."); + } else { + char *base64encout = NULL; + base64_encode_alloc((const char*)zipped, zippedSize+4, &base64encout); + if(!base64encout) { + flib_log_e("Error base64-encoding drawn map data."); + } else { + result = flib_netbase_sendf(conn->netBase, "CFG\nDRAWNMAP\n%s\n\n", base64encout); + } + free(base64encout); + } + } + free(zipped); + } + + if(!result) { + uint8_t *copy = flib_bufdupnull(drawData, size); + if(copy) { + free(conn->map->drawData); + conn->map->drawData = copy; + conn->map->drawDataSize = size; + } + } + return result; +} + +int flib_netconn_send_script(flib_netconn *conn, const char *scriptName) { + if(log_badargs_if2(conn==NULL, scriptName==NULL)) { + return -1; + } + if(conn->isChief) { + if(!sendStr(conn, "CFG\nSCRIPT", scriptName)) { + netconn_setScript(conn, scriptName); + return 0; + } + } + return -1; +} + +int flib_netconn_send_scheme(flib_netconn *conn, const flib_scheme *scheme) { + int result = -1; + if(!log_badargs_if3(conn==NULL, scheme==NULL, flib_strempty(scheme->name)) && conn->isChief) { + flib_vector *vec = flib_vector_create(); + if(vec) { + bool error = false; + error |= flib_vector_appendf(vec, "CFG\nSCHEME\n%s\n", scheme->name); + for(int i=0; imods[i] ? "true" : "false"); + } + for(int i=0; isettings[i]); + } + error |= flib_vector_appendf(vec, "\n"); + if(!error) { + result = flib_netbase_send_raw(conn->netBase, flib_vector_data(vec), flib_vector_size(vec)); + } + } + flib_vector_destroy(vec); + } + + if(!result) { + netconn_setScheme(conn, scheme); + } + return result; +} + +int flib_netconn_send_startGame(flib_netconn *conn) { + return sendVoid(conn, "START_GAME"); +} + +int flib_netconn_send_toggleRestrictJoins(flib_netconn *conn) { + return sendVoid(conn, "TOGGLE_RESTRICT_JOINS"); +} + +int flib_netconn_send_toggleRestrictTeams(flib_netconn *conn) { + return sendVoid(conn, "TOGGLE_RESTRICT_TEAMS"); +} + +int flib_netconn_send_teamchat(flib_netconn *conn, const char *chat) { + if(!flib_strempty(chat)) { + return sendStr(conn, "TEAMCHAT", chat); + } + return 0; +} + +int flib_netconn_send_engineMessage(flib_netconn *conn, const uint8_t *message, size_t size) { + int result = -1; + if(!log_badargs_if2(conn==NULL, message==NULL && size>0)) { + char *base64encout = NULL; + base64_encode_alloc((const char*)message, size, &base64encout); + if(base64encout) { + result = flib_netbase_sendf(conn->netBase, "EM\n%s\n\n", base64encout); + } + free(base64encout); + } + return result; +} + +int flib_netconn_send_roundfinished(flib_netconn *conn, bool withoutError) { + return sendInt(conn, "ROUNDFINISHED", withoutError ? 1 : 0); +} + diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/net/netprotocol.c --- a/project_files/frontlib/net/netprotocol.c Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/net/netprotocol.c Tue Jan 21 22:43:06 2014 +0100 @@ -1,192 +1,192 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "netprotocol.h" - -#include "../util/util.h" -#include "../util/logging.h" - -#include "../base64/base64.h" - -#include - -#include -#include -#include -#include - -static int fillTeamFromMsg(flib_team *team, char **parts) { - team->name = flib_strdupnull(parts[0]); - team->grave = flib_strdupnull(parts[1]); - team->fort = flib_strdupnull(parts[2]); - team->voicepack = flib_strdupnull(parts[3]); - team->flag = flib_strdupnull(parts[4]); - team->ownerName = flib_strdupnull(parts[5]); - if(!team->name || !team->grave || !team->fort || !team->voicepack || !team->flag || !team->ownerName) { - return -1; - } - - errno = 0; - long difficulty = strtol(parts[6], NULL, 10); - if(errno) { - return -1; - } - - for(int i=0; ihogs[i]; - hog->difficulty = difficulty; - hog->name = flib_strdupnull(parts[7+2*i]); - hog->hat = flib_strdupnull(parts[8+2*i]); - if(!hog->name || !hog->hat) { - return -1; - } - } - - // Set some default assumptions as well - team->colorIndex = DEFAULT_COLOR_INDEX; - team->hogsInGame = DEFAULT_HEDGEHOG_COUNT; - team->remoteDriven = true; - return 0; -} - -flib_team *flib_team_from_netmsg(char **parts) { - flib_team *result = NULL; - flib_team *tmpTeam = flib_calloc(1, sizeof(flib_team)); - if(tmpTeam) { - if(!fillTeamFromMsg(tmpTeam, parts)) { - result = tmpTeam; - tmpTeam = NULL; - } else { - flib_log_e("Error parsing team from net."); - } - } - flib_team_destroy(tmpTeam); - return result; -} - -flib_scheme *flib_scheme_from_netmsg(char **parts) { - flib_scheme *result = flib_scheme_create(parts[0]); - if(result) { - for(int i=0; imods[i] = !strcmp(parts[i+1], "true"); - } - for(int i=0; isettings[i] = atoi(parts[i+flib_meta.modCount+1]); - } - } - return result; -} - -flib_map *flib_map_from_netmsg(char **parts) { - flib_map *result = flib_map_create_named(parts[3], parts[0]); - if(result) { - result->mapgen = atoi(parts[1]); - result->mazeSize = atoi(parts[2]); - result->templateFilter = atoi(parts[4]); - } - return result; -} - -int flib_drawnmapdata_from_netmsg(char *netmsg, uint8_t** outbuf, size_t *outlen) { - int result = -1; - - // First step: base64 decoding - char *base64decout = NULL; - size_t base64declen; - bool ok = base64_decode_alloc(netmsg, strlen(netmsg), &base64decout, &base64declen); - if(ok && base64declen>3) { - // Second step: unzip with the QCompress header. That header is just a big-endian - // uint32 indicating the length of the uncompressed data. - uint8_t *ubyteBuf = (uint8_t*)base64decout; - uint32_t unzipLen = - (((uint32_t)ubyteBuf[0])<<24) - + (((uint32_t)ubyteBuf[1])<<16) - + (((uint32_t)ubyteBuf[2])<<8) - + ubyteBuf[3]; - if(unzipLen==0) { - *outbuf = NULL; - *outlen = 0; - result = 0; - } else { - uint8_t *out = flib_malloc(unzipLen); - if(out) { - uLongf actualUnzipLen = unzipLen; - int resultcode = uncompress(out, &actualUnzipLen, (Bytef*)(base64decout+4), base64declen-4); - if(resultcode == Z_OK) { - *outbuf = out; - *outlen = actualUnzipLen; - out = NULL; - result = 0; - } else { - flib_log_e("Uncompressing drawn map failed. Code: %i", resultcode); - } - } - free(out); - } - } else { - flib_log_e("base64 decoding of drawn map failed."); - } - free(base64decout); - return result; -} - -flib_room *flib_room_from_netmsg(char **params) { - flib_room *result = NULL; - flib_room *tmpRoom = flib_calloc(1, sizeof(flib_room)); - if(tmpRoom) { - tmpRoom->inProgress = !strcmp(params[0], "True"); - tmpRoom->name = flib_strdupnull(params[1]); - tmpRoom->playerCount = atoi(params[2]); - tmpRoom->teamCount = atoi(params[3]); - tmpRoom->owner = flib_strdupnull(params[4]); - tmpRoom->map = flib_strdupnull(params[5]); - tmpRoom->scheme = flib_strdupnull(params[6]); - tmpRoom->weapons = flib_strdupnull(params[7]); - if(tmpRoom->name && tmpRoom->owner && tmpRoom->map && tmpRoom->scheme && tmpRoom->weapons) { - result = tmpRoom; - tmpRoom = NULL; - } - } - flib_room_destroy(tmpRoom); - return result; -} - -int fillRoomArray(flib_room **array, char **params, int count) { - for(int i=0; i + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "netprotocol.h" + +#include "../util/util.h" +#include "../util/logging.h" + +#include "../base64/base64.h" + +#include + +#include +#include +#include +#include + +static int fillTeamFromMsg(flib_team *team, char **parts) { + team->name = flib_strdupnull(parts[0]); + team->grave = flib_strdupnull(parts[1]); + team->fort = flib_strdupnull(parts[2]); + team->voicepack = flib_strdupnull(parts[3]); + team->flag = flib_strdupnull(parts[4]); + team->ownerName = flib_strdupnull(parts[5]); + if(!team->name || !team->grave || !team->fort || !team->voicepack || !team->flag || !team->ownerName) { + return -1; + } + + errno = 0; + long difficulty = strtol(parts[6], NULL, 10); + if(errno) { + return -1; + } + + for(int i=0; ihogs[i]; + hog->difficulty = difficulty; + hog->name = flib_strdupnull(parts[7+2*i]); + hog->hat = flib_strdupnull(parts[8+2*i]); + if(!hog->name || !hog->hat) { + return -1; + } + } + + // Set some default assumptions as well + team->colorIndex = DEFAULT_COLOR_INDEX; + team->hogsInGame = DEFAULT_HEDGEHOG_COUNT; + team->remoteDriven = true; + return 0; +} + +flib_team *flib_team_from_netmsg(char **parts) { + flib_team *result = NULL; + flib_team *tmpTeam = flib_calloc(1, sizeof(flib_team)); + if(tmpTeam) { + if(!fillTeamFromMsg(tmpTeam, parts)) { + result = tmpTeam; + tmpTeam = NULL; + } else { + flib_log_e("Error parsing team from net."); + } + } + flib_team_destroy(tmpTeam); + return result; +} + +flib_scheme *flib_scheme_from_netmsg(char **parts) { + flib_scheme *result = flib_scheme_create(parts[0]); + if(result) { + for(int i=0; imods[i] = !strcmp(parts[i+1], "true"); + } + for(int i=0; isettings[i] = atoi(parts[i+flib_meta.modCount+1]); + } + } + return result; +} + +flib_map *flib_map_from_netmsg(char **parts) { + flib_map *result = flib_map_create_named(parts[3], parts[0]); + if(result) { + result->mapgen = atoi(parts[1]); + result->mazeSize = atoi(parts[2]); + result->templateFilter = atoi(parts[4]); + } + return result; +} + +int flib_drawnmapdata_from_netmsg(char *netmsg, uint8_t** outbuf, size_t *outlen) { + int result = -1; + + // First step: base64 decoding + char *base64decout = NULL; + size_t base64declen; + bool ok = base64_decode_alloc(netmsg, strlen(netmsg), &base64decout, &base64declen); + if(ok && base64declen>3) { + // Second step: unzip with the QCompress header. That header is just a big-endian + // uint32 indicating the length of the uncompressed data. + uint8_t *ubyteBuf = (uint8_t*)base64decout; + uint32_t unzipLen = + (((uint32_t)ubyteBuf[0])<<24) + + (((uint32_t)ubyteBuf[1])<<16) + + (((uint32_t)ubyteBuf[2])<<8) + + ubyteBuf[3]; + if(unzipLen==0) { + *outbuf = NULL; + *outlen = 0; + result = 0; + } else { + uint8_t *out = flib_malloc(unzipLen); + if(out) { + uLongf actualUnzipLen = unzipLen; + int resultcode = uncompress(out, &actualUnzipLen, (Bytef*)(base64decout+4), base64declen-4); + if(resultcode == Z_OK) { + *outbuf = out; + *outlen = actualUnzipLen; + out = NULL; + result = 0; + } else { + flib_log_e("Uncompressing drawn map failed. Code: %i", resultcode); + } + } + free(out); + } + } else { + flib_log_e("base64 decoding of drawn map failed."); + } + free(base64decout); + return result; +} + +flib_room *flib_room_from_netmsg(char **params) { + flib_room *result = NULL; + flib_room *tmpRoom = flib_calloc(1, sizeof(flib_room)); + if(tmpRoom) { + tmpRoom->inProgress = !strcmp(params[0], "True"); + tmpRoom->name = flib_strdupnull(params[1]); + tmpRoom->playerCount = atoi(params[2]); + tmpRoom->teamCount = atoi(params[3]); + tmpRoom->owner = flib_strdupnull(params[4]); + tmpRoom->map = flib_strdupnull(params[5]); + tmpRoom->scheme = flib_strdupnull(params[6]); + tmpRoom->weapons = flib_strdupnull(params[7]); + if(tmpRoom->name && tmpRoom->owner && tmpRoom->map && tmpRoom->scheme && tmpRoom->weapons) { + result = tmpRoom; + tmpRoom = NULL; + } + } + flib_room_destroy(tmpRoom); + return result; +} + +int fillRoomArray(flib_room **array, char **params, int count) { + for(int i=0; i - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef NETPROTOCOL_H_ -#define NETPROTOCOL_H_ - -#include "../model/team.h" -#include "../model/scheme.h" -#include "../model/map.h" -#include "../model/room.h" - -#include - -/** - * Create a new team from this 23-part net message - */ -flib_team *flib_team_from_netmsg(char **parts); - -/** - * Create a new scheme from this net message, which must have - * meta->modCount+meta->settingCount+1 parts. - */ -flib_scheme *flib_scheme_from_netmsg(char **parts); - -/** - * Create a new map from this five-part netmsg - */ -flib_map *flib_map_from_netmsg(char **parts); - -/** - * Decode the drawn map data from this netmessage line. - * - * The data is first base64 decoded and then quncompress()ed. - * The return value is a newly allocated byte buffer, the length - * is written to the variable pointed to by outlen. - * Returns NULL on error. - */ -int flib_drawnmapdata_from_netmsg(char *netmsg, uint8_t **outbuf, size_t *outlen); - -/** - * Create a new room from this 8-part net message - */ -flib_room *flib_room_from_netmsg(char **params); - -/** - * Create an array of count rooms from count*8 netmessage parts - */ -flib_room **flib_room_array_from_netmsg(char **params, int count); - -#endif /* NETPROTOCOL_H_ */ +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef NETPROTOCOL_H_ +#define NETPROTOCOL_H_ + +#include "../model/team.h" +#include "../model/scheme.h" +#include "../model/map.h" +#include "../model/room.h" + +#include + +/** + * Create a new team from this 23-part net message + */ +flib_team *flib_team_from_netmsg(char **parts); + +/** + * Create a new scheme from this net message, which must have + * meta->modCount+meta->settingCount+1 parts. + */ +flib_scheme *flib_scheme_from_netmsg(char **parts); + +/** + * Create a new map from this five-part netmsg + */ +flib_map *flib_map_from_netmsg(char **parts); + +/** + * Decode the drawn map data from this netmessage line. + * + * The data is first base64 decoded and then quncompress()ed. + * The return value is a newly allocated byte buffer, the length + * is written to the variable pointed to by outlen. + * Returns NULL on error. + */ +int flib_drawnmapdata_from_netmsg(char *netmsg, uint8_t **outbuf, size_t *outlen); + +/** + * Create a new room from this 8-part net message + */ +flib_room *flib_room_from_netmsg(char **params); + +/** + * Create an array of count rooms from count*8 netmessage parts + */ +flib_room **flib_room_array_from_netmsg(char **params, int count); + +#endif /* NETPROTOCOL_H_ */ diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/socket.c --- a/project_files/frontlib/socket.c Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/socket.c Tue Jan 21 22:43:06 2014 +0100 @@ -1,191 +1,191 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "socket.h" -#include "util/logging.h" -#include "util/util.h" -#include -#include -#include - -struct _flib_tcpsocket { - TCPsocket sock; - SDLNet_SocketSet sockset; -}; - -struct _flib_acceptor { - TCPsocket sock; - uint16_t port; -}; - -static uint32_t getPeerIp(TCPsocket sock) { - IPaddress *addr = SDLNet_TCP_GetPeerAddress(sock); - return SDLNet_Read32(&addr->host); -} - -static bool connectionIsLocal(TCPsocket sock) { - return getPeerIp(sock) == (uint32_t)((127UL<<24)+1); // 127.0.0.1 -} - -static flib_tcpsocket *createSocket(TCPsocket sdlsock) { - flib_tcpsocket *result = flib_calloc(1, sizeof(flib_tcpsocket)); - if(result) { - result->sock = sdlsock; - result->sockset = SDLNet_AllocSocketSet(1); - - if(!result->sockset) { - flib_log_e("Can't allocate socket: Out of memory!"); - SDLNet_FreeSocketSet(result->sockset); - free(result); - result = NULL; - } else { - SDLNet_AddSocket(result->sockset, (SDLNet_GenericSocket)result->sock); - } - } - return result; -} - -TCPsocket listen(uint16_t port) { - IPaddress addr; - addr.host = INADDR_ANY; - SDLNet_Write16(port, &addr.port); - TCPsocket sock = SDLNet_TCP_Open(&addr); - if(!sock) { - flib_log_w("Unable to listen on port %u: %s", (unsigned)port, SDLNet_GetError()); - } - return sock; -} - -flib_acceptor *flib_acceptor_create(uint16_t port) { - flib_acceptor *result = flib_calloc(1, sizeof(flib_acceptor)); - if(result) { - if(port > 0) { - result->port = port; - result->sock = listen(result->port); - } else { - /* SDL_net does not seem to have a way to listen on a random unused port - and find out which port that is, so let's try to find one ourselves. */ - srand(time(NULL)); - for(int i=0; !result->sock && i<1000; i++) { - // IANA suggests using ports in the range 49152-65535 for things like this - result->port = 49152+(rand()%(65536-49152)); - result->sock = listen(result->port); - } - } - if(!result->sock) { - flib_log_e("Failed to create acceptor."); - free(result); - result = NULL; - } - } - return result; -} - -uint16_t flib_acceptor_listenport(flib_acceptor *acceptor) { - if(!acceptor) { - flib_log_e("Call to flib_acceptor_listenport with acceptor==null"); - return 0; - } - return acceptor->port; -} - -void flib_acceptor_close(flib_acceptor *acceptor) { - if(acceptor) { - SDLNet_TCP_Close(acceptor->sock); - free(acceptor); - } -} - -flib_tcpsocket *flib_socket_accept(flib_acceptor *acceptor, bool localOnly) { - flib_tcpsocket *result = NULL; - if(!acceptor) { - flib_log_e("Call to flib_socket_accept with acceptor==null"); - } else { - TCPsocket sock = NULL; - while(!result && (sock = SDLNet_TCP_Accept(acceptor->sock))) { - if(localOnly && !connectionIsLocal(sock)) { - flib_log_i("Rejected nonlocal connection attempt from %s", flib_format_ip(getPeerIp(sock))); - } else { - result = createSocket(sock); - } - if(!result) { - SDLNet_TCP_Close(sock); - } - } - } - return result; -} - -flib_tcpsocket *flib_socket_connect(const char *host, uint16_t port) { - flib_tcpsocket *result = NULL; - if(!host || port==0) { - flib_log_e("Invalid parameter in flib_socket_connect"); - } else { - IPaddress ip; - if(SDLNet_ResolveHost(&ip,host,port)==-1) { - flib_log_e("SDLNet_ResolveHost: %s\n", SDLNet_GetError()); - } else { - TCPsocket sock=SDLNet_TCP_Open(&ip); - if(!sock) { - flib_log_e("SDLNet_TCP_Open: %s\n", SDLNet_GetError()); - } else { - result = createSocket(sock); - if(result) { - sock = NULL; - } - } - SDLNet_TCP_Close(sock); - } - } - return result; -} - -void flib_socket_close(flib_tcpsocket *sock) { - if(sock) { - SDLNet_DelSocket(sock->sockset, (SDLNet_GenericSocket)sock->sock); - SDLNet_TCP_Close(sock->sock); - SDLNet_FreeSocketSet(sock->sockset); - free(sock); - } -} - -int flib_socket_nbrecv(flib_tcpsocket *sock, void *data, int maxlen) { - if(!sock || (maxlen>0 && !data)) { - flib_log_e("Call to flib_socket_nbrecv with sock==null or data==null"); - return -1; - } - int readySockets = SDLNet_CheckSockets(sock->sockset, 0); - if(readySockets>0) { - int size = SDLNet_TCP_Recv(sock->sock, data, maxlen); - return size>0 ? size : -1; - } else if(readySockets==0) { - return 0; - } else { - flib_log_e("Error in select system call: %s", SDLNet_GetError()); - return -1; - } -} - -int flib_socket_send(flib_tcpsocket *sock, const void *data, int len) { - if(!sock || (len>0 && !data)) { - flib_log_e("Call to flib_socket_send with sock==null or data==null"); - return -1; - } - return SDLNet_TCP_Send(sock->sock, data, len); -} +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "socket.h" +#include "util/logging.h" +#include "util/util.h" +#include +#include +#include + +struct _flib_tcpsocket { + TCPsocket sock; + SDLNet_SocketSet sockset; +}; + +struct _flib_acceptor { + TCPsocket sock; + uint16_t port; +}; + +static uint32_t getPeerIp(TCPsocket sock) { + IPaddress *addr = SDLNet_TCP_GetPeerAddress(sock); + return SDLNet_Read32(&addr->host); +} + +static bool connectionIsLocal(TCPsocket sock) { + return getPeerIp(sock) == (uint32_t)((127UL<<24)+1); // 127.0.0.1 +} + +static flib_tcpsocket *createSocket(TCPsocket sdlsock) { + flib_tcpsocket *result = flib_calloc(1, sizeof(flib_tcpsocket)); + if(result) { + result->sock = sdlsock; + result->sockset = SDLNet_AllocSocketSet(1); + + if(!result->sockset) { + flib_log_e("Can't allocate socket: Out of memory!"); + SDLNet_FreeSocketSet(result->sockset); + free(result); + result = NULL; + } else { + SDLNet_AddSocket(result->sockset, (SDLNet_GenericSocket)result->sock); + } + } + return result; +} + +TCPsocket listen(uint16_t port) { + IPaddress addr; + addr.host = INADDR_ANY; + SDLNet_Write16(port, &addr.port); + TCPsocket sock = SDLNet_TCP_Open(&addr); + if(!sock) { + flib_log_w("Unable to listen on port %u: %s", (unsigned)port, SDLNet_GetError()); + } + return sock; +} + +flib_acceptor *flib_acceptor_create(uint16_t port) { + flib_acceptor *result = flib_calloc(1, sizeof(flib_acceptor)); + if(result) { + if(port > 0) { + result->port = port; + result->sock = listen(result->port); + } else { + /* SDL_net does not seem to have a way to listen on a random unused port + and find out which port that is, so let's try to find one ourselves. */ + srand(time(NULL)); + for(int i=0; !result->sock && i<1000; i++) { + // IANA suggests using ports in the range 49152-65535 for things like this + result->port = 49152+(rand()%(65536-49152)); + result->sock = listen(result->port); + } + } + if(!result->sock) { + flib_log_e("Failed to create acceptor."); + free(result); + result = NULL; + } + } + return result; +} + +uint16_t flib_acceptor_listenport(flib_acceptor *acceptor) { + if(!acceptor) { + flib_log_e("Call to flib_acceptor_listenport with acceptor==null"); + return 0; + } + return acceptor->port; +} + +void flib_acceptor_close(flib_acceptor *acceptor) { + if(acceptor) { + SDLNet_TCP_Close(acceptor->sock); + free(acceptor); + } +} + +flib_tcpsocket *flib_socket_accept(flib_acceptor *acceptor, bool localOnly) { + flib_tcpsocket *result = NULL; + if(!acceptor) { + flib_log_e("Call to flib_socket_accept with acceptor==null"); + } else { + TCPsocket sock = NULL; + while(!result && (sock = SDLNet_TCP_Accept(acceptor->sock))) { + if(localOnly && !connectionIsLocal(sock)) { + flib_log_i("Rejected nonlocal connection attempt from %s", flib_format_ip(getPeerIp(sock))); + } else { + result = createSocket(sock); + } + if(!result) { + SDLNet_TCP_Close(sock); + } + } + } + return result; +} + +flib_tcpsocket *flib_socket_connect(const char *host, uint16_t port) { + flib_tcpsocket *result = NULL; + if(!host || port==0) { + flib_log_e("Invalid parameter in flib_socket_connect"); + } else { + IPaddress ip; + if(SDLNet_ResolveHost(&ip,host,port)==-1) { + flib_log_e("SDLNet_ResolveHost: %s\n", SDLNet_GetError()); + } else { + TCPsocket sock=SDLNet_TCP_Open(&ip); + if(!sock) { + flib_log_e("SDLNet_TCP_Open: %s\n", SDLNet_GetError()); + } else { + result = createSocket(sock); + if(result) { + sock = NULL; + } + } + SDLNet_TCP_Close(sock); + } + } + return result; +} + +void flib_socket_close(flib_tcpsocket *sock) { + if(sock) { + SDLNet_DelSocket(sock->sockset, (SDLNet_GenericSocket)sock->sock); + SDLNet_TCP_Close(sock->sock); + SDLNet_FreeSocketSet(sock->sockset); + free(sock); + } +} + +int flib_socket_nbrecv(flib_tcpsocket *sock, void *data, int maxlen) { + if(!sock || (maxlen>0 && !data)) { + flib_log_e("Call to flib_socket_nbrecv with sock==null or data==null"); + return -1; + } + int readySockets = SDLNet_CheckSockets(sock->sockset, 0); + if(readySockets>0) { + int size = SDLNet_TCP_Recv(sock->sock, data, maxlen); + return size>0 ? size : -1; + } else if(readySockets==0) { + return 0; + } else { + flib_log_e("Error in select system call: %s", SDLNet_GetError()); + return -1; + } +} + +int flib_socket_send(flib_tcpsocket *sock, const void *data, int len) { + if(!sock || (len>0 && !data)) { + flib_log_e("Call to flib_socket_send with sock==null or data==null"); + return -1; + } + return SDLNet_TCP_Send(sock->sock, data, len); +} diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/socket.h --- a/project_files/frontlib/socket.h Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/socket.h Tue Jan 21 22:43:06 2014 +0100 @@ -1,91 +1,91 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/* - * Sockets for TCP networking. - * - * This layer offers some functionality over what SDL_net offers directly: listening - * sockets (called acceptors here) can be bound to port 0, which will make them listen - * on a random unused port, if one can be found. To support this feature, you can also - * query the local port that an acceptor is listening on. - * - * Further, we support nonblocking reads here. - */ - -#ifndef SOCKET_H_ -#define SOCKET_H_ - -#include -#include - -typedef struct _flib_tcpsocket flib_tcpsocket; -typedef struct _flib_acceptor flib_acceptor; - -/** - * Create a new acceptor which will listen for incoming TCP connections - * on the given port. If port is 0, this will listen on a random - * unused port which can then be queried with flib_acceptor_listenport. - * - * Returns NULL on error. - */ -flib_acceptor *flib_acceptor_create(uint16_t port); - -/** - * Return the port on which the acceptor is listening. - */ -uint16_t flib_acceptor_listenport(flib_acceptor *acceptor); - -/** - * Close the acceptor and free its memory. NULL-safe. - */ -void flib_acceptor_close(flib_acceptor *acceptor); - -/** - * Try to accept a connection from an acceptor (listening socket). - * if localOnly is true, this will only accept connections which came from 127.0.0.1 - * Returns NULL if nothing can be accepted. - */ -flib_tcpsocket *flib_socket_accept(flib_acceptor *acceptor, bool localOnly); - -/** - * Try to connect to the server at the given address. - */ -flib_tcpsocket *flib_socket_connect(const char *host, uint16_t port); - -/** - * Close the socket and free its memory. NULL-safe. - */ -void flib_socket_close(flib_tcpsocket *socket); - -/** - * Attempt to receive up to maxlen bytes from the socket, but does not - * block if nothing is available. - * Returns the ammount of data received, 0 if there was nothing to receive, - * or a negative number if the connection was closed or an error occurred. - */ -int flib_socket_nbrecv(flib_tcpsocket *sock, void *data, int maxlen); - -/** - * Blocking send all the data in the data buffer. Returns the actual ammount - * of data sent, or a negative value on error. If the value returned here - * is less than len, either the connection closed or an error occurred. - */ -int flib_socket_send(flib_tcpsocket *sock, const void *data, int len); - -#endif /* SOCKET_H_ */ +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * Sockets for TCP networking. + * + * This layer offers some functionality over what SDL_net offers directly: listening + * sockets (called acceptors here) can be bound to port 0, which will make them listen + * on a random unused port, if one can be found. To support this feature, you can also + * query the local port that an acceptor is listening on. + * + * Further, we support nonblocking reads here. + */ + +#ifndef SOCKET_H_ +#define SOCKET_H_ + +#include +#include + +typedef struct _flib_tcpsocket flib_tcpsocket; +typedef struct _flib_acceptor flib_acceptor; + +/** + * Create a new acceptor which will listen for incoming TCP connections + * on the given port. If port is 0, this will listen on a random + * unused port which can then be queried with flib_acceptor_listenport. + * + * Returns NULL on error. + */ +flib_acceptor *flib_acceptor_create(uint16_t port); + +/** + * Return the port on which the acceptor is listening. + */ +uint16_t flib_acceptor_listenport(flib_acceptor *acceptor); + +/** + * Close the acceptor and free its memory. NULL-safe. + */ +void flib_acceptor_close(flib_acceptor *acceptor); + +/** + * Try to accept a connection from an acceptor (listening socket). + * if localOnly is true, this will only accept connections which came from 127.0.0.1 + * Returns NULL if nothing can be accepted. + */ +flib_tcpsocket *flib_socket_accept(flib_acceptor *acceptor, bool localOnly); + +/** + * Try to connect to the server at the given address. + */ +flib_tcpsocket *flib_socket_connect(const char *host, uint16_t port); + +/** + * Close the socket and free its memory. NULL-safe. + */ +void flib_socket_close(flib_tcpsocket *socket); + +/** + * Attempt to receive up to maxlen bytes from the socket, but does not + * block if nothing is available. + * Returns the ammount of data received, 0 if there was nothing to receive, + * or a negative number if the connection was closed or an error occurred. + */ +int flib_socket_nbrecv(flib_tcpsocket *sock, void *data, int maxlen); + +/** + * Blocking send all the data in the data buffer. Returns the actual ammount + * of data sent, or a negative value on error. If the value returned here + * is less than len, either the connection closed or an error occurred. + */ +int flib_socket_send(flib_tcpsocket *sock, const void *data, int len); + +#endif /* SOCKET_H_ */ diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/util/buffer.c --- a/project_files/frontlib/util/buffer.c Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/util/buffer.c Tue Jan 21 22:43:06 2014 +0100 @@ -1,177 +1,177 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "buffer.h" -#include "logging.h" -#include "util.h" - -#include -#include -#include - -#define MIN_VECTOR_CAPACITY 16 - -struct _flib_vector { - void *data; - size_t size; - size_t capacity; -}; - -flib_vector *flib_vector_create() { - flib_vector *result = NULL; - flib_vector *tmpVector = flib_calloc(1, sizeof(flib_vector)); - if(tmpVector) { - tmpVector->data = flib_malloc(MIN_VECTOR_CAPACITY); - if(tmpVector->data) { - tmpVector->size = 0; - tmpVector->capacity = MIN_VECTOR_CAPACITY; - result = tmpVector; - tmpVector = NULL; - } - } - flib_vector_destroy(tmpVector); - return result; -} - -void flib_vector_destroy(flib_vector *vec) { - if(vec) { - free(vec->data); - free(vec); - } -} - -static int setCapacity(flib_vector *vec, size_t newCapacity) { - if(newCapacity == vec->capacity) { - return 0; - } - void *newData = realloc(vec->data, newCapacity); - if(newData) { - vec->data = newData; - vec->capacity = newCapacity; - return 0; - } else { - return -1; - } -} - -static int allocateExtraCapacity(flib_vector *vec, size_t extraCapacity) { - if(extraCapacity <= SIZE_MAX - vec->capacity) { - return setCapacity(vec, vec->capacity + extraCapacity); - } else { - return -1; - } -} - -int flib_vector_resize(flib_vector *vec, size_t newSize) { - if(log_badargs_if(vec==NULL)) { - return -1; - } - - if(vec->capacity < newSize) { - // Resize exponentially for constant amortized time, - // But at least by as much as we need of course - size_t extraCapacity = (vec->capacity)/2; - size_t minExtraCapacity = newSize - vec->capacity; - if(extraCapacity < minExtraCapacity) { - extraCapacity = minExtraCapacity; - } - - if(allocateExtraCapacity(vec, extraCapacity)) { - allocateExtraCapacity(vec, minExtraCapacity); - } - } else if(vec->capacity/2 > newSize) { - size_t newCapacity = newSize+newSize/4; - if(newCapacity < MIN_VECTOR_CAPACITY) { - newCapacity = MIN_VECTOR_CAPACITY; - } - setCapacity(vec, newCapacity); - } - - if(vec->capacity >= newSize) { - vec->size = newSize; - return 0; - } else { - return -1; - } -} - -int flib_vector_append(flib_vector *vec, const void *data, size_t len) { - if(!log_badargs_if2(vec==NULL, data==NULL && len>0) - && !log_oom_if(len > SIZE_MAX-vec->size)) { - size_t oldSize = vec->size; - if(!log_oom_if(flib_vector_resize(vec, vec->size+len))) { - memmove(((uint8_t*)vec->data) + oldSize, data, len); - return 0; - } - } - return -1; -} - -int flib_vector_appendf(flib_vector *vec, const char *fmt, ...) { - int result = -1; - if(!log_badargs_if2(vec==NULL, fmt==NULL)) { - va_list argp; - va_start(argp, fmt); - char *formatted = flib_vasprintf(fmt, argp); - va_end(argp); - - - if(formatted) { - size_t len = strlen(formatted); - result = flib_vector_append(vec, formatted, len); - } - } - return result; -} - -flib_buffer flib_vector_as_buffer(flib_vector *vec) { - if(log_badargs_if(vec==NULL)) { - flib_buffer result = {NULL, 0}; - return result; - } else { - flib_buffer result = {vec->data, vec->size}; - return result; - } -} - -flib_constbuffer flib_vector_as_constbuffer(flib_vector *vec) { - if(log_badargs_if(vec==NULL)) { - flib_constbuffer result = {NULL, 0}; - return result; - } else { - flib_constbuffer result = {vec->data, vec->size}; - return result; - } -} - -void *flib_vector_data(flib_vector *vec) { - if(log_badargs_if(vec==NULL)) { - return NULL; - } else { - return vec->data; - } -} - -size_t flib_vector_size(flib_vector *vec) { - if(log_badargs_if(vec==NULL)) { - return 0; - } else { - return vec->size; - } -} +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "buffer.h" +#include "logging.h" +#include "util.h" + +#include +#include +#include + +#define MIN_VECTOR_CAPACITY 16 + +struct _flib_vector { + void *data; + size_t size; + size_t capacity; +}; + +flib_vector *flib_vector_create() { + flib_vector *result = NULL; + flib_vector *tmpVector = flib_calloc(1, sizeof(flib_vector)); + if(tmpVector) { + tmpVector->data = flib_malloc(MIN_VECTOR_CAPACITY); + if(tmpVector->data) { + tmpVector->size = 0; + tmpVector->capacity = MIN_VECTOR_CAPACITY; + result = tmpVector; + tmpVector = NULL; + } + } + flib_vector_destroy(tmpVector); + return result; +} + +void flib_vector_destroy(flib_vector *vec) { + if(vec) { + free(vec->data); + free(vec); + } +} + +static int setCapacity(flib_vector *vec, size_t newCapacity) { + if(newCapacity == vec->capacity) { + return 0; + } + void *newData = realloc(vec->data, newCapacity); + if(newData) { + vec->data = newData; + vec->capacity = newCapacity; + return 0; + } else { + return -1; + } +} + +static int allocateExtraCapacity(flib_vector *vec, size_t extraCapacity) { + if(extraCapacity <= SIZE_MAX - vec->capacity) { + return setCapacity(vec, vec->capacity + extraCapacity); + } else { + return -1; + } +} + +int flib_vector_resize(flib_vector *vec, size_t newSize) { + if(log_badargs_if(vec==NULL)) { + return -1; + } + + if(vec->capacity < newSize) { + // Resize exponentially for constant amortized time, + // But at least by as much as we need of course + size_t extraCapacity = (vec->capacity)/2; + size_t minExtraCapacity = newSize - vec->capacity; + if(extraCapacity < minExtraCapacity) { + extraCapacity = minExtraCapacity; + } + + if(allocateExtraCapacity(vec, extraCapacity)) { + allocateExtraCapacity(vec, minExtraCapacity); + } + } else if(vec->capacity/2 > newSize) { + size_t newCapacity = newSize+newSize/4; + if(newCapacity < MIN_VECTOR_CAPACITY) { + newCapacity = MIN_VECTOR_CAPACITY; + } + setCapacity(vec, newCapacity); + } + + if(vec->capacity >= newSize) { + vec->size = newSize; + return 0; + } else { + return -1; + } +} + +int flib_vector_append(flib_vector *vec, const void *data, size_t len) { + if(!log_badargs_if2(vec==NULL, data==NULL && len>0) + && !log_oom_if(len > SIZE_MAX-vec->size)) { + size_t oldSize = vec->size; + if(!log_oom_if(flib_vector_resize(vec, vec->size+len))) { + memmove(((uint8_t*)vec->data) + oldSize, data, len); + return 0; + } + } + return -1; +} + +int flib_vector_appendf(flib_vector *vec, const char *fmt, ...) { + int result = -1; + if(!log_badargs_if2(vec==NULL, fmt==NULL)) { + va_list argp; + va_start(argp, fmt); + char *formatted = flib_vasprintf(fmt, argp); + va_end(argp); + + + if(formatted) { + size_t len = strlen(formatted); + result = flib_vector_append(vec, formatted, len); + } + } + return result; +} + +flib_buffer flib_vector_as_buffer(flib_vector *vec) { + if(log_badargs_if(vec==NULL)) { + flib_buffer result = {NULL, 0}; + return result; + } else { + flib_buffer result = {vec->data, vec->size}; + return result; + } +} + +flib_constbuffer flib_vector_as_constbuffer(flib_vector *vec) { + if(log_badargs_if(vec==NULL)) { + flib_constbuffer result = {NULL, 0}; + return result; + } else { + flib_constbuffer result = {vec->data, vec->size}; + return result; + } +} + +void *flib_vector_data(flib_vector *vec) { + if(log_badargs_if(vec==NULL)) { + return NULL; + } else { + return vec->data; + } +} + +size_t flib_vector_size(flib_vector *vec) { + if(log_badargs_if(vec==NULL)) { + return 0; + } else { + return vec->size; + } +} diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/util/buffer.h --- a/project_files/frontlib/util/buffer.h Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/util/buffer.h Tue Jan 21 22:43:06 2014 +0100 @@ -1,104 +1,104 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef BUFFER_H_ -#define BUFFER_H_ - -#include -#include - -/** - * A simple struct to hold both the pointer to an array and its size, - * for e.g. conveniently returning it from a function. - * - * Convention: Size is zero iff data is a NULL pointer. - */ -typedef struct { - void *data; - size_t size; -} flib_buffer; - -/** - * Just like flib_buffer, but the contents are not supposed to be modified. - */ -typedef struct { - const void *data; - size_t size; -} flib_constbuffer; - -/** - * Simple variable-capacity data structure that can be efficiently appended to. - */ -typedef struct _flib_vector flib_vector; - -/** - * Create a new vector. Needs to be destroyed again later with flib_vector_destroy. - * May return NULL if memory runs out. - */ -flib_vector *flib_vector_create(); - -/** - * Free the memory of this vector - */ -void flib_vector_destroy(flib_vector *vec); - -/** - * Resize the vector. This changes the size, and ensures the capacity is large enough to - * for the new size. Can also free memory if the new size is smaller. There is no guarantee - * about the contents of extra memory. - */ -int flib_vector_resize(flib_vector *vec, size_t newSize); - -/** - * Append the provided data to the end of the vector, enlarging it as required. - * The vector remains unchanged if appending fails. - * Returns 0 on success. - */ -int flib_vector_append(flib_vector *vec, const void *data, size_t len); - -/** - * Append data from a format string to the buffer (without trailing 0) - * Returns 0 on success. - */ -int flib_vector_appendf(flib_vector *vec, const char *template, ...); - -/** - * Return a pointer to the current data buffer of the vector. This pointer can - * become invalid if the vector size or capacity is changed. - */ -void *flib_vector_data(flib_vector *vec); - -/** - * Return the current size of the vector. - */ -size_t flib_vector_size(flib_vector *vec); - -/** - * Return a buffer pointing to the current contents of the vector. - * These will become invalid if the vector size or capacity is changed. - */ -flib_buffer flib_vector_as_buffer(flib_vector *vec); - -/** - * Return a constbuffer pointing to the current contents of the vector. - * These will become invalid if the vector size or capacity is changed. - */ -flib_constbuffer flib_vector_as_constbuffer(flib_vector *vec); - -#endif +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef BUFFER_H_ +#define BUFFER_H_ + +#include +#include + +/** + * A simple struct to hold both the pointer to an array and its size, + * for e.g. conveniently returning it from a function. + * + * Convention: Size is zero iff data is a NULL pointer. + */ +typedef struct { + void *data; + size_t size; +} flib_buffer; + +/** + * Just like flib_buffer, but the contents are not supposed to be modified. + */ +typedef struct { + const void *data; + size_t size; +} flib_constbuffer; + +/** + * Simple variable-capacity data structure that can be efficiently appended to. + */ +typedef struct _flib_vector flib_vector; + +/** + * Create a new vector. Needs to be destroyed again later with flib_vector_destroy. + * May return NULL if memory runs out. + */ +flib_vector *flib_vector_create(); + +/** + * Free the memory of this vector + */ +void flib_vector_destroy(flib_vector *vec); + +/** + * Resize the vector. This changes the size, and ensures the capacity is large enough to + * for the new size. Can also free memory if the new size is smaller. There is no guarantee + * about the contents of extra memory. + */ +int flib_vector_resize(flib_vector *vec, size_t newSize); + +/** + * Append the provided data to the end of the vector, enlarging it as required. + * The vector remains unchanged if appending fails. + * Returns 0 on success. + */ +int flib_vector_append(flib_vector *vec, const void *data, size_t len); + +/** + * Append data from a format string to the buffer (without trailing 0) + * Returns 0 on success. + */ +int flib_vector_appendf(flib_vector *vec, const char *template, ...); + +/** + * Return a pointer to the current data buffer of the vector. This pointer can + * become invalid if the vector size or capacity is changed. + */ +void *flib_vector_data(flib_vector *vec); + +/** + * Return the current size of the vector. + */ +size_t flib_vector_size(flib_vector *vec); + +/** + * Return a buffer pointing to the current contents of the vector. + * These will become invalid if the vector size or capacity is changed. + */ +flib_buffer flib_vector_as_buffer(flib_vector *vec); + +/** + * Return a constbuffer pointing to the current contents of the vector. + * These will become invalid if the vector size or capacity is changed. + */ +flib_constbuffer flib_vector_as_constbuffer(flib_vector *vec); + +#endif diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/util/inihelper.c --- a/project_files/frontlib/util/inihelper.c Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/util/inihelper.c Tue Jan 21 22:43:06 2014 +0100 @@ -1,321 +1,321 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "inihelper.h" -#include "../iniparser/dictionary.h" -#include "../iniparser/iniparser.h" - -#include "logging.h" -#include "util.h" - -#include -#include -#include -#include -#include -#include - -struct _flib_ini { - dictionary *inidict; - char *currentSection; -}; - -static char *createDictKey(const char *sectionName, const char *keyName) { - return flib_asprintf("%s:%s", sectionName, keyName); -} - -/** - * Turns a string into a lowercase string, in-place. - */ -static void strToLower(char *str) { - if(str) { - while(*str) { - *str = tolower(*str); - str++; - } - } -} - -flib_ini *flib_ini_create(const char *filename) { - flib_ini *result = NULL; - flib_ini *tmpIni = flib_calloc(1, sizeof(flib_ini)); - if(tmpIni) { - if(filename) { - tmpIni->inidict = iniparser_load(filename); - } - if(!tmpIni->inidict) { - tmpIni->inidict = dictionary_new(0); - } - if(tmpIni->inidict) { - result = tmpIni; - tmpIni = NULL; - } - } - flib_ini_destroy(tmpIni); - return result; -} - -flib_ini *flib_ini_load(const char *filename) { - flib_ini *result = NULL; - if(!log_badargs_if(filename==NULL)) { - flib_ini *tmpIni = flib_calloc(1, sizeof(flib_ini)); - if(tmpIni) { - tmpIni->inidict = iniparser_load(filename); - if(tmpIni->inidict) { - result = tmpIni; - tmpIni = NULL; - } - } - flib_ini_destroy(tmpIni); - } - return result; -} - -int flib_ini_save(flib_ini *ini, const char *filename) { - int result = INI_ERROR_OTHER; - if(!log_badargs_if2(ini==NULL, filename==NULL)) { - FILE *file = fopen(filename, "wb"); - if(!file) { - flib_log_e("Error opening file \"%s\" for writing.", filename); - } else { - iniparser_dump_ini(ini->inidict, file); - if(fclose(file)) { - flib_log_e("Write error on ini file \"%s\"", filename); - } else { - result = 0; - } - } - } - return result; -} - -void flib_ini_destroy(flib_ini *ini) { - if(ini) { - if(ini->inidict) { - iniparser_freedict(ini->inidict); - } - free(ini->currentSection); - free(ini); - } -} - -int flib_ini_enter_section(flib_ini *ini, const char *section) { - int result = INI_ERROR_OTHER; - if(ini) { - free(ini->currentSection); - ini->currentSection = NULL; - } - if(!log_badargs_if2(ini==NULL, section==NULL)) { - if(!iniparser_find_entry(ini->inidict, section)) { - flib_log_d("Ini section %s not found", section); - result = INI_ERROR_NOTFOUND; - } else { - ini->currentSection = flib_strdupnull(section); - if(ini->currentSection) { - // Usually iniparser ignores case, but some section-handling functions don't, - // so we set it to lowercase manually - strToLower(ini->currentSection); - result = 0; - } - } - } - return result; -} - -int flib_ini_create_section(flib_ini *ini, const char *section) { - int result = INI_ERROR_OTHER; - if(!log_badargs_if2(ini==NULL, section==NULL)) { - result = flib_ini_enter_section(ini, section); - if(result == INI_ERROR_NOTFOUND) { - if(iniparser_set(ini->inidict, section, NULL)) { - flib_log_e("Error creating ini section %s", section); - result = INI_ERROR_OTHER; - } else { - result = flib_ini_enter_section(ini, section); - } - } - } - return result; -} - -/** - * The result is an internal string of the iniparser, don't free it. - */ -static char *findValue(dictionary *dict, const char *section, const char *key) { - char *result = NULL; - char *dictKey = createDictKey(section, key); - if(dictKey) { - result = iniparser_getstring(dict, dictKey, NULL); - } - free(dictKey); - return result; -} - -int flib_ini_get_str(flib_ini *ini, char **outVar, const char *key) { - char *tmpValue = NULL; - int result = flib_ini_get_str_opt(ini, &tmpValue, key, NULL); - if(result==0) { - if(tmpValue == NULL) { - result = INI_ERROR_NOTFOUND; - } else { - *outVar = tmpValue; - tmpValue = NULL; - } - } - free(tmpValue); - return result; -} - -int flib_ini_get_str_opt(flib_ini *ini, char **outVar, const char *key, const char *def) { - int result = INI_ERROR_OTHER; - if(!log_badargs_if4(ini==NULL, ini->currentSection==NULL, outVar==NULL, key==NULL)) { - const char *value = findValue(ini->inidict, ini->currentSection, key); - if(!value) { - value = def; - } - char *valueDup = flib_strdupnull(value); - if(valueDup || !def) { - *outVar = valueDup; - result = 0; - } - } - return result; -} - -int flib_ini_get_int(flib_ini *ini, int *outVar, const char *key) { - char *tmpValue = NULL; - int result = flib_ini_get_str(ini, &tmpValue, key); - if(result==0) { - errno = 0; - long val = strtol(tmpValue, NULL, 10); - if(errno!=0 || valINT_MAX) { - flib_log_w("Cannot parse ini setting %s/%s = \"%s\" as integer.", ini->currentSection, key, tmpValue); - result = INI_ERROR_FORMAT; - } else { - *outVar = val; - } - } - free(tmpValue); - return result; -} - -int flib_ini_get_int_opt(flib_ini *ini, int *outVar, const char *key, int def) { - int tmpValue; - int result = flib_ini_get_int(ini, &tmpValue, key); - if(result == 0) { - *outVar = tmpValue; - } else if(result == INI_ERROR_NOTFOUND || result == INI_ERROR_FORMAT) { - *outVar = def; - result = 0; - } - return result; -} - -int flib_ini_get_bool(flib_ini *ini, bool *outVar, const char *key) { - char *tmpValue = NULL; - int result = flib_ini_get_str(ini, &tmpValue, key); - if(result==0) { - bool trueval = strchr("1tTyY", tmpValue[0]); - bool falseval = strchr("0fFnN", tmpValue[0]); - if(!trueval && !falseval) { - flib_log_w("ini setting %s/%s = \"%s\" is not a recognized truth value.", ini->currentSection, key, tmpValue); - result = INI_ERROR_FORMAT; - } else { - *outVar = trueval; - } - } - free(tmpValue); - return result; -} - -int flib_ini_get_bool_opt(flib_ini *ini, bool *outVar, const char *key, bool def) { - bool tmpValue; - int result = flib_ini_get_bool(ini, &tmpValue, key); - if(result == 0) { - *outVar = tmpValue; - } else if(result == INI_ERROR_NOTFOUND || result == INI_ERROR_FORMAT) { - *outVar = def; - result = 0; - } - return result; -} - -int flib_ini_set_str(flib_ini *ini, const char *key, const char *value) { - int result = INI_ERROR_OTHER; - if(!log_badargs_if4(ini==NULL, ini->currentSection==NULL, key==NULL, value==NULL)) { - char *dictKey = createDictKey(ini->currentSection, key); - if(dictKey) { - result = iniparser_set(ini->inidict, dictKey, value); - if(result) { - flib_log_e("Error setting ini entry %s to %s", dictKey, value); - } - } - free(dictKey); - } - return result; -} - -int flib_ini_set_int(flib_ini *ini, const char *key, int value) { - int result = INI_ERROR_OTHER; - char *strvalue = flib_asprintf("%i", value); - if(strvalue) { - result = flib_ini_set_str(ini, key, strvalue); - } - free(strvalue); - return result; -} - -int flib_ini_set_bool(flib_ini *ini, const char *key, bool value) { - return flib_ini_set_str(ini, key, value ? "true" : "false"); -} - -int flib_ini_get_sectioncount(flib_ini *ini) { - if(!log_badargs_if(ini==NULL)) { - return iniparser_getnsec(ini->inidict); - } - return INI_ERROR_OTHER; -} - -char *flib_ini_get_sectionname(flib_ini *ini, int number) { - if(!log_badargs_if2(ini==NULL, number<0)) { - return flib_strdupnull(iniparser_getsecname(ini->inidict, number)); - } - return NULL; -} - -int flib_ini_get_keycount(flib_ini *ini) { - if(!log_badargs_if2(ini==NULL, ini->currentSection==NULL)) { - return iniparser_getsecnkeys(ini->inidict, ini->currentSection); - } - return INI_ERROR_OTHER; -} - -char *flib_ini_get_keyname(flib_ini *ini, int number) { - char *result = NULL; - if(!log_badargs_if3(ini==NULL, ini->currentSection==NULL, number<0)) { - int keyCount = iniparser_getsecnkeys(ini->inidict, ini->currentSection); - char **keys = iniparser_getseckeys(ini->inidict, ini->currentSection); - if(keys && keyCount>number) { - // The keys are in the format section:key, so we have to skip the section and colon. - result = flib_strdupnull(keys[number]+strlen(ini->currentSection)+1); - } - free(keys); - } - return result; -} +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "inihelper.h" +#include "../iniparser/dictionary.h" +#include "../iniparser/iniparser.h" + +#include "logging.h" +#include "util.h" + +#include +#include +#include +#include +#include +#include + +struct _flib_ini { + dictionary *inidict; + char *currentSection; +}; + +static char *createDictKey(const char *sectionName, const char *keyName) { + return flib_asprintf("%s:%s", sectionName, keyName); +} + +/** + * Turns a string into a lowercase string, in-place. + */ +static void strToLower(char *str) { + if(str) { + while(*str) { + *str = tolower(*str); + str++; + } + } +} + +flib_ini *flib_ini_create(const char *filename) { + flib_ini *result = NULL; + flib_ini *tmpIni = flib_calloc(1, sizeof(flib_ini)); + if(tmpIni) { + if(filename) { + tmpIni->inidict = iniparser_load(filename); + } + if(!tmpIni->inidict) { + tmpIni->inidict = dictionary_new(0); + } + if(tmpIni->inidict) { + result = tmpIni; + tmpIni = NULL; + } + } + flib_ini_destroy(tmpIni); + return result; +} + +flib_ini *flib_ini_load(const char *filename) { + flib_ini *result = NULL; + if(!log_badargs_if(filename==NULL)) { + flib_ini *tmpIni = flib_calloc(1, sizeof(flib_ini)); + if(tmpIni) { + tmpIni->inidict = iniparser_load(filename); + if(tmpIni->inidict) { + result = tmpIni; + tmpIni = NULL; + } + } + flib_ini_destroy(tmpIni); + } + return result; +} + +int flib_ini_save(flib_ini *ini, const char *filename) { + int result = INI_ERROR_OTHER; + if(!log_badargs_if2(ini==NULL, filename==NULL)) { + FILE *file = fopen(filename, "wb"); + if(!file) { + flib_log_e("Error opening file \"%s\" for writing.", filename); + } else { + iniparser_dump_ini(ini->inidict, file); + if(fclose(file)) { + flib_log_e("Write error on ini file \"%s\"", filename); + } else { + result = 0; + } + } + } + return result; +} + +void flib_ini_destroy(flib_ini *ini) { + if(ini) { + if(ini->inidict) { + iniparser_freedict(ini->inidict); + } + free(ini->currentSection); + free(ini); + } +} + +int flib_ini_enter_section(flib_ini *ini, const char *section) { + int result = INI_ERROR_OTHER; + if(ini) { + free(ini->currentSection); + ini->currentSection = NULL; + } + if(!log_badargs_if2(ini==NULL, section==NULL)) { + if(!iniparser_find_entry(ini->inidict, section)) { + flib_log_d("Ini section %s not found", section); + result = INI_ERROR_NOTFOUND; + } else { + ini->currentSection = flib_strdupnull(section); + if(ini->currentSection) { + // Usually iniparser ignores case, but some section-handling functions don't, + // so we set it to lowercase manually + strToLower(ini->currentSection); + result = 0; + } + } + } + return result; +} + +int flib_ini_create_section(flib_ini *ini, const char *section) { + int result = INI_ERROR_OTHER; + if(!log_badargs_if2(ini==NULL, section==NULL)) { + result = flib_ini_enter_section(ini, section); + if(result == INI_ERROR_NOTFOUND) { + if(iniparser_set(ini->inidict, section, NULL)) { + flib_log_e("Error creating ini section %s", section); + result = INI_ERROR_OTHER; + } else { + result = flib_ini_enter_section(ini, section); + } + } + } + return result; +} + +/** + * The result is an internal string of the iniparser, don't free it. + */ +static char *findValue(dictionary *dict, const char *section, const char *key) { + char *result = NULL; + char *dictKey = createDictKey(section, key); + if(dictKey) { + result = iniparser_getstring(dict, dictKey, NULL); + } + free(dictKey); + return result; +} + +int flib_ini_get_str(flib_ini *ini, char **outVar, const char *key) { + char *tmpValue = NULL; + int result = flib_ini_get_str_opt(ini, &tmpValue, key, NULL); + if(result==0) { + if(tmpValue == NULL) { + result = INI_ERROR_NOTFOUND; + } else { + *outVar = tmpValue; + tmpValue = NULL; + } + } + free(tmpValue); + return result; +} + +int flib_ini_get_str_opt(flib_ini *ini, char **outVar, const char *key, const char *def) { + int result = INI_ERROR_OTHER; + if(!log_badargs_if4(ini==NULL, ini->currentSection==NULL, outVar==NULL, key==NULL)) { + const char *value = findValue(ini->inidict, ini->currentSection, key); + if(!value) { + value = def; + } + char *valueDup = flib_strdupnull(value); + if(valueDup || !def) { + *outVar = valueDup; + result = 0; + } + } + return result; +} + +int flib_ini_get_int(flib_ini *ini, int *outVar, const char *key) { + char *tmpValue = NULL; + int result = flib_ini_get_str(ini, &tmpValue, key); + if(result==0) { + errno = 0; + long val = strtol(tmpValue, NULL, 10); + if(errno!=0 || valINT_MAX) { + flib_log_w("Cannot parse ini setting %s/%s = \"%s\" as integer.", ini->currentSection, key, tmpValue); + result = INI_ERROR_FORMAT; + } else { + *outVar = val; + } + } + free(tmpValue); + return result; +} + +int flib_ini_get_int_opt(flib_ini *ini, int *outVar, const char *key, int def) { + int tmpValue; + int result = flib_ini_get_int(ini, &tmpValue, key); + if(result == 0) { + *outVar = tmpValue; + } else if(result == INI_ERROR_NOTFOUND || result == INI_ERROR_FORMAT) { + *outVar = def; + result = 0; + } + return result; +} + +int flib_ini_get_bool(flib_ini *ini, bool *outVar, const char *key) { + char *tmpValue = NULL; + int result = flib_ini_get_str(ini, &tmpValue, key); + if(result==0) { + bool trueval = strchr("1tTyY", tmpValue[0]); + bool falseval = strchr("0fFnN", tmpValue[0]); + if(!trueval && !falseval) { + flib_log_w("ini setting %s/%s = \"%s\" is not a recognized truth value.", ini->currentSection, key, tmpValue); + result = INI_ERROR_FORMAT; + } else { + *outVar = trueval; + } + } + free(tmpValue); + return result; +} + +int flib_ini_get_bool_opt(flib_ini *ini, bool *outVar, const char *key, bool def) { + bool tmpValue; + int result = flib_ini_get_bool(ini, &tmpValue, key); + if(result == 0) { + *outVar = tmpValue; + } else if(result == INI_ERROR_NOTFOUND || result == INI_ERROR_FORMAT) { + *outVar = def; + result = 0; + } + return result; +} + +int flib_ini_set_str(flib_ini *ini, const char *key, const char *value) { + int result = INI_ERROR_OTHER; + if(!log_badargs_if4(ini==NULL, ini->currentSection==NULL, key==NULL, value==NULL)) { + char *dictKey = createDictKey(ini->currentSection, key); + if(dictKey) { + result = iniparser_set(ini->inidict, dictKey, value); + if(result) { + flib_log_e("Error setting ini entry %s to %s", dictKey, value); + } + } + free(dictKey); + } + return result; +} + +int flib_ini_set_int(flib_ini *ini, const char *key, int value) { + int result = INI_ERROR_OTHER; + char *strvalue = flib_asprintf("%i", value); + if(strvalue) { + result = flib_ini_set_str(ini, key, strvalue); + } + free(strvalue); + return result; +} + +int flib_ini_set_bool(flib_ini *ini, const char *key, bool value) { + return flib_ini_set_str(ini, key, value ? "true" : "false"); +} + +int flib_ini_get_sectioncount(flib_ini *ini) { + if(!log_badargs_if(ini==NULL)) { + return iniparser_getnsec(ini->inidict); + } + return INI_ERROR_OTHER; +} + +char *flib_ini_get_sectionname(flib_ini *ini, int number) { + if(!log_badargs_if2(ini==NULL, number<0)) { + return flib_strdupnull(iniparser_getsecname(ini->inidict, number)); + } + return NULL; +} + +int flib_ini_get_keycount(flib_ini *ini) { + if(!log_badargs_if2(ini==NULL, ini->currentSection==NULL)) { + return iniparser_getsecnkeys(ini->inidict, ini->currentSection); + } + return INI_ERROR_OTHER; +} + +char *flib_ini_get_keyname(flib_ini *ini, int number) { + char *result = NULL; + if(!log_badargs_if3(ini==NULL, ini->currentSection==NULL, number<0)) { + int keyCount = iniparser_getsecnkeys(ini->inidict, ini->currentSection); + char **keys = iniparser_getseckeys(ini->inidict, ini->currentSection); + if(keys && keyCount>number) { + // The keys are in the format section:key, so we have to skip the section and colon. + result = flib_strdupnull(keys[number]+strlen(ini->currentSection)+1); + } + free(keys); + } + return result; +} diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/util/inihelper.h --- a/project_files/frontlib/util/inihelper.h Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/util/inihelper.h Tue Jan 21 22:43:06 2014 +0100 @@ -1,178 +1,178 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * Convenience interface for ini reading/writing. - * - * We currently use iniparser in the background, but using its interface directly is a bit verbose. - * This module is supposed to 1. make ini reading and writing a bit more convenient, and 2. hide - * the iniparser dependency so it can at need be easily replaced. - */ - -#ifndef INIHELPER_H_ -#define INIHELPER_H_ - -#include - -#define INI_ERROR_NOTFOUND -1 -#define INI_ERROR_FORMAT -2 -#define INI_ERROR_OTHER -100 - -typedef struct _flib_ini flib_ini; - -/** - * Create a new ini data structure, pre-filled with the contents of - * the file "filename" if it exists. If filename is null, or the file - * is not found, an empty ini will be created. However, if an error - * occurs while reading the ini file (or any other error), null - * is returned. - * - * This behavior is useful for modifying an existing ini file without - * discarding unknown keys. - */ -flib_ini *flib_ini_create(const char *filename); - -/** - * Similar to flib_ini_create, but fails if the file is not found - * or if filename is null. - */ -flib_ini *flib_ini_load(const char *filename); - -/** - * Store the ini to the file "filename", overwriting - * the previous contents. Returns 0 on success. - */ -int flib_ini_save(flib_ini *ini, const char *filename); - -void flib_ini_destroy(flib_ini *ini); - -/** - * Enter the section with the specified name. Returns 0 on - * success, INI_ERROR_NOTFOUND if the section does not exist - * and a different value if another error occurs. - * If an error occurs, there is no current section. - * - * The section name should only consist of letters and - * numbers. - */ -int flib_ini_enter_section(flib_ini *ini, const char *section); - -/** - * Creates and enters the section with the specified name. Simply - * enters the section if it exists already. Returns 0 on success - * and a different value if another error occurs. - * If an error occurs, there is no current section. - */ -int flib_ini_create_section(flib_ini *ini, const char *section); - -/** - * Find a key in the current section and store the value in outVar - * as a newly allocated string. Returns 0 on success, INI_ERROR_NOTFOUND - * if the key was not found and a different value for other errors, - * e.g. if there is no current section. - */ -int flib_ini_get_str(flib_ini *ini, char **outVar, const char *key); - -/** - * Find a key in the current section and store the value in outVar - * as a newly allocated string. If the key is not found, the default - * value will be used instead. Returns 0 on success. - */ -int flib_ini_get_str_opt(flib_ini *ini, char **outVar, const char *key, const char *def); - -/** - * Find a key in the current section and store the value in outVar - * as an int. Returns 0 on success, INI_ERROR_NOTFOUND - * if the key was not found, INI_ERROR_FORMAT if it was found but - * could not be converted to an int, and a different value for other - * errors, e.g. if there is no current section. - */ -int flib_ini_get_int(flib_ini *ini, int *outVar, const char *key); - -/** - * Find a key in the current section and store the value in outVar - * as an int. If the key is not found, the default value will be used instead. - * Returns 0 on success, INI_ERROR_FORMAT if the value was found but - * could not be converted to int, and another value otherwise. - */ -int flib_ini_get_int_opt(flib_ini *ini, int *outVar, const char *key, int def); - -/** - * Find a key in the current section and store the value in outVar - * as a bool. Treats everything beginning with "Y", "T" or "1" as true, - * everything starting with "N", "F" or "1" as false. - * - * Returns 0 on success, INI_ERROR_NOTFOUND if the key was not found, - * INI_ERROR_FORMAT if the value could not be interpreted as boolean, - * and another value otherwise. - */ -int flib_ini_get_bool(flib_ini *ini, bool *outVar, const char *key); - -/** - * Find a key in the current section and store the value in outVar - * as a bool. If the key is not found, the default value will be - * used instead. Returns 0 on success, INI_ERROR_FORMAT if the - * value could not be interpreted as boolean, and another value otherwise. - */ -int flib_ini_get_bool_opt(flib_ini *ini, bool *outVar, const char *key, bool def); - -/** - * In the current section, associate key with value. Returns 0 on success. - */ -int flib_ini_set_str(flib_ini *ini, const char *key, const char *value); - -/** - * In the current section, associate key with value. Returns 0 on success. - */ -int flib_ini_set_int(flib_ini *ini, const char *key, int value); - -/** - * In the current section, associate key with value. Returns 0 on success. - */ -int flib_ini_set_bool(flib_ini *ini, const char *key, bool value); - -/** - * Returns the number of sections in the ini file, or a negative value on error. - */ -int flib_ini_get_sectioncount(flib_ini *ini); - -/** - * Returns the name of the section, or NULL on error. The returned string must - * be free()d. - * - * Note: There is no guarantee that the order of the sections - * will remain stable if the ini is modified. - */ -char *flib_ini_get_sectionname(flib_ini *ini, int number); - -/** - * Returns the number of keys in the current section, or -1 on error. - */ -int flib_ini_get_keycount(flib_ini *ini); - -/** - * Returns the name of the key in the current section, or NULL on error. - * The returned string must be free()d. - * - * Note: There is no guarantee that the order of the keys in a section - * will remain stable if the ini is modified. - */ -char *flib_ini_get_keyname(flib_ini *ini, int number); - -#endif /* INIHELPER_H_ */ +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * Convenience interface for ini reading/writing. + * + * We currently use iniparser in the background, but using its interface directly is a bit verbose. + * This module is supposed to 1. make ini reading and writing a bit more convenient, and 2. hide + * the iniparser dependency so it can at need be easily replaced. + */ + +#ifndef INIHELPER_H_ +#define INIHELPER_H_ + +#include + +#define INI_ERROR_NOTFOUND -1 +#define INI_ERROR_FORMAT -2 +#define INI_ERROR_OTHER -100 + +typedef struct _flib_ini flib_ini; + +/** + * Create a new ini data structure, pre-filled with the contents of + * the file "filename" if it exists. If filename is null, or the file + * is not found, an empty ini will be created. However, if an error + * occurs while reading the ini file (or any other error), null + * is returned. + * + * This behavior is useful for modifying an existing ini file without + * discarding unknown keys. + */ +flib_ini *flib_ini_create(const char *filename); + +/** + * Similar to flib_ini_create, but fails if the file is not found + * or if filename is null. + */ +flib_ini *flib_ini_load(const char *filename); + +/** + * Store the ini to the file "filename", overwriting + * the previous contents. Returns 0 on success. + */ +int flib_ini_save(flib_ini *ini, const char *filename); + +void flib_ini_destroy(flib_ini *ini); + +/** + * Enter the section with the specified name. Returns 0 on + * success, INI_ERROR_NOTFOUND if the section does not exist + * and a different value if another error occurs. + * If an error occurs, there is no current section. + * + * The section name should only consist of letters and + * numbers. + */ +int flib_ini_enter_section(flib_ini *ini, const char *section); + +/** + * Creates and enters the section with the specified name. Simply + * enters the section if it exists already. Returns 0 on success + * and a different value if another error occurs. + * If an error occurs, there is no current section. + */ +int flib_ini_create_section(flib_ini *ini, const char *section); + +/** + * Find a key in the current section and store the value in outVar + * as a newly allocated string. Returns 0 on success, INI_ERROR_NOTFOUND + * if the key was not found and a different value for other errors, + * e.g. if there is no current section. + */ +int flib_ini_get_str(flib_ini *ini, char **outVar, const char *key); + +/** + * Find a key in the current section and store the value in outVar + * as a newly allocated string. If the key is not found, the default + * value will be used instead. Returns 0 on success. + */ +int flib_ini_get_str_opt(flib_ini *ini, char **outVar, const char *key, const char *def); + +/** + * Find a key in the current section and store the value in outVar + * as an int. Returns 0 on success, INI_ERROR_NOTFOUND + * if the key was not found, INI_ERROR_FORMAT if it was found but + * could not be converted to an int, and a different value for other + * errors, e.g. if there is no current section. + */ +int flib_ini_get_int(flib_ini *ini, int *outVar, const char *key); + +/** + * Find a key in the current section and store the value in outVar + * as an int. If the key is not found, the default value will be used instead. + * Returns 0 on success, INI_ERROR_FORMAT if the value was found but + * could not be converted to int, and another value otherwise. + */ +int flib_ini_get_int_opt(flib_ini *ini, int *outVar, const char *key, int def); + +/** + * Find a key in the current section and store the value in outVar + * as a bool. Treats everything beginning with "Y", "T" or "1" as true, + * everything starting with "N", "F" or "1" as false. + * + * Returns 0 on success, INI_ERROR_NOTFOUND if the key was not found, + * INI_ERROR_FORMAT if the value could not be interpreted as boolean, + * and another value otherwise. + */ +int flib_ini_get_bool(flib_ini *ini, bool *outVar, const char *key); + +/** + * Find a key in the current section and store the value in outVar + * as a bool. If the key is not found, the default value will be + * used instead. Returns 0 on success, INI_ERROR_FORMAT if the + * value could not be interpreted as boolean, and another value otherwise. + */ +int flib_ini_get_bool_opt(flib_ini *ini, bool *outVar, const char *key, bool def); + +/** + * In the current section, associate key with value. Returns 0 on success. + */ +int flib_ini_set_str(flib_ini *ini, const char *key, const char *value); + +/** + * In the current section, associate key with value. Returns 0 on success. + */ +int flib_ini_set_int(flib_ini *ini, const char *key, int value); + +/** + * In the current section, associate key with value. Returns 0 on success. + */ +int flib_ini_set_bool(flib_ini *ini, const char *key, bool value); + +/** + * Returns the number of sections in the ini file, or a negative value on error. + */ +int flib_ini_get_sectioncount(flib_ini *ini); + +/** + * Returns the name of the section, or NULL on error. The returned string must + * be free()d. + * + * Note: There is no guarantee that the order of the sections + * will remain stable if the ini is modified. + */ +char *flib_ini_get_sectionname(flib_ini *ini, int number); + +/** + * Returns the number of keys in the current section, or -1 on error. + */ +int flib_ini_get_keycount(flib_ini *ini); + +/** + * Returns the name of the key in the current section, or NULL on error. + * The returned string must be free()d. + * + * Note: There is no guarantee that the order of the keys in a section + * will remain stable if the ini is modified. + */ +char *flib_ini_get_keyname(flib_ini *ini, int number); + +#endif /* INIHELPER_H_ */ diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/util/list.h --- a/project_files/frontlib/util/list.h Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/util/list.h Tue Jan 21 22:43:06 2014 +0100 @@ -1,80 +1,80 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * Simple dynamic array manipulation functions. - */ - -#ifndef LIST_H_ -#define LIST_H_ - -#include -#include -#include -#include "util.h" -#include "logging.h" - -/** - * Generate a static function that inserts a new value into a heap array of the given type, - * using realloc and memmove to increase the capacity and shift existing values. - * The function takes a pointer to the array variable and a pointer to the size variable - * because both can be changed by this operation (realloc / increment). - * The function returns 0 on success and leaves the array unchanged on error. - */ -#define GENERATE_STATIC_LIST_INSERT(fname, type) \ - static int fname(type **listptr, int *listSizePtr, type element, int pos) { \ - int result = -1; \ - if(!log_badargs_if4(listptr==NULL, listSizePtr==NULL, pos < 0, pos > *listSizePtr)) { \ - type *newList = flib_realloc(*listptr, ((*listSizePtr)+1)*sizeof(type)); \ - if(newList) { \ - memmove(newList + (pos+1), newList + pos, ((*listSizePtr)-pos)*sizeof(type)); \ - newList[pos] = element; \ - (*listSizePtr)++; \ - *listptr = newList; \ - result = 0; \ - } \ - } \ - return result; \ - } - -/** - * Generate a static function that deletes a value from a heap array of the given type, - * using realloc and memmove to decrease the capacity and shift existing values. - * The function takes a pointer to the array variable and a pointer to the size variable - * because both can be changed by this operation (realloc / decrement). - * The function returns 0 on success and leaves the array unchanged on error. - */ -#define GENERATE_STATIC_LIST_DELETE(fname, type) \ - static int fname(type **listPtr, int *listSizePtr, int pos) { \ - int result = -1; \ - if(!log_badargs_if4(listPtr==NULL, listSizePtr==NULL, pos < 0, pos >= *listSizePtr)) { \ - memmove((*listPtr) + pos, (*listPtr) + (pos+1), ((*listSizePtr)-(pos+1))*sizeof(type)); \ - (*listSizePtr)--; \ - \ - size_t newCharSize = (*listSizePtr)*sizeof(type); \ - type *newList = flib_realloc((*listPtr), newCharSize); \ - if(newList || newCharSize==0) { \ - (*listPtr) = newList; \ - } /* If the realloc fails, just keep using the old buffer...*/ \ - result = 0; \ - } \ - return result; \ - } - -#endif /* LIST_H_ */ +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * Simple dynamic array manipulation functions. + */ + +#ifndef LIST_H_ +#define LIST_H_ + +#include +#include +#include +#include "util.h" +#include "logging.h" + +/** + * Generate a static function that inserts a new value into a heap array of the given type, + * using realloc and memmove to increase the capacity and shift existing values. + * The function takes a pointer to the array variable and a pointer to the size variable + * because both can be changed by this operation (realloc / increment). + * The function returns 0 on success and leaves the array unchanged on error. + */ +#define GENERATE_STATIC_LIST_INSERT(fname, type) \ + static int fname(type **listptr, int *listSizePtr, type element, int pos) { \ + int result = -1; \ + if(!log_badargs_if4(listptr==NULL, listSizePtr==NULL, pos < 0, pos > *listSizePtr)) { \ + type *newList = flib_realloc(*listptr, ((*listSizePtr)+1)*sizeof(type)); \ + if(newList) { \ + memmove(newList + (pos+1), newList + pos, ((*listSizePtr)-pos)*sizeof(type)); \ + newList[pos] = element; \ + (*listSizePtr)++; \ + *listptr = newList; \ + result = 0; \ + } \ + } \ + return result; \ + } + +/** + * Generate a static function that deletes a value from a heap array of the given type, + * using realloc and memmove to decrease the capacity and shift existing values. + * The function takes a pointer to the array variable and a pointer to the size variable + * because both can be changed by this operation (realloc / decrement). + * The function returns 0 on success and leaves the array unchanged on error. + */ +#define GENERATE_STATIC_LIST_DELETE(fname, type) \ + static int fname(type **listPtr, int *listSizePtr, int pos) { \ + int result = -1; \ + if(!log_badargs_if4(listPtr==NULL, listSizePtr==NULL, pos < 0, pos >= *listSizePtr)) { \ + memmove((*listPtr) + pos, (*listPtr) + (pos+1), ((*listSizePtr)-(pos+1))*sizeof(type)); \ + (*listSizePtr)--; \ + \ + size_t newCharSize = (*listSizePtr)*sizeof(type); \ + type *newList = flib_realloc((*listPtr), newCharSize); \ + if(newList || newCharSize==0) { \ + (*listPtr) = newList; \ + } /* If the realloc fails, just keep using the old buffer...*/ \ + result = 0; \ + } \ + return result; \ + } + +#endif /* LIST_H_ */ diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/util/logging.c --- a/project_files/frontlib/util/logging.c Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/util/logging.c Tue Jan 21 22:43:06 2014 +0100 @@ -1,145 +1,145 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "logging.h" - -#include -#include -#include -#include - -static int flib_loglevel = FLIB_LOGLEVEL_INFO; -static FILE *flib_logfile = NULL; -void (*flib_logCallback)(int level, const char *msg) = NULL; - -char* flib_format_ip(uint32_t numip) { - static char ip[16]; - snprintf(ip, 16, "%u.%u.%u.%u", (unsigned)(numip>>24), (unsigned)((numip>>16)&0xff), (unsigned)((numip>>8)&0xff), (unsigned)(numip&0xff)); - return ip; -} - -static inline FILE *flib_log_getfile() { - if(flib_logfile==NULL) { - return stdout; - } else { - return flib_logfile; - } -} - -static int log_time(char *buffer) { - time_t timer; - struct tm* tm_info; - - time(&timer); - tm_info = localtime(&timer); - - return strftime(buffer, 25, "%Y-%m-%d %H:%M:%S", tm_info); -} - -static char getPrefix(int level) { - switch(level) { - case FLIB_LOGLEVEL_ERROR: return 'E'; - case FLIB_LOGLEVEL_WARNING: return 'W'; - case FLIB_LOGLEVEL_INFO: return 'I'; - case FLIB_LOGLEVEL_DEBUG: return 'D'; - default: return '?'; - } -} - -static void _flib_vflog(const char *func, int level, const char *fmt, va_list args) { - if(level >= flib_loglevel) { - char logbuffer[1024]; - logbuffer[0] = getPrefix(level); - logbuffer[1] = ' '; - - int pos = 2; - - int len = log_time(logbuffer+pos); - if(len>=0) { - pos += len; - if(pos>sizeof(logbuffer)-1) pos = sizeof(logbuffer)-1; - } else { - return; - } - - len = snprintf(logbuffer+pos, sizeof(logbuffer)-pos, " [%-30s] ", func); - if(len>=0) { - pos += len; - if(pos>sizeof(logbuffer)-1) pos = sizeof(logbuffer)-1; - } else { - return; - } - - len = vsnprintf(logbuffer+pos, sizeof(logbuffer)-pos, fmt, args); - if(len>=0) { - pos += len; - if(pos>sizeof(logbuffer)-1) pos = sizeof(logbuffer)-1; - } else { - return; - } - - if(flib_logCallback != NULL) { - flib_logCallback(level, logbuffer); - } else { - FILE *logfile = flib_log_getfile(); - fputs(logbuffer, logfile); - fputc('\n', logfile); - fflush(logfile); - } - } -} - -void _flib_flog(const char *func, int level, const char *fmt, ...) { - va_list argp; - va_start(argp, fmt); - _flib_vflog(func, level, fmt, argp); - va_end(argp); -} - -bool _flib_fassert(const char *func, int level, bool cond, const char *fmt, ...) { - if(!cond) { - va_list argp; - va_start(argp, fmt); - _flib_vflog(func, level, fmt, argp); - va_end(argp); - } - return !cond; -} - -int flib_log_getLevel() { - return flib_loglevel; -} - -void flib_log_setLevel(int level) { - flib_loglevel = level; -} - -void flib_log_setFile(FILE *file) { - flib_logfile = file; - flib_logCallback = NULL; -} - -bool flib_log_isActive(int level) { - return level >= flib_log_getLevel(); -} - -void flib_log_setCallback(void (*logCallback)(int level, const char *msg)) { - flib_logCallback = logCallback; - flib_logfile = NULL; -} +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "logging.h" + +#include +#include +#include +#include + +static int flib_loglevel = FLIB_LOGLEVEL_INFO; +static FILE *flib_logfile = NULL; +void (*flib_logCallback)(int level, const char *msg) = NULL; + +char* flib_format_ip(uint32_t numip) { + static char ip[16]; + snprintf(ip, 16, "%u.%u.%u.%u", (unsigned)(numip>>24), (unsigned)((numip>>16)&0xff), (unsigned)((numip>>8)&0xff), (unsigned)(numip&0xff)); + return ip; +} + +static inline FILE *flib_log_getfile() { + if(flib_logfile==NULL) { + return stdout; + } else { + return flib_logfile; + } +} + +static int log_time(char *buffer) { + time_t timer; + struct tm* tm_info; + + time(&timer); + tm_info = localtime(&timer); + + return strftime(buffer, 25, "%Y-%m-%d %H:%M:%S", tm_info); +} + +static char getPrefix(int level) { + switch(level) { + case FLIB_LOGLEVEL_ERROR: return 'E'; + case FLIB_LOGLEVEL_WARNING: return 'W'; + case FLIB_LOGLEVEL_INFO: return 'I'; + case FLIB_LOGLEVEL_DEBUG: return 'D'; + default: return '?'; + } +} + +static void _flib_vflog(const char *func, int level, const char *fmt, va_list args) { + if(level >= flib_loglevel) { + char logbuffer[1024]; + logbuffer[0] = getPrefix(level); + logbuffer[1] = ' '; + + int pos = 2; + + int len = log_time(logbuffer+pos); + if(len>=0) { + pos += len; + if(pos>sizeof(logbuffer)-1) pos = sizeof(logbuffer)-1; + } else { + return; + } + + len = snprintf(logbuffer+pos, sizeof(logbuffer)-pos, " [%-30s] ", func); + if(len>=0) { + pos += len; + if(pos>sizeof(logbuffer)-1) pos = sizeof(logbuffer)-1; + } else { + return; + } + + len = vsnprintf(logbuffer+pos, sizeof(logbuffer)-pos, fmt, args); + if(len>=0) { + pos += len; + if(pos>sizeof(logbuffer)-1) pos = sizeof(logbuffer)-1; + } else { + return; + } + + if(flib_logCallback != NULL) { + flib_logCallback(level, logbuffer); + } else { + FILE *logfile = flib_log_getfile(); + fputs(logbuffer, logfile); + fputc('\n', logfile); + fflush(logfile); + } + } +} + +void _flib_flog(const char *func, int level, const char *fmt, ...) { + va_list argp; + va_start(argp, fmt); + _flib_vflog(func, level, fmt, argp); + va_end(argp); +} + +bool _flib_fassert(const char *func, int level, bool cond, const char *fmt, ...) { + if(!cond) { + va_list argp; + va_start(argp, fmt); + _flib_vflog(func, level, fmt, argp); + va_end(argp); + } + return !cond; +} + +int flib_log_getLevel() { + return flib_loglevel; +} + +void flib_log_setLevel(int level) { + flib_loglevel = level; +} + +void flib_log_setFile(FILE *file) { + flib_logfile = file; + flib_logCallback = NULL; +} + +bool flib_log_isActive(int level) { + return level >= flib_log_getLevel(); +} + +void flib_log_setCallback(void (*logCallback)(int level, const char *msg)) { + flib_logCallback = logCallback; + flib_logfile = NULL; +} diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/util/logging.h --- a/project_files/frontlib/util/logging.h Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/util/logging.h Tue Jan 21 22:43:06 2014 +0100 @@ -1,106 +1,106 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef LOGGING_H_ -#define LOGGING_H_ - -#include -#include -#include - -#define FLIB_LOGLEVEL_ALL -100 -#define FLIB_LOGLEVEL_DEBUG -1 -#define FLIB_LOGLEVEL_INFO 0 -#define FLIB_LOGLEVEL_WARNING 1 -#define FLIB_LOGLEVEL_ERROR 2 -#define FLIB_LOGLEVEL_NONE 100 - -/** - * Returns a pointer to a static buffer, don't free or store. - */ -char* flib_format_ip(uint32_t numip); - -/** - * Evaluates the expression cond. If it is true, a formatted error will be logged. - * Returns true if an error is logged, false otherwise (i.e. the boolean value of the argument) - * Usage: log_e_if(errorHasHappened, "Format string", formatArg, ...); - */ -#define log_e_if(cond, ...) _flib_fassert(__func__, FLIB_LOGLEVEL_ERROR, !(bool)(cond), __VA_ARGS__) -#define log_w_if(cond, ...) _flib_fassert(__func__, FLIB_LOGLEVEL_WARNING, !(bool)(cond), __VA_ARGS__) - -/** - * Helper macros for log_badargs_if - * The t parameters are the textual representation of the c parameters. They need to be passed - * explicitly, to prevent them from being expanded in prescan. - */ -#define _flib_lbi(c1,t1) log_e_if(c1, "Invalid Argument (%s)", t1) -#define _flib_lbi2(c1,t1,c2,t2) (_flib_lbi(c1,t1) || _flib_lbi(c2,t2)) -#define _flib_lbi3(c1,t1,c2,t2,c3,t3) (_flib_lbi(c1,t1) || _flib_lbi2(c2,t2,c3,t3)) -#define _flib_lbi4(c1,t1,c2,t2,c3,t3,c4,t4) (_flib_lbi(c1,t1) || _flib_lbi3(c2,t2,c3,t3,c4,t4)) -#define _flib_lbi5(c1,t1,c2,t2,c3,t3,c4,t4,c5,t5) (_flib_lbi(c1,t1) || _flib_lbi4(c2,t2,c3,t3,c4,t4,c5,t5)) -#define _flib_lbi6(c1,t1,c2,t2,c3,t3,c4,t4,c5,t5,c6,t6) (_flib_lbi(c1,t1) || _flib_lbi5(c2,t2,c3,t3,c4,t4,c5,t5,c6,t6)) - -/** - * These macros log an "Invalid Argument" error for the first of their arguments that evaluates to true. - * The text of the argument is included in the log message. - * The expression returns true if any of its arguments is true (i.e. if an argument error was logged). - * - * For example, log_badargs_if(x==NULL) will log "Invalid Argument (x==NULL)" and return true if x is NULL. - */ -#define log_badargs_if(c1) _flib_lbi(c1,#c1) -#define log_badargs_if2(c1, c2) _flib_lbi2(c1,#c1,c2,#c2) -#define log_badargs_if3(c1, c2, c3) _flib_lbi3(c1,#c1,c2,#c2,c3,#c3) -#define log_badargs_if4(c1, c2, c3, c4) _flib_lbi4(c1,#c1,c2,#c2,c3,#c3,c4,#c4) -#define log_badargs_if5(c1, c2, c3, c4, c5) _flib_lbi5(c1,#c1,c2,#c2,c3,#c3,c4,#c4,c5,#c5) -#define log_badargs_if6(c1, c2, c3, c4, c5, c6) _flib_lbi6(c1,#c1,c2,#c2,c3,#c3,c4,#c4,c5,#c5,c6,#c6) - -#define log_oom_if(cond) log_e_if(cond, "Out of Memory") - -#define flib_log_e(...) _flib_flog(__func__, FLIB_LOGLEVEL_ERROR, __VA_ARGS__) -#define flib_log_w(...) _flib_flog(__func__, FLIB_LOGLEVEL_WARNING, __VA_ARGS__) -#define flib_log_i(...) _flib_flog(__func__, FLIB_LOGLEVEL_INFO, __VA_ARGS__) -#define flib_log_d(...) _flib_flog(__func__, FLIB_LOGLEVEL_DEBUG, __VA_ARGS__) - -bool _flib_fassert(const char *func, int level, bool cond, const char *fmt, ...); -void _flib_flog(const char *func, int level, const char *fmt, ...); - -/** - * Only log messages that are at least the indicated level - */ -void flib_log_setLevel(int level); -int flib_log_getLevel(); - -/** - * Log to the indicated file. You can pass NULL to log to stdout. - * This overrides setCallback and vice versa. - */ -void flib_log_setFile(FILE *logfile); - -/** - * Returns whether messages of this level are logged at the moment. - */ -bool flib_log_isActive(int level); - -/** - * Allows logging through an arbitrary callback function. Useful for integrating into an - * existing logging system. This overrides setFile and vice versa. - */ -void flib_log_setCallback(void (*logCallback)(int level, const char *msg)); - -#endif /* LOGGING_H_ */ +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef LOGGING_H_ +#define LOGGING_H_ + +#include +#include +#include + +#define FLIB_LOGLEVEL_ALL -100 +#define FLIB_LOGLEVEL_DEBUG -1 +#define FLIB_LOGLEVEL_INFO 0 +#define FLIB_LOGLEVEL_WARNING 1 +#define FLIB_LOGLEVEL_ERROR 2 +#define FLIB_LOGLEVEL_NONE 100 + +/** + * Returns a pointer to a static buffer, don't free or store. + */ +char* flib_format_ip(uint32_t numip); + +/** + * Evaluates the expression cond. If it is true, a formatted error will be logged. + * Returns true if an error is logged, false otherwise (i.e. the boolean value of the argument) + * Usage: log_e_if(errorHasHappened, "Format string", formatArg, ...); + */ +#define log_e_if(cond, ...) _flib_fassert(__func__, FLIB_LOGLEVEL_ERROR, !(bool)(cond), __VA_ARGS__) +#define log_w_if(cond, ...) _flib_fassert(__func__, FLIB_LOGLEVEL_WARNING, !(bool)(cond), __VA_ARGS__) + +/** + * Helper macros for log_badargs_if + * The t parameters are the textual representation of the c parameters. They need to be passed + * explicitly, to prevent them from being expanded in prescan. + */ +#define _flib_lbi(c1,t1) log_e_if(c1, "Invalid Argument (%s)", t1) +#define _flib_lbi2(c1,t1,c2,t2) (_flib_lbi(c1,t1) || _flib_lbi(c2,t2)) +#define _flib_lbi3(c1,t1,c2,t2,c3,t3) (_flib_lbi(c1,t1) || _flib_lbi2(c2,t2,c3,t3)) +#define _flib_lbi4(c1,t1,c2,t2,c3,t3,c4,t4) (_flib_lbi(c1,t1) || _flib_lbi3(c2,t2,c3,t3,c4,t4)) +#define _flib_lbi5(c1,t1,c2,t2,c3,t3,c4,t4,c5,t5) (_flib_lbi(c1,t1) || _flib_lbi4(c2,t2,c3,t3,c4,t4,c5,t5)) +#define _flib_lbi6(c1,t1,c2,t2,c3,t3,c4,t4,c5,t5,c6,t6) (_flib_lbi(c1,t1) || _flib_lbi5(c2,t2,c3,t3,c4,t4,c5,t5,c6,t6)) + +/** + * These macros log an "Invalid Argument" error for the first of their arguments that evaluates to true. + * The text of the argument is included in the log message. + * The expression returns true if any of its arguments is true (i.e. if an argument error was logged). + * + * For example, log_badargs_if(x==NULL) will log "Invalid Argument (x==NULL)" and return true if x is NULL. + */ +#define log_badargs_if(c1) _flib_lbi(c1,#c1) +#define log_badargs_if2(c1, c2) _flib_lbi2(c1,#c1,c2,#c2) +#define log_badargs_if3(c1, c2, c3) _flib_lbi3(c1,#c1,c2,#c2,c3,#c3) +#define log_badargs_if4(c1, c2, c3, c4) _flib_lbi4(c1,#c1,c2,#c2,c3,#c3,c4,#c4) +#define log_badargs_if5(c1, c2, c3, c4, c5) _flib_lbi5(c1,#c1,c2,#c2,c3,#c3,c4,#c4,c5,#c5) +#define log_badargs_if6(c1, c2, c3, c4, c5, c6) _flib_lbi6(c1,#c1,c2,#c2,c3,#c3,c4,#c4,c5,#c5,c6,#c6) + +#define log_oom_if(cond) log_e_if(cond, "Out of Memory") + +#define flib_log_e(...) _flib_flog(__func__, FLIB_LOGLEVEL_ERROR, __VA_ARGS__) +#define flib_log_w(...) _flib_flog(__func__, FLIB_LOGLEVEL_WARNING, __VA_ARGS__) +#define flib_log_i(...) _flib_flog(__func__, FLIB_LOGLEVEL_INFO, __VA_ARGS__) +#define flib_log_d(...) _flib_flog(__func__, FLIB_LOGLEVEL_DEBUG, __VA_ARGS__) + +bool _flib_fassert(const char *func, int level, bool cond, const char *fmt, ...); +void _flib_flog(const char *func, int level, const char *fmt, ...); + +/** + * Only log messages that are at least the indicated level + */ +void flib_log_setLevel(int level); +int flib_log_getLevel(); + +/** + * Log to the indicated file. You can pass NULL to log to stdout. + * This overrides setCallback and vice versa. + */ +void flib_log_setFile(FILE *logfile); + +/** + * Returns whether messages of this level are logged at the moment. + */ +bool flib_log_isActive(int level); + +/** + * Allows logging through an arbitrary callback function. Useful for integrating into an + * existing logging system. This overrides setFile and vice versa. + */ +void flib_log_setCallback(void (*logCallback)(int level, const char *msg)); + +#endif /* LOGGING_H_ */ diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/util/util.c --- a/project_files/frontlib/util/util.c Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/util/util.c Tue Jan 21 22:43:06 2014 +0100 @@ -1,212 +1,212 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "util.h" -#include "logging.h" - -#include -#include -#include -#include -#include -#include -#include - -char *flib_asprintf(const char *fmt, ...) { - va_list argp; - va_start(argp, fmt); - char *result = flib_vasprintf(fmt, argp); - va_end(argp); - return result; -} - -char *flib_vasprintf(const char *fmt, va_list args) { - char *result = NULL; - if(!log_badargs_if(fmt==NULL)) { - int requiredSize = vsnprintf(NULL, 0, fmt, args)+1; // Figure out how much memory we need, - if(!log_e_if(requiredSize<0, "Error formatting string with template \"%s\"", fmt)) { - char *tmpbuf = flib_malloc(requiredSize); // allocate it - if(tmpbuf && vsnprintf(tmpbuf, requiredSize, fmt, args)>=0) { // and then do the actual formatting. - result = tmpbuf; - tmpbuf = NULL; - } - free(tmpbuf); - } - } - return result; -} - -char *flib_join(char **parts, int partCount, const char *delimiter) { - char *result = NULL; - if(!log_badargs_if2(parts==NULL, delimiter==NULL)) { - size_t totalSize = 1; - size_t delimLen = strlen(delimiter); - for(int i=0; i0) { - strcpy(result+outpos, delimiter); - outpos += delimLen; - } - strcpy(result+outpos, parts[i]); - outpos += strlen(parts[i]); - } - } - } - return result; -} - -char *flib_strdupnull(const char *str) { - return str==NULL ? NULL : flib_asprintf("%s", str); -} - -void *flib_bufdupnull(const void *buf, size_t size) { - void *result = NULL; - if(!log_badargs_if(buf==NULL && size>0)) { - result = flib_malloc(size); - if(result) { - memcpy(result, buf, size); - } - } - return result; -} - -void *flib_malloc(size_t size) { - void *result = malloc(size); - if(!result && size>0) { - flib_log_e("Out of memory trying to malloc %zu bytes.", size); - } - return result; -} - -void *flib_calloc(size_t count, size_t elementsize) { - void *result = calloc(count, elementsize); - if(!result && count>0 && elementsize>0) { - flib_log_e("Out of memory trying to calloc %zu objects of %zu bytes each.", count, elementsize); - } - return result; -} - -void *flib_realloc(void *ptr, size_t size) { - void *result = realloc(ptr, size); - if(!result && size>0) { - flib_log_e("Out of memory trying to realloc %zu bytes.", size); - } - return result; -} - -static bool isAsciiAlnum(char c) { - return (c>='0' && c<='9') || (c>='a' && c <='z') || (c>='A' && c <='Z'); -} - -char *flib_urlencode(const char *inbuf) { - return flib_urlencode_pred(inbuf, isAsciiAlnum); -} - -static size_t countCharsToEscape(const char *inbuf, bool (*needsEscaping)(char c)) { - size_t result = 0; - for(const char *c=inbuf; *c; c++) { - if(needsEscaping(*c)) { - result++; - } - } - return result; -} - -char *flib_urlencode_pred(const char *inbuf, bool (*needsEscaping)(char c)) { - char *result = NULL; - if(inbuf && !log_badargs_if(needsEscaping == NULL)) { - size_t insize = strlen(inbuf); - if(!log_e_if(insize > SIZE_MAX/4, "String too long: %zu bytes.", insize)) { - size_t escapeCount = countCharsToEscape(inbuf, needsEscaping); - result = flib_malloc(insize + escapeCount*2 + 1); - } - if(result) { - char *out = result; - for(const char *in = inbuf; *in; in++) { - if(!needsEscaping(*in)) { - *out = *in; - out++; - } else { - snprintf(out, 4, "%%%02x", (unsigned)(*(uint8_t*)in)); - out += 3; - } - } - *out = 0; - } - } - return result; -} - -char *flib_urldecode(const char *inbuf) { - if(!inbuf) { - return NULL; - } - char *outbuf = flib_malloc(strlen(inbuf)+1); - if(!outbuf) { - return NULL; - } - - size_t inpos = 0, outpos = 0; - while(inbuf[inpos]) { - if(inbuf[inpos] == '%' && isxdigit(inbuf[inpos+1]) && isxdigit(inbuf[inpos+2])) { - char temp[3] = {inbuf[inpos+1],inbuf[inpos+2],0}; - outbuf[outpos++] = strtol(temp, NULL, 16); - inpos += 3; - } else { - outbuf[outpos++] = inbuf[inpos++]; - } - } - outbuf[outpos] = 0; - char *shrunk = realloc(outbuf, outpos+1); - return shrunk ? shrunk : outbuf; -} - -bool flib_contains_dir_separator(const char *str) { - if(!log_badargs_if(!str)) { - for(;*str;str++) { - if(*str=='\\' || *str=='/') { - return true; - } - } - } - return false; -} - -bool flib_strempty(const char *str) { - return !str || !*str; -} - -int flib_gets(char *str, size_t strlen) { - if(fgets(str, strlen, stdin)) { - for(char *s=str; *s; s++) { - if(*s=='\r' || *s=='\n') { - *s = 0; - break; - } - } - return 0; - } - return -1; -} +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "util.h" +#include "logging.h" + +#include +#include +#include +#include +#include +#include +#include + +char *flib_asprintf(const char *fmt, ...) { + va_list argp; + va_start(argp, fmt); + char *result = flib_vasprintf(fmt, argp); + va_end(argp); + return result; +} + +char *flib_vasprintf(const char *fmt, va_list args) { + char *result = NULL; + if(!log_badargs_if(fmt==NULL)) { + int requiredSize = vsnprintf(NULL, 0, fmt, args)+1; // Figure out how much memory we need, + if(!log_e_if(requiredSize<0, "Error formatting string with template \"%s\"", fmt)) { + char *tmpbuf = flib_malloc(requiredSize); // allocate it + if(tmpbuf && vsnprintf(tmpbuf, requiredSize, fmt, args)>=0) { // and then do the actual formatting. + result = tmpbuf; + tmpbuf = NULL; + } + free(tmpbuf); + } + } + return result; +} + +char *flib_join(char **parts, int partCount, const char *delimiter) { + char *result = NULL; + if(!log_badargs_if2(parts==NULL, delimiter==NULL)) { + size_t totalSize = 1; + size_t delimLen = strlen(delimiter); + for(int i=0; i0) { + strcpy(result+outpos, delimiter); + outpos += delimLen; + } + strcpy(result+outpos, parts[i]); + outpos += strlen(parts[i]); + } + } + } + return result; +} + +char *flib_strdupnull(const char *str) { + return str==NULL ? NULL : flib_asprintf("%s", str); +} + +void *flib_bufdupnull(const void *buf, size_t size) { + void *result = NULL; + if(!log_badargs_if(buf==NULL && size>0)) { + result = flib_malloc(size); + if(result) { + memcpy(result, buf, size); + } + } + return result; +} + +void *flib_malloc(size_t size) { + void *result = malloc(size); + if(!result && size>0) { + flib_log_e("Out of memory trying to malloc %zu bytes.", size); + } + return result; +} + +void *flib_calloc(size_t count, size_t elementsize) { + void *result = calloc(count, elementsize); + if(!result && count>0 && elementsize>0) { + flib_log_e("Out of memory trying to calloc %zu objects of %zu bytes each.", count, elementsize); + } + return result; +} + +void *flib_realloc(void *ptr, size_t size) { + void *result = realloc(ptr, size); + if(!result && size>0) { + flib_log_e("Out of memory trying to realloc %zu bytes.", size); + } + return result; +} + +static bool isAsciiAlnum(char c) { + return (c>='0' && c<='9') || (c>='a' && c <='z') || (c>='A' && c <='Z'); +} + +char *flib_urlencode(const char *inbuf) { + return flib_urlencode_pred(inbuf, isAsciiAlnum); +} + +static size_t countCharsToEscape(const char *inbuf, bool (*needsEscaping)(char c)) { + size_t result = 0; + for(const char *c=inbuf; *c; c++) { + if(needsEscaping(*c)) { + result++; + } + } + return result; +} + +char *flib_urlencode_pred(const char *inbuf, bool (*needsEscaping)(char c)) { + char *result = NULL; + if(inbuf && !log_badargs_if(needsEscaping == NULL)) { + size_t insize = strlen(inbuf); + if(!log_e_if(insize > SIZE_MAX/4, "String too long: %zu bytes.", insize)) { + size_t escapeCount = countCharsToEscape(inbuf, needsEscaping); + result = flib_malloc(insize + escapeCount*2 + 1); + } + if(result) { + char *out = result; + for(const char *in = inbuf; *in; in++) { + if(!needsEscaping(*in)) { + *out = *in; + out++; + } else { + snprintf(out, 4, "%%%02x", (unsigned)(*(uint8_t*)in)); + out += 3; + } + } + *out = 0; + } + } + return result; +} + +char *flib_urldecode(const char *inbuf) { + if(!inbuf) { + return NULL; + } + char *outbuf = flib_malloc(strlen(inbuf)+1); + if(!outbuf) { + return NULL; + } + + size_t inpos = 0, outpos = 0; + while(inbuf[inpos]) { + if(inbuf[inpos] == '%' && isxdigit(inbuf[inpos+1]) && isxdigit(inbuf[inpos+2])) { + char temp[3] = {inbuf[inpos+1],inbuf[inpos+2],0}; + outbuf[outpos++] = strtol(temp, NULL, 16); + inpos += 3; + } else { + outbuf[outpos++] = inbuf[inpos++]; + } + } + outbuf[outpos] = 0; + char *shrunk = realloc(outbuf, outpos+1); + return shrunk ? shrunk : outbuf; +} + +bool flib_contains_dir_separator(const char *str) { + if(!log_badargs_if(!str)) { + for(;*str;str++) { + if(*str=='\\' || *str=='/') { + return true; + } + } + } + return false; +} + +bool flib_strempty(const char *str) { + return !str || !*str; +} + +int flib_gets(char *str, size_t strlen) { + if(fgets(str, strlen, stdin)) { + for(char *s=str; *s; s++) { + if(*s=='\r' || *s=='\n') { + *s = 0; + break; + } + } + return 0; + } + return -1; +} diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/util/util.h --- a/project_files/frontlib/util/util.h Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/util/util.h Tue Jan 21 22:43:06 2014 +0100 @@ -1,122 +1,122 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef FLIB_UTIL_H_ -#define FLIB_UTIL_H_ - -#include -#include -#include - -/** - * Prints a format string to a newly allocated buffer of the required size. - * Parameters are like those for printf. Returns NULL on error. - * - * Returned buffer must be free()d - */ -char *flib_asprintf(const char *fmt, ...); - -/** - * Exactly as flib_asprintf, but accepts a va_list. - */ -char *flib_vasprintf(const char *fmt, va_list args); - -/** - * Creates a new string (that must be freed) containing all parts - * joined together, with the specified delimiter between each. - */ -char *flib_join(char **parts, int partCount, const char *delimiter); - -/** - * Return a duplicate of the provided string, or NULL if an error - * occurs or if str is already NULL. - * - * Returned buffer must be free()d - */ -char *flib_strdupnull(const char *str); - -/** - * Return a duplicate of the provided buffer, or NULL if an error - * occurs or if buf is already NULL or if size is 0. - * - * Returned buffer must be free()d - */ -void *flib_bufdupnull(const void *buf, size_t size); - -/** - * Simple malloc wrapper that automatically logs an error if no memory - * is available. Otherwise behaves exactly like malloc. - */ -void *flib_malloc(size_t size); - -/** - * Simple calloc wrapper that automatically logs an error if no memory - * is available. Otherwise behaves exactly like calloc. - */ -void *flib_calloc(size_t count, size_t elementsize); - -/** - * Simple realloc wrapper that automatically logs an error if no memory - * is available. Otherwise behaves exactly like realloc. - */ -void *flib_realloc(void *ptr, size_t size); - -/** - * Replace all non-alphanumeric and non-ascii bytes with escape - * sequences in the form %XX. Does not modify the original string, - * but returns a newly allocated one that must be free()d. Returns - * null on failure or if null was passed as argument. - * - * This should work fine with all ASCII-based charsets including UTF-8. - */ -char *flib_urlencode(const char *str); - -/** - * Replace some bytes with escape sequences in the form %XX. - * Does not modify the original string, but returns a newly allocated - * one that must be free()d. - * - * All bytes for which the predicate function returns true are escaped. - * - * Returns null on failure or if null was passed as argument. - */ -char *flib_urlencode_pred(const char *str, bool (*needsEscaping)(char c)); - -/** - * Replace escape sequences of the form %XX with their byte values. - * Does not modify the original string, but returns a newly allocated - * one that must be free()d. Returns null on failure or if null was - * passed as argument. - */ -char *flib_urldecode(const char *str); - -/** - * Figure out if the string contains / or \. Useful in routines that - * construct filenames. - */ -bool flib_contains_dir_separator(const char *str); - -/** - * Returns true if str is either NULL or points to a 0-length string - */ -bool flib_strempty(const char *str); - -int flib_gets(char *str, size_t strlen); - -#endif +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef FLIB_UTIL_H_ +#define FLIB_UTIL_H_ + +#include +#include +#include + +/** + * Prints a format string to a newly allocated buffer of the required size. + * Parameters are like those for printf. Returns NULL on error. + * + * Returned buffer must be free()d + */ +char *flib_asprintf(const char *fmt, ...); + +/** + * Exactly as flib_asprintf, but accepts a va_list. + */ +char *flib_vasprintf(const char *fmt, va_list args); + +/** + * Creates a new string (that must be freed) containing all parts + * joined together, with the specified delimiter between each. + */ +char *flib_join(char **parts, int partCount, const char *delimiter); + +/** + * Return a duplicate of the provided string, or NULL if an error + * occurs or if str is already NULL. + * + * Returned buffer must be free()d + */ +char *flib_strdupnull(const char *str); + +/** + * Return a duplicate of the provided buffer, or NULL if an error + * occurs or if buf is already NULL or if size is 0. + * + * Returned buffer must be free()d + */ +void *flib_bufdupnull(const void *buf, size_t size); + +/** + * Simple malloc wrapper that automatically logs an error if no memory + * is available. Otherwise behaves exactly like malloc. + */ +void *flib_malloc(size_t size); + +/** + * Simple calloc wrapper that automatically logs an error if no memory + * is available. Otherwise behaves exactly like calloc. + */ +void *flib_calloc(size_t count, size_t elementsize); + +/** + * Simple realloc wrapper that automatically logs an error if no memory + * is available. Otherwise behaves exactly like realloc. + */ +void *flib_realloc(void *ptr, size_t size); + +/** + * Replace all non-alphanumeric and non-ascii bytes with escape + * sequences in the form %XX. Does not modify the original string, + * but returns a newly allocated one that must be free()d. Returns + * null on failure or if null was passed as argument. + * + * This should work fine with all ASCII-based charsets including UTF-8. + */ +char *flib_urlencode(const char *str); + +/** + * Replace some bytes with escape sequences in the form %XX. + * Does not modify the original string, but returns a newly allocated + * one that must be free()d. + * + * All bytes for which the predicate function returns true are escaped. + * + * Returns null on failure or if null was passed as argument. + */ +char *flib_urlencode_pred(const char *str, bool (*needsEscaping)(char c)); + +/** + * Replace escape sequences of the form %XX with their byte values. + * Does not modify the original string, but returns a newly allocated + * one that must be free()d. Returns null on failure or if null was + * passed as argument. + */ +char *flib_urldecode(const char *str); + +/** + * Figure out if the string contains / or \. Useful in routines that + * construct filenames. + */ +bool flib_contains_dir_separator(const char *str); + +/** + * Returns true if str is either NULL or points to a 0-length string + */ +bool flib_strempty(const char *str); + +int flib_gets(char *str, size_t strlen); + +#endif diff -r 4feced261c68 -r de822cd3df3a share/hedgewars/Data/Locale/fr.txt --- a/share/hedgewars/Data/Locale/fr.txt Tue Jan 21 22:38:13 2014 +0100 +++ b/share/hedgewars/Data/Locale/fr.txt Tue Jan 21 22:43:06 2014 +0100 @@ -136,7 +136,7 @@ 02:01=%1 fait splish splash splosh ! 02:01=%1 va dormir avec les poissons ! 02:01=%1 pense que la physique de l'eau est nulle dans ce jeu ! -02:01=%1 a l'air assoiffé ! +02:01=%1 a l'air assoiffé ! 02:01=La mer réclame %1 ! 02:01=Un hérisson à la mer ! 02:01=%1 aurait dû prendre son masque et son tuba ! @@ -256,7 +256,7 @@ 02:06=Prends-la ou explose-la, le choix est tien ! 02:06=Mmmmh, Munitions ! 02:06=Une boîte de pouvoir destructif ! -02:06=Courrier aérien ! +02:06=Courrier aérien ! 02:06=Quelque soit ce qu'il y a dans cette boîte, ce n'est pas une pizza ! 02:06=Prends-la ! 02:06=Lâcher d'armes en approche ! @@ -270,7 +270,7 @@ ; New utility crate 02:07=Boite à outils ! 02:07=Ça peut être pratique... -02:07=Utilisez cette boîte ! +02:07=Utilisez cette boîte ! 02:07=Regardez en-dessous ! 02:07=Des outils pour toi ! 02:07=Ça devrait être bien ! diff -r 4feced261c68 -r de822cd3df3a share/hedgewars/Data/Locale/missions_el.txt --- a/share/hedgewars/Data/Locale/missions_el.txt Tue Jan 21 22:38:13 2014 +0100 +++ b/share/hedgewars/Data/Locale/missions_el.txt Tue Jan 21 22:43:06 2014 +0100 @@ -1,7 +1,7 @@ Basic_Training_-_Bazooka.name=Βασική Εκπαίδευση Μπαζούκα Basic_Training_-_Bazooka.desc="Το κλειδί είναι να χρησιμοποιήσεις τον άνεμο προς όφελός σου!" -Basic_Training_-_Grenade.name=Βασική Εκπαίδευση Χειροβομβίδας +Basic_Training_-_Grenade.name=Βασική Εκπαίδευση Χειροβομβίδας Basic_Training_-_Grenade.desc="Θυμίσου, τραβάς την περόνη ΚΑΙ πετάς!" Basic_Training_-_Cluster_Bomb.name=Βασική Εκπαίδευση Βόμβας Θραυσμάτων diff -r 4feced261c68 -r de822cd3df3a share/hedgewars/Data/Locale/tips_en.xml --- a/share/hedgewars/Data/Locale/tips_en.xml Tue Jan 21 22:38:13 2014 +0100 +++ b/share/hedgewars/Data/Locale/tips_en.xml Tue Jan 21 22:43:06 2014 +0100 @@ -49,7 +49,7 @@ Heads or tails? Type '/rnd' in lobby and you'll find out. Also '/rnd rock paper scissors' works! You're able to associate Hedgewars related files (savegames and demo recordings) with the game to launch them right from your favorite file or internet browser. - The version of Hedgewars supports Xfire. Make sure to add Hedgewars to its game list so your friends can see you playing. + The version of Hedgewars supports Xfire. Make sure to add Hedgewars to its game list so your friends can see you playing. You can find your Hedgewars configuration files under "My Documents\Hedgewars". Create backups or take the files with you, but don't edit them by hand. diff -r 4feced261c68 -r de822cd3df3a share/hedgewars/Data/Maps/Basketball/desc.txt --- a/share/hedgewars/Data/Maps/Basketball/desc.txt Tue Jan 21 22:38:13 2014 +0100 +++ b/share/hedgewars/Data/Maps/Basketball/desc.txt Tue Jan 21 22:43:06 2014 +0100 @@ -1,1 +1,1 @@ -en_US=Who said hedgehogs can't play basketball? +en_US=Who said hedgehogs can't play basketball? diff -r 4feced261c68 -r de822cd3df3a share/hedgewars/Data/Maps/CTF_Blizzard/desc.txt --- a/share/hedgewars/Data/Maps/CTF_Blizzard/desc.txt Tue Jan 21 22:38:13 2014 +0100 +++ b/share/hedgewars/Data/Maps/CTF_Blizzard/desc.txt Tue Jan 21 22:43:06 2014 +0100 @@ -1,1 +1,1 @@ -en_US=Capture the Flag\, blizzard style! +en_US=Capture the Flag\, blizzard style! diff -r 4feced261c68 -r de822cd3df3a share/hedgewars/Data/Maps/Control/desc.txt --- a/share/hedgewars/Data/Maps/Control/desc.txt Tue Jan 21 22:38:13 2014 +0100 +++ b/share/hedgewars/Data/Maps/Control/desc.txt Tue Jan 21 22:43:06 2014 +0100 @@ -1,1 +1,1 @@ -en_US=Islands scattered everywhere\, full set of weapons. +en_US=Islands scattered everywhere\, full set of weapons. diff -r 4feced261c68 -r de822cd3df3a share/hedgewars/Data/Maps/Knockball/desc.txt --- a/share/hedgewars/Data/Maps/Knockball/desc.txt Tue Jan 21 22:38:13 2014 +0100 +++ b/share/hedgewars/Data/Maps/Knockball/desc.txt Tue Jan 21 22:43:06 2014 +0100 @@ -1,1 +1,1 @@ -en_US=Knock your opponents off the platforms using only a bat! +en_US=Knock your opponents off the platforms using only a bat! diff -r 4feced261c68 -r de822cd3df3a share/hedgewars/Data/Missions/Training/User_Mission_-_Nobody_Laugh.lua --- a/share/hedgewars/Data/Missions/Training/User_Mission_-_Nobody_Laugh.lua Tue Jan 21 22:38:13 2014 +0100 +++ b/share/hedgewars/Data/Missions/Training/User_Mission_-_Nobody_Laugh.lua Tue Jan 21 22:43:06 2014 +0100 @@ -1,130 +1,130 @@ --------------------------------------- --- NOBODY LAUGH --- a hilarious (not really) adventure --------------------------------------- - -HedgewarsScriptLoad("/Scripts/Locale.lua") -HedgewarsScriptLoad("/Scripts/Tracker.lua") - -local hhs = {} - -function onGameInit() - - Seed = 0 - GameFlags = gfInfAttack + gfPerHogAmmo +gfDisableWind - SuddenDeathTurns = 9999 - TurnTime = 180000 - CaseFreq = 0 - MinesNum = 0 - Explosives = 0 - Map = "Bath" - Theme = "Nature" - - AddTeam(loc("Nameless Heroes"), 14483456, "eyecross", "Wood", "HillBilly", "cm_birdy") - hhs[1] = AddHog(loc( "Hunter" ), 0, 1, "Skull") - SetGearPosition(hhs[1], 1267, 451) - hhs[2] = AddHog(loc("Drowner"), 0, 31, "mp3") - SetGearPosition(hhs[2], 1332, 451) - - AddTeam(loc("Clowns"), 1175851, "Duck2", "Tank", "Mobster", "cm_spider") - hhs[3] = AddHog("Poison", 5, 100, "WhySoSerious") - SetGearPosition(hhs[3], 1133, 446) - hhs[4] = AddHog("Bobo", 5, 100, "clown") - SetGearPosition(hhs[4], 1215, 553) - hhs[5] = AddHog("Copper", 5, 10, "clown-copper") - SetGearPosition(hhs[5], 414, 376) - hhs[6] = AddHog("Derp", 5, 100, "clown-crossed") - SetGearPosition(hhs[6], 1590, 886) - hhs[7] = AddHog("Eckles", 5, 100, "clown-copper") - SetGearPosition(hhs[7], 772, 754) - hhs[8] = AddHog("Frank", 5, 50, "clown-copper") - SetGearPosition(hhs[8], 1688, 714) - hhs[9] = AddHog("Harry", 5, 50, "clown-copper") - SetGearPosition(hhs[9], 1932, 837) - hhs[10] = AddHog("Igmund", 5, 50, "WhySoSerious") - SetGearPosition(hhs[10], 1601, 733) - -end - -function onGameStart() - - AddAmmo(enemy, amAirAttack, 100) - - ShowMission( loc("Nobody Laugh"), - loc("User Challenge"), - loc("Eliminate the enemy before the time runs out") - , 0, 0 - ) - - -- GIRDERS - PlaceGirder(1212, 710, 7) - PlaceGirder(1215, 570, 4) - PlaceGirder(1288, 520, 2) - PlaceGirder(1184, 468, 4) - PlaceGirder(1344, 468, 4) - PlaceGirder(1247, 346, 4) - - PlaceGirder(667, 438, 4) - PlaceGirder(507, 438, 4) - PlaceGirder(434, 487, 2) - PlaceGirder(505, 537, 4) - PlaceGirder(665, 537, 4) - PlaceGirder(737, 487, 2) - - PlaceGirder(416, 465, 6) - PlaceGirder(1415, 378, 6) - PlaceGirder(1300, 625, 3) - PlaceGirder(1359, 566, 3) - PlaceGirder(1436, 538, 0) - PlaceGirder(1505, 468, 4) - - ------ AMMO CRATE LIST ------ - tempG = SpawnAmmoCrate(1242, 315, amBaseballBat) - tempG = SpawnAmmoCrate(1309, 315, amAirAttack) - tempG = SpawnAmmoCrate(144, 895, amAirAttack) - tempG = SpawnAmmoCrate(664, 699, amIceGun) - tempG = SpawnAmmoCrate(1572, 444, amFirePunch) - tempG = SpawnAmmoCrate(1574, 382, amDynamite) - - ------ UTIL CRATE LIST ------ - tempG = SpawnUtilityCrate(654, 513, amParachute) - tempG = SpawnUtilityCrate(1569, 413, amParachute) - - -- HOG AMMO - AddAmmo(hhs[1],amParachute,1) - AddAmmo(hhs[1],amHammer,1) - AddAmmo(hhs[2],amWhip,1) - - for i = 3, 10 do - AddAmmo(hhs[i], amDeagle, 100) - AddAmmo(hhs[i], amShotgun, 100) - AddAmmo(hhs[i], amGrenade, 100) - AddAmmo(hhs[i], amBazooka, 100) - AddAmmo(hhs[i], amDrill, 100) - end - -end - -function onNewTurn() - SetWind(100) -end - -function onAmmoStoreInit() - - SetAmmo(amBaseballBat, 0, 0, 0, 1) - SetAmmo(amAirAttack, 0, 0, 0, 1) - SetAmmo(amFirePunch, 0, 0, 0, 1) - SetAmmo(amDynamite, 0, 0, 0, 1) - SetAmmo(amHammer, 0, 0, 0, 1) - SetAmmo(amIceGun, 0, 0, 0, 1) - - SetAmmo(amParachute, 0, 0, 0, 1) - - SetAmmo(amSwitch, 9, 0, 0, 0) - SetAmmo(amSkip, 9, 0, 0, 0) - -end - ------------------------------- --- I'm in whitesppaaaaaaaaaacceeeee :D ------------------------------- +-------------------------------------- +-- NOBODY LAUGH +-- a hilarious (not really) adventure +-------------------------------------- + +HedgewarsScriptLoad("/Scripts/Locale.lua") +HedgewarsScriptLoad("/Scripts/Tracker.lua") + +local hhs = {} + +function onGameInit() + + Seed = 0 + GameFlags = gfInfAttack + gfPerHogAmmo +gfDisableWind + SuddenDeathTurns = 9999 + TurnTime = 180000 + CaseFreq = 0 + MinesNum = 0 + Explosives = 0 + Map = "Bath" + Theme = "Nature" + + AddTeam(loc("Nameless Heroes"), 14483456, "eyecross", "Wood", "HillBilly", "cm_birdy") + hhs[1] = AddHog(loc( "Hunter" ), 0, 1, "Skull") + SetGearPosition(hhs[1], 1267, 451) + hhs[2] = AddHog(loc("Drowner"), 0, 31, "mp3") + SetGearPosition(hhs[2], 1332, 451) + + AddTeam(loc("Clowns"), 1175851, "Duck2", "Tank", "Mobster", "cm_spider") + hhs[3] = AddHog("Poison", 5, 100, "WhySoSerious") + SetGearPosition(hhs[3], 1133, 446) + hhs[4] = AddHog("Bobo", 5, 100, "clown") + SetGearPosition(hhs[4], 1215, 553) + hhs[5] = AddHog("Copper", 5, 10, "clown-copper") + SetGearPosition(hhs[5], 414, 376) + hhs[6] = AddHog("Derp", 5, 100, "clown-crossed") + SetGearPosition(hhs[6], 1590, 886) + hhs[7] = AddHog("Eckles", 5, 100, "clown-copper") + SetGearPosition(hhs[7], 772, 754) + hhs[8] = AddHog("Frank", 5, 50, "clown-copper") + SetGearPosition(hhs[8], 1688, 714) + hhs[9] = AddHog("Harry", 5, 50, "clown-copper") + SetGearPosition(hhs[9], 1932, 837) + hhs[10] = AddHog("Igmund", 5, 50, "WhySoSerious") + SetGearPosition(hhs[10], 1601, 733) + +end + +function onGameStart() + + AddAmmo(enemy, amAirAttack, 100) + + ShowMission( loc("Nobody Laugh"), + loc("User Challenge"), + loc("Eliminate the enemy before the time runs out") + , 0, 0 + ) + + -- GIRDERS + PlaceGirder(1212, 710, 7) + PlaceGirder(1215, 570, 4) + PlaceGirder(1288, 520, 2) + PlaceGirder(1184, 468, 4) + PlaceGirder(1344, 468, 4) + PlaceGirder(1247, 346, 4) + + PlaceGirder(667, 438, 4) + PlaceGirder(507, 438, 4) + PlaceGirder(434, 487, 2) + PlaceGirder(505, 537, 4) + PlaceGirder(665, 537, 4) + PlaceGirder(737, 487, 2) + + PlaceGirder(416, 465, 6) + PlaceGirder(1415, 378, 6) + PlaceGirder(1300, 625, 3) + PlaceGirder(1359, 566, 3) + PlaceGirder(1436, 538, 0) + PlaceGirder(1505, 468, 4) + + ------ AMMO CRATE LIST ------ + tempG = SpawnAmmoCrate(1242, 315, amBaseballBat) + tempG = SpawnAmmoCrate(1309, 315, amAirAttack) + tempG = SpawnAmmoCrate(144, 895, amAirAttack) + tempG = SpawnAmmoCrate(664, 699, amIceGun) + tempG = SpawnAmmoCrate(1572, 444, amFirePunch) + tempG = SpawnAmmoCrate(1574, 382, amDynamite) + + ------ UTIL CRATE LIST ------ + tempG = SpawnUtilityCrate(654, 513, amParachute) + tempG = SpawnUtilityCrate(1569, 413, amParachute) + + -- HOG AMMO + AddAmmo(hhs[1],amParachute,1) + AddAmmo(hhs[1],amHammer,1) + AddAmmo(hhs[2],amWhip,1) + + for i = 3, 10 do + AddAmmo(hhs[i], amDeagle, 100) + AddAmmo(hhs[i], amShotgun, 100) + AddAmmo(hhs[i], amGrenade, 100) + AddAmmo(hhs[i], amBazooka, 100) + AddAmmo(hhs[i], amDrill, 100) + end + +end + +function onNewTurn() + SetWind(100) +end + +function onAmmoStoreInit() + + SetAmmo(amBaseballBat, 0, 0, 0, 1) + SetAmmo(amAirAttack, 0, 0, 0, 1) + SetAmmo(amFirePunch, 0, 0, 0, 1) + SetAmmo(amDynamite, 0, 0, 0, 1) + SetAmmo(amHammer, 0, 0, 0, 1) + SetAmmo(amIceGun, 0, 0, 0, 1) + + SetAmmo(amParachute, 0, 0, 0, 1) + + SetAmmo(amSwitch, 9, 0, 0, 0) + SetAmmo(amSkip, 9, 0, 0, 0) + +end + +------------------------------ +-- I'm in whitesppaaaaaaaaaacceeeee :D +------------------------------ diff -r 4feced261c68 -r de822cd3df3a share/hedgewars/Data/Scripts/Multiplayer/Frenzy.lua --- a/share/hedgewars/Data/Scripts/Multiplayer/Frenzy.lua Tue Jan 21 22:38:13 2014 +0100 +++ b/share/hedgewars/Data/Scripts/Multiplayer/Frenzy.lua Tue Jan 21 22:43:06 2014 +0100 @@ -1,142 +1,142 @@ -------------------------------------------- --- FRENZY --- a hedgewars mode inspired by Hysteria -------------------------------------------- - -HedgewarsScriptLoad("/Scripts/Locale.lua") -HedgewarsScriptLoad("/Scripts/Tracker.lua") - -local cTimer = 0 -local cn = 0 - -function initialSetup(gear) - SetHealth(gear, 75) -- official is 80, but that assumes bazookas/grenades that do 50 damage -end - -function showStartingInfo() - - ruleSet = "" .. - loc("RULES") .. ": " .. "|" .. - loc("Each turn is only ONE SECOND!") .. "|" .. - loc("Use your ready time to think.") .. "|" .. - loc("Slot keys save time! (F1-F10 by default)") .. "|" .. - " |" .. - loc("SLOTS") .. ": " .. "|" .. - loc("Slot") .. " 1 - " .. loc("Bazooka") .. "|" .. - loc("Slot") .. " 2 - " .. loc("Grenade") .. "|" .. - loc("Slot") .. " 3 - " .. loc("Shotgun") .. "|" .. - loc("Slot") .. " 4 - " .. loc("Shoryuken") .. "|" .. - loc("Slot") .. " 5 - " .. loc("Mine") .. "|" .. - loc("Slot") .. " 6 - " .. loc("Teleport") .. "|" .. - loc("Slot") .. " 7 - " .. loc("Blowtorch") .. "|" .. - loc("Slot") .. " 8 - " .. loc("Flying Saucer") .. "|" .. - loc("Slot") .. " 9 - " .. loc("Molotov") .. "|" .. - loc("Slot") .. " 10 - " .. loc("Low Gravity") - - ShowMission(loc("FRENZY"), - loc("a frenetic Hedgewars mini-game"), - ruleSet, 0, 4000) - -end - -function onGameInit() - - if TurnTime > 10001 then - Ready = 8000 - else - Ready = TurnTime - end - - TurnTime = 1000 - - --These are the official settings, but I think I prefer allowing customization in this regard - --MinesNum = 8 - --MinesTime = 3000 - --MinesDudPercent = 30 - --Explosives = 0 - - --Supposedly official settings - HealthCaseProb = 0 - CrateFreq = 0 - - --Approximation of Official Settings - --SuddenDeathTurns = 10 - --WaterRise = 47 - --HealthDecrease = 0 - -end - -function onGameStart() - showStartingInfo() - runOnHogs(initialSetup) -end - -function onSlot(sln) - cTimer = 8 - cn = sln -end - -function onGameTick() - if cTimer ~= 0 then - cTimer = cTimer -1 - if cTimer == 1 then - ChangeWep(cn) - cn = 0 - cTimer = 0 - end - end -end - -function ChangeWep(s) - - if s == 0 then - ParseCommand("setweap " .. string.char(amBazooka)) - elseif s == 1 then - ParseCommand("setweap " .. string.char(amGrenade)) - elseif s == 2 then - ParseCommand("setweap " .. string.char(amShotgun)) - elseif s == 3 then - ParseCommand("setweap " .. string.char(amFirePunch)) - elseif s == 4 then - ParseCommand("setweap " .. string.char(amMine)) - elseif s == 5 then - ParseCommand("setweap " .. string.char(amTeleport)) - elseif s == 6 then - ParseCommand("setweap " .. string.char(amBlowTorch)) - elseif s == 7 then - ParseCommand("setweap " .. string.char(amJetpack)) - elseif s == 8 then - ParseCommand("setweap " .. string.char(amMolotov)) - elseif s == 9 then - ParseCommand("setweap " .. string.char(amLowGravity)) - end - -end - -function onGearAdd(gear) - if GetGearType(gear) == gtHedgehog then - trackGear(gear) - end -end - -function onGearDelete(gear) - if GetGearType(gear) == gtHedgehog then - trackDeletion(gear) - end -end - -function onAmmoStoreInit() - SetAmmo(amBazooka, 9, 0, 0, 0) - SetAmmo(amGrenade, 9, 0, 0, 0) - SetAmmo(amMolotov, 9, 0, 0, 0) - SetAmmo(amShotgun, 9, 0, 0, 0) - --SetAmmo(amFlamethrower, 9, 0, 0, 0) -- this was suggested on hw.org but it's not present on base - SetAmmo(amFirePunch, 9, 0, 0, 0) - SetAmmo(amMine, 9, 0, 0, 0) - --SetAmmo(amCake, 1, 0, 2, 0) -- maybe it's beefcake? - SetAmmo(amJetpack, 9, 0, 0, 0) - SetAmmo(amBlowTorch, 9, 0, 0, 0) - SetAmmo(amTeleport, 9, 0, 0, 0) - SetAmmo(amLowGravity, 9, 0, 0, 0) - --SetAmmo(amSkipGo, 9, 0, 0, 0) -- not needed with 1s turn time -end +------------------------------------------- +-- FRENZY +-- a hedgewars mode inspired by Hysteria +------------------------------------------- + +HedgewarsScriptLoad("/Scripts/Locale.lua") +HedgewarsScriptLoad("/Scripts/Tracker.lua") + +local cTimer = 0 +local cn = 0 + +function initialSetup(gear) + SetHealth(gear, 75) -- official is 80, but that assumes bazookas/grenades that do 50 damage +end + +function showStartingInfo() + + ruleSet = "" .. + loc("RULES") .. ": " .. "|" .. + loc("Each turn is only ONE SECOND!") .. "|" .. + loc("Use your ready time to think.") .. "|" .. + loc("Slot keys save time! (F1-F10 by default)") .. "|" .. + " |" .. + loc("SLOTS") .. ": " .. "|" .. + loc("Slot") .. " 1 - " .. loc("Bazooka") .. "|" .. + loc("Slot") .. " 2 - " .. loc("Grenade") .. "|" .. + loc("Slot") .. " 3 - " .. loc("Shotgun") .. "|" .. + loc("Slot") .. " 4 - " .. loc("Shoryuken") .. "|" .. + loc("Slot") .. " 5 - " .. loc("Mine") .. "|" .. + loc("Slot") .. " 6 - " .. loc("Teleport") .. "|" .. + loc("Slot") .. " 7 - " .. loc("Blowtorch") .. "|" .. + loc("Slot") .. " 8 - " .. loc("Flying Saucer") .. "|" .. + loc("Slot") .. " 9 - " .. loc("Molotov") .. "|" .. + loc("Slot") .. " 10 - " .. loc("Low Gravity") + + ShowMission(loc("FRENZY"), + loc("a frenetic Hedgewars mini-game"), + ruleSet, 0, 4000) + +end + +function onGameInit() + + if TurnTime > 10001 then + Ready = 8000 + else + Ready = TurnTime + end + + TurnTime = 1000 + + --These are the official settings, but I think I prefer allowing customization in this regard + --MinesNum = 8 + --MinesTime = 3000 + --MinesDudPercent = 30 + --Explosives = 0 + + --Supposedly official settings + HealthCaseProb = 0 + CrateFreq = 0 + + --Approximation of Official Settings + --SuddenDeathTurns = 10 + --WaterRise = 47 + --HealthDecrease = 0 + +end + +function onGameStart() + showStartingInfo() + runOnHogs(initialSetup) +end + +function onSlot(sln) + cTimer = 8 + cn = sln +end + +function onGameTick() + if cTimer ~= 0 then + cTimer = cTimer -1 + if cTimer == 1 then + ChangeWep(cn) + cn = 0 + cTimer = 0 + end + end +end + +function ChangeWep(s) + + if s == 0 then + ParseCommand("setweap " .. string.char(amBazooka)) + elseif s == 1 then + ParseCommand("setweap " .. string.char(amGrenade)) + elseif s == 2 then + ParseCommand("setweap " .. string.char(amShotgun)) + elseif s == 3 then + ParseCommand("setweap " .. string.char(amFirePunch)) + elseif s == 4 then + ParseCommand("setweap " .. string.char(amMine)) + elseif s == 5 then + ParseCommand("setweap " .. string.char(amTeleport)) + elseif s == 6 then + ParseCommand("setweap " .. string.char(amBlowTorch)) + elseif s == 7 then + ParseCommand("setweap " .. string.char(amJetpack)) + elseif s == 8 then + ParseCommand("setweap " .. string.char(amMolotov)) + elseif s == 9 then + ParseCommand("setweap " .. string.char(amLowGravity)) + end + +end + +function onGearAdd(gear) + if GetGearType(gear) == gtHedgehog then + trackGear(gear) + end +end + +function onGearDelete(gear) + if GetGearType(gear) == gtHedgehog then + trackDeletion(gear) + end +end + +function onAmmoStoreInit() + SetAmmo(amBazooka, 9, 0, 0, 0) + SetAmmo(amGrenade, 9, 0, 0, 0) + SetAmmo(amMolotov, 9, 0, 0, 0) + SetAmmo(amShotgun, 9, 0, 0, 0) + --SetAmmo(amFlamethrower, 9, 0, 0, 0) -- this was suggested on hw.org but it's not present on base + SetAmmo(amFirePunch, 9, 0, 0, 0) + SetAmmo(amMine, 9, 0, 0, 0) + --SetAmmo(amCake, 1, 0, 2, 0) -- maybe it's beefcake? + SetAmmo(amJetpack, 9, 0, 0, 0) + SetAmmo(amBlowTorch, 9, 0, 0, 0) + SetAmmo(amTeleport, 9, 0, 0, 0) + SetAmmo(amLowGravity, 9, 0, 0, 0) + --SetAmmo(amSkipGo, 9, 0, 0, 0) -- not needed with 1s turn time +end diff -r 4feced261c68 -r de822cd3df3a share/hedgewars/Data/Scripts/Multiplayer/Mutant.lua --- a/share/hedgewars/Data/Scripts/Multiplayer/Mutant.lua Tue Jan 21 22:38:13 2014 +0100 +++ b/share/hedgewars/Data/Scripts/Multiplayer/Mutant.lua Tue Jan 21 22:43:06 2014 +0100 @@ -1,615 +1,615 @@ -local MUTANT_VERSION = "v0.9.5" - ---[[ ___ ___ - ( ) ( ) -___ .-. .-. ___ ___ | |_ .---. ___ .-. | |_ -( ) ' ( )( ( __) / .-, ( ) ( __) -| .-. .-. | | | | | | (__) ; || .-. .| | -| | | | | | | | | | | ___ .'` || | | || | ___ -| | | | | | | | | | |( / .'| || | | || |( ) -| | | | | | | | | | | | | / | || | | || | | | -| | | | | | | ; ' | ' | ; | ; || | | || ' | | -| | | | | ' `-' / ' `-' ' `-' || | | |' `-' ; -(___)(___)(___'.__.' `.__.`.__.'_(___)(___)`.__. - - ----- Recommended settings: ----- * one hedgehog per team ----- * 'Small' one-island map - ---]] - -HedgewarsScriptLoad("/Scripts/Locale.lua") -HedgewarsScriptLoad("/Scripts/Tracker.lua") - ---[[ - MUTANT SCRIPT - - To Do: -Clean-up this fucking piece of code - -Debug - -Find a girlfriend - -Fix Sheepluva's hat +[p] - -Cookies ------------------------]] - -local hhs = {} -local numhhs = 0 -local meh = false - -local gameOver=false - -local mutant = nil -local mutant_base_health = 200 -local mutant_base_disease = 25 -local disease_timer = 2000 - -local kill_reward = nil -local mt_hurt=false - -local killsCounter = 0 - -local team_fire_punishment = 3 -local mutant_kill_reward = 2 - -local hh_weapons = { amBazooka, amGrenade, amShotgun, amMine} - -local mt_weapons = {amWatermelon, amHellishBomb, amBallgun, amRCPlane, amTeleport} - -local disease=0 -local timer=0 - -local winScore = 15 -local hogsLimit = 1 - -local teams = {} - -local circles = {} -local circleFrame = -1 - -function showStartingInfo() - - ruleSet = loc("RULES") .. ": " .. - " |" .. --" |" .. - loc("The first player to kill someone becomes the Mutant.") .. "|" .. - loc("The Mutant has super-weapons and a lot of health.") .. "|" .. - loc("The Mutant loses health quickly if he doesn't keep scoring kills.") .. "|" .. - " |" .. - loc("Normal players can only score points by killing the mutant.") .. "|" .. - " |" .. "" .. - loc("The player with least points (or most deaths) becomes the Bottom Feeder.") .. "|" .. - loc("The Bottom Feeder can score points by killing anyone.") .. "|" .. - " |" .. - loc("POINTS") .. ": " .. - " |" .. - loc("+2 for becoming a Mutant") .. "|" .. - loc("+1 to a Mutant for killing anyone") .. "|" .. - loc("+1 to a Bottom Feeder for killing anyone") .. "|" .. - loc("-1 to anyone for a suicide") .. "|" .. - loc("Other kills don't give you points.") - - ShowMission(loc("Mutant"), - loc("a Hedgewars tag game"), - ruleSet, 0, 5000) - -end - -function onGameInit() - TurnTime = 20000 - WaterRise = 0 - GameFlags = GameFlags + gfResetWeps + gfPerHogAmmo - HealthCaseProb=0 - HealthCaseAmount=0 - MinesTime=1000 - CaseFreq = 2 -end - - -function limitHogs(gear) - cnthhs = cnthhs + 1 - if cnthhs > 1 then - hogLimitHit = true - SetEffect(gear, heResurrectable, false) - --SetHealth(gear, 0) - SetGearPosition(gear, -100,LAND_HEIGHT) - end -end - -function onGameStart() - trackTeams() - teamScan() - runOnHogs(saveStuff) - --local str = "/say " .. MUTANT_VERSION - --ParseCommand(str) - - hogLimitHit = false - for i=0 , TeamsCount - 1 do - cnthhs = 0 - runOnHogsInTeam(limitHogs, teams[i]) - end - if hogLimitHit then - AddCaption(loc("ONE HOG PER TEAM! KILLING EXCESS HEDGES")) - end - showStartingInfo() -end - - - -function giveWeapons(gear) - if gear == mutant then - AddAmmo(gear, amRope) - for i=1, #mt_weapons do - AddAmmo(gear, mt_weapons[i]) - end - - else - for i=1, #hh_weapons do - AddAmmo(gear,hh_weapons[i]) - end - end -end - -function onAmmoStoreInit() - - SetAmmo(amSkip, 9, 0, 0, 0) - SetAmmo(amRope,0,1,0,5) - SetAmmo(amSnowball,0,1,0,1) - - for i=1, #hh_weapons do - SetAmmo(hh_weapons[i], 0, 0, 0, 1) - end - - for i=1, #mt_weapons do - SetAmmo(mt_weapons[i], 0, 3, 0, 1) - end - -end - -function drawCircles() - for i = 0, #hhs do - if circles[hhs[i]] ~= nil then - DeleteVisualGear(circles[hhs[i]]) - circles[hhs[i]] = nil - end - - if hhs[i] ~= CurrentHedgehog then - if mutant == nil then - circles[hhs[i]] = AddVisualGear(0, 0, vgtCircle, 0, false) - SetVisualGearValues(circles[hhs[i]], 0, 0, 0, 0, 0, 0, 0, 22, 5, 0xff000080) - elseif CurrentHedgehog == mutant then - circles[hhs[i]] = AddVisualGear(0, 0, vgtCircle, 0, false) - SetVisualGearValues(circles[hhs[i]], 0, 0, 0, 0, 0, 0, 0, 22, 3, 0xaa000070) - elseif getGearValue(CurrentHedgehog, "Feeder") and hhs[i] ~= mutant then - circles[hhs[i]] = AddVisualGear(0, 0, vgtCircle, 0, false) - SetVisualGearValues(circles[hhs[i]], 0, 0, 0, 0, 0, 0, 0, 22, 3, 0xaa000070) - elseif hhs[i] == mutant then - circles[hhs[i]] = AddVisualGear(0, 0, vgtCircle, 0, false) - SetVisualGearValues(circles[hhs[i]], 0, 0, 0, 0, 0, 0, 0, 22, 5, 0xff000080) - end - end - end - circleFrame = 0 -end - -function onNewTurn() - - trackTeams() - killsCounter = 0 - - if mutant == nil then - AddCaption( loc("FIRST BLOOD MUTATES") ) - end - - checkScore() - giveWeapons(CurrentHedgehog) - drawCircles() - setAIHints() - kill_reward= numhhs*10 - - if CurrentHedgehog == mutant then - mt_hurt=true - disease= mutant_base_disease - numhhs - else - mt_hurt=false - end - - setGearValue(CurrentHedgehog, "Alive", true) - -end - -function countBodies() - if killsCounter == 2 then - AddCaption(loc("DOUBLE KILL")) - elseif killsCounter == 3 then - AddCaption(loc("MEGA KILL")) - PlaySound(sndRegret) - elseif killsCounter == 4 then - AddCaption(loc("ULTRA KILL")) - elseif killsCounter == 5 then - AddCaption(loc("MONSTER KILL")) - PlaySound(sndIllGetYou) - elseif killsCounter == 6 then - AddCaption(loc("LUDICROUS KILL")) - PlaySound(sndNutter) - elseif killsCounter == 7 then - AddCaption(loc("HOLY SHYTE!")) - PlaySound(sndLaugh) - elseif killsCounter > 8 then - AddCaption(loc("INSANITY")) - end -end - -function onGameTick() - - if circleFrame > -1 then - for i = 0, #hhs do - if circles[hhs[i]] ~= nil and hhs[i]~= nil then - hhx, hhy = GetGearPosition(hhs[i]) - X, Y, dX, dY, Angle, Frame, FrameTicks, State, Timer, Tint = GetVisualGearValues(circles[hhs[i]]) - SetVisualGearValues(circles[hhs[i]], hhx + 1, hhy - 3, 0, 0, 0, 0, 0, 40 - (circleFrame % 25), Timer, Tint) - end - end - - circleFrame = circleFrame + 0.06 - - if circleFrame >= 25 then - for i = 0, #hhs do - if circles[hhs[i]] ~= nil then - DeleteVisualGear(circles[hhs[i]]) - circles[hhs[i]] = nil - end - end - end - end - - if TurnTimeLeft==0 and mt_hurt then - mt_hurt = false - end - - if mt_hurt and mutant~=nil then - timer = timer + 1 - if timer > disease_timer then - timer = 0 - SetHealth(mutant, GetHealth(mutant)-disease ) - AddVisualGear(GetX(mutant), GetY(mutant)-5, vgtHealthTag, disease, true) - if GetHealth(mutant)<=0 then - SetHealth(mutant,0) - mt_hurt= false - setGearValue(mutant,"SelfDestruct",true) - TurnTimeLeft = 0 - end - end - end - -end - -function saveStuff(gear) - setGearValue(gear,"Name",GetHogName(gear)) - setGearValue(gear,"Hat",GetHogHat(gear)) -end - -function armageddon(gear) - SetState(gear, gstLoser) - SetEffect(gear, heResurrectable, false) - SetHealth(gear, 0) -end - -function updateScore() - - local showScore = "" - - for i=0, TeamsCount-1 do - if teams[i]~= nil then - - local curr_score = getTeamValue(teams[i], "Score") - showScore = showScore .. teams[i] .. ": " .. curr_score .. " (deaths: " .. getTeamValue(teams[i], "DeadHogs") .. ") " .. "|" - - end - end - - ShowMission(loc("Score"), - "-------", - showScore, 0, 200) - - HideMission() - -end - -function checkScore() -local showScore = "" -local lowest_score_team = nil -local min_score=nil -local winTeam = nil - -local only_low_score = true - - for i=0, TeamsCount-1 do - if teams[i]~=nil then - local curr_score = getTeamValue(teams[i], "Score") - - runOnHogsInTeam(removeFeeder, teams[i]) - - showScore = showScore .. teams[i] ..": " .. curr_score .. " (deaths: " .. getTeamValue(teams[i], "DeadHogs") .. ") " .. "|" - - if curr_score >= winScore then - gameOver = true - winTeam = teams[i] - end - - if min_score==nil then - min_score= curr_score - lowest_score_team = teams[i] - else - if curr_score <= min_score then - if curr_score == min_score then - if getTeamValue(teams[i], "DeadHogs") == getTeamValue(lowest_score_team, "DeadHogs") then - only_low_score = false - else - if getTeamValue(teams[i], "DeadHogs") > getTeamValue(lowest_score_team, "DeadHogs") then - lowest_score_team = teams[i] - end - only_low_score = true - end - - else - min_score= curr_score - lowest_score_team = teams[i] - only_low_score = true - end - end - end - end - end - - if gameOver then - TurnTimeLeft = 0 - for i=0, #teams do - if teams[i]~=winTeam then - runOnHogsInTeam(armageddon, teams[i]) - end - end - - ShowMission( loc("WINNER IS ") .. winTeam, - "~~~~~~~~~~~~~~~~~~~~~~~~~", - showScore, 0, 200) - else - - if only_low_score then - runOnHogsInTeam(setFeeder, lowest_score_team) - end - - if meh == false then - meh = true - else - ShowMission( loc("Score"), - loc("-------"), - showScore, 0, 200) - end - - end -end - -function backToNormal(gear) - SetHogName(gear, getGearValue(gear,"Name")) - SetHogHat(gear, 'NoHat') - SetHogHat(gear, getGearValue(gear,"Hat")) - setGearValue(mutant,"SelfDestruct",false) - mt_hurt=false - mutant=nil -end - -function setAIHints() - for i = 0, #hhs do - if mutant == nil or hhs[i] == mutant or CurrentHedgehog == mutant then - SetGearAIHints(hhs[i], aihUsual) - else - SetGearAIHints(hhs[i], aihDoesntMatter) - end - end -end - -function removeFeeder(gear) - if gear~=nil then - setGearValue(gear,"Feeder",false) - if gear~= mutant then - SetHogName(gear, getGearValue(gear,"Name") ) - SetHogHat(gear, 'NoHat') - SetHogHat(gear, getGearValue(gear,"Hat")) - end - end -end - -function setFeeder(gear) - if gear~= mutant and gear~= nil then - SetHogName(gear,"BOTTOM FEEDER") - SetHogHat(gear, 'poke_slowpoke') - setGearValue(gear,"Feeder", true) - end -end - -function setMutantStuff(gear) - mutant = gear - - SetHogName(gear,"MUTANT") - SetHogHat(gear,'WhySoSerious') - SetHealth(gear, ( mutant_base_health + numhhs*25) ) - SetEffect(gear, hePoisoned, 1) - setGearValue(mutant,"SelfDestruct",false) - setGearValue(gear, "Feeder", false) - - AddCaption(getGearValue(gear, "Name") .. loc(" HAS MUTATED")) - - TurnTimeLeft=0 - - AddVisualGear(GetX(gear), GetY(gear), vgtSmokeRing, 0, false) - AddVisualGear(GetX(gear), GetY(gear), vgtSmokeRing, 0, false) - AddVisualGear(GetX(gear), GetY(gear), vgtSmokeRing, 0, false) - AddVisualGear(GetX(gear), GetY(gear), vgtSmokeRing, 0, false) - AddVisualGear(GetX(gear), GetY(gear), vgtSmokeRing, 0, false) - PlaySound(sndSuddenDeath) -end - -function teamScan() - - for i=0, TeamsCount-1 do --nil filling - teams[i]=nil - end - - for i=0, #hhs do - for j=0, TeamsCount-1 do - if teams[j] ==nil and hhs[i]~=nil then - teams[j] = GetHogTeamName(hhs[i]) - setTeamValue(teams[j],"Score",0) - setTeamValue(teams[j], "DeadHogs",0) - break - end - - if teams[j] == GetHogTeamName(hhs[i]) then - break - end - end - end - - ---***--- -end - -function set_Mutant_and_Score(gear) - -local curr_team = GetHogTeamName(CurrentHedgehog) - - if gear == CurrentHedgehog then - if CurrentHedgehog == mutant then - PlaySound(sndHomerun) - if getGearValue(gear, "SelfDestruct")==false then - decreaseTeamValue(curr_team,"Score") - end - backToNormal(gear) - else - decreaseTeamValue(curr_team,"Score") - end - - else - if gear == mutant then - backToNormal(mutant) - if curr_team ~=GetHogTeamName(gear) then - if getGearValue(CurrentHedgehog, "Alive") then - setMutantStuff(CurrentHedgehog) - setTeamValue(curr_team,"Score",(getTeamValue(curr_team,"Score") + mutant_kill_reward)) - end - else - setTeamValue(curr_team,"Score",(getTeamValue(curr_team,"Score") - team_fire_punishment)) - end - else - if mutant==nil then - if curr_team ~=GetHogTeamName(gear) then - if getGearValue(CurrentHedgehog, "Alive") then - setMutantStuff(CurrentHedgehog) - setTeamValue(curr_team,"Score",(getTeamValue(curr_team,"Score") + mutant_kill_reward)) - else - increaseTeamValue(curr_team,"Score") - end - else - setTeamValue(curr_team,"Score",(getTeamValue(curr_team,"Score") - team_fire_punishment)) - end - else - if curr_team ~=GetHogTeamName(gear) then - if CurrentHedgehog==mutant and getGearValue(mutant,"SelfDestruct")==false then - SetHealth(CurrentHedgehog, GetHealth(CurrentHedgehog)+kill_reward) - AddCaption("+" .. kill_reward .. loc(" HP") ) - increaseTeamValue(curr_team,"Score") - end - if getGearValue(CurrentHedgehog,"Feeder") then - increaseTeamValue(curr_team,"Score") - end - else - setTeamValue(curr_team,"Score",(getTeamValue(curr_team,"Score") - team_fire_punishment)) - end - end - end - end -end - -function onGearResurrect(gear) -if not gameOver then - if GetGearType(gear) == gtHedgehog then - - increaseTeamValue(GetHogTeamName(gear), "DeadHogs") - - if gear==CurrentHedgehog then - setGearValue(CurrentHedgehog, "Alive", false) - end - set_Mutant_and_Score(gear) - if gear~=CurrentHedgehog then - killsCounter = killsCounter + 1 - countBodies() - end - AddVisualGear(GetX(gear), GetY(gear), vgtSmokeRing, 0, false) - PlaySound(sndWhack) - updateScore() - end -end -end - -function onGearAdd(gear) - - -- Catch hedgehogs for the tracker - if GetGearType(gear) == gtHedgehog then - trackGear(gear) - hhs[numhhs] = gear - numhhs = numhhs + 1 - SetEffect(gear, heResurrectable, 1) - end -end - -function checkEmptyTeam (teamName) - for i=0 , #hhs do - if hhs[i]~=nil then - if teamName == GetHogTeamName(hhs[i]) then - return false - end - end - end - return true -end - -function onGearDelete(gear) - -- Remove hogs that are gone - if GetGearType(gear) == gtHedgehog then - numhhs = numhhs - 1 - - local found - for i=0, #hhs do - if hhs[i] == gear then - found = i - break - end - end - for i = found, #hhs - 1 do - hhs[i] = hhs[i + 1] - end - hhs[#hhs] = nil - - local t_name = GetHogTeamName(gear) - if checkEmptyTeam(t_name) then - for i = 0, TeamsCount - 1 do - if teams[i] == t_name then - found = i - break - end - end - for i = found, TeamsCount - 2 do - teams[i] = teams[i + 1] - end - teams[TeamsCount - 1] = nil - TeamsCount = TeamsCount - 1 - end - AddVisualGear(GetX(gear), GetY(gear), vgtBigExplosion, 0, false) - trackDeletion(gear) - end -end - ---[[ -S T A R R I N G - prof - Coding, implementing and evangelism - vos - Initial idea and script improvements - mikade - Moving the `how to play` into the game so that people know `how to play`, and whitespace :D ---]] +local MUTANT_VERSION = "v0.9.5" + +--[[ ___ ___ + ( ) ( ) +___ .-. .-. ___ ___ | |_ .---. ___ .-. | |_ +( ) ' ( )( ( __) / .-, ( ) ( __) +| .-. .-. | | | | | | (__) ; || .-. .| | +| | | | | | | | | | | ___ .'` || | | || | ___ +| | | | | | | | | | |( / .'| || | | || |( ) +| | | | | | | | | | | | | / | || | | || | | | +| | | | | | | ; ' | ' | ; | ; || | | || ' | | +| | | | | ' `-' / ' `-' ' `-' || | | |' `-' ; +(___)(___)(___'.__.' `.__.`.__.'_(___)(___)`.__. + + +---- Recommended settings: +---- * one hedgehog per team +---- * 'Small' one-island map + +--]] + +HedgewarsScriptLoad("/Scripts/Locale.lua") +HedgewarsScriptLoad("/Scripts/Tracker.lua") + +--[[ + MUTANT SCRIPT + + To Do: -Clean-up this fucking piece of code + -Debug + -Find a girlfriend + -Fix Sheepluva's hat +[p] + -Cookies +-----------------------]] + +local hhs = {} +local numhhs = 0 +local meh = false + +local gameOver=false + +local mutant = nil +local mutant_base_health = 200 +local mutant_base_disease = 25 +local disease_timer = 2000 + +local kill_reward = nil +local mt_hurt=false + +local killsCounter = 0 + +local team_fire_punishment = 3 +local mutant_kill_reward = 2 + +local hh_weapons = { amBazooka, amGrenade, amShotgun, amMine} + +local mt_weapons = {amWatermelon, amHellishBomb, amBallgun, amRCPlane, amTeleport} + +local disease=0 +local timer=0 + +local winScore = 15 +local hogsLimit = 1 + +local teams = {} + +local circles = {} +local circleFrame = -1 + +function showStartingInfo() + + ruleSet = loc("RULES") .. ": " .. + " |" .. --" |" .. + loc("The first player to kill someone becomes the Mutant.") .. "|" .. + loc("The Mutant has super-weapons and a lot of health.") .. "|" .. + loc("The Mutant loses health quickly if he doesn't keep scoring kills.") .. "|" .. + " |" .. + loc("Normal players can only score points by killing the mutant.") .. "|" .. + " |" .. "" .. + loc("The player with least points (or most deaths) becomes the Bottom Feeder.") .. "|" .. + loc("The Bottom Feeder can score points by killing anyone.") .. "|" .. + " |" .. + loc("POINTS") .. ": " .. + " |" .. + loc("+2 for becoming a Mutant") .. "|" .. + loc("+1 to a Mutant for killing anyone") .. "|" .. + loc("+1 to a Bottom Feeder for killing anyone") .. "|" .. + loc("-1 to anyone for a suicide") .. "|" .. + loc("Other kills don't give you points.") + + ShowMission(loc("Mutant"), + loc("a Hedgewars tag game"), + ruleSet, 0, 5000) + +end + +function onGameInit() + TurnTime = 20000 + WaterRise = 0 + GameFlags = GameFlags + gfResetWeps + gfPerHogAmmo + HealthCaseProb=0 + HealthCaseAmount=0 + MinesTime=1000 + CaseFreq = 2 +end + + +function limitHogs(gear) + cnthhs = cnthhs + 1 + if cnthhs > 1 then + hogLimitHit = true + SetEffect(gear, heResurrectable, false) + --SetHealth(gear, 0) + SetGearPosition(gear, -100,LAND_HEIGHT) + end +end + +function onGameStart() + trackTeams() + teamScan() + runOnHogs(saveStuff) + --local str = "/say " .. MUTANT_VERSION + --ParseCommand(str) + + hogLimitHit = false + for i=0 , TeamsCount - 1 do + cnthhs = 0 + runOnHogsInTeam(limitHogs, teams[i]) + end + if hogLimitHit then + AddCaption(loc("ONE HOG PER TEAM! KILLING EXCESS HEDGES")) + end + showStartingInfo() +end + + + +function giveWeapons(gear) + if gear == mutant then + AddAmmo(gear, amRope) + for i=1, #mt_weapons do + AddAmmo(gear, mt_weapons[i]) + end + + else + for i=1, #hh_weapons do + AddAmmo(gear,hh_weapons[i]) + end + end +end + +function onAmmoStoreInit() + + SetAmmo(amSkip, 9, 0, 0, 0) + SetAmmo(amRope,0,1,0,5) + SetAmmo(amSnowball,0,1,0,1) + + for i=1, #hh_weapons do + SetAmmo(hh_weapons[i], 0, 0, 0, 1) + end + + for i=1, #mt_weapons do + SetAmmo(mt_weapons[i], 0, 3, 0, 1) + end + +end + +function drawCircles() + for i = 0, #hhs do + if circles[hhs[i]] ~= nil then + DeleteVisualGear(circles[hhs[i]]) + circles[hhs[i]] = nil + end + + if hhs[i] ~= CurrentHedgehog then + if mutant == nil then + circles[hhs[i]] = AddVisualGear(0, 0, vgtCircle, 0, false) + SetVisualGearValues(circles[hhs[i]], 0, 0, 0, 0, 0, 0, 0, 22, 5, 0xff000080) + elseif CurrentHedgehog == mutant then + circles[hhs[i]] = AddVisualGear(0, 0, vgtCircle, 0, false) + SetVisualGearValues(circles[hhs[i]], 0, 0, 0, 0, 0, 0, 0, 22, 3, 0xaa000070) + elseif getGearValue(CurrentHedgehog, "Feeder") and hhs[i] ~= mutant then + circles[hhs[i]] = AddVisualGear(0, 0, vgtCircle, 0, false) + SetVisualGearValues(circles[hhs[i]], 0, 0, 0, 0, 0, 0, 0, 22, 3, 0xaa000070) + elseif hhs[i] == mutant then + circles[hhs[i]] = AddVisualGear(0, 0, vgtCircle, 0, false) + SetVisualGearValues(circles[hhs[i]], 0, 0, 0, 0, 0, 0, 0, 22, 5, 0xff000080) + end + end + end + circleFrame = 0 +end + +function onNewTurn() + + trackTeams() + killsCounter = 0 + + if mutant == nil then + AddCaption( loc("FIRST BLOOD MUTATES") ) + end + + checkScore() + giveWeapons(CurrentHedgehog) + drawCircles() + setAIHints() + kill_reward= numhhs*10 + + if CurrentHedgehog == mutant then + mt_hurt=true + disease= mutant_base_disease - numhhs + else + mt_hurt=false + end + + setGearValue(CurrentHedgehog, "Alive", true) + +end + +function countBodies() + if killsCounter == 2 then + AddCaption(loc("DOUBLE KILL")) + elseif killsCounter == 3 then + AddCaption(loc("MEGA KILL")) + PlaySound(sndRegret) + elseif killsCounter == 4 then + AddCaption(loc("ULTRA KILL")) + elseif killsCounter == 5 then + AddCaption(loc("MONSTER KILL")) + PlaySound(sndIllGetYou) + elseif killsCounter == 6 then + AddCaption(loc("LUDICROUS KILL")) + PlaySound(sndNutter) + elseif killsCounter == 7 then + AddCaption(loc("HOLY SHYTE!")) + PlaySound(sndLaugh) + elseif killsCounter > 8 then + AddCaption(loc("INSANITY")) + end +end + +function onGameTick() + + if circleFrame > -1 then + for i = 0, #hhs do + if circles[hhs[i]] ~= nil and hhs[i]~= nil then + hhx, hhy = GetGearPosition(hhs[i]) + X, Y, dX, dY, Angle, Frame, FrameTicks, State, Timer, Tint = GetVisualGearValues(circles[hhs[i]]) + SetVisualGearValues(circles[hhs[i]], hhx + 1, hhy - 3, 0, 0, 0, 0, 0, 40 - (circleFrame % 25), Timer, Tint) + end + end + + circleFrame = circleFrame + 0.06 + + if circleFrame >= 25 then + for i = 0, #hhs do + if circles[hhs[i]] ~= nil then + DeleteVisualGear(circles[hhs[i]]) + circles[hhs[i]] = nil + end + end + end + end + + if TurnTimeLeft==0 and mt_hurt then + mt_hurt = false + end + + if mt_hurt and mutant~=nil then + timer = timer + 1 + if timer > disease_timer then + timer = 0 + SetHealth(mutant, GetHealth(mutant)-disease ) + AddVisualGear(GetX(mutant), GetY(mutant)-5, vgtHealthTag, disease, true) + if GetHealth(mutant)<=0 then + SetHealth(mutant,0) + mt_hurt= false + setGearValue(mutant,"SelfDestruct",true) + TurnTimeLeft = 0 + end + end + end + +end + +function saveStuff(gear) + setGearValue(gear,"Name",GetHogName(gear)) + setGearValue(gear,"Hat",GetHogHat(gear)) +end + +function armageddon(gear) + SetState(gear, gstLoser) + SetEffect(gear, heResurrectable, false) + SetHealth(gear, 0) +end + +function updateScore() + + local showScore = "" + + for i=0, TeamsCount-1 do + if teams[i]~= nil then + + local curr_score = getTeamValue(teams[i], "Score") + showScore = showScore .. teams[i] .. ": " .. curr_score .. " (deaths: " .. getTeamValue(teams[i], "DeadHogs") .. ") " .. "|" + + end + end + + ShowMission(loc("Score"), + "-------", + showScore, 0, 200) + + HideMission() + +end + +function checkScore() +local showScore = "" +local lowest_score_team = nil +local min_score=nil +local winTeam = nil + +local only_low_score = true + + for i=0, TeamsCount-1 do + if teams[i]~=nil then + local curr_score = getTeamValue(teams[i], "Score") + + runOnHogsInTeam(removeFeeder, teams[i]) + + showScore = showScore .. teams[i] ..": " .. curr_score .. " (deaths: " .. getTeamValue(teams[i], "DeadHogs") .. ") " .. "|" + + if curr_score >= winScore then + gameOver = true + winTeam = teams[i] + end + + if min_score==nil then + min_score= curr_score + lowest_score_team = teams[i] + else + if curr_score <= min_score then + if curr_score == min_score then + if getTeamValue(teams[i], "DeadHogs") == getTeamValue(lowest_score_team, "DeadHogs") then + only_low_score = false + else + if getTeamValue(teams[i], "DeadHogs") > getTeamValue(lowest_score_team, "DeadHogs") then + lowest_score_team = teams[i] + end + only_low_score = true + end + + else + min_score= curr_score + lowest_score_team = teams[i] + only_low_score = true + end + end + end + end + end + + if gameOver then + TurnTimeLeft = 0 + for i=0, #teams do + if teams[i]~=winTeam then + runOnHogsInTeam(armageddon, teams[i]) + end + end + + ShowMission( loc("WINNER IS ") .. winTeam, + "~~~~~~~~~~~~~~~~~~~~~~~~~", + showScore, 0, 200) + else + + if only_low_score then + runOnHogsInTeam(setFeeder, lowest_score_team) + end + + if meh == false then + meh = true + else + ShowMission( loc("Score"), + loc("-------"), + showScore, 0, 200) + end + + end +end + +function backToNormal(gear) + SetHogName(gear, getGearValue(gear,"Name")) + SetHogHat(gear, 'NoHat') + SetHogHat(gear, getGearValue(gear,"Hat")) + setGearValue(mutant,"SelfDestruct",false) + mt_hurt=false + mutant=nil +end + +function setAIHints() + for i = 0, #hhs do + if mutant == nil or hhs[i] == mutant or CurrentHedgehog == mutant then + SetGearAIHints(hhs[i], aihUsual) + else + SetGearAIHints(hhs[i], aihDoesntMatter) + end + end +end + +function removeFeeder(gear) + if gear~=nil then + setGearValue(gear,"Feeder",false) + if gear~= mutant then + SetHogName(gear, getGearValue(gear,"Name") ) + SetHogHat(gear, 'NoHat') + SetHogHat(gear, getGearValue(gear,"Hat")) + end + end +end + +function setFeeder(gear) + if gear~= mutant and gear~= nil then + SetHogName(gear,"BOTTOM FEEDER") + SetHogHat(gear, 'poke_slowpoke') + setGearValue(gear,"Feeder", true) + end +end + +function setMutantStuff(gear) + mutant = gear + + SetHogName(gear,"MUTANT") + SetHogHat(gear,'WhySoSerious') + SetHealth(gear, ( mutant_base_health + numhhs*25) ) + SetEffect(gear, hePoisoned, 1) + setGearValue(mutant,"SelfDestruct",false) + setGearValue(gear, "Feeder", false) + + AddCaption(getGearValue(gear, "Name") .. loc(" HAS MUTATED")) + + TurnTimeLeft=0 + + AddVisualGear(GetX(gear), GetY(gear), vgtSmokeRing, 0, false) + AddVisualGear(GetX(gear), GetY(gear), vgtSmokeRing, 0, false) + AddVisualGear(GetX(gear), GetY(gear), vgtSmokeRing, 0, false) + AddVisualGear(GetX(gear), GetY(gear), vgtSmokeRing, 0, false) + AddVisualGear(GetX(gear), GetY(gear), vgtSmokeRing, 0, false) + PlaySound(sndSuddenDeath) +end + +function teamScan() + + for i=0, TeamsCount-1 do --nil filling + teams[i]=nil + end + + for i=0, #hhs do + for j=0, TeamsCount-1 do + if teams[j] ==nil and hhs[i]~=nil then + teams[j] = GetHogTeamName(hhs[i]) + setTeamValue(teams[j],"Score",0) + setTeamValue(teams[j], "DeadHogs",0) + break + end + + if teams[j] == GetHogTeamName(hhs[i]) then + break + end + end + end + + ---***--- +end + +function set_Mutant_and_Score(gear) + +local curr_team = GetHogTeamName(CurrentHedgehog) + + if gear == CurrentHedgehog then + if CurrentHedgehog == mutant then + PlaySound(sndHomerun) + if getGearValue(gear, "SelfDestruct")==false then + decreaseTeamValue(curr_team,"Score") + end + backToNormal(gear) + else + decreaseTeamValue(curr_team,"Score") + end + + else + if gear == mutant then + backToNormal(mutant) + if curr_team ~=GetHogTeamName(gear) then + if getGearValue(CurrentHedgehog, "Alive") then + setMutantStuff(CurrentHedgehog) + setTeamValue(curr_team,"Score",(getTeamValue(curr_team,"Score") + mutant_kill_reward)) + end + else + setTeamValue(curr_team,"Score",(getTeamValue(curr_team,"Score") - team_fire_punishment)) + end + else + if mutant==nil then + if curr_team ~=GetHogTeamName(gear) then + if getGearValue(CurrentHedgehog, "Alive") then + setMutantStuff(CurrentHedgehog) + setTeamValue(curr_team,"Score",(getTeamValue(curr_team,"Score") + mutant_kill_reward)) + else + increaseTeamValue(curr_team,"Score") + end + else + setTeamValue(curr_team,"Score",(getTeamValue(curr_team,"Score") - team_fire_punishment)) + end + else + if curr_team ~=GetHogTeamName(gear) then + if CurrentHedgehog==mutant and getGearValue(mutant,"SelfDestruct")==false then + SetHealth(CurrentHedgehog, GetHealth(CurrentHedgehog)+kill_reward) + AddCaption("+" .. kill_reward .. loc(" HP") ) + increaseTeamValue(curr_team,"Score") + end + if getGearValue(CurrentHedgehog,"Feeder") then + increaseTeamValue(curr_team,"Score") + end + else + setTeamValue(curr_team,"Score",(getTeamValue(curr_team,"Score") - team_fire_punishment)) + end + end + end + end +end + +function onGearResurrect(gear) +if not gameOver then + if GetGearType(gear) == gtHedgehog then + + increaseTeamValue(GetHogTeamName(gear), "DeadHogs") + + if gear==CurrentHedgehog then + setGearValue(CurrentHedgehog, "Alive", false) + end + set_Mutant_and_Score(gear) + if gear~=CurrentHedgehog then + killsCounter = killsCounter + 1 + countBodies() + end + AddVisualGear(GetX(gear), GetY(gear), vgtSmokeRing, 0, false) + PlaySound(sndWhack) + updateScore() + end +end +end + +function onGearAdd(gear) + + -- Catch hedgehogs for the tracker + if GetGearType(gear) == gtHedgehog then + trackGear(gear) + hhs[numhhs] = gear + numhhs = numhhs + 1 + SetEffect(gear, heResurrectable, 1) + end +end + +function checkEmptyTeam (teamName) + for i=0 , #hhs do + if hhs[i]~=nil then + if teamName == GetHogTeamName(hhs[i]) then + return false + end + end + end + return true +end + +function onGearDelete(gear) + -- Remove hogs that are gone + if GetGearType(gear) == gtHedgehog then + numhhs = numhhs - 1 + + local found + for i=0, #hhs do + if hhs[i] == gear then + found = i + break + end + end + for i = found, #hhs - 1 do + hhs[i] = hhs[i + 1] + end + hhs[#hhs] = nil + + local t_name = GetHogTeamName(gear) + if checkEmptyTeam(t_name) then + for i = 0, TeamsCount - 1 do + if teams[i] == t_name then + found = i + break + end + end + for i = found, TeamsCount - 2 do + teams[i] = teams[i + 1] + end + teams[TeamsCount - 1] = nil + TeamsCount = TeamsCount - 1 + end + AddVisualGear(GetX(gear), GetY(gear), vgtBigExplosion, 0, false) + trackDeletion(gear) + end +end + +--[[ +S T A R R I N G + prof - Coding, implementing and evangelism + vos - Initial idea and script improvements + mikade - Moving the `how to play` into the game so that people know `how to play`, and whitespace :D +--]] diff -r 4feced261c68 -r de822cd3df3a share/hedgewars/Data/Scripts/Multiplayer/Racer.lua --- a/share/hedgewars/Data/Scripts/Multiplayer/Racer.lua Tue Jan 21 22:38:13 2014 +0100 +++ b/share/hedgewars/Data/Scripts/Multiplayer/Racer.lua Tue Jan 21 22:43:06 2014 +0100 @@ -1,720 +1,720 @@ - ------------------------------------------- --- RACER 0.6 --- map-independant racing script --- by mikade ------------------------------------------ - ------------------------------------ ---0.1: took all the code from crazy racer and scrapped most of it ------------------------------------ - --- Removed tumbler system --- Removed extra adds like boosters etc --- Added experimental waypoint placement system --- More user feedback --- Reduced race complexity limit to 5 waypoints --- stop placement at complexity limit reached and end turn --- guys dont keep racing after dying --- invulnerable feasibility --- reverted time keeping method --- reduced feedback display time --- colour-coded addcaptions --- cleaned up code --- support for more players properly added --- tardis fix --- remove airstrikes - --- i think the remainder 0 .456 sec of the tracktime isnt getting reset on newturn - --- update feedback - -------- --- 0.2 -------- - --- allow gameflags --- extend time to 90s --- remove other air-attack based weps --- turn off water rise for sd - -------- --- 0.3 -------- - --- prevent WP being placed in land --- prevent waypoints being placed outside border - -------- --- 0.4 -------- - --- update user feedback --- add more sounds - -------- --- 0.5 -------- - --- fix ghost disappearing if hog falls in water or somehow dies --- lengthen ghost tracking interval to improve performance on slower machines --- increase waypoint limit to 8 --- allow for persistent showmission information - -------- --- 0.6 -------- - --- remove hogs from racing area as per request - ------------------------------ --- SCRIPT BEGINS ------------------------------ - -HedgewarsScriptLoad("/Scripts/Locale.lua") - ------------------- --- Got Variables? ------------------- - -local fMod = 1000000 -- 1 -local roundLimit = 3 -local roundNumber = 0 -local firstClan = 10 - -local fastX = {} -local fastY = {} -local fastCount = 0 -local fastIndex = 0 -local fastColour - -local currX = {} -local currY = {} -local currCount = 0 - -local specialPointsX = {} -local specialPointsY = {} -local specialPointsCount = 0 - --------------------------- --- hog and team tracking variales --------------------------- - -local numhhs = 0 -- store number of hedgehogs -local hhs = {} -- store hedgehog gears - -local numTeams -- store the number of teams in the game -local teamNameArr = {} -- store the list of teams -local teamClan = {} -local teamSize = {} -- store how many hogs per team -local teamIndex = {} -- at what point in the hhs{} does each team begin - -local teamComment = {} -local teamScore = {} - -------- --- racer vars --------- - -local cGear = nil - -local bestClan = nil -local bestTime = nil - -local gameBegun = false -local gameOver = false -local racerActive = false -local trackTime = 0 - -local wpCirc = {} -local wpX = {} -local wpY = {} -local wpCol = {} -local wpActive = {} -local wpRad = 450 --75 -local wpCount = 0 -local wpLimit = 8 - -local roundN -local lastRound -local RoundHasChanged - -------------------- --- general methods -------------------- - -function RebuildTeamInfo() - - - -- make a list of individual team names - for i = 0, (TeamsCount-1) do - teamNameArr[i] = " " -- = i - teamSize[i] = 0 - teamIndex[i] = 0 - teamScore[i] = 100000 - end - numTeams = 0 - - for i = 0, (numhhs-1) do - - z = 0 - unfinished = true - while(unfinished == true) do - - newTeam = true - tempHogTeamName = GetHogTeamName(hhs[i]) -- this is the new name - - if tempHogTeamName == teamNameArr[z] then - newTeam = false - unfinished = false - end - - z = z + 1 - - if z == TeamsCount then - unfinished = false - if newTeam == true then - teamNameArr[numTeams] = tempHogTeamName - numTeams = numTeams + 1 - end - end - - end - - end - - -- find out how many hogs per team, and the index of the first hog in hhs - for i = 0, (numTeams-1) do - for z = 0, (numhhs-1) do - if GetHogTeamName(hhs[z]) == teamNameArr[i] then - teamClan[i] = GetHogClan(hhs[z]) - if teamSize[i] == 0 then - teamIndex[i] = z -- should give starting index - end - teamSize[i] = teamSize[i] + 1 - --add a pointer so this hog appears at i in hhs - end - end - - end - -end - - ------------------ --- RACER METHODS ------------------ - -function CheckWaypoints() - - trackFinished = true - - for i = 0, (wpCount-1) do - - g1X, g1Y = GetGearPosition(CurrentHedgehog) - g2X, g2Y = wpX[i], wpY[i] - - g1X = g1X - g2X - g1Y = g1Y - g2Y - dist = (g1X*g1X) + (g1Y*g1Y) - - --if i == 0 then - -- AddCaption(dist .. "/" .. (wpRad*wpRad) ) - --end - - NR = (48/100*wpRad)/2 - - if dist < (NR*NR) then - --if dist < (wpRad*wpRad) then - --AddCaption("howdy") - wpActive[i] = true - wpCol[i] = GetClanColor(GetHogClan(CurrentHedgehog)) -- new --GetClanColor(1) - SetVisualGearValues(wpCirc[i], wpX[i], wpY[i], 20, 100, 1, 10, 0, wpRad, 5, wpCol[i]) - - wpRem = 0 - for k = 0, (wpCount-1) do - if wpActive[k] == false then - wpRem = wpRem + 1 - end - end - - AddCaption(loc("Way-Points Remaining") .. ": " .. wpRem,0xffba00ff,capgrpAmmoinfo) - - end - - if wpActive[i] == false then - trackFinished = false - end - - end - - return(trackFinished) - -end - -function AdjustScores() - - if bestTime == nil then - bestTime = 100000 - bestClan = 10 - bestTimeComment = "N/A" - end - - newScore = false - - -- update this clan's time if the new track is better - for i = 0, (numTeams-1) do - if teamClan[i] == GetHogClan(CurrentHedgehog) then - if trackTime < teamScore[i] then - teamScore[i] = trackTime - newScore = true - else - newScore = false - end - end - end - - --bestTime = 100000 - --bestClan = 10 - - -- find the best time out of those so far - for i = 0, (numTeams-1) do - if teamScore[i] < bestTime then - bestTime = teamScore[i] - bestClan = teamClan[i] - end - end - - if bestTime ~= 100000 then - bestTimeComment = (bestTime/1000) ..loc("s") - end - - if newScore == true then - if trackTime == bestTime then -- best time of the race - ShowMission(loc("RACER"), - loc("TRACK COMPLETED"), - loc("NEW RACE RECORD: ") .. (trackTime/1000) ..loc("s") .. "|" .. - loc("WINNING TIME: ") .. bestTimeComment, 0, 4000) - PlaySound(sndHomerun) - else -- best time for the clan - ShowMission(loc("RACER"), - loc("TRACK COMPLETED"), - loc("NEW CLAN RECORD: ") .. (trackTime/1000) ..loc("s") .. "|" .. - loc("WINNING TIME: ") .. bestTimeComment, 4, 4000) - end - else -- not any kind of new score - ShowMission(loc("RACER"), - loc("TRACK COMPLETED"), - loc("TIME: ") .. (trackTime/1000) ..loc("s") .. "|" .. - loc("WINNING TIME: ") .. bestTimeComment, -amSkip, 4000) - PlaySound(sndHellish) - end - - - -------- - --new - -------- - - if bestTime == trackTime then - --AddCaption("wooooooooooooooooooooooooooooo") - - fastColour = GetClanColor(GetHogClan(CurrentHedgehog)) - - for i = 0, (currCount-1) do - fastX[i] = currX[i] - fastY[i] = currY[i] - end - - fastCount = currCount - fastIndex = 0 - - --currCount = 0 -- is this needed? - - else - currCount = 0 - fastIndex = 0 - end - - -end - -function onNewRound() - - roundNumber = roundNumber + 1 - - totalComment = "" - for i = 0, (TeamsCount-1) do - if teamNameArr[i] ~= " " then -- teamScore[teamClan[i]] - teamComment[i] = teamNameArr[i] .. ": " .. (teamScore[i]/1000) .. loc("s|") - totalComment = totalComment .. teamComment[i] - elseif teamNameArr[i] == " " then - teamComment[i] = "|" - end - end - - ShowMission( loc("RACER"), - loc("STATUS UPDATE"), - loc("Rounds Complete: ") .. roundNumber .. "/" .. roundLimit .. "|" .. " " .. "|" .. - loc("Best Team Times: ") .. "|" .. totalComment, 0, 4000) - - -- end game if its at round limit - if roundNumber == roundLimit then - for i = 0, (numhhs-1) do - if GetHogClan(hhs[i]) ~= bestClan then - SetEffect(hhs[i], heResurrectable, 0) - SetHealth(hhs[i],0) - end - end - gameOver = true - TurnTimeLeft = 1 - end - -end - -function CheckForNewRound() - - ------------- - ------ new - ------------- - - --[[turnN = turnN + 1 - if gameBegun == false then - if turnN == 2 then - for i = 0, (numhhs-1) do - if hhs[i] ~= nil then - SetEffect(hhs[i], heResurrectable, 0) - SetHealth(hhs[i],0) - end - end - gameOver = true - TurnTimeLeft = 1 - end - else - - - end]] - - --[[if roundBegun == true then - - if RoundHasChanged == true then - roundN = roundN + 1 - RoundHasChanged = false - onNewRound() - end - - if lastRound ~= TotalRounds then -- new round, but not really - - if RoundHasChanged == false then - RoundHasChanged = true - end - - end - - AddCaption("RoundN:" .. roundN .. "; " .. "TR: " .. TotalRounds) - - lastRound = TotalRounds - - end]] - - ------------ - ----- old - ------------ - - if GetHogClan(CurrentHedgehog) == firstClan then - onNewRound() - end - -end - -function DisableTumbler() - currCount = 0 - fastIndex = 0 - TurnTimeLeft = 0 - racerActive = false -- newadd -end - -function HandleGhost() - - -- get the current xy of the racer at this point - currX[currCount] = GetX(CurrentHedgehog) - currY[currCount] = GetY(CurrentHedgehog) - currCount = currCount + 1 - - -- draw a ping of smoke where the fastest player was at this point - if (fastCount ~= 0) and (fastIndex < fastCount) then - - fastIndex = fastIndex + 1 - - tempE = AddVisualGear(fastX[fastIndex], fastY[fastIndex], vgtSmoke, 0, false) - g1, g2, g3, g4, g5, g6, g7, g8, g9, g10 = GetVisualGearValues(tempE) - SetVisualGearValues(tempE, g1, g2, g3, g4, g5, g6, g7, g8, g9, fastColour ) - - --AddCaption("fC: " .. fastIndex .. " / " .. fastCount) - - else - - --AddCaption("excep fC: " .. fastIndex .. " / " .. fastCount) - - end - - - -end - -function TryRepositionHogs() - - if MapHasBorder() == true then - - for i = 0, (numhhs-1) do - if hhs[i] ~= nil then - SetGearPosition(hhs[i],GetX(hhs[i]), TopY-10) - end - end - - end - -end - ----------------------------------- --- GAME METHODS / EVENT HANDLERS ----------------------------------- - -function onGameInit() - GameFlags = bor(GameFlags,gfInfAttack + gfInvulnerable) - CaseFreq = 0 - TurnTime = 90000 - WaterRise = 0 -end - - -function onGameStart() - - roundN = 0 - lastRound = TotalRounds - RoundHasChanged = false -- true - - for i = 0, (specialPointsCount-1) do - PlaceWayPoint(specialPointsX[i], specialPointsY[i]) - end - - RebuildTeamInfo() - - ShowMission ( - loc("RACER"), - loc("a Hedgewars mini-game"), - - loc("Build a track and race.") .. "|" .. - loc("Round Limit:") .. " " .. roundLimit .. "|" .. - - "", 4, 4000 - ) - - TryRepositionHogs() - -end - -function PlaceWayPoint(x,y) - - if (wpCount < wpLimit) then -- seems to not work with a hedgehog nil chek - - wpX[wpCount] = x - wpY[wpCount] = y - wpCol[wpCount] = 0xffffffff - wpCirc[wpCount] = AddVisualGear(wpX[wpCount],wpY[wpCount],vgtCircle,0,true) - --100 - SetVisualGearValues(wpCirc[wpCount], wpX[wpCount], wpY[wpCount], 20, 100, 1, 10, 0, wpRad, 5, wpCol[wpCount]) - - wpCount = wpCount + 1 - - AddCaption(loc("Waypoint placed.") .. " " .. loc("Available points remaining: ") .. (wpLimit-wpCount)) - - end - -end - -function onSpecialPoint(x,y,flag) - specialPointsX[specialPointsCount] = x - specialPointsY[specialPointsCount] = y - specialPointsCount = specialPointsCount + 1 -end - -function onNewTurn() - - CheckForNewRound() - TryRepositionHogs() - - racerActive = false - - trackTime = 0 - - currCount = 0 -- hopefully this solves problem - AddAmmo(CurrentHedgehog, amAirAttack, 0) - gTimer = 0 - - -- Set the waypoints to unactive on new round - for i = 0,(wpCount-1) do - wpActive[i] = false - wpCol[i] = 0xffffffff - SetVisualGearValues(wpCirc[i], wpX[i], wpY[i], 20, 100, 1, 10, 0, wpRad, 5, wpCol[i]) - end - - -- Handle Starting Stage of Game - if (gameOver == false) and (gameBegun == false) then - if wpCount >= 3 then - gameBegun = true - roundNumber = 0 - firstClan = GetHogClan(CurrentHedgehog) - ShowMission(loc("RACER"), - loc("GAME BEGUN!!!"), - loc("Complete the track as fast as you can!"), 2, 4000) - else - ShowMission(loc("RACER"), - loc("NOT ENOUGH WAYPOINTS"), - loc("Place more waypoints using the 'Air Attack' weapon."), 2, 4000) - AddAmmo(CurrentHedgehog, amAirAttack, 4000) - ParseCommand("setweap " .. string.char(amAirAttack)) - end - end - - if gameOver == true then - gameBegun = false - racerActive = false -- newadd - end - - AddAmmo(CurrentHedgehog, amTardis, 0) - AddAmmo(CurrentHedgehog, amDrillStrike, 0) - AddAmmo(CurrentHedgehog, amMineStrike, 0) - AddAmmo(CurrentHedgehog, amNapalm, 0) - AddAmmo(CurrentHedgehog, amPiano, 0) - -end - -function onGameTick20() - - -- airstrike detected, convert this into a potential waypoint spot - if cGear ~= nil then - x,y = GetGearPosition(cGear) - if x > -9000 then - x,y = GetGearTarget(cGear) - - - if TestRectForObstacle(x-20, y-20, x+20, y+20, true) then - AddCaption(loc("Please place the way-point in the open, within the map boundaries.")) - PlaySound(sndDenied) - elseif (y > WaterLine-50) then - AddCaption(loc("Please place the way-point further from the waterline.")) - PlaySound(sndDenied) - else - PlaceWayPoint(x, y) - if wpCount == wpLimit then - AddCaption(loc("Race complexity limit reached.")) - DisableTumbler() - end - end - else - DeleteGear(cGear) - end - SetGearPosition(cGear, -10000, 0) - end - - - -- start the player tumbling with a boom once their turn has actually begun - if racerActive == false then - - if (TurnTimeLeft > 0) and (TurnTimeLeft ~= TurnTime) then - - -- if the gamehas started put the player in the middle of the first - --waypoint that was placed - if gameBegun == true then - AddCaption(loc("Good to go!")) - racerActive = true - trackTime = 0 - - SetGearPosition(CurrentHedgehog, wpX[0], wpY[0]) - AddGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), gtGrenade, 0, 0, 0, 1) - FollowGear(CurrentHedgehog) - - HideMission() - - else - -- still in placement mode - end - - end - end - - - - -- has the player started his tumbling spree? - if (CurrentHedgehog ~= nil) then - - --airstrike conversion used to be here - - -- if the RACE has started, show tracktimes and keep tabs on waypoints - if (racerActive == true) and (gameBegun == true) then - - --ghost - if GameTime%40 == 0 then - HandleGhost() - end - - trackTime = trackTime + 20 - - if GameTime%100 == 0 then - - if trackTime%1000 == 0 then - AddCaption((trackTime/1000)..'.0',GetClanColor(GetHogClan(CurrentHedgehog)),capgrpMessage2) - else - AddCaption(trackTime/1000,GetClanColor(GetHogClan(CurrentHedgehog)),capgrpMessage2) - end - - if (CheckWaypoints() == true) then - AdjustScores() - racerActive = false - DisableTumbler() - end - - end - - end - - -- if the player has expended his tunbling time, stop him tumbling - if TurnTimeLeft <= 20 then - DisableTumbler() - end - - end - -end - -function onGearResurrect(gear) - - AddVisualGear(GetX(gear), GetY(gear), vgtBigExplosion, 0, false) - - if gear == CurrentHedgehog then - DisableTumbler() - end - -end - -function onGearAdd(gear) - - if GetGearType(gear) == gtHedgehog then - hhs[numhhs] = gear - numhhs = numhhs + 1 - SetEffect(gear, heResurrectable, 1) - end - - if GetGearType(gear) == gtAirAttack then - cGear = gear - end - -end - -function onGearDelete(gear) - - if GetGearType(gear) == gtAirAttack then - cGear = nil - end - -end + +------------------------------------------ +-- RACER 0.6 +-- map-independant racing script +-- by mikade +----------------------------------------- + +----------------------------------- +--0.1: took all the code from crazy racer and scrapped most of it +----------------------------------- + +-- Removed tumbler system +-- Removed extra adds like boosters etc +-- Added experimental waypoint placement system +-- More user feedback +-- Reduced race complexity limit to 5 waypoints +-- stop placement at complexity limit reached and end turn +-- guys dont keep racing after dying +-- invulnerable feasibility +-- reverted time keeping method +-- reduced feedback display time +-- colour-coded addcaptions +-- cleaned up code +-- support for more players properly added +-- tardis fix +-- remove airstrikes + +-- i think the remainder 0 .456 sec of the tracktime isnt getting reset on newturn + +-- update feedback + +------- +-- 0.2 +------- + +-- allow gameflags +-- extend time to 90s +-- remove other air-attack based weps +-- turn off water rise for sd + +------- +-- 0.3 +------- + +-- prevent WP being placed in land +-- prevent waypoints being placed outside border + +------- +-- 0.4 +------- + +-- update user feedback +-- add more sounds + +------- +-- 0.5 +------- + +-- fix ghost disappearing if hog falls in water or somehow dies +-- lengthen ghost tracking interval to improve performance on slower machines +-- increase waypoint limit to 8 +-- allow for persistent showmission information + +------- +-- 0.6 +------- + +-- remove hogs from racing area as per request + +----------------------------- +-- SCRIPT BEGINS +----------------------------- + +HedgewarsScriptLoad("/Scripts/Locale.lua") + +------------------ +-- Got Variables? +------------------ + +local fMod = 1000000 -- 1 +local roundLimit = 3 +local roundNumber = 0 +local firstClan = 10 + +local fastX = {} +local fastY = {} +local fastCount = 0 +local fastIndex = 0 +local fastColour + +local currX = {} +local currY = {} +local currCount = 0 + +local specialPointsX = {} +local specialPointsY = {} +local specialPointsCount = 0 + +-------------------------- +-- hog and team tracking variales +-------------------------- + +local numhhs = 0 -- store number of hedgehogs +local hhs = {} -- store hedgehog gears + +local numTeams -- store the number of teams in the game +local teamNameArr = {} -- store the list of teams +local teamClan = {} +local teamSize = {} -- store how many hogs per team +local teamIndex = {} -- at what point in the hhs{} does each team begin + +local teamComment = {} +local teamScore = {} + +------- +-- racer vars +-------- + +local cGear = nil + +local bestClan = nil +local bestTime = nil + +local gameBegun = false +local gameOver = false +local racerActive = false +local trackTime = 0 + +local wpCirc = {} +local wpX = {} +local wpY = {} +local wpCol = {} +local wpActive = {} +local wpRad = 450 --75 +local wpCount = 0 +local wpLimit = 8 + +local roundN +local lastRound +local RoundHasChanged + +------------------- +-- general methods +------------------- + +function RebuildTeamInfo() + + + -- make a list of individual team names + for i = 0, (TeamsCount-1) do + teamNameArr[i] = " " -- = i + teamSize[i] = 0 + teamIndex[i] = 0 + teamScore[i] = 100000 + end + numTeams = 0 + + for i = 0, (numhhs-1) do + + z = 0 + unfinished = true + while(unfinished == true) do + + newTeam = true + tempHogTeamName = GetHogTeamName(hhs[i]) -- this is the new name + + if tempHogTeamName == teamNameArr[z] then + newTeam = false + unfinished = false + end + + z = z + 1 + + if z == TeamsCount then + unfinished = false + if newTeam == true then + teamNameArr[numTeams] = tempHogTeamName + numTeams = numTeams + 1 + end + end + + end + + end + + -- find out how many hogs per team, and the index of the first hog in hhs + for i = 0, (numTeams-1) do + for z = 0, (numhhs-1) do + if GetHogTeamName(hhs[z]) == teamNameArr[i] then + teamClan[i] = GetHogClan(hhs[z]) + if teamSize[i] == 0 then + teamIndex[i] = z -- should give starting index + end + teamSize[i] = teamSize[i] + 1 + --add a pointer so this hog appears at i in hhs + end + end + + end + +end + + +----------------- +-- RACER METHODS +----------------- + +function CheckWaypoints() + + trackFinished = true + + for i = 0, (wpCount-1) do + + g1X, g1Y = GetGearPosition(CurrentHedgehog) + g2X, g2Y = wpX[i], wpY[i] + + g1X = g1X - g2X + g1Y = g1Y - g2Y + dist = (g1X*g1X) + (g1Y*g1Y) + + --if i == 0 then + -- AddCaption(dist .. "/" .. (wpRad*wpRad) ) + --end + + NR = (48/100*wpRad)/2 + + if dist < (NR*NR) then + --if dist < (wpRad*wpRad) then + --AddCaption("howdy") + wpActive[i] = true + wpCol[i] = GetClanColor(GetHogClan(CurrentHedgehog)) -- new --GetClanColor(1) + SetVisualGearValues(wpCirc[i], wpX[i], wpY[i], 20, 100, 1, 10, 0, wpRad, 5, wpCol[i]) + + wpRem = 0 + for k = 0, (wpCount-1) do + if wpActive[k] == false then + wpRem = wpRem + 1 + end + end + + AddCaption(loc("Way-Points Remaining") .. ": " .. wpRem,0xffba00ff,capgrpAmmoinfo) + + end + + if wpActive[i] == false then + trackFinished = false + end + + end + + return(trackFinished) + +end + +function AdjustScores() + + if bestTime == nil then + bestTime = 100000 + bestClan = 10 + bestTimeComment = "N/A" + end + + newScore = false + + -- update this clan's time if the new track is better + for i = 0, (numTeams-1) do + if teamClan[i] == GetHogClan(CurrentHedgehog) then + if trackTime < teamScore[i] then + teamScore[i] = trackTime + newScore = true + else + newScore = false + end + end + end + + --bestTime = 100000 + --bestClan = 10 + + -- find the best time out of those so far + for i = 0, (numTeams-1) do + if teamScore[i] < bestTime then + bestTime = teamScore[i] + bestClan = teamClan[i] + end + end + + if bestTime ~= 100000 then + bestTimeComment = (bestTime/1000) ..loc("s") + end + + if newScore == true then + if trackTime == bestTime then -- best time of the race + ShowMission(loc("RACER"), + loc("TRACK COMPLETED"), + loc("NEW RACE RECORD: ") .. (trackTime/1000) ..loc("s") .. "|" .. + loc("WINNING TIME: ") .. bestTimeComment, 0, 4000) + PlaySound(sndHomerun) + else -- best time for the clan + ShowMission(loc("RACER"), + loc("TRACK COMPLETED"), + loc("NEW CLAN RECORD: ") .. (trackTime/1000) ..loc("s") .. "|" .. + loc("WINNING TIME: ") .. bestTimeComment, 4, 4000) + end + else -- not any kind of new score + ShowMission(loc("RACER"), + loc("TRACK COMPLETED"), + loc("TIME: ") .. (trackTime/1000) ..loc("s") .. "|" .. + loc("WINNING TIME: ") .. bestTimeComment, -amSkip, 4000) + PlaySound(sndHellish) + end + + + -------- + --new + -------- + + if bestTime == trackTime then + --AddCaption("wooooooooooooooooooooooooooooo") + + fastColour = GetClanColor(GetHogClan(CurrentHedgehog)) + + for i = 0, (currCount-1) do + fastX[i] = currX[i] + fastY[i] = currY[i] + end + + fastCount = currCount + fastIndex = 0 + + --currCount = 0 -- is this needed? + + else + currCount = 0 + fastIndex = 0 + end + + +end + +function onNewRound() + + roundNumber = roundNumber + 1 + + totalComment = "" + for i = 0, (TeamsCount-1) do + if teamNameArr[i] ~= " " then -- teamScore[teamClan[i]] + teamComment[i] = teamNameArr[i] .. ": " .. (teamScore[i]/1000) .. loc("s|") + totalComment = totalComment .. teamComment[i] + elseif teamNameArr[i] == " " then + teamComment[i] = "|" + end + end + + ShowMission( loc("RACER"), + loc("STATUS UPDATE"), + loc("Rounds Complete: ") .. roundNumber .. "/" .. roundLimit .. "|" .. " " .. "|" .. + loc("Best Team Times: ") .. "|" .. totalComment, 0, 4000) + + -- end game if its at round limit + if roundNumber == roundLimit then + for i = 0, (numhhs-1) do + if GetHogClan(hhs[i]) ~= bestClan then + SetEffect(hhs[i], heResurrectable, 0) + SetHealth(hhs[i],0) + end + end + gameOver = true + TurnTimeLeft = 1 + end + +end + +function CheckForNewRound() + + ------------- + ------ new + ------------- + + --[[turnN = turnN + 1 + if gameBegun == false then + if turnN == 2 then + for i = 0, (numhhs-1) do + if hhs[i] ~= nil then + SetEffect(hhs[i], heResurrectable, 0) + SetHealth(hhs[i],0) + end + end + gameOver = true + TurnTimeLeft = 1 + end + else + + + end]] + + --[[if roundBegun == true then + + if RoundHasChanged == true then + roundN = roundN + 1 + RoundHasChanged = false + onNewRound() + end + + if lastRound ~= TotalRounds then -- new round, but not really + + if RoundHasChanged == false then + RoundHasChanged = true + end + + end + + AddCaption("RoundN:" .. roundN .. "; " .. "TR: " .. TotalRounds) + + lastRound = TotalRounds + + end]] + + ------------ + ----- old + ------------ + + if GetHogClan(CurrentHedgehog) == firstClan then + onNewRound() + end + +end + +function DisableTumbler() + currCount = 0 + fastIndex = 0 + TurnTimeLeft = 0 + racerActive = false -- newadd +end + +function HandleGhost() + + -- get the current xy of the racer at this point + currX[currCount] = GetX(CurrentHedgehog) + currY[currCount] = GetY(CurrentHedgehog) + currCount = currCount + 1 + + -- draw a ping of smoke where the fastest player was at this point + if (fastCount ~= 0) and (fastIndex < fastCount) then + + fastIndex = fastIndex + 1 + + tempE = AddVisualGear(fastX[fastIndex], fastY[fastIndex], vgtSmoke, 0, false) + g1, g2, g3, g4, g5, g6, g7, g8, g9, g10 = GetVisualGearValues(tempE) + SetVisualGearValues(tempE, g1, g2, g3, g4, g5, g6, g7, g8, g9, fastColour ) + + --AddCaption("fC: " .. fastIndex .. " / " .. fastCount) + + else + + --AddCaption("excep fC: " .. fastIndex .. " / " .. fastCount) + + end + + + +end + +function TryRepositionHogs() + + if MapHasBorder() == true then + + for i = 0, (numhhs-1) do + if hhs[i] ~= nil then + SetGearPosition(hhs[i],GetX(hhs[i]), TopY-10) + end + end + + end + +end + +---------------------------------- +-- GAME METHODS / EVENT HANDLERS +---------------------------------- + +function onGameInit() + GameFlags = bor(GameFlags,gfInfAttack + gfInvulnerable) + CaseFreq = 0 + TurnTime = 90000 + WaterRise = 0 +end + + +function onGameStart() + + roundN = 0 + lastRound = TotalRounds + RoundHasChanged = false -- true + + for i = 0, (specialPointsCount-1) do + PlaceWayPoint(specialPointsX[i], specialPointsY[i]) + end + + RebuildTeamInfo() + + ShowMission ( + loc("RACER"), + loc("a Hedgewars mini-game"), + + loc("Build a track and race.") .. "|" .. + loc("Round Limit:") .. " " .. roundLimit .. "|" .. + + "", 4, 4000 + ) + + TryRepositionHogs() + +end + +function PlaceWayPoint(x,y) + + if (wpCount < wpLimit) then -- seems to not work with a hedgehog nil chek + + wpX[wpCount] = x + wpY[wpCount] = y + wpCol[wpCount] = 0xffffffff + wpCirc[wpCount] = AddVisualGear(wpX[wpCount],wpY[wpCount],vgtCircle,0,true) + --100 + SetVisualGearValues(wpCirc[wpCount], wpX[wpCount], wpY[wpCount], 20, 100, 1, 10, 0, wpRad, 5, wpCol[wpCount]) + + wpCount = wpCount + 1 + + AddCaption(loc("Waypoint placed.") .. " " .. loc("Available points remaining: ") .. (wpLimit-wpCount)) + + end + +end + +function onSpecialPoint(x,y,flag) + specialPointsX[specialPointsCount] = x + specialPointsY[specialPointsCount] = y + specialPointsCount = specialPointsCount + 1 +end + +function onNewTurn() + + CheckForNewRound() + TryRepositionHogs() + + racerActive = false + + trackTime = 0 + + currCount = 0 -- hopefully this solves problem + AddAmmo(CurrentHedgehog, amAirAttack, 0) + gTimer = 0 + + -- Set the waypoints to unactive on new round + for i = 0,(wpCount-1) do + wpActive[i] = false + wpCol[i] = 0xffffffff + SetVisualGearValues(wpCirc[i], wpX[i], wpY[i], 20, 100, 1, 10, 0, wpRad, 5, wpCol[i]) + end + + -- Handle Starting Stage of Game + if (gameOver == false) and (gameBegun == false) then + if wpCount >= 3 then + gameBegun = true + roundNumber = 0 + firstClan = GetHogClan(CurrentHedgehog) + ShowMission(loc("RACER"), + loc("GAME BEGUN!!!"), + loc("Complete the track as fast as you can!"), 2, 4000) + else + ShowMission(loc("RACER"), + loc("NOT ENOUGH WAYPOINTS"), + loc("Place more waypoints using the 'Air Attack' weapon."), 2, 4000) + AddAmmo(CurrentHedgehog, amAirAttack, 4000) + ParseCommand("setweap " .. string.char(amAirAttack)) + end + end + + if gameOver == true then + gameBegun = false + racerActive = false -- newadd + end + + AddAmmo(CurrentHedgehog, amTardis, 0) + AddAmmo(CurrentHedgehog, amDrillStrike, 0) + AddAmmo(CurrentHedgehog, amMineStrike, 0) + AddAmmo(CurrentHedgehog, amNapalm, 0) + AddAmmo(CurrentHedgehog, amPiano, 0) + +end + +function onGameTick20() + + -- airstrike detected, convert this into a potential waypoint spot + if cGear ~= nil then + x,y = GetGearPosition(cGear) + if x > -9000 then + x,y = GetGearTarget(cGear) + + + if TestRectForObstacle(x-20, y-20, x+20, y+20, true) then + AddCaption(loc("Please place the way-point in the open, within the map boundaries.")) + PlaySound(sndDenied) + elseif (y > WaterLine-50) then + AddCaption(loc("Please place the way-point further from the waterline.")) + PlaySound(sndDenied) + else + PlaceWayPoint(x, y) + if wpCount == wpLimit then + AddCaption(loc("Race complexity limit reached.")) + DisableTumbler() + end + end + else + DeleteGear(cGear) + end + SetGearPosition(cGear, -10000, 0) + end + + + -- start the player tumbling with a boom once their turn has actually begun + if racerActive == false then + + if (TurnTimeLeft > 0) and (TurnTimeLeft ~= TurnTime) then + + -- if the gamehas started put the player in the middle of the first + --waypoint that was placed + if gameBegun == true then + AddCaption(loc("Good to go!")) + racerActive = true + trackTime = 0 + + SetGearPosition(CurrentHedgehog, wpX[0], wpY[0]) + AddGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), gtGrenade, 0, 0, 0, 1) + FollowGear(CurrentHedgehog) + + HideMission() + + else + -- still in placement mode + end + + end + end + + + + -- has the player started his tumbling spree? + if (CurrentHedgehog ~= nil) then + + --airstrike conversion used to be here + + -- if the RACE has started, show tracktimes and keep tabs on waypoints + if (racerActive == true) and (gameBegun == true) then + + --ghost + if GameTime%40 == 0 then + HandleGhost() + end + + trackTime = trackTime + 20 + + if GameTime%100 == 0 then + + if trackTime%1000 == 0 then + AddCaption((trackTime/1000)..'.0',GetClanColor(GetHogClan(CurrentHedgehog)),capgrpMessage2) + else + AddCaption(trackTime/1000,GetClanColor(GetHogClan(CurrentHedgehog)),capgrpMessage2) + end + + if (CheckWaypoints() == true) then + AdjustScores() + racerActive = false + DisableTumbler() + end + + end + + end + + -- if the player has expended his tunbling time, stop him tumbling + if TurnTimeLeft <= 20 then + DisableTumbler() + end + + end + +end + +function onGearResurrect(gear) + + AddVisualGear(GetX(gear), GetY(gear), vgtBigExplosion, 0, false) + + if gear == CurrentHedgehog then + DisableTumbler() + end + +end + +function onGearAdd(gear) + + if GetGearType(gear) == gtHedgehog then + hhs[numhhs] = gear + numhhs = numhhs + 1 + SetEffect(gear, heResurrectable, 1) + end + + if GetGearType(gear) == gtAirAttack then + cGear = gear + end + +end + +function onGearDelete(gear) + + if GetGearType(gear) == gtAirAttack then + cGear = nil + end + +end diff -r 4feced261c68 -r de822cd3df3a share/hedgewars/Data/Themes/Golf/theme.cfg --- a/share/hedgewars/Data/Themes/Golf/theme.cfg Tue Jan 21 22:38:13 2014 +0100 +++ b/share/hedgewars/Data/Themes/Golf/theme.cfg Tue Jan 21 22:43:06 2014 +0100 @@ -1,23 +1,23 @@ -sky = 34, 67, 135 -border = 38, 114, 35 -water-top = 72, 105, 127 -water-bottom = 37, 76, 91 -water-opacity = 128 -music = Golf.ogg -clouds = 9 -object = Hole, 2, 0, 31, 123, 1, 1, 31, 0, 40, 27 -object = Car, 1, 78, 320, 80, 30, 1, 0, 0, 330, 220 -object = Club, 3, 180, 175, 5, 1, 2, 189, 155, 15, 20, 0, 0, 100, 100 -object = Club2, 1, 126, 26, 1, 1, 2, 0, 0, 20, 30, 240, 23, 15, 10 -object = Flag1, 1, 0, 305, 15, 5, 1, 20, 0, 103, 260 -object = Flag2, 1, 40, 305, 10, 4, 1, 0, 0, 53, 270 -object = Flag3, 1, 0, 280, 12, 7, 1, 30, 0, 112, 260 -object = Flag4, 1, 275, 145, 8, 12, 1, 0, 0, 250, 158 -object = Tee, 2, 6, 20, 2, 2, 1, 0, 0, 12, 15 -object = Ball, 4, 8, 15, 2, 1, 1, 0, 0, 16, 8 -object = Ball, 3, 0, 0, 6, 16, 1, 10, 0, 6, 16 -object = Ball, 3, 10, 0, 6, 16, 1, 0, 0, 6, 16 -object = Bag, 1, 65, 0, 129, 44, 1, 0, 71, 234, 81 -spray = Balldirt, 5 -flakes = 55, 40, 99999999, 30, 200 - +sky = 34, 67, 135 +border = 38, 114, 35 +water-top = 72, 105, 127 +water-bottom = 37, 76, 91 +water-opacity = 128 +music = Golf.ogg +clouds = 9 +object = Hole, 2, 0, 31, 123, 1, 1, 31, 0, 40, 27 +object = Car, 1, 78, 320, 80, 30, 1, 0, 0, 330, 220 +object = Club, 3, 180, 175, 5, 1, 2, 189, 155, 15, 20, 0, 0, 100, 100 +object = Club2, 1, 126, 26, 1, 1, 2, 0, 0, 20, 30, 240, 23, 15, 10 +object = Flag1, 1, 0, 305, 15, 5, 1, 20, 0, 103, 260 +object = Flag2, 1, 40, 305, 10, 4, 1, 0, 0, 53, 270 +object = Flag3, 1, 0, 280, 12, 7, 1, 30, 0, 112, 260 +object = Flag4, 1, 275, 145, 8, 12, 1, 0, 0, 250, 158 +object = Tee, 2, 6, 20, 2, 2, 1, 0, 0, 12, 15 +object = Ball, 4, 8, 15, 2, 1, 1, 0, 0, 16, 8 +object = Ball, 3, 0, 0, 6, 16, 1, 10, 0, 6, 16 +object = Ball, 3, 10, 0, 6, 16, 1, 0, 0, 6, 16 +object = Bag, 1, 65, 0, 129, 44, 1, 0, 71, 234, 81 +spray = Balldirt, 5 +flakes = 55, 40, 99999999, 30, 200 + diff -r 4feced261c68 -r de822cd3df3a tools/build_windows.bat --- a/tools/build_windows.bat Tue Jan 21 22:38:13 2014 +0100 +++ b/tools/build_windows.bat Tue Jan 21 22:43:06 2014 +0100 @@ -1,65 +1,65 @@ -@echo off -::edit these variables if you need -set PASCAL=C:\FPC\2.6.0\bin\i386-win32\ -set QTDIR=C:\QtSDK\Desktop\Qt\4.7.4\mingw\bin -set PATH=%PATH%;%PASCAL% -set BUILD_TYPE="Debug" - -:setup -set CURRDIR="%CD%" -cd .. - -echo Fetching all DLLs... -if %BUILD_TYPE%=="Debug" ( - for %%G in (QtCored4 QtGuid4 QtNetworkd4) do xcopy /d/y %QTDIR%\%%G.dll %CD%\bin\ -) -:: should you libgcc dynamically you should try adding libgcc_s_dw2-1 and mingwm10 -for %%G in (QtCore4 QtGui4 QtNetwork4) do ( - xcopy /d/y %QTDIR%\%%G.dll %CD%\bin\ -) - -if not exist %CD%\misc\winutils\bin\ mkdir %CD%\misc\winutils\bin\ -if not exist %CD%\misc\winutils\bin\SDL.dll cscript %CD%\tools\w32DownloadUnzip.vbs http://www.libsdl.org/release/SDL-1.2.15-win32.zip %CD%\misc\winutils\bin -if not exist %CD%\misc\winutils\bin\SDL_image.dll cscript %CD%\tools\w32DownloadUnzip.vbs http://www.libsdl.org/projects/SDL_image/release/SDL_image-1.2.12-win32.zip %CD%\misc\winutils\bin -if not exist %CD%\misc\winutils\bin\SDL_net.dll cscript %CD%\tools\w32DownloadUnzip.vbs http://www.libsdl.org/projects/SDL_net/release/SDL_net-1.2.8-win32.zip %CD%\misc\winutils\bin -if not exist %CD%\misc\winutils\bin\SDL_mixer.dll cscript %CD%\tools\w32DownloadUnzip.vbs http://www.libsdl.org/projects/SDL_mixer/release/SDL_mixer-1.2.12-win32.zip %CD%\misc\winutils\bin -if not exist %CD%\misc\winutils\bin\SDL_ttf.dll cscript %CD%\tools\w32DownloadUnzip.vbs http://www.libsdl.org/projects/SDL_ttf/release/SDL_ttf-2.0.11-win32.zip %CD%\misc\winutils\bin - -::for video recording -if not exist %CD%\misc\winutils\bin\avformat-54.dll cscript %CD%\tools\w32DownloadUnzip.vbs http://hedgewars.googlecode.com/files/libav-win32-20121022-dll.zip %CD%\misc\winutils\bin -if not exist %CD%\misc\winutils\bin\glut32.dll cscript %CD%\tools\w32DownloadUnzip.vbs https://user.xmission.com/~nate/glut/glut-3.7.6-bin.zip %CD%\misc\winutils\bin -copy /y %CD%\misc\winutils\bin\glut-3.7.6-bin\glut32.dll %CD%\misc\winutils\bin\glut32.dll - -::this is needed because fpc png unit hardcodes libpng-1.2.12 -if not exist %CD%\misc\winutils\bin\libpng13.dll copy /y %CD%\misc\winutils\bin\libpng15-15.dll %CD%\misc\winutils\bin\libpng13.dll - -xcopy /d/y %CD%\misc\winutils\bin\*.dll %CD%\bin\ - -::setting up the environment... -call %QTDIR%\qtenv2.bat - -echo Running cmake... -set ERRORLEVEL= -cmake . -G "MinGW Makefiles" -DPNG_LIBRARY="%CD%\misc\winutils\bin\libpng13.dll" -DCMAKE_BUILD_TYPE="%BUILD_TYPE%" -DCMAKE_PREFIX_PATH="%CD%\misc\winutils\\" -:: prefix should be last - -if %ERRORLEVEL% NEQ 0 goto exitpoint - -echo Running make... -set ERRORLEVEL= -mingw32-make VERBOSE=1 -if %ERRORLEVEL% NEQ 0 goto exitpoint - -echo Installing... -set ERRORLEVEL= -mingw32-make install > nul -if %ERRORLEVEL% NEQ 0 goto exitpoint - -echo Creating commodity shortcut... -copy /y %CD%\misc\winutils\Hedgewars.lnk C:%HOMEPATH%\Desktop\Hedgewars.lnk - -echo ALL DONE, Hedgewars has been successfully compiled and installed - -:exitpoint -cd %CURRDIR% -pause +@echo off +::edit these variables if you need +set PASCAL=C:\FPC\2.6.0\bin\i386-win32\ +set QTDIR=C:\QtSDK\Desktop\Qt\4.7.4\mingw\bin +set PATH=%PATH%;%PASCAL% +set BUILD_TYPE="Debug" + +:setup +set CURRDIR="%CD%" +cd .. + +echo Fetching all DLLs... +if %BUILD_TYPE%=="Debug" ( + for %%G in (QtCored4 QtGuid4 QtNetworkd4) do xcopy /d/y %QTDIR%\%%G.dll %CD%\bin\ +) +:: should you libgcc dynamically you should try adding libgcc_s_dw2-1 and mingwm10 +for %%G in (QtCore4 QtGui4 QtNetwork4) do ( + xcopy /d/y %QTDIR%\%%G.dll %CD%\bin\ +) + +if not exist %CD%\misc\winutils\bin\ mkdir %CD%\misc\winutils\bin\ +if not exist %CD%\misc\winutils\bin\SDL.dll cscript %CD%\tools\w32DownloadUnzip.vbs http://www.libsdl.org/release/SDL-1.2.15-win32.zip %CD%\misc\winutils\bin +if not exist %CD%\misc\winutils\bin\SDL_image.dll cscript %CD%\tools\w32DownloadUnzip.vbs http://www.libsdl.org/projects/SDL_image/release/SDL_image-1.2.12-win32.zip %CD%\misc\winutils\bin +if not exist %CD%\misc\winutils\bin\SDL_net.dll cscript %CD%\tools\w32DownloadUnzip.vbs http://www.libsdl.org/projects/SDL_net/release/SDL_net-1.2.8-win32.zip %CD%\misc\winutils\bin +if not exist %CD%\misc\winutils\bin\SDL_mixer.dll cscript %CD%\tools\w32DownloadUnzip.vbs http://www.libsdl.org/projects/SDL_mixer/release/SDL_mixer-1.2.12-win32.zip %CD%\misc\winutils\bin +if not exist %CD%\misc\winutils\bin\SDL_ttf.dll cscript %CD%\tools\w32DownloadUnzip.vbs http://www.libsdl.org/projects/SDL_ttf/release/SDL_ttf-2.0.11-win32.zip %CD%\misc\winutils\bin + +::for video recording +if not exist %CD%\misc\winutils\bin\avformat-54.dll cscript %CD%\tools\w32DownloadUnzip.vbs http://hedgewars.googlecode.com/files/libav-win32-20121022-dll.zip %CD%\misc\winutils\bin +if not exist %CD%\misc\winutils\bin\glut32.dll cscript %CD%\tools\w32DownloadUnzip.vbs https://user.xmission.com/~nate/glut/glut-3.7.6-bin.zip %CD%\misc\winutils\bin +copy /y %CD%\misc\winutils\bin\glut-3.7.6-bin\glut32.dll %CD%\misc\winutils\bin\glut32.dll + +::this is needed because fpc png unit hardcodes libpng-1.2.12 +if not exist %CD%\misc\winutils\bin\libpng13.dll copy /y %CD%\misc\winutils\bin\libpng15-15.dll %CD%\misc\winutils\bin\libpng13.dll + +xcopy /d/y %CD%\misc\winutils\bin\*.dll %CD%\bin\ + +::setting up the environment... +call %QTDIR%\qtenv2.bat + +echo Running cmake... +set ERRORLEVEL= +cmake . -G "MinGW Makefiles" -DPNG_LIBRARY="%CD%\misc\winutils\bin\libpng13.dll" -DCMAKE_BUILD_TYPE="%BUILD_TYPE%" -DCMAKE_PREFIX_PATH="%CD%\misc\winutils\\" +:: prefix should be last + +if %ERRORLEVEL% NEQ 0 goto exitpoint + +echo Running make... +set ERRORLEVEL= +mingw32-make VERBOSE=1 +if %ERRORLEVEL% NEQ 0 goto exitpoint + +echo Installing... +set ERRORLEVEL= +mingw32-make install > nul +if %ERRORLEVEL% NEQ 0 goto exitpoint + +echo Creating commodity shortcut... +copy /y %CD%\misc\winutils\Hedgewars.lnk C:%HOMEPATH%\Desktop\Hedgewars.lnk + +echo ALL DONE, Hedgewars has been successfully compiled and installed + +:exitpoint +cd %CURRDIR% +pause diff -r 4feced261c68 -r de822cd3df3a tools/w32DownloadUnzip.vbs --- a/tools/w32DownloadUnzip.vbs Tue Jan 21 22:38:13 2014 +0100 +++ b/tools/w32DownloadUnzip.vbs Tue Jan 21 22:43:06 2014 +0100 @@ -1,66 +1,66 @@ -' w32DownloadUnzip.vbs -' Download a zipfile and uncompress it with no external tools in Windows -' -' Copyright (c) 2012, Vittorio Giovara, -' Redistribution and use is allowed according to the terms of the BSD license. -' -' References -' http://superuser.com/questions/59465/is-it-possible-to-download-using-the-windows-command-line -' http://stackoverflow.com/questions/1021557/how-to-unzip-a-file-using-the-command-line -' http://stackoverflow.com/questions/424331/get-the-current-temporary-directory-path-in-vbscript - -Set ArgObj = WScript.Arguments - -If (Wscript.Arguments.Count = 1) Then - strFileURL = ArgObj(0) - strOutputPath = CreateObject("Scripting.FileSystemObject").GetAbsolutePathName(".") -Else - If (Wscript.Arguments.Count = 2) Then - strFileURL = ArgObj(0) - strOutputPath = ArgObj(1) - Else - WScript.Echo ("Usage: csript.exe w32DownloadUnzip.vbs url output") - WScript.Quit - End if -End if - -' Temporary directory -strHDLocation = WScript.CreateObject("Scripting.FileSystemObject").GetSpecialFolder(2) + "\hwlibtemp.zip" - -' Fetch the file -WScript.Echo ( "Trying to download from " & strFileURL) -Set objXMLHTTP = CreateObject("MSXML2.XMLHTTP") -objXMLHTTP.open "GET", strFileURL, false -objXMLHTTP.send() - -If objXMLHTTP.Status = 200 Then - Set objADOStream = CreateObject("ADODB.Stream") - objADOStream.Open - objADOStream.Type = 1 'adTypeBinary - - objADOStream.Write objXMLHTTP.ResponseBody - objADOStream.Position = 0 'Set the stream position to the start - - Set objFSO = Createobject("Scripting.FileSystemObject") - If objFSO.Fileexists(strHDLocation) Then objFSO.DeleteFile strHDLocation - Set objFSO = Nothing - - objADOStream.SaveToFile strHDLocation - objADOStream.Close - Set objADOStream = Nothing - Set objXMLHTTP = Nothing -Else - WScript.Echo ("Error downloading file (error code: " & objXMLHTTP.Status & ")") - Set objXMLHTTP = Nothing - WScript.Quit -End if - -WScript.Echo ( "Extracting file to " & strOutputPath) -Set objShell = CreateObject( "Shell.Application" ) -Set objSource = objShell.NameSpace(strHDLocation).Items() -Set objTarget = objShell.NameSpace(strOutputPath) -intOptions = 16 'no user prompt -objTarget.CopyHere objSource, intOptions - -WScript.Echo ( "Success!" ) -Set objShell = Nothing +' w32DownloadUnzip.vbs +' Download a zipfile and uncompress it with no external tools in Windows +' +' Copyright (c) 2012, Vittorio Giovara, +' Redistribution and use is allowed according to the terms of the BSD license. +' +' References +' http://superuser.com/questions/59465/is-it-possible-to-download-using-the-windows-command-line +' http://stackoverflow.com/questions/1021557/how-to-unzip-a-file-using-the-command-line +' http://stackoverflow.com/questions/424331/get-the-current-temporary-directory-path-in-vbscript + +Set ArgObj = WScript.Arguments + +If (Wscript.Arguments.Count = 1) Then + strFileURL = ArgObj(0) + strOutputPath = CreateObject("Scripting.FileSystemObject").GetAbsolutePathName(".") +Else + If (Wscript.Arguments.Count = 2) Then + strFileURL = ArgObj(0) + strOutputPath = ArgObj(1) + Else + WScript.Echo ("Usage: csript.exe w32DownloadUnzip.vbs url output") + WScript.Quit + End if +End if + +' Temporary directory +strHDLocation = WScript.CreateObject("Scripting.FileSystemObject").GetSpecialFolder(2) + "\hwlibtemp.zip" + +' Fetch the file +WScript.Echo ( "Trying to download from " & strFileURL) +Set objXMLHTTP = CreateObject("MSXML2.XMLHTTP") +objXMLHTTP.open "GET", strFileURL, false +objXMLHTTP.send() + +If objXMLHTTP.Status = 200 Then + Set objADOStream = CreateObject("ADODB.Stream") + objADOStream.Open + objADOStream.Type = 1 'adTypeBinary + + objADOStream.Write objXMLHTTP.ResponseBody + objADOStream.Position = 0 'Set the stream position to the start + + Set objFSO = Createobject("Scripting.FileSystemObject") + If objFSO.Fileexists(strHDLocation) Then objFSO.DeleteFile strHDLocation + Set objFSO = Nothing + + objADOStream.SaveToFile strHDLocation + objADOStream.Close + Set objADOStream = Nothing + Set objXMLHTTP = Nothing +Else + WScript.Echo ("Error downloading file (error code: " & objXMLHTTP.Status & ")") + Set objXMLHTTP = Nothing + WScript.Quit +End if + +WScript.Echo ( "Extracting file to " & strOutputPath) +Set objShell = CreateObject( "Shell.Application" ) +Set objSource = objShell.NameSpace(strHDLocation).Items() +Set objTarget = objShell.NameSpace(strOutputPath) +intOptions = 16 'no user prompt +objTarget.CopyHere objSource, intOptions + +WScript.Echo ( "Success!" ) +Set objShell = Nothing