Update for Heliothryx game:

- added localization tool

Updates for Marble Match-3 game:
- added localization support
- some cosmetic changes



git-svn-id: svn://kolibrios.org@5243 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
alpine 2014-12-19 17:29:02 +00:00
parent ba5bb1ced2
commit 2815962839
29 changed files with 661 additions and 348 deletions

View File

@ -1,8 +1,21 @@
if tup.getconfig("NO_FASM") ~= "" or tup.getconfig("NO_GCC") ~= "" then return end if tup.getconfig("NO_FASM") ~= "" or tup.getconfig("NO_GCC") ~= "" then return end
-- tup.rule("echo \"#define LANG_" .. ((tup.getconfig("LANG") == "") and "en" or tup.getconfig("LANG")) .. "\" > lang.h", {"lang.h"})
HELPERDIR = (tup.getconfig("HELPERDIR") == "") and "../.." or tup.getconfig("HELPERDIR") HELPERDIR = (tup.getconfig("HELPERDIR") == "") and "../.." or tup.getconfig("HELPERDIR")
tup.include(HELPERDIR .. "/use_gcc.lua") tup.include(HELPERDIR .. "/use_gcc.lua")
tup.include(HELPERDIR .. "/use_sound.lua") tup.include(HELPERDIR .. "/use_sound.lua")
LDFLAGS = LDFLAGS .. " -T kolibri.ld" LDFLAGS = LDFLAGS .. " -T kolibri.ld"
tup.append_table(OBJS, tup.rule("start.asm", "fasm %f %o", "start.o")) 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("heliothryx") if tup.getconfig("LANG") == "ru"
then C_LANG = "LANG_RU"
elseif tup.getconfig("LANG") == "sp"
then C_LANG = "LANG_SP" -- just for example, other languages are not implemented
else C_LANG = "LANG_EN" -- default language is English
end
CFLAGS = CFLAGS .. " -DRS_KOS -D" .. C_LANG .. " "
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/rsgame.c", "game/rsgamedraw.c", "game/rskos.c", "game/rsgametext.c", "game/rsgamemenu.c"}
link_gcc ("heliothryx")

View File

@ -170,5 +170,24 @@ void* memcpy(void *dst, const void *src, unsigned size)
} }
char* strchr(char* s, int c) {
while (*s) {
if (*s == (char) c) {
return s;
};
s++;
};
return NULL;
};
unsigned int strlen ( char * str ) {
unsigned int len = 0;
while ( *str ) {
len++;
str++;
};
return len;
};

View File

@ -50,4 +50,7 @@ void free(void* pointer);
void* memset(void *mem, int c, unsigned size); void* memset(void *mem, int c, unsigned size);
void* memcpy(void *dst, const void *src, unsigned size); void* memcpy(void *dst, const void *src, unsigned size);
char* strchr(char* s, int c);
unsigned int strlen ( char * str );
#endif #endif

View File

@ -40,43 +40,52 @@
#define RS_KEY_X 45 #define RS_KEY_X 45
unsigned int get_time();
typedef void RSFUNC0(); typedef void RSFUNC0();
typedef void RSFUNC1i(int); /*typedef void RSFUNC1i(int);
typedef void RSFUNC2i(int,int); typedef void RSFUNC2i(int,int);
typedef void RSFUNC1i1f(int,float); typedef void RSFUNC1i1f(int,float); */
typedef RSFUNC0 *PRSFUNC0; typedef RSFUNC0 *PRSFUNC0;
typedef RSFUNC1i *PRSFUNC1i; /*typedef RSFUNC1i *PRSFUNC1i;
typedef RSFUNC2i *PRSFUNC2i; typedef RSFUNC2i *PRSFUNC2i;
typedef RSFUNC1i1f *PRSFUNC1i1f; typedef RSFUNC1i1f *PRSFUNC1i1f;*/
/*
void NullFunc0(); void NullFunc0();
void NullFunc1i(int i); void NullFunc1i(int i);
void NullFunc2i(int i, int j); void NullFunc2i(int i, int j);
void NullFunc1i1f(int i, float f); void NullFunc1i1f(int i, float f);
*/
typedef struct rs_app_t { typedef struct rs_app_t {
unsigned short app_time; unsigned short app_time;
unsigned short delta_time; unsigned short delta_time;
PRSFUNC2i OnSize; /*
PRSFUNC2i OnKeyDown; PRSFUNC2i OnKeyDown;
PRSFUNC1i OnKeyUp; PRSFUNC1i OnKeyUp;
PRSFUNC2i OnMouseDown;
PRSFUNC2i OnMouseUp;
PRSFUNC0 OnAppProcess; PRSFUNC0 OnAppProcess;
PRSFUNC0 rsAppOnInitDisplay; PRSFUNC0 rsAppOnInitDisplay;
PRSFUNC0 rsAppOnTermDisplay; PRSFUNC0 rsAppOnTermDisplay;
*/
} rs_app_t; } rs_app_t;
extern rs_app_t rs_app; extern rs_app_t rs_app;
void rsAppZero(); //void rsAppZero();

View File

