codepad
[
create a new paste
]
login
|
about
Language:
C
C++
D
Haskell
Lua
OCaml
PHP
Perl
Plain Text
Python
Ruby
Scheme
Tcl
// // 誰が得するのかわからない "キャラクタ・グラフィック・ライブラリ" // + どこかで見たようなOS風 by ミングスレの名無し // // 名称: vip32API // バージョン: 0.2 // 用途目的: 特になし // 使用方法: main以下を見ると吉 // // もうちょいまとまったら sourceforge にうpするつもり // //#define WINDOWS #define ONLINE_COMPILER #include <memory> #include <vector> #include <string> #include <queue> #include <cstdlib> #ifdef WINDOWS #define CLS "cls" #else #define CLS "reset" #endif #define PIXEL_CHARACTER char typedef unsigned char byte; typedef unsigned int uint; // -------------------------------------------- 固有事情を鑑みて自前スマポ template<typename T> struct Auto_Ptr { T *ptr; Auto_Ptr(): ptr(0) {} Auto_Ptr(T *p): ptr(p) {} Auto_Ptr(const Auto_Ptr& base) { ptr = base.ptr; const_cast<Auto_Ptr*>(&base)->ptr = NULL; } ~Auto_Ptr() { if(ptr) delete ptr; } T* operator->() { return ptr; } T& operator=(const Auto_Ptr& right) { ptr = right.ptr; const_cast<Auto_Ptr*>(&right)->ptr = NULL; return *ptr; } }; // -------------------------------------------- 最も基本的なBMPならぬ"C"MPサーフェス #define _GET(cm,x,y) (cm).buff[(x)+(y)*((cm)._w)] #define _SET(cm,x,y,v) (cm).buff[(x)+(y)*((cm)._w)] = (v) #define _VALID_X(cm,x) ((x)>=0 && (x)<(cm)._w) #define _VALID_Y(cm,y) ((y)>=0 && (y)<(cm)._h) class DrawCtrl; template<typename _BASE_TYPE> class _Surface { friend class DrawCtrl; private: struct { _BASE_TYPE *buff; _BASE_TYPE space; int _w, _h; } cm; void make(int w, int h); void merge(const _Surface &sur, _BASE_TYPE sp); public: int x, y; _Surface(): x(0), y(0) { cm.buff = cm._w = cm._h = 0; } _Surface(int w, int h, _BASE_TYPE spc): x(0), y(0) { cm.space = spc; make(w, h); } ~_Surface() { delete [] cm.buff; } _Surface& operator+=(const _Surface& sur); _Surface& operator*=(const _Surface& sur); }; template<typename _BASE_TYPE> void _Surface<_BASE_TYPE>::make(int w, int h) { cm._w = w; cm._h = h; uint sz = w * h + 1; cm.buff = new _BASE_TYPE[sz]; memset(cm.buff, cm.space, sizeof(_BASE_TYPE) * sz); } template<typename _BASE_TYPE> void _Surface<_BASE_TYPE>::merge(const _Surface<_BASE_TYPE> &sur, _BASE_TYPE sp) { for(int yy = 0; yy < sur.cm._h; ++yy) { for(int xx = 0; xx < sur.cm._w; ++xx) { int px = sur.x + xx; int py = sur.y + yy; if( !_VALID_X(cm, px) || !_VALID_Y(cm, py) || (sp != _BASE_TYPE(0) && _GET(sur.cm, xx, yy) == sp) ) continue; _SET(cm, px, py, _GET(sur.cm, xx, yy)); } } } // 基本的な重ね合わせだけサポート:上書き template<typename _BASE_TYPE> _Surface<_BASE_TYPE>& _Surface<_BASE_TYPE>::operator+=(const _Surface<_BASE_TYPE>& sur) { this->merge(sur, _BASE_TYPE(0)); return *this; } // 基本的な重ね合わせだけサポート:透過合成 template<typename _BASE_TYPE> _Surface<_BASE_TYPE>& _Surface<_BASE_TYPE>::operator*=(const _Surface<_BASE_TYPE>& sur) { this->merge(sur, cm.space); return *this; } // -------------------------------------------- ちょっと迷う。設計的に #define VIDEO_WIDTH 20 #define VIDEO_HEIGHT 20 #define C_SPC 32 typedef PIXEL_CHARACTER _BaseType; typedef _Surface<_BaseType> Surface; typedef Auto_Ptr<Surface> _PSurface; typedef Surface* HSURFACE; class DrawCtrl; typedef Auto_Ptr<DrawCtrl> HDC; class DrawCtrl { private: std::vector<_PSurface> _sur; _PSurface _vram; HSURFACE create(uint w, uint h, _BaseType spc) { Surface *sur = new Surface(w, h, spc); _sur.push_back(_PSurface(sur)); return _sur.back().ptr; } public: DrawCtrl() { _vram = _PSurface(new Surface(VIDEO_WIDTH, VIDEO_HEIGHT, C_SPC)); } HSURFACE getPrimarySurface() { return _vram.ptr; } HSURFACE createSurface(uint w, uint h) { return create(w, h, C_SPC); } HSURFACE createCompatibleSurface(HSURFACE base) { if(base == NULL) base = _vram.ptr; return create(base->cm._w, base->cm._h, base->cm.space); } void clear(); void paint(); void textOut(HSURFACE sur, int x, int y, const _BaseType *str); void drawRect(HSURFACE sur, int x, int y, int w, int h); }; void DrawCtrl::textOut(HSURFACE sur, int x, int y, const _BaseType *str) { if(!_VALID_Y(sur->cm, y)) return; int p = 0; for(int i=x; *(str+p) != _BaseType(0) && i< sur->cm._w + x; ++i) { if(_VALID_X(sur->cm, i)) _SET(sur->cm, i, y, *(str+(p++))); } } void DrawCtrl::drawRect(HSURFACE sur, int x, int y, int w, int h) { for(int i=x; i<(x+w); ++i) { if(!_VALID_X(sur->cm, i)) continue; if(_VALID_Y(sur->cm, y)) _SET(sur->cm, i, y, _BaseType('#')); if(_VALID_Y(sur->cm, y+h-1)) _SET(sur->cm, i, y+h-1, _BaseType('#')); } for(int i=y; i<(y+h); ++i) { if(!_VALID_Y(sur->cm, i)) continue; if(_VALID_X(sur->cm, x)) _SET(sur->cm, x, i, _BaseType('#')); if(_VALID_X(sur->cm, x+w-1)) _SET(sur->cm, x+w-1, i, _BaseType('#')); } } void DrawCtrl::clear() { #ifndef ONLINE_COMPILER system(CLS); #endif } void DrawCtrl::paint() { for(int y=0; y<_vram->cm._h; ++y) { _BaseType *ps = &(_vram->cm.buff[y*_vram->cm._w]); _BaseType *pe = ps + _vram->cm._w; _BaseType b = *pe; *pe = _BaseType(0); printf("%s\n", ps); *pe = b; } } // -------------------------------------------- アプリケーション // ------------------------------------------------------------------- // 定義系 ------------------------------------------------------------ // とりあえずメッセージ enum WM_MSG { WM_UNDEFINED, WM_CREATE, WM_PAINT, WM_FOO, WM_DESTOROY }; // ハンドル系 TODO: こっちのハンドルは本当にハンドル typedef unsigned int HANDLE; typedef HANDLE HWND; typedef unsigned long WPARAM, LPARAM; typedef bool (*WndProc)(HWND, WM_MSG, WPARAM, LPARAM); // ウィンドプロシジャ typedef struct { std::string name; WndProc proc; } Window; // なんかウィンドウ // メッセージ構造体 typedef struct _tMsg { HWND hWnd; WM_MSG msg; WPARAM wparam; LPARAM lparam; _tMsg(): msg(WM_UNDEFINED), wparam(0), lparam(0) {} _tMsg(HWND h, WM_MSG m, WPARAM wp, LPARAM lp): hWnd(h), msg(m), wparam(wp), lparam(lp) {} } MSG; typedef std::queue<MSG> MsgQue; // メッセージのキュー typedef std::pair<Window, MsgQue> WinSet; // ウィンドウとメッセージキューのセット typedef std::vector<WinSet> EnumWin; // ウィンドウの列挙 typedef std::vector<HDC> EnumDc; // 描画領域の列挙 // ------------------------------------------------------------------- // OSの中 ------------------------------------------------------------ EnumWin ew; EnumDc ed; HDC& GetDC(HWND hWnd) { return ed[hWnd]; } HANDLE RegisterWindow(const char *name, WndProc proc) // 実質CreateWindowの仕事もしてる状態 { Window wm = {std::string(name), proc}; ew.push_back(WinSet(wm, MsgQue())); ed.push_back(HDC(new DrawCtrl())); return (HANDLE)ew.size()-1; } bool GetMessage(HANDLE hWnd, MSG &msg) { if( ew[hWnd].second.size()<1 ) return false; MSG m = ew[hWnd].second.front(); msg.hWnd = hWnd; msg.msg = m.msg; msg.wparam = m.wparam; msg.lparam = m.lparam; ew[hWnd].second.pop(); return true; } bool DispatchMessage(MSG &msg) { return ew[msg.hWnd].first.proc(msg.hWnd, msg.msg, msg.wparam, msg.lparam); } void os_no_sigoto(HWND hWnd) { // TODO: ここだよねキモ ew[hWnd].second.push(MSG(hWnd, WM_CREATE, 0, 0)); ew[hWnd].second.push(MSG(hWnd, WM_FOO, 0, 0)); ew[hWnd].second.push(MSG(hWnd, WM_PAINT, 0, 0)); ew[hWnd].second.push(MSG(hWnd, WM_DESTOROY, 0, 0)); } // ------------------------------------------------------------------- // ------------------------------------------------------------------- // ------------------------------------------------------------------- // このOSで動かす何らかのアプリケーションコード ---------------------- // ここから下を各PGが、固有のアプリケーションとして書く -------------- // ------------------------------------------------------------------- // // TODO: 元ネタ32API 風にしてしまうか、それだと *ダサい* から // 普通にクラスにしてしまうかで、設計的な迷い中 // 上のSurfaceもそうだがハンドルとか言いつつ生ポ。ニュアンス変更予定 // -------------------------------------------- ウィンドプロシジャ bool proc(HWND hWnd, WM_MSG msg, WPARAM wParam, LPARAM lParam) { static HDC dc; static HSURFACE surf; switch(msg) { case WM_CREATE: break; case WM_FOO: break; case WM_PAINT: dc = GetDC(hWnd); dc->drawRect(dc->getPrimarySurface(), 0, 0, VIDEO_WIDTH, VIDEO_HEIGHT); surf = dc->createCompatibleSurface(NULL); dc->drawRect(surf, 2, 2, 20, 20); dc->textOut(surf, 1, 3, "-- vipper --"); (*dc->getPrimarySurface()) *= *surf; dc->clear(); dc->paint(); break; case WM_DESTOROY: break; default: // noop break; } return true; } // -------------------------------------------- メイン:とりあえず動確 int main() { HWND hWnd = RegisterWindow("名前", proc); // ウィンドウを登録して MSG msg; os_no_sigoto(hWnd); while(GetMessage(hWnd, msg)) // ウィンドウにメッセージがあるか尋ねて { if(!DispatchMessage(msg)) break; // あればディスパッチ } return 0; }
Private
[
?
]
Run code
Submit