#include "ConsoleBuffer.h"
#include <new>
#include <assert.h>
#include <sdi/panic.h>
#include <string.h>
static const unsigned int VIDEO_MEMORY_SIZE = 4000;
static const unsigned int LINE_LENGTH = 160;
ConsoleBuffer::ConsoleBuffer(unsigned int size, char* vmStart, int* focus) {
if(size < VIDEO_MEMORY_SIZE) {
panic("ConsoleBuffer to small! Must be at least 4000 bytes = screen size");
}
hasFocus = focus;
buffer = new char[size];
bufferSize = size;
memset(buffer, 0, size);
videoMemStart = vmStart;
colorCode = 0x07;
cursorColor = 0xf8;
screenStart = 0;
cursorPosition = 0;
savedCursorPos = 0;
};
ConsoleBuffer::~ConsoleBuffer() {};
void ConsoleBuffer::CursorUp(int n) {};
void ConsoleBuffer::CursorDown(int n) {};
void ConsoleBuffer::CursorLeft(int n) {
assert(cursorPosition % 2 == 0);
unsigned int newPosition = cursorPosition - n * 2;
if(newPosition < screenStart && newPosition > 0) {
screenStart -= LINE_LENGTH;
}
SetColor(colorCode);
cursorPosition = newPosition;
SetColor(cursorColor);
};
void ConsoleBuffer::CursorRight(int n) {
assert(cursorPosition % 2 == 0);
SetColor(colorCode);
if(cursorPosition + (n*2) >= screenStart + VIDEO_MEMORY_SIZE) {
if(cursorPosition + (n*2) >= bufferSize) {
int lines = 1;
memmove(buffer, buffer + lines * 160, bufferSize - lines * 160);
memset(buffer + bufferSize - lines * 160, 0, lines * 160);
cursorPosition -= LINE_LENGTH;
}
screenStart += LINE_LENGTH;
}
cursorPosition += (n*2);
SetColor(cursorColor);
};
void ConsoleBuffer::SetCursor(int z, int s) {
};
void ConsoleBuffer::SaveCursor() {
savedCursorPos = cursorPosition;
};
void ConsoleBuffer::LoadCursor() {
SetColor(colorCode);
cursorPosition = savedCursorPos;
SetColor(cursorColor);
update();
};
TODO:
void ConsoleBuffer::ClearScreen() {
memset(buffer + screenStart, 0, VIDEO_MEMORY_SIZE);
cursorPosition = screenStart;
SetColor(cursorColor);
update();
};
void ConsoleBuffer::ClearLine(uint8_t n) {
if(0 == n) {
memset(buffer + cursorPosition, 0, LINE_LENGTH - (cursorPosition % LINE_LENGTH));
} else if (1 == n) {
memset(buffer + cursorPosition - (cursorPosition % LINE_LENGTH), 0, (cursorPosition % LINE_LENGTH) + 1);
} else if(2 == n) {
memset(buffer + cursorPosition - (cursorPosition % LINE_LENGTH), 0, LINE_LENGTH);
}
SetColor(cursorColor);
update();
};
void ConsoleBuffer::SetColor(uint8_t c) {
assert(cursorPosition % 2 == 0);
buffer[cursorPosition + 1] = c;
};
void ConsoleBuffer::DeleteLast() {
assert(cursorPosition % 2 == 0);
if(cursorPosition > 0) {
if(0 == cursorPosition % LINE_LENGTH) {
CursorLeft(1);
while((cursorPosition > 0) && (0 == buffer[cursorPosition])) {
if(0 == cursorPosition % LINE_LENGTH) {
update();
return;
}
CursorLeft(1);
}
} else {
CursorLeft(1);
}
buffer[cursorPosition] = 0;
update();
}
};
void ConsoleBuffer::Delete() {
assert(cursorPosition % 2 == 0);
buffer[cursorPosition] = 0;
update();
};
void ConsoleBuffer::NewLine() {
assert(cursorPosition % 2 == 0);
SetColor(colorCode);
buffer[cursorPosition] = ' ';
unsigned int newPosition = cursorPosition - (cursorPosition % LINE_LENGTH) + LINE_LENGTH;
if(newPosition >= screenStart + VIDEO_MEMORY_SIZE) {
if(newPosition >= bufferSize) {
int lines = 1;
memmove(buffer, buffer + lines * 160, bufferSize - lines * 160);
memset(buffer + bufferSize - lines * 160, 0, lines * 160);
newPosition -= lines * LINE_LENGTH;
screenStart -= lines * LINE_LENGTH;
}
screenStart += LINE_LENGTH;
}
cursorPosition = newPosition;
SetColor(cursorColor);
update();
};
void ConsoleBuffer::appendChar(char c) {
if(cursorPosition >= screenStart + VIDEO_MEMORY_SIZE) {
screenStart = cursorPosition - (cursorPosition % LINE_LENGTH) - 25 * LINE_LENGTH;
}
buffer[cursorPosition] = c;
CursorRight(1);
};
void ConsoleBuffer::appendString(buffer_t *string) {
for(unsigned int i=0; i<string->_length; i++) {
appendChar(string->_buffer[i]);
}
};
void ConsoleBuffer::update() {
if(*hasFocus != 0) {
memcpy(videoMemStart, buffer + screenStart, VIDEO_MEMORY_SIZE);
}
};
void ConsoleBuffer::PageDown() {
if(screenStart + VIDEO_MEMORY_SIZE + LINE_LENGTH <= bufferSize) {
screenStart += 160;
update();
}
};
void ConsoleBuffer::PageUp() {
if(screenStart >= 160) {
screenStart -= 160;
update();
}
};
void ConsoleBuffer::SetGraphic(int n) {
switch (n) {
case 0:
colorCode = 0x07;
break;
case 1:
colorCode |= 0x8;
break;
case 5:
colorCode |= 0x80;
break;
case 30:
colorCode &= 0xf8;
break;
case 31:
colorCode &= 0xf8;
colorCode |= 0x04;
break;
case 32:
colorCode &= 0xf8;
colorCode |= 0x02;
break;
case 33:
colorCode &= 0xf8;
colorCode |= 0x03;
break;
case 34:
colorCode &= 0xf8;
colorCode |= 0x01;
break;
case 35:
colorCode &= 0xf8;
colorCode |= 0x05;
break;
case 36:
colorCode &= 0xf8;
colorCode |= 0x06;
break;
case 37:
colorCode &= 0xf8;
colorCode |= 0x07;
break;
case 40:
colorCode &= 0x8f;
break;
case 41:
colorCode &= 0x8f;
colorCode |= 0x40;
break;
case 42:
colorCode &= 0x8f;
colorCode |= 0x20;
break;
case 43:
colorCode &= 0x8f;
colorCode |= 0x30;
break;
case 44:
colorCode &= 0x8f;
colorCode |= 0x10;
break;
case 45:
colorCode &= 0x8f;
colorCode |= 0x50;
break;
case 46:
colorCode &= 0x8f;
colorCode |= 0x60;
break;
case 47:
colorCode &= 0x8f;
colorCode |= 0x70;
break;
}
};