├── .gitignore ├── LICENSE ├── MarcoList.md ├── README.md ├── darwin ├── adapter.hpp ├── core.hpp ├── darwin.hpp ├── debugger.hpp ├── graphics.hpp ├── module.hpp ├── random.hpp ├── timer.hpp ├── unix_adapter.cpp ├── unix_conio.hpp ├── unix_module.hpp ├── win32_adapter.cpp ├── win32_conio.hpp └── win32_module.hpp ├── examples ├── cdpf_drawer.cpp ├── cdpf_viewer.cpp ├── snake.cpp └── texteditor.cpp ├── format.bat ├── format.sh ├── reference.md └── tests ├── test1.cpp ├── test_draw_line.cpp ├── test_game.cpp ├── test_rect.cpp └── test_triangle.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Compiled Dynamic libraries 12 | *.so 13 | *.dylib 14 | *.dll 15 | 16 | # Fortran module files 17 | *.mod 18 | *.smod 19 | 20 | # Compiled Static libraries 21 | *.lai 22 | *.la 23 | *.a 24 | *.lib 25 | 26 | # Executables 27 | *.exe 28 | *.out 29 | *.app 30 | 31 | # Logs 32 | *.log -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. -------------------------------------------------------------------------------- /MarcoList.md: -------------------------------------------------------------------------------- 1 | ###Marco List: 2 | **DARWIN_FORCE_BUILTIN**:Darwin will use built-in modules instead of dynamically loaded modules. But you still need to load a module at the beginning of the program (as long as you use a name that has no effect on your program) to start the Darwin function. 3 | **DARWIN_FORCE_UNIX**:Darwin will force use unix headers. 4 | **DARWIN_FORCE_WIN32**:Darwin will force use win32 headers. 5 | **DARWIN_STRICT_CHECK**:Darwin will terminate the program if there have any warning. 6 | **DARWIN_IGNORE_WARNING**:Darwin will ignore every warning and stop writing warnings to log file. 7 | **DARWIN_DISABLE_LOG**:Directly disable the log. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Covariant Darwin Universal Character Interface 2 | ### Darwin是什么? 3 | **Darwin**是Covariant Studio开发的一款通用字符接口,脱胎于CGL而生。 4 | -------------------------------------------------------------------------------- /darwin/adapter.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * Covariant Darwin Universal Character Graphics Library 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Copyright (C) 2018 Michael Lee(李登淳) 18 | * Email: mikecovlee@163.com 19 | * Github: https://github.com/mikecovlee 20 | */ 21 | #include "./core.hpp" 22 | #include 23 | 24 | namespace darwin { 25 | class platform_adapter { 26 | public: 27 | platform_adapter() = default; 28 | 29 | platform_adapter(const platform_adapter &) = delete; 30 | 31 | virtual ~platform_adapter() = default; 32 | 33 | virtual status get_state() const =0; 34 | 35 | virtual results init()=0; 36 | 37 | virtual results stop()=0; 38 | 39 | virtual results exec_commands(commands)=0; 40 | 41 | virtual bool is_kb_hit()=0; 42 | 43 | virtual int get_kb_hit()=0; 44 | 45 | virtual results fit_drawable()=0; 46 | 47 | virtual drawable *get_drawable()=0; 48 | 49 | virtual results update_drawable()=0; 50 | }; 51 | 52 | class module_adapter { 53 | public: 54 | module_adapter() = default; 55 | 56 | module_adapter(const module_adapter &) = delete; 57 | 58 | virtual ~module_adapter() = default; 59 | 60 | virtual status get_state() const =0; 61 | 62 | virtual results load_module(const std::string &)=0; 63 | 64 | virtual results free_module()=0; 65 | 66 | virtual platform_adapter *get_platform_adapter()=0; 67 | }; 68 | 69 | typedef platform_adapter *(*module_enterance)(); 70 | 71 | const char *module_enterance_name = "COV_DARWIN_MODULE_MAIN"; 72 | } -------------------------------------------------------------------------------- /darwin/core.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * Covariant Darwin Universal Character Graphics Library 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Copyright (C) 2018 Michael Lee(李登淳) 18 | * Email: mikecovlee@163.com 19 | * Github: https://github.com/mikecovlee 20 | */ 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include "./debugger.hpp" 29 | 30 | namespace darwin { 31 | enum class status { 32 | null, ready, busy, leisure, error 33 | }; 34 | enum class results { 35 | null, success, failure 36 | }; 37 | enum class colors { 38 | white, black, red, green, blue, pink, yellow, cyan 39 | }; 40 | enum class attris { 41 | bright, underline 42 | }; 43 | enum class commands { 44 | echo_on, echo_off, reset_cursor, reset_attri, clrscr 45 | }; 46 | 47 | class pixel final { 48 | char mChar = ' '; 49 | std::array mAttris = {{false, false}}; 50 | std::array mColors = {{colors::white, colors::black}}; 51 | public: 52 | pixel() = default; 53 | 54 | pixel(const pixel &) = default; 55 | 56 | pixel(char ch, bool bright, bool underline, colors fcolor, colors bcolor) : mChar(ch), mAttris( 57 | { 58 | bright, underline 59 | }), mColors({fcolor, bcolor}) 60 | { 61 | if (ch <= 31 || ch >= 127) 62 | mChar = '\?'; 63 | } 64 | 65 | ~pixel() = default; 66 | 67 | void set_char(char c) 68 | { 69 | if (c > 31 && c < 127) 70 | mChar = c; 71 | else 72 | mChar = '\?'; 73 | } 74 | 75 | char get_char() const 76 | { 77 | return mChar; 78 | } 79 | 80 | void set_front_color(colors c) 81 | { 82 | mColors[0] = c; 83 | } 84 | 85 | colors get_front_color() const 86 | { 87 | return mColors[0]; 88 | } 89 | 90 | void set_back_color(colors c) 91 | { 92 | mColors[1] = c; 93 | } 94 | 95 | colors get_back_color() const 96 | { 97 | return mColors[1]; 98 | } 99 | 100 | void set_colors(const std::array &c) 101 | { 102 | mColors = c; 103 | } 104 | 105 | const std::array &get_colors() const 106 | { 107 | return mColors; 108 | } 109 | 110 | void set_bright(bool value) 111 | { 112 | mAttris[0] = value; 113 | } 114 | 115 | bool is_bright() const 116 | { 117 | return mAttris[0]; 118 | } 119 | 120 | void set_underline(bool value) 121 | { 122 | mAttris[1] = value; 123 | } 124 | 125 | bool is_underline() const 126 | { 127 | return mAttris[1]; 128 | } 129 | 130 | void set_attris(const std::array &a) 131 | { 132 | mAttris = a; 133 | } 134 | 135 | const std::array &get_attris() const 136 | { 137 | return mAttris; 138 | } 139 | }; 140 | 141 | class drawable { 142 | public: 143 | static double draw_line_precision; 144 | 145 | drawable() = default; 146 | 147 | drawable(const drawable &) = default; 148 | 149 | virtual ~drawable() = default; 150 | 151 | virtual std::type_index get_type() const final 152 | { 153 | return typeid(*this); 154 | } 155 | 156 | virtual std::shared_ptr clone() 157 | { 158 | return nullptr; 159 | } 160 | 161 | virtual bool usable() const =0; 162 | 163 | virtual void clear()=0; 164 | 165 | virtual void fill(const pixel &)=0; 166 | 167 | virtual void resize(std::size_t, std::size_t)=0; 168 | 169 | virtual std::size_t get_width() const =0; 170 | 171 | virtual std::size_t get_height() const =0; 172 | 173 | virtual const pixel &get_pixel(std::size_t, std::size_t) const =0; 174 | 175 | virtual void draw_pixel(int, int, const pixel &)=0; 176 | 177 | virtual void draw_line(int p0x, int p0y, int p1x, int p1y, const pixel &pix) 178 | { 179 | if (!this->usable()) 180 | Darwin_Error("Use of not available object."); 181 | if (p0x < 0 || p0y < 0 || p1x < 0 || p1y < 0 || p0x > this->get_width() - 1 || 182 | p0y > this->get_height() - 1 || p1x > this->get_width() - 1 || p1y > this->get_height() - 1) 183 | Darwin_Warning("Out of range."); 184 | long w(p1x - p0x), h(p1y - p0y); 185 | double distance(std::sqrt(std::pow(w, 2) + std::pow(h, 2)) * draw_line_precision); 186 | for (double c = 0; c <= 1; c += 1.0 / distance) 187 | this->draw_pixel(static_cast(p0x + w * c), static_cast(p0y + h * c), pix); 188 | this->draw_pixel(p0x, p0y, pix); 189 | this->draw_pixel(p1x, p1y, pix); 190 | } 191 | 192 | virtual void draw_rect(int x, int y, int w, int h, const pixel &pix) 193 | { 194 | if (!this->usable()) 195 | Darwin_Error("Use of not available object."); 196 | if (x < 0 || y < 0 || x > this->get_width() - 1 || y > this->get_height() - 1 || 197 | x + w > this->get_width() || y + h > this->get_height()) 198 | Darwin_Warning("Out of range."); 199 | for (int i = 0; i != w; w > 0 ? ++i : --i) { 200 | this->draw_pixel(x + i, y, pix); 201 | this->draw_pixel(x + i, y + (h > 0 ? h - 1 : h + 1), pix); 202 | } 203 | for (int i = 0; i != h; h > 0 ? ++i : --i) { 204 | this->draw_pixel(x, y + i, pix); 205 | this->draw_pixel(x + (w > 0 ? w - 1 : w + 1), y + i, pix); 206 | } 207 | } 208 | 209 | virtual void fill_rect(int x, int y, int w, int h, const pixel &pix) 210 | { 211 | if (!this->usable()) 212 | Darwin_Error("Use of not available object."); 213 | if (x < 0 || y < 0 || x > this->get_width() - 1 || y > this->get_height() - 1 || 214 | x + w > this->get_width() || y + h > this->get_height()) 215 | Darwin_Warning("Out of range."); 216 | for (int cy = 0; cy != h; h > 0 ? ++cy : --cy) 217 | for (int cx = 0; cx != w; w > 0 ? ++cx : --cx) 218 | this->draw_pixel(x + cx, y + cy, pix); 219 | } 220 | 221 | virtual void draw_triangle(int x1, int y1, int x2, int y2, int x3, int y3, const pixel &pix) 222 | { 223 | if (!this->usable()) 224 | Darwin_Error("Use of not available object."); 225 | this->draw_line(x1, y1, x2, y2, pix); 226 | this->draw_line(x2, y2, x3, y3, pix); 227 | this->draw_line(x3, y3, x1, y1, pix); 228 | } 229 | 230 | virtual void fill_triangle(int x1, int y1, int x2, int y2, int x3, int y3, const pixel &pix) 231 | { 232 | if (!this->usable()) 233 | Darwin_Error("Use of not available object."); 234 | int v1x(x2 - x1), v1y(y2 - y1), v2x(x3 - x2), v2y(y3 - y2); 235 | if (v1x * v2y - v2x * v1y == 0) 236 | Darwin_Warning("Three points in a line."); 237 | if (y2 < y1) { 238 | std::swap(y1, y2); 239 | std::swap(x1, x2); 240 | } 241 | if (y3 < y2) { 242 | std::swap(y2, y3); 243 | std::swap(x2, x3); 244 | } 245 | if (y2 < y1) { 246 | std::swap(y1, y2); 247 | std::swap(x1, x2); 248 | } 249 | if (y1 == y2) { 250 | double k1(double(x3 - x1) / double(y3 - y1)), k2(double(x3 - x2) / double(y3 - y2)); 251 | for (int y = 0; y <= y3 - y2; ++y) 252 | this->draw_line(x1 + k1 * y, y1 + y, x2 + k2 * y, y2 + y, pix); 253 | } 254 | else if (y2 == y3) { 255 | double k1(double(x3 - x1) / double(y3 - y1)), k2(double(x2 - x1) / double(y2 - y1)); 256 | for (int y = 0; y <= y2 - y1; ++y) 257 | this->draw_line(x1 + k1 * y, y1 + y, x1 + k2 * y, y1 + y, pix); 258 | } 259 | else { 260 | double k1(double(x3 - x1) / double(y3 - y1)), k2(double(x3 - x2) / double(y3 - y2)), k3( 261 | double(x2 - x1) / double(y2 - y1)); 262 | for (int y = 0; y <= y3 - y1; ++y) { 263 | if (y < y2 - y1) 264 | this->draw_line(x1 + k1 * y, y1 + y, x1 + k3 * y, y1 + y, pix); 265 | else 266 | this->draw_line(x1 + k1 * y, y1 + y, x2 + k2 * (y - (y2 - y1)), y1 + y, pix); 267 | } 268 | } 269 | } 270 | 271 | virtual void draw_string(int x, int y, const std::string &str, const pixel &pix) 272 | { 273 | if (!this->usable()) 274 | Darwin_Error("Use of not available object."); 275 | if (x < 0 || y < 0 || x > this->get_width() - 1 || y > this->get_height() - 1 || 276 | x + str.size() > this->get_width()) 277 | Darwin_Warning("Out of range."); 278 | pixel p = pix; 279 | for (int i = 0; i < str.size(); ++i) { 280 | p.set_char(str.at(i)); 281 | this->draw_pixel(x + i, y, p); 282 | } 283 | } 284 | 285 | virtual void draw_picture(int col, int row, const drawable &pic) 286 | { 287 | if (!this->usable() || !pic.usable()) 288 | Darwin_Error("Use of not available object."); 289 | if (col < 0 || row < 0 || col > this->get_width() - 1 || row > this->get_height() - 1) 290 | Darwin_Warning("Out of range."); 291 | int y0(row >= 0 ? row : 0), y1(row >= 0 ? 0 : -row); 292 | while (y0 < this->get_height() && y1 < pic.get_height()) { 293 | int x0(col >= 0 ? col : 0), x1(col >= 0 ? 0 : -col); 294 | while (x0 < this->get_width() && x1 < pic.get_width()) { 295 | this->draw_pixel(x0, y0, pic.get_pixel(x1, y1)); 296 | ++x0; 297 | ++x1; 298 | } 299 | ++y0; 300 | ++y1; 301 | } 302 | } 303 | }; 304 | 305 | double drawable::draw_line_precision = 1.5; 306 | } 307 | -------------------------------------------------------------------------------- /darwin/darwin.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * Covariant Darwin Universal Character Graphics Library 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Copyright (C) 2018 Michael Lee(李登淳) 18 | * Email: mikecovlee@163.com 19 | * Github: https://github.com/mikecovlee 20 | * 21 | * Library Version: 17.10.1 22 | * 23 | * Marco List: 24 | * Library Version: __Darwin 25 | * 26 | * See MarcoList.md to learn more about Covariant Darwin UCGL Marcos. 27 | * See Reference.md to learn more about Covariant Darwin UCGL. 28 | */ 29 | 30 | #ifndef __cplusplus 31 | #error Darwin UCGL need C++ Compiler 32 | #endif 33 | 34 | #if __cplusplus < 201103L 35 | #error Darwin UCGL need C++11 or later standard. 36 | #endif 37 | 38 | #define __Darwin 171001L 39 | 40 | #include "./timer.hpp" 41 | #include "./core.hpp" 42 | #include "./random.hpp" 43 | #include "./adapter.hpp" 44 | #include "./graphics.hpp" 45 | #include 46 | 47 | namespace darwin { 48 | class sync_clock final { 49 | private: 50 | timer_t mBegin; 51 | std::size_t mFreq; 52 | public: 53 | sync_clock() : mBegin(timer::time()), mFreq(60) {} 54 | 55 | sync_clock(std::size_t freq) : mBegin(timer::time()), mFreq(freq) {} 56 | 57 | ~sync_clock() = default; 58 | 59 | std::size_t get_freq() const 60 | { 61 | return mFreq; 62 | } 63 | 64 | void set_freq(std::size_t freq) 65 | { 66 | mFreq = freq; 67 | } 68 | 69 | void reset() 70 | { 71 | mBegin = timer::time(); 72 | } 73 | 74 | void sync() 75 | { 76 | timer_t spend = timer::time() - mBegin; 77 | timer_t period = 1000 / mFreq; 78 | if (period > spend) 79 | timer::delay(period - spend); 80 | } 81 | }; 82 | 83 | class darwin_rt final { 84 | protected: 85 | module_adapter *m_module = nullptr; 86 | platform_adapter *m_platform = nullptr; 87 | public: 88 | darwin_rt() = delete; 89 | 90 | darwin_rt(module_adapter *module) : m_module(module) {} 91 | 92 | darwin_rt(const darwin_rt &) = delete; 93 | 94 | darwin_rt(darwin_rt &&) = delete; 95 | 96 | ~darwin_rt(); 97 | 98 | void load(const std::string &); 99 | 100 | void exit(); 101 | 102 | status get_state() const 103 | { 104 | if (m_module == nullptr) return status::error; 105 | if (m_platform == nullptr) return status::leisure; 106 | if (m_module->get_state() == status::busy || m_platform->get_state() == status::busy) return status::busy; 107 | if (m_module->get_state() == status::ready && m_platform->get_state() == status::ready) 108 | return status::ready; 109 | return status::null; 110 | } 111 | 112 | virtual bool is_kb_hit() 113 | { 114 | if (m_platform == nullptr) Darwin_Error("Adapter is not ready."); 115 | return m_platform->is_kb_hit(); 116 | } 117 | 118 | virtual int get_kb_hit() 119 | { 120 | if (m_platform == nullptr) Darwin_Error("Adapter is not ready."); 121 | return m_platform->get_kb_hit(); 122 | } 123 | 124 | results fit_drawable() 125 | { 126 | if (m_platform == nullptr) return results::failure; 127 | return m_platform->fit_drawable(); 128 | } 129 | 130 | drawable *get_drawable() 131 | { 132 | if (m_platform == nullptr) return nullptr; 133 | return m_platform->get_drawable(); 134 | } 135 | 136 | results update_drawable() 137 | { 138 | if (m_platform == nullptr) return results::failure; 139 | return m_platform->update_drawable(); 140 | } 141 | }; 142 | } 143 | 144 | darwin::darwin_rt::~darwin_rt() 145 | { 146 | exit(); 147 | } 148 | 149 | void darwin::darwin_rt::load(const std::string &file) 150 | { 151 | if (get_state() != status::leisure || m_module->get_state() != status::leisure) 152 | Darwin_Error("Adapter Busy."); 153 | if (m_module->load_module(file) == results::failure) 154 | Darwin_Error("Adapter returns failure."); 155 | m_platform = m_module->get_platform_adapter(); 156 | m_platform->init(); 157 | } 158 | 159 | void darwin::darwin_rt::exit() 160 | { 161 | if (m_platform != nullptr && m_platform->get_state() == status::ready) 162 | m_platform->stop(); 163 | if (m_module != nullptr && m_module->get_state() == status::ready) 164 | m_module->free_module(); 165 | m_platform = nullptr; 166 | } 167 | 168 | #ifdef DARWIN_FORCE_UNIX 169 | #include "./unix_module.hpp" 170 | #else 171 | #ifdef DARWIN_FORCE_WIN32 172 | #include "./win32_module.hpp" 173 | #else 174 | #if defined(__WIN32__) || defined(WIN32) 175 | 176 | #include "./win32_module.hpp" 177 | 178 | #else 179 | 180 | #include "./unix_module.hpp" 181 | 182 | #endif 183 | #endif 184 | #endif 185 | namespace darwin { 186 | static std::string screen_shot_path = "./darwin_screen_shot.cdpf"; 187 | 188 | void print_screen() 189 | { 190 | static std::deque file_buffer; 191 | serial_picture(runtime.get_drawable(), file_buffer); 192 | outfs out(screen_shot_path); 193 | for (auto &it:file_buffer) 194 | out.printf("%c", it); 195 | out.flush(); 196 | } 197 | } 198 | -------------------------------------------------------------------------------- /darwin/debugger.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * Covariant Darwin Universal Character Graphics Library 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Copyright (C) 2018 Michael Lee(李登淳) 18 | * Email: mikecovlee@163.com 19 | * Github: https://github.com/mikecovlee 20 | */ 21 | #include 22 | #include 23 | #include 24 | #include "./timer.hpp" 25 | 26 | namespace darwin { 27 | class warning final : public std::exception { 28 | std::string mWhat = "Darwin Warning"; 29 | public: 30 | warning() = default; 31 | 32 | warning(const std::string &str) noexcept: 33 | mWhat("Darwin Warning:" + str) {} 34 | 35 | warning(const warning &) = default; 36 | 37 | warning(warning &&) = default; 38 | 39 | virtual ~warning() = default; 40 | 41 | virtual const char *what() const noexcept override 42 | { 43 | return this->mWhat.c_str(); 44 | } 45 | }; 46 | 47 | class error final : public std::exception { 48 | std::string mWhat = "Darwin Error"; 49 | public: 50 | error() = default; 51 | 52 | error(const std::string &str) noexcept: 53 | mWhat("Darwin Error:" + str) {} 54 | 55 | error(const error &) = default; 56 | 57 | error(error &&) = default; 58 | 59 | virtual ~error() = default; 60 | 61 | error &operator=(const error &)= default; 62 | 63 | error &operator=(error &&)= default; 64 | 65 | virtual const char *what() const noexcept override 66 | { 67 | return this->mWhat.c_str(); 68 | } 69 | }; 70 | 71 | class outfs final { 72 | FILE *mfp = nullptr; 73 | public: 74 | outfs() = default; 75 | 76 | outfs(const char *path) : mfp(fopen(path, "w")) {} 77 | 78 | outfs(const std::string &path) : mfp(fopen(path.c_str(), "w")) {} 79 | 80 | ~outfs() 81 | { 82 | if (this->mfp != nullptr) fclose(this->mfp); 83 | } 84 | 85 | outfs &operator=(const outfs &)= delete; 86 | 87 | operator bool() const noexcept 88 | { 89 | return this->mfp != nullptr; 90 | } 91 | 92 | bool usable() const noexcept 93 | { 94 | return this->mfp != nullptr; 95 | } 96 | 97 | void open(const char *path) 98 | { 99 | if (this->mfp == nullptr) { 100 | this->mfp = fopen(path, "w"); 101 | } 102 | } 103 | 104 | void open(const std::string &path) 105 | { 106 | if (this->mfp == nullptr) { 107 | this->mfp = fopen(path.c_str(), "w"); 108 | } 109 | } 110 | 111 | void close() 112 | { 113 | if (this->mfp != nullptr) 114 | fclose(this->mfp); 115 | this->mfp = nullptr; 116 | } 117 | 118 | template 119 | void printf(const char *format, ArgsT...args) 120 | { 121 | fprintf(this->mfp, format, args...); 122 | } 123 | 124 | void flush() 125 | { 126 | if (this->mfp != nullptr) { 127 | fflush(this->mfp); 128 | } 129 | } 130 | }; 131 | 132 | #ifndef DARWIN_DISABLE_LOG 133 | 134 | class debugger final { 135 | static outfs out; 136 | public: 137 | #ifdef DARWIN_STRICT_CHECK 138 | static constexpr bool strict=true; 139 | #else 140 | static constexpr bool strict = false; 141 | #endif 142 | #ifdef DARWIN_IGNORE_WARNING 143 | static constexpr bool ignore=true; 144 | #else 145 | static constexpr bool ignore = false; 146 | #endif 147 | 148 | static void log(const char *file, int line, const char *func, const char *msg) 149 | { 150 | if (!out.usable()) 151 | out.open("./darwin_runtime.log"); 152 | out.printf("[Darwin Log(%ums)]:In function \"%s\"(%s:%d):%s\n", timer::time(), func, file, line, msg); 153 | } 154 | 155 | static void warning(const char *file, int line, const char *func, const char *msg) 156 | { 157 | if (ignore) 158 | return; 159 | if (!out.usable()) 160 | out.open("./darwin_runtime.log"); 161 | out.printf("[Darwin Warning(%ums)]:In function \"%s\"(%s:%d):%s\n", timer::time(), func, file, line, msg); 162 | if (strict) { 163 | out.flush(); 164 | std::terminate(); 165 | } 166 | } 167 | 168 | static void error(const char *file, int line, const char *func, const char *msg) 169 | { 170 | out.printf("[Darwin Error(%ums)]:In function \"%s\"(%s:%d):%s\n", timer::time(), func, file, line, msg); 171 | out.flush(); 172 | std::terminate(); 173 | } 174 | 175 | static void log_path(const char *path) 176 | { 177 | out.close(); 178 | out.open(path); 179 | } 180 | }; 181 | 182 | outfs debugger::out; 183 | #endif 184 | } 185 | 186 | #ifndef DARWIN_DISABLE_LOG 187 | 188 | #define Darwin_Log(msg) darwin::debugger::log(__FILE__,__LINE__,__func__,msg); 189 | #define Darwin_Warning(msg) darwin::debugger::warning(__FILE__,__LINE__,__func__,msg); 190 | #define Darwin_Error(msg) darwin::debugger::error(__FILE__,__LINE__,__func__,msg); 191 | #define Darwin_Set_Log_Path(path) darwin::debugger::log_path(path); 192 | 193 | #else 194 | 195 | #define Darwin_Log(msg) 196 | 197 | #ifndef DARWIN_STRICT_CHECK 198 | 199 | #define Darwin_Warning(msg) 200 | 201 | #else 202 | 203 | #define Darwin_Warning(msg) throw darwin::warning(msg); 204 | 205 | #endif 206 | 207 | #define Darwin_Error(msg) throw darwin::error(msg); 208 | #define Darwin_Set_Log_Path(path) 209 | 210 | #endif -------------------------------------------------------------------------------- /darwin/graphics.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * Covariant Darwin Universal Character Graphics Library 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Copyright (C) 2018 Michael Lee(李登淳) 18 | * Email: mikecovlee@163.com 19 | * Github: https://github.com/mikecovlee 20 | */ 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include "./core.hpp" 26 | 27 | namespace darwin { 28 | class picture : public drawable { 29 | protected: 30 | std::size_t mWidth, mHeight; 31 | pixel *mImage = nullptr; 32 | 33 | void copy(std::size_t w, std::size_t h, pixel *const img) 34 | { 35 | if (img != nullptr) { 36 | delete[] this->mImage; 37 | this->mImage = new pixel[w * h]; 38 | this->mWidth = w; 39 | this->mHeight = h; 40 | for (std::size_t i = 0; i < this->mWidth * this->mHeight; ++i) 41 | this->mImage[i] = img[i]; 42 | } 43 | } 44 | 45 | public: 46 | picture() : mWidth(0), mHeight(0), mImage(nullptr) {} 47 | 48 | picture(std::size_t w, std::size_t h) : mImage(new pixel[h * w]), mWidth(w), mHeight(h) {} 49 | 50 | picture(std::size_t w, std::size_t h, const pixel &pix) : mImage(new pixel[h * w]), mWidth(w), mHeight(h) 51 | { 52 | for (pixel *it = this->mImage; it != this->mImage + w * h; ++it) *it = pix; 53 | } 54 | 55 | picture(const picture &img) : mWidth(0), mHeight(0), mImage(nullptr) 56 | { 57 | copy(img.mWidth, img.mHeight, img.mImage); 58 | } 59 | 60 | picture(picture &&img) : mWidth(0), mHeight(0), mImage(nullptr) 61 | { 62 | copy(img.mWidth, img.mHeight, img.mImage); 63 | } 64 | 65 | virtual ~picture() 66 | { 67 | delete[] this->mImage; 68 | } 69 | 70 | picture &operator=(const picture &img) 71 | { 72 | if (&img != this) 73 | this->copy(img.mWidth, img.mHeight, img.mImage); 74 | return *this; 75 | } 76 | 77 | picture &operator=(picture &&img) 78 | { 79 | if (&img != this) 80 | this->copy(img.mWidth, img.mHeight, img.mImage); 81 | return *this; 82 | } 83 | 84 | virtual std::shared_ptr clone() override 85 | { 86 | return std::make_shared(*this); 87 | } 88 | 89 | virtual bool usable() const override 90 | { 91 | return this->mImage != nullptr; 92 | } 93 | 94 | virtual std::size_t get_width() const override 95 | { 96 | return this->mWidth; 97 | } 98 | 99 | virtual std::size_t get_height() const override 100 | { 101 | return this->mHeight; 102 | } 103 | 104 | virtual void resize(std::size_t w, std::size_t h) override 105 | { 106 | if (w == this->mWidth && h == this->mHeight) 107 | return; 108 | delete[] this->mImage; 109 | this->mImage = new pixel[h * w]; 110 | this->mWidth = w; 111 | this->mHeight = h; 112 | } 113 | 114 | virtual void fill(const pixel &pix) override 115 | { 116 | if (this->mImage == nullptr) 117 | Darwin_Error("Use of not available object."); 118 | for (pixel *it = this->mImage; it != this->mImage + this->mWidth * this->mHeight; ++it) *it = pix; 119 | } 120 | 121 | virtual void clear() override 122 | { 123 | if (this->mImage != nullptr) { 124 | delete[] this->mImage; 125 | this->mImage = new pixel[mHeight * mWidth]; 126 | } 127 | } 128 | 129 | virtual const pixel &get_pixel(std::size_t x, std::size_t y) const override 130 | { 131 | if (this->mImage == nullptr) 132 | Darwin_Error("Use of not available object."); 133 | if (x > this->mWidth - 1 || y > this->mHeight - 1) 134 | Darwin_Error("Out of range."); 135 | return this->mImage[y * this->mWidth + x]; 136 | } 137 | 138 | virtual void draw_pixel(int x, int y, const pixel &pix) override 139 | { 140 | if (this->mImage == nullptr) 141 | Darwin_Error("Use of not available object."); 142 | if (x < 0 || y < 0 || x > this->mWidth - 1 || y > this->mHeight - 1) { 143 | Darwin_Warning("Out of range."); 144 | return; 145 | } 146 | this->mImage[y * this->mWidth + x] = pix; 147 | } 148 | }; 149 | 150 | bool serial_picture(drawable *pic, std::deque &dat) 151 | { 152 | if (pic == nullptr) return false; 153 | if (pic->get_width() > 9999 || pic->get_height() > 9999) return false; 154 | static std::string tmp; 155 | dat.clear(); 156 | tmp = std::to_string(pic->get_width()); 157 | for (int count = 4 - tmp.size(); count > 0; --count) 158 | dat.push_back('0'); 159 | for (auto &ch:tmp) 160 | dat.push_back(ch); 161 | tmp = std::to_string(pic->get_height()); 162 | for (int count = 4 - tmp.size(); count > 0; --count) 163 | dat.push_back('0'); 164 | for (auto &ch:tmp) 165 | dat.push_back(ch); 166 | for (std::size_t y = 0; y < pic->get_height(); ++y) { 167 | for (std::size_t x = 0; x < pic->get_width(); ++x) { 168 | const pixel &pix = pic->get_pixel(x, y); 169 | dat.push_back(pix.get_char()); 170 | if (pix.is_bright()) 171 | dat.push_back('0'); 172 | else 173 | dat.push_back('1'); 174 | if (pix.is_underline()) 175 | dat.push_back('0'); 176 | else 177 | dat.push_back('1'); 178 | switch (pix.get_front_color()) { 179 | case colors::white: 180 | dat.push_back('1'); 181 | break; 182 | case colors::black: 183 | dat.push_back('2'); 184 | break; 185 | case colors::red: 186 | dat.push_back('3'); 187 | break; 188 | case colors::green: 189 | dat.push_back('4'); 190 | break; 191 | case colors::blue: 192 | dat.push_back('5'); 193 | break; 194 | case colors::pink: 195 | dat.push_back('6'); 196 | break; 197 | case colors::yellow: 198 | dat.push_back('7'); 199 | break; 200 | case colors::cyan: 201 | dat.push_back('8'); 202 | break; 203 | } 204 | switch (pix.get_back_color()) { 205 | case colors::white: 206 | dat.push_back('1'); 207 | break; 208 | case colors::black: 209 | dat.push_back('2'); 210 | break; 211 | case colors::red: 212 | dat.push_back('3'); 213 | break; 214 | case colors::green: 215 | dat.push_back('4'); 216 | break; 217 | case colors::blue: 218 | dat.push_back('5'); 219 | break; 220 | case colors::pink: 221 | dat.push_back('6'); 222 | break; 223 | case colors::yellow: 224 | dat.push_back('7'); 225 | break; 226 | case colors::cyan: 227 | dat.push_back('8'); 228 | break; 229 | } 230 | } 231 | } 232 | return true; 233 | } 234 | 235 | bool unserial_picture(drawable *pic, const std::deque &dat) 236 | { 237 | if (pic == nullptr) return false; 238 | std::string tmp; 239 | tmp = {dat[0], dat[1], dat[2], dat[3]}; 240 | std::size_t w = std::stoul(tmp); 241 | tmp = {dat[4], dat[5], dat[6], dat[7]}; 242 | std::size_t h = std::stoul(tmp); 243 | pic->resize(w, h); 244 | pixel pix; 245 | int x(0), y(0); 246 | for (std::size_t i = 8; i < dat.size() && y < h; i += 5) { 247 | pix.set_char(dat[i]); 248 | if (dat[i + 1] == '0') 249 | pix.set_bright(true); 250 | else 251 | pix.set_bright(false); 252 | if (dat[i + 2] == '0') 253 | pix.set_underline(true); 254 | else 255 | pix.set_underline(false); 256 | switch (dat[i + 3]) { 257 | case '1': 258 | pix.set_front_color(colors::white); 259 | break; 260 | case '2': 261 | pix.set_front_color(colors::black); 262 | break; 263 | case '3': 264 | pix.set_front_color(colors::red); 265 | break; 266 | case '4': 267 | pix.set_front_color(colors::green); 268 | break; 269 | case '5': 270 | pix.set_front_color(colors::blue); 271 | break; 272 | case '6': 273 | pix.set_front_color(colors::pink); 274 | break; 275 | case '7': 276 | pix.set_front_color(colors::yellow); 277 | break; 278 | case '8': 279 | pix.set_front_color(colors::cyan); 280 | break; 281 | } 282 | switch (dat[i + 4]) { 283 | case '1': 284 | pix.set_back_color(colors::white); 285 | break; 286 | case '2': 287 | pix.set_back_color(colors::black); 288 | break; 289 | case '3': 290 | pix.set_back_color(colors::red); 291 | break; 292 | case '4': 293 | pix.set_back_color(colors::green); 294 | break; 295 | case '5': 296 | pix.set_back_color(colors::blue); 297 | break; 298 | case '6': 299 | pix.set_back_color(colors::pink); 300 | break; 301 | case '7': 302 | pix.set_back_color(colors::yellow); 303 | break; 304 | case '8': 305 | pix.set_back_color(colors::cyan); 306 | break; 307 | } 308 | pic->draw_pixel(x, y, pix); 309 | if (x >= w - 1) { 310 | x = 0; 311 | ++y; 312 | } 313 | else 314 | ++x; 315 | } 316 | return true; 317 | } 318 | } 319 | -------------------------------------------------------------------------------- /darwin/module.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * Covariant Darwin Universal Character Graphics Library 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Copyright (C) 2018 Michael Lee(李登淳) 18 | * Email: mikecovlee@163.com 19 | * Github: https://github.com/mikecovlee 20 | */ 21 | #include "./adapter.hpp" 22 | 23 | namespace darwin { 24 | platform_adapter *module_resource(); 25 | } 26 | extern "C" 27 | { 28 | darwin::platform_adapter *COV_DARWIN_MODULE_MAIN() 29 | { 30 | return darwin::module_resource(); 31 | } 32 | } -------------------------------------------------------------------------------- /darwin/random.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * Covariant Darwin Universal Character Graphics Library 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Copyright (C) 2018 Michael Lee(李登淳) 18 | * Email: mikecovlee@163.com 19 | * Github: https://github.com/mikecovlee 20 | */ 21 | #include 22 | #include 23 | #include 24 | 25 | namespace darwin { 26 | namespace random { 27 | static std::default_random_engine random_engine(time(nullptr)); 28 | template 29 | struct random_traits; 30 | 31 | template 32 | struct random_traits { 33 | static T rand(T begin, T end) 34 | { 35 | return std::uniform_int_distribution(begin, end)(random_engine); 36 | } 37 | }; 38 | 39 | template 40 | struct random_traits { 41 | static T rand(T begin, T end) 42 | { 43 | return std::uniform_real_distribution(begin, end)(random_engine); 44 | } 45 | }; 46 | } 47 | 48 | template 49 | T rand(T begin, T end) 50 | { 51 | return random::random_traits::value>::rand(begin, end); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /darwin/timer.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * Covariant Darwin Universal Character Graphics Library 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Copyright (C) 2018 Michael Lee(李登淳) 18 | * Email: mikecovlee@163.com 19 | * Github: https://github.com/mikecovlee 20 | */ 21 | #include 22 | #include 23 | #include 24 | 25 | namespace darwin { 26 | typedef unsigned long timer_t; 27 | 28 | class timer; 29 | } 30 | class darwin::timer final { 31 | static std::chrono::time_point m_timer; 32 | public: 33 | enum class time_unit { 34 | nano_sec, micro_sec, milli_sec, second, minute 35 | }; 36 | 37 | static void reset() 38 | { 39 | m_timer = std::chrono::high_resolution_clock::now(); 40 | } 41 | 42 | static timer_t time(time_unit unit = time_unit::milli_sec) 43 | { 44 | switch (unit) { 45 | case time_unit::nano_sec: 46 | return std::chrono::duration_cast( 47 | std::chrono::high_resolution_clock::now() - m_timer).count(); 48 | case time_unit::micro_sec: 49 | return std::chrono::duration_cast( 50 | std::chrono::high_resolution_clock::now() - m_timer).count(); 51 | case time_unit::milli_sec: 52 | return std::chrono::duration_cast( 53 | std::chrono::high_resolution_clock::now() - m_timer).count(); 54 | case time_unit::second: 55 | return std::chrono::duration_cast( 56 | std::chrono::high_resolution_clock::now() - m_timer).count(); 57 | case time_unit::minute: 58 | return std::chrono::duration_cast( 59 | std::chrono::high_resolution_clock::now() - m_timer).count(); 60 | } 61 | return 0; 62 | } 63 | 64 | static void delay(timer_t time, time_unit unit = time_unit::milli_sec) 65 | { 66 | switch (unit) { 67 | case time_unit::nano_sec: 68 | std::this_thread::sleep_for(std::chrono::nanoseconds(time)); 69 | break; 70 | case time_unit::micro_sec: 71 | std::this_thread::sleep_for(std::chrono::microseconds(time)); 72 | break; 73 | case time_unit::milli_sec: 74 | std::this_thread::sleep_for(std::chrono::milliseconds(time)); 75 | break; 76 | case time_unit::second: 77 | std::this_thread::sleep_for(std::chrono::seconds(time)); 78 | break; 79 | case time_unit::minute: 80 | std::this_thread::sleep_for(std::chrono::minutes(time)); 81 | break; 82 | } 83 | } 84 | 85 | static timer_t measure(const std::function &func, time_unit unit = time_unit::milli_sec) 86 | { 87 | timer_t begin(0), end(0); 88 | begin = time(unit); 89 | func(); 90 | end = time(unit); 91 | return end - begin; 92 | } 93 | }; 94 | 95 | std::chrono::time_point 96 | darwin::timer::m_timer(std::chrono::high_resolution_clock::now()); -------------------------------------------------------------------------------- /darwin/unix_adapter.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Covariant Darwin Universal Character Graphics Library 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | * Copyright (C) 2018 Michael Lee(李登淳) 17 | * Email: mikecovlee@163.com 18 | * Github: https://github.com/mikecovlee 19 | */ 20 | #include "./module.hpp" 21 | #include "./graphics.hpp" 22 | #include "./unix_conio.hpp" 23 | #include 24 | #include 25 | 26 | namespace darwin { 27 | class unix_adapter : public platform_adapter { 28 | bool mReady = false; 29 | picture mDrawable; 30 | public: 31 | unix_adapter() = default; 32 | 33 | virtual ~unix_adapter() = default; 34 | 35 | virtual status get_state() const override 36 | { 37 | if (mReady) 38 | return status::ready; 39 | else 40 | return status::leisure; 41 | } 42 | 43 | virtual results init() override 44 | { 45 | conio::reset(); 46 | //conio::clrscr(); 47 | conio::echo(false); 48 | mReady = true; 49 | return results::success; 50 | } 51 | 52 | virtual results stop() override 53 | { 54 | conio::reset(); 55 | //conio::clrscr(); 56 | conio::echo(true); 57 | mReady = false; 58 | return results::success; 59 | } 60 | 61 | virtual results exec_commands(commands c) override 62 | { 63 | switch (c) { 64 | case commands::echo_on: 65 | conio::echo(true); 66 | break; 67 | case commands::echo_off: 68 | conio::echo(false); 69 | break; 70 | case commands::reset_cursor: 71 | conio::gotoxy(0, 0); 72 | break; 73 | case commands::reset_attri: 74 | conio::reset(); 75 | break; 76 | case commands::clrscr: 77 | conio::clrscr(); 78 | break; 79 | } 80 | return results::success; 81 | } 82 | 83 | virtual bool is_kb_hit() override 84 | { 85 | return conio::kbhit(); 86 | } 87 | 88 | virtual int get_kb_hit() override 89 | { 90 | return conio::getch(); 91 | } 92 | 93 | virtual results fit_drawable() override 94 | { 95 | mDrawable.resize(conio::terminal_width(), conio::terminal_height()); 96 | return results::success; 97 | } 98 | 99 | virtual drawable *get_drawable() override 100 | { 101 | return &mDrawable; 102 | } 103 | 104 | virtual results update_drawable() override 105 | { 106 | conio::gotoxy(0, 0); 107 | std::size_t sw(std::min(mDrawable.get_width(), conio::terminal_width())), sh( 108 | std::min(mDrawable.get_height(), conio::terminal_height())); 109 | for (std::size_t y = 0; y < sh; ++y) { 110 | for (std::size_t x = 0; x < sw; ++x) { 111 | const pixel &pix = mDrawable.get_pixel(x, y); 112 | std::string cmd = "\e[0m\e["; 113 | switch (pix.get_front_color()) { 114 | case colors::white: 115 | cmd += "37;"; 116 | break; 117 | case colors::black: 118 | cmd += "30;"; 119 | break; 120 | case colors::red: 121 | cmd += "31;"; 122 | break; 123 | case colors::green: 124 | cmd += "32;"; 125 | break; 126 | case colors::blue: 127 | cmd += "34;"; 128 | break; 129 | case colors::pink: 130 | cmd += "35;"; 131 | break; 132 | case colors::yellow: 133 | cmd += "33;"; 134 | break; 135 | case colors::cyan: 136 | cmd += "36;"; 137 | break; 138 | default: 139 | return results::failure; 140 | break; 141 | } 142 | switch (pix.get_back_color()) { 143 | case colors::white: 144 | cmd += "47"; 145 | break; 146 | case colors::black: 147 | cmd += "40"; 148 | break; 149 | case colors::red: 150 | cmd += "41"; 151 | break; 152 | case colors::green: 153 | cmd += "42"; 154 | break; 155 | case colors::blue: 156 | cmd += "44"; 157 | break; 158 | case colors::pink: 159 | cmd += "45"; 160 | break; 161 | case colors::yellow: 162 | cmd += "43"; 163 | break; 164 | case colors::cyan: 165 | cmd += "46"; 166 | break; 167 | default: 168 | return results::failure; 169 | break; 170 | } 171 | if (pix.is_bright()) 172 | cmd += ";1"; 173 | if (pix.is_underline()) 174 | cmd += ";4"; 175 | cmd += "m"; 176 | printf("%s%c", cmd.c_str(), pix.get_char()); 177 | } 178 | conio::reset(); 179 | printf("\n"); 180 | } 181 | fflush(stdout); 182 | return results::success; 183 | } 184 | } dunixadapter; 185 | 186 | platform_adapter *module_resource() 187 | { 188 | return &dunixadapter; 189 | } 190 | } 191 | -------------------------------------------------------------------------------- /darwin/unix_conio.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * Covariant Darwin Universal Character Graphics Library 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Copyright (C) 2018 Michael Lee(李登淳) 18 | * Email: mikecovlee@163.com 19 | * Github: https://github.com/mikecovlee 20 | */ 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | namespace conio { 28 | static int terminal_width() 29 | { 30 | struct winsize size; 31 | ioctl(STDIN_FILENO, TIOCGWINSZ, &size); 32 | return size.ws_col; 33 | } 34 | 35 | static int terminal_height() 36 | { 37 | struct winsize size; 38 | ioctl(STDIN_FILENO, TIOCGWINSZ, &size); 39 | return size.ws_row - 1; 40 | } 41 | 42 | static void gotoxy(int x, int y) 43 | { 44 | printf("\x1B[%d;%df", y, x); 45 | } 46 | 47 | static void echo(bool in) 48 | { 49 | struct termios oldt, newt; 50 | tcgetattr(0, &oldt); 51 | newt = oldt; 52 | if (in) { 53 | printf("\33[?25h"); 54 | newt.c_lflag |= ECHO; 55 | newt.c_lflag |= ICANON; 56 | } 57 | else { 58 | printf("\33[?25l"); 59 | newt.c_lflag &= ~ECHO; 60 | newt.c_lflag &= ~ICANON; 61 | } 62 | tcsetattr(0, TCSANOW, &newt); 63 | } 64 | 65 | static void reset() 66 | { 67 | printf("\e[37;40;0m"); 68 | } 69 | 70 | static void clrscr() 71 | { 72 | printf("\x1B[2J\x1B[0;0f"); 73 | } 74 | 75 | static int getch() 76 | { 77 | int ch; 78 | ch = getchar(); 79 | return ch; 80 | } 81 | 82 | static int kbhit() 83 | { 84 | int ret; 85 | fd_set fds; 86 | struct timeval tv; 87 | tv.tv_sec = 0; 88 | tv.tv_usec = 0; 89 | FD_ZERO(&fds); 90 | FD_SET(0, &fds); 91 | select(1, &fds, 0, 0, &tv); 92 | ret = FD_ISSET(0, &fds); 93 | return ret; 94 | } 95 | } -------------------------------------------------------------------------------- /darwin/unix_module.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * Covariant Darwin Universal Character Graphics Library 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Copyright (C) 2018 Michael Lee(李登淳) 18 | * Email: mikecovlee@163.com 19 | * Github: https://github.com/mikecovlee 20 | */ 21 | #include 22 | #include 23 | #include 24 | 25 | #ifdef DARWIN_FORCE_BUILTIN 26 | #include "./unix_adapter.cpp" 27 | #endif 28 | namespace darwin { 29 | class unix_module_adapter : public module_adapter { 30 | void *m_handle = nullptr; 31 | platform_adapter *m_adapter = nullptr; 32 | 33 | static void force_exit(int); 34 | 35 | static void handle_segfault(int); 36 | 37 | public: 38 | unix_module_adapter() = default; 39 | 40 | virtual ~unix_module_adapter() = default; 41 | 42 | virtual status get_state() const override 43 | { 44 | if (m_adapter != nullptr) 45 | return status::ready; 46 | else 47 | return status::leisure; 48 | } 49 | 50 | virtual results load_module(const std::string &path) override 51 | { 52 | signal(SIGSEGV, handle_segfault); 53 | signal(SIGINT, force_exit); 54 | signal(SIGABRT, force_exit); 55 | #ifdef DARWIN_FORCE_BUILTIN 56 | m_adapter=module_resource(); 57 | #else 58 | m_handle = dlopen(path.c_str(), RTLD_LAZY); 59 | if (m_handle == nullptr) return results::failure; 60 | module_enterance enterance = (module_enterance) dlsym(m_handle, module_enterance_name); 61 | m_adapter = enterance(); 62 | #endif 63 | if (m_adapter == nullptr) return results::failure; 64 | return results::success; 65 | } 66 | 67 | virtual results free_module() override 68 | { 69 | signal(SIGSEGV, nullptr); 70 | signal(SIGINT, nullptr); 71 | signal(SIGABRT, nullptr); 72 | #ifndef DARWIN_FORCE_BUILTIN 73 | dlclose(m_handle); 74 | m_handle = nullptr; 75 | #endif 76 | m_adapter = nullptr; 77 | return results::success; 78 | } 79 | 80 | virtual platform_adapter *get_platform_adapter() override 81 | { 82 | return this->m_adapter; 83 | } 84 | } dunixmodule; 85 | 86 | static darwin_rt runtime(&dunixmodule); 87 | } 88 | 89 | void darwin::unix_module_adapter::force_exit(int flag) 90 | { 91 | printf("Darwin have been exited safety.\n"); 92 | runtime.exit(); 93 | std::exit(0); 94 | } 95 | 96 | void darwin::unix_module_adapter::handle_segfault(int flag) 97 | { 98 | printf("Your program have some problem about the Segmentation Fault.Please check your program after we terminate this program.\n"); 99 | printf("Darwin have been exited safety.\n"); 100 | runtime.exit(); 101 | std::exit(-1); 102 | } 103 | -------------------------------------------------------------------------------- /darwin/win32_adapter.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Covariant Darwin Universal Character Graphics Library 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | * Copyright (C) 2018 Michael Lee(李登淳) 17 | * Email: mikecovlee@163.com 18 | * Github: https://github.com/mikecovlee 19 | */ 20 | #include "./module.hpp" 21 | #include "./graphics.hpp" 22 | #include "./win32_conio.hpp" 23 | #include 24 | #include 25 | 26 | namespace darwin { 27 | class win32_adapter : public platform_adapter { 28 | bool mReady = false; 29 | picture mDrawable; 30 | public: 31 | win32_adapter() = default; 32 | 33 | virtual ~win32_adapter() = default; 34 | 35 | virtual status get_state() const override 36 | { 37 | if (mReady) 38 | return status::ready; 39 | else 40 | return status::leisure; 41 | } 42 | 43 | virtual results init() override 44 | { 45 | conio::set_title("Covariant Darwin UCGL"); 46 | conio::reset(); 47 | //conio::clrscr(); 48 | conio::echo(false); 49 | mReady = true; 50 | return results::success; 51 | } 52 | 53 | virtual results stop() override 54 | { 55 | conio::reset(); 56 | //conio::clrscr(); 57 | conio::echo(true); 58 | mReady = false; 59 | return results::success; 60 | } 61 | 62 | virtual results exec_commands(commands c) override 63 | { 64 | switch (c) { 65 | case commands::echo_on: 66 | conio::echo(true); 67 | break; 68 | case commands::echo_off: 69 | conio::echo(false); 70 | break; 71 | case commands::reset_cursor: 72 | conio::gotoxy(0, 0); 73 | break; 74 | case commands::reset_attri: 75 | conio::reset(); 76 | break; 77 | case commands::clrscr: 78 | conio::clrscr(); 79 | break; 80 | } 81 | return results::success; 82 | } 83 | 84 | virtual bool is_kb_hit() override 85 | { 86 | return conio::kbhit(); 87 | } 88 | 89 | virtual int get_kb_hit() override 90 | { 91 | return conio::getch(); 92 | } 93 | 94 | virtual results fit_drawable() override 95 | { 96 | mDrawable.resize(conio::terminal_width(), conio::terminal_height()); 97 | return results::success; 98 | } 99 | 100 | virtual drawable *get_drawable() override 101 | { 102 | return &mDrawable; 103 | } 104 | 105 | virtual results update_drawable() override 106 | { 107 | conio::gotoxy(0, 0); 108 | std::size_t sw(std::min(mDrawable.get_width(), conio::terminal_width())), sh( 109 | std::min(mDrawable.get_height(), conio::terminal_height())); 110 | conio::console buf(sw, sh); 111 | for (std::size_t y = 0; y < sh; ++y) { 112 | for (std::size_t x = 0; x < sw; ++x) { 113 | const pixel &pix = mDrawable.get_pixel(x, y); 114 | int fcolor, bcolor; 115 | switch (pix.get_front_color()) { 116 | case colors::white: 117 | fcolor = 15; 118 | break; 119 | case colors::black: 120 | fcolor = 0; 121 | break; 122 | case colors::red: 123 | fcolor = 12; 124 | break; 125 | case colors::green: 126 | fcolor = 10; 127 | break; 128 | case colors::blue: 129 | fcolor = 9; 130 | break; 131 | case colors::pink: 132 | fcolor = 13; 133 | break; 134 | case colors::yellow: 135 | fcolor = 14; 136 | break; 137 | case colors::cyan: 138 | fcolor = 11; 139 | break; 140 | default: 141 | return results::failure; 142 | break; 143 | } 144 | switch (pix.get_back_color()) { 145 | case colors::white: 146 | bcolor = 15; 147 | break; 148 | case colors::black: 149 | bcolor = 8; 150 | break; 151 | case colors::red: 152 | bcolor = 12; 153 | break; 154 | case colors::green: 155 | bcolor = 10; 156 | break; 157 | case colors::blue: 158 | bcolor = 9; 159 | break; 160 | case colors::pink: 161 | bcolor = 13; 162 | break; 163 | case colors::yellow: 164 | bcolor = 14; 165 | break; 166 | case colors::cyan: 167 | bcolor = 11; 168 | break; 169 | default: 170 | return results::failure; 171 | break; 172 | } 173 | buf.set_color(fcolor, bcolor); 174 | buf.put_char(pix.get_char()); 175 | } 176 | buf.reset(); 177 | } 178 | buf.flush(); 179 | return results::success; 180 | } 181 | } dwin32adapter; 182 | 183 | platform_adapter *module_resource() 184 | { 185 | return &dwin32adapter; 186 | } 187 | } 188 | -------------------------------------------------------------------------------- /darwin/win32_conio.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * Covariant Darwin Universal Character Graphics Library 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Copyright (C) 2018 Michael Lee(李登淳) 18 | * Email: mikecovlee@163.com 19 | * Github: https://github.com/mikecovlee 20 | */ 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | namespace conio { 27 | static HANDLE StdHandle = GetStdHandle(STD_OUTPUT_HANDLE); 28 | 29 | static int terminal_width() 30 | { 31 | static CONSOLE_SCREEN_BUFFER_INFO csbi; 32 | GetConsoleScreenBufferInfo(StdHandle, &csbi); 33 | return csbi.srWindow.Right - csbi.srWindow.Left; 34 | } 35 | 36 | static int terminal_height() 37 | { 38 | static CONSOLE_SCREEN_BUFFER_INFO csbi; 39 | GetConsoleScreenBufferInfo(StdHandle, &csbi); 40 | return csbi.srWindow.Bottom - csbi.srWindow.Top; 41 | } 42 | 43 | static void gotoxy(SHORT x, SHORT y) 44 | { 45 | SetConsoleCursorPosition(StdHandle, {x, y}); 46 | } 47 | 48 | static void echo(bool mode) 49 | { 50 | static CONSOLE_CURSOR_INFO cci; 51 | GetConsoleCursorInfo(StdHandle, &cci); 52 | cci.bVisible = mode; 53 | SetConsoleCursorInfo(StdHandle, &cci); 54 | } 55 | 56 | class console final { 57 | SHORT w, h; 58 | std::size_t offset = 0; 59 | CHAR_INFO *buffer = nullptr; 60 | WORD attri = 0; 61 | public: 62 | console() = delete; 63 | 64 | console(std::size_t width, std::size_t height) : w(width), h(height), buffer(new CHAR_INFO[w * h]) {} 65 | 66 | ~console() 67 | { 68 | delete[] buffer; 69 | } 70 | 71 | void set_color(int textcolor, int bgcolor) 72 | { 73 | attri = textcolor + (bgcolor - 8) * 16; 74 | } 75 | 76 | void reset() 77 | { 78 | set_color(15, 8); 79 | } 80 | 81 | void put_char(char ch) 82 | { 83 | buffer[offset].Attributes = attri; 84 | buffer[offset].Char.AsciiChar = ch; 85 | ++offset; 86 | } 87 | 88 | void flush() 89 | { 90 | static CONSOLE_SCREEN_BUFFER_INFO csbi; 91 | GetConsoleScreenBufferInfo(StdHandle, &csbi); 92 | WriteConsoleOutput(StdHandle, buffer, {w, h}, {0, 0}, &csbi.srWindow); 93 | } 94 | }; 95 | 96 | static void set_title(const char *title) 97 | { 98 | SetConsoleTitle(title); 99 | } 100 | 101 | static void set_color(int textcolor, int bgcolor) 102 | { 103 | SetConsoleTextAttribute(StdHandle, textcolor + (bgcolor - 8) * 16); 104 | } 105 | 106 | static void reset() 107 | { 108 | set_color(15, 8); 109 | } 110 | 111 | static void clrscr() 112 | { 113 | system("cls"); 114 | } 115 | 116 | static int getch() 117 | { 118 | return ::getch(); 119 | } 120 | 121 | static int kbhit() 122 | { 123 | return ::kbhit(); 124 | } 125 | } -------------------------------------------------------------------------------- /darwin/win32_module.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * Covariant Darwin Universal Character Graphics Library 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Copyright (C) 2018 Michael Lee(李登淳) 18 | * Email: mikecovlee@163.com 19 | * Github: https://github.com/mikecovlee 20 | */ 21 | #include 22 | #include 23 | #include 24 | 25 | #ifdef DARWIN_FORCE_BUILTIN 26 | 27 | #include "./win32_adapter.cpp" 28 | 29 | #endif 30 | namespace darwin { 31 | class win32_module_adapter : public module_adapter { 32 | HINSTANCE m_handle = nullptr; 33 | platform_adapter *m_adapter = nullptr; 34 | 35 | static void force_exit(int); 36 | 37 | static void handle_segfault(int); 38 | 39 | public: 40 | win32_module_adapter() {} 41 | 42 | virtual ~win32_module_adapter() {} 43 | 44 | virtual status get_state() const override 45 | { 46 | if (m_adapter != nullptr) 47 | return status::ready; 48 | else 49 | return status::leisure; 50 | } 51 | 52 | virtual results load_module(const std::string &path) override 53 | { 54 | signal(SIGSEGV, handle_segfault); 55 | signal(SIGINT, force_exit); 56 | signal(SIGABRT, force_exit); 57 | #ifdef DARWIN_FORCE_BUILTIN 58 | m_adapter = module_resource(); 59 | #else 60 | m_handle = LoadLibrary(path.c_str()); 61 | if (m_handle == nullptr) return results::failure; 62 | module_enterance enterance = (module_enterance) GetProcAddress(m_handle, module_enterance_name); 63 | m_adapter = enterance(); 64 | #endif 65 | if (m_adapter == nullptr) return results::failure; 66 | return results::success; 67 | } 68 | 69 | virtual results free_module() override 70 | { 71 | signal(SIGSEGV, nullptr); 72 | signal(SIGINT, nullptr); 73 | signal(SIGABRT, nullptr); 74 | #ifndef DARWIN_FORCE_BUILTIN 75 | FreeLibrary(m_handle); 76 | m_handle = nullptr; 77 | #endif 78 | m_adapter = nullptr; 79 | return results::success; 80 | } 81 | 82 | virtual platform_adapter *get_platform_adapter() override 83 | { 84 | return this->m_adapter; 85 | } 86 | } dwin32module; 87 | 88 | static darwin_rt runtime(&dwin32module); 89 | } 90 | 91 | void darwin::win32_module_adapter::force_exit(int flag) 92 | { 93 | printf("Darwin have been exited safety.\n"); 94 | runtime.exit(); 95 | std::exit(0); 96 | } 97 | 98 | void darwin::win32_module_adapter::handle_segfault(int flag) 99 | { 100 | printf("Your program have some problem about the Segmentation Fault.Please check your program after we terminate this program.\n"); 101 | printf("Darwin have been exited safety.\n"); 102 | runtime.exit(); 103 | std::exit(-1); 104 | } 105 | -------------------------------------------------------------------------------- /examples/cdpf_drawer.cpp: -------------------------------------------------------------------------------- 1 | #define DARWIN_FORCE_BUILTIN 2 | #define DARWIN_DISABLE_LOG 3 | #include "../darwin/darwin.hpp" 4 | #include 5 | #include 6 | #include 7 | using namespace darwin; 8 | class cdpf_drawer final { 9 | picture mPic; 10 | public: 11 | cdpf_drawer()=default; 12 | cdpf_drawer(const cdpf_drawer&)=delete; 13 | ~cdpf_drawer()=default; 14 | void save() 15 | { 16 | std::deque buf; 17 | outfs out; 18 | serial_picture(&mPic,buf); 19 | auto pic=runtime.get_drawable(); 20 | sync_clock clock(60); 21 | std::string str0("Please enter a file path"),buff; 22 | bool run=true; 23 | while(run) { 24 | clock.reset(); 25 | if(runtime.is_kb_hit()) { 26 | char ch=runtime.get_kb_hit(); 27 | switch(ch) { 28 | default: 29 | buff+=ch; 30 | break; 31 | case 127: 32 | if(!buff.empty()) 33 | buff.pop_back(); 34 | break; 35 | case ' ': 36 | out.open(buff); 37 | for(auto& c:buf) 38 | out.printf("%c",c); 39 | out.flush(); 40 | run=false; 41 | break; 42 | } 43 | } 44 | pic->clear(); 45 | int str_size=(str0.size()>buff.size()?str0.size()+2:buff.size()+2); 46 | pic->draw_rect(0.5*(pic->get_width()-str_size-2),0.5*pic->get_height()-2,str_size+2,5,pixel(' ',true,false,colors::black,colors::blue)); 47 | pic->fill_rect(0.5*(pic->get_width()-str_size),0.5*pic->get_height()-1,str_size,3,pixel(' ',true,false,colors::black,colors::cyan)); 48 | pic->draw_string(0.5*(pic->get_width()-str_size-2)+1,0.5*pic->get_height()-2,str0,pixel(' ',true,false,colors::white,colors::blue)); 49 | pic->draw_string(0.5*(pic->get_width()-str_size)+1,0.5*pic->get_height(),buff,pixel(' ',true,false,colors::white,colors::cyan)); 50 | runtime.update_drawable(); 51 | clock.sync(); 52 | } 53 | } 54 | void about() 55 | { 56 | auto pic=runtime.get_drawable(); 57 | sync_clock clock(60); 58 | std::string str0("About This Software"),buff("Copyright (C) 2017 Covariant Studio"); 59 | bool run=true; 60 | while(run) { 61 | clock.reset(); 62 | if(runtime.is_kb_hit()) { 63 | runtime.get_kb_hit(); 64 | run=false; 65 | } 66 | pic->clear(); 67 | int str_size=(str0.size()>buff.size()?str0.size()+2:buff.size()+2); 68 | pic->draw_rect(0.5*(pic->get_width()-str_size-2),0.5*pic->get_height()-2,str_size+2,5,pixel(' ',true,false,colors::black,colors::blue)); 69 | pic->fill_rect(0.5*(pic->get_width()-str_size),0.5*pic->get_height()-1,str_size,3,pixel(' ',true,false,colors::black,colors::cyan)); 70 | pic->draw_string(0.5*(pic->get_width()-str_size-2)+1,0.5*pic->get_height()-2,str0,pixel(' ',true,false,colors::white,colors::blue)); 71 | pic->draw_string(0.5*(pic->get_width()-str_size)+1,0.5*pic->get_height(),buff,pixel(' ',true,false,colors::white,colors::cyan)); 72 | runtime.update_drawable(); 73 | clock.sync(); 74 | } 75 | } 76 | void open_exsist() 77 | { 78 | std::deque buf; 79 | auto pic=runtime.get_drawable(); 80 | sync_clock clock(60); 81 | std::string str0("Please enter a file path"),buff; 82 | auto func0=[&] { 83 | std::ifstream in(buff); 84 | for(char c; in.get(c); buf.push_back(c)); 85 | unserial_picture(&mPic,buf); 86 | }; 87 | bool run=true; 88 | while(run) { 89 | clock.reset(); 90 | if(runtime.is_kb_hit()) { 91 | char ch=runtime.get_kb_hit(); 92 | switch(ch) { 93 | default: 94 | buff+=ch; 95 | break; 96 | case 127: 97 | if(!buff.empty()) 98 | buff.pop_back(); 99 | break; 100 | case ' ': 101 | func0(); 102 | run=false; 103 | break; 104 | } 105 | } 106 | pic->clear(); 107 | int str_size=(str0.size()>buff.size()?str0.size()+2:buff.size()+2); 108 | pic->draw_rect(0.5*(pic->get_width()-str_size-2),0.5*pic->get_height()-2,str_size+2,5,pixel(' ',true,false,colors::black,colors::blue)); 109 | pic->fill_rect(0.5*(pic->get_width()-str_size),0.5*pic->get_height()-1,str_size,3,pixel(' ',true,false,colors::black,colors::cyan)); 110 | pic->draw_string(0.5*(pic->get_width()-str_size-2)+1,0.5*pic->get_height()-2,str0,pixel(' ',true,false,colors::white,colors::blue)); 111 | pic->draw_string(0.5*(pic->get_width()-str_size)+1,0.5*pic->get_height(),buff,pixel(' ',true,false,colors::white,colors::cyan)); 112 | runtime.update_drawable(); 113 | clock.sync(); 114 | } 115 | } 116 | void new_picture() 117 | { 118 | auto pic=runtime.get_drawable(); 119 | sync_clock clock(60); 120 | std::string buff0,buff1; 121 | std::string but0("Default"),but1("OK"); 122 | int select=0; 123 | int limit=5; 124 | bool run=true; 125 | while(run) { 126 | clock.reset(); 127 | if(runtime.is_kb_hit()) { 128 | char ch=runtime.get_kb_hit(); 129 | switch(ch) { 130 | case 's': 131 | if(select<3) 132 | ++select; 133 | break; 134 | case 'w': 135 | if(select>0) 136 | --select; 137 | break; 138 | case 127: 139 | switch(select) { 140 | case 0: 141 | if(!buff0.empty()) 142 | buff0.pop_back(); 143 | break; 144 | case 1: 145 | if(!buff1.empty()) 146 | buff1.pop_back(); 147 | break; 148 | } 149 | break; 150 | case '\t': 151 | if(select<3) 152 | ++select; 153 | else 154 | select=0; 155 | break; 156 | case ' ': 157 | switch(select) { 158 | default: 159 | if(select<2) 160 | ++select; 161 | break; 162 | case 2: 163 | buff0=std::to_string(pic->get_width()-2); 164 | buff1=std::to_string(pic->get_height()-2); 165 | break; 166 | case 3: 167 | mPic.clear(); 168 | mPic.resize(std::stoul(buff0),std::stoul(buff1)); 169 | mPic.fill(pixel(' ',true,false,colors::black,colors::white)); 170 | run=false; 171 | break; 172 | } 173 | break; 174 | default: 175 | switch(select) { 176 | case 0: 177 | if(ch>47&&ch<58&&buff0.size()47&&ch<58&&buff1.size()clear(); 196 | pic->draw_rect(0.25*pic->get_width(),0.25*pic->get_height(),0.5*pic->get_width(),0.5*pic->get_height(),pixel(' ',true,false,colors::black,colors::blue)); 197 | pic->fill_rect(0.25*pic->get_width()+1,0.25*pic->get_height()+1,0.5*pic->get_width()-2,0.5*pic->get_height()-2,pixel(' ',true,false,colors::black,colors::cyan)); 198 | pic->draw_string(0.25*pic->get_width()+1,0.25*pic->get_height(),"CDPF Drawer v1.0-New Picture",pixel(' ',true,false,colors::white,colors::blue)); 199 | pic->draw_string(0.25*pic->get_width()+4,0.25*pic->get_height()+2,"Picture Width:",pixel(' ',true,false,colors::white,colors::cyan)); 200 | pic->draw_string(0.25*pic->get_width()+4,0.25*pic->get_height()+4,"Picture Height:",pixel(' ',true,false,colors::white,colors::cyan)); 201 | pic->draw_line(0.25*pic->get_width()+4,0.25*pic->get_height()+3,0.25*pic->get_width()+4+limit,0.25*pic->get_height()+3,pixel(' ',true,false,colors::white,colors::white)); 202 | pic->draw_line(0.25*pic->get_width()+4,0.25*pic->get_height()+5,0.25*pic->get_width()+4+limit,0.25*pic->get_height()+5,pixel(' ',true,false,colors::white,colors::white)); 203 | pic->draw_string(0.25*pic->get_width()+4,0.25*pic->get_height()+3,buff0,pixel(' ',true,false,colors::black,colors::white)); 204 | pic->draw_string(0.25*pic->get_width()+4,0.25*pic->get_height()+5,buff1,pixel(' ',true,false,colors::black,colors::white)); 205 | if(select==2) 206 | pic->draw_rect(0.25*pic->get_width()+3,0.75*pic->get_height()-5,but0.size()+2,3,pixel('#',true,false,colors::blue,colors::blue)); 207 | else 208 | pic->draw_rect(0.25*pic->get_width()+3,0.75*pic->get_height()-5,but0.size()+2,3,pixel(' ',true,false,colors::blue,colors::blue)); 209 | pic->draw_string(0.25*pic->get_width()+4,0.75*pic->get_height()-4,but0,pixel(' ',true,false,colors::white,colors::blue)); 210 | if(select==3) 211 | pic->draw_rect(0.25*pic->get_width()+3+but0.size()+4,0.75*pic->get_height()-5,but1.size()+2,3,pixel('#',true,false,colors::blue,colors::blue)); 212 | else 213 | pic->draw_rect(0.25*pic->get_width()+3+but0.size()+4,0.75*pic->get_height()-5,but1.size()+2,3,pixel(' ',true,false,colors::blue,colors::blue)); 214 | pic->draw_string(0.25*pic->get_width()+4+but0.size()+4,0.75*pic->get_height()-4,but1,pixel(' ',true,false,colors::white,colors::blue)); 215 | if(select<2) 216 | pic->draw_string(0.25*pic->get_width()+2,0.25*pic->get_height()+3+2*select,"->",pixel(' ',true,false,colors::white,colors::cyan)); 217 | runtime.update_drawable(); 218 | clock.sync(); 219 | } 220 | } 221 | void start() 222 | { 223 | auto pic=runtime.get_drawable(); 224 | sync_clock clock(60); 225 | int select=0; 226 | bool run=true; 227 | while(run) { 228 | clock.reset(); 229 | if(runtime.is_kb_hit()) { 230 | switch(runtime.get_kb_hit()) { 231 | case '\t': 232 | if(select<3) 233 | ++select; 234 | else 235 | select=0; 236 | break; 237 | case 's': 238 | if(select<3) 239 | ++select; 240 | break; 241 | case 'w': 242 | if(select>0) 243 | --select; 244 | break; 245 | case ' ': 246 | switch(select) { 247 | case 0: 248 | new_picture(); 249 | run=false; 250 | break; 251 | case 1: 252 | open_exsist(); 253 | run=false; 254 | break; 255 | case 2: 256 | about(); 257 | break; 258 | case 3: 259 | runtime.exit(); 260 | std::exit(0); 261 | run=false; 262 | break; 263 | } 264 | break; 265 | } 266 | } 267 | runtime.fit_drawable(); 268 | pic->clear(); 269 | pic->draw_rect(0.25*pic->get_width(),0.25*pic->get_height(),0.5*pic->get_width(),0.5*pic->get_height(),pixel(' ',true,false,colors::black,colors::blue)); 270 | pic->fill_rect(0.25*pic->get_width()+1,0.25*pic->get_height()+1,0.5*pic->get_width()-2,0.5*pic->get_height()-2,pixel(' ',true,false,colors::black,colors::cyan)); 271 | pic->draw_string(0.25*pic->get_width()+1,0.25*pic->get_height(),"CDPF Drawer v1.0-Welcome",pixel(' ',true,false,colors::white,colors::blue)); 272 | pic->draw_string(0.25*pic->get_width()+4,0.5*(pic->get_height()-6),"Getting start",pixel(' ',true,false,colors::white,colors::red)); 273 | pic->draw_string(0.25*pic->get_width()+4,0.5*(pic->get_height()-6)+2,"New Picture",pixel(' ',true,false,colors::white,colors::cyan)); 274 | pic->draw_string(0.25*pic->get_width()+4,0.5*(pic->get_height()-6)+3,"Open Exsist Picture",pixel(' ',true,false,colors::white,colors::cyan)); 275 | pic->draw_string(0.25*pic->get_width()+4,0.5*(pic->get_height()-6)+4,"About This Software",pixel(' ',true,false,colors::white,colors::cyan)); 276 | pic->draw_string(0.25*pic->get_width()+4,0.5*(pic->get_height()-6)+5,"Exit",pixel(' ',true,false,colors::white,colors::cyan)); 277 | pic->draw_string(0.25*pic->get_width()+2,0.5*(pic->get_height()-6)+2+select,"->",pixel(' ',true,false,colors::white,colors::cyan)); 278 | runtime.update_drawable(); 279 | clock.sync(); 280 | } 281 | } 282 | void menu() 283 | { 284 | auto pic=runtime.get_drawable(); 285 | sync_clock clock(60); 286 | int select=0; 287 | bool run=true; 288 | while(run) { 289 | clock.reset(); 290 | if(runtime.is_kb_hit()) { 291 | switch(runtime.get_kb_hit()) { 292 | case '\t': 293 | if(select<5) 294 | ++select; 295 | else 296 | select=0; 297 | break; 298 | case 's': 299 | if(select<5) 300 | ++select; 301 | break; 302 | case 'w': 303 | if(select>0) 304 | --select; 305 | break; 306 | case ' ': 307 | switch(select) { 308 | case 0: 309 | return; 310 | break; 311 | case 1: 312 | save(); 313 | return; 314 | break; 315 | case 2: 316 | new_picture(); 317 | break; 318 | case 3: 319 | open_exsist(); 320 | break; 321 | case 4: 322 | about(); 323 | break; 324 | case 5: 325 | runtime.exit(); 326 | std::exit(0); 327 | break; 328 | } 329 | run=false; 330 | break; 331 | } 332 | } 333 | runtime.fit_drawable(); 334 | pic->clear(); 335 | pic->draw_rect(0.25*pic->get_width(),0.25*pic->get_height(),0.5*pic->get_width(),0.5*pic->get_height(),pixel(' ',true,false,colors::black,colors::blue)); 336 | pic->fill_rect(0.25*pic->get_width()+1,0.25*pic->get_height()+1,0.5*pic->get_width()-2,0.5*pic->get_height()-2,pixel(' ',true,false,colors::black,colors::cyan)); 337 | pic->draw_string(0.25*pic->get_width()+1,0.25*pic->get_height(),"CDPF Drawer v1.0-Menu",pixel(' ',true,false,colors::white,colors::blue)); 338 | pic->draw_string(0.25*pic->get_width()+4,0.5*(pic->get_height()-8),"Pause",pixel(' ',true,false,colors::white,colors::red)); 339 | pic->draw_string(0.25*pic->get_width()+4,0.5*(pic->get_height()-8)+2,"Continue",pixel(' ',true,false,colors::white,colors::cyan)); 340 | pic->draw_string(0.25*pic->get_width()+4,0.5*(pic->get_height()-8)+3,"Save",pixel(' ',true,false,colors::white,colors::cyan)); 341 | pic->draw_string(0.25*pic->get_width()+4,0.5*(pic->get_height()-8)+4,"New Picture",pixel(' ',true,false,colors::white,colors::cyan)); 342 | pic->draw_string(0.25*pic->get_width()+4,0.5*(pic->get_height()-8)+5,"Open Exsist Picture",pixel(' ',true,false,colors::white,colors::cyan)); 343 | pic->draw_string(0.25*pic->get_width()+4,0.5*(pic->get_height()-8)+6,"About This Software",pixel(' ',true,false,colors::white,colors::cyan)); 344 | pic->draw_string(0.25*pic->get_width()+4,0.5*(pic->get_height()-8)+7,"Exit",pixel(' ',true,false,colors::white,colors::cyan)); 345 | pic->draw_string(0.25*pic->get_width()+2,0.5*(pic->get_height()-8)+2+select,"->",pixel(' ',true,false,colors::white,colors::cyan)); 346 | runtime.update_drawable(); 347 | clock.sync(); 348 | } 349 | } 350 | void main() 351 | { 352 | auto pic=runtime.get_drawable(); 353 | sync_clock clock(60); 354 | int mode=0; 355 | int str_size=0; 356 | std::string str0(" Please Select The Front Color(Key 1~8) "),str1(" Please Select The Back Color(Key 1~8) "),str2(" Please Select The Character "),str3("Please Input String"); 357 | std::string buff; 358 | bool fmod=false; 359 | std::deque> vertex; 360 | bool run=true; 361 | int cx(0),cy(0); 362 | pixel pix('@',true,false,colors::black,colors::white); 363 | while(run) { 364 | clock.reset(); 365 | if(runtime.is_kb_hit()) { 366 | if(mode==4) { 367 | char ch=runtime.get_kb_hit(); 368 | switch(ch) { 369 | default: 370 | buff+=ch; 371 | break; 372 | case 127: 373 | if(!buff.empty()) 374 | buff.pop_back(); 375 | break; 376 | case ' ': 377 | mPic.draw_string(0.5*mPic.get_width()+2+vertex[0][0],0.5*mPic.get_height()+vertex[0][1],buff,pix); 378 | buff.clear(); 379 | vertex.clear(); 380 | mode=0; 381 | break; 382 | } 383 | } 384 | else if(mode==7) { 385 | pix.set_char(runtime.get_kb_hit()); 386 | mode=0; 387 | } 388 | else { 389 | switch(runtime.get_kb_hit()) { 390 | case '1': 391 | switch(mode) { 392 | case 5: 393 | pix.set_front_color(colors::white); 394 | break; 395 | case 6: 396 | pix.set_back_color(colors::white); 397 | break; 398 | } 399 | mode=0; 400 | break; 401 | case '2': 402 | switch(mode) { 403 | case 5: 404 | pix.set_front_color(colors::black); 405 | break; 406 | case 6: 407 | pix.set_back_color(colors::black); 408 | break; 409 | } 410 | mode=0; 411 | break; 412 | case '3': 413 | switch(mode) { 414 | case 5: 415 | pix.set_front_color(colors::red); 416 | break; 417 | case 6: 418 | pix.set_back_color(colors::red); 419 | break; 420 | } 421 | mode=0; 422 | break; 423 | case '4': 424 | switch(mode) { 425 | case 5: 426 | pix.set_front_color(colors::green); 427 | break; 428 | case 6: 429 | pix.set_back_color(colors::green); 430 | break; 431 | } 432 | mode=0; 433 | break; 434 | case '5': 435 | switch(mode) { 436 | case 5: 437 | pix.set_front_color(colors::blue); 438 | break; 439 | case 6: 440 | pix.set_back_color(colors::blue); 441 | break; 442 | } 443 | mode=0; 444 | break; 445 | case '6': 446 | switch(mode) { 447 | case 5: 448 | pix.set_front_color(colors::pink); 449 | break; 450 | case 6: 451 | pix.set_back_color(colors::pink); 452 | break; 453 | } 454 | mode=0; 455 | break; 456 | case '7': 457 | switch(mode) { 458 | case 5: 459 | pix.set_front_color(colors::yellow); 460 | break; 461 | case 6: 462 | pix.set_back_color(colors::yellow); 463 | break; 464 | } 465 | mode=0; 466 | break; 467 | case '8': 468 | switch(mode) { 469 | case 5: 470 | pix.set_front_color(colors::cyan); 471 | break; 472 | case 6: 473 | pix.set_back_color(colors::cyan); 474 | break; 475 | } 476 | mode=0; 477 | break; 478 | case 's': 479 | ++cy; 480 | break; 481 | case 'w': 482 | --cy; 483 | break; 484 | case 'd': 485 | ++cx; 486 | break; 487 | case 'a': 488 | --cx; 489 | break; 490 | case 'q': 491 | mPic.draw_pixel(0.5*mPic.get_width()+cx+2,0.5*mPic.get_height()+cy,pix); 492 | break; 493 | case 'e': 494 | switch(mode) { 495 | case 0: 496 | if(fmod) { 497 | vertex.push_back({cx,cy}); 498 | mode=11; 499 | fmod=false; 500 | } 501 | else 502 | mode=1; 503 | break; 504 | case 1: 505 | mode=0; 506 | break; 507 | case 11: 508 | mPic.draw_line(0.5*mPic.get_width()+2+vertex[0][0],0.5*mPic.get_height()+vertex[0][1],0.5*mPic.get_width()+cx+2,0.5*mPic.get_height()+cy,pix); 509 | vertex.clear(); 510 | mode=0; 511 | break; 512 | } 513 | break; 514 | case 'r': 515 | switch(mode) { 516 | case 0: 517 | vertex.push_back({cx,cy}); 518 | if(fmod) { 519 | mode=12; 520 | fmod=false; 521 | } 522 | else 523 | mode=2; 524 | break; 525 | case 2: 526 | mPic.draw_rect(0.5*mPic.get_width()+2+vertex[0][0],0.5*mPic.get_height()+vertex[0][1],cx-vertex[0][0],cy-vertex[0][1],pix); 527 | vertex.clear(); 528 | mode=0; 529 | break; 530 | case 12: 531 | mPic.fill_rect(0.5*mPic.get_width()+2+vertex[0][0],0.5*mPic.get_height()+vertex[0][1],cx-vertex[0][0],cy-vertex[0][1],pix); 532 | vertex.clear(); 533 | mode=0; 534 | break; 535 | } 536 | break; 537 | case 't': 538 | switch(mode) { 539 | case 0: 540 | vertex.push_back({cx,cy}); 541 | if(fmod) { 542 | mode=23; 543 | fmod=false; 544 | } 545 | else 546 | mode=3; 547 | break; 548 | case 3: 549 | vertex.push_back({cx,cy}); 550 | mode=13; 551 | break; 552 | case 13: 553 | mPic.draw_triangle(0.5*mPic.get_width()+2+vertex[0][0],0.5*mPic.get_height()+vertex[0][1],0.5*mPic.get_width()+2+vertex[1][0],0.5*mPic.get_height()+vertex[1][1],0.5*mPic.get_width()+cx+2,0.5*mPic.get_height()+cy,pix); 554 | vertex.clear(); 555 | mode=0; 556 | break; 557 | case 23: 558 | vertex.push_back({cx,cy}); 559 | mode=33; 560 | break; 561 | case 33: 562 | mPic.fill_triangle(0.5*mPic.get_width()+2+vertex[0][0],0.5*mPic.get_height()+vertex[0][1],0.5*mPic.get_width()+2+vertex[1][0],0.5*mPic.get_height()+vertex[1][1],0.5*mPic.get_width()+cx+2,0.5*mPic.get_height()+cy,pix); 563 | vertex.clear(); 564 | mode=0; 565 | break; 566 | } 567 | break; 568 | case 'g': 569 | vertex.push_back({cx,cy}); 570 | mode=mode==0?4:0; 571 | break; 572 | case 'z': 573 | mode=mode==0?5:0; 574 | break; 575 | case 'x': 576 | mode=mode==0?6:0; 577 | break; 578 | case 'c': 579 | mode=mode==0?7:0; 580 | break; 581 | case 'f': 582 | fmod=fmod?false:true; 583 | break; 584 | case 'm': 585 | menu(); 586 | break; 587 | } 588 | } 589 | } 590 | runtime.fit_drawable(); 591 | switch(mode) { 592 | case 1: 593 | mPic.draw_pixel(0.5*mPic.get_width()+cx+2,0.5*mPic.get_height()+cy,pix); 594 | break; 595 | } 596 | pic->clear(); 597 | pic->draw_picture(0.5*(pic->get_width()-mPic.get_width()),0.5*(pic->get_height()-mPic.get_height()),mPic); 598 | pic->draw_rect(0,0,pic->get_width(),pic->get_height(),pixel(' ',true,false,colors::black,colors::blue)); 599 | pic->draw_string(1,0,"CDPF Drawer v1.0",pixel(' ',true,false,colors::white,colors::blue)); 600 | if(fmod) 601 | pic->draw_string(1,pic->get_height()-1,"Function Mode",pixel(' ',true,false,colors::white,colors::blue)); 602 | switch(mode) { 603 | case 2: 604 | pic->draw_rect(0.5*pic->get_width()+2+vertex[0][0],0.5*pic->get_height()+vertex[0][1],cx-vertex[0][0],cy-vertex[0][1],pix); 605 | break; 606 | case 3: 607 | pic->draw_line(0.5*pic->get_width()+2+vertex[0][0],0.5*pic->get_height()+vertex[0][1],0.5*pic->get_width()+cx+2,0.5*pic->get_height()+cy,pix); 608 | break; 609 | case 4: 610 | str_size=(str3.size()>buff.size()?str3.size()+2:buff.size()+2); 611 | pic->draw_rect(0.5*(pic->get_width()-str_size-2),0.5*pic->get_height()-2,str_size+2,5,pixel(' ',true,false,colors::black,colors::blue)); 612 | pic->fill_rect(0.5*(pic->get_width()-str_size),0.5*pic->get_height()-1,str_size,3,pixel(' ',true,false,colors::black,colors::cyan)); 613 | pic->draw_string(0.5*(pic->get_width()-str_size-2)+1,0.5*pic->get_height()-2,str3,pixel(' ',true,false,colors::white,colors::blue)); 614 | pic->draw_string(0.5*(pic->get_width()-str_size)+1,0.5*pic->get_height(),buff,pixel(' ',true,false,colors::white,colors::cyan)); 615 | break; 616 | case 5: 617 | pic->draw_rect(0.5*(pic->get_width()-str0.size()-2),0.5*pic->get_height()-2,str0.size()+2,5,pixel(' ',true,false,colors::black,colors::blue)); 618 | pic->fill_rect(0.5*(pic->get_width()-str0.size()),0.5*pic->get_height()-1,str0.size(),3,pixel(' ',true,false,colors::black,colors::cyan)); 619 | pic->draw_string(0.5*(pic->get_width()-str0.size()-2)+1,0.5*pic->get_height()-2,"Select Front Color",pixel(' ',true,false,colors::white,colors::blue)); 620 | pic->draw_string(0.5*(pic->get_width()-str0.size()),0.5*pic->get_height(),str0,pixel(' ',true,false,colors::white,colors::cyan)); 621 | break; 622 | case 6: 623 | pic->draw_rect(0.5*(pic->get_width()-str1.size()-2),0.5*pic->get_height()-2,str1.size()+2,5,pixel(' ',true,false,colors::black,colors::blue)); 624 | pic->fill_rect(0.5*(pic->get_width()-str1.size()),0.5*pic->get_height()-1,str1.size(),3,pixel(' ',true,false,colors::black,colors::cyan)); 625 | pic->draw_string(0.5*(pic->get_width()-str1.size()-2)+1,0.5*pic->get_height()-2,"Select Back Color",pixel(' ',true,false,colors::white,colors::blue)); 626 | pic->draw_string(0.5*(pic->get_width()-str1.size()),0.5*pic->get_height(),str1,pixel(' ',true,false,colors::white,colors::cyan)); 627 | break; 628 | case 7: 629 | pic->draw_rect(0.5*(pic->get_width()-str2.size()-2),0.5*pic->get_height()-2,str2.size()+2,5,pixel(' ',true,false,colors::black,colors::blue)); 630 | pic->fill_rect(0.5*(pic->get_width()-str2.size()),0.5*pic->get_height()-1,str2.size(),3,pixel(' ',true,false,colors::black,colors::cyan)); 631 | pic->draw_string(0.5*(pic->get_width()-str2.size()-2)+1,0.5*pic->get_height()-2,"Select Character",pixel(' ',true,false,colors::white,colors::blue)); 632 | pic->draw_string(0.5*(pic->get_width()-str2.size()),0.5*pic->get_height(),str2,pixel(' ',true,false,colors::white,colors::cyan)); 633 | break; 634 | case 11: 635 | pic->draw_line(0.5*pic->get_width()+2+vertex[0][0],0.5*pic->get_height()+vertex[0][1],0.5*pic->get_width()+cx+2,0.5*pic->get_height()+cy,pix); 636 | break; 637 | case 12: 638 | pic->fill_rect(0.5*pic->get_width()+2+vertex[0][0],0.5*pic->get_height()+vertex[0][1],cx-vertex[0][0],cy-vertex[0][1],pix); 639 | break; 640 | case 13: 641 | pic->draw_triangle(0.5*pic->get_width()+2+vertex[0][0],0.5*pic->get_height()+vertex[0][1],0.5*pic->get_width()+2+vertex[1][0],0.5*pic->get_height()+vertex[1][1],0.5*pic->get_width()+cx+2,0.5*pic->get_height()+cy,pix); 642 | break; 643 | case 23: 644 | pic->draw_line(0.5*pic->get_width()+2+vertex[0][0],0.5*pic->get_height()+vertex[0][1],0.5*pic->get_width()+cx+2,0.5*pic->get_height()+cy,pix); 645 | break; 646 | case 33: 647 | pic->fill_triangle(0.5*pic->get_width()+2+vertex[0][0],0.5*pic->get_height()+vertex[0][1],0.5*pic->get_width()+2+vertex[1][0],0.5*pic->get_height()+vertex[1][1],0.5*pic->get_width()+cx+2,0.5*pic->get_height()+cy,pix); 648 | break; 649 | } 650 | pic->draw_string(0.5*pic->get_width()+cx,0.5*pic->get_height()+cy,"->",pixel(' ',true,false,colors::white,colors::black)); 651 | pic->draw_pixel(0.5*pic->get_width()+cx+2,0.5*pic->get_height()+cy,pix); 652 | runtime.update_drawable(); 653 | clock.sync(); 654 | } 655 | } 656 | }; 657 | int main() 658 | { 659 | runtime.load("./darwin.module"); 660 | cdpf_drawer main_prog; 661 | main_prog.start(); 662 | main_prog.main(); 663 | runtime.exit(); 664 | return 0; 665 | } 666 | -------------------------------------------------------------------------------- /examples/cdpf_viewer.cpp: -------------------------------------------------------------------------------- 1 | #define DARWIN_FORCE_BUILTIN 2 | #define DARWIN_DISABLE_LOG 3 | #include "../darwin/darwin.hpp" 4 | #include 5 | #include 6 | int main(int arg_size,char** arg_array) 7 | { 8 | if(arg_size<2) { 9 | printf("Wrong size of arguments.\n"); 10 | return -1; 11 | } 12 | using namespace darwin; 13 | std::ifstream infs(arg_array[1]); 14 | if(!infs) { 15 | printf("File open error.\n"); 16 | return -1; 17 | } 18 | std::deque buff; 19 | for(char c; infs.get(c); buff.push_back(c)); 20 | picture pic; 21 | runtime.load("./darwin.module"); 22 | unserial_picture(&pic,buff); 23 | std::string head="Covariant Darwin Picture File Viewer 1.0"; 24 | std::string help="Q:Exit W:Up S:Down A:Left D:Right"; 25 | std::string info="File:\""+std::string(arg_array[1])+"\" Width:"+std::to_string(pic.get_width())+"pix Height:"+std::to_string(pic.get_height())+"pix"; 26 | auto dpic=runtime.get_drawable(); 27 | int x(0),y(0); 28 | bool running=true; 29 | sync_clock clock(30); 30 | while(running) { 31 | if(runtime.is_kb_hit()) { 32 | switch(runtime.get_kb_hit()) { 33 | case 'w': 34 | --y; 35 | break; 36 | case 's': 37 | ++y; 38 | break; 39 | case 'a': 40 | --x; 41 | break; 42 | case 'd': 43 | ++x; 44 | break; 45 | case 'q': 46 | running=false; 47 | break; 48 | } 49 | } 50 | clock.reset(); 51 | runtime.fit_drawable(); 52 | dpic->fill(pixel(' ',true,false,colors::white,colors::white)); 53 | dpic->draw_picture((dpic->get_width()-pic.get_width())/2+x,(dpic->get_height()-pic.get_height())/2+y,pic); 54 | dpic->draw_line(0,0,dpic->get_width()-1,0,pixel(' ',true,false,colors::blue,colors::blue)); 55 | dpic->draw_line(0,1,dpic->get_width()-1,1,pixel(' ',true,false,colors::cyan,colors::cyan)); 56 | dpic->draw_line(0,dpic->get_height()-1,dpic->get_width()-1,dpic->get_height()-1,pixel(' ',true,false,colors::blue,colors::blue)); 57 | dpic->draw_string(0,0,head,pixel(' ',true,false,colors::white,colors::blue)); 58 | dpic->draw_string(0,1,help,pixel(' ',true,false,colors::white,colors::cyan)); 59 | dpic->draw_string(0,dpic->get_height()-1,info,pixel(' ',true,false,colors::white,colors::blue)); 60 | runtime.update_drawable(); 61 | clock.sync(); 62 | } 63 | runtime.exit(); 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /examples/snake.cpp: -------------------------------------------------------------------------------- 1 | #define DARWIN_FORCE_BUILTIN 2 | #include "../darwin/darwin.hpp" 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | using position_type=std::array; 9 | darwin::pixel head_pix('#',true,false,darwin::colors::white,darwin::colors::black); 10 | darwin::pixel body_pix('+',true,false,darwin::colors::white,darwin::colors::black); 11 | darwin::pixel food_pix('@',true,false,darwin::colors::white,darwin::colors::black); 12 | std::deque snake_body; 13 | position_type snake_head= {0,0}; 14 | position_type food= {0,0}; 15 | int heading=2; 16 | /* 17 | 1=left 18 | 2=right 19 | -1=up 20 | -2=down 21 | */ 22 | int init_long=5; 23 | bool god_mode=false; 24 | bool cross_wall=false; 25 | int hard=3; 26 | int score=0; 27 | 28 | void die() 29 | { 30 | auto pic=darwin::runtime.get_drawable(); 31 | darwin::sync_clock clock(30); 32 | std::string str0="You die!Your score is "+std::to_string(score); 33 | std::string str1="Press any key to continue..."; 34 | while(true) { 35 | clock.reset(); 36 | if(darwin::runtime.is_kb_hit()) { 37 | darwin::runtime.get_kb_hit(); 38 | break; 39 | } 40 | pic->clear(); 41 | pic->fill(darwin::pixel(' ',true,false,darwin::colors::white,darwin::colors::red)); 42 | pic->draw_string(0.5*(pic->get_width()-str0.size()),0.5*pic->get_height(),str0,darwin::pixel(' ',true,false,darwin::colors::white,darwin::colors::red)); 43 | pic->draw_string(0.5*(pic->get_width()-str1.size()),pic->get_height()-1,str1,darwin::pixel(' ',true,false,darwin::colors::white,darwin::colors::red)); 44 | darwin::runtime.update_drawable(); 45 | clock.sync(); 46 | } 47 | } 48 | void gen_food() 49 | { 50 | auto pic=darwin::runtime.get_drawable(); 51 | bool is_fit=true; 52 | while(is_fit) { 53 | food[0]=darwin::rand(0,pic->get_width()-1); 54 | food[1]=darwin::rand(0,pic->get_height()-1); 55 | is_fit=false; 56 | for(auto& p:snake_body) { 57 | if(p[0]==food[0]&&p[1]==food[1]) 58 | is_fit=true; 59 | } 60 | } 61 | } 62 | void start() 63 | { 64 | auto pic=darwin::runtime.get_drawable(); 65 | darwin::sync_clock clock(30); 66 | snake_head= {init_long,0.5*pic->get_height()}; 67 | for(int i=0; iget_width()-1; 111 | else if(snake_head[0]>pic->get_width()-1) 112 | snake_head[0]-=pic->get_width()-1; 113 | else if(snake_head[1]<0) 114 | snake_head[1]+=pic->get_height()-1; 115 | else if(snake_head[1]>pic->get_height()-1) 116 | snake_head[1]-=pic->get_height()-1; 117 | } 118 | else if(snake_head[0]<0||snake_head[0]>pic->get_width()-1||snake_head[1]<0||snake_head[1]>pic->get_height()-1) { 119 | die(); 120 | return; 121 | } 122 | if(!god_mode) { 123 | for(auto& p:snake_body) { 124 | if(p[0]==snake_head[0]&&p[1]==snake_head[1]) { 125 | die(); 126 | return; 127 | } 128 | } 129 | } 130 | snake_body.push_front(snake_head); 131 | if(snake_head[0]==food[0]&&snake_head[1]==food[1]) { 132 | gen_food(); 133 | score+=10*(1.0/hard); 134 | } 135 | else 136 | snake_body.pop_back(); 137 | frame=0; 138 | } 139 | pic->clear(); 140 | for(auto& p:snake_body) 141 | pic->draw_pixel(p[0],p[1],body_pix); 142 | pic->draw_pixel(snake_head[0],snake_head[1],head_pix); 143 | pic->draw_pixel(food[0],food[1],food_pix); 144 | darwin::runtime.update_drawable(); 145 | ++frame; 146 | clock.sync(); 147 | } 148 | } 149 | int main() 150 | { 151 | darwin::timer::delay(1000); 152 | darwin::runtime.load("./darwin.module"); 153 | darwin::runtime.fit_drawable(); 154 | while(true) { 155 | snake_body.clear(); 156 | heading=2; 157 | start(); 158 | } 159 | return 0; 160 | } -------------------------------------------------------------------------------- /examples/texteditor.cpp: -------------------------------------------------------------------------------- 1 | // 关闭Darwin UCGL的扩展功能和日志功能 2 | #define DARWIN_FORCE_BUILTIN 3 | #define DARWIN_DISABLE_LOG 4 | // 引入Darwin UCGL 5 | #include 6 | // 其他STL 7 | #include 8 | #include 9 | #include 10 | #include 11 | // 引入Darwin UCGL名称空间 12 | using namespace darwin; 13 | // 按键映射 14 | namespace keymap { 15 | constexpr int key_esc = 27; 16 | constexpr int key_enter_unix = '\r'; 17 | constexpr int key_enter_win32 = '\n'; 18 | constexpr int key_delete_unix = 127; 19 | constexpr int key_delete_win32 = '\b'; 20 | constexpr int key_tab = '\t'; 21 | constexpr int key_up = 'w'; 22 | constexpr int key_down = 's'; 23 | constexpr int key_left = 'a'; 24 | constexpr int key_right = 'd'; 25 | constexpr int key_mode = 'i'; 26 | constexpr int key_quit = 'q'; 27 | constexpr int key_reload = 'r'; 28 | constexpr int key_save = 'x'; 29 | constexpr int key_find = 'f'; 30 | constexpr int key_info = 'v'; 31 | } // namespace keymap 32 | // 文本编辑器类 33 | class texteditor final { 34 | // 渲染器属性 35 | std::size_t render_border = 0, render_offx = 0, render_offy = 0; 36 | // 光标属性 37 | std::size_t cursor_count = 0, cursor_x = 0, cursor_y = 0; 38 | // 窗口属性 39 | std::size_t last_win_width = 0, last_win_height = 0; 40 | // 文本 Buffer 41 | std::vector file_buffer; 42 | // 查找高亮属性 43 | std::size_t find_x = 0, find_y = 0; 44 | // 帧 Buffer 45 | darwin::drawable *pic = nullptr; 46 | // 状态 47 | bool text_modified = false; 48 | bool insert_mode = false; 49 | bool found_text = false; 50 | bool expect_txt = false; 51 | // 字符 Buffer 52 | std::string find_target; 53 | std::string char_buffer; 54 | std::string file_path; 55 | // 挂起任务 56 | enum class await_process_type { 57 | null, 58 | quit, 59 | reload 60 | } await_process = await_process_type::null; 61 | // 编辑器状态 62 | enum class editor_status_type { 63 | null, 64 | asking, 65 | confirm, 66 | info, 67 | setup, 68 | notfound, 69 | finding, 70 | replace 71 | } editor_status = editor_status_type::null; 72 | 73 | public: 74 | // Tab 缩进宽度 75 | unsigned int tab_indent = 4; 76 | // 构造函数 & 赋值函数 77 | texteditor() = default; 78 | texteditor(const texteditor &) = delete; 79 | texteditor &operator=(const texteditor &) = delete; 80 | 81 | private: 82 | // 文件操作 83 | void load_file(const std::string &path) 84 | { 85 | std::ifstream in(file_path); 86 | for (std::string line; std::getline(in, line); file_buffer.push_back(line)) { 87 | for (std::size_t i = 0; i < line.size(); ++i) { 88 | if (line[i] == '\t') { 89 | line[i] = ' '; 90 | for (std::size_t count = 0; count < tab_indent - 1; ++count) 91 | line.insert(line.begin() + i, ' '); 92 | } 93 | } 94 | } 95 | } 96 | void save_file(const std::string &path) 97 | { 98 | std::ofstream out(path); 99 | for (std::size_t idx = 0; idx < file_buffer.size() - 1; ++idx) 100 | out << file_buffer[idx] << std::endl; 101 | out << file_buffer[file_buffer.size() - 1] << std::flush; 102 | text_modified = false; 103 | } 104 | // 各类属性 105 | std::size_t text_area_width() 106 | { 107 | return pic->get_width() - render_border - 5; 108 | } 109 | std::size_t text_area_height() 110 | { 111 | return pic->get_height() - 2; 112 | } 113 | std::size_t text_offset_x() 114 | { 115 | return render_offx + cursor_x; 116 | } 117 | std::size_t text_offset_y() 118 | { 119 | return render_offy + cursor_y; 120 | } 121 | std::string ¤t_line() 122 | { 123 | return file_buffer[text_offset_y()]; 124 | } 125 | // 工具 126 | void force_refresh() 127 | { 128 | cursor_count = 59; 129 | } 130 | bool is_validate_path_char(int ch) 131 | { 132 | return std::isalnum(ch) || ch == ' ' || ch == '\\' || ch == '/'; 133 | } 134 | void adjust_cursor(std::size_t x_offset) 135 | { 136 | if (x_offset < cursor_x + render_offx) { 137 | x_offset = cursor_x + render_offx - x_offset; 138 | for (; x_offset > 0 && cursor_x > 0; --x_offset, --cursor_x) 139 | ; 140 | for (; x_offset > 0 && render_offx > 0; --x_offset, --render_offx) 141 | ; 142 | if (cursor_x == 0 && render_offx < 4) 143 | std::swap(cursor_x, render_offx); 144 | } 145 | else { 146 | for (; cursor_x + render_offx < x_offset && cursor_x < pic->get_width() - 1; ++cursor_x) 147 | ; 148 | for (; cursor_x + render_offx < x_offset && cursor_x + render_offx < current_line().size(); ++render_offx) 149 | ; 150 | } 151 | } 152 | // 文本查找 153 | void reset_find() 154 | { 155 | find_x = find_y = 0; 156 | found_text = false; 157 | expect_txt = false; 158 | } 159 | void find() 160 | { 161 | while (find_y < file_buffer.size()) { 162 | auto &line = file_buffer[find_y]; 163 | auto pos = line.find(find_target, expect_txt ? find_x + 1 : 0); 164 | if (pos != std::string::npos) { 165 | if (!expect_txt || pos > find_x) { 166 | found_text = true; 167 | expect_txt = true; 168 | find_x = pos; 169 | break; 170 | } 171 | } 172 | expect_txt = false; 173 | find_x = 0; 174 | ++find_y; 175 | } 176 | if (found_text) { 177 | if (find_y == file_buffer.size()) { 178 | reset_find(); 179 | find(); 180 | } 181 | cursor_x = render_offx = 0; 182 | cursor_y = 0; 183 | if (find_y < file_buffer.size() - text_area_height()) 184 | render_offy = find_y > 4 ? find_y - 4 : 0; 185 | else 186 | render_offy = file_buffer.size() - text_area_height(); 187 | if (find_x + find_target.size() > text_area_width()) 188 | render_offx = find_x + find_target.size() - text_area_width() + 1; 189 | } 190 | } 191 | // 键盘事件处理 192 | void key_up() 193 | { 194 | if (cursor_y > 0) 195 | --cursor_y; 196 | else if (render_offy > 0) 197 | --render_offy; 198 | if (cursor_x + render_offx > current_line().size()) 199 | adjust_cursor(current_line().size()); 200 | } 201 | void key_down() 202 | { 203 | if (cursor_y < text_area_height() - 1) 204 | ++cursor_y; 205 | else if (render_offy + text_area_height() < file_buffer.size()) 206 | ++render_offy; 207 | if (cursor_x + render_offx > current_line().size()) 208 | adjust_cursor(current_line().size()); 209 | } 210 | void key_left() 211 | { 212 | if (cursor_x > 0) 213 | --cursor_x; 214 | else if (render_offx > 0) 215 | --render_offx; 216 | else if (cursor_y + render_offy > 0) { 217 | if (render_offy > 0) 218 | --render_offy; 219 | else if (cursor_y > 0) 220 | --cursor_y; 221 | adjust_cursor(current_line().size()); 222 | } 223 | } 224 | void key_right() 225 | { 226 | if (cursor_x < text_area_width()) { 227 | if (text_offset_x() < current_line().size()) 228 | ++cursor_x; 229 | else if (text_offset_y() < file_buffer.size() - 1) { 230 | cursor_x = render_offx = 0; 231 | key_down(); 232 | } 233 | } 234 | else if (text_offset_x() < current_line().size()) 235 | ++render_offx; 236 | else if (render_offy + text_area_height() < file_buffer.size()) { 237 | render_offx = 0; 238 | ++render_offy; 239 | } 240 | } 241 | void key_enter() 242 | { 243 | auto &line = current_line(); 244 | auto line_current = line.substr(0, text_offset_x()); 245 | auto line_next = line.substr(text_offset_x()); 246 | line = line_current; 247 | file_buffer.insert(file_buffer.begin() + text_offset_y() + 1, line_next); 248 | key_down(); 249 | cursor_x = render_offx = 0; 250 | text_modified = true; 251 | } 252 | void key_delete() 253 | { 254 | auto &line = current_line(); 255 | if (cursor_x + render_offx == 0) { 256 | if (text_offset_y() != 0) { 257 | key_up(); 258 | adjust_cursor(current_line().size()); 259 | current_line().append(line); 260 | file_buffer.erase(file_buffer.begin() + text_offset_y() + 1); 261 | text_modified = true; 262 | } 263 | } 264 | else { 265 | if (line.size() > 0) { 266 | line.erase(text_offset_x() - 1, 1); 267 | key_left(); 268 | text_modified = true; 269 | } 270 | } 271 | } 272 | // 事件响应 273 | bool window_resized() 274 | { 275 | if (last_win_width != pic->get_width() || last_win_height != pic->get_height()) { 276 | last_win_width = pic->get_width(); 277 | last_win_height = pic->get_height(); 278 | while (cursor_x >= text_area_width()) { 279 | --cursor_x; 280 | ++render_offx; 281 | } 282 | return true; 283 | } 284 | else 285 | return false; 286 | } 287 | bool keyboard_input() 288 | { 289 | if (await_process != await_process_type::null) 290 | return true; 291 | if (darwin::runtime.is_kb_hit()) { 292 | cursor_count = 0; 293 | if (insert_mode) { 294 | int key = darwin::runtime.get_kb_hit(); 295 | if (key != keymap::key_esc) { 296 | auto &line = current_line(); 297 | switch (key) { 298 | case keymap::key_enter_unix: 299 | case keymap::key_enter_win32: 300 | key_enter(); 301 | break; 302 | case keymap::key_delete_unix: 303 | case keymap::key_delete_win32: 304 | key_delete(); 305 | break; 306 | case keymap::key_tab: 307 | line.insert(text_offset_x(), std::string(tab_indent, ' ')); 308 | adjust_cursor(text_offset_x() + tab_indent); 309 | text_modified = true; 310 | break; 311 | default: 312 | line.insert(line.begin() + text_offset_x(), key); 313 | adjust_cursor(text_offset_x() + 1); 314 | text_modified = true; 315 | break; 316 | } 317 | } 318 | else 319 | insert_mode = false; 320 | } 321 | else { 322 | switch (std::tolower(darwin::runtime.get_kb_hit())) { 323 | case keymap::key_up: 324 | key_up(); 325 | break; 326 | case keymap::key_down: 327 | key_down(); 328 | break; 329 | case keymap::key_left: 330 | key_left(); 331 | break; 332 | case keymap::key_right: 333 | key_right(); 334 | break; 335 | case keymap::key_mode: 336 | insert_mode = true; 337 | break; 338 | case keymap::key_save: 339 | save_file(file_path); 340 | break; 341 | case keymap::key_reload: 342 | if (text_modified) { 343 | await_process = await_process_type::reload; 344 | editor_status = editor_status_type::asking; 345 | } 346 | else { 347 | file_buffer.clear(); 348 | load_file(file_path); 349 | } 350 | break; 351 | case keymap::key_quit: 352 | if (text_modified) { 353 | await_process = await_process_type::quit; 354 | editor_status = editor_status_type::asking; 355 | } 356 | else 357 | std::exit(0); 358 | break; 359 | case keymap::key_find: 360 | find_target.clear(); 361 | char_buffer.clear(); 362 | editor_status = editor_status_type::setup; 363 | break; 364 | case keymap::key_info: { 365 | std::size_t char_count = 0; 366 | for (auto &line : file_buffer) 367 | char_count += line.size(); 368 | char_buffer = std::to_string(file_buffer.size()) + " line(s), " + std::to_string(char_count) + " character(s)"; 369 | editor_status = editor_status_type::info; 370 | break; 371 | } 372 | default: 373 | insert_mode = true; 374 | break; 375 | } 376 | } 377 | return true; 378 | } 379 | else 380 | return false; 381 | } 382 | bool cursor_timer() 383 | { 384 | ++cursor_count; 385 | if (cursor_count == 30 || cursor_count == 60) 386 | return true; 387 | else 388 | return false; 389 | } 390 | // 渲染函数 391 | void render_linenum() 392 | { 393 | render_border = std::to_string(file_buffer.size()).size(); 394 | for (std::size_t i = 0; i < text_area_height(); ++i) { 395 | pic->draw_line(2, i + 1, 1 + render_border, i + 1, pixel(' ', true, false, colors::white, colors::white)); 396 | std::string txt = std::to_string(render_offy + i + 1); 397 | pic->draw_string(2 + (render_border - txt.size()), i + 1, txt, pixel(' ', true, false, colors::black, colors::white)); 398 | } 399 | } 400 | void render_text() 401 | { 402 | for (std::size_t y = 0; y < text_area_height() && y + render_offy < file_buffer.size(); ++y) { 403 | for (std::size_t x = 0; x < text_area_width() && x + render_offx < file_buffer[y + render_offy].size(); ++x) { 404 | char ch = file_buffer[y + render_offy][x + render_offx]; 405 | if (found_text && x + render_offx >= find_x && x + render_offx < find_x + find_target.size() && y + render_offy == find_y) 406 | pic->draw_pixel(x + 3 + render_border, y + 1, pixel(ch, true, false, colors::white, colors::pink)); 407 | else 408 | pic->draw_pixel(x + 3 + render_border, y + 1, pixel(ch, true, false, colors::white, colors::black)); 409 | } 410 | } 411 | } 412 | void render_cursor() 413 | { 414 | if (cursor_count <= 30) 415 | darwin::runtime.get_drawable()->draw_pixel(cursor_x + 3 + render_border, cursor_y + 1, pixel(' ', true, false, colors::white, colors::white)); 416 | else if (cursor_count == 60) 417 | cursor_count = 0; 418 | } 419 | void draw_basic_frame() 420 | { 421 | pic->fill(pixel(' ', true, false, colors::white, colors::black)); 422 | pic->draw_line(0, 0, pic->get_width() - 1, 0, pixel(' ', true, false, colors::blue, colors::blue)); 423 | if (text_modified) 424 | pic->draw_string(2, 0, "Darwin UCGL Texteditor: " + file_path + " (Unsaved)", pixel(' ', true, false, colors::white, colors::blue)); 425 | else 426 | pic->draw_string(2, 0, "Darwin UCGL Texteditor: " + file_path, pixel(' ', true, false, colors::white, colors::blue)); 427 | pic->draw_line(0, 0, 0, pic->get_height() - 1, pixel(' ', true, false, colors::blue, colors::blue)); 428 | pic->draw_line(1, 0, 1, pic->get_height() - 1, pixel(' ', true, false, colors::blue, colors::blue)); 429 | pic->draw_line(pic->get_width() - 1, 0, pic->get_width() - 1, pic->get_height() - 1, pixel(' ', true, false, colors::blue, colors::blue)); 430 | pic->draw_line(pic->get_width() - 2, 0, pic->get_width() - 2, pic->get_height() - 1, pixel(' ', true, false, colors::blue, colors::blue)); 431 | render_linenum(); 432 | render_text(); 433 | } 434 | // 处理挂起任务 435 | void exec_await_process() 436 | { 437 | switch (await_process) { 438 | default: 439 | break; 440 | case await_process_type::quit: 441 | std::exit(0); 442 | break; 443 | case await_process_type::reload: 444 | text_modified = false; 445 | file_buffer.clear(); 446 | load_file(file_path); 447 | break; 448 | } 449 | await_process = await_process_type::null; 450 | } 451 | // 运行状态实现 452 | void run_normal() 453 | { 454 | darwin::runtime.fit_drawable(); 455 | if (window_resized() || keyboard_input() || cursor_timer()) { 456 | draw_basic_frame(); 457 | pic->draw_line(2, pic->get_height() - 1, pic->get_width() - 3, pic->get_height() - 1, pixel(' ', true, false, colors::blue, colors::blue)); 458 | if (insert_mode) 459 | pic->draw_string(2, pic->get_height() - 1, "INSERT (Press ESC to exit)", pixel(' ', true, false, colors::white, colors::blue)); 460 | else 461 | pic->draw_string(2, pic->get_height() - 1, "WASD: Move I: Insert X: Save R: Reload F: Find V: Info Q: Exit", pixel(' ', true, false, colors::white, colors::blue)); 462 | render_cursor(); 463 | darwin::runtime.update_drawable(); 464 | } 465 | } 466 | void run_unsaved_asking() 467 | { 468 | darwin::runtime.fit_drawable(); 469 | draw_basic_frame(); 470 | pic->draw_line(2, pic->get_height() - 1, pic->get_width() - 3, pic->get_height() - 1, pixel(' ', true, false, colors::red, colors::red)); 471 | pic->draw_string(2, pic->get_height() - 1, "File unsaved, continue without saving? (Yes(Y), No(N) or other key to cancel)", pixel(' ', true, false, colors::white, colors::red)); 472 | if (darwin::runtime.is_kb_hit()) { 473 | switch (std::tolower(darwin::runtime.get_kb_hit())) { 474 | case 'y': 475 | exec_await_process(); 476 | editor_status = editor_status_type::null; 477 | force_refresh(); 478 | break; 479 | case 'n': 480 | editor_status = editor_status_type::confirm; 481 | char_buffer = file_path; 482 | break; 483 | default: 484 | await_process = await_process_type::null; 485 | editor_status = editor_status_type::null; 486 | force_refresh(); 487 | break; 488 | } 489 | } 490 | darwin::runtime.update_drawable(); 491 | } 492 | void run_unsaved_confirm() 493 | { 494 | darwin::runtime.fit_drawable(); 495 | draw_basic_frame(); 496 | pic->draw_line(2, pic->get_height() - 1, pic->get_width() - 3, pic->get_height() - 1, pixel(' ', true, false, colors::cyan, colors::cyan)); 497 | pic->draw_string(2, pic->get_height() - 1, "Save to: " + char_buffer, pixel(' ', true, false, colors::white, colors::cyan)); 498 | if (darwin::runtime.is_kb_hit()) { 499 | int key = 0; 500 | switch (key = std::tolower(darwin::runtime.get_kb_hit())) { 501 | case keymap::key_delete_unix: 502 | case keymap::key_delete_win32: 503 | if (!char_buffer.empty()) 504 | char_buffer.pop_back(); 505 | break; 506 | case keymap::key_enter_unix: 507 | case keymap::key_enter_win32: 508 | save_file(char_buffer); 509 | exec_await_process(); 510 | editor_status = editor_status_type::null; 511 | force_refresh(); 512 | break; 513 | default: 514 | if (is_validate_path_char(key)) 515 | char_buffer.push_back(key); 516 | break; 517 | } 518 | } 519 | darwin::runtime.update_drawable(); 520 | } 521 | void run_find_setup() 522 | { 523 | darwin::runtime.fit_drawable(); 524 | draw_basic_frame(); 525 | pic->draw_line(2, pic->get_height() - 1, pic->get_width() - 3, pic->get_height() - 1, pixel(' ', true, false, colors::white, colors::white)); 526 | pic->draw_string(2, pic->get_height() - 1, "Find: " + find_target, pixel(' ', true, false, colors::black, colors::white)); 527 | if (darwin::runtime.is_kb_hit()) { 528 | int key = 0; 529 | switch (key = std::tolower(darwin::runtime.get_kb_hit())) { 530 | case keymap::key_delete_unix: 531 | case keymap::key_delete_win32: 532 | if (!find_target.empty()) 533 | find_target.pop_back(); 534 | break; 535 | case keymap::key_enter_unix: 536 | case keymap::key_enter_win32: 537 | if (find_target.empty()) { 538 | editor_status = editor_status_type::null; 539 | force_refresh(); 540 | break; 541 | } 542 | find(); 543 | if (found_text) 544 | editor_status = editor_status_type::finding; 545 | else 546 | editor_status = editor_status_type::notfound; 547 | break; 548 | default: 549 | if (!std::iscntrl(key)) 550 | find_target.push_back(key); 551 | break; 552 | } 553 | } 554 | darwin::runtime.update_drawable(); 555 | } 556 | void run_notfound() 557 | { 558 | darwin::runtime.fit_drawable(); 559 | draw_basic_frame(); 560 | pic->draw_line(2, pic->get_height() - 1, pic->get_width() - 3, pic->get_height() - 1, pixel(' ', true, false, colors::white, colors::white)); 561 | pic->draw_string(2, pic->get_height() - 1, "Find: \"" + find_target + "\" not found (Press Q to close)", pixel(' ', true, false, colors::black, colors::white)); 562 | if (darwin::runtime.is_kb_hit()) { 563 | if (std::tolower(darwin::runtime.get_kb_hit()) == 'q') { 564 | editor_status = editor_status_type::null; 565 | force_refresh(); 566 | } 567 | } 568 | darwin::runtime.update_drawable(); 569 | } 570 | void run_finding() 571 | { 572 | darwin::runtime.fit_drawable(); 573 | draw_basic_frame(); 574 | pic->draw_line(2, pic->get_height() - 1, pic->get_width() - 3, pic->get_height() - 1, pixel(' ', true, false, colors::white, colors::white)); 575 | pic->draw_string(2, pic->get_height() - 1, "Find: \"" + find_target + "\" (Next(N) Replace(R) Quit(Q))", pixel(' ', true, false, colors::black, colors::white)); 576 | if (darwin::runtime.is_kb_hit()) { 577 | switch (std::tolower(darwin::runtime.get_kb_hit())) { 578 | case 'n': 579 | find(); 580 | break; 581 | case 'r': 582 | editor_status = editor_status_type::replace; 583 | break; 584 | case 'q': 585 | reset_find(); 586 | if (text_offset_x() > current_line().size()) 587 | adjust_cursor(current_line().size()); 588 | editor_status = editor_status_type::null; 589 | force_refresh(); 590 | break; 591 | } 592 | } 593 | darwin::runtime.update_drawable(); 594 | } 595 | void run_replace() 596 | { 597 | darwin::runtime.fit_drawable(); 598 | draw_basic_frame(); 599 | pic->draw_line(2, pic->get_height() - 1, pic->get_width() - 3, pic->get_height() - 1, pixel(' ', true, false, colors::pink, colors::pink)); 600 | pic->draw_string(2, pic->get_height() - 1, "Replace: " + char_buffer, pixel(' ', true, false, colors::white, colors::pink)); 601 | if (darwin::runtime.is_kb_hit()) { 602 | int key = 0; 603 | switch (key = std::tolower(darwin::runtime.get_kb_hit())) { 604 | case keymap::key_delete_unix: 605 | case keymap::key_delete_win32: 606 | if (!char_buffer.empty()) 607 | char_buffer.pop_back(); 608 | break; 609 | case keymap::key_enter_unix: 610 | case keymap::key_enter_win32: 611 | if (char_buffer != find_target) { 612 | text_modified = true; 613 | file_buffer[find_y].replace(find_x, find_target.size(), char_buffer); 614 | find(); 615 | if (found_text) 616 | editor_status = editor_status_type::finding; 617 | else { 618 | reset_find(); 619 | if (text_offset_x() > current_line().size()) 620 | adjust_cursor(current_line().size()); 621 | editor_status = editor_status_type::notfound; 622 | } 623 | } 624 | break; 625 | default: 626 | if (!std::iscntrl(key)) 627 | char_buffer.push_back(key); 628 | break; 629 | } 630 | } 631 | darwin::runtime.update_drawable(); 632 | } 633 | void run_info() 634 | { 635 | darwin::runtime.fit_drawable(); 636 | draw_basic_frame(); 637 | pic->draw_line(2, pic->get_height() - 1, pic->get_width() - 3, pic->get_height() - 1, pixel(' ', true, false, colors::yellow, colors::yellow)); 638 | pic->draw_string(2, pic->get_height() - 1, "File Info: " + char_buffer + " (Press Q to close)", pixel(' ', true, false, colors::white, colors::yellow)); 639 | if (darwin::runtime.is_kb_hit()) { 640 | if (std::tolower(darwin::runtime.get_kb_hit()) == 'q') { 641 | editor_status = editor_status_type::null; 642 | force_refresh(); 643 | } 644 | } 645 | darwin::runtime.update_drawable(); 646 | } 647 | 648 | public: 649 | // 主函数 650 | void run(const std::string &path) 651 | { 652 | file_path = path; 653 | load_file(file_path); 654 | darwin::runtime.load("./darwin.module"); 655 | darwin::runtime.fit_drawable(); 656 | pic = darwin::runtime.get_drawable(); 657 | darwin::sync_clock clock(60); 658 | while (true) { 659 | clock.reset(); 660 | switch (editor_status) { 661 | case editor_status_type::null: 662 | run_normal(); 663 | break; 664 | case editor_status_type::asking: 665 | run_unsaved_asking(); 666 | break; 667 | case editor_status_type::confirm: 668 | run_unsaved_confirm(); 669 | break; 670 | case editor_status_type::setup: 671 | run_find_setup(); 672 | break; 673 | case editor_status_type::notfound: 674 | run_notfound(); 675 | break; 676 | case editor_status_type::finding: 677 | run_finding(); 678 | break; 679 | case editor_status_type::replace: 680 | run_replace(); 681 | break; 682 | case editor_status_type::info: 683 | run_info(); 684 | break; 685 | } 686 | clock.sync(); 687 | } 688 | } 689 | }; 690 | // 启动进程 691 | int main(int argc, char **argv) 692 | { 693 | if (argc != 2) 694 | return -1; 695 | texteditor editor; 696 | editor.run(argv[1]); 697 | return 0; 698 | } -------------------------------------------------------------------------------- /format.bat: -------------------------------------------------------------------------------- 1 | @del /F /Q .\examples\*.gch 2 | @del /F /Q .\darwin\*.gch 3 | @del /F /Q .\tests\*.gch 4 | @astyle .\examples\*.* 5 | @astyle .\darwin\*.* 6 | @astyle .\tests\*.* 7 | @del /F /Q .\examples\*.orig 8 | @del /F /Q .\darwin\*.orig 9 | @del /F /Q .\tests\*.orig 10 | @astyle -A4 -N -t .\examples\*.* 11 | @astyle -A4 -N -t .\darwin\*.* 12 | @astyle -A4 -N -t .\tests\*.* 13 | @del /F /Q .\examples\*.orig 14 | @del /F /Q .\darwin\*.orig 15 | @del /F /Q .\tests\*.orig -------------------------------------------------------------------------------- /format.sh: -------------------------------------------------------------------------------- 1 | #/bin/sh 2 | rm ./examples/*.gch 3 | rm ./darwin/*.gch 4 | rm ./tests/*.gch 5 | astyle ./examples/*.* 6 | astyle ./darwin/*.* 7 | astyle ./tests/*.* 8 | rm ./examples/*.orig 9 | rm ./darwin/*.orig 10 | rm ./tests/*.orig 11 | astyle -A4 -N -t ./examples/*.* 12 | astyle -A4 -N -t ./darwin/*.* 13 | astyle -A4 -N -t ./tests/*.* 14 | rm ./examples/*.orig 15 | rm ./darwin/*.orig 16 | rm ./tests/*.orig -------------------------------------------------------------------------------- /reference.md: -------------------------------------------------------------------------------- 1 | #Covariant Darwin Reference 2 | ##第一部分:概述 3 | **Covariant Darwin**是一款使用C++编程语言编写的跨平台字符图形库,编译Darwin需要您的编译器支持C++11/14标准。 4 | ##第二部分:编译和运行 5 | Darwin除C++ STL和必要的C API之外,核心组件不依赖其他程序库。Darwin能够自动选择适用于您平台的适配程序库和组件(编译期),但您可能需要家在一些为Darwin编写的扩展模块才能使程序正常运转。Darwin在GCC和LLVM Clang编译器上能够编译通过,其他编译器未作测试。 6 | ##第三部分:基础组件 7 | ###1:计时器(`headers/timer.hpp`) 8 | Darwin计时器(`darwin::timer`)是一个类(`class`),但是其成员都是静态成员。使用类包装计时器主要目的是隐藏内部实现。 9 | ####类型定义 10 | `darwin::timer_t` 定义为无符号长整数类型(`unsigned long`),用于储存时间。 11 | `darwin::timer::time_unit` 定义为 `enum class`,包含了5个枚举量: 12 | 1. `nano_sec` 纳秒* 13 | 2. `micro_sec` 微秒* 14 | 3. `milli_sec` 毫秒 15 | 4. `second` 秒 16 | 5. `minute` 分 17 | > *注意:带星号的内容在Microsoft Windows®操作系统中可能无法正常工作。* 18 | 19 | ####静态方法 20 | `static void reset()` 重置时钟,在程序加载时会自动重置一次。 21 | `static timer_t time(time_unit unit=time_unit::milli_sec)` 获取从上次重置时钟到函数执行的时间,时间单位默认为毫秒。 22 | `static void delay(timer_t time,time_unit unit=time_unit::milli_sec)` 使当前线程阻塞一段时间,时间单位默认为毫秒。 23 | `static timer_t measure(const std::function& func,time_unit unit=time_unit::milli_sec)` 计算一个函数消耗的时间,这个函数必须为void()形式的函数。时间单位默认为毫秒。 24 | ###2:调试器(`headers/debugger.hpp`) 25 | ####宏定义 26 | `Darwin_log(msg)` 向日志中输出一条消息。 27 | `Darwin_Warning(msg)` 报告一条警告消息,可以通过定义`DARWIN_IGNORE_WARNING`宏来忽略所有警告,可以通过定义`DARWIN_STRICT_CHECK`宏让Darwin收到警告后立刻停止运行。 28 | `Darwin_Error(msg)` 报告一条错误消息,Darwin会立刻停止运行。 29 | Darwin会默认将所有日志输出到可执行文件同一目录中的`darwin_runtime.log`文件中。可以通过`Darwin_Set_Log_Path(path)`宏来重新设置日志文件的路径。 30 | ####输出文件流类(`darwin::outfs`) 31 | 特点:**不可继承,非线程安全,不可复制,RAII** 32 | #####构造函数 33 | `outfs::outfs()` 构建一个空的实例。 34 | `outfs::outfs(const char*)`和`outfs::outfs(const std::string&)` 打开一个文件,如文件不存在将会新建一个文件。 35 | #####成员函数 36 | `bool usable() const noexcept` 获取可用状态。 37 | `void open(const char*)`和`void open(const std::string&)` 打开一个文件,如已经打开另一个文件则操作无效。 38 | `void close()` 关闭已经打开的文件。 39 | `template void printf(const char* format,...)` 格式化输出。 40 | `void flush()` 刷新文件流。 41 | #####示例 42 | ```c++ 43 | #include "./headers/debugger.hpp" 44 | int main() 45 | { 46 | darwin::outfs out("./abc.txt"); 47 | if(!out) return -1; 48 | out.printf("%s\n","Hello,World!"); 49 | return 0; 50 | } 51 | ``` 52 | ##第四部分:核心组件 53 | ###1:`enum class`定义 54 | **`darwin::status`(状态):** 55 | 1. `null`(空) 56 | 2. `ready`(就绪) 57 | 3. `busy`(忙碌) 58 | 4. `leisure`(空闲) 59 | 5. `error`(错误) 60 | 61 | **`darwin::results`(结果):** 62 | 1. `null`(空) 63 | 2. `success`(成功) 64 | 3. `failure`(失败) 65 | 66 | **`darwin::colors`(颜色):** 67 | 1. `white`(白色) 68 | 2. `black`(黑色) 69 | 3. `red`(红色) 70 | 4. `green`(绿色) 71 | 5. `blue`(蓝色) 72 | 6. `pink`(粉色) 73 | 7. `yellow`(黄色) 74 | 8. `cyan`(青色) 75 | 76 | **`darwin::attris`(属性):** 77 | 1. `bright`(高亮) 78 | 2. `underline`(下划线) 79 | 80 | ###2:像素类(`darwin::pixel`) 81 | 特点:**不可继承,非线程安全** 82 | ####构造函数 83 | `pixel::pixel()` 构造一个默认的实例(空格,无高亮,无下划线,前白后黑) 。 84 | `pixel::pixel(const pixel&)` 复制构造。 85 | `pixel::pixel(char,bool,bool,colors,colors)` 自定义构造,五个参数分别指定字符,是否高亮,是否下划线,前景色和背景色。 86 | ####成员函数 87 | `void set_char(char)` 设置pixel的字符。 88 | `char get_char() const` 获取pixel的字符。 89 | `void set_front_color(colors)` 设置pixel的前景色。 90 | `colors get_front_color() const` 获取pixel的前景色。 91 | `void set_back_color(colors)` 设置pixel的背景色。 92 | `colors get_back_color() const` 获取pixel的背景色。 93 | `void set_colors(const std::array&)` 批量设置pixel的颜色,数组第一个元素为前景色,第二个元素是背景色。 94 | `const std::array& get_colors() const` 批量获取pixel的颜色,数组第一个元素为前景色,第二个元素是背景色。 95 | `void set_bright(bool)` 设置高亮属性,`true`为开启,`false`为关闭。 96 | `bool is_bright() const` 获取高亮属性的状态。 97 | `void set_underline(bool)` 设置下划线属性,`true`为开启,`false`为关闭。 98 | `void is_underline() const` 获取下划线属性的状态。 99 | `void set_attris(const std::array&)` 批量设置pixel的属性,数组第一个元素为高亮,第二个元素为下划线。 100 | `const std::array& get_attris() const` 批量获取pixel的属性,数组第一个元素为高亮,第二个元素为下划线。 -------------------------------------------------------------------------------- /tests/test1.cpp: -------------------------------------------------------------------------------- 1 | #define DARWIN_FORCE_BUILTIN 2 | #include "../darwin/darwin.hpp" 3 | #include 4 | int main() 5 | { 6 | darwin::runtime.load("./darwin.module"); 7 | auto pic=darwin::runtime.get_drawable(); 8 | std::string greeting="Hello,World!"; 9 | darwin::pixel p(' ', true,false, darwin::colors::red,darwin::colors::white); 10 | darwin::sync_clock clock(30); 11 | while(true) { 12 | clock.reset(); 13 | darwin::runtime.fit_drawable(); 14 | p.set_char(' '); 15 | pic->fill(p); 16 | for(std::size_t x=0; xget_width(); ++x) { 17 | p.set_char(greeting[x]); 18 | pic->draw_pixel(x,0,p); 19 | } 20 | darwin::runtime.update_drawable(); 21 | clock.sync(); 22 | } 23 | return 0; 24 | } -------------------------------------------------------------------------------- /tests/test_draw_line.cpp: -------------------------------------------------------------------------------- 1 | #define DARWIN_FORCE_BUILTIN 2 | #define DARWIN_DISABLE_LOG 3 | #include "../darwin/darwin.hpp" 4 | int main() 5 | { 6 | darwin::runtime.load("./darwin.module"); 7 | auto pic=darwin::runtime.get_drawable(); 8 | darwin::sync_clock clock(30); 9 | int x0(0),y0(0),x1(1),y1(1); 10 | while(true) { 11 | if(darwin::runtime.is_kb_hit()) { 12 | switch(darwin::runtime.get_kb_hit()) { 13 | case 'w': 14 | --y0; 15 | break; 16 | case 's': 17 | ++y0; 18 | break; 19 | case 'a': 20 | --x0; 21 | break; 22 | case 'd': 23 | ++x0; 24 | break; 25 | case 'i': 26 | --y1; 27 | break; 28 | case 'k': 29 | ++y1; 30 | break; 31 | case 'j': 32 | --x1; 33 | break; 34 | case 'l': 35 | ++x1; 36 | break; 37 | case 'c': 38 | darwin::print_screen(); 39 | break; 40 | } 41 | } 42 | clock.reset(); 43 | darwin::runtime.fit_drawable(); 44 | pic->clear(); 45 | pic->draw_line(x0,y0,x1,y1,darwin::pixel('@',true,false,darwin::colors::blue,darwin::colors::white)); 46 | darwin::runtime.update_drawable(); 47 | clock.sync(); 48 | } 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /tests/test_game.cpp: -------------------------------------------------------------------------------- 1 | #define DARWIN_IGNORE_WARNING 2 | #define DARWIN_FORCE_BUILTIN 3 | #include "../darwin/darwin.hpp" 4 | #include 5 | 6 | struct sandbox { 7 | double gravity=10; 8 | double air_drop=5; 9 | double delta_time=0.1; 10 | } world; 11 | 12 | struct entity { 13 | double mass=0.5; 14 | double size=0.01; 15 | double speed_x=15; 16 | double speed_y=0; 17 | double posit_x=0; 18 | double posit_y=0; 19 | } ball; 20 | 21 | void run() 22 | { 23 | double ax(0),ay(0); 24 | if(ball.speed_x>0) 25 | ax=-(world.air_drop*ball.size*ball.speed_x)/ball.mass; 26 | if(ball.speed_y>0) 27 | ay=(ball.mass*world.gravity-world.air_drop*ball.size*ball.speed_y)/ball.mass; 28 | if(ball.speed_y==0) 29 | ay=(ball.mass*world.gravity)/ball.mass; 30 | if(ball.speed_y<0) 31 | ay=(ball.mass*world.gravity+std::abs(world.air_drop*ball.size*ball.speed_y))/ball.mass; 32 | ball.posit_x+=ball.speed_x*world.delta_time+0.5*ax*std::pow(world.delta_time,2); 33 | ball.posit_y+=ball.speed_y*world.delta_time+0.5*ay*std::pow(world.delta_time,2); 34 | ball.speed_x+=ax*world.delta_time; 35 | ball.speed_y+=ay*world.delta_time; 36 | } 37 | 38 | int main() 39 | { 40 | using namespace darwin; 41 | runtime.load("./darwin.module"); 42 | auto pic=runtime.get_drawable(); 43 | sync_clock clock(30); 44 | while(true) { 45 | clock.reset(); 46 | runtime.fit_drawable(); 47 | pic->clear(); 48 | pic->draw_string(0,0,"Simple Sandbox",pixel(' ', true,false, colors::black, colors::white)); 49 | if(ball.posit_x<0) ball.speed_x=std::abs(ball.speed_x); 50 | if(ball.posit_y<0) ball.speed_y=std::abs(ball.speed_y); 51 | if(ball.posit_x>pic->get_width()-1) ball.speed_x=-std::abs(ball.speed_x); 52 | if(ball.posit_y>pic->get_height()-1) ball.speed_y=-std::abs(ball.speed_y); 53 | run(); 54 | pic->draw_pixel(ball.posit_x,ball.posit_y,pixel('@', true,false, colors::white, colors::black)); 55 | runtime.update_drawable(); 56 | clock.sync(); 57 | } 58 | return 0; 59 | } -------------------------------------------------------------------------------- /tests/test_rect.cpp: -------------------------------------------------------------------------------- 1 | #define DARWIN_FORCE_BUILTIN 2 | #include "../darwin/darwin.hpp" 3 | #include 4 | #include 5 | int main() 6 | { 7 | std::string str; 8 | std::getline(std::cin,str); 9 | darwin::runtime.load("./darwin.module"); 10 | auto pic=darwin::runtime.get_drawable(); 11 | darwin::pixel pix(' ',true,false,darwin::colors::black,darwin::colors::white); 12 | darwin::sync_clock clock(60); 13 | while(true) { 14 | clock.reset(); 15 | darwin::runtime.fit_drawable(); 16 | pic->draw_rect(1,1,pic->get_width()-2,pic->get_height()-2,pix); 17 | pic->fill_rect(2,2,pic->get_width()-4,pic->get_height()-4,darwin::pixel(' ',true,false,darwin::colors::black,darwin::colors::cyan)); 18 | pic->draw_string(0.5*(pic->get_width()-str.size()),0.5*pic->get_height(),str,pix); 19 | darwin::runtime.update_drawable(); 20 | clock.sync(); 21 | } 22 | darwin::runtime.exit(); 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /tests/test_triangle.cpp: -------------------------------------------------------------------------------- 1 | #define DARWIN_FORCE_BUILTIN 2 | #define DARWIN_DISABLE_LOG 3 | #include "../darwin/darwin.hpp" 4 | int main() 5 | { 6 | darwin::runtime.load("./darwin.module"); 7 | auto pic=darwin::runtime.get_drawable(); 8 | darwin::runtime.fit_drawable(); 9 | darwin::sync_clock clock(30); 10 | std::deque> points= {{0,0},{int(pic->get_width()-1),0},{int(0.5*pic->get_width()),int(0.5*pic->get_height())}}; 11 | int focus=2; 12 | while(true) { 13 | if(darwin::runtime.is_kb_hit()) { 14 | switch(darwin::runtime.get_kb_hit()) { 15 | case 'w': 16 | --points[focus][1]; 17 | break; 18 | case 's': 19 | ++points[focus][1]; 20 | break; 21 | case 'a': 22 | --points[focus][0]; 23 | break; 24 | case 'd': 25 | ++points[focus][0]; 26 | break; 27 | case '1': 28 | focus=0; 29 | break; 30 | case '2': 31 | focus=1; 32 | break; 33 | case '3': 34 | focus=2; 35 | break; 36 | } 37 | } 38 | clock.reset(); 39 | darwin::runtime.fit_drawable(); 40 | pic->clear(); 41 | pic->fill_triangle(points[0][0],points[0][1],points[1][0],points[1][1],points[2][0],points[2][1],darwin::pixel(' ',true,false,darwin::colors::black,darwin::colors::white)); 42 | pic->draw_pixel(points[focus][0],points[focus][1],darwin::pixel('#',true,false,darwin::colors::black,darwin::colors::white)); 43 | darwin::runtime.update_drawable(); 44 | clock.sync(); 45 | } 46 | return 0; 47 | } 48 | --------------------------------------------------------------------------------