ballerburg-1.0.1/0000755000175000017500000000000012145514563013210 5ustar thomasthomasballerburg-1.0.1/README.txt0000644000175000017500000000557412145514531014714 0ustar thomasthomas ============================ = Ballerburg SDL v1.0.1 = ============================ Copyright (C) 1987, 1989 Eckhard Kruse Copyright (C) 2010, 2013 Thomas Huth For my sister Martina Huth - I will never forget the countless happy hours that we had with this game during our childhood. 1) Lizenz --------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . 2) What is Ballerburg? ---------------------- Ballerburg is a classical castle combat game. Two castles, separated by a hill, shoot each other with their cannons until one of the king is hit or surrenders. Ballerburg was originally developed in 1987 by Eckhard Kruse for the Atari ST computers - a cutting-edge 16/32-bit computer at that time. Now, a quarter of a century later, here's the adaption of Ballerburg for recent operating systems that are supported by the SDL library (like GNU/Linux for example) - thanks to the original source code of the old Ballerburg that has kindly been released by Eckhard Kruse to the public. 3) Compiling and installing --------------------------- For compiling the source code of Ballerburg SDL, you need the GCC C-compiler, CMake and the following libraries (including their headers / development packages): - SDL Version 1.2 (http://www.libsdl.org/) - SDL_gfx Version 2.0 (http://www.ferzkopp.net/) For configuring the build, you've got to run "cmake" first, using the path of the sources as parameter. Alternatively, you can also use the supplied "configure" script or a GUI tool like "cmake-gui". After the configuration step, you can compile the source code with "make" and if everything worked fine, install the program with "make install". 4) Starting the game -------------------- To run the game, simply execute the "ballerburg" program from the folder where you've installed the game into. The game itself should be self-explanatory most of the time, for the details please have a look at the manual in the doc directory. Please press the "ESC" key to enter the main menu (for setting up various game options or for starting a new game). Press "f" to toggle between windowed and fullscreen mode. The key "q" is used for leaving the game. 5) Contact ---------- If you have questions, suggestions or patches, please write a mail to the following address: huth at tuxfamily.org Now have fun with Ballerburg! ballerburg-1.0.1/doc/0000755000175000017500000000000012145515676013763 5ustar thomasthomasballerburg-1.0.1/doc/en/0000755000175000017500000000000012145514531014352 5ustar thomasthomasballerburg-1.0.1/doc/en/manual.html0000644000175000017500000003253712145514531016527 0ustar thomasthomas Manual for Ballerburg SDL

Manual for Ballerburg SDL

1. Objective of the game

Ballerburg is about two lords of castles pitted against each other, with the goal of defeating the opponent through targeted cannon shots. Players are able to obtain money from mining after buying shaft towers and from their people by levying taxes, and with these funds players may purchase e.g. new cannons and ammunition.

2. Game modes

There are different playing modes available in the game's settings menu, which can be brought up by pressing the Escape key. Ordinarily, the game is played between two human players. Another option is for one player to fight the computer. The computer can be set to be the player on the left or right hand side of the screen. It is also possible to let two computer- controlled players battle each other. Since it is possible to change playing modes mid-game, one can for example momentarily let the computer shoot for one's own side, or, if you're battling a computer-controlled player and the situation's dire, you might for instance momentarily switch modes to human vs. human and weaken the opponent by making bad decisions for him.

3. Player names and computer-controlled player

In the settings menu you can change the name of the human player. The name for the computer-controlled player can be changed under the label 'AI strategy'. Both settings can also safely be changed while a game is already running. The first player is always on the left side of the screen, and the second player is on the right side. The name of the computer-controlled player also stand for a certain strategy. The numbers next to 'AI strength' control the shooting accuracy of the computer players. The highest value 4 here means that almost every shot will hit its goal. The AI strategies differentiate into the priorities of the targets, i.e. some computer players shoot always at the cannons (if available), while some others rather try to hit the money of the opponent.

Oaf : No special target, just tries to hit the castle somewhere.
Yokel : First the money, then gunpowder/cannonballs, then the king
Boor : First the money, then cannons, then the king
Doofus : Money, gunpowder, cannonballs, shaft towers, cannons, king: Everything with the same probability
Fumbler : First cannons, then the king
Geezer : First the shaft towers, then cannons, then the king
Ruffian : Aims only at the king

Note that only Doofus, Fumbler, Geezer and Ruffian are able to buy shaft towers.

4. New game, choosing the castles

By clicking 'New game' in the settings menu, you can choose new castles for both sides and then start the new game by clicking 'OK'. Unless you've already extended the file with the castles, 'BALLER.DAT', you can decide between 9 different standard castles here. If both players are on the same skill level, you should of course select the same castles here, because the different castles have quite different strengths. If you choose smaller castles, the game normally won't last as long as with the bigger castles.

Here are now the values of the 9 standard castles:

Cannons Money Gunpowder Cannonballs People
2 400 180 12 200
5 500 180 12 270
5 500 150 14 270
6 500 190 12 300
3 500 120 6 220
4 500 120 10 240
6 800 120 12 500
3 500 120 9 500
1 1000 120 12 300

5. The battlefield: The mountain and the castles

After you've started a new game, the castles and the mountain will be drawn on the screen. Both, the position of the castles and the shape and height of the mountain are random (within certain limits). The castles consist of the following parts:

The active wind information indicates the active player. If the player still has a vane, a zoomed version of the vane will be shown in the box at the bottom of the screen together with the strength and direction of the wind.

6. Course of the game

After starting the game, the players take their turns until one of them wins. Within a turn, the player can do several things: After clicking on either the powder magazine, the cannonballs magazine or the treasure chamber, the properties of the player will be displayed along with the market where the player can buy various things (more on this topic can be found in the next chapter). By clicking on the throne room, the king will comment on your latest progress.

The round can be completed in two ways: In case you don't have a cannon anymore, or you don't have enough powder or cannonballs or just don't like to shoot, you can simply click on 'Done' at the bottom of the screen. In all other cases you should choose the cannon that you want to shoot with, select the angle and powder and then click 'OK' to fire a cannonball. More on shooting can be found in chapter 8.

7. Your properties and the market

When clicking on one of the three magazines, you get the properties and market dialog which is described here now: In the section titled with 'You have' your properties and the amount of your people are listed. By clicking on the corresponding arrows, you can also adjust the taxes here that you demand from your people. Higher taxes mean more money per subject. But beware, when you raise the taxes, some of your people might leave your kingdom. On the other side, lowering the taxes might render your kingdom more attractive again, so that a certain amount of people might immigrate again. But like in real life, there are no exact values for the amount of immigrants, emmigrants and the amount of money you earn, they fluctuate within certain ranges. And be warned: If you raise the taxes too much, your income declines again – which people are really interested in generating earnings if they have to give everything away again?

The second part of the dialog is used for the market. Here you can buy certain things and repair your castle. You can trigger one of the actions by clicking on the price of the corresponding entry. However, this is only possible if the entry is active. In case it is inactive, you either do not have enough money or one of the following reasons occured:

Please also note that you can not buy more cannonballs and gunpowder than you can store in your magazines. If you try to buy more, you still have to pay the money, but you can not store the bought goods! The treasure chamber behaves in a similar way: If it is completely filled, all additional earned money will be discarded.

Buying a shaft tower is long-term capital investment. For each shaft tower, you earn approximately between 40 and 70 money units each round.

Now a word about laying bricks: When you choose this menu entry, you get 20 bricks (the remeaining are shown at the bottom of the screen) which you have to lay immediately. Please note that you can only extend the existing walls of your castle, i.e. you can not lay the bricks somewhere up in the air. Furthermore, don't even think of laying the bricks at your opponent's castle, e.g. to block the other's cannons – of course this is forbidden, you are only allowed to extend your own castle.

