commit f35b40efc75999c4562056e916b3f9291b50ac7f Author: khuxkm Date: Mon Jul 23 07:51:34 2018 -0400 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3f945fc --- /dev/null +++ b/.gitignore @@ -0,0 +1,44 @@ +# ---> Lua +# Compiled Lua sources +luac.out + +# luarocks build files +*.src.rock +*.zip +*.tar.gz + +# Object files +*.o +*.os +*.ko +*.obj +*.elf + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo +*.def +*.exp + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Compiled .love +funkfc.love diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..472ac23 --- /dev/null +++ b/LICENSE @@ -0,0 +1,8 @@ +MIT License +Copyright (c) + +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. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..1a07ebb --- /dev/null +++ b/Makefile @@ -0,0 +1,8 @@ +funkfc.love: $(wildcard src/*) + cd src && zip -9 -r ../funkfc.love * + +.PHONY: clean test +clean: + rm funkfc.love +test: + @love funkfc.love diff --git a/README.md b/README.md new file mode 100644 index 0000000..c062bf5 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# Funk + +A fantasy console thingamagoocus. diff --git a/src/cindy.lua b/src/cindy.lua new file mode 100644 index 0000000..c3d16c4 --- /dev/null +++ b/src/cindy.lua @@ -0,0 +1,247 @@ +local cindy = { + _VERSION = 'cindy 0.1', + _LICENSE = 'WTFPL, http://www.wtfpl.net', + _URL = 'https://github.com/megagrump/cindy', + _DESCRIPTION = 'True Colors for LOVE 11', +} + +--[[----------------------------------------------------------------------------------------------------------------- + +cindy adds functions to LOVE 11.x that accept/return colors in the [0-255] range instead of the newly introduced +[0.0-1.0] range. + +In love.graphics: +- clearBytes +- getColorBytes, setColorBytes +- getBackgroundColorBytes, setBackgroundColorBytes +- getColorMaskBytes, setColorMaskBytes + +In ImageData: +- getPixelBytes, setPixelBytes +- mapPixelBytes + +In ParticleSystem: +- setColorsBytes, getColorsBytes + +In SpriteBatch: +- getColorBytes, setColorBytes + +In Shader: +- sendColorBytes + +These functions behave the same as their built-in counterparts, except for the different value range. +Note that calling them has additional runtime costs. + +To replace all original functions, call cindy.applyPatch() at the start of the program: require('cindy').applyPatch() - +this effectively restores the pre-11.0 behavior. + +-------------------------------------------------------------------------------------------------------------------]] + +local gfx, reg = love.graphics, debug.getregistry() +local ImageData, ParticleSystem, SpriteBatch, Shader = reg.ImageData, reg.ParticleSystem, reg.SpriteBatch, reg.Shader +local clear, getColor, setColor = gfx.clear, gfx.getColor, gfx.setColor +local getBackgroundColor, setBackgroundColor = gfx.getBackgroundColor, gfx.setBackgroundColor +local getColorMask, setColorMask = gfx.getColorMask, gfx.setColorMask +local getPixel, setPixel, mapPixel = ImageData.getPixel, ImageData.setPixel, ImageData.mapPixel +local getParticleColors, setParticleColors = ParticleSystem.getColors, ParticleSystem.setColors +local getBatchColor, setBatchColor = SpriteBatch.getColor, SpriteBatch.setColor +local sendColor = Shader.sendColor + +--------------------------------------------------------------------------------------------------------------------- + +local function round(v) + return math.floor(v + .5) +end + +-- convert a single channel value from [0-1] to [0-255] +function cindy.channel2byte(c) + return round(c * 255) +end + +-- convert a single channel value from [0-255] to [0-1] +function cindy.byte2channel(c) + return c / 255 +end + +-- convert RGBA values from [0-1] to [0-255] +function cindy.rgba2bytes(r, g, b, a) + return round(r * 255), round(g * 255), round(b * 255), a and round(a * 255) +end + +-- convert RGBA values from [0-255] to [0-1] +function cindy.bytes2rgba(r, g, b, a) + return r / 255, g / 255, b / 255, a and a / 255 +end + +-- convert RGBA value table from [0-1] to [0-255]. places the result in dest, if given +function cindy.table2bytes(color, dest) + dest = dest or {} + dest[1], dest[2], dest[3], dest[4] = cindy.rgba2bytes(color[1], color[2], color[3], color[4]) + return dest +end + +-- convert RGBA value table from [0-255] to [0-1]. places the result in dest, if given +function cindy.bytes2table(color, dest) + dest = dest or {} + dest[1], dest[2], dest[3], dest[4] = cindy.bytes2rgba(color[1], color[2], color[3], color[4]) + return dest +end + +-- convert RGBA values or table from [0-1] to [0-255]. returns separate values +function cindy.color2bytes(r, g, b, a) + if type(r) == 'table' then + r, g, b, a = r[1], r[2], r[3], r[4] + end + + return cindy.rgba2bytes(r, g, b, a) +end + +-- convert RGBA values or table from [0-255] to [0-1]. returns separate values +function cindy.bytes2color(r, g, b, a) + if type(r) == 'table' then + r, g, b, a = r[1], r[2], r[3], r[4] + end + + return cindy.bytes2rgba(r, g, b, a) +end + +-- patch all LÖVE functions to accept colors in the [0-255] range +function cindy.applyPatch() + gfx.clear, gfx.getColor, gfx.setColor = gfx.clearBytes, gfx.getColorBytes, gfx.setColorBytes + gfx.getBackgroundColor, gfx.setBackgroundColor = gfx.getBackgroundColorBytes, gfx.setBackgroundColorBytes + gfx.getColorMask, gfx.setColorMask = gfx.getMaskColorBytes, gfx.setMaskColorBytes + ImageData.getPixel, ImageData.setPixel = ImageData.getPixelBytes, ImageData.setPixelBytes + ImageData.mapPixel = ImageData.mapPixelBytes + ParticleSystem.getColors, ParticleSystem.setColors = ParticleSystem.getColorsBytes, ParticleSystem.setColorsBytes + SpriteBatch.getColor, SpriteBatch.setColor = SpriteBatch.getColorBytes, SpriteBatch.setColorBytes + Shader.sendColor = Shader.sendColorBytes + + return cindy +end + +--------------------------------------------------------------------------------------------------------------------- + +local tempTables = { {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {} } + +function gfx.getColorBytes() + return cindy.rgba2bytes(getColor()) +end + +function gfx.setColorBytes(r, g, b, a) + return setColor(cindy.bytes2color(r, g, b, a)) +end + +function gfx.getBackgroundColorBytes() + return cindy.rgba2bytes(getBackgroundColor()) +end + +function gfx.setBackgroundColorBytes(r, g, b, a) + return setBackgroundColor(cindy.bytes2color(r, g, b, a)) +end + +function gfx.getColorMaskBytes() + return cindy.rgba2bytes(getColorMask()) +end + +function gfx.setColorMaskBytes(r, g, b, a) + return setColorMask(cindy.bytes2color(r, g, b, a)) +end + +function gfx.clearBytes(...) + local nargs = select('#', ...) + + if nargs == 0 or type(select(1, ...)) == 'boolean' then + return clear(...) + end + + local args = {...} + for i = 1, nargs do + if type(args[i]) == 'table' then + args[i] = cindy.bytes2table(args[i], tempTables[i]) + elseif type(args[i]) == 'number' then + args[i] = args[i] / 255 + end + end + + return clear(unpack(args)) +end + +--------------------------------------------------------------------------------------------------------------------- + +function ImageData:getPixelBytes(x, y) + return cindy.rgba2bytes(getPixel(self, x, y)) +end + +function ImageData:setPixelBytes(x, y, r, g, b, a) + return setPixel(self, x, y, cindy.bytes2rgba(r, g, b, a)) +end + +function ImageData:mapPixelBytes(fn) + return mapPixel(self, function(x, y, r, g, b, a) + return cindy.bytes2rgba(fn(x, y, cindy.rgba2bytes(r, g, b, a))) + end) +end + +--------------------------------------------------------------------------------------------------------------------- + +function ParticleSystem:setColorsBytes(...) + local args, nargs = {...}, select('#', ...) + + if type(args[1]) == 'table' then + for i = 1, nargs do + args[i] = cindy.bytes2table(args[i], tempTables[i]) + end + else + for i = 1, nargs do + args[i] = args[i] / 255 + end + end + + return setParticleColors(self, unpack(args)) +end + +function ParticleSystem:getColorsBytes() + local colors = { getParticleColors(self) } + local ncolors = #colors + + for i = 1, ncolors do + local rgba = colors[i] + rgba[1], rgba[2], rgba[3], rgba[4] = cindy.rgba2bytes(rgba[1], rgba[2], rgba[3], rgba[4]) + end + + return unpack(colors) +end + +--------------------------------------------------------------------------------------------------------------------- + +function SpriteBatch:getColorBytes() + local r, g, b, a = getBatchColor(self) + + if r then + return cindy.rgba2bytes(r, g, b, a) + end +end + +function SpriteBatch:setColorBytes(r, g, b, a) + if r then + return setBatchColor(self, cindy.bytes2color(r, g, b, a)) + end + + return setBatchColor(self) +end + +--------------------------------------------------------------------------------------------------------------------- + +function Shader:sendColorBytes(name, ...) + local colors, ncolors = {...}, select('#', ...) + + for i = 1, ncolors do + colors[i] = cindy.bytes2table(colors[i], tempTables[i]) + end + + return sendColor(self, name, unpack(colors)) +end + +--------------------------------------------------------------------------------------------------------------------- + +return cindy diff --git a/src/conf.lua b/src/conf.lua new file mode 100644 index 0000000..62f76ee --- /dev/null +++ b/src/conf.lua @@ -0,0 +1,55 @@ +local conf = {} + +function love.conf(t) + t.identity = "funkfc" -- The name of the save directory (string) + t.appendidentity = false -- Search files in source directory before save directory (boolean) + t.version = "11.0" -- The LOVE version this game was made for (string) + t.console = false -- Attach a console (boolean, Windows only) + t.accelerometerjoystick = false -- Enable the accelerometer on iOS and Android by exposing it as a Joystick (boolean) + t.externalstorage = false -- True to save files (and read from the save directory) in external storage on Android (boolean) + t.gammacorrect = false -- Enable gamma-correct rendering, when supported by the system (boolean) + + t.audio.mixwithsystem = true -- Keep background music playing when opening LOVE (boolean, iOS and Android only) + + t.window.title = "Funk" -- The window title (string) + t.window.icon = nil -- Filepath to an image to use as the window's icon (string) + t.window.width = 256*2 -- The window width (number) + t.window.height = 224*2 -- The window height (number) + t.window.borderless = false -- Remove all border visuals from the window (boolean) + t.window.resizable = false -- Let the window be user-resizable (boolean) + t.window.minwidth = 1 -- Minimum window width if the window is resizable (number) + t.window.minheight = 1 -- Minimum window height if the window is resizable (number) + t.window.fullscreen = false -- Enable fullscreen (boolean) + t.window.fullscreentype = "desktop" -- Choose between "desktop" fullscreen or "exclusive" fullscreen mode (string) + t.window.vsync = 1 -- Vertical sync mode (number) + t.window.msaa = 0 -- The number of samples to use with multi-sampled antialiasing (number) + t.window.display = 1 -- Index of the monitor to show the window in (number) + t.window.highdpi = false -- Enable high-dpi mode for the window on a Retina display (boolean) + t.window.x = nil -- The x-coordinate of the window's position in the specified display (number) + t.window.y = nil -- The y-coordinate of the window's position in the specified display (number) + + t.modules.audio = false -- Enable the audio module (boolean) + t.modules.data = true -- Enable the data module (boolean) + t.modules.event = true -- Enable the event module (boolean) + t.modules.font = true -- Enable the font module (boolean) + t.modules.graphics = true -- Enable the graphics module (boolean) + t.modules.image = true -- Enable the image module (boolean) + t.modules.joystick = false -- Enable the joystick module (boolean) + t.modules.keyboard = true -- Enable the keyboard module (boolean) + t.modules.math = false -- Enable the math module (boolean) + t.modules.mouse = false -- Enable the mouse module (boolean) + t.modules.physics = false -- Enable the physics module (boolean) + t.modules.sound = false -- Enable the sound module (boolean) + t.modules.system = false -- Enable the system module (boolean) + t.modules.thread = false -- Enable the thread module (boolean) + t.modules.timer = true -- Enable the timer module (boolean), Disabling it will result 0 delta time in love.update + t.modules.touch = false -- Enable the touch module (boolean) + t.modules.video = false -- Enable the video module (boolean) + t.modules.window = true -- Enable the window module (boolean) + + t.debug = true + + conf.properties = t +end + +return conf diff --git a/src/log.lua b/src/log.lua new file mode 100644 index 0000000..849088b --- /dev/null +++ b/src/log.lua @@ -0,0 +1,8 @@ +local function log(s,prefix) + if not CONFIG.debug then return end +-- for i=1,#CONFIG.ignore do if (prefix..debug.getinfo(2).name)==CONFIG.ignore[i] then return end end + prefix = prefix and prefix or "" + print(prefix..debug.getinfo(2).name..":: "..s) +end + +return log diff --git a/src/main.lua b/src/main.lua new file mode 100644 index 0000000..c6d4fdf --- /dev/null +++ b/src/main.lua @@ -0,0 +1,21 @@ +_G.CONFIG = require("conf").properties +local log = require("log") +local pal = require("palette").getPalette("CADE-15") +function love.load() + require("cindy").applyPatch() + scr = love.graphics.newCanvas(256,244) + love.graphics.setCanvas(scr) + pal.setColor(10) + love.graphics.rectangle("fill",0,0,5,5) + love.graphics.setCanvas() +end + +function love.update(dt) + if love.keyboard.isDown("escape") then love.event.quit() end +end + +function love.draw() + love.graphics.setBackgroundColor(0,0,0) + love.graphics.setColor(255,255,255) + love.graphics.draw(scr,0,0,0,2,2) +end diff --git a/src/palette.lua b/src/palette.lua new file mode 100644 index 0000000..2191c3d --- /dev/null +++ b/src/palette.lua @@ -0,0 +1,46 @@ +local palette = {} +local palettes = {} + +local function setColorPal(p) + return function(i) + c = p[i+1] + love.graphics.setColor(c[1],c[2],c[3]) + end +end + +local function setBGColorPal(p) + return function(i) + c = p[i+1] + love.graphics.setBackgroundColor(c[1],c[2],c[3]) + end +end + +local function getColorPal(c) + return function(i,name_fields) + i = i + 1 + name_fields = name_fields and name_fields or false + if not name_fields then return c[i] end + local col = c[i] + col.r = col[1] + col.g = col[2] + col.b = col[3] + return col + end +end + +function palette.register(name,colors) + local pal = {} + pal.name = name + pal.colors = colors + pal.setColor = setColorPal(colors) + pal.setBackgroundColor = setBGColorPal(colors) + pal.getColor = getColorPal(colors) + palettes[name]=pal + return pal +end + +function palette.getPalette(name) return palettes[name] end + +palette.register("CADE-15",{{56,40,44},{16,15,12},{53,22,92},{68,98,188},{76,186,255},{4,85,36},{28,153,36},{92,74,108},{124,142,141},{56,16,0},{142,2,50},{188,70,4},{250,125,97},{212,146,12},{255,215,80},{226,241,210}}) + +return palette diff --git a/tools/cade15.gpl b/tools/cade15.gpl new file mode 100644 index 0000000..1498a5a --- /dev/null +++ b/tools/cade15.gpl @@ -0,0 +1,19 @@ +GIMP Palette +Name: CADE-15 by MonstersGoBoom +# Generated by palstring2gpl + 56 40 44 Color0 + 16 15 12 Color1 + 53 22 92 Color2 + 68 98 188 Color3 + 76 186 255 Color4 + 4 85 36 Color5 + 28 153 36 Color6 + 92 74 108 Color7 +124 142 141 Color8 + 56 16 0 Color9 +142 2 50 Color10 +188 70 4 Color11 +250 125 97 Color12 +212 146 12 Color13 +255 215 80 Color14 +226 241 210 Color15 diff --git a/tools/cade15.paldef b/tools/cade15.paldef new file mode 100644 index 0000000..3bf78ca --- /dev/null +++ b/tools/cade15.paldef @@ -0,0 +1 @@ +palette.register("CADE-15",{{56,40,44},{16,15,12},{53,22,92},{68,98,188},{76,186,255},{4,85,36},{28,153,36},{92,74,108},{124,142,141},{56,16,0},{142,2,50},{188,70,4},{250,125,97},{212,146,12},{255,215,80},{226,241,210}}) \ No newline at end of file diff --git a/tools/cade15.palstr b/tools/cade15.palstr new file mode 100644 index 0000000..272b2b6 --- /dev/null +++ b/tools/cade15.palstr @@ -0,0 +1 @@ +38282c100f0c35165c4462bc4cbaff0455241c99245c4a6c7c8e8d3810008e0232bc4604fa7d61d4920cffd750e2f1d2 diff --git a/tools/palstr2gpl b/tools/palstr2gpl new file mode 100755 index 0000000..69d2c41 --- /dev/null +++ b/tools/palstr2gpl @@ -0,0 +1,29 @@ +#!/usr/bin/python +import argparse + +TITLE = "GIMP Palette" +NAME_HEAD = "Name: " +COMMENT = "# {}" + +HEADER = "{}\n{}{{}}\n{}\n".format(TITLE,NAME_HEAD,COMMENT.format("Generated by palstring2gpl")) + +COLOR_STR = "{:>3} {:>3} {:>3} Color{}\n" + +parser = argparse.ArgumentParser(description="Converts TIC-80 style pal strings to GIMP palettes.") +parser.add_argument("palstr",help="File with the palette string.") +parser.add_argument("gpl",help="File to put result in.") +parser.add_argument("name",help="Name of palette. Defaults to 'New palette'.",default="New palette") +args = parser.parse_args() + +def split(s,n): + for i in range(0,len(s),n): + yield s[i:i+n] + +t = [] +with open(args.palstr) as f: + t = [[int(x,16) for x in split(y,2)] for y in split(f.read().strip(),6)] +#print(t) +with open(args.gpl,"w") as f: + f.write(HEADER.format(args.name)) + for c in range(len(t)): + f.write(COLOR_STR.format(*(t[c]+[c]))) diff --git a/tools/palstr2paldef b/tools/palstr2paldef new file mode 100755 index 0000000..9ff1037 --- /dev/null +++ b/tools/palstr2paldef @@ -0,0 +1,29 @@ +#!/usr/bin/python +import argparse + +HEADER = "palette.register(\"{}\",{{" +COLOR_STR = "{{{},{},{}}}" +FOOTER = "})" + +parser = argparse.ArgumentParser(description="Converts TIC-80 style pal strings to palette definitions (for src/palette.lua)") +parser.add_argument("palstr",help="File with the palette string.") +parser.add_argument("paldef",help="File to put result in.") +parser.add_argument("name",help="Name of palette. Defaults to 'New palette'.",default="New palette") +args = parser.parse_args() + +def split(s,n): + for i in range(0,len(s),n): + yield s[i:i+n] + +t = [] +with open(args.palstr) as f: + t = [[int(x,16) for x in split(y,2)] for y in split(f.read().strip(),6)] +#print(t) +with open(args.paldef,"w") as f: + f.write(HEADER.format(args.name)) + for i in range(len(t)): + c = t[i] + f.write(COLOR_STR.format(*c)) + if (i+1)