Read and Write, not getting same values.

This is a discussion on Read and Write, not getting same values. within the C++ Programming forums, part of the General Programming Boards category; I'm trying to write back to a block in memory (that I write to a file later with no problems) ...

  1. #1
    Registered User
    Join Date
    Sep 2006
    Posts
    6

    Read and Write, not getting same values.

    I'm trying to write back to a block in memory (that I write to a file later with no problems) but for some reason after the 3rd loop it is not writing properly. It keeps adding on 101 in different offsets when it's not supposed to...I think...I don't know, at least it's not one of this programs intended functions. void parse_stats() does it's job and write_stats() should be formatting it the way parse stats reads...sorry bout the lack of comments. It's a diablo II v1.11 savegame editor I am working on as a hobby in linux or even windows if need be.

    Code:
    void parse_stats(unsigned int offset)
    {
    	unsigned long int temp_read, current_stat, current_value;
    	unsigned long int *read[16] = {&d2s_stats.strength, &d2s_stats.energy, 
    		&d2s_stats.dexterity, &d2s_stats.vitality,
    		&d2s_stats.stat_points, &d2s_stats.skill_points, 
    		&d2s_stats.current_hp,	&d2s_stats.total_hp,
    		&d2s_stats.current_mp, &d2s_stats.total_mp, 
    		&d2s_stats.current_sp, &d2s_stats.total_sp,
    		&d2s_stats.level, &d2s_stats.experience, 
    		&d2s_stats.gold_in_belt, &d2s_stats.gold_in_stash};
    	unsigned int counter = 0;
    					
    	for (;;)
    	{
    		file.seekg((counter / 8) + offset, ios::beg);
    		file.read((char*)&temp_read, 4);
    		current_stat = temp_read >> (counter % 8) & 0x1FF;
    		counter += current_stat_length[current_stat];
    		if(current_stat == 0x1FF)
    		{
    			file.seekg(-4, ios::cur);
    			break;
    		}
    		file.seekg((counter / 8) + offset, ios::beg);
    		file.read((char*)&temp_read, 4);
    		current_value = temp_read >> (counter % 8) & stat_filter[current_stat];
    		*read[current_stat] = current_value;
    		counter += stat_length[current_stat];
    //		cout << stat_name[current_stat] << current_value << endl;
    	}
    }
    
    void write_stats(char* stat[55])
    {
    
    	unsigned long int temp_write, current_stat, current_value;
    	unsigned long int *write[16] = {&d2s_stats.strength, &d2s_stats.energy, 
    		&d2s_stats.dexterity, &d2s_stats.vitality,
    		&d2s_stats.stat_points, &d2s_stats.skill_points, 
    		&d2s_stats.current_hp,	&d2s_stats.total_hp,
    		&d2s_stats.current_mp, &d2s_stats.total_mp, 
    		&d2s_stats.current_sp, &d2s_stats.total_sp,
    		&d2s_stats.level, &d2s_stats.experience, 
    		&d2s_stats.gold_in_belt, &d2s_stats.gold_in_stash};
    	unsigned int counter = 0;
    					
    	for (int i = 0;i < 16;i++)
    	{
    		stat[counter / 8] += (i << (counter % 8)) & 
    				(current_stat_length_filter[i] << (counter % 8)) ;
    		counter += current_stat_length[i];
    		stat[counter / 8] += (*write[i] << (counter % 8)) & 
    				(stat_filter[i] << (counter % 8));
    		current_value = *write[i];
    		counter += stat_length[i];
    		cin.get();
    		cout << stat_name[i] << current_value << endl;
    	}
    }
    Last edited by Salem; 09-13-2006 at 12:51 AM. Reason: code line length wrapping

  2. #2
    Registered User
    Join Date
    Sep 2006
    Posts
    6
    if you need more info just let me know but someone please help. I've been working on this part for at least a whole day and I haven't got a clue what is wrong with my math.

  3. #3
    Registered User
    Join Date
    Sep 2006
    Posts
    6

    Unhappy

    Can someone please help? help a guy out it maybe simpler than you think but I need a guru...I've only been programming for 2 years, I'ven't made a mistake like this so I don't know what to do.

  4. #4
    Cat
    Cat is offline
    Registered User
    Join Date
    May 2003
    Posts
    1,571
    Are all the stats you are trying to read/write in sequential order in the file, and of a known size?

    I can't really make heads nor tails of what the code is doing, but if you just need to read/write from a binary file you can generally accomplish that in far simpler ways.

    Perhaps you should try explaining exactly what the code is supposed to do?
    You ever try a pink golf ball, Wally? Why, the wind shear on a pink ball alone can take the head clean off a 90 pound midget at 300 yards.

  5. #5
    Registered User
    Join Date
    Nov 2005
    Posts
    673
    Looks to me like a Diablo 2 character hack...

  6. #6
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,750
    Go through it a line at a time very slowly with a debugger.
    When action != expectation, you've found a bug.
    Whether that bug is in your code, or in your head is to be decided when you find out.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  7. #7
    Registered User
    Join Date
    Sep 2006
    Posts
    6
    >Looks to me like a Diablo 2 character hack

    You are correct sir. This is a Diablo II Savegame editor. But I already said this in my original post. Now here is the problem in much greater detail. Blizzard it seems is not kind enough to keep all values on 8 bit boundaries. The reading function runs a running total of how many bits have been extracted so far and based on a little math, reads the value shifted by however man bits are left over. This is why the % 8 is there. Each value has a certain length. The first few stats are 9 bits for a descriptor of what the value it is describing and 10 bits for the value it's self. This total of 19 % 8 = 3 is where the next value will be, two bytes and 3 bits from the original location of where everything starts.

    Code:
    hex values from the files
    (69 66) 00 28 08 F0 80 80 0C 06 50 <--- is what the original file looks like
    (69 66) 00 28 08 F0 A8 80 0C 06 58 <--- is what it writes back
     ^ header (if)
    Hopefully this illustraits my problem. Where as after writing 32 bits it goes to hell in a hand basket. I've considered using a long unsigned int but the issue is there is a 32 bit value so it is too small and I'd rather just make it overflow like it does now because it sort of does the job. Except for the little lost bits.

  8. #8
    Registered User
    Join Date
    Sep 2006
    Posts
    6
    Now this works but I need to find out why I'm missing bits.

    Code:
    void write_stats(char stat[55])
    {
    	long unsigned int temp_write;
    	unsigned long int current_stat, current_value;
    	unsigned long int *write[16] = {&d2s_stats.strength, &d2s_stats.energy, &d2s_stats.dexterity, &d2s_stats.vitality,
    		&d2s_stats.stat_points, &d2s_stats.skill_points, &d2s_stats.current_hp,	&d2s_stats.total_hp,
    		&d2s_stats.current_mp, &d2s_stats.total_mp, &d2s_stats.current_sp, &d2s_stats.total_sp,
    		&d2s_stats.level, &d2s_stats.experience, &d2s_stats.gold_in_belt, &d2s_stats.gold_in_stash};
    	unsigned int counter = 0;
    					
    	for (int i = 0;i < 16;i++)
    	{
    		temp_write = 0;
    		temp_write = (i << (counter % 8));
    		stat[counter / 8] = temp_write;
    		counter += current_stat_length[i];
    		temp_write = 0;
    		temp_write = (*write[i] << (counter % 8));
    		stat[counter / 8] = temp_write;
    		current_value = *write[i];
    		counter += stat_length[i];
    		cout << stat_name[i] << current_value << endl;
    	}
    	cout << sizeof(long unsigned int) << endl;
    }
    Last edited by Wraith-Lunati; 09-13-2006 at 09:02 AM.

  9. #9
    Registered User
    Join Date
    Nov 2005
    Posts
    673
    Well, I am sorry I was unable to read the entire post, and was more so looking at what might be wrong in your code.. Anyways it was midnight at last post, and I still had homework

  10. #10
    Registered User
    Join Date
    Sep 2006
    Posts
    6
    No body even mentioned:

    A char will fit into an unsigned long int but not the other way around.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problems with fstream, one variabile for write and read
    By Smjert in forum C++ Programming
    Replies: 3
    Last Post: 02-03-2009, 10:19 PM
  2. read write lock in C#
    By George2 in forum C# Programming
    Replies: 0
    Last Post: 04-16-2008, 09:49 AM
  3. how do i read 2 consecutive values in vector and compute?
    By dalearyous in forum C++ Programming
    Replies: 8
    Last Post: 03-30-2006, 04:22 PM
  4. Replies: 3
    Last Post: 03-04-2005, 02:46 PM
  5. Serial Communications in C
    By ExDigit in forum Windows Programming
    Replies: 7
    Last Post: 01-09-2002, 10:52 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21