Day11 制作窗口

文章目錄

      • 1. 顯示窗口(harib08d)
      • 2. 消除閃爍1(harib08g)
      • 3. 消除閃爍2(harib08h)

本章的前三節做了如下修改:

  1. 解決了鼠標無法隱藏在屏幕右側和下側的問題。
  2. 當鼠標隱藏在右側時會在屏幕最左側產生陰影的問題。
  3. 在struct SHEET結構體中添加struct SHTCTL類型指針,以減少接口中參數列表的個數。

1. 顯示窗口(harib08d)

類似制作背景和鼠標,需要先準備一個圖層,然后在圖層buffer中描繪一個類似窗口的圖。make_window8函數類似graphic.c中的init_screen8函數,其中“x”按鈕使用類似init_mouse_cursor8的方法。

void make_window8(unsigned char *buf, int xsize, int ysize, char *title)
{static char closebtn[14][16] = {"OOOOOOOOOOOOOOO@","OQQQQQQQQQQQQQ$@","OQQQQQQQQQQQQQ$@","OQQQ@@QQQQ@@QQ$@","OQQQQ@@QQ@@QQQ$@","OQQQQQ@@@@QQQQ$@","OQQQQQQ@@QQQQQ$@","OQQQQQ@@@@QQQQ$@","OQQQQ@@QQ@@QQQ$@","OQQQ@@QQQQ@@QQ$@","OQQQQQQQQQQQQQ$@","OQQQQQQQQQQQQQ$@","O$$$$$$$$$$$$$$@","@@@@@@@@@@@@@@@@"};int x, y;char c;boxfill8(buf, xsize, COL8_C6C6C6, 0,         0,         xsize - 1, 0        );boxfill8(buf, xsize, COL8_FFFFFF, 1,         1,         xsize - 2, 1        );boxfill8(buf, xsize, COL8_C6C6C6, 0,         0,         0,         ysize - 1);boxfill8(buf, xsize, COL8_FFFFFF, 1,         1,         1,         ysize - 2);boxfill8(buf, xsize, COL8_848484, xsize - 2, 1,         xsize - 2, ysize - 2);boxfill8(buf, xsize, COL8_000000, xsize - 1, 0,         xsize - 1, ysize - 1);boxfill8(buf, xsize, COL8_C6C6C6, 2,         2,         xsize - 3, ysize - 3);boxfill8(buf, xsize, COL8_000084, 3,         3,         xsize - 4, 20       );boxfill8(buf, xsize, COL8_848484, 1,         ysize - 2, xsize - 2, ysize - 2);boxfill8(buf, xsize, COL8_000000, 0,         ysize - 1, xsize - 1, ysize - 1);putfonts8_asc(buf, xsize, 24, 4, COL8_FFFFFF, title);for (y = 0; y < 14; y++) {for (x = 0; x < 16; x++) {c = closebtn[y][x];if (c == '@') {c = COL8_000000;} else if (c == '$') {c = COL8_848484;} else if (c == 'Q') {c = COL8_C6C6C6;} else {c = COL8_FFFFFF;}buf[(5 + y) * xsize + (xsize - 21 + x)] = c;}}return;
}

在HariMain函數中相應的調用窗口函數和圖層處理函數,顯示效果:
在這里插入圖片描述

2. 消除閃爍1(harib08g)

圖層刷新的規則:

  1. 如果窗口圖層變化,無鼠標圖層,則刷新窗口圖層,不需要刷新背景圖層。
  2. 如果窗口圖層變化,鼠標在其上,則刷新窗口圖層的同時刷新鼠標圖層(因為窗口的刷新會覆蓋鼠標的一部分顯示區域),同樣不需要刷新背景圖層。

首先修改sheet_refreshsub函數,在參數列表中追加h0入參,表示只刷新在此h0圖層及以上的圖層。對應的sheet處理函數有對sheet_refreshsub的調用都需要修改。

void sheet_refreshsub(struct SHTCTL *ctl, int vx0, int vy0, int vx1, int vy1, int h0)
{// 略for (h = h0; h <= ctl->top; h++) {// 略}return;
}

其中,在sheet_slide函數中,圖層移動時會導致下面的圖層露出,因此需要從下面的圖層開始刷新。在圖層所移動到的目標位置處,比新移來的圖層低的圖層沒有什么變化,只是需要隱藏一部分,所以只需要刷新移動圖層和它上面的圖層。
sheet_updown函數中,同樣的思路,針對個別不需要自下而上全部刷新的圖層,僅刷新其局部。
查看效果,窗口圖層已經不再閃爍了,只是如果鼠標放置在上面,還是會產生閃爍。
在這里插入圖片描述

3. 消除閃爍2(harib08h)

鼠標的閃爍顯現是由于一會描繪一會消除產生的。如果期望消除閃爍,就需要在刷新窗口時,避開鼠標覆蓋的區域對VRAM的寫入處理。
開辟一塊內存,大小與VRAM相同,稱其為map。這塊內存用來表示畫面上的點是哪個圖層的像素,因此可以理解為圖層的地圖。
如圖,期望刷新圖層1的時候,參照map的內容刷新,就不必擔心圖層1和圖層2的重疊部分了。
在這里插入圖片描述

struct SHTCTL {unsigned char *vram, *map;int xsize, ysize, top;struct SHEET *sheets[MAX_SHEETS];struct SHEET sheets0[MAX_SHEETS];
};/* 向圖層中寫入號碼 */
void sheet_refreshmap(struct SHTCTL *ctl, int vx0, int vy0, int vx1, int vy1, int h0)
{int h, bx, by, vx, vy, bx0, by0, bx1, by1;unsigned char *buf, sid, *map = ctl->map;struct SHEET *sht;if (vx0 < 0) { vx0 = 0; }if (vy0 < 0) { vy0 = 0; }if (vx1 > ctl->xsize) { vx1 = ctl->xsize; }if (vy1 > ctl->ysize) { vy1 = ctl->ysize; }for (h = h0; h <= ctl->top; h++) {sht = ctl->sheets[h];sid = sht - ctl->sheets0; /* 將進行了減法運算的地址作為圖層的號碼 */buf = sht->buf;bx0 = vx0 - sht->vx0;by0 = vy0 - sht->vy0;bx1 = vx1 - sht->vx0;by1 = vy1 - sht->vy0;if (bx0 < 0) { bx0 = 0; }if (by0 < 0) { by0 = 0; }if (bx1 > sht->bxsize) { bx1 = sht->bxsize; }if (by1 > sht->bysize) { by1 = sht->bysize; }for (by = by0; by < by1; by++) {vy = sht->vy0 + by;for (bx = bx0; bx < bx1; bx++) {vx = sht->vx0 + bx;if (buf[by * sht->bxsize + bx] != sht->col_inv) {map[vy * ctl->xsize + vx] = sid;}}}}return;
}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的范圍超出了畫面則修正 */if (vx0 < 0) { vx0 = 0; }if (vy0 < 0) { vy0 = 0; }if (vx1 > ctl->xsize) { vx1 = ctl->xsize; }if (vy1 > ctl->ysize) { vy1 = ctl->ysize; }for (h = h0; h <= h1; h++) {sht = ctl->sheets[h];buf = sht->buf;sid = sht - ctl->sheets0;/* 利用vx0 ~ vy1,對bx0 ~ by1倒推 */bx0 = vx0 - sht->vx0;by0 = vy0 - sht->vy0;bx1 = vx1 - sht->vx0;by1 = vy1 - sht->vy0;if (bx0 < 0) { bx0 = 0; }if (by0 < 0) { by0 = 0; }if (bx1 > sht->bxsize) { bx1 = sht->bxsize; }if (by1 > sht->bysize) { by1 = sht->bysize; }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) {		// 修改點vram[vy * ctl->xsize + vx] = buf[by * sht->bxsize + bx];}}}}return;
}void sheet_refresh(struct SHEET *sht, int bx0, int by0, int bx1, int by1)
{if (sht->height >= 0) { /* 如果正在顯示,則按照新圖層的信息進行刷新 */sheet_refreshsub(sht->ctl, sht->vx0 + bx0, sht->vy0 + by0, sht->vx0 + bx1, sht->vy0 + by1, sht->height, sht->height);}return;
}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;if (sht->height >= 0) { /* 如果正在顯示,則按照新圖層的信息進行刷新 */sheet_refreshmap(ctl, old_vx0, old_vy0, old_vx0 + sht->bxsize, old_vy0 + sht->bysize, 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;
}

sheet_refresh函數里,由于圖層的上下關系沒有變,所以不需要重新進行refreshmap的處理。
sheet_slide函數里,需要先重寫map,分別對應移動前后的圖層,然后調用sheet_refreshsub函數。在移動前的地方,只針對上層圖層移走后而露出的下層圖層進行重繪就行了,在移動目的地處僅重繪了一張移動過去的圖層。
sheet_updown函數,同樣在調用sheet_refreshsub之前,需要先執行sheet_refreshmap重新繪制map。
此時的屏幕將不再閃爍,看起來像是一個比較現代化的電腦了。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/86871.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/86871.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/86871.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

python+uniapp基于微信小程序蜀味道江湖餐飲管理系統nodejs+java

文章目錄 具體實現截圖本項目支持的技術路線源碼獲取詳細視頻演示&#xff1a;文章底部獲取博主聯系方式&#xff01;&#xff01;&#xff01;&#xff01;本系統開發思路進度安排及各階段主要任務java類核心代碼部分展示主要參考文獻&#xff1a;源碼獲取/詳細視頻演示 ##項目…

postgresql增量備份系列二 pg_probackup

已經很久沒有發文章了,主要是最近工作上的內容都不適合發文章公開。可能往后文章發表也不這么頻繁了,不過大家有問題我們可以交流。之前有寫過PG增量備份的其他工具使用方法,pg_probackup也是應用比較多的PG備份工具。 一. pg_probackup pg_probackup 是一個用于管理 Postg…

云手機主要是指什么?

云手機是指一種可以運行在云服務器中的手機&#xff0c;主要是將云計算技術運用于網絡終端服務&#xff0c;通過云服務器來實現云服務的手機&#xff0c;也是一款深度結合了網絡服務的手機&#xff0c;通過自帶的系統和網絡終端可以通過網絡實現眾多功能。 那么&#xff0c;下面…

CAU數據挖掘 支持向量機

SVM大致思想 線性分類問題 在一群點中用線性函數分類&#xff1a; 但也有線性不可分問題&#xff1a; 線性不可分問題&#xff1a; 最大間隔法 兩個平行超平面間隔距離最大 軟間隔 部分難以區分的點忽略 升維 通過升維將非線性變為線性 計算統計理論基礎 學習過…

探索理解 Spring AI Advisors:構建可擴展的 AI 應用

Spring AI Advisors API 提供了一種靈活且強大的方式來攔截、修改和增強 Spring 應用程序中的 AI 驅動交互。其核心思想類似于 Spring AOP&#xff08;面向切面編程&#xff09;中的“通知”&#xff08;Advice&#xff09;&#xff0c;允許開發者在不修改核心業務邏輯的情況下…

Linux SSH服務全面配置指南:從基礎到安全加固

Linux SSH服務全面配置指南&#xff1a;從基礎到安全加固 概述 作為網絡安全工程師&#xff0c;SSH&#xff08;Secure Shell&#xff09;服務的安全配置是我們日常工作中不可忽視的重要環節。本文將從基礎配置到高級安全加固&#xff0c;全面解析SSH服務的各項參數&#xff…

.NET測試工具Parasoft dotTEST內置安全標準,編碼合規更高效

在追求開發速度的時代&#xff0c;確保代碼安全并滿足嚴苛的行業合規標準如OWASP、CWE、PCI DSS、ISO 26262等已成為開發者的核心挑戰&#xff0c;但開發人員常因復雜的編碼標準和漏洞排查而效率低下。.NET測試工具Parasoft dotTEST內置安全標準&#xff0c;實現即插即用&#…

對象的finalization機制Test

Java語言提供了對象終止(finalization)機制來允許開發人員自定義對象被銷毀之前的處理邏輯。當垃圾回收器發現沒有引用指向一個對象時&#xff0c;通常接下來要做的就是垃圾回收&#xff0c;即清除該對象&#xff0c;而finalization機制使得在清除此對象之前&#xff0c;總會先…

AI初學者如何對大模型進行微調?——零基礎保姆級實戰指南

僅需8GB顯存&#xff0c;三步完成個人專屬大模型訓練 四步實戰&#xff1a;從環境配置到模型發布 步驟1&#xff1a;云端環境搭建&#xff08;10分鐘&#xff09; 推薦使用阿里魔塔ModelScope免費GPU資源&#xff1a; # 注冊后執行環境初始化 pip3 install --upgrade pip pi…

“單一職責”模式之裝飾器模式

目錄 “單一職責”模式裝飾器模式 Decorator引例動機 Motivation模式定義結構 Structure要點總結 “單一職責”模式 在軟件組件的設計中&#xff0c;如果責任劃分的不清晰&#xff0c;使用繼承得到的結果往往是隨著需求的變化&#xff0c;子類急劇膨脹&#xff0c;同時充斥著重…

idea, CreateProcess error=206, 文件名或擴展名太長

idea, CreateProcess error206, 文件名或擴展名太長 解決 “CreateProcess error206, 文件名或擴展名太長” 錯誤 CreateProcess error206 是 Windows 系統特有的錯誤&#xff0c;表示命令行參數超出了 Windows 的 32767 字符限制。這個問題在 Java 開發中尤其常見&#xff0c…

一鍵高效率圖片MD5修改工具PHP版

文章目錄 圖片MD5修改工具項目簡介功能特點技術原理系統需求安裝方法使用方法Web界面模式命令行模式文件結構常見問題注意事項開發者信息效果演示更多干貨??1.如果我的博客對你有幫助、如果你喜歡我的博客內容,請 “??點贊” “??評論” “??收藏” 一鍵三連哦!2.??…

跨主機用 Docker Compose 部署 PostgreSQL + PostGIS 主從

q下面是跨主機用 Docker Compose 部署 PostgreSQL PostGIS 主從復制的完整詳細步驟&#xff08;主庫 從庫&#xff09;&#xff0c;主從都用官方 PostGIS 鏡像 postgis/postgis:15-3.3&#xff0c;并注意網絡與持久化。復制即可。 &#x1f6a9; 跨主機 PostgreSQL PostGIS …

會議動態|千眼狼高速攝像機、DIC測量系統等科學儀器亮相第十五屆全國爆炸力學學術會議

第十五屆全國爆炸力學學術會議于6月28日在紹興盛大召開&#xff0c;會議匯聚來自全國爆炸力學與沖擊領域專家學者2000余人&#xff0c;聚焦“爆炸與沖擊動力學工程應用”、“材料動態力學行為與損傷斷裂“、“工程爆破與毀傷評估”、“含能材料與水中爆炸”、“結構動態響應與安…

vscode一個文件夾有殘余的git倉庫文件,已經失效了,怎樣進行清空倉庫殘余文件并重新初始化git--ubuntu

vscode一個文件夾有殘余的git倉庫文件&#xff0c;已經失效了&#xff0c;怎樣進行清空倉庫殘余文件并重新初始化git–ubuntu 首先要把工作區里重要的文件備份好&#xff0c;防止操作時數據丟失。刪除.git文件夾 rm -rf .git初始化 (base) zd4090zd4090-System-Product-Name:…

6月30日作業

思維導圖 一、讀取文件&#xff0c;效果類似 cat 的功能 代碼 #include <25041head.h>int main(int argc, const char *argv[]) {//打開文件printf("請輸入你要讀取的文件路徑&#xff1a;");char str[128]"";scanf("%s",str);FILE *fpf…

ubuntu源碼安裝python3.13遇到Could not build the ssl module!解決方法

我在Ubuntu 24.04.2 LTS下載源碼安裝Python 3.13.5時&#xff1a; #./configure --enable-loadable-sqlite-extensions --enable-optimizations #make 顯示錯誤信息&#xff1a; Could not build the ssl module! Python requires a OpenSSL 1.1.1 or newer 查詢我的openssl版…

Ai工具分享(2):Vscode+Cline無限免費的使用教程

大家好,我是程序員寒山。 今天給大家分享一個最新的免費使用的Ai插件Cline的方法,之前也給大家分享過一些免費的方案,但是這些都是隨時在變化,之前推薦的很多都不能使用了。 Ai工具分享(2):Vscode+Cline無限免費的使用教 今天再給大家推薦一個,可以免費使用,且沒有token…

Docker 目錄遷移腳本【Windows Junction 類型鏈接】

Docker 目錄遷移腳本完整教程&#xff1a;從誕生到自動化使用 一、腳本誕生背景與開發歷程 1. 為什么需要遷移 Docker 目錄&#xff1f; 系統盤空間壓力&#xff1a;Docker 鏡像和容器數據通常存儲在C:\Users\用戶名目錄下&#xff0c;隨著使用時間增長會占用大量系統盤空間…

spring-ai 工作流

目錄 工作流概念工作流程圖spring-boot 編碼定義節點 (Node)定義節點圖StateGraphcontroller測試瀏覽器測試用戶輸入 工作流概念 工作流是以相對固化的模式來人為地拆解任務&#xff0c;將一個大任務拆解為包含多個分支的固化流程。工作流的優勢是確定性強&#xff0c;模型作為…