deepstone
changeset 0:f04884489bad
dos3d initial import
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Mon, 21 Nov 2011 06:14:01 +0200 |
parents | |
children | 0b7f840afe4a |
files | .hgignore COPYING Makefile Makefile.bcc README dosemu/conio.h dosemu/dosemu.c src/mglgen.c src/mglimpl.h src/mglrast.c src/mingl.c src/mingl.h src/mouse.c src/mouse.h src/pit8254.h src/scantmpl.h src/test.c src/timer.c src/timer.h src/vga.c src/vga.h |
diffstat | 21 files changed, 2864 insertions(+), 0 deletions(-) [+] |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/.hgignore Mon Nov 21 06:14:01 2011 +0200 1.3 @@ -0,0 +1,4 @@ 1.4 +\.o$ 1.5 +\.obj$ 1.6 +\.d$ 1.7 +^test$
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/COPYING Mon Nov 21 06:14:01 2011 +0200 2.3 @@ -0,0 +1,674 @@ 2.4 + GNU GENERAL PUBLIC LICENSE 2.5 + Version 3, 29 June 2007 2.6 + 2.7 + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> 2.8 + Everyone is permitted to copy and distribute verbatim copies 2.9 + of this license document, but changing it is not allowed. 2.10 + 2.11 + Preamble 2.12 + 2.13 + The GNU General Public License is a free, copyleft license for 2.14 +software and other kinds of works. 2.15 + 2.16 + The licenses for most software and other practical works are designed 2.17 +to take away your freedom to share and change the works. By contrast, 2.18 +the GNU General Public License is intended to guarantee your freedom to 2.19 +share and change all versions of a program--to make sure it remains free 2.20 +software for all its users. We, the Free Software Foundation, use the 2.21 +GNU General Public License for most of our software; it applies also to 2.22 +any other work released this way by its authors. You can apply it to 2.23 +your programs, too. 2.24 + 2.25 + When we speak of free software, we are referring to freedom, not 2.26 +price. Our General Public Licenses are designed to make sure that you 2.27 +have the freedom to distribute copies of free software (and charge for 2.28 +them if you wish), that you receive source code or can get it if you 2.29 +want it, that you can change the software or use pieces of it in new 2.30 +free programs, and that you know you can do these things. 2.31 + 2.32 + To protect your rights, we need to prevent others from denying you 2.33 +these rights or asking you to surrender the rights. Therefore, you have 2.34 +certain responsibilities if you distribute copies of the software, or if 2.35 +you modify it: responsibilities to respect the freedom of others. 2.36 + 2.37 + For example, if you distribute copies of such a program, whether 2.38 +gratis or for a fee, you must pass on to the recipients the same 2.39 +freedoms that you received. You must make sure that they, too, receive 2.40 +or can get the source code. And you must show them these terms so they 2.41 +know their rights. 2.42 + 2.43 + Developers that use the GNU GPL protect your rights with two steps: 2.44 +(1) assert copyright on the software, and (2) offer you this License 2.45 +giving you legal permission to copy, distribute and/or modify it. 2.46 + 2.47 + For the developers' and authors' protection, the GPL clearly explains 2.48 +that there is no warranty for this free software. For both users' and 2.49 +authors' sake, the GPL requires that modified versions be marked as 2.50 +changed, so that their problems will not be attributed erroneously to 2.51 +authors of previous versions. 2.52 + 2.53 + Some devices are designed to deny users access to install or run 2.54 +modified versions of the software inside them, although the manufacturer 2.55 +can do so. This is fundamentally incompatible with the aim of 2.56 +protecting users' freedom to change the software. The systematic 2.57 +pattern of such abuse occurs in the area of products for individuals to 2.58 +use, which is precisely where it is most unacceptable. Therefore, we 2.59 +have designed this version of the GPL to prohibit the practice for those 2.60 +products. If such problems arise substantially in other domains, we 2.61 +stand ready to extend this provision to those domains in future versions 2.62 +of the GPL, as needed to protect the freedom of users. 2.63 + 2.64 + Finally, every program is threatened constantly by software patents. 2.65 +States should not allow patents to restrict development and use of 2.66 +software on general-purpose computers, but in those that do, we wish to 2.67 +avoid the special danger that patents applied to a free program could 2.68 +make it effectively proprietary. To prevent this, the GPL assures that 2.69 +patents cannot be used to render the program non-free. 2.70 + 2.71 + The precise terms and conditions for copying, distribution and 2.72 +modification follow. 2.73 + 2.74 + TERMS AND CONDITIONS 2.75 + 2.76 + 0. Definitions. 2.77 + 2.78 + "This License" refers to version 3 of the GNU General Public License. 2.79 + 2.80 + "Copyright" also means copyright-like laws that apply to other kinds of 2.81 +works, such as semiconductor masks. 2.82 + 2.83 + "The Program" refers to any copyrightable work licensed under this 2.84 +License. Each licensee is addressed as "you". "Licensees" and 2.85 +"recipients" may be individuals or organizations. 2.86 + 2.87 + To "modify" a work means to copy from or adapt all or part of the work 2.88 +in a fashion requiring copyright permission, other than the making of an 2.89 +exact copy. The resulting work is called a "modified version" of the 2.90 +earlier work or a work "based on" the earlier work. 2.91 + 2.92 + A "covered work" means either the unmodified Program or a work based 2.93 +on the Program. 2.94 + 2.95 + To "propagate" a work means to do anything with it that, without 2.96 +permission, would make you directly or secondarily liable for 2.97 +infringement under applicable copyright law, except executing it on a 2.98 +computer or modifying a private copy. Propagation includes copying, 2.99 +distribution (with or without modification), making available to the 2.100 +public, and in some countries other activities as well. 2.101 + 2.102 + To "convey" a work means any kind of propagation that enables other 2.103 +parties to make or receive copies. Mere interaction with a user through 2.104 +a computer network, with no transfer of a copy, is not conveying. 2.105 + 2.106 + An interactive user interface displays "Appropriate Legal Notices" 2.107 +to the extent that it includes a convenient and prominently visible 2.108 +feature that (1) displays an appropriate copyright notice, and (2) 2.109 +tells the user that there is no warranty for the work (except to the 2.110 +extent that warranties are provided), that licensees may convey the 2.111 +work under this License, and how to view a copy of this License. If 2.112 +the interface presents a list of user commands or options, such as a 2.113 +menu, a prominent item in the list meets this criterion. 2.114 + 2.115 + 1. Source Code. 2.116 + 2.117 + The "source code" for a work means the preferred form of the work 2.118 +for making modifications to it. "Object code" means any non-source 2.119 +form of a work. 2.120 + 2.121 + A "Standard Interface" means an interface that either is an official 2.122 +standard defined by a recognized standards body, or, in the case of 2.123 +interfaces specified for a particular programming language, one that 2.124 +is widely used among developers working in that language. 2.125 + 2.126 + The "System Libraries" of an executable work include anything, other 2.127 +than the work as a whole, that (a) is included in the normal form of 2.128 +packaging a Major Component, but which is not part of that Major 2.129 +Component, and (b) serves only to enable use of the work with that 2.130 +Major Component, or to implement a Standard Interface for which an 2.131 +implementation is available to the public in source code form. A 2.132 +"Major Component", in this context, means a major essential component 2.133 +(kernel, window system, and so on) of the specific operating system 2.134 +(if any) on which the executable work runs, or a compiler used to 2.135 +produce the work, or an object code interpreter used to run it. 2.136 + 2.137 + The "Corresponding Source" for a work in object code form means all 2.138 +the source code needed to generate, install, and (for an executable 2.139 +work) run the object code and to modify the work, including scripts to 2.140 +control those activities. However, it does not include the work's 2.141 +System Libraries, or general-purpose tools or generally available free 2.142 +programs which are used unmodified in performing those activities but 2.143 +which are not part of the work. For example, Corresponding Source 2.144 +includes interface definition files associated with source files for 2.145 +the work, and the source code for shared libraries and dynamically 2.146 +linked subprograms that the work is specifically designed to require, 2.147 +such as by intimate data communication or control flow between those 2.148 +subprograms and other parts of the work. 2.149 + 2.150 + The Corresponding Source need not include anything that users 2.151 +can regenerate automatically from other parts of the Corresponding 2.152 +Source. 2.153 + 2.154 + The Corresponding Source for a work in source code form is that 2.155 +same work. 2.156 + 2.157 + 2. Basic Permissions. 2.158 + 2.159 + All rights granted under this License are granted for the term of 2.160 +copyright on the Program, and are irrevocable provided the stated 2.161 +conditions are met. This License explicitly affirms your unlimited 2.162 +permission to run the unmodified Program. The output from running a 2.163 +covered work is covered by this License only if the output, given its 2.164 +content, constitutes a covered work. This License acknowledges your 2.165 +rights of fair use or other equivalent, as provided by copyright law. 2.166 + 2.167 + You may make, run and propagate covered works that you do not 2.168 +convey, without conditions so long as your license otherwise remains 2.169 +in force. You may convey covered works to others for the sole purpose 2.170 +of having them make modifications exclusively for you, or provide you 2.171 +with facilities for running those works, provided that you comply with 2.172 +the terms of this License in conveying all material for which you do 2.173 +not control copyright. Those thus making or running the covered works 2.174 +for you must do so exclusively on your behalf, under your direction 2.175 +and control, on terms that prohibit them from making any copies of 2.176 +your copyrighted material outside their relationship with you. 2.177 + 2.178 + Conveying under any other circumstances is permitted solely under 2.179 +the conditions stated below. Sublicensing is not allowed; section 10 2.180 +makes it unnecessary. 2.181 + 2.182 + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 2.183 + 2.184 + No covered work shall be deemed part of an effective technological 2.185 +measure under any applicable law fulfilling obligations under article 2.186 +11 of the WIPO copyright treaty adopted on 20 December 1996, or 2.187 +similar laws prohibiting or restricting circumvention of such 2.188 +measures. 2.189 + 2.190 + When you convey a covered work, you waive any legal power to forbid 2.191 +circumvention of technological measures to the extent such circumvention 2.192 +is effected by exercising rights under this License with respect to 2.193 +the covered work, and you disclaim any intention to limit operation or 2.194 +modification of the work as a means of enforcing, against the work's 2.195 +users, your or third parties' legal rights to forbid circumvention of 2.196 +technological measures. 2.197 + 2.198 + 4. Conveying Verbatim Copies. 2.199 + 2.200 + You may convey verbatim copies of the Program's source code as you 2.201 +receive it, in any medium, provided that you conspicuously and 2.202 +appropriately publish on each copy an appropriate copyright notice; 2.203 +keep intact all notices stating that this License and any 2.204 +non-permissive terms added in accord with section 7 apply to the code; 2.205 +keep intact all notices of the absence of any warranty; and give all 2.206 +recipients a copy of this License along with the Program. 2.207 + 2.208 + You may charge any price or no price for each copy that you convey, 2.209 +and you may offer support or warranty protection for a fee. 2.210 + 2.211 + 5. Conveying Modified Source Versions. 2.212 + 2.213 + You may convey a work based on the Program, or the modifications to 2.214 +produce it from the Program, in the form of source code under the 2.215 +terms of section 4, provided that you also meet all of these conditions: 2.216 + 2.217 + a) The work must carry prominent notices stating that you modified 2.218 + it, and giving a relevant date. 2.219 + 2.220 + b) The work must carry prominent notices stating that it is 2.221 + released under this License and any conditions added under section 2.222 + 7. This requirement modifies the requirement in section 4 to 2.223 + "keep intact all notices". 2.224 + 2.225 + c) You must license the entire work, as a whole, under this 2.226 + License to anyone who comes into possession of a copy. This 2.227 + License will therefore apply, along with any applicable section 7 2.228 + additional terms, to the whole of the work, and all its parts, 2.229 + regardless of how they are packaged. This License gives no 2.230 + permission to license the work in any other way, but it does not 2.231 + invalidate such permission if you have separately received it. 2.232 + 2.233 + d) If the work has interactive user interfaces, each must display 2.234 + Appropriate Legal Notices; however, if the Program has interactive 2.235 + interfaces that do not display Appropriate Legal Notices, your 2.236 + work need not make them do so. 2.237 + 2.238 + A compilation of a covered work with other separate and independent 2.239 +works, which are not by their nature extensions of the covered work, 2.240 +and which are not combined with it such as to form a larger program, 2.241 +in or on a volume of a storage or distribution medium, is called an 2.242 +"aggregate" if the compilation and its resulting copyright are not 2.243 +used to limit the access or legal rights of the compilation's users 2.244 +beyond what the individual works permit. Inclusion of a covered work 2.245 +in an aggregate does not cause this License to apply to the other 2.246 +parts of the aggregate. 2.247 + 2.248 + 6. Conveying Non-Source Forms. 2.249 + 2.250 + You may convey a covered work in object code form under the terms 2.251 +of sections 4 and 5, provided that you also convey the 2.252 +machine-readable Corresponding Source under the terms of this License, 2.253 +in one of these ways: 2.254 + 2.255 + a) Convey the object code in, or embodied in, a physical product 2.256 + (including a physical distribution medium), accompanied by the 2.257 + Corresponding Source fixed on a durable physical medium 2.258 + customarily used for software interchange. 2.259 + 2.260 + b) Convey the object code in, or embodied in, a physical product 2.261 + (including a physical distribution medium), accompanied by a 2.262 + written offer, valid for at least three years and valid for as 2.263 + long as you offer spare parts or customer support for that product 2.264 + model, to give anyone who possesses the object code either (1) a 2.265 + copy of the Corresponding Source for all the software in the 2.266 + product that is covered by this License, on a durable physical 2.267 + medium customarily used for software interchange, for a price no 2.268 + more than your reasonable cost of physically performing this 2.269 + conveying of source, or (2) access to copy the 2.270 + Corresponding Source from a network server at no charge. 2.271 + 2.272 + c) Convey individual copies of the object code with a copy of the 2.273 + written offer to provide the Corresponding Source. This 2.274 + alternative is allowed only occasionally and noncommercially, and 2.275 + only if you received the object code with such an offer, in accord 2.276 + with subsection 6b. 2.277 + 2.278 + d) Convey the object code by offering access from a designated 2.279 + place (gratis or for a charge), and offer equivalent access to the 2.280 + Corresponding Source in the same way through the same place at no 2.281 + further charge. You need not require recipients to copy the 2.282 + Corresponding Source along with the object code. If the place to 2.283 + copy the object code is a network server, the Corresponding Source 2.284 + may be on a different server (operated by you or a third party) 2.285 + that supports equivalent copying facilities, provided you maintain 2.286 + clear directions next to the object code saying where to find the 2.287 + Corresponding Source. Regardless of what server hosts the 2.288 + Corresponding Source, you remain obligated to ensure that it is 2.289 + available for as long as needed to satisfy these requirements. 2.290 + 2.291 + e) Convey the object code using peer-to-peer transmission, provided 2.292 + you inform other peers where the object code and Corresponding 2.293 + Source of the work are being offered to the general public at no 2.294 + charge under subsection 6d. 2.295 + 2.296 + A separable portion of the object code, whose source code is excluded 2.297 +from the Corresponding Source as a System Library, need not be 2.298 +included in conveying the object code work. 2.299 + 2.300 + A "User Product" is either (1) a "consumer product", which means any 2.301 +tangible personal property which is normally used for personal, family, 2.302 +or household purposes, or (2) anything designed or sold for incorporation 2.303 +into a dwelling. In determining whether a product is a consumer product, 2.304 +doubtful cases shall be resolved in favor of coverage. For a particular 2.305 +product received by a particular user, "normally used" refers to a 2.306 +typical or common use of that class of product, regardless of the status 2.307 +of the particular user or of the way in which the particular user 2.308 +actually uses, or expects or is expected to use, the product. A product 2.309 +is a consumer product regardless of whether the product has substantial 2.310 +commercial, industrial or non-consumer uses, unless such uses represent 2.311 +the only significant mode of use of the product. 2.312 + 2.313 + "Installation Information" for a User Product means any methods, 2.314 +procedures, authorization keys, or other information required to install 2.315 +and execute modified versions of a covered work in that User Product from 2.316 +a modified version of its Corresponding Source. The information must 2.317 +suffice to ensure that the continued functioning of the modified object 2.318 +code is in no case prevented or interfered with solely because 2.319 +modification has been made. 2.320 + 2.321 + If you convey an object code work under this section in, or with, or 2.322 +specifically for use in, a User Product, and the conveying occurs as 2.323 +part of a transaction in which the right of possession and use of the 2.324 +User Product is transferred to the recipient in perpetuity or for a 2.325 +fixed term (regardless of how the transaction is characterized), the 2.326 +Corresponding Source conveyed under this section must be accompanied 2.327 +by the Installation Information. But this requirement does not apply 2.328 +if neither you nor any third party retains the ability to install 2.329 +modified object code on the User Product (for example, the work has 2.330 +been installed in ROM). 2.331 + 2.332 + The requirement to provide Installation Information does not include a 2.333 +requirement to continue to provide support service, warranty, or updates 2.334 +for a work that has been modified or installed by the recipient, or for 2.335 +the User Product in which it has been modified or installed. Access to a 2.336 +network may be denied when the modification itself materially and 2.337 +adversely affects the operation of the network or violates the rules and 2.338 +protocols for communication across the network. 2.339 + 2.340 + Corresponding Source conveyed, and Installation Information provided, 2.341 +in accord with this section must be in a format that is publicly 2.342 +documented (and with an implementation available to the public in 2.343 +source code form), and must require no special password or key for 2.344 +unpacking, reading or copying. 2.345 + 2.346 + 7. Additional Terms. 2.347 + 2.348 + "Additional permissions" are terms that supplement the terms of this 2.349 +License by making exceptions from one or more of its conditions. 2.350 +Additional permissions that are applicable to the entire Program shall 2.351 +be treated as though they were included in this License, to the extent 2.352 +that they are valid under applicable law. If additional permissions 2.353 +apply only to part of the Program, that part may be used separately 2.354 +under those permissions, but the entire Program remains governed by 2.355 +this License without regard to the additional permissions. 2.356 + 2.357 + When you convey a copy of a covered work, you may at your option 2.358 +remove any additional permissions from that copy, or from any part of 2.359 +it. (Additional permissions may be written to require their own 2.360 +removal in certain cases when you modify the work.) You may place 2.361 +additional permissions on material, added by you to a covered work, 2.362 +for which you have or can give appropriate copyright permission. 2.363 + 2.364 + Notwithstanding any other provision of this License, for material you 2.365 +add to a covered work, you may (if authorized by the copyright holders of 2.366 +that material) supplement the terms of this License with terms: 2.367 + 2.368 + a) Disclaiming warranty or limiting liability differently from the 2.369 + terms of sections 15 and 16 of this License; or 2.370 + 2.371 + b) Requiring preservation of specified reasonable legal notices or 2.372 + author attributions in that material or in the Appropriate Legal 2.373 + Notices displayed by works containing it; or 2.374 + 2.375 + c) Prohibiting misrepresentation of the origin of that material, or 2.376 + requiring that modified versions of such material be marked in 2.377 + reasonable ways as different from the original version; or 2.378 + 2.379 + d) Limiting the use for publicity purposes of names of licensors or 2.380 + authors of the material; or 2.381 + 2.382 + e) Declining to grant rights under trademark law for use of some 2.383 + trade names, trademarks, or service marks; or 2.384 + 2.385 + f) Requiring indemnification of licensors and authors of that 2.386 + material by anyone who conveys the material (or modified versions of 2.387 + it) with contractual assumptions of liability to the recipient, for 2.388 + any liability that these contractual assumptions directly impose on 2.389 + those licensors and authors. 2.390 + 2.391 + All other non-permissive additional terms are considered "further 2.392 +restrictions" within the meaning of section 10. If the Program as you 2.393 +received it, or any part of it, contains a notice stating that it is 2.394 +governed by this License along with a term that is a further 2.395 +restriction, you may remove that term. If a license document contains 2.396 +a further restriction but permits relicensing or conveying under this 2.397 +License, you may add to a covered work material governed by the terms 2.398 +of that license document, provided that the further restriction does 2.399 +not survive such relicensing or conveying. 2.400 + 2.401 + If you add terms to a covered work in accord with this section, you 2.402 +must place, in the relevant source files, a statement of the 2.403 +additional terms that apply to those files, or a notice indicating 2.404 +where to find the applicable terms. 2.405 + 2.406 + Additional terms, permissive or non-permissive, may be stated in the 2.407 +form of a separately written license, or stated as exceptions; 2.408 +the above requirements apply either way. 2.409 + 2.410 + 8. Termination. 2.411 + 2.412 + You may not propagate or modify a covered work except as expressly 2.413 +provided under this License. Any attempt otherwise to propagate or 2.414 +modify it is void, and will automatically terminate your rights under 2.415 +this License (including any patent licenses granted under the third 2.416 +paragraph of section 11). 2.417 + 2.418 + However, if you cease all violation of this License, then your 2.419 +license from a particular copyright holder is reinstated (a) 2.420 +provisionally, unless and until the copyright holder explicitly and 2.421 +finally terminates your license, and (b) permanently, if the copyright 2.422 +holder fails to notify you of the violation by some reasonable means 2.423 +prior to 60 days after the cessation. 2.424 + 2.425 + Moreover, your license from a particular copyright holder is 2.426 +reinstated permanently if the copyright holder notifies you of the 2.427 +violation by some reasonable means, this is the first time you have 2.428 +received notice of violation of this License (for any work) from that 2.429 +copyright holder, and you cure the violation prior to 30 days after 2.430 +your receipt of the notice. 2.431 + 2.432 + Termination of your rights under this section does not terminate the 2.433 +licenses of parties who have received copies or rights from you under 2.434 +this License. If your rights have been terminated and not permanently 2.435 +reinstated, you do not qualify to receive new licenses for the same 2.436 +material under section 10. 2.437 + 2.438 + 9. Acceptance Not Required for Having Copies. 2.439 + 2.440 + You are not required to accept this License in order to receive or 2.441 +run a copy of the Program. Ancillary propagation of a covered work 2.442 +occurring solely as a consequence of using peer-to-peer transmission 2.443 +to receive a copy likewise does not require acceptance. However, 2.444 +nothing other than this License grants you permission to propagate or 2.445 +modify any covered work. These actions infringe copyright if you do 2.446 +not accept this License. Therefore, by modifying or propagating a 2.447 +covered work, you indicate your acceptance of this License to do so. 2.448 + 2.449 + 10. Automatic Licensing of Downstream Recipients. 2.450 + 2.451 + Each time you convey a covered work, the recipient automatically 2.452 +receives a license from the original licensors, to run, modify and 2.453 +propagate that work, subject to this License. You are not responsible 2.454 +for enforcing compliance by third parties with this License. 2.455 + 2.456 + An "entity transaction" is a transaction transferring control of an 2.457 +organization, or substantially all assets of one, or subdividing an 2.458 +organization, or merging organizations. If propagation of a covered 2.459 +work results from an entity transaction, each party to that 2.460 +transaction who receives a copy of the work also receives whatever 2.461 +licenses to the work the party's predecessor in interest had or could 2.462 +give under the previous paragraph, plus a right to possession of the 2.463 +Corresponding Source of the work from the predecessor in interest, if 2.464 +the predecessor has it or can get it with reasonable efforts. 2.465 + 2.466 + You may not impose any further restrictions on the exercise of the 2.467 +rights granted or affirmed under this License. For example, you may 2.468 +not impose a license fee, royalty, or other charge for exercise of 2.469 +rights granted under this License, and you may not initiate litigation 2.470 +(including a cross-claim or counterclaim in a lawsuit) alleging that 2.471 +any patent claim is infringed by making, using, selling, offering for 2.472 +sale, or importing the Program or any portion of it. 2.473 + 2.474 + 11. Patents. 2.475 + 2.476 + A "contributor" is a copyright holder who authorizes use under this 2.477 +License of the Program or a work on which the Program is based. The 2.478 +work thus licensed is called the contributor's "contributor version". 2.479 + 2.480 + A contributor's "essential patent claims" are all patent claims 2.481 +owned or controlled by the contributor, whether already acquired or 2.482 +hereafter acquired, that would be infringed by some manner, permitted 2.483 +by this License, of making, using, or selling its contributor version, 2.484 +but do not include claims that would be infringed only as a 2.485 +consequence of further modification of the contributor version. For 2.486 +purposes of this definition, "control" includes the right to grant 2.487 +patent sublicenses in a manner consistent with the requirements of 2.488 +this License. 2.489 + 2.490 + Each contributor grants you a non-exclusive, worldwide, royalty-free 2.491 +patent license under the contributor's essential patent claims, to 2.492 +make, use, sell, offer for sale, import and otherwise run, modify and 2.493 +propagate the contents of its contributor version. 2.494 + 2.495 + In the following three paragraphs, a "patent license" is any express 2.496 +agreement or commitment, however denominated, not to enforce a patent 2.497 +(such as an express permission to practice a patent or covenant not to 2.498 +sue for patent infringement). To "grant" such a patent license to a 2.499 +party means to make such an agreement or commitment not to enforce a 2.500 +patent against the party. 2.501 + 2.502 + If you convey a covered work, knowingly relying on a patent license, 2.503 +and the Corresponding Source of the work is not available for anyone 2.504 +to copy, free of charge and under the terms of this License, through a 2.505 +publicly available network server or other readily accessible means, 2.506 +then you must either (1) cause the Corresponding Source to be so 2.507 +available, or (2) arrange to deprive yourself of the benefit of the 2.508 +patent license for this particular work, or (3) arrange, in a manner 2.509 +consistent with the requirements of this License, to extend the patent 2.510 +license to downstream recipients. "Knowingly relying" means you have 2.511 +actual knowledge that, but for the patent license, your conveying the 2.512 +covered work in a country, or your recipient's use of the covered work 2.513 +in a country, would infringe one or more identifiable patents in that 2.514 +country that you have reason to believe are valid. 2.515 + 2.516 + If, pursuant to or in connection with a single transaction or 2.517 +arrangement, you convey, or propagate by procuring conveyance of, a 2.518 +covered work, and grant a patent license to some of the parties 2.519 +receiving the covered work authorizing them to use, propagate, modify 2.520 +or convey a specific copy of the covered work, then the patent license 2.521 +you grant is automatically extended to all recipients of the covered 2.522 +work and works based on it. 2.523 + 2.524 + A patent license is "discriminatory" if it does not include within 2.525 +the scope of its coverage, prohibits the exercise of, or is 2.526 +conditioned on the non-exercise of one or more of the rights that are 2.527 +specifically granted under this License. You may not convey a covered 2.528 +work if you are a party to an arrangement with a third party that is 2.529 +in the business of distributing software, under which you make payment 2.530 +to the third party based on the extent of your activity of conveying 2.531 +the work, and under which the third party grants, to any of the 2.532 +parties who would receive the covered work from you, a discriminatory 2.533 +patent license (a) in connection with copies of the covered work 2.534 +conveyed by you (or copies made from those copies), or (b) primarily 2.535 +for and in connection with specific products or compilations that 2.536 +contain the covered work, unless you entered into that arrangement, 2.537 +or that patent license was granted, prior to 28 March 2007. 2.538 + 2.539 + Nothing in this License shall be construed as excluding or limiting 2.540 +any implied license or other defenses to infringement that may 2.541 +otherwise be available to you under applicable patent law. 2.542 + 2.543 + 12. No Surrender of Others' Freedom. 2.544 + 2.545 + If conditions are imposed on you (whether by court order, agreement or 2.546 +otherwise) that contradict the conditions of this License, they do not 2.547 +excuse you from the conditions of this License. If you cannot convey a 2.548 +covered work so as to satisfy simultaneously your obligations under this 2.549 +License and any other pertinent obligations, then as a consequence you may 2.550 +not convey it at all. For example, if you agree to terms that obligate you 2.551 +to collect a royalty for further conveying from those to whom you convey 2.552 +the Program, the only way you could satisfy both those terms and this 2.553 +License would be to refrain entirely from conveying the Program. 2.554 + 2.555 + 13. Use with the GNU Affero General Public License. 2.556 + 2.557 + Notwithstanding any other provision of this License, you have 2.558 +permission to link or combine any covered work with a work licensed 2.559 +under version 3 of the GNU Affero General Public License into a single 2.560 +combined work, and to convey the resulting work. The terms of this 2.561 +License will continue to apply to the part which is the covered work, 2.562 +but the special requirements of the GNU Affero General Public License, 2.563 +section 13, concerning interaction through a network will apply to the 2.564 +combination as such. 2.565 + 2.566 + 14. Revised Versions of this License. 2.567 + 2.568 + The Free Software Foundation may publish revised and/or new versions of 2.569 +the GNU General Public License from time to time. Such new versions will 2.570 +be similar in spirit to the present version, but may differ in detail to 2.571 +address new problems or concerns. 2.572 + 2.573 + Each version is given a distinguishing version number. If the 2.574 +Program specifies that a certain numbered version of the GNU General 2.575 +Public License "or any later version" applies to it, you have the 2.576 +option of following the terms and conditions either of that numbered 2.577 +version or of any later version published by the Free Software 2.578 +Foundation. If the Program does not specify a version number of the 2.579 +GNU General Public License, you may choose any version ever published 2.580 +by the Free Software Foundation. 2.581 + 2.582 + If the Program specifies that a proxy can decide which future 2.583 +versions of the GNU General Public License can be used, that proxy's 2.584 +public statement of acceptance of a version permanently authorizes you 2.585 +to choose that version for the Program. 2.586 + 2.587 + Later license versions may give you additional or different 2.588 +permissions. However, no additional obligations are imposed on any 2.589 +author or copyright holder as a result of your choosing to follow a 2.590 +later version. 2.591 + 2.592 + 15. Disclaimer of Warranty. 2.593 + 2.594 + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 2.595 +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 2.596 +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 2.597 +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 2.598 +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 2.599 +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 2.600 +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 2.601 +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 2.602 + 2.603 + 16. Limitation of Liability. 2.604 + 2.605 + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 2.606 +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 2.607 +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 2.608 +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 2.609 +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 2.610 +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 2.611 +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 2.612 +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 2.613 +SUCH DAMAGES. 2.614 + 2.615 + 17. Interpretation of Sections 15 and 16. 2.616 + 2.617 + If the disclaimer of warranty and limitation of liability provided 2.618 +above cannot be given local legal effect according to their terms, 2.619 +reviewing courts shall apply local law that most closely approximates 2.620 +an absolute waiver of all civil liability in connection with the 2.621 +Program, unless a warranty or assumption of liability accompanies a 2.622 +copy of the Program in return for a fee. 2.623 + 2.624 + END OF TERMS AND CONDITIONS 2.625 + 2.626 + How to Apply These Terms to Your New Programs 2.627 + 2.628 + If you develop a new program, and you want it to be of the greatest 2.629 +possible use to the public, the best way to achieve this is to make it 2.630 +free software which everyone can redistribute and change under these terms. 2.631 + 2.632 + To do so, attach the following notices to the program. It is safest 2.633 +to attach them to the start of each source file to most effectively 2.634 +state the exclusion of warranty; and each file should have at least 2.635 +the "copyright" line and a pointer to where the full notice is found. 2.636 + 2.637 + <one line to give the program's name and a brief idea of what it does.> 2.638 + Copyright (C) <year> <name of author> 2.639 + 2.640 + This program is free software: you can redistribute it and/or modify 2.641 + it under the terms of the GNU General Public License as published by 2.642 + the Free Software Foundation, either version 3 of the License, or 2.643 + (at your option) any later version. 2.644 + 2.645 + This program is distributed in the hope that it will be useful, 2.646 + but WITHOUT ANY WARRANTY; without even the implied warranty of 2.647 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 2.648 + GNU General Public License for more details. 2.649 + 2.650 + You should have received a copy of the GNU General Public License 2.651 + along with this program. If not, see <http://www.gnu.org/licenses/>. 2.652 + 2.653 +Also add information on how to contact you by electronic and paper mail. 2.654 + 2.655 + If the program does terminal interaction, make it output a short 2.656 +notice like this when it starts in an interactive mode: 2.657 + 2.658 + <program> Copyright (C) <year> <name of author> 2.659 + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 2.660 + This is free software, and you are welcome to redistribute it 2.661 + under certain conditions; type `show c' for details. 2.662 + 2.663 +The hypothetical commands `show w' and `show c' should show the appropriate 2.664 +parts of the General Public License. Of course, your program's commands 2.665 +might be different; for a GUI interface, you would use an "about box". 2.666 + 2.667 + You should also get your employer (if you work as a programmer) or school, 2.668 +if any, to sign a "copyright disclaimer" for the program, if necessary. 2.669 +For more information on this, and how to apply and follow the GNU GPL, see 2.670 +<http://www.gnu.org/licenses/>. 2.671 + 2.672 + The GNU General Public License does not permit incorporating your program 2.673 +into proprietary programs. If your program is a subroutine library, you 2.674 +may consider it more useful to permit linking proprietary applications with 2.675 +the library. If this is what you want to do, use the GNU Lesser General 2.676 +Public License instead of this License. But first, please read 2.677 +<http://www.gnu.org/philosophy/why-not-lgpl.html>.
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/Makefile Mon Nov 21 06:14:01 2011 +0200 3.3 @@ -0,0 +1,21 @@ 3.4 +obj = src/test.o \ 3.5 + src/mingl.o src/mglrast.o src/mglgen.o \ 3.6 + dosemu/dosemu.o 3.7 +dep = $(obj:.o=.d) 3.8 +bin = test 3.9 + 3.10 +CC = gcc 3.11 +CFLAGS = -pedantic -Wall -g `pkg-config --cflags sdl` -Isrc -Idosemu 3.12 +LDFLAGS = `pkg-config --libs sdl` 3.13 + 3.14 +$(bin): $(obj) 3.15 + $(CC) -o $@ $(obj) $(LDFLAGS) 3.16 + 3.17 +-include $(dep) 3.18 + 3.19 +%.d: %.c 3.20 + @$(CPP) $(CFLAGS) $< -MM -MT $(@:.d=.o) >$@ 3.21 + 3.22 +.PHONY: clean 3.23 +clean: 3.24 + rm -f $(obj) $(bin)
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/Makefile.bcc Mon Nov 21 06:14:01 2011 +0200 4.3 @@ -0,0 +1,25 @@ 4.4 +.AUTODEPEND 4.5 + 4.6 +obj = src\test.obj src\vga.obj src\timer.obj src\mouse.obj \ 4.7 + src\mingl.obj src\mglrast.obj src\mglgen.obj 4.8 +bin = dos3d.exe 4.9 + 4.10 +CC = bcc 4.11 + 4.12 +# 286 instructions, large memory model 4.13 +CFLAGS = -1 -f287 -ml -O -G -Isrc 4.14 + 4.15 +$(bin): $(obj) 4.16 + $(CC) @&&| 4.17 +$(CFLAGS) -e$@ 4.18 +$(obj) 4.19 +| 4.20 + 4.21 +.SUFFIXES: .c .obj 4.22 + 4.23 +.c.obj: 4.24 + $(CC) $(CFLAGS) -o$@ -c $< 4.25 + 4.26 +clean: 4.27 + del src\*.obj 4.28 + del $(bin)
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/README Mon Nov 21 06:14:01 2011 +0200 5.3 @@ -0,0 +1,17 @@ 5.4 +A short trip back in time in the days of 16bit graphics programming for MS-DOS 5.5 +in VGA mode 13h. 5.6 + 5.7 +Copyright (C) 2011 John Tsiombikas <nuclear@member.fsf.org> 5.8 +Feel free to use, modify and redistribute this code under the terms of the GNU 5.9 +General Public License version 3 (or at your option any later version published 5.10 +by the free software foundation). See COPYING for details. 5.11 + 5.12 +interesting source code files: 5.13 +- mingl.c: quick & dirty 256-color renderer with a vaguely GL-like interface. 5.14 +- vga.c: denthoresque vga mode 13h driver. 5.15 +- timer.c: DOS timer and 8254 code. 5.16 + 5.17 +To compile this you need Borland C, any version should do. Just type make. 5.18 + 5.19 +Special thanks to the vim project for providing a DOS version of vim, without it 5.20 +this would be much less enjoyable.
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/dosemu/conio.h Mon Nov 21 06:14:01 2011 +0200 6.3 @@ -0,0 +1,7 @@ 6.4 +#ifndef CONIO_H_ 6.5 +#define CONIO_H_ 6.6 + 6.7 +int kbhit(void); 6.8 +char getch(void); 6.9 + 6.10 +#endif /* CONIO_H_ */
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/dosemu/dosemu.c Mon Nov 21 06:14:01 2011 +0200 7.3 @@ -0,0 +1,221 @@ 7.4 +/* 7.5 +256-color 3D graphics hack for real-mode DOS. 7.6 +Copyright (C) 2011 John Tsiombikas <nuclear@member.fsf.org> 7.7 + 7.8 +This program is free software: you can redistribute it and/or modify 7.9 +it under the terms of the GNU General Public License as published by 7.10 +the Free Software Foundation, either version 3 of the License, or 7.11 +(at your option) any later version. 7.12 + 7.13 +This program is distributed in the hope that it will be useful, 7.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 7.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 7.16 +GNU General Public License for more details. 7.17 + 7.18 +You should have received a copy of the GNU General Public License 7.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 7.20 +*/ 7.21 + 7.22 +/* This file implements all calls made to dos-specific code using SDL 7.23 + * Don't ask why ... 7.24 + */ 7.25 + 7.26 +#include <stdlib.h> 7.27 +#include <assert.h> 7.28 +#include <SDL.h> 7.29 +#include "vga.h" 7.30 +#include "conio.h" 7.31 +#include "mouse.h" 7.32 +#include "timer.h" 7.33 + 7.34 +static void proc_events(void); 7.35 + 7.36 +/* ----- graphics (vga.c implementation) ----- */ 7.37 +static SDL_Surface *fbsurf; 7.38 + 7.39 +#define DOUBLESZ (fbsurf->w != 320) 7.40 + 7.41 +void set_video_mode(int mode) 7.42 +{ 7.43 + int resx = 320, resy = 200; 7.44 + 7.45 + if(getenv("DOSEMU_DOUBLESIZE")) { 7.46 + resx *= 2; 7.47 + resy *= 2; 7.48 + } 7.49 + 7.50 + switch(mode) { 7.51 + case 0x13: 7.52 + SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER); 7.53 + if(!(fbsurf = SDL_SetVideoMode(resx, resy, 8, SDL_HWPALETTE))) { 7.54 + fprintf(stderr, "failed to set video mode\n"); 7.55 + abort(); 7.56 + } 7.57 + SDL_ShowCursor(0); 7.58 + break; 7.59 + 7.60 + case 3: 7.61 + SDL_ShowCursor(1); 7.62 + SDL_Quit(); 7.63 + break; 7.64 + 7.65 + default: 7.66 + break; 7.67 + } 7.68 +} 7.69 + 7.70 +void set_palette(unsigned char c, unsigned char r, unsigned char g, unsigned char b) 7.71 +{ 7.72 + SDL_Color col; 7.73 + col.r = r; 7.74 + col.g = g; 7.75 + col.b = b; 7.76 + 7.77 + if(SDL_SetPalette(fbsurf, SDL_LOGPAL | SDL_PHYSPAL, &col, c, 1) != 1) { 7.78 + fprintf(stderr, "set_palette failed to set the required color\n"); 7.79 + } 7.80 +} 7.81 + 7.82 +void copy_frame(unsigned char *frame) 7.83 +{ 7.84 + if(SDL_MUSTLOCK(fbsurf)) { 7.85 + SDL_LockSurface(fbsurf); 7.86 + } 7.87 + 7.88 + if(DOUBLESZ) { 7.89 + int i, j; 7.90 + Uint16 *dest = fbsurf->pixels; 7.91 + 7.92 + for(i=0; i<200; i++) { 7.93 + for(j=0; j<320; j++) { 7.94 + Uint16 twopix = ((Uint16)*frame << 8) | (Uint16)*frame; 7.95 + dest[j] = dest[j + 320] = twopix; 7.96 + frame++; 7.97 + } 7.98 + dest += fbsurf->pitch; 7.99 + } 7.100 + } else { 7.101 + memcpy(fbsurf->pixels, frame, 64000); 7.102 + } 7.103 + 7.104 + if(SDL_MUSTLOCK(fbsurf)) { 7.105 + SDL_UnlockSurface(fbsurf); 7.106 + } 7.107 + SDL_Flip(fbsurf); 7.108 +} 7.109 + 7.110 +void wait_vsync(void) 7.111 +{ 7.112 +} 7.113 + 7.114 +/* ----- event handling (conio.h) ----- */ 7.115 +static SDL_Event *keybev; 7.116 +static int mousex, mousey, bnmask; 7.117 + 7.118 +int kbhit(void) 7.119 +{ 7.120 + if(!keybev) { 7.121 + proc_events(); 7.122 + } 7.123 + return keybev != 0; 7.124 +} 7.125 + 7.126 +char getch(void) 7.127 +{ 7.128 + char res; 7.129 + 7.130 + while(!keybev) { 7.131 + SDL_Event ev; 7.132 + SDL_WaitEvent(&ev); 7.133 + SDL_PushEvent(&ev); 7.134 + proc_events(); 7.135 + } 7.136 + res = keybev->key.keysym.sym; 7.137 + keybev = 0; 7.138 + return res; 7.139 +} 7.140 + 7.141 +/* mouse handling (mouse.c implementation) */ 7.142 +int have_mouse(void) 7.143 +{ 7.144 + return 1; 7.145 +} 7.146 + 7.147 +int read_mouse(int *xp, int *yp) 7.148 +{ 7.149 + if(xp) *xp = mousex; 7.150 + if(yp) *yp = mousey; 7.151 + return bnmask; 7.152 +} 7.153 + 7.154 +static void proc_events(void) 7.155 +{ 7.156 + static SDL_Event ev; 7.157 + 7.158 + while(SDL_PollEvent(&ev)) { 7.159 + switch(ev.type) { 7.160 + case SDL_KEYDOWN: 7.161 + keybev = &ev; 7.162 + return; 7.163 + 7.164 + case SDL_MOUSEMOTION: 7.165 + mousex = ev.motion.x; 7.166 + mousey = ev.motion.y; 7.167 + 7.168 + if(DOUBLESZ) { 7.169 + mousex /= 2; 7.170 + mousey /= 2; 7.171 + } 7.172 + break; 7.173 + 7.174 + case SDL_MOUSEBUTTONDOWN: 7.175 + case SDL_MOUSEBUTTONUP: 7.176 + { 7.177 + int mask = 0; 7.178 + switch(ev.button.button) { 7.179 + case SDL_BUTTON_LEFT: 7.180 + mask = MOUSE_LEFT; 7.181 + break; 7.182 + case SDL_BUTTON_MIDDLE: 7.183 + mask = MOUSE_MIDDLE; 7.184 + break; 7.185 + case SDL_BUTTON_RIGHT: 7.186 + mask = MOUSE_RIGHT; 7.187 + default: 7.188 + break; 7.189 + } 7.190 + if(!mask) { 7.191 + break; 7.192 + } 7.193 + 7.194 + if(ev.button.state == SDL_PRESSED) { 7.195 + bnmask |= mask; 7.196 + } else { 7.197 + bnmask &= ~mask; 7.198 + } 7.199 + } 7.200 + break; 7.201 + 7.202 + default: 7.203 + break; 7.204 + } 7.205 + } 7.206 +} 7.207 + 7.208 +/* ---- timer.c implementation ---- */ 7.209 +static Uint32 start_time; 7.210 + 7.211 +void init_timer(int res_hz) 7.212 +{ 7.213 + reset_timer(); 7.214 +} 7.215 + 7.216 +void reset_timer(void) 7.217 +{ 7.218 + start_time = SDL_GetTicks(); 7.219 +} 7.220 + 7.221 +unsigned long get_msec(void) 7.222 +{ 7.223 + return (unsigned long)(SDL_GetTicks() - start_time); 7.224 +}
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/src/mglgen.c Mon Nov 21 06:14:01 2011 +0200 8.3 @@ -0,0 +1,167 @@ 8.4 +/* 8.5 +256-color 3D graphics hack for real-mode DOS. 8.6 +Copyright (C) 2011 John Tsiombikas <nuclear@member.fsf.org> 8.7 + 8.8 +This program is free software: you can redistribute it and/or modify 8.9 +it under the terms of the GNU General Public License as published by 8.10 +the Free Software Foundation, either version 3 of the License, or 8.11 +(at your option) any later version. 8.12 + 8.13 +This program is distributed in the hope that it will be useful, 8.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 8.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 8.16 +GNU General Public License for more details. 8.17 + 8.18 +You should have received a copy of the GNU General Public License 8.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 8.20 +*/ 8.21 +#include <math.h> 8.22 +#include <assert.h> 8.23 +#include "mingl.h" 8.24 + 8.25 + 8.26 +void mgl_cube(float sz) 8.27 +{ 8.28 + float hsz = sz * 0.5; 8.29 + 8.30 + mgl_begin(MGL_QUADS); 8.31 + /* front */ 8.32 + mgl_normal(0, 0, 1); 8.33 + mgl_vertex3f(-hsz, hsz, hsz); 8.34 + mgl_vertex3f(-hsz, -hsz, hsz); 8.35 + mgl_vertex3f(hsz, -hsz, hsz); 8.36 + mgl_vertex3f(hsz, hsz, hsz); 8.37 + /* back */ 8.38 + mgl_normal(0, 0, -1); 8.39 + mgl_vertex3f(hsz, hsz, -hsz); 8.40 + mgl_vertex3f(hsz, -hsz, -hsz); 8.41 + mgl_vertex3f(-hsz, -hsz, -hsz); 8.42 + mgl_vertex3f(-hsz, hsz, -hsz); 8.43 + /* right */ 8.44 + mgl_normal(1, 0, 0); 8.45 + mgl_vertex3f(hsz, hsz, hsz); 8.46 + mgl_vertex3f(hsz, -hsz, hsz); 8.47 + mgl_vertex3f(hsz, -hsz, -hsz); 8.48 + mgl_vertex3f(hsz, hsz, -hsz); 8.49 + /* left */ 8.50 + mgl_normal(-1, 0, 0); 8.51 + mgl_vertex3f(-hsz, hsz, -hsz); 8.52 + mgl_vertex3f(-hsz, -hsz, -hsz); 8.53 + mgl_vertex3f(-hsz, -hsz, hsz); 8.54 + mgl_vertex3f(-hsz, hsz, hsz); 8.55 + /* top */ 8.56 + mgl_normal(0, 1, 0); 8.57 + mgl_vertex3f(-hsz, hsz, -hsz); 8.58 + mgl_vertex3f(-hsz, hsz, hsz); 8.59 + mgl_vertex3f(hsz, hsz, hsz); 8.60 + mgl_vertex3f(hsz, hsz, -hsz); 8.61 + /* bottom */ 8.62 + mgl_normal(0, -1, 0); 8.63 + mgl_vertex3f(hsz, -hsz, -hsz); 8.64 + mgl_vertex3f(hsz, -hsz, hsz); 8.65 + mgl_vertex3f(-hsz, -hsz, hsz); 8.66 + mgl_vertex3f(-hsz, -hsz, -hsz); 8.67 + mgl_end(); 8.68 +} 8.69 + 8.70 +void mgl_sphere(float rad, int usub, int vsub) 8.71 +{ 8.72 + mgl_sphere_part(rad, usub, vsub, 1.0, 1.0); 8.73 +} 8.74 + 8.75 +#define sphere_vertex(u, v) \ 8.76 + do { \ 8.77 + float x, y, z, theta, phi; \ 8.78 + float costheta, sinphi; \ 8.79 + theta = (u) * 2.0 * M_PI; \ 8.80 + phi = (v) * M_PI; \ 8.81 + costheta = cos(theta); \ 8.82 + sinphi = sin(phi); \ 8.83 + x = costheta * sinphi; \ 8.84 + y = cos(phi); \ 8.85 + z = sin(theta) * sinphi; \ 8.86 + mgl_normal(x, y, z); \ 8.87 + mgl_texcoord2f(u, v); \ 8.88 + mgl_vertex3f(rad * x, rad * y, rad * z); \ 8.89 + } while(0) 8.90 + 8.91 +void mgl_sphere_part(float rad, int usub, int vsub, float umax, float vmax) 8.92 +{ 8.93 + int i, j; 8.94 + float u, v, du, dv; 8.95 + 8.96 + assert(usub > 2); 8.97 + assert(vsub > 2); 8.98 + 8.99 + du = umax / (float)usub; 8.100 + dv = vmax / (float)vsub; 8.101 + 8.102 + mgl_begin(MGL_QUADS); 8.103 + 8.104 + u = 0.0; 8.105 + for(i=0; i<usub; i++) { 8.106 + v = 0.0; 8.107 + for(j=0; j<vsub; j++) { 8.108 + sphere_vertex(u, v); 8.109 + sphere_vertex(u + du, v); 8.110 + sphere_vertex(u + du, v + dv); 8.111 + sphere_vertex(u, v + dv); 8.112 + v += dv; 8.113 + } 8.114 + u += du; 8.115 + } 8.116 + mgl_end(); 8.117 +} 8.118 + 8.119 +void mgl_torus(float inner, float outer, int usub, int vsub) 8.120 +{ 8.121 + mgl_torus_part(inner, outer, usub, vsub, 1.0, 0.0, 1.0); 8.122 +} 8.123 + 8.124 +#define torus_vertex(u, v) \ 8.125 + do { \ 8.126 + float rx, ry, rz, cx, cy, cz, theta, phi; \ 8.127 + float costheta, sintheta, sinphi; \ 8.128 + theta = (u) * 2.0 * M_PI; \ 8.129 + phi = (v) * 2.0 * M_PI; \ 8.130 + costheta = cos(theta); \ 8.131 + sintheta = sin(theta); \ 8.132 + sinphi = sin(phi); \ 8.133 + cx = costheta * inner; \ 8.134 + cy = 0.0f; \ 8.135 + cz = sintheta * inner; \ 8.136 + rx = costheta * sinphi; \ 8.137 + ry = cos(phi); \ 8.138 + rz = sintheta * sinphi; \ 8.139 + mgl_normal(rx, ry, rz); \ 8.140 + mgl_texcoord2f(u, v); \ 8.141 + mgl_vertex3f(outer * rx + cx, outer * ry + cy, outer * rz + cz); \ 8.142 + } while(0) 8.143 + 8.144 +void mgl_torus_part(float inner, float outer, int usub, int vsub, float umax, float vmin, float vmax) 8.145 +{ 8.146 + int i, j; 8.147 + float u, v, du, dv; 8.148 + 8.149 + assert(usub > 2); 8.150 + assert(vsub > 2); 8.151 + 8.152 + du = umax / (float)usub; 8.153 + dv = (vmax - vmin) / (float)vsub; 8.154 + 8.155 + mgl_begin(MGL_QUADS); 8.156 + 8.157 + u = 0.0; 8.158 + for(i=0; i<usub; i++) { 8.159 + v = vmin; 8.160 + for(j=0; j<vsub; j++) { 8.161 + torus_vertex(u, v); 8.162 + torus_vertex(u + du, v); 8.163 + torus_vertex(u + du, v + dv); 8.164 + torus_vertex(u, v + dv); 8.165 + v += dv; 8.166 + } 8.167 + u += du; 8.168 + } 8.169 + mgl_end(); 8.170 +}
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/src/mglimpl.h Mon Nov 21 06:14:01 2011 +0200 9.3 @@ -0,0 +1,75 @@ 9.4 +/* 9.5 +256-color 3D graphics hack for real-mode DOS. 9.6 +Copyright (C) 2011 John Tsiombikas <nuclear@member.fsf.org> 9.7 + 9.8 +This program is free software: you can redistribute it and/or modify 9.9 +it under the terms of the GNU General Public License as published by 9.10 +the Free Software Foundation, either version 3 of the License, or 9.11 +(at your option) any later version. 9.12 + 9.13 +This program is distributed in the hope that it will be useful, 9.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 9.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9.16 +GNU General Public License for more details. 9.17 + 9.18 +You should have received a copy of the GNU General Public License 9.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 9.20 +*/ 9.21 +#ifndef MGL_IMPL_H_ 9.22 +#define MGL_IMPL_H_ 9.23 + 9.24 +#define MATRIX_STACK_SIZE 8 9.25 +#define MAX_LIGHTS 4 9.26 + 9.27 +#define ROUND(x) ((x) >= 0.0 ? (x) + 0.5 : (x) - 0.5) 9.28 + 9.29 +typedef struct { 9.30 + float x, y, z, w; 9.31 +} vec4_t; 9.32 + 9.33 +typedef struct { 9.34 + float x, y, z; 9.35 +} vec3_t; 9.36 + 9.37 +typedef struct { 9.38 + float x, y; 9.39 +} vec2_t; 9.40 + 9.41 +typedef float mat4_t[16]; 9.42 + 9.43 +struct vertex { 9.44 + vec4_t pos; 9.45 + vec3_t norm; 9.46 + vec2_t tc; 9.47 + float energy; 9.48 + int cidx; 9.49 +}; 9.50 + 9.51 +struct state { 9.52 + unsigned int flags; 9.53 + int ord, frontface, cullface; 9.54 + int mmode, mtop[2]; 9.55 + mat4_t matrix[2][MATRIX_STACK_SIZE]; 9.56 + int prim; 9.57 + struct vertex curv, v[4]; 9.58 + int vidx; 9.59 + int vp[4]; /* viewport */ 9.60 + int col_range; /* color interpolation range */ 9.61 + vec3_t ldir[MAX_LIGHTS]; 9.62 + float lint[MAX_LIGHTS]; 9.63 +}; 9.64 + 9.65 +struct framebuffer { 9.66 + int width, height; 9.67 + unsigned char *pixels; 9.68 + unsigned short **zbuf; /* zbuffer broken in 64k tiles */ 9.69 +}; 9.70 + 9.71 +int mgl_rast_init(struct state *state, struct framebuffer *fbuf); 9.72 +void mgl_rast_cleanup(void); 9.73 +void mgl_rast_prepare(void); 9.74 +void mgl_draw_point(struct vertex *v); 9.75 +void mgl_draw_line(struct vertex *v0, struct vertex *v1); 9.76 +void mgl_draw_poly(struct vertex *v, int numv); 9.77 + 9.78 +#endif /* MGL_IMPL_H_ */
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/src/mglrast.c Mon Nov 21 06:14:01 2011 +0200 10.3 @@ -0,0 +1,163 @@ 10.4 +/* 10.5 +256-color 3D graphics hack for real-mode DOS. 10.6 +Copyright (C) 2011 John Tsiombikas <nuclear@member.fsf.org> 10.7 + 10.8 +This program is free software: you can redistribute it and/or modify 10.9 +it under the terms of the GNU General Public License as published by 10.10 +the Free Software Foundation, either version 3 of the License, or 10.11 +(at your option) any later version. 10.12 + 10.13 +This program is distributed in the hope that it will be useful, 10.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 10.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10.16 +GNU General Public License for more details. 10.17 + 10.18 +You should have received a copy of the GNU General Public License 10.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 10.20 +*/ 10.21 +#include <stdio.h> 10.22 +#include <stdlib.h> 10.23 +#include <string.h> 10.24 +#include <assert.h> 10.25 +#include "mingl.h" 10.26 +#include "mglimpl.h" 10.27 + 10.28 + 10.29 +static struct vertex *vleft, *vright; 10.30 +static struct framebuffer *fb; 10.31 +static struct state *st; 10.32 + 10.33 + 10.34 +#define SCAN_EDGE scan_edge_flat 10.35 +#define SCAN_LINE scan_line_flat 10.36 +#undef INTERP_DEPTH 10.37 +#undef INTERP_ENERGY 10.38 +#include "scantmpl.h" 10.39 +#undef SCAN_EDGE 10.40 +#undef SCAN_LINE 10.41 + 10.42 +#define SCAN_EDGE scan_edge_z 10.43 +#define SCAN_LINE scan_line_z 10.44 +#define INTERP_DEPTH 10.45 +#undef INTERP_ENERGY 10.46 +#include "scantmpl.h" 10.47 +#undef SCAN_EDGE 10.48 +#undef SCAN_LINE 10.49 + 10.50 +#define SCAN_EDGE scan_edge_e 10.51 +#define SCAN_LINE scan_line_e 10.52 +#undef INTERP_DEPTH 10.53 +#define INTERP_ENERGY 10.54 +#include "scantmpl.h" 10.55 +#undef SCAN_EDGE 10.56 +#undef SCAN_LINE 10.57 + 10.58 +#define SCAN_EDGE scan_edge_ze 10.59 +#define SCAN_LINE scan_line_ze 10.60 +#define INTERP_DEPTH 10.61 +#define INTERP_ENERGY 10.62 +#include "scantmpl.h" 10.63 +#undef SCAN_EDGE 10.64 +#undef SCAN_LINE 10.65 + 10.66 +static void (*scan_edge)(struct vertex*, struct vertex*); 10.67 +static void (*scan_line)(int, unsigned char*); 10.68 + 10.69 +int mgl_rast_init(struct state *state, struct framebuffer *fbuf) 10.70 +{ 10.71 + fb = fbuf; 10.72 + st = state; 10.73 + 10.74 + if(!(vleft = malloc(fb->height * sizeof *vleft))) { 10.75 + return -1; 10.76 + } 10.77 + if(!(vright = malloc(fb->height * sizeof *vright))) { 10.78 + free(vleft); 10.79 + return -1; 10.80 + } 10.81 + 10.82 + scan_edge = scan_edge_flat; 10.83 + scan_line = scan_line_flat; 10.84 + 10.85 + return 0; 10.86 +} 10.87 + 10.88 +void mgl_rast_cleanup(void) 10.89 +{ 10.90 + free(vleft); 10.91 + free(vright); 10.92 +} 10.93 + 10.94 +void mgl_rast_prepare(void) 10.95 +{ 10.96 + static void (*sedge[])(struct vertex*, struct vertex*) = { 10.97 + scan_edge_flat, /* 00 */ 10.98 + scan_edge_z, /* 01 */ 10.99 + scan_edge_e, /* 10 */ 10.100 + scan_edge_ze /* 11 */ 10.101 + }; 10.102 + static void (*sline[])(int, unsigned char*) = { 10.103 + scan_line_flat, /* 00 */ 10.104 + scan_line_z, /* 01 */ 10.105 + scan_line_e, /* 10 */ 10.106 + scan_line_ze /* 11 */ 10.107 + }; 10.108 + int bits = 0; 10.109 + 10.110 + if(st->flags & MGL_SMOOTH) { 10.111 + bits |= 2; 10.112 + } 10.113 + if((st->flags & MGL_DEPTH_TEST) && fb->zbuf) { 10.114 + bits |= 1; 10.115 + } 10.116 + 10.117 + scan_edge = sedge[bits]; 10.118 + scan_line = sline[bits]; 10.119 +} 10.120 + 10.121 +void mgl_draw_point(struct vertex *v) 10.122 +{ 10.123 + int x = (int)ROUND(v->pos.x); 10.124 + int y = (int)ROUND(v->pos.y); 10.125 + 10.126 + if(x >= 0 && x < fb->width && y >= 0 && y < fb->height) { 10.127 + int cidx = v->cidx + v->energy * st->col_range; 10.128 + fb->pixels[y * fb->width + x] = cidx; 10.129 + } 10.130 +} 10.131 + 10.132 +void mgl_draw_line(struct vertex *v0, struct vertex *v1) 10.133 +{ 10.134 + /* TODO */ 10.135 + fprintf(stderr, "draw_line unimplemented\n"); 10.136 + abort(); 10.137 +} 10.138 + 10.139 +void mgl_draw_poly(struct vertex *v, int numv) 10.140 +{ 10.141 + int ybeg, yend, i; 10.142 + unsigned char *sline; 10.143 + 10.144 + ybeg = fb->height; 10.145 + yend = 0; 10.146 + 10.147 + for(i=0; i<numv; i++) { 10.148 + struct vertex *v0 = v + i; 10.149 + struct vertex *v1 = v + (i + 1) % numv; 10.150 + int y = (int)ROUND(v0->pos.y); 10.151 + 10.152 + scan_edge(v0, v1); 10.153 + 10.154 + if(y > yend) yend = y; 10.155 + if(y < ybeg) ybeg = y; 10.156 + } 10.157 + 10.158 + if(ybeg < 0) ybeg = 0; 10.159 + if(yend >= fb->height) yend = fb->height - 1; 10.160 + 10.161 + sline = fb->pixels + ybeg * fb->width; 10.162 + for(i=ybeg; i<yend; i++) { 10.163 + scan_line(i, sline); 10.164 + sline += fb->width; 10.165 + } 10.166 +}
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/src/mingl.c Mon Nov 21 06:14:01 2011 +0200 11.3 @@ -0,0 +1,466 @@ 11.4 +/* 11.5 +256-color 3D graphics hack for real-mode DOS. 11.6 +Copyright (C) 2011 John Tsiombikas <nuclear@member.fsf.org> 11.7 + 11.8 +This program is free software: you can redistribute it and/or modify 11.9 +it under the terms of the GNU General Public License as published by 11.10 +the Free Software Foundation, either version 3 of the License, or 11.11 +(at your option) any later version. 11.12 + 11.13 +This program is distributed in the hope that it will be useful, 11.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 11.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11.16 +GNU General Public License for more details. 11.17 + 11.18 +You should have received a copy of the GNU General Public License 11.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 11.20 +*/ 11.21 +#include <stdio.h> 11.22 +#include <stdlib.h> 11.23 +#include <string.h> 11.24 +#include <math.h> 11.25 +#include <assert.h> 11.26 +#include "mingl.h" 11.27 +#include "mglimpl.h" 11.28 + 11.29 +#define DOT(a, b) ((a).x * (b).x + (a).y * (b).y + (a).z * (b).z) 11.30 + 11.31 +static void transform(vec4_t *res, vec4_t *v, float *mat); 11.32 +static void transform3(vec3_t *res, vec3_t *v, float *mat); 11.33 +static void vertex_proc(struct vertex *vert); 11.34 + 11.35 +static struct state st; 11.36 +static struct framebuffer fb; 11.37 + 11.38 +int mgl_init(int width, int height) 11.39 +{ 11.40 + int i; 11.41 + 11.42 + st.flags = 0; 11.43 + st.mmode = 0; 11.44 + 11.45 + mgl_front_face(MGL_CCW); 11.46 + mgl_cull_face(MGL_BACK); 11.47 + 11.48 + st.curv.cidx = 0; 11.49 + st.curv.energy = 1.0; 11.50 + st.curv.norm.x = st.curv.norm.y = st.curv.norm.z = 0.0; 11.51 + 11.52 + if(!(fb.pixels = malloc(width * height))) { 11.53 + return -1; 11.54 + } 11.55 + fb.width = width; 11.56 + fb.height = height; 11.57 + fb.zbuf = 0; 11.58 + 11.59 + if(mgl_rast_init(&st, &fb) == -1) { 11.60 + free(fb.pixels); 11.61 + return -1; 11.62 + } 11.63 + 11.64 + st.mtop[0] = st.mtop[1] = 0; 11.65 + 11.66 + mgl_matrix_mode(MGL_MODELVIEW); 11.67 + mgl_load_identity(); 11.68 + mgl_matrix_mode(MGL_PROJECTION); 11.69 + mgl_load_identity(); 11.70 + 11.71 + /* initial viewport in the size of the framebuffer */ 11.72 + st.vp[0] = st.vp[1] = 0; 11.73 + st.vp[2] = width; 11.74 + st.vp[3] = height; 11.75 + 11.76 + st.col_range = 256; 11.77 + for(i=0; i<MAX_LIGHTS; i++) { 11.78 + st.ldir[i].x = st.ldir[i].y = 0.0f; 11.79 + st.ldir[i].z = 1.0f; 11.80 + st.lint[i] = 0.0f; 11.81 + } 11.82 + 11.83 + return 0; 11.84 +} 11.85 + 11.86 +void mgl_free(void) 11.87 +{ 11.88 + mgl_rast_cleanup(); 11.89 + free(fb.pixels); 11.90 +} 11.91 + 11.92 +unsigned char *mgl_framebuffer(void) 11.93 +{ 11.94 + return fb.pixels; 11.95 +} 11.96 + 11.97 +void mgl_clear(int cidx) 11.98 +{ 11.99 + memset(fb.pixels, cidx, fb.width * fb.height); 11.100 +} 11.101 + 11.102 +void mgl_enable(unsigned int bit) 11.103 +{ 11.104 + st.flags |= bit; 11.105 +} 11.106 + 11.107 +void mgl_disable(unsigned int bit) 11.108 +{ 11.109 + st.flags &= ~bit; 11.110 +} 11.111 + 11.112 +void mgl_front_face(int ff) 11.113 +{ 11.114 + st.frontface = ff; 11.115 +} 11.116 + 11.117 +void mgl_cull_face(int cf) 11.118 +{ 11.119 + st.cullface = cf; 11.120 +} 11.121 + 11.122 +void mgl_color_range(int rng) 11.123 +{ 11.124 + st.col_range = rng; 11.125 +} 11.126 + 11.127 +void mgl_light_intensity(int ltidx, float intens) 11.128 +{ 11.129 + assert(ltidx >= 0 && ltidx < MAX_LIGHTS); 11.130 + st.lint[ltidx] = intens; 11.131 +} 11.132 + 11.133 +void mgl_light_direction(int ltidx, float x, float y, float z) 11.134 +{ 11.135 + vec3_t dir; 11.136 + float mag; 11.137 + assert(ltidx >= 0 && ltidx < MAX_LIGHTS); 11.138 + 11.139 + dir.x = x; 11.140 + dir.y = y; 11.141 + dir.z = z; 11.142 + transform3(&st.ldir[ltidx], &dir, st.matrix[MGL_MODELVIEW][st.mtop[MGL_MODELVIEW]]); 11.143 + 11.144 + mag = sqrt(DOT(st.ldir[ltidx], st.ldir[ltidx])); 11.145 + if(fabs(mag) < 1e-6) { 11.146 + mag = 1.0f; 11.147 + } 11.148 + st.ldir[ltidx].x /= mag; 11.149 + st.ldir[ltidx].y /= mag; 11.150 + st.ldir[ltidx].z /= mag; 11.151 +} 11.152 + 11.153 +void mgl_begin(int prim) 11.154 +{ 11.155 + st.prim = prim; 11.156 + st.vidx = 0; 11.157 + 11.158 + st.ord = st.frontface; 11.159 + if(st.cullface == MGL_FRONT) { 11.160 + st.ord = st.frontface == MGL_CCW ? MGL_CW : MGL_CCW; 11.161 + } 11.162 + 11.163 + /* select the correct rasterizer according to state */ 11.164 + mgl_rast_prepare(); 11.165 +} 11.166 + 11.167 +void mgl_end(void) 11.168 +{ 11.169 +} 11.170 + 11.171 +void mgl_vertex2f(float x, float y) 11.172 +{ 11.173 + mgl_vertex4f(x, y, 0.0f, 1.0f); 11.174 +} 11.175 + 11.176 +void mgl_vertex3f(float x, float y, float z) 11.177 +{ 11.178 + mgl_vertex4f(x, y, z, 1.0f); 11.179 +} 11.180 + 11.181 +void mgl_vertex4f(float x, float y, float z, float w) 11.182 +{ 11.183 + st.v[st.vidx].pos.x = x; 11.184 + st.v[st.vidx].pos.y = y; 11.185 + st.v[st.vidx].pos.z = z; 11.186 + st.v[st.vidx].pos.w = w; 11.187 + st.v[st.vidx].cidx = st.curv.cidx; 11.188 + st.v[st.vidx].energy = st.curv.energy; 11.189 + st.v[st.vidx].norm = st.curv.norm; 11.190 + st.v[st.vidx].tc = st.curv.tc; 11.191 + 11.192 + vertex_proc(st.v + st.vidx); 11.193 + 11.194 + if(++st.vidx >= st.prim) { 11.195 + switch(st.prim) { 11.196 + case MGL_POINTS: 11.197 + mgl_draw_point(st.v); 11.198 + break; 11.199 + case MGL_LINES: 11.200 + mgl_draw_line(st.v, st.v + 1); 11.201 + break; 11.202 + case MGL_TRIANGLES: 11.203 + case MGL_QUADS: 11.204 + mgl_draw_poly(st.v, st.prim); 11.205 + break; 11.206 + default: 11.207 + fprintf(stderr, "invalid primitive: %d\n", st.prim); 11.208 + abort(); 11.209 + } 11.210 + st.vidx = 0; 11.211 + } 11.212 +} 11.213 + 11.214 +void mgl_color1f(float energy) 11.215 +{ 11.216 + st.curv.energy = energy; 11.217 +} 11.218 + 11.219 +void mgl_index(int c) 11.220 +{ 11.221 + st.curv.cidx = c; 11.222 +} 11.223 + 11.224 +void mgl_normal(float x, float y, float z) 11.225 +{ 11.226 + st.curv.norm.x = x; 11.227 + st.curv.norm.y = y; 11.228 + st.curv.norm.z = z; 11.229 +} 11.230 + 11.231 +void mgl_texcoord2f(float x, float y) 11.232 +{ 11.233 + st.curv.tc.x = x; 11.234 + st.curv.tc.y = y; 11.235 +} 11.236 + 11.237 +static void transform(vec4_t *res, vec4_t *v, float *mat) 11.238 +{ 11.239 + res->x = mat[0] * v->x + mat[4] * v->y + mat[8] * v->z + mat[12] * v->w; 11.240 + res->y = mat[1] * v->x + mat[5] * v->y + mat[9] * v->z + mat[13] * v->w; 11.241 + res->z = mat[2] * v->x + mat[6] * v->y + mat[10] * v->z + mat[14] * v->w; 11.242 + res->w = mat[3] * v->x + mat[7] * v->y + mat[11] * v->z + mat[15] * v->w; 11.243 +} 11.244 + 11.245 +/* the matrix is 4x4 (16 floats), just ignoring anything out of the 3x3 */ 11.246 +static void transform3(vec3_t *res, vec3_t *v, float *mat) 11.247 +{ 11.248 + res->x = mat[0] * v->x + mat[4] * v->y + mat[8] * v->z; 11.249 + res->y = mat[1] * v->x + mat[5] * v->y + mat[9] * v->z; 11.250 + res->z = mat[2] * v->x + mat[6] * v->y + mat[10] * v->z; 11.251 +} 11.252 + 11.253 +static void vertex_proc(struct vertex *vert) 11.254 +{ 11.255 + vec4_t pview, pclip; 11.256 + 11.257 + float *mvmat = st.matrix[MGL_MODELVIEW][st.mtop[MGL_MODELVIEW]]; 11.258 + float *pmat = st.matrix[MGL_PROJECTION][st.mtop[MGL_PROJECTION]]; 11.259 + 11.260 + /* modelview transformation */ 11.261 + transform(&pview, &vert->pos, mvmat); 11.262 + 11.263 + if(st.flags & MGL_LIGHTING) { 11.264 + if((st.flags & MGL_SMOOTH) || st.vidx == 0) { 11.265 + int i; 11.266 + vec3_t norm; 11.267 + float irrad = 0.0f; 11.268 + 11.269 + transform3(&norm, &vert->norm, mvmat); 11.270 + 11.271 + for(i=0; i<MAX_LIGHTS; i++) { 11.272 + if(st.lint[i] > 1e-6f) { 11.273 + float ndotl = DOT(norm, st.ldir[i]); 11.274 + if(ndotl < 0.0) { 11.275 + ndotl = 0.0; 11.276 + } 11.277 + irrad += ndotl * st.lint[i]; 11.278 + } 11.279 + } 11.280 + vert->energy = irrad; 11.281 + } else { 11.282 + vert->energy = st.v[0].energy; 11.283 + } 11.284 + } 11.285 + 11.286 + transform(&pclip, &pview, pmat); 11.287 + /* TODO clipping in homogenous clip space */ 11.288 + 11.289 + if(pclip.w < 1e-6 && pclip.w > -1e-6) { 11.290 + vert->pos.x = vert->pos.y = vert->pos.z = vert->pos.w = 0.0f; 11.291 + return; 11.292 + } 11.293 + 11.294 + /* perspective division */ 11.295 + vert->pos.x = pclip.x / pclip.w; 11.296 + vert->pos.y = pclip.y / pclip.w; 11.297 + vert->pos.z = pclip.z / pclip.w; 11.298 + vert->pos.w = pclip.w; 11.299 + 11.300 + /* viewport transformation */ 11.301 + vert->pos.x = st.vp[0] + st.vp[2] * (vert->pos.x * 0.5 + 0.5); 11.302 + vert->pos.y = st.vp[1] + st.vp[3] * (-vert->pos.y * 0.5 + 0.5); 11.303 +} 11.304 + 11.305 +void mgl_viewport(int x, int y, int width, int height) 11.306 +{ 11.307 + st.vp[0] = x; 11.308 + st.vp[1] = y; 11.309 + st.vp[2] = width; 11.310 + st.vp[3] = height; 11.311 +} 11.312 + 11.313 +void mgl_matrix_mode(int mmode) 11.314 +{ 11.315 + st.mmode = mmode; 11.316 +} 11.317 + 11.318 +void mgl_push_matrix(void) 11.319 +{ 11.320 + float *topmat; 11.321 + if(st.mtop[st.mmode] >= MATRIX_STACK_SIZE - 1) { 11.322 + fprintf(stderr, "mgl_push_matrix: stack overflow\n"); 11.323 + abort(); 11.324 + } 11.325 + 11.326 + topmat = st.matrix[st.mmode][st.mtop[st.mmode]]; 11.327 + memcpy(topmat + 16, topmat, 16 * sizeof *topmat); 11.328 + st.mmode++; 11.329 +} 11.330 + 11.331 +void mgl_pop_matrix(void) 11.332 +{ 11.333 + if(st.mtop[st.mmode] <= 0) { 11.334 + fprintf(stderr, "mgl_pop_matrix: stack underflow\n"); 11.335 + abort(); 11.336 + } 11.337 + st.mtop[st.mmode]--; 11.338 +} 11.339 + 11.340 +void mgl_load_matrix(float *mat) 11.341 +{ 11.342 + float *dest = st.matrix[st.mmode][st.mtop[st.mmode]]; 11.343 + memcpy(dest, mat, 16 * sizeof *dest); 11.344 +} 11.345 + 11.346 +#define M(i,j) (((j) << 2) + (i)) 11.347 +void mgl_mult_matrix(float *m2) 11.348 +{ 11.349 + int i, j; 11.350 + float m1[16]; 11.351 + float *dest = st.matrix[st.mmode][st.mtop[st.mmode]]; 11.352 + 11.353 + memcpy(m1, dest, sizeof m1); 11.354 + 11.355 + for(i=0; i<4; i++) { 11.356 + for(j=0; j<4; j++) { 11.357 + dest[M(i,j)] = m1[M(0,j)] * m2[M(i,0)] + 11.358 + m1[M(1,j)] * m2[M(i,1)] + 11.359 + m1[M(2,j)] * m2[M(i,2)] + 11.360 + m1[M(3,j)] * m2[M(i,3)]; 11.361 + } 11.362 + } 11.363 +} 11.364 + 11.365 +void mgl_load_identity(void) 11.366 +{ 11.367 + static float id[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; 11.368 + mgl_load_matrix((float*)id); 11.369 +} 11.370 + 11.371 +void mgl_translate(float x, float y, float z) 11.372 +{ 11.373 + float xform[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; 11.374 + xform[12] = x; 11.375 + xform[13] = y; 11.376 + xform[14] = z; 11.377 + mgl_mult_matrix(xform); 11.378 +} 11.379 + 11.380 +void mgl_rotate(float deg, float x, float y, float z) 11.381 +{ 11.382 + float xform[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; 11.383 + 11.384 + float angle = M_PI * deg / 180.0f; 11.385 + float sina = sin(angle); 11.386 + float cosa = cos(angle); 11.387 + float one_minus_cosa = 1.0f - cosa; 11.388 + float nxsq = x * x; 11.389 + float nysq = y * y; 11.390 + float nzsq = z * z; 11.391 + 11.392 + xform[0] = nxsq + (1.0f - nxsq) * cosa; 11.393 + xform[4] = x * y * one_minus_cosa - z * sina; 11.394 + xform[8] = x * z * one_minus_cosa + y * sina; 11.395 + xform[1] = x * y * one_minus_cosa + z * sina; 11.396 + xform[5] = nysq + (1.0 - nysq) * cosa; 11.397 + xform[9] = y * z * one_minus_cosa - x * sina; 11.398 + xform[2] = x * z * one_minus_cosa - y * sina; 11.399 + xform[6] = y * z * one_minus_cosa + x * sina; 11.400 + xform[10] = nzsq + (1.0 - nzsq) * cosa; 11.401 + 11.402 + mgl_mult_matrix(xform); 11.403 +} 11.404 + 11.405 +void mgl_scale(float x, float y, float z) 11.406 +{ 11.407 + float xform[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; 11.408 + xform[0] = x; 11.409 + xform[5] = y; 11.410 + xform[10] = z; 11.411 + mgl_mult_matrix(xform); 11.412 +} 11.413 + 11.414 +void gl_ortho(float left, float right, float bottom, float top, float nr, float fr) 11.415 +{ 11.416 + float xform[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; 11.417 + 11.418 + float dx = right - left; 11.419 + float dy = top - bottom; 11.420 + float dz = fr - nr; 11.421 + 11.422 + float tx = -(right + left) / dx; 11.423 + float ty = -(top + bottom) / dy; 11.424 + float tz = -(fr + nr) / dz; 11.425 + 11.426 + float sx = 2.0 / dx; 11.427 + float sy = 2.0 / dy; 11.428 + float sz = -2.0 / dz; 11.429 + 11.430 + xform[0] = sx; 11.431 + xform[5] = sy; 11.432 + xform[10] = sz; 11.433 + xform[12] = tx; 11.434 + xform[13] = ty; 11.435 + xform[14] = tz; 11.436 + 11.437 + mgl_mult_matrix(xform); 11.438 +} 11.439 + 11.440 +void mgl_frustum(float left, float right, float bottom, float top, float nr, float fr) 11.441 +{ 11.442 + float xform[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; 11.443 + 11.444 + float dx = right - left; 11.445 + float dy = top - bottom; 11.446 + float dz = fr - nr; 11.447 + 11.448 + float a = (right + left) / dx; 11.449 + float b = (top + bottom) / dy; 11.450 + float c = -(fr + nr) / dz; 11.451 + float d = -2.0 * fr * nr / dz; 11.452 + 11.453 + xform[0] = 2.0 * nr / dx; 11.454 + xform[5] = 2.0 * nr / dy; 11.455 + xform[8] = a; 11.456 + xform[9] = b; 11.457 + xform[10] = c; 11.458 + xform[11] = -1.0f; 11.459 + xform[14] = d; 11.460 + 11.461 + mgl_mult_matrix(xform); 11.462 +} 11.463 + 11.464 +void mgl_perspective(float vfov, float aspect, float nr, float fr) 11.465 +{ 11.466 + float vfov_rad = M_PI * vfov / 180.0; 11.467 + float x = nr * tan(vfov_rad / 2.0); 11.468 + mgl_frustum(-aspect * x, aspect * x, -x, x, nr, fr); 11.469 +}
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/src/mingl.h Mon Nov 21 06:14:01 2011 +0200 12.3 @@ -0,0 +1,95 @@ 12.4 +/* 12.5 +256-color 3D graphics hack for real-mode DOS. 12.6 +Copyright (C) 2011 John Tsiombikas <nuclear@member.fsf.org> 12.7 + 12.8 +This program is free software: you can redistribute it and/or modify 12.9 +it under the terms of the GNU General Public License as published by 12.10 +the Free Software Foundation, either version 3 of the License, or 12.11 +(at your option) any later version. 12.12 + 12.13 +This program is distributed in the hope that it will be useful, 12.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 12.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12.16 +GNU General Public License for more details. 12.17 + 12.18 +You should have received a copy of the GNU General Public License 12.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 12.20 +*/ 12.21 +#ifndef MINGL_H_ 12.22 +#define MINGL_H_ 12.23 + 12.24 +/* enable bitflags */ 12.25 +#define MGL_CULL_FACE 1 12.26 +#define MGL_DEPTH_TEST 2 12.27 +#define MGL_SMOOTH 4 12.28 +#define MGL_LIGHTING 8 12.29 + 12.30 +/* primitives */ 12.31 +#define MGL_POINTS 1 12.32 +#define MGL_LINES 2 12.33 +#define MGL_TRIANGLES 3 12.34 +#define MGL_QUADS 4 12.35 + 12.36 +/* matrices */ 12.37 +#define MGL_MODELVIEW 0 12.38 +#define MGL_PROJECTION 1 12.39 +#define MGL_TEXTURE 2 12.40 + 12.41 +#define MGL_FRONT 0 12.42 +#define MGL_BACK 1 12.43 + 12.44 +#define MGL_CCW 0 12.45 +#define MGL_CW 1 12.46 + 12.47 +int mgl_init(int width, int height); 12.48 +void mgl_free(void); 12.49 + 12.50 +unsigned char *mgl_framebuffer(void); 12.51 + 12.52 +void mgl_clear(int cidx); 12.53 + 12.54 +void mgl_enable(unsigned int bit); 12.55 +void mgl_disable(unsigned int bit); 12.56 + 12.57 +void mgl_front_face(int ff); 12.58 +void mgl_cull_face(int cf); 12.59 + 12.60 +void mgl_color_range(int rng); 12.61 +void mgl_light_intensity(int ltidx, float intens); 12.62 +void mgl_light_direction(int ltidx, float x, float y, float z); 12.63 + 12.64 +void mgl_begin(int prim); 12.65 +void mgl_end(void); 12.66 + 12.67 +void mgl_vertex2f(float x, float y); 12.68 +void mgl_vertex3f(float x, float y, float z); 12.69 +void mgl_vertex4f(float x, float y, float z, float w); 12.70 +void mgl_color1f(float energy); 12.71 +void mgl_index(int cidx); 12.72 +void mgl_normal(float x, float y, float z); 12.73 +void mgl_texcoord2f(float x, float y); 12.74 + 12.75 +void mgl_viewport(int x, int y, int width, int height); 12.76 + 12.77 +void mgl_matrix_mode(int mmode); 12.78 +void mgl_push_matrix(void); 12.79 +void mgl_pop_matrix(void); 12.80 +void mgl_load_matrix(float *mat); 12.81 +void mgl_mult_matrix(float *mat); 12.82 +void mgl_load_identity(void); 12.83 + 12.84 +void mgl_translate(float x, float y, float z); 12.85 +void mgl_rotate(float angle, float x, float y, float z); 12.86 +void mgl_scale(float x, float y, float z); 12.87 + 12.88 +void mgl_ortho(float left, float right, float bottom, float top, float nr, float fr); 12.89 +void mgl_frustum(float left, float right, float bottom, float top, float nr, float fr); 12.90 +void mgl_perspective(float vfov, float aspect, float nr, float fr); 12.91 + 12.92 +void mgl_cube(float sz); 12.93 +void mgl_sphere(float rad, int usub, int vsub); 12.94 +void mgl_sphere_part(float rad, int usub, int vsub, float umax, float vmax); 12.95 +void mgl_torus(float inner, float outer, int usub, int vsub); 12.96 +void mgl_torus_part(float inner, float outer, int usub, int vsub, float umax, float vmin, float vmax); 12.97 + 12.98 +#endif /* MINGL_H_ */
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 13.2 +++ b/src/mouse.c Mon Nov 21 06:14:01 2011 +0200 13.3 @@ -0,0 +1,74 @@ 13.4 +#include "mouse.h" 13.5 + 13.6 +#define INTR 0x33 13.7 + 13.8 +#define QUERY 0 13.9 +#define SHOW 1 13.10 +#define HIDE 2 13.11 +#define READ 3 13.12 +#define WRITE 4 13.13 + 13.14 +#define XLIM 7 13.15 +#define YLIM 8 13.16 + 13.17 +int have_mouse(void) 13.18 +{ 13.19 + int res; 13.20 + asm { 13.21 + mov ax, QUERY 13.22 + int INTR 13.23 + mov res, ax 13.24 + } 13.25 + return res; 13.26 +} 13.27 + 13.28 +void show_mouse(int show) 13.29 +{ 13.30 + int cmd = show ? SHOW : HIDE; 13.31 + asm { 13.32 + mov ax, cmd 13.33 + int INTR 13.34 + } 13.35 +} 13.36 + 13.37 +int read_mouse(int *xp, int *yp) 13.38 +{ 13.39 + int x, y, bn; 13.40 + 13.41 + asm { 13.42 + mov ax, READ 13.43 + int INTR 13.44 + mov bn, bx 13.45 + mov x, cx 13.46 + mov y, dx 13.47 + /* XXX some sort of div by 8 in the original code ? */ 13.48 + } 13.49 + 13.50 + if(xp) *xp = x; 13.51 + if(yp) *yp = y; 13.52 + return bn; 13.53 +} 13.54 + 13.55 +void set_mouse(int x, int y) 13.56 +{ 13.57 + asm { 13.58 + mov ax, WRITE 13.59 + mov cx, x 13.60 + mov dx, y 13.61 + int INTR 13.62 + } 13.63 +} 13.64 + 13.65 +void set_mouse_limits(int xmin, int ymin, int xmax, int ymax) 13.66 +{ 13.67 + asm { 13.68 + mov ax, XLIM 13.69 + mov cx, xmin 13.70 + mov dx, xmax 13.71 + int INTR 13.72 + mov ax, YLIM 13.73 + mov cx, ymin 13.74 + mov dx, ymax 13.75 + int INTR 13.76 + } 13.77 +}
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 14.2 +++ b/src/mouse.h Mon Nov 21 06:14:01 2011 +0200 14.3 @@ -0,0 +1,14 @@ 14.4 +#ifndef MOUSE_H_ 14.5 +#define MOUSE_H_ 14.6 + 14.7 +#define MOUSE_LEFT 1 14.8 +#define MOUSE_RIGHT 2 14.9 +#define MOUSE_MIDDLE 4 14.10 + 14.11 +int have_mouse(void); 14.12 +void show_mouse(int show); 14.13 +int read_mouse(int *xp, int *yp); 14.14 +void set_mouse(int x, int y); 14.15 +void set_mouse_limits(int xmin, int ymin, int xmax, int ymax); 14.16 + 14.17 +#endif /* MOUSE_H_ */
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 15.2 +++ b/src/pit8254.h Mon Nov 21 06:14:01 2011 +0200 15.3 @@ -0,0 +1,34 @@ 15.4 +#ifndef PIT8254_H_ 15.5 +#define PIT8254_H_ 15.6 + 15.7 +/* frequency of the oscillator driving the 8254 timer */ 15.8 +#define OSC_FREQ_HZ 1193182 15.9 + 15.10 +/* I/O ports connected to the 8254 */ 15.11 +#define PORT_DATA0 0x40 15.12 +#define PORT_DATA1 0x41 15.13 +#define PORT_DATA2 0x42 15.14 +#define PORT_CMD 0x43 15.15 + 15.16 +/* command bits */ 15.17 +#define CMD_CHAN0 0 15.18 +#define CMD_CHAN1 (1 << 6) 15.19 +#define CMD_CHAN2 (2 << 6) 15.20 +#define CMD_RDBACK (3 << 6) 15.21 + 15.22 +#define CMD_LATCH 0 15.23 +#define CMD_ACCESS_LOW (1 << 4) 15.24 +#define CMD_ACCESS_HIGH (2 << 4) 15.25 +#define CMD_ACCESS_BOTH (3 << 4) 15.26 + 15.27 +#define CMD_OP_INT_TERM 0 15.28 +#define CMD_OP_ONESHOT (1 << 1) 15.29 +#define CMD_OP_RATE (2 << 1) 15.30 +#define CMD_OP_SQWAVE (3 << 1) 15.31 +#define CMD_OP_SW_STROBE (4 << 1) 15.32 +#define CMD_OP_HW_STROBE (5 << 1) 15.33 + 15.34 +#define CMD_MODE_BIN 0 15.35 +#define CMD_MODE_BCD 1 15.36 + 15.37 +#endif /* PIT8254_H_ */
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 16.2 +++ b/src/scantmpl.h Mon Nov 21 06:14:01 2011 +0200 16.3 @@ -0,0 +1,158 @@ 16.4 +/* 16.5 +256-color 3D graphics hack for real-mode DOS. 16.6 +Copyright (C) 2011 John Tsiombikas <nuclear@member.fsf.org> 16.7 + 16.8 +This program is free software: you can redistribute it and/or modify 16.9 +it under the terms of the GNU General Public License as published by 16.10 +the Free Software Foundation, either version 3 of the License, or 16.11 +(at your option) any later version. 16.12 + 16.13 +This program is distributed in the hope that it will be useful, 16.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 16.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16.16 +GNU General Public License for more details. 16.17 + 16.18 +You should have received a copy of the GNU General Public License 16.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 16.20 +*/ 16.21 +static void SCAN_EDGE(struct vertex *v0, struct vertex *v1) 16.22 +{ 16.23 + int i, start, end; 16.24 + float dx, dy, dfdx; 16.25 +#ifdef INTERP_DEPTH 16.26 + float z, dz, dfdz; 16.27 +#endif 16.28 +#ifdef INTERP_ENERGY 16.29 + float e, de, dfde; 16.30 +#endif 16.31 + float x, y; 16.32 + struct vertex *edge; 16.33 + 16.34 + dy = v1->pos.y - v0->pos.y; 16.35 + if(dy < 1e-6 && dy > -1e-6) { 16.36 + return; 16.37 + } 16.38 + 16.39 + dx = v1->pos.x - v0->pos.x; 16.40 + dfdx = dx / dy; 16.41 + 16.42 +#ifdef INTERP_DEPTH 16.43 + assert(fb->zbuf); 16.44 + dz = v1->pos.z - v0->pos.z; 16.45 + dfdz = dz / dy; 16.46 +#endif 16.47 +#ifdef INTERP_ENERGY 16.48 + de = v1->energy - v0->energy; 16.49 + dfde = de / dy; 16.50 +#endif 16.51 + 16.52 + if(dy < 0.0) { 16.53 + struct vertex *tmp = v0; 16.54 + v0 = v1; 16.55 + v1 = tmp; 16.56 + edge = (st->ord == MGL_CCW) ? vright : vleft; 16.57 + } else { 16.58 + edge = (st->ord == MGL_CCW) ? vleft : vright; 16.59 + } 16.60 + 16.61 + start = (int)ROUND(v0->pos.y); 16.62 + end = (int)ROUND(v1->pos.y); 16.63 + 16.64 + x = v0->pos.x; 16.65 +#ifdef INTERP_DEPTH 16.66 + z = v0->pos.z; 16.67 +#endif 16.68 +#ifdef INTERP_ENERGY 16.69 + e = v0->energy; 16.70 +#endif 16.71 + for(i=start; i<end; i++) { 16.72 + edge[i].pos.x = x; 16.73 + x += dfdx; 16.74 + 16.75 + edge[i].cidx = v0->cidx; 16.76 +#ifdef INTERP_DEPTH 16.77 + edge[i].pos.z = z; 16.78 + z += dfdz; 16.79 +#endif 16.80 + 16.81 +#ifdef INTERP_ENERGY 16.82 + edge[i].energy = e; 16.83 + e += dfde; 16.84 +#else 16.85 + edge[i].energy = v0->energy; 16.86 +#endif 16.87 + } 16.88 +} 16.89 + 16.90 +static void SCAN_LINE(int y, unsigned char *sline) 16.91 +{ 16.92 + int i, x0, x1, len, tmp, cidx; 16.93 +#if defined(INTERP_DEPTH) || defined(INTERP_ENERGY) 16.94 + float x, dx; 16.95 +#endif 16.96 +#ifdef INTERP_DEPTH 16.97 + float z, dz, dfdz; 16.98 +#endif 16.99 +#ifdef INTERP_ENERGY 16.100 + float e, de, dfde; 16.101 +#endif 16.102 + struct vertex *left, *right; 16.103 + 16.104 + x0 = (int)ROUND(vleft[y].pos.x); 16.105 + x1 = (int)ROUND(vright[y].pos.x); 16.106 + len = x1 - x0; 16.107 + 16.108 + if(x1 < x0) { 16.109 + if(st->flags & MGL_CULL_FACE) { 16.110 + return; 16.111 + } 16.112 + tmp = x0; 16.113 + x0 = x1; 16.114 + x1 = tmp; 16.115 + len = -len; 16.116 + 16.117 + left = vright; 16.118 + right = vleft; 16.119 + } else { 16.120 + left = vleft; 16.121 + right = vright; 16.122 + } 16.123 + 16.124 + if(x0 < 0) x0 = 0; 16.125 + if(x1 >= fb->width) x1 = fb->width - 1; 16.126 + 16.127 + assert(len >= 0); 16.128 + 16.129 + cidx = left[y].cidx; 16.130 +#if !defined(INTERP_DEPTH) && !defined(INTERP_ENERGY) 16.131 + /* no interpolation at all, just memset the whole scanline */ 16.132 + memset(sline + x0, cidx + left[y].energy * st->col_range, len); 16.133 +#else 16.134 + /* otherwise do a loop and interpolate whatever needs interpolating */ 16.135 + x = left[y].pos.x; 16.136 + dx = right[y].pos.x - x; 16.137 + 16.138 + if(dx < 0.5 && dx > -0.5) { 16.139 + return; 16.140 + } 16.141 + 16.142 +#ifdef INTERP_DEPTH 16.143 + z = left[y].pos.z; 16.144 + dz = right[y].pos.z - z; 16.145 + dfdz = dz / dx; 16.146 +#endif 16.147 +#ifdef INTERP_ENERGY 16.148 + e = left[y].energy; 16.149 + de = right[y].energy - e; 16.150 + dfde = de / dx; 16.151 +#endif 16.152 + 16.153 + for(i=0; i<len; i++) { 16.154 +#ifdef INTERP_ENERGY 16.155 + cidx = left[y].cidx + e * st->col_range; 16.156 + e += dfde; 16.157 +#endif 16.158 + sline[x0 + i] = cidx; 16.159 + } 16.160 +#endif /* flat */ 16.161 +}
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 17.2 +++ b/src/test.c Mon Nov 21 06:14:01 2011 +0200 17.3 @@ -0,0 +1,399 @@ 17.4 +/* 17.5 +256-color 3D graphics hack for real-mode DOS. 17.6 +Copyright (C) 2011 John Tsiombikas <nuclear@member.fsf.org> 17.7 + 17.8 +This program is free software: you can redistribute it and/or modify 17.9 +it under the terms of the GNU General Public License as published by 17.10 +the Free Software Foundation, either version 3 of the License, or 17.11 +(at your option) any later version. 17.12 + 17.13 +This program is distributed in the hope that it will be useful, 17.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 17.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17.16 +GNU General Public License for more details. 17.17 + 17.18 +You should have received a copy of the GNU General Public License 17.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 17.20 +*/ 17.21 +#include <stdio.h> 17.22 +#include <stdlib.h> 17.23 +#include <string.h> 17.24 +#include <signal.h> 17.25 +#include <conio.h> 17.26 +#include "vga.h" 17.27 +#include "mingl.h" 17.28 +#include "timer.h" 17.29 +#include "mouse.h" 17.30 + 17.31 +#define ROFFS 64 17.32 +#define GOFFS 128 17.33 +#define BOFFS 192 17.34 + 17.35 +static int init(void); 17.36 +static void shutdown(void); 17.37 +static void redraw(void); 17.38 +static void draw_cursor(unsigned char *fb, int xsz, int ysz, int mx, int my, int cidx); 17.39 +static int keyb(char key); 17.40 +static void mouse_button(int bn, int x, int y); 17.41 +static void mouse_motion(int x, int y); 17.42 +static void sighandler(int s); 17.43 +static int parse_args(int argc, char **argv); 17.44 +static void print_perf(void); 17.45 + 17.46 +static unsigned char *fbuf; 17.47 + 17.48 +static int use_vsync = 1; 17.49 +static int under_windows = 0; 17.50 +static unsigned long num_frm; 17.51 + 17.52 +enum { CUBE, SPHERE, TORUS, NUM_PRIMS }; 17.53 +static int prim = SPHERE; 17.54 +static int auto_rotate = 1; 17.55 +static float cam_theta, cam_phi; 17.56 + 17.57 +static int mx, my; 17.58 + 17.59 +int main(int argc, char **argv) 17.60 +{ 17.61 + int mbn, prev_mx = -1, prev_my = -1, prev_mbn = 0; 17.62 + 17.63 + if(parse_args(argc, argv) == -1) { 17.64 + return 1; 17.65 + } 17.66 + 17.67 + if(init() == -1) { 17.68 + return 1; 17.69 + } 17.70 + 17.71 + reset_timer(); 17.72 + 17.73 + for(;;) { 17.74 + if(kbhit()) { 17.75 + if(keyb(getch()) == 0) { 17.76 + break; 17.77 + } 17.78 + } 17.79 + 17.80 + mbn = read_mouse(&mx, &my); 17.81 + if(mbn != prev_mbn) { 17.82 + mouse_button(mbn, mx, my); 17.83 + prev_mbn = mbn; 17.84 + } 17.85 + if(mx != prev_mx || my != prev_my) { 17.86 + if(mbn) { 17.87 + mouse_motion(mx, my); 17.88 + } 17.89 + prev_mx = mx; 17.90 + prev_my = my; 17.91 + } 17.92 + 17.93 + redraw(); 17.94 + } 17.95 + 17.96 + shutdown(); 17.97 + print_perf(); 17.98 + return 0; 17.99 +} 17.100 + 17.101 +static int init(void) 17.102 +{ 17.103 + int i; 17.104 + 17.105 + init_timer(under_windows ? 0 : 100); 17.106 + 17.107 + set_video_mode(0x13); 17.108 + 17.109 + signal(SIGINT, sighandler); 17.110 + signal(SIGSEGV, sighandler); 17.111 + signal(SIGFPE, sighandler); 17.112 + signal(SIGILL, sighandler); 17.113 + signal(SIGABRT, sighandler); 17.114 + 17.115 + for(i=0; i<64; i++) { 17.116 + int x = i << 2; 17.117 + set_palette(i, x, x, x); 17.118 + set_palette(i + ROFFS, x, 0, 0); 17.119 + set_palette(i + GOFFS, 0, x, 0); 17.120 + set_palette(i + BOFFS, 0, 0, x); 17.121 + } 17.122 + 17.123 + if(mgl_init(320, 200) == -1) { 17.124 + fprintf(stderr, "mgl init failed\n"); 17.125 + return -1; 17.126 + } 17.127 + fbuf = mgl_framebuffer(); 17.128 + 17.129 + mgl_enable(MGL_CULL_FACE); 17.130 + mgl_enable(MGL_SMOOTH); 17.131 + mgl_color_range(63); /* gradient range */ 17.132 + 17.133 + mgl_enable(MGL_LIGHTING); 17.134 + mgl_light_intensity(0, 1.0); 17.135 + mgl_light_direction(0, -0.5, 0.5, 1); 17.136 + 17.137 + mgl_matrix_mode(MGL_PROJECTION); 17.138 + mgl_load_identity(); 17.139 + mgl_perspective(45.0, 320.0 / 200.0, 0.5, 100.0); 17.140 + 17.141 + return 0; 17.142 +} 17.143 + 17.144 +static void shutdown(void) 17.145 +{ 17.146 + mgl_free(); 17.147 + set_video_mode(3); 17.148 +} 17.149 + 17.150 +static void redraw(void) 17.151 +{ 17.152 + float angle = get_msec() / 10.0; 17.153 + mgl_clear(0); 17.154 + 17.155 + mgl_matrix_mode(MGL_MODELVIEW); 17.156 + mgl_load_identity(); 17.157 + if(auto_rotate) { 17.158 + mgl_rotate(angle, 0, 0, 1); 17.159 + mgl_rotate(angle * 0.5, 1, 0, 0); 17.160 + } else { 17.161 + mgl_rotate(cam_theta, 0, 1, 0); 17.162 + mgl_rotate(cam_phi, 1, 0, 0); 17.163 + } 17.164 + mgl_translate(0, 0, -4); 17.165 + 17.166 + switch(prim) { 17.167 + case TORUS: 17.168 + mgl_index(GOFFS); 17.169 + mgl_torus(1.0, 0.25, 16, 8); 17.170 + break; 17.171 + case SPHERE: 17.172 + mgl_index(BOFFS); 17.173 + mgl_sphere(1.0, 16, 8); 17.174 + break; 17.175 + case CUBE: 17.176 + mgl_index(ROFFS); 17.177 + mgl_cube(1.0); 17.178 + } 17.179 + 17.180 + /*mgl_begin(MGL_QUADS); 17.181 + mgl_index(ROFFS); 17.182 + mgl_color1f(1.0); 17.183 + mgl_vertex2f(-1, -1); 17.184 + mgl_vertex2f(1, -1); 17.185 + mgl_color1f(0.1); 17.186 + mgl_vertex2f(1, 1); 17.187 + mgl_vertex2f(-1, 1); 17.188 + mgl_end();*/ 17.189 + 17.190 + if(!auto_rotate) { 17.191 + draw_cursor(fbuf, 320, 200, mx, my, 63); 17.192 + } 17.193 + 17.194 + copy_frame(fbuf); 17.195 + if(use_vsync) { 17.196 + wait_vsync(); 17.197 + } 17.198 + num_frm++; 17.199 +} 17.200 + 17.201 +static void draw_cursor(unsigned char *fb, int xsz, int ysz, int mx, int my, int cidx) 17.202 +{ 17.203 + static char img[] = 17.204 + "oo........" 17.205 + "oxo......." 17.206 + "oxxo......" 17.207 + "oxxxo....." 17.208 + "oxxxxo...." 17.209 + "oxxxxxo..." 17.210 + "oxxxxxxo.." 17.211 + "oxxxxxxxo." 17.212 + "oxxxxxxxxo" 17.213 + "oxxxxxoooo" 17.214 + "oxxoxxo..." 17.215 + "oxo.oxxo.." 17.216 + "oo..oxxo.." 17.217 + ".....oxxo." 17.218 + ".....oxxo." 17.219 + "......oo.."; 17.220 + int i, j, w = 10, h = 16; 17.221 + 17.222 + if(mx < 0 || my < 0) { 17.223 + return; 17.224 + } 17.225 + if(mx + w >= xsz) { 17.226 + w = xsz - mx; 17.227 + } 17.228 + if(my + h >= ysz) { 17.229 + h = ysz - my; 17.230 + } 17.231 + 17.232 + fb += my * xsz + mx; 17.233 + for(i=0; i<h; i++) { 17.234 + for(j=0; j<w; j++) { 17.235 + char c = img[(i << 3) + (i << 1) + j]; 17.236 + if(c != '.') { 17.237 + fb[j] = c == 'x' ? 0 : cidx; 17.238 + } 17.239 + } 17.240 + fb += xsz; 17.241 + } 17.242 +} 17.243 + 17.244 +static int keyb(char key) 17.245 +{ 17.246 + switch(key) { 17.247 + case 'q': 17.248 + case 27: 17.249 + return 0; 17.250 + 17.251 + case ' ': 17.252 + auto_rotate = !auto_rotate; 17.253 + break; 17.254 + 17.255 + case 'p': 17.256 + prim = (prim + 1) % NUM_PRIMS; 17.257 + break; 17.258 + 17.259 + default: 17.260 + break; 17.261 + } 17.262 + return 1; 17.263 +} 17.264 + 17.265 +static int bnstate; 17.266 +static int prev_x, prev_y; 17.267 + 17.268 +static void mouse_button(int bn, int x, int y) 17.269 +{ 17.270 + bnstate = bn; 17.271 + prev_x = x; 17.272 + prev_y = y; 17.273 +} 17.274 + 17.275 +static void mouse_motion(int x, int y) 17.276 +{ 17.277 + int dx, dy; 17.278 + 17.279 + dx = x - prev_x; 17.280 + dy = y - prev_y; 17.281 + prev_x = x; 17.282 + prev_y = y; 17.283 + 17.284 + if(bnstate) { 17.285 + cam_theta += dx; 17.286 + cam_phi += dy; 17.287 + 17.288 + if(cam_phi > 90) cam_phi = 90; 17.289 + if(cam_phi < -90) cam_phi = -90; 17.290 + } 17.291 +} 17.292 + 17.293 +static void sighandler(int s) 17.294 +{ 17.295 + set_video_mode(3); 17.296 + 17.297 + switch(s) { 17.298 + case SIGABRT: 17.299 + fprintf(stderr, "abort\n"); 17.300 + break; 17.301 + 17.302 + case SIGILL: 17.303 + fprintf(stderr, "illegal operation\n"); 17.304 + break; 17.305 + 17.306 + case SIGSEGV: 17.307 + fprintf(stderr, "segmentation fault\n"); 17.308 + break; 17.309 + 17.310 + case SIGINT: 17.311 + fprintf(stderr, "interrupted\n"); 17.312 + break; 17.313 + 17.314 + case SIGFPE: 17.315 + fprintf(stderr, "floating point exception\n"); 17.316 + break; 17.317 + 17.318 + default: 17.319 + fprintf(stderr, "unexpected signal\n"); 17.320 + } 17.321 + 17.322 + exit(1); 17.323 +} 17.324 + 17.325 +static int parse_args(int argc, char **argv) 17.326 +{ 17.327 + int i; 17.328 + 17.329 + for(i=1; i<argc; i++) { 17.330 + if(argv[i][0] == '-') { 17.331 + if(argv[i][2] != 0) { 17.332 + goto invalid; 17.333 + } 17.334 + switch(argv[i][1]) { 17.335 + case 'a': 17.336 + auto_rotate = !auto_rotate; 17.337 + break; 17.338 + 17.339 + case 'v': 17.340 + use_vsync = !use_vsync; 17.341 + break; 17.342 + 17.343 + case 'p': 17.344 + if(strcmp(argv[++i], "cube") == 0) { 17.345 + prim = CUBE; 17.346 + } else if(strcmp(argv[i], "sphere") == 0) { 17.347 + prim = SPHERE; 17.348 + } else if(strcmp(argv[i], "torus") == 0) { 17.349 + prim = TORUS; 17.350 + } else { 17.351 + goto invalid; 17.352 + } 17.353 + break; 17.354 + 17.355 + case 'w': 17.356 + under_windows = 1; 17.357 + break; 17.358 + 17.359 + case 'h': 17.360 + printf("Usage %s [options]\n", argv[0]); 17.361 + printf("options:\n"); 17.362 + printf(" -p select one of (cube|sphere|torus)\n"); 17.363 + printf(" -v use vsync\n"); 17.364 + printf(" -w run under windows\n"); 17.365 + printf(" -h print usage information and exit\n"); 17.366 + exit(0); 17.367 + 17.368 + default: 17.369 + goto invalid; 17.370 + } 17.371 + } else { 17.372 + goto invalid; 17.373 + } 17.374 + } 17.375 + 17.376 + return 0; 17.377 + 17.378 +invalid: 17.379 + fprintf(stderr, "invalid argument: %s\n", argv[i]); 17.380 + return -1; 17.381 +} 17.382 + 17.383 + 17.384 +static void print_perf(void) 17.385 +{ 17.386 + unsigned long msec, avg_frame_time; 17.387 + float sec, fps; 17.388 + 17.389 + msec = get_msec(); 17.390 + if(!num_frm || msec < 1000) { 17.391 + printf("leaving so soon? (%lu ms)\n", msec); 17.392 + return; 17.393 + } 17.394 + 17.395 + sec = msec / 1000.0f; 17.396 + fps = (float)num_frm / sec; 17.397 + avg_frame_time = msec / num_frm; 17.398 + 17.399 + printf("%lu frames in %.2f seconds\n", num_frm, sec); 17.400 + printf(" avg. frame time: %lu ms\n", avg_frame_time); 17.401 + printf(" avg. framerate: %.2f fps\n", fps); 17.402 +}
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 18.2 +++ b/src/timer.c Mon Nov 21 06:14:01 2011 +0200 18.3 @@ -0,0 +1,127 @@ 18.4 +/* 18.5 +256-color 3D graphics hack for real-mode DOS. 18.6 +Copyright (C) 2011 John Tsiombikas <nuclear@member.fsf.org> 18.7 + 18.8 +This program is free software: you can redistribute it and/or modify 18.9 +it under the terms of the GNU General Public License as published by 18.10 +the Free Software Foundation, either version 3 of the License, or 18.11 +(at your option) any later version. 18.12 + 18.13 +This program is distributed in the hope that it will be useful, 18.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 18.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18.16 +GNU General Public License for more details. 18.17 + 18.18 +You should have received a copy of the GNU General Public License 18.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 18.20 +*/ 18.21 +#include <stdio.h> 18.22 +#include <stdlib.h> 18.23 +#include <dos.h> 18.24 +#include "pit8254.h" 18.25 + 18.26 +#define PIT_TIMER_INTR 8 18.27 +#define DOS_TIMER_INTR 0x1c 18.28 + 18.29 +/* macro to divide and round to the nearest integer */ 18.30 +#define DIV_ROUND(a, b) \ 18.31 + ((a) / (b) + ((a) % (b)) / ((b) / 2)) 18.32 + 18.33 +static void set_timer_reload(int reload_val); 18.34 +static void cleanup(void); 18.35 +static void interrupt dos_timer_intr(); 18.36 +static void interrupt timer_irq(); 18.37 +static void interrupt (*prev_timer_intr)(); 18.38 + 18.39 +static unsigned long ticks; 18.40 +static unsigned long tick_interval, ticks_per_dos_intr; 18.41 +static int inum; 18.42 + 18.43 +void init_timer(int res_hz) 18.44 +{ 18.45 + 18.46 + disable(); 18.47 + if(res_hz > 0) { 18.48 + int reload_val = DIV_ROUND(OSC_FREQ_HZ, res_hz); 18.49 + set_timer_reload(reload_val); 18.50 + 18.51 + tick_interval = DIV_ROUND(1000, res_hz); 18.52 + ticks_per_dos_intr = DIV_ROUND(65535L, reload_val); 18.53 + 18.54 + inum = PIT_TIMER_INTR; 18.55 + prev_timer_intr = getvect(inum); 18.56 + setvect(inum, timer_irq); 18.57 + } else { 18.58 + tick_interval = 55; 18.59 + 18.60 + inum = DOS_TIMER_INTR; 18.61 + prev_timer_intr = getvect(inum); 18.62 + setvect(inum, dos_timer_intr); 18.63 + } 18.64 + enable(); 18.65 + 18.66 + atexit(cleanup); 18.67 +} 18.68 + 18.69 +static void cleanup(void) 18.70 +{ 18.71 + if(!prev_timer_intr) { 18.72 + return; /* init hasn't ran, there's nothing to cleanup */ 18.73 + } 18.74 + 18.75 + disable(); 18.76 + if(inum == PIT_TIMER_INTR) { 18.77 + /* restore the original timer frequency */ 18.78 + set_timer_reload(65535); 18.79 + } 18.80 + 18.81 + /* restore the original interrupt handler */ 18.82 + setvect(inum, prev_timer_intr); 18.83 + enable(); 18.84 +} 18.85 + 18.86 +void reset_timer(void) 18.87 +{ 18.88 + ticks = 0; 18.89 +} 18.90 + 18.91 +unsigned long get_msec(void) 18.92 +{ 18.93 + return ticks * tick_interval; 18.94 +} 18.95 + 18.96 +static void set_timer_reload(int reload_val) 18.97 +{ 18.98 + outportb(PORT_CMD, CMD_CHAN0 | CMD_ACCESS_BOTH | CMD_OP_SQWAVE); 18.99 + outportb(PORT_DATA0, reload_val & 0xff); 18.100 + outportb(PORT_DATA0, (reload_val >> 8) & 0xff); 18.101 +} 18.102 + 18.103 +static void interrupt dos_timer_intr() 18.104 +{ 18.105 + ticks++; 18.106 + prev_timer_intr(); 18.107 +} 18.108 + 18.109 +/* first PIC command port */ 18.110 +#define PIC1_CMD 0x20 18.111 +/* end of interrupt control word */ 18.112 +#define OCW2_EOI (1 << 5) 18.113 + 18.114 +static void interrupt timer_irq() 18.115 +{ 18.116 + static unsigned long dos_ticks; 18.117 + 18.118 + ticks++; 18.119 + 18.120 + if(++dos_ticks >= ticks_per_dos_intr) { 18.121 + /* I suppose the dos irq handler does the EOI so I shouldn't 18.122 + * do it if I am to call the previous function 18.123 + */ 18.124 + prev_timer_intr(); 18.125 + dos_ticks = 0; 18.126 + } else { 18.127 + /* send EOI to the PIC */ 18.128 + outportb(PIC1_CMD, OCW2_EOI); 18.129 + } 18.130 +}
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 19.2 +++ b/src/timer.h Mon Nov 21 06:14:01 2011 +0200 19.3 @@ -0,0 +1,29 @@ 19.4 +/* 19.5 +256-color 3D graphics hack for real-mode DOS. 19.6 +Copyright (C) 2011 John Tsiombikas <nuclear@member.fsf.org> 19.7 + 19.8 +This program is free software: you can redistribute it and/or modify 19.9 +it under the terms of the GNU General Public License as published by 19.10 +the Free Software Foundation, either version 3 of the License, or 19.11 +(at your option) any later version. 19.12 + 19.13 +This program is distributed in the hope that it will be useful, 19.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 19.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19.16 +GNU General Public License for more details. 19.17 + 19.18 +You should have received a copy of the GNU General Public License 19.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 19.20 +*/ 19.21 +#ifndef TIMER_H_ 19.22 +#define TIMER_H_ 19.23 + 19.24 +/* expects the required timer resolution in hertz 19.25 + * if res_hz is 0, the current resolution is retained 19.26 + */ 19.27 +void init_timer(int res_hz); 19.28 + 19.29 +void reset_timer(void); 19.30 +unsigned long get_msec(void); 19.31 + 19.32 +#endif /* TIMER_H_ */
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 20.2 +++ b/src/vga.c Mon Nov 21 06:14:01 2011 +0200 20.3 @@ -0,0 +1,68 @@ 20.4 +/* 20.5 +256-color 3D graphics hack for real-mode DOS. 20.6 +Copyright (C) 2011 John Tsiombikas <nuclear@member.fsf.org> 20.7 + 20.8 +This program is free software: you can redistribute it and/or modify 20.9 +it under the terms of the GNU General Public License as published by 20.10 +the Free Software Foundation, either version 3 of the License, or 20.11 +(at your option) any later version. 20.12 + 20.13 +This program is distributed in the hope that it will be useful, 20.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 20.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20.16 +GNU General Public License for more details. 20.17 + 20.18 +You should have received a copy of the GNU General Public License 20.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 20.20 +*/ 20.21 +#include <dos.h> 20.22 +#include <string.h> 20.23 + 20.24 +void set_video_mode(int mode) 20.25 +{ 20.26 + asm { 20.27 + mov ax, mode 20.28 + int 0x10 20.29 + } 20.30 +} 20.31 + 20.32 +void set_palette(unsigned char c, unsigned char r, unsigned char g, unsigned char b) 20.33 +{ 20.34 + asm { 20.35 + mov dx, 0x3c8 20.36 + mov al, c 20.37 + out dx, al 20.38 + inc dx 20.39 + mov al, r 20.40 + shr al, 2 20.41 + out dx, al 20.42 + mov al, g 20.43 + shr al, 2 20.44 + out dx, al 20.45 + mov al, b 20.46 + shr al, 2 20.47 + out dx, al 20.48 + } 20.49 +} 20.50 + 20.51 +void copy_frame(unsigned char *frame) 20.52 +{ 20.53 + _fmemcpy(MK_FP(0xa000, 0), frame, 64000); 20.54 +} 20.55 + 20.56 +void wait_vsync(void) 20.57 +{ 20.58 + asm mov dx, 0x3da 20.59 +l1: 20.60 + asm { 20.61 + in al, dx 20.62 + and al, 0x8 20.63 + jnz l1 20.64 + } 20.65 +l2: 20.66 + asm { 20.67 + in al, dx 20.68 + and al, 0x8 20.69 + jz l2 20.70 + } 20.71 +}
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 21.2 +++ b/src/vga.h Mon Nov 21 06:14:01 2011 +0200 21.3 @@ -0,0 +1,26 @@ 21.4 +/* 21.5 +256-color 3D graphics hack for real-mode DOS. 21.6 +Copyright (C) 2011 John Tsiombikas <nuclear@member.fsf.org> 21.7 + 21.8 +This program is free software: you can redistribute it and/or modify 21.9 +it under the terms of the GNU General Public License as published by 21.10 +the Free Software Foundation, either version 3 of the License, or 21.11 +(at your option) any later version. 21.12 + 21.13 +This program is distributed in the hope that it will be useful, 21.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 21.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21.16 +GNU General Public License for more details. 21.17 + 21.18 +You should have received a copy of the GNU General Public License 21.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 21.20 +*/ 21.21 +#ifndef VGA_H_ 21.22 +#define VGA_H_ 21.23 + 21.24 +void set_video_mode(int mode); 21.25 +void set_palette(unsigned char c, unsigned char r, unsigned char g, unsigned char b); 21.26 +void copy_frame(unsigned char *frame); 21.27 +void wait_vsync(void); 21.28 + 21.29 +#endif /* VGA_H_ */