/*+include\kit\_misc_time.hpp+*/ #ifndef _KIT_INC__MISC_TIME_HPP #define _KIT_INC__MISC_TIME_HPP #include "commondef.hpp" namespace kit { namespace time { u64 getTicks(); u64 getTicksPerSecond(); f64 getUptime(); void sleep(u32 milliseconds); }; }; #endif /* _KIT_INC__MISC_TIME_HPP */ /*-include\kit\_misc_time.hpp-*/ /*+include\kit\_video_Bitmap.hpp+*/ #ifndef _KIT_INC__VIDEO_BITMAP_HPP #define _KIT_INC__VIDEO_BITMAP_HPP #include "commondef.hpp" #include "_video_misc.hpp" namespace kit { struct _BitmapOpaque; class Bitmap { u32 _type; u32 _padding32; _BitmapOpaque* _opq = nullptr; bool _valid = false; public: u32 _getType(){ return _type; } _BitmapOpaque* _accessOpaque(){ return _opq; } //loads from memory Bitmap(const color::ARGB* pixelData, u32 width, u32 height, bool directAccess = false); //loads from file Bitmap(const char* fileName, u32 width, u32 height, bool directAccess = false); ~Bitmap(); }; }; #endif /* _KIT_INC__VIDEO_BITMAP_HPP */ /*-include\kit\_video_Bitmap.hpp-*/ /*+include\kit\_video_misc.hpp+*/ #ifndef _KIT_INC__VIDEO_MISC_HPP #define _KIT_INC__VIDEO_MISC_HPP #include "commondef.hpp" namespace kit { namespace color { //what GDI uses (save for the alpha channel) union ARGB { //4B; 0xAARRGGBB u32 v; //entire color [v]alue struct { u8 b; u8 g; u8 r; u8 a; }; ARGB() : v(0) {} ARGB(u32 _v) : v(_v) {} ARGB(u8 _r, u8 _g, u8 _b, u8 _a) : r(_r), g(_g), b(_b), a(_a) {} inline void operator=(const u32 cv){ v = cv; } inline bool operator==(const ARGB& c){ return (v == c.v); }; inline bool operator!=(const ARGB& c){ return (v != c.v); }; inline bool operator==(const u32& cv){ return (v == cv); }; inline bool operator!=(const u32& cv){ return (v != cv); }; }; union ABGR { //4B; 0xAABBGGRR u32 v; //entire color [v]alue struct { u8 r; u8 g; u8 b; u8 a; }; ABGR() : v(0) {} ABGR(u32 _v) : v(_v) {} ABGR(u8 _r, u8 _g, u8 _b, u8 _a) : r(_r), g(_g), b(_b), a(_a) {} inline void operator=(const u32 cv){ v = cv; } inline bool operator==(const ABGR& c){ return (v == c.v); }; inline bool operator!=(const ABGR& c){ return (v != c.v); }; inline bool operator==(const u32& cv){ return (v == cv); }; inline bool operator!=(const u32& cv){ return (v != cv); }; }; }; namespace shape { struct point { //8B s32 x, y; point() : x(0), y(0) {} point(s32 _x, s32 _y) : x(_x), y(_y) {} inline bool operator==(const point& p){ return (x==p.x && y==p.y); }; inline bool operator!=(const point& p){ return (x!=p.x && y!=p.y); }; }; struct rect { //16B s32 x, y; //x & y position of the rectangle's top-left corner s32 w, h; //the rectangle's width & height rect() : x(0), y(0), w(0), h(0) {} rect(s32 _x, s32 _y) : x(_x), y(_y) {} rect(s32 _x, s32 _y, s32 _w, s32 _h) : x(_x), y(_y), w(_w), h(_h) {} inline bool operator==(const rect& r){ return (x==r.x && y==r.y && w==r.w && h==r.h); }; inline bool operator!=(const rect& r){ return (x!=r.x && y!=r.y && w!=r.w && h!=r.h); }; }; struct line { //16B s32 x0, y0; s32 x1, y1; line() : x0(0), y0(0), x1(0), y1(0) {} line(s32 _x0, s32 _y0, s32 _x1, s32 _y1) : x0(_x0), y0(_y0), x1(_x1), y1(_y1) {} inline bool operator==(const line& l){ return (x0==l.x0 && y0==l.y0 && x1==l.x1 && y1==l.y1); }; inline bool operator!=(const line& l){ return (x0!=l.x0 && y0!=l.y0 && x1!=l.x1 && y1!=l.y1); }; }; struct fpoint { //8B f32 x, y; fpoint() : x(0.0f), y(0.0f) {} fpoint(f32 _x, f32 _y) : x(_x), y(_y) {} inline bool operator==(const fpoint& p){ return (x==p.x && y==p.y); }; inline bool operator!=(const fpoint& p){ return (x!=p.x && y!=p.y); }; }; struct frect { //16B f32 x, y; //x & y position of rectangle's top-left corner f32 w, h; //the rectangle's width & height frect() : x(0.0f), y(0.0f), w(0.0f), h(0.0f) {} frect(f32 _x, f32 _y) : x(_x), y(_y) {} frect(f32 _x, f32 _y, f32 _w, f32 _h) : x(_x), y(_y), w(_w), h(_h) {} inline bool operator==(const frect& r){ return (x==r.x && y==r.y && w==r.w && h==r.h); }; inline bool operator!=(const frect& r){ return (x!=r.x && y!=r.y && w!=r.w && h!=r.h); }; }; struct fline { //16B f32 x0, y0; f32 x1, y1; fline() : x0(0.0f), y0(0.0f), x1(0.0f), y1(0.0f) {} fline(f32 _x0, f32 _y0, f32 _x1, f32 _y1) : x0(_x0), y0(_y0), x1(_x1), y1(_y1) {} inline bool operator==(const fline& l){ return (x0==l.x0 && y0==l.y0 && x1==l.x1 && y1==l.y1); }; inline bool operator!=(const fline& l){ return (x0!=l.x0 && y0!=l.y0 && x1!=l.x1 && y1!=l.y1); }; }; struct dpoint { //16B f64 x, y; dpoint() : x(0.0), y(0.0) {} dpoint(f64 _x, f64 _y) : x(_x), y(_y) {} inline bool operator==(const dpoint& p){ return (x==p.x && y==p.y); }; inline bool operator!=(const dpoint& p){ return (x!=p.x && y!=p.y); }; }; struct drect { //32B f64 x, y; //x & y position of rectangle's top-left corner f64 w, h; //the rectangle's width & height drect() : x(0.0), y(0.0), w(0.0), h(0.0) {} drect(f64 _x, f64 _y) : x(_x), y(_y) {} drect(f64 _x, f64 _y, f64 _w, f64 _h) : x(_x), y(_y), w(_w), h(_h) {} inline bool operator==(const drect& r){ return (x==r.x && y==r.y && w==r.w && h==r.h); }; inline bool operator!=(const drect& r){ return (x!=r.x && y!=r.y && w!=r.w && h!=r.h); }; }; struct dline { //32B f64 x0, y0; f64 x1, y1; dline() : x0(0.0), y0(0.0), x1(0.0), y1(0.0) {} dline(f64 _x0, f64 _y0, f64 _x1, f64 _y1) : x0(_x0), y0(_y0), x1(_x1), y1(_y1) {} inline bool operator==(const dline& l){ return (x0==l.x0 && y0==l.y0 && x1==l.x1 && y1==l.y1); }; inline bool operator!=(const dline& l){ return (x0!=l.x0 && y0!=l.y0 && x1!=l.x1 && y1!=l.y1); }; }; }; }; #endif /* _KIT_INC__VIDEO_MISC_HPP */ /*-include\kit\_video_misc.hpp-*/ /*+include\kit\_video_Window.hpp+*/ #ifndef _KIT_INC__VIDEO_WINDOW_HPP #define _KIT_INC__VIDEO_WINDOW_HPP #include "commondef.hpp" #include "_video_misc.hpp" #include "_video_WindowEvent.hpp" namespace kit { enum WindowPositionEnum { WINPOS_UNDEFINED = 0xC0000000, WINPOS_CENTERED = 0xC0000001, WINPOS_UNCHANGED = 0xC0000002, }; //(some flags override others!) enum WindowFlagEnum { WINFLAG_HIDDEN = 0x01, // window is not visible WINFLAG_BORDERLESS = 0x02, // window lacks any decoration WINFLAG_RESIZABLE = 0x04, // window can be resized WINFLAG_MINIMIZED = 0x08, // window is minimized WINFLAG_MAXIMIZED = 0x10, // window is maximized WINFLAG_FOCUS = 0x20, // window has grabbed input focus WINFLAG_FULLSCREEN = 0x40, // window is in fullscreen mode (non-exclusive) }; struct _WindowOpaque; class Window { u32 _type; u32 _padding32; _WindowOpaque* _opq = nullptr; char _title[256]; bool _constructing = true; bool _valid = false; public: u32 _getType(){ return _type; } _WindowOpaque* _accessOpaque(){ return _opq; }; //don't touch this, seriously Window(const char* windowTitle, u32 windowWidth, u32 windowHeight, u32 windowFlags = 0, s32 windowX = WINPOS_UNDEFINED, s32 windowY = WINPOS_UNDEFINED, u32 canvasWidth = 0, u32 canvasHeight = 0, bool directAccess = false); ~Window(); bool isConstructing(){ return _constructing; } bool isValid(){ return _valid; } bool isClosed(); const char* getTitle(){ return _title; } shape::rect getWindowRect(); shape::point getCanvasSize(); color::ARGB* getPixels(); void setWindowRect(shape::rect* newRect); void setVisibility(bool showWindow = true); void setFocus(bool enable = true); void setFullscreen(bool enable); bool pollEvent(WindowEvent* event_p = nullptr); void lock(bool locked = true); void unlock(){ lock(false); } void present(); void clear(color::ARGB color = 0x00000000); }; }; #endif /* _KIT__VIDEO_WINDOW_HPP */ /*-include\kit\_video_Window.hpp-*/ /*+include\kit\_video_WindowEvent.hpp+*/ #ifndef _KIT_INC__VIDEO_WINDOWEVENT_HPP #define _KIT_INC__VIDEO_WINDOWEVENT_HPP #include "commondef.hpp" namespace kit { #define KIT_EVENT_ID(_id) ( (_id) & 0xffff0000 ) #define KIT_SUBEVENT_ID(_id) ( (_id) & 0xffff ) enum WindowEventEnum { WINEVENT_NULL = 0x00000000, WINEVENT_COMMON = 0x00010000, //WindowEvent_Common WINEVENT_WIN = 0x00020000, //WindowEvent_Win WINEVENT_WIN_CLOSE = WINEVENT_WIN | 0x0001, WINEVENT_WIN_MOVED = WINEVENT_WIN | 0x0002, WINEVENT_WIN_RESIZED = WINEVENT_WIN | 0x0003, WINEVENT_WIN_UNFOCUSING = WINEVENT_WIN | 0x0004, WINEVENT_WIN_FOCUSED = WINEVENT_WIN | 0x0005, WINEVENT_KEY = 0x00030000, //WindowEvent_Key WINEVENT_KEY_CHAR = WINEVENT_KEY | 0x0001, WINEVENT_KEY_UP = WINEVENT_KEY | 0x0002, WINEVENT_KEY_DOWN = WINEVENT_KEY | 0x0003, WINEVENT_MOUSE = 0x00040000, //WindowEvent_Mouse WINEVENT_MOUSE_MOVE = WINEVENT_MOUSE | 0x0001, WINEVENT_MOUSE_LEAVE = WINEVENT_MOUSE | 0x0002, //(not fully implemented) WINEVENT_MOUSE_ENTER = WINEVENT_MOUSE | 0x0003, //(not fully implemented) WINEVENT_MOUSE_UP = WINEVENT_MOUSE | 0x0004, WINEVENT_MOUSE_DOWN = WINEVENT_MOUSE | 0x0005, WINEVENT_MOUSE_HWHEEL = WINEVENT_MOUSE | 0x0006, WINEVENT_MOUSE_VWHEEL = WINEVENT_MOUSE | 0x0007, }; /*+WINEVENT_COMMON+*/ struct WindowEvent_Common { //16B u32 type; u32 winIndex; u64 timestamp; }; /*-WINEVENT_COMMON-*/ /*+WINEVENT_WIN+*/ struct WindowEvent_Win { //24B u32 type; u32 winIndex; u64 timestamp; union { s32 data1, dataX; }; union { s32 data2, dataY; }; }; /*-WINEVENT_WIN-*/ /*+WINEVENT_KEY+*/ enum WindowEvent_Key_ModifierEnum { KMOD_NONE = 0x0000, KMOD_LSHIFT = 0x0001, KMOD_RSHIFT = 0x0002, KMOD_LCTRL = 0x0004, KMOD_RCTRL = 0x0008, KMOD_LALT = 0x0010, KMOD_RALT = 0x0020, KMOD_LGUI = 0x0040, //windows key? KMOD_RGUI = 0x0080, // KMOD_LWIN = KMOD_LGUI, KMOD_RWIN = KMOD_RGUI, KMOD_NUMLOCK = 0x1000, KMOD_CAPSLOCK = 0x2000, KMOD_ALTGRAPH = 0x4000, KMOD_SCROLLOCK = 0x8000, KMOD_CTRL = ( KMOD_LCTRL | KMOD_RCTRL ), KMOD_SHIFT = ( KMOD_LSHIFT | KMOD_RSHIFT ), KMOD_ALT = ( KMOD_LALT | KMOD_RALT ), KMOD_GUI = ( KMOD_LGUI | KMOD_RGUI ), KMOD_WIN = ( KMOD_LWIN | KMOD_RWIN ), }; enum WindowEvent_Key_PhysicalEnum { //tbd }; enum WindowEvent_Key_VirtualEnum { //(misc. mouse) = 0x01 -> 0x06 //(reserved) = 0x07, VKEY_BACK = 0x08, //backspace key VKEY_BACKSPACE = VKEY_BACK, VKEY_TAB = 0x09, //(reserved) = 0x0A -> 0x0B, VKEY_CLEAR = 0x0C, VKEY_RETURN = 0x0D, //enter key VKEY_ENTER = VKEY_RETURN, //(unassigned) = 0x0E -> 0x0F, VKEY_SHIFT = 0x10, VKEY_CONTROL = 0x11, //ctrl key VKEY_CTRL = VKEY_CONTROL, VKEY_MENU = 0x12, //alt key VKEY_ALT = VKEY_MENU, VKEY_PAUSE = 0x13, VKEY_CAPITAL = 0x14, //caps lock key VKEY_CAPSLOCK = VKEY_CAPITAL, //(IME stuff) = 0x15 -> 0x1A, VKEY_ESCAPE = 0x1B, //esc key //(IME stuff) = 0x1C -> 0x1F, VKEY_SPACE = 0x20, //space bar key VKEY_PRIOR = 0x21, //page up key VKEY_PGUP = VKEY_PRIOR, VKEY_NEXT = 0x22, //page down key VKEY_PGDN = VKEY_NEXT, VKEY_END = 0x23, VKEY_HOME = 0x24, VKEY_LEFT = 0x25, //left arrow key VKEY_UP = 0x26, //up arrow key VKEY_RIGHT = 0x27, //right arrow key VKEY_DOWN = 0x28, //down arrow key VKEY_SELECT = 0x29, VKEY_PRINT = 0x2A, VKEY_EXECUTE = 0x2B, VKEY_SNAPSHOT = 0x2C, //print screen key VKEY_PRTSC = VKEY_SNAPSHOT, VKEY_INSERT = 0x2D, //ins key VKEY_DELETE = 0x2E, //del key VKEY_HELP = 0x2F, //help key VKEY_0 = 0x30, //'0' VKEY_1 = 0x31, //'1' VKEY_2 = 0x32, //'2' VKEY_3 = 0x33, //'3' VKEY_4 = 0x34, //'4' VKEY_5 = 0x35, //'5' VKEY_6 = 0x36, //'6' VKEY_7 = 0x37, //'7' VKEY_8 = 0x38, //'8' VKEY_9 = 0x39, //'9' //(undefined) = 0x3A -> 0x40, VKEY_A = 0x41, //'A' VKEY_B = 0x42, //'B' VKEY_C = 0x43, //'C' VKEY_D = 0x44, //'D' VKEY_E = 0x45, //'E' VKEY_F = 0x46, //'F' VKEY_G = 0x47, //'G' VKEY_H = 0x48, //'H' VKEY_I = 0x49, //'I' VKEY_J = 0x4A, //'J' VKEY_K = 0x4B, //'K' VKEY_L = 0x4C, //'L' VKEY_M = 0x4D, //'M' VKEY_N = 0x4E, //'N' VKEY_O = 0x4F, //'O' VKEY_P = 0x50, //'P' VKEY_Q = 0x51, //'Q' VKEY_R = 0x52, //'R' VKEY_S = 0x53, //'S' VKEY_T = 0x54, //'T' VKEY_U = 0x55, //'U' VKEY_V = 0x56, //'V' VKEY_W = 0x57, //'W' VKEY_X = 0x58, //'X' VKEY_Y = 0x59, //'Y' VKEY_Z = 0x5A, //'Z' VKEY_LWIN = 0x5B, //left windows key VKEY_RWIN = 0x5C, //right windows key VKEY_APPS = 0x5D, //applications key //(reserved) = 0x5E, VKEY_SLEEP = 0x5F, //computer sleep key VKEY_NUMPAD0 = 0x60, VKEY_NUMPAD1 = 0x61, VKEY_NUMPAD2 = 0x62, VKEY_NUMPAD3 = 0x63, VKEY_NUMPAD4 = 0x64, VKEY_NUMPAD5 = 0x65, VKEY_NUMPAD6 = 0x66, VKEY_NUMPAD7 = 0x67, VKEY_NUMPAD8 = 0x68, VKEY_NUMPAD9 = 0x69, VKEY_MULTIPLY = 0x6A, //numpad '*' VKEY_ADD = 0x6B, //numpad '+' VKEY_SEPARATOR = 0x6C, //numpad enter VKEY_SUBTRACT = 0x6D, //numpad '-' VKEY_DECIMAL = 0x6E, //numpad '.' VKEY_DIVIDE = 0x6F, //numpad '/' VKEY_F1 = 0x70, VKEY_F2 = 0x71, VKEY_F3 = 0x72, VKEY_F4 = 0x73, VKEY_F5 = 0x74, VKEY_F6 = 0x75, VKEY_F7 = 0x76, VKEY_F8 = 0x77, VKEY_F9 = 0x78, VKEY_F10 = 0x79, VKEY_F11 = 0x7A, VKEY_F12 = 0x7B, VKEY_F13 = 0x7C, VKEY_F14 = 0x7D, VKEY_F15 = 0x7E, VKEY_F16 = 0x7F, VKEY_F17 = 0x80, VKEY_F18 = 0x81, VKEY_F19 = 0x82, VKEY_F20 = 0x83, VKEY_F21 = 0x84, VKEY_F22 = 0x85, VKEY_F23 = 0x86, VKEY_F24 = 0x87, //(reserved) = 0x88 -> 0x8F, VKEY_NUMLOCK = 0x90, VKEY_SCROLL = 0x91, //scroll lock key VKEY_SCROLLOCK = VKEY_SCROLL, //(OEM-specific) = 0x92 -> 0x96, //(unassigned) = 0x97 -> 0x9F, //(l/r key variants) = 0xA0 -> 0xA5, //(browser keys) = 0xA6 -> 0xAC, VKEY_VOLUME_MUTE = 0xAD, VKEY_VOLUME_DOWN = 0xAE, VKEY_VOLUME_UP = 0xAF, VKEY_MEDIA_NEXT_TRACK = 0xB0, VKEY_MEDIA_PREV_TRACK = 0xB1, VKEY_MEDIA_STOP = 0xB2, VKEY_MEDIA_PLAY_PAUSE = 0xB3, //Play/Pause Media key //(launch keys) = 0xB4 -> 0xB7, //(reserved) = 0xB8 -> 0xB9, VKEY_OEM_1 = 0xBA, //misc. chars; varies by keyboard (';',':' on US standard) VKEY_SEMICOLON = VKEY_OEM_1, VKEY_OEM_PLUS = 0xBB, //'+' in any country/region VKEY_PLUS = VKEY_OEM_PLUS, VKEY_OEM_COMMA = 0xBC, //',' in any country/region VKEY_COMMA = VKEY_OEM_COMMA, VKEY_OEM_MINUS = 0xBD, //'-' in any country/region VKEY_MINUS = VKEY_OEM_MINUS, VKEY_OEM_PERIOD = 0xBE, //'.' in any country/region VKEY_PERIOD = VKEY_OEM_PERIOD, VKEY_OEM_2 = 0xBF, //misc. chars; varies by keyboard ('/','?' on US standard) VKEY_FSLASH = VKEY_OEM_2, VKEY_OEM_3 = 0xC0, //misc. chars; varies by keyboard ('`','~' on US standard) VKEY_BACKTICK = VKEY_OEM_3, //(reserved) = 0xC1 -> 0xDA, VKEY_OEM_4 = 0xDB, //misc. chars; varies by keyboard ('[','{' on US standard) VKEY_LBRACKET = VKEY_OEM_4, VKEY_OEM_5 = 0xDC, //misc. chars; varies by keyboard ('\\','|' on US standard) VKEY_BSLASH = VKEY_OEM_5, VKEY_OEM_6 = 0xDD, //misc. chars; varies by keyboard (']','}' on US standard) VKEY_RBRACKET = VKEY_OEM_6, VKEY_OEM_7 = 0xDE, //misc. chars; varies by keyboard ('\'','\"' on US standard) VKEY_APOSTROPHE = VKEY_OEM_7, VKEY_OEM_8 = 0xDF, //misc. chars; varies by keyboard //(reserved) = 0xE0, //(misc.) = 0xE1 -> 0xE7, //(unassigned) = 0xE8, //(misc.) = 0xE9 -> 0xFE, }; union WindowEvent_Key_Mod { //2B struct { u16 lshift : 1; u16 rshift : 1; u16 lctrl : 1; u16 rctrl : 1; u16 lalt : 1; u16 ralt : 1; u16 lgui : 1; u16 rgui : 1; u16 _unused : 4; u16 numlock : 1; u16 capslock : 1; u16 altgraph : 1; u16 scrollock : 1; }; u16 all; }; struct WindowEvent_Key_Sym { //8B union { WindowEvent_Key_Mod kmod; u16 kmods; }; u8 _unused; u8 pkey; //physical key code (named .scancode in SDL's Keysym struct) u8 vkey; //virtual key code (named .sym in SDL's Keysym struct) bool pressed; bool ischar; //'is event KEY_CHAR?', otherwise it's KEY_UP or KEY_DOWN bool repeat; }; struct WindowEvent_Key { //24B u32 type; u32 winIndex; u64 timestamp; union { struct { //(basically a copy of WindowEvent_Key_Sym) u16 kmods; u8 _unused; u8 pkey; u8 vkey; bool pressed; bool ischar; bool repeat; }; WindowEvent_Key_Sym sym; }; }; /*-WINEVENT_KEY-*/ /*+WINEVENT_MOUSE+*/ //how many steps between mouse wheel notches #define KIT_MOUSE_WHEEL_DELTA (120) enum WindowEvent_Mouse_ButtonEnum { MBUTTON_LEFT = 0x01, MBUTTON_MIDDLE = 0x02, MBUTTON_RIGHT = 0x04, MBUTTON_X1 = 0x08, MBUTTON_X2 = 0x10, }; struct WindowEvent_Mouse { //40B u32 type; u32 winIndex; u64 timestamp; s32 x; //coordinates relative to window s32 y; //^^ s32 dx; //delta x (coordinates relative to last recorded x position) s32 dy; //delta y (coordinates relative to last recorded y position) s32 data; //currently used to store the value of wheel events before delta is applied u8 _unused; u8 button; //flags for currently pressed buttons (WindowEvent_Mouse_ButtonEnum) bool pressed; //will be true if button is nonzero bool dblClick; //'is double click?' }; /*-WINEVENT_MOUSE-*/ union WindowEvent { //B u32 type; WindowEvent_Common common; WindowEvent_Win win; WindowEvent_Key key; WindowEvent_Mouse mouse; WindowEvent() : type(WINEVENT_NULL) {} }; }; #endif /* _KIT_INC__VIDEO_WINDOWEVENT_HPP */ /*-include\kit\_video_WindowEvent.hpp-*/ /*+include\kit\all.hpp+*/ #ifndef _KIT_INC_ALL_HPP #define _KIT_INC_ALL_HPP #include "commondef.hpp" #include "misc.hpp" #include "video.hpp" #endif /* _KIT_INC_ALL_HPP */ /*-include\kit\all.hpp-*/ /*+include\kit\commondef.hpp+*/ #ifndef _KIT_INC_COMMONDEF_HPP #define _KIT_INC_COMMONDEF_HPP namespace kit { #ifndef MIN #define MIN(a,b) ( ((a)<(b)) ? (a) : (b) ) #endif /* MIN(a,b) */ #ifndef MAX #define MAX(a,b) ( ((a)>(b)) ? (a) : (b) ) #endif /* MAX(a,b) */ #ifndef CLAMP #define CLAMP(n, mn, mx) MIN(MAX(n,mn),mx) #endif /* CLAMP(n, mn, mx) */ // integer bounds #define KIT_U8_MAX (0xff) #define KIT_U16_MAX (0xffff) #define KIT_U32_MAX (0xffffffff) #define KIT_U64_MAX (0xffffffffffffffff) // #define KIT_S8_MIN (-0x80) #define KIT_S8_MAX ( 0x7f) #define KIT_S16_MIN (-0x8000) #define KIT_S16_MAX ( 0x7fff) #define KIT_S32_MIN (-0x80000000) #define KIT_S32_MAX ( 0x7fffffff) #define KIT_S64_MIN (-0x8000000000000000) #define KIT_S64_MAX ( 0x7fffffffffffffff) // most significant bits/Bytes #define KIT_MSb_8 (0x80) #define KIT_MSb_16 (0x8000) #define KIT_MSb_32 (0x80000000) #define KIT_MSb_64 (0x8000000000000000) // #define KIT_MSB_8 (0xff) #define KIT_MSB_16 (0xff00) #define KIT_MSB_32 (0xff000000) #define KIT_MSB_64 (0xff00000000000000) #if defined(_STDINT) || defined(_CSTDINT_) typedef uint8_t u8 ; typedef uint16_t u16; typedef uint32_t u32; typedef uint64_t u64; typedef int8_t s8 ; typedef int16_t s16; typedef int32_t s32; typedef int64_t s64; #else typedef unsigned char u8 ; typedef unsigned short u16; typedef unsigned int u32; typedef unsigned long long u64; typedef signed char s8 ; typedef signed short s16; typedef signed int s32; typedef signed long long s64; #endif // for consistency typedef float f32; typedef double f64; typedef void* _GenericOpaquePtr; }; #endif /* _KIT_INC_COMMONDEF_HPP */ /*-include\kit\commondef.hpp-*/ /*+include\kit\misc.hpp+*/ #ifndef _KIT_INC_VIDEO_MISC_HPP #define _KIT_INC_VIDEO_MISC_HPP #include "commondef.hpp" #include "_misc_Mutex.hpp" #include "_misc_time.hpp" #endif /* _KIT_INC_VIDEO_MISC_HPP */ /*-include\kit\misc.hpp-*/ /*+include\kit\video.hpp+*/ #ifndef _KIT_INC_VIDEO_HPP #define _KIT_INC_VIDEO_HPP #include "commondef.hpp" #include "_video_misc.hpp" #include "_video_Window.hpp" #include "_video_Bitmap.hpp" #endif /* _KIT_INC_VIDEO_HPP */ /*-include\kit\video.hpp-*/ /*+src\kit_win32\_kit_globals.hpp+*/ #ifndef _KIT_SRC_KIT_GLOBALS_HPP #define _KIT_SRC_KIT_GLOBALS_HPP /* tbd: bitmap stuff when blitting, allow for nullptr rect so that the entire thing can be copied (also, add separate 'blitAll' function that uses only a destination position) */ #include #include #include #ifdef _DEBUG #define _printf(_fmt,...) printf(_fmt,__VA_ARGS__) #else #define _printf(_fmt,...) #endif #if defined(_DEBUG) #include #define loghere printf("line %4i: (%s)\n",__LINE__,__FILE__); #else #define loghere /* do {} while(0); */ #endif /* _DEBUG */ #define KIT_LOCK_SPINCOUNT (2048) //used for Window and Bitmap #define KIT_INITIAL_STRETCH_MODE COLORONCOLOR //class type ID numbers #define KIT_CONTAINS_OPAQUE (0x80000000) #define KIT_CLASSTYPE_NULL (0) #define KIT_CLASSTYPE_MUTEXSIMPLE (1 | KIT_CONTAINS_OPAQUE) #define KIT_CLASSTYPE_WINDOW (2 | KIT_CONTAINS_OPAQUE) #define KIT_CLASSTYPE_BITMAP (3 | KIT_CONTAINS_OPAQUE) namespace kit { /*++++++++++*/ /*+kit_main+*/ /*++++++++++*/ namespace w32 { extern HINSTANCE hThisInst; extern HINSTANCE hPrevInst; extern LPSTR lpszArg; extern int nCmdShow; extern LARGE_INTEGER ticksPerSecond; //used in time::getTicksPerSecond() }; /*++++++++++*/ /*+kit_main+*/ /*++++++++++*/ }; #endif /* _KIT_SRC_KIT_GLOBALS_HPP */ /*-src\kit_win32\_kit_globals.hpp-*/ /*+src\kit_win32\kit_Bitmap_shared.hpp+*/ #ifndef _KIT_SRC_KIT_BITMAP_SHARED_HPP #define _KIT_SRC_KIT_BITMAP_SHARED_HPP #include "_kit_globals.hpp" namespace kit { /*++++++++++++*/ /*+kit_Bitmap+*/ /*++++++++++++*/ struct _BitmapOpaque { BITMAPINFO info; HBITMAP handle; color::ARGB* pixels; shape::point size; HDC devCtx; s32 stretchMode; //stretch mode when used as blit destination u8 _unused[3]; //false for CreateDIBitmap() bitmap, true for CreateDIBSection() bitmap bool directAccess; }; //returns true on success static inline bool PopulateBitmapOpaque(_BitmapOpaque& bmp, const color::ARGB* pixelData, s32 width, s32 height, bool directAccess) { //fill in internal bitmap info bmp.info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmp.info.bmiHeader.biWidth = width; bmp.info.bmiHeader.biHeight = height; bmp.info.bmiHeader.biPlanes = 1; //should always be 1 bmp.info.bmiHeader.biBitCount = 32; //for 0x--RRGGBB bmp.info.bmiHeader.biCompression = BI_RGB; //uncompressed rgb bmp.pixels = nullptr; bmp.size.x = width; bmp.size.y = height; //create the bitmap's device context (for rendering directly to the bitmap) bmp.stretchMode = KIT_INITIAL_STRETCH_MODE; //determines whether you can edit the bitmap color data directly bmp.directAccess = directAccess; bmp.devCtx = CreateCompatibleDC(nullptr); if(bmp.devCtx == nullptr) return false; if(directAccess){ bmp.handle = CreateDIBSection(nullptr, &bmp.info, DIB_RGB_COLORS, (void**)&bmp.pixels, nullptr, 0); if(pixelData!=nullptr && bmp.pixels!=nullptr) memcpy(bmp.pixels, pixelData, sizeof(color::ARGB)*width*height); } else { bmp.handle = CreateDIBitmap(nullptr, (BITMAPINFOHEADER*)&bmp.info, (pixelData != nullptr) ? CBM_INIT : 0, pixelData, &bmp.info, DIB_RGB_COLORS); } if(bmp.handle != nullptr){ SelectObject(bmp.devCtx, bmp.handle); SetStretchBltMode(bmp.devCtx, KIT_INITIAL_STRETCH_MODE); return true; } else { DeleteDC(bmp.devCtx); bmp.devCtx = nullptr; return false; } } static inline bool ResizeBitmapOpaque(_BitmapOpaque& bmp, s32 width, s32 height) { //set dimensions of bitmap to new values bmp.size.x = width; bmp.size.y = height; //working with shape::point is a lot prettier than... bmp.info.bmiHeader.biWidth = width; //...whatever this is bmp.info.bmiHeader.biHeight = height; //delete old bitmap if(bmp.handle != nullptr) DeleteObject(bmp.handle); //create new bitmap if(bmp.directAccess){ bmp.handle = CreateDIBSection(nullptr, &bmp.info, DIB_RGB_COLORS, (void**)&bmp.pixels, nullptr, 0); } else { bmp.handle = CreateDIBitmap(nullptr, (BITMAPINFOHEADER*)&bmp.info, 0, nullptr, &bmp.info, DIB_RGB_COLORS); } //bind device context to new bitmap SelectObject(bmp.devCtx, bmp.handle); return true; } /*------------*/ /*-kit_Bitmap-*/ /*------------*/ }; #endif /* _KIT_SRC_KIT_BITMAP_SHARED_HPP */ /*-src\kit_win32\kit_Bitmap_shared.hpp-*/ /*+src\kit_win32\kit_Window_shared.hpp+*/ #ifndef _KIT_SRC_KIT_WINDOW_SHARED_HPP #define _KIT_SRC_KIT_WINDOW_SHARED_HPP #include #include "_kit_globals.hpp" #include "kit_Bitmap_shared.hpp" namespace kit { union WindowEvent; /*++++++++++++*/ /*+kit_Window+*/ /*++++++++++++*/ namespace w32 { extern u32 winCount; //number of existing kit::Window instances extern const char winClassName[]; extern WNDCLASSEXA winClass; extern ATOM winClassAtom; }; struct _WindowOpaque { CRITICAL_SECTION lock; //eventQueueEnd indicates what index should be queued to next, //while eventQueueNext indicates what index should be dequeued next //(if they are the same, that means the queue is empty!) WindowEvent* eventQueue; u16 eventQueueNext; u16 eventQueueEnd; u32 winIndex; HWND winHandle; shape::rect winRect; //contains both window position, and window size DWORD winFlags; DWORD winFlagsEx; bool winFullscreen; bool winShown; bool winFocus; bool winClosed; //true if window has been destroyed, false otherwise WindowEvent_Key_Mod kmod; //key modifier flags for key events (shift, ctrl, ...) //set to true after first WINEVENT_MOUSE_MOVE since entering client area bool mouseWasMovedBefore; bool canvasStretch; //if false, canvas is resized alongside window _BitmapOpaque canvas; shape::point mousePosition; bool keyStates[256]; //true if a virtual key code's key is currently pressed }; /*------------*/ /*-kit_Window-*/ /*------------*/ /*+++++++++++++++++++++++*/ /*+kit_Window_WindowProc+*/ /*+++++++++++++++++++++++*/ namespace w32 { extern LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM); }; /*-----------------------*/ /*-kit_Window_WindowProc-*/ /*-----------------------*/ static inline shape::rect ConvertToKitRect(RECT& rectIn){ shape::rect rectOut; rectOut.x = rectIn.left; rectOut.y = rectIn.top; rectOut.w = rectIn.right - rectIn.left; rectOut.h = rectIn.bottom - rectIn.top; return rectOut; } static inline RECT ConvertFromKitRect(shape::rect& rectIn){ RECT rectOut; rectOut.left = rectIn.x; rectOut.top = rectIn.y; rectOut.right = rectIn.x + rectIn.w; rectOut.bottom = rectIn.y + rectIn.h; return rectOut; } //assumes window is without a menu static inline shape::point CalculateWindowSize(u32 innerWidth, u32 innerHeight, u32 flags, u32 flagsEx) { RECT winSize; winSize.left = 0; winSize.top = 0; winSize.right = innerWidth; winSize.bottom = innerHeight; AdjustWindowRectEx(&winSize, flags, false, flagsEx); shape::point winSizeAdjusted; winSizeAdjusted.x = winSize.right - winSize.left; winSizeAdjusted.y = winSize.bottom - winSize.top; return winSizeAdjusted; } static inline void HandlePreCreationWindowFlags(_WindowOpaque* opq, u32 kitWinFlags) { //pre-creation window flag handling (save for WINFLAG_FULLSCREEN) opq->winFlags = WS_OVERLAPPEDWINDOW; //will be hidden initially opq->winFlagsEx = 0; if(kitWinFlags & WINFLAG_FULLSCREEN) opq->winFullscreen = true; if(kitWinFlags & WINFLAG_BORDERLESS){ kitWinFlags &= ~WINFLAG_RESIZABLE; opq->winFlags |= WS_POPUP; opq->winFlags &= ~WS_CAPTION; opq->winFlags &= ~WS_SYSMENU; } if(!(kitWinFlags & WINFLAG_RESIZABLE)) opq->winFlags &= ~WS_THICKFRAME; if(kitWinFlags & WINFLAG_MINIMIZED) opq->winFlags |= WS_MINIMIZE; if(kitWinFlags & WINFLAG_MAXIMIZED) opq->winFlags |= WS_MAXIMIZE; } //returns false if queue is full static inline bool AddToEventQueue(_WindowOpaque* opq, WindowEvent& event){ if((opq->eventQueueEnd+1) != opq->eventQueueNext){ opq->eventQueue[opq->eventQueueEnd++] = event; return true; } else { //don't add to queue if doing so would overwrite a previous event return false; } } //returns a WINEVENT_NULL event if queue is empty static inline WindowEvent RemoveFromEventQueue(_WindowOpaque* opq){ if(opq->eventQueueNext != opq->eventQueueEnd){ return opq->eventQueue[opq->eventQueueNext++]; } else { static WindowEvent nullEvent; //should auto-initialize to type WINEVENT_NULL return nullEvent; } } }; #endif /* _KIT_SRC_KIT_WINDOW_SHARED_HPP */ /*-src\kit_win32\kit_Window_shared.hpp-*/ /*+src\kit_win32\kit_Window_WindowProcEvent.hpp+*/ #ifndef _KIT_SRC_KIT_WINDOW_WINDOWPROCEVENT_HPP #define _KIT_SRC_KIT_WINDOW_WINDOWPROCEVENT_HPP #include #include "_kit_globals.hpp" //(the WindowEvent used inside WindowProc is named "event") #define KIT_HANDLE_EVENT(_name,...) \ kit::WindowProcEvent::_name(event,__VA_ARGS__) namespace kit { namespace WindowProcEvent { /*+WINEVENT_WIN+*/ //triggered when a window requests to be closed static inline void WIN_CLOSE(WindowEvent& event){ event.type = WINEVENT_WIN_CLOSE; } static inline void WIN_MOVED(WindowEvent& event, shape::rect& newRect){ event.type = WINEVENT_WIN_MOVED; //(dataX&Y are unioned with data1&2) event.win.dataX = newRect.x; //new horizontal position event.win.dataY = newRect.y; //new vertical position } static inline void WIN_RESIZED(WindowEvent& event, shape::rect& newRect){ event.type = WINEVENT_WIN_RESIZED; //(dataX&Y are unioned with data1&2) event.win.dataX = newRect.w; //new width event.win.dataY = newRect.h; //new height } static inline void WIN_UNFOCUSING(WindowEvent& event){ event.type = WINEVENT_WIN_UNFOCUSING; } static inline void WIN_FOCUSED(WindowEvent& event){ event.type = WINEVENT_WIN_FOCUSED; } /*-WINEVENT_WIN-*/ /*+WINEVENT_KEY+*/ union KEY_Params { struct { u32 repeatCount : 16; // 0 -> 15 u32 scanCode : 8; //16 -> 23 u32 extendedKey : 1; //24 u32 _reserved : 4; //25 -> 28 u32 altKeyDown : 1; //29 u32 prevUnpressed : 1; //30 u32 currUnpressed : 1; //31 }; u32 value; KEY_Params(u32 _value) : value(_value) {} }; //this event handler is used for KEY_CHAR, KEY_UP, and KEY_DOWN events static inline void KEY_CHARUPDOWN(WindowEvent& event, bool charEvent, u8 virtualKeyCode, KEY_Params& params, u16 kmods) { if(charEvent){ event.type = WINEVENT_KEY_CHAR; } else { if(params.currUnpressed) event.type = WINEVENT_KEY_UP; else event.type = WINEVENT_KEY_DOWN; } event.key.kmods = kmods; event.key.pkey = params.scanCode; event.key.vkey = virtualKeyCode; event.key.pressed = !params.currUnpressed; event.key.repeat = params.repeatCount>0; //modified to act as a boolean event.key.ischar = charEvent; } /*-WINEVENT_KEY-*/ /*+WINEVENT_MOUSE+*/ union MOUSE_ButtonStates { struct { u8 left : 1; u8 middle : 1; u8 right : 1; u8 x1 : 1; u8 x2 : 1; u8 _unused : 3; }; u8 value; MOUSE_ButtonStates() : value(0) {} MOUSE_ButtonStates(u8 _value) : value(_value) {} }; //MOUSE_MOVED was already taken by a win32 macro >:( static inline void MOUSE_MOVE(WindowEvent& event, u8 buttonStates, shape::point& previous, shape::point& current) { event.type = WINEVENT_MOUSE_MOVE; event.mouse.x = current.x; event.mouse.y = current.y; event.mouse.dx = current.x - previous.x; event.mouse.dy = current.y - previous.y; event.mouse.button = buttonStates; event.mouse.pressed = buttonStates!=0; } static inline void MOUSE_LEAVE(WindowEvent& event){ event.type = WINEVENT_MOUSE_LEAVE; } static inline void MOUSE_ENTER(WindowEvent& event){ event.type = WINEVENT_MOUSE_ENTER; } //same event handler is used for both MOUSE_UP and MOUSE_DOWN events static inline void MOUSE_UPDOWN(WindowEvent& event, shape::point& clickPosition, u8 buttonStates, bool pressed, bool doubleClick) { if(pressed) event.type = WINEVENT_MOUSE_DOWN; else event.type = WINEVENT_MOUSE_UP; event.mouse.x = clickPosition.x; event.mouse.y = clickPosition.y; event.mouse.button = buttonStates; event.mouse.pressed = pressed; event.mouse.dblClick = doubleClick; } //same event handler is used for both MOUSE_HWHEEL and MOUSE_VWHEEL events static inline void MOUSE_HVWHEEL(WindowEvent& event, bool verticalScroll, s16 scrollAmount, u8 buttonStates, shape::point& mousePos) { if(verticalScroll){ event.type = WINEVENT_MOUSE_VWHEEL; event.mouse.dy = scrollAmount/WHEEL_DELTA; } else { event.type = WINEVENT_MOUSE_HWHEEL; event.mouse.dx = scrollAmount/WHEEL_DELTA; } event.mouse.x = mousePos.x; event.mouse.y = mousePos.y; event.mouse.data = scrollAmount; //the scroll value before delta is applied event.mouse.button = buttonStates; event.mouse.pressed = buttonStates!=0; } /*-WINEVENT_MOUSE-*/ }; /* WindowProcEvent */ }; /* namespace kit */ #endif /* _KIT_SRC_KIT_WINDOW_WINDOWPROCEVENT_HPP */ /*-src\kit_win32\kit_Window_WindowProcEvent.hpp-*/