2015-05-19 21:54:34 +00:00
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
/*
|
|
|
|
Copyright (C) 2007 Jonathon Fowler <jf@jonof.id.au>
|
|
|
|
|
|
|
|
This file is part of JFShadowWarrior
|
|
|
|
|
|
|
|
Shadow Warrior 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#import <Cocoa/Cocoa.h>
|
|
|
|
|
|
|
|
#include "compat.h"
|
|
|
|
#include "types.h"
|
|
|
|
#include "build.h"
|
|
|
|
#include "baselayer.h"
|
|
|
|
#include "grpscan.h"
|
|
|
|
#include "gamedefs.h"
|
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
#import "GrpFile.game.h"
|
|
|
|
#import "GameListSource.game.h"
|
|
|
|
|
|
|
|
static struct {
|
|
|
|
int fullscreen;
|
|
|
|
int xdim3d, ydim3d, bpp3d;
|
|
|
|
int forcesetup;
|
|
|
|
char selectedgrp[BMAX_PATH+1];
|
|
|
|
int samplerate, bitspersample, channels;
|
|
|
|
int usemouse, usejoystick;
|
|
|
|
} 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 NSButton *useMouseButton;
|
|
|
|
IBOutlet NSButton *useJoystickButton;
|
|
|
|
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.usemouse = [useMouseButton state] == NSOnState;
|
|
|
|
settings.usejoystick = [useJoystickButton state] == NSOnState;
|
|
|
|
settings.forcesetup = [alwaysShowButton state] == NSOnState;
|
|
|
|
|
|
|
|
[NSApp stopModal];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)setupRunMode
|
|
|
|
{
|
|
|
|
getvalidmodes();
|
|
|
|
|
|
|
|
[fullscreenButton setState: (settings.fullscreen ? NSOnState : NSOffState)];
|
|
|
|
[alwaysShowButton setState: (settings.forcesetup ? NSOnState : NSOffState)];
|
|
|
|
[useMouseButton setState: (settings.usemouse ? NSOnState : NSOffState)];
|
|
|
|
[useJoystickButton setState: (settings.usejoystick ? 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 stringWithUTF8String:settings.selectedgrp]];
|
|
|
|
if (row >= 0) {
|
|
|
|
[[gameList documentView] scrollRowToVisible:row];
|
|
|
|
[[gameList documentView] selectRowIndexes:[NSIndexSet indexSetWithIndex:row] byExtendingSelection:NO];
|
|
|
|
}
|
|
|
|
|
|
|
|
[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)
|
|
|
|
{
|
|
|
|
if (startwin != nil) return 1;
|
|
|
|
|
|
|
|
startwin = [[StartupWinController alloc] initWithWindowNibName:@"startwin.game"];
|
|
|
|
if (startwin == nil) return -1;
|
|
|
|
|
|
|
|
{
|
|
|
|
static unsigned soundQualityFrequencies[] = { 44100, 22050, 11025 };
|
|
|
|
static unsigned soundQualitySampleSizes[] = { 16, 8 };
|
|
|
|
static unsigned soundQualityChannels[] = { 2, 1 };
|
|
|
|
unsigned 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;
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
extern char* grpfile;
|
|
|
|
extern int32 ScreenMode, ScreenWidth, ScreenHeight, ScreenBPP, ForceSetup, UseMouse, UseJoystick;
|
|
|
|
|
|
|
|
int startwin_run(void)
|
|
|
|
{
|
|
|
|
int retval;
|
|
|
|
|
|
|
|
if (startwin == nil) return 0;
|
|
|
|
|
|
|
|
ScanGroups();
|
|
|
|
|
|
|
|
settings.fullscreen = ScreenMode;
|
|
|
|
settings.xdim3d = ScreenWidth;
|
|
|
|
settings.ydim3d = ScreenHeight;
|
|
|
|
settings.bpp3d = ScreenBPP;
|
|
|
|
settings.samplerate = MixRate;
|
|
|
|
settings.bitspersample = NumBits;
|
|
|
|
settings.channels = NumChannels;
|
|
|
|
settings.usemouse = UseMouse;
|
|
|
|
settings.usejoystick = UseJoystick;
|
|
|
|
settings.forcesetup = ForceSetup;
|
|
|
|
strncpy(settings.selectedgrp, grpfile, BMAX_PATH);
|
|
|
|
|
|
|
|
[startwin setupRunMode];
|
|
|
|
|
|
|
|
switch ([NSApp runModalForWindow:[startwin window]]) {
|
2015-10-10 06:57:46 +00:00
|
|
|
#ifdef MAC_OS_X_VERSION_10_9
|
|
|
|
case NSModalResponseStop: retval = 1; break;
|
|
|
|
case NSModalResponseAbort: retval = 0; break;
|
|
|
|
#else
|
2015-05-19 21:54:34 +00:00
|
|
|
case NSRunStoppedResponse: retval = 1; break;
|
|
|
|
case NSRunAbortedResponse: retval = 0; break;
|
2015-10-10 06:57:46 +00:00
|
|
|
#endif
|
2015-05-19 21:54:34 +00:00
|
|
|
default: retval = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
[startwin setupMessagesMode];
|
|
|
|
|
|
|
|
if (retval) {
|
|
|
|
ScreenMode = settings.fullscreen;
|
|
|
|
ScreenWidth = settings.xdim3d;
|
|
|
|
ScreenHeight = settings.ydim3d;
|
|
|
|
ScreenBPP = settings.bpp3d;
|
|
|
|
MixRate = settings.samplerate;
|
|
|
|
NumBits = settings.bitspersample;
|
|
|
|
NumChannels = settings.channels;
|
|
|
|
UseMouse = settings.usemouse;
|
|
|
|
UseJoystick = settings.usejoystick;
|
|
|
|
ForceSetup = settings.forcesetup;
|
|
|
|
grpfile = settings.selectedgrp;
|
|
|
|
}
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|