# HG changeset patch # User unc0rr # Date 1255365870 0 # Node ID 6800f8aa0184e69a5af870ea503a77a7f66bf4cf # Parent 241e3bb6a1460967aa14f4458af9880d7d652514 Huge Smaxx patch with some fixes by me: - support for non power of two textures - modelview matrix calculation optimizations - health effect when picking up health crates or using vampirism - rc plane training time trial - fix visual gear drawing position (might require recheck) - gamepad support - reordered options in frontend - updated binding options (subcaptions, descriptions and localizable names) - cfg-dir parameter for frontend (allows teams/settings to sit on a usb flash drive for example) - icons for chatroom user list diff -r 241e3bb6a146 -r 6800f8aa0184 QTfrontend/CMakeLists.txt --- a/QTfrontend/CMakeLists.txt Mon Oct 12 13:56:07 2009 +0000 +++ b/QTfrontend/CMakeLists.txt Mon Oct 12 16:44:30 2009 +0000 @@ -5,8 +5,8 @@ set(QT_USE_QTGUI TRUE) set(QT_USE_QTNETWORK TRUE) set(QT_USE_QTSVG TRUE) -set(QT_USE_QTXML TRUE) -# set(QT_USE_QTOPENGL TRUE) +set(QT_USE_QTXML FALSE) +set(QT_USE_QTOPENGL FALSE) set(QT_USE_QTMAIN TRUE) find_package(Qt4 REQUIRED) diff -r 241e3bb6a146 -r 6800f8aa0184 QTfrontend/SDLs.cpp --- a/QTfrontend/SDLs.cpp Mon Oct 12 13:56:07 2009 +0000 +++ b/QTfrontend/SDLs.cpp Mon Oct 12 16:44:30 2009 +0000 @@ -21,14 +21,26 @@ #include "SDL.h" #include "hwconsts.h" +#include + +extern char sdlkeys[1024][2][128]; +extern char xb360buttons[][128]; +extern char xb360dpad[128]; +extern char xbox360axes[][128]; + bool hardware; extern char *programname; -SDLInteraction::SDLInteraction(bool hardware_snd) +SDLInteraction::SDLInteraction() { music = -1; - hardware = hardware_snd; - SDL_Init(SDL_INIT_VIDEO); + hardware = false; + SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK); + + + if(SDL_NumJoysticks()) + addGameControllerKeys(); + SDL_QuitSubSystem(SDL_INIT_JOYSTICK); } SDLInteraction::~SDLInteraction() @@ -37,6 +49,11 @@ openal_close(); } +void SDLInteraction::setHardwareSound(bool hardware_snd) +{ + hardware = hardware_snd; +} + QStringList SDLInteraction::getResolutions() const { QStringList result; @@ -58,6 +75,87 @@ return result; } +void SDLInteraction::addGameControllerKeys() const +{ + QStringList result; + + int i = 0; + while(i < 1024 && sdlkeys[i][1][0] != '\0') + i++; + + // Iterate through all game controllers + for(int jid = 0; jid < SDL_NumJoysticks(); jid++) + { + SDL_Joystick* joy = SDL_JoystickOpen(jid); + + // Retrieve the game controller's name and strip "Controller (...)" that's added by some drivers (English only) + QString joyname = QString(SDL_JoystickName(jid)).replace(QRegExp("^Controller \\((.*)\\)$"), "\\1"); + + // Connected Xbox 360 controller? Use specific button names then + // Might be interesting to add 'named' buttons for the most often used gamepads + bool isxb = joyname.contains("Xbox 360"); + + // This part of the string won't change for multiple keys/hats, so keep it + QString prefix = QString("%1 (%2): ").arg(joyname).arg(jid + 1); + + // Register entries for missing axes not assigned to sticks of this joystick/gamepad + for(int aid = 0; aid < SDL_JoystickNumAxes(joy) && i < 1021; aid++) + { + // Axis 2 on xbox 360 is left/right trigger but those are used as buttons anyway so skip it + if(aid == 2 && isxb) + continue; + + // Again store the part of the string not changing for multiple uses + QString axis = prefix + QApplication::translate("binds (keys)", "Axis") + QString(" %1 ").arg(aid + 1); + + // Entry for "Axis Up" + sprintf(sdlkeys[i][0], "j%da%du", jid, aid); + sprintf(sdlkeys[i++][1], "%s", ((isxb && aid < 5) ? (prefix + QApplication::translate("binds (keys)", xbox360axes[aid * 2])) : axis + QApplication::translate("binds (keys)", "(Up)")).toStdString().c_str()); + + // Entry for "Axis Down" + sprintf(sdlkeys[i][0], "j%da%dd", jid, aid); + sprintf(sdlkeys[i++][1], "%s", ((isxb && aid < 5) ? (prefix + QApplication::translate("binds (keys)", xbox360axes[aid * 2 + 1])) : axis + QApplication::translate("binds (keys)", "(Down)")).toStdString().c_str()); + } + + // Register entries for all coolie hats of this joystick/gamepad + for(int hid = 0; hid < SDL_JoystickNumHats(joy) && i < 1019; hid++) + { + // Again store the part of the string not changing for multiple uses + QString hat = prefix + (isxb ? (QApplication::translate("binds (keys)", xb360dpad) + QString(" ")) : QApplication::translate("binds (keys)", "Hat") + QString(" %1 ").arg(hid + 1)); + + // Entry for "Hat Up" + sprintf(sdlkeys[i][0], "j%dh%du", jid, hid); + sprintf(sdlkeys[i++][1], "%s", (hat + QApplication::translate("binds (keys)", "(Up)")).toStdString().c_str()); + + // Entry for "Hat Down" + sprintf(sdlkeys[i][0], "j%dh%dd", jid, hid); + sprintf(sdlkeys[i++][1], "%s", (hat + QApplication::translate("binds (keys)", "(Down)")).toStdString().c_str()); + + // Entry for "Hat Left" + sprintf(sdlkeys[i][0], "j%dh%dl", jid, hid); + sprintf(sdlkeys[i++][1], "%s", (hat + QApplication::translate("binds (keys)", "(Left)")).toStdString().c_str()); + + // Entry for "Hat Right" + sprintf(sdlkeys[i][0], "j%dh%dr", jid, hid); + sprintf(sdlkeys[i++][1], "%s", (hat + QApplication::translate("binds (keys)", "(Right)")).toStdString().c_str()); + } + + // Register entries for all buttons of this joystick/gamepad + for(int bid = 0; bid < SDL_JoystickNumButtons(joy) && i < 1022; bid++) + { + // Buttons + sprintf(sdlkeys[i][0], "j%db%d", jid, bid); + sprintf(sdlkeys[i++][1], "%s", (prefix + ((isxb && bid < 10) ? (QApplication::translate("binds (keys)", xb360buttons[bid]) + QString(" ")) : QApplication::translate("binds (keys)", "Button") + QString(" %1").arg(bid + 1))).toStdString().c_str()); + } + // Close the game controller as we no longer need it + SDL_JoystickClose(joy); + } + + // Terminate the list + sdlkeys[i][0][0] = '\0'; + sdlkeys[i][1][0] = '\0'; +} + void SDLInteraction::StartMusic() { OpenAL_Init(); diff -r 241e3bb6a146 -r 6800f8aa0184 QTfrontend/SDLs.h --- a/QTfrontend/SDLs.h Mon Oct 12 13:56:07 2009 +0000 +++ b/QTfrontend/SDLs.h Mon Oct 12 16:44:30 2009 +0000 @@ -44,9 +44,11 @@ int music; public: - SDLInteraction(bool); + SDLInteraction(); ~SDLInteraction(); + void setHardwareSound(bool hardware_snd); QStringList getResolutions() const; + void addGameControllerKeys() const; void StartMusic(); void StopMusic(); }; diff -r 241e3bb6a146 -r 6800f8aa0184 QTfrontend/binds.cpp --- a/QTfrontend/binds.cpp Mon Oct 12 13:56:07 2009 +0000 +++ b/QTfrontend/binds.cpp Mon Oct 12 16:44:30 2009 +0000 @@ -20,43 +20,50 @@ const BindAction cbinds[BINDS_NUMBER] = { - {"+up", "up", QT_TRANSLATE_NOOP("binds", "up"), false}, - {"+left", "left", QT_TRANSLATE_NOOP("binds", "left"), false}, - {"+right", "right", QT_TRANSLATE_NOOP("binds", "right"), false}, - {"+down", "down", QT_TRANSLATE_NOOP("binds", "down"), false}, - {"ljump", "return", QT_TRANSLATE_NOOP("binds", "jump"), false}, - {"hjump", "backspace", QT_TRANSLATE_NOOP("binds", "jump"), false}, - {"+attack", "space", QT_TRANSLATE_NOOP("binds", "attack"), false}, - {"+precise", "left_shift", QT_TRANSLATE_NOOP("binds", "precise aim"), false}, - {"put", "mousel", QT_TRANSLATE_NOOP("binds", "put"), false}, - {"switch", "tab", QT_TRANSLATE_NOOP("binds", "switch"), false}, - {"findhh", "h", QT_TRANSLATE_NOOP("binds", "find hedgehog"), true}, - {"ammomenu", "mouser", QT_TRANSLATE_NOOP("binds", "ammo menu"), false}, - {"slot 1", "f1", QT_TRANSLATE_NOOP("binds", "slot 1"), false}, - {"slot 2", "f2", QT_TRANSLATE_NOOP("binds", "slot 2"), false}, - {"slot 3", "f3", QT_TRANSLATE_NOOP("binds", "slot 3"), false}, - {"slot 4", "f4", QT_TRANSLATE_NOOP("binds", "slot 4"), false}, - {"slot 5", "f5", QT_TRANSLATE_NOOP("binds", "slot 5"), false}, - {"slot 6", "f6", QT_TRANSLATE_NOOP("binds", "slot 6"), false}, - {"slot 7", "f7", QT_TRANSLATE_NOOP("binds", "slot 7"), false}, - {"slot 8", "f8", QT_TRANSLATE_NOOP("binds", "slot 8"), false}, - {"slot 9", "f9", QT_TRANSLATE_NOOP("binds", "slot 9"), true}, - {"timer 1", "1", QT_TRANSLATE_NOOP("binds", "timer 1 sec"), false}, - {"timer 2", "2", QT_TRANSLATE_NOOP("binds", "timer 2 sec"), false}, - {"timer 3", "3", QT_TRANSLATE_NOOP("binds", "timer 3 sec"), false}, - {"timer 4", "4", QT_TRANSLATE_NOOP("binds", "timer 4 sec"), false}, - {"timer 5", "5", QT_TRANSLATE_NOOP("binds", "timer 5 sec"), true}, - {"chat", "t", QT_TRANSLATE_NOOP("binds", "chat"), false}, - {"history", "`", QT_TRANSLATE_NOOP("binds", "chat history"), false}, - {"pause", "p", QT_TRANSLATE_NOOP("binds", "pause"), false}, - {"confirm", "y", QT_TRANSLATE_NOOP("binds", "confirmation"), false}, - {"+voldown", "9", QT_TRANSLATE_NOOP("binds", "volume down"), false}, - {"+volup", "0", QT_TRANSLATE_NOOP("binds", "volume up"), false}, - {"zoomin", "wheeldown", QT_TRANSLATE_NOOP("binds", "zoom in"), false}, - {"zoomout", "wheelup", QT_TRANSLATE_NOOP("binds", "zoom out"), false}, - {"zoomreset", "mousem", QT_TRANSLATE_NOOP("binds", "reset zoom"), false}, - {"fullscr", "f12", QT_TRANSLATE_NOOP("binds", "change mode"), false}, - {"capture", "c", QT_TRANSLATE_NOOP("binds", "capture"), false}, - {"rotmask", "delete", QT_TRANSLATE_NOOP("binds", "hedgehogs\ninfo"), false}, - {"quit", "escape", QT_TRANSLATE_NOOP("binds", "quit"), true} + {"+up", "up", QT_TRANSLATE_NOOP("binds", "up"), QT_TRANSLATE_NOOP("binds (categories)", "Basic controls"), QT_TRANSLATE_NOOP("binds (descriptions)", "Move your hogs and aim:")}, + {"+left", "left", QT_TRANSLATE_NOOP("binds", "left"), NULL, NULL}, + {"+right", "right", QT_TRANSLATE_NOOP("binds", "right"), NULL, NULL}, + {"+down", "down", QT_TRANSLATE_NOOP("binds", "down"), NULL, NULL}, + {"+precise", "left_shift", QT_TRANSLATE_NOOP("binds", "precise aim"), NULL, NULL}, + {"ljump", "return", QT_TRANSLATE_NOOP("binds", "long jump"), NULL, QT_TRANSLATE_NOOP("binds (descriptions)", "Traverse gaps and obstacles by jumping:")}, + {"hjump", "backspace", QT_TRANSLATE_NOOP("binds", "high jump"), NULL, NULL}, + {"+attack", "space", QT_TRANSLATE_NOOP("binds", "attack"), NULL, QT_TRANSLATE_NOOP("binds (descriptions)", "Fire your selected weapon or trigger an utility item:")}, + {"put", "mousel", QT_TRANSLATE_NOOP("binds", "put"), NULL, QT_TRANSLATE_NOOP("binds (descriptions)", "Pick a weapon or a target location under the cursor:")}, + {"switch", "tab", QT_TRANSLATE_NOOP("binds", "switch"), NULL, QT_TRANSLATE_NOOP("binds (descriptions)", "Switch your currently active hog (if possible):")}, + {"ammomenu", "mouser", QT_TRANSLATE_NOOP("binds", "ammo menu"), QT_TRANSLATE_NOOP("binds (categories)", "Weapon controls"), QT_TRANSLATE_NOOP("binds (descriptions)", "Pick a weapon or utility item:")}, + {"slot 1", "f1", QT_TRANSLATE_NOOP("binds", "slot 1"), NULL, NULL}, + {"slot 2", "f2", QT_TRANSLATE_NOOP("binds", "slot 2"), NULL, NULL}, + {"slot 3", "f3", QT_TRANSLATE_NOOP("binds", "slot 3"), NULL, NULL}, + {"slot 4", "f4", QT_TRANSLATE_NOOP("binds", "slot 4"), NULL, NULL}, + {"slot 5", "f5", QT_TRANSLATE_NOOP("binds", "slot 5"), NULL, NULL}, + {"slot 6", "f6", QT_TRANSLATE_NOOP("binds", "slot 6"), NULL, NULL}, + {"slot 7", "f7", QT_TRANSLATE_NOOP("binds", "slot 7"), NULL, NULL}, + {"slot 8", "f8", QT_TRANSLATE_NOOP("binds", "slot 8"), NULL, NULL}, + {"slot 9", "f9", QT_TRANSLATE_NOOP("binds", "slot 9"), NULL, NULL}, + {"timer 1", "1", QT_TRANSLATE_NOOP("binds", "timer 1 sec"), NULL, QT_TRANSLATE_NOOP("binds (descriptions)", "Set the timer on bombs and timed weapons:")}, + {"timer 2", "2", QT_TRANSLATE_NOOP("binds", "timer 2 sec"), NULL, NULL}, + {"timer 3", "3", QT_TRANSLATE_NOOP("binds", "timer 3 sec"), NULL, NULL}, + {"timer 4", "4", QT_TRANSLATE_NOOP("binds", "timer 4 sec"), NULL, NULL}, + {"timer 5", "5", QT_TRANSLATE_NOOP("binds", "timer 5 sec"), NULL, NULL}, + {"findhh", "h", QT_TRANSLATE_NOOP("binds", "find hedgehog"), QT_TRANSLATE_NOOP("binds (categories)", "Camera and cursor controls"), QT_TRANSLATE_NOOP("binds (descriptions)", "Move the camera to the active hog:")}, + {"+cur_u", "", QT_TRANSLATE_NOOP("binds", "up"), NULL, QT_TRANSLATE_NOOP("binds (descriptions)", "Move the cursor or camera without using the mouse:")}, + {"+cur_l", "", QT_TRANSLATE_NOOP("binds", "left"), NULL, NULL}, + {"+cur_r", "", QT_TRANSLATE_NOOP("binds", "right"), NULL, NULL}, + {"+cur_d", "", QT_TRANSLATE_NOOP("binds", "down"), NULL, NULL}, +// {"+cur_m", "", QT_TRANSLATE_NOOP("binds", "movement key modifier"), NULL, QT_TRANSLATE_NOOP("binds (descriptions)", "Specify a modifier key to move camera and cursor using your default hog movement keys:")}, + {"zoomin", "wheeldown", QT_TRANSLATE_NOOP("binds", "zoom in"), NULL, QT_TRANSLATE_NOOP("binds (descriptions)", "Modify the camera's zoom level:")}, + {"zoomout", "wheelup", QT_TRANSLATE_NOOP("binds", "zoom out"), NULL, NULL}, + {"zoomreset", "mousem", QT_TRANSLATE_NOOP("binds", "reset zoom"), NULL, NULL}, + {"chat", "t", QT_TRANSLATE_NOOP("binds", "chat"), QT_TRANSLATE_NOOP("binds (categories)", "Other"), QT_TRANSLATE_NOOP("binds (descriptions)", "Talk to your team or all participants:")}, + {"history", "`", QT_TRANSLATE_NOOP("binds", "chat history"), NULL, NULL}, + {"pause", "p", QT_TRANSLATE_NOOP("binds", "pause"), NULL, QT_TRANSLATE_NOOP("binds (descriptions)", "Pause, continue or leave your game:")}, + {"quit", "escape", QT_TRANSLATE_NOOP("binds", "quit"), NULL, NULL}, + {"confirm", "y", QT_TRANSLATE_NOOP("binds", "confirmation"), NULL, NULL}, + {"+voldown", "9", QT_TRANSLATE_NOOP("binds", "volume down"), NULL, QT_TRANSLATE_NOOP("binds (descriptions)", "Modify the game's volume while playing:")}, + {"+volup", "0", QT_TRANSLATE_NOOP("binds", "volume up"), NULL, NULL}, +#ifndef _WIN32 + {"fullscr", "f12", QT_TRANSLATE_NOOP("binds", "change mode"), NULL, QT_TRANSLATE_NOOP("binds (descriptions)", "Toggle fullscreen mode:")}, +#endif + {"capture", "c", QT_TRANSLATE_NOOP("binds", "capture"), NULL, QT_TRANSLATE_NOOP("binds (descriptions)", "Take a screenshot:")}, + {"rotmask", "delete", QT_TRANSLATE_NOOP("binds", "hedgehogs\ninfo"), NULL, QT_TRANSLATE_NOOP("binds (descriptions)", "Toggle labels above hedgehogs:")} }; diff -r 241e3bb6a146 -r 6800f8aa0184 QTfrontend/binds.h --- a/QTfrontend/binds.h Mon Oct 12 13:56:07 2009 +0000 +++ b/QTfrontend/binds.h Mon Oct 12 16:44:30 2009 +0000 @@ -21,14 +21,19 @@ #include -#define BINDS_NUMBER 39 +#ifdef _WIN32 +#define BINDS_NUMBER 42 +#else +#define BINDS_NUMBER 43 +#endif struct BindAction { QString action; QString strbind; const char * name; - bool chwidget; + const char * category; + const char * description; }; extern const BindAction cbinds[BINDS_NUMBER]; diff -r 241e3bb6a146 -r 6800f8aa0184 QTfrontend/chatwidget.cpp --- a/QTfrontend/chatwidget.cpp Mon Oct 12 13:56:07 2009 +0000 +++ b/QTfrontend/chatwidget.cpp Mon Oct 12 16:44:30 2009 +0000 @@ -107,6 +107,7 @@ void HWChatWidget::nickAdded(const QString& nick) { QListWidgetItem * item = new QListWidgetItem(nick); + item->setIcon(QIcon(":/res/hh_small.png")); chatNicks->addItem(item); } diff -r 241e3bb6a146 -r 6800f8aa0184 QTfrontend/game.cpp --- a/QTfrontend/game.cpp Mon Oct 12 13:56:07 2009 +0000 +++ b/QTfrontend/game.cpp Mon Oct 12 16:44:30 2009 +0000 @@ -141,7 +141,7 @@ HWProto::addStringListToBuffer(traincfg, team1.TeamGameConfig(100)); - QFile file(datadir->absolutePath() + "/Trainings/001_Shotgun.txt"); + QFile file(datadir->absolutePath() + "/Trainings/003_RCPlane.txt"); if(!file.open(QFile::ReadOnly)) { emit ErrorMessage(tr("Error reading training config file")); diff -r 241e3bb6a146 -r 6800f8aa0184 QTfrontend/hwconsts.cpp.in --- a/QTfrontend/hwconsts.cpp.in Mon Oct 12 13:56:07 2009 +0000 +++ b/QTfrontend/hwconsts.cpp.in Mon Oct 12 16:44:30 2009 +0000 @@ -20,6 +20,7 @@ QString * cProtoVer = new QString("${HEDGEWARS_PROTO_VER}"); QString * cDataDir = new QString("${HEDGEWARS_DATADIR}"); +QString * cConfigDir = new QString(""); QString * cVersionString = new QString("${HEDGEWARS_VERSION}"); QDir * bindir = new QDir("${HEDGEWARS_BINDIR}"); diff -r 241e3bb6a146 -r 6800f8aa0184 QTfrontend/hwconsts.h --- a/QTfrontend/hwconsts.h Mon Oct 12 13:56:07 2009 +0000 +++ b/QTfrontend/hwconsts.h Mon Oct 12 16:44:30 2009 +0000 @@ -25,6 +25,7 @@ extern QString * cProtoVer; extern QString * cVersionString; extern QString * cDataDir; +extern QString * cConfigDir; extern QDir * bindir; extern QDir * cfgdir; diff -r 241e3bb6a146 -r 6800f8aa0184 QTfrontend/hwform.cpp --- a/QTfrontend/hwform.cpp Mon Oct 12 13:56:07 2009 +0000 +++ b/QTfrontend/hwform.cpp Mon Oct 12 16:44:30 2009 +0000 @@ -77,9 +77,9 @@ CustomizePalettes(); - sdli = new SDLInteraction(ui.pageOptions->CBHardwareSound->isChecked()); + sdli.setHardwareSound(ui.pageOptions->CBHardwareSound->isChecked()); - ui.pageOptions->CBResolution->addItems(sdli->getResolutions()); + ui.pageOptions->CBResolution->addItems(sdli.getResolutions()); config = new GameUIConfig(this, cfgdir->absolutePath() + "/hedgewars.ini"); @@ -784,9 +784,11 @@ pRegisterServer->unregister(); pRegisterServer = 0; } + setVisible(false); break; } case gsFinished: { + setVisible(true); GoBack(); Music(ui.pageOptions->CBEnableMusic->isChecked()); if (wBackground) wBackground->startAnimation(); @@ -795,6 +797,7 @@ break; } default: { + setVisible(true); quint8 id = ui.Pages->currentIndex(); if (id == ID_PAGE_INGAME) { GoBack(); @@ -889,9 +892,9 @@ void HWForm::Music(bool checked) { if (checked) - sdli->StartMusic(); + sdli.StartMusic(); else - sdli->StopMusic(); + sdli.StopMusic(); } void HWForm::NetGameChangeStatus(bool isMaster) diff -r 241e3bb6a146 -r 6800f8aa0184 QTfrontend/hwform.h --- a/QTfrontend/hwform.h Mon Oct 12 13:56:07 2009 +0000 +++ b/QTfrontend/hwform.h Mon Oct 12 16:44:30 2009 +0000 @@ -148,7 +148,7 @@ AmmoSchemeModel * ammoSchemeModel; QStack PagesStack; QTime eggTimer; - SDLInteraction * sdli; + SDLInteraction sdli; BGWidget * wBackground; #ifdef __APPLE__ diff -r 241e3bb6a146 -r 6800f8aa0184 QTfrontend/main.cpp --- a/QTfrontend/main.cpp Mon Oct 12 13:56:07 2009 +0000 +++ b/QTfrontend/main.cpp Mon Oct 12 16:44:30 2009 +0000 @@ -75,11 +75,15 @@ *cDataDir = f.absoluteFilePath(); } + if(parsedArgs.contains("config-dir")) { + QFileInfo f(parsedArgs["config-dir"]); + *cConfigDir = f.absoluteFilePath(); + } + app.setStyle(new QPlastiqueStyle); QDateTime now = QDateTime::currentDateTime(); - QDateTime zero; - srand(now.secsTo(zero)); + srand(now.toTime_t()); rand(); Q_INIT_RESOURCE(hedgewars); @@ -288,23 +292,37 @@ bindir->cd("bin"); // workaround over NSIS installer - cfgdir->setPath(cfgdir->homePath()); - + if(cConfigDir->length() == 0) + cfgdir->setPath(cfgdir->homePath()); + else + cfgdir->setPath(*cConfigDir); + + if(cConfigDir->length() == 0) + { #ifdef __APPLE__ - if (checkForDir(cfgdir->absolutePath() + "/Library/Application Support/Hedgewars")) - { - checkForDir(cfgdir->absolutePath() + "/Library/Application Support/Hedgewars/Demos"); - checkForDir(cfgdir->absolutePath() + "/Library/Application Support/Hedgewars/Saves"); + if (checkForDir(cfgdir->absolutePath() + "/Library/Application Support/Hedgewars")) + { + checkForDir(cfgdir->absolutePath() + "/Library/Application Support/Hedgewars/Demos"); + checkForDir(cfgdir->absolutePath() + "/Library/Application Support/Hedgewars/Saves"); + } + cfgdir->cd("Library/Application Support/Hedgewars"); +#else + if (checkForDir(cfgdir->absolutePath() + "/.hedgewars")) + { + checkForDir(cfgdir->absolutePath() + "/.hedgewars/Demos"); + checkForDir(cfgdir->absolutePath() + "/.hedgewars/Saves"); + } + cfgdir->cd(".hedgewars"); +#endif } - cfgdir->cd("Library/Application Support/Hedgewars"); -#else - if (checkForDir(cfgdir->absolutePath() + "/.hedgewars")) + else { - checkForDir(cfgdir->absolutePath() + "/.hedgewars/Demos"); - checkForDir(cfgdir->absolutePath() + "/.hedgewars/Saves"); + if (checkForDir(cfgdir->absolutePath())) + { + checkForDir(cfgdir->absolutePath() + "/Demos"); + checkForDir(cfgdir->absolutePath() + "/Saves"); + } } - cfgdir->cd(".hedgewars"); -#endif datadir->cd(bindir->absolutePath()); datadir->cd(*cDataDir); diff -r 241e3bb6a146 -r 6800f8aa0184 QTfrontend/pages.cpp --- a/QTfrontend/pages.cpp Mon Oct 12 13:56:07 2009 +0000 +++ b/QTfrontend/pages.cpp Mon Oct 12 16:44:30 2009 +0000 @@ -243,39 +243,42 @@ BindsBox = new QToolBox(GBoxBinds); BindsBox->setLineWidth(0); GBBLayout->addWidget(BindsBox); - page_A = new QWidget(this); - BindsBox->addItem(page_A, QToolBox::tr("Actions")); - page_W = new QWidget(this); - BindsBox->addItem(page_W, QToolBox::tr("Weapons")); - page_WP = new QWidget(this); - BindsBox->addItem(page_WP, QToolBox::tr("Weapon properties")); - page_O = new QWidget(this); - BindsBox->addItem(page_O, QToolBox::tr("Other")); page2Layout->addWidget(GBoxBinds, 0, 0); - QStringList binds; - for(int i = 0; strlen(sdlkeys[i][1]) > 0; i++) - { - binds << sdlkeys[i][1]; - } - quint16 widind = 0, i = 0; + quint16 num = 0; + QWidget * curW = NULL; + QGridLayout * pagelayout = NULL; + QLabel* l = NULL; while (i < BINDS_NUMBER) { - quint16 num = 0; - QWidget * curW = BindsBox->widget(widind); - QGridLayout * pagelayout = new QGridLayout(curW); - do { - LBind[i] = new QLabel(curW); - LBind[i]->setText(QApplication::translate("binds", cbinds[i].name)); - LBind[i]->setAlignment(Qt::AlignRight); - pagelayout->addWidget(LBind[i], num, 0); - CBBind[i] = new QComboBox(curW); - CBBind[i]->addItems(binds); - pagelayout->addWidget(CBBind[i], num, 1); - num++; - } while (!cbinds[i++].chwidget); - pagelayout->addWidget(new QWidget(curW), num, 0, 1, 2); - widind++; + if(cbinds[i].category != NULL) + { + if(curW != NULL) + { + l = new QLabel(curW); + l->setText(""); + pagelayout->addWidget(l, num++, 0, 1, 2); + } + curW = new QWidget(this); + BindsBox->addItem(curW, QApplication::translate("binds (categories)", cbinds[i].category)); + pagelayout = new QGridLayout(curW); + num = 0; + } + if(cbinds[i].description != NULL) + { + l = new QLabel(curW); + l->setText((num > 0 ? QString("\n") : QString("")) + QApplication::translate("binds (descriptions)", cbinds[i].description)); + pagelayout->addWidget(l, num++, 0, 1, 2); + } + + l = new QLabel(curW); + l->setText(QApplication::translate("binds", cbinds[i].name)); + l->setAlignment(Qt::AlignRight); + pagelayout->addWidget(l, num, 0); + CBBind[i] = new QComboBox(curW); + for(int j = 0; sdlkeys[j][1][0] != '\0'; j++) + CBBind[i]->addItem(QApplication::translate("binds (keys)", sdlkeys[j][1]).contains(": ") ? QApplication::translate("binds (keys)", sdlkeys[j][1]) : QApplication::translate("binds (keys)", "Keyboard") + QString(": ") + QApplication::translate("binds (keys)", sdlkeys[j][1]), sdlkeys[j][0]); + pagelayout->addWidget(CBBind[i++], num++, 1); } } @@ -398,6 +401,14 @@ QVBoxLayout * GBAlayout = new QVBoxLayout(AGGroupBox); QHBoxLayout * GBAreslayout = new QHBoxLayout(0); + CBFrontendFullscreen = new QCheckBox(AGGroupBox); + CBFrontendFullscreen->setText(QCheckBox::tr("Frontend fullscreen")); + GBAlayout->addWidget(CBFrontendFullscreen); + + CBFrontendEffects = new QCheckBox(AGGroupBox); + CBFrontendEffects->setText(QCheckBox::tr("Frontend effects (requires restart)")); + GBAlayout->addWidget(CBFrontendEffects); + QLabel * resolution = new QLabel(AGGroupBox); resolution->setText(QLabel::tr("Resolution")); GBAreslayout->addWidget(resolution); @@ -406,6 +417,10 @@ GBAreslayout->addWidget(CBResolution); GBAlayout->addLayout(GBAreslayout); + CBFullscreen = new QCheckBox(AGGroupBox); + CBFullscreen->setText(QCheckBox::tr("Fullscreen")); + GBAlayout->addWidget(CBFullscreen); + QHBoxLayout * GBAfpslayout = new QHBoxLayout(0); QLabel * maxfps = new QLabel(AGGroupBox); maxfps->setText(QLabel::tr("FPS limit")); @@ -413,23 +428,11 @@ GBAlayout->addLayout(GBAfpslayout); CBReduceQuality = new QCheckBox(AGGroupBox); - CBReduceQuality->setText(QCheckBox::tr("Reduce Quality")); + CBReduceQuality->setText(QCheckBox::tr("Reduced quality")); GBAlayout->addWidget(CBReduceQuality); - CBFrontendEffects = new QCheckBox(AGGroupBox); - CBFrontendEffects->setText(QCheckBox::tr("Frontend Effects (Requires Restart)")); - GBAlayout->addWidget(CBFrontendEffects); - - CBFullscreen = new QCheckBox(AGGroupBox); - CBFullscreen->setText(QCheckBox::tr("Fullscreen")); - GBAlayout->addWidget(CBFullscreen); - - CBFrontendFullscreen = new QCheckBox(AGGroupBox); - CBFrontendFullscreen->setText(QCheckBox::tr("Frontend fullscreen")); - GBAlayout->addWidget(CBFrontendFullscreen); - CBHardwareSound = new QCheckBox(AGGroupBox); - CBHardwareSound->setText(QCheckBox::tr("Use hardware sound (if available; requires restart)")); + CBHardwareSound->setText(QCheckBox::tr("Hardware sound (if available; requires restart)")); //CBHardwareSound->setEnabled(openal_ready()); GBAlayout->addWidget(CBHardwareSound); @@ -776,7 +779,7 @@ { QGridLayout * pageLayout = new QGridLayout(this); - QHBoxLayout * newRoomLayout = new QHBoxLayout(this); + QHBoxLayout * newRoomLayout = new QHBoxLayout(); QLabel * roomNameLabel = new QLabel(this); roomNameLabel->setText(tr("Room Name:")); roomName = new QLineEdit(this); diff -r 241e3bb6a146 -r 6800f8aa0184 QTfrontend/pages.h --- a/QTfrontend/pages.h Mon Oct 12 13:56:07 2009 +0000 +++ b/QTfrontend/pages.h Mon Oct 12 16:44:30 2009 +0000 @@ -159,10 +159,6 @@ QComboBox *CBVoicepack; QGroupBox *GBoxBinds; QToolBox *BindsBox; - QWidget *page_A; - QWidget *page_W; - QWidget *page_WP; - QWidget *page_O; QPushButton *BtnTeamDiscard; QPushButton *BtnTeamSave; QPushButton * BtnTestSound; @@ -176,9 +172,6 @@ public slots: void CBFort_activated(const QString & gravename); -private: - QLabel * LBind[BINDS_NUMBER]; - private slots: void testSound(); }; diff -r 241e3bb6a146 -r 6800f8aa0184 QTfrontend/sdlkeys.h --- a/QTfrontend/sdlkeys.h Mon Oct 12 13:56:07 2009 +0000 +++ b/QTfrontend/sdlkeys.h Mon Oct 12 16:44:30 2009 +0000 @@ -16,135 +16,164 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -char sdlkeys[][2][16] = -{ - {"mousel", "mousel"}, - {"mousem", "mousem"}, - {"mouser", "mouser"}, - {"wheelup", "wheelup"}, - {"wheeldown", "wheeldown"}, - {"backspace", "backspace"}, - {"tab", "tab"}, - {"clear", "clear"}, - {"return", "return"}, - {"pause", "pause"}, - {"escape", "escape"}, - {"space", "space"}, - {"!", "!"}, - {"\"", "\""}, - {"#", "#"}, - {"$", "$"}, - {"&", "&"}, - {"'", "'"}, - {"(", "("}, - {")", ")"}, - {"*", "*"}, - {"+", "+"}, - {",", ","}, - {"-", "-"}, - {".", "."}, - {"/", "/"}, - {"0", "0"}, - {"1", "1"}, - {"2", "2"}, - {"3", "3"}, - {"4", "4"}, - {"5", "5"}, - {"6", "6"}, - {"7", "7"}, - {"8", "8"}, - {"9", "9"}, - {":", ":"}, - {";", ";"}, - {"<", "<"}, - {"=", "="}, - {">", ">"}, - {"?", "?"}, - {"@", "@"}, - {"[", "["}, - {"\\", "\\"}, - {"]", "]"}, - {"^", "^"}, - {"_", "_"}, - {"`", "`"}, - {"a", "a"}, - {"b", "b"}, - {"c", "c"}, - {"d", "d"}, - {"e", "e"}, - {"f", "f"}, - {"g", "g"}, - {"h", "h"}, - {"i", "i"}, - {"j", "j"}, - {"k", "k"}, - {"l", "l"}, - {"m", "m"}, - {"n", "n"}, - {"o", "o"}, - {"p", "p"}, - {"q", "q"}, - {"r", "r"}, - {"s", "s"}, - {"t", "t"}, - {"u", "u"}, - {"v", "v"}, - {"w", "w"}, - {"x", "x"}, - {"y", "y"}, - {"z", "z"}, - {"delete", "delete"}, - {"[0]", "[0]"}, - {"[1]", "[1]"}, - {"[2]", "[2]"}, - {"[3]", "[3]"}, - {"[4]", "[4]"}, - {"[5]", "[5]"}, - {"[6]", "[6]"}, - {"[7]", "[7]"}, - {"[8]", "[8]"}, - {"[9]", "[9]"}, - {"[.]", "[.]"}, - {"[/]", "[/]"}, - {"[*]", "[*]"}, - {"[-]", "[-]"}, - {"[+]", "[+]"}, - {"enter", "enter"}, - {"equals", "equals"}, - {"up", "up"}, - {"down", "down"}, - {"right", "right"}, - {"left", "left"}, - {"insert", "insert"}, - {"home", "home"}, - {"end", "end"}, - {"page up", "page up"}, - {"page down", "page down"}, - {"f1", "f1"}, - {"f2", "f2"}, - {"f3", "f3"}, - {"f4", "f4"}, - {"f5", "f5"}, - {"f6", "f6"}, - {"f7", "f7"}, - {"f8", "f8"}, - {"f9", "f9"}, - {"f10", "f10"}, - {"f11", "f11"}, - {"f12", "f12"}, - {"f13", "f13"}, - {"f14", "f14"}, - {"f15", "f15"}, - {"numlock", "numlock"}, - {"caps_lock", "caps_lock"}, - {"scroll_lock", "scroll_lock"}, - {"right_shift", "right_shift"}, - {"left_shift", "left_shift"}, - {"right_ctrl", "right_ctrl"}, - {"left_ctrl", "left_ctrl"}, - {"right_alt", "right_alt"}, - {"left_alt", "left_alt"}, - {"right_meta", "right_meta"}, - {"left_meta", "left_meta"}, - {"", ""} +char sdlkeys[1024][2][128] = { + {"mousel", QT_TRANSLATE_NOOP("binds (keys)", "Mouse: Left button")}, + {"mousem", QT_TRANSLATE_NOOP("binds (keys)", "Mouse: Middle button")}, + {"mouser", QT_TRANSLATE_NOOP("binds (keys)", "Mouse: Right button")}, + {"wheelup", QT_TRANSLATE_NOOP("binds (keys)", "Mouse: Wheel up")}, + {"wheeldown", QT_TRANSLATE_NOOP("binds (keys)", "Mouse: Wheel down")}, + {"backspace", QT_TRANSLATE_NOOP("binds (keys)", "Backspace")}, + {"tab", QT_TRANSLATE_NOOP("binds (keys)", "Tab")}, + {"clear", QT_TRANSLATE_NOOP("binds (keys)", "Clear")}, + {"return", QT_TRANSLATE_NOOP("binds (keys)", "Return")}, + {"pause", QT_TRANSLATE_NOOP("binds (keys)", "Pause")}, + {"escape", QT_TRANSLATE_NOOP("binds (keys)", "Escape")}, + {"space", QT_TRANSLATE_NOOP("binds (keys)", "Space")}, + {"!", "!"}, + {"\"", "\""}, + {"#", "#"}, + {"$", "$"}, + {"&", "&"}, + {"'", "'"}, + {"(", "("}, + {")", ")"}, + {"*", "*"}, + {"+", "+"}, + {", ", ", "}, + {"-", "-"}, + {".", "."}, + {"/", "/"}, + {"0", "0"}, + {"1", "1"}, + {"2", "2"}, + {"3", "3"}, + {"4", "4"}, + {"5", "5"}, + {"6", "6"}, + {"7", "7"}, + {"8", "8"}, + {"9", "9"}, + {":", ":"}, + {";", ";"}, + {"<", "<"}, + {"=", "="}, + {">", ">"}, + {"?", "?"}, + {"@", "@"}, + {"[", "["}, + {"\\", "\\"}, + {"]", "]"}, + {"^", "^"}, + {"_", "_"}, + {"`", "`"}, + {"a", "A"}, + {"b", "B"}, + {"c", "C"}, + {"d", "D"}, + {"e", "E"}, + {"f", "F"}, + {"g", "G"}, + {"h", "H"}, + {"i", "I"}, + {"j", "J"}, + {"k", "K"}, + {"l", "L"}, + {"m", "M"}, + {"n", "N"}, + {"o", "O"}, + {"p", "P"}, + {"q", "Q"}, + {"r", "R"}, + {"s", "S"}, + {"t", "T"}, + {"u", "U"}, + {"v", "V"}, + {"w", "W"}, + {"x", "X"}, + {"y", "Y"}, + {"z", "Z"}, + {"delete", QT_TRANSLATE_NOOP("binds (keys)", "Delete")}, + {"[0]", QT_TRANSLATE_NOOP("binds (keys)", "Numpad 0")}, + {"[1]", QT_TRANSLATE_NOOP("binds (keys)", "Numpad 1")}, + {"[2]", QT_TRANSLATE_NOOP("binds (keys)", "Numpad 2")}, + {"[3]", QT_TRANSLATE_NOOP("binds (keys)", "Numpad 3")}, + {"[4]", QT_TRANSLATE_NOOP("binds (keys)", "Numpad 4")}, + {"[5]", QT_TRANSLATE_NOOP("binds (keys)", "Numpad 5")}, + {"[6]", QT_TRANSLATE_NOOP("binds (keys)", "Numpad 6")}, + {"[7]", QT_TRANSLATE_NOOP("binds (keys)", "Numpad 7")}, + {"[8]", QT_TRANSLATE_NOOP("binds (keys)", "Numpad 8")}, + {"[9]", QT_TRANSLATE_NOOP("binds (keys)", "Numpad 9")}, + {"[.]", QT_TRANSLATE_NOOP("binds (keys)", "Numpad .")}, + {"[/]", QT_TRANSLATE_NOOP("binds (keys)", "Numpad /")}, + {"[*]", QT_TRANSLATE_NOOP("binds (keys)", "Numpad *")}, + {"[-]", QT_TRANSLATE_NOOP("binds (keys)", "Numpad -")}, + {"[+]", QT_TRANSLATE_NOOP("binds (keys)", "Numpad +")}, + {"enter", QT_TRANSLATE_NOOP("binds (keys)", "Enter")}, + {"equals", QT_TRANSLATE_NOOP("binds (keys)", "Equals")}, + {"up", QT_TRANSLATE_NOOP("binds (keys)", "Up")}, + {"down", QT_TRANSLATE_NOOP("binds (keys)", "Down")}, + {"right", QT_TRANSLATE_NOOP("binds (keys)", "Right")}, + {"left", QT_TRANSLATE_NOOP("binds (keys)", "Left")}, + {"insert", QT_TRANSLATE_NOOP("binds (keys)", "Insert")}, + {"home", QT_TRANSLATE_NOOP("binds (keys)", "Home")}, + {"end", QT_TRANSLATE_NOOP("binds (keys)", "End")}, + {"page up", QT_TRANSLATE_NOOP("binds (keys)", "Page up")}, + {"page down", QT_TRANSLATE_NOOP("binds (keys)", "Page down")}, + {"f1", "F1"}, + {"f2", "F2"}, + {"f3", "F3"}, + {"f4", "F4"}, + {"f5", "F5"}, + {"f6", "F6"}, + {"f7", "F7"}, + {"f8", "F8"}, + {"f9", "F9"}, + {"f10", "F10"}, + {"f11", "F11"}, + {"f12", "F12"}, + {"f13", "F13"}, + {"f14", "F14"}, + {"f15", "F15"}, + {"numlock", QT_TRANSLATE_NOOP("binds (keys)", "Num lock")}, + {"caps_lock", QT_TRANSLATE_NOOP("binds (keys)", "Caps lock")}, + {"scroll_lock", QT_TRANSLATE_NOOP("binds (keys)", "Scroll lock")}, + {"right_shift", QT_TRANSLATE_NOOP("binds (keys)", "Right shift")}, + {"left_shift", QT_TRANSLATE_NOOP("binds (keys)", "Left shift")}, + {"right_ctrl", QT_TRANSLATE_NOOP("binds (keys)", "Right ctrl")}, + {"left_ctrl", QT_TRANSLATE_NOOP("binds (keys)", "Left ctrl")}, + {"right_alt", QT_TRANSLATE_NOOP("binds (keys)", "Right alt")}, + {"left_alt", QT_TRANSLATE_NOOP("binds (keys)", "Left alt")}, + {"right_meta", QT_TRANSLATE_NOOP("binds (keys)", "Right meta")}, + {"left_meta", QT_TRANSLATE_NOOP("binds (keys)", "Left meta")} + }; + +// button name definitions for Microsoft's XBox360 controller +// don't modify button order! +char xb360buttons[][128] = { + QT_TRANSLATE_NOOP("binds (keys)", "A button"), + QT_TRANSLATE_NOOP("binds (keys)", "B button"), + QT_TRANSLATE_NOOP("binds (keys)", "X button"), + QT_TRANSLATE_NOOP("binds (keys)", "Y button"), + QT_TRANSLATE_NOOP("binds (keys)", "LB button"), + QT_TRANSLATE_NOOP("binds (keys)", "RB button"), + QT_TRANSLATE_NOOP("binds (keys)", "Back button"), + QT_TRANSLATE_NOOP("binds (keys)", "Start button"), + QT_TRANSLATE_NOOP("binds (keys)", "Left stick"), + QT_TRANSLATE_NOOP("binds (keys)", "Right stick") }; + +// axis name definitions for Microsoft's XBox360 controller +// don't modify axis order! +char xbox360axes[][128] = { + QT_TRANSLATE_NOOP("binds (keys)", "Left stick (Right)"), + QT_TRANSLATE_NOOP("binds (keys)", "Left stick (Left)"), + QT_TRANSLATE_NOOP("binds (keys)", "Left stick (Down)"), + QT_TRANSLATE_NOOP("binds (keys)", "Left stick (Up)"), + QT_TRANSLATE_NOOP("binds (keys)", "Left trigger"), + QT_TRANSLATE_NOOP("binds (keys)", "Right trigger"), + QT_TRANSLATE_NOOP("binds (keys)", "Right stick (Down)"), + QT_TRANSLATE_NOOP("binds (keys)", "Right stick (Up)"), + QT_TRANSLATE_NOOP("binds (keys)", "Right stick (Right)"), + QT_TRANSLATE_NOOP("binds (keys)", "Right stick (Left)"), +}; +char xb360dpad[128] = QT_TRANSLATE_NOOP("binds (keys)", "DPad"); diff -r 241e3bb6a146 -r 6800f8aa0184 QTfrontend/team.cpp --- a/QTfrontend/team.cpp Mon Oct 12 13:56:07 2009 +0000 +++ b/QTfrontend/team.cpp Mon Oct 12 16:44:30 2009 +0000 @@ -214,7 +214,7 @@ for(int i = 0; i < BINDS_NUMBER; i++) { - hwform->ui.pageEditTeam->CBBind[i]->setCurrentIndex(hwform->ui.pageEditTeam->CBBind[i]->findText(binds[i].strbind)); + hwform->ui.pageEditTeam->CBBind[i]->setCurrentIndex(hwform->ui.pageEditTeam->CBBind[i]->findData(binds[i].strbind)); } } @@ -233,7 +233,7 @@ Voicepack = hwform->ui.pageEditTeam->CBVoicepack->currentText(); for(int i = 0; i < BINDS_NUMBER; i++) { - binds[i].strbind = hwform->ui.pageEditTeam->CBBind[i]->currentText(); + binds[i].strbind = hwform->ui.pageEditTeam->CBBind[i]->itemData(hwform->ui.pageEditTeam->CBBind[i]->currentIndex()).toString(); } } @@ -251,7 +251,8 @@ if (!m_isNetTeam) for(int i = 0; i < BINDS_NUMBER; i++) - sl.push_back(QString("ebind " + binds[i].strbind + " " + binds[i].action)); + if(!binds[i].strbind.isEmpty()) + sl.push_back(QString("ebind " + binds[i].strbind + " " + binds[i].action)); for (int t = 0; t < numHedgehogs; t++) { diff -r 241e3bb6a146 -r 6800f8aa0184 hedgewars/CCHandlers.inc --- a/hedgewars/CCHandlers.inc Mon Oct 12 13:56:07 2009 +0000 +++ b/hedgewars/CCHandlers.inc Mon Oct 12 16:44:30 2009 +0000 @@ -184,6 +184,46 @@ else CurrentTeam^.Binds[b]:= s end; +procedure chCurU_p(var s: shortstring); +begin +CursorMovementY:= -1; +end; + +procedure chCurU_m(var s: shortstring); +begin +CursorMovementY:= 0; +end; + +procedure chCurD_p(var s: shortstring); +begin +CursorMovementY:= 1; +end; + +procedure chCurD_m(var s: shortstring); +begin +CursorMovementY:= 0; +end; + +procedure chCurL_p(var s: shortstring); +begin +CursorMovementX:= -1; +end; + +procedure chCurL_m(var s: shortstring); +begin +CursorMovementX:= 0; +end; + +procedure chCurR_p(var s: shortstring); +begin +CursorMovementX:= 1; +end; + +procedure chCurR_m(var s: shortstring); +begin +CursorMovementX:= 0; +end; + procedure chLeft_p(var s: shortstring); begin if CheckNoTeamOrHH then exit; @@ -576,10 +616,13 @@ end; SDL_WM_SetCaption('Hedgewars', nil); -{$IFDEF DEBUGFILE} -AddFileLog('Freeing old primary surface...'); -{$ENDIF} -if SDLPrimSurface <> nil then SDL_FreeSurface(SDLPrimSurface); +if SDLPrimSurface <> nil then + begin + {$IFDEF DEBUGFILE} + AddFileLog('Freeing old primary surface...'); + {$ENDIF} + SDL_FreeSurface(SDLPrimSurface); + end; {$IFDEF DARWIN} //remove the topbar from Mac and iPhone diff -r 241e3bb6a146 -r 6800f8aa0184 hedgewars/GSHandlers.inc --- a/hedgewars/GSHandlers.inc Mon Oct 12 13:56:07 2009 +0000 +++ b/hedgewars/GSHandlers.inc Mon Oct 12 16:44:30 2009 +0000 @@ -2130,7 +2130,9 @@ begin AllInactive:= false; -if Gear^.Timer > 0 then dec(Gear^.Timer); +if ((TrainingFlags and tfRCPlane) = 0) and (Gear^.Timer > 0) then dec(Gear^.Timer); + +if ((TrainingFlags and tfRCPlane) <> 0) and ((TrainingFlags and tfTimeTrial) <> 0 ) and (TimeTrialStartTime = 0) then TimeTrialStartTime:= RealTicks; HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; FollowGear:= Gear; @@ -2172,37 +2174,87 @@ Gear^.X:= Gear^.X + Gear^.dX; Gear^.Y:= Gear^.Y + Gear^.dY; -if (GameTicks and $FF) = 0 then - if Gear^.Timer < 3500 then - AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtEvilTrace, 0, _0, _0, 0) - else +if (TrainingFlags and tfRCPlane) = 0 then + begin + if (GameTicks and $FF) = 0 then + if Gear^.Timer < 3500 then + AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtEvilTrace, 0, _0, _0, 0) + else + AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, _0, _0, 0); + + if ((HHGear^.Message and gm_Attack) <> 0) and (Gear^.Health <> 0) then + begin + HHGear^.Message := HHGear^.Message and not gm_Attack; + AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAirBomb, 0, Gear^.dX * _0_5, Gear^.dY * _0_5, 0); + dec(Gear^.Health) + end; + + if ((HHGear^.Message and gm_LJump) <> 0) + and ((Gear^.State and gsttmpFlag) = 0) then + begin + Gear^.State:= Gear^.State or gsttmpFlag; + PauseMusic; + playSound(sndRideOfTheValkyries, false, nil); + end; + + // pickup bonuses + t:= CheckGearNear(Gear, gtCase, 36, 36); + if t <> nil then + PickUp(HHGear, t); + end +else + begin + if (GameTicks and $FF) = 0 then AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, _0, _0, 0); -if ((HHGear^.Message and gm_Attack) <> 0) and (Gear^.Health <> 0) then - begin - HHGear^.Message := HHGear^.Message and not gm_Attack; - AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAirBomb, 0, Gear^.dX * _0_5, Gear^.dY * _0_5, 0); - dec(Gear^.Health) - end; + // pickup targets + t:= CheckGearNear(Gear, gtTarget, 36, 36); + if t <> nil then + begin; + // TODO: Sound! + PlaySound(sndGraveImpact, false, nil); + DeleteGear(t); + TrainingTargetGear:= AddGear(0, 0, gtTarget, 0, _0, _0, 0); + FindPlace(TrainingTargetGear, false, 0, LAND_WIDTH); + inc(TurnTimeLeft, TrainingTimeInc); + + if TrainingTimeInc > TrainingTimeInM then + dec(TrainingTimeInc, TrainingTimeInD); + if TurnTimeLeft > TrainingTimeMax then TurnTimeLeft:= TrainingTimeMax; + end; -if ((HHGear^.Message and gm_LJump) <> 0) - and ((Gear^.State and gsttmpFlag) = 0) then - begin - Gear^.State:= Gear^.State or gsttmpFlag; - PauseMusic; - playSound(sndRideOfTheValkyries, false, nil); - end; + if (TurnTimeLeft > 0) then + dec(TurnTimeLeft) + else + begin + if ((TrainingFlags and tfTimeTrial) <>0) and (TimeTrialStopTime = 0) then TimeTrialStopTime:= RealTicks; + StopSound(sndRCPlane); + ResumeMusic; + doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 25, EXPLAutoSound); + for i:= 0 to 32 do + begin + dX:= AngleCos(i * 64) * _0_5 * (GetRandom + _1); + dY:= AngleSin(i * 64) * _0_5 * (GetRandom + _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; + DeleteGear(Gear); + AfterAttack; + TurnTimeLeft:= 0; + CurAmmoGear:= nil; + HHGear^.Message:= 0; + ParseCommand('/taunt '#1, true); + exit; + end; -// pickup bonuses -t:= CheckGearNear(Gear, gtCase, 36, 36); -if t <> nil then - PickUp(HHGear, t); - + end; + CheckCollision(Gear); if ((Gear^.State and gstCollision) <> 0) or CheckGearDrowning(Gear) then begin + if ((TrainingFlags and tfRCPlane) <> 0) and ((TrainingFlags and tfTimeTrial) <> 0 ) and (TimeTrialStopTime = 0) then TimeTrialStopTime:= RealTicks; StopSound(sndRCPlane); StopSound(sndRideOfTheValkyries); ResumeMusic; diff -r 241e3bb6a146 -r 6800f8aa0184 hedgewars/HHHandlers.inc --- a/hedgewars/HHHandlers.inc Mon Oct 12 13:56:07 2009 +0000 +++ b/hedgewars/HHHandlers.inc Mon Oct 12 16:44:30 2009 +0000 @@ -43,14 +43,14 @@ inc(i); TryDo(i < 2, 'Engine bug: no ammo in current slot', true) end; - until (Ammo^[slot, CurAmmo].Count > 0) and (Team^.Clan^.TurnNumber > Ammoz[Ammo^[slot, CurAmmo].AmmoType].SkipTurns) + until (Ammo^[slot, CurAmmo].Count > 0) and ((Team^.Clan^.TurnNumber > Ammoz[Ammo^[slot, CurAmmo].AmmoType].SkipTurns) or ((TrainingFlags and tfIgnoreDelays) <> 0)) end else begin i:= 0; // check whether there is ammo in slot while (i <= cMaxSlotAmmoIndex) and ((Ammo^[slot, i].Count = 0) - or (Team^.Clan^.TurnNumber <= Ammoz[Ammo^[slot, i].AmmoType].SkipTurns)) do inc(i); + or ((Team^.Clan^.TurnNumber <= Ammoz[Ammo^[slot, i].AmmoType].SkipTurns) and ((TrainingFlags and tfIgnoreDelays) = 0))) do inc(i); if i <= cMaxSlotAmmoIndex then begin @@ -67,7 +67,7 @@ begin weap:= TAmmoType(Gear^.MsgParam); -if PHedgehog(Gear^.Hedgehog)^.Team^.Clan^.TurnNumber <= Ammoz[weap].SkipTurns then exit; // weapon is not activated yet +if (PHedgehog(Gear^.Hedgehog)^.Team^.Clan^.TurnNumber <= Ammoz[weap].SkipTurns) and ((TrainingFlags and tfIgnoreDelays) = 0) then exit; // weapon is not activated yet Gear^.MsgParam:= Ammoz[weap].Slot; @@ -164,7 +164,7 @@ PlaySound(sndWhipCrack, false, nil) end; amBaseballBat: begin - CurAmmoGear:= AddGear(hwRound(X) + hwSign(dX) * 10, hwRound(Y), gtShover, 0, xx * _0_5, yy * _0_5, 0); + CurAmmoGear:= AddGear(hwRound(X) + hwSign(dX) * 10, hwRound(Y), gtShover, gsttmpFlag, xx * _0_5, yy * _0_5, 0); PlaySound(sndBaseballBat, false, nil); end; amParachute: CurAmmoGear:= AddGear(hwRound(X), hwRound(Y), gtParachute, 0, _0, _0, 0); @@ -297,6 +297,7 @@ procedure PickUp(HH, Gear: PGear); var s: shortstring; a: TAmmoType; + i: Integer; begin Gear^.Message:= gm_Destroy; case Gear^.Pos of @@ -318,7 +319,14 @@ s:= '+' + s; AddCaption(s, PHedgehog(HH^.Hedgehog)^.Team^.Clan^.Color, capgrpAmmoinfo); RenderHealth(PHedgehog(HH^.Hedgehog)^); - RecountTeamHealth(PHedgehog(HH^.Hedgehog)^.Team) + RecountTeamHealth(PHedgehog(HH^.Hedgehog)^.Team); + + i:= 0; + while i < Gear^.Health do + begin + AddVisualGear(hwRound(HH^.X), hwRound(HH^.Y), vgtHealth); + inc(i, 5); + end; end; end end; @@ -543,7 +551,22 @@ end; CheckGearDrowning(Gear); if (Gear^.State and gstDrowning) <> 0 then isCursorVisible:= false - end + end; + +if (hwAbs(Gear^.dY) > _0) and (Gear^.FlightTime > 0) then + begin + inc(Gear^.FlightTime, 1); + if Gear^.FlightTime = 2000 then + begin + AddCaption(GetEventString(eidHomerun), $FFFFFF, capgrpMessage); + PlaySound(sndHomerun, false, nil) + end; + end +else + begin + Gear^.FlightTime:= 0; + end; + end; procedure doStepHedgehogDriven(Gear: PGear); diff -r 241e3bb6a146 -r 6800f8aa0184 hedgewars/SDLh.pas --- a/hedgewars/SDLh.pas Mon Oct 12 13:56:07 2009 +0000 +++ b/hedgewars/SDLh.pas Mon Oct 12 16:44:30 2009 +0000 @@ -63,6 +63,7 @@ SDL_SRCALPHA = $00010000; SDL_INIT_VIDEO = $00000020; SDL_INIT_AUDIO = $00000010; + SDL_INIT_JOYSTICK = $00000200; SDL_APPINPUTFOCUS=$00000010; @@ -96,8 +97,8 @@ SDL_NOEVENT = 0; SDL_KEYDOWN = 2; SDL_KEYUP = 3; - SDL_QUITEV = 12; - SDL_VIDEORESIZE = 16; + //SDL_QUITEV = 12; + SDL_VIDEORESIZE = 16; // TODO: outdated? no longer in SDL 1.3? {$IFDEF SDL13} SDL_WINDOWEVENT = 1; @@ -106,12 +107,22 @@ SDL_MOUSEBUTTONDOWN = 6; SDL_MOUSEBUTTONUP = 7; SDL_MOUSEWHEEL = 8; //different handling, should create SDL_MouseWheelEvent type + SDL_JOYAXIS = 10; + SDL_JOYHAT = 12; + SDL_JOYBUTTONDOWN = 13; + SDL_JOYBUTTONUP = 14; + SDL_QUITEV = 15; {$ELSE} SDL_ACTIVEEVENT = 1; SDL_MOUSEBUTTONDOWN = 5; SDL_MOUSEBUTTONUP = 6; SDL_BUTTON_WHEELDUP = 4; SDL_BUTTON_WHEELDOWN = 5; + SDL_JOYAXIS = 7; + SDL_JOYHAT = 9; + SDL_JOYBUTTONDOWN = 10; + SDL_JOYBUTTONUP = 11; + SDL_QUITEV = 12; {$ENDIF} {*end sdl_event binding*} @@ -283,7 +294,28 @@ w, h: LongInt; end; - PSDL_Event = ^TSDL_Event; + TSDL_JoyAxisEvent = record + type_: Byte; + which: Byte; + axis: Byte; + value: LongInt; + end; + + TSDL_JoyHatEvent = record + type_: Byte; + which: Byte; + hat: Byte; + value: Byte; + end; + + TSDL_JoyButtonEvent = record + type_: Byte; + which: Byte; + button: Byte; + state: Byte; + end; + + PSDL_Event = ^TSDL_Event; TSDL_Event = record case Byte of {$IFDEF SDL13} @@ -306,6 +338,10 @@ SDL_MOUSEBUTTONDOWN, SDL_MOUSEBUTTONUP: (button: TSDL_MouseButtonEvent); {$ENDIF} + SDL_JOYAXIS: (jaxis: TSDL_JoyAxisEvent); + SDL_JOYHAT: (jhat: TSDL_JoyHatEvent); + SDL_JOYBUTTONDOWN, + SDL_JOYBUTTONUP: (jbutton: TSDL_JoyButtonEvent); end; PByteArray = ^TByteArray; @@ -365,6 +401,7 @@ function SDL_GetKeyName(key: Longword): PChar; cdecl; external SDLLibName; procedure SDL_WarpMouse(x, y: Word); cdecl; external SDLLibName; +procedure SDL_PumpEvents; cdecl; external SDLLibName; function SDL_PollEvent(event: PSDL_Event): LongInt; cdecl; external SDLLibName; function SDL_ShowCursor(toggle: LongInt): LongInt; cdecl; external SDLLibName; @@ -490,6 +527,37 @@ function SDLNet_Read16(buf: pointer): Word; function SDLNet_Read32(buf: pointer): LongWord; +// Joystick/Controller support +type PSDLJoystick = ^TSDLJoystick; + TSDLJoystick = record + end; + +function SDL_NumJoysticks: LongInt; cdecl; external SDLLibName; +function SDL_JoystickName(idx: LongInt): PChar; cdecl; external SDLLibName; +function SDL_JoystickOpen(idx: LongInt): PSDLJoystick; cdecl; external SDLLibName; +function SDL_JoystickOpened(idx: LongInt): LongInt; cdecl; external SDLLibName; +function SDL_JoystickIndex(joy: PSDLJoystick): LongInt; cdecl; external SDLLibName; +function SDL_JoystickNumAxes(joy: PSDLJoystick): LongInt; cdecl; external SDLLibName; +function SDL_JoystickNumBalls(joy: PSDLJoystick): LongInt; cdecl; external SDLLibName; +function SDL_JoystickNumHats(joy: PSDLJoystick): LongInt; cdecl; external SDLLibName; +function SDL_JoystickNumButtons(joy: PSDLJoystick): LongInt; cdecl; external SDLLibName; +procedure SDL_JoystickUpdate; cdecl; external SDLLibName; +function SDL_JoystickEventState(state: LongInt): LongInt; cdecl; external SDLLibName; +function SDL_JoystickGetAxis(joy: PSDLJoystick; axis: LongInt): Word; cdecl; external SDLLibName; +const SDL_HAT_CENTERED = $00; + SDL_HAT_UP = $01; + SDL_HAT_RIGHT = $02; + SDL_HAT_DOWN = $04; + SDL_HAT_LEFT = $08; + SDL_HAT_RIGHTUP = SDL_HAT_RIGHT or SDL_HAT_UP; + SDL_HAT_RIGHTDOWN = SDL_HAT_RIGHT or SDL_HAT_DOWN; + SDL_HAT_LEFTUP = SDL_HAT_LEFT or SDL_HAT_UP; + SDL_HAT_LEFTDOWN = SDL_HAT_LEFT or SDL_HAT_DOWN; +function SDL_JoystickGetBall(joy: PSDLJoystick; ball: LongInt; dx: PInteger; dy: PInteger): Word; cdecl; external SDLLibName; +function SDL_JoystickGetHat(joy: PSDLJoystick; hat: LongInt): Byte; cdecl; external SDLLibName; +function SDL_JoystickGetButton(joy: PSDLJoystick; button: LongInt): Byte; cdecl; external SDLLibName; +procedure SDL_JoystickClose(joy: PSDLJoystick); cdecl; external SDLLibName; + implementation function SDL_MustLock(Surface: PSDL_Surface): Boolean; diff -r 241e3bb6a146 -r 6800f8aa0184 hedgewars/hwengine.pas --- a/hedgewars/hwengine.pas Mon Oct 12 13:56:07 2009 +0000 +++ b/hedgewars/hwengine.pas Mon Oct 12 16:44:30 2009 +0000 @@ -89,7 +89,7 @@ AssignHHCoords; AddMiscGears; StoreLoad; - InitWorld; + InitWorld; ResetKbd; SoundLoad; if GameType = gmtSave then @@ -182,6 +182,10 @@ SDL_MOUSEBUTTONDOWN: if event.button.button = SDL_BUTTON_WHEELDOWN then uKeys.wheelDown:= true; SDL_MOUSEBUTTONUP: if event.button.button = SDL_BUTTON_WHEELDUP then uKeys.wheelUp:= true; {$ENDIF} + SDL_JOYAXIS: ControllerAxisEvent(event.jaxis.which, event.jaxis.axis, event.jaxis.value); + SDL_JOYHAT: ControllerHatEvent(event.jhat.which, event.jhat.hat, event.jhat.value); + SDL_JOYBUTTONDOWN: ControllerButtonEvent(event.jbutton.which, event.jbutton.button, true); + SDL_JOYBUTTONUP: ControllerButtonEvent(event.jbutton.which, event.jbutton.button, false); SDL_QUITEV: isTerminated:= true end; CurrTime:= SDL_GetTicks; @@ -388,7 +392,7 @@ var s: shortstring; begin WriteToConsole('Init SDL... '); -SDLTry(SDL_Init(SDL_INIT_VIDEO) >= 0, true); +SDLTry(SDL_Init(SDL_INIT_VIDEO or SDL_INIT_JOYSTICK) >= 0, true); WriteLnToConsole(msgOK); SDL_EnableUNICODE(1); @@ -399,6 +403,7 @@ ShowMainWindow; +ControllerInit; // has to happen before InitKbdKeyTable to map keys InitKbdKeyTable; if recordFileName = '' then InitIPC; @@ -431,7 +436,8 @@ 'Some parameters not set (flags = ' + inttostr(InitStepsFlags) + ')', true); -MainLoop +MainLoop; +ControllerClose end; ///////////////////////// diff -r 241e3bb6a146 -r 6800f8aa0184 hedgewars/uConsole.pas --- a/hedgewars/uConsole.pas Mon Oct 12 13:56:07 2009 +0000 +++ b/hedgewars/uConsole.pas Mon Oct 12 16:44:30 2009 +0000 @@ -244,6 +244,7 @@ RegisterVariable('damagepct', vtLongInt, @cDamagePercent, false); RegisterVariable('landadds', vtLongInt, @cLandAdditions , false); RegisterVariable('gmflags' , vtLongInt, @GameFlags , false); +RegisterVariable('trflags' , vtLongInt, @TrainingFlags , false); RegisterVariable('turntime', vtLongInt, @cHedgehogTurnTime, false); RegisterVariable('minestime', vtLongInt, @cMinesTime, false); RegisterVariable('fort' , vtCommand, @chFort , false); @@ -297,6 +298,14 @@ 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 ); finalization FreeVariablesList diff -r 241e3bb6a146 -r 6800f8aa0184 hedgewars/uConsts.pas --- a/hedgewars/uConsts.pas Mon Oct 12 13:56:07 2009 +0000 +++ b/hedgewars/uConsts.pas Mon Oct 12 16:44:30 2009 +0000 @@ -64,7 +64,7 @@ sprSpeechCorner, sprSpeechEdge, sprSpeechTail, sprThoughtCorner, sprThoughtEdge, sprThoughtTail, sprShoutCorner, sprShoutEdge, sprShoutTail, - sprSniperRifle, sprBubbles, sprJetpack); + sprSniperRifle, sprBubbles, sprJetpack, sprHealth); TGearType = (gtAmmo_Bomb, gtHedgehog, gtAmmo_Grenade, gtHealthTag, // 3 gtGrave, gtUFO, gtShotgunShot, gtPickHammer, gtRope, // 8 @@ -79,7 +79,7 @@ TVisualGearType = (vgtFlake, vgtCloud, vgtExplPart, vgtExplPart2, vgtFire, vgtSmallDamageTag, vgtTeamHealthSorter, vgtSpeechBubble, vgtBubble, - vgtSteam); + vgtSteam, vgtHealth); TGearsType = set of TGearType; @@ -94,7 +94,8 @@ sndFirePunch3, sndFirePunch4, sndFirePunch5, sndFirePunch6, sndMelon, sndHellish, sndYoohoo, sndRCPlane, sndWhipCrack, sndRideOfTheValkyries, sndDenied, sndPlaced, sndBaseballBat, - sndVaporize, sndWarp, sndSuddenDeath, sndMortar, sndShutter); + sndVaporize, sndWarp, sndSuddenDeath, sndMortar, sndShutter, + sndHomerun); TAmmoType = (amNothing, amGrenade, amClusterBomb, amBazooka, amUFO, amShotgun, amPickHammer, amSkip, amRope, amMine, amDEagle, amDynamite, amFirePunch, amWhip, @@ -244,6 +245,13 @@ cSendEmptyPacketTime = 1000; + // Training Flags + tfNone = $00000000; + tfTimeTrial = $00000001; + tfRCPlane = $00000002; + tfSpawnTargets = $00000004; + tfIgnoreDelays = $00000008; + gfForts = $00000001; gfMultiWeapon = $00000002; gfSolidLand = $00000004; @@ -604,7 +612,9 @@ (FileName: 'Bubbles'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil; Width: 16; Height: 16; imageWidth: 0; imageHeight: 0; saveSurf: false), // sprBubbles (FileName: 'amJetpack'; Path: ptHedgehog; AltPath: ptNone; Texture: nil; Surface: nil; - Width: 64; Height: 64; imageWidth: 0; imageHeight: 0; saveSurf: false) // sprJetpack + Width: 64; Height: 64; imageWidth: 0; imageHeight: 0; saveSurf: false), // sprJetpack + (FileName: 'Health'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil; + Width: 16; Height: 16; imageWidth: 0; imageHeight: 0; saveSurf: false) // sprHealth ); Wavez: array [TWave] of record @@ -682,7 +692,8 @@ (FileName: 'warp.ogg'; Path: ptSounds),// sndWarp (FileName: 'suddendeath.ogg'; Path: ptSounds),// sndSuddenDeath (FileName: 'mortar.ogg'; Path: ptSounds),// sndMortar - (FileName: 'shutterclick.ogg'; Path: ptSounds) // sndShutter + (FileName: 'shutterclick.ogg'; Path: ptSounds),// sndShutter + (FileName: 'homerun.ogg'; Path: ptSounds) // sndHomerun ); Ammoz: array [TAmmoType] of record diff -r 241e3bb6a146 -r 6800f8aa0184 hedgewars/uGears.pas --- a/hedgewars/uGears.pas Mon Oct 12 13:56:07 2009 +0000 +++ b/hedgewars/uGears.pas Mon Oct 12 16:44:30 2009 +0000 @@ -54,6 +54,7 @@ Z: Longword; IntersectGear: PGear; TriggerId: Longword; + FlightTime: Longword; uid: Longword end; @@ -76,6 +77,7 @@ SuddenDeathDmg: Boolean = false; SpeechType: Longword = 1; SpeechText: shortstring; + TrainingTargetGear: PGear = nil; implementation uses uWorld, uMisc, uStore, uConsole, uSound, uTeams, uRandom, uCollisions, @@ -224,6 +226,7 @@ Result^.CollisionIndex:= -1; Result^.Timer:= Timer; Result^.Z:= cUsualZ; +Result^.FlightTime:= 0; Result^.uid:= Counter; if CurrentTeam <> nil then @@ -697,7 +700,8 @@ procedure ApplyDamage(Gear: PGear; Damage: Longword); var s: shortstring; - vampDmg, tmpDmg: Longword; + vampDmg, tmpDmg, i: Longword; + vg: PVisualGear; begin if (Gear^.Kind = gtHedgehog) and (Damage>=1) then begin @@ -718,6 +722,13 @@ AddCaption(s, CurrentHedgehog^.Team^.Clan^.Color, capgrpAmmoinfo); RenderHealth(CurrentHedgehog^); RecountTeamHealth(CurrentHedgehog^.Team); + i:= 0; + while i < vampDmg do + begin + vg:= AddVisualGear(hwRound(CurrentHedgehog^.Gear^.X), hwRound(CurrentHedgehog^.Gear^.Y), vgtHealth); + if vg <> nil then vg^.Frame:= 10; + inc(i, 5); + end; end end; if ((GameFlags and gfKarma) <> 0) and @@ -1249,13 +1260,17 @@ if Gear^.Invulnerable then begin - DrawSprite(sprInvulnerable, sx - 24, sy - 24, 0); + glColor4f(1, 1, 1, 0.25 + abs(1 - ((RealTicks div 2) mod 1500) / 750)); + DrawSprite(sprInvulnerable, sx - 24, sy - 24, 0); + glColor4f(1, 1, 1, 1); end; if cVampiric and (CurrentHedgehog^.Gear <> nil) and (CurrentHedgehog^.Gear = Gear) then begin + glColor4f(1, 1, 1, 0.25 + abs(1 - (RealTicks mod 1500) / 750)); DrawSprite(sprVampiric, sx - 24, sy - 24, 0); + glColor4f(1, 1, 1, 1); end; end; @@ -1402,11 +1417,14 @@ case Gear^.Kind of gtAmmo_Bomb: DrawRotated(sprBomb, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, 0, Gear^.DirAngle); - gtRCPlane: if (Gear^.Tag = -1) then + gtRCPlane: begin + if (Gear^.Tag = -1) then DrawRotated(sprPlane, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, -1, DxDy2Angle(Gear^.dX, Gear^.dY) + 90) else DrawRotated(sprPlane, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy,0,DxDy2Angle(Gear^.dY, Gear^.dX)); - + if ((TrainingFlags and tfRCPlane) <> 0) and (TrainingTargetGear <> nil) and ((Gear^.State and gstDrowning) = 0) then + DrawRotatedf(sprFinger, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, GameTicks div 32 mod 16, 0, DxDy2Angle(Gear^.X - TrainingTargetGear^.X, TrainingTargetGear^.Y - Gear^.Y)); + end; gtBall: DrawRotatedf(sprBalls, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, Gear^.Tag,0, DxDy2Angle(Gear^.dY, Gear^.dX)); gtDrill: DrawRotated(sprDrill, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, 0, DxDy2Angle(Gear^.dY, Gear^.dX)); @@ -1496,6 +1514,12 @@ begin AddGear(0, 0, gtATStartGame, 0, _0, _0, 2000); +if (TrainingFlags and tfSpawnTargets) <> 0 then + begin + TrainingTargetGear:= AddGear(0, 0, gtTarget, 0, _0, _0, 0); + FindPlace(TrainingTargetGear, false, 0, LAND_WIDTH); + end; + if ((GameFlags and gfForts) = 0) and ((GameFlags and gfMines) <> 0) then for i:= 0 to Pred(cLandAdditions) do begin @@ -1642,9 +1666,12 @@ while i > 0 do begin dec(i); - Gear:= t^.ar[i]; - if (Gear^.State and gstNoDamage) = 0 then - case Gear^.Kind of + Gear:= t^.ar[i]; + if (Gear^.State and gstNoDamage) = 0 then + begin + if (Gear^.Kind = gtHedgehog) and (Ammo^.State and gsttmpFlag <> 0) then Gear^.FlightTime:= 1; + + case Gear^.Kind of gtHedgehog, gtMine, gtTarget, @@ -1675,6 +1702,7 @@ FollowGear:= Gear end; end + end; end; if i <> 0 then SetAllToActive end; @@ -1977,4 +2005,4 @@ finalization FreeGearsList; -end. +end. \ No newline at end of file diff -r 241e3bb6a146 -r 6800f8aa0184 hedgewars/uKeys.pas --- a/hedgewars/uKeys.pas Mon Oct 12 13:56:07 2009 +0000 +++ b/hedgewars/uKeys.pas Mon Oct 12 16:44:30 2009 +0000 @@ -32,10 +32,27 @@ procedure SetBinds(var binds: TBinds); procedure SetDefaultBinds; -var KbdKeyPressed: boolean; +procedure ControllerInit; +procedure ControllerClose; +procedure ControllerAxisEvent(joy, axis: Byte; value: Integer); +procedure ControllerHatEvent(joy, hat, value: Byte); +procedure ControllerButtonEvent(joy, button: Byte; pressed: Boolean); + +var hideAmmoMenu: boolean; wheelUp: boolean = false; wheelDown: boolean = false; + ControllerNumControllers: Integer; + ControllerEnabled: Integer; + ControllerNumAxes: array[0..5] of Integer; + //ControllerNumBalls: array[0..5] of Integer; + ControllerNumHats: array[0..5] of Integer; + ControllerNumButtons: array[0..5] of Integer; + ControllerAxes: array[0..5] of array[0..19] of Integer; + //ControllerBalls: array[0..5] of array[0..19] of array[0..1] of Integer; + ControllerHats: array[0..5] of array[0..19] of Byte; + ControllerButtons: array[0..5] of array[0..19] of Byte; + implementation uses SDLh, uTeams, uConsole, uMisc, uStore; const KeyNumber = 1024; @@ -53,17 +70,22 @@ KeyNameToCode:= Result end; + procedure ProcessKbd; -var i: LongInt; - s: shortstring; +var i, j, k: LongInt; pkbd: PByteArray; Trusted: boolean; + s: shortstring; begin -KbdKeyPressed:= false; + +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); {$IFDEF SDL13} pkbd := SDL_GetKeyboardState(nil); i := SDL_GetMouseState(0, nil, nil); @@ -71,7 +93,6 @@ pkbd := SDL_GetKeyState(nil); i := SDL_GetMouseState(nil, nil); {$ENDIF} - // mouse buttons {$IFDEF DARWIN} pkbd^[1]:= ((i and 1) and not (pkbd^[306] or pkbd^[305])); @@ -88,11 +109,36 @@ wheelUp:= false; wheelDown:= false; +// Controller(s) +k:= 500; // 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 pkbd^[k + 0]:= 1 else pkbd^[k + 0]:= 0; + if ControllerAxes[j][i] < -20000 then pkbd^[k + 1]:= 1 else pkbd^[k + 1]:= 0; + inc(k, 2); + end; + for i:= 0 to Pred(ControllerNumHats[j]) do + begin + pkbd^[k + 0]:= ControllerHats[j][i] and SDL_HAT_UP; + pkbd^[k + 1]:= ControllerHats[j][i] and SDL_HAT_RIGHT; + pkbd^[k + 2]:= ControllerHats[j][i] and SDL_HAT_DOWN; + pkbd^[k + 3]:= ControllerHats[j][i] and SDL_HAT_LEFT; + inc(k, 4); + end; + for i:= 0 to Pred(ControllerNumButtons[j]) do + begin + pkbd^[k]:= ControllerButtons[j][i]; + inc(k, 1); + end; + end; + // now process strokes for i:= 1 to cKeyMaxIndex do if CurrentBinds[i][0] <> #0 then begin - if (i > 3) and (pkbd^[i] <> 0) then KbdKeyPressed:= true; + if (i > 3) and (pkbd^[i] <> 0) and not (hideAmmoMenu or (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 (pkbd^[i] <> 0) then ParseCommand(CurrentBinds[i], Trusted) else if (CurrentBinds[i][1] = '+') and (pkbd^[i] = 0) @@ -103,11 +149,11 @@ ParseCommand(s, Trusted) end; tkbd[i]:= pkbd^[i] - end + end; end; procedure ResetKbd; -var i, t: LongInt; +var i, j, k, t: LongInt; pkbd: PByteArray; begin @@ -118,12 +164,36 @@ {$ENDIF} TryDo(i < cKeyMaxIndex, 'SDL keys number is more than expected (' + inttostr(i) + ')', true); +k:= 500; +for j:= 0 to Pred(ControllerNumControllers) do + begin + for i:= 0 to Pred(ControllerNumAxes[j]) do + begin + pkbd^[k + 0]:= 0; + pkbd^[k + 1]:= 0; + inc(k, 2); + end; + for i:= 0 to Pred(ControllerNumHats[j]) do + begin + pkbd^[k + 0]:= 0; + pkbd^[k + 1]:= 0; + pkbd^[k + 2]:= 0; + pkbd^[k + 3]:= 0; + inc(k, 4); + end; + for i:= 0 to Pred(ControllerNumButtons[j]) do + begin + pkbd^[k]:= 0; + inc(k, 1); + end; + end; + for t:= 0 to Pred(i) do tkbd[i]:= pkbd^[i] end; procedure InitKbdKeyTable; -var i, t: LongInt; +var i, j, k, t: LongInt; s: string[15]; begin KeyNames[1]:= 'mousel'; @@ -144,6 +214,31 @@ end; end; +// Controller(s) +k:= 500; +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'; @@ -182,6 +277,87 @@ tkbd[271]:= 1 end; +var Controller: array [0..5] of PSDLJoystick; + +procedure ControllerInit; +var i, j: Integer; +begin +ControllerEnabled:= 0; +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; + initialization end. diff -r 241e3bb6a146 -r 6800f8aa0184 hedgewars/uLocale.pas --- a/hedgewars/uLocale.pas Mon Oct 12 13:56:07 2009 +0000 +++ b/hedgewars/uLocale.pas Mon Oct 12 16:44:30 2009 +0000 @@ -32,7 +32,8 @@ sidConfirm, sidSuddenDeath, sidRemaining, sidFuel, sidSync); TEventId = (eidDied, eidDrowned, eidRoundStart, eidRoundWin, eidRoundDraw, - eidNewHealthPack, eidNewAmmoPack, eidNewUtilityPack, eidTurnSkipped, eidHurtSelf); + eidNewHealthPack, eidNewAmmoPack, eidNewUtilityPack, eidTurnSkipped, eidHurtSelf, + eidHomerun); const MAX_EVENT_STRINGS = 100; var trammo: array[TAmmoStrId] of string; diff -r 241e3bb6a146 -r 6800f8aa0184 hedgewars/uMisc.pas --- a/hedgewars/uMisc.pas Mon Oct 12 13:56:07 2009 +0000 +++ b/hedgewars/uMisc.pas Mon Oct 12 16:44:30 2009 +0000 @@ -43,6 +43,7 @@ GameState : TGameState = Low(TGameState); GameType : TGameType = gmtLocal; GameFlags : Longword = 0; + TrainingFlags : Longword = 0; TurnTimeLeft : Longword = 0; cSuddenDTurns : LongInt = 15; cDamagePercent : LongInt = 100; @@ -71,7 +72,14 @@ cAltDamage : boolean = true; GameTicks : LongWord = 0; + TrainingTimeInc: Longword = 10000; + TrainingTimeInD: Longword = 250; + TrainingTimeInM: Longword = 5000; + TrainingTimeMax: Longword = 90000; + TimeTrialStartTime: Longword = 0; + TimeTrialStopTime: Longword = 0; + cSkyColor : Longword = 0; cWhiteColor : Longword = $FFFFFFFF; cColorNearBlack : Longword = $FF000010; @@ -102,6 +110,8 @@ var cSendCursorPosTime : LongWord = 50; ShowCrosshair : boolean; + CursorMovementX : Integer = 0; + CursorMovementY : Integer = 0; cDrownSpeed, cMaxWindSpeed, cWindSpeed, @@ -127,6 +137,7 @@ var WaterColorArray: array[0..3] of HwColor4f; +procedure movecursor(dx, dy: Integer); function hwSign(r: hwFloat): LongInt; function Min(a, b: LongInt): LongInt; function Max(a, b: LongInt): LongInt; @@ -169,6 +180,20 @@ var f: textfile; {$ENDIF} +procedure movecursor(dx, dy: Integer); +var x, y: LongInt; +begin +if (dx = 0) and (dy = 0) then exit; +{$IFDEF SDL13} +SDL_GetMouseState(0, @x, @y); +{$ELSE} +SDL_GetMouseState(@x, @y); +{$ENDIF} +Inc(x, dx); +Inc(y, dy); +SDL_WarpMouse(x, y); +end; + function hwSign(r: hwFloat): LongInt; begin // yes, we have negative zero for a reason @@ -388,7 +413,7 @@ if SDL_MustLock(surf) then SDLTry(SDL_LockSurface(surf) >= 0, true); -if not (isPowerOf2(Surf^.w) and isPowerOf2(Surf^.h)) then +if (not SupportNPOTT) and (not (isPowerOf2(Surf^.w) and isPowerOf2(Surf^.h))) then begin tw:= toPowerOf2(Surf^.w); th:= toPowerOf2(Surf^.h); diff -r 241e3bb6a146 -r 6800f8aa0184 hedgewars/uStore.pas --- a/hedgewars/uStore.pas Mon Oct 12 13:56:07 2009 +0000 +++ b/hedgewars/uStore.pas Mon Oct 12 16:44:30 2009 +0000 @@ -22,7 +22,7 @@ {$IFDEF GLES11} gles11, {$ELSE} - GL, + GL, GLext, {$ENDIF} uFloat; {$INCLUDE options.inc} @@ -64,6 +64,7 @@ SyncTexture, ConfirmTexture: PTexture; cScaleFactor: GLfloat = 2.0; + SupportNPOTT: Boolean = false; implementation uses uMisc, uConsole, uLand, uLocale, uWorld; @@ -347,7 +348,7 @@ _l, _r, _t, _b: real; VertexBuffer, TextureBuffer: array [0..3] of TVertex2f; begin -if SourceTexture^.h = 0 then exit; +if (SourceTexture^.h = 0) or (SourceTexture^.w = 0) then exit; rr.x:= X; rr.y:= Y; rr.w:= r^.w; @@ -967,32 +968,56 @@ LoadImage:= tmpsurf //Result end; +function glLoadExtension(extension : string) : boolean; +begin + glLoadExtension:= glext_LoadExtension(extension); + if not glLoadExtension then + WriteLnToConsole('OpenGL: "' + extension + '" failed to load') + else + WriteLnToConsole('OpenGL: "' + extension + '" loaded'); +end; + procedure SetupOpenGL; begin -SetScale(2.0); - -glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); -glMatrixMode(GL_MODELVIEW); - glGetIntegerv(GL_MAX_TEXTURE_SIZE, @MaxTextureSize); {$IFDEF DEBUGFILE} AddFileLog('GL_MAX_TEXTURE_SIZE: ' + inttostr(MaxTextureSize)); {$ENDIF} +{$IFNDEF GLES11} +SupportNPOTT:= glLoadExtension('GL_ARB_texture_non_power_of_two'); +{$ENDIF} + +// set view port to whole window +glViewport(0, 0, cScreenWidth, cScreenHeight); + +glMatrixMode(GL_MODELVIEW); +// prepare default translation/scaling +glLoadIdentity; +glScalef(2.0 / cScreenWidth, -2.0 / cScreenHeight, 1.0); +glTranslatef(0, -cScreenHeight / 2, 0); + +// enable alpha blending +glEnable(GL_BLEND); +glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); end; procedure SetScale(f: GLfloat); begin -cScaleFactor:= f; +// leave immediately if scale factor didn't change +if f = cScaleFactor then exit; -glLoadIdentity; -glViewport(0, 0, cScreenWidth, cScreenHeight); -glScalef(f / cScreenWidth, -f / cScreenHeight, 1.0); -//glTranslatef(-cScreenWidth / 2, -cScreenHeight / 2, 0); -glTranslatef(0, -cScreenHeight / 2, 0); +if f = 2.0 then // default scaling + glPopMatrix // "return" to default scaling +else // other scaling + begin + glPushMatrix; // save default scaling + glLoadIdentity; + glScalef(f / cScreenWidth, -f / cScreenHeight, 1.0); + glTranslatef(0, -cScreenHeight / 2, 0); + end; -// glTranslatex(320, 0, 0); -// glRotatef(90.0, 0.0, 0.0, 1.0); +cScaleFactor:= f; end; //////////////////////////////////////////////////////////////////////////////// diff -r 241e3bb6a146 -r 6800f8aa0184 hedgewars/uVisualGears.pas --- a/hedgewars/uVisualGears.pas Mon Oct 12 13:56:07 2009 +0000 +++ b/hedgewars/uVisualGears.pas Mon Oct 12 16:44:30 2009 +0000 @@ -173,6 +173,17 @@ dec(Gear^.FrameTicks, Steps) end; +procedure doStepHealth(Gear: PVisualGear; Steps: Longword); +begin +Gear^.X:= Gear^.X + Gear^.dX * Steps; +Gear^.Y:= Gear^.Y - Gear^.dY * Steps; + +if Gear^.FrameTicks <= Steps then + DeleteVisualGear(Gear) +else + dec(Gear^.FrameTicks, Steps); +end; + procedure doStepSteam(Gear: PVisualGear; Steps: Longword); begin Gear^.X:= Gear^.X + (cWindSpeed * 100 + Gear^.dX) * Steps; @@ -319,7 +330,8 @@ @doStepTeamHealthSorter, @doStepSpeechBubble, @doStepBubble, - @doStepSteam + @doStepSteam, + @doStepHealth ); function AddVisualGear(X, Y: LongInt; Kind: TVisualGearType): PVisualGear; @@ -395,25 +407,28 @@ Result^.FrameTicks:= 1100 end; vgtBubble: begin - t:= random(1024); - sp:= _0_001 * (random(85) + 95); dx.isNegative:= random(2) = 0; dx.QWordValue:= random(100000000); - dy:= sp; + dy:= _0_001 * (random(85) + 95); dy.isNegative:= false; FrameTicks:= 250 + random(1751); Frame:= random(5) end; vgtSteam: begin - t:= random(1024); - sp:= _0_001 * (random(95) + 70); dx.isNegative:= random(2) = 0; dx.QWordValue:= random(100000000); - dy:= sp; + dy:= _0_001 * (random(85) + 95); dy.isNegative:= false; Frame:= 7 - random(3); FrameTicks:= cExplFrameTicks * 2; end; + vgtHealth: begin + dx:= _0_001 * random(45); + dx.isNegative:= random(2) = 0; + dy:= _0_001 * (random(20) + 25); + Frame:= 0; + FrameTicks:= random(750) + 1250; + end; end; if VisualGearsList <> nil then @@ -472,11 +487,19 @@ begin if not cReducedQuality then case Gear^.Kind of - vgtExplPart: DrawSprite(sprExplPart, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, 7 - Gear^.Frame); - vgtExplPart2: DrawSprite(sprExplPart2, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, 7 - Gear^.Frame); - vgtFire: DrawSprite(sprFlame, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, (RealTicks div 64 + Gear^.Frame) mod 8); - vgtBubble: DrawSprite(sprBubbles, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, Gear^.Frame);//(RealTicks div 64 + Gear^.Frame) mod 8); - vgtSteam: DrawSprite(sprExplPart, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, 7 - Gear^.Frame); + vgtExplPart: DrawSprite(sprExplPart, hwRound(Gear^.X) + WorldDx - 16, hwRound(Gear^.Y) + WorldDy - 16, 7 - Gear^.Frame); + vgtExplPart2: DrawSprite(sprExplPart2, hwRound(Gear^.X) + WorldDx - 16, hwRound(Gear^.Y) + WorldDy - 16, 7 - Gear^.Frame); + vgtFire: DrawSprite(sprFlame, hwRound(Gear^.X) + WorldDx - 8, hwRound(Gear^.Y) + WorldDy, (RealTicks div 64 + Gear^.Frame) mod 8); + vgtBubble: DrawSprite(sprBubbles, hwRound(Gear^.X) + WorldDx - 8, hwRound(Gear^.Y) + WorldDy - 8, Gear^.Frame);//(RealTicks div 64 + Gear^.Frame) mod 8); + vgtSteam: DrawSprite(sprExplPart, hwRound(Gear^.X) + WorldDx - 16, hwRound(Gear^.Y) + WorldDy - 16, 7 - Gear^.Frame); + vgtHealth: begin + case Gear^.Frame div 10 of + 0:glColor4f(0, 1, 0, Gear^.FrameTicks / 1000); + 1:glColor4f(1, 0, 0, Gear^.FrameTicks / 1000); + end; + DrawSprite(sprHealth, hwRound(Gear^.X) + WorldDx - 8, hwRound(Gear^.Y) + WorldDy - 8, 0); + glColor4f(1, 1, 1, 1); + end; end; case Gear^.Kind of vgtSmallDamageTag: DrawCentered(hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, Gear^.Tex); diff -r 241e3bb6a146 -r 6800f8aa0184 hedgewars/uWorld.pas --- a/hedgewars/uWorld.pas Mon Oct 12 13:56:07 2009 +0000 +++ b/hedgewars/uWorld.pas Mon Oct 12 16:44:30 2009 +0000 @@ -83,7 +83,7 @@ var x, y, i, t, l, g: LongInt; Slot, Pos: LongInt; begin -if (TurnTimeLeft = 0) or (((CurAmmoGear = nil) or ((CurAmmoGear^.Ammo^.Propz and ammoprop_AltAttack) = 0)) and KbdKeyPressed) then bShowAmmoMenu:= false; +if (TurnTimeLeft = 0) or (((CurAmmoGear = nil) or ((CurAmmoGear^.Ammo^.Propz and ammoprop_AltAttack) = 0)) and hideAmmoMenu) then bShowAmmoMenu:= false; if bShowAmmoMenu then begin FollowGear:= nil; @@ -138,6 +138,8 @@ begin l:= Ammoz[Ammo^[i, t].AmmoType].SkipTurns - CurrentTeam^.Clan^.TurnNumber; + if (TrainingFlags and tfIgnoreDelays) <> 0 then l:= -1; + if l >= 0 then begin DrawSprite(sprAMAmmosBW, x + g * 33 + 35, y + 1, LongInt(Ammo^[i, t].AmmoType)-1); @@ -168,7 +170,7 @@ if Ammo^[Slot, Pos].Count < AMMO_INFINITE then DrawTexture(cScreenWidth div 2 + AMxShift - 35, cScreenHeight - 68, CountTexz[Ammo^[Slot, Pos].Count]); - if bSelected and (Ammoz[Ammo^[Slot, Pos].AmmoType].SkipTurns - CurrentTeam^.Clan^.TurnNumber < 0) then + if bSelected and (((TrainingFlags and tfIgnoreDelays) <> 0) or (Ammoz[Ammo^[Slot, Pos].AmmoType].SkipTurns - CurrentTeam^.Clan^.TurnNumber < 0)) then begin bShowAmmoMenu:= false; SetWeapon(Ammo^[Slot, Pos].AmmoType); @@ -416,8 +418,53 @@ DrawSprite(sprFrame, -cScreenWidth div 2 + t - 4, cScreenHeight - 48, 0); end; +// Timetrial +if ((TrainingFlags and tfTimeTrial) <> 0) and (TimeTrialStartTime > 0) then + begin + if TimeTrialStopTime = 0 then i:= RealTicks - TimeTrialStartTime else i:= TimeTrialStopTime - TimeTrialStartTime; + t:= 272; + // right frame + DrawSprite(sprFrame, -cScreenWidth div 2 + t, 8, 1); + dec(t, 32); + // 1 ms + DrawSprite(sprBigDigit, -cScreenWidth div 2 + t, 8, i mod 10); + dec(t, 32); + i:= i div 10; + // 10 ms + DrawSprite(sprBigDigit, -cScreenWidth div 2 + t, 8, i mod 10); + dec(t, 32); + i:= i div 10; + // 100 ms + DrawSprite(sprBigDigit, -cScreenWidth div 2 + t, 8, i mod 10); + dec(t, 16); + // Point + DrawSprite(sprBigDigit, -cScreenWidth div 2 + t, 8, 11); + dec(t, 32); + i:= i div 10; + // 1 s + DrawSprite(sprBigDigit, -cScreenWidth div 2 + t, 8, i mod 10); + dec(t, 32); + i:= i div 10; + // 10s + DrawSprite(sprBigDigit, -cScreenWidth div 2 + t, 8, i mod 6); + dec(t, 16); + // Point + DrawSprite(sprBigDigit, -cScreenWidth div 2 + t, 8, 10); + dec(t, 32); + i:= i div 6; + // 1 m + DrawSprite(sprBigDigit, -cScreenWidth div 2 + t, 8, i mod 10); + dec(t, 32); + i:= i div 10; + // 10 m + DrawSprite(sprBigDigit, -cScreenWidth div 2 + t, 8, i mod 10); + // left frame + DrawSprite(sprFrame, -cScreenWidth div 2 + t - 4, 8, 0); + end; + // Captions -i:= 8; +if ((TrainingFlags and tfTimeTrial) <> 0) and (TimeTrialStartTime > 0) then i:= 48 else i:= 8; + for grp:= Low(TCapGroup) to High(TCapGroup) do with Captions[grp] do if Tex <> nil then @@ -561,11 +608,8 @@ procedure MoveCamera; const PrevSentPointTime: LongWord = 0; -var EdgesDist, cw, wdy: LongInt; +var EdgesDist, wdy: LongInt; begin - -cw:= round(cScreenWidth / cScaleFactor); - if (not (CurrentTeam^.ExtDriven and isCursorVisible)) and cHasFocus then begin {$IFDEF SDL13} diff -r 241e3bb6a146 -r 6800f8aa0184 share/hedgewars/Data/Graphics/BigDigits.png Binary file share/hedgewars/Data/Graphics/BigDigits.png has changed diff -r 241e3bb6a146 -r 6800f8aa0184 share/hedgewars/Data/Graphics/Frame.png Binary file share/hedgewars/Data/Graphics/Frame.png has changed diff -r 241e3bb6a146 -r 6800f8aa0184 share/hedgewars/Data/Graphics/Health.png Binary file share/hedgewars/Data/Graphics/Health.png has changed diff -r 241e3bb6a146 -r 6800f8aa0184 share/hedgewars/Data/Locale/de.txt --- a/share/hedgewars/Data/Locale/de.txt Mon Oct 12 13:56:07 2009 +0000 +++ b/share/hedgewars/Data/Locale/de.txt Mon Oct 12 16:44:30 2009 +0000 @@ -7,9 +7,9 @@ 00:04=Schrotflinte 00:05=Presslufthammer 00:06=Runde überspringen -00:07=Seil +00:07=Enterhaken 00:08=Mine -00:09=DEagle +00:09=Desert Eagle 00:10=Dynamit 00:11=Baseballschläger 00:12=Feuerfaust @@ -31,7 +31,7 @@ 00:28=Bohrkopfrakete 00:29=Ballpistole 00:30=Napalm -00:31=RC Flugzeug +00:31=RC-Flugzeug 00:32=Schwerkraft verringern 00:33=Zusatzschaden 00:34=Unverwundbarkeit @@ -39,17 +39,18 @@ 00:36=Laservisier 00:37=Vampirismus 00:38=Scharfschützengewehr -00:39=Flying Saucer +00:39=Fliegende Untertasse 01:00=Auf in die Schlacht! 01:01=Unentschieden 01:02=%1 gewinnt! -01:03=Lautstärke %1% +01:03=Lautstärke: %1 % 01:04=Pausiert 01:05=Wirklich beenden (Z/Esc)? 01:06=Sudden Death! -01:07=Remaining -01:08=Fuel +01:07=verbleibend +01:08=Treibstoff +01:09=Synchronisiere ... ; Event messages ; Hog (%1) died @@ -57,9 +58,19 @@ 02:00=%1 steht wohl nicht mehr auf! 02:00=%1 hat's nicht geschafft! 02:00=%1 stellt sich tot! -02:00=%1 scheint schon bessere Tage gesehen zu haben! +02:00=%1 hat schon bessere Tage gesehen! 02:00=%1 sieht tote Igel! 02:00=%1 hat ins Gras gebissen! +02:00=%1 ist Futter für die Würmer! +02:00=Das war's wohl, %1! +02:00=%1 hat's hinter sich! +02:00=%1 kann schon das Licht sehen! +02:00=Für %1 gehen alle Lichter aus! +02:00=%1 kommt wieder! +02:00=%1 ist urlaubsreif! +02:00=%1 trifft seine Ahnen. +02:00=%1 war nicht hartnäckig genug! + ; Hog (%1) drowned 02:01=%1 geht auf Tauchstation! 02:01=%1 sucht nach der Titanic! @@ -68,30 +79,72 @@ 02:01=%1 hat sich nass gemacht! 02:01=%1 versagt beim Seepferdchen! 02:01=%1 ist ein Opfer der Gezeiten! +02:01=%1 findet Nemo! +02:01=%1 taucht unter ... +02:01=Atlantis wartet, %1! +02:01=%1 nimmt ein entspannendes Bad. +02:01=%1 hat nie das Seepferdchen gemacht! +02:01=%1 ist Fischfutter! +02:01=%1 im Rausch der Tiefe! +02:01=Was für ein feuchtes Erlebnis! +02:01=%1 geht unter die Perlentaucher! +02:01=Igel über Bord! +02:01=%1 verlässt das sinkende Schiff. +02:01=%1 überschätzt seinen Auftrieb! +02:01=%1 erliegt dem Sog der Tiefe! +02:01=%1 geht der Sache auf den Grund! + ; Round starts 02:02=Auf in die Schlacht! 02:02=Geladen und entsichert! 02:02=Jetzt geht's rund! 02:02=Los geht's! 02:02=Alles angetreten! + ; Round ends (win; unused atm) 02:03=... + ; Round ends (draw; unused atm) 02:04=... + ; New health crate 02:05=Alles Gute kommt von oben! -02:05=Der Arzt hat's verschrieben ... +02:05=Linderung in Sicht! +02:05=Das kommt gelegen! +02:05=Jemand denkt an euch! +02:05=Mit Liebe verpackt? + ; New ammo crate 02:06=Nachschub! 02:06=Zeit zum Nachladen! +02:06=Was wohl darin ist? +02:06=Bringt das die Wende? +02:06=Tod aus der Luft! + ; New utility crate 02:07=Nützliches? 02:07=Tooltime! +02:07=Was wohl darin ist? +02:07=Lieferung frei Haus! +02:07=Mehr als nur eine Kiste! + ; Hog (%1) skips his turn 02:08=%1 ist so ein Langeweiler ... +02:08=%1 denkt weiter nach ... +02:08=Das war öde, %1! +02:08=%1 führt etwas im Schilde! +02:08=%1 setzt aus. +02:08=%1 ist ein Drückeberger. +02:08=%1 überdenkt die Situation. +02:08=%1 kann sich nicht entscheiden. + ; 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! +; Hog (%1) shot an home run (using the bat and another hog) +02:10=Home Run! +02:10=Ein Vogel, ein Flugzeug, ... +02:10=Der verleiht Flügel! \ No newline at end of file diff -r 241e3bb6a146 -r 6800f8aa0184 share/hedgewars/Data/Locale/en.txt --- a/share/hedgewars/Data/Locale/en.txt Mon Oct 12 13:56:07 2009 +0000 +++ b/share/hedgewars/Data/Locale/en.txt Mon Oct 12 16:44:30 2009 +0000 @@ -343,3 +343,7 @@ 02:09=I'm sure nobody saw that %1 02:09=%1 needs to review his field manual 02:09=%1's weapon clearly malfunctioned +; Hog shot an home run (using the bat and another hog) +02:10=Home Run! +02:10=A bird, a plane, ... +02:10=That one is out! \ No newline at end of file diff -r 241e3bb6a146 -r 6800f8aa0184 share/hedgewars/Data/Trainings/003_RCPlane.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/hedgewars/Data/Trainings/003_RCPlane.txt Mon Oct 12 16:44:30 2009 +0000 @@ -0,0 +1,12 @@ +seed 1 +$gmflags 268435458 +$trflags 15 +$turntime 30000 +$casefreq 0 +$landadds 0 +$delay 0 +map EarthRise +theme EarthRise +ammstore 000000000000000000000000000000100000000000000000000000000000000000000000000000 +addtrig C7 1 1 +addtrig F2147483649 2 1 \ No newline at end of file