482 lines
11 KiB
C
Raw Permalink Normal View History

//<2F>Ķ<EFBFBD><C4B6><EFBFBD>Ӧ<EFBFBD><D3A6>
2021-08-10 15:02:33 +08:00
#include "stdio.h"
#include "sys.h"
#include "systick.h"
2021-08-10 15:02:33 +08:00
#include "key.h"
#include "lcd.h"
#include "GameEngine.h"
#include "SD.h"
#include "APP_Reader.h"
/**************************************** ˽<>ж<EFBFBD><D0B6><EFBFBD> ****************************************/
typedef struct
{
FSIZE_t page_ptr;
uint32_t page_size;
} Page; //ҳ<><EFBFBD><E1B9B9><EFBFBD><EFBFBD>
typedef struct
{
uint8_t font_size;
uint32_t page_num;
uint32_t page_amount;
} Save; //<2F><EFBFBD><EFBFBD><E1B9B9><EFBFBD><EFBFBD>
/*****************************************************************************************/
/**************************************** ȫ<>ֱ<EFBFBD><D6B1><EFBFBD> ****************************************/
FIL file; //<2F>ļ<EFBFBD>
char filename[32]; //<2F>ļ<EFBFBD><C4BC><EFBFBD>
char filepath[32]; //<2F>ļ<EFBFBD>·<EFBFBD><C2B7>
FIL page_file; //<2F><>ҳ<EFBFBD>ļ<EFBFBD>
char page_filepath[32]; //<2F><>ҳ<EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>
char page_filename[32]; //<2F><>ҳ<EFBFBD>ļ<EFBFBD>·<EFBFBD><C2B7>
FIL save_file; //<2F><EFBFBD>ļ<EFBFBD>
char save_filepath[32]; //<2F><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>
char save_filename[32]; //<2F><EFBFBD>ļ<EFBFBD>·<EFBFBD><C2B7>
uint32_t page_amount = 1; //ҳ<><D2B3>
uint8_t current_font_size = FONT_24; //<2F><>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
uint32_t current_page = 1; //<2F><>ǰҳ<C7B0><D2B3>
/*****************************************************************************************/
/**************************************** ˽<>к<EFBFBD><D0BA><EFBFBD> ****************************************/
uint8_t APP_Reader_ReadPage(uint8_t font_size, uint32_t page_num);
uint8_t APP_Reader_SplitPages(uint8_t font_size);
uint8_t APP_Reader_Menu(void);
uint8_t APP_Reader_SaveWrite(void);
uint8_t APP_Reader_SaveRead(void);
void APP_Reader_Msg(uint8_t *head, uint8_t *content);
void APP_Reader_Msg_NoBlock(uint8_t *head, uint8_t *content);
2021-08-10 15:02:33 +08:00
/*****************************************************************************************/
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ķ<EFBFBD><EFBFBD><EFBFBD>
*/
void APP_Reader_Launcher(void)
{
//GUI ѡȡ<D1A1>ļ<EFBFBD>
uint8_t ret;
if ((ret = SD_SelectFile(filename, "txt")) != SD_OK)
2021-08-10 15:02:33 +08:00
{
if (ret == SD_ERROR)
APP_Reader_Msg("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "ѡȡ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\n\n<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
2021-08-10 15:02:33 +08:00
return;
}
SD_GetPath(filepath, filename);
//<2F><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>
if (f_open(&file, filepath, FA_OPEN_EXISTING | FA_READ) != FR_OK)
{
APP_Reader_Msg("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\n\n<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
return;
}
//<2F><><EFBFBD>
uint8_t is_saved = 0;
if (APP_Reader_SaveRead() == 0)
is_saved = 1;
uint32_t save_page_amount = page_amount;
//<2F><>ҳ
if (APP_Reader_SplitPages(current_font_size) != 0)
{
APP_Reader_Msg("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "<EFBFBD><EFBFBD>ҳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\n\n<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
return;
}
if (is_saved == 0 || save_page_amount != page_amount)
current_page = 1;
//<2F><>ʼ<EFBFBD>Ķ<EFBFBD>
f_open(&page_file, page_filepath, FA_OPEN_EXISTING | FA_READ); //<2F>򿪷<EFBFBD>ҳ<EFBFBD>ļ<EFBFBD>
while (1)
{
GE_Draw_ClrAll(WHITE);
if (APP_Reader_ReadPage(current_font_size, current_page) != 0)
{
GE_Draw_ClrAll(WHITE);
APP_Reader_Msg("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\n\n<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
return;
}
switch (KEY_GetKeyWait())
{
case JOY_L_UP: //<2F><><EFBFBD>ò˵<C3B2>
2021-08-10 15:02:33 +08:00
{
if (APP_Reader_Menu() != 0)
return;
}
break;
case JOY_D_DOWN: //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҳ
2021-08-10 15:02:33 +08:00
{
if (current_page == page_amount)
APP_Reader_Msg("<EFBFBD><EFBFBD>ʾ", "<EFBFBD>ѵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һҳ<EFBFBD><EFBFBD>");
else
current_page++;
}
break;
case JOY_U_DOWN: //<2F><>ǰ<EFBFBD><C7B0>ҳ
2021-08-10 15:02:33 +08:00
{
if (current_page == 1)
APP_Reader_Msg("<EFBFBD><EFBFBD>ʾ", "<EFBFBD>ѵ<EFBFBD><EFBFBD><EFBFBD>һҳ<EFBFBD><EFBFBD>");
else
current_page--;
}
}
}
}
/**
* @brief <EFBFBD><EFBFBD>ʾijһҳ
* @param font_size: <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С
* @param page_num: ҳ<EFBFBD><EFBFBD><EFBFBD> 1 <EFBFBD><EFBFBD>ʼ
* @retval <EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0<EFBFBD><EFBFBD>ʧ<EFBFBD>ܷ<EFBFBD><EFBFBD><EFBFBD> 1
*/
uint8_t APP_Reader_ReadPage(uint8_t font_size, uint32_t page_num)
{
FRESULT f_res;
uint32_t br;
uint32_t page_br;
Page page;
//<2F><><EFBFBD><EFBFBD>ҳ<EFBFBD><D2B3>Ϣ
f_res = f_lseek(&page_file, (page_num - 1) * sizeof(Page));
f_res = f_read(&page_file, &page, sizeof(Page), &page_br);
//<2F><>ȡ<EFBFBD>ļ<EFBFBD>
uint8_t buffer[1500];
f_res = f_lseek(&file, page.page_ptr);
f_res = f_read(&file, buffer, page.page_size, &br);
if (f_res != FR_OK)
return 1;
*((uint8_t *)buffer + page.page_size) = '\0';
GE_Font_Print(0, 0, BORDER_MAX, BORDER_MAX, font_size, BLACK, WHITE, TRUE, buffer);
2021-08-10 15:02:33 +08:00
GE_Font_Print(
1,
223,
BORDER_MAX,
BORDER_MAX,
FONT_16,
BLUE,
WHITE,
TRUE,
"ҳ<EFBFBD><EFBFBD>:%d/%d %.1f%%",
page_num,
page_amount,
(float)page_num / (float)page_amount * 100.0);
2021-08-10 15:02:33 +08:00
GE_Draw_Disp();
2021-08-10 15:02:33 +08:00
return 0;
}
/**
* @brief <EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD>ҳ
* @param font_size: <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С
* @retval <EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0<EFBFBD><EFBFBD>ʧ<EFBFBD>ܷ<EFBFBD><EFBFBD><EFBFBD> 1
*/
uint8_t APP_Reader_SplitPages(uint8_t font_size)
{
APP_Reader_Msg_NoBlock("<EFBFBD><EFBFBD>ʾ", "<EFBFBD><EFBFBD><EFBFBD>ڷ<EFBFBD>ҳ<EFBFBD><EFBFBD>...\n\n<EFBFBD><EFBFBD><EFBFBD>Ե<EFBFBD>");
2021-08-10 15:02:33 +08:00
uint32_t br;
FRESULT f_res;
char ch;
uint8_t x, y;
Page page;
FSIZE_t fptr = 0;
uint32_t page_bw;
uint8_t x_max, y_max;
if (font_size == FONT_16)
{
x_max = 40;
y_max = 13;
}
else
{
x_max = 26;
y_max = 9;
}
strcpy(page_filename, filename);
strcat(page_filename, ".page");
SD_GetPath(page_filepath, page_filename);
f_res = f_open(&page_file, page_filepath, FA_CREATE_ALWAYS | FA_WRITE);
page_amount = 1;
f_lseek(&file, 0);
page.page_size = 0;
while (1)
{
x = 0;
y = 0;
while (1)
{
if (f_res != FR_OK)
return 1;
f_res = f_read(&file, &ch, 1, &br); //<2F><>һ<EFBFBD><D2BB><EFBFBD>ַ<EFBFBD>
page.page_size++;
if (br == 0) //<2F><>ҳ<EFBFBD><D2B3><EFBFBD><EFBFBD>
{
page.page_ptr = fptr;
f_res = f_write(&page_file, &page, sizeof(Page), &page_bw);
f_res = f_close(&page_file);
if (f_res != FR_OK)
return 1;
else
return 0;
}
if (ch <= 0x80) //ASCII <20>ַ<EFBFBD>
{
if (ch == '\r' || ch == '\0') //<2F><><EFBFBD>Ե<EFBFBD><D4B5>ַ<EFBFBD>
continue;
if ((x + 1 > x_max) || (ch == '\n'))
{
x = 0;
y++;
if (y + 1 > y_max)
{
if (ch != '\n')
f_res = f_lseek(&file, file.fptr - 1);
page.page_size--;
break;
}
}
if (ch != '\n')
x++;
}
else //GBK <20>ַ<EFBFBD>
{
f_res = f_lseek(&file, file.fptr + 1);
page.page_size++;
if (x + 2 > x_max)
{
x = 0;
y++;
if (y + 1 > y_max)
{
f_res = f_lseek(&file, file.fptr - 2);
page.page_size -= 2;
break;
}
}
x += 2;
}
}
page_amount++; //ҳ<><D2B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
page.page_ptr = fptr; //<2F><>ҳ<EFBFBD><D2B3>ʼָ<CABC><D6B8>
f_res = f_write(&page_file, &page, sizeof(Page), &page_bw); //д<><D0B4><EFBFBD><EFBFBD>ҳ<EFBFBD>ļ<EFBFBD>
page.page_size = 0; //ҳ<><D2B3>С<EFBFBD><D0A1><EFBFBD><EFBFBD>
fptr = file.fptr; //<2F><>ҳ<EFBFBD><D2B3>ʼָ<CABC><D6B8>
}
}
/**
* @brief <EFBFBD><EFBFBD><EFBFBD>ò˵<EFBFBD>
* @retval <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ķ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ķ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1
*/
uint8_t APP_Reader_Menu(void)
{
uint8_t content[3][GE_GUI_MENUBOX_CONTENT_LEN] = {"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "<EFBFBD>˳<EFBFBD><EFBFBD>Ķ<EFBFBD><EFBFBD><EFBFBD>", "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>"};
2021-08-10 15:02:33 +08:00
GE_Draw_Fill(50, 50, 220, 140, WHITE);
switch (GE_GUI_MenuBox(50, 50, 220, 140, "<EFBFBD>˵<EFBFBD>", 3, content, NULL))
{
case 0: //<2F><><EFBFBD><EFBFBD>
2021-08-10 15:02:33 +08:00
{
KEY_ClearKey();
}
break;
case 1: //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2021-08-10 15:02:33 +08:00
{
GE_Draw_Fill(50, 50, 220, 140, WHITE);
uint8_t content[2][GE_GUI_MENUBOX_CONTENT_LEN] = {"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "С<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"};
if (GE_GUI_MenuBox(50, 50, 220, 140, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", 2, content, NULL) == 1)
{
if (current_font_size == FONT_24)
{
APP_Reader_Msg("<EFBFBD><EFBFBD>ʾ", "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>ô<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
current_page--;
}
else
{
float read_pos = (float)current_page / (float)page_amount;
current_font_size = FONT_24;
f_close(&page_file);
APP_Reader_SplitPages(current_font_size);
f_open(&page_file, page_filepath, FA_OPEN_EXISTING | FA_READ);
current_page = (float)page_amount * read_pos;
}
}
else
{
if (current_font_size == FONT_16)
{
APP_Reader_Msg("<EFBFBD><EFBFBD>ʾ", "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>С<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
current_page--;
}
else
{
float read_pos = (float)current_page / (float)page_amount;
current_font_size = FONT_16;
f_close(&page_file);
APP_Reader_SplitPages(current_font_size);
f_open(&page_file, page_filepath, FA_OPEN_EXISTING | FA_READ);
current_page = (float)page_amount * read_pos;
}
}
}
break;
case 2: //<2F>˳<EFBFBD>
2021-08-10 15:02:33 +08:00
{
//<2F>ر<EFBFBD><D8B1>ļ<EFBFBD>
f_close(&page_file);
f_close(&file);
APP_Reader_SaveWrite();
return 1;
}
break;
case 3: //<2F><><EFBFBD><EFBFBD>
{
}
2021-08-10 15:02:33 +08:00
}
return 0;
}
/**
* @brief <EFBFBD><EFBFBD><EFBFBD>
* @retval <EFBFBD>д<EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0<EFBFBD><EFBFBD><EFBFBD>޴<EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1
*/
uint8_t APP_Reader_SaveRead(void)
{
uint32_t save_br;
Save save;
strcpy(save_filename, filename);
strcat(save_filename, ".save");
SD_GetPath(save_filepath, save_filename);
if (f_open(&save_file, save_filepath, FA_OPEN_EXISTING | FA_READ) != FR_OK ||
f_read(&save_file, &save, sizeof(Save), &save_br) != FR_OK)
{
f_close(&save_file);
return 1;
}
f_close(&save_file);
if (save.font_size == FONT_16)
current_font_size = FONT_16;
else if (save.font_size == FONT_24)
current_font_size = FONT_24;
else
return 1;
current_page = save.page_num;
page_amount = save.page_amount;
return 0;
}
/**
* @brief д<EFBFBD>
* @retval <EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0<EFBFBD><EFBFBD>ʧ<EFBFBD>ܷ<EFBFBD><EFBFBD><EFBFBD> 1
*/
uint8_t APP_Reader_SaveWrite(void)
{
uint32_t save_bw;
Save save;
save.font_size = current_font_size;
save.page_num = current_page;
save.page_amount = page_amount;
strcpy(save_filename, filename);
strcat(save_filename, ".save");
SD_GetPath(save_filepath, save_filename);
f_open(&save_file, save_filepath, FA_CREATE_ALWAYS | FA_WRITE);
f_write(&save_file, &save, sizeof(Save), &save_bw);
f_close(&save_file);
return 0;
}
/**
* @brief <EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>º<EFBFBD><EFBFBD>˳<EFBFBD>
* @param head: <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param content: <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
void APP_Reader_Msg(uint8_t *head, uint8_t *content)
{
GE_Draw_Fill(60, 75, 200, 90, WHITE);
GE_GUI_MsgBox(60, 75, 200, 90, head, content, NULL);
KEY_WaitKey(JOY_L);
}
/**
* @brief <EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>º<EFBFBD><EFBFBD>˳<EFBFBD>
* @param head: <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param content: <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
void APP_Reader_Msg_NoBlock(uint8_t *head, uint8_t *content)
{
GE_Draw_Fill(60, 75, 200, 90, WHITE);
GE_GUI_MsgBox(60, 75, 200, 90, head, content, NULL);
2021-08-10 15:02:33 +08:00
}