From 49df16bc7fa6a693da8ccc575d382dbb952e8f4a Mon Sep 17 00:00:00 2001 From: admin Date: Sat, 19 Nov 2011 19:09:07 +0000 Subject: [PATCH] DXGL 0.0.6: New faster surface locking engine Fix distortion in non-multiple-of-8 video modes Add LGPL license file Fix configuration loading for DirectDrawCreateEx() Add DDRAW caps bits Add IDirectDraw::GetDisplayMode() Add IDirectDraw::RestoreDisplayMode() Start creating NSIS installer Various minor fixes git-svn-id: https://www.williamfeely.info/svn/dxgl@6 8a90861a-4eca-46d5-b744-240ff16d0c4d --- COPYING.txt | 502 ++++++++++++++++++++++++++++++++++ Installer/dxgl.nsi | 112 ++++++++ ReadMe.txt | 33 ++- ddraw/ddraw.cpp | 1 + ddraw/ddraw.rc | 8 +- ddraw/ddraw.vcxproj | 2 + ddraw/ddraw.vcxproj.filters | 6 + ddraw/glDirectDraw.cpp | 227 +++++++++++++-- ddraw/glDirectDraw.h | 2 +- ddraw/glDirectDrawSurface.cpp | 319 ++++++++++----------- ddraw/glDirectDrawSurface.h | 16 +- ddraw/scalers.cpp | 105 +++++++ ddraw/scalers.h | 28 ++ dxglcfg/dxglcfg.rc | 8 +- dxgltest/Tests2D.cpp | 4 +- dxgltest/dxgltest.cpp | 1 + dxgltest/dxgltest.rc | 8 +- 17 files changed, 1170 insertions(+), 212 deletions(-) create mode 100644 COPYING.txt create mode 100644 Installer/dxgl.nsi create mode 100644 ddraw/scalers.cpp create mode 100644 ddraw/scalers.h diff --git a/COPYING.txt b/COPYING.txt new file mode 100644 index 00000000..4362b491 --- /dev/null +++ b/COPYING.txt @@ -0,0 +1,502 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/Installer/dxgl.nsi b/Installer/dxgl.nsi new file mode 100644 index 00000000..29291487 --- /dev/null +++ b/Installer/dxgl.nsi @@ -0,0 +1,112 @@ +; Script generated by the HM NIS Edit Script Wizard. + +SetCompressor /SOLID lzma + +; HM NIS Edit Wizard helper defines +!define PRODUCT_NAME "DXGL" +!define PRODUCT_VERSION "0.0.6" +!define PRODUCT_PUBLISHER "William Feely" +!define PRODUCT_WEB_SITE "https://www.williamfeely.info/wiki/DXGL" +!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\dxglcfg.exe" +!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" +!define PRODUCT_UNINST_ROOT_KEY "HKLM" + +; MUI2 +!include "MUI2.nsh" + +; MUI Settings +!define MUI_ABORTWARNING +!define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\modern-install.ico" +!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico" + +; Welcome page +!insertmacro MUI_PAGE_WELCOME +; License page +!insertmacro MUI_PAGE_LICENSE "..\COPYING.txt" +; Directory page +!insertmacro MUI_PAGE_DIRECTORY +; Instfiles page +!insertmacro MUI_PAGE_INSTFILES +; Finish page +!define MUI_FINISHPAGE_RUN "$INSTDIR\dxglcfg.exe" +!define MUI_FINISHPAGE_RUN_TEXT "Configure DXGL" +!define MUI_FINISHPAGE_SHOWREADME "$INSTDIR\ReadMe.txt" +!insertmacro MUI_PAGE_FINISH + +; Uninstaller pages +!insertmacro MUI_UNPAGE_INSTFILES + +; Language files +!insertmacro MUI_LANGUAGE "English" + +; MUI end ------ + +Name "${PRODUCT_NAME} ${PRODUCT_VERSION}" +OutFile "DXGL-0.0.6-win32.exe" +InstallDir "$PROGRAMFILES\DXGL" +InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" "" +ShowInstDetails show +ShowUnInstDetails show + +Section "MainSection" SEC01 + SetOutPath "$INSTDIR" + SetOverwrite ifnewer + File "..\Release\dxgltest.exe" + CreateDirectory "$SMPROGRAMS\DXGL" + CreateShortCut "$SMPROGRAMS\DXGL\DXGL Test.lnk" "$INSTDIR\dxgltest.exe" + File "..\Release\dxglcfg.exe" + CreateShortCut "$SMPROGRAMS\DXGL\Configure DXGL.lnk" "$INSTDIR\dxglcfg.exe" + File "..\Release\ddraw.dll" + File "..\ReadMe.txt" + File "..\COPYING.txt" +SectionEnd + +Section -AdditionalIcons + WriteIniStr "$INSTDIR\${PRODUCT_NAME}.url" "InternetShortcut" "URL" "${PRODUCT_WEB_SITE}" + CreateShortCut "$SMPROGRAMS\DXGL\Website.lnk" "$INSTDIR\${PRODUCT_NAME}.url" + CreateShortCut "$SMPROGRAMS\DXGL\Uninstall.lnk" "$INSTDIR\uninst.exe" +SectionEnd + +Section -Post + WriteUninstaller "$INSTDIR\uninst.exe" + WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\dxglcfg.exe" + WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)" + WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninst.exe" + WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\dxglcfg.exe" + WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}" + WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}" + WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}" +SectionEnd + + +Function un.onUninstSuccess + HideWindow + MessageBox MB_ICONINFORMATION|MB_OK "$(^Name) was successfully removed from your computer." +FunctionEnd + +Function un.onInit + MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "Are you sure you want to completely remove $(^Name) and all of its components?" IDYES +2 + Abort +FunctionEnd + +Section Uninstall + Delete "$INSTDIR\${PRODUCT_NAME}.url" + Delete "$INSTDIR\uninst.exe" + Delete "$INSTDIR\COPYING.txt" + Delete "$INSTDIR\ReadMe.txt" + Delete "$INSTDIR\ddraw.dll" + Delete "$INSTDIR\dxglcfg.exe" + Delete "$INSTDIR\dxgltest.exe" + + Delete "$SMPROGRAMS\DXGL\Uninstall.lnk" + Delete "$SMPROGRAMS\DXGL\Website.lnk" + Delete "$SMPROGRAMS\DXGL\Configure DXGL.lnk" + Delete "$SMPROGRAMS\DXGL\DXGL Test.lnk" + + RMDir "$SMPROGRAMS\DXGL" + RMDir "$INSTDIR" + + DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" + DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY}" + SetAutoClose true +SectionEnd \ No newline at end of file diff --git a/ReadMe.txt b/ReadMe.txt index 28c4e16e..1c600ebb 100644 --- a/ReadMe.txt +++ b/ReadMe.txt @@ -7,7 +7,8 @@ DXGL is currently in a pre-alpha stage and very little works at this point. == System Requirements == * Windows operating system (currently XP or above) -* OpenGL 2.0 or higher compatible video card, with hardware accelerated non-power-of-two size textures +* OpenGL 2.0 or higher compatible video card, with hardware accelerated non-power-of-two size textures. + Geforce FX series graphics cards are NOT supported because non-power-of-two textures are emulated in software. == Build Requirements == * Visual Studio 2010 or Visual C++ 2010 Express @@ -24,27 +25,30 @@ http://www.microsoft.com/downloads/en/details.aspx?FamilyID=689655B4-C55D-4F9B-9 == Progress == What works: -* DirectDraw object creation and destruction +* DirectDraw object creation and destruction (versions 1 to 7) * Display mode enumeration and switching (with emulated mode switching) * Fullscreen and windowed modes. * Basic Blt() functionality +* 8-bit color What partially works: -* SetCooperativeLevel (not always on top for debugging purposes.) -* 8-bit color +* SetCooperativeLevel (destroys the GL context if switching between windowed and fullscreen modes) What doesn't work: * Most functions are stubbed out and return an error * No 3D graphics support +* Blt() may cause crashing == Roadmap == These are goals to be set for future releases. +Please see https://www.williamfeely.info/wiki/DXGL for updated information. -- Version 0.0.6 Pre-Alpha -* Fix distortion on non-multiple-of-8 width physical modes -* Improve surface locking and unlocking -* Start making DirectDraw programs run -* Start an AppDB for compatible programs +- Version 0.0.7 Pre-Alpha +* Fix blitting in fullscreen. + +- Version 0.1.0 Alpha +* Implement per-application settings +* Create installer == Installation == @@ -58,7 +62,16 @@ SVN readonly access is available at: https://www.williamfeely.info/svn/dxgl There is a Mediawiki-based SVN log at: -http://www.williamfeely.info/wiki/Special:Code/DXGL +https://www.williamfeely.info/wiki/Special:Code/DXGL + +== AppDB == + +An AppDB system (similar to that on winehq.org) is now available at: + +https://www.williamfeely.info/appdb/ + +This requires a user account separate from the other services. + == Bug reports == diff --git a/ddraw/ddraw.cpp b/ddraw/ddraw.cpp index 75b96692..a1810cb8 100644 --- a/ddraw/ddraw.cpp +++ b/ddraw/ddraw.cpp @@ -98,6 +98,7 @@ HRESULT WINAPI DirectDrawCreateClipper(DWORD dwFlags, LPDIRECTDRAWCLIPPER FAR *l } HRESULT WINAPI DirectDrawCreateEx(GUID FAR *lpGUID, LPVOID *lplpDD, REFIID iid, IUnknown FAR *pUnkOuter) { + GetCurrentConfig(&dxglcfg); glDirectDraw7 *myddraw; HRESULT error; if(iid != IID_IDirectDraw7) return DDERR_UNSUPPORTED; diff --git a/ddraw/ddraw.rc b/ddraw/ddraw.rc index 4e91792b..13f260ca 100644 --- a/ddraw/ddraw.rc +++ b/ddraw/ddraw.rc @@ -36,8 +36,8 @@ IDI_ICON1 ICON "..\\common\\dxgl.ico" // LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL 1 VERSIONINFO - FILEVERSION 0,0,5,0 - PRODUCTVERSION 0,0,5,0 + FILEVERSION 0,0,6,0 + PRODUCTVERSION 0,0,6,0 FILEOS VOS__WINDOWS32 FILETYPE VFT_DLL FILESUBTYPE VFT2_UNKNOWN @@ -50,12 +50,12 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL { VALUE "CompanyName", "William Feely" VALUE "FileDescription", "DXGL DDraw Library" - VALUE "FileVersion", "0.0.5.0" + VALUE "FileVersion", "0.0.6.0" VALUE "InternalName", "DXGL" VALUE "LegalCopyright", "Copyright (C) 2011 William Feely" VALUE "OriginalFilename", "DDraw.dll" VALUE "ProductName", "DXGL" - VALUE "ProductVersion", "0.0.5.0" + VALUE "ProductVersion", "0.0.6.0" } } BLOCK "VarFileInfo" diff --git a/ddraw/ddraw.vcxproj b/ddraw/ddraw.vcxproj index 146fe902..c19a11b7 100644 --- a/ddraw/ddraw.vcxproj +++ b/ddraw/ddraw.vcxproj @@ -172,6 +172,7 @@ + @@ -207,6 +208,7 @@ Create Create + diff --git a/ddraw/ddraw.vcxproj.filters b/ddraw/ddraw.vcxproj.filters index 0ddef69f..48de195e 100644 --- a/ddraw/ddraw.vcxproj.filters +++ b/ddraw/ddraw.vcxproj.filters @@ -68,6 +68,9 @@ Header Files\include\GL + + Header Files + @@ -100,6 +103,9 @@ Source Files + + Source Files + diff --git a/ddraw/glDirectDraw.cpp b/ddraw/glDirectDraw.cpp index ed2e8658..29064f2d 100644 --- a/ddraw/glDirectDraw.cpp +++ b/ddraw/glDirectDraw.cpp @@ -26,6 +26,7 @@ bool directdraw_created = false; // emulate only one ddraw device bool wndclasscreated = false; + void DiscardDuplicateModes(DEVMODE **array, DWORD *count) { DEVMODE *newarray = (DEVMODE *)malloc(sizeof(DEVMODE)*(*count)); @@ -401,6 +402,116 @@ HRESULT EnumDisplayModes(DWORD dwFlags, LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID free(modes); return DD_OK; } +HRESULT EnumDisplayModes(DWORD dwFlags, LPDDSURFACEDESC2 lpDDSurfaceDesc, LPVOID lpContext, LPDDENUMMODESCALLBACK2 lpEnumModesCallback) +{ + bool match; + DWORD modenum = 0; + DWORD modemax = 128; + DEVMODE mode; + ZeroMemory(&mode,sizeof(DEVMODE)); + mode.dmSize = sizeof(DEVMODE); + DEVMODE *modes = (DEVMODE*)malloc(128*sizeof(DEVMODE)); + DEVMODE *tmp; + if(!modes) return DDERR_OUTOFMEMORY; + DDSURFACEDESC2 ddmode; + ZeroMemory(&ddmode,sizeof(DDSURFACEDESC)); + ddmode.dwSize = sizeof(DDSURFACEDESC); + ddmode.dwFlags = DDSD_HEIGHT | DDSD_WIDTH | DDSD_PITCH | DDSD_PIXELFORMAT | DDSD_REFRESHRATE; + while(EnumDisplaySettings(NULL,modenum++,&mode)) + { + modes[modenum-1] = mode; + if(modenum >= modemax) + { + modemax += 128; + tmp = (DEVMODE*)realloc(modes,modemax*sizeof(DEVMODE)); + if(tmp == NULL) + { + free(modes); + return DDERR_OUTOFMEMORY; + } + modes = tmp; + } + } + DiscardDuplicateModes(&modes,&modenum); + if(dxglcfg.AllColorDepths) AddExtraColorModes(&modes,&modenum); + if(dxglcfg.ExtraModes && (dxglcfg.scaler != 0)) AddExtraResolutions(&modes,&modenum); + modenum--; + switch(dxglcfg.SortModes) + { + case 0: + default: + break; + case 1: + qsort(modes,modenum,sizeof(DEVMODE),(int(*)(const void*, const void*))SortDepth); + break; + case 2: + qsort(modes,modenum,sizeof(DEVMODE),(int(*)(const void*, const void*))SortRes); + break; + } + for(DWORD i = 0; i < modenum; i++) + { + match = true; + if(dwFlags & DDEDM_REFRESHRATES) ddmode.dwRefreshRate = modes[i].dmDisplayFrequency; + else + { + ddmode.dwRefreshRate = 0; + for(DWORD x = 0; x < i; x++) + if((modes[x].dmBitsPerPel == modes[i].dmBitsPerPel) && + (modes[x].dmPelsWidth == modes[i].dmPelsWidth) && + (modes[x].dmPelsHeight == modes[i].dmPelsHeight)) match = false; + } + if(lpDDSurfaceDesc) + { + if(lpDDSurfaceDesc->dwFlags & DDSD_WIDTH) + if(lpDDSurfaceDesc->dwWidth != modes[i].dmPelsWidth) match = false; + if(lpDDSurfaceDesc->dwFlags & DDSD_HEIGHT) + if(lpDDSurfaceDesc->dwHeight != modes[i].dmPelsHeight) match = false; + if(lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT) + if(lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount != modes[i].dmBitsPerPel) match = false; + if(lpDDSurfaceDesc->dwFlags & DDSD_REFRESHRATE) + if(lpDDSurfaceDesc->dwRefreshRate != modes[i].dmDisplayFrequency) match = false; + } + if(match) + { + if(modes[i].dmBitsPerPel == 8) ddmode.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8; + else if(modes[i].dmBitsPerPel == 4) ddmode.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED4; + else ddmode.ddpfPixelFormat.dwFlags = DDPF_RGB; + if(modes[i].dmBitsPerPel == 8) + { + ddmode.ddpfPixelFormat.dwRBitMask = 0; + ddmode.ddpfPixelFormat.dwGBitMask = 0; + ddmode.ddpfPixelFormat.dwBBitMask = 0; + } + else if(modes[i].dmBitsPerPel == 15) + { + ddmode.ddpfPixelFormat.dwRBitMask = 0x7C00; + ddmode.ddpfPixelFormat.dwGBitMask = 0x3E0; + ddmode.ddpfPixelFormat.dwRBitMask = 0x1F; + } + else if(modes[i].dmBitsPerPel == 16) + { + ddmode.ddpfPixelFormat.dwRBitMask = 0xF800; + ddmode.ddpfPixelFormat.dwGBitMask = 0x7E0; + ddmode.ddpfPixelFormat.dwBBitMask = 0x1F; + } + else + { + ddmode.ddpfPixelFormat.dwRBitMask = 0xFF0000; + ddmode.ddpfPixelFormat.dwRBitMask = 0xFF00; + ddmode.ddpfPixelFormat.dwRBitMask = 0xFF; + } + ddmode.ddpfPixelFormat.dwRGBBitCount = modes[i].dmBitsPerPel; + ddmode.dwWidth = modes[i].dmPelsWidth; + ddmode.dwHeight = modes[i].dmPelsHeight; + if(modes[i].dmBitsPerPel == 15) ddmode.lPitch = modes[i].dmPelsWidth * 2; + else if(modes[i].dmBitsPerPel == 4) ddmode.lPitch = modes[i].dmPelsWidth / 2; + else ddmode.lPitch = modes[i].dmPelsWidth * (modes[i].dmBitsPerPel / 8); + if(lpEnumModesCallback(&ddmode,lpContext) == DDENUMRET_CANCEL) return DD_OK; + } + } + free(modes); + return DD_OK; +} // DDRAW7/common routines glDirectDraw7::glDirectDraw7(GUID FAR* lpGUID, LPDIRECTDRAW FAR* lplpDD, IUnknown FAR* pUnkOuter) @@ -414,6 +525,7 @@ glDirectDraw7::glDirectDraw7(GUID FAR* lpGUID, LPDIRECTDRAW FAR* lplpDD, IUnknow fpusetup = false; threadsafe = false; nowindowchanges = false; + ZeroMemory(&oldmode,sizeof(DEVMODE)); surfaces = (glDirectDrawSurface7 **)malloc(1024*sizeof(glDirectDrawSurface7 *)); if(!surfaces) { @@ -602,8 +714,7 @@ HRESULT WINAPI glDirectDraw7::DuplicateSurface(LPDIRECTDRAWSURFACE7 lpDDSurface, } HRESULT WINAPI glDirectDraw7::EnumDisplayModes(DWORD dwFlags, LPDDSURFACEDESC2 lpDDSurfaceDesc2, LPVOID lpContext, LPDDENUMMODESCALLBACK2 lpEnumModesCallback) { - FIXME("IDirectDraw::EnumDisplayModes: stub\n"); - return DDERR_GENERIC; + return ::EnumDisplayModes(dwFlags,lpDDSurfaceDesc2,lpContext,lpEnumModesCallback); } HRESULT WINAPI glDirectDraw7::EnumSurfaces(DWORD dwFlags, LPDDSURFACEDESC2 lpDDSD2, LPVOID lpContext, LPDDENUMSURFACESCALLBACK7 lpEnumSurfacesCallback) { @@ -612,25 +723,89 @@ HRESULT WINAPI glDirectDraw7::EnumSurfaces(DWORD dwFlags, LPDDSURFACEDESC2 lpDDS } HRESULT WINAPI glDirectDraw7::FlipToGDISurface() { - FIXME("IDirectDraw::FlipToGDISurface: stub\n"); - return DDERR_GENERIC; + HRESULT error = DD_OK; + if(primary) + { + if(primary->flipcount) + { + while(primary->flipcount != 0) + { + error = primary->Flip(NULL,DDFLIP_WAIT); + if(error != DD_OK) break; + } + } + return(error); + } + else return DDERR_NOTFOUND; } HRESULT WINAPI glDirectDraw7::GetCaps(LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELCaps) { - FIXME("IDirectDraw::GetCaps: Fill in as implemented.\n"); + //TODO: Fill in as implemented. DDCAPS_DX7 ddCaps; ZeroMemory(&ddCaps,sizeof(DDCAPS_DX7)); - ddCaps.dwSize = sizeof(DDCAPS_DX7); - ddCaps.dwCaps = 0; // FIXME: Fill in capabilities - ddCaps.dwCaps2 = 0; - memcpy(lpDDDriverCaps,&ddCaps,sizeof(DDCAPS_DX7)); - memcpy(lpDDHELCaps,&ddCaps,sizeof(DDCAPS_DX7)); + if(lpDDDriverCaps) ddCaps.dwSize = lpDDDriverCaps->dwSize; + else if(lpDDHELCaps) ddCaps.dwSize = lpDDHELCaps->dwSize; + else return DDERR_INVALIDPARAMS; + ddCaps.dwCaps = DDCAPS_BLT | DDCAPS_BLTCOLORFILL | DDCAPS_BLTSTRETCH | + DDCAPS_GDI | DDCAPS_PALETTE; + ddCaps.dwCaps2 = DDCAPS2_CANRENDERWINDOWED | DDCAPS2_WIDESURFACES; + ddCaps.dwFXCaps = DDFXCAPS_BLTSHRINKX | DDFXCAPS_BLTSHRINKY | + DDFXCAPS_BLTSTRETCHX | DDFXCAPS_BLTSTRETCHY; + ddCaps.dwPalCaps = DDPCAPS_8BIT | DDPCAPS_PRIMARYSURFACE; + ddCaps.ddsOldCaps.dwCaps = ddCaps.ddsCaps.dwCaps = + DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP | DDSCAPS_FRONTBUFFER | + DDSCAPS_OFFSCREENPLAIN | DDSCAPS_PALETTE | DDSCAPS_SYSTEMMEMORY | + DDSCAPS_VIDEOMEMORY; + if(lpDDDriverCaps) memcpy(lpDDDriverCaps,&ddCaps,lpDDDriverCaps->dwSize); + if(lpDDHELCaps) memcpy(lpDDHELCaps,&ddCaps,lpDDHELCaps->dwSize); return DD_OK; } HRESULT WINAPI glDirectDraw7::GetDisplayMode(LPDDSURFACEDESC2 lpDDSurfaceDesc2) { - FIXME("IDirectDraw::GetDisplayMode: stub\n"); - return DDERR_GENERIC; + if(!lpDDSurfaceDesc2) return DDERR_INVALIDPARAMS; + DDSURFACEDESC2 ddsdMode; + ZeroMemory(&ddsdMode, sizeof(DDSURFACEDESC2)); + ddsdMode.dwSize = sizeof(DDSURFACEDESC2); + DEVMODE currmode; + EnumDisplaySettings(NULL,ENUM_CURRENT_SETTINGS,&currmode); + if(currmode.dmBitsPerPel == 8) ddsdMode.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8; + else if(currmode.dmBitsPerPel == 4) ddsdMode.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED4; + else ddsdMode.ddpfPixelFormat.dwFlags = DDPF_RGB; + if(currmode.dmBitsPerPel == 8) + { + ddsdMode.ddpfPixelFormat.dwRBitMask = 0; + ddsdMode.ddpfPixelFormat.dwGBitMask = 0; + ddsdMode.ddpfPixelFormat.dwBBitMask = 0; + } + else if(currmode.dmBitsPerPel == 15) + { + ddsdMode.ddpfPixelFormat.dwRBitMask = 0x7C00; + ddsdMode.ddpfPixelFormat.dwGBitMask = 0x3E0; + ddsdMode.ddpfPixelFormat.dwRBitMask = 0x1F; + } + else if(currmode.dmBitsPerPel == 16) + { + ddsdMode.ddpfPixelFormat.dwRBitMask = 0xF800; + ddsdMode.ddpfPixelFormat.dwGBitMask = 0x7E0; + ddsdMode.ddpfPixelFormat.dwBBitMask = 0x1F; + } + else + { + ddsdMode.ddpfPixelFormat.dwRBitMask = 0xFF0000; + ddsdMode.ddpfPixelFormat.dwRBitMask = 0xFF00; + ddsdMode.ddpfPixelFormat.dwRBitMask = 0xFF; + } + ddsdMode.ddpfPixelFormat.dwRGBBitCount = currmode.dmBitsPerPel; + ddsdMode.dwWidth = currmode.dmPelsWidth; + ddsdMode.dwHeight = currmode.dmPelsHeight; + if(currmode.dmBitsPerPel == 15) ddsdMode.lPitch = currmode.dmPelsWidth * 2; + else if(currmode.dmBitsPerPel == 4) ddsdMode.lPitch = currmode.dmPelsWidth / 2; + else ddsdMode.lPitch = currmode.dmPelsWidth * (currmode.dmBitsPerPel / 8); + if(lpDDSurfaceDesc2->dwSize < sizeof(DDSURFACEDESC)) return DDERR_INVALIDPARAMS; + if(lpDDSurfaceDesc2->dwSize > sizeof(DDSURFACEDESC2)) + lpDDSurfaceDesc2->dwSize = sizeof(DDSURFACEDESC2); + memcpy(lpDDSurfaceDesc2,&ddsdMode,lpDDSurfaceDesc2->dwSize); + return DD_OK; } HRESULT WINAPI glDirectDraw7::GetFourCCCodes(LPDWORD lpNumCodes, LPDWORD lpCodes) { @@ -668,8 +843,11 @@ HRESULT WINAPI glDirectDraw7::Initialize(GUID FAR *lpGUID) } HRESULT WINAPI glDirectDraw7::RestoreDisplayMode() { - FIXME("IDirectDraw::RestoreDisplayMode: stub\n"); - return DDERR_GENERIC; + if(oldmode.dmSize != 0) + { + ChangeDisplaySettingsEx(NULL,&oldmode,NULL,0,NULL); + } + return DD_OK; } HRESULT WINAPI glDirectDraw7::SetCooperativeLevel(HWND hWnd, DWORD dwFlags) { @@ -807,6 +985,11 @@ HRESULT WINAPI glDirectDraw7::SetDisplayMode(DWORD dwWidth, DWORD dwHeight, DWOR float aspect,xmul,ymul; LONG error; DWORD flags; + if(!oldmode.dmSize) + { + oldmode.dmSize = sizeof(DEVMODE); + EnumDisplaySettings(NULL,ENUM_CURRENT_SETTINGS,&oldmode); + } currmode.dmSize = sizeof(DEVMODE); EnumDisplaySettings(NULL,ENUM_CURRENT_SETTINGS,&currmode); switch(dxglcfg.scaler) @@ -1266,10 +1449,9 @@ HRESULT WINAPI glDirectDraw1::GetCaps(LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELC { return glDD7->GetCaps(lpDDDriverCaps,lpDDHELCaps); } -HRESULT WINAPI glDirectDraw1::GetDisplayMode(LPDDSURFACEDESC lpDDSurfaceDesc2) +HRESULT WINAPI glDirectDraw1::GetDisplayMode(LPDDSURFACEDESC lpDDSurfaceDesc) { - FIXME("glDirectDraw1::GetDisplayMode: stub\n"); - return DDERR_GENERIC; + return glDD7->GetDisplayMode((LPDDSURFACEDESC2)lpDDSurfaceDesc); } HRESULT WINAPI glDirectDraw1::GetFourCCCodes(LPDWORD lpNumCodes, LPDWORD lpCodes) { @@ -1387,10 +1569,9 @@ HRESULT WINAPI glDirectDraw2::GetCaps(LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELC { return glDD7->GetCaps(lpDDDriverCaps,lpDDHELCaps); } -HRESULT WINAPI glDirectDraw2::GetDisplayMode(LPDDSURFACEDESC lpDDSurfaceDesc2) +HRESULT WINAPI glDirectDraw2::GetDisplayMode(LPDDSURFACEDESC lpDDSurfaceDesc) { - FIXME("glDirectDraw2::GetDisplayMode: stub\n"); - return DDERR_GENERIC; + return glDD7->GetDisplayMode((LPDDSURFACEDESC2)lpDDSurfaceDesc); } HRESULT WINAPI glDirectDraw2::GetFourCCCodes(LPDWORD lpNumCodes, LPDWORD lpCodes) { @@ -1496,8 +1677,7 @@ HRESULT WINAPI glDirectDraw4::DuplicateSurface(LPDIRECTDRAWSURFACE4 lpDDSurface, } HRESULT WINAPI glDirectDraw4::EnumDisplayModes(DWORD dwFlags, LPDDSURFACEDESC2 lpDDSurfaceDesc, LPVOID lpContext, LPDDENUMMODESCALLBACK2 lpEnumModesCallback) { - FIXME("glDirectDraw4::EnumDisplayModes: stub\n"); - return DDERR_GENERIC; + return ::EnumDisplayModes(dwFlags,lpDDSurfaceDesc,lpContext,lpEnumModesCallback); } HRESULT WINAPI glDirectDraw4::EnumSurfaces(DWORD dwFlags, LPDDSURFACEDESC2 lpDDSD, LPVOID lpContext, LPDDENUMSURFACESCALLBACK2 lpEnumSurfacesCallback) { @@ -1514,8 +1694,7 @@ HRESULT WINAPI glDirectDraw4::GetCaps(LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELC } HRESULT WINAPI glDirectDraw4::GetDisplayMode(LPDDSURFACEDESC2 lpDDSurfaceDesc2) { - FIXME("glDirectDraw4::GetDisplayMode: stub\n"); - return DDERR_GENERIC; + return glDD7->GetDisplayMode(lpDDSurfaceDesc2); } HRESULT WINAPI glDirectDraw4::GetFourCCCodes(LPDWORD lpNumCodes, LPDWORD lpCodes) { diff --git a/ddraw/glDirectDraw.h b/ddraw/glDirectDraw.h index 5b35ff21..e050cf10 100644 --- a/ddraw/glDirectDraw.h +++ b/ddraw/glDirectDraw.h @@ -85,7 +85,6 @@ class glDirectDraw7 : public IDirectDraw7 LRESULT WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); DWORD GetBPP(){return primarybpp;} DWORD GetBPPMultipleOf8(){if(primarybpp == 15) return 16; else return primarybpp;} - DWORD GetBPPPowerOf2(){if(primarybpp == 15) return 16; if(primarybpp == 24) return 32; else return primarybpp;} HGLRC hRC; HDC hDC; DWORD screenx,screeny,screenrefresh,screenbpp; @@ -116,6 +115,7 @@ class glDirectDraw7 : public IDirectDraw7 int clippercount, clippercountmax; GLuint palprog; GLCAPS gl_caps; + DEVMODE oldmode; }; class glDirectDraw1 : public IDirectDraw diff --git a/ddraw/glDirectDrawSurface.cpp b/ddraw/glDirectDrawSurface.cpp index 05810b72..ded7ab11 100644 --- a/ddraw/glDirectDrawSurface.cpp +++ b/ddraw/glDirectDrawSurface.cpp @@ -16,6 +16,7 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #include "common.h" +#include "scalers.h" #include "shaders.h" #include "ddraw.h" #include "glDirectDraw.h" @@ -23,13 +24,86 @@ #include "glDirectDrawPalette.h" #include "glDirectDrawClipper.h" +inline int NextMultipleOf8(int number){return ((number+7) & (~7));} inline int NextMultipleOf4(int number){return ((number+3) & (~3));} inline int NextMultipleOf2(int number){return ((number+1) & (~1));} +#ifdef _M_X64 +#define NextMultipleOfWord NextMultipleOf8 +#else +#define NextMultipleOfWord NextMultipleOf4 +#endif + + +int UploadTexture(char *buffer, char *bigbuffer, GLuint texture, int x, int y, int bigx, int bigy, int pitch, int bigpitch, int bpp, int texformat, int texformat2) +{ + if(bpp == 15) bpp = 16; + int i; + glBindTexture(GL_TEXTURE_2D,texture); // Select surface's texture + if((x == bigx && y == bigy) || !bigbuffer) + { + glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,x,y,0,texformat,texformat2,buffer); + } + else + { + switch(bpp) + { + case 8: + ScaleNearest8(bigbuffer,buffer,bigx,bigy,x,y,pitch,bigpitch); + break; + case 16: + ScaleNearest16(bigbuffer,buffer,bigx,bigy,x,y,pitch/2,bigpitch/2); + break; + case 24: + ScaleNearest24(bigbuffer,buffer,bigx,bigy,x,y,pitch,bigpitch); + break; + case 32: + ScaleNearest32(bigbuffer,buffer,bigx,bigy,x,y,pitch/4,bigpitch/4); + break; + break; + } + glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,bigx,bigy,0,texformat,texformat2,bigbuffer); + } + return 0; +} +int DownloadTexture(char *buffer, char *bigbuffer, GLuint texture, int x, int y, int bigx, int bigy, int pitch, int bigpitch, int bpp, int texformat, int texformat2) +{ + glBindTexture(GL_TEXTURE_2D,texture); // Select surface's texture + int i; + if((bigx == x && bigy == y) || !bigbuffer) + { + glGetTexImage(GL_TEXTURE_2D,0,texformat,texformat2,buffer); // Shortcut for no scaling + } + else + { + glGetTexImage(GL_TEXTURE_2D,0,texformat,texformat2,bigbuffer); + switch(bpp) + { + case 8: + ScaleNearest8(buffer,bigbuffer,x,y,bigx,bigy,bigpitch,pitch); + break; + case 15: + case 16: + ScaleNearest16(buffer,bigbuffer,x,y,bigx,bigy,bigpitch/2,pitch/2); + break; + case 24: + ScaleNearest24(buffer,bigbuffer,x,y,bigx,bigy,bigpitch,pitch); + break; + case 32: + ScaleNearest32(buffer,bigbuffer,x,y,bigx,bigy,bigpitch/4,pitch/4); + break; + break; + } + } + return 0; +} // DDRAW7 routines glDirectDrawSurface7::glDirectDrawSurface7(LPDIRECTDRAW7 lpDD7, LPDDSURFACEDESC2 lpDDSurfaceDesc2, LPDIRECTDRAWSURFACE7 *lplpDDSurface7, HRESULT *error, bool copysurface, glDirectDrawPalette *palettein) { + dirty = 2; locked = 0; + pagelocked = 0; + flipcount = 0; bitmapinfo = (BITMAPINFO *)malloc(sizeof(BITMAPINFO)+(255*sizeof(RGBQUAD))); palette = NULL; clipper = NULL; @@ -38,6 +112,8 @@ glDirectDrawSurface7::glDirectDrawSurface7(LPDIRECTDRAW7 lpDD7, LPDDSURFACEDESC2 dds2 = NULL; dds3 = NULL; dds4 = NULL; + buffer = gdibuffer = NULL; + bigbuffer = NULL; DWORD colormasks[3]; if(copysurface) { @@ -130,7 +206,7 @@ glDirectDrawSurface7::glDirectDrawSurface7(LPDIRECTDRAW7 lpDD7, LPDDSURFACEDESC2 { info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); info.bmiHeader.biWidth = fakex; - info.bmiHeader.biHeight = -fakey; + info.bmiHeader.biHeight = -(signed)fakey; info.bmiHeader.biPlanes = 1; info.bmiHeader.biCompression = BI_RGB; info.bmiHeader.biSizeImage = 0; @@ -149,7 +225,7 @@ glDirectDrawSurface7::glDirectDrawSurface7(LPDIRECTDRAW7 lpDD7, LPDDSURFACEDESC2 { info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); info.bmiHeader.biWidth = fakex; - info.bmiHeader.biHeight = -fakey; + info.bmiHeader.biHeight = -(signed)fakey; info.bmiHeader.biPlanes = 1; info.bmiHeader.biCompression = BI_RGB; info.bmiHeader.biSizeImage = 0; @@ -177,17 +253,21 @@ glDirectDrawSurface7::glDirectDrawSurface7(LPDIRECTDRAW7 lpDD7, LPDDSURFACEDESC2 surfacetype=2; } bitmapinfo->bmiHeader.biWidth = ddsd.dwWidth; - bitmapinfo->bmiHeader.biHeight = -ddsd.dwHeight; + bitmapinfo->bmiHeader.biHeight = -(signed)ddsd.dwHeight; switch(surfacetype) { case 0: - buffer = (char *)malloc((ddsd.ddpfPixelFormat.dwRGBBitCount * fakex * fakey)/8); + buffer = (char *)malloc(NextMultipleOfWord((ddsd.ddpfPixelFormat.dwRGBBitCount * ddsd.dwWidth)/8) * ddsd.dwHeight); + if((ddsd.dwWidth != fakex) || (ddsd.dwHeight != fakey)) + bigbuffer = (char *)malloc(NextMultipleOfWord((ddsd.ddpfPixelFormat.dwRGBBitCount * fakex)/8) * fakey); if(!buffer) *error = DDERR_OUTOFMEMORY; + goto maketex; break; case 1: buffer = NULL; break; case 2: + maketex: buffer = NULL; glGenTextures(1,&texture); glBindTexture(GL_TEXTURE_2D,texture); @@ -227,7 +307,7 @@ glDirectDrawSurface7::glDirectDrawSurface7(LPDIRECTDRAW7 lpDD7, LPDDSURFACEDESC2 ddsd.ddpfPixelFormat.dwRBitMask = 0; ddsd.ddpfPixelFormat.dwGBitMask = 0; ddsd.ddpfPixelFormat.dwBBitMask = 0; - ddsd.lPitch = ddsd.dwWidth; + ddsd.lPitch = NextMultipleOfWord(ddsd.dwWidth); break; case 15: texformat = GL_BGRA; @@ -236,7 +316,7 @@ glDirectDrawSurface7::glDirectDrawSurface7(LPDIRECTDRAW7 lpDD7, LPDDSURFACEDESC2 ddsd.ddpfPixelFormat.dwRBitMask = 0x7C00; ddsd.ddpfPixelFormat.dwGBitMask = 0x3E0; ddsd.ddpfPixelFormat.dwBBitMask = 0x1F; - ddsd.lPitch = ddsd.dwWidth*2; + ddsd.lPitch = NextMultipleOfWord(ddsd.dwWidth*2); ddsd.ddpfPixelFormat.dwRGBBitCount = 16; break; case 16: @@ -246,7 +326,7 @@ glDirectDrawSurface7::glDirectDrawSurface7(LPDIRECTDRAW7 lpDD7, LPDDSURFACEDESC2 ddsd.ddpfPixelFormat.dwRBitMask = 0xF800; ddsd.ddpfPixelFormat.dwGBitMask = 0x7E0; ddsd.ddpfPixelFormat.dwBBitMask = 0x1F; - ddsd.lPitch = ddsd.dwWidth*2; + ddsd.lPitch = NextMultipleOfWord(ddsd.dwWidth*2); break; case 24: texformat = GL_BGR; @@ -255,7 +335,8 @@ glDirectDrawSurface7::glDirectDrawSurface7(LPDIRECTDRAW7 lpDD7, LPDDSURFACEDESC2 ddsd.ddpfPixelFormat.dwRBitMask = 0xFF0000; ddsd.ddpfPixelFormat.dwGBitMask = 0xFF00; ddsd.ddpfPixelFormat.dwBBitMask = 0xFF; - ddsd.lPitch = ddsd.dwWidth*4; + ddsd.lPitch = NextMultipleOfWord(ddsd.dwWidth*3); + break; case 32: texformat = GL_BGRA; texformat2 = GL_UNSIGNED_BYTE; @@ -263,7 +344,7 @@ glDirectDrawSurface7::glDirectDrawSurface7(LPDIRECTDRAW7 lpDD7, LPDDSURFACEDESC2 ddsd.ddpfPixelFormat.dwRBitMask = 0xFF0000; ddsd.ddpfPixelFormat.dwGBitMask = 0xFF00; ddsd.ddpfPixelFormat.dwBBitMask = 0xFF; - ddsd.lPitch = ddsd.dwWidth*4; + ddsd.lPitch = NextMultipleOfWord(ddsd.dwWidth*4); break; default: *error = DDERR_INVALIDPIXELFORMAT; @@ -313,6 +394,8 @@ glDirectDrawSurface7::~glDirectDrawSurface7() if(bitmapinfo) free(bitmapinfo); if(palette) palette->Release(); if(backbuffer) backbuffer->Release(); + if(buffer) free(buffer); + if(bigbuffer) free(bigbuffer); ddInterface->Release(); } HRESULT WINAPI glDirectDrawSurface7::QueryInterface(REFIID riid, void** ppvObj) @@ -414,6 +497,22 @@ HRESULT WINAPI glDirectDrawSurface7::AddOverlayDirtyRect(LPRECT lpRect) } HRESULT WINAPI glDirectDrawSurface7::Blt(LPRECT lpDestRect, LPDIRECTDRAWSURFACE7 lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx) { + glDirectDrawSurface7 *src = (glDirectDrawSurface7 *)lpDDSrcSurface; + if(dirty & 1) + { + UploadTexture(buffer,bigbuffer,texture,ddsd.dwWidth,ddsd.dwHeight, + fakex,fakey,ddsd.lPitch,(NextMultipleOf4((ddInterface->GetBPPMultipleOf8()/8)*fakex)), + ddsd.ddpfPixelFormat.dwRGBBitCount,texformat,texformat2); + dirty &= ~1; + } + if(src->dirty & 1) + { + UploadTexture(src->buffer,src->bigbuffer,src->texture,src->ddsd.dwWidth,src->ddsd.dwHeight, + src->fakex,src->fakey,src->ddsd.lPitch, + (NextMultipleOf4((ddInterface->GetBPPMultipleOf8()/8)*src->fakex)), + src->ddsd.ddpfPixelFormat.dwRGBBitCount,src->texformat,src->texformat2); + src->dirty &= ~1; + } LONG sizes[6]; ddInterface->GetSizes(sizes); int error; @@ -449,7 +548,7 @@ HRESULT WINAPI glDirectDrawSurface7::Blt(LPRECT lpDestRect, LPDIRECTDRAWSURFACE7 srcrect.left = 0; srcrect.top = 0; srcrect.right = ddsdSrc.dwWidth; - srcrect.right = ddsdSrc.dwHeight; + srcrect.bottom = ddsdSrc.dwHeight; } else srcrect = *lpSrcRect; GLfloat coords[8]; @@ -488,7 +587,7 @@ HRESULT WINAPI glDirectDrawSurface7::Blt(LPRECT lpDestRect, LPDIRECTDRAWSURFACE7 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0); } glPopAttrib(); - if(ddsd.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER | DDSCAPS_PRIMARYSURFACE)) RenderScreen(texture); + if(ddsd.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER | DDSCAPS_PRIMARYSURFACE)) RenderScreen(texture,this); return DD_OK; } HRESULT WINAPI glDirectDrawSurface7::BltBatch(LPDDBLTBATCH lpDDBltBatch, DWORD dwCount, DWORD dwFlags) @@ -518,6 +617,7 @@ HRESULT WINAPI glDirectDrawSurface7::EnumOverlayZOrders(DWORD dwFlags, LPVOID lp } HRESULT WINAPI glDirectDrawSurface7::Flip(LPDIRECTDRAWSURFACE7 lpDDSurfaceTargetOverride, DWORD dwFlags) { + int flips = 1; if(lpDDSurfaceTargetOverride) return DDERR_GENERIC; if(ddsd.ddsCaps.dwCaps & DDSCAPS_FLIP) { @@ -540,15 +640,18 @@ HRESULT WINAPI glDirectDrawSurface7::Flip(LPDIRECTDRAWSURFACE7 lpDDSurfaceTarget tmp = tmp->GetBackbuffer(); tmp->SetTexture(textures[i+1]); } - RenderScreen(textures[0]); + RenderScreen(textures[0],this); delete textures; } else return DDERR_NOTFLIPPABLE; + flipcount+=flips; + if(flipcount > ddsd.dwBackBufferCount) flipcount -= (ddsd.dwBackBufferCount+1); return DD_OK; } HRESULT WINAPI glDirectDrawSurface7::GetAttachedSurface(LPDDSCAPS2 lpDDSCaps, LPDIRECTDRAWSURFACE7 FAR *lplpDDAttachedSurface) { DDSCAPS2 ddsComp; + if(!backbuffer) return DDERR_NOTFOUND; backbuffer->GetCaps(&ddsComp); unsigned __int64 comp1,comp2; memcpy(&comp1,lpDDSCaps,sizeof(unsigned __int64)); @@ -591,7 +694,6 @@ HRESULT WINAPI glDirectDrawSurface7::GetDC(HDC FAR *lphDC) DWORD colors[256]; HRESULT error; LPVOID surface; - unsigned char *bitmap; error = this->Lock(NULL,&ddsd,0,NULL); if(error != DD_OK) return error; hdc = CreateCompatibleDC(NULL); @@ -639,8 +741,8 @@ HRESULT WINAPI glDirectDrawSurface7::GetPalette(LPDIRECTDRAWPALETTE FAR *lplpDDP } HRESULT WINAPI glDirectDrawSurface7::GetPixelFormat(LPDDPIXELFORMAT lpDDPixelFormat) { - FIXME("glDirectDrawSurface7::GetPixelFormat: stub\n"); - return DDERR_GENERIC; + *lpDDPixelFormat = ddsd.ddpfPixelFormat; + return DD_OK; } HRESULT WINAPI glDirectDrawSurface7::GetSurfaceDesc(LPDDSURFACEDESC2 lpDDSurfaceDesc) { @@ -650,8 +752,7 @@ HRESULT WINAPI glDirectDrawSurface7::GetSurfaceDesc(LPDDSURFACEDESC2 lpDDSurface } HRESULT WINAPI glDirectDrawSurface7::Initialize(LPDIRECTDRAW lpDD, LPDDSURFACEDESC2 lpDDSurfaceDesc) { - FIXME("glDirectDrawSurface7::Initialize: stub\n"); - return DDERR_GENERIC; + return DDERR_ALREADYINITIALIZED; } HRESULT WINAPI glDirectDrawSurface7::IsLost() { @@ -659,93 +760,37 @@ HRESULT WINAPI glDirectDrawSurface7::IsLost() return DDERR_GENERIC; } -inline RGBTRIPLE _32to24(unsigned long color) -{ - RGBTRIPLE tmp; - tmp.rgbtBlue = color & 0xFF; - tmp.rgbtGreen = (color >> 8) & 0xFF; - tmp.rgbtRed = (color >> 16) & 0xFF; - return tmp; -} - HRESULT WINAPI glDirectDrawSurface7::Lock(LPRECT lpDestRect, LPDDSURFACEDESC2 lpDDSurfaceDesc, DWORD dwFlags, HANDLE hEvent) { if(locked) return DDERR_SURFACEBUSY; - DWORD x,y; - unsigned char *bitmap = (unsigned char *)malloc((ddInterface->GetBPPPowerOf2()/8) * ddsd.dwWidth * ddsd.dwHeight); - unsigned short *&bmp16 = (unsigned short *&)bitmap; - RGBTRIPLE *&bmp24 = (RGBTRIPLE *&)bitmap; - unsigned long *&bmp32 = (unsigned long *&)bitmap; - unsigned char *temptex; - unsigned short *&tmptex16 = (unsigned short *&)temptex; - unsigned long *&tmptex32 = (unsigned long *&)temptex; - if(ddInterface->GetBPP() == 24) ddsd.lPitch = ddsd.dwWidth * (ddInterface->GetBPPMultipleOf8()/8); - else ddsd.lPitch = ddsd.dwWidth * (ddInterface->GetBPPMultipleOf8()/8); - float mulx, muly; - if(!bitmap) return DDERR_OUTOFMEMORY; + dirty |= 1; + retry: switch(surfacetype) { + default: + return DDERR_GENERIC; + break; case 0: - FIXME("glDirectDrawSurface7::Lock: surface type 0 not supported yet"); - return DDERR_UNSUPPORTED; + if(dirty & 2) + DownloadTexture(buffer,bigbuffer,texture,ddsd.dwWidth,ddsd.dwHeight,fakex,fakey,ddsd.lPitch, + (ddInterface->GetBPPMultipleOf8()/8)*fakex,ddsd.ddpfPixelFormat.dwRGBBitCount,texformat,texformat2); + ddsd.lpSurface = buffer; break; case 1: FIXME("glDirectDrawSurface7::Lock: surface type 1 not supported yet"); return DDERR_UNSUPPORTED; break; case 2: - glBindTexture(GL_TEXTURE_2D,this->texture); // Select surface's texture - if(fakex == ddsd.dwWidth && fakey == ddsd.dwHeight) - { - if(ddInterface->GetBPP() == 24) - { - temptex = (unsigned char *)malloc(NextMultipleOf4((ddInterface->GetBPPPowerOf2()/8)*fakex)*fakey); - for(x = 0; x < ddsd.dwWidth*ddsd.dwHeight; x++) - bmp24[x] = _32to24(tmptex32[x]); - glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,fakex,fakey,0,texformat,texformat2,temptex); - free(temptex); - } - glGetTexImage(GL_TEXTURE_2D,0,texformat,texformat2,bitmap); // Shortcut for no scaling - } - else - { - mulx = (float)fakex / (float)ddsd.dwWidth; - muly = (float)fakey / (float)ddsd.dwHeight; - temptex = (unsigned char *)malloc(NextMultipleOf4((ddInterface->GetBPPPowerOf2()/8)*fakex)*fakey); - if(!temptex) - { - free(bitmap); - return DDERR_OUTOFMEMORY; - } - glGetTexImage(GL_TEXTURE_2D,0,texformat,texformat2,temptex); - switch(ddInterface->GetBPPMultipleOf8()) - { - case 8: - for(y = 0; y < ddsd.dwHeight; y++) - for(x = 0; x < ddsd.dwWidth; x++) - bitmap[x + (ddsd.dwWidth*y)] = temptex[(int)(x*mulx) + (fakex*(int)(y*muly))]; - break; - case 16: - for(y = 0; y < ddsd.dwHeight; y++) - for(x = 0; x < ddsd.dwWidth; x++) - bmp16[x + (ddsd.dwWidth*y)] = tmptex16[(int)(x*mulx) + (fakex*(int)(y*muly))]; - break; - case 24: - for(y = 0; y < ddsd.dwHeight; y++) - for(x = 0; x < ddsd.dwWidth; x++) - bmp24[x + (ddsd.dwWidth*y)] = _32to24(tmptex32[(int)(x*mulx) + (fakex*(int)(y*muly))]); - break; - case 32: - for(y = 0; y < ddsd.dwHeight; y++) - for(x = 0; x < ddsd.dwWidth; x++) - bmp32[x + (ddsd.dwWidth*y)] = tmptex32[(int)(x*mulx) + (fakex*(int)(y*muly))]; - break; - break; - } - free(temptex); - } + buffer = (char *)malloc(ddsd.lPitch * ddsd.dwHeight); + if((ddsd.dwWidth != fakex) || (ddsd.dwHeight != fakey)) + bigbuffer = (char *)malloc((ddsd.ddpfPixelFormat.dwRGBBitCount * NextMultipleOfWord(fakex) * fakey)/8); + else bigbuffer = NULL; + DownloadTexture(buffer,bigbuffer,texture,ddsd.dwWidth,ddsd.dwHeight,fakex,fakey,ddsd.lPitch, + (ddInterface->GetBPPMultipleOf8()/8)*fakex,ddsd.ddpfPixelFormat.dwRGBBitCount,texformat,texformat2); + dirty &= ~2; + surfacetype = 0; + goto retry; } - ddsd.lpSurface = bitmap; memcpy(lpDDSurfaceDesc,&ddsd,lpDDSurfaceDesc->dwSize); locked++; return DD_OK; @@ -799,73 +844,12 @@ HRESULT WINAPI glDirectDrawSurface7::SetPalette(LPDIRECTDRAWPALETTE lpDDPalette) return DD_OK; } -inline unsigned int _24to32(RGBTRIPLE color) -{ - return color.rgbtBlue | (color.rgbtGreen << 8) | (color.rgbtRed << 16); -} - HRESULT WINAPI glDirectDrawSurface7::Unlock(LPRECT lpRect) { if(!locked) return DDERR_NOTLOCKED; locked--; - unsigned char *bitmap = (unsigned char *)ddsd.lpSurface; - unsigned short *&bmp16 = (unsigned short *&)bitmap; - RGBTRIPLE *&bmp24 = (RGBTRIPLE *&)bitmap; - unsigned long *&bmp32 = (unsigned long *&)bitmap; - unsigned char *temptex; - unsigned short *&tmptex16 = (unsigned short *&)temptex; - unsigned long *&tmptex32 = (unsigned long *&)temptex; - float mulx, muly; - DWORD x,y; - glBindTexture(GL_TEXTURE_2D,this->texture); // Select surface's texture - if(ddsd.dwWidth == fakex && ddsd.dwHeight == fakey) - { - if(ddInterface->GetBPP() == 24) - { - temptex = (unsigned char *)malloc(NextMultipleOf4((ddInterface->GetBPPPowerOf2()/8)*fakex)*fakey); - for(x = 0; x < ddsd.dwWidth*ddsd.dwHeight; x++) - tmptex32[x] = _24to32(bmp24[x]); - glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,fakex,fakey,0,texformat,texformat2,temptex); - free(temptex); - } - else glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,fakex,fakey,0,texformat,texformat2,bitmap); - } - else - { - temptex = (unsigned char *)malloc(NextMultipleOf4((ddInterface->GetBPPPowerOf2()/8)*fakex)*fakey); - if(!temptex) return DDERR_OUTOFMEMORY; - mulx = (float)ddsd.dwWidth / (float)fakex; - muly = (float)ddsd.dwHeight / (float)fakey; - switch(ddInterface->GetBPPMultipleOf8()) - { - case 8: - for(y = 0; y < fakey; y++) - for(x = 0; x < fakex; x++) - temptex[x + (NextMultipleOf4(fakex)*y)] = bitmap[(int)(x*mulx) + (ddsd.dwWidth*(int)(y*muly))]; - break; - case 16: - for(y = 0; y < fakey; y++) - for(x = 0; x < fakex; x++) - tmptex16[x + (NextMultipleOf2(fakex)*y)] = bmp16[(int)(x*mulx) + (ddsd.dwWidth*(int)(y*muly))]; - break; - case 24: - for(y = 0; y < fakey; y++) - for(x = 0; x < fakex; x++) - tmptex32[x + (fakex*y)] = _24to32(bmp24[(int)(x*mulx) + (ddsd.dwWidth*(int)(y*muly))]); - break; - case 32: - for(y = 0; y < fakey; y++) - for(x = 0; x < fakex; x++) - tmptex32[x + (fakex*y)] = bmp32[(int)(x*mulx) + (ddsd.dwWidth*(int)(y*muly))]; - break; - break; - } - glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,fakex,fakey,0,texformat,texformat2,temptex); - free(temptex); - } - if(ddsd.lpSurface) free(ddsd.lpSurface); ddsd.lpSurface = NULL; - if(ddsd.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER | DDSCAPS_PRIMARYSURFACE)) RenderScreen(texture); + if(ddsd.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER | DDSCAPS_PRIMARYSURFACE)) RenderScreen(texture,this); return DD_OK; } HRESULT WINAPI glDirectDrawSurface7::UpdateOverlay(LPRECT lpSrcRect, LPDIRECTDRAWSURFACE7 lpDDDestSurface, LPRECT lpDestRect, DWORD dwFlags, LPDDOVERLAYFX lpDDOverlayFx) @@ -884,12 +868,20 @@ HRESULT WINAPI glDirectDrawSurface7::UpdateOverlayZOrder(DWORD dwFlags, LPDIRECT return DDERR_GENERIC; } -void glDirectDrawSurface7::RenderScreen(GLuint texture) +void glDirectDrawSurface7::RenderScreen(GLuint texture, glDirectDrawSurface7 *surface) { LONG sizes[6]; glMatrixMode(GL_PROJECTION); glLoadIdentity(); RECT r,r2; + if(surface->dirty & 1) + { + UploadTexture(buffer,surface->bigbuffer,texture,surface->ddsd.dwWidth,surface->ddsd.dwHeight, + surface->fakex,surface->fakey,surface->ddsd.lPitch, + (NextMultipleOf4((ddInterface->GetBPPMultipleOf8()/8)*surface->fakex)), + surface->ddsd.ddpfPixelFormat.dwRGBBitCount,surface->texformat,surface->texformat2); + surface->dirty &= ~1; + } if(ddsd.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) { if(ddInterface->GetFullscreen()) @@ -910,7 +902,7 @@ void glDirectDrawSurface7::RenderScreen(GLuint texture) ClientToScreen(hwnd,(LPPOINT)&r2.left); ClientToScreen(hwnd,(LPPOINT)&r2.right); glViewport(0,0,r.right,r.bottom); - glOrtho(r2.left,r2.right,fakey-r2.bottom,fakey-r2.top,0,1); + glOrtho((signed)r2.left,(signed)r2.right,(signed)(fakey-r2.bottom),(signed)(fakey-r2.top),0,1); } } else glOrtho(0,fakex,fakey,0,0,1); @@ -976,13 +968,22 @@ HRESULT WINAPI glDirectDrawSurface7::GetDDInterface(LPVOID FAR *lplpDD) } HRESULT WINAPI glDirectDrawSurface7::PageLock(DWORD dwFlags) { - FIXME("glDirectDrawSurface7::PageLock: stub\n"); - return DDERR_GENERIC; + if(surfacetype == 1) + { + pagelocked++; + return DD_OK; + } + else return DDERR_CANTPAGELOCK; } HRESULT WINAPI glDirectDrawSurface7::PageUnlock(DWORD dwFlags) { - FIXME("glDirectDrawSurface7::PageUnlock: stub\n"); - return DDERR_GENERIC; + if(surfacetype == 1) + { + if(!pagelocked) return DDERR_NOTPAGELOCKED; + pagelocked--; + return DD_OK; + } + else return DDERR_CANTPAGEUNLOCK; } // ddraw 3+ api HRESULT WINAPI glDirectDrawSurface7::SetSurfaceDesc(LPDDSURFACEDESC2 lpddsd2, DWORD dwFlags) diff --git a/ddraw/glDirectDrawSurface.h b/ddraw/glDirectDrawSurface.h index e0807b2a..daa923be 100644 --- a/ddraw/glDirectDrawSurface.h +++ b/ddraw/glDirectDrawSurface.h @@ -89,15 +89,22 @@ class glDirectDrawSurface7 : public IDirectDrawSurface7 } void SetTexture(GLuint newtexture){texture = newtexture;}; glDirectDrawSurface7 *GetBackbuffer(){return backbuffer;}; - void RenderScreen(GLuint texture); + void RenderScreen(GLuint texture, glDirectDrawSurface7 *surface); // Special ddraw2->ddraw7 api HRESULT WINAPI Unlock2(LPVOID lpSurfaceData); glDirectDrawSurface1 *dds1; glDirectDrawSurface2 *dds2; glDirectDrawSurface3 *dds3; glDirectDrawSurface4 *dds4; -private: + int flipcount; + GLenum texformat; + GLenum texformat2; DWORD fakex,fakey; + DWORD dirty; + // dirty bits: + // 1 - Surface was locked + // 2 - Texture was written to by ddraw +private: ULONG refcount; int locked; HDC hdc; @@ -109,11 +116,12 @@ class glDirectDrawSurface7 : public IDirectDrawSurface7 GLuint texture,paltex; int surfacetype; // 0-generic memory, 1-GDI surface, 2-OpenGL Texture char *buffer; + char *bigbuffer; + char *gdibuffer; glDirectDrawSurface7 *backbuffer; glDirectDrawPalette *palette; glDirectDrawClipper *clipper; - GLenum texformat; - GLenum texformat2; + int pagelocked; }; // Legacy DDRAW Interfaces diff --git a/ddraw/scalers.cpp b/ddraw/scalers.cpp new file mode 100644 index 00000000..173a4580 --- /dev/null +++ b/ddraw/scalers.cpp @@ -0,0 +1,105 @@ +// DXGL +// Copyright (C) 2011 William Feely + +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +#include "common.h" +#include "scalers.h" +#include + + +void ScaleNearest8(void *dest, void *src, int dw, int dh, int sw, int sh, int inpitch, int outpitch) +{ + BYTE *d = (BYTE *)dest; + BYTE *s = (BYTE *)src; + int rx = (int)((sw<<16)/dw)+1; + int ry = (int)((sh<<16)/dh)+1; + int x2,y2; + for(int y = 0; y < dh; y++) + { + int b1 = y*outpitch; + y2 = ((y*ry)>>16); + int b2 = y2*inpitch; + for(int x = 0; x < dw; x++) + { + x2 = ((x*rx)>>16); + y2 = ((y*ry)>>16); + d[b1+x] = s[b2+x2]; + } + } +} +void ScaleNearest16(void *dest, void *src, int dw, int dh, int sw, int sh, int inpitch, int outpitch) +{ + WORD *d = (WORD *)dest; + WORD *s = (WORD *)src; + int rx = (int)((sw<<16)/dw)+1; + int ry = (int)((sh<<16)/dh)+1; + int x2,y2; + for(int y = 0; y < dh; y++) + { + int b1 = y*outpitch; + y2 = ((y*ry)>>16); + int b2 = y2*inpitch; + for(int x = 0; x < dw; x++) + { + x2 = ((x*rx)>>16); + y2 = ((y*ry)>>16); + d[b1+x] = s[b2+x2]; + } + } +} +void ScaleNearest24(void *dest, void *src, int dw, int dh, int sw, int sh, int inpitch, int outpitch) +{ + RGBTRIPLE *d = (RGBTRIPLE *)dest; + RGBTRIPLE *s = (RGBTRIPLE *)src; + char *d8 = (char*)dest; + char *s8 = (char*)src; + int rx = (int)((sw<<16)/dw)+1; + int ry = (int)((sh<<16)/dh)+1; + int x2,y2; + for(int y = 0; y < dh; y++) + { + d8 = (y*outpitch)+(char*)dest; + y2 = ((y*ry)>>16); + s8 = (y2*inpitch)+(char*)src; + d = (RGBTRIPLE*)d8; + s = (RGBTRIPLE*)s8; + for(int x = 0; x < dw; x++) + { + x2 = ((x*rx)>>16); + y2 = ((y*ry)>>16); + d[x] = s[x2]; + } + } +} +void ScaleNearest32(void *dest, void *src, int dw, int dh, int sw, int sh, int inpitch, int outpitch) +{ + DWORD *d = (DWORD *)dest; + DWORD *s = (DWORD *)src; + int rx = (int)((sw<<16)/dw)+1; + int ry = (int)((sh<<16)/dh)+1; + int x2,y2; + for(int y = 0; y < dh; y++) + { + int b1 = y*outpitch; + y2 = ((y*ry)>>16); + int b2 = y2*inpitch; + for(int x = 0; x < dw; x++) + { + x2 = ((x*rx)>>16); + d[b1+x] = s[b2+x2]; + } + } +} diff --git a/ddraw/scalers.h b/ddraw/scalers.h new file mode 100644 index 00000000..13f02085 --- /dev/null +++ b/ddraw/scalers.h @@ -0,0 +1,28 @@ +// DXGL +// Copyright (C) 2011 William Feely + +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +#pragma once +#ifndef _SCALERS_H +#define _SCALERS_H + +void ScaleNearest8(void *dest, void *src, int dw, int dh, int sw, int sh, int inpitch, int outpitch); +void ScaleNearest16(void *dest, void *src, int dw, int dh, int sw, int sh, int inpitch, int outpitch); +void ScaleNearest24(void *dest, void *src, int dw, int dh, int sw, int sh, int inpitch, int outpitch); +void ScaleNearest32(void *dest, void *src, int dw, int dh, int sw, int sh, int inpitch, int outpitch); + + +#endif //_SCALERS_H \ No newline at end of file diff --git a/dxglcfg/dxglcfg.rc b/dxglcfg/dxglcfg.rc index c0ce5d7e..d21e34ba 100644 --- a/dxglcfg/dxglcfg.rc +++ b/dxglcfg/dxglcfg.rc @@ -96,8 +96,8 @@ IDI_STAR ICON "..\\common\\star.ico" // LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL 1 VERSIONINFO - FILEVERSION 0,0,5,0 - PRODUCTVERSION 0,0,5,0 + FILEVERSION 0,0,6,0 + PRODUCTVERSION 0,0,6,0 FILEOS VOS__WINDOWS32 FILETYPE VFT_APP FILESUBTYPE VFT2_UNKNOWN @@ -109,12 +109,12 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL BLOCK "08000352" { VALUE "FileDescription", "DXGL Configuration Program" - VALUE "FileVersion", "0.0.5.0" + VALUE "FileVersion", "0.0.6.0" VALUE "InternalName", "DXGL" VALUE "LegalCopyright", "Copyright © 2011 William Feely" VALUE "OriginalFilename", "dxglcfg.exe" VALUE "ProductName", "DXGL" - VALUE "ProductVersion", "0.0.5.0" + VALUE "ProductVersion", "0.0.6.0" } } BLOCK "VarFileInfo" diff --git a/dxgltest/Tests2D.cpp b/dxgltest/Tests2D.cpp index 8072de9d..902887f5 100644 --- a/dxgltest/Tests2D.cpp +++ b/dxgltest/Tests2D.cpp @@ -114,7 +114,7 @@ void RunTest2D(int testnum, int width, int height, int bpp, int refresh, int bac DDSURFACEDESC2 ddsd; BOOL done = false; ::testnum = testnum; - randnum = time(NULL); + randnum = (unsigned int)time(NULL); ZeroMemory(&ddsd,sizeof(DDSURFACEDESC2)); if(apiver > 3) ddsd.dwSize = sizeof(DDSURFACEDESC2); else ddsd.dwSize = sizeof(DDSURFACEDESC); @@ -409,7 +409,7 @@ void RunTestTimed(int test) void RunTestLooped(int test) { - randnum /= rand(); // Improves randomness of "snow" patterns at certain resolutions + randnum += rand(); // Improves randomness of "snow" patterns at certain resolutions HDC hdc; unsigned int i; POINT p; diff --git a/dxgltest/dxgltest.cpp b/dxgltest/dxgltest.cpp index f278a461..b6aacc71 100644 --- a/dxgltest/dxgltest.cpp +++ b/dxgltest/dxgltest.cpp @@ -449,6 +449,7 @@ INT_PTR CALLBACK DXGLTestCallback(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lPa tabwnd[1] = CreateDialog(hinstance,MAKEINTRESOURCE(IDD_TESTGFX),hTab,Test2DCallback); SendDlgItemMessage(hWnd,IDC_TABS,TCM_GETITEMRECT,0,(LPARAM)&tabrect); SetWindowPos(tabwnd[0],NULL,tabrect.left,tabrect.bottom+3,0,0,SWP_SHOWWINDOW|SWP_NOSIZE); + ShowWindow(tabwnd[1],SWP_HIDEWINDOW); tabopen = 0; ShowWindow(hWnd,SW_SHOWNORMAL); return TRUE; diff --git a/dxgltest/dxgltest.rc b/dxgltest/dxgltest.rc index e71a7f17..bdb5f9ff 100644 --- a/dxgltest/dxgltest.rc +++ b/dxgltest/dxgltest.rc @@ -124,8 +124,8 @@ IDB_DXGLINV64 BITMAP "..\\common\\dxglinv64.bmp" // LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL 1 VERSIONINFO - FILEVERSION 0,0,5,0 - PRODUCTVERSION 0,0,5,0 + FILEVERSION 0,0,6,0 + PRODUCTVERSION 0,0,6,0 FILEOS VOS__WINDOWS32 FILETYPE VFT_APP FILESUBTYPE VFT2_UNKNOWN @@ -137,12 +137,12 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL BLOCK "08000352" { VALUE "FileDescription", "DXGL Test App" - VALUE "FileVersion", "0.0.5.0" + VALUE "FileVersion", "0.0.6.0" VALUE "InternalName", "DXGL" VALUE "LegalCopyright", "Copyright © 2011 William Feely" VALUE "OriginalFilename", "dxgltest.exe" VALUE "ProductName", "DXGL" - VALUE "ProductVersion", "0.0.5.0" + VALUE "ProductVersion", "0.0.6.0" } } BLOCK "VarFileInfo"