Compare commits

..

No commits in common. "8bb88afa6b784e1a26c0ba0e92bbaa142b321005" and "efc9b0fe5eed788daaa3401ea79271687bee6e49" have entirely different histories.

23 changed files with 78 additions and 594 deletions

Binary file not shown.

View File

@ -1,38 +0,0 @@
from scene import Scene
# Palette class (inherits from scene)
class Blobs(Scene):
def __init__(self):
super().__init__()
self.title = "Squares"
self.t = 0
self.dir = True
def update(self):
pass
def draw(self):
clear(0)
for i in range(width):
for j in range(height):
c = cos(i / 10) + (sin(j / 10) + 2)
#c2 = cos(i / 5) + sin(j / 5)
pixel(i, j, 2 * c + self.t)
self.t += (1/5) * (1 if self.dir else - 1)
if(self.t > 64):
self.t = 64
self.dir = not self.dir
if(self.t < 0):
self.t = 0
self.dir = not self.dir

View File

@ -1,9 +1,6 @@
from scene import Scene from scene import Scene
from particles import Particles from particles import Particles
from triangles import Triangles from triangles import Triangles
from squares import Squares
from blobs import Blobs
from threeD import ThreeD
# Palette class (inherits from scene) # Palette class (inherits from scene)
class Palette(Scene): class Palette(Scene):
@ -20,7 +17,7 @@ class Palette(Scene):
for i in range(8): for i in range(8):
for j in range(8): for j in range(8):
rect(10 + (i * 20), 10 + (j * 20), 18, 18, (j * 8 + i)) rectangle(10 + (i * 20), 10 + (j * 20), 18, 18, (j * 8 + i))
text(str(j * 8 + i), 11 + (i * 20), 10 + (j * 20), 63) text(str(j * 8 + i), 11 + (i * 20), 10 + (j * 20), 63)
class RGBTest(Scene): class RGBTest(Scene):
@ -29,9 +26,11 @@ class RGBTest(Scene):
self.title = "RGB To Palette" self.title = "RGB To Palette"
scenes = [ ThreeD(), Particles(), Squares(), Triangles(), Palette(), Blobs()] scenes = [Particles(), Triangles(), Palette()]
current_scene = 0 current_scene = 0
KEY_T = 84 KEY_T = 84
switch = False switch = False
@ -52,5 +51,9 @@ def update():
scenes[current_scene].update() scenes[current_scene].update()
scenes[current_scene].draw() scenes[current_scene].draw()
text("T to change scene", 255, 1,31)

View File

@ -1,29 +0,0 @@
from scene import Scene
s = 128
s2 = 120-12
l = 15
a = 80
t = 0
# Palette class (inherits from scene)
class Mechanical(Scene):
def __init__(self):
super().__init__()
self.title = "Squares"
def update(self):
pass
def draw(self):
clear(0)
rect(120 - s/2, 68 - s/2, s, s, 14)
triangle(120-s/2, 68 - s/2, 120-s/2, 68+s/2,
120 + s/2, 68+s/2, 15)
line(119 + s / 2, 68 + s / 2, 119 + s2 / 2, 68 - s2/2, 15)

View File

@ -151,3 +151,7 @@ class Particles(Scene):
# triangle(mouseX, mouseY, x2, y2, x3, y3, 9) # triangle(mouseX, mouseY, x2, y2, x3, y3, 9)
# lineTri(mouseX, mouseY, x2, y2, x3, y3, 8) # lineTri(mouseX, mouseY, x2, y2, x3, y3, 8)

View File

@ -1,25 +0,0 @@
from scene import Scene
# Palette class (inherits from scene)
class Squares(Scene):
def __init__(self):
super().__init__()
self.title = "Squares"
def update(self):
pass
def draw(self):
clear(0)
for i in range(50):
for j in range(27):
rect(8 * i, 8 * j, 8, 8, (i + j) % 64)
rectBorder(8 * i, 8 * j, 8, 8, (i + j + 1) % 64)

View File

