mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-12-25 17:40:36 +00:00
fixes for Emscripten, and for compiling without tutorial
This commit is contained in:
parent
0e9119c7b2
commit
4570fa2ea4
@ -84,7 +84,9 @@ bool wrongMode(char flags) {
|
|||||||
if(randomPatternsMode) return true;
|
if(randomPatternsMode) return true;
|
||||||
if(yendor::on) return true;
|
if(yendor::on) return true;
|
||||||
if(tactic::on) return true;
|
if(tactic::on) return true;
|
||||||
|
#ifdef TOUR
|
||||||
if(tour::on) return true;
|
if(tour::on) return true;
|
||||||
|
#endif
|
||||||
if(chaosmode != (flags == 'C')) return true;
|
if(chaosmode != (flags == 'C')) return true;
|
||||||
if((numplayers() > 1) != (flags == 'm')) return true;
|
if((numplayers() > 1) != (flags == 'm')) return true;
|
||||||
return false;
|
return false;
|
||||||
@ -519,7 +521,9 @@ void achievement_final(bool really_final) {
|
|||||||
#ifdef HAVE_ACHIEVEMENTS
|
#ifdef HAVE_ACHIEVEMENTS
|
||||||
// upload_score(LB_STATISTICS, time(NULL));
|
// upload_score(LB_STATISTICS, time(NULL));
|
||||||
if(cheater) return;
|
if(cheater) return;
|
||||||
|
#ifdef TOUR
|
||||||
if(tour::on) return;
|
if(tour::on) return;
|
||||||
|
#endif
|
||||||
|
|
||||||
if(sphere && euclidland == laHalloween) {
|
if(sphere && euclidland == laHalloween) {
|
||||||
if(shmup::on || chaosmode || purehepta || numplayers() > 1 || tactic::on || randomPatternsMode)
|
if(shmup::on || chaosmode || purehepta || numplayers() > 1 || tactic::on || randomPatternsMode)
|
||||||
|
472
direntx.c
Normal file
472
direntx.c
Normal file
@ -0,0 +1,472 @@
|
|||||||
|
/*
|
||||||
|
* dirent.c
|
||||||
|
*
|
||||||
|
* This file has no copyright assigned and is placed in the Public Domain.
|
||||||
|
*
|
||||||
|
* This file is a part of the mingw-runtime package.
|
||||||
|
* No warranty is given; refer to the file DISCLAIMER within the package.
|
||||||
|
*
|
||||||
|
* Derived from DIRLIB.C by Matt J. Weinstein
|
||||||
|
* This note appears in the DIRLIB.H
|
||||||
|
* DIRLIB.H by M. J. Weinstein Released to public domain 1-Jan-89
|
||||||
|
*
|
||||||
|
* Updated by Jeremy Bettis <jeremy@hksys.com>
|
||||||
|
* Significantly revised and rewinddir, seekdir and telldir added
|
||||||
|
* by Colin Peters <colin@fu.is.saga-u.ac.jp>
|
||||||
|
* Further significantly revised for improved memory utilisation,
|
||||||
|
* efficiency in operation, and better POSIX standards compliance
|
||||||
|
* by Keith Marshall <keithmarshall@users.sourceforge.net>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <io.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
_CRTIMP char* __cdecl __MINGW_NOTHROW _fullpath (char*, const char*, size_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <windows.h>
|
||||||
|
#include <tchar.h>
|
||||||
|
|
||||||
|
#define DIRENT_RETURN_NOTHING
|
||||||
|
#define DIRENT_REJECT( chk, err, rtn ) \
|
||||||
|
do { if( chk ){ errno = (err); return rtn; }} while(0)
|
||||||
|
|
||||||
|
union __dirstream_t
|
||||||
|
{
|
||||||
|
/* Actual (private) declaration for opaque data type "DIR". */
|
||||||
|
|
||||||
|
/* dirent struct to return from dir (NOTE: this makes this thread
|
||||||
|
* safe as long as only one thread uses a particular DIR struct at
|
||||||
|
* a time) */
|
||||||
|
struct dirent dd_dir;
|
||||||
|
|
||||||
|
struct __dirstream_private_t
|
||||||
|
{
|
||||||
|
/* Three padding fields, matching the head of dd_dir...
|
||||||
|
*/
|
||||||
|
long dd_ino; /* Always zero. */
|
||||||
|
unsigned short dd_reclen; /* Always zero. */
|
||||||
|
unsigned short dd_namlen; /* Length of name in d_name. */
|
||||||
|
|
||||||
|
/* ...to keep the start of this disk transfer area for this dir
|
||||||
|
* aligned at the offset of the dd_dir.d_type field
|
||||||
|
*/
|
||||||
|
struct _finddata_t dd_dta;
|
||||||
|
|
||||||
|
/* _findnext handle */
|
||||||
|
intptr_t dd_handle;
|
||||||
|
|
||||||
|
/* Status of search:
|
||||||
|
* (type is now int -- was short in older versions).
|
||||||
|
* 0 = not started yet (next entry to read is first entry)
|
||||||
|
* -1 = off the end
|
||||||
|
* positive = 0 based index of next entry
|
||||||
|
*/
|
||||||
|
int dd_stat;
|
||||||
|
|
||||||
|
/* given path for dir with search pattern (struct is extended) */
|
||||||
|
char dd_name[1];
|
||||||
|
|
||||||
|
} dd_private;
|
||||||
|
};
|
||||||
|
|
||||||
|
union __wdirstream_t
|
||||||
|
{
|
||||||
|
/* Actual (private) declaration for opaque data type "_WDIR". */
|
||||||
|
|
||||||
|
/* dirent struct to return from dir (NOTE: this makes this thread
|
||||||
|
* safe as long as only one thread uses a particular DIR struct at
|
||||||
|
* a time) */
|
||||||
|
struct _wdirent dd_dir;
|
||||||
|
|
||||||
|
struct __wdirstream_private_t
|
||||||
|
{
|
||||||
|
/* Three padding fields, matching the head of dd_dir...
|
||||||
|
*/
|
||||||
|
long dd_ino; /* Always zero. */
|
||||||
|
unsigned short dd_reclen; /* Always zero. */
|
||||||
|
unsigned short dd_namlen; /* Length of name in d_name. */
|
||||||
|
|
||||||
|
/* ...to keep the start of this disk transfer area for this dir
|
||||||
|
* aligned at the offset of the dd_dir.d_type field
|
||||||
|
*/
|
||||||
|
struct _wfinddata_t dd_dta;
|
||||||
|
|
||||||
|
/* _findnext handle */
|
||||||
|
intptr_t dd_handle;
|
||||||
|
|
||||||
|
/* Status of search:
|
||||||
|
* 0 = not started yet (next entry to read is first entry)
|
||||||
|
* -1 = off the end
|
||||||
|
* positive = 0 based index of next entry
|
||||||
|
*/
|
||||||
|
int dd_stat;
|
||||||
|
|
||||||
|
/* given path for dir with search pattern (struct is extended) */
|
||||||
|
wchar_t dd_name[1];
|
||||||
|
|
||||||
|
} dd_private;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* We map the BSD d_type field in the returned dirent structure
|
||||||
|
* from the Microsoft _finddata_t dd_dta.attrib bits, which are:
|
||||||
|
*
|
||||||
|
* _A_NORMAL (0x0000) normal file: best fit for DT_REG
|
||||||
|
* _A_RDONLY (0x0001) read-only: no BSD d_type equivalent
|
||||||
|
* _A_HIDDEN (0x0002) hidden entity: no BSD equivalent
|
||||||
|
* _A_SYSTEM (0x0004) system entity: no BSD equivalent
|
||||||
|
* _A_VOLID (0x0008) volume label: no BSD equivalent
|
||||||
|
* _A_SUBDIR (0x0010) directory: best fit for DT_DIR
|
||||||
|
* _A_ARCH (0x0020) "dirty": no BSD equivalent
|
||||||
|
*
|
||||||
|
* Of these, _A_RDONLY, _A_HIDDEN, _A_SYSTEM, and _A_ARCH are
|
||||||
|
* modifier bits, rather than true entity type specifiers; we
|
||||||
|
* will ignore them in the mapping, by applying this mask:
|
||||||
|
*/
|
||||||
|
#define DT_IGNORED (_A_RDONLY | _A_HIDDEN | _A_SYSTEM | _A_ARCH)
|
||||||
|
|
||||||
|
#define DIRENT_OPEN(D) \
|
||||||
|
((D).dd_handle = _tfindfirst((D).dd_name, &((D).dd_dta)))
|
||||||
|
|
||||||
|
#define DIRENT_UPDATE(D) \
|
||||||
|
_tfindnext( (D).dd_handle, &(D).dd_dta )
|
||||||
|
|
||||||
|
|
||||||
|
/*****
|
||||||
|
*
|
||||||
|
* opendir()
|
||||||
|
*
|
||||||
|
* Returns a pointer to a DIR structure appropriately filled in
|
||||||
|
* to begin searching a directory.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
_TDIR *
|
||||||
|
_topendir( const _TCHAR *path_name )
|
||||||
|
{
|
||||||
|
_TDIR *nd;
|
||||||
|
_TCHAR abs_path[MAX_PATH];
|
||||||
|
|
||||||
|
/* Reject any request which passes a NULL or an empty path name;
|
||||||
|
* note that POSIX doesn't specify the handling for the NULL case,
|
||||||
|
* and some implementations may simply fail with a segmentation
|
||||||
|
* fault. We will fail more gracefully. Previous versions used
|
||||||
|
* EFAULT here, but EINVAL seems more appropriate; however, POSIX
|
||||||
|
* specifies neither of these for any opendir() failure.
|
||||||
|
*/
|
||||||
|
DIRENT_REJECT( (path_name == NULL), EINVAL, (_TDIR *)(NULL) );
|
||||||
|
/*
|
||||||
|
* Conversely, POSIX *does* specify ENOENT for the empty path
|
||||||
|
* name case, where we previously had ENOTDIR; here, we correct
|
||||||
|
* this previous anomaly.
|
||||||
|
*/
|
||||||
|
DIRENT_REJECT( (*path_name == _T('\0')), ENOENT, (_TDIR *)(NULL) );
|
||||||
|
|
||||||
|
/* Identify the absolute path name corresponding to the (maybe
|
||||||
|
* relative) path name we are to process; (this ensures that we
|
||||||
|
* may always refer back to this same path name, e.g. to rewind
|
||||||
|
* the "directory stream", even after an intervening change of
|
||||||
|
* current working directory).
|
||||||
|
*/
|
||||||
|
_tfullpath( abs_path, path_name, MAX_PATH );
|
||||||
|
|
||||||
|
/* Ensure that the generated absolute path name ends with a
|
||||||
|
* directory separator (backslash) character, so that we may
|
||||||
|
* correctly append a wild-card matching pattern which will
|
||||||
|
* cause _findfirst() and _findnext() to return every entry
|
||||||
|
* in the specified directory; (note that, for now we may
|
||||||
|
* simply assume that abs_path refers to a directory;
|
||||||
|
* we will verify that when we call _findfirst() on it).
|
||||||
|
*/
|
||||||
|
if( *abs_path != _T('\0') )
|
||||||
|
{
|
||||||
|
size_t offset = _tcslen( abs_path ) - 1;
|
||||||
|
if( (abs_path[offset] != _T('/')) && (abs_path[offset] != _T('\\')) )
|
||||||
|
_tcscat( abs_path, _T("\\") );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now append the "match everything" wild-card pattern.
|
||||||
|
*/
|
||||||
|
_tcscat( abs_path, _T("*") );
|
||||||
|
|
||||||
|
/* Allocate space to store DIR structure. The size MUST be
|
||||||
|
* adjusted to accommodate the complete absolute path name for
|
||||||
|
* the specified directory, extended to include the wild-card
|
||||||
|
* matching pattern, as above; (note that we DO NOT need any
|
||||||
|
* special provision for the terminating NUL on the path name,
|
||||||
|
* since the base size of the DIR structure includes it).
|
||||||
|
*/
|
||||||
|
nd = (_TDIR *)(malloc(
|
||||||
|
sizeof( _TDIR ) + (_tcslen( abs_path ) * sizeof( _TCHAR ))
|
||||||
|
));
|
||||||
|
|
||||||
|
/* Bail out, if insufficient memory.
|
||||||
|
*/
|
||||||
|
DIRENT_REJECT( (nd == NULL), ENOMEM, (_TDIR *)(NULL) );
|
||||||
|
|
||||||
|
/* Copy the extended absolute path name string into place
|
||||||
|
* within the allocated space for the DIR structure.
|
||||||
|
*/
|
||||||
|
_tcscpy( nd->dd_private.dd_name, abs_path );
|
||||||
|
|
||||||
|
/* Initialize the "directory stream", by calling _findfirst() on it;
|
||||||
|
* this leaves the data for the first directory entry in the internal
|
||||||
|
* dirent buffer, ready to be retrieved by readdir().
|
||||||
|
*/
|
||||||
|
if( DIRENT_OPEN( nd->dd_private ) == (intptr_t)(-1) )
|
||||||
|
{
|
||||||
|
/* The _findfirst() call, (implied by DIRENT_OPEN), failed;
|
||||||
|
* _findfirst() sets EINVAL where POSIX mandates ENOTDIR...
|
||||||
|
*/
|
||||||
|
if( errno == EINVAL )
|
||||||
|
errno = ENOTDIR;
|
||||||
|
|
||||||
|
/* ...otherwise, while it may not be strictly POSIX conformant,
|
||||||
|
* just accept whatever value _findfirst() assigned to errno. In
|
||||||
|
* any event, prepare to return the NULL "directory stream"; since
|
||||||
|
* this implies that we will lose our reference pointer to the
|
||||||
|
* block of memory we allocated for the stream, free that
|
||||||
|
* before we bail out.
|
||||||
|
*/
|
||||||
|
free( nd );
|
||||||
|
return (_TDIR *)(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize the status, (i.e. the location index), so that
|
||||||
|
* readdir() will simply return the first directory entry, which
|
||||||
|
* has already been fetched by _findfirst(), without performing
|
||||||
|
* an intervening _findnext() call.
|
||||||
|
*/
|
||||||
|
nd->dd_private.dd_stat = 0;
|
||||||
|
|
||||||
|
/* The d_ino and d_reclen fields have no relevance in MS-Windows;
|
||||||
|
* initialize them to zero, as a one-time assignment for this DIR
|
||||||
|
* instance, and henceforth forget them; (users should simply
|
||||||
|
* ignore them).
|
||||||
|
*/
|
||||||
|
nd->dd_dir.d_ino = 0;
|
||||||
|
nd->dd_dir.d_reclen = 0;
|
||||||
|
|
||||||
|
/* We've now completely initialized an instance of a DIR structure,
|
||||||
|
* representing the requested "directory stream"; return a pointer
|
||||||
|
* via which the caller may access it.
|
||||||
|
*/
|
||||||
|
return nd;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*****
|
||||||
|
*
|
||||||
|
* readdir()
|
||||||
|
*
|
||||||
|
* Return a pointer to a dirent structure filled in with information
|
||||||
|
* on the next available entry, (if any), in the "directory stream".
|
||||||
|
*/
|
||||||
|
struct _tdirent *
|
||||||
|
_treaddir( _TDIR *dirp )
|
||||||
|
{
|
||||||
|
/* Check for a valid DIR stream reference; (we can't really
|
||||||
|
* be certain until we try to read from it, except in the case
|
||||||
|
* of a NULL pointer reference). Where we lack a valid reference,
|
||||||
|
* POSIX mandates reporting EBADF; we previously had EFAULT, so
|
||||||
|
* this version corrects the former anomaly.
|
||||||
|
*/
|
||||||
|
DIRENT_REJECT( (dirp == NULL), EBADF, (struct _tdirent *)(NULL) );
|
||||||
|
|
||||||
|
/* Okay to proceed. If this is the first readdir() request
|
||||||
|
* following an opendir(), or a rewinddir(), then we already
|
||||||
|
* have the requisite return information...
|
||||||
|
*/
|
||||||
|
if( dirp->dd_private.dd_stat++ > 0 )
|
||||||
|
{
|
||||||
|
/* Otherwise...
|
||||||
|
*
|
||||||
|
* Get the next search entry. POSIX mandates that this must
|
||||||
|
* return NULL after the last entry has been read, but that it
|
||||||
|
* MUST NOT change errno in this case. MS-Windows _findnext()
|
||||||
|
* DOES change errno (to ENOENT) after the last entry has been
|
||||||
|
* read, so we must be prepared to restore it to its previous
|
||||||
|
* value, when no actual error has occurred.
|
||||||
|
*/
|
||||||
|
int prev_errno = errno;
|
||||||
|
if( DIRENT_UPDATE( dirp->dd_private ) != 0 )
|
||||||
|
{
|
||||||
|
/* May be an error, or just the case described above...
|
||||||
|
*/
|
||||||
|
if( GetLastError() == ERROR_NO_MORE_FILES )
|
||||||
|
/*
|
||||||
|
* ...which requires us to reset errno.
|
||||||
|
*/
|
||||||
|
errno = prev_errno;
|
||||||
|
|
||||||
|
/* In either case, there is no valid data to return.
|
||||||
|
*/
|
||||||
|
return (struct _tdirent *)(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Successfully got an entry. Everything about the file is
|
||||||
|
* already appropriately filled in, except for the length of
|
||||||
|
* the file name in the d_namlen field...
|
||||||
|
*/
|
||||||
|
dirp->dd_dir.d_namlen = _tcslen( dirp->dd_dir.d_name );
|
||||||
|
/*
|
||||||
|
* ...and the attributes returned in the dd_dta.attrib field;
|
||||||
|
* these require adjustment to their BSD equivalents, which are
|
||||||
|
* returned via the union with the dd_dir.d_type field:
|
||||||
|
*/
|
||||||
|
switch( dirp->dd_dir.d_type &= ~DT_IGNORED )
|
||||||
|
{
|
||||||
|
case DT_REG:
|
||||||
|
case DT_DIR:
|
||||||
|
/* After stripping out the modifier bits in DT_IGNORED,
|
||||||
|
* (which we ALWAYS ignore), this pair require no further
|
||||||
|
* adjustment...
|
||||||
|
*/
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* ...while nothing else has an appropriate equivalent
|
||||||
|
* in the BSD d_type identification model.
|
||||||
|
*/
|
||||||
|
dirp->dd_dir.d_type = DT_UNKNOWN;
|
||||||
|
}
|
||||||
|
return &dirp->dd_dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*****
|
||||||
|
*
|
||||||
|
* closedir()
|
||||||
|
*
|
||||||
|
* Frees up resources allocated by opendir().
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
_tclosedir( _TDIR * dirp )
|
||||||
|
{
|
||||||
|
/* Attempting to reference a directory stream via a NULL pointer
|
||||||
|
* would cause a segmentation fault; evade this. Since NULL can
|
||||||
|
* never represent an open directory stream, set the EBADF errno
|
||||||
|
* status, as mandated by POSIX, once again correcting previous
|
||||||
|
* anomalous use of EFAULT in this context.
|
||||||
|
*/
|
||||||
|
DIRENT_REJECT(
|
||||||
|
((dirp == NULL) || (_findclose( dirp->dd_private.dd_handle ) != 0)),
|
||||||
|
EBADF, -1
|
||||||
|
);
|
||||||
|
|
||||||
|
/* If we didn't bail out above, we have a valid DIR structure
|
||||||
|
* with which we have finished; release the memory allocated
|
||||||
|
* to it, before returning "success".
|
||||||
|
*/
|
||||||
|
free( dirp );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*****
|
||||||
|
*
|
||||||
|
* rewinddir()
|
||||||
|
*
|
||||||
|
* Return to the beginning of the directory "stream". We simply call
|
||||||
|
* _findclose(), to clear prior context, then _findfirst() to restart
|
||||||
|
* the directory search, resetting the location index appropriately,
|
||||||
|
* as it would be left by opendir().
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
_trewinddir( _TDIR * dirp )
|
||||||
|
{
|
||||||
|
/* This is an XSI extension to POSIX, which specifies no formal
|
||||||
|
* error conditions; we will continue to check for and evade the
|
||||||
|
* potential segmentation fault which would result from passing a
|
||||||
|
* NULL reference pointer. For consistency with the core functions
|
||||||
|
* implemented above, we will again report this as EBADF, rather
|
||||||
|
* than the EFAULT of previous versions.
|
||||||
|
*/
|
||||||
|
DIRENT_REJECT(
|
||||||
|
((dirp == NULL) || (_findclose( dirp->dd_private.dd_handle ) != 0)),
|
||||||
|
EBADF, DIRENT_RETURN_NOTHING
|
||||||
|
);
|
||||||
|
|
||||||
|
/* We successfully closed the prior search context; reopen...
|
||||||
|
*/
|
||||||
|
if( DIRENT_OPEN( dirp->dd_private ) != (intptr_t)(-1) )
|
||||||
|
/*
|
||||||
|
* ...and, on success, reset the location index.
|
||||||
|
*/
|
||||||
|
dirp->dd_private.dd_stat = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*****
|
||||||
|
*
|
||||||
|
* telldir()
|
||||||
|
*
|
||||||
|
* Returns the "position" in the "directory stream" which can then
|
||||||
|
* be passed to seekdir(), to return back to a previous entry. We
|
||||||
|
* simply return the current location index from the dd_stat field.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
long
|
||||||
|
_ttelldir( _TDIR * dirp )
|
||||||
|
{
|
||||||
|
/* This too is a POSIX-XSI extension, with no mandatory error
|
||||||
|
* conditions. Once again, evade a potential segmentation fault
|
||||||
|
* on passing a NULL reference pointer, again reporting it as
|
||||||
|
* EBADF in preference to the EFAULT of previous versions.
|
||||||
|
*/
|
||||||
|
DIRENT_REJECT( (dirp == NULL), EBADF, -1 );
|
||||||
|
|
||||||
|
/* We didn't bail out; just assume dirp is valid, and return
|
||||||
|
* the location index from the dd_stat field.
|
||||||
|
*/
|
||||||
|
return dirp->dd_private.dd_stat;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*****
|
||||||
|
*
|
||||||
|
* seekdir()
|
||||||
|
*
|
||||||
|
* Seek to an entry previously returned by telldir(). We rewind
|
||||||
|
* the "directory stream", then repeatedly call _findnext() while
|
||||||
|
* incrementing its internal location index until it matches the
|
||||||
|
* position requested, or we reach the end of the stream. This is
|
||||||
|
* not perfect, in that the directory may have changed while we
|
||||||
|
* weren't looking, but it is the best we can achieve, and may
|
||||||
|
* likely reproduce the behaviour of other implementations.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
_tseekdir( _TDIR * dirp, long loc )
|
||||||
|
{
|
||||||
|
/* Another POSIX-XSI extension, with no specified mandatory
|
||||||
|
* error conditions; we require a seek location of zero or
|
||||||
|
* greater, and will reject less than zero as EINVAL...
|
||||||
|
*/
|
||||||
|
DIRENT_REJECT( (loc < 0L), EINVAL, DIRENT_RETURN_NOTHING );
|
||||||
|
|
||||||
|
/* Other than this, we simply accept any error condition
|
||||||
|
* which arises as we "rewind" the "directory stream"...
|
||||||
|
*/
|
||||||
|
_trewinddir( dirp );
|
||||||
|
|
||||||
|
/* ...and, if this is successful...
|
||||||
|
*/
|
||||||
|
if( (loc > 0) && (dirp->dd_private.dd_handle != (intptr_t)(-1)) )
|
||||||
|
/*
|
||||||
|
* ...seek forward until the location index within
|
||||||
|
* the DIR structure matches the requested location.
|
||||||
|
*/
|
||||||
|
while( (++dirp->dd_private.dd_stat < loc)
|
||||||
|
&& (DIRENT_UPDATE( dirp->dd_private ) == 0) )
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* $RCSfile: dirent.c,v $: end of file */
|
4
game.cpp
4
game.cpp
@ -5392,8 +5392,10 @@ void movecost(cell* from, cell *to) {
|
|||||||
addMessage(XLAT("As you leave, your powers are drained!"));
|
addMessage(XLAT("As you leave, your powers are drained!"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef TOUR
|
||||||
if(from->land != to->land && tour::on)
|
if(from->land != to->land && tour::on)
|
||||||
tour::checkGoodLand(to->land);
|
tour::checkGoodLand(to->land);
|
||||||
|
#endif
|
||||||
|
|
||||||
if(to->land ==laCrossroads4 && !chaosUnlocked) {
|
if(to->land ==laCrossroads4 && !chaosUnlocked) {
|
||||||
achievement_gain("CR4");
|
achievement_gain("CR4");
|
||||||
@ -5574,10 +5576,12 @@ bool collectItem(cell *c2, bool telekinesis) {
|
|||||||
if(shmup::on) gainLife();
|
if(shmup::on) gainLife();
|
||||||
else placeGolem(cwt.c, c2, moTameBomberbird);
|
else placeGolem(cwt.c, c2, moTameBomberbird);
|
||||||
}
|
}
|
||||||
|
#ifdef TOUR
|
||||||
else if(tour::on && (c2->item == itOrbSafety || c2->item == itOrbRecall)) {
|
else if(tour::on && (c2->item == itOrbSafety || c2->item == itOrbRecall)) {
|
||||||
addMessage(XLAT("This Orb is not compatible with the Tutorial."));
|
addMessage(XLAT("This Orb is not compatible with the Tutorial."));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
else if(c2->item == itOrbSafety) {
|
else if(c2->item == itOrbSafety) {
|
||||||
playSound(c2, "pickup-orb"); // TODO safety
|
playSound(c2, "pickup-orb"); // TODO safety
|
||||||
items[c2->item] += 7;
|
items[c2->item] += 7;
|
||||||
|
@ -6728,8 +6728,10 @@ void showGameover() {
|
|||||||
dialog::addInfo(XLAT("Your score: %1", its(gold())));
|
dialog::addInfo(XLAT("Your score: %1", its(gold())));
|
||||||
dialog::addInfo(XLAT("Enemies killed: %1", its(tkills())));
|
dialog::addInfo(XLAT("Enemies killed: %1", its(tkills())));
|
||||||
|
|
||||||
if(tour::on) ;
|
#ifdef TOUR
|
||||||
else if(items[itOrbYendor]) {
|
if(tour::on) ; else
|
||||||
|
#endif
|
||||||
|
if(items[itOrbYendor]) {
|
||||||
dialog::addInfo(XLAT("Orbs of Yendor found: %1", its(items[itOrbYendor])), iinf[itOrbYendor].color);
|
dialog::addInfo(XLAT("Orbs of Yendor found: %1", its(items[itOrbYendor])), iinf[itOrbYendor].color);
|
||||||
dialog::addInfo(XLAT("CONGRATULATIONS!"), iinf[itOrbYendor].color);
|
dialog::addInfo(XLAT("CONGRATULATIONS!"), iinf[itOrbYendor].color);
|
||||||
}
|
}
|
||||||
@ -7638,9 +7640,11 @@ void drawscreen() {
|
|||||||
|
|
||||||
#ifndef MOBILE
|
#ifndef MOBILE
|
||||||
if(cmode == emNormal || cmode == emVisual1 || cmode == emVisual2 || cmode == emChangeMode ) {
|
if(cmode == emNormal || cmode == emVisual1 || cmode == emVisual2 || cmode == emChangeMode ) {
|
||||||
|
#ifdef TOUR
|
||||||
if(tour::on)
|
if(tour::on)
|
||||||
displayButton(vid.xres-8, vid.yres-vid.fsize, XLAT("(ESC) tour menu"), SDLK_ESCAPE, 16);
|
displayButton(vid.xres-8, vid.yres-vid.fsize, XLAT("(ESC) tour menu"), SDLK_ESCAPE, 16);
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
displayButton(vid.xres-8, vid.yres-vid.fsize, XLAT("(v) menu"), 'v', 16);
|
displayButton(vid.xres-8, vid.yres-vid.fsize, XLAT("(v) menu"), 'v', 16);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#define NOGFX
|
#define NOGFX
|
||||||
#define NOPNG
|
#define NOPNG
|
||||||
#define DEMO
|
#define DEMO
|
||||||
|
#define TOUR
|
||||||
|
|
||||||
#ifdef FAKEWEB
|
#ifdef FAKEWEB
|
||||||
void mainloopiter();
|
void mainloopiter();
|
||||||
@ -17,6 +18,8 @@ void initweb();
|
|||||||
|
|
||||||
void loadCompressedChar(int &otwidth, int &otheight, int *tpix);
|
void loadCompressedChar(int &otwidth, int &otheight, int *tpix);
|
||||||
|
|
||||||
|
const char *wheresounds;
|
||||||
|
|
||||||
#include "hyper.cpp"
|
#include "hyper.cpp"
|
||||||
|
|
||||||
void playSound(cell *c, const string& fname, int vol) { }
|
void playSound(cell *c, const string& fname, int vol) { }
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
|
|
||||||
namespace mapeditor {
|
namespace mapeditor {
|
||||||
int subcanvas;
|
int subcanvas;
|
||||||
|
int displaycodes;
|
||||||
|
|
||||||
#ifndef NOEDIT
|
#ifndef NOEDIT
|
||||||
map<int, cell*> modelcell;
|
map<int, cell*> modelcell;
|
||||||
|
|
||||||
@ -425,7 +427,6 @@ namespace mapeditor {
|
|||||||
int subscreen; //0=normal, 1=config, 2=patterns, 3=predesigned
|
int subscreen; //0=normal, 1=config, 2=patterns, 3=predesigned
|
||||||
|
|
||||||
bool symRotation, sym01, sym02, sym03;
|
bool symRotation, sym01, sym02, sym03;
|
||||||
int displaycodes;
|
|
||||||
int whichpart;
|
int whichpart;
|
||||||
|
|
||||||
cell *drawcell;
|
cell *drawcell;
|
||||||
|
@ -1493,7 +1493,7 @@ void showDemo() {
|
|||||||
dialog::addBreak(50);
|
dialog::addBreak(50);
|
||||||
|
|
||||||
dialog::addItem(XLAT("play"), 'f');
|
dialog::addItem(XLAT("play"), 'f');
|
||||||
dialog::addItem(XLAT("tutorial"), 't');
|
dialog::addItem(XLAT("tutorial"), 'T');
|
||||||
dialog::addItem(XLAT("help"), 'h'); dialog::lastItem().keycaption += " / F1";
|
dialog::addItem(XLAT("help"), 'h'); dialog::lastItem().keycaption += " / F1";
|
||||||
dialog::addItem(XLAT("toggle high detail"), 'a');
|
dialog::addItem(XLAT("toggle high detail"), 'a');
|
||||||
dialog::addBreak(100);
|
dialog::addBreak(100);
|
||||||
@ -1522,9 +1522,9 @@ void handleDemoKey(int sym, int uni) {
|
|||||||
else restartGame();
|
else restartGame();
|
||||||
cmode = emNormal;
|
cmode = emNormal;
|
||||||
}
|
}
|
||||||
else if(sym == 't') {
|
else if(sym == 'T') {
|
||||||
firstland = laIce;
|
firstland = laIce;
|
||||||
if(!tour::on) restartGame('T');
|
if(!tour::on) tour::start();
|
||||||
cmode = emNormal;
|
cmode = emNormal;
|
||||||
}
|
}
|
||||||
else if(sym == 't') {
|
else if(sym == 't') {
|
||||||
|
9
tour.cpp
9
tour.cpp
@ -42,10 +42,15 @@ static struct { const char *name; int id; int legal; const char *help; } slides[
|
|||||||
},
|
},
|
||||||
{"Hypersian Rug model", 21, LEGAL_HYPERBOLIC,
|
{"Hypersian Rug model", 21, LEGAL_HYPERBOLIC,
|
||||||
"New players think that the action of HyperRogue takes place on a sphere. "
|
"New players think that the action of HyperRogue takes place on a sphere. "
|
||||||
|
#ifdef WEB
|
||||||
|
"This is not true -- try the Turorial in the native desktop version shows "
|
||||||
|
"the surface HyperRogue actually takes place on."
|
||||||
|
#else
|
||||||
"This is not true -- the next slide will show the surface HyperRogue "
|
"This is not true -- the next slide will show the surface HyperRogue "
|
||||||
"actually takes place on.\n\n"
|
"actually takes place on.\n\n"
|
||||||
"Use arrow keys to rotate the model, and Page Up/Down to zoom.\n\n"
|
"Use arrow keys to rotate the model, and Page Up/Down to zoom.\n\n"
|
||||||
"If you do not see anything, press '5' to try a safer renderer."
|
"If you do not see anything, press '5' to try a safer renderer."
|
||||||
|
#endif
|
||||||
},
|
},
|
||||||
{"Expansion", 22, LEGAL_ANY,
|
{"Expansion", 22, LEGAL_ANY,
|
||||||
"The next slide shows the number of cells in distance 1, 2, 3, ... from you. "
|
"The next slide shows the number of cells in distance 1, 2, 3, ... from you. "
|
||||||
@ -205,6 +210,7 @@ static struct { const char *name; int id; int legal; const char *help; } slides[
|
|||||||
"The following slide is a visualization of the Collatz conjecture. "
|
"The following slide is a visualization of the Collatz conjecture. "
|
||||||
"Press '5' for a spiral rendering of the Collatz conjecture visualization."},
|
"Press '5' for a spiral rendering of the Collatz conjecture visualization."},
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef WEB
|
||||||
{"Shoot'em up mode", 52, LEGAL_NONE,
|
{"Shoot'em up mode", 52, LEGAL_NONE,
|
||||||
"In the shoot'em up mode, space and time is continuous. "
|
"In the shoot'em up mode, space and time is continuous. "
|
||||||
"You attack by throwing knives. "
|
"You attack by throwing knives. "
|
||||||
@ -212,6 +218,7 @@ static struct { const char *name; int id; int legal; const char *help; } slides[
|
|||||||
"There are other special modes too which change the gameplay or "
|
"There are other special modes too which change the gameplay or "
|
||||||
"focus on a particular challenge."
|
"focus on a particular challenge."
|
||||||
},
|
},
|
||||||
|
#endif
|
||||||
{"THE END", 99, LEGAL_ANY,
|
{"THE END", 99, LEGAL_ANY,
|
||||||
"This tour shows just a small part of what you can see in the world of HyperRogue. "
|
"This tour shows just a small part of what you can see in the world of HyperRogue. "
|
||||||
"For example, "
|
"For example, "
|
||||||
@ -275,6 +282,7 @@ void presentation(int mode) {
|
|||||||
// Hypersian Rug
|
// Hypersian Rug
|
||||||
if(id == 21) {
|
if(id == 21) {
|
||||||
static int wm, mm;
|
static int wm, mm;
|
||||||
|
#ifndef WEB
|
||||||
if(mode == 1) {
|
if(mode == 1) {
|
||||||
rug::init();
|
rug::init();
|
||||||
wm = vid.wallmode;
|
wm = vid.wallmode;
|
||||||
@ -292,6 +300,7 @@ void presentation(int mode) {
|
|||||||
rug::rendernogl = !rug::rendernogl;
|
rug::rendernogl = !rug::rendernogl;
|
||||||
rug::init();
|
rug::init();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expansion
|
// Expansion
|
||||||
|
@ -789,7 +789,10 @@ int newmodecode = 254;
|
|||||||
|
|
||||||
int modecode() {
|
int modecode() {
|
||||||
#ifndef NOSAVE
|
#ifndef NOSAVE
|
||||||
if(anticheat::tampered || cheater || tour::on) return 6;
|
if(anticheat::tampered || cheater) return 6;
|
||||||
|
#ifdef TOUR
|
||||||
|
if(tour::on) return 6;
|
||||||
|
#endif
|
||||||
if(quotient) return 6;
|
if(quotient) return 6;
|
||||||
#endif
|
#endif
|
||||||
int xcode = 0;
|
int xcode = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user