Replace macOS journal implementation with the reimplementation

This commit is contained in:
Vinyl Darkscratch 2017-03-30 17:04:37 -07:00
parent 2d03bebd61
commit cb77de041b
83 changed files with 79 additions and 708 deletions

View file

@ -53,53 +53,7 @@ unix:!macx {
# OS X
macx {
# Directly copied from Linux, assuming this works but unsure
SOURCES += \
mac/main.c \
mac/niko.c \
mac/journal.c \
mac/image/niko1.c \
mac/image/niko2.c \
mac/image/niko3.c \
mac/image/default.c \
mac/image/c1.c \
mac/image/c2.c \
mac/image/c3.c \
mac/image/c4.c \
mac/image/c5.c \
mac/image/c6.c \
mac/image/c7.c \
mac/image/s1.c \
mac/image/s2.c \
mac/image/s3.c \
mac/image/s4.c \
mac/image/t1.c \
mac/image/t2.c \
mac/image/t3.c \
mac/image/t4.c \
mac/image/t5.c \
mac/image/t6.c \
mac/image/t7.c \
mac/image/t8.c \
mac/image/t9.c \
mac/image/t10.c \
mac/image/t11.c \
mac/image/t12.c \
mac/image/t13.c \
mac/image/t14.c \
mac/image/t15.c \
mac/image/t16.c \
mac/image/final.c \
mac/image/save.c
HEADERS += \
mac/display.h \
mac/image.h
QMAKE_CFLAGS += -pthread
LIBS += -pthread -lxcb -lxcb-util -lxcb-image -lxcb-shape -lxcb-icccm -lxcb-ewmh
}
# Windows

40
journal/mac/README.md Normal file
View file

@ -0,0 +1,40 @@
OneShot Journal
===============
This is a Linux- and macOS-compatible reimplementation of the Author's Journal, a element in the game [OneShot](http://oneshot-game.com).
Usage
-----
This journal requires Python 3.x and PyQt5 to run. On macOS or Debian/Ubuntu-based systems, install via one of the following commands:
brew install pyqt5 # macOS (Homebrew)
port install pyqt5 # macOS (MacPorts)
sudo apt-get install python3-pyqt5 # Ubuntu/Debian
This will install PyQt5 and all necessary files. Next, extract the images from the original OneShot journal program using the instructions in the following section, then use the following command to start the journal:
python3 journal.py
Start OneShot and play normally.
Building the app bundle
-----------------------
To create the macOS app bundle, PyInstaller is required. Install via one of the following commands:
brew install pyinstaller # macOS (Homebrew)
port install pyinstaller # macOS (MacPorts)
*Note: If you plan to use Python 3.6, at the time of this writing, the stable release (3.2.1) of PyInstaller only supports up to Python 3.5, however the [development build](http://www.pyinstaller.org/downloads.html) implements Python 3.6 support.*
Now that everything is installed, let's create our app bundle:
pyinstaller journal.spec --onefile --windowed
This should collect all the required runtime files and create the bundle in `dist/_______.app`.
Extracting the images
---------------------
First, aquire a copy of the Windows-version journal executable. Next, download [ResourcesExtract](http://www.nirsoft.net/utils/resources_extract.html) and run it, either via Wine or from a Windows install. Set the filename to the journal executable and the destination to the images directory in your local copy of this repo. Set the program to extract only bitmaps, then press Start. Once extraction completes run the included Python script `renameandconvert.py` (requires ImageMagick), which will create the required PNGs.

View file

@ -1,17 +0,0 @@
#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]))
#define STRING(x) sizeof(x) - 1, (x)
#define ARRAY(x) sizeof(x), (x)
#endif // DISPLAY_H

View file

@ -1,113 +0,0 @@
#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

View file

@ -1,12 +0,0 @@
#!/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"

View file

Before

Width:  |  Height:  |  Size: 183 KiB

After

Width:  |  Height:  |  Size: 183 KiB

View file

Before

Width:  |  Height:  |  Size: 234 KiB

After

Width:  |  Height:  |  Size: 234 KiB

View file

Before

Width:  |  Height:  |  Size: 288 KiB

After

Width:  |  Height:  |  Size: 288 KiB

View file

Before

Width:  |  Height:  |  Size: 218 KiB

After

Width:  |  Height:  |  Size: 218 KiB

View file

Before

Width:  |  Height:  |  Size: 267 KiB

After

Width:  |  Height:  |  Size: 267 KiB

View file

Before

Width:  |  Height:  |  Size: 216 KiB

After

Width:  |  Height:  |  Size: 216 KiB

View file

Before

Width:  |  Height:  |  Size: 289 KiB

After

Width:  |  Height:  |  Size: 289 KiB

View file

Before

Width:  |  Height:  |  Size: 430 B

After

Width:  |  Height:  |  Size: 430 B

View file

Before

Width:  |  Height:  |  Size: 269 KiB

After

Width:  |  Height:  |  Size: 269 KiB

View file

Before

Width:  |  Height:  |  Size: 519 B

After

Width:  |  Height:  |  Size: 519 B

View file

Before

Width:  |  Height:  |  Size: 510 B

After

Width:  |  Height:  |  Size: 510 B

View file

Before

Width:  |  Height:  |  Size: 520 B

After

Width:  |  Height:  |  Size: 520 B

View file

Before

Width:  |  Height:  |  Size: 265 KiB

After

Width:  |  Height:  |  Size: 265 KiB

View file

Before

Width:  |  Height:  |  Size: 250 KiB

After

Width:  |  Height:  |  Size: 250 KiB

View file

Before

Width:  |  Height:  |  Size: 227 KiB

After

Width:  |  Height:  |  Size: 227 KiB

View file

Before

Width:  |  Height:  |  Size: 360 KiB

After

Width:  |  Height:  |  Size: 360 KiB

View file

Before

Width:  |  Height:  |  Size: 548 KiB

After

Width:  |  Height:  |  Size: 548 KiB

View file

Before

Width:  |  Height:  |  Size: 250 KiB

After

Width:  |  Height:  |  Size: 250 KiB

View file

Before

Width:  |  Height:  |  Size: 248 KiB

After

Width:  |  Height:  |  Size: 248 KiB

View file

Before

Width:  |  Height:  |  Size: 246 KiB

After

Width:  |  Height:  |  Size: 246 KiB

View file

Before

Width:  |  Height:  |  Size: 118 KiB

After

Width:  |  Height:  |  Size: 118 KiB

View file

Before

Width:  |  Height:  |  Size: 133 KiB

After

Width:  |  Height:  |  Size: 133 KiB

View file

Before

Width:  |  Height:  |  Size: 150 KiB

After

Width:  |  Height:  |  Size: 150 KiB

View file

Before

Width:  |  Height:  |  Size: 206 KiB

After

Width:  |  Height:  |  Size: 206 KiB

View file

Before

Width:  |  Height:  |  Size: 110 KiB

After

Width:  |  Height:  |  Size: 110 KiB

View file

Before

Width:  |  Height:  |  Size: 224 KiB

After

Width:  |  Height:  |  Size: 224 KiB

View file

Before

Width:  |  Height:  |  Size: 258 KiB

After

Width:  |  Height:  |  Size: 258 KiB

View file

Before

Width:  |  Height:  |  Size: 224 KiB

After

Width:  |  Height:  |  Size: 224 KiB

View file

Before

Width:  |  Height:  |  Size: 100 KiB

After

Width:  |  Height:  |  Size: 100 KiB

View file

Before

Width:  |  Height:  |  Size: 326 KiB

After

Width:  |  Height:  |  Size: 326 KiB

View file

Before

Width:  |  Height:  |  Size: 174 KiB

After

Width:  |  Height:  |  Size: 174 KiB

View file

Before

Width:  |  Height:  |  Size: 252 KiB

After

Width:  |  Height:  |  Size: 252 KiB

View file

Before

Width:  |  Height:  |  Size: 207 KiB

After

Width:  |  Height:  |  Size: 207 KiB

View file

@ -1,235 +0,0 @@
#include <xcb/xcb_ewmh.h>
#include <xcb/xcb_icccm.h>
#include <pthread.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/inotify.h>
#include <unistd.h>
#include <string.h>
#include <limits.h>
#include "display.h"
#include "image.h"
#define PIPE_DIR "/tmp"
#define PIPE_NAME "oneshot-pipe"
#define PIPE_PATH PIPE_DIR "/" PIPE_NAME
#define MESSAGE_BUF_SIZE 256
#define PAGES \
PAGE(default) \
PAGE(c1) \
PAGE(c2) \
PAGE(c3) \
PAGE(c4) \
PAGE(c5) \
PAGE(c6) \
PAGE(c7) \
PAGE(s1) \
PAGE(s2) \
PAGE(s3) \
PAGE(s4) \
PAGE(t1) \
PAGE(t2) \
PAGE(t3) \
PAGE(t4) \
PAGE(t5) \
PAGE(t6) \
PAGE(t7) \
PAGE(t8) \
PAGE(t9) \
PAGE(t10) \
PAGE(t11) \
PAGE(t12) \
PAGE(t13) \
PAGE(t14) \
PAGE(t15) \
PAGE(t16) \
PAGE(final) \
PAGE(save)
struct ThreadData {
struct Display *dpy;
xcb_window_t window;
xcb_gcontext_t gc;
xcb_pixmap_t *masks;
xcb_pixmap_t *images;
volatile int page;
};
void set_page(struct ThreadData *threaddata, const char *name)
{
int page = 0;
#define PAGE(x) if (strncmp(name, #x, MESSAGE_BUF_SIZE) == 0) { goto end; } else { ++page; }
PAGES
#undef PAGE
end:
threaddata->page = page;
xcb_shape_mask(threaddata->dpy->c, ShapeSet, ShapeBounding,
threaddata->window, 0, 0, threaddata->masks[page]);
xcb_copy_area(threaddata->dpy->c,
threaddata->images[page],
threaddata->window,
threaddata->gc,
0, 0, 0, 0, JOURNAL_WIDTH, JOURNAL_HEIGHT);
xcb_flush(threaddata->dpy->c);
}
static void *ipc_thread(void *data)
{
struct ThreadData *threaddata = (struct ThreadData*)data;
for (;;) {
// Try to open pipe
int pipe = open(PIPE_PATH, O_RDONLY);
if (pipe == -1) {
// Use the default image for now
set_page(threaddata, "default");
// Wait until the pipe appears to try again
int inotify = inotify_init();
inotify_add_watch(inotify, PIPE_DIR, IN_CREATE);
char inotify_buf[sizeof(struct inotify_event) + NAME_MAX + 1];
for (;;) {
ssize_t result = read(inotify, inotify_buf, sizeof(inotify_buf));
if (result > 0) {
struct inotify_event *e = (struct inotify_event*)inotify_buf;
if (strcmp(e->name, PIPE_NAME) == 0)
break;
} else {
break;
}
}
close(inotify);
} else {
// Message loop
char message[MESSAGE_BUF_SIZE];
for (;;) {
ssize_t len = read(pipe, message, sizeof(message));
if (len > 0) {
set_page(threaddata, message);
} else if (len == 0) {
exit(0); // empty string
} else {
// End of the line
break;
}
}
close(pipe);
}
}
return NULL;
}
int do_journal(struct Display *dpy)
{
// Connect EWMH
xcb_ewmh_connection_t ewmh;
xcb_ewmh_init_atoms_replies(&ewmh, xcb_ewmh_init_atoms(dpy->c, &ewmh), NULL);
// Request some atoms
xcb_intern_atom_cookie_t WM_DELETE_WINDOW_cookie = xcb_intern_atom(dpy->c, false, STRING("WM_DELETE_WINDOW"));
xcb_intern_atom_cookie_t _NET_WM_PING_cookie = xcb_intern_atom(dpy->c, false, STRING("_NET_WM_PING"));
xcb_intern_atom_cookie_t WM_PROTOCOLS_cookie = xcb_intern_atom(dpy->c, false, STRING("WM_PROTOCOLS"));
xcb_atom_t WM_DELETE_WINDOW = xcb_intern_atom_reply(dpy->c, WM_DELETE_WINDOW_cookie, NULL)->atom;
xcb_atom_t _NET_WM_PING = xcb_intern_atom_reply(dpy->c, _NET_WM_PING_cookie, NULL)->atom;
xcb_atom_t WM_PROTOCOLS = xcb_intern_atom_reply(dpy->c, WM_PROTOCOLS_cookie, NULL)->atom;
// Create window
uint32_t values[] = {
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,
0, 0, JOURNAL_WIDTH, JOURNAL_HEIGHT,
0, XCB_WINDOW_CLASS_INPUT_OUTPUT, dpy->screen->root_visual,
XCB_CW_EVENT_MASK, &values);
xcb_atom_t protocols[] = {
WM_DELETE_WINDOW,
_NET_WM_PING,
};
xcb_icccm_set_wm_protocols(dpy->c, window, WM_PROTOCOLS, ARRAY(protocols));
xcb_icccm_set_wm_name(dpy->c, window, XCB_ATOM_STRING, 8, STRING(""));
xcb_icccm_set_wm_class(dpy->c, window, ARRAY("_______\0OneshotJournal"));
xcb_ewmh_set_wm_window_type(&ewmh, window, 1, &ewmh._NET_WM_WINDOW_TYPE_NORMAL);
xcb_size_hints_t size_hints;
xcb_icccm_size_hints_set_min_size(&size_hints, JOURNAL_WIDTH, JOURNAL_HEIGHT);
xcb_icccm_size_hints_set_max_size(&size_hints, JOURNAL_WIDTH, JOURNAL_HEIGHT);
xcb_icccm_set_wm_size_hints(dpy->c, window, XCB_ATOM_WM_NORMAL_HINTS, &size_hints);
// Create pixmaps
xcb_pixmap_t masks[] = {
#define PAGE(x) create_mask(dpy->c, window, x##_mask, JOURNAL_WIDTH, JOURNAL_HEIGHT),
PAGES
#undef PAGE
};
xcb_pixmap_t images[] = {
#define PAGE(x) create_image(dpy->c, window, x##_rgb, JOURNAL_WIDTH, JOURNAL_HEIGHT),
PAGES
#undef PAGE
};
// Create graphics context
xcb_gcontext_t gc = xcb_generate_id(dpy->c);
xcb_create_gc(dpy->c, gc, window, 0, NULL);
// Start IPC thread
struct ThreadData threaddata = {
dpy,
window,
gc,
masks,
images,
0,
};
pthread_t thread;
if (pthread_create(&thread, NULL, ipc_thread, &threaddata) != 0)
return 1;
// Map!
xcb_map_window(dpy->c, window);
xcb_flush(dpy->c);
// Handle events
xcb_generic_event_t *e;
while ((e = xcb_wait_for_event(dpy->c))) {
switch (e->response_type & ~0x80) {
case XCB_EXPOSE: {
xcb_expose_event_t *ee = (xcb_expose_event_t*)e;
xcb_copy_area(dpy->c, images[threaddata.page],
window, gc,
ee->x, ee->y, ee->x, ee->y,
ee->width, ee->height);
xcb_flush(dpy->c);
} break;
case XCB_CLIENT_MESSAGE: {
xcb_client_message_event_t *ce = (xcb_client_message_event_t*)e;
if (ce->type == WM_PROTOCOLS && ce->format == 32) {
xcb_atom_t atom = ce->data.data32[0];
if (atom == WM_DELETE_WINDOW) {
goto end;
} else if (atom == _NET_WM_PING) {
ce->window = dpy->screen->root;
xcb_send_event(dpy->c, false, dpy->screen->root,
XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT,
(const char*)e);
}
}
} break;
}
free(e);
}
end:
xcb_free_gc(dpy->c, gc);
for (size_t i = 0; i < ARRAY_SIZE(masks); ++i) {
xcb_free_pixmap(dpy->c, masks[i]);
xcb_free_pixmap(dpy->c, images[i]);
}
return 0;
}

View file

@ -1,3 +1,5 @@
# -*- coding: utf-8 -*-
import os
import sys
import time

37
journal/mac/journal.spec Normal file
View file

@ -0,0 +1,37 @@
# -*- mode: python -*-
block_cipher = None
a = Analysis(['journal.py'],
pathex=['.'],
binaries=[],
datas=[('images', 'images')],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
exclude_binaries=True,
name='_______',
debug=False,
strip=False,
upx=True,
console=False )
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
name='_______')
app = BUNDLE(coll,
name='_______.app',
icon='assets/icon_journal.icns',
bundle_identifier="APPL"
)

View file

@ -1,26 +0,0 @@
#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;
}

View file

@ -1,114 +0,0 @@
#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;
}
free(e);
} 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;
}