@ -1,165 +0,0 @@
from scene import Scene
from triangles import draw_line
import math
# Palette class (inherits from scene)
class ThreeD(Scene):
def __init__(self):
super().__init__()
self.title = "Squares"
self.t = 0
self.x = 0.01
self.y = 0
self.z = 0
self.a = 10
self.b = 28
self.c = 8.0/3.0
self.scale = 5
self.focal_length = 800
self.screen_width = width * 4
self.screen_height = height * 4
self.lines = []
self.points = []
self.gradient = [4, 8, 6, 15, 18, 19, 26, 25, 24, 23, 16, 23, 22, 7, 5]
self.gradient = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
def update(self):
self.t += 0.00002
if(len(self.points) > 1200):
return
dx = (self.a * (self.y - self.x)) * self.t
dy = (self.x * (self.b - self.z) - self.y) * self.t
dz = (self.x * self.y - self.c * self.z) * self.t
self.x += dx
self.y += dy
self.z += dz
self.points.append((self.x, self.y, self.z))
def line3D(self, x1, y1, z1, x2, y2, z2, c):
self.lines.append(((x1, y1, z1), (x2, y2, z2), c))
def draw(self):
self.lines.clear()
clear(0)
for i in range(len(self.points)):
size = len(self.points)
if(i < size - 1):
x, y, z = self.points[i]
x2, y2, z2 = self.points[i + 1]
x *= self.scale
y *= self.scale
z *= self.scale
x2 *= self.scale
y2 *= self.scale
z2 *= self.scale
self.line3D(x, y, z, x2, y2, z2, self.gradient[int(i / 5) % len(self.gradient)])
self.render_scene(self.focal_length, self.screen_width, self.screen_height, 0, self.t*500, self.t * 200, 0, 0, 300)
def rotate_point(self, x, y, z, angle_x, angle_y, angle_z):
"""Rotates a point around the X, Y, and Z axes."""
# Rotation around the X axis
cos_x, sin_x = math.cos(angle_x), math.sin(angle_x)
y, z = y * cos_x - z * sin_x, y * sin_x + z * cos_x
# Rotation around the Y axis
cos_y, sin_y = math.cos(angle_y), math.sin(angle_y)
x, z = x * cos_y + z * sin_y, -x * sin_y + z * cos_y
# Rotation around the Z axis
cos_z, sin_z = math.cos(angle_z), math.sin(angle_z)
x, y = x * cos_z - y * sin_z, x * sin_z + y * cos_z
return x, y, z
def project_point(self, x, y, z, focal_length, screen_width, screen_height, angle_x, angle_y, angle_z, translate_x, translate_y, translate_z):
x, y, z = self.rotate_point(x, y, z, angle_x, angle_y, angle_z)
# Apply translation
x += translate_x
y += translate_y
z += translate_z
"""Projects a 3D point onto a 2D screen using perspective projection."""
if z == 0:
z = 0.001 # Avoid division by zero
# Perspective projection formula
screen_x = (x * focal_length) / z
screen_y = (y * focal_length) / z
# Translate to screen coordinates (centered)
screen_x += screen_width / 2
screen_y += screen_height / 2
return screen_x, screen_y
def z_sort_lines(self, lines):
"""Sorts lines based on their average Z values for depth ordering."""
return sorted(lines, key=lambda line: (line[0][2] + line[1][2]) / 2, reverse=True)
def draw_3d_line(self, x1, y1, z1, x2, y2, z2, focal_length, screen_width, screen_height, color, angle_x, angle_y, angle_z, translate_x, translate_y, translate_z):
"""Draws a 3D line projected onto a 2D screen."""
# Project the endpoints
screen_x1, screen_y1 = self.project_point(x1, y1, z1, focal_length, screen_width, screen_height, angle_x, angle_y, angle_z, translate_x, translate_y, translate_z)
screen_x2, screen_y2 = self.project_point(x2, y2, z2, focal_length, screen_width, screen_height, angle_x, angle_y, angle_z, translate_x, translate_y, translate_z)
screen_x12, screen_y12 = self.project_point(x1 + 5, y1, z1, focal_length, screen_width, screen_height, angle_x, angle_y, angle_z, translate_x, translate_y, translate_z)
screen_x22, screen_y22 = self.project_point(x2 + 5, y2, z2, focal_length, screen_width, screen_height, angle_x, angle_y, angle_z, translate_x, translate_y, translate_z)
# Use the renderer to draw the line on the screen
line(screen_x1 / 4, screen_y1 / 4, screen_x2 / 4, screen_y2 / 4, color)
def render_scene(self, focal_length, screen_width, screen_height, angle_x, angle_y, angle_z, translate_x, translate_y, translate_z):
"""Renders the 3D lines in the scene with perspective projection and Z-sorting."""
# Sort the lines by Z value (depth)
sorted_lines = self.z_sort_lines(self.lines)
i = 0
# Draw each line
for line in sorted_lines:
(x1, y1, z1), (x2, y2, z2), c = line
self.draw_3d_line(x1, y1, z1, x2, y2, z2, focal_length, screen_width, screen_height, c, angle_x, angle_y, angle_z, translate_x, translate_y, translate_z)
i += 1
# Example usage
# renderer is an object that has a draw_line(x1, y1, x2, y2) function
liines = [
((-50, -50, -50), (50, -50, -50)),
((50, -50, -50), (50, 50, -50)),
((50, 50, -50), (-50, 50, -50)),
((-50, 50, -50), (-50, -50, -50)),
((-50, -50, 50), (50, -50, 50)),
((50, -50, 50), (50, 50, 50)),
((50, 50, 50), (-50, 50, 50)),
((-50, 50, 50), (-50, -50, 50)),
((-50, -50, -50), (-50, -50, 50)),
((50, -50, -50), (50, -50, 50)),
((50, 50, -50), (50, 50, 50)),
((-50, 50, -50), (-50, 50, 50)),
]
# Assuming you have a renderer object

View File

@ -77,7 +77,7 @@ class Triangles(Scene):
y = rnd(0, height) y = rnd(0, height)
c = 0 c = 0
if(rnd(0,9) < 5): if(rnd(0,9) < 5):
c = getPixel(x -3 ,y-3) c = get_pixel(x -3 ,y-3)
else: else:
c = 0 c = 0

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 B

View File

