So I've got off the ground.

If you have any questions on programming, this is the place to ask them, whether you're a newbie or an experienced programmer. Discussion on programming in general is also welcome. We will help you with programming homework, but we will not do your work for you! Any porting requests must be made in Developmental Ideas.
N64VSNES
DCEmu Freak
DCEmu Freak
Posts: 65
https://www.artistsworkshop.eu/meble-kuchenne-na-wymiar-warszawa-gdzie-zamowic/
Joined: Sun Apr 10, 2011 12:05 pm
Has thanked: 0
Been thanked: 0

Re: So I've got off the ground.

Post by N64VSNES »

This is going great so far.

Although I've hit another brick wall, I tried to load a bigger image such as 512x512 which I often use in my games for tilesheets but I get this error:

Image

I don't understand what's different as they're both PNG's and the only difference I'm aware of is the size. 32x32 V 512x512
User avatar
Quzar
Dream Coder
Dream Coder
Posts: 7497
Joined: Wed Jul 31, 2002 12:14 am
Location: Miami, FL
Has thanked: 4 times
Been thanked: 9 times
Contact:

Re: So I've got off the ground.

Post by Quzar »

What it looks like is happening is that png_to_texture is unable to open the file, but there isn't any short-circuiting, so what happens is you end up passing a kos_img_t with garbage in it.

If you could post the relevant section of your code, it might be more apparent what the problem is.
"When you post fewer lines of text than your signature, consider not posting at all." - A Wise Man
N64VSNES
DCEmu Freak
DCEmu Freak
Posts: 65
Joined: Sun Apr 10, 2011 12:05 pm
Has thanked: 0
Been thanked: 0

Re: So I've got off the ground.

Post by N64VSNES »

Sure but I doubt it's not finding the file though because it runs fine on PC (this is multiplatform)

Here is how I load the image:

Code: Select all

void Sprite::Load(const char *filename) {
	std::string f = "/cd/";
	f += filename;
	png_to_img(f.c_str(), PNG_FULL_ALPHA, &kos_img);
	p_Texture = pvr_mem_malloc(kos_img.w * kos_img.h * 2);
	pvr_txr_load_kimg( &kos_img, p_Texture, 0);
	Pos.w = Crop.w =  kos_img.w;
	Pos.h = Crop.h = kos_img.h;
	fWidth = kos_img.w;
	fHeight = kos_img.h;
	Crop.x = Crop.y = Pos.x = Pos.y = 0;
}
Here is the class itself:

Code: Select all

class Sprite {

	public:

		Sprite();
		~Sprite();

		void Load(const char* filename);
		void Render();

		Rectangle Pos;
		Rectangle Crop;

	private:
		pvr_ptr_t p_Texture;
		kos_img_t kos_img;
		unsigned int fWidth;
		unsigned int fHeight;
	};
I should really be erasing kos_img but I'll get to that later lol.
User avatar
BlueCrab
The Crabby Overlord
The Crabby Overlord
Posts: 5658
Joined: Mon May 27, 2002 11:31 am
Location: Sailing the Skies of Arcadia
Has thanked: 9 times
Been thanked: 69 times
Contact:

Re: So I've got off the ground.

Post by BlueCrab »

The first error message in the output you provided is clearly stating that it can't read the file. Its looking for the file /cd/Data/ChronoTest/2/TileSet.png, and its not finding it.

The crash is because you're not checking for an error condition from png_to_img, and passing junk to pvr_txr_load_kimg.
N64VSNES
DCEmu Freak
DCEmu Freak
Posts: 65
Joined: Sun Apr 10, 2011 12:05 pm
Has thanked: 0
Been thanked: 0

Re: So I've got off the ground.

Post by N64VSNES »

Yeah I've figured this much out. But I don't understand why it can't read the file :? I've checked that the file is and path is correct several times and it's just a simple PNG like the previous one I had tested with. The only difference is the size.

If it's not the path then perhaps it's something to do with the image format? I've saved them in the same way so that seems unlikely too.

