Compare commits
No commits in common. "8bb88afa6b784e1a26c0ba0e92bbaa142b321005" and "efc9b0fe5eed788daaa3401ea79271687bee6e49" have entirely different histories.
8bb88afa6b
...
efc9b0fe5e
Binary file not shown.
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -1,9 +1,6 @@
|
||||
from scene import Scene
|
||||
from particles import Particles
|
||||
from triangles import Triangles
|
||||
from squares import Squares
|
||||
from blobs import Blobs
|
||||
from threeD import ThreeD
|
||||
|
||||
# Palette class (inherits from scene)
|
||||
class Palette(Scene):
|
||||
@ -20,7 +17,7 @@ class Palette(Scene):
|
||||
|
||||
for i 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)
|
||||
|
||||
class RGBTest(Scene):
|
||||
@ -29,9 +26,11 @@ class RGBTest(Scene):
|
||||
self.title = "RGB To Palette"
|
||||
|
||||
|
||||
scenes = [ ThreeD(), Particles(), Squares(), Triangles(), Palette(), Blobs()]
|
||||
scenes = [Particles(), Triangles(), Palette()]
|
||||
current_scene = 0
|
||||
|
||||
|
||||
|
||||
KEY_T = 84
|
||||
|
||||
switch = False
|
||||
@ -52,5 +51,9 @@ def update():
|
||||
scenes[current_scene].update()
|
||||
scenes[current_scene].draw()
|
||||
|
||||
text("T to change scene", 255, 1,31)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
|
||||
|
||||
|
||||
@ -151,3 +151,7 @@ class Particles(Scene):
|
||||
# triangle(mouseX, mouseY, x2, y2, x3, y3, 9)
|
||||
|
||||
# lineTri(mouseX, mouseY, x2, y2, x3, y3, 8)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
165
python/threeD.py
165
python/threeD.py
@ -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
|
||||
|
||||
@ -77,7 +77,7 @@ class Triangles(Scene):
|
||||
y = rnd(0, height)
|
||||
c = 0
|
||||
if(rnd(0,9) < 5):
|
||||
c = getPixel(x -3 ,y-3)
|
||||
c = get_pixel(x -3 ,y-3)
|
||||
else:
|
||||
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 |
@ -64,23 +64,7 @@ void Graphics::draw(StateManager* stateManager) {
|
||||
void Graphics::copyBufferToGPU() {
|
||||
Color* pixel_data = LoadImageColors(m_virtualScreenImageBuffer);
|
||||
for (int i = 0; i < m_screenWidth * m_screenHeight; ++i) {
|
||||
uint32_t rgb = 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);
|
||||
pixel_data[i] = GetColor(m_paletteByID[m_virtualScreenColorBuffer[i]]);
|
||||
}
|
||||
UpdateTexture(m_virtualScreen.texture, pixel_data);
|
||||
UnloadImageColors(pixel_data);
|
||||
@ -197,7 +181,7 @@ void Graphics::bindMethods(pkpy::VM *vm) {
|
||||
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 y = pkpy::py_cast<float>(vm, args[1]);
|
||||
|
||||
@ -213,7 +197,7 @@ void Graphics::bindMethods(pkpy::VM *vm) {
|
||||
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 y = pkpy::py_cast<float>(vm, args[1]);
|
||||
float width = pkpy::py_cast<float>(vm, args[2]);
|
||||
@ -223,16 +207,6 @@ void Graphics::bindMethods(pkpy::VM *vm) {
|
||||
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){
|
||||
float x1 = pkpy::py_cast<float>(vm, args[0]);
|
||||
float y1 = pkpy::py_cast<float>(vm, args[1]);
|
||||
@ -245,16 +219,6 @@ void Graphics::bindMethods(pkpy::VM *vm) {
|
||||
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){
|
||||
pkpy::PyObject* func_str = vm->builtins->attr("str");
|
||||
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) {
|
||||
paletteIndex = Clamp(paletteIndex, 0, m_paletteByID.size() - 1);
|
||||
if(x < 0 || y < 0 || x >= m_screenWidth || y >= m_screenHeight) return;
|
||||
|
||||
m_virtualScreenColorBuffer[y * m_screenWidth + x] = paletteIndex;
|
||||
}
|
||||
|
||||
@ -424,25 +389,15 @@ 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) {
|
||||
int currentX = 0;
|
||||
int currentY = y;
|
||||
|
||||
for (int i = 0; i < s.size(); ++i) {
|
||||
char c = s[i];
|
||||
// Handle new lines
|
||||
if(c != '\n') {
|
||||
std::string bitData = m_currentFont->GetCharData((int) c);
|
||||
std::string bitData = m_currentFont->GetCharData((int)c);
|
||||
for (int j = 0; j < bitData.size(); ++j) {
|
||||
if (bitData[j] == '1'){
|
||||
Pixel(x + (j % m_currentFont->GetWidth()) + ((m_currentFont->GetWidth() + 1) * currentX),currentY + (j / m_currentFont->GetWidth()), paletteIndex);
|
||||
}
|
||||
if(bitData[j] == '1')
|
||||
Pixel(x + (j % m_currentFont->GetWidth()) + ((m_currentFont->GetWidth() + 1) * i), y + (j / m_currentFont->GetWidth()), paletteIndex);
|
||||
|
||||
}
|
||||
currentX++;
|
||||
}else{
|
||||
currentX = 0;
|
||||
currentY += m_currentFont->GetHeight() + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -58,12 +58,6 @@ void Pycron::StartGameLoop() {
|
||||
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, "sin(num: float) -> float", getSin);
|
||||
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, "keyp(keycode: int) -> bool", getKeyPressed);
|
||||
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));
|
||||
}
|
||||
|
||||
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) {
|
||||
return pkpy::py_var(vm, GetFPS());
|
||||
}
|
||||
|
||||
@ -36,7 +36,6 @@ public:
|
||||
static pkpy::PyObject* getRandomNumber(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* getTan(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* getKeyDown(pkpy::VM* vm, pkpy::ArgsView args);
|
||||
|
||||
@ -13,6 +13,5 @@ public:
|
||||
virtual void OnExit() = 0;
|
||||
virtual void OnKeyPressed(int key) = 0;
|
||||
virtual void OnCharPressed(char character) = 0;
|
||||
virtual void OnMousePressed(int button) = 0;
|
||||
|
||||
};
|
||||
|
||||
@ -15,6 +15,7 @@ StateManager::~StateManager() {
|
||||
m_currentState = nullptr;
|
||||
delete m_gameState;
|
||||
delete m_editorState;
|
||||
delete m_graphics;
|
||||
}
|
||||
|
||||
|
||||
@ -30,9 +31,13 @@ void StateManager::ChangeState(StateManager::StateType state) {
|
||||
}
|
||||
|
||||
if(m_currentState){
|
||||
if(m_currentState == m_gameState){
|
||||
m_currentState->OnEnter();
|
||||
if(m_gameState->m_errorThrown){
|
||||
m_pycron->m_graphics->Text(m_gameState->m_previousError, 2, 2, 59);
|
||||
}
|
||||
}else{
|
||||
m_currentState->OnEnter();
|
||||
if(m_currentState == m_gameState && m_gameState->m_errorThrown){
|
||||
m_pycron->m_graphics->Text(m_gameState->m_previousError, 2, 2, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -48,8 +53,13 @@ void StateManager::Draw() {
|
||||
}
|
||||
|
||||
if(m_currentState){
|
||||
if(m_currentState == m_gameState && m_gameState->m_errorThrown){
|
||||
m_pycron->m_graphics->Text(m_gameState->m_previousError, 2, 2, 4);
|
||||
if(m_currentState == m_gameState){
|
||||
if(m_gameState->m_errorThrown){
|
||||
m_pycron->m_graphics->Text(m_gameState->m_previousError, 2, 2, 59);
|
||||
}
|
||||
else{
|
||||
m_currentState->Draw();
|
||||
}
|
||||
}
|
||||
else{
|
||||
m_currentState->Draw();
|
||||
@ -65,7 +75,3 @@ void StateManager::OnCharPressed(char c) {
|
||||
m_currentState->OnCharPressed(c);
|
||||
}
|
||||
|
||||
void StateManager::OnMousePressed(int button) {
|
||||
m_currentState->OnMousePressed(button);
|
||||
}
|
||||
|
||||
|
||||
@ -33,7 +33,6 @@ public:
|
||||
|
||||
void OnKeyPressed(int key);
|
||||
void OnCharPressed(char c);
|
||||
void OnMousePressed(int button);
|
||||
|
||||
void RequestLoadGame();
|
||||
void RequestRunGame();
|
||||
|
||||
@ -7,27 +7,23 @@
|
||||
#include <algorithm>
|
||||
#include <raylib.h>
|
||||
#include "EditorState.h"
|
||||
#include <math.h>
|
||||
#include "../../Utilities.h"
|
||||
|
||||
|
||||
|
||||
EditorState::EditorState(pkpy::VM *vm, Graphics *graphics) : m_vm(vm), m_graphics(graphics){
|
||||
m_pythonTokenizer = new PythonTokenizer();
|
||||
|
||||
std::string randomSource = Pycron::loadFileToString("../python/threeD.py");
|
||||
//randomSource = Pycron::loadFileToString("../src/States/Editor/EditorState.cpp");
|
||||
Token a(TokenType::Keyword, "Test");
|
||||
|
||||
std::string randomSource = Pycron::loadFileToString("../python/triangles.py");
|
||||
|
||||
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_shadowColor = 28;
|
||||
m_baseTextColor = 42;
|
||||
m_lineNumberBackgroundColor = 57;
|
||||
m_lineNumberTextColor = 7;
|
||||
m_lineNumberTextColor = 6;
|
||||
m_unknownTextColor = 4;
|
||||
m_identifierTextColor = 63;
|
||||
m_keywordTextColor = 31;
|
||||
@ -53,9 +49,6 @@ EditorState::EditorState(pkpy::VM *vm, Graphics *graphics) : m_vm(vm), m_graphic
|
||||
m_textWindowXOffset = 26;
|
||||
m_textWindowYOffset = 20;
|
||||
|
||||
m_lineNumberWindowXOffset = 3;
|
||||
m_lineNumberWindowYOffset = 20;
|
||||
|
||||
m_textWindowWidth = 330;
|
||||
m_textWindowHeight = 168;
|
||||
|
||||
@ -64,12 +57,15 @@ EditorState::EditorState(pkpy::VM *vm, Graphics *graphics) : m_vm(vm), m_graphic
|
||||
m_scrollX = 0;
|
||||
m_scrollY = 0;
|
||||
|
||||
m_lastFurthestColumn = 0;
|
||||
|
||||
m_cursorBlinkTimer = 0;
|
||||
m_cursorBlinkInterval = 0.5;
|
||||
|
||||
|
||||
|
||||
std::cout << (int)m_charWidth << "!\n";
|
||||
|
||||
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_characterBuffer = std::vector<char>(m_width * m_height);
|
||||
@ -97,11 +93,12 @@ void EditorState::Draw() {
|
||||
if(m_dirty){
|
||||
Clear();
|
||||
m_dirty = false;
|
||||
|
||||
int cursorPos = m_scrollY + m_cursorY;
|
||||
|
||||
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;
|
||||
|
||||
if(index > m_text.size() - 1) break;
|
||||
@ -110,23 +107,6 @@ void EditorState::Draw() {
|
||||
auto tokens = m_pythonTokenizer->tokenizeLine(m_text[index]);
|
||||
|
||||
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) {
|
||||
int color = m_baseTextColor;
|
||||
TokenType type = tokens[j].type;
|
||||
@ -169,25 +149,9 @@ void EditorState::Draw() {
|
||||
|
||||
// Draw the cursor
|
||||
if(m_cursorVisible) {
|
||||
int currentLine = m_scrollY + m_cursorY;
|
||||
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 x = m_cursorX * m_charWidth + m_textBounds->x;
|
||||
int y = m_cursorY * m_charHeight + m_textBounds->y;
|
||||
|
||||
int index = m_cursorY * m_width + (m_cursorX + offset);
|
||||
int index = m_cursorY * m_width + m_cursorX;
|
||||
|
||||
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]);
|
||||
@ -201,54 +165,10 @@ void EditorState::Draw() {
|
||||
m_cursorVisible = !m_cursorVisible;
|
||||
m_cursorBlinkTimer = 0.0;
|
||||
}
|
||||
|
||||
// Editor frame image
|
||||
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);
|
||||
|
||||
}
|
||||
@ -262,116 +182,39 @@ void EditorState::OnExit() {
|
||||
}
|
||||
|
||||
void EditorState::OnKeyPressed(int key) {
|
||||
|
||||
|
||||
if (key == KEY_LEFT) {
|
||||
if (m_cursorX > 0) {
|
||||
if(key == KEY_LEFT && 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 (m_cursorX < std::min(m_width - 1, (int) m_text[m_scrollY + m_cursorY].size())) {
|
||||
if(key == KEY_RIGHT && m_cursorX < m_width - 1){
|
||||
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(IsKeyDown(KEY_LEFT_SHIFT)){
|
||||
m_scrollY -= m_height;
|
||||
bool success = m_scrollY > 0;
|
||||
if(!success && m_cursorY > 0) m_cursorY--;
|
||||
}else{
|
||||
if( m_cursorY > 0)
|
||||
{
|
||||
m_cursorY--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_scrollY > 0)
|
||||
{
|
||||
m_scrollY--;
|
||||
}
|
||||
}
|
||||
|
||||
if(m_scrollY < 0){
|
||||
m_scrollY = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(key == KEY_DOWN )
|
||||
{
|
||||
if(IsKeyDown(KEY_LEFT_SHIFT)){
|
||||
m_scrollY += m_height;
|
||||
bool success = m_scrollY + m_height <= m_text.size() - 1;
|
||||
if(!success && m_cursorY < std::min(m_height - 1, static_cast<int>(m_text.size()) - 1)) m_cursorY++;
|
||||
}else{
|
||||
if(m_cursorY < std::min(m_height - 1, static_cast<int>(m_text.size()) - 1))
|
||||
{
|
||||
m_cursorY++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_scrollY + m_height < m_text.size())
|
||||
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_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() {
|
||||
for (int i = 0; i < m_width * m_height; ++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) {
|
||||
for (int i = 0; i < text.size(); ++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) {
|
||||
m_text.clear();
|
||||
|
||||
|
||||
@ -20,7 +20,6 @@ public:
|
||||
void OnExit() override;
|
||||
void OnKeyPressed(int key) override;
|
||||
void OnCharPressed(char character) override;
|
||||
void OnMousePressed(int button) override;
|
||||
|
||||
private:
|
||||
pkpy::VM* m_vm;
|
||||
@ -30,10 +29,6 @@ private:
|
||||
// Editor images
|
||||
PycronImage* m_editorFrame;
|
||||
|
||||
PycronImage* m_LineNumberDetailLeft;
|
||||
PycronImage* m_LineNumberDetailCenter;
|
||||
PycronImage* m_LineNumberDetailRight;
|
||||
|
||||
// Size of the character in pixels
|
||||
uint8_t m_charWidth, m_charHeight;
|
||||
|
||||
@ -76,9 +71,6 @@ private:
|
||||
int m_textWindowXOffset;
|
||||
int m_textWindowYOffset;
|
||||
|
||||
int m_lineNumberWindowXOffset;
|
||||
int m_lineNumberWindowYOffset;
|
||||
|
||||
int m_textWindowWidth;
|
||||
int m_textWindowHeight;
|
||||
|
||||
@ -87,8 +79,6 @@ private:
|
||||
int m_scrollX;
|
||||
int m_scrollY;
|
||||
|
||||
int m_lastFurthestColumn;
|
||||
|
||||
bool m_dirty;
|
||||
|
||||
bool m_drawShadows;
|
||||
|
||||
@ -11,7 +11,6 @@
|
||||
GameState::GameState(pkpy::VM* vm, Graphics* graphics) :m_vm(vm), m_graphics(graphics){
|
||||
m_updateFunction = nullptr;
|
||||
m_previousError = "";
|
||||
|
||||
}
|
||||
|
||||
void GameState::Draw() {
|
||||
@ -27,17 +26,11 @@ void GameState::Draw() {
|
||||
}
|
||||
|
||||
void GameState::OnEnter() {
|
||||
m_graphics->Clear(0);
|
||||
PreProcessScripts();
|
||||
|
||||
}
|
||||
|
||||
void GameState::OnExit() {
|
||||
for(const auto& pair : m_vm->_lazy_modules){
|
||||
m_vm->_modules.del(pair.first);
|
||||
}
|
||||
m_vm->_lazy_modules.clear();
|
||||
|
||||
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);
|
||||
m_vm->_exec(code, m_vm->_main);
|
||||
m_updateFunction = m_vm->eval("update");
|
||||
// if(m_updateFunction == nullptr){
|
||||
// m_previousError = "";
|
||||
// }
|
||||
}catch(pkpy::Exception e){
|
||||
m_previousError = e.summary();
|
||||
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) {
|
||||
m_vm->_lazy_modules.clear();
|
||||
|
||||
for(const auto& pair : fileContents){
|
||||
try{
|
||||
if(pair.first != MAIN_FILE){
|
||||
// parse out file name as module ex: test.py is test
|
||||
size_t pos = pair.first.find_last_of(".");
|
||||
if(pos == std::string::npos || pos == 0){
|
||||
throw pkpy::Exception("Invalid file name");
|
||||
@ -109,7 +102,3 @@ void GameState::OnCharPressed(char character) {
|
||||
|
||||
}
|
||||
|
||||
void GameState::OnMousePressed(int button) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -16,7 +16,6 @@ public:
|
||||
void OnExit() override;
|
||||
void OnKeyPressed(int key) override;
|
||||
void OnCharPressed(char character) override;
|
||||
void OnMousePressed(int button) override;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
@ -3,7 +3,6 @@
|
||||
//
|
||||
|
||||
#include "Utilities.h"
|
||||
|
||||
namespace Utilities {
|
||||
Color ColorFromHex(int hexValue) {
|
||||
// Extract red, green, blue, and alpha components from the hexadecimal value
|
||||
@ -19,8 +18,4 @@ namespace Utilities {
|
||||
// Create and return the color
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,10 +1,7 @@
|
||||
#pragma once
|
||||
#include "raylib.h"
|
||||
#include "Utilities.h"
|
||||
#include "Graphics/Rectangle.h"
|
||||
|
||||
|
||||
namespace Utilities {
|
||||
Color ColorFromHex(int hexValue);
|
||||
bool RectContainsPoint(pycron::Rectangle* r, int x, int y);
|
||||
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user