diff --git a/basegraph.cpp b/basegraph.cpp index cfdf33e5..842d05cb 100644 --- a/basegraph.cpp +++ b/basegraph.cpp @@ -458,13 +458,14 @@ struct fontdata { #if CAP_SDLTTF TTF_Font* font[max_font_size+1]; #endif + struct basic_textureinfo *finf; ~fontdata(); }; #endif EX map fontdatas; -EX fontdata *cfont; +EX fontdata *cfont, *cfont_chinese; EX fontdata* font_by_name(string fname) { auto& fd = fontdatas[fname]; @@ -475,6 +476,7 @@ EX fontdata* font_by_name(string fname) { #endif for(int i=0; i<=max_glfont_size; i++) fd.glfont[i] = nullptr; for(int i=0; i<=max_font_size; i++) fd.font[i] = nullptr; + fd.finf = nullptr; } return &fd; } @@ -1479,8 +1481,11 @@ EX int SDL_Init1(Uint32 flags) { EX void set_cfont() { int f = font_id; - if(lang() == 8 && among(f, 0, 1, 2)) f = 3; + int fch = f; + if(among(f, 0, 1, 2)) fch = 3; + if(lang() == 8) f = fch; cfont = font_by_name(font_filenames[last_font_id = f]); + cfont_chinese = font_by_name(font_filenames[fch]); } EX void init_font() { diff --git a/config.cpp b/config.cpp index afad245a..24e37174 100644 --- a/config.cpp +++ b/config.cpp @@ -1343,6 +1343,7 @@ EX void initConfig() { param_i(vid.monmode, "monster display mode", DEFAULT_MONMODE); param_i(vid.wallmode, "wall display mode", DEFAULT_WALLMODE); + param_b(zh_ascii, "chinese_ascii", false)->editable("Chinese ASCII", 'Z'); param_i(vid.highlightmode, "highlightmode"); param_b(vid.always3, "3D always", false)->switcher = geom3::switch_fpp; @@ -2513,6 +2514,7 @@ EX void configureInterface() { add_edit(display_yasc_codes); add_edit(vid.orbmode); + add_edit(zh_ascii); dialog::addSelItem(XLAT("draw crosshair"), crosshair_size > 0 ? fts(crosshair_size) : ONOFF(false), 'x'); dialog::add_action([] () { diff --git a/drawing.cpp b/drawing.cpp index f7a19bcf..5772aa30 100644 --- a/drawing.cpp +++ b/drawing.cpp @@ -125,6 +125,8 @@ struct dqi_string : drawqueueitem { int frame; /** alignment (0-8-16) */ int align; + /** current font */ + fontdata *font; void draw() override; color_t outline_group() override { return 1; } }; @@ -2246,6 +2248,7 @@ void dqi_line::draw() { } void dqi_string::draw() { + dynamicval df(cfont, font); #if CAP_SVG if(svg::in) { svg::text(x, y, size, str, frame, color, align); @@ -2284,6 +2287,13 @@ EX void sortquickqueue() { else i++; } +EX void clear_curvedata() { + if(keep_curvedata) return; + curvedata.clear(); + for(auto& d: fontdatas) if(d.second.finf) d.second.finf->tvertices.clear(); + curvestart = 0; + } + EX void quickqueue() { current_display->next_shader_flags = 0; spherespecial = 0; @@ -2291,11 +2301,7 @@ EX void quickqueue() { int siz = isize(ptds); for(int i=0; idraw(); ptds.clear(); - if(!keep_curvedata) { - curvedata.clear(); - finf.tvertices.clear(); - curvestart = 0; - } + clear_curvedata(); } /* todo */ @@ -2713,11 +2719,7 @@ EX void drawqueue() { } #endif - if(!keep_curvedata) { - curvedata.clear(); - finf.tvertices.clear(); - curvestart = 0; - } + clear_curvedata(); #if CAP_GL GLERR("drawqueue"); @@ -2828,6 +2830,7 @@ EX void queuestr(int x, int y, int shift, int size, string str, color_t col, int ptd.size = size; ptd.color = darkened(col); ptd.frame = frame ? ((poly_outline & ~ 255)+frame) : 0; + ptd.font = cfont; } EX void queuecircle(int x, int y, int size, color_t color, PPR prio IS(PPR::CIRCLE), color_t fillcolor IS(0)) { @@ -2866,8 +2869,6 @@ EX void queuestr(const shiftpoint& h, int size, const string& chr, color_t col, queuestr(xc, yc, sc, size, chr, col, frame); } -EX basic_textureinfo finf; - #if CAP_GL #if HDR using pointfunction = function; @@ -2879,6 +2880,9 @@ EX hyperpoint default_pointfunction(ld x, ld y) { #if !CAP_EXTFONT EX void write_in_space(const shiftmatrix& V, int fsize, double size, const string& s, color_t col, int frame IS(0), int align IS(8), PPR prio IS(PPR::TEXT), pointfunction pf IS(default_pointfunction)) { + if(!cfont->finf) cfont->finf = new basic_textureinfo; + auto& finf = *cfont->finf; + init_glfont(fsize); glfont_t& f(*(cfont->glfont[fsize])); finf.texture_id = f.texture; diff --git a/graph.cpp b/graph.cpp index a53b8ddf..0def196a 100644 --- a/graph.cpp +++ b/graph.cpp @@ -26,6 +26,8 @@ EX int detaillevel = 0; EX bool first_cell_to_draw = true; +EX bool zh_ascii = false; + EX bool in_perspective() { return models::is_perspective(pconf.model); } @@ -852,16 +854,35 @@ EX color_t orb_inner_color(eItem it) { return iinf[it].color; } -EX void draw_ascii(const shiftmatrix& V, char glyph, color_t col, ld size) { - string s = s0 + glyph; +EX void draw_ascii(const shiftmatrix& V, const string& s, color_t col, ld size, ld size2) { int id = isize(ptds); if(WDIM == 2 && GDIM == 3) queuestrn(V * lzpush(cgi.FLOOR - cgi.scalefactor * size / 4), size * mapfontscale / 100, s, darkenedby(col, darken), 0); else - queuestrn(V, mapfontscale / 100, s, darkenedby(col, darken), GDIM == 3 ? 0 : 2); + queuestrn(V, size2 * mapfontscale / 100, s, darkenedby(col, darken), GDIM == 3 ? 0 : 2); while(id < isize(ptds)) ptds[id++]->prio = PPR::MONSTER_BODY; } +EX void draw_ascii(const shiftmatrix& V, char glyph, color_t col, ld size) { + draw_ascii(V, s0 + glyph, col, size, 1); + } + +EX void draw_ascii_or_zh(const shiftmatrix& V, char glyph, const string& name, color_t col, ld size, ld zh_size) { +#if CAP_TRANS + if(zh_ascii) { + auto p = XLAT1_acc(name, 8); + if(p) { + string chinese = p; + chinese.resize(utfsize(chinese[0])); + dynamicval df(cfont, cfont_chinese); + draw_ascii(V, chinese, col, size, zh_size); + return; + } + } +#endif + draw_ascii(V, glyph, col, size); + } + EX void queue_goal_text(shiftpoint P1, ld sizemul, const string& s, color_t color) { #if CAP_VR if(vrhr::enabled) { @@ -904,7 +925,7 @@ EX bool drawItemType(eItem it, cell *c, const shiftmatrix& V, color_t icol, int if(WDIM == 3 && c == centerover && in_perspective() && hdist0(tC0(V)) < cgi.orbsize * 0.25) return false; if(!mmitem || !CAP_SHAPES) { - draw_ascii(V, iinf[it].glyph, icol, 1); + draw_ascii_or_zh(V, iinf[it].glyph, iinf[it].name, icol, 1, 0.5); return true; } @@ -1273,7 +1294,7 @@ EX bool drawItemType(eItem it, cell *c, const shiftmatrix& V, color_t icol, int } else { - draw_ascii(V, xch, icol, 1); + draw_ascii_or_zh(V, xch, iinf[it].name, icol, 1, 0.5); } return true; @@ -1292,7 +1313,7 @@ void humanoid_eyes(const shiftmatrix& V, color_t ecol, color_t hcol = skincolor) EX void drawTerraWarrior(const shiftmatrix& V, int t, int hp, double footphase) { if(!mmmon) { - draw_ascii(V, 'T', gradient(0x202020, 0xFFFFFF, 0, t, 6), 1.5); + draw_ascii_or_zh(V, 'T', minf[moTerraWarrior].name, gradient(0x202020, 0xFFFFFF, 0, t, 6), 1.5, 1); return; } ShadowV(V, cgi.shPBody); @@ -1652,7 +1673,7 @@ EX bool drawMonsterType(eMonster m, cell *where, const shiftmatrix& V1, color_t #endif if(!mmmon || !CAP_SHAPES) { - draw_ascii(V1, xch, asciicol, 1.5); + draw_ascii_or_zh(V1, xch, minf[m].name, asciicol, 1.5, 1); return true; } @@ -2653,7 +2674,7 @@ EX bool drawMonsterType(eMonster m, cell *where, const shiftmatrix& V1, color_t } else - draw_ascii(V1, minf[m].glyph, asciicol, 1.5); + draw_ascii_or_zh(V1, minf[m].glyph, minf[m].name, asciicol, 1.5, 1); return true; #endif diff --git a/hud.cpp b/hud.cpp index d94be59a..a2d4cd7a 100644 --- a/hud.cpp +++ b/hud.cpp @@ -261,7 +261,23 @@ bool displayglyph(int cx, int cy, int buttonsize, char glyph, color_t color, int sortquickqueue(); quickqueue(); } - else if(glyph == '*') + else if(zh_ascii) { + const char* zh; + + if(isMonster) { + eMonster m = eMonster(id - ittypes); + zh = XLAT1_acc(minf[m].name, 8); + } + else { + eItem it = eItem(id); + zh = XLAT1_acc(iinf[it].name, 8); + } + + if(!zh) goto non_zh; + dynamicval df(cfont, cfont_chinese); + displaystr(cx + buttonsize/2, cy, 0, glsize, zh, darkenedby(color, b?0:1), 0); + } + else non_zh: if(glyph == '*') displaychr(cx + buttonsize/2, cy+buttonsize/4, 0, glsize*3/2, glyph, darkenedby(color, b?0:1)); else displaychr(cx + buttonsize/2, cy, 0, glsize, glyph, darkenedby(color, b?0:1)); diff --git a/language.cpp b/language.cpp index b8076114..5fe0712e 100644 --- a/language.cpp +++ b/language.cpp @@ -390,6 +390,21 @@ EX string XLAT(string x, stringpar p1, stringpar p2, stringpar p3, stringpar p4, return x; } +EX const char* XLAT1_to(string x, int language) { +#if CAP_TRANS + const fullnoun *N = findInHashTable(x, all_nouns); + if(N) return N->n[7].nom; +#endif + return nullptr; + } + +EX const char* XLAT1_acc(string x, int language) { +#if CAP_TRANS + const fullnoun *N = findInHashTable(x, all_nouns); + if(N) return N->n[7].acc; +#endif + return nullptr; + } EX string XLATN(string x) { #if CAP_TRANS