[MSX-C] Q&A official thread

Page 29/57
22 | 23 | 24 | 25 | 26 | 27 | 28 | | 30 | 31 | 32 | 33 | 34

By Grauw

Ascended (10604)

Grauw's picture

22-02-2016, 21:57

Reading into a buffer per-byte is inefficient though… better to read larger blocks at a time.

E.g. off the top of my head based on Sylvester’s example:

TINY buf[256];
…
int size = fread(buf, 256, 1, fp);
if (size != 39) {
    printf("Unexpected size.");
} else if (buf[0] != 0xfe) {
    printf("Not a palette file.");
} else {
    while (i = 0; i < 16; i++) {
        printf("%5x", ((int*)(buf + 7))[i]);
    }
}

Note sure if the ((int*)(buf + 7))[i] expression produces the expected result, but you get the drift.

Could also define a struct { byte id, int start, int end, int exec, int[16] palette } and read straight into that, with block size sizeof(thestruct)… Seems like a really convenient way to do it actually Smile.

By AxelStone

Prophet (3120)

AxelStone's picture

22-02-2016, 23:18

Here goes an almost working code:

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

#define REGISTROS 16
int paleta[REGISTROS];
int valores[REGISTROS];

NAT grbdat[16]={0x0442,0x0000,0x0400,0x0040,0x0200,0x0221,0x0231,0x0224,0x0346,0x0777,0x0436,0x0120,0x0555,0x0420,0x0250,0x0113};

readHex() {
	FILE *file;
	char *head;
	char str[2];
	int i;
	int valor;
	printf("Loading pal...\n");
	file=fopen("arthur4.pl5","rb");
	fread(head,sizeof(char),7,file); /* Quitamos cabecera */
	fread(paleta,sizeof(int),REGISTROS,file);
	printf("Loaded\n");
	fclose(file);
	for(i=0;i<REGISTROS;i++) {
		printf("%x ",paleta[i]); /* 1st printf */
		printf("%x ",grbdat[i]); /* 2nd printf */
		sprintf(str,"%x", paleta[i]);
		sscanf(str,"%x",&valor); 
		printf("%x ",valor); /* 3rd printf */
	}
}

main() {
	readHex();
}

The 3 printf prints exactly the same, so it's supossed that palette is being readed correctly.
442 0 400 ...

However this funcion works (sets palete correctly):

loadplt() {
	TINY pal;
	iniplt();
	for(pal=0;pal<16;pal++) {
		setplt(pal,grbdat[pal]); 
	}
	rstplt();
} 

And this one not:

ldplt() {
	FILE *fp;
	char *head;
	char str[2];
	int i;
	NAT valor;
	TINY pal;
	fp=fopen("arthur4.pl5","rb");
	if(fp==NULL) {
		printf("File read error!");
		return;
	}
	fread(head,sizeof(char),7,fp);		 
	fread(paleta,sizeof(int),REGISTROS,fp);
	fclose(fp);
	iniplt();
	for(pal=0;pal<16;pal++) {
		sprintf(str,"%x",paleta[i]);
		sscanf(str,"%x",&valor);
		setplt(pal,&valor);
	}
	rstplt(); 
}

What's wrong? Question

By Grauw

Ascended (10604)

Grauw's picture

23-02-2016, 00:19

	fread(head,sizeof(char),7,file); /* Quitamos cabecera */

Ai, scary, uninitialised head pointer, reading into unallocated space -> memory corruption.

	char str[2];

C strings are null-terminated so you don’t allocate enough space to hold a 4-digit hexadecimal number + null terminator -> memory corruption.

		sprintf(str,"%x",paleta[i]);
		sscanf(str,"%x",&valor);

Why do you sprintf and then sscanf? NAT is just an int right? You can pass paleta[i] directly to setplt() without first converting it to string and back.

By Grauw

Ascended (10604)

Grauw's picture

23-02-2016, 00:17

Also, here’s an example of loading into a struct:

struct BinPalette {
   TINY head[7];            /* char */
   NAT paleta[REGISTROS];   /* int */
};

ldplt() {
   FILE *fp;
   BinPalette binpal;
   int i;
   TINY pal;

   fp = fopen("arthur4.pl5", "rb");
   if (fp == NULL) {
      printf("File read error!");
      return;
   }
   fread(&binpal, sizeof(BinPalette), 1, fp);
   fclose(fp);
   iniplt();
   for (pal = 0; pal < REGISTROS; pal++) {
      setplt(pal, binpal.paleta[i]);
   }
   rstplt(); 
}

Note that I’m unfamiliar with the exact syntax of K&R C so fingers crossed that it works Smile, but hopefully it’ll illustrate the idea.

By AxelStone

Prophet (3120)

AxelStone's picture

23-02-2016, 08:48

It seems a good way Grauw, as soon as I come back home I will try it thanks Wink

By DarkSchneider

Paladin (944)

DarkSchneider's picture

23-02-2016, 10:17

What about this?

#define PALETTE_COLOR_COUNT 16

void ldplt(void) {
	FILE *f;
	NAT palette[PALETTE_COLOR_COUNT];
	NAT palette_address;
	
	palette_address = 0x7680; // palette address on VRAM
	
	f = fopen("file.pl5", "rb");
	if(f != NULL) {
		fseek(f, 7, SEEK_SET); // bypass the header
		fread(palette, sizeof(NAT), PALETTE_COLOR_COUNT, f);
		fclose(f);
		
		// copy palette to VRAM palette address
		ldirvm(palette_address, palette, sizeof(NAT)*PALETTE_COLOR_COUNT);
		// restore the palette
		rstplt();
	}
}

By AxelStone

Prophet (3120)

AxelStone's picture

23-02-2016, 15:26

I've just tested @DarkSchneider code and works. Only one modification: fseek doesn't exist un MSX-C, replace with fread of 7 bytes to skip file header.

By DarkSchneider

Paladin (944)

DarkSchneider's picture

23-02-2016, 16:18

It would be useful to have a "seek", at least forward, function for files. Maybe this one works:

#define FSEEK_BUFFER_SIZE 32
#define FSEEK_STEPS_SHIFT 5 // FSEEK_STEPS_SHIFT = log2(FSEEK_BUFFER_SIZE)

int ffwd(int size, FILE *f) {
	char buffer[FSEEK_BUFFER_SIZE];
	int steps, remainder;
	
	steps = size >> FSEEK_STEPS_SHIFT;
	remainder = size - (steps << FSEEK_STEPS_SHIFT);
	
	// steps
	while(steps > 0) {
		fread(buffer, FSEEK_BUFFER_SIZE, 1, f);
		if(feof(f) || ferror(f)) {
			return 0; // fail
		}
		steps--;
	}
	// remainder
	if(remainder > 0) {
		fread(buffer, remainder, 1, f);
		if(feof(f) || ferror(f)) {
			return 0; // fail
		}
	}
	return 1; // success
}

By AxelStone

Prophet (3120)

AxelStone's picture

25-02-2016, 19:56

Let's go to the next quetion. Somebody knows how to reserve memory statically? This is, I'm not talking about malloc function (dinamically reserved), I'm talking about somekind of compiler option to tells it "I want to reserve memory from D800H to DC87H, not use it since I'm going to store here a asm function to be called during execution".

Is there any compiler directive to indicate it? Thanks.

By Grauw

Ascended (10604)

Grauw's picture

25-02-2016, 20:00

A global byte array?

The space will be reserved statically, although you can’t tell it what start address it must have (idk if you need that).

Page 29/57
22 | 23 | 24 | 25 | 26 | 27 | 28 | | 30 | 31 | 32 | 33 | 34