video.cpp
This commit is contained in:
parent
f551ca29ce
commit
90424967b7
166
exp/video.cpp
Normal file
166
exp/video.cpp
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <conio.h>
|
||||||
|
#include <dos.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
typedef unsigned char uint8;
|
||||||
|
typedef unsigned uint16;
|
||||||
|
typedef unsigned long uint32;
|
||||||
|
|
||||||
|
struct vbeInfo {
|
||||||
|
char Signature[4];
|
||||||
|
uint16 Version;
|
||||||
|
uint32 OemString;
|
||||||
|
uint8 Capabilities[4];
|
||||||
|
uint32 VideoModes;
|
||||||
|
uint16 TotalMem;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct modeInfo {
|
||||||
|
uint16 attributes;
|
||||||
|
uint8 winA,winB;
|
||||||
|
uint16 granularity;
|
||||||
|
uint16 winsize;
|
||||||
|
uint16 segmentA, segmentB;
|
||||||
|
uint32 realFctPtr;
|
||||||
|
uint16 pitch; // uint8s per scanline
|
||||||
|
|
||||||
|
uint16 Xres, Yres;
|
||||||
|
uint8 Wchar, Ychar, planes, bpp, banks;
|
||||||
|
uint8 memory_model, bank_size, image_pages;
|
||||||
|
uint8 reserved0;
|
||||||
|
|
||||||
|
uint8 red_mask, red_position;
|
||||||
|
uint8 green_mask, green_position;
|
||||||
|
uint8 blue_mask, blue_position;
|
||||||
|
uint8 rsv_mask, rsv_position;
|
||||||
|
uint8 directcolor_attributes;
|
||||||
|
|
||||||
|
uint32 physbase; // your LFB address ;)
|
||||||
|
uint32 reserved1;
|
||||||
|
uint16 reserved2;
|
||||||
|
};
|
||||||
|
|
||||||
|
uint16 GetInfo (vbeInfo far* info)
|
||||||
|
{
|
||||||
|
REGS regs;
|
||||||
|
SREGS segregs;
|
||||||
|
|
||||||
|
regs.x.ax = 0x4f00;
|
||||||
|
regs.x.di = FP_OFF(info);
|
||||||
|
segregs.es = FP_SEG(info);
|
||||||
|
int86x(0x10, ®s, ®s, &segregs);
|
||||||
|
|
||||||
|
return regs.x.ax;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16 GetModeInfo (modeInfo far* info, uint16 mode)
|
||||||
|
{
|
||||||
|
REGS regs;
|
||||||
|
SREGS segregs;
|
||||||
|
|
||||||
|
regs.x.ax = 0x4f01;
|
||||||
|
regs.x.cx = mode;
|
||||||
|
regs.x.di = FP_OFF(info);
|
||||||
|
segregs.es = FP_SEG(info);
|
||||||
|
int86x(0x10, ®s, ®s, &segregs);
|
||||||
|
|
||||||
|
return regs.x.ax;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetMode (uint16 mode)
|
||||||
|
{
|
||||||
|
REGS regs;
|
||||||
|
|
||||||
|
regs.x.ax = 0x4F02;
|
||||||
|
regs.x.bx = mode;
|
||||||
|
int86(0x10, ®s, ®s);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16 bank_current = 0xffff;
|
||||||
|
void SwitchBank (uint16 bank)
|
||||||
|
{
|
||||||
|
if (bank == bank_current) return;
|
||||||
|
|
||||||
|
REGS regs;
|
||||||
|
regs.x.ax = 0x4F05;
|
||||||
|
regs.x.bx = 0;
|
||||||
|
regs.x.dx = bank;
|
||||||
|
int86(0x10, ®s, ®s);
|
||||||
|
|
||||||
|
bank_current = bank;
|
||||||
|
}
|
||||||
|
|
||||||
|
modeInfo* CurrentMode;
|
||||||
|
|
||||||
|
void PutPixel (int x, int y, uint16 color)
|
||||||
|
{
|
||||||
|
unsigned address = (y * CurrentMode->Xres) + x;
|
||||||
|
unsigned bank_size = CurrentMode->granularity * 1024;
|
||||||
|
unsigned bank_number = address / bank_size;
|
||||||
|
unsigned bank_offset = address % bank_size;
|
||||||
|
|
||||||
|
SwitchBank (bank_number);
|
||||||
|
|
||||||
|
uint16 far* ptr = (uint16 far*) (bank_offset + 0xA0000l);
|
||||||
|
*ptr = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetBestMode (uint16 X, uint16 Y, uint8 bpp)
|
||||||
|
{
|
||||||
|
vbeInfo* info = (vbeInfo*) malloc (sizeof(vbeInfo) * 2);
|
||||||
|
modeInfo* modeinf = (modeInfo*) malloc (sizeof(modeInfo) * 4);
|
||||||
|
|
||||||
|
strncpy(info->Signature, "VBE2", 4);
|
||||||
|
|
||||||
|
if (GetInfo(info) != 0x4F) {
|
||||||
|
printf("Error\n"); return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16 far* modes = (uint16 far*) info->VideoModes;
|
||||||
|
uint16 best = 0x13;
|
||||||
|
uint16 bestpixdiff = (320 * 200) - (X * Y);
|
||||||
|
uint16 bestdppdiff = 8 >= bpp ? 8 - bpp : (bpp - 8) * 2;
|
||||||
|
|
||||||
|
for (int i = 0; modes[i] != 0xFFFF; i++)
|
||||||
|
{
|
||||||
|
if (GetModeInfo(modeinf, modes[i]) != 0x4F) continue;
|
||||||
|
if ((modeinf->attributes & 0x90) != 0x90) continue;
|
||||||
|
if (modeinf->memory_model != 4 && modeinf->memory_model != 6) continue;
|
||||||
|
|
||||||
|
if (X == modeinf->Xres && Y == modeinf->Yres && bpp == modeinf->bpp) {
|
||||||
|
best = modes[i]; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16 pixdiff = (modeinf->Xres * modeinf->Yres) - (X*Y);
|
||||||
|
uint16 dppdiff = (modeinf->bpp >= bpp) ? (modeinf->bpp - bpp) : (bpp - modeinf->bpp);
|
||||||
|
if ( bestpixdiff > pixdiff || (bestpixdiff == pixdiff && bestdppdiff > dppdiff) )
|
||||||
|
{
|
||||||
|
best = modes[i];
|
||||||
|
bestpixdiff = pixdiff;
|
||||||
|
bestdppdiff = dppdiff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CurrentMode = modeinf;
|
||||||
|
GetModeInfo(CurrentMode, best);
|
||||||
|
printf("Best mode found: %ux%u %ubpp\n", CurrentMode->Xres, CurrentMode->Yres, CurrentMode->bpp);
|
||||||
|
|
||||||
|
// Set mode
|
||||||
|
SetMode (best);
|
||||||
|
|
||||||
|
free (info);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
SetBestMode(800, 600, 15);
|
||||||
|
|
||||||
|
for (int i = 0; i < 700; i++)
|
||||||
|
for (int j = 0; j < 500; j++)
|
||||||
|
PutPixel (i, j, 0x7FFF - i - j);
|
||||||
|
|
||||||
|
free (CurrentMode);
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user