mirror of
https://github.com/rvtr/TwlToolsRED.git
synced 2025-10-31 06:41:18 -04:00
468 lines
9.6 KiB
C
468 lines
9.6 KiB
C
|
||
#include <twl.h>
|
||
#include "text.h"
|
||
|
||
#define TAB_SIZE 8
|
||
#define Y_LINE_VIRTUAL_MAX (Y_LINE_MAX*10)
|
||
/*****************************************************/
|
||
|
||
static LINE_BUF *lb_free_ptr;
|
||
static int x_size = X_LINE_MAX;
|
||
static int y_size = Y_LINE_MAX;
|
||
|
||
void text_display_newline_on(TEXT_CTRL *tc)
|
||
{
|
||
tc->text_buf.display_newline = 1;
|
||
}
|
||
|
||
void text_display_newline_off(TEXT_CTRL *tc)
|
||
{
|
||
tc->text_buf.display_newline = 0;
|
||
}
|
||
|
||
void text_blink_current_line(TEXT_CTRL *tc)
|
||
{
|
||
tc->text_buf.cur->blink_flag = 1;
|
||
}
|
||
|
||
void text_blink_clear(TEXT_CTRL *tc)
|
||
{
|
||
LINE_BUF *lb;
|
||
lb = tc->text_buf.start;
|
||
while( lb != NULL ) {
|
||
lb->blink_flag = 0;
|
||
lb = lb->next;
|
||
}
|
||
}
|
||
|
||
static void link_line_buf(LINE_BUF *m,LINE_BUF *s)
|
||
{
|
||
if( m->next != NULL ) {
|
||
s->next = m->next;
|
||
(s->next)->prev = s;
|
||
}
|
||
else
|
||
s->next = NULL;
|
||
|
||
m->next = s;
|
||
s->prev = m;
|
||
}
|
||
|
||
static void unlink_line_buf(LINE_BUF *s)
|
||
{
|
||
if( (s->prev != NULL ) && (s->next != NULL) ) {
|
||
(s->prev)->next = s->next;
|
||
(s->next)->prev = s->prev;
|
||
s->next = NULL;
|
||
s->prev = NULL;
|
||
}
|
||
else if( s->next != NULL) {
|
||
s->prev = NULL;
|
||
(s->next)->prev = NULL;
|
||
s->next = NULL;
|
||
}
|
||
else if( s->prev != NULL ) {
|
||
s->next = NULL;
|
||
(s->prev)->next = NULL;
|
||
s->prev = NULL;
|
||
}
|
||
}
|
||
|
||
static LINE_BUF *alloc_line_buf(void)
|
||
{
|
||
LINE_BUF *tmp;
|
||
if( lb_free_ptr == NULL ) {
|
||
OS_TPrintf("Error: %s %d\n",__FUNCTION__,__LINE__);
|
||
return NULL;
|
||
}
|
||
if( lb_free_ptr->next == NULL ) {
|
||
OS_TPrintf("Error: %s %d\n",__FUNCTION__,__LINE__);
|
||
return NULL;
|
||
}
|
||
tmp = lb_free_ptr;
|
||
lb_free_ptr = lb_free_ptr->next;
|
||
unlink_line_buf(tmp);
|
||
tmp->last_count = 0;
|
||
tmp->cur_count = 0;
|
||
tmp->blink_flag = 0;
|
||
#if 0
|
||
for(i = 0 ; i < LINE_BUF_X_SIZE ; i++)
|
||
tmp->buf[i] = 0x20;
|
||
#endif
|
||
return(tmp);
|
||
}
|
||
|
||
static void free_line_buf(LINE_BUF *lb)
|
||
{
|
||
lb->next = lb_free_ptr;
|
||
lb->prev = NULL;
|
||
(lb->next)->prev = lb;
|
||
lb_free_ptr = lb;
|
||
}
|
||
|
||
static int init_lb_heap(void *heap_start, void *heap_end)
|
||
{
|
||
int i;
|
||
LINE_BUF *lb_heap=(LINE_BUF *)heap_start;
|
||
lb_free_ptr = (LINE_BUF *)heap_start;
|
||
lb_heap[0].prev = NULL;
|
||
|
||
i = 0;
|
||
while( (u32)&(lb_heap[i+1]) < (u32)heap_end ) {
|
||
link_line_buf(&(lb_heap[i]), &(lb_heap[i+1]));
|
||
i++;
|
||
}
|
||
lb_heap[i].next = NULL;
|
||
return i; /* num of line buffer */
|
||
#if 0
|
||
OS_Printf("text_heap s %08x\n",(u32)heap_start);
|
||
OS_Printf("text_heap e %08x\n",(u32)heap_end);
|
||
#endif
|
||
|
||
}
|
||
|
||
static void init_text_buf(TEXT_BUF *tb)
|
||
{
|
||
tb->num_y = &y_size;
|
||
tb->num_x = &x_size;
|
||
tb->virtual_x = LINE_BUF_X_SIZE - X_LINE_MAX - 1;
|
||
// tb->virtual_y = Y_LINE_MAX * 4;
|
||
tb->virtual_y = Y_LINE_VIRTUAL_MAX;
|
||
tb->start = tb->cur = alloc_line_buf();
|
||
tb->display_offset_y = 0;
|
||
tb->display_offset_x = 0;
|
||
}
|
||
|
||
|
||
void init_text(TEXT_CTRL *tc, u16 *screen, u16 *screen_bg1, u16 palette)
|
||
{
|
||
tc->screen = screen;
|
||
tc->screen_bg1 = screen_bg1;
|
||
tc->x_line = 0;
|
||
tc->y_line = 0;
|
||
tc->palette = palette;
|
||
init_text_buf(&(tc->text_buf));
|
||
}
|
||
|
||
|
||
/*
|
||
0 -> black
|
||
1 -> red
|
||
2 -> green
|
||
3 -> blue
|
||
4 -> yellow
|
||
5 -> purple
|
||
6 -> sky blue
|
||
7 -> red
|
||
8 -> green
|
||
9 -> blue
|
||
0xA -> yellow
|
||
0xB -> purple
|
||
0xC -> sky blue
|
||
0xD -> white
|
||
0xE -> white
|
||
0xF -> white
|
||
|
||
*/
|
||
|
||
void m_set_palette(TEXT_CTRL *tc, u16 num)
|
||
{
|
||
tc->palette = (u16)(0x0f & num);
|
||
}
|
||
|
||
u16 m_get_palette(TEXT_CTRL *tc)
|
||
{
|
||
return tc->palette;
|
||
}
|
||
|
||
void m_set_display_offset_x(TEXT_CTRL *tc, int offset)
|
||
{
|
||
TEXT_BUF *tb = &(tc->text_buf);
|
||
if( ( offset >= 0 ) && (offset < tb->virtual_x) ) {
|
||
tb->display_offset_x = offset;
|
||
}
|
||
}
|
||
|
||
int m_get_display_offset_x(TEXT_CTRL *tc)
|
||
{
|
||
TEXT_BUF *tb = &(tc->text_buf);
|
||
return tb->display_offset_x;
|
||
}
|
||
|
||
void m_set_display_offset_y(TEXT_CTRL *tc, int offset)
|
||
{
|
||
TEXT_BUF *tb = &(tc->text_buf);
|
||
LINE_BUF *lb = tb->cur;
|
||
int line_count = 0;
|
||
while( lb != NULL ) {
|
||
line_count++;
|
||
lb = lb->prev;
|
||
}
|
||
if( ( offset >= 0 ) && (offset < line_count - Y_LINE_MAX ) ) {
|
||
tb->display_offset_y = offset;
|
||
}
|
||
}
|
||
|
||
int m_get_display_offset_y(TEXT_CTRL *tc)
|
||
{
|
||
TEXT_BUF *tb = &(tc->text_buf);
|
||
return tb->display_offset_y;
|
||
}
|
||
|
||
static void clear_line(TEXT_CTRL *tc)
|
||
{
|
||
int i;
|
||
i = tc->x_line;
|
||
|
||
for( ; i < X_LINE_MAX ; i++)
|
||
tc->screen[(tc->y_line * X_LINE_MAX ) + i] = 0;
|
||
|
||
}
|
||
|
||
static void add_y_line(TEXT_CTRL *tc,u16 num)
|
||
{
|
||
tc->y_line += num;
|
||
if( tc->y_line > Y_LINE_MAX ) {
|
||
tc->y_line = 0;
|
||
}
|
||
}
|
||
|
||
static void add_x_line(TEXT_CTRL *tc,u16 num)
|
||
{
|
||
tc->x_line += num;
|
||
|
||
if( tc->x_line > X_LINE_MAX ) {
|
||
tc->x_line = 0;
|
||
tc->y_line++;
|
||
if( tc->y_line > Y_LINE_MAX ) {
|
||
tc->y_line = 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
static void put_char_vram(TEXT_CTRL *tc, int c, u16 col)
|
||
{
|
||
|
||
switch( c ) {
|
||
case '\0':
|
||
break;
|
||
case '\n':
|
||
clear_line(tc);
|
||
tc->x_line = 0;
|
||
add_y_line(tc, 1 );
|
||
break;
|
||
case '\r':
|
||
tc->x_line = 0;
|
||
break;
|
||
case '\t':
|
||
add_x_line(tc, TAB_SIZE );
|
||
break;
|
||
case '\f':
|
||
tc->x_line = 0;
|
||
tc->y_line = 0;
|
||
clear_line(tc);
|
||
break;
|
||
case '\b': /* Back Space */
|
||
case '\v': /* Vertical Tab */
|
||
break;
|
||
default:
|
||
if( ( c < 0x20 ) || ( 0x7f < c ) )
|
||
c = 0x20; /* white space */
|
||
tc->screen[(tc->y_line * X_LINE_MAX ) + tc->x_line] = (u16)((col << 12) | (0x00ff & c));
|
||
add_x_line(tc, 1 );
|
||
}
|
||
}
|
||
|
||
/**********************/
|
||
|
||
void m_putchar(TEXT_CTRL *tc, int c)
|
||
{
|
||
int i;
|
||
LINE_BUF *tmp;
|
||
TEXT_BUF *tb = &(tc->text_buf);
|
||
|
||
switch( c ) {
|
||
case '\0':
|
||
break;
|
||
case '\n':
|
||
if( tb->cur->next == NULL ) {
|
||
tmp = tb->cur; /* <20>\<5C><><EFBFBD>J<EFBFBD>n<EFBFBD>o<EFBFBD>b<EFBFBD>t<EFBFBD>@<40><><EFBFBD>Čv<C48C>Z */
|
||
for(i = 0 ; (i < *(tb->num_y)-1) && (i < LINE_BUF_Y_SIZE) ; i++) {
|
||
if( tmp->prev == NULL )
|
||
break;
|
||
tmp = tmp->prev;
|
||
}
|
||
tb->start = tmp; /* <20>\<5C><><EFBFBD>J<EFBFBD>n<EFBFBD>o<EFBFBD>b<EFBFBD>t<EFBFBD>@ */
|
||
|
||
/* <20><><EFBFBD><EFBFBD><EFBFBD>Ȃ<EFBFBD><C882>o<EFBFBD>b<EFBFBD>t<EFBFBD>@<40><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>A<EFBFBD><41><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ۑ<EFBFBD><DB91>p<EFBFBD>o<EFBFBD>[<5B>`<60><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͎c<CD8E><63> */
|
||
i = 0;
|
||
while(tmp->prev != NULL) {
|
||
tmp = tmp->prev;
|
||
i++;
|
||
if( i > tb->virtual_y-1 ) {
|
||
unlink_line_buf( tmp );
|
||
free_line_buf( tmp );
|
||
}
|
||
}
|
||
|
||
tmp = alloc_line_buf(); /* <20>o<EFBFBD>b<EFBFBD>t<EFBFBD>@<40><><EFBFBD>P<EFBFBD>擾 */
|
||
if( tmp == NULL ) {
|
||
/* <20><><EFBFBD>C<EFBFBD><43><EFBFBD>o<EFBFBD>b<EFBFBD>t<EFBFBD>@<40><><EFBFBD>Ȃ<EFBFBD> */
|
||
OS_TPrintf("Free line buffer shortage!!\n");
|
||
return;
|
||
}
|
||
link_line_buf(tb->cur, tmp); /* <20>擾<EFBFBD><E693BE><EFBFBD><EFBFBD><EFBFBD>o<EFBFBD>b<EFBFBD>t<EFBFBD>@<40><><EFBFBD>J<EFBFBD><4A><EFBFBD><EFBFBD><EFBFBD>g
|
||
<20>o<EFBFBD>b<EFBFBD>t<EFBFBD>@<40>̎<EFBFBD><CC8E>Ƀ<EFBFBD><C983><EFBFBD><EFBFBD>N */
|
||
tb->cur = tmp; /* <20>J<EFBFBD><4A><EFBFBD><EFBFBD><EFBFBD>g<EFBFBD>o<EFBFBD>b<EFBFBD>t<EFBFBD>@<40><><EFBFBD>X<EFBFBD>V */
|
||
tb->cur->cur_count = 0;
|
||
tb->cur->last_count = 0;
|
||
}
|
||
else {
|
||
tb->cur = tb->cur->next;
|
||
tb->cur->cur_count = 0;
|
||
tb->cur->last_count = 0;
|
||
}
|
||
break;
|
||
case '\r':
|
||
tb->cur->cur_count = 0;
|
||
break;
|
||
case '\t':
|
||
tb->cur->cur_count += TAB_SIZE;
|
||
if( tb->cur->cur_count > LINE_BUF_X_SIZE )
|
||
tb->cur->cur_count = LINE_BUF_X_SIZE;
|
||
if( tb->cur->cur_count > tb->cur->last_count )
|
||
tb->cur->last_count = tb->cur->cur_count;
|
||
break;
|
||
case '\f':
|
||
tb->cur = tb->start;
|
||
tb->cur->cur_count = 0;
|
||
tb->cur->last_count = 0;
|
||
break;
|
||
case '\a': /* BELL */
|
||
break;
|
||
case '\b': /* Back Space */
|
||
if( tb->cur->cur_count > 0 )
|
||
tb->cur->cur_count--;
|
||
break;
|
||
case '\v': /* Vertical Tab */
|
||
break;
|
||
default:
|
||
if( tb->cur->cur_count >= LINE_BUF_X_SIZE ) {
|
||
/* add 2008.08.14 */
|
||
/* <20><><EFBFBD>C<EFBFBD><43><EFBFBD>o<EFBFBD>b<EFBFBD>t<EFBFBD>@<40><><EFBFBD>I<EFBFBD>[<5B>o<EFBFBD>[<5B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̋<EFBFBD><CC8B><EFBFBD> */
|
||
if( tb->display_newline == 0 ) {
|
||
/* <20>\<5C><><EFBFBD><EFBFBD><EFBFBD>Ȃ<EFBFBD> */
|
||
break;
|
||
}
|
||
else {
|
||
/* <20><><EFBFBD>s<EFBFBD><73><EFBFBD>ĕ\<5C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
||
m_putchar(tc, '\n');
|
||
}
|
||
}
|
||
tb->cur->buf[tb->cur->cur_count] = c;
|
||
tb->cur->col[tb->cur->cur_count] = tc->palette;
|
||
tb->cur->cur_count++;
|
||
if( tb->cur->cur_count > LINE_BUF_X_SIZE ) {
|
||
tb->cur->cur_count = LINE_BUF_X_SIZE;
|
||
break;
|
||
}
|
||
if( tb->cur->cur_count > tb->cur->last_count )
|
||
tb->cur->last_count = tb->cur->cur_count;
|
||
break;
|
||
}
|
||
}
|
||
|
||
|
||
int init_text_buf_sys(void *heap_start, void *heap_end)
|
||
{
|
||
return init_lb_heap(heap_start, heap_end);
|
||
}
|
||
|
||
static int blink_counter = 0;
|
||
static int blink_flag = 0;
|
||
|
||
void text_buf_to_vram(TEXT_CTRL *tc)
|
||
{
|
||
int x_line,line_no;
|
||
int c;
|
||
u16 col;
|
||
int i;
|
||
LINE_BUF *lb;
|
||
TEXT_BUF *tb = &(tc->text_buf);
|
||
|
||
blink_counter++;
|
||
|
||
/* blink interval */
|
||
if( blink_flag == 1 ) {
|
||
if( blink_counter > 100 ) {
|
||
blink_counter = 0;
|
||
blink_flag ^= 1;
|
||
}
|
||
}
|
||
else {
|
||
if( blink_counter > 20 ) {
|
||
blink_counter = 0;
|
||
blink_flag ^= 1;
|
||
}
|
||
}
|
||
|
||
lb = tb->start;
|
||
i = 0;
|
||
while( i < tb->display_offset_y ) {
|
||
if( lb->prev == NULL ) {
|
||
break;
|
||
}
|
||
lb = lb->prev;
|
||
i++;
|
||
}
|
||
|
||
|
||
put_char_vram(tc, '\f', (u16)0);
|
||
|
||
for(line_no = 0 ; line_no < *tb->num_y ; line_no++ ){
|
||
//miya x_line = 0;
|
||
x_line = tb->display_offset_x;
|
||
|
||
if( lb == NULL)
|
||
break;
|
||
while( x_line < lb->last_count ) {
|
||
//miya 2008.09.10
|
||
// if( x_line >= (*tb->num_x + 1)) {
|
||
if( x_line >= (*tb->num_x + 1 + tb->display_offset_x)) {
|
||
break;
|
||
}
|
||
else {
|
||
if( lb->blink_flag ) {
|
||
if( blink_flag == 0 ) {
|
||
c = 0;
|
||
col = 0;
|
||
}
|
||
else {
|
||
c = lb->buf[x_line];
|
||
col = lb->col[x_line];
|
||
}
|
||
}
|
||
else {
|
||
c = lb->buf[x_line];
|
||
col = lb->col[x_line];
|
||
}
|
||
put_char_vram(tc, c, col);
|
||
|
||
}
|
||
x_line++;
|
||
}
|
||
//miya 2008.09.10
|
||
// if( x_line <= *tb->num_x ) {
|
||
if( x_line <= *tb->num_x + tb->display_offset_x ) {
|
||
put_char_vram(tc, '\n', (u16)0);
|
||
}
|
||
lb = lb->next;
|
||
}
|
||
|
||
for( ; line_no < *tb->num_y ; line_no++ ) {
|
||
put_char_vram(tc, '\n', (u16)0);
|
||
}
|
||
}
|
||
|
||
|