Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[port to the Plan9 OS] one (?) remaining issue : alock.0 #1076

Open
staalmannen opened this issue Jul 9, 2023 · 3 comments
Open

[port to the Plan9 OS] one (?) remaining issue : alock.0 #1076

staalmannen opened this issue Jul 9, 2023 · 3 comments

Comments

@staalmannen
Copy link

Hi I have been trying to port NetHack to Plan9 (9front, amd64 arch but should work on all) using PDCursesMod, Lua and pcre (for regex) as external dependencies. It builds successfully now but It is still not playable and I think (hope) there is only one remaining issue.

https://github.com/staalmannen/NetHack

It now builds but stops at the start screen complaining about no alock.0 file being found. If this file is created by touch in HACKDIR, it will look for block.0 and so on. I have tried for with and without FCNTL enabled.

I suppose the issue is in src/files.c but I have not been able to find exactly where. Since alock.0 is not created, I guess somewhere before new_nhfile()?

@pat-rankin
Copy link

pat-rankin commented Jul 9, 2023

files.c refers to that type of file as a 'level file' and the .0 level file is used for synchronizing access so referred to as a lock file. The lock file setup is done with routines in files.c called by code in unixmain.c or equivalent. It sounds like getlock() is where your trouble occurs.

If nethack is being run with a limit on number of simultaneous players, the level files are named
<lowercase letter>lock.<digits>
If nethack is being run without such a limit, they're named
<character name><user id>.<digits>
with the first part being the same as save file names. The limit comes from MAXPLAYERS in the sysconf file; it used to be a command line argument passed by the shell script that runs nethack.

Entering a dungeon level during play creates a level file for it, named with a non-zero suffix. Saving collects the contents of all the individual level files (plus non-level data) into a single save file and deletes each one as it's processed. Restoring splits a save file back into the individual level files (and loads the non-level data into memory).

If the INSURANCE feature is disabled at build time or the checkpoint option is Off at run-time, the lock file just contains a process ID number. However when checkpoint is On, the lock file also contains 'game state' (hero's inventory, dungeon layout, plus other stuff that isn't part of any individual level file), and it gets updated each time you change level. NetHack's 'recover' utility can use it plus the level files to construct a save file for a crashed game (current up through the last level change).

[Edit: added backslashes to the file name patterns so that github won't eat the angle brackets.]

@staalmannen
Copy link
Author

staalmannen commented Jul 12, 2023

I confirmed that it looks for <character name><user id>.<digits> when MAXPLAYERS is commented out in sysconf.

I will try to figure out where the error happens

@nhmall
Copy link
Contributor

nhmall commented Sep 20, 2023

I noticed, when looking at some of your modifications, that you redeclared some fields that had been declared using the Bitfield macro:

--- a/include/config.h
+++ b/include/config.h
@@ -490,8 +490,9 @@ typedef unsigned char uchar;
  * allocate a separate character for each bitfield.  (The bitfields used never
  * have more than 7 bits, and most are only 1 bit.)
  */
+#ifndef Plan9
 #define BITFIELDS /* Good bitfield handling */
-
+#endif
 /* #define STRNCMPI */ /* compiler/library has the strncmpi function */
 
 };

for example:

--- a/include/objclass.h
+++ b/include/objclass.h
@@ -47,6 +47,17 @@ struct objclass {
     short oc_name_idx;              /* index of actual name */
     short oc_descr_idx;             /* description when name unknown */
     char *oc_uname;                 /* called by user */
+#ifdef Plan9
+    int oc_name_known;     /* discovered */
+    int oc_merge;          /* merge otherwise equal objects */
+    int oc_uses_known;     /* obj->known affects full description */
+    int oc_pre_discovered; /* already known at start of game; flagged*/
+    int oc_magic;          /* inherently magical object */
+    int oc_charged;        /* may have +n or (n) charges */
+    int oc_unique;         /* special one-of-a-kind object */
+    int oc_nowish;         /* cannot wish for this object */
+    int oc_big;
+#else
     Bitfield(oc_name_known, 1);     /* discovered */
     Bitfield(oc_merge, 1);          /* merge otherwise equal objects */
     Bitfield(oc_uses_known, 1);     /* obj->known affects full description;

The reason that NetHack uses a Bitfield macro to declare its bitfields is precisely to avoid the need to do that sort of thing.

If BITFIELDS is not defined when include/global.h is defining the Bitfield macro, the Bitfield macro is defined such that the expansion will result in each field being an unsiged char (uchar), instead of actual bitfields.

If, for some reason, you really did want them to be int under Plan9 (unsigned int would be a better choice than int, as the fields are assumed to be unsigned in the NetHack code.), rather than uchar, you could just change the macro definition for Bitfield when BITFIELDS isn't defined (around line 132 in include/global.h), and ensure that BITFIELDS is not defined during compilation, rather than add those #if / #else / #endif conditional blocks for the Bitfield fields.

#ifdef BITFIELDS
#define Bitfield(x, n) unsigned x : n
#else
#define Bitfield(x, n) uchar x
#endif

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants