00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "global.h"
00022 #include "htcurses.h"
00023
00024 #include <stdio.h>
00025 #include <stdlib.h>
00026 #include <string.h>
00027
00028 #define WIN32_LEAN_AND_MEAN
00029 #include <windows.h>
00030
00031
00032 #ifdef __RSXNT__
00033 extern "C" {
00034 int __dj_stderr;
00035 }
00036 #endif
00037
00038 HANDLE output;
00039
00040
00041
00042
00043 screendrawbuf::screendrawbuf(char *title)
00044 {
00045 bounds b;
00046 CONSOLE_SCREEN_BUFFER_INFO screen_info;
00047
00048 buf = NULL;
00049 cursorx = 0;
00050 cursory = 0;
00051
00052 init_console();
00053
00054 GetConsoleScreenBufferInfo(output, &screen_info);
00055
00056 SetConsoleTitleA(title);
00057
00058 b.x = 0;
00059 b.y = 0;
00060
00061
00062 b.w = screen_info.srWindow.Right - screen_info.srWindow.Left + 1;
00063 b.h = screen_info.srWindow.Bottom - screen_info.srWindow.Top + 1;
00064 b_setbounds(&b);
00065
00066 cursor_visible = true;
00067 cursor_redraw = true;
00068 hidecursor();
00069 show();
00070 }
00071
00072 screendrawbuf::~screendrawbuf()
00073 {
00074
00075 b_printchar(size.w-1, size.h-1, VCP(VC_WHITE, VC_BLACK), ' ');
00076
00077 setcursor(0, size.h-1);
00078 show();
00079 if (buf) free(buf);
00080 }
00081
00082 bool screendrawbuf::init_console()
00083 {
00084 CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
00085 SMALL_RECT windowRect;
00086
00087 output = GetStdHandle(STD_OUTPUT_HANDLE);
00088
00089 if (output == INVALID_HANDLE_VALUE) return false;
00090 if (SetConsoleActiveScreenBuffer(output) == FALSE) return false;
00091 if (!GetConsoleScreenBufferInfo(output, &csbiInfo)) return false;
00092 windowRect.Left = 0;
00093 windowRect.Top = 0;
00094 windowRect.Right = csbiInfo.dwSize.X - 1;
00095 windowRect.Bottom = csbiInfo.dwSize.Y - 1;
00096 if (!SetConsoleWindowInfo(output, TRUE, &windowRect)) return false;
00097 if (SetConsoleMode(output, 0) == FALSE) return false;
00098 return true;
00099 }
00100
00101 void screendrawbuf::drawbuffer(drawbuf *b, int x, int y, bounds *clipping)
00102 {
00103 drawbufch *ch=b->buf;
00104 for (int iy=0; iy<b->size.h; iy++) {
00105 int dest = x+(iy+y)*size.w;
00106 if (y+iy>=clipping->y+clipping->h) break;
00107 if (y+iy>=clipping->y)
00108 for (int ix=0; ix<b->size.w; ix++) {
00109 if ((x+ix<clipping->x+clipping->w) && (x+ix>=clipping->x)) {
00110 put_vc(dest, ch->ch, ch->c);
00111 }
00112 dest++;
00113 ch++;
00114 }
00115 }
00116 }
00117
00118 void screendrawbuf::b_fill(int x, int y, int w, int h, int c, int ch)
00119 {
00120 for (int i=0; i<h; i++) {
00121 int dest = x+(i+y)*size.w;
00122 if (y+i>=size.h) break;
00123 if (y+i>=0)
00124 for (int j=0; j<w; j++) {
00125 if (x+j>=0) put_vc(dest, ch, c);
00126 if (x+j>=size.w-1) break;
00127 dest++;
00128 }
00129 }
00130 }
00131
00132 void screendrawbuf::b_printchar(int x, int y, int c, int ch)
00133 {
00134 int dest = x+y*size.w;
00135 put_vc(dest, ch, c);
00136 }
00137
00138 int screendrawbuf::b_lprint(int x, int y, int c, int l, char *text)
00139 {
00140 int n=0;
00141 int dest = x+y*size.w;
00142 while ((*text) && (n<l)) {
00143 put_vc(dest, (unsigned char)*text, c);
00144 dest++;
00145 text++;
00146 n++;
00147 }
00148 return n;
00149 }
00150
00151 int screendrawbuf::b_lprintw(int x, int y, int c, int l, int *text)
00152 {
00153 int n=0;
00154 int dest = x+y*size.w;
00155 while ((*text) && (n<l)) {
00156 put_vc(dest, (unsigned char)*text, c);
00157 dest++;
00158 text++;
00159 n++;
00160 }
00161 return n;
00162 }
00163
00164 void screendrawbuf::b_resize(int rw, int rh)
00165 {
00166
00167 }
00168
00169 void screendrawbuf::b_rmove(int rx, int ry)
00170 {
00171
00172 }
00173
00174 void screendrawbuf::b_setbounds(bounds *b)
00175 {
00176 genericdrawbuf::b_setbounds(b);
00177 if (buf) free(buf);
00178 buf = (CHAR_INFO *)malloc(size.w * size.h * sizeof(CHAR_INFO));
00179 b_fill(size.x, size.y, size.w, size.h, VCP(VC_WHITE, VC_BLACK), ' ');
00180 }
00181
00182 void screendrawbuf::show()
00183 {
00184 COORD xy, xy2;
00185 if (cursor_redraw) {
00186 xy.X=cursorx;
00187 xy.Y=cursory;
00188 SetConsoleCursorPosition(output, xy);
00189 cursor_redraw = false;
00190 }
00191 xy.X = 0;
00192 xy.Y = 0;
00193 xy2.X = size.w;
00194 xy2.Y = size.h;
00195 SMALL_RECT sr;
00196 sr.Left = 0;
00197 sr.Top = 0;
00198 sr.Right = size.w-1;
00199 sr.Bottom = size.h-1;
00200 WriteConsoleOutput(output, (CHAR_INFO *)buf, xy2, xy, &sr);
00201 }
00202
00203 void screendrawbuf::getcursor(int *x, int *y)
00204 {
00205 *x=cursorx;
00206 *y=cursory;
00207 }
00208
00209 void screendrawbuf::hidecursor()
00210 {
00211 if (cursor_visible) {
00212 COORD xy;
00213 xy.X=size.w-1;
00214 xy.Y=size.h-1;
00215 SetConsoleCursorPosition(output, xy);
00216 CONSOLE_CURSOR_INFO ci;
00217 ci.dwSize = 0xd;
00218 ci.bVisible = false;
00219 if (!SetConsoleCursorInfo(output, &ci)) {
00220 }
00221 cursor_visible = false;
00222 }
00223 }
00224
00225 void screendrawbuf::setcursor(int x, int y)
00226 {
00227 showcursor();
00228 cursorx=x;
00229 cursory=y;
00230 cursor_redraw = true;
00231 }
00232
00233 void screendrawbuf::setcursormode(bool override)
00234 {
00235 }
00236
00237 void screendrawbuf::showcursor()
00238 {
00239 if (!cursor_visible) {
00240 CONSOLE_CURSOR_INFO ci;
00241 ci.dwSize = 0xd;
00242 ci.bVisible = true;
00243 SetConsoleCursorInfo(output, &ci);
00244 cursor_visible = true;
00245 }
00246 }
00247
00248
00249
00250 void screendrawbuf::put_vc(int dest, char ch, int vc)
00251 {
00252 int fg, bg;
00253 if (VC_GET_BASECOLOR(VCP_BACKGROUND(vc))==VC_TRANSPARENT) {
00254 bg=((byte)((CHAR_INFO *)buf)[dest].Attributes)>>4;
00255 } else if (VC_GET_LIGHT(VCP_BACKGROUND(vc))) {
00256 bg=VC_GET_BASECOLOR(VCP_BACKGROUND(vc))+8;
00257 } else {
00258 bg=VC_GET_BASECOLOR(VCP_BACKGROUND(vc));
00259 }
00260 if (VC_GET_BASECOLOR(VCP_FOREGROUND(vc))==VC_TRANSPARENT) {
00261 fg=(byte)(((CHAR_INFO *)buf)[dest].Attributes&0xf);
00262 } else if (VC_GET_LIGHT(VCP_FOREGROUND(vc))) {
00263 fg=VC_GET_BASECOLOR(VCP_FOREGROUND(vc))+8;
00264 } else {
00265 fg=VC_GET_BASECOLOR(VCP_FOREGROUND(vc));
00266 }
00267 if (ch) ((CHAR_INFO *)buf)[dest].Char.AsciiChar = ch;
00268 ((CHAR_INFO *)buf)[dest].Attributes = (unsigned char)((bg<<4)|fg);
00269 }