Compare commits

..
Author SHA1 Message Date
kichikuou bc9fc924ed [experimental] Unicode mode
This adds "Unicode mode", in which scenarios can be written in any
language. xsys35c 1.2.0 and later can produce Unicode scenarios.

- nact->encoding represents the current scenario encoding. The initial
  value is SJIS, and ZU command changes it to UTF8.

- Use conversion macros that switch the behavior by the scenario
  encoding. For example, toUTF8() calls sjis2utf() if the scenario
  encoding is SJIS, and calls strdup() if it is UTF8.

- Fix various string processing functions to work with UTF8.
2020-08-09 21:24:56 +09:00
kichikuou d8fbf9a8b1 Cleanup 2020-08-09 13:41:26 +09:00
kichikuou 077e4d32e0 Fix emscripten build 2020-08-08 23:07:53 +09:00
kichikuou 652e4b9111 Simplify ags_drawStringToSurface() 2020-08-08 22:57:22 +09:00
kichikuou 3cecc58607 Narrow dependency on font.h
This removes font.h dependency from header files such as ags.h and
nact.h. After this, font.h must be explicitly included in order to use
font functions.
2020-08-08 22:52:47 +09:00
kichikuou f31742a503 Font functions only handle utf-8 strings
Conversion from Shift_JIS is done in ags.c.
2020-08-08 22:03:58 +09:00
kichikuou e830190537 Add ags_drawStringToSurface() 2020-08-08 21:28:01 +09:00
kichikuou 7d8458c86d Emscripten: Remove getMemory from EXTRA_EXPORTED_RUNTIME_METHODS 2020-08-08 14:29:44 +09:00
kichikuou dfc10a7f34 Update emscripten to 1.40.1 2020-08-08 10:35:23 +09:00
kichikuou a5684cffa4 Switch README.md to English, and add a link to the releases page 2020-08-06 19:28:15 +09:00
44 changed files with 479 additions and 274 deletions
+1 -1
View File
@@ -2,7 +2,7 @@ name: Emscripten Build
on: [push, pull_request]
env:
emscripten-version: 1.39.16
emscripten-version: 1.40.1
jobs:
build:
+11 -11
View File
@@ -1,24 +1,24 @@
# xsytem35-sdl2
アリスソフトのゲームエンジン System3.x のフリー実装である xsystem35 を SDL2 に対応して、emscripten でコンパイルできるようにしたものです。
This is a multi-platform port of xsystem35, a free implementation of AriceSoft's System3.x game engine.
## ビルド方法
### Linux
## Download
Prebuilt binaries for Windows and Android can be downloaded from the [Releases](https://github.com/kichikuou/xsystem35-sdl2/releases) page.
[cmake](https://cmake.org/) が必要です。
## Build
### Linux (Debian / Ubuntu)
$ sudo apt install build-essential cmake libsdl2-dev libsdl2-ttf-dev libsdl2-mixer-dev
$ mkdir -p out/debug
$ cd out/debug
$ cmake -DCMAKE_BUILD_TYPE=Debug ../../
$ make && make install
cmake の実行でエラーになる場合は必要なライブラリをインストールしてください。
グラフィックスシステムとして X11 と SDL2 が使用可能です。両方存在する場合は X11 が優先されますが、`cmake` のオプションに `-DENABLE_X11=NO` を指定すると SDL2 が使われます。
You can choose between X11 and SDL2 as the graphics backend. If both libraries are found, X11 is used by default, but if `-DENABLE_X11=NO` flag is given to the `cmake` invocation, then SDL2 will be used.
### MacOS
[Homebrew](https://brew.sh/index_ja) が必要です。
[Homebrew](https://brew.sh/index_ja) is needed.
$ brew install cmake pkg-config sdl2 sdl2_mixer freetype libjpeg
$ mkdir -p out/debug
@@ -28,7 +28,7 @@ cmake の実行でエラーになる場合は必要なライブラリをイン
### Windows
[MSYS2](https://www.msys2.org) が必要です。
[MSYS2](https://www.msys2.org) is needed.
$ pacman -S cmake mingw-w64-x86_64-cmake mingw-w64-x86_64-SDL2 mingw-w64-x86_64-SDL2_ttf mingw-w64-x86_64-SDL2_mixer mingw-w64-x86_64-libjpeg-turbo
$ mkdir -p out/debug
@@ -43,8 +43,8 @@ cmake の実行でエラーになる場合は必要なライブラリをイン
$ emcmake cmake -DCMAKE_BUILD_TYPE=MinSizeRel ../../
$ make
実行するには、[鬼畜王 on Webのリポジトリ](https://github.com/kichikuou/web)をチェックアウトして、`docs`ディレクトリに `out/xsystem35.*` をすべてコピーしてください。
To use the generated binary, checkout [Kichikuou on Web](https://github.com/kichikuou/web) and copy `out/xsystem35.*` into its `docs` directory.
### Android
[android/README.md](android/) を参照してください。
See [android/README.md](android/).
+1 -1
View File
@@ -39,7 +39,7 @@ static void Init(void) { /* 0 */
}
static void InitGame() { /* 1 */
nact->ags.font->antialiase_on = TRUE;
ags_setAntialiasedStringMode(TRUE);
sys_setHankakuMode(2);
nact->msgout = ntmsg_add;
+1 -13
View File
@@ -104,7 +104,7 @@ void ntmsg_init() {
// 主人公名前
nt_sstr_regist_replace(utf2sjis(SNAME_RYO), utf2sjis(SNAME_RYO_DEF));
nt_sstr_regist_replace(fromUTF8(SNAME_RYO), fromUTF8(SNAME_RYO_DEF));
night.msg.cbmove = cb_mousemove;
night.msg.cbrelease = cb_keyrelease;
@@ -188,12 +188,6 @@ void ntmsg_add(const char *msg) {
if (msg[0] == '\0') return;
if (0) {
char *b = sjis2utf(msg);
fprintf(stderr, "add msg '%s'\n", b);
free(b);
}
len = MSGBUFMAX - (int)strlen(night.msgbuf);
if (len < 0) {
WARNING("buf shortage (%d)\n", len);
@@ -260,12 +254,6 @@ static void ntmsg_out(int wNum, int wSize, int wColorR, int wColorG, int wColorB
dt_setfont(wFont, wSize);
if (1) {
char *b = sjis2utf(mbuf);
fprintf(stderr, "msg '%s'\n", b);
free(b);
}
cw = dt_drawtext_col(sp->u.msg.canvas,
sp->u.msg.dspcur.x,
sp->u.msg.dspcur.y,
+4 -18
View File
@@ -30,7 +30,6 @@
#include "portab.h"
#include "nact.h"
#include "system.h"
#include "utfsjis.h"
#include "ags.h"
#include "surface.h"
#include "ngraph.h"
@@ -204,24 +203,14 @@ int nt_scg_create_blend(int wNumDstCG, int wNumBaseCG, int wX, int wY, int wNumB
// 指定の文字列のCGを作成
int nt_scg_create_text(int wNumCG, int wSize, int wR, int wG, int wB, char *cText) {
cginfo_t *i;
agsurface_t *glyph;
FONT *font;
if (0) {
char *b = sjis2utf(cText);
WARNING("str = '%s'\n", b);
free(b);
}
spcg_assert_no(wNumCG);
// 勝手に出ていいのかな?
if (strlen(cText) == 0) return OK;
font = nact->ags.font;
font->sel_font(FONT_GOTHIC, wSize);
glyph = font->get_glyph(cText);
ags_setFont(FONT_GOTHIC, wSize);
agsurface_t *glyph = ags_drawStringToSurface(cText);
i = malloc(sizeof(cginfo_t));
i->type = CG_SET;
i->no = wNumCG;
@@ -242,8 +231,6 @@ int nt_scg_create_text(int wNumCG, int wSize, int wR, int wG, int wB, char *cTex
// 数字文字列のCGを作成
int nt_scg_create_textnum(int wNumCG, int wSize, int wR, int wG, int wB, int wFigs, int wZeroPadding, int wValue) {
cginfo_t *i;
agsurface_t *glyph;
FONT *font;
char s[256], ss[256];
spcg_assert_no(wNumCG);
@@ -257,9 +244,8 @@ int nt_scg_create_textnum(int wNumCG, int wSize, int wR, int wG, int wB, int wFi
}
sprintf(s, ss, wValue);
font = nact->ags.font;
font->sel_font(FONT_GOTHIC, wSize);
glyph = font->get_glyph(s);
ags_setFont(FONT_GOTHIC, wSize);
agsurface_t *glyph = ags_drawStringToSurface(s);
i = malloc(sizeof(cginfo_t));
i->type = CG_SET;
+1 -1
View File
@@ -132,7 +132,7 @@ static void Init() {
sact.dmap = sf_create_pixel(sf0->width, sf0->height, 16);
// その他 System35 のデフォルト動作の変更
nact->ags.font->antialiase_on = TRUE;
ags_setAntialiasedStringMode(TRUE);
sys_setHankakuMode(2); // 全角半角変換無し
ags_autorepeat(FALSE); // key auto repeat off
+7 -21
View File
@@ -35,7 +35,6 @@
#include "sactcg.h"
#include "surface.h"
#include "ngraph.h"
#include "utfsjis.h"
#include "sactcg_stretch.c"
#include "sactcg_blend.c"
@@ -202,24 +201,14 @@ int scg_create_blend(int wNumDstCG, int wNumBaseCG, int wX, int wY, int wNumBlen
// 指定の文字列のCGを作成
int scg_create_text(int wNumCG, int wSize, int wR, int wG, int wB, int wText) {
cginfo_t *i;
agsurface_t *glyph;
FONT *font;
if (0) {
char *b = sjis2utf(v_str(wText-1));
WARNING("str = '%s'\n", b);
free(b);
}
spcg_assert_no(wNumCG);
// 勝手に出ていいのかな?
if (v_strlen(wText -1) == 0) return OK;
font = nact->ags.font;
font->sel_font(FONT_GOTHIC, wSize);
glyph = font->get_glyph(v_str(wText -1));
ags_setFont(FONT_GOTHIC, wSize);
agsurface_t *glyph = ags_drawStringToSurface(v_str(wText -1));
i = malloc(sizeof(cginfo_t));
i->type = CG_SET;
i->no = wNumCG;
@@ -240,8 +229,6 @@ int scg_create_text(int wNumCG, int wSize, int wR, int wG, int wB, int wText) {
// 数字文字列のCGを作成
int scg_create_textnum(int wNumCG, int wSize, int wR, int wG, int wB, int wFigs, int wZeroPadding, int wValue) {
cginfo_t *i;
agsurface_t *glyph;
FONT *font;
char s[256], ss[256];
spcg_assert_no(wNumCG);
@@ -254,11 +241,10 @@ int scg_create_textnum(int wNumCG, int wSize, int wR, int wG, int wB, int wFigs,
sprintf(ss, sss, wFigs);
}
sprintf(s, ss, wValue);
font = nact->ags.font;
font->sel_font(FONT_GOTHIC, wSize);
glyph = font->get_glyph(s);
ags_setFont(FONT_GOTHIC, wSize);
agsurface_t *glyph = ags_drawStringToSurface(s);
i = malloc(sizeof(cginfo_t));
i->type = CG_SET;
i->no = wNumCG;
+5 -5
View File
@@ -43,7 +43,7 @@
#define LOGMSG_LINES 6
static const char *logmsg[LOGMSG_LINES] = {
static const char *logmsg_utf8[LOGMSG_LINES] = {
"\n",
"※バックログ操作方法※",
"[ESC]またはマウス右クリックでゲームに戻る",
@@ -110,15 +110,15 @@ static void draw_log() {
int sblog_start(void) {
static char *logmsg_sjis[6];
if (!logmsg_sjis[0]) {
static char *logmsg[LOGMSG_LINES];
if (!logmsg[0]) {
for (int i = 0; i < LOGMSG_LINES; i++)
logmsg_sjis[i] = utf2sjis(logmsg[i]);
logmsg[i] = fromUTF8(logmsg_utf8[i]);
}
// 説明文章を追加
for (int i = 0; i < LOGMSG_LINES; i++)
sact.log = list_append(sact.log, logmsg_sjis[i]);
sact.log = list_append(sact.log, logmsg[i]);
back = sf_dup(sf0);
chr = sf_create_surface(sf0->width, sf0->height, 8);
-13
View File
@@ -38,7 +38,6 @@
#include "ngraph.h"
#include "drawtext.h"
#include "sactlog.h"
#include "utfsjis.h"
// メッセージキー待ちの時、表示するアニメーションに関する情報
struct markinfo {
@@ -193,12 +192,6 @@ void smsg_add(const char *msg) {
if (msg[0] == '\0') return;
if (0) {
char *b = sjis2utf(msg);
fprintf(stderr, "add msg '%s'\n", b);
free(b);
}
len = MSGBUFMAX - (int)strlen(sact.msgbuf);
if (len < 0) {
WARNING("buf shortage (%d)\n", len);
@@ -304,12 +297,6 @@ void smsg_out(int wNum, int wSize, int wColorR, int wColorG, int wColorB, int wF
}
dt_setfont(wFont, wSize);
if (0) {
char *b = sjis2utf(mbuf);
fprintf(stderr, "msg '%s'\n", b);
free(b);
}
cw = dt_drawtext_col(sp->u.msg.canvas,
sp->u.msg.dspcur.x,
sp->u.msg.dspcur.y + wRSize + wRLineSpace,
+6 -13
View File
@@ -29,7 +29,6 @@
#include "system.h"
#include "nact.h"
#include "ags.h"
#include "font.h"
#include "surface.h"
#include "ngraph.h"
@@ -59,13 +58,10 @@ int dt_setfont(int type, int size) {
* @return: 実際に描画した幅
*/
int dt_drawtext(surface_t *sf, int x, int y, char *buf) {
agsurface_t *glyph;
int sx, sy, sw, sh;
FONT *font = nact->ags.font;
font->sel_font(ftype, fsize);
glyph = font->get_glyph(buf);
ags_setFont(ftype, fsize);
agsurface_t *glyph = ags_drawStringToSurface(buf);
if (glyph == NULL) return 0;
sx = x; sy = y;
@@ -92,13 +88,10 @@ int dt_drawtext(surface_t *sf, int x, int y, char *buf) {
* @return: 実際に描画した幅
*/
int dt_drawtext_col(surface_t *sf, int x, int y, char *buf, int r, int g, int b) {
agsurface_t *glyph;
int sx, sy, sw, sh;
FONT *font = nact->ags.font;
font->sel_font(ftype, fsize);
glyph = font->get_glyph(buf);
ags_setFont(ftype, fsize);
agsurface_t *glyph = ags_drawStringToSurface(buf);
if (glyph == NULL) return 0;
sx = x; sy = y;
+1 -1
View File
@@ -85,7 +85,7 @@ if (EMSCRIPTEN)
"SHELL:-s ALLOW_MEMORY_GROWTH=1"
"SHELL:-s NO_EXIT_RUNTIME=1"
"SHELL:-s EXPORTED_FUNCTIONS=\"['_main','_ags_setAntialiasedStringMode', '_ald_getdata', '_ald_freedata']\""
"SHELL:-s EXTRA_EXPORTED_RUNTIME_METHODS=\"['getValue','getMemory','addRunDependency','removeRunDependency']\"")
"SHELL:-s EXTRA_EXPORTED_RUNTIME_METHODS=\"['getValue','addRunDependency','removeRunDependency']\"")
elseif (ANDROID)
+16 -7
View File
@@ -186,16 +186,16 @@ void ags_setViewArea(int x, int y, int width, int height) {
void ags_setWindowTitle(const char *src) {
#define TITLEHEAD "XSystem35 Version "VERSION":"
BYTE *dst, *d;
BYTE *utf, *d;
dst = sjis2utf(src);
if (NULL == (d = malloc(strlen(dst) + strlen(TITLEHEAD) + 1))) {
utf = toUTF8(src);
if (NULL == (d = malloc(strlen(utf) + strlen(TITLEHEAD) + 1))) {
NOMEMERR();
}
strcpy(d, TITLEHEAD);
strcat(d, dst);
strcat(d, utf);
SetWindowTitle(d);
free(dst);
free(utf);
free(d);
}
@@ -402,11 +402,20 @@ int ags_drawString(int x, int y, const char *src, int col) {
if (!check_param_xy(&x, &y)) return 0;
DspDeviceSync();
w = DrawString(x, y, src, col);
char *utf8 = toUTF8(src);
w = DrawString(x, y, utf8, col);
free(utf8);
return w;
}
agsurface_t *ags_drawStringToSurface(const char *str) {
char *utf8 = toUTF8(str);
agsurface_t *sf = nact->ags.font->get_glyph(utf8);
free(utf8);
return sf;
}
void ags_drawCg8bit(cgdata *cg, int x, int y) {
int sx, sy, w, h;
+13 -2
View File
@@ -29,8 +29,8 @@
#include "portab.h"
#include "cg.h"
#include "graphics.h"
#include "font.h"
struct _FONT;
/* マウスカーソルの種類 */
#define CURSOR_ARROW 1
@@ -136,7 +136,7 @@ struct _ags {
boolean fullscree_is_on; /* if full-screen mode then true */
FONT *font; /* font device */
struct _FONT *font; /* font device */
agsurface_t *dib; /* main surface */
void (*eventcb)(agsevent_t *e); /* deliver event */
};
@@ -224,7 +224,18 @@ extern void ags_whiteOut(int rate, boolean flg);
extern void ags_fader_callback();
/* フォント関連 */
typedef enum {
FONT_X11,
FONT_FT2,
FONT_SDLTTF
} fontdev_t;
enum FontType {
FONT_GOTHIC,
FONT_MINCHO,
};
extern void ags_setFont(int type, int size);
extern agsurface_t *ags_drawStringToSurface(const char *str);
/* カーソル関係 */
extern void ags_setCursorType(int type);
+16 -16
View File
@@ -367,7 +367,7 @@ void commands2F23() {
int y = getCaliValue();
char *vFileName = sys_getString(0);
char *fname_utf8 = sjis2utf(vFileName);
char *fname_utf8 = toUTF8(vFileName);
sysVar[0] = cg_load_with_filename(fname_utf8, x, y);
free(fname_utf8);
@@ -380,7 +380,7 @@ void commands2F24() {
int *var = NULL, _var = 0;
int num = 0;
char *fname_utf8 = sjis2utf(file_name);
char *fname_utf8 = toUTF8(file_name);
switch(type) {
case 0:
var = getCaliVariable();
@@ -412,8 +412,8 @@ void commands2F26() {
char *title = sys_getString(0);
char *t1, *t2, *t3;
t1 = sjis2utf(title);
t2 = sjis2utf(v_str(dst_no -1));
t1 = toUTF8(title);
t2 = toUTF8(v_str(dst_no -1));
mi_param.title = t1;
mi_param.oldstring = t2;
@@ -426,10 +426,10 @@ void commands2F26() {
return;
}
t3 = utf2sjis(mi_param.newstring);
t3 = fromUTF8(mi_param.newstring);
/* 全角文字以外は不可 */
if (!sjis_has_hankaku(t3)) {
if (nact->encoding != SHIFT_JIS || !sjis_has_hankaku(t3)) {
v_strcpy(dst_no -1, t3);
}
free(t1);
@@ -457,7 +457,7 @@ void commands2F28() {
if (nact->game_title_utf8)
free(nact->game_title_utf8);
nact->game_title_utf8 = sjis2utf(title);
nact->game_title_utf8 = toUTF8(title);
ags_setWindowTitle(title);
@@ -478,7 +478,7 @@ void commands2F29() {
if (ni_param.title != NULL) {
free(ni_param.title);
}
t = sjis2utf(title);
t = toUTF8(title);
ni_param.title = t;
DEBUG_COMMAND("NT(new) %s:\n", title);
@@ -489,7 +489,7 @@ void commands2F2A() {
char *file_name = sys_getString(0);
int *var, _var = 0, cnt;
char *fname_utf8 = sjis2utf(file_name);
char *fname_utf8 = toUTF8(file_name);
switch(type) {
case 0:
var = getCaliVariable();
@@ -924,8 +924,8 @@ void commands2F57() {
char *t1, *t2, *t3;
INPUTSTRING_PARAM p;
t1 = sjis2utf(sTitle);
t2 = sjis2utf(v_str(eStrVar -1));
t1 = toUTF8(sTitle);
t2 = toUTF8(v_str(eStrVar -1));
p.title = t1;
p.oldstring = t2;
p.max = eLength;
@@ -934,10 +934,10 @@ void commands2F57() {
if (p.newstring == NULL) {
*vResult = 65535;
} else {
t3 = utf2sjis(p.newstring);
if (!sjis_has_hankaku(t3)) {
t3 = fromUTF8(p.newstring);
if (nact->encoding != SHIFT_JIS || !sjis_has_hankaku(t3)) {
v_strcpy(eStrVar -1, t3);
*vResult = sjis_count_char(t3);
*vResult = v_strlen(eStrVar -1);
} else {
*vResult = 65535;
}
@@ -971,7 +971,7 @@ void commands2F5A() {
char *sText = sys_getString(0);
char *t1;
t1 = sjis2utf(sText);
t1 = toUTF8(sText);
menu_msgbox_open(t1);
free(t1);
@@ -982,7 +982,7 @@ void commands2F5B() {
int eNum = getCaliValue();
char *t1;
t1 = sjis2utf(v_str(eNum) - 1);
t1 = toUTF8(v_str(eNum) - 1);
menu_msgbox_open(t1);
free(t1);
+2
View File
@@ -1098,6 +1098,8 @@ void check_command(int c0) {
undeferr();
}
break;
case 'U':
commandZU(); break;
case 'Z':
switch(sl_getc()) {
case 0:
+1
View File
@@ -304,6 +304,7 @@ extern void commandZI();
extern void commandZA();
extern void commandZK();
extern void commandZR();
extern void commandZU();
/* define in cmd2F.c */
extern void commands2F00();
+5 -1
View File
@@ -22,9 +22,11 @@
/* $Id: cmdh.c,v 1.5 2000/09/10 10:39:48 chikama Exp $ */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "portab.h"
#include "xsystem35.h"
#include "utfsjis.h"
#include "hankaku.h"
void commandH() {
@@ -32,7 +34,9 @@ void commandH() {
int num = getCaliValue();
char buf[512];
sys_addMsg(format_number_zenkaku(num, fig, buf));
char *s = fromSJIS(format_number_zenkaku(num, fig, buf));
sys_addMsg(s);
free(s);
DEBUG_COMMAND("H %d,%d:\n",fig,num);
}
+2 -2
View File
@@ -112,7 +112,7 @@ void commandLE() {
int *var, _var = 0;
int num;
char *fname_utf8 = sjis2utf(filename);
char *fname_utf8 = toUTF8(filename);
switch(type) {
case 0: /* T2 */
var = getCaliVariable();
@@ -246,7 +246,7 @@ void commandLC() {
int y = getCaliValue();
char *filename = sys_getString(':');
char *fname_utf8 = sjis2utf(filename);
char *fname_utf8 = toUTF8(filename);
sysVar[0] = cg_load_with_filename(fname_utf8, x, y);
free(fname_utf8);
+20 -15
View File
@@ -62,34 +62,37 @@ void commandMP() {
/* 指定の文字列を指定文字数だけ表示する(Xコマンドの桁数指定) */
int num1 = getCaliValue();
int num2 = getCaliValue();
const char bstr[3] = "\x81\x40"; // full-width whitespace
const char *fullwidth_blank[CHARACTER_ENCODING_MAX + 1] = {
[SHIFT_JIS] = "\x81\x40",
[UTF8] = " ",
};
const char *src = v_str(num1 - 1);
int chars = num2;
char *str;
/* Patched English executable appends num2 spaces instead of truncating */
if (have_eng_mp_patch) {
str = calloc(strlen(src) + num2 * 2 + 1, 1);
str = calloc(strlen(src) + num2 * strlen(fullwidth_blank[nact->encoding]) + 1, 1);
if (NULL == str) {
NOMEMERR();
}
strcpy(str, src);
}
else {
str = calloc(num2 * 2 + 1, 1);
str = calloc(num2 * MAX_BYTES_PAR_CHAR(nact->encoding) + 1, 1);
if (NULL == str) {
NOMEMERR();
}
const char *p = src;
while (*p && chars > 0) {
p += CHECKSJIS1BYTE(*p) ? 2 : 1;
p = advance_char(p, nact->encoding);
chars--;
}
strncpy(str, src, p - src);
}
while (chars-- > 0) {
strcat(str, bstr);
strcat(str, fullwidth_blank[nact->encoding]);
}
sys_addMsg(str);
@@ -105,8 +108,8 @@ void commandMI() { /* T2 */
char *title = sys_getString(':');
char *t1, *t2, *t3;
t1 = sjis2utf(title);
t2 = sjis2utf(v_str(dst_no -1));
t1 = toUTF8(title);
t2 = toUTF8(v_str(dst_no -1));
mi_param.title = t1;
mi_param.oldstring = t2;
@@ -119,10 +122,10 @@ void commandMI() { /* T2 */
return;
}
t3 = utf2sjis(mi_param.newstring);
t3 = fromUTF8(mi_param.newstring);
/* 全角文字以外は不可 */
if (!sjis_has_hankaku(t3)) {
if (nact->encoding != SHIFT_JIS ||!sjis_has_hankaku(t3)) {
v_strcpy(dst_no -1, t3);
}
free(t1);
@@ -163,7 +166,7 @@ void commandMT() {
if (nact->game_title_utf8)
free(nact->game_title_utf8);
nact->game_title_utf8 = sjis2utf(str);
nact->game_title_utf8 = toUTF8(str);
ags_setWindowTitle(str);
/* 闘神都市II 対策 */
@@ -197,7 +200,9 @@ void commandMH() {
int num2 = getCaliValue();
char buf[512];
v_strcpy(num1 - 1, format_number_zenkaku(num2, fig, buf));
char *s = fromSJIS(format_number_zenkaku(num2, fig, buf));
v_strcpy(num1 - 1, s);
free(s);
DEBUG_COMMAND("MH %d,%d,%d:\n",num1,fig,num2);
}
@@ -215,7 +220,7 @@ void commandML() {
int *var = getCaliVariable();
int str_no = getCaliValue();
*var = sjis_count_char(v_str(str_no -1));
*var = v_strlen(str_no -1);
DEBUG_COMMAND("ML %p,%d:\n",var, str_no);
}
@@ -338,7 +343,7 @@ void commandMJ() {
INPUTSTRING_PARAM mj_param;
char *t1, *t2;
t1 = sjis2utf(v_str(num -1));
t1 = toUTF8(v_str(num -1));
mj_param.max = max_len;
mj_param.x = x;
mj_param.y = y;
@@ -349,8 +354,8 @@ void commandMJ() {
menu_inputstring2(&mj_param);
if (mj_param.newstring == NULL) return;
t2 = utf2sjis(mj_param.newstring);
if (!sjis_has_hankaku(t2)) {
t2 = fromUTF8(mj_param.newstring);
if (nact->encoding != SHIFT_JIS || !sjis_has_hankaku(t2)) {
v_strcpy(num -1, t2);
}
free(t1);
+2 -6
View File
@@ -375,13 +375,9 @@ void commandNI() { /* From Panyo */
void commandNT() { /* From Panyo */
/* NIコマンドで表示するタイトルを設定する。*/
char *str = sys_getString(':');
char *t;
if (ni_param.title != NULL) {
free(ni_param.title);
}
t = sjis2utf(str);
ni_param.title = t;
free(ni_param.title);
ni_param.title = toUTF8(str);
DEBUG_COMMAND("NT %p:\n", str);
}
+1 -1
View File
@@ -87,7 +87,7 @@ void commandQE() {
char *filename = sys_getString(':');
int *var, _var = 0, cnt;
char *fname_utf8 = sjis2utf(filename);
char *fname_utf8 = toUTF8(filename);
switch(type) {
case 0:
var = getCaliVariable();
+11
View File
@@ -35,6 +35,7 @@
#include "message.h"
#include "input.h"
#include "nact.h"
#include "font.h"
void commandZC() {
/* システムの使用環境を変更する */
@@ -524,3 +525,13 @@ void commandZR() {
DEBUG_COMMAND("ZR %d,%d:\n", num, *var);
}
void commandZU() {
/* xsystem35 extension: sets unicode mode */
int sw = getCaliValue();
if (sw <= CHARACTER_ENCODING_MAX)
sys_setCharacterEncoding(sw);
DEBUG_COMMAND("ZU %d:\n",sw);
}
+2 -13
View File
@@ -30,10 +30,6 @@
/* font の種類 */
#define FONTTYPEMAX 2
/* fontの名前 */
#define FONT_GOTHIC (0)
#define FONT_MINCHO (1)
struct agsurface;
struct _FONT {
@@ -45,9 +41,9 @@ struct _FONT {
void (*sel_font)(int type, int size);
struct agsurface *(*get_glyph)(const unsigned char *str);
struct agsurface *(*get_glyph)(const char *str_utf8);
int (*draw_glyph)(int x, int y, const unsigned char *str, int col);
int (*draw_glyph)(int x, int y, const char *str_utf8, int col);
boolean (*self_drawable)();
};
@@ -71,13 +67,6 @@ extern FONT *font_x11_new();
/* デフォルトのフォント名 */
#define FONT_DEFAULTNAME_X "-*-*-medium-r-normal--%d-*-*-*-c-*-jisx0208.1983-0,-*-*-medium-r-normal--%d-*-*-*-c-*-jisx0201.1976-0,*"
// Font devices
typedef enum {
FONT_X11,
FONT_FT2,
FONT_SDLTTF
} fontdev_t;
#ifdef __EMSCRIPTEN__
int load_mincho_font(void);
#endif
+5 -19
View File
@@ -34,6 +34,7 @@
#include "system.h"
#include "font.h"
#include "ags.h"
#include "utfsjis.h"
extern const unsigned short *s2u[];
@@ -59,20 +60,6 @@ static FONT *this;
static void pixmap2comimg(BYTE *src, int x, int y, int w, int h, int src_bpl);
static void pixmapmono2comimg(BYTE *src, int x, int y, int w, int h, int src_bpl);
static int toUnicode(const unsigned char **msg) {
int code;
if (**msg >= 0xa0 && **msg <= 0xdf) {
code = 0xff60 + (**msg) - 0xa0; (*msg)++;
} else if (**msg&0x80) {
code = s2u[**msg - 0x80][*(*msg+1) - 0x40];
(*msg) += 2;
} else {
code = **msg; (*msg)++;
}
return code;
}
static boolean select_charmap(FT_Face f, int type) {
int i;
@@ -197,21 +184,20 @@ static void clear_canvas(void) {
memset(img_glyph.pixel, 0, GLYPH_PIXMAP_WIDTH * GLYPH_PIXMAP_HEIGHT);
}
static agsurface_t *font_ttf_get_glyph(const unsigned char *_msg) {
static agsurface_t *font_ttf_get_glyph(const char *str_utf8) {
FT_GlyphSlot slot;
FT_UShort code;
FT_Error err;
FT_Pixel_Mode pixelmode;
FT_Int loadflag;
int x = 0;
const unsigned char *msg = _msg;
if (fontset == NULL) return &img_glyph;
clear_canvas();
while (*msg) {
code = toUnicode(&msg);
while (*str_utf8) {
code = utf8_next_codepoint(&str_utf8);
if (this->antialiase_on) {
loadflag = FT_LOAD_RENDER;
@@ -266,7 +252,7 @@ static agsurface_t *font_ttf_get_glyph(const unsigned char *_msg) {
return &img_glyph;
}
static int font_ttf_draw_glyph(int x, int y, const unsigned char *str, int col) {
static int font_ttf_draw_glyph(int x, int y, const char *str_utf8, int col) {
return 0;
}
+8 -17
View File
@@ -9,7 +9,6 @@
#include "system.h"
#include "font.h"
#include "sdl_private.h"
#include "utfsjis.h"
typedef struct {
int size;
@@ -69,7 +68,7 @@ static void font_sdlttf_sel_font(int type, int size) {
}
}
static agsurface_t *font_sdlttf_get_glyph(const unsigned char *msg) {
static agsurface_t *font_sdlttf_get_glyph(const char *str_utf8) {
static SDL_Surface *fs;
static agsurface_t result;
@@ -80,15 +79,12 @@ static agsurface_t *font_sdlttf_get_glyph(const unsigned char *msg) {
fs = NULL;
}
BYTE* conv = sjis2utf(msg);
SDL_Color color = {255, 255, 255, 0};
if (this->antialiase_on) {
fs = TTF_RenderUTF8_Shaded(fontset->id, conv, color, color);
fs = TTF_RenderUTF8_Shaded(fontset->id, str_utf8, color, color);
} else {
fs = TTF_RenderUTF8_Solid(fontset->id, conv, color);
fs = TTF_RenderUTF8_Solid(fontset->id, str_utf8, color);
}
free(conv);
if (!fs) {
WARNING("Text rendering failed: %s\n", TTF_GetError());
return NULL;
@@ -142,30 +138,27 @@ static void sdl_drawAntiAlias_8bpp(int dstx, int dsty, SDL_Surface *src, unsigne
SDL_UnlockSurface(sdl_dib);
}
static int font_sdlttf_draw_glyph(int x, int y, const unsigned char *str, int cl) {
static int font_sdlttf_draw_glyph(int x, int y, const char *str_utf8, int cl) {
SDL_Surface *fs;
SDL_Rect r_src, r_dst;
int w, h, maxy;
BYTE *conv;
if (!*str)
if (!*str_utf8)
return 0;
if (!fontset)
return 0;
conv = sjis2utf(str);
if (this->antialiase_on) {
fs = TTF_RenderUTF8_Blended(fontset->id, conv, sdl_col[cl]);
fs = TTF_RenderUTF8_Blended(fontset->id, str_utf8, sdl_col[cl]);
} else {
fs = TTF_RenderUTF8_Solid(fontset->id, conv, sdl_col[cl]);
fs = TTF_RenderUTF8_Solid(fontset->id, str_utf8, sdl_col[cl]);
}
if (!fs) {
WARNING("Text rendering failed: %s\n", TTF_GetError());
free(conv);
return 0;
}
TTF_SizeUTF8(fontset->id, conv, &w, &h);
TTF_SizeUTF8(fontset->id, str_utf8, &w, &h);
y = max(0, y - (TTF_FontAscent(fontset->id) - fontset->size * 0.9));
if (sdl_dib->format->BitsPerPixel == 8 && this->antialiase_on) {
@@ -177,8 +170,6 @@ static int font_sdlttf_draw_glyph(int x, int y, const unsigned char *str, int cl
}
SDL_FreeSurface(fs);
free(conv);
return w;
}
+9 -29
View File
@@ -36,7 +36,6 @@
#include "ags.h"
#include "xcore.h"
#include "xcore_private.h"
#include "utfsjis.h"
#include "antialiase.h"
/* fontset の為の情報 */
@@ -151,22 +150,13 @@ static agsurface_t *get_drawn_glyph(const char *str, int w) {
return dst;
}
static agsurface_t *font_x11_get_glyph(const unsigned char *str) {
agsurface_t *dst;
int w;
BYTE *conv;
static agsurface_t *font_x11_get_glyph(const char *str_utf8) {
int w = XmbTextEscapement(fontset, str_utf8, strlen(str_utf8));
/* convert string code from sjis to utf-8 */
conv = sjis2utf(str);
w = XmbTextEscapement(fontset, conv, strlen(conv));
if (w == 0) {
free(conv);
if (w == 0)
return NULL;
}
dst = get_drawn_glyph(conv, w);
agsurface_t *dst = get_drawn_glyph(str_utf8, w);
image_get_glyph(dst, &img_glyph);
if (this->antialiase_on) {
@@ -178,27 +168,17 @@ static agsurface_t *font_x11_get_glyph(const unsigned char *str) {
free(dst->pixel);
free(dst);
free(conv);
return &img_glyph;
}
static int font_x11_draw_glyph(int x, int y, const unsigned char *str, int col) {
int w;
BYTE *conv;
/* convert string code from sjis to utf-8 */
conv = sjis2utf(str);
w = XmbTextEscapement(fontset, conv, strlen(conv));
if (w == 0) {
free(conv);
static int font_x11_draw_glyph(int x, int y, const char *str_utf8, int col) {
int w = XmbTextEscapement(fontset, str_utf8, strlen(str_utf8));
if (w == 0)
return 0;
}
if (!x11_dibinfo->shared) {
/* 一度 Pixmap に書いてからイメージを取得してDIBへ */
agsurface_t *dst = get_drawn_glyph(conv, w);
agsurface_t *dst = get_drawn_glyph(str_utf8, w);
if (DIB_DEPTH == dib_depth_candidate) {
image_getGlyphImage(DIB, dst, x, y, PAL2PIC(col));
@@ -208,7 +188,7 @@ static int font_x11_draw_glyph(int x, int y, const unsigned char *str, int col)
free(dst);
} else {
Xcore_setForeground(col);
XmbDrawString(x11_display, x11_pixmap, fontset, x11_gc_pix, x, y + font_ascent, conv, strlen(conv));
XmbDrawString(x11_display, x11_pixmap, fontset, x11_gc_pix, x, y + font_ascent, str_utf8, strlen(str_utf8));
x11_needSync = TRUE;
}
return w;
+196 -2
View File
@@ -140,7 +140,7 @@ static const char zenkaku_digits[][3] = {
0x81,0x40,0x00, /* space */
};
BYTE *zen2han(const BYTE *src) {
static BYTE *zen2han_sjis(const BYTE *src) {
BYTE c0, c1;
char *dst, *_dst;
@@ -173,7 +173,201 @@ BYTE *zen2han(const BYTE *src) {
return _dst;
}
BYTE *han2zen(const BYTE *src) {
static char *zen2han_utf8(const char *src) {
char *dst, *_dst;
dst = _dst = malloc(strlen(src) + 1);
if (dst == NULL) {
fprintf(stderr, "zen2han(): Out of Memory (size %zu)", strlen(src) + 1);
return NULL;
}
const char *p = src;
while (*p) {
const char *prev = p;
switch (utf8_next_codepoint(&p)) {
case L'': *dst++ = '\''; break;
case L'': *dst++ = '"'; break;
case L' ': *dst++ = ' '; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, "ソ"); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': strcpy(dst, ""); dst += 3; break;
case L'': *dst++ = '!'; break;
case L'': *dst++ = '#'; break;
case L'': *dst++ = '$'; break;
case L'': *dst++ = '%'; break;
case L'': *dst++ = '&'; break;
case L'': *dst++ = '('; break;
case L'': *dst++ = ')'; break;
case L'': *dst++ = '*'; break;
case L'': *dst++ = '+'; break;
case L'': *dst++ = ','; break;
case L'': *dst++ = '-'; break;
case L'': *dst++ = '.'; break;
case L'': *dst++ = '/'; break;
case L'': *dst++ = '0'; break;
case L'': *dst++ = '1'; break;
case L'': *dst++ = '2'; break;
case L'': *dst++ = '3'; break;
case L'': *dst++ = '4'; break;
case L'': *dst++ = '5'; break;
case L'': *dst++ = '6'; break;
case L'': *dst++ = '7'; break;
case L'': *dst++ = '8'; break;
case L'': *dst++ = '9'; break;
case L'': *dst++ = ':'; break;
case L'': *dst++ = ';'; break;
case L'': *dst++ = '<'; break;
case L'': *dst++ = '='; break;
case L'': *dst++ = '>'; break;
case L'': *dst++ = '?'; break;
case L'': *dst++ = '@'; break;
case L'': *dst++ = 'A'; break;
case L'': *dst++ = 'B'; break;
case L'': *dst++ = 'C'; break;
case L'': *dst++ = 'D'; break;
case L'': *dst++ = 'E'; break;
case L'': *dst++ = 'F'; break;
case L'': *dst++ = 'G'; break;
case L'': *dst++ = 'H'; break;
case L'': *dst++ = 'I'; break;
case L'': *dst++ = 'J'; break;
case L'': *dst++ = 'K'; break;
case L'': *dst++ = 'L'; break;
case L'': *dst++ = 'M'; break;
case L'': *dst++ = 'N'; break;
case L'': *dst++ = 'O'; break;
case L'': *dst++ = 'P'; break;
case L'': *dst++ = 'Q'; break;
case L'': *dst++ = 'R'; break;
case L'': *dst++ = 'S'; break;
case L'': *dst++ = 'T'; break;
case L'': *dst++ = 'U'; break;
case L'': *dst++ = 'V'; break;
case L'': *dst++ = 'W'; break;
case L'': *dst++ = 'X'; break;
case L'': *dst++ = 'Y'; break;
case L'': *dst++ = 'Z'; break;
case L'': *dst++ = '['; break;
case L'': *dst++ = ']'; break;
case L'': *dst++ = '^'; break;
case L'_': *dst++ = '_'; break;
case L'': *dst++ = '`'; break;
case L'': *dst++ = 'a'; break;
case L'': *dst++ = 'b'; break;
case L'': *dst++ = 'c'; break;
case L'': *dst++ = 'd'; break;
case L'': *dst++ = 'e'; break;
case L'': *dst++ = 'f'; break;
case L'': *dst++ = 'g'; break;
case L'': *dst++ = 'h'; break;
case L'': *dst++ = 'i'; break;
case L'': *dst++ = 'j'; break;
case L'': *dst++ = 'k'; break;
case L'': *dst++ = 'l'; break;
case L'': *dst++ = 'm'; break;
case L'': *dst++ = 'n'; break;
case L'': *dst++ = 'o'; break;
case L'': *dst++ = 'p'; break;
case L'': *dst++ = 'q'; break;
case L'': *dst++ = 'r'; break;
case L'': *dst++ = 's'; break;
case L'': *dst++ = 't'; break;
case L'': *dst++ = 'u'; break;
case L'': *dst++ = 'v'; break;
case L'': *dst++ = 'w'; break;
case L'': *dst++ = 'x'; break;
case L'': *dst++ = 'y'; break;
case L'': *dst++ = 'z'; break;
case L'': *dst++ = '{'; break;
case L'': *dst++ = '|'; break;
case L'': *dst++ = '}'; break;
case L'': *dst++ = '~'; break;
case L'': *dst++ = '\\'; break;
default:
while (prev < p)
*dst++ = *prev++;
break;
}
}
*dst = 0;
return _dst;
}
BYTE *zen2han(const BYTE *src, CharacterEncoding enc) {
switch (enc) {
case SHIFT_JIS:
return zen2han_sjis(src);
case UTF8:
return zen2han_utf8(src);
default:
return (BYTE *)src;
}
}
BYTE *han2zen(const BYTE *src, CharacterEncoding enc) {
if (enc != SHIFT_JIS)
return (BYTE *)src; // Not implemented
BYTE c0;
BYTE *dst, *_dst;
dst = _dst = malloc(strlen(src) * 2 + 1);
+3 -2
View File
@@ -24,9 +24,10 @@
#define __HANKAKU_H__
#include "portab.h"
#include "utfsjis.h"
extern BYTE *zen2han(const BYTE *src);
extern BYTE *han2zen(const BYTE *src);
extern BYTE *zen2han(const BYTE *src, CharacterEncoding enc);
extern BYTE *han2zen(const BYTE *src, CharacterEncoding enc);
extern char *format_number(int n, int width, char *buf);
extern char *format_number_zenkaku(int n, int width, char *buf);
+4 -2
View File
@@ -52,9 +52,11 @@ static void zen2han_test(void) {
"ベペボポヮヰヱヴヵヶΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩα"
"βγδεζηθικλμνξοπρστυφχψω";
for (const Zen2hanTestCase *tc = testcases; tc->zen; tc++) {
ASSERT_STRCMP(sjis2utf(zen2han(utf2sjis(tc->zen))), tc->han);
ASSERT_STRCMP(sjis2utf(zen2han(utf2sjis(tc->zen), SHIFT_JIS)), tc->han);
ASSERT_STRCMP(zen2han(tc->zen, UTF8), tc->han);
}
ASSERT_STRCMP(sjis2utf(zen2han(utf2sjis(unconvertable))), unconvertable);
ASSERT_STRCMP(sjis2utf(zen2han(utf2sjis(unconvertable), SHIFT_JIS)), unconvertable);
ASSERT_STRCMP(zen2han(unconvertable, UTF8), unconvertable);
}
static void format_number_test(void) {
+5 -2
View File
@@ -326,11 +326,14 @@ void msg_getMessageLocation(MyPoint *loc) {
void msg_hitAnyKey() {
int w;
static BYTE hak[] = {0x81, 0xa5, 0x00}; /* ▼ */
const char *prompt[CHARACTER_ENCODING_MAX + 1] = {
[SHIFT_JIS] = "\x81\xa5",
[UTF8] = "",
};
w = ags_drawString(msg.win->x + msg.win->width - msg.MsgFontSize,
msg.win->y + msg.win->height - msg.MsgFontSize,
hak, msg.HitAnyKeyMsgColor);
prompt[nact->encoding], msg.HitAnyKeyMsgColor);
ags_updateArea(msg.win->x + msg.win->width - msg.MsgFontSize,
msg.win->y + msg.win->height - msg.MsgFontSize,
w, msg.MsgFontSize);
+11 -5
View File
@@ -70,6 +70,10 @@ void sys_setHankakuMode(int mode) {
msg_msgHankakuMode = mode;
}
void sys_setCharacterEncoding(CharacterEncoding encoding) {
nact->encoding = encoding;
}
/* 文字列の取り出し */
char *sys_getString(char term) {
int c0;
@@ -103,9 +107,9 @@ void sys_addMsg(const char *str) {
switch(msg_msgHankakuMode) {
case 0:
msg = han2zen(str); break;
msg = han2zen(str, nact->encoding); break;
case 1:
msg = zen2han(str); break;
msg = zen2han(str, nact->encoding); break;
case 2:
msg = str; break;
default:
@@ -126,7 +130,7 @@ void sys_addMsg(const char *str) {
}
}
if (msg && msg_msgHankakuMode < 2) {
if (msg != str) {
free((char *)msg);
}
}
@@ -136,8 +140,10 @@ static int checkMessage() {
char *index = msgbuf;
int c0 = sl_getc();
while (c0 == 0x20 || c0 > 0x80) {
if (c0 == 0x20) {
while (c0 == 0x20 || c0 >= 0x80) {
if (nact->encoding == UTF8) {
*index++ = (char)c0;
} else if (c0 == 0x20) {
*index++ = (char)c0;
} else if (c0 >= 0xe0) {
*index++ = (char)c0; *index++ = (char)sl_getc();
+8 -1
View File
@@ -27,12 +27,17 @@
#include "portab.h"
#include "graphics.h"
#include "scenario.h"
#include "font.h"
#include "s39ain.h"
#include "gameresource.h"
#include "selection.h"
#include "message.h"
#include "ags.h"
#include "utfsjis.h"
#define toUTF8(s) codeconv(UTF8, nact->encoding, s)
#define toSJIS(s) codeconv(SHIFT_JIS, nact->encoding, s)
#define fromUTF8(s) codeconv(nact->encoding, UTF8, s)
#define fromSJIS(s) codeconv(nact->encoding, SHIFT_JIS, s)
/* コマンド解析時に参照する */
#define sys_getc sl_getc
@@ -47,6 +52,7 @@ extern int *getVariable();
extern char *sys_getString(char term);
extern void sys_addMsg(const char *str);
extern void sys_setHankakuMode(int mode);
extern void sys_setCharacterEncoding(CharacterEncoding encoding);
extern char *sys_getConstString();
// extern boolean sys_nact_engine();
@@ -62,6 +68,7 @@ typedef struct {
boolean is_message_locked; /* pointer 等の event handler を呼び出さない */
boolean popupmenu_opened; /* popup menu が 開いているか */
boolean mmx_is_ok; /* MMX が有効かどうか */
CharacterEncoding encoding;
char *game_title_utf8;
int scenario_version;
+3 -3
View File
@@ -53,7 +53,7 @@ extern void sdl_setPallet(Pallet256 *pal, int src, int cnt);
extern void sdl_drawRectangle(int x, int y, int w, int h, int cl);
extern void sdl_fillRectangle(int x, int y, int w, int h, unsigned long c);
extern void sdl_drawLine(int x1, int y1, int x2, int y2, unsigned long col);
extern int sdl_drawString(int x, int y, const char *msg, unsigned long col);
extern int sdl_drawString(int x, int y, const char *str_utf8, unsigned long col);
extern void sdl_copyArea(int sx,int sy, int w, int h, int dx, int dy);
extern void sdl_drawTT(int x,int y,int w,int h,const char *bitmap,int ww, boolean antialiased);
extern void sdl_copyAreaSP(int sx, int sy, int w, int h, int dx, int dy, int sp);
@@ -78,7 +78,7 @@ extern void sdl_delRegion(void *src);
extern void sdl_maskupdate(int sx, int sy, int w, int h, int dx, int dy, int func, int step);
/* フォント関連 */
extern void sdl_setFontDevice(FONT *f);
extern void sdl_setFontDevice(struct _FONT *f);
/* fader */
extern void sdl_fadeIn(int step);
@@ -123,7 +123,7 @@ extern void sdl_wait_vsync();
#define SetPallet(pal,src,cnt) sdl_setPallet((pal),(src),(cnt))
/* 描画関係 */
#define DrawString(x,y,str,col) sdl_drawString((x),(y),(str),(col))
#define DrawString(x,y,str_utf8,col) sdl_drawString((x),(y),(str_utf8),(col))
#define FillRectangle(x,y,w,h,col) sdl_fillRectangle((x),(y),(w),(h),(col))
#define CopyArea(sx,sy,w,h,dx,dy) sdl_copyArea((sx),(sy),(w),(h),(dx),(dy))
#define CopyAreaSP(sx,sy,w,h,dx,dy,col) sdl_copyAreaSP((sx),(sy),(w),(h),(dx),(dy),(col))
+3 -3
View File
@@ -412,15 +412,15 @@ static void sdl_drawAntiAlias_8bpp(int dstx, int dsty, agsurface_t *src, unsigne
SDL_UnlockSurface(sdl_dib);
}
int sdl_drawString(int x, int y, const char *msg, unsigned long col) {
int sdl_drawString(int x, int y, const char *str_utf8, unsigned long col) {
int w;
sdl_pal_check();
if (sdl_font->self_drawable()) {
w = sdl_font->draw_glyph(x, y, msg, col);
w = sdl_font->draw_glyph(x, y, str_utf8, col);
} else {
agsurface_t *glyph = sdl_font->get_glyph(msg);
agsurface_t *glyph = sdl_font->get_glyph(str_utf8);
SDL_Rect r_src, r_dst;
if (glyph == NULL) return 0;
+3 -2
View File
@@ -29,7 +29,8 @@
#include "portab.h"
#include "ags.h"
#include "font.h"
struct _FONT;
struct sdl_private_data {
SDL_Window *window;
@@ -47,7 +48,7 @@ struct sdl_private_data {
SDL_Rect view;
FONT *font;
struct _FONT *font;
boolean dirty;
+2 -2
View File
@@ -173,8 +173,8 @@ static void makeDIB(int width, int height, int depth) {
image_setdepth(sdl_dibinfo->depth);
}
void sdl_setFontDevice(FONT *f) {
sdl_font = f;
void sdl_setFontDevice(struct _FONT *f) {
sdl_font = f;
}
/* offscreen の設定 */
+50 -10
View File
@@ -33,6 +33,18 @@
#include "utfsjis.h"
#include "s2utbl.h"
char* codeconv(CharacterEncoding tocode,
CharacterEncoding fromcode,
const char *str) {
if (tocode == fromcode)
return strdup(str);
if (tocode == UTF8 && fromcode == SHIFT_JIS)
return (char *)sjis2utf((char *)str);
if (tocode == SHIFT_JIS && fromcode == UTF8)
return (char *)utf2sjis((char *)str);
return NULL;
}
BYTE *sjis2utf(const BYTE *src) {
BYTE* dst = malloc(strlen(src) * 3 + 1);
BYTE* dstp = dst;
@@ -147,15 +159,43 @@ boolean sjis_has_zenkaku(const BYTE *src) {
return FALSE;
}
/* src 中の文字数を数える 全角文字も1文字 */
int sjis_count_char(const BYTE *src) {
int c = 0;
while(*src) {
if (CHECKSJIS1BYTE(*src)) {
src++;
}
c++; src++;
int utf8_next_codepoint(const char **msg) {
int code;
const unsigned char *s = (const unsigned char *)*msg;
if (*s <= 0x7f) {
code = *s++;
} else if (*s <= 0xbf) {
// Invalid UTF-8 sequence
code = '?';
s++;
} else if (*s <= 0xdf) {
code = (s[0] & 0x1f) << 6 | (s[1] & 0x3f);
s += 2;
} else if (*s <= 0xef) {
code = (s[0] & 0xf) << 12 | (s[1] & 0x3f) << 6 | (s[2] & 0x3f);
s += 3;
} else if (*s <= 0xf7) {
code = (s[0] & 0x7) << 18 | (s[1] & 0x3f) << 12 | (s[2] & 0x3f) << 6 | (s[3] & 0x3f);
s += 4;
} else {
code = 0xfffd; // REPLACEMENT CHARACTER
s++;
while (0x80 <= *s && *s <= 0xbf)
s++;
}
return c;
*msg = (const char *)s;
return code;
}
char *advance_char(const char *s, CharacterEncoding e) {
switch (e) {
case SHIFT_JIS:
return (char *)s + ((CHECKSJIS1BYTE(*s) && *(s + 1)) ? 2 : 1);
case UTF8:
while (UTF8_TRAIL_BYTE(*++s))
;
return (char *)s;
}
return NULL;
}
+19 -1
View File
@@ -26,12 +26,30 @@
#include "portab.h"
typedef enum {
SHIFT_JIS,
UTF8,
CHARACTER_ENCODING_MAX = UTF8
} CharacterEncoding;
#define MAX_SJIS_BYTES_PAR_CHAR 2
#define MAX_UTF8_BYTES_PAR_CHAR 4
#define MAX_BYTES_PAR_CHAR(encoding) \
((encoding) == SHIFT_JIS ? MAX_SJIS_BYTES_PAR_CHAR : MAX_UTF8_BYTES_PAR_CHAR)
#define UTF8_TRAIL_BYTE(b) ((signed char)(b) < -0x40)
#define CHECKSJIS1BYTE(b) ( ((b) & 0xe0) == 0x80 || ((b) & 0xe0) == 0xe0 )
extern char* codeconv(CharacterEncoding tocode,
CharacterEncoding fromcode,
const char *str);
extern BYTE* sjis2utf(const BYTE *src);
extern BYTE* utf2sjis(const BYTE *src);
extern boolean sjis_has_hankaku(const BYTE *src);
extern boolean sjis_has_zenkaku(const BYTE *src);
extern int sjis_count_char(const BYTE *src);
extern int utf8_next_codepoint(const char **msg);
extern char *advance_char(const char *s, CharacterEncoding e);
#endif /* __UTFSJIS__ */
+10 -3
View File
@@ -45,7 +45,7 @@ int strvar_len = STRVAR_LEN;
static char *advance(const char *s, int n) {
while (*s && n > 0) {
s += (CHECKSJIS1BYTE(*s) && *(s + 1)) ? 2 : 1;
s = advance_char(s, nact->encoding);
n--;
}
return (char *)s;
@@ -175,7 +175,14 @@ void v_strcat(int no, const char *str) {
/* 文字変数の長さ */
size_t v_strlen(int no) {
return sjis_count_char(v_str(no));
const char *s = v_str(no);
int c = 0;
while (*s) {
s = advance_char(s, nact->encoding);
c++;
}
return c;
}
/* Width of a string (2 for full-width characters, 1 for half-width) */
@@ -207,7 +214,7 @@ int v_strstr(int no, int start, const char *str) {
return -1;
int n = start;
while (p < found) {
p += CHECKSJIS1BYTE(*p) ? 2 : 1;
p = advance_char(p, nact->encoding);
n++;
}
return n;
+3 -4
View File
@@ -29,7 +29,6 @@
#include "portab.h"
#include "image.h"
#include "xcore_image.h"
#include "font.h"
#include "cursor.h"
#include "ags.h"
@@ -57,7 +56,7 @@ extern void Xcore_setForeground(unsigned long col);
extern void Xcore_drawRectangle(int x, int y, int w, int h, unsigned long col);
extern void Xcore_fillRectangle(int x, int y, int w, int h, unsigned long col);
extern void Xcore_drawLine(int x0, int y0, int x1, int y1, unsigned long col);
extern int Xcore_drawString(int x, int y, const char *msg, unsigned long col);
extern int Xcore_drawString(int x, int y, const char *str_utf8, unsigned long col);
extern void Xcore_copyArea(int sx, int sy, int w, int h, int dx, int dy);
// extern void Xcore_drawTT(int x, int y, int w, int h, const char *bitmap, int ww, boolean antialiased);
extern int Xcore_eCopyArea(int sx, int sy, int w, int h, int dx, int dy, int t,int opt, boolean flg, int spCol);
@@ -71,7 +70,7 @@ extern void Xcore_maskupdate(int sx, int sy, int w, int h, int dx, int dy, int f
/* フォント関連 */
// extern FONT *Xcore_getFontDevice(void);
extern void Xcore_setFontDevice(FONT *f);
extern void Xcore_setFontDevice(struct _FONT *f);
/* fader */
extern void Xcore_fadeIn(int step);
@@ -116,7 +115,7 @@ extern boolean RawKeyInfo[256];
#define SetForeground(col) Xcore_setForeground((col))
/* 描画関係 */
#define DrawString(x,y,str,col) Xcore_drawString((x),(y),(str),(col))
#define DrawString(x,y,str_utf8,col) Xcore_drawString((x),(y),(str_utf8),(col))
#define FillRectangle(x,y,w,h,col) Xcore_fillRectangle((x),(y),(w),(h),(col))
#define CopyArea(sx,sy,w,h,dx,dy) Xcore_copyArea((sx),(sy),(w),(h),(dx),(dy))
#define CopyAreaSP(sx,sy,w,h,dx,dy,col) image_copyAreaSP(nact->ags.dib, (sx),(sy),(w),(h),(dx),(dy),(col))
+3 -3
View File
@@ -172,14 +172,14 @@ void Xcore_drawLine(int x1, int y1, int x2, int y2, unsigned long col) {
}
}
int Xcore_drawString(int x, int y, const char *msg, unsigned long col) {
int Xcore_drawString(int x, int y, const char *str_utf8, unsigned long col) {
int w;
if (x11_font->self_drawable()) {
w = x11_font->draw_glyph(x, y, msg, col);
w = x11_font->draw_glyph(x, y, str_utf8, col);
x11_needSync = TRUE;
} else {
agsurface_t *glyph = x11_font->get_glyph(msg);
agsurface_t *glyph = x11_font->get_glyph(str_utf8);
if (glyph == NULL) return 0;
+3 -2
View File
@@ -31,10 +31,11 @@
#include <X11/extensions/XShm.h>
#include "portab.h"
#include "font.h"
#include "ags.h"
#include "image.h"
struct _FONT;
/* dib/work image 情報 */
typedef struct {
XImage *ximg; /* XImage/ShmXImage 使用時の XImage */
@@ -63,7 +64,7 @@ struct xcore_private_data {
int dib_depth_candidate; /* DIB depth if required pixmap depth isnt 8 */
FONT *fontinfo; /* font object */
struct _FONT *fontinfo; /* font object */
boolean noSHM; /* dont have X-SHM extension */
+1 -1
View File
@@ -486,7 +486,7 @@ void x11_makeWorkImage(int w, int h) {
alloced = TRUE;
}
void Xcore_setFontDevice(FONT *f) {
void Xcore_setFontDevice(struct _FONT *f) {
x11_font = f;
}
+1
View File
@@ -62,6 +62,7 @@
#include "randMT.h"
#include "counter.h"
#include "ags.h"
#include "font.h"
#include "graphicsdevice.h"
#include "menu.h"
#include "music.h"