@20140602 By LFsWang
#include<cstdio>
#include<easyx.h>
#include<ctime>
#include<Windows.h>
#include<mmsystem.h>
#include<conio.h>
#include<cstdlib>
#include<sstream>
#include<cmath>
//ONLY C++ 11 Support!
#include<thread>
#include<future>
#include<mutex>
#include<chrono>
#pragma comment(lib,"winmm.lib")
#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )
using namespace std;
//Global
mutex Lock;
mutex EndOfProc;
//BASIC Function
bool checkKeyDown(int kb){
USHORT usResult=GetAsyncKeyState(kb);
return usResult==(USHORT)0x8001;
}
void Blur(DWORD* pMem)
{
int WinW=GetSystemMetrics(SM_CXSCREEN);
int WinH=GetSystemMetrics(SM_CYSCREEN)-1;
for(int i = WinW; i < WinW * WinH; i++)
{
pMem[i] = RGB(
(GetRValue(pMem[i]) + GetRValue(pMem[i - WinW]) + GetRValue(pMem[i - 1]) + GetRValue(pMem[i + 1]) + GetRValue(pMem[i + WinW])) / 5,
(GetGValue(pMem[i]) + GetGValue(pMem[i - WinW]) + GetGValue(pMem[i - 1]) + GetGValue(pMem[i + 1]) + GetGValue(pMem[i + WinW])) / 5,
(GetBValue(pMem[i]) + GetBValue(pMem[i - WinW]) + GetBValue(pMem[i - 1]) + GetBValue(pMem[i + 1]) + GetBValue(pMem[i + WinW])) / 5);
}
}
//Advance
char buffer[100];
void update(long t,string s = ""){
cleardevice();
int WinW=GetSystemMetrics(SM_CXSCREEN);
int WinH=GetSystemMetrics(SM_CYSCREEN);
int wordH=textheight("00:00:00");
int wordW=textwidth("00:00:00");
int dx=(WinW-wordW)/2;
int dy=(WinH-wordH)/2;
if(s.size()==0){
int ms=t%CLOCKS_PER_SEC;
t/=CLOCKS_PER_SEC;
long hr=t/3600;t%=3600;
long mi=t/60;t%=60;
long se=t;
sprintf_s(buffer,"%02ld:%02ld:%02ld",hr,mi,se,ms);
outtextxy(dx,dy,buffer);
}else{
outtextxy(dx,dy,s.c_str());
}
FlushBatchDraw();
}
void SetFullScreen(){
HWND hWnd=GetHWnd();
int WinW=GetSystemMetrics(SM_CXSCREEN);
int WinH=GetSystemMetrics(SM_CYSCREEN);
Resize(NULL,WinW,WinH);
SetWindowLong(hWnd,GWL_STYLE,GetWindowLong(hWnd,GWL_STYLE)-WS_CAPTION);
SetWindowPos(hWnd,HWND_TOP,0,0,WinW,WinH,SWP_SHOWWINDOW);
}
void SetFont(){
settextcolor(LIGHTRED);
int WindowsWidth=GetSystemMetrics(SM_CXSCREEN);
int fontsize;
//00:00:00:000
fontsize=(int)(WindowsWidth*0.9/6);
settextstyle(fontsize,0,"Digital-7 Mono");
}
void procFlicker(string s,int limit){
int k=0;
while(k<limit){
if(!EndOfProc.try_lock()){
return ;
}
EndOfProc.unlock();
if(k%6<3){
update(0,s);
}else{
cleardevice();
FlushBatchDraw();
}
k++;
Sleep(100);
}
return ;
}
const int TLE=10800*CLOCKS_PER_SEC;
//const int TLE=10*CLOCKS_PER_SEC;
int StartTime;
int _tmpAdd;
bool pauseFlag=false;
void procClock(){
int E;
int distime;
do{
if(!EndOfProc.try_lock()){
return ;
}
EndOfProc.unlock();
Lock.lock();
E=clock();
distime=E-StartTime;
int tm=TLE-distime;
if(tm<0)tm=0;
if(!pauseFlag){
update(tm);
}
Lock.unlock();
Sleep(20);
}while(distime<TLE||pauseFlag);
}
char GetAvaibleInput(){
if(checkKeyDown('0'))return '0';
if(checkKeyDown('1'))return '1';
if(checkKeyDown('2'))return '2';
if(checkKeyDown('3'))return '3';
if(checkKeyDown('4'))return '4';
if(checkKeyDown('5'))return '5';
if(checkKeyDown('6'))return '6';
if(checkKeyDown('7'))return '7';
if(checkKeyDown('8'))return '8';
if(checkKeyDown('9'))return '9';
if(checkKeyDown('O'))return 'O';
if(checkKeyDown('P'))return 'P';
if(checkKeyDown('Z'))return 'Z';
return 0;
}
int main(){
HWND hWnd;
future<void> task;
future_status::future_status taskStatus;
//Init Graph
hWnd=initgraph(1300,400);
SetFont();
SetFullScreen();
BeginBatchDraw();
//Wait
while(1){
if(checkKeyDown('A')){
break;
}
Sleep(20);
}
Sleep(100);
//Show 88:88:88
task = async(procFlicker,"88:88:88",30);
while(1){
taskStatus = task.wait_for(std::chrono::milliseconds(0));
if(taskStatus == future_status::ready){
task.get();
break;
}
Sleep(100);
}
//Show 03:00:00
update(0,"03:00:00");
while(1){
if(checkKeyDown('B')){
break;
}
Sleep(100);
}
ostringstream oss;
//Main Clock
StartTime=clock();
string cmd;
bool SetCmdFlag=false;
bool Jumpflag=false;
bool JumpLock=false;
int timeAddFlag=1;
int pauseStart=0;
//mulit thread
task=async(procClock);
while(1){
taskStatus = task.wait_for(std::chrono::microseconds(0));
//check if clock finished
if(taskStatus == future_status::ready){
task.get();
break;
}
//GetCommandFlag
if(checkKeyDown('I')){
SetCmdFlag=true;
timeAddFlag=1;
cmd="";
}
if(checkKeyDown('D')){
SetCmdFlag=true;
timeAddFlag=-1;
cmd="";
}
if(checkKeyDown('E')){
Lock.lock();
pauseFlag=!pauseFlag;
if(pauseFlag)
{
pauseStart=clock();
}
else
{
int nowclock=clock();
StartTime+=nowclock-pauseStart;
}
Lock.unlock();
}
if(checkKeyDown('Z')){
if(JumpLock){
Jumpflag=true;
EndOfProc.lock();
task.get();
EndOfProc.unlock();
break;
}
else{
JumpLock=true;
}
}
if(checkKeyDown('P')){//Fail
SetCmdFlag=false;
JumpLock=false;
}
if(SetCmdFlag){
char t=GetAvaibleInput();
if(t=='O'){//run
int ad=atoi(cmd.c_str());
Lock.lock();
StartTime+=ad*CLOCKS_PER_SEC*timeAddFlag;
Lock.unlock();
SetCmdFlag=false;
}
if(isdigit(t)){
cmd.push_back(t);
}
}
Sleep(10);
}
//
if(Jumpflag)
{
int leftTime=TLE- ( clock() - StartTime );
if(leftTime>0)
{
for(int i=4;i>=0;--i)
{
for(int j=99;j>=0;j-=1)
{
int dt=(double)leftTime*( exp( (i+j/100.0)/2.5)-1 )/(exp(2.0)-1);
update(dt);
Sleep(8);
}
}
}
}
//Ending!
task = async(procFlicker,"00:00:00",100000);
while(1){
taskStatus = task.wait_for(std::chrono::milliseconds(0));
if(taskStatus == future_status::ready){
task.get();
break;
}
if(checkKeyDown(VK_ESCAPE)){
EndOfProc.lock();
task.get();
EndOfProc.unlock();
break;
}
Sleep(100);
}
update(0,"00:00:00");
for(int i=0;i<300;++i){
Blur(GetImageBuffer());
FlushBatchDraw();
Sleep(25);
}
EndBatchDraw();
closegraph();
return 0;
}