@ -64,23 +64,7 @@ void Graphics::draw(StateManager* stateManager) {
void Graphics::copyBufferToGPU() { void Graphics::copyBufferToGPU() {
Color* pixel_data = LoadImageColors(m_virtualScreenImageBuffer); Color* pixel_data = LoadImageColors(m_virtualScreenImageBuffer);
for (int i = 0; i < m_screenWidth * m_screenHeight; ++i) { for (int i = 0; i < m_screenWidth * m_screenHeight; ++i) {
uint32_t rgb = m_paletteByID[m_virtualScreenColorBuffer[i]]; pixel_data[i] = GetColor(m_paletteByID[m_virtualScreenColorBuffer[i]]);
uint8_t r = rgb >> 16 & 0xFF;
uint8_t g = rgb >> 8 & 0xFF;
uint8_t b = rgb & 0xFF;
double dR = (double)r * 0.2126;
double dG = (double)g * 0.7152;
double dB = (double)b * 0.0722;
int gray = (int)(dR + dG + dB);
double naiveGray = (r + g + b) / 3.0;
//gray = (int)naiveGray;
unsigned int out = 255;
out |= gray << 8;
out |= gray << 16;
out |= gray << 24;
pixel_data[i] = GetColor(rgb);
} }
UpdateTexture(m_virtualScreen.texture, pixel_data); UpdateTexture(m_virtualScreen.texture, pixel_data);
UnloadImageColors(pixel_data); UnloadImageColors(pixel_data);
@ -197,7 +181,7 @@ void Graphics::bindMethods(pkpy::VM *vm) {
return vm->None; return vm->None;
}); });
vm->bind(vm->builtins, "getPixel(x: int, y: int) -> int", [this](pkpy::VM* vm, pkpy::ArgsView args){ vm->bind(vm->builtins, "get_pixel(x: int, y: int) -> int", [this](pkpy::VM* vm, pkpy::ArgsView args){
float x = pkpy::py_cast<float>(vm, args[0]); float x = pkpy::py_cast<float>(vm, args[0]);
float y = pkpy::py_cast<float>(vm, args[1]); float y = pkpy::py_cast<float>(vm, args[1]);
@ -213,7 +197,7 @@ void Graphics::bindMethods(pkpy::VM *vm) {
return vm->None; return vm->None;
}); });
vm->bind(vm->builtins, "rect(x: int, y: int, width: int, height: int, color: int)", [this](pkpy::VM* vm, pkpy::ArgsView args){ vm->bind(vm->builtins, "rectangle(x: int, y: int, width: int, height: int, color: int)", [this](pkpy::VM* vm, pkpy::ArgsView args){
float x = pkpy::py_cast<float>(vm, args[0]); float x = pkpy::py_cast<float>(vm, args[0]);
float y = pkpy::py_cast<float>(vm, args[1]); float y = pkpy::py_cast<float>(vm, args[1]);
float width = pkpy::py_cast<float>(vm, args[2]); float width = pkpy::py_cast<float>(vm, args[2]);
@ -223,16 +207,6 @@ void Graphics::bindMethods(pkpy::VM *vm) {
return vm->None; return vm->None;
}); });
vm->bind(vm->builtins, "rectBorder(x: int, y: int, width: int, height: int, color: int)", [this](pkpy::VM* vm, pkpy::ArgsView args){
float x = pkpy::py_cast<float>(vm, args[0]);
float y = pkpy::py_cast<float>(vm, args[1]);
float width = pkpy::py_cast<float>(vm, args[2]);
float height = pkpy::py_cast<float>(vm, args[3]);
float paletteIndex = pkpy::py_cast<float>(vm, args[4]);
this->RectBorder(x, y, width, height, paletteIndex);
return vm->None;
});
vm->bind(vm->builtins, "triangle(x1: int, y1: int, x2: int, y2: int, x3: int, y3: int, color: int)", [this](pkpy::VM* vm, pkpy::ArgsView args){ vm->bind(vm->builtins, "triangle(x1: int, y1: int, x2: int, y2: int, x3: int, y3: int, color: int)", [this](pkpy::VM* vm, pkpy::ArgsView args){
float x1 = pkpy::py_cast<float>(vm, args[0]); float x1 = pkpy::py_cast<float>(vm, args[0]);
float y1 = pkpy::py_cast<float>(vm, args[1]); float y1 = pkpy::py_cast<float>(vm, args[1]);
@ -245,16 +219,6 @@ void Graphics::bindMethods(pkpy::VM *vm) {
return vm->None; return vm->None;
}); });
vm->bind(vm->builtins, "line(x1: int, y1: int, x2: int, y2: int, color: int)", [this](pkpy::VM* vm, pkpy::ArgsView args){
float x1 = pkpy::py_cast<float>(vm, args[0]);
float y1 = pkpy::py_cast<float>(vm, args[1]);
float x2 = pkpy::py_cast<float>(vm, args[2]);
float y2 = pkpy::py_cast<float>(vm, args[3]);
float paletteIndex = pkpy::py_cast<float>(vm, args[4]);
this->Line(x1, y1, x2, y2, paletteIndex);
return vm->None;
});
vm->bind(vm->builtins, "text(t: string, x: int, y: int, color: int)", [this](pkpy::VM* vm, pkpy::ArgsView args){ vm->bind(vm->builtins, "text(t: string, x: int, y: int, color: int)", [this](pkpy::VM* vm, pkpy::ArgsView args){
pkpy::PyObject* func_str = vm->builtins->attr("str"); pkpy::PyObject* func_str = vm->builtins->attr("str");
pkpy::PyObject* result = vm->call(func_str, args[0]); pkpy::PyObject* result = vm->call(func_str, args[0]);
@ -279,6 +243,7 @@ void Graphics::Clear(int paletteIndex) {
void Graphics::Pixel(int x, int y, int paletteIndex) { void Graphics::Pixel(int x, int y, int paletteIndex) {
paletteIndex = Clamp(paletteIndex, 0, m_paletteByID.size() - 1); paletteIndex = Clamp(paletteIndex, 0, m_paletteByID.size() - 1);
if(x < 0 || y < 0 || x >= m_screenWidth || y >= m_screenHeight) return; if(x < 0 || y < 0 || x >= m_screenWidth || y >= m_screenHeight) return;
m_virtualScreenColorBuffer[y * m_screenWidth + x] = paletteIndex; m_virtualScreenColorBuffer[y * m_screenWidth + x] = paletteIndex;
} }
@ -424,24 +389,14 @@ void Graphics::RectBorder(int x, int y, int width, int height, int paletteIndex)
} }
void Graphics::Text(const std::string& s, int x, int y, int paletteIndex) { void Graphics::Text(const std::string& s, int x, int y, int paletteIndex) {
int currentX = 0;
int currentY = y;
for (int i = 0; i < s.size(); ++i) { for (int i = 0; i < s.size(); ++i) {
char c = s[i]; char c = s[i];
// Handle new lines std::string bitData = m_currentFont->GetCharData((int)c);
if(c != '\n') { for (int j = 0; j < bitData.size(); ++j) {
std::string bitData = m_currentFont->GetCharData((int) c); if(bitData[j] == '1')
for (int j = 0; j < bitData.size(); ++j) { Pixel(x + (j % m_currentFont->GetWidth()) + ((m_currentFont->GetWidth() + 1) * i), y + (j / m_currentFont->GetWidth()), paletteIndex);
if (bitData[j] == '1'){
Pixel(x + (j % m_currentFont->GetWidth()) + ((m_currentFont->GetWidth() + 1) * currentX),currentY + (j / m_currentFont->GetWidth()), paletteIndex);
}
}
currentX++;
}else{
currentX = 0;
currentY += m_currentFont->GetHeight() + 1;
} }
} }
} }

View File

@ -58,12 +58,6 @@ void Pycron::StartGameLoop() {
m_stateManager->OnKeyPressed(key); m_stateManager->OnKeyPressed(key);
} }
} }
for (int button = MouseButton::MOUSE_BUTTON_LEFT; button < MouseButton::MOUSE_BUTTON_BACK; ++button) {
if(IsMouseButtonPressed(button)){
m_stateManager->OnMousePressed(button);
}
}
} }
} }
@ -71,7 +65,6 @@ void Pycron::bindMethods() {
m_vm->bind(m_vm->builtins, "rnd(min: float, max: float) -> int", getRandomNumber); m_vm->bind(m_vm->builtins, "rnd(min: float, max: float) -> int", getRandomNumber);
m_vm->bind(m_vm->builtins, "sin(num: float) -> float", getSin); m_vm->bind(m_vm->builtins, "sin(num: float) -> float", getSin);
m_vm->bind(m_vm->builtins, "cos(num: float) -> float", getCos); m_vm->bind(m_vm->builtins, "cos(num: float) -> float", getCos);
m_vm->bind(m_vm->builtins, "tan(num: float) -> float", getTan);
m_vm->bind(m_vm->builtins, "fps() -> int", getFPS); m_vm->bind(m_vm->builtins, "fps() -> int", getFPS);
m_vm->bind(m_vm->builtins, "keyp(keycode: int) -> bool", getKeyPressed); m_vm->bind(m_vm->builtins, "keyp(keycode: int) -> bool", getKeyPressed);
m_vm->bind(m_vm->builtins, "key(keycode: int) -> bool", getKeyDown); m_vm->bind(m_vm->builtins, "key(keycode: int) -> bool", getKeyDown);
@ -138,11 +131,6 @@ pkpy::PyObject* Pycron::getCos(pkpy::VM* vm, pkpy::ArgsView args) {
return pkpy::py_var(vm, cos(num)); return pkpy::py_var(vm, cos(num));
} }
pkpy::PyObject* Pycron::getTan(pkpy::VM* vm, pkpy::ArgsView args) {
auto num = pkpy::py_cast<double>(vm, args[0]);
return pkpy::py_var(vm, tan(num));
}
pkpy::PyObject* Pycron::getFPS(pkpy::VM* vm, pkpy::ArgsView args) { pkpy::PyObject* Pycron::getFPS(pkpy::VM* vm, pkpy::ArgsView args) {
return pkpy::py_var(vm, GetFPS()); return pkpy::py_var(vm, GetFPS());
} }

