mirror of
https://github.com/Lorenzooone/Pokemon-Gen3-to-Gen-X.git
synced 2026-03-21 17:24:39 -05:00
630 lines
17 KiB
C
630 lines
17 KiB
C
#include "base_include.h"
|
|
#include <stdarg.h>
|
|
#include "optimized_swi.h"
|
|
#include "print_system.h"
|
|
#include "text_handler.h"
|
|
#include "graphics_handler.h"
|
|
#include "sprite_handler.h"
|
|
#include "useful_qualifiers.h"
|
|
#include "config_settings.h"
|
|
#include <stddef.h>
|
|
|
|
#include "text_gen3_to_general_int_bin.h"
|
|
#include "amiga_font_c_bin.h"
|
|
#include "jp_font_c_bin.h"
|
|
#include "window_graphics_bin.h"
|
|
|
|
#define VRAM_SIZE 0x10000
|
|
#define VRAM_END (((uintptr_t)VRAM_0)+VRAM_SIZE)
|
|
#define PALETTE 0xF
|
|
#define PALETTE_SIZE 0x10
|
|
#define PALETTE_BASE 0x5000000
|
|
#define FONT_TILES 0x100
|
|
#define FONT_SIZE (FONT_TILES*TILE_SIZE)
|
|
#define FONT_1BPP_SIZE (FONT_SIZE>>2)
|
|
#define FONT_POS (((uintptr_t)VRAM_0) + 0)
|
|
#define JP_FONT_POS (FONT_POS + FONT_SIZE)
|
|
#define NUMBERS_POS (VRAM_END - (10000*2))
|
|
#define ARRANGEMENT_POS (JP_FONT_POS+FONT_SIZE)
|
|
#ifdef __NDS__
|
|
#define FONT_POS_SUB (((uintptr_t)VRAM_0_SUB) + 0)
|
|
#define JP_FONT_POS_SUB (FONT_POS_SUB + FONT_SIZE)
|
|
#define ARRANGEMENT_POS_SUB (JP_FONT_POS_SUB+FONT_SIZE)
|
|
#endif
|
|
#define X_OFFSET_POS 0
|
|
#define Y_OFFSET_POS 1
|
|
|
|
#define SCREEN_SIZE 0x800
|
|
|
|
#define CPUFASTSET_FILL (0x1000000)
|
|
|
|
#define NUM_DIGITS 12
|
|
|
|
void set_arrangements(u8);
|
|
void process_arrangements(void);
|
|
void enable_screens(void);
|
|
void set_screens_positions(void);
|
|
static void base_flush(void);
|
|
void new_line(void);
|
|
u8 write_char(u16);
|
|
void write_above_char(u16);
|
|
int sub_printf(u8*);
|
|
int sub_printf_gen3(u8*, size_t, u8);
|
|
int prepare_base_10(int, u8*);
|
|
int prepare_base_16(u32, u8*);
|
|
int digits_print(u8*, int, u8, u8);
|
|
int write_base_10(int, int, u8);
|
|
int write_base_16(u32, int, u8);
|
|
void swap_buffer_screen_internal(u8);
|
|
u8 is_screen_disabled(u8);
|
|
|
|
u8 x_pos;
|
|
u8 y_pos;
|
|
screen_t* screen;
|
|
#ifdef __NDS__
|
|
screen_t* screen_sub;
|
|
#endif
|
|
u8 screen_num;
|
|
u8 loaded_screen_num;
|
|
|
|
u8 screens_flush;
|
|
u8 enabled_screen[TOTAL_BG];
|
|
u8 updated_screen[TOTAL_BG];
|
|
u8 buffer_screen[TOTAL_BG];
|
|
u8 screen_positions[TOTAL_BG][2];
|
|
|
|
IWRAM_CODE void set_arrangements(u8 bg_num){
|
|
if(bg_num >= TOTAL_BG)
|
|
bg_num = TOTAL_BG-1;
|
|
BGCTRL[bg_num] = get_bg_priority(bg_num) | ((((uintptr_t)get_screen(bg_num))-((uintptr_t)VRAM_0))>>3);
|
|
#if defined (__NDS__) && (SAME_ON_BOTH_SCREENS)
|
|
BGCTRL_SUB[bg_num] = get_bg_priority(bg_num) | ((((uintptr_t)get_screen(bg_num))-((uintptr_t)VRAM_0))>>3);
|
|
#endif
|
|
}
|
|
|
|
IWRAM_CODE void process_arrangements() {
|
|
for(int i = 0; i < TOTAL_BG; i++)
|
|
if(updated_screen[i]) {
|
|
set_arrangements(i);
|
|
updated_screen[i] = 0;
|
|
swap_buffer_screen_internal(i);
|
|
}
|
|
}
|
|
|
|
IWRAM_CODE void swap_buffer_screen_internal(u8 bg_num) {
|
|
if(bg_num >= TOTAL_BG)
|
|
bg_num = TOTAL_BG-1;
|
|
buffer_screen[bg_num] ^= 1;
|
|
if(bg_num == screen_num) {
|
|
screen = get_screen(bg_num);
|
|
#if defined (__NDS__) && (SAME_ON_BOTH_SCREENS)
|
|
screen_sub = get_screen_sub(bg_num);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
IWRAM_CODE void enable_screens() {
|
|
for(int i = 0; i < TOTAL_BG; i++)
|
|
if(enabled_screen[i]) {
|
|
REG_DISPCNT |= (0x100)<<i;
|
|
#if defined (__NDS__) && (SAME_ON_BOTH_SCREENS)
|
|
REG_DISPCNT_SUB |= (0x100)<<i;
|
|
#endif
|
|
}
|
|
else {
|
|
REG_DISPCNT &= ~((0x100)<<i);
|
|
#if defined (__NDS__) && (SAME_ON_BOTH_SCREENS)
|
|
REG_DISPCNT_SUB &= ~((0x100)<<i);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
u8 is_screen_disabled(u8 bg_num) {
|
|
if(bg_num >= TOTAL_BG)
|
|
bg_num = TOTAL_BG-1;
|
|
if(REG_DISPCNT & ((0x100)<<bg_num))
|
|
return 0;
|
|
return 1;
|
|
}
|
|
|
|
IWRAM_CODE void set_screens_positions() {
|
|
for(int i = 0; i < TOTAL_BG; i++) {
|
|
BG_OFFSET[i].x = screen_positions[i][X_OFFSET_POS];
|
|
BG_OFFSET[i].y = screen_positions[i][Y_OFFSET_POS];
|
|
#if defined (__NDS__) && (SAME_ON_BOTH_SCREENS)
|
|
BG_OFFSET_SUB[i].x = screen_positions[i][X_OFFSET_POS];
|
|
BG_OFFSET_SUB[i].y = screen_positions[i][Y_OFFSET_POS];
|
|
#endif
|
|
}
|
|
}
|
|
|
|
ALWAYS_INLINE void base_flush() {
|
|
process_arrangements();
|
|
set_screens_positions();
|
|
enable_screens();
|
|
loaded_screen_num = screen_num;
|
|
screens_flush = 0;
|
|
}
|
|
|
|
IWRAM_CODE void flush_screens() {
|
|
if(screens_flush) {
|
|
base_flush();
|
|
update_normal_oam();
|
|
}
|
|
}
|
|
|
|
void init_numbers() {
|
|
u16* numbers_storage = (u16*)NUMBERS_POS;
|
|
|
|
for(int i = 0; i < 10; i++)
|
|
for(int j = 0; j < 10; j++)
|
|
for(int k = 0; k < 10; k++)
|
|
for(int l = 0; l < 10; l++)
|
|
numbers_storage[l + (k*10) + (j*100) + (i*1000)] = l | (k<<4) | (j<<8) | (i<<12);
|
|
}
|
|
|
|
void set_text_palettes() {
|
|
BG_PALETTE[0]=get_full_colour(BACKGROUND_COLOUR_POS);
|
|
BG_PALETTE[(PALETTE*PALETTE_SIZE)]=get_full_colour(BACKGROUND_COLOUR_POS);
|
|
BG_PALETTE[(PALETTE*PALETTE_SIZE)+1]=get_full_colour(FONT_COLOUR_POS);
|
|
BG_PALETTE[(PALETTE*PALETTE_SIZE)+2]=get_full_colour(BACKGROUND_COLOUR_POS);
|
|
BG_PALETTE[(PALETTE*PALETTE_SIZE)+3]=get_full_colour(WINDOW_COLOUR_1_POS);
|
|
BG_PALETTE[(PALETTE*PALETTE_SIZE)+4]=get_full_colour(WINDOW_COLOUR_2_POS);
|
|
#if defined (__NDS__) && (SAME_ON_BOTH_SCREENS)
|
|
BG_PALETTE_SUB[0]=get_full_colour(BACKGROUND_COLOUR_POS);
|
|
BG_PALETTE_SUB[(PALETTE*PALETTE_SIZE)]=get_full_colour(BACKGROUND_COLOUR_POS);
|
|
BG_PALETTE_SUB[(PALETTE*PALETTE_SIZE)+1]=get_full_colour(FONT_COLOUR_POS);
|
|
BG_PALETTE_SUB[(PALETTE*PALETTE_SIZE)+2]=get_full_colour(BACKGROUND_COLOUR_POS);
|
|
BG_PALETTE_SUB[(PALETTE*PALETTE_SIZE)+3]=get_full_colour(WINDOW_COLOUR_1_POS);
|
|
BG_PALETTE_SUB[(PALETTE*PALETTE_SIZE)+4]=get_full_colour(WINDOW_COLOUR_2_POS);
|
|
#endif
|
|
}
|
|
|
|
void init_text_system() {
|
|
REG_DISPCNT = 0 | TILE_1D_MAP | ACTIVATE_SCREEN_HW;
|
|
#if defined (__NDS__) && (SAME_ON_BOTH_SCREENS)
|
|
REG_DISPCNT_SUB = 0 | TILE_1D_MAP | ACTIVATE_SCREEN_HW;
|
|
#endif
|
|
screens_flush = 0;
|
|
for(int i = 0; i < TOTAL_BG; i++) {
|
|
enabled_screen[i] = 0;
|
|
updated_screen[i] = 0;
|
|
buffer_screen[i] = 0;
|
|
set_arrangements(i);
|
|
set_bg_pos(i, 0, 0);
|
|
}
|
|
set_text_palettes();
|
|
set_screen(0);
|
|
|
|
// This is for the first frame
|
|
for(size_t i = 0; i < (TILE_SIZE>>2); i++)
|
|
*((u32*)(FONT_POS+(i<<2))) = 0x22222222;
|
|
#if defined (__NDS__) && (SAME_ON_BOTH_SCREENS)
|
|
for(size_t i = 0; i < (TILE_SIZE>>2); i++)
|
|
*((u32*)(FONT_POS_SUB+(i<<2))) = 0x22222222;
|
|
#endif
|
|
|
|
default_reset_screen();
|
|
enable_screen(0);
|
|
|
|
// Load english font
|
|
u32 buffer[FONT_1BPP_SIZE>>2];
|
|
u8 colors[] = {2, 1};
|
|
LZ77UnCompWram(amiga_font_c_bin, buffer);
|
|
convert_1bpp((u8*)buffer, (u32*)FONT_POS, FONT_1BPP_SIZE, colors, 1);
|
|
#if defined (__NDS__) && (SAME_ON_BOTH_SCREENS)
|
|
convert_1bpp((u8*)buffer, (u32*)FONT_POS_SUB, FONT_1BPP_SIZE, colors, 1);
|
|
#endif
|
|
|
|
PRINT_FUNCTION("\n Loading...");
|
|
base_flush();
|
|
|
|
// Set empty tile
|
|
for(size_t i = 0; i < (TILE_SIZE>>2); i++)
|
|
*((u32*)(FONT_POS+TILE_SIZE+(i<<2))) = 0;
|
|
#if defined (__NDS__) && (SAME_ON_BOTH_SCREENS)
|
|
for(size_t i = 0; i < (TILE_SIZE>>2); i++)
|
|
*((u32*)(FONT_POS_SUB+TILE_SIZE+(i<<2))) = 0;
|
|
#endif
|
|
|
|
// Load japanese font
|
|
LZ77UnCompWram(jp_font_c_bin, buffer);
|
|
convert_1bpp((u8*)buffer, (u32*)JP_FONT_POS, FONT_1BPP_SIZE, colors, 0);
|
|
#if defined (__NDS__) && (SAME_ON_BOTH_SCREENS)
|
|
convert_1bpp((u8*)buffer, (u32*)JP_FONT_POS_SUB, FONT_1BPP_SIZE, colors, 0);
|
|
#endif
|
|
|
|
// Set window tiles
|
|
for(size_t i = 0; i < (window_graphics_bin_size>>2); i++)
|
|
*((u32*)(FONT_POS+(2*TILE_SIZE)+(i<<2))) = ((const u32*)window_graphics_bin)[i];
|
|
#if defined (__NDS__) && (SAME_ON_BOTH_SCREENS)
|
|
for(size_t i = 0; i < (window_graphics_bin_size>>2); i++)
|
|
*((u32*)(FONT_POS_SUB+(2*TILE_SIZE)+(i<<2))) = ((const u32*)window_graphics_bin)[i];
|
|
#endif
|
|
}
|
|
|
|
void set_updated_screen() {
|
|
wait_for_vblank_if_needed();
|
|
updated_screen[screen_num] = 1;
|
|
}
|
|
|
|
void swap_buffer_screen(u8 bg_num, u8 effective_swap) {
|
|
wait_for_vblank_if_needed();
|
|
if(bg_num >= TOTAL_BG)
|
|
bg_num = TOTAL_BG-1;
|
|
if(effective_swap && is_screen_disabled(bg_num))
|
|
swap_buffer_screen_internal(bg_num);
|
|
updated_screen[bg_num] = 1;
|
|
}
|
|
|
|
IWRAM_CODE void prepare_flush() {
|
|
screens_flush = 1;
|
|
}
|
|
|
|
void wait_for_vblank_if_needed() {
|
|
// Avoid writing where you shouldn't
|
|
if(screens_flush)
|
|
VBlankIntrWait();
|
|
}
|
|
|
|
IWRAM_CODE void swap_screen_enabled_state(u8 bg_num){
|
|
wait_for_vblank_if_needed();
|
|
if(bg_num >= TOTAL_BG)
|
|
bg_num = TOTAL_BG-1;
|
|
enabled_screen[bg_num] ^= 1;
|
|
}
|
|
|
|
IWRAM_CODE void enable_screen(u8 bg_num){
|
|
wait_for_vblank_if_needed();
|
|
if(bg_num >= TOTAL_BG)
|
|
bg_num = TOTAL_BG-1;
|
|
enabled_screen[bg_num] = 1;
|
|
}
|
|
|
|
IWRAM_CODE void disable_screen(u8 bg_num){
|
|
wait_for_vblank_if_needed();
|
|
if(bg_num >= TOTAL_BG)
|
|
bg_num = TOTAL_BG-1;
|
|
enabled_screen[bg_num] = 0;
|
|
}
|
|
|
|
void disable_all_screens_but_current(){
|
|
for(int i = 0; i < TOTAL_BG; i++) {
|
|
if(i != screen_num)
|
|
disable_screen(i);
|
|
}
|
|
}
|
|
|
|
u8 get_bg_priority(u8 bg_num) {
|
|
if(bg_num >= TOTAL_BG)
|
|
bg_num = TOTAL_BG-1;
|
|
return TOTAL_BG-1-bg_num;
|
|
}
|
|
|
|
u8 get_curr_priority() {
|
|
return get_bg_priority(screen_num);
|
|
}
|
|
|
|
u8 get_loaded_priority() {
|
|
return get_bg_priority(loaded_screen_num);
|
|
}
|
|
|
|
void set_bg_pos(u8 bg_num, int x, int y){
|
|
wait_for_vblank_if_needed();
|
|
if(bg_num >= TOTAL_BG)
|
|
bg_num = TOTAL_BG-1;
|
|
if(x < 0)
|
|
x = SCREEN_REAL_WIDTH + x;
|
|
if(y < 0)
|
|
y = SCREEN_REAL_HEIGHT + y;
|
|
screen_positions[bg_num][X_OFFSET_POS] = x;
|
|
screen_positions[bg_num][Y_OFFSET_POS] = y;
|
|
}
|
|
|
|
u8 get_screen_num(){
|
|
return screen_num;
|
|
}
|
|
|
|
screen_t* get_screen(u8 bg_num){
|
|
if(bg_num >= TOTAL_BG)
|
|
bg_num = TOTAL_BG-1;
|
|
return (screen_t*)(ARRANGEMENT_POS+(SCREEN_SIZE*(bg_num+(TOTAL_BG*buffer_screen[bg_num]))));
|
|
}
|
|
|
|
#ifdef __NDS__
|
|
screen_t* get_screen_sub(u8 bg_num){
|
|
if(bg_num >= TOTAL_BG)
|
|
bg_num = TOTAL_BG-1;
|
|
return (screen_t*)(ARRANGEMENT_POS_SUB+(SCREEN_SIZE*(bg_num+(TOTAL_BG*buffer_screen[bg_num]))));
|
|
}
|
|
#endif
|
|
|
|
void set_screen(u8 bg_num){
|
|
if(bg_num >= TOTAL_BG)
|
|
bg_num = TOTAL_BG-1;
|
|
screen_num = bg_num;
|
|
screen = get_screen(bg_num);
|
|
#ifdef __NDS__
|
|
screen_sub = get_screen_sub(bg_num);
|
|
#endif
|
|
}
|
|
|
|
void reset_screen(u8 blank_fill){
|
|
set_updated_screen();
|
|
*((u32*)screen) = (PALETTE<<28) | (PALETTE<<12) | 0;
|
|
if(blank_fill)
|
|
*((u32*)screen) = (PALETTE<<28) | (PALETTE<<12) | 0x00010001;
|
|
CpuFastSet(screen, screen, CPUFASTSET_FILL | (SCREEN_SIZE>>2));
|
|
#if defined (__NDS__) && (SAME_ON_BOTH_SCREENS)
|
|
*((u32*)screen_sub) = (PALETTE<<28) | (PALETTE<<12) | 0;
|
|
if(blank_fill)
|
|
*((u32*)screen_sub) = (PALETTE<<28) | (PALETTE<<12) | 0x00010001;
|
|
CpuFastSet(screen_sub, screen_sub, CPUFASTSET_FILL | (SCREEN_SIZE>>2));
|
|
#endif
|
|
x_pos = 0;
|
|
y_pos = 0;
|
|
}
|
|
|
|
void default_reset_screen(){
|
|
reset_screen(REGULAR_FILL);
|
|
}
|
|
|
|
void set_text_x(u8 new_x){
|
|
new_x %= X_SIZE;
|
|
if(new_x < X_LIMIT)
|
|
x_pos = new_x;
|
|
else
|
|
x_pos = X_LIMIT-1;
|
|
}
|
|
|
|
void set_text_y(u8 new_y){
|
|
new_y %= Y_SIZE;
|
|
y_pos = new_y;
|
|
x_pos = 0;
|
|
}
|
|
|
|
u8 get_text_x(){
|
|
return x_pos;
|
|
}
|
|
|
|
u8 get_text_y(){
|
|
return y_pos;
|
|
}
|
|
|
|
void new_line(){
|
|
x_pos = 0;
|
|
y_pos += 1;
|
|
if(y_pos >= Y_SIZE)
|
|
y_pos = 0;
|
|
}
|
|
|
|
u8 write_char(u16 character) {
|
|
screen[x_pos+(y_pos*X_SIZE)] = character | (PALETTE << 12);
|
|
#if defined (__NDS__) && (SAME_ON_BOTH_SCREENS)
|
|
screen_sub[x_pos+(y_pos*X_SIZE)] = character | (PALETTE << 12);
|
|
#endif
|
|
x_pos++;
|
|
if(x_pos >= X_LIMIT) {
|
|
new_line();
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void write_above_char(u16 character) {
|
|
u8 y_pos_altered = y_pos-1;
|
|
if(!y_pos)
|
|
y_pos_altered = Y_SIZE-1;
|
|
screen[x_pos+(y_pos_altered*X_SIZE)] = character | (PALETTE << 12);
|
|
#if defined (__NDS__) && (SAME_ON_BOTH_SCREENS)
|
|
screen_sub[x_pos+(y_pos_altered*X_SIZE)] = character | (PALETTE << 12);
|
|
#endif
|
|
}
|
|
|
|
int sub_printf(u8* string) {
|
|
while((*string) != '\0')
|
|
if(write_char(*(string++)))
|
|
return 0;
|
|
return 0;
|
|
}
|
|
|
|
int sub_printf_gen3(u8* string, size_t size_max, u8 is_jp) {
|
|
size_t curr_pos = 0;
|
|
while((*string) != GEN3_EOL) {
|
|
if(is_jp) {
|
|
u8 character = *(string++);
|
|
if((character >= GEN3_FIRST_TICKS_START && character <= GEN3_FIRST_TICKS_END) || (character >= GEN3_SECOND_TICKS_START && character <= GEN3_SECOND_TICKS_END))
|
|
write_above_char(GENERIC_TICKS_CHAR+FONT_TILES);
|
|
else if((character >= GEN3_FIRST_CIRCLE_START && character <= GEN3_FIRST_CIRCLE_END) || (character >= GEN3_SECOND_CIRCLE_START && character <= GEN3_SECOND_CIRCLE_END))
|
|
write_above_char(GENERIC_CIRCLE_CHAR+FONT_TILES);
|
|
if(write_char(character+FONT_TILES))
|
|
return 0;
|
|
}
|
|
else if(write_char(text_gen3_to_general_int_bin[*(string++)]))
|
|
return 0;
|
|
curr_pos++;
|
|
if(curr_pos == size_max)
|
|
return 0;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int prepare_base_10(int number, u8* digits) {
|
|
u16* numbers_storage = (u16*)NUMBERS_POS;
|
|
|
|
for(int i = 0; i < NUM_DIGITS; i++)
|
|
digits[i] = 0;
|
|
u8 pos = NUM_DIGITS-1;
|
|
|
|
u8 minus = 0;
|
|
u8 special = 0;
|
|
if(number < 0){
|
|
minus = 1;
|
|
number = -number;
|
|
if(number < 0) {
|
|
number -= 1;
|
|
special = 1;
|
|
}
|
|
}
|
|
|
|
int mod;
|
|
while(number >= 10000) {
|
|
number = SWI_DivDivMod(number, 10000, &mod);
|
|
for(int i = 0; i < 4; i++)
|
|
digits[pos--] = ((numbers_storage[mod]>>(i*4)) & 0xF) + '0';
|
|
}
|
|
u8 found = 0;
|
|
u8 found_pos = 0;
|
|
for(int i = 0; i < 4; i++) {
|
|
u8 digit = ((numbers_storage[number]>>((3-i)*4)) & 0xF);
|
|
if(digit || found) {
|
|
digits[pos-(3-i)] = digit + '0';
|
|
if(!found)
|
|
found_pos = (3-i);
|
|
found = 1;
|
|
}
|
|
}
|
|
|
|
if(!found)
|
|
digits[pos] = '0';
|
|
|
|
pos -= found_pos;
|
|
|
|
if(minus) {
|
|
pos -= 1;
|
|
digits[pos] = '-';
|
|
if(special)
|
|
digits[NUM_DIGITS-1] += 1;
|
|
}
|
|
|
|
return pos;
|
|
}
|
|
|
|
int prepare_base_16(u32 number, u8* digits) {
|
|
for(int i = 0; i < NUM_DIGITS; i++)
|
|
digits[i] = 0;
|
|
|
|
u8 pos = NUM_DIGITS-1;
|
|
u8 digit;
|
|
while(number >= 0x10) {
|
|
digit = number & 0xF;
|
|
if(digit >= 0xA)
|
|
digit += 'A' - 0xA;
|
|
else
|
|
digit += '0';
|
|
digits[pos--] = digit;
|
|
number >>= 4;
|
|
}
|
|
|
|
digit = number & 0xF;
|
|
if(digit >= 0xA)
|
|
digit += 'A' - 0xA;
|
|
else
|
|
digit += '0';
|
|
digits[pos] = digit;
|
|
|
|
return pos;
|
|
}
|
|
|
|
int digits_print(u8* digits, int max, u8 sub, u8 start_pos) {
|
|
for(int i = NUM_DIGITS-max; i < start_pos; i++)
|
|
if(write_char(sub))
|
|
return 0;
|
|
for(int i = start_pos; i < NUM_DIGITS; i++)
|
|
if(write_char(digits[i]))
|
|
return 0;
|
|
return 0;
|
|
}
|
|
|
|
int write_base_10(int number, int max, u8 sub) {
|
|
u8 digits[NUM_DIGITS];
|
|
u8 start_pos = prepare_base_10(number, digits);
|
|
|
|
return digits_print(digits, max, sub, start_pos);
|
|
}
|
|
|
|
int write_base_16(u32 number, int max, u8 sub) {
|
|
u8 digits[NUM_DIGITS];
|
|
u8 start_pos = prepare_base_16(number, digits);
|
|
|
|
return digits_print(digits, max, sub, start_pos);
|
|
}
|
|
|
|
int fast_printf(const char * format, ... ) {
|
|
set_updated_screen();
|
|
va_list va;
|
|
va_start(va, format);
|
|
int consumed = 0;
|
|
u8 curr_x_pos = 0;
|
|
while((*format) != '\0') {
|
|
u8 character = *format;
|
|
switch(character) {
|
|
case '\x01':
|
|
sub_printf(va_arg(va, u8*));
|
|
break;
|
|
case '\x02':
|
|
write_char((u8)va_arg(va, int));
|
|
break;
|
|
case '\x03':
|
|
write_base_10(va_arg(va, int), 0, 0);
|
|
break;
|
|
case '\x04':
|
|
write_base_16(va_arg(va, u32), 0, 0);
|
|
break;
|
|
case '\x05':
|
|
sub_printf_gen3(va_arg(va, u8*), va_arg(va, size_t), va_arg(va, int));
|
|
break;
|
|
case '\x09':
|
|
write_base_10(va_arg(va, int), va_arg(va, int), ' ');
|
|
break;
|
|
case '\x0B':
|
|
write_base_10(va_arg(va, int), va_arg(va, int), '0');
|
|
break;
|
|
case '\x0C':
|
|
write_base_16(va_arg(va, u32), va_arg(va, int), ' ');
|
|
break;
|
|
case '\x0D':
|
|
write_base_16(va_arg(va, u32), va_arg(va, int), '0');
|
|
break;
|
|
case '\x11':
|
|
curr_x_pos = x_pos;
|
|
sub_printf(va_arg(va, u8*));
|
|
x_pos = curr_x_pos + va_arg(va, int);
|
|
if(x_pos >= X_LIMIT)
|
|
new_line();
|
|
break;
|
|
case '\x13':
|
|
curr_x_pos = x_pos;
|
|
write_base_10(va_arg(va, int), 0, 0);
|
|
x_pos = curr_x_pos + va_arg(va, int);
|
|
if(x_pos >= X_LIMIT)
|
|
new_line();
|
|
break;
|
|
case '\x14':
|
|
curr_x_pos = x_pos;
|
|
write_base_16(va_arg(va, u32), 0, 0);
|
|
x_pos = curr_x_pos + va_arg(va, int);
|
|
if(x_pos >= X_LIMIT)
|
|
new_line();
|
|
break;
|
|
case '\x15':
|
|
curr_x_pos = x_pos;
|
|
sub_printf(va_arg(va, u8*));
|
|
x_pos = curr_x_pos + va_arg(va, int);
|
|
if(x_pos >= X_LIMIT)
|
|
new_line();
|
|
break;
|
|
case '\n':
|
|
new_line();
|
|
break;
|
|
default:
|
|
write_char(character);
|
|
break;
|
|
}
|
|
format++;
|
|
}
|
|
|
|
va_end(va);
|
|
return consumed;
|
|
}
|