Files
nethack/sys/mac/macmain.c
2015-02-27 19:33:22 -05:00

292 lines
7.0 KiB
C

/* NetHack 3.5 macmain.c $NHDT-Date$ $NHDT-Branch$:$NHDT-Revision$ */
/* NetHack 3.5 macmain.c $Date: 2009/05/06 10:49:11 $ $Revision: 1.15 $ */
/* SCCS Id: @(#)macmain.c 3.5 2008/01/30 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
/* main.c - Mac NetHack */
#include "hack.h"
#include "dlb.h"
#include "macwin.h"
#include "mactty.h"
#if 1 /*!TARGET_API_MAC_CARBON*/
#include <OSUtils.h>
#include <files.h>
#include <Types.h>
#include <Dialogs.h>
#include <Packages.h>
#include <ToolUtils.h>
#include <Resources.h>
#include <Errors.h>
#endif
#ifndef O_RDONLY
#include <fcntl.h>
#endif
static void finder_file_request(void);
int main(void);
#if __SC__ || __MRC__
QDGlobals qd;
#endif
int
main (void)
{
register int fd = -1;
int argc = 1;
boolean resuming = FALSE; /* assume new game */
sys_early_init();
windowprocs = mac_procs;
InitMac ();
hname = "Mac Hack";
hackpid = getpid();
setrandom();
initoptions();
init_nhwindows(&argc, (char **)&hname);
/*
* It seems you really want to play.
*/
u.uhp = 1; /* prevent RIP on early quits */
finder_file_request ();
dlb_init(); /* must be before newgame() */
/*
* Initialize the vision system. This must be before mklev() on a
* new game or before a level restore on a saved game.
*/
vision_init();
display_gamewindows();
set_playmode(); /* sets plname to "wizard" for wizard mode */
/* strip role,race,&c suffix; calls askname() if plname[] is empty
or holds a generic user name like "player" or "games" */
plnamesuffix();
/* unlike Unix where the game might be invoked with a script
which forces a particular character name for each player
using a shared account, we always allow player to rename
the character during role/race/&c selection */
iflags.renameallowed = TRUE;
getlock();
/*
* First, try to find and restore a save file for specified character.
* We'll return here if new game player_selection() renames the hero.
*/
attempt_restore:
if ((fd = restore_saved_game()) >= 0) {
#ifdef NEWS
if(iflags.news) {
display_file(NEWS, FALSE);
iflags.news = FALSE; /* in case dorecover() fails */
}
#endif
pline("Restoring save file...");
mark_synch(); /* flush output */
game_active = 1;
if (dorecover(fd)) {
resuming = TRUE; /* not starting new game */
if (discover)
You("are in non-scoring discovery mode.");
if (discover || wizard) {
if(yn("Do you want to keep the save file?") == 'n')
(void) delete_savefile();
else {
nh_compress(fqname(SAVEF, SAVEPREFIX, 0));
}
}
}
}
if (!resuming) {
/* new game: start by choosing role, race, etc;
player might change the hero's name while doing that,
in which case we try to restore under the new name
and skip selection this time if that didn't succeed */
if (!iflags.renameinprogress) {
player_selection();
if (iflags.renameinprogress) {
/* player has renamed the hero while selecting role;
discard current lock file and create another for
the new character name */
delete_levelfile(0); /* remove empty lock file */
getlock();
goto attempt_restore;
}
}
game_active = 1; /* done with selection, draw active game window */
newgame();
if (discover)
You("are in non-scoring discovery mode.");
}
UndimMenuBar (); /* Yes, this is the place for it (!) */
moveloop(resuming);
exit(EXIT_SUCCESS);
/*NOTREACHED*/
return 0;
}
static OSErr
copy_file(short src_vol, long src_dir, short dst_vol, long dst_dir,
Str255 fName,
pascal OSErr (*opener)(short vRefNum, long dirID,
ConstStr255Param fileName,
signed char permission, short *refNum)) {
short src_ref, dst_ref;
OSErr err = (*opener)(src_vol, src_dir, fName, fsRdPerm, &src_ref);
if (err == noErr) {
err = (*opener)(dst_vol, dst_dir, fName, fsWrPerm, &dst_ref);
if (err == noErr) {
long file_len;
err = GetEOF(src_ref, &file_len);
if (err == noErr) {
Handle buf;
long count = MaxBlock();
if (count > file_len)
count = file_len;
buf = NewHandle(count);
err = MemError();
if (err == noErr) {
while (count > 0) {
OSErr rd_err = FSRead(src_ref, &count, *buf);
err = FSWrite(dst_ref, &count, *buf);
if (err == noErr)
err = rd_err;
file_len -= count;
}
if (file_len == 0)
err = noErr;
DisposeHandle(buf);
}
}
FSClose(dst_ref);
}
FSClose(src_ref);
}
return err;
}
static void
force_hdelete(short vol, long dir, Str255 fName)
{
HRstFLock(vol, dir, fName);
HDelete (vol, dir, fName);
}
void
process_openfile (short src_vol, long src_dir, Str255 fName, OSType ftype)
{
OSErr err = noErr;
if (ftype != SAVE_TYPE)
return; /* only deal with save files */
if (src_vol != theDirs.dataRefNum || src_dir != theDirs.dataDirID &&
CatMove(src_vol, src_dir, fName, theDirs.dataDirID, "\p:") != noErr) {
HCreate(theDirs.dataRefNum, theDirs.dataDirID, fName, MAC_CREATOR, SAVE_TYPE);
err = copy_file(src_vol, src_dir, theDirs.dataRefNum, theDirs.dataDirID,
fName, &HOpen); /* HOpenDF is only there under 7.0 */
if (err == noErr)
err = copy_file(src_vol, src_dir, theDirs.dataRefNum, theDirs.dataDirID,
fName, &HOpenRF);
if (err == noErr)
force_hdelete(src_vol, src_dir, fName);
else
HDelete(theDirs.dataRefNum, theDirs.dataDirID, fName);
}
if (err == noErr) {
short ref;
ref = HOpenResFile(theDirs.dataRefNum, theDirs.dataDirID, fName, fsRdPerm);
if (ref != -1) {
Handle name = Get1Resource('STR ', PLAYER_NAME_RES_ID);
if (name) {
Str255 save_f_p;
P2C(*(StringHandle)name, plname);
set_savefile_name(TRUE);
C2P(fqname(SAVEF, SAVEPREFIX, 0), save_f_p);
force_hdelete(theDirs.dataRefNum, theDirs.dataDirID, save_f_p);
if (HRename(theDirs.dataRefNum, theDirs.dataDirID, fName, save_f_p) == noErr)
macFlags.gotOpen = 1;
}
CloseResFile(ref);
}
}
}
static void
finder_file_request(void)
{
if (macFlags.hasAE) {
/* we're capable of handling Apple Events, so let's see if we have any */
EventRecord event;
long toWhen = TickCount () + 20; /* wait a third of a second for all initial AE */
while (TickCount () < toWhen) {
if (WaitNextEvent (highLevelEventMask, &event, 3L, 0)) {
AEProcessAppleEvent(&event);
if (macFlags.gotOpen)
break;
}
}
}
#if 0
#ifdef MAC68K
else {
short finder_msg, file_count;
CountAppFiles(&finder_msg, &file_count);
if (finder_msg == appOpen && file_count == 1) {
OSErr err;
AppFile src;
FSSpec filespec;
GetAppFiles(1, &src);
err = FSMakeFSSpec(src.vRefNum, 0, src.fName, &filespec);
if (err == noErr && src.fType == SAVE_TYPE) {
process_openfile (filespec.vRefNum, filespec.parID, filespec.name, src.fType);
if (macFlags.gotOpen)
ClrAppFiles(1);
}
}
}
#endif /* MAC68K */
#endif /* 0 */
}
/* validate wizard mode if player has requested access to it */
boolean
authorize_wizard_mode()
{
/* other ports validate user name or character name here */
return TRUE;
}
/*macmain.c*/