mirror of
https://github.com/DrBeef/Raze.git
synced 2024-11-16 09:21:12 +00:00
67ed6945fd
NAM and Napalm can now share their con, def, and rts files if the one for their respective game is not present because the con and rts files are identical. Also, decapitalize two string literals missed in r2540. git-svn-id: https://svn.eduke32.com/eduke32@2726 1a8010ca-5511-0410-912e-c29ae57300e0
448 lines
13 KiB
Objective-C
448 lines
13 KiB
Objective-C
// Objective-C programmers shall recoil in fear at this mess
|
|
|
|
#import <Cocoa/Cocoa.h>
|
|
|
|
#define GetTime xGetTime
|
|
#include "duke3d.h"
|
|
#include "game.h"
|
|
#undef GetTime
|
|
#include "common.h"
|
|
#include "common_game.h"
|
|
#include "build.h"
|
|
#include "compat.h"
|
|
#include "baselayer.h"
|
|
#include "grpscan.h"
|
|
|
|
#import "GrpFile.game.h"
|
|
#import "GameListSource.game.h"
|
|
|
|
static id nsapp;
|
|
|
|
static struct {
|
|
int fullscreen;
|
|
int xdim3d, ydim3d, bpp3d;
|
|
int forcesetup;
|
|
char selectedgrp[BMAX_PATH+1];
|
|
int game;
|
|
int samplerate, bitspersample, channels;
|
|
} settings;
|
|
|
|
static struct soundQuality_t {
|
|
int frequency;
|
|
int samplesize;
|
|
int channels;
|
|
} * soundQualities = 0;
|
|
|
|
|
|
@interface StartupWinController : NSWindowController
|
|
{
|
|
NSMutableArray *modeslist3d;
|
|
GameListSource *gamelistsrc;
|
|
|
|
IBOutlet NSButton *alwaysShowButton;
|
|
IBOutlet NSButton *fullscreenButton;
|
|
IBOutlet NSTextView *messagesView;
|
|
IBOutlet NSTabView *tabView;
|
|
IBOutlet NSPopUpButton *videoMode3DPUButton;
|
|
IBOutlet NSPopUpButton *soundQualityPUButton;
|
|
IBOutlet NSScrollView *gameList;
|
|
|
|
IBOutlet NSButton *cancelButton;
|
|
IBOutlet NSButton *startButton;
|
|
}
|
|
|
|
- (void)dealloc;
|
|
- (void)populateVideoModes:(BOOL)firstTime;
|
|
- (void)populateSoundQuality:(BOOL)firstTime;
|
|
|
|
- (IBAction)alwaysShowClicked:(id)sender;
|
|
- (IBAction)fullscreenClicked:(id)sender;
|
|
|
|
- (IBAction)cancel:(id)sender;
|
|
- (IBAction)start:(id)sender;
|
|
|
|
- (void)setupRunMode;
|
|
- (void)setupMessagesMode;
|
|
- (void)putsMessage:(NSString *)str;
|
|
- (void)setTitle:(NSString *)str;
|
|
|
|
@end
|
|
|
|
@implementation StartupWinController
|
|
|
|
- (void)dealloc
|
|
{
|
|
[gamelistsrc release];
|
|
[modeslist3d release];
|
|
[super dealloc];
|
|
}
|
|
|
|
- (void)populateVideoModes:(BOOL)firstTime
|
|
{
|
|
int i, mode3d, fullscreen = ([fullscreenButton state] == NSOnState);
|
|
int idx3d = -1;
|
|
int xdim, ydim, bpp;
|
|
|
|
if (firstTime) {
|
|
xdim = settings.xdim3d;
|
|
ydim = settings.ydim3d;
|
|
bpp = settings.bpp3d;
|
|
} else {
|
|
mode3d = [[modeslist3d objectAtIndex:[videoMode3DPUButton indexOfSelectedItem]] intValue];
|
|
if (mode3d >= 0) {
|
|
xdim = validmode[mode3d].xdim;
|
|
ydim = validmode[mode3d].ydim;
|
|
bpp = validmode[mode3d].bpp;
|
|
}
|
|
|
|
}
|
|
mode3d = checkvideomode(&xdim, &ydim, bpp, fullscreen, 1);
|
|
if (mode3d < 0) {
|
|
int i, cd[] = { 32, 24, 16, 15, 8, 0 };
|
|
for (i=0; cd[i]; ) { if (cd[i] >= bpp) i++; else break; }
|
|
for ( ; cd[i]; i++) {
|
|
mode3d = checkvideomode(&xdim, &ydim, cd[i], fullscreen, 1);
|
|
if (mode3d < 0) continue;
|
|
break;
|
|
}
|
|
}
|
|
|
|
[modeslist3d release];
|
|
[videoMode3DPUButton removeAllItems];
|
|
|
|
modeslist3d = [[NSMutableArray alloc] init];
|
|
|
|
for (i = 0; i < validmodecnt; i++) {
|
|
if (fullscreen == validmode[i].fs) {
|
|
if (i == mode3d) idx3d = [modeslist3d count];
|
|
[modeslist3d addObject:[NSNumber numberWithInt:i]];
|
|
[videoMode3DPUButton addItemWithTitle:[NSString stringWithFormat:@"%d %C %d %d-bpp",
|
|
validmode[i].xdim, 0xd7, validmode[i].ydim, validmode[i].bpp]];
|
|
}
|
|
}
|
|
|
|
if (idx3d >= 0) [videoMode3DPUButton selectItemAtIndex:idx3d];
|
|
}
|
|
|
|
- (void)populateSoundQuality:(BOOL)firstTime
|
|
{
|
|
int i, curidx = -1;
|
|
|
|
[soundQualityPUButton removeAllItems];
|
|
|
|
for (i = 0; soundQualities[i].frequency > 0; i++) {
|
|
const char *ch;
|
|
switch (soundQualities[i].channels) {
|
|
case 1: ch = "Mono"; break;
|
|
case 2: ch = "Stereo"; break;
|
|
default: ch = "?"; break;
|
|
}
|
|
|
|
NSString *s = [NSString stringWithFormat:@"%dkHz, %d-bit, %s",
|
|
soundQualities[i].frequency / 1000,
|
|
soundQualities[i].samplesize,
|
|
ch
|
|
];
|
|
[soundQualityPUButton addItemWithTitle:s];
|
|
|
|
if (firstTime &&
|
|
soundQualities[i].frequency == settings.samplerate &&
|
|
soundQualities[i].samplesize == settings.bitspersample &&
|
|
soundQualities[i].channels == settings.channels) {
|
|
curidx = i;
|
|
}
|
|
}
|
|
|
|
if (firstTime && curidx < 0) {
|
|
soundQualities[i].frequency = settings.samplerate;
|
|
soundQualities[i].samplesize = settings.bitspersample;
|
|
soundQualities[i].channels = settings.channels;
|
|
|
|
const char *ch;
|
|
switch (soundQualities[i].channels) {
|
|
case 1: ch = "Mono"; break;
|
|
case 2: ch = "Stereo"; break;
|
|
default: ch = "?"; break;
|
|
}
|
|
NSString *s = [NSString stringWithFormat:@"%dkHz, %d-bit, %s",
|
|
soundQualities[i].frequency / 1000,
|
|
soundQualities[i].samplesize,
|
|
ch
|
|
];
|
|
[soundQualityPUButton addItemWithTitle:s];
|
|
|
|
curidx = i++;
|
|
soundQualities[i].frequency = -1;
|
|
}
|
|
|
|
if (curidx >= 0) {
|
|
[soundQualityPUButton selectItemAtIndex:curidx];
|
|
}
|
|
}
|
|
|
|
- (IBAction)alwaysShowClicked:(id)sender
|
|
{
|
|
}
|
|
|
|
- (IBAction)fullscreenClicked:(id)sender
|
|
{
|
|
[self populateVideoModes:NO];
|
|
}
|
|
|
|
- (IBAction)cancel:(id)sender
|
|
{
|
|
[nsapp abortModal];
|
|
}
|
|
|
|
- (IBAction)start:(id)sender
|
|
{
|
|
int mode = [[modeslist3d objectAtIndex:[videoMode3DPUButton indexOfSelectedItem]] intValue];
|
|
if (mode >= 0) {
|
|
settings.xdim3d = validmode[mode].xdim;
|
|
settings.ydim3d = validmode[mode].ydim;
|
|
settings.bpp3d = validmode[mode].bpp;
|
|
settings.fullscreen = validmode[mode].fs;
|
|
}
|
|
|
|
int quality = [soundQualityPUButton indexOfSelectedItem];
|
|
if (quality >= 0) {
|
|
settings.samplerate = soundQualities[quality].frequency;
|
|
settings.bitspersample = soundQualities[quality].samplesize;
|
|
settings.channels = soundQualities[quality].channels;
|
|
}
|
|
|
|
int row = [[gameList documentView] selectedRow];
|
|
if (row >= 0) {
|
|
struct grpfile *p = [[gamelistsrc grpAtIndex:row] entryptr];
|
|
if (p) {
|
|
strcpy(settings.selectedgrp, p->name);
|
|
settings.game = p->game;
|
|
}
|
|
}
|
|
|
|
settings.forcesetup = [alwaysShowButton state] == NSOnState;
|
|
|
|
[nsapp stopModal];
|
|
}
|
|
|
|
- (void)setupRunMode
|
|
{
|
|
getvalidmodes();
|
|
|
|
[fullscreenButton setState: (settings.fullscreen ? NSOnState : NSOffState)];
|
|
[alwaysShowButton setState: (settings.forcesetup ? NSOnState : NSOffState)];
|
|
[self populateVideoModes:YES];
|
|
[self populateSoundQuality:YES];
|
|
|
|
// enable all the controls on the Configuration page
|
|
NSEnumerator *enumerator = [[[[tabView tabViewItemAtIndex:0] view] subviews] objectEnumerator];
|
|
NSControl *control;
|
|
while ((control = [enumerator nextObject])) [control setEnabled:true];
|
|
|
|
gamelistsrc = [[GameListSource alloc] init];
|
|
[[gameList documentView] setDataSource:gamelistsrc];
|
|
[[gameList documentView] deselectAll:nil];
|
|
|
|
int row = [gamelistsrc findIndexForGrpname:[NSString stringWithCString:settings.selectedgrp]];
|
|
if (row >= 0) {
|
|
[[gameList documentView] scrollRowToVisible:row];
|
|
#if defined(MAC_OS_X_VERSION_10_3) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_3)
|
|
[[gameList documentView] selectRowIndexes:[NSIndexSet indexSetWithIndex:row] byExtendingSelection:NO];
|
|
#else
|
|
[[gameList documentView] selectRow:row byExtendingSelection:NO];
|
|
#endif
|
|
}
|
|
|
|
[cancelButton setEnabled:true];
|
|
[startButton setEnabled:true];
|
|
|
|
[tabView selectTabViewItemAtIndex:0];
|
|
[NSCursor unhide]; // Why should I need to do this?
|
|
}
|
|
|
|
- (void)setupMessagesMode
|
|
{
|
|
[tabView selectTabViewItemAtIndex:2];
|
|
|
|
// disable all the controls on the Configuration page except "always show", so the
|
|
// user can enable it if they want to while waiting for something else to happen
|
|
NSEnumerator *enumerator = [[[[tabView tabViewItemAtIndex:0] view] subviews] objectEnumerator];
|
|
NSControl *control;
|
|
while ((control = [enumerator nextObject])) {
|
|
if (control == alwaysShowButton) continue;
|
|
[control setEnabled:false];
|
|
}
|
|
|
|
[cancelButton setEnabled:false];
|
|
[startButton setEnabled:false];
|
|
}
|
|
|
|
- (void)putsMessage:(NSString *)str
|
|
{
|
|
NSRange end;
|
|
NSTextStorage *text = [messagesView textStorage];
|
|
BOOL shouldAutoScroll;
|
|
|
|
shouldAutoScroll = ((int)NSMaxY([messagesView bounds]) == (int)NSMaxY([messagesView visibleRect]));
|
|
|
|
end.location = [text length];
|
|
end.length = 0;
|
|
|
|
[text beginEditing];
|
|
[messagesView replaceCharactersInRange:end withString:str];
|
|
[text endEditing];
|
|
|
|
if (shouldAutoScroll) {
|
|
end.location = [text length];
|
|
end.length = 0;
|
|
[messagesView scrollRangeToVisible:end];
|
|
}
|
|
}
|
|
|
|
- (void)setTitle:(NSString *)str
|
|
{
|
|
[[self window] setTitle:str];
|
|
}
|
|
|
|
@end
|
|
|
|
static StartupWinController *startwin = nil;
|
|
|
|
int startwin_open(void)
|
|
{
|
|
// PK: is this the entry point?
|
|
|
|
// fix for "ld: absolute address to symbol _NSApp in a different linkage unit not supported"
|
|
// (OS X 10.6) when building for PPC
|
|
nsapp = [NSApplication sharedApplication];
|
|
|
|
if (startwin != nil) return 1;
|
|
|
|
startwin = [[StartupWinController alloc] initWithWindowNibName:@"startwin.game"];
|
|
if (startwin == nil) return -1;
|
|
|
|
{
|
|
static int soundQualityFrequencies[] = { 48000, 44100, 32000, 24000, 22050 };
|
|
static int soundQualitySampleSizes[] = { 16, 8 };
|
|
static int soundQualityChannels[] = { 2, 1 };
|
|
int f, b, c, i;
|
|
|
|
i = sizeof(soundQualityFrequencies) *
|
|
sizeof(soundQualitySampleSizes) *
|
|
sizeof(soundQualityChannels) /
|
|
sizeof(int) + 2; // one for the terminator, one for a custom setting
|
|
soundQualities = (struct soundQuality_t *) malloc(i * sizeof(struct soundQuality_t));
|
|
|
|
i = 0;
|
|
for (c = 0; c < sizeof(soundQualityChannels) / sizeof(int); c++) {
|
|
for (b = 0; b < sizeof(soundQualitySampleSizes) / sizeof(int); b++) {
|
|
for (f = 0; f < sizeof(soundQualityFrequencies) / sizeof(int); f++) {
|
|
soundQualities[i].frequency = soundQualityFrequencies[f];
|
|
soundQualities[i].samplesize = soundQualitySampleSizes[b];
|
|
soundQualities[i].channels = soundQualityChannels[c];
|
|
|
|
i++;
|
|
}
|
|
}
|
|
}
|
|
|
|
soundQualities[i].frequency = -1;
|
|
}
|
|
|
|
[startwin setupMessagesMode];
|
|
[startwin showWindow:nil];
|
|
|
|
return 0;
|
|
}
|
|
|
|
int startwin_close(void)
|
|
{
|
|
if (startwin == nil) return 1;
|
|
|
|
[startwin close];
|
|
[startwin release];
|
|
startwin = nil;
|
|
|
|
free(soundQualities);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int startwin_puts(const char *s)
|
|
{
|
|
NSString *ns;
|
|
|
|
if (!s) return -1;
|
|
if (startwin == nil) return 1;
|
|
|
|
ns = [[NSString alloc] initWithCString:s];
|
|
[startwin putsMessage:ns];
|
|
[ns release];
|
|
|
|
return 0;
|
|
}
|
|
|
|
int startwin_settitle(const char *s)
|
|
{
|
|
NSString *ns;
|
|
|
|
if (!s) return -1;
|
|
if (startwin == nil) return 1;
|
|
|
|
ns = [[NSString alloc] initWithCString:s];
|
|
[startwin setTitle:ns];
|
|
[ns release];
|
|
|
|
return 0;
|
|
}
|
|
|
|
int startwin_idle(void *v)
|
|
{
|
|
if (startwin) [[startwin window] displayIfNeeded];
|
|
return 0;
|
|
}
|
|
|
|
|
|
int startwin_run(void)
|
|
{
|
|
int retval;
|
|
|
|
if (startwin == nil) return 0;
|
|
|
|
settings.fullscreen = ud.config.ScreenMode;
|
|
settings.xdim3d = ud.config.ScreenWidth;
|
|
settings.ydim3d = ud.config.ScreenHeight;
|
|
settings.bpp3d = ud.config.ScreenBPP;
|
|
settings.samplerate = ud.config.MixRate;
|
|
settings.bitspersample = ud.config.NumBits;
|
|
settings.channels = ud.config.NumChannels;
|
|
settings.forcesetup = ud.config.ForceSetup;
|
|
// settings.game = gametype;
|
|
strncpy(settings.selectedgrp, G_GrpFile(), BMAX_PATH);
|
|
|
|
[startwin setupRunMode];
|
|
|
|
switch ([nsapp runModalForWindow:[startwin window]]) {
|
|
case NSRunStoppedResponse: retval = 1; break;
|
|
case NSRunAbortedResponse: retval = 0; break;
|
|
default: retval = -1;
|
|
}
|
|
|
|
[startwin setupMessagesMode];
|
|
|
|
if (retval) {
|
|
ud.config.ScreenMode = settings.fullscreen;
|
|
ud.config.ScreenWidth = settings.xdim3d;
|
|
ud.config.ScreenHeight = settings.ydim3d;
|
|
ud.config.ScreenBPP = settings.bpp3d;
|
|
ud.config.MixRate = settings.samplerate;
|
|
ud.config.NumBits = settings.bitspersample;
|
|
ud.config.NumChannels = settings.channels;
|
|
ud.config.ForceSetup = settings.forcesetup;
|
|
clearGrpNamePtr();
|
|
g_grpNamePtr = dup_filename(settings.selectedgrp);
|
|
// gametype = settings.game;
|
|
}
|
|
|
|
return retval;
|
|
}
|