View file

@ -1,34 +0,0 @@
"""
This is a setup.py script generated by py2applet
Usage:
python3 setup-unix-remake.py py2app
"""
from setuptools import setup
APP = ['journal.py']
APP_NAME = "_______"
DATA_FILES = ["images"]
OPTIONS = {
'argv_emulation': True,
# 'plist': {
# 'CFBundleName': APP_NAME,
# 'CFBundleDisplayName': APP_NAME,
# 'CFBundleGetInfoString': "You only have one shot.",
# 'CFBundleIdentifier': 'com.oneshot-game.hunternet93.journal-remake',
# 'CFBundleVersion': '1.0',
# 'CFBundleShortVersionString': '1.0',
# 'LSApplicationCategoryType': 'public.app-category.games',
# 'LSMinimumSystemVersion': '10.7',
# 'NSHumanReadableCopyright': u"Copyright © 2017, hunternet93 and Vinyl Darkscratch, MIT License. https://github.com/hunternet93/OneShot-Journal"
# }
}
setup(
name=APP_NAME,
app=APP,
data_files=DATA_FILES,
options={'py2app': OPTIONS},
setup_requires=['py2app'],
)

View file

@ -1,89 +0,0 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover
.hypothesis/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# IPython Notebook
.ipynb_checkpoints
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# dotenv
.env
# virtualenv
venv/
ENV/
# Spyder project settings
.spyderproject
# Rope project settings
.ropeproject

View file

@ -1,22 +0,0 @@
OneShot Journal
===============
This is a Linux-compatible reimplementation of the Author's Journal, a element in the game [OneShot](http://oneshot-game.com).
Usage
-----
This journal requires PyQt5 to run. On Debian/Ubuntu-based systems, install via the following command:
sudo apt-get install python3-pyqt5
This will install PyQt5 and all necessary files. Next, extract the images from the original OneShot journal program using the instructions in the following section, then use the following command to start the journal:
python3 journal.py
Start OneShot and play normally.
Extracting the images
---------------------
First, aquire a copy of the Windows-version journal executable. Next, download [ResourcesExtract](http://www.nirsoft.net/utils/resources_extract.html) and run it, either via Wine or from a Windows install. Set the filename to the journal executable and the destination to the images directory in your local copy of this repo. Set the program to extract only bitmaps, then press Start. Once extraction completes run the included Python script `renameandconvert.py` (requires ImageMagick), which will create the required PNGs.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 183 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 234 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 288 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 218 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 267 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 216 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 289 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 430 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 269 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 519 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 510 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 520 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 265 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 250 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 227 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 360 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 548 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 250 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 248 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 246 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 206 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 224 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 258 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 224 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 326 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 174 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 252 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 207 KiB