diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ca1eb22 --- /dev/null +++ b/Makefile @@ -0,0 +1,27 @@ +PROJECT_NAME := "alchemyst-go" +PKG := "lab.zaar.be/thefish/$(PROJECT_NAME)" +GO=$(shell which go) +CWD=$(shell pwd) +GLIDE=$(shell which glide) + +LDFLAGS="-X \"main.versionInfo=${PKG_VER}-${CI_PIPELINE_ID} built at $(shell date) on $(shell hostname) with $(shell go version)\"" + +.PHONY: all build test get-dep + +all: build test + +#build: build.spec build.server +build: build.server + +#build.spec: +# $(CWD)/bin/oapi-codegen --generate types,spec -o $(CWD)/api/inner/inner.gen.go $(CWD)/public/schema/api.yaml + +build.server: + $(GO) build -ldflags $(LDFLAGS) -o $(CWD)/bin/game $(CWD)/cmd/main.go + +test: + $(GO) test -v $(go list ./... | grep -v /vendor/) + +get-dep: + GIT_SSL_NO_VERIFY=true go mod vendor + diff --git a/cmd/game/main.go b/cmd/game/main.go new file mode 100644 index 0000000..866061b --- /dev/null +++ b/cmd/game/main.go @@ -0,0 +1,65 @@ +package main + +import ( + "github.com/rs/zerolog" + "github.com/rs/zerolog/log" + "lab.zaar.be/thefish/alchemyst-go/ui" + "lab.zaar.be/thefish/alchemyst-go/ui/mainwindow" + "lab.zaar.be/thefish/alchemyst-go/util" + blt "lab.zaar.be/thefish/bearlibterminal" + "os" + "time" +) + +func main() { + + config := util.LoadConfig() + + //var logLevels = map[string]zerolog.Level{"debug": zerolog.DebugLevel, "info": zerolog.InfoLevel, "warn": zerolog.WarnLevel} + //var logger = log.Output(zerolog.ConsoleWriter{Out: os.Stdout, TimeFormat: time.RFC3339}).Level(logLevels[opts.Verbosity]) + var logger = log.Output(zerolog.ConsoleWriter{Out: os.Stdout, TimeFormat: time.RFC3339}) + + mainCtx := util.NewClientContext(config, &logger) + + log.Info().Msg("Starting...") + + defer mainwindow.Shutdown(mainCtx) + + mainwindow.Init(mainCtx) + + blt.Print(1, 1, "Hello, [font=italic]world[/font]!") + blt.Print(1, 4, "Testing line-spacing") + blt.PrintExt(1, 6, 5, 4, 1, "Lorem ipsum dolor sit amet") + blt.Refresh() + + mainLoop(mainCtx) +} + +func mainLoop(ctx util.ClientCtx) { + + var exit = false + + for !exit { + var key, keycode = ui.ReadKey(ctx) + if key != "" { + blt.ClearArea(0, 3, 80, 1) + } + switch key { + case "F10": + blt.Set("window: size=100x47; font: ./resources/fonts-ttf/UbuntuMono-R.ttf, size=10;") + case "Ctrl+q": + fallthrough + case "Escape": + exit = true + default: + blt.Print(1, 3, "Key: "+key) + } + + if keycode == blt.TK_CLOSE { + exit = true + } + + blt.Refresh() + } + +} diff --git a/config.json b/config.json index 9e0a9d3..5e30eac 100644 --- a/config.json +++ b/config.json @@ -1,4 +1,7 @@ { + "version": "0.0.0.1", "title" : "Test Go+BLT App", + "sizeX": 100, + "sizeY": 47, "fpsLimit" : 60 } \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..02e6de2 --- /dev/null +++ b/go.mod @@ -0,0 +1,8 @@ +module lab.zaar.be/thefish/alchemyst-go + +go 1.12 + +require ( + github.com/rs/zerolog v1.15.0 + lab.zaar.be/thefish/bearlibterminal v0.0.0-20191017122032-d103ac97db64 +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..6c6c321 --- /dev/null +++ b/go.sum @@ -0,0 +1,14 @@ +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= +github.com/rs/zerolog v1.15.0 h1:uPRuwkWF4J6fGsJ2R0Gn2jB1EQiav9k3S6CSdygQJXY= +github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= +github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +lab.zaar.be/thefish/bearlibterminal v0.0.0-20191017122032-d103ac97db64 h1:cz/z5Mxo1ZK4HQi8qrSozTJvHnzqjMdvq5zi8PAORu8= +lab.zaar.be/thefish/bearlibterminal v0.0.0-20191017122032-d103ac97db64/go.mod h1:tV7Vxx6vf9dPgj9B+RPeSrmtRl8nTSH07HIyBSSnEc4= diff --git a/main.go b/main.go deleted file mode 100644 index c0d37f4..0000000 --- a/main.go +++ /dev/null @@ -1,64 +0,0 @@ -package main - -import "log" -import ( - blt "bearlibterminal" - "ui" - "util" -) - -var version = "0.0.0" - -func main() { - defer shutdown() - log.Println("Starting...") - - config := util.LoadConfig() - - blt.Open() - //blt.Set("window: size=80x25, title="+config.Title+" v"+string(version)+"; font: ./fonts/Monaco-Linux.ttf, size=10") - blt.Set("window: size=100x47, title="+config.Title+" v"+string(version)+"; font: ./resources/fonts-bitmap/ibmnew8x12.png, size=8x12;") - - blt.Print(1, 1, "Hello, [font=italic]world[/font]!") - blt.Print(1, 4, "Testing line-spacing") - blt.PrintExt(1, 6, 5, 4, 1, "Lorem ipsum dolor sit amet") - blt.Refresh() - - mainLoop() -} - -func mainLoop () { - - var exit = false - - for !exit { - var key, keycode = ui.ReadKey() - if key != "" { - blt.ClearArea(0,3, 80, 1) - } - switch key { - case "F10": - blt.Set("window: size=100x47; font: ./resources/fonts-ttf/UbuntuMono-R.ttf, size=10;") - case "Ctrl+q": - fallthrough - case "Escape": - exit = true - default: - blt.Print( 1, 3, "Key: " + key ) - } - - if keycode ==blt.TK_CLOSE { - exit = true - } - - blt.Refresh() - } - -} - -func shutdown() { - - log.Println("Here we must save state, but it is not done yet") - log.Println("Exiting application...") - blt.Close() -} \ No newline at end of file diff --git a/src/bearlibterminal/BearLibTerminal.go b/src/bearlibterminal/BearLibTerminal.go deleted file mode 100644 index 099dd61..0000000 --- a/src/bearlibterminal/BearLibTerminal.go +++ /dev/null @@ -1,392 +0,0 @@ -/* -* BearLibTerminal -* Copyright (C) 2016-2017 Joe "ZhayTee" Toscano, Cfyz -* -* 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. - */ - -package bearlibterminal - -// #cgo LDFLAGS: -L. -Wl,-rpath -Wl,./ -lBearLibTerminal -// #include -// #include -import "C" - -import ( - "unsafe" -) - -// compile with go build -o test -// check relative path with objdump -p test | grep RPATH -// must be: RPATH ./ -// make sure that .so is globally visible during development! -// in ubunutu: $ sudo echo "/path/to/libbearterminal.so" > /etc/ld.so.conf.d/libbearterminal.conf && sudo ldconfig -// when development is complete, just $ sudo rm /etc/ld.so.conf.d/libbearterminal.conf -// compiled binaties must still work in same folder with .so - -// -// Keyboard scancodes for events/states -// -const ( - TK_NONE = 0x00 - TK_A = 0x04 - TK_B = 0x05 - TK_C = 0x06 - TK_D = 0x07 - TK_E = 0x08 - TK_F = 0x09 - TK_G = 0x0A - TK_H = 0x0B - TK_I = 0x0C - TK_J = 0x0D - TK_K = 0x0E - TK_L = 0x0F - TK_M = 0x10 - TK_N = 0x11 - TK_O = 0x12 - TK_P = 0x13 - TK_Q = 0x14 - TK_R = 0x15 - TK_S = 0x16 - TK_T = 0x17 - TK_U = 0x18 - TK_V = 0x19 - TK_W = 0x1A - TK_X = 0x1B - TK_Y = 0x1C - TK_Z = 0x1D - TK_1 = 0x1E - TK_2 = 0x1F - TK_3 = 0x20 - TK_4 = 0x21 - TK_5 = 0x22 - TK_6 = 0x23 - TK_7 = 0x24 - TK_8 = 0x25 - TK_9 = 0x26 - TK_0 = 0x27 - TK_RETURN = 0x28 - TK_ENTER = 0x28 - TK_ESCAPE = 0x29 - TK_BACKSPACE = 0x2A - TK_TAB = 0x2B - TK_SPACE = 0x2C - TK_MINUS = 0x2D /* - */ - TK_EQUALS = 0x2E /* = */ - TK_LBRACKET = 0x2F /* [ */ - TK_RBRACKET = 0x30 /* ] */ - TK_BACKSLASH = 0x31 /* \ */ - TK_SEMICOLON = 0x33 /* ; */ - TK_APOSTROPHE = 0x34 /* ' */ - TK_GRAVE = 0x35 /* ` */ - TK_COMMA = 0x36 /* , */ - TK_PERIOD = 0x37 /* . */ - TK_SLASH = 0x38 /* / */ - TK_F1 = 0x3A - TK_F2 = 0x3B - TK_F3 = 0x3C - TK_F4 = 0x3D - TK_F5 = 0x3E - TK_F6 = 0x3F - TK_F7 = 0x40 - TK_F8 = 0x41 - TK_F9 = 0x42 - TK_F10 = 0x43 - TK_F11 = 0x44 - TK_F12 = 0x45 - TK_PAUSE = 0x48 /* Pause/Break */ - TK_INSERT = 0x49 - TK_HOME = 0x4A - TK_PAGEUP = 0x4B - TK_DELETE = 0x4C - TK_END = 0x4D - TK_PAGEDOWN = 0x4E - TK_RIGHT = 0x4F /* Right arrow */ - TK_LEFT = 0x50 /* Left arrow */ - TK_DOWN = 0x51 /* Down arrow */ - TK_UP = 0x52 /* Up arrow */ - TK_KP_DIVIDE = 0x54 /* '/' on numpad */ - TK_KP_MULTIPLY = 0x55 /* '*' on numpad */ - TK_KP_MINUS = 0x56 /* '-' on numpad */ - TK_KP_PLUS = 0x57 /* '+' on numpad */ - TK_KP_ENTER = 0x58 - TK_KP_1 = 0x59 - TK_KP_2 = 0x5A - TK_KP_3 = 0x5B - TK_KP_4 = 0x5C - TK_KP_5 = 0x5D - TK_KP_6 = 0x5E - TK_KP_7 = 0x5F - TK_KP_8 = 0x60 - TK_KP_9 = 0x61 - TK_KP_0 = 0x62 - TK_KP_PERIOD = 0x63 /* '.' on numpad */ - TK_SHIFT = 0x70 - TK_CONTROL = 0x71 - TK_ALT = 0x72 -) - -// -// Mouse events/states -// -const ( - TK_MOUSE_LEFT = 0x80 /* Buttons */ - TK_MOUSE_RIGHT = 0x81 - TK_MOUSE_MIDDLE = 0x82 - TK_MOUSE_X1 = 0x83 - TK_MOUSE_X2 = 0x84 - TK_MOUSE_MOVE = 0x85 /* Movement event */ - TK_MOUSE_SCROLL = 0x86 /* Mouse scroll event */ - TK_MOUSE_X = 0x87 /* Cusor position in cells */ - TK_MOUSE_Y = 0x88 - TK_MOUSE_PIXEL_X = 0x89 /* Cursor position in pixels */ - TK_MOUSE_PIXEL_Y = 0x8A - TK_MOUSE_WHEEL = 0x8B /* Scroll direction and amount */ - TK_MOUSE_CLICKS = 0x8C /* Number of consecutive clicks */ -) - -// -// If key was released instead of pressed, it's code will be OR'ed with TK_KEY_RELEASED: -// a) pressed 'A': 0x04 -// b) released 'A': 0x04|VK_KEY_RELEASED = 0x104 -// -const TK_KEY_RELEASED = 0x100 - -// -// Virtual key-codes for internal terminal states/variables. -// These can be accessed via terminal_state function. -// -const ( - TK_WIDTH = 0xC0 /* Terminal window size in cells */ - TK_HEIGHT = 0xC1 - TK_CELL_WIDTH = 0xC2 /* Character cell size in pixels */ - TK_CELL_HEIGHT = 0xC3 - TK_COLOR = 0xC4 /* Current foregroung color */ - TK_BKCOLOR = 0xC5 /* Current background color */ - TK_LAYER = 0xC6 /* Current layer */ - TK_COMPOSITION = 0xC7 /* Current composition state */ - TK_CHAR = 0xC8 /* Translated ANSI code of last produced character */ - TK_WCHAR = 0xC9 /* Unicode codepoint of last produced character */ - TK_EVENT = 0xCA /* Last dequeued event */ - TK_FULLSCREEN = 0xCB /* Fullscreen state */ -) - -// -// Other events -// -const ( - TK_CLOSE = 0xE0 - TK_RESIZED = 0xE1 -) - -// -// Generic mode enum. -// Right now it is used for composition option only. -// -const ( - TK_OFF = 0 - TK_ON = 1 -) - -// -// Input result codes for terminal_read function. -// -const ( - TK_INPUT_NONE = 0 - TK_INPUT_CANCELLED = -1 -) - -const ( - TK_ALIGN_DEFAULT = 0 - TK_ALIGN_LEFT = 1 - TK_ALIGN_RIGHT = 2 - TK_ALIGN_CENTER = 3 - TK_ALIGN_TOP = 4 - TK_ALIGN_BOTTOM = 8 - TK_ALIGN_MIDDLE = 12 -) - -// -// Initialization and configuration -// - -func Open() int { - return int(C.terminal_open()) -} - -func Close() { - C.terminal_close() -} - -func Set(value string) int { - cstring := C.CString(value) - defer C.free(unsafe.Pointer(cstring)) - return int(C.terminal_set(cstring)) -} - -// -// Output state -// - -func Color(color uint32) { - C.terminal_color(C.color_t(color)) -} - -func BkColor(color uint32) { - C.terminal_bkcolor(C.color_t(color)) -} - -func Composition(mode int) { - C.terminal_composition(C.int(mode)) -} - -func Layer(index int) { - C.terminal_layer(C.int(index)) -} - -func Font(name string) { - cstring := C.CString(name) - defer C.free(unsafe.Pointer(cstring)) - C.terminal_font(cstring) -} - -// -// Output -// - -func Clear() { - C.terminal_clear() -} - -func ClearArea(x, y, w, h int) { - C.terminal_clear_area(C.int(x), C.int(y), C.int(w), C.int(h)) -} - -func Crop(x, y, w, h int) { - C.terminal_crop(C.int(x), C.int(y), C.int(w), C.int(h)) -} - -func Refresh() { - C.terminal_refresh() -} - -func Put(x, y, code int) { - C.terminal_put(C.int(x), C.int(y), C.int(code)) -} - -func Pick(x, y, index int) int { - return int(C.terminal_pick(C.int(x), C.int(y), C.int(index))) -} - -func PickColor(x, y, index int) uint32 { - val := C.terminal_pick_color(C.int(x), C.int(y), C.int(index)) - return uint32(val) -} - -func PickBkColor(x, y int) uint32 { - val := C.terminal_pick_bkcolor(C.int(x), C.int(y)) - return uint32(val) -} - -func PutExt(x, y, dx, dy, code int, corners [4]uint32) { - var cornerColors [4]C.color_t - for i := 0; i < 4; i++ { - cornerColors[i] = C.color_t(corners[i]) - } - - C.terminal_put_ext(C.int(x), C.int(y), C.int(dx), C.int(dy), C.int(code), &cornerColors[0]) -} - -func PrintExt(x, y, w, h, alignment int, s string) (width, height int) { - cstring := C.CString(s) - defer C.free(unsafe.Pointer(cstring)) - sz := C.terminal_print_ext(C.int(x), C.int(y), C.int(w), C.int(h), C.int(alignment), cstring) - return int(sz.width), int(sz.height) -} - -func Print(x, y int, s string) (width, height int) { - return PrintExt(x, y, 0, 0, TK_ALIGN_DEFAULT, s) -} - -func MeasureExt(w, h int, s string) (width, height int) { - cstring := C.CString(s) - defer C.free(unsafe.Pointer(cstring)) - sz := C.terminal_measure_ext(C.int(w), C.int(h), cstring) - return int(sz.width), int(sz.height) -} - -func Measure(s string) (width, height int) { - return MeasureExt(0, 0, s) -} - -// -// Input -// - -func State(code int) int { - return int(C.terminal_state(C.int(code))) -} - -func Check(code int) int { - return int(C.terminal_check(C.int(code))) -} - -func HasInput() bool { - result := int(C.terminal_has_input()) - return result > 0 -} - -func Read() int { - return int(C.terminal_read()) -} - -func Peek() int { - return int(C.terminal_peek()) -} - -func ReadStr(x, y int, max int) (int, string) { - cstring := C.CString("") - defer C.free(unsafe.Pointer(cstring)) - result := int(C.terminal_read_str(C.int(x), C.int(y), cstring, C.int(max))) - return result, C.GoString(cstring) -} - -func Delay(period int) { - C.terminal_delay(C.int(period)) -} - -func Get(key, defaultValue string) string { - cstringKey := C.CString(key) - defer C.free(unsafe.Pointer(cstringKey)) - cstringDefaultValue := C.CString(defaultValue) - defer C.free(unsafe.Pointer(cstringDefaultValue)) - result := C.terminal_get(cstringKey, cstringDefaultValue) - return C.GoString(result) -} - -func ColorFromName(name string) uint32 { - cstring := C.CString(name) - defer C.free(unsafe.Pointer(cstring)) - val := C.color_from_name(cstring) - return uint32(val) -} - -func ColorFromARGB(a, r, g, b uint8) uint32 { - val := C.color_from_argb(C.uint8_t(a), C.uint8_t(r), C.uint8_t(g), C.uint8_t(b)) - return uint32(val) -} diff --git a/src/bearlibterminal/BearLibTerminal.h b/src/bearlibterminal/BearLibTerminal.h deleted file mode 100644 index 0fb46fa..0000000 --- a/src/bearlibterminal/BearLibTerminal.h +++ /dev/null @@ -1,765 +0,0 @@ -/* -* BearLibTerminal -* Copyright (C) 2013-2017 Cfyz -* -* 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. -*/ - -#ifndef BEARLIBTERMINAL_H -#define BEARLIBTERMINAL_H - -#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) -#define _CRT_SECURE_NO_WARNINGS -#endif - -#ifdef __GNUC__ -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 1) -#pragma GCC diagnostic ignored "-Wformat-nonliteral" /* False-positive when wrapping vsnprintf. */ -#endif /* __GNUC__ >= 4.1 */ -#endif - -#include -#include -#include -#include -#include -#include -#if defined(__cplusplus) -#include -#endif - -/* - * Keyboard scancodes for events/states - */ -#define TK_A 0x04 -#define TK_B 0x05 -#define TK_C 0x06 -#define TK_D 0x07 -#define TK_E 0x08 -#define TK_F 0x09 -#define TK_G 0x0A -#define TK_H 0x0B -#define TK_I 0x0C -#define TK_J 0x0D -#define TK_K 0x0E -#define TK_L 0x0F -#define TK_M 0x10 -#define TK_N 0x11 -#define TK_O 0x12 -#define TK_P 0x13 -#define TK_Q 0x14 -#define TK_R 0x15 -#define TK_S 0x16 -#define TK_T 0x17 -#define TK_U 0x18 -#define TK_V 0x19 -#define TK_W 0x1A -#define TK_X 0x1B -#define TK_Y 0x1C -#define TK_Z 0x1D -#define TK_1 0x1E -#define TK_2 0x1F -#define TK_3 0x20 -#define TK_4 0x21 -#define TK_5 0x22 -#define TK_6 0x23 -#define TK_7 0x24 -#define TK_8 0x25 -#define TK_9 0x26 -#define TK_0 0x27 -#define TK_RETURN 0x28 -#define TK_ENTER 0x28 -#define TK_ESCAPE 0x29 -#define TK_BACKSPACE 0x2A -#define TK_TAB 0x2B -#define TK_SPACE 0x2C -#define TK_MINUS 0x2D /* - */ -#define TK_EQUALS 0x2E /* = */ -#define TK_LBRACKET 0x2F /* [ */ -#define TK_RBRACKET 0x30 /* ] */ -#define TK_BACKSLASH 0x31 /* \ */ -#define TK_SEMICOLON 0x33 /* ; */ -#define TK_APOSTROPHE 0x34 /* ' */ -#define TK_GRAVE 0x35 /* ` */ -#define TK_COMMA 0x36 /* , */ -#define TK_PERIOD 0x37 /* . */ -#define TK_SLASH 0x38 /* / */ -#define TK_F1 0x3A -#define TK_F2 0x3B -#define TK_F3 0x3C -#define TK_F4 0x3D -#define TK_F5 0x3E -#define TK_F6 0x3F -#define TK_F7 0x40 -#define TK_F8 0x41 -#define TK_F9 0x42 -#define TK_F10 0x43 -#define TK_F11 0x44 -#define TK_F12 0x45 -#define TK_PAUSE 0x48 /* Pause/Break */ -#define TK_INSERT 0x49 -#define TK_HOME 0x4A -#define TK_PAGEUP 0x4B -#define TK_DELETE 0x4C -#define TK_END 0x4D -#define TK_PAGEDOWN 0x4E -#define TK_RIGHT 0x4F /* Right arrow */ -#define TK_LEFT 0x50 /* Left arrow */ -#define TK_DOWN 0x51 /* Down arrow */ -#define TK_UP 0x52 /* Up arrow */ -#define TK_KP_DIVIDE 0x54 /* '/' on numpad */ -#define TK_KP_MULTIPLY 0x55 /* '*' on numpad */ -#define TK_KP_MINUS 0x56 /* '-' on numpad */ -#define TK_KP_PLUS 0x57 /* '+' on numpad */ -#define TK_KP_ENTER 0x58 -#define TK_KP_1 0x59 -#define TK_KP_2 0x5A -#define TK_KP_3 0x5B -#define TK_KP_4 0x5C -#define TK_KP_5 0x5D -#define TK_KP_6 0x5E -#define TK_KP_7 0x5F -#define TK_KP_8 0x60 -#define TK_KP_9 0x61 -#define TK_KP_0 0x62 -#define TK_KP_PERIOD 0x63 /* '.' on numpad */ -#define TK_SHIFT 0x70 -#define TK_CONTROL 0x71 -#define TK_ALT 0x72 - -/* - * Mouse events/states - */ -#define TK_MOUSE_LEFT 0x80 /* Buttons */ -#define TK_MOUSE_RIGHT 0x81 -#define TK_MOUSE_MIDDLE 0x82 -#define TK_MOUSE_X1 0x83 -#define TK_MOUSE_X2 0x84 -#define TK_MOUSE_MOVE 0x85 /* Movement event */ -#define TK_MOUSE_SCROLL 0x86 /* Mouse scroll event */ -#define TK_MOUSE_X 0x87 /* Cusor position in cells */ -#define TK_MOUSE_Y 0x88 -#define TK_MOUSE_PIXEL_X 0x89 /* Cursor position in pixels */ -#define TK_MOUSE_PIXEL_Y 0x8A -#define TK_MOUSE_WHEEL 0x8B /* Scroll direction and amount */ -#define TK_MOUSE_CLICKS 0x8C /* Number of consecutive clicks */ - -/* - * If key was released instead of pressed, it's code will be OR'ed with TK_KEY_RELEASED: - * a) pressed 'A': 0x04 - * b) released 'A': 0x04|VK_KEY_RELEASED = 0x104 - */ -#define TK_KEY_RELEASED 0x100 - -/* - * Virtual key-codes for internal terminal states/variables. - * These can be accessed via terminal_state function. - */ -#define TK_WIDTH 0xC0 /* Terminal window size in cells */ -#define TK_HEIGHT 0xC1 -#define TK_CELL_WIDTH 0xC2 /* Character cell size in pixels */ -#define TK_CELL_HEIGHT 0xC3 -#define TK_COLOR 0xC4 /* Current foregroung color */ -#define TK_BKCOLOR 0xC5 /* Current background color */ -#define TK_LAYER 0xC6 /* Current layer */ -#define TK_COMPOSITION 0xC7 /* Current composition state */ -#define TK_CHAR 0xC8 /* Translated ANSI code of last produced character */ -#define TK_WCHAR 0xC9 /* Unicode codepoint of last produced character */ -#define TK_EVENT 0xCA /* Last dequeued event */ -#define TK_FULLSCREEN 0xCB /* Fullscreen state */ - -/* - * Other events - */ -#define TK_CLOSE 0xE0 -#define TK_RESIZED 0xE1 - -/* - * Generic mode enum. - * Right now it is used for composition option only. - */ -#define TK_OFF 0 -#define TK_ON 1 - -/* - * Input result codes for terminal_read function. - */ -#define TK_INPUT_NONE 0 -#define TK_INPUT_CANCELLED -1 - -/* - * Text printing alignment. - */ -#define TK_ALIGN_DEFAULT 0 -#define TK_ALIGN_LEFT 1 -#define TK_ALIGN_RIGHT 2 -#define TK_ALIGN_CENTER 3 -#define TK_ALIGN_TOP 4 -#define TK_ALIGN_BOTTOM 8 -#define TK_ALIGN_MIDDLE 12 - -/* - * Terminal uses unsigned 32-bit value for color representation in ARGB order (0xAARRGGBB), e. g. - * a) solid red is 0xFFFF0000 - * b) half-transparent green is 0x8000FF00 - */ -typedef uint32_t color_t; - -typedef struct dimensions_t_ -{ - int width; - int height; -} -dimensions_t; - -#if defined(BEARLIBTERMINAL_STATIC_BUILD) -# define TERMINAL_API -#elif defined(_WIN32) -# if defined(BEARLIBTERMINAL_BUILDING_LIBRARY) -# define TERMINAL_API __declspec(dllexport) -# else -# define TERMINAL_API __declspec(dllimport) -# endif -#else -# if defined(BEARLIBTERMINAL_BUILDING_LIBRARY) && __GNUC__ >= 4 -# define TERMINAL_API __attribute__ ((visibility ("default"))) -# else -# define TERMINAL_API -# endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -TERMINAL_API int terminal_open(); -TERMINAL_API void terminal_close(); -TERMINAL_API int terminal_set8(const int8_t* value); -TERMINAL_API int terminal_set16(const int16_t* value); -TERMINAL_API int terminal_set32(const int32_t* value); -TERMINAL_API void terminal_refresh(); -TERMINAL_API void terminal_clear(); -TERMINAL_API void terminal_clear_area(int x, int y, int w, int h); -TERMINAL_API void terminal_crop(int x, int y, int w, int h); -TERMINAL_API void terminal_layer(int index); -TERMINAL_API void terminal_color(color_t color); -TERMINAL_API void terminal_bkcolor(color_t color); -TERMINAL_API void terminal_composition(int mode); -TERMINAL_API void terminal_font8(const int8_t* name); -TERMINAL_API void terminal_font16(const int16_t* name); -TERMINAL_API void terminal_font32(const int32_t* name); -TERMINAL_API void terminal_put(int x, int y, int code); -TERMINAL_API void terminal_put_ext(int x, int y, int dx, int dy, int code, color_t* corners); -TERMINAL_API int terminal_pick(int x, int y, int index); -TERMINAL_API color_t terminal_pick_color(int x, int y, int index); -TERMINAL_API color_t terminal_pick_bkcolor(int x, int y); -TERMINAL_API void terminal_print_ext8(int x, int y, int w, int h, int align, const int8_t* s, int* out_w, int* out_h); -TERMINAL_API void terminal_print_ext16(int x, int y, int w, int h, int align, const int16_t* s, int* out_w, int* out_h); -TERMINAL_API void terminal_print_ext32(int x, int y, int w, int h, int align, const int32_t* s, int* out_w, int* out_h); -TERMINAL_API void terminal_measure_ext8(int w, int h, const int8_t* s, int* out_w, int* out_h); -TERMINAL_API void terminal_measure_ext16(int w, int h, const int16_t* s, int* out_w, int* out_h); -TERMINAL_API void terminal_measure_ext32(int w, int h, const int32_t* s, int* out_w, int* out_h); -TERMINAL_API int terminal_has_input(); -TERMINAL_API int terminal_state(int code); -TERMINAL_API int terminal_read(); -TERMINAL_API int terminal_read_str8(int x, int y, int8_t* buffer, int max); -TERMINAL_API int terminal_read_str16(int x, int y, int16_t* buffer, int max); -TERMINAL_API int terminal_read_str32(int x, int y, int32_t* buffer, int max); -TERMINAL_API int terminal_peek(); -TERMINAL_API void terminal_delay(int period); -TERMINAL_API const int8_t* terminal_get8(const int8_t* key, const int8_t* default_); -TERMINAL_API const int16_t* terminal_get16(const int16_t* key, const int16_t* default_); -TERMINAL_API const int32_t* terminal_get32(const int32_t* key, const int32_t* default_); -TERMINAL_API color_t color_from_name8(const int8_t* name); -TERMINAL_API color_t color_from_name16(const int16_t* name); -TERMINAL_API color_t color_from_name32(const int32_t* name); - -#ifdef __cplusplus -} /* End of extern "C" */ -#endif - -/* - * Utility macro trick which allows macro-in-macro expansion - */ -#define TERMINAL_CAT(a, b) TERMINAL_PRIMITIVE_CAT(a, b) -#define TERMINAL_PRIMITIVE_CAT(a, b) a ## b - -/* - * wchar_t has different sized depending on platform. Furthermore, it's size - * can be changed for GCC compiler. - */ -#if !defined(__SIZEOF_WCHAR_T__) -# if defined(_WIN32) -# define __SIZEOF_WCHAR_T__ 2 -# else -# define __SIZEOF_WCHAR_T__ 4 -# endif -#endif - -#if __SIZEOF_WCHAR_T__ == 2 -#define TERMINAL_WCHAR_SUFFIX 16 -#define TERMINAL_WCHAR_TYPE int16_t -#else // 4 -#define TERMINAL_WCHAR_SUFFIX 32 -#define TERMINAL_WCHAR_TYPE int32_t -#endif - -#if defined(__cplusplus) -#define TERMINAL_INLINE inline -#define TERMINAL_DEFAULT(value) = value -#else -#define TERMINAL_INLINE static inline -#define TERMINAL_DEFAULT(value) -#endif - -/* - * These functions provide inline string formatting support - * for terminal_setf, terminal_printf, etc. - * - * Using static termporary buffer is okay because terminal API is not - * required to be multiple-thread safe by design. - */ - -#define TERMINAL_VSPRINTF_MAXIMUM_BUFFER_SIZE 65536 - -TERMINAL_INLINE const char* terminal_vsprintf(const char* s, va_list args) -{ - static int buffer_size = 512; - static char* buffer = NULL; - int rc = 0; - - if (!s) - return NULL; - else if (!buffer) - buffer = (char*)malloc(buffer_size); - - while (1) - { - buffer[buffer_size-1] = '\0'; - rc = vsnprintf(buffer, buffer_size, s, args); - if (rc >= buffer_size || buffer[buffer_size-1] != '\0') - { - if (buffer_size >= TERMINAL_VSPRINTF_MAXIMUM_BUFFER_SIZE) - return NULL; - - buffer_size *= 2; - buffer = (char*)realloc(buffer, buffer_size); - } - else - { - break; - } - } - - return rc >= 0? buffer: NULL; -} - -TERMINAL_INLINE const wchar_t* terminal_vswprintf(const wchar_t* s, va_list args) -{ - static int buffer_size = 512; - static wchar_t* buffer = NULL; - int rc = 0; - - if (!s) - return NULL; - else if (!buffer) - buffer = (wchar_t*)malloc(buffer_size * sizeof(wchar_t)); - - while (1) - { - buffer[buffer_size-1] = L'\0'; -#if defined(_WIN32) - rc = _vsnwprintf(buffer, buffer_size, s, args); -#else - rc = vswprintf(buffer, buffer_size, s, args); -#endif - if (rc >= buffer_size || buffer[buffer_size-1] != L'\0') - { - if (buffer_size >= TERMINAL_VSPRINTF_MAXIMUM_BUFFER_SIZE) - return NULL; - - buffer_size *= 2; - buffer = (wchar_t*)realloc(buffer, buffer_size * sizeof(wchar_t)); - } - else - { - break; - } - } - - return rc >= 0? buffer: NULL; -} - -#define TERMINAL_FORMATTED_WRAP(type, call) \ - type ret; \ - va_list args; \ - va_start(args, s); \ - ret = call; \ - va_end(args); \ - return ret; - -#define TERMINAL_FORMATTED_WRAP_V(call) \ - va_list args; \ - va_start(args, s); \ - call; \ - va_end(args); - -/* - * This set of inline functions define basic name substitution + type cast: - * terminal_[w]xxxx -> terminal_xxxx{8|16|32} - */ - -TERMINAL_INLINE int terminal_set(const char* s) -{ - return terminal_set8((const int8_t*)s); -} - -TERMINAL_INLINE int terminal_setf(const char* s, ...) -{ - TERMINAL_FORMATTED_WRAP(int, terminal_set(terminal_vsprintf(s, args))) -} - -TERMINAL_INLINE int terminal_wset(const wchar_t* s) -{ - return TERMINAL_CAT(terminal_set, TERMINAL_WCHAR_SUFFIX)((const TERMINAL_WCHAR_TYPE*)s); -} - -TERMINAL_INLINE int terminal_wsetf(const wchar_t* s, ...) -{ - TERMINAL_FORMATTED_WRAP(int, terminal_wset(terminal_vswprintf(s, args))) -} - -TERMINAL_INLINE void terminal_font(const char* name) -{ - terminal_font8((const int8_t*)name); -} - -TERMINAL_INLINE void terminal_wfont(const wchar_t* name) -{ - TERMINAL_CAT(terminal_font, TERMINAL_WCHAR_SUFFIX)((const TERMINAL_WCHAR_TYPE*)name); -} - -TERMINAL_INLINE dimensions_t terminal_print(int x, int y, const char* s) -{ - dimensions_t ret; - terminal_print_ext8(x, y, 0, 0, TK_ALIGN_DEFAULT, (const int8_t*)s, &ret.width, &ret.height); - return ret; -} - -TERMINAL_INLINE dimensions_t terminal_printf(int x, int y, const char* s, ...) -{ - TERMINAL_FORMATTED_WRAP(dimensions_t, terminal_print(x, y, terminal_vsprintf(s, args))) -} - -TERMINAL_INLINE dimensions_t terminal_wprint(int x, int y, const wchar_t* s) -{ - dimensions_t ret; - TERMINAL_CAT(terminal_print_ext, TERMINAL_WCHAR_SUFFIX)(x, y, 0, 0, TK_ALIGN_DEFAULT, (const TERMINAL_WCHAR_TYPE*)s, &ret.width, &ret.height); - return ret; -} - -TERMINAL_INLINE dimensions_t terminal_wprintf(int x, int y, const wchar_t* s, ...) -{ - TERMINAL_FORMATTED_WRAP(dimensions_t, terminal_wprint(x, y, terminal_vswprintf(s, args))) -} - -TERMINAL_INLINE dimensions_t terminal_print_ext(int x, int y, int w, int h, int align, const char* s) -{ - dimensions_t ret; - terminal_print_ext8(x, y, w, h, align, (const int8_t*)s, &ret.width, &ret.height); - return ret; -} - -TERMINAL_INLINE dimensions_t terminal_printf_ext(int x, int y, int w, int h, int align, const char* s, ...) -{ - TERMINAL_FORMATTED_WRAP(dimensions_t, terminal_print_ext(x, y, w, h, align, terminal_vsprintf(s, args))); -} - -TERMINAL_INLINE dimensions_t terminal_wprint_ext(int x, int y, int w, int h, int align, const wchar_t* s) -{ - dimensions_t ret; - TERMINAL_CAT(terminal_print_ext, TERMINAL_WCHAR_SUFFIX)(x, y, w, h, align, (const TERMINAL_WCHAR_TYPE*)s, &ret.width, &ret.height); - return ret; -} - -TERMINAL_INLINE dimensions_t terminal_wprintf_ext(int x, int y, int w, int h, int align, const wchar_t* s, ...) -{ - TERMINAL_FORMATTED_WRAP(dimensions_t, terminal_wprint_ext(x, y, w, h, align, terminal_vswprintf(s, args))) -} - -TERMINAL_INLINE dimensions_t terminal_measure(const char* s) -{ - dimensions_t ret; - terminal_measure_ext8(0, 0, (const int8_t*)s, &ret.width, &ret.height); - return ret; -} - -TERMINAL_INLINE dimensions_t terminal_measuref(const char* s, ...) -{ - TERMINAL_FORMATTED_WRAP(dimensions_t, terminal_measure(terminal_vsprintf(s, args))) -} - -TERMINAL_INLINE dimensions_t terminal_wmeasure(const wchar_t* s) -{ - dimensions_t ret; - TERMINAL_CAT(terminal_measure_ext, TERMINAL_WCHAR_SUFFIX)(0, 0, (const TERMINAL_WCHAR_TYPE*)s, &ret.width, &ret.height); - return ret; -} - -TERMINAL_INLINE dimensions_t terminal_wmeasuref(const wchar_t* s, ...) -{ - TERMINAL_FORMATTED_WRAP(dimensions_t, terminal_wmeasure(terminal_vswprintf(s, args))) -} - -TERMINAL_INLINE dimensions_t terminal_measure_ext(int w, int h, const char* s) -{ - dimensions_t ret; - terminal_measure_ext8(w, h, (const int8_t*)s, &ret.width, &ret.height); - return ret; -} - -TERMINAL_INLINE dimensions_t terminal_measuref_ext(int w, int h, const char* s, ...) -{ - TERMINAL_FORMATTED_WRAP(dimensions_t, terminal_measure_ext(w, h, terminal_vsprintf(s, args))) -} - -TERMINAL_INLINE dimensions_t terminal_wmeasure_ext(int w, int h, const wchar_t* s) -{ - dimensions_t ret; - TERMINAL_CAT(terminal_measure_ext, TERMINAL_WCHAR_SUFFIX)(w, h, (const TERMINAL_WCHAR_TYPE*)s, &ret.width, &ret.height); - return ret; -} - -TERMINAL_INLINE dimensions_t terminal_wmeasuref_ext(int w, int h, const wchar_t* s, ...) -{ - TERMINAL_FORMATTED_WRAP(dimensions_t, terminal_wmeasure_ext(w, h, terminal_vswprintf(s, args))) -} - -TERMINAL_INLINE int terminal_read_str(int x, int y, char* buffer, int max) -{ - return terminal_read_str8(x, y, (int8_t*)buffer, max); -} - -TERMINAL_INLINE int terminal_read_wstr(int x, int y, wchar_t* buffer, int max) -{ - return TERMINAL_CAT(terminal_read_str, TERMINAL_WCHAR_SUFFIX)(x, y, (TERMINAL_WCHAR_TYPE*)buffer, max); -} - -TERMINAL_INLINE const char* terminal_get(const char* key, const char* default_ TERMINAL_DEFAULT((const char*)0)) -{ - return (const char*)terminal_get8((const int8_t*)key, (const int8_t*)default_); -} - -TERMINAL_INLINE const wchar_t* terminal_wget(const wchar_t* key, const wchar_t* default_ TERMINAL_DEFAULT((const wchar_t*)0)) -{ - return (const wchar_t*)TERMINAL_CAT(terminal_get, TERMINAL_WCHAR_SUFFIX)((const TERMINAL_WCHAR_TYPE*)key, (const TERMINAL_WCHAR_TYPE*)default_); -} - -TERMINAL_INLINE color_t color_from_name(const char* name) -{ - return color_from_name8((const int8_t*)name); -} - -TERMINAL_INLINE color_t color_from_wname(const wchar_t* name) -{ - return TERMINAL_CAT(color_from_name, TERMINAL_WCHAR_SUFFIX)((const TERMINAL_WCHAR_TYPE*)name); -} - -#ifdef __cplusplus -/* - * C++ supports function overloading, should take advantage of it. - */ - -TERMINAL_INLINE int terminal_set(const wchar_t* s) -{ - return terminal_wset(s); -} - -TERMINAL_INLINE int terminal_setf(const wchar_t* s, ...) -{ - TERMINAL_FORMATTED_WRAP(int, terminal_wset(terminal_vswprintf(s, args))); -} - -TERMINAL_INLINE void terminal_color(const char* name) -{ - terminal_color(color_from_name(name)); -} - -TERMINAL_INLINE void terminal_color(const wchar_t* name) -{ - terminal_color(color_from_wname(name)); -} - -TERMINAL_INLINE void terminal_bkcolor(const char* name) -{ - terminal_bkcolor(color_from_name(name)); -} - -TERMINAL_INLINE void terminal_bkcolor(const wchar_t* name) -{ - terminal_bkcolor(color_from_wname(name)); -} - -TERMINAL_INLINE void terminal_font(const wchar_t* name) -{ - terminal_wfont(name); -} - -TERMINAL_INLINE void terminal_put_ext(int x, int y, int dx, int dy, int code) -{ - terminal_put_ext(x, y, dx, dy, code, 0); -} - -TERMINAL_INLINE dimensions_t terminal_print(int x, int y, const wchar_t* s) -{ - return terminal_wprint(x, y, s); -} - -TERMINAL_INLINE dimensions_t terminal_printf(int x, int y, const wchar_t* s, ...) -{ - TERMINAL_FORMATTED_WRAP(dimensions_t, terminal_wprint(x, y, terminal_vswprintf(s, args))) -} - -TERMINAL_INLINE dimensions_t terminal_print_ext(int x, int y, int w, int h, int align, const wchar_t* s) -{ - return terminal_wprint_ext(x, y, w, h, align, s); -} - -TERMINAL_INLINE dimensions_t terminal_printf_ext(int x, int y, int w, int h, int align, const wchar_t* s, ...) -{ - TERMINAL_FORMATTED_WRAP(dimensions_t, terminal_wprint_ext(x, y, w, h, align, terminal_vswprintf(s, args))) -} - -TERMINAL_INLINE dimensions_t terminal_measure(const wchar_t* s) -{ - return terminal_wmeasure(s); -} - -TERMINAL_INLINE dimensions_t terminal_measuref(const wchar_t* s, ...) -{ - TERMINAL_FORMATTED_WRAP(dimensions_t, terminal_wmeasure(terminal_vswprintf(s, args))) -} - -TERMINAL_INLINE dimensions_t terminal_measure_ext(int w, int h, const wchar_t* s) -{ - return terminal_wmeasure_ext(w, h, s); -} - -TERMINAL_INLINE dimensions_t terminal_measuref_ext(int w, int h, const wchar_t* s, ...) -{ - TERMINAL_FORMATTED_WRAP(dimensions_t, terminal_wmeasure_ext(w, h, terminal_vswprintf(s, args))) -} - -TERMINAL_INLINE int terminal_read_str(int x, int y, wchar_t* buffer, int max) -{ - return terminal_read_wstr(x, y, buffer, max); -} - -TERMINAL_INLINE color_t color_from_name(const wchar_t* name) -{ - return color_from_wname(name); -} - -TERMINAL_INLINE int terminal_pick(int x, int y) -{ - return terminal_pick(x, y, 0); -} - -TERMINAL_INLINE color_t terminal_pick_color(int x, int y) -{ - return terminal_pick_color(x, y, 0); -} - -TERMINAL_INLINE const wchar_t* terminal_get(const wchar_t* key, const wchar_t* default_ = (const wchar_t*)0) -{ - return terminal_wget(key, default_); -} - -template T terminal_get(const C* key, const T& default_ = T()) -{ - const C* result_str = terminal_get(key, (const C*)0); - if (result_str[0] == C(0)) - return default_; - T result; - return (bool)(std::basic_istringstream(result_str) >> result)? result: default_; -} - -#endif /* __cplusplus */ - -/* - * Color routines - */ -TERMINAL_INLINE color_t color_from_argb(uint8_t a, uint8_t r, uint8_t g, uint8_t b) -{ - return ((color_t)a << 24) | (r << 16) | (g << 8) | b; -} - -/* - * Other functional sugar - */ -TERMINAL_INLINE int terminal_check(int code) -{ - return terminal_state(code) > 0; -} - -/* - * WinMain entry point handling macro. This allows easier entry point definition. - * The macro will expand to proper WinMain stub regardless of header include order. - */ -#if defined(_WIN32) - -/* - * WinMain probe macro. It will expand to either X or X_WINDOWS_ depending on - * Windows.h header inclusion. - */ -#define TERMINAL_TAKE_CARE_OF_WINMAIN TERMINAL_WINMAIN_PROBE_IMPL(_WINDOWS_) -#define TERMINAL_WINMAIN_PROBE_IMPL(DEF) TERMINAL_PRIMITIVE_CAT(TERMINAL_WINMAIN_IMPL, DEF) - -/* - * Trivial no-arguments WinMain implementation. It just calls main. - */ -#define TERMINAL_WINMAIN_IMPL_BASE(INSTANCE_T, STRING_T)\ - extern "C" int main();\ - extern "C" int __stdcall WinMain(INSTANCE_T hInstance, INSTANCE_T hPrevInstance, STRING_T lpCmdLine, int nCmdShow)\ - {\ - return main();\ - } - -/* - * Macro expands to empty string. Windows.h is included thus code MUST use - * predefined types or else MSVC will complain. - */ -#define TERMINAL_WINMAIN_IMPL TERMINAL_WINMAIN_IMPL_BASE(HINSTANCE, LPSTR) - -/* - * Macro expands to macro name. Windows.h wasn't included, so WinMain will be - * defined with fundamental types (enough for linker to find it). - */ -#define TERMINAL_WINMAIN_IMPL_WINDOWS_ TERMINAL_WINMAIN_IMPL_BASE(void*, char*) - -#else - -/* - * Only Windows has WinMain but macro still must be defined for cross-platform - * applications. - */ -#define TERMINAL_TAKE_CARE_OF_WINMAIN - -#endif - -#endif // BEARLIBTERMINAL_H diff --git a/src/bearlibterminal/libBearLibTerminal.so b/src/bearlibterminal/libBearLibTerminal.so deleted file mode 100755 index 9f08275..0000000 Binary files a/src/bearlibterminal/libBearLibTerminal.so and /dev/null differ diff --git a/src/game/abilities.go b/src/game/abilities.go deleted file mode 100644 index d1536f6..0000000 --- a/src/game/abilities.go +++ /dev/null @@ -1,13 +0,0 @@ -package game - -//spells, abilities etc -type Ability interface { - Use() -} - -//magic spellz -type Spell interface { - Ability - GetCooldown() int - ApplyCost() int -} \ No newline at end of file diff --git a/src/game/item.go b/src/game/item.go deleted file mode 100644 index 2f87f66..0000000 --- a/src/game/item.go +++ /dev/null @@ -1,26 +0,0 @@ -package game - -//something that could be carried and dropped -type Luggage interface { - Mob - Drop(carrier Monster) bool - Pickup(carrier Monster) bool -} - -//something that could be used from inventory -type Usable interface { - GetUsageVariants() //not Use() cause you could do many things with a potion - drink and throw for instance - Use(variant string) -} -//Item that could be carried and used -type Item interface { - Luggage - Usable -} - -//something you can wear -type Wearable interface { - Luggage - Wear() - Takeoff() -} diff --git a/src/game/level.go b/src/game/level.go deleted file mode 100644 index 4a76198..0000000 --- a/src/game/level.go +++ /dev/null @@ -1,7 +0,0 @@ -package game - -type Level struct { - Branch string - Map Map - Mobs map[string]Mob -} diff --git a/src/game/map.go b/src/game/map.go deleted file mode 100644 index d0020be..0000000 --- a/src/game/map.go +++ /dev/null @@ -1,30 +0,0 @@ -package game - -type Map struct { - SizeX int - SizeY int - Geometry [][]Tile -} - -//just coordinates -type Coords struct { - X, Y int -} - -type color struct { - alpha int - red int - green int - blue int -} - -//packed char, fgColor, bgColor and render settings -type Drawable interface { -} - -type Tile struct { - Drawable - BlocksPass bool - BlocksSight bool - //colordance and other stuff later -} diff --git a/src/game/mob.go b/src/game/mob.go deleted file mode 100644 index d65ca2d..0000000 --- a/src/game/mob.go +++ /dev/null @@ -1,36 +0,0 @@ -package game - -//see https://stackoverflow.com/questions/32188653/golang-and-inheritance - -//something that could be placed on map - MapObject -type Mob interface { - Drawable - GetCoords() Coords - SetCoords(x, y int) - SetX(x int) - SetY(y int) -} - -//something that must be ai-processed -type Sentient interface { - SetAi() - GetAi() - TakeTurn() -} - -//something with inventory -type Monster interface { - Mob -} - -//Something that can fight -type Fighter interface { - Mob - Spawn() - Die() - Attack() - Move() - GetBuffs() - SetBuffs() -} - diff --git a/src/game/state.go b/src/game/state.go deleted file mode 100644 index cde26fe..0000000 --- a/src/game/state.go +++ /dev/null @@ -1 +0,0 @@ -package game diff --git a/src/ui/keyinput.go b/src/ui/keyinput.go deleted file mode 100644 index 7603edf..0000000 --- a/src/ui/keyinput.go +++ /dev/null @@ -1,35 +0,0 @@ -package ui - -import blt "bearlibterminal" -import ( - "fmt" - "util" -) - -var modifiers = []int{blt.TK_SHIFT, blt.TK_ALT, blt.TK_CONTROL} - -func ReadKey() (string, int) { - if !blt.HasInput() { - return "", blt.TK_NONE - } - var key = blt.Read() - var pressed = "" - var isModifier, _ = util.InArray(key, modifiers) - if (!isModifier) { - - pressed = Scancodemap[key] - - if blt.Check(blt.TK_SHIFT) != 0 { - pressed = "Shift+" + pressed - } - if blt.Check(blt.TK_ALT) != 0 { - pressed = "Alt+" + pressed - } - if blt.Check(blt.TK_CONTROL) != 0 { - pressed = "Ctrl+" + pressed - } - fmt.Println(pressed) - } - - return pressed, key -} diff --git a/src/ui/scancodemap.go b/src/ui/scancodemap.go deleted file mode 100644 index ab1e2c3..0000000 --- a/src/ui/scancodemap.go +++ /dev/null @@ -1,100 +0,0 @@ -package ui - -import blt "bearlibterminal" - -var Scancodemap = map[int]string{ - blt.TK_A: "a", - blt.TK_B: "b", - blt.TK_C: "c", - blt.TK_D: "d", - blt.TK_E: "e", - blt.TK_F: "f", - blt.TK_G: "g", - blt.TK_H: "h", - blt.TK_I: "i", - blt.TK_J: "j", - blt.TK_K: "k", - blt.TK_L: "l", - blt.TK_M: "m", - blt.TK_N: "n", - blt.TK_O: "o", - blt.TK_P: "p", - blt.TK_Q: "q", - blt.TK_R: "r", - blt.TK_S: "s", - blt.TK_T: "t", - blt.TK_U: "u", - blt.TK_V: "v", - blt.TK_W: "w", - blt.TK_X: "x", - blt.TK_Y: "y", - blt.TK_Z: "z", - blt.TK_1: "1", - blt.TK_2: "2", - blt.TK_3: "3", - blt.TK_4: "4", - blt.TK_5: "5", - blt.TK_6: "6", - blt.TK_7: "7", - blt.TK_8: "8", - blt.TK_9: "9", - blt.TK_0: "0", - blt.TK_ENTER: "Enter", - blt.TK_ESCAPE: "Escape", - blt.TK_BACKSPACE: "Backspace", - blt.TK_TAB: "Tab", - blt.TK_SPACE: "Space", - blt.TK_MINUS: "-", - blt.TK_EQUALS: "=", - blt.TK_LBRACKET: "LBracket", - blt.TK_RBRACKET: "RBracket", - blt.TK_BACKSLASH: "\\", - blt.TK_SEMICOLON: ";", - blt.TK_APOSTROPHE: "'", - blt.TK_GRAVE: "`", - blt.TK_COMMA: ",", - blt.TK_PERIOD: ".", - blt.TK_SLASH: "/", - blt.TK_F1: "F1", - blt.TK_F2: "F2", - blt.TK_F3: "F3", - blt.TK_F4: "F4", - blt.TK_F5: "F5", - blt.TK_F6: "F6", - blt.TK_F7: "F7", - blt.TK_F8: "F8", - blt.TK_F9: "F9", - blt.TK_F10: "F10", - blt.TK_F11: "F11", - blt.TK_F12: "F12", - blt.TK_PAUSE: "Pause", - blt.TK_INSERT: "Insert", - blt.TK_HOME: "Home", - blt.TK_PAGEUP: "PageUp", - blt.TK_DELETE: "Delete", - blt.TK_END: "End", - blt.TK_PAGEDOWN: "PageDown", - blt.TK_RIGHT: "Right", - blt.TK_LEFT: "Left", - blt.TK_DOWN: "Down", - blt.TK_UP: "Up", - blt.TK_KP_DIVIDE: "KP_DIVIDE", - blt.TK_KP_MULTIPLY: "KP_MULTIPLY", - blt.TK_KP_MINUS: "KP_MINUS", - blt.TK_KP_PLUS: "KP_PLUS", - blt.TK_KP_ENTER: "KP_ENTER", - blt.TK_KP_1: "KP_1", - blt.TK_KP_2: "KP_2", - blt.TK_KP_3: "KP_3", - blt.TK_KP_4: "KP_4", - blt.TK_KP_5: "KP_5", - blt.TK_KP_6: "KP_6", - blt.TK_KP_7: "KP_7", - blt.TK_KP_8: "KP_8", - blt.TK_KP_9: "KP_9", - blt.TK_KP_0: "KP_0", - blt.TK_KP_PERIOD: "KP_PERIOD", - blt.TK_SHIFT: "SHIFT", - blt.TK_CONTROL: "CONTROL", - blt.TK_ALT: "ALT", -} diff --git a/src/util/util.go b/src/util/util.go deleted file mode 100644 index abf310b..0000000 --- a/src/util/util.go +++ /dev/null @@ -1,51 +0,0 @@ -package util - -import ( - "reflect" - "flag" - "io/ioutil" - "log" - "encoding/json" -) - -type Config struct { - Title string `json:"title"` - FpsLimit int `json:"fpsLimit, omitempty" validate:"required"` -} - -func LoadConfig () *Config { - var configArg string = "./config.json" - flag.StringVar(&configArg, "cfg", configArg, "config file location") - flag.Parse() - - // get config - data, err := ioutil.ReadFile(configArg) - if err != nil { - log.Fatalf("Application couldn't read config at %s", configArg) - } - config := new(Config) - err = json.Unmarshal(data, config) - if err != nil { - log.Fatalln(err) - } - return config -} - -func InArray(val interface{}, array interface{}) (exists bool, index int) { - exists = false - index = -1 - - switch reflect.TypeOf(array).Kind() { - case reflect.Slice: - s := reflect.ValueOf(array) - - for i := 0; i < s.Len(); i++ { - if reflect.DeepEqual(val, s.Index(i).Interface()) == true { - index = i - exists = true - return - } - } - } - return -} \ No newline at end of file diff --git a/ui/keyinput.go b/ui/keyinput.go new file mode 100644 index 0000000..245e6c1 --- /dev/null +++ b/ui/keyinput.go @@ -0,0 +1,34 @@ +package ui + +import ( + "lab.zaar.be/thefish/alchemyst-go/util" + blt "lab.zaar.be/thefish/bearlibterminal" +) + +var modifiers = []int{blt.TK_SHIFT, blt.TK_ALT, blt.TK_CONTROL} + +func ReadKey(ctx util.ClientCtx) (string, int) { + if !blt.HasInput() { + return "", blt.TK_NONE + } + var key = blt.Read() + var pressed = "" + var isModifier, _ = util.InArray(key, modifiers) + if !isModifier { + + pressed = Scancodemap[key] + + if blt.Check(blt.TK_SHIFT) != 0 { + pressed = "Shift+" + pressed + } + if blt.Check(blt.TK_ALT) != 0 { + pressed = "Alt+" + pressed + } + if blt.Check(blt.TK_CONTROL) != 0 { + pressed = "Ctrl+" + pressed + } + ctx.Logger().Debug().Msg(pressed) + } + + return pressed, key +} diff --git a/ui/mainwindow/window.go b/ui/mainwindow/window.go new file mode 100644 index 0000000..a810476 --- /dev/null +++ b/ui/mainwindow/window.go @@ -0,0 +1,27 @@ +package mainwindow + +import ( + "fmt" + "lab.zaar.be/thefish/alchemyst-go/util" + blt "lab.zaar.be/thefish/bearlibterminal" +) + +func Init(ctx util.ClientCtx) { + ctx.Logger().Info().Msgf("Opening main window...") + config := ctx.Config() + blt.Open() + //blt.Set("window: size=80x25, title="+config.Title+" v"+string(version)+"; font: ./fonts/Monaco-Linux.ttf, size=10") + blt.Set( + fmt.Sprintf("window: size=%dx%d, title=%s v%s; font: ./resources/fonts-bitmap/ibmnew8x12.png, size=8x12;", + config.MainWindowSizeX, + config.MainWindowSizeY, + config.Title, + config.Version, + ), + ) +} + +func Shutdown(ctx util.ClientCtx) { + ctx.Logger().Info().Msg("Closing main window...") + blt.Close() +} diff --git a/ui/scancodemap.go b/ui/scancodemap.go new file mode 100644 index 0000000..a4a3850 --- /dev/null +++ b/ui/scancodemap.go @@ -0,0 +1,100 @@ +package ui + +import blt "lab.zaar.be/thefish/bearlibterminal" + +var Scancodemap = map[int]string{ + blt.TK_A: "a", + blt.TK_B: "b", + blt.TK_C: "c", + blt.TK_D: "d", + blt.TK_E: "e", + blt.TK_F: "f", + blt.TK_G: "g", + blt.TK_H: "h", + blt.TK_I: "i", + blt.TK_J: "j", + blt.TK_K: "k", + blt.TK_L: "l", + blt.TK_M: "m", + blt.TK_N: "n", + blt.TK_O: "o", + blt.TK_P: "p", + blt.TK_Q: "q", + blt.TK_R: "r", + blt.TK_S: "s", + blt.TK_T: "t", + blt.TK_U: "u", + blt.TK_V: "v", + blt.TK_W: "w", + blt.TK_X: "x", + blt.TK_Y: "y", + blt.TK_Z: "z", + blt.TK_1: "1", + blt.TK_2: "2", + blt.TK_3: "3", + blt.TK_4: "4", + blt.TK_5: "5", + blt.TK_6: "6", + blt.TK_7: "7", + blt.TK_8: "8", + blt.TK_9: "9", + blt.TK_0: "0", + blt.TK_ENTER: "Enter", + blt.TK_ESCAPE: "Escape", + blt.TK_BACKSPACE: "Backspace", + blt.TK_TAB: "Tab", + blt.TK_SPACE: "Space", + blt.TK_MINUS: "-", + blt.TK_EQUALS: "=", + blt.TK_LBRACKET: "LBracket", + blt.TK_RBRACKET: "RBracket", + blt.TK_BACKSLASH: "\\", + blt.TK_SEMICOLON: ";", + blt.TK_APOSTROPHE: "'", + blt.TK_GRAVE: "`", + blt.TK_COMMA: ",", + blt.TK_PERIOD: ".", + blt.TK_SLASH: "/", + blt.TK_F1: "F1", + blt.TK_F2: "F2", + blt.TK_F3: "F3", + blt.TK_F4: "F4", + blt.TK_F5: "F5", + blt.TK_F6: "F6", + blt.TK_F7: "F7", + blt.TK_F8: "F8", + blt.TK_F9: "F9", + blt.TK_F10: "F10", + blt.TK_F11: "F11", + blt.TK_F12: "F12", + blt.TK_PAUSE: "Pause", + blt.TK_INSERT: "Insert", + blt.TK_HOME: "Home", + blt.TK_PAGEUP: "PageUp", + blt.TK_DELETE: "Delete", + blt.TK_END: "End", + blt.TK_PAGEDOWN: "PageDown", + blt.TK_RIGHT: "Right", + blt.TK_LEFT: "Left", + blt.TK_DOWN: "Down", + blt.TK_UP: "Up", + blt.TK_KP_DIVIDE: "KP_DIVIDE", + blt.TK_KP_MULTIPLY: "KP_MULTIPLY", + blt.TK_KP_MINUS: "KP_MINUS", + blt.TK_KP_PLUS: "KP_PLUS", + blt.TK_KP_ENTER: "KP_ENTER", + blt.TK_KP_1: "KP_1", + blt.TK_KP_2: "KP_2", + blt.TK_KP_3: "KP_3", + blt.TK_KP_4: "KP_4", + blt.TK_KP_5: "KP_5", + blt.TK_KP_6: "KP_6", + blt.TK_KP_7: "KP_7", + blt.TK_KP_8: "KP_8", + blt.TK_KP_9: "KP_9", + blt.TK_KP_0: "KP_0", + blt.TK_KP_PERIOD: "KP_PERIOD", + blt.TK_SHIFT: "SHIFT", + blt.TK_CONTROL: "CONTROL", + blt.TK_ALT: "ALT", +} diff --git a/util/config.go b/util/config.go new file mode 100644 index 0000000..c1985d9 --- /dev/null +++ b/util/config.go @@ -0,0 +1,34 @@ +package util + +import ( + "encoding/json" + "flag" + "io/ioutil" + "log" +) + +type Config struct { + Title string `json:"title"` + FpsLimit int `json:"fpsLimit, omitempty" validate:"required"` + Version string `json:"version"` + MainWindowSizeX int `json:"sizeX"` + MainWindowSizeY int `json:"sizeY"` +} + +func LoadConfig() *Config { + var configArg string = "./config.json" + flag.StringVar(&configArg, "cfg", configArg, "config file location") + flag.Parse() + + // get config + data, err := ioutil.ReadFile(configArg) + if err != nil { + log.Fatalf("Application couldn't read config at %s", configArg) + } + config := new(Config) + err = json.Unmarshal(data, config) + if err != nil { + log.Fatalln(err) + } + return config +} diff --git a/util/context.go b/util/context.go new file mode 100644 index 0000000..1a2d19f --- /dev/null +++ b/util/context.go @@ -0,0 +1,44 @@ +package util + +import ( + "context" + "fmt" + "github.com/rs/zerolog" +) + +const ( + configKey = "config" + loggerKey = "logger" +) + +type ClientCtx struct { + ctx context.Context +} + +func NewClientContext(config *Config, logger *zerolog.Logger) ClientCtx { + ctx := context.Context(context.TODO()) + ctx = context.WithValue(ctx, configKey, config) + ctx = context.WithValue(ctx, loggerKey, logger) + return ClientCtx{ctx: ctx} +} + +func (c *ClientCtx) Config() *Config { + cfg, ok := c.ctx.Value(configKey).(*Config) + if !ok { + panic(fmt.Errorf("no access to config from context")) + } + return cfg +} + +func (c *ClientCtx) Logger() *zerolog.Logger { + logger, ok := c.ctx.Value(loggerKey).(*zerolog.Logger) + if !ok { + panic(fmt.Errorf("no access to logger from context")) + } + return logger +} + +//func FromContext(ctx context.Context) (*User, bool) { +// u, ok := ctx.Value(userKey).(*User) +// return u, ok +//} \ No newline at end of file diff --git a/util/util.go b/util/util.go new file mode 100644 index 0000000..b7c80bf --- /dev/null +++ b/util/util.go @@ -0,0 +1,24 @@ +package util + +import ( + "reflect" +) + +func InArray(val interface{}, array interface{}) (exists bool, index int) { + exists = false + index = -1 + + switch reflect.TypeOf(array).Kind() { + case reflect.Slice: + s := reflect.ValueOf(array) + + for i := 0; i < s.Len(); i++ { + if reflect.DeepEqual(val, s.Index(i).Interface()) == true { + index = i + exists = true + return + } + } + } + return +}