Fix build + format README.md of 2014/maffiodo1

The build requires SDL1, not SDL2. Linker errors otherwise.

Format fix and typo fix README.md.
This commit is contained in:
Cody Boone Ferguson committed 2023-05-13 05:08:10 -07:00
1 parent 42c67315fa
commit cc0f625497
2 files changed
+226 -139

No files matched your search

+2 -2
View File
@@ -64,7 +64,7 @@ CDEFINE=
# Include files that are needed to compile
#
CINCLUDE= `${SDL2_CONFIG} --cflags`
CINCLUDE= `${SDL1_CONFIG} --cflags`
# Optimization
#
@@ -76,7 +76,7 @@ CFLAGS= ${CSTD} ${CWARN} ${ARCH} ${CDEFINE} ${CINCLUDE} ${OPT}
# Libraries needed to build
#
LIBS= `${SDL2_CONFIG} --libs`
LIBS= `${SDL1_CONFIG} --libs`
# C compiler to use
#
+224 -137
View File
@@ -6,66 +6,16 @@
## To build:
This entry requires SDL to be installed.
This entry requires SDL to be installed. See the [faq.md](/faq.md) if you don't
know how to do this for your system.
```sh
make
```
### To install SDL and SDL2:
#### macOS users
If you have not aleady do so, install Homebrew. See the following for information:
https://brew.sh
Then to install SDL and SDL2, execute the following command:
```sh
brew install sdl2 sdl12-compat
eval "$(/opt/homebrew/bin/brew shellenv)"
```
#### Linux users:
To install SDL and SDL2, execute the following command as root:
```sh
dnf install SDL2 SDL2-devel sdl12-compat sdl12-compat-devel
```
Use make as follows:
```sh
make ... SDL2_INCLUDE_ROOT=/usr
```
or set the following environment variable:
```sh
export SDL2_INCLUDE_ROOT=/usr
```
#### Debian users
To install SDL and SDL2, execute the following command as root:
```sh
apt install libsdl1.2debian libsdl1.2-dev libsdl2-dev
```
Use make as follows:
```sh
make ... SDL2_INCLUDE_ROOT=/usr
```
or set the following environment variable:
```sh
export SDL2_INCLUDE_ROOT=/usr
```
[Cody Boone Ferguson](/winners.html#Cody_Boone_Ferguson) fixed the build for
this entry: it does not require SDL2 but SDL1 so there were linking errors.
Thank you Cody!
## To run:
@@ -78,162 +28,299 @@ cat mario.level | ./prog 320 200 800 300 128 144 mario.rgba mario8.wav 10343679
```sh
cat giana.level | ./prog 320 200 1000 300 192 168 giana.rgba giana8.wav 5459393
cat mario.level | ./prog 320 200 800 300 128 144 mario.rgba mario8.wav 10343679 && telnet towel.blinkenlights.nl
cat mario.level | ./prog 320 200 800 300 128 144 mario.rgba mario8.wav 10343679 && telnet telehack.com 23
```
If you end up telnetting to the server you can try:
```
ls # show files including games
wumpus.bas # play Hunt the Wumpus
advent.gam # you know what this is! :-)
starwars # animated Star Wars 'film'
```
NOTE: the author stated that the sky colour is incorrect in some versions of
macOS, offering a workaround. Cody tested this out in the most recent macOS
version and this does not seem to be a problem any more. As he played (and beat)
the entire series many times years ago he can confirm that the sky is more or
less correct though it's possible that because he's practically blind he might
have missed something :-) He guesses that the problem might have been the
version of `SDL1` but he does not know this either way.
Cody notes ironically that the author stated that in Super Mario Bros one cannot
go through walls but there are known glitches where you can in some areas (as he
recalls this also applied to the arcade version, Mario Bros, but he cannot
confirm this now) :-)
## Judges' remarks:
A classic for a particular generation. Like all good programs, being data
driven means you can do fun things in small spaces.
NOTE: the author states to use `tabsize=4` to see the magic of the formatting of
the code. In `vim` you can do:
```
:set tabstop=4
```
in command mode to see this effect. You don't need to modify your `.vimrc` file!
You can also use `expand` as described below if your terminal has enough rows
and you don't want to move about in the code. The vim command should immediately
take effect.
## Author's remarks:
### Remarks
Use tabsize=4 to see the magic
Use `tabsize=4` to see the magic.
```sh
./expand -t 4 < prog.c
expand -t 4 prog.c
```
The program returns 0 if the user win or *not-zero* if loose so you can test it and make something useful (or not), like that:
The program returns 0 if the player wins or *non-zero* if the player loses so
you can test it and make something useful (or not), like this:
```sh
cat mario.level | ./prog 320 200 800 300 128 144 mario.rgba mario8.wav 10343679 && telnet towel.blinkenlights.nl
cat mario.level | ./prog 320 200 800 300 128 144 mario.rgba mario8.wav 10343679 && telnet telehack.com 23
```
This is an engine for **Platform Games**. It can be used to create games like the legendary [Super Mario Bros](http://en.wikipedia.org/wiki/Super_Mario_Bros.).
With this simple and clear sourcecode you can create all the games you want, for free!
and type in: `starwars`
In my two tests i tried to create one level of [Super Mario Bros](http://en.wikipedia.org/wiki/Super_Mario_Bros.) and one of [The Great Giana The Sisters](http://en.wikipedia.org/wiki/The_Great_Giana_Sisters).
Both games are classic *platform games* and both share the same fundamental rules:
- there is a player
- there is a powerup that can change the look of the player and/or give to him/her more power!
- there are walls, floors and ceilings. the player can move and jump over these type of obstacles but cannot walk through them
- there are enemies and, if the player collides with an enemy, the player dies or loses its powers
This is an engine for [platform
game](https://en.wikipedia.org/wiki/Platform_game). It can be used to create
games like the legendary [Super Mario
Bros](http://en.wikipedia.org/wiki/Super_Mario_Bros.).
### Regards running under Mac OS X
With this simple and clear source code you can create all the games you want,
for free!
The color of the sky is wrong on MacOS. You need to flip some bytes from the last parameter of the program:
In my two tests I tried to create one level of [Super Mario
Bros](http://en.wikipedia.org/wiki/Super_Mario_Bros.) and one of [The Great
Giana The Sisters](http://en.wikipedia.org/wiki/The_Great_Giana_Sisters).
MARIO LAST PARAMETER: 4292124159
Both games are classic [platform
games](https://en.wikipedia.org/wiki/Platform_game) and both share the same
fundamental rules:
GIANA LAST PARAMETER: 3243070463
- There is a character.
- There are power-ups that can change the look of the character and/or give the
character more or different powers or abilities!
- There are walls, floors and ceilings. The character can move and jump over
these type of obstacles but cannot walk through them.
- There are enemies and; if the character collides with an enemy, the character
dies or loses its powers.
### Running under macOS
[NOTE: this seems to no longer be the case as of 2023 and most likely much
earlier. However one can change the look of the game doing this anyway:]
The color of the sky is wrong on macOS. You need to flip some bytes from the
last parameter of the program:
* MARIO LAST PARAMETER: `4292124159`
* GIANA LAST PARAMETER: `3243070463`
### Regarding how to compile
The code requires libSDL1.X.
The code requires `SDL1`.
The build process will generate some warnings (60~ on clang) about:
- **incompatible pointer types**: because all pointers are declared to *int* or *char*, to save tokens
- **type specifier missing, defaults to 'int'**: because i need to save tokens
- **using the result of an assignment as a condition without parentheses**: because while(c=getchar()) is not evil
- `incompatible pointer types`: because all pointers are declared to `int` or
`char`, to save bytes.
- `type specifier missing, defaults to 'int'`: because I need to save bytes.
- `using the result of an assignment as a condition without parentheses`:
because `while(c=getchar())` is not evil.
### How it works
## Parameters
1. Window width
2. Window height
3. Level width
4. Level height
5. Sprites image width
6. Sprites image height
7. Filename of the sprites image (raw RGBA image)
8. Filename of the music (WAVE 8000 Hz 8bit Mono)
9. Sky color. This number depends on the system where you run the program. See **NOTE on MacOS**
1. Window width.
2. Window height.
3. Level width.
4. Level height.
5. Sprites image width.
6. Sprites image height.
7. Filename of the sprites image (raw RGBA image).
8. Filename of the music (WAVE 8000 Hz 8bit Mono).
9. Sky color. This number depends on the system where you run the program. See
note on macOS.
## Sprites
The program read a single image that contains all the game sprites. The image must be a grid of 8xN sprites. The size of a single sprite must be square. The program calculates the size in this way:
The program read a single image that contains all the game sprites. The image
must be a grid of 8xN sprites. The size of a single sprite must be square. The
program calculates the size in this way:
sprite_size = image_width / 8
```
sprite_size = image_width / 8
```
Each sprite is identified by its position inside the grid, counting line by line, from left to right (for example sprite 0 is the top left sprite in the grid, sprite 8 is the first sprite of the second row of the grid).
Each sprite is identified by its position inside the grid, counting line by
line, from left to right (for example sprite 0 is the top left sprite in the
grid, sprite 8 is the first sprite of the second row of the grid etc.).
Some positions of the grid have a predefined purpose:
```
Position | Description
:-----------------|:--------------
0 | Player stand right
1 | Player walk right frame 0
2 | Player walk right frame 1
3 | Player jump right
4 | Player stand left
5 | Player walk left frame 0
6 | Player walk left frame 1
7 | Player jump left
8 *(second row)* | Super player stand right
9 | Super player walk right frame 0
10 | Super player walk right frame 1
11 | Super player jump right
12 | Super player stand left
13 | Super player walk left frame 0
14 | Super player walk left frame 1
15 | Super player jump left
0 | Player standing right
1 | Player walking right frame 0
2 | Player walking right frame 1
3 | Player jumping right
4 | Player standing left
5 | Player walking left frame 0
6 | Player walking left frame 1
7 | Player jumping left
8 *(second row)* | Super player standing right
9 | Super player walking right frame 0
10 | Super player walking right frame 1
11 | Super player jumping right
12 | Super player standing left
13 | Super player walking left frame 0
14 | Super player walking left frame 1
15 | Super player jumping left
24 | Player dead
32 | Player win
40 | Super player win
32 | Player won
40 | Super player won
```
All the others sprites can be used as you want, depending on the game you want to create.
All the others sprites can be used as you want, depending on the game you want
to create.
## Levels
The program reads the level description from **stdin**.
The program reads the level description from `stdin`.
The level description is a sequence of rows where each row describe an object. You can input as many objects as you want but the maximum number of objects handled by the program is 333. You can modify this value by editing the source here:
The level description is a sequence of rows where each row describe an object.
You can input as many objects as you want but the maximum number of objects
handled by the program is 333. You can modify this value by editing the source
here:
```c
C[333*7],d=333;
```
Each row have six columns:
Each row has six columns:
1. Screen X: x position of the object in the level
2. Screen Y: y position of the object in the level
3. Sprite: id of the sprite to be used for the object
4. CLASSFLAGS: a bitmask that describe how the object behaves
5. CLASSPARAM0: a parameter that depends on CLASSFLAGS
6. CLASSPARAM1: a parameter that depends on CLASSFLAGS
1. `Screen X` : `x` position of the object in the level.
2. `Screen Y` : `y` position of the object in the level.
3. `Sprite` : `id` of the sprite to be used for the object.
4. `CLASSFLAGS` : a bitmask that describe how the object behaves.
5. `CLASSPARAM0`: a parameter that depends on `CLASSFLAGS`.
6. `CLASSPARAM1`: a parameter that depends on `CLASSFLAGS`.
CLASSFLAGS must be a combination (bitwise or) of some of these constants:
`CLASSFLAGS` must be a combination (bitwise OR) of some of these constants:
NAME | CONSTANT | CLASS
:----------|:----------|:---------
ENEMY | 1 | An enemy. CLASSPARAM0 can be 0 if the enemy don't move, 1 if the initial move direction is right, -1 if direction is left. All enemies that walk will change its direction after 20 pixels. The sprite of an enemy must have 2 others adjacent sprites: SPRITE-1, used when the enemy die, and SPRITE+1, used when it walks
BLOCK | 2 | A wall. Player can walk over the object but can not pass through it
GIFT BLOCK | 4 | When the player hits the object from below, a new object is created. CLASSFLAGS of the new object is defined in CLASSPARAM0. The sprite used for the new object is defined in CLASSPARAM1. The sprite of the gift object must have an adjacent sprite: SPRITE+1, used when the block is hit
POWERUP | 8 | This is the classic Mario's mushroom. When the player hit the powerup object, the player become *Super player*. If CLASSFLAGS has the bit ZOOM, the player height will be doubled.<br>The *Super player* can hit the enemies without die, but when this happens, the *Super player* goes back to being normal
END | 16 | When the player hits this object the level ends. Player win
ZOOM | 32 | This flag can be used with POWERUP to indicate a powerup that will doubles the size of the player (like Mario's mushroom)
DESTROY | 64 | When the player hits the object the object disappear. This is the classic Mario's coin, but the engine does not counts the points, so, from the user point of view, this object is useless
DESTROYUP | 128 | This object is like a BLOCK but when the player hits the object from below, the object disappear
* `ENEMY` (`1`)
If CLASSFLAGS is zero the object has only an aesthetic function.
An enemy. CLASSPARAM0 can be 0 if the enemies don't move, 1 if the
initial move direction is right, -1 if that direction is left. All
enemies that walk will change their direction after 20 steps. The
sprite of an enemy must have 2 other adjacent sprites: SPRITE-1,
used when the enemy dies, and SPRITE+1, used when it moves.
The last row of the level descriptor must have all its columns set equal to -1.
* `BLOCK` (`2`)
A wall. Player can walk over the object but can not pass through it.
* `OBJECT BLOCK` (`4`)
When the player hits the object from below, a new object is created.
CLASSFLAGS of the new object is defined in CLASSPARAM0. The sprite
used for the new object is defined in CLASSPARAM1. The sprite of the
new object must have an adjacent sprite: SPRITE+1, used when the
block is hit.
* `POWERUP` (`8`)
This is a power-up like the classic Mario mushroom. When the
character hits the power-up object, the character becomes the Super
character. If CLASSFLAGS has the bit ZOOM, the character height will
be doubled. The Super character can hit the enemies without dying,
but when this happens, the Super character goes back to being
normal.
* `END` (`16`)
When the player hits this object the level ends; the player wins.
* `ZOOM` (`32`)
This flag can be used with POWERUP to indicate a power-up that
will double the size of the player (like the Mario mushroom).
* `DESTROY` (`64`)
When the player hits the object (e.g. the classic Mario coin) the
object disappears but the engine does not counts the points, so,
from the player point of view, this object is useless.
* `DESTROYUP` (`128`)
This object is like a BLOCK but when the player hits the object
from below, the object disappears.
If `CLASSFLAGS` is `0` the object only has an aesthetic function.
The last row of the level descriptor must have all its columns set equal to
`-1`.
### Limitations
Some classical features are missing: throw objects, shoot, multiple lives, points counter. You can add those features if you want!
Some classical features are missing: throwing objects, shooting, multiple lives,
score tracking. You can add those features if you want!
The program allow to run one level only. It's easy to add a menu and multiple levels but the size of the engine will grow too much.
The program allows only one level. It's easy to add a menu and multiple levels
but the size of the engine would too big for the contest.
When the *Super player* become bigger (ZOOM flag), the player can collide with blocks and get stuck inside them. This is a KNOWN BUG. When your player become bigger, stay away from blocks!
When the `Super character` becomes bigger (`ZOOM` flag), the character can
collide with blocks and get stuck inside them. This is a KNOWN BUG. When your
player become bigger, stay away from blocks!
There is one audio track only (game effects are missing).
There's only one audio track (game effects are missing).
### Credits
Some of the sprites used in the examples are identical to those of the original games, others were designed by me.
Some of the sprites used in the examples are identical to those of the original
games; the others were designed by me.
The music used in the examples have been resampled, starting from the original versions for the [Commodore Amiga](http://en.wikipedia.org/wiki/Amiga) and [Nintendo NES](http://en.wikipedia.org/wiki/Nintendo_Entertainment_System).
The music used in the examples have been
[resampled](https://en.wikipedia.org/wiki/Sample-rate_conversion), starting from
the original versions for the [Commodore
Amiga](http://en.wikipedia.org/wiki/Amiga) and [Nintendo
NES](http://en.wikipedia.org/wiki/Nintendo_Entertainment_System).
[Super Mario Bros](http://en.wikipedia.org/wiki/Super_Mario_Bros.) is a game created by Nintendo Entertainment, my use of the sprites does not intend to infringe the intellectual property of Nintendo but only demonstrate the operation of the program. From my point of view this is a tribute to the legendary game [Super Mario Bros](http://en.wikipedia.org/wiki/Super_Mario_Bros.)!
[Super Mario Bros](http://en.wikipedia.org/wiki/Super_Mario_Bros.) is a game
created by [Nintendo Co., Ltd](https://en.wikipedia.org/wiki/Nintendo). My use
of the [sprites](https://en.wikipedia.org/wiki/Sprite_(computer_graphics)) does
not intend to infringe the [intellectual
property](https://en.wikipedia.org/wiki/Intellectual_property) of Nintendo but
only demonstrates the operation of the program. From my point of view this is a
tribute to the legendary game [Super Mario
Bros](http://en.wikipedia.org/wiki/Super_Mario_Bros.)!
[The Great Giana The Sisters](http://en.wikipedia.org/wiki/The_Great_Giana_Sisters) is the game created by Time Warp Productions and also for this game worth my previous notes. Long live [The Great Giana The Sisters](http://en.wikipedia.org/wiki/The_Great_Giana_Sisters) !! :)
[The Great Giana The
Sisters](http://en.wikipedia.org/wiki/The_Great_Giana_Sisters) is the game
created by [Time Warp
Productions](https://www.ign.com/games/producer/time-warp-productions) and my
justification for the sprites for Mario are the same for this game. Long live
[The Great Giana The
Sisters](http://en.wikipedia.org/wiki/The_Great_Giana_Sisters) !! :)
## Copyright and CC BY-SA 4.0 License: