reading void pointers

Member
Posts: 567
Joined: 2004.07
Post: #1
I'm working on an md2 loading app, which opens via NSDocument and NSData (hence why it is in this forum). However, I think my data retrieval functions are faulty, though I can't think why. an example of one is:
PHP Code:
int ReadInt(void **data)
{
    
int i = *(int *)(*data);
    *(
int*)(*data)++;
    
// *data += sizeof(int);
    
return i;

All the other datatypes, (e. byte, float, short, etc) are the same, except int is substituted for the specific data type.
  1. I load the md2 into the void, and extract the identity fine (IDP2). The next four bytes are supposed to be an integer, looking at both cone3d's and seth's code, is supposed to be the version number (8). however, it thinks that the version is 134217728, and the skinwidth (the next four bytes) is zero. WTH is going on here? Huh
  2. when I compare the identification string (IDP2) with
    PHP Code:
    strcmp(header.ident"IDP2"); 
    it returns false, though when I print the string, it prints IDP2 Blink


I call the functions here:
PHP Code:
- (BOOL)extractHeader
{    
    
int c;
    for (
04c++)
    {
        
header.ident[c] = ReadChar(&modelData);
    }
    
header.ident[4] = 0x00;       // terminate the string
    
header.version =            ReadInt(&modelData);
    
header.skinwidth =            ReadInt(&modelData);
    
header.skinheight =        ReadInt(&modelData);
    
header.framesize =        ReadInt(&modelData);
    
header.NumSkins =        ReadInt(&modelData);
    
header.NumVertices =        ReadInt(&modelData);
    
header.NumTexCoords =    ReadInt(&modelData);
    
header.NumTriangles =        ReadInt(&modelData);
    
header.NumGLCmds =        ReadInt(&modelData);
    
header.NumFrames =        ReadInt(&modelData);
    
header.offsetSkins =        ReadInt(&modelData);
    
header.offsetST =            ReadInt(&modelData);
    
header.offsetTriangles =    ReadInt(&modelData);
    
header.offsetFrames =        ReadInt(&modelData);
    
header.offsetGLCmds =        ReadInt(&modelData);
    
header.offsetEndOfFile =    ReadInt(&modelData);
    
printf("ident: %s\n"header.ident);
    
printf("version: %d\n"header.version);
    
printf("skinwidth: %d\n"header.skinwidth);
    return 
TRUE;


BTW, it compiles with no errors, and doesn't crash.

It's not magic, it's Ruby.
Quote this message in a reply
Moderator
Posts: 133
Joined: 2008.05
Post: #2
strcmp returns an integer, not a boolean value. So the first mismatch of characters it finds, it will return either: a negative number if the first string's mismatched character is "less than"(a < b < c < d < e < etc.), a zero if there are no mismatched chars (also known as FALSE) or a positive number if the mismatched character in the first string is "greater than" the one in the second string.

So, to check for equality, you'd do a if(!strcmp(s1, s2))
Quote this message in a reply
Member
Posts: 567
Joined: 2004.07
Post: #3
Yea, I know. But at the moment, that's a low-key problem.

It's not magic, it's Ruby.
Quote this message in a reply
Moderator
Posts: 771
Joined: 2003.04
Post: #4
Nayr Wrote:I load the md2 into the void, and extract the identity fine (IDP2). The next four bytes are supposed to be an integer, looking at both cone3d's and seth's code, is supposed to be the version number (8). however, it thinks that the version is 134217728, and the skinwidth (the next for bytes) is zero. WTH is going on here?


Endian issues: if you reverse the bytes you'll get 8.
Quote this message in a reply
Member
Posts: 567
Joined: 2004.07
Post: #5
Aha! Thankee, my ufo fellow!

It's not magic, it's Ruby.
Quote this message in a reply
Moderator
Posts: 133
Joined: 2008.05
Post: #6
Nayr Wrote:Yea, I know. But at the moment, that's a low-key problem.


If you knew, then why did you ask?
Quote this message in a reply
Member
Posts: 567
Joined: 2004.07
Post: #7
LongJumper Wrote:If you knew, then why did you ask?
I understood because I called the function as
PHP Code:
if(!strcmp(header.ident"IDP2")) return FALSE
It still returns false, i'm not sure what the problem is.

I got basic byte-swap working, And i'm trying to figure out how to byte-swap longs, doubles, and floats.

It's not magic, it's Ruby.
Quote this message in a reply
Member
Posts: 567
Joined: 2004.07
Post: #8
actually, I'm not so sure it does work. My run log:
Code:
Number Of Vertices: -2147483648
Number Of Frames: 1073741824
Size Of Frames: 32768

It's not magic, it's Ruby.
Quote this message in a reply
Puzzler183
Unregistered
 
Post: #9
printf the value, of the strcmp. It will tell you in what way the comparison fails.

Are you sure you are swapping byts properly? You'd be best to use the SDL_endian.h functions for that, because they are as fast as possible and you know they work.
Quote this message in a reply
Moderator
Posts: 771
Joined: 2003.04
Post: #10
Nayr Wrote:I understood because I called the function as
PHP Code:
if(!strcmp(header.ident"IDP2")) return FALSE
It still returns false, i'm not sure what the problem is.

Well, you are telling it to return FALSE...
Try if(!strcmp(header.ident, "IDP2")) return THEY_ARE_EQUAL;

That is, !strcmp(header.ident, "IDP2") means header.ident == "IDP2", not header.ident != "IDP2" - Read LongJumper's post again.

Quote:I got basic byte-swap working, And i'm trying to figure out how to byte-swap longs, doubles, and floats.

Try this:
PHP Code:
#define MACPPC2BYTES(p) p[0] = ((unsigned char *)p)[0]+(((short)((unsigned char *)p)[1])<<8)
#define MACPPC4BYTES(p) p[0] = ((unsigned char *)p)[0]+(((int)((unsigned char *)p)[1])<<8)+(((int)((unsigned char *)p)[2])<<16)+(((int)((unsigned char *)p)[3])<<24) 

BTW, floats are the same as ints for endian purposes (that is, use MACPPC4BYTES for both), and you don't need long or doubles for MD2s.

[Edit: The first define expects p to be a short pointer, the second expects it to be an int pointer.]
Quote this message in a reply
Member
Posts: 567
Joined: 2004.07
Post: #11
First off, I would rather not use SDL, as I am using cocoa. Hence why it is in this forum. Second, I was under the impression that strcmp returned fals if the strings weren't the same. i wouldn't have to ask these questions, but i lost my C manual, and It's harder than it sounds to find some stuff, like getting info from void pointers, on google. Thirdly, I want this code for more than just longs and doubles. But thanks for the help! Grin i will report back later to tell if it worked. I hope so.

It's not magic, it's Ruby.
Quote this message in a reply
w_reade
Unregistered
 
Post: #12
First: fair enough Smile.
Second: "man strcmp" in a terminal window.
Third: when you're byteswapping, all that matters is the size of the data type. AFAIK you're pretty much limited to* swapping 2, 4 or 8 byte data, so with one more macro you'd have everything you need.

*edit: OK, you might come across the odd lump of data in lumps of 3 bytes, or 6 bits, or whatever, so feel free to insert the word "normally" Wink.
Quote this message in a reply
Member
Posts: 567
Joined: 2004.07
Post: #13
w_reade Wrote:First: fair enough Smile.
Second: "man strcmp" in a terminal window.
Third: when you're byteswapping, all that matters is the size of the data type. AFAIK you're pretty much limited to swapping 2, 4 or 8 byte data, so with one more macro you'd have everything you need.
what about 6 bytes?

It's not magic, it's Ruby.
Quote this message in a reply
Puzzler183
Unregistered
 
Post: #14
Quote:First off, I would rather not use SDL, as I am using cocoa.

Well, it was more of a steal their macros and put them in your source since they are guaranteed to work, but whatev.

Quote:what about 6 bytes?
No legit data tyeps are 6 bytes, only 2, 4, 8 and maybe 10 if you use long doubles (80 bit IEEE).
Quote this message in a reply
w_reade
Unregistered
 
Post: #15
Nayr Wrote:what about 6 bytes?

OK, you can have any size you want, especially if you're dealing with funny custom data formats. But 99% of the bytes I've swapped have been in chunks of 2 or 4 Smile.

I totally failed to notice you'd replied when I edited, btw -- no faked-march-stealing apparently-duplicitous offence intended :-/.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Thread-Safe reference counted smart pointers in c++ JeroMiya 1 3,361 Nov 21, 2006 12:28 PM
Last Post: OneSadCookie
  Should global variables be pointers or full objects? ia3n_g 1 2,501 Aug 4, 2006 05:53 PM
Last Post: OneSadCookie
  Dangling Pointers/ Memory Leak definitions... WhatMeWorry 1 4,148 Oct 3, 2005 10:43 AM
Last Post: OneSadCookie
  NULL versus 0 pointers? WhatMeWorry 14 7,349 Apr 6, 2005 05:42 AM
Last Post: Andrew
  Pointers &amp; Archiving in Cocoa Shivers 6 3,903 Apr 4, 2005 02:36 AM
Last Post: DoG