reading sc5 file in C

Pagina 1/3
| 2 | 3

Door Wolverine_nl

Paragon (1160)

afbeelding van Wolverine_nl

01-06-2014, 21:46

Hi,
I am struggling with reading a .sc5 file in C. I am using fgets to read the binary file, but it's not really going very well. Maybe someone has done this before? I tried a few standard things from books and from the web, but they arent meant for graphical screen data. I want to load the screendata and copy the data to vram so I can use it.

I got the following:

main()
{
FILE *scrfile;
int c;

scrfile = fopen("test.sc5","rb");
if(!scrfile)
{
/* if file doesnt exist */
exit(1);
}

while( (c = fgets(scrfile)) != EOF)
{
/* and here i am stuck, how do i collect the content of the sc5 file?  */
/* do I treat the scrfile as a buffer and can i put this buffer 
somewhere to later copy it to vram? */

  int i;

  for(i = 0;i < scrfile_size;++i) {
  putchar(scrfile[i]); }
}
fclose(scrfile);
return(0);
}

Aangemeld of registreer om reacties te plaatsen

Van Daemos

Prophet (2066)

afbeelding van Daemos

01-06-2014, 22:06

You have the file opened so you can now copy its contents to the RAM or directly to the VRAM by first copying portions to the RAM then out the portions to the VRAM or the dirty method by reading the whole filedata into the RAM then copying it to the VRAM.

You skip the first (not sure 5 or 7) bytes then simply lineary output the data to the VRAM page. The pallet data is at the end of the file so copy it and write it to the pallet registers.

Van hit9918

Prophet (2932)

afbeelding van hit9918

01-06-2014, 23:34

I wonder, did compiler tell no error?
Is it no standard library? Because normaly fgets has much different parameters.
fgets is about strings, it will swallow 0 bytes as "end of string". or find no 0 end and then mess all up.

You need fgetc().
But for apropriate speed, better would be fread().
Reading 512 bytes at once.
The return value then is not EOF, but saying how much could be read.

Van Wolverine_nl

Paragon (1160)

afbeelding van Wolverine_nl

02-06-2014, 12:03

ah, thanks, so fread and I read in as a pointer untill the [max_bytes] is reached.
I did read with fgets/c not as an integer, but as char, that worked, but couldnt use the data and fgets has 2 extra parameters indeed, it did continue compile, but with warning.
I will try to make it work with fread and create a pointer array.

Van ro

Scribe (4964)

afbeelding van ro

02-06-2014, 12:19

Yes, skip the first 7 bytes (bin header) and remember that one byte contains two pixels in screen 5 Wink

Van Wolverine_nl

Paragon (1160)

afbeelding van Wolverine_nl

02-06-2014, 12:30

thanks Ro for the reminder Smile
I will post the code once I have a working version of it, maybe some1 also wants this in their library, it's ASCII MSX-C though, but conversing it into ANSI C shouldnt be that hard. Wink

Van hit9918

Prophet (2932)

afbeelding van hit9918

02-06-2014, 20:43

Quote:

it did continue compile, but with warning.

A warning is misleading. Calling a function with less parameters than nessesary is bad error.

Quote:

I will try to make it work with fread and create a pointer array

Mhm why? I am a big fan of pointerarrays in 8bit game dev but... there is no need here.

first have a buffer
	char buf[512];
who knows how small is MSX stack, keep this outside the function, keeping it off the stack.

then in the function:

while (1) {
	int n;
	n = fread(buf,1,512,filepointer);
	
	now dump n bytes from buf to vram. take care, n might be 0.
	
	if (n == 0) break;
}

A thing with fread is that it might transfer in smaller chunks than requested.
when n < 512, it doesnt mean one is at end of the file.
only when it really is 0.
being picky, when it is 0, one would have to check whether the reason was an error.
but that can be added later, properly get it to vram first.

Van Wolverine_nl

Paragon (1160)

afbeelding van Wolverine_nl

03-06-2014, 16:02

I got a screen full of junk at the moment, my internet at my appartmrnt isnt working now, will post the code later.

Van MsxKun

Paragon (1124)

afbeelding van MsxKun

03-06-2014, 18:02

I woudln't know. I needed a proper viewer to use in linux and the linux version of ViewMSX was very so so.
At the end I made my viewer, but using PureBasic.

