2020-12-11 21:47:11 -05:00
|
|
|
#include <ultra64.h>
|
|
|
|
|
#include <PR/gs2dex.h>
|
2020-12-12 16:20:37 -05:00
|
|
|
#include <PR/gu.h>
|
2020-12-15 22:57:04 -05:00
|
|
|
#include <stdarg.h>
|
2020-12-11 21:47:11 -05:00
|
|
|
|
2020-12-15 17:46:07 -05:00
|
|
|
#include "config.h"
|
|
|
|
|
|
2020-12-11 21:47:11 -05:00
|
|
|
#include "s2d_draw.h"
|
2020-12-11 22:51:58 -05:00
|
|
|
#include "s2d_print.h"
|
2020-12-15 17:46:07 -05:00
|
|
|
#include "s2d_ustdlib.h"
|
2021-03-11 16:50:55 -05:00
|
|
|
#include "s2d_error.h"
|
2020-12-11 21:47:11 -05:00
|
|
|
|
2021-03-11 16:50:55 -05:00
|
|
|
static int s2d_width(const char *str, int line, int len);
|
|
|
|
|
|
2021-05-31 01:32:58 -04:00
|
|
|
enum S2DPrintModes {
|
|
|
|
|
MODE_DRAW_DROPSHADOW,
|
|
|
|
|
MODE_DRAW_NORMALTEXT,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static int s2d_snprint(int x, int y, int align, const char *str, uObjMtx *buf, int len, int mode) {
|
2020-12-11 21:47:11 -05:00
|
|
|
char *p = str;
|
2020-12-15 22:57:04 -05:00
|
|
|
int tmp_len = 0;
|
2020-12-15 23:06:09 -05:00
|
|
|
int orig_x = x;
|
|
|
|
|
int orig_y = y;
|
2021-02-24 12:28:46 -05:00
|
|
|
int line = 0;
|
2021-05-16 11:37:06 -04:00
|
|
|
char button = '\0';
|
2020-12-15 23:36:40 -05:00
|
|
|
|
2020-12-16 18:06:46 -05:00
|
|
|
if (*p == '\0') return;
|
|
|
|
|
|
2021-05-31 02:37:39 -04:00
|
|
|
#ifdef DRAW_S2D
|
|
|
|
|
s2d_rdp_init();
|
|
|
|
|
#else
|
|
|
|
|
f3d_rdp_init();
|
|
|
|
|
#endif
|
2020-12-19 14:16:59 -05:00
|
|
|
|
2020-12-18 18:38:27 -05:00
|
|
|
// resets parameters
|
2020-12-15 23:36:40 -05:00
|
|
|
s2d_red = s2d_green = s2d_blue = 255;
|
|
|
|
|
s2d_alpha = 255;
|
2020-12-18 18:38:27 -05:00
|
|
|
drop_shadow = FALSE;
|
2021-02-24 12:28:46 -05:00
|
|
|
|
|
|
|
|
switch (align) {
|
|
|
|
|
case ALIGN_CENTER:
|
|
|
|
|
x = orig_x - s2d_width(str, line, len) / 2;
|
|
|
|
|
break;
|
|
|
|
|
case ALIGN_RIGHT:
|
|
|
|
|
x = orig_x - s2d_width(str, line, len);
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-11 22:51:58 -05:00
|
|
|
do {
|
2020-12-16 18:06:46 -05:00
|
|
|
char current_char = *p;
|
2020-12-15 22:57:04 -05:00
|
|
|
|
2020-12-16 18:06:46 -05:00
|
|
|
switch (current_char) {
|
2020-12-11 22:51:58 -05:00
|
|
|
case CH_SCALE:
|
2020-12-13 18:31:42 -05:00
|
|
|
CH_SKIP(p);
|
2021-04-20 00:50:13 -04:00
|
|
|
myScale = (f32)s2d_atoi(p, &p) / 100.0f;
|
2020-12-11 21:47:11 -05:00
|
|
|
break;
|
2020-12-11 22:51:58 -05:00
|
|
|
case CH_ROT:
|
2020-12-13 18:31:42 -05:00
|
|
|
CH_SKIP(p);
|
2020-12-16 18:06:46 -05:00
|
|
|
myDegrees = s2d_atoi(p, &p);
|
2020-12-11 21:47:11 -05:00
|
|
|
break;
|
2020-12-11 22:51:58 -05:00
|
|
|
case CH_TRANSLATE:
|
2020-12-13 18:31:42 -05:00
|
|
|
CH_SKIP(p);
|
2021-02-24 12:28:46 -05:00
|
|
|
orig_x = s2d_atoi(p, &p);
|
|
|
|
|
line++;
|
|
|
|
|
switch (align) {
|
|
|
|
|
case ALIGN_LEFT:
|
|
|
|
|
x = orig_x;
|
|
|
|
|
break;
|
|
|
|
|
case ALIGN_CENTER:
|
|
|
|
|
x = orig_x - s2d_width(str, line, len) / 2;
|
|
|
|
|
break;
|
|
|
|
|
case ALIGN_RIGHT:
|
|
|
|
|
x = orig_x - s2d_width(str, line, len);
|
|
|
|
|
}
|
2020-12-13 18:31:42 -05:00
|
|
|
CH_SKIP(p);
|
|
|
|
|
CH_SKIP(p);
|
2021-02-24 12:28:46 -05:00
|
|
|
orig_y = s2d_atoi(p, &p);
|
|
|
|
|
y = orig_y;
|
2020-12-12 15:33:14 -05:00
|
|
|
break;
|
2020-12-12 19:45:53 -05:00
|
|
|
case CH_COLOR:
|
2020-12-13 18:31:42 -05:00
|
|
|
CH_SKIP(p);
|
2020-12-12 19:45:53 -05:00
|
|
|
s2d_red = s2d_atoi(p, &p);
|
2020-12-13 18:31:42 -05:00
|
|
|
CH_SKIP(p); CH_SKIP(p);
|
2020-12-12 21:56:36 -05:00
|
|
|
|
2020-12-12 19:45:53 -05:00
|
|
|
s2d_green = s2d_atoi(p, &p);
|
2020-12-13 18:31:42 -05:00
|
|
|
CH_SKIP(p); CH_SKIP(p);
|
2020-12-12 21:56:36 -05:00
|
|
|
|
2020-12-12 19:45:53 -05:00
|
|
|
s2d_blue = s2d_atoi(p, &p);
|
2020-12-13 18:31:42 -05:00
|
|
|
CH_SKIP(p); CH_SKIP(p);
|
2020-12-12 21:56:36 -05:00
|
|
|
|
2020-12-12 19:45:53 -05:00
|
|
|
s2d_alpha = s2d_atoi(p, &p);
|
|
|
|
|
break;
|
2020-12-18 18:38:27 -05:00
|
|
|
case CH_DROPSHADOW:
|
2021-05-31 01:32:58 -04:00
|
|
|
drop_shadow = 1;
|
2021-04-20 03:00:55 -04:00
|
|
|
|
|
|
|
|
// WIP: drop shadow custom offset
|
|
|
|
|
// TODO: unique offset per string; fix negative offsets
|
2021-05-31 01:32:58 -04:00
|
|
|
CH_SKIP(p);
|
|
|
|
|
drop_x = s2d_atoi(p, &p);
|
|
|
|
|
CH_SKIP(p); CH_SKIP(p);
|
|
|
|
|
drop_y = s2d_atoi(p, &p);
|
2021-05-16 11:37:06 -04:00
|
|
|
break;
|
|
|
|
|
case CH_BUTTON:
|
|
|
|
|
if (len - tmp_len == 1) break;
|
|
|
|
|
if (len - tmp_len > 2) {
|
|
|
|
|
CH_SKIP(p);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
button = p[1];
|
|
|
|
|
CH_SKIP(p);
|
|
|
|
|
switch (button) {
|
|
|
|
|
case 'A':
|
|
|
|
|
if (!(CONTROLLER_HELD_INPUT & A_BUTTON)) return 1;
|
|
|
|
|
break;
|
|
|
|
|
case 'B':
|
|
|
|
|
if (!(CONTROLLER_HELD_INPUT & B_BUTTON)) return 1;
|
|
|
|
|
break;
|
|
|
|
|
case 'Z':
|
|
|
|
|
if (!(CONTROLLER_HELD_INPUT & Z_TRIG)) return 1;
|
|
|
|
|
break;
|
|
|
|
|
case 'L':
|
|
|
|
|
if (!(CONTROLLER_HELD_INPUT & L_TRIG)) return 1;
|
|
|
|
|
break;
|
|
|
|
|
case 'R':
|
|
|
|
|
if (!(CONTROLLER_HELD_INPUT & R_TRIG)) return 1;
|
|
|
|
|
break;
|
|
|
|
|
case 'S':
|
|
|
|
|
if (!(CONTROLLER_HELD_INPUT & START_BUTTON)) return 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-12-18 18:38:27 -05:00
|
|
|
break;
|
2020-12-15 23:06:09 -05:00
|
|
|
case '\n':
|
2021-02-24 12:28:46 -05:00
|
|
|
line++;
|
|
|
|
|
switch (align) {
|
|
|
|
|
case ALIGN_LEFT:
|
|
|
|
|
x = orig_x;
|
|
|
|
|
break;
|
|
|
|
|
case ALIGN_CENTER:
|
|
|
|
|
x = orig_x - s2d_width(str, line, len) / 2;
|
|
|
|
|
break;
|
|
|
|
|
case ALIGN_RIGHT:
|
|
|
|
|
x = orig_x - s2d_width(str, line, len);
|
|
|
|
|
}
|
|
|
|
|
y += TEX_HEIGHT / TEX_RES;
|
2020-12-15 23:36:40 -05:00
|
|
|
break;
|
|
|
|
|
case '\t':
|
2021-02-24 12:28:46 -05:00
|
|
|
x += TAB_WIDTH_H / TEX_RES;
|
2020-12-15 23:36:40 -05:00
|
|
|
break;
|
|
|
|
|
case '\v':
|
2021-02-24 12:28:46 -05:00
|
|
|
x += TAB_WIDTH_V / TEX_RES;
|
|
|
|
|
y += TEX_HEIGHT / TEX_RES;
|
2020-12-15 23:06:09 -05:00
|
|
|
break;
|
2021-01-09 21:53:27 -05:00
|
|
|
// case CH_SEPARATOR:
|
|
|
|
|
// CH_SKIP(p);
|
|
|
|
|
// break;
|
2021-02-24 12:28:46 -05:00
|
|
|
case CH_RESET:
|
|
|
|
|
s2d_red = s2d_green = s2d_blue = 255;
|
|
|
|
|
s2d_alpha = 255;
|
|
|
|
|
drop_shadow = FALSE;
|
2021-04-20 03:00:55 -04:00
|
|
|
drop_x = 0;
|
|
|
|
|
drop_y = 0;
|
2021-02-24 12:28:46 -05:00
|
|
|
myScale = 1;
|
|
|
|
|
myDegrees = 0;
|
|
|
|
|
break;
|
2020-12-11 21:47:11 -05:00
|
|
|
default:
|
2021-01-09 21:53:27 -05:00
|
|
|
if (current_char != '\0' && current_char != CH_SEPARATOR) {
|
2021-04-20 00:50:13 -04:00
|
|
|
char *tbl = segmented_to_virtual(s2d_kerning_table);
|
|
|
|
|
|
2021-05-31 01:32:58 -04:00
|
|
|
if (drop_shadow && mode == MODE_DRAW_DROPSHADOW) {
|
2021-05-31 02:37:39 -04:00
|
|
|
glyph_shadow(current_char, x + drop_x, y + drop_y, (buf++));
|
2021-05-31 01:32:58 -04:00
|
|
|
} else if (mode == MODE_DRAW_NORMALTEXT) {
|
2021-05-31 02:37:39 -04:00
|
|
|
glyph_draw(current_char, x, y, (buf++));
|
2021-05-31 01:32:58 -04:00
|
|
|
}
|
2021-04-20 00:50:13 -04:00
|
|
|
(x += (tbl[(int) current_char] * (BASE_SCALE * myScale)));
|
2020-12-15 22:57:04 -05:00
|
|
|
}
|
2020-12-11 21:47:11 -05:00
|
|
|
}
|
2020-12-15 17:46:07 -05:00
|
|
|
if (*p == '\0') break;
|
2020-12-13 22:24:18 -05:00
|
|
|
p++;
|
2020-12-15 22:57:04 -05:00
|
|
|
tmp_len++;
|
|
|
|
|
} while (tmp_len < len);
|
2021-04-20 00:50:13 -04:00
|
|
|
myScale = 1.0f;
|
2020-12-12 15:33:14 -05:00
|
|
|
myDegrees = 0;
|
2021-04-20 03:00:55 -04:00
|
|
|
drop_shadow = FALSE;
|
|
|
|
|
drop_x = 0;
|
|
|
|
|
drop_y = 0;
|
2021-05-16 11:37:06 -04:00
|
|
|
return 0;
|
2020-12-11 21:47:11 -05:00
|
|
|
}
|
2020-12-11 22:51:58 -05:00
|
|
|
|
2021-05-31 01:32:58 -04:00
|
|
|
static int s2d_string_has_dropshadow(const char *str) {
|
|
|
|
|
char *p = str;
|
|
|
|
|
|
|
|
|
|
int result = FALSE;
|
|
|
|
|
|
|
|
|
|
do {if (*p == CH_DROPSHADOW) result = TRUE;} while (*(++p) != '\0');
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// deprecated
|
2021-02-24 12:28:46 -05:00
|
|
|
void s2d_print(int x, int y, int align, const char *str, uObjMtx *buf) {
|
2021-03-11 16:50:55 -05:00
|
|
|
if (s2d_check_align(align) != 0) return;
|
|
|
|
|
if (s2d_check_str(str) != 0) return;
|
|
|
|
|
|
2021-05-31 01:32:58 -04:00
|
|
|
s2d_snprint(x, y, align, str, buf, s2d_strlen(str), MODE_DRAW_DROPSHADOW);
|
|
|
|
|
s2d_snprint(x, y, align, str, buf, s2d_strlen(str), MODE_DRAW_NORMALTEXT);
|
2020-12-15 22:57:04 -05:00
|
|
|
}
|
|
|
|
|
|
2021-02-24 12:28:46 -05:00
|
|
|
void s2d_print_alloc(int x, int y, int align, const char *str) {
|
2021-03-11 16:50:55 -05:00
|
|
|
int len;
|
|
|
|
|
|
|
|
|
|
if (s2d_check_align(align) != 0) return;
|
|
|
|
|
if (s2d_check_str(str) != 0) return;
|
|
|
|
|
|
|
|
|
|
len = s2d_strlen(str);
|
|
|
|
|
|
2021-05-31 01:32:58 -04:00
|
|
|
if (s2d_string_has_dropshadow(str)) {
|
|
|
|
|
uObjMtx *b = alloc(sizeof(uObjMtx) * len);
|
|
|
|
|
s2d_snprint(x, y, align, str, b, len, MODE_DRAW_DROPSHADOW);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uObjMtx *b2 = alloc(sizeof(uObjMtx) * len);
|
|
|
|
|
s2d_snprint(x, y, align, str, b2, len, MODE_DRAW_NORMALTEXT);
|
2021-01-07 14:07:27 -05:00
|
|
|
}
|
|
|
|
|
|
2021-05-31 01:32:58 -04:00
|
|
|
// deprecated
|
2021-02-24 12:28:46 -05:00
|
|
|
void s2d_type_print(int x, int y, int align, const char *str, uObjMtx *buf, int *pos) {
|
2021-03-11 16:50:55 -05:00
|
|
|
int len;
|
|
|
|
|
|
|
|
|
|
if (s2d_check_align(align) != 0) return;
|
|
|
|
|
if (s2d_check_str(str) != 0) return;
|
|
|
|
|
|
|
|
|
|
len = s2d_strlen(str);
|
2020-12-15 17:46:07 -05:00
|
|
|
|
2021-05-31 01:32:58 -04:00
|
|
|
s2d_snprint(x, y, align, str, buf, *pos, MODE_DRAW_DROPSHADOW);
|
|
|
|
|
|
|
|
|
|
int result = s2d_snprint(x, y, align, str, buf, *pos, MODE_DRAW_NORMALTEXT);
|
2020-12-15 17:46:07 -05:00
|
|
|
if (s2d_timer % 2 == 0) {
|
2021-05-16 11:37:06 -04:00
|
|
|
if (*pos < len && result != 1) {
|
2020-12-15 22:57:04 -05:00
|
|
|
(*pos)++;
|
|
|
|
|
}
|
2020-12-15 17:46:07 -05:00
|
|
|
}
|
2020-12-13 22:24:18 -05:00
|
|
|
}
|
|
|
|
|
|
2021-05-16 11:37:06 -04:00
|
|
|
void s2d_type_print_alloc(int x, int y, int align, const char *str, int *pos) {
|
|
|
|
|
int len;
|
|
|
|
|
|
|
|
|
|
if (s2d_check_align(align) != 0) return;
|
|
|
|
|
if (s2d_check_str(str) != 0) return;
|
|
|
|
|
|
|
|
|
|
len = s2d_strlen(str);
|
|
|
|
|
|
2021-05-31 01:32:58 -04:00
|
|
|
uObjMtx *b = alloc(sizeof(uObjMtx) * (*pos));
|
|
|
|
|
|
|
|
|
|
if (s2d_string_has_dropshadow(str)) {
|
|
|
|
|
uObjMtx *b_d = alloc(sizeof(uObjMtx) * (*pos));
|
|
|
|
|
s2d_snprint(x, y, align, str, b_d, *pos, MODE_DRAW_DROPSHADOW);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int result = s2d_snprint(x, y, align, str, b, *pos, MODE_DRAW_NORMALTEXT);
|
|
|
|
|
if (s2d_timer % 2 == 0) {
|
|
|
|
|
if (*pos < len && result != 1) {
|
|
|
|
|
(*pos)++;
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-05-16 11:37:06 -04:00
|
|
|
}
|
|
|
|
|
|
2021-05-31 01:32:58 -04:00
|
|
|
// broken atm
|
2021-03-11 16:50:55 -05:00
|
|
|
static int s2d_width(const char *str, int line, int len) {
|
2021-02-24 12:28:46 -05:00
|
|
|
char *p = str;
|
|
|
|
|
int tmp_len = 0;
|
|
|
|
|
int curLine = 0;
|
|
|
|
|
int width = 0;
|
|
|
|
|
int scale = 1;
|
|
|
|
|
|
|
|
|
|
if (*p == '\0') return width;
|
|
|
|
|
|
|
|
|
|
do {
|
|
|
|
|
char current_char = *p;
|
|
|
|
|
switch (current_char) {
|
|
|
|
|
case CH_SCALE:
|
|
|
|
|
CH_SKIP(p);
|
|
|
|
|
scale = s2d_atoi(p, &p);
|
|
|
|
|
break;
|
|
|
|
|
case CH_ROT:
|
|
|
|
|
CH_SKIP(p);
|
|
|
|
|
s2d_atoi(p, &p);
|
|
|
|
|
break;
|
|
|
|
|
case CH_TRANSLATE:
|
|
|
|
|
CH_SKIP(p);
|
|
|
|
|
s2d_atoi(p, &p);
|
|
|
|
|
curLine++;
|
|
|
|
|
CH_SKIP(p);
|
|
|
|
|
CH_SKIP(p);
|
|
|
|
|
s2d_atoi(p, &p);
|
|
|
|
|
break;
|
|
|
|
|
case CH_COLOR:
|
|
|
|
|
CH_SKIP(p);
|
|
|
|
|
s2d_atoi(p, &p);
|
|
|
|
|
CH_SKIP(p); CH_SKIP(p);
|
|
|
|
|
s2d_atoi(p, &p);
|
|
|
|
|
CH_SKIP(p); CH_SKIP(p);
|
|
|
|
|
s2d_atoi(p, &p);
|
|
|
|
|
CH_SKIP(p); CH_SKIP(p);
|
|
|
|
|
s2d_atoi(p, &p);
|
|
|
|
|
break;
|
|
|
|
|
case CH_DROPSHADOW:
|
|
|
|
|
case CH_RESET:
|
|
|
|
|
break;
|
|
|
|
|
case '\n':
|
|
|
|
|
curLine++;
|
|
|
|
|
break;
|
|
|
|
|
case '\t':
|
|
|
|
|
if (curLine == line)
|
|
|
|
|
width += TAB_WIDTH_H / TEX_RES;
|
|
|
|
|
break;
|
|
|
|
|
case '\v':
|
|
|
|
|
if (curLine == line)
|
|
|
|
|
width += TAB_WIDTH_V / TEX_RES;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
if (current_char != '\0' && curLine == line)
|
2021-03-11 16:50:55 -05:00
|
|
|
width += s2d_kerning_table[(int) current_char] * scale;
|
2021-02-24 12:28:46 -05:00
|
|
|
}
|
|
|
|
|
if (*p == '\0') break;
|
|
|
|
|
p++;
|
|
|
|
|
tmp_len++;
|
|
|
|
|
} while (tmp_len < len && curLine <= line);
|
|
|
|
|
return width;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// void s2d_vsprint(int x, int y, int align, uObjMtx *buf, const char *str, ...) {
|
2020-12-16 01:12:08 -05:00
|
|
|
// int last_chr;
|
|
|
|
|
// va_list args;
|
|
|
|
|
// char *dst = alloc(s2d_strlen(str) * 2);
|
|
|
|
|
// va_start(args, str);
|
|
|
|
|
// last_chr = vsprintf(dst, str, str, args);
|
|
|
|
|
// if (last_chr >= 0) {
|
|
|
|
|
// dst[last_chr] = '\0';
|
|
|
|
|
// }
|
2021-03-11 16:50:55 -05:00
|
|
|
// s2d_print(x, y, align, dst, buf);
|
2020-12-16 01:12:08 -05:00
|
|
|
// }
|
2020-12-15 22:57:04 -05:00
|
|
|
|
|
|
|
|
|