|
@@ -11,6 +11,11 @@
|
|
|
|
|
|
#include "./editor.h"
|
|
#include "./editor.h"
|
|
|
|
|
|
|
|
+#define SCREEN_WIDTH 800
|
|
|
|
+#define SCREEN_HEIGHT 600
|
|
|
|
+#define FPS 60
|
|
|
|
+#define DELTA_TIME (1.0f / FPS)
|
|
|
|
+
|
|
#define FONT_WIDTH 128
|
|
#define FONT_WIDTH 128
|
|
#define FONT_HEIGHT 64
|
|
#define FONT_HEIGHT 64
|
|
#define FONT_COLS 18
|
|
#define FONT_COLS 18
|
|
@@ -139,6 +144,8 @@ void render_text_sized(SDL_Renderer *renderer, Font *font, const char *text, siz
|
|
}
|
|
}
|
|
|
|
|
|
Editor editor = {0};
|
|
Editor editor = {0};
|
|
|
|
+Vec2f camera_pos = {0};
|
|
|
|
+Vec2f camera_vel = {0};
|
|
|
|
|
|
#define UNHEX(color) \
|
|
#define UNHEX(color) \
|
|
((color) >> (8 * 0)) & 0xFF, \
|
|
((color) >> (8 * 0)) & 0xFF, \
|
|
@@ -146,11 +153,28 @@ Editor editor = {0};
|
|
((color) >> (8 * 2)) & 0xFF, \
|
|
((color) >> (8 * 2)) & 0xFF, \
|
|
((color) >> (8 * 3)) & 0xFF
|
|
((color) >> (8 * 3)) & 0xFF
|
|
|
|
|
|
-void render_cursor(SDL_Renderer *renderer, const Font *font)
|
|
|
|
|
|
+Vec2f window_size(SDL_Window *window)
|
|
|
|
+{
|
|
|
|
+ int w, h;
|
|
|
|
+ SDL_GetWindowSize(window, &w, &h);
|
|
|
|
+ return vec2f((float) w, (float) h);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Vec2f camera_project_point(SDL_Window *window, Vec2f point)
|
|
|
|
+{
|
|
|
|
+ return vec2f_add(
|
|
|
|
+ vec2f_sub(point, camera_pos),
|
|
|
|
+ vec2f_mul(window_size(window), vec2fs(0.5f)));
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+void render_cursor(SDL_Renderer *renderer, SDL_Window *window, const Font *font)
|
|
{
|
|
{
|
|
const Vec2f pos =
|
|
const Vec2f pos =
|
|
- vec2f((float) editor.cursor_col * FONT_CHAR_WIDTH * FONT_SCALE,
|
|
|
|
- (float) editor.cursor_row * FONT_CHAR_HEIGHT * FONT_SCALE);
|
|
|
|
|
|
+ camera_project_point(
|
|
|
|
+ window,
|
|
|
|
+ vec2f((float) editor.cursor_col * FONT_CHAR_WIDTH * FONT_SCALE,
|
|
|
|
+ (float) editor.cursor_row * FONT_CHAR_HEIGHT * FONT_SCALE));
|
|
|
|
|
|
const SDL_Rect rect = {
|
|
const SDL_Rect rect = {
|
|
.x = (int) floorf(pos.x),
|
|
.x = (int) floorf(pos.x),
|
|
@@ -176,7 +200,6 @@ void usage(FILE *stream)
|
|
|
|
|
|
// TODO: Save file
|
|
// TODO: Save file
|
|
// TODO: ncurses renderer
|
|
// TODO: ncurses renderer
|
|
-// TODO: scrolling
|
|
|
|
// TODO: Jump forward/backward by a word
|
|
// TODO: Jump forward/backward by a word
|
|
// TODO: Delete a word
|
|
// TODO: Delete a word
|
|
// TODO: Blinking cursor
|
|
// TODO: Blinking cursor
|
|
@@ -202,7 +225,9 @@ int main(int argc, char **argv)
|
|
scc(SDL_Init(SDL_INIT_VIDEO));
|
|
scc(SDL_Init(SDL_INIT_VIDEO));
|
|
|
|
|
|
SDL_Window *window =
|
|
SDL_Window *window =
|
|
- scp(SDL_CreateWindow("Text Editor", 0, 0, 800, 600,
|
|
|
|
|
|
+ scp(SDL_CreateWindow("Text Editor",
|
|
|
|
+ 0, 0,
|
|
|
|
+ SCREEN_WIDTH, SCREEN_HEIGHT,
|
|
SDL_WINDOW_RESIZABLE));
|
|
SDL_WINDOW_RESIZABLE));
|
|
|
|
|
|
SDL_Renderer *renderer =
|
|
SDL_Renderer *renderer =
|
|
@@ -213,6 +238,7 @@ int main(int argc, char **argv)
|
|
|
|
|
|
bool quit = false;
|
|
bool quit = false;
|
|
while (!quit) {
|
|
while (!quit) {
|
|
|
|
+ const Uint32 start = SDL_GetTicks();
|
|
SDL_Event event = {0};
|
|
SDL_Event event = {0};
|
|
while (SDL_PollEvent(&event)) {
|
|
while (SDL_PollEvent(&event)) {
|
|
switch (event.type) {
|
|
switch (event.type) {
|
|
@@ -279,16 +305,36 @@ int main(int argc, char **argv)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ {
|
|
|
|
+ const Vec2f cursor_pos =
|
|
|
|
+ vec2f((float) editor.cursor_col * FONT_CHAR_WIDTH * FONT_SCALE,
|
|
|
|
+ (float) editor.cursor_row * FONT_CHAR_HEIGHT * FONT_SCALE);
|
|
|
|
+
|
|
|
|
+ camera_vel = vec2f_mul(
|
|
|
|
+ vec2f_sub(cursor_pos, camera_pos),
|
|
|
|
+ vec2fs(2.0f));
|
|
|
|
+
|
|
|
|
+ camera_pos = vec2f_add(camera_pos, vec2f_mul(camera_vel, vec2fs(DELTA_TIME)));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
scc(SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0));
|
|
scc(SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0));
|
|
scc(SDL_RenderClear(renderer));
|
|
scc(SDL_RenderClear(renderer));
|
|
|
|
|
|
for (size_t row = 0; row < editor.size; ++row) {
|
|
for (size_t row = 0; row < editor.size; ++row) {
|
|
const Line *line = editor.lines + row;
|
|
const Line *line = editor.lines + row;
|
|
- render_text_sized(renderer, &font, line->chars, line->size, vec2f(0.0f, (float) row * FONT_CHAR_HEIGHT * FONT_SCALE), 0xFFFFFFFF, FONT_SCALE);
|
|
|
|
|
|
+ const Vec2f line_pos = camera_project_point(window, vec2f(0.0f, (float) row * FONT_CHAR_HEIGHT * FONT_SCALE));
|
|
|
|
+ render_text_sized(renderer, &font, line->chars, line->size, line_pos, 0xFFFFFFFF, FONT_SCALE);
|
|
}
|
|
}
|
|
- render_cursor(renderer, &font);
|
|
|
|
|
|
+ render_cursor(renderer, window, &font);
|
|
|
|
|
|
SDL_RenderPresent(renderer);
|
|
SDL_RenderPresent(renderer);
|
|
|
|
+
|
|
|
|
+ const Uint32 duration = SDL_GetTicks() - start;
|
|
|
|
+ const Uint32 delta_time_ms = 1000 / FPS;
|
|
|
|
+ if (duration < delta_time_ms) {
|
|
|
|
+ SDL_Delay(delta_time_ms - duration);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
SDL_Quit();
|
|
SDL_Quit();
|