/***************************************************************************

  common.c

  Generic functions used in different emulators.
  There's not much for now, but it could grow in the future... ;-)

***************************************************************************/

#include <stdio.h>
#include "Z80.h"
#include "roms.h"
#include "vidhrdw.h"
#include "osdepend.h"


/***************************************************************************

  Read ROMs into memory.

  Arguments:
  unsigned char *dest - Pointer to the start of the memory region
                        where the ROMs will be loaded.

  const struct RomModule *romp - pointer to an array of Rommodule structures,
                                 as defined in common.h.

  const char *basename - Name of the directory where the files are
                         stored. The function also supports the
						 control sequence %s in file names: for example,
						 if the RomModule gives the name "%s.bar", and
						 the basename is "foo", the file "foo/foo.bar"
						 will be loaded.

***************************************************************************/
int readroms(unsigned char *dest,const struct RomModule *romp,const char *basename)
{
	FILE *f;
	char buf[100];
	char name[100];


	while (romp->name)
	{
		sprintf(buf,romp->name,basename);
		sprintf(name,"%s/%s",basename,buf);

		if ((f = fopen(name,"rb")) == 0)
		{
			printf("Unable to open file %s\n",name);
			return 1;
		}
		if (fread(dest + romp->offset,1,romp->size,f) != romp->size)
		{
			printf("Unable to read file %s\n",name);
			fclose(f);
			return 1;
		}
		fclose(f);

		romp++;
	}

	return 0;
}



void setdipswitches(int *dsw,const struct DSW *dswsettings)
{
	struct DisplayText dt[40];
	int settings[20];
	int i,s,key;
	int total;


	total = 0;
	while (dswsettings[total].num != -1)
	{
		int msk,val;


		msk = dswsettings[total].mask;
		if (msk == 0) return;	/* error in DSW definition, quit */
		val = dsw[dswsettings[total].num];
		while ((msk & 1) == 0)
		{
			val >>= 1;
			msk >>= 1;
		}
		settings[total] = val & msk;

		total++;
	}

	s = 0;
	do
	{
		for (i = 0;i < total;i++)
		{
			dt[2 * i].color = (i == s) ? YELLOW_TEXT : WHITE_TEXT;
			dt[2 * i].text = dswsettings[i].name;
			dt[2 * i].x = 2 + FIRST_VISIBLE_COLUMN;
			dt[2 * i].y = 2 * i + (V_CHARS - 2 * total - 1) / 2;
			dt[2 * i + 1].color = (i == s) ? YELLOW_TEXT : WHITE_TEXT;
			dt[2 * i + 1].text = dswsettings[i].values[settings[i]];
			dt[2 * i + 1].x = LAST_VISIBLE_COLUMN - 2 - strlen(dt[2 * i + 1].text);
			dt[2 * i + 1].y = dt[2 * i].y;
		}
		dt[2 * i].text = 0;	/* terminate array */

		displaytext(dt,1);

		key = osd_read_key();

		switch (key)
		{
			case OSD_KEY_DOWN:
				if (s < total - 1) s++;
				break;

			case OSD_KEY_UP:
				if (s > 0) s--;
				break;

			case OSD_KEY_RIGHT:
				if (dswsettings[s].reverse == 0)
				{
					if (dswsettings[s].values[settings[s] + 1] != 0) settings[s]++;
				}
				else
				{
					if (settings[s] > 0) settings[s]--;
				}
				break;

			case OSD_KEY_LEFT:
				if (dswsettings[s].reverse == 0)
				{
					if (settings[s] > 0) settings[s]--;
				}
				else
				{
					if (dswsettings[s].values[settings[s] + 1] != 0) settings[s]++;
				}
				break;
		}
	} while (key != OSD_KEY_TAB && key != OSD_KEY_ESC);

	while (osd_key_pressed(key));	/* wait for key release */

	if (key == OSD_KEY_ESC) CPURunning = 0;

	while (--total >= 0)
	{
		int msk;


		msk = dswsettings[total].mask;
		while ((msk & 1) == 0)
		{
			settings[total] <<= 1;
			msk >>= 1;
		}

		dsw[dswsettings[total].num] = (dsw[dswsettings[total].num] & ~dswsettings[total].mask) | settings[total];
	}

	vh_screenrefresh();
}
