Skip to content

Commit

Permalink
[Maintenance] Introduce proper Shift-JIS and JIS X 0208 types
Browse files Browse the repository at this point in the history
Much more semantic than that twobyte_t abomination.

Part of P0212, funded by GhostRiderCog, Lmocinemod, and LeyDud.
  • Loading branch information
nmlgc committed Aug 11, 2022
1 parent e4124ca commit 60a7e44
Show file tree
Hide file tree
Showing 51 changed files with 229 additions and 174 deletions.
2 changes: 2 additions & 0 deletions decomp.hpp
Expand Up @@ -3,6 +3,8 @@
* Declarations to help decompiling the seemingly impossible
*/

#define DECOMP_HPP

// Flag comparisons
// ----------------
// When used inside a conditional expression like
Expand Down
43 changes: 43 additions & 0 deletions shiftjis.hpp
@@ -0,0 +1,43 @@
// 2-byte JIS X 0208 codepoint.
typedef uint16_t jis_t;

// Multibyte Shift-JIS string. Use as replacement for `unsigned char` in
// situations where the contents are assumed to be Shift-JIS.
typedef uint8_t shiftjis_t;
typedef int8_t sshiftjis_t; // MODDERS: Delete

// 2-byte/fullwidth Shift-JIS codepoint.
typedef uint16_t shiftjis_kanji_t;
typedef int8_t sshiftjis_kanji_t; // MODDERS: Delete

// ZUN bloat: Byte-swapped 2-byte/fullwidth Shift-JIS codepoint for bytewise
// access.
typedef uint16_t shiftjis_kanji_swapped_t;
typedef int16_t sshiftjis_kanji_swapped_t; // MODDERS: Delete

#define kanji_swap(kanji) static_cast<shiftjis_kanji_swapped_t>( \
(static_cast<shiftjis_kanji_t>(kanji) << 8) | \
(static_cast<shiftjis_kanji_t>(kanji) >> 8) \
)

#ifdef DECOMP_HPP
// Way too often, the games store fullwidth Shift-JIS codepoints in two
// 8-bit variables rather than a single 16-bit one.
typedef StupidBytewiseWrapperAround<shiftjis_kanji_t> ShiftJISKanji;
#endif

// Good luck deriving this from the StupidBytewiseWrapperAround template.
template <unsigned int Length> union ShiftJISKanjiBuffer {
shiftjis_kanji_t t[Length];
int8_t byte[sizeof(uint16_t) * Length];
uint8_t ubyte[sizeof(uint16_t) * Length];
};

inline jis_t shiftjis_to_jis(shiftjis_kanji_t shiftjis) {
return (0x1F21 +
(((shiftjis >> 8) - (shiftjis >> 15) < 0x9E)
? ((((shiftjis >> 8) - (shiftjis >> 15) - 0x40) & 0x1FF))
: ((shiftjis >> 8) - (shiftjis >> 15) + 0x62)
) + ((shiftjis & 0x3F) << 9)
);
}
1 change: 1 addition & 0 deletions th01/core/initexit.cpp
Expand Up @@ -6,6 +6,7 @@
#include "pc98.h"
#include "planar.h"
#include "master.hpp"
#include "shiftjis.hpp"
extern "C" {
#include "th01/hardware/graph.h"
#include "th01/hardware/palette.h"
Expand Down
4 changes: 2 additions & 2 deletions th01/end/end.cpp
Expand Up @@ -4,8 +4,8 @@
#include "platform.h"
#include "pc98.h"
#include "planar.h"
#include "twobyte.h"
#include "master.hpp"
#include "shiftjis.hpp"
#include "th01/common.h"
#include "th01/rank.h"
#include "th01/resident.hpp"
Expand Down Expand Up @@ -511,7 +511,7 @@ void verdict_title_calculate_and_render(void)

void verdict_animate_and_regist(void)
{
const char* RANKS[RANK_COUNT] = {
const shiftjis_t* RANKS[RANK_COUNT] = {
" EASY ",
"NORMAL",
" HARD ",
Expand Down
4 changes: 2 additions & 2 deletions th01/end/type.hpp
Expand Up @@ -3,10 +3,10 @@ static const uint4_t COL_TYPE = 15;
// Types [len] half- (ank) or full-width (kanji) characters of [str] onto the
// given position in VRAM, with a frame delay between each character.
void pascal graph_type_ank_n(
screen_x_t left, vram_y_t top, int len, const char *str
screen_x_t left, vram_y_t top, int len, const sshiftjis_t *str
);
void pascal graph_type_kanji_n(
screen_x_t left, vram_y_t top, int len, const char *str
screen_x_t left, vram_y_t top, int len, const sshiftjis_kanji_t *str
);

#define graph_type_ank(left, top, str) { \
Expand Down
9 changes: 5 additions & 4 deletions th01/formats/scoredat.hpp
Expand Up @@ -17,25 +17,26 @@
int8_t scoredat_name_byte_encode(int8_t byte);
int8_t scoredat_name_byte_decode(int8_t byte);

#if 0
// On-disk structure of the REYHI*.DAT files.
// For reference, never actually used by the game itself
struct scoredat_t {
// Not null-terminated!
char magic[sizeof(SCOREDAT_MAGIC) - 1];

// Exclusively used to store full-width Shift-JIS code points.
// Not null-terminated.
int16_t name[SCOREDAT_PLACES][SCOREDAT_NAME_KANJI];
shiftjis_kanji_t name[SCOREDAT_PLACES][SCOREDAT_NAME_KANJI];

uint32_t score[SCOREDAT_PLACES];
int16_t stage[SCOREDAT_PLACES];
twobyte_t route[SCOREDAT_PLACES];
shiftjis_kanji_t route[SCOREDAT_PLACES];
};
#endif

extern int8_t* scoredat_names; // Yeah, technically a scoredat_name_t.
extern int16_t* scoredat_stages;
extern int32_t* scoredat_score;
extern int8_t* scoredat_routes; // Yeah, technically a twobyte_t.
extern int8_t* scoredat_routes; // Yeah, technically a shiftjis_kanji_t.

// Byte-wise access to [scoredat_routes].
inline int8_t& scoredat_route_byte(int place, int byte) {
Expand Down
2 changes: 1 addition & 1 deletion th01/fuuin_02.cpp
Expand Up @@ -14,8 +14,8 @@
#include "planar.h"
#include "decomp.hpp"
#include "pc98kbd.h"
#include "twobyte.h"
#include "master.hpp"
#include "shiftjis.hpp"
#include "th01/rank.h"
extern "C" {
#include "th01/hardware/graph.h"
Expand Down
5 changes: 3 additions & 2 deletions th01/fuuin_04.cpp
Expand Up @@ -9,6 +9,7 @@
#include "pc98.h"
#include "planar.h"
#include "master.hpp"
#include "shiftjis.hpp"
extern "C" {
#include "th01/hardware/graph.h"
#include "th01/hardware/grppsafx.h"
Expand Down Expand Up @@ -102,7 +103,7 @@ void pascal grp_palette_white_in(unsigned int frames)
#pragma option -O-

void pascal graph_type_ank_n(
screen_x_t left, vram_y_t top, int len, const char *str
screen_x_t left, vram_y_t top, int len, const sshiftjis_t *str
)
{
for(int i = 0; i < len; i++) {
Expand All @@ -114,7 +115,7 @@ void pascal graph_type_ank_n(
}

void pascal graph_type_kanji_n(
screen_x_t left, vram_y_t top, int len, const char *str
screen_x_t left, vram_y_t top, int len, const sshiftjis_kanji_t *str
)
{
for(int i = 0; i < len; i++) {
Expand Down
10 changes: 6 additions & 4 deletions th01/hardware/graph.cpp
Expand Up @@ -3,9 +3,11 @@
#include <mbctype.h>
#include <mbstring.h>
#include "platform.h"
#include "decomp.hpp"
#include "pc98.h"
#include "planar.h"
#include "master.hpp"
#include "shiftjis.hpp"
#include "th01/v_colors.hpp"
#include "th01/math/clamp.hpp"
#include "th01/hardware/egc.h"
Expand Down Expand Up @@ -729,13 +731,13 @@ inline pixel_t fx_spacing_from(int col_and_fx) {
return ((col_and_fx / 0x40) % 8);
}

pixel_t text_extent_fx(int col_and_fx, const unsigned char *str)
pixel_t text_extent_fx(int col_and_fx, const shiftjis_t *str)
{
register pixel_t ret = 0;
register pixel_t spacing = fx_spacing_from(col_and_fx);
while(*str) {
if(_ismbblead(str[0])) {
uint16_t codepoint = ((char)str[0] << 8) + str[0];
shiftjis_kanji_t codepoint = ((char)str[0] << 8) + str[0];
str++;
str++;
if(codepoint < 0x8540) {
Expand All @@ -757,11 +759,11 @@ pixel_t text_extent_fx(int col_and_fx, const unsigned char *str)
#include "th01/hardware/grppsafx.cpp"

void graph_putsa_fx(
screen_x_t left, vram_y_t top, int16_t col_and_fx, const unsigned char *str
screen_x_t left, vram_y_t top, int16_t col_and_fx, const shiftjis_t *str
)
{
register screen_x_t x = left;
uint16_t codepoint;
jis_t codepoint;
dots_t(GLYPH_FULL_W) glyph_row;
dots8_t far *vram;
int fullwidth;
Expand Down
1 change: 1 addition & 0 deletions th01/hardware/grp2xscs.cpp
Expand Up @@ -4,6 +4,7 @@
#include "platform.h"
#include "pc98.h"
#include "planar.h"
#include "shiftjis.hpp"
extern "C" {
#include "th01/hardware/graph.h"
#include "th01/hardware/grppsafx.h"
Expand Down
4 changes: 2 additions & 2 deletions th01/hardware/grp2xscs.hpp
Expand Up @@ -14,8 +14,8 @@ void graph_2xscale_byterect_1_to_0_slow(
// (Which are the only things that this 2× scale is performed on anyway.)

// Blits [str] to the given glyph [row] with the given color and effects, for
// a later 2× scale of the
inline void graph_glyphrow_put(int row, int col_and_fx, const char *str) {
// a later 2× nearest-neighbor scale of the same row.
inline void graph_glyphrow_put(int row, int col_and_fx, const shiftjis_t *str) {
graph_putsa_fx(0, (GLYPH_H * row), (FX_CLEAR_BG | col_and_fx), str);
}

Expand Down
7 changes: 6 additions & 1 deletion th01/hardware/grppffx.cpp
Expand Up @@ -2,12 +2,17 @@
#include <stdarg.h>
#include "platform.h"
#include "pc98.h"
#include "shiftjis.hpp"
extern "C" {
#include "th01/hardware/grppsafx.h"
}

void graph_printf_fx(
screen_x_t left, vram_y_t top, int16_t col_and_fx, const char *fmt, ...
screen_x_t left,
vram_y_t top,
int16_t col_and_fx,
const shiftjis_t *fmt,
...
)
{
char str[256];
Expand Down
2 changes: 1 addition & 1 deletion th01/hardware/grppfnfx.cpp
Expand Up @@ -10,7 +10,7 @@ void graph_putfwnum_fx(
int digit;
int digit_prev;
unsigned long divisor = 1;
const char* FULLWIDTH_NUMERAL[10] = FULLWIDTH_NUMERALS;
const shiftjis_t* FULLWIDTH_NUMERAL[10] = FULLWIDTH_NUMERALS;

for(divisor_i = 0; divisor_i < digits; divisor_i++) {
divisor *= 10;
Expand Down
13 changes: 7 additions & 6 deletions th01/hardware/grppsafx.h
Expand Up @@ -44,19 +44,20 @@
// Puts the given [str] onto the graphics RAM at the given position,
// with the given graphics color and effect.
void DEFCONV graph_putsa_fx(
screen_x_t left,
vram_y_t top,
int16_t col_and_fx,
const unsigned char *str
screen_x_t left, vram_y_t top, int16_t col_and_fx, const shiftjis_t *str
);
#endif

#if (GAME == 1)
// Variadic version of graph_putsa_fx().
void graph_printf_fx(
screen_x_t left, vram_y_t top, int16_t col_and_fx, const char *fmt, ...
screen_x_t left,
vram_y_t top,
int16_t col_and_fx,
const shiftjis_t *fmt,
...
);

// Calculates the width of [str], displayed with the given [fx].
int text_extent_fx(int fx, const unsigned char *str);
int text_extent_fx(int fx, const shiftjis_t *str);
#endif
8 changes: 4 additions & 4 deletions th01/hardware/tram_x16.cpp
@@ -1,4 +1,4 @@
void TRAMCursor::putkanji(uint16_t jis_kanji, int atrb)
void TRAMCursor::putkanji(jis_t jis_kanji, int atrb)
{
// Yes, this is a correct way of writing any fullwidth character to TRAM.
// More research and proof forthcoming...
Expand All @@ -10,7 +10,7 @@ void TRAMCursor::putkanji(uint16_t jis_kanji, int atrb)
p++;
}

void TRAMCursor::putkanji_for_5_rows(uint16_t jis_kanji, int atrb)
void TRAMCursor::putkanji_for_5_rows(jis_t jis_kanji, int atrb)
{
for(int y = 0; y < 5; y++) {
for(int x = 0; x < (RES_X / GLYPH_FULL_W); x++) {
Expand All @@ -21,7 +21,7 @@ void TRAMCursor::putkanji_for_5_rows(uint16_t jis_kanji, int atrb)

// Heavily inspired by the INT 18h, AH=14h sample program from the PC-9801
// Programmers' Bible, on p. 121.
void pascal tram_x16_kanji_center_reverse(uint16_t jis_kanji)
void pascal tram_x16_kanji_center_reverse(jis_t jis_kanji)
{
utram_kanji_amount_t x;
upixel_t glyph_y;
Expand Down Expand Up @@ -56,7 +56,7 @@ void pascal tram_x16_kanji_center_reverse(uint16_t jis_kanji)
}

// Where was this function above? :P
void int18h_14h(REGS& in, pc98_glyph_t& glyph, uint16_t jis)
void int18h_14h(REGS& in, pc98_glyph_t& glyph, jis_t jis)
{
REGS out;
in.w.bx = FP_SEG(&glyph);
Expand Down
23 changes: 7 additions & 16 deletions th01/hardware/tram_x16.hpp
@@ -1,12 +1,3 @@
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
// ------------------------

Expand All @@ -26,7 +17,7 @@ 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);
void int18h_14h(REGS& in, pc98_glyph_t& glyph, jis_t jis);

inline void fontrom_get(REGS& in, pc98_glyph_ank_8x16_t& glyph, char ank) {
int18h_14h(in, glyph, (0x8000 + ank));
Expand All @@ -35,23 +26,23 @@ inline void fontrom_get(REGS& in, pc98_glyph_ank_8x16_t& glyph, char ank) {

class TRAMCursor {
struct {
uint16_t left;
uint16_t right;
jis_t left;
jis_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);
void putkanji(jis_t jis_kanji, int atrb);

// Calls putkanji() for the next 5 TRAM rows.
void putkanji_for_5_rows(uint16_t jis_kanji, int atrb);
void putkanji_for_5_rows(jis_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) {
void putkanji_until_end(jis_t jis_kanji, int atrb) {
putkanji_for_5_rows(jis_kanji, atrb);
}

Expand All @@ -68,7 +59,7 @@ class TRAMCursor {

// 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);
void pascal tram_x16_kanji_center_reverse(jis_t jis_kanji);

// Shows the red "STAGE [stage_num]" letters.
void pascal tram_x16_stage(unsigned int stage_num);
Expand Down

0 comments on commit 60a7e44

Please sign in to comment.