mirror of https://github.com/nmlgc/ReC98.git
112 lines
3.2 KiB
C++
112 lines
3.2 KiB
C++
inline uint16_t shiftjis_to_jis(uint16_t shiftjis) {
|
||
return (0x1F21 +
|
||
(((shiftjis >> 8) - (shiftjis >> 15) < 0x9E)
|
||
? ((((shiftjis >> 8) - (shiftjis >> 15) - 0x40) & 0x1FF))
|
||
: ((shiftjis >> 8) - (shiftjis >> 15) + 0x62)
|
||
) + ((shiftjis & 0x3F) << 9)
|
||
);
|
||
}
|
||
|
||
// Font ROM glyph retrieval
|
||
// ------------------------
|
||
|
||
// Structure returned from INT 18h, AH=14h. The amount of bytes returned
|
||
// depends on the type of glyph (8×8, 8×16, or 16×16) indicated by its code
|
||
// point, so make sure to allocate the correct subclass for it.
|
||
struct pc98_glyph_t {
|
||
uint8_t tram_w;
|
||
uint8_t h_divided_by_8;
|
||
};
|
||
|
||
struct pc98_glyph_ank_8x16_t : public pc98_glyph_t {
|
||
DotRect<dots_t(GLYPH_HALF_W), GLYPH_H> dots;
|
||
};
|
||
|
||
struct pc98_glyph_kanji_t : public pc98_glyph_t {
|
||
DotRect<dots_t(GLYPH_FULL_W), GLYPH_H> dots;
|
||
};
|
||
|
||
void int18h_14h(REGS& in, pc98_glyph_t& glyph, uint16_t jis);
|
||
|
||
inline void fontrom_get(REGS& in, pc98_glyph_ank_8x16_t& glyph, char ank) {
|
||
int18h_14h(in, glyph, (0x8000 + ank));
|
||
}
|
||
// ------------------------
|
||
|
||
class TRAMCursor {
|
||
struct {
|
||
uint16_t left;
|
||
uint16_t right;
|
||
} near* p;
|
||
|
||
public:
|
||
// Writes the given fullwidth JIS code point with the given attribute to
|
||
// the left and right cells at the current cursor position, then advances
|
||
// the cursor. Halfwidth code points will also be written to both cells.
|
||
void putkanji(uint16_t jis_kanji, int atrb);
|
||
|
||
// Calls putkanji() for the next 5 TRAM rows.
|
||
void putkanji_for_5_rows(uint16_t jis_kanji, int atrb);
|
||
|
||
// This is always called at the (0-based) line 21, and therefore always
|
||
// ends up writing into the second TRAM page. Luckily, that page is used,
|
||
// and no code cares about it...
|
||
void putkanji_until_end(uint16_t jis_kanji, int atrb) {
|
||
putkanji_for_5_rows(jis_kanji, atrb);
|
||
}
|
||
|
||
void rewind_to_topleft() {
|
||
p = 0;
|
||
}
|
||
};
|
||
|
||
/// 16× letter rendering
|
||
/// --------------------
|
||
/// These are rendered by retrieving the glyphs from font ROM and then printing
|
||
/// them to text RAM with one fullwidth space per glyph dot, effectively
|
||
/// scaling them up to 16× their size.
|
||
|
||
// Fills text RAM with black and renders a transparent [jis_kanji] at its
|
||
// center.
|
||
void pascal tram_x16_kanji_center_reverse(uint16_t jis_kanji);
|
||
|
||
// Shows the red "STAGE [stage_num]" letters.
|
||
void pascal tram_x16_stage(unsigned int stage_num);
|
||
|
||
#define tram_x16_put_center_margin(tram_cursor, x, atrb) \
|
||
for(x = 0; x < (((RES_X / GLYPH_FULL_W) - GLYPH_FULL_W) / 2); x++) { \
|
||
tram_cursor.putkanji(' ', atrb); \
|
||
}
|
||
|
||
// Helper functions
|
||
// ----------------
|
||
|
||
template <class RowDots> struct TRAMx16Row {
|
||
RowDots dot_cur;
|
||
RowDots dots;
|
||
|
||
pixel_t w() const {
|
||
return ((sizeof(dots) * BYTE_DOTS));
|
||
}
|
||
};
|
||
|
||
#define tram_x16_row_init(row, row_dots) \
|
||
row.dots = row_dots; \
|
||
row.dot_cur = (1 << (row.w()- 1));
|
||
|
||
#define tram_x16_row_put(row, tram_cursor, x, atrb_fg, atrb_bg) \
|
||
for(x = 0; x < row.w(); x++) { \
|
||
if((row.dots & row.dot_cur) == 0) { \
|
||
tram_cursor.putkanji(' ', atrb_bg); \
|
||
} else { \
|
||
tram_cursor.putkanji(' ', atrb_fg); \
|
||
} \
|
||
row.dot_cur >>= 1; \
|
||
}
|
||
|
||
#define tram_x16_row_put_red(row, tram_cursor, x, row_dots) \
|
||
tram_x16_row_init(row, glyphs[i].byte[glyph_y]); \
|
||
tram_x16_row_put(row, tram_cursor, x, (TX_RED | TX_REVERSE), TX_BLACK);
|
||
// ----------------
|
||
// --------------------
|