summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--games/clonekeen/README23
-rw-r--r--games/clonekeen/clonekeen.6227
-rw-r--r--games/clonekeen/clonekeen.SlackBuild98
-rw-r--r--games/clonekeen/clonekeen.desktop8
-rw-r--r--games/clonekeen/clonekeen.info14
-rw-r--r--games/clonekeen/clonekeen.pngbin0 -> 1081 bytes
-rw-r--r--games/clonekeen/clonekeen.sh13
-rw-r--r--games/clonekeen/doinst.sh4
-rw-r--r--games/clonekeen/extract_shareware_data.c172
-rw-r--r--games/clonekeen/patch.txt12
-rw-r--r--games/clonekeen/slack-desc19
-rw-r--r--games/clonekeen/slackbuild.diff286
-rw-r--r--games/clonekeen/story.txt92
13 files changed, 968 insertions, 0 deletions
diff --git a/games/clonekeen/README b/games/clonekeen/README
new file mode 100644
index 0000000000..9d202387f4
--- /dev/null
+++ b/games/clonekeen/README
@@ -0,0 +1,23 @@
+clonekeen (open source engine for id Software's Commander Keen game)
+
+CloneKeen is an open-source clone of ID's classic DOS game Commander
+Keen. CloneKeen runs under many platforms including Linux & win32. There
+are some improvements over the original such as 2-player support. Original
+game data files are required.
+
+clonekeen is able to run Commander Keen episodes 1, 2, and 3. Episodes
+4 through 6 are not yet supported. Copy the *.ck1, *.ck2, and/or *.ck3
+files from the game installation directory to /usr/share/games/clonekeen
+
+Optionally, the package can include the shareware (episode 1) game data
+files. To do this, download 1keen.zip:
+
+ftp://ftp.3drealms.com/share/1keen.zip
+
+...and place it in the directory where the SlackBuild script is. Also
+you must install libdynamite (available from SBo), since it's required
+to extract the game data. After running the SlackBuild script, the
+resulting package can be installed on a system without libdynamite
+(it's only required at build time). The extractor may also be useful
+for extracting the .SHR files from uninstalled copies of the commercial
+Commander Keen games (not tested by author).
diff --git a/games/clonekeen/clonekeen.6 b/games/clonekeen/clonekeen.6
new file mode 100644
index 0000000000..69b5587384
--- /dev/null
+++ b/games/clonekeen/clonekeen.6
@@ -0,0 +1,227 @@
+.TH CLONEKEEN 6 "March 25, 2010"
+.SH NAME
+clonekeen \- Clone of id Software's "Commander Keen" game
+.br
+.SH SYNOPSIS
+.B clonekeen
+[\fIwarplevel\fR]
+[\fIOPTIONS\fR]
+.SH DESCRIPTION
+CloneKeen is an almost almost complete open\-source clone of
+the old classic DOS game, \fICommander Keen: Invasion of the
+Vorticons\fR by ID Software. CloneKeen requires the original game
+data files to work. You can play all three episodes of the game
+(but not the later episodes 4 through 6, nor "Keen Dreams").
+.PP
+CloneKeen tries to mostly replicate the original game,
+however there are also a number of improvements,
+including smoother scrolling, better graphic effects
+in some parts of the game, and 2\-player support.
+.PP
+See story.txt for a description of the game's plot.
+.SH OPTIONS
+.TP
+\fBwarplevel\fR
+specify a level number (such as 2) to go directly to that level. This option
+must be given first. Example: \fBclonekeen 1 \-fs\fR to start the game on
+level 1 in fullscreen mode.
+.TP
+\fB\-1player\fR, \fB\-2player\fR
+select number of players (1\-2); defaults to 1. This is local multiplayer,
+with 2 players using the same keyboard (there is no network play).
+.TP
+\fB\-nopk\fR
+do not allow players to kill each other in multiplayer games
+.TP
+\fB\-ep1\fR, \fB\-ep2\fR, \fB\-ep3\fR
+select episode 1, 2, or 3; defaults to 1
+.TP
+\fB\-dtm\fR
+go directly to the world map, bypassing intro and title screen
+.TP
+\fB\-mean\fR
+increase game difficulty
+.TP
+\fB\-cheat\fR
+enable function key cheat/debug codes
+.TP
+\fB\-rec\fR
+record player actions to demo.dat for making a demo
+.TP
+\fB\-eseq\fR
+for the impatient\-\-cut directly to the ending sequence
+.TP
+\fB\-fs\fR
+use fullscreen mode
+.TP
+\fB\-dbl\fR
+zoom image 2x
+.TP
+\fB\-showfps\fR
+show frames/second in upper\-right of screen
+.SH CONTROLS
+.TP
+\fBArrows\fR
+Movement
+.TP
+\fBSpace\fR
+Show inventory and status
+.TP
+\fBControl\fR
+Jump (or on the map screen, enter a level)
+.TP
+\fBAlt\fR
+Pogo stick (if you have it)
+.TP
+\fBCtrl+Alt\fR
+Fire Raygun (if it has charges)
+.TP
+\fBF3\fR
+Save the game
+.TP
+\fBEscape\fR
+At the intro or title screen, quits the game. During gameplay, brings up
+the quit menu (press Escape again to return to the game).
+.TP
+\fBF10\fR
+Switch to fullscreen and enable scale2x mode. Only active during the
+intro screen (blue text on starfield).
+.PP
+In 2\-player games, player 2's controls are:
+.TP
+\fBW\fR
+On the Map stage, move up. On a level, jump.
+.TP
+\fBQ\fR
+Pogo stick (if you have it)
+.TP
+\fBQ+W\fR
+Fire Raygun (if it has charges)
+.TP
+\fBA\fR
+Left
+.TP
+\fBS\fR
+Down
+.TP
+\fBD\fR
+Right
+.SH CHEAT CODES
+There are a full assortment of cheat codes available. Some cheats must first
+be enabled with -cheat or through the options menu. C+T+SPACE and G+O+D will
+always work.
+.TP
+\fBG+O+D\fR
+God \- Toggles GOD mode. You can't protect yourself
+ from dying if you fall off the map though.
+ (Use TAB to revive in this case).
+.TP
+\fBTab\fR
+Noclip/Revive \-
+Turns off clipping, allowing you to walk through
+ walls / Aborts a dying sequence.
+.TP
+\fBC+T+Space\fR
+All Items \- Gives all items, similar to the original.
+.TP
+\fBF2\fR
+Nofall \- Disables gravity, so Keen can walk on air.
+.TP
+\fBF6\fR
+Debug mode/RADAR \- Press once: enables debug mode, press again,
+ enables radar in upper\-left corner.
+.TP
+\fBF7\fR
+Throttle off \- Disables speed throttle so the game goes really
+ fast.
+.TP
+\fBF8\fR
+Frame\-by\-frame mode \- Just as it sounds, see in\-game instructions.
+.TP
+\fBF9\fR
+Abort level \- Marks level as "done", and returns to the map.
+.TP
+\fBKeypad +\fR
+Force fall \- Allows fall to a platform below the current one.
+ The opposite of F2.
+.SH GAMEPLAY
+(taken/modified from the original game's in\-game help)
+.PP
+When you are on the Mars map, you may be blocked by a city, shrine, or other
+obstacle. You must enter the city (press Ctrl) and finish it
+before proceeding.
+.PP
+When you enter a city, you can get things by simply running into them.
+.PP
+If you cannot pass through a door, there may be a "keycard" that the door
+requires. This keycard will be the same color as the door.
+.SH TREASURES
+(taken/modified from the original game's in\-game help)
+.PP
+\fBLollipop\fR \- 100 points
+.br
+\fBSoda\fR \- 200 points
+.br
+\fBPizza\fR \- 500 points
+.br
+\fBBook\fR \- 1000 points
+.br
+\fBTeddy Bear\fR \- 5000 points
+.PP
+You get an extra Keen every 20,000 points.
+.SH FILES
+.TP
+\fB~/.clonekeen\fR
+Per\-user savegames and config data. This directory is created the first
+time you run \fBclonekeen\fR.
+.TP
+\fB~/.clonekeen/defaultargs\fR
+Default arguments to pass to the game. Good candidates are \-fs, \-dbl,
+and/or -cheat. Put the arguments in the file on the same line,
+separated by spaces, e.g.:
+.PP
+\fBecho "-dbl -fs -cheat" > ~/.clonekeen/defaultargs\fR
+.TP
+\fB/usr/share/games/clonekeen/\fR
+System\-wide game data files (including the ones that come with
+the original game). Data files may be named in all\-uppercase or
+all\-lowercase (EGAHEAD.CK1 or egahead.ck1, or even mixed case like
+EGAHEAD.ck1 or egahead.CK1, but not egaHead.ck1)
+.TP
+\fB/usr/games/clonekeen\-bin\fR
+Main game binary. Generally not to be run directly: it expects to find the
+data files in the current dir, and writes config/savegame data in the
+current dir. Use the \fBclonekeen\fR wrapper script instead.
+.TP
+\fB/usr/games/clonekeen\fR
+Wrapper script. Creates ~/.clonekeen, populates it with symlinks to the
+game data files, runs the main binary.
+.SH BUGS
+Actually not bugs, these are features that were in the original DOS version
+of the game that are not (yet?) implemented in clonekeen:
+.PP
+No way to customize keyboard controls
+.PP
+No support for joystick controls
+.PP
+No support for in\-game help (probably just as well, the help talks about
+joysticks, and customizing keyboard controls...)
+.PP
+Also, the DOS build of clonekeen appears to support up to 4 (or maybe
+only 3) player
+games, but the Linux build only defines enough control keys
+for 2 players.
+.SH AUTHOR
+clonekeen was written by Caitlin Shaw.
+.PP
+This manual page and the wrapper script were written by B. Watson for the SlackBuilds.org project.
+.SH SEE ALSO
+\fB/usr/doc/clonekeen-8.3/readme.txt\fR
+.br
+\fB/usr/doc/clonekeen-8.3/story.txt\fR
+.br
+\fBhttp://clonekeen.sourceforge.net/\fR
+.br
+\fBhttp://www.3drealms.com/tech/keen.html\fR
+.br
+\fBhttp://en.wikipedia.org/wiki/Commander_Keen\fR
diff --git a/games/clonekeen/clonekeen.SlackBuild b/games/clonekeen/clonekeen.SlackBuild
new file mode 100644
index 0000000000..a5c6aa2374
--- /dev/null
+++ b/games/clonekeen/clonekeen.SlackBuild
@@ -0,0 +1,98 @@
+#!/bin/sh
+
+# Slackware build script for clonekeen
+
+# Written by B. Watson (yalhcru@gmail.com)
+
+PRGNAM=clonekeen
+VERSION=${VERSION:-8.3}
+ARCH=${ARCH:-i486}
+BUILD=${BUILD:-1}
+TAG=${TAG:-_SBo}
+
+CWD=$(pwd)
+TMP=${TMP:-/tmp/SBo}
+PKG=$TMP/package-$PRGNAM
+OUTPUT=${OUTPUT:-/tmp}
+
+if [ "$ARCH" = "i486" ]; then
+ SLKCFLAGS="-O2 -march=i486 -mtune=i686"
+ LIBDIRSUFFIX=""
+elif [ "$ARCH" = "i686" ]; then
+ SLKCFLAGS="-O2 -march=i686 -mtune=i686"
+ LIBDIRSUFFIX=""
+elif [ "$ARCH" = "x86_64" ]; then
+ SLKCFLAGS="-O2 -fPIC"
+ LIBDIRSUFFIX="64"
+fi
+
+set -e
+
+SRCVER=$( echo $VERSION | sed 's/\.//g' )
+SRCDIR=keen
+
+rm -rf $PKG
+mkdir -p $TMP $PKG $OUTPUT
+cd $TMP
+rm -rf $SRCDIR
+unzip $CWD/CKBeta${SRCVER}_Bin_W32.zip
+unzip -o $CWD/CKBeta${SRCVER}_Src.zip
+cd $SRCDIR
+chown -R root:root .
+find . \
+ \( -perm 777 -o -perm 775 -o -perm 711 -o -perm 555 -o -perm 511 \) \
+ -exec chmod 755 {} \; -o \
+ \( -perm 666 -o -perm 664 -o -perm 600 -o -perm 444 -o -perm 440 -o -perm 400 \) \
+ -exec chmod 644 {} \;
+
+# See patch.txt for details on what this patch does and why.
+patch -p1 < $CWD/slackbuild.diff
+
+# Ugh. The src tarball ships with compiled .o files!
+make -f Makefile.lnx -C src clean all CFLAGS="$SLKCFLAGS"
+
+# Manual install
+mkdir -p $PKG/usr/games $PKG/usr/share/games/$PRGNAM/data
+install -m0755 -s src/keen $PKG/usr/games/$PRGNAM-bin
+install -m0755 -oroot -groot $CWD/$PRGNAM.sh $PKG/usr/games/$PRGNAM
+ln -sf $PRGNAM $PKG/usr/games/keen
+install -m0644 bin/*.{DAT,dat} $PKG/usr/share/games/$PRGNAM
+install -m0644 bin/data/* $PKG/usr/share/games/$PRGNAM/data
+
+# story.txt is an ASCII-only version of storytxt.ck1 from the
+# shareware release
+mkdir -p $PKG/usr/doc/$PRGNAM-$VERSION
+cp $CWD/story.txt readme.txt $PKG/usr/doc/$PRGNAM-$VERSION
+cat $CWD/$PRGNAM.SlackBuild > $PKG/usr/doc/$PRGNAM-$VERSION/$PRGNAM.SlackBuild
+
+# Optional shareware data. It's compressed in an oddball format,
+# you need libdynamite to build the extractor.
+if [ -e $CWD/1keen.zip ]; then
+ mkdir -p tmpdata
+ cd tmpdata
+ gcc -Wall -o extract_shareware_data $CWD/extract_shareware_data.c -ldynamite
+ unzip $CWD/1keen.zip
+ ./extract_shareware_data CK1SW131.SHR
+ cp *.ck1 $PKG/usr/share/games/$PRGNAM/data
+ cp vendor.doc $PKG/usr/doc/$PRGNAM-$VERSION/vendor_doc.txt
+ cp order.frm $PKG/usr/doc/$PRGNAM-$VERSION/order_form.txt
+ cd -
+fi
+
+mkdir -p $PKG/usr/man/man6
+gzip -9c < $CWD/$PRGNAM.6 > $PKG/usr/man/man6/$PRGNAM.6.gz
+ln -sf $PRGNAM.6.gz $PKG/usr/man/man6/keen.6.gz
+
+# Icon from here: http://www.dosclassics.com/download/228
+mkdir -p $PKG/usr/share/pixmaps
+cat $CWD/$PRGNAM.png > $PKG/usr/share/pixmaps/$PRGNAM.png
+
+mkdir -p $PKG/usr/share/applications
+cat $CWD/$PRGNAM.desktop > $PKG/usr/share/applications/$PRGNAM.desktop
+
+mkdir -p $PKG/install
+cat $CWD/slack-desc > $PKG/install/slack-desc
+cat $CWD/doinst.sh > $PKG/install/doinst.sh
+
+cd $PKG
+/sbin/makepkg -l y -c n $OUTPUT/$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.${PKGTYPE:-tgz}
diff --git a/games/clonekeen/clonekeen.desktop b/games/clonekeen/clonekeen.desktop
new file mode 100644
index 0000000000..f915444afd
--- /dev/null
+++ b/games/clonekeen/clonekeen.desktop
@@ -0,0 +1,8 @@
+[Desktop Entry]
+Name=CloneKeen
+GenericName=Commander Keen Clone
+Type=Application
+Exec=clonekeen -cheat
+Icon=clonekeen
+Terminal=false
+Categories=Game;ActionGame;
diff --git a/games/clonekeen/clonekeen.info b/games/clonekeen/clonekeen.info
new file mode 100644
index 0000000000..a59bb6ae91
--- /dev/null
+++ b/games/clonekeen/clonekeen.info
@@ -0,0 +1,14 @@
+PRGNAM="clonekeen"
+VERSION="8.3"
+HOMEPAGE="http://clonekeen.sourceforge.net/"
+DOWNLOAD="http://downloads.sourceforge.net/project/clonekeen/clonekeen/Beta%208.3/CKBeta83_Src.zip
+ http://downloads.sourceforge.net/project/clonekeen/clonekeen/Beta%208.3/CKBeta83_Bin_W32.zip
+ ftp://ftp.3drealms.com/share/1keen.zip"
+DOWNLOAD_x86_64=""
+MD5SUM="9aa11b4793bad38bde2eb45597adb54e
+ a0dfcd00f3d039ef544f344b605f83bd
+ 7375d0452276388d52c35d0b3ad6ab82"
+MD5SUM_x86_64=""
+MAINTAINER="B. Watson"
+EMAIL="yalhcru@gmail.com"
+APPROVED="dsomero"
diff --git a/games/clonekeen/clonekeen.png b/games/clonekeen/clonekeen.png
new file mode 100644
index 0000000000..414d5cbfc3
--- /dev/null
+++ b/games/clonekeen/clonekeen.png
Binary files differ
diff --git a/games/clonekeen/clonekeen.sh b/games/clonekeen/clonekeen.sh
new file mode 100644
index 0000000000..e189070a09
--- /dev/null
+++ b/games/clonekeen/clonekeen.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+set -e
+
+GAME=clonekeen
+HOMEDIR=~/.$GAME
+mkdir -p $HOMEDIR
+cd $HOMEDIR
+if [ -e defaultargs ]; then
+ ARGS="`cat defaultargs`"
+fi
+ln -s /usr/share/games/$GAME/* . &>/dev/null || true
+exec $GAME-bin "$@" $ARGS
diff --git a/games/clonekeen/doinst.sh b/games/clonekeen/doinst.sh
new file mode 100644
index 0000000000..392c12adb9
--- /dev/null
+++ b/games/clonekeen/doinst.sh
@@ -0,0 +1,4 @@
+if [ -x /usr/bin/update-desktop-database ]; then
+ /usr/bin/update-desktop-database -q usr/share/applications
+fi
+
diff --git a/games/clonekeen/extract_shareware_data.c b/games/clonekeen/extract_shareware_data.c
new file mode 100644
index 0000000000..7b5fb6593f
--- /dev/null
+++ b/games/clonekeen/extract_shareware_data.c
@@ -0,0 +1,172 @@
+/* utility to extract the .SHR installer data files of early ID software
+ shareware games
+
+ Copyright (C) 2007 Hans de Goede <j.w.r.degoede@hhs.nl>
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <libdynamite.h>
+
+struct cookie_s {
+ char *in_buffer;
+ int in_buffer_remaining;
+ int in_buffer_index;
+ int in_buffer_size;
+ FILE* out_file;
+};
+
+size_t reader(void* buffer, size_t size, void* cookie)
+{
+ struct cookie_s *c = cookie;
+ if (size > c->in_buffer_remaining)
+ size = c->in_buffer_remaining;
+
+ memcpy (buffer, c->in_buffer + c->in_buffer_index, size);
+
+ c->in_buffer_index += size;
+ c->in_buffer_remaining -= size;
+
+ return size;
+}
+
+size_t writer(void* buffer, size_t size, void* cookie)
+{
+ struct cookie_s *c = cookie;
+ return fwrite(buffer, 1, size, c->out_file);
+}
+
+int main(int argc, char *argv[])
+{
+ struct cookie_s cookie;
+ FILE *in_file;
+ char filename[16];
+ unsigned char buf[4];
+ int i, compressed_size;
+
+ if (argc != 2) {
+ fprintf(stderr, "%s: Usage: %s <filename.CHR> %d\n", argv[0], argv[0], argc);
+ return 1;
+ }
+
+ in_file = fopen(argv[1], "r");
+ if (!in_file) {
+ fprintf(stderr, "error opening: %s", argv[1]);
+ perror(NULL);
+ return 1;
+ }
+
+ /* skip first 0x3A bytes header */
+ if (fseek(in_file, 0x3A, SEEK_CUR)) {
+ perror("error skipping initial file header");
+ return 1;
+ }
+
+ cookie.in_buffer = malloc(65536);
+ if (!cookie.in_buffer) {
+ fprintf(stderr, "Error: out of memory\n");
+ return 1;
+ }
+ cookie.in_buffer_size = 65536;
+
+ while (1)
+ {
+ /* get the name of the file */
+ if (fread(filename, 1, sizeof(filename), in_file) != sizeof(filename)) {
+ if (feof(in_file)) {
+ free(cookie.in_buffer);
+ fclose(in_file);
+ return 0; /* done */
+ }
+ perror("error getting output filename from file");
+ return 1;
+ }
+
+ /* verify the filename and convert to lower case */
+ for (i = 0 ; i < sizeof(filename); i++) {
+ if (filename[i] == 0)
+ break; /* done */
+ if (!isprint(filename[i])) {
+ fprintf(stderr, "error invalid output filename\n");
+ return 1;
+ }
+ filename[i] = tolower(filename[i]);
+ }
+ if (i == sizeof(filename)) {
+ fprintf(stderr, "error too long output filename\n");
+ return 1;
+ }
+
+ /* seek to compressed size */
+ if (fseek(in_file, 0x88 - sizeof(filename), SEEK_CUR)) {
+ perror("error skipping file header before file size");
+ return 1;
+ }
+
+ if (fread(buf, 1, 4, in_file) != 4) {
+ perror("error reading file size");
+ return 1;
+ }
+ compressed_size = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
+ if (compressed_size > cookie.in_buffer_size) {
+ cookie.in_buffer = realloc(cookie.in_buffer, compressed_size);
+ if (!cookie.in_buffer) {
+ fprintf(stderr, "Error: out of memory\n");
+ return 1;
+ }
+ cookie.in_buffer_size = compressed_size;
+ }
+
+ /* seek to begin of compressed data */
+ if (fseek(in_file, 0x1C, SEEK_CUR)) {
+ perror("error skipping file header before file size");
+ return 1;
+ }
+
+ /* read compressed data */
+ if (fread(cookie.in_buffer, 1, compressed_size, in_file) !=
+ compressed_size) {
+ perror("error reading compressed data");
+ return 1;
+ }
+
+ cookie.in_buffer_index = 0;
+ cookie.in_buffer_remaining = compressed_size;
+
+ cookie.out_file = fopen(filename, "w");
+ if (!cookie.out_file) {
+ fprintf(stderr, "Error creating: %s for writing", filename);
+ perror(NULL);
+ return 1;
+ }
+
+ printf("decompressing: %s, compressed size: %d\n", filename,
+ compressed_size);
+
+ if ((i = dynamite_explode(reader, writer, &cookie))) {
+ fprintf(stderr, "Error: %d while decompressing\n", i);
+ return i;
+ }
+
+ fclose(cookie.out_file);
+ }
+
+ /* never reached */
+ return 0;
+}
diff --git a/games/clonekeen/patch.txt b/games/clonekeen/patch.txt
new file mode 100644
index 0000000000..634e06b612
--- /dev/null
+++ b/games/clonekeen/patch.txt
@@ -0,0 +1,12 @@
+slackbuild.diff does the following things:
+
+- Allows data filenames to be upper/lower/mixed case
+- Stops creating an empty "ck.log" file in the cwd
+- Stops segfaulting on exit due to double-free bug
+- Gets rid of non-functional -3player, -4player,
+ -host, and -join options
+- Sets the default frameskip to 1. This is because there is no
+ way to DECREASE the frameskip from the in-game Options menu,
+ and the original default was 2. Anyone who has an old/slow
+ enough machine to need frameskip 2 can still set it (increasing
+ the frameskip works fine, you just can't decrease it...)
diff --git a/games/clonekeen/slack-desc b/games/clonekeen/slack-desc
new file mode 100644
index 0000000000..b81a4a7c8c
--- /dev/null
+++ b/games/clonekeen/slack-desc
@@ -0,0 +1,19 @@
+# HOW TO EDIT THIS FILE:
+# The "handy ruler" below makes it easier to edit a package description. Line
+# up the first '|' above the ':' following the base package name, and the '|'
+# on the right side marks the last column you can put a character in. You must
+# make exactly 11 lines for the formatting to be correct. It's also
+# customary to leave one space after the ':'.
+
+ |-----handy-ruler------------------------------------------------------|
+clonekeen: clonekeen (open source engine for id Software's Commander Keen games)
+clonekeen:
+clonekeen: CloneKeen is an open-source clone of ID's classic DOS game
+clonekeen: Commander Keen. CloneKeen runs under many platforms including Linux &
+clonekeen: win32. There are some improvements over the original such as 2-player
+clonekeen: support. Original game data files are required.
+clonekeen:
+clonekeen:
+clonekeen:
+clonekeen:
+clonekeen:
diff --git a/games/clonekeen/slackbuild.diff b/games/clonekeen/slackbuild.diff
new file mode 100644
index 0000000000..f95cc882db
--- /dev/null
+++ b/games/clonekeen/slackbuild.diff
@@ -0,0 +1,286 @@
+diff -Naur keen.orig/src/Makefile.lnx keen/src/Makefile.lnx
+--- keen.orig/src/Makefile.lnx 2005-11-09 22:27:50.000000000 -0500
++++ keen/src/Makefile.lnx 2010-03-26 03:06:24.000000000 -0400
+@@ -31,6 +31,7 @@
+ sdl/keydrv.o sdl/snddrv.o sdl/timedrv.o sdl/viddrv.o \
+ scale2x/scalebit.o scale2x/scale2x.o scale2x/scale3x.o \
+ scale2x/pixel.o \
++ unix_fopen_wrapper.o \
+ keen.h keenext.h sounds.h funcdefs.h latch.h game.h
+ gcc -g3 -o keen \
+ main.o fileio.o \
+@@ -51,6 +52,7 @@
+ sdl/keydrv.o sdl/snddrv.o sdl/timedrv.o sdl/viddrv.o \
+ scale2x/scalebit.o scale2x/scale2x.o scale2x/scale3x.o \
+ scale2x/pixel.o \
++ unix_fopen_wrapper.o \
+ `sdl-config --libs`
+
+
+diff -Naur keen.orig/src/keen.h keen/src/keen.h
+--- keen.orig/src/keen.h 2005-11-07 16:39:12.000000000 -0500
++++ keen/src/keen.h 2010-03-26 03:06:24.000000000 -0400
+@@ -14,6 +14,10 @@
+ #include <windows.h>
+ #endif
+
++#ifdef TARGET_LNX
++ #include "unix_fopen_wrapper.h"
++#endif
++
+ #include "sounds.h"
+ #include "funcdefs.h"
+ #include "latch.h"
+diff -Naur keen.orig/src/main.c keen/src/main.c
+--- keen.orig/src/main.c 2005-11-09 23:35:10.000000000 -0500
++++ keen/src/main.c 2010-03-26 03:11:56.000000000 -0400
+@@ -75,7 +75,7 @@
+
+ char loadinggame, loadslot;
+
+-FILE *log=NULL;
++/* FILE *log=NULL; */
+
+ stFade fade;
+ stMap map;
+@@ -161,7 +161,7 @@
+ SetDefaultOptions();
+ setoption(OPT_FULLSCREEN, "SDL Fullscreen Mode", 0);
+ setoption(OPT_ZOOM, "Image Zoom", 1);
+- setoption(OPT_FRAMESKIP, "Frameskip", 2);
++ setoption(OPT_FRAMESKIP, "Frameskip", 1);
+
+ /* process command line options */
+ VidDrv_printf("Processing command-line options.\n");
+@@ -180,6 +180,7 @@
+ {
+ numplayers = 2;
+ }
++ /*
+ else if (strcmp(tempbuf, "-3player")==0)
+ {
+ numplayers = 3;
+@@ -188,6 +189,7 @@
+ {
+ numplayers = 4;
+ }
++ */
+ else if (strcmp(tempbuf, "-single")==0)
+ {
+ numplayers = 1;
+@@ -240,6 +242,7 @@
+ {
+ showfps = 1;
+ }
++ /*
+ else if (strcmp(tempbuf, "-host")==0) // start network server
+ {
+ is_server = 1;
+@@ -250,6 +253,7 @@
+ is_client = 1;
+ localmp = 0;
+ }
++ */
+ else if (i!=1 || atoi(argv[i])==0)
+ {
+ VidDrv_printf("Wait a minute...what the hell does '%s' mean?\n",tempbuf);
+diff -Naur keen.orig/src/misc.c keen/src/misc.c
+--- keen.orig/src/misc.c 2005-11-16 20:04:28.000000000 -0500
++++ keen/src/misc.c 2010-03-26 03:15:46.000000000 -0400
+@@ -1103,7 +1103,7 @@
+ {
+ VidDrv_printf("Usage: keen [lvlnum] [-*player] [-nopk] [-ep*] [-dtm] [-nocheat] [-rec] -[eseq]\n\n");
+ VidDrv_printf("lvlnum specify a level number (such as 2) to go directly to that level\n");
+- VidDrv_printf("-*player select number of players (1-4); defaults to 1\n");
++ VidDrv_printf("-*player select number of players (1-2); defaults to 1\n");
+ VidDrv_printf("-nopk do not allow players to kill each other in multiplayer games\n");
+ VidDrv_printf("-ep* select episode 1, 2, or 3; defaults to 1\n");
+ VidDrv_printf("-dtm go directly to the world map, bypassing intro and title screen\n");
+diff -Naur keen.orig/src/sdl/viddrv.c keen/src/sdl/viddrv.c
+--- keen.orig/src/sdl/viddrv.c 2005-11-16 20:08:30.000000000 -0500
++++ keen/src/sdl/viddrv.c 2010-03-26 03:06:24.000000000 -0400
+@@ -29,8 +29,10 @@
+
+ SDL_Rect dstrect;
+
++#ifndef TARGET_LNX
+ extern FILE *log;
+ #define CKLOGFILENAME "ck.log"
++#endif
+
+ #define MAX_CONSOLE_MESSAGES 3
+ #define CONSOLE_MESSAGE_X 3
+@@ -222,11 +224,11 @@
+ // applies all changes to the palette made with pal_set
+ void pal_apply(void)
+ {
+- SDL_SetColors(screen, &MyPalette, 0, 256);
+- SDL_SetColors(ScrollSurface, &MyPalette, 0, 256);
++ SDL_SetColors(screen, MyPalette, 0, 256);
++ SDL_SetColors(ScrollSurface, MyPalette, 0, 256);
+ if (blitsurface_alloc)
+ {
+- SDL_SetColors(BlitSurface, &MyPalette, 0, 256);
++ SDL_SetColors(BlitSurface, MyPalette, 0, 256);
+ }
+ }
+
+@@ -338,9 +340,9 @@
+ // shuts down the video driver
+ void VidDrv_Stop(void)
+ {
+- if(screen) { SDL_FreeSurface(screen); VidDrv_printf("freed screen\n"); }
+- if(ScrollSurface) { SDL_FreeSurface(ScrollSurface); VidDrv_printf("freed scrollsurface\n"); }
+- if(blitsurface_alloc) { blitsurface_alloc = 0; SDL_FreeSurface(BlitSurface); VidDrv_printf("freed blitsurface\n"); }
++ if(screen) { SDL_FreeSurface(screen); screen = NULL; VidDrv_printf("freed screen\n"); }
++ if(ScrollSurface) { SDL_FreeSurface(ScrollSurface); ScrollSurface = NULL; VidDrv_printf("freed scrollsurface\n"); }
++ if(blitsurface_alloc) { blitsurface_alloc = 0; SDL_FreeSurface(BlitSurface); BlitSurface = NULL; VidDrv_printf("freed blitsurface\n"); }
+ }
+
+ // resets graphics to allow changing of resolution or zoom settings
+@@ -365,10 +367,12 @@
+ // SDL-specific, not win32-specific)
+ void VidDrv_InitConsole(void)
+ {
++#ifndef TARGET_LNX
+ FILE *fp;
+ // erase contents of log file
+ fp = fopen(CKLOGFILENAME, "wb");
+ fclose(fp);
++#endif
+ }
+
+ void VidDrv_printf(const char *str, ...)
+diff -Naur keen.orig/src/unix_fopen_wrapper.c keen/src/unix_fopen_wrapper.c
+--- keen.orig/src/unix_fopen_wrapper.c 1969-12-31 19:00:00.000000000 -0500
++++ keen/src/unix_fopen_wrapper.c 2010-03-26 03:06:24.000000000 -0400
+@@ -0,0 +1,123 @@
++
++/* semi-case-insensitive fopen() replacement.
++
++Usage:
++
++#include "unix_fopen_wrapper.h"
++FILE *foo = fopen("bar.baz", "rb");
++
++fopen() gets redefined to unix_fopen() in the header file.
++unix_fopen() attempts to call the real fopen() on:
++
++bar.baz
++BAR.baz
++Bar.baz
++bar.BAZ
++BAR.BAZ
++Bar.BAZ
++bar.Baz
++BAR.Baz
++Bar.Baz
++
++It'll still miss e.g. baR.baz or bAr.baz
++
++If there's no . in the filename (e.g. "bar"), just check
++for bar, BAR, Bar
++*/
++
++#include <stdio.h>
++#include <ctype.h>
++#include <string.h>
++#include <limits.h>
++
++void lcase_all(char *c) {
++ if(!c || !*c) return;
++ while(*c && *c != '.') {
++ *c = tolower(*c);
++ c++;
++ }
++}
++
++void ucase_all(char *c) {
++ if(!c || !*c) return;
++ while(*c && *c != '.') {
++ *c = toupper(*c);
++ c++;
++ }
++}
++
++void ucase_first(char *c) {
++ if(!c || !*c) return;
++ lcase_all(c);
++ c[0] = toupper(c[0]);
++}
++
++FILE *unix_fopen(const char *path, const char *mode) {
++ FILE *result;
++ char realpath[PATH_MAX], *name, *ext;
++
++/* #define DEBUG_FOPEN */
++
++#ifdef DEBUG_FOPEN
++#define TRY_FOPEN(p, m) { \
++ result = fopen(p, m); \
++ fprintf(stderr, "-- %s:%d: (%s,%s): %s\n", \
++ __FILE__, __LINE__, p, m, (result ? "OK" : "fail")); \
++ if(result) return result; \
++}
++#else
++#define TRY_FOPEN(p, m) { if( (result = fopen(p, m)) ) return result; }
++#endif
++
++ /* try it as-is first */
++ TRY_FOPEN(path, mode);
++
++ /* parse into name and (possible) extension */
++ strcpy(realpath, path);
++ ext = strrchr(realpath, '.');
++ if(ext) {
++ ++ext;
++ if(!ext[0]) ext = NULL;
++ }
++
++ /* skip any directory component(s) */
++ name = strrchr(realpath, '/');
++ if(!name) name = realpath;
++
++ /* permutations... */
++ lcase_all(ext);
++ lcase_all(name);
++ TRY_FOPEN(realpath, mode);
++
++ ucase_all(name);
++ TRY_FOPEN(realpath, mode);
++
++ ucase_first(name);
++ TRY_FOPEN(realpath, mode);
++
++ ucase_all(ext);
++ lcase_all(name);
++ TRY_FOPEN(realpath, mode);
++
++ ucase_all(name);
++ TRY_FOPEN(realpath, mode);
++
++ ucase_first(name);
++ TRY_FOPEN(realpath, mode);
++
++ ucase_first(ext);
++ lcase_all(name);
++ TRY_FOPEN(realpath, mode);
++
++ ucase_all(name);
++ TRY_FOPEN(realpath, mode);
++
++ ucase_first(name);
++ TRY_FOPEN(realpath, mode);
++
++#ifdef DEBUG_FOPEN
++ fprintf(stderr, "%s:%s: TRY_FOPEN(%s,%s): Giving up",
++ __FILE__, __LINE__, path, mode);
++#endif
++ return NULL;
++}
+diff -Naur keen.orig/src/unix_fopen_wrapper.h keen/src/unix_fopen_wrapper.h
+--- keen.orig/src/unix_fopen_wrapper.h 1969-12-31 19:00:00.000000000 -0500
++++ keen/src/unix_fopen_wrapper.h 2010-03-26 03:06:24.000000000 -0400
+@@ -0,0 +1,2 @@
++FILE *unix_fopen(const char *path, const char *mode);
++#define fopen(x,y) unix_fopen(x,y)
diff --git a/games/clonekeen/story.txt b/games/clonekeen/story.txt
new file mode 100644
index 0000000000..484838b5be
--- /dev/null
+++ b/games/clonekeen/story.txt
@@ -0,0 +1,92 @@
+ COMMANDER KEEN
+ in
+ "Invasion of the Vorticons"
+
+
+Billy Blaze, eight year-old genius, working diligently in his backyard
+clubhouse has created an interstellar starship from old soup cans, rubber
+cement and plastic tubing. While his folks are out on the town and the
+babysitter has fallen asleep, Billy travels into his backyard workshop, dons
+his brother's football helmet, and transforms into...
+
+ COMMANDER KEEN--defender of Earth!
+
+In his ship, the Bean-with-Bacon Megarocket, Keen dispenses galactic justice
+with an iron hand!
+
+
+ Episode One: Marooned on Mars
+
+
+In this episode, aliens from the planet Vorticon VI find out about the eight
+year-old genius and plan his destruction. While Keen is out exploring the
+mountains of Mars, the Vorticons steal vital parts of his ship and take
+them to distant Martian cities! Can Keen recover all the pieces of his
+ship and repel the Vorticon invasion? Will he make it back before his
+parents get home? Stay tuned!
+
+ WHAT THE VORTICONS HAVE STOLEN
+
+The Bean-with-Bacon Megarocket was constructed from objects around the house
+that you have "modified" into starship parts:
+
+ JOYSTICK (from your brother's video game) Manual flight control.
+
+ CAR BATTERY (from your Mom's car) Electrical systems power.
+
+ VACUUM CLEANER (from the kitchen, heavily modified) Ion propulsion
+unit (with carpet height adjustment).
+
+ EVERCLEAR (from your Dad's liquor cabinet) Fuel.
+
+
+
+The Vorticons have taken these pieces to the far reaches of Mars and are
+guarding them. You must find the members of this Vorticon outpost and wrest
+the parts back from their wicked, clawed hands!
+
+ INFORMATION ON MARS
+
+Unbeknownst to NASA, when the Viking Lander settled to the surface of
+Mars, it caused a major political upheaval. Viking actually landed on the
+despotic Martian king! The Yorps (the extremely friendly one-eyed
+Martians) were free from enslavement, and the Gargs (the vicious, aggressive
+Martians) were angry.
+
+The Martians created robots for menial work and guard duties. Beware of the
+tank-like Guard Robots--they are VERY good at what they do.
+
+Martians have been visiting Earth in UFOs for decades. Why? They come to
+Earth for one reason--THEY WANT OUR TOYS. Hula hoops and skateboards are
+holy objects to them! Who knows...you may find some toys useful!
+
+There are signs everywhere. You haven't been able to decipher them yet....
+
+ THE ADVENTURE BEGINS...
+
+Your task is before you. Go get 'em, Commander Keen!
+
+______________________________________
+
+
+And don't miss episodes Two and Three in the "Invasion of the Vorticons"
+trilogy!
+
+
+ Episode Two: The Earth Explodes
+
+Keen has assembled his ship and returned home, only to find the Vorticon
+Mothership hovering over the Earth, ready to destroy all of Earth's cities
+and wonders! Keen must sneak aboard, stop the imminent destruction of Earth
+and find a way to neutralize the Mothership! If he fails...THE EARTH
+EXPLODES! (No pressure.)
+
+ Episode Three: Keen Must Die!
+
+Keen flies to the planet Vorticon VI to once and for all rid the galaxy of
+the Vorticon menace. The entire planet is waiting for his arrival, with
+only one order given--Commander Keen must die! What evil being is behind
+all this? Stay tuned for the climactic, shocking finale!
+
+
+Commander Keen says: "You won't believe what happens in Episode Three!"