File: macmain.c

package info (click to toggle)
nethack 3.4.3-6
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 13,512 kB
  • ctags: 16,957
  • sloc: ansic: 196,792; cpp: 7,083; sh: 6,785; yacc: 2,005; lex: 377; makefile: 120; awk: 89; sed: 11
file content (288 lines) | stat: -rw-r--r-- 6,337 bytes parent folder | download | duplicates (12)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
/*	SCCS Id: @(#)macmain.c	3.1	97/01/22	*/
/* 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 !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;

	windowprocs = mac_procs;
	InitMac ();

	hname = "Mac Hack";
	hackpid = getpid();

	/*
	 * Initialisation of the boundaries of the mazes
	 * Both boundaries have to be even.
	 */

	x_maze_max = COLNO-1;
	if (x_maze_max % 2)
		x_maze_max--;
	y_maze_max = ROWNO-1;
	if (y_maze_max % 2)
		y_maze_max--;

	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();

#ifdef WIZARD
	if (wizard)
		Strcpy(plname, "wizard");
	else
#endif
	if(!*plname || !strncmp(plname, "player", 4) || !strncmp(plname, "games", 4))
		askname();
	plnamesuffix();		/* strip suffix from name; calls askname() */
				/* again if suffix was whole name */
				/* accepts any suffix */

	Sprintf (lock, "%d%s", getuid (), plname);
	getlock ();

	if ((fd = restore_saved_game()) >= 0) {
#ifdef WIZARD
		/* Since wizard is actually flags.debug, restoring might
		 * overwrite it.
		 */
		boolean remember_wiz_mode = wizard;
#endif
#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)) {
#ifdef WIZARD
			if(!wizard && remember_wiz_mode) wizard = TRUE;
#endif
			check_special_room(FALSE);

			if (discover || wizard) {
				if(yn("Do you want to keep the save file?") == 'n')
					(void) delete_savefile();
				else {
					compress(fqname(SAVEF, SAVEPREFIX, 0));
				}
			}
		}
		else {
			fd = -1; /* set bad status */
		}
	}
	if (fd < 0) {
		player_selection();
		game_active = 1;	/* done with selection, draw active game window */
		newgame();
		set_wear();
		(void) pickup(1);
	}

	if (discover)
		You("are in non-scoring discovery mode.");
	flags.move = 0;

	UndimMenuBar (); /* Yes, this is the place for it (!) */
	
	moveloop();

	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();
				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 */
}

/*macmain.c*/