Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
87 KB
Referenced Files
None
Subscribers
None
diff --git a/data/levelpacks/classic/locale/it.po b/data/levelpacks/classic/locale/it.po
new file mode 100644
index 0000000..13fa289
--- /dev/null
+++ b/data/levelpacks/classic/locale/it.po
@@ -0,0 +1,118 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: meandmyshadow 0.4\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2012-04-01 17:56+0300\n"
+"PO-Revision-Date: 2012-07-14 13:24+0100\n"
+"Last-Translator: BioHazardX <dhamp90@aol.com>\n"
+"Language-Team: \n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: classic/End.map:1
+msgid "End"
+msgstr "Fine"
+
+#: classic/Here.map:1
+msgid "Here"
+msgstr "Qui"
+
+#: classic/Road.map:1
+msgid "Road"
+msgstr "Strada"
+
+#: classic/FreeFall2.map:1
+msgid "FreeFall2"
+msgstr "Caduta libera parte seconda"
+
+#: classic/UpDown.map:1
+msgid "UpDown"
+msgstr "Su e giù"
+
+#: classic/Control.map:1
+msgid "Control"
+msgstr "Controllo"
+
+#: classic/FreeFall.map:1
+msgid "FreeFall"
+msgstr "Caduta libera"
+
+#: classic/SomeSpikes.map:1
+msgid "SomeSpikes"
+msgstr "Qualche spuntone"
+
+#: classic/BabySteps.map:1
+msgid "BabySteps"
+msgstr "Primi passi"
+
+#: classic/levels.lst:1
+msgid "Default level pack"
+msgstr "Pacchetto di livelli predefinito"
+
+#: classic/Lab.map:1
+msgid "Lab"
+msgstr "Laboratorio"
+
+#: classic/Spiky.map:1
+msgid "Spiky"
+msgstr "Pungente"
+
+#: classic/Credits.map:1
+msgid "Credits"
+msgstr "Riconoscimenti"
+
+#: classic/Headache.map:1
+msgid "Headache"
+msgstr "Mal di testa"
+
+#: classic/LeftRight.map:1
+msgid "LeftRight"
+msgstr "Destra e sinistra"
+
+#: classic/Jumping.map:1
+msgid "Jumping"
+msgstr "Salto"
+
+#: classic/ShadowBlocks.map:1
+msgid "ShadowBlocks"
+msgstr "Blocchi-ombra"
+
+#: classic/Tricky.map:1
+msgid "Tricky"
+msgstr "Complicato"
+
+#: classic/Jumper.map:1
+msgid "Jumper"
+msgstr "Il saltatore"
+
+#: classic/FirstSpikes.map:1
+msgid "FirstSpikes"
+msgstr "Primi spuntoni"
+
+#: classic/Carry.map:1
+msgid "Carry"
+msgstr "Traiettoria"
+
+#: classic/Timing.map:1
+msgid "Timing"
+msgstr "Sincronizzazione"
+
+#: classic/Shadow.map:1
+msgid "Shadow"
+msgstr "Ombra"
+
+#: classic/LittleHelp.map:1
+msgid "LittleHelp"
+msgstr "Un piccolo aiuto"
+
+#: classic/Tower.map:1
+msgid "Tower"
+msgstr "Torre"
+
diff --git a/data/levelpacks/default/locale/it.po b/data/levelpacks/default/locale/it.po
new file mode 100644
index 0000000..1f1c0cd
--- /dev/null
+++ b/data/levelpacks/default/locale/it.po
@@ -0,0 +1,98 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: meandmyshadow 0.4\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2012-04-01 17:56+0300\n"
+"PO-Revision-Date: 2012-07-14 13:24+0100\n"
+"Last-Translator: BioHazardX <dhamp90@aol.com>\n"
+"Language-Team: \n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: default/Regroup.map:1
+msgid "Regroup"
+msgstr "Raggruppamento"
+
+#: default/Switches.map:1
+msgid "Switches"
+msgstr "Interruttori"
+
+#: default/4.map:1
+msgid "Both Up and Down"
+msgstr "Sia su che giù"
+
+#: default/map02.map:1
+msgid "Snail"
+msgstr "Lumaca"
+
+#: default/Towers.map:1
+msgid "Towers"
+msgstr "Torri"
+
+#: default/map01.map:1
+msgid "Simple"
+msgstr "Semplice"
+
+#: default/map04.map:1
+msgid "Double trouble"
+msgstr "Doppio problema"
+
+#: default/3.map:1
+msgid "Running in the Sky"
+msgstr "Correndo nel cielo"
+
+#: default/Skyscrapers.map:1
+msgid "Skyscrapers"
+msgstr "Grattacieli"
+
+#: default/QuickSwap.map:1
+msgid "Quick swap"
+msgstr "Scambio veloce"
+
+#: default/5.map:1
+msgid "stopping the spikes"
+msgstr "Ferma gli spuntoni"
+
+#: default/levels.lst:1
+msgid "Default"
+msgstr "Predefinito"
+
+#: default/Remote.map:1
+msgid "Remote control"
+msgstr "Controllo remoto"
+
+#: default/map03.map:1
+msgid "Spiky travel"
+msgstr "Viaggio tra gli spuntoni"
+
+#: default/Sweeper.map:1
+msgid "Sweeper"
+msgstr "La spazzatrice"
+
+#: default/1.map:1
+msgid "Building Teamwork"
+msgstr "Costruzione del lavoro di squadra"
+
+#: default/Timing.map:1
+msgid "Timing"
+msgstr "Sincronizzazione"
+
+#: default/Volcano.map:1
+msgid "Volcano"
+msgstr "Vulcano"
+
+#: default/map05.map:1
+msgid "Wall breaking"
+msgstr "Muri da demolire"
+
+#: default/2.map:1
+msgid "Tricky Jumping"
+msgstr "Salti difficili"
+
diff --git a/data/levelpacks/tutorial/locale/it.po b/data/levelpacks/tutorial/locale/it.po
new file mode 100644
index 0000000..a0a8b32
--- /dev/null
+++ b/data/levelpacks/tutorial/locale/it.po
@@ -0,0 +1,470 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: meandmyshadow 0.4\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2012-04-01 17:56+0300\n"
+"PO-Revision-Date: 2012-07-14 13:24+0100\n"
+"Last-Translator: BioHazardX <dhamp90@aol.com>\n"
+"Language-Team: \n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: tutorial/tut12.map:17
+msgid "Now you'll need to help your shadow cross.\n"
+msgstr "Ora dovrai aiutare la tua ombra ad attraversare.\n"
+
+#: tutorial/tut07.map:33
+msgid ""
+"If your shadow dies you'll have to restart.\n"
+"Restart the game by pressing the 'R' key."
+msgstr ""
+"Se la tua ombra muore devi ricominciare dall'inizio.\n"
+"Ricomincia il gioco premendo il tasto \"r\"."
+
+#: tutorial/tut18.map:14
+msgid ""
+"This trigger will deactivate the moving block.\n"
+"Try to stop it at the right moment.\n"
+"You can only do this once, so if it fails you'll\n"
+"have to reset the level with the 'R' key."
+msgstr ""
+"Questo innesco disattiverà il blocco mobile:\n"
+"prova a fermarlo al momento giusto.\n"
+"Puoi usarlo solo una volta, e se fallisci\n"
+"dovrai riavviare il livello con il tasto \"r\"."
+
+#: tutorial/tut20.map:1
+msgid "Portal mayhem"
+msgstr "Caos di portali"
+
+#: tutorial/tut21.map:49
+msgid ""
+"If your shadow falls down here you will have to restart.\n"
+"Press 'R' to restart the level."
+msgstr ""
+"Se la tua ombra cade giù devi ricominciare dall'inizio.\n"
+"Premi \"r\" per riavviare il livello."
+
+#: tutorial/tut02.map:18
+msgid ""
+"You can jump using the up key.\n"
+"Try jumping over these blocks."
+msgstr ""
+"Salta usando la freccia in su.\n"
+"Prova a saltare oltre a questi blocchi."
+
+#: tutorial/tut23.map:1
+msgid "Collecting Keys"
+msgstr "Chiavi da collezionare"
+
+#: tutorial/tut10.map:46
+msgid "You've chosen the right way."
+msgstr "Hai scelto la strada giusta."
+
+#: tutorial/tut22.map:1
+msgid "Shadow swap"
+msgstr "Scambio dell'ombra"
+
+#: tutorial/tut20.map:187
+msgid ""
+"A dead end, you'd better go back and choose\n"
+"the other portal."
+msgstr ""
+"Un vicolo cieco, fai meglio a ritornare indietro e\n"
+"scegliere l'altro portale."
+
+#: tutorial/tut03.map:13
+msgid ""
+"See those gaps over there?\n"
+"Reach the finish without falling."
+msgstr ""
+"Vedi questi baratri laggiù?\n"
+"Raggiungi l'uscita senza cadere."
+
+#: tutorial/tut05.map:1
+msgid "Shadow"
+msgstr "Ombra"
+
+#: tutorial/tut10.map:19
+msgid ""
+"You can save your progress in a level with\n"
+"checkpoints. You can restore them at any\n"
+"time using the F3 button."
+msgstr ""
+"Puoi salvare il tuo progresso nel livello grazie ai\n"
+"checkpoint. Puoi utilizzarli ogni volta usando\n"
+"il tasto F3."
+
+#: tutorial/tut01.map:18
+msgid ""
+"Welcome to Me and My Shadow.\n"
+"You can use the arrow keys to walk to the exit.\n"
+"\n"
+"Good luck!"
+msgstr ""
+"Benvenuti a Me and My Shadow.\n"
+"Usa i tasti a freccia per camminare fino all'uscita.\n"
+"\n"
+"Buona fortuna!"
+
+#: tutorial/tut07.map:1
+msgid "Shadow challenge"
+msgstr "Sfida dell'ombra"
+
+#: tutorial/tut22.map:22
+msgid ""
+"You need your shadow to reach the exit.\n"
+"Make use of the swapper to get him down (or \n"
+"to get yourself down)."
+msgstr ""
+"La tua ombra ha bisogno di raggiungere l'uscita.\n"
+"Fai uso dello scambiatore per farla scendere da lì (oppure \n"
+"usalo per far scendere te stesso)."
+
+#: tutorial/tut02.map:1
+msgid "First jumps"
+msgstr "Primi salti"
+
+#: tutorial/tut20.map:16
+msgid ""
+"Portals point to another portal or to nothing.\n"
+"Try to reach the exit in this portal mayhem."
+msgstr ""
+"Un portale ti trasporterà in un altro portale o in un vicolo cieco.\n"
+"Prova a raggiungere l'uscita in questo caos di portali."
+
+#: tutorial/tut08.map:21
+msgid ""
+"You and your shadow need to work together.\n"
+"Move your shadow towards the wall and jump\n"
+"on him so that you can jump over the wall."
+msgstr ""
+"Tu e la tua ombra avete bisogno di lavorare insieme.\n"
+"Muovi la tua ombra verso il muro e saltale\n"
+"sopra la testa per riuscire a oltrepassare il muro."
+
+#: tutorial/tut11.map:17
+msgid ""
+"Until now the levels were static.\n"
+"There are however moving blocks."
+msgstr ""
+"Fino adesso i livelli erano statici.\n"
+"Tuttavia ci sono anche i blocchi mobili."
+
+#: tutorial/tut10.map:32
+msgid "Save your progress here."
+msgstr "Salva qui il tuo progresso."
+
+#: tutorial/tut24.map:18
+msgid ""
+"That's all there is.\n"
+"Now it's time to put your skills to the test.\n"
+"Enter the exit to go to the last level.\n"
+"Good luck!"
+msgstr ""
+"E questo è tutto.\n"
+"Ora è il momento di usare tutte le tue abilità per il test finale.\n"
+"Entra nella porta per andare all'ultimo livello.\n"
+"Buona fortuna!"
+
+#: tutorial/tut10.map:54
+msgid ""
+"This is the wrong way.\n"
+"Go back to the previous checkpoint by pressing F3."
+msgstr ""
+"Questa è la strada sbagliata.\n"
+"Torna indietro al checkpoint precedente premendo F3."
+
+#: tutorial/tut16.map:1
+msgid "The switch"
+msgstr "L'interruttore"
+
+#: tutorial/tut25.map:13
+msgid "The very best of luck!"
+msgstr "Buona fortuna!"
+
+#: tutorial/tut20.map:156
+msgid "Now choose one of the two."
+msgstr "Ora scegline uno dei due."
+
+#: tutorial/tut15.map:20
+msgid ""
+"This gap is impossible to jump over.\n"
+"Step on the button next of you."
+msgstr ""
+"Impossibile saltare al di là del baratro.\n"
+"Usa il pulsante accanto a te."
+
+#: tutorial/tut25.map:46
+msgid ""
+"TIP:\n"
+"Try to get your shadow in front of the shadow\n"
+"wall. If he falls down you'd better restart."
+msgstr ""
+"SUGGERIMENTO:\n"
+"Prova a portare l'ombra davanti al\n"
+"muro ombra. Se cade giù fai meglio a ricominciare."
+
+#: tutorial/tut13.map:18
+msgid "Watch out for the moving spikes."
+msgstr "Fai attenzione agli spuntoni mobili."
+
+#: tutorial/tut25.map:318
+msgid "You have made it!"
+msgstr "Ce l'hai fatta!"
+
+#: tutorial/tut17.map:1
+msgid "Toggle trigger"
+msgstr "Attiva o disattiva l'innesco"
+
+#: tutorial/tut15.map:1
+msgid "Triggering"
+msgstr "Attivazione"
+
+#: tutorial/tut13.map:1
+msgid "Moving spikes"
+msgstr "Spuntoni mobili"
+
+#: tutorial/tut06.map:23
+msgid ""
+"NOTE:\n"
+"Although you can't jump on those blocks\n"
+"you can record the jumps for your shadow."
+msgstr ""
+"NOTE:\n"
+"Sebbene non puoi saltare sopra a questo tipo di blocchi,\n"
+"puoi sempre registrare i propri salti per farci salire la tua ombra."
+
+#: tutorial/tut18.map:1
+msgid "Stop trigger"
+msgstr "Ferma l'innesco"
+
+#: tutorial/tut01.map:1
+msgid "Walk in the park"
+msgstr "Passeggiata al parco"
+
+#: tutorial/tut09.map:14
+msgid ""
+"Those blocks are fragile.\n"
+"If you step on them too often they'll break."
+msgstr ""
+"Questi blocchi sono fragili.\n"
+"Se passi sopra spesso si sgretoleranno."
+
+#: tutorial/tut19.map:1
+msgid "First portals"
+msgstr "Primi portali"
+
+#: tutorial/tut25.map:1
+msgid "Final"
+msgstr "Test finale"
+
+#: tutorial/tut04.map:1
+msgid "First spikes"
+msgstr "Primi spuntoni"
+
+#: tutorial/tut05.map:32
+msgid ""
+"TIP:\n"
+"Think what moves your shadow has to make.\n"
+"Then let your character record those moves.\n"
+"You can break it down into smaller recordings."
+msgstr ""
+"SUGGERIMENTO:\n"
+"Prima pensa a quali mosse deve effettuare la tua ombra,\n"
+"poi registra e fai muovere il personaggio.\n"
+"Puoi registrare a piccoli intervalli."
+
+#: tutorial/tut12.map:1
+msgid "Moving shadow blocks"
+msgstr "Blocchi-ombra mobili"
+
+#: tutorial/tut14.map:1
+msgid "Conveyor madness"
+msgstr "Pazzi trasportatori"
+
+#: tutorial/tut06.map:1
+msgid "Shadow walk"
+msgstr "Passo dell'ombra"
+
+#: tutorial/tut21.map:8
+msgid ""
+"Now it's time for something completely\n"
+"different: swappoints. When you or your\n"
+"shadow activate them you'll swap places."
+msgstr ""
+"Ora è il momento per qualcosa di completamente\n"
+"nuovo: i punti di scambio. Quando tu o la tua\n"
+"ombra attiverete uno di questi vi scambierete le vostre posizioni."
+
+#: tutorial/tut06.map:27
+msgid ""
+"Only your shadow can stand on those shadow\n"
+"blocks. Try to get him up there."
+msgstr ""
+"Solo la tua ombra può stare in questo tipo di\n"
+"blocchi. Prova a farla arrivare in cima."
+
+#: tutorial/tut17.map:14
+msgid ""
+"You've only seen triggers that activate other\n"
+"blocks, but they can also deactivate or toggle\n"
+"them."
+msgstr ""
+"Fino adesso hai visto inneschi che attivano i blocchi\n"
+"una sola volta se usati: dovresti sapere che ci sono alcuni\n"
+"che possono essere attivati e disattivati innumerevoli volte."
+
+#: tutorial/tut14.map:68
+msgid ""
+"When standing on conveyor belts you'll\n"
+"move without walking."
+msgstr ""
+"Se stai nei nastri trasportatori\n"
+"ti muoverai senza camminare."
+
+#: tutorial/tut22.map:33
+msgid ""
+"TIP:\n"
+"When your shadow is trapped stand on the\n"
+"right side of the shadow blocks. Now record \n"
+"the down key and let your shadow mimic."
+msgstr ""
+"SUGGERIMENTO:\n"
+"Quando l'ombra è intrappolata stai nel\n"
+"lato destro dei blocchi-ombra. Ora registra\n"
+"premendo la frecca giù e lascia l'ombra che simuli la mossa."
+
+#: tutorial/tut08.map:1
+msgid "Teamwork"
+msgstr "Gioco di squadra"
+
+#: tutorial/tut14.map:71
+msgid ""
+"Let the shadow finish the level by walking to\n"
+"the finish. But don't stand still because your\n"
+"shadow will move all the way back."
+msgstr ""
+"Lascia che la tua ombra finisca il livello andando verso\n"
+"l'uscita. Evita di stare fermo sennò\n"
+"l'ombra ritornerà al punto di partenza."
+
+#: tutorial/tut24.map:1
+msgid "Warning"
+msgstr "Avviso"
+
+#: tutorial/tut23.map:18
+msgid ""
+"One thing you need to know before you're ready are keys.\n"
+"Sometimes there are keys spread around the level.\n"
+"The exit is locked until you get all the keys."
+msgstr ""
+"Prima di essere pronto, hai bisogno di essere a conoscenza delle chiavi.\n"
+"Qualche volta ce ne sono qualcune sparse per il livello,\n"
+"e l'uscita sarà bloccata finché non otterrai tutte le chiavi."
+
+#: tutorial/tut03.map:34
+msgid "Good job!"
+msgstr "Ottimo lavoro!"
+
+#: tutorial/tut16.map:14
+msgid ""
+"There's another type of trigger: the switch.\n"
+"Use the switch to activate the elevator so that you\n"
+"can reach the exit."
+msgstr ""
+"Questo è un altro tipo di innesco: l'interruttore.\n"
+"Usalo per attivare l'ascensore che ti porterà\n"
+"verso l'uscita."
+
+#: tutorial/tut09.map:1
+msgid "Fragile"
+msgstr "Fragile"
+
+#: tutorial/tut25.map:459
+msgid "Where could your shadow be?"
+msgstr "Dove potrebbe essere finita la tua ombra?"
+
+#: tutorial/tut19.map:42
+msgid ""
+"NOTE:\n"
+"You can go back by entering this portal.\n"
+"It is however a bit different, you don't have to\n"
+"press the down key, it will activate when you walk in it."
+msgstr ""
+"NOTA:\n"
+"Puoi ritornare indietro entrando da questo portale.\n"
+"Comunque è un pò diverso, non hai bisogno di\n"
+"premere la freccia in giù perché si attiverà da solo se ci camminerai sopra."
+
+#: tutorial/tut03.map:1
+msgid "Jumping around"
+msgstr "Saltandoci attorno"
+
+#: tutorial/tut10.map:1
+msgid "Checkpoints"
+msgstr "Checkpoint"
+
+#: tutorial/tut07.map:19
+msgid ""
+"Spikes are not only deadly for you,\n"
+"but also for your shadow."
+msgstr ""
+"Gli spuntoni non sono letali per te,\n"
+"ma per la tua ombra sì."
+
+#: tutorial/tut21.map:1
+msgid "Swappoints"
+msgstr "Punti di scambio"
+
+#: tutorial/tut04.map:19
+msgid ""
+"Spikes are deadly.\n"
+"Don't touch them!"
+msgstr ""
+"Gli spuntoni sono mortali.\n"
+"Non toccarli!"
+
+#: tutorial/levels.lst:2
+msgid "Step by step introduction"
+msgstr "Introduzione passo dopo passo"
+
+#: tutorial/tut11.map:1
+msgid "Moving blocks"
+msgstr "Blocchi mobili"
+
+#: tutorial/tut19.map:39
+msgid ""
+"Now it's time to check out the portals.\n"
+"To get to the exit you'll have to take the portal.\n"
+"Walk to it and press the down arrow to\n"
+"activate."
+msgstr ""
+"Ora è tempo di provare i portali.\n"
+"Per raggiungere l'uscire dovrai entrare all'interno del portale,\n"
+"e per attivarlo dovrai camminarci sopra e poi premere\n"
+"la freccia in giù."
+
+#: tutorial/tut05.map:29
+msgid ""
+"You can't reach the exit, but your shadow can.\n"
+"Press space to record your moves.\n"
+"Press space once again to let your shadow\n"
+"mimic your recording."
+msgstr ""
+"Solo la tua ombra può raggiungere l'uscita.\n"
+"Premi spazio per registrare i tuoi movimenti, poi\n"
+"premilo di nuovo per terminare la registrazione.\n"
+"Infine lascia che l'ombra simuli tutte le tue mosse."
+
+#: tutorial/levels.lst:1
+msgid "You have finished the tutorial!"
+msgstr "Hai completato il tutorial!"
+
diff --git a/data/locale/it.po b/data/locale/it.po
new file mode 100644
index 0000000..f60bb67
--- /dev/null
+++ b/data/locale/it.po
@@ -0,0 +1,1078 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: meandmyshadow 0.4\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2012-06-03 16:20+0200\n"
+"PO-Revision-Date: 2012-07-14 13:24+0100\n"
+"Last-Translator: BioHazardX <dhamp90@aol.com>\n"
+"Language-Team: \n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: ../src/Addons.cpp:40
+#: ../src/TitleMenu.cpp:50
+msgid "Addons"
+msgstr "Estensioni"
+
+#: ../src/Addons.cpp:58
+msgid "Unable to initialize addon menu:"
+msgstr "Impossibile inizializzare il menu delle estensioni:"
+
+#: ../src/Addons.cpp:66
+#: ../src/Addons.cpp:115
+#: ../src/LevelEditSelect.cpp:69
+#: ../src/LevelSelect.cpp:186
+msgid "Back"
+msgstr "Indietro"
+
+#: ../src/Addons.cpp:97
+msgid "Levels"
+msgstr "Livelli"
+
+#: ../src/Addons.cpp:98
+msgid "Level Packs"
+msgstr "Pacchetti di livelli"
+
+#: ../src/Addons.cpp:99
+msgid "Themes"
+msgstr "Temi"
+
+#: ../src/Addons.cpp:119
+#: ../src/Addons.cpp:595
+msgid "Install"
+msgstr "Installa"
+
+#: ../src/Addons.cpp:123
+msgid "Update"
+msgstr "Aggiorna"
+
+#: ../src/Addons.cpp:400
+#: ../src/Addons.cpp:417
+#: ../src/Addons.cpp:434
+#: ../src/Addons.cpp:461
+#: ../src/Addons.cpp:478
+#: ../src/Addons.cpp:492
+msgid "ERROR: Unable to download addon!"
+msgstr "ERRORE: impossibile scaricare l'estensione!"
+
+#: ../src/Addons.cpp:400
+#: ../src/Addons.cpp:417
+#: ../src/Addons.cpp:434
+#: ../src/Addons.cpp:461
+#: ../src/Addons.cpp:478
+#: ../src/Addons.cpp:492
+msgid "ERROR:"
+msgstr "ERRORE:"
+
+#: ../src/Addons.cpp:590
+msgid "Uninstall"
+msgstr "Disinstalla"
+
+# TRANSLATORS: Font used in GUI:
+# - Use "knewave" for languages using Latin and Latin-derived alphabets
+# - "DroidSansFallback" can be used for non-Latin writing systems
+#: ../src/Functions.cpp:592
+#: ../src/Functions.cpp:593
+#: ../src/Functions.cpp:594
+msgid "knewave"
+msgstr "knewave"
+
+# TRANSLATORS: Font used for normal text:
+# - Use "Blokletters-Viltstift" for languages using Latin and Latin-derived alphabets
+# - "DroidSansFallback" can be used for non-Latin writing systems
+#: ../src/Functions.cpp:598
+msgid "Blokletters-Viltstift"
+msgstr "Blokletters-Viltstift"
+
+#: ../src/Functions.cpp:1132
+#: ../src/Functions.cpp:1159
+#: ../src/Functions.cpp:1523
+#: ../src/InputManager.cpp:196
+#: ../src/LevelEditor.cpp:1017
+#: ../src/LevelEditor.cpp:1630
+#: ../src/LevelEditor.cpp:1687
+#: ../src/LevelEditor.cpp:1750
+#: ../src/LevelEditor.cpp:1830
+#: ../src/LevelEditor.cpp:1936
+#: ../src/LevelEditor.cpp:1996
+#: ../src/LevelEditSelect.cpp:175
+#: ../src/LevelEditSelect.cpp:215
+#: ../src/LevelEditSelect.cpp:263
+msgid "OK"
+msgstr "OK"
+
+#: ../src/Functions.cpp:1133
+#: ../src/Functions.cpp:1145
+#: ../src/Functions.cpp:1155
+#: ../src/Functions.cpp:1527
+#: ../src/LevelEditor.cpp:1021
+#: ../src/LevelEditor.cpp:1634
+#: ../src/LevelEditor.cpp:1691
+#: ../src/LevelEditor.cpp:1754
+#: ../src/LevelEditor.cpp:1834
+#: ../src/LevelEditor.cpp:1940
+#: ../src/LevelEditor.cpp:2000
+#: ../src/LevelEditSelect.cpp:179
+#: ../src/LevelEditSelect.cpp:219
+#: ../src/LevelEditSelect.cpp:267
+#: ../src/TitleMenu.cpp:451
+msgid "Cancel"
+msgstr "Indietro"
+
+#: ../src/Functions.cpp:1137
+msgid "Abort"
+msgstr "Rinuncia"
+
+#: ../src/Functions.cpp:1138
+#: ../src/Functions.cpp:1154
+msgid "Retry"
+msgstr "Riprova"
+
+#: ../src/Functions.cpp:1139
+msgid "Ignore"
+msgstr "Ignora"
+
+#: ../src/Functions.cpp:1143
+#: ../src/Functions.cpp:1149
+msgid "Yes"
+msgstr "Sì"
+
+#: ../src/Functions.cpp:1144
+#: ../src/Functions.cpp:1150
+msgid "No"
+msgstr "No"
+
+# TRANSLATORS: Filename is coming before this text
+#: ../src/Functions.cpp:1291
+#, c-format
+msgid ""
+"%s already exists.\n"
+"Do you want to overwrite it?"
+msgstr ""
+"%s esiste già.\n"
+"Vuoi sovrascriverlo?"
+
+#: ../src/Functions.cpp:1291
+msgid "Overwrite Prompt"
+msgstr "Prompt di sovrascrizione"
+
+#: ../src/Functions.cpp:1312
+#: ../src/Functions.cpp:1330
+#, c-format
+msgid "Can't open file %s."
+msgstr "Impossibile aprire il file %s"
+
+#: ../src/Functions.cpp:1312
+#: ../src/Functions.cpp:1330
+msgid "Error"
+msgstr "Errore"
+
+#: ../src/Functions.cpp:1464
+msgid "Save File"
+msgstr "Salva il file"
+
+#: ../src/Functions.cpp:1464
+msgid "Load File"
+msgstr "Carica il file"
+
+#: ../src/Functions.cpp:1468
+msgid "Search In"
+msgstr "Cerca"
+
+#: ../src/Functions.cpp:1478
+msgid "File Name"
+msgstr "Nome file"
+
+# TRANSLATORS: Please do not remove %s or %d from your translation:
+# - %d means the level number in a levelpack
+# - %s means the name of current level
+#: ../src/Game.cpp:233
+#: ../src/Game.cpp:830
+#, c-format
+msgid "Level %d %s"
+msgstr "Livello %d %s"
+
+# TRANSLATORS: Please do not remove %s from your translation:
+# - %s will be replaced with current action key
+#: ../src/Game.cpp:657
+#, c-format
+msgid "Press %s key to save the game."
+msgstr "Premi il tasto %s per salvare il gioco."
+
+# TRANSLATORS: Please do not remove %s from your translation:
+# - %s will be replaced with current action key
+#: ../src/Game.cpp:662
+#, c-format
+msgid "Press %s key to swap the position of player and shadow."
+msgstr "Premi il tasto %s per scambiare la posizione del giocatore con quella dell'ombra."
+
+# TRANSLATORS: Please do not remove %s from your translation:
+# - %s will be replaced with current action key
+#: ../src/Game.cpp:667
+#, c-format
+msgid "Press %s key to activate the switch."
+msgstr "Premi il tasto %s per attivare l'interruttore."
+
+# TRANSLATORS: Please do not remove %s from your translation:
+# - %s will be replaced with current action key
+#: ../src/Game.cpp:672
+#, c-format
+msgid "Press %s key to teleport."
+msgstr "Premi il tasto %s per teletrasportarti."
+
+# TRANSLATORS: Please do not remove %s from your translation:
+# - first %s means currently configured key to restart game
+# - Second %s means configured key to load from last save
+#: ../src/Game.cpp:713
+#, c-format
+msgid "Press %s to restart current level or press %s to load the game."
+msgstr "Premi %s per ricominciare il livello corrente o %s per caricare il gioco."
+
+# TRANSLATORS: Please do not remove %s from your translation:
+# - %s will be replaced with currently configured key to restart game
+#: ../src/Game.cpp:725
+#, c-format
+msgid "Press %s to restart current level."
+msgstr "Premi il tasto %s per ricominciare il livello corrente."
+
+#: ../src/Game.cpp:739
+msgid "Your shadow has died."
+msgstr "La tua ombra è morta."
+
+#: ../src/Game.cpp:782
+#, c-format
+msgid "%d recordings"
+msgstr "%d registrazione"
+
+# TRANSLATORS: This is caption for finished level
+#: ../src/Game.cpp:822
+msgid "You've finished:"
+msgstr "Hai completato:"
+
+# TRANSLATORS: Please do not remove %-.2f from your translation:
+# - %-.2f means time in seconds
+# - s is shortened form of a second. Try to keep it so.
+#: ../src/Game.cpp:1002
+#, c-format
+msgid "Time: %-.2fs"
+msgstr "Tempo: %-.2fs"
+
+# TRANSLATORS: Please do not remove %-.2f from your translation:
+# - %-.2f means time in seconds
+# - s is shortened form of a second. Try to keep it so.
+#: ../src/Game.cpp:1011
+#, c-format
+msgid "Best time: %-.2fs"
+msgstr "Tempo migliore: %-.2fs"
+
+#: ../src/Game.cpp:1022
+#, c-format
+msgid "Target time: %-.2fs"
+msgstr "Tempo obiettivo: %-.2fs"
+
+# TRANSLATORS: Please do not remove %d from your translation:
+# - %d means the number of recordings user has made
+#: ../src/Game.cpp:1043
+#, c-format
+msgid "Recordings: %d"
+msgstr "Registrazione: %d"
+
+# TRANSLATORS: Please do not remove %d from your translation:
+# - %d means the number of recordings user has made
+#: ../src/Game.cpp:1051
+#, c-format
+msgid "Best recordings: %d"
+msgstr "Registrazione migliore: %d"
+
+#: ../src/Game.cpp:1061
+#, c-format
+msgid "Target recordings: %d"
+msgstr "Registrazione obiettivo: %d"
+
+# TRANSLATORS: Please do not remove %s from your translation:
+# - %s will be replaced with name of a prize medal (gold, silver or bronze)
+#: ../src/Game.cpp:1074
+#, c-format
+msgid "You earned the %s medal"
+msgstr "Hai guadagnato la medaglia di %s"
+
+#: ../src/Game.cpp:1074
+msgid "GOLD"
+msgstr "ORO"
+
+#: ../src/Game.cpp:1074
+msgid "SILVER"
+msgstr "ARGENTO"
+
+#: ../src/Game.cpp:1074
+msgid "BRONZE"
+msgstr "BRONZO"
+
+# TRANSLATORS: used as return to the level selector menu
+#: ../src/Game.cpp:1089
+msgid "Menu"
+msgstr "Menu"
+
+# TRANSLATORS: used as restart level
+#: ../src/Game.cpp:1096
+#: ../src/InputManager.cpp:41
+msgid "Restart"
+msgstr "Ricomincia"
+
+# TRANSLATORS: used as next level
+#: ../src/Game.cpp:1103
+msgid "Next"
+msgstr "Prossimo"
+
+#: ../src/Game.cpp:1146
+msgid "Game replay is done."
+msgstr "Il replay di gioco è completato."
+
+#: ../src/Game.cpp:1146
+msgid "Game Replay"
+msgstr "Replay di gioco"
+
+#: ../src/Game.cpp:1303
+#: ../src/Game.cpp:1305
+msgid "Congratulations"
+msgstr "Congratulazioni"
+
+#: ../src/Game.cpp:1305
+msgid "You have finished the levelpack!"
+msgstr "Hai completato il pacchetto di livelli!"
+
+#: ../src/InputManager.cpp:40
+msgid "Up (in menu)"
+msgstr "Su (dal menu)"
+
+#: ../src/InputManager.cpp:40
+msgid "Down (in menu)"
+msgstr "Giù (dal menu)"
+
+#: ../src/InputManager.cpp:40
+msgid "Left"
+msgstr "Sinistra"
+
+#: ../src/InputManager.cpp:40
+msgid "Right"
+msgstr "Destra"
+
+#: ../src/InputManager.cpp:40
+msgid "Jump"
+msgstr "Salta"
+
+#: ../src/InputManager.cpp:40
+msgid "Action"
+msgstr "Azione"
+
+#: ../src/InputManager.cpp:40
+msgid "Space (Record)"
+msgstr "Spazio (registra)"
+
+#: ../src/InputManager.cpp:41
+msgid "Escape"
+msgstr "Esci"
+
+#: ../src/InputManager.cpp:41
+msgid "Tab (View shadow/Level prop.)"
+msgstr "Tab (visualizza ombra/proprietà livello)"
+
+#: ../src/InputManager.cpp:41
+msgid "Save game (in editor)"
+msgstr "Salva gioco (dall'editor)"
+
+#: ../src/InputManager.cpp:41
+msgid "Load game"
+msgstr "Carica gioco"
+
+#: ../src/InputManager.cpp:41
+msgid "Swap (in editor)"
+msgstr "Scambio (dall'editor)"
+
+#: ../src/InputManager.cpp:42
+msgid "Teleport (in editor)"
+msgstr "Teletrasporto (dall'editor)"
+
+#: ../src/InputManager.cpp:42
+msgid "Suicide (in editor)"
+msgstr "Suicidio (dall'editor)"
+
+#: ../src/InputManager.cpp:42
+msgid "Shift (in editor)"
+msgstr "Sposta (dall'editor)"
+
+#: ../src/InputManager.cpp:42
+msgid "Next block type (in Editor)"
+msgstr "Tipo di blocco successivo(dall'editor)"
+
+#: ../src/InputManager.cpp:43
+msgid "Previous block type (in editor)"
+msgstr "Tipo di blocco precedente (dall'editor)"
+
+#: ../src/InputManager.cpp:43
+msgid "Select (in menu)"
+msgstr "Seleziona (dal menu)"
+
+#: ../src/InputManager.cpp:163
+#: ../src/TitleMenu.cpp:430
+msgid "Config Keys"
+msgstr "Configura i tasti"
+
+#: ../src/InputManager.cpp:166
+msgid "Select an item and press a key to config it."
+msgstr "Seleziona una voce e premi un tasto per configurare."
+
+#: ../src/InputManager.cpp:179
+msgid "Primary key"
+msgstr "Tasti primari"
+
+#: ../src/InputManager.cpp:180
+msgid "Alternative key"
+msgstr "Tasti alternativi"
+
+#: ../src/InputManager.cpp:186
+msgid "Unset the key"
+msgstr "Rimuovi il tasto"
+
+#: ../src/InputManager.cpp:300
+msgid "(Not set)"
+msgstr "(non configurato)"
+
+#: ../src/LevelEditor.cpp:121
+msgid "Toolbox"
+msgstr "Toolbox"
+
+#: ../src/LevelEditor.cpp:180
+msgid "Block"
+msgstr "Blocco"
+
+#: ../src/LevelEditor.cpp:180
+msgid "Player Start"
+msgstr "Punto d'inizio giocatore"
+
+#: ../src/LevelEditor.cpp:180
+msgid "Shadow Start"
+msgstr "Punto d'inizio ombra"
+
+#: ../src/LevelEditor.cpp:181
+msgid "Exit"
+msgstr "Uscita"
+
+#: ../src/LevelEditor.cpp:181
+msgid "Shadow Block"
+msgstr "Blocco-ombra"
+
+#: ../src/LevelEditor.cpp:181
+msgid "Spikes"
+msgstr "Spuntoni"
+
+#: ../src/LevelEditor.cpp:182
+msgid "Checkpoint"
+msgstr "Checkpoint"
+
+#: ../src/LevelEditor.cpp:182
+#: ../src/LevelEditSelect.cpp:258
+msgid "Swap"
+msgstr "Scambio"
+
+#: ../src/LevelEditor.cpp:182
+#: ../src/LevelEditor.cpp:1976
+msgid "Fragile"
+msgstr "Fragile"
+
+#: ../src/LevelEditor.cpp:183
+msgid "Moving Block"
+msgstr "Blocco mobile"
+
+#: ../src/LevelEditor.cpp:183
+msgid "Moving Shadow Block"
+msgstr "Blocco-ombra mobile"
+
+#: ../src/LevelEditor.cpp:183
+msgid "Moving Spikes"
+msgstr "Spuntoni mobili"
+
+#: ../src/LevelEditor.cpp:184
+msgid "Teleporter"
+msgstr "Teletrasporto"
+
+#: ../src/LevelEditor.cpp:184
+#: ../src/LevelEditor.cpp:1884
+msgid "Button"
+msgstr "Pulsante"
+
+#: ../src/LevelEditor.cpp:184
+#: ../src/LevelEditor.cpp:1886
+msgid "Switch"
+msgstr "Interruttore"
+
+#: ../src/LevelEditor.cpp:185
+msgid "Conveyor Belt"
+msgstr "Nastro trasportatore"
+
+#: ../src/LevelEditor.cpp:185
+msgid "Shadow Conveyor Belt"
+msgstr "Nastro-ombra trasportatore"
+
+#: ../src/LevelEditor.cpp:185
+msgid "Notification Block"
+msgstr "Blocco di notifica"
+
+#: ../src/LevelEditor.cpp:185
+msgid "Collectable"
+msgstr "Oggetto da collezione"
+
+#: ../src/LevelEditor.cpp:529
+msgid "Are you sure you want to quit?"
+msgstr "Sei sicuro di volere uscire?"
+
+#: ../src/LevelEditor.cpp:529
+msgid "Quit prompt"
+msgstr "Prompt di uscita"
+
+#: ../src/LevelEditor.cpp:957
+#: ../src/LevelEditor.cpp:959
+#: ../src/LevelEditor.cpp:2609
+#: ../src/LevelEditor.cpp:2611
+#, c-format
+msgid "Level \"%s\" saved"
+msgstr "Livello \"%s\" salvato"
+
+#: ../src/LevelEditor.cpp:957
+#: ../src/LevelEditor.cpp:959
+#: ../src/LevelEditor.cpp:2609
+#: ../src/LevelEditor.cpp:2611
+msgid "Saved"
+msgstr "Salvato"
+
+#: ../src/LevelEditor.cpp:972
+#: ../src/LevelEditor.cpp:2732
+msgid "Level settings"
+msgstr "Impostazioni del livello"
+
+#: ../src/LevelEditor.cpp:976
+#: ../src/LevelEditSelect.cpp:154
+msgid "Name:"
+msgstr "Nome:"
+
+#: ../src/LevelEditor.cpp:982
+msgid "Theme:"
+msgstr "Tema:"
+
+#: ../src/LevelEditor.cpp:997
+msgid "Target time (s):"
+msgstr "Tempo obiettivo (s):"
+
+#: ../src/LevelEditor.cpp:1008
+msgid "Target recordings:"
+msgstr "Registrazioni obiettivo:"
+
+#: ../src/LevelEditor.cpp:1576
+#: ../src/LevelEditor.cpp:1793
+msgid "Defined"
+msgstr "Definito"
+
+#: ../src/LevelEditor.cpp:1579
+#: ../src/LevelEditor.cpp:1796
+#: ../src/LevelEditor.cpp:1878
+msgid "None"
+msgstr "Niente"
+
+#: ../src/LevelEditor.cpp:1586
+msgid "Moving block"
+msgstr "Blocco mobile"
+
+#: ../src/LevelEditor.cpp:1589
+msgid "Moving shadow block"
+msgstr "Blocco-ombra mobile"
+
+#: ../src/LevelEditor.cpp:1592
+msgid "Moving spikes"
+msgstr "Spuntoni mobili"
+
+#: ../src/LevelEditor.cpp:1599
+#: ../src/LevelEditor.cpp:1736
+msgid "Enabled"
+msgstr "Attivato"
+
+#: ../src/LevelEditor.cpp:1605
+msgid "Loop"
+msgstr "Ripeti"
+
+#: ../src/LevelEditor.cpp:1611
+msgid "Path"
+msgstr "Percorso"
+
+#: ../src/LevelEditor.cpp:1671
+msgid "Notification block"
+msgstr "Blocco di notifica"
+
+#: ../src/LevelEditor.cpp:1674
+msgid "Enter message here:"
+msgstr "Inserisci qui il messaggio:"
+
+#: ../src/LevelEditor.cpp:1728
+msgid "Shadow Conveyor belt"
+msgstr "Nastro-ombra trasportatore"
+
+#: ../src/LevelEditor.cpp:1730
+msgid "Conveyor belt"
+msgstr "Nastro trasportatore"
+
+#: ../src/LevelEditor.cpp:1742
+msgid "Enter speed here:"
+msgstr "Inserisci qui la velocità:"
+
+#: ../src/LevelEditor.cpp:1800
+msgid "Portal"
+msgstr "Portale"
+
+#: ../src/LevelEditor.cpp:1803
+msgid "Activate on touch"
+msgstr "Attivabile manualmente"
+
+#: ../src/LevelEditor.cpp:1809
+#: ../src/LevelEditor.cpp:1914
+msgid "Targets:"
+msgstr "Obiettivi:"
+
+#: ../src/LevelEditor.cpp:1875
+#, c-format
+msgid "%d Defined"
+msgstr "%d definito"
+
+#: ../src/LevelEditor.cpp:1891
+msgid "Behaviour:"
+msgstr "Comportamento:"
+
+#: ../src/LevelEditor.cpp:1897
+msgid "On"
+msgstr "Attivo"
+
+#: ../src/LevelEditor.cpp:1898
+msgid "Off"
+msgstr "Non attivo"
+
+#: ../src/LevelEditor.cpp:1899
+msgid "Toggle"
+msgstr "Attiva/disattiva"
+
+#: ../src/LevelEditor.cpp:1979
+msgid "State:"
+msgstr "Stato:"
+
+#: ../src/LevelEditor.cpp:1985
+msgid "Complete"
+msgstr "Completo"
+
+#: ../src/LevelEditor.cpp:1986
+msgid "One step"
+msgstr "Primo passo"
+
+#: ../src/LevelEditor.cpp:1987
+msgid "Two steps"
+msgstr "Secondo passo"
+
+#: ../src/LevelEditor.cpp:1988
+msgid "Gone"
+msgstr "Finito"
+
+#: ../src/LevelEditor.cpp:2717
+msgid "Select"
+msgstr "Seleziona"
+
+#: ../src/LevelEditor.cpp:2720
+msgid "Add"
+msgstr "Aggiungi"
+
+#: ../src/LevelEditor.cpp:2723
+msgid "Delete"
+msgstr "Cancella"
+
+#: ../src/LevelEditor.cpp:2726
+msgid "Configure"
+msgstr "Configura"
+
+#: ../src/LevelEditor.cpp:2729
+#: ../src/LevelPlaySelect.cpp:65
+#: ../src/TitleMenu.cpp:47
+msgid "Play"
+msgstr "Gioca"
+
+#: ../src/LevelEditor.cpp:2735
+msgid "Save level"
+msgstr "Salva livello"
+
+#: ../src/LevelEditor.cpp:2738
+msgid "Back to menu"
+msgstr "Ritorna al menu"
+
+#: ../src/LevelEditor.cpp:2776
+#: ../src/LevelEditor.cpp:2782
+#, c-format
+msgid "Movespeed: %s"
+msgstr "Velocità di movimento: %s"
+
+#: ../src/LevelEditSelect.cpp:41
+#: ../src/TitleMenu.cpp:49
+msgid "Map Editor"
+msgstr "Editor di mappe"
+
+#: ../src/LevelEditSelect.cpp:78
+msgid "New Levelpack"
+msgstr "Nuovo pacchetto di livelli"
+
+#: ../src/LevelEditSelect.cpp:83
+msgid "Pack Properties"
+msgstr "Proprietà del pacchetto"
+
+#: ../src/LevelEditSelect.cpp:88
+msgid "Remove Pack"
+msgstr "Rimuovi pacchetto"
+
+#: ../src/LevelEditSelect.cpp:93
+msgid "Move Map"
+msgstr "Sposta mappa"
+
+#: ../src/LevelEditSelect.cpp:99
+msgid "Remove Map"
+msgstr "Rimuovi mappa"
+
+#: ../src/LevelEditSelect.cpp:104
+msgid "Edit Map"
+msgstr "Edita mappa"
+
+#: ../src/LevelEditSelect.cpp:151
+msgid "Properties"
+msgstr "Proprietà"
+
+#: ../src/LevelEditSelect.cpp:161
+msgid "Description:"
+msgstr "Descrizione:"
+
+#: ../src/LevelEditSelect.cpp:168
+msgid "Congratulation text:"
+msgstr "Messaggio di congratulazioni:"
+
+#: ../src/LevelEditSelect.cpp:203
+#: ../src/LevelEditSelect.cpp:371
+msgid "Add level"
+msgstr "Aggiungi livello"
+
+#: ../src/LevelEditSelect.cpp:206
+msgid "File name:"
+msgstr "Nome file:"
+
+#: ../src/LevelEditSelect.cpp:243
+msgid "Move level"
+msgstr "Sposta livello"
+
+#: ../src/LevelEditSelect.cpp:246
+msgid "Level: "
+msgstr "Livello:"
+
+#: ../src/LevelEditSelect.cpp:256
+msgid "Before"
+msgstr "Prima"
+
+#: ../src/LevelEditSelect.cpp:257
+msgid "After"
+msgstr "Dopo"
+
+#: ../src/LevelEditSelect.cpp:439
+msgid "Are you sure?"
+msgstr "Sei sicuro?"
+
+#: ../src/LevelEditSelect.cpp:439
+msgid "Remove prompt"
+msgstr "Prompt di rimozione"
+
+#: ../src/LevelEditSelect.cpp:579
+msgid "No file name given for the new level."
+msgstr "Nessun nome file dato per il nuovo livello."
+
+#: ../src/LevelEditSelect.cpp:579
+msgid "Missing file name"
+msgstr "Nome file mancante"
+
+#: ../src/LevelEditSelect.cpp:656
+msgid "The entered level number isn't valid!"
+msgstr "Il numero livello inserito non è valido!"
+
+#: ../src/LevelEditSelect.cpp:656
+msgid "Illegal number"
+msgstr "Numero incorretto"
+
+#: ../src/LevelPlaySelect.cpp:43
+msgid "Select Level"
+msgstr "Seleziona livello"
+
+#: ../src/LevelPlaySelect.cpp:92
+msgid "Choose a level"
+msgstr "Scegli un livello"
+
+#: ../src/LevelPlaySelect.cpp:93
+#: ../src/LevelPlaySelect.cpp:231
+#: ../src/LevelPlaySelect.cpp:242
+msgid "Time:"
+msgstr "Tempo:"
+
+#: ../src/LevelPlaySelect.cpp:94
+#: ../src/LevelPlaySelect.cpp:240
+#: ../src/LevelPlaySelect.cpp:243
+msgid "Recordings:"
+msgstr "Registrazione:"
+
+#: ../src/TitleMenu.cpp:48
+msgid "Options"
+msgstr "Opzioni"
+
+#: ../src/TitleMenu.cpp:51
+msgid "Quit"
+msgstr "Abbandona"
+
+#: ../src/TitleMenu.cpp:109
+msgid "Enable internet in order to install addons."
+msgstr "Abilita la rete internet per installare le estensioni."
+
+#: ../src/TitleMenu.cpp:109
+msgid "Internet disabled"
+msgstr "Non connesso a internet"
+
+#: ../src/TitleMenu.cpp:188
+msgid "Settings"
+msgstr "Impostazioni"
+
+#: ../src/TitleMenu.cpp:236
+msgid "Music"
+msgstr "Musica"
+
+#: ../src/TitleMenu.cpp:244
+msgid "Sound"
+msgstr "Suono"
+
+#: ../src/TitleMenu.cpp:252
+msgid "Fullscreen"
+msgstr "Schermo intero"
+
+#: ../src/TitleMenu.cpp:257
+msgid "Resolution"
+msgstr "Risoluzione"
+
+#: ../src/TitleMenu.cpp:339
+msgid "Language"
+msgstr "Lingua"
+
+# TRANSLATORS: as detect user's language automatically
+#: ../src/TitleMenu.cpp:348
+msgid "Auto-Detect"
+msgstr "Rilevamento automatico"
+
+#: ../src/TitleMenu.cpp:376
+msgid "Theme"
+msgstr "Tema"
+
+#: ../src/TitleMenu.cpp:409
+msgid "Level themes"
+msgstr "Temi del livello"
+
+#: ../src/TitleMenu.cpp:414
+msgid "Internet"
+msgstr "Internet"
+
+#: ../src/TitleMenu.cpp:420
+msgid "Internet proxy"
+msgstr "Internet proxy"
+
+# TRANSLATORS: Used for button which clear any level progress like unlocked levels and highscores.
+#: ../src/TitleMenu.cpp:437
+msgid "Clear Progress"
+msgstr "Cancella progresso"
+
+#: ../src/TitleMenu.cpp:456
+msgid "Save Changes"
+msgstr "Salva cambiamenti"
+
+#: ../src/TitleMenu.cpp:564
+msgid "Do you really want to reset level progress?"
+msgstr "Vuoi davvero cancellare tutto il progresso dei livelli?"
+
+#: ../src/TitleMenu.cpp:564
+msgid "Warning"
+msgstr "Avviso"
+
+# TRANSLATORS: name of a key
+msgid "backspace"
+msgstr "backspace"
+
+# TRANSLATORS: name of a key
+msgid "tab"
+msgstr "tab"
+
+# TRANSLATORS: name of a key
+msgid "clear"
+msgstr "annulla"
+
+# TRANSLATORS: name of a key
+msgid "return"
+msgstr "invio"
+
+# TRANSLATORS: name of a key
+msgid "pause"
+msgstr "pausa"
+
+# TRANSLATORS: name of a key
+msgid "escape"
+msgstr "escape"
+
+# TRANSLATORS: name of a key
+msgid "space"
+msgstr "spazio"
+
+# TRANSLATORS: name of a key
+msgid "delete"
+msgstr "cancella"
+
+# TRANSLATORS: name of a key
+msgid "enter"
+msgstr "invio"
+
+# TRANSLATORS: name of a key
+msgid "equals"
+msgstr "equals"
+
+# TRANSLATORS: name of a key
+msgid "up"
+msgstr "su"
+
+# TRANSLATORS: name of a key
+msgid "down"
+msgstr "giù"
+
+# TRANSLATORS: name of a key
+msgid "right"
+msgstr "destra"
+
+# TRANSLATORS: name of a key
+msgid "left"
+msgstr "sinistra"
+
+# TRANSLATORS: name of a key
+msgid "insert"
+msgstr "inserimento"
+
+# TRANSLATORS: name of a key
+msgid "home"
+msgstr "home"
+
+# TRANSLATORS: name of a key
+msgid "end"
+msgstr "fine"
+
+# TRANSLATORS: name of a key
+msgid "page up"
+msgstr "pagina su"
+
+# TRANSLATORS: name of a key
+msgid "page down"
+msgstr "pagina giù"
+
+# TRANSLATORS: name of a key
+msgid "numlock"
+msgstr "blocco numeri"
+
+# TRANSLATORS: name of a key
+msgid "caps lock"
+msgstr "blocco maiuscole"
+
+# TRANSLATORS: name of a key
+msgid "scroll lock"
+msgstr "blocco scorrimento"
+
+# TRANSLATORS: name of a key
+msgid "right shift"
+msgstr "shift destro"
+
+# TRANSLATORS: name of a key
+msgid "left shift"
+msgstr "shift sinistro"
+
+# TRANSLATORS: name of a key
+msgid "right ctrl"
+msgstr "ctrl destro"
+
+# TRANSLATORS: name of a key
+msgid "left ctrl"
+msgstr "ctrl sinistro"
+
+# TRANSLATORS: name of a key
+msgid "right alt"
+msgstr "alt destro"
+
+# TRANSLATORS: name of a key
+msgid "left alt"
+msgstr "alt sinistro"
+
+# TRANSLATORS: name of a key
+msgid "right meta"
+msgstr "meta destro"
+
+# TRANSLATORS: name of a key
+msgid "left meta"
+msgstr "meta sinistro"
+
+# TRANSLATORS: name of a key
+msgid "left super"
+msgstr "super sinistro"
+
+# TRANSLATORS: name of a key
+msgid "right super"
+msgstr "super destro"
+
+# TRANSLATORS: name of a key
+msgid "alt gr"
+msgstr "alt gr"
+
+# TRANSLATORS: name of a key
+msgid "compose"
+msgstr "componi"
+
+# TRANSLATORS: name of a key
+msgid "help"
+msgstr "aiuto"
+
+# TRANSLATORS: name of a key
+msgid "print screen"
+msgstr "stampa schermo"
+
+# TRANSLATORS: name of a key
+msgid "sys req"
+msgstr "sys req"
+
+# TRANSLATORS: name of a key
+msgid "break"
+msgstr "interrompi"
+
+# TRANSLATORS: name of a key
+msgid "menu"
+msgstr "menu"
+
+# TRANSLATORS: name of a key
+msgid "power"
+msgstr "power"
+
+# TRANSLATORS: name of a key
+msgid "euro"
+msgstr "euro"
+
+# TRANSLATORS: name of a key
+msgid "undo"
+msgstr "undo"
+
diff --git a/src/Functions.cpp b/src/Functions.cpp
index 32324a6..ce85c68 100644
--- a/src/Functions.cpp
+++ b/src/Functions.cpp
@@ -1,1518 +1,1518 @@
/****************************************************************************
** Copyright (C) 2011 Luka Horvat <redreaper132 at gmail.com>
** Copyright (C) 2011 Edward Lii <edward_iii at myway.com>
** Copyright (C) 2011 O. Bahri Gordebak <gordebak at gmail.com>
**
**
** This file may be used under the terms of the GNU General Public
** License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of
** this file.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
**
****************************************************************************/
#include <stdio.h>
#include <algorithm>
#include <SDL/SDL.h>
#include <SDL/SDL_mixer.h>
#include <SDL/SDL_gfxPrimitives.h>
#include <SDL/SDL_rotozoom.h>
#include <SDL/SDL_syswm.h>
#include <string>
#include "Globals.h"
#include "Functions.h"
#include "FileManager.h"
#include "Objects.h"
#include "Player.h"
#include "GameObjects.h"
#include "LevelPack.h"
#include "TitleMenu.h"
#include "LevelEditSelect.h"
#include "LevelEditor.h"
#include "Game.h"
#include "LevelPlaySelect.h"
#include "Addons.h"
#include "InputManager.h"
#include "ImageManager.h"
#include "MusicManager.h"
#include "LevelPackManager.h"
#include "ThemeManager.h"
#include "GUIListBox.h"
#include "GUIOverlay.h"
#include "libs/tinyformat/tinyformat.h"
#include "libs/tinygettext/tinygettext.hpp"
#include "libs/tinygettext/log.hpp"
extern "C" {
#include "libs/findlocale/findlocale.h"
}
#ifdef HARDWARE_ACCELERATION
#include <GL/gl.h>
#include <GL/glu.h>
//fix some Windows header bug
#ifndef GL_BGR
#define GL_BGR GL_BGR_EXT
#endif
#ifndef GL_BGRA
#define GL_BGRA GL_BGRA_EXT
#endif
#endif
using namespace std;
#ifdef WIN32
#include <windows.h>
#include <shlobj.h>
#else
#include <strings.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <dirent.h>
#endif
//Workaround for the resizing below 800x600 for X systems.
#ifdef __linux__
#include<X11/Xlib.h>
#include<X11/Xutil.h>
#endif
//Initialise the imagemanager.
//The ImageManager is used to prevent loading images multiple times.
ImageManager imageManager;
//Initialise the musicManager.
//The MusicManager is used to prevent loading music files multiple times and for playing/fading music.
MusicManager musicManager;
//Initialise the levelPackManager.
//The LevelPackManager is used to prevent loading levelpacks multiple times and for the game to know which levelpacks there are.
LevelPackManager levelPackManager;
//Map containing changed settings using command line arguments.
map<string,string> tmpSettings;
//Pointer to the settings object.
//It is used to load and save the settings file and change the settings.
Settings* settings=0;
#ifdef HARDWARE_ACCELERATION
GLuint screenTexture;
#endif
SDL_Surface* loadImage(string file){
//We use the imageManager to load the file.
return imageManager.loadImage(file);
}
void applySurface(int x,int y,SDL_Surface* source,SDL_Surface* dest,SDL_Rect* clip){
//The offset is needed to draw at the right location.
SDL_Rect offset;
offset.x=x;
offset.y=y;
//Let SDL do the drawing of the surface.
SDL_BlitSurface(source,clip,dest,&offset);
}
void drawRect(int x,int y,int w,int h,SDL_Surface* dest,Uint32 color){
//NOTE: We let SDL_gfx render it.
rectangleRGBA(dest,x,y,x+w,y+h,color >> 24,color >> 16,color >> 8,255);
}
//Draw a box with anti-aliased borders using SDL_gfx.
void drawGUIBox(int x,int y,int w,int h,SDL_Surface* dest,Uint32 color){
//Fill content's background color from function parameter
boxRGBA(dest,x+1,y+1,x+w-2,y+h-2,color >> 24,color >> 16,color >> 8,color >> 0);
//Draw first black borders around content and leave 1 pixel in every corner
lineRGBA(dest,x+1,y,x+w-2,y,0,0,0,255);
lineRGBA(dest,x+1,y+h-1,x+w-2,y+h-1,0,0,0,255);
lineRGBA(dest,x,y+1,x,y+h-2,0,0,0,255);
lineRGBA(dest,x+w-1,y+1,x+w-1,y+h-2,0,0,0,255);
//Fill the corners with transperent color to create anti-aliased borders
pixelRGBA(dest,x,y,0,0,0,160);
pixelRGBA(dest,x,y+h-1,0,0,0,160);
pixelRGBA(dest,x+w-1,y,0,0,0,160);
pixelRGBA(dest,x+w-1,y+h-1,0,0,0,160);
//Draw second lighter border around content
rectangleRGBA(dest,x+1,y+1,x+w-2,y+h-2,0,0,0,64);
//Create anti-aliasing in corners of second border
pixelRGBA(dest,x+1,y+1,0,0,0,50);
pixelRGBA(dest,x+1,y+h-2,0,0,0,50);
pixelRGBA(dest,x+w-2,y+1,0,0,0,50);
pixelRGBA(dest,x+w-2,y+h-2,0,0,0,50);
}
void drawLine(int x1,int y1,int x2,int y2,SDL_Surface* dest,Uint32 color){
//NOTE: We let SDL_gfx render it.
lineRGBA(dest,x1,y1,x2,y2,color >> 24,color >> 16,color >> 8,255);
}
void drawLineWithArrow(int x1,int y1,int x2,int y2,SDL_Surface* dest,Uint32 color,int spacing,int offset,int xsize,int ysize){
//Draw line first
drawLine(x1,y1,x2,y2,dest,color);
//calc delta and length
double dx=x2-x1;
double dy=y2-y1;
double length=sqrt(dx*dx+dy*dy);
if(length<0.001) return;
//calc the unit vector
dx/=length; dy/=length;
//Now draw arrows on it
for(double p=offset;p<length;p+=spacing){
drawLine(int(x1+p*dx+0.5),int(y1+p*dy+0.5),
int(x1+(p-xsize)*dx-ysize*dy+0.5),int(y1+(p-xsize)*dy+ysize*dx+0.5),dest,color);
drawLine(int(x1+p*dx+0.5),int(y1+p*dy+0.5),
int(x1+(p-xsize)*dx+ysize*dy+0.5),int(y1+(p-xsize)*dy-ysize*dx+0.5),dest,color);
}
}
bool createScreen(){
//Check if we are going fullscreen.
if(settings->getBoolValue("fullscreen"))
pickFullscreenResolution();
//Set the screen_width and height.
SCREEN_WIDTH=atoi(settings->getValue("width").c_str());
SCREEN_HEIGHT=atoi(settings->getValue("height").c_str());
//Update the camera.
camera.w=SCREEN_WIDTH;
camera.h=SCREEN_HEIGHT;
//Boolean if this is the first screen creation.
bool initial=true;
//Check if we should use gl or software rendering.
if(settings->getBoolValue("gl")){
#ifdef HARDWARE_ACCELERATION
SDL_GL_SetAttribute(SDL_GL_RED_SIZE,8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE,8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE,8);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE,16);
SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE,32);
SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE,8);
SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE,8);
SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE,8);
SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE,8);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS,0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES,0);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1);
//Set the video mode.
Uint32 flags=SDL_HWSURFACE | SDL_OPENGL;
if(settings->getBoolValue("fullscreen"))
flags|=SDL_FULLSCREEN;
else if(settings->getBoolValue("resizable"))
flags|=SDL_RESIZABLE;
if(SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,flags)==NULL){
fprintf(stderr,"FATAL ERROR: SDL_SetVideoMode failed\n");
return false;
}
//Delete the old screen.
//Warning: only if previous mode is OpenGL mode.
//NOTE: The previous mode can't switch during runtime.
if(screen){
SDL_FreeSurface(screen);
screen=NULL;
//There was a screen so this isn't the initial screen creation.
initial=false;
}
//Create a screen
screen=SDL_CreateRGBSurface(SDL_HWSURFACE,SCREEN_WIDTH,SCREEN_HEIGHT,32,0x00FF0000,0x0000FF00,0x000000FF,0);
//Create a texture.
glDeleteTextures(1,&screenTexture);
glGenTextures(1,&screenTexture);
//And set up gl correctly.
glClearColor(0, 0, 0, 0);
glClearDepth(1.0f);
glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 1, -1);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_TEXTURE_2D);
glLoadIdentity();
#else
//NOTE: Hardware accelerated rendering requested but compiled without.
cerr<<"FATAL ERROR: Unable to use hardware acceleration (compiled without)."<<endl;
return false;
#endif
}else{
//Set the flags.
Uint32 flags=SDL_HWSURFACE | SDL_DOUBLEBUF;
if(settings->getBoolValue("fullscreen"))
flags|=SDL_FULLSCREEN;
else if(settings->getBoolValue("resizable"))
flags|=SDL_RESIZABLE;
//Check if there already was a screen.
if(screen)
initial=false;
//Create the screen and check if there weren't any errors.
screen=SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,flags);
if(screen==NULL){
fprintf(stderr,"FATAL ERROR: SDL_SetVideoMode failed\n");
return false;
}
}
//Now configure the newly created window (if windowed).
if(settings->getBoolValue("fullscreen")==false)
configureWindow(initial);
//Create the temp surface, just a replica of the screen surface, free the previous one if any.
if(tempSurface)
SDL_FreeSurface(tempSurface);
tempSurface=SDL_CreateRGBSurface(SDL_HWSURFACE|SDL_SRCALPHA,
screen->w,screen->h,screen->format->BitsPerPixel,
screen->format->Rmask,screen->format->Gmask,screen->format->Bmask,0);
//Set the the window caption.
SDL_WM_SetCaption(("Me and My Shadow "+version).c_str(),NULL);
SDL_EnableUNICODE(1);
//Nothing went wrong so return true.
return true;
}
#ifdef WIN32
static WNDPROC m_OldWindowProc=NULL;
static LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){
if(msg==WM_GETMINMAXINFO){
if(m_OldWindowProc){
CallWindowProc(m_OldWindowProc,hwnd,msg,wParam,lParam);
}else{
DefWindowProc(hwnd,msg,wParam,lParam);
}
RECT r={0,0,800,600};
AdjustWindowRect(&r,GetWindowLong(hwnd,GWL_STYLE),FALSE);
MINMAXINFO *info=(MINMAXINFO*)lParam;
info->ptMinTrackSize.x=r.right-r.left;
info->ptMinTrackSize.y=r.bottom-r.top;
return 0;
}else{
if(m_OldWindowProc){
return CallWindowProc(m_OldWindowProc,hwnd,msg,wParam,lParam);
}else{
return DefWindowProc(hwnd,msg,wParam,lParam);
}
}
}
#endif
void pickFullscreenResolution(){
//Vector that will hold the resolutions to choose from.
vector<_res> resolutionList;
//Enumerate avaliable resolutions using SDL_ListModes()
//Note: we enumerate fullscreen resolutions because
// windowed resolutions always can be arbitrary
if(resolutionList.empty()){
SDL_Rect **modes=SDL_ListModes(NULL,SDL_FULLSCREEN|SDL_HWSURFACE);
if(modes==NULL || ((intptr_t)modes) == -1){
cout<<"Error: Can't enumerate avaliable screen resolutions."
" Use predefined screen resolutions list instead."<<endl;
static const _res predefinedResolutionList[] = {
{800,600},
{1024,600},
{1024,768},
{1152,864},
{1280,720},
{1280,768},
{1280,800},
{1280,960},
{1280,1024},
{1360,768},
{1366,768},
{1440,900},
{1600,900},
{1600,1200},
{1680,1080},
{1920,1080},
{1920,1200},
{2560,1440},
{3840,2160}
};
//Fill the resolutionList.
for(unsigned int i=0;i<sizeof(predefinedResolutionList)/sizeof(_res);i++){
resolutionList.push_back(predefinedResolutionList[i]);
}
}else{
//Fill the resolutionList.
for(unsigned int i=0;modes[i]!=NULL;i++){
//Check if the resolution is higher than the minimum (800x600).
if(modes[i]->w>=800 && modes[i]->h>=600){
_res res={modes[i]->w, modes[i]->h};
resolutionList.push_back(res);
}
}
//Reverse it so that we begin with the lowest resolution.
reverse(resolutionList.begin(),resolutionList.end());
}
}
//The resolution that will hold the final result, we start with the minimum (800x600).
_res closestMatch={800,600};
int width=atoi(getSettings()->getValue("width").c_str());
int height=atoi(getSettings()->getValue("height").c_str());
//Now loop through the resolutionList.
for(int i=0;i<(int)resolutionList.size();i++){
//The delta between the closestMatch and the resolution from the list.
int dM=(closestMatch.w-resolutionList[i].w);
//The delta between the target width and the resolution from the list.
int dT=(width-resolutionList[i].w);
//Since the resolutions are getting higher the lower (more negative) the further away it is.
//That's why we check if the deltaMatch is lower than the the deltaTarget.
if((dM)<(dT)){
closestMatch.w=resolutionList[i].w;
closestMatch.h=resolutionList[i].h;
}
}
//Now set the resolution to the closest match.
char s[64];
sprintf(s,"%d",closestMatch.w);
getSettings()->setValue("width",s);
sprintf(s,"%d",closestMatch.h);
getSettings()->setValue("height",s);
}
void configureWindow(bool initial){
//We only need to configure the window if it's resizable.
if(!getSettings()->getBoolValue("resizable"))
return;
//Retrieve the WM info from SDL containing the window handle.
struct SDL_SysWMinfo wmInfo;
SDL_VERSION(&wmInfo.version);
SDL_GetWMInfo(&wmInfo);
#ifdef __linux__
//We assume that a linux system running meandmyshadow is also running an Xorg server.
if(wmInfo.subsystem==SDL_SYSWM_X11){
//Create the size hints to give to the window.
XSizeHints* sizeHints;
if(!(sizeHints=XAllocSizeHints())){
cerr<<"ERROR: Unable to allocate memory for XSizeHings."<<endl;
return;
}
//Configure the size hint.
sizeHints->flags=PMinSize;
sizeHints->min_width=800;
sizeHints->min_height=600;
//Set the normal hints of the window.
(void)wmInfo.info.x11.lock_func;
XSetNormalHints(wmInfo.info.x11.display,wmInfo.info.x11.wmwindow,sizeHints);
(void)wmInfo.info.x11.unlock_func;
//Free size hint structure
XFree(sizeHints);
}else{
//No X11 so an unsupported window manager.
cerr<<"WARNING: Unsupported window manager."<<endl;
}
#elif defined(WIN32)
//We overwrite the window proc of SDL
WNDPROC wndproc=(WNDPROC)GetWindowLong(wmInfo.window,GWL_WNDPROC);
if(wndproc!=NULL && wndproc!=(WNDPROC)WindowProc){
m_OldWindowProc=wndproc;
SetWindowLong(wmInfo.window,GWL_WNDPROC,(LONG)(WNDPROC)WindowProc);
}
#endif
}
void onVideoResize(){
//Check if the resize event isn't malformed.
if(event.resize.w<=0 || event.resize.h<=0)
return;
//Check the size limit.
if(event.resize.w<800)
event.resize.w=800;
if(event.resize.h<600)
event.resize.h=600;
//Check if it really resizes.
if(SCREEN_WIDTH==event.resize.w && SCREEN_HEIGHT==event.resize.h)
return;
char s[32];
//Set the new width and height.
sprintf(s,"%d",event.resize.w);
getSettings()->setValue("width",s);
sprintf(s,"%d",event.resize.h);
getSettings()->setValue("height",s);
//Do resizing.
if(!createScreen())
return;
//Tell the theme to resize.
if(!loadTheme())
return;
//The new resolution is valid.
//Now we can save the settings. (TODO: should we save?)
//saveSettings();
//And let the currentState update it's GUI to the new resolution.
currentState->resize();
}
bool init(){
//Initialze SDL.
if(SDL_Init(SDL_INIT_EVERYTHING)==-1) {
fprintf(stderr,"FATAL ERROR: SDL_Init failed\n");
return false;
}
//Initialze SDL_mixer (audio).
if(Mix_OpenAudio(22050,MIX_DEFAULT_FORMAT,2,512)==-1){
fprintf(stderr,"FATAL ERROR: Mix_OpenAudio failed\n");
return false;
}
//Set the volume.
Mix_Volume(-1,atoi(settings->getValue("sound").c_str()));
//Initialze SDL_ttf (fonts).
if(TTF_Init()==-1){
fprintf(stderr,"FATAL ERROR: TTF_Init failed\n");
return false;
}
//Create the screen.
if(!createScreen())
return false;
//Load key config. Then initalize joystick support.
inputMgr.loadConfig();
inputMgr.openAllJoysitcks();
//Init tinygettext for translations for the right language
dictionaryManager = new tinygettext::DictionaryManager();
dictionaryManager->add_directory(getDataPath()+"locale");
dictionaryManager->set_charset("UTF-8");
//Check if user have defined own language. If not, find it out for the player using findlocale
string lang=getSettings()->getValue("lang");
if(lang.length()>0){
printf("Locale set by user to %s\n",lang.c_str());
language=lang;
}else{
FL_Locale *locale;
FL_FindLocale(&locale,FL_MESSAGES);
printf("Locale isn't set by user: %s\n",locale->lang);
language=locale->lang;
if(locale->country!=NULL){
language+=string("_")+string(locale->country);
}
if(locale->variant!=NULL){
language+=string("@")+string(locale->variant);
}
FL_FreeLocale(&locale);
}
//Now set the language in the dictionaryManager.
dictionaryManager->set_language(tinygettext::Language::from_name(language));
//Disable annoying 'Couldn't translate: blah blah blah'
tinygettext::Log::set_log_info_callback(NULL);
//Create the types of blocks.
for(int i=0;i<TYPE_MAX;i++){
Game::blockNameMap[Game::blockName[i]]=i;
}
//Nothing went wrong so we return true.
return true;
}
static TTF_Font* loadFont(const char* name,int size){
TTF_Font* tmpFont=TTF_OpenFont((getDataPath()+"font/"+name+".ttf").c_str(),size);
if(tmpFont){
return tmpFont;
}else{
return TTF_OpenFont((getDataPath()+"font/DroidSansFallback.ttf").c_str(),size);
}
}
bool loadFonts(){
//Load the fonts.
//NOTE: This is a separate method because it will be called separately when re-initing in case of language change.
//First close the fonts if needed.
if(fontTitle)
TTF_CloseFont(fontTitle);
if(fontGUI)
TTF_CloseFont(fontGUI);
if(fontGUISmall)
TTF_CloseFont(fontGUISmall);
if(fontText)
TTF_CloseFont(fontText);
/// TRANSLATORS: Font used in GUI:
/// - Use "knewave" for languages using Latin and Latin-derived alphabets
/// - "DroidSansFallback" can be used for non-Latin writing systems
fontTitle=loadFont(_("knewave"),55);
fontGUI=loadFont(_("knewave"),32);
fontGUISmall=loadFont(_("knewave"),24);
/// TRANSLATORS: Font used for normal text:
/// - Use "Blokletters-Viltstift" for languages using Latin and Latin-derived alphabets
/// - "DroidSansFallback" can be used for non-Latin writing systems
fontText=loadFont(_("Blokletters-Viltstift"),16);
if(fontTitle==NULL || fontGUI==NULL || fontGUISmall==NULL || fontText==NULL){
printf("ERROR: Unable to load fonts! \n");
return false;
}
//Nothing went wrong so return true.
return true;
}
bool loadTheme(){
SDL_Surface *surface;
//Load the menu background.
surface=loadImage(getDataPath()+"gfx/menu/background.png");
if(surface==NULL){
printf("ERROR: Unable to load menu background.\n");
return false;
}
//Check if previous background exists and it's not cached by image manager
if(menuBackground!=NULL && menuBackground!=surface){
SDL_FreeSurface(menuBackground);
}
menuBackground=surface;
//Check if the menu background needs to be scaled.
if(menuBackground->w!=SCREEN_WIDTH || menuBackground->h!=SCREEN_HEIGHT){
menuBackground=zoomSurface(menuBackground,double(SCREEN_WIDTH)/double(menuBackground->w),double(SCREEN_HEIGHT)/double(menuBackground->h),0);
}
//Load the default theme, if it isn't loaded already.
if(objThemes.themeCount()==0){
if(objThemes.appendThemeFromFile(getDataPath()+"themes/Cloudscape/theme.mnmstheme")==NULL){
printf("ERROR: Can't load default theme file\n");
return false;
}
}else{
//Let the themes scale to the new resolution.
objThemes.scaleToScreen();
}
//Everything went fine so return true.
return true;
}
bool loadFiles(){
- musicManager.destroy();
+ musicManager.destroy();
//Load the music and play it.
if(musicManager.loadMusic((getDataPath()+"music/menu.music")).empty()){
printf("WARNING: Unable to load background music! \n");
}
musicManager.playMusic("menu",false);
//Always load the default music list for fallback.
musicManager.loadMusicList((getDataPath()+"music/default.list"));
//Load the configured music list.
getMusicManager()->loadMusicList((getDataPath()+"music/"+getSettings()->getValue("musiclist")+".list"));
getMusicManager()->setMusicList(getSettings()->getValue("musiclist"));
//Check if music is enabled.
if(getSettings()->getBoolValue("music"))
getMusicManager()->setEnabled();
//Load the fonts.
if(!loadFonts())
return false;
levelPackManager.destroy();
//Now sum up all the levelpacks.
vector<string> v=enumAllDirs(getDataPath()+"levelpacks/");
for(vector<string>::iterator i=v.begin(); i!=v.end(); ++i){
levelPackManager.loadLevelPack(getDataPath()+"levelpacks/"+*i);
}
v=enumAllDirs(getUserPath(USER_DATA)+"levelpacks/");
for(vector<string>::iterator i=v.begin(); i!=v.end(); ++i){
levelPackManager.loadLevelPack(getUserPath(USER_DATA)+"levelpacks/"+*i);
}
v=enumAllDirs(getUserPath(USER_DATA)+"custom/levelpacks/");
for(vector<string>::iterator i=v.begin(); i!=v.end(); ++i){
levelPackManager.loadLevelPack(getUserPath(USER_DATA)+"custom/levelpacks/"+*i);
}
//Now we add a special levelpack that will contain the levels not in a levelpack.
LevelPack* levelsPack=new LevelPack;
levelsPack->levelpackName="Levels";
LevelPack* customLevelsPack=new LevelPack;
customLevelsPack->levelpackName="Custom Levels";
//List the addon levels and add them one for one.
v=enumAllFiles(getUserPath(USER_DATA)+"levels/");
for(vector<string>::iterator i=v.begin(); i!=v.end(); ++i){
levelsPack->addLevel(getUserPath(USER_DATA)+"levels/"+*i);
levelsPack->setLocked(levelsPack->getLevelCount()-1);
}
//List the custom levels and add them one for one.
v=enumAllFiles(getUserPath(USER_DATA)+"custom/levels/");
for(vector<string>::iterator i=v.begin(); i!=v.end(); ++i){
levelsPack->addLevel(getUserPath(USER_DATA)+"custom/levels/"+*i);
levelsPack->setLocked(levelsPack->getLevelCount()-1);
customLevelsPack->addLevel(getUserPath(USER_DATA)+"custom/levels/"+*i);
customLevelsPack->setLocked(customLevelsPack->getLevelCount()-1);
}
//Add them to the manager.
levelPackManager.addLevelPack(levelsPack);
levelPackManager.addLevelPack(customLevelsPack);
//Load the theme, both menu and default.
if(!loadTheme())
return false;
//Nothing failed so return true.
return true;
}
bool loadSettings(){
settings=new Settings(getUserPath(USER_CONFIG)+"meandmyshadow.cfg");
settings->parseFile();
//Now apply settings changed through command line arguments, if any.
map<string,string>::iterator it;
for(it=tmpSettings.begin();it!=tmpSettings.end();++it){
settings->setValue(it->first,it->second);
}
tmpSettings.clear();
//Always return true?
return true;
}
bool saveSettings(){
settings->save();
//Always return true?
return true;
}
Settings* getSettings(){
return settings;
}
MusicManager* getMusicManager(){
return &musicManager;
}
LevelPackManager* getLevelPackManager(){
return &levelPackManager;
}
void flipScreen(){
if(settings->getBoolValue("gl")){
#ifdef HARDWARE_ACCELERATION
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
//Create a texture from the screen surface.
glBindTexture(GL_TEXTURE_2D,screenTexture);
//Set the texture's stretching properties
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D,0,screen->format->BytesPerPixel,screen->w,screen->h,0,GL_BGRA,GL_UNSIGNED_BYTE,screen->pixels);
glBegin(GL_QUADS);
glTexCoord2i(0,0); glVertex3f(0,0,0);
glTexCoord2i(1,0); glVertex3f(SCREEN_WIDTH,0,0);
glTexCoord2i(1,1); glVertex3f(SCREEN_WIDTH,SCREEN_HEIGHT,0);
glTexCoord2i(0,1); glVertex3f(0,SCREEN_HEIGHT,0);
glEnd();
SDL_GL_SwapBuffers();
#else
//NOTE: Trying to flip the screen using gl while compiled without.
cerr<<"FATAL ERROR: Unable to draw to screen using OpenGL (compiled without)."<<endl;
#endif
}else{
SDL_Flip(screen);
}
}
void clean(){
//We delete the settings.
if(settings){
delete settings;
settings=NULL;
}
//Get rid of the currentstate.
//NOTE: The state is probably already deleted by the changeState function.
if(currentState)
delete currentState;
//Destroy the GUI if present.
if(GUIObjectRoot){
delete GUIObjectRoot;
GUIObjectRoot=NULL;
}
//Destroy the imageManager.
imageManager.destroy();
//Destroy the musicManager.
musicManager.destroy();
//Destroy the levelPackManager.
levelPackManager.destroy();
levels=NULL;
//Close all joysticks.
inputMgr.closeAllJoysticks();
//Close the fonts and quit SDL_ttf.
TTF_CloseFont(fontTitle);
TTF_CloseFont(fontGUI);
TTF_CloseFont(fontGUISmall);
TTF_CloseFont(fontText);
TTF_Quit();
//Remove the temp surface.
SDL_FreeSurface(tempSurface);
//Quit SDL.
SDL_Quit();
//And finally stop audio.
Mix_CloseAudio();
}
void setNextState(int newstate){
//Only change the state when we aren't already exiting.
if(nextState!=STATE_EXIT){
nextState=newstate;
}
}
void changeState(){
//Check if there's a nextState.
if(nextState!=STATE_NULL){
//Delete the currentState.
delete currentState;
currentState=NULL;
//Set the currentState to the nextState.
stateID=nextState;
nextState=STATE_NULL;
//Init the state.
switch(stateID){
case STATE_GAME:
currentState=new Game();
break;
case STATE_MENU:
currentState=new Menu();
break;
case STATE_LEVEL_SELECT:
currentState=new LevelPlaySelect();
break;
case STATE_LEVEL_EDIT_SELECT:
currentState=new LevelEditSelect();
break;
case STATE_LEVEL_EDITOR:
currentState=new LevelEditor();
break;
case STATE_OPTIONS:
currentState=new Options();
break;
case STATE_ADDONS:
currentState=new Addons();
break;
}
//NOTE: STATE_EXIT isn't mentioned, meaning that currentState is null.
//This way the game loop will break and the program will exit.
//Fade out.
int fade=255;
SDL_BlitSurface(screen,NULL,tempSurface,NULL);
while(fade>0){
fade-=17;
if(fade<0)
fade=0;
SDL_FillRect(screen,NULL,0);
SDL_SetAlpha(tempSurface, SDL_SRCALPHA, fade);
SDL_BlitSurface(tempSurface,NULL,screen,NULL);
flipScreen();
SDL_Delay(25);
}
}
}
void musicStoppedHook(){
//We just call the musicStopped method of the MusicManager.
musicManager.musicStopped();
}
bool checkCollision(const SDL_Rect& a,const SDL_Rect& b){
//Check if the left side of box a isn't past the right side of b.
if(a.x>=b.x+b.w){
return false;
}
//Check if the right side of box a isn't left of the left side of b.
if(a.x+a.w<=b.x){
return false;
}
//Check if the top side of box a isn't under the bottom side of b.
if(a.y>=b.y+b.h){
return false;
}
//Check if the bottom side of box a isn't above the top side of b.
if(a.y+a.h<=b.y){
return false;
}
//We have collision.
return true;
}
void setCamera(const SDL_Rect& r1,const SDL_Rect& r2){
//SetCamera only works in the Level editor and mouse is inside window.
if(stateID==STATE_LEVEL_EDITOR&&(SDL_GetAppState()&SDL_APPMOUSEFOCUS)){
//Get the mouse coordinates.
int x,y;
SDL_GetMouseState(&x,&y);
//Make sure we avoid the toolbar.
SDL_Rect mouse={x,y,0,0};
//SDL_Rect toolbar={(SCREEN_WIDTH-460)/2,SCREEN_HEIGHT-50,460,50};
if(checkCollision(mouse,r1))
return;
if(checkCollision(mouse,r2))
return;
//Check if the mouse is near the left edge of the screen.
//Else check if the mouse is near the right edge.
if(x<50){
//We're near the left edge so move the camera.
camera.x-=5;
}else if(x>SCREEN_WIDTH-50){
//We're near the right edge so move the camera.
camera.x+=5;
}
//Check if the mouse is near the top edge of the screen.
//Else check if the mouse is near the bottom edge.
if(y<50){
//We're near the top edge so move the camera.
camera.y-=5;
}else if(y>SCREEN_HEIGHT-50){
//We're near the bottom edge so move the camera.
camera.y+=5;
}
}
}
int parseArguments(int argc, char** argv){
//Loop through all arguments.
//We start at one since 0 is the command itself.
for(int i=1;i<argc;i++){
string argument=argv[i];
//Check if the argument is the data-dir.
if(argument=="--data-dir"){
//We need a second argument so we increase i.
i++;
if(i>=argc){
printf("ERROR: Missing argument for command '%s'\n\n",argument.c_str());
return -1;
}
//Configure the dataPath with the given path.
dataPath=argv[i];
if(!getDataPath().empty()){
char c=dataPath[dataPath.size()-1];
if(c!='/'&&c!='\\') dataPath+="/";
}
}else if(argument=="--user-dir"){
//We need a second argument so we increase i.
i++;
if(i>=argc){
printf("ERROR: Missing argument for command '%s'\n\n",argument.c_str());
return -1;
}
//Configure the userPath with the given path.
userPath=argv[i];
if(!userPath.empty()){
char c=userPath[userPath.size()-1];
if(c!='/'&&c!='\\') userPath+="/";
}
}else if(argument=="-f" || argument=="-fullscreen" || argument=="--fullscreen"){
tmpSettings["fullscreen"]="1";
}else if(argument=="-w" || argument=="-windowed" || argument=="--windowed"){
tmpSettings["fullscreen"]="0";
}else if(argument=="-mv" || argument=="-music" || argument=="--music"){
//We need a second argument so we increase i.
i++;
if(i>=argc){
printf("ERROR: Missing argument for command '%s'\n\n",argument.c_str());
return -1;
}
//Now set the music volume.
tmpSettings["music"]=argv[i];
}else if(argument=="-sv" || argument=="-sound" || argument=="--sound"){
//We need a second argument so we increase i.
i++;
if(i>=argc){
printf("ERROR: Missing argument for command '%s'\n\n",argument.c_str());
return -1;
}
//Now set sound volume.
tmpSettings["sound"]=argv[i];
}else if(argument=="-set" || argument=="--set"){
//We need a second and a third argument so we increase i.
i+=2;
if(i>=argc){
printf("ERROR: Missing argument for command '%s'\n\n",argument.c_str());
return -1;
}
//And set the setting.
tmpSettings[argv[i-1]]=argv[i];
}else if(argument=="-v" || argument=="-version" || argument=="--version"){
//Print the version.
printf("%s\n",version.c_str());
return 0;
}else if(argument=="-h" || argument=="-help" || argument=="--help"){
//If the help is requested we'll return false without printing an error.
//This way the usage/help text will be printed.
return -1;
}else{
//Any other argument is unknow so we return false.
printf("ERROR: Unknown argument %s\n\n",argument.c_str());
return -1;
}
}
//If everything went well we can return true.
return 1;
}
//Special structure that will recieve the GUIEventCallbacks of the messagebox.
struct msgBoxHandler:public GUIEventCallback{
public:
//Integer containing the ret(urn) value of the messageBox.
int ret;
public:
//Constructor.
msgBoxHandler():ret(0){}
void GUIEventCallback_OnEvent(std::string name,GUIObject* obj,int eventType){
//Make sure it's a click event.
if(eventType==GUIEventClick){
//Set the return value.
ret=obj->value;
//After a click event we can delete the GUI.
if(GUIObjectRoot){
delete GUIObjectRoot;
GUIObjectRoot=NULL;
}
}
}
};
msgBoxResult msgBox(string prompt,msgBoxButtons buttons,const string& title){
//Create the event handler.
msgBoxHandler objHandler;
//The GUI objects.
GUIObject* obj;
//Create the GUIObjectRoot, the height and y location is temp.
//It depends on the content what it will be.
GUIObject* root=new GUIObject((SCREEN_WIDTH-600)/2,200,600,200,GUIObjectFrame,title.c_str());
//Integer containing the current y location used to grow dynamic depending on the content.
int y=50;
//Now process the prompt.
{
//Pointer to the string.
char* lps=(char*)prompt.c_str();
//Pointer to a character.
char* lp=NULL;
//We keep looping forever.
//The only way out is with the break statement.
for(;;){
//As long as it's still the same sentence we continue.
//It will stop when there's a newline or end of line.
for(lp=lps;*lp!='\n'&&*lp!='\r'&&*lp!=0;lp++);
//Store the character we stopped on. (End or newline)
char c=*lp;
//Set the character in the string to 0, making lps a string containing one sentence.
*lp=0;
//Add a GUIObjectLabel with the sentence.
root->childControls.push_back(new GUIObject(0,y,root->width,25,GUIObjectLabel,lps,0,true,true,GUIGravityCenter));
//Increase y with 25, about the height of the text.
y+=25;
//Check the stored character if it was a stop.
if(c==0){
//It was so break out of the for loop.
lps=lp;
break;
}
//It wasn't meaning more will follow.
//We set lps to point after the "newline" forming a new string.
lps=lp+1;
}
}
//Add 70 to y to leave some space between the content and the buttons.
y+=70;
//Recalc the size of the message box.
root->top=(SCREEN_HEIGHT-y)/2;
root->height=y;
//Now we need to add the buttons.
//Integer containing the number of buttons to add.
int count=0;
//Array with the return codes for the buttons.
int value[3]={0};
//Array containing the captation for the buttons.
string button[3]={"","",""};
switch(buttons){
case MsgBoxOKCancel:
count=2;
button[0]=_("OK");value[0]=MsgBoxOK;
button[1]=_("Cancel");value[1]=MsgBoxCancel;
break;
case MsgBoxAbortRetryIgnore:
count=3;
button[0]=_("Abort");value[0]=MsgBoxAbort;
button[1]=_("Retry");value[1]=MsgBoxRetry;
button[2]=_("Ignore");value[2]=MsgBoxIgnore;
break;
case MsgBoxYesNoCancel:
count=3;
button[0]=_("Yes");value[0]=MsgBoxYes;
button[1]=_("No");value[1]=MsgBoxNo;
button[2]=_("Cancel");value[2]=MsgBoxCancel;
break;
case MsgBoxYesNo:
count=2;
button[0]=_("Yes");value[0]=MsgBoxYes;
button[1]=_("No");value[1]=MsgBoxNo;
break;
case MsgBoxRetryCancel:
count=2;
button[0]=_("Retry");value[0]=MsgBoxRetry;
button[1]=_("Cancel");value[1]=MsgBoxCancel;
break;
default:
count=1;
button[0]=_("OK");value[0]=MsgBoxOK;
break;
}
//Now we start making the buttons.
{
//Reduce y so that the buttons fit inside the frame.
y-=40;
double places[3]={0.0};
if(count==1){
places[0]=0.5;
}else if(count==2){
places[0]=0.4;
places[1]=0.6;
}else if(count==3){
places[0]=0.3;
places[1]=0.5;
places[2]=0.7;
}
//Loop to add the buttons.
for(int i=0;i<count;i++){
obj=new GUIObject(root->width*places[i],y,-1,36,GUIObjectButton,button[i].c_str(),value[i],true,true,GUIGravityCenter);
obj->eventCallback=&objHandler;
root->childControls.push_back(obj);
}
}
//Now we dim the screen and keep the GUI rendering/updating.
GUIOverlay* overlay=new GUIOverlay(root);
overlay->enterLoop(true);
//And return the result.
return (msgBoxResult)objHandler.ret;
}
struct fileDialogHandler:public GUIEventCallback{
public:
//The ret(urn) value, true=ok and false=cancel
bool ret;
//Boolean if it's a save dialog.
bool isSave;
//Boolean if the file should be verified.
bool verifyFile;
//Boolean if files should be listed instead of directories.
bool files;
//Pointer to the textfield containing the filename.
GUIObject* txtName;
//Pointer to the listbox containing the different files.
GUIListBox* lstFile;
//The extension the files listed should have.
const char* extension;
//The current filename.
string fileName;
//The current search path.
string path;
//Vector containing the search paths.
vector<string> searchPath;
public:
//Constructor.
fileDialogHandler(bool isSave=false,bool verifyFile=false, bool files=true):ret(false),
isSave(isSave),verifyFile(verifyFile),
files(files),txtName(NULL),lstFile(NULL),extension(NULL){}
void GUIEventCallback_OnEvent(std::string name,GUIObject* obj,int eventType){
//Check for the ok event.
if(name=="cmdOK"){
//Get the entered fileName from the text field.
std::string s=txtName->caption;
//If it doesn't contain a slash we need to add the path to the fileName.
if(s.find_first_of("/")==string::npos)
s=path+s;
//If the string empty we return.
if(s.empty() || s.find_first_of("*?")!=string::npos)
return;
//We only need to check for extensions if it isn't a folder dialog.
if(files){
//If there isn't right extension add it.
size_t found=s.find_first_of(".");
if(found!=string::npos)
s.replace(s.begin()+found+1,s.end(),extension);
else if (s.substr(found+1)!=extension)
s.append(string(".")+extension);
}
//Check if we should save or load the file.
//
if(isSave){
//Open the file with read permission to check if it already exists.
FILE* f;
f=fopen(processFileName(s).c_str(),"rb");
//Check if it exists.
if(f){
//Close the file.
fclose(f);
//Let the currentState render once to prevent multiple GUI overlapping and prevent the screen from going black.
currentState->render();
//Prompt the user with a Yes or No question.
/// TRANSLATORS: Filename is coming before this text
if(msgBox(tfm::format(_("%s already exists.\nDo you want to overwrite it?"),s),MsgBoxYesNo,_("Overwrite Prompt"))!=MsgBoxYes){
//He answered no, so we return.
return;
}
}
//Check if we should verify the file.
//Verifying only applies to files not to directories.
if(verifyFile && files){
//Open the file with write permission.
f=fopen(processFileName(s).c_str(),"wb");
//Check if their aren't problems.
if(f){
//Close the file.
fclose(f);
}else{
//Let the currentState render once to prevent multiple GUI overlapping and prevent the screen from going black.
currentState->render();
//The file can't be opened so tell the user.
msgBox(tfm::format(_("Can't open file %s."),s),MsgBoxOKOnly,_("Error"));
return;
}
}
}else if(verifyFile && files){
//We need to verify a file for opening.
FILE *f;
f=fopen(processFileName(s).c_str(),"rb");
//Check if it didn't fail.
if(f){
//Succes, so close the file.
fclose(f);
}else{
//Let the currentState render once to prevent multiple GUI overlapping and prevent the screen from going black.
currentState->render();
//Unable to open file so tell the user.
msgBox(tfm::format(_("Can't open file %s."),s),MsgBoxOKOnly,_("Error"));
return;
}
}
//If we haven't returned then it's fine.
//Set the fileName to the chosen file.
fileName=s;
//Delete the GUI.
if(GUIObjectRoot){
delete GUIObjectRoot;
GUIObjectRoot=NULL;
}
//Set return to true.
ret=true;
}else if(name=="cmdCancel"){
//Cancel means we can kill the gui.
if(GUIObjectRoot){
delete GUIObjectRoot;
GUIObjectRoot=NULL;
}
}else if(name=="lstFile"){
//Get a pointer to the listbox.
GUIListBox* obj1=lstFile;
//Make sure the option exist and change textfield to it.
if(obj1!=NULL && txtName!=NULL && obj1->value>=0 && obj1->value<(int)obj1->item.size()){
txtName->caption=obj1->item[obj1->value];
}
}else if(name=="lstSearchIn"){
//Get the searchpath listbox.
GUISingleLineListBox *obj1=dynamic_cast<GUISingleLineListBox*>(obj);
//Check if the entry exists.
if(obj1!=NULL && lstFile!=NULL && obj1->value>=0 && obj1->value<(int)searchPath.size()){
//Temp string.
string s;
//Get the new search path.
path=searchPath[obj1->value];
//Make sure it isn't empty.
if(!path.empty()){
//Process the filename.
s=processFileName(path);
}else{
//It's empty so we give the userpath.
s=getUserPath();
}
//Fill the list with files or directories.
if(files) {
lstFile->item=enumAllFiles(s,extension);
}else
lstFile->item=enumAllDirs(s);
//Remove any selection from the list.
lstFile->value=-1;
}
}
}
};
bool fileDialog(string& fileName,const char* title,const char* extension,const char* path,bool isSave,bool verifyFile,bool files){
//Pointer to GUIObject to make the GUI with.
GUIObject* obj;
//Create the fileDialogHandler, used for event handling.
fileDialogHandler objHandler(isSave,verifyFile,files);
//Vector containing the pathNames.
vector<string> pathNames;
//Set the extension of the objHandler.
objHandler.extension=extension;
//We now need to splits the given path into multiple path names.
if(path && path[0]){
//The string isn't empty.
//Pointer to the paths string.
char* lp=(char*)path;
//Pointer to the first newline.
char* lps=strchr(lp,'\n');
//Pointer used for checking if their's another newline.
//It will indicate if it's the last set or not.
char* lpe;
//Check for a newline.
if(lps){
//We have newline(s) so loop forever.
//We can only break out of the loop when the string ends.
for(;;){
//Add the first searchpath.
//This is the beginning of the string (lp) to the first newline. (lps)
objHandler.searchPath.push_back(string(lp,lps-lp));
//We should have another newline so search for it.
lpe=strchr(lps+1,'\n');
if(lpe){
//We found it so we add that to the pathname.
pathNames.push_back(string(lps+1,lpe-lps-1));
//And start over again by setting lp to the start of a new set of searchPath/pathName.
lp=lpe+1;
}else{
//There is no newline anymore, meaning the last entry, the rest of the string must be the pathName.
pathNames.push_back(string(lps+1));
//And break out of the loop.
break;
}
//We haven't broken out so search for a newline.
lps=strchr(lp,'\n');
//If there isn't a newline break.
if(!lps)
break;
}
}else{
//There is no newline thus the whole string is the searchPath.
objHandler.searchPath.push_back(path);
}
}else{
//Empty so put an empty string as searchPath.
objHandler.searchPath.push_back(string());
}
//It's time to create the GUI.
//If there are more than one pathNames we need to add a GUISingleLineListBox.
int base_y=pathNames.empty()?20:60;
//Create the frame.
GUIObject* root=new GUIObject(100,100-base_y/2,600,400+base_y,GUIObjectFrame,title?title:(isSave?_("Save File"):_("Load File")));
//Create the search path list box if needed.
if(!pathNames.empty()){
root->childControls.push_back(new GUIObject(8,40,184,36,GUIObjectLabel,_("Search In")));
GUISingleLineListBox* obj1=new GUISingleLineListBox(160,40,432,36);
obj1->item=pathNames;
obj1->value=0;
obj1->name="lstSearchIn";
obj1->eventCallback=&objHandler;
root->childControls.push_back(obj1);
}
//Add the FileName label and textfield.
root->childControls.push_back(new GUIObject(8,20+base_y,184,36,GUIObjectLabel,_("File Name")));
{
//Fill the textbox with the given fileName.
string s=fileName;
if(!isSave){
//But only if it isn't empty.
if(s.empty() && extension && extension[0])
s=string("*.")+string(extension);
}
//Create the textbox and add it to the GUI.
objHandler.txtName=new GUIObject(160,20+base_y,432,36,GUIObjectTextBox,s.c_str());
root->childControls.push_back(objHandler.txtName);
}
//Now we add the ListBox containing the files or directories.
{
GUIListBox* obj1=new GUIListBox(8,60+base_y,584,292);
//Get the searchPath.
string s=objHandler.searchPath[0];
//Make sure it isn't empty.
if(!s.empty()){
objHandler.path=s;
s=processFileName(s);
}else{
s=getUserPath();
}
//Check if we should list files or directories.
if(files){
//Fill the list with files.
obj1->item=enumAllFiles(s,extension);
}else{
//Fill the list with directories.
obj1->item=enumAllDirs(s);
}
obj1->name="lstFile";
obj1->eventCallback=&objHandler;
root->childControls.push_back(obj1);
objHandler.lstFile=obj1;
}
//Now create the OK and Cancel buttons.
obj=new GUIObject(200,360+base_y,192,36,GUIObjectButton,_("OK"));
obj->name="cmdOK";
obj->eventCallback=&objHandler;
root->childControls.push_back(obj);
obj=new GUIObject(400,360+base_y,192,36,GUIObjectButton,_("Cancel"));
obj->name="cmdCancel";
obj->eventCallback=&objHandler;
root->childControls.push_back(obj);
//Create the gui overlay.
GUIOverlay* overlay=new GUIOverlay(root);
overlay->enterLoop();
//Now determine what the return value is (and if there is one).
if(objHandler.ret)
fileName=objHandler.fileName;
return objHandler.ret;
}

File Metadata

Mime Type
text/x-diff
Expires
Mon, Jun 15, 11:34 PM (2 w, 3 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
70091
Default Alt Text
(87 KB)

Event Timeline