View File

@ -36,7 +36,6 @@ public:
static pkpy::PyObject* getRandomNumber(pkpy::VM* vm, pkpy::ArgsView args); static pkpy::PyObject* getRandomNumber(pkpy::VM* vm, pkpy::ArgsView args);
static pkpy::PyObject* getSin(pkpy::VM* vm, pkpy::ArgsView args); static pkpy::PyObject* getSin(pkpy::VM* vm, pkpy::ArgsView args);
static pkpy::PyObject* getCos(pkpy::VM* vm, pkpy::ArgsView args); static pkpy::PyObject* getCos(pkpy::VM* vm, pkpy::ArgsView args);
static pkpy::PyObject* getTan(pkpy::VM* vm, pkpy::ArgsView args);
static pkpy::PyObject* getFPS(pkpy::VM* vm, pkpy::ArgsView args); static pkpy::PyObject* getFPS(pkpy::VM* vm, pkpy::ArgsView args);
static pkpy::PyObject* getKeyPressed(pkpy::VM* vm, pkpy::ArgsView args); static pkpy::PyObject* getKeyPressed(pkpy::VM* vm, pkpy::ArgsView args);
static pkpy::PyObject* getKeyDown(pkpy::VM* vm, pkpy::ArgsView args); static pkpy::PyObject* getKeyDown(pkpy::VM* vm, pkpy::ArgsView args);

View File

@ -13,6 +13,5 @@ public:
virtual void OnExit() = 0; virtual void OnExit() = 0;
virtual void OnKeyPressed(int key) = 0; virtual void OnKeyPressed(int key) = 0;
virtual void OnCharPressed(char character) = 0; virtual void OnCharPressed(char character) = 0;
virtual void OnMousePressed(int button) = 0;
}; };

View File

