-
Notifications
You must be signed in to change notification settings - Fork 2.4k
SDL2 port for DOS (DJGPP and VBE 2.0+) #13906
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: SDL2
Are you sure you want to change the base?
Conversation
Timers remain unsupported due to lack of multithreading.
A few other minor style things were tweaked too.
This implementation is probably wrong, but it lays the foundation for doing it better, eventually.
Windows are now always created with the fullscreen flag.
It ain't pretty though!
Key release events do not seem to be visible via _bios_keybrd. This will probably change to use a keyboard interrupt handler.
It doesn't seem to be necessary.
Example toolchain file: ```bash set(CMAKE_SYSTEM_NAME Generic) set(CMAKE_SYSTEM_VERSION 1) if($ENV{DJGPP_PREFIX}) set(DJGPP_PREFIX "$ENV{DJGPP_PREFIX}") else() set(DJGPP_PREFIX "/opt/i386-pc-msdosdjgpp-toolchain") endif() set(CMAKE_C_COMPILER "${DJGPP_PREFIX}/bin/i386-pc-msdosdjgpp-gcc") set(CMAKE_CXX_COMPILER "${DJGPP_PREFIX}/bin/i386-pc-msdosdjgpp-g++") set(CMAKE_STRIP "${DJGPP_PREFIX}/bin/i386-pc-msdosdjgpp-strip") set(PKG_CONFIG_EXECUTABLE "${DJGPP_PREFIX}/bin/i386-pc-msdosdjgpp-pkg-config" CACHE STRING "Path to pkg-config") set(CMAKE_EXE_LINKER_FLAGS_INIT "-static") set(DJGPP_ROOT "${DJGPP_PREFIX}/i386-pc-msdosdjgpp") set(CMAKE_FIND_ROOT_PATH "${DJGPP_ROOT}") set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) link_directories("${DJGPP_ROOT}/lib") include_directories(BEFORE SYSTEM "${DJGPP_ROOT}/sys-include" "${DJGPP_ROOT}/include") ``` Example invocation: ```bash cmake -S. -Bbuild-dos -DCMAKE_TOOLCHAIN_FILE="path/to/djcpp.toolchain.cmake" -DDOS=ON ```
Makes the arrow keys and page up/down work.
Basic TEXTINPUT event firing that assumes US keyboard layout.
This allows S3 trio video cards to work
Calling out via real-mode bridge would kill performance when color cycling. Luckily, VBE 2.0 provides protected mode interface for some of the functions, and setting the palette is one of them. The asm code is based on Allegro 4.2 `vesa_set_palette_range`. Luckily, Allegro license is extremely permissive.
I have a from-scratch DOS port of SDL3 sitting in https://github.com/icculus/SDL/tree/sdl3-dos ... we should compare notes. |
@icculus That's awesome! I've had a look at your branch:
|
palettized 8bpp is still supported in SDL3 |
What a bunch of mad lads 🤠. I know it's not relevant for your Diablo port, but I also had a branch off my VBE work that was for plain old VGA mode 13h. It could serve as a fallback if VBE isn't available for increased compatibility. It keeps its back buffer in RAM (not VGA) though, so it's not as optimal as page-flipping with VBE. I recently migrated the game I'm working on from SDL 2 to 3, so I guess I'll have to check out @icculus's branch now. 👀 |
A similar solution could be used for supporting vba 2.0 or systems with no double buffer modes |
So which one of us is going to be the first to hook the timer interrupt and implement threading? :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I might as well share my own efforts at a DOS port of SDL in case it's useful: https://github.com/ccawley2011/SDL-1.2/tree/dos
set(SDL_SSE OFF) | ||
set(SDL_SSE2 OFF) | ||
set(SDL_SSE3 OFF) | ||
set(SDL_MMX OFF) | ||
set(SDL_3DNOW OFF) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this be detected at runtime for DOS?
|
||
case "$host" in | ||
*-*-msdosdjgpp*) | ||
AC_MSG_NOTICE(skipping unfinished fseeko64 in DJGPP) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this apply when building with CMake as well?
#ifdef HAVE_UCLOCK | ||
return uclock(); | ||
#else | ||
return SDL_GetTicks(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to call clock()
directly here to avoid extra multiplication and division when uclock()
is unavailable?
return -1; | ||
} | ||
|
||
/* Populate color palette for indexed pixel formats. */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be useful to formally standardise the behaviour of paletted framebuffers so that it can be used on other platforms as well (especially ones that have limitations regarding changing the palette).
@@ -152,7 +152,11 @@ int main(int argc, char *argv[]) | |||
RWOP_ERR_QUIT(rwops); | |||
} | |||
if (0 != rwops->read(rwops, test_buf, 1, 1)) { | |||
#ifdef __DJGPP__ | |||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "DJGPP allowed read on write only file\n"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it worthwhile to manually check this in the RWops callback?
movedata(_my_ds(), (uintptr_t)surface->pixels, windata->framebuffer_selector, | ||
framebuffer_offset, surface_size); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How practical would it be to allow direct access to the framebuffer memory by applications to avoid extra memory copying on every frame?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes to the framebuffer show up on the next vertical refresh, you really have to blit it to VRAM in one block at the end.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The port currently requires a mode that supports double buffering, which should avoid that particular issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if a similar buffer could be used on vbe 1.2 where a linear buffer isn't available.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Direct access would require the "Fat DS hack", which has all sorts of issues https://djgpp.mirror.garr.it/v2faq/faq18_6.html
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fwiw, I think the warnings about the Fat DS hack are way overblown.
My SDL3 port is using it, Quake 1 also used it. It's fine, whatever, if you wanted all your bad memory accesses to segfault, don't write DOS programs. :)
Diablo for the most part doesn't require multi threading so it might well be up to you 😅 |
@AJenbo and I took @jayschwa's SDL2 DOS port from a few years ago, rebased it onto the current SDL2, and got palettized output and keyboard fully working.
I understand that the current SDL development focuses on SDL3. I'm posting this PR here for visibility, in case someone might be interested in using it, improving it further, or forward-porting it to SDL3.
Supported
Not supported
Here is a screenshot of DevilutionX running in DOSBox. We also tested on real hardware (hit and miss depending on the graphics card).
The performance is pretty good when using the 640x480 8-bit palettized mode.
Building instructions are here in the "DOS" section: https://github.com/diasurgical/DevilutionX/blob/master/docs/building.md