+++ /dev/null
-#!/bin/sh
-
-echo Building with ...
-echo gcc src/main.c -o res/main $(pkg-config --cflags --libs sdl3 x11 xfixes sdl3-image)
-gcc src/main.c src/neko.c -I src/ -o res/main $(pkg-config --cflags --libs sdl3 x11 xfixes sdl3-image) -lm
-
-echo Running...
-#DISPLAY=:1 ./res/main
-./res/main
--- /dev/null
+#!/bin/sh
+
+echo Building manager with ...
+echo gcc manager.c -o manager
+gcc manager.c -o manager
--- /dev/null
+
+
+void main(void){
+
+}
\ No newline at end of file
--- /dev/null
+#!/bin/sh
+
+echo Building with ...
+echo gcc src/main.c -o res/main $(pkg-config --cflags --libs sdl3 x11 xfixes sdl3-image)
+gcc src/main.c src/neko.c -I src/ -o res/main $(pkg-config --static --cflags --libs sdl3 x11 xfixes sdl3-image) -lm
+
+echo Building static version
+echo gcc src/main.c src/neko.c -I src/ -o res/main
+echo $(pkg-config --cflags sdl3 x11 xfixes sdl3-image)
+echo -Wl,-Bstatic -lSDL3 -lSDL3_image -Wl,-Bdynamic
+echo -lX11 -lXfixes -lm
+gcc src/main.c src/neko.c -I src/ -o res/main \
+ $(pkg-config --cflags sdl3 x11 xfixes sdl3-image) \
+ -Wl,-Bstatic -lSDL3 -lSDL3_image -Wl,-Bdynamic \
+ -lX11 -lXfixes -lm
+
+echo Running...
+#DISPLAY=:1 ./res/main
+./res/main
--- /dev/null
+#ifndef COMMON_H
+#define COMMON_H
+
+extern int WINDOW_WIDTH;
+extern int WINDOW_HEIGHT;
+
+#endif
\ No newline at end of file
--- /dev/null
+/* textures.c ... */
+
+/*
+ * This example creates an SDL window and renderer, and then draws some
+ * textures to it every frame.
+ *
+ * This code is public domain. Feel free to use it for any purpose!
+ */
+
+#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
+
+#include <X11/Xlib.h>
+#include <X11/extensions/shape.h>
+#include <X11/extensions/Xfixes.h>
+#include <X11/Xutil.h>
+
+#include <SDL3/SDL.h>
+#include <SDL3/SDL_main.h>
+#include <SDL3_image/SDL_image.h>
+
+#include <stdio.h>
+
+#include "neko.h"
+#include "common.h"
+
+/* We will use this renderer to draw into this window every frame. */
+static SDL_Window *window = NULL;
+static SDL_Renderer *renderer = NULL;
+static IMG_Animation *anim;
+static SDL_Texture **anim_textures;
+static int current_frame = 1;
+
+int WINDOW_WIDTH;
+int WINDOW_HEIGHT;
+
+void set_override_redirect() {
+ Display *dpy = (Display *)SDL_GetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_X11_DISPLAY_POINTER, NULL);
+ Window xwin = (Window)SDL_GetNumberProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0);
+
+ XSetWindowAttributes attrs;
+ attrs.override_redirect = True;
+
+ XChangeWindowAttributes(dpy, xwin, CWOverrideRedirect, &attrs);
+ XFlush(dpy);
+}
+
+void make_window_clickthrough() {
+ Display *dpy = (Display *)SDL_GetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_X11_DISPLAY_POINTER, NULL);
+ Window xwin = (Window)SDL_GetNumberProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0);
+
+ // Make input shape empty → ignores mouse events
+ XRectangle rect;
+ XserverRegion region = XFixesCreateRegion(dpy, &rect, 0);
+ XFixesSetWindowShapeRegion(dpy, xwin, ShapeInput, 0, 0, region);
+ XFixesDestroyRegion(dpy, region);
+
+ XFlush(dpy);
+}
+
+Uint32 increment_frame(void *userdata, SDL_TimerID timerID, Uint32 interval){
+ current_frame = (current_frame+1) % anim->count;
+ return(interval);
+}
+
+/* This function runs once at startup. */
+SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
+{
+ char *gif_path = NULL;
+
+ SDL_SetAppMetadata("systemd", "1.0", "org.kernel.systemd");
+
+ if (!SDL_Init(SDL_INIT_VIDEO)) {
+ SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
+ return SDL_APP_FAILURE;
+ }
+
+ // Init window size to fullscreen
+ int num_displays;
+ SDL_DisplayID *displays = SDL_GetDisplays(&num_displays);
+ SDL_Log("Found %d display(s)", num_displays);
+
+ const SDL_DisplayMode* DisplayMode = SDL_GetCurrentDisplayMode(displays[0]);
+ SDL_free(displays);
+ if(DisplayMode==NULL){
+ printf("Error could not get display mode");
+ return 1;
+ }
+ WINDOW_WIDTH = DisplayMode->w;
+ WINDOW_HEIGHT = DisplayMode->h;
+
+ if (!SDL_CreateWindowAndRenderer("systemd", WINDOW_WIDTH, WINDOW_HEIGHT,
+ SDL_WINDOW_TRANSPARENT | SDL_WINDOW_ALWAYS_ON_TOP | SDL_WINDOW_BORDERLESS ,
+ &window, &renderer)) {
+ SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
+ return SDL_APP_FAILURE;
+ }
+
+ make_window_clickthrough();
+ set_override_redirect();
+ SDL_SetDefaultTextureScaleMode(renderer, SDL_SCALEMODE_PIXELART);
+
+ neko_init(renderer, window);
+
+ /* Open the image file */
+ SDL_asprintf(&gif_path, "%ssample.gif", SDL_GetBasePath());
+ anim = IMG_LoadAnimation(gif_path);
+ if (!anim) {
+ SDL_Log("Couldn't load %s: %s\n", gif_path, SDL_GetError());
+ return SDL_APP_FAILURE;
+ }
+ SDL_free(gif_path); /* done with this, the file is loaded. */
+ int aw = anim->w;
+ int ah = anim->h;
+
+ anim_textures = (SDL_Texture **)SDL_calloc(anim->count, sizeof(*anim_textures));
+ if (!anim_textures) {
+ SDL_Log("Couldn't allocate textures\n");
+ IMG_FreeAnimation(anim);
+ return SDL_APP_FAILURE;
+ }
+ for (int i = 0; i < anim->count; ++i) {
+ anim_textures[i] = SDL_CreateTextureFromSurface(renderer, anim->frames[i]);
+ }
+ SDL_AddTimer(anim->delays[0], increment_frame, NULL);
+
+ return SDL_APP_CONTINUE; /* carry on with the program! */
+}
+
+/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
+SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
+{
+ if (event->type == SDL_EVENT_QUIT) {
+ return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
+ }
+ return SDL_APP_CONTINUE; /* carry on with the program! */
+}
+
+/* This function runs once per frame, and is the heart of the program. */
+SDL_AppResult SDL_AppIterate(void *appstate)
+{
+ SDL_FRect dst_rect;
+ const Uint64 now = SDL_GetTicks();
+
+ /* as you can see from this, rendering draws over whatever was drawn before it. */
+ SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_TRANSPARENT); /* black, full alpha */
+ SDL_RenderClear(renderer); /* start with a blank canvas. */
+
+ neko_render(renderer, window);
+ /*
+ dst_rect.x = WINDOW_HEIGHT/2;
+ dst_rect.y = WINDOW_HEIGHT/2;
+ dst_rect.h = WINDOW_HEIGHT/10;
+ dst_rect.w = WINDOW_HEIGHT/10;
+ SDL_RenderTexture(renderer, anim_textures[current_frame], NULL, &dst_rect);
+ */
+
+ SDL_RenderPresent(renderer); /* put it all on the screen! */
+
+ return SDL_APP_CONTINUE; /* carry on with the program! */
+}
+
+/* This function runs once at shutdown. */
+void SDL_AppQuit(void *appstate, SDL_AppResult result)
+{
+ neko_quit();
+ /* SDL will clean up the window/renderer for us. */
+}
+
+/* BACKUP SDL_AppIterate
+
+ const float direction = ((now % 2000) >= 1000) ? 1.0f : -1.0f;
+ const float scale = ((float) (((int) (now % 1000)) - 500) / 500.0f) * direction;
+
+ dst_rect.x = (100.0f * scale);
+ dst_rect.y = 0.0f;
+ dst_rect.w = (float) texture_width;
+ dst_rect.h = (float) texture_height;
+ SDL_RenderTexture(renderer, texture, NULL, &dst_rect);
+
+
+ dst_rect.x = ((float) (WINDOW_WIDTH - texture_width)) / 2.0f;
+ dst_rect.y = ((float) (WINDOW_HEIGHT - texture_height)) / 2.0f;
+ dst_rect.w = (float) texture_width/2;
+ dst_rect.h = (float) texture_height/2;
+ SDL_RenderTexture(renderer, texture, NULL, &dst_rect);
+
+
+ dst_rect.x = ((float) (WINDOW_WIDTH - texture_width)) - (100.0f * scale);
+ dst_rect.y = (float) (WINDOW_HEIGHT - texture_height);
+ dst_rect.w = (float) texture_width;
+ dst_rect.h = (float) texture_height;
+*/
\ No newline at end of file
--- /dev/null
+#include "neko.h"
+#include "common.h"
+#include <math.h>
+
+static int texture_width = 0;
+static int texture_height = 0;
+
+static float catx = 200;
+static float caty = 200;
+static float speed = 5.0;
+
+#define TIME_BEFORE_SPLEEP 3000
+#define TIME_BEFORE_RUNNING 1000
+#define TIME_ANIM_INTERVAL 300
+
+enum CatState {
+ ST_SLEEPING,
+ ST_RUNNING,
+ ST_WAKING_UP,
+ ST_STAND_BY,
+} cat_state = ST_RUNNING;
+
+enum CatFrames {
+ STAND_BY=0,
+ WAKING_UP=1,
+ UP=2,
+ DOWN=4,
+ LEFT=6,
+ RIGHT=8,
+ UP_LEFT=10,
+ UP_RIGHT=12,
+ DOWN_RIGHT=14,
+ DOWN_LEFT=16,
+ SLEEPING=18,
+};
+
+static int state_timer;
+static int anim_timer = 0;
+static int current_frame = 0;
+
+static float diffx, diffy;
+
+static IMG_Animation *anim;
+static SDL_Texture **anim_textures;
+
+int neko_init(SDL_Renderer *renderer, SDL_Window *window){
+ char *neko_gif_path = NULL;
+
+ /* Textures are pixel data that we upload to the video hardware for fast drawing. Lots of 2D
+ engines refer to these as "sprites." We'll do a static texture (upload once, draw many
+ times) with data from a bitmap file. */
+
+ /* SDL_Surface is pixel data the CPU can access. SDL_Texture is pixel data the GPU can access.
+ Load a .bmp into a surface, move it to a texture from there. */
+ SDL_asprintf(&neko_gif_path, "%sreal_oneko.gif", SDL_GetBasePath());
+ anim = IMG_LoadAnimation(neko_gif_path);
+ if (!anim) {
+ SDL_Log("Couldn't load %s: %s\n", neko_gif_path, SDL_GetError());
+ return SDL_APP_FAILURE;
+ }
+ SDL_free(neko_gif_path); /* done with this, the file is loaded. */
+
+ texture_width = anim->w;
+ texture_height = anim->h;
+
+ anim_textures = (SDL_Texture **)SDL_calloc(anim->count, sizeof(*anim_textures));
+ if (!anim_textures) {
+ SDL_Log("Couldn't allocate textures\n");
+ IMG_FreeAnimation(anim);
+ return SDL_APP_FAILURE;
+ }
+ for (int i = 0; i < anim->count; ++i) {
+ anim_textures[i] = SDL_CreateTextureFromSurface(renderer, anim->frames[i]);
+ }
+
+ SDL_AddTimer(50, move_cat, window);
+}
+
+void neko_render(SDL_Renderer *renderer, SDL_Window *window){
+ SDL_FRect dst_rect;
+
+ dst_rect.x = catx;
+ dst_rect.y = caty;
+ dst_rect.h = WINDOW_HEIGHT/20;
+ dst_rect.w = WINDOW_HEIGHT/20;
+
+ int texture_index = 0;
+ switch (cat_state)
+ {
+ case ST_SLEEPING:
+ texture_index = SLEEPING+current_frame;
+ break;
+ case ST_WAKING_UP:
+ texture_index = WAKING_UP;
+ break;
+ case ST_STAND_BY:
+ texture_index = STAND_BY;
+ break;
+ case ST_RUNNING:
+ // We do this to know if our cat is moving in diagonals
+ double angle = fabs(atan((double) (diffy/diffx)));
+ if(angle<SDL_PI_D/3 && angle>SDL_PI_D/6){ // Diagonals
+ if(diffy<0){
+ if(diffx<0){
+ texture_index = DOWN_RIGHT+current_frame;
+ }else{
+ texture_index = DOWN_LEFT+current_frame;
+ }
+ }else{
+ if(diffx<0){
+ texture_index = UP_RIGHT+current_frame;
+ }else{
+ texture_index = UP_LEFT+current_frame;
+ }
+ }
+ }else{ // pas diagonals
+ if(fabs(diffy) > fabs(diffx)){
+ if(diffy<0){
+ texture_index = DOWN+current_frame;
+ }else{
+ texture_index = UP+current_frame;
+ }
+ }else{
+ if(diffx<0){
+ texture_index = RIGHT+current_frame;
+ }else{
+ texture_index = LEFT+current_frame;
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ SDL_RenderTexture(renderer, anim_textures[texture_index], NULL, &dst_rect);
+
+ if(SDL_GetTicks()-anim_timer > TIME_ANIM_INTERVAL){
+ current_frame = (current_frame+1) % 2;
+ anim_timer=SDL_GetTicks();
+ }
+}
+
+void neko_quit(){
+ SDL_DestroyTexture(anim_textures[current_frame]);
+}
+
+Uint32 move_cat(void *window, SDL_TimerID timerID, Uint32 interval){
+ float mousex, mousey;
+ float hypo;
+ int windowx, windowy;
+
+ SDL_GetGlobalMouseState(&mousex, &mousey);
+ SDL_GetWindowPosition(window, &windowx, &windowy);
+
+ diffx = catx-(mousex-(float)windowx);
+ diffy = caty-(mousey-(float)windowy);
+ hypo = sqrt(diffx*diffx + diffy*diffy);
+ switch (cat_state)
+ {
+ case ST_RUNNING:
+ if (hypo>50){
+ catx -= (diffx*speed/hypo);
+ caty -= (diffy*speed/hypo);
+ }else{
+ cat_state = ST_STAND_BY;
+ state_timer = SDL_GetTicks();
+ }
+ break;
+ case ST_STAND_BY:
+ if (hypo>50){
+ cat_state = ST_RUNNING;
+ }else if (SDL_GetTicks()-TIME_BEFORE_SPLEEP > state_timer){
+ cat_state = ST_SLEEPING;
+ }
+ break;
+ case ST_SLEEPING:
+ if (hypo>50){
+ cat_state = ST_WAKING_UP;
+ state_timer = SDL_GetTicks();
+ }
+ break;
+ case ST_WAKING_UP:
+ if (SDL_GetTicks()-TIME_BEFORE_RUNNING > state_timer){
+ cat_state = ST_RUNNING;
+ }
+ break;
+
+ default:
+ break;
+ }
+ return(interval);
+}
\ No newline at end of file
--- /dev/null
+#ifndef NEKO_H
+#define NEKO_H
+
+#include <SDL3/SDL.h>
+#include <SDL3/SDL_main.h>
+#include <SDL3_image/SDL_image.h>
+
+#include <stdio.h>
+
+int neko_init(SDL_Renderer *renderer, SDL_Window *window);
+void neko_render(SDL_Renderer *renderer, SDL_Window *window);
+void neko_quit();
+Uint32 move_cat(void *window, SDL_TimerID timerID, Uint32 interval);
+
+#endif
\ No newline at end of file
+++ /dev/null
-#ifndef COMMON_H
-#define COMMON_H
-
-extern int WINDOW_WIDTH;
-extern int WINDOW_HEIGHT;
-
-#endif
\ No newline at end of file
+++ /dev/null
-/* textures.c ... */
-
-/*
- * This example creates an SDL window and renderer, and then draws some
- * textures to it every frame.
- *
- * This code is public domain. Feel free to use it for any purpose!
- */
-
-#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
-
-#include <X11/Xlib.h>
-#include <X11/extensions/shape.h>
-#include <X11/extensions/Xfixes.h>
-#include <X11/Xutil.h>
-
-#include <SDL3/SDL.h>
-#include <SDL3/SDL_main.h>
-#include <SDL3_image/SDL_image.h>
-
-#include <stdio.h>
-
-#include "neko.h"
-#include "common.h"
-
-/* We will use this renderer to draw into this window every frame. */
-static SDL_Window *window = NULL;
-static SDL_Renderer *renderer = NULL;
-static IMG_Animation *anim;
-static SDL_Texture **anim_textures;
-static int current_frame = 1;
-
-int WINDOW_WIDTH;
-int WINDOW_HEIGHT;
-
-void set_override_redirect() {
- Display *dpy = (Display *)SDL_GetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_X11_DISPLAY_POINTER, NULL);
- Window xwin = (Window)SDL_GetNumberProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0);
-
- XSetWindowAttributes attrs;
- attrs.override_redirect = True;
-
- XChangeWindowAttributes(dpy, xwin, CWOverrideRedirect, &attrs);
- XFlush(dpy);
-}
-
-void make_window_clickthrough() {
- Display *dpy = (Display *)SDL_GetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_X11_DISPLAY_POINTER, NULL);
- Window xwin = (Window)SDL_GetNumberProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0);
-
- // Make input shape empty → ignores mouse events
- XRectangle rect;
- XserverRegion region = XFixesCreateRegion(dpy, &rect, 0);
- XFixesSetWindowShapeRegion(dpy, xwin, ShapeInput, 0, 0, region);
- XFixesDestroyRegion(dpy, region);
-
- XFlush(dpy);
-}
-
-Uint32 increment_frame(void *userdata, SDL_TimerID timerID, Uint32 interval){
- current_frame = (current_frame+1) % anim->count;
- return(interval);
-}
-
-/* This function runs once at startup. */
-SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
-{
- char *gif_path = NULL;
-
- SDL_SetAppMetadata("systemd", "1.0", "org.kernel.systemd");
-
- if (!SDL_Init(SDL_INIT_VIDEO)) {
- SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
- return SDL_APP_FAILURE;
- }
-
- // Init window size to fullscreen
- int num_displays;
- SDL_DisplayID *displays = SDL_GetDisplays(&num_displays);
- SDL_Log("Found %d display(s)", num_displays);
-
- const SDL_DisplayMode* DisplayMode = SDL_GetCurrentDisplayMode(displays[0]);
- SDL_free(displays);
- if(DisplayMode==NULL){
- printf("Error could not get display mode");
- return 1;
- }
- WINDOW_WIDTH = DisplayMode->w;
- WINDOW_HEIGHT = DisplayMode->h;
-
- if (!SDL_CreateWindowAndRenderer("systemd", WINDOW_WIDTH, WINDOW_HEIGHT,
- SDL_WINDOW_TRANSPARENT | SDL_WINDOW_ALWAYS_ON_TOP | SDL_WINDOW_BORDERLESS ,
- &window, &renderer)) {
- SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
- return SDL_APP_FAILURE;
- }
-
- make_window_clickthrough();
- set_override_redirect();
- SDL_SetDefaultTextureScaleMode(renderer, SDL_SCALEMODE_PIXELART);
-
- neko_init(renderer, window);
-
- /* Open the image file */
- SDL_asprintf(&gif_path, "%ssample.gif", SDL_GetBasePath());
- anim = IMG_LoadAnimation(gif_path);
- if (!anim) {
- SDL_Log("Couldn't load %s: %s\n", gif_path, SDL_GetError());
- return SDL_APP_FAILURE;
- }
- SDL_free(gif_path); /* done with this, the file is loaded. */
- int aw = anim->w;
- int ah = anim->h;
-
- anim_textures = (SDL_Texture **)SDL_calloc(anim->count, sizeof(*anim_textures));
- if (!anim_textures) {
- SDL_Log("Couldn't allocate textures\n");
- IMG_FreeAnimation(anim);
- return SDL_APP_FAILURE;
- }
- for (int i = 0; i < anim->count; ++i) {
- anim_textures[i] = SDL_CreateTextureFromSurface(renderer, anim->frames[i]);
- }
- SDL_AddTimer(anim->delays[0], increment_frame, NULL);
-
- return SDL_APP_CONTINUE; /* carry on with the program! */
-}
-
-/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
-SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
-{
- if (event->type == SDL_EVENT_QUIT) {
- return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
- }
- return SDL_APP_CONTINUE; /* carry on with the program! */
-}
-
-/* This function runs once per frame, and is the heart of the program. */
-SDL_AppResult SDL_AppIterate(void *appstate)
-{
- SDL_FRect dst_rect;
- const Uint64 now = SDL_GetTicks();
-
- /* as you can see from this, rendering draws over whatever was drawn before it. */
- SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_TRANSPARENT); /* black, full alpha */
- SDL_RenderClear(renderer); /* start with a blank canvas. */
-
- neko_render(renderer, window);
- /*
- dst_rect.x = WINDOW_HEIGHT/2;
- dst_rect.y = WINDOW_HEIGHT/2;
- dst_rect.h = WINDOW_HEIGHT/10;
- dst_rect.w = WINDOW_HEIGHT/10;
- SDL_RenderTexture(renderer, anim_textures[current_frame], NULL, &dst_rect);
- */
-
- SDL_RenderPresent(renderer); /* put it all on the screen! */
-
- return SDL_APP_CONTINUE; /* carry on with the program! */
-}
-
-/* This function runs once at shutdown. */
-void SDL_AppQuit(void *appstate, SDL_AppResult result)
-{
- neko_quit();
- /* SDL will clean up the window/renderer for us. */
-}
-
-/* BACKUP SDL_AppIterate
-
- const float direction = ((now % 2000) >= 1000) ? 1.0f : -1.0f;
- const float scale = ((float) (((int) (now % 1000)) - 500) / 500.0f) * direction;
-
- dst_rect.x = (100.0f * scale);
- dst_rect.y = 0.0f;
- dst_rect.w = (float) texture_width;
- dst_rect.h = (float) texture_height;
- SDL_RenderTexture(renderer, texture, NULL, &dst_rect);
-
-
- dst_rect.x = ((float) (WINDOW_WIDTH - texture_width)) / 2.0f;
- dst_rect.y = ((float) (WINDOW_HEIGHT - texture_height)) / 2.0f;
- dst_rect.w = (float) texture_width/2;
- dst_rect.h = (float) texture_height/2;
- SDL_RenderTexture(renderer, texture, NULL, &dst_rect);
-
-
- dst_rect.x = ((float) (WINDOW_WIDTH - texture_width)) - (100.0f * scale);
- dst_rect.y = (float) (WINDOW_HEIGHT - texture_height);
- dst_rect.w = (float) texture_width;
- dst_rect.h = (float) texture_height;
-*/
\ No newline at end of file
+++ /dev/null
-#include "neko.h"
-#include "common.h"
-#include <math.h>
-
-static int texture_width = 0;
-static int texture_height = 0;
-
-static float catx = 200;
-static float caty = 200;
-static float speed = 5.0;
-
-#define TIME_BEFORE_SPLEEP 3000
-#define TIME_BEFORE_RUNNING 1000
-#define TIME_ANIM_INTERVAL 300
-
-enum CatState {
- ST_SLEEPING,
- ST_RUNNING,
- ST_WAKING_UP,
- ST_STAND_BY,
-} cat_state = ST_RUNNING;
-
-enum CatFrames {
- STAND_BY=0,
- WAKING_UP=1,
- UP=2,
- DOWN=4,
- LEFT=6,
- RIGHT=8,
- UP_LEFT=10,
- UP_RIGHT=12,
- DOWN_RIGHT=14,
- DOWN_LEFT=16,
- SLEEPING=18,
-};
-
-static int state_timer;
-static int anim_timer = 0;
-static int current_frame = 0;
-
-static float diffx, diffy;
-
-static IMG_Animation *anim;
-static SDL_Texture **anim_textures;
-
-int neko_init(SDL_Renderer *renderer, SDL_Window *window){
- char *neko_gif_path = NULL;
-
- /* Textures are pixel data that we upload to the video hardware for fast drawing. Lots of 2D
- engines refer to these as "sprites." We'll do a static texture (upload once, draw many
- times) with data from a bitmap file. */
-
- /* SDL_Surface is pixel data the CPU can access. SDL_Texture is pixel data the GPU can access.
- Load a .bmp into a surface, move it to a texture from there. */
- SDL_asprintf(&neko_gif_path, "%sreal_oneko.gif", SDL_GetBasePath());
- anim = IMG_LoadAnimation(neko_gif_path);
- if (!anim) {
- SDL_Log("Couldn't load %s: %s\n", neko_gif_path, SDL_GetError());
- return SDL_APP_FAILURE;
- }
- SDL_free(neko_gif_path); /* done with this, the file is loaded. */
-
- texture_width = anim->w;
- texture_height = anim->h;
-
- anim_textures = (SDL_Texture **)SDL_calloc(anim->count, sizeof(*anim_textures));
- if (!anim_textures) {
- SDL_Log("Couldn't allocate textures\n");
- IMG_FreeAnimation(anim);
- return SDL_APP_FAILURE;
- }
- for (int i = 0; i < anim->count; ++i) {
- anim_textures[i] = SDL_CreateTextureFromSurface(renderer, anim->frames[i]);
- }
-
- SDL_AddTimer(50, move_cat, window);
-}
-
-void neko_render(SDL_Renderer *renderer, SDL_Window *window){
- SDL_FRect dst_rect;
-
- dst_rect.x = catx;
- dst_rect.y = caty;
- dst_rect.h = WINDOW_HEIGHT/15;
- dst_rect.w = WINDOW_HEIGHT/15;
-
- int texture_index = 0;
- switch (cat_state)
- {
- case ST_SLEEPING:
- texture_index = SLEEPING+current_frame;
- break;
- case ST_WAKING_UP:
- texture_index = WAKING_UP;
- break;
- case ST_STAND_BY:
- texture_index = STAND_BY;
- break;
- case ST_RUNNING:
- // We do this to know if our cat is moving in diagonals
- double angle = fabs(atan((double) (diffy/diffx)));
- if(angle<SDL_PI_D/3 && angle>SDL_PI_D/6){ // Diagonals
- if(diffy<0){
- if(diffx<0){
- texture_index = DOWN_RIGHT+current_frame;
- }else{
- texture_index = DOWN_LEFT+current_frame;
- }
- }else{
- if(diffx<0){
- texture_index = UP_RIGHT+current_frame;
- }else{
- texture_index = UP_LEFT+current_frame;
- }
- }
- }else{ // pas diagonals
- if(fabs(diffy) > fabs(diffx)){
- if(diffy<0){
- texture_index = DOWN+current_frame;
- }else{
- texture_index = UP+current_frame;
- }
- }else{
- if(diffx<0){
- texture_index = RIGHT+current_frame;
- }else{
- texture_index = LEFT+current_frame;
- }
- }
- }
- break;
-
- default:
- break;
- }
-
- SDL_RenderTexture(renderer, anim_textures[texture_index], NULL, &dst_rect);
-
- if(SDL_GetTicks()-anim_timer > TIME_ANIM_INTERVAL){
- current_frame = (current_frame+1) % 2;
- anim_timer=SDL_GetTicks();
- }
-}
-
-void neko_quit(){
- SDL_DestroyTexture(anim_textures[current_frame]);
-}
-
-Uint32 move_cat(void *window, SDL_TimerID timerID, Uint32 interval){
- float mousex, mousey;
- float hypo;
- int windowx, windowy;
-
- SDL_GetGlobalMouseState(&mousex, &mousey);
- SDL_GetWindowPosition(window, &windowx, &windowy);
-
- diffx = catx-(mousex-(float)windowx);
- diffy = caty-(mousey-(float)windowy);
- hypo = sqrt(diffx*diffx + diffy*diffy);
- switch (cat_state)
- {
- case ST_RUNNING:
- if (hypo>50){
- catx -= (diffx*speed/hypo);
- caty -= (diffy*speed/hypo);
- }else{
- cat_state = ST_STAND_BY;
- state_timer = SDL_GetTicks();
- }
- break;
- case ST_STAND_BY:
- if (hypo>50){
- cat_state = ST_RUNNING;
- }else if (SDL_GetTicks()-TIME_BEFORE_SPLEEP > state_timer){
- cat_state = ST_SLEEPING;
- }
- break;
- case ST_SLEEPING:
- if (hypo>50){
- cat_state = ST_WAKING_UP;
- state_timer = SDL_GetTicks();
- }
- break;
- case ST_WAKING_UP:
- if (SDL_GetTicks()-TIME_BEFORE_RUNNING > state_timer){
- cat_state = ST_RUNNING;
- }
- break;
-
- default:
- break;
- }
- return(interval);
-}
\ No newline at end of file
+++ /dev/null
-#ifndef NEKO_H
-#define NEKO_H
-
-#include <SDL3/SDL.h>
-#include <SDL3/SDL_main.h>
-#include <SDL3_image/SDL_image.h>
-
-#include <stdio.h>
-
-int neko_init(SDL_Renderer *renderer, SDL_Window *window);
-void neko_render(SDL_Renderer *renderer, SDL_Window *window);
-void neko_quit();
-Uint32 move_cat(void *window, SDL_TimerID timerID, Uint32 interval);
-
-#endif
\ No newline at end of file