//**************************************************************************
//*                     This file is part of the                           *
//*                      Mpxplay - audio player.                           *
//*                  The source code of Mpxplay is                         *
//*        (C) copyright 1998-2006 by PDSoft (Attila Padar)                *
//*                    http://mpxplay.cjb.net                              *
//*                  email: mpxplay@freemail.hu                            *
//**************************************************************************
//*  This program is distributed in the hope that it will be useful,       *
//*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *
//*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *
//*  Please contact with the author (with me) if you want to use           *
//*  or modify this source.                                                *
//**************************************************************************
//function: keyboard handling (by bios memory area)

//#define KEYBOARD_DEBUG 1

#ifdef KEYBOARD_DEBUG
#include <stdio.h>
#endif

unsigned int pds_kbhit(void)
{
#ifdef __DOS__
 char *biosmem=(char *)0;
 if(*((unsigned short *)&biosmem[0x41a])==*((unsigned short *)&biosmem[0x41c]))
  return 0;
 return 1;
#else
 return kbhit();
#endif
}

#include <stdio.h>

unsigned int pds_extgetch(void)
{
#ifdef __DOS__
 char *biosmem=(char *)0;
 unsigned int keybufferpos;
 while(!pds_kbhit());
 keybufferpos=0x400+*((unsigned short *)&biosmem[0x41a]);
 *((unsigned short *)&biosmem[0x41a])+=2;
 if(*((unsigned short *)&biosmem[0x41a])>=*((unsigned short *)&biosmem[0x482]))
  *((unsigned short *)&biosmem[0x41a])=*((unsigned short *)&biosmem[0x480]);
#ifdef KEYBOARD_DEBUG
 fprintf(stdout,"getch: %4.4X\n",(unsigned long)*((unsigned short *)&biosmem[keybufferpos]));
#endif
 return *((unsigned short *)&biosmem[keybufferpos]);
#else
 unsigned int keycode=getch(); // ??? possibly bad for Mpxplay
 if(!keycode)
  keycode=getch();
 else
  keycode<<=8;                 // ???
 return keycode;
#endif
}

unsigned int pds_look_extgetch(void)
{
 if(pds_kbhit()){
#ifdef __DOS__
  char *biosmem=(char *)0;
  unsigned int keybufferpos=0x400+*((unsigned short *)&biosmem[0x41a]);
#ifdef KEYBOARD_DEBUG
  fprintf(stdout,"lookch: %4.4X\n",(unsigned long)*((unsigned short *)&biosmem[keybufferpos]));
#endif
  return *((unsigned short *)&biosmem[keybufferpos]);
#else
  unsigned int keycode=pds_extgetch();
  pds_pushkey(keycode);
  return keycode;
#endif
 }
 return 0;
}

void pds_pushkey(unsigned int newkey)
{
#ifdef __DOS__
 char *biosmem=(char *)0;
 unsigned int keybufferpos=0x400+*((unsigned short *)&biosmem[0x41c]);
 biosmem[keybufferpos]  =newkey&0xff;
 biosmem[keybufferpos+1]=newkey>>8;
 *((unsigned short *)&biosmem[0x41c])+=2;
 if(*((unsigned short *)&biosmem[0x41c])>=*((unsigned short *)&biosmem[0x482]))
  *((unsigned short *)&biosmem[0x41c])=*((unsigned short *)&biosmem[0x480]);
#else
 ungetch(newkey); // ???
#endif
}

typedef struct char_to_extkey_t{
 char c;
 unsigned short extkey;
}char_to_extkey_t;

static char_to_extkey_t keycodes[]={
 {'1',0x0231},{'2',0x0332},{'3',0x0433},{'4',0x0534},{'5',0x0635},
 {'6',0x0736},{'7',0x0837},{'8',0x0938},{'9',0x0A39},{'0',0x0B30},
 {'-',0x0C2D},{'=',0x0D3D},{'q',0x1071},{'w',0x1177},{'e',0x1265},
 {'r',0x1372},{'t',0x1474},{'y',0x1579},{'u',0x1675},{'i',0x1769},
 {'o',0x186F},{'p',0x1970},{'[',0x1A5B},{']',0x1B5D},{'a',0x1E61},
 {'s',0x1F73},{'d',0x2064},{'f',0x2166},{'g',0x2267},{'h',0x2368},
 {'j',0x246A},{'k',0x256B},{'l',0x266C},{';',0x273B},{'\'',0x2827},
 {'`',0x2960},{'\\',0x2B5C},{'z',0x2C7A},{'x',0x2D78},{'c',0x2E63},
 {'v',0x2F76},{'b',0x3062},{'n',0x316E},{'m',0x326D},{',',0x332C},
 {'.',0x342E},{'/',0x352F},{' ',0x3920},{'!',0x0221},{'@',0x0340},
 {'#',0x0423},{'$',0x0524},{'%',0x0625},{'^',0x075E},{'&',0x0826},
 {'*',0x092A},{'(',0x0A28},{')',0x0B29},{'_',0x0C5F},{'+',0x0D2B},
 {'Q',0x1051},{'W',0x1157},{'E',0x1245},{'R',0x1352},{'T',0x1454},
 {'Y',0x1559},{'U',0x1655},{'I',0x1749},{'O',0x184F},{'P',0x1950},
 {'{',0x1A7B},{'}',0x1B7D},{'A',0x1E41},{'S',0x1F53},{'D',0x2044},
 {'F',0x2146},{'G',0x2247},{'H',0x2348},{'J',0x244A},{'K',0x254B},
 {'L',0x264C},{':',0x273A},{'\"',0x2822},{'~',0x297E},{'|',0x2B7C},
 {'Z',0x2C5A},{'X',0x2D58},{'C',0x2E43},{'V',0x2F56},{'B',0x3042},
 {'N',0x314E},{'M',0x324D},{'<',0x333C},{'>',0x343E},{'?',0x353F},
 {'*',0x372A},{'-',0x4A2D},{'+',0x4E2B},{'/',0xE02F}, // gray buttons
 {0,0x0000}};

unsigned int newfunc_keyboard_char_to_extkey(char c)
{
 char_to_extkey_t *table=&keycodes[0];
 do{
  if(table->c==c)
   return table->extkey;
  table++;
 }while(table->c);
 return 0xffff;
}

char newfunc_keyboard_extkey_to_char(unsigned short extkey)
{
 char_to_extkey_t *table=&keycodes[0];
 do{
  if(table->extkey==extkey)
   return table->c;
  table++;
 }while(table->c);
 return 0xff;
}