Van nerlaska

Master (166)

afbeelding van nerlaska

03-06-2014, 18:25

I hope this code helps you. Regards!

function OpenSC5 (_path)
{
	_tex = null;
	_file = g_msxengine.FileOpen (_path, FILE_MODE_READ);
	if (_file)
	{
		_tex = Render_NewTexture (256, 212, TF_RGB);
		if (Texture_Lock (_tex))
		{
			_pal = ReadBSAVEPalette (_file);
			
			_file.SetPos (0);
			ReadBSAVEHeader (_file);
			for (j=0; j<212; j++)
			{
				for (i=0; i<256; i+=2)
				{
					_color = _file.ReadByte(); 
					Texture_SetColor (_tex, i, j, _pal[_color>>4]);
					Texture_SetColor (_tex, i+1, j, _pal[_color & 0x0F]);
				}
			}
			Texture_Unlock (_tex);
		}
		g_msxengine.FileClose (_file);
	}
	return _tex;
}

function ReadBSAVEPalette (_file, _off = 0x7687)
{
	_pal = [];
	_pal += 16;
	_buffer = Buffer_New(32);
	_file.SetPos (_off); 
	_file.Read (_buffer); 
	for (j=0; j<16; j++)
	{
		_color = Buffer_GetShort (_buffer, j*2);

		_r = ( ((_color & 0x0078) >> 2) | ((_color & 0x0800) >> 11) ) << 3;
		_g = ( ((_color & 0x0700) >> 6) | ((_color & 0xC000) >> 14) ) << 3;
		_b = ( ((_color & 0x0007) << 2) | ((_color & 0x3000) >> 12) ) << 3;
		
		_pal[j] = RGB(_r, _g, _b);
	}
	Buffer_Delete (_buffer);
	return _pal;
}

function ReadBSAVEHeader (_file)
{
	_file.ReadByte(); 
	_file.ReadShort(); 
	_file.ReadShort(); 
	_file.ReadShort(); 
}

Van Wolverine_nl

Paragon (1160)

afbeelding van Wolverine_nl

04-06-2014, 19:05

Well, after some time i got a very raw msx-c code for loading a screen 5 file, mind, I did resaved it in graphsaurus to split the image and the paletfile.
I still see a quick screen filled with lines, this is page 0, I dunno how that came to be, page 1 is working fine and the image is displayed there fine.
here is the somewhat messy code Wink (oh and BTW it is not meant for PC, it is to be executed on MSX-DOS2)

#pragma nonrec
#include <stdio.h>
#include <glib.h>

#define logop (TINY) 0
#define sp_trig (TINY) 0 /* spacebar trigger */

int gfile()
{
FILE *gdata;
static TINY gbuf[27143]; /* total filesize in bytes */
int x;
int i;
int bsize;

bsize = 27143; /* imagesize with header  */
x = 1;

gdata = fopen("titles.sr5","rb");
	if(!gdata)
		{ /* unable to open file handler */
			exit(1); }

fread(gbuf,bsize,x,gdata);

filvrm(0x0000,bsize,*gbuf);
fclose(gdata);

}

gplt()
{
FILE *pdata;
static TINY pbuf[256]; /* total filesize in bytes */
int x;
int i;
int psize;
psize = 256; /* palette  */
x = 1;

pdata = fopen("titles.pl5","rb");
	if(!pdata)
		{ /* unable to open file handler */
			exit(1); }

fread(pbuf,psize,x,pdata);
filvrm(0x7680,psize,*pbuf);
fclose(pdata);
}

main()
{
cls(); screen((TINY)5);
ginit();
color((TINY)15, (TINY)1, (TINY)1);   
iniplt();

gfile();
gplt();
setpg((TINY)1,(TINY)0); 	      

/* spacebar ends program */


while(gttrig(sp_trig) == 0)
	{
		if (gttrig(sp_trig) ==1)
		{
			break;
			}
	}


screen((TINY)0);
color((TINY)15, (TINY)4, (TINY)4);

printf("thanks for testing...");
kilbuf();
}


I think page 0 is this weird filled page because of the header, I didnt find a good way to get rid of it via the code, I was thinking of erasing those first 7 bytes, this is why I am using the pointers, untill now I havent gotten it right.

Pagina 1/3
| 2 | 3