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) )
86 Display_int_PushString(bytes, UTF8Text);
89 _SysDebug("Length(%i) -= bytes(%i)", Length, bytes);
101 void Display_Newline(int bCarriageReturn)
107 if( giCurrentLine == giDisplayLines )
109 if( giCurrentLine == giFirstLine )
112 if(giFirstLine == giDisplayLines)
116 if( bCarriageReturn ) {
117 giCurrentLinePos = 0;
121 giCurrentLinePos = 0;
122 int i = giCurrentCol;
123 if( !gasDisplayLines[giCurrentLine] )
127 Display_AddText(1, " ");
134 giCurrentLinePos += ReadUTF8(gasDisplayLines[giCurrentLine]+giCurrentLinePos, &cp);
135 if( !Unicode_IsPrinting(cp) )
142 void Display_SetCursor(int Row, int Col)
147 void Display_MoveCursor(int RelRow, int RelCol)
152 void Display_ClearLine(int Dir) // 0: All, 1: Forward, -1: Reverse
156 // Completely clear line
157 if( gasDisplayLines[giCurrentLine] )
158 free(gasDisplayLines[giCurrentLine]);
159 gasDisplayLines[giCurrentLine] = NULL;
160 gabDisplayLinesDirty[giCurrentLine] = 1;
164 // Forward clear (truncate)
168 // Reverse clear (replace with spaces)
176 void Display_ClearLines(int Dir) // 0: All, 1: Forward, -1: Reverse
180 // Push giDisplayLines worth of empty lines
181 // Move cursor back up by giDisplayLines
185 // Push (giDisplayLines - (giCurrentLine-giFirstDispLine)) and reverse
189 // Reverse clear (replace with spaces)
197 void Display_SetForeground(uint32_t RGB)
200 sprintf(buf, "\1%06x", RGB&0xFFFFFF);
201 Display_int_PushString(7, buf);
204 void Display_SetBackground(uint32_t RGB)
207 sprintf(buf, "\2%06x", RGB&0xFFFFFF);
208 Display_int_PushString(7, buf);
211 void Display_Flush(void)
214 for( i = 0; i < giDisplayCols; i ++ )
216 int line = (giFirstLine + i) % giDisplayTotalLines;
217 if( !gabDisplayLinesDirty[line] )
219 _SysDebug("Line %i+%i '%s'", giFirstLine, i, gasDisplayLines[line]);
220 AxWin3_RichText_SendLine(gMainWindow, giFirstLine + i, gasDisplayLines[line] );
221 gabDisplayLinesDirty[line] = 0;
225 AxWin3_RichText_SetCursorPos(gMainWindow, giCurrentLine, giCurrentCol);
228 void Display_ShowAltBuffer(int AltBufEnabled)