3 * - By John Hodge (thePowersGang)
6 * - Abstract display manipulation methods
8 #include "include/display.h"
9 #include <acess/sys.h> // _SysDebug
10 #include <stdlib.h> // exit
14 #include <axwin3/axwin.h>
15 #include <axwin3/richtext.h>
17 #define UNIMPLIMENTED() do{_SysDebug("UNIMPLIMENTED %s", __func__); exit(-1);}while(0)
20 extern tHWND gMainWindow;
25 int giDisplayTotalLines;
28 int giCurrentLinePos; // byte offset, not column
30 int giFirstDispLine; // First displayed line
31 int giFirstLine; // Ring buffer start
32 char **gasDisplayLines;
33 int *gaiDisplayLineSizes;
34 char *gabDisplayLinesDirty;
37 void Display_Init(int Cols, int Lines, int ExtraScrollbackLines)
40 giDisplayLines = Lines;
41 giDisplayTotalLines = Lines + ExtraScrollbackLines;
42 gasDisplayLines = calloc( sizeof(char*), (Lines + ExtraScrollbackLines) );
43 gaiDisplayLineSizes = calloc( sizeof(int), (Lines + ExtraScrollbackLines) );
44 gabDisplayLinesDirty = calloc( sizeof(char), (Lines + ExtraScrollbackLines) );
46 AxWin3_RichText_SetLineCount(gMainWindow, Lines+ExtraScrollbackLines);
47 AxWin3_RichText_SetCursorType(gMainWindow, 1); // TODO: enum
50 void Display_int_PushString(int Length, const char *Text)
52 _SysDebug("Line %i += %i '%*C'", giCurrentLine, Length, Length, Text);
53 if( !gasDisplayLines[giCurrentLine] || giCurrentLinePos + Length >= gaiDisplayLineSizes[giCurrentLine] )
55 int reqsize = giCurrentLinePos + Length;
56 gaiDisplayLineSizes[giCurrentLine] = (reqsize + 32-1) & ~(32-1);
57 void *tmp = realloc(gasDisplayLines[giCurrentLine], gaiDisplayLineSizes[giCurrentLine]);
58 if( !tmp ) perror("Display_AddText - realloc");
59 gasDisplayLines[giCurrentLine] = tmp;
62 memcpy(gasDisplayLines[giCurrentLine]+giCurrentLinePos, Text, Length);
63 gabDisplayLinesDirty[giCurrentLine] = 1;
64 gasDisplayLines[giCurrentLine][giCurrentLinePos+Length] = 0;
65 giCurrentLinePos += Length;
69 void Display_AddText(int Length, const char *UTF8Text)
71 _SysDebug("%i '%.*s'", Length, Length, UTF8Text);
72 // Copy as many characters (not bytes, have to trim off the last char) as we can to the current line
73 // - then roll over to the next line
76 int space = giDisplayCols - giCurrentCol;
78 while( space && bytes < Length )
81 bytes += ReadUTF8(UTF8Text+bytes, &cp);
82 if( Unicode_IsPrinting(cp) ) {
88 Display_int_PushString(bytes, UTF8Text);
91 _SysDebug("Length(%i) -= bytes(%i)", Length, bytes);
103 void Display_Newline(int bCarriageReturn)
109 if( giCurrentLine == giDisplayLines )
111 if( giCurrentLine == giFirstLine )
114 if(giFirstLine == giDisplayLines)
118 if( bCarriageReturn ) {
119 giCurrentLinePos = 0;
123 giCurrentLinePos = 0;
124 int i = giCurrentCol;
125 if( !gasDisplayLines[giCurrentLine] )
129 Display_AddText(1, " ");
136 giCurrentLinePos += ReadUTF8(gasDisplayLines[giCurrentLine]+giCurrentLinePos, &cp);
137 if( !Unicode_IsPrinting(cp) )
144 void Display_SetCursor(int Row, int Col)
149 void Display_MoveCursor(int RelRow, int RelCol)
153 for( ; RelRow < 0; RelRow ++ )
156 int delta = ReadUTF8Rev(gasDisplayLines[giCurrentLine], giCurrentLinePos, &cp);
157 if( !Unicode_IsPrinting(cp) )
161 giCurrentLinePos -= delta;
170 void Display_ClearLine(int Dir) // 0: All, 1: Forward, -1: Reverse
174 // Completely clear line
175 if( gasDisplayLines[giCurrentLine] )
176 free(gasDisplayLines[giCurrentLine]);
177 gasDisplayLines[giCurrentLine] = NULL;
178 gabDisplayLinesDirty[giCurrentLine] = 1;
182 // Forward clear (truncate)
186 // Reverse clear (replace with spaces)
194 void Display_ClearLines(int Dir) // 0: All, 1: Forward, -1: Reverse
198 // Push giDisplayLines worth of empty lines
199 // Move cursor back up by giDisplayLines
203 // Push (giDisplayLines - (giCurrentLine-giFirstDispLine)) and reverse
207 // Reverse clear (replace with spaces)
215 void Display_SetForeground(uint32_t RGB)
218 sprintf(buf, "\1%06x", RGB&0xFFFFFF);
219 Display_int_PushString(7, buf);
222 void Display_SetBackground(uint32_t RGB)
225 sprintf(buf, "\2%06x", RGB&0xFFFFFF);
226 Display_int_PushString(7, buf);
229 void Display_Flush(void)
232 for( i = 0; i < giDisplayCols; i ++ )
234 int line = (giFirstLine + i) % giDisplayTotalLines;
235 if( !gabDisplayLinesDirty[line] )
237 _SysDebug("Line %i+%i '%s'", giFirstLine, i, gasDisplayLines[line]);
238 AxWin3_RichText_SendLine(gMainWindow, giFirstLine + i, gasDisplayLines[line] );
239 gabDisplayLinesDirty[line] = 0;
243 AxWin3_RichText_SetCursorPos(gMainWindow, giCurrentLine, giCurrentCol);
246 void Display_ShowAltBuffer(int AltBufEnabled)