Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
desertkun committed Jul 23, 2021
0 parents commit ee06f18
Show file tree
Hide file tree
Showing 163 changed files with 8,980 additions and 0 deletions.
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/hub/bin/
/hub/cmake-build-debug/
/client/bin/
/client/include/spectranet
/client/libs/
*.o
*_p.asm
*_np.asm
*.lib
deployment.xml
9 changes: 9 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[submodule "hub/json"]
path = hub/json
url = https://github.com/nlohmann/json.git
[submodule "hub/img2spec"]
path = hub/img2spec
url = https://github.com/the-channels/img2spec.git
[submodule "hub/cpr"]
path = hub/cpr
url = https://github.com/whoshuu/cpr.git
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2021 desertkun

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
79 changes: 79 additions & 0 deletions Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
![image](https://user-images.githubusercontent.com/1666014/126013799-b499d24f-88e2-42b0-8d3d-c77991c4f9ac.png)

ZX Spectrum client for imageboards.

https://user-images.githubusercontent.com/1666014/126671608-02e74708-55c7-4141-b330-0c9b010e1c9d.mov

## Requirements
* Because speccy does not support any internet connectivity by default, you'll need [Spectranet Cartridge](https://www.bytedelight.com/?page_id=3515). It may be pricey and hard to get, but please support the manufacturer as it's a very Niche product.
* [Fuse Enumator](http://fuse-emulator.sourceforge.net/) supports such cartrige, you'll just need to enable it via "Peripherials->Spectranet" radio button

## To Do List
1. Refactor img2spec tool and split display and processing logic in separate static
library with no executable
2. Ability to save settings
3. Tracking and showing replies to particular post
4. Posting
5. Optimize font rendering speed
6. Cleanup cache after certain timeout
7. Cache the transcoded images and not only originals

## Channels Hub
Because speccy is nowhere near as powerful for SSL, you need an intermediate proxy to preprocess the data.
A special proxy called Hub (`hub/` folder) is supposed to be run somewhere on your local network, e.g. a PC, a router, a raspberry PI etc.

* This proxy does all the heavy lifting, like image spectrumisation (with help of [img2spec](https://github.com/the-channels/img2spec) tool)
* The proxy implements a set of Channels (like a channel for 4chan) and facilitates external calls to provide a standartized API for each channel
* The client doesn't even care what channels are, as long as they use the same API, so potential of having the client to browse pretty much anything is limitless, as long as you have boards (or categories, you can just have one) and a set of conversations (threads) with each thread having posts.

## Channels Proto
A client and the hub communicate via a special protocol, as described in [this document](./proto/Readme.md).

## How to build from source
* The Hub is simply compiled using CMake.
* Take care to fetch all submodules.
* The Client uses Makefiles and can only be compiled using [z88dk](https://github.com/z88dk/z88dk)
* You'd need UNIX to compile the client, so for Windows, you would need to use WSL
* Having all that done, then simply shoot `make`
* While it's included in this repository,
you may refer to [spectranet dev library and headers](https://github.com/spectrumero/spectranet)

##### Windows
* You need a copy of [SDL2 Development Libraries](https://www.libsdl.org/download-2.0.php), copied into `SDL2` folder next to this repository.
The runtime library is actually included in this repository.

##### Mac Os X
* You need a copy of [SDL2 Development Libraries](https://www.libsdl.org/download-2.0.php) from inside of the .dmg file (`SDL2.framework`), copied to `/Library/Frameworks`.

##### Linux
Install these:
```bash
sudo apt-get update
sudo apt-get install -y \
gcc \
git \
g++ \
libgtk-3-0 gtk+-3.0 \
gcc-multilib \
g++-multilib \
build-essential \
xutils-dev \
libssl-dev \
libsdl2-dev \
libsdl2-gfx-dev \
libsdl2-image-dev \
libsdl2-mixer-dev \
libsdl2-net-dev \
libsdl2-ttf-dev \
libreadline6-dev \
libncurses5-dev \
mingw-w64 \
cmake
```
Proceed with cmake as usual.

## Debugging
* The only way to debug is to use netlog, a printf-alike function that
sends printed text to UDP port 9468 on the same host as proxy.
* To see these logs on Linux/Mac, simply do `make listen-for-logs` while
on Windows, you'd need to install netcat and do `nc -lLu -w 1 -p 9468`.
8 changes: 8 additions & 0 deletions client/.idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 25 additions & 0 deletions client/.idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions client/.idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions client/.idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

100 changes: 100 additions & 0 deletions client/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
ROOT_DIR:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))

JUST_PRINT := $(findstring n,$(MAKEFLAGS))
TARGET := sccz80
NETWORK_ENGINE:="spectranet"

COMMON_LIBS = -llibsocket -llibspectranet
INCLUDE_PATH = /usr/local/share/z88dk/include
BIN_NAME = channels__.bin

channels_OUT = bin/channels
ifneq (,$(JUST_PRINT))
PHONY_OBJS := yes
CC = gcc
CFLAGS += -I$(ROOT_DIR)/include/spectranet -I$(INCLUDE_PATH) -I$(ROOT_DIR)/include -I$(ROOT_DIR)/gui -I$(ROOT_DIR)/netlog -I$(ROOT_DIR)/../proto -D__FASTCALL__="" \
-DCHANNELS_PROTO_CLIENT="1" -D__CALLEE__="" -D__SCCZ80="1" -D__SPECTRUM="1" -D__Z80="1" -D__z88dk_callee="" -D__z88dk_fastcall="" -D__preserves_regs="" -D__LIB__="" -D__no_z88dk_declspec="1"
else
CC = zcc
CFLAGS += -I$(ROOT_DIR)/include/spectranet -L$(ROOT_DIR)/libs -I$(INCLUDE_PATH) -SO3 -I$(ROOT_DIR)/include -I$(ROOT_DIR)/gui -I$(ROOT_DIR)/netlog -I$(ROOT_DIR)/../proto -DCHANNELS_PROTO_CLIENT="1"
ZXFLAGS = +zx
channels_CFLAGS = -m -zorg=25000 -pragma-redirect=CRT_FONT_64=_fake_CRT_FONT_64 -pragma-include:zpragma.inc -L/usr/local/share/z88dk/lib/clibs $(COMPILER_LIBS) $(COMMON_LIBS) -create-app $(SUBTYPE)
endif

ifeq ($(NETWORK_ENGINE), "spectranet")
CFLAGS += -D__SPECTRANET="1"
endif

SOURCES := $(wildcard src/*.c gui/*.c netlog/*.c ../proto/channels_proto.c ../proto/proto_objects.c)
OBJECTS = $(SOURCES:.c=.o)

all: bin/channels.tap

libs:
@mkdir -p libs

include/spectranet:
@mkdir -p include/spectranet

libs/libsocket.lib: libs include/spectranet
make DESTLIBS=$(ROOT_DIR)/libs DESTINCLUDE=$(ROOT_DIR)/include/spectranet -C spectranet/socklib plib install

libs/libspectranet.lib: libs include/spectranet
make DESTLIBS=$(ROOT_DIR)/libs DESTINCLUDE=$(ROOT_DIR)/include/spectranet -C spectranet/libspectranet plib install

spectranet-libraries: libs/libsocket.lib libs/libspectranet.lib

bin/channels.tap: spectranet-libraries bin $(OBJECTS)
$(CC) $(ZXFLAGS) $(CFLAGS) -o $(channels_OUT) $(channels_CFLAGS) $(OBJECTS)

bin/channels__.bin: spectranet-libraries bin $(OBJECTS)
$(CC) $(ZXFLAGS) $(CFLAGS) -o $(channels_OUT) $(channels_CFLAGS) $(OBJECTS) -subtype=bin

%.o: %.c
$(CC) $(ZXFLAGS) $(CFLAGS) -c -o $@ $<

bin:
@mkdir -p bin

channels-bin: bin/channels__.bin

boot-zx: channels-bin
cp boot/boot.zx bin/boot.zx

deploy: channels-bin boot-zx
cp bin/channels__.bin bin/channels
ifeq ($(CHANNELS_DEPLOY_TO),)
@echo "Please define CHANNELS_DEPLOY_TO"
else
scp bin/channels__.bin $(CHANNELS_DEPLOY_TO):~/tnfsd/channels
scp bin/boot.zx $(CHANNELS_DEPLOY_TO):~/tnfsd/boot.zx
endif

tnfsd: channels-bin
tnfsd $(ROOT_DIR)/bin

run: bin/channels.tap
open bin/channels.tap

listen-for-logs:
@nc -kluvw 0 9468

get-size:
@cat bin/channels.map | sed -n "s/^\\([a-zA-Z0-9_]*\\).*= .\([A-Z0-9]*\) ; addr.*/\2,\1/p" | sort | python3 tools/symbol_sizes.py

clean:
make -C spectranet/socklib clean
make -C spectranet/libspectranet clean
@rm -f bin/channels*
@rm -f src/*.o
@rm -rf include/spectranet
@rm -f libs/*.lib
@rm -f gui/*.o
@rm -f log/*.o
@rm -f channels_proto/*.o

ifeq ($(PHONY_OBJS),yes)
.PHONY: $(SOURCES)
endif

.PHONY: channels clean run deploy listen-for-logs get-size
Binary file added client/boot/boot.zx
Binary file not shown.
1 change: 1 addition & 0 deletions client/files.lst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
src/zx/main.c
59 changes: 59 additions & 0 deletions client/gui/tiles.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@

/* png2c.py 1.4.3
*
* tiles.png (64x64)
* 8.0 x 8.0 (46 unique)
*
* base: 128
*/

#define TILES_BASE 128
#define TILES_LEN 46
static uchar tiles[] = {
0xd0, 0xd0, 0xd0, 0xd0, 0xdf, 0xc0, 0xff, 0xff, // y:0, x:0 (128)
0x0b, 0x0b, 0x0b, 0x0b, 0xfb, 0x03, 0xff, 0xff, // y:0, x:1 (129)
0xff, 0xff, 0x03, 0xfb, 0x0b, 0x0b, 0x0b, 0x0b, // y:0, x:2 (130)
0xff, 0xff, 0xc0, 0xdf, 0xd0, 0xd0, 0xd0, 0xd0, // y:0, x:3 (131)
0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, // y:0, x:4 (132)
0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, // y:0, x:5 (133)
0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0xff, // y:0, x:6 (134)
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, // y:0, x:7 (135)
0x00, 0x10, 0x00, 0x10, 0x0a, 0x00, 0x00, 0x00, // y:1, x:0 (136)
0x08, 0x00, 0x08, 0x00, 0xa8, 0x00, 0x00, 0x00, // y:1, x:1 (137)
0x00, 0x00, 0x00, 0x50, 0x08, 0x00, 0x08, 0x00, // y:1, x:2 (138)
0x00, 0x00, 0x00, 0x15, 0x00, 0x10, 0x00, 0x10, // y:1, x:3 (139)
0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, // y:1, x:4 (140)
0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, // y:1, x:5 (141)
0x00, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, // y:1, x:6 (142)
0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, // y:1, x:7 (143)
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // y:2, x:0 (144)
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // y:2, x:1 (145)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, // y:2, x:2 (146)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // y:2, x:3 (147)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, // y:2, x:4 (148)
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // y:2, x:5 (149)
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // y:2, x:6 (150)
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // y:2, x:7 (151)
0x00, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x00, // y:3, x:0 (152)
0xff, 0xe9, 0xc9, 0x81, 0x81, 0xcf, 0xef, 0xff, // y:3, x:1 (153)
0xff, 0xff, 0xc3, 0xdf, 0xdf, 0xc3, 0xff, 0xff, // y:3, x:2 (154)
0x00, 0x03, 0x0f, 0x0c, 0x18, 0x18, 0x7e, 0x3c, // y:3, x:3 (155)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, // y:3, x:4 (156)
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // y:3, x:5 (157)
0x3c, 0x7e, 0x18, 0x18, 0x30, 0xf0, 0xc0, 0x00, // y:3, x:6 (158)
0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, // y:3, x:7 (159)
0x00, 0x40, 0xc0, 0xf0, 0xfc, 0xcc, 0x46, 0x06, // y:4, x:0 (160)
0x60, 0x62, 0x33, 0x3f, 0x0f, 0x03, 0x02, 0x00, // y:4, x:1 (161)
0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, // y:4, x:2 (162)
0xff, 0xff, 0xff, 0xff, 0xff, 0xbd, 0x81, 0xff, // y:4, x:3 (163)
0x00, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, // y:4, x:4 (164)
0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x00, // y:4, x:5 (165)
0xff, 0xff, 0xc3, 0xdb, 0xc3, 0xdf, 0xff, 0xff, // y:4, x:6 (166)
0x00, 0x00, 0x03, 0x07, 0x0e, 0x0c, 0x00, 0x00, // y:4, x:7 (167)
0x00, 0x00, 0xc0, 0xe0, 0x70, 0x30, 0x30, 0x70, // y:5, x:0 (168)
0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, // y:5, x:1 (169)
0xe0, 0xc0, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, // y:5, x:2 (170)
0xff, 0xe7, 0xdf, 0xc7, 0xdb, 0xdb, 0xe7, 0xff, // y:5, x:3 (171)
0xff, 0xc7, 0xfb, 0xfb, 0xf7, 0xef, 0xef, 0xff, // y:5, x:4 (172)
};

43 changes: 43 additions & 0 deletions client/gui/zxanimated_icon.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#include <string.h>
#include "zxgui.h"
#include "zxgui_internal.h"
#include "system.h"

static void icon_render(uint8_t x, uint8_t y, struct gui_animated_icon_t* this, struct gui_scene_t* scene)
{
x += this->x;
y += this->y;

if (++this->time)
{
return;
}

this->time = 0;
this->current_frame++;
if (this->current_frame >= this->frames)
{
this->current_frame = 0;
}

zxgui_icon(this->color, x, y, this->w, this->h,
this->source + this->current_frame * this->w * this->h);
}

void zxgui_animated_icon_init(struct gui_animated_icon_t* icon, uint8_t x, uint8_t y, uint8_t w, uint8_t h,
uint8_t frames, uint8_t color, const uint8_t* source)
{
icon->render = (gui_render_f)icon_render;
icon->event = NULL;
icon->flags = GUI_FLAG_DIRTY;
icon->next = NULL;
icon->color = color;
icon->x = x;
icon->y = y;
icon->w = w;
icon->h = h;
icon->frames = frames;
icon->current_frame = 0;
icon->time = 0;
icon->source = source;
}

0 comments on commit ee06f18

Please sign in to comment.