mirror of
https://github.com/ShadauxCat/CATSFC.git
synced 2025-04-02 10:41:47 -04:00
1315 lines
36 KiB
C
1315 lines
36 KiB
C
/* draw.c
|
|
*
|
|
* Copyright (C) 2010 dking <dking024@gmail.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public Licens e as
|
|
* published by the Free Software Foundation; either version 2 of
|
|
* the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
//v1.1
|
|
|
|
/******************************************************************************
|
|
* draw.cpp
|
|
* basic program to draw some graphic
|
|
******************************************************************************/
|
|
#include "port.h"
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include "ds2_malloc.h"
|
|
#include "ds2_cpu.h"
|
|
#include "bdf_font.h"
|
|
#include "gui.h"
|
|
#include "bitmap.h"
|
|
#include "draw.h"
|
|
|
|
/******************************************************************************
|
|
* macro definition
|
|
******************************************************************************/
|
|
#define progress_sx (screen_width2 - SCREEN_WIDTH / 3) // Center -160/-80
|
|
#define progress_ex (screen_width2 + SCREEN_WIDTH / 3) // Center +160/+80
|
|
#define progress_sy (screen_height2 + 3) // Center +3
|
|
#define progress_ey (screen_height2 + 13) // Center +13
|
|
#define yesno_sx (screen_width2 - SCREEN_WIDTH / 3) // Center -160/-80
|
|
#define yesno_ex (screen_width2 + SCREEN_WIDTH / 3) // Center +160/+80
|
|
#define yesno_sy (screen_height2 + 3) // Center +3
|
|
#define yesno_ey (screen_height2 + 13) // Center +13
|
|
#define progress_color COLOR16(15,15,15)
|
|
|
|
//#define progress_wait (0.5 * 1000 * 1000)
|
|
#define progress_wait (OS_TICKS_PER_SEC/2) //0.5S
|
|
|
|
#define FONTS_HEIGHT 14
|
|
|
|
#define SCREEN_PITCH 256
|
|
|
|
#define VRAM_POS(screen, x, y) ((unsigned short*)screen + (x + (y) * SCREEN_PITCH))
|
|
|
|
#define BOOTLOGO "SYSTEM/GUI/boot.bmp"
|
|
#define GUI_SOURCE_PATH "SYSTEM/GUI"
|
|
#define GUI_PIC_BUFSIZE 1024*512
|
|
|
|
char gui_picture[GUI_PIC_BUFSIZE];
|
|
|
|
struct gui_iconlist gui_icon_list[]= {
|
|
//file system
|
|
/* 00 */ {"zipfile", 16, 16, NULL},
|
|
/* 01 */ {"directory", 16, 16, NULL},
|
|
/* 02 */ {"sfcfile", 16, 16, NULL},
|
|
|
|
//title
|
|
/* 03 */ {"stitle", 256, 33, NULL},
|
|
//main menu
|
|
/* 04 */ {"savo", 52, 52, NULL},
|
|
/* 05 */ {"ssaveo", 52, 52, NULL},
|
|
/* 06 */ {"stoolo", 52, 52, NULL},
|
|
/* 07 */ {"scheato", 52, 52, NULL},
|
|
/* 08 */ {"sother", 52, 52, NULL},
|
|
/* 09 */ {"sexito", 52, 52, NULL},
|
|
/* 10 */ {"smsel", 79, 15, NULL},
|
|
/* 11 */ {"smnsel", 79, 15, NULL},
|
|
|
|
/* 12 */ {"snavo", 52, 52, NULL},
|
|
/* 13 */ {"snsaveo", 52, 52, NULL},
|
|
/* 14 */ {"sntoolo", 52, 52, NULL},
|
|
/* 15 */ {"sncheato", 52, 52, NULL},
|
|
/* 16 */ {"snother", 52, 52, NULL},
|
|
/* 17 */ {"snexito", 52, 52, NULL},
|
|
|
|
/* 18 */ {"sunnof", 16, 16, NULL},
|
|
/* 19 */ {"smaini", 85, 38, NULL},
|
|
/* 20 */ {"snmaini", 85, 38, NULL},
|
|
/* 21 */ {"smaybgo", 256, 192, NULL},
|
|
|
|
/* 22 */ {"sticon", 29, 13, NULL},
|
|
/* 23 */ {"ssubbg", 256, 192, NULL},
|
|
|
|
/* 24 */ {"subsela", 245, 22, NULL},
|
|
/* 25 */ {"sfullo", 12, 12, NULL},
|
|
/* 26 */ {"snfullo", 12, 12, NULL},
|
|
/* 27 */ {"semptyo", 12, 12, NULL},
|
|
/* 28 */ {"snemptyo", 12, 12, NULL},
|
|
/* 29 */ {"fdoto", 16, 16, NULL},
|
|
/* 30 */ {"backo", 19, 13, NULL},
|
|
/* 31 */ {"nbacko", 19, 13, NULL},
|
|
/* 32 */ {"chtfile", 16, 15, NULL},
|
|
/* 33 */ {"smsgfr", 193, 111, NULL},
|
|
/* 34 */ {"sbutto", 76, 16, NULL}
|
|
};
|
|
|
|
u16 COLOR_BG = COLOR16( 0, 0, 0);
|
|
u16 COLOR_INACTIVE_ITEM = COLOR16( 0, 0, 0);
|
|
u16 COLOR_ACTIVE_ITEM = COLOR16(31, 31, 31);
|
|
u16 COLOR_MSSG = COLOR16( 0, 0, 0);
|
|
u16 COLOR_INACTIVE_MAIN = COLOR16(31, 31, 31);
|
|
u16 COLOR_ACTIVE_MAIN = COLOR16(31, 31, 31);
|
|
|
|
|
|
/*
|
|
* Drawing string aroud center
|
|
*/
|
|
void print_string_center(void* screen_addr, u32 sy, u32 color, u32 bg_color, char *str)
|
|
{
|
|
int width = 0;//fbm_getwidth(str);
|
|
u32 sx = (SCREEN_WIDTH - width) / 2;
|
|
|
|
PRINT_STRING_BG(screen_addr, str, color, bg_color, sx, sy);
|
|
}
|
|
|
|
/*
|
|
* Drawing string with shadow around center
|
|
*/
|
|
void print_string_shadow_center(void* screen_addr, u32 sy, u32 color, char *str)
|
|
{
|
|
int width = 0;//fbm_getwidth(str);
|
|
u32 sx = (SCREEN_WIDTH - width) / 2;
|
|
|
|
PRINT_STRING_SHADOW(screen_addr, str, color, sx, sy);
|
|
}
|
|
|
|
/*
|
|
* Drawing horizontal line
|
|
*/
|
|
void drawhline(void* screen_addr, u32 sx, u32 ex, u32 y, u32 color)
|
|
{
|
|
u32 x;
|
|
u32 width = (ex - sx) + 1;
|
|
u16 *dst = VRAM_POS(screen_addr, sx, y);
|
|
|
|
for (x = 0; x < width; x++)
|
|
*dst++ = (u16)color;
|
|
}
|
|
|
|
/*
|
|
* Drawing vertical line
|
|
*/
|
|
void drawvline(void* screen_addr, u32 x, u32 sy, u32 ey, u32 color)
|
|
{
|
|
int y;
|
|
int height = (ey - sy) + 1;
|
|
u16 *dst = VRAM_POS(screen_addr, x, sy);
|
|
|
|
for (y = 0; y < height; y++)
|
|
{
|
|
*dst = (u16)color;
|
|
dst += SCREEN_PITCH;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Drawing rectangle
|
|
*/
|
|
void drawbox(void* screen_addr, u32 sx, u32 sy, u32 ex, u32 ey, u32 color)
|
|
{
|
|
drawhline(screen_addr, sx, ex - 1, sy, color);
|
|
drawvline(screen_addr, ex, sy, ey - 1, color);
|
|
drawhline(screen_addr, sx + 1, ex, ey, color);
|
|
drawvline(screen_addr, sx, sy + 1, ey, color);
|
|
}
|
|
|
|
/*
|
|
* Filling a rectangle
|
|
*/
|
|
void drawboxfill(void* screen_addr, u32 sx, u32 sy, u32 ex, u32 ey, u32 color)
|
|
{
|
|
u32 x, y;
|
|
u32 width = (ex - sx) + 1;
|
|
u32 height = (ey - sy) + 1;
|
|
u16 *dst = VRAM_POS(screen_addr, sx, sy);
|
|
|
|
for (y = 0; y < height; y++)
|
|
{
|
|
for (x = 0; x < width; x++)
|
|
{
|
|
dst[x + y * SCREEN_PITCH] = (u16)color;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Drawing a selection item
|
|
- active 0 not fill
|
|
- 1 fill with gray
|
|
- 2 fill with color
|
|
- 3 fill with color and most brithness
|
|
- color 0 Red
|
|
- 1 Green
|
|
- 2 Blue
|
|
------------------------------------------------------*/
|
|
void draw_selitem(void* screen_addr, u32 x, u32 y, u32 color, u32 active)
|
|
{
|
|
u32 size;
|
|
u32 color0, color1, color2, color3;
|
|
|
|
size= 10;
|
|
|
|
switch(active)
|
|
{
|
|
case 1:
|
|
color0 = COLOR16(12, 12, 12);
|
|
color1 = COLOR16(2, 2, 2);
|
|
color2 = COLOR16(7, 7, 7);
|
|
color3 = COLOR16(22, 22, 22);
|
|
break;
|
|
case 2:
|
|
switch(color)
|
|
{
|
|
case 0: //Red
|
|
color0 = COLOR16(12, 12, 12);
|
|
color1 = COLOR16(8, 0, 0);
|
|
color2 = COLOR16(16, 0, 0);
|
|
color3 = COLOR16(24, 0, 0);
|
|
break;
|
|
case 1: //Green
|
|
color0 = COLOR16(12, 12, 12);
|
|
color1 = COLOR16(0, 8, 0);
|
|
color2 = COLOR16(0, 16, 0);
|
|
color3 = COLOR16(0, 24, 0);
|
|
break;
|
|
case 2: //Blue
|
|
color0 = COLOR16(12, 12, 12);
|
|
color1 = COLOR16(0, 0, 8);
|
|
color2 = COLOR16(0, 0, 16);
|
|
color3 = COLOR16(0, 0, 24);
|
|
break;
|
|
default:
|
|
color0 = COLOR16(12, 12, 12);
|
|
color1 = COLOR16(0, 8, 0);
|
|
color2 = COLOR16(0, 16, 0);
|
|
color3 = COLOR16(0, 24, 0);
|
|
break;
|
|
}
|
|
break;
|
|
case 3:
|
|
switch(color)
|
|
{
|
|
case 0: //Red
|
|
color0 = COLOR16(31, 31, 31);
|
|
color1 = COLOR16(16, 0, 0);
|
|
color2 = COLOR16(22, 0, 0);
|
|
color3 = COLOR16(31, 0, 0);
|
|
break;
|
|
case 1: //Green
|
|
color0 = COLOR16(31, 31, 31);
|
|
color1 = COLOR16(0, 16, 0);
|
|
color2 = COLOR16(0, 22, 0);
|
|
color3 = COLOR16(0, 31, 0);
|
|
break;
|
|
case 2: //Blue
|
|
color0 = COLOR16(31, 31, 31);
|
|
color1 = COLOR16(0, 0, 16);
|
|
color2 = COLOR16(0, 0, 22);
|
|
color3 = COLOR16(0, 0, 31);
|
|
break;
|
|
default:
|
|
color0 = COLOR16(31, 31, 31);
|
|
color1 = COLOR16(0, 16, 0);
|
|
color2 = COLOR16(0, 22, 0);
|
|
color3 = COLOR16(0, 31, 0);
|
|
break;
|
|
}
|
|
break;
|
|
default:
|
|
color0= COLOR16(18, 18, 18);
|
|
color1= color2= color3= COLOR16(18, 18, 18);
|
|
break;
|
|
}
|
|
|
|
drawbox(screen_addr, x, y, x+size-1, y+size-1, color0);
|
|
|
|
if(active >0)
|
|
{
|
|
drawbox(screen_addr, x+1, y+1, x+size-2, y+size-2, color1);
|
|
drawbox(screen_addr, x+2, y+2, x+size-3, y+size-3, color2);
|
|
drawboxfill(screen_addr, x+3, y+3, x+size-4, y+size-4, color3);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Drawing message box
|
|
* Note if color_fg is transparent, screen_bg can't be transparent
|
|
*/
|
|
void draw_message(void* screen_addr, u16 *screen_bg, u32 sx, u32 sy, u32 ex, u32 ey,
|
|
u32 color_fg)
|
|
{
|
|
if(!(color_fg & 0x8000))
|
|
{
|
|
// drawbox(screen_addr, sx, sy, ex, ey, COLOR16(12, 12, 12));
|
|
// drawboxfill(screen_addr, sx+1, sy+1, ex-1, ey-1, color_fg);
|
|
show_icon(screen_addr, &ICON_MSG, (NDS_SCREEN_WIDTH - ICON_MSG.x) / 2, (NDS_SCREEN_HEIGHT - ICON_MSG.y) / 2);
|
|
}
|
|
else
|
|
{
|
|
u16 *screenp, *screenp1;
|
|
u32 width, height, i, k;
|
|
u32 tmp, tmp1, tmp2;
|
|
u32 r, g, b;
|
|
|
|
width= ex-sx;
|
|
height= ey-sy;
|
|
r= ((color_fg >> 10) & 0x1F) * 6/7;
|
|
g= ((color_fg >> 5) & 0x1F) * 6/7;
|
|
b= (color_fg & 0x1F) * 6/7;
|
|
for(k= 0; k < height; k++)
|
|
{
|
|
screenp = VRAM_POS(screen_addr, sx, sy+k);
|
|
screenp1 = screen_bg + sx + (sy + k) * SCREEN_PITCH;
|
|
for(i= 0; i < width; i++)
|
|
{
|
|
tmp = *screenp1++;
|
|
tmp1 = ((tmp >> 10) & 0x1F) *1/7 + r;
|
|
tmp2 = (tmp1 > 31) ? 31 : tmp1;
|
|
tmp1 = ((tmp >> 5) & 0x1F) *1/7 + g;
|
|
tmp2 = (tmp2 << 5) | ((tmp1 > 31) ? 31 : tmp1);
|
|
tmp1 = (tmp & 0x1F) *1/7 + b;
|
|
tmp2 = (tmp2 << 5) | ((tmp1 > 31) ? 31 : tmp1);
|
|
*screenp++ = tmp2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Drawing string horizontal center aligned
|
|
*/
|
|
void draw_string_vcenter(void* screen_addr, u32 sx, u32 sy, u32 width, u32 color_fg, char *string)
|
|
{
|
|
u32 x, num, i, m;
|
|
u16 *screenp;
|
|
u16 unicode[256];
|
|
|
|
num= 0;
|
|
while(*string)
|
|
{
|
|
string= utf8decode(string, unicode+num);
|
|
num++;
|
|
}
|
|
|
|
if(num== 0) return;
|
|
|
|
screenp = (unsigned short*)screen_addr + sx + sy*SCREEN_WIDTH;
|
|
i= 0;
|
|
while(i < num)
|
|
{
|
|
m= BDF_cut_unicode(&unicode[i], num-i, width, 1);
|
|
x= (width - BDF_cut_unicode(&unicode[i], m, 0, 3)) / 2;
|
|
while(m--)
|
|
{
|
|
x += BDF_render16_ucs(screenp+x, SCREEN_WIDTH, 0, COLOR_TRANS,
|
|
color_fg, unicode[i++]);
|
|
}
|
|
if (i < num && (unicode[i] == 0x0D || unicode[i] == 0x0A))
|
|
i++;
|
|
else {
|
|
while (i < num && (unicode[i] == ' ')) i++;
|
|
}
|
|
screenp += FONTS_HEIGHT * SCREEN_WIDTH;
|
|
}
|
|
}
|
|
|
|
/*------------------------------------------------------
|
|
Drawing a scroll string
|
|
------------------------------------------------------*/
|
|
//limited
|
|
// < 256 Unicodes
|
|
// width < 256+128
|
|
//#define MAX_SCROLL_STRING 8
|
|
|
|
/*------------------------------------------------------
|
|
- scroll_val < 0 scroll toward left
|
|
- > 0 scroll toward right
|
|
------------------------------------------------------*/
|
|
struct scroll_string_info{
|
|
u16 *screenp;
|
|
u32 sx;
|
|
u32 sy;
|
|
u32 width;
|
|
u32 height;
|
|
u16 *unicode;
|
|
u32 color_bg;
|
|
u32 color_fg;
|
|
u16 *buff_fonts;
|
|
u32 buff_width;
|
|
u16 *buff_bg;
|
|
s32 pos_pixel;
|
|
u32 str_start;
|
|
u32 str_end;
|
|
u32 str_len;
|
|
};
|
|
|
|
static struct scroll_string_info scroll_strinfo[MAX_SCROLL_STRING];
|
|
static u32 scroll_string_num= 0;
|
|
|
|
/*
|
|
* Initialises a text scroller to display a certain string.
|
|
* Input assertions: sx + width < NDS_SCREEN_WIDTH &&
|
|
* sy + [text height] < NDS_SCREEN_HEIGHT && string != NULL &&
|
|
* screen_addr != NULL.
|
|
* Input: 'screen_addr', the address of the upper-left corner of the screen.
|
|
* 'sx' and 'sy', the X and Y coordinates of the upper-left corner of
|
|
* the text.
|
|
* 'width', the width of the scroller's viewport.
|
|
* 'color_bg', the RGB15 color of the background around the text, or
|
|
* COLOR_TRANS for transparency.
|
|
* 'color_fg', the RGB15 color of the text.
|
|
* 'string', the text to be scrolled, encoded as UTF-8.
|
|
* Output: the scroller's handle, to be used to scroll the text in
|
|
* draw_hscroll.
|
|
*/
|
|
u32 hscroll_init(void* screen_addr, u32 sx, u32 sy, u32 width,
|
|
u32 color_bg, u32 color_fg, char *string)
|
|
{
|
|
u32 index, x, textWidth, num, len, i;
|
|
u16 *unicode, *screenp;
|
|
|
|
// 1. Which scroller should we use for this request?
|
|
for(i= 0; i < MAX_SCROLL_STRING; i++)
|
|
{
|
|
if(scroll_strinfo[i].screenp == NULL)
|
|
break;
|
|
}
|
|
|
|
if(i >= MAX_SCROLL_STRING)
|
|
return -1;
|
|
|
|
index= i;
|
|
|
|
// 2. Convert to Unicode while calculating the width of the text.
|
|
unicode= (u16*)malloc(strlen(string)*sizeof(u16));
|
|
if(unicode == NULL)
|
|
{
|
|
scroll_strinfo[index].str_len = 0;
|
|
return -3;
|
|
}
|
|
|
|
num= 0;
|
|
textWidth = 0;
|
|
while(*string)
|
|
{
|
|
string= utf8decode(string, unicode+num);
|
|
if(unicode[num] != 0x0D && unicode[num] != 0x0A) {
|
|
textWidth += BDF_width16_ucs(unicode[num]);
|
|
num++;
|
|
}
|
|
}
|
|
if (textWidth < width)
|
|
textWidth = width;
|
|
|
|
// 3. Allocate a rectangle of pixels for drawing the entire text into.
|
|
screenp= (u16*)malloc(textWidth*FONTS_HEIGHT*sizeof(u16));
|
|
if(screenp == NULL)
|
|
{
|
|
scroll_strinfo[index].str_len = 0;
|
|
free((void*)unicode);
|
|
return -2;
|
|
}
|
|
|
|
if(color_bg == COLOR_TRANS)
|
|
memset(screenp, 0, textWidth*FONTS_HEIGHT*sizeof(u16));
|
|
|
|
scroll_string_num += 1;
|
|
scroll_strinfo[index].screenp = (unsigned short*)screen_addr;
|
|
scroll_strinfo[index].sx= sx;
|
|
scroll_strinfo[index].sy= sy;
|
|
scroll_strinfo[index].color_bg= color_bg;
|
|
scroll_strinfo[index].color_fg= color_fg;
|
|
scroll_strinfo[index].width= width;
|
|
scroll_strinfo[index].height= FONTS_HEIGHT;
|
|
scroll_strinfo[index].unicode= unicode;
|
|
scroll_strinfo[index].buff_fonts= screenp;
|
|
scroll_strinfo[index].buff_bg= 0;
|
|
scroll_strinfo[index].buff_width= textWidth;
|
|
scroll_strinfo[index].pos_pixel= 0;
|
|
scroll_strinfo[index].str_start= 0;
|
|
scroll_strinfo[index].str_end= len-1;
|
|
|
|
scroll_strinfo[index].str_len= num;
|
|
if(num == 0)
|
|
return index; // (1. Which scroller?)
|
|
|
|
// 4. Render text into the allocation.
|
|
i= 0;
|
|
x= 0;
|
|
while(i < num)
|
|
{
|
|
x += BDF_render16_ucs(screenp + x, textWidth, 0, color_bg, color_fg, unicode[i++]);
|
|
}
|
|
|
|
return index; // (1. Which scroller?)
|
|
}
|
|
|
|
u32 draw_hscroll_init(void* screen_addr, u32 sx, u32 sy, u32 width,
|
|
u32 color_bg, u32 color_fg, char *string)
|
|
{
|
|
u32 ret = hscroll_init(screen_addr, sx, sy, width, color_bg, color_fg, string);
|
|
|
|
draw_hscroll(ret, 0 /* stay on the left */);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* Scrolls an initialised scroller's text.
|
|
* A scroller is never allowed to go past the beginning of the text when
|
|
* scrolling to the left, or to go past the end when scrolling to the right.
|
|
* Input assertions: index was returned by a previous call to
|
|
* draw_hscroll_init and not used in a call to draw_hscroll_over.
|
|
* Input: 'index', the scroller's handle.
|
|
* 'scroll_val', the number of pixels to scroll. The sign affects the
|
|
* direction. If scroll_val > 0, the scroller's viewport is moved to
|
|
* the left; if < 0, the scroller's viewport is moved to the right.
|
|
* Output: the number of pixels still available to scroll in the direction
|
|
* specified by the sign of 'scroll_val'.
|
|
*
|
|
* Example: (assume each letter is 1 pixel; this won't be true in reality)
|
|
* [some lengthy text shown in ] |
|
|
* val -5 -> | [lengthy text shown in a scr]xxxxx -> to right, returns 5
|
|
* val -5 -> | [hy text shown in a scroller] -> to right, returns 0
|
|
* val 3 -> xxxxxxx[ngthy text shown in a scrol] | -> to left, returns 7
|
|
* val 3 -> xxxx[ lengthy text shown in a sc] | -> to left, returns 4
|
|
*/
|
|
u32 draw_hscroll(u32 index, s32 scroll_val)
|
|
{
|
|
u32 color_bg, color_fg, i, width, height;
|
|
s32 xoff;
|
|
|
|
if(index >= MAX_SCROLL_STRING) return -1;
|
|
if(scroll_strinfo[index].screenp == NULL) return -2;
|
|
if(scroll_strinfo[index].str_len == 0) return 0;
|
|
|
|
width= scroll_strinfo[index].width;
|
|
height= scroll_strinfo[index].height;
|
|
color_bg= scroll_strinfo[index].color_bg;
|
|
color_fg= scroll_strinfo[index].color_fg;
|
|
|
|
// 1. Shift the scroller.
|
|
scroll_strinfo[index].pos_pixel -= scroll_val;
|
|
if (scroll_strinfo[index].pos_pixel < 0) // Reached the beginning
|
|
scroll_strinfo[index].pos_pixel = 0;
|
|
else if (scroll_strinfo[index].pos_pixel > scroll_strinfo[index].buff_width - width) // Reached the end
|
|
scroll_strinfo[index].pos_pixel = scroll_strinfo[index].buff_width - width;
|
|
|
|
// 2. Draw the scroller's text at its new position.
|
|
u32 x, sx, sy, pixel;
|
|
u16 *screenp, *screenp1;
|
|
|
|
sx= scroll_strinfo[index].sx;
|
|
sy= scroll_strinfo[index].sy;
|
|
|
|
if(color_bg == COLOR_TRANS)
|
|
{
|
|
for(i= 0; i < height; i++)
|
|
{
|
|
screenp= scroll_strinfo[index].screenp + sx + (sy + i) * SCREEN_WIDTH;
|
|
screenp1= scroll_strinfo[index].buff_fonts + scroll_strinfo[index].pos_pixel + i*scroll_strinfo[index].buff_width;
|
|
for(x= 0; x < width; x++)
|
|
{
|
|
pixel= *screenp1++;
|
|
if(pixel) *screenp = pixel;
|
|
screenp ++;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for(i= 0; i < height; i++)
|
|
{
|
|
screenp= scroll_strinfo[index].screenp + sx + (sy + i) * SCREEN_WIDTH;
|
|
screenp1= scroll_strinfo[index].buff_fonts + scroll_strinfo[index].pos_pixel + i*scroll_strinfo[index].buff_width;
|
|
for(x= 0; x < width; x++)
|
|
*screenp++ = *screenp1++;
|
|
}
|
|
}
|
|
|
|
// 3. Return how many more pixels we can scroll in the same direction.
|
|
if(scroll_val > 0)
|
|
// Scrolling to the left: Return the number of pixels we can still go
|
|
// to the left.
|
|
return scroll_strinfo[index].pos_pixel;
|
|
else
|
|
// Scrolling to the right: Return the number of pixels we can still go
|
|
// to the right.
|
|
return scroll_strinfo[index].buff_width - scroll_strinfo[index].pos_pixel - width;
|
|
}
|
|
|
|
void draw_hscroll_over(u32 index)
|
|
{
|
|
if(scroll_strinfo[index].screenp== NULL)
|
|
return;
|
|
|
|
if(index < MAX_SCROLL_STRING && scroll_string_num > 0)
|
|
{
|
|
if(scroll_strinfo[index].unicode)
|
|
{
|
|
free((void*)scroll_strinfo[index].unicode);
|
|
scroll_strinfo[index].unicode= NULL;
|
|
}
|
|
if(scroll_strinfo[index].buff_fonts)
|
|
{
|
|
free((void*)scroll_strinfo[index].buff_fonts);
|
|
scroll_strinfo[index].buff_fonts= NULL;
|
|
}
|
|
scroll_strinfo[index].screenp= NULL;
|
|
scroll_strinfo[index].str_len= 0;
|
|
|
|
scroll_string_num -=1;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Drawing dialog
|
|
*/
|
|
/*
|
|
void draw_dialog(void* screen_addr, u32 sx, u32 sy, u32 ex, u32 ey)
|
|
{
|
|
drawboxfill(screen_addr, sx + 5, sy + 5, ex + 5, ey + 5, COLOR_DIALOG_SHADOW);
|
|
|
|
drawhline(screen_addr, sx, ex - 1, sy, COLOR_FRAME);
|
|
drawvline(screen_addr, ex, sy, ey - 1, COLOR_FRAME);
|
|
drawhline(screen_addr, sx + 1, ex, ey, COLOR_FRAME);
|
|
drawvline(screen_addr, sx, sy + 1, ey, COLOR_FRAME);
|
|
|
|
sx++;
|
|
ex--;
|
|
sy++;
|
|
ey--;
|
|
|
|
drawhline(screen_addr, sx, ex - 1, sy, COLOR_FRAME);
|
|
drawvline(screen_addr, ex, sy, ey - 1, COLOR_FRAME);
|
|
drawhline(screen_addr, sx + 1, ex, ey, COLOR_FRAME);
|
|
drawvline(screen_addr, sx, sy + 1, ey, COLOR_FRAME);
|
|
|
|
sx++;
|
|
ex--;
|
|
sy++;
|
|
ey--;
|
|
|
|
drawboxfill(screen_addr, sx, sy, ex, ey, COLOR_DIALOG);
|
|
}
|
|
*/
|
|
|
|
/*
|
|
* Draw yes or no dialog
|
|
*/
|
|
u32 draw_yesno_dialog(enum SCREEN_ID screen, u32 sy, char *yes, char *no)
|
|
{
|
|
u16 unicode[8];
|
|
u32 len, width, box_width, i;
|
|
char *string;
|
|
void* screen_addr;
|
|
|
|
len= 0;
|
|
string= yes;
|
|
while(*string)
|
|
{
|
|
string= utf8decode(string, &unicode[len]);
|
|
if(unicode[len] != 0x0D && unicode[len] != 0x0A)
|
|
{
|
|
if(len < 8) len++;
|
|
else break;
|
|
}
|
|
}
|
|
width= BDF_cut_unicode(unicode, len, 0, 3);
|
|
|
|
len= 0;
|
|
string= no;
|
|
while(*string)
|
|
{
|
|
string= utf8decode(string, &unicode[len]);
|
|
if(unicode[len] != 0x0D && unicode[len] != 0x0A)
|
|
{
|
|
if(len < 8) len++;
|
|
else break;
|
|
}
|
|
}
|
|
i= BDF_cut_unicode(unicode, len, 0, 3);
|
|
|
|
if(width < i) width= i;
|
|
box_width= 64;
|
|
if(box_width < (width +6)) box_width = width +6;
|
|
|
|
if(screen & UP_MASK)
|
|
screen_addr = up_screen_addr;
|
|
else
|
|
screen_addr = down_screen_addr;
|
|
|
|
sy = (NDS_SCREEN_HEIGHT + ICON_MSG.y) / 2 - 8 - ICON_BUTTON.y;
|
|
|
|
u32 left_sx = NDS_SCREEN_WIDTH / 2 - 8 - ICON_BUTTON.x,
|
|
right_sx = NDS_SCREEN_WIDTH / 2 + 8;
|
|
|
|
show_icon((unsigned short*)screen_addr, &ICON_BUTTON, left_sx, sy);
|
|
draw_string_vcenter((unsigned short*)screen_addr, left_sx + 2, sy, ICON_BUTTON.x - 4, COLOR_WHITE, yes);
|
|
|
|
show_icon((unsigned short*)screen_addr, &ICON_BUTTON, right_sx, sy);
|
|
draw_string_vcenter((unsigned short*)screen_addr, right_sx + 2, sy, ICON_BUTTON.x - 4, COLOR_WHITE, no);
|
|
|
|
ds2_flipScreen(screen, 2);
|
|
|
|
gui_action_type gui_action = CURSOR_NONE;
|
|
while((gui_action != CURSOR_SELECT) && (gui_action != CURSOR_BACK))
|
|
{
|
|
gui_action = get_gui_input();
|
|
if (gui_action == CURSOR_TOUCH)
|
|
{
|
|
struct key_buf inputdata;
|
|
ds2_getrawInput(&inputdata);
|
|
// Turn it into a SELECT (A) or BACK (B) if the button is touched.
|
|
if (inputdata.y >= sy && inputdata.y < sy + ICON_BUTTON.y)
|
|
{
|
|
if (inputdata.x >= left_sx && inputdata.x < left_sx + ICON_BUTTON.x)
|
|
gui_action = CURSOR_SELECT;
|
|
else if (inputdata.x >= right_sx && inputdata.x < right_sx + ICON_BUTTON.x)
|
|
gui_action = CURSOR_BACK;
|
|
}
|
|
}
|
|
mdelay(16);
|
|
}
|
|
|
|
if (gui_action == CURSOR_SELECT)
|
|
return 1;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Draw hotkey dialog
|
|
* Returns DS keys pressed, as in ds2io.h.
|
|
*/
|
|
u32 draw_hotkey_dialog(enum SCREEN_ID screen, u32 sy, char *clear, char *cancel)
|
|
{
|
|
u16 unicode[8];
|
|
u32 len, width, box_width, i;
|
|
char *string;
|
|
void* screen_addr;
|
|
|
|
len= 0;
|
|
string= clear;
|
|
while(*string)
|
|
{
|
|
string= utf8decode(string, &unicode[len]);
|
|
if(unicode[len] != 0x0D && unicode[len] != 0x0A)
|
|
{
|
|
if(len < 8) len++;
|
|
else break;
|
|
}
|
|
}
|
|
width= BDF_cut_unicode(unicode, len, 0, 3);
|
|
|
|
len= 0;
|
|
string= cancel;
|
|
while(*string)
|
|
{
|
|
string= utf8decode(string, &unicode[len]);
|
|
if(unicode[len] != 0x0D && unicode[len] != 0x0A)
|
|
{
|
|
if(len < 8) len++;
|
|
else break;
|
|
}
|
|
}
|
|
i= BDF_cut_unicode(unicode, len, 0, 3);
|
|
|
|
if(width < i) width= i;
|
|
box_width= 64;
|
|
if(box_width < (width +6)) box_width = width +6;
|
|
|
|
if(screen & UP_MASK)
|
|
screen_addr = up_screen_addr;
|
|
else
|
|
screen_addr = down_screen_addr;
|
|
|
|
i= SCREEN_WIDTH/2 - box_width - 2;
|
|
show_icon((unsigned short*)screen_addr, &ICON_BUTTON, 49, 128);
|
|
draw_string_vcenter((unsigned short*)screen_addr, 51, 130, 73, COLOR_WHITE, clear);
|
|
|
|
i= SCREEN_WIDTH/2 + 3;
|
|
show_icon((unsigned short*)screen_addr, &ICON_BUTTON, 136, 128);
|
|
draw_string_vcenter((unsigned short*)screen_addr, 138, 130, 73, COLOR_WHITE, cancel);
|
|
|
|
ds2_flipScreen(screen, 2);
|
|
|
|
// This function has been started by a key press. Wait for it to end.
|
|
struct key_buf inputdata;
|
|
do {
|
|
mdelay(1);
|
|
ds2_getrawInput(&inputdata);
|
|
} while (inputdata.key != 0);
|
|
|
|
// While there are no keys pressed, wait for keys.
|
|
do {
|
|
mdelay(1);
|
|
ds2_getrawInput(&inputdata);
|
|
} while (inputdata.key == 0);
|
|
|
|
// Now, while there are keys pressed, keep a tally of keys that have
|
|
// been pressed. (IGNORE TOUCH AND LID! Otherwise, closing the lid or
|
|
// touching to get to the menu will do stuff the user doesn't expect.)
|
|
u32 TotalKeys = 0;
|
|
|
|
do {
|
|
TotalKeys |= inputdata.key & ~(KEY_TOUCH | KEY_LID);
|
|
// If there's a touch on either button, turn it into a
|
|
// clear (A) or cancel (B) request.
|
|
if (inputdata.key & KEY_TOUCH)
|
|
{
|
|
if (inputdata.y >= 128 && inputdata.y < 128 + ICON_BUTTON.y)
|
|
{
|
|
if (inputdata.x >= 49 && inputdata.x < 49 + ICON_BUTTON.x)
|
|
return KEY_A;
|
|
else if (inputdata.x >= 136 && inputdata.x < 136 + ICON_BUTTON.x)
|
|
return KEY_B;
|
|
}
|
|
}
|
|
mdelay(1);
|
|
ds2_getrawInput(&inputdata);
|
|
} while (inputdata.key != 0 || TotalKeys == 0);
|
|
|
|
return TotalKeys;
|
|
}
|
|
|
|
/*
|
|
* Drawing scroll bar
|
|
*/
|
|
#define SCROLLBAR_COLOR1 COLOR16( 0, 2, 8)
|
|
#define SCROLLBAR_COLOR2 COLOR16(15,15,15)
|
|
|
|
void scrollbar(void* screen_addr, u32 sx, u32 sy, u32 ex, u32 ey, u32 all, u32 view, u32 now)
|
|
{
|
|
u32 scrollbar_sy;
|
|
u32 scrollbar_ey;
|
|
u32 len;
|
|
|
|
len = ey - sy - 2;
|
|
|
|
if ((all != 0) && (all > now))
|
|
scrollbar_sy = (u32)((float)len * (float)now / (float)all) +sy + 1;
|
|
else
|
|
scrollbar_sy = sy + 1;
|
|
|
|
if ((all > (now + view)) && (all != 0))
|
|
scrollbar_ey = (u32)((float)len * (float)(now + view) / (float)all ) + sy + 1;
|
|
else
|
|
scrollbar_ey = len + sy + 1;
|
|
|
|
drawbox(screen_addr, sx, sy, ex, ey, COLOR_BLACK);
|
|
drawboxfill(screen_addr, sx + 1, sy + 1, ex - 1, ey - 1, SCROLLBAR_COLOR1);
|
|
drawboxfill(screen_addr, sx + 1, scrollbar_sy, ex - 1, scrollbar_ey, SCROLLBAR_COLOR2);
|
|
}
|
|
|
|
#if 0
|
|
static struct background back_ground = {{0}, {0}};
|
|
|
|
int show_background(void *screen, char *bgname)
|
|
{
|
|
int ret;
|
|
|
|
if(strcasecmp(bgname, back_ground.bgname))
|
|
{
|
|
char *buff, *src;
|
|
int x, y;
|
|
unsigned short *dst;
|
|
unsigned int type;
|
|
|
|
buff= (char*)malloc(256*192*4);
|
|
|
|
ret= BMP_read(bgname, buff, 256, 192, &type);
|
|
if(ret != BMP_OK)
|
|
{
|
|
free((int)buff);
|
|
return(-1);
|
|
}
|
|
|
|
src = buff;
|
|
|
|
if(type ==2) //2 bytes per pixel
|
|
{
|
|
unsigned short *pt;
|
|
pt = (unsigned short*)buff;
|
|
// memcpy((char*)back_ground.bgbuffer, buff, 256*192*2);
|
|
dst=(unsigned short*)back_ground.bgbuffer;
|
|
for(y= 0; y< 192; y++)
|
|
{
|
|
for(x= 0; x< 256; x++)
|
|
{
|
|
*dst++= RGB16_15(pt);
|
|
pt += 1;
|
|
}
|
|
}
|
|
}
|
|
else if(type ==3) //3 bytes per pixel
|
|
{
|
|
dst=(unsigned short*)back_ground.bgbuffer;
|
|
for(y= 0; y< 192; y++)
|
|
{
|
|
for(x= 0; x< 256; x++)
|
|
{
|
|
*dst++= RGB24_15(buff);
|
|
buff += 3;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
free((int)buff);
|
|
return(-1);
|
|
}
|
|
|
|
free((int)src);
|
|
strcpy(back_ground.bgname, bgname);
|
|
}
|
|
|
|
memcpy((char*)screen, back_ground.bgbuffer, 256*192*2);
|
|
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
* change GUI icon
|
|
*/
|
|
int gui_change_icon(u32 language_id)
|
|
{
|
|
char path[128];
|
|
char fpath[8];
|
|
u32 i, item;
|
|
int err, ret;
|
|
char *buff, *src;
|
|
u32 x, y;
|
|
char *icondst;
|
|
unsigned int type;
|
|
|
|
item= sizeof(gui_icon_list)/16;
|
|
buff= (char*)malloc(256*192*4);
|
|
if(buff == NULL)
|
|
return -1;
|
|
|
|
ret= 0;
|
|
icondst= gui_picture;
|
|
|
|
sprintf(fpath, "%d.bmp", language_id);
|
|
for(i= 0; i< item; i++)
|
|
{
|
|
sprintf(path, "%s/%s/%s%s", main_path, GUI_SOURCE_PATH, gui_icon_list[i].iconname, fpath);
|
|
|
|
src= buff;
|
|
err= BMP_read(path, src, gui_icon_list[i].x, gui_icon_list[i].y, &type);
|
|
if(err != BMP_OK)
|
|
{
|
|
sprintf(path, "%s/%s/%s%s", main_path, GUI_SOURCE_PATH, gui_icon_list[i].iconname, ".bmp");
|
|
err= BMP_read(path, src, gui_icon_list[i].x, gui_icon_list[i].y, &type);
|
|
}
|
|
|
|
if(type < 2) //< 1 byte per pixels, not surpport now
|
|
{
|
|
if(!ret) ret = -(i+1);
|
|
gui_icon_list[i].iconbuff= NULL;
|
|
continue;
|
|
}
|
|
|
|
if(err == BMP_OK)
|
|
{
|
|
unsigned short *dst;
|
|
|
|
if(icondst >= gui_picture + GUI_PIC_BUFSIZE -1)
|
|
{
|
|
ret = 1;
|
|
break;
|
|
}
|
|
|
|
if(type == 2)
|
|
{
|
|
unsigned short *pt;
|
|
pt = (unsigned short*)src;
|
|
// memcpy((char*)icondst, src, 256*192*2);
|
|
dst = (unsigned short*)icondst;
|
|
for(y= 0; y< gui_icon_list[i].y; y++)
|
|
{
|
|
for(x= 0; x < gui_icon_list[i].x; x++)
|
|
{
|
|
*dst++ = RGB16_15(pt);
|
|
pt += 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(type == 3)
|
|
{
|
|
dst = (unsigned short*)icondst;
|
|
for(y= 0; y< gui_icon_list[i].y; y++)
|
|
{
|
|
for(x= 0; x < gui_icon_list[i].x; x++)
|
|
{
|
|
*dst++ = RGB24_15(src);
|
|
src += 3;
|
|
}
|
|
}
|
|
}
|
|
|
|
gui_icon_list[i].iconbuff= icondst;
|
|
icondst += gui_icon_list[i].x*gui_icon_list[i].y*2;
|
|
}
|
|
else
|
|
{
|
|
if(!ret) ret = -(i+1);
|
|
gui_icon_list[i].iconbuff= NULL;
|
|
}
|
|
}
|
|
|
|
free((void*)buff);
|
|
//printf("icon_buf: %08x\n", icondst - gui_picture );
|
|
return ret;
|
|
}
|
|
|
|
/*************************************************************/
|
|
int icon_init(u32 language_id)
|
|
{
|
|
u32 i;
|
|
int ret;
|
|
|
|
//Initial draw_scroll_string function
|
|
scroll_string_num = 0;
|
|
for(i= 0; i < MAX_SCROLL_STRING; i++)
|
|
{
|
|
scroll_strinfo[i].unicode= NULL;
|
|
scroll_strinfo[i].buff_fonts= NULL;
|
|
scroll_strinfo[i].screenp = NULL;
|
|
scroll_strinfo[i].str_len = 0;
|
|
}
|
|
|
|
ret= gui_change_icon(language_id);
|
|
|
|
//#define GUI_INIT_DEBUG
|
|
#if 0
|
|
item= sizeof(gui_icon_list)/12;
|
|
buff= (char*)malloc(256*192*4);
|
|
src= buff;
|
|
ret= 0;
|
|
icondst= gui_picture;
|
|
|
|
for(i= 0; i< item; i++)
|
|
{
|
|
sprintf(path, "%s\\%s", GUI_SOURCE_PATH, gui_icon_list[i].iconname);
|
|
|
|
err= BMP_read(path, buff, gui_icon_list[i].x, gui_icon_list[i].y);
|
|
if(err == BMP_OK)
|
|
{
|
|
unsigned short *dst;
|
|
|
|
if(icondst >= gui_picture + GUI_PIC_BUFSIZE -1)
|
|
{
|
|
ret = 1;
|
|
#ifdef GUI_INIT_DEBUG
|
|
printf("GUI Initial overflow\n");
|
|
#endif
|
|
break;
|
|
}
|
|
|
|
for(y= 0; y< gui_icon_list[i].y; y++)
|
|
{
|
|
dst= (unsigned short*)(icondst + (gui_icon_list[i].y - y -1)*gui_icon_list[i].x*2);
|
|
for(x= 0; x < gui_icon_list[i].x; x++)
|
|
{
|
|
*dst++ = RGB24_15(buff);
|
|
buff += 4;
|
|
}
|
|
}
|
|
|
|
gui_icon_list[i].iconname= icondst;
|
|
icondst += gui_icon_list[i].x*gui_icon_list[i].y*2;
|
|
}
|
|
else
|
|
if(!ret)
|
|
{
|
|
ret = -(i+1);
|
|
gui_icon_list[i].iconname= NULL;
|
|
#ifdef GUI_INIT_DEBUG
|
|
printf("GUI Initial: %s not open\n", path);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
#ifdef GUI_INIT_DEBUG
|
|
printf("GUI buff %d\n", icondst - gui_picture);
|
|
#endif
|
|
|
|
free((int)src);
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
|
|
int color_init()
|
|
{
|
|
char path[MAX_PATH];
|
|
char current_line[256];
|
|
sprintf(path, "%s/%s/%s", main_path, GUI_SOURCE_PATH, "uicolors.txt");
|
|
FILE* fp = fopen(path, "r");
|
|
if (fp != NULL)
|
|
{
|
|
while(fgets(current_line, 256, fp))
|
|
{
|
|
char* colon = strchr(current_line, ':');
|
|
if (colon)
|
|
{
|
|
*colon = '\0';
|
|
u16* color = NULL;
|
|
if (strcasecmp(current_line, "Background") == 0)
|
|
color = &COLOR_BG;
|
|
else if (strcasecmp(current_line, "ActiveItem") == 0)
|
|
color = &COLOR_ACTIVE_ITEM;
|
|
else if (strcasecmp(current_line, "InactiveItem") == 0)
|
|
color = &COLOR_INACTIVE_ITEM;
|
|
else if (strcasecmp(current_line, "MessageText") == 0)
|
|
color = &COLOR_MSSG;
|
|
else if (strcasecmp(current_line, "ActiveMain") == 0)
|
|
color = &COLOR_ACTIVE_MAIN;
|
|
else if (strcasecmp(current_line, "InactiveMain") == 0)
|
|
color = &COLOR_INACTIVE_MAIN;
|
|
|
|
if (color != NULL)
|
|
{
|
|
char* end = strchr(colon + 1, '\0') - 1;
|
|
while (*end && (*end == '\r' || *end == '\n'))
|
|
*end-- = '\0';
|
|
char* ptr = colon + 1;
|
|
while (*ptr && *ptr == ' ')
|
|
ptr++;
|
|
u32 color32;
|
|
u8 r, g, b;
|
|
if (strlen(ptr) == 7 && *ptr == '#')
|
|
{
|
|
color32 = strtol(ptr + 1, NULL, 16);
|
|
r = (color32 >> 16) & 0xFF;
|
|
g = (color32 >> 8) & 0xFF;
|
|
b = color32 & 0xFF;
|
|
*color = COLOR16(r >> 3, g >> 3, b >> 3);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
fclose(fp);
|
|
return 0;
|
|
}
|
|
else
|
|
return 1;
|
|
}
|
|
|
|
/*************************************************************/
|
|
void show_icon(void* screen, struct gui_iconlist* icon, u32 x, u32 y)
|
|
{
|
|
u32 i, k;
|
|
unsigned short *src, *dst;
|
|
|
|
src= (unsigned short*)icon->iconbuff;
|
|
dst = (unsigned short*)screen + y*NDS_SCREEN_WIDTH + x;
|
|
if(NULL == src) return; //The icon may initialized failure
|
|
|
|
if (icon->x == NDS_SCREEN_WIDTH && icon->y == NDS_SCREEN_HEIGHT && x == 0 && y == 0)
|
|
{
|
|
// Don't support transparency for a background.
|
|
memcpy(dst, src, NDS_SCREEN_WIDTH * NDS_SCREEN_HEIGHT * sizeof(u16));
|
|
}
|
|
else
|
|
{
|
|
for(i= 0; i < icon->y; i++)
|
|
{
|
|
for(k= 0; k < icon->x; k++)
|
|
{
|
|
if(0x03E0 != *src) dst[k]= *src;
|
|
src++;
|
|
}
|
|
|
|
dst += NDS_SCREEN_WIDTH;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*************************************************************/
|
|
void show_Vscrollbar(char *screen, u32 x, u32 y, u32 part, u32 total)
|
|
{
|
|
// show_icon((u16*)screen, ICON_VSCROL_UPAROW, x+235, y+55);
|
|
// show_icon((u16*)screen, ICON_VSCROL_DWAROW, x+235, y+167);
|
|
// show_icon((u16*)screen, ICON_VSCROL_SLIDER, x+239, y+64);
|
|
// if(total <= 1)
|
|
// show_icon((u16*)screen, ICON_VSCROL_BAR, x+236, y+64);
|
|
// else
|
|
// show_icon((u16*)screen, ICON_VSCROL_BAR, x+236, y+64+(part*90)/(total-1));
|
|
}
|
|
|
|
/*
|
|
* display a log
|
|
*/
|
|
void show_log(void* screen_addr)
|
|
{
|
|
char tmp_path[MAX_PATH];
|
|
char *buff;
|
|
int x, y;
|
|
unsigned short *dst;
|
|
unsigned int type;
|
|
int ret;
|
|
|
|
sprintf(tmp_path, "%s/%s", main_path, BOOTLOGO);
|
|
buff= (char*)malloc(256*192*4);
|
|
|
|
ret= BMP_read(tmp_path, buff, 256, 192, &type);
|
|
if(ret != BMP_OK)
|
|
{
|
|
free((void*)buff);
|
|
return;
|
|
}
|
|
|
|
if(type ==2) //2 bytes per pixel
|
|
{
|
|
unsigned short *pt;
|
|
pt = (unsigned short*)buff;
|
|
dst=(unsigned short*)screen_addr;
|
|
for(y= 0; y< 192; y++)
|
|
{
|
|
for(x= 0; x< 256; x++)
|
|
{
|
|
*dst++= RGB16_15(pt);
|
|
pt += 1;
|
|
}
|
|
}
|
|
}
|
|
else if(type ==3) //3 bytes per pixel
|
|
{
|
|
unsigned char *pt;
|
|
pt = (unsigned char*)buff;
|
|
dst=(unsigned short*)screen_addr;
|
|
for(y= 0; y< 192; y++)
|
|
{
|
|
for(x= 0; x< 256; x++)
|
|
{
|
|
*dst++= RGB24_15(pt);
|
|
pt += 3;
|
|
}
|
|
}
|
|
}
|
|
|
|
free((void*)buff);
|
|
}
|
|
|
|
/*************************************************************/
|
|
void err_msg(enum SCREEN_ID screen, char *msg)
|
|
{
|
|
// A wild console appeared!
|
|
ConsoleInit(RGB15(31, 31, 31), RGB15(0, 0, 0), UP_SCREEN, 2);
|
|
printf(msg);
|
|
}
|
|
|
|
/*
|
|
* Copy screen
|
|
*/
|
|
void copy_screen(void* to, void *from, u32 x, u32 y, u32 w, u32 h)
|
|
{
|
|
u32 yy;
|
|
unsigned short *src, *dst;
|
|
|
|
//not check argument
|
|
src = (unsigned short*)from;
|
|
dst = (unsigned short*)to;
|
|
|
|
src += y*256+x;
|
|
dst += y*256+x;
|
|
for(yy= 0; yy < h; yy++)
|
|
{
|
|
memcpy((void*)dst, (void*)src, w*2);
|
|
src += 256;
|
|
dst += 256;
|
|
}
|
|
}
|
|
|
|
/*
|
|
*
|
|
*/
|
|
void blit_to_screen(void* screen_addr, u16 *src, u32 w, u32 h, u32 dest_x, u32 dest_y)
|
|
{
|
|
u32 x, y;
|
|
u16 *dst;
|
|
u16 *screenp;
|
|
|
|
if(w > NDS_SCREEN_WIDTH) w= NDS_SCREEN_WIDTH;
|
|
if(h > NDS_SCREEN_HEIGHT) h= NDS_SCREEN_HEIGHT;
|
|
if(dest_x == -1) //align center
|
|
dest_x= (NDS_SCREEN_WIDTH - w)/2;
|
|
if(dest_y == -1)
|
|
dest_y= (NDS_SCREEN_HEIGHT - h)/2;
|
|
|
|
screenp= (unsigned short*)screen_addr -16*256 -8;
|
|
for(y= 0; y < h; y++)
|
|
{
|
|
dst= screenp + (y+dest_y)*256 + dest_x;
|
|
for(x= 0; x < w; x++)
|
|
*dst++ = *src++;
|
|
}
|
|
}
|