init
This commit is contained in:
commit
d940df2869
19
.clang-format
Normal file
19
.clang-format
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
Language: Cpp
|
||||||
|
BasedOnStyle: WebKit
|
||||||
|
IndentWidth: 4
|
||||||
|
ColumnLimit: 80
|
||||||
|
IndentCaseLabels: true
|
||||||
|
InsertNewlineAtEOF: true
|
||||||
|
AllowShortFunctionsOnASingleLine: None
|
||||||
|
|
||||||
|
AlignAfterOpenBracket: AlwaysBreak
|
||||||
|
|
||||||
|
BinPackArguments: false
|
||||||
|
AllowAllArgumentsOnNextLine: true
|
||||||
|
|
||||||
|
# BinPackParameters: OnePerLine # llvm >= 20
|
||||||
|
BinPackParameters: true
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: true
|
||||||
|
PenaltyReturnTypeOnItsOwnLine: 1000 # abitrary, seems to work
|
||||||
|
|
||||||
|
|
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
fed
|
||||||
|
|
27
Makefile
Normal file
27
Makefile
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
|
||||||
|
CFLAGS = -std=c23
|
||||||
|
CFLAGS += -fsanitize=address,undefined -g
|
||||||
|
CFLAGS += -Wall -Wextra -Wpedantic -Wconversion -pedantic -pedantic-errors
|
||||||
|
|
||||||
|
LFLAGS = -lm
|
||||||
|
|
||||||
|
CFLAGS += $(shell pkg-config sdl2 SDL2_ttf --cflags)
|
||||||
|
LFLAGS += $(shell pkg-config sdl2 SDL2_ttf --libs)
|
||||||
|
|
||||||
|
CFILES = \
|
||||||
|
main.c \
|
||||||
|
app.c \
|
||||||
|
buffer.c \
|
||||||
|
editor.c \
|
||||||
|
|
||||||
|
HFILES = $(shell find . -name "*.h")
|
||||||
|
|
||||||
|
TARGET=fed
|
||||||
|
|
||||||
|
$(TARGET): $(CFILES) $(HFILES)
|
||||||
|
gcc -o $@ $(CFILES) $(CFLAGS) $(LFLAGS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(TARGET)
|
||||||
|
|
||||||
|
|
122
app.c
Normal file
122
app.c
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
#include "app.h"
|
||||||
|
#include "editor.h"
|
||||||
|
#include <SDL2/SDL_keycode.h>
|
||||||
|
#include <SDL2/SDL_ttf.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
static void ptr_vec_push(
|
||||||
|
void*** vec, size_t* capacity, size_t* size, void* element)
|
||||||
|
{
|
||||||
|
if (*size + 1 > *capacity) {
|
||||||
|
*capacity *= 2;
|
||||||
|
*vec = realloc(*vec, *capacity * sizeof(void*));
|
||||||
|
}
|
||||||
|
(*vec)[*size] = element;
|
||||||
|
*size += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void app_init(App* app)
|
||||||
|
{
|
||||||
|
const size_t buffers_initial_capacity = 16;
|
||||||
|
|
||||||
|
*app = (App) {
|
||||||
|
.buffers = malloc(buffers_initial_capacity),
|
||||||
|
.buffers_capacity = buffers_initial_capacity,
|
||||||
|
.buffers_size = 0,
|
||||||
|
.res = (AppRessources) {
|
||||||
|
.font = nullptr,
|
||||||
|
.char_size = {},
|
||||||
|
},
|
||||||
|
.editor = {},
|
||||||
|
};
|
||||||
|
editor_init(&app->editor, 1000, 1000, &app->res);
|
||||||
|
}
|
||||||
|
|
||||||
|
void app_deinit(App* app)
|
||||||
|
{
|
||||||
|
if (app->res.font)
|
||||||
|
TTF_CloseFont(app->res.font);
|
||||||
|
for (size_t i = 0; i < app->buffers_size; ++i) {
|
||||||
|
buffer_deinit(app->buffers[i]);
|
||||||
|
free(app->buffers[i]);
|
||||||
|
}
|
||||||
|
free(app->buffers);
|
||||||
|
}
|
||||||
|
|
||||||
|
int app_ressources_load(App* app)
|
||||||
|
{
|
||||||
|
app->res.font
|
||||||
|
= TTF_OpenFont("/usr/share/fonts/TTF/FiraCodeNerdFont-Medium.ttf", 16);
|
||||||
|
if (!app->res.font) {
|
||||||
|
fprintf(stderr, "error: cannot open font: %s\n", SDL_GetError());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
app->res.char_size = text_size("A", app->res.font);
|
||||||
|
app->res.theme = defaultTheme;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void app_ressources_unload(App* app)
|
||||||
|
{
|
||||||
|
if (app->res.font) {
|
||||||
|
TTF_CloseFont(app->res.font);
|
||||||
|
app->res.font = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void app_new_file(App* app)
|
||||||
|
{
|
||||||
|
Buffer* buffer = malloc(sizeof(Buffer));
|
||||||
|
buffer_init(buffer);
|
||||||
|
|
||||||
|
ptr_vec_push(
|
||||||
|
(void***)&app->buffers,
|
||||||
|
&app->buffers_capacity,
|
||||||
|
&app->buffers_size,
|
||||||
|
buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void app_open_file(App* app, const char* path)
|
||||||
|
{
|
||||||
|
Buffer* buffer = malloc(sizeof(Buffer));
|
||||||
|
buffer_from_file(buffer, path);
|
||||||
|
|
||||||
|
ptr_vec_push(
|
||||||
|
(void***)&app->buffers,
|
||||||
|
&app->buffers_capacity,
|
||||||
|
&app->buffers_size,
|
||||||
|
buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void app_prepare(App* app)
|
||||||
|
{
|
||||||
|
if (app->buffers_size == 0) {
|
||||||
|
app_new_file(app);
|
||||||
|
}
|
||||||
|
editor_open(&app->editor, app->buffers[app->buffers_size - 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void app_handle_keydown(App* app, int keysum)
|
||||||
|
{
|
||||||
|
|
||||||
|
switch (keysum) {
|
||||||
|
case SDLK_UP:
|
||||||
|
editor_cursor_up(&app->editor);
|
||||||
|
break;
|
||||||
|
case SDLK_DOWN:
|
||||||
|
editor_cursor_down(&app->editor);
|
||||||
|
break;
|
||||||
|
case SDLK_LEFT:
|
||||||
|
editor_cursor_left(&app->editor);
|
||||||
|
break;
|
||||||
|
case SDLK_RIGHT:
|
||||||
|
editor_cursor_right(&app->editor);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void app_render(App* app, void* renderer)
|
||||||
|
{
|
||||||
|
editor_render(&app->editor, renderer, 0, 0);
|
||||||
|
}
|
29
app.h
Normal file
29
app.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#ifndef APP_H
|
||||||
|
#define APP_H
|
||||||
|
|
||||||
|
#include "app_ressources.h"
|
||||||
|
#include "buffer.h"
|
||||||
|
#include "editor.h"
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Buffer** buffers;
|
||||||
|
size_t buffers_capacity;
|
||||||
|
size_t buffers_size;
|
||||||
|
AppRessources res;
|
||||||
|
Editor editor;
|
||||||
|
} App;
|
||||||
|
|
||||||
|
void app_init(App* app);
|
||||||
|
void app_deinit(App* app);
|
||||||
|
int app_ressources_load(App* app);
|
||||||
|
void app_ressources_unload(App* app);
|
||||||
|
void app_new_file(App* app);
|
||||||
|
void app_open_file(App* app, const char* path);
|
||||||
|
void app_prepare(App* app);
|
||||||
|
void app_handle_keydown(App* app, int keysum);
|
||||||
|
void app_render(App* app, void* renderer);
|
||||||
|
|
||||||
|
extern const Theme defaultTheme;
|
||||||
|
|
||||||
|
#endif
|
28
app_ressources.h
Normal file
28
app_ressources.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#ifndef APP_RESSOURCES_H
|
||||||
|
#define APP_RESSOURCES_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int width, height;
|
||||||
|
} TextSize;
|
||||||
|
|
||||||
|
TextSize text_size(const char* text, void* font);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t r, g, b, a;
|
||||||
|
} Color;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Color foreground;
|
||||||
|
Color background;
|
||||||
|
Color linenumber;
|
||||||
|
} Theme;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
void* font;
|
||||||
|
TextSize char_size;
|
||||||
|
Theme theme;
|
||||||
|
} AppRessources;
|
||||||
|
|
||||||
|
#endif
|
69
buffer.c
Normal file
69
buffer.c
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
#include "buffer.h"
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static int file_read(
|
||||||
|
char** text, size_t* text_capacity, size_t* text_length, const char* path)
|
||||||
|
{
|
||||||
|
FILE* file = fopen(path, "r");
|
||||||
|
if (!file) {
|
||||||
|
fprintf(stderr, "error: could not open file '%s'\n", path);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek(file, 0, SEEK_END);
|
||||||
|
size_t file_size = (size_t)ftell(file);
|
||||||
|
rewind(file);
|
||||||
|
|
||||||
|
size_t initial_capacity = 8;
|
||||||
|
while (initial_capacity < file_size + 1)
|
||||||
|
initial_capacity *= 2;
|
||||||
|
|
||||||
|
*text = calloc(initial_capacity, sizeof(char));
|
||||||
|
*text_capacity = initial_capacity;
|
||||||
|
*text_length = file_size;
|
||||||
|
|
||||||
|
size_t bytes_read = fread(*text, sizeof(char), file_size, file);
|
||||||
|
if (bytes_read != file_size) {
|
||||||
|
fprintf(stderr, "error: could not read file '%s'\n", path);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void buffer_init(Buffer* buffer)
|
||||||
|
{
|
||||||
|
const size_t text_initial_capacity = 8;
|
||||||
|
|
||||||
|
*buffer = (Buffer) {
|
||||||
|
.path = nullptr,
|
||||||
|
.text = calloc(1, text_initial_capacity),
|
||||||
|
.text_capacity = text_initial_capacity,
|
||||||
|
.text_length = 0,
|
||||||
|
.changed = false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
int buffer_from_file(Buffer* buffer, const char* path)
|
||||||
|
{
|
||||||
|
*buffer = (Buffer) {
|
||||||
|
.path = strdup(path),
|
||||||
|
.text = nullptr,
|
||||||
|
.text_capacity = 0,
|
||||||
|
.text_length = 0,
|
||||||
|
.changed = false,
|
||||||
|
};
|
||||||
|
int status = file_read(
|
||||||
|
&buffer->text, &buffer->text_capacity, &buffer->text_length, path);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
void buffer_deinit(Buffer* buffer)
|
||||||
|
{
|
||||||
|
if (buffer->path)
|
||||||
|
free(buffer->path);
|
||||||
|
free(buffer->text);
|
||||||
|
}
|
18
buffer.h
Normal file
18
buffer.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#ifndef BUFFER_H
|
||||||
|
#define BUFFER_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char* path;
|
||||||
|
char* text;
|
||||||
|
size_t text_capacity;
|
||||||
|
size_t text_length;
|
||||||
|
bool changed;
|
||||||
|
} Buffer;
|
||||||
|
|
||||||
|
void buffer_init(Buffer* buffer);
|
||||||
|
int buffer_from_file(Buffer* buffer, const char* path);
|
||||||
|
void buffer_deinit(Buffer* buffer);
|
||||||
|
|
||||||
|
#endif
|
10
compile_flags.txt
Normal file
10
compile_flags.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
-xc
|
||||||
|
-std=c23
|
||||||
|
-Wall
|
||||||
|
-Wextra
|
||||||
|
-Wpedantic
|
||||||
|
-Wconversion
|
||||||
|
-pedantic
|
||||||
|
-pedantic-errors
|
||||||
|
-Wno-unused-variable
|
||||||
|
|
170
editor.c
Normal file
170
editor.c
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
#include "editor.h"
|
||||||
|
#include <SDL2/SDL_render.h>
|
||||||
|
#include <SDL2/SDL_ttf.h>
|
||||||
|
|
||||||
|
void render_text(
|
||||||
|
SDL_Renderer* renderer, const char* text, TTF_Font* font, int x, int y,
|
||||||
|
SDL_Color fg, SDL_Color bg);
|
||||||
|
|
||||||
|
void editor_init(
|
||||||
|
Editor* editor, int width, int height, AppRessources* ressources)
|
||||||
|
{
|
||||||
|
*editor = (Editor) {
|
||||||
|
.buffer = nullptr,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
.cursor_idx = 0,
|
||||||
|
.cursor_line = 1,
|
||||||
|
.cursor_col = 1,
|
||||||
|
ressources,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void editor_open(Editor* editor, Buffer* buffer)
|
||||||
|
{
|
||||||
|
editor->buffer = buffer;
|
||||||
|
editor->cursor_idx = 0;
|
||||||
|
editor->cursor_line = 1;
|
||||||
|
editor->cursor_col = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cols_at_idx(Editor* editor, size_t idx)
|
||||||
|
{
|
||||||
|
Buffer* buffer = editor->buffer;
|
||||||
|
|
||||||
|
int line_start = (int)idx;
|
||||||
|
while (line_start > 0 && buffer->text[line_start] != '\n') {
|
||||||
|
line_start -= 1;
|
||||||
|
}
|
||||||
|
int line_end = (int)idx + 1;
|
||||||
|
while (line_end < (int)buffer->text_length
|
||||||
|
&& buffer->text[line_end] != '\n') {
|
||||||
|
line_end += 1;
|
||||||
|
}
|
||||||
|
printf("idx = %ld, cols = %d\n", idx, line_end - line_start);
|
||||||
|
return line_end - line_start;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cursor_increment(Editor* editor)
|
||||||
|
{
|
||||||
|
if (editor->cursor_idx >= editor->buffer->text_length)
|
||||||
|
return;
|
||||||
|
if (editor->buffer->text[editor->cursor_idx] == '\n') {
|
||||||
|
editor->cursor_line += 1;
|
||||||
|
editor->cursor_col = 1;
|
||||||
|
} else {
|
||||||
|
editor->cursor_col += 1;
|
||||||
|
}
|
||||||
|
editor->cursor_idx += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cursor_decrement(Editor* editor)
|
||||||
|
{
|
||||||
|
if (editor->cursor_idx <= 0)
|
||||||
|
return;
|
||||||
|
editor->cursor_idx -= 1;
|
||||||
|
if (editor->buffer->text[editor->cursor_idx] == '\n') {
|
||||||
|
editor->cursor_line -= 1;
|
||||||
|
editor->cursor_col = cols_at_idx(editor, editor->cursor_idx);
|
||||||
|
} else {
|
||||||
|
editor->cursor_col -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void editor_cursor_up(Editor* editor)
|
||||||
|
{
|
||||||
|
if (editor->cursor_line == 1)
|
||||||
|
return;
|
||||||
|
int originalLine = editor->cursor_line;
|
||||||
|
int originalCol = editor->cursor_col;
|
||||||
|
while (editor->cursor_line >= originalLine
|
||||||
|
|| editor->cursor_col > originalCol) {
|
||||||
|
cursor_decrement(editor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void editor_cursor_down(Editor* editor)
|
||||||
|
{
|
||||||
|
int originalLine = editor->cursor_line;
|
||||||
|
int originalCol = editor->cursor_col;
|
||||||
|
while (editor->cursor_line <= originalLine
|
||||||
|
|| editor->cursor_col > originalCol) {
|
||||||
|
cursor_increment(editor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void editor_cursor_left(Editor* editor)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void editor_cursor_right(Editor* editor)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void editor_render(Editor* editor, void* renderer, int x, int y)
|
||||||
|
{
|
||||||
|
Theme* theme = &editor->ressources->theme;
|
||||||
|
SDL_Color fg = *(SDL_Color*)&theme->foreground;
|
||||||
|
SDL_Color bg = *(SDL_Color*)&theme->background;
|
||||||
|
|
||||||
|
SDL_SetRenderDrawColor(renderer, bg.r, bg.g, bg.b, bg.a);
|
||||||
|
SDL_RenderFillRect(
|
||||||
|
renderer, &(SDL_Rect) { 0, 0, editor->width, editor->height });
|
||||||
|
|
||||||
|
TextSize char_size = editor->ressources->char_size;
|
||||||
|
|
||||||
|
Buffer* buffer = editor->buffer;
|
||||||
|
|
||||||
|
size_t i = 0;
|
||||||
|
int line = 1;
|
||||||
|
int offset_y = 0;
|
||||||
|
|
||||||
|
while (i < buffer->text_length) {
|
||||||
|
size_t line_start = i;
|
||||||
|
while (i < buffer->text_length && buffer->text[i] != '\n') {
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char line_number[16] = "";
|
||||||
|
snprintf(line_number, 15, "%4d", line);
|
||||||
|
|
||||||
|
TextSize ln_size = text_size(line_number, editor->ressources->font);
|
||||||
|
render_text(
|
||||||
|
renderer,
|
||||||
|
line_number,
|
||||||
|
editor->ressources->font,
|
||||||
|
x,
|
||||||
|
y + offset_y,
|
||||||
|
*(SDL_Color*)&theme->linenumber,
|
||||||
|
bg);
|
||||||
|
|
||||||
|
char* line_text = strndup(&buffer->text[line_start], i - line_start);
|
||||||
|
TextSize line_size = text_size(line_text, editor->ressources->font);
|
||||||
|
render_text(
|
||||||
|
renderer,
|
||||||
|
line_text,
|
||||||
|
editor->ressources->font,
|
||||||
|
x + ln_size.width + 8,
|
||||||
|
y + offset_y,
|
||||||
|
fg,
|
||||||
|
bg);
|
||||||
|
free(line_text);
|
||||||
|
|
||||||
|
offset_y += line_size.height;
|
||||||
|
|
||||||
|
if (i < buffer->text_length && buffer->text[i] == '\n') {
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
line += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_SetRenderDrawColor(renderer, fg.r, fg.g, fg.b, fg.a);
|
||||||
|
SDL_RenderFillRect(
|
||||||
|
renderer,
|
||||||
|
&(SDL_Rect) {
|
||||||
|
x + char_size.width * (editor->cursor_col - 1 + 4) + 8 - 1,
|
||||||
|
y + char_size.height * (editor->cursor_line - 1),
|
||||||
|
2,
|
||||||
|
char_size.height,
|
||||||
|
});
|
||||||
|
}
|
26
editor.h
Normal file
26
editor.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#ifndef EDITOR_H
|
||||||
|
#define EDITOR_H
|
||||||
|
|
||||||
|
#include "app_ressources.h"
|
||||||
|
#include "buffer.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Buffer* buffer;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
size_t cursor_idx;
|
||||||
|
int cursor_line;
|
||||||
|
int cursor_col;
|
||||||
|
AppRessources* ressources;
|
||||||
|
} Editor;
|
||||||
|
|
||||||
|
void editor_init(
|
||||||
|
Editor* editor, int width, int height, AppRessources* ressources);
|
||||||
|
void editor_open(Editor* editor, Buffer* buffer);
|
||||||
|
void editor_cursor_up(Editor* editor);
|
||||||
|
void editor_cursor_down(Editor* editor);
|
||||||
|
void editor_cursor_left(Editor* editor);
|
||||||
|
void editor_cursor_right(Editor* editor);
|
||||||
|
void editor_render(Editor* editor, void* renderer, int x, int y);
|
||||||
|
|
||||||
|
#endif
|
175
init.patch
Normal file
175
init.patch
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
diff --git a/.clang-format b/.clang-format
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..a56cbd0
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/.clang-format
|
||||||
|
@@ -0,0 +1,14 @@
|
||||||
|
+Language: Cpp
|
||||||
|
+BasedOnStyle: WebKit
|
||||||
|
+IndentWidth: 4
|
||||||
|
+ColumnLimit: 80
|
||||||
|
+IndentCaseLabels: true
|
||||||
|
+InsertNewlineAtEOF: true
|
||||||
|
+AllowShortFunctionsOnASingleLine: None
|
||||||
|
+
|
||||||
|
+BinPackArguments: false
|
||||||
|
+AllowAllArgumentsOnNextLine: true
|
||||||
|
+
|
||||||
|
+BinPackParameters: false
|
||||||
|
+AllowAllParametersOfDeclarationOnNextLine: true
|
||||||
|
+
|
||||||
|
diff --git a/.gitignore b/.gitignore
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..1fd9dda
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/.gitignore
|
||||||
|
@@ -0,0 +1,2 @@
|
||||||
|
+./game
|
||||||
|
+
|
||||||
|
diff --git a/Makefile b/Makefile
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..3fef9c2
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/Makefile
|
||||||
|
@@ -0,0 +1,17 @@
|
||||||
|
+
|
||||||
|
+CFLAGS = -std=c23
|
||||||
|
+CFLAGS += -fsanitize=address,undefined -g
|
||||||
|
+CFLAGS += -Wall -Wextra -Wpedantic -Wconversion -pedantic -pedantic-errors
|
||||||
|
+
|
||||||
|
+LFLAGS =
|
||||||
|
+
|
||||||
|
+CFLAGS += $(shell pkg-config sdl2 --cflags)
|
||||||
|
+LFLAGS += $(shell pkg-config sdl2 --libs)
|
||||||
|
+
|
||||||
|
+game: main.c
|
||||||
|
+ gcc -o $@ $^ $(CFLAGS) $(LFLAGS)
|
||||||
|
+
|
||||||
|
+clean:
|
||||||
|
+ rm -rf game
|
||||||
|
+
|
||||||
|
+
|
||||||
|
diff --git a/compile_flags.txt b/compile_flags.txt
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..7672925
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/compile_flags.txt
|
||||||
|
@@ -0,0 +1,10 @@
|
||||||
|
+-xc
|
||||||
|
+-std=c23
|
||||||
|
+-Wall
|
||||||
|
+-Wextra
|
||||||
|
+-Wpedantic
|
||||||
|
+-Wconversion
|
||||||
|
+-pedantic
|
||||||
|
+-pedantic-errors
|
||||||
|
+-Wno-unused-variable
|
||||||
|
+
|
||||||
|
diff --git a/main.c b/main.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..879ae5d
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/main.c
|
||||||
|
@@ -0,0 +1,102 @@
|
||||||
|
+#include <SDL2/SDL.h>
|
||||||
|
+#include <SDL2/SDL_blendmode.h>
|
||||||
|
+#include <SDL2/SDL_events.h>
|
||||||
|
+#include <SDL2/SDL_keycode.h>
|
||||||
|
+#include <SDL2/SDL_pixels.h>
|
||||||
|
+#include <SDL2/SDL_rect.h>
|
||||||
|
+#include <SDL2/SDL_render.h>
|
||||||
|
+#include <SDL2/SDL_timer.h>
|
||||||
|
+#include <SDL2/SDL_video.h>
|
||||||
|
+#include <stdint.h>
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+
|
||||||
|
+uint32_t be_to_le_u32(uint32_t be_value);
|
||||||
|
+uint32_t rgba(uint32_t color);
|
||||||
|
+uint32_t rgb(uint32_t color);
|
||||||
|
+
|
||||||
|
+int main(void)
|
||||||
|
+{
|
||||||
|
+
|
||||||
|
+ SDL_Init(SDL_INIT_VIDEO);
|
||||||
|
+
|
||||||
|
+ SDL_Window* window;
|
||||||
|
+ SDL_Renderer* renderer;
|
||||||
|
+
|
||||||
|
+ SDL_CreateWindowAndRenderer(512, 512, 0, &window, &renderer);
|
||||||
|
+ // SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
|
||||||
|
+
|
||||||
|
+ SDL_Texture* buffer = SDL_CreateTexture(renderer,
|
||||||
|
+ SDL_PIXELFORMAT_RGBA32,
|
||||||
|
+ SDL_TEXTUREACCESS_STREAMING,
|
||||||
|
+ 512,
|
||||||
|
+ 512);
|
||||||
|
+
|
||||||
|
+ SDL_SetTextureBlendMode(buffer, SDL_BLENDMODE_BLEND);
|
||||||
|
+
|
||||||
|
+ while (true) {
|
||||||
|
+
|
||||||
|
+ SDL_Event event;
|
||||||
|
+ while (SDL_PollEvent(&event)) {
|
||||||
|
+ switch (event.type) {
|
||||||
|
+ case SDL_QUIT:
|
||||||
|
+ goto exit_game;
|
||||||
|
+ case SDL_KEYDOWN: {
|
||||||
|
+ switch (event.key.keysym.sym) {
|
||||||
|
+ case SDLK_ESCAPE:
|
||||||
|
+ goto exit_game;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ SDL_RenderClear(renderer);
|
||||||
|
+
|
||||||
|
+ uint32_t* pixels;
|
||||||
|
+ int row_size;
|
||||||
|
+ SDL_LockTexture(
|
||||||
|
+ buffer, &(SDL_Rect) { 0, 0, 512, 512 }, (void**)&pixels, &row_size);
|
||||||
|
+ row_size /= sizeof(uint32_t);
|
||||||
|
+
|
||||||
|
+ for (int y = 0; y < 100; ++y) {
|
||||||
|
+ for (int x = 0; x < 100; ++x) {
|
||||||
|
+ pixels[(y + 100) * row_size + x + 100] = rgb(0xff0000);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ SDL_UnlockTexture(buffer);
|
||||||
|
+
|
||||||
|
+ SDL_RenderCopy(renderer, buffer, nullptr, nullptr);
|
||||||
|
+
|
||||||
|
+ SDL_RenderPresent(renderer);
|
||||||
|
+
|
||||||
|
+ SDL_Delay(16);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+exit_game:;
|
||||||
|
+ printf("exitting...\n");
|
||||||
|
+
|
||||||
|
+ SDL_DestroyRenderer(renderer);
|
||||||
|
+ SDL_DestroyWindow(window);
|
||||||
|
+ SDL_Quit();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+uint32_t be_to_le_u32(uint32_t be_value)
|
||||||
|
+{
|
||||||
|
+ uint32_t le_value = 0;
|
||||||
|
+ le_value |= (be_value & 0xff) << 24;
|
||||||
|
+ le_value |= (be_value >> 8 & 0xff) << 16;
|
||||||
|
+ le_value |= (be_value >> 16 & 0xff) << 8;
|
||||||
|
+ le_value |= be_value >> 24 & 0xff;
|
||||||
|
+ return le_value;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+uint32_t rgba(uint32_t color)
|
||||||
|
+{
|
||||||
|
+ return be_to_le_u32(color);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+uint32_t rgb(uint32_t color)
|
||||||
|
+{
|
||||||
|
+ return rgba(color << 8 | 0xff);
|
||||||
|
+}
|
122
main.c
Normal file
122
main.c
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
#include "app.h"
|
||||||
|
#include "app_ressources.h"
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
#include <SDL2/SDL_blendmode.h>
|
||||||
|
#include <SDL2/SDL_error.h>
|
||||||
|
#include <SDL2/SDL_pixels.h>
|
||||||
|
#include <SDL2/SDL_render.h>
|
||||||
|
#include <SDL2/SDL_stdinc.h>
|
||||||
|
#include <SDL2/SDL_surface.h>
|
||||||
|
#include <SDL2/SDL_ttf.h>
|
||||||
|
#include <SDL2/SDL_video.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
const Theme defaultTheme = {
|
||||||
|
.foreground = { 0xfb, 0xf1, 0xc7, 0xff },
|
||||||
|
.background = { 0x28, 0x28, 0x28, 0xff },
|
||||||
|
.linenumber = { 0x7c, 0x6f, 0x64, 0xff },
|
||||||
|
};
|
||||||
|
|
||||||
|
TextSize text_size(const char* text, void* font)
|
||||||
|
{
|
||||||
|
int w, h;
|
||||||
|
TTF_SizeText(font, text, &w, &h);
|
||||||
|
return (TextSize) { w, h };
|
||||||
|
}
|
||||||
|
|
||||||
|
void render_text(
|
||||||
|
SDL_Renderer* renderer, const char* text, TTF_Font* font, int x, int y,
|
||||||
|
SDL_Color fg, SDL_Color bg)
|
||||||
|
{
|
||||||
|
|
||||||
|
SDL_Surface* surface = TTF_RenderUTF8_Shaded(font, text, fg, bg);
|
||||||
|
|
||||||
|
SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface);
|
||||||
|
|
||||||
|
TextSize size = text_size(text, font);
|
||||||
|
SDL_RenderCopy(
|
||||||
|
renderer,
|
||||||
|
texture,
|
||||||
|
nullptr,
|
||||||
|
&(SDL_Rect) { x, y, size.width, size.height });
|
||||||
|
|
||||||
|
SDL_DestroyTexture(texture);
|
||||||
|
SDL_FreeSurface(surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
App app_instance;
|
||||||
|
App* app = &app_instance;
|
||||||
|
app_init(app);
|
||||||
|
|
||||||
|
for (int i = 1; i < argc; ++i) {
|
||||||
|
app_open_file(app, argv[i]);
|
||||||
|
}
|
||||||
|
app_prepare(app);
|
||||||
|
|
||||||
|
SDL_Init(SDL_INIT_VIDEO);
|
||||||
|
TTF_Init();
|
||||||
|
|
||||||
|
app_ressources_load(app);
|
||||||
|
|
||||||
|
SDL_Window* window = SDL_CreateWindow(
|
||||||
|
"fed",
|
||||||
|
SDL_WINDOWPOS_CENTERED,
|
||||||
|
SDL_WINDOWPOS_CENTERED,
|
||||||
|
1000,
|
||||||
|
1000,
|
||||||
|
SDL_WINDOW_RESIZABLE);
|
||||||
|
|
||||||
|
SDL_Renderer* renderer = SDL_CreateRenderer(window, 0, 0);
|
||||||
|
// SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_ADD);
|
||||||
|
|
||||||
|
uint64_t before = SDL_GetTicks64();
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
uint64_t now = SDL_GetTicks64();
|
||||||
|
uint64_t delta = now - before;
|
||||||
|
(void)delta;
|
||||||
|
|
||||||
|
SDL_Event event;
|
||||||
|
while (SDL_PollEvent(&event)) {
|
||||||
|
switch (event.type) {
|
||||||
|
case SDL_QUIT:
|
||||||
|
goto exit_game;
|
||||||
|
case SDL_KEYDOWN: {
|
||||||
|
switch (event.key.keysym.sym) {
|
||||||
|
case SDLK_ESCAPE:
|
||||||
|
goto exit_game;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
app_handle_keydown(app, event.key.keysym.sym);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
|
||||||
|
SDL_RenderClear(renderer);
|
||||||
|
|
||||||
|
app_render(app, renderer);
|
||||||
|
|
||||||
|
SDL_RenderPresent(renderer);
|
||||||
|
SDL_Delay(16);
|
||||||
|
|
||||||
|
before = now;
|
||||||
|
}
|
||||||
|
|
||||||
|
exit_game:;
|
||||||
|
printf("exitting...\n");
|
||||||
|
|
||||||
|
app_ressources_unload(app);
|
||||||
|
|
||||||
|
SDL_DestroyRenderer(renderer);
|
||||||
|
SDL_DestroyWindow(window);
|
||||||
|
|
||||||
|
TTF_Quit();
|
||||||
|
SDL_Quit();
|
||||||
|
|
||||||
|
app_deinit(app);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user