Merge commit 'acb50ad002741b50ed8d57a6959eb6df5765dd96' into master-ptrace-core

This commit is contained in:
Jonathan Campbell 2018-08-09 11:35:26 -07:00
commit 776511d85a
862 changed files with 356647 additions and 2463 deletions

29
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@ -0,0 +1,29 @@
---
name: Bug report
about: Create a report to help us improve DOSBox-X
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Environment (please complete the following information):**
- Operating system
- DOSBox-X release version or commit SHA1 this issue occurred on
- Used configuration, e.g. ```dosbox.conf```
**Additional context**
Add any other context about the problem here.

View File

@ -0,0 +1,17 @@
---
name: Feature request
about: Suggest an idea for this project
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@ -1,12 +1,20 @@
TODO add version
0.82.8
- New xBRZ scaler (with bilinear mode) (Alexat)
- Fixed aspect ratio correction to use the ratio given by VGA emulation
instead of assuming 4:3
- output=surface and xBRZ now permit filling the window just like
output=opengl and output=direct3d
- Added critical section around Windows SDL 1.x resize code to solve
the remaining 0.5% probability that resizing the window causes move
and resize to stop working in Windows 10.
- INT 10h AH=10h now ignores AL=3 in PCjr mode.
- Fixed keyboard handler bug in PCjr mode that caused some CPU
register corruption and general crashiness in games.
- Improved shell: (Aybe, Joncampbell123)
- Ctrl+Left and Ctrl+Right permits word-navigation.
- Added emulation of 'Ins' key behavior.
- Num Lock stays on at startup and is synchronized with host (Aybe)
when DOSBox-X window gains focus (Windows). (Aybe)
- Num Lock, Caps Lock, Scroll Lock are now synchronized at startup
and when DOSBox-X window gains focus again (Windows). (Aybe)
- Added visual feedback to Hat/D-pad buttons in mapper. (Aybe)
- Added documentation for 'dir' command sorting switches. (Aybe)
- Menu 'Show console' is now checked with '-console' (SDL1). (Aybe)
@ -15,12 +23,13 @@ TODO add version
- Axes can be remapped for devices with questionable layout.
- User-settable deadzones for joystick bindings in mapper,
mappings like WSAD keys to axes is less frustrating.
- Improved mouse integration:
- Improved mouse integration (Aybe):
- Now by default DOSBox-X does not emulate mouse movement when the mouse
is not locked. This gives a consistent experience when compared to host OS.
For the old behavior, use [sdl] mouse_emulation=always.
- Added visual or auditive feedback that notifies about auto-lock state.
- Added visual or auditive feedback about auto-lock state (Windows).
This feature can be switched off, use [sdl] autolock_feedback=none.
- Added CAPMOUSE program for capturing/releasing mouse from command line. (Aybe)
0.82.7
- Mac OS X builds now honor showmenu=false by leaving the

31
CODE_OF_CONDUCT.md Normal file
View File

@ -0,0 +1,31 @@
# Community guidelines
Be fair, and work cooperatively. This is a open source project where anyone with an interest in MS-DOS, emulation, and/or DOSBox-X is welcome to talk, chat, develop, and contribute to the project.
Leave your politics at the door. The focus of this project is DOSBox-X and topics related to it including emulation, games, software, hardware, accuracy, code, development, and documentation. Anything else is off-topic and will be treated as such.
I (Jonathan Campbell) will block users from this project that are hostile to this project, it's developers, and/or users with an explicit explanation as to why. That includes threats, slander, gossip, doxxing, and spreading misinformation about myself and/or other users of this project, whether here or anywhere else, on the internet or in real life.
Humor and jokes are welcome as long as they are on-topic. This is a fun hobby project where enthusiasts can get together to hack, modify, explore and share a common interest in this project and the aforementioned topics listed above.
I (Jonathan Campbell), as the owner of this project, reserve the right to block users from this project that violate this Code of Conduct or otherwise disrupt this project according to my judgement. Other users whom I have given access to do so, may block users from this project that explicitly violate this Code of Conduct.
This Code of Conduct is applicable to the DOSBox-X project at https://github.com/joncampbell123/dosbox-x. Forks and projects derived from https://github.com/joncampbell123/dosbox-x may have their own Code of Conduct independent of the main DOSBox-X project, to be upheld and maintained by the owner of that repository only within the domain of that repository. The fork or derived project is free to allow or block users according to the whims and policy of the repository owner, independent of the main DOSBox-X project.
Participation in this project is always voluntary. There is no requirement or obligation to work on this project continuously or in a consistent manner, or at all.
Definition of terms:
* [Anyone, any person at all](https://www.merriam-webster.com/dictionary/anyone)
* [Person, human, individual](https://www.merriam-webster.com/dictionary/person)
* [Interest, a quality in a thing arousing interest](https://www.merriam-webster.com/dictionary/interest)
* [Focus, directed attention](https://www.merriam-webster.com/dictionary/focus)
* [Hostile, marked by malevolence, of an enemy, openly opposed, not hospitable](https://www.merriam-webster.com/dictionary/hostile)
* [Threats, an expression of intention to inflict evil, injury, or damage](https://www.merriam-webster.com/dictionary/threats)
* [Slander, to utter slander against, defame](https://www.merriam-webster.com/dictionary/slander)
* [Defame, to harm the reputation of by communicating false statements about : to harm the reputation of by libel](https://www.merriam-webster.com/dictionary/defame)
* [Gossip, rumor or report of an intimate nature](https://www.merriam-webster.com/dictionary/gossip)
* [Dox, to publicly identify or publish private information about (someone) especially as a form of punishment or revenge](https://www.merriam-webster.com/dictionary/dox)
* [Enthusiast, one who tends to become ardently absorbed in an interest](https://www.merriam-webster.com/dictionary/enthusiast)
* [Joke, something said or done to provoke laughter; especially : a brief oral narrative with a climactic humorous twist, something not to be taken seriously : a trifling matter](https://www.merriam-webster.com/dictionary/joke)
* [Humor, something that is or is designed to be comical or amusing](https://www.merriam-webster.com/dictionary/humor)
* [Hobby, an activity or interest pursued for pleasure or relaxation and not as a main occupation](http://www.dictionary.com/browse/hobby)

31
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,31 @@
## First steps
Before contributing, please check the Issues tab to see whether your potential contribution is already being discussed, or if you'd like to discuss about it first.
## Scope of contributions that are welcome
- the normal operation of games within DOSBox-X
- architectural symmetry with a real DOS environment
- improving a platform-specific build of DOSBox-X or getting it on par with other platforms supported
- non-implemented (or incorrectly) system calls
- missing or incorrect hardware emulation, e.g. video, sound, input
- fixes and/or improvements that allows demoscene productions to run in DOSBox-X
You do not necessarily need to be versed in coding, in this case you will certainly spend most of your time in the Issues tab; either submitting bugs or asking for new features.
## Code
For the code style, please refer to the .editorconfig file, your development environment probably supports it (see https://editorconfig.org/).
The emphasis is put on code clarity, simplicity and documented whenever possible.
Documenting can be 'dynamic', Doxygen-commented methods are preferred but evocative method names are also accepted as long as they're self-explanative.
Recommendations about coding:
- favor the writing of short methods, opposed to long methods, with the exception for really simple to understand code
- maximize code reuse, i.e. don't repeat yourself (DRY)
- simplify your code path for extra clarity, avoid crazing nesting
Obviously when you'll dig in, you will quickly spot that there are many places where these rules are simply not followed ! Over the years, hundreds of people have worked on DOSBox (which DOSBox-X is a fork of), while that helped to raise this project to where it is today, it certainly didn't in terms of clean code. But keep the faith, a huge code cleanup endeavor has started with the goal to raise the metrics of DOSBox-X guts, hopefully ASAP.
That said, welcome to this repository !

View File

@ -0,0 +1,146 @@
2018/07/02 test results and findings.
Test units:
COMP-Compro1997 An old Pentium ? from 1997, with ATI AGP VGA
COMP-IBMPS2-30 An old IBM PS/2 Model 30 (286) with VGA
COMP-P2ISA1997 An old Pentium II from 1997, with S3 VGA
COMP-IBM5150 An old IBM 5150, 8088, with CGA
COMP-Old486y91 An old 486SX 33MHz, with Tseng ET4000
DOSBox-X-1e6bb8dc469761d46217d44615c06a7ff95f2e49 DOSBox-X, by indicated commit
DOSLIB-848166fcacb6292773253273ef192ddae7942064 DOSLIB, by indicated commit
Equipment:
- Composite video capture (PEXHDCAP 1080p60). None of my Happauge USB capture
sticks were willing to capture the CGA composite video output for some reason,
nor would the Happauge WinTV in one of my machines. The PEXHDCAP was able to
but had curious brightness problems as screen contents changed.
- HDMI video capture (PEXHDCAP 1080p30)
- VGA to HDMI adapter (one that matches the mode and converts as-is)
- A mobile phone, pointed at the LCD TV set (second try, IBM 5150 test)
Software:
- DOSBox-X build:
git commit 1e6bb8dc469761d46217d44615c06a7ff95f2e49
- DOSLIB build:
git commit 848166fcacb6292773253273ef192ddae7942064
Findings:
- On the IBM 5150, The IBM BIOS (I think it dates from 1982) is indeed missing
the "number of rows - 1" value in the BIOS data area. This confirms comments
in TEST-FW\VIDEO\PC\TEST.C about how it may not exist according to the
definitions listed in IBM ROM BIOS source code from 1984, while the 1986
listing does list it.
- On the IBM 5150, INT 10h appears to have a bug where all CGA modes work, but
setting mode 7 produces a video mode with horizontal and vertical timing that
is incompatible with NTSC. During that part, neither my capture card nor the
LCD TV set would display anything.
Perhaps the bug, theoretically, is the application of MDA monitor timing for
INT 10h mode 7 even on CGA.
- The EGA palette assumed in 16-color modes didn't always match the TEST-FW
video's assumptions, but the differences are not jarring. They're understandable.
- In the 256-color mode test, three different attribute controller to DAC to
DAC mask behaviors were seen.
The most common, seen on all but two, is that the attribute controller appears
to affect both the low nibble and upper bits (high nibble?) of the 8-bit
color palette index.
When the test program flashes the attribute controller palette #1 for example,
it appears to affect not only every 16th color starting from #1, but also
colors #16-#31.
Generally, flashing attribute controller palette N affects:
Every 16th color starting at N
Colors (N * 16) to (N * 16 + 15)
This remapping needs more investigation on how exactly it works. This should
be done as a separate palette test program targeting only the VGA.
Results so far suggest that both the low nibble and high nibble are translated
through the attribute controller palette registers.
On the Tseng ET4000, the attribute controller only affects the low 4 bits.
It does not affect any of the higher bits.
Flashing attribute color palette N affects only every 16th color starting at N.
Finally, perhaps the most erroneous is DOSBox-X (and DOSBox SVN).
Due to optimizations around lazily updating only part of the color palette,
DOSBox-X only updates ONE color palette entry when the attribute controller
palette is flashing.
Flashing attribute controller palette N affects:
One color at DAC palette entry N
Questions to answer in further development:
For a separate program in TEST-FW\VIDEO\PC, focused on the VGA:
- How exactly does the attribute controller affect all 8 bits of 256-color pixels?
The TEST-FW\VIDEO\PC\TEST.C program only shows what happens when flashing the
attribute controller palette entry between it's initial value and 0x3F (if the
initial value is dimmer than neutral gray) or 0x00 (if brigher than gray).
- How do Attribute Controller registers 0x10 and 0x14 affect this mapping?
See http://www.osdever.net/FreeVGA/vga/attrreg.htm
These registers are documented to affect the color palette entry coming from
the attribute controller, bits 4-5 in one case, and bits 6-7 in non-256-color
modes.
Interesting to check: What happens if register 0x10 bit 6 (8-bit color enable)
is switched off in 256-color mode?
- How does the DAC mask (3C6h) affect the attribute controller, VGA palette,
various AC bits?
It's not clear where the DAC mask is applied, though as "Pel mask" it may be
at the final stage before conversion through the VGA palette. Test program
should confirm this.
Test routine ideas:
- Interactive mode to fiddle with attribute controller, color palette, and
attribute controller bits, with 256-color palette on screen to show effects.
- Non-interactive mode to run through combinations of these bits, for capture
and logging purposes.
Related demoscene capture ideas:
"Copper" (ftp.scene.org/pub/parties/1992/theparty92/demo/copper.zip)
- This demo uses VGA palette tricks that only seem to work in DOSBox-X and
are said only to work on Tseng ET4000AX cards.
Test on ET4000 card vs S3 and ATI to note where it works exactly.
Noted in the past is that on S3 and Paradise chipsets, the "line fading"
effects (explicitly said and during scrolling credits) show absolutely
nothing on-screen.
- This demo abuses the horizontal sync pulse in some parts to make the
picture "wobble", which causes modern VGA monitors and LCDS to switch off
instead. Pull out an old VGA CRT or two and see if the effect can be
recorded off the screen. Noted in past test runs, is that the effect
makes an audible though quiet "ringing" sound in the back of the picture
tube as the CRT tries to follow this "wobble" effect.

View File

@ -0,0 +1,116 @@
2018/07/05 test results and findings.
Test units:
COMP-IBMPS2-30 An old IBM PS/2 Model 30 (286) with VGA
DOSLIB-d7d079bfd75a71b4c4d5b2afc9efc5e69cefa152 DOSLIB, by indicated commit
Equipment:
- HDMI video capture (PEXHDCAP 1080p30)
- VGA to HDMI adapter (one that matches the mode and converts as-is)
Software:
- DOSLIB build:
git commit d7d079bfd75a71b4c4d5b2afc9efc5e69cefa152
Findings:
- VGA DAC test program shows straightforward attribute controller translation, as if
the 8-bit value is split into two 4-bit nibbles and translated on it's way through
the AC palette.
- Switching off 8BIT in the attribute controller shows a strange sort of 640x200
256-color mode, except that each pixel displayed looks as if half the value sent
to the DAC is loaded per pixel clock before becoming the full 8-bit value.
It's not certain yet whether the nibble value is loaded in or shifted in.
It's not certain yet which nibble is loaded first.
- Switching on the 8BIT in the attribute controller for any other video mode seems
to halve the video resolution (skip every other pixel) without any other effects.
- The "MONO" bit, listed on FreeVGA as apparently doing nothing, appears to influence
how the blink attribute is applied on it's way to the DAC.
- On an IBM PS/2 model 30 (VGA), the blink attribute can be switched on in any VGA
graphics mode, which then acts on bit 3 in all modes except 256-color mode where it
affects bit 3 and bit 7 (possibly related to the 4-bit 256-color shift behavior listed
above).
- If MONO=0, and graphics mode, the blink attribute seems to remap like this:
if (color >= 8) {
color = (color & 7) + (blink << 3);
}
else {
color |= 8;
}
- If MONO=1, or alphanumeric (text) mode, the blink attribute seems to remap like this:
color = (color & 7) + (blink << 3);
- Noted, according to VGA register snapshots, is that the BIOS sets MONO=0 for all modes except
mode 7 (80x25 mono text) and mode 15 (640x350 2-color graphics) where MONO=1.
- The DAC mask appears to apply after the Color Select register is applied to bits 7-6.
It also applies after application of Color Select applied to bits 5-4.
- Color Select bits 7-6 / 5-4 do not apply in 256-color mode (ignored). The bit to apply
bits 5-4 from Color Select (P54S) is ignored in 256-color mode. 256-color mode will
not apply any bits from Color Select.
- It appears the attribute controller palette translation (4-to-6) is done first, then
combined with Color Select, before being masked by DAC mask register 3C6h.
Other ideas to follow:
- Jim Leonard on Twitter wants to know if the vertical retrace interrupt works.
Ref: https://twitter.com/MobyGamer/status/1015097180883955712
Ref: https://www.vogons.org/viewtopic.php?t=58445
Questions to answer in further development:
- Is the blink attribute applied before or after the attribute palette remapping?
- What nibble is loaded first when 8BIT=0 in 256-color mode?
- What other VGA cards does this 256-color 8BIT=0 behavior occur, or more specifically,
what do clone cards do in this case?
- Is the value simply replaced a nibble at a time or is it shifted 4 bits and loaded?
- The Tseng ET4000, known to replace only the low 4 bits, should be re-tested with the
new code and to see what odd behaviors it has.
- Do other SVGA cards remap through the attribute controller in a way that the blink
attribute can affect the output in any mode?
- Regarding the vertical retrace interrupt, does it work on the PS/2?
- What other SVGA cards does the vertical retrace interrupt work on?
- Do these SVGA cards work as documented, or do they ignore certain behaviors, act different,
etc?
- What does the Tseng ET3000 do with the attribute controller palette? Is it the same as the
ET4000 or different?
- What does Color Select do on the ET3000/ET4000 cards? If you switch on the P54S bit in
256-color mode, what happens to the palette? Theoretically, according to COPPER.EXE, it
means the low 4 bits get translated by the attribute controller and the upper 4 bits
are replaced with the Color Select Register. Verify this on real hardware.
Ideas for further development:
- DOSLIB VGA test program to demonstrate vertical retrace interrupt, whether it's occurring,
whether it works as documented.

23
PULL_REQUEST_TEMPLATE.md Normal file
View File

@ -0,0 +1,23 @@
# Description
_Summary of changes brought by this PR._
**Does this PR address some issue(s) ?**
_Add the issue(s) fixed, e.g. ```#1234```_
**Does this PR introduce new feature(s) ?**
_Describe the feature(s) introduced._
**Are there any breaking changes ?**
_Describe the breaking changes in detail._
**Additional information**
_Add any additional information that may be useful._

49
appveyor.yml Normal file
View File

@ -0,0 +1,49 @@
#---------------------------------#
# general configuration #
#---------------------------------#
branches:
only:
- master
only_commits:
files:
- src\
- vs2015\
#---------------------------------#
# environment configuration #
#---------------------------------#
image: Visual Studio 2017
init:
- git config --global core.autocrlf true
#---------------------------------#
# build configuration #
#---------------------------------#
platform:
- x64
configuration: Release
build:
project: vs2015\dosbox-x.sln
after_build:
- ps : >-
$shortHash = $env:APPVEYOR_REPO_COMMIT.Substring(0, 7);
7z a dosbox-x-windows-$shortHash.zip C:\projects\dosbox-x\vs2015\..\bin\x64\Release\changelog.txt;
7z a dosbox-x-windows-$shortHash.zip C:\projects\dosbox-x\vs2015\..\bin\x64\Release\dosbox.reference.conf;
7z a dosbox-x-windows-$shortHash.zip C:\projects\dosbox-x\vs2015\..\bin\x64\Release\dosbox-x.exe;
7z a dosbox-x-windows-$shortHash.zip C:\projects\dosbox-x\vs2015\..\bin\x64\Release\FREECG98.BMP;
#---------------------------------#
# artifacts configuration #
#---------------------------------#
artifacts:
- path: dosbox-x-windows-*.zip
name: DOSBox-X Windows Build

View File

@ -1,5 +1,5 @@
dnl Init.
AC_INIT(dosbox-x,0.82.7,[https://github.com/joncampbell123/dosbox-x/issues],[],[http://dosbox-x.software])
AC_INIT(dosbox-x,0.82.8,[https://github.com/joncampbell123/dosbox-x/issues],[],[http://dosbox-x.software])
AC_PREREQ(2.60)
AC_CONFIG_SRCDIR(README)
@ -148,7 +148,7 @@ fi
CFLAGS="$CFLAGS -std=gnu11";
CXXFLAGS="$CXXFLAGS -std=gnu++0x";
dnl Yksoft1 wants a MinGW build for Windows that doesn't use the Windows menu system.
dnl yksoft1 wants a MinGW build for Windows that doesn't use the Windows menu system.
AH_TEMPLATE(C_FORCE_MENU_SDLDRAW,[Define to 1 to force SDL-drawn menus])
AC_ARG_ENABLE(force-menu-sdldraw,AC_HELP_STRING([--enable-force-menu-sdldraw],[Force SDL drawn menus]),enable_force_menu_sdldraw=yes)
@ -156,6 +156,18 @@ dnl This is how the build script can specify a HX DOS extender target
AH_TEMPLATE(C_HX_DOS,[Define to 1 to target HX DOS])
AC_ARG_ENABLE(hx-dos,AC_HELP_STRING([--enable-hx-dos],[Enable HX target]),enable_hx=yes)
dnl Optimize for speed by default
AC_ARG_ENABLE(optimize,AC_HELP_STRING([--disable-optimize],[Don't enable compiler optimizations]))
dnl FIXME: Remove default "-O2" set by some autotools versions. TODO: check availability of sed.
CFLAGS=["`echo $CFLAGS' ' | sed -e 's/-O[^ ]* //g'`"]
CXXFLAGS=["`echo $CXXFLAGS' ' | sed -e 's/-O[^ ]* //g'`"]
if test x$enable_optimize != xno; then
CFLAGS="$CFLAGS -O2"
CXXFLAGS="$CXXFLAGS -O2"
fi
dnl Some stuff for the icon.
case "$host" in
*-*-cygwin* | *-*-mingw32*)
@ -494,6 +506,14 @@ if test x$host = xi386-pc-os2-emx ; then
LIBS=$LIBS_BACKUP
fi
dnl FEATURE: xBRZ
AH_TEMPLATE(C_XBRZ,[Define to 1 to enable XBRZ scaler])
AC_ARG_ENABLE(xbrz,AC_HELP_STRING([--enable-xbrz],[compile with xBRZ scaler (default yes)]),enable_xbrz=$enableval,enable_xbrz=yes)
AM_CONDITIONAL(C_XBRZ, test "x$enable_xbrz" == "xyes")
if test x$enable_xbrz = xyes; then
AC_DEFINE(C_XBRZ,1)
fi
dnl FEATURE: MIDI through ALSA
AC_ARG_ENABLE(alsa-midi,
AC_HELP_STRING([--enable-alsa-midi],[compile with alsa midi support (default yes)]),
@ -794,10 +814,12 @@ src/libs/Makefile
src/libs/zmbv/Makefile
src/libs/gui_tk/Makefile
src/libs/porttalk/Makefile
src/output/Makefile
src/builtin/Makefile
src/misc/Makefile
src/shell/Makefile
src/platform/Makefile
src/xBRZ/Makefile
include/Makefile
dosbox-x.spec
make-rpm.sh

View File

@ -1,4 +1,4 @@
# This is the configuration file for DOSBox 0.82.7. (Please use the latest version of DOSBox)
# This is the configuration file for DOSBox 0.82.8. (Please use the latest version of DOSBox)
# Lines starting with a # are comment lines and are ignored by DOSBox.
# They are used to (briefly) document the effect of each option.
# To write out ALL options, use command 'config -all' with -wc or -writeconf options.
@ -80,38 +80,49 @@ pci=false
sst=false
[sdl]
# fullscreen: Start dosbox directly in fullscreen. (Press ALT-Enter to go back)
# fulldouble: Use double buffering in fullscreen. It can reduce screen flickering, but it can also result in a slow DOSBox.
# fullresolution: What resolution to use for fullscreen: original, desktop or a fixed size (e.g. 1024x768).
# Using your monitor's native resolution with aspect=true might give the best results.
# If you end up with small window on a large screen, try an output different from surface.
# windowresolution: Scale the window to this size IF the output device supports hardware scaling.
# (output=surface does not!)
# output: What video system to use for output.
# Possible values: surface, overlay, opengl, openglnb, openglhq, ddraw.
# autolock: Mouse will automatically lock, if you click on the screen. (Press CTRL-F10 to unlock)
# synced: Mouse position reported will be exactly where user hand has moved to.
# sensitivity: Mouse sensitivity.
# waitonerror: Wait before closing the console if dosbox has an error.
# priority: Priority levels for dosbox. Second entry behind the comma is for when dosbox is not focused/minimized.
# pause is only valid for the second entry.
# Possible values: lowest, lower, normal, higher, highest, pause.
# mapperfile: File used to load/save the key/event mappings from. Resetmapper only works with the default value.
# usescancodes: Avoid usage of symkeys, might not work on all operating systems.
# overscan: Width of overscan border (0 to 10). (works only if output=surface)
# titlebar: Change the string displayed in the DOSBox title bar.
# showmenu: Whether to show the menu bar (if supported). Default true.
# fullscreen: Start dosbox directly in fullscreen. (Press ALT-Enter to go back)
# fulldouble: Use double buffering in fullscreen. It can reduce screen flickering, but it can also result in a slow DOSBox.
# fullresolution: What resolution to use for fullscreen: original, desktop or a fixed size (e.g. 1024x768).
# Using your monitor's native resolution with aspect=true might give the best results.
# If you end up with small window on a large screen, try an output different from surface.
# windowresolution: Scale the window to this size IF the output device supports hardware scaling.
# (output=surface does not!)
# output: What video system to use for output.
# Possible values: surface, overlay, opengl, openglnb, openglhq, ddraw.
# autolock: Mouse will automatically lock, if you click on the screen. (Press CTRL-F10 to unlock)
# autolock_feedback: Autolock status feedback type, i.e. visual, auditive, none.
# Possible values: none, beep, flash.
# sensitivity: Mouse sensitivity.
# mouse_emulation: When is mouse emulated ?
# integration: when not locked
# locked: when locked
# always: every time
# never: at no time
# If disabled, the mouse position in DOSBox-X is exactly where the host OS reports it.
# When using a high DPI mouse, the emulation of mouse movement can noticeably reduce the
# sensitiveness of your device, i.e. the mouse is slower but more precise.
# Possible values: integration, locked, always, never.
# waitonerror: Wait before closing the console if dosbox has an error.
# priority: Priority levels for dosbox. Second entry behind the comma is for when dosbox is not focused/minimized.
# pause is only valid for the second entry.
# Possible values: lowest, lower, normal, higher, highest, pause.
# mapperfile: File used to load/save the key/event mappings from. Resetmapper only works with the default value.
# usescancodes: Avoid usage of symkeys, might not work on all operating systems.
# overscan: Width of overscan border (0 to 10). (works only if output=surface)
# titlebar: Change the string displayed in the DOSBox title bar.
# showmenu: Whether to show the menu bar (if supported). Default true.
fullscreen=false
fulldouble=false
fullresolution=desktop
windowresolution=original
output=surface
autolock=true
synced=false
autolock=false
autolock_feedback=beep
sensitivity=100
mouse_emulation=locked
waitonerror=true
priority=higher,normal
mapperfile=mapper-0.82.7.map
mapperfile=mapper-0.82.8.map
usescancodes=false
overscan=0
titlebar=
@ -128,6 +139,7 @@ showmenu=true
# bochs debug port e9: If set, emulate Bochs debug port E9h. ASCII text written to this I/O port is assumed to be debug output, and logged.
# machine: The type of machine DOSBox tries to emulate.
# Possible values: hercules, cga, cga_mono, cga_rgb, cga_composite, cga_composite2, tandy, pcjr, ega, vgaonly, svga_s3, svga_et3000, svga_et4000, svga_paradise, vesa_nolfb, vesa_oldvbe, amstrad, pc98, pc9801, pc9821, fm_towns.
# svga lfb base: If nonzero, define the physical memory address of the linear framebuffer.
# vmemdelay: VGA Memory I/O delay in nanoseconds. Set to -1 to use default, 0 to disable.
# Default off. Enable this option (-1 or nonzero) if you are running a game or
# demo that needs slower VGA memory (like that of older ISA hardware) to work properly.
@ -165,6 +177,18 @@ showmenu=true
# It is discarded when you boot into another OS. Mainline DOSBox uses 32KB. Testing shows that it is possible
# to run DOSBox with as little as 4KB. If DOSBox-X aborts with error "not enough memory for internal tables"
# then you need to increase this value.
# vga attribute controller mapping: This affects how the attribute controller maps colors, especially in 256-color mode.
# Some SVGA cards handle the attribute controller palette differently than most SVGA cards.
# auto Automatically pick the mapping based on the SVGA chipset.
# 4x4 Split into two 4-bit nibbles, map through AC, recombine. This is standard VGA behavior including clone SVGA cards.
# 4low Split into two 4-bit nibbles, remap only the low 4 bits, recombine. This is standard ET4000 behavior.
#
# NOTES:
# Demoscene executable 'COPPER.EXE' requires the '4low' behavior in order to display line-fading effects
# (including scrolling credits) correctly, else those parts of the demo show up as a blank screen.
#
# 4low behavior is default for ET4000 emulation.
# Possible values: , auto, 4x4, 4low, first16.
# a20: A20 gate emulation mode.
# The on/off/on_fake/off_fake options are intended for testing and debugging DOS development,
# or to emulate obscure hardware, or to work around potential extended memory problems with DOS programs.
@ -344,6 +368,11 @@ showmenu=true
# This does not affect the linear framebuffer's location. It only affects the linear framebuffer
# location reported by the VESA BIOS. Set to nonzero for DOS games with sloppy VESA graphics pointer management.
# MFX "Melvindale" (1996): Set this option to 2 to center the picture properly.
# vesa map non-lfb modes to 128kb region: If set, VESA BIOS SVGA modes will be set to map 128KB of video memory to A0000-BFFFF instead of
# 64KB at A0000-AFFFF. This does not affect the SVGA window size or granularity.
# Some games or demoscene productions assume that they can render into the next SVGA window/bank
# by writing to video memory beyond the current SVGA window address and will not appear correctly
# without this option.
# allow hpel effects: If set, allow the DOS demo or program to change the horizontal pel (panning) register per scanline.
# Some early DOS demos use this to create waving or sinus effects on the picture. Not very many VGA
# chipsets allow this, so far, only ATI chipsets are known to support this effect. Disabled by default.
@ -400,6 +429,7 @@ keyboard hook=false
weitek=false
bochs debug port e9=false
machine=svga_s3
svga lfb base=0
vmemdelay=0
vmemsize=2
vmemsizekb=0
@ -408,6 +438,7 @@ capture chroma format=auto
capture format=default
shell environment size=0
private area size=32768
vga attribute controller mapping=auto
a20=fast
turn off a20 gate on boot=true
isa bus clock=std8.3
@ -473,6 +504,7 @@ rom bios 8x8 CGA font=true
rom bios video parameter table=true
allow more than 640kb base memory=false
vesa lfb base scanline adjust=0
vesa map non-lfb modes to 128kb region=false
allow hpel effects=false
allow hretrace effects=false
hretrace effect weight=4.00
@ -497,24 +529,42 @@ vga palette update on full load=true
ignore odd-even mode in non-cga modes=false
[render]
# frameskip: How many frames DOSBox skips before drawing one.
# aspect: Do aspect correction, if your output method doesn't support scaling this can slow things down!.
# char9: Allow 9-pixel wide text mode fonts.
# doublescan: If set, doublescanned output emits two scanlines for each source line, in the
# same manner as the actual VGA output (320x200 is rendered as 640x400 for example).
# If clear, doublescanned output is rendered at the native source resolution (320x200 as 320x200).
# This affects the raster PRIOR to the software or hardware scalers. Choose wisely.
#
# scaler: Scaler used to enlarge/enhance low resolution modes. If 'forced' is appended,
# then the scaler will be used even if the result might not be desired.
# Possible values: none, normal2x, normal3x, normal4x, normal5x, advmame2x, advmame3x, advinterp2x, advinterp3x, hq2x, hq3x, 2xsai, super2xsai, supereagle, tv2x, tv3x, rgb2x, rgb3x, scan2x, scan3x, hardware_none, hardware2x, hardware3x, hardware4x, hardware5x.
# autofit: Best fits image to window
# - Intended for output=direct3d, fullresolution=original, aspect=true
# frameskip: How many frames DOSBox skips before drawing one.
# aspect: Aspect ratio correction mode. Can be set to the following values:
# 'false' (default):
# 'direct3d'/opengl outputs: image is simply scaled to full window/fullscreen size, possibly resulting in disproportional image
# 'surface' output: it does no aspect ratio correction (default), resulting in disproportional images if VGA mode pixel ratio is not 4:3
# 'true':
# 'direct3d'/opengl outputs: uses output driver functions to scale / pad image with black bars, correcting output to proportional 4:3 image
# In most cases image degradation should not be noticeable (it all depends on the video adapter and how much the image is upscaled).
# Should have none to negligible impact on performance, mostly being done in hardware
# 'surface' output: inherits old DOSBox aspect ratio correction method (adjusting rendered image line count to correct output to 4:3 ratio)
# Due to source image manipulation this mode does not mix well with scalers, i.e. multiline scalers like hq2x/hq3x will work poorly
# Slightly degrades visual image quality. Has a tiny impact on performance
# When using xBRZ scaler with 'surface' output, aspect ratio correction is done by the scaler itself, so none of the above apply
# Possible values: false, true, 0, 1, yes, no, nearest, bilinear.
# char9: Allow 9-pixel wide text mode fonts.
# doublescan: If set, doublescanned output emits two scanlines for each source line, in the
# same manner as the actual VGA output (320x200 is rendered as 640x400 for example).
# If clear, doublescanned output is rendered at the native source resolution (320x200 as 320x200).
# This affects the raster PRIOR to the software or hardware scalers. Choose wisely.
#
# scaler: Scaler used to enlarge/enhance low resolution modes. If 'forced' is appended,
# then the scaler will be used even if the result might not be desired.
# Possible values: none, normal2x, normal3x, normal4x, normal5x, advmame2x, advmame3x, advinterp2x, advinterp3x, hq2x, hq3x, 2xsai, super2xsai, supereagle, tv2x, tv3x, rgb2x, rgb3x, scan2x, scan3x, hardware_none, hardware2x, hardware3x, hardware4x, hardware5x, xbrz, xbrz_bilinear.
# xbrz slice: Number of screen lines to process in single xBRZ scaler taskset task, affects xBRZ performance, 16 is the default
# xbrz fixed scale factor: To use fixed xBRZ scale factor (i.e. to attune performance), set it to 2-6, 0 - use automatic calculation (default)
# xbrz max scale factor: To cap maximum xBRZ scale factor used (i.e. to attune performance), set it to 2-6, 0 - use scaler allowed maximum (default)
# autofit: Best fits image to window
# - Intended for output=direct3d, fullresolution=original, aspect=true
frameskip=0
aspect=false
char9=true
doublescan=true
scaler=normal2x
xbrz slice=16
xbrz fixed scale factor=0
xbrz max scale factor=0
autofit=true
[vsync]
@ -630,10 +680,18 @@ realbig16=false
# allow output port reset: If set (default), allow the application to reset the CPU through the keyboard controller.
# This option is required to allow Windows ME to reboot properly, whereas Windows 9x and earlier
# will reboot without this option using INT 19h
# controllertype: Type of keyboard controller (and keyboard) attached.
# auto Automatically pick according to machine type
# at AT (PS/2) type keyboard
# xt IBM PC/XT type keyboard
# pcjr IBM PCjr type keyboard (only if machine=pcjr)
# pc98 PC-98 keyboard emulation (only if machine=pc98)
# Possible values: auto, at, xt, pcjr, pc98.
# auxdevice: Type of PS/2 mouse attached to the AUX port
# Possible values: none, 2button, 3button, intellimouse, intellimouse45.
aux=true
allow output port reset=true
controllertype=auto
auxdevice=intellimouse
[pci]
@ -874,6 +932,14 @@ io port aliasing=true
# Enable this option for loud music if you want a more pleasing rendition without saturation and distortion.
# unmask dma: Start the DOS virtual machine with the DMA channel already unmasked at the controller.
# Use this for DOS applications that expect to operate the GUS but forget to unmask the DMA channel.
# pic unmask irq: Start the DOS virtual machine with the GUS IRQ already unmasked at the PIC.
# startup initialized: If set, start the GF1 in a fully initialized state (as if ULTRINIT had been run).
# If clear, leave the card in an uninitialized state (as if cold boot).
# Some DOS games or demoscene productions will hang or fail to use the Ultrasound hardware
# because they assume the card is initialized and their hardware detect does not fully initialize the card.
# dma enable on dma control polling: If set, automatically enable GUS DMA transfer bit in specific cases when the DMA control register is being polled.
# THIS IS A HACK. Some games and demoscene productions need this hack to avoid hanging while uploading sample data
# to the Gravis Ultrasound due to bugs in their implementation.
# clear dma tc irq if excess polling: If the DOS application is seen polling the IRQ status register rapidly, automatically clear the DMA TC IRQ status.
# This is a hack that should only be used with DOS applications that need it to avoid bugs in their GUS support code.
# Needed for:
@ -910,6 +976,9 @@ io port aliasing=true
gus=false
autoamp=false
unmask dma=false
pic unmask irq=false
startup initialized=false
dma enable on dma control polling=false
clear dma tc irq if excess polling=false
force master irq enable=false
gus panning table=default

View File

@ -123,6 +123,14 @@
#define BIOS_KEYBOARD_FLAGS3_ID_READ_IN_PROCESS (1 << 7)
#define BIOS_KEYBOARD_LEDS 0x497
#define BIOS_KEYBOARD_LEDS_SCROLL_LOCK (1 << 0)
#define BIOS_KEYBOARD_LEDS_NUM_LOCK (1 << 1)
#define BIOS_KEYBOARD_LEDS_CAPS_LOCK (1 << 2)
#define BIOS_KEYBOARD_LEDS_CIRCUS (1 << 3)
#define BIOS_KEYBOARD_LEDS_ACK (1 << 4)
#define BIOS_KEYBOARD_LEDS_RESEND (1 << 5)
#define BIOS_KEYBOARD_LEDS_MODE (1 << 6)
#define BIOS_KEYBOARD_LEDS_TRANSMIT_ERROR (1 << 7)
#define BIOS_WAIT_FLAG_POINTER 0x498
#define BIOS_WAIT_FLAG_COUNT 0x49c
@ -184,6 +192,12 @@ void BIOS_SetLPTPort (Bitu port, Bit16u baseaddr);
// \brief Synchronizes emulator num lock state with host.
void BIOS_SynchronizeNumLock();
// \brief Synchronizes emulator caps lock state with host.
void BIOS_SynchronizeCapsLock();
// \brief Synchronizes emulator scroll lock state with host.
void BIOS_SynchronizeScrollLock();
bool ISAPNP_RegisterSysDev(const unsigned char *raw,Bitu len,bool already=false);
class ISAPnPDevice {

View File

@ -1,3 +1,3 @@
/*auto-generated*/
#define UPDATED_STR "Jun 27, 2018 11:42:01am"
#define UPDATED_STR "Jul 20, 2018 12:39:13pm"
#define COPYRIGHT_END_YEAR "2018"

View File

@ -682,14 +682,11 @@ extern DOS_InfoBlock dos_infoblock;
struct DOS_Block {
DOS_Date date;
bool hostdate;
DOS_Version version;
Bit16u firstMCB;
Bit16u errorcode;
Bit16u psp();//{return DOS_SDA(DOS_SDA_SEG,DOS_SDA_OFS).GetPSP();};
void psp(Bit16u _seg);//{ DOS_SDA(DOS_SDA_SEG,DOS_SDA_OFS).SetPSP(_seg);};
Bit16u env;
RealPt cpmentry;
RealPt dta();//{return DOS_SDA(DOS_SDA_SEG,DOS_SDA_OFS).GetDTA();};
void dta(RealPt _dta);//{DOS_SDA(DOS_SDA_SEG,DOS_SDA_OFS).SetDTA(_dta);};
Bit8u return_code,return_mode;

View File

@ -43,6 +43,7 @@ void Mouse_ButtonPressed(Bit8u button);
void Mouse_ButtonReleased(Bit8u button);
void Mouse_AutoLock(bool enable);
bool Mouse_IsLocked();
void Mouse_NewVideoMode(void);
#endif

View File

@ -31,10 +31,13 @@
//Enable this for scalers to support 0 input for empty lines
//#define RENDER_NULL_INPUT
enum SCREEN_TYPES {
SCREEN_SURFACE,
SCREEN_OPENGL,
SCREEN_DIRECT3D
enum ASPECT_MODES {
ASPECT_FALSE = 0
,ASPECT_TRUE
#if C_SURFACE_POSTRENDER_ASPECT
,ASPECT_NEAREST
,ASPECT_BILINEAR
#endif
};
typedef struct {
@ -87,12 +90,11 @@ typedef struct {
Bitu cachePitch;
Bit8u *cacheRead;
Bitu inHeight, inLine, outLine;
bool xBRZ;
} scale;
RenderPal_t pal;
RenderPal_t pal;
bool updating;
bool active;
bool aspect;
int aspect;
bool aspectOffload;
bool fullFrame;
bool forceUpdate;

175
include/sdlmain.h Normal file
View File

@ -0,0 +1,175 @@
#include "dosbox.h"
#include "control.h"
#include "menu.h"
#include "mouse.h"
#include "render.h"
#include "video.h"
#include "cross.h"
#include "SDL.h"
#include "SDL_video.h"
#ifdef __WIN32__
#include "SDL_syswm.h"
#endif
#ifndef DOSBOX_SDLMAIN_H
#define DOSBOX_SDLMAIN_H
enum SCREEN_TYPES {
SCREEN_SURFACE
,SCREEN_OPENGL // [FIXME] cannot make this conditional because somehow SDL2 code uses it while C_OPENGL is definitely disabled by C_SDL2 so SCREEN_OPENGL is unavailable
#if C_DIRECT3D
,SCREEN_DIRECT3D
#endif
};
enum AUTOLOCK_FEEDBACK
{
AUTOLOCK_FEEDBACK_NONE,
AUTOLOCK_FEEDBACK_BEEP,
AUTOLOCK_FEEDBACK_FLASH
};
enum PRIORITY_LEVELS {
PRIORITY_LEVEL_PAUSE,
PRIORITY_LEVEL_LOWEST,
PRIORITY_LEVEL_LOWER,
PRIORITY_LEVEL_NORMAL,
PRIORITY_LEVEL_HIGHER,
PRIORITY_LEVEL_HIGHEST
};
// do not specify any defaults inside, it is zeroed at start of main()
struct SDL_Block {
bool inited;
bool active; // if this isn't set don't draw
bool updating;
#if defined(C_SDL2)
bool update_window;
bool update_display_contents;
int window_desired_width, window_desired_height;
#endif
struct {
Bit32u width;
Bit32u height;
Bit32u bpp;
Bitu flags;
double scalex, scaley;
GFX_CallBack_t callback;
} draw;
bool wait_on_error;
struct {
struct {
Bit16u width, height;
bool fixed;
bool display_res;
} full;
struct {
Bit16u width, height;
} window;
Bit8u bpp;
#if defined(C_SDL2)
Bit32u pixelFormat;
#endif
bool fullscreen;
bool lazy_fullscreen;
bool prevent_fullscreen;
bool lazy_fullscreen_req;
bool doublebuf;
SCREEN_TYPES type;
SCREEN_TYPES want_type;
} desktop;
struct {
SDL_Surface * surface;
#if (HAVE_DDRAW_H) && defined(WIN32)
RECT rect;
#endif
} blit;
struct {
PRIORITY_LEVELS focus;
PRIORITY_LEVELS nofocus;
} priority;
SDL_Rect clip;
SDL_Surface * surface;
#if defined(C_SDL2)
SDL_Window * window;
SDL_Renderer * renderer;
const char * rendererDriver;
int displayNumber;
struct {
SDL_Texture * texture;
SDL_PixelFormat * pixelFormat;
} texture;
#endif
SDL_cond *cond;
struct {
bool autolock;
AUTOLOCK_FEEDBACK autolock_feedback;
bool autoenable;
bool requestlock;
bool locked;
Bitu sensitivity;
MOUSE_EMULATION emulation;
} mouse;
SDL_Rect updateRects[1024];
Bitu overscan_color;
Bitu overscan_width;
Bitu num_joysticks;
#if defined (WIN32)
bool using_windib;
#endif
// state of alt-keys for certain special handlings
Bit16u laltstate;
Bit16u raltstate;
bool must_redraw_all;
bool deferred_resize;
bool init_ignore;
unsigned int gfx_force_redraw_count;
struct {
int x;
int y;
double xToY;
double yToX;
} srcAspect;
#if C_SURFACE_POSTRENDER_ASPECT
std::vector<uint32_t> aspectbuf;
#endif
};
#if defined(WIN32) && !defined(C_SDL2)
extern "C" unsigned int SDL1_hax_inhibit_WM_PAINT;
#endif
extern Bitu frames;
extern SDL_Block sdl;
#include <output/output_surface.h>
#include <output/output_direct3d.h>
#include <output/output_opengl.h>
#include <output/output_tools.h>
#include <output/output_tools_xbrz.h>
#include "zipfile.h"
extern Bitu userResizeWindowWidth;
extern Bitu userResizeWindowHeight;
extern Bitu currentWindowWidth;
extern Bitu currentWindowHeight;
extern ZIPFile savestate_zip;
void GFX_DrawSDLMenu(DOSBoxMenu &menu, DOSBoxMenu::displaylist &dl);
void GFX_LogSDLState(void);
void GFX_SDL_Overscan(void);
void GFX_SetIcon(void);
void SDL_rect_cliptoscreen(SDL_Rect &r);
void UpdateWindowDimensions(void);
void UpdateWindowDimensions(Bitu width, Bitu height);
#if defined(C_SDL2)
SDL_Window* GFX_SetSDLWindowMode(Bit16u width, Bit16u height, SCREEN_TYPES screenType);
#endif
#endif /*DOSBOX_SDLMAIN_H*/

View File

@ -312,6 +312,8 @@ enum vm_event {
VM_EVENT_DOS_EXIT_REBOOT_KERNEL=15, // DOS kernel has just finished exiting (hard reset)
VM_EVENT_DOS_SURPRISE_REBOOT, // DOS kernel asked to boot, when apparently having never been shut down (jmp to FFFF:0000)
VM_EVENT_SAVE_STATE, // Save state in progress. Callback handler should refer to global object to write it's state to.
VM_EVENT_LOAD_STATE, // Loading a save state in progress. Callback handler should refer to global object to read state from.
VM_EVENT_MAX
};

View File

@ -27,6 +27,8 @@
#define VGA_LFB_MAPPED
#define S3_LFB_BASE_DEFAULT 0xE0000000u
class PageHandler;
enum VGAModes {
@ -478,6 +480,10 @@ void VGA_ATTR_SetPalette(Bit8u index,Bit8u val);
typedef enum {CGA, EGA, MONO} EGAMonitorMode;
typedef enum {AC_4x4, AC_low4/*4low*/} ACPalRemapMode;
extern unsigned char VGA_AC_remap;
void VGA_ATTR_SetEGAMonitorPalette(EGAMonitorMode m);
/* The VGA Subfunction startups */

View File

@ -87,7 +87,14 @@ void MAPPER_UpdateJoysticks(void);
#endif
/* Mouse related */
//! \brief Toggles mouse capture.
void GFX_CaptureMouse(void);
//! \brief Sets mouse capture state manually.
void GFX_CaptureMouse(bool capture);
//! \brief Notifies mouse capture according current state.
void CaptureMouseNotify();
//! \brief Notifies mouse capture according specific state.
void CaptureMouseNotify(bool capture);
extern bool mouselocked; //true if mouse is confined to window
#endif

82
include/zipcrc.h Normal file
View File

@ -0,0 +1,82 @@
/**
* \file zipcrc.h
* Functions and types for CRC checks.
*
* Generated on Sat Jul 29 13:31:06 2017,
* by pycrc v0.9, https://pycrc.org
* using the configuration:
* Width = 32
* Poly = 0x04c11db7
* Xor_In = 0xffffffff
* ReflectIn = True
* Xor_Out = 0xffffffff
* ReflectOut = True
* Algorithm = table-driven
*****************************************************************************/
#ifndef __ZIPCRC_H__
#define __ZIPCRC_H__
#include <stdlib.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* The definition of the used algorithm.
*
* This is not used anywhere in the generated code, but it may be used by the
* application code to call algoritm-specific code, is desired.
*****************************************************************************/
#define CRC_ALGO_TABLE_DRIVEN 1
/**
* The type of the CRC values.
*
* This type must be big enough to contain at least 32 bits.
*****************************************************************************/
typedef uint_fast32_t zipcrc_t;
/**
* Calculate the initial crc value.
*
* \return The initial crc value.
*****************************************************************************/
static inline zipcrc_t zipcrc_init(void)
{
return 0xffffffff;
}
/**
* Update the crc value with new data.
*
* \param crc The current crc value.
* \param data Pointer to a buffer of \a data_len bytes.
* \param data_len Number of bytes in the \a data buffer.
* \return The updated crc value.
*****************************************************************************/
zipcrc_t zipcrc_update(zipcrc_t crc, const void *data, size_t data_len);
/**
* Calculate the final crc value.
*
* \param crc The current crc value.
* \return The final crc value.
*****************************************************************************/
static inline zipcrc_t zipcrc_finalize(zipcrc_t crc)
{
return crc ^ 0xffffffff;
}
#ifdef __cplusplus
} /* closing brace for extern "C" */
#endif
#endif /* __ZIPCRC_H__ */

137
include/zipfile.h Normal file
View File

@ -0,0 +1,137 @@
#ifndef ZIPFILE_H
#define ZIPFILE_H
#include <stdint.h>
extern "C" {
#include "zipcrc.h"
}
#include <map>
#pragma pack(push,1)
struct ZIPLocalFileHeader { /* ZIP File Format Specification v6.3.4 sec 4.3.7 Local file header */
uint32_t local_file_header_signature; /* +0x00 0x04034b50 */
uint16_t version_needed_to_extract; /* +0x04 */
uint16_t general_purpose_bit_flag; /* +0x06 */
uint16_t compression_method; /* +0x08 */
uint16_t last_mod_file_time; /* +0x0A */
uint16_t last_mod_file_date; /* +0x0C */
uint32_t crc_32; /* +0x0E */
uint32_t compressed_size; /* +0x12 */
uint32_t uncompressed_size; /* +0x16 */
uint16_t file_name_length; /* +0x1A */
uint16_t extra_field_length; /* +0x1C */
}; /* =0x1E */
#pragma pack(pop)
#pragma pack(push,1)
# define PKZIP_CENTRAL_DIRECTORY_HEADER_SIG (0x02014B50UL)
struct pkzip_central_directory_header_main { /* PKZIP APPNOTE 2.0: General Format of a ZIP file section C */
uint32_t sig; /* 4 bytes +0x00 0x02014B50 = 'PK\x01\x02' */
uint16_t version_made_by; /* 2 bytes +0x04 version made by */
uint16_t version_needed_to_extract; /* 2 bytes +0x06 version needed to extract */
uint16_t general_purpose_bit_flag; /* 2 bytes +0x08 general purpose bit flag */
uint16_t compression_method; /* 2 bytes +0x0A compression method */
uint16_t last_mod_file_time; /* 2 bytes +0x0C */
uint16_t last_mod_file_date; /* 2 bytes +0x0E */
uint32_t crc32; /* 4 bytes +0x10 */
uint32_t compressed_size; /* 4 bytes +0x14 */
uint32_t uncompressed_size; /* 4 bytes +0x18 */
uint16_t filename_length; /* 2 bytes +0x1C */
uint16_t extra_field_length; /* 2 bytes +0x1E */
uint16_t file_comment_length; /* 2 bytes +0x20 */
uint16_t disk_number_start; /* 2 bytes +0x22 */
uint16_t internal_file_attributes; /* 2 bytes +0x24 */
uint32_t external_file_attributes; /* 4 bytes +0x26 */
uint32_t relative_offset_of_local_header;/* 4 bytes +0x2A */
}; /* =0x2E */
/* filename and extra field follow, then file data */
#pragma pack(pop)
#pragma pack(push,1)
# define PKZIP_CENTRAL_DIRECTORY_END_SIG (0x06054B50UL)
struct pkzip_central_directory_header_end { /* PKZIP APPNOTE 2.0: General Format of a ZIP file section C */
uint32_t sig; /* 4 bytes +0x00 0x06054B50 = 'PK\x05\x06' */
uint16_t number_of_this_disk; /* 2 bytes +0x04 */
uint16_t number_of_disk_with_start_of_central_directory;
/* 2 bytes +0x06 */
uint16_t total_number_of_entries_of_central_dir_on_this_disk;
/* 2 bytes +0x08 */
uint16_t total_number_of_entries_of_central_dir;
/* 2 bytes +0x0A */
uint32_t size_of_central_directory; /* 4 bytes +0x0C */
uint32_t offset_of_central_directory_from_start_disk;
/* 4 bytes +0x10 */
uint16_t zipfile_comment_length; /* 2 bytes +0x14 */
}; /* =0x16 */
/* filename and extra field follow, then file data */
#pragma pack(pop)
class ZIPFile;
class ZIPFileEntry {
public:
bool can_write = false;
off_t file_length = 0;
off_t file_offset = 0;
off_t file_header_offset = 0;
off_t position = 0;
std::string name;
ZIPFile* file = NULL;
zipcrc_t write_crc = 0;
public:
bool rewind(void);
int read(void *buffer,size_t count);
int write(const void *buffer,size_t count);
private: /* encourage code that uses this C++ class to stream-read so that
this code can add deflate compression support later without pain and hacks */
off_t seek_file(off_t pos);
};
class ZIPFile {
public:
int file_fd = -1;
std::string filename;
std::map<std::string,ZIPFileEntry> entries;
off_t write_pos = 0;
bool can_write = false;
bool wrote_trailer = false;
std::string current_entry; /* currently writing entry */
public:
ZIPFile();
~ZIPFile();
public:
void close(void);
ZIPFileEntry *get_entry(const char *name);
ZIPFileEntry *new_entry(const char *name);
off_t end_of_file(void);
void close_current(void);
int open(const char *path,int mode);
off_t seek_file(off_t pos);
int read(void *buffer,size_t count);
int write(const void *buffer,size_t count);
void writeZIPFooter(void);
};
class zip_nv_pair_map : public std::map<std::string, std::string> {
public:
zip_nv_pair_map();
zip_nv_pair_map(ZIPFileEntry &ent);
public:
std::string &get(const char *name);
bool get_bool(const char *name);
long get_long(const char *name);
unsigned long get_ulong(const char *name);
void process_line(char *line/*will modify, assume caller has put NUL at the end*/);
void read_nv_pairs(ZIPFileEntry &ent);
};
void zip_nv_write(ZIPFileEntry &ent,const char *name,bool val);
void zip_nv_write(ZIPFileEntry &ent,const char *name,long val);
void zip_nv_write_hex(ZIPFileEntry &ent,const char *name,unsigned long val);
#endif //ZIPFILE_H

View File

@ -1,6 +1,6 @@
AM_CPPFLAGS = -I$(top_srcdir)/include "-DRESDIR=\"$(resdir)\""
SUBDIRS = cpu debug dos fpu gui hardware libs ints misc shell builtin platform mt32 aviwriter
SUBDIRS = cpu debug dos fpu gui hardware libs ints misc shell builtin platform mt32 aviwriter output
bin_PROGRAMS = dosbox-x
@ -15,6 +15,10 @@ if HAVE_WINDRES
ico_stuff = winres.rc
endif
if C_XBRZ
SUBDIRS += xBRZ
endif
.rc.o:
$(WINDRES) -o $@ $<
@ -22,7 +26,12 @@ dosbox_x_SOURCES = dosbox.cpp $(ico_stuff)
dosbox_x_LDADD = debug/libdebug.a dos/libdos.a shell/libshell.a builtin/libbuiltin.a \
ints/libints.a misc/libmisc.a hardware/serialport/libserial.a hardware/parport/libparallel.a \
libs/porttalk/libporttalk.a gui/libgui.a libs/gui_tk/libgui_tk.a hardware/libhardware.a \
cpu/libcpu.a hardware/reSID/libresid.a fpu/libfpu.a gui/libgui.a aviwriter/libaviwriter.a
cpu/libcpu.a hardware/reSID/libresid.a fpu/libfpu.a gui/libgui.a aviwriter/libaviwriter.a \
output/liboutput.a
if C_XBRZ
dosbox_x_LDADD += xBRZ/libxbrz.a
endif
if C_MT32
dosbox_x_LDADD += mt32/libmt32.a

View File

@ -331,8 +331,19 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_
return (use_cb?0x13:0x0f);
case CB_IRQ1: // keyboard int9
phys_writeb(physAddress+0x00,(Bit8u)0x50); // push ax
phys_writew(physAddress+0x01,(Bit16u)0x60e4); // in al, 0x60
if (IS_PC98_ARCH) {
if (machine == MCH_PCJR || IS_PC98_ARCH) {
/* NTS: NEC PC-98 does not have keyboard input on port 60h, it's a 8251 UART elsewhere.
*
* IBM PCjr reads the infared input on NMI interrupt, which then calls INT 48h to
* translate to IBM PC/XT scan codes before passing AL directly to IRQ1 (INT 9).
* PCjr keyboard handlers, including games made for the PCjr, assume the scan code
* is in AL and do not read the I/O port */
phys_writew(physAddress+0x01,(Bit16u)0x9090); // nop, nop
}
else {
phys_writew(physAddress+0x01,(Bit16u)0x60e4); // in al, 0x60
}
if (IS_PC98_ARCH || IS_TANDY_ARCH) {
phys_writew(physAddress+0x03,(Bit16u)0x9090); // nop, nop
phys_writeb(physAddress+0x05,(Bit8u)0x90); // nop
phys_writew(physAddress+0x06,(Bit16u)0x9090); // nop, nop (PC-98 does not have INT 15h keyboard hook)
@ -344,7 +355,7 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_
}
if (use_cb) {
if (IS_PC98_ARCH)
if (IS_PC98_ARCH || IS_TANDY_ARCH)
phys_writew(physAddress+0x08,(Bit16u)0x9090); // nop nop
else
phys_writew(physAddress+0x08,(Bit16u)0x0473); // jc skip

View File

@ -32,13 +32,15 @@
#include "lazyflags.h"
#include "support.h"
#include "control.h"
#include "config.h"
#include "zipfile.h"
#if defined(_MSC_VER)
/* we don't care about switch statements with no case labels */
#pragma warning(disable:4065)
#endif
extern ZIPFile savestate_zip;
/* caution: do not uncomment unless you want a lot of spew */
//#define CPU_DEBUG_SPEW
@ -3395,23 +3397,111 @@ void CPU_OnSectionPropChange(Section *x) {
if (test != NULL) test->Change_Config(x);
}
bool CoreRequiresMmap(void) {
#if defined(LINUX)
if (cpudecoder == &CPU_Core_Ptrace_Run)
return true;
#endif
void CPU_LoadState(Section *sec) {
(void)sec;//UNUSED
return false;
/* STOP THE CPU */
CPU_Cycles = CPU_CycleLeft = 0;
{
ZIPFileEntry *ent = savestate_zip.get_entry("cpureg.txt");
if (ent != NULL) {
zip_nv_pair_map nv(*ent);
reg_eax = nv.get_ulong("eax");
reg_ebx = nv.get_ulong("ebx");
reg_ecx = nv.get_ulong("ecx");
reg_edx = nv.get_ulong("edx");
reg_esi = nv.get_ulong("esi");
reg_edi = nv.get_ulong("edi");
reg_ebp = nv.get_ulong("ebp");
reg_esp = nv.get_ulong("esp");
reg_eip = nv.get_ulong("eip");
reg_flags = nv.get_ulong("eflags");
Segs.val[es] = nv.get_ulong("es.val");
Segs.phys[es] = nv.get_ulong("es.phys");
Segs.limit[es] = nv.get_ulong("es.limit");
Segs.expanddown[es] = nv.get_bool("es.expanddown");
Segs.val[cs] = nv.get_ulong("cs.val");
Segs.phys[cs] = nv.get_ulong("cs.phys");
Segs.limit[cs] = nv.get_ulong("cs.limit");
Segs.expanddown[cs] = nv.get_bool("cs.expanddown");
Segs.val[ss] = nv.get_ulong("ss.val");
Segs.phys[ss] = nv.get_ulong("ss.phys");
Segs.limit[ss] = nv.get_ulong("ss.limit");
Segs.expanddown[ss] = nv.get_bool("ss.expanddown");
Segs.val[ds] = nv.get_ulong("ds.val");
Segs.phys[ds] = nv.get_ulong("ds.phys");
Segs.limit[ds] = nv.get_ulong("ds.limit");
Segs.expanddown[ds] = nv.get_bool("ds.expanddown");
Segs.val[fs] = nv.get_ulong("fs.val");
Segs.phys[fs] = nv.get_ulong("fs.phys");
Segs.limit[fs] = nv.get_ulong("fs.limit");
Segs.expanddown[fs] = nv.get_bool("fs.expanddown");
Segs.val[gs] = nv.get_ulong("gs.val");
Segs.phys[gs] = nv.get_ulong("gs.phys");
Segs.limit[gs] = nv.get_ulong("gs.limit");
Segs.expanddown[gs] = nv.get_bool("gs.expanddown");
/* CPU state includes other variables based on flags, update them */
CPU_SetFlags(reg_flags, FMASK_ALL);
}
}
}
void CPU_PreInit() {
Section_prop * section=static_cast<Section_prop *>(control->GetSection("cpu"));
std::string core(section->Get_string("core"));
void CPU_SaveState(Section *sec) {
(void)sec;//UNUSED
#if defined(LINUX)
if (core == "ptrace")
cpudecoder=&CPU_Core_Ptrace_Run;
#endif
{
ZIPFileEntry *ent = savestate_zip.new_entry("cpureg.txt");
if (ent != NULL) {
zip_nv_write_hex(*ent,"eax", reg_eax);
zip_nv_write_hex(*ent,"ebx", reg_ebx);
zip_nv_write_hex(*ent,"ecx", reg_ecx);
zip_nv_write_hex(*ent,"edx", reg_edx);
zip_nv_write_hex(*ent,"esi", reg_esi);
zip_nv_write_hex(*ent,"edi", reg_edi);
zip_nv_write_hex(*ent,"ebp", reg_ebp);
zip_nv_write_hex(*ent,"esp", reg_esp);
zip_nv_write_hex(*ent,"eip", reg_eip);
zip_nv_write_hex(*ent,"eflags", reg_flags);
zip_nv_write_hex(*ent,"es.val", Segs.val[es]);
zip_nv_write_hex(*ent,"es.phys", Segs.phys[es]);
zip_nv_write_hex(*ent,"es.limit", Segs.limit[es]);
zip_nv_write(*ent,"es.expanddown", Segs.expanddown[es]);
zip_nv_write_hex(*ent,"cs.val", Segs.val[cs]);
zip_nv_write_hex(*ent,"cs.phys", Segs.phys[cs]);
zip_nv_write_hex(*ent,"cs.limit", Segs.limit[cs]);
zip_nv_write(*ent,"cs.expanddown", Segs.expanddown[cs]);
zip_nv_write_hex(*ent,"ss.val", Segs.val[ss]);
zip_nv_write_hex(*ent,"ss.phys", Segs.phys[ss]);
zip_nv_write_hex(*ent,"ss.limit", Segs.limit[ss]);
zip_nv_write(*ent,"ss.expanddown", Segs.expanddown[ss]);
zip_nv_write_hex(*ent,"ds.val", Segs.val[ds]);
zip_nv_write_hex(*ent,"ds.phys", Segs.phys[ds]);
zip_nv_write_hex(*ent,"ds.limit", Segs.limit[ds]);
zip_nv_write(*ent,"ds.expanddown", Segs.expanddown[ds]);
zip_nv_write_hex(*ent,"fs.val", Segs.val[fs]);
zip_nv_write_hex(*ent,"fs.phys", Segs.phys[fs]);
zip_nv_write_hex(*ent,"fs.limit", Segs.limit[fs]);
zip_nv_write(*ent,"fs.expanddown", Segs.expanddown[fs]);
zip_nv_write_hex(*ent,"gs.val", Segs.val[gs]);
zip_nv_write_hex(*ent,"gs.phys", Segs.phys[gs]);
zip_nv_write_hex(*ent,"gs.limit", Segs.limit[gs]);
zip_nv_write(*ent,"gs.expanddown", Segs.expanddown[gs]);
}
}
}
void CPU_Init() {
@ -3422,6 +3512,9 @@ void CPU_Init() {
test = new CPU(control->GetSection("cpu"));
AddExitFunction(AddExitFunctionFuncPair(CPU_ShutDown),true);
AddVMEventFunction(VM_EVENT_RESET,AddVMEventFunctionFuncPair(CPU_OnReset));
AddVMEventFunction(VM_EVENT_LOAD_STATE,AddVMEventFunctionFuncPair(CPU_LoadState));
AddVMEventFunction(VM_EVENT_SAVE_STATE,AddVMEventFunctionFuncPair(CPU_SaveState));
}
//initialize static members
bool CPU::inited=false;

View File

@ -639,7 +639,7 @@ extern bool enable_fpu;
#define MULB(op1,load,save) \
reg_ax=reg_al*load(op1); \
FillFlagsNoCFOF(); \
SETFLAGBIT(ZF,reg_al == 0); \
SETFLAGBIT(ZF,reg_al == 0 && CPU_CORE >= CPU_ARCHTYPE_286); \
SETFLAGBIT(PF,PARITY16(reg_ax)); \
if (reg_ax & 0xff00) { \
SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \
@ -653,7 +653,7 @@ extern bool enable_fpu;
reg_ax=(Bit16u)(tempu); \
reg_dx=(Bit16u)(tempu >> 16); \
FillFlagsNoCFOF(); \
SETFLAGBIT(ZF,reg_ax == 0); \
SETFLAGBIT(ZF,reg_ax == 0 && CPU_CORE >= CPU_ARCHTYPE_286); \
SETFLAGBIT(PF,PARITY16(reg_ax)^PARITY16(reg_dx)^FLAG_PF); \
if (reg_dx) { \
SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \
@ -668,7 +668,7 @@ extern bool enable_fpu;
reg_eax=(Bit32u)(tempu); \
reg_edx=(Bit32u)(tempu >> 32); \
FillFlagsNoCFOF(); \
SETFLAGBIT(ZF,reg_eax == 0); \
SETFLAGBIT(ZF,reg_eax == 0 && CPU_CORE >= CPU_ARCHTYPE_286); \
SETFLAGBIT(PF,PARITY32(reg_eax)^PARITY32(reg_edx)^FLAG_PF); \
if (reg_edx) { \
SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \

View File

@ -2612,8 +2612,10 @@ static void LogMCBS(void)
LOG(LOG_MISC,LOG_ERROR)("Conventional memory:");
LogMCBChain(dos.firstMCB);
LOG(LOG_MISC,LOG_ERROR)("Upper memory:");
LogMCBChain(dos_infoblock.GetStartOfUMBChain());
if (dos_infoblock.GetStartOfUMBChain() != 0xFFFF) {
LOG(LOG_MISC,LOG_ERROR)("Upper memory:");
LogMCBChain(dos_infoblock.GetStartOfUMBChain());
}
}
static void LogGDT(void)

View File

@ -44,6 +44,8 @@
#include "control.h"
#include <time.h>
#include "menu.h"
#include "render.h"
#include "mouse.h"
bool Mouse_Drv=true;
bool Mouse_Vertical = false;
@ -751,7 +753,7 @@ public:
}
Bitu loadsz = (isz2 + 0xFU) & (~0xFU);
if (loadsz == 0) loadsz = 0x10;
if (loadsz > (IS_PC98_ARCH ? 0x18000 : 0x20000)) loadsz = (IS_PC98_ARCH ? 0x18000 : 0x20000);
if (loadsz > (IS_PC98_ARCH ? 0x18000u : 0x20000u)) loadsz = (IS_PC98_ARCH ? 0x18000u : 0x20000u);
Bitu segbase = 0x100000 - loadsz;
LOG_MSG("Loading BIOS image %s to 0x%lx, 0x%lx bytes",bios.c_str(),(unsigned long)segbase,(unsigned long)loadsz);
fseek(romfp, 0, SEEK_SET);
@ -3985,6 +3987,7 @@ static void MORE_ProgramStart(Program * * make) {
void REDOS_ProgramStart(Program * * make);
void A20GATE_ProgramStart(Program * * make);
void PC98UTIL_ProgramStart(Program * * make);
void VESAMOED_ProgramStart(Program * * make);
class NMITEST : public Program {
public:
@ -3997,6 +4000,54 @@ static void NMITEST_ProgramStart(Program * * make) {
*make=new NMITEST;
}
class CAPMOUSE : public Program
{
public:
void Run() override
{
auto val = 0;
auto tmp = std::string("");
if(cmd->GetCount() == 0 || cmd->FindExist("/?", true))
val = 0;
else if(cmd->FindExist("/C", false))
val = 1;
else if(cmd->FindExist("/R", false))
val = 2;
auto cap = false;
switch(val)
{
case 2:
break;
case 1:
cap = true;
break;
case 0:
default:
WriteOut("Mouse capture/release.\n\n");
WriteOut("CAPMOUSE /[?|C|R]\n");
WriteOut(" /? help\n");
WriteOut(" /C capture mouse\n");
WriteOut(" /R release mouse\n");
return;
}
CaptureMouseNotify(!cap);
GFX_CaptureMouse(cap);
std::string msg;
msg.append("Mouse ");
msg.append(Mouse_IsLocked() ? "captured" : "released");
msg.append("\n");
WriteOut(msg.c_str());
}
};
void CAPMOUSE_ProgramStart(Program** make)
{
*make = new CAPMOUSE;
}
void DOS_SetupPrograms(void) {
/*Add Messages */
@ -4457,6 +4508,11 @@ void DOS_SetupPrograms(void) {
PROGRAMS_MakeFile("NMITEST.COM",NMITEST_ProgramStart);
PROGRAMS_MakeFile("RE-DOS.COM",REDOS_ProgramStart);
if (IS_VGA_ARCH && svgaCard != SVGA_None)
PROGRAMS_MakeFile("VESAMOED.COM",VESAMOED_ProgramStart);
if (IS_PC98_ARCH)
PROGRAMS_MakeFile("PC98UTIL.COM",PC98UTIL_ProgramStart);
PROGRAMS_MakeFile("CAPMOUSE.COM", CAPMOUSE_ProgramStart);
}

View File

@ -246,6 +246,9 @@ void INT10_Init(Section*);
#if C_NE2000
void NE2K_Init(Section* sec);
#endif
#if C_PRINTER
void PRINTER_Init(Section*);
#endif
signed long long time_to_clockdom(ClockDomain &src,double t) {
signed long long lt = (signed long long)t;
@ -811,6 +814,7 @@ void DOSBOX_SetupConfigSections(void) {
const char* captureformats[] = { "default", "avi-zmbv", "mpegts-h264", 0 };
const char* blocksizes[] = {"1024", "2048", "4096", "8192", "512", "256", 0};
const char* capturechromaformats[] = { "auto", "4:4:4", "4:2:2", "4:2:0", 0};
const char* controllertypes[] = { "auto", "at", "xt", "pcjr", "pc98", 0}; // Future work: Tandy(?) and USB
const char* auxdevices[] = {"none","2button","3button","intellimouse","intellimouse45",0};
const char* cputype_values[] = {"auto", "8086", "8086_prefetch", "80186", "80186_prefetch", "286", "286_prefetch", "386", "386_prefetch", "486", "486_prefetch", "pentium", "pentium_mmx", "ppro_slow", 0};
const char* rates[] = { "44100", "48000", "32000","22050", "16000", "11025", "8000", "49716", 0 };
@ -851,6 +855,8 @@ void DOSBOX_SetupConfigSections(void) {
const char* truefalseautoopt[] = { "true", "false", "1", "0", "auto", 0};
const char* pc98fmboards[] = { "auto", "off", "false", "board26k", "board86", "board86c", 0};
const char* pc98videomodeopt[] = { "", "24khz", "31khz", "15khz", 0};
const char* aspectmodes[] = { "false", "true", "0", "1", "yes", "no", "nearest", "bilinear", 0};
const char *vga_ac_mapping_settings[] = { "", "auto", "4x4", "4low", "first16", 0 };
const char* irqssbhack[] = {
"none", "cs_equ_ds", 0
@ -927,6 +933,9 @@ void DOSBOX_SetupConfigSections(void) {
Pstring->Set_values(machines);
Pstring->Set_help("The type of machine DOSBox tries to emulate.");
Phex = secprop->Add_hex("svga lfb base", Property::Changeable::OnlyAtStart, 0);
Phex->Set_help("If nonzero, define the physical memory address of the linear framebuffer.");
Pint = secprop->Add_int("vmemdelay", Property::Changeable::WhenIdle,0);
Pint->SetMinMax(-1,100000);
Pint->Set_help( "VGA Memory I/O delay in nanoseconds. Set to -1 to use default, 0 to disable.\n"
@ -987,6 +996,22 @@ void DOSBOX_SetupConfigSections(void) {
"to run DOSBox with as little as 4KB. If DOSBox-X aborts with error \"not enough memory for internal tables\"\n"
"then you need to increase this value.");
// NOTE: This will be revised as I test the DOSLIB code against more VGA/SVGA hardware!
Pstring = secprop->Add_string("vga attribute controller mapping",Property::Changeable::WhenIdle,"auto");
Pstring->Set_values(vga_ac_mapping_settings);
Pstring->Set_help(
"This affects how the attribute controller maps colors, especially in 256-color mode.\n"
"Some SVGA cards handle the attribute controller palette differently than most SVGA cards.\n"
" auto Automatically pick the mapping based on the SVGA chipset.\n"
" 4x4 Split into two 4-bit nibbles, map through AC, recombine. This is standard VGA behavior including clone SVGA cards.\n"
" 4low Split into two 4-bit nibbles, remap only the low 4 bits, recombine. This is standard ET4000 behavior.\n"
"\n"
"NOTES:\n"
" Demoscene executable 'COPPER.EXE' requires the '4low' behavior in order to display line-fading effects\n"
" (including scrolling credits) correctly, else those parts of the demo show up as a blank screen.\n"
" \n"
" 4low behavior is default for ET4000 emulation.");
// TODO: At some point, I would like to make "mask" the default instead of "fast"
Pstring = secprop->Add_string("a20",Property::Changeable::WhenIdle,"fast");
Pstring->Set_help("A20 gate emulation mode.\n"
@ -1324,6 +1349,17 @@ void DOSBOX_SetupConfigSections(void) {
"location reported by the VESA BIOS. Set to nonzero for DOS games with sloppy VESA graphics pointer management.\n"
" MFX \"Melvindale\" (1996): Set this option to 2 to center the picture properly.");
/* If set, all VESA BIOS modes map 128KB of video RAM at A0000-BFFFF even though VESA BIOS emulation
* reports a 64KB window. Some demos like the 1996 Wired report
* (ftp.scene.org/pub/parties/1995/wired95/misc/e-w95rep.zip) assume they can write past the window
* by spilling into B0000 without bank switching. */
Pbool = secprop->Add_bool("vesa map non-lfb modes to 128kb region",Property::Changeable::Always,false);
Pbool->Set_help("If set, VESA BIOS SVGA modes will be set to map 128KB of video memory to A0000-BFFFF instead of\n"
"64KB at A0000-AFFFF. This does not affect the SVGA window size or granularity.\n"
"Some games or demoscene productions assume that they can render into the next SVGA window/bank\n"
"by writing to video memory beyond the current SVGA window address and will not appear correctly\n"
"without this option.");
Pbool = secprop->Add_bool("allow hpel effects",Property::Changeable::Always,false);
Pbool->Set_help("If set, allow the DOS demo or program to change the horizontal pel (panning) register per scanline.\n"
"Some early DOS demos use this to create waving or sinus effects on the picture. Not very many VGA\n"
@ -1423,8 +1459,44 @@ void DOSBOX_SetupConfigSections(void) {
Pint->SetMinMax(0,10);
Pint->Set_help("How many frames DOSBox skips before drawing one.");
Pbool = secprop->Add_bool("aspect",Property::Changeable::Always,false);
Pbool->Set_help("Do aspect correction, if your output method doesn't support scaling this can slow things down!.");
Pstring = secprop->Add_string("aspect", Property::Changeable::Always, "false");
Pstring->Set_values(aspectmodes);
Pstring->Set_help(
"Aspect ratio correction mode. Can be set to the following values:\n"
" 'false' (default):\n"
" 'direct3d'/opengl outputs: image is simply scaled to full window/fullscreen size, possibly resulting in disproportional image\n"
" 'surface' output: it does no aspect ratio correction (default), resulting in disproportional images if VGA mode pixel ratio is not 4:3\n"
" 'true':\n"
" 'direct3d'/opengl outputs: uses output driver functions to scale / pad image with black bars, correcting output to proportional 4:3 image\n"
" In most cases image degradation should not be noticeable (it all depends on the video adapter and how much the image is upscaled).\n"
" Should have none to negligible impact on performance, mostly being done in hardware\n"
" 'surface' output: inherits old DOSBox aspect ratio correction method (adjusting rendered image line count to correct output to 4:3 ratio)\n"
" Due to source image manipulation this mode does not mix well with scalers, i.e. multiline scalers like hq2x/hq3x will work poorly\n"
" Slightly degrades visual image quality. Has a tiny impact on performance"
#if C_XBRZ
"\n"
" When using xBRZ scaler with 'surface' output, aspect ratio correction is done by the scaler itself, so none of the above apply"
#endif
#if C_SURFACE_POSTRENDER_ASPECT
"\n"
" 'nearest':\n"
" 'direct3d'/opengl outputs: not available, fallbacks to 'true' mode automatically\n"
" 'surface' output: scaler friendly aspect ratio correction, works by rescaling rendered image using nearest neighbor scaler\n"
" Complex scalers work. Image quality is on par with 'true' mode (and better with scalers). More CPU intensive than 'true' mode\n"
#if C_XBRZ
" When using xBRZ scaler with 'surface' output, aspect ratio correction is done by the scaler itself, so it fallbacks to 'true' mode\n"
#endif
" 'bilinear':\n"
" 'direct3d'/opengl outputs: not available, fallbacks to 'true' mode automatically\n"
" 'surface' output: scaler friendly aspect ratio correction, works by rescaling rendered image using bilinear scaler\n"
" Complex scalers work. Image quality is much better, should be on par with using 'direct3d' output + 'true' mode\n"
" Very CPU intensive, high end CPU may be required"
#if C_XBRZ
"\n"
" When using xBRZ scaler with 'surface' output, aspect ratio correction is done by the scaler itself, so it fallbacks to 'true' mode"
#endif
#endif
);
Pbool = secprop->Add_bool("char9",Property::Changeable::Always,true);
Pbool->Set_help("Allow 9-pixel wide text mode fonts.");
@ -1621,6 +1693,15 @@ void DOSBOX_SetupConfigSections(void) {
"This option is required to allow Windows ME to reboot properly, whereas Windows 9x and earlier\n"
"will reboot without this option using INT 19h");
Pstring = secprop->Add_string("controllertype",Property::Changeable::OnlyAtStart,"auto");
Pstring->Set_values(controllertypes);
Pstring->Set_help("Type of keyboard controller (and keyboard) attached.\n"
"auto Automatically pick according to machine type\n"
"at AT (PS/2) type keyboard\n"
"xt IBM PC/XT type keyboard\n"
"pcjr IBM PCjr type keyboard (only if machine=pcjr)\n"
"pc98 PC-98 keyboard emulation (only if machine=pc98)");
Pstring = secprop->Add_string("auxdevice",Property::Changeable::OnlyAtStart,"intellimouse");
Pstring->Set_values(auxdevices);
Pstring->Set_help("Type of PS/2 mouse attached to the AUX port");
@ -1954,6 +2035,20 @@ void DOSBOX_SetupConfigSections(void) {
Pbool->Set_help("Start the DOS virtual machine with the DMA channel already unmasked at the controller.\n"
"Use this for DOS applications that expect to operate the GUS but forget to unmask the DMA channel.");
Pbool = secprop->Add_bool("pic unmask irq",Property::Changeable::WhenIdle,false);
Pbool->Set_help("Start the DOS virtual machine with the GUS IRQ already unmasked at the PIC.");
Pbool = secprop->Add_bool("startup initialized",Property::Changeable::WhenIdle,false);
Pbool->Set_help("If set, start the GF1 in a fully initialized state (as if ULTRINIT had been run).\n"
"If clear, leave the card in an uninitialized state (as if cold boot).\n"
"Some DOS games or demoscene productions will hang or fail to use the Ultrasound hardware\n"
"because they assume the card is initialized and their hardware detect does not fully initialize the card.");
Pbool = secprop->Add_bool("dma enable on dma control polling",Property::Changeable::WhenIdle,false);
Pbool->Set_help("If set, automatically enable GUS DMA transfer bit in specific cases when the DMA control register is being polled.\n"
"THIS IS A HACK. Some games and demoscene productions need this hack to avoid hanging while uploading sample data\n"
"to the Gravis Ultrasound due to bugs in their implementation.");
Pbool = secprop->Add_bool("clear dma tc irq if excess polling",Property::Changeable::WhenIdle,false);
Pbool->Set_help("If the DOS application is seen polling the IRQ status register rapidly, automatically clear the DMA TC IRQ status.\n"
"This is a hack that should only be used with DOS applications that need it to avoid bugs in their GUS support code.\n"
@ -2201,6 +2296,46 @@ void DOSBOX_SetupConfigSections(void) {
Pstring = Pmulti_remain->GetSection()->Add_string("parameters",Property::Changeable::WhenIdle,"");
Pmulti_remain->Set_help("see serial1");
#if C_PRINTER
// printer redirection parameters
secprop = control->AddSection_prop("printer", &Null_Init);
Pbool = secprop->Add_bool("printer", Property::Changeable::WhenIdle, true);
Pbool->Set_help("Enable printer emulation.");
//secprop->Add_string("fontpath","%%windir%%\\fonts");
Pint = secprop->Add_int("dpi", Property::Changeable::WhenIdle, 360);
Pint->Set_help("Resolution of printer (default 360).");
Pint = secprop->Add_int("width", Property::Changeable::WhenIdle, 85);
Pint->Set_help("Width of paper in 1/10 inch (default 85 = 8.5'').");
Pint = secprop->Add_int("height", Property::Changeable::WhenIdle, 110);
Pint->Set_help("Height of paper in 1/10 inch (default 110 = 11.0'').");
#ifdef C_LIBPNG
Pstring = secprop->Add_string("printoutput", Property::Changeable::WhenIdle, "png");
#else
Pstring = secprop->Add_string("printoutput", Property::Changeable::WhenIdle, "ps");
#endif
Pstring->Set_help("Output method for finished pages: \n"
#ifdef C_LIBPNG
" png : Creates PNG images (default)\n"
#endif
" ps : Creates Postscript\n"
" bmp : Creates BMP images (very huge files, not recommend)\n"
#if defined (WIN32)
" printer : Send to an actual printer (Print dialog will appear)"
#endif
);
Pbool = secprop->Add_bool("multipage", Property::Changeable::WhenIdle, false);
Pbool->Set_help("Adds all pages to one Postscript file or printer job until CTRL-F2 is pressed.");
Pstring = secprop->Add_string("docpath", Property::Changeable::WhenIdle, ".");
Pstring->Set_help("The path where the output files are stored.");
Pint = secprop->Add_int("timeout", Property::Changeable::WhenIdle, 0);
Pint->Set_help("(in milliseconds) if nonzero: the time the page will\n"
"be ejected automatically after when no more data\n"
"arrives at the printer.");
#endif
// parallel ports
secprop=control->AddSection_prop("parallel",&Null_Init,true);
Pstring = secprop->Add_string("parallel1",Property::Changeable::WhenIdle,"disabled");

View File

@ -9,9 +9,7 @@ libgui_a_SOURCES = \
render_templates_sai.h render_templates_hq.h \
render_templates_hq2x.h render_templates_hq3x.h \
midi.cpp midi_win32.h midi_oss.h midi_coreaudio.h midi_alsa.h \
direct3d.cpp direct3d.h \
hq2x_d3d.cpp hq2x_d3d.h \
midi_coremidi.h sdl_gui.cpp dosbox_splash.h menu.cpp ScalingEffect.cpp bitop.cpp ptrop.cpp
midi_coremidi.h sdl_gui.cpp dosbox_splash.h menu.cpp bitop.cpp ptrop.cpp zipcrc.c zipfile.cpp
if C_MT32
AM_CPPFLAGS += -I$(top_srcdir)/src/mt32

View File

@ -155,7 +155,7 @@ public:
caps = SND_SEQ_PORT_CAP_READ;
if (seq_client == SND_SEQ_ADDRESS_SUBSCRIBERS)
caps = ~((unsigned int)SND_SEQ_PORT_CAP_SUBS_READ);
caps |= SND_SEQ_PORT_CAP_SUBS_READ;
my_port =
snd_seq_create_simple_port(seq_handle, "DOSBOX", caps,
SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION);

View File

@ -30,6 +30,7 @@
#include "cross.h"
#include "hardware.h"
#include "support.h"
#include "sdlmain.h"
#include "render_scalers.h"
#if defined(__SSE__)
@ -122,6 +123,11 @@ static void RENDER_EmptyLineHandler(const void * src) {
/*HACK*/
#if defined(__SSE__) && defined(_M_AMD64)
# define sse2_available (1) /* SSE2 is always available on x86_64 */
#else
# ifdef __SSE__
extern bool sse1_available;
extern bool sse2_available;
# endif
#endif
/*END HACK*/
@ -132,10 +138,8 @@ static void RENDER_StartLineHandler(const void * s) {
Bits count = (Bits)render.src.start;
#if defined(__SSE__)
if (sse2_available) {
#if defined (_MSC_VER)
#define SIZEOF_INT_P sizeof(*src)
#endif
static const Bitu simd_inc = 16/SIZEOF_INT_P;
#define MY_SIZEOF_INT_P sizeof(*src)
static const Bitu simd_inc = 16/MY_SIZEOF_INT_P;
while (count >= (Bits)simd_inc) {
__m128i v = _mm_loadu_si128((const __m128i*)src);
__m128i c = _mm_loadu_si128((const __m128i*)cache);
@ -144,6 +148,7 @@ static void RENDER_StartLineHandler(const void * s) {
goto cacheMiss;
count-=(Bits)simd_inc; src+=simd_inc; cache+=simd_inc;
}
#undef MY_SIZEOF_INT_P
}
else
#endif
@ -323,7 +328,6 @@ static Bitu MakeAspectTable(Bitu skip,Bitu height,double scaley,Bitu miny) {
return linesadded;
}
void RENDER_Reset( void ) {
Bitu width=render.src.width;
Bitu height=render.src.height;
@ -341,7 +345,13 @@ void RENDER_Reset( void ) {
ScalerComplexBlock_t *complexBlock = 0;
gfx_scalew = 1;
gfx_scaleh = 1;
if (render.aspect && !render.aspectOffload) {
#if !C_XBRZ
if (render.aspect == ASPECT_TRUE && !render.aspectOffload)
#else
if (render.aspect == ASPECT_TRUE && !render.aspectOffload && !(sdl_xbrz.enable && sdl_xbrz.scale_on))
#endif
{
if (render.src.ratio>1.0) {
gfx_scalew = 1;
gfx_scaleh = render.src.ratio;
@ -350,6 +360,7 @@ void RENDER_Reset( void ) {
gfx_scaleh = 1;
}
}
if ((dblh && dblw) || (render.scale.forced && !dblh && !dblw)) {
/* Initialize always working defaults */
if (render.scale.size == 2)
@ -546,6 +557,12 @@ forcenormal:
height = MakeAspectTable( skip, render.src.height, yscale, yscale);
}
}
/* update the aspect ratio */
sdl.srcAspect.x = render.src.width * (render.src.dblw ? 2 : 1);
sdl.srcAspect.y = (int)floor((render.src.height * (render.src.dblh ? 2 : 1) * render.src.ratio) + 0.5);
sdl.srcAspect.xToY = (double)sdl.srcAspect.x / sdl.srcAspect.y;
sdl.srcAspect.yToX = (double)sdl.srcAspect.y / sdl.srcAspect.x;
LOG_MSG("Aspect ratio: %u x %u xToY=%.3f yToX=%.3f",sdl.srcAspect.x,sdl.srcAspect.y,sdl.srcAspect.xToY,sdl.srcAspect.yToX);
/* Setup the scaler variables */
gfx_flags=GFX_SetSize(width,height,gfx_flags,gfx_scalew,gfx_scaleh,&RENDER_CallBack);
if (gfx_flags & GFX_CAN_8)
@ -718,14 +735,6 @@ static void ChangeScaler(bool pressed) {
#include "vga.h"
bool RENDER_GetAutofit(void) {
return render.autofit;
}
bool RENDER_GetAspect(void) {
return render.aspect;
}
void RENDER_SetForceUpdate(bool f) {
render.forceUpdate = f;
}
@ -748,9 +757,16 @@ void RENDER_OnSectionPropChange(Section *x) {
bool p_doublescan = vga.draw.doublescan_set;
bool p_char9 = vga.draw.char9_set;
bool p_aspect = render.aspect;
int p_aspect = render.aspect;
std::string s_aspect = section->Get_string("aspect");
render.aspect = ASPECT_FALSE;
if (s_aspect == "true" || s_aspect == "1" || s_aspect == "yes") render.aspect = ASPECT_TRUE;
#if C_SURFACE_POSTRENDER_ASPECT
if (s_aspect == "nearest") render.aspect = ASPECT_NEAREST;
if (s_aspect == "bilinear") render.aspect = ASPECT_BILINEAR;
#endif
render.aspect = section->Get_bool("aspect");
render.frameskip.max = (Bitu)section->Get_int("frameskip");
vga.draw.doublescan_set=section->Get_bool("doublescan");
@ -764,6 +780,10 @@ void RENDER_OnSectionPropChange(Section *x) {
mainMenu.get_item("vga_9widetext").check(vga.draw.char9_set).refresh_item(mainMenu);
mainMenu.get_item("doublescan").check(vga.draw.doublescan_set).refresh_item(mainMenu);
#if C_XBRZ
xBRZ_Change_Options(section);
#endif
RENDER_UpdateFrameskipMenu();
}
@ -791,7 +811,8 @@ void RENDER_UpdateFromScalerSetting(void) {
std::string scaler = prop->GetSection()->Get_string("type");
#if C_XBRZ
render.scale.xBRZ = false;
bool old_xBRZ_enable = sdl_xbrz.enable;
sdl_xbrz.enable = false;
#endif
render.scale.forced = false;
@ -827,8 +848,18 @@ void RENDER_UpdateFromScalerSetting(void) {
else if (scaler == "hardware4x") { render.scale.op = scalerOpNormal; render.scale.size = 8; render.scale.hardware=true; }
else if (scaler == "hardware5x") { render.scale.op = scalerOpNormal; render.scale.size = 10; render.scale.hardware=true; }
#if C_XBRZ
else if (scaler == "xbrz") { render.scale.op = scalerOpNormal; render.scale.size = 1; render.scale.hardware = false; render.scale.xBRZ = true; }
else if (scaler == "xbrz_bilinear") { render.scale.op = scalerOpNormal; render.scale.size = 1; render.scale.hardware = false; render.scale.xBRZ = true; }
else if (scaler == "xbrz" || scaler == "xbrz_bilinear") {
render.scale.op = scalerOpNormal;
render.scale.size = 1;
render.scale.hardware = false;
vga.draw.doublescan_set = false;
sdl_xbrz.enable = true;
sdl_xbrz.postscale_bilinear = (scaler == "xbrz_bilinear");
}
#endif
#if C_XBRZ
if (old_xBRZ_enable != sdl_xbrz.enable) RENDER_CallBack(GFX_CallBackReset);
#endif
}
@ -847,7 +878,7 @@ void RENDER_Init() {
//For restarting the renderer.
static bool running = false;
bool aspect = render.aspect;
int aspect = render.aspect;
Bitu scalersize = render.scale.size;
bool scalerforced = render.scale.forced;
scalerOperation_t scaleOp = render.scale.op;
@ -857,7 +888,15 @@ void RENDER_Init() {
render.pal.first=0;
render.pal.last=255;
render.aspect=section->Get_bool("aspect");
std::string s_aspect = section->Get_string("aspect");
render.aspect = ASPECT_FALSE;
if (s_aspect == "true" || s_aspect == "1") render.aspect = ASPECT_TRUE;
#if C_SURFACE_POSTRENDER_ASPECT
if (s_aspect == "nearest") render.aspect = ASPECT_NEAREST;
if (s_aspect == "bilinear") render.aspect = ASPECT_BILINEAR;
#endif
render.frameskip.max=(Bitu)section->Get_int("frameskip");
RENDER_UpdateFrameskipMenu();
@ -879,13 +918,6 @@ void RENDER_Init() {
RENDER_UpdateFromScalerSetting();
#if C_XBRZ
if (render.scale.xBRZ) {
// xBRZ requirements
vga.draw.doublescan_set = false;
}
#endif
render.autofit=section->Get_bool("autofit");
//If something changed that needs a ReInit

File diff suppressed because it is too large Load Diff

80
src/gui/zipcrc.c Normal file
View File

@ -0,0 +1,80 @@
/**
* \file zipcrc.c
* Functions and types for CRC checks.
*
* Generated on Sat Jul 29 13:31:13 2017,
* by pycrc v0.9, https://pycrc.org
* using the configuration:
* Width = 32
* Poly = 0x04c11db7
* Xor_In = 0xffffffff
* ReflectIn = True
* Xor_Out = 0xffffffff
* ReflectOut = True
* Algorithm = table-driven
*****************************************************************************/
#include "zipcrc.h" /* include the header file generated with pycrc */
#include <stdlib.h>
#include <stdint.h>
/**
* Static table used for the table_driven implementation.
*****************************************************************************/
static const zipcrc_t crc_table[256] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
/**
* Update the crc value with new data.
*
* \param crc The current crc value.
* \param data Pointer to a buffer of \a data_len bytes.
* \param data_len Number of bytes in the \a data buffer.
* \return The updated crc value.
*****************************************************************************/
zipcrc_t zipcrc_update(zipcrc_t crc, const void *data, size_t data_len)
{
const unsigned char *d = (const unsigned char *)data;
unsigned int tbl_idx;
while (data_len--) {
tbl_idx = (crc ^ *d) & 0xff;
crc = (crc_table[tbl_idx] ^ (crc >> 8)) & 0xffffffff;
d++;
}
return crc & 0xffffffff;
}

482
src/gui/zipfile.cpp Normal file
View File

@ -0,0 +1,482 @@
#ifndef _GNU_SOURCE
# define _GNU_SOURCE
#endif
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <assert.h>
#include <stdarg.h>
#include <fcntl.h>
#include <sys/types.h>
#include <algorithm> // std::transform
#ifdef WIN32
# include <signal.h>
# include <sys/stat.h>
# include <process.h>
#endif
#include "dosbox.h"
#include "pic.h"
#include "timer.h"
#include "setup.h"
#include "bios.h"
#include "support.h"
#include "debug.h"
#include "ide.h"
#include "bitop.h"
#include "ptrop.h"
#include "mapper.h"
#include "zipfile.h"
#include "mapper.h"
#include "vga.h"
#include "keyboard.h"
#include "cpu.h"
#include "fpu.h"
#include "cross.h"
#include "keymap.h"
bool ZIPFileEntry::rewind(void) {
if (can_write) return false;
return (seek_file(0) == 0);
}
off_t ZIPFileEntry::seek_file(off_t pos) {
if (file == NULL || file_offset == (off_t)0 || can_write) return (off_t)(-1LL);
if (pos < (off_t)0) pos = (off_t)0;
if (pos > file_length) pos = file_length;
pos = file->seek_file(pos + file_offset) - file_offset;
if (pos < 0 || pos > file_length) return (off_t)(-1LL);
position = pos;
return pos;
}
int ZIPFileEntry::read(void *buffer,size_t count) {
if (file == NULL || file_offset == (off_t)0) return -1;
if (position >= file_length) return 0;
size_t mread = file_length - position;
if (mread > count) mread = count;
if (mread > 0) {
if (seek_file(position) != position) return -1;
mread = file->read(buffer,mread);
if (mread > 0) position += mread;
}
return mread;
}
int ZIPFileEntry::write(const void *buffer,size_t count) {
if (file == NULL || file_offset == (off_t)0 || !can_write) return -1;
/* write stream only, no seeking.
* this code assumes the file pointer will not change anywhere else,
* and always to the end */
if (count > 0) {
count = file->write(buffer,count);
if (count > 0) {
position += count;
write_crc = zipcrc_update(write_crc, buffer, count);
file_length = position;
}
}
return count;
}
ZIPFile::ZIPFile() {
}
ZIPFile::~ZIPFile() {
close();
}
void ZIPFile::close(void) {
if (file_fd >= 0) {
::close(file_fd);
file_fd = -1;
}
entries.clear();
}
ZIPFileEntry *ZIPFile::get_entry(const char *name) {
if (file_fd < 0) return NULL;
/* no reading while writing except what is being written */
if (!current_entry.empty() && current_entry != name) return NULL;
/* no empty names */
if (*name == 0) return NULL;
auto i = entries.find(name);
if (i == entries.end()) return NULL;
return &(i->second);
}
ZIPFileEntry *ZIPFile::new_entry(const char *name) {
if (file_fd < 0 || !can_write || wrote_trailer) return NULL;
/* cannot make new entries that exist already */
auto i = entries.find(name);
if (i != entries.end()) return NULL;
/* no empty names */
if (*name == 0) return NULL;
/* close current entry, if open */
close_current();
/* begin new entry at end */
current_entry = name;
write_pos = end_of_file();
ZIPFileEntry *ent = &entries[name];
ent->name = name;
ent->can_write = true;
ent->file_header_offset = write_pos;
write_pos += sizeof(ZIPLocalFileHeader) + ent->name.length();
ent->write_crc = zipcrc_init();
ent->file_offset = write_pos;
ent->file = this;
if (seek_file(ent->file_header_offset) != ent->file_header_offset) {
close_current();
return NULL;
}
ZIPLocalFileHeader hdr;
memset(&hdr,0,sizeof(hdr));
hdr.local_file_header_signature = htole32(0x04034b50); /* PK\x03\x04 */
hdr.version_needed_to_extract = htole16(20); /* PKZIP 2.0 */
hdr.general_purpose_bit_flag = htole16(0 << 1);
hdr.compression_method = 0; /* store (no compression) */
hdr.file_name_length = htole16((uint16_t)ent->name.length());
if (write(&hdr,sizeof(hdr)) != sizeof(hdr)) {
close_current();
return NULL;
}
assert(ent->name.length() != 0);
if ((size_t)write(ent->name.c_str(),ent->name.length()) != ent->name.length()) {
close_current();
return NULL;
}
if (seek_file(ent->file_offset) != ent->file_offset) {
close_current();
return NULL;
}
return ent;
}
off_t ZIPFile::end_of_file(void) {
return lseek(file_fd,0,SEEK_END);
}
void ZIPFile::close_current(void) {
if (!can_write) return;
if (!current_entry.empty()) {
ZIPFileEntry *ent = get_entry(current_entry.c_str());
ZIPLocalFileHeader hdr;
if (ent != NULL && ent->can_write) {
ent->can_write = false;
if (seek_file(ent->file_header_offset) == ent->file_header_offset && read(&hdr,sizeof(hdr)) == sizeof(hdr)) {
hdr.compressed_size = hdr.uncompressed_size = htole32(((uint32_t)ent->file_length));
hdr.crc_32 = htole32(zipcrc_finalize(ent->write_crc));
if (seek_file(ent->file_header_offset) == ent->file_header_offset && write(&hdr,sizeof(hdr)) == sizeof(hdr)) {
/* good */
}
}
}
}
current_entry.clear();
}
int ZIPFile::open(const char *path,int mode) {
unsigned char tmp[512];
close();
if (path == NULL) return -1;
if ((mode & 3) == O_WRONLY) {
LOG_MSG("WARNING: ZIPFile attempt to open with O_WRONLY, which will not work");
return -1;
}
#if defined(O_BINARY)
mode |= O_BINARY;
#endif
file_fd = ::open(path,mode,0644);
if (file_fd < 0) return -1;
if (lseek(file_fd,0,SEEK_SET) != 0) {
close();
return -1;
}
entries.clear();
current_entry.clear();
wrote_trailer = false;
write_pos = 0;
/* WARNING: This assumes O_RDONLY, O_WRONLY, O_RDWR are defined as in Linux (0, 1, 2) in the low two bits */
if ((mode & 3) == O_RDWR)
can_write = true;
else
can_write = false;
/* if we're supposed to READ the ZIP file, then start scanning now */
if ((mode & 3) == O_RDONLY) {
struct pkzip_central_directory_header_main chdr;
struct pkzip_central_directory_header_end ehdr;
off_t fsz = end_of_file();
/* check for 'PK' at the start of the file.
* This code only expects to handle the ZIP files it generated, not ZIP files in general. */
if (fsz < 64 || seek_file(0) != 0 || read(tmp,4) != 4 || memcmp(tmp,"PK\x03\x04",4) != 0) {
LOG_MSG("Not a PKZIP file");
close();
return -1;
}
/* then look for the central directory at the end.
* this code DOES NOT SUPPORT the ZIP comment field, nor will this code generate one. */
if (seek_file(fsz - (off_t)sizeof(ehdr)) != (fsz - (off_t)sizeof(ehdr)) || (size_t)read(&ehdr,sizeof(ehdr)) != sizeof(ehdr) || ehdr.sig != PKZIP_CENTRAL_DIRECTORY_END_SIG || ehdr.size_of_central_directory > 0x100000u/*absurd size*/ || ehdr.offset_of_central_directory_from_start_disk == 0 || (off_t)ehdr.offset_of_central_directory_from_start_disk >= fsz) {
LOG_MSG("Cannot locate Central Directory");
close();
return -1;
}
if (seek_file(ehdr.offset_of_central_directory_from_start_disk) != ehdr.offset_of_central_directory_from_start_disk) {
LOG_MSG("Cannot locate Central Directory #2");
close();
return -1;
}
/* read the central directory */
{
long remain = (long)ehdr.size_of_central_directory;
while (remain >= (long)sizeof(struct pkzip_central_directory_header_main)) {
if (read(&chdr,sizeof(chdr)) != sizeof(chdr)) break;
remain -= sizeof(chdr);
if (chdr.sig != PKZIP_CENTRAL_DIRECTORY_HEADER_SIG) break;
if (chdr.filename_length >= sizeof(tmp)) break;
tmp[chdr.filename_length] = 0;
if (chdr.filename_length != 0) {
if (read(tmp,chdr.filename_length) != chdr.filename_length) break;
remain -= chdr.filename_length;
}
if (tmp[0] == 0) continue;
ZIPFileEntry *ent = &entries[(char*)tmp];
ent->can_write = false;
ent->file_length = htole32(chdr.uncompressed_size);
ent->file_header_offset = htole32(chdr.relative_offset_of_local_header);
ent->file_offset = ent->file_header_offset + sizeof(struct ZIPLocalFileHeader) + htole16(chdr.filename_length) + htole16(chdr.extra_field_length);
ent->position = 0;
ent->name = (char*)tmp;
ent->file = this;
}
}
}
return 0;
}
off_t ZIPFile::seek_file(off_t pos) {
if (file_fd < 0) return (off_t)(-1LL);
return ::lseek(file_fd,pos,SEEK_SET);
}
int ZIPFile::read(void *buffer,size_t count) {
if (file_fd < 0) return -1;
return ::read(file_fd,buffer,count);
}
int ZIPFile::write(const void *buffer,size_t count) {
if (file_fd < 0) return -1;
return ::write(file_fd,buffer,count);
}
void ZIPFile::writeZIPFooter(void) {
struct pkzip_central_directory_header_main chdr;
struct pkzip_central_directory_header_end ehdr;
uint32_t cdircount = 0;
uint32_t cdirbytes = 0;
off_t cdirofs = 0;
if (file_fd < 0 || wrote_trailer || !can_write) return;
close_current();
cdirofs = end_of_file();
for (auto i=entries.begin();i!=entries.end();i++) {
const ZIPFileEntry &ent = i->second;
memset(&chdr,0,sizeof(chdr));
chdr.sig = htole32(PKZIP_CENTRAL_DIRECTORY_HEADER_SIG);
chdr.version_made_by = htole16((0 << 8) + 20); /* PKZIP 2.0 */
chdr.version_needed_to_extract = htole16(20); /* PKZIP 2.0 or higher */
chdr.general_purpose_bit_flag = htole16(0 << 1); /* just lie and say that "normal" deflate was used */
chdr.compression_method = 0; /* stored (no compression) */
chdr.last_mod_file_time = 0;
chdr.last_mod_file_date = 0;
chdr.compressed_size = htole32(((uint32_t)ent.file_length));
chdr.uncompressed_size = htole32(((uint32_t)ent.file_length));
chdr.filename_length = htole16((uint16_t)ent.name.length());
chdr.disk_number_start = htole16(1u);
chdr.internal_file_attributes = 0;
chdr.external_file_attributes = 0;
chdr.relative_offset_of_local_header = htole32(ent.file_header_offset);
chdr.crc32 = htole32(zipcrc_finalize(ent.write_crc));
if (write(&chdr,sizeof(chdr)) != sizeof(chdr)) break;
cdirbytes += sizeof(chdr);
cdircount++;
assert(ent.name.length() != 0);
if ((size_t)write(ent.name.c_str(),ent.name.length()) != ent.name.length()) break;
cdirbytes += ent.name.length();
}
memset(&ehdr,0,sizeof(ehdr));
ehdr.sig = htole32(PKZIP_CENTRAL_DIRECTORY_END_SIG);
ehdr.number_of_disk_with_start_of_central_directory = htole16(0);
ehdr.number_of_this_disk = htole16(0);
ehdr.total_number_of_entries_of_central_dir_on_this_disk = htole16(cdircount);
ehdr.total_number_of_entries_of_central_dir = htole16(cdircount);
ehdr.size_of_central_directory = htole32(cdirbytes);
ehdr.offset_of_central_directory_from_start_disk = htole32(cdirofs);
write(&ehdr,sizeof(ehdr));
wrote_trailer = true;
current_entry.clear();
}
// MOVE
static std::string zip_nv_pair_empty;
zip_nv_pair_map::zip_nv_pair_map() {
}
zip_nv_pair_map::zip_nv_pair_map(ZIPFileEntry &ent) {
read_nv_pairs(ent);
}
std::string &zip_nv_pair_map::get(const char *name) {
auto i = find(name);
if (i != end()) return i->second;
return zip_nv_pair_empty;
}
bool zip_nv_pair_map::get_bool(const char *name) {
std::string &val = get(name);
return (strtol(val.c_str(),NULL,0) > 0);
}
long zip_nv_pair_map::get_long(const char *name) {
std::string &val = get(name);
return strtol(val.c_str(),NULL,0);
}
unsigned long zip_nv_pair_map::get_ulong(const char *name) {
std::string &val = get(name);
return strtoul(val.c_str(),NULL,0);
}
void zip_nv_pair_map::process_line(char *line/*will modify, assume caller has put NUL at the end*/) {
char *equ = strchr(line,'=');
if (equ == NULL) return;
*equ++ = 0; /* overwite '=' with NUL, split name vs value */
/* no null names */
if (*line == 0) return;
(*this)[line] = equ;
}
void zip_nv_pair_map::read_nv_pairs(ZIPFileEntry &ent) {
char tmp[1024],*r,*f;
char line[1024],*w,*wf=line+sizeof(line)-1;
char c;
int l;
clear();
ent.rewind();
w = line;
while ((l=ent.read(tmp,sizeof(tmp))) > 0) {
r = tmp;
f = tmp + l;
while (r < f) {
c = *r++;
if (c == '\n') {
assert(w <= wf);
*w = 0;
process_line(line);
w = line;
}
else if (c == '\r') {
/* ignore */
}
else if (w < wf) {
*w++ = c;
}
}
}
if (w != line) {
assert(w <= wf);
*w = 0;
process_line(line);
w = line;
}
}
static char zip_nv_tmp[1024];
void zip_nv_write(ZIPFileEntry &ent,const char *name,bool val) {
size_t l;
if ((l = ((size_t)snprintf(zip_nv_tmp,sizeof(zip_nv_tmp),"%s=%d\n",name,val?1:0))) >= (sizeof(zip_nv_tmp)-1u))
E_Exit("zip_nv_write buffer overrun (result too long)");
ent.write(zip_nv_tmp,l);
}
void zip_nv_write(ZIPFileEntry &ent,const char *name,long val) {
size_t l;
if ((l = ((size_t)snprintf(zip_nv_tmp,sizeof(zip_nv_tmp),"%s=%ld\n",name,val))) >= (sizeof(zip_nv_tmp)-1u))
E_Exit("zip_nv_write buffer overrun (result too long)");
ent.write(zip_nv_tmp,l);
}
void zip_nv_write_hex(ZIPFileEntry &ent,const char *name,unsigned long val) {
size_t l;
if ((l = ((size_t)snprintf(zip_nv_tmp,sizeof(zip_nv_tmp),"%s=0x%lx\n",name,val))) >= (sizeof(zip_nv_tmp)-1u))
E_Exit("zip_nv_write buffer overrun (result too long)");
ent.write(zip_nv_tmp,l);
}

View File

@ -67,7 +67,10 @@ static Bit8u const irqtable[8] = { 0/*invalid*/, 2, 5, 3, 7, 11, 12, 15 };
static Bit8u const dmatable[8] = { 0/*NO DMA*/, 1, 3, 5, 6, 7, 0/*invalid*/, 0/*invalid*/ };
static Bit8u GUSRam[1024*1024 + 16/*safety margin*/]; // 1024K of GUS Ram
static Bit32s AutoAmp = 512;
static bool unmask_irq = false;
static bool enable_autoamp = false;
static bool startup_ultrinit = false;
static bool dma_enable_on_dma_control_polling = false;
static Bit16u vol16bit[4096];
static Bit32u pantable[16];
static enum GUSType gus_type = GUS_CLASSIC;
@ -85,6 +88,7 @@ struct GFGus {
Bit8u gRegSelect;
Bit16u gRegData;
Bit32u gDramAddr;
Bit32u gDramAddrMask;
Bit16u gCurChannel;
Bit8u gUltraMAXControl;
@ -661,6 +665,14 @@ static Bit16u ExecuteReadRegister(void) {
// NTS: The GUS SDK documents the active channel count as bits 5-0, which is wrong. it's bits 4-0. bits 7-5 are always 1 on real hardware.
return ((Bit16u)(0xE0 | (myGUS.ActiveChannelsUser - 1))) << 8;
case 0x41: // Dma control register - read acknowledges DMA IRQ
if (dma_enable_on_dma_control_polling) {
if (!GetDMAChannel(myGUS.dma1)->masked && !(myGUS.DMAControl & 0x01) && !(myGUS.IRQStatus & 0x80)) {
LOG(LOG_MISC,LOG_DEBUG)("GUS: As instructed, switching on DMA ENABLE upon polling DMA control register (HACK) as workaround");
myGUS.DMAControl |= 0x01;
GUS_StartDMA();
}
}
tmpreg = myGUS.DMAControl & 0xbf;
tmpreg |= (myGUS.IRQStatus & 0x80) >> 1;
myGUS.IRQStatus&=0x7f;
@ -1365,8 +1377,8 @@ static Bitu read_gus(Bitu port,Bitu iolen) {
return reg16;
case 0x307:
if(myGUS.gDramAddr < myGUS.memsize) {
return GUSRam[myGUS.gDramAddr];
if((myGUS.gDramAddr & myGUS.gDramAddrMask) < myGUS.memsize) {
return GUSRam[myGUS.gDramAddr & myGUS.gDramAddrMask];
} else {
return 0;
}
@ -1576,7 +1588,8 @@ static void write_gus(Bitu port,Bitu val,Bitu iolen) {
ExecuteGlobRegister();
break;
case 0x307:
if(myGUS.gDramAddr < myGUS.memsize) GUSRam[myGUS.gDramAddr] = (Bit8u)val;
if ((myGUS.gDramAddr & myGUS.gDramAddrMask) < myGUS.memsize)
GUSRam[myGUS.gDramAddr & myGUS.gDramAddrMask] = (Bit8u)val;
break;
case 0x306:
case 0x706:
@ -1822,6 +1835,9 @@ void GUS_StartDMA() {
LOG(LOG_MISC,LOG_DEBUG)("GUS: Starting DMA transfer interval");
PIC_AddEvent(GUS_DMA_Event,GUS_DMA_Event_interval_init);
if (GetDMAChannel(myGUS.dma1)->masked)
LOG(LOG_MISC,LOG_WARN)("GUS: DMA transfer interval started when channel is masked");
if (gus_warn_dma_conflict)
LOG(LOG_MISC,LOG_WARN)(
"GUS warning: Both DMA channels set to the same channel WITHOUT combining! "
@ -1980,8 +1996,13 @@ public:
memset(&myGUS,0,sizeof(myGUS));
memset(GUSRam,0,1024*1024);
unmask_irq = section->Get_bool("pic unmask irq");
enable_autoamp = section->Get_bool("autoamp");
startup_ultrinit = section->Get_bool("startup initialized");
dma_enable_on_dma_control_polling = section->Get_bool("dma enable on dma control polling");
string s_pantable = section->Get_string("gus panning table");
if (s_pantable == "default" || s_pantable == "" || s_pantable == "accurate")
gus_fixed_table = true;
@ -2142,6 +2163,8 @@ public:
if (myGUS.initUnmaskDMA)
GetDMAChannel(myGUS.dma1)->SetMask(false);
if (unmask_irq)
PIC_SetIRQMask(myGUS.irq1,false);
gus_chan->Enable(true);
@ -2163,7 +2186,19 @@ public:
// master volume update, updates ALL pairs
GUS_ICS2101.updateVolPair(gus_ICS2101::MASTER_OUTPUT_PORT);
}
}
// Default to GUS MAX 1MB maximum
myGUS.gDramAddrMask = 0xFFFFF;
// if instructed, configure the card as if ULTRINIT had been run
if (startup_ultrinit) {
myGUS.gRegData=0x700;
GUSReset();
myGUS.gRegData=0x700;
GUSReset();
}
}
void DOS_Startup() {
int portat = 0x200+GUS_BASE;

View File

@ -138,6 +138,10 @@ static struct {
bool rightctrl_pressed;
} keyb;
void PCjr_stuff_scancode(const unsigned char c) {
keyb.p60data = c;
}
uint8_t Mouse_GetButtonState(void);
uint32_t Keyb_ig_status() {

View File

@ -34,6 +34,7 @@
#include "setup.h"
#include "paging.h"
#include "programs.h"
#include "zipfile.h"
#include "regs.h"
#ifndef WIN32
# include <stdlib.h>
@ -45,6 +46,8 @@
#include <string.h>
extern ZIPFile savestate_zip;
static MEM_Callout_t lfb_mem_cb = MEM_Callout_t_none;
static MEM_Callout_t lfb_mmio_cb = MEM_Callout_t_none;
@ -1724,12 +1727,62 @@ void MEM_InitCallouts(void) {
MEM_callouts[MEM_callouts_index(MEM_TYPE_MB)].resize(64);
}
void MEM_LoadState(Section *sec) {
(void)sec;//UNUSED
if (MemBase != NULL) {
ZIPFileEntry *ent = savestate_zip.get_entry("memory.bin");
if (ent != NULL) {
ent->rewind();
if ((memory.pages*4096) == ent->file_length)
ent->read(MemBase, memory.pages*4096);
else
LOG_MSG("Memory load state failure: Memory size mismatch");
}
}
{
ZIPFileEntry *ent = savestate_zip.get_entry("memory.txt");
if (ent != NULL) {
zip_nv_pair_map nv(*ent);
memory.a20.enabled = nv.get_bool("a20.enabled");
memory.a20.controlport = (Bit8u)nv.get_ulong("a20.controlport");
a20_guest_changeable = nv.get_bool("a20_guest_changeable");
a20_fake_changeable = nv.get_bool("a20_fake_changeable");
}
}
}
void MEM_SaveState(Section *sec) {
(void)sec;//UNUSED
if (MemBase != NULL) {
ZIPFileEntry *ent = savestate_zip.new_entry("memory.bin");
if (ent != NULL) {
ent->write(MemBase, memory.pages*4096);
}
}
{
ZIPFileEntry *ent = savestate_zip.new_entry("memory.txt");
if (ent != NULL) {
zip_nv_write(*ent, "a20.enabled", memory.a20.enabled);
zip_nv_write_hex(*ent,"a20.controlport", memory.a20.controlport);
zip_nv_write(*ent, "a20_guest_changeable", a20_guest_changeable);
zip_nv_write(*ent, "a20_fake_changeable", a20_fake_changeable);
}
}
}
void Init_RAM() {
Section_prop * section=static_cast<Section_prop *>(control->GetSection("dosbox"));
Bitu i;
/* please let me know about shutdown! */
if (!has_Init_RAM) {
AddVMEventFunction(VM_EVENT_LOAD_STATE,AddVMEventFunctionFuncPair(MEM_LoadState));
AddVMEventFunction(VM_EVENT_SAVE_STATE,AddVMEventFunctionFuncPair(MEM_SaveState));
AddExitFunction(AddExitFunctionFuncPair(ShutDownRAM));
has_Init_RAM = true;
}

View File

@ -327,6 +327,11 @@ public:
// TODO: PC-98 does have one parallel port, if at all
if (IS_PC98_ARCH) return;
#if C_PRINTER
// we can only have one printer redirection, hence the variable
bool printer_used = false;
#endif
// default ports & interrupts
Bit8u defaultirq[] = { 7, 5, 12};
Section_prop *section = static_cast <Section_prop*>(configuration);
@ -361,7 +366,26 @@ public:
}
}
else
if(str=="disabled") {
#if C_PRINTER
// allow printer redirection on a single port
if (str == "printer" && !printer_used)
{
CPrinterRedir* cprd = new CPrinterRedir(i, defaultirq[i], &cmd);
if (cprd->InstallationSuccessful)
{
parallelPortObjects[i] = cprd;
printer_used = true;
}
else
{
LOG_MSG("Error: printer is not enabled.");
delete cprd;
parallelPortObjects[i] = 0;
}
}
else
#endif
if(str=="disabled") {
parallelPortObjects[i] = 0;
} else if (str == "disney") {
if (!DISNEY_HasInit()) {

File diff suppressed because it is too large Load Diff

View File

@ -1 +1,248 @@
/*
* Copyright (C) 2002-2013 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//#include <dosbox.h>
#include "config.h"
#if C_PRINTER
#if !defined __PRINTER_H
#define __PRINTER_H
#ifdef C_LIBPNG
#include <png.h>
#endif
#include "SDL.h"
#include <ft2build.h>
#include FT_FREETYPE_H
#if defined (WIN32)
#include <windows.h>
#include <winspool.h>
#endif
#define Z_BEST_COMPRESSION 9
#define Z_DEFAULT_STRATEGY 0
#define STYLE_PROP 0x01
#define STYLE_CONDENSED 0x02
#define STYLE_BOLD 0x04
#define STYLE_DOUBLESTRIKE 0x08
#define STYLE_DOUBLEWIDTH 0x10
#define STYLE_ITALICS 0x20
#define STYLE_UNDERLINE 0x40
#define STYLE_SUPERSCRIPT 0x80
#define STYLE_SUBSCRIPT 0x100
#define STYLE_STRIKETHROUGH 0x200
#define STYLE_OVERSCORE 0x400
#define STYLE_DOUBLEWIDTHONELINE 0x800
#define STYLE_DOUBLEHEIGHT 0x1000
#define SCORE_NONE 0x00
#define SCORE_SINGLE 0x01
#define SCORE_DOUBLE 0x02
#define SCORE_SINGLEBROKEN 0x05
#define SCORE_DOUBLEBROKEN 0x06
#define QUALITY_DRAFT 0x01
#define QUALITY_LQ 0x02
#define COLOR_BLACK 7<<5
enum Typeface
{
roman = 0,
sansserif,
courier,
prestige,
script,
ocrb,
ocra,
orator,
orators,
scriptc,
romant,
sansserifh,
svbusaba = 30,
svjittra = 31
};
class CPrinter {
public:
CPrinter (Bit16u dpi, Bit16u width, Bit16u height, char* output, bool multipageOutput);
virtual ~CPrinter();
// Process one character sent to virtual printer
void printChar(Bit8u ch);
// Hard Reset (like switching printer off and on)
void resetPrinterHard();
// Set Autofeed value
void setAutofeed(bool feed);
// Get Autofeed value
bool getAutofeed();
// True if printer is unable to process more data right now (do not use printChar)
bool isBusy();
// True if the last sent character was received
bool ack();
// Manual formfeed
void formFeed();
// Returns true if the current page is blank
bool isBlank();
private:
// used to fill the color "sub-pallettes"
void FillPalette(Bit8u redmax, Bit8u greenmax, Bit8u bluemax, Bit8u colorID,
SDL_Palette* pal);
// Checks if given char belongs to a command and process it. If false, the character
// should be printed
bool processCommandChar(Bit8u ch);
// Resets the printer to the factory settings
void resetPrinter();
// Reload font. Must be called after changing dpi, style or cpi
void updateFont();
// Clears page. If save is true, saves the current page to a bitmap
void newPage(bool save, bool resetx);
// Blits the given glyph on the page surface. If add is true, the values of bitmap are
// added to the values of the pixels in the page
void blitGlyph(FT_Bitmap bitmap, Bit16u destx, Bit16u desty, bool add);
// Draws an anti-aliased line from (fromx, y) to (tox, y). If broken is true, gaps are included
void drawLine(Bitu fromx, Bitu tox, Bitu y, bool broken);
// Setup the bitGraph structure
void setupBitImage(Bit8u dens, Bit16u numCols);
// Process a character that is part of bit image. Must be called iff bitGraph.remBytes > 0.
void printBitGraph(Bit8u ch);
// Copies the codepage mapping from the constant array to CurMap
void selectCodepage(Bit16u cp);
// Output current page
void outputPage();
// Prints out a byte using ASCII85 encoding (only outputs something every four bytes). When b>255, closes the ASCII85 string
void fprintASCII85(FILE* f, Bit16u b);
// Closes a multipage document
void finishMultipage();
// Returns value of the num-th pixel (couting left-right, top-down) in a safe way
Bit8u getPixel(Bit32u num);
FT_Library FTlib; // FreeType2 library used to render the characters
SDL_Surface* page; // Surface representing the current page
FT_Face curFont; // The font currently used to render characters
Bit8u color;
Real64 curX, curY; // Position of the print head (in inch)
Bit16u dpi; // dpi of the page
Bit16u ESCCmd; // ESC-command that is currently processed
bool ESCSeen; // True if last read character was an ESC (0x1B)
bool FSSeen; // True if last read character was an FS (0x1C) (IBM commands)
Bit8u numParam, neededParam; // Numbers of parameters already read/needed to process command
Bit8u params[20]; // Buffer for the read params
Bit16u style; // Style of font (see STYLE_* constants)
Real64 cpi, actcpi; // CPI value set by program and the actual one (taking in account font types)
Bit8u score; // Score for lines (see SCORE_* constants)
Real64 topMargin, bottomMargin, rightMargin, leftMargin; // Margins of the page (in inch)
Real64 pageWidth, pageHeight; // Size of page (in inch)
Real64 defaultPageWidth, defaultPageHeight; // Default size of page (in inch)
Real64 lineSpacing; // Size of one line (in inch)
Real64 horiztabs[32]; // Stores the set horizontal tabs (in inch)
Bit8u numHorizTabs; // Number of configured tabs
Real64 verttabs[16]; // Stores the set vertical tabs (in inch)
Bit8u numVertTabs; // Number of configured tabs
Bit8u curCharTable; // Currently used char table und charset
Bit8u printQuality; // Print quality (see QUALITY_* constants)
Typeface LQtypeFace; // Typeface used in LQ printing mode
Real64 extraIntraSpace; // Extra space between two characters (set by program, in inch)
bool charRead; // True if a character was read since the printer was last initialized
bool autoFeed; // True if a LF should automatically added after a CR
bool printUpperContr; // True if the upper command characters should be printed
struct bitGraphicParams // Holds information about printing bit images
{
Bit16u horizDens, vertDens; // Density of image to print (in dpi)
bool adjacent; // Print adjacent pixels? (ignored)
Bit8u bytesColumn; // Bytes per column
Bit16u remBytes; // Bytes left to read before image is done
Bit8u column[6]; // Bytes of the current and last column
Bit8u readBytesColumn; // Bytes read so far for the current column
} bitGraph;
Bit8u densk, densl, densy, densz; // Image density modes used in ESC K/L/Y/Z commands
Bit16u curMap[256]; // Currently used ASCII => Unicode mapping
Bit16u charTables[4]; // Charactertables
Real64 definedUnit; // Unit used by some ESC/P2 commands (negative => use default)
bool multipoint; // If multipoint mode is enabled
Real64 multiPointSize; // Point size of font in multipoint mode
Real64 multicpi; // CPI used in multipoint mode
Real64 hmi; // Horizontal motion index (in inch; overrides CPI settings)
Bit8u msb; // MSB mode
Bit16u numPrintAsChar; // Number of bytes to print as characters (even when normally control codes)
#if defined (WIN32)
HDC printerDC; // Win32 printer device
#endif
char* output; // Output method selected by user
void* outputHandle; // If not null, additional pages will be appended to the given handle
bool multipageOutput; // If true, all pages are combined to one file/print job etc. until the "eject page" button is pressed
Bit16u multiPageCounter; // Current page (when printing multipages)
Bit8u ASCII85Buffer[4]; // Buffer used in ASCII85 encoding
Bit8u ASCII85BufferPos; // Position in ASCII85 encode buffer
Bit8u ASCII85CurCol; // Columns printed so far in the current lines
};
#endif
#endif

View File

@ -0,0 +1,72 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "dosbox.h"
#if C_PRINTER
#include "parport.h"
//#include "callback.h"
#include "printer_redir.h"
// Purpose of this is to pass LPT register access to the virtual printer
CPrinterRedir::CPrinterRedir(Bitu nr, Bit8u initIrq, CommandLine* cmd)
:CParallel (cmd, nr, initIrq) {
InstallationSuccessful = PRINTER_isInited();
}
CPrinterRedir::~CPrinterRedir () {
// close file
}
bool CPrinterRedir::Putchar(Bit8u val)
{
Write_CON(0xD4);
// strobe data out
Write_PR(val);
Write_CON(0xD5); // strobe pulse
Write_CON(0xD4); // strobe off
Read_SR(); // clear ack
#if PARALLEL_DEBUG
log_par(dbg_putchar,"putchar 0x%2x",val);
if(dbg_plainputchar) fprintf(debugfp,"%c",val);
#endif
return true;
}
Bitu CPrinterRedir::Read_PR() {
return PRINTER_readdata(0,1);
}
Bitu CPrinterRedir::Read_COM() {
return PRINTER_readcontrol(0,1);
}
Bitu CPrinterRedir::Read_SR() {
return PRINTER_readstatus(0,1);
}
void CPrinterRedir::Write_PR(Bitu val) {
PRINTER_writedata(0,val,1);
}
void CPrinterRedir::Write_CON(Bitu val) {
PRINTER_writecontrol(0,val,1);
}
void CPrinterRedir::Write_IOSEL(Bitu val) {
// nothing
}
void CPrinterRedir::handleUpperEvent(Bit16u type) {}
#endif // C_PRINTER

View File

@ -320,7 +320,17 @@ static Bitu read_data(Bitu port,Bitu iolen) {
/* PC/XT NMI mask register 0xA0. Documentation on the other bits
* is sparse and spread across the internet, but many seem to
* agree that bit 7 is used to enable/disable the NMI (1=enable,
* 0=disable) */
* 0=disable)
*
* Confirmed: IBM PCjr technical reference, BIOS source code.
* Some part of the code writes 0x80 to this port,
* then does some work, then writes 0x00.
*
* IBM PCjr definitions:
* bit[7]: Enable NMI
* bit[6]: IR test enable
* bit[5]: Select clock 1 input
* bit[4]: Disable HRQ */
static void pc_xt_nmi_write(Bitu port,Bitu val,Bitu iolen) {
(void)iolen;//UNUSED
(void)port;//UNUSED
@ -772,6 +782,14 @@ void PIC_Reset(Section *sec) {
enable_slave_pic = section->Get_bool("enable slave pic");
enable_pc_xt_nmi_mask = section->Get_bool("enable pc nmi mask");
if (enable_slave_pic && machine == MCH_PCJR && enable_pc_xt_nmi_mask) {
LOG(LOG_MISC,LOG_DEBUG)("PIC_Reset(): PCjr emulation with NMI mask register requires disabling slave PIC (IRQ 8-15)");
enable_slave_pic = false;
}
if (!enable_slave_pic && IS_PC98_ARCH)
LOG(LOG_MISC,LOG_DEBUG)("PIC_Reset(): PC-98 emulation without slave PIC (IRQ 8-15) is unusual");
/* NTS: This is a good guess. But the 8259 is static circuitry and not driven by a clock.
* But the ability to respond to interrupts is limited by the CPU, too. */
PIC_irq_delay_ns = 1000000000UL / (unsigned long)PIT_TICK_RATE;

View File

@ -2258,9 +2258,9 @@ static void CTMIXER_Reset(void) {
_WHICH_[0]= ((((_VAL_) & 0xf0) >> 3)|(sb.type==SBT_16 ? 1:3)); \
_WHICH_[1]= ((((_VAL_) & 0x0f) << 1)|(sb.type==SBT_16 ? 1:3)); \
#define MAKEPROVOL(_WHICH_) \
((((_WHICH_[0] & 0x1e) << 3) | ((_WHICH_[1] & 0x1e) >> 1)) & (sb.type==SBT_16 ? 0xff:0xee))
#define MAKEPROVOL(_WHICH_) \
((((_WHICH_[0] & 0x1e) << 3) | ((_WHICH_[1] & 0x1e) >> 1)) | \
((sb.type==SBT_PRO1 || sb.type==SBT_PRO2) ? 0x11:0))
// TODO: Put out the various hardware listed here, do some listening tests to confirm the emulation is accurate.
void updateSoundBlasterFilter(Bitu rate) {

View File

@ -135,6 +135,7 @@
#include "pc98_gdc_const.h"
#include "mixer.h"
#include "menu.h"
#include "mem.h"
#include <string.h>
#include <stdlib.h>
@ -145,6 +146,10 @@
# pragma warning(disable:4244) /* const fmath::local::uint64_t to double possible loss of data */
#endif
#include "zipfile.h"
extern ZIPFile savestate_zip;
using namespace std;
extern int vga_memio_delay_ns;
@ -164,6 +169,8 @@ extern uint8_t pc98_egc_srcmask[2]; /* host given (Neko: eg
extern uint8_t pc98_egc_maskef[2]; /* effective (Neko: egc.mask2) */
extern uint8_t pc98_egc_mask[2]; /* host given (Neko: egc.mask) */
uint32_t S3_LFB_BASE = S3_LFB_BASE_DEFAULT;
VGA_Type vga;
SVGA_Driver svga;
int enableCGASnow;
@ -191,6 +198,9 @@ bool pc98_graphics_hide_odd_raster_200line = false;
bool pc98_attr4_graphic = false;
bool gdc_analog = true;
bool pc98_31khz_mode = false;
bool int10_vesa_map_as_128kb = false;
unsigned char VGA_AC_remap = AC_4x4;
unsigned int vga_display_start_hretrace = 0;
float hretrace_fx_avg_weight = 3;
@ -522,6 +532,8 @@ VGA_Vsync VGA_Vsync_Decode(const char *vsyncmodestr) {
return VS_Off;
}
bool has_pcibus_enable(void);
void VGA_Reset(Section*) {
Section_prop * section=static_cast<Section_prop *>(control->GetSection("dosbox"));
string str;
@ -531,6 +543,30 @@ void VGA_Reset(Section*) {
GDC_display_plane_wait_for_vsync = section->Get_bool("pc-98 buffer page flip");
S3_LFB_BASE = section->Get_hex("svga lfb base");
if (S3_LFB_BASE == 0) S3_LFB_BASE = S3_LFB_BASE_DEFAULT;
/* no farther than 32MB below the top */
if (S3_LFB_BASE > 0xFE000000UL)
S3_LFB_BASE = 0xFE000000UL;
if (has_pcibus_enable()) {
/* must be 32MB aligned (PCI) */
S3_LFB_BASE += 0x0FFFFFFUL;
S3_LFB_BASE &= ~0x1FFFFFFUL;
}
else {
/* must be 64KB aligned (ISA) */
S3_LFB_BASE += 0x7FFFUL;
S3_LFB_BASE &= ~0xFFFFUL;
}
/* must not overlap system RAM */
if (S3_LFB_BASE < (MEM_TotalPages()*4096))
S3_LFB_BASE = (MEM_TotalPages()*4096);
LOG(LOG_VGA,LOG_DEBUG)("S3 linear framebuffer at 0x%lx",(unsigned long)S3_LFB_BASE);
pc98_allow_scanline_effect = section->Get_bool("pc-98 allow scanline effect");
mainMenu.get_item("pc98_allow_200scanline").check(pc98_allow_scanline_effect).refresh_item(mainMenu);
@ -551,6 +587,23 @@ void VGA_Reset(Section*) {
// EGC implies 16-color
if (enable_pc98_16color) enable_pc98_16color = true;
str = section->Get_string("vga attribute controller mapping");
if (str == "4x4")
VGA_AC_remap = AC_4x4;
else if (str == "4low")
VGA_AC_remap = AC_low4;
else {
/* auto:
*
* 4x4 by default.
* except for ET4000 which is 4low */
VGA_AC_remap = AC_4x4;
if (IS_VGA_ARCH) {
if (svgaCard == SVGA_TsengET3K || svgaCard == SVGA_TsengET4K)
VGA_AC_remap = AC_low4;
}
}
str = section->Get_string("pc-98 video mode");
if (str == "31khz")
pc98_31khz_mode = true;
@ -599,6 +652,7 @@ void VGA_Reset(Section*) {
vga_sierra_lock_565 = section->Get_bool("sierra ramdac lock 565");
hretrace_fx_avg_weight = section->Get_double("hretrace effect weight");
ignore_vblank_wraparound = section->Get_bool("ignore vblank wraparound");
int10_vesa_map_as_128kb = section->Get_bool("vesa map non-lfb modes to 128kb region");
vga_enable_hretrace_effects = section->Get_bool("allow hretrace effects");
enable_page_flip_debugging_marker = section->Get_bool("page flip debug line");
vga_palette_update_on_full_load = section->Get_bool("vga palette update on full load");
@ -1087,6 +1141,106 @@ void VGA_Destroy(Section*) {
PC98_FM_Destroy(NULL);
}
extern uint8_t pc98_pal_analog[256*3]; /* G R B 0x0..0xF */
extern uint8_t pc98_pal_digital[8]; /* G R B 0x0..0x7 */
void pc98_update_palette(void);
void VGA_LoadState(Section *sec) {
(void)sec;//UNUSED
if (IS_PC98_ARCH) {
{
ZIPFileEntry *ent = savestate_zip.get_entry("vga.pc98.analog.palette.bin");
if (ent != NULL) {
ent->rewind();
ent->read(pc98_pal_analog, 256*3);
}
}
{
ZIPFileEntry *ent = savestate_zip.get_entry("vga.pc98.digital.palette.bin");
if (ent != NULL) {
ent->rewind();
ent->read(pc98_pal_digital, 8);
}
}
pc98_update_palette();
}
else {
{
ZIPFileEntry *ent = savestate_zip.get_entry("vga.ac.palette.bin");
if (ent != NULL) {
ent->rewind();
ent->read(vga.attr.palette, 0x10);
}
}
{
unsigned char tmp[256 * 3];
ZIPFileEntry *ent = savestate_zip.get_entry("vga.dac.palette.bin");
if (ent != NULL) {
ent->rewind();
ent->read(tmp, 256 * 3);
for (unsigned int c=0;c < 256;c++) {
vga.dac.rgb[c].red = tmp[c*3 + 0];
vga.dac.rgb[c].green = tmp[c*3 + 1];
vga.dac.rgb[c].blue = tmp[c*3 + 2];
}
}
}
for (unsigned int i=0;i < 0x10;i++)
VGA_ATTR_SetPalette(i,vga.attr.palette[i]);
VGA_DAC_UpdateColorPalette();
}
}
void VGA_SaveState(Section *sec) {
(void)sec;//UNUSED
if (IS_PC98_ARCH) {
{
ZIPFileEntry *ent = savestate_zip.new_entry("vga.pc98.analog.palette.bin");
if (ent != NULL) {
ent->write(pc98_pal_analog, 256*3);
}
}
{
ZIPFileEntry *ent = savestate_zip.new_entry("vga.pc98.digital.palette.bin");
if (ent != NULL) {
ent->write(pc98_pal_digital, 8);
}
}
}
else {
{
ZIPFileEntry *ent = savestate_zip.new_entry("vga.ac.palette.bin");
if (ent != NULL) {
ent->write(vga.attr.palette, 0x10);
}
}
{
unsigned char tmp[256 * 3];
ZIPFileEntry *ent = savestate_zip.new_entry("vga.dac.palette.bin");
if (ent != NULL) {
for (unsigned int c=0;c < 256;c++) {
tmp[c*3 + 0] = vga.dac.rgb[c].red;
tmp[c*3 + 1] = vga.dac.rgb[c].green;
tmp[c*3 + 2] = vga.dac.rgb[c].blue;
}
ent->write(tmp, 256 * 3);
}
}
}
}
void VGA_Init() {
string str;
Bitu i,j;
@ -1150,6 +1304,9 @@ void VGA_Init() {
AddExitFunction(AddExitFunctionFuncPair(VGA_Destroy));
AddVMEventFunction(VM_EVENT_RESET,AddVMEventFunctionFuncPair(VGA_Reset));
AddVMEventFunction(VM_EVENT_LOAD_STATE,AddVMEventFunctionFuncPair(VGA_LoadState));
AddVMEventFunction(VM_EVENT_SAVE_STATE,AddVMEventFunctionFuncPair(VGA_SaveState));
}
void SVGA_Setup_Driver(void) {

View File

@ -76,16 +76,41 @@ void VGA_ATTR_SetPalette(Bit8u index, Bit8u val) {
val &= 63;
vga.attr.palette[index] = val;
if (!IS_EGA_ARCH) {
if (IS_VGA_ARCH) {
// apply the plane mask
val = vga.attr.palette[index & vga.attr.color_plane_enable];
// replace bits 4-5 if configured
if (vga.attr.mode_control & 0x80)
val = (val&0xf) | (vga.attr.color_select << 4);
// Tseng ET4000AX behavior (according to how COPPER.EXE treats the hardware)
// and according to real hardware:
//
// - If P54S (palette select bits 5-4) are enabled, replace bits 7-4 of the
// color index with the entire color select register. COPPER.EXE line fading
// tricks will not work correctly otherwise.
//
// - If P54S is not enabled, then do not apply any Color Select register bits.
// This is contrary to standard VGA behavior that would always apply Color
// Select bits 3-2 to index bits 7-6 in any mode other than 256-color mode.
if (VGA_AC_remap == AC_low4) {
if (vga.attr.mode_control & 0x80)
val = (val&0xf) | (vga.attr.color_select << 4);
}
// normal VGA/SVGA behavior:
//
// - ignore color select in 256-color mode entirely
//
// - otherwise, if P54S is enabled, replace bits 5-4 with bits 1-0 of color select.
//
// - always replace bits 7-6 with bits 3-2 of color select.
else {
if (!(vga.mode == M_VGA || vga.mode == M_LIN8)) {
// replace bits 5-4 if P54S is enabled
if (vga.attr.mode_control & 0x80)
val = (val&0xf) | ((vga.attr.color_select & 0x3) << 4);
// set bits 6 and 7 (not relevant for EGA)
val |= (vga.attr.color_select & 0xc) << 4;
// always replace bits 7-6
val |= (vga.attr.color_select & 0xc) << 4;
}
}
// apply
VGA_DAC_CombineColor(index,val);

View File

@ -91,24 +91,40 @@ static void VGA_DAC_SendColor( Bitu index, Bitu src ) {
void VGA_DAC_UpdateColor( Bitu index ) {
Bitu maskIndex;
if (IS_EGA_ARCH) {
VGA_DAC_SendColor( index, index );
if (IS_VGA_ARCH) {
if (vga.mode == M_VGA || vga.mode == M_LIN8) {
/* WARNING: This code assumes index < 256 */
switch (VGA_AC_remap) {
case AC_4x4:
default: // <- just in case
/* Standard VGA hardware (including the original IBM PS/2 hardware) */
maskIndex = vga.dac.combine[index&0xF] & 0x0F;
maskIndex += (vga.dac.combine[index>>4u] & 0x0F) << 4u;
maskIndex &= vga.dac.pel_mask;
break;
case AC_low4:
/* Tseng ET4000 behavior, according to the SVGA card I have where only the low 4 bits are translated. --J.C. */
maskIndex = vga.dac.combine[index&0xF] & 0x0F;
/* FIXME: TEST THIS ON THE ACTUAL ET4000. This seems to make COPPER.EXE work correctly.
* Is this what actual ET4000 hardware does in 256-color mode with Color Select? */
if (vga.attr.mode_control & 0x80)
maskIndex += vga.attr.color_select << 4;
else
maskIndex += index & 0xF0;
maskIndex &= vga.dac.pel_mask;
break;
}
}
else {
maskIndex = vga.dac.combine[index&0xF] & vga.dac.pel_mask;
}
VGA_DAC_SendColor( index, maskIndex );
}
else {
switch (vga.mode) {
case M_VGA:
case M_LIN8:
maskIndex = index & vga.dac.pel_mask;
VGA_DAC_SendColor( index, maskIndex );
break;
default:
/* Remember the lookup table is there to handle the color palette AND the DAC mask AND the attribute controller palette */
/* FIXME: Is it: index -> attribute controller -> dac mask, or
* index -> dac mask -> attribute controller? */
maskIndex = vga.dac.combine[index&0xF] & vga.dac.pel_mask;
VGA_DAC_SendColor( index, maskIndex );
break;
}
VGA_DAC_SendColor( index, index );
}
}
@ -120,7 +136,7 @@ void VGA_DAC_UpdateColorPalette() {
void write_p3c6(Bitu port,Bitu val,Bitu iolen) {
(void)iolen;//UNUSED
(void)port;//UNUSED
if((IS_VGA_ARCH) && (svgaCard==SVGA_None) && (vga.dac.hidac_counter>3)) {
if((IS_VGA_ARCH) && (vga.dac.hidac_counter>3)) {
vga.dac.reg02=val;
vga.dac.hidac_counter=0;
VGA_StartResize();
@ -221,28 +237,7 @@ void write_p3c9(Bitu port,Bitu val,Bitu iolen) {
}
if (update) {
switch (vga.mode) {
case M_VGA:
case M_LIN8:
VGA_DAC_UpdateColor( vga.dac.write_index );
if ( GCC_UNLIKELY( vga.dac.pel_mask != 0xff)) {
Bitu index = vga.dac.write_index;
if ( (index & vga.dac.pel_mask) == index ) {
for ( Bitu i = index+1;i<256;i++)
if ( (i & vga.dac.pel_mask) == index )
VGA_DAC_UpdateColor( i );
}
}
break;
default:
/* Check for attributes and DAC entry link */
for (Bitu i=0;i<16;i++) {
if (vga.dac.combine[i]==vga.dac.write_index) {
VGA_DAC_SendColor( i, vga.dac.write_index );
}
}
break;
}
VGA_DAC_UpdateColorPalette(); // FIXME: Yes, this is very inefficient. Will improve later.
/* only if we just completed a color should we advance */
if (vga.dac.pel_index == 0)
@ -278,15 +273,31 @@ Bitu read_p3c9(Bitu port,Bitu iolen) {
}
void VGA_DAC_CombineColor(Bit8u attr,Bit8u pal) {
/* Check if this is a new color */
vga.dac.combine[attr]=pal;
switch (vga.mode) {
case M_LIN8:
break;
case M_VGA:
// used by copper demo; almost no video card seems to support it
// Update: supported by ET4000AX (and not by ET4000AF)
default:
vga.dac.combine[attr] = pal;
if (IS_VGA_ARCH) {
if (vga.mode == M_VGA || vga.mode == M_LIN8) {
switch (VGA_AC_remap) {
case AC_4x4:
default: // <- just in case
/* Standard VGA hardware (including the original IBM PS/2 hardware) */
for (unsigned int i=(unsigned int)attr;i < 0x100;i += 0x10)
VGA_DAC_UpdateColor( i );
for (unsigned int i=0;i < 0x10;i++)
VGA_DAC_UpdateColor( i + (attr<<4u) );
break;
case AC_low4:
/* Tseng ET4000 behavior, according to the SVGA card I have where only the low 4 bits are translated. --J.C. */
for (unsigned int i=(unsigned int)attr;i < 0x100;i += 0x10)
VGA_DAC_UpdateColor( i );
break;
}
}
else {
VGA_DAC_UpdateColor( attr );
}
}
else {
VGA_DAC_SendColor( attr, pal );
}
}

View File

@ -468,7 +468,7 @@ static Bit8u * VGA_Draw_Xlat32_VGA_CRTC_bmode_Line(Bitu vidstart, Bitu /*line*/)
float a = 1.0 / (hretrace_fx_avg_weight + 1);
hretrace_fx_avg *= 1.0 - a;
hretrace_fx_avg += a * skip * ((int)vga_display_start_hretrace - (int)vga.crtc.start_horizontal_retrace);
hretrace_fx_avg += a * 4 * ((int)vga_display_start_hretrace - (int)vga.crtc.start_horizontal_retrace);
int x = (int)floor(hretrace_fx_avg + 0.5);
vidstart += (Bitu)((int)skip * (x >> 2));
@ -493,6 +493,32 @@ static Bit8u * VGA_Draw_Xlat32_VGA_CRTC_bmode_Line(Bitu vidstart, Bitu /*line*/)
static Bit8u * VGA_Draw_Xlat32_Linear_Line(Bitu vidstart, Bitu /*line*/) {
Bit32u* temps = (Bit32u*) TempLine;
/* hack for Surprise! productions "copper" demo.
* when the demo talks about making the picture waver, what it's doing is diddling
* with the Start Horizontal Retrace register of the CRTC once per scanline.
* ...yeah, really. It's a wonder in retrospect the programmer didn't burn out his
* VGA monitor, and I bet this makes the demo effect unwatchable on LCD flat panels or
* scan converters that rely on the pulses to detect VGA mode changes! */
if (vga_enable_hretrace_effects) {
/* NTS: This is NOT BACKWARDS. It makes sense if you think about it: the monitor
* begins swinging the electron beam back on horizontal retract, so if the
* retrace starts sooner, then the blanking on the left side appears to last
* longer because there are more clocks until active display.
*
* Also don't forget horizontal total/blank/retrace etc. registers are in
* character clocks not pixels. In 320x200x256 mode, one character clock is
* 4 pixels.
*
* Finally, we average it with "weight" because CRTs have "inertia" */
float a = 1.0 / (hretrace_fx_avg_weight + 1);
hretrace_fx_avg *= 1.0 - a;
hretrace_fx_avg += a * 4 * ((int)vga_display_start_hretrace - (int)vga.crtc.start_horizontal_retrace);
int x = (int)floor(hretrace_fx_avg + 0.5);
vidstart += (Bitu)((int)x);
}
for(Bitu i = 0; i < (vga.draw.line_length>>2); i++)
temps[i]=vga.dac.xlat32[vga.draw.linear_base[(vidstart+i)&vga.draw.linear_mask]];
@ -2214,7 +2240,6 @@ void VGA_SetupDrawing(Bitu /*val*/) {
vtotal |= (vga.crtc.overflow & 0x20u) << 4u;
vtotal |= (vga.s3.ex_ver_overflow & 0x1u) << 10u;
vtotal += 2u;
vdend |= (vga.crtc.overflow & 0x40u) << 3u;
vdend |= (vga.s3.ex_ver_overflow & 0x2u) << 9u;
vbstart |= (vga.crtc.maximum_scan_line & 0x20u) << 4u;

View File

@ -31,6 +31,9 @@
#include "cpu.h"
#include "pc98_cg.h"
#include "pc98_gdc.h"
#include "zipfile.h"
extern ZIPFile savestate_zip;
extern bool non_cga_ignore_oddeven;
extern bool non_cga_ignore_oddeven_engage;
@ -178,7 +181,7 @@ static inline Bitu VGA_Generic_Read_Handler(PhysPt planeaddr,PhysPt rawaddr,unsi
* Then when addressing VRAM A0 is replaced by a "higher order bit", which is
* probably A14 or A16 depending on Extended Memory bit 1 in Sequencer register 04h memory mode */
if ((vga.gfx.miscellaneous&2) && !non_cga_ignore_oddeven_engage) {/* Odd/Even enable */
const PhysPt mask = (1u << hobit_n) - 2u;
const PhysPt mask = (vga.config.compatible_chain4 ? 0u : ~0xFFFFu) + (1u << hobit_n) - 2u;
const PhysPt hobit = (planeaddr >> hobit_n) & 1u;
/* 1 << 14 = 0x4000
* 1 << 14 - 1 = 0x3FFF
@ -187,7 +190,7 @@ static inline Bitu VGA_Generic_Read_Handler(PhysPt planeaddr,PhysPt rawaddr,unsi
planeaddr = (planeaddr & mask & (vga.mem.memmask >> 2u)) + hobit;
}
else {
const PhysPt mask = (1u << hobit_n) - 1u;
const PhysPt mask = (vga.config.compatible_chain4 ? 0u : ~0xFFFFu) + (1u << hobit_n) - 1u;
planeaddr &= mask & (vga.mem.memmask >> 2u);
}
@ -236,7 +239,7 @@ template <const bool chained> static inline void VGA_Generic_Write_Handler(PhysP
* Then when addressing VRAM A0 is replaced by a "higher order bit", which is
* probably A14 or A16 depending on Extended Memory bit 1 in Sequencer register 04h memory mode */
if ((vga.gfx.miscellaneous&2) && !non_cga_ignore_oddeven_engage) {/* Odd/Even enable */
const PhysPt mask = (1u << hobit_n) - 2u;
const PhysPt mask = (vga.config.compatible_chain4 ? 0u : ~0xFFFFu) + (1u << hobit_n) - 2u;
const PhysPt hobit = (planeaddr >> hobit_n) & 1u;
/* 1 << 14 = 0x4000
* 1 << 14 - 1 = 0x3FFF
@ -245,7 +248,7 @@ template <const bool chained> static inline void VGA_Generic_Write_Handler(PhysP
planeaddr = (planeaddr & mask & (vga.mem.memmask >> 2u)) + hobit;
}
else {
const PhysPt mask = (1u << hobit_n) - 1u;
const PhysPt mask = (vga.config.compatible_chain4 ? 0u : ~0xFFFFu) + (1u << hobit_n) - 1u;
planeaddr &= mask & (vga.mem.memmask >> 2u);
}
@ -2069,6 +2072,32 @@ static void VGA_Memory_ShutDown(Section * /*sec*/) {
}
}
void VGAMEM_LoadState(Section *sec) {
(void)sec;//UNUSED
if (MemBase != NULL) {
ZIPFileEntry *ent = savestate_zip.get_entry("vga.memory.bin");
if (ent != NULL) {
ent->rewind();
if (vga.mem.memsize == ent->file_length)
ent->read(vga.mem.linear, vga.mem.memsize);
else
LOG_MSG("VGA Memory load state failure: VGA Memory size mismatch");
}
}
}
void VGAMEM_SaveState(Section *sec) {
(void)sec;//UNUSED
if (vga.mem.linear != NULL) {
ZIPFileEntry *ent = savestate_zip.new_entry("vga.memory.bin");
if (ent != NULL) {
ent->write(vga.mem.linear, vga.mem.memsize);
}
}
}
void VGA_SetupMemory() {
vga.svga.bank_read = vga.svga.bank_write = 0;
vga.svga.bank_read_full = vga.svga.bank_write_full = 0;
@ -2094,6 +2123,9 @@ void VGA_SetupMemory() {
vga.svga.bank_size = 0x10000; /* most common bank size is 64K */
if (!VGA_Memory_ShutDown_init) {
AddVMEventFunction(VM_EVENT_LOAD_STATE,AddVMEventFunctionFuncPair(VGAMEM_LoadState));
AddVMEventFunction(VM_EVENT_SAVE_STATE,AddVMEventFunctionFuncPair(VGAMEM_SaveState));
AddExitFunction(AddExitFunctionFuncPair(VGA_Memory_ShutDown));
VGA_Memory_ShutDown_init = true;
}

View File

@ -171,6 +171,7 @@ void FinishSetMode_PVGA1A(Bitu /*crtc_base*/, VGA_ModeExtraData* modeData) {
// vga.vmemwrap = 256*1024;
}
// FIXME: What? Is this needed?
vga.config.compatible_chain4 = false;
VGA_SetupHandlers();

View File

@ -7377,21 +7377,61 @@ void ROMBIOS_Init() {
}
}
//! \brief Updates the state of a lockable key.
void UpdateKeyWithLed(int nVirtKey, int flagAct, int flagLed);
void BIOS_SynchronizeNumLock()
{
#if defined(WIN32)
auto flag = mem_readb(BIOS_KEYBOARD_FLAGS1);
auto leds = mem_readb(BIOS_KEYBOARD_LEDS);
auto stat = GetKeyState(VK_NUMLOCK);
if (stat & 1) {
flag |= 0x20;
leds |= 0x02;
}
else {
flag &= ~0x20;
leds &= ~0x02;
}
mem_writeb(BIOS_KEYBOARD_FLAGS1, flag);
mem_writeb(BIOS_KEYBOARD_LEDS, leds);
UpdateKeyWithLed(VK_NUMLOCK, BIOS_KEYBOARD_FLAGS1_NUMLOCK_ACTIVE, BIOS_KEYBOARD_LEDS_NUM_LOCK);
#endif
}
void BIOS_SynchronizeCapsLock()
{
#if defined(WIN32)
UpdateKeyWithLed(VK_CAPITAL, BIOS_KEYBOARD_FLAGS1_CAPS_LOCK_ACTIVE, BIOS_KEYBOARD_LEDS_CAPS_LOCK);
#endif
}
void BIOS_SynchronizeScrollLock()
{
#if defined(WIN32)
UpdateKeyWithLed(VK_SCROLL, BIOS_KEYBOARD_FLAGS1_SCROLL_LOCK_ACTIVE, BIOS_KEYBOARD_LEDS_SCROLL_LOCK);
#endif
}
void UpdateKeyWithLed(int nVirtKey, int flagAct, int flagLed)
{
#if defined(WIN32)
const auto state = GetKeyState(nVirtKey);
const auto flags1 = BIOS_KEYBOARD_FLAGS1;
const auto flags2 = BIOS_KEYBOARD_LEDS;
auto flag1 = mem_readb(flags1);
auto flag2 = mem_readb(flags2);
if (state & 1)
{
flag1 |= flagAct;
flag2 |= flagLed;
}
else
{
flag1 &= ~flagAct;
flag2 &= ~flagLed;
}
mem_writeb(flags1, flag1);
mem_writeb(flags2, flag2);
#else
(void)nVirtKey;
(void)flagAct;
(void)flagLed;
#endif
}

View File

@ -41,7 +41,7 @@
* The proper way is in the mapper, but the repeating key is an unwanted side effect for lower versions of SDL */
#endif
static Bitu call_int16 = 0,call_irq1 = 0,irq1_ret_ctrlbreak_callback = 0,call_irq6 = 0;
static Bitu call_int16 = 0,call_irq1 = 0,irq1_ret_ctrlbreak_callback = 0,call_irq6 = 0,call_irq_pcjr_nmi = 0;
/* Nice table from BOCHS i should feel bad for ripping this */
#define none 0
@ -1215,23 +1215,13 @@ static Bitu IRQ1_Handler_PC98(void) {
}
static Bitu PCjr_NMI_Keyboard_Handler(void) {
Bitu save_eax = reg_eax;
#if 0
Bitu DEBUG_EnableDebugger(void);
DEBUG_EnableDebugger();
#endif
if (IO_ReadB(0x64) & 1) /* while data is available */
reg_eip++; /* skip over EIP to IRQ1 call through */
while (IO_ReadB(0x64) & 1) { /* while data is available */
Bitu save_ip = reg_eip;
/* HACK: IRQ1 handler modifies AX and IP. So do we!
* The NMI handler is registered as CB_IRET which does not save any registers.
* To avoid causing crashes and glitches, save and restore the CPU registers affected NOW.
*
* I don't think the PCjr has the INT 15h hook that AT systems do. */
reg_al=IO_ReadB(0x60);
IRQ1_Handler();
reg_eip = save_ip;
}
reg_ax = save_eax;
return CBRET_NONE;
}
@ -1399,6 +1389,7 @@ Bitu INT16_Handler_Wrap(void) {
//Keyboard initialisation. src/gui/sdlmain.cpp
extern bool startup_state_numlock;
extern bool startup_state_capslock;
extern bool startup_state_scrlock;
static void InitBiosSegment(void) {
/* Setup the variables for keyboard in the bios data segment */
@ -1412,8 +1403,9 @@ static void InitBiosSegment(void) {
#if 0 /*SDL_VERSION_ATLEAST(1, 2, 14)*/
//Nothing, mapper handles all.
#else
if (startup_state_capslock) { flag1|=0x40; leds|=0x04;}
if (startup_state_numlock) { flag1|=0x20; leds|=0x02;}
if (startup_state_capslock) { flag1|=BIOS_KEYBOARD_FLAGS1_CAPS_LOCK_ACTIVE; leds|=BIOS_KEYBOARD_LEDS_CAPS_LOCK;}
if (startup_state_numlock) { flag1|=BIOS_KEYBOARD_FLAGS1_NUMLOCK_ACTIVE; leds|=BIOS_KEYBOARD_LEDS_NUM_LOCK;}
if (startup_state_scrlock) { flag1|=BIOS_KEYBOARD_FLAGS1_SCROLL_LOCK_ACTIVE; leds|=BIOS_KEYBOARD_LEDS_SCROLL_LOCK;}
#endif
mem_writeb(BIOS_KEYBOARD_FLAGS1,flag1);
@ -1435,6 +1427,10 @@ void BIOS_UnsetupKeyboard(void) {
CALLBACK_DeAllocate(call_irq1);
call_irq1 = 0;
}
if (call_irq_pcjr_nmi != 0) {
CALLBACK_DeAllocate(call_irq_pcjr_nmi);
call_irq_pcjr_nmi = 0;
}
if (call_irq6 != 0) {
CALLBACK_DeAllocate(call_irq6);
call_irq6 = 0;
@ -1465,11 +1461,27 @@ void BIOS_SetupKeyboard(void) {
call_irq1=CALLBACK_Allocate();
if (machine == MCH_PCJR) { /* PCjr keyboard interrupt connected to NMI */
/* FIXME: This doesn't take INT 15h hook into consideration */
CALLBACK_Setup(call_irq1,&PCjr_NMI_Keyboard_Handler,CB_IRET,"PCjr NMI Keyboard");
RealSetVec(0x02/*NMI*/,CALLBACK_RealPointer(call_irq1));
call_irq_pcjr_nmi=CALLBACK_Allocate();
CALLBACK_Setup(call_irq_pcjr_nmi,&PCjr_NMI_Keyboard_Handler,CB_IRET,"PCjr NMI Keyboard");
Bit32u a = CALLBACK_RealPointer(call_irq_pcjr_nmi);
RealSetVec(0x02/*NMI*/,a);
/* TODO: PCjr calls INT 48h to convert PCjr scan codes to IBM PC/XT compatible */
a = ((a >> 16) << 4) + (a & 0xFFFF);
/* a+0 = callback instruction (4 bytes)
* a+4 = iret (1 bytes) */
phys_writeb(a+5,0x50); /* push ax */
phys_writew(a+6,0x60E4); /* in al,60h */
phys_writew(a+8,0x09CD); /* int 9h */
phys_writeb(a+10,0x58); /* pop ax */
phys_writew(a+11,0x00EB + ((256-13)<<8)); /* jmp a+0 */
}
else if (IS_PC98_ARCH) {
if (IS_PC98_ARCH) {
CALLBACK_Setup(call_irq1,&IRQ1_Handler_PC98,CB_IRET_EOI_PIC1,Real2Phys(BIOS_DEFAULT_IRQ1_LOCATION),"IRQ 1 Keyboard PC-98");
RealSetVec(0x09/*IRQ 1*/,BIOS_DEFAULT_IRQ1_LOCATION);
}

View File

@ -19,8 +19,7 @@
#include "vga.h"
/* TODO: Make this user-configurable */
#define S3_LFB_BASE 0xE0000000u
extern uint32_t S3_LFB_BASE;
#define BIOSMEM_SEG 0x40u
@ -138,6 +137,7 @@ typedef struct {
Bit16u pmode_interface_start;
Bit16u pmode_interface_window;
Bit16u pmode_interface_palette;
Bit16u vesa_alloc_modes;
Bit16u used;
} rom;
Bit16u vesa_setmode;
@ -151,6 +151,8 @@ typedef struct {
#define _S3_PIXEL_DOUBLE 0x0008
#define _REPEAT1 0x0010 /* VGA doublescan (bit 0 of max scanline) */
#define _CGA_SYNCDOUBLE 0x0020
#define _USER_DISABLED 0x4000 /* disabled (cannot set mode) but still listed in modelist */
#define _USER_MODIFIED 0x8000 /* user modified (through VESAMOED) */
extern Int10Data int10;

View File

@ -26,11 +26,13 @@
#include "mouse.h"
#include "vga.h"
#include "bios.h"
#include "programs.h"
#define SEQ_REGS 0x05
#define GFX_REGS 0x09
#define ATT_REGS 0x15
extern bool int10_vesa_map_as_128kb;
extern bool allow_vesa_lowres_modes;
extern bool vesa12_modes_32bpp;
extern bool allow_vesa_32bpp;
@ -142,11 +144,19 @@ VideoModeBlock ModeList_VGA[]={
// if you select VGA 320x200 with S3 acceleration.
{ 0x153 ,M_LIN8 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , _S3_PIXEL_DOUBLE | _REPEAT1 },
{ 0x15C ,M_LIN8, 512 ,384 ,64 ,48 ,8, 8 ,1 ,0xA0000 ,0x10000,168 ,806 ,128,768 , _S3_PIXEL_DOUBLE | _DOUBLESCAN },
{ 0x159 ,M_LIN8, 400 ,300 ,50 ,37 ,8 ,8 ,1 ,0xA0000 ,0x10000,132 ,628 ,100,600 , _S3_PIXEL_DOUBLE | _DOUBLESCAN },
{ 0x15D ,M_LIN16, 512 ,384 ,64 ,48 ,8, 16 ,1 ,0xA0000 ,0x10000,168 ,806 ,128,768 , _S3_PIXEL_DOUBLE | _DOUBLESCAN },
{ 0x15A ,M_LIN16, 400 ,300 ,50 ,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,132 ,628 ,100,600 , _S3_PIXEL_DOUBLE | _DOUBLESCAN },
{ 0x160 ,M_LIN15 ,320 ,240 ,40 ,30 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 , 80 ,480 , _REPEAT1 },
{ 0x161 ,M_LIN15 ,320 ,400 ,40 ,50 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 , 80 ,400 ,0 },
{ 0x162 ,M_LIN15 ,320 ,480 ,40 ,60 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 , 80 ,480 ,0 },
{ 0x165 ,M_LIN15 ,640 ,400 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0x10000,200 ,449 ,160 ,400 ,0 },
// hack: 320x200x16bpp for "Process" demo (1997) with apparently hard-coded VBE mode
{ 0x136 ,M_LIN16 ,320 ,240 ,40 ,30 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 , 80 ,480 , _REPEAT1 },
// hack: 320x480x256-color alias for Habitual demo. doing this removes the need to run S3VBE20.EXE before running the demo.
// the reason it has to be this particular video mode is because HABITUAL.EXE does not query modes, it simply assumes
// that mode 0x166 is this particular mode and errors out if it can't set it.
@ -510,13 +520,24 @@ static bool SetCurMode(VideoModeBlock modeblock[],Bit16u mode) {
while (modeblock[i].mode!=0xffff) {
if (modeblock[i].mode!=mode)
i++;
/* Hack for VBE 1.2 modes and 24/32bpp ambiguity */
/* Hack for VBE 1.2 modes and 24/32bpp ambiguity UNLESS the user changed the mode */
else if (modeblock[i].mode >= 0x100 && modeblock[i].mode <= 0x11F &&
!(modeblock[i].special & _USER_MODIFIED) &&
((modeblock[i].type == M_LIN32 && !vesa12_modes_32bpp) ||
(modeblock[i].type == M_LIN24 && vesa12_modes_32bpp))) {
/* ignore */
i++;
}
/* ignore deleted modes */
else if (modeblock[i].type == M_ERROR) {
/* ignore */
i++;
}
/* ignore disabled modes */
else if (modeblock[i].special & _USER_DISABLED) {
/* ignore */
i++;
}
else {
if ((!int10.vesa_oldvbe) || (ModeList_VGA[i].mode<0x120)) {
CurMode=&modeblock[i];
@ -1362,6 +1383,12 @@ bool INT10_SetVideoMode(Bit16u mode) {
case M_LIN16:
case M_LIN24:
case M_LIN32:
gfx_data[0x5]|=0x40; //256 color mode
if (int10_vesa_map_as_128kb)
gfx_data[0x6]|=0x01; //graphics mode at 0xa000-bffff
else
gfx_data[0x6]|=0x05; //graphics mode at 0xa000-affff
break;
case M_VGA:
gfx_data[0x5]|=0x40; //256 color mode
gfx_data[0x6]|=0x05; //graphics mode at 0xa000-affff
@ -1764,6 +1791,7 @@ Bitu VideoModeMemSize(Bitu mode) {
if (modelist[i].mode==mode) {
/* Hack for VBE 1.2 modes and 24/32bpp ambiguity */
if (modelist[i].mode >= 0x100 && modelist[i].mode <= 0x11F &&
!(modelist[i].special & _USER_MODIFIED) &&
((modelist[i].type == M_LIN32 && !vesa12_modes_32bpp) ||
(modelist[i].type == M_LIN24 && vesa12_modes_32bpp))) {
/* ignore */
@ -1807,3 +1835,302 @@ Bitu VideoModeMemSize(Bitu mode) {
// Return 0 for all other types, those always fit in memory
return 0;
}
Bitu INT10_WriteVESAModeList(Bitu max_modes);
/* ====================== VESAMOED.COM ====================== */
class VESAMOED : public Program {
public:
void Run(void) {
size_t array_i = 0;
std::string arg,tmp;
bool got_opt=false;
int mode = -1;
int fmt = -1;
int w = -1,h = -1;
int ch = -1;
int newmode = -1;
signed char enable = -1;
bool doDelete = false;
bool modefind = false;
cmd->BeginOpt();
while (cmd->GetOpt(/*&*/arg)) {
got_opt=true;
if (arg == "?" || arg == "help") {
doHelp();
break;
}
else if (arg == "mode") {
cmd->NextOptArgv(/*&*/tmp);
if (tmp == "find") {
modefind = true;
}
else if (isdigit(tmp[0])) {
mode = strtoul(tmp.c_str(),NULL,0);
}
else {
WriteOut("Unknown mode '%s'\n",tmp.c_str());
return;
}
}
else if (arg == "fmt") {
cmd->NextOptArgv(/*&*/tmp);
if (tmp == "LIN4")
fmt = M_LIN4;
else if (tmp == "LIN8")
fmt = M_LIN8;
else if (tmp == "LIN15")
fmt = M_LIN15;
else if (tmp == "LIN16")
fmt = M_LIN16;
else if (tmp == "LIN24")
fmt = M_LIN24;
else if (tmp == "LIN32")
fmt = M_LIN32;
else if (tmp == "TEXT")
fmt = M_TEXT;
else {
WriteOut("Unknown format '%s'\n",tmp.c_str());
return;
}
}
else if (arg == "w") {
cmd->NextOptArgv(/*&*/tmp);
w = strtoul(tmp.c_str(),NULL,0);
}
else if (arg == "h") {
cmd->NextOptArgv(/*&*/tmp);
h = strtoul(tmp.c_str(),NULL,0);
}
else if (arg == "ch") {
cmd->NextOptArgv(/*&*/tmp);
ch = strtoul(tmp.c_str(),NULL,0);
}
else if (arg == "newmode") {
cmd->NextOptArgv(/*&*/tmp);
if (isdigit(tmp[0])) {
newmode = strtoul(tmp.c_str(),NULL,0);
}
else {
WriteOut("Unknown newmode '%s'\n",tmp.c_str());
return;
}
}
else if (arg == "delete") {
doDelete = true;
}
// NTS: If you're wondering why we support disabled modes (modes listed but cannot be set),
// there are plenty of scenarios on actual hardware where this occurs. Laptops, for
// example, have SVGA chipsets that can go up to 1600x1200, but the BIOS will disable
// anything above the native resolution of the laptop's LCD display unless an
// external monitor is attached at boot-up.
else if (arg == "disable") {
enable = 0;
}
else if (arg == "enable") {
enable = 1;
}
else {
WriteOut("Unknown switch %s",arg.c_str());
return;
}
}
cmd->EndOpt();
if(!got_opt) {
doHelp();
return;
}
if (modefind) {
if (w < 0 && h < 0 && fmt < 0)
return;
while (ModeList_VGA[array_i].mode != 0xFFFF) {
bool match = true;
if (w > 0 && (Bitu)w != ModeList_VGA[array_i].swidth)
match = false;
else if (h > 0 && (Bitu)h != ModeList_VGA[array_i].sheight)
match = false;
else if (fmt >= 0 && (Bitu)fmt != ModeList_VGA[array_i].type)
match = false;
else if (ModeList_VGA[array_i].type == M_ERROR)
match = false;
else if (ModeList_VGA[array_i].mode <= 0x13)
match = false;
if (!match)
array_i++;
else
break;
}
}
else {
while (ModeList_VGA[array_i].mode != 0xFFFF) {
if (ModeList_VGA[array_i].mode == (Bitu)mode)
break;
array_i++;
}
}
if (ModeList_VGA[array_i].mode == 0xFFFF) {
WriteOut("Mode not found\n");
return;
}
else if (ModeList_VGA[array_i].mode <= 0x13) {
WriteOut("Editing base VGA modes is not allowed\n");
return;
}
else if (modefind) {
WriteOut("Found mode 0x%x\n",(unsigned int)ModeList_VGA[array_i].mode);
}
if (enable == 0)
ModeList_VGA[array_i].special |= _USER_DISABLED;
else if (enable == 1)
ModeList_VGA[array_i].special &= ~_USER_DISABLED;
if (doDelete) {
if (ModeList_VGA[array_i].type != M_ERROR)
WriteOut("Mode 0x%x deleted\n",ModeList_VGA[array_i].mode);
else
WriteOut("Mode 0x%x already deleted\n",ModeList_VGA[array_i].mode);
ModeList_VGA[array_i].type = M_ERROR;
INT10_WriteVESAModeList(int10.rom.vesa_alloc_modes);
return;
}
if (fmt < 0 && ModeList_VGA[array_i].type == M_ERROR) {
WriteOut("Mode 0x%x is still deleted. Set a format with -fmt to un-delete\n",ModeList_VGA[array_i].mode);
return;
}
if (!modefind && (w > 0 || h > 0 || fmt >= 0 || ch > 0)) {
WriteOut("Changing mode 0x%x parameters\n",(unsigned int)ModeList_VGA[array_i].mode);
ModeList_VGA[array_i].special |= _USER_MODIFIED;
if (fmt >= 0) {
ModeList_VGA[array_i].type = (VGAModes)fmt;
/* will require reprogramming width in some cases! */
if (w < 0) w = ModeList_VGA[array_i].swidth;
}
if (w > 0) {
/* enforce alignment to avoid problems with modesetting code */
{
unsigned int aln = 8;
if (ModeList_VGA[array_i].type == M_LIN4)
aln = 16;
w += aln / 2;
w -= w % aln;
if (w == 0) w = aln;
}
ModeList_VGA[array_i].swidth = (Bitu)w;
if (ModeList_VGA[array_i].type == M_LIN15 || ModeList_VGA[array_i].type == M_LIN16) {
ModeList_VGA[array_i].hdispend = (Bitu)w / 4;
ModeList_VGA[array_i].htotal = ModeList_VGA[array_i].hdispend + 40;
}
else {
ModeList_VGA[array_i].hdispend = (Bitu)w / 8;
ModeList_VGA[array_i].htotal = ModeList_VGA[array_i].hdispend + 20;
}
}
if (h > 0) {
ModeList_VGA[array_i].sheight = (Bitu)h;
if (h >= 340)
ModeList_VGA[array_i].special &= ~_REPEAT1;
else
ModeList_VGA[array_i].special |= _REPEAT1;
if (ModeList_VGA[array_i].special & _REPEAT1)
ModeList_VGA[array_i].vdispend = (Bitu)h * 2;
else
ModeList_VGA[array_i].vdispend = (Bitu)h;
ModeList_VGA[array_i].vtotal = ModeList_VGA[array_i].vdispend + 49;
}
if (ch == 8 || ch == 14 || ch == 16)
ModeList_VGA[array_i].cheight = (Bitu)ch;
ModeList_VGA[array_i].twidth = ModeList_VGA[array_i].swidth / ModeList_VGA[array_i].cwidth;
ModeList_VGA[array_i].theight = ModeList_VGA[array_i].sheight / ModeList_VGA[array_i].cheight;
INT10_WriteVESAModeList(int10.rom.vesa_alloc_modes);
}
if (newmode >= 0x40) {
WriteOut("Mode 0x%x moved to mode 0x%x\n",(unsigned int)ModeList_VGA[array_i].mode,(unsigned int)newmode);
ModeList_VGA[array_i].mode = (Bitu)newmode;
INT10_WriteVESAModeList(int10.rom.vesa_alloc_modes);
}
/* if the new mode cannot fit in available memory, then mark as disabled */
{
unsigned int pitch = 0;
switch (ModeList_VGA[array_i].type) {
case M_LIN4:
pitch = (ModeList_VGA[array_i].swidth / 8) * 4; /* not totally accurate but close enough */
break;
case M_LIN8:
pitch = ModeList_VGA[array_i].swidth;
break;
case M_LIN15:
case M_LIN16:
pitch = ModeList_VGA[array_i].swidth * 2;
break;
case M_LIN24:
pitch = ModeList_VGA[array_i].swidth * 3;
break;
case M_LIN32:
pitch = ModeList_VGA[array_i].swidth * 4;
break;
default:
break;
}
if ((pitch * ModeList_VGA[array_i].sheight) > vga.mem.memsize) {
/* NTS: Actually we don't mark as disabled, the VESA mode query function will
* report as disabled automatically for the same check we do. This just
* lets the user know. */
WriteOut("WARNING: Mode %u x %u as specified exceeds video memory, will be disabled\n",
ModeList_VGA[array_i].swidth,
ModeList_VGA[array_i].sheight);
}
}
}
void doHelp(void) {
WriteOut("VESAMOED VESA BIOS mode editor utility\n");
WriteOut("\n");
WriteOut("NOTE: Due to architectual limitations of VBE emulation,\n");
WriteOut(" Adding new modes is not allowed.\n");
WriteOut("\n");
WriteOut(" -mode <x> VBE video mode to edit.\n");
WriteOut(" Specify video mode in decimal or hexadecimal,\n");
WriteOut(" or specify 'find' to match by fmt, width, height.\n");
WriteOut(" -fmt <x> Change pixel format, or mode to find.\n");
WriteOut(" LIN4, LIN8, LIN15, LIN16,\n");
WriteOut(" LIN24, LIN32, TEXT\n");
WriteOut(" -w <x> Change width (in pixels), or mode to find.\n");
WriteOut(" -h <x> Change height (in pixels), or mode to find.\n");
WriteOut(" -ch <x> Change char height (in pixels), or mode to find.\n");
WriteOut(" -newmode <x> Change video mode number\n");
WriteOut(" -delete Delete video mode\n");
WriteOut(" -disable Disable video mode (list but do not allow setting)\n");
WriteOut(" -enable Enable video mode\n");
}
};
void VESAMOED_ProgramStart(Program * * make) {
*make=new VESAMOED;
}

View File

@ -61,7 +61,7 @@ void CALLBACK_DeAllocate(Bitu in);
static char string_oem[]="S3 Incorporated. Trio64";
static char string_vendorname[]="DOSBox Development Team";
static char string_productname[]="DOSBox - The DOS Emulator";
static char string_productrev[]="DOSBox SVN-X";
static char string_productrev[]="2";
#ifdef _MSC_VER
#pragma pack (1)
@ -169,17 +169,20 @@ Bit8u VESA_GetSVGAModeInformation(Bit16u mode,Bit16u seg,Bit16u off) {
mode&=0x3fff; // vbe2 compatible, ignore lfb and keep screen content bits
if (mode<0x100) return 0x01;
if (svga.accepts_mode) {
if (!svga.accepts_mode(mode)) return 0x01;
}
while (ModeList_VGA[i].mode!=0xffff) {
/* Hack for VBE 1.2 modes and 24/32bpp ambiguity */
if (ModeList_VGA[i].mode >= 0x100 && ModeList_VGA[i].mode <= 0x11F &&
!(ModeList_VGA[i].special & _USER_MODIFIED) &&
((ModeList_VGA[i].type == M_LIN32 && !vesa12_modes_32bpp) ||
(ModeList_VGA[i].type == M_LIN24 && vesa12_modes_32bpp))) {
/* ignore */
i++;
}
/* ignore deleted modes */
else if (ModeList_VGA[i].type == M_ERROR) {
/* ignore */
i++;
}
else if (mode==ModeList_VGA[i].mode)
goto foundit;
else
@ -190,6 +193,15 @@ foundit:
if ((int10.vesa_oldvbe) && (ModeList_VGA[i].mode>=0x120)) return 0x01;
VideoModeBlock * mblock=&ModeList_VGA[i];
/* Don't allow querying modes the SVGA card does not accept,
* unless the user modified the mode. */
if (svga.accepts_mode && !(mblock->special & _USER_MODIFIED)) {
if (!svga.accepts_mode(mode)) return 0x01;
}
/* do not return information on deleted modes */
if (mblock->type == M_ERROR) return 0x01;
bool allow_res = allow_vesa_lowres_modes ||
(ModeList_VGA[i].swidth >= 640 && ModeList_VGA[i].sheight >= 400);
@ -300,7 +312,7 @@ foundit:
pageSize &= ~0xFFFFu;
}
Bitu pages = 0;
if (pageSize > vga.mem.memsize) {
if (pageSize > vga.mem.memsize || (mblock->special & _USER_DISABLED)) {
// mode not supported by current hardware configuration
modeAttributes &= ~0x1;
} else if (pageSize) {
@ -608,72 +620,104 @@ static Bitu VESA_PMSetStart(void) {
extern int vesa_modelist_cap;
Bitu INT10_WriteVESAModeList(Bitu max_modes) {
Bitu mode_wptr = int10.rom.vesa_modes;
Bitu i=0,modecount=0;
//TODO Maybe add normal vga modes too, but only seems to complicate things
while (ModeList_VGA[i].mode!=0xffff) {
bool canuse_mode=false;
/* Hack for VBE 1.2 modes and 24/32bpp ambiguity */
if (ModeList_VGA[i].mode >= 0x100 && ModeList_VGA[i].mode <= 0x11F &&
((ModeList_VGA[i].type == M_LIN32 && !vesa12_modes_32bpp) ||
(ModeList_VGA[i].type == M_LIN24 && vesa12_modes_32bpp))) {
/* ignore */
}
/* ignore deleted modes */
else if (ModeList_VGA[i].type == M_ERROR) {
/* ignore */
}
else {
/* If there is no "accepts mode" then accept.
*
* If the user modified the mode, then accept.
* If the mode exceeds video memory, then the mode will be reported as not supported by VESA BIOS functions.
*
* If the SVGA card would accept the mode (generally it's a memsize check), then accept. */
if (!svga.accepts_mode)
canuse_mode=true;
else if (ModeList_VGA[i].special & _USER_MODIFIED)
canuse_mode=true;
else if (svga.accepts_mode(ModeList_VGA[i].mode))
canuse_mode=true;
if (canuse_mode) {
if (ModeList_VGA[i].mode >= 0x100) {
bool allow_res = allow_vesa_lowres_modes ||
(ModeList_VGA[i].swidth >= 640 && ModeList_VGA[i].sheight >= 400);
switch (ModeList_VGA[i].type) {
case M_LIN32: canuse_mode=allow_vesa_32bpp && allow_res; break;
case M_LIN24: canuse_mode=allow_vesa_24bpp && allow_res; break;
case M_LIN16: canuse_mode=allow_vesa_16bpp && allow_res; break;
case M_LIN15: canuse_mode=allow_vesa_15bpp && allow_res; break;
case M_LIN8: canuse_mode=allow_vesa_8bpp && allow_res; break;
case M_LIN4: canuse_mode=allow_vesa_4bpp; break;
case M_TEXT: canuse_mode=allow_vesa_tty; break;
default: break;
}
}
}
}
if (canuse_mode && vesa_modelist_cap > 0 && (unsigned int)modecount >= (unsigned int)vesa_modelist_cap)
canuse_mode = false;
if (canuse_mode && (unsigned int)modecount >= (unsigned int)max_modes)
canuse_mode = false;
if (ModeList_VGA[i].type != M_TEXT) {
if (canuse_mode && vesa_mode_width_cap > 0 && (unsigned int)ModeList_VGA[i].swidth > (unsigned int)vesa_mode_width_cap)
canuse_mode = false;
if (canuse_mode && vesa_mode_height_cap > 0 && (unsigned int)ModeList_VGA[i].sheight > (unsigned int)vesa_mode_height_cap)
canuse_mode = false;
}
if (ModeList_VGA[i].mode>=0x100 && canuse_mode) {
if ((!int10.vesa_oldvbe) || (ModeList_VGA[i].mode<0x120)) {
phys_writew(PhysMake(0xc000,mode_wptr),ModeList_VGA[i].mode);
mode_wptr+=2;
modecount++;
}
}
i++;
}
assert(modecount <= int10.rom.vesa_alloc_modes); /* do not overrun the buffer */
/* after the buffer, is 0xFFFF */
phys_writew(PhysMake(0xc000,mode_wptr),0xFFFF);
mode_wptr+=2;
return modecount;
}
void INT10_SetupVESA(void) {
Bitu i,modecount=0;
/* BUGFIX: Generating VESA BIOS data when machine=ega or machine=vgaonly is dumb.
* Stop wasting ROM space! --J.C. */
if (machine != MCH_VGA) return;
if (svgaCard == SVGA_None) return;
/* Put the mode list somewhere in memory */
Bitu i,modecount=0;
i=0;
int10.rom.vesa_modes=RealMake(0xc000,int10.rom.used);
//TODO Maybe add normal vga modes too, but only seems to complicate things
while (ModeList_VGA[i].mode!=0xffff) {
bool canuse_mode=false;
/* Hack for VBE 1.2 modes and 24/32bpp ambiguity */
if (ModeList_VGA[i].mode >= 0x100 && ModeList_VGA[i].mode <= 0x11F &&
((ModeList_VGA[i].type == M_LIN32 && !vesa12_modes_32bpp) ||
(ModeList_VGA[i].type == M_LIN24 && vesa12_modes_32bpp))) {
/* ignore */
}
else {
if (!svga.accepts_mode)
canuse_mode=true;
else if (svga.accepts_mode(ModeList_VGA[i].mode))
canuse_mode=true;
if (canuse_mode) {
if (ModeList_VGA[i].mode >= 0x100) {
bool allow_res = allow_vesa_lowres_modes ||
(ModeList_VGA[i].swidth >= 640 && ModeList_VGA[i].sheight >= 400);
switch (ModeList_VGA[i].type) {
case M_LIN32: canuse_mode=allow_vesa_32bpp && allow_res; break;
case M_LIN24: canuse_mode=allow_vesa_24bpp && allow_res; break;
case M_LIN16: canuse_mode=allow_vesa_16bpp && allow_res; break;
case M_LIN15: canuse_mode=allow_vesa_15bpp && allow_res; break;
case M_LIN8: canuse_mode=allow_vesa_8bpp && allow_res; break;
case M_LIN4: canuse_mode=allow_vesa_4bpp; break;
case M_TEXT: canuse_mode=allow_vesa_tty; break;
default: break;
}
}
}
}
if (canuse_mode && vesa_modelist_cap > 0 && (unsigned int)modecount >= (unsigned int)vesa_modelist_cap)
canuse_mode = false;
if (ModeList_VGA[i].type != M_TEXT) {
if (canuse_mode && vesa_mode_width_cap > 0 && (unsigned int)ModeList_VGA[i].swidth > (unsigned int)vesa_mode_width_cap)
canuse_mode = false;
if (canuse_mode && vesa_mode_height_cap > 0 && (unsigned int)ModeList_VGA[i].sheight > (unsigned int)vesa_mode_height_cap)
canuse_mode = false;
}
if (ModeList_VGA[i].mode>=0x100 && canuse_mode) {
if ((!int10.vesa_oldvbe) || (ModeList_VGA[i].mode<0x120)) {
phys_writew(PhysMake(0xc000,int10.rom.used),ModeList_VGA[i].mode);
int10.rom.used+=2;
modecount++;
}
}
i++;
}
int10.rom.vesa_alloc_modes = ~0;
int10.rom.vesa_modes = RealMake(0xc000,int10.rom.used);
modecount = INT10_WriteVESAModeList(0xFFFF/*max mode count*/);
int10.rom.vesa_alloc_modes = (Bit16u)modecount;
int10.rom.used += modecount * 2u;
phys_writew(PhysMake(0xc000,int10.rom.used),0xffff);
int10.rom.used+=2;
int10.rom.oemstring=RealMake(0xc000,int10.rom.used);

View File

@ -156,6 +156,7 @@ static struct {
Bit16u hidden;
float add_x,add_y;
Bit16s min_x,max_x,min_y,max_y;
Bit16s max_screen_x,max_screen_y;
float mickey_x,mickey_y;
float x,y;
float ps2x,ps2y;
@ -555,6 +556,14 @@ void DrawCursor() {
void pc98_mouse_movement_apply(int x,int y);
#if !defined(C_SDL2)
bool GFX_IsFullscreen(void);
#else
static inline bool GFX_IsFullscreen(void) {
return false;
}
#endif
/* FIXME: Re-test this code */
void Mouse_CursorMoved(float xrel,float yrel,float x,float y,bool emulate) {
extern bool Mouse_Vertical;
@ -624,10 +633,10 @@ void Mouse_CursorMoved(float xrel,float yrel,float x,float y,bool emulate) {
emu = true;
break;
case MOUSE_EMULATION_INTEGRATION:
emu = !user_cursor_locked;
emu = !user_cursor_locked && !GFX_IsFullscreen();
break;
case MOUSE_EMULATION_LOCKED:
emu = user_cursor_locked;
emu = user_cursor_locked && !GFX_IsFullscreen();
break;
case MOUSE_EMULATION_NEVER:
default:
@ -635,10 +644,19 @@ void Mouse_CursorMoved(float xrel,float yrel,float x,float y,bool emulate) {
}
if (!emu)
{
const auto x1 = 1.0 / static_cast<double>(user_cursor_sw) * user_cursor_x;
const auto y1 = 1.0 / static_cast<double>(user_cursor_sh) * user_cursor_y;
mouse.x = x1 * mouse.max_x;
mouse.y = y1 * mouse.max_y;
auto x1 = (double)user_cursor_x / static_cast<double>(user_cursor_sw - 1);
auto y1 = (double)user_cursor_y / static_cast<double>(user_cursor_sh - 1);
mouse.x = x1 * mouse.max_screen_x;
mouse.y = y1 * mouse.max_screen_y;
if (mouse.x < mouse.min_x)
mouse.x = mouse.min_x;
if (mouse.y < mouse.min_y)
mouse.y = mouse.min_y;
if (mouse.x > mouse.max_x)
mouse.x = mouse.max_x;
if (mouse.y > mouse.max_y)
mouse.y = mouse.max_y;
}
mouse.ps2x += xrel;
@ -880,6 +898,9 @@ void Mouse_NewVideoMode(void) {
mouse.cursorType = 0;
mouse.enabled=true;
mouse.oldhidden=1;
mouse.max_screen_x = mouse.max_x;
mouse.max_screen_y = mouse.max_y;
}
//Much too empty, Mouse_NewVideoMode contains stuff that should be in here
@ -1024,11 +1045,15 @@ static Bitu INT33_Handler(void) {
mouse.textXorMask = reg_dx;
break;
case 0x0b: /* Read Motion Data */
reg_cx=(Bit16u)static_cast<Bit16s>(mouse.mickey_x);
reg_dx=(Bit16u)static_cast<Bit16s>(mouse.mickey_y);
mouse.mickey_x=0;
mouse.mickey_y=0;
break;
{
bool MOUSE_IsLocked();
const auto locked = MOUSE_IsLocked();
reg_cx = (Bit16u)static_cast<Bit16s>(locked ? mouse.mickey_x : 0);
reg_dx = (Bit16u)static_cast<Bit16s>(locked ? mouse.mickey_y : 0);
mouse.mickey_x = 0;
mouse.mickey_y = 0;
break;
}
case 0x0c: /* Define interrupt subroutine parameters */
mouse.sub_mask=reg_cx;
mouse.sub_seg=SegValue(es);

View File

@ -688,6 +688,12 @@ public:
first_umb_seg=section->Get_hex("umb start");
first_umb_size=section->Get_hex("umb end");
/* This code will mess up the MCB chain in PCjr mode if umb=true */
if (umb_available && machine == MCH_PCJR) {
LOG(LOG_MISC,LOG_DEBUG)("UMB emulation is incompatible with PCjr emulation, disabling UMBs");
umb_available = false;
}
DOS_GetMemory_Choose();
// Sanity check

View File

@ -844,7 +844,9 @@ const char *VM_EVENT_string[VM_EVENT_MAX] = {
"DOS exit, reboot begin",
"DOS exit, kernel reboot exit", // 15
"DOS surprise reboot"
"DOS surprise reboot",
"Save state",
"Load state"
};
VMDispatchState vm_dispatch_state;

4
src/output/Makefile.am Normal file
View File

@ -0,0 +1,4 @@
AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/src
noinst_LIBRARIES = liboutput.a
liboutput_a_SOURCES = output_direct3d.cpp output_opengl.cpp output_surface.cpp output_surface_sdl2.cpp output_surface_sdl.cpp output_tools.cpp output_tools_xbrz.cpp

View File

@ -0,0 +1,342 @@
#include <sys/types.h>
#include <assert.h>
#include <math.h>
#include "dosbox.h"
#include <output/output_direct3d.h>
#include "sdlmain.h"
using namespace std;
#if C_DIRECT3D
CDirect3D* d3d = NULL;
static void d3d_init(void)
{
sdl.desktop.want_type = SCREEN_DIRECT3D;
if (!sdl.using_windib)
{
LOG_MSG("Resetting to WINDIB mode");
SDL_QuitSubSystem(SDL_INIT_VIDEO);
putenv("SDL_VIDEODRIVER=windib");
sdl.using_windib = true;
if (SDL_InitSubSystem(SDL_INIT_VIDEO)<0) E_Exit("Can't init SDL Video %s", SDL_GetError());
GFX_SetIcon(); GFX_SetTitle(-1, -1, -1, false);
if (!sdl.desktop.fullscreen) DOSBox_RefreshMenu();
}
SDL_SysWMinfo wmi;
SDL_VERSION(&wmi.version);
if (!SDL_GetWMInfo(&wmi))
{
LOG_MSG("SDL:Error retrieving window information");
LOG_MSG("Failed to get window info");
OUTPUT_SURFACE_Select();
}
else
{
if (sdl.desktop.fullscreen)
GFX_CaptureMouse();
if (d3d) delete d3d;
d3d = new CDirect3D(640, 400);
if (!d3d)
{
LOG_MSG("Failed to create d3d object");
OUTPUT_SURFACE_Select();
return;
}
else if (d3d->InitializeDX(wmi.child_window, sdl.desktop.doublebuf) != S_OK)
{
LOG_MSG("Unable to initialize DirectX");
OUTPUT_SURFACE_Select();
return;
}
}
# if (C_D3DSHADERS)
if (d3d) {
Section_prop *section = static_cast<Section_prop *>(control->GetSection("sdl"));
Prop_multival* prop = section->Get_multival("pixelshader");
if (SUCCEEDED(d3d->LoadPixelShader(prop->GetSection()->Get_string("type"), 0, 0)))
if (menu.startup)
GFX_ResetScreen();
}
# endif
}
// output API below
void OUTPUT_DIRECT3D_Initialize()
{
// nothing to initialize (yet?)
}
void OUTPUT_DIRECT3D_Select()
{
sdl.desktop.want_type = SCREEN_DIRECT3D;
render.aspectOffload = true;
d3d_init();
#if defined(WIN32) && !defined(C_SDL2)
SDL1_hax_inhibit_WM_PAINT = 1;
#endif
}
Bitu OUTPUT_DIRECT3D_GetBestMode(Bitu flags)
{
flags |= GFX_SCALING;
if (GCC_UNLIKELY(d3d->bpp16))
flags &= ~(GFX_CAN_8 | GFX_CAN_15 | GFX_CAN_32);
else
flags &= ~(GFX_CAN_8 | GFX_CAN_15 | GFX_CAN_16);
return flags;
}
Bitu OUTPUT_DIRECT3D_SetSize()
{
Bitu retFlags = 0;
Bit16u fixedWidth;
Bit16u fixedHeight;
Bit16u windowWidth;
Bit16u windowHeight;
Bitu adjTexWidth = sdl.draw.width;
Bitu adjTexHeight = sdl.draw.height;
if (sdl.desktop.fullscreen)
{
fixedWidth = sdl.desktop.full.fixed ? sdl.desktop.full.width : 0;
fixedHeight = sdl.desktop.full.fixed ? sdl.desktop.full.height : 0;
}
else
{
fixedWidth = sdl.desktop.window.width;
fixedHeight = sdl.desktop.window.height;
}
if (fixedWidth == 0 || fixedHeight == 0)
{
Bitu consider_height = menu.maxwindow ? currentWindowHeight : 0;
Bitu consider_width = menu.maxwindow ? currentWindowWidth : 0;
int final_height = max(consider_height, userResizeWindowHeight);
int final_width = max(consider_width, userResizeWindowWidth);
fixedWidth = final_width;
fixedHeight = final_height;
}
#if DOSBOXMENU_TYPE == DOSBOXMENU_SDLDRAW
/* scale the menu bar if the window is large enough */
{
int cw = fixedWidth, ch = fixedHeight;
Bitu scale = 1;
if (cw == 0) cw = (Bit16u)(sdl.draw.width * sdl.draw.scalex);
if (ch == 0) ch = (Bit16u)(sdl.draw.height * sdl.draw.scaley);
while ((cw / scale) >= (640 * 2) && (ch / scale) >= (400 * 2))
scale++;
LOG_MSG("menuScale=%lu", (unsigned long)scale);
mainMenu.setScale(scale);
if (mainMenu.isVisible())
fixedHeight -= mainMenu.menuBox.h;
}
#endif
sdl.clip.x = sdl.clip.y = 0;
if (fixedWidth && fixedHeight)
{
sdl.clip.w = windowWidth = fixedWidth;
sdl.clip.h = windowHeight = fixedHeight;
if (render.aspect) aspectCorrectFitClip(sdl.clip.w, sdl.clip.h, sdl.clip.x, sdl.clip.y, fixedWidth, fixedHeight);
}
else
{
windowWidth = (Bit16u)(sdl.draw.width * sdl.draw.scalex);
windowHeight = (Bit16u)(sdl.draw.height * sdl.draw.scaley);
if (render.aspect) aspectCorrectExtend(windowWidth, windowHeight);
sdl.clip.w = windowWidth; sdl.clip.h = windowHeight;
}
// when xBRZ scaler is used, we can adjust render target size to exactly what xBRZ scaler will output, leaving final scaling to default D3D scaler / shaders
#if C_XBRZ
if (sdl_xbrz.enable && xBRZ_SetScaleParameters(sdl.draw.width, sdl.draw.height, sdl.clip.w, sdl.clip.h))
{
adjTexWidth = sdl.draw.width * sdl_xbrz.scale_factor;
adjTexHeight = sdl.draw.height * sdl_xbrz.scale_factor;
}
#endif
// Calculate texture size
if ((!d3d->square) && (!d3d->pow2))
{
d3d->dwTexWidth = adjTexWidth;
d3d->dwTexHeight = adjTexHeight;
}
else if (d3d->square)
{
int texsize = 2 << int_log2(adjTexWidth > adjTexHeight ? adjTexWidth : adjTexHeight);
d3d->dwTexWidth = d3d->dwTexHeight = texsize;
}
else
{
d3d->dwTexWidth = 2 << int_log2(adjTexWidth);
d3d->dwTexHeight = 2 << int_log2(adjTexHeight);
}
LOG(LOG_MISC, LOG_DEBUG)("GFX_SetSize Direct3D texture=%ux%u window=%ux%u clip=x,y,w,h=%d,%d,%d,%d",
(unsigned int)d3d->dwTexWidth,
(unsigned int)d3d->dwTexHeight,
(unsigned int)windowWidth,
(unsigned int)windowHeight,
(unsigned int)sdl.clip.x,
(unsigned int)sdl.clip.y,
(unsigned int)sdl.clip.w,
(unsigned int)sdl.clip.h);
#if DOSBOXMENU_TYPE == DOSBOXMENU_SDLDRAW
if (mainMenu.isVisible()) {
windowHeight += mainMenu.menuBox.h;
sdl.clip.y += mainMenu.menuBox.h;
}
#endif
#if (C_D3DSHADERS)
Section_prop *section = static_cast<Section_prop *>(control->GetSection("sdl"));
if (section)
{
Prop_multival* prop = section->Get_multival("pixelshader");
std::string f = prop->GetSection()->Get_string("force");
d3d->LoadPixelShader(prop->GetSection()->Get_string("type"), sdl.draw.scalex, sdl.draw.scaley, (f == "forced"));
}
else
{
LOG_MSG("SDL:D3D:Could not get pixelshader info, shader disabled");
}
#endif
d3d->aspect = false;
d3d->autofit = false;
// Create a dummy sdl surface
// D3D will hang or crash when using fullscreen with ddraw surface, therefore we hack SDL to provide
// a GDI window with an additional 0x40 flag. If this fails or stock SDL is used, use WINDIB output
if (GCC_UNLIKELY(d3d->bpp16))
{
sdl.surface = SDL_SetVideoMode(windowWidth, windowHeight, 16, sdl.desktop.fullscreen ? SDL_FULLSCREEN | 0x40 : SDL_RESIZABLE | 0x40);
sdl.deferred_resize = false;
sdl.must_redraw_all = true;
retFlags = GFX_CAN_16 | GFX_SCALING;
}
else
{
sdl.surface = SDL_SetVideoMode(windowWidth, windowHeight, 0, sdl.desktop.fullscreen ? SDL_FULLSCREEN | 0x40 : SDL_RESIZABLE | 0x40);
sdl.deferred_resize = false;
sdl.must_redraw_all = true;
retFlags = GFX_CAN_32 | GFX_SCALING;
}
if (sdl.surface == NULL)
E_Exit("Could not set video mode %ix%i-%i: %s", sdl.clip.w, sdl.clip.h, d3d->bpp16 ? 16 : 32, SDL_GetError());
if (d3d->dynamic) retFlags |= GFX_HARDWARE;
if (GCC_UNLIKELY(d3d->Resize3DEnvironment(windowWidth, windowHeight, sdl.clip.x, sdl.clip.y, sdl.clip.w, sdl.clip.h, adjTexWidth, adjTexHeight, sdl.desktop.fullscreen) != S_OK))
retFlags = 0;
#if LOG_D3D
LOG_MSG("SDL:D3D:Display mode set to: %dx%d with %fx%f scale", sdl.clip.w, sdl.clip.h, sdl.draw.scalex, sdl.draw.scaley);
#endif
#if DOSBOXMENU_TYPE == DOSBOXMENU_SDLDRAW
mainMenu.screenWidth = sdl.surface->w;
mainMenu.updateRect();
mainMenu.setRedraw();
GFX_DrawSDLMenu(mainMenu, mainMenu.display_list);
#endif
return retFlags;
}
bool OUTPUT_DIRECT3D_StartUpdate(Bit8u* &pixels, Bitu &pitch)
{
#if C_XBRZ
if (sdl_xbrz.enable && sdl_xbrz.scale_on)
{
sdl_xbrz.renderbuf.resize(sdl.draw.width * sdl.draw.height);
pixels = sdl_xbrz.renderbuf.empty() ? nullptr : reinterpret_cast<Bit8u*>(&sdl_xbrz.renderbuf[0]);
pitch = sdl.draw.width * sizeof(uint32_t);
sdl.updating = true;
}
else
{
sdl.updating = d3d->LockTexture(pixels, pitch);
}
#else
sdl.updating = d3d->LockTexture(pixels, pitch);
#endif
return sdl.updating;
}
void OUTPUT_DIRECT3D_EndUpdate(const Bit16u *changedLines)
{
#if C_XBRZ
if (sdl_xbrz.enable && sdl_xbrz.scale_on)
{
// we have xBRZ pseudo render buffer to be output to the pre-sized texture, do the xBRZ part
const int srcWidth = sdl.draw.width;
const int srcHeight = sdl.draw.height;
if (sdl_xbrz.renderbuf.size() == srcWidth * srcHeight && srcWidth > 0 && srcHeight > 0)
{
// we assume render buffer is *not* scaled!
int xbrzWidth = srcWidth * sdl_xbrz.scale_factor;
int xbrzHeight = srcHeight * sdl_xbrz.scale_factor;
sdl_xbrz.pixbuf.resize(xbrzWidth * xbrzHeight);
const uint32_t* renderBuf = &sdl_xbrz.renderbuf[0]; // help VS compiler a little + support capture by value
uint32_t* xbrzBuf = &sdl_xbrz.pixbuf[0];
xBRZ_Render(renderBuf, xbrzBuf, changedLines, srcWidth, srcHeight, sdl_xbrz.scale_factor);
// D3D texture can be not of exactly size we expect, so we copy xBRZ buffer to the texture there, adjusting for texture pitch
Bit8u *tgtPix;
Bitu tgtPitch;
if (d3d->LockTexture(tgtPix, tgtPitch) && tgtPix) // if locking fails, target texture can be nullptr
{
uint32_t* tgtTex = reinterpret_cast<uint32_t*>(static_cast<Bit8u*>(tgtPix));
# if defined(XBRZ_PPL)
concurrency::task_group tg;
for (int i = 0; i < xbrzHeight; i += sdl_xbrz.task_granularity)
{
tg.run([=] {
const int iLast = min(i + sdl_xbrz.task_granularity, xbrzHeight);
xbrz::pitchChange(&xbrzBuf[0], &tgtTex[0], xbrzWidth, xbrzHeight, xbrzWidth * sizeof(uint32_t), tgtPitch, i, iLast, [](uint32_t pix) { return pix; });
});
}
tg.wait();
# else
xbrz::pitchChange(&xbrzBuf[0], &tgtTex[0], xbrzWidth, xbrzHeight, xbrzWidth * sizeof(uint32_t), tgtPitch, 0, xbrzHeight, [](uint32_t pix) { return pix; });
# endif
}
}
}
#endif
if (!menu.hidecycles) frames++; //implemented
if (GCC_UNLIKELY(!d3d->UnlockTexture(changedLines)))
E_Exit("Failed to draw screen!");
}
void OUTPUT_DIRECT3D_Shutdown()
{
if (d3d)
delete d3d;
}
#endif /*C_DIRECT3D*/

View File

@ -0,0 +1,22 @@
#include "dosbox.h"
#ifndef DOSBOX_OUTPUT_DIRECT3D_H
#define DOSBOX_OUTPUT_DIRECT3D_H
#if C_DIRECT3D
#include "direct3d/direct3d.h"
extern CDirect3D* d3d;
// output API
void OUTPUT_DIRECT3D_Initialize();
void OUTPUT_DIRECT3D_Select();
Bitu OUTPUT_DIRECT3D_GetBestMode(Bitu flags);
Bitu OUTPUT_DIRECT3D_SetSize();
bool OUTPUT_DIRECT3D_StartUpdate(Bit8u* &pixels, Bitu &pitch);
void OUTPUT_DIRECT3D_EndUpdate(const Bit16u *changedLines);
void OUTPUT_DIRECT3D_Shutdown();
#endif /*C_DIRECT3D*/
#endif /*DOSBOX_OUTPUT_DIRECT3D_H*/

View File

@ -0,0 +1,606 @@
#include <sys/types.h>
#include <assert.h>
#include <math.h>
#include "dosbox.h"
#include <output/output_opengl.h>
#include "sdlmain.h"
using namespace std;
#if C_OPENGL
PFNGLGENBUFFERSARBPROC glGenBuffersARB = NULL;
PFNGLBINDBUFFERARBPROC glBindBufferARB = NULL;
PFNGLDELETEBUFFERSARBPROC glDeleteBuffersARB = NULL;
PFNGLBUFFERDATAARBPROC glBufferDataARB = NULL;
PFNGLMAPBUFFERARBPROC glMapBufferARB = NULL;
PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB = NULL;
#if C_OPENGL && !defined(C_SDL2) && DOSBOXMENU_TYPE == DOSBOXMENU_SDLDRAW
extern unsigned int SDLDrawGenFontTextureUnitPerRow;
extern unsigned int SDLDrawGenFontTextureRows;
extern unsigned int SDLDrawGenFontTextureWidth;
extern unsigned int SDLDrawGenFontTextureHeight;
extern GLuint SDLDrawGenFontTexture;
extern bool SDLDrawGenFontTextureInit;
#endif
SDL_OpenGL sdl_opengl;
int Voodoo_OGL_GetWidth();
int Voodoo_OGL_GetHeight();
bool Voodoo_OGL_Active();
static SDL_Surface* SetupSurfaceScaledOpenGL(Bit32u sdl_flags, Bit32u bpp)
{
Bit16u fixedWidth;
Bit16u fixedHeight;
Bit16u windowWidth;
Bit16u windowHeight;
if (sdl.desktop.prevent_fullscreen) /* 3Dfx openGL do not allow resize */
sdl_flags &= ~((unsigned int)SDL_RESIZABLE);
if (sdl.desktop.want_type == SCREEN_OPENGL)
sdl_flags |= (unsigned int)SDL_OPENGL;
if (sdl.desktop.fullscreen)
{
fixedWidth = sdl.desktop.full.fixed ? sdl.desktop.full.width : 0;
fixedHeight = sdl.desktop.full.fixed ? sdl.desktop.full.height : 0;
sdl_flags |= (unsigned int)(SDL_FULLSCREEN | SDL_HWSURFACE);
}
else
{
fixedWidth = sdl.desktop.window.width;
fixedHeight = sdl.desktop.window.height;
sdl_flags |= (unsigned int)SDL_HWSURFACE;
}
if (fixedWidth == 0 || fixedHeight == 0)
{
Bitu consider_height = menu.maxwindow ? currentWindowHeight : 0;
Bitu consider_width = menu.maxwindow ? currentWindowWidth : 0;
int final_height = max(consider_height, userResizeWindowHeight);
int final_width = max(consider_width, userResizeWindowWidth);
fixedWidth = final_width;
fixedHeight = final_height;
}
#if DOSBOXMENU_TYPE == DOSBOXMENU_SDLDRAW
/* scale the menu bar if the window is large enough */
{
int cw = fixedWidth, ch = fixedHeight;
int scale = 1;
if (cw == 0)
cw = (Bit16u)(sdl.draw.width*sdl.draw.scalex);
if (ch == 0)
ch = (Bit16u)(sdl.draw.height*sdl.draw.scaley);
while ((cw / scale) >= (640 * 2) && (ch / scale) >= (400 * 2))
scale++;
LOG_MSG("menuScale=%d", scale);
mainMenu.setScale((unsigned int)scale);
if (mainMenu.isVisible())
fixedHeight -= mainMenu.menuBox.h;
}
#endif
sdl.clip.x = 0; sdl.clip.y = 0;
if (Voodoo_OGL_GetWidth() != 0 && Voodoo_OGL_GetHeight() != 0 && Voodoo_OGL_Active() && sdl.desktop.prevent_fullscreen)
{
/* 3Dfx openGL do not allow resize */
sdl.clip.w = windowWidth = (Bit16u)Voodoo_OGL_GetWidth();
sdl.clip.h = windowHeight = (Bit16u)Voodoo_OGL_GetHeight();
}
else if (fixedWidth && fixedHeight)
{
sdl.clip.w = windowWidth = fixedWidth;
sdl.clip.h = windowHeight = fixedHeight;
if (render.aspect) aspectCorrectFitClip(sdl.clip.w, sdl.clip.h, sdl.clip.x, sdl.clip.y, fixedWidth, fixedHeight);
}
else
{
windowWidth = (Bit16u)(sdl.draw.width * sdl.draw.scalex);
windowHeight = (Bit16u)(sdl.draw.height * sdl.draw.scaley);
if (render.aspect) aspectCorrectExtend(windowWidth, windowHeight);
sdl.clip.w = windowWidth; sdl.clip.h = windowHeight;
}
LOG(LOG_MISC, LOG_DEBUG)("GFX_SetSize OpenGL window=%ux%u clip=x,y,w,h=%d,%d,%d,%d",
(unsigned int)windowWidth,
(unsigned int)windowHeight,
(unsigned int)sdl.clip.x,
(unsigned int)sdl.clip.y,
(unsigned int)sdl.clip.w,
(unsigned int)sdl.clip.h);
#if DOSBOXMENU_TYPE == DOSBOXMENU_SDLDRAW
if (mainMenu.isVisible())
{
windowHeight += mainMenu.menuBox.h;
sdl.clip.y += mainMenu.menuBox.h;
}
#endif
sdl.surface = SDL_SetVideoMode(windowWidth, windowHeight, (int)bpp, (unsigned int)sdl_flags);
sdl.deferred_resize = false;
sdl.must_redraw_all = true;
/* There seems to be a problem with MesaGL in Linux/X11 where
* the first swap buffer we do is misplaced according to the
* previous window size.
*
* NTS: This seems to have been fixed, which is why this is
* commented out. I guess not calling GFX_SetSize()
* with a 0x0 widthxheight helps! */
// sdl.gfx_force_redraw_count = 2;
UpdateWindowDimensions();
GFX_LogSDLState();
#if DOSBOXMENU_TYPE == DOSBOXMENU_SDLDRAW
mainMenu.screenWidth = (size_t)(sdl.surface->w);
mainMenu.updateRect();
mainMenu.setRedraw();
#endif
return sdl.surface;
}
// output API below
void OUTPUT_OPENGL_Initialize()
{
memset(&sdl_opengl, 0, sizeof(sdl_opengl));
}
void OUTPUT_OPENGL_Select()
{
sdl.desktop.want_type = SCREEN_OPENGL;
render.aspectOffload = true;
#if defined(WIN32) && !defined(C_SDL2)
SDL1_hax_inhibit_WM_PAINT = 0;
#endif
}
Bitu OUTPUT_OPENGL_GetBestMode(Bitu flags)
{
if (!(flags & GFX_CAN_32)) return 0; // OpenGL requires 32-bit output mode
flags |= GFX_SCALING;
flags &= ~(GFX_CAN_8 | GFX_CAN_15 | GFX_CAN_16);
return flags;
}
Bitu OUTPUT_OPENGL_SetSize()
{
Bitu retFlags = 0;
/* NTS: Apparently calling glFinish/glFlush before setup causes a segfault within
* the OpenGL library on Mac OS X. */
if (sdl_opengl.inited)
{
glFinish();
glFlush();
}
if (sdl_opengl.pixel_buffer_object)
{
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0);
if (sdl_opengl.buffer) glDeleteBuffersARB(1, &sdl_opengl.buffer);
}
else if (sdl_opengl.framebuf)
{
free(sdl_opengl.framebuf);
}
sdl_opengl.framebuf = 0;
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
#if SDL_VERSION_ATLEAST(1, 2, 11)
Section_prop* sec = static_cast<Section_prop*>(control->GetSection("vsync"));
if (sec)
SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, (!strcmp(sec->Get_string("vsyncmode"), "host")) ? 1 : 0);
#endif
SetupSurfaceScaledOpenGL(SDL_RESIZABLE, 0);
if (!sdl.surface || sdl.surface->format->BitsPerPixel < 15)
{
LOG_MSG("SDL:OPENGL:Can't open drawing surface, are you running in 16bpp(or higher) mode?");
return 0;
}
glFinish();
glFlush();
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &sdl_opengl.max_texsize);
Bitu adjTexWidth = sdl.draw.width;
Bitu adjTexHeight = sdl.draw.height;
#if C_XBRZ
// we do the same as with Direct3D: precreate pixel buffer adjusted for xBRZ
if (sdl_xbrz.enable && xBRZ_SetScaleParameters(adjTexWidth, adjTexHeight, sdl.clip.w, sdl.clip.h))
{
adjTexWidth = adjTexWidth * sdl_xbrz.scale_factor;
adjTexHeight = adjTexHeight * sdl_xbrz.scale_factor;
}
#endif
int texsize = 2 << int_log2(adjTexWidth > adjTexHeight ? adjTexWidth : adjTexHeight);
if (texsize > sdl_opengl.max_texsize)
{
LOG_MSG("SDL:OPENGL:No support for texturesize of %d (max size is %d), falling back to surface", texsize, sdl_opengl.max_texsize);
return 0;
}
/* Create the texture and display list */
if (sdl_opengl.pixel_buffer_object)
{
glGenBuffersARB(1, &sdl_opengl.buffer);
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, sdl_opengl.buffer);
glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_EXT, adjTexWidth*adjTexHeight * 4, NULL, GL_STREAM_DRAW_ARB);
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0);
}
else
{
sdl_opengl.framebuf = calloc(adjTexWidth*adjTexHeight, 4); //32 bit color
}
sdl_opengl.pitch = adjTexWidth * 4;
glBindTexture(GL_TEXTURE_2D, 0);
#if DOSBOXMENU_TYPE == DOSBOXMENU_SDLDRAW
if (SDLDrawGenFontTextureInit)
{
glDeleteTextures(1, &SDLDrawGenFontTexture);
SDLDrawGenFontTexture = (GLuint)(~0UL);
SDLDrawGenFontTextureInit = 0;
}
#endif
glViewport(0, 0, sdl.surface->w, sdl.surface->h);
glDeleteTextures(1, &sdl_opengl.texture);
glGenTextures(1, &sdl_opengl.texture);
glBindTexture(GL_TEXTURE_2D, sdl_opengl.texture);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, 0);
// No borders
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, sdl_opengl.bilinear ? GL_LINEAR : GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, sdl_opengl.bilinear ? GL_LINEAR : GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, texsize, texsize, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, 0);
sdl_opengl.menudraw_countdown = 2; // two GL buffers
sdl_opengl.clear_countdown = 2; // two GL buffers
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
// SDL_GL_SwapBuffers();
// glClear(GL_COLOR_BUFFER_BIT);
glShadeModel(GL_FLAT);
glBlendFunc(GL_ONE, GL_ZERO);
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glDisable(GL_BLEND);
glDisable(GL_CULL_FACE);
glDisable(GL_ALPHA_TEST);
glDisable(GL_FOG);
glDisable(GL_SCISSOR_TEST);
glDisable(GL_STENCIL_TEST);
glEnable(GL_TEXTURE_2D);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, sdl.surface->w, sdl.surface->h, 0, -1, 1);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glScaled(1.0 / texsize, 1.0 / texsize, 1.0);
// if (glIsList(sdl_opengl.displaylist))
// glDeleteLists(sdl_opengl.displaylist, 1);
// sdl_opengl.displaylist = glGenLists(1);
sdl_opengl.displaylist = 1;
glNewList(sdl_opengl.displaylist, GL_COMPILE);
glBindTexture(GL_TEXTURE_2D, sdl_opengl.texture);
glBegin(GL_QUADS);
glTexCoord2i(0, 0); glVertex2i(sdl.clip.x, sdl.clip.y); // lower left
glTexCoord2i(adjTexWidth, 0); glVertex2i(sdl.clip.x + sdl.clip.w, sdl.clip.y); // lower right
glTexCoord2i(adjTexWidth, adjTexHeight); glVertex2i(sdl.clip.x + sdl.clip.w, sdl.clip.y + sdl.clip.h); // upper right
glTexCoord2i(0, adjTexHeight); glVertex2i(sdl.clip.x, sdl.clip.y + sdl.clip.h); // upper left
glEnd();
glEndList();
glBindTexture(GL_TEXTURE_2D, 0);
#if DOSBOXMENU_TYPE == DOSBOXMENU_SDLDRAW
void GFX_DrawSDLMenu(DOSBoxMenu &menu, DOSBoxMenu::displaylist &dl);
mainMenu.setRedraw();
GFX_DrawSDLMenu(mainMenu, mainMenu.display_list);
// FIXME: Why do we have to reinitialize the font texture?
// if (!SDLDrawGenFontTextureInit) {
GLuint err = 0;
glGetError(); /* read and discard last error */
SDLDrawGenFontTexture = (GLuint)(~0UL);
glGenTextures(1, &SDLDrawGenFontTexture);
if (SDLDrawGenFontTexture == (GLuint)(~0UL) || (err = glGetError()) != 0)
{
LOG_MSG("WARNING: Unable to make font texture. id=%llu err=%lu",
(unsigned long long)SDLDrawGenFontTexture, (unsigned long)err);
}
else
{
LOG_MSG("font texture id=%lu will make %u x %u",
(unsigned long)SDLDrawGenFontTexture,
(unsigned int)SDLDrawGenFontTextureWidth,
(unsigned int)SDLDrawGenFontTextureHeight);
SDLDrawGenFontTextureInit = 1;
glBindTexture(GL_TEXTURE_2D, SDLDrawGenFontTexture);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, 0);
// No borders
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, SDLDrawGenFontTextureWidth, SDLDrawGenFontTextureHeight, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, 0);
/* load the font */
{
extern Bit8u int10_font_16[256 * 16];
unsigned char *bmp;
uint32_t tmp[8 * 16];
unsigned int x, y, c;
for (c = 0; c < 256; c++)
{
bmp = int10_font_16 + (c * 16);
for (y = 0; y < 16; y++)
{
for (x = 0; x < 8; x++)
{
tmp[(y * 8) + x] = (bmp[y] & (0x80 >> x)) ? 0xFFFFFFFFUL : 0x00000000UL;
}
}
glTexSubImage2D(GL_TEXTURE_2D, /*level*/0, /*x*/(int)((c % 16) * 8), /*y*/(int)((c / 16) * 16),
8, 16, GL_BGRA_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, (void*)tmp);
}
}
glBindTexture(GL_TEXTURE_2D, 0);
}
// }
#endif
glFinish();
glFlush();
sdl_opengl.inited = true;
retFlags = GFX_CAN_32 | GFX_SCALING;
if (sdl_opengl.pixel_buffer_object)
retFlags |= GFX_HARDWARE;
return retFlags;
}
bool OUTPUT_OPENGL_StartUpdate(Bit8u* &pixels, Bitu &pitch)
{
#if C_XBRZ
if (sdl_xbrz.enable && sdl_xbrz.scale_on)
{
sdl_xbrz.renderbuf.resize(sdl.draw.width * sdl.draw.height);
pixels = sdl_xbrz.renderbuf.empty() ? nullptr : reinterpret_cast<Bit8u*>(&sdl_xbrz.renderbuf[0]);
pitch = sdl.draw.width * sizeof(uint32_t);
}
else
#endif
{
if (sdl_opengl.pixel_buffer_object)
{
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, sdl_opengl.buffer);
pixels = (Bit8u *)glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, GL_WRITE_ONLY);
}
else
{
pixels = (Bit8u *)sdl_opengl.framebuf;
}
pitch = sdl_opengl.pitch;
}
sdl.updating = true;
return true;
}
void OUTPUT_OPENGL_EndUpdate(const Bit16u *changedLines)
{
if (!(sdl.must_redraw_all && changedLines == NULL))
{
if (sdl_opengl.clear_countdown > 0)
{
sdl_opengl.clear_countdown--;
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
}
if (sdl_opengl.menudraw_countdown > 0)
{
sdl_opengl.menudraw_countdown--;
#if DOSBOXMENU_TYPE == DOSBOXMENU_SDLDRAW
mainMenu.setRedraw();
GFX_DrawSDLMenu(mainMenu, mainMenu.display_list);
#endif
}
#if C_XBRZ
if (sdl_xbrz.enable && sdl_xbrz.scale_on)
{
// OpenGL pixel buffer is precreated for direct xBRZ output, while xBRZ render buffer is used for rendering
const int srcWidth = sdl.draw.width;
const int srcHeight = sdl.draw.height;
if (sdl_xbrz.renderbuf.size() == srcWidth * srcHeight && srcWidth > 0 && srcHeight > 0)
{
// we assume render buffer is *not* scaled!
const uint32_t* renderBuf = &sdl_xbrz.renderbuf[0]; // help VS compiler a little + support capture by value
uint32_t* trgTex;
if (sdl_opengl.pixel_buffer_object)
{
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, sdl_opengl.buffer);
trgTex = (uint32_t *)glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, GL_WRITE_ONLY);
}
else
{
trgTex = reinterpret_cast<uint32_t*>(static_cast<void*>(sdl_opengl.framebuf));
}
if (trgTex)
xBRZ_Render(renderBuf, trgTex, changedLines, srcWidth, srcHeight, sdl_xbrz.scale_factor);
}
// and here we go repeating some stuff with xBRZ related modifications
if (sdl_opengl.pixel_buffer_object)
{
glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT);
glBindTexture(GL_TEXTURE_2D, sdl_opengl.texture);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
sdl.draw.width * sdl_xbrz.scale_factor, sdl.draw.height * sdl_xbrz.scale_factor, GL_BGRA_EXT,
GL_UNSIGNED_INT_8_8_8_8_REV, 0);
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0);
}
else
{
glBindTexture(GL_TEXTURE_2D, sdl_opengl.texture);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
sdl.draw.width * sdl_xbrz.scale_factor, sdl.draw.height * sdl_xbrz.scale_factor, GL_BGRA_EXT,
#if defined (MACOSX)
// needed for proper looking graphics on macOS 10.12, 10.13
GL_UNSIGNED_INT_8_8_8_8,
#else
// works on Linux
GL_UNSIGNED_INT_8_8_8_8_REV,
#endif
(Bit8u *)sdl_opengl.framebuf);
}
glCallList(sdl_opengl.displaylist);
SDL_GL_SwapBuffers();
}
else
#endif /*C_XBRZ*/
if (sdl_opengl.pixel_buffer_object)
{
if (changedLines && (changedLines[0] == sdl.draw.height))
return;
glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT);
glBindTexture(GL_TEXTURE_2D, sdl_opengl.texture);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
(int)sdl.draw.width, (int)sdl.draw.height, GL_BGRA_EXT,
GL_UNSIGNED_INT_8_8_8_8_REV, (void*)0);
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0);
glCallList(sdl_opengl.displaylist);
SDL_GL_SwapBuffers();
}
else if (changedLines)
{
if (changedLines[0] == sdl.draw.height)
return;
Bitu y = 0, index = 0;
glBindTexture(GL_TEXTURE_2D, sdl_opengl.texture);
while (y < sdl.draw.height)
{
if (!(index & 1))
{
y += changedLines[index];
}
else
{
Bit8u *pixels = (Bit8u *)sdl_opengl.framebuf + y * sdl_opengl.pitch;
Bitu height = changedLines[index];
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, (int)y,
(int)sdl.draw.width, (int)height, GL_BGRA_EXT,
#if defined (MACOSX)
// needed for proper looking graphics on macOS 10.12, 10.13
GL_UNSIGNED_INT_8_8_8_8,
#else
// works on Linux
GL_UNSIGNED_INT_8_8_8_8_REV,
#endif
(void*)pixels);
y += height;
}
index++;
}
glCallList(sdl_opengl.displaylist);
#if 0 /* DEBUG Prove to me that you're drawing the damn texture */
glBindTexture(GL_TEXTURE_2D, SDLDrawGenFontTexture);
glPushMatrix();
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glScaled(1.0 / SDLDrawGenFontTextureWidth, 1.0 / SDLDrawGenFontTextureHeight, 1.0);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_ALPHA_TEST);
glEnable(GL_BLEND);
glBegin(GL_QUADS);
glTexCoord2i(0, 0); glVertex2i(0, 0); // lower left
glTexCoord2i(SDLDrawGenFontTextureWidth, 0); glVertex2i(SDLDrawGenFontTextureWidth, 0); // lower right
glTexCoord2i(SDLDrawGenFontTextureWidth, SDLDrawGenFontTextureHeight); glVertex2i(SDLDrawGenFontTextureWidth, SDLDrawGenFontTextureHeight); // upper right
glTexCoord2i(0, SDLDrawGenFontTextureHeight); glVertex2i(0, SDLDrawGenFontTextureHeight); // upper left
glEnd();
glBlendFunc(GL_ONE, GL_ZERO);
glDisable(GL_ALPHA_TEST);
glEnable(GL_TEXTURE_2D);
glPopMatrix();
glBindTexture(GL_TEXTURE_2D, sdl_opengl.texture);
#endif
SDL_GL_SwapBuffers();
}
if (!menu.hidecycles && !sdl.desktop.fullscreen) frames++;
}
}
void OUTPUT_OPENGL_Shutdown()
{
// nothing to shutdown (yet?)
}
#endif

View File

@ -0,0 +1,70 @@
#include "dosbox.h"
#ifndef DOSBOX_OUTPUT_OPENGL_H
#define DOSBOX_OUTPUT_OPENGL_H
#if C_OPENGL
#include "SDL_opengl.h"
#ifndef APIENTRY
#define APIENTRY
#endif
#ifndef APIENTRYP
#define APIENTRYP APIENTRY *
#endif
#ifndef GL_ARB_pixel_buffer_object
#define GL_ARB_pixel_buffer_object 1
#define GL_PIXEL_PACK_BUFFER_ARB 0x88EB
#define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC
#define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED
#define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF
#endif
#ifndef GL_ARB_vertex_buffer_object
#define GL_ARB_vertex_buffer_object 1
typedef void (APIENTRYP PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers);
typedef void (APIENTRYP PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer);
typedef void (APIENTRYP PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers);
typedef void (APIENTRYP PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage);
typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERARBPROC) (GLenum target, GLenum access);
typedef GLboolean(APIENTRYP PFNGLUNMAPBUFFERARBPROC) (GLenum target);
#endif
extern PFNGLGENBUFFERSARBPROC glGenBuffersARB;
extern PFNGLBINDBUFFERARBPROC glBindBufferARB;
extern PFNGLDELETEBUFFERSARBPROC glDeleteBuffersARB;
extern PFNGLBUFFERDATAARBPROC glBufferDataARB;
extern PFNGLMAPBUFFERARBPROC glMapBufferARB;
extern PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB;
struct SDL_OpenGL {
bool inited;
Bitu pitch;
void * framebuf;
GLuint buffer;
GLuint texture;
GLuint displaylist;
GLint max_texsize;
bool bilinear;
bool packed_pixel;
bool paletted_texture;
bool pixel_buffer_object;
int menudraw_countdown;
int clear_countdown;
};
extern SDL_OpenGL sdl_opengl;
// output API
void OUTPUT_OPENGL_Initialize();
void OUTPUT_OPENGL_Select();
Bitu OUTPUT_OPENGL_GetBestMode(Bitu flags);
Bitu OUTPUT_OPENGL_SetSize();
bool OUTPUT_OPENGL_StartUpdate(Bit8u* &pixels, Bitu &pitch);
void OUTPUT_OPENGL_EndUpdate(const Bit16u *changedLines);
void OUTPUT_OPENGL_Shutdown();
#endif //C_OPENGL
#endif /*DOSBOX_OUTPUT_OPENGL_H*/

View File

@ -0,0 +1,212 @@
#include <sys/types.h>
#include <assert.h>
#include <math.h>
#include "dosbox.h"
#include "sdlmain.h"
#include "vga.h"
using namespace std;
// output API below
void OUTPUT_SURFACE_Initialize()
{
// nothing to initialize (yet?)
}
void OUTPUT_SURFACE_Select()
{
sdl.desktop.want_type = SCREEN_SURFACE;
render.aspectOffload = false;
#if defined(WIN32) && !defined(C_SDL2)
SDL1_hax_inhibit_WM_PAINT = 0;
#endif
}
bool OUTPUT_SURFACE_StartUpdate(Bit8u* &pixels, Bitu &pitch)
{
#if C_XBRZ
if (sdl_xbrz.enable && sdl_xbrz.scale_on)
{
sdl_xbrz.renderbuf.resize(sdl.draw.width * sdl.draw.height);
pixels = sdl_xbrz.renderbuf.empty() ? nullptr : reinterpret_cast<Bit8u*>(&sdl_xbrz.renderbuf[0]);
pitch = sdl.draw.width * sizeof(uint32_t);
}
else
#endif
#if C_SURFACE_POSTRENDER_ASPECT
if (render.aspect == ASPECT_NEAREST || render.aspect == ASPECT_BILINEAR)
{
sdl.aspectbuf.resize(sdl.draw.width * sdl.draw.height);
pixels = sdl.aspectbuf.empty() ? nullptr : reinterpret_cast<Bit8u*>(&sdl.aspectbuf[0]);
pitch = sdl.draw.width * sizeof(uint32_t);
}
else
#endif
{
if (sdl.blit.surface)
{
if (SDL_MUSTLOCK(sdl.blit.surface) && SDL_LockSurface(sdl.blit.surface))
return false;
pixels = (Bit8u *)sdl.blit.surface->pixels;
pitch = sdl.blit.surface->pitch;
}
else
{
if (SDL_MUSTLOCK(sdl.surface) && SDL_LockSurface(sdl.surface))
return false;
pixels = (Bit8u *)sdl.surface->pixels;
pixels += sdl.clip.y * sdl.surface->pitch;
pixels += sdl.clip.x * sdl.surface->format->BytesPerPixel;
pitch = sdl.surface->pitch;
}
}
GFX_SDL_Overscan();
sdl.updating = true;
return true;
}
void OUTPUT_SURFACE_EndUpdate(const Bit16u *changedLines)
{
#if DOSBOXMENU_TYPE == DOSBOXMENU_SDLDRAW
GFX_DrawSDLMenu(mainMenu, mainMenu.display_list);
#endif
#if C_XBRZ
if (sdl_xbrz.enable && sdl_xbrz.scale_on)
{
const int srcWidth = sdl.draw.width;
const int srcHeight = sdl.draw.height;
if (sdl_xbrz.renderbuf.size() == srcWidth * srcHeight && srcWidth > 0 && srcHeight > 0)
{
// please use sdl.clip to keep screen positioning consistent with the rest of the emulator
int clipWidth = sdl.clip.w;
int clipHeight = sdl.clip.h;
int clipX = sdl.clip.x;
int clipY = sdl.clip.y;
// 1. xBRZ-scale render buffer into xbrz pixel buffer
int xbrzWidth = 0;
int xbrzHeight = 0;
uint32_t* xbrzBuf;
xbrzWidth = srcWidth * sdl_xbrz.scale_factor;
xbrzHeight = srcHeight * sdl_xbrz.scale_factor;
sdl_xbrz.pixbuf.resize(xbrzWidth * xbrzHeight);
const uint32_t* renderBuf = &sdl_xbrz.renderbuf[0]; // help VS compiler a little + support capture by value
xbrzBuf = &sdl_xbrz.pixbuf[0];
xBRZ_Render(renderBuf, xbrzBuf, changedLines, srcWidth, srcHeight, sdl_xbrz.scale_factor);
// 2. nearest neighbor/bilinear scale xbrz buffer into output surface clipping area
const bool mustLock = SDL_MUSTLOCK(sdl.surface);
if (mustLock) SDL_LockSurface(sdl.surface);
if (sdl.surface->pixels) // if locking fails, this can be nullptr, also check if we really need to draw
{
uint32_t* clipTrg = reinterpret_cast<uint32_t*>(static_cast<char*>(sdl.surface->pixels) + clipY * sdl.surface->pitch + clipX * sizeof(uint32_t));
xBRZ_PostScale(&xbrzBuf[0], xbrzWidth, xbrzHeight, xbrzWidth * sizeof(uint32_t),
&clipTrg[0], clipWidth, clipHeight, sdl.surface->pitch,
sdl_xbrz.postscale_bilinear, sdl_xbrz.task_granularity);
}
if (mustLock) SDL_UnlockSurface(sdl.surface);
if (!menu.hidecycles && !sdl.desktop.fullscreen) frames++;
#if defined(C_SDL2)
SDL_UpdateWindowSurfaceRects(sdl.window, sdl.updateRects, 1);
#else
SDL_Flip(sdl.surface);
#endif
}
}
else
#endif /*C_XBRZ*/
#if C_SURFACE_POSTRENDER_ASPECT
if (render.aspect == ASPECT_NEAREST || render.aspect == ASPECT_BILINEAR) {
// here we go, adjusting source aspect ratio
int clipWidth = sdl.clip.w;
int clipHeight = sdl.clip.h;
int clipX = sdl.clip.x;
int clipY = sdl.clip.y;
const bool mustLock = SDL_MUSTLOCK(sdl.surface);
if (mustLock) SDL_LockSurface(sdl.surface);
if (sdl.surface->pixels) // if locking fails, this can be nullptr, also check if we really need to draw
{
uint32_t* clipTrg = reinterpret_cast<uint32_t*>(static_cast<char*>(sdl.surface->pixels) + clipY * sdl.surface->pitch + clipX * sizeof(uint32_t));
xBRZ_PostScale(&sdl.aspectbuf[0], sdl.draw.width, sdl.draw.height, sdl.draw.width * sizeof(uint32_t),
&clipTrg[0], clipWidth, clipHeight, sdl.surface->pitch,
(render.aspect == ASPECT_BILINEAR), C_SURFACE_POSTRENDER_ASPECT_BATCH_SIZE);
}
if (mustLock) SDL_UnlockSurface(sdl.surface);
if (!menu.hidecycles && !sdl.desktop.fullscreen) frames++;
#if defined(C_SDL2)
SDL_UpdateWindowSurfaceRects(sdl.window, sdl.updateRects, 1);
#else
SDL_Flip(sdl.surface);
#endif
}
else
#endif /*C_SURFACE_POSTRENDER_ASPECT*/
{
if (SDL_MUSTLOCK(sdl.surface)) {
if (sdl.blit.surface) {
SDL_UnlockSurface(sdl.blit.surface);
int Blit = SDL_BlitSurface(sdl.blit.surface, 0, sdl.surface, &sdl.clip);
LOG(LOG_MISC, LOG_WARN)("BlitSurface returned %d", Blit);
}
else {
SDL_UnlockSurface(sdl.surface);
}
if (changedLines && (changedLines[0] == sdl.draw.height))
return;
if (!menu.hidecycles && !sdl.desktop.fullscreen) frames++;
#if defined(C_SDL2)
SDL_UpdateWindowSurface(sdl.window);
#else
SDL_Flip(sdl.surface);
#endif
}
else if (sdl.must_redraw_all) {
#if defined(C_SDL2)
if (changedLines != NULL) SDL_UpdateWindowSurface(sdl.window);
#else
if (changedLines != NULL) SDL_Flip(sdl.surface);
#endif
}
else if (changedLines) {
if (changedLines[0] == sdl.draw.height)
return;
if (!menu.hidecycles && !sdl.desktop.fullscreen) frames++;
Bitu y = 0, index = 0, rectCount = 0;
while (y < sdl.draw.height) {
if (!(index & 1)) {
y += changedLines[index];
}
else {
SDL_Rect *rect = &sdl.updateRects[rectCount++];
rect->x = sdl.clip.x;
rect->y = sdl.clip.y + y;
rect->w = (Bit16u)sdl.draw.width;
rect->h = changedLines[index];
y += changedLines[index];
SDL_rect_cliptoscreen(*rect);
}
index++;
}
if (rectCount) {
#if defined(C_SDL2)
SDL_UpdateWindowSurfaceRects(sdl.window, sdl.updateRects, rectCount);
#else
SDL_UpdateRects(sdl.surface, rectCount, sdl.updateRects);
#endif
}
}
}
}
void OUTPUT_SURFACE_Shutdown()
{
// nothing to shutdown (yet?)
}

View File

@ -0,0 +1,15 @@
#include "dosbox.h"
#ifndef DOSBOX_OUTPUT_SURFACE_H
#define DOSBOX_OUTPUT_SURFACE_H
// output API
void OUTPUT_SURFACE_Initialize();
void OUTPUT_SURFACE_Select();
Bitu OUTPUT_SURFACE_GetBestMode(Bitu flags);
Bitu OUTPUT_SURFACE_SetSize();
bool OUTPUT_SURFACE_StartUpdate(Bit8u* &pixels, Bitu &pitch);
void OUTPUT_SURFACE_EndUpdate(const Bit16u *changedLines);
void OUTPUT_SURFACE_Shutdown();
#endif /*DOSBOX_OUTPUT_SURFACE_H*/

View File

@ -0,0 +1,335 @@
#include <sys/types.h>
#include <assert.h>
#include <math.h>
#include "dosbox.h"
#include "sdlmain.h"
#include "vga.h"
#include <algorithm> // std::transform
using namespace std;
#if !defined(C_SDL2)
Bitu OUTPUT_SURFACE_GetBestMode(Bitu flags)
{
Bitu testbpp, gotbpp;
flags &= ~GFX_LOVE_8; //Disable love for 8bpp modes
/* Check if we can satisfy the depth it loves */
if (flags & GFX_LOVE_8) testbpp = 8;
else if (flags & GFX_LOVE_15) testbpp = 15;
else if (flags & GFX_LOVE_16) testbpp = 16;
else if (flags & GFX_LOVE_32) testbpp = 32;
else testbpp = 0;
if (sdl.desktop.fullscreen)
gotbpp = (unsigned int)SDL_VideoModeOK(640, 480, testbpp,
(unsigned int)SDL_FULLSCREEN | (unsigned int)SDL_HWSURFACE | (unsigned int)SDL_HWPALETTE);
else
gotbpp = sdl.desktop.bpp;
/* SDL 1.x and sometimes SDL 2.x mistake 15-bit 5:5:5 RGB for 16-bit 5:6:5 RGB
* which causes colors to mis-display. This seems to be common with Windows and Linux.
* If SDL said 16-bit but the bit masks suggest 15-bit, then make the correction now. */
if (gotbpp == 16) {
if (sdl.surface->format->Gshift == 5 && sdl.surface->format->Gmask == (31U << 5U)) {
LOG_MSG("NOTE: SDL returned 16-bit/pixel mode (5:6:5) but failed to recognize your screen is 15-bit/pixel mode (5:5:5)");
gotbpp = 15;
}
}
/* If we can't get our favorite mode check for another working one */
switch (gotbpp) {
case 8:
if (flags & GFX_CAN_8) flags &= ~(GFX_CAN_15 | GFX_CAN_16 | GFX_CAN_32);
break;
case 15:
if (flags & GFX_CAN_15) flags &= ~(GFX_CAN_8 | GFX_CAN_16 | GFX_CAN_32);
break;
case 16:
if (flags & GFX_CAN_16) flags &= ~(GFX_CAN_8 | GFX_CAN_15 | GFX_CAN_32);
break;
case 24:
case 32:
if (flags & GFX_CAN_32) flags &= ~(GFX_CAN_8 | GFX_CAN_15 | GFX_CAN_16);
break;
}
flags |= GFX_CAN_RANDOM;
return flags;
}
Bitu OUTPUT_SURFACE_SetSize()
{
Bitu bpp = 0, retFlags = 0;
// localize width and height variables because they can be locally adjusted by aspect ratio correction
retry:
Bitu width = sdl.draw.width;
Bitu height = sdl.draw.height;
if (sdl.draw.flags & GFX_CAN_32)
bpp = 32;
else if (sdl.draw.flags & GFX_CAN_16)
bpp = 16;
else if (sdl.draw.flags & GFX_CAN_15)
bpp = 15;
else if (sdl.draw.flags & GFX_CAN_8)
bpp = 8;
#if defined(WIN32) && !defined(C_SDL2)
/* SDL 1.x might mis-inform us on 16bpp for 15-bit color, which is bad enough.
But on Windows, we're still required to ask for 16bpp to get the 15bpp mode we want. */
if (bpp == 15)
{
if (sdl.surface->format->Gshift == 5 && sdl.surface->format->Gmask == (31U << 5U))
{
LOG_MSG("SDL hack: Asking for 16-bit color (5:6:5) to get SDL to give us 15-bit color (5:5:5) to match your screen.");
bpp = 16;
}
}
#endif
#if C_XBRZ || C_SURFACE_POSTRENDER_ASPECT
// there is a small problem we need to solve here: aspect corrected windows can be smaller than needed due to source with non-4:3 pixel ratio
// if we detect non-4:3 pixel ratio here with aspect correction on, we correct it so original fits into resized window properly
if (render.aspect) aspectCorrectExtend(width, height);
#endif
sdl.clip.w = width; sdl.clip.h = height;
if (sdl.desktop.fullscreen)
{
Uint32 wflags = SDL_FULLSCREEN | SDL_HWPALETTE |
((sdl.draw.flags & GFX_CAN_RANDOM) ? SDL_SWSURFACE : SDL_HWSURFACE) |
(sdl.desktop.doublebuf ? SDL_DOUBLEBUF | SDL_ASYNCBLIT : 0);
if (sdl.desktop.full.fixed)
{
sdl.clip.x = (Sint16)((sdl.desktop.full.width - width) / 2);
sdl.clip.y = (Sint16)((sdl.desktop.full.height - height) / 2);
sdl.surface = SDL_SetVideoMode(sdl.desktop.full.width, sdl.desktop.full.height, bpp, wflags);
sdl.deferred_resize = false;
sdl.must_redraw_all = true;
#if C_XBRZ
/* scale to fit the window.
* fit by aspect ratio if asked to do so. */
if (sdl_xbrz.enable)
{
sdl.clip.x = sdl.clip.y = 0;
sdl.clip.w = sdl.desktop.full.width;
sdl.clip.h = sdl.desktop.full.height;
if (render.aspect) aspectCorrectFitClip(sdl.clip.w, sdl.clip.h, sdl.clip.x, sdl.clip.y, sdl.desktop.full.width, sdl.desktop.full.height);
}
#endif
}
else
{
sdl.clip.x = 0; sdl.clip.y = 0;
sdl.surface = SDL_SetVideoMode(width, height, bpp, wflags);
sdl.deferred_resize = false;
sdl.must_redraw_all = true;
}
if (sdl.surface == NULL) {
LOG_MSG("Fullscreen not supported: %s", SDL_GetError());
sdl.desktop.fullscreen = false;
GFX_CaptureMouse();
goto retry;
}
}
else
{
int menuheight = 0;
sdl.clip.x = 0; sdl.clip.y = 0;
#if DOSBOXMENU_TYPE == DOSBOXMENU_SDLDRAW
/* scale the menu bar if the window is large enough */
{
Bitu consider_height = menu.maxwindow ? currentWindowHeight : height;
Bitu consider_width = menu.maxwindow ? currentWindowWidth : width;
Bitu final_height = max(max(consider_height, userResizeWindowHeight), (Bitu)(sdl.clip.y + sdl.clip.h));
Bitu final_width = max(max(consider_width, userResizeWindowWidth), (Bitu)(sdl.clip.x + sdl.clip.w));
Bitu scale = 1;
while ((final_width / scale) >= (640 * 2) && (final_height / scale) >= (400 * 2))
scale++;
LOG_MSG("menuScale=%lu", (unsigned long)scale);
mainMenu.setScale(scale);
}
if (mainMenu.isVisible()) menuheight = mainMenu.menuBox.h;
#endif
/* menu size and consideration of width and height */
Bitu consider_height = menu.maxwindow ? currentWindowHeight : (height + (unsigned int)menuheight + (sdl.overscan_width * 2));
Bitu consider_width = menu.maxwindow ? currentWindowWidth : (width + (sdl.overscan_width * 2));
#if DOSBOXMENU_TYPE == DOSBOXMENU_SDLDRAW
if (mainMenu.isVisible())
{
/* enforce a minimum 640x400 surface size.
* the menus are useless below 640x400 */
if (consider_width < (640 + (sdl.overscan_width * 2)))
consider_width = (640 + (sdl.overscan_width * 2));
if (consider_height < (400 + (sdl.overscan_width * 2) + (unsigned int)menuheight))
consider_height = (400 + (sdl.overscan_width * 2) + (unsigned int)menuheight);
}
#endif
/* decide where the rectangle on the screen goes */
int final_width,final_height,ax,ay;
#if C_XBRZ
/* scale to fit the window.
* fit by aspect ratio if asked to do so. */
if (sdl_xbrz.enable)
{
final_height = (int)max(consider_height, userResizeWindowHeight) - (int)menuheight - ((int)sdl.overscan_width * 2);
final_width = (int)max(consider_width, userResizeWindowWidth) - ((int)sdl.overscan_width * 2);
sdl.clip.x = sdl.clip.y = 0;
sdl.clip.w = final_width;
sdl.clip.h = final_height;
if (render.aspect) aspectCorrectFitClip(sdl.clip.w, sdl.clip.h, sdl.clip.x, sdl.clip.y, final_width, final_height);
}
else
#endif
/* center the screen in the window */
{
final_height = (int)max(max(consider_height, userResizeWindowHeight), (Bitu)(sdl.clip.y + sdl.clip.h)) - (int)menuheight - ((int)sdl.overscan_width * 2);
final_width = (int)max(max(consider_width, userResizeWindowWidth), (Bitu)(sdl.clip.x + sdl.clip.w)) - ((int)sdl.overscan_width * 2);
ax = (final_width - (sdl.clip.x + sdl.clip.w)) / 2;
ay = (final_height - (sdl.clip.y + sdl.clip.h)) / 2;
if (ax < 0) ax = 0;
if (ay < 0) ay = 0;
sdl.clip.x += ax + (int)sdl.overscan_width;
sdl.clip.y += ay + (int)sdl.overscan_width;
// sdl.clip.w = currentWindowWidth - sdl.clip.x;
// sdl.clip.h = currentWindowHeight - sdl.clip.y;
}
{
final_width += (int)sdl.overscan_width * 2;
final_height += (int)menuheight + (int)sdl.overscan_width * 2;
sdl.clip.y += (int)menuheight;
LOG_MSG("surface consider=%ux%u final=%ux%u",
(unsigned int)consider_width,
(unsigned int)consider_height,
(unsigned int)final_width,
(unsigned int)final_height);
sdl.surface = SDL_SetVideoMode(final_width, final_height, bpp,
(unsigned int)((sdl.draw.flags & GFX_CAN_RANDOM) ? SDL_SWSURFACE : SDL_HWSURFACE) |
(unsigned int)SDL_HAX_NOREFRESH |
(unsigned int)SDL_RESIZABLE);
sdl.deferred_resize = false;
sdl.must_redraw_all = true;
if (SDL_MUSTLOCK(sdl.surface))
SDL_LockSurface(sdl.surface);
memset(sdl.surface->pixels, 0, (unsigned int)sdl.surface->pitch * (unsigned int)sdl.surface->h);
if (SDL_MUSTLOCK(sdl.surface))
SDL_UnlockSurface(sdl.surface);
}
#ifdef WIN32
if (sdl.surface == NULL)
{
SDL_QuitSubSystem(SDL_INIT_VIDEO);
if (!sdl.using_windib)
{
LOG_MSG("Failed to create hardware surface.\nRestarting video subsystem with windib enabled.");
putenv("SDL_VIDEODRIVER=windib");
sdl.using_windib = true;
}
else
{
LOG_MSG("Failed to create hardware surface.\nRestarting video subsystem with directx enabled.");
putenv("SDL_VIDEODRIVER=directx");
sdl.using_windib = false;
}
SDL_InitSubSystem(SDL_INIT_VIDEO);
GFX_SetIcon(); // set icon again
sdl.surface = SDL_SetVideoMode(width, height, bpp, SDL_HWSURFACE);
sdl.deferred_resize = false;
sdl.must_redraw_all = true;
if (sdl.surface) GFX_SetTitle(-1, -1, -1, false); //refresh title
}
#endif
if (sdl.surface == NULL)
E_Exit("Could not set windowed video mode %ix%i-%i: %s", (int)width, (int)height, (int)bpp, SDL_GetError());
}
if (sdl.surface)
{
switch (sdl.surface->format->BitsPerPixel)
{
case 8:
retFlags = GFX_CAN_8;
break;
case 15:
retFlags = GFX_CAN_15;
break;
case 16:
if (sdl.surface->format->Gshift == 5 && sdl.surface->format->Gmask == (31U << 5U))
retFlags = GFX_CAN_15;
else
retFlags = GFX_CAN_16;
break;
case 32:
retFlags = GFX_CAN_32;
break;
}
if (retFlags && (sdl.surface->flags & SDL_HWSURFACE))
retFlags |= GFX_HARDWARE;
if (retFlags && (sdl.surface->flags & SDL_DOUBLEBUF))
{
sdl.blit.surface = SDL_CreateRGBSurface((Uint32)SDL_HWSURFACE,
(int)sdl.draw.width, (int)sdl.draw.height,
(int)sdl.surface->format->BitsPerPixel,
(Uint32)sdl.surface->format->Rmask,
(Uint32)sdl.surface->format->Gmask,
(Uint32)sdl.surface->format->Bmask,
(Uint32)0u);
/* If this one fails be ready for some flickering... */
}
#if C_XBRZ
if (sdl_xbrz.enable)
{
bool old_scale_on = sdl_xbrz.scale_on;
xBRZ_SetScaleParameters(sdl.draw.width, sdl.draw.height, sdl.clip.w, sdl.clip.h);
if (sdl_xbrz.scale_on != old_scale_on) {
// when we are scaling, we ask render code not to do any aspect correction
// when we are not scaling, render code is allowed to do aspect correction at will
// due to this, at each scale mode change we need to schedule resize again because window size could change
PIC_AddEvent(VGA_SetupDrawing, 50); // schedule another resize here, render has already been initialized at this point and we have just changed its option
}
}
#endif
}
#if DOSBOXMENU_TYPE == DOSBOXMENU_SDLDRAW
mainMenu.screenWidth = (size_t)sdl.surface->w;
mainMenu.updateRect();
mainMenu.setRedraw();
GFX_DrawSDLMenu(mainMenu, mainMenu.display_list);
#endif
return retFlags;
}
#endif /*!defined(C_SDL2)*/

View File

@ -0,0 +1,87 @@
#include <sys/types.h>
#include <assert.h>
#include <math.h>
#include "dosbox.h"
#include "sdlmain.h"
#include "vga.h"
#include <algorithm> // std::transform
using namespace std;
#if defined(C_SDL2)
Bitu OUTPUT_SURFACE_SetSize()
{
Bitu bpp = 0;
Bitu retFlags = 0;
(void)bpp;
retry:
sdl.clip.w = sdl.draw.width;
sdl.clip.h = sdl.draw.height;
if (GFX_IsFullscreen()) {
if (sdl.desktop.full.fixed) {
sdl.clip.x = (Sint16)((sdl.desktop.full.width - sdl.draw.width) / 2);
sdl.clip.y = (Sint16)((sdl.desktop.full.height - sdl.draw.height) / 2);
sdl.window = GFX_SetSDLWindowMode(sdl.desktop.full.width, sdl.desktop.full.height, SCREEN_SURFACE);
if (sdl.window == NULL)
E_Exit("Could not set fullscreen video mode %ix%i-%i: %s", sdl.desktop.full.width, sdl.desktop.full.height, sdl.desktop.bpp, SDL_GetError());
}
else {
sdl.clip.x = 0;
sdl.clip.y = 0;
sdl.window = GFX_SetSDLWindowMode(sdl.draw.width, sdl.draw.height, SCREEN_SURFACE);
if (sdl.window == NULL)
LOG_MSG("Fullscreen not supported: %s", SDL_GetError());
SDL_SetWindowFullscreen(sdl.window, 0);
GFX_CaptureMouse();
goto retry;
}
}
else {
int menuheight = 0;
#if DOSBOXMENU_TYPE == DOSBOXMENU_SDLDRAW
if (mainMenu.isVisible()) menuheight = mainMenu.menuBox.h;
#endif
sdl.clip.x = sdl.overscan_width;
sdl.clip.y = sdl.overscan_width + menuheight;
sdl.window = GFX_SetSDLWindowMode(sdl.draw.width + 2 * sdl.overscan_width, sdl.draw.height + menuheight + 2 * sdl.overscan_width, SCREEN_SURFACE);
if (sdl.window == NULL)
E_Exit("Could not set windowed video mode %ix%i: %s", (int)sdl.draw.width, (int)sdl.draw.height, SDL_GetError());
}
sdl.surface = SDL_GetWindowSurface(sdl.window);
if (sdl.surface == NULL)
E_Exit("Could not retrieve window surface: %s", SDL_GetError());
switch (sdl.surface->format->BitsPerPixel) {
case 8:
retFlags = GFX_CAN_8;
break;
case 15:
retFlags = GFX_CAN_15;
break;
case 16:
retFlags = GFX_CAN_16;
break;
case 32:
retFlags = GFX_CAN_32;
break;
}
sdl.deferred_resize = false;
sdl.must_redraw_all = true;
/* Fix a glitch with aspect=true occuring when
changing between modes with different dimensions */
SDL_FillRect(sdl.surface, NULL, SDL_MapRGB(sdl.surface->format, 0, 0, 0));
#if DOSBOXMENU_TYPE == DOSBOXMENU_SDLDRAW
mainMenu.screenWidth = sdl.surface->w;
mainMenu.updateRect();
mainMenu.setRedraw();
GFX_DrawSDLMenu(mainMenu, mainMenu.display_list);
#endif
return retFlags;
}
#endif /*defined(C_SDL2)*/

View File

@ -0,0 +1,2 @@
// common routines reused in different outputs go there

62
src/output/output_tools.h Normal file
View File

@ -0,0 +1,62 @@
#ifndef DOSBOX_OUTPUT_TOOLS_H
#define DOSBOX_OUTPUT_TOOLS_H
#include <sys/types.h>
#include <assert.h>
#include <math.h>
#include "dosbox.h"
#include "sdlmain.h"
// common headers and static routines reused in different outputs go there
static inline int int_log2(int val)
{
int log = 0;
while ((val >>= 1) != 0) log++;
return log;
}
template <class WH>
inline void aspectCorrectExtend(volatile WH &width, volatile WH &height)
{
if (width * sdl.srcAspect.y != height * sdl.srcAspect.x)
{
// abnormal aspect ratio detected, apply correction
if (width * sdl.srcAspect.y > height * sdl.srcAspect.x)
{
// wide pixel ratio, height should be extended to fit
height = (WH)floor((double)width * sdl.srcAspect.yToX + 0.5);
}
else
{
// long pixel ratio, width should be extended
width = (WH)floor((double)height * sdl.srcAspect.xToY + 0.5);
}
}
}
template <class WH, class XY, class TWH>
inline void aspectCorrectFitClip(volatile WH &clipW, volatile WH &clipH, volatile XY &clipX, volatile XY &clipY, const TWH fullW, const TWH fullH)
{
XY ax, ay;
WH sh = fullH;
WH sw = (WH)floor((double)fullH * sdl.srcAspect.xToY);
if (sw > fullW) {
sh = (WH)floor(((double)sh * fullW) / sw);
sw = fullW;
}
ax = (WH)floor((fullW - sw) / 2);
ay = (WH)floor((fullH - sh) / 2);
if (ax < 0) ax = 0;
if (ay < 0) ay = 0;
clipX = ax; clipY = ay; clipW = sw; clipH = sh;
assert((sdl.clip.x + sdl.clip.w) <= sdl.desktop.full.width);
assert((sdl.clip.y + sdl.clip.h) <= sdl.desktop.full.height);
}
#endif

View File

@ -0,0 +1,185 @@
#include <stdlib.h>
#include <assert.h>
#include <math.h>
#include "dosbox.h"
#include "sdlmain.h"
using namespace std;
#if C_XBRZ
struct SDL_xBRZ sdl_xbrz;
void xBRZ_Initialize()
{
memset(&sdl_xbrz, 0, sizeof(sdl_xbrz));
Section_prop* section = static_cast<Section_prop *>(control->GetSection("render"));
LOG(LOG_MISC, LOG_DEBUG)("Early init (renderer): xBRZ options");
// set some defaults
sdl_xbrz.task_granularity = 16;
sdl_xbrz.max_scale_factor = xbrz::SCALE_FACTOR_MAX;
// read options related to xBRZ here
Prop_multival* prop = section->Get_multival("scaler");
std::string scaler = prop->GetSection()->Get_string("type");
sdl_xbrz.enable = ((scaler == "xbrz") || (scaler == "xbrz_bilinear"));
sdl_xbrz.postscale_bilinear = (scaler == "xbrz_bilinear");
xBRZ_Change_Options(section);
}
void xBRZ_Change_Options(Section_prop* section)
{
sdl_xbrz.task_granularity = section->Get_int("xbrz slice");
sdl_xbrz.fixed_scale_factor = section->Get_int("xbrz fixed scale factor");
sdl_xbrz.max_scale_factor = section->Get_int("xbrz max scale factor");
if ((sdl_xbrz.max_scale_factor < 2) || (sdl_xbrz.max_scale_factor > xbrz::SCALE_FACTOR_MAX))
sdl_xbrz.max_scale_factor = xbrz::SCALE_FACTOR_MAX;
if ((sdl_xbrz.fixed_scale_factor < 2) || (sdl_xbrz.fixed_scale_factor > xbrz::SCALE_FACTOR_MAX))
sdl_xbrz.fixed_scale_factor = 0;
}
// returns true if scaling possible/enabled, false otherwise
bool xBRZ_SetScaleParameters(int srcWidth, int srcHeight, int dstWidth, int dstHeight)
{
sdl_xbrz.scale_factor = (sdl_xbrz.fixed_scale_factor == 0) ?
static_cast<int>(std::sqrt((double)dstWidth * dstHeight / (srcWidth * srcHeight)) + 0.5) :
sdl_xbrz.fixed_scale_factor;
// enable minimal scaling if upscale is still possible but requires post-downscale
// having aspect ratio correction on always implies enabled scaler because it gives better quality than DOSBox own method
if (sdl_xbrz.scale_factor == 1 && (render.aspect || dstWidth > srcWidth || dstHeight > srcHeight))
sdl_xbrz.scale_factor = 2;
if (sdl_xbrz.scale_factor >= 2)
{
// ok to scale, now clamp scale factor if corresponding max option is set
sdl_xbrz.scale_factor = min(sdl_xbrz.scale_factor, sdl_xbrz.max_scale_factor);
sdl_xbrz.scale_on = true;
}
else
{
// scaling impossible
sdl_xbrz.scale_on = false;
}
return sdl_xbrz.scale_on;
}
void xBRZ_Render(const uint32_t* renderBuf, uint32_t* xbrzBuf, const Bit16u *changedLines, const int srcWidth, const int srcHeight, int scalingFactor)
{
#ifdef XBRZ_PPL
if (changedLines) // perf: in worst case similar to full input scaling
{
concurrency::task_group tg; // perf: task_group is slightly faster than pure parallel_for
int yLast = 0;
Bitu y = 0, index = 0;
while (y < sdl.draw.height)
{
if (!(index & 1))
y += changedLines[index];
else
{
const int sliceFirst = y;
const int sliceLast = y + changedLines[index];
y += changedLines[index];
int yFirst = max(yLast, sliceFirst - 2); // we need to update two adjacent lines as well since they are analyzed by xBRZ!
yLast = min(srcHeight, sliceLast + 2); // (and make sure to not overlap with last slice!)
for (int i = yFirst; i < yLast; i += sdl_xbrz.task_granularity)
{
tg.run([=] {
const int iLast = min(i + sdl_xbrz.task_granularity, yLast);
xbrz::scale(scalingFactor, renderBuf, xbrzBuf, srcWidth, srcHeight, xbrz::ColorFormat::RGB, xbrz::ScalerCfg(), i, iLast);
});
}
}
index++;
}
tg.wait();
}
else // process complete input image
{
concurrency::task_group tg;
for (int i = 0; i < srcHeight; i += sdl_xbrz.task_granularity)
{
tg.run([=] {
const int iLast = min(i + sdl_xbrz.task_granularity, srcHeight);
xbrz::scale(scalingFactor, renderBuf, xbrzBuf, srcWidth, srcHeight, xbrz::ColorFormat::RGB, xbrz::ScalerCfg(), i, iLast);
});
}
tg.wait();
}
#else
/* non-PPL for non-Windows.
* combine the code above, cleanly, if possible. */
if (changedLines)
{
int yLast = 0;
Bitu y = 0, index = 0;
while (y < sdl.draw.height)
{
if (!(index & 1))
y += changedLines[index];
else
{
const int sliceFirst = y;
const int sliceLast = y + changedLines[index];
y += changedLines[index];
int yFirst = max(yLast, sliceFirst - 2); // we need to update two adjacent lines as well since they are analyzed by xBRZ!
yLast = min(srcHeight, sliceLast + 2); // (and make sure to not overlap with last slice!)
xbrz::scale(scalingFactor, renderBuf, xbrzBuf, srcWidth, srcHeight, xbrz::ColorFormat::RGB, xbrz::ScalerCfg(), yFirst, yLast);
}
index++;
}
}
else // process complete input image
{
xbrz::scale(scalingFactor, renderBuf, xbrzBuf, srcWidth, srcHeight, xbrz::ColorFormat::RGB, xbrz::ScalerCfg(), 0, srcHeight);
}
#endif /*XBRZ_PPL*/
}
#endif /*C_XBRZ*/
#if C_XBRZ || C_SURFACE_POSTRENDER_ASPECT
void xBRZ_PostScale(const uint32_t* src, const int srcWidth, const int srcHeight, const int srcPitch,
uint32_t* tgt, const int tgtWidth, const int tgtHeight, const int tgtPitch,
const bool bilinear, const int task_granularity)
{
# if defined(XBRZ_PPL)
if (bilinear) {
concurrency::task_group tg;
for (int i = 0; i < tgtHeight; i += task_granularity)
tg.run([=] {
const int iLast = min(i + task_granularity, tgtHeight);
xbrz::bilinearScale(&src[0], srcWidth, srcHeight, srcPitch, &tgt[0], tgtWidth, tgtHeight, tgtPitch, i, iLast, [](uint32_t pix) { return pix; });
});
tg.wait();
}
else
{
concurrency::task_group tg;
for (int i = 0; i < tgtHeight; i += task_granularity)
tg.run([=] {
const int iLast = min(i + task_granularity, tgtHeight);
// perf: going over target is by factor 4 faster than going over source for similar image sizes
xbrz::nearestNeighborScale(&src[0], srcWidth, srcHeight, srcPitch, &tgt[0], tgtWidth, tgtHeight, tgtPitch, i, iLast, [](uint32_t pix) { return pix; });
});
tg.wait();
}
#else
if (bilinear)
xbrz::bilinearScale(&src[0], srcWidth, srcHeight, srcPitch, &tgt[0], tgtWidth, tgtHeight, tgtPitch, 0, tgtHeight, [](uint32_t pix) { return pix; });
else
xbrz::nearestNeighborScale(&src[0], srcWidth, srcHeight, srcPitch, &tgt[0], tgtWidth, tgtHeight, tgtPitch, 0, tgtHeight, [](uint32_t pix) { return pix; });
#endif
}
#endif /*C_XBRZ || C_SURFACE_POSTRENDER_ASPECT*/

View File

@ -0,0 +1,47 @@
#include "dosbox.h"
#ifndef DOSBOX_OUTPUT_TOOLS_XBRZ_H
#define DOSBOX_OUTPUT_TOOLS_XBRZ_H
#if C_XBRZ || C_SURFACE_POSTRENDER_ASPECT
#include <xBRZ/xbrz_tools.h>
#include <cmath>
#if defined(WIN32) && !defined(__MINGW32__) && !defined(HX_DOS)
#define XBRZ_PPL 1
#include <ppl.h>
#endif
#endif /*C_XBRZ || C_SURFACE_POSTRENDER_ASPECT*/
#if C_XBRZ
#include <xBRZ/xbrz.h>
struct SDL_xBRZ {
// configuration
bool enable;
bool postscale_bilinear;
int task_granularity;
int fixed_scale_factor;
int max_scale_factor;
// runtime
bool scale_on;
int scale_factor;
std::vector<uint32_t> renderbuf;
std::vector<uint32_t> pixbuf;
};
extern SDL_xBRZ sdl_xbrz;
void xBRZ_Initialize();
void xBRZ_Change_Options(Section_prop* section);
bool xBRZ_SetScaleParameters(int srcWidth, int srcHeight, int dstWidth, int dstHeight);
void xBRZ_Render(const uint32_t* renderBuf, uint32_t* xbrzBuf, const Bit16u *changedLines, const int srcWidth, const int srcHeight, int scalingFactor);
void xBRZ_PostScale(const uint32_t* src, const int srcWidth, const int srcHeight, const int srcPitch,
uint32_t* tgt, const int tgtWidth, const int tgtHeight, const int tgtPitch,
const bool bilinear, const int task_granularity);
#endif
#endif /*DOSBOX_OUTPUT_TOOLS_XBRZ_H*/

View File

@ -32,6 +32,8 @@
extern bool dos_shell_running_program;
Bitu shell_psp = 0;
void CALLBACK_DeAllocate(Bitu in);
Bitu call_shellstop = 0;
@ -563,6 +565,41 @@ void AUTOEXEC_Init() {
AddVMEventFunction(VM_EVENT_DOS_SURPRISE_REBOOT,AddVMEventFunctionFuncPair(AUTOEXEC_ShutDown));
}
static Bitu INT2E_Handler(void) {
/* Save return address and current process */
RealPt save_ret=real_readd(SegValue(ss),reg_sp);
Bit16u save_psp=dos.psp();
/* Set first shell as process and copy command */
dos.psp(shell_psp);//DOS_FIRST_SHELL);
DOS_PSP psp(shell_psp);//DOS_FIRST_SHELL);
psp.SetCommandTail(RealMakeSeg(ds,reg_si));
SegSet16(ss,RealSeg(psp.GetStack()));
reg_sp=2046;
/* Read and fix up command string */
CommandTail tail;
MEM_BlockRead(PhysMake(dos.psp(),128),&tail,128);
if (tail.count<127) tail.buffer[tail.count]=0;
else tail.buffer[126]=0;
char* crlf=strpbrk(tail.buffer,"\r\n");
if (crlf) *crlf=0;
/* Execute command */
if (strlen(tail.buffer)) {
DOS_Shell temp;
temp.ParseLine(tail.buffer);
temp.RunInternal();
}
/* Restore process and "return" to caller */
dos.psp(save_psp);
SegSet16(cs,RealSeg(save_ret));
reg_ip=RealOff(save_ret);
reg_ax=0;
return CBRET_NONE;
}
static char const * const path_string="PATH=Z:\\";
static char const * const comspec_string="COMSPEC=Z:\\COMMAND.COM";
static char const * const prompt_string="PROMPT=$P$G";
@ -915,6 +952,7 @@ void SHELL_Init() {
// now COMMAND.COM has a main body and PSP segment, reflect it
dos.psp(psp_seg);
shell_psp = psp_seg;
{
DOS_MCB mcb((Bit16u)(env_seg-1));
@ -943,7 +981,13 @@ void SHELL_Init() {
/* Set up int 23 to "int 20" in the psp. Fixes what.exe */
real_writed(0,0x23*4,((Bit32u)psp_seg<<16));
/* Set up int 2e handler */
Bitu call_int2e=CALLBACK_Allocate();
RealPt addr_int2e=RealMake(psp_seg+16+1,8);
CALLBACK_Setup(call_int2e,&INT2E_Handler,CB_IRET_STI,Real2Phys(addr_int2e),"Shell Int 2e");
RealSetVec(0x2e,addr_int2e);
/* Setup environment */
PhysPt env_write=PhysMake(env_seg,0);
MEM_BlockWrite(env_write,path_string,(Bitu)(strlen(path_string)+1));

6
src/xBRZ/Makefile.am Normal file
View File

@ -0,0 +1,6 @@
SUBDIRS =
AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/src -DNDEBUG=1
noinst_LIBRARIES = libxbrz.a
libxbrz_a_SOURCES = xbrz.cpp

View File

@ -21,14 +21,14 @@
namespace xbrz
{
struct ScalerCfg
{
double luminanceWeight = 1;
double equalColorTolerance = 30;
double dominantDirectionThreshold = 3.6;
double steepDirectionThreshold = 2.2;
double newTestAttribute = 0; //unused; test new parameters
};
struct ScalerCfg
{
double luminanceWeight = 1;
double equalColorTolerance = 30;
double dominantDirectionThreshold = 3.6;
double steepDirectionThreshold = 2.2;
double newTestAttribute = 0; //unused; test new parameters
};
}
#endif

View File

@ -231,7 +231,10 @@ void bilinearScale(const uint32_t* src, int srcWidth, int srcHeight, int srcPitc
const double xx1 = x / scaleX - x1;
const double x2x = 1 - xx1;
buf[x] = { x1, x2, xx1, x2x };
buf[x].x1 = x1;
buf[x].x2 = x2;
buf[x].xx1 = xx1;
buf[x].x2x = x2x;
}
for (int y = yFirst; y < yLast; ++y)

BIN
vs2015/TESTING.ZIP Normal file

Binary file not shown.

View File

@ -45,8 +45,17 @@
/* Define to 1 to use inlined memory functions in cpu core */
#define C_CORE_INLINE 1
/* Define to 1 if you have the <d3d9.h> header file. */
#if !defined(C_SDL2)
#define HAVE_D3D9_H 1
#endif
#if HAVE_D3D9_H
/* Define to 1 if you want to add Direct3D output to the list of available outputs */
#define C_DIRECT3D 1
/* Define to 1 to use Direct3D shaders, requires d3d9.h and libd3dx9 */
#define C_D3DSHADERS 1
#endif
/* Define to 1 to enable internal debugger, requires libcurses */
#define C_DEBUG 1
@ -100,6 +109,9 @@
#define C_MODEM 1
#endif
/* Define to 1 to enable internal printer redirection support*/
#define C_PRINTER 1
/* Define to 1 to enable NE2000 ethernet passthrough, requires libpcap */
#define C_NE2000 1
@ -114,9 +126,16 @@
/* Set to 1 to enable SDL 2.x support */
/* #undef C_SDL2 */
#if !defined(C_SDL2)
/* Set to 1 to enable XBRZ support */
#define C_XBRZ 1
/* Set to 1 to enable scaler friendly but CPU intensive aspect ratio correction options (post-scalers) for 'surface' output */
/* Please note that this option includes small part of xBRZ code and uses task group parallelism like xBRZ (batch size is hardcoded here) */
#define C_SURFACE_POSTRENDER_ASPECT 1
#define C_SURFACE_POSTRENDER_ASPECT_BATCH_SIZE 16
#endif /*!defined(C_SDL2)*/
/* Define to 1 if you have setpriority support */
#undef C_SET_PRIORITY
@ -144,11 +163,6 @@
/* Define to 1 to use ALSA for MIDI */
#undef HAVE_ALSA
/* Define to 1 if you have the <d3d9.h> header file. */
#if !defined(C_SDL2)
#define HAVE_D3D9_H 1
#endif
/* Define to 1 if you have the <ddraw.h> header file. */
#if !defined(C_SDL2)
#define HAVE_DDRAW_H 1

View File

@ -1,8 +1,8 @@
#define PACKAGE "dosbox-x"
#define PACKAGE_BUGREPORT "https://github.com/joncampbell123/dosbox-x/issues"
#define PACKAGE_NAME "dosbox-x"
#define PACKAGE_STRING "dosbox-x 0.82.7"
#define PACKAGE_STRING "dosbox-x 0.82.8"
#define PACKAGE_TARNAME "dosbox-x"
#define PACKAGE_URL "http://dosbox-x.software"
#define PACKAGE_VERSION "0.82.7"
#define VERSION "0.82.7"
#define PACKAGE_VERSION "0.82.8"
#define VERSION "0.82.8"

View File

@ -10,6 +10,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dosbox-x", "dosbox-x.vcxpro
{D6973076-9317-4EF2-A0B8-B7A18AC0713E} = {D6973076-9317-4EF2-A0B8-B7A18AC0713E}
{76B22E87-5DD6-4829-BBF0-1DC8025BB87C} = {76B22E87-5DD6-4829-BBF0-1DC8025BB87C}
{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} = {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B} = {78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}
{DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} = {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}
{498C5AE3-3158-40B8-9DCE-A79B7C718803} = {498C5AE3-3158-40B8-9DCE-A79B7C718803}
{671232EC-C55C-4636-A75F-7E4B4C54C314} = {671232EC-C55C-4636-A75F-7E4B4C54C314}
@ -40,6 +41,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libpng", "libpng\projects\v
{ACEE8153-C2AF-4E9E-8881-8FEA759A34D9} = {ACEE8153-C2AF-4E9E-8881-8FEA759A34D9}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "freetype", "freetype\builds\windows\vc2010\freetype.vcxproj", "{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}"
ProjectSection(ProjectDependencies) = postProject
{D6973076-9317-4EF2-A0B8-B7A18AC0713E} = {D6973076-9317-4EF2-A0B8-B7A18AC0713E}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug SDL2|Win32 = Debug SDL2|Win32
@ -176,6 +182,22 @@ Global
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Release|Win32.Build.0 = Release|Win32
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Release|x64.ActiveCfg = Release|x64
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Release|x64.Build.0 = Release|x64
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug SDL2|Win32.ActiveCfg = Debug Static|Win32
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug SDL2|Win32.Build.0 = Debug Static|Win32
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug SDL2|x64.ActiveCfg = Debug Static|x64
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug SDL2|x64.Build.0 = Debug Static|x64
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug|Win32.ActiveCfg = Debug Static|Win32
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug|Win32.Build.0 = Debug Static|Win32
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug|x64.ActiveCfg = Debug Static|x64
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug|x64.Build.0 = Debug Static|x64
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release SDL2|Win32.ActiveCfg = Release Static|Win32
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release SDL2|Win32.Build.0 = Release Static|Win32
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release SDL2|x64.ActiveCfg = Release Static|x64
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release SDL2|x64.Build.0 = Release Static|x64
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release|Win32.ActiveCfg = Release Static|Win32
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release|Win32.Build.0 = Release Static|Win32
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release|x64.ActiveCfg = Release Static|x64
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release|x64.Build.0 = Release Static|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -189,6 +211,7 @@ Global
{671232EC-C55C-4636-A75F-7E4B4C54C314} = {C204B73D-93EA-4E4C-BD5A-FDB7D5D07362}
{ACEE8153-C2AF-4E9E-8881-8FEA759A34D9} = {C204B73D-93EA-4E4C-BD5A-FDB7D5D07362}
{D6973076-9317-4EF2-A0B8-B7A18AC0713E} = {C204B73D-93EA-4E4C-BD5A-FDB7D5D07362}
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B} = {C204B73D-93EA-4E4C-BD5A-FDB7D5D07362}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {EEAF41F1-C358-4B63-A476-64F9473F4D5A}

View File

@ -176,7 +176,7 @@
<ClCompile>
<Optimization>Disabled</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(SolutionDir)/pcap;$(SolutionDir)/..;$(SolutionDir)/../include;$(SolutionDir)/../src/aviwriter;$(SolutionDir)/../src/mt32;$(SolutionDir)/../src/hardware/snd_pc98/cbus;$(SolutionDir)/../src/hardware/snd_pc98/common;$(SolutionDir)/../src/hardware/snd_pc98/generic;$(SolutionDir)/../src/hardware/snd_pc98/sound;$(SolutionDir)/../src/hardware/snd_pc98/x11;$(SolutionDir)/../src/hardware/snd_pc98/sound/getsnd;$(SolutionDir)/libpdcurses;$(SolutionDir)/../src;$(SolutionDir);$(SolutionDir)/zlib;$(SolutionDir)/sdl/include;$(SolutionDir)/libpng;$(SolutionDir)/sdlnet;$(SolutionDir)/libpdcurses;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)/pcap;$(SolutionDir)/..;$(SolutionDir)/../include;$(SolutionDir)/../src/aviwriter;$(SolutionDir)/../src/mt32;$(SolutionDir)/../src/hardware/snd_pc98/cbus;$(SolutionDir)/../src/hardware/snd_pc98/common;$(SolutionDir)/../src/hardware/snd_pc98/generic;$(SolutionDir)/../src/hardware/snd_pc98/sound;$(SolutionDir)/../src/hardware/snd_pc98/x11;$(SolutionDir)/../src/hardware/snd_pc98/sound/getsnd;$(SolutionDir)/libpdcurses;$(SolutionDir)/../src;$(SolutionDir);$(SolutionDir)/zlib;$(SolutionDir)/sdl/include;$(SolutionDir)/libpng;$(SolutionDir)/sdlnet;$(SolutionDir)/libpdcurses;$(SolutionDir)/freetype/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;__WIN32__;%(PreprocessorDefinitions);_FILE_OFFSET_BITS=64</PreprocessorDefinitions>
<PreprocessToFile>false</PreprocessToFile>
<PreprocessSuppressLineNumbers>false</PreprocessSuppressLineNumbers>
@ -198,7 +198,7 @@
</SDLCheck>
</ClCompile>
<Link>
<AdditionalDependencies>winmm.lib;imm32.lib;opengl32.lib;dxguid.lib;version.lib;Iphlpapi.lib;$(SolutionDir)..\obj\libpdcurses\$(Platform)\$(Configuration)\libpdcurses.lib;Ws2_32.lib;$(SolutionDir)..\obj\SDL\$(Platform)\$(Configuration)\SDL.lib;$(SolutionDir)..\obj\SDLmain\$(Platform)\$(Configuration)\SDLmain.lib;$(SolutionDir)..\obj\SDL_net\$(Platform)\$(Configuration)\SDL_net.lib;$(SolutionDir)..\obj\libpdcurses\$(Platform)\$(Configuration)\libpdcurses.lib;%(AdditionalDependencies);$(SolutionDir)..\obj\zlib\$(Platform)\$(Configuration)\zlib.lib;$(SolutionDir)..\obj\libpng\$(Platform)\$(Configuration)\libpng.lib</AdditionalDependencies>
<AdditionalDependencies>winmm.lib;imm32.lib;opengl32.lib;dxguid.lib;version.lib;Iphlpapi.lib;$(SolutionDir)..\obj\libpdcurses\$(Platform)\$(Configuration)\libpdcurses.lib;Ws2_32.lib;$(SolutionDir)..\obj\SDL\$(Platform)\$(Configuration)\SDL.lib;$(SolutionDir)..\obj\SDLmain\$(Platform)\$(Configuration)\SDLmain.lib;$(SolutionDir)..\obj\SDL_net\$(Platform)\$(Configuration)\SDL_net.lib;$(SolutionDir)..\obj\libpdcurses\$(Platform)\$(Configuration)\libpdcurses.lib;%(AdditionalDependencies);$(SolutionDir)..\obj\zlib\$(Platform)\$(Configuration)\zlib.lib;$(SolutionDir)..\obj\libpng\$(Platform)\$(Configuration)\libpng.lib;$(SolutionDir)..\obj\freetype\$(Platform)\Debug Static\freetype.lib</AdditionalDependencies>
<ShowProgress>LinkVerboseLib</ShowProgress>
<OutputFile>$(OutDir)/$(ProjectName).exe</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
@ -233,7 +233,7 @@ copy "$(SolutionDir)\..\CHANGELOG" "$(OutputPath)\changelog.txt"</Command>
<ClCompile>
<Optimization>Disabled</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(SolutionDir)/pcap;$(SolutionDir)/..;$(SolutionDir)/../include;$(SolutionDir)/../src/aviwriter;$(SolutionDir)/../src/mt32;$(SolutionDir)/../src/hardware/snd_pc98/cbus;$(SolutionDir)/../src/hardware/snd_pc98/common;$(SolutionDir)/../src/hardware/snd_pc98/generic;$(SolutionDir)/../src/hardware/snd_pc98/sound;$(SolutionDir)/../src/hardware/snd_pc98/x11;$(SolutionDir)/../src/hardware/snd_pc98/sound/getsnd;$(SolutionDir)/libpdcurses;$(SolutionDir)/sdl2/include;$(SolutionDir)/../src;$(SolutionDir);$(SolutionDir)/zlib;$(SolutionDir)/libpng;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)/pcap;$(SolutionDir)/..;$(SolutionDir)/../include;$(SolutionDir)/../src/aviwriter;$(SolutionDir)/../src/mt32;$(SolutionDir)/../src/hardware/snd_pc98/cbus;$(SolutionDir)/../src/hardware/snd_pc98/common;$(SolutionDir)/../src/hardware/snd_pc98/generic;$(SolutionDir)/../src/hardware/snd_pc98/sound;$(SolutionDir)/../src/hardware/snd_pc98/x11;$(SolutionDir)/../src/hardware/snd_pc98/sound/getsnd;$(SolutionDir)/libpdcurses;$(SolutionDir)/sdl2/include;$(SolutionDir)/../src;$(SolutionDir);$(SolutionDir)/zlib;$(SolutionDir)/libpng;$(SolutionDir)/freetype/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;__WIN32__;%(PreprocessorDefinitions);_FILE_OFFSET_BITS=64;C_SDL2=1</PreprocessorDefinitions>
<PreprocessToFile>false</PreprocessToFile>
<PreprocessSuppressLineNumbers>false</PreprocessSuppressLineNumbers>
@ -256,7 +256,7 @@ copy "$(SolutionDir)\..\CHANGELOG" "$(OutputPath)\changelog.txt"</Command>
</SDLCheck>
</ClCompile>
<Link>
<AdditionalDependencies>winmm.lib;imm32.lib;opengl32.lib;dxguid.lib;version.lib;Iphlpapi.lib;$(SolutionDir)..\obj\libpdcurses\$(Platform)\$(Configuration)\libpdcurses.lib;$(SolutionDir)..\obj\SDL2\$(Platform)\$(Configuration)\sdl2.lib;$(SolutionDir)..\obj\SDL2main\$(Platform)\$(Configuration)\sdl2main.lib;Ws2_32.lib;$(SolutionDir)..\obj\libpdcurses\$(Platform)\$(Configuration)\libpdcurses.lib;%(AdditionalDependencies);$(SolutionDir)..\obj\zlib\$(Platform)\$(Configuration)\zlib.lib;$(SolutionDir)..\obj\libpng\$(Platform)\$(Configuration)\libpng.lib</AdditionalDependencies>
<AdditionalDependencies>winmm.lib;imm32.lib;opengl32.lib;dxguid.lib;version.lib;Iphlpapi.lib;$(SolutionDir)..\obj\libpdcurses\$(Platform)\$(Configuration)\libpdcurses.lib;$(SolutionDir)..\obj\SDL2\$(Platform)\$(Configuration)\sdl2.lib;$(SolutionDir)..\obj\SDL2main\$(Platform)\$(Configuration)\sdl2main.lib;Ws2_32.lib;$(SolutionDir)..\obj\libpdcurses\$(Platform)\$(Configuration)\libpdcurses.lib;%(AdditionalDependencies);$(SolutionDir)..\obj\zlib\$(Platform)\$(Configuration)\zlib.lib;$(SolutionDir)..\obj\libpng\$(Platform)\$(Configuration)\libpng.lib;$(SolutionDir)..\obj\freetype\$(Platform)\Debug Static\freetype.lib</AdditionalDependencies>
<ShowProgress>LinkVerboseLib</ShowProgress>
<OutputFile>$(OutDir)/$(ProjectName).exe</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
@ -294,7 +294,7 @@ copy "$(SolutionDir)\..\CHANGELOG" "$(OutputPath)\changelog.txt"</Command>
<ClCompile>
<Optimization>Disabled</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(SolutionDir)/pcap;$(SolutionDir)/..;$(SolutionDir)/../include;$(SolutionDir)/../src/aviwriter;$(SolutionDir)/../src/mt32;$(SolutionDir)/../src/hardware/snd_pc98/cbus;$(SolutionDir)/../src/hardware/snd_pc98/common;$(SolutionDir)/../src/hardware/snd_pc98/generic;$(SolutionDir)/../src/hardware/snd_pc98/sound;$(SolutionDir)/../src/hardware/snd_pc98/x11;$(SolutionDir)/../src/hardware/snd_pc98/sound/getsnd;$(SolutionDir)/libpdcurses;$(SolutionDir)/../src;$(SolutionDir);$(SolutionDir)/zlib;$(SolutionDir)/sdl/include;$(SolutionDir)/libpng;$(SolutionDir)/sdlnet;$(SolutionDir)/libpdcurses;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)/pcap;$(SolutionDir)/..;$(SolutionDir)/../include;$(SolutionDir)/../src/aviwriter;$(SolutionDir)/../src/mt32;$(SolutionDir)/../src/hardware/snd_pc98/cbus;$(SolutionDir)/../src/hardware/snd_pc98/common;$(SolutionDir)/../src/hardware/snd_pc98/generic;$(SolutionDir)/../src/hardware/snd_pc98/sound;$(SolutionDir)/../src/hardware/snd_pc98/x11;$(SolutionDir)/../src/hardware/snd_pc98/sound/getsnd;$(SolutionDir)/libpdcurses;$(SolutionDir)/../src;$(SolutionDir);$(SolutionDir)/zlib;$(SolutionDir)/sdl/include;$(SolutionDir)/libpng;$(SolutionDir)/sdlnet;$(SolutionDir)/libpdcurses;$(SolutionDir)/freetype/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;__WIN32__;%(PreprocessorDefinitions);_FILE_OFFSET_BITS=64</PreprocessorDefinitions>
<PreprocessToFile>false</PreprocessToFile>
<PreprocessSuppressLineNumbers>false</PreprocessSuppressLineNumbers>
@ -318,7 +318,7 @@ copy "$(SolutionDir)\..\CHANGELOG" "$(OutputPath)\changelog.txt"</Command>
</SDLCheck>
</ClCompile>
<Link>
<AdditionalDependencies>winmm.lib;imm32.lib;opengl32.lib;dxguid.lib;version.lib;Iphlpapi.lib;$(SolutionDir)..\obj\libpdcurses\$(Platform)\$(Configuration)\libpdcurses.lib;Ws2_32.lib;$(SolutionDir)..\obj\SDL\$(Platform)\$(Configuration)\SDL.lib;$(SolutionDir)..\obj\SDLmain\$(Platform)\$(Configuration)\SDLmain.lib;$(SolutionDir)..\obj\SDL_net\$(Platform)\$(Configuration)\SDL_net.lib;$(SolutionDir)..\obj\libpdcurses\$(Platform)\$(Configuration)\libpdcurses.lib;%(AdditionalDependencies);$(SolutionDir)..\obj\zlib\$(Platform)\$(Configuration)\zlib.lib;$(SolutionDir)..\obj\libpng\$(Platform)\$(Configuration)\libpng.lib</AdditionalDependencies>
<AdditionalDependencies>winmm.lib;imm32.lib;opengl32.lib;dxguid.lib;version.lib;Iphlpapi.lib;$(SolutionDir)..\obj\libpdcurses\$(Platform)\$(Configuration)\libpdcurses.lib;Ws2_32.lib;$(SolutionDir)..\obj\SDL\$(Platform)\$(Configuration)\SDL.lib;$(SolutionDir)..\obj\SDLmain\$(Platform)\$(Configuration)\SDLmain.lib;$(SolutionDir)..\obj\SDL_net\$(Platform)\$(Configuration)\SDL_net.lib;$(SolutionDir)..\obj\libpdcurses\$(Platform)\$(Configuration)\libpdcurses.lib;%(AdditionalDependencies);$(SolutionDir)..\obj\zlib\$(Platform)\$(Configuration)\zlib.lib;$(SolutionDir)..\obj\libpng\$(Platform)\$(Configuration)\libpng.lib;$(SolutionDir)..\obj\freetype\$(Platform)\Debug Static\freetype.lib</AdditionalDependencies>
<ShowProgress>LinkVerboseLib</ShowProgress>
<OutputFile>$(OutDir)/$(ProjectName).exe</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
@ -354,7 +354,7 @@ copy "$(SolutionDir)\..\CHANGELOG" "$(OutputPath)\changelog.txt"</Command>
<ClCompile>
<Optimization>Disabled</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(SolutionDir)/pcap;$(SolutionDir)/..;$(SolutionDir)/../include;$(SolutionDir)/../src/aviwriter;$(SolutionDir)/../src/mt32;$(SolutionDir)/../src/hardware/snd_pc98/cbus;$(SolutionDir)/../src/hardware/snd_pc98/common;$(SolutionDir)/../src/hardware/snd_pc98/generic;$(SolutionDir)/../src/hardware/snd_pc98/sound;$(SolutionDir)/../src/hardware/snd_pc98/x11;$(SolutionDir)/../src/hardware/snd_pc98/sound/getsnd;$(SolutionDir)/libpdcurses;$(SolutionDir)/sdl2/include;$(SolutionDir)/../src;$(SolutionDir);$(SolutionDir)/zlib;$(SolutionDir)/libpng;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)/pcap;$(SolutionDir)/..;$(SolutionDir)/../include;$(SolutionDir)/../src/aviwriter;$(SolutionDir)/../src/mt32;$(SolutionDir)/../src/hardware/snd_pc98/cbus;$(SolutionDir)/../src/hardware/snd_pc98/common;$(SolutionDir)/../src/hardware/snd_pc98/generic;$(SolutionDir)/../src/hardware/snd_pc98/sound;$(SolutionDir)/../src/hardware/snd_pc98/x11;$(SolutionDir)/../src/hardware/snd_pc98/sound/getsnd;$(SolutionDir)/libpdcurses;$(SolutionDir)/sdl2/include;$(SolutionDir)/../src;$(SolutionDir);$(SolutionDir)/zlib;$(SolutionDir)/libpng;$(SolutionDir)/freetype/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;__WIN32__;%(PreprocessorDefinitions);_FILE_OFFSET_BITS=64;C_SDL2=1</PreprocessorDefinitions>
<PreprocessToFile>false</PreprocessToFile>
<PreprocessSuppressLineNumbers>false</PreprocessSuppressLineNumbers>
@ -379,7 +379,7 @@ copy "$(SolutionDir)\..\CHANGELOG" "$(OutputPath)\changelog.txt"</Command>
</SDLCheck>
</ClCompile>
<Link>
<AdditionalDependencies>winmm.lib;imm32.lib;opengl32.lib;dxguid.lib;version.lib;Iphlpapi.lib;$(SolutionDir)..\obj\libpdcurses\$(Platform)\$(Configuration)\libpdcurses.lib;$(SolutionDir)..\obj\SDL2\$(Platform)\$(Configuration)\sdl2.lib;$(SolutionDir)..\obj\SDL2main\$(Platform)\$(Configuration)\sdl2main.lib;Ws2_32.lib;$(SolutionDir)..\obj\libpdcurses\$(Platform)\$(Configuration)\libpdcurses.lib;%(AdditionalDependencies);$(SolutionDir)..\obj\zlib\$(Platform)\$(Configuration)\zlib.lib;$(SolutionDir)..\obj\libpng\$(Platform)\$(Configuration)\libpng.lib</AdditionalDependencies>
<AdditionalDependencies>winmm.lib;imm32.lib;opengl32.lib;dxguid.lib;version.lib;Iphlpapi.lib;$(SolutionDir)..\obj\libpdcurses\$(Platform)\$(Configuration)\libpdcurses.lib;$(SolutionDir)..\obj\SDL2\$(Platform)\$(Configuration)\sdl2.lib;$(SolutionDir)..\obj\SDL2main\$(Platform)\$(Configuration)\sdl2main.lib;Ws2_32.lib;$(SolutionDir)..\obj\libpdcurses\$(Platform)\$(Configuration)\libpdcurses.lib;%(AdditionalDependencies);$(SolutionDir)..\obj\zlib\$(Platform)\$(Configuration)\zlib.lib;$(SolutionDir)..\obj\libpng\$(Platform)\$(Configuration)\libpng.lib;$(SolutionDir)..\obj\freetype\$(Platform)\Debug Static\freetype.lib</AdditionalDependencies>
<ShowProgress>LinkVerboseLib</ShowProgress>
<OutputFile>$(OutDir)/$(ProjectName).exe</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
@ -412,7 +412,7 @@ copy "$(SolutionDir)\..\CHANGELOG" "$(OutputPath)\changelog.txt"</Command>
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(SolutionDir)/pcap;$(SolutionDir)/..;$(SolutionDir)/../include;$(SolutionDir)/../src/aviwriter;$(SolutionDir)/../src/mt32;$(SolutionDir)/../src/hardware/snd_pc98/cbus;$(SolutionDir)/../src/hardware/snd_pc98/common;$(SolutionDir)/../src/hardware/snd_pc98/generic;$(SolutionDir)/../src/hardware/snd_pc98/sound;$(SolutionDir)/../src/hardware/snd_pc98/x11;$(SolutionDir)/../src/hardware/snd_pc98/sound/getsnd;$(SolutionDir)/libpdcurses;$(SolutionDir)/../src;$(SolutionDir);$(SolutionDir)/zlib;$(SolutionDir)/sdl/include;$(SolutionDir)/libpng;$(SolutionDir)/sdlnet;$(SolutionDir)/libpdcurses;$(SolutionDir)/libpdcurses;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)/pcap;$(SolutionDir)/..;$(SolutionDir)/../include;$(SolutionDir)/../src/aviwriter;$(SolutionDir)/../src/mt32;$(SolutionDir)/../src/hardware/snd_pc98/cbus;$(SolutionDir)/../src/hardware/snd_pc98/common;$(SolutionDir)/../src/hardware/snd_pc98/generic;$(SolutionDir)/../src/hardware/snd_pc98/sound;$(SolutionDir)/../src/hardware/snd_pc98/x11;$(SolutionDir)/../src/hardware/snd_pc98/sound/getsnd;$(SolutionDir)/libpdcurses;$(SolutionDir)/../src;$(SolutionDir);$(SolutionDir)/zlib;$(SolutionDir)/sdl/include;$(SolutionDir)/libpng;$(SolutionDir)/sdlnet;$(SolutionDir)/libpdcurses;$(SolutionDir)/libpdcurses;$(SolutionDir)/freetype/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;__WIN32__;%(PreprocessorDefinitions);_FILE_OFFSET_BITS=64</PreprocessorDefinitions>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
@ -435,7 +435,7 @@ copy "$(SolutionDir)\..\CHANGELOG" "$(OutputPath)\changelog.txt"</Command>
</SDLCheck>
</ClCompile>
<Link>
<AdditionalDependencies>winmm.lib;imm32.lib;opengl32.lib;dxguid.lib;version.lib;Iphlpapi.lib;$(SolutionDir)..\obj\libpdcurses\$(Platform)\$(Configuration)\libpdcurses.lib;Ws2_32.lib;$(SolutionDir)..\obj\SDL\$(Platform)\$(Configuration)\SDL.lib;$(SolutionDir)..\obj\SDLmain\$(Platform)\$(Configuration)\SDLmain.lib;$(SolutionDir)..\obj\SDL_net\$(Platform)\$(Configuration)\SDL_net.lib;$(SolutionDir)..\obj\libpdcurses\$(Platform)\$(Configuration)\libpdcurses.lib;%(AdditionalDependencies);$(SolutionDir)..\obj\zlib\$(Platform)\$(Configuration)\zlib.lib;$(SolutionDir)..\obj\libpng\$(Platform)\$(Configuration)\libpng.lib</AdditionalDependencies>
<AdditionalDependencies>winmm.lib;imm32.lib;opengl32.lib;dxguid.lib;version.lib;Iphlpapi.lib;$(SolutionDir)..\obj\libpdcurses\$(Platform)\$(Configuration)\libpdcurses.lib;Ws2_32.lib;$(SolutionDir)..\obj\SDL\$(Platform)\$(Configuration)\SDL.lib;$(SolutionDir)..\obj\SDLmain\$(Platform)\$(Configuration)\SDLmain.lib;$(SolutionDir)..\obj\SDL_net\$(Platform)\$(Configuration)\SDL_net.lib;$(SolutionDir)..\obj\libpdcurses\$(Platform)\$(Configuration)\libpdcurses.lib;%(AdditionalDependencies);$(SolutionDir)..\obj\zlib\$(Platform)\$(Configuration)\zlib.lib;$(SolutionDir)..\obj\libpng\$(Platform)\$(Configuration)\libpng.lib;$(SolutionDir)..\obj\freetype\$(Platform)\Release Static\freetype.lib</AdditionalDependencies>
<ShowProgress>LinkVerboseLib</ShowProgress>
<OutputFile>$(OutDir)/$(ProjectName).exe</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
@ -472,7 +472,7 @@ copy "$(SolutionDir)\..\CHANGELOG" "$(OutputPath)\changelog.txt"</Command>
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(SolutionDir)/pcap;$(SolutionDir)/..;$(SolutionDir)/../include;$(SolutionDir)/../src/aviwriter;$(SolutionDir)/../src/mt32;$(SolutionDir)/../src/hardware/snd_pc98/cbus;$(SolutionDir)/../src/hardware/snd_pc98/common;$(SolutionDir)/../src/hardware/snd_pc98/generic;$(SolutionDir)/../src/hardware/snd_pc98/sound;$(SolutionDir)/../src/hardware/snd_pc98/x11;$(SolutionDir)/../src/hardware/snd_pc98/sound/getsnd;$(SolutionDir)/libpdcurses;$(SolutionDir)/sdl2/include;$(SolutionDir)/../src;$(SolutionDir);$(SolutionDir)/zlib;$(SolutionDir)/libpng;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)/pcap;$(SolutionDir)/..;$(SolutionDir)/../include;$(SolutionDir)/../src/aviwriter;$(SolutionDir)/../src/mt32;$(SolutionDir)/../src/hardware/snd_pc98/cbus;$(SolutionDir)/../src/hardware/snd_pc98/common;$(SolutionDir)/../src/hardware/snd_pc98/generic;$(SolutionDir)/../src/hardware/snd_pc98/sound;$(SolutionDir)/../src/hardware/snd_pc98/x11;$(SolutionDir)/../src/hardware/snd_pc98/sound/getsnd;$(SolutionDir)/libpdcurses;$(SolutionDir)/sdl2/include;$(SolutionDir)/../src;$(SolutionDir);$(SolutionDir)/zlib;$(SolutionDir)/libpng;$(SolutionDir)/freetype/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;__WIN32__;%(PreprocessorDefinitions);_FILE_OFFSET_BITS=64;C_SDL2=1</PreprocessorDefinitions>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
@ -497,7 +497,7 @@ copy "$(SolutionDir)\..\CHANGELOG" "$(OutputPath)\changelog.txt"</Command>
<WholeProgramOptimization>false</WholeProgramOptimization>
</ClCompile>
<Link>
<AdditionalDependencies>winmm.lib;imm32.lib;opengl32.lib;dxguid.lib;version.lib;Iphlpapi.lib;$(SolutionDir)..\obj\libpdcurses\$(Platform)\$(Configuration)\libpdcurses.lib;$(SolutionDir)..\obj\SDL2\$(Platform)\$(Configuration)\sdl2.lib;$(SolutionDir)..\obj\SDL2main\$(Platform)\$(Configuration)\sdl2main.lib;Ws2_32.lib;$(SolutionDir)..\obj\libpdcurses\$(Platform)\$(Configuration)\libpdcurses.lib;%(AdditionalDependencies);$(SolutionDir)..\obj\zlib\$(Platform)\$(Configuration)\zlib.lib;$(SolutionDir)..\obj\libpng\$(Platform)\$(Configuration)\libpng.lib</AdditionalDependencies>
<AdditionalDependencies>winmm.lib;imm32.lib;opengl32.lib;dxguid.lib;version.lib;Iphlpapi.lib;$(SolutionDir)..\obj\libpdcurses\$(Platform)\$(Configuration)\libpdcurses.lib;$(SolutionDir)..\obj\SDL2\$(Platform)\$(Configuration)\sdl2.lib;$(SolutionDir)..\obj\SDL2main\$(Platform)\$(Configuration)\sdl2main.lib;Ws2_32.lib;$(SolutionDir)..\obj\libpdcurses\$(Platform)\$(Configuration)\libpdcurses.lib;%(AdditionalDependencies);$(SolutionDir)..\obj\zlib\$(Platform)\$(Configuration)\zlib.lib;$(SolutionDir)..\obj\libpng\$(Platform)\$(Configuration)\libpng.lib;$(SolutionDir)..\obj\freetype\$(Platform)\Release Static\freetype.lib</AdditionalDependencies>
<ShowProgress>LinkVerboseLib</ShowProgress>
<OutputFile>$(OutDir)/$(ProjectName).exe</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
@ -537,7 +537,7 @@ copy "$(SolutionDir)\..\CHANGELOG" "$(OutputPath)\changelog.txt"</Command>
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(SolutionDir)/pcap;$(SolutionDir)/..;$(SolutionDir)/../include;$(SolutionDir)/../src/aviwriter;$(SolutionDir)/../src/mt32;$(SolutionDir)/../src/hardware/snd_pc98/cbus;$(SolutionDir)/../src/hardware/snd_pc98/common;$(SolutionDir)/../src/hardware/snd_pc98/generic;$(SolutionDir)/../src/hardware/snd_pc98/sound;$(SolutionDir)/../src/hardware/snd_pc98/x11;$(SolutionDir)/../src/hardware/snd_pc98/sound/getsnd;$(SolutionDir)/libpdcurses;$(SolutionDir)/../src;$(SolutionDir);$(SolutionDir)/zlib;$(SolutionDir)/sdl/include;$(SolutionDir)/libpng;$(SolutionDir)/sdlnet;$(SolutionDir)/libpdcurses;$(SolutionDir)/sdlnet;$(SolutionDir)/libpdcurses;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)/pcap;$(SolutionDir)/..;$(SolutionDir)/../include;$(SolutionDir)/../src/aviwriter;$(SolutionDir)/../src/mt32;$(SolutionDir)/../src/hardware/snd_pc98/cbus;$(SolutionDir)/../src/hardware/snd_pc98/common;$(SolutionDir)/../src/hardware/snd_pc98/generic;$(SolutionDir)/../src/hardware/snd_pc98/sound;$(SolutionDir)/../src/hardware/snd_pc98/x11;$(SolutionDir)/../src/hardware/snd_pc98/sound/getsnd;$(SolutionDir)/libpdcurses;$(SolutionDir)/../src;$(SolutionDir);$(SolutionDir)/zlib;$(SolutionDir)/sdl/include;$(SolutionDir)/libpng;$(SolutionDir)/sdlnet;$(SolutionDir)/libpdcurses;$(SolutionDir)/sdlnet;$(SolutionDir)/libpdcurses;$(SolutionDir)/freetype/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;__WIN32__;%(PreprocessorDefinitions);_FILE_OFFSET_BITS=64</PreprocessorDefinitions>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
@ -561,7 +561,7 @@ copy "$(SolutionDir)\..\CHANGELOG" "$(OutputPath)\changelog.txt"</Command>
</SDLCheck>
</ClCompile>
<Link>
<AdditionalDependencies>winmm.lib;imm32.lib;opengl32.lib;dxguid.lib;version.lib;Iphlpapi.lib;$(SolutionDir)..\obj\libpdcurses\$(Platform)\$(Configuration)\libpdcurses.lib;Ws2_32.lib;$(SolutionDir)..\obj\SDL\$(Platform)\$(Configuration)\SDL.lib;$(SolutionDir)..\obj\SDLmain\$(Platform)\$(Configuration)\SDLmain.lib;$(SolutionDir)..\obj\SDL_net\$(Platform)\$(Configuration)\SDL_net.lib;$(SolutionDir)..\obj\libpdcurses\$(Platform)\$(Configuration)\libpdcurses.lib;%(AdditionalDependencies);$(SolutionDir)..\obj\zlib\$(Platform)\$(Configuration)\zlib.lib;$(SolutionDir)..\obj\libpng\$(Platform)\$(Configuration)\libpng.lib</AdditionalDependencies>
<AdditionalDependencies>winmm.lib;imm32.lib;opengl32.lib;dxguid.lib;version.lib;Iphlpapi.lib;$(SolutionDir)..\obj\libpdcurses\$(Platform)\$(Configuration)\libpdcurses.lib;Ws2_32.lib;$(SolutionDir)..\obj\SDL\$(Platform)\$(Configuration)\SDL.lib;$(SolutionDir)..\obj\SDLmain\$(Platform)\$(Configuration)\SDLmain.lib;$(SolutionDir)..\obj\SDL_net\$(Platform)\$(Configuration)\SDL_net.lib;$(SolutionDir)..\obj\libpdcurses\$(Platform)\$(Configuration)\libpdcurses.lib;%(AdditionalDependencies);$(SolutionDir)..\obj\zlib\$(Platform)\$(Configuration)\zlib.lib;$(SolutionDir)..\obj\libpng\$(Platform)\$(Configuration)\libpng.lib;$(SolutionDir)..\obj\freetype\$(Platform)\Release Static\freetype.lib</AdditionalDependencies>
<ShowProgress>LinkVerboseLib</ShowProgress>
<OutputFile>$(OutDir)/$(ProjectName).exe</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
@ -599,7 +599,7 @@ copy "$(SolutionDir)\..\CHANGELOG" "$(OutputPath)\changelog.txt"</Command>
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(SolutionDir)/pcap;$(SolutionDir)/..;$(SolutionDir)/../include;$(SolutionDir)/../src/aviwriter;$(SolutionDir)/../src/mt32;$(SolutionDir)/../src/hardware/snd_pc98/cbus;$(SolutionDir)/../src/hardware/snd_pc98/common;$(SolutionDir)/../src/hardware/snd_pc98/generic;$(SolutionDir)/../src/hardware/snd_pc98/sound;$(SolutionDir)/../src/hardware/snd_pc98/x11;$(SolutionDir)/../src/hardware/snd_pc98/sound/getsnd;$(SolutionDir)/libpdcurses;$(SolutionDir)/sdl2/include;$(SolutionDir)/../src;$(SolutionDir);$(SolutionDir)/zlib;$(SolutionDir)/libpng;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)/pcap;$(SolutionDir)/..;$(SolutionDir)/../include;$(SolutionDir)/../src/aviwriter;$(SolutionDir)/../src/mt32;$(SolutionDir)/../src/hardware/snd_pc98/cbus;$(SolutionDir)/../src/hardware/snd_pc98/common;$(SolutionDir)/../src/hardware/snd_pc98/generic;$(SolutionDir)/../src/hardware/snd_pc98/sound;$(SolutionDir)/../src/hardware/snd_pc98/x11;$(SolutionDir)/../src/hardware/snd_pc98/sound/getsnd;$(SolutionDir)/libpdcurses;$(SolutionDir)/sdl2/include;$(SolutionDir)/../src;$(SolutionDir);$(SolutionDir)/zlib;$(SolutionDir)/libpng;$(SolutionDir)/freetype/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;__WIN32__;%(PreprocessorDefinitions);_FILE_OFFSET_BITS=64;C_SDL2=1</PreprocessorDefinitions>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
@ -625,7 +625,7 @@ copy "$(SolutionDir)\..\CHANGELOG" "$(OutputPath)\changelog.txt"</Command>
<WholeProgramOptimization>false</WholeProgramOptimization>
</ClCompile>
<Link>
<AdditionalDependencies>winmm.lib;imm32.lib;opengl32.lib;dxguid.lib;version.lib;Iphlpapi.lib;$(SolutionDir)..\obj\libpdcurses\$(Platform)\$(Configuration)\libpdcurses.lib;$(SolutionDir)..\obj\SDL2\$(Platform)\$(Configuration)\sdl2.lib;$(SolutionDir)..\obj\SDL2main\$(Platform)\$(Configuration)\sdl2main.lib;Ws2_32.lib;$(SolutionDir)..\obj\libpdcurses\$(Platform)\$(Configuration)\libpdcurses.lib;%(AdditionalDependencies);$(SolutionDir)..\obj\zlib\$(Platform)\$(Configuration)\zlib.lib;$(SolutionDir)..\obj\libpng\$(Platform)\$(Configuration)\libpng.lib</AdditionalDependencies>
<AdditionalDependencies>winmm.lib;imm32.lib;opengl32.lib;dxguid.lib;version.lib;Iphlpapi.lib;$(SolutionDir)..\obj\libpdcurses\$(Platform)\$(Configuration)\libpdcurses.lib;$(SolutionDir)..\obj\SDL2\$(Platform)\$(Configuration)\sdl2.lib;$(SolutionDir)..\obj\SDL2main\$(Platform)\$(Configuration)\sdl2main.lib;Ws2_32.lib;$(SolutionDir)..\obj\libpdcurses\$(Platform)\$(Configuration)\libpdcurses.lib;%(AdditionalDependencies);$(SolutionDir)..\obj\zlib\$(Platform)\$(Configuration)\zlib.lib;$(SolutionDir)..\obj\libpng\$(Platform)\$(Configuration)\libpng.lib;$(SolutionDir)..\obj\freetype\$(Platform)\Release Static\freetype.lib</AdditionalDependencies>
<ShowProgress>LinkVerboseLib</ShowProgress>
<OutputFile>$(OutDir)/$(ProjectName).exe</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
@ -722,7 +722,10 @@ copy "$(SolutionDir)\..\CHANGELOG" "$(OutputPath)\changelog.txt"</Command>
<ClCompile Include="..\src\fpu\fpu.cpp" />
<ClCompile Include="..\src\gui\bitop.cpp" />
<ClCompile Include="..\src\gui\ptrop.cpp" />
<ClCompile Include="..\src\gui\zipcrc.c" />
<ClCompile Include="..\src\gui\zipfile.cpp" />
<ClCompile Include="..\src\hardware\8255.cpp" />
<ClCompile Include="..\src\hardware\parport\printer_redir.cpp" />
<ClCompile Include="..\src\hardware\pc98.cpp" />
<ClCompile Include="..\src\hardware\pc98_fm.cpp" />
<ClCompile Include="..\src\hardware\snd_pc98\cbus\board26k.c" />
@ -761,7 +764,6 @@ copy "$(SolutionDir)\..\CHANGELOG" "$(OutputPath)\changelog.txt"</Command>
<ClCompile Include="..\src\aviwriter\avi_writer.cpp" />
<ClCompile Include="..\src\mt32\BReverbModel.cpp" />
<ClCompile Include="..\src\mt32\DelayReverb.cpp" />
<ClCompile Include="..\src\gui\direct3d.cpp" />
<ClCompile Include="..\src\mt32\File.cpp" />
<ClCompile Include="..\src\mt32\FileStream.cpp" />
<ClCompile Include="..\src\mt32\FreeverbModel.cpp" />
@ -769,7 +771,6 @@ copy "$(SolutionDir)\..\CHANGELOG" "$(OutputPath)\changelog.txt"</Command>
<ClCompile Include="..\src\mt32\freeverb\comb.cpp" />
<ClCompile Include="..\src\mt32\freeverb\revmodel.cpp" />
<ClCompile Include="..\src\aviwriter\guid.cpp" />
<ClCompile Include="..\src\gui\hq2x_d3d.cpp" />
<ClCompile Include="..\src\aviwriter\ksdataformat.cpp" />
<ClCompile Include="..\src\mt32\LA32Ramp.cpp" />
<ClCompile Include="..\src\mt32\LA32WaveGenerator.cpp" />
@ -785,7 +786,6 @@ copy "$(SolutionDir)\..\CHANGELOG" "$(OutputPath)\changelog.txt"</Command>
<ClCompile Include="..\src\aviwriter\riff.cpp" />
<ClCompile Include="..\src\aviwriter\riff_wav_writer.cpp" />
<ClCompile Include="..\src\mt32\ROMInfo.cpp" />
<ClCompile Include="..\src\gui\ScalingEffect.cpp" />
<ClCompile Include="..\src\gui\sdlmain.cpp" />
<ClCompile Include="..\src\gui\sdl_gui.cpp" />
<ClCompile Include="..\src\gui\sdl_mapper.cpp" />
@ -900,6 +900,16 @@ copy "$(SolutionDir)\..\CHANGELOG" "$(OutputPath)\changelog.txt"</Command>
<ClCompile Include="..\src\misc\regionalloctracking.cpp" />
<ClCompile Include="..\src\misc\setup.cpp" />
<ClCompile Include="..\src\misc\support.cpp" />
<ClCompile Include="..\src\output\direct3d\direct3d.cpp" />
<ClCompile Include="..\src\output\direct3d\hq2x_d3d.cpp" />
<ClCompile Include="..\src\output\direct3d\ScalingEffect.cpp" />
<ClCompile Include="..\src\output\output_direct3d.cpp" />
<ClCompile Include="..\src\output\output_opengl.cpp" />
<ClCompile Include="..\src\output\output_surface.cpp" />
<ClCompile Include="..\src\output\output_surface_sdl.cpp" />
<ClCompile Include="..\src\output\output_surface_sdl2.cpp" />
<ClCompile Include="..\src\output\output_tools.cpp" />
<ClCompile Include="..\src\output\output_tools_xbrz.cpp" />
<ClCompile Include="..\src\shell\shell.cpp" />
<ClCompile Include="..\src\shell\shell_batch.cpp" />
<ClCompile Include="..\src\shell\shell_cmds.cpp" />
@ -968,6 +978,7 @@ copy "$(SolutionDir)\..\CHANGELOG" "$(OutputPath)\changelog.txt"</Command>
<ClInclude Include="..\include\regs.h" />
<ClInclude Include="..\include\render.h" />
<ClInclude Include="..\include\resource.h" />
<ClInclude Include="..\include\sdlmain.h" />
<ClInclude Include="..\include\selftest.h" />
<ClInclude Include="..\include\serialport.h" />
<ClInclude Include="..\include\setup.h" />
@ -1007,12 +1018,9 @@ copy "$(SolutionDir)\..\CHANGELOG" "$(OutputPath)\changelog.txt"</Command>
<ClInclude Include="..\src\dos\scsidefs.h" />
<ClInclude Include="..\src\dos\wnaspi32.h" />
<ClInclude Include="..\src\fpu\fpu_instructions.h" />
<ClInclude Include="..\src\gui\d3d_components.h" />
<ClInclude Include="..\src\gui\direct3d.h" />
<ClInclude Include="..\src\gui\dosbox.cga640.bmp.h" />
<ClInclude Include="..\src\gui\dosbox.vga16.bmp.h" />
<ClInclude Include="..\src\gui\dosbox_logo.h" />
<ClInclude Include="..\src\gui\hq2x_d3d.h" />
<ClInclude Include="..\src\gui\midi_alsa.h" />
<ClInclude Include="..\src\gui\midi_coreaudio.h" />
<ClInclude Include="..\src\gui\midi_coremidi.h" />
@ -1029,7 +1037,6 @@ copy "$(SolutionDir)\..\CHANGELOG" "$(OutputPath)\changelog.txt"</Command>
<ClInclude Include="..\src\gui\render_templates_hq2x.h" />
<ClInclude Include="..\src\gui\render_templates_hq3x.h" />
<ClInclude Include="..\src\gui\render_templates_sai.h" />
<ClInclude Include="..\src\gui\ScalingEffect.h" />
<ClInclude Include="..\src\hardware\adlib.h" />
<ClInclude Include="..\src\hardware\dbopl.h" />
<ClInclude Include="..\src\hardware\nukedopl.h" />
@ -1118,6 +1125,15 @@ copy "$(SolutionDir)\..\CHANGELOG" "$(OutputPath)\changelog.txt"</Command>
<ClInclude Include="..\src\mt32\TVA.h" />
<ClInclude Include="..\src\mt32\TVF.h" />
<ClInclude Include="..\src\mt32\TVP.h" />
<ClInclude Include="..\src\output\direct3d\d3d_components.h" />
<ClInclude Include="..\src\output\direct3d\direct3d.h" />
<ClInclude Include="..\src\output\direct3d\hq2x_d3d.h" />
<ClInclude Include="..\src\output\direct3d\ScalingEffect.h" />
<ClInclude Include="..\src\output\output_direct3d.h" />
<ClInclude Include="..\src\output\output_opengl.h" />
<ClInclude Include="..\src\output\output_surface.h" />
<ClInclude Include="..\src\output\output_tools.h" />
<ClInclude Include="..\src\output\output_tools_xbrz.h" />
<ClInclude Include="..\src\xBRZ\xbrz.h" />
<ClInclude Include="..\src\xBRZ\xbrz_config.h" />
<ClInclude Include="..\src\xBRZ\xbrz_tools.h" />
@ -1126,4 +1142,4 @@ copy "$(SolutionDir)\..\CHANGELOG" "$(OutputPath)\changelog.txt"</Command>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

View File

@ -79,12 +79,36 @@
<Filter Include="Includes">
<UniqueIdentifier>{39027cf6-2435-4d52-a1ea-c3cc6c7f31ab}</UniqueIdentifier>
</Filter>
<Filter Include="Sources\pc98fmboards">
<UniqueIdentifier>{77588c09-bef2-4f95-a219-8ac9d696a7ff}</UniqueIdentifier>
</Filter>
<Filter Include="Sources\xBRZ">
<UniqueIdentifier>{6212d2c1-4c3f-4ec6-ad0e-88413d9f1b6c}</UniqueIdentifier>
</Filter>
<Filter Include="Sources\output">
<UniqueIdentifier>{b81e382e-b6fe-4ac3-91d1-a4c1e031214b}</UniqueIdentifier>
</Filter>
<Filter Include="Sources\hardware\snd_pc98">
<UniqueIdentifier>{bd560cc3-48c5-40d2-89ed-18bb890e85f6}</UniqueIdentifier>
</Filter>
<Filter Include="Sources\hardware\snd_pc98\cbus">
<UniqueIdentifier>{ac790bbf-6718-4b72-9cd1-b8f76f16c3a6}</UniqueIdentifier>
</Filter>
<Filter Include="Sources\hardware\snd_pc98\common">
<UniqueIdentifier>{845326a1-1737-4d13-8b97-a3e39829ffda}</UniqueIdentifier>
</Filter>
<Filter Include="Sources\hardware\snd_pc98\generic">
<UniqueIdentifier>{f01f7ecf-16a2-47f6-aab2-bb5089d70fc0}</UniqueIdentifier>
</Filter>
<Filter Include="Sources\hardware\snd_pc98\x11">
<UniqueIdentifier>{dd370a1a-f30e-4dbf-9d74-bf98b8be48f8}</UniqueIdentifier>
</Filter>
<Filter Include="Sources\hardware\snd_pc98\sound">
<UniqueIdentifier>{023b0f91-b8ac-4891-b979-69c5decfaa70}</UniqueIdentifier>
</Filter>
<Filter Include="Sources\hardware\snd_pc98\sound\getsnd">
<UniqueIdentifier>{f6769d5c-60ef-441a-9658-290ad81b7cec}</UniqueIdentifier>
</Filter>
<Filter Include="Sources\output\direct3d">
<UniqueIdentifier>{3755469d-f02e-4c3e-b6cd-25db8b71b1fd}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\src\aviwriter\avi_rw_iobuf.cpp">
@ -276,12 +300,6 @@
<ClCompile Include="..\src\fpu\fpu.cpp">
<Filter>Sources\fpu</Filter>
</ClCompile>
<ClCompile Include="..\src\gui\direct3d.cpp">
<Filter>Sources\gui</Filter>
</ClCompile>
<ClCompile Include="..\src\gui\hq2x_d3d.cpp">
<Filter>Sources\gui</Filter>
</ClCompile>
<ClCompile Include="..\src\gui\menu.cpp">
<Filter>Sources\gui</Filter>
</ClCompile>
@ -294,9 +312,6 @@
<ClCompile Include="..\src\gui\render_scalers.cpp">
<Filter>Sources\gui</Filter>
</ClCompile>
<ClCompile Include="..\src\gui\ScalingEffect.cpp">
<Filter>Sources\gui</Filter>
</ClCompile>
<ClCompile Include="..\src\gui\sdl_gui.cpp">
<Filter>Sources\gui</Filter>
</ClCompile>
@ -738,78 +753,6 @@
<ClCompile Include="..\src\dosbox.cpp">
<Filter>Sources</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\hardware.cpp">
<Filter>Sources\hardware\parport</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\cbus\board26k.c">
<Filter>Sources\pc98fmboards</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\cbus\board86.c">
<Filter>Sources\pc98fmboards</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\common\parts.c">
<Filter>Sources\pc98fmboards</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\generic\keydisp.c">
<Filter>Sources\pc98fmboards</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\sound\getsnd\getsmix.c">
<Filter>Sources\pc98fmboards</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\sound\getsnd\getsnd.c">
<Filter>Sources\pc98fmboards</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\sound\getsnd\getwave.c">
<Filter>Sources\pc98fmboards</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\sound\adpcmc.c">
<Filter>Sources\pc98fmboards</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\sound\adpcmg.c">
<Filter>Sources\pc98fmboards</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\sound\fmboard.c">
<Filter>Sources\pc98fmboards</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\sound\fmtimer.c">
<Filter>Sources\pc98fmboards</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\sound\opngenc.c">
<Filter>Sources\pc98fmboards</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\sound\opngeng.c">
<Filter>Sources\pc98fmboards</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\sound\pcm86c.c">
<Filter>Sources\pc98fmboards</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\sound\pcm86g.c">
<Filter>Sources\pc98fmboards</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\sound\psggenc.c">
<Filter>Sources\pc98fmboards</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\sound\psggeng.c">
<Filter>Sources\pc98fmboards</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\sound\rhythmc.c">
<Filter>Sources\pc98fmboards</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\sound\sound.c">
<Filter>Sources\pc98fmboards</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\sound\soundrom.c">
<Filter>Sources\pc98fmboards</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\sound\tms3631c.c">
<Filter>Sources\pc98fmboards</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\sound\tms3631g.c">
<Filter>Sources\pc98fmboards</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\x11\dosio.c">
<Filter>Sources\pc98fmboards</Filter>
</ClCompile>
<ClCompile Include="..\src\cpu\core_dyn_x86.cpp">
<Filter>Sources\cpu</Filter>
</ClCompile>
@ -831,6 +774,117 @@
<ClCompile Include="..\src\gui\ptrop.cpp">
<Filter>Sources\gui</Filter>
</ClCompile>
<ClCompile Include="..\src\output\output_surface.cpp">
<Filter>Sources\output</Filter>
</ClCompile>
<ClCompile Include="..\src\output\output_direct3d.cpp">
<Filter>Sources\output</Filter>
</ClCompile>
<ClCompile Include="..\src\output\output_opengl.cpp">
<Filter>Sources\output</Filter>
</ClCompile>
<ClCompile Include="..\src\output\output_tools.cpp">
<Filter>Sources\output</Filter>
</ClCompile>
<ClCompile Include="..\src\output\output_tools_xbrz.cpp">
<Filter>Sources\output</Filter>
</ClCompile>
<ClCompile Include="..\src\output\output_surface_sdl2.cpp">
<Filter>Sources\output</Filter>
</ClCompile>
<ClCompile Include="..\src\output\output_surface_sdl.cpp">
<Filter>Sources\output</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\hardware.cpp">
<Filter>Sources\hardware</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\sound\adpcmg.c">
<Filter>Sources\hardware\snd_pc98\sound</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\sound\adpcmc.c">
<Filter>Sources\hardware\snd_pc98\sound</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\cbus\board26k.c">
<Filter>Sources\hardware\snd_pc98\cbus</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\cbus\board86.c">
<Filter>Sources\hardware\snd_pc98\cbus</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\x11\dosio.c">
<Filter>Sources\hardware\snd_pc98\x11</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\sound\fmboard.c">
<Filter>Sources\hardware\snd_pc98\sound</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\sound\fmtimer.c">
<Filter>Sources\hardware\snd_pc98\sound</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\sound\getsnd\getsmix.c">
<Filter>Sources\hardware\snd_pc98\sound\getsnd</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\sound\getsnd\getsnd.c">
<Filter>Sources\hardware\snd_pc98\sound\getsnd</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\sound\getsnd\getwave.c">
<Filter>Sources\hardware\snd_pc98\sound\getsnd</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\generic\keydisp.c">
<Filter>Sources\hardware\snd_pc98\generic</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\sound\opngenc.c">
<Filter>Sources\hardware\snd_pc98\sound</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\sound\opngeng.c">
<Filter>Sources\hardware\snd_pc98\sound</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\common\parts.c">
<Filter>Sources\hardware\snd_pc98\common</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\sound\pcm86c.c">
<Filter>Sources\hardware\snd_pc98\sound</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\sound\pcm86g.c">
<Filter>Sources\hardware\snd_pc98\sound</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\sound\psggenc.c">
<Filter>Sources\hardware\snd_pc98\sound</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\sound\psggeng.c">
<Filter>Sources\hardware\snd_pc98\sound</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\sound\rhythmc.c">
<Filter>Sources\hardware\snd_pc98\sound</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\sound\sound.c">
<Filter>Sources\hardware\snd_pc98\sound</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\sound\soundrom.c">
<Filter>Sources\hardware\snd_pc98\sound</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\sound\tms3631c.c">
<Filter>Sources\hardware\snd_pc98\sound</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\snd_pc98\sound\tms3631g.c">
<Filter>Sources\hardware\snd_pc98\sound</Filter>
</ClCompile>
<ClCompile Include="..\src\output\direct3d\direct3d.cpp">
<Filter>Sources\output\direct3d</Filter>
</ClCompile>
<ClCompile Include="..\src\output\direct3d\hq2x_d3d.cpp">
<Filter>Sources\output\direct3d</Filter>
</ClCompile>
<ClCompile Include="..\src\output\direct3d\ScalingEffect.cpp">
<Filter>Sources\output\direct3d</Filter>
</ClCompile>
<ClCompile Include="..\src\gui\zipfile.cpp">
<Filter>Sources</Filter>
</ClCompile>
<ClCompile Include="..\src\gui\zipcrc.c">
<Filter>Sources</Filter>
</ClCompile>
<ClCompile Include="..\src\hardware\parport\printer_redir.cpp">
<Filter>Sources\hardware\parport</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\src\aviwriter\avi.h">
@ -893,12 +947,6 @@
<ClInclude Include="..\src\fpu\fpu_instructions.h">
<Filter>Sources\fpu</Filter>
</ClInclude>
<ClInclude Include="..\src\gui\d3d_components.h">
<Filter>Sources\gui</Filter>
</ClInclude>
<ClInclude Include="..\src\gui\direct3d.h">
<Filter>Sources\gui</Filter>
</ClInclude>
<ClInclude Include="..\src\gui\dosbox.cga640.bmp.h">
<Filter>Sources\gui</Filter>
</ClInclude>
@ -908,9 +956,6 @@
<ClInclude Include="..\src\gui\dosbox_logo.h">
<Filter>Sources\gui</Filter>
</ClInclude>
<ClInclude Include="..\src\gui\hq2x_d3d.h">
<Filter>Sources\gui</Filter>
</ClInclude>
<ClInclude Include="..\src\gui\midi_alsa.h">
<Filter>Sources\gui</Filter>
</ClInclude>
@ -959,9 +1004,6 @@
<ClInclude Include="..\src\gui\render_templates_sai.h">
<Filter>Sources\gui</Filter>
</ClInclude>
<ClInclude Include="..\src\gui\ScalingEffect.h">
<Filter>Sources\gui</Filter>
</ClInclude>
<ClInclude Include="..\src\hardware\adlib.h">
<Filter>Sources\hardware</Filter>
</ClInclude>
@ -1394,60 +1436,6 @@
<ClInclude Include="..\src\libs\zmbv\zmbv_vfw.h">
<Filter>Sources\libs\zmbv</Filter>
</ClInclude>
<ClInclude Include="..\src\hardware\snd_pc98\cbus\board26k.h">
<Filter>Sources\pc98fmboards</Filter>
</ClInclude>
<ClInclude Include="..\src\hardware\snd_pc98\cbus\board86.h">
<Filter>Sources\pc98fmboards</Filter>
</ClInclude>
<ClInclude Include="..\src\hardware\snd_pc98\common\parts.h">
<Filter>Sources\pc98fmboards</Filter>
</ClInclude>
<ClInclude Include="..\src\hardware\snd_pc98\common\profile.h">
<Filter>Sources\pc98fmboards</Filter>
</ClInclude>
<ClInclude Include="..\src\hardware\snd_pc98\common\wavefile.h">
<Filter>Sources\pc98fmboards</Filter>
</ClInclude>
<ClInclude Include="..\src\hardware\snd_pc98\generic\keydisp.h">
<Filter>Sources\pc98fmboards</Filter>
</ClInclude>
<ClInclude Include="..\src\hardware\snd_pc98\sound\getsnd\getsnd.h">
<Filter>Sources\pc98fmboards</Filter>
</ClInclude>
<ClInclude Include="..\src\hardware\snd_pc98\sound\adpcm.h">
<Filter>Sources\pc98fmboards</Filter>
</ClInclude>
<ClInclude Include="..\src\hardware\snd_pc98\sound\fmboard.h">
<Filter>Sources\pc98fmboards</Filter>
</ClInclude>
<ClInclude Include="..\src\hardware\snd_pc98\sound\fmtimer.h">
<Filter>Sources\pc98fmboards</Filter>
</ClInclude>
<ClInclude Include="..\src\hardware\snd_pc98\sound\opngen.h">
<Filter>Sources\pc98fmboards</Filter>
</ClInclude>
<ClInclude Include="..\src\hardware\snd_pc98\sound\pcm86.h">
<Filter>Sources\pc98fmboards</Filter>
</ClInclude>
<ClInclude Include="..\src\hardware\snd_pc98\sound\psggen.h">
<Filter>Sources\pc98fmboards</Filter>
</ClInclude>
<ClInclude Include="..\src\hardware\snd_pc98\sound\rhythm.h">
<Filter>Sources\pc98fmboards</Filter>
</ClInclude>
<ClInclude Include="..\src\hardware\snd_pc98\sound\sound.h">
<Filter>Sources\pc98fmboards</Filter>
</ClInclude>
<ClInclude Include="..\src\hardware\snd_pc98\sound\soundrom.h">
<Filter>Sources\pc98fmboards</Filter>
</ClInclude>
<ClInclude Include="..\src\hardware\snd_pc98\sound\tms3631.h">
<Filter>Sources\pc98fmboards</Filter>
</ClInclude>
<ClInclude Include="..\src\hardware\snd_pc98\x11\dosio.h">
<Filter>Sources\pc98fmboards</Filter>
</ClInclude>
<ClInclude Include="config.h">
<Filter>Includes</Filter>
</ClInclude>
@ -1469,10 +1457,94 @@
<ClInclude Include="..\include\ptrop.h">
<Filter>Includes</Filter>
</ClInclude>
<ClInclude Include="..\include\sdlmain.h">
<Filter>Includes</Filter>
</ClInclude>
<ClInclude Include="..\src\output\output_surface.h">
<Filter>Sources\output</Filter>
</ClInclude>
<ClInclude Include="..\src\output\output_direct3d.h">
<Filter>Sources\output</Filter>
</ClInclude>
<ClInclude Include="..\src\output\output_opengl.h">
<Filter>Sources\output</Filter>
</ClInclude>
<ClInclude Include="..\src\output\output_tools.h">
<Filter>Sources\output</Filter>
</ClInclude>
<ClInclude Include="..\src\output\output_tools_xbrz.h">
<Filter>Sources\output</Filter>
</ClInclude>
<ClInclude Include="..\src\hardware\snd_pc98\sound\adpcm.h">
<Filter>Sources\hardware\snd_pc98\sound</Filter>
</ClInclude>
<ClInclude Include="..\src\hardware\snd_pc98\cbus\board26k.h">
<Filter>Sources\hardware\snd_pc98\cbus</Filter>
</ClInclude>
<ClInclude Include="..\src\hardware\snd_pc98\cbus\board86.h">
<Filter>Sources\hardware\snd_pc98\cbus</Filter>
</ClInclude>
<ClInclude Include="..\src\hardware\snd_pc98\x11\dosio.h">
<Filter>Sources\hardware\snd_pc98\x11</Filter>
</ClInclude>
<ClInclude Include="..\src\hardware\snd_pc98\sound\fmboard.h">
<Filter>Sources\hardware\snd_pc98\sound</Filter>
</ClInclude>
<ClInclude Include="..\src\hardware\snd_pc98\sound\fmtimer.h">
<Filter>Sources\hardware\snd_pc98\sound</Filter>
</ClInclude>
<ClInclude Include="..\src\hardware\snd_pc98\sound\getsnd\getsnd.h">
<Filter>Sources\hardware\snd_pc98\sound\getsnd</Filter>
</ClInclude>
<ClInclude Include="..\src\hardware\snd_pc98\generic\keydisp.h">
<Filter>Sources\hardware\snd_pc98\generic</Filter>
</ClInclude>
<ClInclude Include="..\src\hardware\snd_pc98\sound\opngen.h">
<Filter>Sources\hardware\snd_pc98\sound</Filter>
</ClInclude>
<ClInclude Include="..\src\hardware\snd_pc98\common\parts.h">
<Filter>Sources\hardware\snd_pc98\common</Filter>
</ClInclude>
<ClInclude Include="..\src\hardware\snd_pc98\sound\pcm86.h">
<Filter>Sources\hardware\snd_pc98\sound</Filter>
</ClInclude>
<ClInclude Include="..\src\hardware\snd_pc98\common\profile.h">
<Filter>Sources\hardware\snd_pc98\common</Filter>
</ClInclude>
<ClInclude Include="..\src\hardware\snd_pc98\sound\psggen.h">
<Filter>Sources\hardware\snd_pc98\sound</Filter>
</ClInclude>
<ClInclude Include="..\src\hardware\snd_pc98\sound\rhythm.h">
<Filter>Sources\hardware\snd_pc98\sound</Filter>
</ClInclude>
<ClInclude Include="..\src\hardware\snd_pc98\sound\sound.h">
<Filter>Sources\hardware\snd_pc98\sound</Filter>
</ClInclude>
<ClInclude Include="..\src\hardware\snd_pc98\sound\soundrom.h">
<Filter>Sources\hardware\snd_pc98\sound</Filter>
</ClInclude>
<ClInclude Include="..\src\hardware\snd_pc98\sound\tms3631.h">
<Filter>Sources\hardware\snd_pc98\sound</Filter>
</ClInclude>
<ClInclude Include="..\src\hardware\snd_pc98\common\wavefile.h">
<Filter>Sources\hardware\snd_pc98\common</Filter>
</ClInclude>
<ClInclude Include="..\src\output\direct3d\d3d_components.h">
<Filter>Sources\output\direct3d</Filter>
</ClInclude>
<ClInclude Include="..\src\output\direct3d\direct3d.h">
<Filter>Sources\output\direct3d</Filter>
</ClInclude>
<ClInclude Include="..\src\output\direct3d\hq2x_d3d.h">
<Filter>Sources\output\direct3d</Filter>
</ClInclude>
<ClInclude Include="..\src\output\direct3d\ScalingEffect.h">
<Filter>Sources\output\direct3d</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\src\winres.rc">
<Filter>Sources</Filter>
</ResourceCompile>
</ItemGroup>
</Project>
</Project>

View File

@ -0,0 +1,497 @@
# CMakeLists.txt
#
# Copyright 2013-2018 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# Written originally by John Cary <cary@txcorp.com>
#
# This file is part of the FreeType project, and may only be used, modified,
# and distributed under the terms of the FreeType project license,
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
# indicate that you have read the license and understand and accept it
# fully.
#
#
# The following will 1. create a build directory and 2. change into it and
# call cmake to configure the build with default parameters as a static
# library.
#
# cmake -E make_directory build
# cmake -E chdir build cmake ..
#
# For a dynamic library, use
#
# cmake -E chdir build cmake -D BUILD_SHARED_LIBS:BOOL=true ..
#
# For a framework on OS X, use
#
# cmake -E chdir build cmake -G Xcode -D BUILD_FRAMEWORK:BOOL=true ..
#
# For an iOS static library, use
#
# cmake -E chdir build cmake -G Xcode -D IOS_PLATFORM=OS ..
#
# or
#
# cmake -E chdir build cmake -G Xcode -D IOS_PLATFORM=SIMULATOR ..
#
# Finally, build the project with:
#
# cmake --build build
#
# Install it with
#
# (sudo) cmake --build build --target install
#
# A binary distribution can be made with
#
# cmake --build build --config Release --target package
#
# Please refer to the cmake manual for further options, in particular, how
# to modify compilation and linking parameters.
#
# Some notes.
#
# . `cmake' creates configuration files in
#
# <build-directory>/include/freetype/config
#
# which should be further modified if necessary.
#
# . You can use `cmake' directly on a freshly cloned FreeType git
# repository.
#
# . `CMakeLists.txt' is provided as-is since it is normally not used by the
# developer team.
#
# . Set the `FT_WITH_ZLIB', `FT_WITH_BZIP2', `FT_WITH_PNG', and
# `FT_WITH_HARFBUZZ' CMake variables to `ON' to force using a dependency.
# Leave a variable undefined (which is the default) to use the dependency
# only if it is available. Set `CMAKE_DISABLE_FIND_PACKAGE_HarfBuzz=TRUE' to
# disable a dependency completely (CMake package name, so `BZip2' instead of
# `BZIP2'). Example:
#
# cmake -DFT_WITH_ZLIB=ON -DCMAKE_DISABLE_FIND_PACKAGE_HarfBuzz=TRUE [...]
#
# . Installation of FreeType can be controlled with the CMake variables
# `SKIP_INSTALL_HEADERS', `SKIP_INSTALL_LIBRARIES', and `SKIP_INSTALL_ALL'
# (this is compatible with the same CMake variables in zlib's CMake
# support).
# FreeType explicitly marks the API to be exported and relies on the compiler
# to hide all other symbols. CMake supports a C_VISBILITY_PRESET property
# starting with 2.8.12.
cmake_minimum_required(VERSION 2.8.12)
if (NOT CMAKE_VERSION VERSION_LESS 3.3)
# Allow symbol visibility settings also on static libraries. CMake < 3.3
# only sets the propery on a shared library build.
cmake_policy(SET CMP0063 NEW)
endif ()
include(CheckIncludeFile)
# CMAKE_TOOLCHAIN_FILE must be set before `project' is called, which
# configures the base build environment and references the toolchain file
if (APPLE)
if (DEFINED IOS_PLATFORM)
if (NOT "${IOS_PLATFORM}" STREQUAL "OS"
AND NOT "${IOS_PLATFORM}" STREQUAL "SIMULATOR")
message(FATAL_ERROR
"IOS_PLATFORM must be set to either OS or SIMULATOR")
endif ()
if (NOT "${CMAKE_GENERATOR}" STREQUAL "Xcode")
message(AUTHOR_WARNING
"You should use Xcode generator with IOS_PLATFORM enabled to get Universal builds.")
endif ()
if (BUILD_SHARED_LIBS)
message(FATAL_ERROR
"BUILD_SHARED_LIBS can not be on with IOS_PLATFORM enabled")
endif ()
if (BUILD_FRAMEWORK)
message(FATAL_ERROR
"BUILD_FRAMEWORK can not be on with IOS_PLATFORM enabled")
endif ()
# iOS only uses static libraries
set(BUILD_SHARED_LIBS OFF)
set(CMAKE_TOOLCHAIN_FILE
${CMAKE_SOURCE_DIR}/builds/cmake/iOS.cmake)
endif ()
else ()
if (DEFINED IOS_PLATFORM)
message(FATAL_ERROR "IOS_PLATFORM is not supported on this platform")
endif ()
endif ()
project(freetype C)
set(VERSION_MAJOR "2")
set(VERSION_MINOR "9")
set(VERSION_PATCH "1")
# SOVERSION scheme: CURRENT.AGE.REVISION
# If there was an incompatible interface change:
# Increment CURRENT. Set AGE and REVISION to 0
# If there was a compatible interface change:
# Increment AGE. Set REVISION to 0
# If the source code was changed, but there were no interface changes:
# Increment REVISION.
set(LIBRARY_VERSION "6.16.0")
set(LIBRARY_SOVERSION "6")
# These options mean "require x and complain if not found". They'll get
# optionally found anyway. Use `-DCMAKE_DISABLE_FIND_PACKAGE_x=TRUE` to disable
# searching for a packge entirely (x is the CMake package name, so "BZip2"
# instead of "BZIP2").
option(FT_WITH_ZLIB "Use system zlib instead of internal library." OFF)
option(FT_WITH_BZIP2 "Support bzip2 compressed fonts." OFF)
option(FT_WITH_PNG "Support PNG compressed OpenType embedded bitmaps." OFF)
option(FT_WITH_HARFBUZZ "Improve auto-hinting of OpenType fonts." OFF)
# Disallow in-source builds
if ("${PROJECT_BINARY_DIR}" STREQUAL "${PROJECT_SOURCE_DIR}")
message(FATAL_ERROR
"In-source builds are not permitted! Make a separate folder for"
" building, e.g.,\n"
" cmake -E make_directory build\n"
" cmake -E chdir build cmake ..\n"
"Before that, remove the files created by this failed run with\n"
" cmake -E remove CMakeCache.txt\n"
" cmake -E remove_directory CMakeFiles")
endif ()
# Add local cmake modules
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/builds/cmake)
if (BUILD_FRAMEWORK)
if (NOT "${CMAKE_GENERATOR}" STREQUAL "Xcode")
message(FATAL_ERROR
"You should use Xcode generator with BUILD_FRAMEWORK enabled")
endif ()
set(CMAKE_OSX_ARCHITECTURES "$(ARCHS_STANDARD_32_64_BIT)")
set(BUILD_SHARED_LIBS ON)
endif ()
# Find dependencies
if (FT_WITH_HARFBUZZ)
find_package(HarfBuzz 1.3.0 REQUIRED)
else ()
find_package(HarfBuzz 1.3.0)
endif ()
if (FT_WITH_PNG)
find_package(PNG REQUIRED)
else ()
find_package(PNG)
endif ()
if (FT_WITH_ZLIB)
find_package(ZLIB REQUIRED)
else ()
find_package(ZLIB)
endif ()
if (FT_WITH_BZIP2)
find_package(BZip2 REQUIRED)
else ()
find_package(BZip2)
endif ()
# Create the configuration file
if (UNIX)
check_include_file("unistd.h" HAVE_UNISTD_H)
check_include_file("fcntl.h" HAVE_FCNTL_H)
check_include_file("stdint.h" HAVE_STDINT_H)
file(READ "${PROJECT_SOURCE_DIR}/builds/unix/ftconfig.in"
FTCONFIG_H)
if (HAVE_UNISTD_H)
string(REGEX REPLACE
"#undef +(HAVE_UNISTD_H)" "#define \\1 1"
FTCONFIG_H "${FTCONFIG_H}")
endif ()
if (HAVE_FCNTL_H)
string(REGEX REPLACE
"#undef +(HAVE_FCNTL_H)" "#define \\1 1"
FTCONFIG_H "${FTCONFIG_H}")
endif ()
if (HAVE_STDINT_H)
string(REGEX REPLACE
"#undef +(HAVE_STDINT_H)" "#define \\1 1"
FTCONFIG_H "${FTCONFIG_H}")
endif ()
string(REPLACE "/undef " "#undef "
FTCONFIG_H "${FTCONFIG_H}")
file(WRITE "${PROJECT_BINARY_DIR}/include/freetype/config/ftconfig.h"
"${FTCONFIG_H}")
endif ()
# Create the options file
file(READ "${PROJECT_SOURCE_DIR}/include/freetype/config/ftoption.h"
FTOPTION_H)
if (ZLIB_FOUND)
string(REGEX REPLACE
"/\\* +(#define +FT_CONFIG_OPTION_SYSTEM_ZLIB) +\\*/" "\\1"
FTOPTION_H "${FTOPTION_H}")
endif ()
if (BZIP2_FOUND)
string(REGEX REPLACE
"/\\* +(#define +FT_CONFIG_OPTION_USE_BZIP2) +\\*/" "\\1"
FTOPTION_H "${FTOPTION_H}")
endif ()
if (PNG_FOUND)
string(REGEX REPLACE
"/\\* +(#define +FT_CONFIG_OPTION_USE_PNG) +\\*/" "\\1"
FTOPTION_H "${FTOPTION_H}")
endif ()
if (HARFBUZZ_FOUND)
string(REGEX REPLACE
"/\\* +(#define +FT_CONFIG_OPTION_USE_HARFBUZZ) +\\*/" "\\1"
FTOPTION_H "${FTOPTION_H}")
endif ()
file(WRITE "${PROJECT_BINARY_DIR}/include/freetype/config/ftoption.h"
"${FTOPTION_H}")
file(GLOB PUBLIC_HEADERS "include/ft2build.h" "include/freetype/*.h")
file(GLOB PUBLIC_CONFIG_HEADERS "include/freetype/config/*.h")
file(GLOB PRIVATE_HEADERS "include/freetype/internal/*.h")
set(BASE_SRCS
src/autofit/autofit.c
src/base/ftbase.c
src/base/ftbbox.c
src/base/ftbdf.c
src/base/ftbitmap.c
src/base/ftcid.c
src/base/ftfstype.c
src/base/ftgasp.c
src/base/ftglyph.c
src/base/ftgxval.c
src/base/ftinit.c
src/base/ftmm.c
src/base/ftotval.c
src/base/ftpatent.c
src/base/ftpfr.c
src/base/ftstroke.c
src/base/ftsynth.c
src/base/ftsystem.c
src/base/fttype1.c
src/base/ftwinfnt.c
src/bdf/bdf.c
src/bzip2/ftbzip2.c
src/cache/ftcache.c
src/cff/cff.c
src/cid/type1cid.c
src/gzip/ftgzip.c
src/lzw/ftlzw.c
src/pcf/pcf.c
src/pfr/pfr.c
src/psaux/psaux.c
src/pshinter/pshinter.c
src/psnames/psnames.c
src/raster/raster.c
src/sfnt/sfnt.c
src/smooth/smooth.c
src/truetype/truetype.c
src/type1/type1.c
src/type42/type42.c
src/winfonts/winfnt.c
)
if (WIN32)
enable_language(RC)
list(APPEND BASE_SRCS builds/windows/ftdebug.c
src/base/ftver.rc)
elseif (WINCE)
list(APPEND BASE_SRCS builds/wince/ftdebug.c)
else ()
list(APPEND BASE_SRCS src/base/ftdebug.c)
endif ()
if (BUILD_FRAMEWORK)
list(APPEND BASE_SRCS builds/mac/freetype-Info.plist)
endif ()
if (NOT DISABLE_FORCE_DEBUG_POSTFIX)
set(CMAKE_DEBUG_POSTFIX d)
endif()
add_library(freetype
${PUBLIC_HEADERS}
${PUBLIC_CONFIG_HEADERS}
${PRIVATE_HEADERS}
${BASE_SRCS}
)
set_target_properties(
freetype PROPERTIES
C_VISIBILITY_PRESET hidden)
target_compile_definitions(
freetype PRIVATE FT2_BUILD_LIBRARY)
if (WIN32)
target_compile_definitions(
freetype PRIVATE _CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_WARNINGS)
endif ()
if (BUILD_SHARED_LIBS)
set_target_properties(freetype PROPERTIES
VERSION ${LIBRARY_VERSION}
SOVERSION ${LIBRARY_SOVERSION})
endif ()
target_include_directories(
freetype BEFORE # Pick up ftconfig.h and ftoption.h generated above.
PRIVATE "${PROJECT_BINARY_DIR}/include")
target_include_directories(
freetype
PRIVATE "${PROJECT_SOURCE_DIR}/include")
target_include_directories(
freetype
PUBLIC $<INSTALL_INTERFACE:include/freetype2>)
if (BUILD_FRAMEWORK)
set_property(SOURCE ${PUBLIC_CONFIG_HEADERS}
PROPERTY MACOSX_PACKAGE_LOCATION Headers/config
)
set_target_properties(freetype PROPERTIES
FRAMEWORK TRUE
MACOSX_FRAMEWORK_INFO_PLIST builds/mac/freetype-Info.plist
PUBLIC_HEADER "${PUBLIC_HEADERS}"
XCODE_ATTRIBUTE_INSTALL_PATH "@rpath"
)
endif ()
set(PKG_CONFIG_REQUIRED_PRIVATE "")
if (ZLIB_FOUND)
target_link_libraries(freetype PRIVATE ${ZLIB_LIBRARIES})
target_include_directories(freetype PRIVATE ${ZLIB_INCLUDE_DIRS})
list(APPEND PKG_CONFIG_REQUIRED_PRIVATE zlib)
endif ()
if (BZIP2_FOUND)
target_link_libraries(freetype PRIVATE ${BZIP2_LIBRARIES})
target_include_directories(freetype PRIVATE ${BZIP2_INCLUDE_DIR}) # not BZIP2_INCLUDE_DIRS
list(APPEND PKG_CONFIG_REQUIRED_PRIVATE bzip2)
endif ()
if (PNG_FOUND)
target_link_libraries(freetype PRIVATE ${PNG_LIBRARIES})
target_compile_definitions(freetype PRIVATE ${PNG_DEFINITIONS})
target_include_directories(freetype PRIVATE ${PNG_INCLUDE_DIRS})
list(APPEND PKG_CONFIG_REQUIRED_PRIVATE libpng)
endif ()
if (HARFBUZZ_FOUND)
target_link_libraries(freetype PRIVATE ${HARFBUZZ_LIBRARIES})
target_include_directories(freetype PRIVATE ${HARFBUZZ_INCLUDE_DIRS})
list(APPEND PKG_CONFIG_REQUIRED_PRIVATE harfbuzz)
endif ()
# Installation
include(GNUInstallDirs)
if (NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL)
install(
# Note the trailing slash in the argument to `DIRECTORY'!
DIRECTORY ${PROJECT_SOURCE_DIR}/include/
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/freetype2
COMPONENT headers
PATTERN "internal" EXCLUDE
PATTERN "ftconfig.h" EXCLUDE
PATTERN "ftoption.h" EXCLUDE)
install(
FILES ${PROJECT_BINARY_DIR}/include/freetype/config/ftconfig.h
${PROJECT_BINARY_DIR}/include/freetype/config/ftoption.h
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/freetype2/freetype/config
COMPONENT headers)
endif ()
if (NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL)
# Generate the pkg-config file
if (UNIX)
file(READ ${PROJECT_SOURCE_DIR}/builds/unix/freetype2.in FREETYPE2_PC_IN)
string(REPLACE ";" ", " PKG_CONFIG_REQUIRED_PRIVATE "${PKG_CONFIG_REQUIRED_PRIVATE}")
string(REPLACE "%prefix%" ${CMAKE_INSTALL_PREFIX}
FREETYPE2_PC_IN ${FREETYPE2_PC_IN})
string(REPLACE "%exec_prefix%" "\${prefix}"
FREETYPE2_PC_IN ${FREETYPE2_PC_IN})
string(REPLACE "%libdir%" "\${prefix}/${CMAKE_INSTALL_LIBDIR}"
FREETYPE2_PC_IN ${FREETYPE2_PC_IN})
string(REPLACE "%includedir%" "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}"
FREETYPE2_PC_IN ${FREETYPE2_PC_IN})
string(REPLACE "%ft_version%" "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}"
FREETYPE2_PC_IN ${FREETYPE2_PC_IN})
string(REPLACE "%REQUIRES_PRIVATE%" "${PKG_CONFIG_REQUIRED_PRIVATE}"
FREETYPE2_PC_IN ${FREETYPE2_PC_IN})
string(REPLACE "%LIBS_PRIVATE%" "" # All libs support pkg-config
FREETYPE2_PC_IN ${FREETYPE2_PC_IN})
file(WRITE ${PROJECT_BINARY_DIR}/freetype2.pc ${FREETYPE2_PC_IN})
install(
FILES ${PROJECT_BINARY_DIR}/freetype2.pc
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
COMPONENT pkgconfig)
endif ()
install(
TARGETS freetype
EXPORT freetype-targets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
FRAMEWORK DESTINATION Library/Frameworks
COMPONENT libraries)
install(
EXPORT freetype-targets
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/freetype
FILE freetype-config.cmake
COMPONENT headers)
endif ()
# Packaging
set(CPACK_PACKAGE_NAME ${CMAKE_PROJECT_NAME})
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "The FreeType font rendering library.")
set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README")
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/docs/LICENSE.TXT")
set(CPACK_PACKAGE_VERSION_MAJOR ${VERSION_MAJOR})
set(CPACK_PACKAGE_VERSION_MINOR ${VERSION_MINOR})
set(CPACK_PACKAGE_VERSION_PATCH ${VERSION_PATCH})
set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
if (WIN32)
set(CPACK_GENERATOR ZIP)
else()
set(CPACK_GENERATOR TGZ)
endif()
set(CPACK_COMPONENT_LIBRARIES_DISPLAY_NAME "Libraries")
set(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "C/C++ Headers")
set(CPACK_COMPONENT_LIBRARIES_DESCRIPTION
"Library used to build programs which use FreeType")
set(CPACK_COMPONENT_HEADERS_DESCRIPTION
"C/C++ header files for use with FreeType")
set(CPACK_COMPONENT_HEADERS_DEPENDS libraries)
set(CPACK_COMPONENT_LIBRARIES_GROUP "Development")
set(CPACK_COMPONENT_HEADERS_GROUP "Development")
include(CPack)

2352
vs2015/freetype/ChangeLog Normal file

File diff suppressed because it is too large Load Diff

2613
vs2015/freetype/ChangeLog.20 Normal file

File diff suppressed because it is too large Load Diff

9438
vs2015/freetype/ChangeLog.21 Normal file

File diff suppressed because it is too large Load Diff

2837
vs2015/freetype/ChangeLog.22 Normal file

File diff suppressed because it is too large Load Diff

7948
vs2015/freetype/ChangeLog.23 Normal file

File diff suppressed because it is too large Load Diff

6360
vs2015/freetype/ChangeLog.24 Normal file

File diff suppressed because it is too large Load Diff

5161
vs2015/freetype/ChangeLog.25 Normal file

File diff suppressed because it is too large Load Diff

5711
vs2015/freetype/ChangeLog.26 Normal file

File diff suppressed because it is too large Load Diff

2106
vs2015/freetype/ChangeLog.27 Normal file

File diff suppressed because it is too large Load Diff

3136
vs2015/freetype/ChangeLog.28 Normal file

File diff suppressed because it is too large Load Diff

222
vs2015/freetype/Jamfile Normal file
View File

@ -0,0 +1,222 @@
# FreeType 2 top Jamfile.
#
# Copyright 2001-2018 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
# and distributed under the terms of the FreeType project license,
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
# indicate that you have read the license and understand and accept it
# fully.
# The HDRMACRO is already defined in FTJam and is used to add
# the content of certain macros to the list of included header
# files.
#
# We can compile FreeType 2 with classic Jam however thanks to
# the following code
#
if ! $(JAM_TOOLSET)
{
rule HDRMACRO
{
# nothing
}
}
# We need to invoke a SubDir rule if the FT2 source directory top is not the
# current directory. This allows us to build FreeType 2 as part of a larger
# project easily.
#
if $(FT2_TOP) != $(DOT)
{
SubDir FT2_TOP ;
}
# The following macros define the include directory, the source directory,
# and the final library name (without library extensions). They can be
# replaced by other definitions when the library is compiled as part of
# a larger project.
#
# Name of FreeType include directory during compilation.
# This is relative to FT2_TOP.
#
FT2_INCLUDE_DIR ?= include ;
# Name of FreeType source directory during compilation.
# This is relative to FT2_TOP.
#
FT2_SRC_DIR ?= src ;
# Name of final library, without extension.
#
FT2_LIB ?= $(LIBPREFIX)freetype ;
# Define FT2_BUILD_INCLUDE to point to your build-specific directory.
# This is prepended to FT2_INCLUDE_DIR. It can be used to specify
# the location of a custom <ft2build.h> which will point to custom
# versions of `ftmodule.h' and `ftoption.h', for example.
#
FT2_BUILD_INCLUDE ?= ;
# The list of modules to compile on any given build of the library.
# By default, this will contain _all_ modules defined in FT2_SRC_DIR.
#
# IMPORTANT: You'll need to change the content of `ftmodule.h' as well
# if you modify this list or provide your own.
#
FT2_COMPONENTS ?= autofit # auto-fitter
base # base component (public APIs)
bdf # BDF font driver
bzip2 # support for bzip2-compressed PCF font
cache # cache sub-system
cff # CFF/CEF font driver
cid # PostScript CID-keyed font driver
gzip # support for gzip-compressed PCF font
lzw # support for LZW-compressed PCF font
pcf # PCF font driver
pfr # PFR/TrueDoc font driver
psaux # common PostScript routines module
pshinter # PostScript hinter module
psnames # PostScript names handling
raster # monochrome rasterizer
sfnt # SFNT-based format support routines
smooth # anti-aliased rasterizer
truetype # TrueType font driver
type1 # PostScript Type 1 font driver
type42 # PostScript Type 42 (embedded TrueType) driver
winfonts # Windows FON/FNT font driver
;
# Don't touch.
#
FT2_INCLUDE = $(FT2_BUILD_INCLUDE)
[ FT2_SubDir $(FT2_INCLUDE_DIR) ] ;
FT2_SRC = [ FT2_SubDir $(FT2_SRC_DIR) ] ;
# Location of API Reference Documentation
#
if $(DOC_DIR)
{
DOC_DIR = $(DOCDIR:T) ;
}
else
{
DOC_DIR = docs/reference ;
}
# Only used by FreeType developers.
#
if $(DEBUG_HINTER)
{
CCFLAGS += -DDEBUG_HINTER ;
}
# We need `include' in the current include path in order to
# compile any part of FreeType 2.
#
HDRS += $(FT2_INCLUDE) ;
# We need to #define FT2_BUILD_LIBRARY so that our sources find the
# internal headers
#
CCFLAGS += -DFT2_BUILD_LIBRARY ;
# Uncomment the following line if you want to build individual source files
# for each FreeType 2 module. This is only useful during development, and
# is better defined as an environment variable anyway!
#
# FT2_MULTI = true ;
# The files `ftheader.h', `internal.h', and `ftserv.h' are used to define
# macros that are later used in #include statements. They need to be parsed
# in order to record these definitions.
#
HDRMACRO [ FT2_SubDir $(FT2_INCLUDE_DIR) freetype config ftheader.h ] ;
HDRMACRO [ FT2_SubDir $(FT2_INCLUDE_DIR) freetype internal internal.h ] ;
HDRMACRO [ FT2_SubDir $(FT2_INCLUDE_DIR) freetype internal ftserv.h ] ;
# Now include the Jamfile in `freetype2/src', used to drive the compilation
# of each FreeType 2 component and/or module.
#
SubInclude FT2_TOP $(FT2_SRC_DIR) ;
# Handle the generation of the `ftexport.sym' file, which contains the list
# of exported symbols. This can be used on Unix by libtool.
#
SubInclude FT2_TOP $(FT2_SRC_DIR) tools ;
rule GenExportSymbols
{
local apinames = apinames$(SUFEXE) ;
local aheader ;
local headers ;
for aheader in [ Glob $(2) : *.h ]
{
switch $(aheader)
{
case */ftmac.h :
if ( $(MAC) || $(OS) = MACOSX ) {
headers += $(aheader) ;
}
case *.h : headers += $(aheader) ;
}
}
LOCATE on $(1) = $(ALL_LOCATE_TARGET) ;
APINAMES on $(1) = apinames$(SUFEXE) ;
Depends $(1) : $(apinames) $(headers) ;
GenExportSymbols1 $(1) : $(headers) ;
Clean clean : $(1) ;
}
actions GenExportSymbols1 bind APINAMES
{
$(APINAMES) $(2) > $(1)
}
GenExportSymbols ftexport.sym : include/freetype ;
# Test files (hinter debugging). Only used by FreeType developers.
#
if $(DEBUG_HINTER)
{
SubInclude FT2_TOP tests ;
}
rule RefDoc
{
Depends $1 : all ;
NotFile $1 ;
Always $1 ;
}
actions RefDoc
{
python $(FT2_SRC)/tools/docmaker/docmaker.py
--prefix=ft2
--title=FreeType-2.9.1
--output=$(DOC_DIR)
$(FT2_INCLUDE)/freetype/*.h
$(FT2_INCLUDE)/freetype/config/*.h
}
RefDoc refdoc ;
# end of top Jamfile

Some files were not shown because too many files have changed in this diff Show More