Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /******************************************************************************/
- /******************************************************************************/
- //"kw32g\include\arrlen.hpp":
- #ifndef _ARRLEN_HPP
- #define _ARRLEN_HPP
- #define gl_scenes_len 5
- #define gl_backgrounds_len 4
- #define gl_tilesets_len 2
- #define gl_objImg_len 11
- #define gl_ambience_len 4
- #endif /* _ARRLEN_HPP */
- /******************************************************************************/
- /******************************************************************************/
- //"kw32g\include\globals.hpp":
- #ifndef _GLOBALS_HPP
- #define _GLOBALS_HPP
- #include <kit/all.hpp>
- #include <kit/xmp_sfx.hpp>
- #include <math.h>
- #ifdef _DEBUG
- #include <stdio.h>
- #define _printf(_fmt, ...) printf(_fmt, __VA_ARGS__)
- #else
- #define _printf(_fmt, ...)
- #endif /* _DEBUG */
- #define _getnumallocs _printf("line %i: %llu\n",__LINE__,memory::getNumAllocations()-2);
- #define PRINT_RECT(_r) _printf("(%3i,%3i, %3i,%3i)\n",(_r).x,(_r).y,(_r).w,(_r).h)
- #define SFXPTR(_index) gl_sfx[_index]
- #define SFXPTR_PLAY(_obj_sfx_ptr) { if(_obj_sfx_ptr) _obj_sfx_ptr->play(); }
- #define SFXPTR_PLAYER_FOOTSTEP SFXPTR( 1)
- #define SFXPTR_PLAYER_JUMPING SFXPTR( 2)
- #define SFXPTR_PLAYER_LANDING SFXPTR( 3)
- #define SFXPTR_ACTIVATE_1 SFXPTR( 4)
- #define SFXPTR_ABILITY_PICKUP SFXPTR( 5)
- #define SFXPTR_ABILITY_REMOVED SFXPTR( 6)
- #define SFXPTR_NOPE_1 SFXPTR( 7)
- #define SFXPTR_DLELELE SFXPTR( 8) //gonna start naming most of them by onomatopoeia
- #define SFXPTR_FWSHWSHWSH SFXPTR( 9)
- #define SFXPTR_DEATH SFXPTR(10) //(has an attack of ~5 ticks!)
- #define DISABLE_NS_EDGES 0
- #define SND_TRACK_COUNT 64
- #define _WINDOW_TITLE "platformer prototype"
- #define CANVSIZ_X 768 //32 tiles wide (assuming tiles are 24x24)
- #define CANVSIZ_Y 432 //18 tiles tall
- #define TILESIZ_X 32
- #define TILESIZ_Y 18
- #define lengthof(_array, _type) (sizeof(_array)/sizeof(_type))
- #define memset0( _array ) kit::memory::set((_array), 0, sizeof(_array))
- #define memset0s(_array, _size) kit::memory::set((_array), 0, (_size) )
- #define NULLDELETE(_ptr_to_thing) { delete _ptr_to_thing; _ptr_to_thing = nullptr; }
- #define PTR_OFFSET(_ptr, _offset, _type) ( \
- (_type*)( ((kit::u64)(_ptr)) + ((kit::s64)(_offset)) ) )
- #define PTR_OFFSETB(_ptr, _offset, _type) ( \
- (_type*)( ((kit::u64)(_ptr)) + ((kit::s64)(_offset)*sizeof(_type)) ) )
- #define ARR2D(_x, _y, _x_len) ((_x) + (_y)*(_x_len))
- #define PUN_DEREF(_thing, _to_type) (*(_to_type*)&(_thing));
- #define RND(_v) ( (kit::s32)( ((_v)>=0) ? (_v)+0.5f : (_v-0.5f) ) ) //rounding
- #define TNC(_v) ( (kit::s32) (_v) ) //truncation
- #define LERP(_v0, _v1, _t) ( (1.0f-(_t)) * (_v0) + (_t) * (_v1) )
- //(this is jank, and i wouldn't have done this at all if i hadn't reduced the ticks
- //per frame from 4 to 2 AFTER already having set the arbitrary physics values)
- #define TPF 2 //(ticks per frame)
- #define TPF_MOD (4.0f/TPF)
- #define TPFVALF(_flt) ((_flt)*(TPF_MOD))
- #define TPFVALI(_int) ((kit::s32)((_int)*(TPF_MOD)))
- // >3 frames instead of >0 to account for ghost step
- #define _MID_AIR (gl_player.ticksInAir>(TPF*3))
- #define PLAYER_JUMPED (gl_player.first_jmp || gl_player.second_jmp)
- #define PLAYER_CAN_GND_JMP (!gl_player.first_jmp && !_MID_AIR)
- #define PLAYER_CAN_AIR_JMP (!gl_player.second_jmp && gl_player.has_dbljmp)
- #define PLAYER_CAN_JUMP ( PLAYER_CAN_GND_JMP || PLAYER_CAN_AIR_JMP )
- #define PLAYER_SET_JMP_FLAGS { if( PLAYER_CAN_GND_JMP){ gl_player.first_jmp = true; } \
- else if(PLAYER_CAN_AIR_JMP){ gl_player.second_jmp = true; } }
- #define MID_AIR (_MID_AIR || PLAYER_JUMPED)
- #define VELX_MAX TPFVALF(1.5f )
- #define VELY_MAX TPFVALF(2.5f )
- #define GRAVITY TPFVALF(0.0195f*(TPF_MOD)) //completely arbitrary lol
- #define PLAYER_JUMP_STRENGTH TPFVALF(2.0f*sqrtf(gl_player.scale/2))
- #define PLAYER_JUMP_CANCEL (0.33f ) //multiplier of vel.y when canceling a jump while ascending
- #define PLAYER_SPEED TPFVALF(0.020f*(TPF_MOD))
- #define PLAYER_SCALE (2.0f ) //initial player scale (8px * 2.0f for a 16x16 player sprite)
- #define PLAYER_NEUTRAL TPFVALF(0.1f ) //what +/- range should be considered 'neutral' for vel/acc
- #define PLAYER_AIR_FRICTION (0.5f ) //multiplier for acc.x when adding to vel.x in mid-air
- #define PLAYER_GND_FRICTION (1.0f ) //multiplier of PLAYER_SPEED for on-ground deceleration
- #define PLAYER_RUN_MUL (0.075f/(gl_player.scale/2)) //vel.x's multiplier when adding to runningState
- #define PLAYER_LANDING_VOLUME (0.05f)
- extern char falseStr[]; // = "false"
- extern char trueStr[]; // = "true"
- #define boolStr(_bool_value) ( (_bool_value) ? trueStr : falseStr )
- #define DEATH_PROG_MAX (3.0f)
- extern kit::f32 gl_death_prog;
- extern kit::s32 audioManager(void* userdata);
- //(gl_ as in gl[obal], not [open]gl)
- extern kit::Thread* gl_audioManager_thread;
- extern bool gl_audioManager_exit; //poor mans' semaphores, since
- extern bool gl_audioManager_occ_thr; //my mutexes don't seem to
- extern bool gl_audioManager_occ_sfx; //work across multiple threads :(
- extern bool gl_saveRead_called; //'was saveRead() called this tick?'
- extern kit::u64 gl_tickCounter;
- extern kit::TimerSimple* gl_frameTimer;
- extern kit::SoundEngine* gl_snd;
- extern kit::Window* gl_win;
- extern kit::BitmapFont* gl_text;
- extern kit::FStr* gl_fstr;
- #define gl_textf(_x, _y, _fmt, ...) \
- gl_text->print((_x), (_y), gl_fstr->fmt(_fmt, __VA_ARGS__), 0)
- #define gl_textfs(_x, _y, _fmt, _maxLen, ...) \
- gl_text->print((_x), (_y), gl_fstr->fmt(_fmt, __VA_ARGS__), (_maxLen))
- extern kit::Bitmap* gl_spritesheetPlayer;
- extern kit::Bitmap* gl_spritesheetFont; //a copy of gl_text's texture atlas
- extern kit::Bitmap* gl_spritesheetAbilityIndicators;
- struct ControlStates;
- struct Player;
- struct Scene;
- struct SceneDescriptor;
- struct Object;
- struct SoundEffect;
- typedef bool (*Object_TickCallback)(Object* _obj_a, bool render_only);
- #include <arrlen.hpp>
- #define gl_sfx_len 10
- #define gl_music_len 4
- #define gl_objCallbacks_len 9
- //+1 for the array lengths, since the first valid id is 1, not 0
- extern ControlStates gl_ctrlStates;
- extern Player gl_player;
- extern Scene gl_scene;
- extern SceneDescriptor* gl_scenes[gl_scenes_len+1];
- extern kit::u16 gl_scene_indices[gl_scenes_len+1];
- extern Object* gl_objsCache[gl_scenes_len+1];
- extern kit::Bitmap* gl_backgrounds[gl_backgrounds_len+1];
- extern kit::Bitmap* gl_tileset_missing;
- extern kit::Bitmap* gl_tilesets[gl_tilesets_len+1];
- extern kit::Bitmap* gl_objImg[gl_objImg_len+1];
- extern kit::AudioData* gl_ambience[gl_ambience_len+1];
- extern SoundEffect* gl_sfx[gl_sfx_len+1];
- extern const char gl_sfxNames[gl_sfx_len+1][32]; //sfx file paths
- extern const kit::shape::fpoint gl_sfxSettings[gl_sfx_len+1]; //volume and speedRange
- extern const char gl_music[gl_music_len+1][32]; //the music's file paths
- extern const Object_TickCallback gl_objCallbacks[gl_objCallbacks_len+1];
- #include <text_lines.hpp>
- #ifdef _DEBUG
- #define DBG_TXT(_row, _fmt, ...) gl_textf(1,1+(_row)*9, _fmt, __VA_ARGS__)
- #define WINDOW_TITLE _WINDOW_TITLE" (Debug Build)"
- #if gl_scenes_len > 1
- # define STARTING_SCENE 2
- #else
- # define STARTING_SCENE 1 //if there's only 1 scene you can't go to #2 lol
- #endif
- #define STARTING_POSITION { CANVSIZ_X/2 - 350, CANVSIZ_Y/2 - 80 }
- #else
- #define DBG_TXT(_row, _fmt, ...)
- #define WINDOW_TITLE _WINDOW_TITLE
- #define STARTING_SCENE 1
- #define STARTING_POSITION { CANVSIZ_X/2 - 350, CANVSIZ_Y/2 - 80 }
- #endif
- void gl_win_drawRectEmpty(kit::shape::rect rect, kit::color::ARGB color,
- kit::u32 width = 1);
- kit::f64 frand();
- kit::f32 frandf();
- kit::f64 frandRange(kit::f64 start, kit::f64 maxDeviation);
- //"delta_p" should be a pointer to the point to be filled in with
- //the number of pixels to shift the position by to avoid a collision
- //(passing nullptr to delta_p will result in it being ignored)
- bool rects_overlapping(kit::shape::rect& object_rect, kit::shape::rect& obstacle_rect,
- kit::shape::point* delta_p = nullptr);
- bool subtiles_overlapping(kit::shape::rect& object_rect_ref,
- kit::shape::point* delta_p = nullptr);
- void handleEdgeWrap();
- void drawStuff_and_processObjects();
- kit::color::ARGB unit_to_ryg(kit::f32 unit);
- //assumes 8x8 monospaced with 1 pixel of spacing in both x and y
- kit::shape::point get_text_size(const char* str);
- //x&y determine the CENTER position of the text, not its top-left corner
- //calculates text_size if either text_size.x or .y is 0
- void drawTextBox(kit::s32 x, kit::s32 y, const char* str,
- kit::shape::point text_size = {0,0});
- struct SoundEffect { //40B (not including the size of the AudioData class)
- kit::AudioData* sfx = nullptr;
- kit::f32 volL = 1.0f;
- kit::f32 volR = 1.0f;
- kit::f64 speedBase = 1.0 ;
- kit::f64 speedRange = 0.0 ;
- kit::f32 pan = 0.0f;
- kit::u32 _padding32;
- SoundEffect(const char* filePath, kit::f32 volume = 1.0f,
- kit::f64 _speedRange = 0.0)
- {
- sfx = new kit::AudioData(filePath, gl_snd);
- volL = volume, volR = volume;
- speedRange = _speedRange;
- }
- ~SoundEffect(){ delete sfx; }
- kit::s32 play(){
- if(sfx != nullptr){
- gl_audioManager_occ_sfx = true;
- while(gl_audioManager_occ_thr) kit::time::sleep(0);
- kit::s32 trackNum;
- if(speedRange < 0.0) speedRange = -speedRange;
- if(!speedRange) trackNum = gl_snd->sfxPlay(sfx, volL, volR, 1.0, pan);
- else trackNum = gl_snd->sfxPlay(sfx, volL, volR, frandRange(speedBase,speedRange), pan);
- gl_audioManager_occ_sfx = false;
- return trackNum;
- } else {
- return -1;
- }
- }
- };
- //differs from shape::rect in that the rectangle is defined
- //by 2 points instead of a top-left position + w,h
- struct shape_quad {
- kit::shape::point a, b; //top-left corner, bottom-right corner
- shape_quad() : a(0, 0), b(0, 0) {}
- shape_quad(kit::shape::rect& r) : a(r.x, r.y), b(r.w, r.h) { b += a; }
- inline void operator-=(const shape_quad& q){ a -= q.a; b -= q.b; }
- inline void operator+=(const shape_quad& q){ a += q.a; b += q.b; }
- inline void operator*=(const kit::s32 & v){ a.x *= v; a.y *= v; b.x *= v; b.y *= v; }
- inline void operator/=(const kit::s32 & v){ a.x /= v; a.y /= v; b.x /= v; b.y /= v; }
- };
- //keyboard action states for the current tick
- //(_p, _r for p[ressed] and r[eleased])
- struct ControlStates {
- struct {
- bool up_p, up_r;
- bool down_p, down_r;
- bool left_p, left_r;
- bool right_p, right_r;
- } inst; //instantaneous control states
- bool esc_h;
- //bool action_p, action_r;
- };
- #define CTRLSTATE_SET(_which) gl_ctrlStates._which = true
- #define CTRLSTATE_CLR(_which) gl_ctrlStates._which = false
- #define CTRLSTATE_GET(_which) (gl_ctrlStates._which)
- static inline void clearControlStates(){
- kit::memory::set(&gl_ctrlStates.inst, 0, sizeof(gl_ctrlStates.inst));
- }
- static inline void resetEnvFlags(){
- gl_saveRead_called = false;
- }
- extern bool gl_fullscreen;
- bool handleEvents();
- #define exit_prog_inc 0.013f
- static inline bool handleEscExit(){
- static kit::f32 exit_prog = 0.0f;
- if(CTRLSTATE_GET(esc_h)){
- exit_prog += exit_prog_inc;
- if(exit_prog >= 1.0f) return false;
- } else if(exit_prog > 0.0f){
- exit_prog -= exit_prog_inc;
- exit_prog = MAX(exit_prog, 0.0f);
- goto _draw_rectangle;
- }
- if(exit_prog > 0.0f){
- _draw_rectangle:
- kit::shape::rect visual(0,0, (kit::s32)(CANVSIZ_X*exit_prog),16);
- kit::color::ARGB visual_color = unit_to_ryg(1.0f-exit_prog);
- gl_win->drawRectangles(&visual, 1, visual_color);
- }
- return true;
- }
- void attemptReset(bool skipRead = false);
- void deathAnim();
- #endif /* _GLOBALS_HPP */
- /******************************************************************************/
- /******************************************************************************/
- //"kw32g\include\object.hpp":
- #ifndef _OBJECT_HPP
- #define _OBJECT_HPP
- #include <globals.hpp>
- //if scene_id is 0, the current active scene is used instead
- //(also if 0, this should be called only AFTER loading tile data via loadScene)
- void loadObjects(bool forced = false, kit::u16 scene_id = 0);
- //returns whether the scene's state changed
- bool processObjects(bool in_front, bool render_only = false);
- //struct Object;
- //typedef bool (*Object_TickCallback)(Object* _obj_a, bool render_only);
- //(^^ already defined in globals.hpp)
- struct Object { //48B (28 bytes reserved for the user data)
- kit::u64 _user_0; //data depends on object type
- kit::u64 _user_1; //
- kit::u64 _user_2; //
- kit::u32 _user_3; //
- struct {
- kit::u16 x;
- kit::u16 y;
- } /*-----------*/ size;
- struct {
- kit::u8 x; //hitbox's offset relative to the
- kit::u8 y; //object's actual position
- } /*---------*/ offset;
- kit::s16 x;
- kit::s16 y;
- struct {
- kit::u16 type : 14;
- kit::u16 persistent : 1; //'never reset this object's cached data?'
- kit::u16 in_front : 1; //to either display before player or after foreground
- };
- Object_TickCallback update; //called for every tick that the object is active
- };
- //--OBJECT 1--
- //do not use this object in a scene with more than 2 states
- //also, there can in theory be multiple 1lever(s) in a scene,
- //as long as they share the same values of scene_old&new
- struct _obj_1lever { //24B; 8x24px sprite
- kit::u16 scene_old; //2B
- kit::u16 scene_new; //2B
- kit::u16 sfx_id; //2B
- //-END OF INIT DATA-
- bool init; //1B
- bool flipped; //1B
- kit::Bitmap* img; //8B
- SoundEffect* sfx; //8B
- };
- //--OBJECT 2--
- //0 = shrink
- //1 = double jump
- //2 = speed
- struct _obj_ability { //24B; 24x24px sprite, 24 frames (spritesheet of 24x1)
- kit::u8 which; //1B
- //-END OF INIT DATA-
- bool init; //1B
- kit::u16 frameCounter; //2B
- kit::u32 _padding32; //4B
- kit::Bitmap* img; //8B
- bool* has_ability; //8B; ptr to bool that determines if ability is enabled
- };
- //--OBJECT 3--
- //0 = shrink
- //1 = double jump
- //2 = speed
- struct _obj_ability_remover { //24B; 24x24px sprite, spritesheet of 3x1
- kit::u8 which; //1B
- bool dontReset; //1B; disables resetting player scale back to 2 if .which == 0, etc.
- //-END OF INIT DATA-
- bool init; //1B
- kit::u8 _padding8; //1B
- kit::u32 _padding32; //4B
- kit::Bitmap* img; //8B
- bool* has_ability; //8B; ptr to bool that determines if ability is enabled
- };
- //--OBJECT 4--
- //(not specifying w or h results in the default of _obj_a->size.x/y being used!)
- struct _obj_generic_sprite { //16B
- kit::u16 which; //2B; objimg index
- kit::u8 w,h; //2B; width and height of source sprite (1B each)
- kit::u8 numFrames; //1B; <2 for no animation (static sprite)
- kit::u8 tick_delay; //1B; 'how many ticks per frame?' (ignored if num_frames < 2)
- //-END OF INIT DATA-
- bool init; //1B
- kit::u8 frameCounter; //1B
- kit::Bitmap* img; //8B
- };
- //--OBJECT 5--
- //if both pos_x&y are 0, text box will draw just above the collider
- //otherwise, if one of pos_x&y are 0, center their position based on axis
- struct _obj_msgbox { //24B
- kit::s16 pos_x, pos_y; //4B (2B each)
- kit::u16 which; //2B; gl_text_lines index
- bool show_always; //1B; always display box, instead of on player collide
- //-END OF INIT DATA-
- bool init; //1B
- kit::shape::point str_size; //8B
- const char* str; //8B
- };
- //--OBJECT 6--
- struct _obj_save_interface { //8B
- kit::u8 which; //1B; 0,1,2 = read,write,wipe
- bool passive; //1B; 'bypass need to interact with this object to activate it?'
- //-END OF INIT DATA-
- bool init; //1B
- bool touching; //1B; prevents invoking save function every tick
- kit::s32 box_height; //4B; used for saveWrite's visual effect
- };
- //--OBJECT 7--
- struct _obj_teleporter { //8B
- kit::s16 pos_x, pos_y; //4B; (2B each); where to teleport to on-screen
- kit::u16 scene; //2B; what scene to teleport to (0 for current scene)
- bool passive; //1B; 'bypass need to interact with this object to activate it?'
- //-END OF INIT DATA-
- bool init : 4; //4b
- bool touching : 4; //4b; prevents teleport every tick
- };
- //--OBJECT 8--
- struct _obj_death_zone { //17B
- //-END OF INIT DATA-
- kit::shape::rect collider; //16B
- bool init; // 1B
- };
- //--OBJECT 9--
- #pragma pack(push, 1)
- struct _obj_death_ball { //28B (the absolute maximum, so pack this struct!)
- kit::s16 b_x, b_y; //4B (2B each); waypoint b
- kit::f32 speed; //4B; how much to increment t_value by every tick
- kit::s16 a_x, a_y; //4B (2B each); waypoint a (this defaults to _obj_a->x&y)
- //-END OF INIT DATA-
- kit::u16 _padding16; //2B
- bool init; //1B
- kit::u8 frameCounter; //1B
- kit::Bitmap* img; //8B
- kit::f32 t_value; //4B; interpolation value; a->b->a = 0.0f->1.0f->2.0f
- };
- #pragma pack(pop)
- bool obj_1lever (Object* _obj_a, bool render_only); //1
- bool obj_ability (Object* _obj_a, bool render_only); //2
- bool obj_ability_remover(Object* _obj_a, bool render_only); //3
- bool obj_generic_sprite (Object* _obj_a, bool render_only); //4
- bool obj_msgbox (Object* _obj_a, bool render_only); //5
- bool obj_save_interface (Object* _obj_a, bool render_only); //6
- bool obj_teleporter (Object* _obj_a, bool render_only); //7
- bool obj_death_zone (Object* _obj_a, bool render_only); //8
- bool obj_death_ball (Object* _obj_a, bool render_only); //9
- #endif /* _OBJECT_HPP */
- /******************************************************************************/
- /******************************************************************************/
- //"kw32g\include\player.hpp":
- #ifndef _PLAYER_HPP
- #define _PLAYER_HPP
- #include <globals.hpp>
- struct Player { //80B
- SoundEffect* sfx_footstep = nullptr;
- SoundEffect* sfx_jumping = nullptr;
- SoundEffect* sfx_landing = nullptr;
- kit::shape::point pos; //the player's CENTER position, in pixels
- kit::shape::fpoint rem; //[position] rem[ainder]; (basically pos % 1)
- kit::shape::fpoint vel; //how many pixels to move pos by
- kit::shape::fpoint acc; //how many pixels to change vel by
- kit::u32 ticksInAir = 0; //game ticks, which are 1/4 a frame long (approx. 4.1ms)
- kit::f32 runningState = 0.0f; //current animation frame when running
- kit::f32 scale = PLAYER_SCALE;
- bool facingRight = true;
- bool visible = true;
- bool enforceMaxVel = true;
- bool confused = false;
- bool first_jmp = false;
- bool second_jmp = false;
- bool has_dbljmp = false;
- bool has_shrink = false;
- bool has_speed = false;
- bool going_left = false;
- bool going_right = false;
- bool dying = false;
- //player collider rect is the same as its blit rect for simplicity's sake
- inline kit::shape::rect getRect(){
- kit::shape::rect result;
- //&(~1) for locking size to a multiple of 2 pixels (for even division by 2)
- result.w = abs( RND(8.0f*scale) & (~1) );
- result.h = result.w;
- result.x = RND(pos.x) - result.w/2;
- result.y = RND(pos.y) - result.h/2;
- return result;
- }
- inline void resetAbilities(){
- has_dbljmp = false;
- has_shrink = false;
- has_speed = false;
- }
- inline bool addScale(kit::f32 scale_delta){ return setScale(scale+scale_delta); }
- inline void play_sfx_footstep(bool b=true){ if(sfx_footstep && b) sfx_footstep->play(); }
- inline void play_sfx_jumping (bool b=true){ if(sfx_jumping && b) sfx_jumping ->play(); }
- inline void play_sfx_landing (bool b=true){ if(sfx_landing && b) sfx_landing ->play(); }
- bool setScale(kit::f32 scale_new);
- kit::shape::rect blit(bool only_return_src_rect = false);
- void update();
- kit::shape::rect move(kit::f32 deltaX, kit::f32 deltaY);
- void kill();
- };
- #endif /* _PLAYER_HPP */
- /******************************************************************************/
- /******************************************************************************/
- //"kw32g\include\save.hpp":
- #ifndef _SAVE_HPP
- #define _SAVE_HPP
- #include <globals.hpp>
- void saveReadSystem();
- void saveWriteSystem();
- void saveWipeSystem();
- bool saveRead();
- void saveWrite();
- void saveWipe();
- #endif /* _SAVE_HPP */
- /******************************************************************************/
- /******************************************************************************/
- //"kw32g\include\text_lines.hpp":
- #ifndef TEXT_LINES_DEFINITION
- extern size_t gl_text_lines_len;
- extern const char* gl_text_lines[];
- #else
- size_t gl_text_lines_len;
- const char* gl_text_lines[] = {
- /*0*/ "\
- <INVALID TEXT ID>",
- /*1*/ "\
- Welcome to a demo\n\
- of the current\n\
- features in the\n\
- platformer!",
- /*2*/ "\
- You can use levers to change\n\
- the state of scenes",
- /*3*/ "\
- The shrink ability is used to\n\
- squeeze through tight gaps\n\
- (bound to the \"Z\" key)",
- /*4*/ "\
- The speed ability is used to uncap\n\
- the player's max horizontal speed\n\
- (bound to the \"X\" key)",
- /*5*/ "\
- These objects are used\n\
- to remove one of the\n\
- player's abilities",
- /*6*/ "\
- The double jump ability is\n\
- pretty self-explanatory",
- /*7*/ "\
- There are also teleporters!\n\
- Their usefulness is obvious",
- /*8*/ "\
- You can save your game\n\
- using this handy egg\n\
- (though you can use\n\
- any sprite for this)",
- /*9*/ "\
- Now you're thinking with portals",
- /*10*/ "\
- ~This water is deadly~",
- /*11*/ "\
- This thing also kills you\n\
- (big surprise, I know)",
- /*12*/ "\
- You can get softlocked\n\
- if you touch the shrink\n\
- ability remover (lol)",
- //(this must be here in order for the length
- //of this array to be properly calculated!)
- nullptr,
- };
- #endif /* TEXT_LINES_DEFINITION */
- /******************************************************************************/
- /******************************************************************************/
- //"kw32g\include\tile.hpp":
- #ifndef _TILE_HPP
- #define _TILE_HPP
- #include <globals.hpp>
- union Tile {
- kit::u16 value;
- struct {
- kit::u8 tile;
- kit::u8 collision;
- };
- struct {
- kit::u16 id : 7; //id of what tile to use
- kit::u16 tileset : 1; //whether to use tileset a or b
- kit::u16 collide_a : 1; //'collide with top-left 12x12 section of tile?'
- kit::u16 collide_b : 1; //'collide with top-right 12x12 section of tile?'
- kit::u16 collide_c : 1; //'collide with bottom-left 12x12 section of tile?'
- kit::u16 collide_d : 1; //'collide with bottom-right 12x12 section of tile?'
- kit::u16 platform : 1; //allow falling through top side of tile conditionally
- kit::u16 slippery : 1; //does tile have a lower friction coefficient?
- kit::u16 _unused : 1;
- kit::u16 pass : 1; //allow passing through tile (overrides collision)
- //(pass is always 0 inside the scene descriptor)
- };
- Tile( ) : value( 0) {}
- Tile(kit::u8 _lobyte) : value(0x0f00|_lobyte) {} //assumes full collision
- Tile(kit::u16 _value) : value( _value) {}
- Tile(kit::s32 _value) : value(0xffff& _value) {}
- };
- struct Object;
- //uncompressed scene data
- #define OBJ_RESET_VALUE 3 //# of deaths until non-persistent scene objects reset
- #define PATTERN_LEN (TILESIZ_X*TILESIZ_Y)
- #define CURRENT_SCENE_PTR (gl_scenes[gl_scene.scene])
- struct Scene { //2328B
- kit::Bitmap* bmp_bg = nullptr; //bitmap for background layer (references gl_backgrounds)
- Tile pat_mg[PATTERN_LEN]; //pattern for midground (collision) layer
- Tile pat_fg[PATTERN_LEN]; //pattern for foreground layer
- //(associated scene edges can be manipulated by game states)
- kit::u16 scene; //scene id for the current scene
- kit::u16 music = 0xFFFF; //music id; 0 for no change, -1 (65535) to stop
- kit::u16 ambience_a = 0xFFFF; //ambient track id a; 0 for no change, -1 to stop
- kit::u16 ambience_b = 0xFFFF; //ambient track id b; 0 for no change, -1 to stop
- kit::u16 tileset_a = 0; //1st associated tileset
- kit::u16 tileset_b = 0; //2nd associated tileset
- kit::u8 obj_reset = 0; //used to reset object properties between deaths
- bool repeat_bg = false; //'should bg repeat?' (stretches to screen otherwise)
- char _padding8[2];
- void drawBg();
- void drawTiles(bool drawForeground = false); //draws midground if false
- };
- //for storing the contents of a .ksd file (compressed scene data)
- #define KSD_MAGIC 0x4644536B //"kSDF"
- #define SD_FILELEN(_scene_desc) ((_scene_desc).dataSize+sizeof(SceneDescriptor))
- struct SceneDescriptor { //64B
- /*0x00*/ kit::u32 magic; //= 0x4644536B = "kSDF" (no null terminator)
- /*0x04*/ kit::u32 dataSize; //size of file in bytes, minus the header (which is always 64B)
- //offsets to array data in file (if nullptr, data is assumed to not be present!)
- //(also, objs[x].type refers to the index inside gl_objCallbacks used by the object.
- //each element of gl_objCallbacks is of type Object_TickCallback)
- /*0x08*/ Object* objs; //contains the original states of each object in the scene
- /*0x10*/ Tile* pat_mg; //pattern data is compressed using RLE, where the 1st element's .value
- /*0x18*/ Tile* pat_fg; //member is the run length, with the 2nd being the actual tile data
- struct {
- /*0x20*/ kit::u16 bmp_bg : 15; //associated background id
- /*0x21*/ kit::u16 repeat_bg : 1; //'should bg repeat?' (stretches to screen otherwise)
- };
- struct {
- /*0x22*/ kit::u16 objs_len : 15; //number of objects in scene
- /*0x23*/ kit::u16 visited : 1; //used to help determine if objects should reset on load
- };
- /*0x24*/ kit::u16 tileset_a; //1st associated tileset
- /*0x26*/ kit::u16 tileset_b; //2nd associated tileset
- /*0x28*/ kit::u16 edge_n; //scene id for north edge
- /*0x2A*/ kit::u16 edge_s; //scene id for south edge
- /*0x2C*/ kit::u16 edge_w; //scene id for west edge
- /*0x2E*/ kit::u16 edge_e; //scene id for east edge
- /*0x30*/ kit::u16 scene; //scene id for scene itself
- /*0x32*/ kit::u16 music; //music id; 0 for no change, -1 (65535) to stop
- /*0x34*/ kit::u16 ambience_a; //ambient track id a; 0 for no change, -1 to stop
- /*0x36*/ kit::u16 ambience_b; //ambient track id b; 0 for no change, -1 to stop
- /*0x38*/ kit::BinaryData* fileData = nullptr; //raw file data; appears as nullptr in file
- /*0x40*/ //... (array data is stored in order of: objs, pat_mg, and pat_fg)
- void unload();
- ~SceneDescriptor(){ unload(); }
- SceneDescriptor(){ kit::memory::set(this, 0, sizeof(SceneDescriptor)); }
- SceneDescriptor(kit::u16 scene_id);
- };
- #ifdef _DEBUG
- #include <stdio.h>
- #define printSceneDescHeader(_scene_id) _printSceneDescHeader(_scene_id)
- static inline void _printSceneDescHeader(kit::u16 scene_id){
- if(scene_id > gl_scenes_len) throw "scene_id out of range";
- SceneDescriptor* scene = gl_scenes[scene_id];
- printf("{\n");
- printf(" magic = \"%.4s\" (0x%08X)\n", (char*)&scene->magic, scene->magic);
- printf(" dataSize = %u\n", scene->dataSize);
- printf(" objs = %p\n", scene->objs);
- printf(" pat_mg = %p\n", scene->pat_mg);
- printf(" pat_fg = %p\n", scene->pat_fg);
- printf(" bmp_bg = %u\n", scene->bmp_bg);
- printf(" repeat_bg = %s\n", boolStr(scene->repeat_bg));
- printf(" objs_len = %u\n", scene->objs_len);
- printf(" visited = %s\n", boolStr(scene->visited));
- printf(" tileset_a = %u\n", scene->tileset_a);
- printf(" tileset_b = %u\n", scene->tileset_b);
- printf(" edge_n = %u\n", scene->edge_n);
- printf(" edge_s = %u\n", scene->edge_s);
- printf(" edge_w = %u\n", scene->edge_w);
- printf(" edge_e = %u\n", scene->edge_e);
- printf(" scene = %u\n", scene->scene);
- printf(" music = %u\n", scene->music);
- printf(" ambience_a = %u\n", scene->ambience_a);
- printf(" ambience_b = %u\n", scene->ambience_b);
- printf(" fileData = %p\n", scene->fileData);
- printf("}\n");
- }
- #else
- #define printSceneDescHeader(_scene_id)
- #endif /* _DEBUG */
- //(scene_id references gl_scenes, whose elements are of type SceneDescriptor*)
- void loadScene(kit::u16 scene_id);
- //swap the associations of two scenes, including the scene references themselves
- //(you should never swap out a scene for one that is already active,
- //as this will cause major edge association conflicts!)
- void swapScene(kit::u16 scene_id_old, kit::u16 scene_id_new);
- #endif /* _TILE_HPP */
- /******************************************************************************/
- /******************************************************************************/
- //"kw32g\asset_scripts\convert_all_ambience.py":
- _PRINT = True
- src_folder = '.\\_wav\\'
- dst_folder = '.\\_qoa\\'
- tst_folder = '.\\_test\\'
- def_prefix = '_opt_'
- from time import time
- from os import system as cmd, walk, path, chdir
- import subprocess
- def tryInt(string):
- try:
- return int(string)
- except ValueError:
- return None
- except TypeError:
- return None
- def run_program(args, fatal=False):
- if type(args) != list:
- print('args must be of type list')
- exit(-1)
- if _PRINT: print((' ').join(args))
- returnCode = subprocess.call(args, shell=True)
- if returnCode >= 2**31: returnCode -= 2**32
- if fatal:
- if returnCode != 0:
- if _PRINT: print(f'failed to execute "{args}"')
- exit(-1)
- return True
- else:
- return returnCode == 0
- def tryCmd(s):
- if _PRINT: print(s)
- cmd("powershell -command "+s)
- def convertPath(path, prefix = def_prefix):
- #assumes something like '0_opt_name.wav'
- id = tryInt(path.split(prefix)[0])
- if id == None:
- print(f'failed to get ambience id from "{path}"')
- exit(-1)
- return dst_folder + f'ambience_{id}.qoa'
- def main(cwd = None):
- if cwd != None: chdir(cwd)
- timeStart = time()
- tryCmd(f'rm {dst_folder}*.*')
- #assumes there are no folders in .\_wav\
- files = []
- for root, dirs, _files in walk(src_folder):
- files += _files
- for file in files:
- file_src = path.join(src_folder,file)
- file_dst = convertPath(file)
- file_tst = path.join(tst_folder,file)
- #first, convert all wavs to qoa
- run_program(['qoa_convert.exe', file_src, file_dst])
- #then, do the reverse to check its output for
- #any artifacts or 'rip headphone users' moments
- run_program(['qoa_convert.exe', file_dst, file_tst])
- print(f'AMBIENCE CONVERTED IN {time()-timeStart} SECONDS')
- if __name__ == '__main__':
- tryCmd("pause")
- exit(0)
- if __name__ == '__main__': main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement