⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 winbgi.cpp

📁 一个在电脑上运行的时钟
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//
// winbgi.cpp  -- One of the files required to run BGI graphics programs
//
// You don't need to edit this file, or print it out.

#include "graphics.h"

//namespace bgi {

#include <windows.h>
#include <stddef.h>
#include <stdio.h>
#include <math.h>


#define MAX_PAGES 16

static HDC hdc[4];

static HPEN hPen;
static HRGN hRgn;
static HFONT hFont;
static NPLOGPALETTE pPalette;
static PAINTSTRUCT ps;
static HWND hWnd;
static HBRUSH hBrush[USER_FILL+1];
static HBRUSH hBackgroundBrush;

static HPALETTE hPalette;
static HBITMAP hBitmap[MAX_PAGES];
static HBITMAP hPutimageBitmap;

static int timeout_expired;

#define PEN_CACHE_SIZE   8
#define FONT_CACHE_SIZE  8 
#define BG               64
#define TIMER_ID         1

//
// When XOR or NOT write modes are used for drawing high BG bit is cleared, so
// drawing colors should be adjusted to preserve this bit
// 
#define ADJUSTED_MODE(mode) ((mode) == XOR_PUT || (mode) == NOT_PUT)

int bgiemu_handle_redraw = TRUE;
int bgiemu_default_mode = VGAHI; //VGAMAX;

static int screen_width;
static int screen_height;
static int window_width;
static int window_height;

//Mouse info    (Added 1-Oct-2000, Matthew Weathers)
static bool bMouseUp = false;
static bool bMouseDown = false;
static int iCurrentMouseX = 0;
static int iCurrentMouseY = 0;
static int iClickedMouseX = 0;
static int iClickedMouseY = 0;
static int iWhichMouseButton = LEFT_BUTTON;

static int line_style_cnv[] = {
    PS_SOLID, PS_DOT, PS_DASHDOT, PS_DASH, 
    PS_DASHDOTDOT /* if user style lines are not supported */
}; 
static int write_mode_cnv[] = 
  {R2_COPYPEN, R2_XORPEN, R2_MERGEPEN, R2_MASKPEN, R2_NOTCOPYPEN};
static int bitblt_mode_cnv[] = 
  {SRCCOPY, SRCINVERT, SRCPAINT, SRCAND, NOTSRCCOPY};

static int font_weight[] = 
{ 
    FW_BOLD,    // DefaultFont
    FW_NORMAL,  // TriplexFont
    FW_NORMAL,  // SmallFont
    FW_NORMAL,  // SansSerifFont
    FW_NORMAL,  // GothicFont
    FW_NORMAL,  // ScriptFont
    FW_NORMAL,  // SimplexFont
    FW_NORMAL,  // TriplexScriptFont
    FW_NORMAL,  // ComplexFont
    FW_NORMAL,  // EuropeanFont
    FW_BOLD     // BoldFont
};

static int font_family[] = 
{
    FIXED_PITCH|FF_DONTCARE,     // DefaultFont
    VARIABLE_PITCH|FF_ROMAN,     // TriplexFont
    VARIABLE_PITCH|FF_MODERN,    // SmallFont
    VARIABLE_PITCH|FF_DONTCARE,  // SansSerifFont
    VARIABLE_PITCH|FF_SWISS,     // GothicFont
    VARIABLE_PITCH|FF_SCRIPT,    // ScriptFont
    VARIABLE_PITCH|FF_DONTCARE,  // SimplexFont
    VARIABLE_PITCH|FF_SCRIPT,    // TriplexScriptFont
    VARIABLE_PITCH|FF_DONTCARE,  // ComplexFont
    VARIABLE_PITCH|FF_DONTCARE,  // EuropeanFont
    VARIABLE_PITCH|FF_DONTCARE   // BoldFont
  };

static char* font_name[] = 
{
    "Console",          // DefaultFont
    "Times New Roman",  // TriplexFont
    "Small Fonts",      // SmallFont
    "MS Sans Serif",    // SansSerifFont
    "Arial",            // GothicFont
    "Script",           // ScriptFont
    "Times New Roman",  // SimplexFont
    "Script",           // TriplexScriptFont
    "Courier New",      // ComplexFont
    "Times New Roman",  // EuropeanFont
    "Courier New Bold", // BoldFont
};

static int text_halign_cnv[] = {TA_LEFT, TA_CENTER, TA_RIGHT};  
static int text_valign_cnv[] = {TA_BOTTOM, TA_BASELINE, TA_TOP};

static palettetype current_palette;

static struct { int width; int height; } font_metrics[][11] = { 
{{0,0},{8,8},{16,16},{24,24},{32,32},{40,40},{48,48},{56,56},{64,64},{72,72},{80,80}}, // DefaultFont
{{0,0},{13,18},{14,20},{16,23},{22,31},{29,41},{36,51},{44,62},{55,77},{66,93},{88,124}}, // TriplexFont
{{0,0},{3,5},{4,6},{4,6},{6,9},{8,12},{10,15},{12,18},{15,22},{18,27},{24,36}}, // SmallFont
{{0,0},{11,19},{12,21},{14,24},{19,32},{25,42},{31,53},{38,64},{47,80},{57,96},{76,128}}, // SansSerifFont 
{{0,0},{13,19},{14,21},{16,24},{22,32},{29,42},{36,53},{44,64},{55,80},{66,96},{88,128}}, // GothicFont
// I am not sure about metrics of following fonts
{{0,0},{11,19},{12,21},{14,24},{19,32},{25,42},{31,53},{38,64},{47,80},{57,96},{76,128}}, // ScriptFont
{{0,0},{11,19},{12,21},{14,24},{19,32},{25,42},{31,53},{38,64},{47,80},{57,96},{76,128}}, // SimplexFont
{{0,0},{13,18},{14,20},{16,23},{22,31},{29,41},{36,51},{44,62},{55,77},{66,93},{88,124}}, // TriplexScriptFont
{{0,0},{11,19},{12,21},{14,24},{19,32},{25,42},{31,53},{38,64},{47,80},{57,96},{76,128}}, // ComplexFont
{{0,0},{11,19},{12,21},{14,24},{19,32},{25,42},{31,53},{38,64},{47,80},{57,96},{76,128}}, // EuropeanFont
{{0,0},{11,19},{12,21},{14,24},{19,32},{25,42},{31,53},{38,64},{47,80},{57,96},{76,128}} // BoldFont
}; 

struct BGIimage { 
    short width;
    short height;
    int   reserved; // let bits be aligned to DWORD boundary
    char  bits[1];
};

struct BGIbitmapinfo { 
    BITMAPINFOHEADER hdr;
    short            color_table[64];
};
    
static BGIbitmapinfo bminfo = {
    {sizeof(BITMAPINFOHEADER), 0, 0, 1, 4, BI_RGB}
};

//static int* image_bits; //Bill 2006

static int normal_font_size[] = { 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4};

static linesettingstype line_settings;
static fillsettingstype fill_settings;

static int color;
static int bkcolor;
static int text_color;

static int aspect_ratio_x, aspect_ratio_y;

static textsettingstype text_settings;

static viewporttype view_settings;

static int font_mul_x, font_div_x, font_mul_y, font_div_y;

static enum { ALIGN_NOT_SET, UPDATE_CP, NOT_UPDATE_CP } text_align_mode; 

#define BORDER_WIDTH  8 
#define BORDER_HEIGHT 27

static int write_mode;

static int visual_page;
static int active_page;

static arccoordstype ac;

class char_queue { 
  protected:
    char* buf; 
    int   put_pos;
    int   get_pos;
    int   buf_size; 
  public:
    void  put(char ch) { 
	buf[put_pos] = ch; 
	if (++put_pos == buf_size) { 
	    put_pos = 0;
	}
	if (put_pos == get_pos) { // queue is full
	    (void)get(); // loose one character
	}
    }
    char get() { 
	char ch = buf[get_pos]; 
	if (++get_pos == buf_size) { 
	    get_pos = 0;
	}
	return ch;
    }
    bool is_empty() { 
	return get_pos == put_pos; 
    }
    char_queue(int buf_size = 256) { 
	put_pos = get_pos = 0;
	this->buf_size = buf_size;
	buf = new char[buf_size]; 
    }
    ~char_queue() { 
	delete[] buf; 
    }
};

static char_queue kbd_queue;

inline int convert_userbits(DWORD buf[32], unsigned pattern)
{
    int i = 0, j;
    pattern &= 0xFFFF;

    while (true) { 
	for (j = 0; pattern & 1; j++) pattern >>= 1;
	buf[i++] = j;
	if (pattern == 0) { 
	    buf[i++] = 16 - j;
	    return i;
	}
	for (j = 0; !(pattern & 1); j++) pattern >>= 1;
	buf[i++] = j;
    }
} 


class l2elem { 
  public: 
    l2elem* next;
    l2elem* prev;

    void link_after(l2elem* after) { 
	(next = after->next)->prev = this;
	(prev = after)->next = this;
    }
    void unlink() { 
	prev->next = next;
	next->prev = prev;
    }
    void prune() { 
	next = prev = this;
    }
};

class l2list : public l2elem { 
  public:
    l2list() { prune(); }
};

class pen_cache : public l2list { 
    class pen_cache_item : public l2elem {
      public:
    	HPEN pen;
        int  color;
	int  width;
	int  style;
	unsigned pattern;
    };  
    pen_cache_item* free;
    pen_cache_item  cache[PEN_CACHE_SIZE];

  public: 
    pen_cache() { 
	for (int i = 0; i < PEN_CACHE_SIZE-1; i++) { 
	    cache[i].next = &cache[i+1];
	}
	cache[PEN_CACHE_SIZE-1].next = NULL;
	free = cache;
    }
    void select(int color) 
    {
	for (l2elem* elem = next; elem != this; elem = elem->next) { 
	    pen_cache_item* ci = (pen_cache_item*)elem;
	    if (ci->color == color &&
		ci->style == line_settings.linestyle &&
		ci->width == line_settings.thickness &&
		(line_settings.linestyle != USERBIT_LINE 
		 || line_settings.upattern == ci->pattern))
	    {
		ci->unlink(); // LRU discipline
		ci->link_after(this); 

		if (hPen != ci->pen) { 
		    hPen = ci->pen;
		    SelectObject(hdc[0], hPen);
		    SelectObject(hdc[1], hPen);
		}
		return;	    
	    }
	}
	hPen = NULL;
	if (line_settings.linestyle == USERBIT_LINE) { 
	    LOGBRUSH lb;
	    lb.lbColor = PALETTEINDEX(color);
	    lb.lbStyle = BS_SOLID;
	    DWORD style[32]; 
	    hPen = ExtCreatePen(PS_GEOMETRIC|PS_USERSTYLE, 
				line_settings.thickness, &lb, 
				convert_userbits(style,line_settings.upattern),
				style);
	} 
	if (hPen == NULL) { 
	    hPen = CreatePen(line_style_cnv[line_settings.linestyle], 
			     line_settings.thickness, 
			     PALETTEINDEX(color));
	}
	SelectObject(hdc[0], hPen);
	SelectObject(hdc[1], hPen);
	
	pen_cache_item* p;
	if (free == NULL) {
	    p = (pen_cache_item*)prev; 
	    p->unlink();
	    DeleteObject(p->pen);	    
	} else { 
	    p = free;
	    free = (pen_cache_item*)p->next;
	}
	p->pen   = hPen;
	p->color = color;
	p->width = line_settings.thickness;
	p->style = line_settings.linestyle;
	p->pattern = line_settings.upattern;
	p->link_after(this);
    }  
};	


static pen_cache pcache;



class font_cache : public l2list { 
    class font_cache_item : public l2elem {
      public:
    	HFONT font;
        int   type;
	int   direction;
	int   width, height;
    };  
    font_cache_item* free;
    font_cache_item  cache[FONT_CACHE_SIZE];

  public: 
    font_cache() { 
	for (int i = 0; i < FONT_CACHE_SIZE-1; i++) { 
	    cache[i].next = &cache[i+1];
	}
	cache[FONT_CACHE_SIZE-1].next = NULL;
	free = cache;
    }
    void select(int type, int direction, int width, int height) 
    {
	for (l2elem* elem = next; elem != this; elem = elem->next) { 
	    font_cache_item* ci = (font_cache_item*)elem;
	    if (ci->type == type &&
		ci->direction == direction &&
		ci->width == width &&
		ci->height == height)
	    {
		ci->unlink();
		ci->link_after(this);

		if (hFont != ci->font) { 
		    hFont = ci->font;
		    SelectObject(hdc[0], hFont);
		    SelectObject(hdc[1], hFont);
		}
		return;	    
	    }
	}
	hFont = CreateFont(-height,
			   width,
			   direction*900,
			   (direction&1)*900,
			   font_weight[type],
			   FALSE,
			   FALSE,
			   FALSE,
			   DEFAULT_CHARSET, 
			   OUT_DEFAULT_PRECIS,
			   CLIP_DEFAULT_PRECIS,
			   DEFAULT_QUALITY,
			   font_family[type], 
			   font_name[type]);
	SelectObject(hdc[0], hFont);
	SelectObject(hdc[1], hFont);
	
	font_cache_item* p;
	if (free == NULL) {
	    p = (font_cache_item*)prev; 
	    p->unlink();
	    DeleteObject(p->font);	    
	} else { 
	    p = free;
	    free = (font_cache_item*)p->next;
	}
	p->font = hFont;
	p->type = type;
	p->width = width;
	p->height = height;
	p->direction = direction;
	p->link_after(this);
    }  
};	


static font_cache fcache;


#define FLAGS         PC_NOCOLLAPSE
#define PALETTE_SIZE  256

static PALETTEENTRY BGIcolor[64] = {
		{ 0, 0, 0, FLAGS },        // 0
		{ 0, 0, 255, FLAGS },        // 1
		{ 0, 255, 0, FLAGS },        // 2
		{ 0, 255, 255, FLAGS },        // 3
		{ 255, 0, 0, FLAGS },        // 4
		{ 255, 0, 255, FLAGS },         // 5
		{ 165, 42, 42, FLAGS },        // 6
		{ 211, 211, 211, FLAGS },         // 7
		{ 47, 79, 79, FLAGS },        // 8
		{ 173, 216, 230, FLAGS },        // 9
		{ 32, 178, 170, FLAGS },        // 10
		{ 224, 255, 255, FLAGS },        // 11
		{ 240, 128, 128, FLAGS },        // 12
		{ 219, 112, 147, FLAGS },        // 13
		{ 255, 255, 0, FLAGS },        // 14
		{ 255, 255, 255, FLAGS },        // 15
        { 0xF0, 0xF8, 0xFF, FLAGS },        // 16
        { 0xFA, 0xEB, 0xD7, FLAGS },        // 17
        { 0x22, 0x85, 0xFF, FLAGS },        // 18
        { 0x7F, 0xFF, 0xD4, FLAGS },        // 19
        { 0xF0, 0xFF, 0xFF, FLAGS },        // 20
        { 0xF5, 0xF5, 0xDC, FLAGS },        // 21
        { 0xFF, 0xE4, 0xC4, FLAGS },        // 22
        { 0xFF, 0x7B, 0xCD, FLAGS },        // 23
        { 0x00, 0x00, 0xFF, FLAGS },        // 24
        { 0x8A, 0x2B, 0xE2, FLAGS },        // 25
        { 0xA5, 0x2A, 0x2A, FLAGS },        // 26
        { 0xDE, 0xB8, 0x87, FLAGS },        // 27
        { 0x5F, 0x9E, 0xA0, FLAGS },        // 28
        { 0x7F, 0xFF, 0x00, FLAGS },        // 29
        { 0xD2, 0x50, 0x1E, FLAGS },        // 30
        { 0xFF, 0x7F, 0x50, FLAGS },        // 31
        { 0x64, 0x95, 0xED, FLAGS },        // 32
        { 0xFF, 0xF8, 0xDC, FLAGS },        // 33
        { 0xDC, 0x14, 0x3C, FLAGS },        // 34
        { 0x68, 0xCF, 0xDF, FLAGS },        // 35
        { 0x00, 0x00, 0x8B, FLAGS },        // 36
        { 0x00, 0x8B, 0x8B, FLAGS },        // 37
        { 0xB8, 0x86, 0x0B, FLAGS },        // 38
        { 0xA9, 0xA9, 0xA9, FLAGS },        // 39
        { 0x00, 0x64, 0x00, FLAGS },        // 40
        { 0xBD, 0xB7, 0x6B, FLAGS },        // 41
        { 0x8B, 0x00, 0x8B, FLAGS },        // 42
        { 0x55, 0x6B, 0x2F, FLAGS },        // 43
        { 0xFF, 0x8C, 0x00, FLAGS },        // 44
        { 0xB9, 0x82, 0xFC, FLAGS },        // 45
        { 0x8B, 0x00, 0x00, FLAGS },        // 46
        { 0xE9, 0x96, 0x7A, FLAGS },        // 47
        { 0x8F, 0xBC, 0x8F, FLAGS },        // 48
        { 0x48, 0x3D, 0x8B, FLAGS },        // 49
        { 0x2F, 0x4F, 0x4F, FLAGS },        // 50
        { 0x00, 0xCE, 0xD1, FLAGS },        // 51
        { 0x94, 0x00, 0xD3, FLAGS },        // 52
        { 0xFF, 0x14, 0x93, FLAGS },        // 53
        { 0x00, 0xBF, 0xFF, FLAGS },        // 54
        { 0x69, 0x69, 0x69, FLAGS },        // 55
        { 0x1E, 0x90, 0xFF, FLAGS },        // 56
        { 0xB2, 0x22, 0x22, FLAGS },        // 57
        { 0xFF, 0xFA, 0xF0, FLAGS },        // 58
        { 0x22, 0x8B, 0x22, FLAGS },        // 59
        { 0xFF, 0x00, 0xFF, FLAGS },        // 60
        { 0xDC, 0xDC, 0xDC, FLAGS },        // 61
        { 0xF8, 0xF8, 0xBF, FLAGS },        // 62
        { 0xFF, 0xD7, 0x00, FLAGS },        // 63
};
    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -