Git Product home page Git Product logo

Comments (30)

kjliew avatar kjliew commented on September 18, 2024

Cannot reproduce, FIFA98 & 99 both felt normal. FIFAWC98 showed 55~70FPS on wide camera and over 100FPS on close-up camera. FIFA99 was 30 FPS locked most of the time. The animation looked normal, similar to the NHL99 video on my YouTube channel. If you considered that video slow-motion, then that's about it. Both were demo of the games, not full retailed version. I just let the AI play through the match.

So far, I don't see any performance difference between XQuartz/X11 and SDL2. The Apple GLX in XQuartz is more robust at GL context instantiation & more closely mapped to Windows WGL in functions. SDL2 has to play some tricks over there. However, the OpenGL FBO actually works for SDL2 but not for XQuartz. OpenGL FBO is crucial for WineD3D. While WineD3D can still do without it, some games are not being rendered correctly without FBO. Disney Adventure Mickey & Minny Save The Day is one of them.

SDL2 provides fullscreen & immersive gameplay for customized QEMU that supports both borderless and mode-setting fullscreen. It also supports display gamma controls for games that don't look good with sRGB visuals (washed-out colors) but too dark and unpleasant to play on MacBook retina display at high panel brightness.

It is strange that mouse clicks must follow by movement for clicks to register press-release on macOS. It's probably an issue with SDL2 handling inputs on macOS. It is the same for vanilla QEMU with cocoa display, hence irrelevant to any forms of passthrough or 3D acceleration. I don't have any problem with it for games that I need a mouse to play, such as RTS and First-Person shooters. This is not an issue about input lag or latency as what would have plagued PCem ;)

Moving forwards, the focus of development will be on SDL2 for Linux/Wayland & macOS. Hopefully the same code could reach out to every other platforms supported by SDL2.

from qemu-3dfx.

brunocastello avatar brunocastello commented on September 18, 2024

All three games I ran with glide passthrough. Must be some configuration then.

Here's the steps I followed today to compile and build everything:

First I reinstalled SDL2 as normal from brew (the default formulae without anything from X11):
$ brew reinstall sdl2

Which then gave me SDL 2.0.16.

Next I compiled OpenGlide from your qemu-xtra repo. I followed the instructions there, except for one difference, I removed the "--disable-sdl" flag, which made sense for me since this version of qemu-3dfx now is native and requires SDL2?
$ ../openglide/configure && make && make install

Which then gave me the OpenGlide libs required on the right location for me. Now with SDL2 and OpenGlide in place, all I had to do now is QEMU and the wrappers. I used the QEMU version 6.1.0 to build:

$ ../qemu-6.1.0/configure --prefix="/Volumes/Bruninho HD/Virtual Machines.localized/QEMU/qemu-custom" --enable-sdl --disable-cocoa --target-list=i386-softmmu,x86_64-softmmu && make && make install

Which then installed the binaries in a folder I have to differentiante it from homebrew QEMU version. Next, the wrappers. I followed the instructions for the wrappers without any change at all. They all were built correctly.

Then I made new scripts to run Win98 and WinXP, by just copying the ones I had and made only one change in them:
removed export SDL_VIDEODRIVER=x11 line and fired it up.

Both machines booted normally. Apparently no changes. Then I tested first with NFS2SE.
X11 version tops at 51 fps, constantly 50 fps.
SDL2 version tops at 45 fps, constantly 44.9 fps.

