1 namespace gfx::drivers;
7 #if (defined(__unix__) || defined(__APPLE__)) && !defined(__DOS__)
9 #define bool CursesBool
17 static int CC(int color)
20 int foreground = (color & 0x0700) >> 8;
21 int background = (color & 0x7000) >> 9;
22 int character = color & 0xFF;
23 int pair = background|foreground;
24 if(pair == 0) result |= A_REVERSE;
25 result |= COLOR_PAIR(pair);
26 if(character == 127 || character == 132 || character == 133 || character == 136 ||
27 character == 141 || character == 142 || character == 143 || character == 155 ||
30 else if(character < 32)
33 result |= A_ALTCHARSET;
37 else if(color & 0x0800)
45 class CursesDisplay : LFBDisplay
50 class NCursesDisplayDriver : DisplayDriver
52 class_property(name) = "NCurses";
54 bool CreateDisplaySystem(DisplaySystem displaySystem)
56 displaySystem.flags.text = true;
60 void DestroyDisplaySystem(DisplaySystem displaySystem)
65 void DestroyDisplay(Display display)
67 CursesDisplay cursesDisplay = display.driverData;
68 delete cursesDisplay.bitmap.picture;
69 ((subclass(DisplayDriver))class(LFBDisplayDriver)).DestroyDisplay(display);
71 display.driverData = null;
74 void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
79 bool CreateDisplay(Display display)
82 CursesDisplay cursesDisplay = display.driverData = CursesDisplay { };
86 if(((subclass(DisplayDriver))class(LFBDisplayDriver)).CreateDisplay(display))
88 cursesDisplay.bitmap.pixelFormat = pixelFormatText;
95 bool DisplaySize(Display display, int width, int height)
98 CursesDisplay cursesDisplay = display.driverData;
100 delete cursesDisplay.bitmap.picture;
102 cursesDisplay.bitmap.picture = new0 byte[2 * width / textCellW * height / textCellW];
103 if(cursesDisplay.bitmap.picture)
105 cursesDisplay.bitmap.stride = width / textCellW;
106 cursesDisplay.bitmap.pixelFormat = pixelFormatText;
107 cursesDisplay.bitmap.size = width / textCellW * height / textCellH;
108 display.width = width;
109 display.height = height;
111 ((subclass(DisplayDriver))class(LFBDisplayDriver)).DisplaySize(display, width, height);
117 void DisplayPosition(Display display, int x, int y)
122 void RestorePalette(Display display)
127 void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
132 bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps)
137 bool GetSurface(Display display, Surface surface, int x, int y, Box clip)
139 if((surface.driverData = LFBSurface { }))
140 return ((subclass(DisplayDriver))class(LFBDisplayDriver)).GetSurface(display, surface, x, y, clip);
144 bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x, int y, Box clip)
149 void ReleaseSurface(Display display, Surface surface)
151 ((subclass(DisplayDriver))class(LFBDisplayDriver)).ReleaseSurface(display, surface);
154 void Clip(Display display, Surface surface, Box clip)
156 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Clip(display, surface, clip);
159 bool GrabScreen(Display display, Bitmap bitmapAddress, int x, int y, unsigned int w, unsigned int h)
165 void SetForeground(Display display, Surface surface, ColorAlpha color)
167 ((subclass(DisplayDriver))class(LFBDisplayDriver)).SetForeground(display, surface, color);
170 void SetBackground(Display display, Surface surface, ColorAlpha color)
172 ((subclass(DisplayDriver))class(LFBDisplayDriver)).SetBackground(display, surface, color);
175 ColorAlpha GetPixel(Display display, Surface surface,int x,int y)
180 void PutPixel(Display display, Surface surface,int x,int y)
182 LFBSurface lfbSurface = surface.driverData;
183 ((subclass(DisplayDriver))class(LFBDisplayDriver)).PutPixel(display, surface, x, y);
186 if((x<=surface.box.right)&&(y<=surface.box.bottom)&&(x>=surface.box.left)&&(y>=surface.box.top))
189 if(lfbSurface.opaqueText)
191 mvaddch((y+surface.offset.y),x+surface.offset.x,
192 CC(lfbSurface.background|lfbSurface.foreground|lfbSurface.drawingChar));
196 mvaddch((y+surface.offset.y),x+surface.offset.x,
197 CC(lfbSurface.background|lfbSurface.foreground|lfbSurface.drawingChar));
202 void DrawLine(Display display, Surface surface, int x1, int y1, int x2, int y2)
204 LFBSurface lfbSurface = surface.driverData;
205 ((subclass(DisplayDriver))class(LFBDisplayDriver)).DrawLine(display, surface, x1, y1, x2, y2);
212 if(y1>y2) { int tmp = y2; y2 = y1; y1 = tmp; }
214 if((x1>surface.box.right)||(x1<surface.box.left))return;
215 if((y1>surface.box.bottom)||(y2<surface.box.top))return;
216 if(y1<surface.box.top)y1=surface.box.top;
217 if(y2>surface.box.bottom)y2=surface.box.bottom;
220 if(lfbSurface.opaqueText)
222 mvvline(y1+surface.offset.y,x1+surface.offset.x,
223 CC(lfbSurface.background | lfbSurface.foreground | lfbSurface.drawingChar),y2-y1+1);
227 uint16 * lfbPtr = ((uint16 *)lfbSurface.bitmap.picture) +
228 (y1+surface.offset.y)*lfbSurface.bitmap.stride+x1+surface.offset.x;
230 for(y=y1;y<=y2; y++, lfbPtr += lfbSurface.bitmap.stride)
232 mvaddch(y+surface.offset.y,x1+surface.offset.x,
233 CC((*lfbPtr & 0xF000) | lfbSurface.foreground | lfbSurface.drawingChar));
240 if(x1>x2) { int tmp = x2; x2 = x1; x1 = tmp; }
242 if((y1>surface.box.bottom)||(y1<surface.box.top)) return;
243 if((x1>surface.box.right)||(x2<surface.box.left)) return;
244 if(x1<surface.box.left)x1=surface.box.left;
245 if(x2>surface.box.right)x2=surface.box.right;
248 if(lfbSurface.opaqueText)
250 mvhline(y1+surface.offset.y,x1+surface.offset.x,
251 CC(lfbSurface.background | lfbSurface.foreground | lfbSurface.drawingChar),x2-x1+1);
255 uint16 * lfbPtr = ((uint16 *)lfbSurface.bitmap.picture) +
256 (y1+surface.offset.y)*display.width / textCellW+x1+surface.offset.x;
258 for(x=x1;x<=x2; x++, lfbPtr++)
260 mvaddch(y1+surface.offset.y,x+surface.offset.x,
261 CC((*lfbPtr & 0xF000) | lfbSurface.foreground | lfbSurface.drawingChar));
267 void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
272 void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
274 LFBSurface lfbSurface = surface.driverData;
275 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Area(display, surface, x1, y1, x2, y2);
282 if(x1>x2) { int tmp = x2; x2 = x1; x1 = tmp; }
284 if(x1<surface.box.left) x1=surface.box.left;
285 if(x2>surface.box.right) x2=surface.box.right;
286 if(y1<surface.box.top) y1=surface.box.top;
287 if(y2>surface.box.bottom) y2=surface.box.bottom;
294 mvhline(y+surface.offset.y,x1+surface.offset.x,
295 CC(lfbSurface.background | lfbSurface.foreground | lfbSurface.drawingChar),x2-x1+1);
300 void Clear(Display display, Surface surface, ClearType flags)
302 if(flags != depthBuffer)
303 Area(display, surface, 0, 0, surface.width - 1, surface.height - 1);
306 bool ConvertBitmap(DisplaySystem displaySystem, Bitmap src, PixelFormat format, ColorAlpha * palette)
311 bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
316 void Blit(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h)
321 void Stretch(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
326 void Filter(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
331 void BlitDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h)
336 void StretchDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
341 void FilterDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
346 Font LoadFont(DisplaySystem displaySystem, char * faceName, float size, FontFlags flags)
348 return (void *) true;
351 void UnloadFont(DisplaySystem displaySystem, Font font)
356 void TextFont(Display display, Surface surface, Font font)
360 void TextOpacity(Display display, Surface surface, bool opaque)
362 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextOpacity(display, surface, opaque);
365 void WriteText(Display display, Surface surface, int x, int y, char * text, int len)
367 LFBSurface lfbSurface = surface.driverData;
371 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len);
376 if(y > surface.box.bottom || y < surface.box.top)
378 y += surface.offset.y;
379 lfbPtr = ((uint16 *)lfbSurface.bitmap.picture) + y * lfbSurface.bitmap.stride + x + surface.offset.x;
380 for(c=0; (c<len && x < surface.box.left); c++, x++, lfbPtr++);
381 for(; (c<len && x <= surface.box.right); c++, x++, lfbPtr++)
383 if(lfbSurface.opaqueText)
384 mvaddch(y,x+surface.offset.x,CC(lfbSurface.background|lfbSurface.foreground|text[c]));
386 mvaddch(y,x+surface.offset.x,CC( (*lfbPtr & 0xF000)|lfbSurface.foreground|text[c] ));
390 void FontExtent(DisplaySystem displaySystem, Font font, char * text, int len, int * width, int * height)
392 ((subclass(DisplayDriver))class(LFBDisplayDriver)).FontExtent(displaySystem, font, text, len, width, height);
395 void TextExtent(Display display, Surface surface, char * text, int len, int * width, int * height)
397 FontExtent(display.displaySystem, null, text, len, width, height);
400 void DrawingChar(Display display, Surface surface, char character)
402 ((subclass(DisplayDriver))class(LFBDisplayDriver)).DrawingChar(display, surface, character);
406 void LineStipple(Display display, Surface surface, uint stipple)
411 bool Lock(Display display)
416 void Unlock(Display display)
420 void StartUpdate(Display display)
425 void Scroll(Display display, Box scroll, int x, int y, Extent dirty)
430 void Update(Display display, Box updateBox)
432 CursesDisplay cursesDisplay = display.driverData;
434 leaveok(stdscr, (_Bool)true);
436 if(updateBox == null)
438 cursesDisplay.updateBox.left = display.width;
439 cursesDisplay.updateBox.top = display.height;
440 cursesDisplay.updateBox.right = 0;
441 cursesDisplay.updateBox.bottom = 0;
443 // Log("Here in displayscreen\n");
446 void EndUpdate(Display display)