Page Menu
Home
Phabricator (Chris)
Search
Configure Global Search
Log In
Files
F130699
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
87 KB
Referenced Files
None
Subscribers
None
View Options
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
Details
Attached
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)
Attached To
Mode
R79 meandmyshadow
Attached
Detach File
Event Timeline