Please also note that the prices at the market vary each round. Goods that are very cheap in one round might become expensive in the next one. (I won't tell more about the price system here, so you can be surprised again and again how expensive those shaft towers can be when you just thought that you were ready to buy one...)

8. Shooting

After clicking on one of the cannons, you have to adjust the cannon angle and the amount of gunpowder. By clicking on the single arrows, you adjust the values with single steps, and by clicking on the double arrows you adjust the powder by three units and the angle by 10 degrees. Powder can be selected from 5 units up to 20 units (unless you have less than 20 powder units in your magazine, then the maximum limit will be adjusted accordingly). Using 5 powder units or something similar is hardly of any use – unless you would like to destroy your own shaft towers!?!

The angle can be adjusted in the range of 0 up to 180 degrees. Angles above 90 degrees (or even 80 degrees if you've got very strong opposing wind) are also only useful for self-destructive players.

When you are satisfied with your settings (did you take the wind into account, too?), then you should press 'OK' to fire your cannonball.

9. Striking

In most cases the cannonballs only hit the mountain or the walls of the opponent's castle. The effect is not too exciting; the cannonball creates a crater with a size proportional to the impact velocity. In case you hit the castle, there is also the chance that you killed some of the opponent's people.

Striking a cannon is more exciting; the cannon is destroyed with a big explosion. The same applies to the vane. If you hit the cannonball magazine or the treasure chamber, a certain amount of the content will be destroyed. In case you hit the powder magazine, the whole stock of powder will explode. And if you hit the king, you can congratulate yourself – in this case you've won the game!

The fine art of shooting is to destroy the shaft towers. This is a very difficult task. First, they are located right behind the mountain anyway, so that you need a big angle and a lot of powder to hit them. But additionally you often have to hit them multiple times until they explode. Here's a little hint: If you hit the towers from the side instead from the top, chances are higher that they will be destroyed.

10. Game options

In case two players are playing at the same level, there can be a dead-lock situation where neither player manages to hit the opponent's king. Especially when both players have a lot of people, shaft towers and lay a lot of bricks, it can happen that they get almost unbeatable and these games last forever.

To avoid such neverending games, there are some options in the settings menu which can be used to limit the duration of a party:

11. The end of the game

How can a game end? In the most likely case, one of the two kings gets hit by a cannonball. There is also the possibility that one of the kings surrenders. However, this is only the case if you do not have any cannons left, your treasure room is almost empty and your amount of people is also very low – so it is very unlikely that you can buy a new cannon in the near future. Finally there is the possibility that you run out of people. But this case only happens if you're imposing too high taxes for several rounds, so that all your people emigrate.

ballerburg-1.0.1/doc/de/0000755000175000017500000000000012145514531014340 5ustar thomasthomasballerburg-1.0.1/doc/de/anleitung.html0000644000175000017500000003546112145514531017225 0ustar thomasthomas Ballerburg SDL Anleitung

Spielanleitung zu Ballerburg SDL

1. Sinn des Spieles

Bei dem Spiel Ballerburg geht es darum, dass sich zwei Burgherren mit dem Ziel gegenüber stehen, durch gezielte Kanonenschüsse den Gegner zu besiegen. Dabei haben die Spieler die Möglichkeit, durch Kauf von Fördertürmen Geld zu verdienen, vom Volk Steuern zu fordern und mit diesen Einnahmen zum Beispiel neue Geschütze und Munition zu kaufen.

2. Verschiedene Spielmodi

Über die ESC-Taste erreichen Sie das Einstellungsmenü, in welchem Sie verschiedene Spielmodi auswählen können: Normalerweise kämpfen zwei Spieler gegeneinander. Weiterhin besteht die Möglichkeit, dass ein Spieler gegen einen Computer spielt. Dabei kann der Computer wahlweise auf der linken oder rechten Seite spielen. Schließlich können Sie auch zwei Computer gegeneinander spielen lassen. Da Sie den Modus während des laufenden Spieles ändern können, besteht zum Beispiel die Möglichkeit, dass Sie zwischendurch auch einmal den Computer für sich schießen lassen, oder dass Sie in einem aussichtslosen Kampf gegen den Computer durch vorübergehendes Umschalten auf 'Spieler gegen Spieler' Ihren Gegner durch eigene Entscheidungen schwächen.

3. Spielernamen und Computerspieler

Im Einstellungsmenü können Sie die Namen der menschlichen Spieler bestimmen. Die Namen der Computer legen Sie beim unter 'KI Strategie' fest. Beides kann auch während einer Partie geändert werden. Computer 1 und Spieler 1 spielen immer auf der linken Computer 2 und Spieler 2 auf der rechten Seite. Die Namen der Computer stehen gleichzeitig für eine bestimmte Strategie. Die Zahlen 1-4 unter 'KI Stärke' stellen die Treffsicherheit der Computerspieler dar. Dabei bedeutet 4, dass praktisch jeder Schuss ein Treffer ist. Die Strategien unterscheiden sich darin, dass die Computer den Zielen eine unterschiedliche Priorität geben, d.h. manche Computer schießen grundsätzlich auf Kanonen, wenn welche vorhanden sind, während andere zum Beispiel eher auf das gegnerische Geld zielen.

Tölpel : Kein konkretes Ziel, versucht nur, die Burg irgendwie zu treffen.
Dummel : Geld vor Pulver/Kugeln vor König
Brubbel : Geld vor Kanonen vor König
Wusel : Geld, Pulver, Kugeln, Fördertürme, Kanonen, König: Alle mit gleicher Wahrscheinlichkeit
Brösel : Kanonen vor König
Toffel : Förderturme vor Kanonen vor König
Rüpel : Zielt nur auf den König.

Desweiteren sind nur Wusel, Brösel, Toffel und Rüpel in der Lage, sich Fördertürme zu kaufen.

4. Neues Spiel, Wahl der Burgen

Nach Anklicken von 'Neues Spiel' können Sie für die beiden Seiten Burgen auswählen und anschließend mit 'OK' das Spiel beginnen. Sollten Sie nicht bereits die Burgendatei 'BALLER.DAT' erweitert haben, so stehen Ihnen 9 Burgen zur Verfügung. Bei gleichguten Spielern sollten Sie in der Regel auch gleiche Burgen auswählen, denn sie unterscheiden sich in der Stärke teilweise recht erheblich untereinander. Bei der Wahl von kleineren Burgen wird sich natürlich auch im allgemeinen die Gesamtspieldauer verkürzen.

Hier nun die Werte der Standard-Burgen:

Kanonen Geld Pulver Kugeln Volk
2 400 180 12 200
5 500 180 12 270
5 500 150 14 270
6 500 190 12 300
3 500 120 6 220
4 500 120 10 240
6 800 120 12 500
3 500 120 9 500
1 1000 120 12 300

5. Das Spielfeld: Der Berg und die Burgen

Nachdem Sie nun mit 'Neues Spiel' das Spiel begonnen haben, werden die Burgen und der Berg gezeichnet. Sowohl die Lage der Burgen als auch das Aussehen und die Höhe das Berges sind (innerhalb eines gewissen Rahmens) zufällig. Die Burgen bestehen aus folgenden Teilen:

Durch die aktive Windanzeige sieht man, wer am Zug ist. Ist der Spieler im Besitz einer Windfahne, so wird sie im Kasten unten vergrößert gezeigt und außerdem die genaue Windgeschwindigkeit und -richtung angegeben.

6. Spielablauf

Nach dem Starten des Spieles führen die Spieler immer abwechselnd Ihre Aktionen aus, bis einer gewonnen hat. Innerhalb eines Zuges kann der Spieler verschiedene Dinge machen: Nach Anklicken einer der Kammern für Pulver, Kugeln oder Geld wird der Besitz des Spielers angezeigt und man hat dann die Möglichkeit, auf dem Markt verschiedene Dinge zu kaufen. Mehr dazu wird im nächsten Abschnitt gesagt. Durch Anklicken des Königs können Sie erfahren, was Ihr Herrscher denn zu Ihren Erfolgen zu sagen hat.

Abgeschlossen werden kann der Zug durch zweierlei Möglichkeiten: Sollten Sie keine Kanone, nicht genügend Pulver bzw. Kugeln oder einfach keine Lust zum Schießen haben, so müssen Sie auf 'Fertig' am unteren Bildschirmrand klicken. Andernfalls wählen Sie die Kanone, mit der Sie schießen wollen, aus, stellen Winkel und Pulver ein und klicken auf 'OK'. (Näheres zum Schießen in Abschnitt 8)

7. Der eigene Besitz und der Markt

Wenn Sie während Ihres Zuges auf eine der drei Kammern klicken, so erscheint eine Übersicht, auf die jetzt näher eingegangen werden soll. Unter 'Du hast' steht eine genaue Aufzählung über Ihren Besitz sowie über die Größe Ihres Volkes. Außerdem können Sie hier die Steuern, die Sie von Ihrem Volk fordern, durch Klicken auf die entsprechenden Pfeile einstellen. Bei hohen Steuern bekommen Sie natürlich mehr Geld als bei niedrigen. Allerdings kann Sie bei zu hohen Steuern ein Teil des Volkes verlassen. Bei niedrigen Steuern hingegen können Sie sich einer gewissen Zahl Einwanderer erfreuen. Um das ganze etwas interessanter zu machen, schwanken allerdings die Zahl der Ein/Auswanderer sowie die Einnahmen auch bei konstanten Steuern innerhalb einer gewissen Bandbreite. Außerdem, seien Sie gewarnt: Bei gar zu hohen Steuern, nehmen Ihre Einnahmen wieder ab. (Welches Volk hat schon Lust, Gewinne zu erwirtschaften, wenn es sowieso wieder alles abgeben muss.)

Der zweite Teil der Anzeige stellt den Markt dar. Hier haben Sie die Möglichkeit, gewisse Dinge zu kaufen oder auch Ihre Burg zu reparieren. Sie führen eine Aktion aus, indem sie einfach auf die entsprechende Bezeichnung klicken. Dies ist jedoch nur dann möglich, wenn der Eintrag aktiv ist. Sollte er nicht anwählbar sein, so liegt es entweder an mangelndem Geld oder an einem der nachfolgenden Gründe:

Beim Kaufen von Kugeln oder Pulver sollten Sie beachten, dass Sie nur soviel einkaufen können, wie in Ihre Kammern passt. Weiteres Anklicken der entsprechenden Menüpunkte verringert zwar nach wie vor das Geld um den angezeigten Preis, bringt aber keine neuen Kugeln oder Fässer! Ähnliches gilt für die Schatzkammer: Ist sie gefüllt, so können Sie auch mit den schönsten Einnahmen Ihr Vermögen nicht weiter steigern.

Der Kauf von Fördertürmen ist eine langfristige Investition. Pro Runde und pro Turm nehmen Sie ungefähr zwischen 40 und 70 Geldeinheiten ein.

Nun noch zum Anbauen: Wählen Sie diesen Punkt an, so stehen Ihnen 20 Steine zur Verfügung ( die verbleibenen werden unten angezeigt ), die Sie sofort alle anbauen müssen. Beachten Sie, dass Sie nicht 'irgendwo in der Luft' anbauen können, sondern von den vorhanden Wänden ausgehen müssen. Desweiteren brauchen Sie nicht auf den bösen Gedanken zu kommen, bei der Burg des Gegners zum Beispiel die Geschütze zuzumauern - das geht nämlich nicht, Sie können nur im Bereich Ihrer eigenen Burg bauen.

Zu den Preisen ist nur zu sagen, dass Sie alle jeweils in einem bestimmten Bereich schwanken und dass Sie teilweise unterschiedlich starken Sprüngen unterworfen sind. (Mehr möchte ich eigentlich nicht verraten, denn so können Sie noch immer wieder staunen, wie teuer doch Fördertürme sein können...)

8. Schießen

Nach dem Anklicken einer Kanone haben Sie Winkel und Pulver einzustellen. Mit den einfachen Pfeilen stellen Sie in Einerschritten, mit den doppelten in Dreier- ( Pulver ) bzw. Zehnerschritten ( Winkel ) ein. Die Pulvermenge liegt zwischen 5 und 20 Einheiten. ( Wenn Sie insgesamt weniger als 20 Pulvereinheiten haben, liegt die Obergrenze automatisch auch niedriger. ) Pulvermengen im Bereich von 5 werden Sie eigentlich nur selten gebrauchen, nämlich nur dann, wenn Sie Ihre eigenen Fördertürme kaputt schießen wollen?!

Winkel können Sie im Bereich von 0 bis 180 Grad einstellen. Winkel über 90 (bei stärkerem Gegenwind auch schon über 80) und unter 10 Grad sind allerdings erfahrungsgemäß auch nur sehr bedingt brauchbar.

Wenn Sie schließlich mit Ihren Einstellungen zufrieden sind (haben Sie auch den Wind berücksichtigt?), können Sie mit 'OK' den Schuss auslösen.

9. Treffen

Nachdem Sie in Abschnitt 8 lesen konnten, wie man schießt, möchte ich Ihnen nun verraten, was man denn so alles treffen kann: In der größten Zahl der Fälle wird die Kugel wohl nur den Berg oder die Mauern der Burg treffen. In diesem Fall passiert nicht viel: Es entsteht ein in der Tiefe der Aufprallgeschwindigkeit proportionales Loch. Sollten Sie die Burg getroffen haben, so können außerdem ein paar Leute der Bevölkerung sterben.

Interessanter wird es dagegen, wenn Sie eine Kanone treffen. Diese wird dann nämlich mit einer Explosion verschwinden. Gleiches gilt für die Windfahne. Treffen Sie die Kammern für Geld oder Kugeln, so geht ein bestimmter Betrag verloren. Ein Treffer in der Pulverkammer bewirkt, dass das gesamte Pulver explodiert. Wenn Sie den König treffen, ist das besonders effektiv - Sie haben dann nämlich gewonnen.

Die hohe Kunst des Schießens, Fördertürme zu zerstören, ist eine schwierige Angelegenheit. Mitunter sind sie sowieso schon so hinter dem Berg versteckt, dass sie nur mit steilen Schüssen und viel Pulver zu erreichen sind. Nun kommt aber auch noch hinzu, dass man häufig eine ganze Reihe von Schüssen braucht, um einen Turm zu zerstören. Hier ein kleiner Tip: Schüsse, die den Turm seitlich treffen, sind eher von Erfolg gekrönt.

10. Spieloptionen

Da sich bei gleichguten Spielern manchmal Patt-Situationen einstellten, in denen keiner es schaffte, den anderen zu besiegen, kann es zu dem Problem kommen, dass ein Spiel quasi endlos dauern konnte. Insbesondere durch viel Volk und häufiges 'Anbauen' kann es passieren, dass man praktisch unbesiegbar wird.

Für diesen Fall gibt es im Hauptmenü daher noch verschiedene Optionen, mit welchen sich die Spieldauer begrenzen lässt:

11. Spielende

Wann ist das Spiel denn eigentlich zu Ende? Nun, ganz einfach: Der weit am häufigsten auftretende Fall ist, dass ein König getroffen wird. Es besteht jedoch auch die Möglichkeit, dass sich ein König von ganz alleine ergibt. Dies ist jedoch nur dann der Fall, wenn man keine Kanonen mehr besitzt, die finanziellen Mittel so bescheiden sind, dass man sich in absehbarer Zeit keine Kanone leisten können wird und auch das Volk aufgrund mangelnder Größe nicht die Hoffnung zulässt, durch Steuern genug Einkünfte zu schaffen. Die dritte, letzte und seltenste Möglichkeit für ein Spielende besteht darin, dass man kein Volk mehr hat, denn dann gibt es ja auch nichts mehr zu regieren. Dieser Fall tritt aber wirklich nur dann ein, wenn jemand sein Volk über längere Zeit mit gewaltigen Steuern zum Auswandern veranlasst hat.

ballerburg-1.0.1/doc/CMakeLists.txt0000644000175000017500000000066712145514531016521 0ustar thomasthomas INSTALL(FILES de/anleitung.html en/manual.html DESTINATION ${DOCDIR}) add_custom_target(manpages ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/ballerburg.1.gz) add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/ballerburg.1.gz COMMAND gzip -c -9 ${CMAKE_CURRENT_SOURCE_DIR}/ballerburg.1 > ${CMAKE_CURRENT_BINARY_DIR}/ballerburg.1.gz DEPENDS ballerburg.1) INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/ballerburg.1.gz DESTINATION ${MANDIR}) ballerburg-1.0.1/doc/ballerburg.10000644000175000017500000000313112145514531016151 0ustar thomasthomas.\" Hey, EMACS: -*- nroff -*- .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) .TH "BALLERBURG" "1" "2011-06-25" "Ballerburg SDL" "" .\" Please adjust this date whenever revising the manpage. .SH "NAME" ballerburg \- A castle combat game .SH "SYNOPSIS" .B ballerburg .SH "DESCRIPTION" Ballerburg is a castle combat game. Two players (which can be human or computer-controlled) try to destroy the opponent's castle with their cannons. .PP There are two ways to win the game: Either by directly hitting the opponents king with a cannonball, or by destroying enough of the opponents commodities so that the king capitulates automatically. .SH COPYRIGHT Copyright (C) 1987, 1989 Eckhard Kruse .br Copyright (C) 2010, 2011 Thomas Huth .PP This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. .PP This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. .PP You should have received a copy of the GNU General Public License along with this program. If not, see . .SH "SEE ALSO" The main program documentation, usually in /usr/share/doc/ballerburg. .PP The homepage of Ballerburg SDL: http://baller.tuxfamily.org/ ballerburg-1.0.1/doc/authors.txt0000644000175000017500000000123412145514531016176 0ustar thomasthomas People who contributed to Ballerburg SDL: - Thomas Huth : Main developer of Ballerburg SDL, adapted the old Ballerburg sources to recent systems, maintains the Ballerburg SDL project. - Eero Tamminen : Finnish translations - Jens Ropers : Most of the English translations - Andrea Musuruane : Italian translations Ballerburg SDL uses source code from other projects which we would like to acknowledge here: - Eckhard Kruse : Wrote the original Ballerburg game for the Atari ST. - Stefan Berndtsson : The original version of the PSG soundchip emulation. - Kolja Koischwitz : Designed some additional castles (used in Ballerburg^2) ballerburg-1.0.1/doc/changelog.txt0000644000175000017500000002437512145515676016466 0ustar thomasthomas2013-05-17 * doc/CMakeLists.txt: Install english manual, too * src/font8x16.h, src/font8x16.png: Beautified some characters * CMakeLists.txt, LIESMICH.txt, README.txt, po/de.po, po/fi.po, po/it.po: Bumped version to 1.0.1 * po/it.po: Updated the Italian translation. Thanks to Andrea Musuruane! 2013-05-10 * po/de.po, po/fi.po, src/baller1.c: Use proper C format strings in game-over text to ease translations 2013-05-06 * po/CMakeLists.txt: Remove absolute path names from ballerburg.pot file * doc/authors.txt, po/it.po: Added Italian translation (thanks to Andrea Musuruane) 2013-03-30 * src/baller2.c, src/market.c, src/screen.c, src/screen.h: Removed unused functions vswr_mode and vst_color * CMakeLists.txt, LIESMICH.txt, README.txt, po/de.po, po/fi.po, src/baller1.c: Bumped version number to 1.0 * src/ballergui.c: Removed superfluous printf * src/baller2.c: Redraw cannoneer after a shot * src/baller2.c: Make sure that the cannonball always gets erased at the end * src/baller1.c, src/ballergui.c, src/ballergui.h, src/market.c: Make sure that dialogs are not called at the wrong point in time * src/baller.dat: Fixed the roof color of the first BB2 castle * src/baller1.c: Some minor code clean-up * src/screen.c, src/screen.h: Removed unused vst_height function * src/baller1.c: Added the seventh computer player to the table 2013-03-12 * src/baller1.c: Cleaned up t_load and t_save a little bit 2012-12-27 * src/baller1.c: Translate the names in the ending screen 2012-12-24 * src/baller1.c, src/baller1.h, src/settings.c: Use computer player names if the user selected computer players in the GUI * src/ballergui.c: Make sure that highscore table is not shown recursively * src/ballergui.c: Make sure that we really quit (e.g. when showing the highscore table) * po/de.po, po/fi.po, src/baller1.c, src/screen.c: Improved the highscore table * src/baller1.c, src/baller1.h, src/baller2.c: Cleaned up the global variables a little bit * src/baller1.c: Fixed stupid bug (introduced while fixing compiler warnings two commits ago) 2012-07-11 * po/fi.po: Updated Finnish translation. Thanks to Eero Tamminen for the updates! 2012-07-02 * CMakeLists.txt, src/baller1.c: Enabled some more GCC warnings * doc/en/manual.html: Improved the English translation of the manual. Thanks to Eero Tamminen for the patch. * src/psg.c, src/psg.h: Dosound does not change the buffer, so make parameter const 2012-04-26 * cmake/DistClean.cmake: Improved distclean target * doc/en/manual.html: Added the English manual * po/de.po, src/baller1.c: Translation of the initial player names 2012-04-24 * doc/CMakeLists.txt, doc/de/anleitung.html: Updated the german manual * src/baller.dat: Moved the position of the last castle a little bit 2012-03-27 * doc/de/anleitung.html, doc/de/anleitung.txt: Convertet anleitung.txt to HTML 2012-03-26 * doc/authors.txt: Added the authors.txt file * README.txt: English translation of the README file * LIESMICH.txt: Updated the LIESMICH.txt file * src/market.c: Made the market dialog a little bit wider so that all languages fit 2012-03-21 * src/baller1.h, src/music.c, src/music.h, src/screen.c, src/screen.h: Some minor cleanups * src/ballergui.c: Renamed event variable to avoid confusion with event function * po/de.po, po/fi.po, src/baller2.c, src/dlgAlert.c: Slightly improved the kings dialog * src/baller2.c: Restory light blue background after shaft tower explosion * po/de.po: Updated german translation * src/baller1.c, src/sdlgui.h, src/settings.c: Reworked settings dialog to support both, AI strength and strategy settings 2012-03-20 * src/ballergui.c: Show table when pressing 't' 2012-03-19 * src/baller1.c, src/baller1.h: Got rid of t_na array, using cn instead. * src/market.c, src/screen.c, src/screen.h: Added dedicated functions for saving and restoring screen background areas 2012-03-17 * src/screen.c, src/screen.h: Removed form_alert and graf_mouse 2012-03-12 * src/baller1.c, src/baller2.c, src/screen.c, src/screen.h: Replaced movmem with memmove * src/screen.c: Some more speed optimizations * src/baller2.c, src/screen.c, src/screen.h: Speed up the cannonball drawing by calling SDL_UpdateRect only once 2012-03-09 * po/fi.po: Eero Tamminen translated the remaining missing Finnish strings 2012-03-08 * src/baller.dat: Added some castles from Ballerburg^2 (by Kolja Koischwitz) * src/settings.c: Made the castle selection dialog a little bit bigger * src/baller1.c, src/baller1.h: Made the loading of the castles a little bit more robust * po/fi.po: Added framework for Finnish translation * src/market.c, src/screen.c, src/screen.h, src/sdlgui.c, src/sdlgui.h: Added function for drawing centered text 2012-03-07 * po/de.po, src/market.c: Proper translation when laying bricks 2012-03-06 * src/sdlgui.c: Fixed translation of radio buttons and check boxes * po/de.po, src/baller2.c: The messages from the king are now correctly translated * src/sdlgui.c: The UTF-8 string can also be specified without dash 2012-03-05 * src/sdlgui.c: Convert UTF-8 to latin1 while rendering the font glyphs 2012-02-19 * src/i18n.h, src/sdlgui.c: Add basic gettext support to the SDL-GUI dialogs. * src/dlgAlert.c: Calculation of the alert dialog button widths was wrong. Now the buttons should have the right widths. 2012-02-14 * CMakeLists.txt, po/CMakeLists.txt, po/de.po: Added CMake file for building .po files and added German translation 2012-02-11 * src/baller1.c, src/baller2.c, src/ballergui.c, src/cannoneer.c, src/market.c, src/screen.c, src/sdlgui.c, src/settings.c: Translated the strings in the C sources into English. Other languages will be handled by gettext later. Thanks to Jens Ropers for the English translations. 2012-02-06 * CMakeLists.txt, cmake/config-cmake.h, src/baller1.c, src/i18n.h: Check for libintl.h instead of gettext 2012-02-05 * CMakeLists.txt, cmake/config-cmake.h, src/baller1.c, src/i18n.h, src/paths.c, src/paths.h: First steps to support gettext i18n 2011-12-05 * src/music.c, src/psg.c, src/sdlgui.c: Silenced compiler warnings with GCC 4.6 2011-06-28 * LIESMICH.txt, doc/ballerburg.1, src/baller2.c: Updated documentation 2011-06-26 * CMakeLists.txt, cmake/Uninstall.cmake: Added 'uninstall' target * src/CMakeLists.txt, src/baller.mus, src/baller1.c, src/baller1.h, src/music.c, src/music.h, src/psg.c, src/psg.h: Added game-over music. 2011-06-25 * src/paths.c: Disable debug printf * cmake/DistClean.cmake: Remove Ballerburg-specific files during distclean * CMakeLists.txt, cmake/config-cmake.h, doc/CMakeLists.txt, src/CMakeLists.txt, src/baller1.c, src/paths.c, src/paths.h: Added the possibility to install the game * doc/ballerburg.1: Dummy manual page 2011-06-23 * configure: Added 'configure' wrapper script * src/baller.h, src/baller1.c, src/baller2.c, src/ballergui.c, src/cannoneer.c: Deleted old GEM related code 2011-06-17 * src/baller1.c, src/baller1.h, src/baller2.c, src/settings.c, src/settings.h: Added dialog for selecting the castles * src/screen.c: Color fine tuning 2011-06-16 * src/screen.c: Smoother edges for the vane box 2011-05-28 * src/baller1.c, src/baller1.h, src/ballergui.c, src/settings.c, src/settings.h: Extended the settings dialog * src/CMakeLists.txt, src/baller1.c, src/baller2.c, src/ballergui.c, src/ballergui.h, src/cannoneer.c, src/market.c, src/settings.c, src/settings.h: Added first version of the settings dialog, with the possibility to select the player types 2011-03-19 * src/psg.c: Changed audio frequency to 22 kHz - since this sounds somewhat more original than 44 kHz * src/baller1.c: Implemented first version of ending screen * src/market.c: Removed debug code * src/CMakeLists.txt, src/baller1.c, src/baller2.c, src/baller2.h, src/psg.c, src/psg.h, src/screen.c, src/screen.h: Initial sound support via libpsg 2011-02-22 * CMakeLists.txt, cmake/FindSDL_gfx.cmake, src/CMakeLists.txt: Let CMake search for SDL_gfx, too 2011-02-19 * LIESMICH.txt: Added german README file 2011-02-18 * src/baller1.c, src/baller1.h, src/baller2.c, src/screen.c, src/screen.h, src/sdlgui.c, src/sdlgui.h: Implemented button for losing a turn 2011-02-05 * src/screen.c: Draw a gradient in the panel 2011-01-25 * src/baller1.c, src/baller2.c, src/screen.c: Print wind speed and other small cosmetic changes * src/market.c: Small facelift for the market dialog 2011-01-09 * src/baller1.c: Do not exchange digits in print-out * src/baller2.c: Clear destroyed vane with background color 2011-01-08 * src/CMakeLists.txt, src/baller1.c, src/baller2.c, src/baller2.h, src/market.c, src/market.h: Implemented market dialog * src/cannoneer.c, src/font10x16.bmp, src/font10x16.h, src/font8x16.h, src/font8x16.png, src/screen.c, src/sdlgui.c: Implemented v_gtext and switched to a smaller font 2010-12-28 * src/baller1.c, src/baller1.h, src/baller2.c, src/cannoneer.c, src/screen.c, src/screen.h: Improved screen drawing ... the castles now look much nicer 2010-12-26 * src/baller2.c, src/screen.c, src/screen.h: Draw the hill with a nice green color * src/ballergui.c: Wait for events instead of polling to save CPU time 2010-12-02 * src/baller1.c, src/baller1.h, src/baller2.c, src/dlgAlert.c: Silenced most compiler warnings 2010-12-01 * src/cannoneer.c: Call filledCircleColor directly to avoid SDL_UpdateRect of v_circle 2010-11-26 * src/CMakeLists.txt, src/ballergui.c, src/cannoneer.c: Improved cannoneer dialog * src/baller1.c, src/baller1.h, src/baller2.c, src/screen.c: Cleaned up a little bit * src/sdlgui.c, src/sdlgui.h: Added the possibility to draw user-defined objects in the GUI 2010-11-21 * src/baller.h, src/baller1.c, src/baller1.h, src/baller2.c, src/ballergui.c, src/ballergui.h, src/dlgAlert.c, src/sdlgui.c: Initial version of the cannoneer dialog 2010-11-06 * CMakeLists.txt, COPYING.txt, cmake/DistClean.cmake, cmake/FindMath.cmake, cmake/config-cmake.h, doc/de/anleitung.txt, src/CMakeLists.txt, src/baller.dat, src/baller.h, src/baller1.c, src/baller1.h, src/baller2.c, src/baller2.h, src/ballergui.c, src/ballergui.h, src/dlgAlert.c, src/font10x16.bmp, src/font10x16.h, src/screen.c, src/screen.h, src/sdlgui.c, src/sdlgui.h: Initial check-in ballerburg-1.0.1/cmake/0000755000175000017500000000000012145514531014263 5ustar thomasthomasballerburg-1.0.1/cmake/config-cmake.h0000644000175000017500000000044012145514531016755 0ustar thomasthomas/* CMake config.h for Ballerburg SDL */ /* Relative path from bindir to datadir */ #define BIN2DATADIR "@BIN2DATADIR@" /* Relative path from bindir to localedir */ #define BIN2LOCALEDIR "@BIN2LOCALEDIR@" /* Define if you have the libintl.h header file */ #cmakedefine HAVE_LIBINTL_H 1 ballerburg-1.0.1/cmake/FindSDL_gfx.cmake0000644000175000017500000000067212145514531017361 0ustar thomasthomas if(SDLGFX_INCLUDE_DIR) # Already in cache, be silent set(SDLGFX_FIND_QUIETLY TRUE) endif(SDLGFX_INCLUDE_DIR) find_path(SDLGFX_INCLUDE_DIR SDL_gfxPrimitives.h PATH_SUFFIXES SDL) find_library(SDLGFX_LIBRARY NAMES SDL_gfx) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(SDLGFX DEFAULT_MSG SDLGFX_LIBRARY SDLGFX_INCLUDE_DIR) mark_as_advanced(SDLGFX_LIBRARY SDLGFX_INCLUDE_DIR) ballerburg-1.0.1/cmake/FindMath.cmake0000644000175000017500000000060112145514531016754 0ustar thomasthomas if(MATH_INCLUDE_DIR) # Already in cache, be silent set(MATH_FIND_QUIETLY TRUE) endif(MATH_INCLUDE_DIR) find_path(MATH_INCLUDE_DIR math.h) find_library(MATH_LIBRARY NAMES m) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(MATH DEFAULT_MSG MATH_LIBRARY MATH_INCLUDE_DIR) mark_as_advanced(MATH_LIBRARY MATH_INCLUDE_DIR) ballerburg-1.0.1/cmake/Uninstall.cmake0000644000175000017500000000220112145514531017231 0ustar thomasthomas# # "uninstall" target for reverting "make install" # # cmake_policy(SET CMP0007 NEW) if (NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/install_manifest.txt") message(FATAL_ERROR "Cannot find install manifest: \"${CMAKE_CURRENT_BINARY_DIR}/install_manifest.txt\"") endif() file(READ "${CMAKE_CURRENT_BINARY_DIR}/install_manifest.txt" files) string(REGEX REPLACE "\n" ";" files "${files}") # list(REVERSE files) foreach (file ${files}) message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") if (EXISTS "$ENV{DESTDIR}${file}") execute_process( COMMAND ${CMAKE_COMMAND} -E remove "$ENV{DESTDIR}${file}" OUTPUT_VARIABLE rm_out RESULT_VARIABLE rm_retval ) if(NOT ${rm_retval} EQUAL 0) message(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") endif (NOT ${rm_retval} EQUAL 0) else (EXISTS "$ENV{DESTDIR}${file}") message(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.") endif (EXISTS "$ENV{DESTDIR}${file}") endforeach(file) execute_process( COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_CURRENT_BINARY_DIR}/install_manifest.txt ) ballerburg-1.0.1/cmake/DistClean.cmake0000644000175000017500000000131512145514531017133 0ustar thomasthomas# # "distclean" target for removing the generated files from CMake # if(UNIX) add_custom_target(distclean COMMENT "Cleaning up for distribution") # Clean up Ballerburg specific files: foreach(CLEAN_FILE config.h src/ballerburg install_manifest.txt po/ballerburg.pot) add_custom_command(TARGET distclean POST_BUILD COMMAND rm -f ${CLEAN_FILE} DEPENDS clean) endforeach(CLEAN_FILE) # Clean up files that can appear at multiple places: foreach(CLEAN_FILE CMakeFiles CMakeCache.txt '*.a' '*.1.gz' '*.mo' cmake_install.cmake Makefile) add_custom_command(TARGET distclean POST_BUILD COMMAND find . -depth -name ${CLEAN_FILE} | xargs rm -rf DEPENDS clean) endforeach(CLEAN_FILE) endif(UNIX) ballerburg-1.0.1/configure0000755000175000017500000000332312145514531015113 0ustar thomasthomas#!/bin/sh # NOTE: this is a simple script wrapper around the cmake command line # tools, for those used to the autotools configure script conventions if ! which cmake > /dev/null; then echo "ERROR: You need the 'cmake' program to configure the build process." echo "Please install 'cmake' first, then try again." exit 1 fi print_help() { echo "This is a simple configure script wrapper around cmake build system." echo "Parameters are:" echo " --prefix= Set the install prefix to path" echo " --enable-debug Enable debug (non-optimized) build" echo " --disable-color-make Disable color output for Makefiles" echo echo "Please run cmake directly for full control over the build." echo } cmake_args="" build_type="Release" while [ $# -gt 0 ] do preq=${1%=*} # get part before = case $preq in --help) print_help exit 0 ;; --prefix) prefix=${1##*=} # get part after = cmake_args="$cmake_cmd -DCMAKE_INSTALL_PREFIX:PATH=$prefix" ;; --enable-debug) build_type="Debug" cmake_args="$cmake_args -DCMAKE_BUILD_TYPE:STRING=Debug" ;; --disable-debug) build_type="Release" cmake_args="$cmake_args -DCMAKE_BUILD_TYPE:STRING=Release" ;; --enable-color-make) cmake_args="$cmake_args -DCMAKE_COLOR_MAKEFILE:BOOL=1" ;; --disable-color-make) cmake_args="$cmake_args -DCMAKE_COLOR_MAKEFILE:BOOL=0" ;; *) echo "Invalid argument: $preq" echo "Run $0 --help for a list of valid parameters." exit 2 ;; esac shift 1 done cmake `dirname $0` $cmake_args || exit 1 echo echo "Now you must type: make; make install" echo "to actually build and install the software" echo ballerburg-1.0.1/CMakeLists.txt0000644000175000017500000000516612145514531015753 0ustar thomasthomas# ############################### # CMake build file for Ballerburg # ############################### cmake_minimum_required (VERSION 2.8 FATAL_ERROR) project (ballerburg C) set(VERSION 1.0.1) set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") include(CheckIncludeFiles) include(CheckFunctionExists) include(CheckCCompilerFlag) include(DistClean) # Set build type to "Release" if user did not specify any build type yet # Other possible values: Debug, Release, RelWithDebInfo and MinSizeRel if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release) endif(NOT CMAKE_BUILD_TYPE) # #################### # Paths configuration: # #################### if(NOT BINDIR) set(BINDIR bin) endif() if(NOT DATADIR) set(DATADIR share/ballerburg) endif() if(NOT BIN2DATADIR) set(BIN2DATADIR "../share/ballerburg" CACHE STRING "Relative path from bindir to datadir") mark_as_advanced(BIN2DATADIR) endif() if(NOT LOCALEDIR) set(LOCALEDIR share/locale) endif() if(NOT BIN2LOCALEDIR) set(BIN2LOCALEDIR "../share/locale" CACHE STRING "Relative path from bindir to locale directory") mark_as_advanced(BIN2LOCALEDIR) endif() if(NOT MANDIR) set(MANDIR share/man/man1) endif() if(NOT DOCDIR) set(DOCDIR share/doc/ballerburg) endif() # #################### # Check for libraries: # #################### find_package(SDL REQUIRED) find_package(SDL_gfx REQUIRED) find_package(Math REQUIRED) find_package(Gettext) # ########################### # Check for optional headers: # ########################### check_include_files(libintl.h HAVE_LIBINTL_H) # ############### # Various CFLAGS: # ############### if(CMAKE_COMPILER_IS_GNUCC) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsigned-char -Wall") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wextra -Wno-unused-parameter") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wmissing-prototypes -Wstrict-prototypes") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wbad-function-cast") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wformat-security -Wpointer-arith") #set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wcast-qual -Wshadow") #set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror") if (CMAKE_BUILD_TYPE STREQUAL "Debug") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_FORTIFY_SOURCE=2") endif(CMAKE_BUILD_TYPE STREQUAL "Debug") endif(CMAKE_COMPILER_IS_GNUCC) # ######################################### # Create config.h and recurse into subdirs: # ######################################### configure_file(${CMAKE_SOURCE_DIR}/cmake/config-cmake.h ${CMAKE_BINARY_DIR}/config.h) add_subdirectory(src) add_subdirectory(doc) add_subdirectory(po) add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P ${CMAKE_SOURCE_DIR}/cmake/Uninstall.cmake) ballerburg-1.0.1/LIESMICH.txt0000644000175000017500000000563312145514531015150 0ustar thomasthomas ============================ = Ballerburg SDL v1.0.1 = ============================ Copyright (C) 1987, 1989 Eckhard Kruse Copyright (C) 2010, 2013 Thomas Huth Für meine Schwester Martina Huth - ich werde nie die vielen schönen Stunden vergessen, die wir mit diesem Spiel in unserer Kindheit hatten. 1) Lizenz --------- Dieses Programm ist freie Software. Sie können es unter den Bedingungen der GNU General Public License, wie von der Free Software Foundation veröffentlicht, weitergeben und/oder modifizieren, entweder gemäß Version 3 der Lizenz oder (nach Ihrer Option) jeder späteren Version. Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, dass es Ihnen von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE, sogar ohne die implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK. Details finden Sie in der GNU General Public License. Sie sollten ein Exemplar der GNU General Public License zusammen mit diesem Programm erhalten haben. Falls nicht, siehe kann die Lizenz unter eingesehen werden. 2) Was ist Ballerburg? ---------------------- Ballerburg ist ein klassisches Burgenkampfspiel, bei dem sich zwei durch einen Berg getrennte Burgen mit ihren Kanonen gegenseitig bekämpfen müssen. Ballerburg wurde 1987 von Eckhard Kruse für den damals topaktuellen 16/32-Bit Computer Atari ST entwickelt. Jetzt, ein viertel Jahrhundert später liegt mit "Ballerburg SDL" nun die Anpassung des alten Source- codes, welcher von Eckhard Kruse freundlicherweise frei gegeben wurde, an GNU/Linux und andere Systeme mit SDL-Unterstützung vor. 3) Compilieren des Sourcecodes ------------------------------ Zum Compilieren wird der GCC C-Compiler, CMake und folgende Bibliotheken (inklusive Header / Development-Paketen) benötigt: - SDL Version 1.2 (http://www.libsdl.org/) - SDL_gfx Version 2.0 (http://www.ferzkopp.net/) Vor dem ersten Compilieren muss "cmake" mit dem Pfad zu den Sourcen als Parameter aufgerufen werden. Alternativ kann das "configure"-Script oder ein Tool wie "cmake-gui" benutzt werden. Nach dem Konfigurationsvorgang kann der Sourcecode mittels Aufruf von "make" compiliert und anschließen mittels "make install" installiert werden. 4) Spielstart ------------- Zum Starten des Spiels muss man das "ballerburg" Programm starten. Der Spielablauf sollte weitgehen selbsterklärend sein, notfalls gibt es im doc-Verzeichnis auch die Anleitung des orginalen Ballerburgs (Datei "anleitung.html"). Über die "ESC"-Taste erreicht man das Hauptmenü zum Einstellen der Spieler und um ein neues Spiel zu starten. Mittels der "f"-Taste kann zwischen dem Fenster- und Vollbildmodus gewechselt werden, und mit "q" kann das Spiel beendet werden. 5) Kontakt ---------- Bei Fragen, Anregung, Patches oder Kritik bitte eine Mail an folgende Adresse schreiben: huth at tuxfamily.org Und nun viel Spaß mit Ballerburg! ballerburg-1.0.1/COPYING.txt0000644000175000017500000010451312145514531015060 0ustar thomasthomas GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . ballerburg-1.0.1/po/0000755000175000017500000000000012145517051013621 5ustar thomasthomasballerburg-1.0.1/po/it.po0000644000175000017500000001766712145517051014616 0ustar thomasthomas# Italian translations for Ballerburg package # Copyright (C) 2013 Andrea Musuruane . # This file is distributed under the same license as the ballerburg package. # msgid "" msgstr "" "Project-Id-Version: ballerburg 1.0.1\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-05-15 14:42+0200\n" "PO-Revision-Date: 2013-05-16 10:02+0100\n" "Last-Translator: Andrea Musuruane \n" "Language-Team: Italian\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-1\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.4\n" #: src/baller1.c:68 msgid "Oaf" msgstr "Goffo" #: src/baller1.c:68 msgid "Yokel" msgstr "Bifolco" #: src/baller1.c:68 msgid "Boor" msgstr "Cafone" #: src/baller1.c:68 msgid "Doofus" msgstr "Stupido" #: src/baller1.c:69 msgid "Fumbler" msgstr "Pasticcione" #: src/baller1.c:69 msgid "Geezer" msgstr "Vecchio" #: src/baller1.c:69 msgid "Ruffian" msgstr "Farabutto" #: src/baller1.c:105 msgid "Not enough memory for loading the castles." msgstr "Memoria insufficiente per caricare i castelli." #: src/baller1.c:117 msgid "William" msgstr "William" #: src/baller1.c:118 msgid "Frederick" msgstr "Frederick" #: src/baller1.c:178 msgid "Games" msgstr "Partite" #: src/baller1.c:179 msgid "Total won" msgstr "Totale vinte" #: src/baller1.c:180 msgid "Total lost" msgstr "Totale perse" #: src/baller1.c:181 msgid "Won in %" msgstr "Vittorie in %" #: src/baller1.c:293 msgid "You don't have enough gunpowder." msgstr "Non hai abbastanza polvere da sparo." #: src/baller1.c:293 src/baller1.c:297 msgid "Cancel" msgstr "Annulla" #: src/baller1.c:297 msgid "You don't have any cannonballs left." msgstr "Non hai abbastanza palle di cannone." #: src/baller1.c:383 #, c-format msgid "!! %s has won !!" msgstr "%s ha vinto!!" #: src/baller1.c:396 #, c-format msgid "( %s' king was hit," msgstr "( il Re di %s è stato colpito," #: src/baller1.c:398 #, c-format msgid "( %s's king was hit," msgstr "( il Re di %s è stato colpito," #: src/baller1.c:399 msgid "and upon hearing this, the people capitulated. )" msgstr "e dopo aver sentito questo, il popolo capitolò. )" #: src/baller1.c:403 #, c-format msgid "( %s' king has capitulated" msgstr "( Il Re di %s ha capitolato" #: src/baller1.c:406 #, c-format msgid "( %s's king has capitulated" msgstr "( Il Re di %s ha capitolato" #: src/baller1.c:408 msgid " because of the hopeless situation. )" msgstr " a causa della situazione disperata. )" #: src/baller1.c:411 #, c-format msgid "( %s has no folk left. )" msgstr "( %s non ha più sudditi. )" #: src/baller1.c:415 msgid "( The limit of maximum rounds has been reached." msgstr "( E' stato raggiunto il limite massimo di turni impostato." #: src/baller1.c:416 #, c-format msgid "%s is worse off. )" msgstr "%s sta peggio. )" #: src/baller2.c:486 msgid " Round " msgstr " Turno " #: src/baller2.c:660 msgid "The king says:" msgstr "Il Re dice:" #: src/baller2.c:661 msgid "Humbly acknowledged" msgstr "Ammesso con umiltà" #: src/baller2.c:662 msgid "" "Well...\n" " alright...\n" " Carry on..." msgstr "" "Beh...\n" " va bene...\n" " Prosegui..." #: src/baller2.c:663 msgid "" "We are satisfied\n" " with your performance!" msgstr "" "Siamo soddisfatti\n" " del tuo rendimento!" #: src/baller2.c:664 msgid "" "Excellent,\n" " keep at it!" msgstr "" "Eccellente,\n" " continua a farlo!" #: src/baller2.c:665 msgid "" "Maybe you ought to\n" " lower Our taxes..." msgstr "" "Forse dovresti\n" " abbassare le nostre tasse..." #: src/baller2.c:666 msgid "" "If you keep this up,\n" " We shall discharge you!" msgstr "" "Se continui così,\n" " dovremo congedarti!" #: src/baller2.c:667 msgid "" "Why don't you buy\n" " a shaft tower..." msgstr "" "Perché non compri\n" " un castelletto?" #: src/baller2.c:668 msgid "" "You ought to\n" " kindly make more of\n" " an effort!" msgstr "" "Cortesemente\n" " dovresti fare più\n" " di uno sforzo!" #: src/baller2.c:669 msgid "" "You don't need to visit Us\n" " in each round." msgstr "" "Non devi venire a trovarci\n" " ad ogni turno." #: src/baller2.c:670 #, c-format msgid "" "Are you aware\n" " that you have already visited Us\n" " %d times thus far?" msgstr "" "Sei consapevole\n" " che sei già venuto a trovarci\n" " %d volte fino ad ora?" #: src/baller2.c:671 msgid "" "So, are you certain\n" " that you will manage\n" " without a weather vane?" msgstr "" "Allora, sei certo\n" " di gestirlo\n" " senza una banderuola?" #: src/baller2.c:672 msgid "Nice to see you..." msgstr "Piacere di vederti..." #: src/baller2.c:673 msgid "" "What are We supposed\n" " to say in such an\n" " early phase?" msgstr "" "Cosa dovremmo\n" " dire in una fase\n" " così precoce?" #: src/baller2.c:674 msgid "" "You ought to earn more money,\n" " build more shaft towers,\n" " and vanquish the opponent." msgstr "" "Dovresti guadagnare più soldi,\n" " costruire più castelletti,\n" " e sconfiggere l'avversario." #: src/baller2.c:675 msgid "" "We do not have anything new\n" " to say to you." msgstr "" "Non abbiamo nulla di nuovo\n" " da dirti." #: src/baller2.c:676 msgid "" "We are pleased for you\n" " to come around and visit Us." msgstr "" "Siamo contenti che\n" " tu sia venuto a trovarci." #: src/baller2.c:691 msgid "" "The king is not in the mood\n" "to talk to you." msgstr "" "Il Re non è in vena \n" "di parlare con te." #: src/baller2.c:691 msgid "Too bad." msgstr "Peccato." #: src/ballergui.c:52 src/settings.c:223 msgid "Quit Ballerburg?" msgstr "Esci da Ballerburg?" #: src/ballergui.c:52 src/settings.c:223 msgid "Yes" msgstr "Sì" #: src/ballergui.c:52 src/settings.c:223 msgid "No" msgstr "No" #: src/cannoneer.c:59 msgid "Cannon" msgstr "Cannone" #: src/cannoneer.c:61 msgid "Angle:" msgstr "Angolo:" #: src/cannoneer.c:68 src/market.c:83 msgid "Gunpowder:" msgstr "Polvere:" #: src/market.c:77 msgid "You have:" msgstr "Hai:" #: src/market.c:79 msgid "Funds:" msgstr "Capitale:" #: src/market.c:80 msgid "Shaft towers:" msgstr "Castelletti:" #: src/market.c:81 msgid "Cannons:" msgstr "Cannoni:" #: src/market.c:82 src/market.c:104 msgid "Weather vane:" msgstr "Banderuola:" #: src/market.c:84 msgid "Cannonballs:" msgstr "Palle di cannone:" #: src/market.c:85 msgid "Population:" msgstr "Popolazione:" #: src/market.c:86 msgid "Taxes in %" msgstr "Tasse in %" #: src/market.c:99 msgid "Market:" msgstr "Mercato:" #: src/market.c:101 msgid "Lay bricks:" msgstr "Posare i mattoni:" #: src/market.c:102 msgid "Shaft tower:" msgstr "Castelletto:" #: src/market.c:103 msgid "Cannon:" msgstr "Cannone:" #: src/market.c:105 msgid "Powder x30:" msgstr "Polvere x30:" #: src/market.c:106 msgid "2 cannonballs:" msgstr "2 palle di cannone:" #: src/market.c:114 src/screen.c:40 msgid "Done" msgstr "Fatto" #: src/market.c:135 msgid " Lay bricks: " msgstr " Disponi i mattoni: " #: src/market.c:136 src/market.c:159 #, c-format msgid " Bricks left: %02d " msgstr " Mattoni rimasti: %02d " #: src/settings.c:65 msgid "Settings" msgstr "Impostazioni" #: src/settings.c:68 src/settings.c:247 msgid "Player 1" msgstr "Giocatore 1" #: src/settings.c:69 src/settings.c:86 msgid "Name:" msgstr "Nome:" #: src/settings.c:71 src/settings.c:88 msgid "Human" msgstr "Umano" #: src/settings.c:72 src/settings.c:89 msgid "Computer" msgstr "Computer" #: src/settings.c:73 src/settings.c:90 msgid "AI strategy:" msgstr "Strategia IA:" #: src/settings.c:78 src/settings.c:95 msgid "AI strength:" msgstr "Forza IA:" #: src/settings.c:85 src/settings.c:251 msgid "Player 2" msgstr "Giocatore 2" #: src/settings.c:101 msgid "Maximum rounds:" msgstr "Numero di turni:" #: src/settings.c:105 msgid "unlimited" msgstr "illimitato" #: src/settings.c:107 msgid "King may capitulate" msgstr "Il Re può capitolare" #: src/settings.c:108 msgid "Players may build" msgstr "I giocatori possono costruire" #: src/settings.c:110 src/settings.c:245 msgid "New game" msgstr "Nuova partita" #: src/settings.c:111 msgid "Continue game" msgstr "Continua partita" #: src/settings.c:112 msgid "Exit program" msgstr "Esci dal programma" ballerburg-1.0.1/po/CMakeLists.txt0000644000175000017500000000232712145514531016365 0ustar thomasthomas# ##################################### # CMake build file for the translations # ##################################### if (GETTEXT_FOUND) # Generate template file add_custom_target(po-template ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}.pot) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}.pot COMMAND xgettext -k_ -kN_ --package-version=${VERSION} --package-name=${CMAKE_PROJECT_NAME} -o ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}.pot ${CMAKE_CURRENT_SOURCE_DIR}/../src/*.c COMMAND sed -i -e s/charset=CHARSET/charset=ISO-8859-1/ -e s%"${CMAKE_CURRENT_SOURCE_DIR}/../"%%g ${CMAKE_PROJECT_NAME}.pot DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/../src/*.c ) file(GLOB POFILES *.po) foreach(POFILE ${POFILES}) string(REGEX REPLACE "(.*)/(.*)\\.po" "\\2" LANG ${POFILE}) string(REPLACE ".po" ".mo" MOFILE ${POFILE}) add_custom_command( OUTPUT ${MOFILE} COMMAND ${GETTEXT_MSGFMT_EXECUTABLE} -o ${MOFILE} ${POFILE} DEPENDS ${POFILE} ) add_custom_target(mo-file-${LANG} ALL DEPENDS ${MOFILE}) install(FILES ${MOFILE} RENAME ${CMAKE_PROJECT_NAME}.mo DESTINATION ${LOCALEDIR}/${LANG}/LC_MESSAGES) endforeach() endif (GETTEXT_FOUND) ballerburg-1.0.1/po/de.po0000644000175000017500000001751512145514531014562 0ustar thomasthomas# German translations for Ballerburg package # Copyright (C) 2012 Thomas Huth # This file is distributed under the same license as the ballerburg package. # msgid "" msgstr "" "Project-Id-Version: ballerburg 1.0.1\n" "Report-Msgid-Bugs-To: Thomas Huth\n" "POT-Creation-Date: 2013-05-10 22:34+0200\n" "PO-Revision-Date: 2012-04-26 20:05+0100\n" "Last-Translator: Thomas Huth \n" "Language-Team: German\n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-1\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: src/baller1.c:68 msgid "Oaf" msgstr "Tölpel" #: src/baller1.c:68 msgid "Yokel" msgstr "Dummel" #: src/baller1.c:68 msgid "Boor" msgstr "Brubbel" #: src/baller1.c:68 msgid "Doofus" msgstr "Wusel" #: src/baller1.c:69 msgid "Fumbler" msgstr "Brösel" #: src/baller1.c:69 msgid "Geezer" msgstr "Toffel" #: src/baller1.c:69 msgid "Ruffian" msgstr "Rüpel" #: src/baller1.c:105 msgid "Not enough memory for loading the castles." msgstr "Nicht genug Speicher um die Burgen zu laden." #: src/baller1.c:117 msgid "William" msgstr "Wilhelm" #: src/baller1.c:118 msgid "Frederick" msgstr "Friedrich" #: src/baller1.c:178 msgid "Games" msgstr "Spiele" #: src/baller1.c:179 msgid "Total won" msgstr "Gewonnen" #: src/baller1.c:180 msgid "Total lost" msgstr "Verloren" #: src/baller1.c:181 msgid "Won in %" msgstr "Siege %" #: src/baller1.c:294 msgid "You don't have enough gunpowder." msgstr "Dein Pulver reicht nicht!" #: src/baller1.c:294 src/baller1.c:298 msgid "Cancel" msgstr "Abbruch" #: src/baller1.c:298 msgid "You don't have any cannonballs left." msgstr "Du hast keine Kugeln mehr!" #: src/baller1.c:384 msgid "!! %s has won !!" msgstr "!! %s hat gewonnen !!" #: src/baller1.c:397 msgid "( %s' king was hit," msgstr "( %s' König wurde getroffen," #: src/baller1.c:399 msgid "( %s's king was hit," msgstr "( %ss König wurde getroffen," #: src/baller1.c:400 msgid "and upon hearing this, the people capitulated. )" msgstr " daraufhin ergab sich dessen Volk. )" #: src/baller1.c:404 msgid "( %s' king has capitulated" msgstr "( %s' König hat aufgrund der" #: src/baller1.c:407 msgid "( %s's king has capitulated" msgstr "( %ss König hat aufgrund der" #: src/baller1.c:409 msgid " because of the hopeless situation. )" msgstr " aussichtslosen Lage kapituliert. )" #: src/baller1.c:412 msgid "( %s has no folk left. )" msgstr "( %s hat kein Volk mehr. )" #: src/baller1.c:416 msgid "( The limit of maximum rounds has been reached." msgstr "( Die maximale Rundenzahl ist erreicht." #: src/baller1.c:417 msgid "%s is worse off. )" msgstr "%s befindet sich in der schlechteren Lage. )" #: src/baller2.c:486 msgid " Round " msgstr " Runde " #: src/baller2.c:660 msgid "The king says:" msgstr "Der König meint:" #: src/baller2.c:661 msgid "Humbly acknowledged" msgstr "Demütig zur Kenntnis genommen" #: src/baller2.c:662 msgid "" "Well...\n" " alright...\n" " Carry on..." msgstr "" "Naja...\n" " Nun gut...\n" " Weiter so..." #: src/baller2.c:663 msgid "" "We are satisfied\n" " with your performance!" msgstr "" "Ich bin zufrieden\n" " mit Ihren Leistungen!" #: src/baller2.c:664 msgid "" "Excellent,\n" " keep at it!" msgstr "" "Hervorragend,\n" " weiter so!" #: src/baller2.c:665 msgid "" "Maybe you ought to\n" " lower Our taxes..." msgstr "" "Vielleicht sollten Sie mal\n" " die Steuern senken..." #: src/baller2.c:666 msgid "" "If you keep this up,\n" " We shall discharge you!" msgstr "" "Wenn Sie so weiter machen\n" " werde ich Sie entlassen!" #: src/baller2.c:667 msgid "" "Why don't you buy\n" " a shaft tower..." msgstr "" "Vielleicht mal 'nen\n" " Förderturm kaufen..." #: src/baller2.c:668 msgid "" "You ought to\n" " kindly make more of\n" " an effort!" msgstr "" "Sie sollten sich\n" " gefälligst mehr Mühe\n" " geben!" #: src/baller2.c:669 msgid "" "You don't need to visit Us\n" " in each round." msgstr "" "Sie brauchen nicht\n" " jede Runde zu kommen." #: src/baller2.c:670 #, c-format msgid "" "Are you aware\n" " that you have already visited Us\n" " %d times thus far?" msgstr "" "Wissen Sie eigentlich,\n" " dass Sie mich bereits\n" " %d mal besucht haben?" #: src/baller2.c:671 msgid "" "So, are you certain\n" " that you will manage\n" " without a weather vane?" msgstr "" "Und Sie sind sich sicher,\n" " dass Sie auch ohne eine\n" " Windfahne zurecht kommen?" #: src/baller2.c:672 msgid "Nice to see you..." msgstr "Schön, Sie zu sehen..." #: src/baller2.c:673 msgid "" "What are We supposed\n" " to say in such an\n" " early phase?" msgstr "" "Was soll ich denn in\n" " so einer frühen Phase\n" " schon sagen?" #: src/baller2.c:674 msgid "" "You ought to earn more money,\n" " build more shaft towers,\n" " and vanquish the opponent." msgstr "" "Sie sollten mehr Geld\n" " verdienen, Fördertürme bauen\n" " und den Gegner besiegen." #: src/baller2.c:675 msgid "" "We do not have anything new\n" " to say to you." msgstr "" "Ich habe Ihnen nichts\n" " neues zu sagen." #: src/baller2.c:676 msgid "" "We are pleased for you\n" " to come around and visit Us." msgstr "" "Find' ich nett, dass\n" " Sie mich mal besuchen!" #: src/baller2.c:691 msgid "" "The king is not in the mood\n" "to talk to you." msgstr "" "Der König hat keine Lust,\n" "dich zu sprechen." #: src/baller2.c:691 msgid "Too bad." msgstr "Schade" #: src/ballergui.c:52 src/settings.c:223 msgid "Quit Ballerburg?" msgstr "Ballerburg beenden?" #: src/ballergui.c:52 src/settings.c:223 msgid "Yes" msgstr "Ja" #: src/ballergui.c:52 src/settings.c:223 msgid "No" msgstr "Nein" #: src/cannoneer.c:59 msgid "Cannon" msgstr "Kanone" #: src/cannoneer.c:61 msgid "Angle:" msgstr "Winkel:" #: src/cannoneer.c:68 src/market.c:83 msgid "Gunpowder:" msgstr "Pulver:" #: src/market.c:77 msgid "You have:" msgstr "Du hast:" #: src/market.c:79 msgid "Funds:" msgstr "Geld:" #: src/market.c:80 msgid "Shaft towers:" msgstr "Fördertürme:" #: src/market.c:81 msgid "Cannons:" msgstr "Geschütze:" #: src/market.c:82 src/market.c:104 msgid "Weather vane:" msgstr "Windfahne:" #: src/market.c:84 msgid "Cannonballs:" msgstr "Kugeln:" #: src/market.c:85 msgid "Population:" msgstr "Volk:" #: src/market.c:86 msgid "Taxes in %" msgstr "Steuern in %" #: src/market.c:99 msgid "Market:" msgstr "Markt:" #: src/market.c:101 msgid "Lay bricks:" msgstr "Anbauen:" #: src/market.c:102 msgid "Shaft tower:" msgstr "Förderturm:" #: src/market.c:103 msgid "Cannon:" msgstr "Geschütz:" #: src/market.c:105 msgid "Powder x30:" msgstr "30 Pulver:" #: src/market.c:106 msgid "2 cannonballs:" msgstr "2 Kugeln:" #: src/market.c:114 src/screen.c:40 msgid "Done" msgstr "Fertig" #: src/market.c:135 msgid " Lay bricks: " msgstr " Anbauen: " #: src/market.c:136 src/market.c:159 #, c-format msgid " Bricks left: %02d " msgstr " Verbleibende Steine: %02d " #: src/settings.c:65 msgid "Settings" msgstr "Einstellungen" #: src/settings.c:68 src/settings.c:247 msgid "Player 1" msgstr "Spieler 1" #: src/settings.c:69 src/settings.c:86 msgid "Name:" msgstr "Name:" #: src/settings.c:71 src/settings.c:88 msgid "Human" msgstr "Mensch" #: src/settings.c:72 src/settings.c:89 msgid "Computer" msgstr "Computer" #: src/settings.c:73 src/settings.c:90 msgid "AI strategy:" msgstr "KI Strategie:" #: src/settings.c:78 src/settings.c:95 msgid "AI strength:" msgstr "KI Stärke:" #: src/settings.c:85 src/settings.c:251 msgid "Player 2" msgstr "Spieler 2" #: src/settings.c:101 msgid "Maximum rounds:" msgstr "Maximale Rundenzahl:" #: src/settings.c:105 msgid "unlimited" msgstr "unbegrenzt" #: src/settings.c:107 msgid "King may capitulate" msgstr "König kann kapitulieren" #: src/settings.c:108 msgid "Players may build" msgstr "Anbauen ist erlaubt" #: src/settings.c:110 src/settings.c:245 msgid "New game" msgstr "Neues Spiel" #: src/settings.c:111 msgid "Continue game" msgstr "Weiterspielen" #: src/settings.c:112 msgid "Exit program" msgstr "Programm beenden" ballerburg-1.0.1/po/fi.po0000644000175000017500000001745112145514531014567 0ustar thomasthomas# -*- coding: iso-latin-1; -*- # Finnish translations for Ballerburg # # Based on the finnish Atari ST version of Ballerburg by Eero Tamminen. # # This file is distributed under the same license as the ballerburg package. # msgid "" msgstr "" "Project-Id-Version: ballerburg 1.0.1\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-05-10 22:40+0200\n" "PO-Revision-Date: 2012-03-08 22:12+0100\n" "Last-Translator: Eero Tamminen\n" "Language-Team: Finnish\n" "Language: fi\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-1\n" "Content-Transfer-Encoding: 8bit\n" #: src/baller1.c:68 msgid "Oaf" msgstr "Ääliö" #: src/baller1.c:68 msgid "Yokel" msgstr "Juntti" #: src/baller1.c:68 msgid "Boor" msgstr "Moukka" #: src/baller1.c:68 msgid "Doofus" msgstr "Tahvo" #: src/baller1.c:69 msgid "Fumbler" msgstr "Tumpelo" #: src/baller1.c:69 msgid "Geezer" msgstr "Hyypiö" #: src/baller1.c:69 msgid "Ruffian" msgstr "Lurjus" #: src/baller1.c:105 msgid "Not enough memory for loading the castles." msgstr "Muisti ei riitä linnojen lataukseen!" #: src/baller1.c:117 msgid "William" msgstr "Viljami" #: src/baller1.c:118 msgid "Frederick" msgstr "Reetu" #: src/baller1.c:178 msgid "Games" msgstr "Pelit" #: src/baller1.c:179 msgid "Total won" msgstr "Voitetut" #: src/baller1.c:180 msgid "Total lost" msgstr "Hävityt" #: src/baller1.c:181 msgid "Won in %" msgstr "Voitto-%" #: src/baller1.c:294 msgid "You don't have enough gunpowder." msgstr "Ei tarpeeksi ruutia!" #: src/baller1.c:294 src/baller1.c:298 msgid "Cancel" msgstr "Peru" #: src/baller1.c:298 msgid "You don't have any cannonballs left." msgstr "Ei tykinkuulia!" #: src/baller1.c:384 #, c-format msgid "!! %s has won !!" msgstr "!! %s on voittanut !!" #: src/baller1.c:397 #, c-format msgid "( %s' king was hit," msgstr "( %s: Kuninkaaseen osui, ja" #: src/baller1.c:399 #, c-format msgid "( %s's king was hit," msgstr "( %s: Kuninkaaseen osui, ja" #: src/baller1.c:400 msgid "and upon hearing this, the people capitulated. )" msgstr "sen kuultuaan hänen alamaisensa antautuivat. )" #: src/baller1.c:404 #, c-format msgid "( %s' king has capitulated" msgstr "( %s: Tässä tilanteessa Kuningas" #: src/baller1.c:407 #, c-format msgid "( %s's king has capitulated" msgstr "( %s: Tässä tilanteessa Kuningas" #: src/baller1.c:409 msgid " because of the hopeless situation. )" msgstr " ei voinut muuta kuin antautua. )" #: src/baller1.c:412 #, c-format msgid "( %s has no folk left. )" msgstr "( %s kaikki alamaiset katosivat. )" #: src/baller1.c:416 msgid "( The limit of maximum rounds has been reached." msgstr "( Kaikki kierrokset on käyty." #: src/baller1.c:417 #, c-format msgid "%s is worse off. )" msgstr "%s oli huonommassa asemassa. )" #: src/baller2.c:486 msgid " Round " msgstr " Vuoro " #: src/baller2.c:660 msgid "The king says:" msgstr "Kuningas lausui:" #: src/baller2.c:661 msgid "Humbly acknowledged" msgstr "Nöyrästi huomioitu" #: src/baller2.c:662 msgid "" "Well...\n" " alright...\n" " Carry on..." msgstr "" "Hmm...\n" " No, niin...\n" " Jatkakaa..." #: src/baller2.c:663 msgid "" "We are satisfied\n" " with your performance!" msgstr "" "Olemme tyytyväisiä\n" " saavutuksiinne!" #: src/baller2.c:664 msgid "" "Excellent,\n" " keep at it!" msgstr "" "Erinomaista,\n" " jatkakaa toki!" #: src/baller2.c:665 msgid "" "Maybe you ought to\n" " lower Our taxes..." msgstr "" "Ehkäpä teidän pitäisi\n" " alentaa verojamme..." #: src/baller2.c:666 msgid "" "If you keep this up,\n" " We shall discharge you!" msgstr "" "Jatkakaa samalla tavalla\n" " ja lennätte pihalle!" #: src/baller2.c:667 msgid "" "Why don't you buy\n" " a shaft tower..." msgstr "" "Ettekö ostaisi\n" " akselitornia..." #: src/baller2.c:668 msgid "" "You ought to\n" " kindly make more of\n" " an effort!" msgstr "" "Voisitteko\n" " ystävällisesti tehdä\n" " itsekin jotain!" #: src/baller2.c:669 msgid "" "You don't need to visit Us\n" " in each round." msgstr "" "Miksi vaivaatte\n" " meitä jatkuvasti?" #: src/baller2.c:670 #, c-format msgid "" "Are you aware\n" " that you have already visited Us\n" " %d times thus far?" msgstr "" "Tiedättekö, että\n" " olette pyytänyt\n" " audienssiamme %d kertaa?" #: src/baller2.c:671 msgid "" "So, are you certain\n" " that you will manage\n" " without a weather vane?" msgstr "" "Niin, selviättekö varmasti\n" " ilman tuuliviiriä?" #: src/baller2.c:672 msgid "Nice to see you..." msgstr "Mukava nähdä teitä taas..." #: src/baller2.c:673 msgid "" "What are We supposed\n" " to say in such an\n" " early phase?" msgstr "" "Mitä meidän pitäisi\n" " sanoa näin\n" " aikaisessa vaiheessa?" #: src/baller2.c:674 msgid "" "You ought to earn more money,\n" " build more shaft towers,\n" " and vanquish the opponent." msgstr "" "Teidän pitäisi tienata lisää,\n" "rakentaa akselitorneja,\n" " ja kukistakaa kilpailijanne." #: src/baller2.c:675 msgid "" "We do not have anything new\n" " to say to you." msgstr "" "Meillä ei ole teille mitään\n" " uutta sanottavaa." #: src/baller2.c:676 msgid "" "We are pleased for you\n" " to come around and visit Us." msgstr "" "Olipa ystävällistä, että\n" " tulitte luoksemme." #: src/baller2.c:691 msgid "" "The king is not in the mood\n" "to talk to you." msgstr "" "Kuningas ei ole\n" "keskustelutuulella." #: src/baller2.c:691 msgid "Too bad." msgstr "Harmi." #: src/ballergui.c:52 src/settings.c:223 msgid "Quit Ballerburg?" msgstr "Lopetetaanko Ballerburg?" #: src/ballergui.c:52 src/settings.c:223 msgid "Yes" msgstr "Kyllä" #: src/ballergui.c:52 src/settings.c:223 msgid "No" msgstr "Ei" #: src/cannoneer.c:59 msgid "Cannon" msgstr "Kanuuna" #: src/cannoneer.c:61 msgid "Angle:" msgstr "Kulma:" #: src/cannoneer.c:68 src/market.c:83 msgid "Gunpowder:" msgstr "Ruuti:" #: src/market.c:77 msgid "You have:" msgstr "Sinulla on:" #: src/market.c:79 msgid "Funds:" msgstr "Varoja:" #: src/market.c:80 msgid "Shaft towers:" msgstr "Akselitorneja:" #: src/market.c:81 msgid "Cannons:" msgstr "Kanuunoita:" #: src/market.c:82 src/market.c:104 msgid "Weather vane:" msgstr "Tuuliviirejä:" #: src/market.c:84 msgid "Cannonballs:" msgstr "Kanuunankuulia:" #: src/market.c:85 msgid "Population:" msgstr "Väestö:" #: src/market.c:86 msgid "Taxes in %" msgstr "Vero-%" #: src/market.c:99 msgid "Market:" msgstr "Markkinat:" #: src/market.c:101 msgid "Lay bricks:" msgstr "Rakenna:" #: src/market.c:102 msgid "Shaft tower:" msgstr "Akselitorni:" #: src/market.c:103 msgid "Cannon:" msgstr "Kanuuna:" #: src/market.c:105 msgid "Powder x30:" msgstr "Ruutia x30:" #: src/market.c:106 msgid "2 cannonballs:" msgstr "2 kanuunankuulaa:" #: src/market.c:114 src/screen.c:40 msgid "Done" msgstr "Valmis" #: src/market.c:135 msgid " Lay bricks: " msgstr " Rakenna: " #: src/market.c:136 src/market.c:159 #, c-format msgid " Bricks left: %02d " msgstr " Tiiliä jäljellä: %02d " #: src/settings.c:65 msgid "Settings" msgstr "Asetukset" #: src/settings.c:68 src/settings.c:247 msgid "Player 1" msgstr "Pelaaja 1" #: src/settings.c:69 src/settings.c:86 msgid "Name:" msgstr "Nimi:" #: src/settings.c:71 src/settings.c:88 msgid "Human" msgstr "Ihminen" #: src/settings.c:72 src/settings.c:89 msgid "Computer" msgstr "Tietokone" #: src/settings.c:73 src/settings.c:90 msgid "AI strategy:" msgstr "Strategia:" #: src/settings.c:78 src/settings.c:95 msgid "AI strength:" msgstr "Tekoälykkyys:" #: src/settings.c:85 src/settings.c:251 msgid "Player 2" msgstr "Pelaaja 2" #: src/settings.c:101 msgid "Maximum rounds:" msgstr "Kierroksia enintään:" #: src/settings.c:105 msgid "unlimited" msgstr "rajoittamaton" #: src/settings.c:107 msgid "King may capitulate" msgstr "Kuningas voi antautua" #: src/settings.c:108 msgid "Players may build" msgstr "Pelaajat voivat rakentaa" #: src/settings.c:110 src/settings.c:245 msgid "New game" msgstr "Uusi peli" #: src/settings.c:111 msgid "Continue game" msgstr "Jatka peliä" #: src/settings.c:112 msgid "Exit program" msgstr "Lopeta ohjelma" ballerburg-1.0.1/src/0000755000175000017500000000000012145514532013773 5ustar thomasthomasballerburg-1.0.1/src/baller1.h0000644000175000017500000000343312145514531015470 0ustar thomasthomas/* baller1.h - prototypes and definitions for baller1.c Copyright (C) 2010, 2011 Thomas Huth This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #define P57 57.296 #define G 0.02 /* Fallbeschleunigung ( g/500 ) */ extern short handle, mx,my,bt,dum,m_buf[8], xy[100], bur[2],bx[2],by[2], ge[2],pu[2],ku[2],vo[2],st[2],kn[2], wx[2],wy[2], *bg, zug,n, p[6], max_rund, fx,fy,fw,fh, *burgen[], b_anz; extern int ftx, fty, ftw, fth; extern const char *l_nam, *r_nam; extern int f; extern char mod, wnd, end, an_erl, au_kap, nsp1[],nsp2[]; extern int cw[2],cx[2]; extern const char *cn[7]; typedef struct { short x,y,w,p; } ka_t; extern ka_t ka[2][10]; typedef struct { short x,y; } ft_t; extern ft_t ft[2][5]; #define fn() f=1-2*(n&1) int main(int argc, char **argv); void tabelle(void); void z_txt(short a); void neues(void); int ein_zug(void); void rechnen(void); void ende(void); int m_wait(void); void werdran(char c); void fahne(void); int t_load(void); int t_save(void); void burgen_laden(void); int obj_do(int adr); void gem_init(void); int loc(int x, int y); void line(short x1, short y1, short x2, short y2); void box(short x, short y, short x2, short y2, short c); ballerburg-1.0.1/src/baller1.c0000644000175000017500000003537612145514531015476 0ustar thomasthomas/* baller1.c Copyright (C) 1987, 1989 Eckhard Kruse Copyright (C) 2010, 2013 Thomas Huth This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /********************************************************************** * B a l l e r b u r g Modul 1 * * Dies ist der Hauptteil von Ballerburg. Die Routinen dieses Teils * * dienen im großen und ganzen der Steuerung des Programmes, sowie * * der Ausführung elementarer Grafikoperationen. * **********************************************************************/ #include #include #include #include #include #include "baller1.h" #include "baller2.h" #include "ballergui.h" #include "screen.h" #include "psg.h" #include "market.h" #include "music.h" #include "paths.h" #include "i18n.h" #define Min(a,b) ((a)<(b)?(a):(b)) #define Max(a,b) ((a)>(b)?(a):(b)) #define menu(a) /* wind_update(3-a) */ #define hide() /* graf_mouse(256,0) */ #define show() /* graf_mouse(257,0) */ #define COMP_NUM 7 short handle, mx,my,bt,dum,m_buf[8], xy[100], bur[2],bx[2],by[2], ge[2],pu[2],ku[2],vo[2],st[2],kn[2], wx[2],wy[2], *bg, zug,n, p[6], max_rund, *burgen[30], b_anz; static short ws, wc, t_gew[COMP_NUM][COMP_NUM+4]; int ftx, fty, ftw, fth; /* Koordinaten von "Fertig" */ void *bur_ad; const char *l_nam, *r_nam; int f; char mod, wnd, end, txt[4], an_erl, au_kap; int cw[2] = { 2, 2 }; /* Computer strategy */ int cx[2] = { 1, 1 }; /* Computer strength */ /* Computer player names (i.e. the strategies) */ const char *cn[COMP_NUM] = { N_("Oaf"), N_("Yokel"), N_("Boor"), N_("Doofus"), N_("Fumbler"), N_("Geezer"), N_("Ruffian") }; char nsp1[22], nsp2[22]; /* Names of the players */ ka_t ka[2][10]; ft_t ft[2][5]; /** * Initialize internationalization support */ static void i18n_init(void) { #if HAVE_LIBINTL_H setlocale(LC_ALL, ""); bindtextdomain("ballerburg", Paths_GetLocaleDir()); textdomain("ballerburg"); #endif } /*****************************************************************************/ int main(int argc, char **argv) { Paths_Init(argv[0]); i18n_init(); scr_init(); scr_init_done_button(&ftx, &fty, &ftw, &fth); m_laden("baller.mus"); /* Laden der Musikdatei mit Funktion aus music.c */ bur_ad = malloc(32000); /* Speicher für Burgdaten */ if (!bur_ad) { puts(_("Not enough memory for loading the castles.")); exit(-1); } an_erl=1; max_rund=32767; au_kap=1; t_load(); burgen_laden(); psg_audio_init(); strcpy(nsp1, _("William")); strcpy(nsp2, _("Frederick")); l_nam = nsp1; r_nam = nsp2; mod=0; /* Spielmodus ( wer gegen wen ) */ neues(); while ( ein_zug() ); t_save(); return 0; } /**************************** Tabelle ****************************************/ void tabelle(void) { short i,j; void *save_area; save_area = scr_save_bg(17, 55, 640-17*2+1, 400-55*2+24+1); vsf_interior(handle,0); box(17,56, 623,367, 1); box(19,58, 621,365, 1); box(20,59, 620,364, 1); line(108,59, 108,364); for (i = 116; i < 584; i += 72) line(i,59,i,364); line(20,84, 620,84); for (i = 92; i < 264; i += 24) line(20,i, 620,i); for (i = 268; i < 364; i += 24) line(20,i, 620,i); for (i = 0; i < COMP_NUM; i++) v_gtext(handle, 124+i*72, 78, _(cn[i])); for (i = 0; i < COMP_NUM; i++) v_gtext(handle, 36, 110+i*24, _(cn[i])); vsf_interior(handle,2); vsf_style(handle, 1); for (i = 0; i < COMP_NUM; i++) { for (j = 0; j < COMP_NUM+4; j++) { z_txt(t_gew[i][j]); if (j == COMP_NUM+3 && !t_gew[i][COMP_NUM]) { txt[0]=32; txt[1]='-'; txt[2]=0; } v_gtext(handle, 140+i*72, 110+j*24+8*(j>=COMP_NUM), txt); if (i == j) box(116+i*72, 92+j*24, 188+i*72, 116+j*24, 1); } } v_gtext(handle, 28, 286, _("Games")); v_gtext(handle, 28, 310, _("Total won")); v_gtext(handle, 28, 334, _("Total lost")); v_gtext(handle, 28, 358, _("Won in %")); line(20, 59, 108, 84); v_gtext(handle, 36, 80, "-"); v_gtext(handle, 88, 72, "+"); while (bt == 0 && event(1, 0) == 0); while (bt != 0 && event(1, 0) == 0); scr_restore_bg(save_area); } void z_txt(short a) { txt[0]=a/100+48; txt[1]=a%100/10+48; txt[2]=a%10+48; if (a<100) { txt[0]=32; if (a<10) txt[1]=32; } } /******************** Initialisierung vor neuem Spiel ************************/ void neues(void) { static short pr[6]={ 200,500,400,150,50,50 }; /* Preise zu Beginn */ short j; wnd=rand()%60-30; st[0]=st[1]=20; kn[0]=kn[1]=0; for ( j=0;j<6;j++ ) p[j]=pr[j]*(95+rand()%11)/100; bild(); for ( n=0;n<2;n++ ) { bg=burgen[bur[n]]; wx[n]=n? 639-bg[23]:bg[23]; wy[n]=by[n]-bg[24]; for ( f=0;f<5; ) ft[n][f++].x=-1; } zug=n=end=0; f=1; } /************************* Durchführen eines Zuges ***************************/ int ein_zug(void) { short i = 0, fl, a; // puts("ein zug ..."); n=zug&1; fn(); kn[n]&=~16; wnd=wnd*9/10+rand()%12-6; werdran(1); do { fl=0; menu(1); do { if (event(!(mod&(2-n)), 1) != 0) return(0); } while (!bt && !(mod&(2-n))); //printf("ein zug %i %i %i\n", bt, mod, a); menu(0); bg=burgen[bur[n]]; if ( mod&(2-n) ) { hide(); i=comp(); show(); fl=1+(i<0); } else if (mx > ftx && mx < ftx+ftw && my > fty && my < fty+fth) { /* "Fertig"-Knopf wurde gedrueckt */ scr_draw_done_button(1); do { event(1, 0); } while (bt); scr_draw_done_button(0); fl=2; } else { for ( i=0;i<10;i++ ) if ( ka[n][i].x<=mx && ka[n][i].x+20>=mx && ka[n][i].x!=-1 && ka[n][i].y>=my && ka[n][i].y-14<=my ) break; if ( i>9 ) { if (drin( bg[25],bg[26],bg[31],bg[32],0,mx,my) || drin( bg[27],bg[28],bg[33],bg[34],0,mx,my) || drin( bg[29],bg[30],bg[35],bg[36],0,mx,my)) markt(); else if (drin( bg[21],bg[22],30,25,0,mx,my)) koenig(); } else if (pu[n] < 5) { DlgAlert_Notice(_("You don't have enough gunpowder."), _("Cancel")); } else if (ku[n] == 0) { DlgAlert_Notice(_("You don't have any cannonballs left."), _("Cancel")); } else fl=sch_obj(i); } } while ( !fl ); werdran(0); if ( fl<2 ) schuss(i); if ( ~kn[n]&16 ) kn[n]&=~15; rechnen(); zug++; for ( i=0;i<10;i++ ) if ( ka[n][i].x>-1 ) break; n=zug&1; bg=burgen[bur[n]]; for ( a=0;a<10;a++ ) if ( ka[n][a].x>-1 ) break; if ( a==10 && i<10 && bg[40]>vo[n] && ge[n]=max_rund ) { static int h[2]; for (n=0;n<2;n++) { h[n]=ge[n]+pu[n]*p[4]/30+ku[n]*p[5]/2+(wx[n]>-1)*p[3]+vo[n]*4; for (i=0;i<5;i++) if ( ft[n][i].x>-1 ) h[n]+=p[1]; for (i=0;i<10;i++) if ( ka[n][i].x>-1 ) h[n]+=p[2]; } end=65+(h[1]65? 130-j:j)/(150-rand()%50); vo[n]=vo[n]*(95+rand()%11)/100+(21-j+rand()%9)*(8+rand()%5)/20; if ( vo[n]<0 ) { vo[n]=0; end=n+49; } for ( j=0;j<5;j++ ) ge[n]+=(40+rand()%31)*(ft[n][j].x>-1); for ( j=0;j<6;j++ ) { p[j]+=psp[j]*(rand()%99)/98-psp[j]/2; p[j]=Max(p[j],pmi[j]); p[j]=Min(p[j],pma[j]); } drw_gpk(0); } /******************************* Spielende ***********************************/ void ende(void) { char s1[80], s2[80], s3[80]; int a, b; int i; const char *loser; int with_s = 0; snprintf(s1, sizeof(s1), _("!! %s has won !!"), end&2 ? _(l_nam) : _(r_nam)); loser = (end&2) ? _(r_nam) : _(l_nam); if ((end&240) < 48) { a = loser[strlen(loser)-1]; with_s = (a=='s' || a=='S'); } switch ( end&240 ) { case 16: if (with_s) snprintf(s2, sizeof(s2), _("( %s' king was hit,"), loser); else snprintf(s2, sizeof(s2), _("( %s's king was hit,"), loser); strcpy(s3, _("and upon hearing this, the people capitulated. )")); break; case 32: if (with_s) snprintf(s2, sizeof(s2), _("( %s' king has capitulated"), loser); else snprintf(s2, sizeof(s2), _("( %s's king has capitulated"), loser); strcpy(s3, _(" because of the hopeless situation. )")); break; case 48: snprintf(s2, sizeof(s2), _("( %s has no folk left. )"), loser); s3[0]=0; break; case 64: strcpy(s2, _("( The limit of maximum rounds has been reached.")); snprintf(s3, sizeof(s3), _("%s is worse off. )"), loser); } for (a = 0; a < COMP_NUM && strncmp(cn[a], l_nam, 7); a++); for (b = 0; b < COMP_NUM && strncmp(cn[b], r_nam, 7); b++); if (a < COMP_NUM && b < COMP_NUM && a != b) { if (~end&2) { int c; c=a; a=b; b=c; } t_gew[a][b]++; t_gew[b][a]++; t_gew[b][COMP_NUM+2]++; t_gew[a][COMP_NUM+3] = 100 * ++t_gew[a][COMP_NUM+1] / ++t_gew[a][COMP_NUM]; t_gew[b][COMP_NUM+3] = 100 * t_gew[b][COMP_NUM+1] / ++t_gew[b][COMP_NUM]; } scr_color(0x00800000); for (i = 0; i < 8; i++) { short rxy[4]; if (i!=7) scr_fillcolor((i*32)<<16); else scr_fillcolor(0xffffff); rxy[0] = 40 + i*8; rxy[1] = 80 + i*8; rxy[2] = 600 - i*8; rxy[3] = 320 - i*8; v_bar(handle, rxy); } v_gtext(handle, 140, 170, s1); v_gtext(handle, 140, 210, s2); v_gtext(handle, 140, 230, s3); bt = 0; m_musik(); Giaccess( 0,138 ); Giaccess( 0,139 ); Giaccess( 0,140 ); } /** * Die Routine m_wait() wird von m_musik() nach jedem 1/96 Takt * aufgerufen. * In diesem Fall macht sie nichts anderes als die eigentliche * Warteschleife aufzurufen. In eigenen Programmen könnten Sie hier * während der Musik zusätzliche Aktionen ablaufen lassen. */ int m_wait(void) { m_wloop(); return (event(0, 0) != 0 || bt); } /** Anzeige des Spielers, der am Zug ist, sowie Darstellung der Windfahnen ***/ void werdran(char c) { char ad[8]; int i; short x, y, w, h, c1, s1, c2, s2; double wk,wl; /* Anzahl der Spielrunden ausgeben */ z_txt(zug/2+1); v_gtext(handle, 332, 395+16, txt); if ( c ) { x = 5+(629-104)*n; y = 410; w = 104; h = 48; /* Wind ausgeben: */ ad[0] = ad[5] = 4+28*!wnd-(wnd>0); i = wnd<0? -wnd:wnd; ad[1] = ad[4] = ' '; ad[2] = 48+i/10; ad[3] = 48+i%10; ad[6] = 0; if ( wx[n]<0 ) { ad[0]=ad[5]=32; ad[2]=ad[3]='?'; } v_gtext(handle, x+4, y+h+12, "Wind:"); v_gtext(handle, x+52, y+h+12, ad); c=wnd>0? 1:-1; wk=c*wnd/15.0; wl=wk*.82; if ( wk>1.57 ) wk=1.57; if ( wl>1.57 ) wl=1.57; s1=c*20*sin(wk); c1=20*cos(wk); s2=c*20*sin(wl); c2=20*cos(wl); ws=s1/2.0; ws+=!ws; wc=c1/2.0; hide(); if ( wx[n]>-1 ) { color(1); x+=w/2; line( x,y+h,x,y+5 ); line( x+1,y+h,x+1,y+5 ); xy[0]=xy[2]=x+1; xy[1]=y+5; xy[3]=y+11; if ( wk<.2 ) { xy[0]=x-1; xy[1]=xy[3]=y+5; xy[2]=x+2; } xy[4]=xy[2]+s1; xy[5]=xy[3]+c1; xy[8]=xy[0]+s1; xy[9]=xy[1]+c1; xy[10]=xy[0]; xy[11]=xy[1]; xy[6] = ((xy[4] + xy[8]) >> 1) + s2; xy[7] = ((xy[5] + xy[9]) >> 1) + c2; v_pline( handle,6,xy ); } fahne(); show(); } else { hide(); clr(5+(629-104)*n,410, 104,48+16); show(); } } /******************* Darstellung der beiden Windfahnen ***********************/ void fahne(void) { int m=-1; while ( ++m<2 ) if ( wx[m]>-1 ) { clr_bg( wx[m]-10,wy[m]-15,20,15 ); color(1); line( wx[m],wy[m],wx[m],wy[m]-15 ); if ( m==n ) { line( wx[m],wy[m]-15,wx[m]+ws,wy[m]-13+wc ); line( wx[m],wy[m]-11,wx[m]+ws,wy[m]-13+wc ); } } } /********************** BALLER.TAB laden/speichern ***************************/ int t_load(void) { #if 1 //printf("t_load does not work yet\n"); #else FILE *f_h; f_h = fopen("baller.tab", "rb"); if (!f_h) { perror("t_load"); return(1); } fread(&an_erl, 1, 1, f_h); fread(&au_kap, 1, 1, f_h); fread(&max_rund, 2, 1, f_h); fread(t_gew, 1, sizeof(t_gew), f_h); fclose(f_h); #endif return(0); } int t_save(void) { #if 1 //printf("t_save not implemented yet\n"); #else FILE *f_h; f_h = fopen("baller.tab", "wb"); if (!f_h) { perror("t_save"); return 1; } fwrite(&an_erl, 1, 1, f_h); fwrite(&au_kap, 1, 1, f_h); fwrite(&max_rund, 2, 1, f_h); fwrite(t_gew, 1, sizeof(t_gew), f_h); fclose(f_h); #endif return(0); } /************************* BALLER.DAT laden **********************************/ /* liest ein char von der Datei */ static char zeichen(FILE *f_h) { char a; if (fread(&a, 1, 1, f_h) != 1) { perror("zeichen"); exit(-1); } return a; } /* liest eine Dezimalzahl von der Datei, Remarks werden überlesen */ static int rdzahl(FILE *f_h) { char a,sign=1,rem=0; /* wird durch * getoggled, und zeigt damit an, */ /* ob man sich in einer Bemerkung befindet */ int val=0; do if ( (a=zeichen(f_h))=='*' ) rem=!rem; while ((a != '-' && a < '0') || a > '9' || rem); if ( a=='-' ) { sign=-1; a=zeichen(f_h); } while ( a>='0' && a<='9' ) { val*=10; val+=a-'0'; a=zeichen(f_h); } return( sign*val ); } void burgen_laden(void) { short *a,j; FILE *f_h; char *dat_name; dat_name = malloc(FILENAME_MAX); if (!dat_name) { perror("burgen_laden"); exit(-1); } snprintf(dat_name, FILENAME_MAX, "%s/baller.dat", Paths_GetDataDir()); f_h = fopen(dat_name, "rb"); free(dat_name); dat_name = NULL; if (!f_h) { /* Try to open in current directory instead */ f_h = fopen( "baller.dat", "rb"); if (!f_h) { perror("'baller.dat'"); exit(-1); } } a = (short *)bur_ad; b_anz = 0; while ((j=rdzahl(f_h)) != -999 && b_anz < (int)(sizeof(burgen)/sizeof(burgen[0]))) { burgen[b_anz++]=a; *a++=j; for ( j=0;j<40;j++ ) *a++=rdzahl(f_h); while ( (*a++=rdzahl(f_h))!=-1 ); } fclose(f_h); } /* Ermittelt, ob Punkt gesetzt ist */ int loc(int x, int y) { int a; a = scr_getpixel(x,y); // printf("loc %i %i = 0x%x\n", x,y, a); return ((a&0xff) != 0xff); } void line(short x1, short y1, short x2, short y2) /* Zeichnet eine Linie */ { xy[0]=x1; xy[1]=y1; xy[2]=x2; xy[3]=y2; v_pline( handle, 2, xy ); } void box(short x, short y, short x2, short y2, short c) { color(c); xy[0]=x; xy[1]=y; xy[2]=x2; xy[3]=y2; v_bar( handle,xy ); } ballerburg-1.0.1/src/sdlgui.c0000644000175000017500000006221612145514532015435 0ustar thomasthomas/* sdlgui.c This file is distributed under the GNU Public License, version 2 or at your option any later version. Read the file gpl.txt for details. A tiny graphical user interface for the SDL library. */ const char SDLGui_fileid[] = "sdlgui.c : " __DATE__ " " __TIME__; #include #include #include #include #include "i18n.h" #include "sdlgui.h" #include "baller1.h" #include "font8x16.h" int sdlgui_fontwidth; /* Width of the actual font */ int sdlgui_fontheight; /* Height of the actual font */ static SDL_Surface *pSdlGuiScrn; /* Pointer to the actual main SDL screen surface */ //static SDL_Surface *pSmallFontGfx = NULL; /* The small font graphics */ static SDL_Surface *pBigFontGfx = NULL; /* The big font graphics */ static SDL_Surface *pFontGfx = NULL; /* The actual font graphics */ static int current_object = 0; /* Current selected object */ static bool has_utf8; /** * Load an 1 plane XBM into a 8 planes SDL_Surface. */ static SDL_Surface *SDLGui_LoadXBM(int w, int h, const void *pXbmBits) { SDL_Surface *bitmap; Uint8 *dstbits; const Uint8 *srcbits; int x, y, srcpitch; int mask; srcbits = pXbmBits; /* Allocate the bitmap */ bitmap = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 8, 0, 0, 0, 0); if (bitmap == NULL) { fprintf(stderr, "Failed to allocate bitmap: %s", SDL_GetError()); return NULL; } srcpitch = ((w + 7) / 8); dstbits = (Uint8 *)bitmap->pixels; mask = 1; /* Copy the pixels */ for (y = 0 ; y < h ; y++) { for (x = 0 ; x < w ; x++) { dstbits[x] = (srcbits[x / 8] & mask) ? 1 : 0; mask <<= 1; mask |= (mask >> 8); mask &= 0xFF; } dstbits += bitmap->pitch; srcbits += srcpitch; } return bitmap; } /*-----------------------------------------------------------------------*/ /** * Initialize the GUI. */ int SDLGui_Init(void) { char *lang; SDL_Color blackWhiteColors[2] = {{255, 255, 255, 0}, {0, 0, 0, 0}}; if (/*pSmallFontGfx &&*/ pBigFontGfx) { /* already initialized */ return 0; } /* Initialize the font graphics: */ // pSmallFontGfx = SDLGui_LoadXBM(font5x8_width, font5x8_height, font5x8_bits); pBigFontGfx = SDLGui_LoadXBM(font8x16_width, font8x16_height, font8x16_bits); if (/*pSmallFontGfx == NULL ||*/ pBigFontGfx == NULL) { fprintf(stderr, "Error: Can not init font graphics!\n"); return -1; } /* Set color palette of the font graphics: */ //SDL_SetColors(pSmallFontGfx, blackWhiteColors, 0, 2); SDL_SetColors(pBigFontGfx, blackWhiteColors, 0, 2); /* Set font color 0 as transparent: */ //SDL_SetColorKey(pSmallFontGfx, (SDL_SRCCOLORKEY|SDL_RLEACCEL), 0); SDL_SetColorKey(pBigFontGfx, (SDL_SRCCOLORKEY|SDL_RLEACCEL), 0); /* Check for UTF-8 locale */ lang = getenv("LANG"); if (lang != NULL) { has_utf8 = (strstr(lang, "utf-8") != NULL) || (strstr(lang, "UTF-8") != NULL) || (strstr(lang, "utf8") != NULL) || (strstr(lang, "UTF8") != NULL); } else { has_utf8 = false; } return 0; } /*-----------------------------------------------------------------------*/ /** * Uninitialize the GUI. */ int SDLGui_UnInit(void) { /* if (pSmallFontGfx) { SDL_FreeSurface(pSmallFontGfx); pSmallFontGfx = NULL; } */ if (pBigFontGfx) { SDL_FreeSurface(pBigFontGfx); pBigFontGfx = NULL; } return 0; } /*-----------------------------------------------------------------------*/ /** * Inform the SDL-GUI about the actual SDL_Surface screen pointer and * prepare the font to suit the actual resolution. */ int SDLGui_SetScreen(SDL_Surface *pScrn) { pSdlGuiScrn = pScrn; /* Decide which font to use - small or big one: */ // if (pSdlGuiScrn->w >= 640 && pSdlGuiScrn->h >= 400 && pBigFontGfx != NULL) { pFontGfx = pBigFontGfx; } /* else { pFontGfx = pSmallFontGfx; } */ if (pFontGfx == NULL) { fprintf(stderr, "Error: A problem with the font occured!\n"); return -1; } /* Get the font width and height: */ sdlgui_fontwidth = pFontGfx->w/16; sdlgui_fontheight = pFontGfx->h/16; return 0; } /*-----------------------------------------------------------------------*/ /** * Return character size for current font in given arguments. */ void SDLGui_GetFontSize(int *width, int *height) { *width = sdlgui_fontwidth; *height = sdlgui_fontheight; } /*-----------------------------------------------------------------------*/ /** * Center a dialog so that it appears in the middle of the screen. * Note: We only store the coordinates in the root box of the dialog, * all other objects in the dialog are positioned relatively to this one. */ void SDLGui_CenterDlg(SGOBJ *dlg) { dlg[0].x = (pSdlGuiScrn->w/sdlgui_fontwidth-dlg[0].w)/2; dlg[0].y = (pSdlGuiScrn->h/sdlgui_fontheight-dlg[0].h)/2; } /** * Convert UTF-8 character to our internal Latin1 representation and * increase the string index. */ static char SDLGui_Utf8ToLatin1(const char *txt, int *i) { unsigned char c; c = txt[*i]; *i += 1; if (c < 0x80 || !has_utf8) { return c; } /* Quick and dirty convertion for latin1 characters only... */ if ((c & 0xc0) == 0xc0) { c = c << 6; c |= (txt[*i] & 0x7f); *i += 1; } else { printf("Unsupported character '%c' (0x%x)\n", c, c); } return c; } /** * Draw a text string. */ void SDLGui_Text(int x, int y, const char *txt) { int i, p; unsigned char c; SDL_Rect sr, dr; sr.w = dr.w = sdlgui_fontwidth; sr.h = dr.h = sdlgui_fontheight; i = p = 0; while (txt[i] != 0) { c = SDLGui_Utf8ToLatin1(txt, &i); sr.x = sdlgui_fontwidth * (c % 16); sr.y = sdlgui_fontheight * (c / 16); dr.x = x + p * sdlgui_fontwidth; dr.y = y; SDL_BlitSurface(pFontGfx, &sr, pSdlGuiScrn, &dr); p += 1; } } /*-----------------------------------------------------------------------*/ /** * Draw a dialog text object. */ static void SDLGui_DrawText(const SGOBJ *tdlg, int objnum) { int x, y; x = (tdlg[0].x+tdlg[objnum].x)*sdlgui_fontwidth; y = (tdlg[0].y+tdlg[objnum].y)*sdlgui_fontheight; SDLGui_Text(x, y, _(tdlg[objnum].txt)); } /*-----------------------------------------------------------------------*/ /** * Draw a edit field object. */ static void SDLGui_DrawEditField(const SGOBJ *edlg, int objnum) { int x, y; SDL_Rect rect; x = (edlg[0].x+edlg[objnum].x)*sdlgui_fontwidth; y = (edlg[0].y+edlg[objnum].y)*sdlgui_fontheight; SDLGui_Text(x, y, edlg[objnum].txt); rect.x = x; rect.y = y + edlg[objnum].h * sdlgui_fontheight; rect.w = edlg[objnum].w * sdlgui_fontwidth; rect.h = 1; SDL_FillRect(pSdlGuiScrn, &rect, SDL_MapRGB(pSdlGuiScrn->format,160,160,160)); } /*-----------------------------------------------------------------------*/ /** * Draw a dialog box object. */ static void SDLGui_DrawBox(const SGOBJ *bdlg, int objnum) { SDL_Rect rect; int x, y, w, h, offset; Uint32 grey = SDL_MapRGB(pSdlGuiScrn->format,192,192,192); Uint32 upleftc, downrightc; x = bdlg[objnum].x*sdlgui_fontwidth; y = bdlg[objnum].y*sdlgui_fontheight; if (objnum > 0) /* Since the root object is a box, too, */ { /* we have to look for it now here and only */ x += bdlg[0].x*sdlgui_fontwidth; /* add its absolute coordinates if we need to */ y += bdlg[0].y*sdlgui_fontheight; } w = bdlg[objnum].w*sdlgui_fontwidth; h = bdlg[objnum].h*sdlgui_fontheight; if (bdlg[objnum].state & SG_SELECTED) { upleftc = SDL_MapRGB(pSdlGuiScrn->format,128,128,128); downrightc = SDL_MapRGB(pSdlGuiScrn->format,255,255,255); } else { upleftc = SDL_MapRGB(pSdlGuiScrn->format,255,255,255); downrightc = SDL_MapRGB(pSdlGuiScrn->format,128,128,128); } /* The root box should be bigger than the screen, so we disable the offset there: */ if (objnum != 0) offset = 1; else offset = 0; /* Draw background: */ rect.x = x; rect.y = y; rect.w = w; rect.h = h; SDL_FillRect(pSdlGuiScrn, &rect, grey); /* Draw upper border: */ rect.x = x; rect.y = y - offset; rect.w = w; rect.h = 1; SDL_FillRect(pSdlGuiScrn, &rect, upleftc); /* Draw left border: */ rect.x = x - offset; rect.y = y; rect.w = 1; rect.h = h; SDL_FillRect(pSdlGuiScrn, &rect, upleftc); /* Draw bottom border: */ rect.x = x; rect.y = y + h - 1 + offset; rect.w = w; rect.h = 1; SDL_FillRect(pSdlGuiScrn, &rect, downrightc); /* Draw right border: */ rect.x = x + w - 1 + offset; rect.y = y; rect.w = 1; rect.h = h; SDL_FillRect(pSdlGuiScrn, &rect, downrightc); } /*-----------------------------------------------------------------------*/ /** * Draw a normal button. */ void SDLGui_DrawButton(const SGOBJ *bdlg, int objnum) { int x,y; char *txt = _(bdlg[objnum].txt); SDLGui_DrawBox(bdlg, objnum); x = (bdlg[0].x + bdlg[objnum].x) * sdlgui_fontwidth + (bdlg[objnum].w - strlen(txt)) * sdlgui_fontwidth / 2; y = (bdlg[0].y + bdlg[objnum].y + (bdlg[objnum].h-1)/2) * sdlgui_fontheight; if (bdlg[objnum].state & SG_SELECTED) { x+=1; y+=1; } SDLGui_Text(x, y, txt); } /*-----------------------------------------------------------------------*/ /** * Draw a dialog radio button object. */ static void SDLGui_DrawRadioButton(const SGOBJ *rdlg, int objnum) { char str[80]; int x, y; x = (rdlg[0].x + rdlg[objnum].x) * sdlgui_fontwidth; y = (rdlg[0].y + rdlg[objnum].y) * sdlgui_fontheight; if (rdlg[objnum].state & SG_SELECTED) str[0]=SGRADIOBUTTON_SELECTED; else str[0]=SGRADIOBUTTON_NORMAL; str[1]=' '; strcpy(&str[2], _(rdlg[objnum].txt)); SDLGui_Text(x, y, str); } /*-----------------------------------------------------------------------*/ /** * Draw a dialog check box object. */ static void SDLGui_DrawCheckBox(const SGOBJ *cdlg, int objnum) { char str[80]; int x, y; x = (cdlg[0].x + cdlg[objnum].x) * sdlgui_fontwidth; y = (cdlg[0].y + cdlg[objnum].y) * sdlgui_fontheight; if ( cdlg[objnum].state&SG_SELECTED ) str[0]=SGCHECKBOX_SELECTED; else str[0]=SGCHECKBOX_NORMAL; str[1]=' '; strcpy(&str[2], _(cdlg[objnum].txt)); SDLGui_Text(x, y, str); } /*-----------------------------------------------------------------------*/ /** * Draw a scrollbar button. */ static void SDLGui_DrawScrollbar(const SGOBJ *bdlg, int objnum) { SDL_Rect rect; int x, y, w, h; Uint32 grey0 = SDL_MapRGB(pSdlGuiScrn->format,128,128,128); Uint32 grey1 = SDL_MapRGB(pSdlGuiScrn->format,196,196,196); Uint32 grey2 = SDL_MapRGB(pSdlGuiScrn->format, 64, 64, 64); x = bdlg[objnum].x * sdlgui_fontwidth; y = bdlg[objnum].y * sdlgui_fontheight + bdlg[objnum].h; x += bdlg[0].x*sdlgui_fontwidth; /* add mainbox absolute coordinates */ y += bdlg[0].y*sdlgui_fontheight; /* add mainbox absolute coordinates */ w = 1 * sdlgui_fontwidth; h = bdlg[objnum].w; /* Draw background: */ rect.x = x; rect.y = y; rect.w = w; rect.h = h; SDL_FillRect(pSdlGuiScrn, &rect, grey0); /* Draw upper border: */ rect.x = x; rect.y = y; rect.w = w; rect.h = 1; SDL_FillRect(pSdlGuiScrn, &rect, grey1); /* Draw bottom border: */ rect.x = x; rect.y = y + h - 1; rect.w = w; rect.h = 1; SDL_FillRect(pSdlGuiScrn, &rect, grey2); } /*-----------------------------------------------------------------------*/ /** * Draw a dialog popup button object. */ static void SDLGui_DrawPopupButton(const SGOBJ *pdlg, int objnum) { int x, y, w; const char *downstr = "\x02"; SDLGui_DrawBox(pdlg, objnum); x = (pdlg[0].x + pdlg[objnum].x) * sdlgui_fontwidth; y = (pdlg[0].y + pdlg[objnum].y) * sdlgui_fontheight; w = pdlg[objnum].w*sdlgui_fontwidth; //h = pdlg[objnum].h*sdlgui_fontheight; SDLGui_Text(x, y, pdlg[objnum].txt); SDLGui_Text(x+w-sdlgui_fontwidth, y, downstr); } /*-----------------------------------------------------------------------*/ /** * Let the user insert text into an edit field object. * NOTE: The dlg[objnum].txt must point to an an array that is big enough * for dlg[objnum].w characters! */ static void SDLGui_EditField(SGOBJ *dlg, int objnum) { size_t cursorPos; /* Position of the cursor in the edit field */ int blinkState = 0; /* Used for cursor blinking */ int bStopEditing = false; /* true if user wants to exit the edit field */ char *txt; /* Shortcut for dlg[objnum].txt */ SDL_Rect rect; Uint32 grey, cursorCol; SDL_Event event; int nOldUnicodeMode; /* Enable unicode translation to get proper characters with SDL_PollEvent */ nOldUnicodeMode = SDL_EnableUNICODE(true); grey = SDL_MapRGB(pSdlGuiScrn->format, 192, 192, 192); cursorCol = SDL_MapRGB(pSdlGuiScrn->format, 128, 128, 128); rect.x = (dlg[0].x + dlg[objnum].x) * sdlgui_fontwidth; rect.y = (dlg[0].y + dlg[objnum].y) * sdlgui_fontheight; rect.w = (dlg[objnum].w + 1) * sdlgui_fontwidth - 1; rect.h = dlg[objnum].h * sdlgui_fontheight; txt = dlg[objnum].txt; cursorPos = strlen(txt); do { /* Look for events */ if (SDL_PollEvent(&event) == 0) { /* No event: Wait some time for cursor blinking */ SDL_Delay(250); blinkState ^= 1; } else { /* Handle events */ do { switch (event.type) { case SDL_QUIT: /* User wants to quit */ // bQuitProgram = true; bStopEditing = true; break; case SDL_MOUSEBUTTONDOWN: /* Mouse pressed -> stop editing */ bStopEditing = true; break; case SDL_KEYDOWN: /* Key pressed */ switch (event.key.keysym.sym) { case SDLK_RETURN: case SDLK_KP_ENTER: bStopEditing = true; break; case SDLK_LEFT: if (cursorPos > 0) cursorPos -= 1; break; case SDLK_RIGHT: if (cursorPos < strlen(txt)) cursorPos += 1; break; case SDLK_BACKSPACE: if (cursorPos > 0) { memmove(&txt[cursorPos-1], &txt[cursorPos], strlen(&txt[cursorPos])+1); cursorPos -= 1; } break; case SDLK_DELETE: if (cursorPos < strlen(txt)) memmove(&txt[cursorPos], &txt[cursorPos+1], strlen(&txt[cursorPos+1])+1); break; default: /* If it is a "good" key then insert it into the text field */ if (event.key.keysym.unicode >= 32 && event.key.keysym.unicode < 128 /* && event.key.keysym.unicode != PATHSEP*/) { if (strlen(txt) < (size_t)dlg[objnum].w) { memmove(&txt[cursorPos+1], &txt[cursorPos], strlen(&txt[cursorPos])+1); txt[cursorPos] = event.key.keysym.unicode; cursorPos += 1; } } break; } break; } } while (SDL_PollEvent(&event)); blinkState = 1; } /* Redraw the text field: */ SDL_FillRect(pSdlGuiScrn, &rect, grey); /* Draw background */ /* Draw the cursor: */ if (blinkState && !bStopEditing) { SDL_Rect cursorrect; cursorrect.x = rect.x + cursorPos * sdlgui_fontwidth; cursorrect.y = rect.y; cursorrect.w = sdlgui_fontwidth; cursorrect.h = rect.h; SDL_FillRect(pSdlGuiScrn, &cursorrect, cursorCol); } SDLGui_Text(rect.x, rect.y, dlg[objnum].txt); /* Draw text */ SDL_UpdateRects(pSdlGuiScrn, 1, &rect); } while (!bStopEditing); SDL_EnableUNICODE(nOldUnicodeMode); } /** * Draw a user object. */ static void SDLGui_DrawUserObj(const SGOBJ *bdlg, int objnum) { int x, y, w, h; char (*userfun)(int x, int y, int w, int h); x = bdlg[objnum].x*sdlgui_fontwidth; y = bdlg[objnum].y*sdlgui_fontheight; /* add absolute coordinates */ x += bdlg[0].x*sdlgui_fontwidth; y += bdlg[0].y*sdlgui_fontheight; w = bdlg[objnum].w*sdlgui_fontwidth; h = bdlg[objnum].h*sdlgui_fontheight; userfun = (void*)bdlg[objnum].txt; userfun(x, y, w, h); } /*-----------------------------------------------------------------------*/ /** * Draw a whole dialog. */ void SDLGui_DrawDialog(const SGOBJ *dlg) { int i; for (i = 0; dlg[i].type != -1; i++) { switch (dlg[i].type) { case SGBOX: SDLGui_DrawBox(dlg, i); break; case SGTEXT: SDLGui_DrawText(dlg, i); break; case SGEDITFIELD: SDLGui_DrawEditField(dlg, i); break; case SGBUTTON: SDLGui_DrawButton(dlg, i); break; case SGRADIOBUT: SDLGui_DrawRadioButton(dlg, i); break; case SGCHECKBOX: SDLGui_DrawCheckBox(dlg, i); break; case SGPOPUP: SDLGui_DrawPopupButton(dlg, i); break; case SGSCROLLBAR: SDLGui_DrawScrollbar(dlg, i); break; case SGUSER: SDLGui_DrawUserObj(dlg, i); break; } } SDL_UpdateRect(pSdlGuiScrn, 0,0,0,0); } /*-----------------------------------------------------------------------*/ /** * Search an object at a certain position. */ static int SDLGui_FindObj(const SGOBJ *dlg, int fx, int fy) { int len, i; int ob = -1; int xpos, ypos; len = 0; while (dlg[len].type != -1) len++; xpos = fx / sdlgui_fontwidth; ypos = fy / sdlgui_fontheight; /* Now search for the object: */ for (i = len; i >= 0; i--) { /* clicked on a scrollbar ? */ if (dlg[i].type == SGSCROLLBAR) { if (xpos >= dlg[0].x+dlg[i].x && xpos < dlg[0].x+dlg[i].x+1) { ypos = dlg[i].y * sdlgui_fontheight + dlg[i].h + dlg[0].y * sdlgui_fontheight; if (fy >= ypos && fy < ypos + dlg[i].w) { ob = i; break; } } } /* clicked on another object ? */ else if (xpos >= dlg[0].x+dlg[i].x && ypos >= dlg[0].y+dlg[i].y && xpos < dlg[0].x+dlg[i].x+dlg[i].w && ypos < dlg[0].y+dlg[i].y+dlg[i].h) { ob = i; break; } } return ob; } /*-----------------------------------------------------------------------*/ /** * Search a button with a special flag (e.g. SG_DEFAULT or SG_CANCEL). */ static int SDLGui_SearchFlaggedButton(const SGOBJ *dlg, int flag) { int i = 0; while (dlg[i].type != -1) { if (dlg[i].flags & flag) return i; i++; } return 0; } /*-----------------------------------------------------------------------*/ /** * Show and process a dialog. Returns the button number that has been * pressed or SDLGUI_UNKNOWNEVENT if an unsupported event occured (will be * stored in parameter pEventOut). */ int SDLGui_DoDialog(SGOBJ *dlg, SDL_Event *pEventOut) { int obj=0; int oldbutton=0; int retbutton=0; int i, j, b; SDL_Event sdlEvent; SDL_Rect rct; Uint32 grey; SDL_Surface *pBgSurface; SDL_Rect dlgrect, bgrect; if (pSdlGuiScrn->h / sdlgui_fontheight < dlg[0].h) { fprintf(stderr, "Screen size too small for dialog!\n"); return SDLGUI_ERROR; } grey = SDL_MapRGB(pSdlGuiScrn->format,192,192,192); dlgrect.x = dlg[0].x * sdlgui_fontwidth; dlgrect.y = dlg[0].y * sdlgui_fontheight; dlgrect.w = dlg[0].w * sdlgui_fontwidth; dlgrect.h = dlg[0].h * sdlgui_fontheight; bgrect.x = bgrect.y = 0; bgrect.w = dlgrect.w; bgrect.h = dlgrect.h; /* Save background */ pBgSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, dlgrect.w, dlgrect.h, pSdlGuiScrn->format->BitsPerPixel, pSdlGuiScrn->format->Rmask, pSdlGuiScrn->format->Gmask, pSdlGuiScrn->format->Bmask, pSdlGuiScrn->format->Amask); if (pSdlGuiScrn->format->palette != NULL) { SDL_SetColors(pBgSurface, pSdlGuiScrn->format->palette->colors, 0, pSdlGuiScrn->format->palette->ncolors-1); } if (pBgSurface != NULL) { SDL_BlitSurface(pSdlGuiScrn, &dlgrect, pBgSurface, &bgrect); } else { fprintf(stderr, "SDLGUI_DoDialog: CreateRGBSurface failed: %s\n", SDL_GetError()); } /* (Re-)draw the dialog */ SDLGui_DrawDialog(dlg); /* Is the left mouse button still pressed? Yes -> Handle TOUCHEXIT objects here */ SDL_PumpEvents(); b = SDL_GetMouseState(&i, &j); /* If current object is the scrollbar, and mouse is still down, we can scroll it */ /* also if the mouse pointer has left the scrollbar */ if (dlg[current_object].type == SGSCROLLBAR) { if (b & SDL_BUTTON(1)) { obj = current_object; dlg[obj].state |= SG_MOUSEDOWN; oldbutton = obj; retbutton = obj; } else { obj = current_object; current_object = 0; dlg[obj].state &= SG_MOUSEUP; retbutton = obj; oldbutton = obj; } } else { obj = SDLGui_FindObj(dlg, i, j); current_object = obj; if (obj > 0 && (dlg[obj].flags&SG_TOUCHEXIT) ) { oldbutton = obj; if (b & SDL_BUTTON(1)) { dlg[obj].state |= SG_SELECTED; retbutton = obj; } } } /* The main loop */ while (retbutton == 0 /*&& !bQuitProgram*/) { if (SDL_WaitEvent(&sdlEvent) == 1) /* Wait for events */ switch (sdlEvent.type) { case SDL_QUIT: retbutton = SDLGUI_QUIT; break; case SDL_MOUSEBUTTONDOWN: if (sdlEvent.button.button != SDL_BUTTON_LEFT) { /* Not left mouse button -> unsupported event */ if (pEventOut) retbutton = SDLGUI_UNKNOWNEVENT; break; } /* It was the left button: Find the object under the mouse cursor */ obj = SDLGui_FindObj(dlg, sdlEvent.button.x, sdlEvent.button.y); if (obj>0) { if (dlg[obj].type==SGBUTTON) { dlg[obj].state |= SG_SELECTED; SDLGui_DrawButton(dlg, obj); SDL_UpdateRect(pSdlGuiScrn, (dlg[0].x+dlg[obj].x)*sdlgui_fontwidth-2, (dlg[0].y+dlg[obj].y)*sdlgui_fontheight-2, dlg[obj].w*sdlgui_fontwidth+4, dlg[obj].h*sdlgui_fontheight+4); oldbutton=obj; } if (dlg[obj].type==SGSCROLLBAR) { dlg[obj].state |= SG_MOUSEDOWN; oldbutton=obj; } if ( dlg[obj].flags&SG_TOUCHEXIT ) { dlg[obj].state |= SG_SELECTED; retbutton = obj; } } break; case SDL_MOUSEBUTTONUP: if (sdlEvent.button.button != SDL_BUTTON_LEFT) { /* Not left mouse button -> unsupported event */ if (pEventOut) retbutton = SDLGUI_UNKNOWNEVENT; break; } /* It was the left button: Find the object under the mouse cursor */ obj = SDLGui_FindObj(dlg, sdlEvent.button.x, sdlEvent.button.y); if (obj>0) { switch (dlg[obj].type) { case SGBUTTON: if (oldbutton==obj) retbutton=obj; break; case SGSCROLLBAR: dlg[obj].state &= SG_MOUSEUP; if (oldbutton==obj) retbutton=obj; break; case SGEDITFIELD: SDLGui_EditField(dlg, obj); break; case SGRADIOBUT: for (i = obj-1; i > 0 && dlg[i].type == SGRADIOBUT; i--) { dlg[i].state &= ~SG_SELECTED; /* Deselect all radio buttons in this group */ rct.x = (dlg[0].x+dlg[i].x)*sdlgui_fontwidth; rct.y = (dlg[0].y+dlg[i].y)*sdlgui_fontheight; rct.w = sdlgui_fontwidth; rct.h = sdlgui_fontheight; SDL_FillRect(pSdlGuiScrn, &rct, grey); /* Clear old */ SDLGui_DrawRadioButton(dlg, i); SDL_UpdateRects(pSdlGuiScrn, 1, &rct); } for (i = obj+1; dlg[i].type == SGRADIOBUT; i++) { dlg[i].state &= ~SG_SELECTED; /* Deselect all radio buttons in this group */ rct.x = (dlg[0].x+dlg[i].x)*sdlgui_fontwidth; rct.y = (dlg[0].y+dlg[i].y)*sdlgui_fontheight; rct.w = sdlgui_fontwidth; rct.h = sdlgui_fontheight; SDL_FillRect(pSdlGuiScrn, &rct, grey); /* Clear old */ SDLGui_DrawRadioButton(dlg, i); SDL_UpdateRects(pSdlGuiScrn, 1, &rct); } dlg[obj].state |= SG_SELECTED; /* Select this radio button */ rct.x = (dlg[0].x+dlg[obj].x)*sdlgui_fontwidth; rct.y = (dlg[0].y+dlg[obj].y)*sdlgui_fontheight; rct.w = sdlgui_fontwidth; rct.h = sdlgui_fontheight; SDL_FillRect(pSdlGuiScrn, &rct, grey); /* Clear old */ SDLGui_DrawRadioButton(dlg, obj); SDL_UpdateRects(pSdlGuiScrn, 1, &rct); break; case SGCHECKBOX: dlg[obj].state ^= SG_SELECTED; rct.x = (dlg[0].x+dlg[obj].x)*sdlgui_fontwidth; rct.y = (dlg[0].y+dlg[obj].y)*sdlgui_fontheight; rct.w = sdlgui_fontwidth; rct.h = sdlgui_fontheight; SDL_FillRect(pSdlGuiScrn, &rct, grey); /* Clear old */ SDLGui_DrawCheckBox(dlg, obj); SDL_UpdateRects(pSdlGuiScrn, 1, &rct); break; case SGPOPUP: dlg[obj].state |= SG_SELECTED; SDLGui_DrawPopupButton(dlg, obj); SDL_UpdateRect(pSdlGuiScrn, (dlg[0].x+dlg[obj].x)*sdlgui_fontwidth-2, (dlg[0].y+dlg[obj].y)*sdlgui_fontheight-2, dlg[obj].w*sdlgui_fontwidth+4, dlg[obj].h*sdlgui_fontheight+4); retbutton=obj; break; } } if (oldbutton > 0 && dlg[oldbutton].type == SGBUTTON) { dlg[oldbutton].state &= ~SG_SELECTED; SDLGui_DrawButton(dlg, oldbutton); SDL_UpdateRect(pSdlGuiScrn, (dlg[0].x+dlg[oldbutton].x)*sdlgui_fontwidth-2, (dlg[0].y+dlg[oldbutton].y)*sdlgui_fontheight-2, dlg[oldbutton].w*sdlgui_fontwidth+4, dlg[oldbutton].h*sdlgui_fontheight+4); oldbutton = 0; } if (obj >= 0 && (dlg[obj].flags&SG_EXIT)) { retbutton = obj; } break; case SDL_JOYAXISMOTION: case SDL_JOYBALLMOTION: case SDL_JOYHATMOTION: case SDL_MOUSEMOTION: break; case SDL_KEYDOWN: /* Key pressed */ if (sdlEvent.key.keysym.sym == SDLK_RETURN || sdlEvent.key.keysym.sym == SDLK_KP_ENTER) { retbutton = SDLGui_SearchFlaggedButton(dlg, SG_DEFAULT); } else if (sdlEvent.key.keysym.sym == SDLK_ESCAPE) { retbutton = SDLGui_SearchFlaggedButton(dlg, SG_CANCEL); } else if (pEventOut) { retbutton = SDLGUI_UNKNOWNEVENT; } break; default: if (pEventOut) retbutton = SDLGUI_UNKNOWNEVENT; break; } } /* Restore background */ if (pBgSurface) { SDL_BlitSurface(pBgSurface, &bgrect, pSdlGuiScrn, &dlgrect); SDL_FreeSurface(pBgSurface); } /* Copy event data of unsupported events if caller wants to have it */ if (retbutton == SDLGUI_UNKNOWNEVENT && pEventOut) memcpy(pEventOut, &sdlEvent, sizeof(SDL_Event)); //if (retbutton == SDLGUI_QUIT) // bQuitProgram = true; bt = 0; // FIXME: Hack return retbutton; } ballerburg-1.0.1/src/psg.c0000644000175000017500000002241612145514531014734 0ustar thomasthomas/* * libpsg - a simple YM-2149 soundchip emulation library. * * Copyright (C) 2000 Stefan Berndtsson (NoCrew) * Copyright (C) 2011 Thomas Huth * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #include #include #include #include #include #include "psg.h" psg psg_struct; //#define FIXED_MATH 1 #ifdef FIXED_MATH # define FIXED_TYPE int # define FIXED(x) ((int)((x) * 256)) # define DIV(x, y) ((((x) + ((y) >> 1)) << 8) / (y)) # define MOD(x, y) ((x) % (y)) # define FIXED_TO_INT(x) (((x) + 128) >> 8) #else # define FIXED_TYPE double # define FIXED(x) x # define DIV(x, y) ((x) / (y)) # define MOD(x, y) fmod (x, y) # define FIXED_TO_INT(x) (x) #endif #define INLINE static __inline__ #define TYPE_SQUARE 0 #if 0 /* undefined at the moment */ # define TYPE_SINUS 1 # define TYPE_PSGSQR 2 #endif #define MFP_FREQUENCY 2457600 #define PSG_FREQUENCY 2000000 #define QUALITY (1<<14) #define SAMPLE_TYPE TYPE_SQUARE #define SAMPLE_MAX 0x7fff #define SAMPLE_MIN 0x8000 #define NOISE_MAX 0xffff struct frame { int wave_period[3]; int rfreq[3]; int rvol[3]; int tone[3]; int noise[3]; int env[3]; int env_mode; int env_period; double env_freq; int sample_freq; }; #define ONE FIXED (1) #define PI FIXED (M_PI) INLINE FIXED_TYPE env_wave_00XX(FIXED_TYPE in) { if(in < PI) return ONE - DIV (in, PI); else return 0; } INLINE FIXED_TYPE env_wave_01XX(FIXED_TYPE in) { if(in < PI) return DIV (in, PI); else return 0; } INLINE FIXED_TYPE env_wave_1000(FIXED_TYPE in) { return ONE - DIV (MOD (in, PI), PI); } INLINE FIXED_TYPE env_wave_1001(FIXED_TYPE in) { if(in < PI) return ONE - DIV (in, PI); else return 0; } INLINE FIXED_TYPE env_wave_1010(FIXED_TYPE in) { FIXED_TYPE tmp; tmp = MOD (in, PI*2); if(tmp < PI) return ONE - DIV (tmp, PI); else return DIV (tmp - PI, PI); } INLINE FIXED_TYPE env_wave_1011(FIXED_TYPE in) { if(in < PI) return ONE - DIV (in, PI); else return ONE; } INLINE FIXED_TYPE env_wave_1100(FIXED_TYPE in) { return DIV (MOD (in, PI), PI); } INLINE FIXED_TYPE env_wave_1101(FIXED_TYPE in) { if(in < PI) return DIV (in, PI); else return ONE; } INLINE FIXED_TYPE env_wave_1110(FIXED_TYPE in) { FIXED_TYPE tmp; tmp = MOD (in, PI*2); if(tmp < PI) return DIV (tmp, PI); else return ONE - DIV (tmp - PI, PI); } INLINE FIXED_TYPE env_wave_1111(FIXED_TYPE in) { if(in < PI) return DIV (in, PI); else return ONE; } static FIXED_TYPE env_wave(FIXED_TYPE in, int mode) { switch(mode) { case 0: case 1: case 2: case 3: return env_wave_00XX(in); break; case 4: case 5: case 6: case 7: return env_wave_01XX(in); break; case 8: return env_wave_1000(in); break; case 9: return env_wave_1001(in); break; case 10: return env_wave_1010(in); break; case 11: return env_wave_1011(in); break; case 12: return env_wave_1100(in); break; case 13: return env_wave_1101(in); break; case 14: return env_wave_1110(in); break; case 15: return env_wave_1111(in); break; } return 0; } /* Period counter for seamless frames */ struct frame tdata; /* Values stolen from STonX */ static int amps[16]= {0,1,1,2,3,4,5,7,12,20,28,44,70,110,165,255}; static int16_t _clip(int input) { if(input < -32768) return (int16_t)-32768; if(input > 32767) return (int16_t) 32767; return input; } psg *psg_init(int mode, int bits, int freq) { int i; if((bits != 16)) { fprintf(stderr, "Unsupported bitvalue\n"); return (psg *)NULL; } if((mode < 0) || (mode > 1)) { fprintf(stderr, "Unsupported mode\n"); return (psg *)NULL; } if(freq != 44100 && freq != 22050) { fprintf(stderr, "Unsupported frequency\n"); return (psg *)NULL; } psg_struct.output.mode = mode; psg_struct.output.bits = bits; psg_struct.output.freq = freq; tdata.sample_freq = freq; for(i=0; i<3; i++) { tdata.wave_period[i] = 0; } return &psg_struct; } static int16_t _get_one_tonesample(int offset) { if((offset&(QUALITY-1)) < (QUALITY/2)) return SAMPLE_MAX; else return SAMPLE_MIN; } static int16_t _get_one_noisesample(int offset) { return (NOISE_MAX&rand())-SAMPLE_MAX; } static int _get_real_freq(int psgfreq, int sample_freq) { int denominator; if(psgfreq) { denominator = sample_freq * psgfreq; return (QUALITY *(PSG_FREQUENCY/16.0) + (denominator >> 1)) / denominator; } else return 0; } static void psg_update_values(psg *psg) { int i, tmp; for(i=0; i<3; i++) { if(psg->regs[8+i] == 16) { tdata.rvol[i] = 0; tdata.env[i] = 1; if(psg->regs[13] != 0xff) { //tdata.env_period = 0; tdata.env_mode = psg->regs[13]; } } else { tdata.rvol[i] = psg->regs[8+i]; tdata.env[i] = 0; } tmp = psg->regs[11] + (psg->regs[12] << 8); if(tmp) tdata.env_freq = ((double)PSG_FREQUENCY/(256.0 * tmp)); else tdata.env_freq = 0; tdata.rfreq[i] = _get_real_freq((psg->regs[1+i*2]<<8) + psg->regs[0+i*2], psg->output.freq); tdata.tone[i] = !(psg->regs[7] & (1<regs[7] & (8<>8))); } else { tmp = _clip(tmp + ((_get_one_tonesample(tdata.wave_period[i])* amps[tdata.rvol[i]])>>8)); } tdata.wave_period[i] += tdata.rfreq[i]; } if(tdata.noise[i] && !tdata.tone[i]) { if(tdata.env[i]) { tmp = _clip(tmp + ((_get_one_noisesample(tdata.wave_period[i])* amps[(int) (15*env_wave(tdata.env_period*M_PI*2/QUALITY, tdata.env_mode))]>>8))); } else { tmp = _clip(tmp + ((_get_one_noisesample(tdata.wave_period[i])* amps[tdata.rvol[i]])>>8)); } // tdata.wave_period[i] += tdata.rfreq[i]; } if(tdata.noise[i] && tdata.tone[i]) { if(tdata.env[i]) { tmp = _clip(tmp + ((_clip(_get_one_tonesample(tdata.wave_period[i])+ _get_one_noisesample(tdata.wave_period[i]))* amps[(int) (15*env_wave(tdata.env_period*M_PI*2/QUALITY, tdata.env_mode))]>>8))); } else { tmp = _clip(tmp + (_clip(_get_one_tonesample(tdata.wave_period[i])+ _get_one_noisesample(tdata.wave_period[i]))* amps[tdata.rvol[i]]>>8)); } tdata.wave_period[i] += tdata.rfreq[i]; } } if(tdata.env_freq) tdata.env_period += 2*(QUALITY/(tdata.sample_freq * tdata.env_freq)); return tmp; } int psg_create_samples(void *buffer, psg *psg, int samples) { int16_t *tmp; int i, tval; tmp = (int16_t *) buffer; for(i=0; ioutput.mode) *tmp++ = tval; } return 0; } /** * SDL audio callback function - copy emulation sound to audio system. */ static void Audio_CallBack(void *userdata, Uint8 *stream, int len) { psg_create_samples(stream, &psg_struct, len/4); } unsigned int Giaccess(unsigned int data, unsigned int reg) { if (reg & 0x80) { psg_struct.regs[reg&0x0f] = data; psg_update_values(&psg_struct); if ((reg&0x0f) == 13) tdata.env_period = 0; return 0; } else { return psg_struct.regs[reg&0x0f]; } } void Dosound(const unsigned char *buf) { int i = 0; while (buf[i] != 0xff) { if (buf[i] >= 16) { printf("Dosound: Unsupported opcode 0x%02x\n", buf[i]); } else { psg_struct.regs[buf[i]] = buf[i+1]; if (buf[i] == 13) tdata.env_period = 0; } i += 2; } psg_update_values(&psg_struct); } /** * Initialize the audio subsystem. Return true if all OK. */ void psg_audio_init(void) { SDL_AudioSpec desiredAudioSpec; /* We fill in the desired SDL audio options here */ /* Init the SDL's audio subsystem: */ if (SDL_WasInit(SDL_INIT_AUDIO) == 0) { if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) { fprintf(stderr, "Could not init audio: %s\n", SDL_GetError() ); return; } } psg_init(1, 16, 44100); /* Set up SDL audio: */ desiredAudioSpec.freq = 22050; desiredAudioSpec.format = AUDIO_S16SYS; /* 16-Bit signed */ desiredAudioSpec.channels = 2; /* stereo */ desiredAudioSpec.callback = Audio_CallBack; desiredAudioSpec.userdata = NULL; desiredAudioSpec.samples = 512; /* buffer size in samples */ if (SDL_OpenAudio(&desiredAudioSpec, NULL)) /* Open audio device */ { fprintf(stderr, "Can't use audio: %s\n", SDL_GetError()); SDL_QuitSubSystem(SDL_INIT_AUDIO); return; } SDL_PauseAudio(0); } ballerburg-1.0.1/src/baller2.h0000644000175000017500000000232312145514531015466 0ustar thomasthomas/* baller2.h - prototypes and definitions for baller2.c Copyright (C) 2010 Thomas Huth This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ int comp(void); void z_kn(void); void z_ka(void); void z_ft(void); void z_ge(void); void z_pk(void); void schuss(int k); void expls(int x, int y, int w, int h, int d); int kugel(int x, int y); void baller(unsigned char r); void bild(void); void burg(int nn); void init_ka(int k, int xr); void drw_all(void); void drw_gpk(char w); void draw(short x, short y, short *a); void fturm(void); void koenig(void); int drin(short xk, short yk, short w, short h, short r, short x, short y); ballerburg-1.0.1/src/sdlgui.h0000644000175000017500000000433012145514532015433 0ustar thomasthomas/* sdlgui.h This file is distributed under the GNU Public License, version 2 or at your option any later version. Read the file gpl.txt for details. Header for the tiny graphical user interface for the SDL library. */ #ifndef SDLGUI_H #define SDLGUI_H #include enum { SGBOX, SGTEXT, SGEDITFIELD, SGBUTTON, SGRADIOBUT, SGCHECKBOX, SGPOPUP, SGSCROLLBAR, SGUSER }; /* Object flags: */ #define SG_TOUCHEXIT 1 /* Exit immediately when mouse button is pressed down */ #define SG_EXIT 2 /* Exit when mouse button has been pressed (and released) */ #define SG_DEFAULT 4 /* Marks a default button, selectable with return key */ #define SG_CANCEL 8 /* Marks a cancel button, selectable with ESC key */ /* Object states: */ #define SG_SELECTED 1 #define SG_MOUSEDOWN 16 #define SG_MOUSEUP (((int)-1) - SG_MOUSEDOWN) /* Special characters: */ #define SGRADIOBUTTON_NORMAL 12 #define SGRADIOBUTTON_SELECTED 13 #define SGCHECKBOX_NORMAL 14 #define SGCHECKBOX_SELECTED 15 #define SGARROWUP 1 #define SGARROWDOWN 2 #define SGFOLDER 5 #define SGARROWLEFTSTR "\x04" #define SGARROWRIGHTSTR "\x03" /* Return codes: */ #define SDLGUI_ERROR -1 #define SDLGUI_QUIT -2 #define SDLGUI_UNKNOWNEVENT -3 typedef struct { int type; /* What type of object */ int flags; /* Object flags */ int state; /* Object state */ int x, y; /* The offset to the upper left corner */ int w, h; /* Width and height (for scrollbar : height and position) */ char *txt; /* Text string */ } SGOBJ; extern int sdlgui_fontwidth; /* Width of the actual font */ extern int sdlgui_fontheight; /* Height of the actual font */ extern int SDLGui_Init(void); extern int SDLGui_UnInit(void); extern int SDLGui_SetScreen(SDL_Surface *pScrn); extern void SDLGui_GetFontSize(int *width, int *height); extern void SDLGui_Text(int x, int y, const char *txt); extern void SDLGui_DrawDialog(const SGOBJ *dlg); extern int SDLGui_DoDialog(SGOBJ *dlg, SDL_Event *pEventOut); extern void SDLGui_CenterDlg(SGOBJ *dlg); void SDLGui_DrawButton(const SGOBJ *bdlg, int objnum); #endif ballerburg-1.0.1/src/font8x16.png0000644000175000017500000000506212145514531016100 0ustar thomasthomas‰PNG  IHDR€^’!{bKGDª#2 pHYs  šœtIMEÝà39 ÃIDATxÚí]Û’ì ¤Sùÿ_î󨀢æ23[§Üw&‰Á+Mƒ (¿ýÛÕÿ…HK¬ã{”/(hßY=ÈR"Pü[žÿ¥zÏ’V¨­ó  þAé†Ü3Í?^ŠRº¿Ž©'’°“/쵨1ª[%©º›¹©€@¨Æ†BäùŽ{€ºë‚I‰¹!pÔ…±ÐCM€­RõÎk=^Àª^J¶YÏ<¡ð¹9µt€æ"™é©£ ºèƺ!À9ñH½öif=áâ;Ö6ÞBÓkð´ÃÝZ:ºcëÝOõšõyƒšHï‚ C¯ŒÒ¯®‚TßY¾ ¿VÇ›,–K€%À` °X,*PXƒM´Íöò=îÛ([ŸÚ€œ–q²TšÆ}+ Cò„ÔÙJc×~øÈ ÁÐJ[K9!0n\K€d…çxK4/.âpöÅjèöžAAcÑLv11¥Ø2C*3dŸé~$«ö »ÐµfˆÔ‹ÖÂbÛöìšç°mÆÙ¹T+Q4±”ÄäÝIèLGc£Ÿ_ØwØe˜-ÙHSü£ƒ¶xÃ)“/`ÚàÆHÜ€;WcñôÌóÒª…pŒ-âex'ú4Õm™çK€]œC¡8,œã"o¥(…þ:::³“"»rT¸u­Û© Ìõ,lãþîTW:ÍjC¥kƒ¾2__Ç!‘kpìH©ÒãþmbA޹һˈ¹Kâpé³èt;ŠÝYX ¡›TJ“ªGÒ¥­#3`äiÊ2hHíÂd/©QØ#HQM**Ñ ë­Èd¢êDw¯i Û€Di5â\fÍÁ.Õî>+Ñ,“®m«HäÜÓéyêð>Sî×8¥Ž½`ë&Wþì&E)”Fü»žÔ"»a±‹s• |‚·@F† ßTÇ“Žå…­[Z×z_éÿ ¤¥eWuÌ€(½bî§ìb¼`§ htÝRãcÂÙóž‡û¾èqšWhýÞÒóý»Sh<ÛÓ£Ezg[©7£¶[èÉVDgã± Jýæ4¬Ÿž–‚ôÕcÅ(¨9‰ªI¨ÐiÛ»Ž‰ñÚËúSñ:ªFÏ‚M”—úB7(š+;!Q?å½Ý®Ã yÑ2eÁ{=ëððãX?‡0JÍŸ°Cg-m¸ø50jÜ«u*ÜéóZ¿3S´†7ð[¹åóölÔŸ/-ú¥§ìƒ;ôxû~`ï· bRR³ñnïëûjwAÈlÓ]d² M¤­J§Ž}…à¼iS¶Þ¤ü.BíMSf2vY®‰¯»†½n¥ŽÅœuÞž8–®× ¸ƒ¨3ÁIJ†S*R1? «å$<ï\wÑt`ÛLb½•rø8¾Fkv’%ÀV™¦‚}ë†]_òvÝíaDË·¥âh®JðêÂÙïÕÈÁ·¼&@…Ù<&´œ VÔ7ЙLnc=¸ošúwÛ€ XR¼OˆÊµ“©Ýñ3o];]ý戇¶ÿUЂ`¤tBe6‡Èú˜öy]sÕTÇÅ9â´Š•¶.Þ 5$Gá‘Ï|k‚6Ã[Ó ŽõTqüÎÆ,7´®ï û"Gÿåˆn*˜®îÓç YŒÈ¢C|Ãëà守‰çˆ((Q¿Qáý?„&ˆq'/ãrïã4™Z-fC Õe®¦QnUF¥™ò·¨eã†:f©°S@_£rD®š½/}«|w'¿¯Œ^š7!™>ŽñzG\>iÃ+ÊéÀ+¿yó¼Ò‰¢ñ¹´*ýíðA Ú¸@šÿ’¹ÔPƒµþÆàHGOA°\¶–®Ù¼ŽïÆ( §Í¼¦‰N•@s­Ò)}šVÌÞŠ¶¯¬Ûpˆ&Âr61BO¢· Gx AÕL&^È–Sƒ²Áy¿IÜ3bA‘w)˜Ì´LOa¶rEnîówwBâÑVÌûçå¼×L¥œ¦‰Ž£Ü²8øð8Лñ–»èâü:[‹%@‹ èÙdýýøRV€ÒU° }0Á„Ï£XÌ]× 2bIÀLv½øùê†æuüÙ¼b¦UWîï30û0ÙU]žy‚üÒSn K»4ù &Ô{ü@”3gZ9Lªß©íì»÷Š›;!l~‚^9iâRæKâʪMÐÅ,~à÷x â¦ñÁí‘‹ð|è\ É€!Ix 8Bè~ðy€*„ä¯LkÖú ¼'«ÒÏ·:sýÙ,H'hžw¹«§rYŠr^~c™+K€Æõ¤VÎ8eÎ;|Åsb8ªKBb¿Íù<ÙÁÔt~´¿‘ßnþNÁÈÞO9(tÞ¢^iˆ°ä7¼Ç°ú>å•êþ/óž–MLé#¢éÂê«2¹óùhú¬"DDþ’‰zPüÅQIEND®B`‚ballerburg-1.0.1/src/screen.c0000644000175000017500000002221612145514531015420 0ustar thomasthomas/* screen.c - Screen functions for Ballerburg Copyright (C) 2010, 2013 Thomas Huth This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "i18n.h" #include "screen.h" #include "sdlgui.h" #define min(a,b) ((a)<(b)?(a):(b)) #define max(a,b) ((a)>(b)?(a):(b)) SDL_Surface *surf; Uint32 the_color, fill_color; Uint32 bg_color; int fill_style, fill_interior; static SGOBJ donebuttondlg[] = { { SGBOX, 0, 0, 36,29, 8,1, NULL }, { SGBUTTON, SG_EXIT, 0, 0,0, 8,1, N_("Done") } }; void scr_init(void) { if (SDL_Init(SDL_INIT_VIDEO) < 0) { fprintf(stderr, "Could not initialize the SDL library:\n %s\n", SDL_GetError() ); exit(-1); } surf = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE|SDL_HWPALETTE); if (!surf) { fprintf(stderr, "Could not initialize the SDL library:\n %s\n", SDL_GetError() ); exit(-1); } SDL_WM_SetCaption("Ballerburg SDL", "Ballerburg"); bg_color = SDL_MapRGB(surf->format,0xe0,0xf0,0xff); SDLGui_Init(); SDLGui_SetScreen(surf); } void scr_clear(void) { SDL_Rect rect; Uint32 white; int i; white = SDL_MapRGB(surf->format,0xff,0xff,0xff); rect.x = 0; rect.y = 0; rect.w = 640; rect.h = 400; SDL_FillRect(surf, &rect, bg_color); for (i = 0; i < 80; i += 1) { rect.x = 0; rect.y = 479-i; rect.w = 640; rect.h = 1; SDL_FillRect(surf, &rect, SDL_MapRGB(surf->format,8+i/2,32+i,8+i/2)); } /* Left vane box: */ rect.x = 5; rect.y = 410; rect.w = 104; rect.h = 48+16; for (i = 1; i < 5; i++) { rectangleRGBA(surf, rect.x-i, rect.y-i, rect.x+rect.w-1+i, rect.y+rect.h-1+i, 0xf0, 0xff, 0xf0, 0xff-i*0x3c); } SDL_FillRect(surf, &rect, white); /* Right vane box: */ rect.x = 5+(629-104); rect.y = 410; rect.w = 104; rect.h = 48+16; for (i = 1; i < 5; i++) { rectangleRGBA(surf, rect.x-i, rect.y-i, rect.x+rect.w-1+i, rect.y+rect.h-1+i, 0xf0, 0xff, 0xf0, 0xff-i*0x3c); } SDL_FillRect(surf, &rect, white); } void v_gtext(int handle, int x, int y, const char *text) { SDL_Rect rect; // printf("v_gtext: %s\n", text); y -= 12; rect.x = x; rect.y = y; rect.w = strlen(text) * sdlgui_fontwidth; rect.h = sdlgui_fontheight; SDL_FillRect(surf, &rect, SDL_MapRGB(surf->format,0xff,0xff,0xff)); SDLGui_Text(x, y, text); SDL_UpdateRects(surf, 1, &rect); } /** * Draw centered text */ void scr_ctr_text(int cx, int y, const char *text) { SDL_Rect rect; rect.w = strlen(text) * sdlgui_fontwidth; rect.h = sdlgui_fontheight; rect.x = cx - rect.w / 2; rect.y = y; SDL_FillRect(surf, &rect, SDL_MapRGB(surf->format,0xff,0xff,0xff)); SDLGui_Text(rect.x, rect.y, text); SDL_UpdateRects(surf, 1, &rect); } void v_circle(int handle, int x, int y, int w) { SDL_Rect rect; filledCircleColor(surf, x, y, w, the_color); rect.x = max(x-w, 0); rect.y = max(y-w, 0); rect.w = min(2*w, 640-x+w); rect.h = min(2*w, 480-y+w); SDL_UpdateRects(surf, 1, &rect); } static void update_fill_color(void) { if (fill_interior == 0) { fill_color = 0xffffffff; } else if (fill_interior == 1) { fill_color = 0x000000ff; } else if (fill_interior == 2) { switch (fill_style) { case 1: fill_color = 0xc0b0a0ff; break; // Table color case 2: fill_color = 0x602060ff; break; // King color case 9: fill_color = 0x909080ff; break; // Wall color case 11: fill_color = 0xc04020ff; break; // Roof color } } else { puts("unknown fill interior"); } } void vsf_style(short handle, short val) { fill_style = val; update_fill_color(); } void vsf_interior(short handle, short val) { fill_interior = val; update_fill_color(); } void v_bar(short handle, short *xy) { SDL_Rect rect; Uint8 r, g, b; r = fill_color >> 24; g = fill_color >> 16; b = fill_color >> 8; rect.x = xy[0]; rect.y = xy[1]; rect.w = xy[2]-xy[0]+1; rect.h = xy[3]-xy[1]+1; SDL_FillRect(surf, &rect, SDL_MapRGB(surf->format,r,g,b)); rectangleColor(surf, xy[0], xy[1], xy[2], xy[3], the_color); SDL_UpdateRects(surf, 1, &rect); } void clr(short x, short y, short w, short h) { SDL_Rect rect; rect.x = x; rect.y = y; rect.w = w; rect.h = h; SDL_FillRect(surf, &rect, SDL_MapRGB(surf->format,0xff,0xff,0xff)); SDL_UpdateRect(surf, x,y, w,h); } void clr_bg(short x, short y, short w, short h) { SDL_Rect rect; rect.x = x; rect.y = y; rect.w = w; rect.h = h; SDL_FillRect(surf, &rect, bg_color); SDL_UpdateRect(surf, x,y, w,h); } void v_fillarea(short handle, short num, short xy[]) { int i; Sint16 vx[512], vy[512]; //printf("v_fillarea %i\n", num); if (num > 512) { puts("v_fillarea overlow"); exit(-2); } for (i = 0; i < num; i++) { vx[i] = xy[i*2]; vy[i] = xy[i*2+1]; } filledPolygonColor(surf, vx, vy, num, fill_color); SDL_UpdateRect(surf, 0,0, 640,480); } void v_pline(short handle, short num, short xy[]) { int i; int maxx, maxy; int minx, miny; minx = 639; miny = 399; maxx = 0; maxy = 0; // printf("v_pline %i\n", num); for (i = 0; i < num-1; i++) { if (xy[i*2] < 0 || xy[i*2] > 639 || xy[i*2+1] < 0 || xy[i*2+1] > 479) { printf("bad coordinates!\n"); return; } if (xy[i*2] > maxx) maxx = xy[i*2]; if (xy[i*2+1] > maxy) maxy = xy[i*2+1]; if (xy[i*2] < minx) minx = xy[i*2]; if (xy[i*2+1] < miny) miny = xy[i*2+1]; lineColor(surf, xy[i*2], xy[i*2+1], xy[i*2+2], xy[i*2+3], the_color|0x1000); } if (xy[i*2] > maxx) maxx = xy[i*2]; if (xy[i*2+1] > maxy) maxy = xy[i*2+1]; if (xy[i*2] < minx) minx = xy[i*2]; if (xy[i*2+1] < miny) miny = xy[i*2+1]; //printf("blit %i %i %i %i\n", minx,miny, maxx-minx+1,maxy-miny+1); SDL_UpdateRect(surf, minx,miny, maxx-minx+1,maxy-miny+1); } void scr_line(int x1, int y1, int x2, int y2, int rgb) { int minx, miny, maxx, maxy; if (x1 < x2) { minx = x1; maxx = x2; } else { minx = x2; maxx = x1; } if (y1 < y2) { miny = y1; maxy = y2; } else { miny = y2; maxy = y1; } lineColor(surf, x1, y1, x2, y2, (rgb<<8)|0xff); SDL_UpdateRect(surf, minx, miny, maxx-minx+1, maxy-miny+1); } int scr_getpixel(int x, int y) { Uint32 *p = surf->pixels; Uint32 c; SDL_PixelFormat *fmt = surf->format; c = p[y*640+x]; c = ((((c & fmt->Rmask) >> fmt->Rshift) << fmt->Rloss) << 16) | ((((c & fmt->Gmask) >> fmt->Gshift) << fmt->Gloss) << 8) | (((c & fmt->Bmask) >> fmt->Bshift) << fmt->Bloss); return c; } void scr_color(int c) { the_color = (c << 8) | 0xff; } void scr_fillcolor(int c) { fill_color = (c << 8) | 0xff; } /** * Select foreground (1) or background (0) color */ void color(int c) { if (c) the_color = 0x000000ff; else the_color = (bg_color<<8) | 0x0ff; } void scr_init_done_button(int *bx, int *by, int *bw, int *bh) { int fontw, fonth; /* Calculate the "Done" button coordinates */ SDLGui_GetFontSize(&fontw, &fonth); *bx = donebuttondlg[0].x * fontw; *by = donebuttondlg[0].y * fonth; *bw = donebuttondlg[0].w * fontw; *bh = donebuttondlg[0].h * fonth; } void scr_draw_done_button(int selected) { if (selected) donebuttondlg[1].state |= SG_SELECTED; else donebuttondlg[1].state &= ~SG_SELECTED; SDLGui_DrawButton(donebuttondlg, 1); SDL_UpdateRect(surf, 0,0, 0,0); } /** * Draws a fast cannonball */ void scr_cannonball(int x, int y) { lineColor(surf, x-2,y-2,x+1,y-2, the_color); lineColor(surf, x-3,y-1,x+2,y-1, the_color); lineColor(surf, x-3,y ,x+2,y , the_color); lineColor(surf, x-3,y+1,x+2,y+1, the_color); lineColor(surf, x-2,y+2,x+1,y+2, the_color); SDL_UpdateRect(surf, x-3, y-3, 6, 6); } /** * Stores information about saved background area */ struct savebg { SDL_Rect rect; SDL_Rect bgrect; SDL_Surface *bgsurf; }; /** * Save a part of the background of the screen */ void *scr_save_bg(int x, int y, int w, int h) { struct savebg *s; s = malloc(sizeof(struct savebg)); if (!s) return NULL; s->rect.x = x; s->rect.y = y; s->rect.w = w; s->rect.h = h; s->bgrect.x = s->bgrect.y = 0; s->bgrect.w = s->rect.w; s->bgrect.h = s->rect.h; s->bgsurf = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, surf->format->BitsPerPixel, surf->format->Rmask, surf->format->Gmask, surf->format->Bmask, surf->format->Amask); if (s->bgsurf != NULL) { /* Save background */ SDL_BlitSurface(surf, &s->rect, s->bgsurf, &s->bgrect); } else { fprintf(stderr, "scr_save_bg: CreateRGBSurface failed: %s\n", SDL_GetError()); } return s; } /** * Restore part of the background */ void scr_restore_bg(void *ps) { struct savebg *s = ps; /* Restore background */ if (s != NULL && s->bgsurf != NULL) { SDL_BlitSurface(s->bgsurf, &s->bgrect, surf, &s->rect); SDL_FreeSurface(s->bgsurf); } SDL_UpdateRects(surf, 1, &s->rect); } ballerburg-1.0.1/src/cannoneer.c0000644000175000017500000001101712145514531016106 0ustar thomasthomas/* cannoneer.c Copyright (C) 1987, 1989 Eckhard Kruse Copyright (C) 2010 Thomas Huth This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "i18n.h" #include "ballergui.h" #include "baller1.h" #include "sdlgui.h" #include "screen.h" static void draw_cannoneer(int x, int y, int w, int h); static short wi, pv; /* Winkel und Pulver */ /* The cannoneer dialog data: */ #define WL2 3 /* Winkel um 10 verkleinern */ #define WL1 4 /* Winkel um 1 verkleinern */ #define WR1 6 #define WR2 7 #define PL2 9 #define PL1 10 #define PR1 12 #define PR2 13 #define SOK 14 #define SAB 15 // #define WINK TBD // #define PULV TBD static char dlg_winkel[4]; static char dlg_pulver[3]; static SGOBJ cannoneerdlg[] = { { SGBOX, 0, 0, 0,0, 42,15, NULL }, { SGTEXT, 0, 0, 18,1, 6,1, N_("Cannon") }, { SGTEXT, 0, 0, 2,3, 7,1, N_("Angle:") }, { SGBUTTON, SG_EXIT, 0, 12,3, 4,1, "\x04\04" }, // 2 arrows left { SGBUTTON, SG_EXIT, 0, 17,3, 3,1, "\x04" }, // Arrow left { SGTEXT, 0, 0, 22,3, 4,1, dlg_winkel }, { SGBUTTON, SG_EXIT, 0, 26,3, 3,1, "\x03" }, // Arrow right { SGBUTTON, SG_EXIT, 0, 30,3, 4,1, "\x03\x03" }, // 2 arrows right { SGTEXT, 0, 0, 2,5, 7,1, N_("Gunpowder:") }, { SGBUTTON, SG_EXIT, 0, 12,5, 4,1, "\x04\04" }, // 2 arrows left { SGBUTTON, SG_EXIT, 0, 17,5, 3,1, "\x04" }, // Arrow left { SGTEXT, 0, 0, 22,5, 4,1, dlg_pulver }, { SGBUTTON, SG_EXIT, 0, 26,5, 3,1, "\x03" }, // Arrow right { SGBUTTON, SG_EXIT, 0, 30,5, 4,1, "\x03\x03" }, // 2 arrows right { SGBUTTON, SG_DEFAULT, 0, 33,11, 8,1, "OK" }, { SGBUTTON, SG_CANCEL, 0, 33,13, 8,1, "Cancel" }, { SGBOX, 0, 0, 2,7, 30,7, NULL }, { SGUSER, 0, 0, 2,7, 30,7, (void*)draw_cannoneer }, { -1, 0, 0, 0,0, 0,0, NULL } }; /** * Draw cannoneer */ static void draw_cannoneer(int x, int y, int w, int h) { static short fig[]={ 0,0,15,20,30,20,20,15,10,0,10,-30,18,-18,20,-5,24,-6, 20,-25,10,-40,0,-45, -10,-40,-20,-25,-24,-6,-20,-5,-18,-18,-10,-30,-10,0, -20,15,-30,20,-15,20, -1,-1 }; /* Daten für das Männchen */ int xk,yk; int fl; int i; double s,c; SDL_Rect rect; rect.x = x + 1; rect.y = y + 1; rect.w = w - 2; rect.h = h - 2; SDL_FillRect(surf, &rect, SDL_MapRGB(surf->format,0xff,0xff,0xff)); xk = x + w / 2; yk = y + h / 2 + 40; /* Draw the cannoneer man */ color(1); filledCircleColor(surf, xk-88*f, yk-60, 15, 0x000000ff); i=0; while ( fig[i]!=-1 ) { xy[i]=xk-88*f+fig[i]; i++; xy[i]=yk-5+fig[i]; i++; } xy[i++]=xy[0]; xy[i++]=xy[1]; v_fillarea( handle,i/2-1,xy ); /* Draw the cannon */ color( 1 ); filledCircleColor(surf, xk, yk, 15, 0x000000ff); s=sin(wi/P57); c=cos(wi/P57); fl=-f; if ( wi>90 ) { fl=-fl; c=-c; } xy[0]=xk+fl*(c*14+s*14); xy[1]=yk+s*14-c*14; xy[2]=xk+fl*(c*14+s*40); xy[3]=yk+s*14-c*40; xy[4]=xk-fl*(c*55-s*40); xy[5]=yk-s*55-c*40; xy[6]=xk-fl*(c*55-s*14); xy[7]=yk-s*55-c*14; xy[8]=xy[0]; xy[9]=xy[1]; v_fillarea( handle,4,xy ); } /** * Kanonenobjektbaum, Wahl von Winkel und Pulver */ int sch_obj(short k) { short i = 0; char *aw,*ap; dlg_winkel[0] = dlg_pulver[0] = 0; aw = dlg_winkel; ap = dlg_pulver; *(ap+2)=0; SDLGui_CenterDlg(cannoneerdlg); wi=ka[n][k].w; pv=ka[n][k].p; vsf_interior( handle,1 ); do { if (pv > pu[n]) { pv=pu[n]; } *aw=48+wi/100; *(aw+1)=48+wi%100/10; *(aw+2)=48+wi%10; if (wi < 100) { *aw=*(aw+1); *(aw+1)=*(aw+2); *(aw+2)=0; } *ap=48+pv/10; *(ap+1)=48+pv%10; if (pv<10) { *ap=*(ap+1); *(ap+1)=0; } i = SDLGui_DoDialog(cannoneerdlg, NULL); wi-=10*(i==WL2)-10*(i==WR2)+(i==WL1)-(i==WR1); if ( wi<0 ) wi=0; if ( wi>180 ) wi=180; pv-= 3*(i==PL2)- 3*(i==PR2)+(i==PL1)-(i==PR1); if ( pv<5 ) pv=5; if ( pv>20 ) pv=20; } while (i != SOK && i != SAB); SDL_UpdateRect(surf, 0,0, 0,0); ka[n][k].w=wi; ka[n][k].p=pv; return (i == SOK); } ballerburg-1.0.1/src/baller.dat0000644000175000017500000001751012145514531015731 0ustar thomasthomas*=============================================================================* * BALLER.DAT : Burgdaten für Ballerburg * * 28.4.87 Eckhard Kruse * * Einige Informationen vorweg: * * - Bemerkungen müssen in Sternchen eingeschlossen werden * * - Die Zahlen müssen durch Kommata oder Blanks voneinander getrennt sein * * - Alle Angaben beziehen sich direkt auf die Rasterkoordinaten ( RC ) der * * hohen Auflösung * * - Stellen Sie sich die Burgdaten nur für die linke Burg vor. Die rechte * * Burg wird einfach durch Spiegelung gezeichnet. * * - Der Koordinatenursprung liegt am linken Bildschirmrand an der Unterkante* * der Burg. Es gibt nur positive Koordinaten ( und 0 ). * * - Ballerburg entdeckt keine Fehler in der Burgdatei. Fehlerhafte Daten * * können schlimmstenfalls zum Absturz führen. * * - Zum Erstellen von eigenen Burgen entwerfen Sie diese am besten zuerst * * auf Millimeterpapier und lesen dann die Koordinaten einfach ab. * *=============================================================================* *========================= Daten für die 1. Burg =============================* 130 * Ausdehnung in X-Richtung ( entspricht dem höchsten X-Wert der * * Zeichendaten. ), darf nicht größer als 200 sein. * 10,31, 70,36, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1 * X,Y-Koordinaten der 10 möglichen Kanonen, nicht verwandte sind mit -1,-1 * * anzugeben. Die Koordinaten beziehen sich auf die linke, untere Ecke. Die * * Maße einer Kanone: 20x12 * * Die nächsten 5 Koordinatenpaare ( außer der Fahne ) beziehen sich auf die * * linke untere Ecke des zu zeichnenden 'Kastens'. * 40,1 * X,Y-Koordinaten des Trohnes * 18,70 * X,Y-Koordinaten der Fahne ( bezogen auf das untere Stangenende. ) * 9,1 * X,Y-Koordinaten des Geldes * 80,3 * X,Y-Koordinaten des Pulvers * 103,25 * X,Y-Koordinaten der Kugeln * 21,20 * Breite, Höhe der Geldkammer ( Größe eines Sackes: 7x10 ) * 27,18 * Breite, Höhe der Pulverkammer ( Größe eines Fasses: 9x9 ) * 24,18 * Breite, Höhe der Kugelkammer ( Größe einer Kugel: 6x6 ) * * Durch die Maße der Kammern wird automatisch die Obergrenze für Geld, * * Pulver und Kugeln festgelegt. Die Maße müssen jeweils ein Vielfaches der * * Größen der einzelnen Objekte sein. * * Der Trohn hat immer die Maße 30x25, die Windfahne 30x15. * 400 * Startwert für das Geld * 180 * Startwert für das Pulver * 12 * Startwert für die Kugeln * 200 * Startwert für das Volk * 0,0,0,0 * reservierte, nicht verwandte Werte * *=============================================================================* * Es folgen nun die Daten für das eigentliche Aussehen der Burg. Die Zeichen- * * routine liest die Zahlen der Reihe nach und interpretiert sie wie folgt: * * - Ist die Zahl >=0, so sei sie das erste Element einer X,Y-Koordinatenliste,* * die mit einer -9 abgeschlossen wird. Diese Koordinaten stellen die * * Eckpunkte einer zu füllenden Fläche dar. * * ( Geschieht mit v_fillarea( handle,n,xy ). ) * * - Ist die Zahl eine -2, so werden die beiden folgenden Zahlen als Style und * * Index eines neuen Füllmusters angesehen. Der Startwert vor dem Zeichnen * * ist 2,9 ( Mauerwerk ). Das Zeichnen geschieht übrigens im Schreibmodus 4 * * ( reverse transparent ). Dies bewirkt, daß die Füllmuster invers erschei- * * nen. Um es Ihnen etwas einfacher zu machen: Sie brauchen sich eigentlich * * nur zu merken, daß vor dem Zeichnen von Mauern -2,2,9 und vor dem Zeichnen* * von Dächern -2,2,11 stehen muß. * * - Die -1 schließt die Zeichendaten und gleichzeitig die Daten einer Burg ab.* *=============================================================================* 0,0,0,30,5,55,30,55,10,45,10,30,30,30,75,65,80,60,70,50,70,35,90,35,100,45, 100,60,130,60,130,0,-9, -2,2,11, 5,55,18,70,30,55,-9, 100,60,115,70,130,60,-9, -1 *=============================================================================* * Für die folgenden Burgen gilt der gleiche Aufbau der Daten. Ich habe daher * * auf die Erläuterungen verzichtet. * *========================= Daten für die 2. Burg =============================* 150 10,11,10,51,50,51,80,46,130,46,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 45,1 135,100 80,1, 52,30, 126,1 35,20, 63,9, 18,36 500,180,12,270 0,0,0,0 0,0,0,70,30,70,10,65,10,50,30,50,10,30,10,10,30,10,50,50,70,50,80,45,120,45, 120,70,150,70,130,60,130,45,150,45,150,0,-9, -2,2,11, 0,70,15,100,30,70,-9, 120,70,135,100,150,70,-9, -1 *========================= Daten für die 3. Burg =============================* 130 0,70,20,70,50,40,50,16,110,40,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 10,1 95,60 11,30, 50,1, 80,15 28,30, 72,9, 42,18 500,150,14,270 0,0,0,0 0,0,0,70,40,70,50,50,50,40,70,40,50,30,50,15,70,15,80,40,130,40,130,0,-9, -2,2,11, 80,40,95,60,110,40,-9, -1 *========================= Daten für die 4. Burg =============================* 170 10,36,70,40,90,40,75,80,150,21,150,56,-1,-1,-1,-1,-1,-1,-1,-1 60,1 15,80 15,5, 100,1, 100,20 35,20, 63,9, 36,18 500,190,12,300 0,0,0,0 0,0,0,60,30,60,10,50,10,35,30,35,75,80,95,80,70,55,70,40,110,40,120,70,150,70, 150,55,170,55,150,35,150,20,170,20,170,0,-9, -2,2,11, 0,60,15,80,30,60,-9, 120,70,140,90,160,70,-9, -1 *========================= Daten für die 5. Burg =============================* 115 10,36,55,31,90,51,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 10,1 27,67 50,1, 85,1, 102,1 28,10, 9,36, 6,36 500,120,6,220 0,0,0,0 0,0,0,55,27,67,30,60,10,50,10,35,30,35,55,60,70,60,55,45,55,30,75,30,85,50, 115,50,115,0,-9, -1 *========================= Daten für die 6. Burg =============================* 140 10,60,30,60,90,40,110,40,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 90,1 90,85 10,1, 50,1, 15,38 28,20, 27,18, 30,12 500,120,10,240 0,0,0,0 0,0,10,60,50,60,55,30,70,30,70,70,110,70,90,55,90,40,130,40,140,0,-9, -2,2,11, 70,70,90,85,110,70,-9, -1 *==================== Some castles from Ballerburg^2 =========================* 150,40,91,40,61,40,31,40, 1,60, 1,80, 1,-1,-1,-1,-1,-1,-1,-1,-1 114, 3,23,130, 9,82,9,40, 8,3, 28,20, 27,36, 30,30, 800,120,12,500 0,0,0,0 6,0,6,105,2,115,2,130,8,130,8,122,11,122,11,130,17,130,17,122,20,122, 20,130,26,130,26,122,29,122,29,130,35,130,35,122,38,122,38,130,44,130, 44,115,40,105,40,90,60,90,60,85,40,75,40,60,60,60,60,55,40,45,40,30, 60,30,60,25,40,15,40,1,110,1,110,33,150,33,150,0,-9, -2,2,11,108,33,128,50,151,33,-9,-1 160,47,121,70,121,93,121,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 65,2,155,30,69,90,71,56,71,32,21,20,18,18,18,18,500,120,9,500 0,0,0,0 0,0,0,30,15,30,30,35,40,45,45,60,47,120,60,120,60,50,55,35,50,25,35,10, 25,5,5,0,0,0,63,0,64,120,95,120,96,0,155,0,135,5,125,10,110,25,105,35, 100,50,100,120,113,120,115,60,120,45,130,35,145,30,160,30,160,0,-9,-1 185, 82,126,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 80,40, 45,125, 15,45, 125,40, 81,79, 49,30,45,36,24,36,1000,120,12,300 0,0,0,0 30,0,15,13,1,45,1,65,15,100,35,120,45,125,30,100, 30,90,35,85,45,82,50,82,70,95,75,105,75,135, 80,125,105,125,110,135, 110,105,115,95,135,82,140,82,150,85,155,90,155,100,140,125, 150,120,170,100,184,65,184,45,170,13,155,0,160,15,160,20, 155,30,145,35,130,35,120,22,110,35,105,35,92,18,80,35,65,22,55,35, 40,35,30,30,25,20,25,15,30,0,-9,-1 * Hier z.B. koennen Sie Ihre eigenen Kreationen einschieben. Die Anzahl der * * Burgen ist beliebig und wird von Ballerburg automatisch erkannt * -999 * Ende der Burgendatei * ballerburg-1.0.1/src/music.h0000644000175000017500000000206712145514531015270 0ustar thomasthomas/* music.h - prototypes and definitions for music.c Copyright (C) 2011 Thomas Huth This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ void m_laden(const char * string); void m_musik(void); void m_wloop(void); void s_note(unsigned int wert); void s_init(void); void s_quit(void); void s_freq(unsigned short freq); void s_laut(short laut); void s_rausch(short periode); void s_t_an(void); void s_t_aus(void); void s_r_an(void); void s_r_aus(void); void s_aus(void); ballerburg-1.0.1/src/music.c0000644000175000017500000002404412145514531015262 0ustar thomasthomas/* music.c Copyright (C) 1986 Eckhard Kruse Copyright (C) 2011 Thomas Huth This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /********************************************************************* * Abspielen von Musik-Editor Stücken * * * * Gleich einmal vorweg wie ein Programm aussieht, das die hier * * definierten Routinen verwendet: * * * * extern void m_laden(), m_musik(), m_wloop(); * * main() * * { * * int save_ssp; * * m_laden("DATEI.MUS"); Datei laden * * m_musik(); Musik abspielen * * } * * int m_wait() Warteschleife * * { * * m_wloop(); * * return 0; return 1 um abzubrechen * * } * *********************************************************************/ #include #include #include #include #include "psg.h" #include "music.h" #include "paths.h" extern int m_wait(void); /* Diese Funktion muss in Ihrem Hauptprogramm stehen, * * sie wird von m_musik() nach jedem 1/96 Takt aufgerufen, und sie sollte * * immer eine bestimmte Zeitspanne warten ( bestimmt die Ablaufgeschwindig- * * keit der Musik ). Dies kann durch den Aufruf von m_wloop() geschehen. */ unsigned short *takte; short buffer[100], *liste, max_abl, max_tkt, walz, tempo, temp, w_len, save7, reg7, kanal, tra[3], lau[3]; /**************** Tabellen für Noten- und Frequenzwerte **********************/ short st_wert[] = { 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 27, 28, 30, 32, 34, 36, 38, 40, 42, 45, 47, 50, 53, 56, 60, 63, 67, 71, 75, 80, 84, 89, 95, 100, 106, 113, 119, 127, 134, 142, 150, 159, 169, 179, 190, 201, 213, 226, 239, 253, 268, 284, 301, 319, 338, 358, 379, 402, 426, 451, 478, 506, 536, 568, 602, 638, 676, 716, 759, 804, 852, 903, 956, 1013, 1073, 1136, 1204, 1276, 1351, 1432, 1517, 1607, 1703, 1804, 1911, 2025, 2145, 2273, 2408, 2553, 2703, 2864, 3034, 3214, 3405, 3608, 3823 } ; char st_ton[] = { 0, 1, 3, 5, 7, 8, 10, 12, 13, 15, 17, 19, 20, 22, 24, 25, 27, 29, 31, 32, 34, 36, 37, 39, 41, 43, 44, 46, 48, 49, 51, 53, 55, 56, 58, 60, 61, 63, 65, 67, 68, 70, 72, 73, 75, 77, 79, 80, 82, 84, 85, 87, 89, 91, 92, 94, 96 } ; /******************** Laden und Speicher reservieren *************************/ void m_laden(const char * string) { FILE *f_handle; int i; char *fname; fname = malloc(FILENAME_MAX); if (!fname) { perror("m_laden"); return; } snprintf(fname, FILENAME_MAX, "%s/%s", Paths_GetDataDir(), string); /* Open file in data directory */ f_handle = fopen(fname, "rb"); free(fname); fname = NULL; if (!f_handle) { /* Try local directory instead */ f_handle = fopen(string, "rb"); if (!f_handle) { perror("Loading music failed"); return; } } if (fread(buffer, 16, 1, f_handle) != 1) { perror("Failed to read music file"); return; } for (i = 0; i < 16/2; i++) { buffer[i] = SDL_SwapBE16(buffer[i]); } tempo=buffer[2]; max_abl=buffer[3]; max_tkt=buffer[4]; walz=buffer[7]; if( walz ) w_len=72; else w_len=96; liste=( short *)malloc((max_abl+2)<<3 ); /* Reserviere Speicherbereich der Größe (w_len*2)*(max_tkt+2) und lösch ihn. */ takte=( unsigned short *)calloc( w_len*2, max_tkt+2+2 ); if (fread(buffer, 1, 36, f_handle) != 36) { perror("Failed to read music file"); return; } for (i = 0; i < 36/2; i++) { buffer[i] = SDL_SwapBE16(buffer[i]); } if (fread(liste, (max_abl+1)<<3, 1, f_handle) != 1) { perror("Failed to read music file"); return; } for (i = 0; i < ((max_abl+1)<<3)/2; i++) { liste[i] = SDL_SwapBE16(liste[i]); } if (fread(&takte[100], (max_tkt+1)*w_len, 2, f_handle) != 2) { perror("Failed to read music file"); return; } for (i = 0; i < (max_tkt+1)*w_len; i++) { takte[100+i] = SDL_SwapBE16(takte[100+i]); } fclose(f_handle); } /************************ Stück spielen **************************************/ void m_musik(void) { short buf_ptr, lis_ptr, ende, help, kan1, kan2, kan3, rau; if (!liste || !takte) return; s_init(); buffer[0]=0; buffer[1]=-2; buf_ptr=2; lis_ptr=0; temp=100; lau[0]=lau[1]=lau[2]=100; tra[0]=tra[1]=tra[2]=0; ende=0; while( !ende ) { switch( liste[lis_ptr] ) { case -1: if( buffer[--buf_ptr]==-2 ) ende=1; lis_ptr=buffer[--buf_ptr]; break; case -2: tra[0]=liste[++lis_ptr]; tra[1]=liste[++lis_ptr]; tra[2]=liste[++lis_ptr]; lis_ptr++; break; case -3: lau[0]=liste[++lis_ptr]; lau[1]=liste[++lis_ptr]; lau[2]=liste[++lis_ptr]; lis_ptr++; break; case -4: temp=liste[++lis_ptr]; lis_ptr+=3; break; case -5: lis_ptr+=4; buffer[buf_ptr++]=lis_ptr; buffer[buf_ptr++]=0; break; case -6: lis_ptr+=4; if( buffer[buf_ptr-1]==liste[lis_ptr-3] ) { buf_ptr-=2; help=0; while( help>=0 ) { if( liste[lis_ptr]==-1 ) help=-1; help+=( liste[lis_ptr]==-5 )-( liste[lis_ptr]==-7 ); lis_ptr+=4; } } break; case -7: buffer[buf_ptr-1]++; lis_ptr=buffer[buf_ptr-2]; break; case -8: if( liste[++lis_ptr]<0 ) lis_ptr+=3; else { buffer[buf_ptr++]=lis_ptr+3; buffer[buf_ptr++]=-5; lis_ptr=(liste[lis_ptr]-1)<<2; } break; default: rau =( liste[lis_ptr]>=0 )*(( liste[lis_ptr+0] )*w_len +100); lis_ptr++; kan1=( liste[lis_ptr]>=0 )*(( liste[lis_ptr+0] )*w_len +100); lis_ptr++; kan2=( liste[lis_ptr]>=0 )*(( liste[lis_ptr+0] )*w_len +100); lis_ptr++; kan3=( liste[lis_ptr]>=0 )*(( liste[lis_ptr+0] )*w_len +100); lis_ptr++; for( help=0; help>2 & 63 ]; if( wert & 0x4000 ) ton_nr--; if( wert & 0x8000 ) ton_nr++; if( ( wert & 0xc000 ) == 0xc000 ) { s_rausch( wert&255 ); } else { ton_nr-=tra[kanal]; if( ton_nr<0 ) ton_nr=0; if( ton_nr>95 ) ton_nr=95; s_freq( (st_wert[ton_nr]*(4-(wert&3))+st_wert[ton_nr+1]*(wert&3) )>>2 ); if( wert & 0x1000 ) s_t_an(); else s_t_aus(); if( wert & 0x2000 ) s_r_an(); else s_r_aus(); s_laut( (wert>>8 & 15)*lau[kanal]/100 ); } } /*************************** Sound Ansteuerung *******************************/ /**************************** Initialisierung ********************************/ void s_init(void) { reg7=save7=Giaccess( 0, 0x07 ); s_rausch( 0 ); } /*********************** Wiederherstellen vor Ende ***************************/ void s_quit(void) { s_aus(); Giaccess( save7, 0x87 ); } /************************** Tonfrequenz setzen *******************************/ void s_freq(unsigned short freq) { short kan; kan=kanal<<1; Giaccess( freq&0xff, kan+0x80 ); Giaccess( freq>>8, kan+0x81 ); } /************************** Lautstärke setzen ********************************/ void s_laut(short laut) { Giaccess( laut, kanal+0x88 ); } /************************* Rauschperiode setzen ******************************/ void s_rausch(short periode) { Giaccess( periode, 0x86 ); } /**************************** Ton einschalten ********************************/ void s_t_an(void) { reg7&=( 254-kanal-( kanal==2 ) ); Giaccess( reg7, 0x87 ); } /**************************** Ton ausschalten ********************************/ void s_t_aus(void) { reg7|=( 1+kanal+( kanal==2 ) ); Giaccess( reg7, 0x87 ); } /*************************** Rauschen einschalten ****************************/ void s_r_an(void) { reg7 &= 255 -((1 + kanal + (kanal == 2)) << 3); Giaccess(reg7, 0x87); } /*************************** Rauschen ausschalten ****************************/ void s_r_aus(void) { reg7 |= ((1 + kanal + (kanal == 2)) << 3); Giaccess(reg7, 0x87); } /*************************** Sound abschalten ********************************/ void s_aus(void) { kanal=0; s_laut( 0 ); kanal=1; s_laut( 0 ); kanal=2; s_laut( 0 ); } ballerburg-1.0.1/src/CMakeLists.txt0000644000175000017500000000112612145514531016532 0ustar thomasthomas include_directories(${CMAKE_BINARY_DIR} ${MATH_INCLUDE_DIR} ${SDL_INCLUDE_DIR} ${SDLGFX_INCLUDE_DIR}) add_executable (ballerburg baller1.c baller2.c ballergui.c cannoneer.c screen.c psg.c dlgAlert.c sdlgui.c market.c music.c paths.c settings.c) target_link_libraries(ballerburg ${SDL_LIBRARY} ${SDLGFX_LIBRARY} ${MATH_LIBRARY}) if(SDLMAIN_LIBRARY) target_link_libraries(ballerburg ${SDLMAIN_LIBRARY}) endif(SDLMAIN_LIBRARY) install(TARGETS ballerburg RUNTIME DESTINATION ${BINDIR}) install(FILES baller.dat baller.mus DESTINATION ${DATADIR}) ballerburg-1.0.1/src/market.c0000644000175000017500000001525712145514531015433 0ustar thomasthomas/* market.c Copyright (C) 1987, 1989 Eckhard Kruse Copyright (C) 2010, 2013 Thomas Huth This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include "i18n.h" #include "baller1.h" #include "baller2.h" #include "ballergui.h" #include "screen.h" #include "sdlgui.h" #include "market.h" static char dlg_geld[6]; static char dlg_geschuetze[6]; static char dlg_pulver[6]; static char dlg_volk[6]; static char dlg_ftuerme[6]; static char dlg_fahne[6]; static char dlg_kugeln[6]; static char dlg_steuern[6]; static char dlg_anbauenpreis[6]; static char dlg_fturmpreis[6]; static char dlg_geschuetzpreis[6]; static char dlg_fahnepreis[6]; static char dlg_pulverpreis[6]; static char dlg_kugelpreis[6]; #define SH1 11 /* Geld */ #define SH2 12 /* Fördertürme */ #define SH3 13 /* Geschütze */ #define SH4 14 /* Windfahne */ #define SH5 15 /* Pulver */ #define SH6 16 /* Kugeln */ #define SH7 17 /* Volk */ #define SH8 18 /* Steuern */ #define SHK 19 /* Steuern runter */ #define SHG 20 /* Steuern rauf */ #define SM1 29 /* Preis für Anbauen */ #define SM2 30 /* Preis für Förderturm */ #define SM3 31 /* Preis für Geschütz */ #define SM4 32 /* Preis für Windfahne */ #define SM5 33 /* Preis für Pulver */ #define SM6 34 /* Preis für Kugeln */ #define FERTIG 35 static SGOBJ marktdlg[] = { { SGBOX, 0, 0, 0,0, 54,18, NULL }, { SGBOX, 0, 0, 1,1, 52,7, NULL }, { SGTEXT, 0, 0, 23,1, 8,1, N_("You have:") }, { SGTEXT, 0, 0, 2,3, 10,1, N_("Funds:") }, { SGTEXT, 0, 0, 28,3, 12,1, N_("Shaft towers:") }, { SGTEXT, 0, 0, 2,4, 10,1, N_("Cannons:") }, { SGTEXT, 0, 0, 28,4, 12,1, N_("Weather vane:") }, { SGTEXT, 0, 0, 2,5, 10,1, N_("Gunpowder:") }, { SGTEXT, 0, 0, 28,5, 12,1, N_("Cannonballs:") }, { SGTEXT, 0, 0, 2,6, 10,1, N_("Population:") }, { SGTEXT, 0, 0, 28,6, 12,1, N_("Taxes in %") }, { SGTEXT, 0, 0, 19,3, 5,1, dlg_geld }, { SGTEXT, 0, 0, 47,3, 5,1, dlg_ftuerme }, { SGTEXT, 0, 0, 19,4, 5,1, dlg_geschuetze }, { SGTEXT, 0, 0, 47,4, 5,1, dlg_fahne }, { SGTEXT, 0, 0, 19,5, 5,1, dlg_pulver }, { SGTEXT, 0, 0, 47,5, 5,1, dlg_kugeln }, { SGTEXT, 0, 0, 19,6, 5,1, dlg_volk }, { SGTEXT, 0, 0, 45,6, 5,1, dlg_steuern }, { SGBUTTON, SG_EXIT, 0, 46,6, 1,1, SGARROWLEFTSTR }, { SGBUTTON, SG_EXIT, 0, 51,6, 1,1, SGARROWRIGHTSTR }, { SGBOX, 0, 0, 1,9, 52,6, NULL }, { SGTEXT, 0, 0, 23,9, 8,1, N_("Market:") }, { SGTEXT, 0, 0, 2,11, 10,1, N_("Lay bricks:") }, { SGTEXT, 0, 0, 28,11, 12,1, N_("Shaft tower:") }, { SGTEXT, 0, 0, 2,12, 10,1, N_("Cannon:") }, { SGTEXT, 0, 0, 28,12, 12,1, N_("Weather vane:") }, { SGTEXT, 0, 0, 2,13, 10,1, N_("Powder x30:") }, { SGTEXT, 0, 0, 28,13, 12,1, N_("2 cannonballs:") }, { SGTEXT, 0, 0, 19,11, 5,1, dlg_anbauenpreis }, { SGTEXT, 0, 0, 47,11, 5,1, dlg_fturmpreis }, { SGTEXT, 0, 0, 19,12, 5,1, dlg_geschuetzpreis }, { SGTEXT, 0, 0, 47,12, 5,1, dlg_fahnepreis }, { SGTEXT, 0, 0, 19,13, 5,1, dlg_pulverpreis }, { SGTEXT, 0, 0, 47,13, 5,1, dlg_kugelpreis }, { SGBUTTON, SG_DEFAULT, 0, 21,16, 12,1, N_("Done") }, { -1, 0, 0, 0,0, 0,0, NULL } }; /** * Anbauen */ static void anbau(void) { short s; char brickstr[80]; void *savearea; /* Save background */ savearea = scr_save_bg(220, 375-12, 25*8, 38); color(1); vsf_interior( handle,2 ); vsf_style( handle,9 ); scr_ctr_text(320, 365, _(" Lay bricks: ")); sprintf(brickstr, _(" Bricks left: %02d "), 20); scr_ctr_text(320, 382, brickstr); s=20; scr_color(0x909080); do { if (event(1, 0)) exit(0); if ( bt && (n? mx>624-bg[0] : mx155 ) { if ( !( loc(mx,my) || loc(mx+1,my+1) || loc(mx-1,my-1) ) && ( loc(mx+3,my-1)||loc(mx+3,my+1)||loc(mx-3,my-1)||loc(mx-3,my+1)|| loc(mx+1,my+2)||loc(mx-1,my+2)||loc(mx+1,my-2)||loc(mx-1,my-2) )) { xy[0]=mx-2; xy[1]=my-1; xy[2]=mx+2; xy[3]=my+1; v_bar( handle,xy ); s--; sprintf(brickstr, _(" Bricks left: %02d "), s); scr_ctr_text(320, 382, brickstr); } } } while ( s>0 && bt<2 ); /* Restore background */ scr_restore_bg(savearea); } /** * 5-stellige Zahl, rechtsbündig, ohne führende Nullen */ static void zahl(short nr, short wert) { short i,a,b; char *adr; adr = marktdlg[nr].txt; for (b = i = 0, a = 10000; i < 5; i++, a /= 10) { *adr++ = 48 + wert/a - 16*(wert -1); } for (ko = k = 0; k < 10; ) { /* Kanonen zählen */ ko += (ka[n][k++].x > -1); } for (k = 0; k < 10; k++) { if (bg[1+k*2] > -1 && ka[n][k].x == -1) { /* Platz für neue Kanone? */ for (a = 1; a < 10; a++) { if (loc(639*n+(bg[1+k*2]+5+a)*f, by[n]-bg[2+k*2]-a)) break; } if (a > 9) break; } } zahl(SH1, ge[n]); zahl(SH2, t); zahl(SH3, ko); zahl(SH4, wx[n]>-1); zahl(SH5, pu[n]); zahl(SH6, ku[n]); zahl(SH7, vo[n]); zahl(SH8, st[n]); for (a = 0; a < 6; a++) { // fprintf(stderr,"a=%i: ge=%i p=%i an_erl=%i bg=%i t=%i k=%i wx=%i\n", // a, ge[n], p[a], an_erl, bg[0], t, k, wx[n]); if (ge[n] < p[a] || (!an_erl && a == 0) || (a == 1 && (bg[0]+t*30 > 265 || t > 4)) || (a == 2 && k > 9) || (a == 3 && wx[n] > -1)) { marktdlg[SM1 + a].type = SGTEXT; } else { marktdlg[SM1 + a].type = SGBUTTON; } } a = SDLGui_DoDialog(marktdlg, NULL); if (a == SHK) { st[n]-=2*(st[n]>0); } else if (a == SHG) { st[n]+=2*(st[n]<100); } else if (a != FERTIG && a >= SM1 && a <= SM6) { ge[n] -= p[a-SM1]; if (a < SM5) { drw_all(); if (a == SM1) anbau(); else if (a == SM2) fturm(); else if (a == SM3) init_ka( k,639*n ); else if (a == SM4) { wx[n]=639*n+f*bg[23]; wy[n]=by[n]-bg[24]; werdran(1); } } else { pu[n]+=30*(a==SM5); ku[n]+=2*(a==SM6); drw_gpk(a-SM4); drw_gpk(0); } } } while (a != FERTIG); SDL_UpdateRect(surf, 0,0, 0,0); } ballerburg-1.0.1/src/paths.h0000644000175000017500000000074212145514531015265 0ustar thomasthomas/* Ballerburg This file is distributed under the GNU Public License, version 2 or at your option any later version. Read the file gpl.txt for details. */ #ifndef BALLER_PATHS_H #define BALLER_PATHS_H extern void Paths_Init(const char *argv0); extern const char *Paths_GetWorkingDir(void); extern const char *Paths_GetDataDir(void); extern const char *Paths_GetLocaleDir(void); extern const char *Paths_GetUserHome(void); extern const char *Paths_GetProgHome(void); #endif ballerburg-1.0.1/src/ballergui.c0000644000175000017500000000461612145514531016113 0ustar thomasthomas/* ballergui.c - GUI related functions for Ballerburg Copyright (C) 2010, 2013 Thomas Huth This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "i18n.h" #include "baller1.h" #include "ballergui.h" #include "screen.h" #include "settings.h" static int gui_handle_keys(SDL_Event *ev, int allow_dlgs) { static bool in_table = false; switch (ev->key.keysym.sym) { case SDLK_ESCAPE: if (allow_dlgs) return settings(); break; case SDLK_f: SDL_WM_ToggleFullScreen(surf); break; case SDLK_t: if (in_table || !allow_dlgs) break; in_table = true; tabelle(); in_table = false; break; case SDLK_q: return DlgAlert_Query(_("Quit Ballerburg?"), _("Yes"), _("No")); default: break; } return 0; } int event(int wait, int allow_dlgs) { int ev_avail; SDL_Event ev; static bool quitflag = false; // printf("event(%i)\n", wait); if (quitflag) return 1; if (wait) ev_avail = SDL_WaitEvent(&ev); else ev_avail = SDL_PollEvent(&ev); while (ev_avail) { // printf("EVENT = %i\n", ev.type); switch(ev.type) { case SDL_QUIT: quitflag = true; return 1; case SDL_MOUSEMOTION: /* Read/Update internal mouse position */ mx = ev.motion.x; my = ev.motion.y; break; case SDL_MOUSEBUTTONDOWN: if (ev.button.button == SDL_BUTTON_LEFT) { bt |= 1; } else if (ev.button.button == SDL_BUTTON_RIGHT) { bt |= 2; } break; case SDL_MOUSEBUTTONUP: if (ev.button.button == SDL_BUTTON_LEFT) { bt &= ~1; } else if (ev.button.button == SDL_BUTTON_RIGHT) { bt &= ~2; } break; case SDL_KEYUP: if (gui_handle_keys(&ev, allow_dlgs)) { quitflag = true; return 1; } break; } ev_avail = SDL_PollEvent(&ev); } return 0; } ballerburg-1.0.1/src/psg.h0000644000175000017500000000340012145514531014731 0ustar thomasthomas/* * libpsg - a simple YM-2149 soundchip emulation library. * * Copyright (C) 2000 Stefan Berndtsson (NoCrew) * Copyright (C) 2011 Thomas Huth * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #ifndef PSG_H #define PSG_H #define SND_MONO 0 #define SND_STEREO 1 struct sndconfig { int mode; int bits; int freq; }; struct spsg { int regs[15]; int env_kept; struct sndconfig output; }; typedef struct spsg psg; /** * PSG *psg_init(int mode, int bits, int freq) * Action: * setup all internal variables. * Parameters: * mode - mono/stereo * bits - 8/16 * freq - frequency for audio output * Return: * psg - empty struct for you to use */ psg *psg_init(int, int, int); /** * psg_create_samples(void *output_buffer, * psg *psg_struct, * int usec); * Action: * builds a sample of length 'usec' into 'output_buffer' * from 'psg_struct' * Parameters: * buffer - allocated output buffer of suitable size * psg_struct - psg as returned from psg_init() * samples - amount of samples to produce * Return: * int - 0 if things go ok */ int psg_create_samples(void *buffer, psg *psgstruct, int samples); void psg_audio_init(void); unsigned int Giaccess(unsigned int data, unsigned int reg); void Dosound(const unsigned char *buf); #endif /* PSG_H */ ballerburg-1.0.1/src/settings.h0000644000175000017500000000005612145514532016005 0ustar thomasthomas int settings(void); void dlg_new_game(void); ballerburg-1.0.1/src/dlgAlert.c0000644000175000017500000001321112145514531015672 0ustar thomasthomas/* * dlgAlert.c - AES-like AlertBox * * Copyright (c) 2004 Petr Stehlik * Copyright (c) 2004, 2010 Thomas Huth * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This file is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * (http://www.gnu.org/licenses/) for more details. */ const char DlgAlert_fileid[] = "dlgAlert.c : " __DATE__ " " __TIME__; #include #include #include "sdlgui.h" #include "screen.h" #define MAX_LINES 4 static char dlglines[MAX_LINES][50+1]; #define DLGALERT_OK 5 #define DLGALERT_CANCEL 6 /* The "Alert"-dialog: */ static SGOBJ alertdlg[] = { { SGBOX, 0, 0, 0,0, 52,8, NULL }, { SGTEXT, 0, 0, 1,1, 50,1, dlglines[0] }, { SGTEXT, 0, 0, 1,2, 50,1, dlglines[1] }, { SGTEXT, 0, 0, 1,3, 50,1, dlglines[2] }, { SGTEXT, 0, 0, 1,4, 50,1, dlglines[3] }, { SGBUTTON, SG_DEFAULT, 0, 5,6, 8,1, "OK" }, { SGBUTTON, SG_CANCEL, 0, 24,6, 8,1, "Cancel" }, { -1, 0, 0, 0,0, 0,0, NULL } }; /*-----------------------------------------------------------------------*/ /** * Breaks long string to several strings of max_width, divided by '\0', * sets text_width to the longest line width and returns the number of lines * you need to display the strings. */ static int DlgAlert_FormatTextToBox(char *text, int max_width, int *text_width) { int columns = 0; int lines = 1; int txtlen; char *p; /* pointer to begin of actual line */ char *q; /* pointer to start of next search */ char *llb; /* pointer to last place suitable for breaking the line */ char *txtend; /* pointer to end of the text */ txtlen = strlen(text); q = p = text; llb = text-1; /* pointer to last line break */ txtend = text + txtlen; if (txtlen <= max_width && strchr(text, '\n') == NULL) { *text_width = txtlen; return lines; } while(q < txtend) /* q was last place suitable for breaking */ { char *r = strpbrk(q, " \t/\\\n"); /* find next suitable place for the break */ if (r == NULL) r = txtend; /* if there's no place then point to the end */ if ((r-p) <= max_width && *r != '\n') /* '\n' is always used for breaking */ { llb = r; /* remember new place suitable for breaking */ q++; if ((r-p) > columns) columns = r - p; continue; /* search again */ } if ((r-p) > max_width) /* too long line already? */ { if (p > llb) /* bad luck - no place for the delimiter. Let's do it the strong way */ llb = p + max_width; /* we loose one character */ } else llb = r; /* break from previous delimiter */ *llb = '\0'; /* BREAK */ if ((llb-p) > columns) columns = llb - p; /* longest line so far */ p = q = llb + 1; /* next line begins here */ lines++; /* increment line counter */ } *text_width = columns; return lines; /* return line counter */ } /*-----------------------------------------------------------------------*/ /** * Show the "alert" dialog. Return true if user pressed "OK". */ static int DlgAlert_ShowDlg(const char *text) { static int maxlen = sizeof(dlglines[0])-1; char *t = (char *)malloc(strlen(text)+1); char *orig_t = t; int lines, i, len, offset; bool bOldMouseVisibility; int nOldMouseX, nOldMouseY; strcpy(t, text); lines = DlgAlert_FormatTextToBox(t, maxlen, &len); offset = (maxlen-len)/2; for(i=0; i. */ #include extern SDL_Surface *surf; void v_pline(short handle, short num, short xy[]); void v_fillarea(short handle, short num, short xy[]); void v_circle(int handle, int x, int y, int w); void v_bar(short handle, short *xy); void clr(short x, short y, short w, short h); void clr_bg(short x, short y, short w, short h); void vsf_interior(short handle, short val); void v_gtext(int handle, int x, int y, const char *text); void vsf_style(short handle, short val); void scr_init(void); void scr_clear(void); void scr_line(int x1, int y1, int x2, int y2, int rgba); int scr_getpixel(int x, int y); void scr_color(int c); void scr_fillcolor(int c); void color(int a); void scr_init_done_button(int *bx, int *by, int *bw, int *bh); void scr_draw_done_button(int selected); void scr_ctr_text(int cx, int y, const char *text); void scr_cannonball(int x, int y); void *scr_save_bg(int x, int y, int w, int h); void scr_restore_bg(void *ps); int DlgAlert_Notice(const char *text, const char *button); int DlgAlert_Query(const char *text, const char *button1, const char *button2); ballerburg-1.0.1/src/font8x16.h0000644000175000017500000006213312145514531015545 0ustar thomasthomas#define font8x16_width 128 #define font8x16_height 256 static char font8x16_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x00, 0x00, 0x3C, 0xFF, 0xE7, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0xFF, 0xFF, 0x00, 0x24, 0x24, 0x00, 0x00, 0x3C, 0xFF, 0xE7, 0x00, 0x00, 0x00, 0x00, 0x24, 0x24, 0x81, 0x81, 0x00, 0x24, 0x24, 0x1C, 0x38, 0xBD, 0xFF, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x81, 0x81, 0x00, 0x24, 0x24, 0x34, 0x2C, 0x99, 0xFF, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x42, 0x5A, 0x81, 0xA1, 0x00, 0x42, 0x24, 0x27, 0xE4, 0xC3, 0x7F, 0x99, 0x00, 0x00, 0x00, 0x00, 0x42, 0x5A, 0x81, 0xA1, 0x00, 0x42, 0x24, 0x41, 0x82, 0xC3, 0x7F, 0xBD, 0x00, 0x00, 0x00, 0x00, 0x81, 0xBD, 0x81, 0xA1, 0x00, 0x42, 0x66, 0x81, 0x81, 0xE7, 0x3F, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x81, 0xBD, 0x81, 0xA1, 0x00, 0x66, 0x42, 0x81, 0x81, 0xE7, 0x3F, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x81, 0xBD, 0x81, 0x91, 0x00, 0x24, 0x42, 0x41, 0x82, 0xC3, 0x9F, 0xBD, 0x00, 0x00, 0x00, 0x00, 0x81, 0xBD, 0x81, 0x91, 0x00, 0x24, 0x42, 0x27, 0xE4, 0xC3, 0x9F, 0x99, 0x00, 0x00, 0x00, 0x00, 0x42, 0x5A, 0x81, 0x95, 0x00, 0x24, 0x24, 0x34, 0x2C, 0x99, 0xCF, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x42, 0x5A, 0x81, 0x95, 0x00, 0x24, 0x24, 0x1C, 0x38, 0xBD, 0xCF, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x81, 0x89, 0x00, 0x24, 0x24, 0x00, 0x00, 0x3C, 0xE7, 0xE7, 0x00, 0x00, 0x00, 0x00, 0x24, 0x24, 0x81, 0x81, 0x00, 0x3C, 0x18, 0x00, 0x00, 0x3C, 0xE7, 0xE7, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x24, 0x00, 0x10, 0x00, 0x1C, 0x10, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x24, 0x50, 0x3C, 0x4C, 0x34, 0x10, 0x30, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x10, 0x24, 0x50, 0x52, 0x52, 0x24, 0x10, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x10, 0x24, 0x50, 0x12, 0x32, 0x14, 0x10, 0x08, 0x10, 0x24, 0x18, 0x00, 0x00, 0x00, 0x20, 0x00, 0x10, 0x00, 0xFC, 0x12, 0x2C, 0x0C, 0x00, 0x04, 0x20, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x30, 0x00, 0x10, 0x00, 0x28, 0x3C, 0x30, 0x0C, 0x00, 0x04, 0x20, 0x7E, 0x7E, 0x00, 0x7E, 0x00, 0x30, 0x00, 0x10, 0x00, 0x28, 0x50, 0x10, 0x1A, 0x00, 0x04, 0x20, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x10, 0x00, 0x7E, 0x50, 0x78, 0xF2, 0x00, 0x08, 0x10, 0x24, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14, 0x52, 0xA8, 0x22, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x38, 0x0C, 0x00, 0x10, 0x00, 0x14, 0x3C, 0x94, 0x76, 0x00, 0x30, 0x0C, 0x00, 0x00, 0x38, 0x00, 0x38, 0x04, 0x00, 0x10, 0x00, 0x00, 0x10, 0x64, 0xDC, 0x00, 0x20, 0x04, 0x00, 0x00, 0x38, 0x00, 0x38, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x3C, 0x3C, 0x00, 0x7E, 0x3C, 0x7E, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x18, 0x24, 0x24, 0x20, 0x02, 0x24, 0x40, 0x24, 0x24, 0x00, 0x00, 0x20, 0x00, 0x04, 0x24, 0x24, 0x14, 0x42, 0x42, 0x30, 0x02, 0x02, 0x40, 0x42, 0x42, 0x00, 0x00, 0x10, 0x7E, 0x08, 0x42, 0x24, 0x12, 0x42, 0x42, 0x28, 0x02, 0x02, 0x20, 0x42, 0x42, 0x00, 0x00, 0x08, 0x7E, 0x10, 0x42, 0x42, 0x10, 0x40, 0x20, 0x24, 0x3A, 0x3A, 0x20, 0x24, 0x42, 0x30, 0x30, 0x04, 0x00, 0x20, 0x20, 0x42, 0x10, 0x20, 0x38, 0x22, 0x26, 0x26, 0x10, 0x3C, 0x64, 0x30, 0x30, 0x02, 0x00, 0x40, 0x10, 0x42, 0x10, 0x38, 0x20, 0x22, 0x40, 0x42, 0x10, 0x24, 0x5C, 0x00, 0x00, 0x04, 0x00, 0x20, 0x08, 0x42, 0x10, 0x0C, 0x40, 0x7E, 0x40, 0x42, 0x08, 0x42, 0x40, 0x00, 0x00, 0x08, 0x7E, 0x10, 0x08, 0x24, 0x10, 0x02, 0x42, 0x20, 0x42, 0x42, 0x08, 0x42, 0x40, 0x00, 0x00, 0x10, 0x7E, 0x08, 0x00, 0x24, 0x10, 0x02, 0x24, 0x20, 0x24, 0x24, 0x04, 0x24, 0x24, 0x30, 0x30, 0x20, 0x00, 0x04, 0x08, 0x18, 0x7E, 0x7E, 0x3C, 0x20, 0x3C, 0x3C, 0x04, 0x3C, 0x3C, 0x30, 0x30, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x18, 0x1E, 0x3C, 0x3E, 0x7E, 0x7E, 0x3C, 0x42, 0x7C, 0xF8, 0x42, 0x02, 0x42, 0x42, 0x3C, 0x24, 0x3C, 0x32, 0x24, 0x22, 0x02, 0x02, 0x24, 0x42, 0x10, 0x20, 0x42, 0x02, 0x42, 0x46, 0x24, 0x42, 0x24, 0x22, 0x42, 0x42, 0x02, 0x02, 0x42, 0x42, 0x10, 0x20, 0x22, 0x02, 0x66, 0x46, 0x42, 0x72, 0x24, 0x22, 0x02, 0x42, 0x02, 0x02, 0x02, 0x42, 0x10, 0x20, 0x22, 0x02, 0x66, 0x4A, 0x42, 0x5A, 0x42, 0x32, 0x02, 0x42, 0x02, 0x02, 0x02, 0x42, 0x10, 0x20, 0x12, 0x02, 0x5A, 0x4A, 0x42, 0x4A, 0x42, 0x1E, 0x02, 0x42, 0x3E, 0x3E, 0x72, 0x7E, 0x10, 0x20, 0x1E, 0x02, 0x5A, 0x52, 0x42, 0x4A, 0x7E, 0x22, 0x02, 0x42, 0x02, 0x02, 0x42, 0x42, 0x10, 0x20, 0x12, 0x02, 0x42, 0x52, 0x42, 0x3A, 0x42, 0x42, 0x02, 0x42, 0x02, 0x02, 0x42, 0x42, 0x10, 0x20, 0x22, 0x02, 0x42, 0x62, 0x42, 0x02, 0x42, 0x42, 0x42, 0x42, 0x02, 0x02, 0x42, 0x42, 0x10, 0x22, 0x22, 0x02, 0x42, 0x62, 0x42, 0x44, 0x42, 0x22, 0x24, 0x22, 0x02, 0x02, 0x64, 0x42, 0x10, 0x24, 0x42, 0x02, 0x42, 0x42, 0x24, 0x3C, 0x42, 0x3E, 0x3C, 0x3E, 0x7E, 0x02, 0x3C, 0x42, 0x7C, 0x18, 0x42, 0x7E, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x3C, 0x3E, 0x3C, 0x7C, 0x42, 0x42, 0x42, 0x42, 0x44, 0x7E, 0x3C, 0x00, 0x3C, 0x18, 0x00, 0x22, 0x24, 0x22, 0x24, 0x10, 0x42, 0x42, 0x42, 0x42, 0x44, 0x40, 0x04, 0x04, 0x20, 0x3C, 0x00, 0x42, 0x42, 0x42, 0x42, 0x10, 0x42, 0x42, 0x42, 0x24, 0x28, 0x40, 0x04, 0x04, 0x20, 0x24, 0x00, 0x42, 0x42, 0x42, 0x02, 0x10, 0x42, 0x42, 0x42, 0x24, 0x28, 0x20, 0x04, 0x0C, 0x20, 0x42, 0x00, 0x42, 0x42, 0x42, 0x04, 0x10, 0x42, 0x24, 0x42, 0x24, 0x38, 0x30, 0x04, 0x18, 0x20, 0x00, 0x00, 0x22, 0x42, 0x22, 0x3C, 0x10, 0x42, 0x24, 0x42, 0x18, 0x10, 0x18, 0x04, 0x18, 0x20, 0x00, 0x00, 0x3E, 0x42, 0x1E, 0x20, 0x10, 0x42, 0x24, 0x5A, 0x18, 0x10, 0x0C, 0x04, 0x30, 0x20, 0x00, 0x00, 0x02, 0x42, 0x12, 0x40, 0x10, 0x42, 0x24, 0x5A, 0x24, 0x10, 0x04, 0x04, 0x30, 0x20, 0x00, 0x00, 0x02, 0x72, 0x22, 0x42, 0x10, 0x42, 0x18, 0x66, 0x24, 0x10, 0x02, 0x04, 0x20, 0x20, 0x00, 0x00, 0x02, 0x24, 0x42, 0x24, 0x10, 0x24, 0x18, 0x42, 0x42, 0x10, 0x02, 0x04, 0x40, 0x20, 0x00, 0x00, 0x02, 0x7C, 0x42, 0x3C, 0x10, 0x3C, 0x18, 0x42, 0x42, 0x10, 0x7E, 0x3C, 0x40, 0x3C, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x02, 0x00, 0x40, 0x00, 0x38, 0x00, 0x02, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x02, 0x00, 0x40, 0x00, 0x4C, 0x00, 0x02, 0x10, 0x40, 0x02, 0x10, 0x00, 0x00, 0x00, 0x30, 0x00, 0x02, 0x00, 0x40, 0x00, 0x44, 0x00, 0x02, 0x10, 0x40, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x40, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x3A, 0x3C, 0x5C, 0x3C, 0x3E, 0x7C, 0x3A, 0x18, 0x70, 0x22, 0x10, 0x2C, 0x3A, 0x3C, 0x00, 0x44, 0x26, 0x44, 0x64, 0x24, 0x04, 0x22, 0x26, 0x10, 0x40, 0x12, 0x10, 0x5A, 0x26, 0x24, 0x00, 0x40, 0x42, 0x02, 0x42, 0x42, 0x04, 0x22, 0x42, 0x10, 0x40, 0x0A, 0x10, 0x4A, 0x42, 0x42, 0x00, 0x7C, 0x42, 0x02, 0x42, 0x7E, 0x04, 0x22, 0x42, 0x10, 0x40, 0x0E, 0x10, 0x4A, 0x42, 0x42, 0x00, 0x42, 0x42, 0x02, 0x42, 0x02, 0x04, 0x3C, 0x42, 0x10, 0x40, 0x12, 0x10, 0x4A, 0x42, 0x42, 0x00, 0x42, 0x26, 0x44, 0x64, 0x44, 0x04, 0x02, 0x42, 0x10, 0x40, 0x22, 0x10, 0x4A, 0x42, 0x24, 0x00, 0x7C, 0x3A, 0x3C, 0x5C, 0x3C, 0x04, 0x3C, 0x42, 0x7E, 0x40, 0x42, 0x7C, 0x4A, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x10, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x10, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x10, 0x4C, 0x00, 0x3A, 0x5C, 0x3A, 0x3C, 0x3E, 0x42, 0x42, 0x42, 0x42, 0x42, 0x7C, 0x08, 0x10, 0x10, 0x5A, 0x00, 0x26, 0x64, 0x4C, 0x42, 0x04, 0x42, 0x42, 0x42, 0x24, 0x42, 0x40, 0x0E, 0x10, 0x70, 0x32, 0x00, 0x42, 0x42, 0x04, 0x02, 0x04, 0x42, 0x24, 0x42, 0x24, 0x42, 0x20, 0x08, 0x10, 0x10, 0x00, 0x00, 0x42, 0x42, 0x04, 0x3C, 0x04, 0x42, 0x24, 0x5A, 0x18, 0x42, 0x30, 0x08, 0x10, 0x10, 0x00, 0x00, 0x42, 0x42, 0x04, 0x40, 0x04, 0x42, 0x24, 0x5A, 0x24, 0x42, 0x0C, 0x18, 0x10, 0x18, 0x00, 0x00, 0x26, 0x64, 0x04, 0x42, 0x4C, 0x64, 0x18, 0x66, 0x24, 0x64, 0x04, 0x10, 0x10, 0x08, 0x00, 0x00, 0x3A, 0x5C, 0x04, 0x3C, 0x38, 0x5C, 0x18, 0x24, 0x42, 0x5C, 0x7C, 0x70, 0x10, 0x0E, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x24, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x38, 0x00, 0x00, 0x18, 0x24, 0x24, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x4C, 0x00, 0x42, 0x18, 0x22, 0x00, 0x3C, 0x40, 0x50, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x18, 0x3C, 0x4C, 0x41, 0x42, 0x18, 0x04, 0x00, 0x24, 0x7C, 0x58, 0x00, 0x00, 0x24, 0x00, 0x00, 0x18, 0x02, 0x0C, 0x3E, 0x3C, 0x00, 0x32, 0x00, 0x7E, 0x42, 0x34, 0x7E, 0x00, 0x7E, 0x00, 0x00, 0x18, 0x02, 0x3E, 0x22, 0x3C, 0x00, 0x24, 0x00, 0x66, 0x7C, 0x1A, 0x7E, 0x3C, 0x66, 0x00, 0x00, 0x18, 0x02, 0x0C, 0x22, 0x18, 0x00, 0x4C, 0x00, 0x46, 0x00, 0x0F, 0x40, 0x00, 0x7E, 0x00, 0x00, 0x18, 0x02, 0x0C, 0x22, 0x3C, 0x18, 0x38, 0x00, 0x66, 0x7E, 0x1A, 0x40, 0x00, 0x56, 0x00, 0x00, 0x18, 0x3C, 0x1E, 0x5F, 0x18, 0x18, 0x44, 0x00, 0x42, 0x00, 0x2C, 0x00, 0x00, 0x42, 0x00, 0x00, 0x18, 0x18, 0xF6, 0x41, 0x18, 0x18, 0x24, 0x00, 0x24, 0x00, 0x58, 0x00, 0x00, 0x24, 0x00, 0x00, 0x18, 0x18, 0x66, 0x00, 0x18, 0x18, 0x3C, 0x00, 0x3C, 0x00, 0x50, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x1C, 0x1C, 0x30, 0x00, 0x7C, 0x00, 0x00, 0x0C, 0x1C, 0x00, 0x00, 0x00, 0x06, 0x18, 0x3C, 0x00, 0x34, 0x34, 0x18, 0x00, 0x7E, 0x00, 0x00, 0x0C, 0x34, 0x00, 0x02, 0x02, 0x08, 0x18, 0x24, 0x00, 0x30, 0x30, 0x0C, 0x00, 0x5E, 0x00, 0x00, 0x0C, 0x22, 0x0A, 0x00, 0x00, 0x04, 0x00, 0x24, 0x00, 0x18, 0x18, 0x00, 0x00, 0x5E, 0x00, 0x00, 0x0C, 0x22, 0x1A, 0x20, 0x20, 0x28, 0x18, 0x18, 0x18, 0x04, 0x34, 0x00, 0x00, 0x5C, 0x38, 0x00, 0x0C, 0x34, 0x2C, 0x10, 0x10, 0x14, 0x18, 0x00, 0x7E, 0x3C, 0x1C, 0x00, 0x22, 0x58, 0x38, 0x00, 0x1C, 0x1C, 0x58, 0x08, 0x28, 0x08, 0x0C, 0x00, 0x18, 0x00, 0x00, 0x00, 0x22, 0x58, 0x38, 0x00, 0x00, 0x00, 0xF0, 0x24, 0x54, 0x24, 0x04, 0x00, 0x18, 0x00, 0x00, 0x00, 0x22, 0x58, 0x00, 0x00, 0x00, 0x3E, 0x58, 0x10, 0x40, 0x10, 0x42, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x22, 0x58, 0x00, 0x00, 0x00, 0x00, 0x34, 0x30, 0x20, 0x30, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x58, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x70, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x58, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x20, 0x18, 0x0C, 0x24, 0x24, 0x00, 0x00, 0x06, 0x30, 0x18, 0x24, 0x0C, 0x30, 0x18, 0x24, 0x18, 0x18, 0x24, 0x30, 0x00, 0x18, 0x78, 0x3C, 0x18, 0x0C, 0x24, 0x24, 0x30, 0x0C, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x3C, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x18, 0x34, 0x42, 0x7E, 0x7E, 0x7E, 0x7E, 0x7C, 0x7C, 0x7C, 0x7C, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x34, 0x02, 0x02, 0x02, 0x02, 0x02, 0x10, 0x10, 0x10, 0x10, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x32, 0x02, 0x02, 0x02, 0x02, 0x02, 0x10, 0x10, 0x10, 0x10, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x7E, 0x02, 0x02, 0x02, 0x02, 0x02, 0x10, 0x10, 0x10, 0x10, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x32, 0x02, 0x3E, 0x3E, 0x3E, 0x3E, 0x10, 0x10, 0x10, 0x10, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x32, 0x02, 0x02, 0x02, 0x02, 0x02, 0x10, 0x10, 0x10, 0x10, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x32, 0x42, 0x02, 0x02, 0x02, 0x02, 0x10, 0x10, 0x10, 0x10, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x32, 0x24, 0x02, 0x02, 0x02, 0x02, 0x10, 0x10, 0x10, 0x10, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x72, 0x3C, 0x7E, 0x7E, 0x7E, 0x7E, 0x7C, 0x7C, 0x7C, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x30, 0x18, 0x0C, 0x24, 0x00, 0x00, 0x0C, 0x30, 0x18, 0x24, 0x60, 0x00, 0x00, 0x3E, 0x30, 0x30, 0x0C, 0x24, 0x30, 0x00, 0x00, 0x3C, 0x30, 0x0C, 0x24, 0x00, 0x18, 0x04, 0x38, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x24, 0x00, 0x00, 0x00, 0x42, 0x00, 0x04, 0x44, 0x42, 0x42, 0x3C, 0x3C, 0x3C, 0x3C, 0x24, 0x00, 0x62, 0x42, 0x42, 0x42, 0x42, 0x44, 0x04, 0x44, 0x42, 0x46, 0x24, 0x24, 0x24, 0x24, 0x42, 0x00, 0x62, 0x42, 0x42, 0x42, 0x42, 0x44, 0x3C, 0x44, 0x42, 0x46, 0x42, 0x42, 0x42, 0x42, 0x42, 0x02, 0x52, 0x42, 0x42, 0x42, 0x42, 0x28, 0x44, 0x26, 0x4F, 0x4A, 0x42, 0x42, 0x42, 0x42, 0x42, 0x22, 0x52, 0x42, 0x42, 0x42, 0x42, 0x28, 0x44, 0x14, 0x42, 0x4A, 0x42, 0x42, 0x42, 0x42, 0x42, 0x34, 0x4A, 0x42, 0x42, 0x42, 0x42, 0x10, 0x44, 0x24, 0x42, 0x52, 0x42, 0x42, 0x42, 0x42, 0x42, 0x1C, 0x4A, 0x42, 0x42, 0x42, 0x42, 0x10, 0x44, 0x44, 0x42, 0x52, 0x42, 0x42, 0x42, 0x42, 0x42, 0x34, 0x46, 0x42, 0x42, 0x42, 0x42, 0x10, 0x04, 0x44, 0x22, 0x62, 0x24, 0x24, 0x24, 0x24, 0x24, 0x22, 0x24, 0x24, 0x24, 0x24, 0x24, 0x10, 0x04, 0x34, 0x3E, 0x62, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x02, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x10, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x20, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x04, 0x20, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00, 0x0C, 0x30, 0x18, 0x28, 0x24, 0x24, 0x00, 0x00, 0x0C, 0x30, 0x18, 0x24, 0x18, 0x30, 0x18, 0x24, 0x18, 0x18, 0x24, 0x14, 0x24, 0x18, 0x00, 0x00, 0x18, 0x18, 0x24, 0x24, 0x30, 0x18, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x2C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x5A, 0x44, 0x24, 0x24, 0x24, 0x24, 0x10, 0x10, 0x10, 0x10, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x58, 0x02, 0x42, 0x42, 0x42, 0x42, 0x10, 0x10, 0x10, 0x10, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x3C, 0x02, 0x7E, 0x7E, 0x7E, 0x7E, 0x10, 0x10, 0x10, 0x10, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x1A, 0x02, 0x02, 0x02, 0x02, 0x02, 0x10, 0x10, 0x10, 0x10, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x5A, 0x44, 0x44, 0x44, 0x44, 0x44, 0x10, 0x10, 0x10, 0x10, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x34, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x7E, 0x7E, 0x7E, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x1A, 0x28, 0x0C, 0x30, 0x18, 0x28, 0x24, 0x00, 0x00, 0x04, 0x20, 0x18, 0x24, 0x60, 0x04, 0x24, 0x0C, 0x14, 0x18, 0x18, 0x24, 0x14, 0x24, 0x18, 0x00, 0x0C, 0x30, 0x24, 0x24, 0x30, 0x04, 0x24, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x04, 0x00, 0x32, 0x3A, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x04, 0x42, 0x3C, 0x26, 0x24, 0x24, 0x24, 0x24, 0x24, 0x7E, 0x24, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x42, 0x64, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x7E, 0x52, 0x42, 0x42, 0x42, 0x42, 0x42, 0x24, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x52, 0x42, 0x42, 0x42, 0x42, 0x42, 0x44, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x18, 0x4A, 0x42, 0x42, 0x42, 0x42, 0x42, 0x44, 0x42, 0x24, 0x42, 0x24, 0x24, 0x24, 0x24, 0x24, 0x18, 0x24, 0x64, 0x64, 0x64, 0x64, 0x64, 0x24, 0x64, 0x3C, 0x42, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x3C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x3C, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x40, 0x04, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x04, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x04, 0x3C, }; ballerburg-1.0.1/src/ballergui.h0000644000175000017500000000007412145514531016112 0ustar thomasthomas int event(int wait, int allow_dlgs); int sch_obj(short k); ballerburg-1.0.1/src/i18n.h0000644000175000017500000000054712145514531014730 0ustar thomasthomas #ifndef BALLER_I18N_H #define BALLER_I18N_H #include #if HAVE_LIBINTL_H #include #define _(string) ((string)[0]?gettext(string):(string)) #define gettext_noop(string) string #define N_(string) gettext_noop(string) #else #define _(string) (string) #define N_(string) string #endif /* HAVE_GETTEXT */ #endif /* BALLER_I18N_H */ ballerburg-1.0.1/src/settings.c0000644000175000017500000002075412145514532016007 0ustar thomasthomas/* settings.c Copyright (C) 2011 Thomas Huth This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "i18n.h" #include "ballergui.h" #include "baller1.h" #include "baller2.h" #include "sdlgui.h" #include "screen.h" #include "settings.h" #define P1_HUMAN 6 #define P1_COMPUTER 7 #define P1_AISTRATEGYLEFT 10 #define P1_AISTRATEGYSTR 11 #define P1_AISTRATEGYRIGHT 12 #define P1_AISTRENGTHLEFT 15 #define P1_AISTRENGTHSTR 16 #define P1_AISTRENGTHRIGHT 17 #define P2_HUMAN 22 #define P2_COMPUTER 23 #define P2_AISTRATEGYLEFT 26 #define P2_AISTRATEGYSTR 27 #define P2_AISTRATEGYRIGHT 28 #define P2_AISTRENGTHLEFT 31 #define P2_AISTRENGTHSTR 32 #define P2_AISTRENGTHRIGHT 33 #define ROUNDS_20 35 #define ROUNDS_50 36 #define ROUNDS_100 37 #define ROUNDS_NOLIMIT 38 #define GIVEUPALLOWED 39 #define REPAIRALLOWED 40 #define NEWGAME 41 #define CONTINUE 42 #define QUITGAME 43 static char dlg_p1level[2] = "2"; static char dlg_p2level[2] = "3"; static SGOBJ settingsdlg[] = { { SGBOX, 0, 0, 0,0, 71,22, NULL }, { SGTEXT, 0, 0, 27,1, 13,1, N_("Settings") }, { SGBOX, 0, 0, 1,3, 34,11, NULL }, { SGTEXT, 0, 0, 12,4, 9,1, N_("Player 1") }, { SGTEXT, 0, 0, 3,6, 5,1, N_("Name:") }, { SGEDITFIELD, 0, 0, 9,6, 22,1, nsp1 }, { SGRADIOBUT, 0, SG_SELECTED, 3,8, 8,1, N_("Human") }, { SGRADIOBUT, 0, 0, 15,8, 10,1, N_("Computer") }, { SGTEXT, 0, 0, 3,10, 15,1, N_("AI strategy:") }, { SGBOX, 0, 0, 19,10, 15,1, NULL }, { SGBUTTON, SG_EXIT, 0, 19,10, 2,1, SGARROWLEFTSTR }, { SGTEXT, 0, 0, 22,10, 8,1, NULL }, { SGBUTTON, SG_EXIT, 0, 32,10, 2,1, SGARROWRIGHTSTR }, { SGTEXT, 0, 0, 3,12, 15,1, N_("AI strength:") }, { SGBOX, 0, 0, 23,12, 7,1, NULL }, { SGBUTTON, SG_EXIT, 0, 23,12, 2,1, SGARROWLEFTSTR }, { SGTEXT, 0, 0, 26,12, 1,1, dlg_p1level }, { SGBUTTON, SG_EXIT, 0, 28,12, 2,1, SGARROWRIGHTSTR }, { SGBOX, 0, 0, 36,3, 34,11, NULL }, { SGTEXT, 0, 0, 47,4, 9,1, N_("Player 2") }, { SGTEXT, 0, 0, 38,6, 5,1, N_("Name:") }, { SGEDITFIELD, 0, 0, 44,6, 22,1, nsp2 }, { SGRADIOBUT, 0, SG_SELECTED, 38,8, 8,1, N_("Human") }, { SGRADIOBUT, 0, 0, 50,8, 10,1, N_("Computer") }, { SGTEXT, 0, 0, 38,10, 15,1, N_("AI strategy:") }, { SGBOX, 0, 0, 54,10, 15,1, NULL }, { SGBUTTON, SG_EXIT, 0, 54,10, 2,1, SGARROWLEFTSTR }, { SGTEXT, 0, 0, 57,10, 8,1, NULL }, { SGBUTTON, SG_EXIT, 0, 67,10, 2,1, SGARROWRIGHTSTR }, { SGTEXT, 0, 0, 38,12, 15,1, N_("AI strength:") }, { SGBOX, 0, 0, 58,12, 7,1, NULL }, { SGBUTTON, SG_EXIT, 0, 58,12, 2,1, SGARROWLEFTSTR }, { SGTEXT, 0, 0, 61,12, 1,1, dlg_p2level }, { SGBUTTON, SG_EXIT, 0, 63,12, 2,1, SGARROWRIGHTSTR }, { SGTEXT, 0, 0, 3,15, 20,1, N_("Maximum rounds:") }, { SGRADIOBUT, 0, 0, 25,15, 4,1, "20" }, { SGRADIOBUT, 0, 0, 31,15, 4,1, "50" }, { SGRADIOBUT, 0, 0, 37,15, 5,1, "100" }, { SGRADIOBUT, 0, SG_SELECTED, 44,15, 12,1, N_("unlimited") }, { SGCHECKBOX, 0, SG_SELECTED, 3,17, 26,1, N_("King may capitulate") }, { SGCHECKBOX, 0, SG_SELECTED, 36,17, 22,1, N_("Players may build") }, { SGBUTTON, 0, 0, 2,20, 20,1, N_("New game") }, { SGBUTTON, SG_DEFAULT, 0, 24,20, 19,1, N_("Continue game") }, { SGBUTTON, 0, 0, 45,20, 20,1, N_("Exit program") }, { -1, 0, 0, 0,0, 0,0, NULL } }; /** * Settings dialog */ int settings(void) { int retbut; int done = 0; SDLGui_CenterDlg(settingsdlg); do { settingsdlg[P1_AISTRATEGYSTR].txt = (char *)cn[cw[0]]; settingsdlg[P2_AISTRATEGYSTR].txt = (char *)cn[cw[1]]; dlg_p1level[0] = '1' + cx[0]; dlg_p2level[0] = '1' + cx[1]; retbut = SDLGui_DoDialog(settingsdlg, NULL); switch (retbut) { case P1_AISTRATEGYLEFT: if (cw[0] > 0) cw[0] -= 1; break; case P1_AISTRATEGYRIGHT: if (cw[0] < 6) cw[0] += 1; break; case P1_AISTRENGTHLEFT: if (cx[0] > 0) cx[0] -= 1; break; case P1_AISTRENGTHRIGHT: if (cx[0] < 3) cx[0] += 1; break; case P2_AISTRATEGYLEFT: if (cw[1] > 0) cw[1] -= 1; break; case P2_AISTRATEGYRIGHT: if (cw[1] < 6) cw[1] += 1; break; case P2_AISTRENGTHLEFT: if (cx[1] > 0) cx[1] -= 1; break; case P2_AISTRENGTHRIGHT: if (cx[1] < 3) cx[1] += 1; break; default: done = 1; } } while (!done); SDL_UpdateRect(surf, 0,0, 0,0); if (settingsdlg[P1_HUMAN].state & SG_SELECTED) { if (settingsdlg[P2_HUMAN].state & SG_SELECTED) mod = 0; /* Human vs. human */ else mod = 1; /* Human vs. computer */ } else { if (settingsdlg[P2_HUMAN].state & SG_SELECTED) mod = 2; /* Computer vs. human */ else mod = 3; /* Computer vs. computer */ } if (mod < 2) l_nam = nsp1; else l_nam = cn[cw[0]]; if (mod & 1) r_nam = cn[cw[1]]; else r_nam = nsp2; /* Max. amount of rounds */ if (settingsdlg[ROUNDS_20].state & SG_SELECTED) max_rund = 20; else if (settingsdlg[ROUNDS_50].state & SG_SELECTED) max_rund = 50; else if (settingsdlg[ROUNDS_100].state & SG_SELECTED) max_rund = 100; else if (settingsdlg[ROUNDS_NOLIMIT].state & SG_SELECTED) max_rund = 32767; /* Is the king allowed to give up? */ au_kap = settingsdlg[GIVEUPALLOWED].state & SG_SELECTED; /* Is repairing allowed? */ an_erl = settingsdlg[REPAIRALLOWED].state & SG_SELECTED; /* New game? */ if (retbut == NEWGAME) { dlg_new_game(); } /* Quit game? */ else if (retbut == QUITGAME || retbut == SDLGUI_QUIT) { return DlgAlert_Query(_("Quit Ballerburg?"), _("Yes"), _("No")); } return 0; } /* ---------------------------------------------------------------- */ static void draw_castle1(int x, int y, int w, int h); static void draw_castle2(int x, int y, int w, int h); #define NEW_P1_PREV 3 #define NEW_P1_NEXT 4 #define NEW_P2_PREV 6 #define NEW_P2_NEXT 7 #define NEW_OK 8 #define NEW_ABORT 9 static SGOBJ newgamedlg[] = { { SGBOX, 0, 0, 0,0, 58,20, NULL }, { SGTEXT, 0, 0, 24,1, 12,1, N_("New game") }, { SGTEXT, 0, 0, 9,3, 23,1, N_("Player 1") }, { SGBUTTON, SG_EXIT, 0, 2,16, 12,1, "\x04" }, // Arrow left { SGBUTTON, SG_EXIT, 0, 16,16, 12,1, "\x03" }, // Arrow right { SGTEXT, 0, 0, 37,3, 23,1, N_("Player 2") }, { SGBUTTON, SG_EXIT, 0, 30,16, 12,1, "\x04" }, // Arrow left { SGBUTTON, SG_EXIT, 0, 44,16, 12,1, "\x03" }, // Arrow right { SGBUTTON, SG_DEFAULT, 0, 19,18, 8,1, "OK" }, { SGBUTTON, SG_CANCEL, 0, 31,18, 8,1, "Cancel" }, { SGBOX, 0, 0, 2,5, 26,10, NULL }, { SGUSER, 0, 0, 2,5, 26,10, (void*)draw_castle1 }, { SGBOX, 0, 0, 30,5, 26,10, NULL }, { SGUSER, 0, 0, 30,5, 26,10, (void*)draw_castle2 }, { -1, 0, 0, 0,0, 0,0, NULL } }; /** * Draw castle */ static void draw_castle(int n, int x, int y, int w, int h) { SDL_Rect rect; short oy0,oy1; rect.x = x + 1; rect.y = y + 1; rect.w = w - 2; rect.h = h - 2; SDL_FillRect(surf, &rect, SDL_MapRGB(surf->format,0xff,0xff,0xff)); oy0 = by[0]; oy1 = by[1]; bx[0]=x; by[0]=y+h; bx[1]=x+w; by[1]=y+h; burg(n+1); by[0]=oy0; by[1]=oy1; } static void draw_castle1(int x, int y, int w, int h) { draw_castle(1, x, y, w, h); } static void draw_castle2(int x, int y, int w, int h) { draw_castle(2, x, y, w, h); } /** * Dialog for "new game" */ void dlg_new_game(void) { int retbut; short ob0, ob1, ol[8]; /* Sichern der alten Werte */ ob0 = bur[0]; ob1 = bur[1]; ol[0]=ge[0]; ol[1]=ge[1]; ol[2]=pu[0]; ol[3]=pu[1]; ol[4]=ku[0]; ol[5]=ku[1]; ol[6]=vo[0]; ol[7]=vo[1]; SDLGui_CenterDlg(newgamedlg); do { retbut = SDLGui_DoDialog(newgamedlg, NULL); switch (retbut) { case NEW_P1_PREV: bur[0] = (bur[0] - 1 + b_anz) % b_anz; break; case NEW_P1_NEXT: bur[0] = (bur[0] + 1 + b_anz) % b_anz; break; case NEW_P2_PREV: bur[1] = (bur[1] - 1 + b_anz) % b_anz; break; case NEW_P2_NEXT: bur[1] = (bur[1] + 1 + b_anz) % b_anz; break; } } while (retbut != NEW_OK && retbut != NEW_ABORT); ge[0]=ol[0]; ge[1]=ol[1]; pu[0]=ol[2]; pu[1]=ol[3]; ku[0]=ol[4]; ku[1]=ol[5]; vo[0]=ol[6]; vo[1]=ol[7]; fn(); if (retbut == NEW_OK) { neues(); werdran(1); } else /* if (retbut == NEW_ABORT) */ { bur[0]=ob0; bur[1]=ob1; } SDL_UpdateRect(surf, 0,0, 0,0); } ballerburg-1.0.1/src/market.h0000644000175000017500000000140212145514531015423 0ustar thomasthomas/* market.h - prototypes and definitions for market.c Copyright (C) 2010 Thomas Huth This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ void markt(void); ballerburg-1.0.1/src/paths.c0000644000175000017500000001736712145514531015273 0ustar thomasthomas/* Ballerburg - paths.c This file is distributed under the GNU Public License, version 2 or at your option any later version. Read the file gpl.txt for details. Set up the various path strings. */ const char Paths_fileid[] = "Ballerburg paths.c : " __DATE__ " " __TIME__; #include #include #include #include #include #include #include #include "config.h" #include "paths.h" #if defined(WIN32) && !defined(mkdir) #define mkdir(name,mode) mkdir(name) #endif /* WIN32 */ #ifdef WIN32 #define PATHSEP '\\' #else #define PATHSEP '/' #endif static char sWorkingDir[FILENAME_MAX]; /* Working directory */ static char sDataDir[FILENAME_MAX]; /* Directory where data files can be found */ static char sLocaleDir[FILENAME_MAX]; /* Directory where locale files can be found */ static char sUserHomeDir[FILENAME_MAX]; /* User's home directory ($HOME) */ static char sProgHomeDir[FILENAME_MAX]; /* Program's home directory ($HOME/.config/ballerburg/) */ /** * Return pointer to current working directory string */ const char *Paths_GetWorkingDir(void) { return sWorkingDir; } /** * Return pointer to data directory string */ const char *Paths_GetDataDir(void) { return sDataDir; } /** * Return pointer to data directory string */ const char *Paths_GetLocaleDir(void) { return sLocaleDir; } /** * Return pointer to user's home directory string */ const char *Paths_GetUserHome(void) { return sUserHomeDir; } /** * Return pointer to program's home directory string */ const char *Paths_GetProgHome(void) { return sProgHomeDir; } /** * Return TRUE if file exists, is readable or writable at least and is not * a directory. */ static bool Paths_FileExists(const char *filename) { struct stat buf; if (stat(filename, &buf) == 0 && (buf.st_mode & (S_IRUSR|S_IWUSR)) && !(buf.st_mode & S_IFDIR)) { /* file points to user readable regular file */ return true; } return false; } /** * Return TRUE if directory exists. */ static bool Paths_DirExists(const char *path) { struct stat buf; return (stat(path, &buf) == 0 && S_ISDIR(buf.st_mode)); } /** * Explore the PATH environment variable to see where our executable is * installed. */ static void Paths_GetExecDirFromPATH(const char *argv0, char *pExecDir, int nMaxLen) { char *pPathEnv; char *pAct; char *pTmpName; const char *pToken; /* Get the PATH environment string */ pPathEnv = getenv("PATH"); if (!pPathEnv) return; /* Duplicate the string because strtok destroys it later */ pPathEnv = strdup(pPathEnv); if (!pPathEnv) return; pTmpName = malloc(FILENAME_MAX); if (!pTmpName) return; /* If there is a semicolon in the PATH, we assume it is the PATH * separator token (like on Windows), otherwise we use a colon. */ if (strchr((pPathEnv), ';')) pToken = ";"; else pToken = ":"; pAct = strtok (pPathEnv, pToken); while (pAct) { snprintf(pTmpName, FILENAME_MAX, "%s%c%s", pAct, PATHSEP, argv0); if (Paths_FileExists(pTmpName)) { /* Found the executable - so use the corresponding path: */ strncpy(pExecDir, pAct, nMaxLen); pExecDir[nMaxLen-1] = 0; break; } pAct = strtok (0, pToken); } free(pPathEnv); free(pTmpName); } /** * Locate the directory where the executable resides */ static char *Paths_InitExecDir(const char *argv0) { char *psExecDir; /* Path string where the executable can be found */ /* Allocate memory for storing the path string of the executable */ psExecDir = malloc(FILENAME_MAX); if (!psExecDir) { fprintf(stderr, "Out of memory (Paths_Init)\n"); exit(-1); } /* Determine the bindir... * Start with empty string, then try to use OS specific functions, * and finally analyze the PATH variable if it has not been found yet. */ psExecDir[0] = '\0'; #if defined(__linux__) { int i; /* On Linux, we can analyze the symlink /proc/self/exe */ i = readlink("/proc/self/exe", psExecDir, FILENAME_MAX); if (i > 0) { char *p; psExecDir[i] = '\0'; p = strrchr(psExecDir, '/'); /* Search last slash */ if (p) *p = 0; /* Strip file name from path */ } } //#elif defined(WIN32) || defined(__CEGCC__) // /* On Windows we can use GetModuleFileName for getting the exe path */ // GetModuleFileName(NULL, psExecDir, FILENAME_MAX); #endif /* If we do not have the execdir yet, analyze argv[0] and the PATH: */ if (psExecDir[0] == 0) { if (strchr(argv0, PATHSEP) == 0) { /* No separator in argv[0], we have to explore PATH... */ Paths_GetExecDirFromPATH(argv0, psExecDir, FILENAME_MAX); } else { /* There was a path separator in argv[0], so let's assume a * relative or absolute path to the current directory in argv[0] */ char *p; strncpy(psExecDir, argv0, FILENAME_MAX); psExecDir[FILENAME_MAX-1] = 0; p = strrchr(psExecDir, PATHSEP); /* Search last slash */ if (p) *p = 0; /* Strip file name from path */ } } return psExecDir; } /** * Initialize the users home directory string * and program's home directory (~/.config/xxx) */ static void Paths_InitHomeDirs(void) { char *psHome; psHome = getenv("HOME"); if (!psHome) { /* Windows home path? */ psHome = getenv("HOMEPATH"); } if (!psHome) { /* $HOME not set, so let's use current working dir as home */ strcpy(sUserHomeDir, sWorkingDir); strcpy(sProgHomeDir, sWorkingDir); } else { strncpy(sUserHomeDir, psHome, FILENAME_MAX); sUserHomeDir[FILENAME_MAX-1] = 0; /* Try to use a .config directory in the users home directory */ snprintf(sProgHomeDir, FILENAME_MAX, "%s%c./config/ballerburg", sUserHomeDir, PATHSEP); if (!Paths_DirExists(sProgHomeDir)) { /* Program home directory does not exists yet... * ...so let's try to create it: */ if (1 /*mkdir(sProgHomeDir, 0755) != 0*/) { /* Failed to create, so use user's home dir instead */ strcpy(sProgHomeDir, sUserHomeDir); } } } } /** * Initialize the data directory string */ static void Paths_InitPackageDir(char *psPkgDir, const char *psRelPath, const char *psExecDir) { char *pTempName; if (psExecDir && strlen(psExecDir) > 0) { snprintf(psPkgDir, FILENAME_MAX, "%s%c%s", psExecDir, PATHSEP, psRelPath); } else { /* bindir could not be determined, let's assume the destination dir is * relative to current working directory... */ strcpy(psPkgDir, psRelPath); } pTempName = malloc(FILENAME_MAX); if (!pTempName) { perror("Init data dir malloc"); return; } if (realpath(psPkgDir, pTempName) != NULL) { strncpy(psPkgDir, pTempName, FILENAME_MAX); } free(pTempName); } /** * Initialize directory names * * The datadir will be initialized relative to the bindir (where the executable * has been installed to). This means a lot of additional effort since we first * have to find out where the executable is. But thanks to this effort, we get * a relocatable package (we don't have any absolute path names in the program)! */ void Paths_Init(const char *argv0) { char *psExecDir; /* Path string where the executable can be found */ /* Init working directory string */ if (getcwd(sWorkingDir, FILENAME_MAX) == NULL) { /* This should never happen... just in case... */ strcpy(sWorkingDir, "."); } /* Init the user's home directory string */ Paths_InitHomeDirs(); /* Get the directory where the executable resides */ psExecDir = Paths_InitExecDir(argv0); /* Now create the package path names from the bindir path name: */ Paths_InitPackageDir(sDataDir, BIN2DATADIR, psExecDir); Paths_InitPackageDir(sLocaleDir, BIN2LOCALEDIR, psExecDir); free(psExecDir); /*fprintf(stderr, " WorkingDir = %s\n DataDir = %s\n UserHomeDir = %s\n ProgHomeDir = %s\n", sWorkingDir, sDataDir, sUserHomeDir, sProgHomeDir);*/ } ballerburg-1.0.1/src/baller2.c0000644000175000017500000003636112145514531015472 0ustar thomasthomas/* baller2.c Copyright (C) 1987, 1989 Eckhard Kruse Copyright (C) 2010, 2013 Thomas Huth This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /***************************************************************************** * B a l l e r b u r g Modul 2 * * Dies ist der zweite Teil des Ballerburg Sourcecode. Hier werden die * * Computer gesteuert und der Flug der Kugel dargestellt. Außerdem sind * * alle Routinen in Zusammenhang mit dem König beinhaltet. * *****************************************************************************/ #include #include #include #include #include "i18n.h" #include "baller1.h" #include "baller2.h" #include "screen.h" #include "psg.h" #include "market.h" #define Min(a,b) ((a)<(b)?(a):(b)) #define Max(a,b) ((a)>(b)?(a):(b)) #define hide() /*graf_mouse(256,0)*/ #define show() /*graf_mouse(257,0)*/ void expls(int x, int y, int w, int h, int d); /***************** Grafikdaten für Trohn, Kanone... **************************/ short trohn[]={ -2,2,2, 8,3,5,12,8,12,12,16,12,17,14,15, 15,15,17,17,17,16,21,11,24,11,21,3,-9, -4, 3,0,5,2,24,2,26,0,-9, 19,4,18,9,-9, 10,4,11,9,-9, 14,4,15,4,-9, 8,10,11,11,-9, 21,10,18,11,-9, 14,17,15,17,-9, 13,19,13,19,-9, 16,19,16,19,-9, 12,22,12,21,15,21,14,22, 17,21,17,22,-9, 6,13,6,17,5,16,5,17,7,17,7,16,-9, -1 }, kanon[]={ -2,1,1, 1,0,3,3,5,0,3,3,3,11,2,11,2,9,4,9,4,11,3,11,3,8,0,5, 3,8,6,5,3,8,3,3,-9, 11,0,13,2,15,0,16,0,17,1,17,2,15,4,19,8,16,11,8,3,-9, -1 }, sack[]={ -4, 1,1,1,4,2,5,2,0,3,0,3,8,2,8,4,8,3,8,3,6,4,6,4,0,5,0, 5,6,6,5,6,1,-9, -1 }, fass[]={ -4, 2,0,6,0,8,3,8,5,6,8,2,8,0,5,0,3,2,0,3,0,3,3,2,4,3,5,3,8, 5,8,5,5,6,4,5,3,5,1,-9, -1 }, kuge[]={ -2,1,1, 1,0,0,1,0,3,1,4,3,4,4,3,4,1,3,0,-9,-1 }, turm[]={ -4, 23,30,27,0,3,10,24,20,6,30,23,30,5,20,26,10,2,0,6,30,-9, 8,0,8,31,9,34,11,36,14,37,15,37,18,36,20,34,21,31,21,29,20,26,18,24,15,23, 14,23,11,24,9,26,8,29,-9, 14,23,15,37,-9, 10,25,19,35,-9, 10,35,19,25,-9, 21,30,21,0,-9, -1 }; /************************ Der Computer agiert: *******************************/ int zx,zy; /* Koordinaten des Zieles */ short *bh; static double vvx,vvy; int comp(void) /* Führt einen Zug des Computers durch */ { char wd; int i,t; register double x2=0,x,y,vx2,vx,vy=0,wi; st[n]=16; for ( i=0;i<10;i++ ) if ( ka[n][i].x>-1 ) break; if ( pu[n]<20 && ge[n]>=p[4] ) { pu[n]+=30; /* Pulv. kaufen*/ ge[n]-=p[4]; } if ( !ku[n] && ge[n]>=p[5] ) { ku[n]+=2; /* Kug. kaufen*/ ge[n]-=p[5]; } if ( i>9 && ge[n]>=p[2] ) { init_ka(i=0,639*n); /* Ka. kauf.*/ ge[n]-=p[2]; } if ( (ft[n][0].x<0 || ft[n][1].x<0 || ft[n][2].x<0 ) && ge[n]>=p[1] && cw[n]>2 ) { ge[n]-=p[1]; /* Förderturm kaufen */ fturm(); } drw_all(); if ( i>9 || pu[n]<20 || !ku[n] ) return(-1); /* Jetzt kommen die Berechnungen für den Schuss: */ bh=burgen[bur[!n]]; do i=rand()%10; while ( ka[n][i].x==-1 ); zx=639*!n-f*(rand()%bh[0]); zy=by[!n]; t=rand()%100; if ( cw[n] ) z_kn(); switch ( cw[n] ) /* Die verschiedenen Strategien */ { case 1: if ( t<30 ) z_ge(); if ( t>60 ) z_pk(); break; case 2: z_ka(); if ( t<90 ) z_ge(); break; case 3: if ( t<50 )z_ka(); else if ( t<70 )z_ge(); else if ( t<90 )z_pk(); if ( !(rand()%3) ) z_ft(); break; case 4: z_ka(); break; case 5: z_ka(); if ( t<90 ) z_ft(); } y=ka[n][i].y-10-zy; t=49-cx[n]*16; /* Berechnen der Distanz */ x=ka[n][i].x+9+8*f-zx -t/2+rand()%t; if ( x<0 ) x=-x; wd=n? -wnd:wnd; x2=-1; for ( vx=.5; vx<7 && ( x2vx ); ) /* Zeitberechnung bei */ { /* verschiedenen X-Geschwindigkeiten */ vx+=.4; t=x2=0; vx2=vx; while ( vx2>0 && x2-1 ) break; if ( i<10 ) { do i=rand()%10; while ( ka[!n][i].x==-1 ); zx=ka[!n][i].x+10; zy=ka[!n][i].y; } } void z_ft(void) { short i; for ( i=0;i<5;i++ ) if ( ft[!n][i].x>-1 ) break; if ( i<5 ) { zx=ft[!n][i].x-15*f; zy=ft[!n][i].y-10; } } void z_ge(void) { if ( ge[!n]>100 ) { zx=!n*639-f*(bh[25]+bh[31]/2); zy=by[!n]-bh[26]; } } void z_pk(void) { short i; if ( ku[!n] || pu[!n]>19 ) { i=rand()&2; zx=!n*639-f*(bh[27+i]+bh[33+i]/2); zy=by[!n]-bh[28+i]; } } /********************************* Ein Schuss ********************************/ /* k = Nr. der Kanone */ void schuss(int k) { double x, y; double ox = 0.0, oy = 0.0; double vx, vy; short v,c,a, j; short oldn; hide(); pu[n]-=ka[n][k].p; ku[n]--; drw_gpk(1); drw_gpk(2); x=ka[n][k].x+9+8*f; y=ka[n][k].y-10; c=2; vx=(.4+0.25*ka[n][k].p)*cos( ka[n][k].w/P57 )*f; vy=(.4+0.25*ka[n][k].p)*sin( ka[n][k].w/P57 ); if ( mod&(2-n) ) { vx=vvx; vy=vvy; } color(1); baller(0); kugel( (int)x,(int)y ); v=1; while ( x>3 && x<637 && y<396 && ( v || c ) ) /* Flugschleife */ { ox=x; oy=y; x+=vx; y-=vy; vy-=G; vx+=(wnd/2-vx)/5000; color(0); kugel( (int)ox,(int)oy ); if ( x>=3 && x<=637 && y>= 3 && y <= 397) { v=!loc((int)x,(int)y) & !loc((int)x-1,(int)y+1) & !loc((int)x+1,(int)y+2); } color(1); kugel( (int)x,(int)y ); SDL_Delay(8); SDL_PumpEvents(); a=1000+2*y; if ( a<30 ) a=30; Giaccess( 10,137 ); Giaccess( 244,135 ); Giaccess( a&255,130 ); Giaccess( a>>8,131 ); if ( c ) c--; } color( 0 ); kugel( (int)x,(int)y ); draw(ka[n][k].x+20*n, ka[n][k].y, kanon); oldn=n; if ( !v ) for ( c=0;c<4;c++ ) /* Einschlag der Kugel */ { if ( ox>6 && ox<634 ) v_circle( handle, (int)ox,(int)oy, 5 ); baller(22+c*3); for ( n=0;n<2;n++ ) /* Treffer ? */ { bg=burgen[bur[n]]; if ( rand()&1 && (n? x>639-bg[0] : xox && ka[n][j].x>-1 && ka[n][j].y-16oy ) { clr_bg( a=ka[n][j].x,v=ka[n][j].y-12,20,13 ); expls( a+10,v+6,10,8,50 ); color(0); ka[n][j].x=-1; } for ( j=0;j<5;j++ ) if ( ft[n][j].x>-1 && drin( a=639*n+f*ft[n][j].x,v=by[n]-ft[n][j].y, 30,37,2,(int)ox,(int)oy ) ) { if ( drin( a,v,30,37,-2,(int)ox,(int)oy ) ) { expls((a=ft[n][j].x-29*n)+15,(v=ft[n][j].y-40)+20,15,20,120); clr_bg( a,v,30,40 ); ft[n][j].x=-1; } c=4; } if ( ox>wx[n]-11 && oxwy[n]-16 && oy-1) { /* Windfahne getroffen */ clr_bg(wx[n]-10, wy[n]-15, 20, 15); wx[n]=-1; } if ( drin( bg[21],bg[22],30,25,0,(int)ox,(int)oy ) ) { end=n+17; expls( a=639*n+f*(bg[21]+15),v=by[n]-bg[22]-12,17,17,40 ); v_circle( handle, a,v,17 ); expls( a,v,17,17,200 ); c=4; } for ( j=0;j<6;j+=2 ) if ( drin( bg[25+j],bg[26+j],a=bg[31+j],v=bg[32+j],3, (int)ox,(int)oy ) ) break; switch ( j ) { case 0: ge[n]-=Min(200,ge[n]); break; case 2: pu[n]=0; break; case 4: ku[n]-=Min(2,ku[n]); } if ( j<6 ) { expls( 639*n+f*(bg[25+j]+a/2),by[n]-bg[26+j]-v/2, a/2,v/2,60+100*(j==2) ); drw_gpk(j/2); c=4; } } ox+=vx; oy-=vy; } n=oldn; fn(); Giaccess( 0,137 ); show(); } /****************************** Explosion ************************************/ void expls(int x, int y, int w, int h, int d) { int i,j; color(0); for ( i=0;i<32; ) { xy[i++]=x; xy[i++]=y; } while ( d-->0 ) { int fire_col; v_pline( handle,2,xy ); memmove(xy, xy+4, 120); for ( j=28;j<32; ) { xy[j++]=x-w+w*(rand()&511)/256; xy[j++]=y-h+h*(rand()&511)/256; } fire_col = (rand()&0x3f) + 0xc0; fire_col = (fire_col << 16) | ((rand()%fire_col) << 8); scr_line(xy[28], xy[29], xy[30], xy[31], fire_col); baller((d&31)^31); SDL_Delay(10); } for ( i=0;i<32;i+=4 ) { v_pline( handle,2,xy+i ); } } int kugel(int x, int y) { if (x < 3 || x > 637 || y < 3 || y > 397) return 0; scr_cannonball(x, y); return 1; } void baller(unsigned char r) { static unsigned char s_bal[] = { 0,0, 1,15, 6,31, 9,0, 11,0, 12,50, 13,0, 7,192, 8,16, 255,0 }; s_bal[5] = r; Dosound( s_bal ); SDL_Delay(10); } /**************************** Neues Bild zeichnen ****************************/ void bild(void) { short y,x1,x2,v1,v2; hide(); scr_clear(); by[0] = (rand()%80 + 300) & ~3; by[1] = (rand()%80 + 300) & ~3; y=400; x1=0; x2=2556; color( 1 ); v1=v2=2; while ( x120 ) { int green = 0x70 + (400-y)/4; scr_line(x1/4, y, x2/4, y, 0x300030+(green<<8)); if (y == by[0]) { x1 = *burgen[bur[0]] * 4; } if (y == by[1]) { x2 = (639 - *burgen[bur[1]]) << 2; } if ( x1 ) { v1=v1+rand()%5-2; v1=Max(0,v1); v1=Min(7,v1); x1+=v1; } if ( x2<2556 ) { v2=v2+rand()%5-2; v2=Max(0,v2); v2=Min(7,v2); x2-=v2; } } memset(ka, -1, sizeof(ka)); burg(0); burg(1); v_gtext(handle, 276, 395+16, _(" Round ")); scr_draw_done_button(0); show(); } /***************************** Burg zeichnen *********************************/ void burg(int nn) { short i,xr; short oldn; oldn=n; n=nn; fn(); xr=n&2? bx[n&=1]:639*n; bg=burgen[bur[n]]; ge[n]=bg[37]; pu[n]=bg[38]; ku[n]=bg[39]; vo[n]=bg[40]; color(1); draw( xr,by[n], &bg[45] ); clr( xr+f*bg[21]-n*30,by[n]-bg[22]-25,30,25 ); color(1); draw( xr+f*bg[21],by[n]-bg[22], trohn ); n=nn; for ( i=0; i<10 && bg[i*2+1]>-1; i++ ) init_ka( i,xr ); drw_all(); n=oldn; } void init_ka(int k, int xr) /* Kanone k setzen */ { short x,y; draw( x=xr+bg[1+k*2]*f, y=by[n&1]-bg[2+k*2], kanon ); if ( ~n&2 ) { ka[n][k].x=x-20*n; ka[n][k].y=y; ka[n][k].w=45; ka[n][k].p=12; } } void drw_all(void) /* Geld, Pulver und Kugeln zeichnen */ { drw_gpk(0); drw_gpk(1); drw_gpk(2); } void drw_gpk(char w) { short i = 0,z, x,y, xr,yr, xp = 0, yp = 0, m=n&1; short *a = NULL; switch ( w ) { case 0: a=sack; xp=7; yp=10; i=(ge[m]+149)/150; break; case 1: a=fass; xp=yp=9; i=(pu[m]+29)/30; break; case 2: a=kuge; xp=yp=6; i=ku[m]; } bg=burgen[bur[m]]; w*=2; xr=(n&2? bx[m]:639*m)+f*bg[25+w]; yr=by[m]-bg[26+w]; hide(); clr( xr-bg[31+w]*m-!n,yr-bg[32+w],bg[31+w]+1,bg[32+w]+1 ); color(1); for ( y=z=0; i>0 && y0 && x0 ) /* Maximalbetrag überschritten ? */ switch ( w ) { case 0: ge[m]=z*150; break; case 2: pu[m]=z*30; break; case 4: ku[m]=z; } } /***************************** Zeichenroutine ********************************/ void draw(short x, short y, short *a) { short i,fil=1; hide(); vsf_interior( handle,2 ); vsf_style( handle,9 ); while ( *a!=-1 ) { if ( *a==-2 ) { vsf_interior( handle,*++a ); vsf_style( handle,*++a ); } else if ( *a==-4 ) fil=!fil; else { i=0; while ( *a>-1 ) { xy[i++]=x+*a++*f; xy[i++]=y-*a++; } xy[i++]=xy[0]; xy[i++]=xy[1]; if ( fil ) v_fillarea( handle,i/2,xy ); else v_pline( handle,i/2-1,xy ); } a++; } show(); } /** * Förderturm bauen */ void fturm(void) { short x,y,yy,i,t; hide(); for ( t=0;t<5;t++ ) if ( ft[n][t].x==-1 ) break; x=639*n+f*(bg[0]+20+30*t); y=380; do { while ( loc(x,y) && loc(x+29*f,y--) ); yy=y; for ( i=0;i<40;i++,y-- ) if ( loc(x,y) && loc(x+29*f,y) ) break; } while ( i<40 ); y=yy; clr_bg( x-29*n,y-70,30,70 ); color( 1 ); draw( ft[n][t].x=x,ft[n][t].y=y,turm ); show(); } /* ************************ Audience with the king ************************* */ const char kna[] = N_("The king says:"), kne[] = N_("Humbly acknowledged"), kn0[] = N_("Well...\n alright...\n Carry on..."), kn1[] = N_("We are satisfied\n with your performance!"), kn2[] = N_("Excellent,\n keep at it!"), kn3[] = N_("Maybe you ought to\n lower Our taxes..."), kn4[] = N_("If you keep this up,\n We shall discharge you!"), kn5[] = N_("Why don't you buy\n a shaft tower..."), kn6[] = N_("You ought to\n kindly make more of\n an effort!"), kn7[] = N_("You don't need to visit Us\n in each round."), kn8[] = N_("Are you aware\n that you have already visited Us\n %d times thus far?"), kn9[] = N_("So, are you certain\n that you will manage\n without a weather vane?"), kn10[] = N_("Nice to see you..."), kn11[] = N_("What are We supposed\n to say in such an\n early phase?"), kn12[] = N_("You ought to earn more money,\n build more shaft towers,\n and vanquish the opponent."), kn13[] = N_("We do not have anything new\n to say to you."), kn14[] = N_("We are pleased for you\n to come around and visit Us."); void koenig(void) { char a[300]; static char kn_visited[80]; const char *s[20]; char k, t; int i, j; static const char *ltz[2]; for ( j=k=0;j<10;j++ ) k+=ka[n][j].x>-1; for ( j=t=0;j<5;j++ ) t+=ft[n][j].x>-1; if ( !(rand()%20) || kn[n]&16 || (kn[n]&15)>9 ) DlgAlert_Notice(_("The king is not in the mood\nto talk to you."), _("Too bad.")); else { sprintf(kn_visited, _(kn8), kn[n]/256); j=rand(); i=2; s[0]=j&1 ? _(kn0) : _(kn10); s[1]=j&2 ? _(kn12) : _(kn6); if ( j&4 ) s[i++] = _(kn14); if (ge[n] > p[1] && t < 3) s[i++] = _(kn5); if ((st[n] > 40 && vo[n] < bg[40]) || st[n] > 70) s[i++] = _(kn3); if (wx[n] < 0) s[i++] = _(kn9); if (ge[n] > bg[37] && vo[n] > bg[40] && k > 1) s[1] = t<2 ? _(kn1) : _(kn2); if (t > 2) s[i++] = _(kn2); if (k < 1 && ge[n] < p[2]) s[i++] = _(kn4); if ((kn[n]&15) > 4) { s[i++] = _(kn7); s[i++] = _(kn7); s[i++] = _(kn7); } if ((kn[n]&15) > 6 || (!(rand()&7) && kn[n] > 2048)) { s[i++] = kn_visited; s[i++] = kn_visited; } if (zug < 4) s[1] = s[2] = s[(i=4)-1] = _(kn11); do if (s[j=rand()%i] == ltz[n]) { s[i++] = _(kn13); s[i++] = _(kn13); } while (s[j] == ltz[n]); ltz[n] = s[j]; snprintf(a, sizeof(a), "%s\n'%s'", _(kna), s[j]); DlgAlert_Notice(a, _(kne)); } kn[n]|=16; kn[n]+=256; if ( ~kn[n]&15 ) kn[n]++; } /* Test, ob Koord. innerhalb eines Rechteckes */ int drin(short xk, short yk, short w, short h, short r, short x, short y) { if ( n ) xk=639-xk-w; return( x>xk-r && xby[n]-yk-h-r ); } ballerburg-1.0.1/src/baller.mus0000644000175000017500000001173412145514531015767 0ustar thomasthomasi ÿûÿþÿôüü üüüüÿúüÿùüüüüü ÿþÿÐ ÿþÿÎÿþÿþ ÿþÿÍÿýÿý ÿþÿÌÿüÿü ÿþÿÐÿû ÿþÿô0ü ü ÿþÿÐÿï üÿÿpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppphhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh````````````hhhhhhhhhhhhpppppppppppppppppppppppp||||||||||||||||||||||||||||||||||||||||||||||||xxxxxxxxxxxxxxxxxxxxxxxxžtžtžtžtžtžtžtžtžtžtžtžtttttttttttttppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppD@<988998899DDEEDDEEDDEED@<988998899DDEEDDEEDDEED@<988998899DDEEDDEEDDEEppppppppppppDDDDDDDDDDDD888888888888œ<œ<œ<œ<œ<œ<DDDDDDDDDDDDDDDDDDDDDDDDHHHHHHžLžLžLžLžLžLžLžLžLžLžLžLTTTTTTTTTTTT^D^D@@@@@@@@@@HHHHHHHHHHHHžLžLžLžLžLžLžLžLžLžLžLžLHHHHHHžLžLžLžLžLžLžLžLžLžLžLžLHHHHHHHHHHHHžLžLžLžLžLžLTTTTTTTTTTTTTTTTTTTTTTTT````````````````````````XXXXXXXXXXXXXXXXXXTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT¢žœœœœœœœœœœœœœœœœœœœœœœ®ª¨¨¨¨¢žœœœœœœœœœœ¢žœœœœœœœœœœ¢žœœœœœœœœœœ®ª¨¨¨¨¢žœœœœœœœœœœ’ŽŒŒŒŒŒŒŒŒŒŒTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTž<ž<ž<ž<ž<ž<ž<ž<ž<ž<ž<ž<<<<<<<<<<<<<<<<<<<<<<<<<®ª¨¨¨¨®ª¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨º¶´´´´®ª¨¨¨¨¨¨¨¨¨¨®ª¨¨¨¨¨¨¨¨¨¨®ª¨¨¨¨œœœœœœœœœœœœ;8;8;8888888888888888888888<8<88888<888888888888888888=8=8=8888888888888888<888888<8<88888888888;888;888;888888;D;DDDDDDDDDDDDDDDDDDDDDDD