Compare commits

..

3 commits

Author SHA1 Message Date
cat
5b256e74cd why did this not commit 2025-06-28 16:01:22 +10:00
cat
fbedd77ed1 finally start on the rewrite 2025-06-28 15:59:51 +10:00
cat
57ad9fd139 i would like for this program to be comprehensible 2025-06-23 16:35:26 +10:00
15 changed files with 67 additions and 356 deletions

31
dat.h
View file

@ -1,34 +1,15 @@
typedef struct Samply Samply;
typedef struct Action Action;
typedef struct Image Image;
typedef struct State State;
struct Samply {
Image *tx; /* this is a pointer to one of the images below */
Image *idle;
Image *walka;
Image *walkb;
Image *error;
struct Action {
// step
// click
};
struct Image {
char *name; /* used for debugging purposes */
int w;
int h;
int bpp;
char *name;
int w, h, bpp;
unsigned char *data;
SDL_Surface *sur;
SDL_Texture *tex;
};
struct State {
SDL_Window *win;
SDL_Renderer *ren;
SDL_DisplayID dpy;
SDL_Rect bounds;
Uint64 lastframe;
Uint64 frame;
Samply *sam;
};

8
fns.h
View file

@ -4,10 +4,4 @@
#define fuck(...) SDL_LogCritical(SDL_LOG_CATEGORY_APPLICATION, __VA_ARGS__)
void free_image(Image *i);
Image *load_image(SDL_Renderer *ren, char *path);
int samply_step(State *st);
void put_samply_to_bed(Samply *sam);
Samply *wake_samply_up(State *st);
int in_bounds(Image *i, int x, int y, SDL_Rect *bounds);
int load_image(Image *i, SDL_Renderer *ren);

97
img.c
View file

@ -1,7 +1,7 @@
#define STB_IMAGE_IMPLEMENTATION
#define STBI_MALLOC(sz) SDL_malloc(sz)
#define STBI_REALLOC(p,newsz) SDL_realloc(p,newsz)
#define STBI_FREE(p) SDL_free(p)
#define STBI_MALLOC(sz) SDL_malloc(sz)
#define STBI_REALLOC(p,newsz) SDL_realloc(p,newsz)
#define STBI_FREE(p) SDL_free(p)
#include <SDL3/SDL.h>
#include "stb_image.h"
@ -11,78 +11,49 @@
void
free_image(Image *i)
{
if (i) {
if (i->tex) {
babble("free img %s texture...", i->name);
SDL_DestroyTexture(i->tex);
}
if (i->sur) {
babble("destroy image %s surface...", i->name);
SDL_DestroySurface(i->sur);
}
if (i->data) {
babble("free img %s data...", i->name);
stbi_image_free(i->data);
}
if (i->name) {
babble("free img %s name...", i->name);
SDL_free(i->name);
}
babble("free aforementioned img...");
SDL_free(i);
if (i->tex) {
babble("destroying texture for image %s...", i->name);
SDL_DestroyTexture(i->tex);
}
if (i->sur) {
babble("destroying surface for image %s...", i->name);
SDL_DestroySurface(i->sur);
}
if (i->data) {
babble("destroying data for image %s...", i->name);
stbi_image_free(i->data);
}
}
Image *
load_image(SDL_Renderer *ren, char *path)
int
load_image(Image *i, SDL_Renderer *ren)
{
Image *i;
babble("create image %s...", path);
babble("alloc image...", path);
i = SDL_calloc(1, sizeof(Image));
if (!i) {
shit("mem alloc fail: %s", SDL_GetError());
return NULL;
}
babble("alloc image %s name...", path);
i->name = SDL_strdup(path);
if (!i->name) {
shit("strdup fail: %s", SDL_GetError());
free_image(i);
return NULL;
}
babble("alloc image %s data...", i->name);
i->data = stbi_load(path, &i->w, &i->h,
&i->bpp, 4);
babble("opening image %s...", i->name);
i->data = stbi_load(i->name, &i->w, &i->h, &i->bpp, 4);
if (!i->data) {
shit("img load fail: %s", stbi_failure_reason());
free_image(i);
return NULL;
shit("stbi_load: %s", stbi_failure_reason());
goto err;
}
babble("alloc image %s surface...", i->name);
i->sur = SDL_CreateSurfaceFrom(i->w, i->h,
SDL_PIXELFORMAT_RGBA32, i->data,
i->w * 4);
babble("creating surface for image %s...", i->name);
i->sur = SDL_CreateSurfaceFrom(i->w, i->h, SDL_PIXELFORMAT_RGBA32,
i->data, i->w * 4);
if (!i->sur) {
shit("surface creation fail: %s", SDL_GetError());
free_image(i);
return NULL;
shit("SDL_CreateSurfaceFrom: %s", SDL_GetError());
goto err;
}
babble("alloc image %s texture...", i->name);
babble("creating texture for image %s...", i->name);
i->tex = SDL_CreateTextureFromSurface(ren, i->sur);
if (!i->tex) {
shit("surface creation fail: %s", SDL_GetError());
SDL_DestroySurface(i->sur);
free_image(i);
return NULL;
shit("SDL_CreateTextureFromSurface: %s", SDL_GetError());
goto err;
}
babble("image %s created", path);
return i;
babble("created image %s!", i->name);
return 0;
err:
free_image(i);
return -1;
}

11
readme
View file

@ -1,5 +1,7 @@
horny desktop pet thing.
currently being rewritten to make structural sense.
you need sdl3 to build it.
i have not tried cross-compiling to windows yet.
@ -8,12 +10,3 @@ i want people to be able to create their own pets without having to
figure out how to recompile.
run it with `SDL_LOGGING=app=debug ./slutpet` for verbose logging
file layout:
dat.h - data structure header
fns.h - functions and macros header
slutpet.c - sdl init and close
img.c - loading images
samply.c - pet Samply

110
samply.c
View file

@ -1,110 +0,0 @@
#include <SDL3/SDL.h>
#include "dat.h"
#include "fns.h"
int
samply_step(State *st)
{
Uint64 ms;
int x, y;
if (SDL_GetWindowPosition(st->win, &x, &y) == false) {
shit("window pos query fail: %s", SDL_GetError());
goto render_it;
}
ms = SDL_GetTicks();
if ((ms / 100) % 2) {
babble("anim walka");
st->sam->tx = st->sam->walka;
} else {
babble("anim walkb");
st->sam->tx = st->sam->walkb;
}
x++;
babble("bounds %d %d %d %d", st->bounds.x, st->bounds.y,
st->bounds.w, st->bounds.h);
babble("img %d %d %d %d", x, y, st->sam->tx->w / 4, st->sam->tx->h);
// if (in_bounds(st->sam->tx, x, y, &st->bounds) == false) {
if (st->bounds.w - st->sam->tx->w / 4 < x) {
st->sam->tx = st->sam->idle;
x = st->bounds.w - st->sam->tx->w / 4;
babble("*bonk*");
}
if (SDL_SetWindowPosition(st->win, x, y) == false)
shit("window pos set fail: %s", SDL_GetError());
render_it:
if (SDL_RenderTexture(st->ren, st->sam->tx->tex, NULL, NULL) == false) {
fuck("rendertexture fail: %s", SDL_GetError());
return -1;
}
}
void
put_samply_to_bed(Samply *sam)
{
if (sam) {
babble("free samply idle!!");
free_image(sam->idle);
babble("free samply walk a!!");
free_image(sam->walka);
babble("free samply walk b!!");
free_image(sam->walkb);
babble("free samply woozy!!");
free_image(sam->error);
babble("good night, samply!!");
SDL_free(sam);
}
}
Samply *
wake_samply_up(State *st)
{
Samply *sam;
babble("wake up, samply!!");
sam = SDL_calloc(1, sizeof(Samply));
if (!sam) {
fuck("samply would rather stay in bed. too bad! %s", SDL_GetError());
return NULL;
}
babble("stand samply up!!");
sam->idle = load_image(st->ren, "samply/Samply.png");
if (!sam->idle) {
fuck("samply would rather stay in bed. too bad!");
put_samply_to_bed(sam);
return NULL;
}
babble("samply walk! part 1!!");
sam->walka = load_image(st->ren, "samply/Samply_Walk1.png");
if (!sam->walka) {
fuck("samply would rather stay in bed. too bad!");
put_samply_to_bed(sam);
return NULL;
}
babble("samply walk! part 2!!");
sam->walkb = load_image(st->ren, "samply/Samply_Walk2.png");
if (!sam->walkb) {
fuck("samply would rather stay in bed. too bad!");
put_samply_to_bed(sam);
return NULL;
}
babble("samply woozy!!");
sam->error = load_image(st->ren, "samply/SamplyERROR.png");
if (!sam->error) {
fuck("samply would rather stay in bed. too bad!");
put_samply_to_bed(sam);
return NULL;
}
sam->tx = sam->idle;
return sam;
}

4
samply/act.c Normal file
View file

@ -0,0 +1,4 @@
#include <SDL3/SDL.h>
#include "../dat.h"
#include "samply.h"

View file

Before

Width:  |  Height:  |  Size: 98 KiB

After

Width:  |  Height:  |  Size: 98 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 90 KiB

After

Width:  |  Height:  |  Size: 90 KiB

Before After
Before After

7
samply/img.c Normal file
View file

@ -0,0 +1,7 @@
#include <SDL3/SDL.h>
#include "../dat.h"
#include "samply.h"
struct Image samply_sprites[] = {
};

6
samply/samply.h Normal file
View file

@ -0,0 +1,6 @@
typedef struct Samply Samply;
struct Samply {
};
extern Image samply_sprites[];

View file

Before

Width:  |  Height:  |  Size: 71 KiB

After

Width:  |  Height:  |  Size: 71 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 71 KiB

After

Width:  |  Height:  |  Size: 71 KiB

Before After
Before After

17
sdl.c
View file

@ -1,17 +0,0 @@
#include <SDL3/SDL.h>
#include "dat.h"
#include "fns.h"
int
in_bounds(Image *i, int x, int y, SDL_Rect *bounds)
{
SDL_Rect r;
SDL_Rect irect = { x, y, i->w, i->h };
if (SDL_GetRectUnion(&irect, bounds, &r) == false) {
shit("rect union math fail: %s", SDL_GetError());
return false;
}
return SDL_RectsEqual(&irect, &r);
}

View file

@ -1,4 +1,4 @@
.Dd May 24, 2025
.Dd June 28, 2025
.Dt SLUTPET 6
.Os
.
@ -15,3 +15,9 @@
be a desktop pet thing,
but currently it doesn't actually exist.
Try again later.
.
.Sh INTERNALS
Currently this section is just notes on how I'm going to
try to implement everything. Later this will just be
describing the program's layout, to hopefully make
it easier to figure out how to modify it.

124
slutpet.c
View file

@ -1,124 +0,0 @@
#define SDL_MAIN_USE_CALLBACKS
#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>
#include "stb_image.h"
#include "dat.h"
#include "fns.h"
void
SDL_AppQuit(void *as, SDL_AppResult res)
{
State *st;
st = as;
if (st) {
babble("put samply to bed!!");
put_samply_to_bed(st->sam);
babble("free state...");
SDL_free(st);
}
babble("bye!");
return;
}
SDL_AppResult
SDL_AppEvent(void *as, SDL_Event *ev)
{
switch (ev->type) {
case SDL_EVENT_MOUSE_BUTTON_DOWN:
babble("mouse button down event");
if (ev->button.button == SDL_BUTTON_RIGHT) {
babble("right-click quit requested");
return SDL_APP_SUCCESS;
}
break;
case SDL_EVENT_QUIT:
babble("quit requested");
return SDL_APP_SUCCESS;
break; /* unreachable; here for visual symmetry */
}
return SDL_APP_CONTINUE;
}
SDL_AppResult
SDL_AppIterate(void *as)
{
State *st = as;
SDL_Texture *tx;
Uint64 ms;
st->frame++;
SDL_SetRenderDrawColor(st->ren, 0, 0, 0, SDL_ALPHA_TRANSPARENT);
SDL_RenderClear(st->ren);
if (samply_step(st) < 0)
return SDL_APP_FAILURE;
SDL_RenderPresent(st->ren);
st->lastframe = SDL_GetTicks();
return SDL_APP_CONTINUE;
}
SDL_AppResult
SDL_AppInit(void **as, int argc, char **argv)
{
State *st;
babble("init sdl...");
if (!SDL_Init(SDL_INIT_VIDEO)) {
fuck("sdl init fail: %s", SDL_GetError());
return SDL_APP_FAILURE;
}
babble("alloc state...");
st = SDL_calloc(1, sizeof(State));
if (!st) {
fuck("mem alloc fail: %s", SDL_GetError());
return SDL_APP_FAILURE;
}
*as = st;
SDL_SetHint(SDL_HINT_X11_FORCE_OVERRIDE_REDIRECT, "1");
st->lastframe = SDL_GetTicks();
st->frame = 0;
babble("create win+render...");
if (!SDL_CreateWindowAndRenderer("slutpet", 320, 320,
SDL_WINDOW_TRANSPARENT | SDL_WINDOW_BORDERLESS
| SDL_WINDOW_NOT_FOCUSABLE
| SDL_WINDOW_ALWAYS_ON_TOP,
&st->win, &st->ren)) {
fuck("win creation fail: %s", SDL_GetError());
return SDL_APP_FAILURE;
}
if (SDL_EnableScreenSaver() == false)
shit("cannot disable screensaver: %s", SDL_GetError());
st->dpy = SDL_GetDisplayForWindow(st->win);
if (!st->dpy) {
fuck("cannot get current display: %s", SDL_GetError());
return SDL_APP_FAILURE;
}
if (SDL_GetDisplayBounds(st->dpy, &st->bounds) == false) {
fuck("cannot get display bounds: %s", SDL_GetError());
return SDL_APP_FAILURE;
}
babble("create samply!!...");
st->sam = wake_samply_up(st);
if (!st->sam) {
fuck("samply said no. too bad!");
return SDL_APP_FAILURE;
}
babble("hi!!");
babble("program startup took %llums!", SDL_GetTicks());
return SDL_APP_CONTINUE;
}