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);
102 void Display_Newline(int bCarriageReturn)
108 if( giCurrentLine == giDisplayLines )
110 if( giCurrentLine == giFirstLine )
113 if(giFirstLine == giDisplayLines)
117 if( bCarriageReturn ) {
118 giCurrentLinePos = 0;
122 giCurrentLinePos = 0;
123 int i = giCurrentCol;
124 if( !gasDisplayLines[giCurrentLine] )
128 Display_AddText(1, " ");
135 giCurrentLinePos += ReadUTF8(gasDisplayLines[giCurrentLine]+giCurrentLinePos, &cp);
136 if( !Unicode_IsPrinting(cp) )
143 void Display_SetCursor(int Row, int Col)
148 void Display_MoveCursor(int RelRow, int RelCol)
152 for( ; RelRow < 0; RelRow ++ )
155 int delta = ReadUTF8Rev(gasDisplayLines[giCurrentLine], giCurrentLinePos, &cp);
156 if( !Unicode_IsPrinting(cp) )
160 giCurrentLinePos -= delta;
169 void Display_ClearLine(int Dir) // 0: All, 1: Forward, -1: Reverse
173 // Completely clear line
174 if( gasDisplayLines[giCurrentLine] )
175 free(gasDisplayLines[giCurrentLine]);
176 gasDisplayLines[giCurrentLine] = NULL;
177 gabDisplayLinesDirty[giCurrentLine] = 1;
181 // Forward clear (truncate)
185 // Reverse clear (replace with spaces)
193 void Display_ClearLines(int Dir) // 0: All, 1: Forward, -1: Reverse
197 // Push giDisplayLines worth of empty lines
198 // Move cursor back up by giDisplayLines
202 // Push (giDisplayLines - (giCurrentLine-giFirstDispLine)) and reverse
206 // Reverse clear (replace with spaces)
214 void Display_SetForeground(uint32_t RGB)
217 sprintf(buf, "\1%06x", RGB&0xFFFFFF);
218 Display_int_PushString(7, buf);
221 void Display_SetBackground(uint32_t RGB)
224 sprintf(buf, "\2%06x", RGB&0xFFFFFF);
225 Display_int_PushString(7, buf);
228 void Display_Flush(void)
231 for( i = 0; i < giDisplayCols; i ++ )
233 int line = (giFirstLine + i) % giDisplayTotalLines;
234 if( !gabDisplayLinesDirty[line] )
236 _SysDebug("Line %i+%i '%s'", giFirstLine, i, gasDisplayLines[line]);
237 AxWin3_RichText_SendLine(gMainWindow, giFirstLine + i, gasDisplayLines[line] );
238 gabDisplayLinesDirty[line] = 0;
240 AxWin3_RichText_SetCursorPos(gMainWindow, giCurrentLine, giCurrentCol);
243 void Display_ShowAltBuffer(int AltBufEnabled)