@ -15,6 +15,7 @@ StateManager::~StateManager() {
m_currentState = nullptr; m_currentState = nullptr;
delete m_gameState; delete m_gameState;
delete m_editorState; delete m_editorState;
delete m_graphics;
} }
@ -30,9 +31,13 @@ void StateManager::ChangeState(StateManager::StateType state) {
} }
if(m_currentState){ if(m_currentState){
m_currentState->OnEnter(); if(m_currentState == m_gameState){
if(m_currentState == m_gameState && m_gameState->m_errorThrown){ m_currentState->OnEnter();
m_pycron->m_graphics->Text(m_gameState->m_previousError, 2, 2, 4); if(m_gameState->m_errorThrown){
m_pycron->m_graphics->Text(m_gameState->m_previousError, 2, 2, 59);
}
}else{
m_currentState->OnEnter();
} }
} }
} }
@ -48,8 +53,13 @@ void StateManager::Draw() {
} }
if(m_currentState){ if(m_currentState){
if(m_currentState == m_gameState && m_gameState->m_errorThrown){ if(m_currentState == m_gameState){
m_pycron->m_graphics->Text(m_gameState->m_previousError, 2, 2, 4); if(m_gameState->m_errorThrown){
m_pycron->m_graphics->Text(m_gameState->m_previousError, 2, 2, 59);
}
else{
m_currentState->Draw();
}
} }
else{ else{
m_currentState->Draw(); m_currentState->Draw();
@ -65,7 +75,3 @@ void StateManager::OnCharPressed(char c) {
m_currentState->OnCharPressed(c); m_currentState->OnCharPressed(c);
} }
void StateManager::OnMousePressed(int button) {
m_currentState->OnMousePressed(button);
}

View File

@ -33,7 +33,6 @@ public:
void OnKeyPressed(int key); void OnKeyPressed(int key);
void OnCharPressed(char c); void OnCharPressed(char c);
void OnMousePressed(int button);
void RequestLoadGame(); void RequestLoadGame();
void RequestRunGame(); void RequestRunGame();

View File

@ -7,27 +7,23 @@
#include <algorithm> #include <algorithm>
#include <raylib.h> #include <raylib.h>
#include "EditorState.h" #include "EditorState.h"
#include <math.h>
#include "../../Utilities.h"
EditorState::EditorState(pkpy::VM *vm, Graphics *graphics) : m_vm(vm), m_graphics(graphics){ EditorState::EditorState(pkpy::VM *vm, Graphics *graphics) : m_vm(vm), m_graphics(graphics){
m_pythonTokenizer = new PythonTokenizer(); m_pythonTokenizer = new PythonTokenizer();
std::string randomSource = Pycron::loadFileToString("../python/threeD.py"); Token a(TokenType::Keyword, "Test");
//randomSource = Pycron::loadFileToString("../src/States/Editor/EditorState.cpp");
std::string randomSource = Pycron::loadFileToString("../python/triangles.py");
m_editorFrame = m_graphics->loadImage("../resources/EditorFrame.png"); m_editorFrame = m_graphics->loadImage("../resources/EditorFrame.png");
m_LineNumberDetailLeft = m_graphics->loadImage("../resources/LineNumberDetailLeft.png");
m_LineNumberDetailCenter = m_graphics->loadImage("../resources/LineNumberDetailCenter.png");
m_LineNumberDetailRight = m_graphics->loadImage("../resources/LineNumberDetailRight.png");
m_baseBackgroundColor = 56; m_baseBackgroundColor = 56;
m_shadowColor = 28; m_shadowColor = 28;
m_baseTextColor = 42; m_baseTextColor = 42;
m_lineNumberBackgroundColor = 57; m_lineNumberBackgroundColor = 57;
m_lineNumberTextColor = 7; m_lineNumberTextColor = 6;
m_unknownTextColor = 4; m_unknownTextColor = 4;
m_identifierTextColor = 63; m_identifierTextColor = 63;
m_keywordTextColor = 31; m_keywordTextColor = 31;
@ -53,9 +49,6 @@ EditorState::EditorState(pkpy::VM *vm, Graphics *graphics) : m_vm(vm), m_graphic
m_textWindowXOffset = 26; m_textWindowXOffset = 26;
m_textWindowYOffset = 20; m_textWindowYOffset = 20;
m_lineNumberWindowXOffset = 3;
m_lineNumberWindowYOffset = 20;
m_textWindowWidth = 330; m_textWindowWidth = 330;
m_textWindowHeight = 168; m_textWindowHeight = 168;
@ -64,12 +57,15 @@ EditorState::EditorState(pkpy::VM *vm, Graphics *graphics) : m_vm(vm), m_graphic
m_scrollX = 0; m_scrollX = 0;
m_scrollY = 0; m_scrollY = 0;
m_lastFurthestColumn = 0;
m_cursorBlinkTimer = 0; m_cursorBlinkTimer = 0;
m_cursorBlinkInterval = 0.5; m_cursorBlinkInterval = 0.5;
std::cout << (int)m_charWidth << "!\n";
m_width = (int)(m_textBounds->width / m_charWidth); m_width = (int)(m_textBounds->width / m_charWidth);
std::cout << m_textBounds->width << " : " << (int)m_charWidth << " = " << m_width;
m_height = (int)(m_textBounds->height / m_charHeight); m_height = (int)(m_textBounds->height / m_charHeight);
m_characterBuffer = std::vector<char>(m_width * m_height); m_characterBuffer = std::vector<char>(m_width * m_height);
@ -97,11 +93,12 @@ void EditorState::Draw() {
if(m_dirty){ if(m_dirty){
Clear(); Clear();
m_dirty = false; m_dirty = false;
int cursorPos = m_scrollY + m_cursorY;
for (int i = 0; i < m_height; ++i) { for (int i = 0; i < m_height; ++i) {
// if(i > m_text.size() - 1) break;
// Line numbers TODO: maybe not have this as part of the buffer, instead as a custom bar. (Allows for more custom functionality such as bookmarks)
// std::string lineNumber = std::to_string(std::abs(m_cursorY - i));
// if(i == m_cursorY) lineNumber = std::to_string(m_cursorY);
int index = i + m_scrollY; int index = i + m_scrollY;
if(index > m_text.size() - 1) break; if(index > m_text.size() - 1) break;
@ -110,23 +107,6 @@ void EditorState::Draw() {
auto tokens = m_pythonTokenizer->tokenizeLine(m_text[index]); auto tokens = m_pythonTokenizer->tokenizeLine(m_text[index]);
int currentPos = 0; int currentPos = 0;
if(index == cursorPos){
std::string lineNumber = std::to_string(cursorPos);
int offset = std::max((int)lineNumber.size() - 3, 0);
bool collision = false;
for (int j = 0; j < offset; ++j) {
if(m_text[index].size() < offset) break;
if(m_text[index][j] != ' '){
collision = true;
break;
}
}
if(!collision) offset = 0;
currentPos = offset;
}
for (int j = 0; j < tokens.size(); ++j) { for (int j = 0; j < tokens.size(); ++j) {
int color = m_baseTextColor; int color = m_baseTextColor;
TokenType type = tokens[j].type; TokenType type = tokens[j].type;
@ -169,25 +149,9 @@ void EditorState::Draw() {
// Draw the cursor // Draw the cursor
if(m_cursorVisible) { if(m_cursorVisible) {
int currentLine = m_scrollY + m_cursorY; int x = m_cursorX * m_charWidth + m_textBounds->x;
std::string lineNumber = std::to_string(currentLine);
int offset = std::max((int)lineNumber.size() - 3, 0);
bool collision = false;
for (int i = 0; i < offset; ++i) {
if(m_text[currentLine].size() < offset) break;
if(m_text[currentLine][i] != ' '){
collision = true;
break;
}
}
if(!collision) offset = 0;
int x = (m_cursorX + offset) * m_charWidth + m_textBounds->x;
int y = m_cursorY * m_charHeight + m_textBounds->y; int y = m_cursorY * m_charHeight + m_textBounds->y;
int index = m_cursorY * m_width + m_cursorX;
int index = m_cursorY * m_width + (m_cursorX + offset);
if(m_drawShadows) m_graphics->Rect(x, y, m_charWidth + 1, m_charHeight + 1, m_shadowColor); if(m_drawShadows) m_graphics->Rect(x, y, m_charWidth + 1, m_charHeight + 1, m_shadowColor);
m_graphics->Rect(x - 1, y - 1, m_charWidth + 1, m_charHeight + 1, m_foregroundIndexBuffer[index]); m_graphics->Rect(x - 1, y - 1, m_charWidth + 1, m_charHeight + 1, m_foregroundIndexBuffer[index]);
@ -201,54 +165,10 @@ void EditorState::Draw() {
m_cursorVisible = !m_cursorVisible; m_cursorVisible = !m_cursorVisible;
m_cursorBlinkTimer = 0.0; m_cursorBlinkTimer = 0.0;
} }
// Editor frame image // Editor frame image
m_graphics->Img(m_editorFrame, 0, 0); m_graphics->Img(m_editorFrame, 0, 0);
// Line Numbers
for (int i = 0; i < m_height; ++i) {
if(i + m_scrollY >= m_text.size()) return;
int lineNum = i + m_scrollY + 1;
std::string lineNumber = std::to_string(lineNum);
int delta = std::max(0, 3 - (int)lineNumber.size());
lineNumber = std::string(delta, ' ') + lineNumber;
lineNumber = lineNumber.substr(lineNumber.size() - 3);
int highlight = i == m_cursorY ? m_lineNumberTextColor : m_commentTextColor;
if(lineNum > 999){
lineNumber[0] = ' ';
int dotX = m_lineNumberWindowXOffset;
int dotY = m_lineNumberWindowYOffset + (i * m_charHeight) + m_graphics->GetCurrentFontHeight() - 1;
m_graphics->Pixel(dotX, dotY, highlight);
m_graphics->Pixel(dotX + 2, dotY, highlight);
m_graphics->Pixel(dotX + 4, dotY, highlight);
}
m_graphics->Text(lineNumber, m_lineNumberWindowXOffset, m_lineNumberWindowYOffset + (i * m_charHeight), highlight);
}
// Line Number Detail
if(m_scrollY + 1 + m_cursorY > 999){
int lineNum = m_scrollY + 1 + m_cursorY;
std::string lineNumber = std::to_string(lineNum);
int lineNumberDetailXOffset = 3;
int lineNumberDetailYOffset = 3;
int yOffset = m_lineNumberWindowYOffset - lineNumberDetailYOffset + (m_cursorY * (m_graphics->GetCurrentFontHeight() + 1));
m_graphics->Img(m_LineNumberDetailLeft, m_lineNumberWindowXOffset - lineNumberDetailXOffset, yOffset);
for (int i = 0; i < lineNumber.size(); ++i) {
int offset = m_lineNumberWindowXOffset + (i * 6);
m_graphics->Img(m_LineNumberDetailCenter, offset, yOffset);
}
m_graphics->Img(m_LineNumberDetailRight, m_lineNumberWindowXOffset + (lineNumber.size() * 6), yOffset);
m_graphics->Text(lineNumber, m_lineNumberWindowXOffset, yOffset + lineNumberDetailYOffset, m_lineNumberTextColor);
}
//m_graphics->RectBorder(m_textBounds->x, m_textBounds->y, m_textBounds->width, m_textBounds->height, 23); //m_graphics->RectBorder(m_textBounds->x, m_textBounds->y, m_textBounds->width, m_textBounds->height, 23);
} }
@ -262,116 +182,39 @@ void EditorState::OnExit() {
} }
void EditorState::OnKeyPressed(int key) { void EditorState::OnKeyPressed(int key) {
if(key == KEY_LEFT && m_cursorX > 0){
m_cursorX--;
if (key == KEY_LEFT) {
if (m_cursorX > 0) {
m_cursorX--;
m_lastFurthestColumn = m_cursorX;
} else {
if( m_cursorY > 0)
{
m_cursorY--;
}
else
{
m_scrollY--;
}
if(m_scrollY < 0){
m_scrollY = 0;
}else{
m_cursorX = (int)m_text[m_scrollY + m_cursorY].size();
m_lastFurthestColumn = m_cursorX;
};
}
} }
if (key == KEY_RIGHT) { if(key == KEY_RIGHT && m_cursorX < m_width - 1){
if (m_cursorX < std::min(m_width - 1, (int) m_text[m_scrollY + m_cursorY].size())) { m_cursorX++;
m_cursorX++;
m_lastFurthestColumn = m_cursorX;
} else {
m_cursorX = 0;
m_lastFurthestColumn = m_cursorX;
if(m_cursorY < std::min(m_height - 1, static_cast<int>(m_text.size()) - 1))
{
m_cursorY++;
}
else
{
m_scrollY++;
}
if(m_scrollY + m_height > m_text.size() - 1){
m_scrollY = m_text.size() - 1 - m_height;
}
if(m_scrollY < 0){
m_scrollY = 0;
}
}
} }
if(key == KEY_UP){ if(key == KEY_UP){
if(IsKeyDown(KEY_LEFT_SHIFT)){ if( m_cursorY > 0)
m_scrollY -= m_height; {
bool success = m_scrollY > 0; m_cursorY--;
if(!success && m_cursorY > 0) m_cursorY--; }
}else{ else
if( m_cursorY > 0) {
{ if(m_scrollY > 0)
m_cursorY--;
}
else
{ {
m_scrollY--; m_scrollY--;
} }
} }
if(m_scrollY < 0){
m_scrollY = 0;
}
} }
if(key == KEY_DOWN ) if(key == KEY_DOWN )
{ {
if(IsKeyDown(KEY_LEFT_SHIFT)){ if(m_cursorY < std::min(m_height - 1, static_cast<int>(m_text.size()) - 1))
m_scrollY += m_height; {
bool success = m_scrollY + m_height <= m_text.size() - 1; m_cursorY++;
if(!success && m_cursorY < std::min(m_height - 1, static_cast<int>(m_text.size()) - 1)) m_cursorY++; }
}else{ else
if(m_cursorY < std::min(m_height - 1, static_cast<int>(m_text.size()) - 1)) {
{ if(m_scrollY + m_height < m_text.size())
m_cursorY++;
}
else
{
m_scrollY++; m_scrollY++;
}
}
if(m_scrollY + m_height > m_text.size() - 1){
m_scrollY = m_text.size() - 1 - m_height;
}
if(m_scrollY < 0){
m_scrollY = 0;
} }
} }
int currentLineLength = (int)m_text[m_scrollY + m_cursorY].size();
if(currentLineLength <= m_cursorX){
m_cursorX = currentLineLength;
}else{
m_cursorX = std::min(m_lastFurthestColumn, currentLineLength);
};
m_cursorVisible = true; m_cursorVisible = true;
m_cursorBlinkTimer = 0; m_cursorBlinkTimer = 0;
@ -385,31 +228,6 @@ void EditorState::OnCharPressed(char character){
} }
void EditorState::OnMousePressed(int button) {
int x = m_graphics->mouseX();
int y = m_graphics->mouseY();
if(Utilities::RectContainsPoint(m_textBounds, x, y)){
x -= m_textWindowXOffset;
y -= m_textWindowYOffset;
x /= m_charWidth;
y /= m_charHeight;
m_cursorY = std::min((int)m_text.size() - 1, y);
m_cursorX = std::min((int)m_text[m_cursorY + m_scrollY].size(), x);
m_lastFurthestColumn = m_cursorX;
m_cursorVisible = true;
m_cursorBlinkTimer = 0;
m_dirty = true;
}
}
void EditorState::Clear() { void EditorState::Clear() {
for (int i = 0; i < m_width * m_height; ++i) { for (int i = 0; i < m_width * m_height; ++i) {
m_characterBuffer[i] = ' '; m_characterBuffer[i] = ' ';
@ -418,7 +236,6 @@ void EditorState::Clear() {
} }
} }
void EditorState::Text(const std::string &text, int x, int y, int fg, int bg) { void EditorState::Text(const std::string &text, int x, int y, int fg, int bg) {
for (int i = 0; i < text.size(); ++i) { for (int i = 0; i < text.size(); ++i) {
int charX = x + i; int charX = x + i;
@ -436,6 +253,7 @@ void EditorState::Text(const std::string &text, int x, int y, int fg, int bg) {
} }
} }
void EditorState::LoadStringToBuffer(const std::string &text) { void EditorState::LoadStringToBuffer(const std::string &text) {
m_text.clear(); m_text.clear();

View File

@ -20,7 +20,6 @@ public:
void OnExit() override; void OnExit() override;
void OnKeyPressed(int key) override; void OnKeyPressed(int key) override;
void OnCharPressed(char character) override; void OnCharPressed(char character) override;
void OnMousePressed(int button) override;
private: private:
pkpy::VM* m_vm; pkpy::VM* m_vm;
@ -30,10 +29,6 @@ private:
// Editor images // Editor images
PycronImage* m_editorFrame; PycronImage* m_editorFrame;
PycronImage* m_LineNumberDetailLeft;
PycronImage* m_LineNumberDetailCenter;
PycronImage* m_LineNumberDetailRight;
// Size of the character in pixels // Size of the character in pixels
uint8_t m_charWidth, m_charHeight; uint8_t m_charWidth, m_charHeight;
@ -76,9 +71,6 @@ private:
int m_textWindowXOffset; int m_textWindowXOffset;
int m_textWindowYOffset; int m_textWindowYOffset;
int m_lineNumberWindowXOffset;
int m_lineNumberWindowYOffset;
int m_textWindowWidth; int m_textWindowWidth;
int m_textWindowHeight; int m_textWindowHeight;
@ -87,8 +79,6 @@ private:
int m_scrollX; int m_scrollX;
int m_scrollY; int m_scrollY;
int m_lastFurthestColumn;
bool m_dirty; bool m_dirty;
bool m_drawShadows; bool m_drawShadows;

View File

@ -11,7 +11,6 @@
GameState::GameState(pkpy::VM* vm, Graphics* graphics) :m_vm(vm), m_graphics(graphics){ GameState::GameState(pkpy::VM* vm, Graphics* graphics) :m_vm(vm), m_graphics(graphics){
m_updateFunction = nullptr; m_updateFunction = nullptr;
m_previousError = ""; m_previousError = "";
} }
void GameState::Draw() { void GameState::Draw() {
@ -27,17 +26,11 @@ void GameState::Draw() {
} }
void GameState::OnEnter() { void GameState::OnEnter() {
m_graphics->Clear(0);
PreProcessScripts(); PreProcessScripts();
} }
void GameState::OnExit() { void GameState::OnExit() {
for(const auto& pair : m_vm->_lazy_modules){
m_vm->_modules.del(pair.first);
}
m_vm->_lazy_modules.clear(); m_vm->_lazy_modules.clear();
m_updateFunction = m_vm->None; m_updateFunction = m_vm->None;
} }
@ -56,6 +49,9 @@ void GameState::PreProcessScripts() {
pkpy::CodeObject_ code = m_vm->compile(main, MAIN_FILE, pkpy::EXEC_MODE, false); pkpy::CodeObject_ code = m_vm->compile(main, MAIN_FILE, pkpy::EXEC_MODE, false);
m_vm->_exec(code, m_vm->_main); m_vm->_exec(code, m_vm->_main);
m_updateFunction = m_vm->eval("update"); m_updateFunction = m_vm->eval("update");
// if(m_updateFunction == nullptr){
// m_previousError = "";
// }
}catch(pkpy::Exception e){ }catch(pkpy::Exception e){
m_previousError = e.summary(); m_previousError = e.summary();
std::cout << e.summary() << "\n"; std::cout << e.summary() << "\n";
@ -86,12 +82,9 @@ std::unordered_map<std::string, std::string> GameState::readPythonFiles(const st
} }
void GameState::loadPythonModules(std::unordered_map<std::string, std::string> &fileContents) { void GameState::loadPythonModules(std::unordered_map<std::string, std::string> &fileContents) {
m_vm->_lazy_modules.clear();
for(const auto& pair : fileContents){ for(const auto& pair : fileContents){
try{ try{
if(pair.first != MAIN_FILE){ if(pair.first != MAIN_FILE){
// parse out file name as module ex: test.py is test
size_t pos = pair.first.find_last_of("."); size_t pos = pair.first.find_last_of(".");
if(pos == std::string::npos || pos == 0){ if(pos == std::string::npos || pos == 0){
throw pkpy::Exception("Invalid file name"); throw pkpy::Exception("Invalid file name");
@ -109,7 +102,3 @@ void GameState::OnCharPressed(char character) {
} }
void GameState::OnMousePressed(int button) {
}

View File

@ -16,7 +16,6 @@ public:
void OnExit() override; void OnExit() override;
void OnKeyPressed(int key) override; void OnKeyPressed(int key) override;
void OnCharPressed(char character) override; void OnCharPressed(char character) override;
void OnMousePressed(int button) override;
private: private:

View File

@ -3,7 +3,6 @@
// //
#include "Utilities.h" #include "Utilities.h"
namespace Utilities { namespace Utilities {
Color ColorFromHex(int hexValue) { Color ColorFromHex(int hexValue) {
// Extract red, green, blue, and alpha components from the hexadecimal value // Extract red, green, blue, and alpha components from the hexadecimal value
@ -19,8 +18,4 @@ namespace Utilities {
// Create and return the color // Create and return the color
return ColorFromNormalized({ rf, gf, bf, 1.0f }); // Alpha is set to 1.0 (fully opaque) return ColorFromNormalized({ rf, gf, bf, 1.0f }); // Alpha is set to 1.0 (fully opaque)
} }
bool RectContainsPoint(pycron::Rectangle* r, int x, int y){
return x >= r->x && x <= r->x + r->width && y >= r->y && y <= r->y + r->height;
}
} }

View File

@ -1,10 +1,7 @@
#pragma once #pragma once
#include "raylib.h" #include "raylib.h"
#include "Utilities.h"
#include "Graphics/Rectangle.h"
namespace Utilities { namespace Utilities {
Color ColorFromHex(int hexValue); Color ColorFromHex(int hexValue);
bool RectContainsPoint(pycron::Rectangle* r, int x, int y);
} }