Commit c93ad6f7 authored by Fabian Greffrath's avatar Fabian Greffrath

Imported Upstream version 1.1.1

parent df1f9556
......@@ -4,7 +4,7 @@ ROTT Port README
This is a port of Apogee's 3D action title Rise of the Triad, originally
released in 1994. This port duplicates the functionality of the original
game on modern operating systems, including Linux, Win32, and OSX.
game on modern operating systems, including Linux, Win32, and Mac OS X.
This port makes use of the Simple Direct Media Layer, or SDL, and an additional
library named SDL_mixer. If you do not have these libraries installed, check
......@@ -12,18 +12,57 @@ the links section below.
This software is distributed in source code format and is licensed under the
terms of the GNU General Public License. A copy of this license is included
with the software in the file gnu.txt.
with the software in the file COPYING.
This software is not supported by 3D Realms, Apogee, or the porters.
For reference, the primary contributors to this port are:
Steven Fuller
Ryan Gordon
Ryan C. Gordon
John Hall
Dan Olson
-------------------------
Notes for the 1.1 Release
-------------------------
Thanks to the effort of the contributors listed below (and probably many more),
lots of bug fixes, portability improvements and new features have found their
way into the 1.1 release. Many changes have been ported over from the WinRott
port (not WinRottGL but plain WinRott) with the high resolution software
rendering support being the main feature of all these changes. Portability
fixes include support for 64-bit and big-endian systems.
Birger N. Andreasen (author of the WinRott port
<http://home14.inet.tele.dk/Bna-Info/>, initial work by Jonathan Bailey)
Hans de Goede (porting of the WinRott high resolution renderer,
lots of bug and portability fixes for the Fedora package)
Alexander Thomas aka Dr. Lex (author of the OS X port
<http://www.dr-lex.be/software/rott.html>, thanks Filippo Giunchedi for
creating the appropriate patch for the Debian package)
Michael Karcher (lots of bug and portability fixes for the Debian package)
Fabian Greffrath (some minor improvements)
---------------------------
Notes for the 1.1.1 Release
---------------------------
Version 1.1.1 is merely a bugfix release that contains all the patches that
have accumulated in Fedora and Debian during the previous year.
Enabling the use of UNICODE (instead of keyboard scancodes) for the cheat codes
and names in the highscore table is considered the release goal for the next
point release. Getting network play working is considered the release goal for
the 2.0 version. Work on both of these projects has not yet begun, though...
In this context: Please send bug reports, questions, suggestions and comments
to the Fedora or Debian maintainers of the respective rott packages in these
distributions. Patches are always welcome. ;-)
-------------
General Hints
-------------
......@@ -55,8 +94,6 @@ Known Issues
------------
- Demos go out of sync.
- DOS border coloring not implemented.
- Screen shake from DOS version not implemented.
- No netplay support.
......
......@@ -51,7 +51,7 @@ And on and on... And thanks to Scott and George, for providing a place for us to
A little history...
by Scott Miller
ROTT, as it quickly became known, marked a turning point for Apogee. It was our first in-house game since I started the company in 1987 with my home grown Kroz games, the games that started the shareware revolution that resulted in the launch of three of the most successful independent PC developers, Epic, Id, and us -- all three still kicking after 12+ years (as of Dec. '02). It's hard to believe we're among the oldest of all surviving independent PC developers in the world now. Before ROTT, Apogee, as we were then known, solely worked with outside development teams, often funding and helping organize these teams, and helping guide their game designs using our experience. But around 1993 it was evident that this method wasn't going to work out much longer because as games got larger and more complicated to make, team sizes had to grow, too. So, in 1994 we started hiring developers to form our own internal team, with the first of those hires including William Scarboro, Nolan Martin, Mark Dochtermann, Jim Dosé, and the ever creative Tom Hall to run the show.
ROTT, as it quickly became known, marked a turning point for Apogee. It was our first in-house game since I started the company in 1987 with my home grown Kroz games, the games that started the shareware revolution that resulted in the launch of three of the most successful independent PC developers, Epic, Id, and us -- all three still kicking after 12+ years (as of Dec. '02). It's hard to believe we're among the oldest of all surviving independent PC developers in the world now. Before ROTT, Apogee, as we were then known, solely worked with outside development teams, often funding and helping organize these teams, and helping guide their game designs using our experience. But around 1993 it was evident that this method wasn't going to work out much longer because as games got larger and more complicated to make, team sizes had to grow, too. So, in 1994 we started hiring developers to form our own internal team, with the first of those hires including William Scarboro, Nolan Martin, Mark Dochtermann, Jim Dosé, and the ever creative Tom Hall to run the show.
As Tom notes above, ROTT was originally an Id-approved sequel to Wolfenstein 3-D, using the original Wolf engine. The game was going to be called, Wolfenstein: Rise of the Triad, and explore what happened after Hitler's demise. About 4-5 months into development, though, a surprise call from John Romero ended the project, and we were left with a lot of content specific to the Wolfenstein premise, which had to be rolled into a new game concept so that we didn't waste all that we'd done. The result was a bit of a mish-mash, and as Tom says above, the project probably should've been restarted using our new Build engine, which our second internal team down the hall was using, making Duke Nukem 3D.
......
.TH ROTT 6 "2008-04-23" "1.0" "Rise of the Triad"
.SH NAME
rott \- Rise of the Triad
.SH SYNOPSIS
.B rott
.RI [ options ]
.SH DESCRIPTION
.B ROTT
is a port of Apogee's 3D action title Rise of the Triad, originally released in 1994.
This port duplicates the functionality of the original game on modern operating systems, including Linux, Win32, and Mac OS X.
.SH OPTIONS
.TP
.BR aim
Give aim crosshair.
.TP
.BR fullscreen
Start in fullscreen mode.
.TP
.BR window
Start in windowed mode.
.TP
.BR resolution\ \fIwidth\fPx\fIheight\fP
Specify the screen resolution to use (next parameter is widthxheight).
Valid resolutions are 320x200, 640x480 and 800x600.
.TP
.BR spaceball
Enable check for Spaceball.
.TP
.BR nojoys
Disable check for joystick.
.TP
.BR nomouse
Disable check for mouse.
.TP
.BR nosound
Disable sound.
.TP
.BR cyberman
Enable check for Cyberman.
.TP
.BR assassin
Enable check for Wingman Assassin.
.TP
.BR ver
Version number.
.TP
.BR mapstats
Dump Map statistics to ERROR.
.TP
.BR tilestats
Dump Tile statistics to ERROR.
.TP
.BR mono
Enable mono-monitor support.
.TP
.BR screenshots
Clean screen capture for shots.
.TP
.BR pause
Pauses startup screen information.
.TP
.BR enablevr
Enable VR helmet input devices.
.TP
.BR noecho
Turn off sound reverb.
.TP
.BR demoexit
Exit program when demo is terminated.
.TP
.BR warp\ \fIlevel\fP
Warp to specific ROTT level (next paramater is level to start on).
.TP
.BR timelimit\ \fItime\fP
Play ROTT in time limit mode (next paramater is time in seconds).
.TP
.BR maxtimelimit\ \fItime\fP
Maximimum time to count down from (next paramater is time in seconds).
.TP
.BR dopefish
?
.SH AUTHORS
ROTT was created and published as shareware by Apogee Software, Ltd. and was published commercially by FormGen, Inc.
.PP
The primary contributors to the icculus.org port are: Steven Fuller, Ryan C. Gordon, John Hall and Dan Olson.
.PP
This manual page was written by Fabian Greffrath <fabian@debian-unofficial.org>
for the Debian project (but may be used by others).
.386
.MODEL flat
SCREENROW = 96
;================
;
; R_DrawFilmColumn
;
;================
SCREENWIDTH = 96
.data
loopcount dd 0
pixelcount dd 0
_cin_yl dd 0
_cin_yh dd 0
_cin_ycenter dd 0
_cin_iscale dd 0
_cin_texturemid dd 0
_cin_source dd 0
PUBLIC _cin_yl
PUBLIC _cin_yh
PUBLIC _cin_ycenter
PUBLIC _cin_iscale
PUBLIC _cin_texturemid
PUBLIC _cin_source
EXTRN _ylookup:DWORD
.code
SEGMENT text USE32
ALIGN 16
PROC R_DrawFilmColumn_
PUBLIC R_DrawFilmColumn_
push ebp
mov ebp,[_cin_yl]
mov ebx,ebp
add edi,[_ylookup+ebx*4]
mov eax,[_cin_yh]
inc eax
sub eax,ebp ; pixel count
mov [pixelcount],eax ; save for final pixel
js done ; nothing to scale
shr eax,1 ; double pixel count
mov [loopcount],eax
mov ecx,[_cin_iscale]
mov eax,[_cin_ycenter]
sub eax,ebp
imul ecx
mov ebp,[_cin_texturemid]
sub ebp,eax
mov esi,[_cin_source]
mov ebx,[_cin_iscale]
mov eax,OFFSET patch1+2 ; convice tasm to modify code...
mov [eax],ebx
mov eax,OFFSET patch2+2 ; convice tasm to modify code...
mov [eax],ebx
; eax aligned colormap
; ebx aligned colormap
; ecx,edx scratch
; esi virtual source
; edi moving destination pointer
; ebp frac
mov ecx,ebp ; begin calculating first pixel
add ebp,ebx ; advance frac pointer
shr ecx,16 ; finish calculation for first pixel
mov edx,ebp ; begin calculating second pixel
add ebp,ebx ; advance frac pointer
shr edx,16 ; finish calculation for second pixel
mov al,[esi+ecx] ; get first pixel
mov bl,[esi+edx] ; get second pixel
test [pixelcount],0fffffffeh
jnz doubleloop ; at least two pixels to map
jmp checklast
ALIGN 16
doubleloop:
mov ecx,ebp ; begin calculating third pixel
patch1:
add ebp,12345678h ; advance frac pointer
mov [edi],al ; write first pixel
shr ecx,16 ; finish calculation for third pixel
mov edx,ebp ; begin calculating fourth pixel
patch2:
add ebp,12345678h ; advance frac pointer
mov [edi+SCREENWIDTH],bl ; write second pixel
shr edx,16 ; finish calculation for fourth pixel
mov al,[esi+ecx] ; get third pixel
add edi,SCREENWIDTH*2 ; advance to third pixel destination
mov bl,[esi+edx] ; get fourth pixel
dec [loopcount] ; done with loop?
jnz doubleloop
; check for final pixel
checklast:
test [pixelcount],1
jz done
mov [edi],al ; write final pixel
done:
pop ebp
ret
ENDP
;============================
;
; DrawFilmPost
;
;
;============================
IDEAL
PROC DrawFilmPost_
PUBLIC DrawFilmPost_
;EDI - Destination for post
;ESI - Source data
;ECX - Length of post
mov ebx,ecx
shr ebx,1
jz dfextra
dfloop:
mov ax,[esi]
mov [edi],al
add esi,2
add edi,SCREENROW*2
mov [edi-SCREENROW],ah
dec ebx
jnz dfloop
MASKFLAG ecx,1
jz dfdone
dfextra:
mov al,[esi]
mov [edi],al
dfdone:
ret
ENDP
ENDS
END
B/* Localized versions of Info.plist keys */
This diff is collapsed.
/* SDLMain.m - main entry point for our Cocoa-ized SDL app
Initial Version: Darrell Walisser <dwaliss1@purdue.edu>
Non-NIB-Code & other changes: Max Horn <max@quendi.de>
Feel free to customize this file to suit your needs
*/
#import <Cocoa/Cocoa.h>
@interface SDLMain : NSObject
@end
/* SDLMain.m - main entry point for our Cocoa-ized SDL app
Initial Version: Darrell Walisser <dwaliss1@purdue.edu>
Non-NIB-Code & other changes: Max Horn <max@quendi.de>
Feel free to customize this file to suit your needs
*/
#import "SDL.h"
#import "SDLMain.h"
#import <sys/param.h> /* for MAXPATHLEN */
#import <unistd.h>
/* Use this flag to determine whether we use SDLMain.nib or not */
#define SDL_USE_NIB_FILE 0
static int gArgc;
static char **gArgv;
static BOOL gFinderLaunch;
#if SDL_USE_NIB_FILE
/* A helper category for NSString */
@interface NSString (ReplaceSubString)
- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString;
@end
#else
/* An internal Apple class used to setup Apple menus */
@interface NSAppleMenuController:NSObject {}
- (void)controlMenu:(NSMenu *)aMenu;
@end
#endif
@interface SDLApplication : NSApplication
@end
@implementation SDLApplication
/* Invoked from the Quit menu item */
- (void)terminate:(id)sender
{
/* Post a SDL_QUIT event */
SDL_Event event;
event.type = SDL_QUIT;
SDL_PushEvent(&event);
}
@end
/* The main class of the application, the application's delegate */
@implementation SDLMain
/* Set the working directory to the .app's parent directory */
- (void) setupWorkingDirectory:(BOOL)shouldChdir
{
char parentdir[MAXPATHLEN];
char *c;
strncpy ( parentdir, gArgv[0], sizeof(parentdir) );
c = (char*) parentdir;
while (*c != '\0') /* go to end */
c++;
while (*c != '/') /* back up to parent */
c--;
*c++ = '\0'; /* cut off last part (binary name) */
if (shouldChdir)
{
assert ( chdir (parentdir) == 0 ); /* chdir to the binary app's parent */
assert ( chdir ("../../../") == 0 ); /* chdir to the .app's parent */
}
}
#if SDL_USE_NIB_FILE
/* Fix menu to contain the real app name instead of "SDL App" */
- (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName
{
NSRange aRange;
NSEnumerator *enumerator;
NSMenuItem *menuItem;
aRange = [[aMenu title] rangeOfString:@"SDL App"];
if (aRange.length != 0)
[aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:appName]];
enumerator = [[aMenu itemArray] objectEnumerator];
while ((menuItem = [enumerator nextObject]))
{
aRange = [[menuItem title] rangeOfString:@"SDL App"];
if (aRange.length != 0)
[menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:appName]];
if ([menuItem hasSubmenu])
[self fixMenu:[menuItem submenu] withAppName:appName];
}
[ aMenu sizeToFit ];
}
#else
void setupAppleMenu(void)
{
/* warning: this code is very odd */
NSAppleMenuController *appleMenuController;
NSMenu *appleMenu;
NSMenuItem *appleMenuItem;
appleMenuController = [[NSAppleMenuController alloc] init];
appleMenu = [[NSMenu alloc] initWithTitle:@""];
appleMenuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
[appleMenuItem setSubmenu:appleMenu];
/* yes, we do need to add it and then remove it --
if you don't add it, it doesn't get displayed
if you don't remove it, you have an extra, titleless item in the menubar
when you remove it, it appears to stick around
very, very odd */
[[NSApp mainMenu] addItem:appleMenuItem];
[appleMenuController controlMenu:appleMenu];
[[NSApp mainMenu] removeItem:appleMenuItem];
[appleMenu release];
[appleMenuItem release];
}
/* Create a window menu */
void setupWindowMenu(void)
{
NSMenu *windowMenu;
NSMenuItem *windowMenuItem;
NSMenuItem *menuItem;
windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
/* "Minimize" item */
menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"];
[windowMenu addItem:menuItem];
[menuItem release];
/* Put menu into the menubar */
windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""];
[windowMenuItem setSubmenu:windowMenu];
[[NSApp mainMenu] addItem:windowMenuItem];
/* Tell the application object that this is now the window menu */
[NSApp setWindowsMenu:windowMenu];
/* Finally give up our references to the objects */
[windowMenu release];
[windowMenuItem release];
}
/* Replacement for NSApplicationMain */
void CustomApplicationMain (argc, argv)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
SDLMain *sdlMain;
/* Ensure the application object is initialised */
[SDLApplication sharedApplication];
/* Set up the menubar */
[NSApp setMainMenu:[[NSMenu alloc] init]];
setupAppleMenu();
setupWindowMenu();
/* Create SDLMain and make it the app delegate */
sdlMain = [[SDLMain alloc] init];
[NSApp setDelegate:sdlMain];
/* Start the main event loop */
[NSApp run];
[sdlMain release];
[pool release];
}
#endif
/* Called when the internal event loop has just started running */
- (void) applicationDidFinishLaunching: (NSNotification *) note
{
int status;
/* Set the working directory to the .app's parent directory */
[self setupWorkingDirectory:gFinderLaunch];
#if SDL_USE_NIB_FILE
/* Set the main menu to contain the real app name instead of "SDL App" */
[self fixMenu:[NSApp mainMenu] withAppName:[[NSProcessInfo processInfo] processName]];
#endif
/* Hand off to main application code */
status = SDL_main (gArgc, gArgv);
/* We're done, thank you for playing */
exit(status);
}
@end
@implementation NSString (ReplaceSubString)
- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString
{
unsigned int bufferSize;
unsigned int selfLen = [self length];
unsigned int aStringLen = [aString length];
unichar *buffer;
NSRange localRange;
NSString *result;
bufferSize = selfLen + aStringLen - aRange.length;
buffer = NSAllocateMemoryPages(bufferSize*sizeof(unichar));
/* Get first part into buffer */
localRange.location = 0;
localRange.length = aRange.location;
[self getCharacters:buffer range:localRange];
/* Get middle part into buffer */
localRange.location = 0;
localRange.length = aStringLen;
[aString getCharacters:(buffer+aRange.location) range:localRange];
/* Get last part into buffer */
localRange.location = aRange.location + aRange.length;
localRange.length = selfLen - localRange.location;
[self getCharacters:(buffer+aRange.location+aStringLen) range:localRange];
/* Build output string */
result = [NSString stringWithCharacters:buffer length:bufferSize];
NSDeallocateMemoryPages(buffer, bufferSize);
return result;
}
@end
#ifdef main
# undef main
#endif
/* Main entry point to executable - should *not* be SDL_main! */
int main (int argc, char **argv)
{
/* Copy the arguments into a global variable */
int i;
/* This is passed if we are launched by double-clicking */
if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) {
gArgc = 1;
gFinderLaunch = YES;
} else {
gArgc = argc;
gFinderLaunch = NO;
}
gArgv = (char**) malloc (sizeof(*gArgv) * (gArgc+1));
assert (gArgv != NULL);
for (i = 0; i < gArgc; i++)
gArgv[i] = argv[i];
gArgv[i] = NULL;
#if SDL_USE_NIB_FILE
[SDLApplication poseAsClass:[NSApplication class]];
NSApplicationMain (argc, argv);
#else
CustomApplicationMain (argc, argv);
#endif
return 0;
}
[Desktop Entry]
Type=Application
Name=Rise of the Triad
Comment=A high quality, fast scrolling first-person perspective 3D action game
Icon=rott
TryExec=rott