Next I tested FIFA 99. Splash screen, menus, they all looked like they were garbled (but I think it's just resolution, my windows desktop resolution is 1024x768 windowed QEMU). Menu buttons were HARD to click and press. Also lagging a bit. I chose to play the default match: Manchester United vs Arsenal. While looking at the terminal, I see the fps being constant in the 50/59 fps, floating a lot. But the game feels slower than X11 version, where it was fluid like a hot knife in butter (just like it was on Intel Mac & VMware Fusion), the SDL2 version was slower than DOSBox-X.

FIFA 98 suffers from the same problem, but worse. Mouse leaves a trail and freezes once in a while. Worst moment is when I need to choose a side to play (default match, England vs Italy). It takes a long time for the icon to move to the side I chose. Next menu (choose venue & weather) also lags a bit. Now Ingame, same feedback as in FIFA 99.

So, this was my first experience with the new version straight out of the compilation and build. Since you say it's normal on your side, I must be missing some configuration.

Both Windows 98 and Windows XP are using the VBEMP driver, latest DirectX 9.0c. I am using -device sb16 (which I had in a real PC, back in late 90's) because when I use AC97 I get messages on terminal about AC97 errors even though I had installed a driver.

EDIT: BTW, in both versions I have two games that would benefit from MESA passthrough - Counter-Strike 1.6 and Grand Prix 3, but they do not seem to make it work. I tried various WineD3D dlls versions.

from qemu-3dfx.

brunocastello avatar brunocastello commented on September 18, 2024

I can make a video recording to show what happens in FIFA, but only after work today (Monday).

from qemu-3dfx.

kjliew avatar kjliew commented on September 18, 2024

The only time that I had the "slow-motion" as you described in FIFA98/99 demo was when I run them on my old Core i3-4010U laptop with QEMU KVM, and the fix for that was to force VSYNC off or limit the frame rate. You can find out how to limit frame rate from my post at VOGONS. To force VSYNC off, create the file from where you start up QEMU.

echo "ContextVsyncOff,1" >> glide.cfg

I don't do this myself. On the M1, XQuartz has no OpenGL VSYNC controls but it is OFF by default. SDL2 supports VSYNC control but I do not experience it with 60 FPS locked, so I guess it may be OFF in my case. You can try it. I also use AC97 and I did have both SB16 & AWE32 back then in the 90's but that didn't make me want to use either on VM. I am not the likes of PCem fans that fueled excitement in re-creation of "what I wish/used to have back then". I am all after the best quality & experience for games, not 640x480 16bpp on a bulky CRT monitor at 15FPS I used to play back then.

To fix mouse leaving trails

echo "LfbHandler,1" >> glide.cfg

Since the M1 cannot virtualize x86, a more accurate LFB model won't hurt performance. In some cases, LfbHandler also has better performance for TCG due to zero-copy. The momentary freeze at certain menu seems normal, I was experiencing the same with the demo.

If you can get the games working in OpenGL or Glide, they are gifts to you. Use it extensively, they are more robust and guarantee to work better. This is also the advantage for Windows folks for the excellent dgVoodoo2 Glide wrappers. Otherwise, you would have to donate to the Project to get QEMU optimized WineD3D libraries. This is a disadvantage for macOS users as they must understand that game support is difficult. I can't do anything when the game worked on Windows/Linux but not macOS. Apple macOS on M1 is also a hardened platform and I don't have Apple ID developer's key to sign prebuilt host binaries, so only guest binaries can be delivered. You can also wait if someone will do it for QEMU or DIY at WineHQ.

Please do not suggest sourcing the games from abandonware website. I would rather have one donate to the Project with game elections and I will buy the game. Otherwise, I will just make use of game demos for games that I don't currently own.

from qemu-3dfx.

brunocastello avatar brunocastello commented on September 18, 2024

OK, I'll try out your tweaks and report back.

You can also wait if someone will do it for QEMU or DIY at WineHQ.

If you can tell me how and what I need to to build my own libraries, I can happily try to build them. I do have an Apple ID Dev account as well; Sometimes I build basic things with Xcode for my iPhone. If I managed to build all this for QEMU at this point, certainly the WineD3D libraries can't be THAT hard for myself to build. I do have some light programming skills but my dad is much more skilled at it than me (+50 yrs of experience while I have only +20).

from qemu-3dfx.

brunocastello avatar brunocastello commented on September 18, 2024

Thanks, your tweaks improved all three games massively. All them are back to the speed levels of X11 version, if not even better. Certainly NFS2SE feels much faster now!

They also fixed some of the graphics problems I had in FIFA 98. Only one more left to fix on FIFA 99:

Screen Shot 2021-11-22 at 2 36 10 AM

This happens both ingame menus and game menus. I think it is related to the resolution. The gameplay graphics (stadium, players...) are unaffected by this, they are perfect still. Since I play games in two scenarios:

  • When I have the MacBook Air 13" in clamshell mode + 40" Samsung 4K TV HDMI;
  • When I am on the road with the Mac

I prefer a widescreen desktop resolution, what would work for me in both scenarios is something like 1280x768 (or 720?), be it windowed or not (in first scenario I prefer windowed, on mac I'd rather go full screen). How would you work around this for the games that aren't widescreen? VMware SVGA3D in VMware Fusion can make them widescreen, so I believe there must be a way (you made it happen with Moto Racer, remember?). If there is not a way, don't worry... not a problem I can play 4:3 original resolution.

BTW, I went to test Counter-Strike 1.6 with MESA and it fired up Xquartz (???) and crashed the VM. I think I forgot to replace opengl32.dll in this game, but I am not sure. I am going to test it again.

If you are interested, how about creating an App/Game DB, like PCGamingWiki, with the configs and tweaks like these you suggested, for the users of each game, so they can tweak it without having to ask your help every time? I could contribute with the games I listed plus some more. This certainly would be good for the community who want to play through QEMU.

Exciting times are ahead for QEMU macOS/Linux gamers! I'll do more testing tomorrow. Might as well just keep a backup of the X11 version on my Time Capsule to be safe.

from qemu-3dfx.

kjliew avatar kjliew commented on September 18, 2024

You have just proven yourself to be skillful at building and compiling. You're right, WineD3D libraries can't be that hard to build with the instructions available at WineHQ. Just pick a version and try it. You will make it. Good Luck!
(...whispering...) PCem S3 ViRGE may support Direct3D on M1, just don't use a Voodoo ;)

The garbled text in menu was likely due to OpenGlide imperfect LFB scaling. This is common when games write to LFB for bitmap text instead of sending textured triangles to draw the text. When scaling is not integer, there will be artifacts. So when a game native renders at 640x480, you will need to scale at 1280x960.

OpenGlide is using primitive OpenGL without shader and buffer objects. This makes scaling quite difficult to be perfect at different aspect ratio, so it will always scale at the same aspect ratio. For Glide, it will mostly in 4:3. It would probably take me several years to ramp up on OpenGL to be able to improve it. The source code is out there and you already know how to build it. You're welcome to take your shot at improving it.

WineD3D is different, it is quite advanced in OpenGL and makes heavy use of shader and buffer objects. The rendering is done with FBO. The final output from FBO can be blit into any display dimension without affecting subsequent pixels operation at the FBO. Hence it is able to scale from 640x480 to anything you have as QEMU desktop resolution at ease. It is indeed quite challenging for MESA GL to support WineD3D. I have done the hard part, now you just need to build the libraries.

from qemu-3dfx.

brunocastello avatar brunocastello commented on September 18, 2024

Well, the instructions are de facto there:
https://wiki.winehq.org/MacOS/Building

Whether they support M1 and Win32s is another story. However, in your videos/screenshots, it’s possible to see that your last used version was 5.0.3?

EDIT: The resolution change in windows 98 did the trick for FIFA 99. Good catch. But I thought that OpenGlide was able to temporarily change it for a game with a cfg setting...

from qemu-3dfx.

kjliew avatar kjliew commented on September 18, 2024

You'd also proven yourself to be skillful at decipher the codes embedded in YouTube videos.
(... whispering ...) Did you see the prophecy of PCem future going down the drain ... ;)

The versions aren't very important. After it was built, it can't be that hard to work upwards or downwards.

from qemu-3dfx.

brunocastello avatar brunocastello commented on September 18, 2024

@kjliew do I need any of these things before I hit make? Not sure what else you're using to compile Wine on macOS apart of what was described on WineHQ documentation. Xquartz/X11 2.8.1 is still installed though.

Screen Shot 2021-11-22 at 6 29 57 PM

EDIT: Nevermind... I think I was wrong. Figured out that what is needed is WineD3D for Windows Guest, not on Mac Host... hmmm...

from qemu-3dfx.

brunocastello avatar brunocastello commented on September 18, 2024

Okay, while I managed to build the WineD3D dlls from several different versions, when I tried them none of them worked for different reasons on each version I tried. This is hard. I don't know which version will work for 98 and/or XP, and I don't know if it needs some kind of patch or not, other than the old trick of renaming ddraw.dll in game folder and patching the game binary to look for it.

I was using his script https://github.com/adolfintel/wined3d4win to build them from winehq.org sources, and a 32 bit Debian 10 VM to build it, because his script kept saying that it needed a 32 bit host to build. (Which IMO is a good idea to use a VM, because I don't want to mess with my M1 homebrew again and fill it up with uneeded libraries) I was pissed when DOSBOX-X required a bunch of libraries for something related to video recording to build it from source.

If only I had a "how to build WineD3D libraries" on anything (be it a Mac or Ubuntu VM) then I could build it somehow.

Still trying it...

from qemu-3dfx.

kjliew avatar kjliew commented on September 18, 2024

There is a YouTube video giving you an idea of how Direct3D games typically work to play them in QEMU Windows guests, from Install to Play, absolutely zero trick. The video is also hinting ... "May the Force be with You" ;)

WineHQ has its forums. You're welcome to gather the voices of QEMU macOS/Linux VM gamers in solidarity to steer WINE developers towards the belief of values in supporting legacy Windows VMs, or to whoever provides WineD3D for Windows. Otherwise, Mystery Sith with Dark Forces evil projects/developers may exert donation out of it.

Perhaps with Virgil 3D now supporting macOS and Windows, anyone can just use Linux VM to play Windows games as simple as installing WINE packages from the distros.

from qemu-3dfx.

brunocastello avatar brunocastello commented on September 18, 2024

Well, I give up. The closest I have been was when I tried one of the very old WineD3D on Windows builds from Federico Dossena, I think it was 1.7.52 or older. Either that or one of the oldest versions from savannah releases.

I prepared GP3 to use it and the result was a crash to desktop. Game didn't even start. This appeared on terminal:

Screen Shot 2021-11-23 at 11 35 13 PM

Interesting that it fired X11 before crashing to desktop, though. Glide games didn't need it.

from qemu-3dfx.

kjliew avatar kjliew commented on September 18, 2024

Very well, I guess your original issues have all been answered. WineD3D issues should be directed to WineHQ or whoever provides them.

When you decided to become a donor supporting this Project, you will have GP3 running on M1, but frankly I cannot guarantee GP3 playability as though the laughing stock of "Max Payne is playable with PCem". GP3 software renderer does look quite good if you don't mind. The M1 family is a great SoC that even seasonal Apple basher like myself was in awe and went out to get one to "experience" it. But when ones need x86 virtualization, Intel/AMD offerings still reign supreme.

I will leave the issue open for couple more days before closing it.

from qemu-3dfx.

kjliew avatar kjliew commented on September 18, 2024

Here's the performance expectation for GP3 with QEMU WinXP VM on M1. There are other issues with WineD3D on Apple OpenGL, for eg. scaling does not work and smog trails aren't rendered correctly. I am not sure about wet track, rain splashing & reflection effects. On Linux KVM, the Ryzen APU checked out everything perfectly on 15W TDP thin & light laptop.

image

from qemu-3dfx.

brunocastello avatar brunocastello commented on September 18, 2024

Better leave it for software mode then. Too bad that on software mode the cockpit has a black part around on all cars (that's a bug of the game itself, not your patch, it has been like that for 20+ years).

Now I just need to find out a way to play Counter-Strike 1.6 (might as well just move to CS:GO native mac version) and FIFA 2000 (this one I believe does not have glide anymore) as well as Grand Prix 4, this one the most important.

from qemu-3dfx.

brunocastello avatar brunocastello commented on September 18, 2024

BTW, I forgot to mention: Win 98 with VBEMP driver lets me play GP3 on software mode just fine. But when I go to Win XP, with VBEMP NT driver, GP3 on software mode just plays the background music with a black screen. I cannot play the game with any other video card that is not the cirrus-vga with the standard cirrus-vga driver provided by Microsoft. I can't understand why. Which leads me to the question:

Yours on software mode runs just fine in XP? Maybe it's the VBEMP NT driver version?

from qemu-3dfx.

kjliew avatar kjliew commented on September 18, 2024

GP3 software 3D renderer also works with WineD3D which emulates DDRAW with OpenGL backend. But you're right, VBEMP gave a black screen, QXL complained about missing 8-bit mode, which makes sense and why Cirrus-VGA works.

from qemu-3dfx.

brunocastello avatar brunocastello commented on September 18, 2024

I did manage once to make the game see the WineD3D Emulation "card" in game settings (???), by just removing the opengl32.dll and adding the WineD3D libraries from fdossena. However, when I ran the calibration, the video was like it had only 16 colors and ran it for a brief moment until it crashed QEMU halfway through (probably due to an unsupported mode).

from qemu-3dfx.

brunocastello avatar brunocastello commented on September 18, 2024

QXL complained about missing 8-bit mode,

Wait. How did you compile your build with QXL ? Mine does not have that. homebrew QEMU and UTM does have, but the build I compiled for your patch does not. Apparently I missed some configure argument...

from qemu-3dfx.

brunocastello avatar brunocastello commented on September 18, 2024

@kjliew hi, I noticed that one of my CDs is Grand Prix Legends and it can run on both glide and d3d. I am going for glide, ofc. I am getting this:

glidept: DLL loaded - glide2x.dll
trace: _grSstQueryBoards@4 called
trace: _grGlideInit@0 called
glidept: 7a8c114-18:38:52 Nov 21 2021 build WRAPFX32
wr2x_trace: _grSstQueryHardware@4
wr2x_trace: _grSstSelect@4
wr2x_trace: _grErrorSetCallback@4
glidept: grSstWinOpen called, fmt 0 org 0 buf 2 aux 0 gLfb 0xde8b9000
wr2x_trace: _grSstWinOpen@28
glidept: LFB mode is MMIO Handlers (slow), Zero-copy
Info: Apple M1 OpenGL 2.1 Metal - 76.1
Info: Pixel Format ABGR8888 D32S8 nAux 0 nSamples 0 0
window 1280x960 (scaled)
glidept: grSstWinClose called
glidept: grSstWinOpen called, fmt 0 org 0 buf 2 aux 0 gLfb 0xde8b9000
glidept: LFB mode is MMIO Handlers (slow), Zero-copy
Info: Apple M1 OpenGL 2.1 Metal - 76.1
Info: Pixel Format ABGR8888 D32S8 nAux 0 nSamples 0 0
window 1280x960 (scaled)
WARN LFB writeMode not 565, 5

And then the game crashes. Any idea? Some sort of glide.cfg trick that is needed?

EDIT: Kinda fixed it with a switch to 16bit in Windows. However GPL cockpit has a garbled mirror in the cars. Well... CrossOver it is then.

from qemu-3dfx.

brunocastello avatar brunocastello commented on September 18, 2024

So when a game native renders at 640x480, you will need to scale at 1280x960.

1280x960 is good enough for a windowed mode. What if I want to play in full screen, which resolution should I set to have both desktop and game with a perfect 4:3 screen? In this question I am thinking about the 13" screen of my MBA when I am not in clamshell mode and using the external 40" screen.

When using the 40" external screen, in full screen mode the games are pinned to the top left of my screen.

It is indeed quite challenging for MESA GL to support WineD3D. I have done the hard part, now you just need to build the libraries.

I did try to build several WineD3D versions, some did build successfully, but none of them worked at all when installed next to the game. I've managed to build some with a VMware Win 10 VM & MSYS2 to build them. I guess that these WineD3D libraries are missing something to work.

from qemu-3dfx.

brunocastello avatar brunocastello commented on September 18, 2024

@kjliew do you know why when I run NFS2SE all of sudden my whole screen is brighter? like, brightness was ramped up to max?

from qemu-3dfx.

kjliew avatar kjliew commented on September 18, 2024

This is how the game is supposed to work with the 3Dfx Glide gamma correction API. On Windows and Linux, OpenGlide maps the Glide gamma correction API to platform specific implementation on Win32 API and XVideoModeExtension. XQuartz does not support XVideoModeExtension. When SDL2 modernization landed for OpenGlide, the gamma correction API was wired up with SDL2 implementation of gamma correction and that worked for macOS. I believe SDL2 on macOS wraps into NSWindow/Carbon gamma correction support. It is similar with Win32 and XVideoModeExtension which is display rather than framebuffer gamma correction. So the whole screen lit up but only you get to see it. For screen recording or real-time game streaming, display gamma correction cannot be shown unless one has done video touch-up or recorded with external camera.

My post at VOGONS gave insight about improvements on OpenGlide in this respect.
https://www.vogons.org/viewtopic.php?f=28&t=83597

Many 3Dfx games were notoriously dark when they were played with Glide wrappers without proper gamma correction support. On real 3Dfx Voodoos hardware, Glide rendering has a 1.7 default gamma correction. If you prefer only the game to lit up and not the entire screen, then you can use sRGB visual, which comes with fixed 2.2 gamma correction, but not all games will look good at such high gamma correction.

Many dislike the way display gamma correction works at whole screen but it is simple just to wire up with the respective platform API when one is available. A more sophisticated approach is to use GPU shader-based gamma correction. IMHO, it is better to have it than without. And with SDL2 modernization for OpenGlide, full-screen, immersive game play was made possible on macOS so it does not matter anymore for display gamma correction to apply for the entire screen.

from qemu-3dfx.

brunocastello avatar brunocastello commented on September 18, 2024

OK, I get it.

@kjliew btw, am I correct to think that to add SPICE support, I just need to get spice-protocol from brew and recompile it with the flag --enable-spice, so I can use the guest tools (notably the QXL video driver) in Windows XP?

from qemu-3dfx.

brunocastello avatar brunocastello commented on September 18, 2024

GP3 software 3D renderer also works with WineD3D which emulates DDRAW with OpenGL backend. But you're right, VBEMP gave a black screen, QXL complained about missing 8-bit mode, which makes sense and why Cirrus-VGA works.

Hi @kjliew , have you found a fix for that on XP? Maybe an older version of VBEMP NT could help? There aren't many (or any) drivers for cirrus-vga that could give me the desired resolution and let me play GP3 on it.

I have also tried with hardware accel set to none in Windows XP, no luck. But I had to set it to none before because some crashes killed the VM when I was doing simple things like moving a window around the desktop on Windows. Weird. I still find it funny that it works for vmware-svga + VBEMP 9x on Windows 98, but not on XP with vmware-svga + VBEMP NT. There must be some difference.

EDIT: Fixed a typo at the end.

from qemu-3dfx.

brunocastello avatar brunocastello commented on September 18, 2024

@kjliew I have another question, how did you install or built MESA on macOS? I just installed the one from homebrew.

from qemu-3dfx.

brunocastello avatar brunocastello commented on September 18, 2024

Why it calls Xquartz app on my Mac and crashes QEMU back to the terminal whenever I try to run a game with any WineD3D libraries? I tried Counter-Strike with WineD3D 6.0.2 and Grand Prix 3 with WineD3D 1.9.7. The first game just locks up while loading the map, and GP3 crashes QEMU when XQuartz is fired up.

from qemu-3dfx.

sofakng avatar sofakng commented on September 18, 2024

Why it calls Xquartz app on my Mac and crashes QEMU back to the terminal whenever I try to run a game with any WineD3D libraries? I tried Counter-Strike with WineD3D 6.0.2 and Grand Prix 3 with WineD3D 1.9.7. The first game just locks up while loading the map, and GP3 crashes QEMU when XQuartz is fired up.

Sorry to bring up an old issue but I'm having the same problem...

from qemu-3dfx.

kjliew avatar kjliew commented on September 18, 2024

Master Yoda from another Parallel universe had telepathically taught the young Padawan the art of devouring the Sith's ⚡️FORCE LIGHTNING⚡️

from qemu-3dfx.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.