ZealOS/src/System/Gr/GrScreen.ZC
GutPuncher 2ffd423f7b
Refactor framebuffer handling and remove redundant variables. (not tested on baremetal)
- Removed the 'fb_width_from_pitch' variable and replaced its usage with 'sys_framebuffer_pidth' to standardize the handling of framebuffer width-from-pitch across the codebase.
- Updated references to 'fb_width_from_pitch' in display and screen update functions to use 'sys_framebuffer_pidth', ensuring consistent calculations.
- Replaced 'sys_framebuffer_pitch / (sys_framebuffer_bpp / 8)' with 'sys_framebuffer_pidth' to avoid redundant calculations and improve code readability.
- Fixed framebuffer calculations in 'GrCalcScreenUpdates', 'GrUpdateScreen32', and related functions to use the correct framebuffer width-from-pitch value.
- Corrected and simplified screen update logic in 'GrZoomInScreen' and 'GrUpdateScreen'.
2024-12-02 01:02:34 -05:00

437 lines
9.5 KiB
HolyC
Executable File

#help_index "Graphics/Screen"
U0 GrUpdateTaskODEs(CTask *task)
{
sys_task_being_screen_updated = task;
try
ODEsUpdate(task);
catch
{
LBts(&task->win_inhibit, WIf_SELF_ODE);
"Exception in WinMgr: Update Task ODEs\n";
PutExcept;
Sleep(3000);
LFBFlush;
}
sys_task_being_screen_updated = NULL;
}
U0 GrUpdateTaskWin(CTask *task)
{ //Draw a win. Only Core0 tasks have a win.
CDC *dc;
CD3I64 saved_scroll;
sys_task_being_screen_updated = task;
try
{
if (!Bt(&task->display_flags, DISPLAYf_NO_BORDER))
TextBorder(Fs, task->win_left, task->win_right, task->win_top, task->win_bottom,
task->border_attr, task == sys_focus_task);
TextRect(task->win_left, task->win_right, task->win_top, task->win_bottom, task->text_attr << 8);
if (task == sys_winmgr_task)
{
if (gr.fp_wall_paper)
(*gr.fp_wall_paper)(task);
}
else if (!(task->win_inhibit & WIF_SELF_DOC))
DocUpdateTaskDocs(task);
if (TaskValidate(task))
{
if (task->draw_it)
{
dc = DCAlias(gr.dc2, task);
(*task->draw_it)(task, dc);
DCDel(dc);
}
if (TaskValidate(task))
{
WinScrollNull(task, &saved_scroll);
DrawCtrls(task);
WinScrollRestore(task, &saved_scroll);
}
}
}
catch
{
if (task != Fs && TaskValidate(task))
{
LBtr(&task->display_flags, DISPLAYf_SHOW);
"Exception in WinMgr: Update Task Win\n";
PutExcept;
Sleep(3000);
LFBFlush;
}
}
sys_task_being_screen_updated = NULL;
}
U0 GrUpdateTasks()
{//Only called by WinMgr
I64 i;
CTask *task, *task1;
try
{
winmgr.ode_time = 0;
if (Bt(&sys_semas[SEMA_UPDATE_WIN_Z_BUF], 0))
WinZBufUpdate;
task1 = task = sys_winmgr_task;
do
{ //Loop through Core0 tasks.
if (!TaskValidate(task))
break;
if (Bt(&task->display_flags, DISPLAYf_SHOW) && Bt(gr.win_uncovered_bitmap, task->win_z_num))
GrUpdateTaskWin(task);
if (!TaskValidate(task))
break;
task = task->next_task;
}
while (task != task1);
for (i = 0; i < mp_count; i++)
{ //Loop through all cores.
task1 = task = cpu_structs[i].executive_task;
do
{
if (!TaskValidate(task))
break;
GrUpdateTaskODEs(task);
if (!TaskValidate(task))
break;
task = task->next_task;
}
while (task != task1);
}
}
catch
{
PutExcept(FALSE);
Debug("Exception in WinMgr");
}
winmgr.last_ode_time = winmgr.ode_time;
ode_alloced_factor = LowPass1(0.1, ode_alloced_factor, Clamp(Gs->idle_factor - 0.1, 0.2, 0.8), 1 / winmgr.fps);
sys_task_being_screen_updated = NULL;
}
U0 GrFixZoomScale()
{
gr.screen_zoom = ClampI64(gr.screen_zoom, 1, GR_SCREEN_ZOOM_MAX);
if (gr.screen_zoom == 1)
{
gr.sx = 0;
gr.sy = 0;
}
else
{
gr.sx = ClampI64(gr.sx, 0, GR_WIDTH - GR_WIDTH / gr.screen_zoom);
gr.sy = ClampI64(gr.sy, 0, GR_HEIGHT - GR_HEIGHT / gr.screen_zoom);
}
}
public U0 GrScaleZoom(F64 scale)
{//Multiply zoom factor larger or smaller.
F64 s = gr.screen_zoom;
gr.screen_zoom = gr.screen_zoom * scale;
GrFixZoomScale;
s /= gr.screen_zoom;
mouse.scale.x *= s;
mouse.scale.y *= s;
mouse.scale.z *= s;
mouse.offset.x = mouse.pos.x - (mouse.pos.x - mouse.offset.x) * s;
mouse.offset.y = mouse.pos.y - (mouse.pos.y - mouse.offset.y) * s;
mouse.offset.z = mouse.pos.z - (mouse.pos.z - mouse.offset.z) * s;
gr.sx = mouse.pos.x - GR_WIDTH >> 1 / gr.screen_zoom;
gr.sy = mouse.pos.y - GR_HEIGHT >> 1 / gr.screen_zoom;
GrFixZoomScale;
}
U0 GrZoomInScreen()
{
I64 i, j, k, l;
U8 *src, *src2, *dst;
GrFixZoomScale;
src = gr.dc2->body + gr.sx + gr.sy * GR_WIDTH;
dst = gr.zoomed_dc->body;
for (i = 0; i < GR_HEIGHT / gr.screen_zoom; i++)
{
k = gr.screen_zoom;
while (k--)
{
src2 = src;
for (l = 0; l < GR_WIDTH / gr.screen_zoom; l++)
{
for (j = 0; j < gr.screen_zoom - 1; j++)
*dst++ = *src2;
*dst++ = *src2++;
}
}
src += GR_WIDTH;
}
}
U0 GrUpdateTextBG()
{
I64 reg RSI *dst = gr.dc2->body, reg R13 c, row, col,
num_rows = TEXT_ROWS, num_cols = TEXT_COLS, i, j, cur_ch,
reg R12 w1 = gr.dc2->width_internal, w2 = -7 * w1 + 8, w3 = 7 * w1, w4 = 0;
U32 *src = gr.text_base;
Bool blink_flag = Blink;
U8 *dst2 = dst;
if (gr.pan_text_x || gr.hide_col)
{
gr.pan_text_x = ClampI64(gr.pan_text_x, -7, 7);
j = AbsI64(gr.pan_text_x) / FONT_WIDTH + 1;
num_cols -= j;
if (gr.pan_text_x < 0)
{
src += j;
i = FONT_WIDTH * j + gr.pan_text_x;
}
else
i = gr.pan_text_x;
dst2 = dst(U8 *) + i;
w4 = j;
w3 += j * FONT_WIDTH;
j *= FONT_WIDTH;
dst(U8 *) = gr.dc2->body;
for (row = num_rows * FONT_HEIGHT; row--;)
{
for (col = i; col--;)
*dst(U8 *)++ = 0;
dst(U8 *) += w1 - i - j;
for (col = j; col--;)
*dst(U8 *)++ = 0;
}
}
dst = dst2;
if (gr.pan_text_y || gr.hide_row)
{
gr.pan_text_y = ClampI64(gr.pan_text_y, -7, 7);
j = AbsI64(gr.pan_text_y) / FONT_HEIGHT + 1;
num_rows -= j;
if (gr.pan_text_y < 0)
{
src += w1 / FONT_WIDTH * j;
i = w1 * (FONT_HEIGHT * j + gr.pan_text_y);
}
else
i = w1 * gr.pan_text_y;
dst2 = dst(U8 *) + i;
j *= w1 * FONT_HEIGHT;
dst(U8 *) = gr.dc2->body;
for (row = i; row--;)
*dst(U8 *)++ = 0;
dst(U8 *) = gr.dc2->body + TEXT_ROWS * TEXT_COLS * FONT_HEIGHT * FONT_WIDTH - j;
for (row=j;row--;)
*dst(U8 *)++ = 0;
}
dst = dst2;
for (row = num_rows; row--;)
{
for (col = num_cols; col--;)
{
cur_ch = *src++;
if (cur_ch & (ATTRF_SEL | ATTRF_INVERT | ATTRF_BLINK))
{
if (cur_ch & ATTRF_SEL)
cur_ch.u8[1] = cur_ch.u8[1] ^ 0xFF;
if (cur_ch & ATTRF_INVERT)
cur_ch.u8[1] = cur_ch.u8[1] << 4 + cur_ch.u8[1] >> 4;
if (cur_ch & ATTRF_BLINK && blink_flag)
cur_ch.u8[1] = cur_ch.u8[1] << 4 + cur_ch.u8[1] >> 4;
}
c = gr.to_8_colors[cur_ch.u8[1] >> 4];
MOV U64 [RSI], R13
ADD RSI, R12
MOV U64 [RSI], R13
ADD RSI, R12
MOV U64 [RSI], R13
ADD RSI, R12
MOV U64 [RSI], R13
ADD RSI, R12
MOV U64 [RSI], R13
ADD RSI, R12
MOV U64 [RSI], R13
ADD RSI, R12
MOV U64 [RSI], R13
ADD RSI, R12
MOV U64 [RSI], R13
dst(U8 *) += w2;
}
src += w4;
dst(U8 *) += w3;
}
}
U0 GrUpdateTextFG()
{//See $LK,"TextBase Layer",A="HI:TextBase Layer"$.
U32 *src = gr.text_base;
I64 i, j, cur_ch, *dst = gr.dc2->body, w1 = gr.dc2->width_internal, w2 = 7 * w1, w4 = 0,
num_rows = TEXT_ROWS, num_cols = TEXT_COLS, row, col;
U8 *dst_start = gr.dc2->body, *dst_end = dst_start + w1 * gr.dc2->height - 7 * w1 - 8;
Bool blink_flag = Blink;
if (gr.pan_text_x || gr.hide_col)
{
gr.pan_text_x = ClampI64(gr.pan_text_x, -7, 7);
j = AbsI64(gr.pan_text_x) / FONT_WIDTH + 1;
num_cols -= j;
if (gr.pan_text_x < 0)
{
src += j;
dst(U8 *) += FONT_WIDTH * j;
}
w4 = j;
w2 += j * FONT_WIDTH;
}
if (gr.pan_text_y || gr.hide_row)
{
gr.pan_text_y = ClampI64(gr.pan_text_y, -7, 7);
j = AbsI64(gr.pan_text_y) / FONT_HEIGHT + 1;
num_rows -= j;
if (gr.pan_text_y < 0)
{
src += w1 / FONT_WIDTH * j;
dst(U8 *) += w1 * FONT_HEIGHT * j;
}
}
for (row = num_rows; row--;)
{
for (col = num_cols; col--;)
{
cur_ch = *src++;
if (cur_ch & (ATTRF_UNDERLINE | ATTRF_SEL | ATTRF_INVERT | ATTRF_BLINK))
{
if (cur_ch & ATTRF_SEL)
cur_ch.u8[1] = cur_ch.u8[1] ^ 0xFF;
if (cur_ch & ATTRF_INVERT)
cur_ch.u8[1] = cur_ch.u8[1] << 4 + cur_ch.u8[1] >> 4;
if (cur_ch & ATTRF_BLINK && blink_flag)
cur_ch.u8[1] = cur_ch.u8[1] << 4 + cur_ch.u8[1] >> 4;
}
if (i = cur_ch.u16[1]&0x3FF+gr.pan_text_x+gr.pan_text_y<<5) {
j = i &0x1F;
if (j & 0x10)
j |= ~0x1F;
i >>= 5;
if (i & 0x10)
i |= ~0x1F;
i = w1 * i + j;
if (dst_start <= dst(U8 *) + i < dst_end)
GrRopEquU8NoClipping(cur_ch & (ATTRF_UNDERLINE + 0xFFF), dst(U8 *) + i, w1);
}
else
GrRopEquU8NoClipping(cur_ch & (ATTRF_UNDERLINE + 0xFFF), dst, w1);
dst(U8 *) += 8;
}
src += w4;
dst(U8 *) += w2;
}
}
U0 DCBlotColor8(CDC *dc, CDC *img)
{
U8 *src = img->body, *b0 = dc->body;
I64 j, k, d0 = img->width_internal * img->height;
for (k = 0; k < d0; k++)
{
j = *src++;
if (j != TRANSPARENT)
*b0++ = j;
else
b0++;
}
}
U0 GrCalcScreenUpdates()
{
U8 *screen, reg RCX *last_screen = gr.screen_cache;
U32 *src = text.raw_screen, *dst = text.fb_alias;
U64 i, j, x, y, yi;
if (gr.screen_zoom == 1)
screen = gr.dc2->body;
else
screen = gr.zoomed_dc->body;
for (y = yi = 0; y < GR_HEIGHT; yi = ++y * GR_WIDTH)
{
for (x = 0; x < GR_WIDTH; x++)
{
i = x + yi;
j = x + y * sys_framebuffer_pidth;
if (screen[i] != last_screen[i])
{
dst = text.fb_alias + j;
src = text.raw_screen + j;
*dst = *src;
}
}
}
MemCopy(gr.screen_cache, screen, GR_WIDTH * GR_HEIGHT);
}
U0 GrUpdateScreen32()
{
U64 x, y, j, i;
U32 *dst;
U8 *src;
if (gr.screen_zoom == 1)
src = gr.dc2->body;
else
{
GrZoomInScreen;
src = gr.zoomed_dc->body;
}
for (y = j = i = 0; y < GR_HEIGHT; j = ++y * sys_framebuffer_pidth, i = y * GR_WIDTH)
{
for (x = 0; x < GR_WIDTH; x++)
{
dst = text.raw_screen + x + j;
*dst = gr_palette[src[x + i] & 0xFF];
}
}
GrCalcScreenUpdates;
if (LBtr(&sys_semas[SEMA_FLUSH_VBE_IMAGE], 0))
MemCopy(text.fb_alias, text.raw_screen, text.buffer_size);
}
U0 GrUpdateScreen()
{//Called by the Window Manager $LK,"HERE",A="FF:::/System/WinMgr.ZC,GrUpdateScreen"$, 30 times a second.
CDC *dc;
if (text.is_fb_busy)
return;
GrUpdateTextBG;
GrUpdateTextFG;
GrUpdateTasks;
DCBlotColor8(gr.dc2, gr.dc);
dc = DCAlias(gr.dc2, Fs);
dc->flags |= DCF_ON_TOP;
if (gr.fp_final_screen_update)
(*gr.fp_final_screen_update)(dc);
DCDel(dc);
DCBlotColor4(gr.dc1->body, gr.dc2->body, gr.dc_cache->body, GR_HEIGHT * GR_WIDTH >> 3);
GrUpdateScreen32;
}