230 lines
5.1 KiB
C
230 lines
5.1 KiB
C
|
|
//<2F><>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>
|
|||
|
|
|
|||
|
|
#include "sys.h"
|
|||
|
|
#include "systick.h"
|
|||
|
|
#include "tim.h"
|
|||
|
|
|
|||
|
|
#include "key.h"
|
|||
|
|
#include "lcd.h"
|
|||
|
|
#include "led.h"
|
|||
|
|
|
|||
|
|
#include "GameEngine.h"
|
|||
|
|
#include "SD.h"
|
|||
|
|
|
|||
|
|
#include "APP_Video.h"
|
|||
|
|
|
|||
|
|
/**************************************** ˽<>ж<EFBFBD><D0B6><EFBFBD> ****************************************/
|
|||
|
|
|
|||
|
|
typedef struct
|
|||
|
|
{
|
|||
|
|
double fps;
|
|||
|
|
uint32_t frame_count;
|
|||
|
|
} VideoInfo; //<2F><>Ƶ<EFBFBD><C6B5>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD>
|
|||
|
|
|
|||
|
|
/*****************************************************************************************/
|
|||
|
|
|
|||
|
|
/**************************************** ȫ<>ֱ<EFBFBD><D6B1><EFBFBD> ****************************************/
|
|||
|
|
|
|||
|
|
FIL video_file; //<2F><>Ƶ<EFBFBD>ļ<EFBFBD>
|
|||
|
|
char video_filename[32]; //<2F><>Ƶ<EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>
|
|||
|
|
char video_filepath[32]; //<2F><>Ƶ<EFBFBD>ļ<EFBFBD>·<EFBFBD><C2B7>
|
|||
|
|
|
|||
|
|
VideoInfo video_info;
|
|||
|
|
|
|||
|
|
volatile uint32_t current_frame = 0;
|
|||
|
|
volatile uint8_t is_to_play = 0;
|
|||
|
|
volatile uint8_t is_disp_progress = 0;
|
|||
|
|
|
|||
|
|
/*****************************************************************************************/
|
|||
|
|
|
|||
|
|
/**************************************** ˽<>к<EFBFBD><D0BA><EFBFBD> ****************************************/
|
|||
|
|
|
|||
|
|
void APP_Video_Play(void);
|
|||
|
|
uint8_t APP_Video_Menu(void);
|
|||
|
|
void APP_Video_Msg(uint8_t *head, uint8_t *content);
|
|||
|
|
|
|||
|
|
/*****************************************************************************************/
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
*/
|
|||
|
|
void APP_Video_Launcher(void)
|
|||
|
|
{
|
|||
|
|
//GUI ѡȡ<D1A1>ļ<EFBFBD>
|
|||
|
|
uint8_t ret;
|
|||
|
|
if ((ret = SD_SelectFile(video_filename, "32v")) != SD_OK)
|
|||
|
|
{
|
|||
|
|
if (ret == SD_ERROR)
|
|||
|
|
APP_Video_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;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
SD_GetPath(video_filepath, video_filename);
|
|||
|
|
|
|||
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>
|
|||
|
|
uint8_t res;
|
|||
|
|
if (res = f_open(&video_file, video_filepath, FA_OPEN_EXISTING | FA_READ) != FR_OK)
|
|||
|
|
{
|
|||
|
|
char temp[10];
|
|||
|
|
sprintf(temp, "%d", res);
|
|||
|
|
APP_Video_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>");
|
|||
|
|
APP_Video_Msg("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", temp);
|
|||
|
|
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//<2F><>ȡ<EFBFBD><C8A1>Ƶ<EFBFBD><C6B5>Ϣ
|
|||
|
|
uint32_t br;
|
|||
|
|
if (f_read(&video_file, &video_info, sizeof(video_info), &br) != FR_OK)
|
|||
|
|
{
|
|||
|
|
APP_Video_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;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (video_info.fps <= 0.0 || video_info.fps > 45.0)
|
|||
|
|
{
|
|||
|
|
APP_Video_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;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//<2F><><EFBFBD>ö<EFBFBD>ʱ<EFBFBD><CAB1>
|
|||
|
|
TIM_Set(TIM2, video_info.fps, 0, 0);
|
|||
|
|
|
|||
|
|
f_lseek(&video_file, 153600);
|
|||
|
|
APP_Video_Play();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ
|
|||
|
|
* @retval <EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0<EFBFBD><EFBFBD>ʧ<EFBFBD>ܷ<EFBFBD><EFBFBD><EFBFBD> 1
|
|||
|
|
*/
|
|||
|
|
void APP_Video_Play(void)
|
|||
|
|
{
|
|||
|
|
uint32_t br;
|
|||
|
|
|
|||
|
|
while (1)
|
|||
|
|
{
|
|||
|
|
if (f_read(&video_file, GE_Draw_VRam, sizeof(GE_Draw_VRam), &br) != FR_OK)
|
|||
|
|
{
|
|||
|
|
APP_Video_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;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
current_frame++;
|
|||
|
|
|
|||
|
|
if (is_disp_progress != 0)
|
|||
|
|
{
|
|||
|
|
GE_Draw_Fill(8, 228, 304, 8, WHITE);
|
|||
|
|
GE_Draw_Rectangle(10, 230, 300, 4, GREEN);
|
|||
|
|
GE_Draw_Rectangle(11, 231, (float)current_frame / (float)video_info.frame_count * 298.0, 2, BLUE);
|
|||
|
|
|
|||
|
|
is_disp_progress++; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0 ʱ<><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
switch (KEY_GetKey())
|
|||
|
|
{
|
|||
|
|
case JOY_R_UP: //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
{
|
|||
|
|
is_disp_progress = !is_disp_progress;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
|
|||
|
|
case JOY_L_UP: //<2F>˵<EFBFBD>
|
|||
|
|
{
|
|||
|
|
//<2F>رն<D8B1>ʱ<EFBFBD><CAB1>
|
|||
|
|
TIM_Set(TIM2, 0, 0, 0);
|
|||
|
|
|
|||
|
|
if (APP_Video_Menu() == 1)
|
|||
|
|
return;
|
|||
|
|
|
|||
|
|
//<2F><EFBFBD>ʱ<EFBFBD><CAB1>
|
|||
|
|
TIM_Set(TIM2, video_info.fps, 0, 0);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
while (is_to_play != 1)
|
|||
|
|
;
|
|||
|
|
|
|||
|
|
GE_Draw_Disp();
|
|||
|
|
is_to_play = 0;
|
|||
|
|
|
|||
|
|
if (br == 0)
|
|||
|
|
{
|
|||
|
|
f_lseek(&video_file, 153600);
|
|||
|
|
current_frame = 0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief <EFBFBD><EFBFBD><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_Video_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>"};
|
|||
|
|
while (1)
|
|||
|
|
{
|
|||
|
|
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>
|
|||
|
|
{
|
|||
|
|
KEY_ClearKey();
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
|
|||
|
|
case 1: //<2F><>Ƶ<EFBFBD><C6B5>Ϣ
|
|||
|
|
{
|
|||
|
|
char str_info[50];
|
|||
|
|
sprintf(str_info, "<EFBFBD><EFBFBD>Ƶ֡<EFBFBD><EFBFBD>: %.2lf\n<EFBFBD><EFBFBD>Ƶʱ<EFBFBD><EFBFBD>: %.2lfs", video_info.fps, (double)video_info.frame_count / video_info.fps);
|
|||
|
|
GE_Draw_Fill(50, 50, 220, 140, WHITE);
|
|||
|
|
GE_GUI_MsgBox(50, 50, 220, 140, "<EFBFBD><EFBFBD>Ƶ<EFBFBD><EFBFBD>Ϣ", str_info, NULL);
|
|||
|
|
|
|||
|
|
KEY_WaitKey(JOY_L);
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
|
|||
|
|
case 2: //<2F>˳<EFBFBD><CBB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
{
|
|||
|
|
f_close(&video_file);
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
|
|||
|
|
case 3: //<2F><><EFBFBD><EFBFBD>
|
|||
|
|
{
|
|||
|
|
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_Video_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 TIM2 <EFBFBD>жϴ<EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
*/
|
|||
|
|
void TIM2_IRQHandler(void)
|
|||
|
|
{
|
|||
|
|
if ((TIM2->SR & TIM_FLAG_UPDATE) != RESET)
|
|||
|
|
{
|
|||
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>±<EFBFBD>־
|
|||
|
|
TIM2->SR = ~TIM_FLAG_UPDATE;
|
|||
|
|
|
|||
|
|
is_to_play = 1;
|
|||
|
|
}
|
|||
|
|
}
|