code help please

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • will_asher
    DaJAngband Maintainer
    • Apr 2007
    • 1124

    code help please

    It took me a good bit of trial and error to figure out how to assign a random name to an individual ego item so that it looks like a randart. After a while, I finally got it to work, but now I can't save it in the savefile.
    I have the random name saved as:
    char o_ptr->randego_name
    How can I save that in the savefile with the rest of the o_ptr stuff?
    There's wr_byte and wr_s16b, etc. but no wr_char, and I don't know how to make one.

    EDIT: If someone could do me a huge favor and write a wr_char function (and probably a rd_char function for load.c) for me, I'd be very grateful. All of the wr_xxxx functions are at the top of save.c.
    Last edited by will_asher; March 3, 2010, 09:20.
    Will_Asher
    aka LibraryAdventurer

    My old variant DaJAngband:
    http://sites.google.com/site/dajangbandwebsite/home (defunct and so old it's forked from Angband 3.1.0 -I think- but it's probably playable...)
  • takkaria
    Veteran
    • Apr 2007
    • 1951

    #2
    Originally posted by will_asher
    It took me a good bit of trial and error to figure out how to assign a random name to an individual ego item so that it looks like a randart. After a while, I finally got it to work, but now I can't save it in the savefile.
    I have the random name saved as:
    char o_ptr->randego_name
    How can I save that in the savefile with the rest of the o_ptr stuff?
    There's wr_byte and wr_s16b, etc. but no wr_char, and I don't know how to make one.

    EDIT: If someone could do me a huge favor and write a wr_char function (and probably a rd_char function for load.c) for me, I'd be very grateful. All of the wr_xxxx functions are at the top of save.c.
    How about wr_string()?
    takkaria whispers something about options. -more-

    Comment

    • will_asher
      DaJAngband Maintainer
      • Apr 2007
      • 1124

      #3
      Originally posted by takkaria
      How about wr_string()?
      Whatever will allow me to save those random names in the savefile would be awesome.

      EDIT: Oh. I just noticed there's already an wr_string() which I hadn't noticed. Would I need to declare o_ptr->randego_name as a cptr instead of a char? I don't know the difference between cptr and char. (The computer with my current DaJAngband stuff is not available at the moment or I'd go ahead and try it).
      Will_Asher
      aka LibraryAdventurer

      My old variant DaJAngband:
      http://sites.google.com/site/dajangbandwebsite/home (defunct and so old it's forked from Angband 3.1.0 -I think- but it's probably playable...)

      Comment

      • konijn_
        Hellband maintainer
        • Jul 2007
        • 367

        #4
        Originally posted by will_asher
        Whatever will allow me to save those random names in the savefile would be awesome.

        EDIT: Oh. I just noticed there's already an wr_string() which I hadn't noticed. Would I need to declare o_ptr->randego_name as a cptr instead of a char? I don't know the difference between cptr and char. (The computer with my current DaJAngband stuff is not available at the moment or I'd go ahead and try it).
        Assuming your code works, randego_name is probably char*, it should work.

        T.
        * Are you ready for something else ? Hellband 0.8.8 is out! *

        Comment

        • will_asher
          DaJAngband Maintainer
          • Apr 2007
          • 1124

          #5
          How do I find this bug?

          Okay, now I have a completely different coding-related problem:

          I had a game of DaJAngband on an older computer where I found a crash bug. So I brought the savefile over to the computer with my compiler/debugger on it to look for the bug, and it didn't crash. I tried making sure the old computer had the newest compile and the exact same files. So the two computers were using the exact same .exe file, the exact same files in the lib folder, and the exact same savefile, but it crashed on the older computer and didn't crash on the computer that has my compiler/debugger on it.
          I haven't ever knowingly changed anything platform-specific in the code. Both computers are using Windows (although the older one has XP and the newer one has Vista). I don't understand why it would crash on one computer and not the other. How would I go about finding this bug?
          Will_Asher
          aka LibraryAdventurer

          My old variant DaJAngband:
          http://sites.google.com/site/dajangbandwebsite/home (defunct and so old it's forked from Angband 3.1.0 -I think- but it's probably playable...)

          Comment

          • Pete Mack
            Prophet
            • Apr 2007
            • 6883

            #6
            If you have a working debugger, you can just track down where it crashes and see what caused the crash. If you don't (can't get gdb to work, etc), you may need to install Visual Studio Express and debug with that. It takes a while to get set up, but learning to debug with VS is a lot easer than with gdb.

            Oh yeah, and if you do get it to work, please make the project file available for Angband. Things would be easier on windows if VS were officially supported.

            Comment

            • will_asher
              DaJAngband Maintainer
              • Apr 2007
              • 1124

              #7
              Originally posted by Pete Mack
              If you have a working debugger, you can just track down where it crashes and see what caused the crash. If you don't (can't get gdb to work, etc), you may need to install Visual Studio Express and debug with that. It takes a while to get set up, but learning to debug with VS is a lot easer than with gdb.
              My problem here is that it doesn't crash on the computer that has the debugger, so how do I track down where it crashes? It would be a lot of trouble to get the debugger onto the old computer because it isn't connected to the internet.

              Originally posted by Pete Mack
              Oh yeah, and if you do get it to work, please make the project file available for Angband. Things would be easier on windows if VS were officially supported.
              I had been using VS on (yet) another computer, but that computer kindof died, and I had problems installing VS on the computer I'm using now so I went back to using Dev C++. Its debugger isn't as good, but it does have one.
              Will_Asher
              aka LibraryAdventurer

              My old variant DaJAngband:
              http://sites.google.com/site/dajangbandwebsite/home (defunct and so old it's forked from Angband 3.1.0 -I think- but it's probably playable...)

              Comment

              • PowerDiver
                Prophet
                • Mar 2008
                • 2820

                #8
                Originally posted by will_asher
                I don't understand why it would crash on one computer and not the other. How would I go about finding this bug?
                The recent OS-related crash differences that I have read about here have been due to accessing bad pointers. If you read from a bad pointer, should that cause a crash or simply return an arbitrary result? Different OSes treat this differently. Whether that difference is true of Vista vs XP is beyond my knowledge.

                You might try to track down recent fixes to V that fix these kinds of bugs. Perhaps someone with a better memory can list some of them for you. Unfortunately that won't help if you introduced the bug yourself.

                Comment

                • Pete Mack
                  Prophet
                  • Apr 2007
                  • 6883

                  #9
                  I no longer have an XP box, so I can't help there.
                  MS does distribute an ISO you can burn, if you really get desperate, but it may not crash in a version recompiled in VS.

                  Otherwise, you can try valgrind if you have access to a linux account. It's very good at tracking down bad pointer use.

                  Comment

                  • konijn_
                    Hellband maintainer
                    • Jul 2007
                    • 367

                    #10
                    Originally posted by will_asher
                    Okay, now I have a completely different coding-related problem:

                    I had a game of DaJAngband on an older computer where I found a crash bug. So I brought the savefile over to the computer with my compiler/debugger on it to look for the bug, and it didn't crash. <snip more stuff>
                    Greetings,

                    I would compile the game once more in Visual Studio and build a Debug version and try the debug version on your old machine. When it crashes, the Debug version should tell you at least in which file / line the crash happens.

                    T.
                    * Are you ready for something else ? Hellband 0.8.8 is out! *

                    Comment

                    • konijn_
                      Hellband maintainer
                      • Jul 2007
                      • 367

                      #11
                      Originally posted by Pete Mack
                      If you have a working debugger, you can just track down where it crashes and see what caused the crash. If you don't (can't get gdb to work, etc), you may need to install Visual Studio Express and debug with that. It takes a while to get set up, but learning to debug with VS is a lot easer than with gdb.

                      Oh yeah, and if you do get it to work, please make the project file available for Angband. Things would be easier on windows if VS were officially supported.
                      Dean and I have tried, VS does not like the source in folders structure of Angband.. The unintended consequence of that is that we are locking out newbie developers that need the best debugger on a free compiler for the most dominant platform that is out there..

                      T.
                      * Are you ready for something else ? Hellband 0.8.8 is out! *

                      Comment

                      • zaimoni
                        Knight
                        • Apr 2007
                        • 590

                        #12
                        Originally posted by PowerDiver
                        The recent OS-related crash differences that I have read about here have been due to accessing bad pointers. If you read from a bad pointer, should that cause a crash or simply return an arbitrary result? Different OSes treat this differently. Whether that difference is true of Vista vs XP is beyond my knowledge.
                        On Windows, reading from a bad pointer pointing into a non-existent memory page always errors. Vista+ have Data Execution Prevention available; if this is turned on it converts some things that are silent in XP- into errors. (I have Data Execution Prevention set globally, contrary to default, on my Vista and higher systems; I'd rather have browsers crash out than soak a drive-by malware infection.)

                        A read from a bad pointer into an existing memory page is likely to not crash, but as with all undefined behavior you take your chances....
                        Zaiband: end the "I shouldn't have survived that" experience. V3.0.6 fork on Hg.
                        Zaiband 3.0.10 ETA Mar. 7 2011 (Yes, schedule slipped. Latest testing indicates not enough assert() calls to allow release.)
                        Z.C++: pre-alpha C/C++ compiler system (usable preprocessor). Also on Hg. Z.C++ 0.0.10 ETA December 31 2011

                        Comment

                        • will_asher
                          DaJAngband Maintainer
                          • Apr 2007
                          • 1124

                          #13
                          I'm still trying to track down the cause of this crash bug. I've narrowed it down and I'm almost positive that it happens in the itemlist function having to do with object mimmics showing up on the object list (unless there's more than one crash bug..). And it doesn't just happen on the older computer like I thought at first, but it doesn't happen reliably.

                          I've been working on trying to fix this bug for what seems like a long time now, so I thought I'd post the function here so maybe someone else can tell me what I did wrong. I copied the function from vanilla 3.1.1. The only changes I've made to it were:
                          1) to get it to work in my code based on vanilla 3.0.9
                          2) make objects sort by value (in the compare_items() function which I didn't copy here because I'm pretty sure it's not the problem)
                          3) to make object mimmics show up on the object list.

                          The only way I could figure how to put mimmics on the object list was to create a fake object for the mimmic and it seems to be forgetting that fake object between when it's created and when it actually lists the objects. It shows (nothing) on the object list instead of the mimmicked object, but it has the (nothing) in the middle of the list so I think it got sorted by value okay, but then lost the object.
                          m_ptr->disguised holds the k_idx of the object that the monster is disguised as.
                          I know the disguise_object_desc() function works, because it's also used when you (l)ook at the disguised mimmic, and there's no problems there.

                          Code:
                          /*
                           * Display visible items, similar to display_monlist (the object list)
                           * copied from V3.1.1
                           */
                          void display_itemlist(void)
                          {
                          	int max, mx, my;
                          	unsigned num;
                          	int line = 1, x = 0;
                          	int cur_x;
                          	unsigned i;
                          	unsigned disp_count = 0;
                          	byte a;
                          	char c;
                          
                          	object_type *types[MAX_ITEMLIST+2];
                          	int counts[MAX_ITEMLIST+2];
                          	unsigned counter = 0;
                          
                          	int dungeon_hgt = p_ptr->depth == 0 ? TOWN_HGT : DUNGEON_HGT;
                          	int dungeon_wid = p_ptr->depth == 0 ? TOWN_WID : DUNGEON_WID;
                          
                          	byte attr;
                          	char buf[80];
                          
                          	int floor_list[MAX_FLOOR_STACK];
                          
                          	/* Clear the term if in a subwindow, set x otherwise */
                          	if (Term != angband_term[0])
                          	{
                          		clear_from(0);
                          		max = Term->hgt - 1;
                          	}
                          	else
                          	{
                          		x = 13;
                          		max = Term->hgt - 2;
                          	}
                          
                          	/* Look at each square of the dungeon for items */
                          	for (my = 0; my < dungeon_hgt; my++)
                          	{
                          		for (mx = 0; mx < dungeon_wid; mx++)
                          		{
                          			(void)scan_floor(floor_list, &num, my, mx, 3);
                          			/* num = scan_floor(floor_list, MAX_FLOOR_STACK, my, mx, 3); */
                          
                          			/* check for object mimmics */
                                      if (cave_m_idx[my][mx] > 0)
                          			{
                          				monster_type *m_ptr = &mon_list[cave_m_idx[my][mx]];
                          				monster_race *r_ptr = &r_info[m_ptr->r_idx];
                          				/* disguised == 1 means it's mimmicking a terrain, not an object */
                          				if ((r_ptr->flags1 & (RF1_CHAR_MULTI)) && (m_ptr->disguised > 1) &&
                          					((m_ptr->meet == 100) || (player_can_see_bold(my, mx))))
                          				{
                          					object_type *i_ptr;
                          					object_type object_type_body;
                          					unsigned j;
                          
                          					/* Get local object */
                          					i_ptr = &object_type_body;
                          
                          					/* Create the item */
                          					object_prep(i_ptr, m_ptr->disguised);
                          					
                          					/* mark item as a disguised monster */
                          					i_ptr->thisbrand = 77;
                          
                          					/* Skip gold/squelched */
                          					if (i_ptr->tval == TV_GOLD)	continue;
                          					/* we'll need this if you uncomment the squelch bit */
                          					/* if (i_ptr->tval == TV_CHEST) i_ptr->pval = randint(5); */
                          
                          					/* skip squelched only if hide_squelchable is on */
                          					/* (if you can see an object, but it's not on the object */
                          					/* list then it's obvious that something's up.  If you see */
                                              /* an object that you have squelched, you may forget that */
                                              /* it's squelched.) */
                          					/* if ((squelch_item_ok(i_ptr)) && (hide_squelchable)) continue; */
                          
                          					/* See if we've already seen a similar item; if so, just add */
                          					/* to its count */
                          					for (j = 0; j < counter; j++)
                          					{
                          						if (object_similar(i_ptr, types[j]))
                          						{
                          							counts[j] += i_ptr->number;
                          							break;
                          						}
                          					}
                          
                          					/* We saw a new item. So insert it at the end of the list and */
                          					/* then sort it forward using compare_items(). The types list */
                          					/* is always kept sorted. */
                          					if (j == counter)
                          					{
                          						types[counter] = i_ptr;
                          						counts[counter] = i_ptr->number;
                          
                          						while (j > 0 && compare_items(types[j - 1], types[j]) > 0)
                          						{
                          							object_type *tmp_o = types[j - 1];
                          							int tmpcount;
                          
                          							types[j - 1] = types[j];
                          							types[j] = tmp_o;
                          							tmpcount = counts[j - 1];
                          							counts[j - 1] = counts[j];
                          							counts[j] = tmpcount;
                          							j--;
                          						}
                          						counter++;
                          					}
                          				}
                          			}
                          
                          			/* Iterate over all the items found on this square */
                          			for (i = 0; i < num; i++)
                          			{
                          				object_type *o_ptr = &o_list[floor_list[i]];
                          				unsigned j;
                          
                          				/* Skip gold/squelched */
                          				if (o_ptr->tval == TV_GOLD)	continue;
                          					
                          				/* skep squelched only if hide_squelchable is on */
                                          if ((squelch_item_ok(o_ptr)) && (hide_squelchable)) continue;
                          
                          				/* See if we've already seen a similar item; if so, just add */
                          				/* to its count */
                          				for (j = 0; j < counter; j++)
                          				{
                          					if (object_similar(o_ptr, types[j]))
                          					{
                          						counts[j] += o_ptr->number;
                          						break;
                          					}
                          				}
                          
                          				/* We saw a new item. So insert it at the end of the list and */
                          				/* then sort it forward using compare_items(). The types list */
                          				/* is always kept sorted. */
                          				if (j == counter)
                          				{
                          					types[counter] = o_ptr;
                          					counts[counter] = o_ptr->number;
                          
                          					while (j > 0 && compare_items(types[j - 1], types[j]) > 0)
                          					{
                          						object_type *tmp_o = types[j - 1];
                          						int tmpcount;
                          
                          						types[j - 1] = types[j];
                          						types[j] = tmp_o;
                          						tmpcount = counts[j - 1];
                          						counts[j - 1] = counts[j];
                          						counts[j] = tmpcount;
                          						j--;
                          					}
                          					counter++;
                          				}
                          			}
                          		}
                          	}
                          
                          	/* Note no visible items */
                          	if (!counter)
                          	{
                          		/* Clear display and print note */
                          		c_prt(TERM_SLATE, "You see no items.", 0, 0);
                          		if (Term == angband_term[0])
                          			Term_addstr(-1, TERM_WHITE, "  (Press any key to continue.)");
                          
                          		/* Done */
                          		return;
                          	}
                          	else
                          	{
                          		/* Reprint Message */
                          		prt(format("You can see %d item%s: (unaware objects in red)",
                          				   counter, (counter > 1 ? "s" : "")), 0, 0);
                          	}
                          
                          	for (i = 0; i < counter; i++)
                          	{
                          		/* o_name will hold the object_desc() name for the object. */
                          		/* o_desc will also need to put a (x4) behind it. */
                          		/* can there be more than 999 stackable items on a level? */
                          		char o_name[80];
                          		char o_desc[86];
                          
                          		object_type *o_ptr = types[i];
                          
                          		/* We shouldn't list coins or squelched items */
                          		if (o_ptr->tval == TV_GOLD)	continue;
                          					
                          		/* skep squelched only if hide_squelchable is on */
                          		/* if ((squelch_item_ok(o_ptr)) && (hide_squelchable)) continue; */
                          		
                          		if (o_ptr->thisbrand == 77) disguise_object_desc(o_name, sizeof(o_name), o_ptr->k_idx);
                          		else object_desc(o_name, sizeof(o_name), o_ptr, FALSE, 3);
                          
                          		if (counts[i] > 1)
                          			sprintf(o_desc, "%s (x%d)", o_name, counts[i]);
                          		else
                          			sprintf(o_desc, "%s", o_name);
                          
                          		/* Reset position */
                          		cur_x = x;
                          
                          		/* See if we need to scroll or not */
                          		if (Term == angband_term[0] && (line == max) && disp_count != counter)
                          		{
                          			prt("-- more --", line, x);
                          			anykey();
                          
                          			/* Clear the screen */
                          			for (line = 1; line <= max; line++)
                          				prt("", line, x);
                          
                          			/* Reprint Message */
                          			prt(format("You can see %d item%s:",
                          					   counter, (counter > 1 ? "s" : "")), 0, 0);
                          
                          			/* Reset */
                          			line = 1;
                          		}
                          		else if (line == max)
                          		{
                          			continue;
                          		}
                          
                          		/* Note the number of items actually displayed */
                          		disp_count++;
                          
                          		if (artifact_p(o_ptr) && (object_known_p(o_ptr)))
                          			/* known artifact */
                          			attr = TERM_VIOLET;
                          		else if (!object_aware_p(o_ptr))
                          			/* unaware of kind */
                          			attr = TERM_RED;
                          		else if (object_is_worthless(o_ptr))
                          			/* worthless */
                          			attr = TERM_SLATE;
                          		else
                          			/* default */
                          			attr = TERM_WHITE;
                          
                          		a = object_attr(o_ptr);
                          		c = object_char(o_ptr);
                          
                          		/* Display the pict */
                          		Term_putch(cur_x++, line, a, c);
                          		if (use_bigtile) Term_putch(cur_x++, line, 255, -1);
                          		Term_putch(cur_x++, line, TERM_WHITE, ' ');
                          
                          		/* Print and bump line counter */
                          		c_prt(attr, o_desc, line, cur_x);
                          		line++;
                          	}
                          
                          	if (disp_count != counter)
                          	{
                          		/* Print "and others" message if we've run out of space */
                          		strnfmt(buf, sizeof buf, "  ...and %d others.", counter - disp_count);
                          		c_prt(TERM_WHITE, buf, line, x);
                          	}
                          	else
                          	{
                          		/* Otherwise clear a line at the end, for main-term display */
                          		prt("", line, x);
                          	}
                          
                          	if (Term == angband_term[0])
                          		Term_addstr(-1, TERM_WHITE, "  (Press any key to continue.)");
                          }
                          PS: I don't see the point of a mimmic if you can't actually mistake the mimmic for the object it is mimmicking.
                          Last edited by will_asher; March 14, 2010, 07:08.
                          Will_Asher
                          aka LibraryAdventurer

                          My old variant DaJAngband:
                          http://sites.google.com/site/dajangbandwebsite/home (defunct and so old it's forked from Angband 3.1.0 -I think- but it's probably playable...)

                          Comment

                          • Derakon
                            Prophet
                            • Dec 2009
                            • 9022

                            #14
                            I'll admit I didn't read all the code, but I think I see your problem. Your code looks broadly like this:
                            Code:
                            list_of_objects = []
                            for each tile in dungeon {
                              append objects in tile to list_of_objects
                              if monster is in tile and monster is a mimic {
                                fake_object = makeObjectFromMonster(monster)
                                append fake_object to list_of_objects
                              }
                            }
                            The problem is that fake_object goes out of scope when the if statement closes, rendering it invalid. Future created objects then can use the memory that was used by fake_object, writing random stuff to it which will cause a crash when you later try to read it.

                            Comment

                            • Nick
                              Vanilla maintainer
                              • Apr 2007
                              • 9637

                              #15
                              I don't know if you've looked there, but NPP does that precise thing with making mimics look really like objects. AFAIK it doesn't have an item list, though.
                              One for the Dark Lord on his dark throne
                              In the Land of Mordor where the Shadows lie.

                              Comment

                              Working...
                              😀
                              😂
                              🥰
                              😘
                              🤢
                              😎
                              😞
                              😡
                              👍
                              👎