# HG changeset patch # User Medo # Date 1335995625 -7200 # Node ID 6af78154dc6286a2b57452ab7e22ad520d851462 # Parent 9e724f4863a338372a57e7c23fc40e2fb4b8bb3d# Parent e118ee168577bf0265f8bdd31026aa0c7fb11055 Merge diff -r 9e724f4863a3 -r 6af78154dc62 CMakeLists.txt --- a/CMakeLists.txt Sun Apr 01 15:23:34 2012 +0200 +++ b/CMakeLists.txt Wed May 02 23:53:45 2012 +0200 @@ -159,7 +159,7 @@ if(Optz) # set(pascal_compiler_flags_cmn "-O3" "-OpPENTIUM4" "-CfSSE3" "-Xs" "-Si" ${pascal_compiler_flags_cmn}) - set(pascal_compiler_flags_cmn "-Os" "-Xs" "-Si" ${pascal_compiler_flags_cmn}) + set(pascal_compiler_flags_cmn "-Os" "-Ooregvar" "-Xs" "-Si" ${pascal_compiler_flags_cmn}) set(haskell_compiler_flags_cmn "-w" "-fno-warn-unused-do-bind" ${haskell_compiler_flags_cmn}) else(Optz) set(pascal_compiler_flags_cmn "-O-" "-g" "-gl" "-gv" "-dDEBUGFILE" ${pascal_compiler_flags_cmn}) diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/CMakeLists.txt --- a/QTfrontend/CMakeLists.txt Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/CMakeLists.txt Wed May 02 23:53:45 2012 +0200 @@ -119,6 +119,7 @@ HWApplication.h hwform.h team.h + util/DataManager.h ) set(hwfr_hdrs diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/CocoaInitializer.h --- a/QTfrontend/CocoaInitializer.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/CocoaInitializer.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2005-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/CocoaInitializer.mm --- a/QTfrontend/CocoaInitializer.mm Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/CocoaInitializer.mm Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2005-2011 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/HWApplication.cpp --- a/QTfrontend/HWApplication.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/HWApplication.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2005-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/HWApplication.h --- a/QTfrontend/HWApplication.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/HWApplication.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2005-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/InstallController.cpp --- a/QTfrontend/InstallController.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/InstallController.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2009-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/InstallController.h --- a/QTfrontend/InstallController.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/InstallController.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2009-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/KB.h --- a/QTfrontend/KB.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/KB.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/M3Panel.h --- a/QTfrontend/M3Panel.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/M3Panel.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2009-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/M3Panel.mm --- a/QTfrontend/M3Panel.mm Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/M3Panel.mm Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2009-2011 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/SparkleAutoUpdater.mm --- a/QTfrontend/SparkleAutoUpdater.mm Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/SparkleAutoUpdater.mm Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2005-2011 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/achievements.cpp --- a/QTfrontend/achievements.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/achievements.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2005-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/achievements.h --- a/QTfrontend/achievements.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/achievements.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2005-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/binds.cpp --- a/QTfrontend/binds.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/binds.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2005-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/binds.h --- a/QTfrontend/binds.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/binds.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2005-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/drawmapscene.cpp --- a/QTfrontend/drawmapscene.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/drawmapscene.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 @@ -31,19 +31,28 @@ DrawMapScene::DrawMapScene(QObject *parent) : QGraphicsScene(parent), m_pen(Qt::yellow), - m_brush(Qt::yellow) + m_brush(Qt::yellow), + m_cursor(new QGraphicsEllipseItem(-0.5, -0.5, 1, 1)) { setSceneRect(0, 0, 4096, 2048); QLinearGradient gradient(0, 0, 0, 2048); gradient.setColorAt(0, QColor(60, 60, 155)); gradient.setColorAt(1, QColor(155, 155, 60)); - setBackgroundBrush(QBrush(gradient)); + + m_eraser = QBrush(gradient); + setBackgroundBrush(m_eraser); + m_isErasing = false; m_pen.setWidth(76); m_pen.setJoinStyle(Qt::RoundJoin); m_pen.setCapStyle(Qt::RoundCap); m_currPath = 0; + + m_isCursorShown = false; + m_cursor->setPen(QPen(Qt::green)); + m_cursor->setZValue(1); + m_cursor->setScale(m_pen.width()); } void DrawMapScene::mouseMoveEvent(QGraphicsSceneMouseEvent * mouseEvent) @@ -62,12 +71,16 @@ else { path.lineTo(mouseEvent->scenePos()); - paths.first().second.append(mouseEvent->scenePos().toPoint()); + paths.first().points.append(mouseEvent->scenePos().toPoint()); } m_currPath->setPath(path); emit pathChanged(); } + + if(!m_isCursorShown) + showCursor(); + m_cursor->setPos(mouseEvent->scenePos()); } void DrawMapScene::mousePressEvent(QGraphicsSceneMouseEvent * mouseEvent) @@ -79,7 +92,12 @@ p += QPointF(0.01, 0.01); path.moveTo(p); path.lineTo(mouseEvent->scenePos()); - paths.prepend(qMakePair(serializePenWidth(m_pen.width()), QList() << mouseEvent->scenePos().toPoint())); + + PathParams params; + params.width = serializePenWidth(m_pen.width()); + params.erasing = m_isErasing; + params.points = QList() << mouseEvent->scenePos().toPoint(); + paths.prepend(params); m_currPath->setPath(path); emit pathChanged(); @@ -91,7 +109,7 @@ { QPainterPath path = m_currPath->path(); path.lineTo(mouseEvent->scenePos()); - paths.first().second.append(mouseEvent->scenePos().toPoint()); + paths.first().points.append(mouseEvent->scenePos().toPoint()); m_currPath->setPath(path); simplifyLast(); @@ -107,15 +125,39 @@ else if(wheelEvent->delta() < 0 && m_pen.width() >= 16) m_pen.setWidth(m_pen.width() - 10); + m_cursor->setScale(m_pen.width()); + if(m_currPath) { m_currPath->setPen(m_pen); - paths.first().first = serializePenWidth(m_pen.width()); + paths.first().width = serializePenWidth(m_pen.width()); } } +void DrawMapScene::showCursor() +{ + qDebug() << "show cursor"; + if(!m_isCursorShown) + addItem(m_cursor); + + m_isCursorShown = true; +} + +void DrawMapScene::hideCursor() +{ + qDebug() << "hide cursor"; + if(m_isCursorShown) + removeItem(m_cursor); + + m_isCursorShown = false; +} + void DrawMapScene::undo() { + // cursor is a part of items() + if(m_isCursorShown) + return; + if(items().size()) { removeItem(items().first()); @@ -135,6 +177,10 @@ void DrawMapScene::clearMap() { + // cursor is a part of items() + if(m_isCursorShown) + return; + // don't clear if already cleared if(!items().size()) return; @@ -155,6 +201,16 @@ emit pathChanged(); } + +void DrawMapScene::setErasing(bool erasing) +{ + m_isErasing = erasing; + if(erasing) + m_pen.setBrush(m_eraser); + else + m_pen.setBrush(m_brush); +} + QByteArray DrawMapScene::encode() { QByteArray b; @@ -162,13 +218,14 @@ for(int i = paths.size() - 1; i >= 0; --i) { int cnt = 0; - QPair > points = paths.at(i); - foreach(QPoint point, points.second) + PathParams params = paths.at(i); + foreach(QPoint point, params.points) { qint16 px = qToBigEndian((qint16)point.x()); qint16 py = qToBigEndian((qint16)point.y()); quint8 flags = 0; - if(!cnt) flags = 0x80 + points.first; + if(!cnt) flags = 0x80 + params.width; + if(params.erasing) flags |= 0x40; b.append((const char *)&px, 2); b.append((const char *)&py, 2); b.append((const char *)&flags, 1); @@ -183,12 +240,14 @@ void DrawMapScene::decode(QByteArray data) { + bool erasing = m_isErasing; + oldItems.clear(); oldPaths.clear(); clear(); paths.clear(); - QPair > points; + PathParams params; while(data.size() >= 5) { @@ -201,37 +260,43 @@ if(flags & 0x80) { - if(points.second.size()) + if(params.points.size()) { - addPath(pointsToPath(points.second), m_pen); + addPath(pointsToPath(params.points), m_pen); - paths.prepend(points); + paths.prepend(params); - points.second.clear(); + params.points.clear(); } - quint8 penWidth = flags & 0x7f; + quint8 penWidth = flags & 0x3f; m_pen.setWidth(deserializePenWidth(penWidth)); - points.first = penWidth; + if(flags & 0x40) + m_pen.setBrush(m_eraser); + else + m_pen.setBrush(m_brush); + params.width = penWidth; } - points.second.append(QPoint(px, py)); + params.points.append(QPoint(px, py)); } - if(points.second.size()) + if(params.points.size()) { - addPath(pointsToPath(points.second), m_pen); - paths.prepend(points); + addPath(pointsToPath(params.points), m_pen); + paths.prepend(params); } emit pathChanged(); + + setErasing(erasing); } void DrawMapScene::simplifyLast() { if(!paths.size()) return; - QList points = paths.at(0).second; + QList points = paths.at(0).points; QPoint prevPoint = points.first(); int i = 1; @@ -248,18 +313,27 @@ } } - paths[0].second = points; + paths[0].points = points; // redraw path { - QGraphicsPathItem * pathItem = static_cast(items()[0]); - pathItem->setPath(pointsToPath(paths[0].second)); + QGraphicsPathItem * pathItem = static_cast(items()[m_isCursorShown ? 1 : 0]); + pathItem->setPath(pointsToPath(paths[0].points)); } emit pathChanged(); } +int DrawMapScene::pointsCount() +{ + int cnt = 0; + foreach(PathParams p, paths) + cnt += p.points.size(); + + return cnt; +} + QPainterPath DrawMapScene::pointsToPath(const QList points) { QPainterPath path; diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/drawmapscene.h --- a/QTfrontend/drawmapscene.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/drawmapscene.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 @@ -21,10 +21,18 @@ #include #include +#include class QGraphicsPathItem; -typedef QList > > Paths; +struct PathParams +{ + quint8 width; + bool erasing; + QList points; +}; + +typedef QList Paths; class DrawMapScene : public QGraphicsScene { @@ -34,6 +42,7 @@ QByteArray encode(); void decode(QByteArray data); + int pointsCount(); signals: void pathChanged(); @@ -42,14 +51,21 @@ void undo(); void clearMap(); void simplifyLast(); + void setErasing(bool erasing); + void showCursor(); + void hideCursor(); private: QPen m_pen; + QBrush m_eraser; QBrush m_brush; QGraphicsPathItem * m_currPath; Paths paths; Paths oldPaths; + bool m_isErasing; QList oldItems; + QGraphicsEllipseItem * m_cursor; + bool m_isCursorShown; virtual void mouseMoveEvent(QGraphicsSceneMouseEvent * mouseEvent); virtual void mousePressEvent(QGraphicsSceneMouseEvent * mouseEvent); diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/game.cpp --- a/QTfrontend/game.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/game.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2005-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 @@ -115,10 +115,11 @@ void HWGame::SendQuickConfig() { QByteArray teamscfg; + ThemeModel * themeModel = DataManager::instance().themeModel(); HWProto::addStringToBuffer(teamscfg, "TL"); HWProto::addStringToBuffer(teamscfg, QString("etheme %1") - .arg((themesModel->rowCount() > 0) ? themesModel->index(rand() % themesModel->rowCount()).data().toString() : "steel")); + .arg((themeModel->rowCount() > 0) ? themeModel->index(rand() % themeModel->rowCount()).data().toString() : "steel")); HWProto::addStringToBuffer(teamscfg, "eseed " + QUuid::createUuid().toString()); HWTeam team1; diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/game.h --- a/QTfrontend/game.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/game.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2005-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/gameuiconfig.cpp --- a/QTfrontend/gameuiconfig.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/gameuiconfig.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 @@ -41,6 +41,11 @@ //Form->resize(value("frontend/width", 640).toUInt(), value("frontend/height", 450).toUInt()); resizeToConfigValues(); + reloadValues(); +} + +void GameUIConfig::reloadValues(void) +{ Form->ui.pageOptions->WeaponTooltip->setChecked(value("misc/weaponTooltips", true).toBool()); int t = Form->ui.pageOptions->CBResolution->findText(value("video/resolution").toString()); @@ -68,11 +73,18 @@ QString netNick = value("net/nick", "").toString(); Form->ui.pageOptions->editNetNick->setText(netNick); + bool savePwd = value("net/savepassword",true).toBool(); + Form->ui.pageOptions->CBSavePassword->setChecked(savePwd); Form->ui.pageOptions->editNetPassword->installEventFilter(this); int passLength = value("net/passwordlength", 0).toInt(); setNetPasswordLength(passLength); + if (savePwd == false) { + Form->ui.pageOptions->editNetPassword->setEnabled(savePwd); + Form->ui.pageOptions->editNetPassword->setText(""); + setNetPasswordLength(0); + } delete netHost; netHost = new QString(value("net/ip", "").toString()); @@ -149,11 +161,12 @@ setValue("audio/volume", Form->ui.pageOptions->volumeBox->value()); setValue("net/nick", netNick()); - if (netPasswordIsValid()) + if (netPasswordIsValid() && Form->ui.pageOptions->CBSavePassword->isChecked()) { setValue("net/passwordhash", netPasswordHash()); setValue("net/passwordlength", netPasswordLength()); } + setValue("net/savepassword", Form->ui.pageOptions->CBSavePassword->isChecked()); setValue("net/ip", *netHost); setValue("net/port", netPort); setValue("net/servername", Form->ui.pageNetServer->leServerDescr->text()); diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/gameuiconfig.h --- a/QTfrontend/gameuiconfig.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/gameuiconfig.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 @@ -64,6 +64,7 @@ bool isAutoUpdateEnabled(); #endif #endif + void reloadValues(void); signals: void frontendFullscreen(bool value); diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/hwconsts.cpp.in --- a/QTfrontend/hwconsts.cpp.in Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/hwconsts.cpp.in Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2007-2011 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 @@ -27,10 +27,6 @@ QDir * cfgdir = new QDir(); QDir * datadir = new QDir(); -ThemesModel * themesModel; -QStringList * mapList; -QStringList * scriptList; - bool custom_config = false; bool custom_data = false; diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/hwconsts.h --- a/QTfrontend/hwconsts.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/hwconsts.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2005-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 @@ -22,7 +22,6 @@ #include #include -#include "themesmodel.h" extern QString * cProtoVer; extern QString * cVersionString; @@ -41,10 +40,6 @@ class QStringListModel; -extern ThemesModel * themesModel; -extern QStringList * mapList; -extern QStringList * scriptList; - extern QString * cDefaultAmmoStore; extern int cAmmoNumber; extern QList< QPair > cDefaultAmmos; diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/hwform.cpp --- a/QTfrontend/hwform.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/hwform.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2005-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 @@ -83,6 +83,7 @@ #include "netudpserver.h" #include "chatwidget.h" #include "input_ip.h" +#include "input_password.h" #include "ammoSchemeModel.h" #include "bgwidget.h" #include "xfire.h" @@ -90,7 +91,7 @@ #include "mouseoverfilter.h" #include "roomslistmodel.h" -#include "HWDataManager.h" +#include "DataManager.h" #ifdef __APPLE__ #include "M3Panel.h" @@ -119,7 +120,7 @@ { // set music track SDLInteraction::instance().setMusicTrack( - HWDataManager::instance().findFileForRead("Music/main_theme.ogg") + DataManager::instance().findFileForRead("Music/main_theme.ogg") ); #ifdef USE_XFIRE @@ -154,8 +155,10 @@ connect (hideFrontend, SIGNAL(activated()), this, SLOT(showMinimized())); #else // ctrl+q closes frontend for consistency - QShortcut *closeFrontend = new QShortcut(QKeySequence("Ctrl+Q"), this); + QShortcut * closeFrontend = new QShortcut(QKeySequence("Ctrl+Q"), this); connect (closeFrontend, SIGNAL(activated()), this, SLOT(close())); + QShortcut * updateData = new QShortcut(QKeySequence("F5"), this); + connect (updateData, SIGNAL(activated()), &DataManager::instance(), SLOT(reload())); #endif UpdateTeamsLists(); @@ -592,6 +595,11 @@ ui.pageOptions->setTeamOptionsEnabled(true); } + if (id == ID_PAGE_SETUP) + { + config->reloadValues(); + } + // load and save ignore/friends lists if (lastid == ID_PAGE_NETGAME) // leaving a room ui.pageNetGame->pChatWidget->saveLists(ui.pageOptions->editNetNick->text()); @@ -638,7 +646,7 @@ //New page animation animationNewSlide = new QPropertyAnimation(ui.Pages->widget(id), "pos"); animationNewSlide->setDuration(duration); - animationNewSlide->setStartValue(QPoint(20000/coeff, 0)); + animationNewSlide->setStartValue(QPoint(this->width()*1.5/coeff, 0)); animationNewSlide->setEndValue(QPoint(0, 0)); animationNewSlide->setEasingCurve(QEasingCurve::OutExpo); @@ -656,7 +664,7 @@ animationOldSlide = new QPropertyAnimation(ui.Pages->widget(lastid), "pos"); animationOldSlide->setDuration(duration); animationOldSlide->setStartValue(QPoint(0, 0)); - animationOldSlide->setEndValue(QPoint(-20000/coeff, 0)); + animationOldSlide->setEndValue(QPoint(this->width()*1.5/coeff, 0)); animationOldSlide->setEasingCurve(QEasingCurve::OutExpo); #ifdef false @@ -935,25 +943,34 @@ void HWForm::NetPassword(const QString & nick) { - bool ok = false; int passLength = config->value("net/passwordlength", 0).toInt(); QString hash = config->value("net/passwordhash", "").toString(); // If the password is blank, ask the user to enter one in if (passLength == 0) { - QString password = QInputDialog::getText(this, tr("Password"), tr("Your nickname %1 is\nregistered on Hedgewars.org\nPlease provide your password below\nor pick another nickname in game config:").arg(nick), QLineEdit::Password, passLength==0?NULL:QString(passLength,'\0'), &ok); - - if (!ok) + HWPasswordDialog * hpd = new HWPasswordDialog(this, tr("Your nickname %1 is\nregistered on Hedgewars.org\nPlease provide your password below\nor pick another nickname in game config:").arg(nick)); + hpd->cbSave->setChecked(config->value("net/savepassword", true).toBool()); + if (hpd->exec() != QDialog::Accepted) { ForcedDisconnect(tr("No password supplied.")); + delete hpd; return; } + QString password = hpd->lePassword->text(); hash = QCryptographicHash::hash(password.toLatin1(), QCryptographicHash::Md5).toHex(); - config->setValue("net/passwordhash", hash); - config->setValue("net/passwordlength", password.size()); - config->setNetPasswordLength(password.size()); + + bool save = hpd->cbSave->isChecked(); + config->setValue("net/savepassword", save); + if (save) // user wants to save password + { + config->setValue("net/passwordhash", hash); + config->setValue("net/passwordlength", password.size()); + config->setNetPasswordLength(password.size()); + } + + delete hpd; } hwnet->SendPasswordHash(hash); @@ -1180,6 +1197,7 @@ netPort = hpd->sbPort->value(); NetConnectServer(*netHost, netPort); } + delete hpd; } void HWForm::NetStartServer() @@ -1524,7 +1542,7 @@ HWTeam team(ui.pageCampaign->CBTeam->currentText()); ui.pageCampaign->CBSelect->clear(); - QStringList entries = HWDataManager::instance().entryList( + QStringList entries = DataManager::instance().entryList( "Missions/Campaign", QDir::Files, QStringList("*#*.lua") diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/hwform.h --- a/QTfrontend/hwform.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/hwform.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2005-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/main.cpp --- a/QTfrontend/main.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/main.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2005-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 @@ -32,7 +32,7 @@ #include "hwconsts.h" #include "newnetclient.h" -#include "HWDataManager.h" +#include "DataManager.h" #ifdef _WIN32 #include @@ -209,67 +209,7 @@ return 1; } - HWDataManager & dataMgr = HWDataManager::instance(); - - { - QStringList themes; - - themes.append(dataMgr.entryList( - "Themes", - QDir::AllDirs | QDir::NoDotAndDotDot) - ); - - QList > icons; - - themes.sort(); - for(int i = themes.size() - 1; i >= 0; --i) - { - QString file = dataMgr.findFileForRead( - QString("Themes/%1/icon.png").arg(themes.at(i)) - ); - - if(QFile::exists(file)) - { - // load icon - QPair ic; - ic.first = QIcon(file); - - // load preview icon - ic.second = QIcon( - dataMgr.findFileForRead( - QString("Themes/%1/icon@2x.png").arg(themes.at(i)) - ) - ); - - icons.prepend(ic); - } - else - { - themes.removeAt(i); - } - } - - themesModel = new ThemesModel(themes); - Q_ASSERT(themes.size() == icons.size()); - for(int i = 0; i < icons.size(); ++i) - { - themesModel->setData(themesModel->index(i), icons[i].first, Qt::DecorationRole); - themesModel->setData(themesModel->index(i), icons[i].second, Qt::UserRole); - } - } - - mapList = new QStringList(dataMgr.entryList( - QString("Maps"), - QDir::Dirs | QDir::NoDotAndDotDot - ) - ); - - scriptList = new QStringList(dataMgr.entryList( - QString("Scripts/Multiplayer"), - QDir::Files, - QStringList("*.lua") - ) - ); + DataManager & dataMgr = DataManager::instance(); QTranslator Translator; { diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/model/GameStyleModel.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/QTfrontend/model/GameStyleModel.cpp Wed May 02 23:53:45 2012 +0200 @@ -0,0 +1,96 @@ +/* + * Hedgewars, a free turn based strategy game + * Copyright (c) 2004-2012 Andrey Korotaev + * + * 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 + */ + +/** + * @file + * @brief GameStyleModel class implementation + */ + +#include "GameStyleModel.h" + + +void GameStyleModel::loadGameStyles() +{ + beginResetModel(); + + + // empty list, so that we can (re)fill it + QStandardItemModel::clear(); + + QList items; + items.append(new QStandardItem("Normal")); + + // define a separator item + QStandardItem * separator = new QStandardItem("---"); + separator->setData(QLatin1String("separator"), Qt::AccessibleDescriptionRole); + separator->setFlags(separator->flags() & ~( Qt::ItemIsEnabled | Qt::ItemIsSelectable ) ); + + items.append(separator); + + + QStringList scripts = DataManager::instance().entryList( + QString("Scripts/Multiplayer"), + QDir::Files, + QStringList("*.lua") + ); + + foreach(QString script, scripts) + { + script = script.remove(".lua", Qt::CaseInsensitive); + + QFile scriptCfgFile(DataManager::instance().findFileForRead( + QString("Scripts/Multiplayer/%2.cfg").arg(script))); + + QString name = script; + name = name.replace("_", " "); + + QString scheme = "locked"; + QString weapons = "locked"; + + if (scriptCfgFile.exists() && scriptCfgFile.open(QFile::ReadOnly)) + { + QTextStream input(&scriptCfgFile); + input >> scheme; + input >> weapons; + scriptCfgFile.close(); + + if (!scheme.isEmpty()) + scheme.replace("_", " "); + + if (!weapons.isEmpty()) + weapons.replace("_", " "); + } + + QStandardItem * item = new QStandardItem(name); + + item->setData(script, ScriptRole); + item->setData(scheme, SchemeRole); + item->setData(weapons, WeaponsRole); + + items.append(item); + } + + QStandardItemModel::appendColumn(items); + + + endResetModel(); +} + + + + diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/model/GameStyleModel.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/QTfrontend/model/GameStyleModel.h Wed May 02 23:53:45 2012 +0200 @@ -0,0 +1,48 @@ +/* + * Hedgewars, a free turn based strategy game + * Copyright (c) 2004-2012 Andrey Korotaev + * + * 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 + */ + +/** + * @file + * @brief GameStyleModel class definition + */ + +#ifndef HEDGEWARS_GAMESTYLEMODEL_H +#define HEDGEWARS_GAMESTYLEMODEL_H + +#include +#include +#include + +#include "DataManager.h" + +/** + * @brief A model listing available game styles + */ +class GameStyleModel : public QStandardItemModel +{ + Q_OBJECT + + public: + enum DataRoles { ScriptRole = Qt::UserRole+1, SchemeRole, WeaponsRole }; + + public slots: + /// reloads the themes from the DataManager + void loadGameStyles(); +}; + +#endif // HEDGEWARS_GAMESTYLEMODEL_H diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/model/HatModel.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/QTfrontend/model/HatModel.cpp Wed May 02 23:53:45 2012 +0200 @@ -0,0 +1,148 @@ +/* + * Hedgewars, a free turn based strategy game + * Copyright (c) 2004-2012 Andrey Korotaev + * + * 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 + */ + +/** + * @file + * @brief HatModel class implementation + */ + +#include "HatModel.h" + +#include +#include +#include +#include "hwform.h" // player hash + +#include "DataManager.h" + +HatModel::HatModel(QObject* parent) : + QAbstractListModel(parent) +{ + hats = QVector >(); +} + +void HatModel::loadHats() +{ + // this method resets the contents of this model (important to know for views). + beginResetModel(); + + // prepare hats Vector + hats.clear(); + + DataManager & dataMgr = DataManager::instance(); + + QPixmap hhpix = QPixmap( + dataMgr.findFileForRead("Graphics/Hedgehog/Idle.png") + ).copy(0, 0, 32, 32); + + // my reserved hats + QStringList hatsList = dataMgr.entryList( + "Graphics/Hats/Reserved", + QDir::Files, + QStringList(playerHash+"*.png") + ); + + int nReserved = hatsList.size(); + + // regular hats + hatsList.append(dataMgr.entryList( + "Graphics/Hats", + QDir::Files, + QStringList("*.png") + ) + ); + + + int nHats = hatsList.size(); + + for (int i = 0; i < nHats; i++) + { + bool isReserved = (i < nReserved); + + QString str = hatsList.at(i); + str = str.remove(QRegExp("\\.png$")); + QPixmap pix( + dataMgr.findFileForRead( + "Graphics/Hats/" + QString(isReserved?"Reserved/":"") + str + + ".png" + ) + ); + + // rename properly + if (isReserved) + str = "Reserved "+str.remove(0,32); + + QPixmap tmppix(32, 37); + tmppix.fill(QColor(Qt::transparent)); + + QPainter painter(&tmppix); + painter.drawPixmap(QPoint(0, 5), hhpix); + painter.drawPixmap(QPoint(0, 0), pix.copy(0, 0, 32, 32)); + if(pix.width() > 32) + painter.drawPixmap(QPoint(0, 0), pix.copy(32, 0, 32, 32)); + painter.end(); + + if (str == "NoHat") + hats.prepend(qMakePair(str, QIcon(tmppix))); + else + hats.append(qMakePair(str, QIcon(tmppix))); + } + + + endResetModel(); +} + +QVariant HatModel::headerData(int section, + Qt::Orientation orientation, int role) const +{ + Q_UNUSED(section); + Q_UNUSED(orientation); + Q_UNUSED(role); + + return QVariant(); +} + +int HatModel::rowCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + else + return hats.size(); +} + +/*int HatModel::columnCount(const QModelIndex & parent) const +{ + if (parent.isValid()) + return 0; + else + return 2; +} +*/ +QVariant HatModel::data(const QModelIndex &index, + int role) const +{ + if (!index.isValid() || index.row() < 0 + || index.row() >= hats.size() + || (role != Qt::DisplayRole && role != Qt::DecorationRole)) + return QVariant(); + + if (role == Qt::DisplayRole) + return hats.at(index.row()).first; + else // role == Qt::DecorationRole + return hats.at(index.row()).second; +} diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/model/HatModel.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/QTfrontend/model/HatModel.h Wed May 02 23:53:45 2012 +0200 @@ -0,0 +1,53 @@ +/* + * Hedgewars, a free turn based strategy game + * Copyright (c) 2004-2012 Andrey Korotaev + * + * 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 + */ + +/** + * @file + * @brief HatModel class definition + */ + +#ifndef HEDGEWARS_HATMODEL_H +#define HEDGEWARS_HATMODEL_H + +#include +#include +#include +#include +#include + +class HatModel : public QAbstractListModel +{ + Q_OBJECT + + public: + HatModel(QObject *parent = 0); + + QVariant headerData(int section, Qt::Orientation orientation, int role) const; + int rowCount(const QModelIndex & parent) const; + //int columnCount(const QModelIndex & parent) const; + + public slots: + /// Reloads hats using the DataManager. + void loadHats(); + + QVariant data(const QModelIndex &index, int role) const; + protected: + QVector > hats; +}; + +#endif // HEDGEWARS_HATMODEL_H diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/model/MapModel.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/QTfrontend/model/MapModel.cpp Wed May 02 23:53:45 2012 +0200 @@ -0,0 +1,238 @@ +/* + * Hedgewars, a free turn based strategy game + * Copyright (c) 2004-2012 Andrey Korotaev + * + * 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 + */ + +/** + * @file + * @brief MapModel class implementation + */ + +#include "MapModel.h" + + +void MapModel::loadMaps() +{ + // this method resets the contents of this model (important to know for views). + beginResetModel(); + + // we'll need the DataManager a few times, so let's get a reference to it + DataManager & datamgr = DataManager::instance(); + + // fetch list of available maps + QStringList maps = + datamgr.entryList("Maps", QDir::AllDirs | QDir::NoDotAndDotDot); + + // empty list, so that we can (re)fill it + QStandardItemModel::clear(); + + QList genMaps; + QList missionMaps; + QList staticMaps; + + // add generated/handdrawn maps to list + // TODO: icons for these + + genMaps.append( + infoToItem(QIcon(), QComboBox::tr("generated map..."), GeneratedMap, "+rnd+")); + genMaps.append( + infoToItem(QIcon(), QComboBox::tr("generated maze..."), GeneratedMaze, "+maze+")); + genMaps.append( + infoToItem(QIcon(), QComboBox::tr("hand drawn map..."), HandDrawnMap, "+drawn+")); + + // only 2 map relate files are relevant: + // - the cfg file that contains the settings/info of the map + // - the lua file - if it exists it's a mission, otherwise it isn't + QFile mapLuaFile; + QFile mapCfgFile; + + // add mission/static maps to lists + foreach (QString map, maps) + { + mapCfgFile.setFileName( + datamgr.findFileForRead(QString("Maps/%1/map.cfg").arg(map))); + mapLuaFile.setFileName( + datamgr.findFileForRead(QString("Maps/%1/map.lua").arg(map))); + + + if (mapCfgFile.open(QFile::ReadOnly)) + { + QString caption; + QString theme; + quint32 limit = 0; + QString scheme; + QString weapons; + // if there is a lua file for this map, then it's a mission + bool isMission = mapLuaFile.exists(); + MapType type = isMission?MissionMap:StaticMap; + + // load map info from file + QTextStream input(&mapCfgFile); + input >> theme; + input >> limit; + if (isMission) { // scheme and weapons are only relevant for missions + input >> scheme; + input >> weapons; + } + mapCfgFile.close(); + + // let's use some semi-sane hedgehog limit, rather than none + if (limit == 0) + limit = 18; + + + // the default scheme/weaponset for missions. + // if empty we assume the map sets these internally -> locked + if (isMission) + { + if (scheme.isEmpty()) + scheme = "locked"; + else + scheme.replace("_", " "); + + if (weapons.isEmpty()) + weapons = "locked"; + else + weapons.replace("_", " "); + } + + // add a mission caption prefix to missions + if (isMission) + { + // TODO: icon + caption = QComboBox::tr("Mission") + ": " + map; + } + else + caption = map; + + // we know everything there is about the map, let's get am item for it + QStandardItem * item = infoToItem( + QIcon(), caption, type, map, theme, limit, scheme, weapons); + + // append item to the list + if (isMission) + missionMaps.append(item); + else + staticMaps.append(item); + + } + + } + + + // define a separator item + QStandardItem separator("---"); + separator.setData(QLatin1String("separator"), Qt::AccessibleDescriptionRole); + separator.setFlags(separator.flags() & ~( Qt::ItemIsEnabled | Qt::ItemIsSelectable ) ); + + // create list: + // generated+handdrawn maps, 2 saperators, missions, 1 separator, static maps + QList items; + items.append(genMaps); + items.append(separator.clone()); + items.append(separator.clone()); + items.append(missionMaps); + items.append(separator.clone()); + items.append(staticMaps); + + + // create row-index lookup table + + m_mapIndexes.clear(); + + int count = items.size(); + + for (int i = 0; i < count; i++) + { + QStandardItem * si = items.at(i); + QVariant v = si->data(Qt::UserRole + 1); + if (v.canConvert()) + m_mapIndexes.insert(v.value().name, i); + } + + + // store start-index and count of relevant types + + m_typeLoc.insert(GeneratedMap, QPair(0, 1)); + m_typeLoc.insert(GeneratedMaze, QPair(1, 1)); + m_typeLoc.insert(HandDrawnMap, QPair(2, 1)); + // mission maps + int startIdx = genMaps.size() + 2; // start after genMaps and 2 separators + count = missionMaps.size(); + m_typeLoc.insert(MissionMap, QPair(startIdx, count)); + // static maps + startIdx += count + 1; // start after missions and 2 separators + count = staticMaps.size(); + m_typeLoc.insert(StaticMap, QPair(startIdx, count)); + + // store list contents in the item model + QStandardItemModel::appendColumn(items); + + + endResetModel(); +} + + +int MapModel::randomMap(MapType type) const +{ + // return a random index for this type or -1 if none available + QPair loc = m_typeLoc.value(type, QPair(-1,0)); + + int startIdx = loc.first; + int count = loc.second; + + if (count < 1) + return -1; + else + return startIdx + (rand() % count); +} + + +QStandardItem * MapModel::infoToItem( + const QIcon & icon, + const QString caption, + MapType type, + QString name, + QString theme, + quint32 limit, + QString scheme, + QString weapons) +const +{ + QStandardItem * item = new QStandardItem(icon, caption); + MapInfo mapInfo; + QVariant qvar(QVariant::UserType); + + mapInfo.type = type; + mapInfo.name = name; + mapInfo.theme = theme; + mapInfo.limit = limit; + mapInfo.scheme = scheme; + mapInfo.weapons = weapons; + + + qvar.setValue(mapInfo); + item->setData(qvar, Qt::UserRole + 1); + + return item; +} + + +int MapModel::indexOf(const QString & map) const +{ + return m_mapIndexes.value(map, -1); +} + diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/model/MapModel.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/QTfrontend/model/MapModel.h Wed May 02 23:53:45 2012 +0200 @@ -0,0 +1,120 @@ +/* + * Hedgewars, a free turn based strategy game + * Copyright (c) 2004-2012 Andrey Korotaev + * + * 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 + */ + +/** + * @file + * @brief MapModel class definition + */ + +#ifndef HEDGEWARS_MAPMODEL_H +#define HEDGEWARS_MAPMODEL_H + +#include +#include +#include +#include +#include +#include +#include + +#include "DataManager.h" + +/** + * @brief A model that vertically lists available maps + * + * @author sheepluva + * @since 0.9.18 + */ +class MapModel : public QStandardItemModel +{ + Q_OBJECT + + public: + enum MapType { + Invalid, + GeneratedMap, + GeneratedMaze, + HandDrawnMap, + MissionMap, + StaticMap + }; + + /// a struct for holding the attributes of a map. + struct MapInfo + { + MapType type; ///< The map-type + QString name; ///< The internal name. + QString theme; ///< The theme to be used. (can be empty) + quint32 limit; ///< The maximum allowed number of hedgehogs. + QString scheme; ///< Default scheme name or "locked", for mission-maps. + QString weapons; ///< Default weaponset name or "locked", for missions-maps. + }; + + /** + * @brief Returns the row-index of the given map. + * @param map map of which to get the row-index of. + * @return row-index of map or -1 if not available. + */ + int indexOf(const QString & map) const; + + /** + * @brief Returns the row-index of a random map with a specified type. + * @param type desired type of map. + * @return row-index of a map with the desired type, -1 if none found. + */ + int randomMap(MapType type) const; + + public slots: + /// Reloads the maps using the DataManager. + void loadMaps(); + + + private: + /// start-index and map count for each map-type. + QMap > m_typeLoc; + + /// map index lookup table + QHash m_mapIndexes; + + /** + * @brief Creates a QStandardItem, that holds the map info and item appearance. + * The used role for the data is Qt::UserRole + 1. + * @param icon the icon to be displayed (can be an empty QIcon()). + * @param caption the text to be displayed. + * @param type the type of the map. + * @param name the internal name of the map. + * @param theme the theme of the map (or empty if none). + * @param limit the hedgehog limit of the map. + * @param scheme mission map: default scheme name or "locked". + * @param weapons mission map: default weaponset name or "locked". + * @return pointer to item representing the map info: at Qt::UserRole + 1. + */ + QStandardItem * infoToItem( + const QIcon & icon, + const QString caption, + MapType type = Invalid, + QString name = "", + QString theme = "", + quint32 limit = 0, + QString scheme = "", + QString weapons = "") const; +}; + +Q_DECLARE_METATYPE(MapModel::MapInfo) + +#endif // HEDGEWARS_MAPMODEL_H diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/model/ThemeModel.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/QTfrontend/model/ThemeModel.cpp Wed May 02 23:53:45 2012 +0200 @@ -0,0 +1,97 @@ +/* + * Hedgewars, a free turn based strategy game + * Copyright (c) 2004-2012 Andrey Korotaev + * + * 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 + */ + +/** + * @file + * @brief ThemeModel class implementation + */ + +#include "ThemeModel.h" + +ThemeModel::ThemeModel(QObject *parent) : + QAbstractListModel(parent) +{ + m_data = QList >(); +} + +int ThemeModel::rowCount(const QModelIndex &parent) const +{ + if(parent.isValid()) + return 0; + else + return m_data.size(); +} + + +QVariant ThemeModel::data(const QModelIndex &index, int role) const +{ + if(index.column() > 0 || index.row() >= m_data.size()) + return QVariant(); + else + return m_data.at(index.row()).value(role); +} + + +void ThemeModel::loadThemes() +{ + beginResetModel(); + + + DataManager & datamgr = DataManager::instance(); + + QStringList themes = + datamgr.entryList("Themes", QDir::AllDirs | QDir::NoDotAndDotDot); + + m_data.clear(); + +#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) + m_data.reserve(themes.size()); +#endif + + foreach (QString theme, themes) + { + // themes without icon are supposed to be hidden + QString iconpath = + datamgr.findFileForRead(QString("Themes/%1/icon.png").arg(theme)); + + if (!QFile::exists(iconpath)) + continue; + + QMap dataset; + + // set name + dataset.insert(Qt::DisplayRole, theme); + + // load and set icon + QIcon icon(iconpath); + dataset.insert(Qt::DecorationRole, icon); + + // load and set preview icon + QIcon preview(datamgr.findFileForRead(QString("Themes/%1/icon@2x.png").arg(theme))); + dataset.insert(Qt::UserRole, preview); + + m_data.append(dataset); + } + + + endResetModel(); +} + + + + diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/model/ThemeModel.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/QTfrontend/model/ThemeModel.h Wed May 02 23:53:45 2012 +0200 @@ -0,0 +1,57 @@ +/* + * Hedgewars, a free turn based strategy game + * Copyright (c) 2004-2012 Andrey Korotaev + * + * 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 + */ + +/** + * @file + * @brief ThemeModel class definition + */ + +#ifndef HEDGEWARS_THEMEMODEL_H +#define HEDGEWARS_THEMEMODEL_H + +#include +#include +#include +#include + +#include "DataManager.h" + +/** + * @brief A model listing available themes + */ +class ThemeModel : public QAbstractListModel +{ + Q_OBJECT + + public: + explicit ThemeModel(QObject *parent = 0); + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role) const; + + + public slots: + /// reloads the themes from the DataManager + void loadThemes(); + + + private: + QList > m_data; +}; + +#endif // HEDGEWARS_THEMEMODEL_H diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/model/ammoSchemeModel.cpp --- a/QTfrontend/model/ammoSchemeModel.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/model/ammoSchemeModel.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2005-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/model/ammoSchemeModel.h --- a/QTfrontend/model/ammoSchemeModel.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/model/ammoSchemeModel.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2005-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/model/hats.cpp --- a/QTfrontend/model/hats.cpp Sun Apr 01 15:23:34 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,129 +0,0 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (c) 2008-2012 Andrey Korotaev - * - * 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 -#include -#include -#include "hwconsts.h" -#include "hwform.h" -#include "hats.h" - -#include "HWDataManager.h" - -HatsModel::HatsModel(QObject* parent) : - QAbstractListModel(parent) -{ - HWDataManager & dataMgr = HWDataManager::instance(); - - QPixmap hhpix = QPixmap( - dataMgr.findFileForRead("Graphics/Hedgehog/Idle.png") - ).copy(0, 0, 32, 32); - - // my reserved hats - QStringList hatsList = dataMgr.entryList( - "Graphics/Hats/Reserved", - QDir::Files, - QStringList(playerHash+"*.png") - ); - - int nReserved = hatsList.size(); - - // regular hats - hatsList.append(dataMgr.entryList( - "Graphics/Hats", - QDir::Files, - QStringList("*.png") - ) - ); - - - int nHats = hatsList.size(); - - for (int i = 0; i < nHats; i++) - { - bool isReserved = (i < nReserved); - - QString str = hatsList.at(i); - str = str.remove(QRegExp("\\.png$")); - QPixmap pix( - dataMgr.findFileForRead( - "Graphics/Hats/" + QString(isReserved?"Reserved/":"") + str + - ".png" - ) - ); - - // rename properly - if (isReserved) - str = "Reserved "+str.remove(0,32); - - QPixmap tmppix(32, 37); - tmppix.fill(QColor(Qt::transparent)); - - QPainter painter(&tmppix); - painter.drawPixmap(QPoint(0, 5), hhpix); - painter.drawPixmap(QPoint(0, 0), pix.copy(0, 0, 32, 32)); - if(pix.width() > 32) - painter.drawPixmap(QPoint(0, 0), pix.copy(32, 0, 32, 32)); - painter.end(); - - if (str == "NoHat") - hats.prepend(qMakePair(str, QIcon(tmppix))); - else - hats.append(qMakePair(str, QIcon(tmppix))); - } -} - -QVariant HatsModel::headerData(int section, - Qt::Orientation orientation, int role) const -{ - Q_UNUSED(section); - Q_UNUSED(orientation); - Q_UNUSED(role); - - return QVariant(); -} - -int HatsModel::rowCount(const QModelIndex &parent) const -{ - if (parent.isValid()) - return 0; - else - return hats.size(); -} - -/*int HatsModel::columnCount(const QModelIndex & parent) const -{ - if (parent.isValid()) - return 0; - else - return 2; -} -*/ -QVariant HatsModel::data(const QModelIndex &index, - int role) const -{ - if (!index.isValid() || index.row() < 0 - || index.row() >= hats.size() - || (role != Qt::DisplayRole && role != Qt::DecorationRole)) - return QVariant(); - - if (role == Qt::DisplayRole) - return hats.at(index.row()).first; - else // role == Qt::DecorationRole - return hats.at(index.row()).second; -} diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/model/hats.h --- a/QTfrontend/model/hats.h Sun Apr 01 15:23:34 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +0,0 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (c) 2008-2012 Andrey Korotaev - * - * 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 - */ - -#ifndef _HATS_INCLUDED -#define _HATS_INCLUDED - -#include -#include -#include -#include -#include - -class HatsModel : public QAbstractListModel -{ - Q_OBJECT - - public: - HatsModel(QObject *parent = 0); - - QVariant headerData(int section, Qt::Orientation orientation, int role) const; - int rowCount(const QModelIndex & parent) const; - //int columnCount(const QModelIndex & parent) const; - - QVariant data(const QModelIndex &index, int role) const; - protected: - QVector > hats; -}; - -#endif // _HATS_INCLUDED diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/model/netserverslist.cpp --- a/QTfrontend/model/netserverslist.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/model/netserverslist.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2007-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/model/netserverslist.h --- a/QTfrontend/model/netserverslist.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/model/netserverslist.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2007-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/model/roomslistmodel.cpp --- a/QTfrontend/model/roomslistmodel.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/model/roomslistmodel.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,11 +1,39 @@ +/* + * Hedgewars, a free turn based strategy game + * Copyright (c) 2004-2012 Andrey Korotaev + * + * 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 + */ + +/** + * @file + * @brief RoomsListModel class implementation + */ + #include "roomslistmodel.h" +#include +#include +#include + RoomsListModel::RoomsListModel(QObject *parent) : - QAbstractTableModel(parent) + QAbstractTableModel(parent), + c_nColumns(8) { m_headerData = QStringList() - << QString() + << tr("In progress") << tr("Room Name") << tr("C") << tr("T") @@ -13,8 +41,11 @@ << tr("Map") << tr("Rules") << tr("Weapons"); + + m_mapModel = DataManager::instance().mapModel(); } + QVariant RoomsListModel::headerData(int section, Qt::Orientation orientation, int role) const { if(orientation == Qt::Vertical || role != Qt::DisplayRole) @@ -23,6 +54,7 @@ return QVariant(m_headerData.at(section)); } + int RoomsListModel::rowCount(const QModelIndex & parent) const { if(parent.isValid()) @@ -31,49 +63,130 @@ return m_data.size(); } + int RoomsListModel::columnCount(const QModelIndex & parent) const { if(parent.isValid()) return 0; else - return 8; + return c_nColumns; } + QVariant RoomsListModel::data(const QModelIndex &index, int role) const { - if (!index.isValid() || index.row() < 0 - || index.row() >= m_data.size() - || index.column() >= 8 - || (role != Qt::EditRole && role != Qt::DisplayRole) - ) + int column = index.column(); + int row = index.row(); + + // invalid index + if (!index.isValid()) + return QVariant(); + + // invalid row + if ((row < 0) || (row >= m_data.size())) + return QVariant(); + + // invalid column + if ((column < 0) || (column >= c_nColumns)) return QVariant(); - return m_data.at(index.row()).at(index.column()); + // not a role we have data for + if (role != Qt::DisplayRole) + // only custom-align counters + if ((role != Qt::TextAlignmentRole) + || ((column != PlayerCountColumn) && (column != TeamCountColumn))) + // only decorate name column + if ((role != Qt::DecorationRole) || (column != NameColumn)) + // only dye map column + if ((role != Qt::ForegroundRole) || (column != MapColumn)) + return QVariant(); + + // decorate room name based on room state + if (role == Qt::DecorationRole) + { + const QIcon roomBusyIcon(":/res/iconDamage.png"); + const QIcon roomWaitingIcon(":/res/iconTime.png"); + + if (m_data.at(row).at(0).isEmpty()) + return QVariant(roomWaitingIcon); + else + return QVariant(roomBusyIcon); + } + + QString content = m_data.at(row).at(column); + + if (role == Qt::DisplayRole) + { + // supply in progress flag as bool + if (column == 0) + return QVariant(QString(!content.isEmpty())); + + // display room names + if (column == 5) + { + // special names + if (content[0] == '+') + { + if (content == "+rnd+") return tr("Random Map"); + if (content == "+maze+") return tr("Random Maze"); + if (content == "+drawn+") return tr("Hand-drawn"); + } + + // prefix ? if map not available + if ((m_mapModel->indexOf(content) < 0)) + return QString ("? %1").arg(content); + } + + return content; + } + + // dye map names red if map not available + if (role == Qt::ForegroundRole) + { + if ((m_mapModel->indexOf(content) < 0)) + return QBrush(QColor("darkred")); + else + return QVariant(); + } + + if (role == Qt::TextAlignmentRole) + { + return (int)(Qt::AlignHCenter | Qt::AlignVCenter); + } + + Q_ASSERT(false); + return QVariant(); } + void RoomsListModel::setRoomsList(const QStringList & rooms) { - if(m_data.size()) - { - beginRemoveRows(QModelIndex(), 0, m_data.size() - 1); - m_data.clear(); - endRemoveRows(); - } + beginResetModel(); + + m_data.clear(); - for(int i = 0; i < rooms.size(); i += 8) + int nRooms = rooms.size(); + + for (int i = 0; i < nRooms; i += c_nColumns) { QStringList l; - //l.reserve(8); not really that useful an optimisation and causes problems w/ old Qt. Harmless to leave it out. - for(int t = 0; t < 8; ++t) + +#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) + l.reserve(c_nColumns); // small optimisation not supported in old Qt +#endif + + for (int t = 0; t < c_nColumns; t++) + { l.append(rooms[i + t]); + } m_data.append(roomInfo2RoomRecord(l)); } - beginInsertRows(QModelIndex(), 0, m_data.size() - 1); - endInsertRows(); + endResetModel(); } + void RoomsListModel::addRoom(const QStringList & info) { beginInsertRows(QModelIndex(), 0, 0); @@ -83,12 +196,33 @@ endInsertRows(); } + +int RoomsListModel::rowOfRoom(const QString & name) +{ + int size = m_data.size(); + + if (size < 1) + return -1; + + int i = 0; + + // search for record with matching room name + while(m_data[i].at(NameColumn) != name) + { + i++; + if(i >= size) + return -1; + } + + return i; +} + + void RoomsListModel::removeRoom(const QString & name) { - int i = 0; - while(i < m_data.size() && m_data[i].at(0) != name) - ++i; - if(i >= m_data.size()) + int i = rowOfRoom(name); + + if (i < 0) return; beginRemoveRows(QModelIndex(), i, i); @@ -98,25 +232,32 @@ endRemoveRows(); } + void RoomsListModel::updateRoom(const QString & name, const QStringList & info) { - int i = 0; - while(i < m_data.size() && m_data[i].at(0) != name) - ++i; - if(i >= m_data.size()) + int i = rowOfRoom(name); + + if (i < 0) return; - m_data[i] = roomInfo2RoomRecord(info); emit dataChanged(index(i, 0), index(i, columnCount(QModelIndex()) - 1)); } + QStringList RoomsListModel::roomInfo2RoomRecord(const QStringList & info) { QStringList result; result = info; + // for matters of less memory usage and quicker access store + // the boolean string as either "t" or empty + if (info[StateColumn].toLower() == "true") + result[StateColumn] = "t"; + else + result[StateColumn] = QString(); + return result; } diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/model/roomslistmodel.h --- a/QTfrontend/model/roomslistmodel.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/model/roomslistmodel.h Wed May 02 23:53:45 2012 +0200 @@ -1,13 +1,51 @@ -#ifndef ROOMSLISTMODEL_H -#define ROOMSLISTMODEL_H +/* + * Hedgewars, a free turn based strategy game + * Copyright (c) 2004-2012 Andrey Korotaev + * + * 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 + */ + +/** + * @file + * @brief RoomsListModel class definition + */ + +#ifndef HEDGEWARS_ROOMSLISTMODEL_H +#define HEDGEWARS_ROOMSLISTMODEL_H #include #include +#include "DataManager.h" + class RoomsListModel : public QAbstractTableModel { Q_OBJECT public: + // if you add a column here, also incr. c_nColumns in constructor + // also adjust header in constructor to changes + enum Column { + StateColumn, + NameColumn, + PlayerCountColumn, + TeamCountColumn, + OwnerColumn, + MapColumn, + SchemeColumn, + WeaponsColumn + }; + explicit RoomsListModel(QObject *parent = 0); QVariant headerData(int section, Qt::Orientation orientation, int role) const; @@ -20,12 +58,15 @@ void addRoom(const QStringList & info); void removeRoom(const QString & name); void updateRoom(const QString & name, const QStringList & info); + int rowOfRoom(const QString & name); private: + const int c_nColumns; QList m_data; QStringList m_headerData; + MapModel * m_mapModel; QStringList roomInfo2RoomRecord(const QStringList & info); }; -#endif // ROOMSLISTMODEL_H +#endif // HEDGEWARS_ROOMSLISTMODEL_H diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/model/themesmodel.cpp --- a/QTfrontend/model/themesmodel.cpp Sun Apr 01 15:23:34 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +0,0 @@ - -#include "themesmodel.h" - -ThemesModel::ThemesModel(QStringList themes, QObject *parent) : - QAbstractListModel(parent) -{ -#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) - m_data.reserve(themes.size()); -#endif - - foreach(QString theme, themes) - { - m_data.append(QHash()); - m_data.last().insert(Qt::DisplayRole, theme); - } -} - -int ThemesModel::rowCount(const QModelIndex &parent) const -{ - if(parent.isValid()) - return 0; - else - return m_data.size(); -} - -QVariant ThemesModel::data(const QModelIndex &index, int role) const -{ - if(index.column() > 0 || index.row() >= m_data.size()) - return QVariant(); - else - return m_data.at(index.row()).value(role); -} - -bool ThemesModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - if(index.column() > 0 || index.row() >= m_data.size()) - return false; - else - { - m_data[index.row()].insert(role, value); - - return true; - } - -} - - - - diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/model/themesmodel.h --- a/QTfrontend/model/themesmodel.h Sun Apr 01 15:23:34 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,28 +0,0 @@ -#ifndef THEMESMODEL_H -#define THEMESMODEL_H - -#include -#include -#include - -class ThemesModel : public QAbstractListModel -{ - Q_OBJECT - public: - explicit ThemesModel(QStringList themes, QObject *parent = 0); - - int rowCount(const QModelIndex &parent = QModelIndex()) const; - QVariant data(const QModelIndex &index, int role) const; - bool setData(const QModelIndex &index, const QVariant &value, - int role = Qt::EditRole); - - signals: - - public slots: - - private: - - QList > m_data; -}; - -#endif // THEMESMODEL_H diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/net/hwmap.cpp --- a/QTfrontend/net/hwmap.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/net/hwmap.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,7 +1,7 @@ /* * Hedgewars, a free turn based strategy game * Copyright (c) 2006-2007 Ulyanov Igor - * Copyright (c) 2007-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/net/hwmap.h --- a/QTfrontend/net/hwmap.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/net/hwmap.h Wed May 02 23:53:45 2012 +0200 @@ -1,7 +1,7 @@ /* * Hedgewars, a free turn based strategy game * Copyright (c) 2006 Igor Ulyanov - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/net/netregister.cpp --- a/QTfrontend/net/netregister.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/net/netregister.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2007-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/net/netregister.h --- a/QTfrontend/net/netregister.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/net/netregister.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2007-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/net/netserver.cpp --- a/QTfrontend/net/netserver.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/net/netserver.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,7 +1,7 @@ /* * Hedgewars, a free turn based strategy game * Copyright (c) 2006-2008 Igor Ulyanov - * Copyright (c) 2008-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/net/netserver.h --- a/QTfrontend/net/netserver.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/net/netserver.h Wed May 02 23:53:45 2012 +0200 @@ -1,7 +1,7 @@ /* * Hedgewars, a free turn based strategy game * Copyright (c) 2006-2008 Igor Ulyanov - * Copyright (c) 2008-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/net/netudpserver.cpp --- a/QTfrontend/net/netudpserver.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/net/netudpserver.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,7 +1,7 @@ /* * Hedgewars, a free turn based strategy game * Copyright (c) 2007-2008 Igor Ulyanov - * Copyright (c) 2008-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/net/netudpserver.h --- a/QTfrontend/net/netudpserver.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/net/netudpserver.h Wed May 02 23:53:45 2012 +0200 @@ -1,7 +1,7 @@ /* * Hedgewars, a free turn based strategy game * Copyright (c) 2007-2008 Igor Ulyanov - * Copyright (c) 2008-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/net/netudpwidget.cpp --- a/QTfrontend/net/netudpwidget.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/net/netudpwidget.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,7 +1,7 @@ /* * Hedgewars, a free turn based strategy game * Copyright (c) 2007 Igor Ulyanov - * Copyright (c) 2007-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/net/netudpwidget.h --- a/QTfrontend/net/netudpwidget.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/net/netudpwidget.h Wed May 02 23:53:45 2012 +0200 @@ -1,7 +1,7 @@ /* * Hedgewars, a free turn based strategy game * Copyright (c) 2007 Igor Ulyanov - * Copyright (c) 2007-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/net/newnetclient.cpp --- a/QTfrontend/net/newnetclient.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/net/newnetclient.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,7 +1,7 @@ /* * Hedgewars, a free turn based strategy game * Copyright (c) 2006-2008 Igor Ulyanov - * Copyright (c) 2008-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/net/newnetclient.h --- a/QTfrontend/net/newnetclient.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/net/newnetclient.h Wed May 02 23:53:45 2012 +0200 @@ -1,7 +1,7 @@ /* * Hedgewars, a free turn based strategy game * Copyright (c) 2006-2008 Igor Ulyanov - * Copyright (c) 2008-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/net/proto.cpp --- a/QTfrontend/net/proto.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/net/proto.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/net/proto.h --- a/QTfrontend/net/proto.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/net/proto.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/net/tcpBase.cpp --- a/QTfrontend/net/tcpBase.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/net/tcpBase.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,7 +1,7 @@ /* * Hedgewars, a free turn based strategy game * Copyright (c) 2006-2007 Igor Ulyanov - * Copyright (c) 2007-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/net/tcpBase.h --- a/QTfrontend/net/tcpBase.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/net/tcpBase.h Wed May 02 23:53:45 2012 +0200 @@ -1,7 +1,7 @@ /* * Hedgewars, a free turn based strategy game * Copyright (c) 2006-2007 Igor Ulyanov - * Copyright (c) 2007-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/sdlkeys.h --- a/QTfrontend/sdlkeys.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/sdlkeys.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2005-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/team.cpp --- a/QTfrontend/team.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/team.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2005-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 @@ -25,7 +25,6 @@ #include "team.h" #include "hwform.h" -#include "hats.h" HWTeam::HWTeam(const QString & teamname) : QObject(0) diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/team.h --- a/QTfrontend/team.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/team.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2005-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * Copyright (c) 2007 Igor Ulyanov * * This program is free software; you can redistribute it and/or modify diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/dialog/input_ip.cpp --- a/QTfrontend/ui/dialog/input_ip.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/dialog/input_ip.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2007-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/dialog/input_ip.h --- a/QTfrontend/ui/dialog/input_ip.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/dialog/input_ip.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2007-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/dialog/input_password.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/QTfrontend/ui/dialog/input_password.cpp Wed May 02 23:53:45 2012 +0200 @@ -0,0 +1,53 @@ +/* + * Hedgewars, a free turn based strategy game + * Copyright (c) 2004-2012 Andrey Korotaev + * + * 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 +#include +#include +#include +#include +#include + +#include "input_password.h" + +HWPasswordDialog::HWPasswordDialog(QWidget* parent, const QString & label) : QDialog(parent) +{ + setWindowTitle(tr("Password")); + + QGridLayout * layout = new QGridLayout(this); + + QLabel * lbLabel = new QLabel(this); + lbLabel->setText(label); + layout->addWidget(lbLabel, 0, 0); + + lePassword = new QLineEdit(this); + lePassword->setEchoMode(QLineEdit::Password); + layout->addWidget(lePassword, 1, 0); + + cbSave = new QCheckBox(this); + cbSave->setText(QCheckBox::tr("Save password")); + layout->addWidget(cbSave, 2, 0); + + QDialogButtonBox* dbbButtons = new QDialogButtonBox(this); + QPushButton * pbOK = dbbButtons->addButton(QDialogButtonBox::Ok); + QPushButton * pbCancel = dbbButtons->addButton(QDialogButtonBox::Cancel); + layout->addWidget(dbbButtons, 3, 0); + + connect(pbOK, SIGNAL(clicked()), this, SLOT(accept())); + connect(pbCancel, SIGNAL(clicked()), this, SLOT(reject())); +} diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/dialog/input_password.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/QTfrontend/ui/dialog/input_password.h Wed May 02 23:53:45 2012 +0200 @@ -0,0 +1,38 @@ +/* + * Hedgewars, a free turn based strategy game + * Copyright (c) 2004-2012 Andrey Korotaev + * + * 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 + */ + +#ifndef INPUT_PASSWORD_H +#define INPUT_PASSWORD_H + +#include + +class QLineEdit; +class QCheckBox; + +class HWPasswordDialog : public QDialog +{ + Q_OBJECT + public: + HWPasswordDialog(QWidget* parent, const QString & label); + + QLineEdit* lePassword; + QCheckBox* cbSave; +}; + + +#endif // INPUT_PASSWORD_H diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/mouseoverfilter.cpp --- a/QTfrontend/ui/mouseoverfilter.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/mouseoverfilter.cpp Wed May 02 23:53:45 2012 +0200 @@ -11,7 +11,7 @@ #include "ui_hwform.h" #include "hwform.h" #include "gameuiconfig.h" -#include "HWDataManager.h" +#include "DataManager.h" #include "SDLInteraction.h" MouseOverFilter::MouseOverFilter(QObject *parent) : @@ -41,7 +41,7 @@ QTabWidget * tab = dynamic_cast(dist); if (HWForm::config->isFrontendSoundEnabled() && (button || textfield || checkbox || droplist || slider || tab)) { - HWDataManager & dataMgr = HWDataManager::instance(); + DataManager & dataMgr = DataManager::instance(); SDLInteraction::instance().playSoundFile(dataMgr.findFileForRead("Sounds/steps.ogg")); } diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/AbstractPage.cpp --- a/QTfrontend/ui/page/AbstractPage.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/AbstractPage.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/AbstractPage.h --- a/QTfrontend/ui/page/AbstractPage.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/AbstractPage.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pageadmin.cpp --- a/QTfrontend/ui/page/pageadmin.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pageadmin.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pageadmin.h --- a/QTfrontend/ui/page/pageadmin.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pageadmin.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pagecampaign.cpp --- a/QTfrontend/ui/page/pagecampaign.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pagecampaign.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pagecampaign.h --- a/QTfrontend/ui/page/pagecampaign.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pagecampaign.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pageconnecting.cpp --- a/QTfrontend/ui/page/pageconnecting.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pageconnecting.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pageconnecting.h --- a/QTfrontend/ui/page/pageconnecting.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pageconnecting.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pagedata.cpp --- a/QTfrontend/ui/page/pagedata.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pagedata.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 @@ -30,6 +30,7 @@ #include "pagedata.h" #include "databrowser.h" #include "hwconsts.h" +#include "DataManager.h" #include "quazip.h" #include "quazipfile.h" @@ -52,6 +53,7 @@ void PageDataDownload::connectSignals() { connect(web, SIGNAL(anchorClicked(QUrl)), this, SLOT(request(const QUrl&))); + connect(this, SIGNAL(goBack()), this, SLOT(onPageLeave())); } PageDataDownload::PageDataDownload(QWidget* parent) : AbstractPage(parent) @@ -60,6 +62,8 @@ web->setOpenLinks(false); // fetchList(); + + m_contentDownloaded = false; } void PageDataDownload::request(const QUrl &url) @@ -217,6 +221,8 @@ qWarning("read all but not EOF"); return false; } + + m_contentDownloaded = true; } file.close(); @@ -232,3 +238,13 @@ return true; } + + +void PageDataDownload::onPageLeave() +{ + if (m_contentDownloaded) + { + m_contentDownloaded = false; + DataManager::instance().reload(); + } +} diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pagedata.h --- a/QTfrontend/ui/page/pagedata.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pagedata.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 @@ -46,6 +46,8 @@ QHash progressBars; QVBoxLayout *progressBarsLayout; + bool m_contentDownloaded; ///< true if something was downloaded since last page leave + bool extractDataPack(QByteArray * buf); private slots: @@ -54,6 +56,8 @@ void pageDownloaded(); void fileDownloaded(); void downloadProgress(qint64, qint64); + + void onPageLeave(); }; #endif diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pagedrawmap.cpp --- a/QTfrontend/ui/page/pagedrawmap.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pagedrawmap.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 @@ -19,6 +19,7 @@ #include #include #include +#include #include "pagedrawmap.h" #include "drawmapwidget.h" @@ -28,19 +29,22 @@ { QGridLayout * pageLayout = new QGridLayout(); - pbUndo = addButton(tr("Undo"), pageLayout, 0, 0); - pbClear = addButton(tr("Clear"), pageLayout, 1, 0); - pbLoad = addButton(tr("Load"), pageLayout, 2, 0); - pbSave = addButton(tr("Save"), pageLayout, 3, 0); + cbEraser = new QCheckBox(tr("Eraser"), this); + pageLayout->addWidget(cbEraser, 0, 0); + pbUndo = addButton(tr("Undo"), pageLayout, 1, 0); + pbClear = addButton(tr("Clear"), pageLayout, 2, 0); + pbLoad = addButton(tr("Load"), pageLayout, 3, 0); + pbSave = addButton(tr("Save"), pageLayout, 4, 0); drawMapWidget = new DrawMapWidget(this); - pageLayout->addWidget(drawMapWidget, 0, 1, 5, 1); + pageLayout->addWidget(drawMapWidget, 0, 1, 6, 1); return pageLayout; } void PageDrawMap::connectSignals() { + connect(cbEraser, SIGNAL(toggled(bool)), drawMapWidget, SLOT(setErasing(bool))); connect(pbUndo, SIGNAL(clicked()), drawMapWidget, SLOT(undo())); connect(pbClear, SIGNAL(clicked()), drawMapWidget, SLOT(clear())); connect(pbLoad, SIGNAL(clicked()), this, SLOT(load())); diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pagedrawmap.h --- a/QTfrontend/ui/page/pagedrawmap.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pagedrawmap.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 @@ -41,6 +41,7 @@ QPushButton * pbClear; QPushButton * pbLoad; QPushButton * pbSave; + QCheckBox * cbEraser; private slots: void load(); diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pageeditteam.cpp --- a/QTfrontend/ui/page/pageeditteam.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pageeditteam.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 @@ -29,10 +29,9 @@ #include "sdlkeys.h" #include "SquareLabel.h" -#include "hats.h" #include "HWApplication.h" -#include "HWDataManager.h" +#include "DataManager.h" #include "pageeditteam.h" @@ -61,11 +60,12 @@ GBoxHedgehogs->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); QGridLayout * GBHLayout = new QGridLayout(GBoxHedgehogs); - HatsModel * hatsModel = new HatsModel(GBoxHedgehogs); + HatModel * hatModel = DataManager::instance().hatModel(); + for(int i = 0; i < HEDGEHOGS_PER_TEAM; i++) { HHHats[i] = new QComboBox(GBoxHedgehogs); - HHHats[i]->setModel(hatsModel); + HHHats[i]->setModel(hatModel); HHHats[i]->setIconSize(QSize(32, 37)); //HHHats[i]->setSizeAdjustPolicy(QComboBox::AdjustToContents); //HHHats[i]->setModelColumn(1); @@ -245,7 +245,7 @@ m_playerHash = "0000000000000000000000000000000000000000"; - HWDataManager & dataMgr = HWDataManager::instance(); + DataManager & dataMgr = DataManager::instance(); QStringList list; @@ -333,14 +333,14 @@ void PageEditTeam::CBFort_activated(const QString & fortname) { - HWDataManager & dataMgr = HWDataManager::instance(); + DataManager & dataMgr = DataManager::instance(); QPixmap pix(dataMgr.findFileForRead("Forts/" + fortname + "L.png")); FortPreview->setPixmap(pix); } void PageEditTeam::testSound() { - HWDataManager & dataMgr = HWDataManager::instance(); + DataManager & dataMgr = DataManager::instance(); QString voiceDir = QString("Sounds/voices/") + CBVoicepack->currentText(); diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pageeditteam.h --- a/QTfrontend/ui/page/pageeditteam.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pageeditteam.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pagefeedback.cpp --- a/QTfrontend/ui/page/pagefeedback.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pagefeedback.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pagefeedback.h --- a/QTfrontend/ui/page/pagefeedback.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pagefeedback.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pagegamestats.cpp --- a/QTfrontend/ui/page/pagegamestats.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pagegamestats.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2010-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pagegamestats.h --- a/QTfrontend/ui/page/pagegamestats.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pagegamestats.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2010-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pageinfo.cpp --- a/QTfrontend/ui/page/pageinfo.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pageinfo.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pageinfo.h --- a/QTfrontend/ui/page/pageinfo.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pageinfo.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pageingame.cpp --- a/QTfrontend/ui/page/pageingame.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pageingame.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pageingame.h --- a/QTfrontend/ui/page/pageingame.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pageingame.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pagemain.cpp --- a/QTfrontend/ui/page/pagemain.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pagemain.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pagemain.h --- a/QTfrontend/ui/page/pagemain.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pagemain.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pagemultiplayer.cpp --- a/QTfrontend/ui/page/pagemultiplayer.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pagemultiplayer.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pagemultiplayer.h --- a/QTfrontend/ui/page/pagemultiplayer.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pagemultiplayer.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pagenet.cpp --- a/QTfrontend/ui/page/pagenet.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pagenet.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pagenet.h --- a/QTfrontend/ui/page/pagenet.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pagenet.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pagenetgame.cpp --- a/QTfrontend/ui/page/pagenetgame.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pagenetgame.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 @@ -40,6 +40,7 @@ pChatWidget = new HWChatWidget(this, m_gameSettings, true); pChatWidget->setShowReady(true); // show status bulbs by default pChatWidget->setShowFollow(false); // don't show follow in nicks' context menus + pChatWidget->setIgnoreListKick(true); // kick ignored players automatically pageLayout->addWidget(pChatWidget, 2, 0, 1, 2); pageLayout->setRowStretch(1, 100); pageLayout->setRowStretch(2, 100); diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pagenetgame.h --- a/QTfrontend/ui/page/pagenetgame.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pagenetgame.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pagenetserver.cpp --- a/QTfrontend/ui/page/pagenetserver.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pagenetserver.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pagenetserver.h --- a/QTfrontend/ui/page/pagenetserver.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pagenetserver.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pagenettype.cpp --- a/QTfrontend/ui/page/pagenettype.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pagenettype.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pagenettype.h --- a/QTfrontend/ui/page/pagenettype.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pagenettype.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pageoptions.cpp --- a/QTfrontend/ui/page/pageoptions.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pageoptions.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 @@ -187,28 +187,12 @@ groupMisc->setTitle(QGroupBox::tr("Misc")); QGridLayout * MiscLayout = new QGridLayout(groupMisc); - labelNN = new QLabel(groupMisc); - labelNN->setText(QLabel::tr("Net nick")); - MiscLayout->addWidget(labelNN, 0, 0); - - editNetNick = new QLineEdit(groupMisc); - editNetNick->setMaxLength(20); - editNetNick->setText(QLineEdit::tr("unnamed")); - connect(editNetNick, SIGNAL(editingFinished()), this, SLOT(trimNetNick())); - MiscLayout->addWidget(editNetNick, 0, 1); - - labelNetPassword = new QLabel(groupMisc); - labelNetPassword->setText(QLabel::tr("Password")); - MiscLayout->addWidget(labelNetPassword, 1, 0); - - editNetPassword = new QLineEdit(groupMisc); - editNetPassword->setEchoMode(QLineEdit::Password); - MiscLayout->addWidget(editNetPassword, 1, 1); - + // Label for "Language" QLabel *labelLanguage = new QLabel(groupMisc); labelLanguage->setText(QLabel::tr("Locale") + " *"); - MiscLayout->addWidget(labelLanguage, 2, 0); + MiscLayout->addWidget(labelLanguage, 0, 0); + // List of installed languages CBLanguage = new QComboBox(groupMisc); QDir tmpdir; tmpdir.cd(cfgdir->absolutePath()); @@ -233,26 +217,49 @@ CBLanguage->addItem(QLocale::languageToString(loc.language()) + " (" + QLocale::countryToString(loc.country()) + ")", loc.name()); } - MiscLayout->addWidget(CBLanguage, 2, 1); + MiscLayout->addWidget(CBLanguage, 0, 1); + + // Label and field for net nick + labelNN = new QLabel(groupMisc); + labelNN->setText(QLabel::tr("Nickname")); + MiscLayout->addWidget(labelNN, 1, 0); + + editNetNick = new QLineEdit(groupMisc); + editNetNick->setMaxLength(20); + editNetNick->setText(QLineEdit::tr("anonymous")); + MiscLayout->addWidget(editNetNick, 1, 1); + + // Label and field for password + labelNetPassword = new QLabel(groupMisc); + labelNetPassword->setText(QLabel::tr("Password")); + MiscLayout->addWidget(labelNetPassword, 2, 0); + + editNetPassword = new QLineEdit(groupMisc); + editNetPassword->setEchoMode(QLineEdit::Password); + MiscLayout->addWidget(editNetPassword, 2, 1); + + CBSavePassword = new QCheckBox(groupMisc); + CBSavePassword->setText(QCheckBox::tr("Save password")); + MiscLayout->addWidget(CBSavePassword, 3, 0, 1, 2); CBAltDamage = new QCheckBox(groupMisc); CBAltDamage->setText(QCheckBox::tr("Alternative damage show")); - MiscLayout->addWidget(CBAltDamage, 3, 0, 1, 2); + MiscLayout->addWidget(CBAltDamage, 4, 0, 1, 2); CBNameWithDate = new QCheckBox(groupMisc); CBNameWithDate->setText(QCheckBox::tr("Append date and time to record file name")); - MiscLayout->addWidget(CBNameWithDate, 4, 0, 1, 2); + MiscLayout->addWidget(CBNameWithDate, 5, 0, 1, 2); BtnAssociateFiles = new QPushButton(groupMisc); BtnAssociateFiles->setText(QPushButton::tr("Associate file extensions")); BtnAssociateFiles->setEnabled(!custom_data && !custom_config); - MiscLayout->addWidget(BtnAssociateFiles, 5, 0, 1, 2); + MiscLayout->addWidget(BtnAssociateFiles, 6, 0, 1, 2); #ifdef __APPLE__ #ifdef SPARKLE_ENABLED CBAutoUpdate = new QCheckBox(groupMisc); CBAutoUpdate->setText(QCheckBox::tr("Check for updates at startup")); - MiscLayout->addWidget(CBAutoUpdate, 6, 0, 1, 3); + MiscLayout->addWidget(CBAutoUpdate, 7, 0, 1, 3); #endif #endif gbTBLayout->addWidget(groupMisc, 2, 0); @@ -338,7 +345,6 @@ CBStereoMode->addItem(QComboBox::tr("Blue/Red grayscale")); CBStereoMode->addItem(QComboBox::tr("Red/Green grayscale")); CBStereoMode->addItem(QComboBox::tr("Green/Red grayscale")); - connect(CBStereoMode, SIGNAL(currentIndexChanged(int)), this, SLOT(forceFullscreen(int))); GBAstereolayout->addWidget(CBStereoMode); GBAlayout->addLayout(GBAstereolayout); @@ -402,9 +408,12 @@ void PageOptions::connectSignals() { + connect(SLQuality, SIGNAL(valueChanged(int)), this, SLOT(setQuality(int))); connect(CBResolution, SIGNAL(currentIndexChanged(int)), this, SLOT(setResolution(int))); connect(CBFullscreen, SIGNAL(stateChanged(int)), this, SLOT(setFullscreen(int))); - connect(SLQuality, SIGNAL(valueChanged(int)), this, SLOT(setQuality(int))); + connect(CBStereoMode, SIGNAL(currentIndexChanged(int)), this, SLOT(forceFullscreen(int))); + connect(editNetNick, SIGNAL(editingFinished()), this, SLOT(trimNetNick())); + connect(CBSavePassword, SIGNAL(stateChanged(int)), this, SLOT(savePwdChanged(int))); } PageOptions::PageOptions(QWidget* parent) : AbstractPage(parent) @@ -466,6 +475,14 @@ editNetNick->setText(editNetNick->text().trimmed()); } +void PageOptions::savePwdChanged(int state) { + if (state == 0) { + editNetPassword->setEnabled(false); + editNetPassword->setText(""); + } else + editNetPassword->setEnabled(true); +} + void PageOptions::requestEditSelectedTeam() { emit editTeamRequested(CBTeamName->currentText()); diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pageoptions.h --- a/QTfrontend/ui/page/pageoptions.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pageoptions.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 @@ -56,6 +56,7 @@ QCheckBox *CBFullscreen; QCheckBox *CBFrontendFullscreen; QCheckBox *CBShowFPS; + QCheckBox *CBSavePassword; QCheckBox *CBAltDamage; QCheckBox *CBNameWithDate; #ifdef __APPLE__ @@ -100,6 +101,7 @@ void trimNetNick(); void requestEditSelectedTeam(); void requestDeleteSelectedTeam(); + void savePwdChanged(int state); }; #endif diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pageplayrecord.cpp --- a/QTfrontend/ui/page/pageplayrecord.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pageplayrecord.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ +#include "pageplayrecord.h" + #include #include #include @@ -26,7 +28,8 @@ #include #include "hwconsts.h" -#include "pageplayrecord.h" + +#include "DataManager.h" QLayout * PagePlayDemo::bodyLayoutDefinition() { @@ -61,6 +64,7 @@ { connect(BtnRenameRecord, SIGNAL(clicked()), this, SLOT(renameRecord())); connect(BtnRemoveRecord, SIGNAL(clicked()), this, SLOT(removeRecord())); + connect(&DataManager::instance(), SIGNAL(updated()), this, SLOT(refresh())); } PagePlayDemo::PagePlayDemo(QWidget* parent) : AbstractPage(parent) @@ -103,6 +107,14 @@ } } + +void PagePlayDemo::refresh() +{ + if (this->isVisible()); + FillFromDir(recType); +} + + void PagePlayDemo::renameRecord() { QListWidgetItem * curritem = DemosList->currentItem(); diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pageplayrecord.h --- a/QTfrontend/ui/page/pageplayrecord.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pageplayrecord.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 @@ -47,6 +47,9 @@ QPushButton *BtnRemoveRecord; QListWidget *DemosList; + public slots: + void refresh(); + private: QLayout * bodyLayoutDefinition(); void connectSignals(); diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pageroomslist.cpp --- a/QTfrontend/ui/page/pageroomslist.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pageroomslist.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 @@ -26,6 +26,10 @@ #include #include +#include + +#include "roomslistmodel.h" + #include "ammoSchemeModel.h" #include "pageroomslist.h" #include "hwconsts.h" @@ -61,7 +65,7 @@ filterLayout->addWidget(stateLabel); filterLayout->addWidget(CBState); - filterLayout->addSpacing(30); + filterLayout->addStretch(1); QLabel * ruleLabel = new QLabel(this); ruleLabel->setText(tr("Rules:")); @@ -69,7 +73,7 @@ filterLayout->addWidget(ruleLabel); filterLayout->addWidget(CBRules); - filterLayout->addSpacing(30); + filterLayout->addStretch(1); QLabel * weaponLabel = new QLabel(this); weaponLabel->setText(tr("Weapons:")); @@ -77,14 +81,17 @@ filterLayout->addWidget(weaponLabel); filterLayout->addWidget(CBWeapons); - filterLayout->addSpacing(30); + filterLayout->addStretch(1); QLabel * searchLabel = new QLabel(this); searchLabel->setText(tr("Search:")); searchText = new QLineEdit(this); searchText->setMaxLength(60); + searchText->setMinimumWidth(100); + searchText->setMaximumWidth(360); filterLayout->addWidget(searchLabel); filterLayout->addWidget(searchText); + filterLayout->setStretchFactor(searchText, 2); pageLayout->addLayout(filterLayout, 4, 0, 1, 2); @@ -139,11 +146,21 @@ connect(BtnRefresh, SIGNAL(clicked()), this, SLOT(onRefreshClick())); connect(BtnClear, SIGNAL(clicked()), this, SLOT(onClearClick())); connect(roomsList, SIGNAL(doubleClicked (const QModelIndex &)), this, SLOT(onJoinClick())); - connect(CBState, SIGNAL(currentIndexChanged (int)), this, SLOT(onRefreshClick())); - connect(CBRules, SIGNAL(currentIndexChanged (int)), this, SLOT(onRefreshClick())); - connect(CBWeapons, SIGNAL(currentIndexChanged (int)), this, SLOT(onRefreshClick())); - connect(searchText, SIGNAL(textChanged (const QString &)), this, SLOT(onRefreshClick())); + connect(CBState, SIGNAL(currentIndexChanged (int)), this, SLOT(onFilterChanged())); + connect(CBRules, SIGNAL(currentIndexChanged (int)), this, SLOT(onFilterChanged())); + connect(CBWeapons, SIGNAL(currentIndexChanged (int)), this, SLOT(onFilterChanged())); + connect(searchText, SIGNAL(textChanged (const QString &)), this, SLOT(onFilterChanged())); connect(this, SIGNAL(askJoinConfirmation (const QString &)), this, SLOT(onJoinConfirmation(const QString &)), Qt::QueuedConnection); + + // save header state on change + connect(roomsList->horizontalHeader(), SIGNAL(sortIndicatorChanged(int, Qt::SortOrder)), + this, SLOT(saveHeaderState())); + connect(roomsList->horizontalHeader(), SIGNAL(sectionResized), + this, SLOT(saveHeaderState())); + + // sorting + connect(roomsList->horizontalHeader(), SIGNAL(sortIndicatorChanged(int, Qt::SortOrder)), + this, SLOT(onSortIndicatorChanged(int, Qt::SortOrder))); } @@ -152,6 +169,11 @@ { m_gameSettings = gameSettings; + roomsModel = NULL; + stateFilteredModel = NULL; + schemeFilteredModel = NULL; + weaponsFilteredModel = NULL; + initPage(); // not the most elegant solution but it works @@ -472,18 +494,118 @@ chatWidget->setUser(nickname); } -void PageRoomsList::setModel(QAbstractTableModel *model) +void PageRoomsList::setModel(RoomsListModel * model) { - roomsList->setModel(model); + // filter chain: + // model -> stateFilteredModel -> schemeFilteredModel -> + // -> weaponsFilteredModel -> roomsModel (search filter+sorting) + + if (roomsModel == NULL) + { + roomsModel = new QSortFilterProxyModel(this); + roomsModel->setDynamicSortFilter(true); + roomsModel->setSortCaseSensitivity(Qt::CaseInsensitive); + roomsModel->sort(RoomsListModel::StateColumn, Qt::AscendingOrder); + + stateFilteredModel = new QSortFilterProxyModel(this); + schemeFilteredModel = new QSortFilterProxyModel(this); + weaponsFilteredModel = new QSortFilterProxyModel(this); + + stateFilteredModel->setDynamicSortFilter(true); + schemeFilteredModel->setDynamicSortFilter(true); + weaponsFilteredModel->setDynamicSortFilter(true); - roomsList->hideColumn(0); + roomsModel->setFilterKeyColumn(-1); // search in all columns + stateFilteredModel->setFilterKeyColumn(RoomsListModel::StateColumn); + schemeFilteredModel->setFilterKeyColumn(RoomsListModel::SchemeColumn); + weaponsFilteredModel->setFilterKeyColumn(RoomsListModel::WeaponsColumn); + + roomsModel->setFilterCaseSensitivity(Qt::CaseInsensitive); + schemeFilteredModel->setFilterCaseSensitivity(Qt::CaseInsensitive); + weaponsFilteredModel->setFilterCaseSensitivity(Qt::CaseInsensitive); + + schemeFilteredModel->setSourceModel(stateFilteredModel); + weaponsFilteredModel->setSourceModel(schemeFilteredModel); + roomsModel->setSourceModel(weaponsFilteredModel); + + // let the table view display the last model in the filter chain + roomsList->setModel(roomsModel); + } + + stateFilteredModel->setSourceModel(model); + + roomsList->hideColumn(RoomsListModel::StateColumn); QHeaderView * h = roomsList->horizontalHeader(); - h->resizeSection(1, 200); - h->resizeSection(2, 50); - h->resizeSection(3, 50); - h->resizeSection(4, 100); - h->resizeSection(5, 100); - h->resizeSection(6, 100); - h->resizeSection(7, 100); + + if (!restoreHeaderState()) + { + h->resizeSection(RoomsListModel::PlayerCountColumn, 32); + h->resizeSection(RoomsListModel::TeamCountColumn, 32); + h->resizeSection(RoomsListModel::OwnerColumn, 100); + h->resizeSection(RoomsListModel::MapColumn, 100); + h->resizeSection(RoomsListModel::SchemeColumn, 100); + h->resizeSection(RoomsListModel::WeaponsColumn, 100); + } + + h->setSortIndicatorShown(true); + h->setResizeMode(RoomsListModel::NameColumn, QHeaderView::Stretch); +} + + +void PageRoomsList::onSortIndicatorChanged(int logicalIndex, Qt::SortOrder order) +{ + if (roomsModel == NULL) + return; + + // three state sorting: asc -> dsc -> default (by room state) + if ((order == Qt::AscendingOrder) && (logicalIndex == roomsModel->sortColumn())) + roomsList->horizontalHeader()->setSortIndicator( + RoomsListModel::StateColumn, Qt::AscendingOrder); + else + roomsModel->sort(logicalIndex, order); } + + +void PageRoomsList::onFilterChanged() +{ + if (roomsModel == NULL) + return; + + roomsModel->setFilterWildcard(QString("*%1*").arg(searchText->text())); + + int stateIdx = CBState->currentIndex(); + // any = 0, in lobby/false = 1, in progress/true = 2 + + if (stateIdx == 0) + stateFilteredModel->setFilterWildcard("*"); // "any" + else + stateFilteredModel->setFilterFixedString(QString(stateIdx == 2)); + + if (CBRules->currentIndex() == 0) + schemeFilteredModel->setFilterWildcard("*"); // "any" + else + schemeFilteredModel->setFilterWildcard( + QString("*%1*").arg(CBRules->currentText())); + + if (CBWeapons->currentIndex() == 0) + weaponsFilteredModel->setFilterWildcard("*"); // "any" + else + weaponsFilteredModel->setFilterWildcard( + QString("*%1*").arg(CBWeapons->currentText())); +} + + +bool PageRoomsList::restoreHeaderState() +{ + if (!m_gameSettings->contains("frontend/roomslist_header")) + return false; + return roomsList->horizontalHeader()->restoreState(QByteArray::fromHex( + (m_gameSettings->value("frontend/roomslist_header").toByteArray()))); +} + +void PageRoomsList::saveHeaderState() +{ + m_gameSettings->setValue("frontend/roomslist_header", + roomsList->horizontalHeader()->saveState().toHex()); +} diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pageroomslist.h --- a/QTfrontend/ui/page/pageroomslist.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pageroomslist.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 @@ -24,6 +24,8 @@ class HWChatWidget; class AmmoSchemeModel; class QTableView; +class RoomsListModel; +class QSortFilterProxyModel; class PageRoomsList : public AbstractPage { @@ -49,7 +51,7 @@ HWChatWidget * chatWidget; QLabel * lblCount; - void setModel(QAbstractTableModel * model); + void setModel(RoomsListModel * model); public slots: void setAdmin(bool); @@ -73,12 +75,20 @@ void onRefreshClick(); void onClearClick(); void onJoinConfirmation(const QString &); + void onSortIndicatorChanged(int logicalIndex, Qt::SortOrder order); + void onFilterChanged(); + void saveHeaderState(); private: QSettings * m_gameSettings; + QSortFilterProxyModel * roomsModel; + QSortFilterProxyModel * stateFilteredModel; + QSortFilterProxyModel * schemeFilteredModel; + QSortFilterProxyModel * weaponsFilteredModel; AmmoSchemeModel * ammoSchemeModel; + bool restoreHeaderState(); }; #endif diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pagescheme.cpp --- a/QTfrontend/ui/page/pagescheme.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pagescheme.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pagescheme.h --- a/QTfrontend/ui/page/pagescheme.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pagescheme.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pageselectweapon.cpp --- a/QTfrontend/ui/page/pageselectweapon.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pageselectweapon.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pageselectweapon.h --- a/QTfrontend/ui/page/pageselectweapon.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pageselectweapon.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pagesingleplayer.cpp --- a/QTfrontend/ui/page/pagesingleplayer.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pagesingleplayer.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pagesingleplayer.h --- a/QTfrontend/ui/page/pagesingleplayer.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pagesingleplayer.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pagetraining.cpp --- a/QTfrontend/ui/page/pagetraining.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pagetraining.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 @@ -28,7 +28,7 @@ #include #include "hwconsts.h" -#include "HWDataManager.h" +#include "DataManager.h" #include "pagetraining.h" @@ -115,7 +115,7 @@ { initPage(); - HWDataManager & dataMgr = HWDataManager::instance(); + DataManager & dataMgr = DataManager::instance(); // get locale QSettings settings(cfgdir->absolutePath() + "/hedgewars.ini", @@ -186,7 +186,7 @@ void PageTraining::updateInfo() { - HWDataManager & dataMgr = HWDataManager::instance(); + DataManager & dataMgr = DataManager::instance(); if (lstMissions->currentItem()) { diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/page/pagetraining.h --- a/QTfrontend/ui/page/pagetraining.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/page/pagetraining.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/FreqSpinBox.cpp --- a/QTfrontend/ui/widget/FreqSpinBox.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/FreqSpinBox.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2005-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/FreqSpinBox.h --- a/QTfrontend/ui/widget/FreqSpinBox.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/FreqSpinBox.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2005-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/HistoryLineEdit.cpp --- a/QTfrontend/ui/widget/HistoryLineEdit.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/HistoryLineEdit.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,7 +1,7 @@ /* * Hedgewars, a free turn based strategy game * Copyright (c) 2006-2007 Igor Ulyanov - * Copyright (c) 2007-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/HistoryLineEdit.h --- a/QTfrontend/ui/widget/HistoryLineEdit.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/HistoryLineEdit.h Wed May 02 23:53:45 2012 +0200 @@ -1,7 +1,7 @@ /* * Hedgewars, a free turn based strategy game * Copyright (c) 2006-2007 Igor Ulyanov - * Copyright (c) 2007-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/SmartLineEdit.cpp --- a/QTfrontend/ui/widget/SmartLineEdit.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/SmartLineEdit.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,7 +1,7 @@ /* * Hedgewars, a free turn based strategy game * Copyright (c) 2006-2007 Igor Ulyanov - * Copyright (c) 2007-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/SmartLineEdit.h --- a/QTfrontend/ui/widget/SmartLineEdit.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/SmartLineEdit.h Wed May 02 23:53:45 2012 +0200 @@ -1,7 +1,7 @@ /* * Hedgewars, a free turn based strategy game * Copyright (c) 2006-2007 Igor Ulyanov - * Copyright (c) 2007-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/SquareLabel.cpp --- a/QTfrontend/ui/widget/SquareLabel.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/SquareLabel.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/SquareLabel.h --- a/QTfrontend/ui/widget/SquareLabel.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/SquareLabel.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/about.cpp --- a/QTfrontend/ui/widget/about.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/about.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/about.h --- a/QTfrontend/ui/widget/about.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/about.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/bgwidget.cpp --- a/QTfrontend/ui/widget/bgwidget.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/bgwidget.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,7 +1,7 @@ /* * Hedgewars, a free turn based strategy game * Copyright (c) 2009 Kristian Lehmann - * Copyright (c) 2009-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/bgwidget.h --- a/QTfrontend/ui/widget/bgwidget.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/bgwidget.h Wed May 02 23:53:45 2012 +0200 @@ -1,7 +1,7 @@ /* * Hedgewars, a free turn based strategy game * Copyright (c) 2009 Kristian Lehmann - * Copyright (c) 2009-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/chatwidget.cpp --- a/QTfrontend/ui/widget/chatwidget.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/chatwidget.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,7 +1,7 @@ /* * Hedgewars, a free turn based strategy game * Copyright (c) 2007 Igor Ulyanov - * Copyright (c) 2007-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 @@ -37,7 +37,7 @@ #include -#include "HWDataManager.h" +#include "DataManager.h" #include "hwconsts.h" #include "gameuiconfig.h" @@ -126,7 +126,7 @@ if (orgStyleSheet.isEmpty()) { // load external stylesheet if there is any - QFile extFile(HWDataManager::instance().findFileForRead("css/chat.css")); + QFile extFile(DataManager::instance().findFileForRead("css/chat.css")); QFile resFile(":/res/css/chat.css"); @@ -247,17 +247,22 @@ this->notify = notify; m_isAdmin = false; + m_autoKickEnabled = false; if(gameSettings->value("frontend/sound", true).toBool()) { - if (notify) - m_helloSound = HWDataManager::instance().findFileForRead( - "Sounds/voices/Classic/Hello.ogg"); + QStringList vpList = + QStringList() << "Classic" << "Default" << "Mobster" << "Russian"; - m_hilightSound = HWDataManager::instance().findFileForRead( + foreach (QString vp, vpList) + { + m_helloSounds.append(DataManager::instance().findFileForRead( + QString("Sounds/voices/%1/Hello.ogg").arg(vp))); + } + + m_hilightSound = DataManager::instance().findFileForRead( "Sounds/beep.ogg"); - //m_hilightSound = m_helloSound;//"Sounds/beep.ogg"; } mainLayout.setSpacing(1); @@ -395,6 +400,11 @@ } } +void HWChatWidget::setIgnoreListKick(bool enabled) +{ + m_autoKickEnabled = enabled; +} + void HWChatWidget::loadList(QStringList & list, const QString & file) { list.clear(); @@ -632,6 +642,13 @@ void HWChatWidget::nickAdded(const QString & nick, bool notifyNick) { bool isIgnored = ignoreList.contains(nick, Qt::CaseInsensitive); + + if (isIgnored && m_isAdmin && m_autoKickEnabled) + { + emit kick(nick); + return; + } + QListWidgetItem * item = new ListWidgetNickItem(nick, friendsList.contains(nick, Qt::CaseInsensitive), isIgnored); updateNickItem(item); chatNicks->addItem(item); @@ -643,7 +660,8 @@ if(notifyNick && notify && gameSettings->value("frontend/sound", true).toBool()) { - SDLInteraction::instance().playSoundFile(m_helloSound); + SDLInteraction::instance().playSoundFile( + m_helloSounds.at(rand() % m_helloSounds.size())); } } @@ -968,7 +986,7 @@ void HWChatWidget::saveStyleSheet() { QString dest = - HWDataManager::instance().findFileForWrite("css/chat.css"); + DataManager::instance().findFileForWrite("css/chat.css"); QFile file(dest); if (file.open(QIODevice::WriteOnly | QIODevice::Text)) diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/chatwidget.h --- a/QTfrontend/ui/widget/chatwidget.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/chatwidget.h Wed May 02 23:53:45 2012 +0200 @@ -1,7 +1,7 @@ /* * Hedgewars, a free turn based strategy game * Copyright (c) 2007 Igor Ulyanov - * Copyright (c) 2007-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 @@ -72,6 +72,7 @@ HWChatWidget(QWidget* parent, QSettings * gameSettings, bool notify); void loadLists(const QString & nick); void saveLists(const QString & nick); + void setIgnoreListKick(bool enabled); ///< automatically kick people on ignore list (if possible) void setShowReady(bool s); void setShowFollow(bool enabled); QStringList ignoreList, friendsList; @@ -136,13 +137,14 @@ QAction * acIgnore; QAction * acFriend; QSettings * gameSettings; - QString m_helloSound; + QStringList m_helloSounds; QString m_hilightSound; QString m_userNick; QString m_clickedNick; QList m_highlights; ///< regular expressions used for highlighting bool notify; bool showReady; + bool m_autoKickEnabled; private slots: void returnPressed(); diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/databrowser.cpp --- a/QTfrontend/ui/widget/databrowser.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/databrowser.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,3 +1,26 @@ +/* + * Hedgewars, a free turn based strategy game + * Copyright (c) 2004-2012 Andrey Korotaev + * + * 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 + */ + +/** + * @file + * @brief DataBrowser class implementation + */ + #include #include #include diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/databrowser.h --- a/QTfrontend/ui/widget/databrowser.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/databrowser.h Wed May 02 23:53:45 2012 +0200 @@ -1,5 +1,28 @@ -#ifndef DATABROWSER_H -#define DATABROWSER_H +/* + * Hedgewars, a free turn based strategy game + * Copyright (c) 2004-2012 Andrey Korotaev + * + * 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 + */ + +/** + * @file + * @brief DataBrowser class definition + */ + +#ifndef HEDGEWARS_DATABROWSER_H +#define HEDGEWARS_DATABROWSER_H #include #include @@ -30,4 +53,4 @@ void resourceDownloaded(); }; -#endif // DATABROWSER_H +#endif // HEDGEWARS_DATABROWSER_H diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/drawmapwidget.cpp --- a/QTfrontend/ui/widget/drawmapwidget.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/drawmapwidget.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 @@ -19,6 +19,7 @@ #include #include #include +#include #include "drawmapwidget.h" @@ -51,8 +52,10 @@ void DrawMapWidget::setScene(DrawMapScene * scene) { + m_scene = scene; + ui->graphicsView->setScene(scene); - m_scene = scene; + connect(scene, SIGNAL(pathChanged()), this, SLOT(pathChanged())); } void DrawMapWidget::resizeEvent(QResizeEvent * event) @@ -80,6 +83,11 @@ if(m_scene) m_scene->clearMap(); } +void DrawMapWidget::setErasing(bool erasing) +{ + if(m_scene) m_scene->setErasing(erasing); +} + void DrawMapWidget::save(const QString & fileName) { if(m_scene) @@ -105,3 +113,53 @@ m_scene->decode(qUncompress(QByteArray::fromBase64(f.readAll()))); } } + +void DrawMapWidget::pathChanged() +{ + ui->lblPoints->setNum(m_scene->pointsCount()); +} + + + +DrawMapView::DrawMapView(QWidget *parent) : + QGraphicsView(parent) +{ + setMouseTracking(true); + + m_scene = 0; +} + + +DrawMapView::~DrawMapView() +{ + +} + +void DrawMapView::setScene(DrawMapScene *scene) +{ + m_scene = scene; + + QGraphicsView::setScene(scene); +} + +// Why don't I ever recieve this event? +void DrawMapView::enterEvent(QEvent *event) +{ + if(m_scene) + m_scene->showCursor(); + + QGraphicsView::enterEvent(event); +} + +void DrawMapView::leaveEvent(QEvent *event) +{ + if(m_scene) + m_scene->hideCursor(); + + QGraphicsView::leaveEvent(event); +} + +bool DrawMapView::viewportEvent(QEvent *event) +{ + return QGraphicsView::viewportEvent(event); +} diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/drawmapwidget.h --- a/QTfrontend/ui/widget/drawmapwidget.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/drawmapwidget.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 @@ -23,23 +23,50 @@ #include #include #include +#include #include "qaspectratiolayout.h" #include "drawmapscene.h" + +class DrawMapView : public QGraphicsView +{ + Q_OBJECT + +public: + explicit DrawMapView(QWidget *parent = 0); + ~DrawMapView(); + + void setScene(DrawMapScene *scene); + +protected: + void enterEvent(QEvent * event); + void leaveEvent(QEvent * event); + bool viewportEvent(QEvent * event); + +private: + DrawMapScene * m_scene; +}; + namespace Ui { class Ui_DrawMapWidget { public: - QGraphicsView *graphicsView; + DrawMapView *graphicsView; + QLabel * lblPoints; void setupUi(QWidget *drawMapWidget) { - QAspectRatioLayout * arLayout = new QAspectRatioLayout(drawMapWidget); + QVBoxLayout * vbox = new QVBoxLayout(drawMapWidget); + vbox->setMargin(0); + lblPoints = new QLabel("0", drawMapWidget); + vbox->addWidget(lblPoints); + QAspectRatioLayout * arLayout = new QAspectRatioLayout(); arLayout->setMargin(0); + vbox->addLayout(arLayout); - graphicsView = new QGraphicsView(drawMapWidget); + graphicsView = new DrawMapView(drawMapWidget); arLayout->addWidget(graphicsView); retranslateUi(drawMapWidget); @@ -70,6 +97,7 @@ public slots: void undo(); void clear(); + void setErasing(bool erasing); void save(const QString & fileName); void load(const QString & fileName); @@ -82,6 +110,9 @@ Ui::DrawMapWidget *ui; DrawMapScene * m_scene; + + private slots: + void pathChanged(); }; #endif // DRAWMAPWIDGET_H diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/fpsedit.cpp --- a/QTfrontend/ui/widget/fpsedit.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/fpsedit.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/fpsedit.h --- a/QTfrontend/ui/widget/fpsedit.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/fpsedit.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/frameTeam.cpp --- a/QTfrontend/ui/widget/frameTeam.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/frameTeam.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,7 +1,7 @@ /* * Hedgewars, a free turn based strategy game * Copyright (c) 2006-2007 Igor Ulyanov - * Copyright (c) 2007-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 @@ -56,15 +56,19 @@ void FrameTeams::resetColors() { - currentColor=availableColors.end() - 1; // ensure next color is the first one + currentColor = availableColors.last(); // ensure next color is the first one } QColor FrameTeams::getNextColor() const { - QList::ConstIterator nextColor=currentColor; - ++nextColor; - if (nextColor==availableColors.end()) nextColor=availableColors.begin(); - return *nextColor; + int idx = availableColors.indexOf(currentColor); + + idx++; + + if (idx >= availableColors.size()) + idx = 0; + + return availableColors.at(idx); } void FrameTeams::addTeam(HWTeam team, bool willPlay) diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/frameTeam.h --- a/QTfrontend/ui/widget/frameTeam.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/frameTeam.h Wed May 02 23:53:45 2012 +0200 @@ -1,7 +1,7 @@ /* * Hedgewars, a free turn based strategy game * Copyright (c) 2006-2007 Igor Ulyanov - * Copyright (c) 2007-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 @@ -55,7 +55,7 @@ const int maxHedgehogsPerGame; int overallHedgehogs; QList availableColors; - QList::Iterator currentColor; + QColor currentColor; void emitTeamColorChanged(const HWTeam& team); diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/gamecfgwidget.cpp --- a/QTfrontend/ui/widget/gamecfgwidget.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/gamecfgwidget.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 @@ -28,7 +28,7 @@ #include "gamecfgwidget.h" #include "igbox.h" -#include "HWDataManager.h" +#include "DataManager.h" #include "hwconsts.h" #include "ammoSchemeModel.h" #include "proto.h" @@ -56,41 +56,8 @@ Scripts = new QComboBox(GBoxOptions); GBoxOptionsLayout->addWidget(Scripts, 1, 1); - Scripts->addItem("Normal"); - Scripts->insertSeparator(1); - - for (int i = 0; i < scriptList->size(); ++i) - { - QString script = (*scriptList)[i].remove(".lua", Qt::CaseInsensitive); - QList scriptInfo; - scriptInfo.push_back(script); - QFile scriptCfgFile(HWDataManager::instance().findFileForRead( - QString("Scripts/Multiplayer/%2.cfg").arg(script))); - if (scriptCfgFile.exists() && scriptCfgFile.open(QFile::ReadOnly)) - { - QString scheme; - QString weapons; - QTextStream input(&scriptCfgFile); - input >> scheme; - input >> weapons; - if (scheme.isEmpty()) - scheme = "locked"; - scheme.replace("_", " "); - if (weapons.isEmpty()) - weapons = "locked"; - weapons.replace("_", " "); - scriptInfo.push_back(scheme); - scriptInfo.push_back(weapons); - scriptCfgFile.close(); - } - else - { - scriptInfo.push_back("locked"); - scriptInfo.push_back("locked"); - } - Scripts->addItem(script.replace("_", " "), scriptInfo); - } - + Scripts->setModel(DataManager::instance().gameStyleModel()); + m_curScript = Scripts->currentText(); connect(Scripts, SIGNAL(currentIndexChanged(int)), this, SLOT(scriptChanged(int))); QWidget *SchemeWidget = new QWidget(GBoxOptions); @@ -146,6 +113,8 @@ connect(pMapContainer, SIGNAL(newTemplateFilter(int)), this, SLOT(templateFilterChanged(int))); connect(pMapContainer, SIGNAL(drawMapRequested()), this, SIGNAL(goToDrawMap())); connect(pMapContainer, SIGNAL(drawnMapChanged(const QByteArray &)), this, SLOT(onDrawnMapChanged(const QByteArray &))); + + connect(&DataManager::instance(), SIGNAL(updated()), this, SLOT(updateModelViews())); } void GameCFGWidget::jumpToSchemes() @@ -244,7 +213,7 @@ if (Scripts->currentIndex() > 0) { - bcfg << QString("escript Scripts/Multiplayer/%1.lua").arg(Scripts->itemData(Scripts->currentIndex()).toList()[0].toString()).toUtf8(); + bcfg << QString("escript Scripts/Multiplayer/%1.lua").arg(Scripts->itemData(Scripts->currentIndex(), GameStyleModel::ScriptRole).toString()).toUtf8(); } bcfg << QString("eseed " + pMapContainer->getCurrentSeed()).toUtf8(); @@ -525,10 +494,13 @@ void GameCFGWidget::scriptChanged(int index) { + const QString & name = Scripts->itemText(index); + m_curScript = name; + if(isEnabled() && index > 0) { - QString scheme = Scripts->itemData(Scripts->currentIndex()).toList()[1].toString(); - QString weapons = Scripts->itemData(Scripts->currentIndex()).toList()[2].toString(); + QString scheme = Scripts->itemData(index, GameStyleModel::SchemeRole).toString(); + QString weapons = Scripts->itemData(index, GameStyleModel::WeaponsRole).toString(); if (scheme == "locked") { @@ -571,7 +543,7 @@ WeaponsName->setEnabled(true); bindEntries->setEnabled(true); } - emit paramChanged("SCRIPT", QStringList(Scripts->itemText(index))); + emit paramChanged("SCRIPT", QStringList(name)); } void GameCFGWidget::mapgenChanged(MapGenerator m) @@ -593,3 +565,17 @@ { emit paramChanged("DRAWNMAP", QStringList(qCompress(data, 9).toBase64())); } + + +void GameCFGWidget::updateModelViews() +{ + // restore game-style selection + if (!m_curScript.isEmpty()) + { + int idx = Scripts->findText(m_curScript); + if (idx >= 0) + Scripts->setCurrentIndex(idx); + else + Scripts->setCurrentIndex(0); + } +} diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/gamecfgwidget.h --- a/QTfrontend/ui/widget/gamecfgwidget.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/gamecfgwidget.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 @@ -72,6 +72,7 @@ void mapgenChanged(MapGenerator m); void maze_sizeChanged(int s); void onDrawnMapChanged(const QByteArray & data); + void updateModelViews(); private: QGridLayout mainLayout; @@ -79,6 +80,7 @@ QString curNetAmmoName; QString curNetAmmo; QRegExp seedRegexp; + QString m_curScript; void setNetAmmo(const QString& name, const QString& ammo); diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/hedgehogerWidget.cpp --- a/QTfrontend/ui/widget/hedgehogerWidget.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/hedgehogerWidget.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,7 +1,7 @@ /* * Hedgewars, a free turn based strategy game * Copyright (c) 2006-2008 Ulyanov Igor - * Copyright (c) 2008-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 @@ -19,6 +19,8 @@ #include "hedgehogerWidget.h" +#include + #include "frameTeam.h" CHedgehogerWidget::CHedgehogerWidget(const QImage& im, const QImage& img, QWidget * parent) : @@ -32,6 +34,8 @@ numItems = pOurFrameTeams->maxHedgehogsPerGame - pOurFrameTeams->overallHedgehogs; } else numItems = 4; pOurFrameTeams->overallHedgehogs += numItems;*/ + + this->setMinimumWidth(48); } void CHedgehogerWidget::incItems() @@ -74,3 +78,34 @@ { return numItems; } + +void CHedgehogerWidget::paintEvent(QPaintEvent* event) +{ + Q_UNUSED(event); + + if (this->width() >= 11 * numItems + 26) + ItemNum::paintEvent(event); + else + { + int width = this->width() - 38; + QPainter painter(this); + + for(int i=0; iwidth() - 12, 23, QString::number(numItems)); + +} diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/hedgehogerWidget.h --- a/QTfrontend/ui/widget/hedgehogerWidget.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/hedgehogerWidget.h Wed May 02 23:53:45 2012 +0200 @@ -1,7 +1,7 @@ /* * Hedgewars, a free turn based strategy game * Copyright (c) 2006-2007 Ulyanov Igor - * Copyright (c) 2007-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 @@ -42,6 +42,8 @@ virtual void incItems(); virtual void decItems(); + virtual void paintEvent(QPaintEvent* event); + private: CHedgehogerWidget(); FrameTeams* pOurFrameTeams; diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/igbox.cpp --- a/QTfrontend/ui/widget/igbox.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/igbox.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2008-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/igbox.h --- a/QTfrontend/ui/widget/igbox.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/igbox.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2008-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/itemNum.h --- a/QTfrontend/ui/widget/itemNum.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/itemNum.h Wed May 02 23:53:45 2012 +0200 @@ -32,13 +32,12 @@ unsigned char getItemsNum() const; void setItemsNum(const unsigned char num); - private: + protected: QImage m_im; QImage m_img; bool infinityState; bool enabled; - protected: ItemNum(const QImage& im, const QImage& img, QWidget * parent, unsigned char min=2, unsigned char max=8); virtual QSize sizeHint () const; virtual ~ItemNum()=0; diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/mapContainer.cpp --- a/QTfrontend/ui/widget/mapContainer.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/mapContainer.cpp Wed May 02 23:53:45 2012 +0200 @@ -68,104 +68,13 @@ chooseMap = new QComboBox(mapWidget); chooseMap->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); - chooseMap->addItem( -// FIXME - need real icons. Disabling until then -//QIcon(":/res/mapRandom.png"), - QComboBox::tr("generated map...")); - chooseMap->addItem( -// FIXME - need real icons. Disabling until then -//QIcon(":/res/mapMaze.png"), - QComboBox::tr("generated maze...")); - - chooseMap->addItem(QComboBox::tr("hand drawn map...")); - chooseMap->insertSeparator(chooseMap->count()); // separator between generators and missions - - chooseMap->insertSeparator(chooseMap->count()); // separator between generators and missions - - int missionindex = chooseMap->count(); - numMissions = 0; - QFile mapLuaFile; - QFile mapCfgFile; - for (int i = 0; i < mapList->size(); ++i) - { - QString map = (*mapList)[i]; - mapCfgFile.setFileName( - QString("%1/Data/Maps/%2/map.cfg") - .arg(cfgdir->absolutePath()) - .arg(map)); - if (mapCfgFile.exists()) - { - mapLuaFile.setFileName( - QString("%1/Data/Maps/%2/map.lua") - .arg(cfgdir->absolutePath()) - .arg(map)); - } - else - { - mapCfgFile.setFileName( - QString("%1/Maps/%2/map.cfg") - .arg(datadir->absolutePath()) - .arg(map)); - mapLuaFile.setFileName( - QString("%1/Maps/%2/map.lua") - .arg(datadir->absolutePath()) - .arg(map)); - } + m_mapModel = DataManager::instance().mapModel(); + chooseMap->setEditable(false); + chooseMap->setModel(m_mapModel); - if (mapCfgFile.open(QFile::ReadOnly)) - { - QString theme; - quint32 limit = 0; - QString scheme; - QString weapons; - QList mapInfo; - bool isMission = mapLuaFile.exists(); - - QTextStream input(&mapCfgFile); - input >> theme; - input >> limit; - input >> scheme; - input >> weapons; - mapInfo.push_back(map); - mapInfo.push_back(theme); - if (limit) - mapInfo.push_back(limit); - else - mapInfo.push_back(18); - - - mapInfo.push_back(isMission); + // update model views after model changes (to e.g. re-adjust separators) + connect(&DataManager::instance(), SIGNAL(updated()), this, SLOT(updateModelViews())); - if (scheme.isEmpty()) - scheme = "locked"; - scheme.replace("_", " "); - - if (weapons.isEmpty()) - weapons = "locked"; - weapons.replace("_", " "); - - mapInfo.push_back(scheme); - mapInfo.push_back(weapons); - - if(isMission) - { - chooseMap->insertItem(missionindex++, -// FIXME - need real icons. Disabling until then -//QIcon(":/res/mapMission.png"), - QComboBox::tr("Mission") + ": " + map, mapInfo); - numMissions++; - } - else - chooseMap->addItem( -// FIXME - need real icons. Disabling until then -//QIcon(":/res/mapCustom.png"), - map, mapInfo); - mapCfgFile.close(); - } - } - chooseMap->insertSeparator(missionindex); // separator between missions and maps - - connect(chooseMap, SIGNAL(activated(int)), this, SLOT(mapChanged(int))); mapLayout->addWidget(chooseMap, 1, 1); QLabel * lblMap = new QLabel(tr("Map"), mapWidget); @@ -208,14 +117,16 @@ //gbThemes->setStyleSheet("padding: 0px"); // doesn't work - stylesheet is set with icon mapLayout->addWidget(gbThemes, 0, 2, 3, 1); - + // disallow row to be collapsed (so it can't get ignored when Qt applies rowSpan of gbThemes) + mapLayout->setRowMinimumHeight(2, 13); QVBoxLayout * gbTLayout = new QVBoxLayout(gbThemes); gbTLayout->setContentsMargins(0, 0, 0 ,0); gbTLayout->setSpacing(0); lvThemes = new QListView(mapWidget); lvThemes->setMinimumHeight(30); lvThemes->setFixedWidth(140); - lvThemes->setModel(themesModel); + m_themeModel = DataManager::instance().themeModel(); + lvThemes->setModel(m_themeModel); lvThemes->setIconSize(QSize(16, 16)); lvThemes->setEditTriggers(QListView::NoEditTriggers); @@ -264,6 +175,12 @@ setRandomSeed(); setRandomTheme(); + + chooseMap->setCurrentIndex(0); + mapChanged(0); + connect(chooseMap, SIGNAL(currentIndexChanged(int)), this, SLOT(mapChanged(int))); + + updateModelViews(); } void HWMapContainer::setImage(const QImage newImage) @@ -294,9 +211,13 @@ void HWMapContainer::mapChanged(int index) { - switch(index) + Q_ASSERT(chooseMap->itemData(index, Qt::UserRole + 1).canConvert()); + m_mapInfo = chooseMap->itemData(index, Qt::UserRole + 1).value(); + m_curMap = chooseMap->currentText(); + + switch(m_mapInfo.type) { - case MAPGEN_REGULAR: + case MapModel::GeneratedMap: mapgen = MAPGEN_REGULAR; updatePreview(); gbThemes->show(); @@ -304,10 +225,8 @@ cbTemplateFilter->show(); maze_size_label->hide(); cbMazeSize->hide(); - emit mapChanged("+rnd+"); - emit themeChanged(chooseMap->itemData(index).toList()[1].toString()); break; - case MAPGEN_MAZE: + case MapModel::GeneratedMaze: mapgen = MAPGEN_MAZE; updatePreview(); gbThemes->show(); @@ -315,10 +234,8 @@ cbTemplateFilter->hide(); maze_size_label->show(); cbMazeSize->show(); - emit mapChanged("+maze+"); - emit themeChanged(chooseMap->itemData(index).toList()[1].toString()); break; - case MAPGEN_DRAWN: + case MapModel::HandDrawnMap: mapgen = MAPGEN_DRAWN; updatePreview(); gbThemes->show(); @@ -326,8 +243,6 @@ cbTemplateFilter->hide(); maze_size_label->hide(); cbMazeSize->hide(); - emit mapChanged("+drawn+"); - emit themeChanged(chooseMap->itemData(index).toList()[1].toString()); break; default: mapgen = MAPGEN_MAP; @@ -337,9 +252,16 @@ cbTemplateFilter->hide(); maze_size_label->hide(); cbMazeSize->hide(); - emit mapChanged(chooseMap->itemData(index).toList()[0].toString()); + m_theme = m_mapInfo.theme; } + // the map has no pre-defined theme, so let's use the selected one + if (m_mapInfo.theme.isEmpty()) + { + m_theme = lvThemes->currentIndex().data().toString(); + emit themeChanged(m_theme); + } + emit mapChanged(m_mapInfo.name); emit mapgenChanged(mapgen); } @@ -385,20 +307,10 @@ void HWMapContainer::themeSelected(const QModelIndex & current, const QModelIndex &) { - QString theme = current.data().toString(); - QList mapInfo; - mapInfo.push_back(QString("+rnd+")); - mapInfo.push_back(theme); - mapInfo.push_back(18); - mapInfo.push_back(false); - chooseMap->setItemData(0, mapInfo); - mapInfo[0] = QString("+maze+"); - chooseMap->setItemData(1, mapInfo); - mapInfo[0] = QString("+drawn+"); - chooseMap->setItemData(2, mapInfo); + m_theme = current.data().toString(); gbThemes->setIcon(qVariantValue(current.data(Qt::UserRole))); - emit themeChanged(theme); + emit themeChanged(m_theme); } QString HWMapContainer::getCurrentSeed() const @@ -409,18 +321,17 @@ QString HWMapContainer::getCurrentMap() const { if(chooseMap->currentIndex() < MAPGEN_MAP) return QString(); - return chooseMap->itemData(chooseMap->currentIndex()).toList()[0].toString(); + return(m_mapInfo.name); } QString HWMapContainer::getCurrentTheme() const { - return chooseMap->itemData(chooseMap->currentIndex()).toList()[1].toString(); + return(m_theme); } bool HWMapContainer::getCurrentIsMission() const { - if(!chooseMap->currentIndex()) return false; - return chooseMap->itemData(chooseMap->currentIndex()).toList()[3].toBool(); + return(m_mapInfo.type == MapModel::MissionMap); } int HWMapContainer::getCurrentHHLimit() const @@ -430,12 +341,12 @@ QString HWMapContainer::getCurrentScheme() const { - return chooseMap->itemData(chooseMap->currentIndex()).toList()[4].toString(); + return(m_mapInfo.scheme); } QString HWMapContainer::getCurrentWeapons() const { - return chooseMap->itemData(chooseMap->currentIndex()).toList()[5].toString(); + return(m_mapInfo.weapons); } quint32 HWMapContainer::getTemplateFilter() const @@ -459,21 +370,15 @@ void HWMapContainer::setSeed(const QString & seed) { intSetSeed(seed); - if (chooseMap->currentIndex() < MAPGEN_DRAWN) + if ((m_mapInfo.type == MapModel::GeneratedMap) || (m_mapInfo.type == MapModel::GeneratedMaze)) updatePreview(); } void HWMapContainer::intSetMap(const QString & map) { - int id = 0; - for(int i = 0; i < chooseMap->count(); i++) - if(!chooseMap->itemData(i).isNull() && chooseMap->itemData(i).toList()[0].toString() == map) - { - id = i; - break; - } + int id = m_mapModel->indexOf(map); - if(id > 0) + if(id >= 0) { if (pMap) { @@ -493,7 +398,7 @@ void HWMapContainer::setTheme(const QString & theme) { - QModelIndexList mdl = themesModel->match(themesModel->index(0), Qt::DisplayRole, theme); + QModelIndexList mdl = m_themeModel->match(m_themeModel->index(0), Qt::DisplayRole, theme); if(mdl.size()) lvThemes->setCurrentIndex(mdl.at(0)); @@ -501,53 +406,41 @@ void HWMapContainer::setRandomMap() { + int idx; + setRandomSeed(); - switch(chooseMap->currentIndex()) + switch(m_mapInfo.type) { - case MAPGEN_REGULAR: - case MAPGEN_MAZE: + case MapModel::GeneratedMap: + case MapModel::GeneratedMaze: setRandomTheme(); break; - case MAPGEN_DRAWN: + case MapModel::HandDrawnMap: emit drawMapRequested(); break; - default: - if(chooseMap->currentIndex() <= numMissions + MAPGEN_MAP + 1) - setRandomMission(); - else - setRandomStatic(); + case MapModel::MissionMap: + case MapModel::StaticMap: + // get random map of same type + idx = m_mapModel->randomMap(m_mapInfo.type); + chooseMap->setCurrentIndex(idx); break; + case MapModel::Invalid: + Q_ASSERT(false); } } -void HWMapContainer::setRandomStatic() -{ - int i = MAPGEN_MAP + 3 + numMissions + rand() % (chooseMap->count() - MAPGEN_MAP - 3 - numMissions); - chooseMap->setCurrentIndex(i); - mapChanged(i); -} - -void HWMapContainer::setRandomMission() -{ - int i = MAPGEN_MAP + 2 + rand() % numMissions; - chooseMap->setCurrentIndex(i); - mapChanged(i); -} void HWMapContainer::setRandomSeed() { - m_seed = QUuid::createUuid().toString(); - seedEdit->setText(m_seed); + setSeed(QUuid::createUuid().toString()); emit seedChanged(m_seed); - if (chooseMap->currentIndex() < MAPGEN_MAP) - updatePreview(); } void HWMapContainer::setRandomTheme() { - if(!themesModel->rowCount()) return; - quint32 themeNum = rand() % themesModel->rowCount(); - lvThemes->setCurrentIndex(themesModel->index(themeNum)); + if(!m_themeModel->rowCount()) return; + quint32 themeNum = rand() % m_themeModel->rowCount(); + lvThemes->setCurrentIndex(m_themeModel->index(themeNum)); } void HWMapContainer::intSetTemplateFilter(int filter) @@ -644,31 +537,31 @@ void HWMapContainer::updatePreview() { - int curIndex = chooseMap->currentIndex(); - - switch(curIndex) + switch(m_mapInfo.type) { - case MAPGEN_REGULAR: + case MapModel::GeneratedMap: askForGeneratedPreview(); break; - case MAPGEN_MAZE: + case MapModel::GeneratedMaze: askForGeneratedPreview(); break; - case MAPGEN_DRAWN: + case MapModel::HandDrawnMap: askForGeneratedPreview(); break; default: QPixmap mapImage; - QFile tmpfile; - tmpfile.setFileName(cfgdir->absolutePath() + "/Data/Maps/" + chooseMap->itemData(curIndex).toList()[0].toString() + "/preview.png"); - if (!tmpfile.exists()) tmpfile.setFileName(datadir->absolutePath() + "/Maps/" + chooseMap->itemData(curIndex).toList()[0].toString() + "/preview.png"); - if(!mapImage.load(QFileInfo(tmpfile).absoluteFilePath())) + bool success = mapImage.load( + DataManager::instance().findFileForRead( + "Maps/" + m_mapInfo.name + "/preview.png") + ); + + if(!success) { imageButt->setIcon(QIcon()); return; } - hhLimit = chooseMap->itemData(curIndex).toList()[2].toInt(); + hhLimit = m_mapInfo.limit; addInfoToPreview(mapImage); } } @@ -683,3 +576,29 @@ updatePreview(); } + + +void HWMapContainer::updateModelViews() +{ + // restore theme selection + // do this before map selection restore, because map may overwrite theme + if (!m_theme.isEmpty()) + { + QModelIndexList mdl = m_themeModel->match(m_themeModel->index(0), Qt::DisplayRole, m_theme); + if (mdl.size() > 0) + lvThemes->setCurrentIndex(mdl.at(0)); + else + setRandomTheme(); + } + + // restore map selection + if (!m_curMap.isEmpty()) + { + int idx = chooseMap->findText(m_curMap); + if (idx >= 0) + chooseMap->setCurrentIndex(idx); + else + chooseMap->setCurrentIndex(0); + } + +} diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/mapContainer.h --- a/QTfrontend/ui/widget/mapContainer.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/mapContainer.h Wed May 02 23:53:45 2012 +0200 @@ -1,7 +1,7 @@ /* * Hedgewars, a free turn based strategy game * Copyright (c) 2006-2007 Igor Ulyanov - * Copyright (c) 2007-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 @@ -27,12 +27,15 @@ #include #include +#include "DataManager.h" + #include "hwmap.h" #include "drawmapscene.h" class QPushButton; class IconedGroupBox; class QListView; +class SeparatorPainter; class MapFileErrorException { @@ -69,6 +72,7 @@ void setMazeSize(int size); void setDrawnMapData(const QByteArray & ar); void setAllMapParameters(const QString & map, MapGenerator m, int mazesize, const QString & seed, int tmpl); + void updateModelViews(); signals: void seedChanged(const QString & seed); @@ -87,8 +91,6 @@ void setRandomSeed(); void setRandomTheme(); void setRandomMap(); - void setRandomStatic(); - void setRandomMission(); void themeSelected(const QModelIndex & current, const QModelIndex &); void addInfoToPreview(QPixmap image); void seedEdited(); @@ -100,8 +102,10 @@ QGridLayout mainLayout; QPushButton* imageButt; QComboBox* chooseMap; + MapModel * m_mapModel; IconedGroupBox* gbThemes; QListView* lvThemes; + ThemeModel * m_themeModel; HWMap* pMap; QString m_seed; QPushButton* seedSet; @@ -114,7 +118,6 @@ QLabel *maze_size_label; QComboBox *cbMazeSize; MapGenerator mapgen; - int numMissions; DrawMapScene drawMapScene; void intSetSeed(const QString & seed); @@ -123,6 +126,10 @@ void intSetTemplateFilter(int); void intSetMazeSize(int size); void updatePreview(); + + MapModel::MapInfo m_mapInfo; + QString m_theme; + QString m_curMap; }; #endif // _HWMAP_CONTAINER_INCLUDED diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/qpushbuttonwithsound.cpp --- a/QTfrontend/ui/widget/qpushbuttonwithsound.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/qpushbuttonwithsound.cpp Wed May 02 23:53:45 2012 +0200 @@ -2,7 +2,7 @@ #include #include "qpushbuttonwithsound.h" -#include "HWDataManager.h" +#include "DataManager.h" #include "SDLInteraction.h" #include "hwform.h" #include "gameuiconfig.h" @@ -19,7 +19,7 @@ if ( !isSoundEnabled || !HWForm::config->isFrontendSoundEnabled()) return; - HWDataManager & dataMgr = HWDataManager::instance(); + DataManager & dataMgr = DataManager::instance(); if (this->isEnabled()) SDLInteraction::instance().playSoundFile(dataMgr.findFileForRead("Sounds/roperelease.ogg")); diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/selectWeapon.cpp --- a/QTfrontend/ui/widget/selectWeapon.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/selectWeapon.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,7 +1,7 @@ /* * Hedgewars, a free turn based strategy game * Copyright (c) 2006-2008 Igor Ulyanov - * Copyright (c) 2008-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/selectWeapon.h --- a/QTfrontend/ui/widget/selectWeapon.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/selectWeapon.h Wed May 02 23:53:45 2012 +0200 @@ -1,7 +1,7 @@ /* * Hedgewars, a free turn based strategy game * Copyright (c) 2006-2008 Igor Ulyanov - * Copyright (c) 2008-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/teamselect.cpp --- a/QTfrontend/ui/widget/teamselect.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/teamselect.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,7 +1,7 @@ /* * Hedgewars, a free turn based strategy game * Copyright (c) 2006-2007 Igor Ulyanov - * Copyright (c) 2007-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/teamselect.h --- a/QTfrontend/ui/widget/teamselect.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/teamselect.h Wed May 02 23:53:45 2012 +0200 @@ -1,7 +1,7 @@ /* * Hedgewars, a free turn based strategy game * Copyright (c) 2006-2007 Igor Ulyanov - * Copyright (c) 2007-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/teamselhelper.cpp --- a/QTfrontend/ui/widget/teamselhelper.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/teamselhelper.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,7 +1,7 @@ /* * Hedgewars, a free turn based strategy game * Copyright (c) 2006-2007 Igor Ulyanov - * Copyright (c) 2007-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 @@ -32,10 +32,11 @@ emit teamActivated(text()); } -TeamShowWidget::TeamShowWidget(HWTeam team, bool isPlaying, QWidget * parent) : +TeamShowWidget::TeamShowWidget(HWTeam team, bool isPlaying, FrameTeams * parent) : QWidget(parent), mainLayout(this), m_team(team), m_isPlaying(isPlaying), phhoger(0), colorButt(0) { + m_parentFrameTeams = parent; QPalette newPalette = palette(); newPalette.setColor(QPalette::Window, QColor(0x00, 0x00, 0x00)); setPalette(newPalette); @@ -129,43 +130,31 @@ void TeamShowWidget::incrementTeamColor() { - FrameTeams* pOurFrameTeams=dynamic_cast(parentWidget()); - QColor color; - if(++pOurFrameTeams->currentColor==pOurFrameTeams->availableColors.end()) - pOurFrameTeams->currentColor=pOurFrameTeams->availableColors.begin(); - color=*pOurFrameTeams->currentColor; - - changeTeamColor(color); + changeTeamColor(m_parentFrameTeams->getNextColor()); } void TeamShowWidget::decrementTeamColor() { - FrameTeams* pOurFrameTeams=dynamic_cast(parentWidget()); - QColor color; - if(pOurFrameTeams->currentColor==pOurFrameTeams->availableColors.begin()) - pOurFrameTeams->currentColor=pOurFrameTeams->availableColors.end()-1; - else --pOurFrameTeams->currentColor; - color=*pOurFrameTeams->currentColor; + const QList & availColors = m_parentFrameTeams->availableColors; + int idx = availColors.indexOf(m_parentFrameTeams->currentColor); + + idx--; - changeTeamColor(color); + if (idx < 0) + idx = availColors.size() - 1; + + changeTeamColor(availColors.at(idx)); } void TeamShowWidget::changeTeamColor(QColor color) { - FrameTeams* pOurFrameTeams=dynamic_cast(parentWidget()); - // set according color iterator - pOurFrameTeams->currentColor=std::find(pOurFrameTeams->availableColors.begin(), - pOurFrameTeams->availableColors.end(), color); - if(pOurFrameTeams->currentColor==pOurFrameTeams->availableColors.end()) - { - // error condition - pOurFrameTeams->currentColor=pOurFrameTeams->availableColors.begin(); - } + QColor & curColor = m_parentFrameTeams->currentColor; + curColor = color; colorButt->setStyleSheet(QString("QPushButton{" "background-color: %1;" "border-width: 1px;" "border-radius: 2px;" - "}").arg(pOurFrameTeams->currentColor->name())); + "}").arg(curColor.name())); m_team.setColor(color); emit teamColorChanged(m_team); diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/teamselhelper.h --- a/QTfrontend/ui/widget/teamselhelper.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/teamselhelper.h Wed May 02 23:53:45 2012 +0200 @@ -1,7 +1,7 @@ /* * Hedgewars, a free turn based strategy game * Copyright (c) 2006-2007 Igor Ulyanov - * Copyright (c) 2007-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 @@ -57,7 +57,7 @@ void activateTeam(); public: - TeamShowWidget(HWTeam team, bool isPlaying, QWidget * parent); + TeamShowWidget(HWTeam team, bool isPlaying, FrameTeams * parent); void setPlaying(bool isPlaying); void setHHNum(unsigned int num); void setInteractivity(bool interactive); @@ -71,6 +71,7 @@ CHedgehogerWidget* phhoger; QPushButton* colorButt; QPushButton* butt; + FrameTeams * m_parentFrameTeams; // QPushButton* bText; signals: diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/togglebutton.cpp --- a/QTfrontend/ui/widget/togglebutton.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/togglebutton.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,7 +1,7 @@ /* * Hedgewars, a free turn based strategy game * Copyright (c) 2009 Kristian Lehmann - * Copyright (c) 2009-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/togglebutton.h --- a/QTfrontend/ui/widget/togglebutton.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/togglebutton.h Wed May 02 23:53:45 2012 +0200 @@ -1,7 +1,7 @@ /* * Hedgewars, a free turn based strategy game * Copyright (c) 2009 Kristian Lehmann - * Copyright (c) 2009-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/vertScrollArea.cpp --- a/QTfrontend/ui/widget/vertScrollArea.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/vertScrollArea.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,7 +1,7 @@ /* * Hedgewars, a free turn based strategy game * Copyright (c) 2006 Igor Ulyanov - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/vertScrollArea.h --- a/QTfrontend/ui/widget/vertScrollArea.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/vertScrollArea.h Wed May 02 23:53:45 2012 +0200 @@ -1,7 +1,7 @@ /* * Hedgewars, a free turn based strategy game * Copyright (c) 2006 Igor Ulyanov - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/weaponItem.cpp --- a/QTfrontend/ui/widget/weaponItem.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/weaponItem.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,7 +1,7 @@ /* * Hedgewars, a free turn based strategy game * Copyright (c) 2006-2008 Igor Ulyanov - * Copyright (c) 2008-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui/widget/weaponItem.h --- a/QTfrontend/ui/widget/weaponItem.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui/widget/weaponItem.h Wed May 02 23:53:45 2012 +0200 @@ -1,7 +1,7 @@ /* * Hedgewars, a free turn based strategy game * Copyright (c) 2006-2008 Igor Ulyanov - * Copyright (c) 2008-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui_hwform.cpp --- a/QTfrontend/ui_hwform.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui_hwform.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/ui_hwform.h --- a/QTfrontend/ui_hwform.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/ui_hwform.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/util/DataManager.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/QTfrontend/util/DataManager.cpp Wed May 02 23:53:45 2012 +0200 @@ -0,0 +1,164 @@ +/* + * Hedgewars, a free turn based strategy game + * Copyright (c) 2004-2012 Andrey Korotaev + * + * 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 + */ + +/** + * @file + * @brief DataManager class implementation + */ + +#include +#include + +#include + +#include "hwconsts.h" + +#include "DataManager.h" + + +DataManager::DataManager() +{ + m_userData = new QDir(cfgdir->absolutePath()); + if (!m_userData->cd("Data")) + m_userData = NULL; + + m_defaultData = new QDir(datadir->absolutePath()); + + m_hatModel = NULL; + m_mapModel = NULL; + m_themeModel = NULL; +} + + +DataManager & DataManager::instance() +{ + static DataManager instance; + return instance; +} + + +QStringList DataManager::entryList( + const QString & subDirectory, + QDir::Filters filters, + const QStringList & nameFilters +) const +{ + QStringList result; + + if (m_userData != NULL) + { + QDir tmpDir(*m_userData); + if (tmpDir.cd(subDirectory)) + result.append(tmpDir.entryList(nameFilters, filters)); + } + + QDir tmpDir(*m_defaultData); + if (tmpDir.cd(subDirectory)) + result.append(tmpDir.entryList(nameFilters, filters)); + + result.removeDuplicates(); + + // sort case-insensitive + QMap sortedFileNames; + foreach ( QString fn, result) + { + sortedFileNames.insert(fn.toLower(), fn); + } + result = sortedFileNames.values(); + + return result; +} + + +QString DataManager::findFileForRead( + const QString & relativeDataFilePath) const +{ + QString path; + + if (m_userData != NULL) + path = m_userData->absolutePath()+"/"+relativeDataFilePath; + + if ((!path.isEmpty()) && (!QFile::exists(path))) + path = m_defaultData->absolutePath()+"/"+relativeDataFilePath; + + return path; +} + + +QString DataManager::findFileForWrite( + const QString & relativeDataFilePath) const +{ + if (m_userData != NULL) + { + QString path = m_userData->absolutePath()+"/"+relativeDataFilePath; + + // create folders if needed + QDir tmp; + tmp.mkpath(QFileInfo(path).absolutePath()); + + return path; + } + + + return ""; +} + +GameStyleModel * DataManager::gameStyleModel() +{ + if (m_gameStyleModel == NULL) { + m_gameStyleModel = new GameStyleModel(); + m_gameStyleModel->loadGameStyles(); + } + return m_gameStyleModel; +} + +HatModel * DataManager::hatModel() +{ + if (m_hatModel == NULL) { + m_hatModel = new HatModel(); + m_hatModel->loadHats(); + } + return m_hatModel; +} + +MapModel * DataManager::mapModel() +{ + if (m_mapModel == NULL) { + m_mapModel = new MapModel(); + m_mapModel->loadMaps(); + } + return m_mapModel; +} + +ThemeModel * DataManager::themeModel() +{ + if (m_themeModel == NULL) { + m_themeModel = new ThemeModel(); + m_themeModel->loadThemes(); + } + return m_themeModel; +} + +void DataManager::reload() +{ + m_gameStyleModel->loadGameStyles(); + m_hatModel->loadHats(); + m_mapModel->loadMaps(); + m_themeModel->loadThemes(); + emit updated(); +} diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/util/DataManager.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/QTfrontend/util/DataManager.h Wed May 02 23:53:45 2012 +0200 @@ -0,0 +1,168 @@ +/* + * Hedgewars, a free turn based strategy game + * Copyright (c) 2004-2012 Andrey Korotaev + * + * 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 + */ + +/** + * @file + * @brief DataManager class definition + */ + +#ifndef HEDGEWARS_DATAMANAGER_H +#define HEDGEWARS_DATAMANAGER_H + +#include +#include + +#include + +#include "GameStyleModel.h" +#include "HatModel.h" +#include "MapModel.h" +#include "ThemeModel.h" + +class QDir; +class QFile; +class QStringList; +class GameStyleModel; +class HatModel; +class MapModel; +class ThemeModel; + +/** + * @brief Offers access to the data files of hedgewars. + * + * @see singleton pattern + * + * @author sheepluva + * @since 0.9.17 + */ +class DataManager: public QObject +{ + Q_OBJECT + + public: + /** + * @brief Returns reference to the singleton instance of this class. + * + * @see singleton pattern + * + * @return reference to the instance. + */ + static DataManager & instance(); + + /** + * @brief Returns a sorted list of data directory entries. + * + * @param subDirectory sub-directory to search. + * @param filters filters for entry type. + * @param nameFilters filters by name patterns. + * @return a sorted list of matches in the subDirectory of data directory. + */ + QStringList entryList(const QString & subDirectory, + QDir::Filters filters = QDir::NoFilter, + const QStringList & nameFilters = QStringList("*") + ) const; + + /** + * @brief Returns the path for the desires data file. + * + * Use this method if you want to read an existing data file. + * + * @param relativeDataFilePath relative path of the data file. + * @return real path to the file. + */ + QString findFileForRead(const QString & relativeDataFilePath) const; + + + /** + * @brief Returns the path for the data file that is to be written. + * + * Use this method if you want to create or write into a data file. + * + * @param relativeDataFilePath relative path of data file write path. + * @return destination of path data file. + */ + QString findFileForWrite(const QString & relativeDataFilePath) const; + + + /** + * @brief Returns pointer to a model of available game styles. + * + * The model is updated automatically on data reload. + * + * @return game style model pointer. + */ + GameStyleModel * gameStyleModel(); + + /** + * @brief Returns pointer to a model of available hats. + * + * The model is updated automatically on data reload. + * + * @return hat model pointer. + */ + HatModel * hatModel(); + + /** + * @brief Returns pointer to a model of available maps. + * + * The model is updated automatically on data reload. + * + * @return map model pointer. + */ + MapModel * mapModel(); + + /** + * @brief Returns pointer to a model of available themes. + * + * The model is updated automatically on data reload. + * + * @return theme model pointer. + */ + ThemeModel * themeModel(); + + public slots: + /// Reloads data from storage. + void reload(); + + + signals: + /// This signal is emitted after the data has been updated. + void updated(); + + + private: + /** + * @brief Class constructor of the singleton. + * + * Not to be used from outside the class, + * use the static {@link DataManager::instance()} instead. + * + * @see singleton pattern + */ + DataManager(); + + QDir * m_defaultData; ///< directory of the installed data + QDir * m_userData; ///< directory of custom data in the user's directory + + GameStyleModel * m_gameStyleModel; ///< game style model instance + HatModel * m_hatModel; ///< hat model instance + MapModel * m_mapModel; ///< map model instance + ThemeModel * m_themeModel; ///< theme model instance +}; + +#endif // HEDGEWARS_DATAMANAGER_H diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/util/HWDataManager.cpp --- a/QTfrontend/util/HWDataManager.cpp Sun Apr 01 15:23:34 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,117 +0,0 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2007 Igor Ulyanov - * Copyright (c) 2007-2012 Andrey Korotaev - * - * 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 - */ - -/** - * @file - * @brief HWDataManager class implementation - */ - -#include -#include - -#include - -#include "hwconsts.h" - -#include "HWDataManager.h" - - -HWDataManager::HWDataManager() -{ - userData = new QDir(cfgdir->absolutePath()); - if (!userData->cd("Data")) - userData = NULL; - - defaultData = new QDir(datadir->absolutePath()); -} - - -HWDataManager & HWDataManager::instance() -{ - static HWDataManager instance; - return instance; -} - - -QStringList HWDataManager::entryList( - const QString & subDirectory, - QDir::Filters filters, - const QStringList & nameFilters -) const -{ - QStringList result; - - if (userData != NULL) - { - QDir tmpDir(*userData); - if (tmpDir.cd(subDirectory)) - result.append(tmpDir.entryList(nameFilters, filters)); - } - - QDir tmpDir(*defaultData); - if (tmpDir.cd(subDirectory)) - result.append(tmpDir.entryList(nameFilters, filters)); - - result.removeDuplicates(); - - // sort case-insensitive - QMap sortedFileNames; - foreach ( QString fn, result) - { - sortedFileNames.insert(fn.toLower(), fn); - } - result = sortedFileNames.values(); - - return result; -} - - -QString HWDataManager::findFileForRead( - const QString & relativeDataFilePath) const -{ - QString path; - - if (userData != NULL) - path = userData->absolutePath()+"/"+relativeDataFilePath; - - if ((!path.isEmpty()) && (!QFile::exists(path))) - path = defaultData->absolutePath()+"/"+relativeDataFilePath; - - return path; -} - - -QString HWDataManager::findFileForWrite( - const QString & relativeDataFilePath) const -{ - if (userData != NULL) - { - QString path = userData->absolutePath()+"/"+relativeDataFilePath; - - // create folders if needed - QDir tmp; - tmp.mkpath(QFileInfo(path).absolutePath()); - - return path; - } - - - return ""; -} - diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/util/HWDataManager.h --- a/QTfrontend/util/HWDataManager.h Sun Apr 01 15:23:34 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,107 +0,0 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (c) 2006-2007 Igor Ulyanov - * Copyright (c) 2007-2012 Andrey Korotaev - * - * 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 - */ - -/** - * @file - * @brief HWDataManager class definition - */ - -#ifndef HEDGEWARS_HWDATAMANAGER_H -#define HEDGEWARS_HWDATAMANAGER_H - -#include -#include - -#include - -class QDir; -class QFile; -class QStringList; - -/** - * @brief Offers access to the data files of hedgewars. - * - * @see singleton pattern - * - * @author sheepluva - * @since 0.9.17 - */ -class HWDataManager -{ - public: - /** - * @brief Returns reference to the singleton instance of this class. - * - * @see singleton pattern - * - * @return reference to the instance. - */ - static HWDataManager & instance(); - - /** - * @brief Returns a sorted list of data directory entries. - * - * @param subDirectory sub-directory to search. - * @param filters filters for entry type. - * @param nameFilters filters by name patterns. - * @return a sorted list of matches in the subDirectory of data directory. - */ - QStringList entryList(const QString & subDirectory, - QDir::Filters filters = QDir::NoFilter, - const QStringList & nameFilters = QStringList("*") - ) const; - - /** - * @brief Returns the path for the desires data file. - * - * Use this method if you want to read an existing data file. - * - * @param relativeDataFilePath relative path of the data file. - * @return real path to the file. - */ - QString findFileForRead(const QString & relativeDataFilePath) const; - - - /** - * @brief Returns the path for the data file that is to be written. - * - * Use this method if you want to create or write into a data file. - * - * @param relativeDataFilePath relative path of data file write path. - * @return destination of path data file. - */ - QString findFileForWrite(const QString & relativeDataFilePath) const; - - - private: - /** - * @brief Class constructor of the singleton. - * - * Not to be used from outside the class, - * use the static {@link HWDataManager::instance()} instead. - * - * @see singleton pattern - */ - HWDataManager(); - - QDir * defaultData; ///< directory of the installed data - QDir * userData; ///< directory of custom data in the user's directory -}; - -#endif // HEDGEWARS_HWDATAMANAGER_H diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/util/SDLInteraction.cpp --- a/QTfrontend/util/SDLInteraction.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/util/SDLInteraction.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2007-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/util/SDLInteraction.h --- a/QTfrontend/util/SDLInteraction.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/util/SDLInteraction.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2007-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 @@ -43,7 +43,7 @@ * @brief Class constructor of the singleton. * * Not to be used from outside the class, - * use the static {@link HWDataManager::instance()} instead. + * use the static {@link DataManager::instance()} instead. * * @see singleton pattern */ diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/util/namegen.cpp --- a/QTfrontend/util/namegen.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/util/namegen.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,7 +1,7 @@ /* * Hedgewars, a free turn based strategy game * Copyright (c) 2009 Martin Minarik - * Copyright (c) 2009-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 @@ -23,7 +23,7 @@ #include #include "hwform.h" -#include "HWDataManager.h" +#include "DataManager.h" #include "namegen.h" @@ -125,7 +125,7 @@ QStringList list; // find .txt to load the names from - QFile * file = new QFile(HWDataManager::instance().findFileForRead(QString( + QFile * file = new QFile(DataManager::instance().findFileForRead(QString( "Names/%1.txt").arg(filename))); if (file->exists() && file->open(QIODevice::ReadOnly | QIODevice::Text)) @@ -154,7 +154,7 @@ QStringList list; // find .cfg to load the dicts from - QFile * file = new QFile(HWDataManager::instance().findFileForRead(QString( + QFile * file = new QFile(DataManager::instance().findFileForRead(QString( "Names/%1.cfg").arg(hatname))); if (file->exists() && file->open(QIODevice::ReadOnly | QIODevice::Text)) @@ -184,7 +184,7 @@ // find .ini to load the names from QFile * file = new QFile( - HWDataManager::instance().findFileForRead(QString("Names/types.ini"))); + DataManager::instance().findFileForRead(QString("Names/types.ini"))); if (file->exists() && file->open(QIODevice::ReadOnly | QIODevice::Text)) @@ -243,7 +243,7 @@ QStringList Graves; //list all available Graves - Graves.append(HWDataManager::instance().entryList( + Graves.append(DataManager::instance().entryList( "Graphics/Graves", QDir::Files, QStringList("*.png") @@ -265,7 +265,7 @@ QStringList Forts; //list all available Forts - Forts.append(HWDataManager::instance().entryList( + Forts.append(DataManager::instance().entryList( "Forts", QDir::Files, QStringList("*L.png") diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/util/namegen.h --- a/QTfrontend/util/namegen.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/util/namegen.h Wed May 02 23:53:45 2012 +0200 @@ -1,7 +1,7 @@ /* * Hedgewars, a free turn based strategy game * Copyright (c) 2009 Martin Minarik - * Copyright (c) 2009-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/xfire.cpp --- a/QTfrontend/xfire.cpp Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/xfire.cpp Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2010-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 QTfrontend/xfire.h --- a/QTfrontend/xfire.h Sun Apr 01 15:23:34 2012 +0200 +++ b/QTfrontend/xfire.h Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ /* * Hedgewars, a free turn based strategy game - * Copyright (c) 2010-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 diff -r 9e724f4863a3 -r 6af78154dc62 foo diff -r 9e724f4863a3 -r 6af78154dc62 gameServer/CoreTypes.hs --- a/gameServer/CoreTypes.hs Sun Apr 01 15:23:34 2012 +0200 +++ b/gameServer/CoreTypes.hs Wed May 02 23:53:45 2012 +0200 @@ -192,6 +192,7 @@ data Notice = NickAlreadyInUse | AdminLeft + | WrongPassword deriving Enum data ShutdownException = diff -r 9e724f4863a3 -r 6af78154dc62 gameServer/HWProtoInRoomState.hs --- a/gameServer/HWProtoInRoomState.hs Sun Apr 01 15:23:34 2012 +0200 +++ b/gameServer/HWProtoInRoomState.hs Wed May 02 23:53:45 2012 +0200 @@ -278,6 +278,8 @@ where engineMsg cl = toEngineMsg $ B.concat ["b", nick cl, "(team): ", msg, "\x20\x20"] +handleCmd_inRoom ["LIST"] = return [] -- for old clients (<= 0.9.17) + handleCmd_inRoom (s:_) = return [ProtocolError $ "Incorrect command '" `B.append` s `B.append` "' (state: in room)"] handleCmd_inRoom [] = return [ProtocolError "Empty command (state: in room)"] diff -r 9e724f4863a3 -r 6af78154dc62 gameServer/HWProtoLobbyState.hs --- a/gameServer/HWProtoLobbyState.hs Sun Apr 01 15:23:34 2012 +0200 +++ b/gameServer/HWProtoLobbyState.hs Wed May 02 23:53:45 2012 +0200 @@ -76,7 +76,7 @@ else if isRestrictedJoins jRoom then [Warning "Joining restricted"] else if roomPassword /= password jRoom then - [Warning "Wrong password"] + [NoticeMessage WrongPassword] else [ MoveToRoom jRI, diff -r 9e724f4863a3 -r 6af78154dc62 gameServer/Utils.hs --- a/gameServer/Utils.hs Sun Apr 01 15:23:34 2012 +0200 +++ b/gameServer/Utils.hs Wed May 02 23:53:45 2012 +0200 @@ -123,9 +123,7 @@ where f = map Char.toUpper . UTF8.toString -roomInfo n r - | isRestrictedJoins r = [] - | otherwise = [ +roomInfo n r = [ showB $ isJust $ gameInfo r, name r, showB $ playersIn r, diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/ArgParsers.inc --- a/hedgewars/ArgParsers.inc Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/ArgParsers.inc Wed May 02 23:53:45 2012 +0200 @@ -50,10 +50,10 @@ UserNick:= DecodeBase64(ParamStr(14)); val(ParamStr(15), cReducedQuality); val(ParamStr(16), tmp); - cGrayScale:= false; + GrayScale:= false; if (tmp > 9) and (tmp < 16) then begin - cGrayScale:= true; + GrayScale:= true; cStereoMode:= TStereoMode(max(0, min(ord(high(TStereoMode)), tmp-9))) end else if tmp <= 9 then diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/CMakeLists.txt --- a/hedgewars/CMakeLists.txt Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/CMakeLists.txt Wed May 02 23:53:45 2012 +0200 @@ -16,6 +16,7 @@ set(engine_sources ${hwengine_project} SDLh.pas + PNGh.pas uAI.pas uAIActions.pas uAIAmmoTests.pas @@ -34,7 +35,7 @@ uGears.pas uGearsRender.pas uIO.pas - uKeys.pas + uInputHandler.pas uLand.pas uLandGenMaze.pas uLandGraphics.pas @@ -63,7 +64,6 @@ uWorld.pas GSHandlers.inc VGSHandlers.inc - HHHandlers.inc ArgParsers.inc options.inc adler32.pas @@ -141,11 +141,24 @@ message(FATAL_ERROR "No Pascal compiler found!") endif() + +#DEPENDECIES AND EXECUTABLES SECTION +find_package(PNG) +if(${PNG_FOUND}) + message(STATUS "PNG screenshots enabled (library found at ${PNG_LIBRARY})") + set(pascal_compiler_flags_cmn "-dPNG_SCREENSHOTS" ${pascal_compiler_flags_cmn}) + if(APPLE) # need to explictly link with the static lib + string(REGEX REPLACE "(.*)libpng.*" "\\1" PNG_LIBDIR "${PNG_LIBRARY}") + set(pascal_compiler_flags_cmn "-k${PNG_LIBDIR}/libpng.a" ${pascal_compiler_flags_cmn}) + endif() +else() + message(STATUS "PNG library not found, switching to screenshots in BMP format") +endif() + set(pascal_compiler ${fpc_executable}) set(pascal_compiler_flags ${noexecstack_flags} ${pascal_compiler_flags_cmn} ${hwengine_project}) -#DEPENDECIES AND EXECUTABLES SECTION IF(NOT APPLE) #here is the command for standard executables or for shared library add_custom_command(OUTPUT "${EXECUTABLE_OUTPUT_PATH}/${engine_output_name}${CMAKE_EXECUTABLE_SUFFIX}" diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/GL.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hedgewars/GL.h Wed May 02 23:53:45 2012 +0200 @@ -0,0 +1,3 @@ +#pragma once + +#include diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/GSHandlers.inc --- a/hedgewars/GSHandlers.inc Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/GSHandlers.inc Wed May 02 23:53:45 2012 +0200 @@ -170,14 +170,14 @@ Gear^.Y := Gear^.Y + cDrownSpeed; Gear^.X := Gear^.X + Gear^.dX * cDrownSpeed; // Create some bubbles (0.5% might be better but causes too few bubbles sometimes) - if ((not SuddenDeathDmg and (cWaterOpacity < $FF)) - or (SuddenDeathDmg and (cSDWaterOpacity < $FF))) and ((GameTicks and $1F) = 0) then + if ((not SuddenDeathDmg and (WaterOpacity < $FF)) + or (SuddenDeathDmg and (SDWaterOpacity < $FF))) and ((GameTicks and $1F) = 0) then if (Gear^.Kind = gtHedgehog) and (Random(4) = 0) then AddVisualGear(hwRound(Gear^.X) - Gear^.Radius, hwRound(Gear^.Y) - Gear^.Radius, vgtBubble) else if Random(12) = 0 then AddVisualGear(hwRound(Gear^.X) - Gear^.Radius, hwRound(Gear^.Y) - Gear^.Radius, vgtBubble); - if (not SuddenDeathDmg and (cWaterOpacity > $FE)) - or (SuddenDeathDmg and (cSDWaterOpacity > $FE)) + if (not SuddenDeathDmg and (WaterOpacity > $FE)) + or (SuddenDeathDmg and (SDWaterOpacity > $FE)) or (hwRound(Gear^.Y) > Gear^.Radius + cWaterLine + cVisibleWater) then DeleteGear(Gear); end; @@ -345,8 +345,8 @@ doMakeExplosion(x, y, 20, Gear^.Hedgehog, EXPLAutoSound); for i:= 0 to 4 do begin - dX := rndSign(GetRandom * _0_1) + Gear^.dX / 5; - dY := (GetRandom - _3) * _0_08; + dX := rndSign(GetRandomf * _0_1) + Gear^.dX / 5; + dY := (GetRandomf - _3) * _0_08; FollowGear := AddGear(x, y, gtCluster, 0, dX, dY, 25) end end; @@ -357,8 +357,8 @@ doMakeExplosion(x, y, 75, Gear^.Hedgehog, EXPLAutoSound); for i:= 0 to 5 do begin - dX := rndSign(GetRandom * _0_1) + Gear^.dX / 5; - dY := (GetRandom - _1_5) * _0_3; + dX := rndSign(GetRandomf * _0_1) + Gear^.dX / 5; + dY := (GetRandomf - _1_5) * _0_3; FollowGear:= AddGear(x, y, gtMelonPiece, 0, dX, dY, 75); FollowGear^.DirAngle := i * 60 end @@ -371,8 +371,8 @@ for i:= 0 to 127 do begin - dX := AngleCos(i * 16) * _0_5 * (GetRandom + _1); - dY := AngleSin(i * 16) * _0_5 * (GetRandom + _1); + dX := AngleCos(i * 16) * _0_5 * (GetRandomf + _1); + dY := AngleSin(i * 16) * _0_5 * (GetRandomf + _1); if i mod 2 = 0 then begin AddGear(x, y, gtFlame, gstTmpFlag, dX, dY, 0); @@ -477,8 +477,8 @@ end; for i:= 0 to 24 do begin - dX := AngleCos(i * 2) * ((_0_15*(i div 5))) * (GetRandom + _1); - dY := AngleSin(i * 8) * _0_5 * (GetRandom + _1); + dX := AngleCos(i * 2) * ((_0_15*(i div 5))) * (GetRandomf + _1); + dY := AngleSin(i * 8) * _0_5 * (GetRandomf + _1); AddGear(gX, gY, gtFlame, gstTmpFlag, dX, dY, 0); AddGear(gX, gY, gtFlame, gstTmpFlag, dX,-dY, 0); AddGear(gX, gY, gtFlame, gstTmpFlag,-dX, dY, 0); @@ -690,7 +690,7 @@ end else Land[ly, lx]:= lf; if gun then - LandPixels[ry, rx]:= (cExplosionBorderColor and (not AMask)) or (p^[px] and AMask) + LandPixels[ry, rx]:= (ExplosionBorderColor and (not AMask)) or (p^[px] and AMask) else LandPixels[ry, rx]:= addBgColor(LandPixels[ry, rx], p^[px]); end else allpx:= false @@ -1032,7 +1032,7 @@ dec(Gear^.Health, Gear^.Damage); Gear^.Damage := 0 end; - if ((Gear^.State and gstDrowning) <> 0) and (Gear^.Damage < Gear^.Health) and ((not SuddenDeathDmg and (cWaterOpacity < $FF)) or (SuddenDeathDmg and (cSDWaterOpacity < $FF))) then + if ((Gear^.State and gstDrowning) <> 0) and (Gear^.Damage < Gear^.Health) and ((not SuddenDeathDmg and (WaterOpacity < $FF)) or (SuddenDeathDmg and (SDWaterOpacity < $FF))) then begin for i:=(Gear^.Health - Gear^.Damage) * 4 downto 0 do begin @@ -2130,8 +2130,8 @@ doMakeExplosion(x, y, 75, hog, EXPLAutoSound); for i:= 0 to 31 do begin - dX := AngleCos(i * 64) * _0_5 * (getrandom + _1); - dY := AngleSin(i * 64) * _0_5 * (getrandom + _1); + dX := AngleCos(i * 64) * _0_5 * (getrandomf + _1); + dY := AngleSin(i * 64) * _0_5 * (getrandomf + _1); AddGear(x, y, gtFlame, 0, dX, dY, 0); AddGear(x, y, gtFlame, gstTmpFlag, -dX, -dY, 0); end @@ -2715,7 +2715,7 @@ procedure doStepSwitcherWork(Gear: PGear); var HHGear: PGear; - Msg, State: Longword; + State: Longword; begin AllInactive := false; @@ -2800,8 +2800,8 @@ Gear^.dY.isNegative := not dyn; for i:= 0 to 4 do begin - dX := Gear^.dX + (GetRandom - _0_5) * _0_03; - dY := Gear^.dY + (GetRandom - _0_5) * _0_03; + dX := Gear^.dX + (GetRandomf - _0_5) * _0_03; + dY := Gear^.dY + (GetRandomf - _0_5) * _0_03; AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtCluster, 0, dX, dY, 25); end; @@ -2815,8 +2815,6 @@ //////////////////////////////////////////////////////////////////////////////// procedure doStepKamikazeWork(Gear: PGear); - -const upd: Longword = 0; var i: LongWord; HHGear: PGear; @@ -3416,8 +3414,8 @@ gY := hwRound(Gear^.Y) + GetLaunchY(amBallgun, HHGear^.Angle); if (Gear^.Timer mod 100) = 0 then begin - rx := rndSign(getRandom * _0_1); - ry := rndSign(getRandom * _0_1); + rx := rndSign(getRandomf * _0_1); + ry := rndSign(getRandomf * _0_1); AddGear(gx, gy, gtBall, 0, SignAs(AngleSin(HHGear^.Angle) * _0_8, HHGear^.dX) + rx, AngleCos(HHGear^.Angle) * ( - _0_8) + ry, 0); @@ -3540,8 +3538,8 @@ doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 25, Gear^.Hedgehog, EXPLAutoSound); for i:= 0 to 15 do begin - dX := AngleCos(i * 64) * _0_5 * (GetRandom + _1); - dY := AngleSin(i * 64) * _0_5 * (GetRandom + _1); + dX := AngleCos(i * 64) * _0_5 * (GetRandomf + _1); + dY := AngleSin(i * 64) * _0_5 * (GetRandomf + _1); AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, dX, dY, 0); AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, dX, -dY, 0); end; @@ -3973,7 +3971,7 @@ begin CurrentHedgehog^.Gear^.Message := CurrentHedgehog^.Gear^.Message and (not gmSwitch); - CurWeapon:= GetAmmoEntry(CurrentHedgehog^); + CurWeapon:= GetCurAmmoEntry(CurrentHedgehog^); if CurWeapon^.Pos <> 0 then CurWeapon^.Pos := 0 @@ -4344,7 +4342,7 @@ if CurrentHedgehog <> nil then with CurrentHedgehog^ do begin - CurWeapon:= GetAmmoEntry(CurrentHedgehog^); + CurWeapon:= GetCurAmmoEntry(CurrentHedgehog^); if (CurAmmoType = amPortalGun) then begin if not destroyGear then @@ -4444,7 +4442,7 @@ if CurrentHedgehog <> nil then with CurrentHedgehog^ do begin - CurWeapon:= GetAmmoEntry(CurrentHedgehog^); + CurWeapon:= GetCurAmmoEntry(CurrentHedgehog^); // let's save the HH's dX's direction so we can decide where the "top" of the portal hole newPortal^.Elasticity.isNegative := CurrentHedgehog^.Gear^.dX.isNegative; // when doing a backjump the dx is the opposite of the facing direction @@ -4756,8 +4754,8 @@ dec(Gear^.Health); if (Gear^.Health mod 5) = 0 then begin - rx := rndSign(getRandom * _0_1); - ry := rndSign(getRandom * _0_1); + rx := rndSign(getRandomf * _0_1); + ry := rndSign(getRandomf * _0_1); speed := _0_5 * (_10 / Gear^.Tag); AddGear(gx, gy, gtFlame, gstTmpFlag, @@ -4836,8 +4834,8 @@ begin dec(Gear^.Health); - rx := rndSign(getRandom * _0_1); - ry := rndSign(getRandom * _0_1); + rx := rndSign(getRandomf * _0_1); + ry := rndSign(getRandomf * _0_1); speed := (_3 / Gear^.Tag); AddGear(gx, gy, gtFlake, gstTmpFlag, @@ -5148,8 +5146,8 @@ gY := hwRound(Gear^.Y); for i:= 0 to 10 do begin - dX := AngleCos(i * 2) * ((_0_1*(i div 5))) * (GetRandom + _1); - dY := AngleSin(i * 8) * _0_5 * (GetRandom + _1); + dX := AngleCos(i * 2) * ((_0_1*(i div 5))) * (GetRandomf + _1); + dY := AngleSin(i * 8) * _0_5 * (GetRandomf + _1); AddGear(gX, gY, gtFlame, 0, dX, dY, 0); AddGear(gX, gY, gtFlame, 0, dX, -dY, 0); AddGear(gX, gY, gtFlame, 0, -dX, dY, 0); diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/HHHandlers.inc --- a/hedgewars/HHHandlers.inc Sun Apr 01 15:23:34 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,19 +0,0 @@ -(* - * Hedgewars, a free turn based strategy game - * Copyright (c) 2004-2012 Andrey Korotaev - * - * 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 - *) - -//////////////////////////////////////////////////////////////////////////////// diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/Math.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hedgewars/Math.h Wed May 02 23:53:45 2012 +0200 @@ -0,0 +1,2 @@ +#pragma once + diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/PNGh.pas --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hedgewars/PNGh.pas Wed May 02 23:53:45 2012 +0200 @@ -0,0 +1,90 @@ +(* + * Hedgewars, a free turn based strategy game + * Copyright (c) 2004-2012 Andrey Korotaev + * + * 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 "options.inc"} + +unit PNGh; +interface + +uses png; + +{$IFDEF FPC} + {$PACKRECORDS C} +{$ELSE} + {$DEFINE cdecl attribute(cdecl)} +{$ENDIF} + +const + // Constants for libpng, they are not defined in png unit. + // We actually don't need all of them. + + // These describe the color_type field in png_info. + // color type masks + PNG_COLOR_MASK_PALETTE = 1; + PNG_COLOR_MASK_COLOR = 2; + PNG_COLOR_MASK_ALPHA = 4; + + // color types. Note that not all combinations are legal + PNG_COLOR_TYPE_GRAY = 0; + PNG_COLOR_TYPE_PALETTE = PNG_COLOR_MASK_COLOR or PNG_COLOR_MASK_PALETTE; + PNG_COLOR_TYPE_RGB = PNG_COLOR_MASK_COLOR; + PNG_COLOR_TYPE_RGB_ALPHA = PNG_COLOR_MASK_COLOR or PNG_COLOR_MASK_ALPHA; + PNG_COLOR_TYPE_GRAY_ALPHA = PNG_COLOR_MASK_ALPHA; + + // aliases + PNG_COLOR_TYPE_RGBA = PNG_COLOR_TYPE_RGB_ALPHA; + PNG_COLOR_TYPE_GA = PNG_COLOR_TYPE_GRAY_ALPHA; + + // This is for compression type. PNG 1.0-1.2 only define the single type. + PNG_COMPRESSION_TYPE_BASE = 0; // Deflate method 8, 32K window + PNG_COMPRESSION_TYPE_DEFAULT = PNG_COMPRESSION_TYPE_BASE; + + // This is for filter type. PNG 1.0-1.2 only define the single type. + PNG_FILTER_TYPE_BASE = 0; // Single row per-byte filtering + PNG_INTRAPIXEL_DIFFERENCING = 64; // Used only in MNG datastreams + PNG_FILTER_TYPE_DEFAULT = PNG_FILTER_TYPE_BASE; + + // These are for the interlacing type. These values should NOT be changed. + PNG_INTERLACE_NONE = 0; // Non-interlaced image + PNG_INTERLACE_ADAM7 = 1; // Adam7 interlacing + PNG_INTERLACE_LAST = 2; // Not a valid value + +type + // where is better place for this definition? + PFile = ^file; + +procedure png_init_pascal_io(png_ptr: png_structp; pf : PFile); + +implementation + +// We cannot get c-style FILE* pointer to pass it to libpng, so we implement our own writing functions +procedure PngWriteData(png_ptr: png_structp; p: PByte; len: png_size_t); cdecl; +begin + BlockWrite( PFile(png_get_io_ptr(png_ptr))^, p^, len); +end; + +procedure PngFlushData(png_ptr: png_structp); cdecl; +begin +end; + +procedure png_init_pascal_io(png_ptr: png_structp; pf : PFile); +begin + png_set_write_fn(png_ptr, pf, @PngWriteData, @PngFlushData); +end; + +end. diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/PascalExports.pas --- a/hedgewars/PascalExports.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/PascalExports.pas Wed May 02 23:53:45 2012 +0200 @@ -28,7 +28,7 @@ * http://en.wikipedia.org/wiki/X86_calling_conventions#cdecl *) interface -uses uTypes, uConsts, uVariables, GLunit, uKeys, uSound, uAmmos, uUtils, uCommands; +uses uTypes, uConsts, uVariables, GLunit, uInputHandler, uSound, uAmmos, uUtils, uCommands; {$INCLUDE "config.inc"} procedure HW_versionInfo(netProto: PLongInt; versionStr: PPChar); cdecl; export; @@ -52,35 +52,12 @@ versionStr^:= cVersionString; end; -// emulate mouse/keyboard input -procedure HW_click; cdecl; export; -begin - leftClick:= true; -end; - -procedure HW_ammoMenu; cdecl; export; -begin - rightClick:= true; -end; - procedure HW_zoomSet(value: GLfloat); cdecl; export; begin cZoomVal:= value; ZoomValue:= value; end; -procedure HW_zoomIn; cdecl; export; -begin - if wheelDown = false then - wheelUp:= true; -end; - -procedure HW_zoomOut; cdecl; export; -begin - if wheelUp = false then - wheelDown:= true; -end; - procedure HW_zoomReset; cdecl; export; begin ZoomValue:= cZoomVal; @@ -91,84 +68,12 @@ function HW_zoomFactor: GLfloat; cdecl; export; begin - exit( ZoomValue / cDefaultZoomLevel ); + HW_zoomFactor:= ZoomValue / cDefaultZoomLevel; end; function HW_zoomLevel: LongInt; cdecl; export; begin - exit( trunc((ZoomValue - cDefaultZoomLevel) / cZoomDelta) ); -end; - -procedure HW_walkingKeysUp; cdecl; export; -begin - leftKey:= false; - rightKey:= false; - upKey:= false; - downKey:= false; - preciseKey:= false; -end; - -procedure HW_otherKeysUp; cdecl; export; -begin - spaceKey:= false; - enterKey:= false; - backspaceKey:= false; -end; - -procedure HW_allKeysUp; cdecl; export; -begin - // set all keys to released - uKeys.initModule; -end; - -procedure HW_walkLeft; cdecl; export; -begin - leftKey:= true; -end; - -procedure HW_walkRight; cdecl; export; -begin - rightKey:= true; -end; - -procedure HW_preciseSet(status:boolean); cdecl; export; -begin - preciseKey:= status; -end; - -procedure HW_aimUp; cdecl; export; -begin - upKey:= true; -end; - -procedure HW_aimDown; cdecl; export; -begin - downKey:= true; -end; - -procedure HW_shoot; cdecl; export; -begin - spaceKey:= true; -end; - -procedure HW_jump; cdecl; export; -begin - enterKey:= true; -end; - -procedure HW_backjump; cdecl; export; -begin - backspaceKey:= true; -end; - -procedure HW_tab; cdecl; export; -begin - tabKey:= true; -end; - -procedure HW_chat; cdecl; export; -begin - chatAction:= true; + HW_zoomLevel:= trunc((ZoomValue - cDefaultZoomLevel) / cZoomDelta); end; procedure HW_screenshot; cdecl; export; @@ -176,20 +81,9 @@ flagMakeCapture:= true; end; -procedure HW_pause; cdecl; export; -begin - if isPaused = false then - pauseAction:= true; -end; - -procedure HW_pauseToggle; cdecl; export; -begin - pauseAction:= true; -end; - function HW_isPaused: boolean; cdecl; export; begin - exit( isPaused ); + HW_isPaused:= isPaused; end; // equivalent to esc+y; when closeFrontend = true the game exits after memory cleanup @@ -201,11 +95,7 @@ function HW_getSDLWindow: pointer; cdecl; export; begin -{$IFDEF SDL13} - exit( SDLwindow ); -{$ELSE} - exit( nil ); -{$ENDIF} + HW_getSDLWindow:={$IFDEF SDL13}SDLwindow{$ELSE}nil{$ENDIF}; end; // cursor handling @@ -224,45 +114,41 @@ // ammo menu related functions function HW_isAmmoMenuOpen: boolean; cdecl; export; begin - exit( bShowAmmoMenu ); + HW_isAmmoMenuOpen:= bShowAmmoMenu; end; function HW_isAmmoMenuNotAllowed: boolean; cdecl; export; begin; - exit( (TurnTimeLeft = 0) or (not CurrentTeam^.ExtDriven and (((CurAmmoGear = nil) - or ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) = 0)) and hideAmmoMenu)) ); + HW_isAmmoMenuNotAllowed:= ( (TurnTimeLeft = 0) or (not CurrentTeam^.ExtDriven and (((CurAmmoGear = nil) or + ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) = 0)) and hideAmmoMenu)) ); end; function HW_isWeaponRequiringClick: boolean; cdecl; export; begin + HW_isWeaponRequiringClick:= false; if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) and (CurrentHedgehog^.BotLevel = 0) then - exit( (CurrentHedgehog^.Gear^.State and gstHHChooseTarget) <> 0 ) - else - exit(false); + HW_isWeaponRequiringClick:= (CurrentHedgehog^.Gear^.State and gstHHChooseTarget) <> 0; end; function HW_isWeaponTimerable: boolean; cdecl; export; begin + HW_isWeaponTimerable:= false; if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Ammo <> nil) and (CurrentHedgehog^.BotLevel = 0) then - exit( (Ammoz[CurrentHedgehog^.CurAmmoType].Ammo.Propz and ammoprop_Timerable) <> 0) - else - exit(false); + HW_isWeaponTimerable:= (Ammoz[CurrentHedgehog^.CurAmmoType].Ammo.Propz and ammoprop_Timerable) <> 0; end; function HW_isWeaponSwitch: boolean cdecl; export; begin + HW_isWeaponSwitch:= false; if (CurAmmoGear <> nil) and (CurrentHedgehog^.BotLevel = 0) then - exit(CurAmmoGear^.AmmoType = amSwitch) - else - exit(false) + HW_isWeaponSwitch:= (CurAmmoGear^.AmmoType = amSwitch); end; function HW_isWeaponRope: boolean cdecl; export; begin + HW_isWeaponRope:= false; if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Ammo <> nil) and (CurrentHedgehog^.BotLevel = 0) then - exit(CurrentHedgehog^.CurAmmoType = amRope) - else - exit(false); + HW_isWeaponRope:= (CurrentHedgehog^.CurAmmoType = amRope); end; procedure HW_setGrenadeTime(time: LongInt); cdecl; export; @@ -272,14 +158,13 @@ function HW_getGrenadeTime: LongInt; cdecl; export; var CurWeapon: PAmmo; - res: LongInt = 3; begin + HW_getGrenadeTime:= 3; if HW_isWeaponTimerable then begin - CurWeapon:= GetAmmoEntry(CurrentHedgehog^); - res:= CurWeapon^.Timer div 1000; + CurWeapon:= GetCurAmmoEntry(CurrentHedgehog^); + HW_getGrenadeTime:= CurWeapon^.Timer div 1000; end; - exit(res); end; procedure HW_setPianoSound(snd: LongInt); cdecl; export; @@ -302,22 +187,22 @@ function HW_getWeaponNameByIndex(whichone: LongInt): PChar; cdecl; export; begin - exit(str2pchar(trammo[Ammoz[TAmmoType(whichone+1)].NameId])); + HW_getWeaponNameByIndex:= (str2pchar(trammo[Ammoz[TAmmoType(whichone+1)].NameId])); end; function HW_getWeaponCaptionByIndex(whichone: LongInt): PChar; cdecl; export; begin - exit(str2pchar(trammoc[Ammoz[TAmmoType(whichone+1)].NameId])); + HW_getWeaponCaptionByIndex:= (str2pchar(trammoc[Ammoz[TAmmoType(whichone+1)].NameId])); end; function HW_getWeaponDescriptionByIndex(whichone: LongInt): PChar; cdecl; export; begin - exit(str2pchar(trammod[Ammoz[TAmmoType(whichone+1)].NameId])); + HW_getWeaponDescriptionByIndex:= (str2pchar(trammod[Ammoz[TAmmoType(whichone+1)].NameId])); end; -function HW_getNumberOfWeapons:LongInt; cdecl; export; +function HW_getNumberOfWeapons: LongInt; cdecl; export; begin - exit(ord(high(TAmmoType))); + HW_getNumberOfWeapons:= ord(high(TAmmoType)); end; procedure HW_setWeapon(whichone: LongInt); cdecl; export; @@ -329,26 +214,27 @@ function HW_isWeaponAnEffect(whichone: LongInt): boolean; cdecl; export; begin - exit(Ammoz[TAmmoType(whichone+1)].Ammo.Propz and ammoprop_Effect <> 0) + HW_isWeaponAnEffect:= Ammoz[TAmmoType(whichone+1)].Ammo.Propz and ammoprop_Effect <> 0; end; function HW_getAmmoCounts(counts: PLongInt): LongInt; cdecl; export; var a : PHHAmmo; - slot, index: LongInt; + slot, index, res: LongInt; begin + HW_getAmmoCounts:= -1; // nil check if (CurrentHedgehog = nil) or (CurrentHedgehog^.Ammo = nil) or (CurrentTeam = nil) then - exit(-1); + exit; // hog controlled by opponent (net or ai) if (CurrentTeam^.ExtDriven) or (CurrentTeam^.Hedgehogs[0].BotLevel <> 0) then - exit(1); + exit; a:= CurrentHedgehog^.Ammo; for slot:= 0 to cMaxSlotIndex do for index:= 0 to cMaxSlotAmmoIndex do if a^[slot,index].Count <> 0 then // yes, ammomenu is hell counts[ord(a^[slot,index].AmmoType)-1]:= a^[slot,index].Count; - exit(0); + HW_getAmmoCounts:= 0; end; procedure HW_getAmmoDelays (skipTurns: PByte); cdecl; export; @@ -360,20 +246,19 @@ function HW_getTurnsForCurrentTeam: LongInt; cdecl; export; begin + HW_getTurnsForCurrentTeam:= 0; if (CurrentTeam <> nil) and (CurrentTeam^.Clan <> nil) then - exit(CurrentTeam^.Clan^.TurnNumber) - else - exit(0); + HW_getTurnsForCurrentTeam:= CurrentTeam^.Clan^.TurnNumber; end; function HW_getMaxNumberOfHogs: LongInt; cdecl; export; begin - exit(cMaxHHIndex+1); + HW_getMaxNumberOfHogs:= cMaxHHIndex + 1; end; function HW_getMaxNumberOfTeams: LongInt; cdecl; export; begin - exit(cMaxTeams); + HW_getMaxNumberOfTeams:= cMaxTeams; end; procedure HW_memoryWarningCallback; cdecl; export; diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/SDLh.pas --- a/hedgewars/SDLh.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/SDLh.pas Wed May 02 23:53:45 2012 +0200 @@ -51,6 +51,9 @@ {$PACKRECORDS C} {$ELSE} {$DEFINE cdecl attribute(cdecl)} + type PByte = ^Byte; + type PInteger = ^Integer; + type PLongInt = ^LongInt; {$ENDIF} {$IFDEF DARWIN} @@ -111,6 +114,10 @@ SDL_ALLEVENTS = $FFFFFFFF; SDL_APPINPUTFOCUS = $02; + + SDL_BUTTON_LEFT = 1; + SDL_BUTTON_MIDDLE = 2; + SDL_BUTTON_RIGHT = 3; SDL_BUTTON_WHEELUP = 4; SDL_BUTTON_WHEELDOWN = 5; @@ -291,7 +298,6 @@ IMG_INIT_PNG = $00000002; IMG_INIT_TIF = $00000004; - {* SDL_EventMask type definition *} ///////////////////////////////////////////////////////////////// /////////////////////// TYPE DEFINITIONS /////////////////////// @@ -368,7 +374,7 @@ {$ENDIF} end; - SDL_eventaction = (SDL_ADDEVENT = 0, SDL_PEEPEVENT, SDL_GETEVENT); + TSDL_eventaction = (SDL_ADDEVENT, SDL_PEEPEVENT, SDL_GETEVENT); PSDL_Surface = ^TSDL_Surface; TSDL_Surface = record @@ -439,7 +445,7 @@ {$IFDEF SDL13} TSDL_KeySym = record scancode: LongInt; - sym: LongInt; + sym: LongWord; modifier: Word; unicode: LongWord; end; @@ -543,9 +549,9 @@ TSDL_KeyboardEvent = record {$IFDEF SDL13} type_: LongWord; - timestamp: LongWord; +// timestamp: LongWord; windowID: LongWord; - state, repeat_, padding2, padding3: Byte; + state, repeat_ {*,padding2, padding3*}: Byte; {$ELSE} type_, which, state: Byte; {$ENDIF} @@ -570,7 +576,7 @@ type_: LongWord; timestamp: LongWord; windowID: LongWord; - buttonm, state, padding1, padding2: Byte; + button, state, padding1, padding2: Byte; x, y: LongInt; {$ELSE} type_, which, button, state: Byte; @@ -907,15 +913,18 @@ function SDL_SetHint(name, value: PChar): Boolean; cdecl; external SDLLibName; procedure SDL_StartTextInput; cdecl; external SDLLibName; -function SDL_PeepEvents(event: PSDL_Event; numevents: LongInt; action: SDL_eventaction; minType, maxType: LongWord): LongInt; cdecl; external SDLLibName; +function SDL_PeepEvents(event: PSDL_Event; numevents: LongInt; action: TSDL_eventaction; minType, maxType: LongWord): LongInt; cdecl; external SDLLibName; function SDL_CreateThread(fn: Pointer; name: PChar; data: Pointer): PSDL_Thread; cdecl; external SDLLibName; {$ELSE} function SDL_CreateThread(fn: Pointer; data: Pointer): PSDL_Thread; cdecl; external SDLLibName; -function SDL_PeepEvents(event: PSDL_Event; numevents: LongInt; action: SDL_eventaction; mask: LongWord): LongInt; cdecl; external SDLLibName; +function SDL_PeepEvents(event: PSDL_Event; numevents: LongInt; action: TSDL_eventaction; mask: LongWord): LongInt; cdecl; external SDLLibName; {$ENDIF} function SDL_GetMouseState(x, y: PLongInt): Byte; cdecl; external SDLLibName; function SDL_GetKeyName(key: LongWord): PChar; cdecl; external SDLLibName; +function SDL_GetScancodeName(key: LongWord): PChar; cdecl; external SDLLibName; +function SDL_GetKeyFromScancode(key: LongWord): LongInt; cdecl; external SDLLibName; + procedure SDL_PumpEvents; cdecl; external SDLLibName; function SDL_PollEvent(event: PSDL_Event): LongInt; cdecl; external SDLLibName; @@ -966,7 +975,7 @@ procedure SDL_FreeFormat(pixelformat: PSDL_PixelFormat); {$IFDEF SDL13}cdecl; external SDLLibName;{$ENDIF} function SDL_VideoDriverName(namebuf: PChar; maxlen: LongInt): PChar; {$IFNDEF SDL13}cdecl; external SDLLibName;{$ENDIF} function SDL_EnableUNICODE(enable: LongInt): LongInt; {$IFNDEF SDL13}cdecl; external SDLLibName;{$ENDIF} -function SDL_EnableKeyRepeat(delay_, interval: LongInt): LongInt; {$IFNDEF SDL13}cdecl; external SDLLibName;{$ENDIF} +function SDL_EnableKeyRepeat(timedelay, interval: LongInt): LongInt; {$IFNDEF SDL13}cdecl; external SDLLibName;{$ENDIF} (* SDL_ttf *) function TTF_Init: LongInt; cdecl; external SDL_TTFLibName; @@ -1045,11 +1054,10 @@ function SDLNet_Read32(buf: Pointer): LongWord; implementation +{$IFDEF SDL13} uses strings, uVariables; -{$IFDEF SDL13} -// this needs to be reimplemented because in SDL_compat.c the window is the one created in the SDL_SetVideoMode -// compatible function, but we use SDL_CreateWindow, so the window would be NULL +// compatible functions procedure SDL_WarpMouse(x, y: Word); begin SDL_WarpMouseInWindow(SDLwindow, x, y); @@ -1062,37 +1070,40 @@ if (name <> nil) and (namebuf <> nil) then begin strlcopy(namebuf, name, maxlen); - exit(namebuf) + SDL_VideoDriverName:= namebuf end; - exit(name); + SDL_VideoDriverName:= name; end; function SDL_EnableUNICODE(enable: LongInt): LongInt; begin SDL_StartTextInput(); - exit(0); + SDL_EnableUNICODE:= 0; end; -function SDL_EnableKeyRepeat(delay_, interval: LongInt): LongInt; +function SDL_EnableKeyRepeat(timedelay, interval: LongInt): LongInt; begin - exit(0); + timedelay:= timedelay; // avoid hint + interval:= interval; // avoid hint + SDL_EnableKeyRepeat:= 0; end; {$ELSE} -function SDL_AllocFormat(format: LongWord): PSDL_PixelFormat; const conversionFormat: TSDL_PixelFormat = ( palette: nil; BitsPerPixel: 32; BytesPerPixel: 4; Rloss: 0; Gloss: 0; Bloss: 0; Aloss: 0; Rshift: RShift; Gshift: GShift; Bshift: BShift; Ashift: AShift; RMask: RMask; GMask: GMask; BMask: BMask; AMask: AMask; colorkey: 0; alpha: 255); + +function SDL_AllocFormat(format: LongWord): PSDL_PixelFormat; begin format:= format; - exit(@conversionFormat); + SDL_AllocFormat:= @conversionFormat; end; procedure SDL_FreeFormat(pixelformat: PSDL_PixelFormat); begin - pixelformat:= pixelformat; + pixelformat:= pixelformat; // avoid hint end; {$ENDIF} @@ -1109,7 +1120,7 @@ {$IFNDEF SDL_MIXER_NEWER} function Mix_Init(flags: LongInt): LongInt; begin - exit(flags); + Mix_Init:= flags; end; procedure Mix_Quit; @@ -1120,7 +1131,7 @@ {$IFNDEF SDL_IMAGE_NEWER} function IMG_Init(flags: LongInt): LongInt; begin - exit(flags); + IMG_Init:= flags; end; procedure IMG_Quit; diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/VGSHandlers.inc --- a/hedgewars/VGSHandlers.inc Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/VGSHandlers.inc Wed May 02 23:53:45 2012 +0200 @@ -728,16 +728,26 @@ begin inc(Gear^.Timer, Steps); - while Gear^.Timer >= 10 do - begin - dec(Gear^.Timer, 10); - if WindBarWidth < Gear^.Tag then - inc(WindBarWidth) - else if WindBarWidth > Gear^.Tag then - dec(WindBarWidth); - end; +while Gear^.Timer >= 10 do + begin + dec(Gear^.Timer, 10); + if WindBarWidth < Gear^.Tag then + inc(WindBarWidth) + else if WindBarWidth > Gear^.Tag then + dec(WindBarWidth); + end; +if cWindspeedf > Gear^.dAngle then + begin + cWindspeedf := cWindspeedf - Gear^.Angle*Steps; + if cWindspeedf < Gear^.dAngle then cWindspeedf:= Gear^.dAngle; + end +else if cWindspeedf < Gear^.dAngle then + begin + cWindspeedf := cWindspeedf + Gear^.Angle*Steps; + if cWindspeedf > Gear^.dAngle then cWindspeedf:= Gear^.dAngle; + end; -if WindBarWidth = Gear^.Tag then +if (WindBarWidth = Gear^.Tag) and (cWindspeedf = Gear^.dAngle) then DeleteVisualGear(Gear) end; //////////////////////////////////////////////////////////////////////////////// diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/adler32.pas --- a/hedgewars/adler32.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/adler32.pas Wed May 02 23:53:45 2012 +0200 @@ -63,9 +63,10 @@ (* As per the license above, noting that this implementation of adler32 was stripped of everything we didn't need. That means no btypes, file loading, and the assembly version disabled. +Also, the structure was removed to simplify C conversion *) -procedure Adler32Update ( var adler :longint; Msg :pointer; Len :longint ); +function Adler32Update ( var adler :longint; Msg :pointer; Len :longint ) : longint; implementation @@ -123,21 +124,17 @@ end; *) -procedure Adler32Update(var adler: longint; Msg: pointer; Len :longint); +function Adler32Update(var adler: longint; Msg: pointer; Len :longint) : longint; {-update Adler32 with Msg data} const BASE = 65521; {max. prime < 65536 } NMAX = 3854; {max. n with 255n(n+1)/2 + (n+1)(BASE-1) < 2^31} - type - LH = packed record - L, H: word; - end; var s1, s2: longint; i, n: integer; begin - s1 := LH(adler).L; - s2 := LH(adler).H; + s1 := adler and $FFFF; + s2 := adler shr 16; while Len>0 do begin if Len -* -* 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 -*) + * Hedgewars, a free turn based strategy game + * Copyright (c) 2004-2012 Andrey Korotaev + * + * 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 "options.inc"} @@ -29,7 +29,7 @@ program hwengine; {$ENDIF} -uses SDLh, uMisc, uConsole, uGame, uConsts, uLand, uAmmos, uVisualGears, uGears, uStore, uWorld, uKeys, uSound, +uses SDLh, uMisc, uConsole, uGame, uConsts, uLand, uAmmos, uVisualGears, uGears, uStore, uWorld, uInputHandler, uSound, uScript, uTeams, uStats, uIO, uLocale, uChat, uAI, uAIMisc, uRandom, uLandTexture, uCollisions, sysutils, uTypes, uVariables, uCommands, uUtils, uCaptions, uDebug, uCommandHandlers, uLandPainted {$IFDEF SDL13}, uTouch{$ENDIF}{$IFDEF ANDROID}, GLUnit{$ENDIF}; @@ -68,7 +68,7 @@ AddFlakes; AssignHHCoords; AddMiscGears; - StoreLoad; + StoreLoad(false); InitWorld; ResetKbd; SoundLoad; @@ -86,7 +86,7 @@ gsConfirm, gsGame: begin DrawWorld(Lag); // never place between ProcessKbd and DoGameTick - bugs due to /put cmd and isCursorVisible - ProcessKbd; +// ProcessKbd; DoGameTick(Lag); ProcessVisualGears(Lag); end; @@ -132,7 +132,7 @@ begin WriteLnToConsole('Freeing resources...'); FreeActionsList(); - StoreRelease(); + StoreRelease(false); ControllerClose(); CloseIPC(); TTF_Quit(); @@ -168,7 +168,12 @@ SDL_KEYDOWN: if GameState = gsChat then // sdl on iphone supports only ashii keyboards and the unicode field is deprecated in sdl 1.3 - KeyPressChat(event.key.keysym.sym); + KeyPressChat(SDL_GetKeyFromScancode(event.key.keysym.sym))//TODO correct for keymodifiers + else + ProcessKey(event.key); + SDL_KEYUP: + if GameState <> gsChat then + ProcessKey(event.key); SDL_WINDOWEVENT: if event.window.event = SDL_WINDOWEVENT_SHOWN then @@ -207,15 +212,17 @@ {$ELSE} SDL_KEYDOWN: if GameState = gsChat then - KeyPressChat(event.key.keysym.unicode); + KeyPressChat(event.key.keysym.unicode) + else + ProcessKey(event.key); + SDL_KEYUP: + if GameState <> gsChat then + ProcessKey(event.key); SDL_MOUSEBUTTONDOWN: - if event.button.button = SDL_BUTTON_WHEELDOWN then - wheelDown:= true; - + ProcessMouse(event.button, true); SDL_MOUSEBUTTONUP: - if event.button.button = SDL_BUTTON_WHEELUP then - wheelUp:= true; + ProcessMouse(event.button, false); SDL_ACTIVEEVENT: if (event.active.state and SDL_APPINPUTFOCUS) <> 0 then @@ -250,31 +257,31 @@ end; //end case event.type_ of end; //end while SDL_PollEvent(@event) <> 0 do - if (cScreenResizeDelay <> 0) and (cScreenResizeDelay < RealTicks) - and ((cNewScreenWidth <> cScreenWidth) or (cNewScreenHeight <> cScreenHeight)) then - begin - cScreenResizeDelay:= 0; - cScreenWidth:= cNewScreenWidth; - cScreenHeight:= cNewScreenHeight; + if (cScreenResizeDelay <> 0) and (cScreenResizeDelay < RealTicks) and + ((cNewScreenWidth <> cScreenWidth) or (cNewScreenHeight <> cScreenHeight)) then + begin + cScreenResizeDelay:= 0; + cScreenWidth:= cNewScreenWidth; + cScreenHeight:= cNewScreenHeight; - ParseCommand('fullscr '+intToStr(LongInt(cFullScreen)), true); - WriteLnToConsole('window resize: ' + IntToStr(cScreenWidth) + ' x ' + IntToStr(cScreenHeight)); - ScriptOnScreenResize(); - InitCameraBorders(); - InitTouchInterface(); - end; + ParseCommand('fullscr '+intToStr(LongInt(cFullScreen)), true); + WriteLnToConsole('window resize: ' + IntToStr(cScreenWidth) + ' x ' + IntToStr(cScreenHeight)); + ScriptOnScreenResize(); + InitCameraBorders(); + InitTouchInterface(); + end; - if isTerminated = false then - begin - CurrTime:= SDL_GetTicks; - if PrevTime + longword(cTimerInterval) <= CurrTime then - begin - DoTimer(CurrTime - PrevTime); - PrevTime:= CurrTime - end - else SDL_Delay(1); - IPCCheckSock(); - end; + if isTerminated = false then + begin + CurrTime:= SDL_GetTicks; + if PrevTime + longword(cTimerInterval) <= CurrTime then + begin + DoTimer(CurrTime - PrevTime); + PrevTime:= CurrTime + end + else SDL_Delay(1); + IPCCheckSock(); + end; end; end; @@ -442,7 +449,7 @@ //uFloat does not need initialization //uGame does not need initialization uGears.initModule; - uKeys.initModule; + uInputHandler.initModule; //uLandGraphics does not need initialization //uLandObjects does not need initialization //uLandTemplates does not need initialization @@ -478,7 +485,7 @@ uLandTexture.freeModule; //uLandObjects does not need to be freed //uLandGraphics does not need to be freed - uKeys.freeModule; //stub + uInputHandler.freeModule; //stub uGears.freeModule; //uGame does not need to be freed //uFloat does not need to be freed diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/options.inc --- a/hedgewars/options.inc Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/options.inc Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ (* * Hedgewars, a free turn based strategy game - * Copyright (c) 2004, 2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 @@ -17,12 +17,12 @@ *) {$IFDEF FPC} - {$J+} + {$WRITEABLECONST OFF} + {$MODE OBJFPC} {$ELSE} {$ERROR Only Free Pascal supported!} {$ENDIF} -{$MODE OBJFPC} {$MACRO ON} {$DEFINE GLunit:=GL} @@ -63,4 +63,8 @@ //{$DEFINE COUNTTICKS} {$ENDIF} +{$IFNDEF MOBILE} + {$DEFINE USE_AM_NUMCOLUMN} +{$ENDIF} + //also available LUA_DISABLED diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/pas2c.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hedgewars/pas2c.h Wed May 02 23:53:45 2012 +0200 @@ -0,0 +1,93 @@ +#pragma once + +#include +#include + +typedef union string255_ + { + struct { + char s[256]; + }; + struct { + char len; + char str[255]; + }; + } string255; +typedef struct string192_ + { + char s[193]; + } string192; +typedef struct string31_ + { + char s[32]; + } string31; +typedef struct string15_ + { + char s[16]; + } string15; + +typedef uint8_t Byte; +typedef int8_t ShortInt; +typedef uint16_t Word; +typedef int16_t SmallInt; +typedef uint32_t LongWord; +typedef int32_t LongInt; +typedef uint64_t QWord; +typedef int64_t Int64; + +typedef LongInt Integer; +typedef float extended; +typedef float real; + +typedef bool boolean; + +typedef void * pointer; +typedef Byte * PByte; +typedef char * PChar; +typedef LongInt * PLongInt; +typedef Integer * PInteger; + +#ifdef __GNUG__ +#define NULL __null +#else /* G++ */ +/* shield NULL definition for non-gnu parsers */ +#ifndef __cplusplus +#define NULL ((void *)0) +#else +#define NULL 0 +#endif /* __cplusplus */ +#endif /* G++ */ + +#define new(a) __new((void **)&a, sizeof(*(a))) +void __new(void ** p, int size); + +#define dispose(a) __dispose(a, sizeof(*(a))) +void __dispose(pointer p, int size); + +#define FillChar(a, b, c) __FillChar(&(a), b, c) + +void __FillChar(pointer p, int size, char fill); +string255 _strconcat(string255 a, string255 b); +string255 _strappend(string255 s, char c); +string255 _strprepend(char c, string255 s); +bool _strcompare(string255 a, string255 b); +char * _pchar(string255 s); + +int Length(string255 a); +string255 copy(string255 a, int s, int l); +string255 delete(string255 a, int s, int l); + +#define STRINIT(a) {.len = sizeof(a) - 1, .str = a} + +typedef int file; +extern int FileMode; +extern int IOResult; + +#define assign(a, b) assign_(&(a), b) +void assign_(int * f, string255 fileName); +void reset(int f, int size); +#define BlockRead(a, b, c, d) BlockRead_(a, &(b), c, &(d)) +void BlockRead_(int f, void * p, int size, int * sizeRead); +void close(int f); + +bool odd(int i); diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/pas2cSystem.pas --- a/hedgewars/pas2cSystem.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/pas2cSystem.pas Wed May 02 23:53:45 2012 +0200 @@ -11,19 +11,19 @@ SmallInt = integer; ShortInt = integer; QWord = integer; - GLInt = integer; - GLUInt = integer; + GLint = integer; + GLuint = integer; gl_unsigned_byte = integer; + Int = integer; pointer = pointer; - PChar = pointer; float = float; single = float; double = float; real = float; extended = float; - GLFloat = float; + GLfloat = float; gl_float = float; boolean = boolean; @@ -35,6 +35,8 @@ widechar = string; char = char; + PChar = ^char; + PPChar = ^Pchar; PByte = ^Byte; PLongInt = ^LongInt; @@ -44,30 +46,43 @@ Handle = integer; stderr = Handle; + png_structp = pointer; + png_size_t = integer; + var false, true: boolean; + write, writeLn, read, readLn: procedure; + StrLen, ord, Succ, Pred : function : integer; inc, dec, Low, High, Lo, Hi : function : integer; odd, even : function : boolean; Now : function : integer; - Length : function : integer; - SetLength, val : procedure; new, dispose, FillChar, Move : procedure; trunc, round : function : integer; Abs, Sqr : function : integer; - StrPas, FormatDateTime, copy, delete, str : function : shortstring; + StrPas, FormatDateTime, copy, delete, str, pos, trim, LowerCase : function : shortstring; + Length, StrToInt : function : integer; + SetLength, val : procedure; + _pchar : function : PChar; - assign, rewrite, reset, flush : procedure; - IOResult : function : integer; - exit, break, halt : procedure; - TextFile : Handle; + assign, rewrite, reset, flush, BlockWrite, BlockRead, close : procedure; + IOResult : integer; + exit, break, halt, continue : procedure; + TextFile, file : Handle; + FileMode : integer; + FileExists, DirectoryExists, eof : function : boolean; + ExtractFileName : function : string; + exitcode : integer; + + ParamCount : function : integer; + ParamStr : function : string; - Sqrt, ArcTan2, pi, cos, sin : function : float; + sqrt, arctan2, pi, cos, sin, power : function : float; TypeInfo, GetEnumName : function : shortstring; @@ -86,6 +101,45 @@ glcolor4ub, gl_texture_wrap_s, gltexparameteri, gl_texture_wrap_t, gl_texture_min_filter, gl_linear, gl_texture_mag_filter, glgentextures, - gldeletetextures : procedure; + gldeletetextures, glreadpixels, glclearcolor, + gl_line_strip, gldeleterenderbuffersext, + gldeleteframebuffersext, glext_loadextension, + gl_max_texture_size, glgetintegerv, gl_renderer, + glgetstring, gl_vendor, gl_version, glgenframebuffersext, + glbindframebufferext, glgenrenderbuffersext, + glbindrenderbufferext, glrenderbufferstorageext, + glframebufferrenderbufferext, glframebuffertexture2dext, + gl_framebuffer_ext, gl_depth_component, + gl_depth_attachment_ext, gl_renderbuffer_ext, gl_rgba8, + gl_color_attachment0_ext, gl_modelview, gl_blend, + gl_src_alpha, gl_one_minus_src_alpha, + gl_perspective_correction_hint, gl_fastest, + gl_dither, gl_vertex_array, gl_texture_coord_array, + glviewport, glloadidentity, glmatrixmode, glhint, + glblendfunc, glenableclientstate, gl_color_buffer_bit, + glclear, gldisableclientstate, gl_color_array, + glcolorpointer, gl_depth_buffer_bit, gl_quads, + glbegin, glend, gltexcoord2f, glvertex2d, + gl_true, gl_false, glcolormask, gl_projection, + gl_texture_priority, glenum, gl_clamp_to_edge, + gl_extensions, gl_bgra : procedure; TThreadId : function : integer; + BeginThread, ThreadSwitch : procedure; + InterlockedIncrement, InterlockedDecrement : procedure; + + random : function : integer; + randomize : procedure; + + Assigned : function : boolean; + + _strconcat, _strappend, _strprepend : function : string; + _strcompare, _strncompare : function : boolean; + + png_structp, png_set_write_fn, png_get_io_ptr, + png_get_libpng_ver, png_create_write_struct, + png_create_info_struct, png_destroy_write_struct, + png_write_row, png_set_ihdr, png_write_info, + png_write_end : procedure; + + EnumToStr : function : string; diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uAI.pas --- a/hedgewars/uAI.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uAI.pas Wed May 02 23:53:45 2012 +0200 @@ -291,7 +291,8 @@ function Think(Me: Pointer): ptrint; var BackMe, WalkMe: TGear; - StartTicks, currHedgehogIndex, itHedgehog, switchesNum, i, switchCount: Longword; + switchCount: LongInt; + StartTicks, currHedgehogIndex, itHedgehog, switchesNum, i: Longword; switchImmediatelyAvailable: boolean; Actions: TActions; begin @@ -319,7 +320,7 @@ if not switchImmediatelyAvailable then begin // when AI has to use switcher, make it cost smth unless they have a lot of switches - if (SwitchCount < 10) then Actions.Score:= (-27+SwitchCount*3)*4000; + if (switchCount < 10) then Actions.Score:= (-27+switchCount*3)*4000; AddAction(Actions, aia_Weapon, Longword(amSwitch), 300 + random(200), 0, 0); AddAction(Actions, aia_attack, aim_push, 300 + random(300), 0, 0); AddAction(Actions, aia_attack, aim_release, 1, 0, 0); @@ -408,8 +409,7 @@ end; procedure ProcessBot; -const StartTicks: Longword = 0; - cStopThinkTime = 40; +const cStopThinkTime = 40; begin with CurrentHedgehog^ do if (Gear <> nil) @@ -439,6 +439,7 @@ procedure initModule; begin hasThread:= 0; + StartTicks:= 0; ThinkThread:= ThinkThread; end; diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uAIActions.pas --- a/hedgewars/uAIActions.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uAIActions.pas Wed May 02 23:53:45 2012 +0200 @@ -126,8 +126,6 @@ end; procedure CheckHang(Me: PGear); -const PrevX: LongInt = 0; - timedelta: Longword = 0; begin if hwRound(Me^.X) <> PrevX then begin diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uAIAmmoTests.pas --- a/hedgewars/uAIAmmoTests.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uAIAmmoTests.pas Wed May 02 23:53:45 2012 +0200 @@ -166,7 +166,7 @@ value:= - Metric(Targ.X, Targ.Y, EX, EY) div 64; if valueResult <= value then begin - ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random((Level - 1) * 9)); + ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random((Level - 1) * 9)); ap.Power:= trunc(sqrt(r) * cMaxPower) - random((Level - 1) * 17 + 1); ap.ExplR:= 100; ap.ExplX:= EX; @@ -223,7 +223,7 @@ if valueResult <= value then begin - ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random((Level - 1) * 9)); + ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random((Level - 1) * 9)); ap.Power:= trunc(sqrt(r) * cMaxPower) - random((Level - 1) * 17 + 1); ap.ExplR:= 0; ap.ExplX:= EX; @@ -273,7 +273,7 @@ if valueResult < Score then begin - ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random(Level)); + ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level)); ap.Power:= trunc(sqrt(r) * cMaxPower) + AIrndSign(random(Level) * 15); ap.Time:= TestTime; ap.ExplR:= 100; @@ -327,7 +327,7 @@ if valueResult < Score then begin - ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random(Level)); + ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level)); ap.Power:= trunc(sqrt(r) * cMaxPower) + AIrndSign(random(Level) * 15); ap.Time:= TestTime; ap.ExplR:= 100; @@ -384,7 +384,7 @@ if valueResult < Score then begin - ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random(Level)); + ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level)); ap.Power:= trunc(sqrt(r) * cMaxPower * 0.9) + AIrndSign(random(Level) * 15); ap.Time:= TestTime; ap.ExplR:= 90; @@ -436,7 +436,7 @@ if valueResult < Score then begin - ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random(Level)); + ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level)); ap.Power:= trunc(sqrt(r) * cMaxPower * 0.9) + AIrndSign(random(Level) * 15); ap.Time:= TestTime; ap.ExplR:= 300; @@ -474,22 +474,22 @@ function TestMortar(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; //const tDelta = 24; var Vx, Vy: real; - Score, EX, EY, valueResult: LongInt; + Score, EX, EY: LongInt; TestTime: Longword; x, y, dY, meX, meY: real; begin -valueResult:= BadTurn; +TestMortar:= BadTurn; ap.ExplR:= 0; meX:= hwFloat2Float(Me^.X); meY:= hwFloat2Float(Me^.Y); if (Level > 2) then - exit(BadTurn); + exit; TestTime:= Solve(Targ.X, Targ.Y, trunc(meX), trunc(meY)); if TestTime = 0 then - exit(BadTurn); + exit; Vx:= (Targ.X - meX) / TestTime; Vy:= cGravityf * (TestTime div 2) - (Targ.Y - meY) / TestTime; @@ -520,17 +520,15 @@ else Score:= BadTurn; - if valueResult < Score then + if BadTurn < Score then begin - ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random(Level)); + ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level)); ap.Power:= 1; ap.ExplR:= 100; ap.ExplX:= EX; ap.ExplY:= EY; - valueResult:= Score + TestMortar:= Score end; - -TestMortar:= valueResult; end; function TestShotgun(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; @@ -541,6 +539,7 @@ rx, ry, valueResult: LongInt; range: integer; begin +TestShotgun:= BadTurn; ap.ExplR:= 0; ap.Time:= 0; ap.Power:= 1; @@ -548,26 +547,28 @@ y:= hwFloat2Float(Me^.Y); range:= Metric(trunc(x), trunc(y), Targ.X, Targ.Y); if ( range < MIN_RANGE ) or ( range > MAX_RANGE ) then - exit(BadTurn); + exit; Vx:= (Targ.X - x) * 1 / 1024; Vy:= (Targ.Y - y) * 1 / 1024; -ap.Angle:= DxDy2AttackAngle(Vx, -Vy); +ap.Angle:= DxDy2AttackAnglef(Vx, -Vy); repeat x:= x + vX; y:= y + vY; rx:= trunc(x); ry:= trunc(y); if TestCollExcludingMe(Me, rx, ry, 2) then - begin + begin x:= x + vX * 8; y:= y + vY * 8; valueResult:= RateShotgun(Me, vX, vY, rx, ry); - if valueResult = 0 then - valueResult:= - Metric(Targ.X, Targ.Y, rx, ry) div 64 - else - dec(valueResult, Level * 4000); - exit(valueResult * 27 div 20) // 27/20 is reuse bonus + if valueResult = 0 then + valueResult:= - Metric(Targ.X, Targ.Y, rx, ry) div 64 + else + dec(valueResult, Level * 4000); + // 27/20 is reuse bonus + TestShotgun:= valueResult * 27 div 20; + exit end until (Abs(Targ.X - trunc(x)) + Abs(Targ.Y - trunc(y)) < 4) or (x < 0) @@ -591,11 +592,14 @@ x:= hwFloat2Float(Me^.X); y:= hwFloat2Float(Me^.Y); if Abs(trunc(x) - Targ.X) + Abs(trunc(y) - Targ.Y) < 40 then - exit(BadTurn); +begin + TestDesertEagle:= BadTurn; + exit; +end; t:= 0.5 / sqrt(sqr(Targ.X - x)+sqr(Targ.Y-y)); Vx:= (Targ.X - x) * t; Vy:= (Targ.Y - y) * t; -ap.Angle:= DxDy2AttackAngle(Vx, -Vy); +ap.Angle:= DxDy2AttackAnglef(Vx, -Vy); d:= 0; repeat @@ -628,11 +632,12 @@ x, y: real; begin Level:= Level; // avoid compiler hint +TestBaseballBat:= BadTurn; ap.ExplR:= 0; x:= hwFloat2Float(Me^.X); y:= hwFloat2Float(Me^.Y); if (Level > 2) or (Abs(trunc(x) - Targ.X) + Abs(trunc(y) - Targ.Y) > 25) then - exit(BadTurn); + exit; ap.Time:= 0; ap.Power:= 1; @@ -641,7 +646,7 @@ else ap.Angle:= - cMaxAngle div 4; -valueResult:= RateShove(Me, trunc(x) + 10 * hwSign(Targ.X - x), trunc(y), 15, 30, 115, hwSign(Me^.dX)*0.353, -0.353, 1); +valueResult:= RateShove(Me, trunc(x) + LongWord(10*hwSignf(Targ.X - x)), trunc(y), 15, 30, 115, hwSign(Me^.dX)*0.353, -0.353, 1); if valueResult <= 0 then valueResult:= BadTurn else @@ -650,7 +655,7 @@ end; function TestFirePunch(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; -var i, val1, val2, t: LongInt; +var val1: LongInt; x, y: real; begin Level:= Level; // avoid compiler hint @@ -665,12 +670,13 @@ begin // TODO - find out WTH this works. if TestColl(trunc(x), trunc(y) - 16, 6) and - (RateShove(Me, trunc(x) + 10 * hwSign(Me^.dX), + (RateShove(Me, trunc(x) + LongWord(10 * hwSign(Me^.dX)), trunc(y) - 40, 30, 30, 40, hwSign(Me^.dX)*0.45, -0.9, 1) = 0) then val1:= Succ(BadTurn) else val1:= BadTurn; - exit(val1) + TestFirePunch:= val1; + exit; end; (* For some silly reason, having this enabled w/ the AI @@ -714,17 +720,18 @@ or (Abs(trunc(y) - 50 - Targ.Y) > 50) then begin if TestColl(trunc(x), trunc(y) - 16, 6) - and (RateShove(Me, trunc(x) + 10 * hwSign(Me^.dX), trunc(y) - 40, 30, 30, 40, hwSign(Me^.dX), -0.8, 1) = 0) then + and (RateShove(Me, trunc(x) + LongWord(10 * hwSign(Me^.dX)), trunc(y) - 40, 30, 30, 40, hwSign(Me^.dX), -0.8, 1) = 0) then valueResult:= Succ(BadTurn) else valueResult:= BadTurn; - exit(valueResult) + TestWhip:= valueResult; + exit; end; valueResult:= 0; for i:= 0 to 4 do - valueResult:= valueResult + RateShove(Me, trunc(x) + 10 * hwSign(Targ.X - x), - trunc(y) - 20 * i - 5, 10, 30, 40, hwSign(Me^.dX), -0.8, 1); + valueResult:= valueResult + RateShove(Me, trunc(x) + LongWord(10 * hwSignf(Targ.X - x)), + trunc(y) - LongWord(20 * i) - 5, 10, 30, 40, hwSign(Me^.dX), -0.8, 1); if valueResult <= 0 then valueResult:= BadTurn else @@ -762,7 +769,10 @@ ap.ExplR:= 0; ap.Time:= 0; if (Level > 3) then - exit(BadTurn); +begin + TestAirAttack:= BadTurn; + exit; +end; ap.AttackPutX:= Targ.X; ap.AttackPutY:= Targ.Y; @@ -790,10 +800,10 @@ if b[i] then begin fexit:= false; - if TestColl(trunc(X) + i * 30, trunc(Y), 4) then + if TestColl(trunc(X) + LongWord(i * 30), trunc(Y), 4) then begin b[i]:= false; - dmg[i]:= RateExplosion(Me, trunc(X) + i * 30, trunc(Y), 58) + dmg[i]:= RateExplosion(Me, trunc(X) + LongWord(i * 30), trunc(Y), 58) // 58 (instead of 60) for better prediction (hh moves after explosion of one of the rockets) end end; @@ -826,8 +836,9 @@ maxTop: longword; begin TestTeleport := BadTurn; + exit; Level:= Level; // avoid compiler hint - FillBonuses(true, [gtCase]); + //FillBonuses(true, [gtCase]); if bonuses.Count = 0 then begin if Me^.Health <= 100 then diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uAIMisc.pas --- a/hedgewars/uAIMisc.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uAIMisc.pas Wed May 02 23:53:45 2012 +0200 @@ -1,6 +1,6 @@ (* * Hedgewars, a free turn based strategy game - * Copyright (c) 2005-2012 Andrey Korotaev + * Copyright (c) 2004-2012 Andrey Korotaev * * 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 @@ -48,18 +48,22 @@ procedure freeModule; procedure FillTargets; -procedure FillBonuses(isAfterAttack: boolean; filter: TGearsType = []); +procedure FillBonuses(isAfterAttack: boolean); procedure AwareOfExplosion(x, y, r: LongInt); inline; -function RatePlace(Gear: PGear): LongInt; -function TestCollExcludingMe(Me: PGear; x, y, r: LongInt): boolean; inline; -function TestColl(x, y, r: LongInt): boolean; inline; -function TraceShoveFall(Me: PGear; x, y, dX, dY: Real): LongInt; -function RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord = 0): LongInt; -function RateShove(Me: PGear; x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt; -function RateShotgun(Me: PGear; gdX, gdY: real; x, y: LongInt): LongInt; -function RateHammer(Me: PGear): LongInt; -function HHGo(Gear, AltGear: PGear; var GoInfo: TGoInfo): boolean; -function AIrndSign(num: LongInt): LongInt; + +function RatePlace(Gear: PGear): LongInt; +function TestColl(x, y, r: LongInt): boolean; inline; +function TestCollExcludingMe(Me: PGear; x, y, r: LongInt): boolean; inline; +function TraceShoveFall(Me: PGear; x, y, dX, dY: Real): LongInt; + +function RateExplosion(Me: PGear; x, y, r: LongInt): LongInt; inline; +function RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt; +function RateShove(Me: PGear; x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt; +function RateShotgun(Me: PGear; gdX, gdY: real; x, y: LongInt): LongInt; +function RateHammer(Me: PGear): LongInt; + +function HHGo(Gear, AltGear: PGear; var GoInfo: TGoInfo): boolean; +function AIrndSign(num: LongInt): LongInt; var ThinkingHH: PGear; Targets: TTargets; @@ -126,7 +130,7 @@ TryDo(bonuses.Count <= MAXBONUS, 'Bonuses overflow', true) end; -procedure FillBonuses(isAfterAttack: boolean; filter: TGearsType); +procedure FillBonuses(isAfterAttack: boolean); var Gear: PGear; MyClan: PClan; begin @@ -135,7 +139,6 @@ Gear:= GearsList; while Gear <> nil do begin - if (filter = []) or (Gear^.Kind in filter) then case Gear^.Kind of gtCase: AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 33, 25); @@ -179,11 +182,11 @@ AddBonus(X, Y, Radius + 10, -Radius); end; -procedure AwareOfExplosion(x, y, r: LongInt); +procedure AwareOfExplosion(x, y, r: LongInt); inline; begin -KnownExplosion.X:= x; -KnownExplosion.Y:= y; -KnownExplosion.Radius:= r + KnownExplosion.X:= x; + KnownExplosion.Y:= y; + KnownExplosion.Radius:= r end; function RatePlace(Gear: PGear): LongInt; @@ -210,54 +213,67 @@ // Wrapper to test various approaches. If it works reasonably, will just replace. // Right now, converting to hwFloat is a tad inefficient since the x/y were hwFloat to begin with... -function TestCollExcludingMe(Me: PGear; x, y, r: LongInt): boolean; +function TestCollExcludingMe(Me: PGear; x, y, r: LongInt): boolean; inline; var MeX, MeY: LongInt; begin + TestCollExcludingMe:= false; if ((x and LAND_WIDTH_MASK) = 0) and ((y and LAND_HEIGHT_MASK) = 0) then - begin + begin MeX:= hwRound(Me^.X); MeY:= hwRound(Me^.Y); // We are still inside the hog. Skip radius test if ((((x-MeX)*(x-MeX)) + ((y-MeY)*(y-MeY))) < 256) and ((Land[y, x] and $FF00) = 0) then - exit(false); - end; - exit(TestColl(x, y, r)) + exit; + end; + TestCollExcludingMe:= TestColl(x, y, r) end; -function TestColl(x, y, r: LongInt): boolean; +function TestColl(x, y, r: LongInt): boolean; inline; var b: boolean; begin -b:= (((x-r) and LAND_WIDTH_MASK) = 0)and(((y-r) and LAND_HEIGHT_MASK) = 0) and (Land[y-r, x-r] <> 0); -if b then - exit(true); + TestColl:= true; + + b:= (((x-r) and LAND_WIDTH_MASK) = 0) and (((y-r) and LAND_HEIGHT_MASK) = 0) and (Land[y-r, x-r] <> 0); + if b then + exit; + + b:= (((x-r) and LAND_WIDTH_MASK) = 0) and (((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x-r] <> 0); + if b then + exit; -b:=(((x-r) and LAND_WIDTH_MASK) = 0)and(((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x-r] <> 0); -if b then - exit(true); + b:= (((x+r) and LAND_WIDTH_MASK) = 0) and (((y-r) and LAND_HEIGHT_MASK) = 0) and (Land[y-r, x+r] <> 0); + if b then + exit; -b:=(((x+r) and LAND_WIDTH_MASK) = 0)and(((y-r) and LAND_HEIGHT_MASK) = 0) and (Land[y-r, x+r] <> 0); -if b then - exit(true); + b:= (((x+r) and LAND_WIDTH_MASK) = 0) and (((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x+r] <> 0); + if b then + exit; -TestColl:=(((x+r) and LAND_WIDTH_MASK) = 0)and(((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x+r] <> 0) + TestColl:= false; end; function TestCollWithLand(x, y, r: LongInt): boolean; inline; var b: boolean; begin -b:= (((x-r) and LAND_WIDTH_MASK) = 0)and(((y-r) and LAND_HEIGHT_MASK) = 0) and (Land[y-r, x-r] > 255); -if b then - exit(true); + TestCollWithLand:= true; -b:=(((x-r) and LAND_WIDTH_MASK) = 0)and(((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x-r] > 255); -if b then - exit(true); - -b:=(((x+r) and LAND_WIDTH_MASK) = 0)and(((y-r) and LAND_HEIGHT_MASK) = 0) and (Land[y-r, x+r] > 255); -if b then - exit(true); - -TestCollWithLand:=(((x+r) and LAND_WIDTH_MASK) = 0) and (((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x+r] > 255) + b:= (((x-r) and LAND_WIDTH_MASK) = 0) and (((y-r) and LAND_HEIGHT_MASK) = 0) and (Land[y-r, x-r] > 255); + if b then + exit; + + b:= (((x-r) and LAND_WIDTH_MASK) = 0) and (((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x-r] > 255); + if b then + exit; + + b:= (((x+r) and LAND_WIDTH_MASK) = 0) and (((y-r) and LAND_HEIGHT_MASK) = 0) and (Land[y-r, x+r] > 255); + if b then + exit; + + b:= (((x+r) and LAND_WIDTH_MASK) = 0) and (((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x+r] > 255); + if b then + exit; + + TestCollWithLand:= false; end; function TraceFall(eX, eY: LongInt; x, y, dX, dY: Real; r: LongWord): LongInt; @@ -271,48 +287,73 @@ // ok. attempt approximate search for an unbroken trajectory into water. if it continues far enough, assume out of map rCorner:= r * 0.75; while true do - begin + begin x:= x + dX; y:= y + dY; dY:= dY + cGravityf; skipLandCheck:= skipLandCheck and (r <> 0) and (abs(eX-x) + abs(eY-y) < r) and ((abs(eX-x) < rCorner) or (abs(eY-y) < rCorner)); if not skipLandCheck and TestCollWithLand(trunc(x), trunc(y), cHHRadius) then - begin + begin if 0.4 < dY then - begin + begin dmg := 1 + trunc((abs(dY) - 0.4) * 70); - if dmg >= 1 then exit(dmg) + if dmg >= 1 then + begin + TraceFall:= dmg; + exit end; - exit(0) end; - if (y > cWaterLine) or (x > 4096) or (x < 0) then exit(-1); // returning -1 for drowning so it can be considered in the Rate routine + TraceFall:= 0; + exit end; + if (y > cWaterLine) or (x > 4096) or (x < 0) then + begin + // returning -1 for drowning so it can be considered in the Rate routine + TraceFall:= -1; + exit; + end; + end; end; function TraceShoveFall(Me: PGear; x, y, dX, dY: Real): LongInt; var dmg: LongInt; begin while true do - begin + begin x:= x + dX; y:= y + dY; dY:= dY + cGravityf; // consider adding dX/dY calc here for fall damage if TestCollExcludingMe(Me, trunc(x), trunc(y), cHHRadius) then - begin + begin if 0.4 < dY then - begin + begin dmg := 1 + trunc((abs(dY) - 0.4) * 70); - if dmg >= 1 then exit(dmg) + if dmg >= 1 then + begin + TraceShoveFall:= dmg; + exit end; - exit(0) end; - if (y > cWaterLine) or (x > 4096) or (x < 0) then exit(-1); // returning -1 for drowning so it can be considered in the Rate routine + TraceShoveFall:= 0; + exit end; + if (y > cWaterLine) or (x > 4096) or (x < 0) then + begin + // returning -1 for drowning so it can be considered in the Rate routine + TraceShoveFall:= -1; + exit; + end; + end; end; // Flags are not defined yet but 1 for checking drowning and 2 for assuming land erasure. -function RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord = 0): LongInt; +function RateExplosion(Me: PGear; x, y, r: LongInt): LongInt; +begin + RateExplosion:= RateExplosion(Me, x, y, r, 0); +end; + +function RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt; var i, fallDmg, dmg, dmgBase, rate, erasure: LongInt; dX, dY, dmgMod: real; begin @@ -487,95 +528,95 @@ function HHJump(Gear: PGear; JumpType: TJumpType; var GoInfo: TGoInfo): boolean; var bX, bY: LongInt; - bRes: boolean; begin -bRes:= false; +HHJump:= false; GoInfo.Ticks:= 0; GoInfo.JumpType:= jmpNone; bX:= hwRound(Gear^.X); bY:= hwRound(Gear^.Y); case JumpType of - jmpNone: - exit(bRes); + jmpNone: exit; jmpHJump: - if TestCollisionYwithGear(Gear, -1) = 0 then + if TestCollisionYwithGear(Gear, -1) = 0 then begin - Gear^.dY:= -_0_2; - SetLittle(Gear^.dX); - Gear^.State:= Gear^.State or gstMoving or gstHHJumping; + Gear^.dY:= -_0_2; + SetLittle(Gear^.dX); + Gear^.State:= Gear^.State or gstMoving or gstHHJumping; end else - exit(bRes); + exit; jmpLJump: - begin - if TestCollisionYwithGear(Gear, -1) <> 0 then - if not TestCollisionXwithXYShift(Gear, _0, -2, hwSign(Gear^.dX)) then - Gear^.Y:= Gear^.Y - int2hwFloat(2) - else - if not TestCollisionXwithXYShift(Gear, _0, -1, hwSign(Gear^.dX)) then - Gear^.Y:= Gear^.Y - _1; - if not (TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) - or (TestCollisionYwithGear(Gear, -1) <> 0)) then + begin + if TestCollisionYwithGear(Gear, -1) <> 0 then + if not TestCollisionXwithXYShift(Gear, _0, -2, hwSign(Gear^.dX)) then + Gear^.Y:= Gear^.Y - int2hwFloat(2) + else + if not TestCollisionXwithXYShift(Gear, _0, -1, hwSign(Gear^.dX)) then + Gear^.Y:= Gear^.Y - _1; + if not (TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) or + (TestCollisionYwithGear(Gear, -1) <> 0)) then begin - Gear^.dY:= -_0_15; - Gear^.dX:= SignAs(_0_15, Gear^.dX); - Gear^.State:= Gear^.State or gstMoving or gstHHJumping + Gear^.dY:= -_0_15; + Gear^.dX:= SignAs(_0_15, Gear^.dX); + Gear^.State:= Gear^.State or gstMoving or gstHHJumping end else - exit(bRes) - end - end; + exit + end +end; repeat if not (hwRound(Gear^.Y) + cHHRadius < cWaterLine) then - exit(bRes); + exit; if (Gear^.State and gstMoving) <> 0 then - begin + begin if (GoInfo.Ticks = 350) then if (not (hwAbs(Gear^.dX) > cLittle)) and (Gear^.dY < -_0_02) then - begin + begin Gear^.dY:= -_0_25; Gear^.dX:= SignAs(_0_02, Gear^.dX) - end; - if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then SetLittle(Gear^.dX); - Gear^.X:= Gear^.X + Gear^.dX; - inc(GoInfo.Ticks); - Gear^.dY:= Gear^.dY + cGravity; - if Gear^.dY > _0_4 then - exit(bRes); - if (Gear^.dY.isNegative)and (TestCollisionYwithGear(Gear, -1) <> 0) then - Gear^.dY:= _0; - Gear^.Y:= Gear^.Y + Gear^.dY; - if (not Gear^.dY.isNegative)and (TestCollisionYwithGear(Gear, 1) <> 0) then + end; + if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then SetLittle(Gear^.dX); + Gear^.X:= Gear^.X + Gear^.dX; + inc(GoInfo.Ticks); + Gear^.dY:= Gear^.dY + cGravity; + if Gear^.dY > _0_4 then + exit; + if (Gear^.dY.isNegative) and (TestCollisionYwithGear(Gear, -1) <> 0) then + Gear^.dY:= _0; + Gear^.Y:= Gear^.Y + Gear^.dY; + if (not Gear^.dY.isNegative) and (TestCollisionYwithGear(Gear, 1) <> 0) then begin - Gear^.State:= Gear^.State and not (gstMoving or gstHHJumping); - Gear^.dY:= _0; - case JumpType of - jmpHJump: - if bY - hwRound(Gear^.Y) > 5 then - begin - bRes:= true; - GoInfo.JumpType:= jmpHJump; - inc(GoInfo.Ticks, 300 + 300) // 300 before jump, 300 after - end; - jmpLJump: if abs(bX - hwRound(Gear^.X)) > 30 then - begin - bRes:= true; - GoInfo.JumpType:= jmpLJump; - inc(GoInfo.Ticks, 300 + 300) // 300 before jump, 300 after - end - end; - exit(bRes) + Gear^.State:= Gear^.State and not (gstMoving or gstHHJumping); + Gear^.dY:= _0; + case JumpType of + jmpHJump: + if bY - hwRound(Gear^.Y) > 5 then + begin + HHJump:= true; + GoInfo.JumpType:= jmpHJump; + inc(GoInfo.Ticks, 300 + 300) // 300 before jump, 300 after + end; + jmpLJump: + if abs(bX - hwRound(Gear^.X)) > 30 then + begin + HHJump:= true; + GoInfo.JumpType:= jmpLJump; + inc(GoInfo.Ticks, 300 + 300) // 300 before jump, 300 after + end end; + exit end; + end; until false end; function HHGo(Gear, AltGear: PGear; var GoInfo: TGoInfo): boolean; var pX, pY: LongInt; begin +HHGo:= false; AltGear^:= Gear^; GoInfo.Ticks:= 0; @@ -585,7 +626,7 @@ pX:= hwRound(Gear^.X); pY:= hwRound(Gear^.Y); if pY + cHHRadius >= cWaterLine then - exit(false); + exit; if (Gear^.State and gstMoving) <> 0 then begin inc(GoInfo.Ticks); @@ -594,7 +635,7 @@ begin Goinfo.FallPix:= 0; HHJump(AltGear, jmpLJump, GoInfo); // try ljump instead of fall with damage - exit(false) + exit end; Gear^.Y:= Gear^.Y + Gear^.dY; if hwRound(Gear^.Y) > pY then @@ -605,7 +646,8 @@ Gear^.State:= Gear^.State and not (gstMoving or gstHHJumping); Gear^.dY:= _0; HHJump(AltGear, jmpLJump, GoInfo); // try ljump instead of fall - exit(true) + HHGo:= true; + exit end; continue end; @@ -613,9 +655,9 @@ Gear^.dX:= -cLittle else if (Gear^.Message and gmRight )<>0 then - Gear^.dX:= cLittle + Gear^.dX:= cLittle else - exit(false); + exit; if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then begin if not (TestCollisionXwithXYShift(Gear, _0, -6, hwSign(Gear^.dX)) @@ -643,17 +685,18 @@ end; if not TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then - begin + begin Gear^.X:= Gear^.X + int2hwFloat(hwSign(Gear^.dX)); inc(GoInfo.Ticks, cHHStepTicks) - end; - + end; + + // too scared to reformat this part if TestCollisionYwithGear(Gear, 1) = 0 then begin Gear^.Y:= Gear^.Y + _1; if TestCollisionYwithGear(Gear, 1) = 0 then - begin + begin Gear^.Y:= Gear^.Y + _1; if TestCollisionYwithGear(Gear, 1) = 0 then @@ -685,10 +728,12 @@ end end; if (pX <> hwRound(Gear^.X)) and ((Gear^.State and gstMoving) = 0) then - exit(true); +begin + HHGo:= true; + exit; +end; until (pX = hwRound(Gear^.X)) and (pY = hwRound(Gear^.Y)) and ((Gear^.State and gstMoving) = 0); HHJump(AltGear, jmpHJump, GoInfo); -HHGo:= false; end; function AIrndSign(num: LongInt): LongInt; diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uAmmos.pas --- a/hedgewars/uAmmos.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uAmmos.pas Wed May 02 23:53:45 2012 +0200 @@ -26,13 +26,13 @@ procedure freeModule; procedure AddAmmoStore; -procedure SetAmmoLoadout(s: shortstring); -procedure SetAmmoProbability(s: shortstring); -procedure SetAmmoDelay(s: shortstring); -procedure SetAmmoReinforcement(s: shortstring); +procedure SetAmmoLoadout(var s: shortstring); +procedure SetAmmoProbability(var s: shortstring); +procedure SetAmmoDelay(var s: shortstring); +procedure SetAmmoReinforcement(var s: shortstring); procedure AssignStores; procedure AddAmmo(var Hedgehog: THedgehog; ammo: TAmmoType); -procedure AddAmmo(var Hedgehog: THedgehog; ammo: TAmmoType; cnt: LongWord); +procedure SetAmmo(var Hedgehog: THedgehog; ammo: TAmmoType; cnt: LongWord); function HHHasAmmo(var Hedgehog: THedgehog; Ammo: TAmmoType): LongWord; procedure PackAmmo(Ammo: PHHAmmo; Slot: LongInt); procedure OnUsedAmmo(var Hedgehog: THedgehog); @@ -43,7 +43,7 @@ procedure DisableSomeWeapons; procedure ResetWeapons; function GetAmmoByNum(num: Longword): PHHAmmo; -function GetAmmoEntry(var Hedgehog: THedgehog): PAmmo; +function GetCurAmmoEntry(var Hedgehog: THedgehog): PAmmo; function GetAmmoEntry(var Hedgehog: THedgehog; am: TAmmoType): PAmmo; var StoreCnt: Longword; @@ -145,13 +145,13 @@ function GetAmmoByNum(num: Longword): PHHAmmo; begin -TryDo(num < StoreCnt, 'Invalid store number', true); -exit(StoresList[num]) + TryDo(num < StoreCnt, 'Invalid store number', true); + GetAmmoByNum:= StoresList[num] end; -function GetAmmoEntry(var Hedgehog: THedgehog): PAmmo; +function GetCurAmmoEntry(var Hedgehog: THedgehog): PAmmo; begin -GetAmmoEntry:= GetAmmoEntry(Hedgehog, Hedgehog.CurAmmoType) + GetCurAmmoEntry:= GetAmmoEntry(Hedgehog, Hedgehog.CurAmmoType) end; function GetAmmoEntry(var Hedgehog: THedgehog; am: TAmmoType): PAmmo; @@ -200,11 +200,11 @@ if (cnt <> AMMO_INFINITE) then begin inc(cnt, Ammoz[ammo].NumberInCase); - AddAmmo(Hedgehog, ammo, cnt) + SetAmmo(Hedgehog, ammo, cnt) end end; -procedure AddAmmo(var Hedgehog: THedgehog; ammo: TAmmoType; cnt: LongWord); +procedure SetAmmo(var Hedgehog: THedgehog; ammo: TAmmoType; cnt: LongWord); var ammos: TAmmoCounts; slot, ami: LongInt; hhammo: PHHAmmo; @@ -224,7 +224,7 @@ if ammos[ammo] > AMMO_INFINITE then ammos[ammo]:= AMMO_INFINITE; FillAmmoStore(hhammo, ammos); -CurWeapon:= GetAmmoEntry(Hedgehog); +CurWeapon:= GetCurAmmoEntry(Hedgehog); with Hedgehog, CurWeapon^ do if (Count = 0) or (AmmoType = amNothing) then begin @@ -258,7 +258,7 @@ procedure OnUsedAmmo(var Hedgehog: THedgehog); var CurWeapon: PAmmo; begin -CurWeapon:= GetAmmoEntry(Hedgehog); +CurWeapon:= GetCurAmmoEntry(Hedgehog); with Hedgehog do begin @@ -280,18 +280,21 @@ function HHHasAmmo(var Hedgehog: THedgehog; Ammo: TAmmoType): LongWord; var slot, ami: LongInt; begin -Slot:= Ammoz[Ammo].Slot; -ami:= 0; -while (ami <= cMaxSlotAmmoIndex) do - begin + HHHasAmmo:= 0; + Slot:= Ammoz[Ammo].Slot; + ami:= 0; + while (ami <= cMaxSlotAmmoIndex) do + begin with Hedgehog.Ammo^[Slot, ami] do if (AmmoType = Ammo) then if Hedgehog.Team^.Clan^.TurnNumber > Ammoz[AmmoType].SkipTurns then - exit(Count) - else exit(0); - inc(ami) - end; -HHHasAmmo:= 0 + begin + HHHasAmmo:= Count; + exit; + end + else exit; + inc(ami) + end; end; procedure ApplyAngleBounds(var Hedgehog: THedgehog; AmmoType: TAmmoType); @@ -352,14 +355,14 @@ begin Timer:= 10; - CurWeapon:= GetAmmoEntry(Hedgehog); + CurWeapon:= GetCurAmmoEntry(Hedgehog); if (CurWeapon^.Count = 0) then SwitchToFirstLegalAmmo(Hedgehog) else if CurWeapon^.AmmoType = amNothing then Hedgehog.CurAmmoType:= amNothing; - CurWeapon:= GetAmmoEntry(Hedgehog); + CurWeapon:= GetCurAmmoEntry(Hedgehog); ApplyAngleBounds(Hedgehog, CurWeapon^.AmmoType); @@ -421,22 +424,22 @@ Ammoz[t].Probability:= 0 end; -procedure SetAmmoLoadout(s: shortstring); +procedure SetAmmoLoadout(var s: shortstring); begin ammoLoadout:= s; end; -procedure SetAmmoProbability(s: shortstring); +procedure SetAmmoProbability(var s: shortstring); begin ammoProbability:= s; end; -procedure SetAmmoDelay(s: shortstring); +procedure SetAmmoDelay(var s: shortstring); begin ammoDelay:= s; end; -procedure SetAmmoReinforcement(s: shortstring); +procedure SetAmmoReinforcement(var s: shortstring); begin ammoReinforcement:= s; end; @@ -470,11 +473,11 @@ procedure initModule; var i: Longword; begin - RegisterVariable('ammloadt', vtCommand, @SetAmmoLoadout, false); - RegisterVariable('ammdelay', vtCommand, @SetAmmoDelay, false); - RegisterVariable('ammprob', vtCommand, @SetAmmoProbability, false); - RegisterVariable('ammreinf', vtCommand, @SetAmmoReinforcement, false); - RegisterVariable('ammstore', vtCommand, @chAddAmmoStore , false); + RegisterVariable('ammloadt', @SetAmmoLoadout, false); + RegisterVariable('ammdelay', @SetAmmoDelay, false); + RegisterVariable('ammprob', @SetAmmoProbability, false); + RegisterVariable('ammreinf', @SetAmmoReinforcement, false); + RegisterVariable('ammstore', @chAddAmmoStore , false); StoreCnt:= 0; ammoLoadout:= ''; diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uCaptions.pas --- a/hedgewars/uCaptions.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uCaptions.pas Wed May 02 23:53:45 2012 +0200 @@ -90,7 +90,7 @@ with Captions[grp] do if Tex <> nil then begin - DrawCentered(0, offset, Tex); + DrawTextureCentered(0, offset, Tex); inc(offset, Tex^.h + 2); if EndTime <= RealTicks then begin diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uChat.pas --- a/hedgewars/uChat.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uChat.pas Wed May 02 23:53:45 2012 +0200 @@ -31,7 +31,7 @@ procedure KeyPressChat(Key: Longword); implementation -uses SDLh, uKeys, uTypes, uVariables, uCommands, uUtils, uTextures, uRender, uIO; +uses SDLh, uInputHandler, uTypes, uVariables, uCommands, uUtils, uTextures, uRender, uIO; const MaxStrIndex = 27; @@ -52,7 +52,8 @@ ChatReady: boolean; showAll: boolean; -const colors: array[#1..#6] of TSDL_Color = ( +const colors: array[#0..#6] of TSDL_Color = ( + (r:$FF; g:$FF; b:$FF; unused:$FF), // unused, feel free to take it for anything (r:$FF; g:$FF; b:$FF; unused:$FF), // chat message [White] (r:$FF; g:$00; b:$FF; unused:$FF), // action message [Purple] (r:$90; g:$FF; b:$90; unused:$FF), // join/leave message [Lime] @@ -272,7 +273,7 @@ end; procedure KeyPressChat(Key: Longword); -const firstByteMark: array[1..4] of byte = (0, $C0, $E0, $F0); +const firstByteMark: array[0..3] of byte = (0, $C0, $E0, $F0); var i, btw: integer; utf8: shortstring; begin @@ -322,7 +323,7 @@ Key:= Key shr 6 end; - utf8:= char(Key or firstByteMark[btw]) + utf8; + utf8:= char(Key or firstByteMark[Pred(btw)]) + utf8; if byte(InputStr.s[0]) + btw > 240 then exit; @@ -361,7 +362,7 @@ procedure chHistory(var s: shortstring); begin s:= s; // avoid compiler hint - uChat.showAll:= not uChat.showAll + showAll:= not showAll end; procedure chChat(var s: shortstring); @@ -387,11 +388,11 @@ procedure initModule; var i: ShortInt; begin - RegisterVariable('chatmsg', vtCommand, @chChatMessage, true); - RegisterVariable('say', vtCommand, @chSay, true); - RegisterVariable('team', vtCommand, @chTeamSay, true); - RegisterVariable('history', vtCommand, @chHistory, true ); - RegisterVariable('chat', vtCommand, @chChat, true ); + RegisterVariable('chatmsg', @chChatMessage, true); + RegisterVariable('say', @chSay, true); + RegisterVariable('team', @chTeamSay, true); + RegisterVariable('history', @chHistory, true ); + RegisterVariable('chat', @chChat, true ); lastStr:= 0; visibleCount:= 0; diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uCollisions.pas --- a/hedgewars/uCollisions.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uCollisions.pas Wed May 02 23:53:45 2012 +0200 @@ -47,8 +47,10 @@ function TestCollisionX(Gear: PGear; Dir: LongInt): boolean; function TestCollisionY(Gear: PGear; Dir: LongInt): boolean; -function TestCollisionXwithXYShift(Gear: PGear; ShiftX: hwFloat; ShiftY: LongInt; Dir: LongInt; withGear: boolean = true): boolean; -function TestCollisionYwithXYShift(Gear: PGear; ShiftX, ShiftY: LongInt; Dir: LongInt; withGear: boolean = true): boolean; +function TestCollisionXwithXYShift(Gear: PGear; ShiftX: hwFloat; ShiftY: LongInt; Dir: LongInt): boolean; inline; +function TestCollisionXwithXYShift(Gear: PGear; ShiftX: hwFloat; ShiftY: LongInt; Dir: LongInt; withGear: boolean): boolean; +function TestCollisionYwithXYShift(Gear: PGear; ShiftX, ShiftY: LongInt; Dir: LongInt): boolean; inline; +function TestCollisionYwithXYShift(Gear: PGear; ShiftX, ShiftY: LongInt; Dir: LongInt; withGear: boolean): boolean; function TestRectancleForObstacle(x1, y1, x2, y2: LongInt; landOnly: boolean): boolean; @@ -57,7 +59,7 @@ function CalcSlopeTangent(Gear: PGear; collisionX, collisionY: LongInt; var outDeltaX, outDeltaY: LongInt; TestWord: LongWord): Boolean; implementation -uses uConsts, uLandGraphics, uVariables, uDebug, uGears, uGearsList; +uses uConsts, uLandGraphics, uVariables, uDebug, uGearsList; type TCollisionEntry = record X, Y, Radius: LongInt; @@ -153,6 +155,8 @@ x:= x - Gear^.Radius else x:= x + Gear^.Radius; + +TestCollisionXwithGear:= true; if (x and LAND_WIDTH_MASK) = 0 then begin y:= hwRound(Gear^.Y) - Gear^.Radius + 1; @@ -160,7 +164,7 @@ repeat if (y and LAND_HEIGHT_MASK) = 0 then if Land[y, x] > TestWord then - exit(true); + exit; inc(y) until (y > i); end; @@ -196,7 +200,10 @@ repeat if (x and LAND_WIDTH_MASK) = 0 then if Land[y, x] > TestWord then - exit(Land[y, x]); + begin + TestCollisionYwithGear:= Land[y, x]; + exit; + end; inc(x) until (x > i); end; @@ -213,6 +220,8 @@ x:= x - Gear^.Radius else x:= x + Gear^.Radius; + +TestCollisionXKick:= true; if (x and LAND_WIDTH_MASK) = 0 then begin y:= hwRound(Gear^.Y) - Gear^.Radius + 1; @@ -220,7 +229,7 @@ repeat if (y and LAND_HEIGHT_MASK) = 0 then if Land[y, x] > 255 then - exit(true) + exit else if Land[y, x] <> 0 then flag:= true; inc(y) @@ -255,7 +264,8 @@ Active:= true end; DeleteCI(cGear); - exit(false) + TestCollisionXKick:= false; + exit; end end end; @@ -270,6 +280,8 @@ y:= y - Gear^.Radius else y:= y + Gear^.Radius; + +TestCollisionYKick:= true; if (y and LAND_HEIGHT_MASK) = 0 then begin x:= hwRound(Gear^.X) - Gear^.Radius + 1; @@ -278,7 +290,7 @@ if (x and LAND_WIDTH_MASK) = 0 then if Land[y, x] > 0 then if Land[y, x] > 255 then - exit(true) + exit else if Land[y, x] <> 0 then flag:= true; inc(x) @@ -289,10 +301,8 @@ if flag then begin if hwAbs(Gear^.dY) < cHHKick then - exit(true); - if (Gear^.State and gstHHJumping <> 0) - and (not Gear^.dY.isNegative) - and (Gear^.dY < _0_4) then + exit; + if (Gear^.State and gstHHJumping <> 0) and (not Gear^.dY.isNegative) and (Gear^.dY < _0_4) then exit; mx:= hwRound(Gear^.X); @@ -313,12 +323,18 @@ Active:= true end; DeleteCI(cGear); - exit(false) + TestCollisionYKick:= false; + exit end end end; -function TestCollisionXwithXYShift(Gear: PGear; ShiftX: hwFloat; ShiftY: LongInt; Dir: LongInt; withGear: boolean = true): boolean; +function TestCollisionXwithXYShift(Gear: PGear; ShiftX: hwFloat; ShiftY: LongInt; Dir: LongInt): boolean; inline; +begin + TestCollisionXwithXYShift:= TestCollisionXwithXYShift(Gear, ShiftX, ShiftY, Dir, true); +end; + +function TestCollisionXwithXYShift(Gear: PGear; ShiftX: hwFloat; ShiftY: LongInt; Dir: LongInt; withGear: boolean): boolean; begin Gear^.X:= Gear^.X + ShiftX; Gear^.Y:= Gear^.Y + int2hwFloat(ShiftY); @@ -328,6 +344,7 @@ Gear^.X:= Gear^.X - ShiftX; Gear^.Y:= Gear^.Y - int2hwFloat(ShiftY) end; + function TestCollisionX(Gear: PGear; Dir: LongInt): boolean; var x, y, i: LongInt; begin @@ -336,6 +353,8 @@ x:= x - Gear^.Radius else x:= x + Gear^.Radius; + +TestCollisionX:= true; if (x and LAND_WIDTH_MASK) = 0 then begin y:= hwRound(Gear^.Y) - Gear^.Radius + 1; @@ -343,7 +362,7 @@ repeat if (y and LAND_HEIGHT_MASK) = 0 then if Land[y, x] > 255 then - exit(true); + exit; inc(y) until (y > i); end; @@ -358,6 +377,8 @@ y:= y - Gear^.Radius else y:= y + Gear^.Radius; + +TestCollisionY:= true; if (y and LAND_HEIGHT_MASK) = 0 then begin x:= hwRound(Gear^.X) - Gear^.Radius + 1; @@ -365,14 +386,19 @@ repeat if (x and LAND_WIDTH_MASK) = 0 then if Land[y, x] > 255 then - exit(true); + exit; inc(x) until (x > i); end; TestCollisionY:= false end; -function TestCollisionYwithXYShift(Gear: PGear; ShiftX, ShiftY: LongInt; Dir: LongInt; withGear: boolean = true): boolean; +function TestCollisionYwithXYShift(Gear: PGear; ShiftX, ShiftY: LongInt; Dir: LongInt): boolean; inline; +begin + TestCollisionYwithXYShift:= TestCollisionYwithXYShift(Gear, ShiftX, ShiftY, Dir, true); +end; + +function TestCollisionYwithXYShift(Gear: PGear; ShiftX, ShiftY: LongInt; Dir: LongInt; withGear: boolean): boolean; begin Gear^.X:= Gear^.X + int2hwFloat(ShiftX); Gear^.Y:= Gear^.Y + int2hwFloat(ShiftY); @@ -390,33 +416,34 @@ var x, y: LongInt; TestWord: LongWord; begin +TestRectancleForObstacle:= true; + if landOnly then TestWord:= 255 else TestWord:= 0; if x1 > x2 then - begin +begin x := x1; x1 := x2; x2 := x; - end; +end; if y1 > y2 then - begin +begin y := y1; y1 := y2; y2 := y; - end; +end; if (hasBorder and ((y1 < 0) or (x1 < 0) or (x2 > LAND_WIDTH))) then - exit(true); + exit; for y := y1 to y2 do for x := x1 to x2 do - if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) - and (Land[y, x] > TestWord) then - exit(true); + if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) and (Land[y, x] > TestWord) then + exit; TestRectancleForObstacle:= false end; @@ -430,6 +457,8 @@ isColl: Boolean; begin + CalcSlopeTangent:= false; + dx:= Gear^.dX; dy:= Gear^.dY; @@ -554,11 +583,11 @@ ldy:= rdy - ldy; if ((ldx = 0) and (ldy = 0)) then - EXIT(false); + exit; outDeltaX:= ldx; outDeltaY:= ldy; -exit(true); +CalcSlopeTangent:= true; end; function CalcSlopeBelowGear(Gear: PGear): hwFloat; diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uCommandHandlers.pas --- a/hedgewars/uCommandHandlers.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uCommandHandlers.pas Wed May 02 23:53:45 2012 +0200 @@ -41,7 +41,6 @@ end; procedure chQuit(var s: shortstring); -const prevGState: TGameState = gsConfirm; begin s:= s; // avoid compiler hint if (GameState = gsGame) or (GameState = gsChat) then @@ -659,90 +658,191 @@ ZoomValue:= cDefaultZoomLevel; end; +procedure chMapGen(var s: shortstring); +begin +val(s, cMapGen) +end; + +procedure chTemplateFilter(var s: shortstring); +begin +val(s, cTemplateFilter) +end; + +procedure chInactDelay(var s: shortstring); +begin +val(s, cInactDelay) +end; + +procedure chReadyDelay(var s: shortstring); +begin +val(s, cReadyDelay) +end; + +procedure chCaseFactor(var s: shortstring); +begin +val(s, cCaseFactor) +end; + +procedure chHealthCaseProb(var s: shortstring); +begin +val(s, cHealthCaseProb) +end; + +procedure chHealthCaseAmount(var s: shortstring); +begin +val(s, cHealthCaseAmount) +end; + +procedure chSuddenDTurns(var s: shortstring); +begin +val(s, cSuddenDTurns) +end; + +procedure chWaterRise(var s: shortstring); +begin +val(s, cWaterRise) +end; + +procedure chHealthDecrease(var s: shortstring); +begin +val(s, cHealthDecrease) +end; + +procedure chDamagePercent(var s: shortstring); +begin +val(s, cDamagePercent) +end; + +procedure chRopePercent(var s: shortstring); +begin +val(s, cRopePercent) +end; + +procedure chGetAwayTime(var s: shortstring); +begin +val(s, cGetAwayTime) +end; + +procedure chMineDudPercent(var s: shortstring); +begin +val(s, cMineDudPercent) +end; + +procedure chLandMines(var s: shortstring); +begin +val(s, cLandMines) +end; + +procedure chExplosives(var s: shortstring); +begin +val(s, cExplosives) +end; + +procedure chGameFlags(var s: shortstring); +begin +val(s, GameFlags) +end; + +procedure chHedgehogTurnTime(var s: shortstring); +begin +val(s, cHedgehogTurnTime) +end; + +procedure chMinesTime(var s: shortstring); +begin +val(s, cMinesTime) +end; + +procedure chFastUntilLag(var s: shortstring); +var i: LongInt; +begin +val(s, i); +fastUntilLag:= i <> 0 +end; procedure initModule; begin //////// Begin top sorted by freq analysis not including chatmsg - RegisterVariable('+right' , vtCommand, @chRight_p , false); - RegisterVariable('-right' , vtCommand, @chRight_m , false); - RegisterVariable('+up' , vtCommand, @chUp_p , false); - RegisterVariable('-up' , vtCommand, @chUp_m , false); - RegisterVariable('+left' , vtCommand, @chLeft_p , false); - RegisterVariable('-left' , vtCommand, @chLeft_m , false); - RegisterVariable('+attack' , vtCommand, @chAttack_p , false); - RegisterVariable('+down' , vtCommand, @chDown_p , false); - RegisterVariable('-down' , vtCommand, @chDown_m , false); - RegisterVariable('hjump' , vtCommand, @chHJump , false); - RegisterVariable('ljump' , vtCommand, @chLJump , false); - RegisterVariable('nextturn', vtCommand, @chNextTurn , false); - RegisterVariable('-attack' , vtCommand, @chAttack_m , false); - RegisterVariable('slot' , vtCommand, @chSlot , false); - RegisterVariable('setweap' , vtCommand, @chSetWeapon , false); + RegisterVariable('+right' , @chRight_p , false); + RegisterVariable('-right' , @chRight_m , false); + RegisterVariable('+up' , @chUp_p , false); + RegisterVariable('-up' , @chUp_m , false); + RegisterVariable('+left' , @chLeft_p , false); + RegisterVariable('-left' , @chLeft_m , false); + RegisterVariable('+attack' , @chAttack_p , false); + RegisterVariable('+down' , @chDown_p , false); + RegisterVariable('-down' , @chDown_m , false); + RegisterVariable('hjump' , @chHJump , false); + RegisterVariable('ljump' , @chLJump , false); + RegisterVariable('nextturn', @chNextTurn , false); + RegisterVariable('-attack' , @chAttack_m , false); + RegisterVariable('slot' , @chSlot , false); + RegisterVariable('setweap' , @chSetWeapon , false); //////// End top by freq analysis - RegisterVariable('gencmd' , vtCommand, @chGenCmd , false); - RegisterVariable('flag' , vtCommand, @chFlag , false); - RegisterVariable('script' , vtCommand, @chScript , false); - RegisterVariable('proto' , vtCommand, @chCheckProto , true ); - RegisterVariable('spectate', vtBoolean, @fastUntilLag , false); - RegisterVariable('capture' , vtCommand, @chCapture , true ); - RegisterVariable('rotmask' , vtCommand, @chRotateMask , true ); - RegisterVariable('rdriven' , vtCommand, @chTeamLocal , false); - RegisterVariable('map' , vtCommand, @chSetMap , false); - RegisterVariable('theme' , vtCommand, @chSetTheme , false); - RegisterVariable('seed' , vtCommand, @chSetSeed , false); - RegisterVariable('template_filter', vtLongInt, @cTemplateFilter, false); - RegisterVariable('mapgen' , vtLongInt, @cMapGen , false); - RegisterVariable('maze_size',vtLongInt, @cTemplateFilter, false); - RegisterVariable('delay' , vtLongInt, @cInactDelay , false); - RegisterVariable('ready' , vtLongInt, @cReadyDelay , false); - RegisterVariable('casefreq', vtLongInt, @cCaseFactor , false); - RegisterVariable('healthprob', vtLongInt, @cHealthCaseProb, false); - RegisterVariable('hcaseamount', vtLongInt, @cHealthCaseAmount, false); - RegisterVariable('sd_turns', vtLongInt, @cSuddenDTurns , false); - RegisterVariable('waterrise', vtLongInt, @cWaterRise , false); - RegisterVariable('healthdec', vtLongInt, @cHealthDecrease, false); - RegisterVariable('damagepct',vtLongInt, @cDamagePercent , false); - RegisterVariable('ropepct' , vtLongInt, @cRopePercent , false); - RegisterVariable('getawaytime' , vtLongInt, @cGetAwayTime , false); - RegisterVariable('minedudpct',vtLongInt,@cMineDudPercent, false); - RegisterVariable('minesnum', vtLongInt, @cLandMines , false); - RegisterVariable('explosives',vtLongInt,@cExplosives , false); - RegisterVariable('gmflags' , vtLongInt, @GameFlags , false); - RegisterVariable('turntime', vtLongInt, @cHedgehogTurnTime, false); - RegisterVariable('minestime',vtLongInt, @cMinesTime , false); - RegisterVariable('fort' , vtCommand, @chFort , false); - RegisterVariable('grave' , vtCommand, @chGrave , false); - RegisterVariable('hat' , vtCommand, @chSetHat , false); - RegisterVariable('quit' , vtCommand, @chQuit , true ); - RegisterVariable('forcequit', vtCommand, @chForceQuit , true ); - RegisterVariable('confirm' , vtCommand, @chConfirm , true ); - RegisterVariable('halt', vtCommand, @chHalt , true ); - RegisterVariable('+speedup', vtCommand, @chSpeedup_p , true ); - RegisterVariable('-speedup', vtCommand, @chSpeedup_m , true ); - RegisterVariable('zoomin' , vtCommand, @chZoomIn , true ); - RegisterVariable('zoomout' , vtCommand, @chZoomOut , true ); - RegisterVariable('zoomreset',vtCommand, @chZoomReset , true ); - RegisterVariable('ammomenu', vtCommand, @chAmmoMenu , true); - RegisterVariable('+precise', vtCommand, @chPrecise_p , false); - RegisterVariable('-precise', vtCommand, @chPrecise_m , false); - RegisterVariable('switch' , vtCommand, @chSwitch , false); - RegisterVariable('timer' , vtCommand, @chTimer , false); - RegisterVariable('taunt' , vtCommand, @chTaunt , false); - RegisterVariable('put' , vtCommand, @chPut , false); - RegisterVariable('+volup' , vtCommand, @chVol_p , true ); - RegisterVariable('-volup' , vtCommand, @chVol_m , true ); - RegisterVariable('+voldown', vtCommand, @chVol_m , true ); - RegisterVariable('-voldown', vtCommand, @chVol_p , true ); - RegisterVariable('findhh' , vtCommand, @chFindhh , true ); - RegisterVariable('pause' , vtCommand, @chPause , true ); - RegisterVariable('+cur_u' , vtCommand, @chCurU_p , true ); - RegisterVariable('-cur_u' , vtCommand, @chCurU_m , true ); - RegisterVariable('+cur_d' , vtCommand, @chCurD_p , true ); - RegisterVariable('-cur_d' , vtCommand, @chCurD_m , true ); - RegisterVariable('+cur_l' , vtCommand, @chCurL_p , true ); - RegisterVariable('-cur_l' , vtCommand, @chCurL_m , true ); - RegisterVariable('+cur_r' , vtCommand, @chCurR_p , true ); - RegisterVariable('-cur_r' , vtCommand, @chCurR_m , true ); + RegisterVariable('gencmd' , @chGenCmd , false); + RegisterVariable('flag' , @chFlag , false); + RegisterVariable('script' , @chScript , false); + RegisterVariable('proto' , @chCheckProto , true ); + RegisterVariable('spectate', @chFastUntilLag , false); + RegisterVariable('capture' , @chCapture , true ); + RegisterVariable('rotmask' , @chRotateMask , true ); + RegisterVariable('rdriven' , @chTeamLocal , false); + RegisterVariable('map' , @chSetMap , false); + RegisterVariable('theme' , @chSetTheme , false); + RegisterVariable('seed' , @chSetSeed , false); + RegisterVariable('template_filter', @chTemplateFilter, false); + RegisterVariable('mapgen' , @chMapGen , false); + RegisterVariable('maze_size',@chTemplateFilter, false); + RegisterVariable('delay' , @chInactDelay , false); + RegisterVariable('ready' , @chReadyDelay , false); + RegisterVariable('casefreq', @chCaseFactor , false); + RegisterVariable('healthprob', @chHealthCaseProb, false); + RegisterVariable('hcaseamount', @chHealthCaseAmount, false); + RegisterVariable('sd_turns', @chSuddenDTurns , false); + RegisterVariable('waterrise', @chWaterRise , false); + RegisterVariable('healthdec', @chHealthDecrease, false); + RegisterVariable('damagepct',@chDamagePercent , false); + RegisterVariable('ropepct' , @chRopePercent , false); + RegisterVariable('getawaytime' , @chGetAwayTime , false); + RegisterVariable('minedudpct',@chMineDudPercent, false); + RegisterVariable('minesnum', @chLandMines , false); + RegisterVariable('explosives',@chExplosives , false); + RegisterVariable('gmflags' , @chGameFlags , false); + RegisterVariable('turntime', @chHedgehogTurnTime, false); + RegisterVariable('minestime',@chMinesTime , false); + RegisterVariable('fort' , @chFort , false); + RegisterVariable('grave' , @chGrave , false); + RegisterVariable('hat' , @chSetHat , false); + RegisterVariable('quit' , @chQuit , true ); + RegisterVariable('forcequit', @chForceQuit , true ); + RegisterVariable('confirm' , @chConfirm , true ); + RegisterVariable('halt', @chHalt , true ); + RegisterVariable('+speedup', @chSpeedup_p , true ); + RegisterVariable('-speedup', @chSpeedup_m , true ); + RegisterVariable('zoomin' , @chZoomIn , true ); + RegisterVariable('zoomout' , @chZoomOut , true ); + RegisterVariable('zoomreset',@chZoomReset , true ); + RegisterVariable('ammomenu', @chAmmoMenu , true); + RegisterVariable('+precise', @chPrecise_p , false); + RegisterVariable('-precise', @chPrecise_m , false); + RegisterVariable('switch' , @chSwitch , false); + RegisterVariable('timer' , @chTimer , false); + RegisterVariable('taunt' , @chTaunt , false); + RegisterVariable('put' , @chPut , false); + RegisterVariable('+volup' , @chVol_p , true ); + RegisterVariable('-volup' , @chVol_m , true ); + RegisterVariable('+voldown', @chVol_m , true ); + RegisterVariable('-voldown', @chVol_p , true ); + RegisterVariable('findhh' , @chFindhh , true ); + RegisterVariable('pause' , @chPause , true ); + RegisterVariable('+cur_u' , @chCurU_p , true ); + RegisterVariable('-cur_u' , @chCurU_m , true ); + RegisterVariable('+cur_d' , @chCurD_p , true ); + RegisterVariable('-cur_d' , @chCurD_m , true ); + RegisterVariable('+cur_l' , @chCurL_p , true ); + RegisterVariable('-cur_l' , @chCurL_m , true ); + RegisterVariable('+cur_r' , @chCurR_p , true ); + RegisterVariable('-cur_r' , @chCurR_m , true ); end; procedure freeModule; diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uCommands.pas --- a/hedgewars/uCommands.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uCommands.pas Wed May 02 23:53:45 2012 +0200 @@ -23,31 +23,30 @@ interface var isDeveloperMode: boolean; -type TVariableType = (vtCommand, vtLongInt, vtBoolean); - TCommandHandler = procedure (var params: shortstring); +type TCommandHandler = procedure (var params: shortstring); procedure initModule; procedure freeModule; -procedure RegisterVariable(Name: shortstring; VType: TVariableType; p: pointer; Trusted: boolean); +procedure RegisterVariable(Name: shortstring; p: TCommandHandler; Trusted: boolean); procedure ParseCommand(CmdStr: shortstring; TrustedSource: boolean); +procedure ParseTeamCommand(s: shortstring); procedure StopMessages(Message: Longword); implementation -uses Types, uConsts, uVariables, uConsole, uUtils, uDebug; +uses uConsts, uVariables, uConsole, uUtils, uDebug; type PVariable = ^TVariable; TVariable = record Next: PVariable; Name: string[15]; - VType: TVariableType; - Handler: pointer; + Handler: TCommandHandler; Trusted: boolean; end; var Variables: PVariable; -procedure RegisterVariable(Name: shortstring; VType: TVariableType; p: pointer; Trusted: boolean); +procedure RegisterVariable(Name: shortstring; p: TCommandHandler; Trusted: boolean); var value: PVariable; begin @@ -55,7 +54,6 @@ TryDo(value <> nil, 'RegisterVariable: value = nil', true); FillChar(value^, sizeof(TVariable), 0); value^.Name:= Name; -value^.VType:= VType; value^.Handler:= p; value^.Trusted:= Trusted; @@ -70,8 +68,7 @@ procedure ParseCommand(CmdStr: shortstring; TrustedSource: boolean); -var ii: LongInt; - s: shortstring; +var s: shortstring; t: PVariable; c: char; begin @@ -80,54 +77,40 @@ exit; c:= CmdStr[1]; if (c = '/') or (c = '$') then - Delete(CmdStr, 1, 1) -else - c:= '/'; + Delete(CmdStr, 1, 1); s:= ''; SplitBySpace(CmdStr, s); -AddFileLog('[Cmd] ' + c + CmdStr + ' (' + inttostr(length(s)) + ')'); +AddFileLog('[Cmd] ' + CmdStr + ' (' + inttostr(length(s)) + ')'); t:= Variables; while t <> nil do begin if t^.Name = CmdStr then begin if TrustedSource or t^.Trusted then - case t^.VType of - vtCommand: if c='/' then - begin - TCommandHandler(t^.Handler)(s); - end; - vtLongInt: if c='$' then - if s[0]=#0 then - begin - str(PLongInt(t^.Handler)^, s); - WriteLnToConsole('$' + CmdStr + ' is "' + s + '"'); - end - else - val(s, PLongInt(t^.Handler)^); - vtBoolean: if c='$' then - if s[0]=#0 then - begin - str(ord(boolean(t^.Handler^)), s); - WriteLnToConsole('$' + CmdStr + ' is "' + s + '"'); - end - else - begin - val(s, ii); - boolean(t^.Handler^):= not (ii = 0) - end; - end; - exit - end - else - t:= t^.Next - end; + t^.Handler(s); + exit + end + else + t:= t^.Next + end; case c of '$': WriteLnToConsole(errmsgUnknownVariable + ': "$' + CmdStr + '"') else WriteLnToConsole(errmsgUnknownCommand + ': "/' + CmdStr + '"') end end; +procedure ParseTeamCommand(s: shortstring); +var Trusted: boolean; +begin +Trusted:= (CurrentTeam <> nil) + and (not CurrentTeam^.ExtDriven) + and (CurrentHedgehog^.BotLevel = 0); +ParseCommand(s, Trusted); +if (CurrentTeam <> nil) and (not CurrentTeam^.ExtDriven) and (ReadyTimeLeft > 1) then + ParseCommand('gencmd R', true) +end; + + procedure StopMessages(Message: Longword); begin diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uConsole.pas --- a/hedgewars/uConsole.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uConsole.pas Wed May 02 23:53:45 2012 +0200 @@ -31,8 +31,8 @@ implementation uses Types, uVariables, uUtils {$IFDEF ANDROID}, log in 'log.pas'{$ENDIF}; -const cLineWidth: LongInt = 0; - cLinesCount = 8; +const cLinesCount = 8; +var cLineWidth: LongInt; type TTextLine = record @@ -97,7 +97,7 @@ if Length(s) = High(s) then Dec(s[0]); s[Ord(Length(s))+1] := #0; - exit(@s[1]); + ShortStringAsPChar:= @s[1]; end; function GetLastConsoleLine: shortstring; diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uConsts.pas --- a/hedgewars/uConsts.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uConsts.pas Wed May 02 23:53:45 2012 +0200 @@ -51,7 +51,6 @@ cWhiteColor : Longword = $FFFFFFFF; cYellowColor : Longword = $FFFFFF00; cNearBlackColor : Longword = $FF000010; - cExplosionBorderColor : LongWord = $FF808080; {$WARNINGS OFF} cAirPlaneSpeed: hwFloat = (isNegative: false; QWordValue: 3006477107); // 1.4 @@ -103,18 +102,18 @@ MAXNAMELEN = 192; MAXROPEPOINTS = 3840; + {$IFNDEF PAS2C} // some opengl headers do not have these macros GL_BGR = $80E0; GL_BGRA = $80E1; GL_CLAMP_TO_EDGE = $812F; GL_TEXTURE_PRIORITY = $8066; + {$ENDIF} cSendCursorPosTime : LongWord = 50; cVisibleWater : LongInt = 128; cCursorEdgesDist : LongInt = 100; cTeamHealthWidth : LongInt = 128; - cWaterOpacity : byte = $80; - cSDWaterOpacity : byte = $80; cifRandomize = $00000001; cifTheme = $00000002; @@ -122,16 +121,10 @@ cifAllInited = cifRandomize or cifTheme or cifMap; cTransparentColor: Longword = $00000000; - cGrayScale: Boolean = false; RGB_LUMINANCE_RED = 0.212671; RGB_LUMINANCE_GREEN = 0.715160; RGB_LUMINANCE_BLUE = 0.072169; -(* - RGB_LUMINANCE_RED = 0.3333333333; - RGB_LUMINANCE_GREEN = 0.3333333333; - RGB_LUMINANCE_BLUE = 0.3333333333; -*) cMaxTeams = 8; cMaxHHIndex = 7; @@ -155,6 +148,12 @@ cKeyMaxIndex = 1023; + cHHFileName = 'Hedgehog'; + cCHFileName = 'Crosshair'; + cThemeCFGFilename = 'theme.cfg'; + + cFontBorder = 2; + // do not change this value cDefaultZoomLevel = 2.0; @@ -259,6 +258,7 @@ ammoprop_Utility = $00001000; ammoprop_Effect = $00002000; ammoprop_SetBounce = $00004000; + ammoprop_NeedUpDown = $00008000;//Used by TouchInterface to show or hide up/down widgets ammoprop_NoRoundEnd = $10000000; AMMO_INFINITE = 100; @@ -312,6 +312,10 @@ FADE_ANIM_TIME = 500; MOVE_ANIM_TIME = 500; {$ENDIF} + + cTagsMasks : array[0..15] of byte = (7, 0, 0, 0, 15, 6, 4, 5, 0, 0, 0, 0, 0, 14, 12, 13); + cTagsMasksNoHealth: array[0..15] of byte = (3, 2, 11, 1, 0, 0, 0, 0, 0, 10, 0, 9, 0, 0, 0, 0); + implementation end. diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uFloat.pas --- a/hedgewars/uFloat.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uFloat.pas Wed May 02 23:53:45 2012 +0200 @@ -90,7 +90,7 @@ function AngleCos(const Angle: Longword): hwFloat; function SignAs(const num, signum: hwFloat): hwFloat; inline; // Returns an hwFloat with the value of parameter num and the sign of signum. function hwSign(r: hwFloat): LongInt; inline; // Returns an integer with value 1 and sign of parameter r. -function hwSign(r: real): LongInt; inline; // Returns an integer with value 1 and sign of parameter r. +function hwSignf(r: real): LongInt; inline; // Returns an integer with value 1 and sign of parameter r. function isZero(const z: hwFloat): boolean; inline; {$IFDEF FPC} {$J-} @@ -424,12 +424,12 @@ hwSign:= 1 end; -function hwSign(r: real): LongInt; +function hwSignf(r: real): LongInt; begin if r < 0 then - hwSign:= -1 + hwSignf:= -1 else - hwSign:= 1 + hwSignf:= 1 end; diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uGame.pas --- a/hedgewars/uGame.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uGame.pas Wed May 02 23:53:45 2012 +0200 @@ -26,7 +26,7 @@ //////////////////// implementation //////////////////// -uses uKeys, uTeams, uIO, uAI, uGears, uSound, uMobile, uVisualGears, uTypes, uVariables{$IFDEF SDL13}, uTouch{$ENDIF}; +uses uInputHandler, uTeams, uIO, uAI, uGears, uSound, uMobile, uVisualGears, uTypes, uVariables{$IFDEF SDL13}, uTouch{$ENDIF}; procedure DoGameTick(Lag: LongInt); var i: LongInt; diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uGears.pas --- a/hedgewars/uGears.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uGears.pas Wed May 02 23:53:45 2012 +0200 @@ -69,6 +69,14 @@ procedure ShotgunShot(Gear: PGear); forward; procedure doStepCase(Gear: PGear); forward; + +var delay: LongWord; + delay2: LongWord; + step: (stDelay, stChDmg, stSweep, stTurnReact, + stAfterDelay, stChWin, stWater, stChWin2, stHealth, + stSpawn, stNTurn); + upd: Longword; + // For better maintainability the step handlers of gears are stored in // separate files. // Note: step handlers of gears that are hedgehogs are in a different file @@ -172,11 +180,6 @@ end; procedure ProcessGears; -const delay: LongWord = 0; - delay2: LongWord = 0; - step: (stDelay, stChDmg, stSweep, stTurnReact, - stAfterDelay, stChWin, stWater, stChWin2, stHealth, - stSpawn, stNTurn) = stDelay; var Gear, t: PGear; i, AliveCount: LongInt; s: shortstring; @@ -996,6 +999,7 @@ var t, aTot: LongInt; i: TAmmoType; begin +Hedgehog:= Hedgehog; // avoid hint aTot:= 0; for i:= Low(TAmmoType) to High(TAmmoType) do @@ -1237,22 +1241,23 @@ procedure initModule; const handlers: array[TGearType] of TGearStepProcedure = ( + @doStepFlame, + @doStepHedgehog, + @doStepMine, + @doStepCase, + @doStepCase, @doStepBomb, - @doStepHedgehog, @doStepShell, @doStepGrave, @doStepBee, @doStepShotgunShot, @doStepPickHammer, @doStepRope, - @doStepMine, - @doStepCase, @doStepDEagleShot, @doStepDynamite, @doStepBomb, @doStepCluster, @doStepShover, - @doStepFlame, @doStepFirePunch, @doStepActionTimer, @doStepActionTimer, @@ -1280,7 +1285,6 @@ @doStepSniperRifleShot, @doStepJetpack, @doStepMolotov, - @doStepCase, @doStepBirdy, @doStepEggWork, @doStepPortalShot, @@ -1302,8 +1306,8 @@ begin doStepHandlers:= handlers; - RegisterVariable('skip', vtCommand, @chSkip, false); - RegisterVariable('hogsay', vtCommand, @chHogSay, true ); + RegisterVariable('skip', @chSkip, false); + RegisterVariable('hogsay', @chHogSay, true ); CurAmmoGear:= nil; GearsList:= nil; @@ -1315,6 +1319,12 @@ AllInactive:= false; PrvInactive:= false; + + //typed const + delay:= 0; + delay2:= 0; + step:= stDelay; + upd:= 0; end; procedure freeModule; diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uGearsHedgehog.pas --- a/hedgewars/uGearsHedgehog.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uGearsHedgehog.pas Wed May 02 23:53:45 2012 +0200 @@ -30,7 +30,7 @@ procedure PickUp(HH, Gear: PGear); implementation -uses uConsts, uVariables, uFloat, uAmmos, uSound, uCaptions, uMisc, +uses uConsts, uVariables, uFloat, uAmmos, uSound, uCaptions, uCommands, uLocale, uUtils, uVisualGears, uStats, uIO, uScript, uGearsList, uGears, uCollisions, uRandom, uStore, uTeams, uGearsUtils; @@ -131,7 +131,7 @@ color: LongWord; begin Gear^.Message:= Gear^.Message and (not gmTimer); -CurWeapon:= GetAmmoEntry(Gear^.Hedgehog^); +CurWeapon:= GetCurAmmoEntry(Gear^.Hedgehog^); with Gear^.Hedgehog^ do if ((Gear^.Message and gmPrecise) <> 0) and ((CurWeapon^.Propz and ammoprop_SetBounce) <> 0) then begin @@ -178,7 +178,7 @@ begin newGear:= nil; bShowFinger:= false; -CurWeapon:= GetAmmoEntry(Gear^.Hedgehog^); +CurWeapon:= GetCurAmmoEntry(Gear^.Hedgehog^); with Gear^, Gear^.Hedgehog^ do begin @@ -634,13 +634,11 @@ end end; -const StepTicks: LongWord = 0; - procedure HedgehogStep(Gear: PGear); var PrevdX: LongInt; CurWeapon: PAmmo; begin -CurWeapon:= GetAmmoEntry(Gear^.Hedgehog^); +CurWeapon:= GetCurAmmoEntry(Gear^.Hedgehog^); if ((Gear^.State and (gstAttacking or gstMoving)) = 0) then begin if isCursorVisible then diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uGearsList.pas --- a/hedgewars/uGearsList.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uGearsList.pas Wed May 02 23:53:45 2012 +0200 @@ -72,7 +72,6 @@ end; function AddGear(X, Y: LongInt; Kind: TGearType; State: Longword; dX, dY: hwFloat; Timer: LongWord): PGear; -const Counter: Longword = 0; var gear: PGear; begin inc(Counter); @@ -285,8 +284,8 @@ gear^.Density:= _1; if (gear^.dY.QWordValue = 0) and (gear^.dX.QWordValue = 0) then begin - gear^.dY:= (getrandom - _0_8) * _0_03; - gear^.dX:= (getrandom - _0_5) * _0_4 + gear^.dY:= (getrandomf - _0_8) * _0_03; + gear^.dX:= (getrandomf - _0_5) * _0_4 end end; gtFirePunch: begin @@ -502,7 +501,7 @@ begin t:= max(Gear^.Damage, Gear^.Health); Gear^.Damage:= t; - if ((not SuddenDeathDmg and (cWaterOpacity < $FF)) or (SuddenDeathDmg and (cWaterOpacity < $FF))) + if ((not SuddenDeathDmg and (WaterOpacity < $FF)) or (SuddenDeathDmg and (WaterOpacity < $FF))) and (hwRound(Gear^.Y) < cWaterLine + 256) then spawnHealthTagForHH(Gear, t); end; diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uGearsRender.pas --- a/hedgewars/uGearsRender.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uGearsRender.pas Wed May 02 23:53:45 2012 +0200 @@ -176,10 +176,10 @@ if RopePoints.Count > 0 then - DrawRotated(sprRopeHook, hwRound(RopePoints.ar[0].X) + WorldDx, hwRound(RopePoints.ar[0].Y) + WorldDy, 1, RopePoints.HookAngle) + DrawSpriteRotated(sprRopeHook, hwRound(RopePoints.ar[0].X) + WorldDx, hwRound(RopePoints.ar[0].Y) + WorldDy, 1, RopePoints.HookAngle) else if Gear^.Elasticity.QWordValue > 0 then - DrawRotated(sprRopeHook, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, 0, DxDy2Angle(Gear^.dY, Gear^.dX)); + DrawSpriteRotated(sprRopeHook, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, 0, DxDy2Angle(Gear^.dY, Gear^.dX)); end; @@ -224,7 +224,7 @@ end else if (Gear^.State and gstHHGone) <> 0 then begin - DrawRotatedF(sprTeleport, sx, sy, Gear^.Pos, sign, 0); + DrawSpriteRotatedF(sprTeleport, sx, sy, Gear^.Pos, sign, 0); exit end; @@ -235,7 +235,7 @@ if HH^.Effects[hePoisoned] then begin Tint($00, $FF, $40, $40); - DrawRotatedTextureF(SpritesData[sprSmokeWhite].texture, 2, 0, 0, sx, sy, 0, 1, 22, 22, (RealTicks shr 36) mod 360); + DrawTextureRotatedF(SpritesData[sprSmokeWhite].texture, 2, 0, 0, sx, sy, 0, 1, 22, 22, (RealTicks shr 36) mod 360); Tint($FF, $FF, $FF, $FF) end; @@ -335,7 +335,7 @@ CrosshairY := Round(hwRound(Gear^.Y) + dy * 80 + GetLaunchY(HH^.CurAmmoType, Gear^.Angle)); - DrawRotatedTex(HH^.Team^.CrosshairTex, + DrawTextureRotated(HH^.Team^.CrosshairTex, 12, 12, CrosshairX + WorldDx, CrosshairY + WorldDy, 0, sign * (Gear^.Angle * 180.0) / cMaxAngle); end; @@ -347,20 +347,20 @@ case CurAmmoGear^.Kind of gtShotgunShot: begin if (CurAmmoGear^.State and gstAnimation <> 0) then - DrawRotated(sprShotgun, hx, hy, sign, aangle) + DrawSpriteRotated(sprShotgun, hx, hy, sign, aangle) else - DrawRotated(sprHandShotgun, hx, hy, sign, aangle); + DrawSpriteRotated(sprHandShotgun, hx, hy, sign, aangle); end; - gtDEagleShot: DrawRotated(sprDEagle, hx, hy, sign, aangle); + gtDEagleShot: DrawSpriteRotated(sprDEagle, hx, hy, sign, aangle); gtSniperRifleShot: begin if (CurAmmoGear^.State and gstAnimation <> 0) then - DrawRotatedF(sprSniperRifle, hx, hy, 1, sign, aangle) + DrawSpriteRotatedF(sprSniperRifle, hx, hy, 1, sign, aangle) else - DrawRotatedF(sprSniperRifle, hx, hy, 0, sign, aangle) + DrawSpriteRotatedF(sprSniperRifle, hx, hy, 0, sign, aangle) end; - gtBallgun: DrawRotated(sprHandBallgun, hx, hy, sign, aangle); + gtBallgun: DrawSpriteRotated(sprHandBallgun, hx, hy, sign, aangle); gtRCPlane: begin - DrawRotated(sprHandPlane, hx, hy, sign, 0); + DrawSpriteRotated(sprHandPlane, hx, hy, sign, 0); defaultPos:= false end; gtRope: begin @@ -386,12 +386,12 @@ with HH^ do if (HatTex <> nil) then begin - DrawRotatedTextureF(HatTex, 1.0, -1.0, -6.0, ox, oy, 0, i, 32, 32, + DrawTextureRotatedF(HatTex, 1.0, -1.0, -6.0, ox, oy, 0, i, 32, 32, i*DxDy2Angle(CurAmmoGear^.dY, CurAmmoGear^.dX) + hAngle); if HatTex^.w > 64 then begin Tint(HH^.Team^.Clan^.Color shl 8 or $FF); - DrawRotatedTextureF(HatTex, 1.0, -1.0, -6.0, ox, oy, 32, i, 32, 32, + DrawTextureRotatedF(HatTex, 1.0, -1.0, -6.0, ox, oy, 32, i, 32, 32, i*DxDy2Angle(CurAmmoGear^.dY, CurAmmoGear^.dX) + hAngle); Tint($FF, $FF, $FF, $FF) end @@ -402,7 +402,7 @@ end; gtBlowTorch: begin - DrawRotated(sprBlowTorch, hx, hy, sign, aangle); + DrawSpriteRotated(sprBlowTorch, hx, hy, sign, aangle); DrawHedgehog(sx, sy, sign, 3, @@ -435,7 +435,7 @@ end; defaultPos:= false end; - gtShover: DrawRotated(sprHandBaseball, hx, hy, sign, aangle + 180); + gtShover: DrawSpriteRotated(sprHandBaseball, hx, hy, sign, aangle + 180); gtFirePunch: begin DrawHedgehog(sx, sy, @@ -453,7 +453,7 @@ gtTeleport: defaultPos:= false; gtWhip: begin - DrawRotatedF(sprWhip, + DrawSpriteRotatedF(sprWhip, sx, sy, 1, @@ -463,7 +463,7 @@ end; gtHammer: begin - DrawRotatedF(sprHammer, + DrawSpriteRotatedF(sprHammer, sx, sy, 1, @@ -473,7 +473,7 @@ end; gtResurrector: begin - DrawRotated(sprHandResurrector, sx, sy, 0, 0); + DrawSpriteRotated(sprHandResurrector, sx, sy, 0, 0); defaultPos:= false end; gtKamikaze: @@ -485,7 +485,7 @@ 6, 0) else - DrawRotatedF(sprKamikaze, + DrawSpriteRotatedF(sprKamikaze, ox, oy, CurAmmoGear^.Pos - 1, sign, @@ -502,7 +502,7 @@ 0) else begin - DrawRotatedF(sprDress, + DrawSpriteRotatedF(sprDress, ox, oy, CurAmmoGear^.Pos, sign, @@ -513,14 +513,14 @@ end; gtFlamethrower: begin - DrawRotatedF(sprHandFlamethrower, hx, hy, (RealTicks div 125) mod 4, sign, aangle); + DrawSpriteRotatedF(sprHandFlamethrower, hx, hy, (RealTicks div 125) mod 4, sign, aangle); if CurAmmoGear^.Tex <> nil then - DrawCentered(sx, sy - 40, CurAmmoGear^.Tex) + DrawTextureCentered(sx, sy - 40, CurAmmoGear^.Tex) end; gtLandGun: - begin DrawRotated(sprHandBallgun, hx, hy, sign, aangle); + begin DrawSpriteRotated(sprHandBallgun, hx, hy, sign, aangle); if CurAmmoGear^.Tex <> nil then - DrawCentered(sx, sy - 40, CurAmmoGear^.Tex) + DrawTextureCentered(sx, sy - 40, CurAmmoGear^.Tex) end; end; @@ -568,7 +568,7 @@ end else begin - DrawRotatedF(Wavez[TWave(Gear^.Tag)].Sprite, + DrawSpriteRotatedF(Wavez[TWave(Gear^.Tag)].Sprite, sx, sy, Gear^.Pos, @@ -592,51 +592,51 @@ dec(HH^.Timer) end; amt:= CurrentHedgehog^.CurAmmoType; - CurWeapon:= GetAmmoEntry(HH^); + CurWeapon:= GetCurAmmoEntry(HH^); case amt of - amBazooka: DrawRotated(sprHandBazooka, hx, hy, sign, aangle); - amSnowball: DrawRotated(sprHandSnowball, hx, hy, sign, aangle); - amMortar: DrawRotated(sprHandMortar, hx, hy, sign, aangle); - amMolotov: DrawRotated(sprHandMolotov, hx, hy, sign, aangle); - amBallgun: DrawRotated(sprHandBallgun, hx, hy, sign, aangle); - amDrill: DrawRotated(sprHandDrill, hx, hy, sign, aangle); - amRope: DrawRotated(sprHandRope, hx, hy, sign, aangle); - amShotgun: DrawRotated(sprHandShotgun, hx, hy, sign, aangle); - amDEagle: DrawRotated(sprHandDEagle, hx, hy, sign, aangle); - amSineGun: DrawRotatedF(sprHandSinegun, hx, hy, 73 + (sign * LongInt(RealTicks div 73)) mod 8, sign, aangle); + amBazooka: DrawSpriteRotated(sprHandBazooka, hx, hy, sign, aangle); + amSnowball: DrawSpriteRotated(sprHandSnowball, hx, hy, sign, aangle); + amMortar: DrawSpriteRotated(sprHandMortar, hx, hy, sign, aangle); + amMolotov: DrawSpriteRotated(sprHandMolotov, hx, hy, sign, aangle); + amBallgun: DrawSpriteRotated(sprHandBallgun, hx, hy, sign, aangle); + amDrill: DrawSpriteRotated(sprHandDrill, hx, hy, sign, aangle); + amRope: DrawSpriteRotated(sprHandRope, hx, hy, sign, aangle); + amShotgun: DrawSpriteRotated(sprHandShotgun, hx, hy, sign, aangle); + amDEagle: DrawSpriteRotated(sprHandDEagle, hx, hy, sign, aangle); + amSineGun: DrawSpriteRotatedF(sprHandSinegun, hx, hy, 73 + (sign * LongInt(RealTicks div 73)) mod 8, sign, aangle); amPortalGun: if (CurWeapon^.Timer and 2) <> 0 then // Add a new Hedgehog value instead of abusing timer? - DrawRotatedF(sprPortalGun, hx, hy, 0, sign, aangle) + DrawSpriteRotatedF(sprPortalGun, hx, hy, 0, sign, aangle) else - DrawRotatedF(sprPortalGun, hx, hy, 1+CurWeapon^.Pos, sign, aangle); + DrawSpriteRotatedF(sprPortalGun, hx, hy, 1+CurWeapon^.Pos, sign, aangle); - amSniperRifle: DrawRotatedF(sprSniperRifle, hx, hy, 0, sign, aangle); - amBlowTorch: DrawRotated(sprHandBlowTorch, hx, hy, sign, aangle); - amCake: DrawRotated(sprHandCake, hx, hy, sign, aangle); - amGrenade: DrawRotated(sprHandGrenade, hx, hy, sign, aangle); - amWatermelon: DrawRotated(sprHandMelon, hx, hy, sign, aangle); - amSkip: DrawRotated(sprHandSkip, hx, hy, sign, aangle); - amClusterBomb: DrawRotated(sprHandCluster, hx, hy, sign, aangle); - amDynamite: DrawRotated(sprHandDynamite, hx, hy, sign, aangle); - amHellishBomb: DrawRotated(sprHandHellish, hx, hy, sign, aangle); - amGasBomb: DrawRotated(sprHandCheese, hx, hy, sign, aangle); - amMine: DrawRotated(sprHandMine, hx, hy, sign, aangle); - amSMine: DrawRotated(sprHandSMine, hx, hy, sign, aangle); + amSniperRifle: DrawSpriteRotatedF(sprSniperRifle, hx, hy, 0, sign, aangle); + amBlowTorch: DrawSpriteRotated(sprHandBlowTorch, hx, hy, sign, aangle); + amCake: DrawSpriteRotated(sprHandCake, hx, hy, sign, aangle); + amGrenade: DrawSpriteRotated(sprHandGrenade, hx, hy, sign, aangle); + amWatermelon: DrawSpriteRotated(sprHandMelon, hx, hy, sign, aangle); + amSkip: DrawSpriteRotated(sprHandSkip, hx, hy, sign, aangle); + amClusterBomb: DrawSpriteRotated(sprHandCluster, hx, hy, sign, aangle); + amDynamite: DrawSpriteRotated(sprHandDynamite, hx, hy, sign, aangle); + amHellishBomb: DrawSpriteRotated(sprHandHellish, hx, hy, sign, aangle); + amGasBomb: DrawSpriteRotated(sprHandCheese, hx, hy, sign, aangle); + amMine: DrawSpriteRotated(sprHandMine, hx, hy, sign, aangle); + amSMine: DrawSpriteRotated(sprHandSMine, hx, hy, sign, aangle); amSeduction: begin - DrawRotated(sprHandSeduction, hx, hy, sign, aangle); + DrawSpriteRotated(sprHandSeduction, hx, hy, sign, aangle); DrawCircle(ox, oy, 248, 4, $FF, $00, $00, $AA); //Tint($FF, $0, $0, $AA); //DrawTexture(ox - 240, oy - 240, SpritesData[sprVampiric].Texture, 10); //Tint($FF, $FF, $FF, $FF); end; - amVampiric: DrawRotatedF(sprHandVamp, hx, hy, (RealTicks div 125) mod 4, sign, aangle); + amVampiric: DrawSpriteRotatedF(sprHandVamp, hx, hy, (RealTicks div 125) mod 4, sign, aangle); amRCPlane: begin - DrawRotated(sprHandPlane, hx, hy, sign, 0); + DrawSpriteRotated(sprHandPlane, hx, hy, sign, 0); defaultPos:= false end; amGirder: begin - DrawRotated(sprHandConstruction, hx, hy, sign, aangle); + DrawSpriteRotated(sprHandConstruction, hx, hy, sign, aangle); DrawSpriteClipped(sprGirder, ox-256, oy-256, @@ -645,34 +645,34 @@ cWaterLine+WorldDy, LongInt(leftX)+WorldDx) end; - amBee: DrawRotatedF(sprHandBee, hx, hy, (RealTicks div 125) mod 4, sign, aangle); - amFlamethrower: DrawRotatedF(sprHandFlamethrower, hx, hy, (RealTicks div 125) mod 4, sign, aangle); - amLandGun: DrawRotated(sprHandBallgun, hx, hy, sign, aangle); + amBee: DrawSpriteRotatedF(sprHandBee, hx, hy, (RealTicks div 125) mod 4, sign, aangle); + amFlamethrower: DrawSpriteRotatedF(sprHandFlamethrower, hx, hy, (RealTicks div 125) mod 4, sign, aangle); + amLandGun: DrawSpriteRotated(sprHandBallgun, hx, hy, sign, aangle); amResurrector: DrawCircle(ox, oy, 98, 4, $F5, $DB, $35, $AA); // I'd rather not like to hardcode 100 here end; case amt of amAirAttack, amMineStrike, - amDrillStrike: DrawRotated(sprHandAirAttack, sx, oy, sign, 0); + amDrillStrike: DrawSpriteRotated(sprHandAirAttack, sx, oy, sign, 0); amPickHammer: DrawHedgehog(sx, sy, sign, 1, 2, 0); - amTeleport: DrawRotatedF(sprTeleport, sx, sy, 0, sign, 0); + amTeleport: DrawSpriteRotatedF(sprTeleport, sx, sy, 0, sign, 0); amKamikaze: DrawHedgehog(sx, sy, sign, 1, 5, 0); - amWhip: DrawRotatedF(sprWhip, + amWhip: DrawSpriteRotatedF(sprWhip, sx, sy, 0, sign, 0); - amHammer: DrawRotatedF(sprHammer, + amHammer: DrawSpriteRotatedF(sprHammer, sx, sy, 0, @@ -700,7 +700,7 @@ end; case amt of - amBaseballBat: DrawRotated(sprHandBaseball, + amBaseballBat: DrawSpriteRotated(sprHandBaseball, sx - 4 * sign, sy + 9, sign, aangle); end; @@ -736,7 +736,7 @@ begin if defaultPos then begin - DrawRotatedF(sprHHIdle, + DrawSpriteRotatedF(sprHHIdle, sx, sy, (RealTicks div 128 + Gear^.Pos) mod 19, @@ -828,7 +828,7 @@ DrawSprite(sprJetpack, sx-36, sy-28, 3) end; if CurAmmoGear^.Tex <> nil then - DrawCentered(sx, sy - 40, CurAmmoGear^.Tex); + DrawTextureCentered(sx, sy - 40, CurAmmoGear^.Tex); DrawAltWeapon(Gear, sx, sy) end; end; @@ -847,17 +847,17 @@ if ((cTagsMask and htHealth) <> 0) then begin dec(t, HealthTagTex^.h + 2); - DrawCentered(ox, t, HealthTagTex) + DrawTextureCentered(ox, t, HealthTagTex) end; if (cTagsMask and htName) <> 0 then begin dec(t, NameTagTex^.h + 2); - DrawCentered(ox, t, NameTagTex) + DrawTextureCentered(ox, t, NameTagTex) end; if (cTagsMask and htTeamName) <> 0 then begin dec(t, Team^.NameTagTex^.h + 2); - DrawCentered(ox, t, Team^.NameTagTex) + DrawTextureCentered(ox, t, Team^.NameTagTex) end; if (cTagsMask and htTransparent) <> 0 then Tint($FF, $FF, $FF, $FF) @@ -865,7 +865,7 @@ if (Gear^.State and gstHHDriven) <> 0 then // Current hedgehog begin if (CurAmmoGear <> nil) and (CurAmmoGear^.Kind = gtResurrector) then - DrawCentered(ox, sy - cHHRadius - 7 - HealthTagTex^.h, HealthTagTex); + DrawTextureCentered(ox, sy - cHHRadius - 7 - HealthTagTex^.h, HealthTagTex); if bShowFinger and ((Gear^.State and gstHHDriven) <> 0) then DrawSprite(sprFinger, ox - 16, oy - 64, @@ -880,7 +880,7 @@ if HH^.Effects[hePoisoned] then begin Tint($00, $FF, $40, $80); - DrawRotatedTextureF(SpritesData[sprSmokeWhite].texture, 1.5, 0, 0, sx, sy, 0, 1, 22, 22, 360 - (RealTicks shr 37) mod 360); + DrawTextureRotatedF(SpritesData[sprSmokeWhite].texture, 1.5, 0, 0, sx, sy, 0, 1, 22, 22, 360 - (RealTicks shr 37) mod 360); end; if HH^.Effects[heResurrected] then begin @@ -913,43 +913,43 @@ begin if Gear^.Target.X <> NoPointX then if Gear^.AmmoType = amBee then - DrawRotatedF(sprTargetBee, Gear^.Target.X + WorldDx, Gear^.Target.Y + WorldDy, 0, 0, (RealTicks shr 3) mod 360) + DrawSpriteRotatedF(sprTargetBee, Gear^.Target.X + WorldDx, Gear^.Target.Y + WorldDy, 0, 0, (RealTicks shr 3) mod 360) else - DrawRotatedF(sprTargetP, Gear^.Target.X + WorldDx, Gear^.Target.Y + WorldDy, 0, 0, (RealTicks shr 3) mod 360); + DrawSpriteRotatedF(sprTargetP, Gear^.Target.X + WorldDx, Gear^.Target.Y + WorldDy, 0, 0, (RealTicks shr 3) mod 360); case Gear^.Kind of - gtGrenade: DrawRotated(sprBomb, x, y, 0, Gear^.DirAngle); - gtSnowball: DrawRotated(sprSnowball, x, y, 0, Gear^.DirAngle); - gtGasBomb: DrawRotated(sprCheese, x, y, 0, Gear^.DirAngle); + gtGrenade: DrawSpriteRotated(sprBomb, x, y, 0, Gear^.DirAngle); + gtSnowball: DrawSpriteRotated(sprSnowball, x, y, 0, Gear^.DirAngle); + gtGasBomb: DrawSpriteRotated(sprCheese, x, y, 0, Gear^.DirAngle); gtMolotov: if (Gear^.State and gstDrowning) = 0 then - DrawRotatedF(sprMolotov, x, y, (RealTicks div 125) mod 8, hwSign(Gear^.dX), Gear^.DirAngle * hwSign(Gear^.dX)) + DrawSpriteRotatedF(sprMolotov, x, y, (RealTicks div 125) mod 8, hwSign(Gear^.dX), Gear^.DirAngle * hwSign(Gear^.dX)) else DrawSprite(sprMolotov, x, y, 8); gtRCPlane: begin aangle:= Gear^.Angle * 360 / 4096; if Gear^.Tag < 0 then aangle:= 360-aangle; Tint(Gear^.Hedgehog^.Team^.Clan^.Color shl 8 or $FF); - DrawRotatedF(sprPlane, x, y, 0, Gear^.Tag, aangle - 90); + DrawSpriteRotatedF(sprPlane, x, y, 0, Gear^.Tag, aangle - 90); Tint($FF, $FF, $FF, $FF); - DrawRotatedF(sprPlane, x, y, 1, Gear^.Tag, aangle - 90) + DrawSpriteRotatedF(sprPlane, x, y, 1, Gear^.Tag, aangle - 90) end; - gtBall: DrawRotatedf(sprBalls, x, y, Gear^.Tag,0, Gear^.DirAngle); + gtBall: DrawSpriteRotatedF(sprBalls, x, y, Gear^.Tag,0, Gear^.DirAngle); gtPortal: if ((Gear^.Tag and 1) = 0) // still moving? or (Gear^.IntersectGear = nil) or (Gear^.IntersectGear^.IntersectGear <> Gear) // not linked&backlinked? or ((Gear^.IntersectGear^.Tag and 1) = 0) then // linked portal still moving? - DrawRotatedf(sprPortal, x, y, Gear^.Tag, hwSign(Gear^.dX), Gear^.DirAngle) - else DrawRotatedf(sprPortal, x, y, 4 + Gear^.Tag div 2, hwSign(Gear^.dX), Gear^.DirAngle); + DrawSpriteRotatedF(sprPortal, x, y, Gear^.Tag, hwSign(Gear^.dX), Gear^.DirAngle) + else DrawSpriteRotatedF(sprPortal, x, y, 4 + Gear^.Tag div 2, hwSign(Gear^.dX), Gear^.DirAngle); gtDrill: if (Gear^.State and gsttmpFlag) <> 0 then - DrawRotated(sprAirDrill, x, y, 0, DxDy2Angle(Gear^.dY, Gear^.dX)) + DrawSpriteRotated(sprAirDrill, x, y, 0, DxDy2Angle(Gear^.dY, Gear^.dX)) else - DrawRotated(sprDrill, x, y, 0, DxDy2Angle(Gear^.dY, Gear^.dX)); + DrawSpriteRotated(sprDrill, x, y, 0, DxDy2Angle(Gear^.dY, Gear^.dX)); gtHedgehog: DrawHH(Gear, x, y); - gtShell: DrawRotated(sprBazookaShell, x, y, 0, DxDy2Angle(Gear^.dY, Gear^.dX)); + gtShell: DrawSpriteRotated(sprBazookaShell, x, y, 0, DxDy2Angle(Gear^.dY, Gear^.dX)); gtGrave: begin DrawTextureF(Gear^.Hedgehog^.Team^.GraveTex, 1, x, y, (GameTicks shr 7+Gear^.uid) and 7, 1, 32, 32); @@ -962,21 +962,21 @@ Tint($FF, $FF, $FF, $FF) end end; - gtBee: DrawRotatedF(sprBee, x, y, (GameTicks shr 5) mod 2, 0, DxDy2Angle(Gear^.dY, Gear^.dX)); + gtBee: DrawSpriteRotatedF(sprBee, x, y, (GameTicks shr 5) mod 2, 0, DxDy2Angle(Gear^.dY, Gear^.dX)); gtPickHammer: DrawSprite(sprPHammer, x - 16, y - 50 + LongInt(((GameTicks shr 5) and 1) * 2), 0); gtRope: DrawRope(Gear); gtMine: if (((Gear^.State and gstAttacking) = 0)or((Gear^.Timer and $3FF) < 420)) and (Gear^.Health <> 0) then - DrawRotated(sprMineOff, x, y, 0, Gear^.DirAngle) + DrawSpriteRotated(sprMineOff, x, y, 0, Gear^.DirAngle) else if Gear^.Health <> 0 then - DrawRotated(sprMineOn, x, y, 0, Gear^.DirAngle) - else DrawRotated(sprMineDead, x, y, 0, Gear^.DirAngle); + DrawSpriteRotated(sprMineOn, x, y, 0, Gear^.DirAngle) + else DrawSpriteRotated(sprMineDead, x, y, 0, Gear^.DirAngle); gtSMine: if (((Gear^.State and gstAttacking) = 0)or((Gear^.Timer and $3FF) < 420)) and (Gear^.Health <> 0) then - DrawRotated(sprSMineOff, x, y, 0, Gear^.DirAngle) + DrawSpriteRotated(sprSMineOff, x, y, 0, Gear^.DirAngle) else if Gear^.Health <> 0 then - DrawRotated(sprSMineOn, x, y, 0, Gear^.DirAngle) - else DrawRotated(sprMineDead, x, y, 0, Gear^.DirAngle); + DrawSpriteRotated(sprSMineOn, x, y, 0, Gear^.DirAngle) + else DrawSpriteRotated(sprMineDead, x, y, 0, Gear^.DirAngle); gtCase: if ((Gear^.Pos and posCaseAmmo) <> 0) then begin @@ -1011,12 +1011,12 @@ DrawSprite(sprExplosives, x - 24, y - 24, i) end else if Gear^.State and gsttmpFlag = 0 then - DrawRotatedF(sprExplosivesRoll, x, y + 4, 0, 0, Gear^.DirAngle) + DrawSpriteRotatedF(sprExplosivesRoll, x, y + 4, 0, 0, Gear^.DirAngle) else - DrawRotatedF(sprExplosivesRoll, x, y + 4, 1, 0, Gear^.DirAngle); + DrawSpriteRotatedF(sprExplosivesRoll, x, y + 4, 1, 0, Gear^.DirAngle); end; - gtDynamite: DrawSprite2(sprDynamite, x - 16, y - 25, Gear^.Tag and 1, Gear^.Tag shr 1); - gtClusterBomb: DrawRotated(sprClusterBomb, x, y, 0, Gear^.DirAngle); + gtDynamite: DrawSprite(sprDynamite, x - 16, y - 25, Gear^.Tag and 1, Gear^.Tag shr 1); + gtClusterBomb: DrawSpriteRotated(sprClusterBomb, x, y, 0, Gear^.DirAngle); gtCluster: DrawSprite(sprClusterParticle, x - 8, y - 8, 0); gtFlame: if Gear^.Tag and 1 = 0 then DrawTextureF(SpritesData[sprFlame].Texture, 2 / (Gear^.Tag mod 3 + 2), x, y, (GameTicks shr 7 + LongWord(Gear^.Tag)) mod 8, 1, 16, 16) @@ -1027,16 +1027,16 @@ end; gtAirAttack: begin Tint(Gear^.Hedgehog^.Team^.Clan^.Color shl 8 or $FF); - DrawRotatedF(sprAirplane, x, y, 0, Gear^.Tag, 0); + DrawSpriteRotatedF(sprAirplane, x, y, 0, Gear^.Tag, 0); Tint($FF, $FF, $FF, $FF); - DrawRotatedF(sprAirplane, x, y, 1, Gear^.Tag, 0); + DrawSpriteRotatedF(sprAirplane, x, y, 1, Gear^.Tag, 0); end; - gtAirBomb: DrawRotated(sprAirBomb, x, y, 0, DxDy2Angle(Gear^.dY, Gear^.dX)); + gtAirBomb: DrawSpriteRotated(sprAirBomb, x, y, 0, DxDy2Angle(Gear^.dY, Gear^.dX)); gtTeleport: begin HHGear:= Gear^.Hedgehog^.Gear; if not Gear^.Hedgehog^.Unplaced then - DrawRotatedF(sprTeleport, x + 1, y - 3, Gear^.Pos, hwSign(Gear^.dX), 0); - DrawRotatedF(sprTeleport, hwRound(HHGear^.X) + 1 + WorldDx, hwRound(HHGear^.Y) - 3 + WorldDy, 11 - Gear^.Pos, hwSign(HHGear^.dX), 0); + DrawSpriteRotatedF(sprTeleport, x + 1, y - 3, Gear^.Pos, hwSign(Gear^.dX), 0); + DrawSpriteRotatedF(sprTeleport, hwRound(HHGear^.X) + 1 + WorldDx, hwRound(HHGear^.Y) - 3 + WorldDy, 11 - Gear^.Pos, hwSign(HHGear^.dX), 0); end; gtSwitcher: DrawSprite(sprSwitch, x - 16, y - 56, (GameTicks shr 6) mod 12); gtTarget: begin @@ -1044,17 +1044,17 @@ DrawSprite(sprTarget, x - 16, y - 16, 0); Tint($FF, $FF, $FF, $FF); end; - gtMortar: DrawRotated(sprMortar, x, y, 0, DxDy2Angle(Gear^.dY, Gear^.dX)); + gtMortar: DrawSpriteRotated(sprMortar, x, y, 0, DxDy2Angle(Gear^.dY, Gear^.dX)); gtCake: if Gear^.Pos = 6 then - DrawRotatedf(sprCakeWalk, x, y, (GameTicks div 40) mod 6, hwSign(Gear^.dX), Gear^.DirAngle * hwSign(Gear^.dX) + 90) + DrawSpriteRotatedF(sprCakeWalk, x, y, (GameTicks div 40) mod 6, hwSign(Gear^.dX), Gear^.DirAngle * hwSign(Gear^.dX) + 90) else - DrawRotatedf(sprCakeDown, x, y, 5 - Gear^.Pos, hwSign(Gear^.dX), Gear^.DirAngle * hwSign(Gear^.dX) + 90); + DrawSpriteRotatedF(sprCakeDown, x, y, 5 - Gear^.Pos, hwSign(Gear^.dX), Gear^.DirAngle * hwSign(Gear^.dX) + 90); gtSeduction: if Gear^.Pos >= 14 then DrawSprite(sprSeduction, x - 16, y - 16, 0); - gtWatermelon: DrawRotatedf(sprWatermelon, x, y, 0, 0, Gear^.DirAngle); - gtMelonPiece: DrawRotatedf(sprWatermelon, x, y, 1, 0, Gear^.DirAngle); - gtHellishBomb: DrawRotated(sprHellishBomb, x, y, 0, Gear^.DirAngle); + gtWatermelon: DrawSpriteRotatedF(sprWatermelon, x, y, 0, 0, Gear^.DirAngle); + gtMelonPiece: DrawSpriteRotatedF(sprWatermelon, x, y, 1, 0, Gear^.DirAngle); + gtHellishBomb: DrawSpriteRotated(sprHellishBomb, x, y, 0, Gear^.DirAngle); gtBirdy: begin if Gear^.State and gstAnimation = gstAnimation then begin @@ -1089,7 +1089,7 @@ DrawTextureF(SpritesData[sprBirdy].Texture, 1, x, y, ((Gear^.Pos shr 6) or (RealTicks shr 8)) mod 2, Gear^.Tag, 75, 75); end; end; - gtEgg: DrawRotatedTextureF(SpritesData[sprEgg].Texture, 1, 0, 0, x, y, 0, 1, 16, 16, Gear^.DirAngle); + gtEgg: DrawTextureRotatedF(SpritesData[sprEgg].Texture, 1, 0, 0, x, y, 0, 1, 16, 16, Gear^.DirAngle); gtPiano: begin if (Gear^.State and gstDrowning) = 0 then begin @@ -1107,25 +1107,25 @@ Tint($C0, $C0, $00, (5000 - Gear^.Timer) div 8) else Tint($C0, $C0, $00, $C0); - DrawRotatedTextureF(SpritesData[sprSmokeWhite].texture, 3, 0, 0, x, y, 0, 1, 22, 22, (RealTicks shr 36 + Gear^.UID * 100) mod 360); + DrawTextureRotatedF(SpritesData[sprSmokeWhite].texture, 3, 0, 0, x, y, 0, 1, 22, 22, (RealTicks shr 36 + Gear^.UID * 100) mod 360); Tint($FF, $FF, $FF, $FF) end; gtResurrector: begin - DrawRotated(sprCross, x, y, 0, 0); + DrawSpriteRotated(sprCross, x, y, 0, 0); Tint($f5, $db, $35, max($00, round($C0 * abs(1 - (GameTicks mod 6000) / 3000)))); DrawTexture(x - 108, y - 108, SpritesData[sprVampiric].Texture, 4.5); Tint($FF, $FF, $FF, $FF); end; - gtNapalmBomb: DrawRotated(sprNapalmBomb, x, y, 0, DxDy2Angle(Gear^.dY, Gear^.dX)); + gtNapalmBomb: DrawSpriteRotated(sprNapalmBomb, x, y, 0, DxDy2Angle(Gear^.dY, Gear^.dX)); gtFlake: if Gear^.State and (gstDrowning or gstTmpFlag) <> 0 then begin - Tint((cExplosionBorderColor shr RShift) and $FF, - (cExplosionBorderColor shr GShift) and $FF, - (cExplosionBorderColor shr BShift) and $FF, + Tint((ExplosionBorderColor shr RShift) and $FF, + (ExplosionBorderColor shr GShift) and $FF, + (ExplosionBorderColor shr BShift) and $FF, $FF); // Needs a nicer white texture to tint - DrawRotatedTextureF(SpritesData[sprSnowDust].Texture, 1, 0, 0, x, y, 0, 1, 8, 8, Gear^.DirAngle); - //DrawRotated(sprSnowDust, x, y, 0, Gear^.DirAngle); + DrawTextureRotatedF(SpritesData[sprSnowDust].Texture, 1, 0, 0, x, y, 0, 1, 8, 8, Gear^.DirAngle); + //DrawSpriteRotated(sprSnowDust, x, y, 0, Gear^.DirAngle); //DrawTexture(x, y, SpritesData[sprVampiric].Texture, 0.1); Tint($FF, $FF, $FF, $FF); end @@ -1140,9 +1140,9 @@ if vobVelocity = 0 then DrawSprite(sprFlake, x, y, Gear^.Timer) else - DrawRotatedF(sprFlake, x, y, Gear^.Timer, 1, Gear^.DirAngle); + DrawSpriteRotatedF(sprFlake, x, y, Gear^.Timer, 1, Gear^.DirAngle); //DrawSprite(sprFlake, x-SpritesData[sprFlake].Width div 2, y-SpritesData[sprFlake].Height div 2, Gear^.Timer) -//DrawRotatedF(sprFlake, x-SpritesData[sprFlake].Width div 2, y-SpritesData[sprFlake].Height div 2, Gear^.Timer, 1, Gear^.DirAngle); +//DrawSpriteRotatedF(sprFlake, x-SpritesData[sprFlake].Width div 2, y-SpritesData[sprFlake].Height div 2, Gear^.Timer, 1, Gear^.DirAngle); if Gear^.FlightTime > 0 then Tint($FF, $FF, $FF, $FF); end; @@ -1171,7 +1171,7 @@ end; if Gear^.RenderTimer and (Gear^.Tex <> nil) then - DrawCentered(x + 8, y + 8, Gear^.Tex); + DrawTextureCentered(x + 8, y + 8, Gear^.Tex); end; end. diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uGearsUtils.pas --- a/hedgewars/uGearsUtils.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uGearsUtils.pas Wed May 02 23:53:45 2012 +0200 @@ -22,7 +22,9 @@ interface uses uTypes, math; -procedure doMakeExplosion(X, Y, Radius: LongInt; AttackingHog: PHedgehog; Mask: Longword; const Tint: LongWord = $FFFFFFFF); +procedure doMakeExplosion(X, Y, Radius: LongInt; AttackingHog: PHedgehog; Mask: Longword); inline; +procedure doMakeExplosion(X, Y, Radius: LongInt; AttackingHog: PHedgehog; Mask: Longword; const Tint: LongWord); + function ModifyDamage(dmg: Longword; Gear: PGear): Longword; procedure ApplyDamage(Gear: PGear; AttackerHog: PHedgehog; Damage: Longword; Source: TDamageSource); procedure spawnHealthTagForHH(HHGear: PGear; dmg: Longword); @@ -30,9 +32,11 @@ procedure CheckHHDamage(Gear: PGear); procedure CalcRotationDirAngle(Gear: PGear); procedure ResurrectHedgehog(gear: PGear); -procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt; skipProximity: boolean = false); + +procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt); inline; +procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt; skipProximity: boolean); + function CheckGearNear(Gear: PGear; Kind: TGearType; rX, rY: LongInt): PGear; -function CheckGearsNear(mX, mY: LongInt; Kind: TGearsType; rX, rY: LongInt): PGear; function CheckGearDrowning(Gear: PGear): boolean; var doStepHandlers: array[TGearType] of TGearStepProcedure; @@ -44,6 +48,11 @@ uLocale, uTextures, uRenderUtils, uRandom, SDLh, uDebug, uGears, uGearsList; +procedure doMakeExplosion(X, Y, Radius: LongInt; AttackingHog: PHedgehog; Mask: Longword); inline; +begin + doMakeExplosion(X, Y, Radius, AttackingHog, Mask, $FFFFFFFF); +end; + procedure doMakeExplosion(X, Y, Radius: LongInt; AttackingHog: PHedgehog; Mask: Longword; const Tint: LongWord); var Gear: PGear; dmg, dmgBase: LongInt; @@ -464,15 +473,41 @@ var i: LongInt; count: LongInt = 0; begin -if (y and LAND_HEIGHT_MASK) = 0 then - for i:= max(x - r, 0) to min(x + r, LAND_WIDTH - 4) do - if Land[y, i] <> 0 then + if (y and LAND_HEIGHT_MASK) = 0 then + for i:= max(x - r, 0) to min(x + r, LAND_WIDTH - 4) do + if Land[y, i] <> 0 then begin - inc(count); - if count = c then - exit(count) + inc(count); + if count = c then + begin + CountNonZeroz:= count; + exit + end; end; -CountNonZeroz:= count; + CountNonZeroz:= count; +end; + + +function NoGearsToAvoid(mX, mY: LongInt; rX, rY: LongInt): boolean; +var t: PGear; +begin +NoGearsToAvoid:= false; +t:= GearsList; +rX:= sqr(rX); +rY:= sqr(rY); +while t <> nil do + begin + if t^.Kind <= gtExplosives then + if not (hwSqr(int2hwFloat(mX) - t^.X) / rX + hwSqr(int2hwFloat(mY) - t^.Y) / rY > _1) then + exit; + t:= t^.NextGear + end; +NoGearsToAvoid:= true +end; + +procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt); inline; +begin + FindPlace(Gear, withFall, Left, Right, false); end; procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt; skipProximity: boolean); @@ -511,14 +546,14 @@ if (y - sy > Gear^.Radius * 2) and (((Gear^.Kind = gtExplosives) and (y < cWaterLine) - and (reallySkip or (CheckGearsNear(x, y - Gear^.Radius, [gtFlame, gtHedgehog, gtMine, gtCase, gtExplosives], 60, 60) = nil)) + and (reallySkip or NoGearsToAvoid(x, y - Gear^.Radius, 60, 60)) and (CountNonZeroz(x, y+1, Gear^.Radius - 1, Gear^.Radius+1) > Gear^.Radius)) or ((Gear^.Kind <> gtExplosives) and (y < cWaterLine) - and (reallySkip or (CheckGearsNear(x, y - Gear^.Radius, [gtFlame, gtHedgehog, gtMine, gtCase, gtExplosives], 110, 110) = nil)))) then - - begin + and (reallySkip or NoGearsToAvoid(x, y - Gear^.Radius, 110, 110)) + )) then + begin ar[cnt].X:= x; if withFall then ar[cnt].Y:= sy + Gear^.Radius @@ -575,27 +610,14 @@ begin if (t <> Gear) and (t^.Kind = Kind) then if not((hwSqr(Gear^.X - t^.X) / rX + hwSqr(Gear^.Y - t^.Y) / rY) > _1) then - exit(t); + begin + CheckGearNear:= t; + exit; + end; t:= t^.NextGear end; CheckGearNear:= nil end; - -function CheckGearsNear(mX, mY: LongInt; Kind: TGearsType; rX, rY: LongInt): PGear; -var t: PGear; -begin -t:= GearsList; -rX:= sqr(rX); -rY:= sqr(rY); -while t <> nil do - begin - if t^.Kind in Kind then - if not (hwSqr(int2hwFloat(mX) - t^.X) / rX + hwSqr(int2hwFloat(mY) - t^.Y) / rY > _1) then - exit(t); - t:= t^.NextGear - end; -CheckGearsNear:= nil -end; end. diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uIO.pas --- a/hedgewars/uIO.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uIO.pas Wed May 02 23:53:45 2012 +0200 @@ -26,6 +26,7 @@ procedure freeModule; procedure SendIPC(s: shortstring); +procedure SendIPCc(c: char); procedure SendIPCXY(cmd: char; X, Y: SmallInt); procedure SendIPCRaw(p: pointer; len: Longword); procedure SendIPCAndWaitReply(s: shortstring); @@ -104,7 +105,7 @@ WriteLnToConsole(msgOK); WriteToConsole('Establishing IPC connection to tcp 127.0.0.1:' + IntToStr(ipcPort) + ' '); {$HINTS OFF} - SDLTry(SDLNet_ResolveHost(ipaddr, '127.0.0.1', ipcPort) = 0, true); + SDLTry(SDLNet_ResolveHost(ipaddr, PChar('127.0.0.1'), ipcPort) = 0, true); {$HINTS ON} IPCSock:= SDLNet_TCP_Open(ipaddr); SDLTry(IPCSock <> nil, true); @@ -123,7 +124,7 @@ begin case s[1] of '!': begin AddFileLog('Ping? Pong!'); isPonged:= true; end; - '?': SendIPC('!'); + '?': SendIPCc('!'); 'e': ParseCommand(copy(s, 2, Length(s) - 1), true); 'E': OutError(copy(s, 2, Length(s) - 1), true); 'W': OutError(copy(s, 2, Length(s) - 1), false); @@ -142,27 +143,26 @@ end; procedure IPCCheckSock; -const ss: shortstring = ''; var i: LongInt; s: shortstring; begin -if IPCSock = nil then - exit; + if IPCSock = nil then + exit; -fds^.numsockets:= 0; -SDLNet_AddSocket(fds, IPCSock); + fds^.numsockets:= 0; + SDLNet_AddSocket(fds, IPCSock); -while SDLNet_CheckSockets(fds, 0) > 0 do + while SDLNet_CheckSockets(fds, 0) > 0 do begin - i:= SDLNet_TCP_Recv(IPCSock, @s[1], 255 - Length(ss)); - if i > 0 then + i:= SDLNet_TCP_Recv(IPCSock, @s[1], 255 - Length(SocketString)); + if i > 0 then begin - s[0]:= char(i); - ss:= ss + s; - while (Length(ss) > 1) and (Length(ss) > byte(ss[1])) do + s[0]:= char(i); + SocketString:= SocketString + s; + while (Length(SocketString) > 1) and (Length(SocketString) > byte(SocketString[1])) do begin - ParseIPCCommand(copy(ss, 2, byte(ss[1]))); - Delete(ss, 1, Succ(byte(ss[1]))) + ParseIPCCommand(copy(SocketString, 2, byte(SocketString[1]))); + Delete(SocketString, 1, Succ(byte(SocketString[1]))) end end else @@ -206,7 +206,7 @@ end; procedure SendStat(sit: TStatInfoType; s: shortstring); -const stc: array [TStatInfoType] of char = 'rDkKHTPsSB'; +const stc: array [TStatInfoType] of char = ('r', 'D', 'k', 'K', 'H', 'T', 'P', 's', 'S', 'B'); var buf: shortstring; begin buf:= 'i' + stc[sit] + s; @@ -229,6 +229,14 @@ end end; +procedure SendIPCc(c: char); +var s: shortstring; +begin + s[0]:= #1; + s[1]:= c; + SendIPC(s); +end; + procedure SendIPCRaw(p: pointer; len: Longword); begin if IPCSock <> nil then @@ -259,7 +267,7 @@ procedure SendIPCAndWaitReply(s: shortstring); begin SendIPC(s); -SendIPC('?'); +SendIPCc('?'); IPCWaitPongEvent end; @@ -267,7 +275,7 @@ begin inc(SendEmptyPacketTicks, Lag); if (SendEmptyPacketTicks >= cSendEmptyPacketTime) then - SendIPC('+') + SendIPCc('+') end; procedure NetGetNextCmd; @@ -347,9 +355,11 @@ 't': ParseCommand('taunt ' + headcmd^.str[2], true); 'h': ParseCommand('hogsay ' + copy(headcmd^.str, 2, Pred(headcmd^.len)), true); '1'..'5': ParseCommand('timer ' + headcmd^.cmd, true); - #128..char(128 + cMaxSlotIndex): ParseCommand('slot ' + char(byte(headcmd^.cmd) - 79), true) else - OutError('Unexpected protocol command: ' + headcmd^.cmd, True) + if (headcmd^.cmd >= #128) and (headcmd^.cmd <= char(128 + cMaxSlotIndex)) then + ParseCommand('slot ' + char(byte(headcmd^.cmd) - 79), true) + else + OutError('Unexpected protocol command: ' + headcmd^.cmd, True) end; RemoveCmd end; @@ -418,14 +428,15 @@ procedure initModule; begin - RegisterVariable('fatal', vtCommand, @chFatalError, true ); + RegisterVariable('fatal', @chFatalError, true ); IPCSock:= nil; headcmd:= nil; lastcmd:= nil; - isPonged:= false; // was const - + isPonged:= false; + SocketString:= ''; + hiTicks:= 0; SendEmptyPacketTicks:= 0; end; diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uInputHandler.pas --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hedgewars/uInputHandler.pas Wed May 02 23:53:45 2012 +0200 @@ -0,0 +1,459 @@ +(* + * Hedgewars, a free turn based strategy game + * Copyright (c) 2004-2012 Andrey Korotaev + * + * 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 "options.inc"} + +unit uInputHandler; +interface +uses SDLh, uTypes; + +procedure initModule; +procedure freeModule; + +function KeyNameToCode(name: shortstring): word; +procedure ProcessKbd; +procedure ProcessMouse(event: TSDL_MouseButtonEvent; ButtonDown: boolean); +procedure ProcessKey(event: TSDL_KeyboardEvent); inline; +procedure ProcessKey(code: LongInt; KeyDown: boolean); + +procedure ResetKbd; +procedure FreezeEnterKey; +procedure InitKbdKeyTable; + +procedure SetBinds(var binds: TBinds); +procedure SetDefaultBinds; + +procedure ControllerInit; +procedure ControllerClose; +procedure ControllerAxisEvent(joy, axis: Byte; value: Integer); +procedure ControllerHatEvent(joy, hat, value: Byte); +procedure ControllerButtonEvent(joy, button: Byte; pressed: Boolean); + +implementation +uses uConsole, uCommands, uMisc, uVariables, uConsts, uUtils, uDebug; + +var tkbd, tkbdn: TKeyboardState; + quitKeyCode: Byte; + KeyNames: array [0..cKeyMaxIndex] of string[15]; + CurrentBinds: TBinds; + +function KeyNameToCode(name: shortstring): word; +var code: Word; +begin + name:= LowerCase(name); + code:= cKeyMaxIndex; + while (code > 0) and (KeyNames[code] <> name) do dec(code); + KeyNameToCode:= code; +end; + +procedure ProcessKbd; +//var i, j, k: LongInt; +begin + +// move cursor/camera +// TODO: Scale on screen dimensions and/or axis value (game controller)? +//TODO what is this for? +movecursor(5 * CursorMovementX, 5 * CursorMovementY); + + +(* +TODO reimplement +$IFNDEF MOBILE +// Controller(s) +k:= j; // should we test k for hitting the limit? sounds rather unlikely to ever reach it +for j:= 0 to Pred(ControllerNumControllers) do + begin + for i:= 0 to Pred(ControllerNumAxes[j]) do + begin + if ControllerAxes[j][i] > 20000 then + tkbdn[k + 0]:= 1 + else + tkbdn[k + 0]:= 0; + if ControllerAxes[j][i] < -20000 then + tkbdn[k + 1]:= 1 + else + tkbdn[k + 1]:= 0; + inc(k, 2); + end; + for i:= 0 to Pred(ControllerNumHats[j]) do + begin + tkbdn[k + 0]:= ControllerHats[j][i] and SDL_HAT_UP; + tkbdn[k + 1]:= ControllerHats[j][i] and SDL_HAT_RIGHT; + tkbdn[k + 2]:= ControllerHats[j][i] and SDL_HAT_DOWN; + tkbdn[k + 3]:= ControllerHats[j][i] and SDL_HAT_LEFT; + inc(k, 4); + end; + for i:= 0 to Pred(ControllerNumButtons[j]) do + begin + tkbdn[k]:= ControllerButtons[j][i]; + inc(k, 1); + end; + end; +$ENDIF *) + +end; + + +procedure ProcessKey(code: LongInt; KeyDown: boolean); +var + Trusted: boolean; + s : string; +begin +hideAmmoMenu:= false; +Trusted:= (CurrentTeam <> nil) + and (not CurrentTeam^.ExtDriven) + and (CurrentHedgehog^.BotLevel = 0); + +tkbdn[code]:= ord(KeyDown); + +// ctrl/cmd + q to close engine and frontend +if(KeyDown and (code = quitKeyCode)) then + begin +{$IFDEF DARWIN} + if ((tkbdn[KeyNameToCode('left_meta')] = 1) or (tkbdn[KeyNameToCode('right_meta')] = 1)) then +{$ELSE} + if ((tkbdn[KeyNameToCode('left_ctrl')] = 1) or (tkbdn[KeyNameToCode('right_ctrl')] = 1)) then +{$ENDIF} + ParseCommand('halt', true); + end; + +if CurrentBinds[code][0] <> #0 then + begin + if (code > 3) and (tkbdn[code] <> 0) and not ((CurrentBinds[code] = 'put') or (CurrentBinds[code] = 'ammomenu') or (CurrentBinds[code] = '+cur_u') or (CurrentBinds[code] = '+cur_d') or (CurrentBinds[code] = '+cur_l') or (CurrentBinds[code] = '+cur_r')) then hideAmmoMenu:= true; + if (tkbd[code] = 0) and (tkbdn[code] <> 0) then + begin + ParseCommand(CurrentBinds[code], Trusted); + if (CurrentTeam <> nil) and (not CurrentTeam^.ExtDriven) and (ReadyTimeLeft > 1) then + ParseCommand('gencmd R', true) + end + else if (CurrentBinds[code][1] = '+') and (tkbdn[code] = 0) and (tkbd[code] <> 0) then + begin + s:= CurrentBinds[code]; + s[1]:= '-'; + ParseCommand(s, Trusted); + if (CurrentTeam <> nil) and (not CurrentTeam^.ExtDriven) and (ReadyTimeLeft > 1) then + ParseCommand('gencmd R', true) + end; + tkbd[code]:= tkbdn[code] + end + +end; + +procedure ProcessKey(event: TSDL_KeyboardEvent); inline; +begin + ProcessKey(event.keysym.sym, event.type_ = SDL_KEYDOWN); +end; + +procedure ProcessMouse(event: TSDL_MouseButtonEvent; ButtonDown: boolean); +begin +case event.button of + SDL_BUTTON_LEFT: + ProcessKey(KeyNameToCode('mousel'), ButtonDown); + SDL_BUTTON_MIDDLE: + ProcessKey(KeyNameToCode('mousem'), ButtonDown); + SDL_BUTTON_RIGHT: + ProcessKey(KeyNameToCode('mouser'), ButtonDown); + SDL_BUTTON_WHEELDOWN: + ProcessKey(KeyNameToCode('wheeldown'), ButtonDown); + SDL_BUTTON_WHEELUP: + ProcessKey(KeyNameToCode('wheelup'), ButtonDown); + end; +end; + +procedure ResetKbd; +var j, k, t: LongInt; + i: LongInt; + pkbd: PByteArray; +begin + +k:= SDL_GetMouseState(nil, nil); +pkbd:=SDL_GetKeyState(@j); + +//TryDo(j < cKeyMaxIndex, 'SDL keys number is more than expected (' + IntToStr(j) + ')', true); + +for i:= 1 to pred(j) do + tkbdn[i]:= pkbd^[i]; + +{$IFNDEF MOBILE} +// Controller(s) +k:= j; // should we test k for hitting the limit? sounds rather unlikely to ever reach it +for j:= 0 to Pred(ControllerNumControllers) do + begin + for i:= 0 to Pred(ControllerNumAxes[j]) do + begin + if ControllerAxes[j][i] > 20000 then + tkbdn[k + 0]:= 1 + else + tkbdn[k + 0]:= 0; + if ControllerAxes[j][i] < -20000 then + tkbdn[k + 1]:= 1 + else + tkbdn[k + 1]:= 0; + inc(k, 2); + end; + for i:= 0 to Pred(ControllerNumHats[j]) do + begin + tkbdn[k + 0]:= ControllerHats[j][i] and SDL_HAT_UP; + tkbdn[k + 1]:= ControllerHats[j][i] and SDL_HAT_RIGHT; + tkbdn[k + 2]:= ControllerHats[j][i] and SDL_HAT_DOWN; + tkbdn[k + 3]:= ControllerHats[j][i] and SDL_HAT_LEFT; + inc(k, 4); + end; + for i:= 0 to Pred(ControllerNumButtons[j]) do + begin + tkbdn[k]:= ControllerButtons[j][i]; + inc(k, 1); + end; + end; +{$ENDIF} + +// what is this final loop for? +for t:= 0 to cKeyMaxIndex do + tkbd[t]:= tkbdn[t] +end; + +procedure InitKbdKeyTable; +var i, j, k, t: LongInt; + s: string[15]; +begin +//TODO in sdl13 this overrides some values (A and B) change indices to some other values at the back perhaps? +KeyNames[1]:= 'mousel'; +KeyNames[2]:= 'mousem'; +KeyNames[3]:= 'mouser'; +KeyNames[4]:= 'wheelup'; +KeyNames[5]:= 'wheeldown'; + +for i:= 6 to cKeyMaxIndex do + begin +{$IFDEF SDL13} + s:= shortstring(SDL_GetScancodeName(i)); +{$ELSE} + s:= shortstring(sdl_getkeyname(i)); +{$ENDIF} + WriteToConsole(IntToStr(i) + ': ' + s + ' ' + IntToStr(cKeyMaxIndex)); + if s = 'unknown key' then KeyNames[i]:= '' + else + begin + for t:= 1 to Length(s) do + if s[t] = ' ' then + s[t]:= '_'; + KeyNames[i]:= LowerCase(s) + end; + end; + +quitKeyCode:= KeyNameToCode('q'); + +// get the size of keyboard array +SDL_GetKeyState(@k); + +// Controller(s) +for j:= 0 to Pred(ControllerNumControllers) do + begin + for i:= 0 to Pred(ControllerNumAxes[j]) do + begin + keynames[k + 0]:= 'j' + IntToStr(j) + 'a' + IntToStr(i) + 'u'; + keynames[k + 1]:= 'j' + IntToStr(j) + 'a' + IntToStr(i) + 'd'; + inc(k, 2); + end; + for i:= 0 to Pred(ControllerNumHats[j]) do + begin + keynames[k + 0]:= 'j' + IntToStr(j) + 'h' + IntToStr(i) + 'u'; + keynames[k + 1]:= 'j' + IntToStr(j) + 'h' + IntToStr(i) + 'r'; + keynames[k + 2]:= 'j' + IntToStr(j) + 'h' + IntToStr(i) + 'd'; + keynames[k + 3]:= 'j' + IntToStr(j) + 'h' + IntToStr(i) + 'l'; + inc(k, 4); + end; + for i:= 0 to Pred(ControllerNumButtons[j]) do + begin + keynames[k]:= 'j' + IntToStr(j) + 'b' + IntToStr(i); + inc(k, 1); + end; + end; + +DefaultBinds[KeyNameToCode('escape')]:= 'quit'; +DefaultBinds[KeyNameToCode('grave')]:= 'history'; +DefaultBinds[KeyNameToCode('delete')]:= 'rotmask'; + +//numpad +//DefaultBinds[265]:= '+volup'; +//DefaultBinds[256]:= '+voldown'; + +DefaultBinds[KeyNameToCode('0')]:= '+volup'; +DefaultBinds[KeyNameToCode('9')]:= '+voldown'; +DefaultBinds[KeyNameToCode('c')]:= 'capture'; +DefaultBinds[KeyNameToCode('h')]:= 'findhh'; +DefaultBinds[KeyNameToCode('p')]:= 'pause'; +DefaultBinds[KeyNameToCode('s')]:= '+speedup'; +DefaultBinds[KeyNameToCode('t')]:= 'chat'; +DefaultBinds[KeyNameToCode('y')]:= 'confirm'; + +DefaultBinds[KeyNameToCode('mousem')]:= 'zoomreset'; +DefaultBinds[KeyNameToCode('wheelup')]:= 'zoomout'; +DefaultBinds[KeyNameToCode('wheeldown')]:= 'zoomin'; + +DefaultBinds[KeyNameToCode('f12')]:= 'fullscr'; + + +DefaultBinds[KeyNameToCode('mousel')]:= '/put'; +DefaultBinds[KeyNameToCode('mouser')]:= 'ammomenu'; +DefaultBinds[KeyNameToCode('backspace')]:= 'hjump'; +DefaultBinds[KeyNameToCode('tab')]:= 'switch'; +DefaultBinds[KeyNameToCode('return')]:= 'ljump'; +DefaultBinds[KeyNameToCode('space')]:= '+attack'; +DefaultBinds[KeyNameToCode('up')]:= '+up'; +DefaultBinds[KeyNameToCode('down')]:= '+down'; +DefaultBinds[KeyNameToCode('left')]:= '+left'; +DefaultBinds[KeyNameToCode('right')]:= '+right'; +DefaultBinds[KeyNameToCode('left_shift')]:= '+precise'; + +for i:= 1 to 10 do DefaultBinds[KeyNameToCode('f'+IntToStr(i))]:= 'slot '+IntToStr(i); +for i:= 1 to 5 do DefaultBinds[KeyNameToCode(IntToStr(i))]:= 'timer '+IntToStr(i); + +SetDefaultBinds(); +end; + +procedure SetBinds(var binds: TBinds); +begin +{$IFDEF MOBILE} + binds:= binds; // avoid hint + CurrentBinds:= DefaultBinds; +{$ELSE} + CurrentBinds:= binds; +{$ENDIF} +end; + +procedure SetDefaultBinds; +begin + CurrentBinds:= DefaultBinds; +end; + +procedure FreezeEnterKey; +begin + tkbd[3]:= 1; + tkbd[13]:= 1; + tkbd[27]:= 1; + tkbd[271]:= 1; +end; + +var Controller: array [0..5] of PSDL_Joystick; + +procedure ControllerInit; +var i, j: Integer; +begin +ControllerEnabled:= 0; +{$IFDEF MOBILE} +exit; // joystick subsystem disabled on iPhone +{$ENDIF} + +SDL_InitSubSystem(SDL_INIT_JOYSTICK); +ControllerNumControllers:= SDL_NumJoysticks(); + +if ControllerNumControllers > 6 then + ControllerNumControllers:= 6; + +WriteLnToConsole('Number of game controllers: ' + IntToStr(ControllerNumControllers)); + +if ControllerNumControllers > 0 then + begin + for j:= 0 to pred(ControllerNumControllers) do + begin + WriteLnToConsole('Using game controller: ' + SDL_JoystickName(j)); + Controller[j]:= SDL_JoystickOpen(j); + if Controller[j] = nil then + WriteLnToConsole('* Failed to open game controller!') + else + begin + ControllerNumAxes[j]:= SDL_JoystickNumAxes(Controller[j]); + //ControllerNumBalls[j]:= SDL_JoystickNumBalls(Controller[j]); + ControllerNumHats[j]:= SDL_JoystickNumHats(Controller[j]); + ControllerNumButtons[j]:= SDL_JoystickNumButtons(Controller[j]); + WriteLnToConsole('* Number of axes: ' + IntToStr(ControllerNumAxes[j])); + //WriteLnToConsole('* Number of balls: ' + IntToStr(ControllerNumBalls[j])); + WriteLnToConsole('* Number of hats: ' + IntToStr(ControllerNumHats[j])); + WriteLnToConsole('* Number of buttons: ' + IntToStr(ControllerNumButtons[j])); + ControllerEnabled:= 1; + + if ControllerNumAxes[j] > 20 then + ControllerNumAxes[j]:= 20; + //if ControllerNumBalls[j] > 20 then ControllerNumBalls[j]:= 20; + + if ControllerNumHats[j] > 20 then + ControllerNumHats[j]:= 20; + + if ControllerNumButtons[j] > 20 then + ControllerNumButtons[j]:= 20; + + // reset all buttons/axes + for i:= 0 to pred(ControllerNumAxes[j]) do + ControllerAxes[j][i]:= 0; + (*for i:= 0 to pred(ControllerNumBalls[j]) do + begin + ControllerBalls[j][i][0]:= 0; + ControllerBalls[j][i][1]:= 0; + end;*) + for i:= 0 to pred(ControllerNumHats[j]) do + ControllerHats[j][i]:= SDL_HAT_CENTERED; + for i:= 0 to pred(ControllerNumButtons[j]) do + ControllerButtons[j][i]:= 0; + end; + end; + // enable event generation/controller updating + SDL_JoystickEventState(1); + end +else + WriteLnToConsole('Not using any game controller'); +end; + +procedure ControllerClose; +var j: Integer; +begin + if ControllerEnabled > 0 then + for j:= 0 to pred(ControllerNumControllers) do + SDL_JoystickClose(Controller[j]); +end; + +procedure ControllerAxisEvent(joy, axis: Byte; value: Integer); +begin + ControllerAxes[joy][axis]:= value; +end; + +procedure ControllerHatEvent(joy, hat, value: Byte); +begin + ControllerHats[joy][hat]:= value; +end; + +procedure ControllerButtonEvent(joy, button: Byte; pressed: Boolean); +begin + if pressed then + ControllerButtons[joy][button]:= 1 + else + ControllerButtons[joy][button]:= 0; +end; + +procedure initModule; +begin + wheelUp:= false; + wheelDown:= false; +end; + +procedure freeModule; +begin + +end; + +end. diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uKeys.pas --- a/hedgewars/uKeys.pas Sun Apr 01 15:23:34 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,539 +0,0 @@ -(* - * Hedgewars, a free turn based strategy game - * Copyright (c) 2004-2012 Andrey Korotaev - * - * 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 "options.inc"} - -unit uKeys; -interface -uses SDLh, uTypes; - -procedure initModule; -procedure freeModule; - -function KeyNameToCode(name: shortstring): word; -procedure ProcessKbd; -procedure ResetKbd; -procedure FreezeEnterKey; -procedure InitKbdKeyTable; - -procedure SetBinds(var binds: TBinds); -procedure SetDefaultBinds; - -procedure ControllerInit; -procedure ControllerClose; -procedure ControllerAxisEvent(joy, axis: Byte; value: Integer); -procedure ControllerHatEvent(joy, hat, value: Byte); -procedure ControllerButtonEvent(joy, button: Byte; pressed: Boolean); - -{$IFDEF MOBILE} -procedure setiPhoneBinds; -{$ENDIF} - -implementation -uses uConsole, uCommands, uMisc, uVariables, uConsts, uUtils, uDebug; - -var tkbd, tkbdn: TKeyboardState; - KeyNames: array [0..cKeyMaxIndex] of string[15]; - -function KeyNameToCode(name: shortstring): word; -var code: Word; -begin - code:= cKeyMaxIndex; - while (code > 0) and (KeyNames[code] <> name) do dec(code); - KeyNameToCode:= code; -end; - - -procedure ProcessKbd; -var i, j, k: LongInt; - s: shortstring; - Trusted: boolean; -{$IFNDEF MOBILE}pkbd: PByteArray;{$ENDIF} -begin -hideAmmoMenu:= false; -Trusted:= (CurrentTeam <> nil) - and (not CurrentTeam^.ExtDriven) - and (CurrentHedgehog^.BotLevel = 0); - -// move cursor/camera -// TODO: Scale on screen dimensions and/or axis value (game controller)? -movecursor(5 * CursorMovementX, 5 * CursorMovementY); - -k:= SDL_GetMouseState(nil, nil); - -{$IFDEF MOBILE} -SDL_GetKeyState(@j); -{$ELSE} -pkbd:= SDL_GetKeyState(@j); -for i:= 6 to pred(j) do // first 6 will be overwritten - tkbdn[i]:= pkbd^[i]; -{$ENDIF} - -// mouse buttons -{$IFDEF DARWIN} -tkbdn[1]:= ((k and 1) and not (tkbdn[306] or tkbdn[305])); -tkbdn[3]:= ((k and 1) and (tkbdn[306] or tkbdn[305])) or (k and 4); -{$ELSE} -tkbdn[1]:= (k and 1); -tkbdn[3]:= ((k shr 2) and 1); -{$ENDIF} -tkbdn[2]:= ((k shr 1) and 1); - -// mouse wheels -tkbdn[4]:= ord(wheelDown); -tkbdn[5]:= ord(wheelUp); -wheelUp:= false; -wheelDown:= false; - -{$IFDEF MOBILE} -setiPhoneBinds(); -{$ELSE} -// Controller(s) -k:= j; // should we test k for hitting the limit? sounds rather unlikely to ever reach it -for j:= 0 to Pred(ControllerNumControllers) do - begin - for i:= 0 to Pred(ControllerNumAxes[j]) do - begin - if ControllerAxes[j][i] > 20000 then - tkbdn[k + 0]:= 1 - else - tkbdn[k + 0]:= 0; - if ControllerAxes[j][i] < -20000 then - tkbdn[k + 1]:= 1 - else - tkbdn[k + 1]:= 0; - inc(k, 2); - end; - for i:= 0 to Pred(ControllerNumHats[j]) do - begin - tkbdn[k + 0]:= ControllerHats[j][i] and SDL_HAT_UP; - tkbdn[k + 1]:= ControllerHats[j][i] and SDL_HAT_RIGHT; - tkbdn[k + 2]:= ControllerHats[j][i] and SDL_HAT_DOWN; - tkbdn[k + 3]:= ControllerHats[j][i] and SDL_HAT_LEFT; - inc(k, 4); - end; - for i:= 0 to Pred(ControllerNumButtons[j]) do - begin - tkbdn[k]:= ControllerButtons[j][i]; - inc(k, 1); - end; - end; -{$ENDIF} - -// ctrl/cmd + q to close engine and frontend -{$IFDEF DARWIN} - if ((tkbdn[KeyNameToCode('left_meta')] = 1) or (tkbdn[KeyNameToCode('right_meta')] = 1)) then - {$ELSE} - if ((tkbdn[KeyNameToCode('left_ctrl')] = 1) or (tkbdn[KeyNameToCode('right_ctrl')] = 1)) then - {$ENDIF} - begin - if tkbdn[KeyNameToCode('q')] = 1 then ParseCommand ('halt', true) - end; - -// now process strokes -for i:= 0 to cKeyMaxIndex do -if CurrentBinds[i][0] <> #0 then - begin - if (i > 3) and (tkbdn[i] <> 0) and not ((CurrentBinds[i] = 'put') or (CurrentBinds[i] = 'ammomenu') or (CurrentBinds[i] = '+cur_u') or (CurrentBinds[i] = '+cur_d') or (CurrentBinds[i] = '+cur_l') or (CurrentBinds[i] = '+cur_r')) then hideAmmoMenu:= true; - if (tkbd[i] = 0) and (tkbdn[i] <> 0) then - begin - ParseCommand(CurrentBinds[i], Trusted); - if (CurrentTeam <> nil) and (not CurrentTeam^.ExtDriven) and (ReadyTimeLeft > 1) then - ParseCommand('gencmd R', true) - end - else if (CurrentBinds[i][1] = '+') and (tkbdn[i] = 0) and (tkbd[i] <> 0) then - begin - s:= CurrentBinds[i]; - s[1]:= '-'; - ParseCommand(s, Trusted); - if (CurrentTeam <> nil) and (not CurrentTeam^.ExtDriven) and (ReadyTimeLeft > 1) then - ParseCommand('gencmd R', true) - end; - tkbd[i]:= tkbdn[i] - end -end; - -procedure ResetKbd; -var j, k, t: LongInt; -{$IFNDEF MOBILE} - i: LongInt; - pkbd: PByteArray; -{$ENDIF} -begin - -k:= SDL_GetMouseState(nil, nil); -{$IFNDEF MOBILE}pkbd:={$ENDIF}SDL_GetKeyState(@j); - -TryDo(j < cKeyMaxIndex, 'SDL keys number is more than expected (' + IntToStr(j) + ')', true); - -{$IFNDEF MOBILE} -for i:= 1 to pred(j) do - tkbdn[i]:= pkbd^[i]; -{$ENDIF} - -// mouse buttons -{$IFDEF DARWIN} -tkbdn[1]:= ((k and 1) and not (tkbdn[306] or tkbdn[305])); -tkbdn[3]:= ((k and 1) and (tkbdn[306] or tkbdn[305])) or (k and 4); -{$ELSE} -tkbdn[1]:= (k and 1); -tkbdn[3]:= ((k shr 2) and 1); -{$ENDIF} -tkbdn[2]:= ((k shr 1) and 1); - -// mouse wheels -tkbdn[4]:= ord(wheelDown); -tkbdn[5]:= ord(wheelUp); -wheelUp:= false; -wheelDown:= false; - -{$IFDEF MOBILE} -setiPhoneBinds(); -{$ELSE} -// Controller(s) -k:= j; // should we test k for hitting the limit? sounds rather unlikely to ever reach it -for j:= 0 to Pred(ControllerNumControllers) do - begin - for i:= 0 to Pred(ControllerNumAxes[j]) do - begin - if ControllerAxes[j][i] > 20000 then - tkbdn[k + 0]:= 1 - else - tkbdn[k + 0]:= 0; - if ControllerAxes[j][i] < -20000 then - tkbdn[k + 1]:= 1 - else - tkbdn[k + 1]:= 0; - inc(k, 2); - end; - for i:= 0 to Pred(ControllerNumHats[j]) do - begin - tkbdn[k + 0]:= ControllerHats[j][i] and SDL_HAT_UP; - tkbdn[k + 1]:= ControllerHats[j][i] and SDL_HAT_RIGHT; - tkbdn[k + 2]:= ControllerHats[j][i] and SDL_HAT_DOWN; - tkbdn[k + 3]:= ControllerHats[j][i] and SDL_HAT_LEFT; - inc(k, 4); - end; - for i:= 0 to Pred(ControllerNumButtons[j]) do - begin - tkbdn[k]:= ControllerButtons[j][i]; - inc(k, 1); - end; - end; -{$ENDIF} - -// what is this final loop for? -for t:= 0 to cKeyMaxIndex do - tkbd[t]:= tkbdn[t] -end; - -procedure InitKbdKeyTable; -var i, j, k, t: LongInt; - s: string[15]; -begin -KeyNames[1]:= 'mousel'; -KeyNames[2]:= 'mousem'; -KeyNames[3]:= 'mouser'; -KeyNames[4]:= 'wheelup'; -KeyNames[5]:= 'wheeldown'; - -for i:= 6 to cKeyMaxIndex do - begin - s:= shortstring(sdl_getkeyname(i)); - //writeln(stdout,IntToStr(i) + ': ' + s); - if s = 'unknown key' then KeyNames[i]:= '' - else - begin - for t:= 1 to Length(s) do - if s[t] = ' ' then - s[t]:= '_'; - KeyNames[i]:= s - end; - end; - -//for i:= 0 to cKeyMaxIndex do writeln(stdout,IntToStr(i) + ': ' + KeyNames[i]); - -// get the size of keyboard array -SDL_GetKeyState(@k); - -// Controller(s) -for j:= 0 to Pred(ControllerNumControllers) do - begin - for i:= 0 to Pred(ControllerNumAxes[j]) do - begin - keynames[k + 0]:= 'j' + IntToStr(j) + 'a' + IntToStr(i) + 'u'; - keynames[k + 1]:= 'j' + IntToStr(j) + 'a' + IntToStr(i) + 'd'; - inc(k, 2); - end; - for i:= 0 to Pred(ControllerNumHats[j]) do - begin - keynames[k + 0]:= 'j' + IntToStr(j) + 'h' + IntToStr(i) + 'u'; - keynames[k + 1]:= 'j' + IntToStr(j) + 'h' + IntToStr(i) + 'r'; - keynames[k + 2]:= 'j' + IntToStr(j) + 'h' + IntToStr(i) + 'd'; - keynames[k + 3]:= 'j' + IntToStr(j) + 'h' + IntToStr(i) + 'l'; - inc(k, 4); - end; - for i:= 0 to Pred(ControllerNumButtons[j]) do - begin - keynames[k]:= 'j' + IntToStr(j) + 'b' + IntToStr(i); - inc(k, 1); - end; - end; - -DefaultBinds[ 27]:= 'quit'; -DefaultBinds[ 96]:= 'history'; -DefaultBinds[127]:= 'rotmask'; - -//numpad -//DefaultBinds[265]:= '+volup'; -//DefaultBinds[256]:= '+voldown'; - -DefaultBinds[KeyNameToCode('0')]:= '+volup'; -DefaultBinds[KeyNameToCode('9')]:= '+voldown'; -DefaultBinds[KeyNameToCode('c')]:= 'capture'; -DefaultBinds[KeyNameToCode('h')]:= 'findhh'; -DefaultBinds[KeyNameToCode('p')]:= 'pause'; -DefaultBinds[KeyNameToCode('s')]:= '+speedup'; -DefaultBinds[KeyNameToCode('t')]:= 'chat'; -DefaultBinds[KeyNameToCode('y')]:= 'confirm'; - -DefaultBinds[KeyNameToCode('mousem')]:= 'zoomreset'; -DefaultBinds[KeyNameToCode('wheelup')]:= 'zoomout'; -DefaultBinds[KeyNameToCode('wheeldown')]:= 'zoomin'; - -DefaultBinds[KeyNameToCode('f12')]:= 'fullscr'; - - -DefaultBinds[ 1]:= '/put'; -DefaultBinds[ 3]:= 'ammomenu'; -DefaultBinds[ 8]:= 'hjump'; -DefaultBinds[ 9]:= 'switch'; -DefaultBinds[13]:= 'ljump'; -DefaultBinds[32]:= '+attack'; -{$IFDEF MOBILE} -DefaultBinds[23]:= '+up'; -DefaultBinds[24]:= '+down'; -DefaultBinds[25]:= '+left'; -DefaultBinds[26]:= '+right'; -DefaultBinds[27]:= '+precise'; -DefaultBinds[44]:= 'chat'; -DefaultBinds[55]:= 'pause'; -{$ELSE} -DefaultBinds[KeyNameToCode('up')]:= '+up'; -DefaultBinds[KeyNameToCode('down')]:= '+down'; -DefaultBinds[KeyNameToCode('left')]:= '+left'; -DefaultBinds[KeyNameToCode('right')]:= '+right'; -DefaultBinds[KeyNameToCode('left_shift')]:= '+precise'; -{$ENDIF} - -for i:= 1 to 10 do DefaultBinds[KeyNameToCode('f'+IntToStr(i))]:= 'slot '+IntToStr(i); -for i:= 1 to 5 do DefaultBinds[KeyNameToCode(IntToStr(i))]:= 'timer '+IntToStr(i); - -SetDefaultBinds(); -end; - -procedure SetBinds(var binds: TBinds); -begin -{$IFDEF MOBILE} - binds:= binds; // avoid hint - CurrentBinds:= DefaultBinds; -{$ELSE} - CurrentBinds:= binds; -{$ENDIF} -end; - -procedure SetDefaultBinds; -begin - CurrentBinds:= DefaultBinds; -end; - -{$IFDEF MOBILE} -procedure setiPhoneBinds; -begin - tkbdn[ 1]:= ord(leftClick); - tkbdn[ 2]:= ord(middleClick); - tkbdn[ 3]:= ord(rightClick); - - tkbdn[23]:= ord(upKey); - tkbdn[24]:= ord(downKey); - tkbdn[25]:= ord(leftKey); - tkbdn[26]:= ord(rightKey); - tkbdn[27]:= ord(preciseKey); - - tkbdn[ 8]:= ord(backspaceKey); - tkbdn[ 9]:= ord(tabKey); - tkbdn[13]:= ord(enterKey); - tkbdn[32]:= ord(spaceKey); - - tkbdn[44]:= ord(chatAction); - tkbdn[55]:= ord(pauseAction); - - // set to false the keys that only need one stoke - leftClick:= false; - middleClick:= false; - rightClick:= false; - - tabKey:= false; - enterKey:= false; - backspaceKey:= false; - - chatAction:= false; - pauseAction:= false; -end; -{$ENDIF} - -procedure FreezeEnterKey; -begin - tkbd[3]:= 1; - tkbd[13]:= 1; - tkbd[27]:= 1; - tkbd[271]:= 1; -end; - -var Controller: array [0..5] of PSDL_Joystick; - -procedure ControllerInit; -var i, j: Integer; -begin -ControllerEnabled:= 0; -{$IFDEF MOBILE} -exit; // joystick subsystem disabled on iPhone -{$ENDIF} - -SDL_InitSubSystem(SDL_INIT_JOYSTICK); -ControllerNumControllers:= SDL_NumJoysticks(); - -if ControllerNumControllers > 6 then - ControllerNumControllers:= 6; - -WriteLnToConsole('Number of game controllers: ' + IntToStr(ControllerNumControllers)); - -if ControllerNumControllers > 0 then - begin - for j:= 0 to pred(ControllerNumControllers) do - begin - WriteLnToConsole('Using game controller: ' + SDL_JoystickName(j)); - Controller[j]:= SDL_JoystickOpen(j); - if Controller[j] = nil then - WriteLnToConsole('* Failed to open game controller!') - else - begin - ControllerNumAxes[j]:= SDL_JoystickNumAxes(Controller[j]); - //ControllerNumBalls[j]:= SDL_JoystickNumBalls(Controller[j]); - ControllerNumHats[j]:= SDL_JoystickNumHats(Controller[j]); - ControllerNumButtons[j]:= SDL_JoystickNumButtons(Controller[j]); - WriteLnToConsole('* Number of axes: ' + IntToStr(ControllerNumAxes[j])); - //WriteLnToConsole('* Number of balls: ' + IntToStr(ControllerNumBalls[j])); - WriteLnToConsole('* Number of hats: ' + IntToStr(ControllerNumHats[j])); - WriteLnToConsole('* Number of buttons: ' + IntToStr(ControllerNumButtons[j])); - ControllerEnabled:= 1; - - if ControllerNumAxes[j] > 20 then - ControllerNumAxes[j]:= 20; - //if ControllerNumBalls[j] > 20 then ControllerNumBalls[j]:= 20; - - if ControllerNumHats[j] > 20 then - ControllerNumHats[j]:= 20; - - if ControllerNumButtons[j] > 20 then - ControllerNumButtons[j]:= 20; - - // reset all buttons/axes - for i:= 0 to pred(ControllerNumAxes[j]) do - ControllerAxes[j][i]:= 0; - (*for i:= 0 to pred(ControllerNumBalls[j]) do - begin - ControllerBalls[j][i][0]:= 0; - ControllerBalls[j][i][1]:= 0; - end;*) - for i:= 0 to pred(ControllerNumHats[j]) do - ControllerHats[j][i]:= SDL_HAT_CENTERED; - for i:= 0 to pred(ControllerNumButtons[j]) do - ControllerButtons[j][i]:= 0; - end; - end; - // enable event generation/controller updating - SDL_JoystickEventState(1); - end -else - WriteLnToConsole('Not using any game controller'); -end; - -procedure ControllerClose; -var j: Integer; -begin - if ControllerEnabled > 0 then - for j:= 0 to pred(ControllerNumControllers) do - SDL_JoystickClose(Controller[j]); -end; - -procedure ControllerAxisEvent(joy, axis: Byte; value: Integer); -begin - ControllerAxes[joy][axis]:= value; -end; - -procedure ControllerHatEvent(joy, hat, value: Byte); -begin - ControllerHats[joy][hat]:= value; -end; - -procedure ControllerButtonEvent(joy, button: Byte; pressed: Boolean); -begin - if pressed then - ControllerButtons[joy][button]:= 1 - else - ControllerButtons[joy][button]:= 0; -end; - -procedure initModule; -begin - wheelUp:= false; - wheelDown:= false; -{$IFDEF HWLIBRARY} - // this function is called by HW_allKeysUp so be careful - - // mouse emulation - leftClick:= false; - middleClick:= false; - rightClick:= false; - - // arrow key emulation - upKey:= false; - downKey:= false; - rightKey:= false; - leftKey:= false; - preciseKey:= false; - - // action key emulation - backspaceKey:= false; - spaceKey:= false; - enterKey:= false; - tabKey:= false; - - // other key emulation - chatAction:= false; - pauseAction:= false; -{$ENDIF} -end; - -procedure freeModule; -begin - -end; - -end. diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uLand.pas --- a/hedgewars/uLand.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uLand.pas Wed May 02 23:53:45 2012 +0200 @@ -57,7 +57,7 @@ // freed in freeModule() below LandBackSurface:= LoadImage(UserPathz[ptCurrTheme] + '/LandBackTex', ifIgnoreCaps or ifTransparent); if LandBackSurface = nil then LandBackSurface:= LoadImage(Pathz[ptCurrTheme] + '/LandBackTex', ifIgnoreCaps or ifTransparent); - if (LandBackSurface <> nil) and cGrayScale then Surface2GrayScale(LandBackSurface); + if (LandBackSurface <> nil) and GrayScale then Surface2GrayScale(LandBackSurface); tmpsurf:= LoadImage(UserPathz[ptCurrTheme] + '/Border', ifIgnoreCaps or ifTransparent); if tmpsurf = nil then tmpsurf:= LoadImage(Pathz[ptCurrTheme] + '/Border', ifCritical or ifIgnoreCaps or ifTransparent); @@ -458,7 +458,7 @@ LandBackSurface:= LoadImage(UserPathz[ptCurrTheme] + '/LandBackTex', ifIgnoreCaps or ifTransparent); if LandBackSurface = nil then LandBackSurface:= LoadImage(Pathz[ptCurrTheme] + '/LandBackTex', ifIgnoreCaps or ifTransparent); - if (LandBackSurface <> nil) and cGrayScale then + if (LandBackSurface <> nil) and GrayScale then Surface2GrayScale(LandBackSurface) end; end; @@ -647,7 +647,7 @@ FreeLandObjects; -if cGrayScale then +if GrayScale then begin if (cReducedQuality and rqBlurryLand) = 0 then for x:= leftX to rightX do @@ -728,7 +728,7 @@ begin adler:= 1; for i:= 0 to LAND_HEIGHT-1 do - Adler32Update(adler, @Land[i,0], LAND_WIDTH); + adler:= Adler32Update(adler, @Land[i,0], LAND_WIDTH); s:= 'M' + IntToStr(adler) + cScriptName; chLandCheck(s); @@ -737,8 +737,8 @@ procedure initModule; begin - RegisterVariable('landcheck', vtCommand, @chLandCheck, false); - RegisterVariable('sendlanddigest', vtCommand, @chSendLandDigest, false); + RegisterVariable('landcheck', @chLandCheck, false); + RegisterVariable('sendlanddigest', @chSendLandDigest, false); LandBackSurface:= nil; digest:= ''; diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uLandGraphics.pas --- a/hedgewars/uLandGraphics.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uLandGraphics.pas Wed May 02 23:53:45 2012 +0200 @@ -328,9 +328,9 @@ if ((Land[t, i] and lfBasic) <> 0) or ((Land[t, i] and lfObject) <> 0) then begin if (cReducedQuality and rqBlurryLand) = 0 then - LandPixels[t, i]:= cExplosionBorderColor + LandPixels[t, i]:= ExplosionBorderColor else - LandPixels[t div 2, i div 2]:= cExplosionBorderColor; + LandPixels[t div 2, i div 2]:= ExplosionBorderColor; Land[t, i]:= Land[t, i] or lfDamaged; //Despeckle(i, t); @@ -343,9 +343,9 @@ if ((Land[t, i] and lfBasic) <> 0) or ((Land[t, i] and lfObject) <> 0) then begin if (cReducedQuality and rqBlurryLand) = 0 then - LandPixels[t, i]:= cExplosionBorderColor + LandPixels[t, i]:= ExplosionBorderColor else - LandPixels[t div 2, i div 2]:= cExplosionBorderColor; + LandPixels[t div 2, i div 2]:= ExplosionBorderColor; Land[t, i]:= Land[t, i] or lfDamaged; //Despeckle(i, t); LandDirty[t div 32, i div 32]:= 1; @@ -357,9 +357,9 @@ if ((Land[t, i] and lfBasic) <> 0) or ((Land[t, i] and lfObject) <> 0) then begin if (cReducedQuality and rqBlurryLand) = 0 then - LandPixels[t, i]:= cExplosionBorderColor + LandPixels[t, i]:= ExplosionBorderColor else - LandPixels[t div 2, i div 2]:= cExplosionBorderColor; + LandPixels[t div 2, i div 2]:= ExplosionBorderColor; Land[t, i]:= Land[t, i] or lfDamaged; //Despeckle(i, t); @@ -372,9 +372,9 @@ if ((Land[t, i] and lfBasic) <> 0) or ((Land[t, i] and lfObject) <> 0) then begin if (cReducedQuality and rqBlurryLand) = 0 then - LandPixels[t, i]:= cExplosionBorderColor + LandPixels[t, i]:= ExplosionBorderColor else - LandPixels[t div 2, i div 2]:= cExplosionBorderColor; + LandPixels[t div 2, i div 2]:= ExplosionBorderColor; Land[t, i]:= Land[t, i] or lfDamaged; //Despeckle(i, y - dy); @@ -503,9 +503,9 @@ if ((Land[ty, tx] and lfBasic) <> 0) or ((Land[ty, tx] and lfObject) <> 0) then begin if (cReducedQuality and rqBlurryLand) = 0 then - LandPixels[ty, tx]:= cExplosionBorderColor + LandPixels[ty, tx]:= ExplosionBorderColor else - LandPixels[ty div 2, tx div 2]:= cExplosionBorderColor; + LandPixels[ty div 2, tx div 2]:= ExplosionBorderColor; Land[ty, tx]:= Land[ty, tx] or lfDamaged; LandDirty[ty div 32, tx div 32]:= 1; @@ -555,9 +555,9 @@ LandDirty[ty div 32, tx div 32]:= 1 end; if (cReducedQuality and rqBlurryLand) = 0 then - LandPixels[ty, tx]:= cExplosionBorderColor + LandPixels[ty, tx]:= ExplosionBorderColor else - LandPixels[ty div 2, tx div 2]:= cExplosionBorderColor + LandPixels[ty div 2, tx div 2]:= ExplosionBorderColor end end; nx:= nx - dY; @@ -581,9 +581,9 @@ if despeckle then LandDirty[ty div 32, tx div 32]:= 1; if (cReducedQuality and rqBlurryLand) = 0 then - LandPixels[ty, tx]:= cExplosionBorderColor + LandPixels[ty, tx]:= ExplosionBorderColor else - LandPixels[ty div 2, tx div 2]:= cExplosionBorderColor + LandPixels[ty div 2, tx div 2]:= ExplosionBorderColor end end; X:= nx; @@ -624,9 +624,9 @@ if despeckle then LandDirty[ty div 32, tx div 32]:= 1; if (cReducedQuality and rqBlurryLand) = 0 then - LandPixels[ty, tx]:= cExplosionBorderColor + LandPixels[ty, tx]:= ExplosionBorderColor else - LandPixels[ty div 2, tx div 2]:= cExplosionBorderColor + LandPixels[ty div 2, tx div 2]:= ExplosionBorderColor end end; nx:= nx - dY; @@ -650,9 +650,9 @@ if despeckle then LandDirty[ty div 32, tx div 32]:= 1; if (cReducedQuality and rqBlurryLand) = 0 then - LandPixels[ty, tx]:= cExplosionBorderColor + LandPixels[ty, tx]:= ExplosionBorderColor else - LandPixels[ty div 2, tx div 2]:= cExplosionBorderColor + LandPixels[ty div 2, tx div 2]:= ExplosionBorderColor end end; nx:= nx - dY; @@ -672,6 +672,7 @@ p: PByteArray; Image: PSDL_Surface; begin +TryPlaceOnLand:= false; numFramesFirstCol:= SpritesData[Obj].imageHeight div SpritesData[Obj].Height; TryDo(SpritesData[Obj].Surface <> nil, 'Assert SpritesData[Obj].Surface failed', true); @@ -693,12 +694,12 @@ begin for x:= 0 to Pred(w) do if (PLongword(@(p^[x * 4]))^) <> 0 then - if ((cpY + y) <= Longint(topY)) or ((cpY + y) >= LAND_HEIGHT) - or ((cpX + x) <= Longint(leftX)) or ((cpX + x) >= Longint(rightX)) or (Land[cpY + y, cpX + x] <> 0) then + if ((cpY + y) <= Longint(topY)) or ((cpY + y) >= LAND_HEIGHT) or + ((cpX + x) <= Longint(leftX)) or ((cpX + x) >= Longint(rightX)) or (Land[cpY + y, cpX + x] <> 0) then begin - if SDL_MustLock(Image) then - SDL_UnlockSurface(Image); - exit(false) + if SDL_MustLock(Image) then + SDL_UnlockSurface(Image); + exit; end; p:= @(p^[Image^.pitch]); end; @@ -758,58 +759,61 @@ var nx, ny, i, j, c, xx, yy: LongInt; pixelsweep: boolean; begin -if (cReducedQuality and rqBlurryLand) = 0 then + Despeckle:= true; + + if (cReducedQuality and rqBlurryLand) = 0 then begin - xx:= X; - yy:= Y; + xx:= X; + yy:= Y; end -else + else begin - xx:= X div 2; - yy:= Y div 2; + xx:= X div 2; + yy:= Y div 2; end; -pixelsweep:= ((Land[Y, X] and $FF00) = 0) and (LandPixels[yy, xx] <> 0); -if (((Land[Y, X] and lfDamaged) <> 0) and ((Land[Y, X] and lfIndestructible) = 0)) or pixelsweep then + + pixelsweep:= ((Land[Y, X] and $FF00) = 0) and (LandPixels[yy, xx] <> 0); + if (((Land[Y, X] and lfDamaged) <> 0) and ((Land[Y, X] and lfIndestructible) = 0)) or pixelsweep then begin - c:= 0; - for i:= -1 to 1 do - for j:= -1 to 1 do - if (i <> 0) or (j <> 0) then + c:= 0; + for i:= -1 to 1 do + for j:= -1 to 1 do + if (i <> 0) or (j <> 0) then begin - ny:= Y + i; - nx:= X + j; - if ((ny and LAND_HEIGHT_MASK) = 0) and ((nx and LAND_WIDTH_MASK) = 0) then + ny:= Y + i; + nx:= X + j; + if ((ny and LAND_HEIGHT_MASK) = 0) and ((nx and LAND_WIDTH_MASK) = 0) then begin - if pixelsweep then + if pixelsweep then begin - if ((cReducedQuality and rqBlurryLand) <> 0) then + if ((cReducedQuality and rqBlurryLand) <> 0) then begin - nx:= nx div 2; - ny:= ny div 2 + nx:= nx div 2; + ny:= ny div 2 end; - if LandPixels[ny, nx] <> 0 then - inc(c); + if LandPixels[ny, nx] <> 0 then + inc(c); end else if Land[ny, nx] > 255 then inc(c); end end; - if c < 4 then // 0-3 neighbours + if c < 4 then // 0-3 neighbours begin - if ((Land[Y, X] and lfBasic) <> 0) and (not disableLandBack) then - LandPixels[yy, xx]:= LandBackPixel(X, Y) - else - LandPixels[yy, xx]:= 0; + if ((Land[Y, X] and lfBasic) <> 0) and (not disableLandBack) then + LandPixels[yy, xx]:= LandBackPixel(X, Y) + else + LandPixels[yy, xx]:= 0; - if not pixelsweep then + if not pixelsweep then begin - Land[Y, X]:= 0; - exit(true) + Land[Y, X]:= 0; + exit end end; end; -Despeckle:= false + Despeckle:= false end; procedure Smooth(X, Y: LongInt); @@ -824,12 +828,12 @@ if (cReducedQuality and rqBlurryLand) = 0 then begin if ((LandPixels[y,x] and AMask) shr AShift) < 10 then - LandPixels[y,x]:= (cExplosionBorderColor and (not AMask)) or (128 shl AShift) + LandPixels[y,x]:= (ExplosionBorderColor and (not AMask)) or (128 shl AShift) else LandPixels[y,x]:= - (((((LandPixels[y,x] and RMask shr RShift) div 2)+((cExplosionBorderColor and RMask) shr RShift) div 2) and $FF) shl RShift) or - (((((LandPixels[y,x] and GMask shr GShift) div 2)+((cExplosionBorderColor and GMask) shr GShift) div 2) and $FF) shl GShift) or - (((((LandPixels[y,x] and BMask shr BShift) div 2)+((cExplosionBorderColor and BMask) shr BShift) div 2) and $FF) shl BShift) or ($FF shl AShift) + (((((LandPixels[y,x] and RMask shr RShift) div 2)+((ExplosionBorderColor and RMask) shr RShift) div 2) and $FF) shl RShift) or + (((((LandPixels[y,x] and GMask shr GShift) div 2)+((ExplosionBorderColor and GMask) shr GShift) div 2) and $FF) shl GShift) or + (((((LandPixels[y,x] and BMask shr BShift) div 2)+((ExplosionBorderColor and BMask) shr BShift) div 2) and $FF) shl BShift) or ($FF shl AShift) end; if (Land[y, x-1] = lfObject) then Land[y,x]:= lfObject @@ -850,12 +854,12 @@ if (cReducedQuality and rqBlurryLand) = 0 then begin if ((LandPixels[y,x] and AMask) shr AShift) < 10 then - LandPixels[y,x]:= (cExplosionBorderColor and (not AMask)) or (64 shl AShift) + LandPixels[y,x]:= (ExplosionBorderColor and (not AMask)) or (64 shl AShift) else LandPixels[y,x]:= - (((((LandPixels[y,x] and RMask shr RShift) * 3 div 4)+((cExplosionBorderColor and RMask) shr RShift) div 4) and $FF) shl RShift) or - (((((LandPixels[y,x] and GMask shr GShift) * 3 div 4)+((cExplosionBorderColor and GMask) shr GShift) div 4) and $FF) shl GShift) or - (((((LandPixels[y,x] and BMask shr BShift) * 3 div 4)+((cExplosionBorderColor and BMask) shr BShift) div 4) and $FF) shl BShift) or ($FF shl AShift) + (((((LandPixels[y,x] and RMask shr RShift) * 3 div 4)+((ExplosionBorderColor and RMask) shr RShift) div 4) and $FF) shl RShift) or + (((((LandPixels[y,x] and GMask shr GShift) * 3 div 4)+((ExplosionBorderColor and GMask) shr GShift) div 4) and $FF) shl GShift) or + (((((LandPixels[y,x] and BMask shr BShift) * 3 div 4)+((ExplosionBorderColor and BMask) shr BShift) div 4) and $FF) shl BShift) or ($FF shl AShift) end; if (Land[y, x-1] = lfObject) then Land[y, x]:= lfObject @@ -876,9 +880,9 @@ or (((Land[y, x+1] and lfDamaged) <> 0) and (((Land[y-1,x] and lfDamaged) <> 0) or ((Land[y+1,x] and lfDamaged) <> 0)))) then begin LandPixels[y,x]:= - (((((LandPixels[y,x] and RMask shr RShift) div 2)+((cExplosionBorderColor and RMask) shr RShift) div 2) and $FF) shl RShift) or - (((((LandPixels[y,x] and GMask shr GShift) div 2)+((cExplosionBorderColor and GMask) shr GShift) div 2) and $FF) shl GShift) or - (((((LandPixels[y,x] and BMask shr BShift) div 2)+((cExplosionBorderColor and BMask) shr BShift) div 2) and $FF) shl BShift) or ($FF shl AShift) + (((((LandPixels[y,x] and RMask shr RShift) div 2)+((ExplosionBorderColor and RMask) shr RShift) div 2) and $FF) shl RShift) or + (((((LandPixels[y,x] and GMask shr GShift) div 2)+((ExplosionBorderColor and GMask) shr GShift) div 2) and $FF) shl GShift) or + (((((LandPixels[y,x] and BMask shr BShift) div 2)+((ExplosionBorderColor and BMask) shr BShift) div 2) and $FF) shl BShift) or ($FF shl AShift) end else if ((((Land[y, x-1] and lfDamaged) <> 0) and ((Land[y+1,x-1] and lfDamaged) <> 0) and ((Land[y+2,x] and lfDamaged) <> 0)) or (((Land[y, x-1] and lfDamaged) <> 0) and ((Land[y-1,x-1] and lfDamaged) <> 0) and ((Land[y-2,x] and lfDamaged) <> 0)) @@ -890,9 +894,9 @@ or (((Land[y-1, x] and lfDamaged) <> 0) and ((Land[y-1,x-1] and lfDamaged) <> 0) and ((Land[y,x-2] and lfDamaged) <> 0))) then begin LandPixels[y,x]:= - (((((LandPixels[y,x] and RMask shr RShift) * 3 div 4)+((cExplosionBorderColor and RMask) shr RShift) div 4) and $FF) shl RShift) or - (((((LandPixels[y,x] and GMask shr GShift) * 3 div 4)+((cExplosionBorderColor and GMask) shr GShift) div 4) and $FF) shl GShift) or - (((((LandPixels[y,x] and BMask shr BShift) * 3 div 4)+((cExplosionBorderColor and BMask) shr BShift) div 4) and $FF) shl BShift) or ($FF shl AShift) + (((((LandPixels[y,x] and RMask shr RShift) * 3 div 4)+((ExplosionBorderColor and RMask) shr RShift) div 4) and $FF) shl RShift) or + (((((LandPixels[y,x] and GMask shr GShift) * 3 div 4)+((ExplosionBorderColor and GMask) shr GShift) div 4) and $FF) shl GShift) or + (((((LandPixels[y,x] and BMask shr BShift) * 3 div 4)+((ExplosionBorderColor and BMask) shr BShift) div 4) and $FF) shl BShift) or ($FF shl AShift) end end end; diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uLandObjects.pas --- a/hedgewars/uLandObjects.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uLandObjects.pas Wed May 02 23:53:45 2012 +0200 @@ -25,7 +25,8 @@ procedure AddObjects(); procedure FreeLandObjects(); procedure LoadThemeConfig; -procedure BlitImageAndGenerateCollisionInfo(cpX, cpY, Width: Longword; Image: PSDL_Surface; extraFlags: Word = 0); +procedure BlitImageAndGenerateCollisionInfo(cpX, cpY, Width: Longword; Image: PSDL_Surface); inline; +procedure BlitImageAndGenerateCollisionInfo(cpX, cpY, Width: Longword; Image: PSDL_Surface; extraFlags: Word); procedure AddOnLandObjects(Surface: PSDL_Surface); implementation @@ -65,8 +66,12 @@ ThemeObjects: TThemeObjects; SprayObjects: TSprayObjects; - -procedure BlitImageAndGenerateCollisionInfo(cpX, cpY, Width: Longword; Image: PSDL_Surface; extraFlags: Word = 0); +procedure BlitImageAndGenerateCollisionInfo(cpX, cpY, Width: Longword; Image: PSDL_Surface); inline; +begin + BlitImageAndGenerateCollisionInfo(cpX, cpY, Width, Image, 0); +end; + +procedure BlitImageAndGenerateCollisionInfo(cpX, cpY, Width: Longword; Image: PSDL_Surface; extraFlags: Word); var p: PLongwordArray; x, y: Longword; bpp: LongInt; @@ -296,11 +301,12 @@ cnt, i: Longword; bRes: boolean; begin +TryPut:= false; cnt:= 0; with Obj do begin if Maxcnt = 0 then - exit(false); + exit; x:= 0; repeat y:= topY+32; // leave room for a hedgie to teleport in @@ -341,11 +347,12 @@ r: TSDL_Rect; bRes: boolean; begin +TryPut:= false; cnt:= 0; with Obj do begin if Maxcnt = 0 then - exit(false); + exit; x:= 0; r.x:= 0; r.y:= 0; @@ -406,7 +413,7 @@ AddProgress; // Set default water greyscale values -if cGrayScale then +if GrayScale then begin for i:= 0 to 3 do begin @@ -461,7 +468,7 @@ SkyColor.g:= StrToInt(Trim(Copy(s, 1, Pred(i)))); Delete(s, 1, i); SkyColor.b:= StrToInt(Trim(s)); - if cGrayScale + if GrayScale then begin t:= round(SkyColor.r * RGB_LUMINANCE_RED + SkyColor.g * RGB_LUMINANCE_GREEN + SkyColor.b * RGB_LUMINANCE_BLUE); @@ -485,7 +492,7 @@ c2.g:= StrToInt(Trim(Copy(s, 1, Pred(i)))); Delete(s, 1, i); c2.b:= StrToInt(Trim(s)); - if cGrayScale then + if GrayScale then begin t:= round(SkyColor.r * RGB_LUMINANCE_RED + SkyColor.g * RGB_LUMINANCE_GREEN + SkyColor.b * RGB_LUMINANCE_BLUE); if t > 255 then @@ -494,7 +501,7 @@ c2.g:= t; c2.b:= t end; - cExplosionBorderColor:= c2.value or AMask; + ExplosionBorderColor:= c2.value or AMask; end else if key = 'water-top' then begin @@ -506,7 +513,7 @@ Delete(s, 1, i); WaterColorArray[0].b:= StrToInt(Trim(s)); WaterColorArray[0].a := 255; - if cGrayScale then + if GrayScale then begin t:= round(WaterColorArray[0].r * RGB_LUMINANCE_RED + WaterColorArray[0].g * RGB_LUMINANCE_GREEN + WaterColorArray[0].b * RGB_LUMINANCE_BLUE); if t > 255 then @@ -527,7 +534,7 @@ Delete(s, 1, i); WaterColorArray[2].b:= StrToInt(Trim(s)); WaterColorArray[2].a := 255; - if cGrayScale then + if GrayScale then begin t:= round(WaterColorArray[2].r * RGB_LUMINANCE_RED + WaterColorArray[2].g * RGB_LUMINANCE_GREEN + WaterColorArray[2].b * RGB_LUMINANCE_BLUE); if t > 255 then @@ -540,8 +547,8 @@ end else if key = 'water-opacity' then begin - cWaterOpacity:= StrToInt(Trim(s)); - cSDWaterOpacity:= cWaterOpacity + WaterOpacity:= StrToInt(Trim(s)); + SDWaterOpacity:= WaterOpacity end else if key = 'music' then MusicFN:= Trim(s) @@ -658,7 +665,7 @@ Delete(s, 1, i); SDWaterColorArray[0].b:= StrToInt(Trim(s)); SDWaterColorArray[0].a := 255; - if cGrayScale then + if GrayScale then begin t:= round(SDWaterColorArray[0].r * RGB_LUMINANCE_RED + SDWaterColorArray[0].g * RGB_LUMINANCE_GREEN + SDWaterColorArray[0].b * RGB_LUMINANCE_BLUE); if t > 255 then @@ -679,7 +686,7 @@ Delete(s, 1, i); SDWaterColorArray[2].b:= StrToInt(Trim(s)); SDWaterColorArray[2].a := 255; - if cGrayScale then + if GrayScale then begin t:= round(SDWaterColorArray[2].r * RGB_LUMINANCE_RED + SDWaterColorArray[2].g * RGB_LUMINANCE_GREEN + SDWaterColorArray[2].b * RGB_LUMINANCE_BLUE); if t > 255 then @@ -691,7 +698,7 @@ SDWaterColorArray[3]:= SDWaterColorArray[2]; end else if key = 'sd-water-opacity' then - cSDWaterOpacity:= StrToInt(Trim(s)) + SDWaterOpacity:= StrToInt(Trim(s)) else if key = 'sd-clouds' then cSDCloudsNumber:= Word(StrToInt(Trim(s))) * cScreenSpace div LAND_WIDTH else if key = 'sd-flakes' then @@ -724,7 +731,7 @@ RQSkyColor.g:= StrToInt(Trim(Copy(s, 1, Pred(i)))); Delete(s, 1, i); RQSkyColor.b:= StrToInt(Trim(s)); - if cGrayScale then + if GrayScale then begin t:= round(RQSkyColor.r * RGB_LUMINANCE_RED + RQSkyColor.g * RGB_LUMINANCE_GREEN + RQSkyColor.b * RGB_LUMINANCE_BLUE); if t > 255 then diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uLandOutline.pas --- a/hedgewars/uLandOutline.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uLandOutline.pas Wed May 02 23:53:45 2012 +0200 @@ -220,47 +220,49 @@ function CheckIntersect(V1, V2, V3, V4: TPoint): boolean; var c1, c2, dm: LongInt; begin + CheckIntersect:= false; dm:= (V4.y - V3.y) * (V2.x - V1.x) - (V4.x - V3.x) * (V2.y - V1.y); c1:= (V4.x - V3.x) * (V1.y - V3.y) - (V4.y - V3.y) * (V1.x - V3.x); if dm = 0 then - exit(false); + exit; + CheckIntersect:= true; c2:= (V2.x - V3.x) * (V1.y - V3.y) - (V2.y - V3.y) * (V1.x - V3.x); if dm > 0 then - begin + begin if (c1 < 0) or (c1 > dm) then - exit(false); - if (c2 < 0) or (c2 > dm) then - exit(false) - end + CheckIntersect:= false + else if (c2 < 0) or (c2 > dm) then + CheckIntersect:= false; + end else - begin + begin if (c1 > 0) or (c1 < dm) then - exit(false); - if (c2 > 0) or (c2 < dm) then - exit(false) - end; + CheckIntersect:= false + else if (c2 > 0) or (c2 < dm) then + CheckIntersect:= false; + end; //AddFileLog('1 (' + inttostr(V1.x) + ',' + inttostr(V1.y) + ')x(' + inttostr(V2.x) + ',' + inttostr(V2.y) + ')'); //AddFileLog('2 (' + inttostr(V3.x) + ',' + inttostr(V3.y) + ')x(' + inttostr(V4.x) + ',' + inttostr(V4.y) + ')'); - CheckIntersect:= true end; function CheckSelfIntersect(var pa: TPixAr; ind: Longword): boolean; var i: Longword; begin + CheckSelfIntersect:= false; if (ind <= 0) or (ind >= Pred(pa.Count)) then - exit(false); + exit; + + CheckSelfIntersect:= true; for i:= 1 to pa.Count - 3 do if (i <= ind - 1) or (i >= ind + 2) then begin - if (i <> ind - 1) and - CheckIntersect(pa.ar[ind], pa.ar[ind - 1], pa.ar[i], pa.ar[i - 1]) then - exit(true); - if (i <> ind + 2) and - CheckIntersect(pa.ar[ind], pa.ar[ind + 1], pa.ar[i], pa.ar[i - 1]) then - exit(true); + if (i <> ind - 1) and CheckIntersect(pa.ar[ind], pa.ar[ind - 1], pa.ar[i], pa.ar[i - 1]) then + exit; + if (i <> ind + 2) and CheckIntersect(pa.ar[ind], pa.ar[ind + 1], pa.ar[i], pa.ar[i - 1]) then + exit; end; CheckSelfIntersect:= false end; diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uLandPainted.pas --- a/hedgewars/uLandPainted.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uLandPainted.pas Wed May 02 23:53:45 2012 +0200 @@ -43,7 +43,7 @@ var pointsListHead, pointsListLast: PPointEntry; -procedure DrawLineOnLand(X1, Y1, X2, Y2, radius: LongInt); +procedure DrawLineOnLand(X1, Y1, X2, Y2, radius: LongInt; color: Longword); var eX, eY, dX, dY: LongInt; i, sX, sY, x, y, d: LongInt; b: boolean; @@ -110,7 +110,7 @@ begin inc(len); if (len mod 4) = 0 then - FillRoundInLand(X, Y, radius, lfBasic) + FillRoundInLand(X, Y, radius, color) end end end; @@ -148,6 +148,7 @@ var pe: PPointEntry; prevPoint: PointRec; radius: LongInt; + color: Longword; begin // shutup compiler prevPoint.X:= 0; @@ -161,14 +162,18 @@ begin if (pe^.point.flags and $80 <> 0) then begin - radius:= (pe^.point.flags and $7F) * 5 + 3; - AddFileLog('[DRAW] Move to: ('+inttostr(pe^.point.X)+','+inttostr(pe^.point.Y)+')'); - FillRoundInLand(pe^.point.X, pe^.point.Y, radius, lfBasic) + if (pe^.point.flags and $40 <> 0) then + color:= 0 + else + color:= lfBasic; + radius:= (pe^.point.flags and $3F) * 5 + 3; + AddFileLog('[DRAW] Move to: ('+inttostr(pe^.point.X)+','+inttostr(pe^.point.Y)+'), radius = '+inttostr(radius)); + FillRoundInLand(pe^.point.X, pe^.point.Y, radius, color) end else begin - AddFileLog('[DRAW] Line to: ('+inttostr(pe^.point.X)+','+inttostr(pe^.point.Y)+')'); - DrawLineOnLand(prevPoint.X, prevPoint.Y, pe^.point.X, pe^.point.Y, radius); + AddFileLog('[DRAW] Line to: ('+inttostr(pe^.point.X)+','+inttostr(pe^.point.Y)+'), radius = '+inttostr(radius)); + DrawLineOnLand(prevPoint.X, prevPoint.Y, pe^.point.X, pe^.point.Y, radius, color); end; prevPoint:= pe^.point; @@ -181,7 +186,7 @@ pointsListHead:= nil; pointsListLast:= nil; - RegisterVariable('draw', vtCommand, @chDraw, false); + RegisterVariable('draw', @chDraw, false); end; procedure freeModule; diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uLandTemplates.pas --- a/hedgewars/uLandTemplates.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uLandTemplates.pas Wed May 02 23:53:45 2012 +0200 @@ -1573,7 +1573,7 @@ ); //////////////////////////////////////////////////////////////////////// -const EdgeTemplates: array[0..42] of TEdgeTemplate = +var EdgeTemplates: array[0..42] of TEdgeTemplate = ( (BasePoints: @Template0Points; BasePointsCount: Succ(High(Template0Points)); diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uMisc.pas --- a/hedgewars/uMisc.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uMisc.pas Wed May 02 23:53:45 2012 +0200 @@ -1,20 +1,20 @@ (* -* Hedgewars, a free turn based strategy game -* Copyright (c) 2004-2012 Andrey Korotaev -* -* 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 -*) + * Hedgewars, a free turn based strategy game + * Copyright (c) 2004-2012 Andrey Korotaev + * + * 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 "options.inc"} @@ -23,20 +23,31 @@ uses SDLh, uConsts, GLunit, uTypes; +procedure initModule; +procedure freeModule; + procedure movecursor(dx, dy: LongInt); function doSurfaceConversion(tmpsurf: PSDL_Surface): PSDL_Surface; function MakeScreenshot(filename: shortstring): boolean; function GetTeamStatString(p: PTeam): shortstring; {$IFDEF SDL13} -function SDL_RectMake(x, y, width, height: LongInt): TSDL_Rect; +function SDL_RectMake(x, y, width, height: LongInt): TSDL_Rect; inline; {$ELSE} -function SDL_RectMake(x, y: SmallInt; width, height: Word): TSDL_Rect; +function SDL_RectMake(x, y: SmallInt; width, height: Word): TSDL_Rect; inline; {$ENDIF} -procedure initModule; -procedure freeModule; implementation -uses typinfo, sysutils, uVariables, uUtils; +uses typinfo, sysutils, uVariables, uUtils + {$IFDEF PNG_SCREENSHOTS}, PNGh, png {$ENDIF} + {$IFNDEF USE_SDLTHREADS} {$IFDEF UNIX}, cthreads{$ENDIF} {$ENDIF}; + +type PScreenshot = ^TScreenshot; + TScreenshot = record + buffer: PByte; + filename: shortstring; + width, height: LongInt; + size: QWord; + end; procedure movecursor(dx, dy: LongInt); var x, y: LongInt; @@ -49,12 +60,65 @@ SDL_WarpMouse(x, y); end; -// captures and saves the screen. returns true on success. -function MakeScreenshot(filename: shortstring): Boolean; -var success: boolean; - p: Pointer; - size: QWord; +{$IFDEF PNG_SCREENSHOTS} +// this funtion will be executed in separate thread +function SaveScreenshot(screenshot: pointer): PtrInt; +var i: LongInt; + png_ptr: ^png_struct; + info_ptr: ^png_info; f: file; + image: PScreenshot; +begin +image:= PScreenshot(screenshot); + +png_ptr := png_create_write_struct(png_get_libpng_ver(nil), nil, nil, nil); +if png_ptr = nil then +begin + // AddFileLog('Error: Could not create png write struct.'); + SaveScreenshot:= 0; + exit; +end; + +info_ptr := png_create_info_struct(png_ptr); +if info_ptr = nil then +begin + png_destroy_write_struct(@png_ptr, nil); + // AddFileLog('Error: Could not create png info struct.'); + SaveScreenshot:= 0; + exit; +end; + +{$IOCHECKS OFF} +Assign(f, image^.filename); +Rewrite(f, 1); +if IOResult = 0 then + begin + png_init_pascal_io(png_ptr,@f); + png_set_IHDR(png_ptr, info_ptr, image^.width, image^.height, + 8, // bit depth + PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + png_write_info(png_ptr, info_ptr); + // glReadPixels and libpng number rows in different order + for i:= image^.height-1 downto 0 do + png_write_row(png_ptr, image^.buffer + i*4*image^.width); + png_write_end(png_ptr, info_ptr); + Close(f); + end; +{$IOCHECKS ON} + +// free everything +png_destroy_write_struct(@png_ptr, @info_ptr); +FreeMem(image^.buffer, image^.size); +Dispose(image); +SaveScreenshot:= 0; +end; + +{$ELSE} // no PNG_SCREENSHOTS + +// this funtion will be executed in separate thread +function SaveScreenshot(screenshot: pointer): PtrInt; +var f: file; // Windows Bitmap Header head: array[0..53] of Byte = ( $42, $4D, // identifier ("BM") @@ -73,93 +137,128 @@ 0, 0, 0, 0, // number of colors (all) 0, 0, 0, 0 // number of important colors ); + image: PScreenshot; + size: QWord; +begin +image:= PScreenshot(screenshot); + +size:= image^.Width*image^.Height*4; + +head[$02]:= (size + 54) and $ff; +head[$03]:= ((size + 54) shr 8) and $ff; +head[$04]:= ((size + 54) shr 16) and $ff; +head[$05]:= ((size + 54) shr 24) and $ff; +head[$12]:= image^.Width and $ff; +head[$13]:= (image^.Width shr 8) and $ff; +head[$14]:= (image^.Width shr 16) and $ff; +head[$15]:= (image^.Width shr 24) and $ff; +head[$16]:= image^.Height and $ff; +head[$17]:= (image^.Height shr 8) and $ff; +head[$18]:= (image^.Height shr 16) and $ff; +head[$19]:= (image^.Height shr 24) and $ff; +head[$22]:= size and $ff; +head[$23]:= (size shr 8) and $ff; +head[$24]:= (size shr 16) and $ff; +head[$25]:= (size shr 24) and $ff; + +{$IOCHECKS OFF} +Assign(f, image^.filename); +Rewrite(f, 1); +if IOResult = 0 then + begin + BlockWrite(f, head, sizeof(head)); + BlockWrite(f, image^.buffer^, size); + Close(f); + end +else + begin + //AddFileLog('Error: Could not write to ' + filename); + end; +{$IOCHECKS ON} + +// free everything +FreeMem(image^.buffer, image^.size); +Dispose(image); +SaveScreenshot:= 0; +end; + +{$ENDIF} // no PNG_SCREENSHOTS + +// captures and saves the screen. returns true on success. +function MakeScreenshot(filename: shortstring): Boolean; +var p: Pointer; + size: QWord; + image: PScreenshot; + format: GLenum; + ext: string[4]; begin // flash ScreenFade:= sfFromWhite; ScreenFadeValue:= sfMax; ScreenFadeSpeed:= 5; +{$IFDEF PNG_SCREENSHOTS} +format:= GL_RGBA; +ext:= '.png'; +{$ELSE} +format:= GL_BGRA; +ext:= '.bmp'; +{$ENDIF} + size:= toPowerOf2(cScreenWidth) * toPowerOf2(cScreenHeight) * 4; -p:= GetMem(size); +p:= GetMem(size); // will be freed in SaveScreenshot() // memory could not be allocated if p = nil then begin AddFileLog('Error: Could not allocate memory for screenshot.'); - exit(false); + MakeScreenshot:= false; + exit; end; -// update header information and file name -filename:= UserPathPrefix + '/Screenshots/' + filename + '.bmp'; - -head[$02]:= (size + 54) and $ff; -head[$03]:= ((size + 54) shr 8) and $ff; -head[$04]:= ((size + 54) shr 16) and $ff; -head[$05]:= ((size + 54) shr 24) and $ff; -head[$12]:= cScreenWidth and $ff; -head[$13]:= (cScreenWidth shr 8) and $ff; -head[$14]:= (cScreenWidth shr 16) and $ff; -head[$15]:= (cScreenWidth shr 24) and $ff; -head[$16]:= cScreenHeight and $ff; -head[$17]:= (cScreenHeight shr 8) and $ff; -head[$18]:= (cScreenHeight shr 16) and $ff; -head[$19]:= (cScreenHeight shr 24) and $ff; -head[$22]:= size and $ff; -head[$23]:= (size shr 8) and $ff; -head[$24]:= (size shr 16) and $ff; -head[$25]:= (size shr 24) and $ff; +// read pixel from the front buffer +glReadPixels(0, 0, cScreenWidth, cScreenHeight, format, GL_UNSIGNED_BYTE, p); -// read pixel from the front buffer -glReadPixels(0, 0, cScreenWidth, cScreenHeight, GL_BGRA, GL_UNSIGNED_BYTE, p); +// allocate and fill structure that will be passed to new thread +New(image); // will be disposed in SaveScreenshot() +image^.filename:= UserPathPrefix + '/Screenshots/' + filename + ext; +image^.width:= cScreenWidth; +image^.height:= cScreenHeight; +image^.size:= size; +image^.buffer:= p; -{$IOCHECKS OFF} -Assign(f, filename); -Rewrite(f, 1); -if IOResult = 0 then - begin - BlockWrite(f, head, sizeof(head)); - BlockWrite(f, p^, size); - Close(f); - success:= true; - end -else - begin - AddFileLog('Error: Could not write to ' + filename); - success:= false; - end; -{$IOCHECKS ON} - -FreeMem(p, size); -MakeScreenshot:= success; +{$IFDEF USE_SDLTHREADS} +SDL_CreateThread(@SaveScreenshot{$IFDEF SDL13}, nil{$ENDIF}, image); +{$ELSE} +BeginThread(@SaveScreenshot, image); +{$ENDIF} +MakeScreenshot:= true; // possibly it is not true but we will not wait for thread to terminate end; // http://www.idevgames.com/forums/thread-5602-post-21860.html#pid21860 function doSurfaceConversion(tmpsurf: PSDL_Surface): PSDL_Surface; var convertedSurf: PSDL_Surface; begin + doSurfaceConversion:= tmpsurf; if ((tmpsurf^.format^.bitsperpixel = 32) and (tmpsurf^.format^.rshift > tmpsurf^.format^.bshift)) or (tmpsurf^.format^.bitsperpixel = 24) then begin convertedSurf:= SDL_ConvertSurface(tmpsurf, conversionFormat, SDL_SWSURFACE); SDL_FreeSurface(tmpsurf); - exit(convertedSurf); + doSurfaceConversion:= convertedSurf; end; - - exit(tmpsurf); end; {$IFDEF SDL13} -function SDL_RectMake(x, y, width, height: LongInt): TSDL_Rect; +function SDL_RectMake(x, y, width, height: LongInt): TSDL_Rect; inline; {$ELSE} -function SDL_RectMake(x, y: SmallInt; width, height: Word): TSDL_Rect; +function SDL_RectMake(x, y: SmallInt; width, height: Word): TSDL_Rect; inline; {$ENDIF} -var rect: TSDL_Rect; begin - rect.x:= x; - rect.y:= y; - rect.w:= width; - rect.h:= height; - exit(rect); + SDL_RectMake.x:= x; + SDL_RectMake.y:= y; + SDL_RectMake.w:= width; + SDL_RectMake.h:= height; end; function GetTeamStatString(p: PTeam): shortstring; @@ -170,7 +269,7 @@ end; procedure initModule; -const SDL_PIXELFORMAT_ABGR8888 = ((1 shl 31) or (6 shl 24) or (7 shl 20) or (6 shl 16) or (32 shl 8) or 4); +const SDL_PIXELFORMAT_ABGR8888 = (1 shl 31) or (6 shl 24) or (7 shl 20) or (6 shl 16) or (32 shl 8) or 4; begin conversionFormat:= SDL_AllocFormat(SDL_PIXELFORMAT_ABGR8888); end; diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uMobile.pas --- a/hedgewars/uMobile.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uMobile.pas Wed May 02 23:53:45 2012 +0200 @@ -44,18 +44,15 @@ // this function is just to determine whether we are running on a limited screen device function isPhone: Boolean; inline; begin + isPhone:= false; {$IFDEF IPHONEOS} - exit(isApplePhone()); + isPhone:= isApplePhone(); {$ENDIF} {$IFDEF ANDROID} //nasty nasty hack. TODO: implement callback to java to have a unified way of determining if it is a tablet if (cScreenWidth < 1000) and (cScreenHeight < 500) then - begin - exit(true); - end - else exit(false); + isPhone:= true; {$ENDIF} - exit(false); end; // this function should make the device vibrate in some way diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uRandom.pas --- a/hedgewars/uRandom.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uRandom.pas Wed May 02 23:53:45 2012 +0200 @@ -35,7 +35,7 @@ procedure freeModule; procedure SetRandomSeed(Seed: shortstring); // Sets the seed that should be used for generating pseudo-random values. -function GetRandom: hwFloat; overload; // Returns a pseudo-random hwFloat. +function GetRandomf: hwFloat; overload; // Returns a pseudo-random hwFloat. function GetRandom(m: LongWord): LongWord; overload; // Returns a positive pseudo-random integer smaller than m. function rndSign(num: hwFloat): hwFloat; // Returns num with a random chance of having a inverted sign. @@ -73,11 +73,11 @@ GetNext end; -function GetRandom: hwFloat; +function GetRandomf: hwFloat; begin GetNext; -GetRandom.isNegative:= false; -GetRandom.QWordValue:= GetNext +GetRandomf.isNegative:= false; +GetRandomf.QWordValue:= GetNext end; function GetRandom(m: LongWord): LongWord; diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uRender.pas --- a/hedgewars/uRender.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uRender.pas Wed May 02 23:53:45 2012 +0200 @@ -24,27 +24,32 @@ uses SDLh, uTypes, GLunit, uConsts; -procedure DrawSpriteFromRect(Sprite: TSprite; r: TSDL_Rect; X, Y, Height, Position: LongInt); -procedure DrawFromRect(X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture); -procedure DrawFromRect(X, Y: LongInt; r: PSDL_Rect; SourceTexture: PTexture); -procedure DrawSprite (Sprite: TSprite; X, Y, Frame: LongInt); -procedure DrawSprite2(Sprite: TSprite; X, Y, FrameX, FrameY: LongInt); -procedure DrawSpriteClipped(Sprite: TSprite; X, Y, TopY, RightX, BottomY, LeftX: LongInt); -procedure DrawTexture(X, Y: LongInt; Texture: PTexture; Scale: GLfloat = 1.0); -procedure DrawTextureF(Texture: PTexture; Scale: GLfloat; X, Y, Frame, Dir, w, h: LongInt); -procedure DrawRotatedTextureF(Texture: PTexture; Scale, OffsetX, OffsetY: GLfloat; X, Y, Frame, Dir, w, h: LongInt; Angle: real); -procedure DrawRotated(Sprite: TSprite; X, Y, Dir: LongInt; Angle: real); -procedure DrawRotatedF(Sprite: TSprite; X, Y, Frame, Dir: LongInt; Angle: real); -procedure DrawRotatedTex(Tex: PTexture; hw, hh, X, Y, Dir: LongInt; Angle: real); -procedure DrawCentered(X, Top: LongInt; Source: PTexture); -procedure DrawLine(X0, Y0, X1, Y1, Width: Single; r, g, b, a: Byte); -procedure DrawFillRect(r: TSDL_Rect); -procedure DrawCircle(X, Y, Radius, Width: LongInt; r, g, b, a: Byte); -procedure DrawCircle(X, Y, Radius, Width: LongInt); -procedure DrawHedgehog(X, Y: LongInt; Dir: LongInt; Pos, Step: LongWord; Angle: real); -procedure DrawScreenWidget(widget: POnScreenWidget); -procedure Tint(r, g, b, a: Byte); inline; -procedure Tint(c: Longword); inline; +procedure DrawSprite (Sprite: TSprite; X, Y, Frame: LongInt); +procedure DrawSprite (Sprite: TSprite; X, Y, FrameX, FrameY: LongInt); +procedure DrawSpriteFromRect (Sprite: TSprite; r: TSDL_Rect; X, Y, Height, Position: LongInt); +procedure DrawSpriteClipped (Sprite: TSprite; X, Y, TopY, RightX, BottomY, LeftX: LongInt); +procedure DrawSpriteRotated (Sprite: TSprite; X, Y, Dir: LongInt; Angle: real); +procedure DrawSpriteRotatedF (Sprite: TSprite; X, Y, Frame, Dir: LongInt; Angle: real); + +procedure DrawTexture (X, Y: LongInt; Texture: PTexture); inline; +procedure DrawTexture (X, Y: LongInt; Texture: PTexture; Scale: GLfloat); +procedure DrawTextureFromRect (X, Y: LongInt; r: PSDL_Rect; SourceTexture: PTexture); +procedure DrawTextureFromRect (X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture); +procedure DrawTextureCentered (X, Top: LongInt; Source: PTexture); +procedure DrawTextureF (Texture: PTexture; Scale: GLfloat; X, Y, Frame, Dir, w, h: LongInt); +procedure DrawTextureRotated (Texture: PTexture; hw, hh, X, Y, Dir: LongInt; Angle: real); +procedure DrawTextureRotatedF (Texture: PTexture; Scale, OffsetX, OffsetY: GLfloat; X, Y, Frame, Dir, w, h: LongInt; Angle: real); + +procedure DrawCircle (X, Y, Radius, Width: LongInt); +procedure DrawCircle (X, Y, Radius, Width: LongInt; r, g, b, a: Byte); + +procedure DrawLine (X0, Y0, X1, Y1, Width: Single; r, g, b, a: Byte); +procedure DrawFillRect (r: TSDL_Rect); +procedure DrawHedgehog (X, Y: LongInt; Dir: LongInt; Pos, Step: LongWord; Angle: real); +procedure DrawScreenWidget (widget: POnScreenWidget); + +procedure Tint (r, g, b, a: Byte); inline; +procedure Tint (c: Longword); inline; implementation @@ -54,15 +59,15 @@ begin r.y:= r.y + Height * Position; r.h:= Height; -DrawFromRect(X, Y, @r, SpritesData[Sprite].Texture) +DrawTextureFromRect(X, Y, @r, SpritesData[Sprite].Texture) end; -procedure DrawFromRect(X, Y: LongInt; r: PSDL_Rect; SourceTexture: PTexture); +procedure DrawTextureFromRect(X, Y: LongInt; r: PSDL_Rect; SourceTexture: PTexture); begin -DrawFromRect(X, Y, r^.w, r^.h, r, SourceTexture) +DrawTextureFromRect(X, Y, r^.w, r^.h, r, SourceTexture) end; -procedure DrawFromRect(X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture); +procedure DrawTextureFromRect(X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture); var rr: TSDL_Rect; _l, _r, _t, _b: real; VertexBuffer, TextureBuffer: array [0..3] of TVertex2f; @@ -106,12 +111,15 @@ TextureBuffer[3].X:= _l; TextureBuffer[3].Y:= _b; - glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]); glTexCoordPointer(2, GL_FLOAT, 0, @TextureBuffer[0]); glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)); end; +procedure DrawTexture(X, Y: LongInt; Texture: PTexture); inline; +begin + DrawTexture(X, Y, Texture, 1.0); +end; procedure DrawTexture(X, Y: LongInt; Texture: PTexture; Scale: GLfloat); begin @@ -131,10 +139,10 @@ procedure DrawTextureF(Texture: PTexture; Scale: GLfloat; X, Y, Frame, Dir, w, h: LongInt); begin - DrawRotatedTextureF(Texture, Scale, 0, 0, X, Y, Frame, Dir, w, h, 0) + DrawTextureRotatedF(Texture, Scale, 0, 0, X, Y, Frame, Dir, w, h, 0) end; -procedure DrawRotatedTextureF(Texture: PTexture; Scale, OffsetX, OffsetY: GLfloat; X, Y, Frame, Dir, w, h: LongInt; Angle: real); +procedure DrawTextureRotatedF(Texture: PTexture; Scale, OffsetX, OffsetY: GLfloat; X, Y, Frame, Dir, w, h: LongInt; Angle: real); var ft, fb, fl, fr: GLfloat; hw, nx, ny: LongInt; VertexBuffer, TextureBuffer: array [0..3] of TVertex2f; @@ -194,15 +202,15 @@ glPopMatrix end; -procedure DrawRotated(Sprite: TSprite; X, Y, Dir: LongInt; Angle: real); +procedure DrawSpriteRotated(Sprite: TSprite; X, Y, Dir: LongInt; Angle: real); begin - DrawRotatedTex(SpritesData[Sprite].Texture, + DrawTextureRotated(SpritesData[Sprite].Texture, SpritesData[Sprite].Width, SpritesData[Sprite].Height, X, Y, Dir, Angle) end; -procedure DrawRotatedF(Sprite: TSprite; X, Y, Frame, Dir: LongInt; Angle: real); +procedure DrawSpriteRotatedF(Sprite: TSprite; X, Y, Frame, Dir: LongInt; Angle: real); begin glPushMatrix; glTranslatef(X, Y, 0); @@ -219,7 +227,7 @@ glPopMatrix end; -procedure DrawRotatedTex(Tex: PTexture; hw, hh, X, Y, Dir: LongInt; Angle: real); +procedure DrawTextureRotated(Texture: PTexture; hw, hh, X, Y, Dir: LongInt; Angle: real); var VertexBuffer: array [0..3] of TVertex2f; begin // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs) @@ -240,7 +248,7 @@ glRotatef(Angle, 0, 0, 1); -glBindTexture(GL_TEXTURE_2D, Tex^.id); +glBindTexture(GL_TEXTURE_2D, Texture^.id); VertexBuffer[0].X:= -hw; VertexBuffer[0].Y:= -hh; @@ -252,21 +260,31 @@ VertexBuffer[3].Y:= hh; glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]); -glTexCoordPointer(2, GL_FLOAT, 0, @Tex^.tb); +glTexCoordPointer(2, GL_FLOAT, 0, @Texture^.tb); glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)); glPopMatrix end; -procedure DrawSprite (Sprite: TSprite; X, Y, Frame: LongInt); +procedure DrawSprite(Sprite: TSprite; X, Y, Frame: LongInt); var row, col, numFramesFirstCol: LongInt; begin -if SpritesData[Sprite].imageHeight = 0 then - exit; -numFramesFirstCol:= SpritesData[Sprite].imageHeight div SpritesData[Sprite].Height; -row:= Frame mod numFramesFirstCol; -col:= Frame div numFramesFirstCol; -DrawSprite2 (Sprite, X, Y, col, row); + if SpritesData[Sprite].imageHeight = 0 then + exit; + numFramesFirstCol:= SpritesData[Sprite].imageHeight div SpritesData[Sprite].Height; + row:= Frame mod numFramesFirstCol; + col:= Frame div numFramesFirstCol; + DrawSprite(Sprite, X, Y, col, row); +end; + +procedure DrawSprite(Sprite: TSprite; X, Y, FrameX, FrameY: LongInt); +var r: TSDL_Rect; +begin + r.x:= FrameX * SpritesData[Sprite].Width; + r.w:= SpritesData[Sprite].Width; + r.y:= FrameY * SpritesData[Sprite].Height; + r.h:= SpritesData[Sprite].Height; + DrawTextureFromRect(X, Y, @r, SpritesData[Sprite].Texture) end; procedure DrawSpriteClipped(Sprite: TSprite; X, Y, TopY, RightX, BottomY, LeftX: LongInt); @@ -290,20 +308,10 @@ dec(r.h, r.y); dec(r.w, r.x); -DrawFromRect(X + r.x, Y + r.y, @r, SpritesData[Sprite].Texture) +DrawTextureFromRect(X + r.x, Y + r.y, @r, SpritesData[Sprite].Texture) end; -procedure DrawSprite2(Sprite: TSprite; X, Y, FrameX, FrameY: LongInt); -var r: TSDL_Rect; -begin - r.x:= FrameX * SpritesData[Sprite].Width; - r.w:= SpritesData[Sprite].Width; - r.y:= FrameY * SpritesData[Sprite].Height; - r.h:= SpritesData[Sprite].Height; - DrawFromRect(X, Y, @r, SpritesData[Sprite].Texture) -end; - -procedure DrawCentered(X, Top: LongInt; Source: PTexture); +procedure DrawTextureCentered(X, Top: LongInt; Source: PTexture); var scale: GLfloat; begin if (Source^.w + 20) > cScreenWidth then @@ -449,9 +457,9 @@ end; procedure DrawScreenWidget(widget: POnScreenWidget); +{$IFDEF USE_TOUCH_INTERFACE} var alpha: byte = $FF; begin -{$IFDEF USE_TOUCH_INTERFACE} with widget^ do begin if (fadeAnimStart <> 0) then @@ -489,37 +497,37 @@ Tint($FF, $FF, $FF, $FF); end; end; +{$ELSE} +begin +widget:= widget; // avoid hint {$ENDIF} end; procedure Tint(r, g, b, a: Byte); inline; -const - lastTint: Longword = 0; -var - nc, tw: Longword; +var nc, tw: Longword; begin -nc:= (a shl 24) or (b shl 16) or (g shl 8) or r; + nc:= (a shl 24) or (b shl 16) or (g shl 8) or r; -if nc = lastTint then - exit; + if nc = lastTint then + exit; -if cGrayScale then - begin - tw:= round(r * RGB_LUMINANCE_RED + g * RGB_LUMINANCE_GREEN + b * RGB_LUMINANCE_BLUE); - if tw > 255 then - tw:= 255; - r:= tw; - g:= tw; - b:= tw - end; + if GrayScale then + begin + tw:= round(r * RGB_LUMINANCE_RED + g * RGB_LUMINANCE_GREEN + b * RGB_LUMINANCE_BLUE); + if tw > 255 then + tw:= 255; + r:= tw; + g:= tw; + b:= tw + end; -glColor4ub(r, g, b, a); -lastTint:= nc; + glColor4ub(r, g, b, a); + lastTint:= nc; end; procedure Tint(c: Longword); inline; begin -Tint(((c shr 24) and $FF), ((c shr 16) and $FF), (c shr 8) and $FF, (c and $FF)) + Tint(((c shr 24) and $FF), ((c shr 16) and $FF), (c shr 8) and $FF, (c and $FF)) end; end. diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uRenderUtils.pas --- a/hedgewars/uRenderUtils.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uRenderUtils.pas Wed May 02 23:53:45 2012 +0200 @@ -24,14 +24,19 @@ uses SDLh, uTypes; procedure flipSurface(Surface: PSDL_Surface; Vertical: Boolean); + procedure copyRotatedSurface(src, dest: PSDL_Surface); // this is necessary since width/height are read only in SDL -procedure copyToXY(src, dest: PSDL_Surface; destX, destY: LongInt); +procedure copyToXY(src, dest: PSDL_Surface; destX, destY: LongInt); inline; procedure copyToXY(src, dest: PSDL_Surface; srcX, srcY, srcW, srcH, destX, destY: LongInt); -procedure DrawSprite2Surf(sprite: TSprite; dest: PSDL_Surface; x,y: LongInt; frame: LongInt = 0); + +procedure DrawSprite2Surf(sprite: TSprite; dest: PSDL_Surface; x,y: LongInt); inline; +procedure DrawSprite2Surf(sprite: TSprite; dest: PSDL_Surface; x,y: LongInt; frame: LongInt); procedure DrawLine2Surf(dest: PSDL_Surface; x0,y0,x1,y1:LongInt; r,g,b: byte); -function RenderStringTex(s: ansistring; Color: Longword; font: THWFont; maxLength: LongWord = 0): PTexture; +procedure DrawRoundRect(rect: PSDL_Rect; BorderColor, FillColor: Longword; Surface: PSDL_Surface; Clear: boolean); + +function RenderStringTex(s: ansistring; Color: Longword; font: THWFont): PTexture; +function RenderStringTex(s: ansistring; Color: Longword; font: THWFont; maxLength: LongWord): PTexture; function RenderSpeechBubbleTex(s: ansistring; SpeechType: Longword; font: THWFont): PTexture; -procedure DrawRoundRect(rect: PSDL_Rect; BorderColor, FillColor: Longword; Surface: PSDL_Surface; Clear: boolean); implementation uses uUtils, uVariables, uConsts, uTextures, sysutils, uDebug; @@ -65,8 +70,13 @@ r.h:= rect^.h - 4; SDL_FillRect(Surface, @r, FillColor) end; +(* +function WriteInRoundRect(Surface: PSDL_Surface; X, Y: LongInt; Color: LongWord; Font: THWFont; s: ansistring): TSDL_Rect; +begin + WriteInRoundRect:= WriteInRoundRect(Surface, X, Y, Color, Font, s, 0); +end;*) -function WriteInRoundRect(Surface: PSDL_Surface; X, Y: LongInt; Color: LongWord; Font: THWFont; s: ansistring; maxLength: LongWord = 0): TSDL_Rect; +function WriteInRoundRect(Surface: PSDL_Surface; X, Y: LongInt; Color: LongWord; Font: THWFont; s: ansistring; maxLength: LongWord): TSDL_Rect; var w, h: LongInt; tmpsurf: PSDL_Surface; clr: TSDL_Color; @@ -76,8 +86,8 @@ if (maxLength <> 0) and (w > maxLength) then w := maxLength; finalRect.x:= X; finalRect.y:= Y; - finalRect.w:= w + FontBorder * 2 + 4; - finalRect.h:= h + FontBorder * 2; + finalRect.w:= w + cFontBorder * 2 + 4; + finalRect.h:= h + cFontBorder * 2; textRect.x:= X; textRect.y:= Y; textRect.w:= w; @@ -87,15 +97,15 @@ clr.g:= (Color shr 8) and $FF; clr.b:= Color and $FF; tmpsurf:= TTF_RenderUTF8_Blended(Fontz[Font].Handle, Str2PChar(s), clr); - finalRect.x:= X + FontBorder + 2; - finalRect.y:= Y + FontBorder; + finalRect.x:= X + cFontBorder + 2; + finalRect.y:= Y + cFontBorder; SDLTry(tmpsurf <> nil, true); SDL_UpperBlit(tmpsurf, @textRect, Surface, @finalRect); SDL_FreeSurface(tmpsurf); finalRect.x:= X; finalRect.y:= Y; - finalRect.w:= w + FontBorder * 2 + 4; - finalRect.h:= h + FontBorder * 2; + finalRect.w:= w + cFontBorder * 2 + 4; + finalRect.h:= h + cFontBorder * 2; WriteInRoundRect:= finalRect; end; @@ -128,9 +138,9 @@ end; end; -procedure copyToXY(src, dest: PSDL_Surface; destX, destY: LongInt); +procedure copyToXY(src, dest: PSDL_Surface; destX, destY: LongInt); inline; begin - copyToXY(src, dest, 0,0,src^.w, src^.h, destX, destY); + copyToXY(src, dest, 0, 0, src^.w, src^.h, destX, destY); end; procedure copyToXY(src, dest: PSDL_Surface; srcX, srcY, srcW, srcH, destX, destY: LongInt); @@ -161,6 +171,11 @@ end; end; +procedure DrawSprite2Surf(sprite: TSprite; dest: PSDL_Surface; x,y: LongInt); inline; +begin + DrawSprite2Surf(sprite, dest, x, y, 0); +end; + procedure DrawSprite2Surf(sprite: TSprite; dest: PSDL_Surface; x,y,frame: LongInt); var numFramesFirstCol, row, col: LongInt; begin @@ -178,12 +193,11 @@ procedure DrawLine2Surf(dest: PSDL_Surface; x0, y0,x1,y1: LongInt; r,g,b: byte); var - max: LongInt; dx,dy,err,e2,sx,sy: LongInt; yMax: LongInt; destPixels: PLongwordArray; begin - max:= (dest^.pitch div 4) * dest^.h; + //max:= (dest^.pitch div 4) * dest^.h; yMax:= dest^.pitch div 4; destPixels:= dest^.pixels; @@ -234,7 +248,12 @@ end; end; -function RenderStringTex(s: ansistring; Color: Longword; font: THWFont; maxLength: LongWord = 0): PTexture; +function RenderStringTex(s: ansistring; Color: Longword; font: THWFont): PTexture; +begin + RenderStringTex:= RenderStringTex(s, Color, font, 0); +end; + +function RenderStringTex(s: ansistring; Color: Longword; font: THWFont; maxLength: LongWord): PTexture; var w, h: LongInt; finalSurface: PSDL_Surface; begin @@ -244,7 +263,7 @@ TTF_SizeUTF8(Fontz[font].Handle, Str2PChar(s), @w, @h); if (maxLength <> 0) and (w > maxLength) then w := maxLength; - finalSurface:= SDL_CreateRGBSurface(SDL_SWSURFACE, w + FontBorder * 2 + 4, h + FontBorder * 2, + finalSurface:= SDL_CreateRGBSurface(SDL_SWSURFACE, w + cFontBorder * 2 + 4, h + cFontBorder * 2, 32, RMask, GMask, BMask, AMask); TryDo(finalSurface <> nil, 'RenderString: fail to create surface', true); diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uScript.pas --- a/hedgewars/uScript.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uScript.pas Wed May 02 23:53:45 2012 +0200 @@ -1023,7 +1023,7 @@ if lua_gettop(L) = 2 then AddAmmo(gear^.Hedgehog^, TAmmoType(lua_tointeger(L, 2))) else - AddAmmo(gear^.Hedgehog^, TAmmoType(lua_tointeger(L, 2)), lua_tointeger(L, 3)) + SetAmmo(gear^.Hedgehog^, TAmmoType(lua_tointeger(L, 2)), lua_tointeger(L, 3)) end else LuaError('Lua: Wrong number of parameters passed to AddAmmo!'); lc_addammo:= 0 @@ -1713,7 +1713,7 @@ exit; // push game variables so they may be modified by the script -ScriptSetInteger('BorderColor', cExplosionBorderColor); +ScriptSetInteger('BorderColor', ExplosionBorderColor); ScriptSetInteger('GameFlags', GameFlags); ScriptSetString('Seed', cSeed); ScriptSetInteger('TemplateFilter', cTemplateFilter); diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uSound.pas --- a/hedgewars/uSound.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uSound.pas Wed May 02 23:53:45 2012 +0200 @@ -36,6 +36,7 @@ uses SDLh, uConsts, uTypes, sysutils; var MusicFN: shortstring; // music file name + previousVolume: LongInt; // cached volume value procedure initModule; procedure freeModule; @@ -90,6 +91,9 @@ // Returns a pointer to the voicepack with the given name. function AskForVoicepack(name: shortstring): Pointer; +// Drastically lower the volume when we lose focus (and restore the previous value) +procedure DampenAudio; +procedure UndampenAudio; implementation uses uVariables, uConsole, uUtils, uCommands, uDebug; @@ -464,8 +468,9 @@ function ChangeVolume(voldelta: LongInt): LongInt; begin + ChangeVolume:= 0; if not isSoundEnabled then - exit(0); + exit; inc(Volume, voldelta); if Volume < 0 then @@ -477,6 +482,17 @@ ChangeVolume:= Volume * 100 div MIX_MAX_VOLUME end; +procedure DampenAudio; +begin + previousVolume:= Volume; + ChangeVolume(-Volume * 7 div 9); +end; + +procedure UndampenAudio; +begin +ChangeVolume(previousVolume - Volume); +end; + procedure PauseMusic; begin if (MusicFN = '') or (not isMusicEnabled) then @@ -528,7 +544,7 @@ procedure initModule; begin - RegisterVariable('voicepack', vtCommand, @chVoicepack, false); + RegisterVariable('voicepack', @chVoicepack, false); MusicFN:=''; end; diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uStore.pas --- a/hedgewars/uStore.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uStore.pas Wed May 02 23:53:45 2012 +0200 @@ -26,8 +26,8 @@ procedure initModule; procedure freeModule; -procedure StoreLoad(reload: boolean = false); -procedure StoreRelease(reload: boolean = false); +procedure StoreLoad(reload: boolean); +procedure StoreRelease(reload: boolean); procedure RenderHealth(var Hedgehog: THedgehog); procedure AddProgress; procedure FinishProgress; @@ -57,10 +57,10 @@ begin w:= 0; h:= 0; // avoid compiler hints TTF_SizeUTF8(Fontz[Font].Handle, Str2PChar(s), @w, @h); -finalRect.x:= X + FontBorder + 2; -finalRect.y:= Y + FontBorder; -finalRect.w:= w + FontBorder * 2 + 4; -finalRect.h:= h + FontBorder * 2; +finalRect.x:= X + cFontBorder + 2; +finalRect.y:= Y + cFontBorder; +finalRect.w:= w + cFontBorder * 2 + 4; +finalRect.h:= h + cFontBorder * 2; clr.r:= Color shr 16; clr.g:= (Color shr 8) and $FF; clr.b:= Color and $FF; @@ -71,8 +71,8 @@ SDL_FreeSurface(tmpsurf); finalRect.x:= X; finalRect.y:= Y; -finalRect.w:= w + FontBorder * 2 + 4; -finalRect.h:= h + FontBorder * 2; +finalRect.w:= w + cFontBorder * 2 + 4; +finalRect.h:= h + cFontBorder * 2; WriteInRect:= finalRect end; @@ -524,28 +524,30 @@ Hedgehog.HealthTagTex:= RenderStringTex(s, Hedgehog.Team^.Clan^.Color, fnt16) end; -function LoadImage(const filename: shortstring; imageFlags: LongInt): PSDL_Surface; +function LoadImage(const filename: shortstring; imageFlags: LongInt): PSDL_Surface; var tmpsurf: PSDL_Surface; s: shortstring; begin -WriteToConsole(msgLoading + filename + '.png [flags: ' + inttostr(imageFlags) + '] '); + LoadImage:= nil; + WriteToConsole(msgLoading + filename + '.png [flags: ' + inttostr(imageFlags) + '] '); -s:= filename + '.png'; -tmpsurf:= IMG_Load(Str2PChar(s)); + s:= filename + '.png'; + tmpsurf:= IMG_Load(Str2PChar(s)); if tmpsurf = nil then - begin + begin OutError(msgFailed, (imageFlags and ifCritical) <> 0); - exit(nil) - end; + exit; + end; if ((imageFlags and ifIgnoreCaps) = 0) and ((tmpsurf^.w > MaxTextureSize) or (tmpsurf^.h > MaxTextureSize)) then - begin + begin SDL_FreeSurface(tmpsurf); OutError(msgFailedSize, (imageFlags and ifCritical) <> 0); // dummy surface to replace non-critical textures that failed to load due to their size - exit(SDL_CreateRGBSurface(SDL_SWSURFACE, 2, 2, 32, RMask, GMask, BMask, AMask)); - end; + LoadImage:= SDL_CreateRGBSurface(SDL_SWSURFACE, 2, 2, 32, RMask, GMask, BMask, AMask); + exit; + end; tmpsurf:= doSurfaceConversion(tmpsurf); @@ -623,7 +625,9 @@ {$IFDEF SDL13} // this function creates an opengles1.1 context by default on mobile devices - // use SDL_GL_SetAttribute to change this behaviour + // unless you un-comment this two attributes + //SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); + //SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); if SDLGLcontext = nil then SDLGLcontext:= SDL_GL_CreateContext(SDLwindow); SDLTry(SDLGLcontext <> nil, true); @@ -665,7 +669,9 @@ AddFileLog('OpenGL-- Renderer: ' + shortstring(pchar(glGetString(GL_RENDERER)))); AddFileLog(' |----- Vendor: ' + shortstring(pchar(glGetString(GL_VENDOR)))); AddFileLog(' |----- Version: ' + shortstring(pchar(glGetString(GL_VERSION)))); - AddFileLog(' \----- Texture Size: ' + inttostr(MaxTextureSize)); + AddFileLog(' |----- Texture Size: ' + inttostr(MaxTextureSize)); + AddFileLog(' \----- Extensions: ' + shortstring(pchar(glGetString(GL_EXTENSIONS)))); + //TODO: don't have the Extensions line trimmed but slipt it into multiple lines {$IFNDEF S3D_DISABLED} if (cStereoMode = smHorizontal) or (cStereoMode = smVertical) or (cStereoMode = smAFR) then @@ -783,7 +789,7 @@ r.w:= squaresize; r.h:= squaresize; - DrawFromRect( -squaresize div 2, (cScreenHeight - squaresize) shr 1, @r, ProgrTex); + DrawTextureFromRect( -squaresize div 2, (cScreenHeight - squaresize) shr 1, @r, ProgrTex); {$IFDEF SDL13} SDL_GL_SwapWindow(SDLwindow); @@ -823,8 +829,8 @@ w:= 0; h:= 0; -wa:= FontBorder * 2 + 4; -ha:= FontBorder * 2; +wa:= cFontBorder * 2 + 4; +ha:= cFontBorder * 2; i:= 0; j:= 0; // avoid compiler hints @@ -882,9 +888,9 @@ DrawRoundRect(@r, cWhiteColor, cNearBlackColor, tmpsurf, true); // render caption -r:= WriteInRect(tmpsurf, 36 + FontBorder + 2, ha, $ffffffff, font, caption); +r:= WriteInRect(tmpsurf, 36 + cFontBorder + 2, ha, $ffffffff, font, caption); // render sub caption -r:= WriteInRect(tmpsurf, 36 + FontBorder + 2, r.y + r.h, $ffc7c7c7, font, subcaption); +r:= WriteInRect(tmpsurf, 36 + cFontBorder + 2, r.y + r.h, $ffc7c7c7, font, subcaption); // render all description lines tmpdesc:= description; @@ -895,21 +901,21 @@ r2:= r; if tmpline <> '' then begin - r:= WriteInRect(tmpsurf, FontBorder + 2, r.y + r.h, $ff707070, font, tmpline); + r:= WriteInRect(tmpsurf, cFontBorder + 2, r.y + r.h, $ff707070, font, tmpline); // render highlighted caption (if there is a ':') tmpline2:= ''; SplitByChar(tmpline, tmpline2, ':'); if tmpline2 <> '' then - WriteInRect(tmpsurf, FontBorder + 2, r2.y + r2.h, $ffc7c7c7, font, tmpline + ':'); + WriteInRect(tmpsurf, cFontBorder + 2, r2.y + r2.h, $ffc7c7c7, font, tmpline + ':'); end end; if extra <> '' then - r:= WriteInRect(tmpsurf, FontBorder + 2, r.y + r.h, extracolor, font, extra); + r:= WriteInRect(tmpsurf, cFontBorder + 2, r.y + r.h, extracolor, font, extra); -r.x:= FontBorder + 6; -r.y:= FontBorder + 4; +r.x:= cFontBorder + 6; +r.y:= cFontBorder + 4; r.w:= 32; r.h:= 32; SDL_FillRect(tmpsurf, @r, $ffffffff); @@ -1113,7 +1119,7 @@ var ai: TAmmoType; i: LongInt; begin - RegisterVariable('fullscr', vtCommand, @chFullScr, true); + RegisterVariable('fullscr', @chFullScr, true); SDLPrimSurface:= nil; diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uTeams.pas --- a/hedgewars/uTeams.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uTeams.pas Wed May 02 23:53:45 2012 +0200 @@ -20,7 +20,7 @@ unit uTeams; interface -uses uConsts, uKeys, uGears, uRandom, uFloat, uStats, uVisualGears, uCollisions, GLunit, uSound, uTypes, uWorld; +uses uConsts, uInputHandler, uGears, uRandom, uFloat, uStats, uVisualGears, uCollisions, GLunit, uSound, uTypes{$IFDEF USE_TOUCH_INTERFACE}, uWorld{$ENDIF}; procedure initModule; procedure freeModule; @@ -37,15 +37,16 @@ implementation uses uLocale, uAmmos, uChat, uMobile, uVariables, uUtils, uIO, uCaptions, uCommands, uDebug, uScript, - uGearsUtils, uGearsList; + uGearsUtils, uGearsList{$IFDEF SDL13}, uTouch{$ENDIF}; -const MaxTeamHealth: LongInt = 0; +var MaxTeamHealth: LongInt; function CheckForWin: boolean; var AliveClan: PClan; s: shortstring; t, AliveCount, i, j: LongInt; begin +CheckForWin:= false; AliveCount:= 0; for t:= 0 to Pred(ClansCount) do if ClansArray[t]^.ClanHealth > 0 then @@ -54,9 +55,8 @@ AliveClan:= ClansArray[t] end; -if (AliveCount > 1) -or ((AliveCount = 1) and ((GameFlags and gfOneClanMode) <> 0)) then - exit(false); +if (AliveCount > 1) or ((AliveCount = 1) and ((GameFlags and gfOneClanMode) <> 0)) then + exit; CheckForWin:= true; TurnTimeLeft:= 0; @@ -205,6 +205,8 @@ procedure AfterSwitchHedgehog; var i, t: LongInt; CurWeapon: PAmmo; + w: real; + vg: PVisualGear; begin if PlacingHogs then @@ -226,7 +228,7 @@ inc(CurrentTeam^.Clan^.TurnNumber); -CurWeapon:= GetAmmoEntry(CurrentHedgehog^); +CurWeapon:= GetCurAmmoEntry(CurrentHedgehog^); if CurWeapon^.Count = 0 then CurrentHedgehog^.CurAmmoType:= amNothing; @@ -248,13 +250,10 @@ if (GameFlags and gfDisableWind) = 0 then begin - cWindSpeed:= rndSign(GetRandom * 2 * cMaxWindSpeed); - // cWindSpeedf:= cWindSpeed.QWordValue / _1.QWordValue throws 'Internal error 200502052' on Darwin - // see http://mantis.freepascal.org/view.php?id=17714 - cWindSpeedf:= SignAs(cWindSpeed,cWindSpeed).QWordValue / SignAs(_1,_1).QWordValue; - if cWindSpeed.isNegative then - CWindSpeedf := -cWindSpeedf; - AddVisualGear(0, 0, vgtSmoothWindBar); + cWindSpeed:= rndSign(GetRandomf * 2 * cMaxWindSpeed); + w:= hwFloat2Float(cWindSpeed); + vg:= AddVisualGear(0, 0, vgtSmoothWindBar); + if vg <> nil then vg^.dAngle:= w; AddFileLog('Wind = '+FloatToStr(cWindSpeed)); end; @@ -289,7 +288,7 @@ AddVoice(sndIllGetYou, CurrentTeam^.voicepack) else AddVoice(sndYesSir, CurrentTeam^.voicepack); - if PlacingHogs or (cHedgehogTurnTime < 1000000) then + if cHedgehogTurnTime < 1000000 then ReadyTimeLeft:= cReadyDelay; AddCaption(Format(shortstring(trmsg[sidReady]), CurrentTeam^.TeamName), cWhiteColor, capgrpGameState) end @@ -301,6 +300,9 @@ end; uMobile.NewTurnBeginning(); +{$IFDEF SDL13} +uTouch.NewTurnBeginning(); +{$ENDIF} ScriptCall('onNewTurn'); end; @@ -605,12 +607,12 @@ procedure initModule; begin -RegisterVariable('addhh', vtCommand, @chAddHH, false); -RegisterVariable('addteam', vtCommand, @chAddTeam, false); -RegisterVariable('hhcoords', vtCommand, @chSetHHCoords, false); -RegisterVariable('bind', vtCommand, @chBind, true ); -RegisterVariable('teamgone', vtCommand, @chTeamGone, true ); -RegisterVariable('finish', vtCommand, @chFinish, true ); // all teams gone +RegisterVariable('addhh', @chAddHH, false); +RegisterVariable('addteam', @chAddTeam, false); +RegisterVariable('hhcoords', @chSetHHCoords, false); +RegisterVariable('bind', @chBind, true ); +RegisterVariable('teamgone', @chTeamGone, true ); +RegisterVariable('finish', @chFinish, true ); // all teams gone CurrentTeam:= nil; PreviousTeam:= nil; @@ -622,6 +624,7 @@ LocalAmmo:= -1; GameOver:= false; NextClan:= true; +MaxTeamHealth:= 0; end; procedure freeModule; diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uTextures.pas --- a/hedgewars/uTextures.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uTextures.pas Wed May 02 23:53:45 2012 +0200 @@ -156,7 +156,7 @@ fromP4:= Surf^.pixels; -if cGrayScale then +if GrayScale then Surface2GrayScale(Surf); if (not SupportNPOTT) and (not (isPowerOf2(Surf^.w) and isPowerOf2(Surf^.h))) then diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uTouch.pas --- a/hedgewars/uTouch.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uTouch.pas Wed May 02 23:53:45 2012 +0200 @@ -22,12 +22,14 @@ interface -uses sysutils, uConsole, uVariables, SDLh, uFloat, uConsts, uCommands, uIO, GLUnit, uTypes; +uses sysutils, uConsole, uVariables, SDLh, uFloat, uConsts, uCommands, uIO, GLUnit, uTypes, uCaptions, uAmmos, uWorld; procedure initModule; procedure ProcessTouch; +procedure NewTurnBeginning; + procedure onTouchDown(x,y: Longword; pointerId: TSDL_FingerId); procedure onTouchMotion(x,y: Longword; dx,dy: LongInt; pointerId: TSDL_FingerId); procedure onTouchUp(x,y: Longword; pointerId: TSDL_FingerId); @@ -59,7 +61,6 @@ const clickTime = 200; - longClickTime = 400; nilFingerId = High(TSDL_FingerId); var @@ -81,6 +82,7 @@ targetAngle: LongInt; buttonsDown: Longword; + targetting, targetted: boolean; //true when targetting an airstrike or the like procedure onTouchDown(x,y: Longword; pointerId: TSDL_FingerId); var @@ -101,35 +103,37 @@ if isOnWidget(fireButton, finger^) then begin - spaceKey:= true; + ParseTeamCommand('+attack'); moveCursor:= false; finger^.pressedWidget:= @fireButton; exit; end; if isOnWidget(arrowLeft, finger^) then begin - leftKey:= true; + ParseTeamCommand('+left'); moveCursor:= false; finger^.pressedWidget:= @arrowLeft; exit; end; if isOnWidget(arrowRight, finger^) then begin - rightKey:= true; + ParseTeamCommand('+right'); moveCursor:= false; finger^.pressedWidget:= @arrowRight; exit; end; if isOnWidget(arrowUp, finger^) then begin - upKey:= true; + ParseTeamCommand('+up'); + aimingUp:= true; moveCursor:= false; finger^.pressedWidget:= @arrowUp; exit; end; if isOnWidget(arrowDown, finger^) then begin - downKey:= true; + ParseTeamCommand('+down'); + aimingDown:= true; moveCursor:= false; finger^.pressedWidget:= @arrowDown; exit; @@ -145,19 +149,30 @@ if isOnWidget(utilityWidget, finger^) then begin - //ParseCommand('/timer ' + inttostr((CurrentHedgeHog^.CurWeapon^.Timer div 1000 + 1) mod 5)); + finger^.pressedWidget:= @utilityWidget; + moveCursor:= false; + if(CurrentHedgehog <> nil) then + begin + if Ammoz[CurrentHedgehog^.CurAmmoType].Ammo.Propz and ammoprop_Timerable <> 0 then + ParseTeamCommand('/timer ' + inttostr((GetCurAmmoEntry(CurrentHedgeHog^)^.Timer div 1000) mod 5 + 1)); + end; + exit; end; dec(buttonsDown);//no buttonsDown, undo the inc() above if buttonsDown = 0 then begin moveCursor:= true; - if pointerCount = 2 then - begin - moveCursor:= false; - pinchSize := calculateDelta(finger^, getSecondFinger(finger^)^); - baseZoomValue := ZoomValue + case pointerCount of + 1: + targetting:= not(targetted) and (CurrentHedgehog <> nil) and (Ammoz[CurrentHedgehog^.CurAmmoType].Ammo.Propz and ammoprop_NeedTarget <> 0); + 2: + begin + moveCursor:= false; + pinchSize := calculateDelta(finger^, getSecondFinger(finger^)^); + baseZoomValue := ZoomValue + end; + end; end; -end; {$ENDIF} end; @@ -214,10 +229,12 @@ finger:= updateFinger(x,y,0,0,pointerId); //Check for onTouchClick event if not(fingerHasMoved(finger^)) then + begin if (RealTicks - finger^.timeSinceDown) < clickTime then onTouchClick(finger^) else - onTouchLongClick(finger^); + onTouchLongClick(finger^); + end; if aimingCrosshair then begin @@ -233,20 +250,34 @@ dec(buttonsDown); if widget = @arrowLeft then - leftKey:= false; + ParseTeamCommand('-left'); if widget = @arrowRight then - rightKey:= false; + ParseTeamCommand('-right'); if widget = @arrowUp then - upKey:= false; + ParseTeamCommand('-up'); if widget = @arrowDown then - downKey:= false; + ParseTeamCommand('-down'); if widget = @fireButton then - spaceKey:= false; + ParseTeamCommand('-attack'); + + if widget = @utilityWidget then + if (CurrentHedgehog <> nil)then + if(Ammoz[CurrentHedgehog^.CurAmmoType].Ammo.Propz and ammoprop_NeedTarget <> 0)then + begin + ParseTeamCommand('put'); + targetted:= true; + end + else if CurAmmoGear^.AmmoType = amSwitch then + ParseTeamCommand('switch') + else WriteLnToConsole(inttostr(ord(Ammoz[CurrentHedgehog^.CurAmmoType].NameId)) + ' ' + inttostr(ord(sidSwitch))); end; + +if targetting then + AddCaption('Press the target button to mark the target', cWhiteColor, capgrpAmmoInfo); deleteFinger(pointerId); {$ENDIF} @@ -262,11 +293,10 @@ {$IFDEF USE_TOUCH_INTERFACE} if isOnWidget(jumpWidget, finger) then begin - ParseCommand('ljump', (CurrentTeam <> nil) and not(CurrentTeam^.ExtDriven) and (CurrentHedgehog^.BotLevel=0)); - if (CurrentTeam <> nil) and (not CurrentTeam^.ExtDriven) and (ReadyTimeLeft > 1) then - ParseCommand('gencmd R', true); + ParseTeamCommand('ljump'); exit; end; + {$ENDIF} end; @@ -305,9 +335,7 @@ if isOnWidget(jumpWidget, finger) then begin - ParseCommand('hjump', (CurrentTeam <> nil) and not(CurrentTeam^.ExtDriven) and (CurrentHedgehog^.BotLevel=0)); - if (CurrentTeam <> nil) and (not CurrentTeam^.ExtDriven) and (ReadyTimeLeft > 1) then - ParseCommand('gencmd R', true); + ParseTeamCommand('hjump'); exit; end; {$ENDIF} @@ -386,21 +414,35 @@ end; +procedure NewTurnBeginning; +begin +targetted:= false; +targetting:= false; +SetUtilityWidgetState; +end; + + procedure ProcessTouch; var deltaAngle: LongInt; begin -invertCursor := not(bShowAmmoMenu); +invertCursor := not(bShowAmmoMenu or targetting); if aimingCrosshair then if CurrentHedgehog^.Gear <> nil then begin deltaAngle:= CurrentHedgehog^.Gear^.Angle - targetAngle; if (deltaAngle > -5) and (deltaAngle < 5) then begin - upKey:= false; - aimingUp:= false; - downKey:= false; - aimingDown:= false; + if(aimingUp)then + begin + aimingUp:= false; + ParseTeamCommand('-up'); + end; + if(aimingDown)then + begin + aimingDown:= false; + ParseTeamCommand('-down'); + end end else begin @@ -408,21 +450,27 @@ begin if aimingUp then begin - upKey:= false; aimingUp:= false; + ParseTeamCommand('-up'); end; - downKey:= true; - aimingDown:= true; + if(aimingDown)then + begin + aimingDown:= true; + ParseTeamCommand('-down'); + end end else begin if aimingDown then begin - downKey:= false; + ParseTeamCommand('-down'); aimingDown:= false; end; - upKey:= true; - aimingUp:= true; + if aimingUp then + begin + aimingUp:= true; + ParseTeamCommand('+up'); + end; end; end; end @@ -430,12 +478,12 @@ begin if aimingUp then begin - upKey:= false; + ParseTeamCommand('-up'); aimingUp:= false; end; if aimingDown then begin - upKey:= false; + ParseTeamCommand('-down'); aimingDown:= false; end; end; @@ -534,7 +582,7 @@ //Method to calculate the distance this finger has moved since the downEvent function fingerHasMoved(finger: TTouch_Data): boolean; begin - fingerHasMoved := trunc(sqrt(sqr(finger.X-finger.historicalX) + sqr(finger.y-finger.historicalY))) > 330; + fingerHasMoved := trunc(sqrt(sqr(finger.X-finger.historicalX) + sqr(finger.y-finger.historicalY))) > 30; end; function calculateDelta(finger1, finger2: TTouch_Data): LongInt; inline; diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uTypes.pas --- a/hedgewars/uTypes.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uTypes.pas Wed May 02 23:53:45 2012 +0200 @@ -59,7 +59,7 @@ sprQuestion, sprPowerBar, sprWindBar, sprWindL, sprWindR, {$IFDEF USE_TOUCH_INTERFACE} sprFireButton, sprArrowUp, sprArrowDown, sprArrowLeft, sprArrowRight, - sprJumpWidget, sprAMWidget, sprPauseButton, sprTimerButton, + sprJumpWidget, sprAMWidget, sprPauseButton, sprTimerButton, sprTargetButton, {$ENDIF} sprFlake, sprHandRope, sprHandBazooka, sprHandShotgun, sprHandDEagle, sprHandAirAttack, sprHandBaseball, sprPHammer, @@ -90,15 +90,16 @@ ); // Gears that interact with other Gears and/or Land - TGearType = (gtGrenade, gtHedgehog, gtShell, gtGrave, gtBee, // 4 - gtShotgunShot, gtPickHammer, gtRope, gtMine, gtCase, // 9 - gtDEagleShot, gtDynamite, gtClusterBomb, gtCluster, gtShover, // 14 - gtFlame, gtFirePunch, gtATStartGame, // 17 - gtATFinishGame, gtParachute, gtAirAttack, gtAirBomb, gtBlowTorch, // 22 - gtGirder, gtTeleport, gtSwitcher, gtTarget, gtMortar, // 27 - gtWhip, gtKamikaze, gtCake, gtSeduction, gtWatermelon, gtMelonPiece, // 33 - gtHellishBomb, gtWaterUp, gtDrill, gtBallGun, gtBall, gtRCPlane, // 39 - gtSniperRifleShot, gtJetpack, gtMolotov, gtExplosives, gtBirdy, // 44 + TGearType = ({-->}gtFlame, gtHedgehog, gtMine, gtCase, gtExplosives, // <-- these are gears which should be avoided when searching a spawn place + gtGrenade, gtShell, gtGrave, gtBee, // 8 + gtShotgunShot, gtPickHammer, gtRope, // 11 + gtDEagleShot, gtDynamite, gtClusterBomb, gtCluster, gtShover, // 16 + gtFirePunch, gtATStartGame, // 18 + gtATFinishGame, gtParachute, gtAirAttack, gtAirBomb, gtBlowTorch, // 23 + gtGirder, gtTeleport, gtSwitcher, gtTarget, gtMortar, // 28 + gtWhip, gtKamikaze, gtCake, gtSeduction, gtWatermelon, gtMelonPiece, // 34 + gtHellishBomb, gtWaterUp, gtDrill, gtBallGun, gtBall, gtRCPlane, // 40 + gtSniperRifleShot, gtJetpack, gtMolotov, gtBirdy, // 44 gtEgg, gtPortal, gtPiano, gtGasBomb, gtSineGunShot, gtFlamethrower, // 50 gtSMine, gtPoisonCloud, gtHammer, gtHammerHit, gtResurrector, // 55 gtNapalmBomb, gtSnowball, gtFlake, gtStructure, gtLandGun, gtTardis); // 61 @@ -112,8 +113,6 @@ vgtBigExplosion, vgtChunk, vgtNote, vgtLineTrail, vgtBulletHit, vgtCircle, vgtSmoothWindBar, vgtStraightShot); - TGearsType = set of TGearType; - // Damage can be caused by different sources TDamageSource = (dsUnknown, dsFall, dsBullet, dsExplosion, dsShove, dsPoison); @@ -175,7 +174,7 @@ Handle: PTTF_Font; Height: LongInt; style: LongInt; - Name: string[21]; + Name: string[31]; end; PAmmo = ^TAmmo; diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uUtils.pas --- a/hedgewars/uUtils.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uUtils.pas Wed May 02 23:53:45 2012 +0200 @@ -26,12 +26,14 @@ procedure SplitBySpace(var a, b: shortstring); procedure SplitByChar(var a, b: ansistring; c: char); +{$IFNDEF PAS2C} function EnumToStr(const en : TGearType) : shortstring; overload; function EnumToStr(const en : TVisualGearType) : shortstring; overload; function EnumToStr(const en : TSound) : shortstring; overload; function EnumToStr(const en : TAmmoType) : shortstring; overload; function EnumToStr(const en : THogEffect) : shortstring; overload; function EnumToStr(const en : TCapGroup) : shortstring; overload; +{$ENDIF} function Min(a, b: LongInt): LongInt; inline; function Max(a, b: LongInt): LongInt; inline; @@ -42,7 +44,7 @@ function DxDy2Angle(const _dY, _dX: hwFloat): GLfloat; function DxDy2Angle32(const _dY, _dX: hwFloat): LongInt; function DxDy2AttackAngle(const _dY, _dX: hwFloat): LongInt; -function DxDy2AttackAngle(const _dY, _dX: extended): LongInt; +function DxDy2AttackAnglef(const _dY, _dX: extended): LongInt; procedure SetLittle(var r: hwFloat); @@ -102,6 +104,7 @@ end else b:= ''; end; +{$IFNDEF PAS2C} function EnumToStr(const en : TGearType) : shortstring; overload; begin EnumToStr:= GetEnumName(TypeInfo(TGearType), ord(en)) @@ -130,7 +133,7 @@ begin EnumToStr := GetEnumName(TypeInfo(TCapGroup), ord(en)) end; - +{$ENDIF} function Min(a, b: LongInt): LongInt; begin @@ -198,9 +201,9 @@ DxDy2AttackAngle:= trunc(arctan2(dY, dX) * MaxAngleDivPI) end; -function DxDy2AttackAngle(const _dY, _dX: extended): LongInt; inline; +function DxDy2AttackAnglef(const _dY, _dX: extended): LongInt; inline; begin -DxDy2AttackAngle:= trunc(arctan2(_dY, _dX) * (cMaxAngle/pi)) +DxDy2AttackAnglef:= trunc(arctan2(_dY, _dX) * (cMaxAngle/pi)) end; @@ -256,8 +259,8 @@ end; +var CharArray: array[byte] of Char; function Str2PChar(const s: shortstring): PChar; -const CharArray: array[byte] of Char = ''; begin CharArray:= s; CharArray[Length(s)]:= #0; @@ -293,12 +296,13 @@ u: WideChar; tmpstr: array[0..256] of WideChar; begin +CheckCJKFont:= font; {$IFNDEF MOBILE} // remove chinese fonts for now if (font >= CJKfnt16) or (length(s) = 0) then {$ENDIF} - exit(font); + exit; l:= Utf8ToUnicode(@tmpstr, Str2PChar(s), length(s))-1; i:= 0; @@ -317,10 +321,13 @@ ((#$AC00 <= u) and (u <= #$D7AF)) or // Hangul Syllables ((#$F900 <= u) and (u <= #$FAFF)) or // CJK Compatibility Ideographs ((#$FE30 <= u) and (u <= #$FE4F))) // CJK Compatibility Forms - then exit(THWFont( ord(font) + ((ord(High(THWFont))+1) div 2) )); + then + begin + CheckCJKFont:= THWFont( ord(font) + ((ord(High(THWFont))+1) div 2) ); + exit; + end; inc(i) end; -exit(font); (* two more to check. pascal WideChar is only 16 bit though ((#$20000 <= u) and (u >= #$2A6DF)) or // CJK Unified Ideographs Extension B ((#$2F800 <= u) and (u >= #$2FA1F))) // CJK Compatibility Ideographs Supplement *) diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uVariables.pas --- a/hedgewars/uVariables.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uVariables.pas Wed May 02 23:53:45 2012 +0200 @@ -110,10 +110,26 @@ GameTicks : LongWord; + // originally typed consts + CharArray: array[byte] of Char; + LastTint: Longword; + SocketString: shortstring; + VGCounter: Longword; + PrevX: LongInt; + timedelta: Longword; + StartTicks: Longword; + Counter: Longword; + StepTicks: LongWord; + ExplosionBorderColor: LongWord; + WaterOpacity: byte; + SDWaterOpacity: byte; + prevGState: TGameState; + GrayScale: Boolean; + // originally from uConsts Pathz: array[TPathType] of shortstring; UserPathz: array[TPathType] of shortstring; - CountTexz: array[1..Pred(AMMO_INFINITE)] of PTexture; + CountTexz: array[0..Pred(AMMO_INFINITE)] of PTexture; LAND_WIDTH : Word; LAND_HEIGHT : Word; LAND_WIDTH_MASK : LongWord; @@ -194,6 +210,17 @@ LuaGoals : shortstring; + VoiceList : array[0..7] of TVoice = ( + ( snd: sndNone; voicepack: nil), + ( snd: sndNone; voicepack: nil), + ( snd: sndNone; voicepack: nil), + ( snd: sndNone; voicepack: nil), + ( snd: sndNone; voicepack: nil), + ( snd: sndNone; voicepack: nil), + ( snd: sndNone; voicepack: nil), + ( snd: sndNone; voicepack: nil)); + LastVoice : TVoice = ( snd: sndNone; voicepack: nil ); + ///////////////////////////////////// //Buttons {$IFDEF USE_TOUCH_INTERFACE} @@ -203,14 +230,11 @@ firebutton, jumpWidget, AMWidget : TOnScreenWidget; pauseButton, utilityWidget : TOnScreenWidget; {$ENDIF} + AMAnimType : LongInt; - AMAnimType : LongInt; + const - cHHFileName = 'Hedgehog'; - cCHFileName = 'Crosshair'; - cThemeCFGFilename = 'theme.cfg'; - - FontBorder = 2; + // these consts are here because they would cause circular dependencies in uConsts/uTypes cPathz: array[TPathType] of shortstring = ( '', // ptNone '', // ptData @@ -236,20 +260,6 @@ 'Graphics/Buttons' // ptButton ); - cTagsMasks : array[0..15] of byte = (7, 0, 0, 0, 15, 6, 4, 5, 0, 0, 0, 0, 0, 14, 12, 13); - cTagsMasksNoHealth: array[0..15] of byte = (3, 2, 11, 1, 0, 0, 0, 0, 0, 10, 0, 9, 0, 0, 0, 0); - - VoiceList : array[0..7] of TVoice = ( - ( snd: sndNone; voicepack: nil), - ( snd: sndNone; voicepack: nil), - ( snd: sndNone; voicepack: nil), - ( snd: sndNone; voicepack: nil), - ( snd: sndNone; voicepack: nil), - ( snd: sndNone; voicepack: nil), - ( snd: sndNone; voicepack: nil), - ( snd: sndNone; voicepack: nil)); - LastVoice : TVoice = ( snd: sndNone; voicepack: nil ); - Fontz: array[THWFont] of THHFont = ( (Handle: nil; Height: 12; @@ -279,8 +289,9 @@ {$ENDIF} ); +var SpritesData: array[TSprite] of record - FileName: string[16]; + FileName: string[15]; Path, AltPath: TPathType; Texture: PTexture; Surface: PSDL_Surface; @@ -406,6 +417,8 @@ Width: 120; Height: 100; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpHigh; getDimensions: false; getImageDimensions: true), // sprPauseButton (FileName: 'pause'; Path: ptButtons; AltPath: ptNone; Texture: nil; Surface: nil;//TODO correct image Width: 120; Height: 128; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpHigh; getDimensions: false; getImageDimensions: true), // sprTimerButton + (FileName: 'forwardjump'; Path: ptButtons; AltPath: ptNone; Texture: nil; Surface: nil;//TODO correct image + Width: 120; Height: 128; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpHigh; getDimensions: false; getImageDimensions: true), // sprTargetButton {$ENDIF} (FileName: 'Flake'; Path:ptCurrTheme; AltPath: ptNone; Texture: nil; Surface: nil; Width: 64; Height: 64; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpHighest; getDimensions: false; getImageDimensions: true),// sprFlake @@ -620,7 +633,7 @@ imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpMedium; getDimensions: false; getImageDimensions: true), //sprHandResurrector - (FileName: 'Cross'; Path: ptGraphics; altPath: ptNone; + (FileName: 'Cross'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil; Width: 108; Height: 138; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpMedium; getDimensions: false; getImageDimensions: true), @@ -662,12 +675,12 @@ Width: 3; Height: 17; imageWidth: 3; imageHeight: 17; saveSurf: false; priority: tpLow; getDimensions: false; getImageDimensions: false) // sprSlider ); - +const Wavez: array [TWave] of record Sprite: TSprite; FramesCount: Longword; Interval: Longword; - cmd: string[20]; + cmd: string[31]; Voice: TSound; VoiceDelay: LongWord; end = ( @@ -681,7 +694,7 @@ ); Soundz: array[TSound] of record - FileName: string[25]; + FileName: string[31]; Path : TPathType; end = ( (FileName: ''; Path: ptNone ),// sndNone @@ -799,7 +812,7 @@ (FileName: 'plane.ogg'; Path: ptSounds),// sndPlane (FileName: 'TARDIS.ogg'; Path: ptSounds) // sndTardis ); - +var Ammoz: array [TAmmoType] of record NameId: TAmmoStrId; NameTex: PTexture; @@ -842,7 +855,11 @@ NameTex: nil; Probability: 0; NumberInCase: 1; - Ammo: (Propz: ammoprop_Timerable or ammoprop_Power or ammoprop_AltUse or ammoprop_SetBounce; + Ammo: (Propz: ammoprop_Timerable or + ammoprop_Power or + ammoprop_AltUse or + ammoprop_SetBounce or + ammoprop_NeedUpDown; Count: AMMO_INFINITE; NumPerTurn: 0; Timer: 3000; @@ -866,7 +883,11 @@ NameTex: nil; Probability: 100; NumberInCase: 3; - Ammo: (Propz: ammoprop_Timerable or ammoprop_Power or ammoprop_AltUse or ammoprop_SetBounce; + Ammo: (Propz: ammoprop_Timerable or + ammoprop_Power or + ammoprop_AltUse or + ammoprop_SetBounce or + ammoprop_NeedUpDown; Count: 5; NumPerTurn: 0; Timer: 3000; @@ -890,7 +911,9 @@ NameTex: nil; Probability: 0; NumberInCase: 1; - Ammo: (Propz: ammoprop_Power or ammoprop_AltUse; + Ammo: (Propz: ammoprop_Power or + ammoprop_AltUse or + ammoprop_NeedUpDown; Count: AMMO_INFINITE; NumPerTurn: 0; Timer: 0; @@ -914,7 +937,10 @@ NameTex: nil; Probability: 100; NumberInCase: 1; - Ammo: (Propz: ammoprop_Power or ammoprop_NeedTarget or ammoprop_DontHold; + Ammo: (Propz: ammoprop_Power or + ammoprop_NeedTarget or + ammoprop_DontHold or + ammoprop_NeedUpDown; Count: 2; NumPerTurn: 0; Timer: 0; @@ -938,7 +964,8 @@ NameTex: nil; Probability: 0; NumberInCase: 1; - Ammo: (Propz: ammoprop_ForwMsgs; + Ammo: (Propz: ammoprop_ForwMsgs or + ammoprop_NeedUpDown; Count: AMMO_INFINITE; NumPerTurn: 1; Timer: 0; @@ -962,7 +989,10 @@ NameTex: nil; Probability: 0; NumberInCase: 1; - Ammo: (Propz: ammoprop_ForwMsgs or ammoprop_AttackInMove or ammoprop_NoCrosshair or ammoprop_DontHold; + Ammo: (Propz: ammoprop_ForwMsgs or + ammoprop_AttackInMove or + ammoprop_NoCrosshair or + ammoprop_DontHold; Count: 2; NumPerTurn: 0; Timer: 0; @@ -986,7 +1016,8 @@ NameTex: nil; Probability: 0; NumberInCase: 1; - Ammo: (Propz: ammoprop_NoCrosshair or ammoprop_DontHold; + Ammo: (Propz: ammoprop_NoCrosshair or + ammoprop_DontHold; Count: AMMO_INFINITE; NumPerTurn: 0; Timer: 0; @@ -1014,7 +1045,8 @@ ammoprop_ForwMsgs or ammoprop_AttackInMove or ammoprop_Utility or - ammoprop_AltAttack; + ammoprop_AltAttack or + ammoprop_NeedUpDown; Count: 5; NumPerTurn: 0; Timer: 0; @@ -1038,7 +1070,11 @@ NameTex: nil; Probability: 100; NumberInCase: 1; - Ammo: (Propz: ammoprop_NoCrosshair or ammoprop_AttackInMove or ammoprop_DontHold or ammoprop_AltUse or ammoprop_SetBounce; + Ammo: (Propz: ammoprop_NoCrosshair or + ammoprop_AttackInMove or + ammoprop_DontHold or + ammoprop_AltUse or + ammoprop_SetBounce; Count: 2; NumPerTurn: 0; Timer: 0; @@ -1062,7 +1098,7 @@ NameTex: nil; Probability: 20; NumberInCase: 2; - Ammo: (Propz: 0; + Ammo: (Propz: ammoprop_NeedUpDown; Count: 3; NumPerTurn: 3; Timer: 0; @@ -1086,7 +1122,10 @@ NameTex: nil; Probability: 100; NumberInCase: 1; - Ammo: (Propz: ammoprop_NoCrosshair or ammoprop_AttackInMove or ammoprop_DontHold or ammoprop_AltUse; + Ammo: (Propz: ammoprop_NoCrosshair or + ammoprop_AttackInMove or + ammoprop_DontHold or + ammoprop_AltUse; Count: 1; NumPerTurn: 0; Timer: 0; @@ -1110,7 +1149,9 @@ NameTex: nil; Probability: 0; NumberInCase: 1; - Ammo: (Propz: ammoprop_NoCrosshair or ammoprop_ForwMsgs or ammoprop_AttackInMove; + Ammo: (Propz: ammoprop_NoCrosshair or + ammoprop_ForwMsgs or + ammoprop_AttackInMove; Count: AMMO_INFINITE; NumPerTurn: 0; Timer: 0; @@ -1120,7 +1161,7 @@ Bounciness: 1000); Slot: 3; TimeAfterTurn: 3000; - MinAngle: 0; + minAngle: 0; maxAngle: 0; isDamaging: true; SkipTurns: 0; @@ -1144,7 +1185,7 @@ Bounciness: 1000); Slot: 3; TimeAfterTurn: 3000; - MinAngle: 0; + minAngle: 0; maxAngle: 0; isDamaging: true; SkipTurns: 0; @@ -1158,7 +1199,8 @@ NameTex: nil; Probability: 100; NumberInCase: 1; - Ammo: (Propz: ammoprop_DontHold; + Ammo: (Propz: ammoprop_DontHold or + ammoprop_NeedUpDown; Count: 1; NumPerTurn: 0; Timer: 0; @@ -1188,7 +1230,8 @@ ammoprop_NoCrosshair or ammoprop_DontHold or ammoprop_Utility or - ammoprop_AltAttack; + ammoprop_AltAttack or + ammoprop_NeedUpDown; Count: 2; NumPerTurn: 0; Timer: 0; @@ -1213,10 +1256,10 @@ Probability: 100; NumberInCase: 1; Ammo: (Propz: ammoprop_NoCrosshair or - ammoprop_NeedTarget or - ammoprop_AttackingPut or - ammoprop_DontHold or - ammoprop_NotBorder; + ammoprop_NeedTarget or + ammoprop_AttackingPut or + ammoprop_DontHold or + ammoprop_NotBorder; Count: 1; NumPerTurn: 0; Timer: 0; @@ -1241,10 +1284,10 @@ Probability: 200; NumberInCase: 1; Ammo: (Propz: ammoprop_NoCrosshair or - ammoprop_NeedTarget or - ammoprop_AttackingPut or - ammoprop_DontHold or - ammoprop_NotBorder; + ammoprop_NeedTarget or + ammoprop_AttackingPut or + ammoprop_DontHold or + ammoprop_NotBorder; Count: 1; NumPerTurn: 0; Timer: 0; @@ -1268,7 +1311,8 @@ NameTex: nil; Probability: 100; NumberInCase: 2; - Ammo: (Propz: ammoprop_ForwMsgs; + Ammo: (Propz: ammoprop_ForwMsgs or + ammoprop_NeedUpDown; Count: 1; NumPerTurn: 0; Timer: 0; @@ -1401,7 +1445,10 @@ NameTex: nil; Probability: 100; NumberInCase: 1; - Ammo: (Propz: ammoprop_ForwMsgs or ammoprop_DontHold or ammoprop_AttackInMove; + Ammo: (Propz: ammoprop_ForwMsgs or + ammoprop_DontHold or + ammoprop_NeedUpDown or + ammoprop_AttackInMove; Count: 1; NumPerTurn: 0; Timer: 0; @@ -1425,7 +1472,9 @@ NameTex: nil; Probability: 100; NumberInCase: 1; - Ammo: (Propz: ammoprop_ForwMsgs or ammoprop_NoCrosshair or ammoprop_DontHold; + Ammo: (Propz: ammoprop_ForwMsgs or + ammoprop_NoCrosshair or + ammoprop_DontHold; Count: 1; NumPerTurn: 0; Timer: 0; @@ -1449,7 +1498,9 @@ NameTex: nil; Probability: 100; NumberInCase: 1; - Ammo: (Propz: ammoprop_ForwMsgs or ammoprop_DontHold or ammoprop_NoCrosshair; + Ammo: (Propz: ammoprop_ForwMsgs or + ammoprop_DontHold or + ammoprop_NoCrosshair; Count: 1; NumPerTurn: 0; Timer: 0; @@ -1473,7 +1524,10 @@ NameTex: nil; Probability: 400; NumberInCase: 1; - Ammo: (Propz: ammoprop_Timerable or ammoprop_Power or ammoprop_AltUse; + Ammo: (Propz: ammoprop_Timerable or + ammoprop_Power or + ammoprop_NeedUpDown or + ammoprop_AltUse; Count: 0; NumPerTurn: 0; Timer: 3000; @@ -1497,7 +1551,9 @@ NameTex: nil; Probability: 400; NumberInCase: 1; - Ammo: (Propz: ammoprop_Power or ammoprop_AltUse; + Ammo: (Propz: ammoprop_Power or + ammoprop_NeedUpDown or + ammoprop_AltUse; Count: 0; NumPerTurn: 0; Timer: 5000; @@ -1522,10 +1578,10 @@ Probability: 100; NumberInCase: 1; Ammo: (Propz: ammoprop_NoCrosshair or - ammoprop_NeedTarget or - ammoprop_AttackingPut or - ammoprop_DontHold or - ammoprop_NotBorder; + ammoprop_NeedTarget or + ammoprop_AttackingPut or + ammoprop_DontHold or + ammoprop_NotBorder; Count: 1; NumPerTurn: 0; Timer: 0; @@ -1549,7 +1605,9 @@ NameTex: nil; Probability: 300; NumberInCase: 1; - Ammo: (Propz: ammoprop_Power or ammoprop_AltUse; + Ammo: (Propz: ammoprop_Power or + ammoprop_NeedUpDown or + ammoprop_AltUse; Count: AMMO_INFINITE; NumPerTurn: 0; Timer: 0; @@ -1573,7 +1631,9 @@ NameTex: nil; Probability: 400; NumberInCase: 1; - Ammo: (Propz: ammoprop_ForwMsgs or ammoprop_DontHold; + Ammo: (Propz: ammoprop_ForwMsgs or + ammoprop_NeedUpDown or + ammoprop_DontHold; Count: AMMO_INFINITE; NumPerTurn: 0; Timer: 5001; @@ -1597,9 +1657,10 @@ NameTex: nil; Probability: 200; NumberInCase: 1; - Ammo: (Propz: ammoprop_ForwMsgs{ or - ammoprop_DontHold or - ammoprop_AltAttack}; + Ammo: (Propz: ammoprop_ForwMsgs or + ammoprop_NeedUpDown{ or + ammoprop_DontHold or + ammoprop_AltAttack}; Count: 1; NumPerTurn: 0; Timer: 0; @@ -1744,6 +1805,7 @@ ammoprop_DontHold or ammoprop_AltUse or ammoprop_Utility or + ammoprop_NeedUpDown or ammoprop_Effect; Count: 1; NumPerTurn: 0; @@ -1797,7 +1859,7 @@ NameTex: nil; Probability: 20; NumberInCase: 2; - Ammo: (Propz: 0; + Ammo: (Propz: ammoprop_NeedUpDown; Count: 2; NumPerTurn: 1; Timer: 0; @@ -1827,6 +1889,7 @@ ammoprop_NoCrosshair or ammoprop_DontHold or ammoprop_Utility or + ammoprop_NeedUpDown or ammoprop_AltAttack; Count: 1; NumPerTurn: 0; @@ -1851,7 +1914,9 @@ NameTex: nil; Probability: 0; NumberInCase: 1; - Ammo: (Propz: ammoprop_Power or ammoprop_AltUse; + Ammo: (Propz: ammoprop_Power or + ammoprop_NeedUpDown or + ammoprop_AltUse; Count: AMMO_INFINITE; NumPerTurn: 0; Timer: 3000; @@ -1877,6 +1942,7 @@ NumberInCase: 1; Ammo: (Propz: ammoprop_ForwMsgs or ammoprop_NoCrosshair or + ammoprop_NeedUpDown or ammoprop_DontHold; Count: 1; NumPerTurn: 0; @@ -1904,6 +1970,7 @@ Ammo: (Propz: ammoprop_NoRoundEnd or ammoprop_AttackInMove or ammoprop_DontHold or + ammoprop_NeedUpDown or ammoprop_Utility; Count: 1; NumPerTurn: 3; @@ -1956,7 +2023,11 @@ NameTex: nil; Probability: 0; NumberInCase: 1; - Ammo: (Propz: ammoprop_Timerable or ammoprop_Power or ammoprop_AltUse or ammoprop_SetBounce; + Ammo: (Propz: ammoprop_Timerable or + ammoprop_Power or + ammoprop_AltUse or + ammoprop_NeedUpDown or + ammoprop_SetBounce; Count: AMMO_INFINITE; NumPerTurn: 0; Timer: 3000; @@ -1980,7 +2051,8 @@ NameTex: nil; Probability: 20; NumberInCase: 2; - Ammo: (Propz: ammoprop_AttackInMove; + Ammo: (Propz: ammoprop_AttackInMove or + ammoprop_NeedUpDown; Count: 1; NumPerTurn: 0; Timer: 0; @@ -2004,7 +2076,9 @@ NameTex: nil; Probability: 20; NumberInCase: 1; - Ammo: (Propz: ammoprop_ForwMsgs or ammoprop_DontHold; + Ammo: (Propz: ammoprop_ForwMsgs or + ammoprop_NeedUpDown or + ammoprop_DontHold; Count: 1; NumPerTurn: 0; Timer: 5001; @@ -2028,7 +2102,8 @@ NameTex: nil; Probability: 100; NumberInCase: 1; - Ammo: (Propz: ammoprop_Power; //FIXME: enable multishoot at altuse, until then removed ammoprop_AltUse + Ammo: (Propz: ammoprop_Power or + ammoprop_NeedUpDown; //FIXME: enable multishoot at altuse, until then removed ammoprop_AltUse Count: 1; NumPerTurn: 1; Timer: 0; @@ -2062,7 +2137,7 @@ Bounciness: 1000); Slot: 3; TimeAfterTurn: 3000; - MinAngle: 0; + minAngle: 0; maxAngle: 0; isDamaging: true; SkipTurns: 0; @@ -2212,6 +2287,7 @@ Probability: 20; NumberInCase: 1; Ammo: (Propz: ammoprop_NoRoundEnd or + ammoprop_NeedTarget or ammoprop_Utility; Count: 1; NumPerTurn: 0; @@ -2232,23 +2308,25 @@ ejectY: -3) ); +const GearKindAmmoTypeMap : array [TGearType] of TAmmoType = ( -(* gtGrenade *) amGrenade +(* gtFlame *) amNothing (* gtHedgehog *) , amNothing +(* gtMine *) , amNothing +(* gtCase *) , amNothing +(* gtExplosives *) , amNothing +(* gtGrenade *) , amGrenade (* gtShell *) , amBazooka (* gtGrave *) , amNothing (* gtBee *) , amBee (* gtShotgunShot *) , amShotgun (* gtPickHammer *) , amPickHammer (* gtRope *) , amRope -(* gtMine *) , amNothing -(* gtCase *) , amNothing (* gtDEagleShot *) , amDEagle (* gtDynamite *) , amDynamite (* gtClusterBomb *) , amClusterBomb (* gtCluster *) , amClusterBomb (* gtShover *) , amBaseballBat // Shover is only used for baseball bat right now -(* gtFlame *) , amNothing (* gtFirePunch *) , amFirePunch (* gtATStartGame *) , amNothing (* gtATFinishGame *) , amNothing @@ -2276,7 +2354,6 @@ (*gtSniperRifleShot *) , amSniperRifle (* gtJetpack *) , amJetpack (* gtMolotov *) , amMolotov -(* gtExplosives *) , amNothing (* gtBirdy *) , amBirdy (* gtEgg *) , amBirdy (* gtPortal *) , amPortalGun @@ -2378,7 +2455,6 @@ vobSDFrameTicks, vobSDFramesCount, vobSDCount: Longword; vobSDVelocity, vobSDFallSpeed: LongInt; - hideAmmoMenu: boolean; wheelUp: boolean; wheelDown: boolean; @@ -2394,29 +2470,7 @@ ControllerHats: array[0..5] of array[0..19] of Byte; ControllerButtons: array[0..5] of array[0..19] of Byte; - DefaultBinds, CurrentBinds: TBinds; - - coeff: LongInt; - -{$IFDEF HWLIBRARY} - leftClick: boolean; - middleClick: boolean; - rightClick: boolean; - - upKey: boolean; - downKey: boolean; - rightKey: boolean; - leftKey: boolean; - preciseKey: boolean; - - backspaceKey: boolean; - spaceKey: boolean; - enterKey: boolean; - tabKey: boolean; - - chatAction: boolean; - pauseAction: boolean; -{$ENDIF} + DefaultBinds : TBinds; var trammo: array[TAmmoStrId] of ansistring; // name of the weapon trammoc: array[TAmmoStrId] of ansistring; // caption of the weapon @@ -2563,12 +2617,28 @@ else cMaxCaptions:= 4; + vobFrameTicks:= 99999; + vobFramesCount:= 4; + vobCount:= 0; + vobVelocity:= 10; + vobFallSpeed:= 100; + vobSDFrameTicks:= 99999; vobSDFramesCount:= 4; vobSDCount:= 30 * cScreenSpace div LAND_WIDTH; vobSDVelocity:= 15; vobSDFallSpeed:= 250; + PrevX:= 0; + timedelta:= 0; + Counter:= 0; + StepTicks:= 0; + ExplosionBorderColor:= $FF808080; + WaterOpacity:= $80; + SDWaterOpacity:= $80; + prevGState:= gsConfirm; + GrayScale:= false; + LuaGoals:= ''; end; diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uVisualGears.pas --- a/hedgewars/uVisualGears.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uVisualGears.pas Wed May 02 23:53:45 2012 +0200 @@ -34,20 +34,26 @@ procedure initModule; procedure freeModule; -function AddVisualGear(X, Y: LongInt; Kind: TVisualGearType; State: LongWord = 0; Critical: Boolean = false): PVisualGear; +function AddVisualGear(X, Y: LongInt; Kind: TVisualGearType): PVisualGear; inline; +function AddVisualGear(X, Y: LongInt; Kind: TVisualGearType; State: LongWord): PVisualGear; inline; +function AddVisualGear(X, Y: LongInt; Kind: TVisualGearType; State: LongWord; Critical: Boolean): PVisualGear; + procedure ProcessVisualGears(Steps: Longword); -procedure KickFlakes(Radius, X, Y: LongInt); procedure DrawVisualGears(Layer: LongWord); procedure DeleteVisualGear(Gear: PVisualGear); function VisualGearByUID(uid : Longword) : PVisualGear; + procedure AddClouds; -procedure ChangeToSDClouds; procedure AddFlakes; -procedure ChangeToSDFlakes; procedure AddDamageTag(X, Y, Damage, Color: LongWord); +procedure ChangeToSDClouds; +procedure ChangeToSDFlakes; + +procedure KickFlakes(Radius, X, Y: LongInt); + implementation -uses uSound, uMobile, uVariables, uTextures, uRender, Math, uRenderUtils, uStore; +uses uSound, uMobile, uVariables, uTextures, uRender, Math, uRenderUtils, uStore, uUtils; const cExplFrameTicks = 110; @@ -112,8 +118,17 @@ @doStepStraightShot ); -function AddVisualGear(X, Y: LongInt; Kind: TVisualGearType; State: LongWord = 0; Critical: Boolean = false): PVisualGear; -const VGCounter: Longword = 0; +function AddVisualGear(X, Y: LongInt; Kind: TVisualGearType): PVisualGear; inline; +begin + AddVisualGear:= AddVisualGear(X, Y, Kind, 0, false); +end; + +function AddVisualGear(X, Y: LongInt; Kind: TVisualGearType; State: LongWord): PVisualGear; inline; +begin + AddVisualGear:= AddVisualGear(X, Y, Kind, State, false); +end; + +function AddVisualGear(X, Y: LongInt; Kind: TVisualGearType; State: LongWord; Critical: Boolean): PVisualGear; var gear: PVisualGear; t: Longword; sp: real; @@ -365,7 +380,11 @@ Frame:= 7; Angle:= 0; end; -vgtSmoothWindBar: Tag:= hwRound(cWindSpeed * 72 / cMaxWindSpeed); +vgtSmoothWindBar: + begin + Angle:= hwFloat2Float(cMaxWindSpeed)*2 / 1440; // seems rate below is supposed to change wind bar at 1px per 10ms. Max time, 1440ms. This tries to match the rate of change + Tag:= hwRound(cWindSpeed * 72 / cMaxWindSpeed); + end; vgtStraightShot: begin Angle:= 0; @@ -566,12 +585,12 @@ if vobSDVelocity = 0 then DrawSprite(sprSDFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame) else - DrawRotatedF(sprSDFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, Gear^.Angle) + DrawSpriteRotatedF(sprSDFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, Gear^.Angle) else if vobVelocity = 0 then DrawSprite(sprFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame) else - DrawRotatedF(sprFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, Gear^.Angle) + DrawSpriteRotatedF(sprFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, Gear^.Angle) end else begin @@ -579,12 +598,12 @@ if vobSDVelocity = 0 then DrawTextureF(SpritesData[sprSDFlake].Texture, Gear^.Scale, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, SpritesData[sprFlake].Width, SpritesData[sprFlake].Height) else - DrawRotatedTextureF(SpritesData[sprSDFlake].Texture, Gear^.Scale, 0, 0, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, SpritesData[sprFlake].Width, SpritesData[sprFlake].Height, Gear^.Angle) + DrawTextureRotatedF(SpritesData[sprSDFlake].Texture, Gear^.Scale, 0, 0, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, SpritesData[sprFlake].Width, SpritesData[sprFlake].Height, Gear^.Angle) else if vobVelocity = 0 then DrawTextureF(SpritesData[sprFlake].Texture, Gear^.Scale, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, SpritesData[sprFlake].Width, SpritesData[sprFlake].Height) else - DrawRotatedTextureF(SpritesData[sprFlake].Texture, Gear^.Scale, 0, 0, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, SpritesData[sprFlake].Width, SpritesData[sprFlake].Height, Gear^.Angle) + DrawTextureRotatedF(SpritesData[sprFlake].Texture, Gear^.Scale, 0, 0, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, SpritesData[sprFlake].Width, SpritesData[sprFlake].Height, Gear^.Angle) end; end; if Gear^.Tint <> $FFFFFFFF then @@ -605,12 +624,12 @@ if vobSDVelocity = 0 then DrawSprite(sprSDFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame) else - DrawRotatedF(sprSDFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, Gear^.Angle) + DrawSpriteRotatedF(sprSDFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, Gear^.Angle) else if vobVelocity = 0 then DrawSprite(sprFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame) else - DrawRotatedF(sprFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, Gear^.Angle); + DrawSpriteRotatedF(sprFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, Gear^.Angle); vgtSmokeTrace: if Gear^.State < 8 then DrawSprite(sprSmokeTrace, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.State); vgtEvilTrace: if Gear^.State < 8 then @@ -661,27 +680,27 @@ if vobSDVelocity = 0 then DrawSprite(sprSDFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame) else - DrawRotatedF(sprSDFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, Gear^.Angle) + DrawSpriteRotatedF(sprSDFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, Gear^.Angle) else if vobVelocity = 0 then DrawSprite(sprFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame) else - DrawRotatedF(sprFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, Gear^.Angle);*) + DrawSpriteRotatedF(sprFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, Gear^.Angle);*) vgtSpeechBubble: begin if (Gear^.Tex <> nil) and (((Gear^.State = 0) and (Gear^.Hedgehog^.Team <> CurrentTeam)) or (Gear^.State = 1)) then begin tinted:= true; Tint($FF, $FF, $FF, $66); - DrawCentered(round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Tex) + DrawTextureCentered(round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Tex) end else if (Gear^.Tex <> nil) and (((Gear^.State = 0) and (Gear^.Hedgehog^.Team = CurrentTeam)) or (Gear^.State = 2)) then - DrawCentered(round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Tex); + DrawTextureCentered(round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Tex); end; - vgtSmallDamageTag: DrawCentered(round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Tex); + vgtSmallDamageTag: DrawTextureCentered(round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Tex); vgtHealthTag: if Gear^.Tex <> nil then begin if Gear^.Frame = 0 then - DrawCentered(round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Tex) + DrawTextureCentered(round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Tex) else begin SetScale(cDefaultZoomLevel); @@ -697,12 +716,12 @@ i:= -1 else i:= 1; - DrawRotatedTextureF(SpritesData[TSprite(Gear^.State)].Texture, Gear^.Scale, 0, 0, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, i, SpritesData[TSprite(Gear^.State)].Width, SpritesData[TSprite(Gear^.State)].Height, Gear^.Angle); + DrawTextureRotatedF(SpritesData[TSprite(Gear^.State)].Texture, Gear^.Scale, 0, 0, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, i, SpritesData[TSprite(Gear^.State)].Width, SpritesData[TSprite(Gear^.State)].Height, Gear^.Angle); end; end; if (cReducedQuality and rqAntiBoom) = 0 then case Gear^.Kind of - vgtChunk: DrawRotatedF(sprChunk, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, Gear^.Angle); + vgtChunk: DrawSpriteRotatedF(sprChunk, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, Gear^.Angle); end; if (Gear^.Tint <> $FFFFFFFF) or tinted then Tint($FF,$FF,$FF,$FF); @@ -722,7 +741,7 @@ vgtBigExplosion: begin tinted:= true; Tint($FF, $FF, $FF, round($FF * (1 - power(Gear^.Timer / 250, 4)))); - DrawRotatedTextureF(SpritesData[sprBigExplosion].Texture, 0.85 * (-power(2, -10 * Int(Gear^.Timer)/250) + 1) + 0.4, 0, 0, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, 0, 1, 385, 385, Gear^.Angle); + DrawTextureRotatedF(SpritesData[sprBigExplosion].Texture, 0.85 * (-power(2, -10 * Int(Gear^.Timer)/250) + 1) + 0.4, 0, 0, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, 0, 1, 385, 385, Gear^.Angle); end; end; if (cReducedQuality and rqAntiBoom) = 0 then @@ -742,7 +761,7 @@ Tint($FF, $FF, $FF, Gear^.FrameTicks); tinted:= true end; - DrawRotatedF(sprShell, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, Gear^.Angle); + DrawSpriteRotatedF(sprShell, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, Gear^.Angle); end; vgtFeather: begin if Gear^.FrameTicks < 255 then @@ -750,36 +769,36 @@ Tint($FF, $FF, $FF, Gear^.FrameTicks); tinted:= true end; - DrawRotatedF(sprFeather, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, Gear^.Angle); + DrawSpriteRotatedF(sprFeather, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, Gear^.Angle); end; - vgtEgg: DrawRotatedF(sprEgg, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, Gear^.Angle); + vgtEgg: DrawSpriteRotatedF(sprEgg, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, Gear^.Angle); vgtBeeTrace: begin if Gear^.FrameTicks < $FF then Tint($FF, $FF, $FF, Gear^.FrameTicks div 2) else Tint($FF, $FF, $FF, $80); tinted:= true; - DrawRotatedF(sprBeeTrace, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, (RealTicks shr 4) mod cMaxAngle); + DrawSpriteRotatedF(sprBeeTrace, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, (RealTicks shr 4) mod cMaxAngle); end; vgtSmokeRing: begin tinted:= true; Tint($FF, $FF, $FF, round(Gear^.alpha * $FF)); - DrawRotatedTextureF(SpritesData[sprSmokeRing].Texture, Gear^.scale, 0, 0, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, 0, 1, 200, 200, Gear^.Angle); + DrawTextureRotatedF(SpritesData[sprSmokeRing].Texture, Gear^.scale, 0, 0, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, 0, 1, 200, 200, Gear^.Angle); end; - vgtNote: DrawRotatedF(sprNote, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, Gear^.Angle); - vgtBulletHit: DrawRotatedF(sprBulletHit, round(Gear^.X) + WorldDx - 0, round(Gear^.Y) + WorldDy - 0, 7 - (Gear^.FrameTicks div 50), 1, Gear^.Angle); + vgtNote: DrawSpriteRotatedF(sprNote, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, Gear^.Angle); + vgtBulletHit: DrawSpriteRotatedF(sprBulletHit, round(Gear^.X) + WorldDx - 0, round(Gear^.Y) + WorldDy - 0, 7 - (Gear^.FrameTicks div 50), 1, Gear^.Angle); end; case Gear^.Kind of vgtFlake: if SuddenDeathDmg then if vobSDVelocity = 0 then DrawTextureF(SpritesData[sprSDFlake].Texture, Gear^.Scale, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, SpritesData[sprFlake].Width, SpritesData[sprFlake].Height) else - DrawRotatedTextureF(SpritesData[sprSDFlake].Texture, Gear^.Scale, 0, 0, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, SpritesData[sprFlake].Width, SpritesData[sprFlake].Height, Gear^.Angle) + DrawTextureRotatedF(SpritesData[sprSDFlake].Texture, Gear^.Scale, 0, 0, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, SpritesData[sprFlake].Width, SpritesData[sprFlake].Height, Gear^.Angle) else if vobVelocity = 0 then DrawTextureF(SpritesData[sprFlake].Texture, Gear^.Scale, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, SpritesData[sprFlake].Width, SpritesData[sprFlake].Height) else - DrawRotatedTextureF(SpritesData[sprFlake].Texture, Gear^.Scale, 0, 0, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, SpritesData[sprFlake].Width, SpritesData[sprFlake].Height, Gear^.Angle); + DrawTextureRotatedF(SpritesData[sprFlake].Texture, Gear^.Scale, 0, 0, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, SpritesData[sprFlake].Width, SpritesData[sprFlake].Height, Gear^.Angle); vgtCircle: if gear^.Angle = 1 then begin tmp:= Gear^.State / 100; @@ -809,12 +828,12 @@ if vobSDVelocity = 0 then DrawTextureF(SpritesData[sprSDFlake].Texture, Gear^.Scale, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, SpritesData[sprFlake].Width, SpritesData[sprFlake].Height) else - DrawRotatedTextureF(SpritesData[sprSDFlake].Texture, Gear^.Scale, 0, 0, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, SpritesData[sprFlake].Width, SpritesData[sprFlake].Height, Gear^.Angle) + DrawTextureRotatedF(SpritesData[sprSDFlake].Texture, Gear^.Scale, 0, 0, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, SpritesData[sprFlake].Width, SpritesData[sprFlake].Height, Gear^.Angle) else if vobVelocity = 0 then DrawTextureF(SpritesData[sprFlake].Texture, Gear^.Scale, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, SpritesData[sprFlake].Width, SpritesData[sprFlake].Height) else - DrawRotatedTextureF(SpritesData[sprFlake].Texture, Gear^.Scale, 0, 0, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, SpritesData[sprFlake].Width, SpritesData[sprFlake].Height, Gear^.Angle); + DrawTextureRotatedF(SpritesData[sprFlake].Texture, Gear^.Scale, 0, 0, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, SpritesData[sprFlake].Width, SpritesData[sprFlake].Height, Gear^.Angle); end; if (Gear^.Tint <> $FFFFFFFF) then Tint($FF,$FF,$FF,$FF); @@ -837,12 +856,12 @@ if vobSDVelocity = 0 then DrawSprite(sprSDFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame) else - DrawRotatedF(sprSDFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, Gear^.Angle) + DrawSpriteRotatedF(sprSDFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, Gear^.Angle) else if vobVelocity = 0 then DrawSprite(sprFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame) else - DrawRotatedF(sprFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, Gear^.Angle); + DrawSpriteRotatedF(sprFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, Gear^.Angle); end; if (Gear^.Tint <> $FFFFFFFF) then Tint($FF,$FF,$FF,$FF); @@ -861,12 +880,12 @@ if vobSDVelocity = 0 then DrawSprite(sprSDFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame) else - DrawRotatedF(sprSDFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, Gear^.Angle) + DrawSpriteRotatedF(sprSDFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, Gear^.Angle) else if vobVelocity = 0 then DrawSprite(sprFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame) else - DrawRotatedF(sprFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, Gear^.Angle); + DrawSpriteRotatedF(sprFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, Gear^.Angle); end; if (Gear^.Tint <> $FFFFFFFF) then Tint($FF,$FF,$FF,$FF); @@ -976,6 +995,7 @@ procedure initModule; var i: LongWord; begin +VGCounter:= 0; for i:= 0 to 6 do VisualGearLayers[i]:= nil; end; @@ -983,6 +1003,7 @@ procedure freeModule; var i: LongWord; begin +VGCounter:= 0; for i:= 0 to 6 do while VisualGearLayers[i] <> nil do DeleteVisualGear(VisualGearLayers[i]); end; diff -r 9e724f4863a3 -r 6af78154dc62 hedgewars/uWorld.pas --- a/hedgewars/uWorld.pas Sun Apr 01 15:23:34 2012 +0200 +++ b/hedgewars/uWorld.pas Wed May 02 23:53:45 2012 +0200 @@ -36,6 +36,7 @@ procedure ShakeCamera(amount: LongInt); procedure InitCameraBorders; procedure InitTouchInterface; +procedure SetUtilityWidgetState(ammoType: TAmmoType); procedure animateWidget(widget: POnScreenWidget; fade, showWidget: boolean); procedure MoveCamera; procedure onFocusStateChanged; @@ -381,6 +382,7 @@ STurns: LongInt; amSurface: PSDL_Surface; AMRect: TSDL_Rect; + tmpsurf: PSDL_Surface; begin SlotsNum:= 0; for i:= 0 to cMaxSlotIndex do @@ -389,11 +391,18 @@ {$IFDEF USE_LANDSCAPE_AMMOMENU} SlotsNumX:= SlotsNum; SlotsNumY:= cMaxSlotAmmoIndex + 2; + {$IFDEF USE_AM_NUMCOLUMN} + inc(SlotsNumY); + {$ENDIF} {$ELSE} SlotsNumX:= cMaxSlotAmmoIndex + 1; SlotsNumY:= SlotsNum + 1; + {$IFDEF USE_AM_NUMCOLUMN} + inc(SlotsNumX); + {$ENDIF} {$ENDIF} + AmmoRect.w:= (BORDERSIZE*2) + (SlotsNumX * AMSlotSize) + (SlotsNumX-1); AmmoRect.h:= (BORDERSIZE*2) + (SlotsNumY * AMSlotSize) + (SlotsNumY-1); amSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, AmmoRect.w, AmmoRect.h, 32, RMask, GMask, BMask, AMask); @@ -415,6 +424,21 @@ {$ELSE} x:= AMRect.x; {$ENDIF} +{$IFDEF USE_AM_NUMCOLUMN} + tmpsurf:= TTF_RenderUTF8_Blended(Fontz[fnt16].Handle, Str2PChar('F' + IntToStr(i+1)), cWhiteColorChannels); + copyToXY(tmpsurf, amSurface, + x + AMSlotPadding + (AMSlotSize shr 1) - (tmpsurf^.w shr 1), + y + AMSlotPadding + (AMSlotSize shr 1) - (tmpsurf^.h shr 1)); + + SDL_FreeSurface(tmpsurf); + {$IFDEF USE_LANDSCAPE_AMMOMENU} + y:= AMRect.y + AMSlotSize + 1; + {$ELSE} + x:= AMRect.x + AMSlotSize + 1; + {$ENDIF} +{$ENDIF} + + for t:=0 to cMaxSlotAmmoIndex do begin if (Ammo^[i, t].Count > 0) and (Ammo^[i, t].AmmoType <> amNothing) then @@ -432,8 +456,8 @@ end else //draw colored version begin - DrawSprite2Surf(sprAMAmmos, amSurface, x + AMSlotPadding, - y + AMSlotPadding, AMFrame); + DrawSprite2Surf(sprAMAmmos, amSurface, x + AMSlotPadding, + y + AMSlotPadding, AMFrame); end; {$IFDEF USE_LANDSCAPE_AMMOMENU} inc(y, AMSlotSize + 1); //the plus one is for the border @@ -480,23 +504,22 @@ begin if (TurnTimeLeft = 0) or (not CurrentTeam^.ExtDriven and (((CurAmmoGear = nil) or ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) = 0)) and hideAmmoMenu)) then -bShowAmmoMenu:= false; - + bShowAmmoMenu:= false; // give the assigned ammo to hedgehog Ammo:= nil; if (CurrentTeam <> nil) and (CurrentHedgehog <> nil) and (not CurrentTeam^.ExtDriven) and (CurrentHedgehog^.BotLevel = 0) then -Ammo:= CurrentHedgehog^.Ammo + Ammo:= CurrentHedgehog^.Ammo else if (LocalAmmo <> -1) then -Ammo:= GetAmmoByNum(LocalAmmo); + Ammo:= GetAmmoByNum(LocalAmmo); Pos:= -1; if Ammo = nil then -begin -bShowAmmoMenu:= false; -AMState:= AMHidden; -exit -end; + begin + bShowAmmoMenu:= false; + AMState:= AMHidden; + exit + end; //Init the menu if(AmmoMenuInvalidated) then @@ -596,13 +619,21 @@ Pos:= -1; Slot:= -1; +{$IFDEF USE_LANDSCAPE_AMMOMENU} + {$IFDEF USE_AM_NUMCOLUMN} +c:= 0; + {$ELSE} c:= -1; -{$IFDEF USE_LANDSCAPE_AMMOMENU} + {$ENDIF} for i:= 0 to cMaxSlotIndex do if ((i = 0) and (Ammo^[i, 1].Count > 0)) or ((i <> 0) and (Ammo^[i, 0].Count > 0)) then begin inc(c); + {$IFDEF USE_AM_NUMCOLUMN} + g:= 1; + {$ELSE} g:= 0; + {$ENDIF} for t:=0 to cMaxSlotAmmoIndex do if (Ammo^[i, t].Count > 0) and (Ammo^[i, t].AmmoType <> amNothing) then begin @@ -623,11 +654,20 @@ end; end; {$ELSE} + {$IFDEF USE_AM_NUMCOLUMN} +c:= -1; + {$ELSE} +c:= 0; + {$ENDIF} for i:= 0 to cMaxSlotIndex do if ((i = 0) and (Ammo^[i, 1].Count > 0)) or ((i <> 0) and (Ammo^[i, 0].Count > 0)) then begin inc(c); + {$IFDEF USE_AM_NUMCOLUMN} + g:= 1; + {$ELSE} g:= 0; + {$ENDIF} for t:=0 to cMaxSlotAmmoIndex do if (Ammo^[i, t].Count > 0) and (Ammo^[i, t].AmmoType <> amNothing) then begin @@ -674,7 +714,7 @@ bSelected:= false; FreeWeaponTooltip; {$IFDEF USE_TOUCH_INTERFACE}//show the aiming buttons + animation - if (Ammo^[Slot, Pos].Propz and ammoprop_NoCrosshair) = 0 then + if (Ammo^[Slot, Pos].Propz and ammoprop_NeedUpDown) <> 0 then begin if not(arrowUp.show) then begin @@ -688,16 +728,8 @@ animateWidget(@arrowUp, true, false); animateWidget(@arrowDown, true, false); end; - if (Ammo^[Slot, Pos].Propz and ammoprop_Timerable) <> 0 then - begin - if not utilityWidget.show then - animateWidget(@utilityWidget, true, true); - end - else - if utilityWidget.show then - animateWidget(@utilityWidget, true, false); + SetUtilityWidgetState(Ammo^[Slot, Pos].AmmoType); {$ENDIF} - exit end; end @@ -714,7 +746,7 @@ {$ENDIF} bSelected:= false; -{$IFNDEF USE_LANDSCAPE_AMMOMENU} +{$IFNDEF USE_TOUCH_INTERFACE} if (AMShiftX = 0) and (AMShiftY = 0) then DrawSprite(sprArrow, CursorPoint.X, cScreenHeight - CursorPoint.Y, (RealTicks shr 6) mod 8); {$ENDIF} @@ -1154,9 +1186,9 @@ DrawVisualGears(6); if SuddenDeathDmg then - DrawWater(cSDWaterOpacity, 0) + DrawWater(SDWaterOpacity, 0) else - DrawWater(cWaterOpacity, 0); + DrawWater(WaterOpacity, 0); // Waves ChangeDepth(RM, cStereo_Water_near); @@ -1164,19 +1196,19 @@ if (cReducedQuality and rq2DWater) = 0 then begin - //DrawWater(cWaterOpacity, - offsetY div 40); + //DrawWater(WaterOpacity, - offsetY div 40); ChangeDepth(RM, cStereo_Water_near); DrawWaves(-1, 50 + WorldDx div 6, - cWaveHeight - offsetY div 40, 8); if SuddenDeathDmg then - DrawWater(cSDWaterOpacity, - offsetY div 20) + DrawWater(SDWaterOpacity, - offsetY div 20) else - DrawWater(cWaterOpacity, - offsetY div 20); + DrawWater(WaterOpacity, - offsetY div 20); ChangeDepth(RM, cStereo_Water_near); DrawWaves( 1, 75 - WorldDx div 4, - cWaveHeight - offsetY div 20, 2); if SuddenDeathDmg then - DrawWater(cSDWaterOpacity, - offsetY div 10) + DrawWater(SDWaterOpacity, - offsetY div 10) else - DrawWater(cWaterOpacity, - offsetY div 10); + DrawWater(WaterOpacity, - offsetY div 10); ChangeDepth(RM, cStereo_Water_near); DrawWaves( -1, 25 + WorldDx div 3, - cWaveHeight - offsetY div 10, 0); end @@ -1200,9 +1232,9 @@ with PHedgehog(CurrentHedgehog)^ do begin if CurAmmoType = amBee then - DrawRotatedF(sprTargetBee, TargetPoint.X + WorldDx, TargetPoint.Y + WorldDy, 0, 0, (RealTicks shr 3) mod 360) + DrawSpriteRotatedF(sprTargetBee, TargetPoint.X + WorldDx, TargetPoint.Y + WorldDy, 0, 0, (RealTicks shr 3) mod 360) else - DrawRotatedF(sprTargetP, TargetPoint.X + WorldDx, TargetPoint.Y + WorldDy, 0, 0, (RealTicks shr 3) mod 360) + DrawSpriteRotatedF(sprTargetP, TargetPoint.X + WorldDx, TargetPoint.Y + WorldDy, 0, 0, (RealTicks shr 3) mod 360) end end; {$WARNINGS ON} @@ -1286,13 +1318,13 @@ r.y:= 0; r.w:= 2 + TeamHealthBarWidth; r.h:= HealthTex^.h; - DrawFromRect(14, cScreenHeight + DrawHealthY + smallScreenOffset, @r, HealthTex); + DrawTextureFromRect(14, cScreenHeight + DrawHealthY + smallScreenOffset, @r, HealthTex); // draw health bars right border inc(r.x, cTeamHealthWidth + 2); if TeamHealth = 0 then inc(r.x); r.w:= 3; - DrawFromRect(TeamHealthBarWidth + 16, cScreenHeight + DrawHealthY + smallScreenOffset, @r, HealthTex); + DrawTextureFromRect(TeamHealthBarWidth + 16, cScreenHeight + DrawHealthY + smallScreenOffset, @r, HealthTex); if not highlight and not hasGone and (TeamHealth > 1) then for i:= 0 to cMaxHHIndex do @@ -1321,15 +1353,15 @@ r.y:= 2; r.w:= NameTagTex^.w - 4; r.h:= NameTagTex^.h - 4; - DrawFromRect(-NameTagTex^.w - 14, cScreenHeight + DrawHealthY + smallScreenOffset + 2, @r, NameTagTex); + DrawTextureFromRect(-NameTagTex^.w - 14, cScreenHeight + DrawHealthY + smallScreenOffset + 2, @r, NameTagTex); // draw flag r.w:= 22; r.h:= 15; - DrawFromRect(-12, cScreenHeight + DrawHealthY + smallScreenOffset + 2, @r, FlagTex); + DrawTextureFromRect(-12, cScreenHeight + DrawHealthY + smallScreenOffset + 2, @r, FlagTex); // draw health bar r.w:= TeamHealthBarWidth + 1; r.h:= HealthTex^.h - 4; - DrawFromRect(16, cScreenHeight + DrawHealthY + smallScreenOffset + 2, @r, HealthTex); + DrawTextureFromRect(16, cScreenHeight + DrawHealthY + smallScreenOffset + 2, @r, HealthTex); end; end; if smallScreenOffset <> 0 then @@ -1404,9 +1436,9 @@ // various captions if fastUntilLag then - DrawCentered(0, (cScreenHeight shr 1), SyncTexture); + DrawTextureCentered(0, (cScreenHeight shr 1), SyncTexture); if isPaused then - DrawCentered(0, (cScreenHeight shr 1), PauseTexture); + DrawTextureCentered(0, (cScreenHeight shr 1), PauseTexture); if not isFirstFrame and (missionTimer <> 0) or isPaused or fastUntilLag or (GameState = gsConfirm) then begin if (ReadyTimeLeft = 0) and (missionTimer > 0) then @@ -1414,7 +1446,7 @@ if missionTimer < 0 then missionTimer:= 0; // avoid subtracting below 0 if missionTex <> nil then - DrawCentered(0, Min((cScreenHeight shr 1) + 100, cScreenHeight - 48 - missionTex^.h), missionTex); + DrawTextureCentered(0, Min((cScreenHeight shr 1) + 100, cScreenHeight - 48 - missionTex^.h), missionTex); end; // fps @@ -1491,7 +1523,7 @@ end; if GameState = gsConfirm then - DrawCentered(0, (cScreenHeight shr 1), ConfirmTexture); + DrawTextureCentered(0, (cScreenHeight shr 1), ConfirmTexture); if ScreenFade <> sfNone then begin @@ -1546,7 +1578,7 @@ begin if (CurAmmoType = amNapalm) or (CurAmmoType = amMineStrike) then DrawLine(-3000, topY-300, 7000, topY-300, 3.0, (Team^.Clan^.Color shr 16), (Team^.Clan^.Color shr 8) and $FF, Team^.Clan^.Color and $FF, $FF); - i:= GetAmmoEntry(CurrentHedgehog^)^.Pos; + i:= GetCurAmmoEntry(CurrentHedgehog^)^.Pos; with Ammoz[CurAmmoType] do if PosCount > 1 then DrawSprite(PosSprite, CursorPoint.X - (SpritesData[PosSprite].Width shr 1), cScreenHeight - CursorPoint.Y - (SpritesData[PosSprite].Height shr 1),i); @@ -1712,6 +1744,38 @@ begin if (not cHasFocus) and (GameState <> gsConfirm) then ParseCommand('quit', true); + +if not cHasFocus then DampenAudio() +else UndampenAudio(); +end; + +procedure SetUtilityWidgetState(ammoType: TAmmoType); +begin +{$IFDEF TOUCH_INTERFACE} +if(ammoType = amNothing)then + ammoType:= CurrentHedgehog^.CurAmmoType; + +if(CurrentHedgehog <> nil)then + if (Ammoz[ammoType].Ammo.Propz and ammoprop_Timerable) <> 0 then + begin + utilityWidget.sprite:= sprTimerButton; + animateWidget(@utilityWidget, true, true); + end + else if (Ammoz[ammoType].Ammo.Propz and ammoprop_NeedTarget) <> 0 then + begin + utilityWidget.sprite:= sprTargetButton; + animateWidget(@utilityWidget, true, true); + end + else if ammoType = amSwitch then + begin + utilityWidget.sprite:= sprTargetButton; + animateWidget(@utilityWidget, true, true); + end + else if utilityWidget.show then + animateWidget(@utilityWidget, true, false); +{$ELSE} +ammoType:= ammoType; // avoid hint +{$ENDIF} end; procedure animateWidget(widget: POnScreenWidget; fade, showWidget: boolean); diff -r 9e724f4863a3 -r 6af78154dc62 misc/hats_js_anim.xhtml --- a/misc/hats_js_anim.xhtml Sun Apr 01 15:23:34 2012 +0200 +++ b/misc/hats_js_anim.xhtml Wed May 02 23:53:45 2012 +0200 @@ -47,6 +47,7 @@ /*var masks = ['2001suit2', '2001suit', '4gsuif', 'AkuAku', 'android', 'angel', 'anzac', 'apple', 'ash', 'Balrog', 'banana', 'Bandit', 'bat', 'beaver', 'beefeater', 'Blanka', 'BlankaToothless', 'BlueCap', 'BlueHair', 'bobby2v', 'bobby', 'Bob', 'BrainSlugMouth', 'BrainSlug', 'britishpithhelmet', 'britmedic', 'britsapper', 'Bub', 'Bunny', 'bushhider', 'charlesdegaulle', 'charmander', 'chef', 'chikorita', 'Chunli', 'clown-copper', 'clown-crossed', 'clown', 'Coonskin3', 'Cororon', 'Cowboy', 'crown', 'cyborg', 'darthvader', 'Deer', 'desertgrenadier01', 'desertgrenadier02', 'desertgrenadier04', 'desertgrenadier05', 'desertgrenadierofficer', 'desertmedic', 'desertsapper1', 'desertsapper2', 'diglett', 'Disguise', 'Dragon', 'dwarf', 'eastertop', 'Elvis', 'Eva_00b', 'Eva_00y', 'Falcon', 'frenchwwigasmask', 'frenchwwihelmet', 'Gasmask', 'Geordi', 'germanwiimedichelmet', 'germanwwihelmetmustache', 'germanwwiipithhelmetdes', 'germanwwitankhelmet', 'Glasses', 'GreenCap', 'GreenHair', 'grenadier1', 'GreyHair', 'Guile', 'hedgehogk', 'HogInTheHat', 'hogpharoah', 'Honda', 'IndianChief', 'infernalhorns', 'InfernalHorns', 'Jason', 'jigglypuff', 'judo', 'junior', 'Ken', 'KirbyMask', 'kiss_criss', 'kiss_frehley', 'kiss_simmons', 'kiss_stanley', 'knight', 'Kululun', 'Ladle', 'lambda', 'Laminaria', 'laurel', 'lemon', 'link', 'lugia', 'Luigi', 'Mario', 'MegaHogX', 'metalband', 'mexicansunbrero', 'mickey_ears', 'Moose', 'mp3', 'mudkip', 'Mummy', 'naruto', 'NinjaFull', 'NinjaStraight', 'NinjaTriangle', 'OldMan', 'OrangeHair', 'orange', 'Pantsu', 'Pig', 'pikachu', 'PinkHair', 'pinksunhat', 'pirate_jack_bandana', 'pirate_jack', 'plainpith', 'Plunger', 'policecap', 'porkey', 'PrincessDaisy', 'PrincessPeach', 'Pumpkin_Hat', 'PurpleHair', 'quotecap', 'Rain', 'Rambo', 'rasta', 'RedCap', 'RedHair', 'RobinHood', 'royalguard', 'RSR', 'Ryu', 'Samurai', 'Samus', 'Santa', 'SauceBoatSilver', 'ShaggyYeti', 'sheep', 'ShortHair_Black', 'ShortHair_Brown', 'ShortHair_Grey', 'ShortHair_Red', 'ShortHair_Yellow', 'Skull', 'Sleepwalker', 'slowpoke', 'Sniper', 'Sonic', 'sovietcomrade2', 'sovietcomrade', 'SparkleSuperFun', 'SparkssHelmet', 'spartan', 'spcartman', 'spidey', 'spkenny', 'spkyle', 'spstan', 'squirtle', 'sth_AmyClassic', 'sth_Amy', 'sth_Eggman', 'sth_Knux', 'sth_Metal', 'sth_Shadow', 'sth_Sonic', 'sth_Super', 'sth_Tails', 'stormcloud', 'stormtrooper', 'StrawHatEyes', 'StrawHatFacial', 'StrawHat', 'Sunglasses', 'SunWukong', 'Teacup', 'Teapot', 'terminatorc', 'Terminator_Glasses', 'thug', 'Toad', 'tophats', 'touhou_chen', 'touhou_marisa', 'touhou_patchouli', 'touhou_remelia', 'touhou_suwako', 'touhou_yukari', 'trenchgrenadier1', 'trenchgrenadier2', 'trenchgrenadier3', 'ushanka', 'vampirichog', 'Vega', 'venom', 'Viking', 'voltorb', 'Wario', 'WhySoSerious', 'WizardHat', 'YellowCap', 'YellowHair', 'Zombi'];*/ var masks = []; var themes = { +"Cave":1, "Golf":1, "Stage":1, "Island":0, diff -r 9e724f4863a3 -r 6af78154dc62 project_files/Android-build/SDL-android-project/jni/SDL/src/video/android/SDL_androidkeyboard.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/jni/SDL/src/video/android/SDL_androidkeyboard.c Wed May 02 23:53:45 2012 +0200 @@ -0,0 +1,185 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_config.h" + +#if SDL_VIDEO_DRIVER_ANDROID + +#include + +#include "../../events/SDL_events_c.h" + +#include "SDL_androidkeyboard.h" +#include "SDL_keycode.h" + + +void Android_InitKeyboard() +{ + SDL_Keycode keymap[SDL_NUM_SCANCODES]; + + /* Add default scancode to key mapping */ + SDL_GetDefaultKeymap(keymap); + SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES); +} + +static SDL_Scancode Android_Keycodes[] = { + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_UNKNOWN */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_SOFT_LEFT */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_SOFT_RIGHT */ + SDL_SCANCODE_AC_HOME, /* AKEYCODE_HOME */ + SDL_SCANCODE_AC_BACK, /* AKEYCODE_BACK */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_CALL */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_ENDCALL */ + SDL_SCANCODE_0, /* AKEYCODE_0 */ + SDL_SCANCODE_1, /* AKEYCODE_1 */ + SDL_SCANCODE_2, /* AKEYCODE_2 */ + SDL_SCANCODE_3, /* AKEYCODE_3 */ + SDL_SCANCODE_4, /* AKEYCODE_4 */ + SDL_SCANCODE_5, /* AKEYCODE_5 */ + SDL_SCANCODE_6, /* AKEYCODE_6 */ + SDL_SCANCODE_7, /* AKEYCODE_7 */ + SDL_SCANCODE_8, /* AKEYCODE_8 */ + SDL_SCANCODE_9, /* AKEYCODE_9 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_STAR */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_POUND */ + SDL_SCANCODE_UP, /* AKEYCODE_DPAD_UP */ + SDL_SCANCODE_DOWN, /* AKEYCODE_DPAD_DOWN */ + SDL_SCANCODE_LEFT, /* AKEYCODE_DPAD_LEFT */ + SDL_SCANCODE_RIGHT, /* AKEYCODE_DPAD_RIGHT */ + SDL_SCANCODE_SELECT, /* AKEYCODE_DPAD_CENTER */ + SDL_SCANCODE_VOLUMEUP, /* AKEYCODE_VOLUME_UP */ + SDL_SCANCODE_VOLUMEDOWN, /* AKEYCODE_VOLUME_DOWN */ + SDL_SCANCODE_POWER, /* AKEYCODE_POWER */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_CAMERA */ + SDL_SCANCODE_CLEAR, /* AKEYCODE_CLEAR */ + SDL_SCANCODE_A, /* AKEYCODE_A */ + SDL_SCANCODE_B, /* AKEYCODE_B */ + SDL_SCANCODE_C, /* AKEYCODE_C */ + SDL_SCANCODE_D, /* AKEYCODE_D */ + SDL_SCANCODE_E, /* AKEYCODE_E */ + SDL_SCANCODE_F, /* AKEYCODE_F */ + SDL_SCANCODE_G, /* AKEYCODE_G */ + SDL_SCANCODE_H, /* AKEYCODE_H */ + SDL_SCANCODE_I, /* AKEYCODE_I */ + SDL_SCANCODE_J, /* AKEYCODE_J */ + SDL_SCANCODE_K, /* AKEYCODE_K */ + SDL_SCANCODE_L, /* AKEYCODE_L */ + SDL_SCANCODE_M, /* AKEYCODE_M */ + SDL_SCANCODE_N, /* AKEYCODE_N */ + SDL_SCANCODE_O, /* AKEYCODE_O */ + SDL_SCANCODE_P, /* AKEYCODE_P */ + SDL_SCANCODE_Q, /* AKEYCODE_Q */ + SDL_SCANCODE_R, /* AKEYCODE_R */ + SDL_SCANCODE_S, /* AKEYCODE_S */ + SDL_SCANCODE_T, /* AKEYCODE_T */ + SDL_SCANCODE_U, /* AKEYCODE_U */ + SDL_SCANCODE_V, /* AKEYCODE_V */ + SDL_SCANCODE_W, /* AKEYCODE_W */ + SDL_SCANCODE_X, /* AKEYCODE_X */ + SDL_SCANCODE_Y, /* AKEYCODE_Y */ + SDL_SCANCODE_Z, /* AKEYCODE_Z */ + SDL_SCANCODE_COMMA, /* AKEYCODE_COMMA */ + SDL_SCANCODE_PERIOD, /* AKEYCODE_PERIOD */ + SDL_SCANCODE_LALT, /* AKEYCODE_ALT_LEFT */ + SDL_SCANCODE_RALT, /* AKEYCODE_ALT_RIGHT */ + SDL_SCANCODE_LSHIFT, /* AKEYCODE_SHIFT_LEFT */ + SDL_SCANCODE_RSHIFT, /* AKEYCODE_SHIFT_RIGHT */ + SDL_SCANCODE_TAB, /* AKEYCODE_TAB */ + SDL_SCANCODE_SPACE, /* AKEYCODE_SPACE */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_SYM */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_EXPLORER */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_ENVELOPE */ + SDL_SCANCODE_RETURN, /* AKEYCODE_ENTER */ + SDL_SCANCODE_BACKSPACE, /* AKEYCODE_DEL */ + SDL_SCANCODE_GRAVE, /* AKEYCODE_GRAVE */ + SDL_SCANCODE_MINUS, /* AKEYCODE_MINUS */ + SDL_SCANCODE_EQUALS, /* AKEYCODE_EQUALS */ + SDL_SCANCODE_LEFTBRACKET, /* AKEYCODE_LEFT_BRACKET */ + SDL_SCANCODE_RIGHTBRACKET, /* AKEYCODE_RIGHT_BRACKET */ + SDL_SCANCODE_BACKSLASH, /* AKEYCODE_BACKSLASH */ + SDL_SCANCODE_SEMICOLON, /* AKEYCODE_SEMICOLON */ + SDL_SCANCODE_APOSTROPHE, /* AKEYCODE_APOSTROPHE */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_SLASH */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_AT */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_NUM */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_HEADSETHOOK */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_FOCUS */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_PLUS */ + SDL_SCANCODE_MENU, /* AKEYCODE_MENU */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_NOTIFICATION */ + SDL_SCANCODE_AC_SEARCH, /* AKEYCODE_SEARCH */ + SDL_SCANCODE_AUDIOPLAY, /* AKEYCODE_MEDIA_PLAY_PAUSE */ + SDL_SCANCODE_AUDIOSTOP, /* AKEYCODE_MEDIA_STOP */ + SDL_SCANCODE_AUDIONEXT, /* AKEYCODE_MEDIA_NEXT */ + SDL_SCANCODE_AUDIOPREV, /* AKEYCODE_MEDIA_PREVIOUS */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_REWIND */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_FAST_FORWARD */ + SDL_SCANCODE_MUTE, /* AKEYCODE_MUTE */ + SDL_SCANCODE_PAGEUP, /* AKEYCODE_PAGE_UP */ + SDL_SCANCODE_PAGEDOWN, /* AKEYCODE_PAGE_DOWN */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_PICTSYMBOLS */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_SWITCH_CHARSET */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_A */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_B */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_C */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_X */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_Y */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_Z */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_L1 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_R1 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_L2 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_R2 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_THUMBL */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_THUMBR */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_START */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_SELECT */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_MODE */ +}; + +static SDL_Scancode +TranslateKeycode(int keycode) +{ + SDL_Scancode scancode = SDL_SCANCODE_UNKNOWN; + + if (keycode < SDL_arraysize(Android_Keycodes)) { + scancode = Android_Keycodes[keycode]; + } + if (scancode == SDL_SCANCODE_UNKNOWN) { + __android_log_print(ANDROID_LOG_INFO, "SDL", "Unknown keycode %d", keycode); + } + __android_log_print(ANDROID_LOG_INFO, "SDLXELI", "keycode %d scancode %d", keycode, scancode); + return scancode; +} + +int +Android_OnKeyDown(int keycode) +{ + return SDL_SendKeyboardKey(SDL_PRESSED, TranslateKeycode(keycode)); +} + +int +Android_OnKeyUp(int keycode) +{ + return SDL_SendKeyboardKey(SDL_RELEASED, TranslateKeycode(keycode)); +} + +#endif /* SDL_VIDEO_DRIVER_ANDROID */ + +/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e724f4863a3 -r 6af78154dc62 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 Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/SDLActivity.java Wed May 02 23:53:45 2012 +0200 @@ -100,11 +100,6 @@ super.onResume(); } - public void onBackPressed(){ - super.onBackPressed(); - PascalExports.HWterminate(true); - } - protected void onDestroy() { super.onDestroy(); Log.v("SDL", "onDestroy()"); @@ -441,7 +436,7 @@ } catch (InterruptedException e) { e.printStackTrace(); } - //Log.v("SDL", "SDL thread terminated"); + Log.v("SDL", "SDL thread terminated"); //Log.v("SDL", "SDL thread terminated"); } } @@ -481,14 +476,14 @@ Log.v("SDL", "surfaceCreated()"); holder.setType(SurfaceHolder.SURFACE_TYPE_GPU); SDLActivity.createEGLSurface(); -// enableSensor(Sensor.TYPE_ACCELEROMETER, true); + // 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); + // enableSensor(Sensor.TYPE_ACCELEROMETER, false); } // Called when the surface is resized @@ -554,7 +549,15 @@ // Key events public boolean onKey(View v, int keyCode, KeyEvent event) { - if(keyCode == KeyEvent.KEYCODE_BACK) return false; + switch(keyCode){ + case KeyEvent.KEYCODE_BACK: + PascalExports.HWterminate(true); + 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); diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Classes/AboutViewController.m --- a/project_files/HedgewarsMobile/Classes/AboutViewController.m Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/AboutViewController.m Wed May 02 23:53:45 2012 +0200 @@ -52,12 +52,12 @@ } -(IBAction) buttonPressed:(id) sender { - [AudioManagerController playBackSound]; + [[AudioManagerController mainManager] playBackSound]; [[self parentViewController] dismissModalViewControllerAnimated:YES]; } -(IBAction) segmentedControlChanged:(id) sender { - [AudioManagerController playClickSound]; + [[AudioManagerController mainManager] playClickSound]; [self.tableView setContentOffset:CGPointMake(0, 0) animated:NO]; [self.tableView reloadData]; } diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Classes/AudioManagerController.h --- a/project_files/HedgewarsMobile/Classes/AudioManagerController.h Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/AudioManagerController.h Wed May 02 23:53:45 2012 +0200 @@ -18,23 +18,41 @@ #import +#import +@class AVAudioPlayer; + @interface AudioManagerController : NSObject { + @private + AVAudioPlayer *backgroundMusic; + SystemSoundID clickSound; + SystemSoundID backSound; + SystemSoundID selSound; + NSOperationQueue *audioFaderQueue; } -+(void) playBackgroundMusic; -+(void) pauseBackgroundMusic; -+(void) stopBackgroundMusic; +@property (nonatomic,retain) AVAudioPlayer *backgroundMusic; +@property (assign) SystemSoundID clickSound; +@property (assign) SystemSoundID backSound; +@property (assign) SystemSoundID selSound; + +@property (nonatomic,retain) NSOperationQueue *audioFaderQueue; + ++(id) mainManager; -+(void) fadeInBackgroundMusic; -+(void) fadeOutBackgroundMusic; +-(void) playBackgroundMusic; +-(void) pauseBackgroundMusic; +-(void) stopBackgroundMusic; -+(void) playClickSound; -+(void) playBackSound; -+(void) playSelectSound; +-(void) fadeInBackgroundMusic; +-(void) fadeOutBackgroundMusic; -+(void) releaseCache; +-(void) playClickSound; +-(void) playBackSound; +-(void) playSelectSound; +-(SystemSoundID) loadSound:(NSString *)snd; +-(void) unloadSounds; @end diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Classes/AudioManagerController.m --- a/project_files/HedgewarsMobile/Classes/AudioManagerController.m Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/AudioManagerController.m Wed May 02 23:53:45 2012 +0200 @@ -19,88 +19,115 @@ #import "AudioManagerController.h" #import "AVFoundation/AVAudioPlayer.h" -#import #import "MXAudioPlayerFadeOperation.h" -static AVAudioPlayer *backgroundMusic = nil; -static SystemSoundID clickSound = -1; -static SystemSoundID backSound = -1; -static SystemSoundID selSound = -1; +#define DEFAULT_VOLUME 0.45f +#define FADEOUT_DURATION 3.0f +#define FADEIN_DURATION 2.0f -static NSOperationQueue *audioFaderQueue = nil; -static MXAudioPlayerFadeOperation *fadeIn = nil; -static MXAudioPlayerFadeOperation *fadeOut = nil; +static AudioManagerController *mainInstance; @implementation AudioManagerController +@synthesize backgroundMusic, clickSound, backSound, selSound, audioFaderQueue; + ++(id) mainManager { + if (mainInstance == nil) + mainInstance = [[self alloc] init]; + return mainInstance; +} + +-(id) init { + if ((self = [super init])) { + self.backgroundMusic = nil; + self.clickSound = -1; + self.backSound = -1; + self.selSound = -1; + + self.audioFaderQueue = nil; + } + return self; +} + +-(void) dealloc { + [self unloadSounds]; + releaseAndNil(backgroundMusic); + releaseAndNil(audioFaderQueue); + mainInstance = nil; + [super dealloc]; +} + +-(void) didReceiveMemoryWarning { + if (self.backgroundMusic.playing == NO) + self.backgroundMusic = nil; + if ([self.audioFaderQueue operationCount] == 0) + self.audioFaderQueue = nil; + + [self unloadSounds]; + MSG_MEMCLEAN(); +} #pragma mark - #pragma mark background music control -+(void) loadBackgroundMusic { - NSString *musicString = [[NSBundle mainBundle] pathForResource:@"hwclassic" ofType:@"mp3"]; - backgroundMusic = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:musicString] error:nil]; - - backgroundMusic.delegate = nil; - backgroundMusic.volume = 0; - backgroundMusic.numberOfLoops = -1; - [backgroundMusic prepareToPlay]; -} - -+(void) playBackgroundMusic { +-(void) playBackgroundMusic { if ([[[NSUserDefaults standardUserDefaults] objectForKey:@"music"] boolValue] == NO) return; - if (backgroundMusic == nil) - [AudioManagerController loadBackgroundMusic]; - - backgroundMusic.volume = 0.45f; - [backgroundMusic play]; + if (self.backgroundMusic == nil) { + NSString *musicString = [[NSBundle mainBundle] pathForResource:@"hwclassic" ofType:@"mp3"]; + self.backgroundMusic = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:musicString] error:nil]; + self.backgroundMusic.delegate = nil; + self.backgroundMusic.numberOfLoops = -1; + } + + self.backgroundMusic.volume = DEFAULT_VOLUME; + [self.backgroundMusic play]; } -+(void) pauseBackgroundMusic { - [backgroundMusic pause]; +-(void) pauseBackgroundMusic { + [self.backgroundMusic pause]; } -+(void) stopBackgroundMusic { - [backgroundMusic stop]; +-(void) stopBackgroundMusic { + [self.backgroundMusic stop]; } -+(void) fadeOutBackgroundMusic { +-(void) fadeOutBackgroundMusic { if ([[[NSUserDefaults standardUserDefaults] objectForKey:@"music"] boolValue] == NO) return; - if (audioFaderQueue == nil) - audioFaderQueue = [[NSOperationQueue alloc] init]; - if (backgroundMusic == nil) - [AudioManagerController loadBackgroundMusic]; - if (fadeOut == nil) - fadeOut = [[MXAudioPlayerFadeOperation alloc] initFadeWithAudioPlayer:backgroundMusic toVolume:0.0 overDuration:3.0]; - - [audioFaderQueue addOperation:fadeOut]; + if (self.audioFaderQueue == nil) + self.audioFaderQueue = [[NSOperationQueue alloc] init]; + + MXAudioPlayerFadeOperation *fadeOut = [[MXAudioPlayerFadeOperation alloc] initFadeWithAudioPlayer:self.backgroundMusic + toVolume:0.0 + overDuration:FADEOUT_DURATION]; + [self.audioFaderQueue addOperation:fadeOut]; + [fadeOut release]; } -+(void) fadeInBackgroundMusic { +-(void) fadeInBackgroundMusic { if ([[[NSUserDefaults standardUserDefaults] objectForKey:@"music"] boolValue] == NO) return; - if (audioFaderQueue == nil) - audioFaderQueue = [[NSOperationQueue alloc] init]; - if (backgroundMusic == nil) - [AudioManagerController loadBackgroundMusic]; - if (fadeIn == nil) - fadeIn = [[MXAudioPlayerFadeOperation alloc] initFadeWithAudioPlayer:backgroundMusic toVolume:0.45 overDuration:2.0]; + if (self.audioFaderQueue == nil) + self.audioFaderQueue = [[NSOperationQueue alloc] init]; + [self playBackgroundMusic]; + MXAudioPlayerFadeOperation *fadeIn = [[MXAudioPlayerFadeOperation alloc] initFadeWithAudioPlayer:self.backgroundMusic + toVolume:DEFAULT_VOLUME + overDuration:FADEIN_DURATION]; [audioFaderQueue addOperation:fadeIn]; + [fadeIn release]; } #pragma mark - #pragma mark sound effects control -+(SystemSoundID) loadSound:(NSString *)snd { - // get the filename of the sound file: - NSString *path = [NSString stringWithFormat:@"%@/%@",[[NSBundle mainBundle] resourcePath],snd]; +-(SystemSoundID) loadSound:(NSString *)snd { + SystemSoundID soundID; - // declare a system sound id and get a URL for the sound file - SystemSoundID soundID; + // get the filename of the sound file in a NSURL format + NSString *path = [[NSBundle mainBundle] pathForResource:snd ofType:@"caf"]; NSURL *filePath = [NSURL fileURLWithPath:path isDirectory:NO]; // use audio sevices to create and play the sound @@ -108,48 +135,40 @@ return soundID; } -+(void) playClickSound { - if ([[[NSUserDefaults standardUserDefaults] objectForKey:@"sound"] boolValue] == NO) - return; - - if (clickSound == -1) - clickSound = [AudioManagerController loadSound:@"clickSound.wav"]; - - AudioServicesPlaySystemSound(clickSound); +-(void) unloadSounds { + AudioServicesDisposeSystemSoundID(clickSound), clickSound = -1; + AudioServicesDisposeSystemSoundID(backSound), backSound = -1; + AudioServicesDisposeSystemSoundID(selSound), selSound = -1; } -+(void) playBackSound { +-(void) playClickSound { if ([[[NSUserDefaults standardUserDefaults] objectForKey:@"sound"] boolValue] == NO) return; - if (backSound == -1) - backSound = [AudioManagerController loadSound:@"backSound.wav"]; + if (self.clickSound == -1) + self.clickSound = [self loadSound:@"clickSound"]; - AudioServicesPlaySystemSound(backSound); + AudioServicesPlaySystemSound(self.clickSound); } -+(void) playSelectSound { +-(void) playBackSound { if ([[[NSUserDefaults standardUserDefaults] objectForKey:@"sound"] boolValue] == NO) return; - if (selSound == -1) - selSound = [AudioManagerController loadSound:@"selSound.wav"]; + if (self.backSound == -1) + self.backSound = [self loadSound:@"backSound"]; - AudioServicesPlaySystemSound(selSound); + AudioServicesPlaySystemSound(self.backSound); } -#pragma mark - -#pragma mark memory management -+(void) releaseCache { - [backgroundMusic stop]; - [backgroundMusic release], backgroundMusic = nil; - [fadeOut release], fadeOut = nil; - [fadeIn release], fadeIn = nil; - [audioFaderQueue release], audioFaderQueue = nil; - AudioServicesDisposeSystemSoundID(clickSound), clickSound = -1; - AudioServicesDisposeSystemSoundID(backSound), backSound = -1; - AudioServicesDisposeSystemSoundID(selSound), selSound = -1; - MSG_MEMCLEAN(); +-(void) playSelectSound { + if ([[[NSUserDefaults standardUserDefaults] objectForKey:@"sound"] boolValue] == NO) + return; + + if (self.selSound == -1) + self.selSound = [self loadSound:@"selSound"]; + + AudioServicesPlaySystemSound(self.selSound); } @end diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Classes/CGPointUtils.h --- a/project_files/HedgewarsMobile/Classes/CGPointUtils.h Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/CGPointUtils.h Wed May 02 23:53:45 2012 +0200 @@ -17,7 +17,7 @@ */ -#import +#include #define degreesToRadians(x) ( M_PI * x / 180.0) diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Classes/CreationChamber.h --- a/project_files/HedgewarsMobile/Classes/CreationChamber.h Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/CreationChamber.h Wed May 02 23:53:45 2012 +0200 @@ -24,6 +24,7 @@ } ++(void) createFirstLaunch; +(void) createSettings; +(void) createTeamNamed:(NSString *)nameWithoutExt; diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Classes/CreationChamber.m --- a/project_files/HedgewarsMobile/Classes/CreationChamber.m Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/CreationChamber.m Wed May 02 23:53:45 2012 +0200 @@ -22,6 +22,56 @@ @implementation CreationChamber +#pragma mark Checking status ++(void) createFirstLaunch { + DLog(@"Creating necessary files"); + NSInteger index; + + // SAVES - just delete and overwrite + if ([[NSFileManager defaultManager] fileExistsAtPath:SAVES_DIRECTORY()]) + [[NSFileManager defaultManager] removeItemAtPath:SAVES_DIRECTORY() error:NULL]; + [[NSFileManager defaultManager] createDirectoryAtPath:SAVES_DIRECTORY() + withIntermediateDirectories:NO + attributes:nil + error:NULL]; + + // SCREENSHOTS - just create it the first time + if ([[NSFileManager defaultManager] fileExistsAtPath:SCREENSHOTS_DIRECTORY()] == NO) + [[NSFileManager defaultManager] createDirectoryAtPath:SCREENSHOTS_DIRECTORY() + withIntermediateDirectories:NO + attributes:nil + error:NULL]; + + // SETTINGS - nsuserdefaults ftw + [self createSettings]; + + // TEAMS - update exisiting teams with new format + NSArray *teamNames = [[NSArray alloc] initWithObjects:@"Edit Me!",@"Ninjas",@"Pirates",@"Robots",nil]; + index = 0; + for (NSString *name in teamNames) + [self createTeamNamed:name ofType:index++ controlledByAI:[name isEqualToString:@"Robots"]]; + [teamNames release]; + + // SCHEMES - always overwrite and delete custom ones + if ([[NSFileManager defaultManager] fileExistsAtPath:SCHEMES_DIRECTORY()] == YES) + [[NSFileManager defaultManager] removeItemAtPath:SCHEMES_DIRECTORY() error:NULL]; + NSArray *schemeNames = [[NSArray alloc] initWithObjects:@"Default",@"Pro Mode",@"Shoppa",@"Clean Slate", + @"Minefield",@"Barrel Mayhem",@"Tunnel Hogs",@"Fort Mode",@"Timeless", + @"Thinking with Portals",@"King Mode",nil]; + index = 0; + for (NSString *name in schemeNames) + [self createSchemeNamed:name ofType:index++]; + [schemeNames release]; + + // WEAPONS - always overwrite as merge is not needed (missing weaps are 0ed automatically) + NSArray *weaponNames = [[NSArray alloc] initWithObjects:@"Default",@"Crazy",@"Pro Mode",@"Shoppa",@"Clean Slate", + @"Minefield",@"Thinking with Portals",nil]; + index = 0; + for (NSString *name in weaponNames) + [self createWeaponNamed:name ofType:index++]; + [weaponNames release]; +} + #pragma mark Settings +(void) createSettings { NSUserDefaults *settings = [NSUserDefaults standardUserDefaults]; @@ -41,11 +91,11 @@ #pragma mark Teams +(void) createTeamNamed:(NSString *)nameWithoutExt { - [CreationChamber createTeamNamed:nameWithoutExt ofType:0 controlledByAI:NO]; + [self createTeamNamed:nameWithoutExt ofType:0 controlledByAI:NO]; } +(void) createTeamNamed:(NSString *)nameWithoutExt ofType:(NSInteger) type { - [CreationChamber createTeamNamed:nameWithoutExt ofType:type controlledByAI:NO]; + [self createTeamNamed:nameWithoutExt ofType:type controlledByAI:NO]; } +(void) createTeamNamed:(NSString *)nameWithoutExt ofType:(NSInteger) type controlledByAI:(BOOL) shouldAITakeOver { @@ -133,7 +183,7 @@ #pragma mark Weapons +(void) createWeaponNamed:(NSString *)nameWithoutExt { - [CreationChamber createWeaponNamed:nameWithoutExt ofType:0]; + [self createWeaponNamed:nameWithoutExt ofType:0]; } +(void) createWeaponNamed:(NSString *)nameWithoutExt ofType:(NSInteger) type { @@ -208,7 +258,7 @@ #pragma mark Schemes +(void) createSchemeNamed:(NSString *)nameWithoutExt { - [CreationChamber createSchemeNamed:nameWithoutExt ofType:0]; + [self createSchemeNamed:nameWithoutExt ofType:0]; } +(void) createSchemeNamed:(NSString *)nameWithoutExt ofType:(NSInteger) type { @@ -230,7 +280,7 @@ NSArray *mods = [[NSArray alloc] initWithContentsOfFile:GAMEMODS_FILE()]; NSMutableArray *gamemodArray= [[NSMutableArray alloc] initWithCapacity:[mods count]]; - for (int i = 0; i < [mods count]; i++) + for (NSUInteger i = 0; i < [mods count]; i++) [gamemodArray addObject:[NSNumber numberWithBool:NO]]; [mods release]; diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Classes/DefinesAndMacros.h --- a/project_files/HedgewarsMobile/Classes/DefinesAndMacros.h Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/DefinesAndMacros.h Wed May 02 23:53:45 2012 +0200 @@ -38,8 +38,8 @@ #define ZAssert(condition, ...) do { if (!(condition)) { ALog(__VA_ARGS__); }} while(0) #define rotationManager(x) (IS_IPAD() ? YES : (x == UIInterfaceOrientationLandscapeRight) || (x == UIInterfaceOrientationLandscapeLeft)) -#define START_TIMER NSTimeInterval start = [NSDate timeIntervalSinceReferenceDate]; -#define END_TIMER(msg) NSTimeInterval stop = [NSDate timeIntervalSinceReferenceDate]; CMLog([NSString stringWithFormat:@"%@ Time = %f", msg, stop-start]); +#define START_TIMER() NSTimeInterval start = [NSDate timeIntervalSinceReferenceDate]; +#define END_TIMER(msg) NSTimeInterval stop = [NSDate timeIntervalSinceReferenceDate]; DLog([NSString stringWithFormat:@"%@ Time = %f", msg, stop-start]); #define DOCUMENTS_FOLDER() [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Classes/EditableCellView.h --- a/project_files/HedgewarsMobile/Classes/EditableCellView.h Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/EditableCellView.h Wed May 02 23:53:45 2012 +0200 @@ -30,8 +30,8 @@ id delegate; UITextField *textField; UILabel *titleLabel; - NSInteger minimumCharacters; - NSInteger maximumCharacters; + NSUInteger minimumCharacters; + NSUInteger maximumCharacters; BOOL respectEditing; @private @@ -41,8 +41,8 @@ @property (nonatomic,assign) id delegate; @property (nonatomic,retain,readonly) UITextField *textField; @property (nonatomic,retain,readonly) UILabel *titleLabel; -@property (nonatomic,assign) NSInteger minimumCharacters; -@property (nonatomic,assign) NSInteger maximumCharacters; +@property (nonatomic,assign) NSUInteger minimumCharacters; +@property (nonatomic,assign) NSUInteger maximumCharacters; @property (nonatomic,assign) BOOL respectEditing; @property (nonatomic,retain) NSString *oldValue; diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Classes/EngineProtocolNetwork.h --- a/project_files/HedgewarsMobile/Classes/EngineProtocolNetwork.h Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/EngineProtocolNetwork.h Wed May 02 23:53:45 2012 +0200 @@ -18,21 +18,30 @@ #import +#import "SDL_net.h" + + +@protocol EngineProtocolDelegate + +-(void) gameEndedWithStatistics:(NSArray *)stats; + +@end @interface EngineProtocolNetwork : NSObject { - NSMutableArray *statsArray; + id delegate; NSOutputStream *stream; TCPsocket csd; NSInteger enginePort; } -@property (nonatomic,assign) NSMutableArray *statsArray; +@property (nonatomic,assign) id delegate; @property (nonatomic,retain) NSOutputStream *stream; @property (assign) TCPsocket csd; @property (assign) NSInteger enginePort; -(id) init; +-(id) initWithPort:(NSInteger) port; -(void) spawnThread:(NSString *)onSaveFile withOptions:(NSDictionary *)dictionary; -(void) engineProtocol:(id) object; diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Classes/EngineProtocolNetwork.m --- a/project_files/HedgewarsMobile/Classes/EngineProtocolNetwork.m Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/EngineProtocolNetwork.m Wed May 02 23:53:45 2012 +0200 @@ -23,20 +23,24 @@ #define BUFFER_SIZE 255 // like in original frontend @implementation EngineProtocolNetwork -@synthesize statsArray, stream, csd, enginePort; +@synthesize delegate, stream, csd, enginePort; --(id) init { - if (self = [super init]) { - self.statsArray = nil; +-(id) initWithPort:(NSInteger) port { + if ((self = [super init])) { + self.delegate = nil; self.csd = NULL; self.stream = nil; - self.enginePort = [HWUtils randomPort]; + self.enginePort = port; } return self; } +-(id) init { + return [self initWithPort:[HWUtils randomPort]]; +} + -(void) dealloc { - releaseAndNil(statsArray); + self.delegate = nil; releaseAndNil(stream); [super dealloc]; } @@ -114,7 +118,7 @@ // if we're loading an older version of ammos fill the engine message with 0s int diff = HW_getNumberOfWeapons() - [[ammoData objectForKey:@"ammostore_initialqt"] length]; NSString *update = @""; - while ([update length] < diff) + while ((int)[update length] < diff) update = [update stringByAppendingString:@"0"]; NSString *ammloadt = [[NSString alloc] initWithFormat:@"eammloadt %@%@", [ammoData objectForKey:@"ammostore_initialqt"], update]; @@ -166,7 +170,7 @@ result = [[basicArray objectAtIndex:0] intValue]; NSArray *basic = [[NSArray alloc] initWithContentsOfFile:BASICFLAGS_FILE()]; - for (int i = 1; i < [basicArray count]; i++) { + for (NSUInteger i = 1; i < [basicArray count]; i++) { NSDictionary *dict = [basic objectAtIndex:i]; NSString *command = [dict objectForKey:@"command"]; NSInteger value = [[basicArray objectAtIndex:i] intValue]; @@ -212,6 +216,7 @@ -(void) engineProtocol:(id) object { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSDictionary *gameConfig = (NSDictionary *)object; + NSMutableArray *statsArray = nil; TCPsocket sd; IPaddress ip; int eProto; @@ -326,10 +331,10 @@ } break; case 'i': - if (self.statsArray == nil) { - self.statsArray = [[NSMutableArray alloc] initWithCapacity:10 - 2]; + if (statsArray == nil) { + statsArray = [[NSMutableArray alloc] initWithCapacity:10 - 2]; NSMutableArray *ranking = [[NSMutableArray alloc] initWithCapacity:4]; - [self.statsArray insertObject:ranking atIndex:0]; + [statsArray insertObject:ranking atIndex:0]; [ranking release]; } NSString *tempStr = [NSString stringWithUTF8String:&buffer[2]]; @@ -338,16 +343,16 @@ int index = [arg length] + 3; switch (buffer[1]) { case 'r': // winning team - [self.statsArray insertObject:[NSString stringWithUTF8String:&buffer[2]] atIndex:1]; + [statsArray insertObject:[NSString stringWithUTF8String:&buffer[2]] atIndex:1]; break; case 'D': // best shot - [self.statsArray addObject:[NSString stringWithFormat:@"The best shot award won by %s (with %@ points)", &buffer[index], arg]]; + [statsArray addObject:[NSString stringWithFormat:@"The best shot award won by %s (with %@ points)", &buffer[index], arg]]; break; case 'k': // best hedgehog - [self.statsArray addObject:[NSString stringWithFormat:@"The best killer is %s with %@ kill(s) in a turn", &buffer[index], arg]]; + [statsArray addObject:[NSString stringWithFormat:@"The best killer is %s with %@ kill(s) in a turn", &buffer[index], arg]]; break; case 'K': // number of hogs killed - [self.statsArray addObject:[NSString stringWithFormat:@"%@ hedgehog(s) were killed during this round", arg]]; + [statsArray addObject:[NSString stringWithFormat:@"%@ hedgehog(s) were killed during this round", arg]]; break; case 'H': // team health/graph break; @@ -355,16 +360,16 @@ // still WIP in statsPage.cpp break; case 'P': // teams ranking - [[self.statsArray objectAtIndex:0] addObject:tempStr]; + [[statsArray objectAtIndex:0] addObject:tempStr]; break; case 's': // self damage - [self.statsArray addObject:[NSString stringWithFormat:@"%s thought it's good to shoot his own hedgehogs with %@ points", &buffer[index], arg]]; + [statsArray addObject:[NSString stringWithFormat:@"%s thought it's good to shoot his own hedgehogs with %@ points", &buffer[index], arg]]; break; case 'S': // friendly fire - [self.statsArray addObject:[NSString stringWithFormat:@"%s killed %@ of his own hedgehogs", &buffer[index], arg]]; + [statsArray addObject:[NSString stringWithFormat:@"%s killed %@ of his own hedgehogs", &buffer[index], arg]]; break; case 'B': // turn skipped - [self.statsArray addObject:[NSString stringWithFormat:@"%s was scared and skipped turn %@ times", &buffer[index], arg]]; + [statsArray addObject:[NSString stringWithFormat:@"%s was scared and skipped turn %@ times", &buffer[index], arg]]; break; default: DLog(@"Unhandled stat message, see statsPage.cpp"); @@ -373,6 +378,9 @@ break; case 'q': // game ended and match finished, statsArray is full of delicious statistics + if (self.delegate != nil && [self.delegate respondsToSelector:@selector(gameEndedWithStatistics:)]) + [self.delegate gameEndedWithStatistics:statsArray]; + [statsArray release]; [HWUtils setGameStatus:gsEnded]; // closing connection here would trigger a "IPC connection lost" error, so we have to wait until recv fails break; diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Classes/FortsViewController.m --- a/project_files/HedgewarsMobile/Classes/FortsViewController.m Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/FortsViewController.m Wed May 02 23:53:45 2012 +0200 @@ -39,7 +39,7 @@ NSArray *directoryContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:FORTS_DIRECTORY() error:NULL]; NSMutableArray *filteredContents = [[NSMutableArray alloc] initWithCapacity:([directoryContents count] / IMGNUM_PER_FORT)]; // we need to remove the double entries and the L.png suffix - for (int i = 0; i < [directoryContents count]; i++) { + for (NSUInteger i = 0; i < [directoryContents count]; i++) { if (i % IMGNUM_PER_FORT == IMGNUM_PER_FORT-1) { NSString *currentName = [directoryContents objectAtIndex:i]; NSString *correctName = [currentName substringToIndex:([currentName length] - 5)]; diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Classes/GameConfigViewController.m --- a/project_files/HedgewarsMobile/Classes/GameConfigViewController.m Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/GameConfigViewController.m Wed May 02 23:53:45 2012 +0200 @@ -47,12 +47,12 @@ [alert show]; [alert release]; } else { - [AudioManagerController playBackSound]; + [[AudioManagerController mainManager] playBackSound]; [[self parentViewController] dismissModalViewControllerAnimated:YES]; } break; case 1: - [AudioManagerController playClickSound]; + [[AudioManagerController mainManager] playClickSound]; if ([self isEverythingSet] == NO) return; theButton.enabled = NO; @@ -66,7 +66,7 @@ break; case 2: - [AudioManagerController playClickSound]; + [[AudioManagerController mainManager] playClickSound]; if (self.helpPage == nil) self.helpPage = [[HelpPageLobbyViewController alloc] initWithNibName:@"HelpPageLobbyViewController-iPad" bundle:nil]; self.helpPage.view.alpha = 0; @@ -85,7 +85,7 @@ UISegmentedControl *theSegment = (UISegmentedControl *)sender; - [AudioManagerController playSelectSound]; + [[AudioManagerController mainManager] playSelectSound]; switch (theSegment.selectedSegmentIndex) { case 0: // this message is compulsory otherwise the table won't be loaded at all @@ -159,7 +159,7 @@ } // play if there aren't too many teams - if ([self.teamConfigViewController.listOfSelectedTeams count] > HW_getMaxNumberOfTeams()) { + if ((int)[self.teamConfigViewController.listOfSelectedTeams count] > HW_getMaxNumberOfTeams()) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Too many teams",@"") message:NSLocalizedString(@"You exceeded the maximum number of tems allowed in a game",@"") delegate:nil diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Classes/GameInterfaceBridge.h --- a/project_files/HedgewarsMobile/Classes/GameInterfaceBridge.h Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/GameInterfaceBridge.h Wed May 02 23:53:45 2012 +0200 @@ -18,19 +18,18 @@ #import +#import "EngineProtocolNetwork.h" -@class EngineProtocolNetwork; - -@interface GameInterfaceBridge : NSObject { +@interface GameInterfaceBridge : NSObject { UIView *blackView; NSString *savePath; - EngineProtocolNetwork *proto; + NSInteger port; } @property (nonatomic,retain) UIView *blackView; @property (nonatomic,retain) NSString *savePath; -@property (nonatomic,retain) EngineProtocolNetwork *proto; +@property (assign) NSInteger port; +(void) startLocalGame:(NSDictionary *)withOptions; +(void) startSaveGame:(NSString *)atPath; diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Classes/GameInterfaceBridge.m --- a/project_files/HedgewarsMobile/Classes/GameInterfaceBridge.m Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/GameInterfaceBridge.m Wed May 02 23:53:45 2012 +0200 @@ -25,19 +25,20 @@ static UIViewController *callingController; @implementation GameInterfaceBridge -@synthesize blackView, savePath, proto; +@synthesize blackView, savePath, port; #pragma mark - #pragma mark Instance methods for engine interaction // prepares the controllers for hosting a game -(void) earlyEngineLaunch:(NSDictionary *)optionsOrNil { [self retain]; - [AudioManagerController fadeOutBackgroundMusic]; + [[AudioManagerController mainManager] fadeOutBackgroundMusic]; EngineProtocolNetwork *engineProtocol = [[EngineProtocolNetwork alloc] init]; - self.proto = engineProtocol; + self.port = engineProtocol.enginePort; + engineProtocol.delegate = self; + [engineProtocol spawnThread:self.savePath withOptions:optionsOrNil]; [engineProtocol release]; - [self.proto spawnThread:self.savePath withOptions:optionsOrNil]; // add a black view hiding the background UIWindow *thisWindow = [[HedgewarsAppDelegate sharedAppDelegate] uiwindow]; @@ -53,9 +54,10 @@ [thisWindow addSubview:self.blackView]; [self.blackView release]; - // keep track of uncompleted games + // keep the point of return for games that completed loading NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; [userDefaults setObject:self.savePath forKey:@"savedGamePath"]; + [userDefaults setObject:[NSNumber numberWithBool:NO] forKey:@"saveIsValid"]; [userDefaults synchronize]; // let's launch the engine using this -perfomSelector so that the runloop can deal with queued messages first @@ -81,26 +83,12 @@ [UIView commitAnimations]; [self.blackView performSelector:@selector(removeFromSuperview) withObject:nil afterDelay:1]; - // engine thread *should* be done by now - NSArray *stats = [[NSArray alloc] initWithArray:self.proto.statsArray copyItems:YES]; - if ([HWUtils gameStatus] == gsEnded && stats != nil) { - StatsPageViewController *statsPage = [[StatsPageViewController alloc] init]; - statsPage.statsArray = stats; - statsPage.modalTransitionStyle = UIModalTransitionStyleCoverVertical; - if ([statsPage respondsToSelector:@selector(setModalPresentationStyle:)]) - statsPage.modalPresentationStyle = UIModalPresentationPageSheet; - - [callingController presentModalViewController:statsPage animated:YES]; - [statsPage release]; - } - [stats release]; - // can remove the savefile if the replay has ended if ([HWUtils gameType] == gtSave) [[NSFileManager defaultManager] removeItemAtPath:self.savePath error:nil]; // restart music and we're done - [AudioManagerController fadeInBackgroundMusic]; + [[AudioManagerController mainManager] fadeInBackgroundMusic]; [HWUtils setGameStatus:gsNone]; [HWUtils setGameType:gtNone]; [self release]; @@ -110,9 +98,8 @@ -(void) engineLaunch { const char *gameArgs[11]; CGFloat width, height; - NSInteger enginePort = self.proto.enginePort; CGFloat screenScale = [[UIScreen mainScreen] safeScale]; - NSString *ipcString = [[NSString alloc] initWithFormat:@"%d",enginePort]; + NSString *ipcString = [[NSString alloc] initWithFormat:@"%d",self.port]; NSString *localeString = [[NSString alloc] initWithFormat:@"%@.txt",[[NSLocale preferredLanguages] objectAtIndex:0]]; NSUserDefaults *settings = [NSUserDefaults standardUserDefaults]; @@ -174,11 +161,23 @@ -(void) dealloc { releaseAndNil(blackView); releaseAndNil(savePath); - releaseAndNil(proto); [super dealloc]; } #pragma mark - +#pragma mark EngineProtocolDelegate methods +-(void) gameEndedWithStatistics:(NSArray *)stats { + if (stats != nil) { + StatsPageViewController *statsPage = [[StatsPageViewController alloc] init]; + statsPage.statsArray = stats; + statsPage.modalTransitionStyle = UIModalTransitionStyleCoverVertical; + + [callingController presentModalViewController:statsPage animated:YES]; + [statsPage release]; + } +} + +#pragma mark - #pragma mark Class methods for setting up the engine from outsite +(void) registerCallingController:(UIViewController *)controller { callingController = controller; diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Classes/GeneralSettingsViewController.m --- a/project_files/HedgewarsMobile/Classes/GeneralSettingsViewController.m Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/GeneralSettingsViewController.m Wed May 02 23:53:45 2012 +0200 @@ -43,7 +43,7 @@ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; [userDefaults synchronize]; if ([[userDefaults objectForKey:@"music"] boolValue] == NO) - [AudioManagerController stopBackgroundMusic]; + [[AudioManagerController mainManager] stopBackgroundMusic]; [super viewWillDisappear:animated]; } @@ -63,7 +63,7 @@ [theOtherSwitch setOn:NO animated:YES]; // since switching sound on won't turn music on anyways, we can always turn off music - [AudioManagerController pauseBackgroundMusic]; + [[AudioManagerController mainManager]pauseBackgroundMusic]; [settings setObject:[NSNumber numberWithBool:NO] forKey:@"music"]; break; case 20: //musicSwitch @@ -76,9 +76,9 @@ [settings setObject:[NSNumber numberWithBool:theSwitch.on] forKey:@"music"]; if (theSwitch.on) - [AudioManagerController playBackgroundMusic]; + [[AudioManagerController mainManager] playBackgroundMusic]; else - [AudioManagerController pauseBackgroundMusic]; + [[AudioManagerController mainManager] pauseBackgroundMusic]; break; case 30: //alternateSwitch [settings setObject:[NSNumber numberWithBool:theSwitch.on] forKey:@"alternate"]; diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Classes/HedgewarsAppDelegate.m --- a/project_files/HedgewarsMobile/Classes/HedgewarsAppDelegate.m Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/HedgewarsAppDelegate.m Wed May 02 23:53:45 2012 +0200 @@ -36,7 +36,7 @@ #pragma mark - #pragma mark AppDelegate methods -(id) init { - if (self = [super init]){ + if ((self = [super init])) { mainViewController = nil; uiwindow = nil; } @@ -68,7 +68,7 @@ [HWUtils releaseCache]; // don't stop music if it is playing if ([HWUtils isGameLaunched]) { - [AudioManagerController releaseCache]; + [[AudioManagerController mainManager] didReceiveMemoryWarning]; HW_memoryWarningCallback(); } MSG_MEMCLEAN(); diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Classes/MGSplitViewController/MGSplitCornersView.m --- a/project_files/HedgewarsMobile/Classes/MGSplitViewController/MGSplitCornersView.m Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/MGSplitViewController/MGSplitCornersView.m Wed May 02 23:53:45 2012 +0200 @@ -7,7 +7,7 @@ // #import "MGSplitCornersView.h" - +#import "CGPointUtils.h" @implementation MGSplitCornersView @@ -40,24 +40,6 @@ #pragma mark - -#pragma mark Geometry helpers - - -double deg2Rad(double degrees) -{ - // Converts degrees to radians. - return degrees * (M_PI / 180.0); -} - - -double rad2Deg(double radians) -{ - // Converts radians to degrees. - return radians * (180 / M_PI); -} - - -#pragma mark - #pragma mark Drawing @@ -78,7 +60,7 @@ case MGCornersPositionLeadingVertical: // top of screen for a left/right split [path moveToPoint:pt]; pt.y += cornerRadius; - [path appendPath:[UIBezierPath bezierPathWithArcCenter:pt radius:cornerRadius startAngle:deg2Rad(90) endAngle:0 clockwise:YES]]; + [path appendPath:[UIBezierPath bezierPathWithArcCenter:pt radius:cornerRadius startAngle:degreesToRadians(90) endAngle:0 clockwise:YES]]; pt.x += cornerRadius; pt.y -= cornerRadius; [path addLineToPoint:pt]; @@ -91,7 +73,7 @@ pt.y = maxY; [path addLineToPoint:pt]; pt.x += cornerRadius; - [path appendPath:[UIBezierPath bezierPathWithArcCenter:pt radius:cornerRadius startAngle:deg2Rad(180) endAngle:deg2Rad(90) clockwise:YES]]; + [path appendPath:[UIBezierPath bezierPathWithArcCenter:pt radius:cornerRadius startAngle:degreesToRadians(180) endAngle:degreesToRadians(90) clockwise:YES]]; pt.y -= cornerRadius; [path addLineToPoint:pt]; pt.x -= cornerRadius; @@ -104,7 +86,7 @@ pt.y = maxY; [path moveToPoint:pt]; pt.y -= cornerRadius; - [path appendPath:[UIBezierPath bezierPathWithArcCenter:pt radius:cornerRadius startAngle:deg2Rad(270) endAngle:deg2Rad(360) clockwise:NO]]; + [path appendPath:[UIBezierPath bezierPathWithArcCenter:pt radius:cornerRadius startAngle:degreesToRadians(270) endAngle:degreesToRadians(360) clockwise:NO]]; pt.x += cornerRadius; pt.y += cornerRadius; [path addLineToPoint:pt]; @@ -118,7 +100,7 @@ pt.y -= cornerRadius; [path addLineToPoint:pt]; pt.x += cornerRadius; - [path appendPath:[UIBezierPath bezierPathWithArcCenter:pt radius:cornerRadius startAngle:deg2Rad(180) endAngle:deg2Rad(270) clockwise:NO]]; + [path appendPath:[UIBezierPath bezierPathWithArcCenter:pt radius:cornerRadius startAngle:degreesToRadians(180) endAngle:degreesToRadians(270) clockwise:NO]]; pt.y += cornerRadius; [path addLineToPoint:pt]; pt.x -= cornerRadius; @@ -134,7 +116,7 @@ pt.y -= cornerRadius; [path addLineToPoint:pt]; pt.x += cornerRadius; - [path appendPath:[UIBezierPath bezierPathWithArcCenter:pt radius:cornerRadius startAngle:deg2Rad(180) endAngle:deg2Rad(270) clockwise:NO]]; + [path appendPath:[UIBezierPath bezierPathWithArcCenter:pt radius:cornerRadius startAngle:degreesToRadians(180) endAngle:degreesToRadians(270) clockwise:NO]]; pt.y += cornerRadius; [path addLineToPoint:pt]; pt.x -= cornerRadius; @@ -147,7 +129,7 @@ pt.y = maxY; [path addLineToPoint:pt]; pt.x += cornerRadius; - [path appendPath:[UIBezierPath bezierPathWithArcCenter:pt radius:cornerRadius startAngle:deg2Rad(180) endAngle:deg2Rad(90) clockwise:YES]]; + [path appendPath:[UIBezierPath bezierPathWithArcCenter:pt radius:cornerRadius startAngle:degreesToRadians(180) endAngle:degreesToRadians(90) clockwise:YES]]; pt.y -= cornerRadius; [path addLineToPoint:pt]; pt.x -= cornerRadius; @@ -160,7 +142,7 @@ pt.y = cornerRadius; [path moveToPoint:pt]; pt.y -= cornerRadius; - [path appendPath:[UIBezierPath bezierPathWithArcCenter:pt radius:cornerRadius startAngle:deg2Rad(270) endAngle:deg2Rad(360) clockwise:NO]]; + [path appendPath:[UIBezierPath bezierPathWithArcCenter:pt radius:cornerRadius startAngle:degreesToRadians(270) endAngle:degreesToRadians(360) clockwise:NO]]; pt.x += cornerRadius; pt.y += cornerRadius; [path addLineToPoint:pt]; @@ -171,7 +153,7 @@ pt.y = maxY - cornerRadius; [path moveToPoint:pt]; pt.y += cornerRadius; - [path appendPath:[UIBezierPath bezierPathWithArcCenter:pt radius:cornerRadius startAngle:deg2Rad(90) endAngle:0 clockwise:YES]]; + [path appendPath:[UIBezierPath bezierPathWithArcCenter:pt radius:cornerRadius startAngle:degreesToRadians(90) endAngle:0 clockwise:YES]]; pt.x += cornerRadius; pt.y -= cornerRadius; [path addLineToPoint:pt]; diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Classes/MGSplitViewController/MGSplitViewController.m --- a/project_files/HedgewarsMobile/Classes/MGSplitViewController/MGSplitViewController.m Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/MGSplitViewController/MGSplitViewController.m Wed May 02 23:53:45 2012 +0200 @@ -702,7 +702,7 @@ } -- (IBAction)showMasterPopover:(id)sender +- (IBAction)showMasterPopover:(id) sender { if (_hiddenPopoverController && !(_hiddenPopoverController.popoverVisible)) { // Inform delegate. diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Classes/MNEValueTrackingSlider.m --- a/project_files/HedgewarsMobile/Classes/MNEValueTrackingSlider.m Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/MNEValueTrackingSlider.m Wed May 02 23:53:45 2012 +0200 @@ -93,7 +93,7 @@ @synthesize thumbRect, textValue; -#pragma Private methods +#pragma mark Private methods -(void) _constructSlider { valuePopupView = [[SliderValuePopupView alloc] initWithFrame:CGRectZero]; diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Classes/MXAudioPlayerFadeOperation.m --- a/project_files/HedgewarsMobile/Classes/MXAudioPlayerFadeOperation.m Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/MXAudioPlayerFadeOperation.m Wed May 02 23:53:45 2012 +0200 @@ -48,7 +48,7 @@ #pragma mark - #pragma mark NSOperation -(id) initFadeWithAudioPlayer:(AVAudioPlayer*)player toVolume:(float)volume overDuration:(NSTimeInterval)duration withDelay:(NSTimeInterval)timeDelay { - if (self = [super init]) { + if ((self = [super init])) { self.audioPlayer = player; [player prepareToPlay]; _fadeDuration = duration; diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Classes/MainMenuViewController.m --- a/project_files/HedgewarsMobile/Classes/MainMenuViewController.m Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/MainMenuViewController.m Wed May 02 23:53:45 2012 +0200 @@ -37,56 +37,6 @@ return rotationManager(interfaceOrientation); } -// check if some configuration files are already set; if they are present it means that the current copy must be updated --(void) createNecessaryFiles { - DLog(@"Creating necessary files"); - NSInteger index; - - // SAVES - just delete and overwrite - if ([[NSFileManager defaultManager] fileExistsAtPath:SAVES_DIRECTORY()]) - [[NSFileManager defaultManager] removeItemAtPath:SAVES_DIRECTORY() error:NULL]; - [[NSFileManager defaultManager] createDirectoryAtPath:SAVES_DIRECTORY() - withIntermediateDirectories:NO - attributes:nil - error:NULL]; - - // SCREENSHOTS - just create it the first time - if ([[NSFileManager defaultManager] fileExistsAtPath:SCREENSHOTS_DIRECTORY()] == NO) - [[NSFileManager defaultManager] createDirectoryAtPath:SCREENSHOTS_DIRECTORY() - withIntermediateDirectories:NO - attributes:nil - error:NULL]; - - // SETTINGS - nsuserdefaults ftw - [CreationChamber createSettings]; - - // TEAMS - update exisiting teams with new format - NSArray *teamNames = [[NSArray alloc] initWithObjects:@"Edit Me!",@"Ninjas",@"Pirates",@"Robots",nil]; - index = 0; - for (NSString *name in teamNames) - [CreationChamber createTeamNamed:name ofType:index++ controlledByAI:[name isEqualToString:@"Robots"]]; - [teamNames release]; - - // SCHEMES - always overwrite and delete custom ones - if ([[NSFileManager defaultManager] fileExistsAtPath:SCHEMES_DIRECTORY()] == YES) - [[NSFileManager defaultManager] removeItemAtPath:SCHEMES_DIRECTORY() error:NULL]; - NSArray *schemeNames = [[NSArray alloc] initWithObjects:@"Default",@"Pro Mode",@"Shoppa",@"Clean Slate", - @"Minefield",@"Barrel Mayhem",@"Tunnel Hogs",@"Fort Mode",@"Timeless", - @"Thinking with Portals",@"King Mode",nil]; - index = 0; - for (NSString *name in schemeNames) - [CreationChamber createSchemeNamed:name ofType:index++]; - [schemeNames release]; - - // WEAPONS - always overwrite as merge is not needed (missing weaps are 0ed automatically) - NSArray *weaponNames = [[NSArray alloc] initWithObjects:@"Default",@"Crazy",@"Pro Mode",@"Shoppa",@"Clean Slate", - @"Minefield",@"Thinking with Portals",nil]; - index = 0; - for (NSString *name in weaponNames) - [CreationChamber createWeaponNamed:name ofType:index++]; - [weaponNames release]; -} - #pragma mark - -(void) viewDidLoad { self.view.frame = [[UIScreen mainScreen] safeBounds]; @@ -104,14 +54,14 @@ [userDefaults setObject:@"" forKey:@"savedGamePath"]; // update the tracking version with the new one [userDefaults setObject:version forKey:@"HedgeVersion"]; + [userDefaults synchronize]; - [userDefaults synchronize]; - [self createNecessaryFiles]; + [CreationChamber createFirstLaunch]; } // prompt for restoring any previous game NSString *saveString = [userDefaults objectForKey:@"savedGamePath"]; - if (saveString != nil && [saveString isEqualToString:@""] == NO) { + if (saveString != nil && [saveString isEqualToString:@""] == NO && [[userDefaults objectForKey:@"saveIsValid"] boolValue]) { if (self.restoreViewController == nil) { NSString *xibName = [@"RestoreViewController-" stringByAppendingString:(IS_IPAD() ? @"iPad" : @"iPhone")]; RestoreViewController *restored = [[RestoreViewController alloc] initWithNibName:xibName bundle:nil]; @@ -132,7 +82,7 @@ } -(void) viewWillAppear:(BOOL)animated { - [AudioManagerController playBackgroundMusic]; + [[AudioManagerController mainManager] playBackgroundMusic]; [super viewWillAppear:animated]; } @@ -143,7 +93,7 @@ NSString *xib = nil; NSString *debugStr = nil; - [AudioManagerController playClickSound]; + [[AudioManagerController mainManager] playClickSound]; switch (button.tag) { case 0: if (nil == self.gameConfigViewController) { diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Classes/MapConfigViewController.m --- a/project_files/HedgewarsMobile/Classes/MapConfigViewController.m Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/MapConfigViewController.m Wed May 02 23:53:45 2012 +0200 @@ -35,7 +35,7 @@ } -(IBAction) mapButtonPressed:(id) sender { - [AudioManagerController playClickSound]; + [[AudioManagerController mainManager] playClickSound]; [self updatePreview]; } @@ -114,7 +114,7 @@ -(UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; - NSInteger row = [indexPath row]; + NSUInteger row = [indexPath row]; UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) @@ -290,7 +290,7 @@ [self updatePreview]; oldValue = num; } - [AudioManagerController playClickSound]; + [[AudioManagerController mainManager] playClickSound]; } // perform actions based on the activated section, then call updatePreview to visually update the selection @@ -299,7 +299,7 @@ NSString *mapgen, *staticmap, *mission; NSInteger newPage = self.segmentedControl.selectedSegmentIndex; - [AudioManagerController playSelectSound]; + [[AudioManagerController mainManager] playSelectSound]; switch (newPage) { case 0: // Random mapgen = @"e$mapgen 0"; diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Classes/MapPreviewButtonView.h --- a/project_files/HedgewarsMobile/Classes/MapPreviewButtonView.h Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/MapPreviewButtonView.h Wed May 02 23:53:45 2012 +0200 @@ -18,6 +18,7 @@ #import +#import "SDL_net.h" @protocol MapPreviewViewDelegate diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Classes/MapPreviewButtonView.m --- a/project_files/HedgewarsMobile/Classes/MapPreviewButtonView.m Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/MapPreviewButtonView.m Wed May 02 23:53:45 2012 +0200 @@ -60,10 +60,10 @@ return SDLNet_TCP_Send(csd, [string UTF8String], length); } --(const uint8_t *)engineProtocol { +-(void) engineProtocol:(uint8_t *)unpackedMap { IPaddress ip; BOOL serverQuit = NO; - static uint8_t map[128*32]; + uint8_t packedMap[128*32]; int port = [HWUtils randomPort]; if (SDLNet_Init() < 0) { @@ -103,50 +103,45 @@ [self sendToEngine:[dictForEngine objectForKey:@"mazeSizeCommand"]]; [self sendToEngine:@"!"]; - memset(map, 0, 128*32); - SDLNet_TCP_Recv(csd, map, 128*32); + memset(packedMap, 0, 128*32); + SDLNet_TCP_Recv(csd, packedMap, 128*32); SDLNet_TCP_Recv(csd, &maxHogs, sizeof(uint8_t)); SDLNet_TCP_Close(csd); serverQuit = YES; } } - [HWUtils freePort:port]; SDLNet_TCP_Close(sd); SDLNet_Quit(); - return map; + + // spread the packed bits in an array of bytes (one pixel per element, 0= transparent 1= color) + int k = 0; + memset(unpackedMap, 255, 128*32*8); // 255 is white + for (int i = 0; i < 32*128; i++) { + for (int j = 7; j >= 0; j--) { + if (((packedMap[i] >> j) & 0x01) != 0) + unpackedMap[k] = 170; // level of gray [0-255] + k++; + } + } + return; } -(void) drawingThread { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - const uint8_t *map = [self engineProtocol]; - uint8_t mapExp[128*32*8]; + uint8_t unpackedMap[128*32*8]; + [self engineProtocol:unpackedMap]; - // draw the buffer (1 pixel per component, 0= transparent 1= color) - int k = 0; - for (int i = 0; i < 32*128; i++) { - unsigned char byte = map[i]; - for (int j = 0; j < 8; j++) { - // select the color based on the leftmost bit - if ((byte & 0x80) != 0) - mapExp[k] = 100; - else - mapExp[k] = 255; - // shift to next bit - byte <<= 1; - k++; - } - } + // http://developer.apple.com/mac/library/qa/qa2001/qa1037.html CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceGray(); - CGContextRef bitmapImage = CGBitmapContextCreate(mapExp, 256, 128, 8, 256, colorspace, kCGImageAlphaNone); + CGContextRef bitmapImage = CGBitmapContextCreate(unpackedMap, 256, 128, 8, 256, colorspace, kCGImageAlphaNone); CGColorSpaceRelease(colorspace); CGImageRef previewCGImage = CGBitmapContextCreateImage(bitmapImage); CGContextRelease(bitmapImage); UIImage *previewImage = [[UIImage alloc] initWithCGImage:previewCGImage]; CGImageRelease(previewCGImage); - previewCGImage = nil; // all these are performed on the main thread to prevent a leak [self performSelectorOnMainThread:@selector(setImageRounded:) @@ -164,18 +159,6 @@ waitUntilDone:NO]; [pool release]; - - /* - // http://developer.apple.com/mac/library/qa/qa2001/qa1037.html - UIGraphicsBeginImageContext(CGSizeMake(256,128)); - CGContextRef context = UIGraphicsGetCurrentContext(); - UIGraphicsPushContext(context); - CGContextSetRGBFillColor(context, 0.5, 0.5, 0.7, 1.0); - CGContextFillRect(context,CGRectMake(xc,yc,1,1)); - UIGraphicsPopContext(); - UIImage *previewImage = UIGraphicsGetImageFromCurrentImageContext(); - UIGraphicsEndImageContext(); - */ } -(void) updatePreviewWithSeed:(NSString *)seed { diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Classes/MissionTrainingViewController.m --- a/project_files/HedgewarsMobile/Classes/MissionTrainingViewController.m Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/MissionTrainingViewController.m Wed May 02 23:53:45 2012 +0200 @@ -64,7 +64,7 @@ UIButton *button = (UIButton *)sender; if (button.tag == 0) { - [AudioManagerController playBackSound]; + [[AudioManagerController mainManager] playBackSound]; [[self parentViewController] dismissModalViewControllerAnimated:YES]; } else { [GameInterfaceBridge registerCallingController:self]; @@ -89,7 +89,7 @@ NSMutableArray *filteredArray = [[NSMutableArray alloc] initWithCapacity:[descArray count]/3]; [descComplete release]; // sanity check to avoid having missions and descriptions conflicts - for (int i = 0; i < [self.listOfMissions count]; i++) { + for (NSUInteger i = 0; i < [self.listOfMissions count]; i++) { NSString *desc = [[self.listOfMissions objectAtIndex:i] stringByDeletingPathExtension]; for (NSString *str in descArray) if ([str hasPrefix:desc] && [str hasSuffix:@"\""]) { diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Classes/ObjcExports.h --- a/project_files/HedgewarsMobile/Classes/ObjcExports.h Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/ObjcExports.h Wed May 02 23:53:45 2012 +0200 @@ -20,7 +20,8 @@ void clearView(void); BOOL isApplePhone(void); -void startSpinningProgress(void); -void stopSpinningProgress(void); +void startLoadingIndicator(void); +void stopLoadingIndicator(void); + void saveBeganSynching(void); void saveFinishedSynching(void); diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Classes/ObjcExports.m --- a/project_files/HedgewarsMobile/Classes/ObjcExports.m Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/ObjcExports.m Wed May 02 23:53:45 2012 +0200 @@ -25,11 +25,11 @@ #pragma mark - #pragma mark functions called by pascal code -BOOL inline isApplePhone() { +BOOL inline isApplePhone(void) { return (IS_IPAD() == NO); } -void startLoadingIndicator() { +void startLoadingIndicator(void) { // this is the first ojbc function called by engine, so we have to initialize some variables here overlay_instance = [[OverlayViewController alloc] initWithNibName:@"OverlayViewController" bundle:nil]; // in order to get rotation events we have to insert the view inside the first view of the second window @@ -57,16 +57,19 @@ [overlay_instance.loadingIndicator release]; } -void stopLoadingIndicator() { +void stopLoadingIndicator(void) { HW_zoomSet(1.7); if ([HWUtils gameType] != gtSave) { [overlay_instance.loadingIndicator stopAnimating]; [overlay_instance.loadingIndicator removeFromSuperview]; [HWUtils setGameStatus:gsInGame]; } + // mark the savefile as valid, eg it's been loaded correctly + [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:YES] forKey:@"saveIsValid"]; + [[NSUserDefaults standardUserDefaults] synchronize]; } -void saveFinishedSynching() { +void saveFinishedSynching(void) { [UIView beginAnimations:@"fading from save synch" context:NULL]; [UIView setAnimationDuration:1]; overlay_instance.view.backgroundColor = [UIColor clearColor]; @@ -81,7 +84,7 @@ [HWUtils setGameStatus:gsInGame]; } -void clearView() { +void clearView(void) { [overlay_instance clearOverlay]; } diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Classes/OverlayViewController.m --- a/project_files/HedgewarsMobile/Classes/OverlayViewController.m Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/OverlayViewController.m Wed May 02 23:53:45 2012 +0200 @@ -227,13 +227,13 @@ HW_backjump(); break; case 10: - [AudioManagerController playClickSound]; + [[AudioManagerController mainManager] playClickSound]; HW_pause(); [self clearOverlay]; [self showPopover]; break; case 11: - [AudioManagerController playClickSound]; + [[AudioManagerController mainManager] playClickSound]; [self clearOverlay]; HW_ammoMenu(); break; diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Classes/RestoreViewController.m --- a/project_files/HedgewarsMobile/Classes/RestoreViewController.m Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/RestoreViewController.m Wed May 02 23:53:45 2012 +0200 @@ -31,11 +31,11 @@ NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; if (theButton.tag != 0) { - [AudioManagerController playClickSound]; + [[AudioManagerController mainManager] playClickSound]; [GameInterfaceBridge registerCallingController:self.parentViewController]; [GameInterfaceBridge startSaveGame:[[NSUserDefaults standardUserDefaults] objectForKey:@"savedGamePath"]]; } else { - [AudioManagerController playBackSound]; + [[AudioManagerController mainManager] playBackSound]; [defaults setObject:@"" forKey:@"savedGamePath"]; [defaults synchronize]; } diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Classes/SavedGamesViewController.m --- a/project_files/HedgewarsMobile/Classes/SavedGamesViewController.m Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/SavedGamesViewController.m Wed May 02 23:53:45 2012 +0200 @@ -66,7 +66,7 @@ UIButton *button = (UIButton *)sender; if (button.tag == 0) { - [AudioManagerController playBackSound]; + [[AudioManagerController mainManager] playBackSound]; [self.tableView setEditing:NO animated:YES]; [[self parentViewController] dismissModalViewControllerAnimated:YES]; } else { diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Classes/SchemeWeaponConfigViewController.m --- a/project_files/HedgewarsMobile/Classes/SchemeWeaponConfigViewController.m Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/SchemeWeaponConfigViewController.m Wed May 02 23:53:45 2012 +0200 @@ -98,11 +98,12 @@ -(void) viewDidLoad { self.sectionsHidden = NO; - NSInteger verticalOffset = IS_IPAD() ? 45 : 0; + NSInteger topOffset = IS_IPAD() ? 45 : 0; + NSInteger bottomOffset = IS_IPAD() ? 3 : 0; UITableView *aTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, - verticalOffset, + topOffset, self.view.frame.size.width, - self.view.frame.size.height - verticalOffset) + self.view.frame.size.height - topOffset - bottomOffset) style:UITableViewStyleGrouped]; aTableView.delegate = self; aTableView.dataSource = self; @@ -271,9 +272,9 @@ if ([[settings objectForKey:@"sync_ws"] boolValue]) { for (NSString *str in self.listOfWeapons) { if ([str isEqualToString:self.selectedScheme]) { - int index = [self.listOfSchemes indexOfObject:str]; + int row = [self.listOfSchemes indexOfObject:str]; self.selectedWeapon = str; - self.lastIndexPath_we = [NSIndexPath indexPathForRow:index inSection:1]; + self.lastIndexPath_we = [NSIndexPath indexPathForRow:row inSection:1]; break; } } diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Classes/ServerProtocolNetwork.h --- a/project_files/HedgewarsMobile/Classes/ServerProtocolNetwork.h Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/ServerProtocolNetwork.h Wed May 02 23:53:45 2012 +0200 @@ -18,7 +18,7 @@ #import -//#import "EngineProtocolNetwork.h" +#import "SDL_net.h" @interface ServerProtocolNetwork : NSObject { diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Classes/ServerProtocolNetwork.m --- a/project_files/HedgewarsMobile/Classes/ServerProtocolNetwork.m Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/ServerProtocolNetwork.m Wed May 02 23:53:45 2012 +0200 @@ -30,7 +30,7 @@ #pragma mark - #pragma mark init and class methods -(id) init:(NSInteger) onPort withAddress:(NSString *)address { - if (self = [super init]) { + if ((self = [super init])) { self.serverPort = onPort; self.serverAddress = address; } diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Classes/SettingsBaseViewController.m --- a/project_files/HedgewarsMobile/Classes/SettingsBaseViewController.m Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/SettingsBaseViewController.m Wed May 02 23:53:45 2012 +0200 @@ -132,7 +132,7 @@ } -(void) dismissSplitView { - [AudioManagerController playBackSound]; + [[AudioManagerController mainManager] playBackSound]; [[[HedgewarsAppDelegate sharedAppDelegate] mainViewController] dismissModalViewControllerAnimated:YES]; } @@ -240,7 +240,7 @@ nextController.navigationItem.hidesBackButton = YES; [nextController viewWillAppear:NO]; [targetController.navigationController pushViewController:nextController animated:NO]; - [AudioManagerController playClickSound]; + [[AudioManagerController mainManager] playClickSound]; } } diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Classes/SquareButtonView.h --- a/project_files/HedgewarsMobile/Classes/SquareButtonView.h Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/SquareButtonView.h Wed May 02 23:53:45 2012 +0200 @@ -21,15 +21,16 @@ @interface SquareButtonView : UIButton { - NSInteger colorIndex; + NSMutableDictionary *ownerDictionary; + NSUInteger colorIndex; NSUInteger selectedColor; NSArray *colorArray; - NSMutableDictionary *ownerDictionary; } +@property (nonatomic,retain) NSMutableDictionary *ownerDictionary; @property (nonatomic,retain) NSArray *colorArray; -@property (nonatomic) NSUInteger selectedColor; -@property (nonatomic,retain) NSMutableDictionary *ownerDictionary; +@property (nonatomic,assign) NSUInteger selectedColor; +@property (nonatomic,assign) NSUInteger colorIndex; -(void) nextColor; -(void) selectColor:(NSUInteger) color; diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Classes/SquareButtonView.m --- a/project_files/HedgewarsMobile/Classes/SquareButtonView.m Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/SquareButtonView.m Wed May 02 23:53:45 2012 +0200 @@ -22,12 +22,12 @@ @implementation SquareButtonView -@synthesize colorArray, selectedColor, ownerDictionary; +@synthesize ownerDictionary, colorIndex, selectedColor, colorArray; -(id) initWithFrame:(CGRect)frame { if ((self = [super initWithFrame:frame])) { - colorIndex = -1; - selectedColor = 0; + self.colorIndex = 0; + self.selectedColor = 0; self.colorArray = [HWUtils teamColors]; @@ -47,24 +47,21 @@ } -(void) nextColor { - colorIndex++; + self.colorIndex++; - if (colorIndex >= [colorArray count]) - colorIndex = 0; + if (self.colorIndex >= [self.colorArray count]) + self.colorIndex = 0; - NSUInteger color = [[self.colorArray objectAtIndex:colorIndex] unsignedIntValue]; - self.backgroundColor = [UIColor colorWithRed:((color & 0x00FF0000) >> 16)/255.0f - green:((color & 0x0000FF00) >> 8)/255.0f - blue: (color & 0x000000FF)/255.0f - alpha:1.0f]; - - [ownerDictionary setObject:[NSNumber numberWithInt:color] forKey:@"color"]; + NSNumber *colorNumber = [self.colorArray objectAtIndex:colorIndex]; + [self.ownerDictionary setObject:colorNumber forKey:@"color"]; + NSUInteger color = [colorNumber unsignedIntValue]; + [self selectColor:color]; } -(void) selectColor:(NSUInteger) color { - if (color != selectedColor) { - selectedColor = color; - colorIndex = [self.colorArray indexOfObject:[NSNumber numberWithUnsignedInt:color]]; + if (color != self.selectedColor) { + self.selectedColor = color; + self.colorIndex = [self.colorArray indexOfObject:[NSNumber numberWithUnsignedInt:color]]; self.backgroundColor = [UIColor colorWithRed:((color & 0x00FF0000) >> 16)/255.0f green:((color & 0x0000FF00) >> 8)/255.0f diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Classes/StatsPageViewController.h --- a/project_files/HedgewarsMobile/Classes/StatsPageViewController.h Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/StatsPageViewController.h Wed May 02 23:53:45 2012 +0200 @@ -26,4 +26,4 @@ @property (nonatomic,retain) NSArray *statsArray; -@end \ No newline at end of file +@end diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Classes/StatsPageViewController.m --- a/project_files/HedgewarsMobile/Classes/StatsPageViewController.m Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/StatsPageViewController.m Wed May 02 23:53:45 2012 +0200 @@ -161,7 +161,7 @@ #pragma mark - #pragma mark button delegate -(void) dismissView { - [AudioManagerController playClickSound]; + [[AudioManagerController mainManager] playClickSound]; [self dismissModalViewControllerAnimated:YES]; } diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Classes/TeamConfigViewController.m --- a/project_files/HedgewarsMobile/Classes/TeamConfigViewController.m Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/HedgewarsMobile/Classes/TeamConfigViewController.m Wed May 02 23:53:45 2012 +0200 @@ -68,7 +68,7 @@ self.cachedContentsOfDir = contentsOfDir; NSArray *colors = [HWUtils teamColors]; NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:[contentsOfDir count]]; - for (int i = 0; i < [contentsOfDir count]; i++) { + for (NSUInteger i = 0; i < [contentsOfDir count]; i++) { NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithObjectsAndKeys: [contentsOfDir objectAtIndex:i],@"team", [NSNumber numberWithInt:4],@"number", @@ -224,8 +224,8 @@ #pragma mark - #pragma mark Table view delegate -(void) tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - NSInteger row = [indexPath row]; - NSInteger section = [indexPath section]; + NSUInteger row = [indexPath row]; + NSUInteger section = [indexPath section]; if (section == 1 && [self.listOfAllTeams count] > row) { [self.listOfSelectedTeams addObject:[self.listOfAllTeams objectAtIndex:row]]; @@ -254,7 +254,7 @@ } -(void) holdAction:(NSString *)content onTable:(UITableView *)aTableView { - NSInteger row; + NSUInteger row; for (row = 0; row < [self.listOfSelectedTeams count]; row++) { NSDictionary *dict = [self.listOfSelectedTeams objectAtIndex:row]; if ([content isEqualToString:[[dict objectForKey:@"team"] stringByDeletingPathExtension]]) diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Hedgewars.xcodeproj/project.pbxproj --- a/project_files/HedgewarsMobile/Hedgewars.xcodeproj/project.pbxproj Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/HedgewarsMobile/Hedgewars.xcodeproj/project.pbxproj Wed May 02 23:53:45 2012 +0200 @@ -69,8 +69,8 @@ 611E0EE711FB20610077A41E /* ammoButton.png in Resources */ = {isa = PBXBuildFile; fileRef = 611E0EE511FB20610077A41E /* ammoButton.png */; }; 611E0EE811FB20610077A41E /* cornerButton.png in Resources */ = {isa = PBXBuildFile; fileRef = 611E0EE611FB20610077A41E /* cornerButton.png */; }; 611E12FF117BBBDA0044B62F /* Entitlements-Development.plist in Resources */ = {isa = PBXBuildFile; fileRef = 611E12FE117BBBDA0044B62F /* Entitlements-Development.plist */; }; - 611EE974122A9C4100DF6938 /* clickSound.wav in Resources */ = {isa = PBXBuildFile; fileRef = 611EE973122A9C4100DF6938 /* clickSound.wav */; }; - 611EE9DA122AA10A00DF6938 /* selSound.wav in Resources */ = {isa = PBXBuildFile; fileRef = 611EE9D8122AA10A00DF6938 /* selSound.wav */; }; + 611EE974122A9C4100DF6938 /* clickSound.caf in Resources */ = {isa = PBXBuildFile; fileRef = 611EE973122A9C4100DF6938 /* clickSound.caf */; }; + 611EE9DA122AA10A00DF6938 /* selSound.caf in Resources */ = {isa = PBXBuildFile; fileRef = 611EE9D8122AA10A00DF6938 /* selSound.caf */; }; 611EEAEE122B2A4D00DF6938 /* HelpPageInGameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 611EEAEC122B2A4D00DF6938 /* HelpPageInGameViewController.m */; }; 611EEAEF122B2A4D00DF6938 /* HelpPageLobbyViewController-iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 611EEAED122B2A4D00DF6938 /* HelpPageLobbyViewController-iPad.xib */; }; 611EEBC1122B34A800DF6938 /* helpingame.png in Resources */ = {isa = PBXBuildFile; fileRef = 611EEBC0122B34A800DF6938 /* helpingame.png */; }; @@ -190,7 +190,7 @@ 6179883C114AA34C00BA94A9 /* uVisualGears.pas in Sources */ = {isa = PBXBuildFile; fileRef = 6179880E114AA34C00BA94A9 /* uVisualGears.pas */; }; 6179883D114AA34C00BA94A9 /* uWorld.pas in Sources */ = {isa = PBXBuildFile; fileRef = 6179880F114AA34C00BA94A9 /* uWorld.pas */; }; 61798935114AB25F00BA94A9 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 61798934114AB25F00BA94A9 /* AudioToolbox.framework */; }; - 61808A5D128C930A005D0E2F /* backSound.wav in Resources */ = {isa = PBXBuildFile; fileRef = 611EE9D7122AA10A00DF6938 /* backSound.wav */; }; + 61808A5D128C930A005D0E2F /* backSound.caf in Resources */ = {isa = PBXBuildFile; fileRef = 611EE9D7122AA10A00DF6938 /* backSound.caf */; }; 61842B24122B619D0096E335 /* HelpPageInGameViewController-iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 61842B23122B619D0096E335 /* HelpPageInGameViewController-iPad.xib */; }; 61842B3E122B65BD0096E335 /* helpabove.png in Resources */ = {isa = PBXBuildFile; fileRef = 61842B3D122B65BD0096E335 /* helpabove.png */; }; 61842B40122B66280096E335 /* helpleft.png in Resources */ = {isa = PBXBuildFile; fileRef = 61842B3F122B66280096E335 /* helpleft.png */; }; @@ -416,9 +416,9 @@ 611E0EE511FB20610077A41E /* ammoButton.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ammoButton.png; path = Resources/Overlay/ammoButton.png; sourceTree = ""; }; 611E0EE611FB20610077A41E /* cornerButton.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = cornerButton.png; path = Resources/Overlay/cornerButton.png; sourceTree = ""; }; 611E12FE117BBBDA0044B62F /* Entitlements-Development.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Entitlements-Development.plist"; sourceTree = ""; }; - 611EE973122A9C4100DF6938 /* clickSound.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; name = clickSound.wav; path = Resources/clickSound.wav; sourceTree = ""; }; - 611EE9D7122AA10A00DF6938 /* backSound.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; name = backSound.wav; path = Resources/backSound.wav; sourceTree = ""; }; - 611EE9D8122AA10A00DF6938 /* selSound.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; name = selSound.wav; path = Resources/selSound.wav; sourceTree = ""; }; + 611EE973122A9C4100DF6938 /* clickSound.caf */ = {isa = PBXFileReference; lastKnownFileType = file; name = clickSound.caf; path = Resources/clickSound.caf; sourceTree = ""; }; + 611EE9D7122AA10A00DF6938 /* backSound.caf */ = {isa = PBXFileReference; lastKnownFileType = file; name = backSound.caf; path = Resources/backSound.caf; sourceTree = ""; }; + 611EE9D8122AA10A00DF6938 /* selSound.caf */ = {isa = PBXFileReference; lastKnownFileType = file; name = selSound.caf; path = Resources/selSound.caf; sourceTree = ""; }; 611EEAEB122B2A4D00DF6938 /* HelpPageInGameViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HelpPageInGameViewController.h; sourceTree = ""; }; 611EEAEC122B2A4D00DF6938 /* HelpPageInGameViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HelpPageInGameViewController.m; sourceTree = ""; }; 611EEAED122B2A4D00DF6938 /* HelpPageLobbyViewController-iPad.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = "HelpPageLobbyViewController-iPad.xib"; sourceTree = ""; }; @@ -891,9 +891,9 @@ isa = PBXGroup; children = ( 612CABC71391D3CC005E9596 /* hwclassic.mp3 */, - 611EE973122A9C4100DF6938 /* clickSound.wav */, - 611EE9D7122AA10A00DF6938 /* backSound.wav */, - 611EE9D8122AA10A00DF6938 /* selSound.wav */, + 611EE973122A9C4100DF6938 /* clickSound.caf */, + 611EE9D7122AA10A00DF6938 /* backSound.caf */, + 611EE9D8122AA10A00DF6938 /* selSound.caf */, ); name = Sounds; sourceTree = ""; @@ -1516,8 +1516,8 @@ 615AD96212073B4D00F2FF04 /* startGameButton.png in Resources */, 615AD9E9120764CA00F2FF04 /* backButton.png in Resources */, 615AD9EB1207654E00F2FF04 /* helpButton.png in Resources */, - 611EE974122A9C4100DF6938 /* clickSound.wav in Resources */, - 611EE9DA122AA10A00DF6938 /* selSound.wav in Resources */, + 611EE974122A9C4100DF6938 /* clickSound.caf in Resources */, + 611EE9DA122AA10A00DF6938 /* selSound.caf in Resources */, 611EEAEF122B2A4D00DF6938 /* HelpPageLobbyViewController-iPad.xib in Resources */, 611EEBC1122B34A800DF6938 /* helpingame.png in Resources */, 611EEBC4122B355700DF6938 /* helpbottom.png in Resources */, @@ -1538,7 +1538,7 @@ 61E2F7451283752C00E12521 /* tw.png in Resources */, 61DF0EDC1284DF2300F3F10B /* HelpPageLobbyViewController-iPhone.xib in Resources */, 61DF0F211284F72A00F3F10B /* HelpPageInGameViewController-iPhone.xib in Resources */, - 61808A5D128C930A005D0E2F /* backSound.wav in Resources */, + 61808A5D128C930A005D0E2F /* backSound.caf in Resources */, 61D3D2A51290E03A003CE7C3 /* irc.png in Resources */, 6172FED91298CF9800D73365 /* background~iphone.png in Resources */, 6172FEEF1298D25D00D73365 /* mediumBackground~ipad.png in Resources */, @@ -1875,6 +1875,7 @@ 61022D7C12305A2800B08935 /* Distro AppStore */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; APPLY_RULES_IN_COPY_FILES = YES; ARCHS = "$(ARCHS_STANDARD_32_BIT)"; CODE_SIGN_IDENTITY = "iPhone Distribution"; @@ -1887,13 +1888,34 @@ FPC_UNITS_PATH = "-Fu\"$(PROJECT_DIR)\""; GCC_C_LANGUAGE_STANDARD = c99; GCC_DEBUGGING_SYMBOLS = default; + GCC_DYNAMIC_NO_PIC = NO; GCC_FAST_MATH = YES; GCC_OPTIMIZATION_LEVEL = s; GCC_PREPROCESSOR_DEFINITIONS = ""; GCC_STRICT_ALIASING = YES; GCC_THUMB_SUPPORT = NO; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; + GCC_WARN_ABOUT_MISSING_NEWLINE = YES; + GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES; + GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; + GCC_WARN_MISSING_PARENTHESES = YES; + GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; + GCC_WARN_PEDANTIC = YES; + GCC_WARN_SHADOW = YES; + GCC_WARN_SIGN_COMPARE = YES; + GCC_WARN_STRICT_SELECTOR_MATCH = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = NO; + GCC_WARN_UNKNOWN_PRAGMAS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_LABEL = YES; + GCC_WARN_UNUSED_PARAMETER = NO; + GCC_WARN_UNUSED_VALUE = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = ( "\"$(SRCROOT)/../../../Library/SDL/src/video\"/**", @@ -1916,6 +1938,12 @@ TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; VALID_ARCHS = "armv7 armv6"; + WARNING_CFLAGS = ( + "-Wall", + "-Wbad-function-cast", + "-Wmissing-declarations", + "-Wnested-externs", + ); }; name = "Distro AppStore"; }; @@ -1956,6 +1984,7 @@ 6137064B117B1CB3004EE44A /* Distro Adhoc */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; APPLY_RULES_IN_COPY_FILES = YES; ARCHS = "$(ARCHS_STANDARD_32_BIT)"; CODE_SIGN_ENTITLEMENTS = "Entitlements-Distribution.plist"; @@ -1969,13 +1998,34 @@ FPC_UNITS_PATH = "-Fu\"$(PROJECT_DIR)\""; GCC_C_LANGUAGE_STANDARD = c99; GCC_DEBUGGING_SYMBOLS = full; + GCC_DYNAMIC_NO_PIC = YES; GCC_FAST_MATH = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; GCC_STRICT_ALIASING = YES; GCC_THUMB_SUPPORT = NO; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; + GCC_WARN_ABOUT_MISSING_NEWLINE = YES; + GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES; + GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; + GCC_WARN_MISSING_PARENTHESES = YES; + GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; + GCC_WARN_PEDANTIC = YES; + GCC_WARN_SHADOW = YES; + GCC_WARN_SIGN_COMPARE = YES; + GCC_WARN_STRICT_SELECTOR_MATCH = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = NO; + GCC_WARN_UNKNOWN_PRAGMAS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_LABEL = YES; + GCC_WARN_UNUSED_PARAMETER = NO; + GCC_WARN_UNUSED_VALUE = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = ( "\"$(SRCROOT)/../../../Library/SDL/src/video\"/**", @@ -1996,6 +2046,12 @@ TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; VALID_ARCHS = "armv7 armv6"; + WARNING_CFLAGS = ( + "-Wall", + "-Wbad-function-cast", + "-Wmissing-declarations", + "-Wnested-externs", + ); }; name = "Distro Adhoc"; }; @@ -2080,6 +2136,7 @@ C01FCF4F08A954540054247B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; APPLY_RULES_IN_COPY_FILES = YES; ARCHS = "$(ARCHS_STANDARD_32_BIT)"; CODE_SIGN_IDENTITY = "iPhone Developer"; @@ -2093,13 +2150,34 @@ FPC_UNITS_PATH = "-Fu\"$(PROJECT_DIR)\""; GCC_C_LANGUAGE_STANDARD = c99; GCC_DEBUGGING_SYMBOLS = full; + GCC_DYNAMIC_NO_PIC = NO; GCC_FAST_MATH = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; GCC_STRICT_ALIASING = YES; GCC_THUMB_SUPPORT = NO; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; + GCC_WARN_ABOUT_MISSING_NEWLINE = YES; + GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES; + GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; + GCC_WARN_MISSING_PARENTHESES = YES; + GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; + GCC_WARN_PEDANTIC = YES; + GCC_WARN_SHADOW = YES; + GCC_WARN_SIGN_COMPARE = YES; + GCC_WARN_STRICT_SELECTOR_MATCH = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = NO; + GCC_WARN_UNKNOWN_PRAGMAS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_LABEL = YES; + GCC_WARN_UNUSED_PARAMETER = NO; + GCC_WARN_UNUSED_VALUE = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = ( "\"$(SRCROOT)/../../../Library/SDL/src/video\"/**", @@ -2120,12 +2198,19 @@ TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = NO; VALID_ARCHS = "armv7 armv6"; + WARNING_CFLAGS = ( + "-Wall", + "-Wbad-function-cast", + "-Wmissing-declarations", + "-Wnested-externs", + ); }; name = Debug; }; C01FCF5008A954540054247B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; APPLY_RULES_IN_COPY_FILES = YES; ARCHS = "$(ARCHS_STANDARD_32_BIT)"; CODE_SIGN_ENTITLEMENTS = "Entitlements-Development.plist"; @@ -2139,13 +2224,34 @@ FPC_UNITS_PATH = "-Fu\"$(PROJECT_DIR)\""; GCC_C_LANGUAGE_STANDARD = c99; GCC_DEBUGGING_SYMBOLS = default; + GCC_DYNAMIC_NO_PIC = YES; GCC_FAST_MATH = YES; GCC_OPTIMIZATION_LEVEL = s; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; GCC_STRICT_ALIASING = YES; GCC_THUMB_SUPPORT = NO; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; + GCC_WARN_ABOUT_MISSING_NEWLINE = YES; + GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES; + GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; + GCC_WARN_MISSING_PARENTHESES = YES; + GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; + GCC_WARN_PEDANTIC = YES; + GCC_WARN_SHADOW = YES; + GCC_WARN_SIGN_COMPARE = YES; + GCC_WARN_STRICT_SELECTOR_MATCH = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = NO; + GCC_WARN_UNKNOWN_PRAGMAS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_LABEL = YES; + GCC_WARN_UNUSED_PARAMETER = NO; + GCC_WARN_UNUSED_VALUE = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = ( "\"$(SRCROOT)/../../../Library/SDL/src/video\"/**", @@ -2167,6 +2273,12 @@ TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = NO; VALID_ARCHS = "armv7 armv6"; + WARNING_CFLAGS = ( + "-Wall", + "-Wbad-function-cast", + "-Wmissing-declarations", + "-Wnested-externs", + ); }; name = Release; }; diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Hedgewars_Prefix.pch --- a/project_files/HedgewarsMobile/Hedgewars_Prefix.pch Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/HedgewarsMobile/Hedgewars_Prefix.pch Wed May 02 23:53:45 2012 +0200 @@ -31,6 +31,5 @@ #import "CreationChamber.h" #import "HWUtils.h" #import "hwconsts.h" -#import "SDL_net.h" #endif diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Resources/backSound.caf Binary file project_files/HedgewarsMobile/Resources/backSound.caf has changed diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Resources/backSound.wav Binary file project_files/HedgewarsMobile/Resources/backSound.wav has changed diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Resources/clickSound.caf Binary file project_files/HedgewarsMobile/Resources/clickSound.caf has changed diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Resources/clickSound.wav Binary file project_files/HedgewarsMobile/Resources/clickSound.wav has changed diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Resources/selSound.caf Binary file project_files/HedgewarsMobile/Resources/selSound.caf has changed diff -r 9e724f4863a3 -r 6af78154dc62 project_files/HedgewarsMobile/Resources/selSound.wav Binary file project_files/HedgewarsMobile/Resources/selSound.wav has changed diff -r 9e724f4863a3 -r 6af78154dc62 project_files/hedgewars.pro --- a/project_files/hedgewars.pro Sun Apr 01 15:23:34 2012 +0200 +++ b/project_files/hedgewars.pro Wed May 02 23:53:45 2012 +0200 @@ -22,7 +22,8 @@ QT += network QT += webkit -HEADERS += ../QTfrontend/model/themesmodel.h \ +HEADERS += ../QTfrontend/model/ThemeModel.h \ + ../QTfrontend/model/MapModel.h \ ../QTfrontend/model/ammoSchemeModel.h \ ../QTfrontend/model/netserverslist.h \ ../QTfrontend/model/hats.h \ @@ -72,7 +73,7 @@ ../QTfrontend/ui/widget/mapContainer.h \ ../QTfrontend/ui/widget/HistoryLineEdit.h \ ../QTfrontend/ui/widget/SmartLineEdit.h \ - ../QTfrontend/util/HWDataManager.h \ + ../QTfrontend/util/DataManager.h \ ../QTfrontend/net/netregister.h \ ../QTfrontend/net/netserver.h \ ../QTfrontend/net/netudpwidget.h \ @@ -100,10 +101,12 @@ ../QTfrontend/ui/qpushbuttonwithsound.h \ ../QTfrontend/ui/widget/qpushbuttonwithsound.h \ ../QTfrontend/ui/page/pagefeedback.h \ - ../QTfrontend/model/roomslistmodel.h + ../QTfrontend/model/roomslistmodel.h \ + ../QTfrontend/ui/dialog/input_password.h SOURCES += ../QTfrontend/model/ammoSchemeModel.cpp \ - ../QTfrontend/model/themesmodel.cpp \ + ../QTfrontend/model/MapModel.cpp \ + ../QTfrontend/model/ThemeModel.cpp \ ../QTfrontend/model/hats.cpp \ ../QTfrontend/model/netserverslist.cpp \ ../QTfrontend/ui/qaspectratiolayout.cpp \ @@ -152,7 +155,7 @@ ../QTfrontend/ui/widget/mapContainer.cpp \ ../QTfrontend/ui/widget/HistoryLineEdit.cpp \ ../QTfrontend/ui/widget/SmartLineEdit.cpp \ - ../QTfrontend/util/HWDataManager.cpp \ + ../QTfrontend/util/DataManager.cpp \ ../QTfrontend/net/tcpBase.cpp \ ../QTfrontend/net/netregister.cpp \ ../QTfrontend/net/proto.cpp \ @@ -178,7 +181,8 @@ ../QTfrontend/ui/mouseoverfilter.cpp \ ../QTfrontend/ui/widget/qpushbuttonwithsound.cpp \ ../QTfrontend/ui/page/pagefeedback.cpp \ - ../QTfrontend/model/roomslistmodel.cpp + ../QTfrontend/model/roomslistmodel.cpp \ + ../QTfrontend/ui/dialog/input_password.cpp win32 { SOURCES += ../QTfrontend/xfire.cpp diff -r 9e724f4863a3 -r 6af78154dc62 share/hedgewars/Data/Locale/cs.txt --- a/share/hedgewars/Data/Locale/cs.txt Sun Apr 01 15:23:34 2012 +0200 +++ b/share/hedgewars/Data/Locale/cs.txt Wed May 02 23:53:45 2012 +0200 @@ -52,6 +52,10 @@ 00:49=OÅŸivovač 00:50=VrtákovÃœ útok 00:51=Hrouda bláta +00:52=Není vybrána şádná zbraň +00:53=TimeBox +00:54=Struktura +00:55=Pozemek s rozpraÅ¡ovačem 01:00=Do boje! 01:01=Kolo nerozhodně @@ -68,6 +72,12 @@ 01:12=Poslední kolo před Náhlou smrtí! 01:13=%1 kol do Náhlé smrti! 01:14=Připrav se, %1! +01:15=NepatrnÃœ +01:16=NízkÃœ +01:17=Normální +01:18=VysokÃœ +01:19=Extrémní +01:20=%1 odskočit ; Event messages ; Hog (%1) died @@ -175,7 +185,7 @@ 02:01=%1 má v ranách slanou vodu 02:01=%1 Å¡el po prkně 02:01=%1 si dává koupel -02:01=%1 je moc moc moc mokrÃœ +02:01=%1 je moc moc moc mokrÃœ 02:01=%1 si namočil bodliny 02:01=%1 naÅ¡el truhlu Mrtvého muÅŸe @@ -434,6 +444,11 @@ 03:48=Čas na kladivo! 03:49=Dělá to, co myslíš 03:50=Krtkův fanda +03:51=Nalezeno na zemi +03:52=NEPOUÅœITO +03:53=Typ 40 +03:54=Vytvořit něco +03:55=UÅŸitečnost ; Weapon Descriptions (use | as line breaks) 04:00=Zaútoč na nepřítele pomocí obyčejného granátu.|Exploduje jakmile časovač dojde k nule.|1-5: Nastavuje časovač|Útok: DrÅŸ pro hození větší silou @@ -487,6 +502,12 @@ 04:47=Zdvojnásob zábavu pomocí dvou ostnatÃœch, zákeřnÃœch, lepkavÃœch|min. Vytvoř řetězovou reakci nebo se braň (nebo oboje!)|Útok: DrÅŸ pro hození větší silou (dvakrát) 04:48=Proč by se měli tÃœrat jen krtci? Mlácení jeÅŸků můşe|bÃœt stejná zábava! Jedna dobrá rána tímhle kladivem|uÅ¡tědří poÅ¡kození za jednu třetinu jeÅŸkova zdraví a|zarazí ho pod zem.|Útok: Aktivace 04:49=Vzkřis své přátele! Ale měj se na pozoru, protoÅŸe|tohle vzkřísí i tvé protivníky.|Útok: DrÅŸ stisknuto pro pomalé oÅŸivování|Nahoru: Zrychlí oÅŸivování +04:50=Je někdo skrÃœvá v podzemí?|Vykopat s vrtačkou stávky!|Časovač určuje, jak daleko to bude kopat. +04:51=Získat ve volném záběru vrhá kouli bláta.|Åœihadla bit, a srazí prasata zpět. +04:52=NEPOUÅœITO +04:53=Vydejte se na dobrodruÅŸství v čase a prostoru,|přičemÅŸ vaÅ¡i kamarádi bojovat dál sám.|BÃœt připraven vrátit kdykoliv,|nebo náhlé smrti nebo pokud jsou vÅ¡ichni poraÅŸeni.|Prohlášení. Nefunguje v náhlé smrti,|Pokud jste sami, nebo jste-li král. +04:54=NEÚPLNÝ +04:55=Sprej proud lepkavÃœmi vločkami.|Stavět mosty, pohřbít nepřátele, utěsnění tunely.|Buďte opatrní, nechcete dostat kaÅŸdÃœ z vás! ; Game goal strings 05:00=Herní módy @@ -510,3 +531,4 @@ 05:18=Neomezeně útoků 05:19=Zbraně jsou obnoveny na konci tahu 05:20=Zbraně nejsou sdíleny mezi jeÅŸky +05:21=Tag tÃœmu: TÃœmy v klanu se postupně střídají|Sdílené čas: TÃœmy v rámci podílu klan zase čas diff -r 9e724f4863a3 -r 6af78154dc62 share/hedgewars/Data/Locale/de.txt --- a/share/hedgewars/Data/Locale/de.txt Sun Apr 01 15:23:34 2012 +0200 +++ b/share/hedgewars/Data/Locale/de.txt Wed May 02 23:53:45 2012 +0200 @@ -103,6 +103,47 @@ 02:00=%1 war einmal. 02:00=%1 hat wohl versagt. 02:00=Mach's gut, %1! +02:00=%1 hinterlÀsst eine Frau und Kind +02:00=%1 ins Leben gerufen hat seine letzte Panzerfaust +02:00=%1 hat seine letzte Granate geworfen +02:00=%1 hat seine letzte Kuchen gebacken +02:00=%1 hat auf seiner letzten Seil schwangen +02:00=%1 genannt hat seinen letzten Luftangriff +02:00=%1 gepumpt hat seine letzte Schrotflinte +02:00=%1 geworfen hat seine letzte Melone +02:00=%1 gezogen hat seinen letzten deagle +02:00=%1 nahm einen Schuss zu viel +02:00=%1 könnte wirklich eine gesundheitliche Kiste verwendet haben +02:00=%1 gegangen ist, um ein besseres Spiel zu spielen +02:00=%1 hat ragequit Leben +02:00=%1 scheitert +02:00=Schlecht schlecht %1... +02:00=%1 lieber Warmux +02:00=%1 wurde blockiert SchÃŒsse mit seinem Gesicht +02:00=%1 ist ein Held unter mir ... err ... Schweine +02:00=%1 findet seinen Platz in der Walhalla +02:00=%1 hat das GebÀude verlassen +02:00=%1 geht den Weg der Dinosaurier +02:00=%1 Igel bringt, einen Schritt nÀher zum Aussterben +02:00=%1 bringt eine TrÀne zu mir ins Auge +02:00=%1 ist ein Ex-Schwein +02:00=%1 wird die Radieschen +02:00=%1 hat aufgehört zu sein +02:00=Verabschieden Sie sich von %1 +02:00=Keine Hoffnung mehr fÃŒr %1 +02:00=%1 steht vor der letzte Vorhang +02:00=Rauchen, wenn du hast, %1 +02:00=%1 erleidet einen spontanen massiven Vorhandensein Ausfall +02:00=%1 weitergegeben hat +02:00=%1 ist mausetot +02:00=%1 nicht mehr +02:00=%1 abgelaufen +02:00=Beraubt des Lebens, %1 ruht in Frieden +02:00=%1 tritt der Chor unsichtbar +02:00=Abschied %1, wussten wir kaum ye! +02:00=%1 hatte eine geringe Toleranz fÃŒr erschossen +02:00=%1 hÀtte verwenden können ein zusÀtzliches Leben +02:00=Gibt es einen Arzt im Haus? ; Hog (%1) drowned 02:01=%1 geht auf Tauchstation! @@ -127,6 +168,51 @@ 02:01=%1 erliegt dem Sog der Tiefe! 02:01=%1 geht der Sache auf den Grund! 02:01=%1 wÀre fast verdurstet! +02:01=%1 checkt das tiefe Ende +02:01=%1 geht gluck gluck gluck +02:01=%1 geht Spritzer +02:01=%1 vergaß seine Armbinden +02:01=%1 wirklich genommen haben sollte Schwimmunterricht +02:01=%1 verließ seinem Surfbrett zu Hause +02:01=%1 wird gewaschen, bis +02:01=%1 ist ein Schwein matschig +02:01=%1 vergessen, sein Leben zu bringen Jacke +02:01=%1 geht Splish Spritzer +02:01=%1 wird mit den Fischen schlafen +02:01=%1 denkt das Wasser saugen Physik in diesem Spiel +02:01=%1 sieht durstig +02:01=Das Meer behauptet %1 +02:01=%1 wird auf dem Meer verschollen +02:01=%1 sollten mitgebracht haben seine TauchausrÃŒstung +02:01=%1 bekommt eine Bestattung auf See +02:01=%1 hat, dass die sinkenden GefÃŒhl +02:01=%1 ÃŒbt seine RÃŒckenschwimmen +02:01=%1 geht auf der Suche nach der Titanic +02:01=%1 ist nicht Jesus +02:01=%1 wird Findet Nemo +02:01=%1 ein Leck +02:01=Du mußt fragen, wie viele Schweine sind da unten +02:01=%1 macht das Meer etwas höher +02:01=%1 nicht in der Marine zu gewinnen +02:01=%1 tut sein IdentitÀtswechsel von einem toten Fisch +02:01=Zumindest ging nicht in die Toilette, %1 +02:01=Sonic nicht schwimmen konnte und kann weder %1 +02:01=%1 will spielen Ecco the Dolphin +02:01=%1, Aquaria ist gegangen, um zu besuchen +02:01=%1 hat festgestellt, die verlorene Stadt Atlantis +02:01=%1 Ziele fÃŒr die Hauptrolle in Bioshock 3 +02:01=Ihre doggy Paddel könnte ein wenig Arbeit, %1 +02:01=%1 sollten mitgebracht haben einen Jet-Ski +02:01=%1 mag es nicht, Wassersport +02:01=%1 wird forever blowing bubbles +02:01=%1 ist kurz von einem Floß +02:01=%1 denkt Salzwasser ist gut fÃŒr die Haut +02:01=%1 bekommt Salzwasser in seine Wunden +02:01=%1 hat ging die Planke +02:01=%1 verfÃŒgt ÃŒber eine Badewanne +02:01=%1 ist nass nass nass +02:01=%1 bekommt seine Federkiele nass +02:01=Es ist Davy Jones 'locker fÃŒr %1 ; Round starts 02:02=Auf in die Schlacht! @@ -135,6 +221,55 @@ 02:02=Los geht's! 02:02=Alles angetreten! 02:02=Los, los, los! +02:02=Lassen Sie uns dies Partei beginnen +02:02=Letzte Schwein steht gewinnt +02:02=Gehen wir! +02:02=Lasst uns rocken! +02:02=Lassen Sie uns jam! +02:02=Es ist Anfang ... +02:02=Dies ist der Beginn von etwas Großem +02:02=Willkommen bei Hedgewars +02:02=Willkommen auf der Front +02:02=Crush deine Feinde! +02:02=Mai die beste Schwein Sieg +02:02=Sieg oder Tod +02:02=Dem Sieger geht die Beute +02:02=Verlieren ist keine Option +02:02=Cry Havoc! Lassen Sie verlieren die Schweine des Krieges! +02:02=Hedgewars, die Ihnen von Hedgewars.org +02:02=GL HF +02:02=Nur sich glÃŒcklich schÀtzen du bist nicht gegen Tiyuri +02:02=Nur sich glÃŒcklich schÀtzen du bist nicht gegen unC0Rr +02:02=Nur sich glÃŒcklich schÀtzen du bist nicht gegen Nemo +02:02=Nur sich glÃŒcklich schÀtzen du bist nicht gegen Smaxx +02:02=Nur sich glÃŒcklich schÀtzen du bist nicht gegen Jessor +02:02=Gib alles! +02:02=Die Verlierer machen die Reinigung auf! +02:02=Lassen Sie den Kampf des Jahrtausends beginnen +02:02=Lassen Sie den Kampf des Jahrhunderts beginnen +02:02=Lassen Sie den Kampf des Jahrzehnts beginnen +02:02=Lassen Sie den Kampf des Jahres beginnen +02:02=Lassen Sie den Kampf des Monats beginnen +02:02=Lassen Sie den Kampf in der Woche beginnen +02:02=Lassen Sie den Kampf des Tages beginnen +02:02=Lassen Sie den Kampf der Stunde beginnen +02:02=Tun Sie Ihr Bestes! +02:02=Zerstöre den Feind! +02:02=Viel GlÃŒck +02:02=Viel Spaß +02:02=KÀmpfe den guten Kampf +02:02=Kampf schmutzig +02:02=Kampf mit Ehre +02:02=Gib nicht auf +02:02=Never surrender +02:02=Rock und Socke! +02:02=Lassen Sie den fragfest beginnen! +02:02=Ich hoffe du bist bereit fÃŒr einen Kampf! +02:02=Gehen gehen! +02:02=Igel Voraus! +02:02=Bringt es ihnen! +02:02=Habt keine Angst! +02:02=Seien Sie mutig und erobern ; Round ends (win; unused atm) 02:03=... @@ -148,6 +283,16 @@ 02:05=Das kommt gelegen! 02:05=Jemand denkt an euch! 02:05=Mit Liebe verpackt? +02:05=Frisches Pflaster! +02:05=So werden Sie sich besser fÃŒhlen +02:05=Ein Hallo-Trank! Whoops falsche Spiel +02:05=Ein wÀhlen mir oben! +02:05=Zugreifen +02:05=Ein gesunder Snack +02:05=Ein Mittel, um Schmerzen +02:05=Richtige Dosierung: so viele wie du finden kannst! +02:05=Schnelle Lieferung +02:05=VorrÀte! ; New ammo crate 02:06=Nachschub! @@ -155,6 +300,22 @@ 02:06=Was wohl darin ist? 02:06=Bringt das die Wende? 02:06=Tod aus der Luft! +02:06=Ein Geschenk! +02:06=Spezielle Lieferung! +02:06=Es war ein Alptraum bekommen dies durch den Zoll +02:06=Destruktive Spielzeug aus dem Himmel +02:06=Warnung! Inhalt FlÃŒchtige +02:06=WÀhlen es oder blasen sie auf, ist Qual der Wahl +02:06=Extras! +02:06=Mmm Munition +02:06=Eine Schachtel zerstörerische Kraft +02:06=Luftpost! +02:06=Was auch immer ist in diesem Feld ist es nicht Pizza +02:06=Bekommen! +02:06=Waffe fallen zu lassen eingehende +02:06=Lassen Sie sich nicht, dass der Feind schnappen! +02:06=Shiny neues Spielzeug! +02:06=Eine geheimnisvolle Kiste! ; New utility crate 02:07=NÃŒtzliches? @@ -162,6 +323,12 @@ 02:07=Was wohl darin ist? 02:07=Lieferung frei Haus! 02:07=Mehr als nur eine Kiste! +02:07=Weitere Hilfsmittel! +02:07=Extras fÃŒr Sie! +02:07=Dies sollte gut sein! +02:07=Verwenden Sie diese mit Bedacht +02:07=Ooo diese Box ist schwer +02:07=Möglicherweise mÃŒssen Sie diese ; Hog (%1) skips his turn 02:08=%1 ist so ein Langeweiler ... @@ -172,12 +339,68 @@ 02:08=%1 ist ein DrÃŒckeberger. 02:08=%1 ÃŒberdenkt die Situation. 02:08=%1 kann sich nicht entscheiden. +02:08=%1 muss ein wenig mehr Motivation +02:08=%1 ist ein Pazifist +02:08=%1 hat eine Verschnaufpause +02:08=%1 hat einen Rest +02:08=%1 SchÃŒttelfrost aus +02:08=%1 hat kein Vertrauen in seine eigenen FÀhigkeiten +02:08=%1 beschließt, nichts zu tun +02:08=%1 lÀsst den Feind zu vernichten selbst +02:08=%1 wÀre bei Partys schrecklich +02:08=%1 versteckt sich +02:08=%1 hat sich entschlossen, diese Chance geben +02:08=%1 entscheidet das Beste, was er tun kann, ist nichts ... +02:08=%1 ist ein großes Weichei +02:08=Bock bock bock, %1 ist ein Huhn +02:08=%1 schaut ein wenig gelb +02:08=%1 ist ein Feigling! +02:08=%1 wird fÃŒr den plötzlichen Tod wartet +02:08=%1 ist wartet auf Sudden Death +02:08=%1 ist nicht die BekÀmpfung von Typ +02:08=%1 ÃŒberdenkt seinen Sinn im Leben +02:08=%1 war nie viel von einem guten Schuss ohnehin +02:08=%1 wollte nicht, dass die Armee in erster Linie verbinden +02:08=Aufhören, unsere Zeit, %1 +02:08=Ich bin in dir enttÀuscht, %1 +02:08=Los, können Sie es besser machen %1 +02:08=%1 wird gebrochen +02:08=%1 hat anscheinend Besseres zu tun +02:08=%1 ist zu Tode erschrocken +02:08=%1 ist eingeschlafen ; Hog (%1) hurts himself only 02:09=%1 sollte besser Zielen ÃŒben! 02:09=%1 scheint sich zu hassen. 02:09=%1 steht auf der falschen Seite! 02:09=%1 lebt gefÀhrlich! +02:09=%1 hat keinen Instinkt der Selbsterhaltung +02:09=%1 durcheinander +02:09=%1 vermasselt +02:09=Das war ein schlechter Schuss, %1 +02:09=%1 ist ein wenig zu sorglos mit gefÀhrlichen Waffen +02:09=%1 sollte eine Änderung der Laufbahn betrachten +02:09=Schlechteste. Schuss. Je! +02:09=Kein kein kein %1, Sie schießen auf den Feind! +02:09=%1 sollte nur werden, den Feind zu vernichten +02:09=%1 bewegt sich einen Schritt nÀher an Selbstmord +02:09=%1, Hilfsmittel der Feind +02:09=Das war dumm %1 +02:09=%1 Leben mit dem Mantra des "keine Schmerzen, keine gewinnen" +02:09=%1 ist verwirrt +02:09=%1 verletzen sich in seiner Verwirrung +02:09=%1 hat ein Talent fÃŒr sich zu blamieren +02:09=%1 ist ein Trottel! +02:09=%1 ist ungeschickt +02:09=%1 zeigt der Feind, wozu er fÀhig ist +02:09=%1 kann nicht erwartet werden, perfekt zu sein werden die ganze Zeit +02:09=Mach dir keine Sorgen %1, pobody die nerfect +02:09=%1 völlig mit Absicht getan +02:09=Ich werde niemandem sagen, wenn Sie nicht tun, %1 +02:09=Wie peinlich! +02:09=Ich bin sicher, niemand sah, dass %1 +02:09=%1, BedÃŒrfnisse, seine Field Manual ÃŒberprÃŒfen +02:09=%1 Waffe eindeutig versagt ; Hog (%1) shot an home run (using the bat and another hog) 02:10=Home Run! @@ -305,7 +528,6 @@ 04:52=NICHT IN VERWENDUNG 04:53=Unternimm eine Reise durch Zeit und Raum,|wÀhrend du deine Kameraden alleine am Schlachtfeld zurÃŒcklÀsst.|Sei darauf vorbereitet jederzeit wieder zurÃŒckzukommen,|oder auf Sudden Death wenn sie alle besiegt wurden.|Disclaimer: Nicht funktionstÃŒchtig wenn in Sudden Death,|wenn du alleine bist - oder der König. 04:54=IN ARBEIT - 04:55=VersprÃŒhe einen Strahl klebriger Flocken.|Baue BrÃŒcken, begrabe Gegner, versiegle Tunnel.|Pass auf, dass du selbst nichts abbekommst! ; Game goal strings diff -r 9e724f4863a3 -r 6af78154dc62 share/hedgewars/Data/Locale/ja.txt --- a/share/hedgewars/Data/Locale/ja.txt Sun Apr 01 15:23:34 2012 +0200 +++ b/share/hedgewars/Data/Locale/ja.txt Wed May 02 23:53:45 2012 +0200 @@ -72,41 +72,481 @@ 01:12=サドンデスたで最埌の番 01:13=サドンデスたで%1番残り 01:14=準備しお、%1 +01:15=わずかな +01:16=䜎い +01:17=通垞の +01:18=高い +01:19=極端な +01:20=%1のバりンス ; Event messages ; Hog (%1) は死んだ。 02:00=%1 は倩囜を芋た。 +02:00=%1はバケツを蹎っおいたす +02:00=%1は光を芋たした +02:00=%1はそれが来るのを芋たせん +02:00=%1波さようなら +02:00=%1はより良い堎所に行っおきたした +02:00=%1は圌のメヌカヌを満たしおいる +02:00=%1は、もはやにハングアップするこずができたす +02:00=%1は自分の矩務を行っおいたす +02:00=%1は究極の犠牲になりたす +02:00=%1はこの浮き䞖に出発 +02:00=%1は朚や葉のようになりたす +02:00=%1がタむムアりトしたした +02:00=%1は平和倖ず蚀われたす。 +02:00=%1を懐かしく思い出すこずでしょう +02:00=%1は、動脈瘀を持っおいる +02:00=%1は劻ず子が残され +02:00=%1は圌の最埌のバズヌカを開始したした +02:00=%1は圌の最埌の手抎匟を投げおいたす +02:00=%1は圌の最埌のケヌキを焌きたした +02:00=%1は圌の最埌のロヌプに振っおいたす +02:00=%1は圌の最埌の空爆を呌びかけおいる +02:00=%1は圌の最埌のショットガンをポンプしおいたす +02:00=%1は圌の最埌のメロンをスロヌしたした +02:00=%1は圌の最埌のを集めおいる +02:00=%1぀があたりにも倚くを撃った +02:00=%1は実際に健康䞊のクレヌトを䜿甚するこずもできたした +02:00=%1は優れたゲヌムをプレむしおしたった +02:00=%1は寿呜を有する +02:00=%1が倱敗した +02:00=貧しい貧しい%1... +02:00=%1のwarmuxを奜む +02:00=%1は圌の顔をしおショットをブロックされおいたす +02:00=%1は私の䞭のヒヌロヌです...誀る...豚 +02:00=%1はノァルハラで圌の堎所を芋぀ける +02:00=%1は、建物を残しおいる +02:00=%1は恐竜の道を行く +02:00=%1が絶滅に䞀歩近づいたハリネズミをもたらす +02:00=%1は私の目に涙をもたらす +02:00=%1は元豚です。 +02:00=%1はヒナギクを抌し䞊げおいる +02:00=%1に該圓しなくな぀たずき、 +02:00=%1に別れを告げる +02:00=%1のために残された垌望しない +02:00=%1は、最終的なカヌテンに盎面しおいる +02:00=%1をあなたが埗た堎合は、をたばこを吞う +02:00=%1は自発的倧芏暡な存圚の障害を受ける +02:00=%1に枡されたした +02:00=%1は石死んでいる +02:00=%1はもうありたせん +02:00=%1は有効期限が切れおいたす +02:00=生呜を倱っお、%1は平和にかかっおいる +02:00=%1は目に芋えない合唱団に参加する +02:00=別れ%1は、我々はほずんどあなたがたを知りたせんでした +02:00=%1が撃たれるの䜎耐性を持っおいた +02:00=%1は䜙分な生掻を䜿甚するこずもできたした +02:00=家の䞭で医者はありたすか + ; Hog (%1) は溺れた。 02:01=%1 はタむタニック芋たい。 +02:01=%1は朜氎艊再生 +02:01=%1はタむタニックを暡倣した +02:01=石のように%1泳ぐ +02:01=レンガのように%1のフロヌト +02:01=%1は深い゚ンドをチェックアりト +02:01=%1は䞀気に飲む䞀気に飲むゎクリずいう音を行く +02:01=%1はスプラッシュを行く +02:01=%1は圌の腕章を忘れおしたった +02:01=%1は本圓に氎泳のレッスンを受けおいる必芁があり +02:01=%1は自宅で圌のサヌフボヌドを残した +02:01=%1は、最倧で掗浄する +02:01=%1はねっずり豚です。 +02:01=%1は、圌のラむフゞャケットを持参するのを忘れた +02:01=%1はスプラッシュを行く +02:01=%1は魚類で眠っおいる +02:01=%1はこのゲヌムでは氎の物理孊を吞うず考えおいる +02:01=%1はのどが枇いお芋える +02:01=海は%1を䞻匵 +02:01=%1は海で倱われる +02:01=%1は圌のスキュヌバギダを持っおいる必芁がありたす +02:01=%1は海に埋葬を取埗したす。 +02:01=%1はその沈没感を持っおいる +02:01=%1は圌の背泳ぎを緎習しおいる +02:01=%1は、タむタニック号の探玢に入りたす +02:01=%1はむ゚スではありたせん +02:01=%1はニモを芋぀けるこずです +02:01=%1のばね挏れ +02:01=あなたがダりンしおありたすどのように倚くの豚䞍思議ちゃ +02:01=%1は海で、若干高めになりたす +02:01=%1は海軍に入隊したせんでした +02:01=%1は死んだ魚の圌の停装を行っおいたす +02:01=少なくずも、あなたはトむレ、%1をシャットダりン行きたせんでした +02:01=゜ニックは泳げなかった、どちら%1猶 +02:01=%1ぱコヌザのむルカを再生したい +02:01=%1は氎族通を蚪問しおしたった +02:01=%1がアトランティスの倱われた郜垂を発芋した +02:01=%1でBioshock3の先導的な圹割を目指しお +02:01=あなたの犬のパドルは、少し䜜業は、%1を䜿甚するこずができたす +02:01=%1はゞェットスキヌを持っおいる必芁がありたす +02:01=%1はりォヌタヌスポヌツが奜きではありたせん。 +02:01=%1は氞遠に泡を吹いおいる +02:01=%1はいかだの短い +02:01=%1は、塩の氎が肌に良いず考えおいる +02:01=%1は圌の傷に塩氎を取埗したす。 +02:01=%1は板を歩いおいたす +02:01=%1はお颚呂を持っおいる +02:01=%1は濡れ濡れ濡れおいる +02:01=%1は圌のクむルが濡れた +02:01=これは、%1のデむビヌゞョヌンズのロッカヌだ + ; 初め 02:02=頑匵っお! +02:02=のは、戊いたしょう +02:02=歊装しお準備を +02:02=レッツランブルに準備ができたした +02:02=それを取埗しおみたしょう +02:02=このパヌティヌを始めるおみたしょう +02:02=最埌の豚に立っお受賞 +02:02=行きたしょう +02:02=ロックしたしょう +02:02=ゞャムしたしょう +02:02=それが始たりだ... +02:02=これは倧きな䜕かの始たりです +02:02=Hedgewarsぞようこそ +02:02=前線ぞようこそ +02:02=あなたの敵を抌し぀ぶす +02:02=最高の豚が勝぀可胜性があり +02:02=勝利か死 +02:02=勝者に戊利品を行く +02:02=ルヌゞングオプションではありたせん +02:02=混乱を叫ぶ戊争の豚を倱いたしょう +02:02=Hedgewarsは、Hedgewars.orgによっおあなたに持っお来られる +02:02=グラム +02:02=ただTiyuri察戊がわからない自分がラッキヌカりント +02:02=ただunC0Rr察戊がわからない自分がラッキヌカりント +02:02=自分だけはラッキヌカりントはニモ察戊じゃないNemo +02:02=ただSmaxx察戊がわからない自分がラッキヌカりント +02:02=自分だけはラッキヌカりントはJessor察戊じゃない +02:02=それはあなたのすべおを䞎える +02:02=敗者は、クリヌニングを行う +02:02=ミレニアムの戊いを始めたしょう +02:02=䞖玀の戊いを始めたしょう +02:02=十幎の戊いを始めたしょう +02:02=今幎の戊いを始めたしょう +02:02=月の戊いを始めたしょう +02:02=週の戊いを始めたしょう +02:02=䞀日の戊いを始めたしょう +02:02=時間の戊いを始めたしょう +02:02=あなたのベストを尜くす +02:02=敵を砎壊する +02:02=幞運 +02:02=楜しむ +02:02=善戊する +02:02=汚れず戊う +02:02=名誉ず戊う +02:02=あきらめおはいけない +02:02=決しお降䌏しない +02:02=岩ず靎䞋を +02:02=を始めたしょう +02:02=私はあなたの闘争のために準備が敎いたしたね +02:02=ゎヌゎヌに行く +02:02=ハリネズミ事前に +02:02=圌らにそれをもたらす +02:02=恐れを持っおいたせん +02:02=勇気をだしお埁服される + ; Round ends (win; unused atm) 02:03=... + ; Round ends (draw; unused atm) 02:04=... + ; New health crate 02:05=救揎物資が入っお来る 02:05=医者の指瀺を聞いおね。 02:05=倩䞎救急箱でございたす +02:05=着信揎助 +02:05=メディック +02:05=空から応急凊眮 +02:05=あなたのための健康パック +02:05=良奜な健康状態...ボックスの圢で +02:05=医垫を呌び出したす +02:05=新鮮なバンド゚むド +02:05=これは、良い感じになりたす +02:05=ハむポヌション間違ったゲヌムおっ +02:05=ピックミヌアップ +02:05=それを぀かむ +02:05=健康的なスナック +02:05=痛みの治療法 +02:05=正しい甚量あなたが芋぀けるこずができる限り倚くの +02:05=緊急配信 +02:05=電源 + ; New ammo crate 02:06=もっず火力だ 02:06=なかになにかな 02:06=パワヌアップ +02:06=より倚くの歊噚 +02:06=揎軍を +02:06=ロックず負荷 +02:06=私は歊噚がそこにあるものだろうか +02:06=電源 +02:06=䜕が内郚だろうか +02:06=クリスマスは、早期Hedgewars入っおくる +02:06=プレれント +02:06=特別配信 +02:06=それは、皎関を介しおこれを取埗する悪倢だった +02:06=倩からの砎壊的なおもちゃ +02:06=譊告揮発性の内容 +02:06=それを拟うか、たたはそれを爆砎する、遞択はあなた次第です +02:06=グッディヌズ +02:06=の匟薬 +02:06=砎壊力のボックス +02:06=航空䟿 +02:06=そのボックスにあるにせよ、それはピザではありたせん +02:06=それを入手 +02:06=歊噚のドロップの着信 +02:06=敵がいるこずを぀かむこずはできたせん +02:06=光沢のある新しいおもちゃ +02:06=神秘的なボックス + ; New utility crate 02:07=必芁かもしれない  02:07=これいいでしょう 02:07=おっず、重い箱これ +02:07=ツヌルの時間 +02:07=これは䟿利になるこずができたした... +02:07=ナヌティリティ +02:07=このボックスをナヌティリティ +02:07=䞋に気を付けろ +02:07=倚くのナヌティリティ +02:07=あなたのためのツヌル +02:07=これは良いはずです +02:07=この賢明を䜿甚したす。 +02:07=このボックスは重いです +02:07=あなたはこれを必芁があるかもしれたせん + ; Hog (%1) skips his turn 02:08=%1 は党く぀たらない。 02:08=%1 は座犅したいもの 02:08=寝ちゃったの、%1 +02:08=%1はすっごく退屈だ... +02:08=%1は気にするこずができたせんでした +02:08=%1は怠惰な豚です。 +02:08=%1は軜率です。 +02:08=%1はあきらめた +02:08=あなたは、あなたが倱う%1を居眠り +02:08=%1臆面もなくスキップしたす +02:08=%1は本圓に怠け者です。 +02:08=%1はもう少しモチベヌションが必芁です +02:08=%1は平和です。 +02:08=%1は息抜きを持っおいる +02:08=%1は残りを持っおいる +02:08=%1の悪寒より +02:08=%1は自分の胜力には信仰を持っおいたせん +02:08=%1は、たったく䜕もしないこずを決定 +02:08=%1は敵が自分自身を砎壊するこずができたす +02:08=%1はパヌティヌでひどいだろう +02:08=%1を隠しお +02:08=%1はこの機䌚に合栌するこずを決定したした +02:08=%1は、圌ができる最善のこずはありたせん...䜕も決定 +02:08=%1は倧きい匱虫です。 +02:08=バックコッコッ、%1はチキンです。 +02:08=%1は少し黄色を探しおいたす +02:08=%1は臆病者だ +02:08=%1は突然死を埅っおいたす +02:08=%1は戊闘型ではありたせん。 +02:08=%1は圌の人生の目的を再考されおい +02:08=%1がずにかく良いショットの倚くはなかった +02:08=%1は最初の堎所に軍隊に参加したくありたせんでした +02:08=%1を私たちの時間を無駄に停止する +02:08=私は、%1、あなたにがっかりしおい +02:08=さあ、あなたはその%1よりも優れお行うこずができたす +02:08=%1の壊れおいたす。 +02:08=%1は明らかに行うには良いこずをしおい +02:08=%1は堅いおびえおいる +02:08=%1が眠っおいる + ; Hog (%1) hurts himself only - see en.txt for examples 02:09=もちろん、%1 がわざずしたねw ; The real saying has けっおん = shortcoming, whereas おっけん = clenched fist 02:09=倧䞈倫 %1、だれにでも おっけん はある +02:09=%1を目指しお緎習しおください +02:09=%1は自分自身を憎むように芋える +02:09=%1は間違った偎に立っおいる +02:09=%1ぱモのようになりたす +02:09=%1のたわりで圌の歊噚間違った方法を持っおいた +02:09=%1は少しサディスティックです。 +02:09=%1はマゟです。 +02:09=%1は自己保存の本胜にはありたせん +02:09=%1が台無しに +02:09=%1が台無しに +02:09=それは悪いショット、%1であった +02:09=%1は危険な歊噚を少し䜙りに軜率です。 +02:09=%1は、キャリアの倉化を考慮する必芁がありたす +02:09=最悪。撮圱した。 +02:09=いいえいいえいいえ%1には、敵に撃぀ん +02:09=%1は唯䞀の敵を砎壊する必芁がありたす +02:09=%1は自殺に䞀歩近づく +02:09=%1は敵を助ける +02:09=それは%1愚かであった +02:09=痛みなくしお埗るものなしのスロヌガンで%1の呜を +02:09=%1が混乱しおいる +02:09=%1は、その混乱の䞭で自分自身を傷぀ける +02:09=%1は、自分自身を恥ずかしいの才芚を持っおいる +02:09=%1は䞍噚甚です +02:09=%1は䞍噚甚です。 +02:09=%1は圌の胜力䜕敵を瀺しおいたす。 +02:09=%1はすべおの時間を完璧なものに期埅するこずはできたせん +02:09=%1、のを心配する必芁はありたせん +02:09=%1は完党に意図的にそれをしたした +02:09=そうでない堎合、私は、%1を誰にも蚀われたせん +02:09=どのように恥ずかしい +02:09=私は誰もその%1を芋たこずが確信しおいる +02:09=%1は圌の分野のマニュアルを確認する必芁がありたす +02:09=%1の歊噚は明らかに故障 + ; Hog shot an home run (using the bat and another hog) 02:10=ホヌムラン! 02:10=鳥、飛行機 いや、%1だ +02:10=が出おいるこずを + ; Hog (%1) has to leave (team is gone) 02:11=%1 は出かけなければ  02:11=%1 はちょっず甚がある +02:11=ビヌム圌のアップ、スコッティ +02:11=%1ベッドに移動しおいたす +02:11=%1行かなければならない + +; Weapon Categories +03:00=時限グレネヌド +03:01=時限グレネヌド +03:02=匟道兵噚 +03:03=誘導兵噚 +03:04=銃耇数枚 +03:05=掘削ツヌル +03:06=アクション +03:07=トランスポヌトナヌティリティ +03:08=近接爆匟 +03:09=銃耇数枚 +03:10=BOOM +03:11=ボンク +03:12=æ­Šè¡“ +03:13=UNUSED +03:14=トランスポヌトナヌティリティ +03:15=空䞭攻撃 +03:16=空䞭攻撃 +03:17=掘削ツヌル +03:18=ナヌティリティ +03:19=トランスポヌトナヌティリティ +03:20=アクション +03:21=匟道兵噚 +03:22=私むンディアナ呌ぶ +03:23=本圓にマヌシャルアヌツ +03:24=ケヌキは嘘ではありたせん +03:25=衣装キット +03:26=ゞュヌシヌなグレネヌド +03:27=燃えるようなグレネヌド +03:28=匟道兵噚 +03:29=匟道兵噚 +03:30=空䞭攻撃 +03:31=リモコン爆匟 +03:32=䞀時的効果 +03:33=䞀時的効果 +03:34=䞀時的効果 +03:35=䞀時的効果 +03:36=䞀時的効果 +03:37=䞀時的効果 +03:38=銃耇数枚 +03:39=トランスポヌトナヌティリティ +03:40=グレネヌドを焌华 +03:41=の倧ファン +03:42=私はここに泚意しお䜜っおいるんだ... +; the misspelled "Beethoven" is intentional (-> to beat) +03:43=の臎呜的な゜ナタを実行する +03:44=最高の前1923 +03:45=科孊の力 +03:46=ホットホットホット +03:47=これらはどこかに䟿利なスティック +03:48=それはハンマヌ時間です +03:49=あなたが掚枬するかしない +03:50=モルファン +03:51=地䞊で発芋 +03:52=UNUSED +03:53=タむプ40 +03:54=䜕かを構築 +03:55=ナヌティリティ + +; Weapon Descriptions (use | as line breaks) +04:00=シンプルな手抎匟を䜿っお敵を攻撃。そのタむマヌがれロに達するずそれが爆発する。1-5セットグレネヌドのタむマヌ攻撃より倚くの電力をスロヌするようにホヌルド +04:01=クラスタヌ爆匟を䜿甚しお敵を攻撃。そのタむマヌがれロに達するず、それは小さな爆匟に分割されたす。1-5セットグレネヌドのタむマヌ攻撃より倚くの電力をスロヌするようにホヌルド +04:02=颚に圱響されるかもしれない匟道発射䜓を䜿甚しお敵を攻撃。攻撃より倚くの電力を䜿っお撮圱するホヌルド +04:03=遞択したタヌゲットにロックされ爆発的な蜂を起動したす。その粟床を向䞊させるためにフルパワヌを䜿っお撮圱しないでください。カヌ゜ルピックタヌゲット攻撃より倚くの電力を䜿っお撮圱するホヌルド +04:04=2ショットでショットガンを䜿っお敵を攻撃する。その広がりあなたのおかげで、あなたの察戊盞手に危害を盎接ヒットする必芁はありたせん。攻撃シュヌト耇数回 +04:05=地䞋に移動地面に穎を開けるず他の領域に到達するを䜿甚しおいたす。攻撃の開始たたは停止掘り +04:06=退屈攻撃する方法はありたせんあなたの匟薬を保存したすか問題ありたせんちょうどあなたのタヌン、臆病者をスキップしお攻撃戊闘せずにタヌンをスキップ +04:07=ロヌプでタむムアりトショットを䜿甚しお、巚倧な距離を埋める。他の豚たたはドロップ手抎匟およびそれらの他の歊噚にスラむドするように勢いを䜿甚しおいたす。攻撃ドロップ手抎匟たたは類䌌の歊噚ロヌプロングゞャンプシュヌトたたは解攟 +04:08=狭い通路の右たたはそれらの足の䞋鉱山をドロップするこずで、離れおあなたの敵を保぀。あなた自身でそれをトリガする前に撀退しおください攻撃あなたの足の隣に地雷を削陀したす。 +04:09=あなたの照準が分からない4打差たでを䜿甚しお攻撃するためにデザヌトむヌグルを䜿甚しおいたす。攻撃シュヌト耇数回 +04:10=ブルヌトフォヌスは垞にオプションです。あなたの敵ず埌退の隣にあるこの叀兞的な爆発物をドロップしたす。攻撃あなたの足の隣にあるドロップダむナマむト +04:11=マップの囜境を越えおたたは氎の䞭にそれらをバッティングしお敵の豚を取り陀く。たたはどのようにお友達にいく぀かの鉱山をノックでしょうか攻撃あなたの前にバットすべおを +04:12=このほずんど臎呜的な歊道技術の力を解き攟぀に近いず個人的な取埗したす。攻撃玠晎らしいを実行したす。 +04:13=UNUSED +04:14=高所恐怖症優れたパラシュヌトを぀かむ。それはあなたが遠すぎたら萜ちる展開ず秋のダメヌゞを受けおから豚を保存したす。攻撃ドロップ手抎匟たたは類䌌の歊噚パラシュヌトロングゞャンプを䌞ばし +04:15=爆撃の実行を䜿甚しお敵を攻撃する飛行機の䞭で呌び出したす。巊右遞択しおタヌゲット領域攻撃方向のカヌ゜ルを決定 +04:16=タヌゲット゚リアにいく぀かの鉱山をドロップするには飛行機の䞭で呌び出したす。巊右遞択しおタヌゲット領域攻撃方向のカヌ゜ルを決定 +04:17=避難が必芁ですかあなたがカバヌ付䞎固䜓地面にトンネルを掘るためにブロヌトヌチを䜿甚しおいたす。攻撃の開始たたは停止掘り +04:18=远加の保護が必芁な堎合、たたは地面を通過したいですか奜きなように、いく぀かの桁に眮きたす。有効な䜍眮に配眮桁巊右カヌ゜ルを配眮する遞択桁 +04:19=それはあなたが数秒以内に危険な状況から豚を保存するこずができたすように、右瞬間テレポヌテヌションで䜿甚するほがすべおの歊噚をより匷力にするこずができたす。カヌ゜ル遞択しおタヌゲット領域 +04:20=別の豚ず、珟圚のタヌンを再生するこずができたす。攻撃スむッチング豚を有効にする +04:21=むンパクト時に耇数の爆匟を解攟したす手抎匟のような匟䞞を撃぀。攻撃フルパワヌで撃぀ +04:22=だけでなく、むンディゞョヌンズのために鞭は倚くの状況で有甚な歊噚である。あなたが厖から誰かを突き出すしたい堎合は特に。攻撃あなたの前にストラむクのすべお +04:23=あなたが倱うものは䜕もない堎合、これはかなり䟿利かもしれたせん。圌の方法䞊のすべおを傷぀けるず終了時に爆発し、特定の方向に圌を起動するこずで、豚を生け莄に捧げる。攻撃壊滅的な、臎呜的な攻撃を開始 +04:24=誕生日おめでずうこのケヌキを起動し、それが右の敵の隣に歩いお、圌らが爆発的パヌティを持たせおみたしょう。ケヌキは、ほがすべおの地圢を通過するこずができたすが、圌は以前、この方法を爆発させるかもしれたせん。攻撃ケヌキを起動するか、停止させるず爆発する +04:25=そしお、いく぀かのギャップや穎が豚に向かっおゞャンプするこずがあなたの敵を取埗するには、この倉装キットを䜿甚しおいたす。攻撃キットを䜿甚しお、別の豚を誘惑しよう +04:26=あなたの敵で、このゞュヌシヌなスむカをスロヌしたす。タむマヌの期限が切れるず、それはいく぀かの爆発的な断片に分割されたす。1-5セットスむカのタむマヌ攻撃より倚くの電力を䜿っお撮圱するホヌルド +04:27=この悪魔のよう爆発を䜿甚しお、あなたの察戊盞手に業火の雚しおみたしょう。近すぎる小さな火灜が長く続くかもしれないず爆発に埗るこずはありたせん。攻撃より倚くの電力を䜿っお撮圱するホヌルド +04:28=このロケットを打ち䞊げた埌の短い時間、それは固䜓地面を掘削を開始し、そのヒュヌズがトリガされるず爆発するか、再び再浮䞊したす。攻撃より倚くの電力を䜿っお撮圱するホヌルド +04:29=これは小さな子䟛のためのものではありたせんボヌル銃は爆薬を充填した小さな色のボヌルのトンを発生させたす。攻撃アップダりン、フルパワヌでシュヌトを目指しお進みたす +04:30=匷力なナパヌムストラむキを起動するには飛行機の䞭で呌び出したす。適切にこの攻撃を目指しおそこに座っお䞍運な豚を含む颚景の巚倧な郚分を根絶するこずができたす。巊右遞択しおタヌゲット領域攻撃方向のカヌ゜ルを決定 +04:31=RCプレヌンは箱を収集したり、遠く離れた豚を攻撃するのに理想的な歊噚です。どちらの敵にそれを操瞊するか、最初のいく぀かの爆匟をドロップしたす。攻撃ワルキュヌレが戊闘に乗りたしょう巊右平面ステアゞャンプ平面たたはドロップロング爆匟を起動したす。 +04:32=䜎重力はどんなダむ゚ットよりも効果的です高く、長い距離を飛び越えたり、敵がさらに飛ぶしたしょう。攻撃アクティブ +04:33=時には、いく぀かのより倚くのダメヌゞを䞎えるためにその少し䜙分なブヌストをちょうど必芁がありたす。攻撃アクティブ +04:34=私に觊れるこずができない攻撃アクティブ +04:35=時には時間が早すぎる実行しおいる。あなたの攻撃を完了するために、いく぀かの䜙分な秒を぀かむ。攻撃アクティブ +04:36=さお、時にはあなたが目指すのはあたりにも悪いです。珟代の技術を䜿甚しおいく぀かの支揎を埗る。攻撃アクティブ +04:37=日光を恐れおはいけたせん。それはちょうど1タヌン持続したすが、あなたが他の豚に䜕のダメヌゞを吞収するこずができるようになりたす。攻撃アクティブ +04:38=スナむパヌラむフルは、あなたの党䜓の兵噚庫の䞭で最も壊滅的な歊噚になりたす、しかし、それは接近戊で非垞に効果的です。ダメヌゞは、そのタヌゲットたでの距離ずずもに増加を䞎えた。攻撃シュヌト回 +04:39=空飛ぶ円盀を䜿甚しおマップの他の郚分に飛ぶ。これは、マスタヌナヌティリティのハヌド戊堎のほが任意の䜍眮に行くこずができるようになりたした。攻撃最倧アクティブ巊右ドロップ手抎匟たたは類䌌の歊噚䞀方向にロングゞャンプ力を適甚したす。 +04:40=すぐになる、燃焌液で満たされたこのボトルを䜿甚しお、火灜のいく぀かの地を蚭定したす。攻撃より倚くの電力を䜿っお撮圱するホヌルド +04:41=蚌拠の性質も、空飛ぶ円盀を䞊回るかもしれたせん。バヌディは、豚を持ち歩くずあなたの敵に卵をドロップするこずができたすバヌディヌを䜿甚するず、あなたのタヌンの時間に食べるように、迅速である攻撃およびドロップ卵アップ巊右䞀方向にフラップ +04:42=この携垯ポヌタル装眮は、瞬時に、あなたの敵、たたは地圢䞊の2点間のあなたの歊噚あなたを茞送するこずが可胜です。賢明にそれを䜿甚しお、キャンペヌンがありたす...倧成功攻撃サむクルポヌタルの色ポヌタルスむッチを撃぀ +04:43=あなたの音楜デビュヌ爆発を成功させる倩からピアノをドロップしたすが、泚意しおください...誰かがそれを再生する必芁があり、それはあなたの人生を芁するかもしれないカヌ゜ル遞択しおタヌゲット領域F1-F9キヌを抌しおピアノを匟く +04:44=これはただのチヌズではなく、生物兵噚だタむマヌがれロに達するず、それは間違いなく臭いをタッチする誰もが䞍幞に毒されたら、それは被害の膚倧な量が発生するこずはありたせん1-5セットグレネヌドのタむマヌ攻撃より倚くの電力をスロヌするようにホヌルド +04:45=すべおのそれらの物理孊のクラスは最終的に報われおいる、あなたの敵に壊滅的な正匊波を起動したす。気を付けろ、この歊噚は非垞にキックをパックしたす。この歊噚は䞍完党です攻撃力シュヌト +04:46=液䜓炎を非垞に暑いずあなたの敵をカバヌしおいたす。ほのがのアタックを䞊䞋にアクティブにしたす。巊右を目指しお進みたす唟の電源を倉曎したす。 +04:47=2先端のずがった、卑劣な、粘着地雷の楜しみを倍増。連鎖反応を蚭定するかあるいは䞡方攻撃を守るより倚くの電力倍で撮圱するホヌルド +04:48=なぜモルすべおの虐埅を取埗する必芁がありたす豚をは、単に楜しみずしおするこずができたすこのハンマヌから良い打撃は豚の健康状態の3分の1をオフに剃るし、それらを地䞋に突入したす。攻撃アクティブ +04:49=あなたの友人を埩掻させるしかし、これはたたあなたの敵を埩掻させるこず泚意しおください。攻撃ゆっくりず埩掻させるために抌された攻撃に泚意しおください。埩掻を加速 +04:50=誰かが地䞋に隠れおいるドリルのストラむキでそれらを掘るタむマヌは、それを掘る方法をはるかに制埡したす。 +04:51=泥のボヌルを投げ぀けるこずによっお自由なショットで取埗したす。刺されは、ビット、豚をバックノックする。 +04:52=UNUSED +04:53=あなたの仲間が単独で戊うために残しながら、時間ず空間を介しお冒険に出る。い぀でも返すように準備する、たたは突然死の堎合、たたは、それらはすべお敗北しおいたす。免責事項。あなたは䞀人である堎合は、突然死で機胜するか、キングである堎合ではありたせん。 +04:54=INCOMPLETE +04:55=スティッキヌフレヌクのストリヌムをスプレヌ。トンネルを封鎖、敵を埋める、ブリッゞを構築したす。あなたが䞊の任意のを取埗しないように泚意しおください + +; Game goal strings +05:00=ゲヌムモヌド +05:01=次の芏則が適甚されたす +05:02=砊あなたの芁塞を守り、敵を打ち負かす +05:03=䜎重力足元に気を぀けお +05:04=䞍死身豚は䞍死身ほがです。 +05:05=吞血鬌豚は、ダメヌゞのために癒される +05:06=カルマ豚は、ダメヌゞのために砎損したす。 +05:07=キングを保護するあなたの王が死んではいけない|堎所キングあなたの王のために保護された出発点をピック +05:08=堎所のハリネズミゲヌムが起動する前に、豚を眮きたす +05:09=砲兵豚の䜍眮を倉曎するには、歩くこずができない +05:10=䞍滅の地圢ほずんどの歊噚は地圢を砎壊するこずはありたせん +05:11=共有匟薬同じ色のすべおのチヌムが圌らの匟薬を共有する +05:12=鉱山タむマヌ鉱山は、%1秒埌を爆発したす。 +05:13=鉱山タむマ鉱山は即座に爆発したす。 +05:14=鉱山タむマ鉱山は0の埌に爆発したす。 0- 5秒 +05:15=ダメヌゞ修正すべおの歊噚は、%1のダメヌゞを行いたす +05:16=すべおの豚の健康状態はタヌン終了時にリセットされたす。 +05:17=死の豚のリスポヌン +05:18=無限の攻撃 +05:19=歊噚はタヌン終了時にリセットされたす。 +05:20=歊噚は豚の間で共有されおいたせん +05:21=タグチヌム䞀族のチヌムは、連続タヌンを取る|共有時間䞀族の株のタヌン時間内にチヌム diff -r 9e724f4863a3 -r 6af78154dc62 share/hedgewars/Data/Maps/CMakeLists.txt diff -r 9e724f4863a3 -r 6af78154dc62 share/hedgewars/Data/Maps/Islands/map.png Binary file share/hedgewars/Data/Maps/Islands/map.png has changed diff -r 9e724f4863a3 -r 6af78154dc62 share/hedgewars/Data/Maps/Sticks/map.cfg diff -r 9e724f4863a3 -r 6af78154dc62 share/hedgewars/Data/Maps/Sticks/preview@2x.png diff -r 9e724f4863a3 -r 6af78154dc62 share/hedgewars/Data/Maps/Trash/map.cfg --- a/share/hedgewars/Data/Maps/Trash/map.cfg Sun Apr 01 15:23:34 2012 +0200 +++ b/share/hedgewars/Data/Maps/Trash/map.cfg Wed May 02 23:53:45 2012 +0200 @@ -1,1 +1,1 @@ -Nature \ No newline at end of file +Compost diff -r 9e724f4863a3 -r 6af78154dc62 share/hedgewars/Data/Music/Golf.ogg Binary file share/hedgewars/Data/Music/Golf.ogg has changed diff -r 9e724f4863a3 -r 6af78154dc62 share/hedgewars/Data/Music/Nature.ogg Binary file share/hedgewars/Data/Music/Nature.ogg has changed diff -r 9e724f4863a3 -r 6af78154dc62 tools/PascalBasics.hs --- a/tools/PascalBasics.hs Sun Apr 01 15:23:34 2012 +0200 +++ b/tools/PascalBasics.hs Wed May 02 23:53:45 2012 +0200 @@ -8,7 +8,7 @@ import Text.Parsec.Language import Data.Char -builtin = ["succ", "pred", "low", "high", "ord"] +builtin = ["succ", "pred", "low", "high", "ord", "inc", "dec", "exit"] pascalLanguageDef = emptyDef diff -r 9e724f4863a3 -r 6af78154dc62 tools/PascalParser.hs --- a/tools/PascalParser.hs Sun Apr 01 15:23:34 2012 +0200 +++ b/tools/PascalParser.hs Wed May 02 23:53:45 2012 +0200 @@ -14,7 +14,7 @@ import PascalBasics import PascalUnitSyntaxTree -knownTypes = ["shortstring", "char", "byte"] +knownTypes = ["shortstring", "ansistring", "char", "byte"] pascalUnit = do comments @@ -113,12 +113,13 @@ comments e <- initExpression comments - return $ VarDeclaration False ([i], fromMaybe (DeriveType e) t) (Just e) + return $ VarDeclaration (isNothing t) ([i], fromMaybe (DeriveType e) t) (Just e) typeDecl = choice [ char '^' >> typeDecl >>= return . PointerTo , try (string "shortstring") >> return (String 255) , try (string "string") >> optionMaybe (brackets pas $ integer pas) >>= return . String . fromMaybe 255 + , try (string "ansistring") >> optionMaybe (brackets pas $ integer pas) >>= return . String . fromMaybe 255 , arrayDecl , recordDecl , setDecl @@ -407,6 +408,7 @@ , withBlock , forCycle , (try $ reference >>= \r -> string ":=" >> return r) >>= \r -> expression >>= return . Assignment r + , builtInFunction expression >>= \(n, e) -> return $ BuiltInFunctionCall e (SimpleReference (Identifier n BTUnknown)) , procCall , char ';' >> comments >> return NOP ] @@ -581,8 +583,8 @@ , Infix (try $ string "or" >> return (InitBinOp "or")) AssocLeft , Infix (try $ string "xor" >> return (InitBinOp "xor")) AssocLeft ] - , [ Infix (try $ string "shl" >> return (InitBinOp "and")) AssocNone - , Infix (try $ string "shr" >> return (InitBinOp "or")) AssocNone + , [ Infix (try $ string "shl" >> return (InitBinOp "shl")) AssocNone + , Infix (try $ string "shr" >> return (InitBinOp "shr")) AssocNone ] , [Prefix (try (string "not") >> return (InitPrefixOp "not"))] ] @@ -596,7 +598,7 @@ builtInFunction e = do name <- choice $ map (\s -> try $ caseInsensitiveString s >>= \i -> notFollowedBy alphaNum >> return i) builtin spaces - exprs <- parens pas $ commaSep1 pas $ e + exprs <- option [] $ parens pas $ option [] $ commaSep1 pas $ e spaces return (name, exprs) diff -r 9e724f4863a3 -r 6af78154dc62 tools/PascalPreprocessor.hs --- a/tools/PascalPreprocessor.hs Sun Apr 01 15:23:34 2012 +0200 +++ b/tools/PascalPreprocessor.hs Wed May 02 23:53:45 2012 +0200 @@ -15,7 +15,7 @@ , (try $ string "//") >> manyTill anyChar (try newline) >> return "\n" ] -initDefines = Map.fromList [("FPC", "")] +initDefines = Map.fromList [("FPC", ""), ("PAS2C", "")] preprocess :: String -> IO String preprocess fn = do @@ -74,7 +74,7 @@ char '"' spaces char '}' - f <- liftIO (readFile fn) + f <- liftIO (readFile fn `catch` error ("File not found: " ++ fn)) c <- getInput setInput $ f ++ c return "" diff -r 9e724f4863a3 -r 6af78154dc62 tools/PascalUnitSyntaxTree.hs --- a/tools/PascalUnitSyntaxTree.hs Sun Apr 01 15:23:34 2012 +0200 +++ b/tools/PascalUnitSyntaxTree.hs Wed May 02 23:53:45 2012 +0200 @@ -32,10 +32,10 @@ | FunctionType TypeDecl [TypeVarDeclaration] | DeriveType InitExpression | VoidType - | UnknownType deriving Show data Range = Range Identifier | RangeFromTo InitExpression InitExpression + | RangeInfinite deriving Show data Initialize = Initialize String deriving Show @@ -52,6 +52,7 @@ | Phrases [Phrase] | SwitchCase Expression [([InitExpression], Phrase)] (Maybe [Phrase]) | Assignment Reference Expression + | BuiltInFunctionCall [Expression] Reference | NOP deriving Show data Expression = Expression String @@ -103,8 +104,9 @@ | BTBool | BTFloat | BTRecord [(String, BaseType)] - | BTArray BaseType BaseType + | BTArray Range BaseType BaseType | BTFunction BaseType + | BTFunctionReturn String BaseType | BTPointerTo BaseType | BTUnresolved String | BTSet BaseType diff -r 9e724f4863a3 -r 6af78154dc62 tools/pas2c.hs --- a/tools/pas2c.hs Sun Apr 01 15:23:34 2012 +0200 +++ b/tools/pas2c.hs Wed May 02 23:53:45 2012 +0200 @@ -1,3 +1,4 @@ +{-# LANGUAGE ScopedTypeVariables #-} module Pas2C where import Text.PrettyPrint.HughesPJ @@ -13,6 +14,7 @@ import System.IO.Error import qualified Data.Map as Map import Data.List (find) +import Numeric import PascalParser import PascalUnitSyntaxTree @@ -29,10 +31,47 @@ currentScope :: [Record], lastIdentifier :: String, lastType :: BaseType, + stringConsts :: [(String, String)], + uniqCounter :: Int, namespaces :: Map.Map String [Record] } -emptyState = RenderState [] "" BTUnknown +emptyState = RenderState [] "" BTUnknown [] 0 + +getUniq :: State RenderState Int +getUniq = do + i <- gets uniqCounter + modify(\s -> s{uniqCounter = uniqCounter s + 1}) + return i + +addStringConst :: String -> State RenderState Doc +addStringConst str = do + strs <- gets stringConsts + let a = find ((==) str . snd) strs + if isJust a then + do + modify (\s -> s{lastType = BTString}) + return . text . fst . fromJust $ a + else + do + i <- getUniq + let sn = "__str" ++ show i + modify (\s -> s{lastType = BTString, stringConsts = (sn, str) : strs}) + return $ text sn + +escapeStr :: String -> String +escapeStr = foldr escapeChar [] + +escapeChar :: Char -> ShowS +escapeChar '"' s = "\\\"" ++ s +escapeChar a s = a : s + +strInit :: String -> Doc +strInit a = text "STRINIT" <> parens (doubleQuotes (text $ escapeStr a)) + +renderStringConsts :: State RenderState Doc +renderStringConsts = liftM (vcat . map (\(a, b) -> text "const string255" <+> (text a) <+> text "=" <+> strInit b <> semi)) + $ gets stringConsts docToLower :: Doc -> Doc docToLower = text . map toLower . render @@ -76,6 +115,8 @@ renderCFiles units = do let u = Map.toList units let nss = Map.map (toNamespace nss) units + hPutStrLn stderr $ "Units: " ++ (show . Map.keys . Map.filter (not . null) $ nss) + --writeFile "pas2c.log" $ unlines . map (\t -> show (fst t) ++ "\n" ++ (unlines . map ((:) '\t' . show) . snd $ t)) . Map.toList $ nss mapM_ (toCFiles nss) u where toNamespace :: Map.Map String [Record] -> PascalUnit -> [Record] @@ -86,10 +127,16 @@ currentScope $ execState (interface2C interface) (emptyState nss) -withState' :: (a -> a) -> State a b -> State a b -withState' f s = do +withState' :: (RenderState -> RenderState) -> State RenderState a -> State RenderState a +withState' f sf = do st <- liftM f get - return $ evalState s st + let (a, s) = runState sf st + modify(\st -> st{ + lastType = lastType s + , uniqCounter = uniqCounter s + , stringConsts = stringConsts s + }) + return a withLastIdNamespace :: State RenderState Doc -> State RenderState Doc withLastIdNamespace f = do @@ -97,11 +144,12 @@ nss <- gets namespaces withState' (\st -> st{currentScope = fromMaybe [] $ Map.lookup li (namespaces st)}) f -withRecordNamespace :: [(String, BaseType)] -> State RenderState Doc -> State RenderState Doc -withRecordNamespace recs = withState' f +withRecordNamespace :: String -> [(String, BaseType)] -> State RenderState Doc -> State RenderState Doc +withRecordNamespace _ [] = error "withRecordNamespace: empty record" +withRecordNamespace prefix recs = withState' f where f st = st{currentScope = records ++ currentScope st} - records = map (\(a, b) -> (map toLower a, (a, b))) recs + records = map (\(a, b) -> (map toLower a, (prefix ++ a, b))) recs toCFiles :: Map.Map String [Record] -> (String, PascalUnit) -> IO () toCFiles _ (_, System _) = return () @@ -110,14 +158,14 @@ toCFiles' p where toCFiles' (fn, p@(Program {})) = writeFile (fn ++ ".c") $ (render2C initialState . pascal2C) p - toCFiles' (fn, (Unit _ interface implementation _ _)) = do - let (a, s) = runState (interface2C interface) initialState - writeFile (fn ++ ".h") $ "#pragma once\n" ++ (render a) - writeFile (fn ++ ".c") $ (render2C s . implementation2C) implementation + toCFiles' (fn, (Unit unitId interface implementation _ _)) = do + let (a, s) = runState (id2C IOInsert (setBaseType BTUnit unitId) >> interface2C interface) initialState + writeFile (fn ++ ".h") $ "#pragma once\n\n#include \"pas2c.h\"\n\n" ++ (render (a $+$ text "")) + writeFile (fn ++ ".c") $ "#include \"" ++ fn ++ ".h\"\n" ++ (render2C s . implementation2C) implementation initialState = emptyState ns render2C :: RenderState -> State RenderState Doc -> String - render2C a = render . flip evalState a + render2C a = render . ($+$ empty) . flip evalState a usesFiles :: PascalUnit -> [String] usesFiles (Program _ (Implementation uses _) _) = "pas2cSystem" : uses2List uses @@ -131,21 +179,29 @@ pascal2C (Program _ implementation mainFunction) = do impl <- implementation2C implementation - main <- tvar2C True + [main] <- tvar2C True (FunctionDeclaration (Identifier "main" BTInt) (SimpleType $ Identifier "int" BTInt) [] (Just (TypesAndVars [], mainFunction))) return $ impl $+$ main interface2C :: Interface -> State RenderState Doc -interface2C (Interface uses tvars) = liftM2 ($+$) (uses2C uses) (typesAndVars2C True tvars) - +interface2C (Interface uses tvars) = do + u <- uses2C uses + tv <- typesAndVars2C True tvars + r <- renderStringConsts + return (u $+$ r $+$ tv) + implementation2C :: Implementation -> State RenderState Doc -implementation2C (Implementation uses tvars) = liftM2 ($+$) (uses2C uses) (typesAndVars2C True tvars) +implementation2C (Implementation uses tvars) = do + u <- uses2C uses + tv <- typesAndVars2C True tvars + r <- renderStringConsts + return (u $+$ r $+$ tv) typesAndVars2C :: Bool -> TypesAndVars -> State RenderState Doc -typesAndVars2C b (TypesAndVars ts) = liftM vcat $ mapM (tvar2C b) ts +typesAndVars2C b (TypesAndVars ts) = liftM (vcat . map (<> semi) . concat) $ mapM (tvar2C b) ts setBaseType :: BaseType -> Identifier -> Identifier setBaseType bt (Identifier i _) = Identifier i bt @@ -158,7 +214,7 @@ where injectNamespace (Identifier i _) = do getNS <- gets (flip Map.lookup . namespaces) - let f = flip (foldl (\a b -> b:a)) (fromMaybe [] (getNS i)) + let f = flip (foldl (flip (:))) (fromMaybe [] (getNS i)) modify (\s -> s{currentScope = f $ currentScope s}) uses2List :: Uses -> [String] @@ -167,6 +223,12 @@ id2C :: InsertOption -> Identifier -> State RenderState Doc id2C IOInsert (Identifier i t) = do + ns <- gets currentScope +{-- case t of + BTUnknown -> do + ns <- gets currentScope + error $ "id2C IOInsert: type BTUnknown for " ++ show i ++ "\nnamespace: " ++ show (take 100 ns) + _ -> do --} modify (\s -> s{currentScope = (n, (i, t)) : currentScope s, lastIdentifier = n}) return $ text i where @@ -175,16 +237,15 @@ let i' = map toLower i v <- gets $ find (\(a, _) -> a == i') . currentScope ns <- gets currentScope + lt <- gets lastType if isNothing v then - error $ "Not defined: '" ++ i' ++ "'\n" -- ++ show ns + error $ "Not defined: '" ++ i' ++ "'\n" ++ show lt ++ "\n" ++ show (take 100 ns) else let vv = snd $ fromJust v in modify (\s -> s{lastType = snd vv, lastIdentifier = fst vv}) >> (return . text . fst $ vv) id2C IODeferred (Identifier i t) = do let i' = map toLower i v <- gets $ find (\(a, _) -> a == i') . currentScope if (isNothing v) then - do - modify (\s -> s{currentScope = (i', (i, t)) : currentScope s}) return $ text i else return . text . fst . snd . fromJust $ v @@ -197,7 +258,8 @@ BTUnknown -> do ns <- gets currentScope error $ "id2CTyped: type BTUnknown for " ++ show i ++ "\ntype: " ++ show t ++ "\nnamespace: " ++ show (take 100 ns) - _ -> id2C IOInsert (Identifier i tb) + _ -> return () + id2C IOInsert (Identifier i tb) resolveType :: TypeDecl -> State RenderState BaseType @@ -221,8 +283,10 @@ where f :: TypeVarDeclaration -> State RenderState [(String, BaseType)] f (VarDeclaration _ (ids, td) _) = mapM (\(Identifier i _) -> liftM ((,) i) $ resolveType td) ids -resolveType (ArrayDecl (Just _) t) = liftM (BTArray BTInt) $ resolveType t -resolveType (ArrayDecl Nothing t) = liftM (BTArray BTInt) $ resolveType t +resolveType (ArrayDecl (Just i) t) = do + t' <- resolveType t + return $ BTArray i BTInt t' +resolveType (ArrayDecl Nothing t) = liftM (BTArray RangeInfinite BTInt) $ resolveType t resolveType (FunctionType t _) = liftM BTFunction $ resolveType t resolveType (DeriveType (InitHexNumber _)) = return BTInt resolveType (DeriveType (InitNumber _)) = return BTInt @@ -236,127 +300,249 @@ resolveType (String _) = return BTString resolveType VoidType = return BTVoid resolveType (Sequence ids) = return $ BTEnum $ map (\(Identifier i _) -> map toLower i) ids -resolveType (RangeType _) = return $ BTUnknown +resolveType (RangeType _) = return $ BTVoid resolveType (Set t) = liftM BTSet $ resolveType t ---resolveType UnknownType = return BTUnknown -resolveType a = error $ "resolveType: " ++ show a - + + +resolve :: String -> BaseType -> State RenderState BaseType +resolve s (BTUnresolved t) = do + v <- gets $ find (\(a, _) -> a == t) . currentScope + if isJust v then + resolve s . snd . snd . fromJust $ v + else + error $ "Unknown type " ++ show t ++ "\n" ++ s +resolve _ t = return t -fromPointer :: BaseType -> State RenderState BaseType -fromPointer (BTPointerTo t) = f t - where - f (BTUnresolved s) = do - v <- gets $ find (\(a, _) -> a == s) . currentScope - if isJust v then - f . snd . snd . fromJust $ v - else - error $ "Unknown type " ++ show t - f t = return t -fromPointer t = error $ "Dereferencing from non-pointer type " ++ show t +fromPointer :: String -> BaseType -> State RenderState BaseType +fromPointer s (BTPointerTo t) = resolve s t +fromPointer s (BTFunctionReturn _ (BTPointerTo t)) = resolve s t +fromPointer s t = do + ns <- gets currentScope + error $ "Dereferencing from non-pointer type " ++ show t ++ "\n" ++ s ++ "\n\n" ++ show (take 100 ns) + + +functionParams2C params = liftM (hcat . punctuate comma . concat) $ mapM (tvar2C False) params - -tvar2C :: Bool -> TypeVarDeclaration -> State RenderState Doc -tvar2C _ (FunctionDeclaration name returnType params Nothing) = do +fun2C :: Bool -> String -> TypeVarDeclaration -> State RenderState [Doc] +fun2C _ _ (FunctionDeclaration name returnType params Nothing) = do t <- type2C returnType - p <- withState' id $ liftM hcat $ mapM (tvar2C False) params - n <- id2C IOInsert name - return $ t <+> n <> parens p <> text ";" + t'<- gets lastType + p <- withState' id $ functionParams2C params + n <- id2C IOInsert $ setBaseType (BTFunction t') name + return [t empty <+> n <> parens p] -tvar2C True (FunctionDeclaration (Identifier i _) returnType params (Just (tvars, phrase))) = do +fun2C True rv (FunctionDeclaration name returnType params (Just (tvars, phrase))) = do + let res = docToLower $ text rv <> text "_result" t <- type2C returnType t'<- gets lastType - n <- id2C IOInsert (Identifier i (BTFunction t')) - (p, ph) <- withState' (\st -> st{currentScope = (lastIdentifier st, (lastIdentifier st ++ "_result", t')) : currentScope st}) $ do - p <- liftM hcat $ mapM (tvar2C False) params + n <- id2C IOInsert $ setBaseType (BTFunction t') name + (p, ph) <- withState' (\st -> st{currentScope = (map toLower rv, (render res, BTFunctionReturn (render n) t')) : currentScope st}) $ do + p <- functionParams2C params ph <- liftM2 ($+$) (typesAndVars2C False tvars) (phrase2C' phrase) return (p, ph) - let res = docToLower $ n <> text "_result" let phrasesBlock = case returnType of VoidType -> ph - _ -> t <+> res <> semi $+$ ph $+$ text "return" <+> res <> semi - return $ - t <+> n <> parens p + _ -> t empty <+> res <> semi $+$ ph $+$ text "return" <+> res <> semi + return [ + t empty <+> n <> parens p $+$ text "{" $+$ nest 4 phrasesBlock $+$ - text "}" + text "}"] where phrase2C' (Phrases p) = liftM vcat $ mapM phrase2C p phrase2C' p = phrase2C p -tvar2C False (FunctionDeclaration (Identifier name _) _ _ _) = error $ "nested functions not allowed: " ++ name +fun2C False _ (FunctionDeclaration (Identifier name _) _ _ _) = error $ "nested functions not allowed: " ++ name +fun2C _ tv _ = error $ "fun2C: I don't render " ++ show tv +tvar2C :: Bool -> TypeVarDeclaration -> State RenderState [Doc] +tvar2C b f@(FunctionDeclaration (Identifier name _) _ _ _) = + fun2C b name f tvar2C _ td@(TypeDeclaration i' t) = do i <- id2CTyped t i' - tp <- type2C t - return $ text "type" <+> i <+> tp <> semi + tp <- case t of + FunctionType {} -> type2C (PointerTo t) + _ -> type2C t + return [text "typedef" <+> tp i] tvar2C _ (VarDeclaration isConst (ids, t) mInitExpr) = do - t' <- type2C t - i <- mapM (id2CTyped t) ids + t' <- liftM (((if isConst then text "const" else empty) <+>) . ) $ type2C t ie <- initExpr mInitExpr - return $ if isConst then text "const" else empty - <+> t' - <+> (hsep . punctuate (char ',') $ i) - <+> ie - <> text ";" + lt <- gets lastType + case (isConst, lt, ids, mInitExpr) of + (True, BTInt, [i], Just _) -> do + i' <- id2CTyped t i + return [text "enum" <> braces (i' <+> ie)] + (True, BTFloat, [i], Just e) -> do + i' <- id2CTyped t i + ie <- initExpr2C e + return [text "#define" <+> i' <+> parens ie <> text "\n"] + _ -> liftM (map(\i -> t' i <+> ie)) $ mapM (id2CTyped t) ids where initExpr Nothing = return $ empty initExpr (Just e) = liftM (text "=" <+>) (initExpr2C e) -tvar2C f (OperatorDeclaration op i ret params body) = - tvar2C f (FunctionDeclaration i ret params body) +tvar2C f (OperatorDeclaration op (Identifier i _) ret params body) = do + r <- op2CTyped op (extractTypes params) + fun2C f i (FunctionDeclaration r ret params body) +op2CTyped :: String -> [TypeDecl] -> State RenderState Identifier +op2CTyped op t = do + t' <- liftM (render . hcat . punctuate (char '_') . map (\t -> t empty)) $ mapM type2C t + bt <- gets lastType + return $ case bt of + BTRecord {} -> Identifier (t' ++ "_op_" ++ opStr) bt + _ -> Identifier t' bt + where + opStr = case op of + "+" -> "add" + "-" -> "sub" + "*" -> "mul" + "/" -> "div" + "=" -> "eq" + "<" -> "lt" + ">" -> "gt" + _ -> error $ "op2CTyped: unknown op '" ++ op ++ "'" + +extractTypes :: [TypeVarDeclaration] -> [TypeDecl] +extractTypes = concatMap f + where + f (VarDeclaration _ (ids, t) _) = replicate (length ids) t + f a = error $ "extractTypes: can't extract from " ++ show a + initExpr2C :: InitExpression -> State RenderState Doc +initExpr2C InitNull = return $ text "NULL" +initExpr2C (InitAddress expr) = liftM ((<>) (text "&")) (initExpr2C expr) +initExpr2C (InitPrefixOp op expr) = liftM (text (op2C op) <>) (initExpr2C expr) initExpr2C (InitBinOp op expr1 expr2) = do e1 <- initExpr2C expr1 e2 <- initExpr2C expr2 - o <- op2C op - return $ parens $ e1 <+> o <+> e2 + return $ parens $ e1 <+> text (op2C op) <+> e2 initExpr2C (InitNumber s) = return $ text s initExpr2C (InitFloat s) = return $ text s initExpr2C (InitHexNumber s) = return $ text "0x" <> (text . map toLower $ s) -initExpr2C (InitString s) = return $ doubleQuotes $ text s +initExpr2C (InitString [a]) = return . quotes $ text [a] +initExpr2C (InitString s) = return $ strInit s +initExpr2C (InitChar a) = return $ quotes $ text "\\x" <> text (showHex (read a) "") initExpr2C (InitReference i) = id2C IOLookup i -initExpr2C _ = return $ text "<>" +initExpr2C (InitRecord fields) = do + (fs :: [Doc]) <- mapM (\(Identifier a _, b) -> liftM (text "." <> text a <+> equals <+>) $ initExpr2C b) fields + return $ lbrace $+$ (nest 4 . vcat . punctuate comma $ fs) $+$ rbrace +initExpr2C (InitArray [value]) = initExpr2C value +initExpr2C (InitArray values) = liftM (braces . vcat . punctuate comma) $ mapM initExpr2C values +initExpr2C r@(InitRange (Range i@(Identifier i' _))) = do + id2C IOLookup i + t <- gets lastType + case t of + BTEnum s -> return . int $ length s + BTInt -> case i' of + "byte" -> return $ int 256 + _ -> error $ "InitRange identifier: " ++ i' + _ -> error $ "InitRange: " ++ show r +initExpr2C (InitRange (RangeFromTo (InitNumber "0") r)) = initExpr2C $ BuiltInFunction "succ" [r] +initExpr2C (InitRange (RangeFromTo (InitChar "0") (InitChar r))) = initExpr2C $ BuiltInFunction "succ" [InitNumber r] +initExpr2C (InitRange a) = error $ show a --return $ text "<>" +initExpr2C (InitSet []) = return $ text "0" +initExpr2C (InitSet a) = return $ text "<>" +initExpr2C (BuiltInFunction "low" [InitReference e]) = return $ + case e of + (Identifier "LongInt" _) -> int (-2^31) + (Identifier "SmallInt" _) -> int (-2^15) + _ -> error $ "BuiltInFunction 'low': " ++ show e +initExpr2C (BuiltInFunction "high" [e]) = do + initExpr2C e + t <- gets lastType + case t of + (BTArray i _ _) -> initExpr2C $ BuiltInFunction "pred" [InitRange i] + a -> error $ "BuiltInFunction 'high': " ++ show a +initExpr2C (BuiltInFunction "succ" [BuiltInFunction "pred" [e]]) = initExpr2C e +initExpr2C (BuiltInFunction "pred" [BuiltInFunction "succ" [e]]) = initExpr2C e +initExpr2C (BuiltInFunction "succ" [e]) = liftM (<> text " + 1") $ initExpr2C e +initExpr2C (BuiltInFunction "pred" [e]) = liftM (<> text " - 1") $ initExpr2C e +initExpr2C b@(BuiltInFunction _ _) = error $ show b +initExpr2C a = error $ "initExpr2C: don't know how to render " ++ show a -type2C :: TypeDecl -> State RenderState Doc -type2C (SimpleType i) = id2C IOLookup i +range2C :: InitExpression -> State RenderState [Doc] +range2C (InitString [a]) = return [quotes $ text [a]] +range2C (InitRange (Range i)) = liftM (flip (:) []) $ id2C IOLookup i +range2C (InitRange (RangeFromTo (InitString [a]) (InitString [b]))) = return $ map (\i -> quotes $ text [i]) [a..b] +range2C a = liftM (flip (:) []) $ initExpr2C a + +baseType2C :: String -> BaseType -> Doc +baseType2C _ BTFloat = text "float" +baseType2C _ BTBool = text "bool" +baseType2C _ BTString = text "string255" +baseType2C s a = error $ "baseType2C: " ++ show a ++ "\n" ++ s + +type2C :: TypeDecl -> State RenderState (Doc -> Doc) +type2C (SimpleType i) = liftM (\i a -> i <+> a) $ id2C IOLookup i type2C t = do r <- type2C' t rt <- resolveType t modify (\st -> st{lastType = rt}) return r where - type2C' VoidType = return $ text "void" - type2C' (String l) = return $ text $ "string" ++ show l - type2C' (PointerTo (SimpleType i)) = liftM (<> text "*") $ id2C IODeferred i - type2C' (PointerTo t) = liftM (<> text "*") $ type2C t + type2C' VoidType = return (text "void" <+>) + type2C' (String l) = return (text "string255" <+>)--return (text ("string" ++ show l) <+>) + type2C' (PointerTo (SimpleType i)) = liftM (\i a -> text "struct __" <> i <+> text "*" <+> a) $ id2C IODeferred i + type2C' (PointerTo t) = liftM (\t a -> t (parens $ text "*" <> a)) $ type2C t type2C' (RecordType tvs union) = do - t <- mapM (tvar2C False) tvs - return $ text "{" $+$ (nest 4 . vcat $ t) $+$ text "}" - type2C' (RangeType r) = return $ text "<>" + t <- withState' id $ mapM (tvar2C False) tvs + u <- unions + return $ \i -> text "struct __" <> i <+> lbrace $+$ nest 4 ((vcat . map (<> semi) . concat $ t) $$ u) $+$ rbrace <+> i + where + unions = case union of + Nothing -> return empty + Just a -> do + structs <- mapM struct2C a + return $ text "union" $+$ braces (nest 4 $ vcat structs) <> semi + struct2C tvs = do + t <- withState' id $ mapM (tvar2C False) tvs + return $ text "struct" $+$ braces (nest 4 (vcat . map (<> semi) . concat $ t)) <> semi + type2C' (RangeType r) = return (text "int" <+>) type2C' (Sequence ids) = do - mapM_ (id2C IOInsert) ids - return $ text "<>" - type2C' (ArrayDecl r t) = return $ text "<>" - type2C' (Set t) = return $ text "<>" - type2C' (FunctionType returnType params) = return $ text "<>" - type2C' (DeriveType _) = return $ text "<>" + is <- mapM (id2C IOInsert . setBaseType bt) ids + return (text "enum" <+> (braces . vcat . punctuate comma . map (\(a, b) -> a <+> equals <+> text "0x" <> text (showHex b "")) $ zip is [1..]) <+>) + where + bt = BTEnum $ map (\(Identifier i _) -> map toLower i) ids + type2C' (ArrayDecl Nothing t) = type2C (PointerTo t) + type2C' (ArrayDecl (Just r) t) = do + t' <- type2C t + r' <- initExpr2C (InitRange r) + return $ \i -> t' i <> brackets r' + type2C' (Set t) = return (text "<>" <+>) + type2C' (FunctionType returnType params) = do + t <- type2C returnType + p <- withState' id $ functionParams2C params + return (\i -> t empty <+> i <> parens p) + type2C' (DeriveType (InitBinOp _ _ i)) = type2C' (DeriveType i) + type2C' (DeriveType (InitPrefixOp _ i)) = type2C' (DeriveType i) + type2C' (DeriveType (InitNumber _)) = return (text "int" <+>) + type2C' (DeriveType (InitHexNumber _)) = return (text "int" <+>) + type2C' (DeriveType (InitFloat _)) = return (text "float" <+>) + type2C' (DeriveType (BuiltInFunction {})) = return (text "int" <+>) + type2C' (DeriveType (InitString {})) = return (text "string255" <+>) + type2C' (DeriveType r@(InitReference {})) = do + initExpr2C r + t <- gets lastType + return (baseType2C (show r) t <+>) + type2C' (DeriveType a) = error $ "Can't derive type from " ++ show a phrase2C :: Phrase -> State RenderState Doc phrase2C (Phrases p) = do ps <- mapM phrase2C p return $ text "{" $+$ (nest 4 . vcat $ ps) $+$ text "}" phrase2C (ProcCall f@(FunCall {}) []) = liftM (<> semi) $ ref2C f -phrase2C (ProcCall ref params) = do +phrase2C (ProcCall ref []) = liftM (<> semi) $ ref2CF ref +phrase2C (ProcCall ref params) = error $ "ProcCall"{-do r <- ref2C ref ps <- mapM expr2C params - return $ r <> parens (hsep . punctuate (char ',') $ ps) <> semi + return $ r <> parens (hsep . punctuate (char ',') $ ps) <> semi -} phrase2C (IfThenElse (expr) phrase1 mphrase2) = do e <- expr2C expr p1 <- (phrase2C . wrapPhrase) phrase1 @@ -367,10 +553,12 @@ elsePart | isNothing mphrase2 = return $ empty | otherwise = liftM (text "else" $$) $ (phrase2C . wrapPhrase) (fromJust mphrase2) phrase2C (Assignment ref expr) = do - r <- ref2C ref - e <- expr2C expr - return $ - r <> text " = " <> e <> semi + r <- ref2C ref + t <- gets lastType + e <- case (t, expr) of + (BTFunction _, (Reference r')) -> ref2C r' + _ -> expr2C expr + return $ r <+> text "=" <+> e <> semi phrase2C (WhileCycle expr phrase) = do e <- expr2C expr p <- phrase2C $ wrapPhrase phrase @@ -378,19 +566,29 @@ phrase2C (SwitchCase expr cases mphrase) = do e <- expr2C expr cs <- mapM case2C cases + d <- dflt return $ - text "switch" <> parens e <> text "of" $+$ (nest 4 . vcat) cs + text "switch" <> parens e $+$ braces (nest 4 . vcat $ cs ++ d) where case2C :: ([InitExpression], Phrase) -> State RenderState Doc case2C (e, p) = do - ie <- mapM initExpr2C e + ies <- mapM range2C e ph <- phrase2C p return $ - text "case" <+> parens (hsep . punctuate (char ',') $ ie) <> char ':' <> nest 4 (ph $+$ text "break;") -phrase2C (WithBlock ref p) = do + vcat (map (\i -> text "case" <+> i <> colon) . concat $ ies) <> nest 4 (ph $+$ text "break;") + dflt | isNothing mphrase = return [] + | otherwise = do + ph <- mapM phrase2C $ fromJust mphrase + return [text "default:" <+> nest 4 (vcat ph)] + +phrase2C wb@(WithBlock ref p) = do r <- ref2C ref - ph <- phrase2C $ wrapPhrase p - return $ text "namespace" <> parens r $$ ph + t <- gets lastType + case t of + (BTRecord rs) -> withRecordNamespace (render r ++ ".") rs $ phrase2C $ wrapPhrase p + a -> do + ns <- gets currentScope + error $ "'with' block referencing non-record type " ++ show a ++ "\n" ++ show wb ++ "\nnamespace: " ++ show (take 100 ns) phrase2C (ForCycle i' e1' e2' p) = do i <- id2C IOLookup i' e1 <- expr2C e1' @@ -403,52 +601,117 @@ phrase2C (RepeatCycle e' p') = do e <- expr2C e' p <- phrase2C (Phrases p') - return $ text "do" <+> p <+> text "while" <> parens (text "!" <> parens e) + return $ text "do" <+> p <+> text "while" <> parens (text "!" <> parens e) <> semi phrase2C NOP = return $ text ";" +phrase2C (BuiltInFunctionCall [] (SimpleReference (Identifier "exit" BTUnknown))) = return $ text "return" <> semi +phrase2C (BuiltInFunctionCall [e] (SimpleReference (Identifier "exit" BTUnknown))) = liftM (\e -> text "return" <> e <> semi) $ expr2C e +phrase2C (BuiltInFunctionCall [e] (SimpleReference (Identifier "dec" BTUnknown))) = liftM (\e -> text "--" <> e <> semi) $ expr2C e +phrase2C (BuiltInFunctionCall [e1, e2] (SimpleReference (Identifier "dec" BTUnknown))) = liftM2 (\a b -> a <> text " -= " <> b <> semi) (expr2C e1) (expr2C e2) +phrase2C (BuiltInFunctionCall [e] (SimpleReference (Identifier "inc" BTUnknown))) = liftM (\e -> text "++" <> e <> semi) $ expr2C e +phrase2C (BuiltInFunctionCall [e1, e2] (SimpleReference (Identifier "inc" BTUnknown))) = liftM2 (\a b -> a <+> text "+=" <+> b <> semi) (expr2C e1) (expr2C e2) +phrase2C a = error $ "phrase2C: " ++ show a wrapPhrase p@(Phrases _) = p wrapPhrase p = Phrases [p] - expr2C :: Expression -> State RenderState Doc expr2C (Expression s) = return $ text s expr2C (BinOp op expr1 expr2) = do e1 <- expr2C expr1 + t1 <- gets lastType e2 <- expr2C expr2 - o <- op2C op - return $ parens $ e1 <+> o <+> e2 + t2 <- gets lastType + case (op2C op, t1, t2) of + ("+", BTString, BTString) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strconcat" (BTFunction BTString)) + ("+", BTString, BTChar) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strappend" (BTFunction BTString)) + ("+", BTChar, BTString) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strprepend" (BTFunction BTString)) + ("==", BTString, _) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strcompare" (BTFunction BTBool)) + ("!=", BTString, _) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strncompare" (BTFunction BTBool)) + ("&", BTBool, _) -> return $ parens e1 <+> text "&&" <+> parens e2 + ("|", BTBool, _) -> return $ parens e1 <+> text "||" <+> parens e2 + (o, _, _) | o `elem` boolOps -> do + modify(\s -> s{lastType = BTBool}) + return $ parens e1 <+> text o <+> parens e2 + | otherwise -> return $ parens e1 <+> text o <+> parens e2 + where + boolOps = ["==", "!=", "<", ">", "<=", ">="] expr2C (NumberLiteral s) = return $ text s expr2C (FloatLiteral s) = return $ text s expr2C (HexNumber s) = return $ text "0x" <> (text . map toLower $ s) -expr2C (StringLiteral s) = return $ doubleQuotes $ text s -expr2C (Reference ref) = ref2C ref -expr2C (PrefixOp op expr) = liftM2 (<+>) (op2C op) (expr2C expr) +expr2C (StringLiteral [a]) = do + modify(\s -> s{lastType = BTChar}) + return . quotes $ text [a] +expr2C (StringLiteral s) = addStringConst s +expr2C (Reference ref) = ref2CF ref +expr2C (PrefixOp op expr) = liftM (text (op2C op) <>) (expr2C expr) expr2C Null = return $ text "NULL" +expr2C (CharCode a) = do + modify(\s -> s{lastType = BTChar}) + return $ quotes $ text "\\x" <> text (showHex (read a) "") +expr2C (HexCharCode a) = return $ quotes $ text "\\x" <> text (map toLower a) +expr2C (SetExpression ids) = mapM (id2C IOLookup) ids >>= return . parens . hcat . punctuate (text " | ") + +expr2C (BuiltInFunCall [e] (SimpleReference (Identifier "ord" _))) = liftM parens $ expr2C e +expr2C (BuiltInFunCall [e] (SimpleReference (Identifier "succ" _))) = liftM (<> text " + 1") $ expr2C e +expr2C (BuiltInFunCall [e] (SimpleReference (Identifier "pred" _))) = liftM (<> text " - 1") $ expr2C e expr2C (BuiltInFunCall params ref) = do r <- ref2C ref + t <- gets lastType ps <- mapM expr2C params + case t of + BTFunction t' -> do + modify (\s -> s{lastType = t'}) + _ -> error $ "BuiltInFunCall lastType: " ++ show t return $ r <> parens (hsep . punctuate (char ',') $ ps) -expr2C _ = return $ text "<>" +expr2C a = error $ "Don't know how to render " ++ show a +ref2CF :: Reference -> State RenderState Doc +ref2CF (SimpleReference name) = do + i <- id2C IOLookup name + t <- gets lastType + case t of + BTFunction _ -> return $ i <> parens empty + _ -> return $ i +ref2CF r = ref2C r ref2C :: Reference -> State RenderState Doc -ref2C ae@(ArrayElement exprs ref) = do - es <- mapM expr2C exprs +-- rewrite into proper form +ref2C (RecordField ref1 (ArrayElement exprs ref2)) = ref2C $ ArrayElement exprs (RecordField ref1 ref2) +ref2C (RecordField ref1 (Dereference ref2)) = ref2C $ Dereference (RecordField ref1 ref2) +ref2C (RecordField ref1 (RecordField ref2 ref3)) = ref2C $ RecordField (RecordField ref1 ref2) ref3 +ref2C (RecordField ref1 (FunCall params ref2)) = ref2C $ FunCall params (RecordField ref1 ref2) +ref2C (ArrayElement (a:b:xs) ref) = ref2C $ ArrayElement (b:xs) (ArrayElement [a] ref) +-- conversion routines +ref2C ae@(ArrayElement [expr] ref) = do + e <- expr2C expr r <- ref2C ref t <- gets lastType ns <- gets currentScope case t of - (BTArray _ (BTArray _ t')) -> modify (\st -> st{lastType = t'}) - (BTArray _ t') -> modify (\st -> st{lastType = t'}) + (BTArray _ _ t') -> modify (\st -> st{lastType = t'}) + (BTFunctionReturn _ (BTArray _ _ t')) -> modify (\st -> st{lastType = t'}) + (BTFunctionReturn _ (BTString)) -> modify (\st -> st{lastType = BTChar}) (BTString) -> modify (\st -> st{lastType = BTChar}) + (BTPointerTo t) -> do + t'' <- fromPointer (show t) =<< gets lastType + case t'' of + BTChar -> modify (\st -> st{lastType = BTChar}) + a -> error $ "Getting element of " ++ show a ++ "\nReference: " ++ show ae ++ "\n" ++ show (take 100 ns) a -> error $ "Getting element of " ++ show a ++ "\nReference: " ++ show ae ++ "\n" ++ show (take 100 ns) - return $ r <> (brackets . hcat) (punctuate comma es) + case t of + BTString -> return $ r <> text ".s" <> brackets e + _ -> return $ r <> brackets e ref2C (SimpleReference name) = id2C IOLookup name -ref2C (RecordField (Dereference ref1) ref2) = do +ref2C rf@(RecordField (Dereference ref1) ref2) = do r1 <- ref2C ref1 - r2 <- ref2C ref2 + t <- fromPointer (show ref1) =<< gets lastType + ns <- gets currentScope + r2 <- case t of + BTRecord rs -> withRecordNamespace "" rs $ ref2C ref2 + BTUnit -> withLastIdNamespace $ ref2C ref2 + a -> error $ "dereferencing from " ++ show a ++ "\n" ++ show rf ++ "\n" ++ show (take 100 ns) return $ r1 <> text "->" <> r2 ref2C rf@(RecordField ref1 ref2) = do @@ -456,48 +719,56 @@ t <- gets lastType ns <- gets currentScope r2 <- case t of - BTRecord rs -> withRecordNamespace rs $ ref2C ref2 - BTUnit -> withLastIdNamespace $ ref2C ref2 + BTFunctionReturn s (BTRecord rs) -> withRecordNamespace "" rs $ ref2C ref2 + BTRecord rs -> withRecordNamespace "" rs $ ref2C ref2 + BTUnit -> withLastIdNamespace $ ref2C ref2 a -> error $ "dereferencing from " ++ show a ++ "\n" ++ show rf ++ "\n" ++ show (take 100 ns) return $ r1 <> text "." <> r2 -ref2C (Dereference ref) = do +ref2C d@(Dereference ref) = do r <- ref2C ref - t <- fromPointer =<< gets lastType + t <- fromPointer (show d) =<< gets lastType modify (\st -> st{lastType = t}) - return $ (parens $ text "*") <> r -ref2C (FunCall params ref) = do - ps <- liftM (parens . hsep . punctuate (char ',')) $ mapM expr2C params + return $ (parens $ text "*" <> r) +ref2C f@(FunCall params ref) = do r <- ref2C ref t <- gets lastType case t of - BTFunction t -> do - modify (\s -> s{lastType = t}) + BTFunction t' -> do + ps <- liftM (parens . hsep . punctuate (char ',')) $ mapM expr2C params + modify (\s -> s{lastType = t'}) return $ r <> ps - _ -> return $ parens r <> ps + BTFunctionReturn r t' -> do + ps <- liftM (parens . hsep . punctuate (char ',')) $ mapM expr2C params + modify (\s -> s{lastType = t'}) + return $ text r <> ps + _ -> case (ref, params) of + (SimpleReference i, [p]) -> ref2C $ TypeCast i p + _ -> error $ "ref2C FunCall erroneous type cast detected: " ++ show f ++ "\nType detected: " ++ show t ref2C (Address ref) = do r <- ref2C ref return $ text "&" <> parens r -ref2C (TypeCast t' expr) = do - t <- id2C IOLookup t' - e <- expr2C expr - return $ parens t <> e +ref2C (TypeCast t'@(Identifier i _) expr) = do + case map toLower i of + "pchar" -> ref2C $ FunCall [expr] (SimpleReference (Identifier "_pchar" $ BTPointerTo BTChar)) + a -> do + e <- expr2C expr + t <- id2C IOLookup t' + return $ parens t <> e ref2C (RefExpression expr) = expr2C expr -op2C :: String -> State RenderState Doc -op2C "or" = return $ text "|" -op2C "and" = return $ text "&" -op2C "not" = return $ text "!" -op2C "xor" = return $ text "^" -op2C "div" = return $ text "/" -op2C "mod" = return $ text "%" -op2C "shl" = return $ text "<<" -op2C "shr" = return $ text ">>" -op2C "<>" = return $ text "!=" -op2C "=" = return $ text "==" -op2C a = return $ text a +op2C :: String -> String +op2C "or" = "|" +op2C "and" = "&" +op2C "not" = "!" +op2C "xor" = "^" +op2C "div" = "/" +op2C "mod" = "%" +op2C "shl" = "<<" +op2C "shr" = ">>" +op2C "<>" = "!=" +op2C "=" = "==" +op2C a = a -maybeVoid "" = "void" -maybeVoid a = a