Compare commits
10 Commits
efc9b0fe5e
...
8bb88afa6b
| Author | SHA1 | Date | |
|---|---|---|---|
| 8bb88afa6b | |||
| a76ba3ccb7 | |||
| bbb1b3dfa9 | |||
| 29e3ba208e | |||
| 611b6def6a | |||
| 028348691a | |||
| 9f04ac67ba | |||
| 5f1ed533cf | |||
| cf74541678 | |||
| 2b23a6a7f1 |
Binary file not shown.
38
python/blobs.py
Normal file
38
python/blobs.py
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
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,6 +1,9 @@
|
|||||||
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):
|
||||||
@ -17,7 +20,7 @@ class Palette(Scene):
|
|||||||
|
|
||||||
for i in range(8):
|
for i in range(8):
|
||||||
for j in range(8):
|
for j in range(8):
|
||||||
rectangle(10 + (i * 20), 10 + (j * 20), 18, 18, (j * 8 + i))
|
rect(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):
|
||||||
@ -26,11 +29,9 @@ class RGBTest(Scene):
|
|||||||
self.title = "RGB To Palette"
|
self.title = "RGB To Palette"
|
||||||
|
|
||||||
|
|
||||||
scenes = [Particles(), Triangles(), Palette()]
|
scenes = [ ThreeD(), Particles(), Squares(), Triangles(), Palette(), Blobs()]
|
||||||
current_scene = 0
|
current_scene = 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
KEY_T = 84
|
KEY_T = 84
|
||||||
|
|
||||||
switch = False
|
switch = False
|
||||||
@ -51,9 +52,5 @@ 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)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
29
python/mechanical.py
Normal file
29
python/mechanical.py
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
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,7 +151,3 @@ 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)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
25
python/squares.py
Normal file
25
python/squares.py
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
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
Normal file
165
python/threeD.py
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
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)
|
y = rnd(0, height)
|
||||||
c = 0
|
c = 0
|
||||||
if(rnd(0,9) < 5):
|
if(rnd(0,9) < 5):
|
||||||
c = get_pixel(x -3 ,y-3)
|
c = getPixel(x -3 ,y-3)
|
||||||
else:
|
else:
|
||||||
c = 0
|
c = 0
|
||||||
|
|
||||||
|
|||||||
BIN
resources/LineNumberDetailCenter.png
Normal file
BIN
resources/LineNumberDetailCenter.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 91 B |
BIN
resources/LineNumberDetailLeft.png
Normal file
BIN
resources/LineNumberDetailLeft.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 117 B |
BIN
resources/LineNumberDetailRight.png
Normal file
BIN
resources/LineNumberDetailRight.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 114 B |
@ -64,7 +64,23 @@ 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) {
|
||||||
pixel_data[i] = GetColor(m_paletteByID[m_virtualScreenColorBuffer[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);
|
||||||
}
|
}
|
||||||
UpdateTexture(m_virtualScreen.texture, pixel_data);
|
UpdateTexture(m_virtualScreen.texture, pixel_data);
|
||||||
UnloadImageColors(pixel_data);
|
UnloadImageColors(pixel_data);
|
||||||
@ -181,7 +197,7 @@ void Graphics::bindMethods(pkpy::VM *vm) {
|
|||||||
return vm->None;
|
return vm->None;
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bind(vm->builtins, "get_pixel(x: int, y: int) -> int", [this](pkpy::VM* vm, pkpy::ArgsView args){
|
vm->bind(vm->builtins, "getPixel(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]);
|
||||||
|
|
||||||
@ -197,7 +213,7 @@ void Graphics::bindMethods(pkpy::VM *vm) {
|
|||||||
return vm->None;
|
return vm->None;
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bind(vm->builtins, "rectangle(x: int, y: int, width: int, height: int, color: int)", [this](pkpy::VM* vm, pkpy::ArgsView args){
|
vm->bind(vm->builtins, "rect(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]);
|
||||||
@ -207,6 +223,16 @@ 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]);
|
||||||
@ -219,6 +245,16 @@ 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]);
|
||||||
@ -243,7 +279,6 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -389,15 +424,25 @@ 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];
|
||||||
std::string bitData = m_currentFont->GetCharData((int)c);
|
// Handle new lines
|
||||||
|
if(c != '\n') {
|
||||||
|
std::string bitData = m_currentFont->GetCharData((int) c);
|
||||||
for (int j = 0; j < bitData.size(); ++j) {
|
for (int j = 0; j < bitData.size(); ++j) {
|
||||||
if(bitData[j] == '1')
|
if (bitData[j] == '1'){
|
||||||
Pixel(x + (j % m_currentFont->GetWidth()) + ((m_currentFont->GetWidth() + 1) * i), y + (j / m_currentFont->GetWidth()), paletteIndex);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -58,6 +58,12 @@ 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,6 +71,7 @@ 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);
|
||||||
@ -131,6 +138,11 @@ 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());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,6 +36,7 @@ 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);
|
||||||
|
|||||||
@ -13,5 +13,6 @@ 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;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -15,7 +15,6 @@ StateManager::~StateManager() {
|
|||||||
m_currentState = nullptr;
|
m_currentState = nullptr;
|
||||||
delete m_gameState;
|
delete m_gameState;
|
||||||
delete m_editorState;
|
delete m_editorState;
|
||||||
delete m_graphics;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -31,13 +30,9 @@ void StateManager::ChangeState(StateManager::StateType state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(m_currentState){
|
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();
|
m_currentState->OnEnter();
|
||||||
|
if(m_currentState == m_gameState && m_gameState->m_errorThrown){
|
||||||
|
m_pycron->m_graphics->Text(m_gameState->m_previousError, 2, 2, 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -53,13 +48,8 @@ void StateManager::Draw() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(m_currentState){
|
if(m_currentState){
|
||||||
if(m_currentState == m_gameState){
|
if(m_currentState == m_gameState && m_gameState->m_errorThrown){
|
||||||
if(m_gameState->m_errorThrown){
|
m_pycron->m_graphics->Text(m_gameState->m_previousError, 2, 2, 4);
|
||||||
m_pycron->m_graphics->Text(m_gameState->m_previousError, 2, 2, 59);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
m_currentState->Draw();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
m_currentState->Draw();
|
m_currentState->Draw();
|
||||||
@ -75,3 +65,7 @@ void StateManager::OnCharPressed(char c) {
|
|||||||
m_currentState->OnCharPressed(c);
|
m_currentState->OnCharPressed(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StateManager::OnMousePressed(int button) {
|
||||||
|
m_currentState->OnMousePressed(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@ -33,6 +33,7 @@ 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();
|
||||||
|
|||||||
@ -7,23 +7,27 @@
|
|||||||
#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();
|
||||||
|
|
||||||
Token a(TokenType::Keyword, "Test");
|
std::string randomSource = Pycron::loadFileToString("../python/threeD.py");
|
||||||
|
//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 = 6;
|
m_lineNumberTextColor = 7;
|
||||||
m_unknownTextColor = 4;
|
m_unknownTextColor = 4;
|
||||||
m_identifierTextColor = 63;
|
m_identifierTextColor = 63;
|
||||||
m_keywordTextColor = 31;
|
m_keywordTextColor = 31;
|
||||||
@ -49,6 +53,9 @@ 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;
|
||||||
|
|
||||||
@ -57,15 +64,12 @@ 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);
|
||||||
@ -93,12 +97,11 @@ 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;
|
||||||
@ -107,6 +110,23 @@ 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;
|
||||||
@ -149,9 +169,25 @@ void EditorState::Draw() {
|
|||||||
|
|
||||||
// Draw the cursor
|
// Draw the cursor
|
||||||
if(m_cursorVisible) {
|
if(m_cursorVisible) {
|
||||||
int x = m_cursorX * m_charWidth + m_textBounds->x;
|
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 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]);
|
||||||
@ -165,10 +201,54 @@ 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);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -182,39 +262,116 @@ void EditorState::OnExit() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EditorState::OnKeyPressed(int key) {
|
void EditorState::OnKeyPressed(int key) {
|
||||||
if(key == KEY_LEFT && m_cursorX > 0){
|
|
||||||
|
|
||||||
|
if (key == KEY_LEFT) {
|
||||||
|
if (m_cursorX > 0) {
|
||||||
m_cursorX--;
|
m_cursorX--;
|
||||||
}
|
m_lastFurthestColumn = m_cursorX;
|
||||||
if(key == KEY_RIGHT && m_cursorX < m_width - 1){
|
} else {
|
||||||
m_cursorX++;
|
|
||||||
}
|
|
||||||
if(key == KEY_UP){
|
|
||||||
if( m_cursorY > 0)
|
if( m_cursorY > 0)
|
||||||
{
|
{
|
||||||
m_cursorY--;
|
m_cursorY--;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
if(m_scrollY > 0)
|
|
||||||
{
|
{
|
||||||
m_scrollY--;
|
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_DOWN )
|
}
|
||||||
{
|
if (key == KEY_RIGHT) {
|
||||||
|
if (m_cursorX < std::min(m_width - 1, (int) m_text[m_scrollY + m_cursorY].size())) {
|
||||||
|
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
|
||||||
|
{
|
||||||
|
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))
|
if(m_cursorY < std::min(m_height - 1, static_cast<int>(m_text.size()) - 1))
|
||||||
{
|
{
|
||||||
m_cursorY++;
|
m_cursorY++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(m_scrollY + m_height < m_text.size())
|
|
||||||
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;
|
||||||
@ -228,6 +385,31 @@ 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] = ' ';
|
||||||
@ -236,6 +418,7 @@ 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;
|
||||||
@ -253,7 +436,6 @@ 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();
|
||||||
|
|
||||||
|
|||||||
@ -20,6 +20,7 @@ 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;
|
||||||
@ -29,6 +30,10 @@ 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;
|
||||||
|
|
||||||
@ -71,6 +76,9 @@ 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;
|
||||||
|
|
||||||
@ -79,6 +87,8 @@ 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;
|
||||||
|
|||||||
@ -11,6 +11,7 @@
|
|||||||
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() {
|
||||||
@ -26,11 +27,17 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,9 +56,6 @@ 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";
|
||||||
@ -82,9 +86,12 @@ 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");
|
||||||
@ -102,3 +109,7 @@ void GameState::OnCharPressed(char character) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GameState::OnMousePressed(int button) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@ -16,6 +16,7 @@ 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:
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#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
|
||||||
@ -18,4 +19,8 @@ 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,10 @@
|
|||||||
#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);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user