diff --git a/CMakeLists.txt b/CMakeLists.txt index 86dff94..51038ba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,10 +42,12 @@ add_executable(Pycron src/main.cpp src/States/GameState.h src/Graphics/Font.cpp src/Graphics/Font.h - src/States/EditorState.cpp - src/States/EditorState.h + src/States/Editor/EditorState.cpp + src/States/Editor/EditorState.h src/Graphics/PycronImage.h - src/Graphics/PycronImage.cpp) + src/Graphics/PycronImage.cpp + src/States/Editor/PythonTokenizer.cpp + src/States/Editor/PythonTokenizer.h) add_subdirectory(dependencies/pocketpy) # Declaring our executable diff --git a/resources/fonts/main.font b/resources/fonts/main.font index 6e1f757..b10d7f9 100644 --- a/resources/fonts/main.font +++ b/resources/fonts/main.font @@ -80,8 +80,8 @@ "101": "00000000000111010001111111000001110", "102": "00000001110100011111010000100001000", "103": "00000000000111010001011110000101110", - "104": "00000100001000011110100011000110001", - "105": "00000001000000001100001000010000100", + "104": "10000100001111010001100011000110001", + "105": "00100000000110000100001000010000100", "106": "00000001000000001100001000010011000", "107": "00000100001001010100110001010010010", "108": "00000001000010000100001000010000010", @@ -97,7 +97,7 @@ "118": "00000000001000110001100010101000100", "119": "00000000001000110101101011010101010", "120": "00000000001000101010001000101010001", - "121": "00000100011000110001011110000101110", + "121": "00000000001000110001011110000101110", "122": "00000000001111100010001000100011111", diff --git a/src/Graphics/Graphics.cpp b/src/Graphics/Graphics.cpp index 8d3b591..7bd07ee 100644 --- a/src/Graphics/Graphics.cpp +++ b/src/Graphics/Graphics.cpp @@ -74,7 +74,7 @@ void Graphics::renderVirtualScreen() { BeginDrawing(); ClearBackground(BLACK); DrawTexturePro(m_virtualScreen.texture, m_virtualScreenLocalBounds, m_virtualScreenWindowBounds, m_origin, 0.0f, WHITE); - //DrawText(std::to_string(GetFPS()).c_str(), 10, 10, 30, YELLOW); + DrawText(std::to_string(GetFPS()).c_str(), 10, 10, 30, YELLOW); EndDrawing(); } diff --git a/src/Pycron.cpp b/src/Pycron.cpp index 2a84668..86fca65 100644 --- a/src/Pycron.cpp +++ b/src/Pycron.cpp @@ -1,8 +1,7 @@ // // Created by Bobby Lucero on 4/20/24. // -#include -#include + #include #include #include "Pycron.h" @@ -11,17 +10,7 @@ std::string Pycron::PythonDirectory = "./python"; -std::string loadFileToString(const std::string& filename) { - std::ifstream file(filename); // Open the file - std::stringstream buffer; // String stream to hold file content - if (file.is_open()) { // Check if file is open - buffer << file.rdbuf(); // Read the entire file into the buffer - file.close(); // Close the file - } else { - std::cerr << "Unable to open file: " << filename << std::endl; - } - return buffer.str(); // Return the content string -} + Pycron::Pycron() { SetTraceLogLevel(LOG_ERROR); @@ -153,3 +142,15 @@ pkpy::PyObject *Pycron::getMouseDown(pkpy::VM *vm, pkpy::ArgsView args) { return pkpy::py_var(vm, held); } +std::string Pycron::loadFileToString(const std::string &filename) { + std::ifstream file(filename); // Open the file + std::stringstream buffer; // String stream to hold file content + if (file.is_open()) { // Check if file is open + buffer << file.rdbuf(); // Read the entire file into the buffer + file.close(); // Close the file + } else { + std::cerr << "Unable to open file: " << filename << std::endl; + } + return buffer.str(); // Return the content string +} + diff --git a/src/Pycron.h b/src/Pycron.h index d637e98..c4b4d3a 100644 --- a/src/Pycron.h +++ b/src/Pycron.h @@ -1,5 +1,7 @@ #pragma once #include +#include +#include #include "pocketpy.h" #include "StateManager.h" #include "Graphics/Graphics.h" @@ -37,5 +39,7 @@ public: static pkpy::PyObject* getKeyDown(pkpy::VM* vm, pkpy::ArgsView args); static pkpy::PyObject* getMousePressed(pkpy::VM* vm, pkpy::ArgsView args); static pkpy::PyObject* getMouseDown(pkpy::VM* vm, pkpy::ArgsView args); + + static std::string loadFileToString(const std::string& filename); }; diff --git a/src/StateManager.cpp b/src/StateManager.cpp index 29fe132..590e10e 100644 --- a/src/StateManager.cpp +++ b/src/StateManager.cpp @@ -8,7 +8,7 @@ StateManager::StateManager(Pycron *pycron, Graphics *graphics) : m_pycron(pycron m_gameState = new GameState(m_pycron->m_vm, graphics); m_editorState = new EditorState(m_pycron->m_vm, graphics); m_currentState = nullptr; - RequestStateChange(GAME); + ChangeState(EDITOR); } StateManager::~StateManager() { @@ -19,7 +19,7 @@ StateManager::~StateManager() { } -void StateManager::RequestStateChange(StateManager::StateType state) { +void StateManager::ChangeState(StateManager::StateType state) { if(m_currentState){ m_currentState->OnExit(); } @@ -46,9 +46,9 @@ void StateManager::Draw() { if(IsKeyPressed(KEY_ENTER)){ if(m_currentState == m_gameState){ - RequestStateChange(EDITOR); + ChangeState(EDITOR); }else{ - RequestStateChange(GAME); + ChangeState(GAME); } } diff --git a/src/StateManager.h b/src/StateManager.h index 62920d4..64767cc 100644 --- a/src/StateManager.h +++ b/src/StateManager.h @@ -3,7 +3,7 @@ #include "Pycron.h" #include "Graphics/Graphics.h" #include "States/GameState.h" -#include "States/EditorState.h" +#include "States/Editor/EditorState.h" class Pycron; class Graphics; @@ -29,7 +29,7 @@ public: explicit StateManager(Pycron* pycron, Graphics* graphics); ~StateManager(); - void RequestStateChange(StateType state); + void ChangeState(StateManager::StateType state); void RequestLoadGame(); void RequestRunGame(); diff --git a/src/States/Editor/EditorState.cpp b/src/States/Editor/EditorState.cpp new file mode 100644 index 0000000..1a01e4e --- /dev/null +++ b/src/States/Editor/EditorState.cpp @@ -0,0 +1,145 @@ +// +// Created by Bobby on 5/13/2024. +// + +#include +#include + +#include "EditorState.h" +#include "../../Graphics/PycronImage.h" +#include "../../Pycron.h" + + +EditorState::EditorState(pkpy::VM *vm, Graphics *graphics) : m_vm(vm), m_graphics(graphics){ + m_pythonTokenizer = new PythonTokenizer(); + + Token a(TokenType::Keyword, "Test"); + + std::string randomSource = Pycron::loadFileToString("../python/main.py"); + + m_baseBackgroundColor = 59; + m_baseTextColor = 51; + m_lineNumberBackgroundColor = 58; + m_lineNumberTextColor = 61; + + m_topLetterSpacing = 1; + m_bottomLetterSpacing = 1; + m_leftLetterSpacing = 1; + m_rightLetterSpacing = 1; + + m_charWidth = m_leftLetterSpacing + m_graphics->GetCurrentFontWidth() + m_rightLetterSpacing; // Final size of char with spacing. If the literal width of the font is n, the final width is n + spacing. + m_charHeight = m_topLetterSpacing + m_graphics->GetCurrentFontHeight() + m_bottomLetterSpacing; + + m_textWidth = (int)(m_graphics->m_screenWidth / m_charWidth); + m_textHeight = (int)(m_graphics->m_screenHeight / m_charHeight); + + m_characterBuffer = std::vector(m_textWidth * m_textHeight); + m_foregroundIndexBuffer = std::vector(m_textWidth * m_textHeight); + m_backgroundIndexBuffer = std::vector(m_textWidth * m_textHeight); + + Clear(); + + + std::string testText = "This is a test\n[Test]\nThis is the end of the test."; + + LoadStringToBuffer(randomSource); + +} + +EditorState::~EditorState() { + delete m_pythonTokenizer; +} + +void EditorState::Draw() { + m_graphics->Clear(0); + + + for (int i = 0; i < m_characterBuffer.size(); ++i) { + int x = (i % m_textWidth) * m_charWidth; + int y = (i / m_textWidth) * m_charHeight; + m_graphics->Rect(x, y, m_charWidth, m_charHeight, m_backgroundIndexBuffer[i]); + m_graphics->Char(m_characterBuffer[i], x + m_leftLetterSpacing + 1, y + m_topLetterSpacing + 1, 0); + m_graphics->Char(m_characterBuffer[i], x + m_leftLetterSpacing, y + m_topLetterSpacing, m_foregroundIndexBuffer[i]); + } + + if(m_dirty){ + Clear(); + m_dirty = false; + for (int i = 0; i < m_text.size(); ++i) { + std::string lineNumber = std::to_string(i); + int size = 2; + int diff = size - (int)lineNumber.size(); + if(diff > 0) lineNumber = std::string(diff, ' ') + lineNumber; + Text(lineNumber, 0, i, m_lineNumberTextColor, m_lineNumberBackgroundColor); + Text(m_text[i], size, i, m_baseTextColor, m_baseBackgroundColor); + } + } + +} + +void EditorState::OnEnter() { + +} + +void EditorState::OnExit() { + +} + +void EditorState::OnKeyPressed(int key) { + std::cout << key << ". \n"; +} + +void EditorState::Clear() { + for (int i = 0; i < m_textWidth * m_textHeight; ++i) { + m_characterBuffer[i] = ' '; + m_foregroundIndexBuffer[i] = m_baseTextColor; + m_backgroundIndexBuffer[i] = m_baseBackgroundColor; + } +} + +void EditorState::Text(const std::string &text, int x, int y, int fg, int bg) { + for (int i = 0; i < text.size(); ++i) { + int charX = x + i; + int charY = y; + if(charX < 0 || charY < 0 || charX >= m_textWidth || charY >= m_textHeight){ + return; + } + char c = text[i]; + int index = y * m_textWidth + (x + i); + m_characterBuffer[index] = c; + m_backgroundIndexBuffer[index] = bg; + m_foregroundIndexBuffer[index] = fg; + + + } +} + +void EditorState::OnCharPressed(char character) { + +} + +void EditorState::LoadStringToBuffer(const std::string &text) { + m_text.clear(); + + + std::vector lines; + size_t start = 0; + size_t end = 0; + + while((end = text.find('\n', start)) != std::string::npos){ + lines.push_back(text.substr(start, end - start)); + start = end + 1; + } + + lines.push_back(text.substr(start)); + + for (const auto& line : lines) { + m_text.push_back(line); + } + + m_dirty = true; +} + + + + diff --git a/src/States/Editor/EditorState.h b/src/States/Editor/EditorState.h new file mode 100644 index 0000000..2d2d0d1 --- /dev/null +++ b/src/States/Editor/EditorState.h @@ -0,0 +1,53 @@ +#pragma once + +#include +#include "PythonTokenizer.h" +#include "../../State.h" + + +class PycronImage; + +class EditorState : public State{ + +public: + EditorState(pkpy::VM* vm, Graphics* graphics); + ~EditorState(); + + void Draw() override; + void OnEnter() override; + void OnExit() override; + void OnKeyPressed(int key) override; + void OnCharPressed(char character) override; + +private: + pkpy::VM* m_vm; + Graphics* m_graphics; + PythonTokenizer* m_pythonTokenizer; + + uint8_t m_charWidth, m_charHeight; + uint8_t m_textWidth, m_textHeight; + uint8_t m_topLetterSpacing, m_bottomLetterSpacing, m_leftLetterSpacing, m_rightLetterSpacing; + // Text Buffer + std::vector m_characterBuffer; + std::vector m_foregroundIndexBuffer; + std::vector m_backgroundIndexBuffer; + + // Text Data + std::vector m_text; + + // Theming + uint8_t m_baseBackgroundColor; + uint8_t m_baseTextColor; + uint8_t m_lineNumberBackgroundColor; + uint8_t m_lineNumberTextColor; + + bool m_dirty; + + void Clear(); + void Text(const std::string &text, int x, int y, int fg = 0, int bg = 63); + + void LoadStringToBuffer(const std::string& text); + + +}; + diff --git a/src/States/Editor/PythonTokenizer.cpp b/src/States/Editor/PythonTokenizer.cpp new file mode 100644 index 0000000..e5159bb --- /dev/null +++ b/src/States/Editor/PythonTokenizer.cpp @@ -0,0 +1,5 @@ +// +// Created by Bobby on 9/28/2024. +// + +#include "PythonTokenizer.h" diff --git a/src/States/Editor/PythonTokenizer.h b/src/States/Editor/PythonTokenizer.h new file mode 100644 index 0000000..d671e28 --- /dev/null +++ b/src/States/Editor/PythonTokenizer.h @@ -0,0 +1,29 @@ +// +// Created by Bobby on 9/28/2024. +// + +#pragma once + +#include + +enum TokenType{ + Keyword, + Identifier, + Literal, + Operator, + Punctuation, + EndOfFile, + Unknown +}; + +struct Token{ + TokenType type; + std::string value; + + Token(TokenType t, const std::string& v) + : type(t), value(v) {} +}; + +class PythonTokenizer { + +}; diff --git a/src/States/EditorState.cpp b/src/States/EditorState.cpp deleted file mode 100644 index 48b9dc5..0000000 --- a/src/States/EditorState.cpp +++ /dev/null @@ -1,77 +0,0 @@ -// -// Created by Bobby on 5/13/2024. -// - -#include "EditorState.h" -#include "../Graphics/PycronImage.h" - - -EditorState::EditorState(pkpy::VM *vm, Graphics *graphics) : m_vm(vm), m_graphics(graphics){ - test = m_graphics->loadImage("resources/plane2.png"); - - m_horizontalLetterSpacing = 1; - m_verticalLetterSpacing = 1; - - m_charWidth = m_graphics->GetCurrentFontWidth() + m_horizontalLetterSpacing; // Final size of char with spacing. If the literal width of the font is n, the final width is n + spacing. - m_charHeight = m_graphics->GetCurrentFontHeight() + m_verticalLetterSpacing; - - m_textWidth = (int)(m_graphics->m_screenWidth / m_charWidth); - m_textHeight = (int)(m_graphics->m_screenHeight / m_charHeight); - - m_characterBuffer = std::vector(m_textWidth * m_textHeight); - - Clear(); - -} - -EditorState::~EditorState() { - delete test; -} - -void EditorState::Draw() { - m_graphics->Clear(1); - std::string text = "Editor State"; - - for (int i = 0; i < m_characterBuffer.size(); ++i) { - m_graphics->Char(m_characterBuffer[i], (i % m_textWidth) * m_charWidth, (i / m_textWidth) * m_charHeight, 5); - } - Clear(); - Text("This is a big long test!!!@%)(!*@#%PALSKDGJ", ((float)m_graphics->mouseX() / m_graphics->m_screenWidth) * m_textWidth, ((float)m_graphics->mouseY() / m_graphics->m_screenHeight) * m_textHeight); - -} - -void EditorState::OnEnter() { - -} - -void EditorState::OnExit() { - -} - -void EditorState::OnKeyPressed(int key) { - std::cout << key << ". \n"; -} - -void EditorState::Clear() { - for (int i = 0; i < m_textWidth * m_textHeight; ++i) { - m_characterBuffer[i] = ' '; - } -} - -void EditorState::Text(const std::string &text, int x, int y) { - for (int i = 0; i < text.size(); ++i) { - int charX = x + i; - int charY = y; - if(charX < 0 || charY < 0 || charX >= m_textWidth || charY >= m_textHeight){ - return; - } - char c = text[i]; - m_characterBuffer[y * m_textWidth + (x + i)] = c; - } -} - -void EditorState::OnCharPressed(char character) { - -} - - diff --git a/src/States/EditorState.h b/src/States/EditorState.h deleted file mode 100644 index 113d60a..0000000 --- a/src/States/EditorState.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once -#include "../State.h" - -class PycronImage; - -class EditorState : public State{ - -public: - EditorState(pkpy::VM* vm, Graphics* graphics); - ~EditorState(); - - void Draw() override; - void OnEnter() override; - void OnExit() override; - void OnKeyPressed(int key) override; - void OnCharPressed(char character) override; - -private: - pkpy::VM* m_vm; - PycronImage* test; - Graphics* m_graphics; - int m_charWidth, m_charHeight; - int m_textWidth, m_textHeight; - int m_horizontalLetterSpacing, m_verticalLetterSpacing; - std::vector m_characterBuffer; - - void Clear(); - void Text(const std::string& text, int x, int y); - - -}; -