From b4fdd5a65905ec34d00fda8d80b0d20ed990a8db Mon Sep 17 00:00:00 2001 From: Alexander Popov Date: Wed, 16 Aug 2023 15:02:01 +0300 Subject: [PATCH] make Games 4 DOS easy --- .editorconfig | 23 ++++ .gitattributes | 6 + .gitignore | 1 + LICENSE | 21 +++ READ.ME | 4 + README.md | 7 + build.bat | 14 ++ examples/mouse.c | 48 +++++++ include/gdos.h | 228 ++++++++++++++++++++++++++++++++ screenshots/cursor_graphics.png | Bin 0 -> 2876 bytes screenshots/cursor_text.png | Bin 0 -> 2722 bytes 11 files changed, 352 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 READ.ME create mode 100644 README.md create mode 100644 build.bat create mode 100644 examples/mouse.c create mode 100644 include/gdos.h create mode 100644 screenshots/cursor_graphics.png create mode 100644 screenshots/cursor_text.png diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..55426ab --- /dev/null +++ b/.editorconfig @@ -0,0 +1,23 @@ +root = true + +[*] +indent_style = space +indent_size = 4 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[{*.c,*.h}] +end_of_line = crlf +indent_style = space +indent_size = 2 + +[*.bat] +end_of_line = crlf + +[*.md] +trim_trailing_whitespace = false + +[{LICENSE,READ.ME}] +end_of_line = crlf diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..e0c7431 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,6 @@ +* text=auto eol=lf +LICENSE eol=crlf +READ.ME eol=crlf +*.c eol=crlf +*.h eol=crlf +*.bat eol=crlf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d3594b6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.EXE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..42233f5 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/READ.ME b/READ.ME new file mode 100644 index 0000000..243727c --- /dev/null +++ b/READ.ME @@ -0,0 +1,4 @@ +Library for GameDev on DOS +========================== + +TBA diff --git a/README.md b/README.md new file mode 100644 index 0000000..4b8d1f9 --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# Library for GameDev 🕹️ on DOS 💽 + +## Screenshots + +![](screenshots/cursor_text.png) + +![](screenshots/cursor_graphics.png) diff --git a/build.bat b/build.bat new file mode 100644 index 0000000..d89b5f5 --- /dev/null +++ b/build.bat @@ -0,0 +1,14 @@ +:: Script for build code in DOS by TCC +:: Alexander Popov + +:: Clear old program +del MOUSE.EXE + +:: Compile program by Turbo C +M: +cd M:/TC +TCC.EXE -eS:/MOUSE.EXE S:/mouse.c +S: + +:: Run PROGRAM +MOUSE.EXE diff --git a/examples/mouse.c b/examples/mouse.c new file mode 100644 index 0000000..ae02d79 --- /dev/null +++ b/examples/mouse.c @@ -0,0 +1,48 @@ +/** + * Example mouse work + * + * Alexander Popov + * License: Unlicense + */ + +#include +#include + +void main() { + int mouse_status; + int mouse_x, mouse_y, mouse_click; + int mouse_x_old = -1, mouse_y_old = -1, mouse_click_old = -1; + + mouse_status = gd_detect_mouse(); + if (mouse_status != GD_TRUE) { + printf("Mouse support not available.\n"); + abort(); + } + + /* example: TEXT_MODE || VGA_256_COLOR_MODE */ + gd_set_mode(VGA_256_COLOR_MODE); + clrscr(); + gd_show_mouse(); + do { + gd_get_mouse_status(&mouse_x, &mouse_y, &mouse_click); + + /* when mouse status change update */ + if (mouse_x != mouse_x_old || + mouse_y != mouse_y_old || + mouse_click != mouse_click_old) + { + mouse_x_old = mouse_x; + mouse_y_old = mouse_y; + mouse_click_old = mouse_click; + + clrscr(); + gotoxy(0, 0); + printf("Mouse position: X=%d, Y=%d, CLICK=%d", mouse_x, mouse_y, mouse_click); + gd_show_mouse(); + } + } while (!kbhit()); + gd_hide_mouse(); + getch(); + + gd_set_mode(TEXT_MODE); +} diff --git a/include/gdos.h b/include/gdos.h new file mode 100644 index 0000000..deb2d80 --- /dev/null +++ b/include/gdos.h @@ -0,0 +1,228 @@ +/** + * Library for GameDev on DOS + * + * Alexander Popov + * Version: 0.0.0 + * + * LICENSE: + * This is free and unencumbered software released into the public domain. + * Anyone is free to copy, modify, publish, use, compile, sell, or + * distribute this software, either in source code form or as a compiled + * binary, for any purpose, commercial or non-commercial, and by any + * means. + * + * In jurisdictions that recognize copyright laws, the author or authors + * of this software dedicate any and all copyright interest in the + * software to the public domain. We make this dedication for the benefit + * of the public at large and to the detriment of our heirs and + * successors. We intend this dedication to be an overt act of + * relinquishment in perpetuity of all present and future rights to this + * software under copyright law. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * For more information, please refer to + * + * THANKS: + * David Brackeen - http://www.brackeen.com/vga/basics.html + * Stanislav Sokolov - https://stanislavs.org/helppc/int_33-3.html + * Team EQA - https://www.equestionanswers.com/c/c-int33-mouse-service.php + */ + +#ifndef GDOS_H_ +#define GDOS_H_ + +#include +#include + +/* ... */ +#define GD_TRUE 1 /* bool true */ +#define GD_FALSE 0 /* bool false */ + +#define VIDEO_INT 0x10 /* BIOS video interrupt */ +#define MOUSE_INTERRUPT 0x33 /* BIOS mouse interrupt */ +#define WRITE_DOT 0x0C /* BIOS func to plot a pixel */ +#define SET_MODE 0x00 /* BIOS func to set the video mode */ + +#define TEXT_MODE 0x03 /* 80x25 text mode */ +#define VGA_4_COLOR_MODE 0x04 /* 320x200 4-color graphics mode */ +#define VGA_MONO_SM_MODE 0x05 /* 320x200 monochrome graphics mode */ +#define VGA_MONO_LG_MODE 0x06 /* 640x200 monochrome graphics mode */ +#define VGA_256_COLOR_MODE 0x13 /* 320x200 graphics mode */ + +#define SCREEN_WIDTH 320 /* width in pixels of mode 0x13 */ +#define SCREEN_HEIGHT 200 /* height in pixels of mode 0x13 */ + +#define GD_DRAW_FAST 1 +#define GD_DRAW_SLOW 0 + +typedef unsigned char byte; +byte *VGA=(byte *)0xA0000000L; /* this points to video memory */ + +/* KEY CODES */ +#define key_ESC 27 /* ESCAPE key */ +#define key_A 65 /* A key */ +#define key_B 66 /* B key */ +#define key_C 67 /* C key */ +#define key_D 68 /* D key */ +#define key_E 69 /* E key */ +#define key_F 70 /* F key */ +#define key_G 71 /* G key */ +#define key_H 72 /* H key */ +#define key_I 73 /* I key */ +#define key_J 74 /* J key */ +#define key_K 75 /* K key */ +#define key_L 76 /* L key */ +#define key_M 77 /* M key */ +#define key_N 78 /* N key */ +#define key_O 79 /* O key */ +#define key_P 80 /* P key */ +#define key_Q 81 /* Q key */ +#define key_R 82 /* R key */ +#define key_S 83 /* S key */ +#define key_T 84 /* T key */ +#define key_U 85 /* U key */ +#define key_V 86 /* V key */ +#define key_W 87 /* W key */ +#define key_X 88 /* X key */ +#define key_Y 89 /* Y key */ +#define key_Z 90 /* Z key */ +#define key_a 97 /* a key */ +#define key_b 98 /* b key */ +#define key_c 99 /* c key */ +#define key_d 100 /* d key */ +#define key_e 101 /* e key */ +#define key_f 102 /* f key */ +#define key_g 103 /* g key */ +#define key_h 104 /* h key */ +#define key_i 105 /* i key */ +#define key_j 106 /* j key */ +#define key_k 107 /* k key */ +#define key_l 108 /* l key */ +#define key_m 109 /* m key */ +#define key_n 110 /* n key */ +#define key_o 111 /* o key */ +#define key_p 112 /* p key */ +#define key_q 113 /* q key */ +#define key_r 114 /* r key */ +#define key_s 115 /* s key */ +#define key_t 116 /* t key */ +#define key_u 117 /* u key */ +#define key_v 118 /* v key */ +#define key_w 119 /* w key */ +#define key_x 120 /* x key */ +#define key_y 121 /* y key */ +#define key_z 122 /* z key */ + +/** + * gd_set_mode(byte mode) + * Sets the video mode + */ +void gd_set_mode(byte mode) { + union REGS regs; + + regs.h.ah = SET_MODE; + regs.h.al = mode; + int86(VIDEO_INT, ®s, ®s); +} + +/** + * gd_draw_pixel(int x, int y, byte color, int draw_mode) + * Draw pixel on VGA + */ +void gd_draw_pixel(int x, int y, byte color, int draw_mode) { + union REGS regs; + + /* draw pixel as fast mode */ + if (draw_mode == 1) { + VGA[y*SCREEN_WIDTH+x]=color; + } + /* draw pixel as slow mode */ + else { + regs.h.ah = WRITE_DOT; + regs.h.al = color; + regs.x.cx = x; + regs.x.dx = y; + int86(VIDEO_INT, ®s, ®s); + } +} + +/** + * gd_get_kb(int *key) + * Gets the ASCII code of the pressed key from the keyboard + */ +void gd_get_kb(int *key) { + if (kbhit()) { + *key = getch(); + } +} + +/** + * gd_detect_mouse(void) + * Return mouse support/available + */ +int gd_detect_mouse(void) { + union REGS in, out; + + in.x.ax = 0; + int86(MOUSE_INTERRUPT, &in, &out); + + /* Mouse support not available */ + if (out.x.ax != 0) { return GD_TRUE; } + else { return GD_FALSE; } +} + +/** + * gd_show_mouse(void) + * Show mouse cursor + */ +int gd_show_mouse(void) { + union REGS in, out; + + in.x.ax = 1; + int86(MOUSE_INTERRUPT, &in, &out); + + return GD_TRUE; +} + +/** + * gd_hide_mouse(void) + * Hide mouse cursor + */ +int gd_hide_mouse(void) { + union REGS in, out; + + in.x.ax = 2; + int86(MOUSE_INTERRUPT, &in, &out); + + return GD_TRUE; +} + +/** + * gd_get_mouse_status(int *x, int *y, int *click) + * Gets mouse position by X,Y and mouse button click status + */ +void gd_get_mouse_status(int *x, int *y, int *click) { + union REGS in, out; + + in.x.ax = 3; + int86(MOUSE_INTERRUPT, &in, &out); + /** + * Click is the integer variable which returns the values + * 1 - Left mouse button + * 2 - Right mouse button + * 3 - Middle mouse button + * 4 - ... + */ + *click = out.x.bx; + *x = out.x.cx; + *y = out.x.dx; +} + +#endif diff --git a/screenshots/cursor_graphics.png b/screenshots/cursor_graphics.png new file mode 100644 index 0000000000000000000000000000000000000000..d60ce0a45dd6d987dfa62f540e32155ae0ac5e61 GIT binary patch literal 2876 zcmeHJ{ZAWp82`3o21vGb!H{LZI^&cd_+e4EjF;MDI^Bq|=;A)sg>kb`!r%U{BuBE-CuDJHrqsf|mcfZ&-xL=7BzJx^26vw~)rD)B^gC89{ z`r_82qq>^DC7c5$KiUgPLa%OHh6oM-#`|Q`4Twsv-N(%^c}q4yrI$yShRA{NOsmFV zohO^+)Mac;TBd9EjFc#(@}S%`9*I5l$3xi)xe;C(s`57epc2Z1_IVfKPqvr2#&n9{ z1SJktoBNw%^LoGqQ)<&T{bqG>?EABe(rEVFgZYRH%Q#f);gQqvZX@}S(u{Rv9;^s5 z0d<)ol!b8(Nf{dYy&cGa!<7^?cxk_>*MOt;aoV5N-E>fM_#8QMiklC3gu7tj;+T$j{rSmjY{JQr)Hh9p-}98 zlg5N5!x|#!J{->Df!!y%xm}obu%3VHZX+&nR8!wQ*2RmaS5hsct|M~{?rsbz<#Q8= zJdz?1ObO#s>j9go6E_Fq1a#tR#Gx#%XVnT(yNPX>BCoQ+WvNc$RY7lbXy-ni}qidJ1-f+TZ!* zJ?6s|3jwW7d-2_usTrY)KOVOtTK;kq^p#ERCju6E{8B>S)`r&b!*UP#e%Ki_J1D(Q zk$u}^>V+W*kwQypu~13d47zZs>$(oD!8K<@fCD~2oEdd8PH!77R5acuQoofdnlA(| zC)Db&KW@en_^d_M;S31ORY6R~ATsN*m*kk}+Q~XzsA(-@+R$ohchaL)t2~b21B7kZ z?<5mGeVc+-U60iBM@@k-pQFFUZD{a*h}y@b%a*0!Nh{>Z{uPycP3Sub%e3Ktyk$C* z=6_yP3wo|WY?fW^xm@!YIL?DSaCSS3I+yA9>nyqR8NVGIhKkR!1#LKOK(N7rjf3z% zEl3LaU~th5LE3a`IebSd+2p;$itG8J+Mb^zE^V1xRvJV!HGMzV?S8tF!$^#bn?ETl z6>-0r`o|Awm-g_CCRUVoFsh%aDF0-2A~#$a{{@>q?>52w19(e$yq-5$D>ofk>w0Cu zXYSm1nr8O0{key?>*~MT96xPbw`3AwCccQfxcy0JDS8PZ6q)DC)vJjoK`Q$oom*!@pGv#~#?mr~|(L1n!YU?CB#Tgbo**sss5#;e$po~Y)ugtKY2 zF&s;H==#B6w%5JP&Q3PDtCefL;YHTkP}U6y{=5F^=(*#^yuqbtqUN-JG0r7sUU zXXaL0-J;M;xd|cunP@-^mqIOM5xKLy;H7)@%H|s4M0_=xXtA)R@WoRq+}0;K#^O|6O**e~;K8Cn zN0}BnC!?bnJXhY#zgU&9yBNPJve9~PXm(a5cfm6QQoTknv1tUsV-%4LOm1y!e%B&I zI+9O#bZaMUoDeIHpl#2g1409o^P|O-f1qKMHds0YS0(1DM32YBh^IghmfFaXMS4VV zohHW%?fd3qT!lw)jOPl_7i^-nz>+&WfhFot9Cc2{eKBS_r_b-C^>LApXw085YlGG> z-=F*~u0Uj~Izo`h4Pa%|)BGe7D%QY7gR9=D7dSqB;ysqLcq|p|@y0%N%p4?M(a;hl z(U*-3!i}?#1+!2t2EjInEZU+jdo7axc-+c!XqYZlla6B{=&1f=gB|128DkNuGoo3b zHY-#8Vdc5loJZyjz;?c?yoql?LU)Ig+Y$Ngd{;caUCw7ImM49Mb1VW+cI#CTuzr(n zRdsh%suQbX4sSjCzBqGu&fvuI@NtCgut=EC%g^+wyYdKixD0j>H+u$1Bkzl+jqQ4g zX_%liA$v>*B6ZCst6rcn#J=s6C6>AqYgYpPe#9&}$#dDvVOvjCDrH~T6r}2(Y3Ja? zU)J#1XqGh|R-Rwk%t-u=E$PDZJ0QK^7YNQqO62#1M;2#P0B7wZwAVX2ere3BmwPzu zPZ-W3r?jaX?WeW4xkQYsL}=P;=-YZ(FYl&NY}KRDx!uV3UcJrTGN|-ljs=P*q0b-? zEfqSEFqRwGbsK%76**%YAoi#1p|9m^z`MsZE7dkk2Wvx^@`G}!%KiFSBob4tc5(8V zw