Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /******************************************************************************/
- /******************************************************************************/
- //"sokoban_and_kit32_2025-01-31\sokoban\src\ctx_main_menu.cpp":
- #include <include_all.hpp>
- #include <cmath>
- using namespace kit;
- enum mouse_zone_names {
- MZONE_PLAY,
- MZONE_EDITOR,
- MZONE_REBIND,
- MZONE_QUIT,
- MZONE_MUSVOL,
- MZONE_SFXVOL,
- MZONE_COUNT,
- };
- #define UV_STEP(_amount) ((1.0f/ICON_MENU_LEN)*(_amount))
- Texture* icon_menu = nullptr;
- Texture* icon_menu_inv = nullptr;
- static Vertex verts[4];
- static s32 verts_indices[6];
- static bool verts_init = false;
- static inline void init_verts(){
- if(verts_init) return;
- verts_init = true;
- clrs::ABGR color = 0xFFFFFFFF;
- verts[0].c = color;
- verts[1].c = color;
- verts[2].c = color;
- verts[3].c = color;
- verts[0].v = 0.0f;
- verts[1].v = 0.0f;
- verts[2].v = 1.0f;
- verts[3].v = 1.0f;
- verts_indices[0] = 0;
- verts_indices[1] = 1;
- verts_indices[2] = 2;
- verts_indices[3] = 3;
- verts_indices[4] = 1;
- verts_indices[5] = 2;
- }
- static inline void _draw_icon(f32 x, f32 y, u32 which,
- bool inverted)
- {
- init_verts();
- verts[0].pos = {x , y };
- verts[1].pos = {x+32, y };
- verts[2].pos = {x , y+32};
- verts[3].pos = {verts[1].x, verts[2].y};
- verts[0].u = verts[2].u = UV_STEP(which );
- verts[1].u = verts[3].u = UV_STEP(which+1);
- if(!inverted) rndr->renderGeometry(verts, 4, icon_menu , verts_indices, 6);
- else rndr->renderGeometry(verts, 4, icon_menu_inv, verts_indices, 6);
- }
- void draw_icon_rgb(f32 x, f32 y, u32 which,
- clrs::ABGR color, bool inverted)
- {
- verts[0].c = color;
- verts[1].c = color;
- verts[2].c = color;
- verts[3].c = color;
- _draw_icon(x, y, which, inverted);
- }
- void draw_icon_hsv(f32 x, f32 y, u32 which,
- f32 hue, bool inverted)
- {
- verts[0].c = hsv2rgb( fmodf(hue+ 0, 360) , 100,100);
- verts[1].c = hsv2rgb( fmodf(hue+ 90, 360) , 100,100);
- verts[2].c = hsv2rgb( fmodf(hue+180, 360) , 100,100);
- verts[3].c = hsv2rgb( fmodf(hue+270, 360) , 100,100);
- _draw_icon(x, y, which, inverted);
- }
- static struct {
- s32 music_pos;
- s32 sfx_pos;
- s32 opt;
- u8 opt_color;
- bool music_up;
- bool sfx_up;
- bool init = false;
- } ctx;
- static inline void new_opt_color(){
- //since text color is black (which is the default text box color),
- //i only want to randomly select colors 1 through 15
- ctx.opt_color = 1+(frandf()*(TEXTCOLORED_LEN-2)+0.5f);
- }
- static inline void reset_ctx(){
- if(ctx.init) return;
- music_play((music_index == -1) ? MUSIC_INDEX_musicbox1_intro
- : MUSIC_INDEX_musicbox1);
- memory::set(&ctx, 0, sizeof(ctx));
- ctx.opt = -1;
- new_opt_color();
- ctx.init = true;
- cursor_scroll = false;
- cursor_snow = true;
- }
- #define MOUSE_ZONES_LEN countof(mouse_zones, shape::rect)
- static shape::rect mouse_zones[] = {
- #define UI_TEXT " Play\n Editor\n Rebind\n Quit"
- {263, 262+16*0-2, 16*7+2, 16+2}, //play
- {263, 262+16*1 , 16*7+2, 16 }, //editor
- {263, 262+16*2 , 16*7+2, 16 }, //rebind
- {263, 262+16*3 , 16*7+2, 16 }, //quit
- #define BAR_HEIGHT 128
- {LOGI_W-64, LOGI_H-BAR_HEIGHT-32, 32, BAR_HEIGHT+32}, //music volume
- {LOGI_W-32, LOGI_H-BAR_HEIGHT-32, 32, BAR_HEIGHT+32}, // sfx volume
- };
- s32 ctx_main_menu_evt(){
- reset_ctx();
- Event evt; bool run = true;
- #define WAS_MOUSE_DOWN (mouseClick && !mouseDrag)
- #define OPT_CHANGED (ctx.opt != opt_old && ctx.opt != -1)
- bool mouseDrag = true;
- bool mouseClick = false;
- s32 opt_old = ctx.opt;
- u32 ctx_which_old = ctx_which;
- while(pollEvent(&evt) && run)
- switch(evt.type){
- case KEVENT_MOUSE_DOWN: mouseDrag = false; ATTR_FALLTHROUGH;
- case KEVENT_MOUSE_MOVED: {
- mouseClick = evt.mouse.button!=0;
- ctx.opt = -1;
- for(u32 i=0; i<MOUSE_ZONES_LEN; ++i){
- shape::point pos = {evt.mouse.x, evt.mouse.y};
- if(point_in_rect(pos, mouse_zones[i])){
- if(opt_old != (s32)i){
- new_opt_color();
- }
- ctx.opt = i; break;
- }
- }
- } goto _def_evt;
- default: _def_evt: run = default_event_handler(evt);
- }
- ctx.music_up = false;
- ctx.sfx_up = false;
- if (ctx.opt<=MZONE_QUIT && OPT_CHANGED ) SFXPLAY(SFXNAME_BLIP1, 1,1.2);
- else if(ctx.opt!=-1 && WAS_MOUSE_DOWN) SFXPLAY(SFXNAME_CHK1 , 1,1.0);
- switch(ctx.opt){
- case MZONE_PLAY : if(WAS_MOUSE_DOWN){ ctx_which = CTX_LVL_SELECT; } break;
- case MZONE_EDITOR: if(WAS_MOUSE_DOWN){ ctx_which = CTX_LVL_EDITOR; } break;
- case MZONE_REBIND: if(WAS_MOUSE_DOWN){ ctx_which = CTX_REBINDING; } break;
- case MZONE_QUIT : if(WAS_MOUSE_DOWN){ run = false; } break;
- case MZONE_MUSVOL: {
- ctx.music_up = true;
- if(mouseClick){
- //should now start at pixel 233, which is 1 pixel into the slider bar
- s32 adjusted = cursor_pos.y-(LOGI_H-BAR_HEIGHT)+1;
- audio->lock();
- settings.music_vol = (f32)adjusted / (BAR_HEIGHT);
- settings.music_vol = CLAMP(1.0f-settings.music_vol, 0.0f, 1.0f);
- audio->unlock();
- }
- } break;
- case MZONE_SFXVOL: {
- ctx.sfx_up = true;
- if(mouseClick){
- //should now start at pixel 233, which is 1 pixel into the slider bar
- s32 adjusted = cursor_pos.y-(LOGI_H-BAR_HEIGHT)+1;
- audio->lock();
- settings.sfx_vol = (f32)adjusted / (BAR_HEIGHT);
- settings.sfx_vol = CLAMP(1.0f-settings.sfx_vol, 0.0f, 1.0f);
- sfx->volumeMaster = settings.sfx_vol;
- audio->unlock();
- }
- } break;
- default:;
- }
- if(ctx_which_old != ctx_which){
- ctx.init = false;
- return -1;
- }
- return run;
- }
- void ctx_main_menu_draw(){
- if(!ctx.init) return;
- text->scale = {2,2};
- //game title
- text->drawBox(KIT_CENTER_TEXT, 32, GAME_NAME);
- //menu buttons
- shape::rect box = text->getRect(KIT_CENTER_TEXT, -32-1, UI_TEXT, true);
- shape::point shift = text->drawBoxNoText(box.x, box.y, box.w, box.h);
- shift.x += box.x;
- shift.y += box.y;
- //will draw ui text, since it's already in the format buffer from getRect()
- text->draw(shift.x, shift.y);
- if(ctx.opt == CLAMP(ctx.opt, MZONE_PLAY, MZONE_QUIT)){
- textColored[ctx.opt_color]->scale = text->scale;
- textColored[ctx.opt_color]->drawChar('\1', shift.x, shift.y + 16*ctx.opt);
- }
- #define BAR_SPEED 8
- if(ctx.music_up) ctx.music_pos = MAX(ctx.music_pos-BAR_SPEED, -BAR_HEIGHT);
- else ctx.music_pos = MIN(ctx.music_pos+BAR_SPEED, 0 );
- if(ctx.sfx_up) ctx.sfx_pos = MAX(ctx.sfx_pos-BAR_SPEED, -BAR_HEIGHT);
- else ctx.sfx_pos = MIN(ctx.sfx_pos+BAR_SPEED, 0 );
- //music note icon
- draw_icon_rgb(LOGI_W-64, LOGI_H+(f32)ctx.music_pos-33,
- 0, unit_to_ryg(settings.music_vol), false);
- //speaker icon
- draw_icon_rgb(LOGI_W-32, LOGI_H+(f32)ctx.sfx_pos-33,
- 1, unit_to_ryg(settings.sfx_vol), false);
- //music volume slider
- shape::rect music_bar = mouse_zones[MZONE_MUSVOL];
- music_bar.y += BAR_HEIGHT+ctx.music_pos+32;
- music_bar.h -= 32;
- rndr->setDrawColor(text->txt_bg);
- rndr->fillRects(&music_bar);
- rndr->setDrawColor(text->txt_bd);
- rndr->drawRects(&music_bar);
- music_bar += {1, 1 + (s32)((1.0f-settings.music_vol)*(BAR_HEIGHT-3))};
- rndr->setDrawColor(0xFFFFFFFF);
- rndr->drawLine(music_bar.x, music_bar.y, music_bar.x+29, music_bar.y);
- //sfx volume slider
- shape::rect sfx_bar = mouse_zones[MZONE_SFXVOL];
- sfx_bar.y += BAR_HEIGHT+ctx.sfx_pos+32;
- sfx_bar.h -= 32;
- rndr->setDrawColor(text->txt_bg);
- rndr->fillRects(&sfx_bar);
- rndr->setDrawColor(text->txt_bd);
- rndr->drawRects(&sfx_bar);
- sfx_bar += {1, 1 + (s32)((1.0f-settings.sfx_vol)*(BAR_HEIGHT-3))};
- rndr->setDrawColor(0xFFFFFFFF);
- rndr->drawLine(sfx_bar.x, sfx_bar.y, sfx_bar.x+29, sfx_bar.y);
- #if defined(_DEBUG) && 0
- rndr->setDrawColor(0xFFFF00FF);
- //if(!(frame_num%2))
- rndr->drawRects(mouse_zones, MOUSE_ZONES_LEN);
- #endif /* _DEBUG */
- }
- /******************************************************************************/
- /******************************************************************************/
- //"sokoban_and_kit32_2025-01-31\sokoban\src\main.cpp":
- #include <include_all.hpp>
- #include <windows.h>
- #include <unistd.h> //for getcwd()
- #include <cstdlib> //for std::srand & std::rand
- #include <cmath>
- using namespace kit;
- /******************************************************************************/
- settings_t settings;
- AudioData* sfxData[SFXDATA_LEN];
- Window* wndw = nullptr;
- Renderer* rndr = nullptr;
- BFont_Texture* text = nullptr;
- BFont_Texture* textColored[16] = {0};
- /****************************** "callbacks.cpp" *******************************/
- s32 cb_audio(void* _dst, const AudioDeviceInfo& info);
- extern bool audioIsReady;
- extern Xmp* music;
- extern Stereo_s16* music_buffer_src; //xmp fills this
- extern Stereo_f32* music_buffer_dst; //dst=src, before applying music_fade
- extern AudioFade music_fade;
- /****************************** "utils_core.cpp" ******************************/
- void tile_init();
- extern Texture* tile_tex;
- /******************************************************************************/
- //just in case you plan on manipulating music_index directly
- //to feed it into music_play or something
- static s32 music_index_old = music_index;
- void music_play(s32 index){
- //since negative indexes are used as a kind of control code,
- //<-1 should be allowed now
- //index = MAX(index, -1);
- if(!audio || index == music_index_old) return;
- audio->lock();
- music_fade.fadeIn = false;
- music_fade.fadeOutCalled = false;
- music_index_old = music_index = index;
- audio->unlock();
- }
- static u32 sampleRate = 0;
- void music_setFadeDelta(f32 fadeTimeSeconds){
- if(!sampleRate) return; //just in case
- music_fade.setDelta(sampleRate, fadeTimeSeconds);
- }
- #if RAND_MAX > 32767
- #error "RAND_MAX > 32767; frand should be altered to accomodate"
- #endif
- //assumes RAND_MAX is 32767
- #define GET_FRAND_VALUE(cast) ( (cast)(std::rand()<<15|std::rand())/0x3FFFFFFF )
- f64 frand (){ return GET_FRAND_VALUE(f64); } // 0.0f -> 1.0f
- f64 frand2 (){ return GET_FRAND_VALUE(f64)*2.0f - 1.0f; } //-1.0f -> 1.0f
- f32 frandf (){ return GET_FRAND_VALUE(f32); } // 0.0f -> 1.0f
- f32 frandf2(){ return GET_FRAND_VALUE(f32)*2.0f - 1.0f; } //-1.0f -> 1.0f
- void settings_load(){
- if(fileio::exists(SETTINGS_PATH)){
- size_t settings_size;
- settings_t* settings_p = (settings_t*)fileio::readAll(SETTINGS_PATH,
- &settings_size);
- if(settings_size < sizeof(settings_t) ||
- settings_p->version != SETTINGS_VERSION)
- {
- memory::free(&settings_p);
- goto _reset_settings;
- } else {
- settings = *settings_p;
- memory::free(&settings_p);
- }
- } else { _reset_settings:
- memory::set(&settings, 0, sizeof(settings_t));
- settings.music_vol = 0.75f;
- settings.sfx_vol = 0.75f;
- }
- }
- void settings_save(){
- settings.version = SETTINGS_VERSION;
- settings.sfx_vol = (sfx->volumeMaster.l+sfx->volumeMaster.r)/2;
- fileio::writeAll(SETTINGS_PATH, &settings, sizeof(settings_t));
- }
- #ifdef _DEBUG
- #define kit_logEvent(_type) kit_LogInfo("unhandled event = %s", getEventText(_type))
- #else
- #define kit_logEvent(_type) ;//kit_LogInfo("event = 0x%08X", (_type))
- #endif
- #define LOGI_Wh (LOGI_W/2)
- #define LOGI_Hh (LOGI_H/2)
- s32 default_event_handler(Event& evt){
- bool run = true;
- switch(evt.type){
- case KEVENT_QUIT: run = false; break;
- case KEVENT_KEY_DOWN: {
- if(evt.key.repeat) break;
- if((evt.key.vkey==VKEY_RETURN && evt.key.kmods&KEYMOD_ALT) ||
- evt.key.vkey == VKEY_F11)
- {
- settings.fullscreen ^= 1;
- //_set_fullscreen:
- wndw->setFullscreen(settings.fullscreen*FULLSCREEN_MODE);
- //makes sure cursor doesn't go out of bounds
- wndw->setGrab(settings.fullscreen);
- }
- /*
- else if(evt.key.vkey == VKEY_ESCAPE &&
- settings.fullscreen)
- {
- settings.fullscreen = false;
- goto _set_fullscreen;
- }
- */
- } break;
- case KEVENT_WIN_MFOCUS_GAINED: showCursor(0); break;
- case KEVENT_WIN_MFOCUS_LOST : showCursor(1); break;
- case KEVENT_MOUSE_MOVED: {
- cursor_pos = shape::point(evt.mouse.x, evt.mouse.y);
- cursor_norm = {(f32)(cursor_pos.x-LOGI_Wh)/LOGI_Wh,
- (f32)(cursor_pos.y-LOGI_Hh)/LOGI_Hh};
- } break;
- case KEVENT_MOUSE_WHEEL: {
- tile_layer = CLAMP(tile_layer+evt.mouse.dy, 0, 999/*or something*/);
- } break;
- default: kit_logEvent(evt.type);
- }
- return run;
- }
- //unit should be between 0.0f and 1.0f
- u32 unit_to_ryg(f32 unit){
- unit = CLAMP(unit*2.0f, 0.0f, 2.0f);
- u8 red = 255, green = 255;
- #define RYG_RND(_v) ( (unsigned char)( (_v)+0.5f ) )
- if(unit < 1.0f) green = RYG_RND(255.0f*( unit));
- else red = RYG_RND(255.0f*(2.0f-unit));
- #undef RYG_RND
- return ABGR_U32(red, green, 0, 255);
- }
- u32 hsv2rgb(f32 H, f32 S, f32 V){
- f32 r, g, b;
- f32 h = H / 360; //normalize values
- f32 s = S / 100;
- f32 v = V / 100;
- //the rest is magic, idk
- s32 i = floor(h*6);
- f32 f = h * 6 - i;
- f32 p = v * (1.0f - s);
- f32 q = v * (1.0f - f * s);
- f32 t = v * (1.0f - (1.0f-f) * s);
- switch (i % 6) {
- case 0: r = v, g = t, b = p; break;
- case 1: r = q, g = v, b = p; break;
- case 2: r = p, g = v, b = t; break;
- case 3: r = p, g = q, b = v; break;
- case 4: r = t, g = p, b = v; break;
- case 5: r = v, g = p, b = q; break;
- }
- //it should be impossible for r,g,b to be uninitialized
- //due to how the switch is set up, so the warning can be ignored
- #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
- #pragma GCC diagnostic push
- return ABGR_U32(r*255, g*255, b*255, 255);
- #pragma GCC diagnostic pop
- }
- /******************************************************************************/
- #define PREVENT_RUNNING_WHILE_ZIPPED 1
- int user_main(int argc, char** argv);
- int main(int argc, char** argv){
- int returnStatus = -1;
- bool extracted = true;
- try {
- u64 timeDelta, timeStartAudio, timeStartAll = time::getMS();
- #if PREVENT_RUNNING_WHILE_ZIPPED == 1
- //this should hopefully prevent people from executing the program
- //before it's unzipped (in most cases, at least)
- #define EXTRACT_MSG "This program must be ran normally, after being unzipped"
- char cwd[256];
- getcwd(cwd, sizeof(cwd));
- cwd[255] = 0; //just in case
- u32 lastChar = strnLen(cwd)-1;
- if(cwd[lastChar]=='/' || cwd[lastChar]=='\\') cwd[lastChar] = 0;
- //first check
- //checks if the program's current working directory is
- //"C:\Users\<name>\AppData" (specific to windows)
- #if defined(_WIN32)
- {
- u32 i = 0, backSlashCount = 0;
- bool foundUsers = false;
- if((cwd[0]|32) == 'c') //(x|32 makes the char x lowercase)
- for(; i<256; ++i){ _start:
- if(cwd[i] == '\0') break;
- if(cwd[i] == '\\') ++backSlashCount;
- if(backSlashCount == 1){
- if(!strnCmp("Users", &cwd[++i], 5)) foundUsers = true;
- goto _start; //++i should only occur once this iteration
- }
- if(foundUsers && backSlashCount == 3){
- if(!strnCmp("AppData", &cwd[++i], 7)){
- extracted = false; throw EXTRACT_MSG;
- }
- break;
- }
- }
- }
- #endif /* defined(_WIN32) */
- //second check
- //all this does is it clips the executable name from the
- //full path (argv[0]) to compare it to the current working directory
- //(this should work even if argv[0] is something else,
- //since you're supposed to run this program normally anyway)
- if(argc > 0){
- char* path = argv[0];
- size_t path_len = strnLen(path);
- s32 i = path_len-1;
- bool fwdSlash = false;
- if(path_len < 256){
- for(; i>=0; --i){
- fwdSlash = path[i]=='/';
- if(fwdSlash || path[i] == '\\'){ path[i] = 0; break; }
- }
- if(i >= 0){
- //throw if the paths are different
- if(strnCmp(path, cwd)){ extracted = false; throw EXTRACT_MSG; }
- //put slash back in case user wants to reference argv[0] too
- path[i] = (fwdSlash) ? '/' : '\\';
- }
- }
- }
- #endif /* PREVENT_RUNNING_WHILE_ZIPPED == 1 */
- settings_load();
- initSubsystems(KINIT_EVERYTHING);
- /********************************* AUDIO INIT *********************************/
- music_fade.fadeVolume = 0.0f;
- AudioDeviceInfo audio_info = audiofunc::getDefaultDevInfo();
- audio_info.sampleFormat = SMPFMT_F32;
- audio_info.numChannels = 2;
- audio_info.zeroBuffer = true;
- audio_info.callback = cb_audio;
- audio_info.userdata = nullptr;
- //(libxmp can only take sample rates between 8kHz and 48kHz)
- audio_info.sampleRate = CLAMP(audio_info.sampleRate, 8000, 48000);
- //actually, for some reason setting audio_info's sampleRate to be lower
- //than 15701 causes _audio.pause() to hang indefinitely (for me at least)
- //tbd: figure out why this happens
- audio_info.sampleRate = MAX(audio_info.sampleRate, 15701);
- sampleRate = audio_info.sampleRate;
- AudioDevice _audio(nullptr, audio_info, false); audio = &_audio;
- _audio.play(); //begin fading in audio
- timeStartAudio = time::getMS();
- SoundEngine _sfx(SFX_TRACKS, sampleRate); sfx = &_sfx;
- _sfx.volumeMaster = settings.sfx_vol;
- Xmp _music; music = &_music;
- //65536 elements specifically is chosen, so that even if the number
- //of sample frames given to the audio callback changes somehow,
- //there will always be enough space for copying (sample frame count is u16)
- //(src = 262,144 Bytes, dst = 524,288 Bytes)
- music_buffer_src = (Stereo_s16*)memory::alloc2(65536*sizeof(Stereo_s16));
- music_buffer_dst = (Stereo_f32*)memory::alloc2(65536*sizeof(Stereo_f32));
- music_fade.userdata_a = (void*)(u64)sampleRate;
- music_setFadeDelta(); //set fade to its default
- /*** SFX INIT ***/
- AudioData sfxData_blip1("dat/sfx/blip1_v3.ogg", AudioDataLoadOGG);
- AudioData sfxData_chk1("dat/sfx/chk1_v2.ogg", AudioDataLoadOGG);
- sfxData_blip1.volume = 0.20f;
- sfxData_chk1.volume = 0.20f;
- sfxData[0] = &sfxData_blip1;
- sfxData[1] = &sfxData_chk1;
- //...
- /********************************* VIDEO INIT *********************************/
- audioIsReady = true;
- { //<- closes at the end of video cleanup
- Window _wndw(WIN_TITLE, WIN_W, WIN_H, WIN_FLAGS|WINFLAG_HIDDEN); wndw=&_wndw;
- Surface icon_win("dat/img/icon_win.png", SurfaceLoadPNG);
- _wndw.setIcon(icon_win);
- Renderer _rndr(_wndw); rndr = &_rndr;
- BFont_Texture _text(_rndr, nullptr, nullptr, GRAY(FF), 16384); text = &_text;
- const clrs::ABGR textColored_colors[TEXTCOLORED_LEN] = {
- 0xFF000000, //gray0 ( 0)
- 0xFF555555, //gray1 ( 85)
- 0xFFAAAAAA, //gray2 (170)
- 0xFFFFFFFF, //gray3 (255)
- 0xFF000080, //redLo
- 0xFF0000FF, //redHi
- 0xFF008000, //greenLo
- 0xFF00FF00, //greenHi
- 0xFF800000, //blueLo
- 0xFFFF0000, //blueHi
- 0xFF808000, //cyanLo
- 0xFFFFFF00, //cyanHi
- 0xFF800080, //magentaLo
- 0xFFFF00FF, //magentaHi
- 0xFF008080, //yellowLo
- 0xFF00FFFF, //yellowHi
- };
- for(u32 i=0; i<TEXTCOLORED_LEN; ++i){
- textColored[i] = new BFont_Texture(_rndr, nullptr, nullptr,
- textColored_colors[i], 1024);
- }
- Texture _tile_tex(*rndr, "dat/img/tiles.png", SurfaceLoadPNG);
- tile_tex = &_tile_tex;
- tile_init();
- Surface im_surf0("dat/img/icon_menu.png", SurfaceLoadPNG);
- Surface im_surf(im_surf0, PIXELFMT_ABGR8888);
- Texture _icon_menu(*rndr, im_surf);
- icon_menu = &_icon_menu;
- shape::point imi_size = im_surf.getSize();
- clrs::ABGR* pixels = (clrs::ABGR*)im_surf.getPixelData();
- size_t pixels_len = imi_size.x*imi_size.y;
- for(size_t i=0; i<pixels_len; ++i)
- pixels[i].v = (pixels[i].a<<24) | (0xFFFFFF-(pixels[i].v&0xFFFFFF));
- Texture _icon_menu_inv(*rndr, im_surf);
- icon_menu_inv = &_icon_menu_inv;
- //...
- /********************************* USER MAIN **********************************/
- wndw->setFullscreen(settings.fullscreen*FULLSCREEN_MODE);
- wndw->setGrab(settings.fullscreen);
- timeDelta = time::getMS()-timeStartAll;
- kit_LogInfo("Initialized in %llums", timeDelta);
- //audio's actual fade DELAY is 90ms, whereas the fade in after that is 10ms.
- //so 95 should put the audio at about halfway through the fade in
- timeDelta = time::getMS()-timeStartAudio;
- time::sleep((u32)MAX((s64)(95-timeDelta), 1));
- //_wndw.setVisibility(true); //this is generally done by user_main
- std::srand((u32)time::getTicks());
- returnStatus = user_main(argc, argv);
- timeStartAll = time::getMS();
- music_setFadeDelta(0.01);
- music_play(-1);
- _wndw.setFullscreen(false);
- _wndw.setVisibility(false);
- _audio.pause(); //begin fading out audio
- /******************************* VIDEO CLEANUP ********************************/
- {
- //...
- }
- for(u32 i=0; i<TEXTCOLORED_LEN; ++i) NULLDELETE(textColored[i],BFont_Texture);
- } //garbage collect video init stuff
- /******************************* AUDIO CLEANUP ********************************/
- //audio's actual fadeout is 10ms, so waiting ~12ms total should be enough
- while(_audio.isPlaying()) time::sleep(4);
- _audio.lock(); //just in case
- memory::free(&music_buffer_src);
- memory::free(&music_buffer_dst);
- {
- //...
- }
- _audio.unlock();
- timeDelta = time::getMS()-timeStartAll;
- kit_LogInfo("Uninitialized in %llums", timeDelta);
- /************************** CATCH EXCEPTION OR EXIT ***************************/
- } catch(const char* errorText){
- kit_LogError("FATAL EXCEPTION OCCURRED: \"%s\"\n", errorText);
- #ifndef _DEBUG
- MessageBeep(MB_ICONERROR);
- showMsgBox(errorText, "FATAL EXCEPTION OCCURRED!", MSGBOX_ERROR);
- #endif /* _DEBUG */
- //redundant, as quitSubsystems already does this when given KINIT_EVERYTHING
- //freeThreadErrors();
- } catch(...){
- kit_LogError("FATAL EXCEPTION OCCURRED: \"(unknown type)\"\n");
- #ifndef _DEBUG
- MessageBeep(MB_ICONERROR);
- showMsgBox("(unknown type)", "FATAL EXCEPTION OCCURRED!", MSGBOX_ERROR);
- #endif /* _DEBUG */
- }
- if(extracted) settings_save();
- //can't error, and is also safe to call even if no subsystems are active!
- quitSubsystems(KINIT_EVERYTHING);
- //a nonzero value indicates a memory leak!
- if(memory::getNumAllocations())
- kit_LogWarn("# OF ALLOCATIONS = %llu", memory::getNumAllocations());
- return returnStatus;
- }
- /******************************************************************************/
- /******************************************************************************/
- //"sokoban_and_kit32_2025-01-31\sokoban\src\user_main.cpp":
- #include <include_all.hpp>
- #include <unistd.h> //for getcwd()
- #include <cmath> //for fabsf
- //begone, unused parameter warning
- #define UM_RETURN(_val) { (void)argc, (void)argv; return (_val); }
- using namespace kit;
- #define CONTEXTS_LEN countof(contexts, ctx_callbacks)
- u32 ctx_which = CTX_MAIN_MENU;
- ctx_callbacks contexts[]{
- {ctx_main_menu_evt , ctx_main_menu_draw },
- {ctx_lvl_select_evt, ctx_lvl_select_draw},
- {ctx_lvl_editor_evt, ctx_lvl_editor_draw},
- };
- shape::point cursor_pos; //logical coordinates, not window coords
- shape::fpoint cursor_norm; //normal coords (-1, 1) (+y is +y, unlike opengl ndc)
- bool cursor_scroll = true;
- bool cursor_snow = false;
- u64 frame_num = 0;
- #define threshhold 0.80f
- #define scroll_multiplier 0.75f
- void update_scroll(){
- shape::fpoint scroll_amnt;
- if(fabsf(cursor_norm.x) >= threshhold){
- scroll_amnt.x = closer_to_0(cursor_norm.x,threshhold) / (1-threshhold);
- scroll_amnt.x *= scroll_multiplier;
- tile_camera.x -= scroll_amnt.x;
- }
- if(fabsf(cursor_norm.y) >= threshhold){
- scroll_amnt.y = closer_to_0(cursor_norm.y,threshhold) / (1-threshhold);
- scroll_amnt.y *= scroll_multiplier;
- tile_camera.y -= scroll_amnt.y;
- }
- }
- #define SNOWFLAKES_LEN 128
- typedef shape::point snowflakes_t;
- static snowflakes_t snowflakes[SNOWFLAKES_LEN];
- static bool snowflakes_dir[SNOWFLAKES_LEN];
- #define chance_to_change_direction (1.0f/8)
- void update_snowflakes(){
- if(!(frame_num%10)){
- for(u32 i=0; i<countof(snowflakes, snowflakes_t); ++i)
- if(snowflakes[i].y >= LOGI_H){ snowflakes[i] = cursor_pos; break; }
- }
- for(u32 i=0; i<countof(snowflakes, snowflakes_t); ++i){
- if(snowflakes[i].y >= LOGI_H) continue;
- if(frandf()<chance_to_change_direction) snowflakes_dir[i] ^= 1;
- snowflakes[i].x += snowflakes_dir[i]*2-1;
- snowflakes[i].y += 1;
- }
- }
- void clear_snowflakes(){
- for(u32 i=0; i<countof(snowflakes, snowflakes_t); ++i) snowflakes[i].y=LOGI_H;
- }
- int user_main(int argc, char** argv){
- //music_play(0);
- wndw->setMinSize(LOGI_W, LOGI_H);
- rndr->setLogicalSize(LOGI_W, LOGI_H);
- wndw->setVisibility(true);
- clear_snowflakes();
- while(true){ _start:
- #ifdef _DEBUG
- u64 ticksStart = time::getTicks();
- #endif /* _DEBUG */
- u64 timeStart = time::getMS();
- ctx_callbacks callbacks;
- if(ctx_which<CONTEXTS_LEN) callbacks = contexts[ctx_which];
- Event e; s32 result = 1;
- if (callbacks.handle_events ) result = callbacks.handle_events();
- else while(pollEvent(&e) && result==1) result = default_event_handler(e);
- if(result== 0) break;
- if(result==-1) goto _start; //context switched; load new callback
- if(cursor_scroll) update_scroll();
- rndr->setDrawColor(GRAY(40));
- rndr->clear();
- if(callbacks.draw_things) callbacks.draw_things();
- rndr->setDrawColor(0xffffffff);
- shape::rect cursor_rect = {cursor_pos.x-1, cursor_pos.y-1, 3, 3};
- rndr->drawRects(&cursor_rect);
- if(cursor_snow)
- rndr->drawPoints(snowflakes, countof(snowflakes, snowflakes_t));
- #ifdef _DEBUG
- text->scale = {1,1};
- f64 secondsDelta = (f64)(time::getTicks()-ticksStart)/time::getTicksPerSecond();
- text->draw(0,-1,"frame %4llu: %3.0fus", 0, frame_num, secondsDelta*1000000);
- #endif
- rndr->present();
- if(cursor_snow) update_snowflakes();
- time::sleep(CLAMP(16-(time::getMS()-timeStart), 1, 16));
- ++frame_num;
- }
- UM_RETURN(0);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement