musicmud-2.1.6/data/
musicmud-2.1.6/data/help/
musicmud-2.1.6/data/policy/
musicmud-2.1.6/data/wild/
musicmud-2.1.6/data/world/
musicmud-2.1.6/doc/
musicmud-2.1.6/src/ident/
musicmud-2.1.6/src/lua/
musicmud-2.1.6/src/lua/include/
musicmud-2.1.6/src/lua/src/lib/
musicmud-2.1.6/src/lua/src/lua/
musicmud-2.1.6/src/lua/src/luac/
/*
 * MusicMUD Daemon, version 1.0
 * Copyright (C) 1998-2003 Abigail Brady
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * 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.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#include "charset.h"
#include "musicmud.h"
#include "msi.h"

static int macroman[128] = {
  /*  0    1   2    3   4     5    6    7  */
    0xc4,0xc5,  0xc7,  0xc9,  0xd1,  0xd6,  0xdc,  0xe1,
    0xe0,0xe2,  0xe4,  0xe3,  0xe5,  0xe7,  0xe9,  0xe8,
    0xea,0xeb,  0xed,  0xec,  0xee,  0xef,  0xf1,  0xf3,
    0xf2,0xf4,  0xf6,  0xf5,  0xfa,  0xf9,  0xfb,  0xfc,
  0x2020,0xb0,  0xa2,  0xa3,  0xa7,  0x2022,0xb6,  0xdf,
    0xae,0xa9,  0x2122,0xb4,  0xa8,  0x2260,0xc6,  0xd8,
  0x221e,0xb1,  0x2264,0x2265,0xa5,  0xb5,  0x2202,0x2211,
  0x220f,0x3c0, 0x222b,0xaa,  0xba,  0x3a9, 0xe6,  0xf8,
    0xbf,0xa1,  0xac,  0x221a,0x192, 0x2248,0x2206,0xab,
    0xbb,0x2026,0xa0,  0xc0,  0xc3,  0xd5,  0x152, 0x153,
  0x2013,0x2014,0x201c,0x201d,0x2018,0x2019,0xf7,  0x25ca,
    0xff,0x178, 0x2044,0x20ac,0x2039,0x203a,0xfb01,0xfb02,
  0x2021,0xb7,  0x201a,0x201e,0x2030,0xc2,  0xca,  0xc1,
    0xcb,0xc8,  0xcd,  0xce,  0xcf,  0xcc,  0xd3,  0xd4,
      -1,0xd2,  0xda,  0xdb,  0xd9,  0x131, 0x2c6, 0x2dc,
    0xaf,0x2d8, 0x2d9, 0x2da, 0xb8,  0x2dd, 0x2db, 0x2c7,
};

static int cp437[128] = {
  0xc7,   0xfc,   0xe9,   0xe2,   0xe4,   0xe0,   0xe5,   0xe7,
  0xea,   0xeb,   0xe8,   0xef,   0xee,   0xec,   0xc4,   0xc5,
  0xc9,   0xe6,   0xc6,   0xf4,   0xf6,   0xf2,   0xfb,   0xf9,
  0xff,   0xd6,   0xdc,   0xa2,   0xa3,   0xa5,   0x20a7, 0x192,
  0xe1,   0xed,   0xf3,   0xfa,   0xf1,   0xd1,   0xaa,   0xba,
  0xbf,   0x2310, 0xac,   0xbd,   0xbc,   0xa1,   0xab,   0xbb,
  0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
  0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510,
  0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f,
  0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567,
  0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b,
  0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580,
  0x3b1,  0xdf,   0x393,  0x3c0,  0x3a3,  0x3c3,  0xb5,   0x3c4,
  0x3a6,  0x398,  0x3a9,  0x3b4,  0x221e, 0x3c6,  0x3b5,  0x2229,
  0x2261, 0xb1,   0x2265, 0x2264, 0x2320, 0x2321, 0xf7,   0x2248,
  0xb0,   0x2219, 0xb7,   0x221a, 0x207f, 0xb2,   0x25a0, 0xa0,
};

static int cp850[128] = {
  0xc7,   0xfc,   0xe9,   0xe2,   0xe4,   0xe0,   0xe5,   0xe7,
  0xea,   0xeb,   0xe8,   0xef,   0xee,   0xec,   0xc4,   0xc5,
  0xc9,   0xe6,   0xc6,   0xf4,   0xf6,   0xf2,   0xfb,   0xf9,
  0xff,   0xd6,   0xdc,   0xf8,   0xa3,   0xd8,   0xd7,   0x192,
  0xe1,   0xed,   0xf3,   0xfa,   0xf1,   0xd1,   0xaa,   0xba,
  0xbf,   0xae,   0xac,   0xbd,   0xbc,   0xa1,   0xab,   0xbb,
  0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0xc1,   0xc2,   0xc0,
  0xa9,   0x2563, 0x2551, 0x2557, 0x255d, 0xa2,   0xa5,   0x2510,
  0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0xe3,   0xc3,
  0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0xa4,
  0xf0,   0xd0,   0xca,   0xcb,   0xc8,   0x131,  0xcd,   0xce,
  0xcf,   0x2518, 0x250c, 0x2588, 0x2584, 0xa6,   0xcc,   0x2580,
  0xd3,   0xdf,   0xd4,   0xd2,   0xf5,   0xd5,   0xb5,   0xfe,
  0xde,   0xda,   0xdb,   0xd9,   0xfd,   0xdd,   0xaf,   0xb4,
  0xad,   0xb1,   0x2017, 0xbe,   0xb6,   0xa7,   0xf7,   0xb8,
  0xb0,   0xa8,   0xb7,   0xb9,   0xb3,   0xb2,   0x25a0, 0xa0,
};

static int cp1252[128] = {
  0x20ac, -1,     0x201a, 0x192,  0x201e, 0x2026, 0x2020, 0x2021,
  0x2c6,  0x2030, 0x160,  0x2039, 0x152,  -1,     0x17d,  -1, 
  -1,     0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014,
  0x2dc,  0x2122, 0x161,  0x203a, 0x153,  -1,     0x17e,  0x178,
  0xa0,   0xa1,   0xa2,   0xa3,   0xa4,   0xa5,   0xa6,   0xa7,
  0xa8,   0xa9,   0xaa,   0xab,   0xac,   0xad,   0xae,   0xaf,
  0xb0,   0xb1,   0xb2,   0xb3,   0xb4,   0xb5,   0xb6,   0xb7,
  0xb8,   0xb9,   0xba,   0xbb,   0xbc,   0xbd,   0xbe,   0xbf,
  0xc0,   0xc1,   0xc2,   0xc3,   0xc4,   0xc5,   0xc6,   0xc7,
  0xc8,   0xc9,   0xca,   0xcb,   0xcc,   0xcd,   0xce,   0xcf,
  0xd0,   0xd1,   0xd2,   0xd3,   0xd4,   0xd5,   0xd6,   0xd7,
  0xd8,   0xd9,   0xda,   0xdb,   0xdc,   0xdd,   0xde,   0xdf,
  0xe0,   0xe1,   0xe2,   0xe3,   0xe4,   0xe5,   0xe6,   0xe7,
  0xe8,   0xe9,   0xea,   0xeb,   0xec,   0xed,   0xee,   0xef,
  0xf0,   0xf1,   0xf2,   0xf3,   0xf4,   0xf5,   0xf6,   0xf7,
  0xf8,   0xf9,   0xfa,   0xfb,   0xfc,   0xfd,   0xfe,   0xff,
};

static int koi8r[128] = {

  // 8
  0x2500, 0x2502, 0x250c, 0x2510, 0x2514, 0x2518, 0x251c, 0x2524,
  0x252c, 0x2534, 0x253c, 0x2580, 0x2584, 0x2588, 0x258c, 0x2590,
  // 9
  0x2591, 0x2592, 0x2593, 0x2320, 0x25a0, 0x2022, 0x221a, 0x2248,
  0x2264, 0x2265, 0x00a0, 0x2321, 0x00b0, 0x00b2, 0x00b7, 0x00f7,
  // a
  0x2550, 0x2551, 0x2552, 0x0451, 0x2553, 0x2554, 0x2555, 0x2556,
  0x2557, 0x2558, 0x2559, 0x255a, 0x255b, 0x255c, 0x255d, 0x255e, 
  // b
  0x255f, 0x2560, 0x2561, 0x0401, 0x2562, 0x2563, 0x2564, 0x2565,
  0x2566, 0x2567, 0x2568, 0x2569, 0x256a, 0x256b, 0x256c, 0x00a9, 

  // c
  0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, 
  0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 
  // d
  0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432,
  0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, 

  // e
  0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, 
  0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 
  // f
  0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412,
  0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a, 
};

static int table2uni(int ch, int *table) {
  if (ch < 128)
    return ch;
  if (ch >= 256)
    return ch;
  return table[ch-128];
}

static int uni2table(int ch, int *table) {
  if (ch < 128)
    return ch;
  for (int i=0;i<128;i++)
    if (table[i] == ch) 
      return i + 128;
  return '?';
}

static int has_tables[CHAR_LAST] = {
  0, 
  0,
  0,
  1, 
  1,
  1,
  0,
  1,
  1,
};


bool has_table(charset c)
{
  if (c < 0)
    return 0;
  if (c >= CHAR_LAST)
    return 0;
  return has_tables[c];
}

int *cpuni_table[CHAR_LAST] = {
  0,
  0,
  0,
  macroman,
  cp850,
  cp437,
  0,
  cp1252,
  koi8r
};

int cp2uni(int ch, charset a)
{
  if (cpuni_table[a])
    return table2uni(ch, cpuni_table[(int)a]);
  if (a==CHAR_LATIN1)
    return ch;
  return '?';
}

int uni2cp(int ch, charset a)
{
  if (cpuni_table[a])
    return uni2table(ch, cpuni_table[(int)a]);
  if (a==CHAR_LATIN1 && ch < 0x100)
    return ch;
  return '?';
}

bool player_knows(const MudObject *who, int uni)
{
  if (uni < 0x7f)
    return 1;
  charset cs = get_charset(who);
  if (cs == CHAR_UNICODE)
    return 1;
  if (has_table(cs)) {
    if (uni2cp(uni, cs)!='?')
      return 1;
    return 0;
  }
  if (cs==CHAR_LATIN1 && uni <= 0x100)
    return 1;

  return 0;
}

charset get_charset(const MudObject *who) {
  if (!who) return CHAR_LATIN1;

  const char *cs = who->get("charset");
  if (streq(cs, "macroman")) return CHAR_MACROMAN;
  if (streq(cs, "cp850")) return CHAR_CP850;
  if (streq(cs, "koi8r")) return CHAR_KOI8R;
  if (streq(cs, "cp437")) return CHAR_CP437;
  if (streq(cs, "cp1252")) return CHAR_CP1252;
  if (streq(cs, "unicode")) return CHAR_UNICODE;
  if (streq(cs, "latin1")) return CHAR_LATIN1;
  if (streq(cs, "ascii")) return CHAR_ASCII;

  if (is_player(who)) {
    const Player *p = (const Player*)who;
    if (p->p && p->p->term.c_str()) {
      const char *t = p->p->term.c_str();
      if (streq(t, "ucryotel")) return CHAR_UNICODE;
      if (streq(t, "beipmu")) return CHAR_CP1252;
    }
  }
  return CHAR_LATIN1;
}