mirror of
https://forgejo.xatacraft.ru/Sunshine/mkxp-sunshine.git
synced 2026-08-19 21:39:57 +00:00
Linux Niko
This commit is contained in:
parent
90eb18a8ac
commit
8c15c73f04
13 changed files with 353 additions and 13 deletions
|
|
@ -1,12 +1,66 @@
|
|||
TEMPLATE = app
|
||||
CONFIG += c++11
|
||||
CONFIG -= app_bundle
|
||||
CONFIG -= qt
|
||||
|
||||
SOURCES += main.cpp \
|
||||
niko.cpp \
|
||||
journal.cpp
|
||||
|
||||
LIBS += -lgdi32 -lshlwapi
|
||||
|
||||
RC_FILE = resources.rc
|
||||
TEMPLATE = app
|
||||
CONFIG -= app_bundle qt
|
||||
QMAKE_CFLAGS += -std=gnu11
|
||||
|
||||
# Linux
|
||||
unix:!macx {
|
||||
SOURCES += \
|
||||
linux/main.c \
|
||||
linux/niko.c \
|
||||
linux/journal.c \
|
||||
linux/image/niko1.c \
|
||||
linux/image/niko2.c \
|
||||
linux/image/niko3.c \
|
||||
linux/image/default.c \
|
||||
linux/image/c1.c \
|
||||
linux/image/c2.c \
|
||||
linux/image/c3.c \
|
||||
linux/image/c4.c \
|
||||
linux/image/c5.c \
|
||||
linux/image/c6.c \
|
||||
linux/image/c7.c \
|
||||
linux/image/s1.c \
|
||||
linux/image/s2.c \
|
||||
linux/image/s3.c \
|
||||
linux/image/s4.c \
|
||||
linux/image/t1.c \
|
||||
linux/image/t2.c \
|
||||
linux/image/t3.c \
|
||||
linux/image/t4.c \
|
||||
linux/image/t5.c \
|
||||
linux/image/t6.c \
|
||||
linux/image/t7.c \
|
||||
linux/image/t8.c \
|
||||
linux/image/t9.c \
|
||||
linux/image/t10.c \
|
||||
linux/image/t11.c \
|
||||
linux/image/t12.c \
|
||||
linux/image/t13.c \
|
||||
linux/image/t14.c \
|
||||
linux/image/t15.c \
|
||||
linux/image/t16.c \
|
||||
linux/image/final.c \
|
||||
linux/image/save.c
|
||||
|
||||
HEADERS += \
|
||||
linux/display.h \
|
||||
linux/image.h
|
||||
|
||||
LIBS += -lxcb -lxcb-util -lxcb-image -lxcb-shape
|
||||
}
|
||||
|
||||
# OS X
|
||||
macx {
|
||||
}
|
||||
|
||||
# Windows
|
||||
win32 {
|
||||
SOURCES += \
|
||||
w32/main.c \
|
||||
w32/niko.c \
|
||||
w32/journal.c
|
||||
|
||||
LIBS += -lgdi32 -lshlwapi
|
||||
|
||||
RC_FILE = w32/resources.rc
|
||||
}
|
||||
|
|
|
|||
15
journal/linux/display.h
Normal file
15
journal/linux/display.h
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
#ifndef DISPLAY_H
|
||||
#define DISPLAY_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <xcb/xcb.h>
|
||||
#include <xcb/xcb_ewmh.h>
|
||||
|
||||
struct Display {
|
||||
xcb_connection_t *c;
|
||||
xcb_screen_t *screen;
|
||||
};
|
||||
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
|
||||
#endif // DISPLAY_H
|
||||
113
journal/linux/image.h
Normal file
113
journal/linux/image.h
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
#ifndef EMBED_H
|
||||
#define EMBED_H
|
||||
|
||||
#include <xcb/xcb_image.h>
|
||||
#include <xcb/shape.h>
|
||||
#include <X11/extensions/shape.h>
|
||||
|
||||
static inline xcb_pixmap_t create_mask(xcb_connection_t *c,
|
||||
xcb_window_t win,
|
||||
unsigned char *bits,
|
||||
uint32_t width,
|
||||
uint32_t height)
|
||||
{
|
||||
return xcb_create_pixmap_from_bitmap_data(c, win, bits, width, height, 1, 0, 0, NULL);
|
||||
}
|
||||
|
||||
static inline xcb_pixmap_t create_image(xcb_connection_t *c,
|
||||
xcb_window_t win,
|
||||
unsigned char *bytes,
|
||||
uint32_t width,
|
||||
uint32_t height)
|
||||
{
|
||||
xcb_image_t *image = xcb_image_create_native(
|
||||
c, width, height, XCB_IMAGE_FORMAT_Z_PIXMAP, 24, NULL, width * height * 4, bytes);
|
||||
xcb_pixmap_t pixmap = xcb_generate_id(c);
|
||||
xcb_create_pixmap(c, 24, pixmap, win, width, height);
|
||||
xcb_gcontext_t gc = xcb_generate_id(c);
|
||||
xcb_create_gc(c, gc, pixmap, 0, NULL);
|
||||
xcb_image_put(c, pixmap, gc, image, 0, 0, 0);
|
||||
xcb_image_destroy(image);
|
||||
xcb_free_gc(c, gc);
|
||||
return pixmap;
|
||||
|
||||
}
|
||||
|
||||
static inline void set_shape(xcb_connection_t *c, xcb_window_t win, xcb_pixmap_t mask)
|
||||
{
|
||||
xcb_shape_mask(c, ShapeSet, ShapeBounding, win, 0, 0, mask);
|
||||
}
|
||||
|
||||
#define NIKO_WIDTH 48
|
||||
#define NIKO_HEIGHT 64
|
||||
extern unsigned char niko1_mask[];
|
||||
extern unsigned char niko1_rgb[];
|
||||
extern unsigned char niko2_mask[];
|
||||
extern unsigned char niko2_rgb[];
|
||||
extern unsigned char niko3_mask[];
|
||||
extern unsigned char niko3_rgb[];
|
||||
|
||||
#define JOURNAL_WIDTH 800
|
||||
#define JOURNAL_HEIGHT 600
|
||||
extern unsigned char default_mask[];
|
||||
extern unsigned char default_rgb[];
|
||||
extern unsigned char c1_mask[];
|
||||
extern unsigned char c1_rgb[];
|
||||
extern unsigned char c2_mask[];
|
||||
extern unsigned char c2_rgb[];
|
||||
extern unsigned char c3_mask[];
|
||||
extern unsigned char c3_rgb[];
|
||||
extern unsigned char c4_mask[];
|
||||
extern unsigned char c4_rgb[];
|
||||
extern unsigned char c5_mask[];
|
||||
extern unsigned char c5_rgb[];
|
||||
extern unsigned char c6_mask[];
|
||||
extern unsigned char c6_rgb[];
|
||||
extern unsigned char c7_mask[];
|
||||
extern unsigned char c7_rgb[];
|
||||
extern unsigned char s1_mask[];
|
||||
extern unsigned char s1_rgb[];
|
||||
extern unsigned char s2_mask[];
|
||||
extern unsigned char s2_rgb[];
|
||||
extern unsigned char s3_mask[];
|
||||
extern unsigned char s3_rgb[];
|
||||
extern unsigned char s4_mask[];
|
||||
extern unsigned char s4_rgb[];
|
||||
extern unsigned char t1_mask[];
|
||||
extern unsigned char t1_rgb[];
|
||||
extern unsigned char t2_mask[];
|
||||
extern unsigned char t2_rgb[];
|
||||
extern unsigned char t3_mask[];
|
||||
extern unsigned char t3_rgb[];
|
||||
extern unsigned char t4_mask[];
|
||||
extern unsigned char t4_rgb[];
|
||||
extern unsigned char t5_mask[];
|
||||
extern unsigned char t5_rgb[];
|
||||
extern unsigned char t6_mask[];
|
||||
extern unsigned char t6_rgb[];
|
||||
extern unsigned char t7_mask[];
|
||||
extern unsigned char t7_rgb[];
|
||||
extern unsigned char t8_mask[];
|
||||
extern unsigned char t8_rgb[];
|
||||
extern unsigned char t9_mask[];
|
||||
extern unsigned char t9_rgb[];
|
||||
extern unsigned char t10_mask[];
|
||||
extern unsigned char t10_rgb[];
|
||||
extern unsigned char t11_mask[];
|
||||
extern unsigned char t11_rgb[];
|
||||
extern unsigned char t12_mask[];
|
||||
extern unsigned char t12_rgb[];
|
||||
extern unsigned char t13_mask[];
|
||||
extern unsigned char t13_rgb[];
|
||||
extern unsigned char t14_mask[];
|
||||
extern unsigned char t14_rgb[];
|
||||
extern unsigned char t15_mask[];
|
||||
extern unsigned char t15_rgb[];
|
||||
extern unsigned char t16_mask[];
|
||||
extern unsigned char t16_rgb[];
|
||||
extern unsigned char final_mask[];
|
||||
extern unsigned char final_rgb[];
|
||||
extern unsigned char save_mask[];
|
||||
extern unsigned char save_rgb[];
|
||||
|
||||
#endif // EMBED_H
|
||||
1
journal/linux/image/.gitignore
vendored
Normal file
1
journal/linux/image/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
*.c
|
||||
12
journal/linux/image/pixmapper.sh
Executable file
12
journal/linux/image/pixmapper.sh
Executable file
|
|
@ -0,0 +1,12 @@
|
|||
#!/bin/bash
|
||||
if [ $# -lt 1 ]; then
|
||||
echo "usage: pixmapper.sh <image>"
|
||||
exit 1
|
||||
fi
|
||||
basename="$(basename "$1" | tr '[:upper:]' '[:lower:]')"
|
||||
name="${basename%.*}"
|
||||
cfile="$name.c"
|
||||
convert "$1" -alpha on -transparent '#00ff00' -alpha extract -negate xbm:- | sed "/^#define/d;s/-_bits/${name}_mask/g;s/^static char/unsigned char/" > "$cfile"
|
||||
echo "unsigned char ${name}_rgb[] = {" >> "$cfile"
|
||||
convert "$1" -alpha on -transparent '#00ff00' -depth 8 bgra:- | xxd -i >> "$cfile"
|
||||
echo "};" >> "$cfile"
|
||||
6
journal/linux/journal.c
Normal file
6
journal/linux/journal.c
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#include "display.h"
|
||||
|
||||
int do_journal(struct Display *dpy)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
26
journal/linux/main.c
Normal file
26
journal/linux/main.c
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#include "display.h"
|
||||
|
||||
extern int do_niko(struct Display *dpy, int x, int y);
|
||||
extern int do_journal(struct Display *dpy);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
// Connect
|
||||
struct Display dpy;
|
||||
dpy.c = xcb_connect(NULL, NULL);
|
||||
dpy.screen = xcb_setup_roots_iterator(xcb_get_setup(dpy.c)).data;
|
||||
|
||||
int result;
|
||||
if (argc == 3) {
|
||||
// argc == 3, assume niko
|
||||
int x = atoi(argv[1]);
|
||||
int y = atoi(argv[2]);
|
||||
result = do_niko(&dpy, x, y);
|
||||
} else {
|
||||
// argc == 3, assume journal
|
||||
result = do_journal(&dpy);
|
||||
}
|
||||
|
||||
xcb_disconnect(dpy.c);
|
||||
return result;
|
||||
}
|
||||
113
journal/linux/niko.c
Normal file
113
journal/linux/niko.c
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
#include <sys/time.h>
|
||||
|
||||
#include "display.h"
|
||||
#include "image.h"
|
||||
|
||||
static uint64_t getticks()
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
return (uint64_t)tv.tv_sec * 1000 + (uint64_t)tv.tv_usec / 1000;
|
||||
}
|
||||
|
||||
static void draw_niko(xcb_connection_t *c,
|
||||
xcb_window_t win,
|
||||
xcb_gcontext_t gc,
|
||||
xcb_pixmap_t masks[3],
|
||||
xcb_pixmap_t images[3],
|
||||
int x, int y, int w, int h,
|
||||
int offset)
|
||||
{
|
||||
int frame;
|
||||
if (offset % 32 >= 16) {
|
||||
frame = 1;
|
||||
} else {
|
||||
if ((offset / 32) % 2)
|
||||
frame = 0;
|
||||
else
|
||||
frame = 2;
|
||||
}
|
||||
xcb_shape_mask(c, ShapeSet, ShapeBounding, win, 0, 0, masks[frame]);
|
||||
xcb_copy_area(c, images[frame], win, gc, x, y, x, y, w, h);
|
||||
|
||||
}
|
||||
|
||||
int do_niko(struct Display *dpy, int x, int y)
|
||||
{
|
||||
// Create window
|
||||
uint32_t values[] = {
|
||||
true, // override_redirect
|
||||
XCB_EVENT_MASK_EXPOSURE, // event mask
|
||||
};
|
||||
xcb_window_t window = xcb_generate_id(dpy->c);
|
||||
xcb_create_window(dpy->c, XCB_COPY_FROM_PARENT, window, dpy->screen->root,
|
||||
x, y, NIKO_WIDTH, NIKO_HEIGHT,
|
||||
0, XCB_WINDOW_CLASS_INPUT_OUTPUT, dpy->screen->root_visual,
|
||||
XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK, &values);
|
||||
|
||||
// Stick window on top
|
||||
xcb_stack_mode_t stack = XCB_STACK_MODE_ABOVE;
|
||||
xcb_configure_window(dpy->c, window, XCB_CONFIG_WINDOW_STACK_MODE, &stack);
|
||||
|
||||
// Create pixmaps
|
||||
xcb_pixmap_t niko_masks[] = {
|
||||
create_mask(dpy->c, window, niko1_mask, NIKO_WIDTH, NIKO_HEIGHT),
|
||||
create_mask(dpy->c, window, niko2_mask, NIKO_WIDTH, NIKO_HEIGHT),
|
||||
create_mask(dpy->c, window, niko3_mask, NIKO_WIDTH, NIKO_HEIGHT),
|
||||
};
|
||||
xcb_pixmap_t niko_images[] = {
|
||||
create_image(dpy->c, window, niko1_rgb, NIKO_WIDTH, NIKO_HEIGHT),
|
||||
create_image(dpy->c, window, niko2_rgb, NIKO_WIDTH, NIKO_HEIGHT),
|
||||
create_image(dpy->c, window, niko3_rgb, NIKO_WIDTH, NIKO_HEIGHT),
|
||||
};
|
||||
|
||||
// Create graphics context
|
||||
xcb_gcontext_t gc = xcb_generate_id(dpy->c);
|
||||
xcb_create_gc(dpy->c, gc, window, 0, NULL);
|
||||
|
||||
// Map!
|
||||
xcb_map_window(dpy->c, window);
|
||||
xcb_flush(dpy->c);
|
||||
|
||||
// Niko movement info
|
||||
int niko_offset = 0;
|
||||
|
||||
uint64_t ticks = getticks();
|
||||
for (;;) {
|
||||
// Handle events
|
||||
for (;;) {
|
||||
xcb_generic_event_t *e = xcb_poll_for_event(dpy->c);
|
||||
if (e) {
|
||||
switch (e->response_type) {
|
||||
case XCB_EXPOSE: {
|
||||
xcb_expose_event_t *ee = (xcb_expose_event_t*)e;
|
||||
draw_niko(dpy->c, window, gc, niko_masks, niko_images,
|
||||
ee->x, ee->y, ee->width, ee->height, niko_offset);
|
||||
xcb_flush(dpy->c);
|
||||
} break;
|
||||
}
|
||||
} else if (getticks() - ticks >= 1000 / 60) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Move niko
|
||||
niko_offset += 2;
|
||||
int new_y = y + niko_offset;
|
||||
if (new_y > dpy->screen->height_in_pixels)
|
||||
break;
|
||||
xcb_configure_window(dpy->c, window, XCB_CONFIG_WINDOW_Y, &new_y);
|
||||
draw_niko(dpy->c, window, gc, niko_masks, niko_images, 0, 0, NIKO_WIDTH, NIKO_HEIGHT, niko_offset);
|
||||
xcb_flush(dpy->c);
|
||||
ticks = getticks();
|
||||
}
|
||||
|
||||
// Free up stuff
|
||||
xcb_free_gc(dpy->c, gc);
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
xcb_free_pixmap(dpy->c, niko_masks[i]);
|
||||
xcb_free_pixmap(dpy->c, niko_images[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
|
|
@ -157,7 +157,7 @@ int do_journal()
|
|||
ShowWindow(window, SW_SHOWNOACTIVATE);
|
||||
UpdateWindow(window);
|
||||
|
||||
image_mutex = CreateMutexW(NULL, NULL, NULL);
|
||||
image_mutex = CreateMutexW(NULL, FALSE, NULL);
|
||||
HANDLE thread = CreateThread(NULL, 0, ipc_thread, NULL, 0, NULL);
|
||||
|
||||
// Dispatch messages
|
||||
Loading…
Reference in a new issue