diff --git a/programs/games/heliothryx/Tupfile.lua b/programs/games/heliothryx/Tupfile.lua new file mode 100644 index 0000000000..bfb07d71b1 --- /dev/null +++ b/programs/games/heliothryx/Tupfile.lua @@ -0,0 +1,8 @@ +if tup.getconfig("NO_FASM") ~= "" or tup.getconfig("NO_GCC") ~= "" then return end +HELPERDIR = (tup.getconfig("HELPERDIR") == "") and "../.." or tup.getconfig("HELPERDIR") +tup.include(HELPERDIR .. "/use_gcc.lua") +tup.include(HELPERDIR .. "/use_sound.lua") +LDFLAGS = LDFLAGS .. " -T kolibri.ld" +tup.append_table(OBJS, tup.rule("start.asm", "fasm %f %o", "start.o")) +compile_gcc{"system/kolibri.c", "game/rs/rsmicrolibc.c", "game/rs/rsplatform_kos.c", "game/rs/rsmx.c", "game/rsnoise.c", "game/rsgentex.c", "game/rsmain.c", "game/rsgame.c", "game/rsgamedraw.c", "game/rskos.c", "game/rsgametext.c", "game/rsgamemenu.c"} +link_gcc("helio") diff --git a/programs/games/heliothryx/game/rs/rsbits.h b/programs/games/heliothryx/game/rs/rsbits.h new file mode 100755 index 0000000000..af85917e69 --- /dev/null +++ b/programs/games/heliothryx/game/rs/rsbits.h @@ -0,0 +1,11 @@ +#ifndef RSBITS_H_INCLUDED +#define RSBITS_H_INCLUDED + +#define BIT_SET(var,mask) { var |= (mask); } +#define BIT_CLEAR(var,mask) { var &= ~(mask); } +#define BIT_TOGGLE(var,mask) { var ^= (mask); } + +#define IS_BIT_SET(var,mask) ( (var) & (mask) ) +#define IS_BIT_CLEARED(var,mask) (!( (var) & (mask) )) + +#endif // RSBITS_H_INCLUDED diff --git a/programs/games/heliothryx/game/rs/rsdebug.h b/programs/games/heliothryx/game/rs/rsdebug.h new file mode 100755 index 0000000000..c824450230 --- /dev/null +++ b/programs/games/heliothryx/game/rs/rsdebug.h @@ -0,0 +1,22 @@ +#ifndef RSDEBUG_H_INCLUDED +#define RSDEBUG_H_INCLUDED + +// KolibriOS Placeholders + +#define DEBUG10(a) +#define DEBUG10f(...) + +#define DEBUG20(a) +#define DEBUG20f(...) + +#define DEBUG30(a) +#define DEBUG30f(...) + + +#define DEBUGR(a) +#define DEBUGRf(...) + + + + +#endif // RSDEBUG_H_INCLUDED diff --git a/programs/games/heliothryx/game/rs/rsmicrolibc.c b/programs/games/heliothryx/game/rs/rsmicrolibc.c new file mode 100644 index 0000000000..e5049201ce --- /dev/null +++ b/programs/games/heliothryx/game/rs/rsmicrolibc.c @@ -0,0 +1,174 @@ +#include "rsmicrolibc.h" + +// some math and string functions + +double sqrt( double val ) { + double result ; + asm volatile ( "fld %1;" + "fsqrt;" + "fstp %0;" : "=g" (result) : "g" (val) + ) ; + return result; +}; + +float sqrtf( float f ) { + return (float) sqrtf(f); +}; + + +double sin(double val) +{ + double result ; + asm volatile ( "fld %1;" + "fsin;" + "fstp %0;" : "=g" (result) : "g" (val) + ) ; + return result; +} + +double cos(double val) +{ + double result ; + asm volatile ( "fld %1;" + "fcos;" + "fstp %0;" : "=g" (result) : "g" (val) + ) ; + return result; +} + + +double exp (double x) +{ + double result; + asm ("fldl2e; " + "fmulp; " + "fld %%st; " + "frndint; " + "fsub %%st,%%st(1); " + "fxch;" + "fchs; " + "f2xm1; " + "fld1; " + "faddp; " + "fxch; " + "fld1; " + "fscale; " + "fstp %%st(1); " + "fmulp" : "=t"(result) : "0"(x)); + return result; +} + +float expf(float x) { + return (float)(exp(x)); +}; + + + + +double log(double Power) +{ + + // From here: http://www.codeproject.com/Tips/311714/Natural-Logarithms-and-Exponent + + double N, P, L, R, A, E; + E = 2.71828182845905; + P = Power; + N = 0.0; + + // This speeds up the convergence by calculating the integral + while(P >= E) + { + P /= E; + N++; + } + N += (P / E); + P = Power; + + do + { + A = N; + L = (P / (exp(N - 1.0))); + R = ((N - 1.0) * E); + N = ((L + R) / E); + } while (!( fabs(N-A)<0.01 )); + + return N; +} + + +float logf(float x) { + return (float)(log(x)); +}; + +double pow(double x, double p) { + + if (x < 0.001) { + return 0.0; + }; + + return exp(p * log(x)); +}; +float powf(float x, float p) { + return expf(p * logf(x)); +}; + + + + +int abs(int x) { + return (x>0) ? x : -x; +}; +double fabs(double x) { + return (x>0) ? x : -x; +}; + +double floor(double x) { + return (double)((int)x); // <--------- only positive! +}; + +double round(double x) { + return floor(x+0.5); +}; +float roundf(float x) { + return (float)round(x); +}; + + + + +void* malloc(unsigned s) +{ + asm ("int $0x40"::"a"(68), "b"(12), "c"(s) ); +} + + +void free(void *p) +{ + asm ("int $0x40"::"a"(68), "b"(13), "c"(p) ); +} + +void* memset(void *mem, int c, unsigned size) +{ + unsigned i; + + for ( i = 0; i < size; i++ ) + *((char *)mem+i) = (char) c; + + return NULL; +} + + +void* memcpy(void *dst, const void *src, unsigned size) +{ + + unsigned i; + + for ( i = 0; i < size; i++) + *(char *)(dst+i) = *(char *)(src+i); + + return NULL; +} + + + + diff --git a/programs/games/heliothryx/game/rs/rsmicrolibc.h b/programs/games/heliothryx/game/rs/rsmicrolibc.h new file mode 100644 index 0000000000..110159ef37 --- /dev/null +++ b/programs/games/heliothryx/game/rs/rsmicrolibc.h @@ -0,0 +1,53 @@ +#ifndef RS_MICROLIBC_FOR_KOLIBRI_H +#define RS_MICROLIBC_FOR_KOLIBRI_H + +// some math and string functions + +#ifndef NULL + #define NULL ((void*)0) +#endif + +#ifndef uint32_t + #define uint32_t unsigned int +#endif + +#ifndef M_PI + #define M_PI 3.14159265358979323846 +#endif + + + +double sqrt( double val ); +float sqrtf( float f ); + +double sin(double x); +float sinf(float x); + +double cos(double x); +float cosf(float x); + +double pow(double x, double p); +float powf(float x, float p); + +double exp(double x); +float expf(float x); + +double log(double x); +float logf(float x); + +int abs(int x); +double fabs(double x); + +double floor(double x); + +double round(double x); +float roundf(float x); + + +void* malloc(unsigned size); +void free(void* pointer); + +void* memset(void *mem, int c, unsigned size); +void* memcpy(void *dst, const void *src, unsigned size); + +#endif diff --git a/programs/games/heliothryx/game/rs/rsmx.c b/programs/games/heliothryx/game/rs/rsmx.c new file mode 100755 index 0000000000..b0a243cd40 --- /dev/null +++ b/programs/games/heliothryx/game/rs/rsmx.c @@ -0,0 +1,192 @@ +#include "rsmx.h" + +#ifdef RS_USE_C_LIBS + #include + #include +#else + #include "rsplatform.h" +#endif + +#include "rsdebug.h" + +// Some matrix and vector stuff +// by Roman Shuvalov + + +rs_vec3_t rs_vec3_sub(rs_vec3_t v1, rs_vec3_t v2) { + return rs_vec3(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z); +}; + +rs_vec3_t rs_vec3_add(rs_vec3_t v1, rs_vec3_t v2) { + return rs_vec3( v1.x + v2.x, v1.y + v2.y, v1.z + v2.z ); +}; + +rs_vec3_t rs_vec3_mult(rs_vec3_t v, float s) { + return rs_vec3( v.x * s, v.y * s, v.z * s ); +}; + + +rs_vec4_t rs_vec4_sub(rs_vec4_t v1, rs_vec4_t v2) { + rs_vec4_t dest; + dest.x = v1.x - v2.x; + dest.y = v1.y - v2.y; + dest.z = v1.z - v2.z; + dest.w = v1.z - v2.w; + return dest; +}; + + +rs_vec4_t rs_vec4(float x, float y, float z, float w) { + rs_vec4_t r; + r.x = x; + r.y = y; + r.z = z; + r.w = w; + return r; +}; + +rs_vec3_t rs_vec3(float x, float y, float z) { + rs_vec3_t r; + r.x = x; + r.y = y; + r.z = z; + return r; +}; + + + + + + +float rs_vec4_length_sqr(rs_vec4_t src) { + return src.x*src.x + src.y*src.y + src.z*src.z + src.w*src.w; +}; + +float rs_vec3_length_sqr(rs_vec3_t src) { + return src.x*src.x + src.y*src.y + src.z*src.z; +}; + + + + +float rs_vec4_length(rs_vec4_t v) { + return sqrtf( rs_vec4_length_sqr(v) ); +}; + +float rs_vec3_length(rs_vec3_t v) { + return sqrtf( rs_vec3_length_sqr(v) ); +}; + + + + +rs_vec3_t rs_vec3_normalize(rs_vec3_t v) { + float s = rs_vec3_length(v); + if (s > 0.00001) { + return rs_vec3( v.x / s, v.y / s, v.z / s ); + } + return rs_vec3(0.0, 0.0, 0.0); +}; + + + +float rs_vec4_dot(rs_vec4_t v1, rs_vec4_t v2) { + return ( (v1.x) * (v2.x) ) + (v1.y * v2.y) + (v1.z * v2.z) + (v1.w * v2.w); +}; + +float rs_vec3_dot(rs_vec3_t v1, rs_vec3_t v2) { + return (v1.x) * (v2.x) + (v1.y * v2.y) + (v1.z * v2.z); +}; + + + + +rs_vec3_t rs_vec3_cross(rs_vec3_t u, rs_vec3_t v) { + rs_vec3_t d; + + d.x = u.y * v.z - u.z * v.y; + d.y = u.z * v.x - u.x * v.z; + d.z = u.x * v.y - u.y * v.x; + + return d; + +}; + + + +float rs_vec4_angle(rs_vec4_t u, rs_vec4_t v) { + return rs_vec4_dot(u, v) / (rs_vec4_length(u) * rs_vec4_length(v) ); +}; + +float rs_vec3_cos_angle(rs_vec3_t u, rs_vec3_t v) { + float ret = rs_vec3_dot(u, v) / (rs_vec3_length(u) * rs_vec3_length(v) ); + return ret; +}; + +float rs_vec3_distance_sqr(rs_vec3_t u, rs_vec3_t v) { + return rs_vec3_length_sqr( rs_vec3(u.x - v.x, u.y - v.y, u.z - v.z) ); +}; + + +float rs_clamp(float x, float min1, float max1) { + if (x < min1) { + return min1; + }; + if (x > max1) { + return max1; + }; + return x; +}; + +int rs_clamp_i(int x, int min1, int max1) { + if (x < min1) { + return min1; + }; + if (x > max1) { + return max1; + }; + return x; +}; + +float rs_exp_interpolate(float v_from, float v_to, float dt) { + return v_from + ( v_to - v_from ) * ( 1 - exp(-dt/1.0) ); +}; + +float rs_max(float x, float y) { + return x > y ? x : y; +}; + +float rs_min(float x, float y) { + return x < y ? x : y; +}; + +float rs_sign(float f) { + return (f >= 0.0) ? 1.0 : -1.0; +}; + +float rs_pow(float f, float p) { + return rs_sign(f) * pow( fabs(f), p ); +}; + +float rs_clamp_angle(float f) { // !!!! only one iteration + if (f > 2.0*M_PI) { + return f - 2.0*M_PI; + }; + + if (f < -2.0*M_PI) { + return f + 2.0*M_PI; + }; + + return f; +}; + +float rs_linear_interpolate(float v_from, float v_to, float t) { + return v_from*(1.0-t) + v_to*t; +}; + +float rs_fract(float f) { + float r = floor(f); + return f - r; +}; + + diff --git a/programs/games/heliothryx/game/rs/rsmx.h b/programs/games/heliothryx/game/rs/rsmx.h new file mode 100755 index 0000000000..b42028388d --- /dev/null +++ b/programs/games/heliothryx/game/rs/rsmx.h @@ -0,0 +1,104 @@ +#ifndef rs_mx_t_H_INCLUDED +#define rs_mx_t_H_INCLUDED + +// Some matrix and vector stuff +// by Roman Shuvalov + +#define RS_SQR(x) ((x)*(x)) + + +// actual period is 1024 ms (1.024 sec) +#define RS_TIME_KOEF_SEC (M_PI * 2.0 * 64.0 / 65536.0) + + + +typedef struct { + union { + struct { + float x; + float y; + float z; + }; + float v[3]; + }; + +} rs_vec3_t; + + +typedef struct { + union { + struct { + float x; + float y; + float z; + float w; + }; + float v[4]; + }; + +} rs_vec4_t; + + + + + + +rs_vec3_t rs_vec3_sub(rs_vec3_t v1, rs_vec3_t v2); + +rs_vec3_t rs_vec3_add(rs_vec3_t v1, rs_vec3_t v2); + +rs_vec3_t rs_vec3_mult(rs_vec3_t v, float s); + + +rs_vec4_t rs_vec4_sub(rs_vec4_t v1, rs_vec4_t v2); + +void rs_vec4_add(rs_vec4_t dest, rs_vec4_t v1, rs_vec4_t v2); + +rs_vec4_t rs_vec4(float x, float y, float z, float w); + +rs_vec3_t rs_vec3(float x, float y, float z); + + + + +float rs_vec4_length_sqr(rs_vec4_t src); +float rs_vec3_length_sqr(rs_vec3_t src); + + + +float rs_vec4_length(rs_vec4_t v); +float rs_vec3_length(rs_vec3_t v); + +float rs_vec4_dot(rs_vec4_t v1, rs_vec4_t v2); +float rs_vec3_dot(rs_vec3_t v1, rs_vec3_t v2); + + +rs_vec3_t rs_vec3_cross(rs_vec3_t u, rs_vec3_t v); + +rs_vec3_t rs_vec3_normalize(rs_vec3_t v); + +float rs_vec4_angle(rs_vec4_t u, rs_vec4_t v); + +float rs_vec3_cos_angle(rs_vec3_t u, rs_vec3_t v); + + + +float rs_vec3_distance_sqr(rs_vec3_t u, rs_vec3_t v); + +float rs_clamp(float x, float min1, float max1); +int rs_clamp_i(int x, int min1, int max1); + +float rs_max(float x, float y); +float rs_min(float x, float y); + +float rs_sign(float f); +float rs_pow(float f, float p); +float rs_fract(float f); + +float rs_exp_interpolate(float v_from, float v_to, float dt); +float rs_linear_interpolate(float v_from, float v_to, float t); + + +float rs_clamp_angle(float f); + +#endif // rs_mx_t_H_INCLUDED diff --git a/programs/games/heliothryx/game/rs/rsplatform.h b/programs/games/heliothryx/game/rs/rsplatform.h new file mode 100644 index 0000000000..00918b6b0d --- /dev/null +++ b/programs/games/heliothryx/game/rs/rsplatform.h @@ -0,0 +1,83 @@ +#ifndef RS_PLATFORM_FOR_KOLIBRI_H +#define RS_PLATFORM_FOR_KOLIBRI_H + +#include "../../system/sound.h" +#include "../../system/kolibri.h" +#include "rsmicrolibc.h" + + +#ifndef uint32_t + #define uint32_t unsigned int +#endif + + +#define RS_KEY_DOWN 80 +#define RS_KEY_UP 72 +#define RS_KEY_LEFT 75 +#define RS_KEY_RIGHT 77 + +#define RS_KEY_RETURN 28 +#define RS_KEY_ESCAPE 1 +#define RS_KEY_SPACE 57 +#define RS_KEY_CONTROL_L 29 + +#define RS_KEY_1 2 +#define RS_KEY_2 3 +#define RS_KEY_3 4 +#define RS_KEY_4 5 +#define RS_KEY_5 6 +#define RS_KEY_6 7 +#define RS_KEY_7 8 +#define RS_KEY_8 9 +#define RS_KEY_9 10 +#define RS_KEY_0 11 + +#define RS_KEY_P 25 + +#define RS_KEY_A 30 +#define RS_KEY_S 31 +#define RS_KEY_Z 44 +#define RS_KEY_X 45 + + +typedef void RSFUNC0(); +typedef void RSFUNC1i(int); +typedef void RSFUNC2i(int,int); +typedef void RSFUNC1i1f(int,float); + +typedef RSFUNC0 *PRSFUNC0; +typedef RSFUNC1i *PRSFUNC1i; +typedef RSFUNC2i *PRSFUNC2i; +typedef RSFUNC1i1f *PRSFUNC1i1f; + + +void NullFunc0(); +void NullFunc1i(int i); +void NullFunc2i(int i, int j); +void NullFunc1i1f(int i, float f); + + +typedef struct rs_app_t { + + unsigned short app_time; + unsigned short delta_time; + + PRSFUNC2i OnSize; + + PRSFUNC2i OnKeyDown; + PRSFUNC1i OnKeyUp; + + PRSFUNC0 OnAppProcess; + + PRSFUNC0 rsAppOnInitDisplay; + PRSFUNC0 rsAppOnTermDisplay; + +} rs_app_t; + +extern rs_app_t rs_app; + +void rsAppZero(); + + + +#endif diff --git a/programs/games/heliothryx/game/rs/rsplatform_kos.c b/programs/games/heliothryx/game/rs/rsplatform_kos.c new file mode 100644 index 0000000000..665103aa26 --- /dev/null +++ b/programs/games/heliothryx/game/rs/rsplatform_kos.c @@ -0,0 +1,244 @@ +#include "rsplatform.h" + +rs_app_t rs_app; + + + + +// set this macro to zero (0) if bug is fixed +#define FIX_MENUETOS_LEGACY_ONE_PIXEL_BORDER_GAP_BUG (-1) + +// Fixed frame rate, set to 25 +#define GAME_REQUIRED_FPS 25 + + + +//extern char PATH[256]; +//extern char PARAM[256]; + +int window_width, window_height; + +int fps = 0; +int dt = 1; +int draw_dt = 1; +int area_width = 160; +int area_height = 160; + +int w_plus = 0; + + + + + +#define BIT_SET(var,mask) { var |= (mask); } +#define BIT_CLEAR(var,mask) { var &= ~(mask); } +#define BIT_TOGGLE(var,mask) { var ^= (mask); } + +#define IS_BIT_SET(var,mask) ( (var) & (mask) ) +#define IS_BIT_CLEARED(var,mask) (!( (var) & (mask) )) + + +void BoardPuts(const char *s) +{ + unsigned int i = 0; + while(*(s + i)) + { + asm volatile ("int $0x40"::"a"(63), "b"(1), "c"(*(s + i))); + i++; + } +} + +void board_write_integer(const char *s, int i) { + + char tmp[16]; + + + +}; + + +void kol_wnd_resize(unsigned w, unsigned h) +{ + asm volatile ("int $0x40"::"a"(67), "b"(-1), "c"(-1), "d"(w), "S"(h)); +} + + + + +void wnd_draw() +{ + + char tmp[] = "Fps:000 | Heliothryx Beta by Roman Shuvalov"; + + kol_paint_start(); + + tmp[4] = '0' + ( (fps/100) % 10 ); + tmp[5] = '0' + ( (fps/10) % 10 ); + tmp[6] = '0' + ( (fps) % 10 ); + + kol_wnd_define(100, 100, window_width, window_height, 0x74ddddff, 0x34ddddff, "HELLO WINDOW"); + kol_wnd_caption(tmp); + + GameProcess(); + + kol_paint_end(); + +} + + + + +/// =========================================================== + +void kol_main() +{ + + BoardPuts("Hello, Heliothryx!\n"); + + int err; + int version =-1; + + if((err = InitSound(&version)) !=0 ){ + BoardPuts("Sound Error 1\n"); + }; + + if( (SOUND_VERSION>(version&0xFFFF)) || + (SOUND_VERSION<(version >> 16))){ + BoardPuts("Sound Error 2\n"); + } + + + unsigned event; + unsigned key; + unsigned key_up; + + unsigned btn; + unsigned pos, x, y; + int gx, gy; + + //srand(kol_system_time_get()); + + // kol_event_mask( 0xC0000027 ); // enable using of mouse + kol_event_mask(7); // keyboard only + + kol_key_mode_set(1); + + area_width = 640; + area_height = 360; + + // Initializing variables + window_width = FIX_MENUETOS_LEGACY_ONE_PIXEL_BORDER_GAP_BUG + area_width + 10; // 2 x 5px border + window_height = FIX_MENUETOS_LEGACY_ONE_PIXEL_BORDER_GAP_BUG + kol_skin_height() + area_height + 5; // bottom 5px border + + + GameInit(); + + wnd_draw(); + + fps = 0; + + unsigned int tick_start = kol_time_tick(); + unsigned int tick_current = tick_start; + unsigned int tick_last = tick_start; + + unsigned int fps_counter = 0; + int wait_time; + int already_drawn = 0; + + float xf; + float xfs; + int xfs_i; + + while (1) { + tick_last = tick_current; + tick_current = kol_time_tick(); + dt = tick_current - tick_last; + tick_last = tick_current; + + already_drawn = 0; + + while (( event = kol_event_wait_time(1) )) { + + switch (event) { + + case 1: + wnd_draw(); // <--- need to clear event! + already_drawn = 1; + break; + + case 2: + key = kol_key_get(); + key = (key & 0xff00)>>8; + key_up = key & 0x80; + key = key & 0x7F; + + if (key_up) { + GameKeyUp(key, 1); + } + else { + GameKeyDown(key); + }; + + break; + + case 3: + switch ((kol_btn_get() & 0xff00)>>8) + { + case 1: // close button + kol_exit(); + case 2: // 'new' button + //init_board(); + //wnd_draw(); + break; + } + break; + + case 6: + btn = kol_mouse_btn(); // read mouse button + pos = kol_mouse_posw(); // read mouse position + x = pos / 65536; + y = pos % 65536; + if (x > window_width) + x=0; + if (y > window_height) + y=0; + + + break; + } + + }; + + + if (!already_drawn) { + wnd_draw(); + }; + + + fps_counter++; + + tick_current = kol_time_tick(); + + if (tick_current > tick_start+100) { + fps = fps_counter; + fps_counter = 0; + tick_start += 100; + }; + + draw_dt = tick_current - tick_last; + + wait_time = (100/GAME_REQUIRED_FPS) - draw_dt; + if (wait_time <= 0) { + wait_time = 1; + }; + kol_sleep(wait_time); + + + } + + GameTerm(); + + kol_exit(); +} + + diff --git a/programs/games/heliothryx/game/rsgame.c b/programs/games/heliothryx/game/rsgame.c new file mode 100755 index 0000000000..5d94f371bd --- /dev/null +++ b/programs/games/heliothryx/game/rsgame.c @@ -0,0 +1,637 @@ +#include "rsgame.h" + +#include "rsgametext.h" + +#include "rsgamemenu.h" + +#include "rsgamedraw.h" + +#include "rskos.h" + +#include "rsgentex.h" +#include "rssoundgen.h" +#include "rsnoise.h" + +#include "rs/rsplatform.h" + + +#ifdef RS_USE_C_LIBS // linux version + #include + #include + #include + + #include "rs/rskeyboard.h" +#endif + + +rs_game_t game; + + +void texture_init(rs_texture_t *tex, int w, int h) { + tex->status = 1; + tex->w = w; + tex->h = h; + tex->data = malloc(w*h*4); // BGRA BGRA +}; + +void texture_free(rs_texture_t *tex) { + free(tex->data); + tex->status = 0; +}; + +void texture_clear(rs_texture_t *tex, unsigned int color) { + int i; + for (i = 0; i < tex->w * tex->h; i++) { + *((unsigned int*)(&tex->data[i*4])) = color; + }; +}; + +void texture_draw(rs_texture_t *dest, rs_texture_t *src, int x, int y, int mode) { + + int i; // y + int j; // x + int k; // color component + + int istart = (y < 0) ? -y : 0; + int iend = src->h - (( (y + src->h) > dest->h) ? (y + src->h - dest->h) : 0); + + int jstart = (x < 0) ? -x : 0; + int jend = src->w - (( (x + src->w) > dest->w) ? (x + src->w - dest->w) : 0); + + int ishift = 0; + int jshift = 0; + + float a; // alpha value + + if (mode & DRAW_TILED_FLAG) { + jshift = x; + ishift = y; + x = y = istart = jstart = 0; + iend = dest->h; + jend = dest->w; + }; + + mode = mode & DRAW_MODE_MASK; + + int modvalue = (src->w*src->h*4); + + if (mode == DRAW_MODE_REPLACE) { + for (i = istart; i < iend; i++) { + for (j = jstart; j < jend; j++) { + for (k = 0; k < 4; k++) { + dest->data[ 4 * ( (y+i)*dest->w + (x+j) ) + k ] = src->data[ (4*(i*src->w + j) + k) % modvalue ]; + }; + }; + }; + } + else if (mode == DRAW_MODE_ADDITIVE) { + for (i = istart; i < iend; i++) { + for (j = jstart; j < jend; j++) { + for (k = 0; k < 3; k++) { // Alpha channel is not added + dest->data[ 4 * ( (y+i)*dest->w + (x+j) ) + k ] = + clamp_byte( dest->data[ 4 * ( (y+i)*dest->w + (x+j) ) + k ] + src->data[ (4*((i+ishift)*src->w + j + jshift) + k) % modvalue] ); + }; + }; + }; + } + else if (mode == DRAW_MODE_ALPHA) { + for (i = istart; i < iend; i++) { + for (j = jstart; j < jend; j++) { + for (k = 0; k < 3; k++) { + a = (1.0 * src->data[ (4*(i*src->w + j) + 3) % modvalue ] / 255.0); + dest->data[ 4 * ( (y+i)*dest->w + (x+j) ) + k ] = + (unsigned char) ( (1.0-a) * dest->data[ 4 * ( (y+i)*dest->w + (x+j) ) + k ] + + a*src->data[ (4*((i+ishift)*src->w + j + jshift) + k) % modvalue] ); + }; + }; + }; + }; + +}; + + + +void texture_set_pixel(rs_texture_t *tex, int x, int y, unsigned int color) { + *((unsigned int*) &tex->data[ 4 * ( (y)*tex->w + (x) ) + 0 ]) = color; +}; + +void texture_draw_vline(rs_texture_t *tex, int x, int y, int l, unsigned int color) { + int i; + if (y+l >= tex->h) { + l = tex->h - y; + }; + for (i = 0; i < l; i++) { + *((unsigned int*) &tex->data[ 4 * ( (y+i)*tex->w + (x) ) + 0 ]) = color; + }; +}; + + + +void soundbuf_init(rs_soundbuf_t *snd, int length_samples) { + snd->status = 1; + snd->length_samples = length_samples; + snd->data = malloc(length_samples*2); + rskos_snd_create_buffer(&snd->hbuf, snd->data, length_samples); +}; + +void soundbuf_free(rs_soundbuf_t *snd) { + snd->status = 0; + free(snd->data); +}; + +void soundbuf_fill(rs_soundbuf_t *snd, int amp, int freq_div) { + int i; + for (i = 0; i < snd->length_samples; i++) { + snd->data[i] = -amp/2 + amp/2*( ( (i % freq_div) > freq_div/2 ) ? 1 : 0 ); + }; + rskos_snd_update_buffer(&snd->hbuf, snd->data, snd->length_samples); +}; + +void soundbuf_sin(rs_soundbuf_t *snd, float freq) { + int i; + int amp = 29000; + for (i = 0; i < snd->length_samples; i++) { + snd->data[i] = ( 1.0 - 1.0*i/snd->length_samples ) * sin(freq*i) * amp; + }; + rskos_snd_update_buffer(&snd->hbuf, snd->data, snd->length_samples); +}; + +void soundbuf_sin_fade(rs_soundbuf_t *snd, float freq) { + int i; + int amp = 29000; + for (i = 0; i < snd->length_samples; i++) { + snd->data[i] = ( 1.0 - 1.0*i/snd->length_samples ) * sin( ( (1.0 - 0.48*i/snd->length_samples) * freq ) *i) * amp; + }; + rskos_snd_update_buffer(&snd->hbuf, snd->data, snd->length_samples); +}; + +void soundbuf_play(rs_soundbuf_t *snd) { + rskos_snd_play(&snd->hbuf, 0); +}; + +void soundbuf_stop(rs_soundbuf_t *snd) { + rskos_snd_stop(&snd->hbuf); +}; + + + +unsigned char clamp_byte(int value) { + value = value * (1 - (value >> 31)); // negative to zero + return (value > 255) ? 255 : value; +}; + + +void game_reg_init() { + game.tx = 0; + game.ty = 0; + game.tz = 0; + + int i; + for (i = 0; i < BULLETS_COUNT; i++) { + game.bullet_x[i] = 0; + game.bullet_y[i] = 0; + }; + game.bullet_index = 0; + + game.status = STATUS_MENU; + + game.window_scale = 2; + #ifdef RS_LINUX + game.window_scale = 3; + window_scale_str[3] = '3'; + #endif + + game.keyboard_state = 0; + + game.menu_index = 0; + game.menu_item_index = 0; +}; + + +int is_key_pressed(int mask) { + return IS_BIT_SET(game.keyboard_state, mask) ? 1 : 0; +}; + + +void GameProcess() { + + if (game.status == STATUS_PLAYING) { + + // shoot + + if ( (game.shoot_keypressed) || (is_key_pressed(RS_ATTACK_KEY_MASK)) ) { + + game.shoot_delay ++; + + if (game.shoot_delay > GAME_SHOOT_PERIOD) { + +// if ( (game.tx > 0) && (game.ty > 5) && (game.tx < GAME_WIDTH-20) && (game.ty < GAME_HEIGHT-10) ) { + + soundbuf_play(&game.sound_test1); + + game.bullet_index++; + game.bullet_index %= BULLETS_COUNT; + game.bullet_x[game.bullet_index] = game.tx + 5; + game.bullet_y[game.bullet_index] = game.ty; +// }; + + game.shoot_delay -= GAME_SHOOT_PERIOD; + game.shoot_keypressed = 0; + + }; + }; + + + + + int speed = 4; + int bullet_speed = 11; + + game.tx += speed * ( is_key_pressed(RS_ARROW_RIGHT_MASK) - is_key_pressed(RS_ARROW_LEFT_MASK) ); + game.ty += speed * ( is_key_pressed(RS_ARROW_DOWN_MASK) - is_key_pressed(RS_ARROW_UP_MASK) ); + + game.tx = rs_clamp_i(game.tx, 5, GAME_WIDTH-25); + game.ty = rs_clamp_i(game.ty, 5, GAME_HEIGHT - 25); + + game.tz += 1; + + int i; + for (i = 0; i < BULLETS_COUNT; i++) { + if (game.bullet_y[i]) { + game.bullet_x[i] += bullet_speed; + if (game.bullet_x[i] > GAME_WIDTH) { + game.bullet_y[i] = 0; + }; + }; + }; + + }; + + game_draw(); + +} + + + + + +void GameInit() { + + game_reg_init(); + + game.scaled_framebuffer = malloc(GAME_WIDTH*game.window_scale * GAME_HEIGHT*game.window_scale * 3); + DEBUG10f("scaled framebuffer: %d (window_scale = %d) \n", game.window_scale * GAME_WIDTH * GAME_HEIGHT * 3, game.window_scale); + + game_font_init(); + + texture_init(&game.framebuffer, GAME_WIDTH, GAME_HEIGHT); + + texture_init(&game.tex, 64, 64); + rs_gen_init(1, 64); + rs_gen_func_set(0, 0.0); + rs_gen_func_cell(0, 1200, 10, NULL, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0); + rs_gen_func_normalize(0, 0.0, 1.0); + rs_gen_func_posterize(0, 5); + rs_gen_tex_out_rgba(0, 0, 0, -1, 1.0, 1.0, 1.0, 1.0); + memcpy(game.tex.data, rs_gen_reg.tex_out, 64*64*4 ); + rs_gen_term(); + + texture_init(&game.tex_clouds, 128, 128); + rs_gen_init(1, 128); + rs_gen_func_perlin(0, 8, 5, 0.5, 1100); + rs_gen_func_normalize(0, 0.0, 1.0); + rs_gen_func_posterize(0, 4); + rs_gen_func_normalize(0, 0.0, 0.50); + rs_gen_tex_out_rgba(0, 0, 0, -1, 0.9, 0.7, 0.5, 1.0); + memcpy(game.tex_clouds.data, rs_gen_reg.tex_out, 128*128*4 ); + rs_gen_term(); + + texture_init(&game.tex_ground, GAME_WIDTH, 50); + + + + int ship_size = 8; + + // 16x8 + + unsigned char tex_ship1_mask[] = { 0x10, 0x58, 0x7C, 0x7C, 0x3E, 0x1E, 0xBE, 0xFE }; + unsigned char tex_ship2_mask[] = { 0x7C, 0x7C, 0x7E, 0x7E, 0x3C, 0x3C, 0x1C, 0x18 }; + unsigned char tex_ship1_overlay_mask[] = { 0x10, 0x18, 0x1C, 0x1C, 0x1C, 0x1C, 0x8C, 0x84 }; + unsigned char tex_ship2_overlay_mask[] = { 0x00, 0x00, 0x20, 0x20, 0x30, 0x30, 0x10, 0x10 }; + + texture_init(&game.tex_ship[0], ship_size, ship_size); + rs_gen_init(2, ship_size); + rs_gen_func_perlin(0, 8, 5, 0.5, 111); + rs_gen_func_normalize(0, 0.0, 1.0); + rs_gen_func_posterize(0, 2); + rs_gen_func_mult_add_value(0, 0, 0.3, 0.7); + + rs_gen_func_set(1, 1.0); + rs_gen_func_apply_mask(1, tex_ship1_mask); +// rs_gen_func_mult_add_value(1, 1, 0.8, 0.2); + rs_gen_tex_out_rgba(0, 0, 0, 1, 0.8, 0.65, 0.66, 1.0); + memcpy(game.tex_ship[0].data, rs_gen_reg.tex_out, ship_size*ship_size*4 ); + rs_gen_term(); + + texture_init(&game.tex_ship[1], ship_size, ship_size); + rs_gen_init(2, ship_size); + rs_gen_func_perlin(0, 8, 5, 0.5, 1100); + rs_gen_func_normalize(0, 0.0, 1.0); + rs_gen_func_posterize(0, 2); + rs_gen_func_mult_add_value(0, 0, 0.1, 0.9); + + rs_gen_func_set(1, 1.0); + rs_gen_func_apply_mask(1, tex_ship1_overlay_mask); +// rs_gen_func_mult_add_value(1, 1, 0.8, 0.2); + rs_gen_tex_out_rgba(0, 0, 0, 1, 0.4, 0.3, 0.3, 1.0); + memcpy(game.tex_ship[1].data, rs_gen_reg.tex_out, ship_size*ship_size*4 ); + rs_gen_term(); + + + texture_init(&game.tex_ship[2], ship_size, ship_size); + rs_gen_init(2, ship_size); + rs_gen_func_perlin(0, 8, 5, 0.5, 111); + rs_gen_func_normalize(0, 0.0, 1.0); + rs_gen_func_posterize(0, 2); + rs_gen_func_mult_add_value(0, 0, 0.3, 0.7); +// rs_gen_func_set(0, 1.0); + rs_gen_func_set(1, 1.0); + rs_gen_func_apply_mask(1, tex_ship2_mask); +// rs_gen_func_mult_add_value(1, 1, 0.8, 0.2); + rs_gen_tex_out_rgba(0, 0, 0, 1, 0.8, 0.65, 0.66, 1.0); + memcpy(game.tex_ship[2].data, rs_gen_reg.tex_out, ship_size*ship_size*4 ); + rs_gen_term(); + + texture_init(&game.tex_ship[3], ship_size, ship_size); + rs_gen_init(2, ship_size); + rs_gen_func_perlin(0, 8, 5, 0.5, 1100); + rs_gen_func_normalize(0, 0.0, 1.0); + rs_gen_func_posterize(0, 2); + rs_gen_func_mult_add_value(0, 0, 0.1, 0.9); + + rs_gen_func_set(1, 1.0); + rs_gen_func_apply_mask(1, tex_ship2_overlay_mask); +// rs_gen_func_mult_add_value(1, 1, 0.8, 0.2); + rs_gen_tex_out_rgba(0, 0, 0, 1, 0.4, 0.3, 0.2, 1.0); + memcpy(game.tex_ship[3].data, rs_gen_reg.tex_out, ship_size*ship_size*4 ); + rs_gen_term(); + + + texture_init(&game.tex_gui_line, GAME_WIDTH, 13); + int i; + for (i = 0; i < GAME_WIDTH*13; i++) { + ( (unsigned int*) (game.tex_gui_line.data)) [i] = 0x668899AA; + }; + + + int rock_size = 32; + rs_gen_init(3, rock_size); + for (i = 0; i < ROCKS_COUNT; i++) { + + DEBUG10f("loading %d ...\n", i); + + texture_init(&(game.tex_rocks[i]), rock_size, rock_size); + + DEBUG10f("loading %d z...\n", i); + + rs_gen_func_set(0, 0.0); + rs_gen_func_radial(0, 0.5, 0.5, 0.5, 0.75, 2.5 + i%5); + + rs_gen_func_perlin(2, 33, 4, 0.5, 350+i); + rs_gen_func_normalize(2, 0.0, 1.0); + rs_gen_func_posterize(2, 4); + + rs_gen_func_cell(1, 410+i, 50, NULL, -2.0, 1.0, 1.0, 1.0, 0.0, 1.0); + rs_gen_func_posterize(1, 2); + rs_gen_func_normalize(1, 0.0, 1.0); + rs_gen_func_add(1, 1, 2, 1.0, 0.5); + rs_gen_func_normalize(1, 0.0, 1.0); + rs_gen_func_posterize(1, 4); + + rs_gen_func_add(1, 0, 1, 1.0, 1.0); + rs_gen_func_normalize(1, 0.0, 1.0); + rs_gen_func_mult(1, 0, 1); + rs_gen_func_normalize(1, 0.0, 1.0); + rs_gen_func_posterize(1, 4); + rs_gen_tex_out_rgba_set(0.0, 0.0, 0.0, 0.0); + rs_gen_tex_out_rgba(1, 1, 1, -1, 0.5+ 0.03*(i%2), 0.7+ 0.03*(i%3) , 0.9, 1.0); + + memcpy(game.tex_rocks[i].data, rs_gen_reg.tex_out, rock_size*rock_size*4 ); + }; + rs_gen_term(); + + + #ifdef RS_LINUX + rs_audio_init(RS_AUDIO_FMT_MONO16, RS_AUDIO_FREQ_16000, 0); + #endif + + soundbuf_init(&game.sound_test1, 2048); +// soundbuf_fill(&game.sound_test1, 2, 50); + soundbuf_sin_fade(&game.sound_test1, 0.7); + + soundbuf_init(&game.sound_test2, 1024); + //soundbuf_fill(&game.sound_test2, 8, 40); + soundbuf_sin(&game.sound_test2, 0.48); + + soundbuf_init(&game.sound_test3, 1024); + //soundbuf_fill(&game.sound_test3, 12, 60); + soundbuf_sin(&game.sound_test3, 0.24); + + +}; + + +void GameTerm() { + + + DEBUG10("--- Game Term ---"); + + #ifdef RS_LINUX + rs_audio_term(); + #endif + + game_font_term(); + + free(game.scaled_framebuffer); + + texture_free(&game.framebuffer); + texture_free(&game.tex); + texture_free(&game.tex_clouds); + texture_free(&game.tex_ground); + + texture_free(&game.tex_gui_line); + + int i; + for (i = 0; i < ROCKS_COUNT; i++) { + texture_free(&game.tex_rocks[i]); + }; + + soundbuf_free(&game.sound_test1); + soundbuf_free(&game.sound_test2); + soundbuf_free(&game.sound_test3); + + +}; + +// ------------ #Event Functions ------------ + + + + + + +void GameKeyDown(int key, int first) { + + + switch (key) { + case RS_KEY_LEFT: + BIT_SET(game.keyboard_state, RS_ARROW_LEFT_MASK); + break; + case RS_KEY_RIGHT: + BIT_SET(game.keyboard_state, RS_ARROW_RIGHT_MASK); + break; + case RS_KEY_UP: + BIT_SET(game.keyboard_state, RS_ARROW_UP_MASK); + break; + case RS_KEY_DOWN: + BIT_SET(game.keyboard_state, RS_ARROW_DOWN_MASK); + break; + case RS_KEY_A: + BIT_SET(game.keyboard_state, RS_ATTACK_KEY_MASK); + game.shoot_keypressed = 1; + break; + }; + + + if (game.status == STATUS_MENU) { + + switch (key) { + case RS_KEY_LEFT: + BIT_SET(game.keyboard_state, RS_ARROW_LEFT_MASK); + + if ( (game.menu_index == MENU_SETTINGS) && (game.menu_item_index == MENU_ITEM_WINDOW_SCALE) ) { + game_change_window_scale(-1); + }; + + //PlayBuffer(hBuff, 0); + break; + case RS_KEY_RIGHT: + BIT_SET(game.keyboard_state, RS_ARROW_RIGHT_MASK); + + if ( (game.menu_index == MENU_SETTINGS) && (game.menu_item_index == MENU_ITEM_WINDOW_SCALE) ) { + game_change_window_scale(1); + }; + + //StopBuffer(hBuff); + break; + case RS_KEY_UP: + BIT_SET(game.keyboard_state, RS_ARROW_UP_MASK); + menu_cursor_up(); + //ResetBuffer(hBuff, 0); + break; + case RS_KEY_DOWN: + BIT_SET(game.keyboard_state, RS_ARROW_DOWN_MASK); + menu_cursor_down(); + break; + case RS_KEY_RETURN: + menu_cursor_click(); + break; + case RS_KEY_ESCAPE: + menu_open(0); + break; + }; + + }; + + if (game.status == STATUS_PLAYING) { + switch (key) { + + case RS_KEY_ESCAPE: + game.status = STATUS_MENU; + menu_open(0); + break; + case RS_KEY_A: + +// if ( (game.tx > 0) && (game.ty > 5) && (game.tx < GAME_WIDTH-20) && (game.ty < GAME_HEIGHT-10) ) { +// +// soundbuf_play(&game.sound_test1); +// +// game.bullet_index++; +// game.bullet_index %= BULLETS_COUNT; +// game.bullet_x[game.bullet_index] = game.tx + 12; +// game.bullet_y[game.bullet_index] = game.ty + 3; +// }; + + break; + + }; + }; + +}; + +void GameKeyUp(int key) { + + switch (key) { + case RS_KEY_LEFT: + BIT_CLEAR(game.keyboard_state, RS_ARROW_LEFT_MASK); + break; + case RS_KEY_RIGHT: + BIT_CLEAR(game.keyboard_state, RS_ARROW_RIGHT_MASK); + break; + case RS_KEY_UP: + BIT_CLEAR(game.keyboard_state, RS_ARROW_UP_MASK); + break; + case RS_KEY_DOWN: + BIT_CLEAR(game.keyboard_state, RS_ARROW_DOWN_MASK); + break; + case RS_KEY_A: + BIT_CLEAR(game.keyboard_state, RS_ATTACK_KEY_MASK); + break; + }; + +}; + + +void game_change_window_scale(int d) { + int scale = window_scale_str[3] - '0'; + + unsigned int w; + unsigned int h; + rskos_get_screen_size(&w, &h); + + int max_scale = (w-20)/GAME_WIDTH; + if ( (h-20)/GAME_HEIGHT < max_scale ) { + max_scale = (h-20)/GAME_HEIGHT; + }; + + scale += d; + if ( scale > max_scale) { + scale = 1; + } + else if (scale < 1) { + scale = max_scale; + }; + + game.window_scale = scale; + + free(game.scaled_framebuffer); + game.scaled_framebuffer = malloc(GAME_WIDTH*game.window_scale * GAME_HEIGHT*game.window_scale * 3); + + + rskos_resize_window( GAME_WIDTH * scale, GAME_HEIGHT * scale ); + + window_scale_str[3] = scale + '0'; +}; + +void game_ding(int i) { + + switch (i) { + case 0: + soundbuf_play(&game.sound_test2); + break; + case 1: + soundbuf_play(&game.sound_test3); + break; + }; + +}; diff --git a/programs/games/heliothryx/game/rsgame.h b/programs/games/heliothryx/game/rsgame.h new file mode 100755 index 0000000000..7f8a6f6716 --- /dev/null +++ b/programs/games/heliothryx/game/rsgame.h @@ -0,0 +1,187 @@ +#ifndef RSGAME_H_INCLUDED +#define RSGAME_H_INCLUDED + +/* + + Heliothryx + Game by Roman Shuvalov + +*/ + + +#include "rskos.h" +#include "rs/rsplatform.h" +//#include "rs/rstexture.h" +//#include "rs/rsshader.h" +//#include "rs/rsgl.h" +#include "rs/rsdebug.h" +#include "rs/rsbits.h" + +//#include "rs/rskeyboard.h" + +//#include "rs/rsaudio.h" + +//#include "rs/rsfile.h" + +//#include "rs/rsvbo.h" +//#include "rs/rsfbo.h" + +//#include "rs/rsthread.h" + +#include "rs/rsmx.h" + + + + +#define GAME_LANG_EN 0 +#define GAME_LANG_RU 1 + +#define GAME_WIDTH 320 +#define GAME_HEIGHT 180 + + +typedef struct { + unsigned int status; + int w; + int h; + unsigned char *data; // BGRA BGRA +} rs_texture_t; + + +// for little-endian +typedef union color_t { + int d; // 0x44332211 (ARGB) + struct { + unsigned char b; // 0x11 + unsigned char g; // 0x22 + unsigned char r; // 0x33 + unsigned char a; // 0x44 + }; +} color_t; + +// for little-endian (ARGB) +#define COLOR_BLACK 0xFF000000 +#define COLOR_TRANSPARENT 0x00000000 +#define COLOR_DARK_RED 0xFF660000 + + + +void texture_init(rs_texture_t *tex, int w, int h); +void texture_free(rs_texture_t *tex); +void texture_clear(rs_texture_t *tex, unsigned int color); +void texture_draw(rs_texture_t *dest, rs_texture_t *src, int x, int y, int mode); +void texture_draw_vline(rs_texture_t *tex, int x, int y, int l, unsigned int color); +void texture_draw_hline(rs_texture_t *tex, int x, int y, int l, unsigned int color); +void texture_set_pixel(rs_texture_t *tex, int x, int y, unsigned int color); + +unsigned char clamp_byte(int value); + +#define DRAW_MODE_REPLACE 0 +#define DRAW_MODE_ADDITIVE 1 +#define DRAW_MODE_ALPHA 2 + +#define DRAW_MODE_MASK 0x0000FFFF +#define DRAW_TILED_FLAG 0x00010000 + + + +typedef struct { + unsigned int status; + int length_samples; + SNDBUF hbuf; + signed short *data; +} rs_soundbuf_t; + +void soundbuf_init(rs_soundbuf_t *snd, int length); +void soundbuf_free(rs_soundbuf_t *snd); +void soundbuf_fill(rs_soundbuf_t *snd, int amp, int freq_div); +void soundbuf_sin(rs_soundbuf_t *snd, float freq); +void soundbuf_sin_fade(rs_soundbuf_t *snd, float freq); +void soundbuf_play(rs_soundbuf_t *snd); +void soundbuf_stop(rs_soundbuf_t *snd); + +// Game Registry + +#define ROCKS_COUNT 3 +#define FONTS_COUNT 4 + +#define STATUS_MENU 0 +#define STATUS_PLAYING 1 +#define STATUS_PAUSED 2 + + +#define RS_ARROW_LEFT_MASK 0x01 +#define RS_ARROW_DOWN_MASK 0x02 +#define RS_ARROW_UP_MASK 0x04 +#define RS_ARROW_RIGHT_MASK 0x08 +#define RS_ATTACK_KEY_MASK 0x10 + +#define BULLETS_COUNT 8 + +#define GAME_SHOOT_PERIOD 3 + +typedef struct rs_game_t { + rs_texture_t framebuffer; + unsigned char *scaled_framebuffer; // 24-bit BGRBGRBGR... for direct drawing + + rs_texture_t tex; + + rs_texture_t tex_clouds; + rs_texture_t tex_ground; + + rs_texture_t tex_ship[4]; + rs_texture_t tex_rocks[ROCKS_COUNT]; + + rs_texture_t tex_font[64*FONTS_COUNT]; + + rs_texture_t tex_gui_line; + + + rs_soundbuf_t sound_test1; + rs_soundbuf_t sound_test2; + rs_soundbuf_t sound_test3; + + int status; + + unsigned int keyboard_state; + + int menu_index; + int menu_item_index; + + int window_scale; + + int tx; + int ty; + int tz; + + int bullet_x[BULLETS_COUNT]; + int bullet_y[BULLETS_COUNT]; + int bullet_index; + int shoot_delay; + int shoot_keypressed; + +} rs_game_t; + +extern rs_game_t game; +void game_reg_init(); + +/* __ + /cc\ + /aaaa\ + |kkkkkk| <-- Easter Egg + \eeee/ +------------------------------- */ + +void GameProcess(); + +void game_ding(int i); + +void GameInit(); +void GameTerm(); + +void GameKeyDown(int key, int first); +void GameKeyUp(int key); + +void game_change_window_scale(int d); + +#endif // RSGAME_H_INCLUDED diff --git a/programs/games/heliothryx/game/rsgamedraw.c b/programs/games/heliothryx/game/rsgamedraw.c new file mode 100755 index 0000000000..a94852a212 --- /dev/null +++ b/programs/games/heliothryx/game/rsgamedraw.c @@ -0,0 +1,112 @@ +#include "rsgamedraw.h" +#include "rsgametext.h" +#include "rsgamemenu.h" + +#include "rskos.h" + +#include "rsnoise.h" + + + + +void game_draw() { + + int w = 320; + int h = 180; + + + int kk = 20; // (rskos_get_time()/1) % 160; +// +// unsigned char *c = game.framebuffer.data; +// +// int i; +// for (i = 0; i < w*h*4; i+=4) { +// c[i+0] = 10; // i/w/3; +// c[i+1] = (( (1*i)*(i + kk)/70) & 5) ? 70 : 0; +// c[i+2] = 50; +// c[i+3] = i % 128; +// }; + + + texture_clear(&game.framebuffer, COLOR_BLACK); +// texture_clear(&game.tex); + +// texture_draw(&game.framebuffer, &game.tex, 40, 40, DRAW_MODE_ADDITIVE); +// texture_draw(&game.framebuffer, &game.tex, 70, 50, DRAW_MODE_ADDITIVE); +// texture_draw(&game.framebuffer, &game.tex, 20, 60, DRAW_MODE_ADDITIVE); +// texture_draw(&game.framebuffer, &game.tex, 60, 70, DRAW_MODE_ADDITIVE); +// +// texture_draw(&game.framebuffer, &game.tex, 111, 150, DRAW_MODE_ADDITIVE); + + int i, c, c2, c3; + for (i = 0; i < 100; i++) { +// DEBUG10f("i = %d, v1 = %.4f, v2 = %.4f \n", i, rs_noise(kk+100, kk+i)*10, rs_noise(kk+200, kk+i+300)*10); + c = (0.5+0.45*rs_noise(kk+150, kk+i))*255; + c2 = c + 0.05*rs_noise(kk+150, kk+i)*255; + c3 = c2; // (0.5+0.49*rs_noise(kk+150, kk+i+2))*255; + texture_set_pixel(&game.framebuffer, (0.5+0.49*rs_noise(kk+1100, kk+i))*GAME_WIDTH, (0.5+0.49*rs_noise(kk+1200, kk+i+1300))*GAME_HEIGHT, + c + (c2<<8) + (c3<<16) + 0xFF000000); + }; + + texture_clear(&game.tex_ground, COLOR_TRANSPARENT); + rs_perlin_configure(47, 4, 0.5, 1000, 256); + for (i = 0; i < game.tex_ground.w; i++) { + texture_draw_vline(&game.tex_ground, i, 25 + rs_perlin(0,i+game.tz)*25, 2, 0xFF113300); + texture_draw_vline(&game.tex_ground, i, 25 + rs_perlin(0,i+game.tz)*25 + 2, 999, 0xFF000000); + }; + + texture_draw(&game.tex_ground, &game.tex_clouds, game.tz, 0, /* game.tx, game.ty, */ DRAW_MODE_ADDITIVE | DRAW_TILED_FLAG ); + texture_draw(&game.framebuffer, &game.tex_ground, 0, GAME_HEIGHT-50, DRAW_MODE_ALPHA); + + + if (game.status == STATUS_MENU) { + + char **title = menu_titles[game.menu_index]; + int y = (game.menu_index == MENU_MAIN) ? 80 : 50; + texture_draw(&game.framebuffer, &game.tex_gui_line, 0, y+15*game.menu_item_index, DRAW_MODE_ALPHA); + while (*title) { + game_textout(20, y, (*(title))[0]==' ' ? 3 : 0 , (*(title))+1 ); // first (zero) char defines action, title starts from second (1st) char + title++; + y+=15; + }; + + if (game.menu_index == MENU_MAIN) { + + for (i = 0; i < ROCKS_COUNT; i++) { + texture_draw(&game.framebuffer, &game.tex_rocks[i], 250+80*rs_noise(i,150), 60+60*rs_noise(i,1110), DRAW_MODE_ADDITIVE ); + }; + + game_textout( GAME_WIDTH/2 - 100, 40, 1, "HELIOTHRYX"); + game_textout( GAME_WIDTH/2 - 8, 58, 3, "TECHDEMO"); + game_textout( 2, GAME_HEIGHT-10, 2, "DEVELOPER: ROMAN SHUVALOV` TOGLIATTI_ 2014"); + }; + + } + else { + + texture_draw(&game.framebuffer, &game.tex_ship[0], game.tx-8, game.ty-4, DRAW_MODE_ALPHA); + texture_draw(&game.framebuffer, &game.tex_ship[1], game.tx-8, game.ty-4, DRAW_MODE_ALPHA); + texture_draw(&game.framebuffer, &game.tex_ship[2], game.tx, game.ty-4, DRAW_MODE_ALPHA); + texture_draw(&game.framebuffer, &game.tex_ship[3], game.tx, game.ty-4, DRAW_MODE_ALPHA); + + int i; + for (i = 0; i < BULLETS_COUNT; i++) { + if (game.bullet_y[i]) { + texture_set_pixel(&game.framebuffer, game.bullet_x[i]-4, game.bullet_y[i], 0xFF00BB00); + texture_set_pixel(&game.framebuffer, game.bullet_x[i]-3, game.bullet_y[i], 0xFF00CC00); + texture_set_pixel(&game.framebuffer, game.bullet_x[i]-2, game.bullet_y[i], 0xFF00DD00); + texture_set_pixel(&game.framebuffer, game.bullet_x[i]-1, game.bullet_y[i], 0xFF00EE00); + texture_set_pixel(&game.framebuffer, game.bullet_x[i]-0, game.bullet_y[i], 0xFF00FF00); + }; + }; + + game_textout( 2, 2, 2, "THIS IS TECHDEMO` "); + game_textout( 2, 12, 2, "USE ARROWS TO MOVE_ TO SHOOT_ TO EXIT` "); + + }; + + + rskos_draw_area(0, 0, w, h, game.window_scale, game.framebuffer.data, game.scaled_framebuffer); + +}; + diff --git a/programs/games/heliothryx/game/rsgamedraw.h b/programs/games/heliothryx/game/rsgamedraw.h new file mode 100755 index 0000000000..21d246cd34 --- /dev/null +++ b/programs/games/heliothryx/game/rsgamedraw.h @@ -0,0 +1,10 @@ +#ifndef RS_GDRAW_H +#define RS_GDRAW_H + +#include "rsgame.h" + +void game_draw(); +void game_loader_draw_mainthread(); + + +#endif diff --git a/programs/games/heliothryx/game/rsgamemenu.c b/programs/games/heliothryx/game/rsgamemenu.c new file mode 100644 index 0000000000..ccbd0a8907 --- /dev/null +++ b/programs/games/heliothryx/game/rsgamemenu.c @@ -0,0 +1,124 @@ +#include "rsgamemenu.h" + +#include "rsgame.h" + +#include "rskos.h" + +PRSFUNC0 menu_actions[] = { + /* a */ &menu_action_start, + /* b */ &menu_action_exit, + /* c */ &menu_action_change_window_scale +}; + +char window_scale_str[] = "c< 2X >"; + +char* menu_main_titles[] = { + "a5TART", + "15ETTING5", + "2ABOUT", + "bQUIT", + 0 +}; + +char* menu_settings_titles[] = { + " WINDOW SCALE:", + window_scale_str, + " ", + "0DONE", + 0 +}; + +char* menu_about_titles[] = { + " DEVELOPED BY", + " ROMAN SHUVALOV", + " ", + "0DONE", + 0 +}; + +char **menu_titles[] = { + /* 0 */ menu_main_titles, + /* 1 */ menu_settings_titles, + /* 2 */ menu_about_titles, + 0 +}; + + +void menu_cursor_down() { + int new_index = game.menu_item_index+1; + while ( (menu_titles[game.menu_index][new_index]) ) { + if ((menu_titles[game.menu_index][new_index][0] != ' ')) { + game.menu_item_index = new_index; + game_ding(1); + return; + }; + new_index++; + }; +}; + +void menu_cursor_up() { + int new_index = game.menu_item_index-1; + while ( new_index+1 ) { + if ((menu_titles[game.menu_index][new_index][0] != ' ')) { + game.menu_item_index = new_index; + game_ding(1); + return; + }; + new_index--; + }; +}; + +void menu_open(int i) { + + game.menu_index = i; + + game.menu_item_index = -1; + // (menu_cursor_down without sound) + int new_index = game.menu_item_index+1; + while ( (menu_titles[game.menu_index][new_index]) ) { + if ((menu_titles[game.menu_index][new_index][0] != ' ')) { + game.menu_item_index = new_index; + return; + }; + new_index++; + }; + +}; + +void menu_cursor_click() { + + char c = menu_titles[game.menu_index][game.menu_item_index][0]; + + game_ding(0); + + if (c > '9') { + // action: call function + menu_actions[c - 'a'](); + } + else { + // action: navigate to menu + menu_open(c - '0'); + }; + +// DEBUG10f("click: %c \n", c); + +}; + +void menu_action_start() { + game.status = STATUS_PLAYING; + + game.tx = GAME_WIDTH/2 - 50; + game.ty = GAME_HEIGHT/2 - 10; + +}; + +void menu_action_exit() { + #ifndef RS_LINUX + GameTerm(); + #endif + rskos_exit(); +}; + +void menu_action_change_window_scale() { + game_change_window_scale(1); +}; diff --git a/programs/games/heliothryx/game/rsgamemenu.h b/programs/games/heliothryx/game/rsgamemenu.h new file mode 100644 index 0000000000..55bf56d916 --- /dev/null +++ b/programs/games/heliothryx/game/rsgamemenu.h @@ -0,0 +1,33 @@ +#ifndef RS_GMENU_H +#define RS_GMENU_H + +#include "rsgame.h" +#include "rs/rsplatform.h" + + +#define MENUS_COUNT 5 + +#define MENU_MAIN 0 +#define MENU_SETTINGS 1 +#define MENU_ABOUT 2 + +#define MENU_ITEM_WINDOW_SCALE 1 + +extern char* menu_main_titles[]; +extern char* menu_settings_titles[]; +extern char* menu_about_titles[]; +extern char **menu_titles[]; +extern PRSFUNC0 menu_actions[]; + +extern char window_scale_str[]; + +void menu_cursor_down(); +void menu_cursor_up(); +void menu_open(int i); +void menu_cursor_click(); + +void menu_action_start(); +void menu_action_exit(); +void menu_action_change_window_scale(); + +#endif diff --git a/programs/games/heliothryx/game/rsgametext.c b/programs/games/heliothryx/game/rsgametext.c new file mode 100755 index 0000000000..d26ca3a650 --- /dev/null +++ b/programs/games/heliothryx/game/rsgametext.c @@ -0,0 +1,561 @@ +#include "rs/rsplatform.h" + +#include "rsgametext.h" + +#include "rsgame.h" +#include "rsgentex.h" + +#include "rskos.h" + + + +#ifdef RS_USE_C_LIBS + #include + #include + #include +#endif + + +signed short pp_seg[32*8] = { + + // 0 + 16, 6-16, + 16, 6+16, + 16, 6, + 13, 0, + + // 1 + 26-16, 16, + 26+16, 16, + 26, 11, + 8, 0, + + // 2 + 26-16, 16, + 26+16, 16, + 26, 21, + 8, 0, + + // 3 + 16, 26-16, + 16, 26+16, + 16, 26, + 13, 0, + + // 4 + 6-16, 16, + 6+16, 16, + 6, 21, + 8, 0, + + // 5 + 6-16, 16, + 6+16, 16, + 6, 11, + 8, 0, + + // 6 + 16, 16-16, + 16, 16+16, + 16, 16, + 13, 0, + + // 7 + 16, 4-22, + 16, 4+22, + 16, 4, + 4, 0, + + + + + // 8 + 16-16, 16, + 16+16, 16, + 16, 11, + 8, 0, + + // 9 + 16-16, 16, + 16+16, 16, + 16, 21, + 8, 0, + + // 10 + 21-16, 11+16, + 21+16, 11-16, + 21, 11, + 9, 0, + + // 11 modified + 16-16, 16+16, + 16+16, 16-16, + 21, 21, + 9, 0, + + // 12 + 16-16, 16-16, + 16+16, 16+16, + 21, 11, + 9, 0, + + // 13 + 21-16, 21-16, + 21+16, 21+16, + 21, 21, + 9, 0, + + // 14 + 16, 16-16, + 16, 16+16, + 10, 16, + 7, 0, + + // 15 + 16, 16-16, + 16, 16+16, + 22, 16, + 7, 0, + + + + + + + // 16 + 16-16, 16+16, + 16+16, 16-16, + 11, 11, + 8, 0, + + // 17 + 11-16, 21+16, + 11+16, 21-16, + 11, 21, + 9, 0, + + // 18 + 11-16, 11-16, + 11+16, 11+16, + 11, 11, + 9, 0, + + // 19 + 16-16, 16-16, + 16+16, 16+16, + 11, 21, + 9, 0, + + // 20 == copy 11 modified + 21-22, 21+22, + 21+22, 21-22, + 21, 21, + 9, 0, + + // 21 - right + 27-12, 28-9, + 27+12, 28+9, + 27, 27, + 4, 0, + + // 22 - left + 5-12, 28+9, + 5+12, 28-9, + 5, 27, + 4, 0, + + + // 23 + 6-16, 16, + 6+16, 16, + 6, 8, + 5, 0, + + + + // 24 + 16-33, 16, + 16+33, 16, + 16, 13, + 4, 0, + + + // 25 + 16-33, 16, + 16+33, 16, + 16, 26, + 4, 0, + + // 26 + 16, 6-16, + 16, 6+16, + 11, 6, + 7, 0, + + // 27 + 16, 26-16, + 16, 26+16, + 11, 26, + 7, 0, + + // 28 + 16, 6-16, + 16, 6+16, + 21, 6, + 7, 0, + + // 29 + 16, 26-16, + 16, 26+16, + 21, 26, + 7, 0, + + + // 30 , + 11-22, 27-22, + 11+22, 27+22, + 11, 25, + 6, 0, + + // 31 not implemented + 16, 26-16, + 16, 26+16, + 16, 26, + 13, 0, + + +}; + +uint32_t ch_seg[64] = { + 0b00111111, // // for cross-line in O | 1<<12 | 1<<19, // 0 + 1<<26 | 1<<8 | 1<<9 | 1<<3, // 1 + 0b01011011, // 2 + 1<<0 | 1<<12 | 1<<15 | 1<<2 | 1<<3, // 3 + 0b01100110, // 4 + 0b01101101, // 5 + 1<<0 | 1<<2 | 1<<3 | 1<<4 | 1<<5 | 1<<6, // 6 // old: 1<<6 | 1<<2 | 1<<3 | 1<<4 | 1<<18 | 1<<28, // 6 + 1<<23 | 1<<0 | 1<<1 | 1<<13 , //0b00000111 , // 7 + + 0b01111111, // 8 + 1<<6 | 1<<5 | 1<<0 | 1<<1 | 1<<2 | 1<<3, // 9 + 1<<24 | 1<<25, // : + 1<<8 | 1<<25, // ; + 1<<12 | 1<<11, // < + 1<<6, // = (-) + 1<<16 | 1<<19, // > + 1<<23 | 1<<0 | 1<<1 | 1<<15 | 1<<25 | 1<<9, // ? + + 1<<19 | 1<<12, // @ (/) + 1<<0 | 1<<1 | 1<<2 | 1<<6 | 1<<4 | 1<<5, // A + 1<<26 | 1<<10 | 1<<6 | 1<<11 | 1<<3 | 1<<4 | 1<<5, // B + 1<<0 | 1<<5 | 1<<4 | 1<<3, // C // corners: 1<<28 | 1<<18 | 1<<17 | 1<<29, + 1<<26 | 1<<27 | 1<<5 | 1<<4 | 1<<10 | 1<<13 , // D + 1<<0 | 1<<14 | 1<<3 | 1<<5 | 1<<4, // E + 1<<0 | 1<<14 | 1<<5 | 1<<4, // F + 1<<0 | 1<<5 | 1<<4 | 1<<3 | 1<<2 | 1<<15, // G + + 1<<1 | 1<<2 | 1<<5 | 1<<4 | 1<<6, // H + 1<<0 | 1<<8 | 1<<9 | 1<<3, // I + 1<<1 | 1<<2 | 1<<3 | 1<<4, // J + 1<<5 | 1<<4 | 1<<14 | 1<<12 | 1<<11, // K + 1<<5 | 1<<4 | 1<<3, // L + 1<<5 | 1<<4 | 1<<1 | 1<<2 | 1<<16 | 1<<12, // M + 1<<5 | 1<<4 | 1<<16 | 1<<11 | 1<<1 | 1<<2, // N + 0b00111111, // O + + 1<<4 | 1<<5 | 1<<0 | 1<<1 | 1<<6, // P + 1<<0 | 1<<1 | 1<<13 | 1<<27 | 1<<4 | 1<<5 | 1<<11, // Q // old: 0b00111111 | 1<<11, // Q + 1<<0 | 1<<1 | 1<<6 | 1<<5 | 1<<4 | 1<<11, // R + 0b01101101, // S + 1<<0 | 1<<8 | 1<<9, // T + 1<<1 | 1<<2 | 1<<3 | 1<<4 | 1<<5, // U + 1<<1 | 1<<13 | 1<<17 | 1<<5, // V + 1<<5 | 1<<4 | 1<<19 | 1<<11 | 1<<2 | 1<<1, // W + + 1<<16 | 1<<11 | 1<<19 | 1<<12, // X + 1<<5 | 1<<6 | 1<<1 | 1<<2 | 1<<3, // Y + 1<<0 | 1<<12 | 1<<19 | 1<<3, // Z + 1<<26 | 1<<8 | 1<<9 | 1<<29 | 1<<2 | 1<<15, // [Ъ + 1<<5 | 1<<4 | 1<<27 | 1<<9 | 1<<14 | 1<<1 | 1<<2, // \Ы + 1<<5 | 1<<4 | 1<<3 | 1<<2 | 1<<6, // ]Ь + 1<<7 | 1<<5 | 1<<4 | 1<<19 | 1<<12 | 1<<1 | 1<<2, // ^Й + 1<<30, // _ (,comma) + + 1<<25, // ` dot + 1<<5 | 1<<0 | 1<<1 | 1<<6 | 1<<2 | 1<<19, // aЯ + 1<<0 | 1<<5 | 1<<4 | 1<<3 | 1<<2 | 1<<6, // bБ + 1<<5 | 1<<4 | 1<<3 | 1<<1 | 1<<2 | 1<<21, // cЦ + 0b011001000000010000011100, // dД + 1<<0 | 1<<1 | 1<<15 | 1<<2 | 1<<3, // eЭ // with corners: 1<<26 | 1<<10 | 1<<6 | 1<<13 | 1<<27, // eЭ + 1<<0 | 1<<1 | 1<<6 | 1<<5 | 1<<8 | 1<<9, // fФ + 1<<4 | 1<<5 | 1<<0, // gГ + 1<<5 | 1<<4 | 1<<3 | 1<<1 | 1<<2 | 1<<9, // hШ, + 1<<5 | 1<<4 | 1<<19 | 1<<12 | 1<<1 | 1<<2, // iИ + 1<<5 | 1<<8 | 1<<1 | 1<<6 | 1<<4 | 1<<9 | 1<<2, // old: 1<<16 | 1<<8 | 1<<12 | 1<<19 | 1<<9 | 1<<11, // jЖ + 1<<5 | 1<<4 | 1<<14 | 1<<8 | 1<<9 | 1<<1 | 1<<2 | 1<<28 | 1<<29, // k_Ю + 1<<4 | 1<<18 | 1<<28 | 1<<1 | 1<<2, // l // old symmetric: 1<<4 | 1<<18 | 1<<10 | 1<<2, // l // old: 1<<19 | 1<<12 | 1<<1 | 1<<2, // lЛ + 1<<5 | 1<<4 | 1<<3 | 1<<1 | 1<<2 | 1<<9 | 1<<21, // mЩ, + 1<<4 | 1<<5 | 1<<0 | 1<<1 | 1<<2, // n + 1<<0 | 1<<12 | 1<<15 | 1<<2 | 1<<3, // oЗ + +}; + + +void game_font_init() { + + DEBUG30(":: font init start"); + + float scale = 1.0; + + int seg; + int ch; + int ch_bit; + +// // FAT FONT #1 (OK) +// float scales[4] = { 0.4, 0.6, 0.2, 2 }; // 2,1,1,1 +// float pows[4] = { 15.0, 19.0, 200.0, 22.0 }; +// float ks1[4] = { 1.2, 1.0, 1.2, 0.90 }; // 0.75 straight +// float ks2[4] = { -1.0, -1.0, -1.0, -1.0 }; +// float pows1[4] = { 1.0, 0.79, 1.0, 1.0 }; +// float pows2[4] = { 1.0, 0.79, 1.0, 1.0 }; +// float clamp1[4] = { 0.8, 0.75, 0.65, 0.87 }; // 0.8 to 0.86 +// float clamp2[4] = { 0.85, 0.85, 0.85, 0.92 }; +// float radiuses[4] = { 1.0, 1.1, 1.2, 0.87 }; + + + float scales[4] = { 0.4, 0.6, 0.2, 2 }; // 2,1,1,1 + //float pows[4] = { 45.0, 100.0, 200.0, 22.0 }; + float pows[4] = { 15.0, 15.0, 15.0, 22.0 }; + float ks1[4] = { 1.0, 1.2, 1.2, 0.90 }; // 0.75 straight + float ks2[4] = { -1.0, -1.0, -1.0, -1.0 }; + float pows1[4] = { 1.3, 1.0, 1.0, 1.0 }; + float pows2[4] = { 1.2, 0.9, 1.0, 1.0 }; + float clamp1[4] = { 0.7, 0.79, 0.65, 0.87 }; // 0.8 to 0.86 + float clamp2[4] = { 0.9, 0.85, 0.85, 0.92 }; + float radiuses[4] = { 0.93, 0.93, 1.2, 0.87 }; + + float colors_r[4] = { 1.0, 0.3, 1.0, 0.3 }; + float colors_g[4] = { 1.0, 0.6, 1.0, 0.6 }; + float colors_b[4] = { 1.0, 1.0, 1.0, 0.9 }; + // 1: 0.5, 0.74, 0.79 + + DEBUG20(":: font init label-a"); + + int font_index = 0; + int font_index_color = 0; + + for (font_index_color = 0; font_index_color < FONTS_COUNT; font_index_color++) { + + font_index = font_index_color % 3; + + DEBUG30f(":: font init label-b (font index %d) \n", font_index); + + scale = scales[font_index]; + + rs_gen_reg.cell_scale = scale; + + int char_tex_size = scale*32; + +// DEBUG10f("char_tex_size %d \n", char_tex_size); + + rs_gen_init(97, char_tex_size); + + for (seg = 0; seg < 32; seg++) { + rs_gen_func_cell(seg, 1, 2, &pp_seg[8*seg], ks1[font_index], pows1[font_index], ks2[font_index], pows2[font_index], 0.0, 0.0); + //rs_gen_func_cell(seg, 1, 2, &pp_seg[8*seg], 1.2, 1.0, -1.0, 1.0, 0.0, 0.0); + //rs_gen_func_cell(seg, 1, 2, &pp_seg[8*seg], 0.48450032, 1.0, -1.0, 2.20, 0.0, 0.0); // toon + rs_gen_func_normalize(seg, 0.0, 1.0); // 0.1 to 1.0 + + rs_gen_func_clamp(seg, clamp1[font_index], clamp2[font_index]); // 0.8, 0.86); // toon 0.775, 0.839889 + rs_gen_func_normalize(seg, 0.0, 1.0); // 0.1 to 1.0 + + rs_gen_func_set(96, 0.0); + rs_gen_func_radial(96, (float)pp_seg[8*seg + 4]/32.0, (float)pp_seg[8*seg + 5]/32.0, (float)pp_seg[8*seg + 6]/32.0*radiuses[font_index], 1.0, pows[font_index]); + rs_gen_func_mult(seg, seg, 96); + }; + + + + for (ch = 0; ch < 64; ch++) { + rs_gen_func_set(32+ch, 0.0); + for (ch_bit = 0; ch_bit < 32; ch_bit++) { + if ( (1< + #include +#endif + +#include "rsnoise.h" + +#include "rs/rsplatform.h" +#include "rs/rsmx.h" + +/* + + Procedural Texture Generator + by Roman Shuvalov + + +*/ + + + + + + + +rs_gen_reg_t rs_gen_reg; + + + + + +void rs_gen_func_mult_add_value(int dest, int src, float val_mult, float val_add) { + int i; + for (i = 0; i < rs_gen_reg.tex_length; i++ ) { + rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i] = rs_gen_reg.tex[src*rs_gen_reg.tex_length + i] * val_mult + val_add; + }; +}; + +void rs_gen_func_perlin(int dest, float freq, int octaves, float persistence, float seed) { + rs_perlin_configure(freq, octaves, persistence, seed, rs_gen_reg.tex_size); + int i, j; + for (i = 0; i < rs_gen_reg.tex_size; i++) { + for (j = 0; j < rs_gen_reg.tex_size; j++) { + rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] = 0.5 + 0.5*rs_perlin(i, j); // rs_perlin(i, j); + }; + }; +}; + +void rs_gen_func_quads(int dest, float freq, int octaves, float persistence, float seed) { + rs_perlin_configure(freq, octaves, persistence, seed, rs_gen_reg.tex_size); + int i, j; + for (i = 0; i < rs_gen_reg.tex_size; i++) { + for (j = 0; j < rs_gen_reg.tex_size; j++) { + rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] = 0.5 + 0.5*rs_quad_noise(i, j); // rs_perlin(i, j); + }; + }; +}; + +void rs_gen_func_cell(int dest, int seed, int num_points, signed short* p_arr, float k1, float pow1, float k2, float pow2, float k3, float pow3) { + + + int x[num_points]; + int y[num_points]; + + int i, j, p, dx, dy; + + int ts = rs_gen_reg.tex_size; + + float mindist, mindist2, mindist3; + float dist; + + if (p_arr == NULL) { + for (p = 0; p < num_points; p++) { + x[p] = (0.5 + 0.5*rs_noise(p, seed)) * ts; + y[p] = (0.5 + 0.5*rs_noise(p, seed+100)) * ts; + // x[p] = (p * 18 ) % ts; + // y[p] = (p * 33 ) % ts; + } + } + else { + for (p = 0; p < num_points; p++) { + x[p] = rs_gen_reg.cell_scale * p_arr[p*2 + 0]; + y[p] = rs_gen_reg.cell_scale * p_arr[p*2 + 1]; + // x[p] = (p * 18 ) % ts; + // y[p] = (p * 33 ) % ts; + } + }; + + int cyclic = ((p_arr!=NULL) && (seed!=0)) ? 0 : 1; + + +// float maxdist = 0.0; +// float mindx, mindy, maxdx, maxdy; + + int ind_index = 0; + int ind_index2 = 0; + + for (i = 0; i < ts; i++) { + for (j = 0; j < ts; j++) { + + // distance to near point + mindist = ts; + for (p = 0; p < num_points; p++) { + dx = (ts/2 - abs( abs(j-x[p]) - ts/2))*cyclic + ( abs(j-x[p]) )*(1-cyclic); + dy = (ts/2 - abs( abs(i-y[p]) - ts/2))*cyclic + ( abs(i-y[p]) )*(1-cyclic); + dist = sqrtf( RS_SQR(dx) + RS_SQR(dy) ); + if (dist < mindist) { + mindist = dist; + ind_index = p; + }; + }; + + mindist2 = ts; + for (p = 0; p < num_points; p++) { + if (p == ind_index) { + continue; + }; + dx = (ts/2 - abs( abs(j-x[p]) - ts/2))*cyclic + ( abs(j-x[p]) )*(1-cyclic); + dy = (ts/2 - abs( abs(i-y[p]) - ts/2))*cyclic + ( abs(i-y[p]) )*(1-cyclic); + dist = sqrtf( RS_SQR(dx) + RS_SQR(dy) ); + if (dist < mindist2) { + mindist2 = dist; + ind_index2 = p; + }; + }; + + mindist3 = ts; + for (p = 0; p < num_points; p++) { + if ( (p == ind_index) || (p == ind_index2) ) { + continue; + }; + dx = (ts/2 - abs( abs(j-x[p]) - ts/2))*cyclic + ( abs(j-x[p]) )*(1-cyclic); + dy = (ts/2 - abs( abs(i-y[p]) - ts/2))*cyclic + ( abs(i-y[p]) )*(1-cyclic); + dist = sqrtf( RS_SQR(dx) + RS_SQR(dy) ); + if (dist < mindist3) { + mindist3 = dist; + }; + }; + + rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] = + k1*rs_pow(mindist,pow1) + k2*rs_pow(mindist2,pow2) + k3*rs_pow(mindist3,pow3); + // mindist2 * mindist3 + mindist; + }; + }; + +}; + +void rs_gen_func_adr(int dest, int src, int adr_x, int adr_y, float src_factor, float adr_factor) { + int i, j; + for (i = 0; i < rs_gen_reg.tex_size; i++) { + for (j = 0; j < rs_gen_reg.tex_size; j++) { + unsigned short u = src_factor*j + adr_factor*(rs_gen_reg.tex[adr_x*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] - 0.5) * rs_gen_reg.tex_size; + unsigned short v = src_factor*i + adr_factor*(rs_gen_reg.tex[adr_y*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] - 0.5) * rs_gen_reg.tex_size; + + u %= rs_gen_reg.tex_size; + v %= rs_gen_reg.tex_size; + + rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] = + rs_gen_reg.tex[src*rs_gen_reg.tex_length + v*rs_gen_reg.tex_size + u]; + }; + }; +}; + +void rs_gen_func_normalmap(int dest_r, int dest_g, int dest_b, int src, float k) { + int i, j; + float max_val = -111111.0; + float min_val = 100000.0; + for (i = 0; i < rs_gen_reg.tex_size; i++) { + for (j = 0; j < rs_gen_reg.tex_size; j++) { + unsigned short um = rs_gen_reg.tex_size + j-2; + unsigned short vm = rs_gen_reg.tex_size + i-2; + + unsigned short u = j; + unsigned short v = i; + + unsigned short up = j+2; + unsigned short vp = i+2; + + um %= rs_gen_reg.tex_size; + vm %= rs_gen_reg.tex_size; + up %= rs_gen_reg.tex_size; + vp %= rs_gen_reg.tex_size; + +// float val1 = rs_gen_reg.tex[src*rs_gen_reg.tex_length + v*rs_gen_reg.tex_size + u]; + + float val_xp = 2.0 * rs_gen_reg.tex[src*rs_gen_reg.tex_length + v*rs_gen_reg.tex_size + up] + + rs_gen_reg.tex[src*rs_gen_reg.tex_length + vm*rs_gen_reg.tex_size + up] + + rs_gen_reg.tex[src*rs_gen_reg.tex_length + vp*rs_gen_reg.tex_size + up]; + + float val_xm = 2.0 * rs_gen_reg.tex[src*rs_gen_reg.tex_length + v*rs_gen_reg.tex_size + um] + + rs_gen_reg.tex[src*rs_gen_reg.tex_length + vm*rs_gen_reg.tex_size + um] + + rs_gen_reg.tex[src*rs_gen_reg.tex_length + vp*rs_gen_reg.tex_size + um]; + + float val_yp = 2.0 * rs_gen_reg.tex[src*rs_gen_reg.tex_length + vp*rs_gen_reg.tex_size + u] + + rs_gen_reg.tex[src*rs_gen_reg.tex_length + vp*rs_gen_reg.tex_size + um] + + rs_gen_reg.tex[src*rs_gen_reg.tex_length + vp*rs_gen_reg.tex_size + up]; + + float val_ym = 2.0 * rs_gen_reg.tex[src*rs_gen_reg.tex_length + vm*rs_gen_reg.tex_size + u] + + rs_gen_reg.tex[src*rs_gen_reg.tex_length + vm*rs_gen_reg.tex_size + um] + + rs_gen_reg.tex[src*rs_gen_reg.tex_length + vm*rs_gen_reg.tex_size + up]; + +// float val_dx = rs_gen_reg.tex[src*rs_gen_reg.tex_length + v*rs_gen_reg.tex_size + u2] - val1; +// float val_dy = rs_gen_reg.tex[src*rs_gen_reg.tex_length + v2*rs_gen_reg.tex_size + u] - val1; + + float val_dx = val_xp - val_xm; + float val_dy = val_yp - val_ym; + + + +// val_dx = val_dx; +// val_dy = -val_dy; + +// val_dx = atan(val_dx * rs_gen_reg.tex_size ) / (M_PI/2); +// val_dy = atan(val_dy * rs_gen_reg.tex_size ) / (M_PI/2); + + float bump_scale = 128.0 / rs_gen_reg.tex_size / k; + + rs_vec3_t bump = rs_vec3_cross( rs_vec3_normalize(rs_vec3(bump_scale, 0.0, val_dy)), + rs_vec3_normalize(rs_vec3(0.0, bump_scale, -val_dx))); + + + + float val_dz = sqrtf( 1.0 - (RS_SQR(k*val_dx) + RS_SQR(k*val_dy)) ); +// val_dz = val_dz; + +// val_dz = 1.0 / 2.0; + + val_dx = 0.5 + 0.5*val_dx; + val_dy = 0.5 + 0.5*val_dy; + val_dz = 0.5 + 0.5*val_dz; + + max_val = rs_max(max_val, fabs(val_dx) ); +// max_val = rs_max(max_val, fabs(val_dy) ); + min_val = rs_min(min_val, val_dx); +// min_val = rs_min(min_val, val_dy); + +// rs_gen_reg.tex[dest_r*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] = val_dy; +// rs_gen_reg.tex[dest_g*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] = val_dx; +// rs_gen_reg.tex[dest_b*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] = val_dz; + + rs_gen_reg.tex[dest_r*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] = 0.5 + 0.5*bump.x; + rs_gen_reg.tex[dest_g*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] = 0.5 + 0.5*bump.y; + rs_gen_reg.tex[dest_b*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] = 0.5 + 0.5*bump.z; + + }; + }; + +////// if (max_val < 0.001) { +////// DEBUG10f("WARNING, max_val of normalmap is too low (%.9f) \n", max_val); +////// max_val = 0.001; +////// }; +////// +////// max_val *= 1.0; +////// +////// for (i = 0; i < rs_gen_reg.tex_size; i++) { +////// for (j = 0; j < rs_gen_reg.tex_size; j++) { +////// +////// rs_gen_reg.tex[dest_r*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] /= max_val; +////// rs_gen_reg.tex[dest_g*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] /= max_val; +////// +////// rs_gen_reg.tex[dest_b*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] = +////// sqrtf( 1.0 - (RS_SQR(rs_gen_reg.tex[dest_r*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j]) +////// + RS_SQR(rs_gen_reg.tex[dest_g*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j])) ); +////// +////// +////// rs_gen_reg.tex[dest_r*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] = +////// 0.5 + 0.5*rs_gen_reg.tex[dest_r*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j]; +////// rs_gen_reg.tex[dest_g*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] = +////// 0.5 + 0.5*rs_gen_reg.tex[dest_g*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j]; +////// +////// +//////// float val_dx = rs_gen_reg.tex[dest_r*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j]; +//////// float val_dy = rs_gen_reg.tex[dest_g*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j]; +//////// +//////// float val_dz = sqrtf( 1.0 - (RS_SQR(k*val_dx) + RS_SQR(k*val_dy)) ); +////// +//////// val_dx = 0.5 + 0.5*k*val_dx; +//////// val_dy = 0.5 + 0.5*k*val_dy; +//////// val_dz = 0.5 + 0.5*val_dz; +////// +////// +////// //rs_gen_reg.tex[dest_b*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] = val_dz; +////// +////// }; +////// }; + + DEBUG10f("\n\nmax val %.3f \nmin %.3f \n", max_val, min_val); + +}; + +void rs_gen_func_radial(int dest, float x, float y, float radius, float v, float power) { + x *= rs_gen_reg.tex_size; + y *= rs_gen_reg.tex_size; + radius *= rs_gen_reg.tex_size; + float val; + int i, j; + for (i = 0; i < rs_gen_reg.tex_size; i++) { + for (j = 0; j < rs_gen_reg.tex_size; j++) { + val = rs_clamp(sqrt(RS_SQR(j-x) + RS_SQR(i-y)) / radius, 0.0, 1.0); + val = pow(val, power); + rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] = + rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j]*val + v*(1.0-val); // 0.5 + 0.5*rs_quad_noise(i, j); // rs_perlin(i, j); + }; + }; +}; + +void rs_gen_func_gradient_v(int dest, float v, float power) { + float val; + int i, j; + for (i = 0; i < rs_gen_reg.tex_size; i++) { + val = rs_clamp( (float) (i) / rs_gen_reg.tex_size, 0.0, 1.0); + val = pow(val, power); + for (j = 0; j < rs_gen_reg.tex_size; j++) { + rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] = + rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j]*val + v*(1.0-val); // 0.5 + 0.5*rs_quad_noise(i, j); // rs_perlin(i, j); + }; + }; +}; + +void rs_gen_func_normalize(int dest, float vmin, float vmax) { + + + // LAGGY !!!!!!!!!!!!! + + float val_min = rs_gen_reg.tex[dest*rs_gen_reg.tex_length]; + float val_max = rs_gen_reg.tex[dest*rs_gen_reg.tex_length]; + float f; + + int i, j; + + for (i = 0; i < rs_gen_reg.tex_size; i++) { + for (j = 0; j < rs_gen_reg.tex_size; j++) { + f = rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] ; + val_max = rs_max(val_max, f); + val_min = rs_min(val_min, f); + }; + }; + + float val_scale = (vmax - vmin) / (val_max - val_min) - vmin; + + for (i = 0; i < rs_gen_reg.tex_size; i++) { + for (j = 0; j < rs_gen_reg.tex_size; j++) { + rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] = + vmin + val_scale * ( rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] - val_min); + }; + }; +}; + + +void rs_gen_func_clamp(int dest, float vmin, float vmax) { + + float val; + int i, j; + for (i = 0; i < rs_gen_reg.tex_size; i++) { + for (j = 0; j < rs_gen_reg.tex_size; j++) { + val = rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j]; + rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] = + rs_clamp(val, vmin, vmax); + }; + }; +}; + + +void rs_gen_func_set(int dest, float val) { + int i, j; + for (i = 0; i < rs_gen_reg.tex_size; i++) { + for (j = 0; j < rs_gen_reg.tex_size; j++) { + rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] = val; + }; + }; +}; + +void rs_gen_func_noise(int dest, int seed) { + int i, j; + for (i = 0; i < rs_gen_reg.tex_size; i++) { + for (j = 0; j < rs_gen_reg.tex_size; j++) { + rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] = rs_noise(i+seed, j+seed/100); + }; + }; +}; + +void rs_gen_func_add(int dest, int src1, int src2, float k1, float k2) { + int i; + for (i = 0; i < rs_gen_reg.tex_length; i++ ) { + rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i] = + rs_gen_reg.tex[src1*rs_gen_reg.tex_length + i] * k1 + + rs_gen_reg.tex[src2*rs_gen_reg.tex_length + i] * k2; + }; +}; + +void rs_gen_func_add_lerped(int dest, int src1, int src2, float k1, float k2) { + int i; + for (i = 0; i < rs_gen_reg.tex_length; i++ ) { + rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i] = + rs_gen_reg.tex[src1*rs_gen_reg.tex_length + i] * (1.0 - 0.5*rs_gen_reg.tex[src2*rs_gen_reg.tex_length + i]) + + (1.0 - 0.5*rs_gen_reg.tex[src1*rs_gen_reg.tex_length + i]) * rs_gen_reg.tex[src2*rs_gen_reg.tex_length + i]; + }; +}; + +void rs_gen_func_lerp_parametric(int dest, int src1, int src2, int param) { + int i; + for (i = 0; i < rs_gen_reg.tex_length; i++ ) { + rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i] = + rs_gen_reg.tex[src1*rs_gen_reg.tex_length + i] * rs_gen_reg.tex[param*rs_gen_reg.tex_length + i] + + rs_gen_reg.tex[src2*rs_gen_reg.tex_length + i] * (1.0 - rs_gen_reg.tex[param*rs_gen_reg.tex_length + i]); + }; +}; + +void rs_gen_func_mult(int dest, int src1, int src2) { + int i; + for (i = 0; i < rs_gen_reg.tex_length; i++ ) { + rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i] = + rs_gen_reg.tex[src1*rs_gen_reg.tex_length + i] * rs_gen_reg.tex[src2*rs_gen_reg.tex_length + i]; + }; +}; + + + + +void rs_gen_init(int tex_count, int tex_size) { + rs_gen_reg.tex_count = tex_count; + rs_gen_reg.tex_size = tex_size; + rs_gen_reg.tex_length = tex_size*tex_size; + rs_gen_reg.tex = malloc(tex_count * tex_size * tex_size * 4); // float + rs_gen_reg.tex_out = malloc(tex_size * tex_size * 4); // unsigned char RGBA, RGB + rs_gen_tex_out_rgba_set(0.0, 0.0, 0.0, 0.0); +}; + +void rs_gen_term() { + free(rs_gen_reg.tex); + free(rs_gen_reg.tex_out); +}; + +void rs_gen_tex_out(int tex, int bpp) { + int i; + int j; + for (i = 0; i < rs_gen_reg.tex_length; i++) { + for (j = 0; j < bpp; j++) { + rs_gen_reg.tex_out[i*bpp + j] = 255*rs_gen_reg.tex[tex*rs_gen_reg.tex_length + i]; + }; + }; +}; + +void rs_gen_tex_out_rgb(int tex_r, int tex_g, int tex_b, float kr, float kg, float kb) { + int bpp = 3; + int i; + for (i = 0; i < rs_gen_reg.tex_length; i++) { + rs_gen_reg.tex_out[i*bpp + 0] += 255*kr*rs_gen_reg.tex[tex_r*rs_gen_reg.tex_length + i]; + rs_gen_reg.tex_out[i*bpp + 1] += 255*kg*rs_gen_reg.tex[tex_g*rs_gen_reg.tex_length + i]; + rs_gen_reg.tex_out[i*bpp + 2] += 255*kb*rs_gen_reg.tex[tex_b*rs_gen_reg.tex_length + i]; + }; +}; + +void rs_gen_tex_out_rgb_set(float r, float g, float b) { + int bpp = 3; + int i; + for (i = 0; i < rs_gen_reg.tex_length; i++) { + rs_gen_reg.tex_out[i*bpp + 0] = 255*r; + rs_gen_reg.tex_out[i*bpp + 1] = 255*g; + rs_gen_reg.tex_out[i*bpp + 2] = 255*b; + }; +}; + +void rs_gen_tex_out_rgba(int tex_r, int tex_g, int tex_b, int tex_a, float kr, float kg, float kb, float ka) { + int bpp = 4; + int i; + for (i = 0; i < rs_gen_reg.tex_length; i++) { + rs_gen_reg.tex_out[i*bpp + 0] += 255*kr*rs_gen_reg.tex[tex_r*rs_gen_reg.tex_length + i]; + rs_gen_reg.tex_out[i*bpp + 1] += 255*kg*rs_gen_reg.tex[tex_g*rs_gen_reg.tex_length + i]; + rs_gen_reg.tex_out[i*bpp + 2] += 255*kb*rs_gen_reg.tex[tex_b*rs_gen_reg.tex_length + i]; + rs_gen_reg.tex_out[i*bpp + 3] += (tex_a<0) ? 255 : 255*ka*rs_gen_reg.tex[tex_a*rs_gen_reg.tex_length + i]; // <---- -1 for alpha=1, for KolibriOS + }; +}; + +void rs_gen_tex_out_rgba_set(float r, float g, float b, float a) { + int bpp = 4; + int i; + for (i = 0; i < rs_gen_reg.tex_length; i++) { + rs_gen_reg.tex_out[i*bpp + 0] = 255*r; + rs_gen_reg.tex_out[i*bpp + 1] = 255*g; + rs_gen_reg.tex_out[i*bpp + 2] = 255*b; + rs_gen_reg.tex_out[i*bpp + 3] = 255*a; + }; +}; + + +void rs_gen_func_apply_mask(int dest, unsigned char *mask_data) { + + int i, j; + for (i = 0; i < rs_gen_reg.tex_size; i++) { + for (j = 0; j < rs_gen_reg.tex_size; j++) { + rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] *= + (mask_data[ j*rs_gen_reg.tex_size/8 + i/8] & (1 << (7 - (i%8)) ) ) ? 1.0 : 0.0; + }; + }; + +}; + +void rs_gen_func_posterize(int dest, int colors_count) { + int i; + float f; + for (i = 0; i < rs_gen_reg.tex_length; i++ ) { + f = rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i]; + f *= (254.0/255.0 + colors_count); + f = floor(f); + f /= colors_count; + rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i] = f; + }; +}; diff --git a/programs/games/heliothryx/game/rsgentex.h b/programs/games/heliothryx/game/rsgentex.h new file mode 100755 index 0000000000..cf27fd0011 --- /dev/null +++ b/programs/games/heliothryx/game/rsgentex.h @@ -0,0 +1,60 @@ +#ifndef RS_GTX_H +#define RS_GTX_H + +#include "rsgame.h" + +/* + + Procedural Texture Generator + by Roman Shuvalov + +*/ + +//void rs_model_create_pyramid(rs_vbo_t* vbo); + +void generate_perlin_tex(); + +typedef struct rs_gen_reg_t { + int tex_size; + int tex_length; // tex_size*tex_size + int tex_count; + float cell_scale; + float *tex; + unsigned char *tex_out; +} rs_gen_reg_t; + +extern rs_gen_reg_t rs_gen_reg; + +void rs_gen_init(int tex_count, int tex_size); + +void rs_gen_tex_out(int tex, int bpp); +void rs_gen_tex_out_rgb_set(float r, float g, float b); +void rs_gen_tex_out_rgb(int tex_r, int tex_g, int tex_b, float kr, float kg, float kb); +void rs_gen_tex_out_rgba_set(float r, float g, float b, float a); +void rs_gen_tex_out_rgba(int tex_r, int tex_g, int tex_b, int tex_a, float kr, float kg, float kb, float ka); + + +void rs_gen_term(); + +void rs_gen_func_mult_add_value(int dest, int src, float val_mult, float val_add); +void rs_gen_func_perlin(int dest, float freq, int octaves, float persistence, float seed); +void rs_gen_func_quads(int dest, float freq, int octaves, float persistence, float seed); +void rs_gen_func_radial(int dest, float x, float y, float radius, float v, float power); +void rs_gen_func_gradient_v(int dest, float v, float power); +void rs_gen_func_add(int dest, int src1, int src2, float k1, float k2); +void rs_gen_func_add_lerped(int dest, int src1, int src2, float k1, float k2); +void rs_gen_func_normalize(int dest, float vmin, float vmax); +void rs_gen_func_clamp(int dest, float vmin, float vmax); +void rs_gen_func_lerp_parametric(int dest, int src1, int src2, int param); +void rs_gen_func_mult(int dest, int src1, int src2); +void rs_gen_func_set(int dest, float val); +void rs_gen_func_noise(int dest, int seed); +void rs_gen_func_cell(int dest, int seed, int num_points, signed short *p, float k1, float pow1, float k2, float pow2, float k3, float pow3); +void rs_gen_func_adr(int dest, int src, int adr_x, int adr_y, float src_factor, float adr_factor); +void rs_gen_func_normalmap(int dest_r, int dest_g, int dest_b, int src, float k); + +void rs_gen_func_apply_mask(int dest, unsigned char *mask_data); +void rs_gen_func_posterize(int dest, int colors_count); + + +#endif diff --git a/programs/games/heliothryx/game/rskos.c b/programs/games/heliothryx/game/rskos.c new file mode 100644 index 0000000000..94231f51c1 --- /dev/null +++ b/programs/games/heliothryx/game/rskos.c @@ -0,0 +1,220 @@ +#include "rskos.h" + +#ifdef RS_LINUX + +#include "rs/rstexture.h" +#include "rs/rsgl.h" +#include "rs/rsshader.h" + +#include "rs/rsaudio.h" + +#include +#include + +//unsigned char* rskos_malloc(unsigned int bytes_count) { +// return malloc(bytes_count); +//}; +// +//void rskos_free(unsigned char* pointer) { +// free(pointer); +//}; +// +//void rskos_memset(unsigned char* pointer, unsigned char value, unsigned int bytes_count) { +// memset(pointer, value, bytes_count); +//}; +// +//void rskos_memcpy(unsigned char* dest, unsigned char* src, unsigned int bytes_count) { +// memcpy(dest, src, bytes_count); +//}; + + + +unsigned int rskos_get_time() { + + return rs_app.app_time; + +}; + +void rskos_draw_area(int x, int y, int w, int h, int k_scale, unsigned char *data, unsigned char *scaled_buffer) { + + + int i, j; + + for (i = 0; i < h*k_scale; i++) { + for (j = 0; j < w*k_scale; j++) { + scaled_buffer[ (i*w*k_scale + j)*3 + 0] = data[ ( (i/k_scale)*w + (j/k_scale) )*4 + 0]; + scaled_buffer[ (i*w*k_scale + j)*3 + 1] = data[ ( (i/k_scale)*w + (j/k_scale) )*4 + 1]; + scaled_buffer[ (i*w*k_scale + j)*3 + 2] = data[ ( (i/k_scale)*w + (j/k_scale) )*4 + 2]; + }; + }; + + + + + + + + glViewport(0, 0, rs_app.width, rs_app.height); + glClearColor( 0.2596078431, 0.2815686275, 0.3929411765, 1.0 ); // #98d0ed + //glClearColor( 0.0, 0.4, 0.1 + 0.5*0.001*(rs_get_time()%1024) , 1.0 ); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // <-- FBO + + + + + + + rs_tx_t tex = rs_tx_create_from_data(w*k_scale, h*k_scale, 3, 0, 1, scaled_buffer); + + glBindTexture(GL_TEXTURE_2D, tex); + + rs_sh_use(DefaultShader); + + rs_mx_identity_modelview(); + rs_mx_ortho_proj(); + + glUniformMatrix4fv( DefaultShader[RS_SH_PROJ_ID], 1, GL_FALSE, rs_reg.mx_proj ); + glUniformMatrix4fv( DefaultShader[RS_SH_MODELVIEW_ID], 1, GL_FALSE, rs_reg.mx_modelview ); + + glrsDrawRect(x, y, x+w*k_scale, y+h*k_scale, DefaultShader[RS_SH_POS_ID], DefaultShader[RS_SH_UV_ID]); + + rs_tx_destroy(&tex); + + + + + rsDoSwapBuffers(); + + // swap buffers (??) + + + +}; + + +void rskos_resize_window(int w, int h) { + // +}; + +void rskos_get_screen_size(unsigned int *pw, unsigned int *ph) { + *pw = rs_app.width + 50; + *ph = rs_app.height + 50; +}; + +void rskos_exit() { + rsAppExit(); +}; + +//void rskos_snd_init() { +// // +// +// rs_audio +// +//}; + +void rskos_snd_create_buffer(SNDBUF *hbuf, signed short *buffer, unsigned int length) { + // + + rs_sound_t *snd = malloc( sizeof(rs_sound_t) ); + rs_sound_create_from_data(snd, length*2, (unsigned char*) buffer); + + *hbuf = snd; + +}; + +void rskos_snd_update_buffer(SNDBUF *hbuf, signed short *buffer, unsigned int length) { + + rs_sound_destroy(*hbuf); + rskos_snd_create_buffer(hbuf, buffer, length); + +}; + +void rskos_snd_play(SNDBUF *hbuf, unsigned int mode) { + + rs_sound_play(*hbuf); + +}; + +void rskos_snd_stop(SNDBUF *hbuf) { + rs_sound_stop(*hbuf); +}; + + +#else + + #include "rs/rsplatform.h" + + + unsigned int rskos_get_time() { + return 1; + }; + + void rskos_draw_area(int x, int y, int w, int h, int k_scale, unsigned char *data, unsigned char *scaled_buffer) { + +// unsigned char *scaled_buffer = malloc(w*k_scale*h*k_scale*3); + int i, j; + + for (i = 0; i < h*k_scale; i++) { + for (j = 0; j < w*k_scale; j++) { + scaled_buffer[ (i*w*k_scale + j)*3 + 0] = data[ ( (i/k_scale)*w + (j/k_scale) )*4 + 0]; + scaled_buffer[ (i*w*k_scale + j)*3 + 1] = data[ ( (i/k_scale)*w + (j/k_scale) )*4 + 1]; + scaled_buffer[ (i*w*k_scale + j)*3 + 2] = data[ ( (i/k_scale)*w + (j/k_scale) )*4 + 2]; + }; + }; + + kol_paint_image(0, 0, w*k_scale, h*k_scale, scaled_buffer); + +// free(image_data); + + + + }; + + void rskos_resize_window(int w, int h) { + + // !!!!!!!!! add define-fix here + + w = -1 + w + 10; // 2 x 5px border + h = -1 + kol_skin_height() + h + 5; // bottom 5px border + + asm volatile ("int $0x40"::"a"(67), "b"(-1), "c"(-1), "d"(w), "S"(h)); + + }; + + void rskos_get_screen_size(unsigned int *pw, unsigned int *ph) { + kol_screen_get_size(pw, ph); + }; + + void rskos_exit() { + kol_exit(); + }; + + #define fmt PCM_1_16_16 // 1 channel, 16 bit per sample, 16 kHz + + void rskos_snd_create_buffer(SNDBUF *phbuf, signed short *buffer, unsigned int length_samples) { + unsigned int snd_format = fmt; + CreateBuffer(snd_format|PCM_STATIC, length_samples*2, phbuf); + int offset = 0; + SetBuffer(*phbuf, (void*)buffer, offset, length_samples*2); + }; + + void rskos_snd_update_buffer(SNDBUF *phbuf, signed short *buffer, unsigned int length_samples) { + unsigned int snd_format = fmt; +// CreateBuffer(snd_format|PCM_STATIC, length, phbuf); + int offset = 0; + SetBuffer(*phbuf, (void*)buffer, offset, length_samples*2); + }; + + void rskos_snd_play(SNDBUF *phbuf, unsigned int mode) { + SetBufferPos(*phbuf, 0); + PlayBuffer(*phbuf, 0); + }; + + void rskos_snd_stop(SNDBUF *phbuf) { + StopBuffer(*phbuf); + }; + + + +#endif diff --git a/programs/games/heliothryx/game/rskos.h b/programs/games/heliothryx/game/rskos.h new file mode 100644 index 0000000000..65f099cd7c --- /dev/null +++ b/programs/games/heliothryx/game/rskos.h @@ -0,0 +1,33 @@ +#ifndef RS_KOS_H +#define RS_KOS_H + +// KolibriOS Stuff +// by Roman Shuvalov + +unsigned int rskos_get_time(); + +void rskos_draw_area(int x, int y, int w, int h, int k_scale, unsigned char *data, unsigned char *scaled_buffer); + +void rskos_resize_window(int w, int h); +void rskos_get_screen_size(unsigned int *pw, unsigned int *ph); + +void rskos_exit(); + +// sound + +#ifndef SNDBUF + #ifdef RS_LINUX + #include "rs/rsaudio.h" + typedef rs_sound_t* SNDBUF; + #else + typedef unsigned int SNDBUF; + #endif +#endif + +//void rskos_snd_init(); +void rskos_snd_create_buffer(SNDBUF *phbuf, signed short *buffer, unsigned int length_samples); +void rskos_snd_update_buffer(SNDBUF *phbuf, signed short *buffer, unsigned int length_samples); +void rskos_snd_play(SNDBUF *phbuf, unsigned int mode); +void rskos_snd_stop(SNDBUF *phbuf); + +#endif diff --git a/programs/games/heliothryx/game/rsmain.c b/programs/games/heliothryx/game/rsmain.c new file mode 100755 index 0000000000..2568626dc9 --- /dev/null +++ b/programs/games/heliothryx/game/rsmain.c @@ -0,0 +1,14 @@ +#include "rsmain.h" + +#include "rsgame.h" + +void rs_main_init() { + + rs_app.rsAppOnInitDisplay = GameInit; + rs_app.rsAppOnTermDisplay = GameTerm; + + rs_app.OnKeyDown = GameKeyDown; + rs_app.OnKeyUp = GameKeyUp; + + rs_app.OnAppProcess = GameProcess; +}; diff --git a/programs/games/heliothryx/game/rsmain.h b/programs/games/heliothryx/game/rsmain.h new file mode 100755 index 0000000000..094475813d --- /dev/null +++ b/programs/games/heliothryx/game/rsmain.h @@ -0,0 +1,3 @@ +#include "rs/rsplatform.h" + +void rs_main_init(); diff --git a/programs/games/heliothryx/game/rsnoise.c b/programs/games/heliothryx/game/rsnoise.c new file mode 100755 index 0000000000..d399484937 --- /dev/null +++ b/programs/games/heliothryx/game/rsnoise.c @@ -0,0 +1,175 @@ +#include "rsnoise.h" + +#include "rsgame.h" + +#ifdef RS_USE_C_LIBS + #include + #include +#else + #include "rs/rsplatform.h" +#endif + +rs_perlin_conf_t rs_perlin_conf; + +void rs_perlin_configure(float freq, int octaves, float persistence, float seed, int tex_size) { + rs_perlin_conf.freq = freq; + rs_perlin_conf.octaves = octaves; + rs_perlin_conf.persistence = persistence; + rs_perlin_conf.seed = seed; + rs_perlin_conf.tex_size = tex_size; + rs_perlin_conf.period = (int) (0.1 + roundf(freq) ); // *tex_size +}; + +float rs_noise(int x, int y) { + // from here, http://www.cplusplus.com/forum/general/85758/ + // koef. changed + int n = x + y * 57 * 5; // no *2 + n = (n << 13) ^ n; + int t = (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff; + return 1.0 - ((float)t) * 0.931322574615478515625e-9;/// 1073741824.0); +} + +float rs_noise_for_perlin(int x, int y) { + + x %= rs_perlin_conf.period; + y %= rs_perlin_conf.period; + + // from here, http://www.cplusplus.com/forum/general/85758/ + // koef. changed + int n = x + y * 57 * 5; // no *2 + n = (n << 13) ^ n; + int t = (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff; + return 1.0 - ((float)t) * 0.931322574615478515625e-9;/// 1073741824.0); +} + +//float rs_noise_periodical(int x, int y, int period) { +// +// x %= period; +// y %= period; +// +// // from here, http://www.cplusplus.com/forum/general/85758/ +// // koef. changed +// int n = x + y * 57 * 5; // no *2 +// n = (n << 13) ^ n; +// int t = (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff; +// return 1.0 - ((float)t) * 0.931322574615478515625e-9;/// 1073741824.0); +//} + +float rs_interpolate(float x, float y, float a) { + float negA = 1.0 - a; + float negASqr = negA * negA; + float fac1 = 3.0 * (negASqr) - 2.0 * (negASqr * negA); + float aSqr = a * a; + float fac2 = 3.0 * aSqr - 2.0 * (aSqr * a); + + return x * fac1 + y * fac2; //add the weighted factors +} + +float rs_perlin_noise(float x, float y) { + +// while (x > rs_perlin_conf.tile_period) { +// x -= rs_perlin_conf.tile_period; +// }; +// +// while (y > rs_perlin_conf.tile_period) { +// y -= rs_perlin_conf.tile_period; +// }; + + int Xint = (int)x; + int Yint = (int)y; + float Xfrac = x - Xint; + float Yfrac = y - Yint; + + + //noise values + float n01= rs_noise_for_perlin(Xint-1, Yint-1); + float n02= rs_noise_for_perlin(Xint+1, Yint-1); + float n03= rs_noise_for_perlin(Xint-1, Yint+1); + float n04= rs_noise_for_perlin(Xint+1, Yint+1); + float n05= rs_noise_for_perlin(Xint-1, Yint); + float n06= rs_noise_for_perlin(Xint+1, Yint); + float n07= rs_noise_for_perlin(Xint, Yint-1); + float n08= rs_noise_for_perlin(Xint, Yint+1); + float n09= rs_noise_for_perlin(Xint, Yint); + + float n12= rs_noise_for_perlin(Xint+2, Yint-1); + float n14= rs_noise_for_perlin(Xint+2, Yint+1); + float n16= rs_noise_for_perlin(Xint+2, Yint); + + float n23= rs_noise_for_perlin(Xint-1, Yint+2); + float n24= rs_noise_for_perlin(Xint+1, Yint+2); + float n28= rs_noise_for_perlin(Xint, Yint+2); + + float n34= rs_noise_for_perlin(Xint+2, Yint+2); + + //find the noise values of the four corners + float x0y0 = 0.0625*(n01+n02+n03+n04) + 0.125*(n05+n06+n07+n08) + 0.25*(n09); + float x1y0 = 0.0625*(n07+n12+n08+n14) + 0.125*(n09+n16+n02+n04) + 0.25*(n06); + float x0y1 = 0.0625*(n05+n06+n23+n24) + 0.125*(n03+n04+n09+n28) + 0.25*(n08); + float x1y1 = 0.0625*(n09+n16+n28+n34) + 0.125*(n08+n14+n06+n24) + 0.25*(n04); + + //interpolate between those values according to the x and y fractions + float v1 = rs_interpolate(x0y0, x1y0, Xfrac); //interpolate in x direction (y) + float v2 = rs_interpolate(x0y1, x1y1, Xfrac); //interpolate in x direction (y+1) + float fin = rs_interpolate(v1, v2, Yfrac); //interpolate in y direction + + return fin; +} + +float rs_perlin(float i, float j) { + + float t = 0.0f; + float _amplitude = 1.0; + + + int k; + + float amplitude_divider = 0.0; + for (k = 0; k < rs_perlin_conf.octaves; k++) { + amplitude_divider += _amplitude; + _amplitude *= rs_perlin_conf.persistence; + }; + + _amplitude = 1.0; + + float freq = rs_perlin_conf.freq; + + for(k = 0; k < rs_perlin_conf.octaves; k++) + { + t += rs_perlin_noise(j * freq / rs_perlin_conf.tex_size + rs_perlin_conf.seed, i * freq / rs_perlin_conf.tex_size + rs_perlin_conf.seed) * _amplitude; + _amplitude *= rs_perlin_conf.persistence; + freq *= 2; + } + + return t / amplitude_divider; +}; + +float rs_quad_noise(float i, float j) { + + float t = 0.0f; + float _amplitude = 1.0; + + + int k; + + float amplitude_divider = 0.0; + for (k = 0; k < rs_perlin_conf.octaves; k++) { + amplitude_divider += _amplitude; + _amplitude *= rs_perlin_conf.persistence; + }; + + _amplitude = 1.0; + + float freq = rs_perlin_conf.freq; + + for(k = 0; k < rs_perlin_conf.octaves; k++) + { + t += rs_noise(j * freq / rs_perlin_conf.tex_size + rs_perlin_conf.seed, i * freq / rs_perlin_conf.tex_size + rs_perlin_conf.seed) * _amplitude; + _amplitude *= rs_perlin_conf.persistence; + freq *= 2; + } + + return t / amplitude_divider; +}; + + diff --git a/programs/games/heliothryx/game/rsnoise.h b/programs/games/heliothryx/game/rsnoise.h new file mode 100755 index 0000000000..25278e0d76 --- /dev/null +++ b/programs/games/heliothryx/game/rsnoise.h @@ -0,0 +1,27 @@ +#ifndef RS_NOISE_H +#define RS_NOISE_H + +#include "rsgame.h" + +//void rs_model_create_pyramid(rs_vbo_t* vbo); + +float rs_perlin(float i, float j); +float rs_quad_noise(float i, float j); + +float rs_noise(int x, int y); +float rs_noise_for_perlin(int x, int y); + +void rs_perlin_configure(float freq, int octaves, float persistence, float seed, int tex_size); + +typedef struct rs_perlin_conf_t { + float freq; + int octaves; + float persistence; + float seed; + int period; + int tex_size; +} rs_perlin_conf_t; + +extern rs_perlin_conf_t rs_perlin_conf; + +#endif diff --git a/programs/games/heliothryx/game/rssoundgen.c b/programs/games/heliothryx/game/rssoundgen.c new file mode 100755 index 0000000000..49c97386e5 --- /dev/null +++ b/programs/games/heliothryx/game/rssoundgen.c @@ -0,0 +1,457 @@ +#include "rssoundgen.h" + +/* + +#include "rsnoise.h" + +#include "rs/rsmx.h" + +#include +#include + +rs_sgen_reg_t rs_sgen_reg; + +void rs_sgen_init(int waves_count, int wave_length) { + rs_sgen_reg.waves_count = waves_count; + rs_sgen_reg.wave_length = wave_length; + rs_sgen_reg.wave = malloc(waves_count * wave_length * 4); // float + rs_sgen_reg.wave_out = malloc(wave_length * 2); // signed short + + memset(rs_sgen_reg.wave, 0, waves_count * wave_length * 4); + memset(rs_sgen_reg.wave_out, 0, wave_length * 2); +}; + +void rs_sgen_term() { + free(rs_sgen_reg.wave); + free(rs_sgen_reg.wave_out); +}; + +int wave_shot_index = 0; + +void rs_sgen_wave_out(int index) { + int i; + for (i = 0; i < rs_sgen_reg.wave_length; i++) { + rs_sgen_reg.wave_out[i] = 32767* (rs_clamp (rs_sgen_reg.wave[index*rs_sgen_reg.wave_length + i], -1.0, 1.0 )); + }; + + +// char cmd[330]; +// memset(cmd, 0, 330); +// sprintf(cmd, "/home/romik/temp/images/sound%d.data", wave_shot_index); +// +// RS_IO_FILE* fp = rs_io_fopen( cmd, "wb"); +// +// rs_io_fwrite(fp, rs_sgen_reg.wave_out, rs_sgen_reg.wave_length*2); +// rs_io_fclose(fp); +// +// wave_shot_index++; + + + +}; + +// -------------------- + + +//float rs_sgen_osc_sin(int i, float freq, float p) { +// // +//}; + + + + +float phaser_alps_a1[6]; +float phaser_alps_zm1[6]; + +float phaser_dmin, phaser_dmax; //range +float phaser_fb; //feedback +float phaser_lfoPhase; +float phaser_lfoInc; +float phaser_depth; +float phaser_sample_rate; +int phaser_value_index = -1; + +float phaser_zm1; + +void phaser_set_range(float f1, float f2); +void phaser_set_rate(float f); +void phaser_alps_delay(int i, float f); +float phaser_alps_update(int i, float f); + +void phaser_reset( float fb, float lfoPhase, float depth, float range_start, float range_end, float rate ) { + memset(phaser_alps_a1, 0, 6*4); + memset(phaser_alps_zm1, 0, 6*4); + + phaser_sample_rate = 44100.0; // !!!! + + phaser_fb = fb; + phaser_lfoPhase = lfoPhase; + phaser_depth = depth; + phaser_zm1 = 0.0; +// phaser_set_range( 440.f, 1600.f ); + phaser_set_range( range_start, range_end ); + phaser_set_rate( rate ); + +}; + +void phaser_set_range(float fMin, float fMax) { // Hz + phaser_dmin = fMin / (phaser_sample_rate/2.f); + phaser_dmax = fMax / (phaser_sample_rate/2.f); +}; + +void phaser_set_rate( float rate ){ // cps + phaser_lfoInc = 2.0f * M_PI * (rate / phaser_sample_rate); +}; + +float phaser_update_sample( float inSamp, int ind ){ + //calculate and update phaser sweep lfo... + float d; + if (phaser_value_index == -1) { + d = phaser_dmin + (phaser_dmax-phaser_dmin) * ((sin( phaser_lfoPhase ) + 1.0f)/2.0f); + } + else { + d = phaser_dmin + (phaser_dmax-phaser_dmin) * (0.5+0.5*rs_sgen_reg.wave[ phaser_value_index*rs_sgen_reg.wave_length + ind ]); + }; + + phaser_lfoPhase += phaser_lfoInc; + if( phaser_lfoPhase >= M_PI * 2.0f ) + phaser_lfoPhase -= M_PI * 2.0f; + + //update filter coeffs + int i; + for(i = 0; i < 6; i++) { + phaser_alps_delay(i, d); + }; + + //calculate output + float y = phaser_alps_update(0, + phaser_alps_update(1, + phaser_alps_update(2, + phaser_alps_update(3, + phaser_alps_update(4, + phaser_alps_update(5, + inSamp + phaser_zm1 * phaser_fb + ) + ) + ) + ) + ) + ); + +// float y = _alps[0].Update( +// _alps[1].Update( +// _alps[2].Update( +// _alps[3].Update( +// _alps[4].Update( +// _alps[5].Update( inSamp + _zm1 * _fb )))))); + phaser_zm1 = y; + +// return sin(440.0*phaser_lfoPhase); + + return inSamp + y * phaser_depth; +} + +void phaser_alps_delay(int i, float delay) { + phaser_alps_a1[i] = (1.0f - delay) / (1.0f + delay); +}; + +float phaser_alps_update(int i, float inSamp) { + float y = inSamp * - phaser_alps_a1[i] + phaser_alps_zm1[i]; + phaser_alps_zm1[i] = y * phaser_alps_a1[i] + inSamp; + return y; +}; + +// ----------------------- + + +void rs_sgen_func_speaker(int index) { + + + + int i; + + float alpha = 0.3 ;// dt / (RC+dt) + + + for (i = 0; i < rs_sgen_reg.wave_length; i++) { + + + if (i == 0) { + rs_sgen_reg.wave[ rs_sgen_reg.wave_length * index + i] = 0.4 * rs_noise(i, 0); + continue; + }; + + + // Low-pass +// rs_sgen_reg.wave[ rs_sgen_reg.wave_length * index + i] = +// alpha * 0.4 * rs_noise(i, 0) + (1.0 - alpha) * (rs_sgen_reg.wave[ rs_sgen_reg.wave_length * index + i - 1 ]); + + + // High-pass + rs_sgen_reg.wave[ rs_sgen_reg.wave_length * index + i] = + alpha * ( rs_sgen_reg.wave[ rs_sgen_reg.wave_length * index + i - 1 ] + 0.4 * rs_noise(i, 0) - 0.4 * rs_noise(i-1, 0) ); + + + +//// rs_sgen_reg.wave[ rs_sgen_reg.wave_length * index + i] = 0.1 * sin( (2.0f * M_PI * 440.0 * i ) / 44100.0 + 9.0*sin(0.12*i) ); +// int t = i + 4*65536; +// int p = (unsigned char) ((((t * (t >> 8 | t >> 9) & 46 & t >> 8)) ^ (t & t >> 13 | t >> 6)) & 0xFF); +//// rs_sgen_reg.wave[ rs_sgen_reg.wave_length * index + i] = (float)(p-128) / 128.0; // (float) 1.0 / 256.0 * (p); + }; + +// rs_sound_create_from_data(&game.test_sound, 688200, audiodata); + +// for (i = 0; i < 20; i++) { +// rs_sound_create_from_data(& (sounds[i]), 11025 * (1 + i % 3) , audiodata2); +// rs_sound_adjust_pitch( &sounds[i], 0.5 + 1.0f * i / 20.0f ); +// }; + +// DEBUG10f("sound is created. length = %d \n", game.test_sound.Length); + + +// memset(audiodata, 0, 688200); +// free(audiodata); + +}; + + +void rs_sgen_func_noise(int index, int seed) { + int i; + for (i = 0; i < rs_sgen_reg.wave_length; i++) { + rs_sgen_reg.wave[ rs_sgen_reg.wave_length * index + i] = rs_noise(seed + i, 0); + }; +}; + + + +void rs_sgen_func_sin(int index, float freq, float p) { + int i; + float f; + + for (i = 0; i < rs_sgen_reg.wave_length; i++) { + f = sin( (2.0f * M_PI * freq * i ) / 44100.0 ); // !!! Only for 44100 kHz + rs_sgen_reg.wave[ rs_sgen_reg.wave_length * index + i] = rs_sign(f) * pow( fabs(f) , p ); // remove koef! + // rs_sgen_reg.wave[ rs_sgen_reg.wave_length * index + i] = 0.1 * sin( (2.0f * M_PI * 440.0 * i ) / 44100.0 + 9.0*sin(0.12*i) ); +// rs_sgen_reg.wave[ rs_sgen_reg.wave_length * index + i] = -1.0 + 2.0 * ( (44100.0 / freq) ) sin( (2.0f * M_PI * freq * i ) / 44100.0 ); // !!! Only for 44100 kHz + }; +}; + + + +void rs_sgen_func_pm(int index, float freq, float p, float k, float freq2, float p2) { + int i; + float f; + + for (i = 0; i < rs_sgen_reg.wave_length; i++) { + f = sin( (2.0f * M_PI * freq * i ) / 44100.0 + k*rs_pow(sin( 2.0f * M_PI * freq2 * i / 44100.0 ), p2) ); // !!! Only for 44100 kHz + rs_sgen_reg.wave[ rs_sgen_reg.wave_length * index + i] = rs_pow(f, p); + // rs_sgen_reg.wave[ rs_sgen_reg.wave_length * index + i] = 0.1 * sin( (2.0f * M_PI * 440.0 * i ) / 44100.0 + 9.0*sin(0.12*i) ); +// rs_sgen_reg.wave[ rs_sgen_reg.wave_length * index + i] = -1.0 + 2.0 * ( (44100.0 / freq) ) sin( (2.0f * M_PI * freq * i ) / 44100.0 ); // !!! Only for 44100 kHz + }; +}; + +void rs_sgen_func_add(int dest, int src1, int src2, float k1, float k2) { + int i; + + for (i = 0; i < rs_sgen_reg.wave_length; i++) { + rs_sgen_reg.wave[ rs_sgen_reg.wave_length * dest + i] = + k1 * rs_sgen_reg.wave[ rs_sgen_reg.wave_length * src1 + i] + + k2 * rs_sgen_reg.wave[ rs_sgen_reg.wave_length * src2 + i]; + }; + +}; + +void rs_sgen_func_mult(int dest, int src1, int src2) { + int i; + + for (i = 0; i < rs_sgen_reg.wave_length; i++) { + rs_sgen_reg.wave[ rs_sgen_reg.wave_length * dest + i] = + rs_sgen_reg.wave[ rs_sgen_reg.wave_length * src1 + i] + * rs_sgen_reg.wave[ rs_sgen_reg.wave_length * src2 + i]; + }; + +}; + + +void rs_sgen_func_normalize(int dest, float amp) { + +// DEBUG10("Normalize..."); + + float val_max = 0.0; // fabs(rs_sgen_reg.wave[ rs_sgen_reg.wave_length * dest ]); + float f; + + int i; + + // Step 1: Normalize Mid-line + + const int mar_samples_count = 512; + + float *mar = malloc( 4 * (2 + rs_sgen_reg.wave_length / mar_samples_count) ); + memset(mar, 0, 4 * (2 + rs_sgen_reg.wave_length / mar_samples_count) ); + +// DEBUG10("label 1"); + + int length_512 = mar_samples_count*(rs_sgen_reg.wave_length/mar_samples_count); // 1024 for 1027 + + int last_length = rs_sgen_reg.wave_length - length_512; + if (!last_length) { + last_length = length_512; + }; + + float koef[2] = { 1.0/mar_samples_count, 1.0/(last_length) }; + +// DEBUG10f("\nkoef 0: %.6f\nkoef 1: %.6f (last_length = %d)\n", koef[0], koef[1], last_length); + + for (i = 0; i < rs_sgen_reg.wave_length; i++) { + mar[1+i/mar_samples_count] += koef[ i / (length_512) ] * rs_sgen_reg.wave[ rs_sgen_reg.wave_length * dest + i]; + }; + +// DEBUG10("label 2"); + + + for (i = 0; i < rs_sgen_reg.wave_length; i++) { + rs_sgen_reg.wave[ rs_sgen_reg.wave_length * dest + i] -= //mar[i/mar_samples_count]; + rs_linear_interpolate( mar[i/mar_samples_count], mar[1+i/mar_samples_count], rs_fract(1.0*i/mar_samples_count) ); + }; +// +// DEBUG10("label 3"); + + free(mar); + +// DEBUG10("label 4"); + + + // Step 2: Normalize Amplitude + + for (i = 0; i < rs_sgen_reg.wave_length; i++) { + f = rs_sgen_reg.wave[ rs_sgen_reg.wave_length * dest + i]; + val_max = rs_max(val_max, fabs(f) ); + }; + + float val_scale = amp / val_max; + +// DEBUG10f("SGEN Normalize: val_max %.3f, val_scale = %.3f \n", val_max, val_scale); + + for (i = 0; i < rs_sgen_reg.wave_length; i++) { + rs_sgen_reg.wave[ rs_sgen_reg.wave_length * dest + i] = val_scale * rs_sgen_reg.wave[ rs_sgen_reg.wave_length * dest + i]; + }; + + + +}; + + + +void rs_sgen_func_limiter(int dest, float val) { + + rs_sgen_func_normalize(dest, 1.0/val); + + int i; + for (i = 0; i < rs_sgen_reg.wave_length; i++) { + rs_sgen_reg.wave[ rs_sgen_reg.wave_length * dest + i] = rs_clamp( + rs_sgen_reg.wave[ rs_sgen_reg.wave_length * dest + i ], -1.0, 1.0 ); + }; + +// float val_scale = amp / val_max; +// +// DEBUG10f("SGEN Normalize: val_max %.3f, val_scale = %.3f \n", val_max, val_scale); +// +// for (i = 0; i < rs_sgen_reg.wave_length; i++) { +// rs_sgen_reg.wave[ rs_sgen_reg.wave_length * dest + i] = val_scale * rs_sgen_reg.wave[ rs_sgen_reg.wave_length * dest + i]; +// }; +}; + + +void rs_sgen_func_reverb(int dest, int src, int echo_delay, float echo_decay_koef) { + + // + + int i; + for (i = 0; i < rs_sgen_reg.wave_length; i++) { + + if (i + echo_delay > rs_sgen_reg.wave_length-1) { + break; + }; + + rs_sgen_reg.wave[ rs_sgen_reg.wave_length * dest + i + echo_delay] += + echo_decay_koef * rs_sgen_reg.wave[ rs_sgen_reg.wave_length * dest + i]; + }; + +}; + + +void rs_sgen_func_lowpass(int dest, int src, float alpha_start, float alpha_end, float alpha_pow) { + + int i; + float alpha, t; + + for (i = 0; i < rs_sgen_reg.wave_length; i++) { + + if (i == 0) { + rs_sgen_reg.wave[ rs_sgen_reg.wave_length * dest + i] = + 0; // rs_sgen_reg.wave[ rs_sgen_reg.wave_length * src + i]; + continue; + }; + + t = (float) i / rs_sgen_reg.wave_length; + alpha = (1.0 - t) * alpha_start + t * alpha_end; + alpha = pow(alpha, alpha_pow); + + // Low-pass + rs_sgen_reg.wave[ rs_sgen_reg.wave_length * dest + i] = + alpha * rs_sgen_reg.wave[ rs_sgen_reg.wave_length * src + i] + + (1.0 - alpha) * (rs_sgen_reg.wave[ rs_sgen_reg.wave_length * dest + i - 1 ]); + + }; +}; + + +void rs_sgen_func_highpass(int dest, int src, float alpha_start, float alpha_end, float alpha_pow) { + + int i; + float t, alpha; + + for (i = 0; i < rs_sgen_reg.wave_length; i++) { + + if (i == 0) { + rs_sgen_reg.wave[ rs_sgen_reg.wave_length * dest + i] = 0; // rs_sgen_reg.wave[ rs_sgen_reg.wave_length * src + i]; + continue; + }; + + t = (float) i / rs_sgen_reg.wave_length; + alpha = (1.0 - t) * alpha_start + t * alpha_end; + alpha = pow(alpha, alpha_pow); + + // High-pass + rs_sgen_reg.wave[ rs_sgen_reg.wave_length * dest + i] = + alpha * ( rs_sgen_reg.wave[ rs_sgen_reg.wave_length * dest + i - 1] + + rs_sgen_reg.wave[ rs_sgen_reg.wave_length * src + i] + - rs_sgen_reg.wave[ rs_sgen_reg.wave_length * src + i - 1] ); + + }; + +}; + +void rs_sgen_func_phaser(int dest, int src, float fb, float lfoPhase, float depth, float range_start, float range_end, float rate) { + + //phaser_reset(0.97, 1.67, 0.5, 1.0, 22050.0, 1.5); + phaser_reset(fb, lfoPhase, depth, range_start, range_end, rate); + + int i; +// float t, alpha; + + for (i = 0; i < rs_sgen_reg.wave_length + 12; i++) { + rs_sgen_reg.wave[ rs_sgen_reg.wave_length * dest + i%rs_sgen_reg.wave_length] = phaser_update_sample( rs_sgen_reg.wave[ rs_sgen_reg.wave_length * src + i%rs_sgen_reg.wave_length], i%rs_sgen_reg.wave_length ); + }; + +}; + +void rs_sgen_func_shift(int dest, int src) { + int i; + for (i = 0; i < rs_sgen_reg.wave_length; i++) { + rs_sgen_reg.wave[ rs_sgen_reg.wave_length * dest + i % rs_sgen_reg.wave_length] + = rs_sgen_reg.wave[ rs_sgen_reg.wave_length * src + (i + rs_sgen_reg.wave_length/2 )%rs_sgen_reg.wave_length]; + }; +}; + +*/ diff --git a/programs/games/heliothryx/game/rssoundgen.h b/programs/games/heliothryx/game/rssoundgen.h new file mode 100755 index 0000000000..58b5387dda --- /dev/null +++ b/programs/games/heliothryx/game/rssoundgen.h @@ -0,0 +1,45 @@ +#ifndef RS_SNDGEN_H +#define RS_SNDGEN_H + +#include "rsgame.h" + +/* + +#include "rs/rsaudio.h" + +typedef struct rs_sgen_reg_t { + int wave_length; + int waves_count; + float *wave; + signed short *wave_out; +} rs_sgen_reg_t; + +extern rs_sgen_reg_t rs_sgen_reg; + +void rs_sgen_init(int waves_count, int wave_length); +void rs_sgen_wave_out(int index); +void rs_sgen_term(); + +void rs_sgen_func_noise(int index, int seed); +void rs_sgen_func_sin(int index, float freq, float p); +void rs_sgen_func_pm(int index, float freq, float p, float k, float freq2, float p2); + +void rs_sgen_func_lowpass(int dest, int src, float alpha_start, float alpha_end, float alpha_pow); +void rs_sgen_func_highpass(int dest, int src, float alpha_start, float alpha_end, float alpha_pow); +//void rs_sgen_func_phaser(int dest, int src); +void rs_sgen_func_phaser(int dest, int src, float fb, float lfoPhase, float depth, float range_start, float range_end, float rate); +void rs_sgen_func_normalize(int dest, float amp); +void rs_sgen_func_limiter(int dest, float val); +void rs_sgen_func_reverb(int dest, int src, int echo_delay, float echo_decay_koef); + +#define rs_sgen_func_copy(dst,src) rs_sgen_func_add(dst,src,dst,1.0,0.0) +void rs_sgen_func_add(int dest, int src1, int src2, float k1, float k2); +void rs_sgen_func_mult(int dest, int src1, int src2); + +void rs_sgen_func_shift(int dest, int src); + +//void rs_gen_func_mult_add_value(int dest, int src, float val_mult, float val_add); + +*/ + +#endif diff --git a/programs/games/heliothryx/kolibri.ld b/programs/games/heliothryx/kolibri.ld new file mode 100644 index 0000000000..5108410375 --- /dev/null +++ b/programs/games/heliothryx/kolibri.ld @@ -0,0 +1,24 @@ +/*OUTPUT_FORMAT("binary")*/ +ENTRY(Start) +SECTIONS +{ + .text 0x000000: + { + *(.text) + } + + .data : { + *(.data) + hEnd = . ; + } + + .bss : + { + *(.bss) + } + Memory = . ; + /DISCARD/ : { + *(.comment) + *(.drectve) + } +} diff --git a/programs/games/heliothryx/start.asm b/programs/games/heliothryx/start.asm new file mode 100644 index 0000000000..d8f0f13995 --- /dev/null +++ b/programs/games/heliothryx/start.asm @@ -0,0 +1,41 @@ + +format MS COFF + +public Start +public _PATH +public _PARAM + +extrn Memory +extrn hEnd + +extrn _kol_main + +section ".text" code + db "MENUET01" + dd 1, Start, hEnd, Memory, hStack, _PARAM, _PATH + +Start: + +; èíèöèàëèçàöèÿ êó÷è +mov eax, 68 +mov ebx, 11 +int 0x40 + +; âûçîâ ãëàâíîé ïðîöåäóðû +mov eax, _kol_main +call eax + +; çàâåðøåíèå ðàáîòû ïðîãðàììû +mov eax, -1 +int 0x40 + +section ".bss" + +_PARAM: +rb 256 + +_PATH: +rb 256 + +rb 8*1024 +hStack: diff --git a/programs/games/heliothryx/system/boolean.h b/programs/games/heliothryx/system/boolean.h new file mode 100644 index 0000000000..072ddad2f3 --- /dev/null +++ b/programs/games/heliothryx/system/boolean.h @@ -0,0 +1,3 @@ + +#define FALSE 0 +#define TRUE 1 diff --git a/programs/games/heliothryx/system/console.c b/programs/games/heliothryx/system/console.c new file mode 100644 index 0000000000..7883274c65 --- /dev/null +++ b/programs/games/heliothryx/system/console.c @@ -0,0 +1,88 @@ + +///=========================== + +#define CON_COLOR_BLUE 1 +#define CON_COLOR_GREEN 2 +#define CON_COLOR_RED 4 +#define CON_COLOR_BRIGHT 8 +/* öâåò ôîíà */ +#define CON_BGR_BLUE 0x10 +#define CON_BGR_GREEN 0x20 +#define CON_BGR_RED 0x40 +#define CON_BGR_BRIGHT 0x80 + +///=========================== + +void (* _stdcall con_init)(unsigned w_w, unsigned w_h, unsigned s_w, unsigned s_h, const char* t); +void (* _cdecl printf)(const char* format,...); +void (* _stdcall _exit)(char bCloseWindow); +void (* __stdcall gets)(char* str, int n); + int (* __stdcall getch)(void); + int (* __stdcall con_get_font_height)(void); + int (* __stdcall con_set_cursor_height)(int new_height); +unsigned (*__stdcall con_get_flags)(void); +unsigned (*__stdcall con_set_flags)(unsigned new_flags); +void (*__stdcall con_cls)(void); + +///=========================== + +void CONSOLE_INIT(char title[]) +{ +kol_struct_import *imp; + +imp = kol_cofflib_load("/sys/lib/console.obj"); +if (imp == NULL) + kol_exit(); + +con_init = ( _stdcall void (*)(unsigned, unsigned, unsigned, unsigned, const char*)) + kol_cofflib_procload (imp, "con_init"); +if (con_init == NULL) + kol_exit(); + +printf = ( _cdecl void (*)(const char*,...)) + kol_cofflib_procload (imp, "con_printf"); +if (printf == NULL) + kol_exit(); + +_exit = ( _stdcall void (*)(char)) + kol_cofflib_procload (imp, "con_exit"); +if (_exit == NULL) + kol_exit(); + +gets = ( _stdcall void (*)(char*, int)) + kol_cofflib_procload (imp, "con_gets"); +if (gets == NULL) + kol_exit(); + +getch = ( _stdcall int (*)(void)) + kol_cofflib_procload (imp, "con_getch2"); +if (getch == NULL) + kol_exit(); + +con_get_font_height = ( _stdcall int (*)(void)) + kol_cofflib_procload (imp, "con_get_font_height"); +if (con_get_font_height == NULL) + kol_exit(); + +con_set_cursor_height = ( _stdcall int (*)(int)) + kol_cofflib_procload (imp, "con_set_cursor_height"); +if (con_set_cursor_height == NULL) + kol_exit(); + +con_get_flags = ( _stdcall unsigned (*)(void)) + kol_cofflib_procload (imp, "con_get_flags"); +if (con_get_flags == NULL) + kol_exit(); + +con_set_flags = ( _stdcall unsigned (*)(unsigned)) + kol_cofflib_procload (imp, "con_set_flags"); +if (con_set_flags == NULL) + kol_exit(); + +con_cls = ( _stdcall void (*)(void)) + kol_cofflib_procload (imp, "con_cls"); +if (con_cls == NULL) + kol_exit(); + +con_init(-1, -1, -1, -1, title); +} diff --git a/programs/games/heliothryx/system/kolibri.c b/programs/games/heliothryx/system/kolibri.c new file mode 100644 index 0000000000..35c33eaef9 --- /dev/null +++ b/programs/games/heliothryx/system/kolibri.c @@ -0,0 +1,440 @@ + +#include "kolibri.h" +//#include "string.h" + + +extern char KOL_PATH[256]; +extern char KOL_PARAM[256]; +extern char KOL_DIR[256]; + + +void kol_exit() +{ +asm volatile ("int $0x40"::"a"(-1)); +} + + +void kol_sleep(unsigned d) +{ +asm volatile ("int $0x40"::"a"(5), "b"(d)); +} + + +// define a window +// x, y - position; w, h - size; cs - color and style; c - caption; b - boder +void kol_wnd_define(unsigned x, unsigned y, unsigned w, unsigned h, unsigned cs, unsigned b, char *t) +{ +asm volatile ("int $0x40"::"a"(0), "b"(x*65536+w), "c"(y*65536+h), "d"(cs), "D"(t), "S"(b) ); +} + + +void kol_wnd_move(unsigned x, unsigned y) +{ +asm volatile ("int $0x40"::"a"(67), "b"(x), "c"(y), "d"(-1), "S"(-1)); +} + + +void kol_event_mask(unsigned e) +{ +asm volatile ("int $0x40"::"a"(40), "b"(e)); +} + + +unsigned kol_event_wait() +{ +asm volatile ("int $0x40"::"a"(10)); +} + + +unsigned kol_event_wait_time(unsigned time) +{ +asm volatile ("int $0x40"::"a"(23), "b"(time)); +} + + +unsigned kol_event_check() +{ +asm volatile ("int $0x40"::"a"(11)); +} + + +void __attribute__((__always_inline__)) inline kol_paint_start() +{ +asm volatile ("int $0x40"::"a"(12), "b"(1)); +} + + +void __attribute__((__always_inline__)) inline kol_paint_end() +{ +asm volatile ("int $0x40"::"a"(12), "b"(2)); +} + + +void kol_paint_pixel(unsigned x, unsigned y, unsigned c) +{ +asm volatile ("int $0x40"::"a"(1), "b"(x), "c"(y), "d"(c)); +} + + +void kol_paint_bar(unsigned x, unsigned y, unsigned w, unsigned h, unsigned c) +{ +asm volatile ("int $0x40"::"a"(13), "b"(x*65536+w), "c"(y*65536+h), "d"(c)); +} + + +void kol_paint_line(unsigned x1, unsigned y1, unsigned x2, unsigned y2, unsigned c) +{ +asm volatile ("int $0x40"::"a"(38), "b"(x1*65536+x2), "c"(y1*65536+y2), "d"(c)); +} + + +void kol_paint_string(unsigned x, unsigned y, char *s, unsigned c) +{ +asm volatile ("int $0x40"::"a"(4), "b"(x*65536+y), "c"(c), "d"(s)); +} + + +void kol_paint_image(unsigned x, unsigned y, unsigned w, unsigned h, char *d) +{ +asm volatile ("int $0x40"::"a"(7), "c"(w*65536+h), "d"(x*65536+y), "b"(d)); +} + + +void kol_paint_image_pal(unsigned x, unsigned y, unsigned w, unsigned h, char *d, unsigned *palette) +{ +asm volatile ("int $0x40"::"a"(65), "b"(d), "c"(w*65536+h), "d"(x*65536+y), "D"(palette), "S"(8)); +} + + +unsigned kol_key_get() +{ +asm volatile ("int $0x40"::"a"(2)); +} + + +unsigned kol_key_control() +{ +asm volatile ("int $0x40"::"a"(66), "b"(3)); +} + + +void kol_key_lang_set(unsigned lang) +{ +asm volatile ("int $0x40"::"a"(21), "b"(2), "c"(9), "d"(lang)); +} + + +unsigned kol_key_lang_get() +{ +asm volatile ("int $0x40"::"a"(26), "b"(2), "c"(9)); +} + + +void kol_key_mode_set(unsigned mode) +{ +asm volatile ("int $0x40"::"a"(66), "b"(1), "c"(mode)); +} + + +unsigned kol_key_mode_get() +{ +asm volatile ("int $0x40"::"a"(66), "b"(2)); +} + + +unsigned kol_btn_get() +{ +asm volatile ("int $0x40"::"a"(17)); +} + + +void kol_btn_define(unsigned x, unsigned y, unsigned w, unsigned h, unsigned d, unsigned c) +{ +asm volatile ("int $0x40"::"a"(8), "b"(x*65536+w), "c"(y*65536+h), "d"(d), "S"(c)); +} + + +void kol_btn_type(unsigned t) +{ +asm volatile ("int $0x40"::"a"(48), "b"(1), "c"(t)); +} + + +void kol_wnd_caption(char *s) +{ +asm volatile ("int $0x40"::"a"(71), "b"(1), "c"(s)); +} + + +unsigned kol_mouse_pos() +{ +asm volatile ("int $0x40"::"a"(37), "b"(0)); +} + + +unsigned kol_mouse_posw() +{ +asm volatile ("int $0x40"::"a"(37), "b"(1)); +} + + +unsigned kol_mouse_btn() +{ +asm volatile ("int $0x40"::"a"(37), "b"(2)); +} + + +void kol_board_putc(char c) +{ +asm volatile ("int $0x40"::"a"(63), "b"(1), "c"(c)); +} + + +void kol_board_puts(char *s) +{ +unsigned i; +i = 0; +while (*(s+i)) + { + asm volatile ("int $0x40"::"a"(63), "b"(1), "c"(*(s+i))); + i++; + } +} + + +void kol_board_puti(int n) +{ +char c; + +if ( n > 1 ) + kol_board_puti(n / 10); + +c = n % 10 + '0'; +asm volatile ("int $0x40"::"a"(63), "b"(1), "c"(c)); + +} + + +int kol_file_70(kol_struct70 *k) +{ +asm volatile ("int $0x40"::"a"(70), "b"(k)); +} + + +kol_struct_import* kol_cofflib_load(char *name) +{ +asm volatile ("int $0x40"::"a"(68), "b"(19), "c"(name)); +} + +/* +void* kol_cofflib_procload (kol_struct_import *imp, char *name) +{ +int i; +for (i=0;;i++) + if ( NULL == ((imp+i) -> name)) + break; + else + if ( 0 == strcmp(name, (imp+i)->name) ) + return (imp+i)->data; +return NULL; +} +*/ + +unsigned kol_cofflib_procnum (kol_struct_import *imp) +{ +unsigned i, n; + +for (i=n=0;;i++) + if ( NULL == ((imp+i) -> name)) + break; + else + n++; + +return n; +} + +/* +void kol_cofflib_procname (kol_struct_import *imp, char *name, unsigned n) +{ +unsigned i; +*name = 0; + +for (i=0;;i++) + if ( NULL == ((imp+i) -> name)) + break; + else + if ( i == n ) + { + strcpy(name, ((imp+i)->name)); + break; + } + +} +*/ + + +unsigned kol_system_cpufreq() +{ +asm volatile ("int $0x40"::"a"(18), "b"(5)); +} + + +unsigned kol_system_mem() +{ +asm volatile ("int $0x40"::"a"(18), "b"(17)); +} + + +unsigned kol_system_memfree() +{ +asm volatile ("int $0x40"::"a"(18), "b"(16)); +} + + +unsigned kol_system_time_get() +{ +asm volatile ("int $0x40"::"a"(3)); +} + + +unsigned kol_system_date_get() +{ +asm volatile ("int $0x40"::"a"(29)); +} + + +unsigned kol_system_end(unsigned param) +{ +asm volatile ("int $0x40"::"a"(18), "b"(9), "c"(param)); +} + + +/* +void kol_path_file2dir(char *dir, char *fname) +{ +unsigned i; +strcpy (dir, fname); +for ( i = strlen(dir);; --i) + if ( '/' == dir[i]) + { + dir[i] = '\0'; + return; + } +} + + +void kol_path_full(char *full, char *fname) +{ +char temp[256]; + +switch (*fname) + { + + case '/': + strncpy(temp, fname+1, 2); + temp[2]=0; + if ( (!strcmp("rd", temp)) || (!strcmp("hd", temp)) || (!strcmp("cd", temp)) ) + strcpy (full, fname); + break; + + case '.': + break; + + default: + break; + + }; + +} +*/ + + +void __attribute__((__always_inline__)) inline kol_screen_wait_rr() +{ +asm volatile ("int $0x40"::"a"(18), "b"(14)); +} + + + +void kol_screen_get_size(unsigned *w, unsigned *h) +{ +unsigned size; +asm volatile ("int $0x40":"=a"(size):"a"(14)); +*w = size / 65536; +*h = size % 65536; +} + + + +unsigned kol_skin_height() +{ +asm volatile ("int $0x40"::"a"(48), "b"(4)); +} + + +unsigned kol_thread_start(unsigned start, unsigned stack) +{ +asm volatile ("int $0x40"::"a"(51), "b"(1), "c"(start), "d"(stack)); +} + + +unsigned kol_time_tick() +{ +asm volatile ("int $0x40"::"a"(26), "b"(9)); +} + + +unsigned kol_sound_speaker(char data[]) +{ +asm volatile ("movl %0, %%esi"::"a"(data)); +asm volatile ("int $0x40"::"a"(55), "b"(55)); +} + + +unsigned kol_process_info(unsigned slot, char buf1k[]) +{ +asm volatile ("int $0x40"::"a"(9), "b"(buf1k), "c"(slot)); +} + + +int kol_process_kill_pid(unsigned process) +{ +asm volatile ("int $0x40"::"a"(18), "b"(18), "c"(process)); +} + +int kol_kill_process(unsigned process) +{ +asm volatile ("int $0x40"::"a"(18), "b"(2), "c"(process)); +} + +void kol_get_kernel_ver(char buff16b[]) +{ +asm volatile ("int $0x40"::"a"(18), "b"(13), "c"(buff16b)); +} + +int kol_buffer_open(char name[], int mode, int size, char **buf) +{ +int error; +asm volatile ("int $0x40":"=a"(*buf), "=d"(error):"a"(68), "b"(22), "c"(name), "d"(size), "S"(mode)); +return error; +} + +void kol_buffer_close(char name[]) +{ +asm volatile ("int $0x40"::"a"(68), "b"(23), "c"(name)); +} + +int kol_clip_num() +{ +asm volatile ("int $0x40"::"a"(54), "b"(0)); +} + +char* kol_clip_get(int n) +{ +asm volatile ("int $0x40"::"a"(54), "b"(1), "c"(n)); +} + +int kol_clip_set(int n, char buffer[]) +{ +asm volatile ("int $0x40"::"a"(54), "b"(2), "c"(n), "d"(buffer)); +} diff --git a/programs/games/heliothryx/system/kolibri.h b/programs/games/heliothryx/system/kolibri.h new file mode 100644 index 0000000000..a3069834e4 --- /dev/null +++ b/programs/games/heliothryx/system/kolibri.h @@ -0,0 +1,116 @@ + +#define NULL ((void*)0) + +#define SHM_OPEN 0 +#define SHM_OPEN_ALWAYS 0x04 +#define SHM_CREATE 0x08 +#define SHM_READ 0x00 +#define SHM_WRITE 0x01 + +#define E_NOTFOUND 5 +#define E_ACCESS 10 +#define E_NOMEM 30 +#define E_PARAM 33 + + +#pragma pack(push,1) +typedef struct +{ +unsigned p00; +unsigned p04; +unsigned p08; +unsigned p12; +unsigned p16; +char p20; +char *p21; +} kol_struct70; +#pragma pack(pop) + + +#pragma pack(push,1) +typedef struct +{ +unsigned p00; +char p04; +char p05[3]; +unsigned p08; +unsigned p12; +unsigned p16; +unsigned p20; +unsigned p24; +unsigned p28; +unsigned p32[2]; +unsigned p40; +} kol_struct_BDVK; +#pragma pack(pop) + + +#pragma pack(push,1) +typedef struct +{ +char *name; +void *data; +} kol_struct_import; +#pragma pack(pop) + + +void kol_exit(); +void kol_sleep(unsigned d); +void kol_wnd_define(unsigned x, unsigned y, unsigned w, unsigned h, unsigned cs, unsigned b, char *t); +void kol_wnd_move(unsigned x, unsigned y); +void kol_wnd_caption(char *s); +void kol_event_mask(unsigned e); +unsigned kol_event_wait(); +unsigned kol_event_wait_time(unsigned time); +unsigned kol_event_check(); +void kol_paint_start(); +void kol_paint_end(); +void kol_paint_pixel(unsigned x, unsigned y, unsigned c); +void kol_paint_bar(unsigned x, unsigned y, unsigned w, unsigned h, unsigned c); +void kol_paint_line(unsigned x1, unsigned y1, unsigned x2, unsigned y2, unsigned c); +void kol_paint_string(unsigned x, unsigned y, char *s, unsigned c); +void kol_paint_image(unsigned x, unsigned y, unsigned w, unsigned h, char *d); +void kol_paint_image_pal(unsigned x, unsigned y, unsigned w, unsigned h, char *d, unsigned *palette); +unsigned kol_key_get(); +unsigned kol_key_control(); +void kol_key_lang_set(unsigned lang); +unsigned kol_key_lang_get(); +void kol_key_mode_set(unsigned mode); +unsigned kol_key_mode_get(); +void kol_btn_define(unsigned x, unsigned y, unsigned w, unsigned h, unsigned d, unsigned c); +unsigned kol_btn_get(); +void kol_btn_type(unsigned t); +unsigned kol_mouse_pos(); +unsigned kol_mouse_posw(); +unsigned kol_mouse_btn(); +void kol_board_putc(char c); +void kol_board_puts(char *s); +void kol_board_puti(int n); +int kol_file_70(kol_struct70 *k); +kol_struct_import* kol_cofflib_load(char *name); +void* kol_cofflib_procload (kol_struct_import *imp, char *name); +unsigned kol_cofflib_procnum (kol_struct_import *imp); +void kol_cofflib_procname (kol_struct_import *imp, char *name, unsigned n); +unsigned kol_system_end(unsigned param); +unsigned kol_system_cpufreq(); +unsigned kol_system_mem(); +unsigned kol_system_memfree(); +unsigned kol_system_time_get(); +unsigned kol_system_date_get(); +void kol_path_file2dir(char *dir, char *fname); +void kol_path_full(char *full, char *fname); +void kol_screen_wait_rr(); +void kol_screen_get_size(unsigned *w, unsigned *h); +unsigned kol_skin_height(); +unsigned kol_thread_start(unsigned start, unsigned stack); +unsigned kol_time_tick(); +unsigned kol_sound_speaker(char data[]); +unsigned kol_process_info(unsigned slot, char buf1k[]); +int kol_process_kill_pid(unsigned process); +void kol_get_kernel_ver(char buff16b[]); +int kol_kill_process(unsigned process); +int kol_buffer_open(char name[], int mode, int size, char **buf); +void kol_buffer_close(char name[]); +int kol_clip_num(); +char* kol_clip_get(int n); +int kol_clip_set(int n, char buffer[]); diff --git a/programs/games/heliothryx/system/sound.h b/programs/games/heliothryx/system/sound.h new file mode 100644 index 0000000000..430c210e36 --- /dev/null +++ b/programs/games/heliothryx/system/sound.h @@ -0,0 +1,133 @@ + +#ifndef _SOUND_H_ +#define _SOUND_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define SOUND_VERSION 0x0100 +#define PCM_ALL 0 + +#define PCM_OUT 0x08000000 +#define PCM_RING 0x10000000 +#define PCM_STATIC 0x20000000 +#define PCM_FLOAT 0x40000000 +#define PCM_FILTER 0x80000000 + +#define PCM_2_16_48 1 +#define PCM_1_16_48 2 +#define PCM_2_16_44 3 +#define PCM_1_16_44 4 +#define PCM_2_16_32 5 +#define PCM_1_16_32 6 +#define PCM_2_16_24 7 +#define PCM_1_16_24 8 +#define PCM_2_16_22 9 +#define PCM_1_16_22 10 +#define PCM_2_16_16 11 +#define PCM_1_16_16 12 +#define PCM_2_16_12 13 +#define PCM_1_16_12 14 +#define PCM_2_16_11 15 +#define PCM_1_16_11 16 +#define PCM_2_16_8 17 +#define PCM_1_16_8 18 +#define PCM_2_8_48 19 +#define PCM_1_8_48 20 +#define PCM_2_8_44 21 +#define PCM_1_8_44 22 +#define PCM_2_8_32 23 +#define PCM_1_8_32 24 +#define PCM_2_8_24 25 +#define PCM_1_8_24 26 +#define PCM_2_8_22 27 +#define PCM_1_8_22 28 +#define PCM_2_8_16 29 +#define PCM_1_8_16 30 +#define PCM_2_8_12 31 +#define PCM_1_8_12 32 +#define PCM_2_8_11 33 +#define PCM_1_8_11 34 +#define PCM_2_8_8 35 +#define PCM_1_8_8 36 + +#define SRV_GETVERSION 0 +#define SND_CREATE_BUFF 1 +#define SND_DESTROY_BUFF 2 +#define SND_SETFORMAT 3 +#define SND_GETFORMAT 4 +#define SND_RESET 5 +#define SND_SETPOS 6 +#define SND_GETPOS 7 +#define SND_SETBUFF 8 +#define SND_OUT 9 +#define SND_PLAY 10 +#define SND_STOP 11 +#define SND_SETVOLUME 12 +#define SND_GETVOLUME 13 +#define SND_SETPAN 14 +#define SND_GETPAN 15 +#define SND_GETBUFFSIZE 16 + +#define PLAY_SYNC 0x80000000 + +typedef unsigned int SNDBUF; + +int _stdcall InitSound(int *version); + +int _stdcall CreateBuffer(unsigned int format,int size,SNDBUF *buf); +int _stdcall DestroyBuffer(SNDBUF hBuff); + +int _stdcall SetFormat(SNDBUF hBuff, unsigned int format); +int _stdcall GetFormat(SNDBUF hBuff, unsigned int *format); + +int _stdcall ResetBuffer(SNDBUF hBuff, unsigned int flags); +int _stdcall SetBufferPos(SNDBUF hBuff, int offset); +int _stdcall GetBufferPos(SNDBUF hBuff, int *offset); +int _stdcall GetBufferSize(SNDBUF hBuff, int *size); + +int _stdcall SetBuffer(SNDBUF hBuff,void* buff, + int offs, int size); +int _stdcall WaveOut(SNDBUF hBuff,void *buff, int size); +int _stdcall PlayBuffer(SNDBUF hBuff,unsigned int flags); +int _stdcall StopBuffer(SNDBUF hBuff); + +int _stdcall SetVolume(SNDBUF hBuff, int left, int right); +int _stdcall GetVolume(SNDBUF hBuff, int *left, int *right); +int _stdcall SetPan(SNDBUF hBuff, int pan); +int _stdcall GetPan(SNDBUF hBuff, int *pan); + +int _stdcall GetMasterVol(int* vol); +int _stdcall SetMasterVol(int vol); + + +typedef struct +{ + unsigned int riff_id; + unsigned int riff_size; + unsigned int riff_format; + + unsigned int fmt_id; + unsigned int fmt_size; + + unsigned short int wFormatTag; + unsigned short int nChannels; + unsigned int nSamplesPerSec; + unsigned int nAvgBytesPerSec; + unsigned short int nBlockAlign; + unsigned short int wBitsPerSample; + unsigned int data_id; + unsigned int data_size; +} WAVEHEADER; + + +unsigned int _stdcall test_wav(WAVEHEADER *hdr); + +#ifdef __cplusplus +extern "C" +} +#endif + +#endif //_SOUND_H_