html5單頁網(wǎng)站天津關鍵詞優(yōu)化網(wǎng)站
寫在前面:這是我在學習了一個學期的《30天自制操作系統(tǒng)》之后,用了差不多一個周的時間,所寫出來的一個紙娃娃操作系統(tǒng),有一個小的開機動畫,可以輸入密碼,然后有一個小的畫圖程序。現(xiàn)在把他寫出來,只是為了記錄這一個學期的學習經(jīng)歷吧,至少證明自己學有所成,所有所獲。
一、實驗環(huán)境
硬件環(huán)境:計算機,無特殊配置要求
軟件環(huán)境:QEMU虛擬機、批處理文件、相關編譯工具等
語言環(huán)境:C語言、匯編語言
二、功能介紹及運行效果截圖
1、開機:
a、通過使用定時器timer3實現(xiàn)對時間的嚴格把控
每0.1秒向緩沖區(qū)發(fā)送一個“1”
b、通過定義圖層,實現(xiàn)開機動畫
每一個圖層都是開機動畫的一幀,都是由一個85x80的數(shù)組實現(xiàn)的,寫在我新建立的start.c文件中,通過不同的符號表示不同的顏色,來實現(xiàn)一張圖案的繪制,多個圖案連在一起,就構成了一段開機動畫,并且可以色彩變換:
c、首先定義圖層的級別,最先要展示的圖層設置為0級,其余的圖層設置為-1級進行隱藏。同時,將每個圖層的位置設置為(0,0)左上角。
然后,通過一個while死循環(huán),跳出循環(huán)的條件是我所設置的一個標志量flagtime為10,而flagtime會在每次timer3向緩沖區(qū)輸入一個1的時候進行增加,并且每0.6秒增加一次,然后根據(jù)不同的flagtime的值,來將不同的圖層的級別設置為1,表示進行展示,而將當前的圖層設置為-1,即進行隱藏
就可以設置一個長達6秒的開機動畫。
d、在開機動畫結束后,注意要將當前圖層設置為隱藏的-1級別,而將我們下面要用的密碼圖層設置為1展示級別
由于為了讓我的動畫更炫酷一點,我增加了一個圓形的加載形式
并且,因為如果將所有的代碼放到bootpack.c文件中,代碼會運行的很慢,所以我在start.c文件中實現(xiàn)了對所有的開機動畫圖層的初始化:
而增加的一個圓形的加載,是在這里實現(xiàn)的
可以實現(xiàn)一個類似于圓形加載的效果,只不過更炫酷一點
效果如下:
然后,為了能夠比較平滑的連接到密碼輸入界面,我需要考慮如何將這個開機動畫回歸到黑色的界面。
首先,加一個劍的移動的函數(shù)分支:
增加了這個函數(shù)分支之后,隨著我給的時間表胡子良flagtime(在函數(shù)中為形參t)隨時間增大,將會進入50的分支,進入該分支后,將會對劍圖案的位置進行移動。
同時,需要對圓環(huán)的位置進行移動,增加一個分支:
通過這個分支,可以實現(xiàn)圓環(huán)的移動。
僅僅移動是不夠的,我還要實現(xiàn)退出,在這里做一個雪花飄落的樣子,就是增加如下的函數(shù)分支:
通過取余操作,可以實現(xiàn)類似于雪花的效果,最終結果如下所示:
2、輸入密碼:
a、首先通過字符數(shù)組的形式定義一個正確的賬號和密碼:
b、再定義另外兩個字符數(shù)組用來存儲我們所輸入的字符
c、在一個while死循環(huán)內(nèi),跳出循環(huán)的條件是標志量flagkaiji為1,即輸入正確的賬號和密碼并且同時按下了回車鍵。
首先會對緩沖區(qū)進行判斷,如果緩沖區(qū)中有值并且這個值在256到511之間,表示此時是鍵盤輸出產(chǎn)生的中斷,然后我們對中斷進行判斷,用sprintf函數(shù)將整型數(shù)據(jù)轉換為兩位十六進制類型,然后用我寫的panduan函數(shù)進行判斷是什么按鍵被按下:
如果按下的按鍵并不是break或者是shift這種功能鍵,就進行判斷。
如果是回車鍵,需要通過strcmp函數(shù)判斷當前輸入的字符串與正確的字符串,如果相等就對標志量flagkaiji進行賦值為1,并將當前的密碼圖層設置為隱藏的-1級別。
如果不相等,需要判斷有沒有輸完,如果只是輸完了賬號一欄,說明我們還需要輸入密碼一欄,將我們的輸入位置j和h調(diào)整為密碼欄的位置即可:
如果已經(jīng)輸入完全了,說明此時輸入者并不知道密碼是什么,或者說輸入的密碼和賬號是錯誤的,這里就可以將輸入欄和密碼欄進行刷新,然后將輸入為止重新進行調(diào)整為開頭,并輸出一行提示錯誤的字符串“passwords error!!!”,注意,還需要將我們的存儲數(shù)組進行清空。
最終結果如下:
輸入密碼界面:
如果輸入錯誤的界面,會出現(xiàn)叉號,并可以重新輸入:
重新輸入正確的密碼則會開機,同樣的,在這里設計了一個比較厲害的動畫:
4、程序:
這里我的程序是直接使用的節(jié)點考試時所編寫的畫圖程序,實現(xiàn)功能很多,這里會直接根據(jù)我的主函數(shù),花費大量篇幅進行講解,每一個功能會進行標紅加粗處理:
if (flagshuangji == 0) {shuangji++;}if (shuangji == 10000) {flagshuangji = 1;shuangji = 0;}sprintf(s, "%010d", shuangji);sheet_refresh(sht_back, 100, 80, 320, 100);
這是我用來判斷雙擊和函數(shù),通過標志量flagshaungji的值來表示兩次鼠標左鍵點擊之間的時間間隔,如果時間間隔足夠小,說明是雙擊。
io_cli();//關閉終端if (fifo32_status(&fifo) == 0) { io_sti();//如果緩沖區(qū)為空則開啟中斷} else {//如果緩沖區(qū)不為空,說明有服務請求運行,或者有中斷發(fā)生i = fifo32_get(&fifo);//取出緩沖區(qū)的值,進行判斷io_sti();if (256 <= i && i <= 511) { //如果是鍵盤操作sprintf(s, "%02X", i - 256);putfonts8_asc_sht(sht_back, 0, 16, COL8_FFFFFF, COL8_008484, s, 2);
panduan(s);
功能1、鍵盤輸入:可以通過鍵盤輸入字符,通過我自己編寫的panduan函數(shù)判斷所按下的按鍵是哪一個按鍵,并作出相應的操作
if (strcmp(sss, "break") != 0 && strcmp(sss, "left shift") != 0 && strcmp(sss, "return") != 0 && flagwenben == 2 && flagguanbi == 0) {if (strcmp(sss, "hc") == 0) {boxfill8(buf_bigwin, binfo->scrnx, dise, j + 3, 16 * (h), j + 3, 16 * (h + 1) - 1);jj[h] = j;h = h + 1;if (h >= binfo->scrny/16-1) {h = binfo->scrny/16-1;}j = wbj;boxfill8(buf_bigwin, binfo->scrnx, zise, j + 3, 16 * (h), j + 3, 16 * (h + 1) - 1);}
/*如果按下的是回車鍵,那么需要實現(xiàn)換行操作,同時記錄當前光標的位置,為下面的刪除鍵操作做鋪墊*/else if (strcmp(sss, "tg") == 0) {boxfill8(buf_bigwin, binfo->scrnx, dise, j + 3, 16 * (h), j + 3, 16 * (h + 1) - 1);j = j - 8*zihao;if (j < wbj) {h = h - 1;if (h < 2) {h = 2;j = wbj;}else {if (jj[h] <= wbj) {j = wbj;}else {if (jj[h] <= wbj) {j = wbj;}else {j = jj[h];}}}}boxfill8(buf_bigwin, binfo->scrnx, dise, j + 3, 16 * h, j + 3 + 8*zihao, 16 * h + 16);boxfill8(buf_bigwin, binfo->scrnx, zise, j + 3, 16 * (h), j + 3, 16 * (h + 1) - 1);}
/*如果按下的是刪除鍵,那么就對前一個字符的位置(8*16像素)進行背景色的填充處理,但需要判斷的是是否需要返回上一行,如果是則取出之前在回車處理中所存儲的jj數(shù)組的相應位置的值*/else if (strcmp(sss, "dx") == 0) {flagdx = !flagdx;}
/*如果按下的是大小寫切換鍵,那么就需要將標志量設置為相反的,以便為下面的輸出做準備*/else {boxfill8(buf_bigwin, binfo->scrnx, dise, j + 3, 16 * h, j + 3 + 8*zihao, 16 * h + 16);if (flagdx == 0) {dahuaxiao(sss);}putfonts8_num(buf_bigwin, binfo->scrnx, j + 3, 16 * h, zise, sss,zihao);j = j + 8*zihao;if (j >= binfo->scrnx-5) {jj[h] = j - 8*zihao;h = h + 1;if (jj[h] <= wbj) {j = wbj;}else {j = jj[h];}}boxfill8(buf_bigwin, binfo->scrnx, zise, j + 3, 16 * h, j + 3, 16 * h + 16 - 1);}}sheet_refresh(sht_bigwin, 0, 0, binfo->scrnx, binfo->scrny-20);}
/*如果是正常的按鍵輸入,那么就通過我所寫的函數(shù)進行字符的打印輸出,這里就是我實現(xiàn)的第二個功能:*/
功能2、改變字號:通過我專門編寫的putfonts8_num函數(shù),可以輸出不同字號的字符,打印在相應的位置,要注意的是需要判斷是否需要換行
else if (512 <= i && i <= 767) { //如果是鼠標操作if (mouse_decode(&mdec, i - 512) != 0) {sprintf(s, "[lcr %4d %4d]", mdec.x, mdec.y);//打印鼠標的位置if ((mdec.btn & 0x01) != 0) {s[1] = 'L';}//判斷按鍵狀態(tài)if ((mdec.btn & 0x02) != 0) {s[3] = 'R';}if ((mdec.btn & 0x04) != 0) {s[2] = 'C';}putfonts8_asc_sht(sht_back, 32, 16, COL8_FFFFFF, COL8_008484, s, 15);
功能3、正常窗口拖動:可以拖動正常大?。?80x140像素)的窗口,并且和鼠標一樣,左邊和上邊不能出界,下邊和右邊可以出界
if ((wx + 0 <= mx && mx <= wx + 120 && wy + 3 <= my && my <= wy + 20) && flag2 == 1 && flag == 1 && (mdec.btn & 0x01) != 0 && flagguanbi == 0) {//如果鼠標在窗口任務欄位置發(fā)生了點擊并移動的操作mx += mdec.x;my += mdec.y;wx += mdec.x;wy += mdec.y;}
功能4、正常窗口畫細線:可以在正常大小的窗口中實現(xiàn)畫細線的操作,并且限定了畫線的范圍,隨著鼠標的移動和點擊,實現(xiàn)畫線操作
else if ((wx + 5 <= mx && mx <= wx + 175 && wy + 25 <= my && my <= wy + 135) && flag2 == 1 && flag == 1 && flagxiangpi == 0 && flagcu == 0 && flagguanbi == 0 && flagquse == 0 && flagtianchong == 0) {//如果鼠標在窗口的范圍內(nèi)并且窗口處于正常的打開狀態(tài)fx = mx;fy = my;mx += mdec.x;my += mdec.y;int ax = mx, ay = my;if ((mdec.btn & 0x01) != 0) {if (wx + 5 <= mx && mx <= wx + 175 && wy + 25 <= my && my <= wy + 135) {if ((fx > mx && my > fy) || (fx < mx && my < fy)) {xian(buf_window, 180, zise, min(fx, mx) - wx, min(fy, my) - wy, max(fx, mx) - wx, max(fy, my) - wy, 1);xian(buf_bigwin, binfo->scrnx, zise, min(fx, mx) - wx, min(fy, my) - wy, max(fx, mx) - wx, max(fy, my) - wy, 1);}else {xian(buf_window, 180, zise, min(fx, mx) - wx, min(fy, my) - wy, max(fx, mx) - wx, max(fy, my) - wy, 0);xian(buf_bigwin, binfo->scrnx, zise, min(fx, mx) - wx, min(fy, my) - wy, max(fx, mx) - wx, max(fy