So it's kind of a brick wall as I don't know what to try :(

Thanks.
N64VSNES
DCEmu Freak
DCEmu Freak
Posts: 65
Joined: Sun Apr 10, 2011 12:05 pm
Has thanked: 0
Been thanked: 0

Re: So I've got off the ground.

Post by N64VSNES »

This actually could be a problem with GCC....Does newlines get read in as part of a string with std::getline() for fstream or something similar? Because hardcoding the path makes it run fine :o

I have to admit I'm a Visual Studio fan.... :(
User avatar
PH3NOM
DC Developer
DC Developer
Posts: 576
Joined: Fri Jun 18, 2010 9:29 pm
Has thanked: 0
Been thanked: 5 times

Re: So I've got off the ground.

Post by PH3NOM »

Maybe the disc structure is the problem?

When you build a "selfboot" cd for dreamcast, in most procedures you will place all of the necessary files, including the boot binary, eg; 1st_read.bin, into a folder named /Data/ and then create the image, or burn it to disc.

So, your compiled binary will be located as /Data/1st_read.bin on your PC.
But when this disc is run on DC 1st_read.bin will be at the root of the cd file-system; /cd/1st_read.bin NOT /cd/Data/1st_read.bin
User avatar
BlueCrab
The Crabby Overlord
The Crabby Overlord
Posts: 5658
Joined: Mon May 27, 2002 11:31 am
Location: Sailing the Skies of Arcadia
Has thanked: 9 times
Been thanked: 69 times
Contact:

Re: So I've got off the ground.

Post by BlueCrab »

N64VSNES wrote:This actually could be a problem with GCC....Does newlines get read in as part of a string with std::getline() for fstream or something similar? Because hardcoding the path makes it run fine :o

I have to admit I'm a Visual Studio fan.... :(
Quite possibly. I know if you're using the C function fgets, the '\n' would still be in it. I've not worked much with C++ lately, so I'm not positive what the standard says about it.

That would explain the extra newline in the output. :wink:
User avatar
Quzar
Dream Coder
Dream Coder
Posts: 7497
Joined: Wed Jul 31, 2002 12:14 am
Location: Miami, FL
Has thanked: 4 times
Been thanked: 9 times
Contact:

Re: So I've got off the ground.

Post by Quzar »

BlueCrab wrote:
N64VSNES wrote:This actually could be a problem with GCC....Does newlines get read in as part of a string with std::getline() for fstream or something similar? Because hardcoding the path makes it run fine :o

I have to admit I'm a Visual Studio fan.... :(
Quite possibly. I know if you're using the C function fgets, the '\n' would still be in it. I've not worked much with C++ lately, so I'm not positive what the standard says about it.

That would explain the extra newline in the output. :wink:
Checking the sources, it seems like it would be exactly this. That explains all the problems. My suggestion would be to use native c strings instead of the convoluted C++ => C way. The only tricky part would be dealing with having to guess a size for the string, but all you need is to define a 'max filename size' wherever the filenames are listed.
"When you post fewer lines of text than your signature, consider not posting at all." - A Wise Man
N64VSNES
DCEmu Freak
DCEmu Freak
Posts: 65
Joined: Sun Apr 10, 2011 12:05 pm
Has thanked: 0
Been thanked: 0

Re: So I've got off the ground.

Post by N64VSNES »

Thanks again guys, I admit I'm not a huge GCC fan because I learned to program on Visual Studio so it feels unnatural.

Turns out it was a newline so I had to swap some things to char pointers and others I could just do:

Code: Select all

str.erase(str.begin()+str.length()-1);
Hopefully I'll be nearing the end of my nooby learning curve soon lol :wink:
N64VSNES
DCEmu Freak
DCEmu Freak
Posts: 65
Joined: Sun Apr 10, 2011 12:05 pm
Has thanked: 0
Been thanked: 0

Re: So I've got off the ground.

Post by N64VSNES »

It's all starting to come along pretty well now so long story short I have a map:

Image

The black is the transparency because I the map itself has 3 layers. Ground, Top, and above. I couldn't render each tile with the Z position at 1 so I had to increase the depth by 1 for each layer. But the transparency is completely screwed now.

I've looked through the examples and searched around the forum but I couldn't find anything to "disable" so I can just draw something and then draw something again which would make it be on top of the previously drawn sprite.

Is this even possible?
And also I should mention that the screenshot was taken from a emulator but I've tested it on my dreamcast too and the is not difference.

Thanks.
User avatar
PH3NOM
DC Developer
DC Developer
Posts: 576
Joined: Fri Jun 18, 2010 9:29 pm
Has thanked: 0
Been thanked: 5 times

Re: So I've got off the ground.

Post by PH3NOM »

BlueCrab wrote:
N64VSNES wrote:This actually could be a problem with GCC....Does newlines get read in as part of a string with std::getline() for fstream or something similar? Because hardcoding the path makes it run fine :o

I have to admit I'm a Visual Studio fan.... :(
Quite possibly. I know if you're using the C function fgets, the '\n' would still be in it. I've not worked much with C++ lately, so I'm not positive what the standard says about it.

That would explain the extra newline in the output. :wink:
Incidentally, that solves the problem of why my M3U playlist code was not working...

Thanks BlueCrab!
N64VSNES
DCEmu Freak
DCEmu Freak
Posts: 65
Joined: Sun Apr 10, 2011 12:05 pm
Has thanked: 0
Been thanked: 0

Re: So I've got off the ground.

Post by N64VSNES »

PH3NOM wrote:
BlueCrab wrote:
N64VSNES wrote:This actually could be a problem with GCC....Does newlines get read in as part of a string with std::getline() for fstream or something similar? Because hardcoding the path makes it run fine :o

I have to admit I'm a Visual Studio fan.... :(
Quite possibly. I know if you're using the C function fgets, the '\n' would still be in it. I've not worked much with C++ lately, so I'm not positive what the standard says about it.

That would explain the extra newline in the output. :wink:
Incidentally, that solves the problem of why my M3U playlist code was not working...

Thanks BlueCrab!
Haha, isn't GCC a bitch? :roll:
Ex-Cyber
DCEmu User with No Life
DCEmu User with No Life
Posts: 3641
Joined: Sat Feb 16, 2002 1:55 pm
Has thanked: 0
Been thanked: 0

Re: So I've got off the ground.

Post by Ex-Cyber »

Is it possible that you're feeding CR+LF line endings (e.g. from a Windows-based text editor) into a library that expects LF line endings, and thus getting a trailing CR included in your string?
"You know, I have a great, wonderful, really original method of teaching antitrust law, and it kept 80 percent of the students awake. They learned things. It was fabulous." -- Justice Stephen Breyer
N64VSNES
DCEmu Freak
DCEmu Freak
Posts: 65
Joined: Sun Apr 10, 2011 12:05 pm
Has thanked: 0
Been thanked: 0

Re: So I've got off the ground.

Post by N64VSNES »

Ex-Cyber wrote:Is it possible that you're feeding CR+LF line endings (e.g. from a Windows-based text editor) into a library that expects LF line endings, and thus getting a trailing CR included in your string?
....I guess you're talking about the the GCC problem? Because it was *something* to do with the end of the string but the newline character is hidden and the was a extra one in the debug output so I think this was the issue. Anyway that's resolved now.

As for the transparency problem....I think there might be a bug in the KOS because I've really tried everything and I have no idea what's wrong with it :|
User avatar
BlueCrab
The Crabby Overlord
The Crabby Overlord
Posts: 5658
Joined: Mon May 27, 2002 11:31 am
Location: Sailing the Skies of Arcadia
Has thanked: 9 times
Been thanked: 69 times
Contact:

Re: So I've got off the ground.

Post by BlueCrab »

N64VSNES wrote:
Ex-Cyber wrote:Is it possible that you're feeding CR+LF line endings (e.g. from a Windows-based text editor) into a library that expects LF line endings, and thus getting a trailing CR included in your string?
....I guess you're talking about the the GCC problem? Because it was *something* to do with the end of the string but the newline character is hidden and the was a extra one in the debug output so I think this was the issue. Anyway that's resolved now.
No, what they're saying (probably correctly) is that your input file has Windows-style (CR+LF - two characters) line endings. KOS, like pretty much all other modern OSes (Linux, UNIX, Mac OS X, *BSD, etc) expects a single LF character as the line ending. They are postulating that the extra CR character (so the LF was stripped out properly) is what was causing the problem, as KOS is not expecting it to be there and treats it as just another character in the filename. I'd venture to guess that since you're using Windows, Ex-Cyber has hit the nail on the head here. Its certainly not a GCC problem, its a problem of mistaken assumptions.
As for the transparency problem....I think there might be a bug in the KOS because I've really tried everything and I have no idea what's wrong with it :|
Give me a small, full, runnable example's source code that shows the bug and I'll take a look at it. I know that transparencies work fine in KOS, as I've used them plenty of times.
N64VSNES
DCEmu Freak
DCEmu Freak
Posts: 65
Joined: Sun Apr 10, 2011 12:05 pm
Has thanked: 0
Been thanked: 0

Re: So I've got off the ground.

Post by N64VSNES »

Code: Select all

class VideoSystem {

	public:

		VideoSystem();
		~VideoSystem();

		void Initialize();
		bool Loop();
		void Flip();

                void DrawPolygon(Eternal::Rectangle *,float r, float g, float b);

	private:
		pvr_poly_hdr_t	hdr;
	};

Eternal::VideoSystem::VideoSystem() {

}

Eternal::VideoSystem::~VideoSystem() {

}

void Eternal::VideoSystem::Initialize() {
	// Set up the parameters
	pvr_init_params_t init_params = {
	{ PVR_BINSIZE_16, PVR_BINSIZE_0, PVR_BINSIZE_0, PVR_BINSIZE_0, PVR_BINSIZE_0 }
		, 512 * 1024
	};
	vid_set_mode(DM_640x480,PM_RGB565);
	pvr_init(&init_params);
	pvr_init_defaults();

	pvr_poly_cxt_t cxt;

	pvr_poly_cxt_col(&cxt, PVR_LIST_OP_POLY);
	pvr_poly_compile(&hdr, &cxt);

}

bool Eternal::VideoSystem::Loop() {
	pvr_wait_ready();
	pvr_scene_begin();
	
	pvr_list_begin(PVR_LIST_TR_POLY);
	pvr_prim(&hdr,sizeof(hdr));

	return true;
}

void Eternal::VideoSystem::Flip() {
	pvr_list_finish();
	pvr_scene_finish();
}

void Eternal::VideoSystem::DrawPolygon(Rectangle *p, float r, float g, float b) {
	pvr_vertex_t vert;

	vert.flags = PVR_CMD_VERTEX;
	vert.x = p->x;
	vert.y = p->y + p->w;
	vert.z = 1.0f;
	vert.u = vert.v = 0.0f;
	vert.argb = PVR_PACK_COLOR(1, r / 255, g / 255, b / 255);
	vert.oargb = 0;
	pvr_prim(&vert, sizeof(vert));

	vert.y = p->y;
	pvr_prim(&vert, sizeof(vert));

	vert.x = p->x + p->w;
	vert.y = p->y + p->h;
	pvr_prim(&vert, sizeof(vert));

	vert.flags = PVR_CMD_VERTEX_EOL;
	vert.y = p->y;
	pvr_prim(&vert, sizeof(vert));
}

class Sprite {

	public:

		Sprite();
		~Sprite();

		void Load(const char* filename);
		void Render();

		Rectangle Pos;
		Rectangle Crop;

	private:
		pvr_ptr_t p_Texture;
		kos_img_t kos_img;
		unsigned int fWidth;
		unsigned int fHeight;
	};


Eternal::Sprite::Sprite() {

}

Eternal::Sprite::~Sprite() {

}

void Eternal::Sprite::Load(const char *filename) {
	std::string f = "/cd/";
	f += filename;
	p_Texture = pvr_mem_malloc(kos_img.w * kos_img.h * 2);
	png_to_img(f.c_str(), PNG_FULL_ALPHA, &kos_img);
	pvr_txr_load_kimg( &kos_img, p_Texture, PNG_FULL_ALPHA);
	Pos.w = Crop.w =  kos_img.w;
	Pos.h = Crop.h = kos_img.h;
	fWidth = kos_img.w;
	fHeight = kos_img.h;
	Crop.x = Crop.y = Pos.x = Pos.y = 0;
}

void Eternal::Sprite::Render() {
	pvr_vertex_t vert;

	pvr_poly_cxt_t cxt;
    pvr_poly_hdr_t hdr;

	Rectangle *p = &Pos;

    pvr_poly_cxt_txr(&cxt, PVR_LIST_TR_POLY, PVR_TXRFMT_ARGB4444, kos_img.w, kos_img.h, p_Texture, PVR_FILTER_NONE);
    pvr_poly_compile(&hdr, &cxt);
    pvr_prim(&hdr, sizeof(hdr));

	vert.flags = PVR_CMD_VERTEX;
	vert.z = p->z;
	vert.x = p->x;
	vert.y = p->y;

	vert.u = Crop.x / fWidth;
	vert.v = Crop.y / fHeight;
	vert.argb = PVR_PACK_COLOR(1, 1, 1, 1);
	vert.oargb = 0;
	pvr_prim(&vert, sizeof(vert));

	vert.x = p->x + p->w;
	vert.y = p->y;
	vert.u = (Crop.x + Crop.w) / fWidth;
	vert.v = Crop.y / fHeight;
	pvr_prim(&vert, sizeof(vert));

	vert.y = p->y + p->h;
	vert.x = p->x;
	vert.u = Crop.x / fWidth;
	vert.v = (Crop.y + Crop.h) / fHeight;
	pvr_prim(&vert, sizeof(vert));

	vert.flags = PVR_CMD_VERTEX_EOL;
	vert.x = p->x + p->w;
	vert.y = p->y + p->h;
	vert.u = (Crop.x + Crop.w) / fWidth;
	vert.v = (Crop.y + Crop.h) / fHeight;
	pvr_prim(&vert, sizeof(vert));
}

int main(int argc,char *args[]) {
       VideoSystem *VideoSystem = new VideoSystem();
       Sprite spr;
       spr.Load("My_texture_with_transparency.png");
	while(VideoSystem->Loop()) {
                // So we can see the transparent parts are black
                // Draw a blue polygon in the backround
                VideoSystem->DrawPolygon(0,0,640,480,0,0,255);
		spr.Render();
		VideoSystem->Flip();
	}
       return 0;
}
I tried to keep it small but also whilst getting everything relevant to KOS and PVR it seemed quite hard.

I do have some debugging stuff in as well but I've removed that to try and keep it short and to the point.

EDIT:
Okay I really screwed up with keeping it small :|
User avatar
BlueCrab
The Crabby Overlord
The Crabby Overlord
Posts: 5658
Joined: Mon May 27, 2002 11:31 am
Location: Sailing the Skies of Arcadia
Has thanked: 9 times
Been thanked: 69 times
Contact:

Re: So I've got off the ground.

Post by BlueCrab »

Two things I can see without having run the code (as I'm at work, and don't have Dreamcast handy), both in the section below:
N64VSNES wrote:

Code: Select all

void Eternal::VideoSystem::Initialize() {
	// Set up the parameters
	pvr_init_params_t init_params = {
	{ PVR_BINSIZE_16, PVR_BINSIZE_0, PVR_BINSIZE_0, PVR_BINSIZE_0, PVR_BINSIZE_0 }
		, 512 * 1024
	};
	vid_set_mode(DM_640x480,PM_RGB565);
	pvr_init(&init_params);
	pvr_init_defaults();

	pvr_poly_cxt_t cxt;

	pvr_poly_cxt_col(&cxt, PVR_LIST_OP_POLY);
	pvr_poly_compile(&hdr, &cxt);

}

bool Eternal::VideoSystem::Loop() {
	pvr_wait_ready();
	pvr_scene_begin();
	
	pvr_list_begin(PVR_LIST_TR_POLY);
	pvr_prim(&hdr,sizeof(hdr));

	return true;
}
First, in your pvr_params, you've set aside no binning space for the Translucent list. Modify the pvr_params so that it looks like this:

Code: Select all

	pvr_init_params_t init_params = {
	{ PVR_BINSIZE_16, PVR_BINSIZE_0, PVR_BINSIZE_16, PVR_BINSIZE_0, PVR_BINSIZE_0 }
		, 512 * 1024
	};
Granted, you're calling pvr_init_defaults() after that, which should init the PVR with the same parameters I specified there, IIRC. You don't need to call pvr_init() then pvr_init_defaults(). Just do one or the other, and if you're going to use pvr_init(), make sure you specify enough binning space for whatever you're going to be sending in.

Second, your polygon context/header for the blue polygon is listed as in the Opaque list in the header, but it appears you're submitting it in the Translucent list. That will, quite likely, cause the hardware to essentially ignore the blue polygon entirely.
N64VSNES
DCEmu Freak
DCEmu Freak
Posts: 65
Joined: Sun Apr 10, 2011 12:05 pm
Has thanked: 0
Been thanked: 0

Re: So I've got off the ground.

Post by N64VSNES »

Tried all that and cleared up my nooby mistakes.....No difference in the emulator and my dreamcast isn't even booting into it now :o

I'll see if I can get that one figured out but the transparent problem remains a mystery :x
BlackAura
DC Developer
DC Developer
Posts: 9951
Joined: Sun Dec 30, 2001 9:02 am
Has thanked: 0
Been thanked: 1 time

Re: So I've got off the ground.

Post by BlackAura »

A few possibilities.

First, The z value probably doesn't do what you think it does. It's doesn't represent the distance from the viewpoint. It's actually 1 / z (because the DC does perspective correct texture mapping, so it needs 1 / z instead of z). So, smaller values are actually further away than larger values.

Second, you can probably forget about this working properly on an emulator. The PVR will actually sort transparent polygons by depth, and then render them back to front. A PC graphics card can't do this, and emulators generally don't bother emulating it.

Third, as BlueCrab said, make sure the TR display list is enabled, that your transparent objects are being rendered into that list, and your pvr_cxt_t was set in the right display list - if you're using a context for an opaque polygon (as the sample code you posted does), it will have all the blending modes disabled, so the background will simply be black. You have to get all of those things right, or blending simply won't work.
Post Reply