《作業系統30天》-合川秀實-學習日誌day11
這次的日誌就不把書上的東西照搬過來了,寫一點關於這個紙娃娃作業系統的理解。
一、新增一個視窗圖層有哪些步驟?(格式:文字說明+對應程式碼)
第一步:定義圖層包 (結構體SHTCTL),建立圖層(SHEET),建立緩衝區buf(地址)
第二步:初始化圖層
第三步:分配記憶體
第四步:初始化圖層背景(把圖層寫進顯示卡)+內容初始化(圖層內容填充)
第五步:設定圖層顯示位置的起始座標(X0,Y0)+設定圖層高度
二、教材202頁,為什麼滑鼠移動到最右邊後左邊會出現滑鼠圖案,為什麼右邊只有一個滑鼠,左邊卻有很多?
我們由上一天內容知道,圖層移動的時候會呼叫sheet_refreshsub()和sheet_slide這兩個函式:
對滑鼠的重新整理:
我們知道滑鼠的座標是經過修正的,所以傳入的old圖層的起始位置其實是在合理範圍內。
檢視refreshsub函式:
對我們有用的是最後的顯示部分,因為不管滑鼠在哪顯示,都用用到畫素點
如果按照書上的方法修改,根據畫素點公式(一維計算)會導致重新整理的畫素點往後偏移16位(相當於往右),所以在螢幕左邊會出現滑鼠。對重新整理old圖層來說,傳入的引數vx0=mx和vx1>xsize,對新圖層來說,也是vx0=mx和vx1>xize,而且老圖層和新圖層的vx1值是相同的,因為當我們把滑鼠放到最右邊的時候,傳入的mx都是同一個值,所以計算出的vx1也是同一個值(mx+16),這個時候兩次呼叫的bx1相同,會先重新整理一次老的,再重新整理一次新的,那還是在原來的位置,所以滑鼠只能在左邊的固定範圍內出現。重新整理的時候因為螢幕的背景是按照一樣的計算公式填充的,所以在邊界移動的時候會有痕跡保留,也就說old的值還存在背景中,背景圖層在重新整理的時候會把“遺留”下來的一起重新整理,可能是滑鼠的顏色,也可能是黑色,驗證我的說法:
改正方法:在sheet_refreshsub函式裡面的迴圈重新整理之前,新增判斷
三、教材216頁,每個圖層的sid是如何設定的?具體數值等於多少?
Sid變數首次出現在sheet_refreshmap函式中,儲存的是每個圖層相對於sheets0的位置,作者給出的解釋是減法計算得出的(地址)圖層號碼,所以說實際上sid是一個地址,是sheet ID的縮寫,出現在函式中是這種形式:
影象形式:相當於一個圖層體包含的多個圖層每個圖層有固定的地址,用當前圖層的地址減去最下面圖層的地址就可以得出當前的sid號了
可以理解成圖層的標號1,2,3………
四、教材216-217頁,結合程式碼,解釋重新整理函式(sheet_refreshsub)的引數和實現邏輯。
Ctl是表示儲存圖層的結構體,座標值就是傳入大小(vx0,vy0)->(vx1,vy1),h0表示從h0層開始重新整理map,直到h1層。
實現邏輯:若h0=1,h1=3當繪製圖層1(sid)時,遍歷map,遇到1時繪製,否則不繪製;之後繪製圖層2,遍歷map,遇到2進行繪製;同理,圖層3也是。在count計數中,每一次計數後的畫面繪製中,只需要遍歷map,繪製計數視窗的圖層就可以了,消除了滑鼠閃爍。
void sheet_refreshsub(struct SHTCTL *ctl, int vx0, int vy0, int vx1, int vy1, int h0, int h1)
{
int h, bx, by, vx, vy, bx0, by0, bx1, by1;
unsigned char *buf, *vram = ctl->vram, *map = ctl->map, sid;
struct SHEET *sht;
/* 如果refresh的範圍超出了畫面則修正 */
for (h = h0; h <= h1; h++) {
/*只重新整理h0-h1範圍內的圖層*/
sht = ctl->sheets[h];
buf = sht->buf;
sid = sht - ctl->sheets0;
/*計算每個圖層的sid,在下面的疊加部分進行重新整理*/
/* 利用vx0~vy1對bx0~by1進行倒推*/
for (by = by0; by < by1; by++) {
vy = sht->vy0 + by;
for (bx = bx0; bx < bx1; bx++) {
vx = sht->vx0 + bx;
if (map[vy * ctl->xsize + vx] == sid) {
/* 判斷是否可以繪製(比如說當前圖層號碼為2,那麼只繪製2那層)*/
vram[vy * ctl->xsize + vx] = buf[by * sht->bxsize + bx];
}
}
}
}
return;
}
五、教材217頁,結合程式碼,解釋滑動函式(sheet_slide)的引數和實現邏輯,注意內部呼叫sheet_refreshmap和sheet_refreshsub時的傳參,特別是高度引數,為什麼這樣傳。
slide函式實現的是圖層的滑動,重新整理移動前的位置,再重新整理移動後的位置
void sheet_slide(struct SHEET *sht, int vx0, int vy0)
{
struct SHTCTL *ctl = sht->ctl;
int old_vx0 = sht->vx0, old_vy0 = sht->vy0;
sht->vx0 = vx0;
sht->vy0 = vy0;
/* old_vx0,old_vy0表示原來的圖層*/
/* vx0,vy0表示新的圖層*/
if (sht->height >= 0) { /* 如果正在顯示,按照新圖層的資訊進行重新整理*/
sheet_refreshmap(ctl, old_vx0, old_vy0, old_vx0 + sht->bxsize, old_vy0 + sht->bysize, 0);
/* 繪製原來圖層位置的新地圖,因為是原來的位置,圖層移走了,無法判斷圖層移動之後的情況,所有要從0開始重新整理 */
sheet_refreshmap(ctl, vx0, vy0, vx0 + sht->bxsize, vy0 + sht->bysize, sht->height);
/* 繪製新圖層位置的新地圖,新地圖只需要從當前的高度開始重新整理,下面的被覆蓋不用重新整理,只需要重新整理高度以上的 */
sheet_refreshsub(ctl, old_vx0, old_vy0, old_vx0 + sht->bxsize, old_vy0 + sht->bysize, 0, sht->height - 1);
/* 原來位置的地圖發生了改變(重新整理),所以相應的我的圖層要根據地圖來重新整理 */
sheet_refreshsub(ctl, vx0, vy0, vx0 + sht->bxsize, vy0 + sht->bysize, sht->height, sht->height);
/* 新的圖層地圖只是在新圖層的高度以上進行了重新整理,所以新高度的地圖已經繪製好了,直接按照地圖重新整理當前這一高度的圖層就可以了 */
}
return;
}
相關文章
- Linux作業系統的日誌說明Linux作業系統
- 作業系統學習作業系統
- 工作學習中如何選擇作業系統?如何學習linux作業系統作業系統Linux
- 國產作業系統學習作業系統
- 作業系統學習(1)-概述作業系統
- 小白如何學習作業系統?作業系統
- 學習日誌
- 開發日誌:Kylin麒麟作業系統部署ASP.NET CORE作業系統ASP.NET
- 學習作業系統的三本書作業系統
- 日誌系統
- MySQL學習之日誌系統MySql
- 作業系統複習作業系統
- 企業級日誌分析系統——ELK
- 11.3 學習日誌
- 日誌框架學習框架
- 有人想學習作業系統原始碼嗎作業系統原始碼
- 作業系統學習筆記:裝置管理作業系統筆記
- Rust 日誌系統實踐總結Rust
- Rsyslog日誌系統
- AIX系統日誌AI
- Linux系統有什麼優點?linux作業系統學習Linux作業系統
- Linux系統級日誌系統Linux
- springboot學習日誌(二)– thymeleaf學習Spring Boot
- Linux學習路線全解,Linux作業系統學習路線Linux作業系統
- Git 學習日誌1Git
- 作業系統學習筆記-1:基礎概念作業系統筆記
- 作業系統——記憶體管理學習筆記作業系統記憶體筆記
- 學習UbuntuLinux作業系統過程和經驗UbuntuLinux作業系統
- 嵌入式Linux作業系統學習規劃Linux作業系統
- 站長必修課:windows作業系統檢視並分析伺服器日誌Windows作業系統伺服器
- 日誌系統相關
- 日誌審計系統
- ELK日誌分析系統
- 上海AI實驗室推出自主學習作業系統OS-CopilotAI作業系統
- 各大作業系統AIX/HPUX/Solaris/Linux下的系統日誌作業系統AILinux
- 作業系統習題以及答案作業系統
- 學習筆記 作業系統Linux-Ubuntu 之初次新增系統呼叫筆記作業系統LinuxUbuntu
- 2024.11.13 日軟體工程學習日誌軟體工程