1 namespace gfx::drivers;
7 #if (defined(__unix__) || defined(__APPLE__)) && !defined(__DOS__)
13 static int CC(int color)
16 int foreground = (color & 0x0700) >> 8;
17 int background = (color & 0x7000) >> 9;
18 int character = color & 0xFF;
19 int pair = background|foreground;
20 if(pair == 0) result |= A_REVERSE;
21 result |= COLOR_PAIR(pair);
22 if(character == 127 || character == 132 || character == 133 || character == 136 ||
23 character == 141 || character == 142 || character == 143 || character == 155 ||
26 else if(character < 32)
29 result |= A_ALTCHARSET;
33 else if(color & 0x0800)
41 class CursesDisplay : LFBDisplay
46 class NCursesDisplayDriver : DisplayDriver
48 class_property(name) = "NCurses";
50 bool CreateDisplaySystem(DisplaySystem displaySystem)
52 displaySystem.flags.text = true;
56 void DestroyDisplaySystem(DisplaySystem displaySystem)
61 void DestroyDisplay(Display display)
63 CursesDisplay cursesDisplay = display.driverData;
64 delete cursesDisplay.bitmap.picture;
65 ((subclass(DisplayDriver))class(LFBDisplayDriver)).DestroyDisplay(display);
67 display.driverData = null;
70 void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
75 bool CreateDisplay(Display display)
78 CursesDisplay cursesDisplay = display.driverData = CursesDisplay { };
82 if(((subclass(DisplayDriver))class(LFBDisplayDriver)).CreateDisplay(display))
84 cursesDisplay.bitmap.pixelFormat = pixelFormatText;
91 bool DisplaySize(Display display, int width, int height)
94 CursesDisplay cursesDisplay = display.driverData;
96 delete cursesDisplay.bitmap.picture;
98 cursesDisplay.bitmap.picture = new0 byte[2 * width / textCellW * height / textCellW];
99 if(cursesDisplay.bitmap.picture)
101 cursesDisplay.bitmap.stride = width / textCellW;
102 cursesDisplay.bitmap.pixelFormat = pixelFormatText;
103 cursesDisplay.bitmap.size = width / textCellW * height / textCellH;
104 display.width = width;
105 display.height = height;
107 ((subclass(DisplayDriver))class(LFBDisplayDriver)).DisplaySize(display, width, height);
113 void DisplayPosition(Display display, int x, int y)
118 void RestorePalette(Display display)
123 void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
128 bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps)
133 bool GetSurface(Display display, Surface surface, int x, int y, Box clip)
135 if((surface.driverData = LFBSurface { }))
136 return ((subclass(DisplayDriver))class(LFBDisplayDriver)).GetSurface(display, surface, x, y, clip);
140 bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x, int y, Box clip)
145 void ReleaseSurface(Display display, Surface surface)
147 ((subclass(DisplayDriver))class(LFBDisplayDriver)).ReleaseSurface(display, surface);
150 void Clip(Display display, Surface surface, Box clip)
152 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Clip(display, surface, clip);
155 bool GrabScreen(Display display, Bitmap bitmapAddress, int x, int y, unsigned int w, unsigned int h)
161 void SetForeground(Display display, Surface surface, ColorAlpha color)
163 ((subclass(DisplayDriver))class(LFBDisplayDriver)).SetForeground(display, surface, color);
166 void SetBackground(Display display, Surface surface, ColorAlpha color)
168 ((subclass(DisplayDriver))class(LFBDisplayDriver)).SetBackground(display, surface, color);
171 ColorAlpha GetPixel(Display display, Surface surface,int x,int y)
176 void PutPixel(Display display, Surface surface,int x,int y)
178 LFBSurface lfbSurface = surface.driverData;
179 ((subclass(DisplayDriver))class(LFBDisplayDriver)).PutPixel(display, surface, x, y);
182 if((x<=surface.box.right)&&(y<=surface.box.bottom)&&(x>=surface.box.left)&&(y>=surface.box.top))
185 if(lfbSurface.opaqueText)
187 mvaddch((y+surface.offset.y),x+surface.offset.x,
188 CC(lfbSurface.background|lfbSurface.foreground|lfbSurface.drawingChar));
192 mvaddch((y+surface.offset.y),x+surface.offset.x,
193 CC(lfbSurface.background|lfbSurface.foreground|lfbSurface.drawingChar));
198 void DrawLine(Display display, Surface surface, int x1, int y1, int x2, int y2)
200 LFBSurface lfbSurface = surface.driverData;
201 ((subclass(DisplayDriver))class(LFBDisplayDriver)).DrawLine(display, surface, x1, y1, x2, y2);
208 if(y1>y2) { int tmp = y2; y2 = y1; y1 = tmp; }
210 if((x1>surface.box.right)||(x1<surface.box.left))return;
211 if((y1>surface.box.bottom)||(y2<surface.box.top))return;
212 if(y1<surface.box.top)y1=surface.box.top;
213 if(y2>surface.box.bottom)y2=surface.box.bottom;
216 if(lfbSurface.opaqueText)
218 mvvline(y1+surface.offset.y,x1+surface.offset.x,
219 CC(lfbSurface.background | lfbSurface.foreground | lfbSurface.drawingChar),y2-y1+1);
223 uint16 * lfbPtr = ((uint16 *)lfbSurface.bitmap.picture) +
224 (y1+surface.offset.y)*lfbSurface.bitmap.stride+x1+surface.offset.x;
226 for(y=y1;y<=y2; y++, lfbPtr += lfbSurface.bitmap.stride)
228 mvaddch(y+surface.offset.y,x1+surface.offset.x,
229 CC((*lfbPtr & 0xF000) | lfbSurface.foreground | lfbSurface.drawingChar));
236 if(x1>x2) { int tmp = x2; x2 = x1; x1 = tmp; }
238 if((y1>surface.box.bottom)||(y1<surface.box.top)) return;
239 if((x1>surface.box.right)||(x2<surface.box.left)) return;
240 if(x1<surface.box.left)x1=surface.box.left;
241 if(x2>surface.box.right)x2=surface.box.right;
244 if(lfbSurface.opaqueText)
246 mvhline(y1+surface.offset.y,x1+surface.offset.x,
247 CC(lfbSurface.background | lfbSurface.foreground | lfbSurface.drawingChar),x2-x1+1);
251 uint16 * lfbPtr = ((uint16 *)lfbSurface.bitmap.picture) +
252 (y1+surface.offset.y)*display.width / textCellW+x1+surface.offset.x;
254 for(x=x1;x<=x2; x++, lfbPtr++)
256 mvaddch(y1+surface.offset.y,x+surface.offset.x,
257 CC((*lfbPtr & 0xF000) | lfbSurface.foreground | lfbSurface.drawingChar));
263 void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
268 void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
270 LFBSurface lfbSurface = surface.driverData;
271 ((subclass(DisplayDriver))class(LFBDisplayDriver)).Area(display, surface, x1, y1, x2, y2);
278 if(x1>x2) { int tmp = x2; x2 = x1; x1 = tmp; }
280 if(x1<surface.box.left) x1=surface.box.left;
281 if(x2>surface.box.right) x2=surface.box.right;
282 if(y1<surface.box.top) y1=surface.box.top;
283 if(y2>surface.box.bottom) y2=surface.box.bottom;
290 mvhline(y+surface.offset.y,x1+surface.offset.x,
291 CC(lfbSurface.background | lfbSurface.foreground | lfbSurface.drawingChar),x2-x1+1);
296 void Clear(Display display, Surface surface, ClearType flags)
298 if(flags != depthBuffer)
299 Area(display, surface, 0, 0, surface.width - 1, surface.height - 1);
302 bool ConvertBitmap(DisplaySystem displaySystem, Bitmap src, PixelFormat format, ColorAlpha * palette)
307 bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
312 void Blit(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h)
317 void Stretch(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
322 void Filter(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
327 void BlitDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h)
332 void StretchDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
337 void FilterDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
342 Font LoadFont(DisplaySystem displaySystem, char * faceName, float size, FontFlags flags)
344 return (void *) true;
347 void UnloadFont(DisplaySystem displaySystem, Font font)
352 void TextFont(Display display, Surface surface, Font font)
356 void TextOpacity(Display display, Surface surface, bool opaque)
358 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextOpacity(display, surface, opaque);
361 void WriteText(Display display, Surface surface, int x, int y, char * text, int len)
363 LFBSurface lfbSurface = surface.driverData;
367 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len);
372 if(y > surface.box.bottom || y < surface.box.top)
374 y += surface.offset.y;
375 lfbPtr = ((uint16 *)lfbSurface.bitmap.picture) + y * lfbSurface.bitmap.stride + x + surface.offset.x;
376 for(c=0; (c<len && x < surface.box.left); c++, x++, lfbPtr++);
377 for(; (c<len && x <= surface.box.right); c++, x++, lfbPtr++)
379 if(lfbSurface.opaqueText)
380 mvaddch(y,x+surface.offset.x,CC(lfbSurface.background|lfbSurface.foreground|text[c]));
382 mvaddch(y,x+surface.offset.x,CC( (*lfbPtr & 0xF000)|lfbSurface.foreground|text[c] ));
386 void FontExtent(DisplaySystem displaySystem, Font font, char * text, int len, int * width, int * height)
388 ((subclass(DisplayDriver))class(LFBDisplayDriver)).FontExtent(displaySystem, font, text, len, width, height);
391 void TextExtent(Display display, Surface surface, char * text, int len, int * width, int * height)
393 FontExtent(display.displaySystem, null, text, len, width, height);
396 void DrawingChar(Display display, Surface surface, char character)
398 ((subclass(DisplayDriver))class(LFBDisplayDriver)).DrawingChar(display, surface, character);
402 void LineStipple(Display display, Surface surface, uint stipple)
407 bool Lock(Display display)
412 void Unlock(Display display)
416 void StartUpdate(Display display)
421 void Scroll(Display display, Box scroll, int x, int y, Extent dirty)
426 void Update(Display display, Box updateBox)
428 CursesDisplay cursesDisplay = display.driverData;
430 leaveok(stdscr, true);
432 if(updateBox == null)
434 cursesDisplay.updateBox.left = display.width;
435 cursesDisplay.updateBox.top = display.height;
436 cursesDisplay.updateBox.right = 0;
437 cursesDisplay.updateBox.bottom = 0;
439 // Log("Here in displayscreen\n");
442 void EndUpdate(Display display)