@ -1,101 +1,101 @@
#include "rsplatform.h" #include "rsplatform.h"
rs_app_t rs_app; rs_app_t rs_app;
// set this macro to zero (0) if bug is fixed // set this macro to zero (0) if bug is fixed
#define FIX_MENUETOS_LEGACY_ONE_PIXEL_BORDER_GAP_BUG (-1) #define FIX_MENUETOS_LEGACY_ONE_PIXEL_BORDER_GAP_BUG (-1)
// Fixed frame rate, set to 25 // Fixed frame rate, set to 25
#define GAME_REQUIRED_FPS 25 #define GAME_REQUIRED_FPS 25
//extern char PATH[256]; //extern char PATH[256];
//extern char PARAM[256]; //extern char PARAM[256];
int window_width, window_height; int window_width, window_height;
int fps = 0; int fps = 0;
int dt = 1; int dt = 1;
int draw_dt = 1; int draw_dt = 1;
int area_width = 160; int area_width = 160;
int area_height = 160; int area_height = 160;
int w_plus = 0; int w_plus = 0;
#define BIT_SET(var,mask) { var |= (mask); } #define BIT_SET(var,mask) { var |= (mask); }
#define BIT_CLEAR(var,mask) { var &= ~(mask); } #define BIT_CLEAR(var,mask) { var &= ~(mask); }
#define BIT_TOGGLE(var,mask) { var ^= (mask); } #define BIT_TOGGLE(var,mask) { var ^= (mask); }
#define IS_BIT_SET(var,mask) ( (var) & (mask) ) #define IS_BIT_SET(var,mask) ( (var) & (mask) )
#define IS_BIT_CLEARED(var,mask) (!( (var) & (mask) )) #define IS_BIT_CLEARED(var,mask) (!( (var) & (mask) ))
void BoardPuts(const char *s) void BoardPuts(const char *s)
{ {
unsigned int i = 0; unsigned int i = 0;
while(*(s + i)) while(*(s + i))
{ {
asm volatile ("int $0x40"::"a"(63), "b"(1), "c"(*(s + i))); asm volatile ("int $0x40"::"a"(63), "b"(1), "c"(*(s + i)));
i++; i++;
} }
} }
void board_write_integer(const char *s, int i) { void board_write_integer(const char *s, int i) {
char tmp[16]; char tmp[16];
}; };
void kol_wnd_resize(unsigned w, unsigned h) void kol_wnd_resize(unsigned w, unsigned h)
{ {
asm volatile ("int $0x40"::"a"(67), "b"(-1), "c"(-1), "d"(w), "S"(h)); asm volatile ("int $0x40"::"a"(67), "b"(-1), "c"(-1), "d"(w), "S"(h));
} }
void wnd_draw() void wnd_draw()
{ {
char tmp[] = "Fps:000 | Heliothryx Beta by Roman Shuvalov"; char tmp[] = "Fps:000 | Heliothryx Beta by Roman Shuvalov";
kol_paint_start(); kol_paint_start();
tmp[4] = '0' + ( (fps/100) % 10 ); tmp[4] = '0' + ( (fps/100) % 10 );
tmp[5] = '0' + ( (fps/10) % 10 ); tmp[5] = '0' + ( (fps/10) % 10 );
tmp[6] = '0' + ( (fps) % 10 ); tmp[6] = '0' + ( (fps) % 10 );
kol_wnd_define(100, 100, window_width, window_height, 0x74ddddff, 0x34ddddff, "HELLO WINDOW"); kol_wnd_define(100, 100, window_width, window_height, 0x74ddddff, 0x34ddddff, "HELLO WINDOW");
kol_wnd_caption(tmp); kol_wnd_caption(tmp);
GameProcess(); GameProcess();
kol_paint_end(); kol_paint_end();
} }
/// =========================================================== /// ===========================================================
void kol_main() void kol_main()
{ {
BoardPuts("Hello, Heliothryx!\n"); BoardPuts("Hello, Heliothryx!\n");
int err; int err;
int version =-1; int version =-1;
if((err = InitSound(&version)) !=0 ){ if((err = InitSound(&version)) !=0 ){
@ -106,139 +106,137 @@ void kol_main()
(SOUND_VERSION<(version >> 16))){ (SOUND_VERSION<(version >> 16))){
BoardPuts("Sound Error 2\n"); BoardPuts("Sound Error 2\n");
} }
unsigned event; unsigned event;
unsigned key; unsigned key;
unsigned key_up; unsigned key_up;
unsigned btn; unsigned btn;
unsigned pos, x, y; unsigned pos, x, y;
int gx, gy; int gx, gy;
//srand(kol_system_time_get()); //srand(kol_system_time_get());
// kol_event_mask( 0xC0000027 ); // enable using of mouse // kol_event_mask( 0xC0000027 ); // enable using of mouse
kol_event_mask(7); // keyboard only kol_event_mask(7); // keyboard only
kol_key_mode_set(1); kol_key_mode_set(1);
area_width = 640; area_width = 640;
area_height = 360; area_height = 360;
// Initializing variables // Initializing variables
window_width = FIX_MENUETOS_LEGACY_ONE_PIXEL_BORDER_GAP_BUG + area_width + 10; // 2 x 5px border 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 window_height = FIX_MENUETOS_LEGACY_ONE_PIXEL_BORDER_GAP_BUG + kol_skin_height() + area_height + 5; // bottom 5px border
GameInit(); GameInit();
wnd_draw(); wnd_draw();
fps = 0; fps = 0;
unsigned int tick_start = kol_time_tick(); unsigned int tick_start = kol_time_tick();
unsigned int tick_current = tick_start; unsigned int tick_current = tick_start;
unsigned int tick_last = tick_start; unsigned int tick_last = tick_start;
unsigned int fps_counter = 0; unsigned int fps_counter = 0;
int wait_time; int wait_time;
int already_drawn = 0; int already_drawn = 0;
float xf; float xf;
float xfs; float xfs;
int xfs_i; int xfs_i;
while (1) { while (1) {
tick_last = tick_current; tick_last = tick_current;
tick_current = kol_time_tick(); tick_current = kol_time_tick();
dt = tick_current - tick_last; dt = tick_current - tick_last;
tick_last = tick_current; tick_last = tick_current;
already_drawn = 0; already_drawn = 0;
while (( event = kol_event_wait_time(1) )) { while (( event = kol_event_wait_time(1) )) {
switch (event) { switch (event) {
case 1: case 1:
wnd_draw(); // <--- need to clear event! wnd_draw(); // <--- need to clear event!
already_drawn = 1; already_drawn = 1;
break; break;
case 2: case 2:
key = kol_key_get(); key = kol_key_get();
key = (key & 0xff00)>>8; key = (key & 0xff00)>>8;
key_up = key & 0x80; key_up = key & 0x80;
key = key & 0x7F; key = key & 0x7F;
if (key_up) { if (key_up) {
GameKeyUp(key, 1); GameKeyUp(key, 1);
} }
else { else {
GameKeyDown(key); GameKeyDown(key);
}; };
break; break;
case 3: case 3:
switch ((kol_btn_get() & 0xff00)>>8) switch ((kol_btn_get() & 0xff00)>>8)
{ {
case 1: // close button case 1: // close button
kol_exit(); kol_exit();
case 2: // 'new' button case 2: // 'new' button
//init_board(); //init_board();
//wnd_draw(); //wnd_draw();
break; break;
} }
break; break;
case 6: case 6:
btn = kol_mouse_btn(); // read mouse button btn = kol_mouse_btn(); // read mouse button
pos = kol_mouse_posw(); // read mouse position pos = kol_mouse_posw(); // read mouse position
x = pos / 65536; x = pos / 65536;
y = pos % 65536; y = pos % 65536;
if (x > window_width) if (x > window_width)
x=0; x=0;
if (y > window_height) if (y > window_height)
y=0; y=0;
break; break;
} }
}; };
if (!already_drawn) { if (!already_drawn) {
wnd_draw(); wnd_draw();
}; };
fps_counter++; fps_counter++;
tick_current = kol_time_tick(); tick_current = kol_time_tick();
if (tick_current > tick_start+100) { if (tick_current > tick_start+100) {
fps = fps_counter; fps = fps_counter;
fps_counter = 0; fps_counter = 0;
tick_start += 100; tick_start += 100;
}; };
draw_dt = tick_current - tick_last; draw_dt = tick_current - tick_last;
wait_time = (100/GAME_REQUIRED_FPS) - draw_dt; wait_time = (100/GAME_REQUIRED_FPS) - draw_dt;
if (wait_time <= 0) { if (wait_time <= 0) {
wait_time = 1; wait_time = 1;
}; };
kol_sleep(wait_time); kol_sleep(wait_time);
} }
GameTerm(); GameTerm();
kol_exit(); kol_exit();
} }

View File

@ -24,6 +24,7 @@
#endif #endif
rs_game_t game; rs_game_t game;
@ -162,6 +163,24 @@ void soundbuf_sin_fade(rs_soundbuf_t *snd, float freq) {
for (i = 0; i < snd->length_samples; i++) { 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; snd->data[i] = ( 1.0 - 1.0*i/snd->length_samples ) * sin( ( (1.0 - 0.48*i/snd->length_samples) * freq ) *i) * amp;
}; };
/*
// ok
rs_sgen_init(2, snd->length_samples);
rs_sgen_func_pm(1, 880.0, 21.0, 0.3, 110.0, 0.3);
rs_sgen_func_normalize(1, 1.0);
rs_sgen_func_lowpass(0, 1, 1.0, 0.0, 1.0);
rs_sgen_wave_out(0);
memcpy(snd->data, rs_sgen_reg.wave_out, snd->length_samples*2 );
rs_sgen_term();
*/
rskos_snd_update_buffer(&snd->hbuf, snd->data, snd->length_samples); rskos_snd_update_buffer(&snd->hbuf, snd->data, snd->length_samples);
}; };
@ -196,9 +215,9 @@ void game_reg_init() {
game.status = STATUS_MENU; game.status = STATUS_MENU;
game.window_scale = 2; game.window_scale = 2;
#ifdef RS_LINUX #ifndef RS_KOS
game.window_scale = 3; game.window_scale = 3;
window_scale_str[3] = '3'; window_scale_str[3] = '3';
#endif #endif
game.keyboard_state = 0; game.keyboard_state = 0;
@ -421,7 +440,7 @@ void GameInit() {
rs_gen_term(); rs_gen_term();
#ifdef RS_LINUX #ifndef RS_KOS
rs_audio_init(RS_AUDIO_FMT_MONO16, RS_AUDIO_FREQ_16000, 0); rs_audio_init(RS_AUDIO_FMT_MONO16, RS_AUDIO_FREQ_16000, 0);
#endif #endif
@ -446,7 +465,7 @@ void GameTerm() {
DEBUG10("--- Game Term ---"); DEBUG10("--- Game Term ---");
#ifdef RS_LINUX #ifndef RS_KOS
rs_audio_term(); rs_audio_term();
#endif #endif
@ -511,6 +530,7 @@ void GameKeyDown(int key, int first) {
if ( (game.menu_index == MENU_SETTINGS) && (game.menu_item_index == MENU_ITEM_WINDOW_SCALE) ) { if ( (game.menu_index == MENU_SETTINGS) && (game.menu_item_index == MENU_ITEM_WINDOW_SCALE) ) {
game_change_window_scale(-1); game_change_window_scale(-1);
game_ding(1);
}; };
//PlayBuffer(hBuff, 0); //PlayBuffer(hBuff, 0);
@ -520,6 +540,7 @@ void GameKeyDown(int key, int first) {
if ( (game.menu_index == MENU_SETTINGS) && (game.menu_item_index == MENU_ITEM_WINDOW_SCALE) ) { if ( (game.menu_index == MENU_SETTINGS) && (game.menu_item_index == MENU_ITEM_WINDOW_SCALE) ) {
game_change_window_scale(1); game_change_window_scale(1);
game_ding(1);
}; };
//StopBuffer(hBuff); //StopBuffer(hBuff);
@ -591,6 +612,16 @@ void GameKeyUp(int key) {
}; };
void GameMouseDown(int x, int y) {
game.tx = x;
game.ty = y;
DEBUG10f("Mouse Down %d, %d \n", x, y);
};
void GameMouseUp(int x, int y) {
//
};
void game_change_window_scale(int d) { void game_change_window_scale(int d) {
int scale = window_scale_str[3] - '0'; int scale = window_scale_str[3] - '0';
@ -621,6 +652,9 @@ void game_change_window_scale(int d) {
rskos_resize_window( GAME_WIDTH * scale, GAME_HEIGHT * scale ); rskos_resize_window( GAME_WIDTH * scale, GAME_HEIGHT * scale );
window_scale_str[3] = scale + '0'; window_scale_str[3] = scale + '0';
}; };
void game_ding(int i) { void game_ding(int i) {

View File

@ -8,6 +8,14 @@
*/ */
#ifndef RS_LINUX
#ifndef RS_WIN32
#ifndef RS_KOS
#error Please specify platform
#endif
#endif
#endif
#include "rskos.h" #include "rskos.h"
#include "rs/rsplatform.h" #include "rs/rsplatform.h"
@ -182,6 +190,9 @@ void GameTerm();
void GameKeyDown(int key, int first); void GameKeyDown(int key, int first);
void GameKeyUp(int key); void GameKeyUp(int key);
void GameMouseDown(int x, int y);
void GameMouseUp(int x, int y);
void game_change_window_scale(int d); void game_change_window_scale(int d);
#endif // RSGAME_H_INCLUDED #endif // RSGAME_H_INCLUDED

View File

@ -6,7 +6,7 @@
#include "rsnoise.h" #include "rsnoise.h"
#include "strings.h"
void game_draw() { void game_draw() {
@ -76,9 +76,9 @@ void game_draw() {
texture_draw(&game.framebuffer, &game.tex_rocks[i], 250+80*rs_noise(i,150), 60+60*rs_noise(i,1110), DRAW_MODE_ADDITIVE ); 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 - 100, 40, 1, "HELI0THRYX");
game_textout( GAME_WIDTH/2 - 8, 58, 3, "TECHDEMO"); game_textout( GAME_WIDTH/2 - 8, 58, 3, "TECHDEM0");
game_textout( 2, GAME_HEIGHT-10, 2, "DEVELOPER: ROMAN SHUVALOV` TOGLIATTI_ 2014"); game_textout( 2, GAME_HEIGHT-10, 2, L_BOTTOM_LINE_DEVELOPER_INFO);
}; };
} }
@ -100,8 +100,8 @@ void game_draw() {
}; };
}; };
game_textout( 2, 2, 2, "THIS IS TECHDEMO` "); game_textout( 2, 2, 2, L_TECHDEMO_LINE1 );
game_textout( 2, 12, 2, "USE ARROWS TO MOVE_ <A> TO SHOOT_ <ESC> TO EXIT` "); game_textout( 2, 12, 2, L_TECHDEMO_LINE2 );
}; };

View File

@ -4,6 +4,8 @@
#include "rskos.h" #include "rskos.h"
#include "strings.h"
PRSFUNC0 menu_actions[] = { PRSFUNC0 menu_actions[] = {
/* a */ &menu_action_start, /* a */ &menu_action_start,
/* b */ &menu_action_exit, /* b */ &menu_action_exit,
@ -12,27 +14,38 @@ PRSFUNC0 menu_actions[] = {
char window_scale_str[] = "c< 2X >"; char window_scale_str[] = "c< 2X >";
/*
First char:
- letter a...z means action (a = 0th, b = 1st, c = 2nd, see menu_actions[] above)
- number 0...9 means goto menu #0, #1, #2... see menu_titles[] below
- space ' ' means no action, menu item is unselectable
- empty string "" is now allowed and can cause segfault
String from second char is label of menu item
*/
char* menu_main_titles[] = { char* menu_main_titles[] = {
"a5TART", "a"L_START,
"15ETTING5", "1"L_SETTINGS,
"2ABOUT", "2"L_ABOUT,
"bQUIT", "b"L_QUIT,
0 0
}; };
char* menu_settings_titles[] = { char* menu_settings_titles[] = {
" WINDOW SCALE:", " "L_WINDOW_SCALE,
window_scale_str, window_scale_str,
" ", " ",
"0DONE", "0"L_DONE,
0 0
}; };
char* menu_about_titles[] = { char* menu_about_titles[] = {
" DEVELOPED BY", " "L_DEVELOPED_BY,
" ROMAN SHUVALOV", " "L_ROMAN_SHUVALOV,
" ", " ",
"0DONE", "0"L_DONE,
0 0
}; };
@ -113,7 +126,7 @@ void menu_action_start() {
}; };
void menu_action_exit() { void menu_action_exit() {
#ifndef RS_LINUX #ifdef RS_KOS
GameTerm(); GameTerm();
#endif #endif
rskos_exit(); rskos_exit();

View File

@ -217,7 +217,7 @@ signed short pp_seg[32*8] = {
11, 25, 11, 25,
6, 0, 6, 0,
// 31 not implemented // 31 not implemented - need to create up-left DOT for percent(%) sign
16, 26-16, 16, 26-16,
16, 26+16, 16, 26+16,
16, 26, 16, 26,
@ -226,8 +226,8 @@ signed short pp_seg[32*8] = {
}; };
uint32_t ch_seg[64] = { unsigned int ch_seg[64] = {
0b00111111, // // for cross-line in O | 1<<12 | 1<<19, // 0 0b00111111 /* | 1<<12 | 1<<19 */, // 0 or O
1<<26 | 1<<8 | 1<<9 | 1<<3, // 1 1<<26 | 1<<8 | 1<<9 | 1<<3, // 1
0b01011011, // 2 0b01011011, // 2
1<<0 | 1<<12 | 1<<15 | 1<<2 | 1<<3, // 3 1<<0 | 1<<12 | 1<<15 | 1<<2 | 1<<3, // 3
@ -261,12 +261,12 @@ uint32_t ch_seg[64] = {
1<<5 | 1<<4 | 1<<3, // L 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<<1 | 1<<2 | 1<<16 | 1<<12, // M
1<<5 | 1<<4 | 1<<16 | 1<<11 | 1<<1 | 1<<2, // N 1<<5 | 1<<4 | 1<<16 | 1<<11 | 1<<1 | 1<<2, // N
0b00111111, // O 1<<16 | 1<<11 | 1<<19 | 1<<12 | 1<<6 | 1<<8 | 1<<9, // O - FREE SYMBOL
1<<4 | 1<<5 | 1<<0 | 1<<1 | 1<<6, // P 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<<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 1<<0 | 1<<1 | 1<<6 | 1<<5 | 1<<4 | 1<<11, // R
0b01101101, // S (1 << 18 | 1 << 13) | (1 << 29 | 1 << 26) | (1 << 5 | 1 << 2) | (1 << 19 | 1 << 12), // percent(%) sign, s == 5 -> // 0b01101101, // S
1<<0 | 1<<8 | 1<<9, // T 1<<0 | 1<<8 | 1<<9, // T
1<<1 | 1<<2 | 1<<3 | 1<<4 | 1<<5, // U 1<<1 | 1<<2 | 1<<3 | 1<<4 | 1<<5, // U
1<<1 | 1<<13 | 1<<17 | 1<<5, // V 1<<1 | 1<<13 | 1<<17 | 1<<5, // V
@ -296,7 +296,7 @@ uint32_t ch_seg[64] = {
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<<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<<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<<4 | 1<<5 | 1<<0 | 1<<1 | 1<<2, // n
1<<0 | 1<<12 | 1<<15 | 1<<2 | 1<<3, // oЗ (1<<8 | 1<<9) | 1<<10 | 1<<18, // 'o' for arrow up ^
}; };

View File

@ -1,6 +1,6 @@
#include "rskos.h" #include "rskos.h"
#ifdef RS_LINUX #ifndef RS_KOS
#include "rs/rstexture.h" #include "rs/rstexture.h"
#include "rs/rsgl.h" #include "rs/rsgl.h"

View File

@ -16,7 +16,7 @@ void rskos_exit();
// sound // sound
#ifndef SNDBUF #ifndef SNDBUF
#ifdef RS_LINUX #ifndef RS_KOS
#include "rs/rsaudio.h" #include "rs/rsaudio.h"
typedef rs_sound_t* SNDBUF; typedef rs_sound_t* SNDBUF;
#else #else

View File

@ -1,14 +0,0 @@
#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;
};

View File

@ -1,3 +0,0 @@
#include "rs/rsplatform.h"
void rs_main_init();

View File

@ -1,13 +1,17 @@
#include "rssoundgen.h" #include "rssoundgen.h"
/*
#include "rsnoise.h" #include "rsnoise.h"
#include "rs/rsmx.h" #include "rs/rsmx.h"
#include <math.h>
#include <string.h> #ifdef RS_KOS
#include "rs/rsplatform.h"
#else
#include <stdlib.h>
#include <math.h>
#include <string.h>
#endif
rs_sgen_reg_t rs_sgen_reg; rs_sgen_reg_t rs_sgen_reg;
@ -454,4 +458,4 @@ void rs_sgen_func_shift(int dest, int src) {
}; };
}; };
*/

View File

@ -3,9 +3,7 @@
#include "rsgame.h" #include "rsgame.h"
/* //#include "rs/rsaudio.h"
#include "rs/rsaudio.h"
typedef struct rs_sgen_reg_t { typedef struct rs_sgen_reg_t {
int wave_length; int wave_length;
@ -40,6 +38,6 @@ 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); //void rs_gen_func_mult_add_value(int dest, int src, float val_mult, float val_add);
*/
#endif #endif

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

View File

@ -0,0 +1,201 @@
<html>
<head>
<meta charset="utf-8">
<title>Heliothryx Localization Tool: Text Converter</title>
<script type="text/javascript">
/*
Russian (Cyrilic) match:
Б b
Г g
Д d
Ж j
З o
И i
Й ^
Л l
П n
Ф f
Ц c
Ч - (4)
Ш h
Щ m
Ъ [
Ы \\
Ь ]
Э e
Ю k
Я a
*/
function convert() {
ar = new Array;
ar["A"] = "A";
ar["B"] = "B";
ar["C"] = "C";
ar["D"] = "D";
ar["E"] = "E";
ar["F"] = "F";
ar["G"] = "G";
ar["H"] = "H";
ar["I"] = "I";
ar["J"] = "J";
ar["K"] = "K";
ar["L"] = "L";
ar["M"] = "M";
ar["N"] = "N";
ar["O"] = "0";
ar["P"] = "P";
ar["Q"] = "Q";
ar["R"] = "R";
ar["S"] = "5";
ar["T"] = "T";
ar["U"] = "U";
ar["V"] = "V";
ar["W"] = "W";
ar["X"] = "X";
ar["Y"] = "Y";
ar["Z"] = "Z";
ar[" "] = " ";
ar["0"] = "0";
ar["1"] = "1";
ar["2"] = "2";
ar["3"] = "3";
ar["4"] = "4";
ar["5"] = "5";
ar["6"] = "6";
ar["7"] = "7";
ar["8"] = "8";
ar["9"] = "9";
ar[":"] = ":";
ar[";"] = ";";
ar["<"] = "<";
ar["-"] = "=";
ar[">"] = ">";
ar["?"] = "?";
ar["/"] = "@";
ar["_"] = "_"; // comma (,)
ar["`"] = "`"; // dot (.)
// CYRILIC
ar["А"] = "A";
ar["Б"] = "b";
ar["В"] = "B";
ar["Г"] = "g";
ar["Д"] = "d";
ar["Е"] = "E";
ar["Ё"] = "E";
ar["Ж"] = "j";
ar["З"] = "3";
ar["И"] = "i";
ar["Й"] = "^";
ar["К"] = "K";
ar["Л"] = "l";
ar["М"] = "M";
ar["Н"] = "H";
ar["О"] = "0";
ar["П"] = "n";
ar["Р"] = "P";
ar["С"] = "C";
ar["Т"] = "T";
ar["У"] = "Y";
ar["Ф"] = "f";
ar["Х"] = "X";
ar["Ц"] = "c";
ar["Ч"] = "4";
ar["Ш"] = "h";
ar["Щ"] = "m";
ar["Ъ"] = "[";
ar["Ы"] = "\\\\";
ar["Ь"] = "]";
ar["Э"] = "e";
ar["Ю"] = "k";
ar["Я"] = "a";
ar["("] = "<";
ar[")"] = ">";
ar[","] = "_";
ar["."] = "`";
s = document.getElementById("inp").value;
s = s.toUpperCase();
s2 = '';
error = '';
for (i in s) {
if (ar[s[i]] != undefined) {
s2 += ar[s[i]];
}
else {
s2 += "`";
error = 1;
};
};
document.getElementById("outp").value = s2;
document.getElementById("outp2").innerHTML = error ? '(disallowed symbols has been replaced with dot)' : '';
};
</script>
</head>
<body>
<h1>Heliothryx Localization Tool: Text Converter</h1>
<img align="right" src="font.png" style="margin-right: 1em; margin-bottom: 1em;">
<p>This is procedural font. To minimize program size, only necessary characters are implemented:</p>
<p>
<ul>
<li>Numbers;</li>
<li>Latin characters from A to Z;</li>
<li>Cyrilic (Russian) characters which can't be replaced by matching Latin characters or numeric symbols;</li>
<li>Some punctuation.</li>
</ul>
</p>
<p>Actually this is part of ASCII table starting from '0' (0x30). </p>
<p>Note that not all latin characters are in fact implemented, for example, 'S' can be successfully replaced by number 5, so other symbol are placed in place of 'S'. Some punctuation symbols are also replaced, for example, dot (.) in ASCII table have 0x2E code which is outside our range, so it is implemented in place of useless grave accent symbol (`). </p>
<p>To make process of writing string constants easier, this tool has been made. Write any text to first field, hit Enter and take string that you can use in your code. If you try to use unsupported characters, they will be replaced by dot and you will get warning. </p>
<div style="clear: both;">&nbsp;</div>
<form>
<div style="border: 1px solid #99CCAA; padding: 8px; background-color: #CCFFDD; display: table;">
<input size=40 id="inp"> <input type="submit" value="Convert (Enter)" onclick="convert(); return false;"> <br>
<input size=40 id="outp"> <span style="color: red; font-weight: bold;" id="outp2"></span>
</div>
</form>
<small>Developed by: Roman Shuvalov</small>
</body>
</html>

View File

@ -8,3 +8,9 @@ Heliothryx -- игра, разрабатываемая на конкурс.
Heliothryx -- game that is developed for contest. Heliothryx -- game that is developed for contest.
Developer: Roman Shuvalov (http://board.kolibrios.org/memberlist.php?mode=viewprofile&u=6469) Developer: Roman Shuvalov (http://board.kolibrios.org/memberlist.php?mode=viewprofile&u=6469)
For Localization:
Text strings are encoded in special format.
Please check out special tool (localization-tool/index.html).
There are instructions and text converter.

View File

@ -170,5 +170,24 @@ void* memcpy(void *dst, const void *src, unsigned size)
} }
char* strchr(char* s, int c) {
while (*s) {
if (*s == (char) c) {
return s;
};
s++;
};
return NULL;
};
unsigned int strlen ( char * str ) {
unsigned int len = 0;
while ( *str ) {
len++;
str++;
};
return len;
};

View File

@ -50,4 +50,7 @@ void free(void* pointer);
void* memset(void *mem, int c, unsigned size); void* memset(void *mem, int c, unsigned size);
void* memcpy(void *dst, const void *src, unsigned size); void* memcpy(void *dst, const void *src, unsigned size);
char* strchr(char* s, int c);
unsigned int strlen ( char * str );
#endif #endif

View File

@ -242,7 +242,7 @@ void game_reg_init() {
game.status = STATUS_LOADING; game.status = STATUS_LOADING;
game.window_scale = 1; // game.window_scale = 1;
// game.window_scale = 2; // game.window_scale = 2;
// #ifndef RS_KOS // #ifndef RS_KOS
@ -451,9 +451,8 @@ void GameInit() {
}; };
// memset( game.field, 0, FIELD_LENGTH ); // memset( game.field, 0, FIELD_LENGTH );
game.scaled_framebuffer = malloc(GAME_WIDTH*game.window_scale * GAME_HEIGHT*game.window_scale * 3); game.bgr_framebuffer = malloc(GAME_WIDTH * GAME_HEIGHT * 3);
DEBUG10f("scaled framebuffer: %d (window_scale = %d) \n", game.window_scale * GAME_WIDTH * GAME_HEIGHT * 3, game.window_scale);
game_font_init(); game_font_init();
game_textures_init_stage1(); game_textures_init_stage1();
@ -574,12 +573,17 @@ void GameKeyDown(int key, int first) {
if (game.status == STATUS_PLAYING) { if (game.status == STATUS_PLAYING) {
#ifndef RS_KOS
if (key == RS_KEY_SPACE) { if (key == RS_KEY_SPACE) {
game.score = 101;
game.score = 101; };
#endif
if (key == RS_KEY_ESCAPE) {
game.time = 0;
game.score = 0;
game.status = STATUS_MENU;
game.need_redraw = 1;
}; };
}; };
@ -624,6 +628,13 @@ void GameMouseDown(int x, int y) {
game.ty = y; game.ty = y;
if (game.status == STATUS_MENU) { if (game.status == STATUS_MENU) {
int i;
for (i = 0; i < FIELD_LENGTH; i++) {
game.field[i] = (unsigned char) (0.99 * fabs(rs_noise(i, seed*7 + 10)) * CRYSTALS_COUNT) | CRYSTAL_VISIBLE_BIT;
};
game.selected = 0;
game.time = 0; game.time = 0;
game.score = 0; game.score = 0;
game.status = STATUS_PLAYING; game.status = STATUS_PLAYING;

View File

@ -139,7 +139,7 @@ void soundbuf_stop(rs_soundbuf_t *snd);
typedef struct rs_game_t { typedef struct rs_game_t {
rs_texture_t framebuffer; rs_texture_t framebuffer;
unsigned char *scaled_framebuffer; // 24-bit BGRBGRBGR... for direct drawing unsigned char *bgr_framebuffer; // 24-bit BGRBGRBGR... for direct drawing
int loader_counter; int loader_counter;
@ -167,7 +167,7 @@ typedef struct rs_game_t {
int menu_index; int menu_index;
int menu_item_index; int menu_item_index;
int window_scale; // int window_scale;
int process_timer; int process_timer;

View File

@ -31,7 +31,8 @@ void game_draw() {
if (game.menu_index == MENU_MAIN) { if (game.menu_index == MENU_MAIN) {
if (game.status == STATUS_LOADING) { if (game.status == STATUS_LOADING) {
game_textout_at_center( 0, 240, 0, "L0ADING```" ); game_textout_at_center( 0, 240, 0, L_LOADING );
game_textout_at_center( -3, 240-2, 3, L_LOADING );
} }
else { else {
@ -39,25 +40,26 @@ void game_draw() {
if (game.time) { if (game.time) {
game_textout_at_center( 0, 230, 0, "LEVEL PA55ED" ); game_textout_at_center( 0, 230, 0, L_LEVEL_PASSED );
game_textout_at_center( -3, 230-2, 3, "LEVEL PA55ED" ); game_textout_at_center( -3, 230-2, 3, L_LEVEL_PASSED );
char s[] = "TIME: 000"; char s[] = L_TIME;
int time_sec = game.time / 25; int time_sec = game.time / 25;
s[6] = '0' + (( time_sec / 100 ) % 10); char *str_num = strchr(s, 'x');
s[7] = '0' + (( time_sec / 10 ) % 10); str_num[0] = '0' + (( time_sec / 100 ) % 10);
s[8] = '0' + (( time_sec / 1 ) % 10); str_num[1] = '0' + (( time_sec / 10 ) % 10);
str_num[2] = '0' + (( time_sec / 1 ) % 10);
game_textout_at_center( 0, 260, 0, s ); game_textout_at_center( 0, 260, 0, s );
game_textout_at_center( -3, 260-2, 3, s ); game_textout_at_center( -3, 260-2, 3, s );
}; };
game_textout_at_center( 0, 300, 0, "CLICK T0 5TART" ); game_textout_at_center( 0, 300, 0, L_START );
game_textout_at_center( -3, 300-2, 3, "CLICK T0 5TART" ); game_textout_at_center( -3, 300-2, 3, L_START );
}; };
game_textout( 2, GAME_HEIGHT-10, 2, "DEVEL0PED BY R0MAN 5HUVAL0V"); game_textout( 2, GAME_HEIGHT-10, 2, L_BOTTOM_LINE_DEVELOPER_INFO);
}; };
} }
@ -92,21 +94,23 @@ void game_draw() {
}; };
char str[] = "TIME: 999 "; char str[] = L_TIME;
int time_sec = game.time / 25; int time_sec = game.time / 25;
str[6] = '0' + ( (time_sec / 100) % 10); char *str_num = strchr(str, 'x');
str[7] = '0' + ( (time_sec / 10) % 10); str_num[0] = '0' + ( (time_sec / 100) % 10);
str[8] = '0' + ( (time_sec / 1) % 10); str_num[1] = '0' + ( (time_sec / 10) % 10);
str_num[2] = '0' + ( (time_sec / 1) % 10);
game_textout( 56+3, 32+2, 0, str ); game_textout( 56+3, 32+2, 0, str );
// game_textout( 56-1, 32-1, 0, str ); // game_textout( 56-1, 32-1, 0, str );
game_textout( 56, 32, 3, str ); game_textout( 56, 32, 3, str );
char sstr[] = "5C0RE: 000 0F 100 "; char sstr[] = L_SCORE;
sstr[7] = '0' + ( (game.score / 100) % 10); str_num = strchr(sstr, 'x');
sstr[8] = '0' + ( (game.score / 10) % 10); str_num[0] = '0' + ( (game.score / 100) % 10);
sstr[9] = '0' + ( (game.score / 1) % 10); str_num[1] = '0' + ( (game.score / 10) % 10);
str_num[2] = '0' + ( (game.score / 1) % 10);
game_textout( 56+3, 64+2, 0, sstr ); game_textout( 56+3, 64+2, 0, sstr );
game_textout( 56, 64, 3, sstr ); game_textout( 56, 64, 3, sstr );
@ -115,7 +119,7 @@ void game_draw() {
// rskos_draw_area(0, 0, w, h, game.window_scale, game.framebuffer.data, NULL, RSKOS_BGRA); // rskos_draw_area(0, 0, w, h, game.window_scale, game.framebuffer.data, NULL, RSKOS_BGRA);
rskos_draw_area(0, 0, w, h, game.window_scale, game.framebuffer.data, game.scaled_framebuffer, 0); rskos_draw_area(0, 0, w, h, 1, game.framebuffer.data, game.bgr_framebuffer, 0);
}; };
if (!continue_need_redraw) { if (!continue_need_redraw) {
@ -218,9 +222,9 @@ void game_textures_init_stage1() {
// float cr_g[CRYSTALS_COUNT] = { 0.1, 0.8, 0.5, 0.0, 0.7, 0.0, 0.8 }; // float cr_g[CRYSTALS_COUNT] = { 0.1, 0.8, 0.5, 0.0, 0.7, 0.0, 0.8 };
// float cr_b[CRYSTALS_COUNT] = { 0.0, 0.1, 0.9, 0.8, 0.0, 0.5, 0.9 }; // float cr_b[CRYSTALS_COUNT] = { 0.0, 0.1, 0.9, 0.8, 0.0, 0.5, 0.9 };
float cr_r[CRYSTALS_COUNT] = { 1.0, 0.4, 0.1, 0.9, 0.9, 0.2, 0.8 }; float cr_r[CRYSTALS_COUNT] = { 1.0, 0.4, 0.10, 0.9, 1.0, 0.2, 0.8 };
float cr_g[CRYSTALS_COUNT] = { 0.1, 1.0, 0.6, 0.1, 0.8, 0.2, 0.8 }; float cr_g[CRYSTALS_COUNT] = { 0.1, 1.0, 0.75, 0.1, 0.9, 0.2, 0.8 };
float cr_b[CRYSTALS_COUNT] = { 0.0, 0.1, 1.0, 1.0, 0.0, 0.9, 0.9 }; float cr_b[CRYSTALS_COUNT] = { 0.0, 0.1, 1.00, 1.0, 0.1, 0.9, 0.9 };
// rs_gen_init(5, CRYSTAL_SIZE); // rs_gen_init(5, CRYSTAL_SIZE);
@ -357,7 +361,7 @@ void game_textures_init_stage2() {
}; };
void game_textures_free() { void game_textures_free() {
free(game.scaled_framebuffer); free(game.bgr_framebuffer);
// texture_free(&game.tex_gui_line); // texture_free(&game.tex_gui_line);

View File

@ -27,25 +27,25 @@ char window_scale_str[] = "c< 2X >";
char* menu_main_titles[] = { char* menu_main_titles[] = {
"a"L_START, "a"L_START,
"1"L_SETTINGS, // "1"L_SETTINGS,
"2"L_ABOUT, // "2"L_ABOUT,
"b"L_QUIT, // "b"L_QUIT,
0 0
}; };
char* menu_settings_titles[] = { char* menu_settings_titles[] = {
" "L_WINDOW_SCALE, // " "L_WINDOW_SCALE,
window_scale_str, // window_scale_str,
" ", // " ",
"0"L_DONE, // "0"L_DONE,
0 0
}; };
char* menu_about_titles[] = { char* menu_about_titles[] = {
" "L_DEVELOPED_BY, // " "L_DEVELOPED_BY,
" "L_ROMAN_SHUVALOV, // " "L_ROMAN_SHUVALOV,
" ", // " ",
"0"L_DONE, // "0"L_DONE,
0 0
}; };

View File

@ -2,10 +2,8 @@
#define RS_STRINGS_H #define RS_STRINGS_H
#ifndef RS_KOS #ifndef RS_KOS
#include "strings_ru.h" #include "strings_en.h"
#else #else
//#include "../lang.h"
#ifdef LANG_RU #ifdef LANG_RU
// Russian // Russian

View File

@ -6,25 +6,17 @@
// Be careful, only specific chars are available to use // Be careful, only specific chars are available to use
// See readme for details // See readme for details
// Main Menu // Lower 'xxx' is used to detect number position, it will be replaced by numbers
#define L_START "5TART"
#define L_SETTINGS "5ETTING5"
#define L_ABOUT "CREDITS"
#define L_QUIT "QUIT"
// Settings menu #define L_LOADING "L0ADING```"
#define L_WINDOW_SCALE "WINDOW SCALE:"
#define L_DONE "DONE"
// About menu #define L_START "CLICK T0 5TART"
#define L_DEVELOPED_BY "DEVELOPED BY"
#define L_ROMAN_SHUVALOV "ROMAN SHUVALOV" #define L_TIME "TIME: xxx"
#define L_SCORE "5C0RE: xxx 0F 100"
#define L_LEVEL_PASSED "LEVEL PA55ED"
// Main screen
#define L_BOTTOM_LINE_DEVELOPER_INFO "DEVELOPER: ROMAN SHUVALOV` TOGLIATTI_ 2014" #define L_BOTTOM_LINE_DEVELOPER_INFO "DEVELOPER: ROMAN SHUVALOV` TOGLIATTI_ 2014"
// Gameplay
#define L_TECHDEMO_LINE1 "THIS IS TECHDEMO` "
#define L_TECHDEMO_LINE2 "USE ARROWS TO MOVE_ <A> TO SHOOT_ <E5C> TO EXIT` "
#endif #endif

View File

@ -6,26 +6,17 @@
// Be careful, only specific chars are available to use // Be careful, only specific chars are available to use
// See readme for details // See readme for details
// Main Menu // Lower 'xxx' is used to detect number position, it will be replaced by numbers
#define L_START "CTAPT"
#define L_SETTINGS "HACTP0^Ki"
#define L_ABOUT "0b igPE"
#define L_QUIT "B\\X0d"
// Settings menu #define L_LOADING "3AgPY3KA```"
#define L_WINDOW_SCALE "MAChTAb 0KHA:"
#define L_DONE "g0T0B0"
// About menu #define L_START "HA4AT] igPY"
#define L_DEVELOPED_BY "PA3PAb0T4iK:"
#define L_ROMAN_SHUVALOV "P0MAH hYBAl0B" #define L_TIME "BPEMa: xxx"
#define L_SCORE "04Ki: xxx i3 100"
#define L_LEVEL_PASSED "YP0BEH] nP0^dEH"
// Main screen
#define L_BOTTOM_LINE_DEVELOPER_INFO "PA3PAb0T4iK: P0MAH hYBAl0B` T0l]aTTi_ 2014" #define L_BOTTOM_LINE_DEVELOPER_INFO "PA3PAb0T4iK: P0MAH hYBAl0B` T0l]aTTi_ 2014"
// Gameplay
#define L_TECHDEMO_LINE1 "eT0 TEXH0dEMKA` "
#define L_TECHDEMO_LINE2 "CTPElKi = dBijEHiE_ <A> = B\\CTPEl_ <E5C> = B\\X0d` "
#endif #endif

View File

@ -8,3 +8,6 @@ Marble Match 3 -- игра, разрабатываемая на конкурс.
Marble Match 3 -- game that is developed for contest. Marble Match 3 -- game that is developed for contest.
Developer: Roman Shuvalov (http://board.kolibrios.org/memberlist.php?mode=viewprofile&u=6469) Developer: Roman Shuvalov (http://board.kolibrios.org/memberlist.php?mode=viewprofile&u=6469)
If you want to translate this game, please use localization tool,
it is same as in my other game, Heliothryx, so please check out
localization readme for Heliothryx and use Heliothryx localization tool.