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 #include <conio.h>
00029 #include <dpmi.h>
00030 #include <go32.h>
00031 #include <pc.h>
00032
00033 void put_vc(unsigned short *dest, char ch, int vc)
00034 {
00035 int fg, bg;
00036 if (VC_GET_BASECOLOR(VCP_BACKGROUND(vc))==VC_TRANSPARENT) {
00037 bg=(((unsigned char*)dest)[1])>>4;
00038 } else if (VC_GET_LIGHT(VCP_BACKGROUND(vc))) {
00039 bg=VC_GET_BASECOLOR(VCP_BACKGROUND(vc))+8;
00040 } else {
00041 bg=VC_GET_BASECOLOR(VCP_BACKGROUND(vc));
00042 }
00043 if (VC_GET_BASECOLOR(VCP_FOREGROUND(vc))==VC_TRANSPARENT) {
00044 fg=(((unsigned char*)dest)[1])&0xf;
00045 } else if (VC_GET_LIGHT(VCP_FOREGROUND(vc))) {
00046 fg=VC_GET_BASECOLOR(VCP_FOREGROUND(vc))+8;
00047 } else {
00048 fg=VC_GET_BASECOLOR(VCP_FOREGROUND(vc));
00049 }
00050 *dest=( ((bg<<4)|fg) <<8)|((unsigned char)ch);
00051 }
00052
00053
00054
00055
00056
00057 screendrawbuf::screendrawbuf(char *title)
00058 {
00059 bounds b;
00060 buf=0;
00061 cursorx=0;
00062 cursory=0;
00063 cursorhidden = false;
00064 cursoroverwrite = false;
00065 hidecursor();
00066
00067 b.x=0;
00068 b.y=0;
00069 b.w=ScreenCols();
00070 b.h=ScreenRows();
00071 b_setbounds(&b);
00072
00073 screensel=__dpmi_allocate_ldt_descriptors(1);
00074 __dpmi_set_descriptor_access_rights(screensel, 0xc0f3);
00075 __dpmi_set_segment_base_address(screensel, 0xb8000);
00076 __dpmi_set_segment_limit(screensel, 0x7fff);
00077
00078 show();
00079 }
00080
00081 screendrawbuf::~screendrawbuf()
00082 {
00083
00084 b_printchar(size.w-1, size.h-1, VCP(VC_WHITE, VC_BLACK), ' ');
00085
00086 setcursormode(false);
00087 setcursor(0, size.h-1);
00088 show();
00089 if (buf) {
00090 delete buf;
00091 }
00092 }
00093
00094 void screendrawbuf::drawbuffer(drawbuf *b, int x, int y, bounds *clipping)
00095 {
00096 drawbufch *ch=b->buf;
00097 for (int iy=0; iy<b->size.h; iy++) {
00098 unsigned short *k=buf+x+(iy+y)*size.w;
00099 if (y+iy>=clipping->y+clipping->h) break;
00100 if (y+iy>=clipping->y)
00101 for (int ix=0; ix<b->size.w; ix++) {
00102 if ((x+ix<clipping->x+clipping->w) && (x+ix>=clipping->x))
00103 put_vc(k, ch->ch, ch->c);
00104 k++;
00105 ch++;
00106 }
00107 }
00108 }
00109
00110 void screendrawbuf::b_fill(int x, int y, int w, int h, int c, int ch)
00111 {
00112 for (int i=0; i<h; i++) {
00113 unsigned short *b=buf+x+(y+i)*size.w;
00114 if (y+i>=size.h) break;
00115 if (y+i>=0)
00116 for (int j=0; j<w; j++) {
00117 if (x+j>=0) put_vc(b, ch, c);
00118 if (x+j>=size.w-1) break;
00119 b++;
00120 }
00121 }
00122 }
00123
00124 void screendrawbuf::b_printchar(int x, int y, int c, int ch)
00125 {
00126 unsigned short*b=buf+x+y*size.w;
00127 put_vc(b, ch, c);
00128 }
00129
00130 int screendrawbuf::b_lprint(int x, int y, int c, int l, char *text)
00131 {
00132 int n=0;
00133 unsigned short *b=buf+x+y*size.w;
00134 while ((*text) && (n<l)) {
00135 put_vc(b, (unsigned char)*text, c);
00136 b++;
00137 text++;
00138 n++;
00139 }
00140 return n;
00141 }
00142
00143 int screendrawbuf::b_lprintw(int x, int y, int c, int l, int *text)
00144 {
00145 int n=0;
00146 unsigned short *b=buf+x+y*size.w;
00147 while ((*text) && (n<l)) {
00148 put_vc(b, (unsigned char)*text, c);
00149 b++;
00150 text++;
00151 n++;
00152 }
00153 return n;
00154 }
00155
00156 void screendrawbuf::b_resize(int rw, int rh)
00157 {
00158
00159 }
00160
00161 void screendrawbuf::b_rmove(int rx, int ry)
00162 {
00163
00164 }
00165
00166 void screendrawbuf::b_setbounds(bounds *b)
00167 {
00168 genericdrawbuf::b_setbounds(b);
00169 if (buf) delete buf;
00170 buf=(unsigned short *)malloc(sizeof *buf * size.w * size.h);
00171 b_fill(size.x, size.y, size.w, size.h, VCP(VC_WHITE, VC_BLACK), ' ');
00172 }
00173
00174 void screendrawbuf::show()
00175 {
00176 gotoxy(cursorx+1, cursory+1);
00177
00178 movedata(_go32_my_ds(), (int)buf, screensel, 0, size.w*size.h*2);
00179 }
00180
00181 void screendrawbuf::getcursor(int *x, int *y)
00182 {
00183 *x=cursorx;
00184 *y=cursory;
00185 }
00186
00187 void screendrawbuf::hidecursor()
00188 {
00189 if (!cursorhidden) {
00190 __dpmi_regs r;
00191 r.h.ah = 1;
00192 r.h.ch = 31;
00193 r.h.cl = 30;
00194 __dpmi_int(0x10, &r);
00195
00196 cursorhidden = true;
00197 }
00198 }
00199
00200 void screendrawbuf::setcursor(int x, int y)
00201 {
00202 showcursor();
00203 cursorx=x;
00204 cursory=y;
00205 }
00206
00207 void screendrawbuf::setcursormode(bool overwrite)
00208 {
00209 if (cursoroverwrite != overwrite) {
00210 cursoroverwrite = overwrite;
00211 if (!cursorhidden) {
00212 hidecursor();
00213 showcursor();
00214 }
00215 }
00216 }
00217
00218 void screendrawbuf::showcursor()
00219 {
00220 if (cursorhidden) {
00221 __dpmi_regs r;
00222 r.h.ah = 1;
00223 if (cursoroverwrite) {
00224 r.h.ch = 0;
00225 r.h.cl = 31;
00226 } else {
00227 r.h.ch = 30;
00228 r.h.cl = 31;
00229 }
00230 __dpmi_int(0x10, &r);
00231
00232 cursorhidden = false;
00233 }
00234 }
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249