• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Canvas

C++ BinaryReader?

18 posts in this topic

Hey guys, im trying to read in data from a binary file, but i cant seem to read it correctly,
the file is a MD3 format, Here is the code i use to read the first few bytes

[CODE]
ifstream md3file;
md3file.open(filename.c_str(), ios::in|ios::binary|ios::ate|ios_base::binary);
// C stuff
md3_header * md3Header = (struct md3_header *)
malloc(sizeof(struct md3_header));//Malloc seems to read the data correctly
//new vector<int>(sizeof(struct md3_header));
// it involves evil casting.
md3file.read((char *) &md3Header, sizeof(struct md3_header));

if((md3Header->ident != 860898377)||(md3Header->version !=15)
||((md3Header->fileID[0] != 'I')
||(md3Header->fileID[1] != 'D')
||(md3Header->fileID[2] != 'P')
||(md3Header->fileID[3] != '3')))
{
cout<<"Bad Version or identifier"<<endl;
cout << md3Header->fileID[0] << md3Header->fileID[1] <<
md3Header->fileID[2] << md3Header->fileID[3] << endl;
cout << md3Header->version << endl;
cout << md3Header->ident << endl;
}
[/CODE]

Now this is what is displayed in my console

Bad Version or identifier
?B??
-23510312
52
now i know this MD3 is correct as another MD3 loader loads it fine :),
Now i want to try and do something different, my code above takes in the struct from my header and places a template inside md3Header, it then puts all the data from the file provided through the parameter into that struct, but as you can see im getting the wrong data,

So here is the question, how can i actually manually tell that my md3Header.fileID[0] to be = to the frist byte in my MD3 file?

in C# i can see it would be so easy just a nice simple md3Header.fileID = getTest(enc.GetString(reader.ReadBytes(4)));
for your information fileID is fileID[4], each has a letter or a number inside it,

Now im not sure if getting the first byte is the way to go, but i want to actually manually put each bit of data into my header pointer
myself instead of trusting "read" function and sizeof

If anyone could help that would be awesome

Canvas
0

Share this post


Link to post
Share on other sites
but what if i wanted to read 4 bytes? or 32 bytes?,

so how would i set my md3Header.fileID[0] be?
md3Header.fileID[0] = new vector[char]....???
0

Share this post


Link to post
Share on other sites
Your specific problem is here: "(char *) &md3Header" - that should be "(char *) md3Header" instead as md3Header is already a pointer.
1

Share this post


Link to post
Share on other sites
without the & i still get this in the console


Bad Version or identifier
8H??
-23508936
52

which is wrong, also i feel that myabe ifstream is wrong? it doesnt seem to be reading my binary md3 file correctly or is that just my code? my header is correct for the format,
i just want to be able to set md3Header.fileID[0] to the first byte or maybe first 4 bytes, once i know how to do that i maybe able to fix the problem
0

Share this post


Link to post
Share on other sites
Is your md3_header struct [url=http://msdn.microsoft.com/en-us/library/2e70t5y1%28v=vs.100%29.aspx]packed[/url] as tightly as possible?
0

Share this post


Link to post
Share on other sites
tell you the truth, i dont understand whta you mean by packed? here is my md3header

[CODE]
#include <GL/glew.h>
#include <GL/gl.h>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <vector>
#include "GameAsset.h"
using namespace std;
#ifndef MD3ASSET_H_
#define MD3ASSET_H_
class Md3Asset : public GameAsset {
public:
Md3Asset(const string &filename);
virtual ~Md3Asset();
virtual void update();
private:
void import_md3_asset(const string &filename);
//May need this
typedef float vec3[3];
struct md3_header
{
char fileID[4]; //Stores the file IDs
int ident; //Stores the identity
int version; //Stores the version, Must be 15
char name[64]; //Stores the name of the file
int flags; //Stores the flags
int num_frames; //Stores number of frames
int num_tags; //Stores number of tags
int num_surfaces; //Stores number of surfaces
int num_skins; //Stores number of skins
int ofs_frames; //Stores offset number of frames
int ofs_tags; //Stores offset number of tags
int ofs_surfaces; //Stores offset number of surfaces
int ofs_eof; //Stores offset end and finish???
};
struct md3_frame
{
float min_bounds[3]; //Min (x,y,z) value for the frame
float max_bounds[3]; //Max (x,y,a) value for the frame
float local_origin[3]; //Stores the frame position
float radius; //Scale/Radius of the frame
char name[16]; //Modeler used to create the loaded model
};
struct md3_tag
{
char name[64]; //Stores the name of the tag
Vector3 origin; //Stores the translation that should be performed
Vector3 axis[3][3]; //Stores the 3x3 rotation matrix for this frame
};
struct md3_surface
{
int ident; //Stores the identity
char name[64]; //Stores the surface name
int flags; //Stores the flags
int num_frames; //Stores the number of frames
int num_shaders; //Stores the number of shaders
int num_verts; //Stores the number of vertices
int num_triangles; //Stores the number of triangles
int ofs_triangles; //Stores the offset triangles
int ofs_shaders; //Stores the offset shaders
int ofs_ST; //Stores the offset starts
int ofs_xyzNormal; //Stores the offset starting positions
int ofs_end; //Stores the offset surface ends
};
struct md3_shader
{
char name[64]; //Stores the file name
int shader_index; //Stores the shader index number
};
struct md3_triangle
{
int indexes[3]; //Stores a list of offset values for Vertex
};
struct md3_texCoord
{
float st[3]; //Stores s & t texture coordinates
};
struct md3_vertex
{
short coord[3]; //x,y,z coordinates in right-handed 3-space
short normal; //Stores angles
};
md3_frame *md3Frame;
md3_tag *md3Tag;
md3_surface *md3Surface;
md3_shader *md3Shader;
md3_triangle *md3Triangle;
md3_texCoord *md3TexCords;
md3_vertex *md3Vertex;
};
#endif
[/CODE]

does packed me, i actually define how long a int, short, char is?
0

Share this post


Link to post
Share on other sites
Assuming your struct is packed, try this:

[code]ifstream md3file;
md3file.open(filename.c_str(), ios::in | ios::binary | ios::ate);
md3_header md3Header;
md3file.read(reinterpret_cast<char *>(&md3Header), sizeof(md3_header));
[/code]
0

Share this post


Link to post
Share on other sites
Ok ApochPiQ, i tried your code with one little change

I removed the & and made my md3Header a pointer
[CODE]
ifstream md3file;
md3file.open(filename.c_str(), ios::in | ios::binary | ios::ate);
md3_header * md3Header;
md3file.read(reinterpret_cast<char *>(md3Header), sizeof(md3_header));
[/CODE]
Now my program opens and then just closes, doesnt display anything in console, a window will appear for a tiny second and then boom its gone
Just did some testing if i remove my check to see if the ident or version is correct it comes up with a window, here is the code for my version checker
[CODE]
if((md3Header->ident != 860898377)||(md3Header->version !=15)
||((md3Header->fileID[0] != 'I')
||(md3Header->fileID[1] != 'D')
||(md3Header->fileID[2] != 'P')
||(md3Header->fileID[3] != '3')))
{
cout<<"Bad Version or identifier"<<endl;
cout << md3Header->fileID[0] << md3Header->fileID[1] <<
md3Header->fileID[2] << md3Header->fileID[3] << endl;
cout << md3Header->version << endl;
cout << md3Header->ident << endl;
}
[/CODE]
0

Share this post


Link to post
Share on other sites
I think you might have some misconceptions about how pointers work.

The code you posted will read into random chunks of memory and obliterate whatever's there. If you're lucky it will crash like you describe; if you're unlucky very literally almost anything could happen to your program's behavior.

I posted code that should work. I really don't understand what you were hoping to accomplish by making that change.
0

Share this post


Link to post
Share on other sites
Ok ive just used your code, the result is different but still not correct, also it froze my laptop :D, here is the output i get with your code implemented


Bad Version or identifier

157955018
0

which still isnt correct :(
0

Share this post


Link to post
Share on other sites
k the first line in the lara_head.MD3 in hex is this
49 44 50 33 0F 00 00 00 00 00 00 00 00 00 00 00 00 = IDP3 which is correct
but in my program it comes up with nothing :D,

still just doesnt seem to read the file correctly, or my header isnt correct, but it matchs many other peoples headers out there,
0

Share this post


Link to post
Share on other sites
Before spending an endless amount of time debugging the read call:

Did you check your stream after opening it? If it fails to find/open the file in the first place, everything after that can't work.

Did you use gcount after read to see how much data you REALLY read into your struct?

Did you at any point consider to initialize your struct to all 0 to tell the difference between "reading wrong data" and "reading no data and having random uninitialized garbage in your struct"?
0

Share this post


Link to post
Share on other sites
You should really learn some basic C++ before you continue. The mistakes you're making are all quite trivial ones, and demonstrate a notable lack of understanding of pointers and basic C++ good practices.

Below is a snippet of working code that should get you started. Do try and read up on the bits and pieces you don't understand, instead of just copying and pasting and hoping it works.

[code]

#include <iostream>
#include <fstream>
#include <vector>
#include <cstdint>
#include <iterator>

struct MD3Vec3 {
float x, y, z;
};

struct MD3Header {
int32_t ident;
int32_t version;
char name[64];
int32_t flags;
int32_t num_frames;
int32_t num_tags;
int32_t num_surfaces;
int32_t num_skins;
int32_t ofs_frames;
int32_t ofs_tags;
int32_t ofs_surfaces;
int32_t ofs_eof;
};

struct MD3Frame
{
MD3Vec3 min_bounds;
MD3Vec3 max_bounds;
MD3Vec3 local_origin;
float radius;
char name[16];
};

struct MD3Tag {
char name[64];
MD3Vec3 origin;
MD3Vec3 axis[3];
};

int main() {
std::ifstream fin("../test.md3", std::ios::binary | std::ios::in);
auto data = std::vector<char>(std::istreambuf_iterator<char>(fin), std::istreambuf_iterator<char>());

MD3Header* header = reinterpret_cast<MD3Header*>(&data.front());

std::cout<<std::hex<<header->ident<<std::endl;

for(int32_t i = 0; i < header->num_frames; ++i) {
MD3Frame* frame = reinterpret_cast<MD3Frame*>(&data.front() + header->ofs_frames) + i;
std::cout<<frame->name<<std::endl;
}
}
[/code]
2

Share this post


Link to post
Share on other sites
Cheers Washu, I have a lesson soon so i wont be able to check your code until 1english time [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img], Sorry about the lack of knowledge, it does come in time tho [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img]

Also here is my header and cpp file before i edit it with washu's code

Md3Asset.cpp
[CODE]
#include "Md3Asset.h"
Md3Asset::Md3Asset(const string &filename) {
import_md3_asset(filename);
// make the objects to display
if(0 == make_resources()) {
cout << "Can't make the required OpenGL resources for Md2Asset." << endl;
// TODO: exit nicely here
}
}
Md3Asset::~Md3Asset() {
// TODO: clean up
}
void Md3Asset::update() {
}
void Md3Asset::import_md3_asset(const string &filename) {
/*ifstream md3file(filename, ios::in|ios::binary);
//md3file.open(filename.c_str(), ios::in|ios::binary|ios::ate|ios_base::binary);
// C stuff
md3_header * md3Header = (struct md3_header *)
malloc(sizeof(struct md3_header));//Malloc seems to read the data correctly
//new vector<int>(sizeof(struct md3_header));
// it involves evil casting.*/
//ifstream is input stream, ofstream is output stream
//fstream is input&output
fstream md3file;
//ios::in = open for input mode
//ios::binary = opens the file in binary mode
md3file.open(filename.c_str(), ios::in | ios::binary | ios::ate);
md3_header md3Header;
md3file.read(reinterpret_cast<char *>(&md3Header), sizeof(md3_header));
if((md3Header.ident != 860898377)||(md3Header.version !=15)
||((md3Header.fileID[0] != 'I')
||(md3Header.fileID[1] != 'D')
||(md3Header.fileID[2] != 'P')
||(md3Header.fileID[3] != '3')))
{
cout<<"Bad Version or identifier"<<endl;
cout << md3Header.fileID[0] << md3Header.fileID[1] <<
md3Header.fileID[2] << md3Header.fileID[3] << endl;
cout << md3Header.version << endl;
cout << md3Header.ident << endl;
}
md3file.close();
}
[/CODE]

Md3Asset.h
[CODE]
#include <GL/glew.h>
#include <GL/gl.h>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <vector>
#include "GameAsset.h"
using namespace std;
#ifndef MD3ASSET_H_
#define MD3ASSET_H_
class Md3Asset : public GameAsset {
public:
Md3Asset(const string &filename);
virtual ~Md3Asset();
virtual void update();
private:
void import_md3_asset(const string &filename);
//May need this
typedef float vec3[3];
struct md3_header
{
char fileID[4]; //Stores the file IDs
int ident; //Stores the identity
int version; //Stores the version, Must be 15
char name[64]; //Stores the name of the file
int flags; //Stores the flags
int num_frames; //Stores number of frames
int num_tags; //Stores number of tags
int num_surfaces; //Stores number of surfaces
int num_skins; //Stores number of skins
int ofs_frames; //Stores offset number of frames
int ofs_tags; //Stores offset number of tags
int ofs_surfaces; //Stores offset number of surfaces
int ofs_eof; //Stores offset end and finish???
};
struct md3_frame
{
float min_bounds[3]; //Min (x,y,z) value for the frame
float max_bounds[3]; //Max (x,y,a) value for the frame
float local_origin[3]; //Stores the frame position
float radius; //Scale/Radius of the frame
char name[16]; //Modeler used to create the loaded model
};
struct md3_tag
{
char name[64]; //Stores the name of the tag
Vector3 origin; //Stores the translation that should be performed
Vector3 axis[3][3]; //Stores the 3x3 rotation matrix for this frame
};
struct md3_surface
{
int ident; //Stores the identity
char name[64]; //Stores the surface name
int flags; //Stores the flags
int num_frames; //Stores the number of frames
int num_shaders; //Stores the number of shaders
int num_verts; //Stores the number of vertices
int num_triangles; //Stores the number of triangles
int ofs_triangles; //Stores the offset triangles
int ofs_shaders; //Stores the offset shaders
int ofs_ST; //Stores the offset starts
int ofs_xyzNormal; //Stores the offset starting positions
int ofs_end; //Stores the offset surface ends
};
struct md3_shader
{
char name[64]; //Stores the file name
int shader_index; //Stores the shader index number
};
struct md3_triangle
{
int indexes[3]; //Stores a list of offset values for Vertex
};
struct md3_texCoord
{
float st[3]; //Stores s & t texture coordinates
};
struct md3_vertex
{
short coord[3]; //x,y,z coordinates in right-handed 3-space
short normal; //Stores angles
};
md3_frame *md3Frame;
md3_tag *md3Tag;
md3_surface *md3Surface;
md3_shader *md3Shader;
md3_triangle *md3Triangle;
md3_texCoord *md3TexCords;
md3_vertex *md3Vertex;
};
#endif
[/CODE]

Thats my code at the moment which will change soonish
0

Share this post


Link to post
Share on other sites
Ok Washu i have added your code and im getting a error

Here is my Md3Asset.cpp file
[CODE]
#include "Md3Asset.h"
Md3Asset::Md3Asset(const string &filename) {
import_md3_asset(filename);
// make the objects to display
if(0 == make_resources()) {
cout << "Can't make the required OpenGL resources for Md3Asset." << endl;
// TODO: exit nicely here
}
}
Md3Asset::Md3Asset(){}
Md3Asset::~Md3Asset() {
// TODO: clean up
}
void Md3Asset::update() {
}
void Md3Asset::import_md3_asset(const string &filename) {
std::ifstream fin("../lara_head.MD3", std::ios::binary | std::ios::in);
auto data = std::vector<char>(std::istreambuf_iterator<char>(fin), std::istreambuf_iterator<char>());
md3_header* header = reinterpret_cast<MD3Header*>(&data.front()); //LINE WONT COMPILE
std::cout<<std::hex<<header->ident<<std::endl;
for(int32_t i = 0; i < header->num_frames; ++i) {
md3_frame* frame = reinterpret_cast<md3_frame*>(&data.front() + header->ofs_frames) + i;
std::cout<<frame->name<<std::endl;
}

};
[/CODE]

and this is my header
Md3Asset.h
[CODE]
#include <iostream>
#include <fstream>
#include <vector>
#include <cstdint>
#include <iterator>
#include "GameAsset.h"
using namespace std;
#ifndef MD3ASSET_H_
#define MD3ASSET_H_
class Md3Asset : public GameAsset {
public :
Md3Asset();
Md3Asset(const string &filename);
virtual ~Md3Asset();
virtual void update();
private:
void import_md3_asset(const string &filename);
struct Vec3 {
float x, y, z;
};
struct md3_header {
int32_t ident;
int32_t version;
char name[64];
int32_t flags;
int32_t num_frames;
int32_t num_tags;
int32_t num_surfaces;
int32_t num_skins;
int32_t ofs_frames;
int32_t ofs_tags;
int32_t ofs_surfaces;
int32_t ofs_eof;
};
struct md3_frame
{
Vec3 min_bounds;
Vec3 max_bounds;
Vec3 local_origin;
float radius;
char name[16];
};
struct md3_tag {
char name[64];
Vec3 origin;
Vec3 axis[3][3];
};
struct md3_surface
{
int32_t ident; //Stores the identity
char name[64]; //Stores the surface name
int32_t flags; //Stores the flags
int32_t num_frames; //Stores the number of frames
int32_t num_shaders; //Stores the number of shaders
int32_t num_verts; //Stores the number of vertices
int32_t num_triangles; //Stores the number of triangles
int32_t ofs_triangles; //Stores the offset triangles
int32_t ofs_shaders; //Stores the offset shaders
int32_t ofs_ST; //Stores the offset starts
int32_t ofs_xyzNormal; //Stores the offset starting positions
int32_t ofs_end; //Stores the offset surface ends
};
struct md3_shader
{
char name[64]; //Stores the file name
int32_t shader_index; //Stores the shader index number
};
struct md3_triangle
{
int32_t indexes[3]; //Stores a list of offset values for Vertex
};
struct md3_texCoord
{
float st[3]; //Stores s & t texture coordinates
};
struct md3_vertex
{
short coord[3]; //x,y,z coordinates in right-handed 3-space
short normal; //Stores angles
};
};
#endif
[/CODE]

Its ok i have changed the line and the code is compiling BUT, when i click build, it builds it then displays a box for a split second and then just dissappears... I now put the load line as this
[CODE]
std::ifstream fin("data/lara/lara_head.MD3", std::ios::binary | std::ios::in);
[/CODE]
and i now get this but still closes
33504449
(from 3DSMax)
0

Share this post


Link to post
Share on other sites
Just a quick check before we go further, the endianness of the file does match that of your machine, right?
1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0