266 lines
5.3 KiB
C++
266 lines
5.3 KiB
C++
// video.c
|
|
// 08/13/03 Josh Holtrop
|
|
// Modified: 03/08/04
|
|
|
|
#include "hos_defines.h"
|
|
#include "video.h"
|
|
#include "video/stdfont.h"
|
|
#include "mm/vmm.h"
|
|
|
|
ModeInfoBlock video_mode;
|
|
dword videoMode = 0; //what video mode # we are in, 0 for console mode
|
|
word *vid_ptr16 = (word *)0xF0000000;
|
|
byte *vid_ptr24 = (byte *)0xF0000000;
|
|
dword *vid_ptr32 = (dword *)0xF0000000;
|
|
void (*video_psetp)(int, dword) = video_psetpnull; //function pointer to set a pixel
|
|
|
|
//Initialized the video mode information block video_mode and allocated double-buffer memory for graphics display
|
|
void video_init()
|
|
{
|
|
videoMode = *(word *)BOOT_VIDEO_MODE;
|
|
|
|
if (!videoMode) //we are in console mode
|
|
return;
|
|
|
|
video_mode = *(ModeInfoBlock *) BOOT_VIDEO_MODE_INFO_BLOCK;
|
|
|
|
switch(video_mode.BitsPerPixel)
|
|
{
|
|
case 16:
|
|
video_psetp = &video_psetp16;
|
|
break;
|
|
case 24:
|
|
video_psetp = &video_psetp24;
|
|
break;
|
|
case 32:
|
|
video_psetp = &video_psetp32;
|
|
}
|
|
|
|
unsigned int vidPages = video_mode.XResolution * video_mode.YResolution * (video_mode.BitsPerPixel >> 3);
|
|
if (vidPages % 4096)
|
|
vidPages = (vidPages >> 12) + 1;
|
|
else
|
|
vidPages = (vidPages >> 12);
|
|
vmm_mapn(0xF0000000, video_mode.PhysBasePtr, vidPages);
|
|
|
|
}
|
|
|
|
//Renders a character using stdfont[] as a bitmask
|
|
void video_renderChar(int x, int y, int character, int font, dword color, int drawBack, dword backColor)
|
|
{
|
|
int charWidth = stdfont_getFontWidth(font);
|
|
if (!charWidth)
|
|
return;
|
|
int charHeight = stdfont_getFontHeight(font);
|
|
int charpos = (character & 0xFF) * charHeight;
|
|
byte *charBMP = (byte *)stdfont_getBitmap(font);
|
|
int row;
|
|
int col;
|
|
for (row = 0; row < charHeight; row++)
|
|
{
|
|
for (col = 0; col < charWidth; col++)
|
|
{
|
|
if ((charBMP[charpos + row] << col) & 0x80)
|
|
video_pset(x + col, y + row, color);
|
|
else if (drawBack)
|
|
video_pset(x + col, y + row, backColor);
|
|
}
|
|
}
|
|
}
|
|
|
|
//Draws a horizontal line
|
|
void video_horiz(int y, int x1, int x2, dword color)
|
|
{
|
|
if (x1 > x2)
|
|
{
|
|
int tmp = x2;
|
|
x2 = x1;
|
|
x1 = tmp; //x2 >= x1 now
|
|
}
|
|
if (x2 < 0)
|
|
return;
|
|
if (x1 >= video_mode.XResolution)
|
|
return;
|
|
if (x1 < 0)
|
|
x1 = 0;
|
|
if (x2 >= video_mode.XResolution)
|
|
x2 = video_mode.XResolution - 1;
|
|
int pixel = y * video_mode.XResolution + x1;
|
|
for (; x1 <= x2; x1++)
|
|
{
|
|
video_psetp(pixel++, color);
|
|
}
|
|
}
|
|
|
|
//Draws a single pixel
|
|
void video_pset(int x, int y, dword color)
|
|
{
|
|
if ((x < 0) || (x >= video_mode.XResolution) || (y < 0) || (y >= video_mode.YResolution))
|
|
return;
|
|
video_psetp(y * video_mode.XResolution + x, color);
|
|
}
|
|
|
|
//Draws a pixel at the specified pixel position
|
|
//This function is needed because external modules do not have access to the function pointer video_psetp
|
|
void video_pseti(int pixel, dword color)
|
|
{
|
|
video_psetp(pixel, color);
|
|
}
|
|
|
|
//Draws a vertical line
|
|
void video_vert(int x, int y1, int y2, dword color)
|
|
{
|
|
if (y1 > y2)
|
|
{
|
|
int tmp = y2;
|
|
y2 = y1;
|
|
y1 = tmp; //y2 >= y1 now
|
|
}
|
|
if (y2 < 0)
|
|
return;
|
|
if (y1 >= video_mode.YResolution)
|
|
return;
|
|
if (y1 < 0)
|
|
y1 = 0;
|
|
if (y2 >= video_mode.YResolution)
|
|
y2 = video_mode.YResolution - 1;
|
|
int pixel = y1 * video_mode.XResolution + x;
|
|
for (; y1 <= y2; y1++)
|
|
{
|
|
video_psetp(pixel, color);
|
|
pixel += video_mode.XResolution;
|
|
}
|
|
}
|
|
|
|
//Draws a rectangle
|
|
void video_rect(int x1, int y1, int x2, int y2, dword color)
|
|
{
|
|
video_horiz(y1, x1, x2, color);
|
|
video_horiz(y2, x1, x2, color);
|
|
video_vert(x1, y1, y2, color);
|
|
video_vert(x2, y1, y2, color);
|
|
}
|
|
|
|
//Draws a filled rectangle
|
|
void video_rectf(int x1, int y1, int x2, int y2, dword color)
|
|
{
|
|
if (y2 < y1)
|
|
{
|
|
int tmp = y2;
|
|
y2 = y1;
|
|
y1 = tmp;
|
|
}
|
|
for (; y1 <= y2; y1++)
|
|
video_horiz(y1, x1, x2, color);
|
|
}
|
|
|
|
//Draws a pixel at the specified pixel position
|
|
void video_psetp16(int pixel, dword color)
|
|
{
|
|
vid_ptr16[pixel] = ((color&0xFF)>>3) | ((((color>>8)&0xFF)>>2)<<5) | ((((color>>16)&0xFF)>>3)<<11);
|
|
}
|
|
|
|
//Draws a pixel at the specified pixel position
|
|
void video_psetp24(int pixel, dword color)
|
|
{
|
|
vid_ptr24[pixel*3] = color & 0xFF;
|
|
vid_ptr24[pixel*3+1] = (color>>8) & 0xFF;
|
|
vid_ptr24[pixel*3+2] = (color>>16) & 0xFF;
|
|
}
|
|
|
|
//Draws a pixel at the specified pixel position
|
|
void video_psetp32(int pixel, dword color)
|
|
{
|
|
vid_ptr32[pixel] = color;
|
|
}
|
|
|
|
//Dummy function to not draw anything if there is no graphical mode enabled
|
|
void video_psetpnull(int pixel, dword color) {}
|
|
|
|
|
|
int video_getWidth()
|
|
{
|
|
return video_mode.XResolution;
|
|
}
|
|
|
|
int video_getHeight()
|
|
{
|
|
return video_mode.YResolution;
|
|
}
|
|
|
|
byte video_getBitsPerPixel()
|
|
{
|
|
return video_mode.BitsPerPixel;
|
|
}
|
|
|
|
dword video_getPhysBasePtr()
|
|
{
|
|
return video_mode.PhysBasePtr;
|
|
}
|
|
|
|
dword video_Mode()
|
|
{
|
|
return videoMode;
|
|
}
|
|
|
|
void video_line(int x0, int y0, int x1, int y1, dword color)
|
|
{
|
|
int dy = y1 - y0;
|
|
int dx = x1 - x0;
|
|
int stepx, stepy;
|
|
if (dy < 0)
|
|
{
|
|
dy = -dy;
|
|
stepy = -1;
|
|
}
|
|
else
|
|
{
|
|
stepy = 1;
|
|
}
|
|
if (dx < 0)
|
|
{
|
|
dx = -dx;
|
|
stepx = -1;
|
|
}
|
|
else
|
|
{
|
|
stepx = 1;
|
|
}
|
|
dy <<= 1; // dy is now 2*dy
|
|
dx <<= 1; // dx is now 2*dx
|
|
video_pset(x0, y0, color);
|
|
|
|
if (dx > dy)
|
|
{
|
|
int fraction = dy - (dx >> 1); // same as 2*dy - dx
|
|
while (x0 != x1)
|
|
{
|
|
if (fraction >= 0)
|
|
{
|
|
y0 += stepy;
|
|
fraction -= dx; // same as fraction -= 2*dx
|
|
}
|
|
x0 += stepx;
|
|
fraction += dy; // same as fraction -= 2*dy
|
|
video_pset(x0, y0, color);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int fraction = dx - (dy >> 1);
|
|
while (y0 != y1)
|
|
{
|
|
if (fraction >= 0)
|
|
{
|
|
x0 += stepx;
|
|
fraction -= dy;
|
|
}
|
|
y0 += stepy;
|
|
fraction += dx;
|
|
video_pset(x0, y0, color);
|
|
}
|
|
}
|
|
}
|
|
|
|
|