From 5e81db3dc12d2d20b7e40dd16ffff27265b53749 Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Fri, 8 Sep 2023 07:36:52 +0300 Subject: [PATCH] first working version --- sdr/foo.v.glsl | 4 +- src/demo.c | 159 +++++++++++++++++++++++++++++++++++++++++++-- src/music.c | 197 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/music.h | 13 ++++ 4 files changed, 365 insertions(+), 8 deletions(-) create mode 100644 src/music.c create mode 100644 src/music.h diff --git a/sdr/foo.v.glsl b/sdr/foo.v.glsl index 1e8d9b6..ce9586b 100644 --- a/sdr/foo.v.glsl +++ b/sdr/foo.v.glsl @@ -1,12 +1,14 @@ attribute vec4 attr_vertex, attr_color; attribute vec2 attr_texcoord; +uniform mat4 matrix_modelview_projection; + varying vec4 color; varying vec2 texcoord; void main() { - gl_Position = attr_vertex; + gl_Position = matrix_modelview_projection * attr_vertex; texcoord = attr_texcoord; color = attr_color; } diff --git a/src/demo.c b/src/demo.c index 265e410..4e857f3 100644 --- a/src/demo.c +++ b/src/demo.c @@ -1,15 +1,30 @@ #include +#include #include #include "demo.h" #include "opengl.h" #include "sanegl.h" #include "assman.h" #include "cmesh.h" +#include "music.h" +static void draw_texquad(float x, float y, float w, float h); +static int piece_hit(int x, int y); static void gen_default_textures(void); static unsigned int sdr_foo; static unsigned int tex_logo; +static unsigned int tex_bg, tex_piece; +static int bg_width, bg_height; +static float bg_aspect; +static int piece_width, piece_height; +static float vis_width, vis_height; +static float xoffs, yoffs; +static float xpos, ypos; +static int dragging; +static int prev_mx, prev_my; +static int xtarg, ytarg; +static int inplace; int demo_init(void) { @@ -20,6 +35,10 @@ int demo_init(void) return -1; } + if(init_music() == -1) { + return -1; + } + /* global "debug" shader which just visualizes normals */ if(!(sdr_dbg = get_sdrprog("sdr/dbg.v.glsl", "sdr/dbg.p.glsl"))) { return -1; @@ -49,13 +68,33 @@ int demo_init(void) gl_end(); swap_buffers(); - glEnable(GL_DEPTH_TEST); + if(!(tex_bg = get_tex2d("data/bunny_bg.jpg"))) { + return -1; + } + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + bg_width = 2048; + bg_height = 1360; + bg_aspect = (float)bg_width / (float)bg_height; + + if(!(tex_piece = get_tex2d("data/bunny.png"))) { + return -1; + } + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + piece_width = piece_height = 512; + + xtarg = 933; + ytarg = 443; + + glDisable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); return 0; } void demo_cleanup(void) { + destroy_music(); destroy_assman(); glDeleteTextures(1, &deftex_white); @@ -67,18 +106,44 @@ void demo_display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glBindTexture(GL_TEXTURE_2D, tex_logo); + gl_matrix_mode(GL_MODELVIEW); + gl_load_identity(); + gl_translatef(xoffs, yoffs, 0); + + glBindTexture(GL_TEXTURE_2D, tex_bg); glUseProgram(sdr_foo); - gl_begin(GL_QUADS); + gl_color3f(1, 1, 1); + draw_texquad(0, 0, bg_width, bg_height); + + gl_load_identity(); + gl_translatef(xpos, vis_height - ypos - piece_height, 0); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glBindTexture(GL_TEXTURE_2D, tex_piece); + if(!inplace) { + gl_color4f(0, 0, 0, 0.65); + draw_texquad(10, -15, piece_width, piece_height); + } + gl_color3f(1, 1, 1); + draw_texquad(0, 0, piece_width, piece_height); + + glDisable(GL_BLEND); +} + +static void draw_texquad(float x, float y, float w, float h) +{ + gl_begin(GL_QUADS); gl_texcoord2f(0, 1); - gl_vertex2f(-1, -1); + gl_vertex2f(x, y); gl_texcoord2f(1, 1); - gl_vertex2f(1, -1); + gl_vertex2f(x + w, 0); gl_texcoord2f(1, 0); - gl_vertex2f(1, 1); + gl_vertex2f(x + w, y + h); gl_texcoord2f(0, 0); - gl_vertex2f(-1, 1); + gl_vertex2f(x, y + h); gl_end(); } @@ -88,18 +153,98 @@ void demo_reshape(int x, int y) win_width = x; win_height = y; win_aspect = (float)x / (float)y; + + gl_matrix_mode(GL_PROJECTION); + gl_load_identity(); + if(bg_aspect >= win_aspect) { + vis_width = bg_width; + vis_height = bg_width / win_aspect; + xoffs = 0; + yoffs = (vis_height - bg_height) * 0.5f; + } else { + vis_width = bg_height * win_aspect; + vis_height = bg_height; + xoffs = (bg_height * win_aspect - bg_width) * 0.5f; + yoffs = 0; + } + gl_ortho(0, vis_width, 0, vis_height, -1, 1); } void demo_keyboard(int key, int pressed) { + if(!pressed) return; + + switch(key) { + case ' ': + xpos = xtarg + xoffs; + ypos = ytarg + yoffs; + break; + } +} + +static void scr_to_vis(int *xp, int *yp) +{ + float x = (float)*xp; + float y = (float)*yp; + *xp = x / (float)win_width * (float)vis_width; + *yp = y / (float)win_height * (float)vis_height; } void demo_mouse(int bn, int pressed, int x, int y) { + if(pressed) { + scr_to_vis(&x, &y); + if(piece_hit(x, y)) { + dragging = 1; + prev_mx = x; + prev_my = y; + inplace = 0; + } + } else { + if(dragging) { + dragging = 0; + + if(fabs(xpos - (xtarg + xoffs)) < 20 && fabs(ypos - (ytarg + yoffs)) < 20) { + xpos = xtarg + xoffs; + ypos = ytarg + yoffs; + inplace = 1; + play_music(); + } + } + } } void demo_motion(int x, int y) { + int dx, dy; + + scr_to_vis(&x, &y); + + dx = x - prev_mx; + dy = y - prev_my; + prev_mx = x; + prev_my = y; + + if(!dragging || !(dx | dy)) { + return; + } + + xpos += dx; + ypos += dy; + + if(xpos < 0) xpos = 0; + if(ypos < 0) ypos = 0; + if(xpos + piece_width > vis_width) xpos = vis_width - piece_width; + if(ypos + piece_height > vis_height) ypos = vis_height - piece_height; +} + +static int piece_hit(int x, int y) +{ + if(x < xpos) return 0; + if(x >= xpos + piece_width) return 0; + if(y < ypos) return 0; + if(y >= ypos + piece_height) return 0; + return 1; } static void gen_default_textures(void) diff --git a/src/music.c b/src/music.c new file mode 100644 index 0000000..81b98d0 --- /dev/null +++ b/src/music.c @@ -0,0 +1,197 @@ +#include +#include +#include "music.h" +#include "assfile.h" +#include "miniaudio/miniaudio.h" + +static const char *fmtname(ma_format fmt); +static ma_result vopen(ma_vfs *vfs, const char *path, ma_uint32 mode, ma_vfs_file *fret); +static ma_result vclose(ma_vfs *vfs, ma_vfs_file fp); +static ma_result vread(ma_vfs *vfs, ma_vfs_file fp, void *dest, size_t sz, size_t *numread); +static ma_result vseek(ma_vfs *vfs, ma_vfs_file fp, ma_int64 offs, ma_seek_origin from); +static ma_result vtell(ma_vfs *vfs, ma_vfs_file fp, ma_int64 *pos); +static ma_result vinfo(ma_vfs *vfs, ma_vfs_file fp, ma_file_info *inf); + +static int init_done; +static ma_engine engine; +static ma_sound sound; +static ma_resource_manager resman; +static ma_uint32 sample_rate; +static float volume; + +static ma_vfs_callbacks vfs = { + vopen, 0, + vclose, + vread, 0, + vseek, + vtell, + vinfo +}; + +int init_music(void) +{ + ma_engine_config engcfg; + ma_resource_manager_config rescfg; + unsigned int flags; + ma_format fmt; + ma_uint32 nchan; + + rescfg = ma_resource_manager_config_init(); + rescfg.pVFS = &vfs; + if(ma_resource_manager_init(&rescfg, &resman) != 0) { + fprintf(stderr, "failed to initialize miniaudio resource manager\n"); + return -1; + } + + engcfg = ma_engine_config_init(); + engcfg.pResourceManager = &resman; + + if(ma_engine_init(&engcfg, &engine) != 0) { + fprintf(stderr, "failed to initialize miniaudio engine\n"); + return -1; + } + + flags = MA_SOUND_FLAG_STREAM; + if(ma_sound_init_from_file(&engine, "data/woodclick.wav", flags, 0, 0, &sound) != 0) { + fprintf(stderr, "failed to load music\n"); + return -1; + } + ma_sound_get_data_format(&sound, &fmt, &nchan, &sample_rate, 0, 0); + printf("loaded sound: %s %u.%03u khz, %u channels\n", fmtname(fmt), + (unsigned int)sample_rate / 1000, (unsigned int)sample_rate % 1000, + (unsigned int)nchan); + + init_done = 1; + volume = 1.0f; + return 0; +} + +void destroy_music(void) +{ + if(init_done) { + ma_sound_stop(&sound); + ma_sound_uninit(&sound); + ma_engine_uninit(&engine); + } + init_done = 0; +} + +void play_music(void) +{ + if(init_done) { + ma_sound_start(&sound); + } +} + +void stop_music(void) +{ + if(init_done) { + ma_sound_stop(&sound); + } +} + +void seek_music(long tm) +{ + ma_uint64 frm; + + if(init_done) { + if(tm < 0) tm = 0; + frm = (ma_uint64)tm * (ma_uint64)sample_rate / 1000llu; + ma_sound_seek_to_pcm_frame(&sound, frm); + } +} + +void set_music_volume(float vol) +{ + if(init_done) { + volume = vol; + ma_engine_set_volume(&engine, vol); + } +} + + +static const char *fmtname(ma_format fmt) +{ + switch(fmt) { + case ma_format_u8: return "8 bit"; + case ma_format_s16: return "16 bit"; + case ma_format_s24: return "24 bit"; + case ma_format_s32: return "32 bit"; + case ma_format_f32: return "float"; + default: + return "unknown"; + } +} + +static ma_result vopen(ma_vfs *vfs, const char *path, ma_uint32 mode, ma_vfs_file *fret) +{ + ass_file *fp; + + if(mode != MA_OPEN_MODE_READ) return -1; + + if(!(fp = ass_fopen(path, "rb"))) { + return -1; + } + *fret = fp; + return 0; +} + +static ma_result vclose(ma_vfs *vfs, ma_vfs_file fp) +{ + ass_fclose(fp); + return 0; +} + +static ma_result vread(ma_vfs *vfs, ma_vfs_file fp, void *dest, size_t sz, size_t *numread) +{ + size_t res; + + res = ass_fread(dest, 1, sz, fp); + if(numread) *numread = res; + + if(res != sz) { + if(res == 0) return MA_AT_END; + } + return MA_SUCCESS; +} + +static ma_result vseek(ma_vfs *vfs, ma_vfs_file fp, ma_int64 offs, ma_seek_origin org) +{ + int from; + switch(org) { + case ma_seek_origin_start: + from = SEEK_SET; + break; + case ma_seek_origin_current: + from = SEEK_CUR; + break; + case ma_seek_origin_end: + from = SEEK_END; + break; + } + return ass_fseek(fp, offs, from) == -1 ? -1 : 0; +} + +static ma_result vtell(ma_vfs *vfs, ma_vfs_file fp, ma_int64 *pos) +{ + *pos = ass_ftell(fp); + return 0; +} + +static ma_result vinfo(ma_vfs *vfs, ma_vfs_file fp, ma_file_info *inf) +{ + int fd; + struct stat st; + +#ifdef _MSC_VER + fd = _fileno(fp); +#else + fd = fileno(fp); +#endif + + if(fstat(fd, &st) != 0) { + return MA_ERROR; + } + inf->sizeInBytes = st.st_size; + return MA_SUCCESS; +} diff --git a/src/music.h b/src/music.h new file mode 100644 index 0000000..d71c7ad --- /dev/null +++ b/src/music.h @@ -0,0 +1,13 @@ +#ifndef MUSIC_H_ +#define MUSIC_H_ + +int init_music(void); +void destroy_music(void); + +void play_music(void); +void stop_music(void); +void seek_music(long tm); + +void set_music_volume(float vol); + +#endif /* MUSIC_H_ */ -- 1.7.10.4