/*--------------------------------------------------------------
   Emulates (slowly) stdio file handling on top of Shinobi
   Another small and nasty but ultimately useful tidbit from

   Thomas Szirtes / Sega Europe
  --------------------------------------------------------------*/

#include "shinobi.h"

/* Assuming mode 1 filesystem. */
#define SECTOR_SIZE 2048

/* Sector buffer. */
Uint8 sector_buffer[SECTOR_SIZE*4];
int into_buf = SECTOR_SIZE;


/* File open. */
GDFS t_fopen(char *fname, char *attributes)
{
    GDFS gdfs;

    gdfs = gdFsOpen (fname, NULL);
    into_buf = SECTOR_SIZE;

    return gdfs;
}


/* File close. */
void t_fclose (GDFS stream)
{
    gdFsClose (stream);
}


/* File close. */
Uint32 t_fread (Uint8 *buffer, Uint32 size, Uint32 count, GDFS stream)
{
	Uint32	num_bytes;
	Uint32	bytes_left;

    num_bytes   = size * count;
    bytes_left  = num_bytes;

	if (into_buf < SECTOR_SIZE )
	{
        /* We still have some bytes already buffered up. */
		while (bytes_left > 0 && into_buf < SECTOR_SIZE )
		{
            *buffer = sector_buffer[into_buf];
            buffer++;
            into_buf++;
            bytes_left--;
		}
	}

    if (bytes_left <= 0)
        return num_bytes-bytes_left;

    /* Load sectors quickly first. */
	while (bytes_left > SECTOR_SIZE)
	{
        if (gdFsRead (stream, 1, buffer) != GDD_ERR_OK)
			return num_bytes - bytes_left;

        buffer += SECTOR_SIZE;
        bytes_left -= SECTOR_SIZE;
	}

    /* Multiple of sector size? */
    if (bytes_left <= 0)
        return num_bytes;

    /* Buffer up spare sector. */
    if (gdFsRead (stream, 1, &sector_buffer) != GDD_ERR_OK)
        return num_bytes - bytes_left;

    into_buf = 0;

    while (bytes_left > 0)
	{
        *buffer = sector_buffer[into_buf];
        buffer++;
        bytes_left--;
        into_buf++;
	}

	return	num_bytes - bytes_left;
}

