music stop; sprite alpha blending; sprite sorting; change to anim

This commit is contained in:
John Alanbrook 2023-11-21 07:07:50 +00:00
parent 051d8653fb
commit 6193bceb74
12 changed files with 136 additions and 74 deletions

View file

@ -31,36 +31,35 @@ ifeq ($(CC), x86_64-w64-mingw32-gcc)
endif
ifdef NEDITOR
CFLAGS += -DNO_EDITOR
CPPFLAGS += -DNO_EDITOR
endif
ifdef NFLAC
CFLAGS += -DNFLAC
CPPFLAGS += -DNFLAC
endif
ifdef NMP3
CFLAGS += -DNMP3
CPPFLAGS += -DNMP3
endif
ifdef NSVG
CFLAGS += -DNSVG
CPPFLAGS += -DNSVG
endif
ifdef NQOA
CFLAGS += -DNQOA
CPPFLAGS += -DNQOA
endif
ifeq ($(DBG),1)
CFLAGS += -g
CPPFLAGS += -g
INFO += _dbg
LDFLAGS += -g
else
CFLAGS += -DNDEBUG
CPPFLAGS += -DNDEBUG
LDFLAGS += -s
endif
ifeq ($(OPT),small)
CFLAGS += -Oz -flto -fno-ident -fno-asynchronous-unwind-tables
CPPFLAGS += -Oz -flto -fno-ident -fno-asynchronous-unwind-tables
LDFLAGS += -flto
ifeq ($(CC), emcc)
@ -70,15 +69,14 @@ ifeq ($(OPT),small)
INFO := $(addsuffix _small,$(INFO))
else
ifeq ($(OPT), 1)
CFLAGS += -O2 -flto
LDFLAGS += -flto
CPPFLAGS += -O2 -flto
INFO := $(addsuffix _opt,$(INFO))
else
CFLAGS += -O0
CPPFLAGS += -O0
endif
endif
CFLAGS += -DHAVE_CEIL -DCP_USE_CGTYPES=0 -DCP_USE_DOUBLES=0 -DTINYSPLINE_FLOAT_PRECISION -DHAVE_FLOOR -DHAVE_FMOD -DHAVE_LRINT -DHAVE_LRINTF $(includeflag) -MD $(WARNING_FLAGS) -I. -DVER=\"$(VER)\" -DINFO=\"$(INFO)\"
CPPFLAGS += -DHAVE_CEIL -DCP_USE_CGTYPES=0 -DCP_USE_DOUBLES=0 -DTINYSPLINE_FLOAT_PRECISION -DHAVE_FLOOR -DHAVE_FMOD -DHAVE_LRINT -DHAVE_LRINTF $(includeflag) -MD $(WARNING_FLAGS) -I. -DVER=\"$(VER)\" -DINFO=\"$(INFO)\"
PKGCMD = tar --directory $(BIN) --exclude="./*.a" --exclude="./obj" -czf $(DISTDIR)/$(DIST) .
ZIP = .tar.gz
@ -89,32 +87,32 @@ ifeq ($(ARCH),)
endif
STEAMPATH = steam/sdk/redistributable_bin
DISCORDPATH = discord/lib
ifdef DISCORD
LDPATHS += $(DISCORDPATH)/$(ARCH)
LDLIBS += discord_game_sdk
CPPFLAGS += -DDISCORD
endif
ifdef STEAM
LDLIBS += steam_api
LDPATHS += $(STEAMPATH)/$(ARCH)
endif
ifeq ($(OS), Windows_NT)
LDFLAGS += -mwin32 -static -g
CFLAGS += -mwin32 -g
LDFLAGS += -mwin32 -static
CPPFLAGS += -mwin32
LDLIBS += mingw32 kernel32 d3d11 user32 shell32 dxgi gdi32 ws2_32 ole32 winmm setupapi m
EXT = .exe
ARCH := x86_64
PKGCMD = cd $(BIN); zip -q -r $(MAKEDIR)/$(DISTDIR)/$(DIST) . -x \*.a ./obj/\*
ZIP = .zip
UNZIP = unzip -o -q $(DISTDIR)/$(DIST) -d $(DESTDIR)
ifdef STEAM
LDPATHS += $(STEAMPATH)/win64
LDLIBS += steam_api64
endif
else ifeq ($(OS), ios)
TTARGET = arm64-apple-ios13.1
SYSRT := /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk
CFLAGS += --target=$(TTARGET) -isysroot $(SYSRT) -DTARGET_OS_IPHONE -x objective-c
LDFLAGS += --target=$(TTARGET) -isysroot $(SYSRT) -framework Foundation -framework UIKit -framework Metal -framework MetalKit -framework AudioToolbox -framework AVFoundation
else ifeq ($(CC), emcc)
OS := Web
LDFLAGS += -sMIN_WEBGL_VERSION=2 -sMAX_WEBGL_VERSION=2 -pthread -sTOTAL_MEMORY=450MB
CFLAGS += -pthread
CPPFLAGS += -pthread
LDLIBS += pthread quickjs GL openal c m dl
CC = emcc
EXT = .html
@ -125,21 +123,14 @@ else
OS := Linux
LDFLAGS += -pthread -rdynamic
LDLIBS += GL pthread c m dl X11 Xi Xcursor EGL asound
ifdef STEAM
LDLIBS += steam_api
LDPATHS += $(STEAMPATH)/linux64
endif
endif
ifeq ($(UNAME), Darwin)
OS := macos
CFLAGS += -arch $(ARCH) -x objective-c
LDFLAGS += -arch $(ARCH) -framework Cocoa -framework QuartzCore -framework AudioToolbox -framework Metal -framework MetalKit
ifdef STEAM
LDPATHS += $(STEAMPATH)/osx
LDLIBS += steam_api
endif
CPPFLAGS += -arch $(ARCH)
CFLAGS += -x objective-c
CXXFLAGS += -std=c++11
LDFLAGS += -framework Cocoa -framework QuartzCore -framework AudioToolbox -framework Metal -framework MetalKit
endif
endif
@ -168,7 +159,7 @@ includeflag := $(addprefix -I, $(includeflag))
# Adding different SDKs
ifdef STEAM
includeflag += -Isteam/sdk/public
CFLAGS += -DSTEAM
CPPFLAGS += -DSTEAM
# BIN += /steam
endif
@ -204,7 +195,7 @@ install: $(BIN)/$(NAME)
$(BIN)/$(NAME): $(BIN)/libengine.a $(BIN)/libquickjs.a
@echo Linking $(NAME)
$(LD) $^ $(LDFLAGS) -L$(BIN) $(LDPATHS) $(LDLIBS) -o $@
$(LD) $^ $(CPPFLAGS) $(LDFLAGS) -L$(BIN) $(LDPATHS) $(LDLIBS) -o $@
@echo Finished build
$(DISTDIR)/$(DIST): $(BIN)/$(NAME)
@ -257,17 +248,17 @@ $(BIN)/libquickjs.a: $(QUICKJS_O)
$(OBJDIR)/%.o: %.c
@mkdir -p $(@D)
@echo Making C object $@
@$(CC) $(CFLAGS) -c $< -o $@
@$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
$(OBJDIR)/%.o: %.cpp
@mkdir -p $(@D)
@echo Making C++ object $@ with $(CXX)
@$(CXX) $(CFLAGS) -c $< -o $@
@$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@
$(OBJDIR)/%.o: %.m
@mkdir -p $(@D)
@echo Making Objective-C object $@
@$(CC) $(CFLAGS) -c $< -o $@
@$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
shaders: $(SHADERS)
@echo Making shaders

View file

@ -33,6 +33,11 @@ Basic boolean flags, set to 0 or 1, to enable or disable features in the build
## Building for Steam
-Get the steam SDK
-Unpack it into a folder named 'steam' at the top level directory
-Move the steam libs into the lib folders arm64, x86, and x86_64
-Make with STEAM=1
Steam uses a C++ based SDK, so a C-only compiler like TCC will not work.
Steam uses a C++ based SDK, so a C-only compiler like TCC will not work.
## Building with Discord
-Get the steam SDK
-Make with DISCORD=1

View file

@ -98,6 +98,7 @@ component.sprite.impl = {
set pos(x) { cmd(37,this.id,x); },
set layer(x) { cmd(60, this.id, x); },
get layer() { return undefined; },
emissive(x) { cmd(170, this.id, x); },
boundingbox() {
return cwh2bb([0,0],[0,0]);
@ -251,7 +252,7 @@ SpriteAnim.find.doc = 'Given a path, find the relevant animation for the file.';
/* Container to play sprites and anim2ds */
component.char2d = Object.create(component.sprite);
Object.assign(component.char2d, {
component.char2dimpl = {
boundingbox() {
var dim = this.acur.dim.slice();
dim = dim.scale(this.gameobject.scale);
@ -273,8 +274,7 @@ Object.assign(component.char2d, {
play_anim(anim) {
this.acur = anim;
this.frame = 0;
this.timer.time = this.acur.frames[this.frame].time;
this.timer.start();
this.gameobject.delay(this.advance.bind(this), this.acur.frames[this.frame].time);
this.setsprite();
},
@ -303,9 +303,7 @@ Object.assign(component.char2d, {
advance() {
this.frame = (this.frame + 1) % this.acur.frames.length;
this.setsprite();
if (this.frame === 0 && !this.acur.loop)
this.timer.pause();
this.gameobject.delay(this.advance.bind(this), this.acur.frames[this.frame].time);
},
devance() {
@ -329,7 +327,6 @@ Object.assign(component.char2d, {
},
kill() {
this.timer.kill();
cmd(9, this.id);
},
@ -351,7 +348,9 @@ Object.assign(component.char2d, {
}
Object.hide(this, 'acur');
},
});
};
Object.assign(component.char2d, component.char2dimpl);
component.char2d.doc = {
doc: "An animation player for sprites.",

View file

@ -108,6 +108,10 @@ var gameobject = {
if (!this.level) return this.worldpos();
return this.level.world2this(this.worldpos());
},
get draw_layer() { return cmd(171, this.body); },
set draw_layer(x) { cmd(172, this.body, x); },
get elasticity() { return cmd(107,this.body); },
set elasticity(x) { cmd(106,this.body,x); },
@ -130,10 +134,6 @@ var gameobject = {
set phys(x) { set_body(1, this.body, x); },
get phys() { return q_body(0,this.body); },
// set mask(x) { cmd(41, this.body, x); },
// get mask() { return cmd(43, this.body); },
// set category(x) { cmd(40, this.body, x); },
// get category() { return cmd(42, this.body); },
get velocity() { return q_body(3, this.body); },
set velocity(x) { set_body(9, this.body, x); },
// get damping() { return cmd(157,this.body); },
@ -225,10 +225,10 @@ var gameobject = {
delete this.objects[obj.toString()];
delete this[obj.toString()];
},
},
draw_layer: 1,
components: {},
objects: {},
level: undefined,
@ -345,6 +345,7 @@ var gameobject = {
max_angularvelocity: Infinity,
mass:1,
layer:0,
draw_layer:0,
worldpos() { return [0,0]; },
save:true,

View file

@ -137,6 +137,18 @@ HMM_Vec2 mat_t_dir(HMM_Mat3 m, HMM_Vec2 dir)
return HMM_MulM3V3(m, (HMM_Vec3){dir.x, dir.y, 1}).XY;
}
HMM_Vec3 mat3_t_pos(HMM_Mat4 m, HMM_Vec3 pos)
{
return HMM_MulM4V4(m, (HMM_Vec4){pos.X, pos.Y, pos.Z, 1}).XYZ;
}
HMM_Vec3 mat3_t_dir(HMM_Mat4 m, HMM_Vec3 dir)
{
m.Columns[4] = (HMM_Vec4){0,0,0,1};
return mat3_t_pos(m, dir);
}
HMM_Vec2 goscale(struct gameobject *go, HMM_Vec2 pos)
{
return HMM_MulV2(go->scale.XY, pos);
@ -301,6 +313,7 @@ int MakeGameobject() {
.mass = 1.f,
.next = -1,
.sensor = 0,
.drawlayer = 0,
.shape_cbs = NULL,
.gravity = 1,
.cgravity = (HMM_Vec2){0,0},

View file

@ -46,6 +46,7 @@ typedef struct gameobject {
HMM_Mat3 transform;
struct gameobject *master;
transform2d t; /* The local transformation of this object */
float drawlayer;
} gameobject;
extern struct gameobject *gameobjects;
@ -77,6 +78,9 @@ HMM_Vec2 mat_t_pos(HMM_Mat3 m, HMM_Vec2 pos);
/* Transform a direction via the matrix - does not take into account translation of matrix */
HMM_Vec2 mat_t_dir(HMM_Mat3 m, HMM_Vec2 dir);
HMM_Vec3 mat3_t_pos(HMM_Mat4 m, HMM_Vec3 pos);
HMM_Vec3 mat3_t_dir(HMM_Mat4 m, HMM_Vec3 dir);
struct gameobject *get_gameobject_from_id(int id);
struct gameobject *id2go(int id);
int id_from_gameobject(struct gameobject *go);

View file

@ -1181,6 +1181,15 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
case 169:
ret = num2js(js2go(argv[1])->timescale);
break;
case 170:
id2sprite(js2int(argv[1]))->emissive = js2color(argv[2]);
break;
case 171:
ret = num2js(js2go(argv[1])->drawlayer);
break;
case 172:
js2go(argv[1])->drawlayer = js2number(argv[2]);
break;
}
if (str)

View file

@ -13,5 +13,6 @@ struct dsp_midi_song {
void play_song(const char *midi, const char *sf);
void dsp_midi_fillbuf(struct dsp_midi_song *song, void *out, int n);
void music_stop();
#endif

View file

@ -30,6 +30,7 @@ struct sprite_vert {
HMM_Vec2 pos;
HMM_Vec2 uv;
struct rgba color;
struct rgba emissive;
};
static int num_spriteverts = 5000;
@ -54,6 +55,7 @@ struct slice9_vert {
int make_sprite(int go) {
struct sprite sprite = {
.color = color_white,
.emissive = {0,0,0,0},
.size = {1.f, 1.f},
.tex = texture_loadfromfile(NULL),
.go = go,
@ -115,21 +117,30 @@ void sprite_io(struct sprite *sprite, FILE *f, int read) {
}
}
int sprite_sort(int *a, int *b)
{
struct gameobject *goa = id2go(sprites[*a].go);
struct gameobject *gob = id2go(sprites[*b].go);
if (goa->drawlayer == gob->drawlayer) return 0;
if (goa->drawlayer > gob->drawlayer) return 1;
return -1;
}
void sprite_draw_all() {
sg_apply_pipeline(pip_sprite);
sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(projection));
static struct sprite **layers[5];
for (int i = 0; i < 5; i++)
arrfree(layers[i]);
static int *layers;
if (layers) arrfree(layers);
for (int i = 0; i < arrlen(sprites); i++)
if (sprites[i].go >= 0 && sprites[i].enabled) arrpush(layers[sprites[i].layer], &sprites[i]);
if (sprites[i].go >= 0 && sprites[i].enabled) arrpush(layers, i);
for (int i = 4; i >= 0; i--)
for (int j = 0; j < arrlen(layers[i]); j++)
sprite_draw(layers[i][j]);
if (arrlen(layers) == 0) return;
if (arrlen(layers) > 1)
qsort(layers, arrlen(layers), sizeof(*layers), sprite_sort);
for (int i = 0; i < arrlen(layers); i++)
sprite_draw(&sprites[layers[i]]);
}
void sprite_loadtex(struct sprite *sprite, const char *path, struct glrect frame) {
@ -151,9 +162,11 @@ void sprite_initialize() {
.attrs = {
[0].format = SG_VERTEXFORMAT_FLOAT2,
[1].format = SG_VERTEXFORMAT_FLOAT2,
[2].format = SG_VERTEXFORMAT_UBYTE4N}},
[2].format = SG_VERTEXFORMAT_UBYTE4N,
[3].format = SG_VERTEXFORMAT_UBYTE4N}},
.primitive_type = SG_PRIMITIVETYPE_TRIANGLE_STRIP,
.label = "sprite pipeline",
.colors[0].blend = blend_trans,
.depth = {
.write_enabled = true,
.compare = SG_COMPAREFUNC_LESS_EQUAL,
@ -192,7 +205,7 @@ void sprite_initialize() {
}
/* offset given in texture offset, so -0.5,-0.5 results in it being centered */
void tex_draw(struct Texture *tex, HMM_Mat3 m, struct glrect r, struct rgba color, int wrap, HMM_Vec2 wrapoffset, float wrapscale) {
void tex_draw(struct Texture *tex, HMM_Mat3 m, struct glrect r, struct rgba color, int wrap, HMM_Vec2 wrapoffset, float wrapscale, struct rgba emissive) {
struct sprite_vert verts[4];
HMM_Vec2 sposes[4] = {
@ -208,9 +221,9 @@ void tex_draw(struct Texture *tex, HMM_Mat3 m, struct glrect r, struct rgba colo
};
for (int i = 0; i < 4; i++) {
HMM_Vec3 v = HMM_MulM3V3(m, (HMM_Vec3){sposes[i].X, sposes[i].Y, 1.0});
verts[i].pos = (HMM_Vec2){v.X, v.Y};
verts[i].pos = mat_t_pos(m, sposes[i]);
verts[i].color = color;
verts[i].emissive = emissive;
}
if (!wrap) {
@ -257,7 +270,7 @@ void sprite_draw(struct sprite *sprite) {
HMM_Mat3 sm = HMM_MulM3(ss, ts);
m = HMM_MulM3(m, sm);
tex_draw(sprite->tex, m, sprite->frame, sprite->color, 0, (HMM_Vec2){0,0}, 0);
tex_draw(sprite->tex, m, sprite->frame, sprite->color, 0, (HMM_Vec2){0,0}, 0, sprite->emissive);
}
}
@ -275,7 +288,7 @@ void gui_draw_img(const char *img, HMM_Vec2 pos, HMM_Vec2 scale, float angle, in
t.pos = pos;
t.angle = angle;
t.scale = scale;
tex_draw(tex, transform2d2mat(t), tex_get_rect(tex), color, wrap, wrapoffset, wrapscale);
tex_draw(tex, transform2d2mat(t), tex_get_rect(tex), color, wrap, wrapoffset, wrapscale, (struct rgba){0,0,0,0});
}
void slice9_draw(const char *img, HMM_Vec2 pos, HMM_Vec2 dimensions, struct rgba color)

View file

@ -15,6 +15,7 @@ struct sprite {
HMM_Vec2 size;
float rotation;
struct rgba color;
struct rgba emissive;
int go; /* id of gameobject */
struct Texture *tex;
struct glrect frame;

View file

@ -36,6 +36,10 @@
#include "steamffi.h"
#endif
#ifdef DISCORD
#include "discord.h"
#endif
#include "string.h"
#include "render.h"
@ -349,6 +353,22 @@ int main(int argc, char **argv) {
#ifdef STEAM
steaminit();
#endif
#ifdef DISCORD
struct IDiscordCore *core;
DiscordCreate(DISCORD_VERSION, &(struct DiscordCreateParams){
.client_id = 1176355046590533714,
.flags = DiscordCreateFlags_Default
}, &core);
struct IDiscordUserManager *dum;
struct IDiscordActivityManager *dam;
dam = core->get_activity_manager(core);
struct DiscordActivity da;
sprintf(da.state, "Playing Solo Pinball");
sprintf(da.details, "COMPetitive");
dam->update_activity(dam, &da, NULL, NULL);
#endif
stm_setup(); /* time */

View file

@ -2,15 +2,18 @@
in vec2 vertex;
in vec2 uv;
in vec4 vc;
in vec4 emissive;
out vec2 texcoords;
out vec4 fcolor;
out vec4 femissive;
uniform vs_p { mat4 proj; };
void main()
{
fcolor = vc;
femissive = emissive;
texcoords = uv;
gl_Position = proj * vec4(vertex, 0.0, 1.0);
}
@ -19,6 +22,7 @@ void main()
@fs fs
in vec2 texcoords;
in vec4 fcolor;
in vec4 femissive;
out vec4 color;
uniform texture2D image;
@ -31,7 +35,8 @@ void main()
if (color.a <= 0.1f)
discard;
color *=fcolor;
color *= fcolor;
color.xyz = mix(color.xyz, femissive.xyz, femissive.a);
}
@end