Merge branch 'dev' into 'master'
Merge into master See merge request link/projekte/ws19/vkvm-new/library!3
This commit is contained in:
commit
f04ea0f73e
|
@ -9,7 +9,7 @@ filelist="$(find . -not \( -path './*build*' -prune \) -not \( -path './include'
|
||||||
for file in $filelist; do
|
for file in $filelist; do
|
||||||
if echo "$file" | grep -q -E ".*(\.cpp|\.h|\.hpp)$" ; then
|
if echo "$file" | grep -q -E ".*(\.cpp|\.h|\.hpp)$" ; then
|
||||||
#Extra check missing dependencies due to clang-tidy doesn't toggle exit code.
|
#Extra check missing dependencies due to clang-tidy doesn't toggle exit code.
|
||||||
clang_tidy_lib_check="$(clang-tidy -warnings-as-errors='*' --color -header-filter='.*,-cpptoml.hpp' "$file" -- -I. -std=c++14 2>&1)"
|
clang_tidy_lib_check="$(clang-tidy -warnings-as-errors='*' --color "$file" -- -I. -std=c++14 2>&1)"
|
||||||
for tidy_line in $clang_tidy_lib_check; do
|
for tidy_line in $clang_tidy_lib_check; do
|
||||||
echo "$tidy_line" | grep -q -v -E "^Error while processing*"
|
echo "$tidy_line" | grep -q -v -E "^Error while processing*"
|
||||||
if [ $? -eq 1 ]; then
|
if [ $? -eq 1 ]; then
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
Checks: '*,-llvm-header-guard,-fuchsia*,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-pro-bounds-constant-array-index,-bugprone-narrowing-conversions,-cppcoreguidelines-narrowing-conversions,-cppcoreguidelines-pro-type-const-cast,-cppcoreguidelines-pro-type-reinterpret-cast,-hicpp-signed-bitwise,-bugprone-exception-escape,-cppcoreguidelines-pro-type-member-init,-cppcoreguidelines-pro-type-cstyle-cast,-hicpp-member-init,-google-readability-namespace-comments,-llvm-namespace-comment,-cppcoreguidelines-pro-type-vararg,-hicpp-vararg,-modernize-use-trailing-return-type'
|
Checks: '*,-llvm-header-guard,-fuchsia*,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-pro-bounds-constant-array-index,-bugprone-narrowing-conversions,-cppcoreguidelines-narrowing-conversions,-cppcoreguidelines-pro-type-const-cast,-cppcoreguidelines-pro-type-reinterpret-cast,-hicpp-signed-bitwise,-bugprone-exception-escape,-cppcoreguidelines-pro-type-member-init,-cppcoreguidelines-pro-type-cstyle-cast,-hicpp-member-init,-google-readability-namespace-comments,-llvm-namespace-comment,-cppcoreguidelines-pro-type-vararg,-hicpp-vararg,-modernize-use-trailing-return-type'
|
||||||
WarningsAsErrors: 'true'
|
WarningsAsErrors: 'true'
|
||||||
|
HeaderFilterRegex: '.*,-catch.hpp'
|
|
@ -12,8 +12,7 @@ project(library)
|
||||||
set(CMAKE_CXX_STANDARD 14)
|
set(CMAKE_CXX_STANDARD 14)
|
||||||
|
|
||||||
# enable clang_tidy
|
# enable clang_tidy
|
||||||
set(CMAKE_CXX_CLANG_TIDY "clang-tidy;-checks=*")
|
set(CMAKE_CXX_CLANG_TIDY clang-tidy;)
|
||||||
set(CMAKE_CXX_CLANG_TIDY clang-tidy;-header-filter=.;)
|
|
||||||
|
|
||||||
|
|
||||||
file(GLOB_RECURSE SOURCES src/*.cpp)
|
file(GLOB_RECURSE SOURCES src/*.cpp)
|
||||||
|
@ -22,7 +21,8 @@ file(GLOB_RECURSE TESTS test/*.cpp)
|
||||||
include_directories(src)
|
include_directories(src)
|
||||||
include_directories(test)
|
include_directories(test)
|
||||||
|
|
||||||
add_library(library ${SOURCES} ${HEADERS} src/FontType.cpp)
|
add_library(library ${SOURCES} ${HEADERS})
|
||||||
|
|
||||||
|
|
||||||
file(COPY "${CMAKE_SOURCE_DIR}/src/"
|
file(COPY "${CMAKE_SOURCE_DIR}/src/"
|
||||||
DESTINATION "${CMAKE_SOURCE_DIR}/include"
|
DESTINATION "${CMAKE_SOURCE_DIR}/include"
|
||||||
|
|
|
@ -2,9 +2,16 @@
|
||||||
|
|
||||||
namespace vkvm {
|
namespace vkvm {
|
||||||
|
|
||||||
Color::Color(unsigned char red, unsigned char green, unsigned char blue) noexcept
|
Color::Color() noexcept
|
||||||
: red(red), green(green), blue(blue) {
|
: red(0), green(0), blue(0) {}
|
||||||
|
|
||||||
|
Color::Color(unsigned char red, unsigned char green, unsigned char blue) noexcept
|
||||||
|
: red(red), green(green), blue(blue) {}
|
||||||
|
|
||||||
|
Color::Color(unsigned int hex) noexcept {
|
||||||
|
red = (unsigned char) ((hex >> 16 & 0xFF));//NOLINT
|
||||||
|
green = (unsigned char) ((hex >> 8u & 0xFF));//NOLINT
|
||||||
|
blue = (unsigned char) ((hex & 0xFF));//NOLINT
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Color::getRed() -> unsigned char {
|
auto Color::getRed() -> unsigned char {
|
||||||
|
@ -30,4 +37,12 @@ namespace vkvm {
|
||||||
auto Color::setBlue(unsigned char value) -> void {
|
auto Color::setBlue(unsigned char value) -> void {
|
||||||
blue = value;
|
blue = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Color::operator==(const Color &other) const {
|
||||||
|
return this->blue == other.blue && this->green == other.green && this->red == other.red;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Color::operator!=(const Color &other) const {
|
||||||
|
return this->blue != other.blue || this->green != other.green || this->red != other.red;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -16,8 +16,12 @@ namespace vkvm {
|
||||||
unsigned char blue;
|
unsigned char blue;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
Color() noexcept;
|
||||||
|
|
||||||
Color(unsigned char red, unsigned char green, unsigned char blue) noexcept;
|
Color(unsigned char red, unsigned char green, unsigned char blue) noexcept;
|
||||||
|
|
||||||
|
explicit Color(unsigned int hex) noexcept;
|
||||||
|
|
||||||
auto getRed() -> unsigned char;
|
auto getRed() -> unsigned char;
|
||||||
|
|
||||||
auto getGreen() -> unsigned char;
|
auto getGreen() -> unsigned char;
|
||||||
|
@ -30,10 +34,17 @@ namespace vkvm {
|
||||||
|
|
||||||
auto setBlue(unsigned char value) -> void;
|
auto setBlue(unsigned char value) -> void;
|
||||||
|
|
||||||
|
bool operator==(const Color &other) const ;
|
||||||
|
|
||||||
|
bool operator!=(const Color &other) const ;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const static Color black = Color(0, 0, 0);
|
const static Color black = Color(0, 0, 0);
|
||||||
const static Color white = Color(255, 255, 255);
|
const static Color white = Color(255, 255, 255);
|
||||||
|
const static Color green = Color(0, 255, 0);
|
||||||
|
const static Color red = Color(255, 0, 0);
|
||||||
|
const static Color blue = Color(0, 0, 255);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,12 +11,17 @@ namespace vkvm {
|
||||||
enum EventType {
|
enum EventType {
|
||||||
Timer = 1,
|
Timer = 1,
|
||||||
MouseMove = 2,
|
MouseMove = 2,
|
||||||
MouseButton = 3,
|
MouseLeftUp = 3,
|
||||||
KeyDown = 4,
|
MouseLeftDown = 4,
|
||||||
KeyUp = 5,
|
MouseRightUp = 5,
|
||||||
UpdateControlRegisters = 6,
|
MouseRightDown = 6,
|
||||||
Redraw = 7,
|
MouseMiddleDown = 7,
|
||||||
RenderText = 8
|
MouseMiddleUp = 8,
|
||||||
|
KeyDown = 9,
|
||||||
|
KeyUp = 10,
|
||||||
|
UpdateControlRegisters = 11,
|
||||||
|
Redraw = 12,
|
||||||
|
RenderText = 13
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
#include "KeyCode.hpp"
|
|
||||||
|
|
||||||
namespace vkvm {
|
|
||||||
|
|
||||||
KeyCode::KeyCode(int value) noexcept : value(value) {}
|
|
||||||
|
|
||||||
auto KeyCode::getValue() -> int {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -5,18 +5,53 @@
|
||||||
|
|
||||||
namespace vkvm {
|
namespace vkvm {
|
||||||
|
|
||||||
class KeyCode {
|
enum KeyCode {
|
||||||
private:
|
Backspcce = 32,
|
||||||
int value;
|
Tab = 33,
|
||||||
public:
|
Enter = 37,
|
||||||
explicit KeyCode(int value) noexcept;
|
ShiftLeft = 249,
|
||||||
|
ShiftRight = 249,
|
||||||
auto getValue() -> int;
|
Ctrl = 251,
|
||||||
|
Alt = 257,
|
||||||
|
Delete = 279,
|
||||||
|
Space = -65224,
|
||||||
|
Zero = -65208,
|
||||||
|
One = -65207,
|
||||||
|
Two = -65206,
|
||||||
|
Three = -65205,
|
||||||
|
Four = -65204,
|
||||||
|
Five = -65203,
|
||||||
|
Six = -65202,
|
||||||
|
Seven = -65201,
|
||||||
|
Eight = -65200,
|
||||||
|
Nine = -65199,
|
||||||
|
A = -65159,
|
||||||
|
B = -65158,
|
||||||
|
C = -65157,
|
||||||
|
D = -65156,
|
||||||
|
E = -65155,
|
||||||
|
F = -65154,
|
||||||
|
G = -65153,
|
||||||
|
H = -65152,
|
||||||
|
I = -65151,
|
||||||
|
J = -65150,
|
||||||
|
K = -65149,
|
||||||
|
L = -65148,
|
||||||
|
M = -65147,
|
||||||
|
N = -65146,
|
||||||
|
O = -65145,
|
||||||
|
P = -65144,
|
||||||
|
Q = -65143,
|
||||||
|
R = -65142,
|
||||||
|
S = -65141,
|
||||||
|
T = -65140,
|
||||||
|
U = -65139,
|
||||||
|
V = -65138,
|
||||||
|
W = -65137,
|
||||||
|
X = -65136,
|
||||||
|
Y = -65135,
|
||||||
|
Z = -65134,
|
||||||
};
|
};
|
||||||
|
|
||||||
const static KeyCode Backspace = KeyCode(8);
|
|
||||||
const static KeyCode tabulator = KeyCode(9);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#include "SharedMemoryAccess.hpp" /* header is important for the shmID. name could be different. maybe not needed cause: (shmget(memory_access_key, NULL, 0)) */
|
#include "SharedMemoryAccess.hpp" /* header is important for the shmID. name could be different. maybe not needed cause: (shmget(memory_access_key, NULL, 0)) */
|
||||||
#include "internal.hpp"
|
#include "internal.hpp"
|
||||||
|
#include "log.hpp"
|
||||||
|
|
||||||
namespace vkvm {
|
namespace vkvm {
|
||||||
constexpr int PERM = 0666; /* access rights */
|
constexpr int PERM = 0666; /* access rights */
|
||||||
|
@ -60,18 +61,36 @@ namespace vkvm {
|
||||||
unlockSharedMemory();
|
unlockSharedMemory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *getLocalMemory(){
|
||||||
|
static bool givenWarning {false};
|
||||||
|
if(!givenWarning && impl.localMemoryWarn){
|
||||||
|
givenWarning = true;
|
||||||
|
log(LogLevel::WARNING, "no shared memory found, using local memory instead!");
|
||||||
|
}
|
||||||
|
if (localSharedMemory.empty()) {
|
||||||
|
constexpr int kilo = 1024;
|
||||||
|
localSharedMemory.resize(impl.sharedMemorySize * kilo);
|
||||||
|
}
|
||||||
|
return &localSharedMemory[0];
|
||||||
|
}
|
||||||
|
|
||||||
auto getSharedMemory() -> char * {
|
auto getSharedMemory() -> char * {
|
||||||
|
if(impl.sharedMemory != nullptr){
|
||||||
|
return impl.sharedMemory;
|
||||||
|
}
|
||||||
int shmId = shmget(impl.sharedMemoryKey, 0, 0);
|
int shmId = shmget(impl.sharedMemoryKey, 0, 0);
|
||||||
if (shmId < 0) {
|
if (shmId < 0) {
|
||||||
//using a local buffer for shared memory testing
|
//using a local buffer for shared memory testing
|
||||||
if (localSharedMemory.empty()) {
|
return getLocalMemory();
|
||||||
initSemaphore();
|
|
||||||
constexpr int kilo = 1024;
|
|
||||||
localSharedMemory.resize(impl.sharedMemorySize * kilo);
|
|
||||||
}
|
|
||||||
return &localSharedMemory[0];
|
|
||||||
}
|
}
|
||||||
return static_cast<char *>(shmat(shmId, nullptr, 0));
|
char *ptr = static_cast<char *>(shmat(shmId, nullptr, 0));
|
||||||
|
if(reinterpret_cast<size_t>(ptr) == static_cast<size_t>(-1)){
|
||||||
|
log(LogLevel::WARNING, strerror(errno));
|
||||||
|
}else{
|
||||||
|
impl.sharedMemory = ptr;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
return getLocalMemory();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto getSharedMemory(char *address, int size, int offset) -> void {
|
auto getSharedMemory(char *address, int size, int offset) -> void {
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace vkvm {
|
||||||
signal(signalNumber, callback);
|
signal(signalNumber, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto getInterrupTable() -> InterruptEntry * {
|
auto getInterruptTable() -> InterruptEntry * {
|
||||||
return reinterpret_cast<InterruptEntry *>(getSharedMemory() + sizeof(Registers) + impl.reservedSize);
|
return reinterpret_cast<InterruptEntry *>(getSharedMemory() + sizeof(Registers) + impl.reservedSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,9 +36,12 @@ namespace vkvm {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto callEvent(EventType type) -> bool {
|
auto callEvent(EventType type) -> bool {
|
||||||
auto ivt = getInterrupTable();
|
auto ivt = getInterruptTable();
|
||||||
if (ivt[type].pid != 0) {
|
for(int i = 0; i < impl.interruptEntrysPerEventType;i++){
|
||||||
sendSignal(ivt[type].pid, ivt[type].signum);
|
auto &entry= ivt[type * impl.interruptEntrysPerEventType + i];
|
||||||
|
if (entry.pid != 0) {
|
||||||
|
sendSignal(entry.pid, entry.signum);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -71,10 +74,10 @@ namespace vkvm {
|
||||||
auto buttonPressed(KeyCode keyCode) -> void {
|
auto buttonPressed(KeyCode keyCode) -> void {
|
||||||
lockSharedMemory();
|
lockSharedMemory();
|
||||||
auto reg = getRegisters();
|
auto reg = getRegisters();
|
||||||
if (reg->keyboardBuffer_index_write == sizeof(reg->keyboardBuffer)) {
|
if (reg->keyboardBuffer_index_write >= sizeof(reg->keyboardBuffer)) {
|
||||||
reg->keyboardBuffer_index_write = 0;
|
reg->keyboardBuffer_index_write = 0;
|
||||||
}
|
}
|
||||||
reg->keyboardBuffer[reg->keyboardBuffer_index_write++] = keyCode.getValue();
|
reg->keyboardBuffer[reg->keyboardBuffer_index_write++] = keyCode;
|
||||||
unlockSharedMemory();
|
unlockSharedMemory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "GraphicMode.hpp"
|
#include "GraphicMode.hpp"
|
||||||
#include "KeyCode.hpp"
|
#include "KeyCode.hpp"
|
||||||
#include "LayoutVersion.hpp"
|
#include "LayoutVersion.hpp"
|
||||||
|
#include <array>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -54,9 +55,12 @@ constexpr int keyboardBufferSize = 16;
|
||||||
int sharedMemoryPid;
|
int sharedMemoryPid;
|
||||||
key_t sharedMemoryKey;
|
key_t sharedMemoryKey;
|
||||||
int sharedMemorySize;
|
int sharedMemorySize;
|
||||||
int interruptEntyCount = 64; //NOLINT
|
int interruptEntyCount = 256; //NOLINT
|
||||||
|
int interruptEntrysPerEventType = 8; //NOLINT
|
||||||
int reservedSize = 1024; //NOLINT
|
int reservedSize = 1024; //NOLINT
|
||||||
std::vector<std::function<void()>> eventTable;
|
std::vector<std::function<void()>> eventTable;
|
||||||
|
bool localMemoryWarn = true;
|
||||||
|
char *sharedMemory = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Impl impl;
|
extern Impl impl;
|
||||||
|
@ -75,7 +79,7 @@ constexpr int keyboardBufferSize = 16;
|
||||||
auto onSignal(int signalNumber, void(*callback)(int)) -> void;
|
auto onSignal(int signalNumber, void(*callback)(int)) -> void;
|
||||||
|
|
||||||
|
|
||||||
auto getInterrupTable() -> InterruptEntry *;
|
auto getInterruptTable() -> InterruptEntry *;
|
||||||
|
|
||||||
auto getRegisters() -> Registers *;
|
auto getRegisters() -> Registers *;
|
||||||
|
|
||||||
|
|
181
src/vkvm.cpp
181
src/vkvm.cpp
|
@ -16,57 +16,144 @@ namespace vkvm {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto setDefaultValues() -> void {
|
auto setDefaultValues() -> void {
|
||||||
|
impl.localMemoryWarn = false;
|
||||||
if(getSharedMemory() != nullptr) {
|
if(getSharedMemory() != nullptr) {
|
||||||
//set default values
|
//set default values
|
||||||
|
setMode(GraphicMode::RGB);
|
||||||
setCharactersPerRow(60);// NOLINT
|
setCharactersPerRow(60);// NOLINT
|
||||||
setCharactersPerColumn(20);// NOLINT
|
setCharactersPerColumn(20);// NOLINT
|
||||||
setHeight(600);// NOLINT
|
setHeight(600);// NOLINT
|
||||||
setWidth(800);// NOLINT
|
setWidth(800);// NOLINT
|
||||||
setMousePosition(42, 42);// NOLINT
|
setMousePosition(42, 42);// NOLINT
|
||||||
setBackgroundColor(Color(200, 50, 20));// NOLINT
|
setBackgroundColor(black);
|
||||||
setForegroundColor(Color(20, 200, 50));// NOLINT
|
setForegroundColor(white);
|
||||||
setMode(GraphicMode::RGB);// NOLINT
|
|
||||||
setRedrawInterval(20);// NOLINT
|
setRedrawInterval(20);// NOLINT
|
||||||
setTimerInterruptInterval(10);// NOLINT
|
setTimerInterruptInterval(10);// NOLINT
|
||||||
|
setFont(FontType(3,"",0,0));
|
||||||
}
|
}
|
||||||
|
impl.localMemoryWarn = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto registerEvent(EventType type, const std::function<void()> &handler) -> bool {
|
auto registerEvent(EventType type, const std::function<void()> &handler) -> bool {
|
||||||
int signum = SIGUSR1 + impl.eventTable.size();
|
int signum = SIGUSR1 + impl.eventTable.size();
|
||||||
auto ivt = getInterrupTable();
|
auto ivt = getInterruptTable();
|
||||||
|
|
||||||
lockSharedMemory();
|
lockSharedMemory();
|
||||||
|
|
||||||
ivt[type].pid = getpid();
|
for(int i = 0; i < impl.interruptEntrysPerEventType;i++){
|
||||||
ivt[type].signum = signum;
|
auto &entry= ivt[type * impl.interruptEntrysPerEventType + i];
|
||||||
impl.eventTable.push_back(handler);
|
if (entry.pid == 0) {
|
||||||
|
|
||||||
onSignal(signum, [](int sig){
|
entry.pid = getpid();
|
||||||
if(sig >= SIGUSR1){
|
entry.signum = signum;
|
||||||
if((sig - SIGUSR1) < impl.eventTable.size()){
|
impl.eventTable.push_back(handler);
|
||||||
impl.eventTable[sig - SIGUSR1]();
|
|
||||||
}
|
onSignal(signum, [](int sig){
|
||||||
|
if(sig >= SIGUSR1){
|
||||||
|
if((sig - SIGUSR1) < impl.eventTable.size()){
|
||||||
|
impl.eventTable[sig - SIGUSR1]();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
unlockSharedMemory();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
unlockSharedMemory();
|
unlockSharedMemory();
|
||||||
|
return false;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto setPixel(int x, int y, Color color) -> bool {
|
auto setPixel(int x, int y, Color color) -> bool {
|
||||||
char *ptr = getPixelArea() + (y * getWidth() + x) * 3;
|
lockSharedMemory();
|
||||||
ptr[0] = color.getRed();
|
auto reg = getRegisters();
|
||||||
ptr[1] = color.getGreen();
|
const int bitsPerPixel = 8;
|
||||||
ptr[2] = color.getBlue();
|
|
||||||
|
switch(reg->graphicMode) {
|
||||||
|
case Text: {
|
||||||
|
int pixelIndex = (y * getWidth() + x);
|
||||||
|
unsigned char *ptr = reinterpret_cast<unsigned char *>(getPixelArea()) + (pixelIndex / bitsPerPixel);
|
||||||
|
if(color == reg->foreground_color){
|
||||||
|
//set bit to 1
|
||||||
|
ptr[0] |= (1 << (pixelIndex % bitsPerPixel));
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
//set bit to 0
|
||||||
|
ptr[0] &= ~(1 << (pixelIndex % bitsPerPixel));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TwoColors: {
|
||||||
|
int pixelIndex = (y * getWidth() + x);
|
||||||
|
unsigned char *ptr = reinterpret_cast<unsigned char *>(getPixelArea()) + (pixelIndex / bitsPerPixel);
|
||||||
|
if(color == reg->foreground_color){
|
||||||
|
//set bit to 1
|
||||||
|
ptr[0] |= (1 << (pixelIndex % bitsPerPixel));
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
//set bit to 0
|
||||||
|
ptr[0] &= ~(1 << (pixelIndex % bitsPerPixel));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Gray_256: {
|
||||||
|
unsigned char *ptr = reinterpret_cast<unsigned char *>(getPixelArea()) + (y * getWidth() + x);
|
||||||
|
int avg = color.getRed() + color.getGreen() + color.getBlue();
|
||||||
|
avg /= 3;
|
||||||
|
ptr[0] = avg;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case RGB: {
|
||||||
|
unsigned char *ptr = reinterpret_cast<unsigned char *>(getPixelArea()) + (y * getWidth() + x) * 3;
|
||||||
|
ptr[0] = color.getRed();
|
||||||
|
ptr[1] = color.getGreen();
|
||||||
|
ptr[2] = color.getBlue();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unlockSharedMemory();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto getPixel(int x, int y) -> Color {
|
auto getPixel(int x, int y) -> Color {
|
||||||
//TODO(julian): other than RGB colores
|
Color color = Color(0,0,0);
|
||||||
//only RGB colores for now
|
auto reg = getRegisters();
|
||||||
unsigned char *ptr = reinterpret_cast<unsigned char *>(getPixelArea()) + (y * getWidth() + x) * 3;
|
const int bitsPerPixel = 8;
|
||||||
return {ptr[0], ptr[1], ptr[2]};
|
|
||||||
|
switch(reg->graphicMode) {
|
||||||
|
case Text: {
|
||||||
|
int pixelIndex = (y * getWidth() + x);
|
||||||
|
unsigned char *ptr = reinterpret_cast<unsigned char *>(getPixelArea()) + pixelIndex / bitsPerPixel;
|
||||||
|
bool bit = static_cast<bool>(ptr[0] & (1 << (pixelIndex % bitsPerPixel)));
|
||||||
|
if(bit){
|
||||||
|
color = reg->foreground_color;
|
||||||
|
}else{
|
||||||
|
color =reg->background_color;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TwoColors: {
|
||||||
|
int pixelIndex = (y * getWidth() + x);
|
||||||
|
unsigned char *ptr = reinterpret_cast<unsigned char *>(getPixelArea()) + (pixelIndex / bitsPerPixel);
|
||||||
|
bool bit = static_cast<bool>(ptr[0] & (1 << (pixelIndex % bitsPerPixel)));
|
||||||
|
if(bit){
|
||||||
|
color = reg->foreground_color;
|
||||||
|
}else{
|
||||||
|
color =reg->background_color;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Gray_256: {
|
||||||
|
unsigned char *ptr = reinterpret_cast<unsigned char *>(getPixelArea()) + (y * getWidth() + x) * 1;
|
||||||
|
color = {ptr[0], ptr[0], ptr[0]};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case RGB: {
|
||||||
|
unsigned char *ptr = reinterpret_cast<unsigned char *>(getPixelArea()) + (y * getWidth() + x) * 3;
|
||||||
|
color = {ptr[0], ptr[1], ptr[2]};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto setText(std::string text) -> bool {
|
auto setText(std::string text) -> bool {
|
||||||
|
@ -123,7 +210,32 @@ namespace vkvm {
|
||||||
|
|
||||||
auto setMode(GraphicMode newValue) -> void {
|
auto setMode(GraphicMode newValue) -> void {
|
||||||
lockSharedMemory();
|
lockSharedMemory();
|
||||||
getRegisters()->graphicMode = newValue;
|
auto reg = getRegisters();
|
||||||
|
if(reg->graphicMode != newValue){
|
||||||
|
|
||||||
|
std::vector<Color> pixels;
|
||||||
|
int height = reg->height_pixels;
|
||||||
|
int width = reg->width_pixels;
|
||||||
|
pixels.resize(height * width);
|
||||||
|
|
||||||
|
for(int y = 0; y < height;y++){
|
||||||
|
for(int x = 0;x < width;x++){
|
||||||
|
pixels[y * width + x] = getPixel(x,y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getRegisters()->graphicMode = newValue;
|
||||||
|
|
||||||
|
unlockSharedMemory();
|
||||||
|
for(int y = 0; y < height;y++){
|
||||||
|
for(int x = 0;x < width;x++){
|
||||||
|
setPixel(x,y, pixels[y * width + x]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lockSharedMemory();
|
||||||
|
}else{
|
||||||
|
reg->graphicMode = newValue;
|
||||||
|
}
|
||||||
unlockSharedMemory();
|
unlockSharedMemory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,7 +263,7 @@ namespace vkvm {
|
||||||
return getRegisters()->background_color;
|
return getRegisters()->background_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto setBackgroundColor(Color newValue) -> void {
|
auto setBackgroundColor(const Color &newValue) -> void {
|
||||||
lockSharedMemory();
|
lockSharedMemory();
|
||||||
getRegisters()->background_color = newValue;
|
getRegisters()->background_color = newValue;
|
||||||
unlockSharedMemory();
|
unlockSharedMemory();
|
||||||
|
@ -161,7 +273,7 @@ namespace vkvm {
|
||||||
return getRegisters()->foreground_color;
|
return getRegisters()->foreground_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto setForegroundColor(Color newValue) -> void {
|
auto setForegroundColor(const Color &newValue) -> void {
|
||||||
lockSharedMemory();
|
lockSharedMemory();
|
||||||
getRegisters()->foreground_color = newValue;
|
getRegisters()->foreground_color = newValue;
|
||||||
unlockSharedMemory();
|
unlockSharedMemory();
|
||||||
|
@ -177,7 +289,7 @@ namespace vkvm {
|
||||||
|
|
||||||
auto getFont() -> FontType {
|
auto getFont() -> FontType {
|
||||||
//TODO(julian): get font properly
|
//TODO(julian): get font properly
|
||||||
return font_1;
|
return {getRegisters()->textMode_font, "", 0, 0};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto setFont(const FontType &newValue) -> void {
|
auto setFont(const FontType &newValue) -> void {
|
||||||
|
@ -192,8 +304,17 @@ namespace vkvm {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto getLastPressedKey() -> KeyCode {
|
auto getLastPressedKey() -> KeyCode {
|
||||||
//TODO(julian): get key properly
|
lockSharedMemory();
|
||||||
return KeyCode(0);
|
auto keyCode = KeyCode(0);
|
||||||
|
auto reg = getRegisters();
|
||||||
|
if(reg->keyboardBuffer_index_read != reg->keyboardBuffer_index_write) {
|
||||||
|
keyCode = static_cast<KeyCode>(reg->keyboardBuffer[reg->keyboardBuffer_index_read++]);
|
||||||
|
if (reg->keyboardBuffer_index_read >= sizeof(reg->keyboardBuffer)) {
|
||||||
|
reg->keyboardBuffer_index_read = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unlockSharedMemory();
|
||||||
|
return keyCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -153,7 +153,7 @@ namespace vkvm {
|
||||||
* set background color in two color mode.
|
* set background color in two color mode.
|
||||||
* @param newValue new background color.
|
* @param newValue new background color.
|
||||||
*/
|
*/
|
||||||
auto setBackgroundColor(Color newValue) -> void;
|
auto setBackgroundColor(const Color &newValue) -> void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get foreground color in two color mode.
|
* get foreground color in two color mode.
|
||||||
|
@ -165,7 +165,7 @@ namespace vkvm {
|
||||||
* set foreground color in two color mode.
|
* set foreground color in two color mode.
|
||||||
* @param newValue new foreground color.
|
* @param newValue new foreground color.
|
||||||
*/
|
*/
|
||||||
auto setForegroundColor(Color newValue) -> void;
|
auto setForegroundColor(const Color &newValue) -> void;
|
||||||
|
|
||||||
//text mode
|
//text mode
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
#include "../src/vkvm.hpp"
|
||||||
|
#include <catch2/catch.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
TEST_CASE("Colors") {
|
||||||
|
vkvm::initialize(0);
|
||||||
|
vkvm::setPixel(10, 10, vkvm::black);//NOLINT
|
||||||
|
vkvm::setPixel(11, 11, vkvm::white);//NOLINT
|
||||||
|
vkvm::setPixel(12, 12, vkvm::green);//NOLINT
|
||||||
|
vkvm::setPixel(13, 13, vkvm::red);//NOLINT
|
||||||
|
vkvm::setPixel(14, 14, vkvm::blue);//NOLINT
|
||||||
|
vkvm::setPixel(15, 15, vkvm::Color(66, 77, 88)); //NOLINT
|
||||||
|
vkvm::setPixel(16, 16, vkvm::Color(0xFFFFFF));//NOLINT
|
||||||
|
|
||||||
|
SECTION("RGB") {
|
||||||
|
REQUIRE(vkvm::getPixel(10, 10) == vkvm::black);//NOLINT
|
||||||
|
REQUIRE(vkvm::getPixel(11, 11) == vkvm::white);//NOLINT
|
||||||
|
REQUIRE(vkvm::getPixel(12, 12) == vkvm::green);//NOLINT
|
||||||
|
REQUIRE(vkvm::getPixel(13, 13) == vkvm::red);//NOLINT
|
||||||
|
REQUIRE(vkvm::getPixel(14, 14) == vkvm::blue);//NOLINT
|
||||||
|
REQUIRE(vkvm::getPixel(15, 15) == vkvm::Color(66, 77, 88));//NOLINT
|
||||||
|
REQUIRE(vkvm::getPixel(16, 16) == vkvm::white);//NOLINT
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("TwoColors") {
|
||||||
|
vkvm::setMode(vkvm::TwoColors);
|
||||||
|
REQUIRE(vkvm::getPixel(10, 10) == vkvm::black);//NOLINT
|
||||||
|
REQUIRE(vkvm::getPixel(11, 11) == vkvm::white);//NOLINT
|
||||||
|
REQUIRE(vkvm::getPixel(12, 12) == vkvm::black);//NOLINT
|
||||||
|
REQUIRE(vkvm::getPixel(13, 13) == vkvm::black);//NOLINT
|
||||||
|
REQUIRE(vkvm::getPixel(14, 14) == vkvm::black);//NOLINT
|
||||||
|
REQUIRE(vkvm::getPixel(15, 15) == vkvm::black);//NOLINT
|
||||||
|
REQUIRE(vkvm::getPixel(16, 16) == vkvm::white);//NOLINT
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Gray256") {
|
||||||
|
vkvm::setMode(vkvm::Gray_256);
|
||||||
|
REQUIRE(vkvm::getPixel(10, 10) == vkvm::black);//NOLINT
|
||||||
|
REQUIRE(vkvm::getPixel(11, 11) == vkvm::white);//NOLINT
|
||||||
|
REQUIRE(vkvm::getPixel(12, 12) == vkvm::Color(85, 85, 85));//NOLINT
|
||||||
|
REQUIRE(vkvm::getPixel(13, 13) == vkvm::Color(85, 85, 85));//NOLINT
|
||||||
|
REQUIRE(vkvm::getPixel(14, 14) == vkvm::Color(85, 85, 85));//NOLINT
|
||||||
|
REQUIRE(vkvm::getPixel(15, 15) == vkvm::Color(77, 77, 77));//NOLINT
|
||||||
|
REQUIRE(vkvm::getPixel(16, 16) == vkvm::white);//NOLINT
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue