Added dynamic windows sizes (resizable windows)

More layer manipulation
Added resize example showing how to use new laywer features
Updated README.m
Bugfixes
This commit is contained in:
Captain4LK 2020-05-10 21:21:10 +02:00
parent 0302a75d00
commit 3d95b505bd
25 changed files with 603 additions and 126 deletions

View file

@ -32,9 +32,18 @@ Linux:
SoftLK has been tested and is working on the following plattforms/os:
* Void GNU/Linux, amd64: [Enter the void](https://voidlinux.org/)
* Void GNU/Linux, amd64: [Enter the void](https://voidlinux.org/)
* Raspbian 10, raspberry pi 4b: [Teach, learn and make](https://www.raspberrypi.org/)
SoftLK should work on any plattform that has a C compiler, SDL2 and OpenGL 2.1, the plattforms listed here are just the ones I frequently test SoftLK on.
## Library Credits
* [stb_image](https://github.com/nothings/stb/blob/master/stb_image.h)
* [stb_image_write](https://github.com/nothings/stb/blob/master/stb_image_write.h)
## Gallery
![performance example](screenshots/performance.png)
![efleder example](screenshots/efelder.png)

View file

@ -20,8 +20,6 @@
#include "ULK_vector.h"
#include <cjson/cJSON.h>
#define WIDTH 1920
#define HEIGHT 1080
typedef struct
{
@ -44,6 +42,14 @@ typedef struct
}Shape;
Shape *shapes;
int shapes_count;
int mode = 0;
int win_width;
int win_height;
int can_width;
int can_height;
int can_x = 0;
int can_y = 0;
float can_scale = 1.0f;
void load_shapes();
void draw_shapes();
@ -53,18 +59,31 @@ void calculate_pos(ULK_vector_2d out, float x, float y);
int main(int argc, char *argv[])
{
SLK_setup(WIDTH,HEIGHT,3,"SLK Engine",1,0);
load_shapes();
SLK_setup(win_width,win_height,3,"SLK Engine",0,1,1);
SLK_timer_set_fps(30);
SLK_mouse_show_cursor(1);
SLK_layer_create(0,SLK_LAYER_RGB); //Layer for drawing shapes
SLK_layer_create(1,SLK_LAYER_RGB); //Layer for drawing electric field
SLK_layer_create(2,SLK_LAYER_RGB);
SLK_layer_activate(0,1);
SLK_layer_activate(1,0);
SLK_layer_activate(2,1);
load_shapes();
SLK_layer_activate(0,1);
SLK_layer_set_dynamic(0,0);
SLK_layer_set_size(0,can_width,can_height);
SLK_layer_set_pos(0,can_x,can_y);
SLK_layer_set_scale(0,can_scale);
SLK_layer_activate(1,0);
SLK_layer_set_dynamic(1,0);
SLK_layer_set_size(1,can_width,can_height);
SLK_layer_set_pos(1,can_x,can_y);
SLK_layer_set_scale(1,can_scale);
SLK_layer_activate(2,1);
SLK_layer_set_dynamic(2,0);
SLK_layer_set_size(2,can_width,can_height);
SLK_layer_set_pos(2,can_x,can_y);
SLK_layer_set_scale(1,can_scale);
draw_shapes();
calculate();
@ -73,6 +92,65 @@ int main(int argc, char *argv[])
{
SLK_update();
if(SLK_key_pressed(SLK_KEY_M))
{
if(mode)
{
mode = 0;
SLK_layer_activate(1,0);
SLK_layer_activate(2,1);
}
else
{
mode = 1;
SLK_layer_activate(1,1);
SLK_layer_activate(2,0);
}
}
if(SLK_mouse_down(SLK_BUTTON_MIDDLE))
{
int x,y;
SLK_mouse_get_relative_pos(&x,&y);
can_x+=x;
can_y+=y;
SLK_layer_set_pos(0,can_x,can_y);
SLK_layer_set_pos(1,can_x,can_y);
SLK_layer_set_pos(2,can_x,can_y);
}
if(SLK_key_down(SLK_KEY_CTRL))
{
int wheel = SLK_mouse_wheel_get_scroll();
if(wheel<0)
{
can_x-=SLK_core_get_width()*can_scale*0.1f*2.f;
can_y-=SLK_core_get_height()*can_scale*0.1f*2.f;
SLK_layer_set_pos(0,can_x,can_y);
SLK_layer_set_pos(1,can_x,can_y);
SLK_layer_set_pos(2,can_x,can_y);
can_scale+=can_scale*0.1f;
SLK_layer_set_scale(0,can_scale);
SLK_layer_set_scale(1,can_scale);
SLK_layer_set_scale(2,can_scale);
}
else if(wheel>0)
{
can_x+=SLK_core_get_width()*can_scale*0.1f*2.f;
can_y+=SLK_core_get_height()*can_scale*0.1f*2.f;
SLK_layer_set_pos(0,can_x,can_y);
SLK_layer_set_pos(1,can_x,can_y);
SLK_layer_set_pos(2,can_x,can_y);
can_scale-=can_scale*0.1f;
SLK_layer_set_scale(0,can_scale);
SLK_layer_set_scale(1,can_scale);
SLK_layer_set_scale(2,can_scale);
}
}
SLK_render_update();
}
@ -98,6 +176,12 @@ void load_shapes()
if(json==NULL)
printf("Json file seems to be faulty!\n");
//Read settings
win_width = cJSON_GetObjectItem(json,"window_width")->valueint;
win_height = cJSON_GetObjectItem(json,"window_height")->valueint;
can_width = cJSON_GetObjectItem(json,"canvas_width")->valueint;
can_height = cJSON_GetObjectItem(json,"canvas_height")->valueint;
//Load all shapes here and count them
circles = cJSON_GetObjectItem(json,"circles");
if(circles==NULL)
@ -133,6 +217,7 @@ void draw_shapes()
int i;
SLK_layer_set_current(0);
SLK_draw_rgb_set_changed(1);
SLK_draw_rgb_set_clear_color(SLK_color_create(0,0,0,0));
SLK_draw_rgb_clear();
@ -152,6 +237,7 @@ void calculate()
int i;
SLK_layer_set_current(1);
SLK_draw_rgb_set_changed(1);
SLK_draw_rgb_set_clear_color(SLK_color_create(0,0,0,0));
SLK_draw_rgb_clear();
@ -166,12 +252,13 @@ void calculate()
}
SLK_layer_set_current(2);
SLK_draw_rgb_set_changed(1);
SLK_draw_rgb_clear();
//Calculate electrical
for(int x = 0;x<WIDTH;x++)
for(int x = 0;x<can_width;x++)
{
for(int y = 0;y<HEIGHT;y++)
for(int y = 0;y<can_height;y++)
{
ULK_vector_2d point;
ULK_vector_2d center;
@ -264,7 +351,7 @@ void calculate_circle(int shape)
SLK_draw_rgb_color((int)pos[0],(int)pos[1],SLK_color_create(255,128,0,255));
}
printf("%d of %d calculated, %f\n",i,shapes[shape].circle.test_points,angle);
printf("%d of %d calculated, %f\n",i+1,shapes[shape].circle.test_points,angle);
}
}

View file

@ -1,25 +1,31 @@
{
"canvas_width":8000,
"canvas_height":8000,
"window_width":800,
"window_height":600,
"circles":
[
{
"x":1520,
"y":540,
"x":3520,
"y":2540,
"radius":128,
"charge":2.0,
"test_points":45
},
{
"x":400,
"y":540,
"x":2400,
"y":2540,
"radius":128,
"charge":-2.0,
"test_points":45
},
{
"x":960,
"y":64,
"x":2960,
"y":2064,
"radius":64,
"charge":-2.0,
"test_points":45
}]
}
]
}

View file

@ -1,5 +1,9 @@
#include "../../include/SLK/SLK.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct
{
int x;
@ -33,7 +37,7 @@ int sort(const void *e0, const void *e1);
int main(int argc, char *argv[])
{
SLK_setup(320,240,5,"SLK Engine",0,SLK_WINDOW_MAX);
SLK_setup(320,240,5,"SLK Engine",0,SLK_WINDOW_MAX,0);
SLK_timer_set_fps(30);
srand(time(NULL));
@ -47,12 +51,14 @@ int main(int argc, char *argv[])
SLK_layer_activate(2,1);
SLK_layer_activate(4,1);
SLK_layer_set_current(0);
SLK_layer_set_current(1);
//SLK_layer_set_size(0,100,100);
SLK_layer_set_tint(1,SLK_color_create(255,255,255,128));
SLK_layer_set_tint(2,SLK_color_create(255,255,255,128));
SLK_layer_set_current(0);
SLK_draw_rgb_set_changed(1);
SLK_layer_set_current(1);
SLK_draw_pal_set_clear_paxel(SLK_color_create_paxel(0,SLK_TRANSPARENT));
SLK_draw_pal_clear();
SLK_draw_rgb_set_clear_color(SLK_color_create(255,255,255,0));
@ -65,12 +71,14 @@ int main(int argc, char *argv[])
gui_01 = SLK_rgb_sprite_load("assets/gui_01.png");
SLK_RGB_sprite *gui_02 = SLK_rgb_sprite_load("assets/gui_02.png");
SLK_layer_set_current(0);
SLK_draw_rgb_set_changed(1);
SLK_draw_rgb_sprite(gui_02,0,220);
SLK_draw_rgb_sprite(gui_01,206,2);
SLK_draw_rgb_string(214,10,1,"pal renderer",SLK_color_create(255,255,255,255));
SLK_rgb_sprite_destroy(gui_02);
SLK_RGB_sprite *gui_03 = SLK_rgb_sprite_load("assets/gui_03.png");
SLK_layer_set_current(4);
SLK_draw_rgb_set_changed(1);
SLK_draw_rgb_sprite(gui_03,0,0);
SLK_rgb_sprite_destroy(gui_03);
@ -94,6 +102,7 @@ int main(int argc, char *argv[])
else if(render_mode==1)
{
SLK_layer_set_current(2);
SLK_draw_rgb_set_changed(1);
SLK_draw_rgb_clear();
}
@ -135,6 +144,7 @@ int main(int argc, char *argv[])
SLK_layer_activate(1,1);
SLK_layer_set_current(0);
SLK_draw_rgb_set_changed(1);
SLK_draw_rgb_sprite(gui_01,206,2);
SLK_draw_rgb_string(214,10,1,"pal renderer",SLK_color_create(255,255,255,255));
}
@ -148,6 +158,7 @@ int main(int argc, char *argv[])
SLK_layer_activate(1,0);
SLK_layer_set_current(0);
SLK_draw_rgb_set_changed(1);
SLK_draw_rgb_sprite(gui_01,206,2);
SLK_draw_rgb_string(214,10,1,"rgb renderer",SLK_color_create(255,255,255,255));
}
@ -159,6 +170,7 @@ int main(int argc, char *argv[])
SLK_layer_set_current(0);
SLK_draw_rgb_set_changed(1);
SLK_draw_rgb_sprite(gui_00,2,2);
SLK_draw_rgb_string(10,10,1,time_stat,SLK_color_create(255,255,255,255));

41
examples/resize/README.md Normal file
View file

@ -0,0 +1,41 @@
## Resize example
This example demonstrates dynamic sized windows, layer scaling, moving and resizing. The image is drawn on a seperate layer, the window itself is resizeable with layer 1 being resized dynamicly. Hold the ctrl key and scroll the mouse wheel to scale the layer, hold the mouse wheel and move the mouse to move it.
## Code Example
This code example creates a resizable window with one dynamic layer.
```c
#include "../../include/SLK/SLK.h"
int main(int argc, char *argv[])
{
//Create a resizable window
//width,height,layer count,window title,fullscreen,pixel scale,dynamic
SLK_setup(320,240,1,"Resizable window",0,3,1);
//Create layer 0 as a rgb layer
SLK_layer_create(0,SLK_LAYER_RGB);
//Flag the layer as active (layers only get drawn if flagged as active)
SLK_layer_activate(0,1);
//Now flag the layer as dynamic. If the dynamic flag is set and SoftLK
//has been started in dynamic mode, windows will be resizable and
//the layers is resized accordingly to the window dimensions.
SLK_layer_set_dynamic(0,1);
while(SLK_core_running())
{
SLK_update();
//Clear the layer so that it does not look weird when resized.
SLK_layer_set_current(0);
SLK_draw_rgb_set_clear_color(SLK_colore_create(255,128,0,255));
SLK_draw_rgb_clear();
SLK_render_update();
}
return 0;
}
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

9
examples/resize/build_linux.sh Executable file
View file

@ -0,0 +1,9 @@
#!/bin/bash
cd "$(dirname "$0")"
gcc -O3 -o engine main.c ../../lib/libSLK.a -lm -lSDL2 -lGL -ldl -Wall
chmod +x engine
./engine
exit
/bin/bash

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

View file

@ -1,6 +1,7 @@
JASC-PAL
0100
16
17
0 0 0
69 36 52
20 12 28
211 170 154

70
examples/resize/main.c Normal file
View file

@ -0,0 +1,70 @@
#include "../../include/SLK/SLK.h"
int main(int argc, char *argv[])
{
SLK_setup(800,600,2,"SoftLK resize test",0,1,1);
SLK_timer_set_fps(60);
SLK_layer_create(1,SLK_LAYER_RGB);
SLK_layer_activate(1,1);
SLK_layer_set_current(1);
SLK_layer_set_dynamic(1,1);
SLK_draw_rgb_set_clear_color(SLK_color_create(128,128,128,255));
SLK_draw_rgb_clear();
int canvas_pos_x = 128;
int canvas_pos_y = 128;
float canvas_scale = 2.0f;
SLK_layer_create(0,SLK_LAYER_RGB);
SLK_layer_activate(0,1);
SLK_layer_set_current(0);
SLK_draw_rgb_set_changed(1);
SLK_layer_set_dynamic(0,0);
SLK_layer_set_size(0,256,224);
SLK_layer_set_pos(0,canvas_pos_x,canvas_pos_y);
SLK_layer_set_scale(0,canvas_scale);
SLK_draw_rgb_set_clear_color(SLK_color_create(255,255,255,255));
SLK_draw_rgb_clear();
SLK_RGB_sprite *logo = SLK_rgb_sprite_load("assets/logo.png");
SLK_draw_rgb_sprite(logo,0,0);
SLK_rgb_sprite_destroy(logo);
while(SLK_core_running())
{
SLK_update();
if(SLK_mouse_down(SLK_BUTTON_MIDDLE))
{
int x,y;
SLK_mouse_get_relative_pos(&x,&y);
canvas_pos_x+=x;
canvas_pos_y+=y;
SLK_layer_set_pos(0,canvas_pos_x,canvas_pos_y);
}
if(SLK_key_down(SLK_KEY_CTRL))
{
int wheel = SLK_mouse_wheel_get_scroll();
if(wheel<0)
{
canvas_scale+=canvas_scale*0.1f;
SLK_layer_set_scale(0,canvas_scale);
}
else if(wheel>0)
{
canvas_scale-=canvas_scale*0.1f;
SLK_layer_set_scale(0,canvas_scale);
}
}
SLK_layer_set_current(1);
SLK_draw_rgb_set_changed(1);
SLK_draw_rgb_set_clear_color(SLK_color_create(128,128,128,255));
SLK_draw_rgb_clear();
SLK_render_update();
}
return 0;
}

View file

@ -32,7 +32,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
//Macros
//Fast integer inbounds checking
#define INBOUNDS(LOWER,UPPER,NUMBER) \
((unsigned)(NUMBER-LOWER)<=(UPPER-LOWER))
((NUMBER-LOWER)<(UPPER-LOWER))
#define SIGNUM(NUM) \
NUM==0?0:(NUM<0?-1:1)

View file

@ -64,10 +64,10 @@ void SLK_draw_pal_circle(int x, int y, int radius, SLK_Paxel paxel);
void SLK_draw_pal_fill_circle(int x, int y, int radius, SLK_Paxel paxel);
//RGB sprite subsystem: SLK_sprite_rgb.c
SLK_RGB_sprite *SLK_rgb_sprite_create(const int width, const int height);
SLK_RGB_sprite *SLK_rgb_sprite_create(int width, int height);
void SLK_rgb_sprite_destroy(SLK_RGB_sprite *s);
SLK_Color SLK_rgb_sprite_get_pixel(const SLK_RGB_sprite *s, const int x, const int y);
void SLK_rgb_sprite_set_pixel(SLK_RGB_sprite *s, const int x, const int y, const SLK_Color c);
SLK_Color SLK_rgb_sprite_get_pixel(const SLK_RGB_sprite *s, int x, int y);
void SLK_rgb_sprite_set_pixel(SLK_RGB_sprite *s, int x, int y, SLK_Color c);
SLK_RGB_sprite *SLK_rgb_sprite_load(const char *path);
void SLK_rgb_sprite_save(const char *path, const SLK_RGB_sprite *s);
void SLK_rgb_sprite_copy(SLK_RGB_sprite *dst, const SLK_RGB_sprite *src);
@ -77,6 +77,7 @@ void SLK_rgb_sprite_copy_partial(SLK_RGB_sprite *dst, const SLK_RGB_sprite *src,
SLK_RGB_sprite *SLK_draw_rgb_get_target();
void SLK_draw_rgb_set_target(SLK_RGB_sprite *s);
void SLK_draw_rgb_set_clear_color(SLK_Color color);
void SLK_draw_rgb_set_changed(int changed);
void SLK_draw_rgb_clear();
void SLK_draw_rgb_color(int x, int y, SLK_Color color);
void SLK_draw_rgb_string(int x, int y, int scale, const char *text, SLK_Color color);
@ -102,25 +103,36 @@ int SLK_key_released(int key);
int SLK_mouse_down(int key);
int SLK_mouse_pressed(int key);
int SLK_mouse_released(int key);
int SLK_mouse_wheel_get_scroll();
void SLK_mouse_get_pos(int *x, int *y);
void SLK_mouse_get_relative_pos(int *x, int *y);
void SLK_mouse_get_layer_pos(unsigned index, int *x, int *y);
void SLK_mouse_show_cursor(int shown);
void SLK_mouse_update(int x, int y);
void SLK_mouse_update_wheel(int wheel);
void SLK_text_input_start(char *text);
void SLK_text_input_stop();
void SLK_input_update_start();
//Layer subsystem: SLK_layer.c
void SLK_layer_create(const unsigned index, const int type);
void SLK_layer_activate(const unsigned index, const int active);
void SLK_layer_set_palette(const unsigned index, SLK_Palette *pal);
void SLK_layer_create(unsigned index, int type);
void SLK_layer_activate(unsigned index, int active);
void SLK_layer_set_palette(unsigned index, SLK_Palette *pal);
void SLK_layer_set_tint(unsigned index, SLK_Color tint);
void SLK_layer_set_current(const unsigned index);
void SLK_layer_set_dynamic(unsigned index, int dynamic);
void SLK_layer_set_pos(unsigned index, int x, int y);
void SLK_layer_set_scale(unsigned index, float scale);
void SLK_layer_set_size(unsigned index, int width, int height);
void SLK_layer_set_current(unsigned index);
//Core subsystem: SLK_core.c
void SLK_setup(const int width, const int height, const int layer_num, const char *title, const int fullscreen, int scale);
void SLK_setup(const int width, const int height, const int layer_num, const char *title, const int fullscreen, int scale, int resizable);
void SLK_update();
void SLK_core_set_title(const char *title);
void SLK_core_set_fullscreen(int fullscreen);
void SLK_core_set_icon(const SLK_RGB_sprite *icon);
int SLK_core_get_width();
int SLK_core_get_height();
int SLK_core_running();
void SLK_core_quit();

View file

@ -90,6 +90,10 @@ typedef struct
{
int type;
int active;
int dynamic;
int x;
int y;
float scale;
SLK_Color tint;
union
@ -149,7 +153,7 @@ enum SLK_flip
SLK_FLIP_HORIZONTAL = 2,
};
enum SLK_window_scale
enum SLK_window
{
SLK_WINDOW_MAX = -1,
};

View file

@ -1,7 +1,7 @@
#!/bin/bash
cd "$(dirname "$0")"
gcc -O3 -c ../src/*/*.c -lm -lSDL2 -ldl -lGL -Wall -fvisibility=hidden
gcc -O3 -c ../src/*/*.c -lm -lSDL2 -ldl -lGL -Wall -Warray-bounds
ar cr libSLK.a *.o
exit

View file

@ -14,6 +14,9 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
*/
//External includes
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//-------------------------------------
//Internal includes
@ -68,7 +71,6 @@ void SLK_core_set_fullscreen(int fullscreen)
SDL_SetWindowSize(sdl_window,screen_width*pixel_scale,screen_height*pixel_scale);
}
SDL_GetWindowSize(sdl_window,&window_width,&window_height);
SLK_render_update_viewport();
}
@ -84,12 +86,26 @@ void SLK_core_set_icon(const SLK_RGB_sprite *icon)
SDL_FreeSurface(surface);
}
//Returns the current viewport width.
int SLK_core_get_width()
{
return screen_width;
}
//Returns the current viewport height.
int SLK_core_get_height()
{
return screen_height;
}
//Updates the engine state.
//Updates the input and the timer.
void SLK_update()
{
SLK_timer_update();
SLK_mouse_update_wheel(0);
//Event managing
SDL_Event event;
while(SDL_PollEvent(&event))
@ -99,9 +115,6 @@ void SLK_update()
case SDL_QUIT:
running = 0;
break;
case SDL_MOUSEMOTION:
SLK_mouse_update(event.motion.x,event.motion.y);
break;
case SDL_KEYDOWN:
if(text_input_active&&event.key.keysym.sym==SDLK_BACKSPACE&&text_input[0]!='\0')
text_input[strlen(text_input)-1] = '\0';
@ -124,10 +137,35 @@ void SLK_update()
if(text_input_active)
strcat(text_input,event.text.text);
break;
case SDL_MOUSEWHEEL:
SLK_mouse_update_wheel(event.wheel.y);
break;
case SDL_WINDOWEVENT:
if(event.window.event==SDL_WINDOWEVENT_RESIZED&&dynamic)
{
int new_width = event.window.data1/pixel_scale+1;
int new_height = event.window.data2/pixel_scale+1;
screen_width = new_width;
screen_height = new_height;
for(int l = 0;l<layer_count;l++)
{
if(layers[l].dynamic)
SLK_layer_set_size(l,new_width,new_height);
}
SLK_render_update_viewport();
}
break;
}
}
//-------------------------------------------
int x,y;
SDL_GetMouseState(&x,&y);
SLK_mouse_update(x,y);
for(int i = 0; i<256; i++)
{
@ -177,12 +215,13 @@ void SLK_update()
//The first function you should call in your code.
//Creates a window, sets its title and allocates space for the layers.
//Also loads the font files in the data dir if availible.
void SLK_setup(const int width, const int height, const int layer_num, const char *title, const int fullscreen, int scale)
void SLK_setup(const int width, const int height, const int layer_num, const char *title, const int fullscreen, int scale, int resizable)
{
pixel_scale = scale;
screen_width = width;
screen_height = height;
layer_count = layer_num;
dynamic = resizable;
layers = malloc(sizeof(SLK_Layer)*layer_num);
memset(layers,0,sizeof(SLK_Layer)*layer_num);
@ -192,7 +231,6 @@ void SLK_setup(const int width, const int height, const int layer_num, const cha
exit(-1);
}
if(pixel_scale==SLK_WINDOW_MAX)
{
SDL_Rect max_size;
@ -220,8 +258,9 @@ void SLK_setup(const int width, const int height, const int layer_num, const cha
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION,2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION,1);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1);
if(fullscreen)
sdl_window = SDL_CreateWindow(title,SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED,0,0,SDL_WINDOW_FULLSCREEN_DESKTOP|SDL_WINDOW_OPENGL);
if(resizable)
sdl_window = SDL_CreateWindow(title,SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED,width*pixel_scale,height*pixel_scale,SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE);
else
sdl_window = SDL_CreateWindow(title,SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED,width*pixel_scale,height*pixel_scale,SDL_WINDOW_OPENGL);
@ -238,10 +277,9 @@ void SLK_setup(const int width, const int height, const int layer_num, const cha
exit(-1);
}
SDL_GL_SetSwapInterval(0);
SDL_GetWindowSize(sdl_window,&window_width,&window_height);
SLK_render_update_viewport();
SLK_render_init();
SLK_core_set_fullscreen(fullscreen);
text_sprite_pal = SLK_pal_sprite_load("data/font8x8.slk");
text_sprite_rgb = SLK_rgb_sprite_load("data/font8x8.png");
@ -302,9 +340,9 @@ void SLK_setup(const int width, const int height, const int layer_num, const cha
key_map[XK_Page_Down] = SLK_KEY_PGDN;
key_map[XK_Insert] = SLK_KEY_INS;
key_map[XK_Shift_L] = SLK_KEY_SHIFT;
key_map[XK_Shift_R] = SLK_KEY_SHIFT;
key_map[XK_Control_L] = SLK_KEY_CTRL;
key_map[XK_Control_R] = SLK_KEY_CTRL;*/
key_map[XK_Shift_R] = SLK_KEY_SHIFT;*/
key_map[SDL_SCANCODE_LCTRL] = SLK_KEY_CTRL;
key_map[SDL_SCANCODE_RCTRL] = SLK_KEY_CTRL;
key_map[SDL_SCANCODE_SPACE] = SLK_KEY_SPACE;
/*key_map[XK_0] = SLK_KEY_K0;

View file

@ -26,7 +26,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
#define SWAP(x,y) \
{ (x)=(x)^(y); (y)=(x)^(y); (x)=(x)^(y); }
#define INBOUNDS(LOWER,UPPER,NUMBER) \
((unsigned)(NUMBER-LOWER)<=(UPPER-LOWER))
((unsigned)(NUMBER-LOWER)<(UPPER-LOWER))
#define SIGNUM(NUM) \
NUM==0?0:(NUM<0?-1:1)
//-------------------------------------

View file

@ -24,7 +24,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
//#defines
#define INBOUNDS(LOWER,UPPER,NUMBER) \
((unsigned)(NUMBER-LOWER)<=(UPPER-LOWER))
((unsigned)(NUMBER-LOWER)<(UPPER-LOWER))
#define SIGNUM(NUM) \
NUM==0?0:(NUM<0?-1:1)
#define SWAP(x,y) \
@ -69,6 +69,14 @@ void SLK_draw_rgb_set_clear_color(SLK_Color color)
target_rgb_clear = color;
}
//Sets wether the target has been changed.
//The gpu texture will only be updated if the target
//has been flagged as changed.
void SLK_draw_rgb_set_changed(int changed)
{
target_rgb->changed = changed;
}
//Clears the draw target to the color specified
//by SKL_draw_rgb_set_clear_color.
void SLK_draw_rgb_clear()
@ -140,10 +148,10 @@ void SLK_draw_rgb_sprite(const SLK_RGB_sprite *s, int x, int y)
draw_start_x = -x;
if(y<0)
draw_start_y = -y;
if(x+draw_end_x>target_pal->width)
draw_end_x = s->width+(target_pal->width-x-draw_end_x);
if(y+draw_end_y>target_pal->height)
draw_end_y = s->height+(target_pal->height-y-draw_end_y);
if(x+draw_end_x>target_rgb->width)
draw_end_x = s->width+(target_rgb->width-x-draw_end_x);
if(y+draw_end_y>target_rgb->height)
draw_end_y = s->height+(target_rgb->height-y-draw_end_y);
for(int x1 = draw_start_x;x1<draw_end_x;x1++)
{

View file

@ -29,6 +29,11 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
//-------------------------------------
//Variables
int mouse_x;
int mouse_y;
int mouse_x_rel;
int mouse_y_rel;
int mouse_wheel;
//-------------------------------------
//Function prototypes
@ -81,12 +86,45 @@ int SLK_mouse_released(int key)
return mouse_state[key].released;
}
//Returns the amount the mouse wheel has been scrolled.
//Negative: towards the user.
int SLK_mouse_wheel_get_scroll()
{
return mouse_wheel;
}
//Stores the current mouse position
//in the provided pointers.
void SLK_mouse_get_pos(int *x, int *y)
{
*x = mouse_x_cache;
*y = mouse_y_cache;
*x = mouse_x;
*y = mouse_y;
}
//Stores the mouse position relative
//to the last position in the
//provided pointers.
void SLK_mouse_get_relative_pos(int *x, int *y)
{
*x = mouse_x_rel;
*y = mouse_y_rel;
}
//Gets the mouse position relative to a layer.
//Layer scaling and position are being considered.
void SLK_mouse_get_layer_pos(unsigned index, int *x, int *y)
{
if(index<layer_count)
{
*x = mouse_x;
*y = mouse_y;
*x-=layers[index].x;
*y-=layers[index].y;
*x/=layers[index].scale;
*y/=layers[index].scale;
}
}
//Updates the mouse position (only the variable,
@ -94,21 +132,32 @@ void SLK_mouse_get_pos(int *x, int *y)
//Used in SLK_update, no need to call yourself.
void SLK_mouse_update(int x, int y)
{
x-=view_x;
y-=view_y;
int mouse_x_cache = mouse_x;
int mouse_y_cache = mouse_y;
x-=view_x;
y-=view_y;
mouse_x_cache = (int)(((float)x/(float)(window_width-(view_x*2))*(float)screen_width));
mouse_y_cache = (int)(((float)y/(float)(window_height-(view_y*2))*(float)screen_height));
mouse_x = (int)(((float)x/(float)(window_width-(view_x*2))*(float)screen_width));
mouse_y = (int)(((float)y/(float)(window_height-(view_y*2))*(float)screen_height));
mouse_x_rel = mouse_x-mouse_x_cache;
mouse_y_rel = mouse_y-mouse_y_cache;
if(mouse_x_cache>=screen_width)
mouse_x_cache = screen_width-1;
if(mouse_y_cache>=screen_height)
mouse_y_cache = screen_height-1;
if(mouse_x>=screen_width)
mouse_x= screen_width-1;
if(mouse_y>=screen_height)
mouse_y= screen_height-1;
if(mouse_x_cache<0)
mouse_x_cache = 0;
if(mouse_y_cache<1)
mouse_y_cache = 1;
if(mouse_x<0)
mouse_x= 0;
if(mouse_y<1)
mouse_y= 1;
}
//Updates the mouse wheel position status.
//Used by SLK_update, no need to call yourself.
void SLK_mouse_update_wheel(int wheel)
{
mouse_wheel = wheel;
}
//Sets wether the cursor should be shown.

View file

@ -42,7 +42,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
//These types are currently availible:
//SLK_LAYER_RGB,
//SLK_LAYER_PAL
void SLK_layer_create(const unsigned index, const int type)
void SLK_layer_create(unsigned index, int type)
{
if(index>=layer_count)
return;
@ -50,10 +50,14 @@ void SLK_layer_create(const unsigned index, const int type)
layers[index].type = type;
layers[index].active = 1;
layers[index].tint = SLK_color_create(255,255,255,255);
layers[index].x = 0;
layers[index].y = 0;
layers[index].scale = 1.0f;
switch(type)
{
case SLK_LAYER_PAL:
{
layers[index].type_0.target = SLK_pal_sprite_create(screen_width,screen_height);
layers[index].type_0.render = SLK_rgb_sprite_create(screen_width,screen_height);
@ -66,7 +70,9 @@ void SLK_layer_create(const unsigned index, const int type)
0,GL_RGBA,GL_UNSIGNED_BYTE,layers[index].type_0.render->data);
break;
}
case SLK_LAYER_RGB:
{
layers[index].type_1.target = SLK_rgb_sprite_create(screen_width,screen_height);
glGenTextures(1,&layers[index].type_1.texture);
@ -79,14 +85,17 @@ void SLK_layer_create(const unsigned index, const int type)
break;
}
case SLK_LAYER_GPU:
{
break;
}
}
}
//Sets wether the layers is supposed to be drawn.
void SLK_layer_activate(const unsigned index, const int active)
void SLK_layer_activate(unsigned index, int active)
{
if(index>=layer_count)
return;
@ -96,7 +105,7 @@ void SLK_layer_activate(const unsigned index, const int active)
//Sets the palette of a layer.
//Only works for SLK_LAYER_PAL layer type.
void SLK_layer_set_palette(const unsigned index, SLK_Palette *pal)
void SLK_layer_set_palette(unsigned index, SLK_Palette *pal)
{
if(index>=layer_count||layers[index].type!=SLK_LAYER_PAL)
return;
@ -107,12 +116,83 @@ void SLK_layer_set_palette(const unsigned index, SLK_Palette *pal)
//Sets the tint a layers is supposed to be drawn with.
void SLK_layer_set_tint(unsigned index, SLK_Color tint)
{
layers[index].tint = tint;
if(index<layer_count)
layers[index].tint = tint;
}
//Sets wether the layers should be resized on
//window resize.
void SLK_layer_set_dynamic(unsigned index, int dynamic)
{
if(index<layer_count)
layers[index].dynamic = dynamic;
}
//Sets the position the layers is supposed to be
//drawn at.
void SLK_layer_set_pos(unsigned index, int x, int y)
{
if(index<layer_count)
{
layers[index].x = x;
layers[index].y = y;
}
}
//Sets the factor the layer is supposed to be scale
//with when drawn.
void SLK_layer_set_scale(unsigned index, float scale)
{
if(index<layer_count)
layers[index].scale = scale;
}
//Sets the size of a non
//dynamic layer.
void SLK_layer_set_size(unsigned index, int width, int height)
{
if(index<layer_count)
{
if(layers[index].type==SLK_LAYER_PAL)
{
if(layers[index].type_0.target==NULL||layers[index].type_0.render==NULL)
{
printf("Error: Layer %d has not been created yet!\n",index);
return;
}
SLK_Pal_sprite *sprite_new = SLK_pal_sprite_create(width,height);
SLK_rgb_sprite_destroy(layers[index].type_0.render);
layers[index].type_0.render = SLK_rgb_sprite_create(width,height);
SLK_pal_sprite_copy(sprite_new,layers[index].type_0.target);
SLK_pal_sprite_destroy(layers[index].type_0.target);
layers[index].type_0.target = sprite_new;
}
else if(layers[index].type==SLK_LAYER_RGB)
{
if(layers[index].type_1.target==NULL)
{
printf("Error: Layer %d has not been created yet!\n",index);
return;
}
SLK_RGB_sprite *sprite_new = SLK_rgb_sprite_create(width,height);
sprite_new->changed = layers[index].type_1.target->changed;
SLK_rgb_sprite_copy(sprite_new,layers[index].type_1.target);
SLK_rgb_sprite_destroy(layers[index].type_1.target);
layers[index].type_1.target = sprite_new;
}
SLK_layer_set_current(index);
}
}
//Sets wich layer is the current default draw target.
//Also overwrites the current draw target.
void SLK_layer_set_current(const unsigned index)
void SLK_layer_set_current(unsigned index)
{
if(index>=layer_count)
return;

View file

@ -15,6 +15,8 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
//External includes
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//-------------------------------------
//Internal includes

View file

@ -55,6 +55,12 @@ void SLK_render_init()
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
//Clears the window and redraws the scene.
@ -62,7 +68,7 @@ void SLK_render_init()
void SLK_render_update()
{
glClear(GL_COLOR_BUFFER_BIT);
glViewport(view_x,view_y,view_width,view_height);
//glViewport(view_x,view_y,view_width,view_height);
for(int l = layer_count-1;l>=0;l--)
{
@ -71,43 +77,61 @@ void SLK_render_update()
switch(layers[l].type)
{
case SLK_LAYER_PAL:
{
float width = (float)layers[l].type_0.target->width*layers[l].scale;
float height = (float)layers[l].type_0.target->height*layers[l].scale;
float x = (float)layers[l].x;
float y = (float)layers[l].y;
for(int i = 0;i<layers[l].type_0.render->width*layers[l].type_0.render->height;i++)
layers[l].type_0.render->data[i] = layers[l].type_0.palette->colors[layers[l].type_0.target->data[i].index];
glBindTexture(GL_TEXTURE_2D,layers[l].type_0.texture);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,screen_width,screen_height,0,GL_RGBA,GL_UNSIGNED_BYTE,layers[l].type_0.render->data);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,layers[l].type_0.render->width,layers[l].type_0.render->height,0,GL_RGBA,GL_UNSIGNED_BYTE,layers[l].type_0.render->data);
glBegin(GL_QUADS);
glColor4ub(layers[l].tint.r,layers[l].tint.g,layers[l].tint.b,layers[l].tint.a);
glTexCoord2f(0.0, 1.0);
glVertex3f(-1.0f,-1.0f,0.0f);
glTexCoord2f(0.0, 0.0);
glVertex3f(-1.0f,1.0f,0.0f);
glTexCoord2f(1.0, 0.0);
glVertex3f( 1.0f,1.0f,0.0f);
glTexCoord2f(1.0,1.0);
glVertex3f(1.0f,-1.0f,0.0f);
glTexCoord2i(0,0);
glVertex3f(x,y,0.0f);
glTexCoord2i(0,1);
glVertex3f(x,y+height,0.0f);
glTexCoord2f(1,1);
glVertex3f(width+x,y+height,0.0f);
glTexCoord2f(1,0);
glVertex3f(width+x,y,0.0f);
glEnd();
break;
}
case SLK_LAYER_RGB:
{
float width = (float)layers[l].type_1.target->width*layers[l].scale;
float height = (float)layers[l].type_1.target->height*layers[l].scale;
float x = (float)layers[l].x;
float y = (float)layers[l].y;
glBindTexture(GL_TEXTURE_2D,layers[l].type_1.texture);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,screen_width,screen_height,0,GL_RGBA,GL_UNSIGNED_BYTE,layers[l].type_1.target->data);
if(layers[l].type_1.target->changed)
{
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,layers[l].type_1.target->width,layers[l].type_1.target->height,0,GL_RGBA,GL_UNSIGNED_BYTE,layers[l].type_1.target->data);
layers[l].type_1.target->changed = 0;
}
glBegin(GL_QUADS);
glColor4ub(layers[l].tint.r,layers[l].tint.g,layers[l].tint.b,layers[l].tint.a);
glTexCoord2f(0.0, 1.0);
glVertex3f(-1.0f,-1.0f,0.0f);
glTexCoord2f(0.0, 0.0);
glVertex3f(-1.0f,1.0f,0.0f);
glTexCoord2f(1.0, 0.0);
glVertex3f( 1.0f,1.0f,0.0f);
glTexCoord2f(1.0,1.0);
glVertex3f(1.0f,-1.0f,0.0f);
glTexCoord2i(0,0);
glVertex3f(x,y,0.0f);
glTexCoord2i(0,1);
glVertex3f(x,y+height,0.0f);
glTexCoord2f(1,1);
glVertex3f(width+x,y+height,0.0f);
glTexCoord2f(1,0);
glVertex3f(width+x,y,0.0f);
glEnd();
break;
}
}
}
}
@ -118,23 +142,41 @@ void SLK_render_update()
//using the current window width and screen width.
void SLK_render_update_viewport()
{
view_width = screen_width*pixel_scale;
view_height = screen_height*pixel_scale;
SDL_GetWindowSize(sdl_window,&window_width,&window_height);
if(view_height<window_height)
{
int p_scale = window_height/screen_height;
view_width = screen_width*p_scale;
view_height = screen_height*p_scale;
}
else
{
int p_scale = window_width/screen_width;
view_width = screen_width*p_scale;
view_height = screen_height*p_scale;
}
if(dynamic)
{
view_width = window_width;
view_height = window_height;
view_x = 0;
view_y = 0;
}
else
{
view_width = screen_width*pixel_scale;
view_height = screen_height*pixel_scale;
view_x = (window_width-view_width)/2;
view_y = (window_height-view_height)/2;
/*if(view_height<window_height)
{
int p_scale = window_height/screen_height;
view_width = screen_width*p_scale;
view_height = screen_height*p_scale;
}
else
{
int p_scale = window_width/screen_width;
view_width = screen_width*p_scale;
view_height = screen_height*p_scale;
}*/
view_x = (window_width-view_width)/2;
view_y = (window_height-view_height)/2;
}
glViewport(view_x,view_y,view_width,view_height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0,screen_width,screen_height,0,1.0,-1.0);
}
//-------------------------------------

View file

@ -14,6 +14,8 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
*/
//External includes
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//-------------------------------------
@ -25,7 +27,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
//#defines
#define INBOUNDS(LOWER,UPPER,NUMBER) \
((unsigned)(NUMBER-LOWER)<=(UPPER-LOWER))
((unsigned)(NUMBER-LOWER)<(UPPER-LOWER))
//-------------------------------------
//Typedefs
@ -43,14 +45,15 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
//and returns a pointer to its location.
SLK_Pal_sprite *SLK_pal_sprite_create(int width, int height)
{
SLK_Pal_sprite *s = malloc(sizeof(SLK_Pal_sprite));
SLK_Pal_sprite *s = malloc(sizeof(SLK_Pal_sprite));
s->width = width;
s->height = height;
s->data = malloc(width*height*sizeof(SLK_Paxel));
memset(s->data,0,sizeof(SLK_Paxel)*width*height);
return s;
s->width = width;
s->height = height;
s->data = malloc(width*height*sizeof(SLK_Paxel));
memset(s->data,0,sizeof(SLK_Paxel)*width*height);
return s;
}
//Destroys a previously allocated sprite.
@ -71,7 +74,7 @@ SLK_Paxel SLK_pal_sprite_get_paxel(const SLK_Pal_sprite *s, int x, int y)
if(INBOUNDS(0,s->width,x)&&INBOUNDS(0,s->height,y))
return s->data[y*s->width+x];
else
return (SLK_Paxel){0,0};
return SLK_color_create_paxel(0,0);
}
//Sets the paxel at the specified
@ -95,8 +98,12 @@ SLK_Pal_sprite *SLK_pal_sprite_load(const char *path)
SLK_Pal_sprite *s = NULL;
int width, height;
if(!f)
if(f==NULL)
{
printf("Failed to open %s!\n",path);
return SLK_pal_sprite_create(1,1);
}
fread(&width,sizeof(int),1,f);
fread(&height,sizeof(int),1,f);

View file

@ -14,6 +14,8 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
*/
//External includes
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//-------------------------------------
@ -31,7 +33,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
//#defines
#define INBOUNDS(LOWER,UPPER,NUMBER) \
((unsigned)(NUMBER-LOWER)<=(UPPER-LOWER))
((unsigned)(NUMBER-LOWER)<(UPPER-LOWER))
//-------------------------------------
//Typedefs
@ -46,7 +48,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
//Function implementations
//Creates a sprites with the specified dimensions and clear it.
SLK_RGB_sprite *SLK_rgb_sprite_create(const int width, const int height)
SLK_RGB_sprite *SLK_rgb_sprite_create(int width, int height)
{
SLK_RGB_sprite *s = malloc(sizeof(SLK_RGB_sprite));
@ -69,7 +71,7 @@ void SLK_rgb_sprite_destroy(SLK_RGB_sprite *s)
}
//Returns the color at the specified position of a sprite.
SLK_Color SLK_rgb_sprite_get_pixel(const SLK_RGB_sprite *s, const int x, const int y)
SLK_Color SLK_rgb_sprite_get_pixel(const SLK_RGB_sprite *s, int x, int y)
{
if(INBOUNDS(0,s->width,x)&&INBOUNDS(0,s->height,y))
return s->data[y*s->width+x];
@ -79,7 +81,7 @@ SLK_Color SLK_rgb_sprite_get_pixel(const SLK_RGB_sprite *s, const int x, const i
//Sets the color of a sprite at the specified position.
//Similar to SLK_draw_rgb_color, but ignores alpha value.
void SLK_rgb_sprite_set_pixel(SLK_RGB_sprite *s, const int x, const int y, const SLK_Color c)
void SLK_rgb_sprite_set_pixel(SLK_RGB_sprite *s, int x, int y, SLK_Color c)
{
if(INBOUNDS(0,s->width,x)&&INBOUNDS(0,s->height,y))
s->data[y*s->width+x] = c;
@ -98,7 +100,7 @@ SLK_RGB_sprite *SLK_rgb_sprite_load(const char *path)
data = stbi_load(path,&width,&height,NULL,4);
if(data==NULL)
{
printf("Unable to load %s\n",path);
printf("Failed to load %s\n",path);
return SLK_rgb_sprite_create(1,1);
}

View file

@ -40,14 +40,12 @@ int view_y;
int view_width;
int view_height;
int running;
int dynamic;
int layer_count;
SLK_Layer *layers;
SLK_Layer *current_layer;
int mouse_x_cache;
int mouse_y_cache;
uint8_t new_key_state[256];
uint8_t old_key_state[256];
SLK_Button keyboard_state[256];