📄 graphics.cpp
字号:
void setwritemode(int mode)
{
write_mode = mode;
}
void setpalette(int index, int color)
{
color &= MAXCOLORS;
BGIpalette[index] = BGIcolor[color];
current_palette.colors[index] = color;
SetPaletteEntries(hPalette, BG+index, 1, &BGIpalette[index]);
RealizePalette(hdc[0]);
if (index == 0) {
bkcolor = 0;
}
}
void setrgbpalette(int index, int red, int green, int blue)
{
BGIpalette[index].peRed = red & 0xFC;
BGIpalette[index].peGreen = green & 0xFC;
BGIpalette[index].peBlue = blue & 0xFC;
SetPaletteEntries(hPalette, BG+index, 1, &BGIpalette[index]);
RealizePalette(hdc[0]);
if (index == 0) {
bkcolor = 0;
}
}
void setallpalette(palettetype* pal)
{
for (int i = 0; i < pal->size; i++) {
current_palette.colors[i] = pal->colors[i] & MAXCOLORS;
BGIpalette[i] = BGIcolor[pal->colors[i] & MAXCOLORS];
}
SetPaletteEntries(hPalette, BG, pal->size, BGIpalette);
RealizePalette(hdc[0]);
bkcolor = 0;
}
palettetype* getdefaultpalette()
{
static palettetype default_palette = { 64,
{ BLACK, BLUE, GREEN, CYAN, RED, MAGENTA, BROWN, LIGHTGRAY, DARKGRAY,
LIGHTBLUE, LIGHTGREEN, LIGHTCYAN, LIGHTRED, LIGHTMAGENTA, YELLOW, WHITE,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63
}};
return &default_palette;
}
void getpalette(palettetype* pal)
{
*pal = current_palette;
}
int getpalettesize()
{
return MAXCOLORS+1;
}
void setbkcolor(int color)
{
color &= MAXCOLORS;
BGIpalette[0] = BGIcolor[color];
SetPaletteEntries(hPalette, BG, 1, &BGIpalette[0]);
RealizePalette(hdc[0]);
bkcolor = color;
}
int getbkcolor()
{
return bkcolor;
}
void setfillstyle(int style, int color)
{
fill_settings.pattern = style;
fill_settings.color = color & MAXCOLORS;
SelectObject(hdc[0], hBrush[style]);
SelectObject(hdc[1], hBrush[style]);
}
void getfillsettings(fillsettingstype* fs)
{
*fs = fill_settings;
}
static fillpatterntype userfillpattern =
{-1, -1, -1, -1, -1, -1, -1, -1};
void setfillpattern(char const* upattern, int color)
{
static HBITMAP hFillBitmap;
static short bitmap_data[8];
for (int i = 0; i < 8; i++) {
bitmap_data[i] = (unsigned char)~upattern[i];
userfillpattern[i] = upattern[i];
}
HBITMAP h = CreateBitmap(8, 8, 1, 1, bitmap_data);
HBRUSH hb = CreatePatternBrush(h);
DeleteObject(hBrush[USER_FILL]);
if (hFillBitmap) {
DeleteObject(hFillBitmap);
}
hFillBitmap = h;
hBrush[USER_FILL] = hb;
SelectObject(hdc[0], hb);
SelectObject(hdc[1], hb);
fill_settings.color = color & MAXCOLORS;
fill_settings.pattern = USER_FILL;
}
void getfillpattern(fillpatterntype fp)
{
memcpy(fp, userfillpattern, sizeof userfillpattern);
}
inline void select_fill_color()
{
if (text_color != fill_settings.color) {
text_color = fill_settings.color;
SetTextColor(hdc[0], PALETTEINDEX(text_color+BG));
SetTextColor(hdc[1], PALETTEINDEX(text_color+BG));
}
}
void setusercharsize(int multx, int divx, int multy, int divy)
{
font_mul_x = multx;
font_div_x = divx;
font_mul_y = multy;
font_div_y = divy;
text_settings.charsize = 0;
}
void moveto(int x, int y)
{
if (bgiemu_handle_redraw || visual_page != active_page) {
MoveToEx(hdc[1], x, y, NULL);
}
if (visual_page == active_page) {
MoveToEx(hdc[0], x, y, NULL);
}
}
void moverel(int dx, int dy)
{
POINT pos;
GetCurrentPositionEx(hdc[1], &pos);
moveto(pos.x + dx, pos.y + dy);
}
static void select_font()
{
if (text_settings.charsize == 0) {
fcache.select(text_settings.font, text_settings.direction,
font_metrics[text_settings.font]
[normal_font_size[text_settings.font]].width
*font_mul_x/font_div_x,
font_metrics[text_settings.font]
[normal_font_size[text_settings.font]].height
*font_mul_y/font_div_y);
} else {
fcache.select(text_settings.font, text_settings.direction,
font_metrics[text_settings.font][text_settings.charsize].width,
font_metrics[text_settings.font][text_settings.charsize].height);
}
}
static void text_output(int x, int y, const char* str)
{
select_font();
if (text_color != color) {
text_color = color;
SetTextColor(hdc[0], PALETTEINDEX(text_color+BG));
SetTextColor(hdc[1], PALETTEINDEX(text_color+BG));
}
if (bgiemu_handle_redraw || visual_page != active_page) {
TextOut(hdc[1], x, y, str, strlen(str));
}
if (visual_page == active_page) {
TextOut(hdc[0], x, y, str, strlen(str));
}
}
void settextstyle(int font, int direction, int char_size)
{
if (char_size > 10) {
char_size = 10;
}
text_settings.direction = direction;
text_settings.font = font;
text_settings.charsize = char_size;
text_align_mode = ALIGN_NOT_SET;
}
void settextjustify(int horiz, int vert)
{
text_settings.horiz = horiz;
text_settings.vert = vert;
text_align_mode = ALIGN_NOT_SET;
}
void gettextsettings(textsettingstype* ts)
{
*ts = text_settings;
}
int textheight(const char* str)
{
SIZE ss;
select_font();
GetTextExtentPoint32(hdc[0], str, strlen(str), &ss);
return ss.cy;
}
int textwidth(const char* str)
{
SIZE ss;
select_font();
GetTextExtentPoint32(hdc[0], str, strlen(str), &ss);
return ss.cx;
}
void outtext(const char* str)
{
if (text_align_mode != UPDATE_CP) {
text_align_mode = UPDATE_CP;
int align = (text_settings.direction == HORIZ_DIR)
? (TA_UPDATECP |
text_halign_cnv[text_settings.horiz] |
text_valign_cnv[text_settings.vert])
: (TA_UPDATECP |
text_valign_cnv[text_settings.horiz] |
text_halign_cnv[text_settings.vert]);
SetTextAlign(hdc[0], align);
SetTextAlign(hdc[1], align);
}
text_output(0, 0, str);
}
void outtextxy(int x, int y, const char* str)
{
if (text_align_mode != NOT_UPDATE_CP) {
text_align_mode = NOT_UPDATE_CP;
int align = (text_settings.direction == HORIZ_DIR)
? (TA_NOUPDATECP |
text_halign_cnv[text_settings.horiz] |
text_valign_cnv[text_settings.vert])
: (TA_NOUPDATECP |
text_valign_cnv[text_settings.horiz] |
text_halign_cnv[text_settings.vert]);
SetTextAlign(hdc[0], align);
SetTextAlign(hdc[1], align);
}
text_output(x, y, str);
}
void setviewport(int x1, int y1, int x2, int y2, int clip)
{
view_settings.left = x1;
view_settings.top = y1;
view_settings.right = x2;
view_settings.bottom = y2;
view_settings.clip = clip;
if (hRgn) {
DeleteObject(hRgn);
}
hRgn = clip ? CreateRectRgn(x1, y1, x2, y2) : NULL;
SelectClipRgn(hdc[1], hRgn);
SetViewportOrgEx(hdc[1], x1, y1, NULL);
SelectClipRgn(hdc[0], hRgn);
SetViewportOrgEx(hdc[0], x1, y1, NULL);
moveto(0,0);
}
void getviewsettings(viewporttype *viewport)
{
*viewport = view_settings;
}
const double pi = 3.14159265358979323846;
inline void arc_coords(double angle, double rx, double ry, int& x, int& y)
{
if (rx == 0 || ry == 0) {
x = y = 0;
return;
}
double s = sin(angle*pi/180.0);
double c = cos(angle*pi/180.0);
if (fabs(s) < fabs(c)) {
double tg = s/c;
double xr = sqrt((double)rx*rx*ry*ry/(ry*ry+rx*rx*tg*tg));
x = int((c >= 0) ? xr : -xr);
y = int((s >= 0) ? -xr*tg : xr*tg);
} else {
double ctg = c/s;
double yr = sqrt((double)rx*rx*ry*ry/(rx*rx+ry*ry*ctg*ctg));
x = int((c >= 0) ? yr*ctg : -yr*ctg);
y = int((s >= 0) ? -yr : yr);
}
}
void ellipse(int x, int y, int start_angle, int end_angle,
int rx, int ry)
{
ac.x = x;
ac.y = y;
arc_coords(start_angle, rx, ry, ac.xstart, ac.ystart);
arc_coords(end_angle, rx, ry, ac.xend, ac.yend);
ac.xstart += x; ac.ystart += y;
ac.xend += x; ac.yend += y;
pcache.select(color+BG);
if (bgiemu_handle_redraw || visual_page != active_page) {
Arc(hdc[1], x-rx, y-ry, x+rx, y+ry,
ac.xstart, ac.ystart, ac.xend, ac.yend);
}
if (visual_page == active_page) {
Arc(hdc[0], x-rx, y-ry, x+rx, y+ry,
ac.xstart, ac.ystart, ac.xend, ac.yend);
}
}
void fillellipse(int x, int y, int rx, int ry)
{
pcache.select(color+BG);
select_fill_color();
if (bgiemu_handle_redraw || visual_page != active_page) {
Ellipse(hdc[1], x-rx, y-ry, x+rx, y+ry);
}
if (visual_page == active_page) {
Ellipse(hdc[0], x-rx, y-ry, x+rx, y+ry);
}
}
static void allocate_new_graphic_page(int page)
{
RECT scr;
scr.left = -view_settings.left;
scr.top = -view_settings.top;
scr.right = screen_width-view_settings.left-1;
scr.bottom = screen_height-view_settings.top-1;
hBitmap[page] = CreateCompatibleBitmap(hdc[0],screen_width,screen_height);
SelectObject(hdc[1], hBitmap[page]);
SelectClipRgn(hdc[1], NULL);
FillRect(hdc[1], &scr, hBackgroundBrush);
SelectClipRgn(hdc[1], hRgn);
}
void setactivepage(int page)
{
if (hBitmap[page] == NULL) {
allocate_new_graphic_page(page);
} else {
SelectObject(hdc[1], hBitmap[page]);
}
if (!bgiemu_handle_redraw && active_page == visual_page) {
POINT pos;
GetCurrentPositionEx(hdc[0], &pos);
MoveToEx(hdc[1], pos.x, pos.y, NULL);
}
active_page = page;
}
void setvisualpage(int page)
{
POINT pos;
if (hdc[page] == NULL) {
allocate_new_graphic_page(page);
}
if (!bgiemu_handle_redraw && active_page == visual_page) {
SelectObject(hdc[1], hBitmap[visual_page]);
SelectClipRgn(hdc[1], NULL);
BitBlt(hdc[1], -view_settings.left, -view_settings.top,
window_width, window_height,
hdc[0], -view_settings.left, -view_settings.top,
SRCCOPY);
SelectClipRgn(hdc[1], hRgn);
GetCurrentPositionEx(hdc[0], &pos);
MoveToEx(hdc[1], pos.x, pos.y, NULL);
}
SelectClipRgn(hdc[0], NULL);
SelectClipRgn(hdc[1], NULL);
SelectObject(hdc[1], hBitmap[page]);
BitBlt(hdc[0], -view_settings.left,
-view_settings.top, window_width, window_height,
hdc[1], -view_settings.left, -view_settings.top, SRCCOPY);
SelectClipRgn(hdc[0], hRgn);
SelectClipRgn(hdc[1], hRgn);
if (page != active_page) {
SelectObject(hdc[1], hBitmap[active_page]);
}
if (active_page != visual_page) {
GetCurrentPositionEx(hdc[1], &pos);
MoveToEx(hdc[0], pos.x, pos.y, NULL);
}
visual_page = page;
}
void setaspectratio(int ax, int ay)
{
aspect_ratio_x = ax;
aspect_ratio_y = ay;
}
void getaspectratio(int* ax, int* ay)
{
*ax = aspect_ratio_x;
*ay = aspect_ratio_y;
}
void circle(int x, int y, int radius)
{
pcache.select(color+BG);
int ry = (unsigned)radius*aspect_ratio_x/aspect_ratio_y;
int rx = radius;
if (bgiemu_handle_redraw || visual_page != active_page) {
Arc(hdc[1], x-rx, y-ry, x+rx, y+ry, x+rx, y, x+rx, y);
}
if (visual_page == active_page) {
Arc(hdc[0], x-rx, y-ry, x+rx, y+ry, x+rx, y, x+rx, y);
}
}
void arc(int x, int y, int start_angle, int end_angle, int radius)
{
ac.x = x;
ac.y = y;
ac.xstart = x + int(radius*cos(start_angle*pi/180.0));
ac.ystart = y - int(radius*sin(start_angle*pi/180.0));
ac.xend = x + int(radius*cos(end_angle*pi/180.0));
ac.yend = y - int(radius*sin(end_angle*pi/180.0));
if (bgiemu_handle_redraw || visual_page != active_page) {
Arc(hdc[1], x-radius, y-radius, x+radius, y+radius,
ac.xstart, ac.ystart, ac.xend, ac.yend);
}
if (visual_page == active_page) {
Arc(hdc[0], x-radius, y-radius, x+radius, y+radius,
ac.xstart, ac.ystart, ac.xend, ac.yend);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -