From 6a129713c50b345a2052187547927f3a0ed964ae Mon Sep 17 00:00:00 2001 From: Marlon Beijer Date: Sun, 2 Jan 2022 13:12:15 +0100 Subject: [PATCH] AmigaOS4 cleanup (#2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add a hint for D3D9Ex to avoid having to choose at compile-time * Use MSVC _byteswap intrinsics for SDL byteswapping functions This generates bswap on x86/x64 and rev on ARM * Fixed bug 5440 - MacCatalyst build failures C.W. Betts I tested building commit http://hg.libsdl.org/SDL/rev/55cdb379e866 on Mac Catalyst and found some issues: * MTLFeatureSet_iOS_* enums aren't available under Mac Catalyst. * OpenGL ES is unavailable under Mac Catalyst. * Some Metal features are available under Catalyst but not iOS, such as displaySyncEnabled. * Set Metal as the default renderer on Mac Catalyst Attaching a patch that will make SDL2 build for Mac Catalyst. * Use specific acquire and release variants of InterlockedExchange on ARM _InterlockedExchange_rel() is required for correctness on ARM because the _ReadWriteBarrier() macro is only a compiler memory barrier, not a hardware memory barrier. Due to ARM's relaxed memory model, this means the '*lock = 0' write may be observed before the operations inside the lock, causing possible corruption of data protected by the lock. _InterlockedExchange_acq() is more efficient on ARM because it avoids an expensive full memory barrier that _InterlockedExchange() does. * Implement SDL_MostSignificantBitIndex32 using MSVC intrinsics * consistently use TEXT() macro with LoadLibrary() and GetModuleHandle() cf. bug #5435. * SDL_wasapi_win32.c (WASAPI_PlatformThreadInit): use L instead of TEXT() because AvSetMmThreadCharacteristicsW specifically accepts WCHAR* input cf. bug #5435. * SDL_dinputjoystick.c (IsXInputDevice): adjust to be ANSI/UNICODE-agnostic cf. bug #5435. * RAWINPUT_InitWindowsGamingInput: change pNamespace from LPTSTR to PCWSTR because WindowsCreateStringReference specifically accepts const WCHAR * - WGI_JoystickInit(): ditto. cf. bug #5435. * SDL_windowswindow.c (SDL_HelperWindowCreate): adjust for ANSI/UNICODE: change SDL_HelperWindowClassName and SDL_HelperWindowName from WCHAR * to be const TCHAR* cf. bug #5435. * SDL_windowsjoystick.c (SDL_CreateDeviceNotification): use L, not TEXT() cf. bug #5435. * simplify Watcom implementation of SDL_MostSignificantBitIndex32() * move SDL_tcsstr definition to core/windows/SDL_windows.h * make ANSI/UNICODE versions of WIN??UTF8 macros individually available. * use WIN_StringToUTF8W macro instead of WIN_StringToUTF8, where needed: i.e. where the string is known guaranteed to be WCHAR*, in: - SDL_dinputjoystick.c (WIN_IsXInputDevice): VARIANT->var is BSTR (WCHAR*) - SDL_rawinputjoystick.c (RAWINPUT_AddDevice): string is WCHAR* - SDL_windows_gaming_input.c (IEventHandler_CRawGameControllerVtbl_InvokeAdded): string is WCHAR* There should be more of these.. * SDL_windows_main.c: use new WIN_StringToUTF8W macro * Valve contributed code is under the Zlib license * Allow setting the player index to -1, which turns off the player LED for PS5 controllers * Fixed detection of the Wooting Two keyboard, which shows up as an Xbox 360 controller * Add SDL_UpdateNVTexture() to update NV12/21 Texture (bug #5430) for renderer software, opengl, and opengles2 * Fixed invalid read in yuv_rgb_sse() (see bug #5430) * Add SDL_UpdateNVTexture for d3d11 (bug #5430) (not tested) * Fix compilation (implicit declaration of function) (see bug #5430) * Fix compilation on Window10 (see bug #5430) * Add SDL_UpdateNVTexture for META (bug #5430) (not tested) * Fix unused variable warning on METAL (see bug #5430) * wmmsg.h: constified wmtab * ran gendynapi.pl after SDL_UpdateNVTexture addition * use WIN_StringToUTF8W instead of WIN_StringToUTF8 where needed (#2) cf. bug #5435. - SDL_wasapi_win32.c (GetWasapiDeviceName): pwszVal is WCHAR* - windows/SDL_sysfilesystem.c (SDL_GetBasePath, SDL_GetPrefPath) - windows/SDL_sysurl.c (SDL_SYS_OpenURL): wurl is WCHAR* - SDL_windowssensor.c (ConnectSensor): bstr_name is WCHAR* - windows/SDL_systhread.c (SDL_SYS_SetupThread): strw is WCHAR* * video/windows: ANSI/UNICODE updates (cf. bug 5435): - explicitly use UNICODE versions of DrawText, EnumDisplaySettings, EnumDisplayDevices, and CreateDC: the underlying structures have WCHAR strings. - change WIN_UpdateDisplayMode and WIN_GetDisplayMode() to accept LPCWSTR instead of LPCTSTR for the same reason. - change WIN_StringToUTF8 and WIN_UTF8ToString to the explicit 'W' versions where appropriate. * Update config.guess and config.sub from mainstream. Recognizes riscv32be and riscv64be. * Add more SDL_HAVE_YUV defines * Fix D3D11 UpdateNVTexture (bug #5430) * Fix software UpdateNVTexture non fullscreen (bug #5430) * Fix D3D11 UpdateTextureNV in non fullscreen (bug #5430) * [KMS/DRM] Rewrite KMSDRM_LEGACY backend to accomodate Vulkan compatibility. Fix several bugs on that backend. * fix build after commit 26e76e851774 * [KMS/DRM] Add Vulkan suport to the KMSDRM_LEGACY backend.Minor text spacing tweaks for better readability. Comment out unused function. * [KMS/DRM] Add the missing files for Vulkan support to the KMSDRM_LEGACY backend, had forgotted to do -hg add-. * [KMS/DRM] Correct drmModeSetCursor() dimensions. * update config.guess and config.sub from mainstream. * [KMS/DRM] Don't use primary plane for scaling because that's unsupported on most LEGACY-only HW. * Fixed building when SDL_LIBUSB_DYNAMIC is defined * Fixed bug 5449 - SDL_DROPFILE update mouse location of drop in Cocoa Dominik Reichardt Exult (http://exult.info) has an editor app that uses GTK+2. Up to now we were using X's drag'n'drop to allow dropping of assets from the editor onto Exult. There is now an experimental branch that makes use of SDL_DROPFILE. That works under X, dropping in Exult's SDL2 window puts the asset right at the spot you dropped at. On macOS with native Exult and Quartz GTK+2 this doesn't work, the location of the drop is where the mouse was last tracked before you left the window (usually one of the edges, unless you tabbed out). All we tried out pointed to the fact that the location update needs to be done by the dropfile event in SDL2, not by our own (which always only worked after the Exult window getting focus). This patch adds this to SDL_cocoawindow.m and it works perfectly, passing the correct coordinates to our code (SDL_GetMouseState()). * Use Clang/GCC builtins for SDL byteswapping functions __builtin_bswap32/64 were introduced in GCC 4.3. __builtin_bswap16 was not available on x86 until GCC 4.8 due to a bug. __builtin_bswap32/64 were introduced in Clang 2.6. __builtin_bswap16 was introduced in Clang 3.2. * Disabled Bluetooth if BLE is not supported BluetoothManager is supported for Android API 18+. On older versions, skip Bluetooth instead of crashing. * [KMS/DRM] Prevent creating another default cursor everytime a window is created. Other fixes and cleanups. * [KMS/DRM] Fix cpmpilation warnings. Thanks to Ozkan Sezer for pointing this out! * [KMS/DRM] Small readability changes. * Fixed joysticks generating SDL mouse events * [KMS/DRM] Go back to the LEGACY interface only because using planes breaks compatibility with HW, so no advantage on using ATOMIC. * Fixed Xbox One Series X share button incorrectly triggering on newer firmware * Fixed bug 5080 - SDL_netbsdaudio: Always use the device's preferred frequency Nia Alarie The NetBSD kernel's audio resampling code is much simpler and lower quality than libsamplerate. Presumably, if SDL always performs I/O on the audio device in its native frequency, we can avoid resampling audio in the kernel and let SDL do it with libsamplerate instead. * regenerated configure * fixed permissions of xcode project file * KMSDRM_LEGACY is no longer legacy * [KMS/DRM] Fix vkQuake3 in OpenGL mode. * acinclude/libtool.m4: Apply macos11 patch from libtool bug #44605 https://debbugs.gnu.org/cgi/bugreport.cgi?bug=44605 https://github.com/macports/macports-ports/blob/master/devel/libtool/files/dynamic_lookup-11.patch ( Also see https://debbugs.gnu.org/cgi/bugreport.cgi?bug=44684 ) This also implicitly covers the macos10.10+ support patch from libtool mainstream which has been in since libtool-v2.4.3, i.e.: http://git.savannah.gnu.org/gitweb/?p=libtool.git;a=commit;h=e145288b059e14ab7e58fc6a304e82d9dad282a6 * [KMS/DRM] Cleanup remainings from plane/scaling usage. * SDL_UpdateNVTexture: for D3D11, same notation as SDL_UpdateTexture (bug #5430) * Fixed bug 5465 - Invalid memcpy inside SDL_GestureDelTouch (Thanks dmikushin and Yuki Okumura) * SDL_UpdateNVTexture: fixed pitch/bpp for GLES2 (bug #5430) * [KMS/DRM] Fix fullscreen to windowed transition. Fix aspect ratio correction without using planes. * [KMS/DRM] Move surface size info to window driverdata, for coherency. * [KMS/DRM] Unused code cleaning. * Gyro and Accel sensor support for Switch Pro Controller. Note that axes are changed to match the axes we're using with PlayStation controllers, since users will appreciate consistent behaviour across devices. * [KMS/DRM] Don't ask SDL to scale image when in Vulkan mode. * [KMS/DRM] Refactor KMSDR_CreateSurface to group all non-Vulkan stuff in a block. * opengl: More work on making line drawing match software renderer. * [KMS/DRM] Add warning comentary to avoid future experiments with scaling. * [KMS/DRM] Enable async pageflips. * testgamecontroller: log which controller the event came from * Only select the gamepad interfaces on the Xbox 360 wireless adapter * Don't blink the Xbox 360 LED when setting the player slot, it's probably already been set by a driver * [KMS/DRM] Refactor, improve and re-comment async pageflips code. * [KMS/DRM] Remove unused header. * [KMS/DRM] Adjust come return values. Improve comments. * Fixed bug 5461 - Add rewritten WSCONS driver for OpenBSD wahil1976 This patch adds a written-from-scratch WSCONS driver for OpenBSD. It does not have hardcoded keymaps, and it features mouse support when wsmux is available. For this to work, it needs access to the /dev/wskbd* devices which are not available to non-root users by default. Access to those can be granted by changing /etc/fbtab to give the logging user the ownership of those devices. * Fixed bug 5462 - debug trap update/fix of assembly for Apple devices David Carlier updating preprocessor constant and proposing 32 bits variant. * Fixed bug 5451 - Can't create EGLSurface in Wayland from SDLWindow (no EGLNativeWindow pointer) sashikknox In some cases, need create EGLWindow with SDLWindow. In X11 i can get pointer to NativeWindow from **struct SDL_SysWMinfo wmInfo** ```C++ struct SDL_SysWMinfo wmInfo; SDL_GetWindowWMInfo(ptSDLWindow, &wmInfo) #if defined(__unix__) && defined(SDL_VIDEO_DRIVER_X11) nativeWindow=(EGLNativeWindowType)wmInfo.info.x11.window; nativeDisplay=(EGLNativeDisplayType)wmInfo.info.x11.display; #endif ``` than i can create EGLSurface ``` eglCreateWindowSurface(nativeDisplay, EGL_CONFIG, nativeWindow, SURFACE_ATTRIBUTES); ``` in Wayland i can do it with same way, just need pointer to **EGLWindow**, we already have pointer to **wl_display** from **SDL_sysWMInfo**, need add to **wl** struct in SDL_SysWMInfo another pointer to **struct wl_egl_window *egl_window;**. And in wayland backend, in function **Wayland_GetWindowWMInfo** return pointer to **egl_window** from **SDL_WindowData** Now i use patched statically built SDL2 in port of Quake 2 GLES2 for SailfishOS (it use QtWayland): link to SDL2 commit and changed string for patch: - https://github.com/savegame/lp-public/commit/6858a618cd179b766fe3cab36055f07cb03ad0ea - https://github.com/savegame/lp-public/blob/b1e29e87b9d15780e47f04918b329ac15554fc69/SDL2/src/video/wayland/SDL_waylandwindow.c#L463 link to use in Quake2 port: 1. here i get pointer to EGLNativeWindowType: https://github.com/savegame/lp-public/blob/6d94fedb1b720da24999ae6286a1809cd3d55ff5/Engine/Sources/Compatibility/OpenGLES/EGLWrapper.c#L319 2. then use it for create EGLSurface: https://github.com/savegame/lp-public/blob/6d94fedb1b720da24999ae6286a1809cd3d55ff5/Engine/Sources/Compatibility/OpenGLES/EGLWrapper.c#L391 * Fixed bug 5463 - generated Wayland interfaces are included in the library's ABI Simon McVittie In versions since 1.15, the `code` mode is a deprecated alias for `public-code`, which emits symbols with default visibility, overriding SDL's -fvisibility=hidden option. Use the `private-code` mode instead. This emits symbols with hidden visibility, so they do not affect the ABI of libSDL. See also: https://bugreports.qt.io/browse/QTBUG-73099, https://lists.freedesktop.org/archives/wayland-devel/2018-February/037097.html * Fixed bug 5287 - Support building for UWP with CMake Jan Niklas Hasse Actually the SDL2-static target works, if I set SDL_SENSOR to OFF. Awesome! See this patch: https://github.com/microsoft/vcpkg/blob/master/ports/sdl2/0003-sdl2-fix-uwp-build.patch * Fixed bug 5195 - Replugging in “mixed” controller types crashes on macOS RustyM This is related to Bug 5034, but crashes under a somewhat different condition. In the latest tip (changeset 13914) or with the SDL 2.0.12 source + David’s 5034 patch, unplugging and then replugging in certain controller types on macOS will crash. A mix of new controllers like Switch Pro, PS4 and Xbox One all work without issue. But if a controller without a rumble function, like many SNES retro USB gamepads, is mixed with a PS4 or Switch Pro controller it will crash. File: joystick/darwin/SDL_sysjoystick.c Function: static recDevice *FreeDevice(recDevice *removeDevice) On line 159: while (device->pNext != removeDevice) { Causes: Thread 1: EXC_BAD_ACCESS (code=1, address=0x188) This can be reproduced in testgamecontroller" by starting the test program with both a “retro” controller plugged in and a “modern rumble” controller (Switch Pro/PS4). This may crash on launch, but it depends on which controller ends up as device 0. If it doesn’t crash, unplug the “modern rumble” controller and plug it back in. Some of the "retro" controllers I’ve seen this crash with: - iBuffalo SNES Controller - 8Bitdo SN30 Gamepad (in MacOS mode) - Retrolink NES Controller - HuiJia SNES Controller Adaptor The issue appears macOS specific. Seen on 10.12.6 and 10.14.6. Not seen on Windows 10. The while loop in FreeDevice() assumes that every device is not NULL. recDevice *device = gpDeviceList; while (device->pNext != removeDevice) { device = device->pNext; } device->pNext = pDeviceNext; So maybe we should check for NULL here? Or instead prevent adding NULL devices to the list in the first place? Checking device for NULL before entering the loop appears to work. recDevice *device = gpDeviceList; if (!device) { while (device->pNext != removeDevice) { device = device->pNext; } } device->pNext = pDeviceNext; * Fixed bug 5445 - Incorrect Switch Pro Controller face buttons when SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS disabled jibb I'm testing with DualShock 4, DualSense, Switch Pro Controller, and PowerA Switch Controller. I'm using the standard mapping file from here: https://raw.github.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt With SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS turned off (set to "0") I expect the button positions to be the same on all devices, based on Xbox controller button naming (eg SDL_GameControllerGetButton(g, SDL_CONTROLLER_BUTTON_Y) gives me whether the North face button is pressed). However, the Switch Pro Controller layout is wrong (matching labels rather than positions, so X and Y are swapped and A and B are swapped). And with the PowerA controller the East and West buttons are correct, but the North and South buttons are swapped instead. Mathias Kaerlev Also seeing this on 2.0.14. This is most likely a regression, since we weren't seeing this on an earlier SDL version. I suspect it might be caused by this commit: https://github.com/spurious/SDL-mirror/commit/a569b211881c6d4c73f3f1019e9f66e754ca546b#diff-da9344d94c66b8c702a45e7649f412039f08bba83bd82de33f5c80ea9c8c39d5 It seems like both the HIDAPI driver and SDL_gamecontroller.c will try to swap the buttons if the hint is set to 0, causing the button remap to cancel out. * Make sure the HIDAPI device is locked when closing it, in case there is rumble pending that didn't complete * Always lock the HIDAPI device when closing, in case rumble is pending * Added HIDAPI rumble debug info * Fixed rumble reset failing for Switch Pro controllers in USB mode * Phantom Nintendo Switch Pro Controller initialization problem * Get the serial number for the Nintendo Switch Pro controller * Fixed build * SDL_hidapi_switch.c: fix build with older compilers * [KMS/DRM] Small fix to KMSDRM_Waitpageflip(). More comments on how it works. * Fixed the screenshot button mapping on third party Bluetooth Nintendo Switch Pro controllers * fix build with --disable-directx * Fixed bug 5473 - Add WSCONS support for NetBSD wahil1976 This patch adds WSCONS support for NetBSD. * [KMS/DRM] Fix for bug #5470: ratio correction for fullscreen windows with no matching resolution. Correct bracket position in else statements so they follow the coding style. * [KMS/DRM] Fix for bug #5468: corruption on dynamic cursor changing caused by wrong buffer size. * Add basic testgles2_sdf program to demonstrate sign distance field with opengles2 * Fix declarations after statement * fix AC_CHECK_HEADER for libusb.h * hidapi/libusb/hid.c: whitespace tidy-up. * SDL_virtualjoystick.c: remove wrong #endif comment. * [KMS/DRM] Revert unaproved fix for bug #5465. * hidapi/libusb/hid.c: fix race condition on device close (bug #5484) From hidapi mainstream git: https://github.com/libusb/hidapi/issues/142 https://github.com/libusb/hidapi/commit/d2c3a9862eefe2d3f4db0f00c0238277bfb4e44b Read callback may fire itself on its own even after its been requested to stop and exactly before the calling code waits for its completion in indefinite loop. Explicitly preventing re-fireing the submission loop fixes the issue. * Use PS4 rumble hint as the default for the PS5 rumble hint Existing SDL applications may not know about the need to set a specific hint to enable rumble on PS5 controllers, even though they may already set the equivalent SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE hint for PS4 controller rumble support. Rather than requiring those developers update their apps, let's use the SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE value as an indication of the behavior they are expected for all PlayStation controllers. * Implement keyboard grab support for Wayland Use zwp_keyboard_shortcuts_inhibit_manager_v1 to allow SDL applications to capture system keyboard shortcuts like Alt+Tab when keyboard grab is enabled via SDL_HINT_GRAB_KEYBOARD. * Don't add paddle mappings for the Xbox One Elite Series 1 controller, since they can't be unmapped and read directly on that controller. * Hint SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS added so we can recognise a Joy-Con as half a Pro Controller, so we can read its analog input and read its sensors just like we do a Pro Controller. * renamed my_gradd.h to SDL_gradd.h * Implement support for minimizing windows on Wayland This required a bit of extra code to deal with the transition from minimized back to fullscreen * Fixed initializing the Nyko and EVORETRO GameCube adaptors This requires root on most Linux distributions, as we have to directly send USB messages to the devices to enable input reports. * Make sure we only do GameCube adapter initialization if we were able to load libusb * Improve reliability of cursor hiding on GNOME Wayland Hiding the cursor doesn't appear to work reliably on GNOME when another window steals mouse focus right as we call SDL_ShowCursor(SDL_DISABLE). This can happen when the keyboard shortcut inhibition permission prompt appears in response to a call to SDL_SetRelativeMouseMode() with SDL_HINT_GRAB_KEYBOARD=1. The result is that the default cursor is stuck locked in position and visible on screen indefinitely. By redrawing the cursor on pointer focus enter, the cursor now disappears upon the first mouse motion event. It's not perfect but it's way better than the current behavior. * Fixed build on Android and iOS * Fixed build * hidapi.h: adjust so that it gives a smaller diff against mainstream * old os2 analogue joystick code ported from SDL-1.2. disabled by default, build-tested only. * SDL_dinputjoystick.c: fixes to dfDIJoystick2[] array from Wine git. Fix V/A/FSlider dwOfs values in c_dfDIJoystick2 https://source.winehq.org/git/wine.git/commitdiff/af2f4194263702a946c65d255580176ee50b5914 Add missing ASPECT flags for c_dfDIJoystick2 https://source.winehq.org/git/wine.git/commitdiff/e2e100272ffede3c720da7bbd11b53ac0bcee8eb Closes bug #5474. * ControllerList: fix typo * Added support for the EVORETRO GameCube Adapter in PC mode * fix permissions of config.guess and config.sub * minor autotools build system updates. * Implement support for inhibiting the screensaver on Wayland We support both the org.freedesktop.ScreenSaver D-Bus API (same as the X11 backend) and the Wayland idle_inhibit_unstable_v1 protocol. Some Wayland compositors only support one or the other, so we need both to for broad compatibility. * Fix continuous scrolling speed on Wayland Wayland compositors seem to have standardized on 10 units per "wheel tick" for continuous scroll events, so we need to convert these axis values to ticks by dividing by 10 before reporting them in SDL_MOUSEWHEEL events. * added SDL_JOYSTICK_OS2 to SDL_config.h.in and SDL_config.h.cmake * renamed SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H to SDL_HAVE_MACHINE_JOYSTICK_H * os2audio: changed backend name from MMOS2 to DART (like SDL-1.2) * move outdated winmm and psp joystick codes to struct _SDL_JoystickDriver build-tested only. (bug #5472.) * Implement keyboard grab support for Windows This is implemented via a low-level keyboard hook. Unfortunately, this is rather invasive, but it's how Microsoft recommends that it be done [0]. We want to do as little as possible in the hook, so we only intercept a few crucial modifier keys there, while leaving other keys to the normal event processing flow. We will only install this hook if SDL_HINT_GRAB_KEYBOARD=1, which is not the default. This will reduce any compatibility concerns to just the SDL applications that explicitly ask for this behavior. We also remove the hook when the grab is terminated to ensure that we're not unnecessarily staying involved in key event processing when it's not required anymore. [0]: https://docs.microsoft.com/en-us/windows/win32/dxtecharts/disabling-shortcut-keys-in-games * Fixed bug 5467 - SDL sys timer Mac OS update proposal David Carlier Change of api from 2016 which reduce code complexity a bit. * Fixed bug 5466 - Add haptic support for Stadia Controller Dimitriy Ryazantcev Consider adding support for Stadia Controller haptics. Here is example code how to deal with it: https://github.com/chromium/chromium/blob/99314be8152e688bafbbf9a615536bdbb289ea87/device/gamepad/hid_haptic_gamepad.cc#L45 * Minor cleanup * waylandtouch: Don't export interface structs These are explicitly written in C code rather than generated at build time, so they weren't affected by changing how we invoke wayland-scanner. Signed-off-by: Simon McVittie * Added Stadia controller source file to Visual Studio and Xcode projects * Implement Wayland_SetWindowResizable * [KMS/DRM] Bugfix for #5489: Non-FULLSCREEN windows incorrecty use videomode changing to look fullscreen. * fix build failure due to -Werror=declaration-after-statement (bug #5500) * minor clean-up in SDL_os2audio.c * CMakeLists.txt: fix check_symbol_exists() for clock_gettime_nsec_np * better check for clock_gettime_nsec_np() -- cf. bug #5467. * GLES2 SDL_Renderer: remove old ZUNE_HD defines and simplify shader cache * Refactor keyboard grab to be managed by the video core This gives us flexibility to add others hints to control keyboard grab behavior without having to touch all of the backends. It also allows us to possibly expose keyboard grab separately from mouse grab for applications that want to manage those independently. * Fix grabbing Alt+Tab and Alt+Esc on Windows 7 * wayland: cancel key repeat when keyboard focus is lost SDL_SetKeyboardFocus(NULL) will lift any keys still pressed when keyboard focus leaves the window, but then key repeat comes behind our backs and presses the key down again. This results in an infinite stream of SDL_KEYDOWN events when focus leaves the window with a key down (particularly noticeable with Alt+Tab). * Rename SetWindowGrab() to SetWindowMouseGrab() * Removed non-functional window grab implementations * Fixed bug 5493 - Hint to let the user opt out of having Switch controllers' Home button lit when opened jibb New hint to let the user opt out of having Switch controllers' Home button lit when opened. This is more consistent with the Switch itself (which doesn't light the button normally) and may be preferred by users who may disconnect their controller without letting the application close it. I think this warrants a Switch-specific hint because the default behaviour is unusual (inconsistent with using a Switch controller on a Switch itself or with some other programs on PC), and because of that it's distinct from other lights (the player number on Switch controllers and the player colour on PlayStation controllers). * Fixed bug 5481 - iOS-specific main sources not used for CMake build. Aaron Barany The CMake build for SDL doesn't set SDLMAIN_SOURCES on iOS to the sources in src/main/ios. As a result, SDL fails to initialize since it falls back to the dummy main. Adding the line file(GLOB SDLMAIN_SOURCES ${SDL2_SOURCE_DIR}/src/main/uikit/*.c) fixes the issue. * Fixed bug 5497 - SDL_COMPOSE_ERROR is wrong UMU #define SDL_COMPOSE_ERROR(str) SDL_STRINGIFY_ARG(__FUNCTION__) ", " str I think SDL_STRINGIFY_ARG should be removed. #define SDL_COMPOSE_ERROR(str) __FUNCTION__ ", " str (verified with Visual Studio 2019) * DirectFB: Split input grab handling into keyboard and mouse parts The grabbed_window field is superfluous now since SDL added the SDL_GetGrabbedWindow() function, so it can be removed. DirectFB_SetWindowMouseGrab() is also simplified because SDL handles ungrabbing any previously grabbed window prior to calling SetWindowMouseGrab() now. Compile-tested only. * SDL_SoftStretch: re-enable USE_ASM_STRETCH path for gcc >= 4.6 * Expose separate keyboard and mouse grab support This adds SDL_SetWindowKeyboardGrab(), SDL_GetWindowKeyboardGrab(), SDL_SetWindowMouseGrab(), SDL_GetWindowMouseGrab(), and new SDL_WINDOW_KEYBOARD_GRABBED flag. It also updates the test harness to exercise this functionality and makes a minor fix to X11 that I missed in https://hg.libsdl.org/SDL/rev/02a2d609369b To fit in with this new support, SDL_WINDOW_INPUT_CAPTURE has been renamed to SDL_WINDOW_MOUSE_CAPTURE with the old name remaining as an alias for backwards compatibility with older code. * SDL_SoftStretch: disable asm path if mprotect isn't available (see bug #3816) * SDL_UpdateTexture: intersect update rect with texture dimension - fix crash with software renderer - fix non texture update with opengl/gles2 * SDL_Update{YUV,NV}Texture: also intersect rect with texture dimension * Fixed building with mingw64 * Fixed bug 3816 - asm code in video/SDL_stretch.c Ozkan Sezer - adds MSVC __declspec(align(x)) support, - disables asm if PAGE_ALIGNED no macro is defined, - still disables asm for gcc < 4.6, need more info, - drops Watcom support. * The Sharkoon Skiller SGH2 headset hangs in DirectInput enumeration, so avoid it here just in case. See bug 5485 for details. * Fixed compile warning * Added explicit case from Uint8 to int before subtracting offset * Fixed bug 3816 - asm code in video/SDL_stretch.c Sylvain I propose this new version for SDL_stretch.c that drops mprotect and asm Code is similar to the StretchLinear, but the steps computation are kept similar to the nearest. so that: - it's pixel perfect with nearest - as fast as asm I think - no asm, nor mprotect - benefit for all archicture * SDL_LowerSoftStretchLinear: assign result from scale_mat() to ret. otherwise it would always return -1 when SSE and NEON instrinsics are absent. * X11: Ungrab the keyboard when the mouse leaves the window GNOME Mutter requires keyboard grab for certain important functionality like window resizing, interaction with the application context menu, and opening the Activites view. To allow Mutter to grab the keyboard as needed, we'll ungrab when the mouse leaves our window. To be safe, we'll do this for all WMs since forks of Mutter and Matacity (and possibly others) may have the same behavior, and we don't want to have to keep track of those. * Added WIN_IsWindows8OrGreater() for internal use * Fixed PS4 controllers over Bluetooth on Windows 7 * Fixed build warning * Fixed compiler warnings * SDL_stretch: remove un-used vars, same notation as blit functions * Fixed bug 5510 - simplify the scaling functions * Fixed bug 5510 - simplify the scaling functions blit auto (generated file) * config.guess and config.sub updates from mainstream * SDL_config_os2.h: remove some duplicated lines. * Note that the Logitech G29 (PS4) is a racing wheel * Make sure we don't create a game controller mapping for HID devices that aren't supported by HIDAPI * Add checks for maximun scaling size (see bug #5510) * Remove old YUV fixme * Properly handle keys already down when the hook is installed For keys that are already down when we install the keyboard hook, we need to allow the WM_KEYUP/WM_SYSKEYUP message to be processed normally. This ensures that other applications see the key up, which prevents the key from being stuck down from the perspective of other apps when our grab is released. * [KMS/DRM] Patch for bug #5513. KMSDRM backend can now manage and use several displays. * [KMS/DRM] Remove unused KMSDRM_SetWindowGrab prototype in header file. * Remove checks on destination scaling size (see bug #5510) * added --enable-xinput switch for windows builds * Fixed crash if the GameCube controller hasn't been opened yet * [KMS/DRM] Correct small omission on bugfix #5513: y-coord correction has to be done on WarpMouseGlobal, too. * Revert checks on destination scaling size (see bug #5510) * Add default handler for Alt+Tab while keyboard grab is enabled By default, we will minimize the window when we receive Alt+Tab with a full-screen keyboard grabbed window to allow the user to escape the full-screen application. Some applications like remote desktop clients may want to handle Alt+Tab themselves, so provide an opt-out via SDL_HINT_ALLOW_ALT_TAB_WHILE_GRABBED=0. * [KMS/DRM] Fix for bug #5518: only do async pageflips when hardware supports them. * [KMS/DRM] Merge patch for bug 5522#: Implement KMSDRM_GetWindowWMInfo(). * wayland: Fix transform and scale handling when setting display mode * cmake: enable AddressSanitizer in Debug builds * free the 'data_device_manager' * free 'outputs' in 'Wayland_DestroyWindow' * Don't enable address sanitize flags without checking compiler first * Fixed bug 5524 - Pass NSString to NSLog() Hiroyuki Iwatsuki If you pass the C string directly to NSLog(), it will be garbled with Japanese and probably other language strings, or no log will be output at all. NSLog("Hello, World!"); // => "Hello, World!" NSLog("こんにちは、世界!"); // => No output... Therefore, you need to convert the string to an NSString before passing it to NSLog(). NSString *str = [NSString stringWithUTF8String:"こんにちは、世界!"]; NSLog(@"%@", str); // => "こんにちは、世界!" Thank you. * wayland: Don't crash when the properties of already existing wl_output change * Don't uncorrelate while rumble is active and stay correlated longer in case raw input messages are lagging a bit. * cmake: enable AddressSanitizer in Debug builds if supported * Removed support for clock_gettime_nsec_np() SDL_GetTicks() was broken and it's not adding any real value here. * Added test command line options to force different window types * Fixed bug 5471 - Creating a fullscreen desktop window goes windowed temporarily This is caused by the Metal renderer recreating the window because by default we create an OpenGL window on macOS. It turns out that at least on macOS 10.15, a window that has been initialized for OpenGL can also be used with Metal. So we'll skip recreating the window in that case. * Fixed detecting the paddles on the Xbox Elite Series 1 controller * SDL_ConvertColorkeyToAlpha: remove and clarify a FIXME This function doesn't handle bpp 1 or 3 case, because those formats never have an alpha channel * SDL_vulkan_utils: minor code clean-up * KMSDRM doesn't have a window manager, so all windows are fullscreen * Android: documention update * Backed out changeset 1cde3dd0f44d - this breaks windows which are created and then set to FULLSCREEN_DESKTOP * Fixed compiler warning * Updated runtime dependency on libudev * Fix Xbox Series X controller on macOS There were two different implementations of IsBluetoothXboxOneController(), one in SDL_hidapi_xbox360.c and one in SDL_hidapi_xboxone.c. The latter had been updated to include USB_PRODUCT_XBOX_ONE_SERIES_X_BLUETOOTH while the former had not. This mismatch led to the Xbox Series X failing on macOS only. We have special code for handling the 360Controller driver for macOS which requires us to use the Xbox 360 driver for wired Xbox One controllers, and the SDL_hidapi_xbox360 version of IsBluetoothXboxOneController() was used to determine which devices were wired. In addition to adding the missing USB_PRODUCT_XBOX_ONE_SERIES_X_BLUETOOTH, this change moves IsBluetoothXboxOneController() into a single shared function which will ensure this bug won't happen again. * [KMS/DRM] Restore all-windows-are-fullscreen functionality, since there is no window manager in KMSDRM. * [KMS/DRM] Remove redundant SDL_SendWindowEvent() call. * [KMS/DRM] Merge patch for bug #5532: No need to correct cursor position now that all windows are fullscreen. Link: https://bugzilla.libsdl.org/show_bug.cgi?id=5519. * [KMS/DRM] Replace indent tabs with spaces, as intended. * [KMS/DRM] Fix build warning. * minor updates to libc function checks * SDL: fix packet handling for original version of Stadia FW * avoid some pedantic warnings in array initializers * add '-shared-libasan' to debug flags (bug #5533) * enable AddressSanitizer only for GCC 5 onwards (bug #5533) * make AddressSanitizer optional and disabled by default * [KMS/DRM] Bugfix number #5535: Improve reliability, by wahil1976. * free the 'display' after it was added to global list * Backed out changeset 852a7bdbdf4b This causes a use-after-free memory error * Fix waiting on condition variables with the SRW lock implmentation When SleepConditionVariableSRW() releases the SRW lock internally, it causes our SDL_mutex_srw state to become inconsistent. The lock is unowned yet inside, the owner is still the sleeping thread and more importantly the owner count is still 1. The next time someone acquires the lock, they will bump the owner count from 1 to 2. At that point, the lock is hosed. From the internal lock state, it looks to us like that owner has acquired the lock recursively, even though they have not. When they call SDL_UnlockMutex(), it will see the owner count > 0 and not call ReleaseSRWLockExclusive(). Now when someone calls SDL_CondSignal(), SleepConditionVariableSRW() will start the wakeup process by attempting to re-acquire the SRW lock. This will deadlock because the lock was never released after the other thread had used it. The thread waiting on the condition variable will never be able to wake up, even if the SDL_CondWaitTimeout() function is used and the timeout expires. * Fixed bug 5543 - Wayland: Fix waylandvideo.h warnings wahil1976 This patch fixes the warnings seen when compiling the Wayland backend. This will also be required in the future to avoid issues with compilation. * Fixed bug 5539 - Clang 11 fails to compile a CMake build with conflicting types for _m_prefetchw vladius In SDL_cpuinfo.h it seems like is not included when __clang__ is defined, as the comment in the file explicitly reads: "Many of the intrinsics SDL uses are not implemented by clang with Visual Studio" However, the SDL_endian.h header does include without any precautions like: >#ifdef _MSC_VER >#include >#endif Maybe it should be changed to something like: >#ifdef _MSC_VER >#ifndef __clang__ >#include >#endif >#endif * Report found joysticks to SDL for event generation (fixes testjoystick) * Update for 2.0.14 release * Do not loop forever * Update version string * Try to filter out invalid UTF-8 bytes when sending text events (#190) * Open screens with SA_LikeWorkbench. This should fix issue with requester palette * Use smart refresh mode also in fullscreen mode. This avoids potential cosmetic issues with open requesters * Give screen a title for identification purposes * Implement SDL_OpenURL * Adapt to SDL_VideoDevice struct changes * Wait for window resize to happen to avoid issue where consequtive SetWindowAttrs calls seem to fail in SDL_SetWindowSize + SDL_SetWindowPos combo * Work around GCC10 change that triggered linking failure with static library * Disable SA_Compositing in fullscreen mode for a small performance gain * Set global IExec and INewlib only if required * Cleanup * More cleanup * More cleanup * Cleanup * Patch OGLES2 renderer compilation for AmigaOS 4 Co-authored-by: Cameron Gutman Co-authored-by: Sam Lantinga Co-authored-by: Ozkan Sezer Co-authored-by: Sylvain Becker Co-authored-by: Manuel Alfayate Corchete Co-authored-by: Jordan Christiansen Co-authored-by: JibbSmart Co-authored-by: Ryan C. Gordon Co-authored-by: Cameron Gutman Co-authored-by: Simon McVittie Co-authored-by: Ethan Lee Co-authored-by: Brandon DeRosier Co-authored-by: Sebastian Krzyszkowiak Co-authored-by: Christian Rauch Co-authored-by: capehill --- CMakeLists.txt | 202 +- Makefile.amigaos4 | 85 + amiga-extra/Install | 28 + amiga-extra/Install.info | Bin 0 -> 18168 bytes configure | 155 +- configure.ac | 109 + docs/README-amigaos4.md | 174 ++ include/SDL_config.h.cmake | 8 + include/SDL_config.h.in | 8 + include/SDL_config_amigaos4.h | 403 ++++ include/SDL_endian.h | 2 +- include/SDL_opengl.h | 11 + include/SDL_platform.h | 5 + include/SDL_syswm.h | 7 + include/SDL_test.h | 26 + src/SDL.c | 14 + src/audio/SDL_audio.c | 3 + src/audio/SDL_sysaudio.h | 1 + src/audio/amigaos4/SDL_os4audio.c | 474 +++++ src/audio/amigaos4/SDL_os4audio.h | 53 + src/cpuinfo/SDL_cpuinfo.c | 24 + src/dynapi/SDL_dynapi.h | 2 + src/events/scancodes_amiga.h | 144 ++ src/file/SDL_rwops.c | 10 + src/filesystem/amigaos4/SDL_sysfilesystem.c | 162 ++ src/joystick/SDL_gamecontrollerdb.h | 16 + src/joystick/SDL_joystick.c | 3 + src/joystick/SDL_sysjoystick.h | 1 + src/joystick/amigaos4/SDL_sysjoystick.c | 650 ++++++ src/loadso/amigaos4/SDL_sysloadso.c | 187 ++ src/main/amigaos4/SDL_dummy_main.c | 28 + src/main/amigaos4/SDL_os4debug.h | 35 + src/main/amigaos4/SDL_os4version.c | 25 + src/misc/amigaos4/SDL_sysurl.c | 65 + src/render/SDL_render.c | 3 + src/render/SDL_sysrender.h | 1 + src/render/amigaos4/SDL_rc_draw.c | 619 ++++++ src/render/amigaos4/SDL_rc_draw.h | 37 + src/render/amigaos4/SDL_rc_texture.c | 355 ++++ src/render/amigaos4/SDL_rc_texture.h | 58 + src/render/amigaos4/SDL_render_compositing.c | 969 +++++++++ src/render/amigaos4/SDL_render_compositing.h | 54 + src/render/opengl/SDL_glfuncs.h | 4 + src/render/opengl/SDL_render_gl.c | 57 +- src/render/opengles2/SDL_render_gles2.c | 367 ++-- src/stdlib/SDL_iconv.c | 6 + src/thread/SDL_thread_c.h | 2 + src/thread/amigaos4/SDL_sysmutex.c | 128 ++ src/thread/amigaos4/SDL_syssem.c | 239 +++ src/thread/amigaos4/SDL_systhread.c | 428 ++++ src/thread/amigaos4/SDL_systhread_c.h | 35 + src/thread/pthread/SDL_syscond.c | 13 + src/thread/pthread/SDL_systhread.c | 8 +- src/timer/amigaos4/SDL_os4timer.c | 245 +++ src/timer/amigaos4/SDL_os4timer_c.h | 50 + src/timer/amigaos4/SDL_systimer.c | 83 + src/timer/unix/SDL_systimer.c | 8 + src/video/SDL_sysvideo.h | 1 + src/video/SDL_video.c | 56 +- .../amigaos4/SDL_os4_notimplemented_funcs.t | 1280 ++++++++++++ .../amigaos4/SDL_os4_notimplemented_table.t | 182 ++ src/video/amigaos4/SDL_os4events.c | 701 +++++++ src/video/amigaos4/SDL_os4events.h | 30 + src/video/amigaos4/SDL_os4framebuffer.c | 203 ++ src/video/amigaos4/SDL_os4framebuffer.h | 32 + src/video/amigaos4/SDL_os4keyboard.c | 164 ++ src/video/amigaos4/SDL_os4keyboard.h | 35 + src/video/amigaos4/SDL_os4library.c | 118 ++ src/video/amigaos4/SDL_os4library.h | 38 + src/video/amigaos4/SDL_os4messagebox.c | 161 ++ src/video/amigaos4/SDL_os4messagebox.h | 32 + src/video/amigaos4/SDL_os4modes.c | 309 +++ src/video/amigaos4/SDL_os4modes.h | 48 + src/video/amigaos4/SDL_os4mouse.c | 550 +++++ src/video/amigaos4/SDL_os4mouse.h | 42 + src/video/amigaos4/SDL_os4opengl.c | 464 +++++ src/video/amigaos4/SDL_os4opengl.h | 47 + src/video/amigaos4/SDL_os4opengles.c | 368 ++++ src/video/amigaos4/SDL_os4opengles.h | 39 + src/video/amigaos4/SDL_os4opengles2wrapper.c | 771 +++++++ src/video/amigaos4/SDL_os4openglwrapper.c | 1847 +++++++++++++++++ src/video/amigaos4/SDL_os4shape.c | 350 ++++ src/video/amigaos4/SDL_os4shape.h | 42 + src/video/amigaos4/SDL_os4video.c | 601 ++++++ src/video/amigaos4/SDL_os4video.h | 105 + src/video/amigaos4/SDL_os4window.c | 1161 +++++++++++ src/video/amigaos4/SDL_os4window.h | 105 + test/Makefile.amigaos4 | 290 +++ test/Makefile.in | 7 + test/configure | 5 + test/configure.ac | 4 + test/helloworld.c | 868 ++++++++ test/sdl2benchmark.c | 738 +++++++ test/testautomation_rwops.c | 8 + test/testgles2.c | 68 +- test/testnative.c | 3 + test/testnative.h | 5 + test/testnativeamigaos4.c | 92 + test/testoverlay2.c | 4 + 99 files changed, 18526 insertions(+), 337 deletions(-) create mode 100644 Makefile.amigaos4 create mode 100755 amiga-extra/Install create mode 100644 amiga-extra/Install.info create mode 100755 docs/README-amigaos4.md create mode 100644 include/SDL_config_amigaos4.h create mode 100644 src/audio/amigaos4/SDL_os4audio.c create mode 100644 src/audio/amigaos4/SDL_os4audio.h create mode 100644 src/events/scancodes_amiga.h create mode 100644 src/filesystem/amigaos4/SDL_sysfilesystem.c create mode 100644 src/joystick/amigaos4/SDL_sysjoystick.c create mode 100644 src/loadso/amigaos4/SDL_sysloadso.c create mode 100644 src/main/amigaos4/SDL_dummy_main.c create mode 100644 src/main/amigaos4/SDL_os4debug.h create mode 100644 src/main/amigaos4/SDL_os4version.c create mode 100644 src/misc/amigaos4/SDL_sysurl.c create mode 100644 src/render/amigaos4/SDL_rc_draw.c create mode 100644 src/render/amigaos4/SDL_rc_draw.h create mode 100644 src/render/amigaos4/SDL_rc_texture.c create mode 100644 src/render/amigaos4/SDL_rc_texture.h create mode 100644 src/render/amigaos4/SDL_render_compositing.c create mode 100644 src/render/amigaos4/SDL_render_compositing.h create mode 100644 src/thread/amigaos4/SDL_sysmutex.c create mode 100644 src/thread/amigaos4/SDL_syssem.c create mode 100644 src/thread/amigaos4/SDL_systhread.c create mode 100644 src/thread/amigaos4/SDL_systhread_c.h create mode 100644 src/timer/amigaos4/SDL_os4timer.c create mode 100644 src/timer/amigaos4/SDL_os4timer_c.h create mode 100644 src/timer/amigaos4/SDL_systimer.c create mode 100644 src/video/amigaos4/SDL_os4_notimplemented_funcs.t create mode 100644 src/video/amigaos4/SDL_os4_notimplemented_table.t create mode 100644 src/video/amigaos4/SDL_os4events.c create mode 100644 src/video/amigaos4/SDL_os4events.h create mode 100644 src/video/amigaos4/SDL_os4framebuffer.c create mode 100644 src/video/amigaos4/SDL_os4framebuffer.h create mode 100644 src/video/amigaos4/SDL_os4keyboard.c create mode 100644 src/video/amigaos4/SDL_os4keyboard.h create mode 100644 src/video/amigaos4/SDL_os4library.c create mode 100644 src/video/amigaos4/SDL_os4library.h create mode 100644 src/video/amigaos4/SDL_os4messagebox.c create mode 100644 src/video/amigaos4/SDL_os4messagebox.h create mode 100644 src/video/amigaos4/SDL_os4modes.c create mode 100644 src/video/amigaos4/SDL_os4modes.h create mode 100644 src/video/amigaos4/SDL_os4mouse.c create mode 100644 src/video/amigaos4/SDL_os4mouse.h create mode 100644 src/video/amigaos4/SDL_os4opengl.c create mode 100644 src/video/amigaos4/SDL_os4opengl.h create mode 100644 src/video/amigaos4/SDL_os4opengles.c create mode 100644 src/video/amigaos4/SDL_os4opengles.h create mode 100644 src/video/amigaos4/SDL_os4opengles2wrapper.c create mode 100644 src/video/amigaos4/SDL_os4openglwrapper.c create mode 100644 src/video/amigaos4/SDL_os4shape.c create mode 100644 src/video/amigaos4/SDL_os4shape.h create mode 100644 src/video/amigaos4/SDL_os4video.c create mode 100644 src/video/amigaos4/SDL_os4video.h create mode 100644 src/video/amigaos4/SDL_os4window.c create mode 100644 src/video/amigaos4/SDL_os4window.h create mode 100644 test/Makefile.amigaos4 create mode 100644 test/helloworld.c create mode 100755 test/sdl2benchmark.c create mode 100644 test/testnativeamigaos4.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 358f32f3afd98..95400595bf954 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -131,6 +131,9 @@ elseif(CMAKE_SYSTEM_NAME MATCHES "BeOS.*") message_error("BeOS support has been removed as of SDL 2.0.2.") elseif(CMAKE_SYSTEM_NAME MATCHES "Haiku.*") set(HAIKU TRUE) +elseif(CMAKE_SYSTEM_NAME MATCHES "Amiga.*") + set(AMIGA TRUE) + message("*** AmigaOS 4 build ***") endif() # Don't mistake osx for unix @@ -153,12 +156,15 @@ endif() # for the time being. This default with change to ON once this becomes # commonly supported in browsers or the Emscripten teams makes a single # binary work everywhere. -if (UNIX_OR_MAC_SYS AND NOT EMSCRIPTEN) +if (AMIGA OR (UNIX_OR_MAC_SYS AND NOT EMSCRIPTEN)) set(SDL_PTHREADS_ENABLED_BY_DEFAULT ON) else() set(SDL_PTHREADS_ENABLED_BY_DEFAULT OFF) endif() +if(UNIX OR MINGW OR MSYS OR AMIGA) + set(OPT_DEF_LIBC ON) +endif() # The hidraw support doesn't catch Xbox, PS4 and Nintendo controllers, # so we'll just use libusb when it's available. libusb does not support iOS, # so we default to yes on iOS. @@ -297,6 +303,7 @@ if(EMSCRIPTEN) set(OPT_DEF_ASM FALSE) set(SDL_SHARED_ENABLED_BY_DEFAULT OFF) set(SDL_ATOMIC_ENABLED_BY_DEFAULT OFF) + set(SDL_THREADS_ENABLED_BY_DEFAULT OFF) set(SDL_LOADSO_ENABLED_BY_DEFAULT OFF) set(SDL_CPUINFO_ENABLED_BY_DEFAULT OFF) set(SDL_DLOPEN_ENABLED_BY_DEFAULT OFF) @@ -552,6 +559,12 @@ if(USE_GCC OR USE_CLANG) endif() endif() +if(AMIGA) + # Disable Altivec for now. It gives problem for people without it. + message("Disabling Altivec...") + set(ALTIVEC FALSE) +endif() + if(ASSEMBLY) if(USE_GCC OR USE_CLANG) set(SDL_ASSEMBLY_ROUTINES 1) @@ -864,13 +877,15 @@ if(LIBC) endif() endif() - check_library_exists(iconv iconv_open "" HAVE_LIBICONV) - check_library_exists(c iconv_open "" HAVE_BUILTIN_ICONV) - if(HAVE_BUILTIN_ICONV) - set(HAVE_ICONV 1) - elseif(HAVE_LIBICONV) - list(APPEND EXTRA_LIBS iconv) - set(HAVE_ICONV 1) + if(NOT AMIGA) # we don't have libiconv + check_library_exists(iconv iconv_open "" HAVE_LIBICONV) + check_library_exists(c iconv_open "" HAVE_BUILTIN_ICONV) + if(HAVE_BUILTIN_ICONV) + set(HAVE_ICONV 1) + elseif(HAVE_LIBICONV) + list(APPEND EXTRA_LIBS iconv) + set(HAVE_ICONV 1) + endif() endif() if(NOT APPLE) @@ -2029,141 +2044,84 @@ elseif(HAIKU) CheckPTHREAD() -elseif(RISCOS) - file(GLOB MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/riscos/*.c) - set(SOURCE_FILES ${SOURCE_FILES} ${MISC_SOURCES}) - set(HAVE_SDL_MISC TRUE) +elseif(AMIGA) + message("AmigaOS 4 specific stuff") - if(SDL_TIMERS) - set(SDL_TIMER_UNIX 1) - file(GLOB TIMER_SOURCES ${SDL2_SOURCE_DIR}/src/timer/unix/*.c) - set(SOURCE_FILES ${SOURCE_FILES} ${TIMER_SOURCES}) - set(HAVE_SDL_TIMERS TRUE) + if(SDL_VIDEO) + set(SDL_VIDEO_DRIVER_AMIGAOS4 1) + file(GLOB AMIGAOS4VIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/amigaos4/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${AMIGAOS4VIDEO_SOURCES}) + set(HAVE_SDL_VIDEO TRUE) - if(CLOCK_GETTIME) - set(HAVE_CLOCK_GETTIME 1) + set(SDL_VIDEO_RENDER_AMIGAOS4 1) + + if(VIDEO_OPENGL) + set(SDL_VIDEO_RENDER_OGL 1) # MiniGL should be there + set(SDL_VIDEO_OPENGL 1) + set(HAVE_VIDEO_OPENGL TRUE) endif() - endif() - CheckPTHREAD() + CheckOpenGLES2() + endif() if(SDL_AUDIO) - CheckOSS() - endif() -elseif(VITA) - # SDL_spinlock.c Needs to be compiled in ARM mode. - check_c_compiler_flag(-marm HAVE_ARM_MODE) - if(HAVE_ARM_MODE) - set_source_files_properties(${SDL2_SOURCE_DIR}/src/atomic/SDL_spinlock.c PROPERTIES COMPILE_FLAGS -marm) + set(SDL_AUDIO_DRIVER_AMIGAOS4 1) + file(GLOB AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/amigaos4/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${AUDIO_SOURCES}) + set(HAVE_SDL_AUDIO TRUE) endif() - file(GLOB MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/vita/*.c) - set(SOURCE_FILES ${SOURCE_FILES} ${MISC_SOURCES}) - set(HAVE_SDL_MISC TRUE) + if(SDL_TIMERS) + set(SDL_TIMER_UNIX 1) + file(GLOB TIMER_SOURCES ${SDL2_SOURCE_DIR}/src/timer/unix/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${TIMER_SOURCES}) + set(HAVE_SDL_TIMERS TRUE) + endif(SDL_TIMERS) - if(SDL_AUDIO) - set(SDL_AUDIO_DRIVER_VITA 1) - file(GLOB VITA_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/vita/*.c) - set(SOURCE_FILES ${SOURCE_FILES} ${VITA_AUDIO_SOURCES}) - set(HAVE_SDL_AUDIO TRUE) + if(SDL_LOADSO) + set(SDL_LOADSO_AMIGAOS4 1) + file(GLOB LOADSO_SOURCES ${SDL2_SOURCE_DIR}/src/loadso/amigaos4/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${LOADSO_SOURCES}) + set(HAVE_SDL_LOADSO TRUE) endif() + if(SDL_FILESYSTEM) - set(SDL_FILESYSTEM_VITA 1) - file(GLOB VITA_FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/vita/*.c) - set(SOURCE_FILES ${SOURCE_FILES} ${VITA_FILESYSTEM_SOURCES}) + set(SDL_FILESYSTEM_AMIGAOS4 1) + file(GLOB FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/amigaos4/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${FILESYSTEM_SOURCES}) set(HAVE_SDL_FILESYSTEM TRUE) endif() + if(SDL_JOYSTICK) - set(SDL_JOYSTICK_VITA 1) - file(GLOB VITA_JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/vita/*.c) - set(SOURCE_FILES ${SOURCE_FILES} ${VITA_JOYSTICK_SOURCES}) + set(SDL_JOYSTICK_AMIGAINPUT 1) # TODO: rename? + file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/amigaos4/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${JOYSTICK_SOURCES}) set(HAVE_SDL_JOYSTICK TRUE) endif() - if(SDL_POWER) - set(SDL_POWER_VITA 1) - file(GLOB VITA_POWER_SOURCES ${SDL2_SOURCE_DIR}/src/power/vita/*.c) - set(SOURCE_FILES ${SOURCE_FILES} ${VITA_POWER_SOURCES}) - set(HAVE_SDL_POWER TRUE) - endif() - if(SDL_THREADS) - set(SDL_THREAD_VITA 1) - set(SOURCE_FILES ${SOURCE_FILES} - ${SDL2_SOURCE_DIR}/src/thread/vita/SDL_sysmutex.c - ${SDL2_SOURCE_DIR}/src/thread/vita/SDL_syssem.c - ${SDL2_SOURCE_DIR}/src/thread/vita/SDL_systhread.c - ${SDL2_SOURCE_DIR}/src/thread/vita/SDL_syscond.c - ${SDL2_SOURCE_DIR}/src/thread/generic/SDL_systls.c) - set(HAVE_SDL_THREADS TRUE) - endif() - if(SDL_TIMERS) - set(SDL_TIMER_VITA 1) - file(GLOB TIMER_SOURCES ${SDL2_SOURCE_DIR}/src/timer/vita/*.c) - set(SOURCE_FILES ${SOURCE_FILES} ${TIMER_SOURCES}) - set(HAVE_SDL_TIMERS TRUE) - endif() - if(SDL_SENSOR) - set(SDL_SENSOR_VITA 1) - set(HAVE_SDL_SENSORS TRUE) - file(GLOB VITA_SENSOR_SOURCES ${SDL2_SOURCE_DIR}/src/sensor/vita/*.c) - set(SOURCE_FILES ${SOURCE_FILES} ${VITA_SENSOR_SOURCES}) - endif() - if(SDL_VIDEO) - set(SDL_VIDEO_DRIVER_VITA 1) - file(GLOB VITA_VIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/vita/*.c) - set(SOURCE_FILES ${SOURCE_FILES} ${VITA_VIDEO_SOURCES}) - set(HAVE_SDL_VIDEO TRUE) - check_include_file(pib.h HAVE_PIGS_IN_BLANKET_H) + CheckPTHREAD() +elseif(RISCOS) + file(GLOB MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/riscos/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${MISC_SOURCES}) + set(HAVE_SDL_MISC TRUE) - if(HAVE_PIGS_IN_BLANKET_H) - set(SDL_VIDEO_OPENGL_ES2 1) - list(APPEND EXTRA_LIBS - pib - ) + if(SDL_TIMERS) + set(SDL_TIMER_UNIX 1) + file(GLOB TIMER_SOURCES ${SDL2_SOURCE_DIR}/src/timer/unix/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${TIMER_SOURCES}) + set(HAVE_SDL_TIMERS TRUE) + if(CLOCK_GETTIME) + set(HAVE_CLOCK_GETTIME 1) endif() - set(SDL_VIDEO_RENDER_VITA_GXM 1) - - list(APPEND EXTRA_LIBS - SceGxm_stub - SceDisplay_stub - SceCtrl_stub - SceAppMgr_stub - SceAudio_stub - SceSysmodule_stub - SceDisplay_stub - SceCtrl_stub - SceIofilemgr_stub - SceCommonDialog_stub - SceTouch_stub - SceHid_stub - SceMotion_stub - m - ) endif() - set(HAVE_ARMSIMD TRUE) - set(SDL_ARM_SIMD_BLITTERS 1) - file(GLOB ARMSIMD_SOURCES ${SDL2_SOURCE_DIR}/src/video/arm/pixman-arm-simd*.S) - set(SOURCE_FILES ${SOURCE_FILES} ${ARMSIMD_SOURCES}) - - set(HAVE_ARMNEON TRUE) - set(SDL_ARM_NEON_BLITTERS 1) - file(GLOB ARMNEON_SOURCES ${SDL2_SOURCE_DIR}/src/video/arm/pixman-arm-neon*.S) - set(SOURCE_FILES ${SOURCE_FILES} ${ARMNEON_SOURCES}) - - set_property(SOURCE ${SDL2_SOURCE_DIR}/src/video/arm/pixman-arm-simd-asm.S PROPERTY LANGUAGE C) - set_property(SOURCE ${SDL2_SOURCE_DIR}/src/video/arm/pixman-arm-neon-asm.S PROPERTY LANGUAGE C) - - add_definitions("-D__VITA__") - add_definitions("-Dmemcpy=sceClibMemcpy") - add_definitions("-Dmemset=sceClibMemset") - add_definitions("-Dmemmove=sceClibMemmove") - add_definitions("-Dmemcmp=sceClibMemcmp") - -# CheckPTHREAD() + CheckPTHREAD() + if(SDL_AUDIO) + CheckOSS() + endif() endif() if(VIDEO_VULKAN) @@ -2263,9 +2221,7 @@ if(NOT CMAKE_HOST_WIN32) WORKING_DIRECTORY ${SDL2_BINARY_DIR}) endif() if(NOT WINDOWS OR CYGWIN) - set(prefix ${CMAKE_INSTALL_PREFIX}) - set(exec_prefix "\${prefix}") set(libdir "\${exec_prefix}/lib${LIB_SUFFIX}") set(bindir "\${exec_prefix}/bin") @@ -2278,12 +2234,12 @@ if(NOT WINDOWS OR CYGWIN) set(ENABLE_STATIC_FALSE "") endif() if(SDL_SHARED) - set(PKGCONFIG_LIBS_PRIV " + set(PKG_CONFIG_LIBS_PRIV " Libs.private:") set(ENABLE_SHARED_TRUE "") set(ENABLE_SHARED_FALSE "#") else() - set(PKGCONFIG_LIBS_PRIV "") + set(PKG_CONFIG_LIBS_PRIV "") set(ENABLE_SHARED_TRUE "#") set(ENABLE_SHARED_FALSE "") endif() diff --git a/Makefile.amigaos4 b/Makefile.amigaos4 new file mode 100644 index 0000000000000..754d92ffc8d6f --- /dev/null +++ b/Makefile.amigaos4 @@ -0,0 +1,85 @@ +# Makefile to build the AmigaOS4 SDL library + +AR = ppc-amigaos-ar +RANLIB = ppc-amigaos-ranlib +CC = ppc-amigaos-gcc +CXX = ppc-amigaos-g++ +STRIP = ppc-amigaos-strip + +AMIGADATE = $(shell date +"%-d.%-m.%Y") + +CFLAGS = -gstabs -O2 -Wall -fPIC -fcommon -I./include -D__AMIGADATE__=\"$(AMIGADATE)\" + +TARGET_STATIC = libSDL2.a +TARGET_SHARED = libSDL2-2.0.so +TESTLIB_STATIC = libSDL2_test.a + +SOURCES = \ + ./src/*.c \ + ./src/atomic/*.c \ + ./src/audio/*.c \ + ./src/audio/amigaos4/*.c \ + ./src/audio/dummy/*.c \ + ./src/cpuinfo/*.c \ + ./src/events/*.c \ + ./src/file/*.c \ + ./src/filesystem/amigaos4/*.c \ + ./src/haptic/*.c \ + ./src/haptic/dummy/*.c \ + ./src/joystick/*.c \ + ./src/joystick/amigaos4/*.c \ + ./src/loadso/amigaos4/*.c \ + ./src/misc/*.c \ + ./src/misc/amigaos4/*.c \ + ./src/render/*.c \ + ./src/power/*.c \ + ./src/render/amigaos4/*.c \ + ./src/render/opengl/*.c \ + ./src/render/opengles2/*.c \ + ./src/render/software/*.c \ + ./src/sensor/*.c \ + ./src/sensor/dummy/*.c \ + ./src/stdlib/*.c \ + ./src/thread/*.c \ + ./src/thread/amigaos4/*.c \ + ./src/thread/generic/SDL_syscond.c \ + ./src/thread/generic/SDL_systls.c \ + ./src/timer/*.c \ + ./src/timer/amigaos4/*.c \ + ./src/video/*.c \ + ./src/video/dummy/*.c \ + ./src/video/amigaos4/*.c \ + ./src/video/yuv2rgb/*.c \ + +TESTLIB_SOURCES =./src/test/*.c + +OBJECTS = $(shell echo $(SOURCES) | sed -e 's,\.c,\.o,g') +TESTLIB_OBJECTS = $(shell echo $(TESTLIB_SOURCES) | sed -e 's,\.c,\.o,g') +VERSION_OBJECT = src/main/amigaos4/SDL_os4version.o + +all: config_copy $(TARGET_STATIC) $(TARGET_SHARED) $(TESTLIB_STATIC) + +$(TESTLIB_STATIC): $(TESTLIB_OBJECTS) + $(AR) crv $@ $^ + $(RANLIB) $@ + +$(TARGET_STATIC): $(OBJECTS) + $(AR) crv $@ $^ + $(RANLIB) $@ + +$(TARGET_SHARED): $(OBJECTS) $(VERSION_OBJECT) + $(CC) -shared -Wl,-soname,$(TARGET_SHARED) -o $(TARGET_SHARED) $(OBJECTS) $(VERSION_OBJECT) + +config_copy: + cp include/SDL_config_amigaos4.h include/SDL_config.h + +clean: + rm -f $(TARGET_STATIC) $(TARGET_SHARED)* $(TESTLIB_STATIC) $(OBJECTS) + +install: + mkdir -p /SDK/local/newlib/lib + mkdir -p /SDK/local/newlib/include/SDL2 + cp -f $(TARGET_STATIC) /SDK/local/newlib/lib + cp -f $(TARGET_SHARED) /SDK/local/newlib/lib + cp -f $(TESTLIB_STATIC) /SDK/local/newlib/lib + cp -f include/*.h /SDK/local/newlib/include/SDL2/ diff --git a/amiga-extra/Install b/amiga-extra/Install new file mode 100755 index 0000000000000..f946b97397523 --- /dev/null +++ b/amiga-extra/Install @@ -0,0 +1,28 @@ +failat 21 + +echo Copying shared object ... +copy SDK/local/newlib/lib/libSDL2-2.0.so SObjs: +copy SDK/local/newlib/lib/libSDL2-2.0_debug.so SObjs: + +set option `RequestChoice "One more question..." "Would you like to install the SDK?" "Yes, please" "No, thanks"` + +If $option eq 1 + echo Copying SDK files ... + copy SDK/#? SDK: all + + protect SDK:local/newlib/bin/sdl2-config +rweds + + cd SDK:local/newlib/lib + makelink from=libSDL2.so to=libSDL2-2.0.so soft +Else + echo Skipped SDK installation ... +EndIf + +echo Setting up link ... + +cd SObjs: +makelink >NIL: from=libSDL2.so to=libSDL2-2.0.so soft + +echo SDL2 is installed :) + +Wait 5 diff --git a/amiga-extra/Install.info b/amiga-extra/Install.info new file mode 100644 index 0000000000000000000000000000000000000000..32b78ba62b48c40dbb766e7dd62e6d0f90348007 GIT binary patch literal 18168 zcmc(_2S8KHy7#?ekf@ZPZ0Qixt!z}9h=3wNQL)hMg{r8a^dg{?1W^#A*g=YbA}CU& z*91^NMT%4rAxQ5X0wG!N46)sP&pqe8=icxAM$IqJ%v!T%&GS6}nYCgkAA&)C6b(cJ z;RH73RN772sk9p!KN@}#!-1S$GSA1hF^2$oezqZG_E*@;vQvWc2>QJVi=tHcbqNAm zAW7&Vf7JgA5@0(WL4Fbi1=@e3D72dqL>Mv@K~x~c5JZiHqAWE8Q75A4f;)l`3E=bv zz-knoghWC4&i23AKk6Y#@Hp20K4G^gn5%!E-Zb|4WB7m6k13dU;MQOLGuYQ-<+Hi4 zgH7}*n?? zJ~$BMFL>G?2(lTN)U6020qb2se86Tpf|x|1=-fOY^fzQLiuOXzqUb0jn2&ZyCW=xZ zStv?^L`f_ZkbqK{Fy4r0I|If+5jr}HdLT#vIy;K)M36$1(T)~E4rfE=q9cxIB;=4H zn=~AoWDKMl9KRai7=qx{5DfSV3^GOqQjCm|hvX(>Bmp2H5Cjlhn+OSRj1GyT6UHDh zFu%wkHAyT)l8ku+4_`;dfFXmylQBf#Ms$IUAtN{%g84-+>JJ;st|$K>g23ab00fB}G*E`~pXfQjV>rlb&p2yp-|Ll8bd1bzqj8INGb$`h( zqu|k?@PRX7SzZG_HISvzuw4UL0{$Y%Ze%4He1NZfuo7_jEjIBrkk=7Vc74AFxWeK^ z$gq-K$Yf9lDghQ7|4vx_djVGg$+7qs3~li?**E(AATlKAPYR)}J^}KEc!Re34CEd* z)qrgbY;_;nYEM8{J-gK=Pr!T9E^YuU&o*#-JE3jiYsy@gW=-)9w zItdL1{FnbEp$!A}M_GXR4+;V1KPZd&4~X%mQ319h zcDzso-+=GPy6?w;W22Vjn%Wz}_F#}^PCnH!e*8jEg zGtbHF*#6n^Ki30ccwQ)oZ%96ng^(Oz9f1A^@wy54eY74yq#+-G+=l)a0)%k_Xh;If z_I3m@CbEbN*MP1QXjnS%r%5#xv$!6h;9j8(*uF^Mr$th+kOUO?4@@`_1?wyDK@mzP zu=Rg|$ku-riLL)2J_@1k1OG?|3Lpi27#VI-@t$Wfq#z&*!Zh}lvqp-VUY0%hyxG;i(CA|NJePJz4wdmTQIXF}jG4)7sH0Q)`AE`ete$6SFwaWpKA4p>gbbOI8=B4Gk^ zi-{mnkSsEW1c_=af&M0;(Mw_86VVzjXcN&sK{lu4*qk?ElSzRDIzWOt;DL^!Xc6R$ z3!7tdkYJku1n1X&%oEz4@H(J?>yW?~7UU26Z-gcaX7UF|QLz7;MUZkBpPdK-wmD#< z^Q)Z({f`6lK_?8nge#XjVIT$&v%uyOwePkkVZaO2?^4DOK+V8{a}ZPT?|)i;>i>^@ z-#^!TxR6ufHNR67vKdGr)PMQk^dH_Q)KIwo19AbASo3TD5A&ZP1pIFb^j`(|AL_p= z@E_EF=trpkfd5MW2~hv((C;9>!SU))|J}j50`*@F`j<&z`xodx@UI(~eY6chcAyK2 zXe(rYFq^@(km}I4@O(ISaQ;qsuLWSef)qoLR5I`lc&v(sHXtxT1>gc01KcbS{-gf$ zLH!4Q@xJl!W;Y z8YFR4%p$R%18BoJhJ^dRMQSWzQ<4J`Txqd)46=+5A%pNlI3y7&-0v;XfcrhL@4E%L z58>lR&O!25vPqz`3HIlpUK8qH2_OjEF-Q=nD4-VPw_o|&4(;Fa7=?KN^Bz3y;UMWa z8XgkF6A|zO3f8SU7;m7oF7As_lm;gUlqJBwbUFbA8VAV$EK*^!z;)q!J)1eMBowY+ z|C|2T0HXl!1T=oW6M$p-cgpv*1J{kB@ied}>_Aapec)oi5Rjt;Ag(EZM8IH>FY-Jn zdI#*GB*n*YIlzZf9b_b=3;GxoVB^3s1keu_1O|=@o*f`>fOc31+U-CcmKQ-zNdgTK z0ecB~aN2gzKOYD^aIX3-1X<}0Y;evRV3SIKKY>3yIuOLS2#`+3;2~QjRCWL|SvVSr z0-hDY_$Y;NE#T&ZYk>#!8EAKhRR2X!5?Bj7fsY}fuNTWtg4uut`2BBeg7zR8!(I!> z7(HlzBO~rnfGn`b$1M_*K3hJ0Y&{txMXa7a;Y7yBhO?P0T0VW^3K^4Zz~;IIbDF>u z88bBGil}pe^%0zovdAFrAb-Ue^8cu;5CeLt55igqPZ!bvnJGkM3Bl~-0IM~CI5vX8$4E+vHRD`Sqdk7lvdjx`LYk+HPL6D24pzDiZ zTMYb;l!1TbMM*|58lW9~M@+FaP5=#g+!!~=H4Qi}NDe$*9&+uzEqegTnCxLP20^Gx zTxK+Y?vRnmQ3TlkRUyL$(EeZW`6In*as6c{u3S>y|>1_%LViV*DAf|Yf zy84(D8B?lEU46oZj46p?bDs&IGa0k{J9o{}5P=yocmk&bpOZ0I8aN+}iuAwbe2leCeMA;6n~WW$lF<9JRBUxIir$~3 zVyS0Q)CWt&R={@${J;itKn6AyUJI}o`o9zq`rZ2%D?tBPek$&U2Jr718t$ni@c&*K zE(T8QO&X32fM94iFGw#MkPI**;5agZ8-w-N;aaup7fU2LYzJCzxKQtAyGzl@+g=T_y4m`4unyTqV-9 z+03j|S+r9F*xbw~MCf1UDj_a}1A8;rFD$NjjYa+(4_MJ)8H4Hq3Jt7Suuy;M*5cv+ z=!5t#{J+@GZ#u`1q7@(xX2F$cqh!p4AXww|$k;L151xvxf#jlM+oQm{KL)S~Aaa4- zOdun4QBV)xC4&0d1tN!jL$5FH#a2Cu@=O`7IUk;YwuQXiYC>TH?4Oav( z>p{bz@ZBMNE@Yr+J0Jt68 zNVo6IWfQ+ZTCDFFBcUv=pZ)zDCj}gaGJlRA+%GKu4gde6nE1U8?tP&BohyL9`}7fH z6^w)Zpq>D1*bW{7Y5*hw$3RZVF~Bf@{;R-xaL+_wj)IJUWNXQPBmvd~ZTvw!Xixmw zn`uJ31f(h?)O8YY<8S<-U$6rxu?U!nF#ruXZg3nGqc=eYNlr$Dgg`>Ww1$cOUlKO| zqe6z2K)=}}|0Jviyyx;PvKcxS$(g-)9eW|2lYX2D(ozMi6f-4Oc=VV{n>) zt{O{t0k4Zma;WSA`p>(J&kpK6rni?22`B3}{$2l}V=-i)uaKBuItx!jkl*xw(f+B+ zK>tBm)PMNJRYD#@478Ks7gq__kk{?{;GGZTDe#yKt~#0u@)p?D zAhsb#zjHC42gh(tz!n1f-zNmxq5cC~8S4KK2s^0%Koq=W4`TQGahOsXJcf*+fcrq1 zWaKFU?rg<*e8}l|94WcrO^MSRO~qPe=s;6`X5il(V_ndG+e732=g5@TpJkYlpDx@ z&~HD?{|_iy2lD?$_W~h)4Gl+~pyTyG{!{1dIHMrlQ4Z)``20sFU}>;JI-Uf&f%_OL zG_n7k{O3GiW@~c_*{63z2SGO29njR%-M33~FX)DoNCcUI*>yx~H+X0B6x4vg#)kme ziWm-av3l4fTo$gg&u`0v*t_@sIf)^mR%e@b1#As^($mx>WB zP4f2MnRpwF~DQ+UvM za4wgUH?ctSZ%6$P=9~CeN1j-(B+^(uo$}#j z;p9|rW7Uew{RP`k*FInSyf#%mnP~RaW+!p>WQd#13H=YfmPb|_ZK}K8cjBQZc3}{n zChA}_Gu$}oNV4O-yw6~EAVBf3rJ^WL3(noae1K?jEwV>q@O9Omlxmx;7KALg{dNB7=G6y_Z>p}!f2sd% z8~*52`pWZm02)#6E$ zq!0ItL?^^o{ON2K)1!%gEFIjX?%GFr&T@~?9Ev;J^2pPpsdtcmF@CJ1HCkpz)JcN` zy9gScDpP~L(Da+ni`#$gc=!I%fi<7Zzv?$M*_wGdjP%lHlHWhH>6ZRvc06xS(*C+( z!PSpHrEf8~cD$z|#LLqpshVp_=2*KtXYag9RIO~>+Cz-AK;wroX8V$~LvnPcm0~=W zu+A2=HRNtdjS~tAZd=0CQ%N++u(&I>^V+ez2U71sEPY>Ct5E&u#mh&=x<$q{O(M$N zavHOGW`frGxfpz_a;~X5mz|Wd@-io7%E9w|E5}LvcrtHl)4J%WZDE@*QTNTGQuh0Z zibdrtosaUEcqcWhkMWe3^_O~kS>*bi>qMWBW;Ihl9B zd}KIpW5Z{;`Z*EZJ}sBo)i1+l6)az0SJm^p&y~=S8Hlg+vtlrM4Q=!pCf}3=4FWSK zMLR7PB75d@?PK5MZSTw4sFTYvRk||yZX?>O8@b)6EyvzWA06*3Z?MU3xb)szZN2B4 zu(0QCwZlyZ>{ynjBa^d(y+!UJCUY%O_G6nIxzwK;TQn6uHQr&kWWHlr)BekprjAhs z1qJkT-j!Ekst#S81SgZo5c;PuPU=uk zjI>1DHF}5Iu!SCRUQyTKV~*r4k7IkUy>QMcUYR_*PakFSTIZCHv}7LQC8)PX z(PG=3_Sfpm@`dlp-)AD|5}0|}QADruUcvoz+ZD+M2J@#SxZ8G?U8=q;-&2OO30h}J z2#RKvi* z+?>?l6~QO6_s^R5wEkgul6VK7Y;rGLi(+Rl)ze(UndLq#CMs9HGC5dFpLpAkXR_zx z{he+zFFc-jxfAR>%Y(#4utY*dQ&(Z9XH8I9y5o7*;nu}z@pv6ROL+^nP#ClvS|2FHEScU+eB72SI?a>(-_d0rJWpB^B3dhL{ z^>a&i*;QVh-1VNdeARG<;y#OHGp_Jv-dbL*oD$U|^Q89I7e3ri^mvTA6HF-y2^&@9 zgcjy7`dod&hYeEl`$~38=jHV6%b7IPyE2Qxuj!`liFb_o!{p4L&(K0Tr=9w+X`%CAuVq%+ zM~SQszM3REv5pnJ`z_4H8@6oUo)?sfRz>bu-CR2J>G`3CxNh%`i>zD8RS%B!Vl#pY zUr${#G~Re=L?U=bzp&_Hx|fbsDMr?A#hCY|h;?b4=f$V1o12?a>*my5z2X`YW19;u zHzY)lCdqQg6v>n92#0p494Ip~+R&Nu5LcWlp_`wQx#pwslR*JqJFlZ;f?*8^}lHT34j|;opg`^TTYEJ9YujQ^C=4(;B@Zpin_KPo! zO&lf5y`y&;(#|hL@Th2=<7s}gCO0)z|LWvIDZO$>XL)dw*{kI>cLx^Q=g+#OpOiq|QCq)`K-kPx+d?9G62~ZX>oM+0JGahFNfEqsY!{83R)4U$U(4 zPfR$R-C0>Q*LoSdwF_SrET(#-^M>rabBgv!Vyf+AMaHGNjJVIUomOUHJn4r_a;SbD zD%+Fog5J2L#_>MCFQs>aX;)6EH#mIw?uc1k%^kT)LWCAN(D3TYW_s0QMXh4i{Pf_J zg5~@hDnL-w6N-#YvTg6H+j;Rb?3_AFb1!jBr3WQ!mXT>)5Mi+A}&AKekEZ9J99Pr%$YMA&B}w06KbWlRux^;5LKZr)fFqPwZG~3 zXCt|Kt96T$-s#hiC#3e(Zx|O=ICn$BtexzEU9k9|yz1MB`N!tVriw$7`pu(6F5V9A zsg6qV=(AKczowIp0S@DzQE@ix;GVUcMw9p67LcN01>H3yQUywS-ap*b5Qk4bdE&%n z?ph6#3G+{}2NLcsJlS%=e|`z&9v4{f8&xCBwOeW)srTT@&Uu;*>ATsHxgv6SwaQml z+2K#31mb+(Gp;UyLBb@)poha1H=$FVF5oTasM1oiU#-?Gnn1-FV!J4jxW-48=@&nK zN)x)DmUh;jx=pOF)6sEpTp8`1HBXPm>zXJMI!UIURH?2Jurav8vzsMjn4>>e8LF`E zh0GC2f{>_abIFFR4kUzZ)4AL{r=8!2#SmlFf?n?uaSq5RhF6 z%g!qY5vXdvlgd95d?O|*ymzaCL72>>x4i;Maa5k*sCTY?;?234L&ZV`Zcnp>MMVQ_ zodbQxC(bRIwG%+xwTyO0#OlIHTfuPa~I+S+;ymC0Dw(^|KXruj{*3jv#l274by`q@5GTgM+oWw@{TE+Njt zEeFn=37d#1B5h0wlv23BtjbrL>f~ZcIZY27fBSIL$tjAOMLAxLaTm*SXP8}CBB)Z# z6J&QKqJ!lwG;d;;^JbD`VUD!2I;AzZLbK7Z@({u(BDz!PV#9`-lfG{oMmrgeMDv+S zbwe7*_aShBA-wBQQF@mz)EJV*xn;PlvwX_8N7Jl_;?trO+dhkppmA#DY_GB-NozAj z4YF;LGPMIIhHGi)Xm!!vbo>w_*5g^`jNy(e1INZl*JDx#vz`ZAf8;eFsdaWZdcW!f zc{WAq)Bjv>)v>=ZDZHz@duh{`h1t7ijht%LEg}z^Q#U;0+~GX*m&g3n-Cf?Cm)u$= zBFe7?3VqJsiY?F0&CRT0zvf6lLAff4Da_kZ9#5rd-lEI)g;F&3dhY36`aYuyngsgc1V#2 z<8meKW_!-QNcr|J3@!sjN6I?Anvaj%;|U_;*ehC|G_45&(_(#ZZk4K2rxbK3zL$jt zlm?tMzPfk2%ZPiVr+egshz+^#(0dQ>haWg>eDd)&kGN$1TTP5nikx*zM(w;7v7oP9 zX&`*=Yn#*(_gy;CqJ+bgz74jaCaF5D@30?;6U1Z0VQmWVxp_%Vb&I_#5V#`CFIh>k zad8PU3+i?>4Zq;v5c-Wh2ZSETF1|4)4pAl3 zC$u|>nxFGTtSeVqT`DgWBbf>&1)TMyo{W%^qOB4Xj2H8}`=vy9q$80O8@&pvbRA$gqqw%IVeI$cAZMK|;F_b(B&yQ$b3wL%k35f9tpWOvK) z7Dba!kk+ae-4Vi~dsfVMr0^29XB26Uoh45m!thY0%JYx1w93RLUYFXA@)d~D7VI=i zzqbGQ6G%a^y~*B3*-z>MiR>qJftbZ7^>Ey=6DPCEQ)J4vJ!=j;IJ6Jbf1Hm`THuXt zn*Q@;*PW!Vk1gMST*Kc~F7559b5HN@(bCcpyC0%7+MRU3%}=@~@W90_a*yfvgv=>S zV!NvATh7pj53?I{8jV93U)^R{%vsgmHjnDU%PkZZbFjS=9dsJJk|b)Nm(|{u_w;cp z5B)KB5iLDF!0Qwxi}W>iK$K>lzl2cVb-PW5TLf^F)7IY)82uR>LQ)bmCa)3DcW_P zwX;&ASTBS_CqI*n8>(I#G2vzTi&mOleAR4_0FvM9R0c;eP6&Tqt+|;mTH?~*PSZn zo~a7H>z(XS5PV_MlyY~7@}N`9)TjNOr>fNO+Aju`^fh1FqX|PjryrfaYn>sjdgAd>EUDlZ9pzh?s%>*}|ZARMEY|G3R%r_yn$`3kQ zImxT4s_Hv9Y&m}7#0tw7N;MtgulgryPfxvj#ebS4nXc)ZB>%y1$Lljq&ZTo@S=+j5 zh5mFenpv<~iA_6ZC@;?yO6A;_dR=%(PtAuV(dx{>2(2pmq>^oG)I#**=EPogb**{h z$A9Vb>kIYG&HJxhxsvhhWq|I`q36oFoHf(!;diAJ4SHH$3%H$ayt*&_or`PiOUFR# z;TtK{)#0__a+QJ#d|V1EMY&Be{OMjR6HPhYg3D{#!@rypo9oP*VOqAt`&vf6OiT>$ zzkOSJ$ByuXSFc{i#ra&ew7kSbK>#(iLkvf*2 zzo|XkWK|fpyDv!-d&whX!#PQTb8EK=QI~AExEQ|97JU^vQ*Rf{bZ$RFElPHG&ig?Hi5FZ}wQplb32&f_M|Cu$0{D6w6!U;kYb2@~wJ;jY&frv+M1MQ$Lxf zaPr$9c{3BPm-ze4nm6&kVfKH$ALn#IPwyJz&W6xpytwT8k&-x@DaocI)mkD|N3Ch4 z`Bz_#`H4w#o?ElwoC*KME{v$+_0^T8gipmH$n3|nt=q`Ghu1OYhFV@q^$+vAN4>=V zF>6-sBWZ6E)+V&MCq6aqd183r)#896Cz)wU<;JcP+alv0y4`hq8vw3QI%l(%AWbMe9ir6XOmC%*gDxxx{A8m&R5^RUr|ZZ5iq<@D+;hw zOt#P2r#hi_a`Mab^I?Zw9!pu~KKt_QlR>EY!{F5ZaCZZ3W?a?bs~T=}FCtwjNc!Z; zYU9>T0kg{v^?bh%U!M{2n&3Q4^(wAflvoh=m7eYG-IuAUJJs=c`PQ}X0xU({R*KF_ zx8^^Xd88f!oc+AXGF|TDiy61*j-2=9k!r2)yvFBEE4^~e9o$>Zv^G5E+IEp+Q)sbG zOR>lc!E9j}2BoKG?{L|sFZ=4otsVQ{J0?#R_xr7VqSPzSos-r6b<|~6b?PsVHYLS( z@y?A{p7MrVi+BRp*ee3=mSyR@PSdGn8&VaZ@PWu_z%V^>K62RPgO@iXM`OkW?c$-9 z)1v$2h72`Q2=>or^@y75RFiqY^M;^H@YQF|Q!xX!&%b0lZ=17zJgHG??;%km;W^Sp zt1?XOZVivqUb)$H3EQQLzDf^|8)}IyEM&}>d0vzkUeR>; z^eZvL?S0xLb=7@i=f&e znqcUMyOshR!l*G+FkFG>xLU;-p5`a>aN!p*dygq8Q;XKcOiNCTAc3s zCuK!Vfmbbd6Gbz@`=uR^TFvO<<@OR)w!*lf^5^x3E=Nhi-1Nr$bYxVcmq==OB2%Ae zJ~+JM|Wwq%oUX-u7Ewr*8Q*!@&82kPcSPnwmBdzUfts%^u@Jvy_m` z*`TJd6-=-!muyi~ywp*0^TFf0RadKHR%vdxmeq-lREl}JFVDT=aU02Ata_;#Z-Arc z-Fk_NGu{^O+W1zqW@o%j4Q{t@4fWoe_|sxV&wtw(xm}Ekqt3>o0 zJkxWNI`VI~lr!E(t(;GP{rUzP8~bP2PPeS)Y6IV^Av$k;wie$UysLoIjqpw@6SE`i zM%5ZKP0jgcU6u_R?c2o&IXafU>5Ty6wzKc8&YICP{g(Ar>a;^C;y-55i-%FU;$o_% zrkkb4aYo17%dT*)mfk>7tDCG$%O?NKtiC>rFaP{@9>yoDQ2YLUAL*@Fc zvf9~GHshyO93=Voq#Nzr`lMx7Tys+O-wc)p~DA)W5AT2!A)J@Yta#d97yEiiFL}qAw;l zM14K4$9OgL(xy<@x+*i;s9QE8-(g^9V@|QxwqEVnovXJ!v76pZ(L_|Jw2H_QVm7OCDun+enudT;@01 zSKd+ee(&J1M>Io6@64a>Z{O})@mq{jeLU28f%~x;Q?_P2x3*u3PGsK88Geb^b1Hn8 zcg@eW`g)EKZu#=%UH$#i=f34(<8pFTz)x7Kn0yif2RE(Ll$O0Fygqrwh77$!hMTi2 zzj;fqw_kc8E-7}XQssSz=f{J=F#!+k4(cw;9W>0iiKmzB%RRiNw{|-AXs=kdEIKqabVuG*-i=t>^LvE$ zYTZ1nJ+;FBLg}`P7gUl0{7rBF(X{#Ore|+#RRl!&TO4Ft_U#q%_}XpIgZZf$U@5?y z;ml6s+!ML=SkY+Zw_L~Wfg*J@Aef6k*Ju5P4gQ9{H*RDYx==B<0|Qrc>hy(FRO~-% zI{YGLr+Yv1mFvKEZUK2O9S0Dvrzbr6YPL0!U)+CkFS9+5VA8~L^2}deU1-r^Abc+A zOy!W&XfwNKIGaeHkC@qeH7iocJHdp;@XXbq(4GXi z$&c*ve>LrT=~ZTU*RJmG#%5Dw#LODbzg8Zaw9Q2&lk+HO&E|PwZC`MOIH+VsC`zraH1*}Q@QTw)@^-$LDOaQ%(3=PTyIoYRXXOE| zRr5?H^IcU{&?8x+gz9k*#~76ww1#ZET0}(Tjq)bC@viQrCypFhn?+CNXrH9z2hGo4 zvzM*Xl(=)BVI*pxNCrzr>*>pvep%LE zHYDceo_7C$9j?HZah2U+Nlc_}$6VobIB#aA3EqOl6?@~nLAcyWeC0)$;jTG@-X>6@ zzgAUuTaFBHgpKs;dKNwTV`Wz8mZQ&dPT-#gC>^q}o>=u>n>V)p4d3p_g6--LqK?|x z`v0L?qnL1w=GlaANJ$!uVl?cTZ{hQ~cB&!P*x2}+!CzIXV9T|0KJCQFo8IJ}ZRP6Q zW4^wx_LuaI(MTl4#g8c-x+Zkt`Q|@MTXK&*QNEqf$nZ;Avx(gJTrMu4%k(a;3+arW z7P3B6=t!9yi8qPDb!ixB>PxK_5V#JKXIq{4vM{k0!{hrOu6}-w_vEo- zw{in*AAldN{_LSLwZ%^wWE?hFh|9W08rY$+5XarbU&JEAOD6MFQzN^l+s`C>4COc< zVU%6)-&g9x8~eCT_m9k0?<407|MKW|-B>Mj$nB6;ZS8=9Q|z@>!AMt@B^KX%FFL=GF_%F3!#Z?UT7VIr?^XsTSGi z->rI`ogKfFOW@XAVDC;YF0KyS+NXQZ4VQlXY7}wXKDZZi^5jX8trmPx(-OPgQnmU= zr6`@oW!71q^G|1{opuEJ@G8WdZp->Zut!^Ud1Hq9Sq>#Z?q`ZT-hH1&yqr9H_is10 z-RJho@WuHg#n0OH7Oi!KmnIa=EZ#qm-U{Bn7B80(iqG+Vm3iz!b9QFtYNef1vc?6c z`u0|BmXUd@^tH9sP;F2*RNkw#wbi1n;Oeckd2#;l6;MD50>uJ(7&ssZB{B zZMG4nIJP-3*AJ(7R*CFXs=v`wl@a&A0=Myia(v6s8YindWd568oYSE1!TBD3+xgOw z`2O?HR$EJ_uE&4TJ-;nk`LT|OOioQyQBl!TN=Zq{9`seFVy36hJksjr<#kSsW{AV# zVh(?;OH53>!2l>$$6rhfWtS1d=L9Gf0@jJ7dbiQ_^pTFqx|R^khzJki z;%gzs&Jr56zy(%d8*>!Y?`Q>(`g~6WToo&~tqD|H zLr4T8NR15~EpBKT{d4YX`G#b1o6Qs7=7_O`ImYS369?Tk>MA}9OI+g=>wqxlEX?QU z@gg4A;vTZgoAKFOaVB zjJ08B#fPsEPj_2M%d|wiHuE_$-Qwl+qVXY88@nZ?7yQ#dGmu%V&G$C4vU1wZT1g%ycet$s}6&ZdPR1%*qW{uCj4 zs+~44xE~xG+&t4?$G^CGbnPI6pp|YSre1thk~x{Xb7_mtZF>0UT~w{h;-4_kHG}pmv=iYJ})S2_58DUC|hK@|7)ZVo*+B*EVw30C_Crk zE;Gy0W=OLUmktQYogoMn`9uLbGz$rm11GmbF^TyHkF zH5>fpNhw-y#K>5CfRSVI&^bx|4C60Sx7=mI>%yZ#uOiI_;KIs%XV4`08m{Je6{hRM zc+Yy7Z>61Q-j0f9GJTaVm*WL2Um-QpM#V)7{{b@)QngkvBO!F?5J?T@D0s~os##&c7_DVEOd#x)CbA|f-zlV@7p zv@#p4q(_M<&q;RLALdg!&ukOTYAzr3vl@5TZOyN~lxC$cy6{@yqriJ^xc!~F@6rBf zmN0+%O9Nn&>mlrYbINbKDT~-UVQy$#(S6c;W^YU zvg=gwwM(|D0-Og(nxyV+dtP79&91M>6mKyI_O@|QpSm;agW?-Cx42lEQ;2`zBd;`e WpR~EwXwr%Dvoe_sVqvl>=KlcmO-tSY literal 0 HcmV?d00001 diff --git a/configure b/configure index 80a528f94a4c8..37a5a42dca669 100755 --- a/configure +++ b/configure @@ -21791,6 +21791,20 @@ $as_echo "#define SDL_VIDEO_DRIVER_HAIKU 1" >>confdefs.h fi } +CheckAmigaOS4Video() +{ + if test x$enable_video = xyes; then + +$as_echo "#define SDL_VIDEO_DRIVER_AMIGAOS4 1" >>confdefs.h +$as_echo "#define SDL_VIDEO_RENDER_AMIGAOS4 1" >> confdefs.h + + SOURCES="$SOURCES $srcdir/src/video/amigaos4/*.c" + + have_video=yes + SUMMARY_video="${SUMMARY_video} amigaos4" + fi +} + CheckCOCOA() { # Check whether --enable-video-cocoa was given. @@ -22633,6 +22647,66 @@ $as_echo "#define SDL_VIDEO_RENDER_OGL 1" >>confdefs.h fi } +CheckAmigaOS4GL() +{ + if test x$enable_video = xyes -a x$enable_video_opengl = xyes; then + +$as_echo "#define SDL_VIDEO_OPENGL 1" >>confdefs.h + + +$as_echo "#define SDL_VIDEO_OPENGL_AMIGAOS4 1" >>confdefs.h + + +$as_echo "#define SDL_VIDEO_RENDER_OGL 1" >>confdefs.h + +# EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lGL -lGLU" + + SUMMARY_video="${SUMMARY_video} opengl" + fi +} + +CheckAmigaOS4GLES2() +{ + if test x$enable_video = xyes -a x$enable_video_opengles = xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OpenGL ES v2 headers" >&5 +$as_echo_n "checking for OpenGL ES v2 headers... " >&6; } + video_opengles_v2=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + #include + #include + +int +main () +{ + + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + video_opengles_v2=yes + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $video_opengles_v2" >&5 +$as_echo "$video_opengles_v2" >&6; } + if test x$video_opengles_v2 = xyes; then + +$as_echo "#define SDL_VIDEO_OPENGL_ES2 1" >>confdefs.h + + +$as_echo "#define SDL_VIDEO_RENDER_OGL_ES2 1" >>confdefs.h + + SUMMARY_video="${SUMMARY_video} opengl_es2" + fi + fi +} + CheckMacGL() { if test x$enable_video = xyes -a x$enable_video_opengl = xyes; then @@ -25444,6 +25518,82 @@ $as_echo "#define SDL_FILESYSTEM_HAIKU 1" >>confdefs.h SOURCES="$srcdir/src/main/haiku/*.cc $SOURCES" EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lroot -lbe -lmedia -lgame -ldevice -ltextencoding" ;; + + *-*-amigaos*) + ARCH=amigaos4 + ac_default_prefix=/progdir + CheckDummyVideo + CheckDummyAudio + CheckAmigaOS4Video + CheckAmigaOS4GL + CheckAmigaOS4GLES2 + #CheckDLOPEN + CheckPTHREAD + + # Set up files for the thread library +# if test x$enable_threads = xyes; then +# +#$as_echo "#define SDL_THREAD_AMIGAOS4 1" >>confdefs.h +# +# SOURCES="$SOURCES $srcdir/src/thread/amigaos4/*.c" +# have_threads=yes +# fi + # Set up files for the audio library + if test x$enable_audio = xyes; then + SUMMARY_audio="${SUMMARY_audio} amigaos4" +$as_echo "#define SDL_AUDIO_DRIVER_AMIGAOS4 1" >>confdefs.h + + SOURCES="$SOURCES $srcdir/src/audio/amigaos4/*.c" + have_audio=yes + fi + # Set up files for the joystick library + if test x$enable_joystick = xyes; then + +$as_echo "#define SDL_JOYSTICK_AMIGAINPUT 1" >>confdefs.h + SUMMARY_input="${SUMMARY_input} amigainput" + SOURCES="$SOURCES $srcdir/src/joystick/amigaos4/*.c" + have_joystick=yes + fi + # Set up files for the timer library +# if test x$enable_timers = xyes; then +# +#$as_echo "#define SDL_TIMER_AMIGAOS4 1" >>confdefs.h +# +# SOURCES="$SOURCES $srcdir/src/timer/amigaos4/*.c" +# have_timers=yes +# fi + if test x$enable_timers = xyes; then + +$as_echo "#define SDL_TIMER_UNIX 1" >>confdefs.h + + SOURCES="$SOURCES $srcdir/src/timer/unix/*.c" + have_timers=yes + fi + # Set up files for the system filesystem library + if test x$enable_filesystem = xyes; then + +$as_echo "#define SDL_FILESYSTEM_AMIGAOS4 1" >>confdefs.h + + SOURCES="$SOURCES $srcdir/src/filesystem/amigaos4/*.c" + have_filesystem=yes + fi + + # Set up files for the shared object loading library + if test x$enable_loadso = xyes; then + +$as_echo "#define SDL_LOADSO_AMIGAOS4 1" >>confdefs.h + + SOURCES="$SOURCES $srcdir/src/loadso/amigaos4/*.c" + have_loadso=yes + fi + + # The AmigaOS4 platform requires special setup. + SOURCES="$srcdir/src/main/amigaos4/*.c $SOURCES" + #EXTRA_LDFLAGS="-use-dynld -Wl,-export-dynamic -Wl,-no-undefined $EXTRA_LDFLAGS -ldl" + EXTRA_LDFLAGS="-lpthread" + + EXTRA_CFLAGS="$EXTRA_CFLAGS -mstrict-align" + ;; *-ios-*) ARCH=ios @@ -25984,9 +26134,8 @@ fi SDL_STATIC_LIBS="$EXTRA_LDFLAGS" - - - +# AmigaOS4 hack! This is only to pass "-use-dynld" for sdl2-config +SDL_LIBS="-use-dynld $SDL_LIBS $EXTRA_LDFLAGS" if test x$enable_shared = xyes; then PKGCONFIG_LIBS_PRIV=" diff --git a/configure.ac b/configure.ac index 6ec90c4a87557..3722f355ac12c 100644 --- a/configure.ac +++ b/configure.ac @@ -2075,6 +2075,18 @@ CheckHaikuVideo() fi } +dnl Set up the AmigaOS video driver if enabled +CheckAmigaOS4Video() +{ + if test x$enable_video = xyes; then + AC_DEFINE(SDL_VIDEO_DRIVER_AMIGAOS4, 1, [ ]) + AC_DEFINE(SDL_VIDEO_RENDER_AMIGAOS4, 1, [ ]) + SOURCES="$SOURCES $srcdir/src/video/amigaos4/*.c" + have_video=yes + SUMMARY_video="${SUMMARY_video} amigaos4" + fi +} + dnl Set up the Cocoa video driver for Mac OS X (but not Darwin) CheckCOCOA() { @@ -2447,6 +2459,40 @@ CheckHaikuGL() fi } +dnl Check for AmigaOS4 OpenGL +CheckAmigaOS4GL() +{ + if test x$enable_video = xyes -a x$enable_video_opengl = xyes; then + AC_DEFINE(SDL_VIDEO_OPENGL, 1, [ ]) + AC_DEFINE(SDL_VIDEO_OPENGL_AMIGAOS4, 1, [ ]) + AC_DEFINE(SDL_VIDEO_RENDER_OGL, 1, [ ]) + #EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lGL -lGLU" + SUMMARY_video="${SUMMARY_video} opengl" + fi +} + +CheckAmigaOS4GLES() +{ + if test x$enable_video = xyes -a x$enable_video_opengles = xyes; then + AC_MSG_CHECKING(for OpenGL ES v2 headers) + video_opengles_v2=no + AC_TRY_COMPILE([ + #include + #include + #include + ],[ + ],[ + video_opengles_v2=yes + ]) + AC_MSG_RESULT($video_opengles_v2) + if test x$video_opengles_v2 = xyes; then + AC_DEFINE(SDL_VIDEO_OPENGL_ES2, 1, [ ]) + AC_DEFINE(SDL_VIDEO_RENDER_OGL_ES2, 1, [ ]) + SUMMARY_video="${SUMMARY_video} opengl_es2" + fi + fi +} + dnl Check for MacOS OpenGL CheckMacGL() { @@ -3948,6 +3994,66 @@ case "$host" in SOURCES="$srcdir/src/main/haiku/*.cc $SOURCES" EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lroot -lbe -lmedia -lgame -ldevice -ltextencoding" ;; + *-*-amigaos*) + ARCH=amigaos4 + ac_default_prefix=/progdir + CheckDummyVideo + CheckDummyAudio + CheckAmigaOS4Video + CheckAmigaOS4GL + CheckAmigaOS4GLES + #CheckDLOPEN + CheckPTHREAD + + # Set up files for the thread library +# if test x$enable_threads = xyes; then +# AC_DEFINE(SDL_THREAD_AMIGAOS4, 1, [ ]) +# SOURCES="$SOURCES $srcdir/src/thread/amigaos4/*.c" +# have_threads=yes +# fi + # Set up files for the audio library + if test x$enable_audio = xyes; then + SUMMARY_audio="${SUMMARY_audio} amigaos4" + AC_DEFINE(SDL_AUDIO_DRIVER_AMIGAOS4, 1, [ ]) + SOURCES="$SOURCES $srcdir/src/audio/amigaos4/*.c" + have_audio=yes + fi + # Set up files for the joystick library + if test x$enable_joystick = xyes; then + SUMMARY_input="${SUMMARY_input} amigainput" + AC_DEFINE(SDL_JOYSTICK_AMIGAINPUT, 1, [ ]) + SOURCES="$SOURCES $srcdir/src/joystick/amigaos4/*.c" + have_joystick=yes + fi + # Set up files for the timer library +# if test x$enable_timers = xyes; then +# AC_DEFINE(SDL_TIMER_AMIGAOS4, 1, [ ]) +# SOURCES="$SOURCES $srcdir/src/timer/amigaos4/*.c" +# have_timers=yes +# fi + if test x$enable_timers = xyes; then + AC_DEFINE(SDL_TIMER_UNIX, 1, [ ]) + SOURCES="$SOURCES $srcdir/src/timer/unix/*.c" + have_timers=yes + fi + # Set up files for the system filesystem library + if test x$enable_filesystem = xyes; then + AC_DEFINE(SDL_FILESYSTEM_AMIGAOS4, 1, [ ]) + SOURCES="$SOURCES $srcdir/src/filesystem/amigaos4/*.c" + have_filesystem=yes + fi + # Set up files for the shared object loading library + if test x$enable_loadso = xyes; then + AC_DEFINE(SDL_LOADSO_AMIGAOS4, 1, [ ]) + SOURCES="$SOURCES $srcdir/src/loadso/amigaos4/*.c" + have_loadso=yes + fi + # The AmigaOS4 platform requires special setup. + SOURCES="$srcdir/src/main/amigaos4/*.c $SOURCES" + #EXTRA_LDFLAGS="-use-dynld -Wl,-export-dynamic -Wl,-no-undefined $EXTRA_LDFLAGS -ldl" + EXTRA_LDFLAGS="" + EXTRA_CFLAGS="$EXTRA_CFLAGS -mstrict-align" + ;; *-ios-*) ARCH=ios @@ -4398,6 +4504,9 @@ fi SDL_STATIC_LIBS="$EXTRA_LDFLAGS" +# AmigaOS4 hack! This is only to pass "-use-dynld" for sdl2-config +SDL_LIBS="-use-dynld $SDL_LIBS" + dnl Expand the cflags and libraries needed by apps using SDL AC_SUBST(SDL_CFLAGS) AC_SUBST(SDL_LIBS) diff --git a/docs/README-amigaos4.md b/docs/README-amigaos4.md new file mode 100755 index 0000000000000..d39d668433880 --- /dev/null +++ b/docs/README-amigaos4.md @@ -0,0 +1,174 @@ +================================================================================ +SDL 2.0 requirements +================================================================================ + +AmigaOS 4.1 Final Edition +MiniGL (optional from SDL2 point of view, but OpenGL context might still be + required by the SDL2 application) +OpenGL ES 2.0 (optional) + +================================================================================ +Building SDL 2.0 library +================================================================================ + + gmake -f Makefile.amigaos4 + + At the moment configure script and CMake are not supported. + +================================================================================ +Using SDL 2.0 in your projects +================================================================================ + + #include "SDL2/SDL.h" + ...do magical SDL2 things... + + + gcc helloworld.c -use-dynld -lSDL2 + +================================================================================ +About SDL_Renderers +================================================================================ + +A renderer is a subsystem that can do 2D drawing. There are 4 renderers: +software, OpenGL, OpenGL ES 2.0 and compositing. + +Software renderer is always available. Pixels are plotted by the CPU so this is +usually a slow option. + +OpenGL renderer uses MiniGL (and Warp3D) for accelerated drawing. Drawing is +done in immediate mode. This should be fairly fast if textures are static. + +OpenGL ES 2.0 renderer uses ogles2.library (and Warp3D Nova). + +Compositing renderer uses AmigaOS 4 graphics.library for accelerated drawing. +However, blended lines and points are not accelerated since compositing doesn't +support them. Compositing renderer supports only 32-bit bitmaps. If (Workbench) +screen mode is 16-bit, color format conversion can slow things down. + +It's possible to select the preferred renderer before its creation, like this: + + SDL_SetHint(SDL_HINT_RENDER_DRIVER, name); + +where name is "software", "opengl" or "compositing". + +It's possible to enable VSYNC with: + + SDL_SetHint(SDL_HINT_RENDER_VSYNC, "1"); + +There is a benchmark tool called sdl2benchmark which was written to test +available renderers. + +================================================================================ +About ENV variables +================================================================================ + +Advanced users may use ENV variables to control some things in SDL2. +Some variables supported by the SDL_Renderer subsystem: + +Batch drawing: + +setenv SDL_RENDER_BATCHING 1 # Enable +setenv SDL_RENDER_BATCHING 0 # Disable + +Driver selection: + +setenv SDL_RENDER_DRIVER "software" +setenv SDL_RENDER_DRIVER "compositing" +setenv SDL_RENDER_DRIVER "opengl" + +VSYNC: + +setenv SDL_RENDER_VSYNC 1 # Enable +setenv SDL_RENDER_VSYNC 0 # Disable + +It must be noted that these variables apply only to those applications that +actually use the SDL_Renderer subsystem, and not 3D games. + +================================================================================ +About OpenGL +================================================================================ + +If you want to draw accelerated 3D graphics or use explicitly OpenGL functions, +you have to create an OpenGL context, instead of an SDL_Renderer. + +If you would like to create an OpenGL ES 2.0 context, you need to specify the +version before window creation, for example: + + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); + +MiniGL context can be created using major version 1 and minor version 3. This is +also the default setup. + + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); + +================================================================================ +About Joysticks +================================================================================ + +Joysticks that are compatible with AmigaInput can be used with SDL2. In addition +to legacy joystick API, SDL supports new game controller API which uses a +predefined database to map joystick axes and buttons. At the moment +game controller database contains the following entries: + +- Speedlink Competition Pro +- Ewent Joypad EW3170 +- PS2 Joystick (USB adaptor) +- SHARK 91230 Joystick +- MAGIC-NS +- Wireless Controller +- 8Bitdo SN30 Pro +- Thrustmaster dual analog 3.2 +- XEOX Gamepad SL-6556-BK +- Strike2 Joystick +- GeeekPi_A gamepad +- Logitech Cordless RumblePad 2 +- Logitech RumblePad 2 USB +- Logitech(R) Precision(TM) Gamepad + +Joysticks can be tested using testjoystick tool. New game controller mappings +can be generated using controllermap tool. New mappings can be then added to +the game controller database. + +================================================================================ +WinUAE +================================================================================ + +Because WinUAE doesn't support hardware-accelerated compositing or 3D, you need +to install the following software: + +- http://os4depot.net/index.php?function=showfile&file=graphics/misc/patchcompositetags.lha +- http://os4depot.net/index.php?function=showfile&file=library/graphics/wazp3d.lha + +================================================================================ +Tips +================================================================================ + +If you are already familiar with SDL 1.2, or porting SDL 1.2 code, it's worth +checking the migration guide at: + +https://wiki.libsdl.org/MigrationGuide + +Always check the return values of functions and in error case you can get more +information using SDL_GetError() function! + +================================================================================ +Limitations +================================================================================ + +Altivec support is disabled. It should be possible to enable in private builds +but it hasn't been tested so far. + +Unsupported subsystems include Haptic and Power. There is no Vulkan backend for +AmigaOS either. + +OpenGL renderer doesn't support render targets and blend modes "ADD" or "MOD". +This is due to missing features in MiniGL. + +================================================================================ +Project page and bug tracker +================================================================================ + +https://github.com/AmigaPorts/SDL diff --git a/include/SDL_config.h.cmake b/include/SDL_config.h.cmake index 0446547e0e497..f097f8e17e447 100644 --- a/include/SDL_config.h.cmake +++ b/include/SDL_config.h.cmake @@ -268,6 +268,7 @@ #cmakedefine SDL_AUDIO_DRIVER_AAUDIO @SDL_AUDIO_DRIVER_AAUDIO@ #cmakedefine SDL_AUDIO_DRIVER_ARTS @SDL_AUDIO_DRIVER_ARTS@ #cmakedefine SDL_AUDIO_DRIVER_ARTS_DYNAMIC @SDL_AUDIO_DRIVER_ARTS_DYNAMIC@ +#cmakedefine SDL_AUDIO_DRIVER_AMIGAOS4 @SDL_AUDIO_DRIVER_AMIGAOS4@ #cmakedefine SDL_AUDIO_DRIVER_COREAUDIO @SDL_AUDIO_DRIVER_COREAUDIO@ #cmakedefine SDL_AUDIO_DRIVER_DISK @SDL_AUDIO_DRIVER_DISK@ #cmakedefine SDL_AUDIO_DRIVER_DSOUND @SDL_AUDIO_DRIVER_DSOUND@ @@ -304,6 +305,7 @@ #cmakedefine SDL_INPUT_LINUXKD @SDL_INPUT_LINUXKD@ #cmakedefine SDL_JOYSTICK_ANDROID @SDL_JOYSTICK_ANDROID@ #cmakedefine SDL_JOYSTICK_HAIKU @SDL_JOYSTICK_HAIKU@ +#cmakedefine SDL_JOYSTICK_AMIGAINPUT @SDL_JOYSTICK_AMIGAINPUT@ #cmakedefine SDL_JOYSTICK_DINPUT @SDL_JOYSTICK_DINPUT@ #cmakedefine SDL_JOYSTICK_XINPUT @SDL_JOYSTICK_XINPUT@ #cmakedefine SDL_JOYSTICK_DUMMY @SDL_JOYSTICK_DUMMY@ @@ -338,6 +340,7 @@ #cmakedefine SDL_LOADSO_DUMMY @SDL_LOADSO_DUMMY@ #cmakedefine SDL_LOADSO_LDG @SDL_LOADSO_LDG@ #cmakedefine SDL_LOADSO_WINDOWS @SDL_LOADSO_WINDOWS@ +#cmakedefine SDL_LOADSO_AMIGAOS4 @SDL_LOADSO_AMIGAOS4@ #cmakedefine SDL_LOADSO_OS2 @SDL_LOADSO_OS2@ /* Enable various threading systems */ @@ -346,6 +349,7 @@ #cmakedefine SDL_THREAD_PTHREAD_RECURSIVE_MUTEX @SDL_THREAD_PTHREAD_RECURSIVE_MUTEX@ #cmakedefine SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP @SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP@ #cmakedefine SDL_THREAD_WINDOWS @SDL_THREAD_WINDOWS@ +#cmakedefine SDL_THREAD_AMIGAOS4 @SDL_THREAD_AMIGAOS4@ #cmakedefine SDL_THREAD_OS2 @SDL_THREAD_OS2@ #cmakedefine SDL_THREAD_VITA @SDL_THREAD_VITA@ @@ -354,6 +358,7 @@ #cmakedefine SDL_TIMER_DUMMY @SDL_TIMER_DUMMY@ #cmakedefine SDL_TIMER_UNIX @SDL_TIMER_UNIX@ #cmakedefine SDL_TIMER_WINDOWS @SDL_TIMER_WINDOWS@ +#cmakedefine SDL_TIMER_AMIGAOS4 @SDL_TIMER_AMIGAOS4@ #cmakedefine SDL_TIMER_OS2 @SDL_TIMER_OS2@ #cmakedefine SDL_TIMER_VITA @SDL_TIMER_VITA@ @@ -361,6 +366,7 @@ #cmakedefine SDL_VIDEO_DRIVER_ANDROID @SDL_VIDEO_DRIVER_ANDROID@ #cmakedefine SDL_VIDEO_DRIVER_EMSCRIPTEN @SDL_VIDEO_DRIVER_EMSCRIPTEN@ #cmakedefine SDL_VIDEO_DRIVER_HAIKU @SDL_VIDEO_DRIVER_HAIKU@ +#cmakedefine SDL_VIDEO_DRIVER_AMIGAOS4 @SDL_VIDEO_DRIVER_AMIGAOS4@ #cmakedefine SDL_VIDEO_DRIVER_COCOA @SDL_VIDEO_DRIVER_COCOA@ #cmakedefine SDL_VIDEO_DRIVER_UIKIT @SDL_VIDEO_DRIVER_UIKIT@ #cmakedefine SDL_VIDEO_DRIVER_DIRECTFB @SDL_VIDEO_DRIVER_DIRECTFB@ @@ -417,6 +423,7 @@ #cmakedefine SDL_VIDEO_RENDER_DIRECTFB @SDL_VIDEO_RENDER_DIRECTFB@ #cmakedefine SDL_VIDEO_RENDER_METAL @SDL_VIDEO_RENDER_METAL@ #cmakedefine SDL_VIDEO_RENDER_VITA_GXM @SDL_VIDEO_RENDER_VITA_GXM@ +#cmakedefine SDL_VIDEO_RENDER_AMIGAOS4 @SDL_VIDEO_RENDER_AMIGAOS4@ /* Enable OpenGL support */ #cmakedefine SDL_VIDEO_OPENGL @SDL_VIDEO_OPENGL@ @@ -455,6 +462,7 @@ #cmakedefine SDL_FILESYSTEM_DUMMY @SDL_FILESYSTEM_DUMMY@ #cmakedefine SDL_FILESYSTEM_UNIX @SDL_FILESYSTEM_UNIX@ #cmakedefine SDL_FILESYSTEM_WINDOWS @SDL_FILESYSTEM_WINDOWS@ +#cmakedefine SDL_FILESYSTEM_AMIGAOS4 @SDL_FILESYSTEM_AMIGAOS4@ #cmakedefine SDL_FILESYSTEM_EMSCRIPTEN @SDL_FILESYSTEM_EMSCRIPTEN@ #cmakedefine SDL_FILESYSTEM_OS2 @SDL_FILESYSTEM_OS2@ #cmakedefine SDL_FILESYSTEM_VITA @SDL_FILESYSTEM_VITA@ diff --git a/include/SDL_config.h.in b/include/SDL_config.h.in index 9ddd932e3779f..b2d3c92107fcb 100644 --- a/include/SDL_config.h.in +++ b/include/SDL_config.h.in @@ -265,6 +265,7 @@ #undef SDL_AUDIO_DRIVER_ANDROID #undef SDL_AUDIO_DRIVER_ARTS #undef SDL_AUDIO_DRIVER_ARTS_DYNAMIC +#undef SDL_AUDIO_DRIVER_AMIGAOS4 #undef SDL_AUDIO_DRIVER_COREAUDIO #undef SDL_AUDIO_DRIVER_DISK #undef SDL_AUDIO_DRIVER_DSOUND @@ -302,6 +303,7 @@ #undef SDL_INPUT_LINUXKD #undef SDL_INPUT_WSCONS #undef SDL_JOYSTICK_HAIKU +#undef SDL_JOYSTICK_AMIGAINPUT #undef SDL_JOYSTICK_DINPUT #undef SDL_JOYSTICK_XINPUT #undef SDL_JOYSTICK_DUMMY @@ -335,6 +337,7 @@ #undef SDL_LOADSO_DUMMY #undef SDL_LOADSO_LDG #undef SDL_LOADSO_WINDOWS +#undef SDL_LOADSO_AMIGAOS4 #undef SDL_LOADSO_OS2 /* Enable various threading systems */ @@ -343,10 +346,12 @@ #undef SDL_THREAD_PTHREAD_RECURSIVE_MUTEX #undef SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP #undef SDL_THREAD_WINDOWS +#undef SDL_THREAD_AMIGAOS4 #undef SDL_THREAD_OS2 /* Enable various timer systems */ #undef SDL_TIMER_HAIKU +#undef SDL_TIMER_AMIGAOS4 #undef SDL_TIMER_DUMMY #undef SDL_TIMER_UNIX #undef SDL_TIMER_WINDOWS @@ -354,6 +359,7 @@ /* Enable various video drivers */ #undef SDL_VIDEO_DRIVER_HAIKU +#undef SDL_VIDEO_DRIVER_AMIGAOS4 #undef SDL_VIDEO_DRIVER_COCOA #undef SDL_VIDEO_DRIVER_DIRECTFB #undef SDL_VIDEO_DRIVER_DIRECTFB_DYNAMIC @@ -405,6 +411,7 @@ #undef SDL_VIDEO_RENDER_OGL_ES2 #undef SDL_VIDEO_RENDER_DIRECTFB #undef SDL_VIDEO_RENDER_METAL +#undef SDL_VIDEO_RENDER_AMIGAOS4 /* Enable OpenGL support */ #undef SDL_VIDEO_OPENGL @@ -439,6 +446,7 @@ #undef SDL_FILESYSTEM_DUMMY #undef SDL_FILESYSTEM_UNIX #undef SDL_FILESYSTEM_WINDOWS +#undef SDL_FILESYSTEM_AMIGAOS4 #undef SDL_FILESYSTEM_NACL #undef SDL_FILESYSTEM_ANDROID #undef SDL_FILESYSTEM_EMSCRIPTEN diff --git a/include/SDL_config_amigaos4.h b/include/SDL_config_amigaos4.h new file mode 100644 index 0000000000000..7ca9681cd6298 --- /dev/null +++ b/include/SDL_config_amigaos4.h @@ -0,0 +1,403 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_config_amigaos4_h_ +#define SDL_config_amigaos4_h_ +#define SDL_config_h_ + +/* This is a set of defines to configure the SDL features */ + +/* General platform specific identifiers */ +#include "SDL_platform.h" + +/* C datatypes */ +#ifdef __LP64__ +#define SIZEOF_VOIDP 8 +#else +#define SIZEOF_VOIDP 4 +#endif +#define HAVE_GCC_ATOMICS 1 +/* #undef HAVE_GCC_SYNC_LOCK_TEST_AND_SET */ + +/* Useful headers */ +#define STDC_HEADERS 1 +#define HAVE_ALLOCA_H 1 +#define HAVE_CTYPE_H 1 +#define HAVE_FLOAT_H 1 +#define HAVE_ICONV_H 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_MALLOC_H 1 +#define HAVE_MATH_H 1 +/* #undef HAVE_MEMORY_H */ +#define HAVE_SIGNAL_H 1 +#define HAVE_STDARG_H 1 +#define HAVE_STDINT_H 1 +#define HAVE_STDIO_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STRINGS_H 1 +#define HAVE_STRING_H 1 +#define HAVE_SYS_TYPES_H 1 +#define HAVE_WCHAR_H 1 +/* #undef HAVE_PTHREAD_NP_H */ +/* #undef HAVE_LIBUNWIND_H */ + +/* C library functions */ +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#ifndef __WIN32__ /* Don't use C runtime versions of these on Windows */ +#define HAVE_GETENV 1 +#define HAVE_SETENV 1 +#define HAVE_PUTENV 1 +/* #undef HAVE_UNSETENV */ +#endif +#define HAVE_QSORT 1 +#define HAVE_ABS 1 +#define HAVE_BCOPY 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +/* #undef HAVE_MEMCMP */ +#define HAVE_WCSLEN 1 +/* #undef HAVE_WCSLCPY */ +/* #undef HAVE_WCSLCAT */ +#define HAVE_WCSCMP 1 +#define HAVE_STRLEN 1 +#define HAVE_STRLCPY 1 +#define HAVE_STRLCAT 1 +/* #undef HAVE__STRREV */ +/* #undef HAVE__STRUPR */ +/* #undef HAVE__STRLWR */ +/* #undef HAVE_INDEX */ +/* #undef HAVE_RINDEX */ +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +/* #undef HAVE_ITOA */ +/* #undef HAVE__LTOA */ +/* #undef HAVE__UITOA */ +/* #undef HAVE__ULTOA */ +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +/* #undef HAVE__I64TOA */ +/* #undef HAVE__UI64TOA */ +#define HAVE_STRTOLL 1 +#define HAVE_STRTOULL 1 +/* #undef HAVE_STRTOD */ +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +/* #undef HAVE__STRICMP */ +#define HAVE_STRCASECMP 1 +/* #undef HAVE__STRNICMP */ +#define HAVE_STRNCASECMP 1 +/* #undef HAVE_SSCANF */ +#define HAVE_VSSCANF 1 +/* #undef HAVE_SNPRINTF */ +#define HAVE_VSNPRINTF 1 +#define HAVE_M_PI /**/ +#define HAVE_ACOS 1 +#define HAVE_ACOSF 1 +#define HAVE_ASIN 1 +#define HAVE_ASINF 1 +#define HAVE_ATAN 1 +#define HAVE_ATANF 1 +#define HAVE_ATAN2 1 +#define HAVE_ATAN2F 1 +#define HAVE_CEIL 1 +#define HAVE_CEILF 1 +#define HAVE_COPYSIGN 1 +#define HAVE_COPYSIGNF 1 +#define HAVE_COS 1 +#define HAVE_COSF 1 +#define HAVE_EXP 1 +#define HAVE_EXPF 1 +#define HAVE_FABS 1 +#define HAVE_FABSF 1 +#define HAVE_FLOOR 1 +#define HAVE_FLOORF 1 +#define HAVE_FMOD 1 +#define HAVE_FMODF 1 +#define HAVE_LOG 1 +#define HAVE_LOGF 1 +#define HAVE_LOG10 1 +#define HAVE_LOG10F 1 +#define HAVE_POW 1 +#define HAVE_POWF 1 +#define HAVE_SCALBN 1 +#define HAVE_SCALBNF 1 +#define HAVE_SIN 1 +#define HAVE_SINF 1 +#define HAVE_SQRT 1 +#define HAVE_SQRTF 1 +#define HAVE_TAN 1 +#define HAVE_TANF 1 +#define HAVE_FOPEN64 1 +#define HAVE_FSEEKO 1 +#define HAVE_FSEEKO64 1 +/* #undef HAVE_SIGACTION */ +/* #undef HAVE_SA_SIGACTION */ +#define HAVE_SETJMP 1 +/* #undef HAVE_NANOSLEEP */ +/* #undef HAVE_SYSCONF */ +/* #undef HAVE_SYSCTLBYNAME */ +/* #undef HAVE_CLOCK_GETTIME */ +/* #undef HAVE_GETPAGESIZE */ +/* #undef HAVE_MPROTECT */ +#define HAVE_ICONV 1 +/* #undef HAVE_PTHREAD_SETNAME_NP */ +/* #undef HAVE_PTHREAD_SET_NAME_NP */ +/* #undef HAVE_SEM_TIMEDWAIT */ +/* #undef HAVE_GETAUXVAL */ +/* #undef HAVE_POLL */ + + +/*#define HAVE_ALTIVEC_H 1*/ +/* #undef HAVE_DBUS_DBUS_H */ +/* #undef HAVE_FCITX_FRONTEND_H */ +/* #undef HAVE_IBUS_IBUS_H */ +/* #undef HAVE_IMMINTRIN_H */ +/* #undef HAVE_LIBSAMPLERATE_H */ +/* #undef HAVE_LIBUDEV_H */ + +/* #undef HAVE_DDRAW_H */ +/* #undef HAVE_DINPUT_H */ +/* #undef HAVE_DSOUND_H */ +/* #undef HAVE_DXGI_H */ +/* #undef HAVE_XINPUT_H */ +/* #undef HAVE_ENDPOINTVOLUME_H */ +/* #undef HAVE_MMDEVICEAPI_H */ +/* #undef HAVE_AUDIOCLIENT_H */ +/* #undef HAVE_XINPUT_GAMEPAD_EX */ +/* #undef HAVE_XINPUT_STATE_EX */ + +/* SDL internal assertion support */ +/* #undef SDL_DEFAULT_ASSERT_LEVEL */ + +/* Allow disabling of core subsystems */ +/* #undef SDL_ATOMIC_DISABLED */ +/* #undef SDL_AUDIO_DISABLED */ +/* #undef SDL_CPUINFO_DISABLED */ +/* #undef SDL_EVENTS_DISABLED */ +/* #undef SDL_FILE_DISABLED */ +/* #undef SDL_JOYSTICK_DISABLED */ +/* #undef SDL_HAPTIC_DISABLED */ +/* #undef SDL_SENSOR_DISABLED */ +/* #undef SDL_LOADSO_DISABLED */ +/* #undef SDL_RENDER_DISABLED */ +/* #undef SDL_THREADS_DISABLED */ +/* #undef SDL_TIMERS_DISABLED */ +/* #undef SDL_VIDEO_DISABLED */ +/* #undef SDL_POWER_DISABLED */ +/* #undef SDL_FILESYSTEM_DISABLED */ + +/* Enable various audio drivers */ +/* #undef SDL_AUDIO_DRIVER_ALSA */ +/* #undef SDL_AUDIO_DRIVER_ALSA_DYNAMIC */ +/* #undef SDL_AUDIO_DRIVER_ANDROID */ +/* #undef SDL_AUDIO_DRIVER_ARTS */ +/* #undef SDL_AUDIO_DRIVER_ARTS_DYNAMIC */ +#define SDL_AUDIO_DRIVER_AMIGAOS4 1 +/* #undef SDL_AUDIO_DRIVER_COREAUDIO */ +/* #undef SDL_AUDIO_DRIVER_DISK */ +/* #undef SDL_AUDIO_DRIVER_DSOUND */ +#define SDL_AUDIO_DRIVER_DUMMY 1 +/* #undef SDL_AUDIO_DRIVER_EMSCRIPTEN */ +/* #undef SDL_AUDIO_DRIVER_ESD */ +/* #undef SDL_AUDIO_DRIVER_ESD_DYNAMIC */ +/* #undef SDL_AUDIO_DRIVER_FUSIONSOUND */ +/* #undef SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC */ +/* #undef SDL_AUDIO_DRIVER_HAIKU */ +/* #undef SDL_AUDIO_DRIVER_JACK */ +/* #undef SDL_AUDIO_DRIVER_JACK_DYNAMIC */ +/* #undef SDL_AUDIO_DRIVER_NACL */ +/* #undef SDL_AUDIO_DRIVER_NAS */ +/* #undef SDL_AUDIO_DRIVER_NAS_DYNAMIC */ +/* #undef SDL_AUDIO_DRIVER_NETBSD */ +/* #undef SDL_AUDIO_DRIVER_OSS */ +/* #undef SDL_AUDIO_DRIVER_OSS_SOUNDCARD_H */ +/* #undef SDL_AUDIO_DRIVER_PAUDIO */ +/* #undef SDL_AUDIO_DRIVER_PULSEAUDIO */ +/* #undef SDL_AUDIO_DRIVER_PULSEAUDIO_DYNAMIC */ +/* #undef SDL_AUDIO_DRIVER_QSA */ +/* #undef SDL_AUDIO_DRIVER_SNDIO */ +/* #undef SDL_AUDIO_DRIVER_SNDIO_DYNAMIC */ +/* #undef SDL_AUDIO_DRIVER_SUNAUDIO */ +/* #undef SDL_AUDIO_DRIVER_WASAPI */ +/* #undef SDL_AUDIO_DRIVER_WINMM */ + +/* Enable various input drivers */ +/* #undef SDL_INPUT_LINUXEV */ +/* #undef SDL_INPUT_LINUXKD */ +/* #undef SDL_INPUT_TSLIB */ +/* #undef SDL_JOYSTICK_HAIKU */ +#define SDL_JOYSTICK_AMIGAINPUT 1 +/* #undef SDL_JOYSTICK_DINPUT */ +/* #undef SDL_JOYSTICK_XINPUT */ +/* #undef SDL_JOYSTICK_DUMMY */ +/* #undef SDL_JOYSTICK_IOKIT */ +/* #undef SDL_JOYSTICK_LINUX */ +/* #undef SDL_JOYSTICK_ANDROID */ +/* #undef SDL_JOYSTICK_WINMM */ +/* #undef SDL_JOYSTICK_USBHID */ +/* #undef SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H */ +/* #undef SDL_JOYSTICK_HIDAPI */ +/* #undef SDL_JOYSTICK_EMSCRIPTEN */ +#define SDL_HAPTIC_DUMMY 1 +/* #undef SDL_HAPTIC_ANDROID */ +/* #undef SDL_HAPTIC_LINUX */ +/* #undef SDL_HAPTIC_IOKIT */ +/* #undef SDL_HAPTIC_DINPUT */ +/* #undef SDL_HAPTIC_XINPUT */ + +/* Enable various sensor drivers */ +/* #undef SDL_SENSOR_ANDROID */ +#define SDL_SENSOR_DUMMY 1 + +/* Enable various shared object loading systems */ +/* #undef SDL_LOADSO_DLOPEN */ +/* #undef SDL_LOADSO_DUMMY */ +/* #undef SDL_LOADSO_LDG */ +/* #undef SDL_LOADSO_WINDOWS */ +#define SDL_LOADSO_AMIGAOS4 1 + +/* Enable various threading systems */ +/* #undef SDL_THREAD_PTHREAD */ +/* #undef SDL_THREAD_PTHREAD_RECURSIVE_MUTEX */ +/* #undef SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP */ +/* #undef SDL_THREAD_WINDOWS */ +#define SDL_THREAD_AMIGAOS4 1 + +/* Enable various timer systems */ +/* #undef SDL_TIMER_HAIKU */ +#define SDL_TIMER_AMIGAOS4 1 +/* #undef SDL_TIMER_DUMMY */ +/* #undef SDL_TIMER_UNIX */ +/* #undef SDL_TIMER_WINDOWS */ + +/* Enable various video drivers */ +/* #undef SDL_VIDEO_DRIVER_HAIKU */ +#define SDL_VIDEO_DRIVER_AMIGAOS4 1 +/* #undef SDL_VIDEO_DRIVER_COCOA */ +/* #undef SDL_VIDEO_DRIVER_DIRECTFB */ +/* #undef SDL_VIDEO_DRIVER_DIRECTFB_DYNAMIC */ +#define SDL_VIDEO_DRIVER_DUMMY 1 +/* #undef SDL_VIDEO_DRIVER_WINDOWS */ +/* #undef SDL_VIDEO_DRIVER_WAYLAND */ +/* #undef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ +/* #undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC */ +/* #undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL */ +/* #undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR */ +/* #undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON */ +/* #undef SDL_VIDEO_DRIVER_X11 */ +/* #undef SDL_VIDEO_DRIVER_RPI */ +/* #undef SDL_VIDEO_DRIVER_KMSDRM */ +/* #undef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC */ +/* #undef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM */ +/* #undef SDL_VIDEO_DRIVER_ANDROID */ +/* #undef SDL_VIDEO_DRIVER_EMSCRIPTEN */ +/* #undef SDL_VIDEO_DRIVER_X11_DYNAMIC */ +/* #undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT */ +/* #undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR */ +/* #undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA */ +/* #undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2 */ +/* #undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR */ +/* #undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS */ +/* #undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE */ +/* #undef SDL_VIDEO_DRIVER_X11_XCURSOR */ +/* #undef SDL_VIDEO_DRIVER_X11_XDBE */ +/* #undef SDL_VIDEO_DRIVER_X11_XINERAMA */ +/* #undef SDL_VIDEO_DRIVER_X11_XINPUT2 */ +/* #undef SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH */ +/* #undef SDL_VIDEO_DRIVER_X11_XRANDR */ +/* #undef SDL_VIDEO_DRIVER_X11_XSCRNSAVER */ +/* #undef SDL_VIDEO_DRIVER_X11_XSHAPE */ +/* #undef SDL_VIDEO_DRIVER_X11_XVIDMODE */ +/* #undef SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS */ +/* #undef SDL_VIDEO_DRIVER_X11_CONST_PARAM_XEXTADDDISPLAY */ +/* #undef SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM */ +/* #undef SDL_VIDEO_DRIVER_NACL */ +/* #undef SDL_VIDEO_DRIVER_VIVANTE */ +/* #undef SDL_VIDEO_DRIVER_VIVANTE_VDK */ +/* #undef SDL_VIDEO_DRIVER_QNX */ + +/* #undef SDL_VIDEO_RENDER_D3D */ +/* #undef SDL_VIDEO_RENDER_D3D11 */ +#define SDL_VIDEO_RENDER_OGL 1 +/* #undef SDL_VIDEO_RENDER_OGL_ES */ +#define SDL_VIDEO_RENDER_OGL_ES2 1 +/* #undef SDL_VIDEO_RENDER_DIRECTFB */ +/* #undef SDL_VIDEO_RENDER_METAL */ +#define SDL_VIDEO_RENDER_AMIGAOS4 1 + +/* Enable OpenGL support */ +#define SDL_VIDEO_OPENGL 1 +/* #undef SDL_VIDEO_OPENGL_ES */ +#define SDL_VIDEO_OPENGL_ES2 1 +/* #undef SDL_VIDEO_OPENGL_BGL */ +/* #undef SDL_VIDEO_OPENGL_CGL */ +/* #undef SDL_VIDEO_OPENGL_EGL */ +/* #undef SDL_VIDEO_OPENGL_GLX */ +/* #undef SDL_VIDEO_OPENGL_WGL */ +/* #undef SDL_VIDEO_OPENGL_OSMESA */ +/* #undef SDL_VIDEO_OPENGL_OSMESA_DYNAMIC */ + +/* Enable Vulkan support */ +/* #undef SDL_VIDEO_VULKAN */ + +/* Enable system power support */ +/* #undef SDL_POWER_LINUX */ +/* #undef SDL_POWER_WINDOWS */ +/* #undef SDL_POWER_MACOSX */ +/* #undef SDL_POWER_HAIKU */ +/* #undef SDL_POWER_ANDROID */ +/* #undef SDL_POWER_EMSCRIPTEN */ +/* #undef SDL_POWER_HARDWIRED */ + +/* Enable system filesystem support */ +/* #undef SDL_FILESYSTEM_HAIKU */ +/* #undef SDL_FILESYSTEM_COCOA */ +/* #undef SDL_FILESYSTEM_DUMMY */ +/* #undef SDL_FILESYSTEM_UNIX */ +/* #undef SDL_FILESYSTEM_WINDOWS */ +#define SDL_FILESYSTEM_AMIGAOS4 1 +/* #undef SDL_FILESYSTEM_NACL */ +/* #undef SDL_FILESYSTEM_ANDROID */ +/* #undef SDL_FILESYSTEM_EMSCRIPTEN */ + +/* Enable assembly routines */ +#define SDL_ASSEMBLY_ROUTINES 1 +/*#define SDL_ALTIVEC_BLITTERS 1*/ + +/* Enable ime support */ +/* #undef SDL_USE_IME */ + +/* Enable dynamic udev support */ +/* #undef SDL_UDEV_DYNAMIC */ + +/* Enable dynamic libsamplerate support */ +/* #undef SDL_LIBSAMPLERATE_DYNAMIC */ + +#endif /* SDL_config_amigaos4_h_ */ diff --git a/include/SDL_endian.h b/include/SDL_endian.h index 0a8e204a4824e..47780a892baad 100644 --- a/include/SDL_endian.h +++ b/include/SDL_endian.h @@ -72,7 +72,7 @@ _m_prefetch(void *__P) #if defined(__hppa__) || \ defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \ (defined(__MIPS__) && defined(__MIPSEB__)) || \ - defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || \ + defined(__ppc__) || defined(__POWERPC__) || defined(__powerpc__) || defined(_M_PPC) || \ defined(__sparc__) #define SDL_BYTEORDER SDL_BIG_ENDIAN #else diff --git a/include/SDL_opengl.h b/include/SDL_opengl.h index 95b51ae45c23c..a3234a868e399 100644 --- a/include/SDL_opengl.h +++ b/include/SDL_opengl.h @@ -37,6 +37,15 @@ #include "SDL_config.h" +#ifdef __AMIGAOS4__ +/* We really need the system headers for MiniGL */ + +#include + +#include "SDL_opengl_glext.h" + +#else + #ifndef __IPHONEOS__ /* No OpenGL on iOS. */ /* @@ -2178,6 +2187,8 @@ typedef void (APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum t #endif /* !__IPHONEOS__ */ +#endif /* __AMIGAOS4__ */ + #endif /* SDL_opengl_h_ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/include/SDL_platform.h b/include/SDL_platform.h index ebaa25242fde0..0a10ae066824b 100644 --- a/include/SDL_platform.h +++ b/include/SDL_platform.h @@ -159,6 +159,11 @@ #define __PSP__ 1 #endif +#if defined(__amigaos4__) +#undef __AMIGAOS4__ +#define __AMIGAOS4__ 1 +#endif + /* The NACL compiler defines __native_client__ and __pnacl__ * Ref: http://www.chromium.org/nativeclient/pnacl/stability-of-the-pnacl-bitcode-abi */ diff --git a/include/SDL_syswm.h b/include/SDL_syswm.h index 12e86a17cc4c9..b90a73056b7aa 100644 --- a/include/SDL_syswm.h +++ b/include/SDL_syswm.h @@ -139,6 +139,7 @@ typedef enum SDL_SYSWM_WAYLAND, SDL_SYSWM_MIR, /* no longer available, left for API/ABI compatibility. Remove in 2.1! */ SDL_SYSWM_WINRT, + SDL_SYSWM_OS4, SDL_SYSWM_ANDROID, SDL_SYSWM_VIVANTE, SDL_SYSWM_OS2, @@ -308,6 +309,12 @@ struct SDL_SysWMinfo EGLSurface surface; } android; #endif +#if defined(SDL_VIDEO_DRIVER_AMIGAOS4) + struct + { + struct Window *window; /**< The AmigaOS 4 window */ + } os4; +#endif #if defined(SDL_VIDEO_DRIVER_OS2) struct diff --git a/include/SDL_test.h b/include/SDL_test.h index 66fde839fa3fe..8cf35e571bc69 100644 --- a/include/SDL_test.h +++ b/include/SDL_test.h @@ -51,7 +51,33 @@ extern "C" { #endif /* Global definitions */ +#ifdef __amigaos4__ +# ifndef __LONG_MAX__ +# define __LONG_MAX__ 2147483647L +# endif +# undef LONG_MIN +# define LONG_MIN (-LONG_MAX-1) +# undef LONG_MAX +# define LONG_MAX __LONG_MAX__ +/* Maximum value an `unsigned long int' can hold. (Minimum is 0). */ +# undef ULONG_MAX +# define ULONG_MAX (LONG_MAX * 2UL + 1) + +# ifndef __LONG_LONG_MAX__ +# define __LONG_LONG_MAX__ 9223372036854775807LL +# endif + +/* Minimum and maximum values a `signed long long int' can hold. */ +# undef LLONG_MIN +# define LLONG_MIN (-LLONG_MAX-1) +# undef LLONG_MAX +# define LLONG_MAX __LONG_LONG_MAX__ + +/* Maximum value an `unsigned long long int' can hold. (Minimum is 0). */ +# undef ULLONG_MAX +# define ULLONG_MAX (LLONG_MAX * 2ULL + 1) +#endif /* * Note: Maximum size of SDLTest log message is less than SDL's limit * to ensure we can fit additional information such as the timestamp. diff --git a/src/SDL.c b/src/SDL.c index 73f1cd7f0bd6c..5993bb2f27e74 100644 --- a/src/SDL.c +++ b/src/SDL.c @@ -52,6 +52,10 @@ #include "joystick/SDL_joystick_c.h" #include "sensor/SDL_sensor_c.h" +#if SDL_THREAD_AMIGAOS4 +#include "thread/amigaos4/SDL_systhread_c.h" +#endif + /* Initialization/Cleanup routines */ #if !SDL_TIMERS_DISABLED # include "timer/SDL_timer_c.h" @@ -158,6 +162,10 @@ SDL_InitSubSystem(Uint32 flags) /* Clear the error message */ SDL_ClearError(); +#if SDL_THREAD_AMIGAOS4 + OS4_InitThreadSubSystem(); +#endif + #if SDL_USE_LIBDBUS SDL_DBus_Init(); #endif @@ -445,6 +453,10 @@ SDL_Quit(void) SDL_TicksQuit(); #endif +#if SDL_THREAD_AMIGAOS4 + OS4_QuitThreadSubSystem(); +#endif + SDL_ClearHints(); SDL_AssertionsQuit(); SDL_LogResetPriorities(); @@ -538,6 +550,8 @@ SDL_GetPlatform() return "iOS"; #elif __PSP__ return "PlayStation Portable"; +#elif __AMIGAOS4__ + return "AmigaOS 4"; #elif __VITA__ return "PlayStation Vita"; #else diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c index 5ce94d1fffcc9..81e4838e07c77 100644 --- a/src/audio/SDL_audio.c +++ b/src/audio/SDL_audio.c @@ -101,6 +101,9 @@ static const AudioBootStrap *const bootstrap[] = { #if SDL_AUDIO_DRIVER_PSP &PSPAUDIO_bootstrap, #endif +#if SDL_AUDIO_DRIVER_AMIGAOS4 + &AMIGAOS4AUDIO_bootstrap, +#endif #if SDL_AUDIO_DRIVER_VITA &VITAAUD_bootstrap, #endif diff --git a/src/audio/SDL_sysaudio.h b/src/audio/SDL_sysaudio.h index 17b9e70583581..daa455d70fab2 100644 --- a/src/audio/SDL_sysaudio.h +++ b/src/audio/SDL_sysaudio.h @@ -211,6 +211,7 @@ extern AudioBootStrap ANDROIDAUDIO_bootstrap; extern AudioBootStrap PSPAUDIO_bootstrap; extern AudioBootStrap VITAAUD_bootstrap; extern AudioBootStrap EMSCRIPTENAUDIO_bootstrap; +extern AudioBootStrap AMIGAOS4AUDIO_bootstrap; extern AudioBootStrap OS2AUDIO_bootstrap; #endif /* SDL_sysaudio_h_ */ diff --git a/src/audio/amigaos4/SDL_os4audio.c b/src/audio/amigaos4/SDL_os4audio.c new file mode 100644 index 0000000000000..efef0f51dd1df --- /dev/null +++ b/src/audio/amigaos4/SDL_os4audio.c @@ -0,0 +1,474 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2017 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_AUDIO_DRIVER_AMIGAOS4 + +// This optimisation assumes that allocated audio buffers +// are sufficiently aligned to treat as arrays of longwords. +// Which they should be, as far as I can tell. +#define POSSIBLY_DANGEROUS_OPTIMISATION 1 + +#include "SDL_audio.h" +#include "SDL_timer.h" +#include "../SDL_audio_c.h" +#include "../SDL_sysaudio.h" +#include "SDL_os4audio.h" + +#include + +#define DEBUG +#include "../../main/amigaos4/SDL_os4debug.h" + +/* The tag name used by the AmigaOS4 audio driver */ +#define DRIVER_NAME "amigaos4" + +static SDL_bool +OS4_OpenAhiDevice(OS4AudioData * os4data) +{ + if (os4data->deviceOpen) { + dprintf("Device already open\n"); + } + + os4data->deviceOpen = SDL_FALSE; + + os4data->ahiReplyPort = (struct MsgPort *)IExec->AllocSysObjectTags(ASOT_PORT, TAG_DONE); + + if (os4data->ahiReplyPort) { + + /* create a iorequest for the device */ + os4data->ahiRequest[0] = (struct AHIRequest *) + IExec->AllocSysObjectTags( + ASOT_IOREQUEST, + ASOIOR_ReplyPort, os4data->ahiReplyPort, + ASOIOR_Size, sizeof(struct AHIRequest), + TAG_DONE); + + if (os4data->ahiRequest[0]) { + + if (!IExec->OpenDevice(AHINAME, 0, (struct IORequest *)os4data->ahiRequest[0], 0)) { + + dprintf("%s opened\n", AHINAME); + + /* Create a copy */ + os4data->ahiRequest[1] = (struct AHIRequest *) + IExec->AllocSysObjectTags( + ASOT_IOREQUEST, + ASOIOR_Duplicate, os4data->ahiRequest[0], + TAG_DONE); + + if (os4data->ahiRequest[1]) { + + dprintf("IO requests created\n"); + + os4data->deviceOpen = SDL_TRUE; + os4data->currentBuffer = 0; + os4data->link = NULL; + } else { + dprintf("Failed to duplicate IO request\n"); + } + } else { + dprintf("Failed to open %s\n", AHINAME); + } + } else { + dprintf("Failed to create IO request\n"); + } + } else { + dprintf("Failed to create reply port\n"); + } + + dprintf("deviceOpen = %d\n", os4data->deviceOpen); + return os4data->deviceOpen; +} + +static void +OS4_CloseAhiDevice(OS4AudioData * os4data) +{ + if (os4data->ahiRequest[0]) { + if (os4data->link) { + dprintf("Aborting I/O...\n"); + + IExec->AbortIO((struct IORequest *)os4data->link); + IExec->WaitIO((struct IORequest *)os4data->link); + } + + dprintf("Closing device\n"); + IExec->CloseDevice((struct IORequest *)os4data->ahiRequest[0]); + + dprintf("Freeing I/O requests\n"); + IExec->FreeSysObject(ASOT_IOREQUEST, os4data->ahiRequest[0]); + os4data->ahiRequest[0] = NULL; + + if (os4data->ahiRequest[1]) { + IExec->FreeSysObject(ASOT_IOREQUEST, os4data->ahiRequest[1]); + os4data->ahiRequest[1] = NULL; + } + } + + if (os4data->ahiReplyPort) { + dprintf("Deleting message port\n"); + IExec->FreeSysObject(ASOT_PORT, os4data->ahiReplyPort); + os4data->ahiReplyPort = NULL; + } + + os4data->deviceOpen = SDL_FALSE; + + dprintf("Device closed\n"); +} + +static SDL_bool +OS4_AudioAvailable(void) +{ + SDL_bool isAvailable = SDL_FALSE; + + OS4AudioData *tempData = SDL_calloc(1, sizeof(OS4AudioData)); + + if (!tempData) { + dprintf("Failed to allocate temp data\n"); + } else { + isAvailable = OS4_OpenAhiDevice(tempData); + + OS4_CloseAhiDevice(tempData); + + SDL_free(tempData); + } + + dprintf("AHI is %savailable\n", isAvailable ? "" : "not "); + return isAvailable; +} + +static int +OS4_SwapBuffer(int current) +{ + return (1 - current); +} + +static void +OS4_FillCaptureRequest(struct AHIRequest * request, void * buffer, int length, int frequency, int type) +{ + request->ahir_Std.io_Message.mn_Node.ln_Pri = 60; + request->ahir_Std.io_Data = buffer, + request->ahir_Std.io_Length = length; + request->ahir_Std.io_Command = CMD_READ; + request->ahir_Volume = 0x10000; + request->ahir_Position = 0x8000; + request->ahir_Link = NULL; + request->ahir_Frequency = frequency; + request->ahir_Type = type; +} + +/* ---------------------------------------------- */ +/* Audio driver exported functions implementation */ +/* ---------------------------------------------- */ +static void +OS4_CloseDevice(_THIS) +{ + OS4AudioData *os4data = _this->hidden; + + dprintf("Called\n"); + + OS4_CloseAhiDevice(os4data); + + if (os4data->audioBuffer[0]) { + SDL_free(os4data->audioBuffer[0]); + os4data->audioBuffer[0] = NULL; + } + + if (os4data->audioBuffer[1]) { + SDL_free(os4data->audioBuffer[1]); + os4data->audioBuffer[1] = NULL; + } + + SDL_free(os4data); +} + +static int +OS4_OpenDevice(_THIS, void * handle, const char * devname, int iscapture) +{ + int result = 0; + OS4AudioData *os4data = NULL; + + dprintf("handle %p, devname %s, iscapture %d\n", handle, devname, iscapture); + + _this->hidden = (OS4AudioData *) SDL_malloc(sizeof(OS4AudioData)); + + if (!_this->hidden) { + dprintf("Failed to allocate private data\n"); + return SDL_OutOfMemory(); + } + + SDL_memset(_this->hidden, 0, sizeof(OS4AudioData)); + os4data = _this->hidden; + + if ((_this->spec.format & 0xff) != 8) { + _this->spec.format = AUDIO_S16MSB; + } + + dprintf("New format = 0x%x\n", _this->spec.format); + dprintf("Buffer size = %d\n", _this->spec.size); + + /* Calculate the final parameters for this audio specification */ + SDL_CalculateAudioSpec(&_this->spec); + + os4data->audioBufferSize = _this->spec.size; + os4data->audioBuffer[0] = (Uint8 *) SDL_malloc(_this->spec.size); + os4data->audioBuffer[1] = (Uint8 *) SDL_malloc(_this->spec.size); + + if (os4data->audioBuffer[0] == NULL || os4data->audioBuffer[1] == NULL) { + OS4_CloseDevice(_this); + dprintf("No memory for audio buffer\n"); + SDL_SetError("No memory for audio buffer"); + return -1; + } + + SDL_memset(os4data->audioBuffer[0], _this->spec.silence, _this->spec.size); + SDL_memset(os4data->audioBuffer[1], _this->spec.silence, _this->spec.size); + + switch(_this->spec.format) { + case AUDIO_S8: + case AUDIO_U8: + os4data->ahiType = (_this->spec.channels < 2) ? AHIST_M8S : AHIST_S8S; + break; + + default: + os4data->ahiType = (_this->spec.channels < 2) ? AHIST_M16S : AHIST_S16S; + break; + } + + return result; +} + +static void +OS4_ThreadInit(_THIS) +{ + OS4AudioData *os4data = _this->hidden; + + dprintf("Called\n"); + + /* Signal must be opened in the task which is using it (player) */ + if (!OS4_OpenAhiDevice(os4data)) { + // FIXME: this is bad. We have failed and SDL core doesn't know about that. + dprintf("Failed to open AHI\n"); + } + + /* This will cause a lot of problems.. and should be removed. + + One possibility: create a configuration GUI or ENV variable that allows + user to select priority, if there is no silver bullet value */ + IExec->SetTaskPri(IExec->FindTask(NULL), 5); +} + +static void +OS4_WaitDevice(_THIS) +{ + /* Dummy - OS4_PlayDevice handles the waiting */ + //dprintf("Called\n"); +} + +static void +OS4_PlayDevice(_THIS) +{ + struct AHIRequest *ahiRequest; + SDL_AudioSpec *spec = &_this->spec; + OS4AudioData *os4data = _this->hidden; + int current = os4data->currentBuffer; + + //dprintf("Called\n"); + + if (!os4data->deviceOpen) { + dprintf("Device is not open\n"); + return; + } + + ahiRequest = os4data->ahiRequest[current]; + + ahiRequest->ahir_Std.io_Message.mn_Node.ln_Pri = 60; + ahiRequest->ahir_Std.io_Data = os4data->audioBuffer[current]; + ahiRequest->ahir_Std.io_Length = os4data->audioBufferSize; + ahiRequest->ahir_Std.io_Offset = 0; + ahiRequest->ahir_Std.io_Command = CMD_WRITE; + ahiRequest->ahir_Volume = 0x10000; + ahiRequest->ahir_Position = 0x8000; + ahiRequest->ahir_Link = os4data->link; + ahiRequest->ahir_Frequency = spec->freq; + ahiRequest->ahir_Type = os4data->ahiType; + + // Convert to signed? + if (spec->format == AUDIO_U8) { +#if POSSIBLY_DANGEROUS_OPTIMISATION + int i, n; + uint32 *mixbuf = (uint32 *)os4data->audioBuffer[current]; + n = os4data->audioBufferSize / 4; // let the gcc optimiser decide the best way to divide by 4 + for (i = 0; i < n; i++) { + *(mixbuf++) ^= 0x80808080; + } + + if (0 != (n = os4data->audioBufferSize & 3)) { + uint8 *mixbuf8 = (uint8 *)mixbuf; + for (i = 0; i < n; i++) { + *(mixbuf8++) -= 128; + } + } +#else + int i; + for (i = 0; i < os4data->audioBufferSize; i++) { + os4data->audioBuffer[current][i] -= 128; + } +#endif + } + + IExec->SendIO((struct IORequest *)ahiRequest); + + if (os4data->link) { + IExec->WaitIO((struct IORequest *)os4data->link); + } + + os4data->link = ahiRequest; + os4data->currentBuffer = OS4_SwapBuffer(current); +} + +static Uint8 * +OS4_GetDeviceBuf(_THIS) +{ + //dprintf("Called\n"); + + return _this->hidden->audioBuffer[_this->hidden->currentBuffer]; +} + +#ifndef MIN +#define MIN(a, b) (a) < (b) ? (a) : (b) +#endif + +#define RESTART_CAPTURE_THRESHOLD 500 + +static int +OS4_CaptureFromDevice(_THIS, void * buffer, int buflen) +{ + struct AHIRequest *request; + SDL_AudioSpec *spec = &_this->spec; + OS4AudioData *os4data = _this->hidden; + Uint32 now; + size_t copyLen; + void *completedBuffer; + int current; + + //dprintf("Called %p, %d\n", buffer, buflen); + + if (!os4data->deviceOpen) { + dprintf("Device is not open\n"); + return 0; + } + + now = SDL_GetTicks(); + current = os4data->currentBuffer; + + request = os4data->ahiRequest[0]; + + if ((now - os4data->lastCaptureTicks) > RESTART_CAPTURE_THRESHOLD) { + + if (os4data->requestSent) { + IExec->WaitIO((struct IORequest *)request); + } + + /* Assume that we have to (re)start recording */ + OS4_FillCaptureRequest( + request, + os4data->audioBuffer[current], + os4data->audioBufferSize, + spec->freq, + os4data->ahiType); + + request->ahir_Std.io_Offset = 0; + + dprintf("Start recording\n"); + + IExec->DoIO((struct IORequest *)request); + os4data->requestSent = SDL_FALSE; + + current = OS4_SwapBuffer(current); + } else { + /* Wait for the previous request completion */ + IExec->WaitIO((struct IORequest *)request); + } + + OS4_FillCaptureRequest( + request, + os4data->audioBuffer[current], + os4data->audioBufferSize, + spec->freq, + os4data->ahiType); + + IExec->SendIO((struct IORequest *)request); + os4data->requestSent = SDL_TRUE; + + current = OS4_SwapBuffer(current); + + completedBuffer = os4data->audioBuffer[current]; + + copyLen = MIN(buflen, os4data->audioBufferSize); + + SDL_memcpy(buffer, completedBuffer, copyLen); + + os4data->lastCaptureTicks = now; + os4data->currentBuffer = current; + + //dprintf("%d bytes copied\n", copyLen); + + return copyLen; +} + +/* ------------------------------------------ */ +/* Audio driver init functions implementation */ +/* ------------------------------------------ */ +static int +OS4_Init(SDL_AudioDriverImpl * impl) +{ + if (!OS4_AudioAvailable()) { + SDL_SetError("Failed to open AHI device"); + return 0; + } + + // impl->DetectDevices? + impl->OpenDevice = OS4_OpenDevice; + impl->ThreadInit = OS4_ThreadInit; + impl->WaitDevice = OS4_WaitDevice; + impl->PlayDevice = OS4_PlayDevice; + // impl->GetPendingBytes? + impl->GetDeviceBuf = OS4_GetDeviceBuf; + impl->CaptureFromDevice = OS4_CaptureFromDevice; + // impl->FlushCapture + // impl->PrepareToClose() + impl->CloseDevice = OS4_CloseDevice; + // impl->Lock+UnlockDevice + // impl->FreeDeviceHandle + // impl->Deinitialize + + impl->HasCaptureSupport = 1; + impl->OnlyHasDefaultOutputDevice = 1; + impl->OnlyHasDefaultCaptureDevice = 1; + + return 1; +} + +AudioBootStrap AMIGAOS4AUDIO_bootstrap = { + DRIVER_NAME, "AmigaOS4 AHI audio", OS4_Init, 0 +}; +#endif diff --git a/src/audio/amigaos4/SDL_os4audio.h b/src/audio/amigaos4/SDL_os4audio.h new file mode 100644 index 0000000000000..53074716414c7 --- /dev/null +++ b/src/audio/amigaos4/SDL_os4audio.h @@ -0,0 +1,53 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2017 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef _SDL_os4audio_h +#define _SDL_os4audio_h + +#include +#include +#include + +#include "SDL_types.h" + +#include "../SDL_sysaudio.h" + +/* Hidden "this" pointer for the video functions */ +#define _THIS SDL_AudioDevice *_this + +struct SDL_PrivateAudioData +{ + struct MsgPort *ahiReplyPort; + struct AHIRequest *ahiRequest[2]; + uint32 ahiType; + int currentBuffer; // buffer number to fill + struct AHIRequest *link; // point to previous I/O request sent + + SDL_bool deviceOpen; + Uint32 audioBufferSize; + Uint8 *audioBuffer[2]; + + Uint32 lastCaptureTicks; + SDL_bool requestSent; // Keeps book of IO done with SendIO(), to avoid issues with WaitIO() +}; + +typedef struct SDL_PrivateAudioData OS4AudioData; + +#endif diff --git a/src/cpuinfo/SDL_cpuinfo.c b/src/cpuinfo/SDL_cpuinfo.c index 1668e701cd099..bdd59a7f783b4 100644 --- a/src/cpuinfo/SDL_cpuinfo.c +++ b/src/cpuinfo/SDL_cpuinfo.c @@ -59,6 +59,11 @@ #include #endif +#ifdef __AMIGAOS4__ +#include +#include +#endif + #if defined(__QNXNTO__) #include #endif @@ -327,6 +332,13 @@ CPU_haveAltiVec(void) int error = sysctl(selectors, 2, &hasVectorUnit, &length, NULL, 0); if (0 == error) altivec = (hasVectorUnit != 0); +#elif defined __amigaos4__ + { + uint32 vec_unit; + + IExec->GetCPUInfoTags(GCIT_VectorUnit, &vec_unit, TAG_DONE); + altivec = (vec_unit == VECTORTYPE_ALTIVEC); + } #elif SDL_ALTIVEC_BLITTERS && HAVE_SETJMP void (*handler) (int sig); handler = signal(SIGILL, illegal_instruction); @@ -809,8 +821,15 @@ SDL_GetCPUCacheLineSize(void) cpuid(0x80000005, a, b, c, d); return (c & 0xff); } else { +#ifdef __AMIGAOS4__ + uint32 size; + + IExec->GetCPUInfoTags(GCIT_CacheLineSize, &size, TAG_DONE); + return size; +#else /* Just make a guess here... */ return SDL_CACHELINE_SIZE; +#endif } } @@ -1009,6 +1028,11 @@ SDL_GetSystemRAM(void) } } #endif +#ifdef __AMIGAOS4__ + if (SDL_SystemRAM <= 0) { + SDL_SystemRAM = IExec->AvailMem(MEMF_TOTAL) / (1024 * 1024); + } +#endif #ifdef __OS2__ if (SDL_SystemRAM <= 0) { Uint32 sysram = 0; diff --git a/src/dynapi/SDL_dynapi.h b/src/dynapi/SDL_dynapi.h index 2619ff7612363..115f55ab9b6c3 100644 --- a/src/dynapi/SDL_dynapi.h +++ b/src/dynapi/SDL_dynapi.h @@ -53,6 +53,8 @@ #define SDL_DYNAMIC_API 0 #elif defined(__PSP__) && __PSP__ #define SDL_DYNAMIC_API 0 +#elif defined(__amigaos4__) /* It seems we cannot load .so from a statically linked binary */ +#define SDL_DYNAMIC_API 0 #elif defined(__riscos__) && __riscos__ /* probably not useful on RISC OS, since dlopen() can't be used when using static linking. */ #define SDL_DYNAMIC_API 0 #elif defined(__clang_analyzer__) diff --git a/src/events/scancodes_amiga.h b/src/events/scancodes_amiga.h new file mode 100644 index 0000000000000..5ae622e753a5c --- /dev/null +++ b/src/events/scancodes_amiga.h @@ -0,0 +1,144 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2014 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../include/SDL_scancode.h" + +/* Amiga virtual key code to SDL_Keycode mapping table + Sources: + - AmigaOS wiki +*/ +/* *INDENT-OFF* */ +static SDL_Scancode const amiga_scancode_table[] = { + /* 0 */ SDL_SCANCODE_GRAVE, + /* 1 */ SDL_SCANCODE_1, + /* 2 */ SDL_SCANCODE_2, + /* 3 */ SDL_SCANCODE_3, + /* 4 */ SDL_SCANCODE_4, + /* 5 */ SDL_SCANCODE_5, + /* 6 */ SDL_SCANCODE_6, + /* 7 */ SDL_SCANCODE_7, + /* 8 */ SDL_SCANCODE_8, + /* 9 */ SDL_SCANCODE_9, + /* 10 */ SDL_SCANCODE_0, + /* 11 */ SDL_SCANCODE_MINUS, + /* 12 */ SDL_SCANCODE_EQUALS, + /* 13 */ SDL_SCANCODE_BACKSLASH, + /* 14 */ SDL_SCANCODE_INTERNATIONAL3, + /* 15 */ SDL_SCANCODE_KP_0, + /* 16 */ SDL_SCANCODE_Q, + /* 17 */ SDL_SCANCODE_W, + /* 18 */ SDL_SCANCODE_E, + /* 19 */ SDL_SCANCODE_R, + /* 20 */ SDL_SCANCODE_T, + /* 21 */ SDL_SCANCODE_Y, + /* 22 */ SDL_SCANCODE_U, + /* 23 */ SDL_SCANCODE_I, + /* 24 */ SDL_SCANCODE_O, + /* 25 */ SDL_SCANCODE_P, + /* 26 */ SDL_SCANCODE_LEFTBRACKET, + /* 27 */ SDL_SCANCODE_RIGHTBRACKET, + /* 28 */ SDL_SCANCODE_UNKNOWN, + /* 29 */ SDL_SCANCODE_KP_1, + /* 30 */ SDL_SCANCODE_KP_2, + /* 31 */ SDL_SCANCODE_KP_3, + /* 32 */ SDL_SCANCODE_A, + /* 33 */ SDL_SCANCODE_S, + /* 34 */ SDL_SCANCODE_D, + /* 35 */ SDL_SCANCODE_F, + /* 36 */ SDL_SCANCODE_G, + /* 37 */ SDL_SCANCODE_H, + /* 38 */ SDL_SCANCODE_J, + /* 39 */ SDL_SCANCODE_K, + /* 40 */ SDL_SCANCODE_L, + /* 41 */ SDL_SCANCODE_SEMICOLON, + /* 42 */ SDL_SCANCODE_APOSTROPHE, + /* 43 */ SDL_SCANCODE_INTERNATIONAL1, + /* 44 */ SDL_SCANCODE_UNKNOWN, + /* 45 */ SDL_SCANCODE_KP_4, + /* 46 */ SDL_SCANCODE_KP_5, + /* 47 */ SDL_SCANCODE_KP_6, + /* 48 */ SDL_SCANCODE_INTERNATIONAL2, + /* 49 */ SDL_SCANCODE_Z, + /* 50 */ SDL_SCANCODE_X, + /* 51 */ SDL_SCANCODE_C, + /* 52 */ SDL_SCANCODE_V, + /* 53 */ SDL_SCANCODE_B, + /* 54 */ SDL_SCANCODE_N, + /* 55 */ SDL_SCANCODE_M, + /* 56 */ SDL_SCANCODE_COMMA, + /* 57 */ SDL_SCANCODE_PERIOD, + /* 58 */ SDL_SCANCODE_SLASH, + /* 59 */ SDL_SCANCODE_UNKNOWN, // or SDL_SCANCODE_INTERNATIONAL1, + /* 60 */ SDL_SCANCODE_KP_PERIOD, + /* 61 */ SDL_SCANCODE_KP_7, + /* 62 */ SDL_SCANCODE_KP_8, + /* 63 */ SDL_SCANCODE_KP_9, + /* 64 */ SDL_SCANCODE_SPACE, + /* 65 */ SDL_SCANCODE_BACKSPACE, + /* 66 */ SDL_SCANCODE_TAB, + /* 67 */ SDL_SCANCODE_KP_ENTER, + /* 68 */ SDL_SCANCODE_RETURN, + /* 69 */ SDL_SCANCODE_ESCAPE, + /* 70 */ SDL_SCANCODE_DELETE, + /* 71 */ SDL_SCANCODE_INSERT, + /* 72 */ SDL_SCANCODE_PAGEUP, + /* 73 */ SDL_SCANCODE_PAGEDOWN, + /* 74 */ SDL_SCANCODE_KP_MINUS, + /* 75 */ SDL_SCANCODE_F11, + /* 76 */ SDL_SCANCODE_UP, + /* 77 */ SDL_SCANCODE_DOWN, + /* 78 */ SDL_SCANCODE_RIGHT, + /* 79 */ SDL_SCANCODE_LEFT, + /* 80 */ SDL_SCANCODE_F1, + /* 81 */ SDL_SCANCODE_F2, + /* 82 */ SDL_SCANCODE_F3, + /* 83 */ SDL_SCANCODE_F4, + /* 84 */ SDL_SCANCODE_F5, + /* 85 */ SDL_SCANCODE_F6, + /* 86 */ SDL_SCANCODE_F7, + /* 87 */ SDL_SCANCODE_F8, + /* 88 */ SDL_SCANCODE_F9, + /* 89 */ SDL_SCANCODE_F10, + /* 90 */ SDL_SCANCODE_KP_LEFTPAREN, + /* 91 */ SDL_SCANCODE_KP_RIGHTPAREN, + /* 92 */ SDL_SCANCODE_KP_DIVIDE, + /* 93 */ SDL_SCANCODE_KP_MULTIPLY, + /* 94 */ SDL_SCANCODE_KP_PLUS, + /* 95 */ SDL_SCANCODE_SCROLLLOCK, // or SDL_SCANCODE_HELP, + /* 96 */ SDL_SCANCODE_LSHIFT, + /* 97 */ SDL_SCANCODE_RSHIFT, + /* 98 */ SDL_SCANCODE_CAPSLOCK, + /* 99 */ SDL_SCANCODE_LCTRL, + /* 100 */ SDL_SCANCODE_LALT, + /* 101 */ SDL_SCANCODE_RALT, + /* 102 */ SDL_SCANCODE_LGUI, + /* 103 */ SDL_SCANCODE_RGUI, + /* 104 */ SDL_SCANCODE_UNKNOWN, + /* 105 */ SDL_SCANCODE_UNKNOWN, + /* 106 */ SDL_SCANCODE_UNKNOWN, + /* 107 */ SDL_SCANCODE_MENU, + /* 108 */ SDL_SCANCODE_KP_PERIOD, + /* 109 */ SDL_SCANCODE_PRINTSCREEN, + /* 110 */ SDL_SCANCODE_PAUSE, + /* 111 */ SDL_SCANCODE_F12, + /* 112 */ SDL_SCANCODE_HOME, + /* 113 */ SDL_SCANCODE_END, +}; +/* *INDENT-ON* */ diff --git a/src/file/SDL_rwops.c b/src/file/SDL_rwops.c index 9552b3d03ab0f..ace07a53f4797 100644 --- a/src/file/SDL_rwops.c +++ b/src/file/SDL_rwops.c @@ -34,6 +34,10 @@ #include "../core/windows/SDL_windows.h" #endif +#ifdef __AMIGAOS4__ +#define off64_t _off64_t +#endif + #ifdef HAVE_STDIO_H #include #endif @@ -615,6 +619,12 @@ stdio_seek(SDL_RWops * context, Sint64 offset, int whence) } #endif +#ifdef __AMIGAOS4__ + if ((context->hidden.stdio.fp->_flags & __SL64) == 0) { + return SDL_SetError("File wasn't opened with fopen64"); + } +#endif + if (fseek(context->hidden.stdio.fp, (fseek_off_t)offset, stdiowhence) == 0) { Sint64 pos = ftell(context->hidden.stdio.fp); if (pos < 0) { diff --git a/src/filesystem/amigaos4/SDL_sysfilesystem.c b/src/filesystem/amigaos4/SDL_sysfilesystem.c new file mode 100644 index 0000000000000..700c0c01f9db5 --- /dev/null +++ b/src/filesystem/amigaos4/SDL_sysfilesystem.c @@ -0,0 +1,162 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2020 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#ifdef SDL_FILESYSTEM_AMIGAOS4 + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* System dependent filesystem routines */ + +#include "SDL_error.h" +#include "SDL_filesystem.h" +#include "../../video/amigaos4/SDL_os4library.h" + +#define DEBUG +#include "../../main/amigaos4/SDL_os4debug.h" + +#include + +static struct DOSIFace* iDos; +static struct DOSBase* dosBase; + +static BOOL +OS4_OpenDosLibrary() +{ + dosBase = (struct DOSBase *)OS4_OpenLibrary("dos.library", 50); + iDos = (struct DOSIFace *)OS4_GetInterface((struct Library *)dosBase); + return iDos != NULL; +} + +static void +OS4_CloseDosLibrary() +{ + OS4_DropInterface((struct Interface **)&iDos); + OS4_CloseLibrary((struct Library **)&dosBase); +} + +char * +SDL_GetBasePath(void) +{ + char* buffer = NULL; + const char* const basePath = "PROGDIR:"; + + size_t len = SDL_strlen(basePath) + 1; + + buffer = (char *) SDL_malloc(len); + if (!buffer) { + SDL_OutOfMemory(); + return NULL; + } + + SDL_memset(buffer, 0, len); + SDL_snprintf(buffer, len, "%s", basePath); + + return buffer; +} + +static BOOL +OS4_CreateDirTree(const char* path) +{ + BOOL success = FALSE; + + char* temp = SDL_strdup(path); + + if (!temp) { + dprintf("Failed to create temporary path\n"); + return FALSE; + } + + const size_t len = SDL_strlen(temp); + + if (len < 1) { + dprintf("Empty string\n"); + return FALSE; + } + + if (temp[len - 1] == '/') { + temp[len - 1] = '\0'; + } + + if (OS4_OpenDosLibrary()) { + BPTR lock = iDos->CreateDirTree(temp); + if (lock) { + success = TRUE; + iDos->UnLock(lock); + } else { + const int32 err = iDos->IoErr(); + dprintf("Failed to create dir tree '%s' (err %d)\n", temp, err); + if (err == ERROR_OBJECT_EXISTS) { + dprintf("Object already exists -> success\n"); + success = TRUE; + } + } + + OS4_CloseDosLibrary(); + } + + SDL_free(temp); + + return success; +} + +char * +SDL_GetPrefPath(const char *org, const char *app) +{ + const char* const envPath = "ENVARC:"; + size_t len = SDL_strlen(envPath) + 1; + char* buffer = NULL; + + if (org) { + len += SDL_strlen(org) + 1; + } + + if (app) { + len += SDL_strlen(app) + 1; + } + + buffer = (char *) SDL_malloc(len); + if (!buffer) { + SDL_OutOfMemory(); + return NULL; + } + + SDL_memset(buffer, 0, len); + SDL_snprintf(buffer, len, envPath); + + if (org) { + SDL_snprintf(buffer + SDL_strlen(buffer), len - SDL_strlen(buffer), "%s/", org); + } + + if (app) { + SDL_snprintf(buffer + SDL_strlen(buffer), len - SDL_strlen(buffer), "%s/", app); + } + + if (OS4_CreateDirTree(buffer)) { + return buffer; + } + + SDL_free(buffer); + return NULL; +} + +#endif /* SDL_FILESYSTEM_AMIGAOS4 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/joystick/SDL_gamecontrollerdb.h b/src/joystick/SDL_gamecontrollerdb.h index 2d54b63a19056..d353161064e17 100644 --- a/src/joystick/SDL_gamecontrollerdb.h +++ b/src/joystick/SDL_gamecontrollerdb.h @@ -862,6 +862,22 @@ static const char *s_ControllerMappings [] = #if defined(SDL_JOYSTICK_EMSCRIPTEN) "default,Standard Gamepad,a:b0,b:b1,back:b8,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b16,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,", #endif +#if defined(__AMIGAOS4__) + "53504545442d4c494e4b20436f6d7065,SPEED-LINK Competition Pro,platform:AmigaOS 4,a:b0,b:b1,x:b3,y:b2,leftx:a0,lefty:a1,", + "47656e6572696320202055534220204a,Ewent Joypad EW3170,platform:AmigaOS 4,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,lefttrigger:b6,righttrigger:b7,", + "555342204a6f79737469636b20202020,PS2 Joystick (USB adaptor),platform:AmigaOS 4,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,lefttrigger:b4,righttrigger:b5,", + "555342204a6f79737469636b20202020,SHARK 91230 Joystick,platform:AmigaOS 4,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,lefttrigger:b4,righttrigger:b5,", + "4d414749432d4e530000000000000000,MAGIC-NS,platform:AmigaOS4,a:b2,b:b1,x:b3,y:b0,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdwn:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", + "576972656c65737320436f6e74726f6c,Wireless Controller,platform:AmigaOS 4,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", + "38426974646f20534e33302050726f20,8Bitdo SN30 Pro,platform:AmigaOS 4,a:b1,b:b0,x:b4,y:b3,back:b10,start:b11,leftstick:b13,rightstick:b14,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b8,righttrigger:b9,", + "5468727573746d617374657220647561,Thrustmaster dual analog 3.2,platform:AmigaOS 4,a:b0,b:b2,x:b1,y:b3,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b6,dpup:h0.9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,", + "58454f582047616d6570616420534c2d,XEOX Gamepad SL-6556-BK,platform:AmigaOS 4,a:b0,b:b1,x:b2,y:b3,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:+a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", + "202055534220204a6f79737469636b20,Strike2 Joystick,platform:AmigaOS 4,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", + "7573622067616d657061642020202020,GeeekPi_A gamepad,platform:AmigaOS 4,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,", + "4c6f67697465636820436f72646c6573,Logitech Cordless RumblePad 2,platform:AmigaOS 4,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b9,leftstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,lefttrigger:b6,righttrigger:b7,", + "4c6f6769746563682052756d626c6550,Logitech RumblePad 2 USB,platform:AmigaOS 4,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", + "4c6f6769746563682852292050726563,Logitech(R) Precision(TM) Gamepad,platform:AmigaOS 4,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:-a1,dpdown:+a1,dpleft:-a0,dpright:+a0,lefttrigger:b6,righttrigger:b7,", +#endif #if defined(SDL_JOYSTICK_VITA) "50535669746120436f6e74726f6c6c65,PSVita Controller,a:b2,b:b1,back:b10,dpdown:b6,dpleft:b7,dpright:b9,dpup:b8,leftshoulder:b4,leftstick:b14,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b15,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,", #endif diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index 5a46f0c8629d6..a1a19a2932409 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -95,6 +95,9 @@ static SDL_JoystickDriver *SDL_joystick_drivers[] = { #ifdef SDL_JOYSTICK_VIRTUAL &SDL_VIRTUAL_JoystickDriver, #endif +#if defined(SDL_JOYSTICK_AMIGAINPUT) + &SDL_AMIGAINPUT_JoystickDriver, +#endif #ifdef SDL_JOYSTICK_VITA &SDL_VITA_JoystickDriver #endif diff --git a/src/joystick/SDL_sysjoystick.h b/src/joystick/SDL_sysjoystick.h index 749c6efd2963c..301f01794270f 100644 --- a/src/joystick/SDL_sysjoystick.h +++ b/src/joystick/SDL_sysjoystick.h @@ -193,6 +193,7 @@ typedef struct _SDL_JoystickDriver #define SDL_LED_MIN_REPEAT_MS 5000 /* The available joystick drivers */ +extern SDL_JoystickDriver SDL_AMIGAINPUT_JoystickDriver; extern SDL_JoystickDriver SDL_ANDROID_JoystickDriver; extern SDL_JoystickDriver SDL_BSD_JoystickDriver; extern SDL_JoystickDriver SDL_DARWIN_JoystickDriver; diff --git a/src/joystick/amigaos4/SDL_sysjoystick.c b/src/joystick/amigaos4/SDL_sysjoystick.c new file mode 100644 index 0000000000000..9e4a4560ec49a --- /dev/null +++ b/src/joystick/amigaos4/SDL_sysjoystick.c @@ -0,0 +1,650 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2020 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if defined(SDL_JOYSTICK_AMIGAINPUT) || defined(SDL_JOYSTICK_DISABLED) + +#define OLDSDK 1 + +#include "SDL_joystick.h" +#include "../SDL_sysjoystick.h" +#include "../SDL_joystick_c.h" +#include "../../video/amigaos4/SDL_os4library.h" + +#include "SDL_events.h" + +#include +#include + +#define DEBUG +#include "../../main/amigaos4/SDL_os4debug.h" + +#define MAX_JOYSTICKS 32 + +#define MAX_AXES 8 +#define MAX_BUTTONS 16 +#define MAX_HATS 8 + +#define BUFFER_OFFSET(buffer, offset) (((int32 *)buffer)[offset]) + +struct joystick +{ + AIN_DeviceID id; + const char *name; +}; + +/* Per-joystick data private to driver */ +struct joystick_hwdata +{ + AIN_DeviceHandle *handle; + APTR context; + + uint32 axisBufferOffset[MAX_AXES]; + int32 axisData[MAX_AXES]; + TEXT axisName[MAX_AXES][32]; + + uint32 buttonBufferOffset[MAX_BUTTONS]; + int32 buttonData[MAX_BUTTONS]; + + uint32 hatBufferOffset[MAX_HATS]; + int32 hatData[MAX_HATS]; +}; + +// TODO: get rid of static data +static uint32 joystickCount; +static struct joystick joystickList [MAX_JOYSTICKS]; +static APTR joystickContext; + +/* A handy container to encapsulate the information we + * need when enumerating joysticks on the system. + */ +struct enumPacket +{ + APTR context; + uint32 *count; + struct joystick *joyList; +}; + +static struct Library *SDL_AIN_Base; +static struct AIN_IFace *SDL_IAIN; + +/* + * Convert AmigaInput hat data to SDL hat data. + */ +static inline Uint8 +AMIGAINPUT_MapHatData(int hat_data) +{ + switch (hat_data) { + case 1: return SDL_HAT_UP; + case 2: return SDL_HAT_UP | SDL_HAT_RIGHT; + case 3: return SDL_HAT_RIGHT; + case 4: return SDL_HAT_DOWN | SDL_HAT_RIGHT; + case 5: return SDL_HAT_DOWN; + case 6: return SDL_HAT_DOWN | SDL_HAT_LEFT; + case 7: return SDL_HAT_LEFT; + case 8: return SDL_HAT_UP | SDL_HAT_LEFT; + default: return SDL_HAT_CENTERED; + } +} + +/* + * Callback to enumerate joysticks + */ +static BOOL +AMIGAINPUT_EnumerateJoysticks(AIN_Device *device, void *UserData) +{ + APTR context = ((struct enumPacket *)UserData)->context; + uint32 *count = ((struct enumPacket *)UserData)->count; + struct joystick *joy = &((struct enumPacket *)UserData)->joyList[*count]; + + BOOL result = FALSE; + + if (*count < MAX_JOYSTICKS) { + dprintf("ENUMJOY: id=%ld, type=%ld, axes=%ld, buttons=%ld\n", + count, + (int32)device->Type, + (int32)device->NumAxes, + (int32)device->NumButtons); + + if (device->Type == AINDT_JOYSTICK) { + /* AmigaInput can report devices even when there's no + * physical stick present. We take some steps to try and + * ignore such bogus devices. + * + * First, check whether we have a useful number of axes and buttons + */ + if ((device->NumAxes > 0) && (device->NumButtons > 0)) { + /* Then, check whether we can actually obtain the device + */ +#if OLDSDK + AIN_DeviceHandle *handle = SDL_IAIN->AIN_ObtainDevice (context, device->DeviceID); +#else + AIN_DeviceHandle *handle = SDL_IAIN->ObtainDevice (context, device->DeviceID); +#endif + + if (handle) { + /* Okay. This appears to be a valid device. We'll report it to SDL. + */ + joy->id = device->DeviceID; + joy->name = SDL_strdup(device->DeviceName); + + dprintf("Found joystick #%d (AI ID=%d) '%s'\n", *count, joy->id, joy->name); + + (*count)++; + +#if OLDSDK + SDL_IAIN->AIN_ReleaseDevice (context, handle); +#else + SDL_IAIN->ReleaseDevice (context, handle); +#endif + + result = TRUE; + } + else + dprintf("Failed to obtain joystick '%s' (AI ID=%d) - ignoring.\n", device->DeviceName, device->DeviceID); + } + else + dprintf("Joystick '%s' (AI ID=%d) has no axes/buttons - ignoring.\n", device->DeviceName, device->DeviceID); + } + } + return result; +} + +static BOOL +AMIGAINPUT_OpenLibrary(void) +{ + dprintf("Called\n"); + + SDL_AIN_Base = OS4_OpenLibrary("AmigaInput.library", 51); + + if (SDL_AIN_Base) { + SDL_IAIN = (struct AIN_IFace *) OS4_GetInterface(SDL_AIN_Base); + + if (!SDL_IAIN) { + OS4_CloseLibrary(&SDL_AIN_Base); + } + } else { + dprintf("Failed to open AmigaInput.library\n"); + } + + return SDL_AIN_Base != NULL; +} + +static void +AMIGAINPUT_CloseLibrary(void) +{ + dprintf("Called\n"); + + OS4_DropInterface((void *) &SDL_IAIN); + OS4_CloseLibrary(&SDL_AIN_Base); +} + +/* Function to scan the system for joysticks. + * It should return 0, or -1 on an unrecoverable fatal error. + */ +static int +AMIGAINPUT_Init(void) +{ + if (AMIGAINPUT_OpenLibrary()) { +#if OLDSDK + joystickContext = SDL_IAIN->AIN_CreateContext(1, NULL); +#else + joystickContext = SDL_IAIN->CreateContext(1, NULL); +#endif + + if (joystickContext) { + struct enumPacket packet = { + joystickContext, + &joystickCount, + &joystickList[0] + }; + +#if OLDSDK + BOOL result = SDL_IAIN->AIN_EnumDevices(joystickContext, AMIGAINPUT_EnumerateJoysticks, &packet); +#else + BOOL result = SDL_IAIN->EnumDevices(joystickContext, AMIGAINPUT_EnumerateJoysticks, &packet); +#endif + dprintf("EnumDevices returned %d\n", result); + dprintf("Found %d joysticks\n", joystickCount); + + if (result) { + /* + + NOTE: AI doesn't seem to handle hotplugged/removed joysticks very well. + Report only devices detected at startup to SDL. + + */ + int i; + + for (i = 0; i < joystickCount; i++) { + dprintf("Add joystick %d\n", i); + SDL_PrivateJoystickAdded(i); + } + } + } + + return 0; + } else { + dprintf("Failed to create context\n"); + } + + return -1; +} + +static int +AMIGAINPUT_GetCount() +{ + return joystickCount; +} + +static void +AMIGAINPUT_Detect() +{ + //dprintf("Called\n"); +} + +/* Function to get the device-dependent name of a joystick */ +static const char * +AMIGAINPUT_GetDeviceName(int device_index) +{ + return joystickList[device_index].name; +} + +static int +AMIGAINPUT_GetDevicePlayerIndex(int device_index) +{ + return device_index; +} + +static void +AMIGAINPUT_SetDevicePlayerIndex(int device_index, int player_index) +{ + dprintf("Not implemented\n"); +} + +static SDL_JoystickID +AMIGAINPUT_GetDeviceInstanceID(int device_index) +{ + return device_index; +} + +/* Function to open a joystick for use. + The joystick to open is specified by the index field of the joystick. + This should fill the nbuttons and naxes fields of the joystick structure. + It returns 0, or -1 if there is an error. + */ +static int +AMIGAINPUT_Open(SDL_Joystick * joystick, int device_index) +{ + AIN_DeviceHandle *handle; + AIN_DeviceID id = joystickList[joystick->instance_id].id; + +#if OLDSDK + handle = SDL_IAIN->AIN_ObtainDevice(joystickContext, id); +#else + handle = SDL_IAIN->ObtainDevice(joystickContext, id); +#endif + + dprintf("Opening joystick #%d (AI ID=%d)\n", joystick->instance_id, id); + + if (handle) { + joystick->hwdata = SDL_calloc(1, sizeof(struct joystick_hwdata)); + + if (joystick->hwdata) { + struct joystick_hwdata *hwdata = joystick->hwdata; + unsigned int num_axes = 0; + unsigned int num_buttons = 0; + unsigned int num_hats = 0; + TEXT tmpstr[32]; + uint32 tmpoffset; + + int i; + BOOL result = TRUE; + + hwdata->handle = handle; + hwdata->context = joystickContext; + + joystick->name = (char *) joystickList[joystick->instance_id].name; + + /* Query number of axes, buttons and hats the device has */ +#if OLDSDK + result = result && SDL_IAIN->AIN_Query(hwdata->context, id, AINQ_NUMAXES, 0, &num_axes, 4); + result = result && SDL_IAIN->AIN_Query(hwdata->context, id, AINQ_NUMBUTTONS, 0, &num_buttons, 4); + result = result && SDL_IAIN->AIN_Query(hwdata->context, id, AINQ_NUMHATS, 0, &num_hats, 4); +#else + result = result && SDL_IAIN->Query(hwdata->context, id, AINQ_NUMAXES, 0, &num_axes, 4); + result = result && SDL_IAIN->Query(hwdata->context, id, AINQ_NUMBUTTONS, 0, &num_buttons, 4); + result = result && SDL_IAIN->Query(hwdata->context, id, AINQ_NUMHATS, 0, &num_hats, 4); +#endif + +// dprintf ("Found %d axes, %d buttons, %d hats\n", num_axes, num_buttons, num_hats); + + joystick->naxes = num_axes < MAX_AXES ? num_axes : MAX_AXES; + joystick->nbuttons = num_buttons < MAX_BUTTONS ? num_buttons : MAX_BUTTONS; + joystick->nhats = num_hats < MAX_HATS ? num_hats : MAX_HATS; + + // Ensure all axis names are null terminated + for (i = 0; i < MAX_AXES; i++) + hwdata->axisName[i][0] = 0; + + /* Query offsets in ReadDevice buffer for axes' data */ + for (i = 0; i < joystick->naxes; i++) { +#if OLDSDK + result = result && SDL_IAIN->AIN_Query(hwdata->context, id, AINQ_AXIS_OFFSET, i, &(hwdata->axisBufferOffset[i]), 4); + result = result && SDL_IAIN->AIN_Query(hwdata->context, id, AINQ_AXISNAME, i, &(hwdata->axisName[i][0]), 32 ); +#else + result = result && SDL_IAIN->Query(hwdata->context, id, AINQ_AXIS_OFFSET, i, &(hwdata->axisBufferOffset[i]), 4); + result = result && SDL_IAIN->Query(hwdata->context, id, AINQ_AXISNAME, i, &(hwdata->axisName[i][0]), 32 ); +#endif + } + + // Sort the axes so that X and Y come first + for (i = 0; i < joystick->naxes; i++) { + if ( ( strcasecmp( &hwdata->axisName[i][0], "X-Axis" ) == 0 ) && ( i != 0 ) ) { + // Back up the zero position axis data + tmpoffset = hwdata->axisBufferOffset[0]; + strlcpy( tmpstr, hwdata->axisName[0], 32 ); + + // Move this one to zero + hwdata->axisBufferOffset[0] = hwdata->axisBufferOffset[i]; + strlcpy( hwdata->axisName[0], hwdata->axisName[i], 32 ); + + // Put the old 0 here + hwdata->axisBufferOffset[i] = tmpoffset; + strlcpy( hwdata->axisName[i], tmpstr, 32 ); + + continue; + } + + if ( ( strcasecmp( &hwdata->axisName[i][0], "Y-Axis" ) == 0 ) && ( i != 1 ) ) { + // Back up the position 1 axis data + tmpoffset = hwdata->axisBufferOffset[1]; + strlcpy( tmpstr, hwdata->axisName[1], 32 ); + + // Move this one to position 1 + hwdata->axisBufferOffset[1] = hwdata->axisBufferOffset[i]; + strlcpy( hwdata->axisName[1], hwdata->axisName[i], 32 ); + + // Put the old 1 here + hwdata->axisBufferOffset[i] = tmpoffset; + strlcpy( hwdata->axisName[i], tmpstr, 32 ); + + continue; + } + } + + /* Query offsets in ReadDevice buffer for buttons' data */ + for (i = 0; i < joystick->nbuttons; i++) { +#if OLDSDK + result = result && SDL_IAIN->AIN_Query(hwdata->context, id, AINQ_BUTTON_OFFSET, i, &(hwdata->buttonBufferOffset[i]), 4); +#else + result = result && SDL_IAIN->Query(hwdata->context, id, AINQ_BUTTON_OFFSET, i, &(hwdata->buttonBufferOffset[i]), 4); +#endif + } + + /* Query offsets in ReadDevice buffer for hats' data */ + for (i = 0; i < joystick->nhats; i++) { +#if OLDSDK + result = result && SDL_IAIN->AIN_Query(hwdata->context, id, AINQ_HAT_OFFSET, i, &(hwdata->hatBufferOffset[i]), 4); +#else + result = result && SDL_IAIN->Query(hwdata->context, id, AINQ_HAT_OFFSET, i, &(hwdata->hatBufferOffset[i]), 4); +#endif + } + + if (result) { + dprintf("Successful\n"); + return 0; + } + } + +#if OLDSDK + SDL_IAIN->AIN_ReleaseDevice (joystickContext, handle); +#else + SDL_IAIN->ReleaseDevice (joystickContext, handle); +#endif + } + + SDL_SetError("Failed to open device\n"); + + dprintf("Failed\n"); + + return -1; +} + +/* Function to update the state of a joystick - called as a device poll. + * This function shouldn't update the joystick structure directly, + * but instead should call SDL_PrivateJoystick*() to deliver events + * and update joystick device state. + */ +static void +AMIGAINPUT_Update(SDL_Joystick * joystick) +{ + struct joystick_hwdata *hwdata = joystick->hwdata; + void *buffer; + + //dprintf("Called %p\n", hwdata); + + /* + * Poll device for data + */ +#if OLDSDK + if (hwdata && SDL_IAIN->AIN_ReadDevice(hwdata->context, hwdata->handle, &buffer)) +#else + if (hwdata && SDL_IAIN->ReadDevice(hwdata->context, hwdata->handle, &buffer)) +#endif + { + int i; + + /* Extract axis data from buffer and notify SDL of any changes + * in axis state + */ + for (i = 0; i < joystick->naxes; i++) { + int axisdata = BUFFER_OFFSET(buffer, hwdata->axisBufferOffset[i]); + + /* Clamp axis data to 16-bits to work around possible AI driver bugs */ + if (axisdata > 32767) axisdata = 32767; + if (axisdata < -32768) axisdata = -32768; + + if (axisdata != hwdata->axisData[i]) { + SDL_PrivateJoystickAxis(joystick, i, (Sint16)axisdata); + hwdata->axisData[i] = axisdata; + } + } + + /* Extract button data from buffer and notify SDL of any changes + * in button state + * + * Note: SDL doesn't support analog buttons. + */ + for (i = 0; i < joystick->nbuttons; i++) { + int buttondata = BUFFER_OFFSET(buffer, hwdata->buttonBufferOffset[i]); + + if (buttondata != hwdata->buttonData[i]) { + SDL_PrivateJoystickButton(joystick, i, buttondata ? SDL_PRESSED : SDL_RELEASED); + hwdata->buttonData[i] = buttondata; + } + } + + /* Extract hat data from buffer and notify SDL of any changes + * in hat state + */ + for (i = 0; i < joystick->nhats; i++) { + int hatdata = BUFFER_OFFSET(buffer, hwdata->hatBufferOffset[i]); + + if (hatdata != hwdata->hatData[i]) { + SDL_PrivateJoystickHat(joystick, i, AMIGAINPUT_MapHatData(hatdata)); + hwdata->hatData[i] = hatdata; + } + } + } +} + +/* Function to close a joystick after use */ +static void +AMIGAINPUT_Close(SDL_Joystick * joystick) +{ + dprintf("Closing joystick #%d (AI ID=%d)\n", joystick->instance_id, joystickList[joystick->instance_id].id); + +#if OLDSDK + SDL_IAIN->AIN_ReleaseDevice(joystick->hwdata->context, joystick->hwdata->handle); +#else + SDL_IAIN->ReleaseDevice(joystick->hwdata->context, joystick->hwdata->handle); +#endif + + SDL_free(joystick->hwdata); + joystick->hwdata = NULL; +} + +/* Function to perform any system-specific joystick related cleanup */ +static void +AMIGAINPUT_Quit(void) +{ + uint32 i; + +#if 0 + + // TODO: check whether this kind of work around makes sense anymore. Anyway, + // SDL_Joysticks declaration has changed so code needs work in case of still necessary. + + // PG + // Close any open joysticks before quitting. + // This stops a hang on exit for bad SDL software that doesn't + // explicitly close all their joysticks. + if (SDL_joysticks) { + for (i=0; SDL_joysticks[i]; ++i) { + SDL_SYS_JoystickClose( SDL_joysticks[i] ); + + /* Free the data associated with this joystick */ + if ( SDL_joysticks[i]->axes ) { + SDL_free(SDL_joysticks[i]->axes); + } + if ( SDL_joysticks[i]->hats ) { + SDL_free(SDL_joysticks[i]->hats); + } + if ( SDL_joysticks[i]->balls ) { + SDL_free(SDL_joysticks[i]->balls); + } + if ( SDL_joysticks[i]->buttons ) { + SDL_free(SDL_joysticks[i]->buttons); + } + + SDL_free(SDL_joysticks[i]); + SDL_joysticks[i] = NULL; + } + } + +#endif + + for (i = 0; i < joystickCount; i++) + SDL_free((char *)joystickList[i].name); + + joystickCount = 0; + + if (joystickContext) { +#if OLDSDK + SDL_IAIN->AIN_DeleteContext(joystickContext); +#else + SDL_IAIN->DeleteContext(joystickContext); +#endif + joystickContext = NULL; + } + + AMIGAINPUT_CloseLibrary(); +} + +static SDL_JoystickGUID +AMIGAINPUT_GetDeviceGUID(int device_index) +{ + SDL_JoystickGUID guid; + /* the GUID is just the first 16 chars of the name for now */ + const char *name = AMIGAINPUT_GetDeviceName(device_index); + SDL_zero( guid ); + SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) ); + return guid; +} + +static int +AMIGAINPUT_Rumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ + dprintf("Called\n"); + return SDL_Unsupported(); +} + +static int +AMIGAINPUT_RumbleTriggers(SDL_Joystick * joystick, Uint16 left_rumble, Uint16 right_rumble) +{ + dprintf("Called\n"); + return SDL_Unsupported(); +} + +static SDL_bool +AMIGAINPUT_HasLED(SDL_Joystick * joystick) +{ + dprintf("Called\n"); + return SDL_FALSE; +} + +static int +AMIGAINPUT_SetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + dprintf("Called\n"); + return SDL_Unsupported(); +} + +static int +AMIGAINPUT_SetSensorsEnabled(SDL_Joystick * joystick, SDL_bool enabled) +{ + dprintf("Called\n"); + return SDL_Unsupported(); +} + +static SDL_bool +AMIGAINPUT_GetGamepadMapping(int device_index, SDL_GamepadMapping * out) +{ + dprintf("Called\n"); + return SDL_FALSE; +} + +SDL_JoystickDriver SDL_AMIGAINPUT_JoystickDriver = +{ + AMIGAINPUT_Init, + AMIGAINPUT_GetCount, + AMIGAINPUT_Detect, + AMIGAINPUT_GetDeviceName, + AMIGAINPUT_GetDevicePlayerIndex, + AMIGAINPUT_SetDevicePlayerIndex, + AMIGAINPUT_GetDeviceGUID, + AMIGAINPUT_GetDeviceInstanceID, + AMIGAINPUT_Open, + AMIGAINPUT_Rumble, + AMIGAINPUT_RumbleTriggers, + AMIGAINPUT_HasLED, + AMIGAINPUT_SetLED, + AMIGAINPUT_SetSensorsEnabled, + AMIGAINPUT_Update, + AMIGAINPUT_Close, + AMIGAINPUT_Quit, + AMIGAINPUT_GetGamepadMapping +}; + +#endif /* SDL_JOYSTICK_AMIGAINPUT || SDL_JOYSTICK_DISABLED */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/loadso/amigaos4/SDL_sysloadso.c b/src/loadso/amigaos4/SDL_sysloadso.c new file mode 100644 index 0000000000000..3006420b779f7 --- /dev/null +++ b/src/loadso/amigaos4/SDL_sysloadso.c @@ -0,0 +1,187 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#ifdef SDL_LOADSO_AMIGAOS4 + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* System dependent library loading routines */ + +#include +#include + +static struct Library *elfBase; +static struct Library *dosBase; + +static struct ElfIFace *iElf; +static struct DOSIFace *iDOS; + +#include "SDL_loadso.h" +#include "../../video/amigaos4/SDL_os4library.h" + +#define DEBUG +#include "../../main/amigaos4/SDL_os4debug.h" + +typedef struct { + Elf32_Handle elf_handle; + APTR shared_object; +} OS4_ObjectHandle; + +static void +OS4_CloseLibs() +{ + OS4_DropInterface((void *)&iElf); + OS4_DropInterface((void *)&iDOS); + + iElf = NULL; + iDOS = NULL; + + OS4_CloseLibrary(&elfBase); + OS4_CloseLibrary(&dosBase); + + elfBase = NULL; + dosBase = NULL; +} + +static BOOL +OS4_OpenLibs() +{ + BOOL result = FALSE; + + if (!elfBase) { + elfBase = OS4_OpenLibrary("elf.library", 52); + + if (elfBase) { + iElf = (struct ElfIFace *) OS4_GetInterface(elfBase); + } + } + + if (!dosBase) { + dosBase = OS4_OpenLibrary("dos.library", 51); + + if (dosBase) { + iDOS = (struct DOSIFace *) OS4_GetInterface(dosBase); + } + } + + if (iElf && iDOS) + { + result = TRUE; + } else { + OS4_CloseLibs(); + } + + return result; +} + +void * +SDL_LoadObject(const char *sofile) +{ + if (OS4_OpenLibs()) { + OS4_ObjectHandle *handle = SDL_malloc(sizeof(OS4_ObjectHandle)); + + if (handle) { + BPTR seglist = iDOS->GetProcSegList(NULL, GPSLF_RUN); + + if (seglist) { + Elf32_Handle eh = NULL; + + iDOS->GetSegListInfoTags(seglist, GSLI_ElfHandle, &eh, TAG_DONE); + + dprintf("Elf handle %p\n", eh); + + if (eh) { + APTR so = iElf->DLOpen(eh, sofile, 0); + + if (so) { + dprintf("'%s' loaded\n", sofile); + + handle->elf_handle = eh; + handle->shared_object = so; + + return handle; + } else { + dprintf("DLOpen failed for '%s'\n", sofile); + SDL_SetError("DLOpen failed for '%s'", sofile); + } + } else { + dprintf("Failed to get elf handle of running task\n"); + SDL_SetError("Failed to get elf handle"); + } + } else { + dprintf("Failed to get seglist\n"); + SDL_SetError("Failed to get seglist"); + } + + SDL_free(handle); + } + } + + return NULL; +} + +void * +SDL_LoadFunction(void *handle, const char *name) +{ + void *symbol = NULL; + + if (OS4_OpenLibs() && handle) { + APTR address = NULL; + OS4_ObjectHandle *oh = handle; + + Elf32_Error result = iElf->DLSym(oh->elf_handle, oh->shared_object, name, &address); + + if (result == ELF32_NO_ERROR) { + symbol = address; + dprintf("Symbol '%s' found at %p\n", name, address); + } else { + dprintf("Symbol '%s' not found\n", name); + SDL_SetError("Symbol '%s' not found", name); + } + } + + return symbol; +} + +void +SDL_UnloadObject(void *handle) +{ + if (OS4_OpenLibs() && handle) { + OS4_ObjectHandle *oh = handle; + + Elf32_Error result = iElf->DLClose(oh->elf_handle, oh->shared_object); + + dprintf("DLClose %s\n", (result == ELF32_NO_ERROR) ? "OK" : "failed" ); + +/* BUG: testloadso crashes on Final Edition...removed this block for now, until a solution is found. + IElf->CloseElfTags( + oh->elf_handle, + TAG_DONE); +*/ + SDL_free(handle); + } + + OS4_CloseLibs(); +} + +#endif /* SDL_LOADSO_AMIGAOS4 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/main/amigaos4/SDL_dummy_main.c b/src/main/amigaos4/SDL_dummy_main.c new file mode 100644 index 0000000000000..0174136b2211d --- /dev/null +++ b/src/main/amigaos4/SDL_dummy_main.c @@ -0,0 +1,28 @@ +/* + SDL_dummy_main.c, placed in the public domain by Sam Lantinga 3/13/14 +*/ +#include "../../SDL_internal.h" + +/* Include the SDL main definition header */ +#include "SDL_main.h" + +#ifdef main +#undef main +int +main(int argc, char *argv[]) +{ + return (SDL_main(argc, argv)); +} +#else +/* Nothing to do on this platform */ +int +SDL_main_stub_symbol(void); + +int +SDL_main_stub_symbol(void) +{ + return 0; +} +#endif + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/main/amigaos4/SDL_os4debug.h b/src/main/amigaos4/SDL_os4debug.h new file mode 100644 index 0000000000000..6133af3a877a5 --- /dev/null +++ b/src/main/amigaos4/SDL_os4debug.h @@ -0,0 +1,35 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef SDL_OS4DEBUG_H +#define SDL_OS4DEBUG_H + +#include + +#ifndef DEBUG +# define dprintf(format, args...) +# define kprintf(format, args...) +#else /* DEBUG */ +# define dprintf(format, args...) IExec->DebugPrintF("[%s] " format, __PRETTY_FUNCTION__ , ## args) +//# define dprintf(format, args...)((struct ExecIFace *)((*(struct ExecBase **)4)->MainInterface))->DebugPrintF("[%s] " format, __PRETTY_FUNCTION__ , ## args) +# define kprintf(format, args...)((struct ExecIFace *)((*(struct ExecBase **)4)->MainInterface))->DebugPrintF(format, ## args) +#endif /* DEBUG */ + +#endif /* SDL_OS4DEBUG_H */ diff --git a/src/main/amigaos4/SDL_os4version.c b/src/main/amigaos4/SDL_os4version.c new file mode 100644 index 0000000000000..d8da95fa91826 --- /dev/null +++ b/src/main/amigaos4/SDL_os4version.c @@ -0,0 +1,25 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2020 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifdef __AMIGADATE__ +static const char* const version __attribute__ ((used)) = "\0$VER: libSDL2.so 0.14 (" __AMIGADATE__ ")\0"; +#endif + diff --git a/src/misc/amigaos4/SDL_sysurl.c b/src/misc/amigaos4/SDL_sysurl.c new file mode 100644 index 0000000000000..b3f3498c93a97 --- /dev/null +++ b/src/misc/amigaos4/SDL_sysurl.c @@ -0,0 +1,65 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2021 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "../SDL_sysurl.h" + +#include "../../video/amigaos4/SDL_os4library.h" + +#define DEBUG +#include "../../main/amigaos4/SDL_os4debug.h" + +#include + +int +SDL_SYS_OpenURL(const char *url) +{ + int result = -1; + + struct Library* dosBase = OS4_OpenLibrary(DOSNAME, 50); + + if (dosBase) { + struct DOSIFace* iDOS = (struct DOSIFace *)OS4_GetInterface(dosBase); + + if (iDOS) { + char buffer[1024]; + snprintf(buffer, sizeof(buffer), "URL:%s", url); + + BPTR handle = iDOS->Open(buffer, MODE_OLDFILE); + + if (handle) { + iDOS->Close(handle); + dprintf("URL '%s' opened\n", url); + result = 0; + } else { + dprintf("Failed to open URL '%s'\n", url); + } + + OS4_DropInterface((void *)&iDOS); + } + + OS4_CloseLibrary(&dosBase); + } + + return result; +} + +/* vi: set ts=4 sw=4 expandtab: */ + diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c index 8288b0f3ccc00..20699734381ad 100644 --- a/src/render/SDL_render.c +++ b/src/render/SDL_render.c @@ -92,6 +92,9 @@ this should probably be removed at some point in the future. --ryan. */ #if !SDL_RENDER_DISABLED static const SDL_RenderDriver *render_drivers[] = { +#if SDL_VIDEO_RENDER_AMIGAOS4 + &OS4_RenderDriver, +#endif #if SDL_VIDEO_RENDER_D3D &D3D_RenderDriver, #endif diff --git a/src/render/SDL_sysrender.h b/src/render/SDL_sysrender.h index 84411082bc030..9cd1c4cc22aae 100644 --- a/src/render/SDL_sysrender.h +++ b/src/render/SDL_sysrender.h @@ -249,6 +249,7 @@ extern SDL_RenderDriver GLES_RenderDriver; extern SDL_RenderDriver DirectFB_RenderDriver; extern SDL_RenderDriver METAL_RenderDriver; extern SDL_RenderDriver PSP_RenderDriver; +extern SDL_RenderDriver OS4_RenderDriver; extern SDL_RenderDriver SW_RenderDriver; extern SDL_RenderDriver VITA_GLES2_RenderDriver; extern SDL_RenderDriver VITA_GXM_RenderDriver; diff --git a/src/render/amigaos4/SDL_rc_draw.c b/src/render/amigaos4/SDL_rc_draw.c new file mode 100644 index 0000000000000..ee3a2fc72234a --- /dev/null +++ b/src/render/amigaos4/SDL_rc_draw.c @@ -0,0 +1,619 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2018 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_RENDER_AMIGAOS4 && !SDL_RENDER_DISABLED + +#include "SDL_render_compositing.h" +#include "SDL_rc_draw.h" + +#include + +#define DEBUG +#include "../../main/amigaos4/SDL_os4debug.h" + +typedef struct { + int x1, y1, x2, y2; + Uint32 (*blendfp)(Uint32, Uint8, Uint8, Uint8, Uint8); + Uint32 *baseaddress; + Uint32 width; + SDL_bool last; + Uint8 sr; + Uint8 sg; + Uint8 sb; + Uint8 sa; +} OS4_LineData; + +#define ABS(a) (((a) < 0) ? -(a) : (a)) +#define ROUNDF(a) (int)((a) + 0.5f) + +static inline Uint32* +OS4_GetMemoryAddress(Uint32 * memory, Uint32 width, Uint16 x, Uint16 y) +{ + return memory + x + y * width; +} + +static inline Uint32 +OS4_GetPixel(Uint32 * memory, Uint32 width, Uint16 x, Uint16 y) +{ + return *(memory + x + y * width); +} + +static inline void +OS4_SetPixel(Uint32 * memory, Uint32 width, Uint16 x, Uint16 y, Uint32 color) +{ + *(memory + x + y * width) = color; +} + +static inline Uint8 +ALPHA(Uint32 c) +{ + return (c >> 24); +} + +static inline Uint8 +RED(Uint32 c) +{ + return (c >> 16); +} + +static inline Uint8 +GREEN(Uint32 c) +{ + return (c >> 8); +} + +static inline Uint8 +BLUE(Uint32 c) +{ + return c; +} + +static inline Uint8 +MUL(Uint8 a, Uint8 b) +{ + Uint32 u = (a * b) / 255; + return u; +} + +static inline Uint8 +ADD(Uint8 a, Uint8 b) +{ + Uint32 c = a + b; + + if (c > 255) c = 255; + + return c; +} + +static Uint32 +BlendPoint(Uint32 old, Uint8 sr, Uint8 sg, Uint8 sb, Uint8 sa) +{ + Uint8 dr, dg, db, da, one_minus_alpha; + + one_minus_alpha = 255 - sa; + + dr = sr + MUL(one_minus_alpha, RED(old)); + dg = sg + MUL(one_minus_alpha, GREEN(old)); + db = sb + MUL(one_minus_alpha, BLUE(old)); + da = sa + MUL(one_minus_alpha, ALPHA(old)); + + return da << 24 | dr << 16 | dg << 8 | db; +} + +static Uint32 +AddPoint(Uint32 old, Uint8 sr, Uint8 sg, Uint8 sb, Uint8 sa) +{ + Uint8 dr, dg, db, da; + + dr = ADD(sr, RED(old)); + dg = ADD(sg, GREEN(old)); + db = ADD(sb, BLUE(old)); + da = ALPHA(old); + + return da << 24 | dr << 16 | dg << 8 | db; +} + +static Uint32 +ModPoint(Uint32 old, Uint8 sr, Uint8 sg, Uint8 sb, Uint8 sa) +{ + Uint8 dr, dg, db, da; + + dr = MUL(sr, RED(old)); + dg = MUL(sg, GREEN(old)); + db = MUL(sb, BLUE(old)); + da = ALPHA(old); + + return da << 24 | dr << 16 | dg << 8 | db; +} + +static Uint32 +NopPoint(Uint32 old, Uint8 sr, Uint8 sg, Uint8 sb, Uint8 sa) +{ + return old; +} + +int +OS4_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, + int count, SDL_BlendMode mode, Uint8 a, Uint8 r, Uint8 g, Uint8 b) +{ + OS4_RenderData *data = (OS4_RenderData *) renderer->driverdata; + struct BitMap *bitmap = OS4_ActivateRenderer(renderer); + int i, status; + + int minx, miny, maxx, maxy; + + if (!bitmap) { + return -1; + } + + minx = data->cliprect.x; + miny = data->cliprect.y; + maxx = data->cliprect.x + data->cliprect.w - 1; + maxy = data->cliprect.y + data->cliprect.h - 1; + + if (mode == SDL_BLENDMODE_NONE) { + + int32 ret = 0; + + const Uint32 color = a << 24 | r << 16 | g << 8 | b; + + for (i = 0; i < count; ++i) { + + int x, y; + + x = points[i].x; + y = points[i].y; + + /* Clipping - is it possible clip with RastPort? */ + if (x < minx || x > maxx || y < miny || y > maxy) { + continue; + } + + ret |= data->iGraphics->WritePixelColor( + &data->rastport, + x, + y, + color); + } + + status = ret ? -1 : 0; + + } else { + + APTR baseaddress; + uint32 bytesperrow; + + APTR lock = data->iGraphics->LockBitMapTags( + bitmap, + LBM_BaseAddress, &baseaddress, + LBM_BytesPerRow, &bytesperrow, + TAG_DONE); + + if (lock) { + + Uint32 (*blendfp)(Uint32, Uint8, Uint8, Uint8, Uint8); + + const Uint32 width = bytesperrow / 4; + Uint8 sr, sg, sb, sa; + + switch (mode) { + case SDL_BLENDMODE_BLEND: + sr = MUL(a, r); + sg = MUL(a, g); + sb = MUL(a, b); + sa = a; + blendfp = BlendPoint; + break; + case SDL_BLENDMODE_ADD: + sr = MUL(a, r); + sg = MUL(a, g); + sb = MUL(a, b); + sa = 0; + blendfp = AddPoint; + break; + case SDL_BLENDMODE_MOD: + sr = r; + sg = g; + sb = b; + sa = 0; + blendfp = ModPoint; + break; + default: + dprintf("Unknown blend mode %d\n", mode); + sr = r; + sg = g; + sb = b; + sa = a; + blendfp = NopPoint; + break; + } + + for (i = 0; i < count; ++i) { + Uint32 newcolor, oldcolor; + int x, y; + + x = points[i].x; + y = points[i].y; + + /* Clipping */ + if (x < minx || x > maxx || y < miny || y > maxy) { + continue; + } + + oldcolor = OS4_GetPixel(baseaddress, width, x, y); + + newcolor = blendfp(oldcolor, sr, sg, sb, sa); + + OS4_SetPixel(baseaddress, width, x, y, newcolor); + } + + data->iGraphics->UnlockBitMap(lock); + + status = 0; + } else { + dprintf("Lock failed\n"); + status = -1; + } + } + + return status; +} + +static void +OS4_HLine(OS4_LineData * data) +{ + int x, minx, maxx; + Uint32 *memory; + + if (data->x1 < data->x2) { + minx = data->x1; + maxx = data->x2; + + if (!data->last) { + --maxx; + } + } else { + minx = data->x2; + maxx = data->x1; + + if (!data->last) { + ++minx; + } + } + + memory = OS4_GetMemoryAddress(data->baseaddress, data->width, minx, data->y1); + + for (x = minx; x <= maxx; ++x) { + Uint32 oldcolor, newcolor; + + oldcolor = *memory; + newcolor = data->blendfp(oldcolor, data->sr, data->sg, data->sb, data->sa); + *memory++ = newcolor; + } +} + +static void +OS4_VLine(OS4_LineData * data) +{ + int y, miny, maxy; + Uint32 *memory; + + if (data->y1 < data->y2) { + miny = data->y1; + maxy = data->y2; + + if (!data->last) { + --maxy; + } + } else { + miny = data->y2; + maxy = data->y1; + + if (!data->last) { + ++miny; + } + } + + memory = OS4_GetMemoryAddress(data->baseaddress, data->width, data->x1, miny); + + for (y = miny; y <= maxy; ++y) { + Uint32 oldcolor, newcolor; + + oldcolor = *memory; + newcolor = data->blendfp(oldcolor, data->sr, data->sg, data->sb, data->sa); + *memory = newcolor; + memory += data->width; + } +} + +static void +OS4_DLine(OS4_LineData * data) +{ + int x, y, startx, starty, endx, endy, ystep, width; + Uint32 *memory; + + if (data->x1 < data->x2) { + startx = data->x1; + starty = data->y1; + + endx = data->x2; + endy = data->y2; + + if (!data->last) { + //--endx; + } + } else { + startx = data->x2; + starty = data->y2; + + endx = data->x1; + endy = data->y1; + + if (!data->last) { + //++startx; + } + } + + if (endy < starty) { + ystep = -1; + width = -data->width; + } else { + ystep = 1; + width = data->width; + } + + memory = OS4_GetMemoryAddress(data->baseaddress, data->width, startx, starty); + + //dprintf("%d, %d -> %d, %d, ystep %d\n", data->x1, data->y1, data->x2, data->y2, ystep); + + for (x = startx, y = starty; x <= endx; ++x, y += ystep) { + Uint32 oldcolor, newcolor; + + oldcolor = *memory; + newcolor = data->blendfp(oldcolor, data->sr, data->sg, data->sb, data->sa); + *memory++ = newcolor; + memory += width; + } +} + +static void +OS4_Line(OS4_LineData *data) +{ + float ystep; + int x, y, startx, starty, endx, endy; + Uint32 *memory; + + if (data->x1 < data->x2) { + startx = data->x1; + starty = data->y1; + + endx = data->x2; + endy = data->y2; + } else { + startx = data->x2; + starty = data->y2; + + endx = data->x1; + endy = data->y1; + } + + // TODO: last + ystep = (float)(endy - starty) / (float)(endx - startx); + + //dprintf("%d, %d -> %d, %d, ystep %d\n", data->x1, data->y1, data->x2, data->y2, (int)(10 * ystep)); + + memory = OS4_GetMemoryAddress(data->baseaddress, data->width, startx, starty); + + if (ystep > 0.5f || ystep < -0.5f) { + + float xstep = 1.0f / ystep; + float fx = startx; + + int lastx = startx; + + for (y = starty ; y <= endy; fx += xstep, ++y) { + + Uint32 oldcolor, newcolor; + + x = ROUNDF(fx); + + oldcolor = *memory; + newcolor = data->blendfp(oldcolor, data->sr, data->sg, data->sb, data->sa); + *memory = newcolor; + memory += data->width; + + memory += (x - lastx); + lastx = x; + } + + } else { + float fy = starty; + + int lasty = starty; + + for (x = startx ; x <= endx; ++x, fy += ystep ) { + Uint32 oldcolor, newcolor; + int diff; + + y = ROUNDF(fy); + + oldcolor = *memory; + newcolor = data->blendfp(oldcolor, data->sr, data->sg, data->sb, data->sa); + *memory++ = newcolor; + + diff = y - lasty; + if (diff < 0) { + memory -= data->width; + lasty = y; + } else if (diff > 0) { + memory += data->width; + lasty = y; + } + } + } +} + +static void +OS4_BlendLine(OS4_LineData * data) +{ + if (data->y1 == data->y2) { + OS4_HLine(data); + } else if (data->x1 == data->x2) { + OS4_VLine(data); + } else if (ABS(data->x1 - data->x2) == ABS(data->y1 - data->y2)) { + OS4_DLine(data); + } else { + OS4_Line(data); + } +} + +int +OS4_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, + int count, SDL_BlendMode mode, Uint8 a, Uint8 r, Uint8 g, Uint8 b) +{ + OS4_RenderData *data = (OS4_RenderData *) renderer->driverdata; + struct BitMap *bitmap = OS4_ActivateRenderer(renderer); + + int i, status; + + if (!bitmap) { + return -1; + } + + if (mode == SDL_BLENDMODE_NONE) { + + const Uint32 color = a << 24 | r << 16 | g << 8 | b; + + data->iGraphics->SetRPAttrs(&data->rastport, RPTAG_APenColor, color, TAG_DONE); + + for (i = 0; i < count - 1; ++i) { + + int x1, y1, x2, y2; + + x1 = points[i].x; + y1 = points[i].y; + x2 = points[i + 1].x; + y2 = points[i + 1].y; + + /* Clipping - is it possible to do with RastPort? */ + if (!SDL_IntersectRectAndLine(&data->cliprect, &x1, &y1, &x2, &y2)) { + continue; + } + + data->iGraphics->Move( + &data->rastport, + x1, + y1); + + data->iGraphics->Draw( + &data->rastport, + x2, + y2); + } + + status = 0; + } else { + + APTR baseaddress; + uint32 bytesperrow; + + APTR lock = data->iGraphics->LockBitMapTags( + bitmap, + LBM_BaseAddress, &baseaddress, + LBM_BytesPerRow, &bytesperrow, + TAG_DONE); + + if (lock) { + + OS4_LineData ld; + ld.baseaddress = baseaddress; + ld.width = bytesperrow / 4; + ld.last = SDL_FALSE; + + switch (mode) { + case SDL_BLENDMODE_BLEND: + ld.sr = MUL(a, r); + ld.sg = MUL(a, g); + ld.sb = MUL(a, b); + ld.sa = a; + ld.blendfp = BlendPoint; + break; + case SDL_BLENDMODE_ADD: + ld.sr = MUL(a, r); + ld.sg = MUL(a, g); + ld.sb = MUL(a, b); + ld.sa = 0; + ld.blendfp = AddPoint; + break; + case SDL_BLENDMODE_MOD: + ld.sr = r; + ld.sg = g; + ld.sb = b; + ld.sa = a; + ld.blendfp = ModPoint; + break; + default: + dprintf("Unknown blend mode %d\n", mode); + ld.sr = r; + ld.sg = g; + ld.sb = b; + ld.sa = a; + ld.blendfp = NopPoint; + break; + } + + for (i = 0; i < count - 1; ++i) { + + ld.x1 = points[i].x; + ld.y1 = points[i].y; + ld.x2 = points[i + 1].x; + ld.y2 = points[i + 1].y; + + /* Clipping */ + if (!SDL_IntersectRectAndLine(&data->cliprect, &ld.x1, &ld.y1, &ld.x2, &ld.y2)) { + continue; + } + + if (i == count - 2) { + ld.last = SDL_TRUE; + } + + OS4_BlendLine(&ld); + } + + data->iGraphics->UnlockBitMap(lock); + + status = 0; + } else { + dprintf("Lock failed\n"); + status = -1; + } + + } + + return status; +} + +#endif /* !SDL_RENDER_DISABLED */ + +/* vi: set ts=4 sw=4 expandtab: */ + diff --git a/src/render/amigaos4/SDL_rc_draw.h b/src/render/amigaos4/SDL_rc_draw.h new file mode 100644 index 0000000000000..1998ecded15da --- /dev/null +++ b/src/render/amigaos4/SDL_rc_draw.h @@ -0,0 +1,37 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2018 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#ifndef _SDL_rc_draw_h +#define _SDL_rc_draw_h + +#include "../SDL_sysrender.h" + +extern int OS4_RenderDrawPoints(SDL_Renderer * renderer, + const SDL_Point * points, int count, SDL_BlendMode mode, Uint8 a, Uint8 r, Uint8 g, Uint8 b); + +extern int OS4_RenderDrawLines(SDL_Renderer * renderer, + const SDL_Point * points, int count, SDL_BlendMode mode, Uint8 a, Uint8 r, Uint8 g, Uint8 b); + +#endif + +/* vi: set ts=4 sw=4 expandtab: */ + diff --git a/src/render/amigaos4/SDL_rc_texture.c b/src/render/amigaos4/SDL_rc_texture.c new file mode 100644 index 0000000000000..b5af26fb1a4be --- /dev/null +++ b/src/render/amigaos4/SDL_rc_texture.c @@ -0,0 +1,355 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2018 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_RENDER_AMIGAOS4 && !SDL_RENDER_DISABLED + +#include "SDL_render_compositing.h" +#include "SDL_rc_texture.h" + +#include + +#define DEBUG +#include "../../main/amigaos4/SDL_os4debug.h" + +static SDL_bool +OS4_IsBlendModeSupported(SDL_BlendMode mode) +{ + switch (mode) { + case SDL_BLENDMODE_NONE: + case SDL_BLENDMODE_BLEND: + case SDL_BLENDMODE_ADD: + //dprintf("Texture blend mode: %d\n", mode); + return SDL_TRUE; + default: + dprintf("Not supported blend mode %d\n", mode); + return SDL_FALSE; + } +} + +int +OS4_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) +{ + int bpp; + Uint32 Rmask, Gmask, Bmask, Amask; + OS4_TextureData *texturedata; + + if (texture->format != SDL_PIXELFORMAT_ARGB8888) { + return SDL_SetError("Not supported texture format"); + } + + if (!SDL_PixelFormatEnumToMasks + (texture->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) { + return SDL_SetError("Unknown texture format"); + } + + //dprintf("Allocation VRAM bitmap %d*%d*%d for texture\n", texture->w, texture->h, bpp); + + texturedata = SDL_calloc(1, sizeof(*texturedata)); + if (!texturedata) + { + dprintf("Failed to allocate driver data\n"); + return SDL_OutOfMemory(); + } + + texturedata->bitmap = OS4_AllocBitMap(renderer, texture->w, texture->h, bpp); + + if (!texturedata->bitmap) { + dprintf("Failed to allocate bitmap\n"); + SDL_free(texturedata); + return SDL_SetError("Failed to allocate bitmap"); + } + + /* Check texture parameters just for debug */ + //OS4_IsColorModEnabled(texture); + OS4_IsBlendModeSupported(texture->blendMode); + + texture->driverdata = texturedata; + + return 0; +} + +static SDL_bool +OS4_ModulateRGB(SDL_Renderer * renderer, SDL_Texture * texture, Uint8 * src, int pitch) +{ + SDL_bool result = SDL_FALSE; + + OS4_RenderData *data = (OS4_RenderData *) renderer->driverdata; + OS4_TextureData *texturedata = (OS4_TextureData *) texture->driverdata; + + if (texturedata->finalbitmap) { + APTR baseaddress; + uint32 bytesperrow; + + APTR lock = data->iGraphics->LockBitMapTags( + texturedata->finalbitmap, + LBM_BaseAddress, &baseaddress, + LBM_BytesPerRow, &bytesperrow, + TAG_DONE); + + if (lock) { + int y; + + for (y = 0; y < texture->h; y++) { + + Uint32 *readaddress = (Uint32 *)(src + y * pitch); + Uint32 *writeaddress = (Uint32 *)(baseaddress + y * bytesperrow); + + int x; + + for (x = 0; x < texture->w; x++) { + + Uint32 oldcolor = readaddress[x]; + Uint32 newcolor = (oldcolor & 0xFF000000); + + Uint8 r = (oldcolor & 0x00FF0000) >> 16; + Uint8 g = (oldcolor & 0x0000FF00) >> 8; + Uint8 b = (oldcolor & 0x000000FF); + + newcolor |= ((r * texture->r) / 255) << 16; + newcolor |= ((g * texture->g) / 255) << 8; + newcolor |= ((b * texture->b) / 255); + + writeaddress[x] = newcolor; + } + } + + data->iGraphics->UnlockBitMap(texturedata->finalbitmap); + + result = SDL_TRUE; + } else { + dprintf("Lock failed\n"); + } + } + + return result; +} + +static SDL_bool +OS4_NeedRemodulation(SDL_Texture * texture) +{ + OS4_TextureData *texturedata = (OS4_TextureData *) texture->driverdata; + + if (texture->r != texturedata->r || + texture->g != texturedata->g || + texture->b != texturedata->b || + texturedata->finalbitmap == NULL) { + + return SDL_TRUE; + } + + return SDL_FALSE; +} + +int +OS4_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture) +{ + /* Modulate only when needed, it's CPU heavy */ + if (OS4_IsColorModEnabled(texture) && OS4_NeedRemodulation(texture)) { + + OS4_RenderData *data = (OS4_RenderData *) renderer->driverdata; + OS4_TextureData *texturedata = (OS4_TextureData *) texture->driverdata; + + if (!texturedata->rambuf) { + struct BitMap *oldRastPortBM; + + if (!(texturedata->rambuf = SDL_malloc(texture->w * texture->h * sizeof(Uint32)))) { + dprintf("Failed to allocate ram buffer\n"); + return SDL_OutOfMemory(); + } + + /* Copy texture from VRAM to RAM buffer for faster color modulation. We also + temporarily borrow rastport from renderer */ + oldRastPortBM = data->rastport.BitMap; + + data->rastport.BitMap = texturedata->bitmap; + + data->iGraphics->ReadPixelArray( + &data->rastport, + 0, + 0, + texturedata->rambuf, + 0, + 0, + texture->w * sizeof(Uint32), + PIXF_A8R8G8B8, + texture->w, + texture->h); + + data->rastport.BitMap = oldRastPortBM; + } + + if (!texturedata->finalbitmap) { + if (!(texturedata->finalbitmap = OS4_AllocBitMap(renderer, texture->w, texture->h, 32))) { + dprintf("Failed to allocate final bitmap\n"); + return SDL_OutOfMemory(); + } + } + + if (!OS4_ModulateRGB(renderer, texture, texturedata->rambuf, texture->w * sizeof(Uint32))) { + return SDL_SetError("RGB modulation failed"); + } + + /* Remember last values so that we can avoid re-modulation with same parameters */ + texturedata->r = texture->r; + texturedata->g = texture->g; + texturedata->b = texture->b; + } + + return 0; +} + +int +OS4_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, const void *pixels, int pitch) +{ + OS4_RenderData *data = (OS4_RenderData *) renderer->driverdata; + OS4_TextureData *texturedata = (OS4_TextureData *) texture->driverdata; + + int32 ret = data->iGraphics->BltBitMapTags( + BLITA_Source, pixels, + BLITA_SrcType, BLITT_ARGB32, + BLITA_SrcBytesPerRow, pitch, + BLITA_Dest, texturedata->bitmap, + BLITA_DestX, rect->x, + BLITA_DestY, rect->y, + BLITA_Width, rect->w, + BLITA_Height, rect->h, + TAG_DONE); + + if (ret != -1) { + dprintf("BltBitMapTags(): %d\n", ret); + return SDL_SetError("BltBitMapTags failed"); + } + + if (OS4_IsColorModEnabled(texture)) { + + if (!texturedata->finalbitmap) { + if (!(texturedata->finalbitmap = OS4_AllocBitMap(renderer, texture->w, texture->h, 32))) { + dprintf("Failed to allocate final bitmap\n"); + return SDL_OutOfMemory(); + } + } + + // This can be really slow, if done per frame + if (!OS4_ModulateRGB(renderer, texture, (Uint8 *)pixels, pitch)) { + return SDL_SetError("RGB modulation failed"); + } + } + + return 0; +} + +int +OS4_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, void **pixels, int *pitch) +{ + OS4_RenderData *data = (OS4_RenderData *) renderer->driverdata; + OS4_TextureData *texturedata = (OS4_TextureData *) texture->driverdata; + + APTR baseaddress; + uint32 bytesperrow; + + //dprintf("Called\n"); + + texturedata->lock = data->iGraphics->LockBitMapTags( + texturedata->bitmap, + LBM_BaseAddress, &baseaddress, + LBM_BytesPerRow, &bytesperrow, + TAG_DONE); + + if (texturedata->lock) { + *pixels = + (void *) ((Uint8 *) baseaddress + rect->y * bytesperrow + + rect->x * 4); + + *pitch = bytesperrow; + + return 0; + } else { + dprintf("Lock failed\n"); + return SDL_SetError("Lock failed"); + } +} + +void +OS4_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) +{ + OS4_RenderData *data = (OS4_RenderData *) renderer->driverdata; + OS4_TextureData *texturedata = (OS4_TextureData *) texture->driverdata; + + //dprintf("Called\n"); + + if (texturedata->lock) { + data->iGraphics->UnlockBitMap(texturedata->lock); + texturedata->lock = NULL; + } +} + +int +OS4_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture) +{ + OS4_RenderData *data = (OS4_RenderData *) renderer->driverdata; + + if (texture) { + OS4_TextureData *texturedata = (OS4_TextureData *) texture->driverdata; + data->target = texturedata->bitmap; + + //dprintf("Render target texture %p (bitmap %p)\n", texture, data->target); + } else { + data->target = data->bitmap; + //dprintf("Render target window\n"); + } + return 0; +} + +void +OS4_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) +{ + OS4_RenderData *data = (OS4_RenderData *) renderer->driverdata; + OS4_TextureData *texturedata = (OS4_TextureData *) texture->driverdata; + + if (texturedata) { + if (texturedata->bitmap) { + //dprintf("Freeing texture bitmap %p\n", texturedata->bitmap); + + data->iGraphics->FreeBitMap(texturedata->bitmap); + texturedata->bitmap = NULL; + } + + if (texturedata->finalbitmap) { + data->iGraphics->FreeBitMap(texturedata->finalbitmap); + texturedata->finalbitmap = NULL; + } + + if (texturedata->rambuf) { + SDL_free(texturedata->rambuf); + texturedata->rambuf = NULL; + } + + SDL_free(texturedata); + } +} + +#endif /* !SDL_RENDER_DISABLED */ + +/* vi: set ts=4 sw=4 expandtab: */ + diff --git a/src/render/amigaos4/SDL_rc_texture.h b/src/render/amigaos4/SDL_rc_texture.h new file mode 100644 index 0000000000000..20e2ce013867d --- /dev/null +++ b/src/render/amigaos4/SDL_rc_texture.h @@ -0,0 +1,58 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2018 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#ifndef _SDL_rc_texture_h +#define _SDL_rc_texture_h + +#include "../SDL_sysrender.h" + +typedef struct +{ + struct BitMap *bitmap; + struct BitMap *finalbitmap; /* Contains color modulated version of bitmap */ + APTR lock; + Uint8 r, g, b; /* Last known color modulation parameters */ + Uint8 *rambuf; /* Work buffer for color modulation */ +} OS4_TextureData; + +extern int OS4_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture); + +extern int OS4_SetTextureColorMod(SDL_Renderer * renderer, + SDL_Texture * texture); + +extern int OS4_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, const void *pixels, + int pitch); + +extern int OS4_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture); + +extern int OS4_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, void **pixels, int *pitch); + +extern void OS4_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture); + +extern void OS4_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture); + +#endif + +/* vi: set ts=4 sw=4 expandtab: */ + diff --git a/src/render/amigaos4/SDL_render_compositing.c b/src/render/amigaos4/SDL_render_compositing.c new file mode 100644 index 0000000000000..0d5d236dec182 --- /dev/null +++ b/src/render/amigaos4/SDL_render_compositing.c @@ -0,0 +1,969 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2020 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_RENDER_AMIGAOS4 && !SDL_RENDER_DISABLED + +#include "SDL_render_compositing.h" +#include "SDL_rc_texture.h" +#include "SDL_rc_draw.h" + +#include "../SDL_sysrender.h" + +#include "../../video/SDL_sysvideo.h" +#include "../../video/amigaos4/SDL_os4window.h" +#include "../../video/amigaos4/SDL_os4video.h" + +#include +#include +#include + +#define DEBUG +#include "../../main/amigaos4/SDL_os4debug.h" + +/* AmigaOS4 (compositing) renderer implementation + +TODO: + +- SDL_BlendMode_Mod: is it impossible to accelerate? +- Blended line drawing could probably be optimized +- Batching RenderCopy(Ex) should be now possible. + +NOTE: + +- compositing is used for blended rectangles and texture blitting +- blended lines and points are drawn with the CPU as compositing doesn't support these primitives + (could try small triangles to plot a point?) +- texture color modulation is implemented by CPU + +*/ + +typedef struct { + float x, y; + float s, t, w; +} OS4_Vertex; + +static const uint16 OS4_QuadIndices[] = { + 0, 1, 2, 2, 3, 0 +}; + +typedef struct { + float srcAlpha; + float destAlpha; + uint32 flags; +} OS4_CompositingParams; + +SDL_bool +OS4_IsColorModEnabled(SDL_Texture * texture) +{ + if ((texture->r & texture->g & texture->b) != 255) { + //dprintf("Color mod enabled (%d, %d, %d)\n", texture->r, texture->g, texture->b); + return SDL_TRUE; + } + + return SDL_FALSE; +} + +struct BitMap * +OS4_AllocBitMap(SDL_Renderer * renderer, int width, int height, int depth) { + OS4_RenderData *data = (OS4_RenderData *) renderer->driverdata; + + return data->iGraphics->AllocBitMapTags( + width, + height, + depth, + BMATags_Displayable, TRUE, + BMATags_PixelFormat, PIXF_A8R8G8B8, + //BMATags_Clear, TRUE, + TAG_DONE); +} + +struct BitMap * +OS4_ActivateRenderer(SDL_Renderer * renderer) +{ + OS4_RenderData *data = (OS4_RenderData *) renderer->driverdata; + + if (!data->target) { + data->target = data->bitmap; + } + + if (!data->target && renderer->window) { + + int width = renderer->window->w; + int height = renderer->window->h; + int depth = 32; + + dprintf("Allocating VRAM bitmap %d*%d*%d for renderer\n", width, height, depth); + + data->target = data->bitmap = OS4_AllocBitMap(renderer, width, height, depth); + + if (!data->bitmap) { + dprintf("Allocation failed\n"); + } + } + + if (!data->solidcolor) { + int width = 1; + int height = 1; + int depth = 32; + + data->solidcolor = OS4_AllocBitMap(renderer, width, height, depth); + + if (!data->solidcolor) { + dprintf("Failed to allocate solid color bitmap\n"); + } + } + + data->rastport.BitMap = data->target; + + return data->target; +} + +static void +OS4_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event) +{ + OS4_RenderData *data = (OS4_RenderData *) renderer->driverdata; + + dprintf("Called with event %d\n", event->event); + + if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED) { + + /* Next time ActivateRenderer() is called, new bitmap will be created */ + if (data->bitmap) { + + dprintf("Freeing renderer bitmap %p\n", data->bitmap); + + data->iGraphics->FreeBitMap(data->bitmap); + data->bitmap = NULL; + data->target = NULL; + } + } +} + +static int +OS4_GetBitMapSize(SDL_Renderer * renderer, struct BitMap * bitmap, int * w, int * h) +{ + OS4_RenderData *data = (OS4_RenderData *) renderer->driverdata; + + if (bitmap) { + if (w) { + *w = data->iGraphics->GetBitMapAttr(bitmap, BMA_ACTUALWIDTH); + //dprintf("w=%d\n", *w); + } + if (h) { + *h = data->iGraphics->GetBitMapAttr(bitmap, BMA_HEIGHT); + //dprintf("h=%d\n", *h); + } + + return 0; + } else { + SDL_SetError("NULL bitmap"); + return -1; + } +} + +static int +OS4_GetOutputSize(SDL_Renderer * renderer, int *w, int *h) +{ + struct BitMap * bitmap = OS4_ActivateRenderer(renderer); + + if (!bitmap) { + SDL_SetError("OS4 renderer doesn't have an output bitmap"); + return -1; + } + + return OS4_GetBitMapSize(renderer, bitmap, w, h); +} + +/* Special function to set our 1 * 1 * 32 bitmap */ +static SDL_bool +OS4_SetSolidColor(SDL_Renderer * renderer, Uint32 color) +{ + OS4_RenderData *data = (OS4_RenderData *) renderer->driverdata; + + if (data->solidcolor) { + APTR baseaddress; + + APTR lock = data->iGraphics->LockBitMapTags( + data->solidcolor, + LBM_BaseAddress, &baseaddress, + TAG_DONE); + + if (lock) { + *(Uint32 *)baseaddress = color; + + data->iGraphics->UnlockBitMap(data->solidcolor); + + return SDL_TRUE; + } else { + dprintf("Lock failed\n"); + } + } + + return SDL_FALSE; +} + +static uint32 +OS4_ConvertBlendMode(SDL_BlendMode mode) +{ + switch (mode) { + case SDL_BLENDMODE_NONE: + return COMPOSITE_Src; + case SDL_BLENDMODE_BLEND: + return COMPOSITE_Src_Over_Dest; + case SDL_BLENDMODE_ADD: + return COMPOSITE_Plus; + case SDL_BLENDMODE_MOD: + // This is not correct, but we can't do modulation at the moment + return COMPOSITE_Src_Over_Dest; + default: + dprintf("Unknown blend mode %d\n", mode); + return COMPOSITE_Src_Over_Dest; + } +} + +static uint32 +OS4_GetCompositeFlags(SDL_BlendMode mode) +{ + uint32 flags = COMPFLAG_IgnoreDestAlpha | COMPFLAG_HardwareOnly; + + if (mode == SDL_BLENDMODE_NONE) { + flags |= COMPFLAG_SrcAlphaOverride; + } + + return flags; +} + +static void +OS4_SetupCompositing(SDL_Texture * dst, OS4_CompositingParams * params, SDL_ScaleMode scaleMode, SDL_BlendMode blendMode, Uint8 alpha) +{ + params->flags = COMPFLAG_HardwareOnly; + + if (scaleMode != SDL_ScaleModeNearest) { + params->flags |= COMPFLAG_SrcFilter; + } + + if (blendMode == SDL_BLENDMODE_NONE) { + if (!dst) { + params->flags |= COMPFLAG_SrcAlphaOverride; + } + params->srcAlpha = 1.0f; + } else { + params->srcAlpha = alpha / 255.0f; + } + + params->destAlpha = 1.0f; +} + +static void +OS4_RotateVertices(OS4_Vertex vertices[4], const double angle, const SDL_FPoint * center) +{ + int i; + + float rads = angle * M_PI / 180.0f; + + float sina = SDL_sinf(rads); + float cosa = SDL_cosf(rads); + + for (i = 0; i < 4; ++i) { + float x = vertices[i].x - center->x; + float y = vertices[i].y - center->y; + + vertices[i].x = x * cosa - y * sina + center->x; + vertices[i].y = x * sina + y * cosa + center->y; + } +} + +static void +OS4_FillVertexData(OS4_Vertex vertices[4], const SDL_Rect * srcrect, const SDL_Rect * dstrect, + const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip) +{ + /* Flip texture coordinates if needed */ + + Uint16 left, right, top, bottom, tmp; + + left = srcrect->x; + right = left + srcrect->w; + top = srcrect->y; + bottom = top + srcrect->h; + + if (flip & SDL_FLIP_HORIZONTAL) { + tmp = left; + left = right; + right = tmp; + } + + if (flip & SDL_FLIP_VERTICAL) { + tmp = bottom; + bottom = top; + top = tmp; + } + + /* + + Plan is to draw quad with two triangles: + + v0-v3 + | \ | + v1-v2 + + */ + + vertices[0].x = dstrect->x; + vertices[0].y = dstrect->y; + vertices[0].s = left; + vertices[0].t = top; + vertices[0].w = 1.0f; + + vertices[1].x = dstrect->x; + vertices[1].y = dstrect->y + dstrect->h; + vertices[1].s = left; + vertices[1].t = bottom; + vertices[1].w = 1.0f; + + vertices[2].x = dstrect->x + dstrect->w; + vertices[2].y = dstrect->y + dstrect->h; + vertices[2].s = right; + vertices[2].t = bottom; + vertices[2].w = 1.0f; + + vertices[3].x = dstrect->x + dstrect->w; + vertices[3].y = dstrect->y; + vertices[3].s = right; + vertices[3].t = top; + vertices[3].w = 1.0f; + + if (angle != 0.0) { + OS4_RotateVertices(vertices, angle, center); + } +} + +static int +OS4_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * points, int count, SDL_BlendMode mode, + Uint8 a, Uint8 r, Uint8 g, Uint8 b) +{ + OS4_RenderData *data = (OS4_RenderData *) renderer->driverdata; + struct BitMap *bitmap = OS4_ActivateRenderer(renderer); + int i, status; + + //dprintf("Called for %d rects\n", count); + //Sint32 s = SDL_GetTicks(); + + if (!bitmap) { + return -1; + } + + if (mode == SDL_BLENDMODE_NONE) { + + const Uint32 color = a << 24 | r << 16 | g << 8 | b; + + for (i = 0; i < count; ++i) { + + SDL_Rect clipped; + + /* Perform clipping - is it possible to use RastPort? */ + if (!SDL_IntersectRect(&points[i], &data->cliprect, &clipped)) { + continue; + } + + data->iGraphics->RectFillColor( + &data->rastport, + clipped.x, + clipped.y, + clipped.x + clipped.w - 1, + clipped.y + clipped.h - 1, + color); // graphics.lib v54! + } + + status = 0; + } else { + + Uint32 colormod; + + if (!data->solidcolor) { + return -1; + } + + colormod = a << 24 | r << 16 | g << 8 | b; + + // Color modulation is implemented through fill texture manipulation + if (!OS4_SetSolidColor(renderer, colormod)) { + return -1; + } + + /* TODO: batch */ + for (i = 0; i < count; ++i) { + + const SDL_Rect srcrect = { 0, 0, 1, 1 }; + + OS4_Vertex vertices[4]; + + uint32 ret_code; + + OS4_FillVertexData(vertices, &srcrect, &points[i], 0.0, NULL, SDL_FLIP_NONE); + + ret_code = data->iGraphics->CompositeTags( + OS4_ConvertBlendMode(mode), + data->solidcolor, + bitmap, + COMPTAG_DestX, data->cliprect.x, + COMPTAG_DestY, data->cliprect.y, + COMPTAG_DestWidth, data->cliprect.w, + COMPTAG_DestHeight, data->cliprect.h, + COMPTAG_Flags, OS4_GetCompositeFlags(mode), + COMPTAG_VertexArray, vertices, + COMPTAG_VertexFormat, COMPVF_STW0_Present, + COMPTAG_NumTriangles, 2, + COMPTAG_IndexArray, OS4_QuadIndices, + TAG_END); + + if (ret_code) { + static Uint32 counter; + + if ((counter++ % 100) == 0) { + dprintf("CompositeTags: %d (fails: %u)\n", ret_code, counter); + } + } + } + + status = 0; + } + + //dprintf("Took %d\n", SDL_GetTicks() - s); + + return status; +} + +static int +OS4_RenderCopyEx(SDL_Renderer * renderer, SDL_RenderCommand * cmd, const OS4_Vertex * vertices, + struct BitMap * dst) +{ + SDL_Texture * texture = cmd->data.draw.texture; + const SDL_BlendMode mode = cmd->data.draw.blend; + + OS4_RenderData *data = (OS4_RenderData *) renderer->driverdata; + OS4_TextureData *texturedata = (OS4_TextureData *) texture->driverdata; + + struct BitMap *src = OS4_IsColorModEnabled(texture) ? + texturedata->finalbitmap : texturedata->bitmap; + + OS4_CompositingParams params; + uint32 ret_code; + + if (!dst) { + return -1; + } + + OS4_SetupCompositing(renderer->target, ¶ms, texture->scaleMode, mode, cmd->data.draw.a); + + ret_code = data->iGraphics->CompositeTags( + OS4_ConvertBlendMode(mode), + src, + dst, + COMPTAG_SrcAlpha, COMP_FLOAT_TO_FIX(params.srcAlpha), + COMPTAG_DestAlpha, COMP_FLOAT_TO_FIX(params.destAlpha), + COMPTAG_DestX, data->cliprect.x, + COMPTAG_DestY, data->cliprect.y, + COMPTAG_DestWidth, data->cliprect.w, + COMPTAG_DestHeight, data->cliprect.h, + COMPTAG_Flags, params.flags, + COMPTAG_VertexArray, vertices, + COMPTAG_VertexFormat, COMPVF_STW0_Present, + COMPTAG_NumTriangles, 2, + COMPTAG_IndexArray, OS4_QuadIndices, + TAG_END); + + if (ret_code) { + static Uint32 counter; + + if ((counter++ % 100) == 0) { + dprintf("CompositeTags: %d (fails: %u)\n", ret_code, counter); + } + + return SDL_SetError("CompositeTags failed"); + } + + return 0; +} + +static int +OS4_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, + Uint32 format, void * pixels, int pitch) +{ + OS4_RenderData *data = (OS4_RenderData *) renderer->driverdata; + SDL_Rect final_rect; + + struct BitMap *bitmap = OS4_ActivateRenderer(renderer); + + //dprintf("Called\n"); + + if (!bitmap) { + return -1; + } + + if (renderer->viewport.x || renderer->viewport.y) { + final_rect.x = renderer->viewport.x + rect->x; + final_rect.y = renderer->viewport.y + rect->y; + final_rect.w = rect->w; + final_rect.h = rect->h; + rect = &final_rect; + } + + if (rect->x < 0 || rect->x+rect->w > renderer->window->w || + rect->y < 0 || rect->y+rect->h > renderer->window->h) { + return SDL_SetError("Tried to read outside of surface bounds"); + } + + if (format != SDL_PIXELFORMAT_ARGB8888) { + return SDL_SetError("Unsupported pixel format"); + } + + data->iGraphics->ReadPixelArray( + &data->rastport, + rect->x, + rect->y, + pixels, + 0, + 0, + pitch, + PIXF_A8R8G8B8, + rect->w, + rect->h); + + return 0; +} + +static int min(int a, int b) +{ + return (a < b) ? a : b; +} + +static void +OS4_RenderPresent(SDL_Renderer * renderer) +{ + SDL_Window *window = renderer->window; + struct BitMap *source = OS4_ActivateRenderer(renderer); + + //dprintf("Called\n"); + //Uint32 s = SDL_GetTicks(); + + if (window && source) { + OS4_RenderData *data = (OS4_RenderData *)renderer->driverdata; + + // TODO: should we take viewport into account? + + SDL_WindowData *windowdata = (SDL_WindowData *)window->driverdata; + + struct Window *syswin = windowdata->syswin; + + if (syswin) { + + int32 ret; + int width; + int height; + + //dprintf("target %p\n", data->target); + + if (data->vsyncEnabled) { + data->iGraphics->WaitTOF(); + } + + data->iLayers->LockLayer(0, syswin->WLayer); + + width = min(window->w, syswin->Width - (syswin->BorderLeft + syswin->BorderRight)); + height = min(window->h, syswin->Height - (syswin->BorderTop + syswin->BorderBottom)); + + ret = data->iGraphics->BltBitMapTags( + BLITA_Source, source, + BLITA_DestType, BLITT_RASTPORT, + BLITA_Dest, syswin->RPort, + BLITA_DestX, syswin->BorderLeft, + BLITA_DestY, syswin->BorderTop, + BLITA_Width, width, + BLITA_Height, height, + TAG_DONE); + + data->iLayers->UnlockLayer(syswin->WLayer); + + if (ret != -1) { + dprintf("BltBitMapTags(): %d\n", ret); + } + } + } + //dprintf("Took %d\n", SDL_GetTicks() - s); +} + +static void +OS4_RenderClear(SDL_Renderer * renderer, Uint8 a, Uint8 r, Uint8 g, Uint8 b, struct BitMap * bitmap) +{ + OS4_RenderData *data = (OS4_RenderData *) renderer->driverdata; + const Uint32 color = (a << 24) | (r << 16) | (g << 8) | b; + + int width = 0; + int height = 0; + + OS4_GetBitMapSize(renderer, bitmap, &width, &height); + + data->iGraphics->RectFillColor( + &data->rastport, + 0, + 0, + width - 1, + height - 1, + color); // graphics.lib v54! +} + +static void +OS4_DestroyRenderer(SDL_Renderer * renderer) +{ + OS4_RenderData *data = (OS4_RenderData *) renderer->driverdata; + + if (data->bitmap) { + dprintf("Freeing renderer bitmap %p\n", data->bitmap); + + data->iGraphics->FreeBitMap(data->bitmap); + data->bitmap = NULL; + } + + if (data->solidcolor) { + data->iGraphics->FreeBitMap(data->solidcolor); + data->solidcolor = NULL; + } + + SDL_free(data); + SDL_free(renderer); +} + +static int +OS4_QueueNop(SDL_Renderer * renderer, SDL_RenderCommand *cmd) +{ + return 0; +} + +static int +OS4_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count) +{ + SDL_Point *verts = (SDL_Point *) SDL_AllocateRenderVertices(renderer, count * sizeof(SDL_Point), 0, &cmd->data.draw.first); + size_t i; + + if (!verts) { + return -1; + } + + cmd->data.draw.count = count; + + if (renderer->viewport.x || renderer->viewport.y) { + const int x = renderer->viewport.x; + const int y = renderer->viewport.y; + for (i = 0; i < count; i++, verts++, points++) { + verts->x = (int)(x + points->x); + verts->y = (int)(y + points->y); + } + } else { + for (i = 0; i < count; i++, verts++, points++) { + verts->x = (int)points->x; + verts->y = (int)points->y; + } + } + + return 0; +} + +static int +OS4_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count) +{ + return OS4_QueueDrawPoints(renderer, cmd, points, count); +} + +static int +OS4_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count) +{ + SDL_Rect *verts = (SDL_Rect *) SDL_AllocateRenderVertices(renderer, count * sizeof(SDL_Rect), 0, &cmd->data.draw.first); + size_t i; + + if (!verts) { + return -1; + } + + cmd->data.draw.count = count; + + if (renderer->viewport.x || renderer->viewport.y) { + const int x = renderer->viewport.x; + const int y = renderer->viewport.y; + + for (i = 0; i < count; i++, verts++, rects++) { + verts->x = (int)(x + rects->x); + verts->y = (int)(y + rects->y); + verts->w = SDL_max((int)rects->w, 1); + verts->h = SDL_max((int)rects->h, 1); + } + } else { + for (i = 0; i < count; i++, verts++, rects++) { + verts->x = (int)rects->x; + verts->y = (int)rects->y; + verts->w = SDL_max((int)rects->w, 1); + verts->h = SDL_max((int)rects->h, 1); + } + } + + return 0; +} + +static int +OS4_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture, + const SDL_Rect * srcrect, const SDL_FRect * dstrect, + const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip) +{ + SDL_Rect final_rect; + SDL_FPoint final_center; + + OS4_Vertex *verts = (OS4_Vertex *) SDL_AllocateRenderVertices(renderer, + 4 * sizeof(OS4_Vertex), 0, &cmd->data.draw.first); + + if (!verts) { + return -1; + } + + cmd->data.draw.count = 1; + + if (renderer->viewport.x || renderer->viewport.y) { + final_rect.x = (int)(renderer->viewport.x + dstrect->x); + final_rect.y = (int)(renderer->viewport.y + dstrect->y); + } else { + final_rect.x = (int)dstrect->x; + final_rect.y = (int)dstrect->y; + } + + final_rect.w = (int)dstrect->w; + final_rect.h = (int)dstrect->h; + + final_center.x = dstrect->x + center->x; + final_center.y = dstrect->y + center->y; + + OS4_FillVertexData(verts, srcrect, &final_rect, angle, &final_center, flip); + + return OS4_SetTextureColorMod(renderer, texture); +} + +static int +OS4_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand * cmd, SDL_Texture * texture, + const SDL_Rect * srcrect, const SDL_FRect *dstrect) +{ + const SDL_FPoint center = { 0.0, 0.0 }; + return OS4_QueueCopyEx(renderer, cmd, texture, srcrect, dstrect, 0.0, ¢er, SDL_FLIP_NONE); +} + +static int +OS4_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand * cmd, void * vertices, size_t vertsize) +{ + OS4_RenderData *data = (OS4_RenderData *)renderer->driverdata; + + struct BitMap *bitmap = OS4_ActivateRenderer(renderer); + + if (!bitmap) { + dprintf("NULL bitmap\n"); + return -1; + } + + while (cmd) { + switch (cmd->command) { + case SDL_RENDERCMD_SETDRAWCOLOR: + // Nothing to do + break; + + case SDL_RENDERCMD_SETVIEWPORT: { + SDL_Rect *viewport = &data->viewport; + if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof(SDL_Rect)) != 0) { + SDL_memcpy(viewport, &cmd->data.viewport.rect, sizeof(SDL_Rect)); + + //dprintf("viewport %d, %d\n", viewport->w, viewport->h); + + if (!data->cliprect_enabled) { + // CompositeTags uses cliprect: with clipping disabled, maximize it + SDL_memcpy(&data->cliprect, viewport, sizeof(SDL_Rect)); + } + } + break; + } + + case SDL_RENDERCMD_SETCLIPRECT: { + const SDL_Rect *rect = &cmd->data.cliprect.rect; + if (data->cliprect_enabled != cmd->data.cliprect.enabled) { + data->cliprect_enabled = cmd->data.cliprect.enabled; + + //dprintf("cliprect enabled %d\n", data->cliprect_enabled); + } + + if (SDL_memcmp(&data->cliprect, rect, sizeof(SDL_Rect)) != 0) { + SDL_memcpy(&data->cliprect, rect, sizeof(SDL_Rect)); + + //dprintf("cliprect %d, %d\n", data->cliprect.w, data->cliprect.h); + } + + if (!data->cliprect_enabled) { + // CompositeTags uses cliprect: with clipping disabled, maximize it + SDL_memcpy(&data->cliprect, &data->viewport, sizeof(SDL_Rect)); + } + break; + } + + case SDL_RENDERCMD_CLEAR: { + const Uint8 r = cmd->data.color.r; + const Uint8 g = cmd->data.color.g; + const Uint8 b = cmd->data.color.b; + const Uint8 a = cmd->data.color.a; + OS4_RenderClear(renderer, a, r, g, b, bitmap); + break; + } + + case SDL_RENDERCMD_DRAW_POINTS: { + const Uint8 r = cmd->data.draw.r; + const Uint8 g = cmd->data.draw.g; + const Uint8 b = cmd->data.draw.b; + const Uint8 a = cmd->data.draw.a; + const size_t count = cmd->data.draw.count; + const SDL_Point *verts = (SDL_Point *)(((Uint8 *) vertices) + cmd->data.draw.first); + const SDL_BlendMode blend = cmd->data.draw.blend; + OS4_RenderDrawPoints(renderer, verts, count, blend, a, r, g, b); + break; + } + + case SDL_RENDERCMD_DRAW_LINES: { + const Uint8 r = cmd->data.draw.r; + const Uint8 g = cmd->data.draw.g; + const Uint8 b = cmd->data.draw.b; + const Uint8 a = cmd->data.draw.a; + const size_t count = cmd->data.draw.count; + const SDL_Point *verts = (SDL_Point *)(((Uint8 *) vertices) + cmd->data.draw.first); + const SDL_BlendMode blend = cmd->data.draw.blend; + OS4_RenderDrawLines(renderer, verts, count, blend, a, r, g, b); + break; + } + + case SDL_RENDERCMD_FILL_RECTS: { + const Uint8 r = cmd->data.draw.r; + const Uint8 g = cmd->data.draw.g; + const Uint8 b = cmd->data.draw.b; + const Uint8 a = cmd->data.draw.a; + const size_t count = cmd->data.draw.count; + const SDL_Rect *verts = (SDL_Rect *)(((Uint8 *) vertices) + cmd->data.draw.first); + const SDL_BlendMode blend = cmd->data.draw.blend; + OS4_RenderFillRects(renderer, verts, count, blend, a, r, g, b); + break; + } + + case SDL_RENDERCMD_COPY: { + const OS4_Vertex *verts = (OS4_Vertex *)(((Uint8 *) vertices) + cmd->data.draw.first); + OS4_RenderCopyEx(renderer, cmd, verts, bitmap); + break; + } + + case SDL_RENDERCMD_COPY_EX: { + const OS4_Vertex *verts = (OS4_Vertex *)(((Uint8 *) vertices) + cmd->data.draw.first); + OS4_RenderCopyEx(renderer, cmd, verts, bitmap); + break; + } + + case SDL_RENDERCMD_NO_OP: + break; + } + + cmd = cmd->next; + } + + return 0; +} + +SDL_Renderer * +OS4_CreateRenderer(SDL_Window * window, Uint32 flags) +{ + SDL_VideoData *videodata = (SDL_VideoData *)SDL_GetVideoDevice()->driverdata; + SDL_Renderer *renderer; + OS4_RenderData *data; + + dprintf("Creating renderer for '%s' (flags 0x%x)\n", window->title, flags); + + renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer)); + if (!renderer) { + SDL_OutOfMemory(); + return NULL; + } + + data = (OS4_RenderData *) SDL_calloc(1, sizeof(*data)); + if (!data) { + OS4_DestroyRenderer(renderer); + SDL_OutOfMemory(); + return NULL; + } + + renderer->WindowEvent = OS4_WindowEvent; + renderer->GetOutputSize = OS4_GetOutputSize; + renderer->CreateTexture = OS4_CreateTexture; + renderer->UpdateTexture = OS4_UpdateTexture; + renderer->LockTexture = OS4_LockTexture; + renderer->UnlockTexture = OS4_UnlockTexture; + renderer->SetRenderTarget = OS4_SetRenderTarget; + renderer->QueueSetViewport = OS4_QueueNop; + renderer->QueueSetDrawColor = OS4_QueueNop; + renderer->QueueDrawPoints = OS4_QueueDrawPoints; + renderer->QueueDrawLines = OS4_QueueDrawLines; + renderer->QueueFillRects = OS4_QueueFillRects; + renderer->QueueCopy = OS4_QueueCopy; + renderer->QueueCopyEx = OS4_QueueCopyEx; + renderer->RunCommandQueue = OS4_RunCommandQueue; + renderer->RenderReadPixels = OS4_RenderReadPixels; + renderer->RenderPresent = OS4_RenderPresent; + renderer->DestroyTexture = OS4_DestroyTexture; + renderer->DestroyRenderer = OS4_DestroyRenderer; + renderer->info = OS4_RenderDriver.info; + + renderer->driverdata = data; + + data->iGraphics = videodata->iGraphics; + data->iLayers = videodata->iLayers; + + data->iGraphics->InitRastPort(&data->rastport); + + data->vsyncEnabled = flags & SDL_RENDERER_PRESENTVSYNC; + + dprintf("VSYNC: %s\n", data->vsyncEnabled ? "on" : "off"); + + return renderer; +} + +SDL_RenderDriver OS4_RenderDriver = { + OS4_CreateRenderer, + { + "compositing", + SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE | SDL_RENDERER_PRESENTVSYNC, + 1, + { + SDL_PIXELFORMAT_ARGB8888, + }, + 0, + 0 + } +}; + +#endif /* !SDL_RENDER_DISABLED */ + +/* vi: set ts=4 sw=4 expandtab: */ + diff --git a/src/render/amigaos4/SDL_render_compositing.h b/src/render/amigaos4/SDL_render_compositing.h new file mode 100644 index 0000000000000..d440518ed8b05 --- /dev/null +++ b/src/render/amigaos4/SDL_render_compositing.h @@ -0,0 +1,54 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2020 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#ifndef _SDL_render_compositing_h +#define _SDL_render_compositing_h + +#include "../SDL_sysrender.h" + +#include "graphics/rastport.h" + +typedef struct +{ + struct GraphicsIFace *iGraphics; + struct LayersIFace * iLayers; + struct BitMap *bitmap; + struct BitMap *target; + struct BitMap *solidcolor; + struct RastPort rastport; + + SDL_Rect cliprect; + SDL_bool cliprect_enabled; + + SDL_Rect viewport; + + SDL_bool vsyncEnabled; +} OS4_RenderData; + +extern struct BitMap * OS4_ActivateRenderer(SDL_Renderer * renderer); +extern struct BitMap * OS4_AllocBitMap(SDL_Renderer * renderer, int width, int height, int depth); +extern SDL_bool OS4_IsColorModEnabled(SDL_Texture * texture); + +#endif + +/* vi: set ts=4 sw=4 expandtab: */ + diff --git a/src/render/opengl/SDL_glfuncs.h b/src/render/opengl/SDL_glfuncs.h index 498dd10861518..c8e43079cc1d0 100644 --- a/src/render/opengl/SDL_glfuncs.h +++ b/src/render/opengl/SDL_glfuncs.h @@ -36,7 +36,11 @@ SDL_PROC_UNUSED(void, glBitmap, (GLsizei, GLsizei, GLfloat, GLfloat, GLfloat, GLfloat, const GLubyte *)) SDL_PROC(void, glBlendEquation, (GLenum)) +#ifdef __AMIGAOS4__ +SDL_PROC(void, glBlendFunc, (GLenum, GLenum)) +#else SDL_PROC_UNUSED(void, glBlendFunc, (GLenum, GLenum)) +#endif SDL_PROC(void, glBlendFuncSeparate, (GLenum, GLenum, GLenum, GLenum)) SDL_PROC_UNUSED(void, glCallList, (GLuint)) SDL_PROC_UNUSED(void, glCallLists, (GLsizei, GLenum, const GLvoid *)) diff --git a/src/render/opengl/SDL_render_gl.c b/src/render/opengl/SDL_render_gl.c index 514ca27e502ea..a122b50af64db 100644 --- a/src/render/opengl/SDL_render_gl.c +++ b/src/render/opengl/SDL_render_gl.c @@ -35,8 +35,13 @@ * these should match the defaults selected in SDL_GL_ResetAttributes */ +#ifdef __AMIGAOS4__ +#define RENDERER_CONTEXT_MAJOR 1 +#define RENDERER_CONTEXT_MINOR 3 +#else #define RENDERER_CONTEXT_MAJOR 2 #define RENDERER_CONTEXT_MINOR 1 +#endif /* OpenGL renderer implementation */ @@ -235,6 +240,12 @@ GL_LoadFunctions(GL_RenderData * data) #define SDL_PROC(ret,func,params) data->func=func; #else int retval = 0; +#ifdef __AMIGAOS4__ +#define SDL_PROC(ret,func,params) \ + do { \ + data->func = SDL_GL_GetProcAddress(#func); \ + } while ( 0 ); +#else #define SDL_PROC(ret,func,params) \ do { \ data->func = SDL_GL_GetProcAddress(#func); \ @@ -242,6 +253,7 @@ GL_LoadFunctions(GL_RenderData * data) retval = SDL_SetError("Couldn't load GL function %s: %s", #func, SDL_GetError()); \ } \ } while ( 0 ); +#endif #endif /* __SDL_NOGETPROCADDR__ */ #include "SDL_glfuncs.h" @@ -1052,6 +1064,29 @@ GL_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * te return 0; } +static void +GlBlendModeHack(GL_RenderData * data, const SDL_BlendMode mode) +{ + switch (mode) { + case SDL_BLENDMODE_NONE: + data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + data->glDisable(GL_BLEND); + break; + + case SDL_BLENDMODE_ADD: + data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + data->glEnable(GL_BLEND); + data->glBlendFunc(GL_SRC_ALPHA, GL_DST_COLOR); + break; + + default: + data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + data->glEnable(GL_BLEND); + data->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + break; + } +} + static void SetDrawState(GL_RenderData *data, const SDL_RenderCommand *cmd, const GL_Shader shader) { @@ -1094,16 +1129,22 @@ SetDrawState(GL_RenderData *data, const SDL_RenderCommand *cmd, const GL_Shader } if (blend != data->drawstate.blend) { - if (blend == SDL_BLENDMODE_NONE) { - data->glDisable(GL_BLEND); + + if (data->glBlendFuncSeparate && data->glBlendEquation) { + if (blend == SDL_BLENDMODE_NONE) { + data->glDisable(GL_BLEND); + } else { + data->glEnable(GL_BLEND); + data->glBlendFuncSeparate(GetBlendFunc(SDL_GetBlendModeSrcColorFactor(blend)), + GetBlendFunc(SDL_GetBlendModeDstColorFactor(blend)), + GetBlendFunc(SDL_GetBlendModeSrcAlphaFactor(blend)), + GetBlendFunc(SDL_GetBlendModeDstAlphaFactor(blend))); + data->glBlendEquation(GetBlendEquation(SDL_GetBlendModeColorOperation(blend))); + } } else { - data->glEnable(GL_BLEND); - data->glBlendFuncSeparate(GetBlendFunc(SDL_GetBlendModeSrcColorFactor(blend)), - GetBlendFunc(SDL_GetBlendModeDstColorFactor(blend)), - GetBlendFunc(SDL_GetBlendModeSrcAlphaFactor(blend)), - GetBlendFunc(SDL_GetBlendModeDstAlphaFactor(blend))); - data->glBlendEquation(GetBlendEquation(SDL_GetBlendModeColorOperation(blend))); + GlBlendModeHack(data, blend); } + data->drawstate.blend = blend; } diff --git a/src/render/opengles2/SDL_render_gles2.c b/src/render/opengles2/SDL_render_gles2.c index f36b34f906176..bbd2e3eeab10c 100644 --- a/src/render/opengles2/SDL_render_gles2.c +++ b/src/render/opengles2/SDL_render_gles2.c @@ -145,7 +145,9 @@ typedef struct GLES2_RenderData SDL_bool debug_enabled; -#define SDL_PROC(ret,func,params) ret (APIENTRY *func) params; +/* AmigaOS 4 workaround: add "my" prefix to function pointer names because glCall gets extended to IOGLES2->glCall + which doesn't compile in cases of data->glCall */ +#define SDL_PROC(ret,func,params) ret (APIENTRY *my##func) params; #include "SDL_gles2funcs.h" #undef SDL_PROC GLES2_FBOList *framebuffers; @@ -191,7 +193,7 @@ GL_ClearErrors(SDL_Renderer *renderer) if (!data->debug_enabled) { return; } - while (data->glGetError() != GL_NO_ERROR) { + while (data->myglGetError() != GL_NO_ERROR) { /* continue; */ } } @@ -207,7 +209,7 @@ GL_CheckAllErrors (const char *prefix, SDL_Renderer *renderer, const char *file, } /* check gl errors (can return multiple errors) */ for (;;) { - GLenum error = data->glGetError(); + GLenum error = data->myglGetError(); if (error != GL_NO_ERROR) { if (prefix == NULL || prefix[0] == '\0') { prefix = "generic"; @@ -243,12 +245,12 @@ static int GLES2_LoadFunctions(GLES2_RenderData * data) #endif #if defined __SDL_NOGETPROCADDR__ -#define SDL_PROC(ret,func,params) data->func=func; +#define SDL_PROC(ret,func,params) data->my##func=func; #else #define SDL_PROC(ret,func,params) \ do { \ - data->func = SDL_GL_GetProcAddress(#func); \ - if ( ! data->func ) { \ + data->my##func = SDL_GL_GetProcAddress(#func); \ + if ( ! data->my##func ) { \ return SDL_SetError("Couldn't load GLES2 function %s: %s", #func, SDL_GetError()); \ } \ } while ( 0 ); @@ -270,7 +272,7 @@ GLES2_GetFBO(GLES2_RenderData *data, Uint32 w, Uint32 h) result = SDL_malloc(sizeof(GLES2_FBOList)); result->w = w; result->h = h; - data->glGenFramebuffers(1, &result->FBO); + data->myglGenFramebuffers(1, &result->FBO); result->next = data->framebuffers; data->framebuffers = result; } @@ -303,7 +305,7 @@ GLES2_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event) if (event->event == SDL_WINDOWEVENT_MINIMIZED) { /* According to Apple documentation, we need to finish drawing NOW! */ - data->glFinish(); + data->myglFinish(); } } @@ -418,17 +420,17 @@ GLES2_CacheProgram(GLES2_RenderData *data, GLuint vertex, GLuint fragment) entry->fragment_shader = fragment; /* Create the program and link it */ - entry->id = data->glCreateProgram(); - data->glAttachShader(entry->id, vertex); - data->glAttachShader(entry->id, fragment); - data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_POSITION, "a_position"); - data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_TEXCOORD, "a_texCoord"); - data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_ANGLE, "a_angle"); - data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_CENTER, "a_center"); - data->glLinkProgram(entry->id); - data->glGetProgramiv(entry->id, GL_LINK_STATUS, &linkSuccessful); + entry->id = data->myglCreateProgram(); + data->myglAttachShader(entry->id, vertex); + data->myglAttachShader(entry->id, fragment); + data->myglBindAttribLocation(entry->id, GLES2_ATTRIBUTE_POSITION, "a_position"); + data->myglBindAttribLocation(entry->id, GLES2_ATTRIBUTE_TEXCOORD, "a_texCoord"); + data->myglBindAttribLocation(entry->id, GLES2_ATTRIBUTE_ANGLE, "a_angle"); + data->myglBindAttribLocation(entry->id, GLES2_ATTRIBUTE_CENTER, "a_center"); + data->myglLinkProgram(entry->id); + data->myglGetProgramiv(entry->id, GL_LINK_STATUS, &linkSuccessful); if (!linkSuccessful) { - data->glDeleteProgram(entry->id); + data->myglDeleteProgram(entry->id); SDL_free(entry); SDL_SetError("Failed to link shader program"); return NULL; @@ -436,33 +438,33 @@ GLES2_CacheProgram(GLES2_RenderData *data, GLuint vertex, GLuint fragment) /* Predetermine locations of uniform variables */ entry->uniform_locations[GLES2_UNIFORM_PROJECTION] = - data->glGetUniformLocation(entry->id, "u_projection"); + data->myglGetUniformLocation(entry->id, "u_projection"); entry->uniform_locations[GLES2_UNIFORM_TEXTURE_V] = - data->glGetUniformLocation(entry->id, "u_texture_v"); + data->myglGetUniformLocation(entry->id, "u_texture_v"); entry->uniform_locations[GLES2_UNIFORM_TEXTURE_U] = - data->glGetUniformLocation(entry->id, "u_texture_u"); + data->myglGetUniformLocation(entry->id, "u_texture_u"); entry->uniform_locations[GLES2_UNIFORM_TEXTURE] = - data->glGetUniformLocation(entry->id, "u_texture"); + data->myglGetUniformLocation(entry->id, "u_texture"); entry->uniform_locations[GLES2_UNIFORM_COLOR] = - data->glGetUniformLocation(entry->id, "u_color"); + data->myglGetUniformLocation(entry->id, "u_color"); entry->color = 0; - data->glUseProgram(entry->id); + data->myglUseProgram(entry->id); if (entry->uniform_locations[GLES2_UNIFORM_TEXTURE_V] != -1) { - data->glUniform1i(entry->uniform_locations[GLES2_UNIFORM_TEXTURE_V], 2); /* always texture unit 2. */ + data->myglUniform1i(entry->uniform_locations[GLES2_UNIFORM_TEXTURE_V], 2); /* always texture unit 2. */ } if (entry->uniform_locations[GLES2_UNIFORM_TEXTURE_U] != -1) { - data->glUniform1i(entry->uniform_locations[GLES2_UNIFORM_TEXTURE_U], 1); /* always texture unit 1. */ + data->myglUniform1i(entry->uniform_locations[GLES2_UNIFORM_TEXTURE_U], 1); /* always texture unit 1. */ } if (entry->uniform_locations[GLES2_UNIFORM_TEXTURE] != -1) { - data->glUniform1i(entry->uniform_locations[GLES2_UNIFORM_TEXTURE], 0); /* always texture unit 0. */ + data->myglUniform1i(entry->uniform_locations[GLES2_UNIFORM_TEXTURE], 0); /* always texture unit 0. */ } if (entry->uniform_locations[GLES2_UNIFORM_PROJECTION] != -1) { - data->glUniformMatrix4fv(entry->uniform_locations[GLES2_UNIFORM_PROJECTION], 1, GL_FALSE, (GLfloat *)entry->projection); + data->myglUniformMatrix4fv(entry->uniform_locations[GLES2_UNIFORM_PROJECTION], 1, GL_FALSE, (GLfloat *)entry->projection); } if (entry->uniform_locations[GLES2_UNIFORM_COLOR] != -1) { - data->glUniform4f(entry->uniform_locations[GLES2_UNIFORM_COLOR], 0.0f, 0.0f, 0.0f, 0.0f); + data->myglUniform4f(entry->uniform_locations[GLES2_UNIFORM_COLOR], 0.0f, 0.0f, 0.0f, 0.0f); } /* Cache the linked program */ @@ -477,7 +479,7 @@ GLES2_CacheProgram(GLES2_RenderData *data, GLuint vertex, GLuint fragment) /* Evict the last entry from the cache if we exceed the limit */ if (data->program_cache.count > GLES2_MAX_CACHED_PROGRAMS) { - data->glDeleteProgram(data->program_cache.tail->id); + data->myglDeleteProgram(data->program_cache.tail->id); data->program_cache.tail = data->program_cache.tail->prev; if (data->program_cache.tail != NULL) { SDL_free(data->program_cache.tail->next); @@ -501,21 +503,21 @@ GLES2_CacheShader(GLES2_RenderData *data, GLES2_ShaderType type, GLenum shader_t } /* Compile */ - id = data->glCreateShader(shader_type); - data->glShaderSource(id, 1, (const char**)&shader_src, NULL); - data->glCompileShader(id); - data->glGetShaderiv(id, GL_COMPILE_STATUS, &compileSuccessful); + id = data->myglCreateShader(shader_type); + data->myglShaderSource(id, 1, (const char**)&shader_src, NULL); + data->myglCompileShader(id); + data->myglGetShaderiv(id, GL_COMPILE_STATUS, &compileSuccessful); if (!compileSuccessful) { SDL_bool isstack = SDL_FALSE; char *info = NULL; int length = 0; - data->glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length); + data->myglGetShaderiv(id, GL_INFO_LOG_LENGTH, &length); if (length > 0) { info = SDL_small_alloc(char, length, &isstack); if (info) { - data->glGetShaderInfoLog(id, length, &length, info); + data->myglGetShaderInfoLog(id, length, &length, info); } } if (info) { @@ -524,7 +526,7 @@ GLES2_CacheShader(GLES2_RenderData *data, GLES2_ShaderType type, GLenum shader_t } else { SDL_SetError("Failed to load the shader"); } - data->glDeleteShader(id); + data->myglDeleteShader(id); return 0; } @@ -646,7 +648,7 @@ GLES2_SelectProgram(GLES2_RenderData *data, GLES2_ImageSource source, int w, int } /* Select that program in OpenGL */ - data->glUseProgram(program->id); + data->myglUseProgram(program->id); /* Set the current program */ data->drawstate.program = program; @@ -896,7 +898,7 @@ SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_I if (data->drawstate.viewport_dirty) { const SDL_Rect *viewport = &data->drawstate.viewport; - data->glViewport(viewport->x, + data->myglViewport(viewport->x, data->drawstate.target ? viewport->y : (data->drawstate.drawableh - viewport->y - viewport->h), viewport->w, viewport->h); if (viewport->w && viewport->h) { @@ -909,9 +911,9 @@ SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_I if (data->drawstate.cliprect_enabled_dirty) { if (!data->drawstate.cliprect_enabled) { - data->glDisable(GL_SCISSOR_TEST); + data->myglDisable(GL_SCISSOR_TEST); } else { - data->glEnable(GL_SCISSOR_TEST); + data->myglEnable(GL_SCISSOR_TEST); } data->drawstate.cliprect_enabled_dirty = SDL_FALSE; } @@ -919,7 +921,7 @@ SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_I if (data->drawstate.cliprect_enabled && data->drawstate.cliprect_dirty) { const SDL_Rect *viewport = &data->drawstate.viewport; const SDL_Rect *rect = &data->drawstate.cliprect; - data->glScissor(viewport->x + rect->x, + data->myglScissor(viewport->x + rect->x, data->drawstate.target ? viewport->y + rect->y : data->drawstate.drawableh - viewport->y - rect->y - rect->h, rect->w, rect->h); data->drawstate.cliprect_dirty = SDL_FALSE; @@ -928,10 +930,10 @@ SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_I if (texture != data->drawstate.texture) { if ((texture != NULL) != data->drawstate.texturing) { if (texture == NULL) { - data->glDisableVertexAttribArray((GLenum) GLES2_ATTRIBUTE_TEXCOORD); + data->myglDisableVertexAttribArray((GLenum) GLES2_ATTRIBUTE_TEXCOORD); data->drawstate.texturing = SDL_FALSE; } else { - data->glEnableVertexAttribArray((GLenum) GLES2_ATTRIBUTE_TEXCOORD); + data->myglEnableVertexAttribArray((GLenum) GLES2_ATTRIBUTE_TEXCOORD); data->drawstate.texturing = SDL_TRUE; } } @@ -940,28 +942,28 @@ SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_I GLES2_TextureData *tdata = (GLES2_TextureData *) texture->driverdata; #if SDL_HAVE_YUV if (tdata->yuv) { - data->glActiveTexture(GL_TEXTURE2); - data->glBindTexture(tdata->texture_type, tdata->texture_v); + data->myglActiveTexture(GL_TEXTURE2); + data->myglBindTexture(tdata->texture_type, tdata->texture_v); - data->glActiveTexture(GL_TEXTURE1); - data->glBindTexture(tdata->texture_type, tdata->texture_u); + data->myglActiveTexture(GL_TEXTURE1); + data->myglBindTexture(tdata->texture_type, tdata->texture_u); - data->glActiveTexture(GL_TEXTURE0); + data->myglActiveTexture(GL_TEXTURE0); } else if (tdata->nv12) { - data->glActiveTexture(GL_TEXTURE1); - data->glBindTexture(tdata->texture_type, tdata->texture_u); + data->myglActiveTexture(GL_TEXTURE1); + data->myglBindTexture(tdata->texture_type, tdata->texture_u); - data->glActiveTexture(GL_TEXTURE0); + data->myglActiveTexture(GL_TEXTURE0); } #endif - data->glBindTexture(tdata->texture_type, tdata->texture); + data->myglBindTexture(tdata->texture_type, tdata->texture); } data->drawstate.texture = texture; } if (texture) { - data->glVertexAttribPointer(GLES2_ATTRIBUTE_TEXCOORD, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid *) (cmd->data.draw.first + (sizeof (GLfloat) * 8))); + data->myglVertexAttribPointer(GLES2_ATTRIBUTE_TEXCOORD, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid *) (cmd->data.draw.first + (sizeof (GLfloat) * 8))); } if (GLES2_SelectProgram(data, imgsrc, texture ? texture->w : 0, texture ? texture->h : 0) < 0) { @@ -972,7 +974,7 @@ SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_I if (program->uniform_locations[GLES2_UNIFORM_PROJECTION] != -1) { if (SDL_memcmp(program->projection, data->drawstate.projection, sizeof (data->drawstate.projection)) != 0) { - data->glUniformMatrix4fv(program->uniform_locations[GLES2_UNIFORM_PROJECTION], 1, GL_FALSE, (GLfloat *)data->drawstate.projection); + data->myglUniformMatrix4fv(program->uniform_locations[GLES2_UNIFORM_PROJECTION], 1, GL_FALSE, (GLfloat *)data->drawstate.projection); SDL_memcpy(program->projection, data->drawstate.projection, sizeof (data->drawstate.projection)); } } @@ -983,43 +985,43 @@ SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_I const Uint8 g = (data->drawstate.color >> 8) & 0xFF; const Uint8 b = (data->drawstate.color >> 0) & 0xFF; const Uint8 a = (data->drawstate.color >> 24) & 0xFF; - data->glUniform4f(program->uniform_locations[GLES2_UNIFORM_COLOR], r * inv255f, g * inv255f, b * inv255f, a * inv255f); + data->myglUniform4f(program->uniform_locations[GLES2_UNIFORM_COLOR], r * inv255f, g * inv255f, b * inv255f, a * inv255f); program->color = data->drawstate.color; } } if (blend != data->drawstate.blend) { if (blend == SDL_BLENDMODE_NONE) { - data->glDisable(GL_BLEND); + data->myglDisable(GL_BLEND); } else { - data->glEnable(GL_BLEND); - data->glBlendFuncSeparate(GetBlendFunc(SDL_GetBlendModeSrcColorFactor(blend)), + data->myglEnable(GL_BLEND); + data->myglBlendFuncSeparate(GetBlendFunc(SDL_GetBlendModeSrcColorFactor(blend)), GetBlendFunc(SDL_GetBlendModeDstColorFactor(blend)), GetBlendFunc(SDL_GetBlendModeSrcAlphaFactor(blend)), GetBlendFunc(SDL_GetBlendModeDstAlphaFactor(blend))); - data->glBlendEquationSeparate(GetBlendEquation(SDL_GetBlendModeColorOperation(blend)), + data->myglBlendEquationSeparate(GetBlendEquation(SDL_GetBlendModeColorOperation(blend)), GetBlendEquation(SDL_GetBlendModeAlphaOperation(blend))); } data->drawstate.blend = blend; } /* all drawing commands use this */ - data->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid *) cmd->data.draw.first); + data->myglVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid *) cmd->data.draw.first); if (is_copy_ex != was_copy_ex) { if (is_copy_ex) { - data->glEnableVertexAttribArray((GLenum) GLES2_ATTRIBUTE_ANGLE); - data->glEnableVertexAttribArray((GLenum) GLES2_ATTRIBUTE_CENTER); + data->myglEnableVertexAttribArray((GLenum) GLES2_ATTRIBUTE_ANGLE); + data->myglEnableVertexAttribArray((GLenum) GLES2_ATTRIBUTE_CENTER); } else { - data->glDisableVertexAttribArray((GLenum) GLES2_ATTRIBUTE_ANGLE); - data->glDisableVertexAttribArray((GLenum) GLES2_ATTRIBUTE_CENTER); + data->myglDisableVertexAttribArray((GLenum) GLES2_ATTRIBUTE_ANGLE); + data->myglDisableVertexAttribArray((GLenum) GLES2_ATTRIBUTE_CENTER); } data->drawstate.is_copy_ex = is_copy_ex; } if (is_copy_ex) { - data->glVertexAttribPointer(GLES2_ATTRIBUTE_ANGLE, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid *) (cmd->data.draw.first + (sizeof (GLfloat) * 16))); - data->glVertexAttribPointer(GLES2_ATTRIBUTE_CENTER, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid *) (cmd->data.draw.first + (sizeof (GLfloat) * 24))); + data->myglVertexAttribPointer(GLES2_ATTRIBUTE_ANGLE, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid *) (cmd->data.draw.first + (sizeof (GLfloat) * 16))); + data->myglVertexAttribPointer(GLES2_ATTRIBUTE_CENTER, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid *) (cmd->data.draw.first + (sizeof (GLfloat) * 24))); } return 0; @@ -1158,12 +1160,12 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver } /* upload the new VBO data for this set of commands. */ - data->glBindBuffer(GL_ARRAY_BUFFER, vbo); + data->myglBindBuffer(GL_ARRAY_BUFFER, vbo); if (data->vertex_buffer_size[vboidx] < vertsize) { - data->glBufferData(GL_ARRAY_BUFFER, vertsize, vertices, GL_STREAM_DRAW); + data->myglBufferData(GL_ARRAY_BUFFER, vertsize, vertices, GL_STREAM_DRAW); data->vertex_buffer_size[vboidx] = vertsize; } else { - data->glBufferSubData(GL_ARRAY_BUFFER, 0, vertsize, vertices); + data->myglBufferSubData(GL_ARRAY_BUFFER, 0, vertsize, vertices); } /* cycle through a few VBOs so the GL has some time with the data before we replace it. */ @@ -1217,22 +1219,22 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver const GLfloat fg = ((GLfloat) g) * inv255f; const GLfloat fb = ((GLfloat) b) * inv255f; const GLfloat fa = ((GLfloat) a) * inv255f; - data->glClearColor(fr, fg, fb, fa); + data->myglClearColor(fr, fg, fb, fa); data->drawstate.clear_color = color; } if (data->drawstate.cliprect_enabled || data->drawstate.cliprect_enabled_dirty) { - data->glDisable(GL_SCISSOR_TEST); + data->myglDisable(GL_SCISSOR_TEST); data->drawstate.cliprect_enabled_dirty = data->drawstate.cliprect_enabled; } - data->glClear(GL_COLOR_BUFFER_BIT); + data->myglClear(GL_COLOR_BUFFER_BIT); break; } case SDL_RENDERCMD_DRAW_POINTS: { if (SetDrawState(data, cmd, GLES2_IMAGESOURCE_SOLID) == 0) { - data->glDrawArrays(GL_POINTS, 0, (GLsizei) cmd->data.draw.count); + data->myglDrawArrays(GL_POINTS, 0, (GLsizei) cmd->data.draw.count); } break; } @@ -1241,7 +1243,7 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver const size_t count = cmd->data.draw.count; SDL_assert(count >= 2); if (SetDrawState(data, cmd, GLES2_IMAGESOURCE_SOLID) == 0) { - data->glDrawArrays(GL_LINE_STRIP, 0, (GLsizei) count); + data->myglDrawArrays(GL_LINE_STRIP, 0, (GLsizei) count); } break; } @@ -1251,7 +1253,7 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver size_t offset = 0; if (SetDrawState(data, cmd, GLES2_IMAGESOURCE_SOLID) == 0) { for (i = 0; i < count; ++i, offset += 4) { - data->glDrawArrays(GL_TRIANGLE_STRIP, (GLsizei) offset, 4); + data->myglDrawArrays(GL_TRIANGLE_STRIP, (GLsizei) offset, 4); } } break; @@ -1260,7 +1262,7 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver case SDL_RENDERCMD_COPY: case SDL_RENDERCMD_COPY_EX: { if (SetCopyState(renderer, cmd) == 0) { - data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + data->myglDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } break; } @@ -1289,7 +1291,7 @@ GLES2_DestroyRenderer(SDL_Renderer *renderer) for (i = 0; i < GLES2_SHADER_COUNT; i++) { GLuint id = data->shader_id_cache[i]; if (id) { - data->glDeleteShader(id); + data->myglDeleteShader(id); } } } @@ -1298,7 +1300,7 @@ GLES2_DestroyRenderer(SDL_Renderer *renderer) GLES2_ProgramCacheEntry *next; entry = data->program_cache.head; while (entry) { - data->glDeleteProgram(entry->id); + data->myglDeleteProgram(entry->id); next = entry->next; SDL_free(entry); entry = next; @@ -1308,13 +1310,13 @@ GLES2_DestroyRenderer(SDL_Renderer *renderer) if (data->context) { while (data->framebuffers) { GLES2_FBOList *nextnode = data->framebuffers->next; - data->glDeleteFramebuffers(1, &data->framebuffers->FBO); + data->myglDeleteFramebuffers(1, &data->framebuffers->FBO); GL_CheckError("", renderer); SDL_free(data->framebuffers); data->framebuffers = nextnode; } - data->glDeleteBuffers(SDL_arraysize(data->vertex_buffers), data->vertex_buffers); + data->myglDeleteBuffers(SDL_arraysize(data->vertex_buffers), data->vertex_buffers); GL_CheckError("", renderer); SDL_GL_DeleteContext(data->context); @@ -1417,63 +1419,63 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) #if SDL_HAVE_YUV if (data->yuv) { - renderdata->glGenTextures(1, &data->texture_v); + renderdata->myglGenTextures(1, &data->texture_v); if (GL_CheckError("glGenTexures()", renderer) < 0) { return -1; } - renderdata->glActiveTexture(GL_TEXTURE2); - renderdata->glBindTexture(data->texture_type, data->texture_v); - renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MIN_FILTER, scaleMode); - renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MAG_FILTER, scaleMode); - renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - renderdata->glTexImage2D(data->texture_type, 0, format, (texture->w + 1) / 2, (texture->h + 1) / 2, 0, format, type, NULL); - - renderdata->glGenTextures(1, &data->texture_u); + renderdata->myglActiveTexture(GL_TEXTURE2); + renderdata->myglBindTexture(data->texture_type, data->texture_v); + renderdata->myglTexParameteri(data->texture_type, GL_TEXTURE_MIN_FILTER, scaleMode); + renderdata->myglTexParameteri(data->texture_type, GL_TEXTURE_MAG_FILTER, scaleMode); + renderdata->myglTexParameteri(data->texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + renderdata->myglTexParameteri(data->texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + renderdata->myglTexImage2D(data->texture_type, 0, format, (texture->w + 1) / 2, (texture->h + 1) / 2, 0, format, type, NULL); + + renderdata->myglGenTextures(1, &data->texture_u); if (GL_CheckError("glGenTexures()", renderer) < 0) { return -1; } - renderdata->glActiveTexture(GL_TEXTURE1); - renderdata->glBindTexture(data->texture_type, data->texture_u); - renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MIN_FILTER, scaleMode); - renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MAG_FILTER, scaleMode); - renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - renderdata->glTexImage2D(data->texture_type, 0, format, (texture->w + 1) / 2, (texture->h + 1) / 2, 0, format, type, NULL); + renderdata->myglActiveTexture(GL_TEXTURE1); + renderdata->myglBindTexture(data->texture_type, data->texture_u); + renderdata->myglTexParameteri(data->texture_type, GL_TEXTURE_MIN_FILTER, scaleMode); + renderdata->myglTexParameteri(data->texture_type, GL_TEXTURE_MAG_FILTER, scaleMode); + renderdata->myglTexParameteri(data->texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + renderdata->myglTexParameteri(data->texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + renderdata->myglTexImage2D(data->texture_type, 0, format, (texture->w + 1) / 2, (texture->h + 1) / 2, 0, format, type, NULL); if (GL_CheckError("glTexImage2D()", renderer) < 0) { return -1; } } else if (data->nv12) { - renderdata->glGenTextures(1, &data->texture_u); + renderdata->myglGenTextures(1, &data->texture_u); if (GL_CheckError("glGenTexures()", renderer) < 0) { return -1; } - renderdata->glActiveTexture(GL_TEXTURE1); - renderdata->glBindTexture(data->texture_type, data->texture_u); - renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MIN_FILTER, scaleMode); - renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MAG_FILTER, scaleMode); - renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - renderdata->glTexImage2D(data->texture_type, 0, GL_LUMINANCE_ALPHA, (texture->w + 1) / 2, (texture->h + 1) / 2, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NULL); + renderdata->myglActiveTexture(GL_TEXTURE1); + renderdata->myglBindTexture(data->texture_type, data->texture_u); + renderdata->myglTexParameteri(data->texture_type, GL_TEXTURE_MIN_FILTER, scaleMode); + renderdata->myglTexParameteri(data->texture_type, GL_TEXTURE_MAG_FILTER, scaleMode); + renderdata->myglTexParameteri(data->texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + renderdata->myglTexParameteri(data->texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + renderdata->myglTexImage2D(data->texture_type, 0, GL_LUMINANCE_ALPHA, (texture->w + 1) / 2, (texture->h + 1) / 2, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NULL); if (GL_CheckError("glTexImage2D()", renderer) < 0) { return -1; } } #endif - renderdata->glGenTextures(1, &data->texture); + renderdata->myglGenTextures(1, &data->texture); if (GL_CheckError("glGenTexures()", renderer) < 0) { return -1; } texture->driverdata = data; - renderdata->glActiveTexture(GL_TEXTURE0); - renderdata->glBindTexture(data->texture_type, data->texture); - renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MIN_FILTER, scaleMode); - renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MAG_FILTER, scaleMode); - renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + renderdata->myglActiveTexture(GL_TEXTURE0); + renderdata->myglBindTexture(data->texture_type, data->texture); + renderdata->myglTexParameteri(data->texture_type, GL_TEXTURE_MIN_FILTER, scaleMode); + renderdata->myglTexParameteri(data->texture_type, GL_TEXTURE_MAG_FILTER, scaleMode); + renderdata->myglTexParameteri(data->texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + renderdata->myglTexParameteri(data->texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); if (texture->format != SDL_PIXELFORMAT_EXTERNAL_OES) { - renderdata->glTexImage2D(data->texture_type, 0, format, texture->w, texture->h, 0, format, type, NULL); + renderdata->myglTexImage2D(data->texture_type, 0, format, texture->w, texture->h, 0, format, type, NULL); if (GL_CheckError("glTexImage2D()", renderer) < 0) { return -1; } @@ -1500,6 +1502,44 @@ GLES2_TexSubImage2D(GLES2_RenderData *data, GLenum target, GLint xoffset, GLint return 0; /* nothing to do */ } +#ifdef SDL_BIG_ENDIAN + /* HACK: do endian conversion. Then shaders and target texture should be compatible. + Alpha channel must be in correct place for blending */ + + src_pitch = width * bpp; + + blob = (Uint8 *)SDL_malloc(src_pitch * height); + if (!blob) { + return SDL_OutOfMemory(); + } + src = blob; + for (y = 0; y < height; ++y) + { + int x; + + if (bpp == 4) { + Uint32* to = (Uint32 *)src; + Uint32* from = (Uint32 *)pixels; + + for (x = 0; x < width; x++) { + to[x] = SDL_SwapLE32(from[x]); + } + } else { + Uint8* to = src; + Uint8* from = (Uint8 *)pixels; + + for (x = 0; x < src_pitch; x += 3) { + to[x + 0] = from[x + 2]; + to[x + 1] = from[x + 1]; + to[x + 2] = from[x + 0]; + } + } + + src += src_pitch; + pixels = (Uint8 *)pixels + pitch; + } + src = blob; +#else /* Reformat the texture data into a tightly packed array */ src_pitch = width * bpp; src = (Uint8 *)pixels; @@ -1517,8 +1557,9 @@ GLES2_TexSubImage2D(GLES2_RenderData *data, GLenum target, GLint xoffset, GLint } src = blob; } +#endif - data->glTexSubImage2D(target, 0, xoffset, yoffset, width, height, format, type, src); + data->myglTexSubImage2D(target, 0, xoffset, yoffset, width, height, format, type, src); if (blob) { SDL_free(blob); } @@ -1542,7 +1583,7 @@ GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect data->drawstate.texture = NULL; /* we trash this state. */ /* Create a texture subimage with the supplied data */ - data->glBindTexture(tdata->texture_type, tdata->texture); + data->myglBindTexture(tdata->texture_type, tdata->texture); GLES2_TexSubImage2D(data, tdata->texture_type, rect->x, rect->y, @@ -1557,9 +1598,9 @@ GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect /* Skip to the correct offset into the next texture */ pixels = (const void*)((const Uint8*)pixels + rect->h * pitch); if (texture->format == SDL_PIXELFORMAT_YV12) { - data->glBindTexture(tdata->texture_type, tdata->texture_v); + data->myglBindTexture(tdata->texture_type, tdata->texture_v); } else { - data->glBindTexture(tdata->texture_type, tdata->texture_u); + data->myglBindTexture(tdata->texture_type, tdata->texture_u); } GLES2_TexSubImage2D(data, tdata->texture_type, rect->x / 2, @@ -1574,9 +1615,9 @@ GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect /* Skip to the correct offset into the next texture */ pixels = (const void*)((const Uint8*)pixels + ((rect->h + 1) / 2) * ((pitch + 1)/2)); if (texture->format == SDL_PIXELFORMAT_YV12) { - data->glBindTexture(tdata->texture_type, tdata->texture_u); + data->myglBindTexture(tdata->texture_type, tdata->texture_u); } else { - data->glBindTexture(tdata->texture_type, tdata->texture_v); + data->myglBindTexture(tdata->texture_type, tdata->texture_v); } GLES2_TexSubImage2D(data, tdata->texture_type, rect->x / 2, @@ -1589,7 +1630,7 @@ GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect } else if (tdata->nv12) { /* Skip to the correct offset into the next texture */ pixels = (const void*)((const Uint8*)pixels + rect->h * pitch); - data->glBindTexture(tdata->texture_type, tdata->texture_u); + data->myglBindTexture(tdata->texture_type, tdata->texture_u); GLES2_TexSubImage2D(data, tdata->texture_type, rect->x / 2, rect->y / 2, @@ -1624,7 +1665,7 @@ GLES2_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture, data->drawstate.texture = NULL; /* we trash this state. */ - data->glBindTexture(tdata->texture_type, tdata->texture_v); + data->myglBindTexture(tdata->texture_type, tdata->texture_v); GLES2_TexSubImage2D(data, tdata->texture_type, rect->x / 2, rect->y / 2, @@ -1634,7 +1675,7 @@ GLES2_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture, tdata->pixel_type, Vplane, Vpitch, 1); - data->glBindTexture(tdata->texture_type, tdata->texture_u); + data->myglBindTexture(tdata->texture_type, tdata->texture_u); GLES2_TexSubImage2D(data, tdata->texture_type, rect->x / 2, rect->y / 2, @@ -1644,7 +1685,7 @@ GLES2_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture, tdata->pixel_type, Uplane, Upitch, 1); - data->glBindTexture(tdata->texture_type, tdata->texture); + data->myglBindTexture(tdata->texture_type, tdata->texture); GLES2_TexSubImage2D(data, tdata->texture_type, rect->x, rect->y, @@ -1675,7 +1716,7 @@ GLES2_UpdateTextureNV(SDL_Renderer * renderer, SDL_Texture * texture, data->drawstate.texture = NULL; /* we trash this state. */ - data->glBindTexture(tdata->texture_type, tdata->texture_u); + data->myglBindTexture(tdata->texture_type, tdata->texture_u); GLES2_TexSubImage2D(data, tdata->texture_type, rect->x / 2, rect->y / 2, @@ -1685,7 +1726,7 @@ GLES2_UpdateTextureNV(SDL_Renderer * renderer, SDL_Texture * texture, GL_UNSIGNED_BYTE, UVplane, UVpitch, 2); - data->glBindTexture(tdata->texture_type, tdata->texture); + data->myglBindTexture(tdata->texture_type, tdata->texture); GLES2_TexSubImage2D(data, tdata->texture_type, rect->x, rect->y, @@ -1737,27 +1778,27 @@ GLES2_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture, SDL_Sc #if SDL_HAVE_YUV if (data->yuv) { - renderdata->glActiveTexture(GL_TEXTURE2); - renderdata->glBindTexture(data->texture_type, data->texture_v); - renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MIN_FILTER, glScaleMode); - renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MAG_FILTER, glScaleMode); - - renderdata->glActiveTexture(GL_TEXTURE1); - renderdata->glBindTexture(data->texture_type, data->texture_u); - renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MIN_FILTER, glScaleMode); - renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MAG_FILTER, glScaleMode); + renderdata->myglActiveTexture(GL_TEXTURE2); + renderdata->myglBindTexture(data->texture_type, data->texture_v); + renderdata->myglTexParameteri(data->texture_type, GL_TEXTURE_MIN_FILTER, glScaleMode); + renderdata->myglTexParameteri(data->texture_type, GL_TEXTURE_MAG_FILTER, glScaleMode); + + renderdata->myglActiveTexture(GL_TEXTURE1); + renderdata->myglBindTexture(data->texture_type, data->texture_u); + renderdata->myglTexParameteri(data->texture_type, GL_TEXTURE_MIN_FILTER, glScaleMode); + renderdata->myglTexParameteri(data->texture_type, GL_TEXTURE_MAG_FILTER, glScaleMode); } else if (data->nv12) { - renderdata->glActiveTexture(GL_TEXTURE1); - renderdata->glBindTexture(data->texture_type, data->texture_u); - renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MIN_FILTER, glScaleMode); - renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MAG_FILTER, glScaleMode); + renderdata->myglActiveTexture(GL_TEXTURE1); + renderdata->myglBindTexture(data->texture_type, data->texture_u); + renderdata->myglTexParameteri(data->texture_type, GL_TEXTURE_MIN_FILTER, glScaleMode); + renderdata->myglTexParameteri(data->texture_type, GL_TEXTURE_MAG_FILTER, glScaleMode); } #endif - renderdata->glActiveTexture(GL_TEXTURE0); - renderdata->glBindTexture(data->texture_type, data->texture); - renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MIN_FILTER, glScaleMode); - renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MAG_FILTER, glScaleMode); + renderdata->myglActiveTexture(GL_TEXTURE0); + renderdata->myglBindTexture(data->texture_type, data->texture); + renderdata->myglTexParameteri(data->texture_type, GL_TEXTURE_MIN_FILTER, glScaleMode); + renderdata->myglTexParameteri(data->texture_type, GL_TEXTURE_MAG_FILTER, glScaleMode); } static int @@ -1770,14 +1811,14 @@ GLES2_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture) data->drawstate.viewport_dirty = SDL_TRUE; if (texture == NULL) { - data->glBindFramebuffer(GL_FRAMEBUFFER, data->window_framebuffer); + data->myglBindFramebuffer(GL_FRAMEBUFFER, data->window_framebuffer); } else { texturedata = (GLES2_TextureData *) texture->driverdata; - data->glBindFramebuffer(GL_FRAMEBUFFER, texturedata->fbo->FBO); + data->myglBindFramebuffer(GL_FRAMEBUFFER, texturedata->fbo->FBO); /* TODO: check if texture pixel format allows this operation */ - data->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texturedata->texture_type, texturedata->texture, 0); + data->myglFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texturedata->texture_type, texturedata->texture, 0); /* Check FBO status */ - status = data->glCheckFramebufferStatus(GL_FRAMEBUFFER); + status = data->myglCheckFramebufferStatus(GL_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) { return SDL_SetError("glFramebufferTexture2D() failed"); } @@ -1802,13 +1843,13 @@ GLES2_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture) /* Destroy the texture */ if (tdata) { - data->glDeleteTextures(1, &tdata->texture); + data->myglDeleteTextures(1, &tdata->texture); #if SDL_HAVE_YUV if (tdata->texture_v) { - data->glDeleteTextures(1, &tdata->texture_v); + data->myglDeleteTextures(1, &tdata->texture_v); } if (tdata->texture_u) { - data->glDeleteTextures(1, &tdata->texture_u); + data->myglDeleteTextures(1, &tdata->texture_u); } #endif SDL_free(tdata->pixel_data); @@ -1843,7 +1884,7 @@ GLES2_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, SDL_GetRendererOutputSize(renderer, &w, &h); - data->glReadPixels(rect->x, renderer->target ? rect->y : (h-rect->y)-rect->h, + data->myglReadPixels(rect->x, renderer->target ? rect->y : (h-rect->y)-rect->h, rect->w, rect->h, GL_RGBA, GL_UNSIGNED_BYTE, temp_pixels); if (GL_CheckError("glReadPixels()", renderer) < 0) { return -1; @@ -1895,7 +1936,7 @@ static int GLES2_BindTexture (SDL_Renderer * renderer, SDL_Texture *texture, flo GLES2_TextureData *texturedata = (GLES2_TextureData *)texture->driverdata; GLES2_ActivateRenderer(renderer); - data->glBindTexture(texturedata->texture_type, texturedata->texture); + data->myglBindTexture(texturedata->texture_type, texturedata->texture); data->drawstate.texture = texture; if (texw) { @@ -1914,7 +1955,7 @@ static int GLES2_UnbindTexture (SDL_Renderer * renderer, SDL_Texture *texture) GLES2_TextureData *texturedata = (GLES2_TextureData *)texture->driverdata; GLES2_ActivateRenderer(renderer); - data->glBindTexture(texturedata->texture_type, 0); + data->myglBindTexture(texturedata->texture_type, 0); data->drawstate.texture = NULL; return 0; @@ -2025,17 +2066,17 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags) } value = 0; - data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value); + data->myglGetIntegerv(GL_MAX_TEXTURE_SIZE, &value); renderer->info.max_texture_width = value; value = 0; - data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value); + data->myglGetIntegerv(GL_MAX_TEXTURE_SIZE, &value); renderer->info.max_texture_height = value; /* we keep a few of these and cycle through them, so data can live for a few frames. */ - data->glGenBuffers(SDL_arraysize(data->vertex_buffers), data->vertex_buffers); + data->myglGenBuffers(SDL_arraysize(data->vertex_buffers), data->vertex_buffers); data->framebuffers = NULL; - data->glGetIntegerv(GL_FRAMEBUFFER_BINDING, &window_framebuffer); + data->myglGetIntegerv(GL_FRAMEBUFFER_BINDING, &window_framebuffer); data->window_framebuffer = (GLuint)window_framebuffer; /* Populate the function pointers for the module */ @@ -2076,14 +2117,14 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags) #endif /* Set up parameters for rendering */ - data->glActiveTexture(GL_TEXTURE0); - data->glPixelStorei(GL_PACK_ALIGNMENT, 1); - data->glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + data->myglActiveTexture(GL_TEXTURE0); + data->myglPixelStorei(GL_PACK_ALIGNMENT, 1); + data->myglPixelStorei(GL_UNPACK_ALIGNMENT, 1); - data->glEnableVertexAttribArray(GLES2_ATTRIBUTE_POSITION); - data->glDisableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD); + data->myglEnableVertexAttribArray(GLES2_ATTRIBUTE_POSITION); + data->myglDisableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD); - data->glClearColor(1.0f, 1.0f, 1.0f, 1.0f); + data->myglClearColor(1.0f, 1.0f, 1.0f, 1.0f); data->drawstate.blend = SDL_BLENDMODE_INVALID; data->drawstate.color = 0xFFFFFFFF; diff --git a/src/stdlib/SDL_iconv.c b/src/stdlib/SDL_iconv.c index 004e7741c7a1f..9109fa087cb46 100644 --- a/src/stdlib/SDL_iconv.c +++ b/src/stdlib/SDL_iconv.c @@ -30,6 +30,12 @@ #include "SDL_stdinc.h" #include "SDL_endian.h" +#ifdef __AMIGAOS4__ +/* HACK: AmigaOS 4 iconv implementation doesn't support all conversions, making testiconv fail. +As a workaround, fallback to custom implementation. */ +#undef HAVE_ICONV +#endif + #if defined(HAVE_ICONV) && defined(HAVE_ICONV_H) #ifdef __FreeBSD__ /* Define LIBICONV_PLUG to use iconv from the base instead of ports and avoid linker errors. */ diff --git a/src/thread/SDL_thread_c.h b/src/thread/SDL_thread_c.h index 0ff4502cae834..e2cc5bd3765d5 100644 --- a/src/thread/SDL_thread_c.h +++ b/src/thread/SDL_thread_c.h @@ -38,6 +38,8 @@ #include "vita/SDL_systhread_c.h" #elif SDL_THREAD_STDCPP #include "stdcpp/SDL_systhread_c.h" +#elif SDL_THREAD_AMIGAOS4 +#include "amigaos4/SDL_systhread_c.h" #elif SDL_THREAD_OS2 #include "os2/SDL_systhread_c.h" #else diff --git a/src/thread/amigaos4/SDL_sysmutex.c b/src/thread/amigaos4/SDL_sysmutex.c new file mode 100644 index 0000000000000..a0961ee272b0a --- /dev/null +++ b/src/thread/amigaos4/SDL_sysmutex.c @@ -0,0 +1,128 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_THREAD_AMIGAOS4 + +/* Mutex functions using the AmigaOS 4 API */ + +#define DEBUG +#include "../../main/amigaos4/SDL_os4debug.h" + +#include "SDL_mutex.h" + +#include + +struct SDL_mutex +{ + APTR mtx; +}; + +SDL_mutex * +SDL_CreateMutex(void) +{ + SDL_mutex* mutex; + + /* Allocate mutex memory */ + mutex = (SDL_mutex *) SDL_malloc(sizeof(*mutex)); + + if (mutex) { + mutex->mtx = IExec->AllocSysObjectTags(ASOT_MUTEX, + ASOMUTEX_Recursive, TRUE, + TAG_DONE); + + if (!mutex->mtx) { + dprintf("Failed to allocate mutex\n"); + SDL_free(mutex); + SDL_OutOfMemory(); + return NULL; + } + + dprintf("Created mutex %p\n", mutex->mtx); + } else { + SDL_OutOfMemory(); + } + + return mutex; +} + +void +SDL_DestroyMutex(SDL_mutex * mutex) +{ + if (mutex) { + dprintf("Destroying mutex %p\n", mutex->mtx); + IExec->FreeSysObject(ASOT_MUTEX, mutex->mtx); + mutex->mtx = NULL; + SDL_free(mutex); + } +} + +int +SDL_LockMutex(SDL_mutex * mutex) +{ + if (mutex == NULL) { + return SDL_SetError("Passed a NULL mutex"); + } + + //dprintf("Called\n"); + + IExec->MutexObtain(mutex->mtx); + + //dprintf("Locked mutex %p\n", mutex); + + return 0; +} + +int +SDL_TryLockMutex(SDL_mutex * mutex) +{ + int retval = 0; + if (mutex == NULL) { + return SDL_SetError("Passed a NULL mutex"); + } + + //dprintf("Called\n"); + + if (!IExec->MutexAttempt(mutex->mtx)) { + retval = SDL_MUTEX_TIMEDOUT; + } + return retval; +} + +/* Unlock the mutex */ +int +SDL_UnlockMutex(SDL_mutex * mutex) +{ + if (mutex == NULL) { + return SDL_SetError("Passed a NULL mutex"); + } + + //dprintf("Unlocking mutex %p\n", mutex); + + IExec->MutexRelease(mutex->mtx); + + return 0; +} + +#endif /* SDL_THREAD_AMIGAOS4 */ + +/* vi: set ts=4 sw=4 expandtab: */ + diff --git a/src/thread/amigaos4/SDL_syssem.c b/src/thread/amigaos4/SDL_syssem.c new file mode 100644 index 0000000000000..169fe704526b8 --- /dev/null +++ b/src/thread/amigaos4/SDL_syssem.c @@ -0,0 +1,239 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_THREAD_AMIGAOS4 + +#define DEBUG +#include "../../main/amigaos4/SDL_os4debug.h" + +#include "SDL_thread.h" +#include "../../timer/amigaos4/SDL_os4timer_c.h" +#include "../../thread/amigaos4/SDL_systhread_c.h" + +#include +#include + +#define MUTEX_SIGNAL SIGBREAKF_CTRL_F +#define BREAK_SIGNAL SIGBREAKF_CTRL_C + +struct SDL_semaphore +{ + APTR mutex; // Protects the control block + Uint32 count; // Current value + struct MinList waiters; // Task waiting on this semaphore +}; + +typedef struct OS4_WaiterNode +{ + struct MinNode node; + struct Task* task; +} OS4_WaiterNode; + +SDL_sem * +SDL_CreateSemaphore(Uint32 initial_value) +{ + SDL_sem* sem = (SDL_sem *) SDL_malloc(sizeof(*sem)); + if (sem) { + sem->mutex = IExec->AllocSysObjectTags(ASOT_MUTEX, + ASOMUTEX_Recursive, TRUE, + TAG_DONE); + + if (!sem->mutex) { + dprintf("Failed to allocate mutex\n"); + SDL_SetError("Failed to allocate mutex"); + SDL_free(sem); + return NULL; + } + + IExec->NewMinList(&sem->waiters); + + sem->count = initial_value; + + dprintf("Created semaphore %p with count %d\n", sem, sem->count); + } else { + SDL_OutOfMemory(); + } + return (sem); +} + +void +SDL_DestroySemaphore(SDL_sem * sem) +{ + if (sem) { + dprintf("Destroying semaphore %p\n", sem); + + if (sem->mutex) { + IExec->MutexObtain(sem->mutex); + + if (!IsMinListEmpty(&sem->waiters)) { + dprintf("Semaphore %p has waiters\n"); + + OS4_WaiterNode* node; + + while ((node = (OS4_WaiterNode *)IExec->RemHead((struct List *)&sem->waiters))) { + dprintf("Interrupting waiting task %p\n", node->task); + + IExec->Signal(node->task, BREAK_SIGNAL); + + /* Reschedule tasks */ + IExec->MutexRelease(sem->mutex); + IExec->MutexObtain(sem->mutex); + } + } + + IExec->MutexRelease(sem->mutex); + + IExec->FreeSysObject(ASOT_MUTEX, sem->mutex); + sem->mutex = NULL; + } + SDL_free(sem); + } +} + +int +SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout) +{ + if (!sem) { + return SDL_SetError("Passed a NULL sem"); + } + + BOOL wait = TRUE; + + struct Task* task = IExec->FindTask(NULL); + + ULONG alarmSignal = 0; + + if (timeout > 0) { + alarmSignal = OS4_TimerSetAlarm(OS4_ThreadGetTimer(), timeout); + } + + while (wait) { + OS4_WaiterNode node; + + IExec->MutexObtain(sem->mutex); + + if (sem->count > 0) { + sem->count--; + wait = FALSE; + } else { + if (timeout == 0) { + //dprintf("Semaphore %p trying timed out\n", sem); + IExec->MutexRelease(sem->mutex); + return SDL_MUTEX_TIMEDOUT; + } + + node.task = task; + IExec->AddTail((struct List *)&sem->waiters, (struct Node *)&node); + } + + IExec->MutexRelease(sem->mutex); + + if (wait) { + //dprintf("Semaphore %p signals before wait 0x%X, count %u\n", sem, IExec->SetSignal(0L, 0L), sem->count); + + const ULONG signals = IExec->Wait(MUTEX_SIGNAL | BREAK_SIGNAL | alarmSignal); + + IExec->MutexObtain(sem->mutex); + IExec->Remove((struct Node *)&node); + IExec->MutexRelease(sem->mutex); + + if (signals & BREAK_SIGNAL) { + dprintf("Semaphore %p interrupted\n", sem); + return SDL_MUTEX_TIMEDOUT; + } + + if (signals & alarmSignal) { + //dprintf("Semaphore %p timer triggered\n"); + return SDL_MUTEX_TIMEDOUT; + } + + if (signals & MUTEX_SIGNAL) { + dprintf("Semaphore %p got signal 0x%X\n", sem, signals); + } + } + } + + if (timeout) { + OS4_TimerClearAlarm(OS4_ThreadGetTimer()); + } + + //dprintf("Semaphore %p obtained\n", sem); + + return 0; +} + +int +SDL_SemTryWait(SDL_sem * sem) +{ + return SDL_SemWaitTimeout(sem, 0); +} + +int +SDL_SemWait(SDL_sem * sem) +{ + //dprintf("Called\n"); + + return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT); +} + +/* Returns the current count of the semaphore */ +Uint32 +SDL_SemValue(SDL_sem * sem) +{ + if (!sem) { + SDL_SetError("Passed a NULL sem"); + return 0; + } + return (Uint32)sem->count; +} + +int +SDL_SemPost(SDL_sem * sem) +{ + if (!sem) { + return SDL_SetError("Passed a NULL sem"); + } + + //dprintf("Called\n"); + + IExec->MutexObtain(sem->mutex); + + if (++sem->count == 1) { + OS4_WaiterNode* node = (OS4_WaiterNode *)IExec->RemHead((struct List *)&sem->waiters); + + if (node) { + dprintf("Signalling task %p for semaphore %p\n", node->task, sem); + IExec->Signal(node->task, MUTEX_SIGNAL); + } + } + + IExec->MutexRelease(sem->mutex); + + dprintf("Semaphore %p value %u\n", sem, sem->count); + + return 0; +} + +#endif /* SDL_THREAD_AMIGAOS4 */ + +/* vi: set ts=4 sw=4 expandtab: */ + diff --git a/src/thread/amigaos4/SDL_systhread.c b/src/thread/amigaos4/SDL_systhread.c new file mode 100644 index 0000000000000..eb1fb04a24d46 --- /dev/null +++ b/src/thread/amigaos4/SDL_systhread.c @@ -0,0 +1,428 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2020 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_THREAD_AMIGAOS4 + +/* AmigaOS 4 thread management routines for SDL */ + +#include "SDL_thread.h" +#include "../SDL_thread_c.h" +#include "../SDL_systhread.h" +#include "SDL_systhread_c.h" + +#define DEBUG +#include "../../main/amigaos4/SDL_os4debug.h" +#include "../../video/amigaos4/SDL_os4library.h" + +#include +#include + +#define CHILD_SIGNAL SIGBREAKF_CTRL_D +#define BREAK_SIGNAL SIGBREAKF_CTRL_C + +static struct DOSIFace* iDOS; // TODO: try to make centralized interface storage for SDL2 - now it's a mess with too many symbols all over the place +static struct DOSBase* dosBase; + +typedef struct OS4_SafeList +{ + APTR mutex; + struct MinList list; +} OS4_SafeList; + +typedef struct OS4_ThreadNode +{ + struct MinNode node; + struct Task* task; + SDL_Thread* thread; + OS4_TimerInstance timer; +} OS4_ThreadNode; + +typedef struct OS4_ThreadControl +{ + OS4_ThreadNode primary; + OS4_SafeList children; + OS4_SafeList waiters; +} OS4_ThreadControl; + +static OS4_ThreadControl control; + +static BOOL initialized = FALSE; + +// NOTE: Init and Quit are called from SDL.c at the moment. +void OS4_InitThreadSubSystem(void) +{ + if (initialized) { + dprintf("Already initialized\n"); + return; + } + + control.primary.task = IExec->FindTask(NULL); + + dprintf("Main task %p\n", control.primary.task); + + control.children.mutex = IExec->AllocSysObjectTags(ASOT_MUTEX, TAG_DONE); + control.waiters.mutex = IExec->AllocSysObjectTags(ASOT_MUTEX, TAG_DONE); + + dprintf("Children mutex %p, waiters mutex %p\n", control.children.mutex, control.waiters.mutex); + + IExec->NewMinList((struct MinList *)&control.children.list); + IExec->NewMinList((struct MinList *)&control.waiters.list); + + dosBase = (struct DOSBase *)OS4_OpenLibrary(DOSNAME, 50); + iDOS = (struct DOSIFace *)OS4_GetInterface((struct Library *)dosBase); + + dprintf("dosBase %p, iDos %p\n", dosBase, iDOS); + + OS4_InitTimerSubSystem(); + OS4_TimerCreate(&control.primary.timer); + + control.primary.task->tc_UserData = &control.primary; // Timer lookup requires this + + initialized = TRUE; +} + +void OS4_QuitThreadSubSystem(void) +{ + struct MinNode* iter; + + if (!initialized) { + dprintf("Not initialized\n"); + return; + } + + dprintf("Called from task %p\n", IExec->FindTask(NULL)); + + do { + IExec->MutexObtain(control.children.mutex); + + if (IsMinListEmpty(&control.children.list)) { + dprintf("No child threads left - proceed with SDL2 shutdown\n"); + IExec->MutexRelease(control.children.mutex); + break; + } else { + for (iter = control.children.list.mlh_Head; iter->mln_Succ; iter = iter->mln_Succ) { + IExec->Signal(((OS4_ThreadNode *)iter)->task, SIGBREAKF_CTRL_C); + } + } + + IExec->MutexRelease(control.children.mutex); + } while (TRUE); + + OS4_TimerDestroy(&control.primary.timer); + + OS4_QuitTimerSubSystem(); + + dprintf("Freeing mutexes\n"); + + IExec->FreeSysObject(ASOT_MUTEX, control.children.mutex); + IExec->FreeSysObject(ASOT_MUTEX, control.waiters.mutex); + + control.children.mutex = NULL; + control.waiters.mutex = NULL; + + dprintf("Dropping iDOS\n"); + + OS4_DropInterface((struct Interface **)&iDOS); + OS4_CloseLibrary((struct Library **)&dosBase); + + initialized = FALSE; + + dprintf("All done\n"); +} + +static LONG +OS4_RunThread(STRPTR args, int32 length, APTR execbase) +{ + struct Task* thisTask = IExec->FindTask(NULL); + + OS4_ThreadNode* node = thisTask->tc_UserData; + + node->task = thisTask; + + dprintf("This task %p, node %p, SDL_Thread %p\n", thisTask, node, node->thread); + + OS4_TimerCreate(&node->timer); + + IExec->MutexObtain(control.children.mutex); + IExec->AddTail((struct List *)&control.children.list, (struct Node *)node); + IExec->MutexRelease(control.children.mutex); + + SDL_RunThread(node->thread); + + return RETURN_OK; +} + +static void +OS4_ExitThread(int32 returnCode, int32 finalData) +{ + struct Task* thisTask = IExec->FindTask(NULL); + + OS4_ThreadNode *node = (OS4_ThreadNode *)finalData; // TODO: cannot use thisTask->tc_UserData if this is sometimes called from other process' context + + dprintf("Called from task %p, finalData %p\n", thisTask, finalData); + + IExec->MutexObtain(control.children.mutex); + + dprintf("Removing node %p from children list\n", node); + + IExec->Remove((struct Node *)node); + + dprintf("Signalling waiters\n"); + + IExec->MutexObtain(control.waiters.mutex); + + if (IsMinListEmpty(&control.waiters.list)) { + dprintf("Waiters list is empty\n"); + } else { + struct MinNode* iter; + + for (iter = control.waiters.list.mlh_Head; iter->mln_Succ; iter = iter->mln_Succ) { + //dprintf("iter %p, sending CHILD_SIGNAL\n", iter); + IExec->Signal(((OS4_ThreadNode *)iter)->task, CHILD_SIGNAL); + } + } + + IExec->MutexRelease(control.waiters.mutex); + + OS4_TimerDestroy(&node->timer); + + IExec->FreeVec(node); + + dprintf("Exiting\n"); + + // Hold the mutex until end, to prevent parent task shutting down the thread subsystem + IExec->MutexRelease(control.children.mutex); +} + +int +SDL_SYS_CreateThread(SDL_Thread * thread) +{ + char nameBuffer[128]; + struct Task* thisTask = IExec->FindTask(NULL); + + OS4_ThreadNode* node = IExec->AllocVecTags(sizeof(OS4_ThreadNode), + AVT_ClearWithValue, 0, + TAG_DONE); + + if (!node) { + dprintf("Failed to allocated thread node\n"); + return SDL_SetError("Not enough resources to create thread"); + } + + dprintf("Node %p\n", node); + + node->thread = thread; + + BPTR inputStream = iDOS->DupFileHandle(iDOS->Input()); + BPTR outputStream = iDOS->DupFileHandle(iDOS->Output()); + BPTR errorStream = iDOS->DupFileHandle(iDOS->ErrorOutput()); + + snprintf(nameBuffer, sizeof(nameBuffer), "SDL thread %s (%p)", thread->name, thread); + + struct Process* child = iDOS->CreateNewProcTags( + NP_Child, TRUE, + NP_Entry, OS4_RunThread, + NP_FinalCode, OS4_ExitThread, + // HACK: when running testthread, sometimes child process is calling exit() and SDL cleanup fails + // because ExitThread() is called from other context. By passing the node pointer, it can be removed + // from the list and quit doesn't hang. + NP_FinalData, (int32)node, + NP_Input, inputStream, + NP_CloseInput, inputStream != ZERO, + NP_Output, outputStream, + NP_CloseOutput, outputStream != ZERO, + NP_Error, errorStream, + NP_CloseError, errorStream != ZERO, + NP_Name, nameBuffer, + NP_Priority, thisTask->tc_Node.ln_Pri, + NP_StackSize, thread->stacksize, + NP_UserData, (APTR)node, + TAG_DONE); + + if (!child) { + dprintf("Failed to create a new thread '%s'\n", thread->name); + return SDL_SetError("Not enough resources to create thread"); + } + + dprintf("Created new thread '%s' (task %p)\n", thread->name, child); + + return 0; +} + +void +SDL_SYS_SetupThread(const char * name) +{ + //dprintf("Called for '%s'\n", name); +} + +SDL_threadID +SDL_ThreadID(void) +{ + return (SDL_threadID) IExec->FindTask(NULL); +} + +int +SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority) +{ + int value; + + switch (priority) { + case SDL_THREAD_PRIORITY_LOW: + value = -5; + break; + case SDL_THREAD_PRIORITY_HIGH: + value = 5; + break; + case SDL_THREAD_PRIORITY_TIME_CRITICAL: + value = 10; + break; + default: + value = 0; + break; + } + + struct Task* task = IExec->FindTask(NULL); + const BYTE old = IExec->SetTaskPri(task, value); + + dprintf("Changed task %p priority from %d to %d\n", task, old, value); + + return 0; +} + +static BOOL +OS4_StartJoining(OS4_ThreadNode * waiterNode, SDL_Thread * thread) +{ + BOOL found = FALSE; + + struct MinNode* iter; + + //dprintf("Start\n"); + + IExec->MutexObtain(control.children.mutex); + + if (IsMinListEmpty(&control.children.list)) { + dprintf("Children list is empty\n"); + } else { + for (iter = control.children.list.mlh_Head; iter->mln_Succ; iter = iter->mln_Succ) { + if (((OS4_ThreadNode *)iter)->thread == thread) { + found = TRUE; + IExec->MutexObtain(control.waiters.mutex); + IExec->AddTail((struct List *)&control.waiters.list, (struct Node *)waiterNode); + IExec->MutexRelease(control.waiters.mutex); + break; + } + } + } + + IExec->MutexRelease(control.children.mutex); + + //dprintf("End\n"); + + return found; +} + +static void +OS4_StopJoining(OS4_ThreadNode * node) +{ + //dprintf("Start\n"); + IExec->MutexObtain(control.waiters.mutex); + IExec->Remove((struct Node *)node); + IExec->MutexRelease(control.waiters.mutex); + //dprintf("End\n"); +} + +void +SDL_SYS_WaitThread(SDL_Thread * thread) +{ + dprintf("Waiting for '%s'\n", thread->name); + + OS4_ThreadNode node; + node.task = IExec->FindTask(NULL); + node.thread = ((OS4_ThreadNode *)node.task->tc_UserData)->thread; + + do { + const BOOL found = OS4_StartJoining(&node, thread); + + if (found) { + const ULONG signals = IExec->Wait(CHILD_SIGNAL | BREAK_SIGNAL); + + OS4_StopJoining(&node); + + if (signals & BREAK_SIGNAL) { + dprintf("Break signal\n"); + return; + } + + dprintf("Some child thread terminated\n"); + } else { + dprintf("Thread '%s' doesn't exist\n", thread->name); + return; + } + } while (TRUE); + + dprintf("Waiting over\n"); +} + +void +SDL_SYS_DetachThread(SDL_Thread * thread) +{ + dprintf("Called for '%s'\n", thread->name); + + // NOTE: not removing from child thread list because child tasks should exit + // before their parent (NP_Child, TRUE) + +#if 0 + IExec->MutexObtain(control.children.mutex); + + if (IsMinListEmpty(&control.children.list)) { + dprintf("Children list is empty\n"); + } else { + struct MinNode* iter; + + for (iter = control.children.list.mlh_Head; iter->mln_Succ; iter = iter->mln_Succ) { + if (((OS4_ThreadNode *)iter)->thread == thread) { + IExec->Remove((struct Node *)iter); + IExec->FreeVec(iter); + break; + } + } + } + + IExec->MutexRelease(control.children.mutex); +#endif +} + +OS4_TimerInstance* +OS4_ThreadGetTimer(void) +{ + struct Task* task = IExec->FindTask(NULL); + OS4_ThreadNode* node = task->tc_UserData; + + //dprintf("Task %p, timer %p\n", task, &node->timer); + + return &node->timer; +} + +#endif /* SDL_THREAD_AMIGAOS4 */ + +/* vi: set ts=4 sw=4 expandtab: */ + diff --git a/src/thread/amigaos4/SDL_systhread_c.h b/src/thread/amigaos4/SDL_systhread_c.h new file mode 100644 index 0000000000000..2ce70d6b7c352 --- /dev/null +++ b/src/thread/amigaos4/SDL_systhread_c.h @@ -0,0 +1,35 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_SYSTHREAD_C_H +#define SDL_SYSTHREAD_C_H + +#include "../../timer/amigaos4/SDL_os4timer_c.h" + +typedef struct Task* SYS_ThreadHandle; + +void OS4_InitThreadSubSystem(void); +void OS4_QuitThreadSubSystem(void); + +OS4_TimerInstance* OS4_ThreadGetTimer(void); + +#endif + diff --git a/src/thread/pthread/SDL_syscond.c b/src/thread/pthread/SDL_syscond.c index 674351e328515..48ec6a6006dad 100644 --- a/src/thread/pthread/SDL_syscond.c +++ b/src/thread/pthread/SDL_syscond.c @@ -29,6 +29,19 @@ #include "SDL_thread.h" #include "SDL_sysmutex_c.h" +#ifdef __amigaos4__ +#ifndef timespec + +/* FIXME: hack to get compile working. At least my SDK defines timespec only for CLIB2 */ +struct timespec +{ + unsigned int tv_sec; + unsigned int tv_nsec; +}; + +#endif +#endif + struct SDL_cond { pthread_cond_t cond; diff --git a/src/thread/pthread/SDL_systhread.c b/src/thread/pthread/SDL_systhread.c index 6902dbc1ab618..ec8e0f5639305 100644 --- a/src/thread/pthread/SDL_systhread.c +++ b/src/thread/pthread/SDL_systhread.c @@ -48,6 +48,7 @@ #endif #endif +#include "SDL_platform.h" #include "SDL_thread.h" #include "../SDL_thread_c.h" #include "../SDL_systhread.h" @@ -59,6 +60,9 @@ #include #endif +#ifdef __amigaos4__ +#include +#endif #ifndef __NACL__ /* List of signals to mask in the subthreads */ @@ -125,7 +129,7 @@ SDL_SYS_CreateThread(SDL_Thread * thread) void SDL_SYS_SetupThread(const char *name) { -#if !defined(__NACL__) +#if !defined(__NACL__) && !defined(__AMIGAOS4__) int i; sigset_t mask; #endif /* !__NACL__ */ @@ -158,7 +162,7 @@ SDL_SYS_SetupThread(const char *name) } /* NativeClient does not yet support signals.*/ -#if !defined(__NACL__) +#if !defined(__NACL__) && !defined(__AMIGAOS4__) /* Mask asynchronous signals for this thread */ sigemptyset(&mask); for (i = 0; sig_list[i]; ++i) { diff --git a/src/timer/amigaos4/SDL_os4timer.c b/src/timer/amigaos4/SDL_os4timer.c new file mode 100644 index 0000000000000..440c5ea50105f --- /dev/null +++ b/src/timer/amigaos4/SDL_os4timer.c @@ -0,0 +1,245 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2020 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "../../SDL_internal.h" + +#if defined(SDL_TIMER_AMIGAOS4) || defined(SDL_TIMERS_DISABLED) + +#include "SDL_types.h" + +#include +#include +#include +#include +#include + +#include "SDL_os4timer_c.h" + +#include "../../thread/amigaos4/SDL_systhread_c.h" + +#define DEBUG +#include "../../main/amigaos4/SDL_os4debug.h" + +static struct TimeVal OS4_StartTime; + +static struct TimerIFace* SDL2_ITimer; + +static ULONG OS4_TimerFrequency; + +typedef struct OS4_ClockVal { + union { + struct EClockVal cv; + Uint64 ticks; + } u; +} OS4_ClockVal; + +// Initialized with the thread sub system +void OS4_InitTimerSubSystem(void) +{ + dprintf("Called\n"); + + struct ExecBase* sysbase = (struct ExecBase *)IExec->Data.LibBase; + struct Library* timerBase = (struct Library *)IExec->FindName(&sysbase->DeviceList, "timer.device"); + + SDL2_ITimer = (struct TimerIFace *)IExec->GetInterface(timerBase, "main", 1, NULL); + + dprintf("ITimer %p\n", SDL2_ITimer); + + if (!SDL2_ITimer) { + dprintf("Failed to get ITimer\n"); + return; + } + + SDL2_ITimer->GetSysTime(&OS4_StartTime); + + struct EClockVal cv; + OS4_TimerFrequency = SDL2_ITimer->ReadEClock(&cv); + + dprintf("Timer frequency %u Hz\n", OS4_TimerFrequency); +} + +void OS4_QuitTimerSubSystem(void) +{ + dprintf("Called\n"); + + IExec->DropInterface((struct Interface *)SDL2_ITimer); + SDL2_ITimer = NULL; +} + +static void +OS4_TimerCleanup(OS4_TimerInstance * timer) +{ + if (timer) { + if (timer->timerRequest) { + dprintf("Freeing timer request %p\n", timer->timerRequest); + IExec->FreeSysObject(ASOT_IOREQUEST, timer->timerRequest); + timer->timerRequest = NULL; + } + + if (timer->timerPort) { + dprintf("Freeing timer port %p\n", timer->timerPort); + IExec->FreeSysObject(ASOT_PORT, timer->timerPort); + timer->timerPort = NULL; + } + } +} + +BOOL +OS4_TimerCreate(OS4_TimerInstance * timer) +{ + BOOL success = FALSE; + + dprintf("Creating timer %p for task %p\n", timer, IExec->FindTask(NULL)); + + if (!timer) { + return FALSE; + } + + timer->timerPort = IExec->AllocSysObject(ASOT_PORT, NULL); + + if (timer->timerPort) { + timer->timerRequest = IExec->AllocSysObjectTags(ASOT_IOREQUEST, + ASOIOR_ReplyPort, timer->timerPort, + ASOIOR_Size, sizeof(struct TimeRequest), + TAG_DONE); + + if (timer->timerRequest) { + if (!(IExec->OpenDevice("timer.device", UNIT_WAITUNTIL, (struct IORequest *)timer->timerRequest, 0))) { + success = TRUE; + } else { + dprintf("Failed to open timer.device\n"); + } + } else { + dprintf("Failed to allocate timer request\n"); + } + } else { + dprintf("Failed to allocate timer port\n"); + } + + if (!success) { + OS4_TimerCleanup(timer); + } + + return success; +} + +void +OS4_TimerDestroy(OS4_TimerInstance * timer) +{ + dprintf("Destroying timer %p for task %p\n", timer, IExec->FindTask(NULL)); + + if (timer && timer->timerRequest) { + if (!IExec->CheckIO((struct IORequest *)timer->timerRequest)) { + IExec->AbortIO((struct IORequest *)timer->timerRequest); + IExec->WaitIO((struct IORequest *)timer->timerRequest); + } + } + + OS4_TimerCleanup(timer); +} + +ULONG +OS4_TimerSetAlarm(OS4_TimerInstance * timer, Uint32 alarmTicks) +{ + const ULONG seconds = alarmTicks / 1000; + struct TimeVal now; + + if (!SDL2_ITimer) { + dprintf("Timer subsystem not initialized\n"); + return 0; + } + + //dprintf("Called for timer %p, ticks %u\n", timer, alarmTicks); + + timer->timerRequest->Request.io_Command = TR_ADDREQUEST; + timer->timerRequest->Time.Seconds = seconds; + timer->timerRequest->Time.Microseconds = (alarmTicks - (seconds * 1000)) * 1000; + + SDL2_ITimer->GetSysTime(&now); + SDL2_ITimer->AddTime(&timer->timerRequest->Time, &now); + + IExec->SetSignal(0, 1L << timer->timerPort->mp_SigBit); + IExec->SendIO((struct IORequest *)timer->timerRequest); + + // Return the alarm signal for Wait() use + return 1L << timer->timerPort->mp_SigBit; +} + +void +OS4_TimerClearAlarm(OS4_TimerInstance * timer) +{ + if (!IExec->CheckIO((struct IORequest *)timer->timerRequest)) { + IExec->AbortIO((struct IORequest *)timer->timerRequest); + } + + IExec->WaitIO((struct IORequest *)timer->timerRequest); +} + +BOOL +OS4_TimerDelay(Uint32 ticks) +{ + OS4_TimerInstance* timer = OS4_ThreadGetTimer(); + + const ULONG alarmSig = OS4_TimerSetAlarm(timer, ticks); + const ULONG sigsReceived = IExec->Wait(alarmSig | SIGBREAKF_CTRL_C); + + OS4_TimerClearAlarm(timer); + + return (sigsReceived & alarmSig) == alarmSig; +} + +void +OS4_TimerGetTime(struct TimeVal * timeval) +{ + if (!SDL2_ITimer) { + dprintf("Timer subsystem not initialized\n"); + timeval->Seconds = 0; + timeval->Microseconds = 0; + return; + } + + SDL2_ITimer->GetSysTime(timeval); + SDL2_ITimer->SubTime(timeval, &OS4_StartTime); +} + +Uint64 +OS4_TimerGetCounter(void) +{ + OS4_ClockVal value; + + if (!SDL2_ITimer) { + dprintf("Timer subsystem not initialized\n"); + return 0; + } + + SDL2_ITimer->ReadEClock(&value.u.cv); + + return value.u.ticks; +} + +Uint64 +OS4_TimerGetFrequency(void) +{ + return OS4_TimerFrequency; +} + +#endif /* (SDL_TIMER_AMIGAOS4) || defined(SDL_TIMERS_DISABLED) */ + diff --git a/src/timer/amigaos4/SDL_os4timer_c.h b/src/timer/amigaos4/SDL_os4timer_c.h new file mode 100644 index 0000000000000..3df2dc2a1ed6d --- /dev/null +++ b/src/timer/amigaos4/SDL_os4timer_c.h @@ -0,0 +1,50 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2020 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_OS4TIMER_C_H +#define SDL_OS4TIMER_C_H + +#include + +struct MsgPort; +struct TimeRequest; +struct TimeVal; + +typedef struct OS4_TimerInstance +{ + struct MsgPort* timerPort; + struct TimeRequest* timerRequest; +} OS4_TimerInstance; + +void OS4_InitTimerSubSystem(void); +void OS4_QuitTimerSubSystem(void); + +BOOL OS4_TimerCreate(OS4_TimerInstance * timer); +void OS4_TimerDestroy(OS4_TimerInstance * timer); +ULONG OS4_TimerSetAlarm(OS4_TimerInstance * timer, Uint32 alarmTicks); +void OS4_TimerClearAlarm(OS4_TimerInstance * timer); +BOOL OS4_TimerDelay(Uint32 ticks); +void OS4_TimerGetTime(struct TimeVal * timeval); +Uint64 OS4_TimerGetCounter(void); +Uint64 OS4_TimerGetFrequency(void); + +#endif /* SDL_OS4TIMER_C_H */ + diff --git a/src/timer/amigaos4/SDL_systimer.c b/src/timer/amigaos4/SDL_systimer.c new file mode 100644 index 0000000000000..eafbe8e098356 --- /dev/null +++ b/src/timer/amigaos4/SDL_systimer.c @@ -0,0 +1,83 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2020 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if defined(SDL_TIMER_AMIGAOS4) || defined(SDL_TIMERS_DISABLED) + +#include + +#include "SDL_timer.h" +#include "SDL_os4timer_c.h" + +#undef DEBUG +#include "../../main/amigaos4/SDL_os4debug.h" + +static SDL_bool started = SDL_FALSE; + +void +SDL_TicksInit(void) +{ + if (started) { + return; + } + started = SDL_TRUE; +} + +void +SDL_TicksQuit(void) +{ + started = SDL_FALSE; +} + +Uint32 +SDL_GetTicks(void) +{ + if (!started) { + SDL_TicksInit(); + } + + struct TimeVal cur; + OS4_TimerGetTime(&cur); + + return cur.Seconds * 1000 + cur.Microseconds / 1000; +} + +Uint64 +SDL_GetPerformanceCounter(void) +{ + return OS4_TimerGetCounter(); +} + +Uint64 +SDL_GetPerformanceFrequency(void) +{ + return OS4_TimerGetFrequency(); +} + +void +SDL_Delay(Uint32 ms) +{ + OS4_TimerDelay(ms); +} + +#endif /* SDL_TIMER_AMIGAOS4 || SDL_TIMERS_DISABLED */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/timer/unix/SDL_systimer.c b/src/timer/unix/SDL_systimer.c index 05db3a9f7af53..9a6ede9be93f6 100644 --- a/src/timer/unix/SDL_systimer.c +++ b/src/timer/unix/SDL_systimer.c @@ -202,7 +202,11 @@ SDL_Delay(Uint32 ms) #if HAVE_NANOSLEEP struct timespec elapsed, tv; #else + +#ifndef __amigaos4__ struct timeval tv; +#endif + Uint32 then, now, elapsed; #endif @@ -229,10 +233,14 @@ SDL_Delay(Uint32 ms) break; } ms -= elapsed; +#ifdef __amigaos4__ + was_error = usleep(ms * 1000); +#else tv.tv_sec = ms / 1000; tv.tv_usec = (ms % 1000) * 1000; was_error = select(0, NULL, NULL, NULL, &tv); +#endif #endif /* HAVE_NANOSLEEP */ } while (was_error && (errno == EINTR)); } diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index 682e52592921b..265409583b81a 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -435,6 +435,7 @@ extern VideoBootStrap KMSDRM_bootstrap; extern VideoBootStrap KMSDRM_LEGACY_bootstrap; extern VideoBootStrap DUMMY_bootstrap; extern VideoBootStrap Wayland_bootstrap; +extern VideoBootStrap OS4_bootstrap; extern VideoBootStrap NACL_bootstrap; extern VideoBootStrap VIVANTE_bootstrap; extern VideoBootStrap Emscripten_bootstrap; diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index a5cbe69629e41..288f2e21bb39f 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -109,6 +109,9 @@ static VideoBootStrap *bootstrap[] = { #if SDL_VIDEO_DRIVER_EMSCRIPTEN &Emscripten_bootstrap, #endif +#if SDL_VIDEO_DRIVER_AMIGAOS4 + &OS4_bootstrap, +#endif #if SDL_VIDEO_DRIVER_QNX &QNX_bootstrap, #endif @@ -151,7 +154,12 @@ static SDL_VideoDevice *_this = NULL; return retval; \ } +#ifdef __AMIGAOS4__ +/* Let's have only one kind of full screen */ +#define FULLSCREEN_MASK (SDL_WINDOW_FULLSCREEN) +#else #define FULLSCREEN_MASK (SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_FULLSCREEN) +#endif #ifdef __MACOSX__ /* Support for Mac OS X fullscreen spaces */ @@ -1154,6 +1162,10 @@ SDL_SetWindowDisplayMode(SDL_Window * window, const SDL_DisplayMode * mode) SDL_DisplayMode fullscreen_mode; if (SDL_GetWindowDisplayMode(window, &fullscreen_mode) == 0) { SDL_SetDisplayModeForDisplay(SDL_GetDisplayForWindow(window), &fullscreen_mode); +#ifdef __AMIGAOS4__ + // Force window on new screen + _this->SetWindowFullscreen(_this, window, SDL_GetDisplayForWindow(window), SDL_TRUE); +#endif } } return 0; @@ -1387,8 +1399,15 @@ SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool fullscreen) return 0; } -#define CREATE_FLAGS \ - (SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_ALWAYS_ON_TOP | SDL_WINDOW_SKIP_TASKBAR | SDL_WINDOW_POPUP_MENU | SDL_WINDOW_UTILITY | SDL_WINDOW_TOOLTIP | SDL_WINDOW_VULKAN | SDL_WINDOW_MINIMIZED | SDL_WINDOW_METAL) +#ifdef __AMIGAOS4__ + /* Without this hack, SDL would trigger us to open a window before screen which causes unnecessary + work, because then we would have to close the window first and re-open it on the custom screen */ + #define CREATE_FLAGS \ + (SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_ALWAYS_ON_TOP | SDL_WINDOW_SKIP_TASKBAR | SDL_WINDOW_POPUP_MENU | SDL_WINDOW_UTILITY | SDL_WINDOW_TOOLTIP | SDL_WINDOW_VULKAN | SDL_WINDOW_MINIMIZED | SDL_WINDOW_METAL | SDL_WINDOW_FULLSCREEN) +#else + #define CREATE_FLAGS \ + (SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_ALWAYS_ON_TOP | SDL_WINDOW_SKIP_TASKBAR | SDL_WINDOW_POPUP_MENU | SDL_WINDOW_UTILITY | SDL_WINDOW_TOOLTIP | SDL_WINDOW_VULKAN | SDL_WINDOW_MINIMIZED | SDL_WINDOW_METAL) +#endif static SDL_INLINE SDL_bool IsAcceptingDragAndDrop(void) @@ -1561,6 +1580,11 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags) window->y = y; window->w = w; window->h = h; + +#ifndef __AMIGAOS4__ +/* On AmigaOS4 we have to open the screen first, therefore this centering +logic fails if screen is of different size. We center the window later +on the backend side, after we know the screen size. */ if (SDL_WINDOWPOS_ISUNDEFINED(x) || SDL_WINDOWPOS_ISUNDEFINED(y) || SDL_WINDOWPOS_ISCENTERED(x) || SDL_WINDOWPOS_ISCENTERED(y)) { SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); @@ -1576,6 +1600,8 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags) window->y = bounds.y + (bounds.h - h) / 2; } } +#endif + window->windowed.x = window->x; window->windowed.y = window->y; window->windowed.w = window->w; @@ -1725,6 +1751,15 @@ SDL_RecreateWindow(SDL_Window * window, Uint32 flags) _this->DestroyWindow(_this, window); } +#ifdef __AMIGAOS4__ + if (window->flags & SDL_WINDOW_OPENGL) { + /* We have to unload the old library in case we have to switch + between MiniGL and OGLES2. Otherwise function pointers will be messed up. */ + SDL_GL_UnloadLibrary(); + window->flags &= ~SDL_WINDOW_OPENGL; + } +#endif + if ((window->flags & SDL_WINDOW_OPENGL) != (flags & SDL_WINDOW_OPENGL)) { if (flags & SDL_WINDOW_OPENGL) { need_gl_load = SDL_TRUE; @@ -3307,8 +3342,13 @@ SDL_GL_ResetAttributes() _this->gl_config.accelerated = -1; /* accelerated or not, both are fine */ #if SDL_VIDEO_OPENGL +#ifdef __AMIGAOS4__ + _this->gl_config.major_version = 1; /* MiniGL */ + _this->gl_config.minor_version = 3; +#else _this->gl_config.major_version = 2; _this->gl_config.minor_version = 1; +#endif _this->gl_config.profile_mask = 0; #elif SDL_VIDEO_OPENGL_ES2 _this->gl_config.major_version = 2; @@ -4061,6 +4101,9 @@ SDL_IsScreenKeyboardShown(SDL_Window *window) #if SDL_VIDEO_DRIVER_X11 #include "x11/SDL_x11messagebox.h" #endif +#if SDL_VIDEO_DRIVER_AMIGAOS4 +#include "amigaos4/SDL_os4messagebox.h" +#endif #if SDL_VIDEO_DRIVER_WAYLAND #include "wayland/SDL_waylandmessagebox.h" #endif @@ -4074,7 +4117,7 @@ SDL_IsScreenKeyboardShown(SDL_Window *window) #include "vita/SDL_vitamessagebox.h" #endif -#if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT || SDL_VIDEO_DRIVER_COCOA || SDL_VIDEO_DRIVER_UIKIT || SDL_VIDEO_DRIVER_X11 || SDL_VIDEO_DRIVER_WAYLAND || SDL_VIDEO_DRIVER_HAIKU || SDL_VIDEO_DRIVER_OS2 +#if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT || SDL_VIDEO_DRIVER_COCOA || SDL_VIDEO_DRIVER_UIKIT || SDL_VIDEO_DRIVER_X11 || SDL_VIDEO_DRIVER_AMIGAOS4 || SDL_VIDEO_DRIVER_WAYLAND || SDL_VIDEO_DRIVER_HAIKU || SDL_VIDEO_DRIVER_OS2 static SDL_bool SDL_MessageboxValidForDriver(const SDL_MessageBoxData *messageboxdata, SDL_SYSWM_TYPE drivertype) { SDL_SysWMinfo info; @@ -4173,6 +4216,13 @@ SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) retval = 0; } #endif +#if SDL_VIDEO_DRIVER_AMIGAOS4 + if (retval == -1 && + SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_OS4) && + OS4_ShowMessageBox(messageboxdata, buttonid) == 0) { + retval = 0; + } +#endif #if SDL_VIDEO_DRIVER_WAYLAND if (retval == -1 && SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_WAYLAND) && diff --git a/src/video/amigaos4/SDL_os4_notimplemented_funcs.t b/src/video/amigaos4/SDL_os4_notimplemented_funcs.t new file mode 100644 index 0000000000000..6f96e52a4d018 --- /dev/null +++ b/src/video/amigaos4/SDL_os4_notimplemented_funcs.t @@ -0,0 +1,1280 @@ +#define FUNC_NOT_IMPLEMENTED printf("function (%s) not implemented on file (%s),%d\n",__FUNCTION__, __FILE__, __LINE__); + +static void AmiglClearIndex( GLfloat c ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glClearIndex(c); +#endif +} + +static void AmiglIndexMask( GLuint mask ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glIndexMask(mask); +#endif +} + +static void AmiglGetPolygonStipple( GLubyte *mask ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glGetPolygonStipple(mask); +#endif +} + +static void AmiglEdgeFlagv( const GLboolean *flag ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glEdgeFlagv(flag); +#endif +} + +static void AmiglClearAccum( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glClearAccum(red, green, blue, alpha); +#endif +} + +static void AmiglAccum( GLenum op, GLfloat value ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glAccum(op, value); +#endif +} + +static void AmiglIndexd( GLdouble c ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glIndexd(c); +#endif +} + +static void AmiglIndexf( GLfloat c ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glIndexf(c); +#endif +} + +static void AmiglIndexi( GLint c ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glIndexi(c); +#endif +} + +static void AmiglIndexs( GLshort c ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glIndexs(c); +#endif +} + +static void AmiglIndexub( GLubyte c ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glIndexub(c); +#endif +} + +static void AmiglIndexdv( const GLdouble *c ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glIndexdv(c); +#endif +} + +static void AmiglIndexfv( const GLfloat *c ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glIndexfv(c); +#endif +} + +static void AmiglIndexiv( const GLint *c ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glIndexiv(c); +#endif +} + +static void AmiglIndexsv( const GLshort *c ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glIndexsv(c); +#endif +} + +static void AmiglIndexubv( const GLubyte *c ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glIndexubv(c); +#endif +} + +static void AmiglTexCoord1s( GLshort s ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glTexCoord1s(s); +#endif +} + +static void AmiglTexCoord2s( GLshort s, GLshort t ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glTexCoord2s(s, t); +#endif +} + +static void AmiglTexCoord3d( GLdouble s, GLdouble t, GLdouble r ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glTexCoord3d(s, t, r); +#endif +} + +static void AmiglTexCoord3i( GLint s, GLint t, GLint r ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glTexCoord3i(s, t, r); +#endif + } + +static void AmiglTexCoord3s( GLshort s, GLshort t, GLshort r ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glTexCoord3s(s, t, r); +#endif + } + +static void AmiglTexCoord4d( GLdouble s, GLdouble t, GLdouble r, GLdouble q ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glTexCoord4d(s, t, r, q); +#endif +} + +static void AmiglTexCoord4i( GLint s, GLint t, GLint r, GLint q ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glTexCoord4i(s, t, r, q); +#endif +} + +static void AmiglTexCoord4s( GLshort s, GLshort t, GLshort r, GLshort q ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glTexCoord4s(s, t, r, q); +#endif +} + +static void AmiglTexCoord1dv( const GLdouble *v ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glTexCoord1dv(v); +#endif +} + +static void AmiglTexCoord1fv( const GLfloat *v ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glTexCoord1fv(v); +#endif +} + +static void AmiglTexCoord1iv( const GLint *v ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glTexCoord1iv(v); +#endif +} + +static void AmiglTexCoord1sv( const GLshort *v ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glTexCoord1sv(v); +#endif +} + +static void AmiglTexCoord2dv( const GLdouble *v ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glTexCoord2dv(v); +#endif +} + +static void AmiglTexCoord2sv( const GLshort *v ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glTexCoord2sv(v); +#endif +} + +static void AmiglTexCoord3dv( const GLdouble *v ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glTexCoord3dv(v); +#endif +} + +static void AmiglTexCoord3iv( const GLint *v ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glTexCoord3iv(v); +#endif +} + +static void AmiglTexCoord3sv( const GLshort *v ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glTexCoord3sv(v); +#endif +} + +static void AmiglTexCoord4dv( const GLdouble *v ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glTexCoord4dv(v); +#endif +} + +static void AmiglTexCoord4iv( const GLint *v ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glTexCoord4iv(v); +#endif +} + +static void AmiglTexCoord4sv( const GLshort *v ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glTexCoord4sv(v); +#endif +} + +static void AmiglIndexPointer( GLenum type, GLsizei stride, const GLvoid *ptr ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glIndexPointer(type, stride, ptr); +#endif +} + +static void AmiglEdgeFlagPointer( GLsizei stride, const GLboolean *ptr ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glEdgeFlagPointer(stride, ptr); +#endif +} + +static void AmiglGetPointerv( GLenum pname, void **params ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glGetPointerv(pname, params); +#endif +} + +static void AmiglPixelMapfv( GLenum map, GLint mapsize, const GLfloat *values ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glPixelMapfv(map, mapsize, values); +#endif +} + +static void AmiglPixelMapuiv( GLenum map, GLint mapsize, const GLuint *values ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glPixelMapuiv(map, mapsize, values); +#endif +} + +static void AmiglPixelMapusv( GLenum map, GLint mapsize, const GLushort *values ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glPixelMapusv(map, mapsize, values); +#endif +} + +static void AmiglGetPixelMapfv( GLenum map, GLfloat *values ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glGetPixelMapfv(map, values); +#endif +} + +static void AmiglGetPixelMapuiv( GLenum map, GLuint *values ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glGetPixelMapuiv(map, values); +#endif +} + +static void AmiglGetPixelMapusv( GLenum map, GLushort *values ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glGetPixelMapusv(map, values); +#endif +} + +static void AmiglTexGend( GLenum coord, GLenum pname, GLdouble param ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glTexGend(coord, pname, param); +#endif +} + +static void AmiglTexGenf( GLenum coord, GLenum pname, GLfloat param ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glTexGenf(coord, pname, param); +#endif +} + +static void AmiglTexGendv( GLenum coord, GLenum pname, const GLdouble *params ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glTexGendv(coord, pname, params); +#endif +} + +static void AmiglTexGeniv( GLenum coord, GLenum pname, const GLint *params ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glTexGeniv(coord, pname, params); +#endif +} + +static void AmiglGetTexGendv( GLenum coord, GLenum pname, GLdouble *params ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glGetTexGendv(coord, pname, params); +#endif +} + +static void AmiglGetTexGenfv( GLenum coord, GLenum pname, GLfloat *params ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glGetTexGenfv(coord, pname, params); +#endif +} + +static void AmiglGetTexGeniv( GLenum coord, GLenum pname, GLint *params ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glGetTexGeniv(coord, pname, params); +#endif +} + +static void AmiglGetTexEnvfv( GLenum target, GLenum pname, GLfloat *params ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glGetTexEnvfv(target, pname, params); +#endif +} + +static void AmiglFogiv( GLenum pname, const GLint *params ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glFogiv(pname, params); +#endif + } + +static void AmiglFeedbackBuffer( GLsizei size, GLenum type, GLfloat *buffer ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glFeedbackBuffer(size, type, buffer); +#endif +} + +static void AmiglPassThrough( GLfloat token ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glPassThrough(token); +#endif +} + +static void AmiglBlendEquationEXT( GLenum mode ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glBlendEquationEXT(mode); +#endif +} + +static void AmiglBlendColorEXT( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glBlendColorEXT(red, green, blue, alpha); +#endif +} + +static void AmiglPolygonOffsetEXT( GLfloat factor, GLfloat bias ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glPolygonOffsetEXT(factor, bias); +#endif +} + +static void AmiglVertexPointerEXT( GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *ptr ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glVertexPointerEXT(size, type, stride, count, ptr); +#endif +} + +static void AmiglNormalPointerEXT( GLenum type, GLsizei stride, GLsizei count, const GLvoid *ptr ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glNormalPointerEXT(type, stride, count, ptr); +#endif +} + +static void AmiglColorPointerEXT( GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *ptr ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glColorPointerEXT(size, type, stride, count, ptr); +#endif +} + +static void AmiglIndexPointerEXT( GLenum type, GLsizei stride, GLsizei count, const GLvoid *ptr ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glIndexPointerEXT(type, stride, count, ptr); +#endif +} + +static void AmiglTexCoordPointerEXT( GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *ptr ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glTexCoordPointerEXT(size, type, stride, count, ptr); +#endif +} + +static void AmiglEdgeFlagPointerEXT( GLsizei stride, GLsizei count, const GLboolean *ptr ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glEdgeFlagPointerEXT(stride, count, ptr); +#endif +} + +static void AmiglGetPointervEXT( GLenum pname, void **params ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glGetPointervEXT(pname, params); +#endif + } + +static void AmiglArrayElementEXT( GLint i ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glArrayElementEXT(i); +#endif +} + +static void AmiglDrawArraysEXT( GLenum mode, GLint first, GLsizei count ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glDrawArraysEXT(mode, first, count); +#endif +} + +static void AmiglGenTexturesEXT( GLsizei n, GLuint *textures ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glGenTexturesEXT(n, textures); +#endif +} + +static void AmiglDeleteTexturesEXT( GLsizei n, const GLuint *textures) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glDeleteTexturesEXT(n, textures); +#endif +} + +static void AmiglBindTextureEXT( GLenum target, GLuint texture ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glBindTextureEXT(target, texture); +#endif +} + +static void AmiglPrioritizeTexturesEXT( GLsizei n, const GLuint *textures, const GLclampf *priorities ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glPrioritizeTexturesEXT(n, textures, priorities); +#endif +} + +static GLboolean AmiglAreTexturesResidentEXT( GLsizei n, const GLuint *textures, GLboolean *residences ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glAreTexturesResidentEXT(n, textures, residences); +#else + return 0; +#endif +} + +static GLboolean AmiglIsTextureEXT( GLuint texture ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glIsTextureEXT(texture); +#else + return 0; +#endif +} + +static void AmiglTexImage3DEXT( GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glTexImage3DEXT(target, level, internalFormat, width, height, depth, border, format, type, pixels); +#endif +} + +static void AmiglTexSubImage3DEXT( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glTexSubImage3DEXT(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); +#endif +} + +static void AmiglCopyTexSubImage3DEXT( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glCopyTexSubImage3DEXT(target, level, xoffset, yoffset, zoffset, x, y, width, height); +#endif +} + +static void AmiglColorSubTableEXT( GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glColorSubTableEXT(target, start, count, format, type, data); +#endif +} + +static void AmiglGetColorTableEXT( GLenum target, GLenum format, GLenum type, GLvoid *table ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glGetColorTableEXT(target, format, type, table); +#endif +} + +static void AmiglGetColorTableParameterfvEXT( GLenum target, GLenum pname, GLfloat *params ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glGetColorTableParameterfvEXT(target, pname, params); +#endif +} + +static void AmiglGetColorTableParameterivEXT( GLenum target, GLenum pname, GLint *params ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glGetColorTableParameterivEXT(target, pname, params); +#endif +} + +static void AmiglMultiTexCoord1dSGIS(GLenum target, GLdouble s) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord1dSGIS(target, s); +#endif +} + +static void AmiglMultiTexCoord1dvSGIS(GLenum target, const GLdouble *v) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord1dvSGIS(target, v); +#endif +} + +static void AmiglMultiTexCoord1fSGIS(GLenum target, GLfloat s) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord1fSGIS(target, s); +#endif +} +static void AmiglMultiTexCoord1fvSGIS(GLenum target, const GLfloat *v) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord1fvSGIS(target, v); +#endif +} + +static void AmiglMultiTexCoord1iSGIS(GLenum target, GLint s) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord1iSGIS(target, s); +#endif +} + +static void AmiglMultiTexCoord1ivSGIS(GLenum target, const GLint *v) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord1ivSGIS(target, v); +#endif +} + +static void AmiglMultiTexCoord1sSGIS(GLenum target, GLshort s) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord1sSGIS(target, s); +#endif +} + +static void AmiglMultiTexCoord1svSGIS(GLenum target, const GLshort *v) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord1svSGIS(target, v); +#endif +} + +static void AmiglMultiTexCoord2dSGIS(GLenum target, GLdouble s, GLdouble t) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord2dSGIS(target, s, t); +#endif +} + +static void AmiglMultiTexCoord2dvSGIS(GLenum target, const GLdouble *v) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord2dvSGIS(target, v); +#endif +} + +static void AmiglMultiTexCoord2fSGIS(GLenum target, GLfloat s, GLfloat t) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord2fSGIS(target, s, t); +#endif +} + +static void AmiglMultiTexCoord2fvSGIS(GLenum target, const GLfloat *v) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord2fvSGIS(target, v); +#endif +} + +static void AmiglMultiTexCoord2iSGIS(GLenum target, GLint s, GLint t) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord2iSGIS(target, s, t); +#endif +} + +static void AmiglMultiTexCoord2ivSGIS(GLenum target, const GLint *v) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord2ivSGIS(target, v); +#endif +} + +static void AmiglMultiTexCoord2sSGIS(GLenum target, GLshort s, GLshort t) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord2sSGIS(target, s, t); +#endif +} + +static void AmiglMultiTexCoord2svSGIS(GLenum target, const GLshort *v) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord2svSGIS(target, v); +#endif +} + +static void AmiglMultiTexCoord3dSGIS(GLenum target, GLdouble s, GLdouble t, GLdouble r) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord3dSGIS(target, s, t, r); +#endif +} + +static void AmiglMultiTexCoord3dvSGIS(GLenum target, const GLdouble *v) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord3dvSGIS(target, v); +#endif +} + +static void AmiglMultiTexCoord3fSGIS(GLenum target, GLfloat s, GLfloat t, GLfloat r) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord3fSGIS(target, s, t, r); +#endif +} + +static void AmiglMultiTexCoord3fvSGIS(GLenum target, const GLfloat *v) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord3fvSGIS(target, v); +#endif +} + +static void AmiglMultiTexCoord3iSGIS(GLenum target, GLint s, GLint t, GLint r) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord3iSGIS(target, s, t, r); +#endif +} + +static void AmiglMultiTexCoord3ivSGIS(GLenum target, const GLint *v) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord3ivSGIS(target, v); +#endif +} + +static void AmiglMultiTexCoord3sSGIS(GLenum target, GLshort s, GLshort t, GLshort r) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord3sSGIS(target, s, t, r); +#endif +} + +static void AmiglMultiTexCoord3svSGIS(GLenum target, const GLshort *v) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord3svSGIS(target, v); +#endif +} + +static void AmiglMultiTexCoord4dSGIS(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord4dSGIS(target, s, t, r, q); +#endif +} + +static void AmiglMultiTexCoord4dvSGIS(GLenum target, const GLdouble *v) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord4dvSGIS(target, v); +#endif +} + +static void AmiglMultiTexCoord4fSGIS(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord4fSGIS(target, s, t, r, q); +#endif +} + +static void AmiglMultiTexCoord4fvSGIS(GLenum target, const GLfloat *v) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord4fvSGIS(target, v); +#endif +} + +static void AmiglMultiTexCoord4iSGIS(GLenum target, GLint s, GLint t, GLint r, GLint q) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord4iSGIS(target, s, t, r, q); +#endif +} + +static void AmiglMultiTexCoord4ivSGIS(GLenum target, const GLint *v) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord4ivSGIS(target, v); +#endif +} + +static void AmiglMultiTexCoord4sSGIS(GLenum target, GLshort s, GLshort t, GLshort r, GLshort q) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord4sSGIS(target, s, t, r, q); +#endif +} + +static void AmiglMultiTexCoord4svSGIS(GLenum target, const GLshort *v) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord4svSGIS(target, v); +#endif +} + +static void AmiglMultiTexCoordPointerSGIS(GLenum target, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoordPointerSGIS(target, size, type, stride, pointer); +#endif +} + +static void AmiglSelectTextureSGIS(GLenum target) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glSelectTextureSGIS(target); +#endif +} + +static void AmiglSelectTextureCoordSetSGIS(GLenum target) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glSelectTextureCoordSetSGIS(target); +#endif +} + +static void AmiglMultiTexCoord1dEXT(GLenum target, GLdouble s) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord1dEXT(target, s); +#endif +} + +static void AmiglMultiTexCoord1dvEXT(GLenum target, const GLdouble *v) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord1dvEXT(target, v); +#endif +} + +static void AmiglMultiTexCoord1fEXT(GLenum target, GLfloat s) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord1fEXT(target, s); +#endif +} + +static void AmiglMultiTexCoord1fvEXT(GLenum target, const GLfloat *v) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord1fvEXT(target, v); +#endif +} + +static void AmiglMultiTexCoord1iEXT(GLenum target, GLint s) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord1iEXT(target, s); +#endif +} + +static void AmiglMultiTexCoord1ivEXT(GLenum target, const GLint *v) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord1ivEXT(target, v); +#endif +} + +static void AmiglMultiTexCoord1sEXT(GLenum target, GLshort s) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord1sEXT(target, s); +#endif +} + +static void AmiglMultiTexCoord1svEXT(GLenum target, const GLshort *v) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord1svEXT(target, v); +#endif +} + +static void AmiglMultiTexCoord2dEXT(GLenum target, GLdouble s, GLdouble t) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord2dEXT(target, s, t); +#endif +} + +static void AmiglMultiTexCoord2dvEXT(GLenum target, const GLdouble *v) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord2dvEXT(target, v); +#endif +} + +static void AmiglMultiTexCoord2fEXT(GLenum target, GLfloat s, GLfloat t) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord2fEXT(target, s, t); +#endif +} + +static void AmiglMultiTexCoord2fvEXT(GLenum target, const GLfloat *v) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord2fvEXT(target, v); +#endif +} + +static void AmiglMultiTexCoord2iEXT(GLenum target, GLint s, GLint t) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord2iEXT(target, s, t); +#endif +} + +static void AmiglMultiTexCoord2ivEXT(GLenum target, const GLint *v) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord2ivEXT(target, v); +#endif +} + +static void AmiglMultiTexCoord2sEXT(GLenum target, GLshort s, GLshort t) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord2sEXT(target, s, t); +#endif +} +static void AmiglMultiTexCoord2svEXT(GLenum target, const GLshort *v) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord2svEXT(target, v); +#endif +} + +static void AmiglMultiTexCoord3dEXT(GLenum target, GLdouble s, GLdouble t, GLdouble r) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord3dEXT(target, s, t, r); +#endif +} + +static void AmiglMultiTexCoord3dvEXT(GLenum target, const GLdouble *v) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord3dvEXT(target, v); +#endif +} + +static void AmiglMultiTexCoord3fEXT(GLenum target, GLfloat s, GLfloat t, GLfloat r) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord3fEXT(target, s, t, r); +#endif +} + +static void AmiglMultiTexCoord3fvEXT(GLenum target, const GLfloat *v) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord3fvEXT(target, v); +#endif +} + +static void AmiglMultiTexCoord3iEXT(GLenum target, GLint s, GLint t, GLint r) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord3iEXT(target, s, t, r); +#endif +} + +static void AmiglMultiTexCoord3ivEXT(GLenum target, const GLint *v) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord3ivEXT(target, v); +#endif +} + +static void AmiglMultiTexCoord3sEXT(GLenum target, GLshort s, GLshort t, GLshort r) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord3sEXT(target, s, t, r); +#endif +} + +static void AmiglMultiTexCoord3svEXT(GLenum target, const GLshort *v) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord3svEXT(target, v); +#endif +} + +static void AmiglMultiTexCoord4dEXT(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord4dEXT(target, s, t, r, q); +#endif +} + +static void AmiglMultiTexCoord4dvEXT(GLenum target, const GLdouble *v) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord4dvEXT(target, v); +#endif +} + +static void AmiglMultiTexCoord4fEXT(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord4fEXT(target, s, t, r, q); +#endif +} + +static void AmiglMultiTexCoord4fvEXT(GLenum target, const GLfloat *v) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord4fvEXT(target, v); +#endif +} + +static void AmiglMultiTexCoord4iEXT(GLenum target, GLint s, GLint t, GLint r, GLint q) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord4iEXT(target, s, t, r, q); +#endif +} + +static void AmiglMultiTexCoord4ivEXT(GLenum target, const GLint *v) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord4ivEXT(target, v); +#endif +} + +static void AmiglMultiTexCoord4sEXT(GLenum target, GLshort s, GLshort t, GLshort r, GLshort q) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord4sEXT(target, s, t, r, q); +#endif +} + +static void AmiglMultiTexCoord4svEXT(GLenum target, const GLshort *v) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glMultiTexCoord4svEXT(target, v); +#endif +} + +static void AmiglInterleavedTextureCoordSetsEXT( GLint factor ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glInterleavedTextureCoordSetsEXT(factor); +#endif +} + +static void AmiglSelectTextureEXT( GLenum target ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glSelectTextureEXT(target); +#endif +} + +static void AmiglSelectTextureCoordSetEXT( GLenum target ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glSelectTextureCoordSetEXT(target); +#endif +} + +static void AmiglSelectTextureTransformEXT( GLenum target ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glSelectTextureTransformEXT(target); +#endif +} + +static void AmiglPointParameterfEXT( GLenum pname, GLfloat param ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glPointParameterfEXT(pname, param); +#endif +} + +static void AmiglPointParameterfvEXT( GLenum pname, GLfloat *params ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glPointParameterfvEXT(pname, params); +#endif +} + +static void AmiglWindowPos2iMESA( GLint x, GLint y ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glWindowPos2iMESA(x, y); +#endif +} + +static void AmiglWindowPos2sMESA( GLshort x, GLshort y ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glWindowPos2sMESA(x, y); +#endif +} + +static void AmiglWindowPos2fMESA( GLfloat x, GLfloat y ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glWindowPos2fMESA(x, y); +#endif +} + +static void AmiglWindowPos2dMESA( GLdouble x, GLdouble y ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glWindowPos2dMESA(x, y); +#endif +} + +static void AmiglWindowPos2ivMESA( const GLint *p ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glWindowPos2ivMESA(p); +#endif +} + +static void AmiglWindowPos2svMESA( const GLshort *p ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glWindowPos2svMESA(p); +#endif +} + +static void AmiglWindowPos2fvMESA( const GLfloat *p ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glWindowPos2fvMESA(p); +#endif +} + +static void AmiglWindowPos2dvMESA( const GLdouble *p ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glWindowPos2dvMESA(p); +#endif +} + +static void AmiglWindowPos3iMESA( GLint x, GLint y, GLint z ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glWindowPos3iMESA(x, y, z); +#endif +} + +static void AmiglWindowPos3sMESA( GLshort x, GLshort y, GLshort z ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glWindowPos3sMESA(x, y, z); +#endif +} + +static void AmiglWindowPos3fMESA( GLfloat x, GLfloat y, GLfloat z ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glWindowPos3fMESA(x, y, z); +#endif +} + +static void AmiglWindowPos3dMESA( GLdouble x, GLdouble y, GLdouble z ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glWindowPos3dMESA(x, y, z); +#endif +} + +static void AmiglWindowPos3ivMESA( const GLint *p ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glWindowPos3ivMESA(p); +#endif +} + +static void AmiglWindowPos3svMESA( const GLshort *p ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glWindowPos3svMESA(p); +#endif +} + +static void AmiglWindowPos3fvMESA( const GLfloat *p ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glWindowPos3fvMESA(p); +#endif +} + +static void AmiglWindowPos3dvMESA( const GLdouble *p ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glWindowPos3dvMESA(p); +#endif +} + +static void AmiglWindowPos4iMESA( GLint x, GLint y, GLint z, GLint w ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glWindowPos4iMESA(x, y, z, w); +#endif +} + +static void AmiglWindowPos4sMESA( GLshort x, GLshort y, GLshort z, GLshort w ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glWindowPos4sMESA(x, y, z, w); +#endif +} + +static void AmiglWindowPos4fMESA( GLfloat x, GLfloat y, GLfloat z, GLfloat w ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glWindowPos4fMESA(x, y, z, w); +#endif +} + +static void AmiglWindowPos4dMESA( GLdouble x, GLdouble y, GLdouble z, GLdouble w) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glWindowPos4dMESA(x, y, z, w); +#endif +} + +static void AmiglWindowPos4ivMESA( const GLint *p ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glWindowPos4ivMESA(p); +#endif +} + +static void AmiglWindowPos4svMESA( const GLshort *p ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glWindowPos4svMESA(p); +#endif +} + +static void AmiglWindowPos4fvMESA( const GLfloat *p ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glWindowPos4fvMESA(p); +#endif +} + +static void AmiglWindowPos4dvMESA( const GLdouble *p ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glWindowPos4dvMESA(p); +#endif +} + +static void AmiglResizeBuffersMESA( void ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glResizeBuffersMESA(); +#endif +} + +static void AmiglTexImage3D( GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glTexImage3D(target, level, internalFormat, width, height, depth, border, format, type, pixels); +#endif +} + +static void AmiglTexSubImage3D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); +#endif +} + +static void AmiglCopyTexSubImage3D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height ) { +FUNC_NOT_IMPLEMENTED +#ifndef __amigaos4__ + return glCopyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height); +#endif +} + + + diff --git a/src/video/amigaos4/SDL_os4_notimplemented_table.t b/src/video/amigaos4/SDL_os4_notimplemented_table.t new file mode 100644 index 0000000000000..30991e573a239 --- /dev/null +++ b/src/video/amigaos4/SDL_os4_notimplemented_table.t @@ -0,0 +1,182 @@ +{ "glClearIndex", AmiglClearIndex }, +{ "glIndexMask", AmiglIndexMask }, +{ "glGetPolygonStipple", AmiglGetPolygonStipple }, +{ "glEdgeFlagv", AmiglEdgeFlagv }, +{ "glClearAccum", AmiglClearAccum }, +{ "glAccum", AmiglAccum }, +{ "glIndexd", AmiglIndexd }, +{ "glIndexf", AmiglIndexf }, +{ "glIndexi", AmiglIndexi }, +{ "glIndexs", AmiglIndexs }, +{ "glIndexub", AmiglIndexub }, +{ "glIndexdv", AmiglIndexdv }, +{ "glIndexfv", AmiglIndexfv }, +{ "glIndexiv", AmiglIndexiv }, +{ "glIndexsv", AmiglIndexsv }, +{ "glIndexubv", AmiglIndexubv }, +{ "glTexCoord1s", AmiglTexCoord1s }, +{ "glTexCoord2s", AmiglTexCoord2s }, +{ "glTexCoord3d", AmiglTexCoord3d }, +{ "glTexCoord3i", AmiglTexCoord3i }, +{ "glTexCoord3s", AmiglTexCoord3s }, +{ "glTexCoord4d", AmiglTexCoord4d }, +{ "glTexCoord4i", AmiglTexCoord4i }, +{ "glTexCoord4s", AmiglTexCoord4s }, +{ "glTexCoord1dv", AmiglTexCoord1dv }, +{ "glTexCoord1fv", AmiglTexCoord1fv }, +{ "glTexCoord1iv", AmiglTexCoord1iv }, +{ "glTexCoord1sv", AmiglTexCoord1sv }, +{ "glTexCoord2dv", AmiglTexCoord2dv }, +{ "glTexCoord2sv", AmiglTexCoord2sv }, +{ "glTexCoord3dv", AmiglTexCoord3dv }, +{ "glTexCoord3iv", AmiglTexCoord3iv }, +{ "glTexCoord3sv", AmiglTexCoord3sv }, +{ "glTexCoord4dv", AmiglTexCoord4dv }, +{ "glTexCoord4iv", AmiglTexCoord4iv }, +{ "glTexCoord4sv", AmiglTexCoord4sv }, +{ "glIndexPointer", AmiglIndexPointer }, +{ "glEdgeFlagPointer", AmiglEdgeFlagPointer }, +{ "glGetPointerv", AmiglGetPointerv }, +{ "glPixelMapfv", AmiglPixelMapfv }, +{ "glPixelMapuiv", AmiglPixelMapuiv }, +{ "glPixelMapusv", AmiglPixelMapusv }, +{ "glGetPixelMapfv", AmiglGetPixelMapfv }, +{ "glGetPixelMapuiv", AmiglGetPixelMapuiv }, +{ "glGetPixelMapusv", AmiglGetPixelMapusv }, +{ "glTexGend", AmiglTexGend }, +{ "glTexGenf", AmiglTexGenf }, +{ "glTexGendv", AmiglTexGendv }, +{ "glTexGeniv", AmiglTexGeniv }, +{ "glGetTexGendv", AmiglGetTexGendv }, +{ "glGetTexGenfv", AmiglGetTexGenfv }, +{ "glGetTexGeniv", AmiglGetTexGeniv }, +{ "glGetTexEnvfv", AmiglGetTexEnvfv }, +{ "glFogiv", AmiglFogiv }, +{ "glFeedbackBuffer", AmiglFeedbackBuffer }, +{ "glPassThrough", AmiglPassThrough }, +{ "glBlendEquationEXT", AmiglBlendEquationEXT }, +{ "glBlendColorEXT", AmiglBlendColorEXT }, +{ "glPolygonOffsetEXT", AmiglPolygonOffsetEXT }, +{ "glVertexPointerEXT", AmiglVertexPointerEXT }, +{ "glNormalPointerEXT", AmiglNormalPointerEXT }, +{ "glColorPointerEXT", AmiglColorPointerEXT }, +{ "glIndexPointerEXT", AmiglIndexPointerEXT }, +{ "glTexCoordPointerEXT", AmiglTexCoordPointerEXT }, +{ "glEdgeFlagPointerEXT", AmiglEdgeFlagPointerEXT }, +{ "glGetPointervEXT", AmiglGetPointervEXT }, +{ "glArrayElementEXT", AmiglArrayElementEXT }, +{ "glDrawArraysEXT", AmiglDrawArraysEXT }, +{ "glGenTexturesEXT", AmiglGenTexturesEXT }, +{ "glDeleteTexturesEXT", AmiglDeleteTexturesEXT }, +{ "glBindTextureEXT", AmiglBindTextureEXT }, +{ "glPrioritizeTexturesEXT", AmiglPrioritizeTexturesEXT }, +{ "glAreTexturesResidentEXT", AmiglAreTexturesResidentEXT }, +{ "glIsTextureEXT", AmiglIsTextureEXT }, +{ "glTexImage3DEXT", AmiglTexImage3DEXT }, +{ "glTexSubImage3DEXT", AmiglTexSubImage3DEXT }, +{ "glCopyTexSubImage3DEXT", AmiglCopyTexSubImage3DEXT }, +{ "glColorSubTableEXT", AmiglColorSubTableEXT }, +{ "glGetColorTableEXT", AmiglGetColorTableEXT }, +{ "glGetColorTableParameterfvEXT", AmiglGetColorTableParameterfvEXT }, +{ "glGetColorTableParameterivEXT", AmiglGetColorTableParameterivEXT }, +{ "glMultiTexCoord1dSGIS", AmiglMultiTexCoord1dSGIS }, +{ "glMultiTexCoord1dvSGIS", AmiglMultiTexCoord1dvSGIS }, +{ "glMultiTexCoord1fSGIS", AmiglMultiTexCoord1fSGIS }, +{ "glMultiTexCoord1fvSGIS", AmiglMultiTexCoord1fvSGIS }, +{ "glMultiTexCoord1iSGIS", AmiglMultiTexCoord1iSGIS }, +{ "glMultiTexCoord1ivSGIS", AmiglMultiTexCoord1ivSGIS }, +{ "glMultiTexCoord1sSGIS", AmiglMultiTexCoord1sSGIS }, +{ "glMultiTexCoord1svSGIS", AmiglMultiTexCoord1svSGIS }, +{ "glMultiTexCoord2dSGIS", AmiglMultiTexCoord2dSGIS }, +{ "glMultiTexCoord2dvSGIS", AmiglMultiTexCoord2dvSGIS }, +{ "glMultiTexCoord2fSGIS", AmiglMultiTexCoord2fSGIS }, +{ "glMultiTexCoord2fvSGIS", AmiglMultiTexCoord2fvSGIS }, +{ "glMultiTexCoord2iSGIS", AmiglMultiTexCoord2iSGIS }, +{ "glMultiTexCoord2ivSGIS", AmiglMultiTexCoord2ivSGIS }, +{ "glMultiTexCoord2sSGIS", AmiglMultiTexCoord2sSGIS }, +{ "glMultiTexCoord2svSGIS", AmiglMultiTexCoord2svSGIS }, +{ "glMultiTexCoord3dSGIS", AmiglMultiTexCoord3dSGIS }, +{ "glMultiTexCoord3dvSGIS", AmiglMultiTexCoord3dvSGIS }, +{ "glMultiTexCoord3fSGIS", AmiglMultiTexCoord3fSGIS }, +{ "glMultiTexCoord3fvSGIS", AmiglMultiTexCoord3fvSGIS }, +{ "glMultiTexCoord3iSGIS", AmiglMultiTexCoord3iSGIS }, +{ "glMultiTexCoord3ivSGIS", AmiglMultiTexCoord3ivSGIS }, +{ "glMultiTexCoord3sSGIS", AmiglMultiTexCoord3sSGIS }, +{ "glMultiTexCoord3svSGIS", AmiglMultiTexCoord3svSGIS }, +{ "glMultiTexCoord4dSGIS", AmiglMultiTexCoord4dSGIS }, +{ "glMultiTexCoord4dvSGIS", AmiglMultiTexCoord4dvSGIS }, +{ "glMultiTexCoord4fSGIS", AmiglMultiTexCoord4fSGIS }, +{ "glMultiTexCoord4fvSGIS", AmiglMultiTexCoord4fvSGIS }, +{ "glMultiTexCoord4iSGIS", AmiglMultiTexCoord4iSGIS }, +{ "glMultiTexCoord4ivSGIS", AmiglMultiTexCoord4ivSGIS }, +{ "glMultiTexCoord4sSGIS", AmiglMultiTexCoord4sSGIS }, +{ "glMultiTexCoord4svSGIS", AmiglMultiTexCoord4svSGIS }, +{ "glMultiTexCoordPointerSGIS", AmiglMultiTexCoordPointerSGIS }, +{ "glSelectTextureSGIS", AmiglSelectTextureSGIS }, +{ "glSelectTextureCoordSetSGIS", AmiglSelectTextureCoordSetSGIS }, +{ "glMultiTexCoord1dEXT", AmiglMultiTexCoord1dEXT }, +{ "glMultiTexCoord1dvEXT", AmiglMultiTexCoord1dvEXT }, +{ "glMultiTexCoord1fEXT", AmiglMultiTexCoord1fEXT }, +{ "glMultiTexCoord1fvEXT", AmiglMultiTexCoord1fvEXT }, +{ "glMultiTexCoord1iEXT", AmiglMultiTexCoord1iEXT }, +{ "glMultiTexCoord1ivEXT", AmiglMultiTexCoord1ivEXT }, +{ "glMultiTexCoord1sEXT", AmiglMultiTexCoord1sEXT }, +{ "glMultiTexCoord1svEXT", AmiglMultiTexCoord1svEXT }, +{ "glMultiTexCoord2dEXT", AmiglMultiTexCoord2dEXT }, +{ "glMultiTexCoord2dvEXT", AmiglMultiTexCoord2dvEXT }, +{ "glMultiTexCoord2fEXT", AmiglMultiTexCoord2fEXT }, +{ "glMultiTexCoord2fvEXT", AmiglMultiTexCoord2fvEXT }, +{ "glMultiTexCoord2iEXT", AmiglMultiTexCoord2iEXT }, +{ "glMultiTexCoord2ivEXT", AmiglMultiTexCoord2ivEXT }, +{ "glMultiTexCoord2sEXT", AmiglMultiTexCoord2sEXT }, +{ "glMultiTexCoord2svEXT", AmiglMultiTexCoord2svEXT }, +{ "glMultiTexCoord3dEXT", AmiglMultiTexCoord3dEXT }, +{ "glMultiTexCoord3dvEXT", AmiglMultiTexCoord3dvEXT }, +{ "glMultiTexCoord3fEXT", AmiglMultiTexCoord3fEXT }, +{ "glMultiTexCoord3fvEXT", AmiglMultiTexCoord3fvEXT }, +{ "glMultiTexCoord3iEXT", AmiglMultiTexCoord3iEXT }, +{ "glMultiTexCoord3ivEXT", AmiglMultiTexCoord3ivEXT }, +{ "glMultiTexCoord3sEXT", AmiglMultiTexCoord3sEXT }, +{ "glMultiTexCoord3svEXT", AmiglMultiTexCoord3svEXT }, +{ "glMultiTexCoord4dEXT", AmiglMultiTexCoord4dEXT }, +{ "glMultiTexCoord4dvEXT", AmiglMultiTexCoord4dvEXT }, +{ "glMultiTexCoord4fEXT", AmiglMultiTexCoord4fEXT }, +{ "glMultiTexCoord4fvEXT", AmiglMultiTexCoord4fvEXT }, +{ "glMultiTexCoord4iEXT", AmiglMultiTexCoord4iEXT }, +{ "glMultiTexCoord4ivEXT", AmiglMultiTexCoord4ivEXT }, +{ "glMultiTexCoord4sEXT", AmiglMultiTexCoord4sEXT }, +{ "glMultiTexCoord4svEXT", AmiglMultiTexCoord4svEXT }, +{ "glInterleavedTextureCoordSetsEXT", AmiglInterleavedTextureCoordSetsEXT }, +{ "glSelectTextureEXT", AmiglSelectTextureEXT }, +{ "glSelectTextureCoordSetEXT", AmiglSelectTextureCoordSetEXT }, +{ "glSelectTextureTransformEXT", AmiglSelectTextureTransformEXT }, +{ "glPointParameterfEXT", AmiglPointParameterfEXT }, +{ "glPointParameterfvEXT", AmiglPointParameterfvEXT }, +{ "glWindowPos2iMESA", AmiglWindowPos2iMESA }, +{ "glWindowPos2sMESA", AmiglWindowPos2sMESA }, +{ "glWindowPos2fMESA", AmiglWindowPos2fMESA }, +{ "glWindowPos2dMESA", AmiglWindowPos2dMESA }, +{ "glWindowPos2ivMESA", AmiglWindowPos2ivMESA }, +{ "glWindowPos2svMESA", AmiglWindowPos2svMESA }, +{ "glWindowPos2fvMESA", AmiglWindowPos2fvMESA }, +{ "glWindowPos2dvMESA", AmiglWindowPos2dvMESA }, +{ "glWindowPos3iMESA", AmiglWindowPos3iMESA }, +{ "glWindowPos3sMESA", AmiglWindowPos3sMESA }, +{ "glWindowPos3fMESA", AmiglWindowPos3fMESA }, +{ "glWindowPos3dMESA", AmiglWindowPos3dMESA }, +{ "glWindowPos3ivMESA", AmiglWindowPos3ivMESA }, +{ "glWindowPos3svMESA", AmiglWindowPos3svMESA }, +{ "glWindowPos3fvMESA", AmiglWindowPos3fvMESA }, +{ "glWindowPos3dvMESA", AmiglWindowPos3dvMESA }, +{ "glWindowPos4iMESA", AmiglWindowPos4iMESA }, +{ "glWindowPos4sMESA", AmiglWindowPos4sMESA }, +{ "glWindowPos4fMESA", AmiglWindowPos4fMESA }, +{ "glWindowPos4dMESA", AmiglWindowPos4dMESA }, +{ "glWindowPos4ivMESA", AmiglWindowPos4ivMESA }, +{ "glWindowPos4svMESA", AmiglWindowPos4svMESA }, +{ "glWindowPos4fvMESA", AmiglWindowPos4fvMESA }, +{ "glWindowPos4dvMESA", AmiglWindowPos4dvMESA }, +{ "glResizeBuffersMESA", AmiglResizeBuffersMESA }, +{ "glTexImage3D", AmiglTexImage3D }, +{ "glTexSubImage3D", AmiglTexSubImage3D }, +{ "glCopyTexSubImage3D", AmiglCopyTexSubImage3D }, diff --git a/src/video/amigaos4/SDL_os4events.c b/src/video/amigaos4/SDL_os4events.c new file mode 100644 index 0000000000000..aed9edb12974b --- /dev/null +++ b/src/video/amigaos4/SDL_os4events.c @@ -0,0 +1,701 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2020 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_AMIGAOS4 + +#include +#include + +#include "SDL_os4video.h" +#include "SDL_os4shape.h" +#include "SDL_os4mouse.h" +#include "SDL_os4window.h" +#include "SDL_os4events.h" + +#include "../../events/SDL_keyboard_c.h" +#include "../../events/SDL_mouse_c.h" +#include "../../events/SDL_windowevents_c.h" +#include "../../events/scancodes_amiga.h" +#include "../../events/SDL_events_c.h" + +//#define DEBUG +#include "../../main/amigaos4/SDL_os4debug.h" + +extern SDL_bool (*OS4_ResizeGlContext)(_THIS, SDL_Window * window); + +struct MyIntuiMessage +{ + uint32 Class; + uint16 Code; + uint16 Qualifier; + + struct Gadget *Gadget; + struct Window *IDCMPWindow; + + int16 RelativeMouseX; + int16 RelativeMouseY; + + int16 WindowMouseX; // Absolute pointer position, relative to + int16 WindowMouseY; // top-left corner of inner window + + int16 ScreenMouseX; + int16 ScreenMouseY; + + int16 Width; // Inner window dimensions + int16 Height; +}; + +struct QualifierItem +{ + UWORD qualifier; + SDL_Keymod keymod; + const char* name; +}; + +extern OS4_GlobalMouseState globalMouseState; + +static void +OS4_SyncKeyModifiers(_THIS) +{ + int i; + UWORD qualifiers = IInput->PeekQualifier(); + + struct QualifierItem map[] = { + { IEQUALIFIER_LSHIFT, KMOD_LSHIFT, "Left Shift" }, + { IEQUALIFIER_RSHIFT, KMOD_RSHIFT, "Right Shift" }, + { IEQUALIFIER_CAPSLOCK, KMOD_CAPS, "Capslock" }, + { IEQUALIFIER_CONTROL, KMOD_CTRL, "Control" }, + { IEQUALIFIER_LALT, KMOD_LALT, "Left Alt" }, + { IEQUALIFIER_RALT, KMOD_RALT, "Right Alt" }, + { IEQUALIFIER_LCOMMAND, KMOD_LGUI, "Left Amiga" }, + { IEQUALIFIER_RCOMMAND, KMOD_RGUI, "Right Amiga" } + }; + + dprintf("Current qualifiers: %d\n", qualifiers); + + for (i = 0; i < SDL_arraysize(map); i++) { + dprintf("%s %s\n", map[i].name, (qualifiers & map[i].qualifier) ? "ON" : "off"); + SDL_ToggleModState(map[i].keymod, (qualifiers & map[i].qualifier) != 0); + } +} + +// We could possibly use also Window.userdata field to contain SDL_Window, +// and thus avoid searching +static SDL_Window * +OS4_FindWindow(_THIS, struct Window * syswin) +{ + SDL_Window *sdlwin; + + for (sdlwin = _this->windows; sdlwin; sdlwin = sdlwin->next) { + + SDL_WindowData *data = sdlwin->driverdata; + + if (data->syswin == syswin) { + + //dprintf("Found window %p\n", syswin); + return sdlwin; + } + } + + dprintf("No SDL window found\n"); + + return NULL; +} + +static char +OS4_TranslateUnicode(_THIS, uint16 code, uint32 qualifier) +{ + struct InputEvent ie; + uint16 res; + char buffer[10]; + + ie.ie_Class = IECLASS_RAWKEY; + ie.ie_SubClass = 0; + ie.ie_Code = code & ~(IECODE_UP_PREFIX); + ie.ie_Qualifier = qualifier; + ie.ie_EventAddress = NULL; + + res = IKeymap->MapRawKey(&ie, buffer, sizeof(buffer), 0); + + if (res != 1) + return 0; + else + return buffer[0]; +} + +static void +OS4_HandleKeyboard(_THIS, struct MyIntuiMessage * imsg) +{ + uint8 rawkey = imsg->Code & 0x7F; + + if (rawkey < sizeof(amiga_scancode_table) / sizeof(amiga_scancode_table[0])) { + + SDL_Scancode s = amiga_scancode_table[rawkey]; + + if (imsg->Code < 0x80) { + char text[2]; + + text[0] = OS4_TranslateUnicode(_this, imsg->Code, imsg->Qualifier); + text[1] = '\0'; + + SDL_SendKeyboardKey(SDL_PRESSED, s); + + if (text[0] && text[0] < 0x80) { + /* SDL wants UTF-8 strings. Filter out codes above 7-bit to avoid + interpretation issues later. */ + SDL_SendKeyboardText(text); + } + } else { + SDL_SendKeyboardKey(SDL_RELEASED, s); + } + } +} + +static void +OS4_HandleHitTestMotion(_THIS, SDL_Window * sdlwin, struct MyIntuiMessage * imsg) +{ + HitTestInfo *hti = &((SDL_WindowData *)sdlwin->driverdata)->hti; + + int16 newx = imsg->ScreenMouseX; + int16 newy = imsg->ScreenMouseY; + + int16 deltax = newx - hti->point.x; + int16 deltay = newy - hti->point.y; + + int16 x, y, w, h; + + if (deltax == 0 && deltay == 0) { + return; + } + + x = sdlwin->x; + y = sdlwin->y; + w = sdlwin->w; + h = sdlwin->h; + + hti->point.x = newx; + hti->point.y = newy; + + switch (hti->htr) { + case SDL_HITTEST_DRAGGABLE: + x += deltax; + y += deltay; + break; + + case SDL_HITTEST_RESIZE_TOPLEFT: + x += deltax; + y += deltay; + w -= deltax; + h -= deltay; + break; + + case SDL_HITTEST_RESIZE_TOP: + y += deltay; + h -= deltay; + break; + + case SDL_HITTEST_RESIZE_TOPRIGHT: + y += deltay; + w += deltax; + h -= deltay; + break; + + case SDL_HITTEST_RESIZE_RIGHT: + w += deltax; + break; + + case SDL_HITTEST_RESIZE_BOTTOMRIGHT: + w += deltax; + h += deltay; + break; + + case SDL_HITTEST_RESIZE_BOTTOM: + h += deltay; + break; + + case SDL_HITTEST_RESIZE_BOTTOMLEFT: + x += deltax; + + w -= deltax; + h += deltay; + break; + + case SDL_HITTEST_RESIZE_LEFT: + x += deltax; + w -= deltax; + break; + + default: + break; + } + + dprintf("newx %d, newy %d (dx %d, dy %d) w=%d h=%d\n", newx, newy, deltax, deltay, w, h); + + sdlwin->x = x; + sdlwin->y = y; + sdlwin->w = w; + sdlwin->h = h; + + OS4_SetWindowBox(_this, sdlwin); +} + +static SDL_bool +OS4_IsHitTestResize(HitTestInfo * hti) +{ + switch (hti->htr) { + case SDL_HITTEST_RESIZE_TOPLEFT: + case SDL_HITTEST_RESIZE_TOP: + case SDL_HITTEST_RESIZE_TOPRIGHT: + case SDL_HITTEST_RESIZE_RIGHT: + case SDL_HITTEST_RESIZE_BOTTOMRIGHT: + case SDL_HITTEST_RESIZE_BOTTOM: + case SDL_HITTEST_RESIZE_BOTTOMLEFT: + case SDL_HITTEST_RESIZE_LEFT: + return SDL_TRUE; + + default: + return SDL_FALSE; + } +} + +static void +OS4_HandleMouseMotion(_THIS, struct MyIntuiMessage * imsg) +{ + SDL_Window *sdlwin = OS4_FindWindow(_this, imsg->IDCMPWindow); + + if (sdlwin) { + HitTestInfo *hti = &((SDL_WindowData *)sdlwin->driverdata)->hti; + + dprintf("X:%d Y:%d, ScreenX: %d ScreenY: %d\n", + imsg->WindowMouseX, imsg->WindowMouseY, imsg->ScreenMouseX, imsg->ScreenMouseY); + + globalMouseState.x = imsg->ScreenMouseX; + globalMouseState.y = imsg->ScreenMouseY; + + if (SDL_GetRelativeMouseMode()) { + SDL_SendMouseMotion(sdlwin, 0 /*mouse->mouseID*/, 1, + imsg->RelativeMouseX, + imsg->RelativeMouseY); + } else { + SDL_SendMouseMotion(sdlwin, 0 /*mouse->mouseID*/, 0, + imsg->WindowMouseX, + imsg->WindowMouseY); + } + + if (hti->htr != SDL_HITTEST_NORMAL) { + OS4_HandleHitTestMotion(_this, sdlwin, imsg); + } + } +} + +static SDL_bool +OS4_HandleHitTest(_THIS, SDL_Window * sdlwin, struct MyIntuiMessage * imsg) +{ + if (sdlwin->hit_test) { + const SDL_Point point = { imsg->WindowMouseX, imsg->WindowMouseY }; + const SDL_HitTestResult rc = sdlwin->hit_test(sdlwin, &point, sdlwin->hit_test_data); + + HitTestInfo *hti = &((SDL_WindowData *)sdlwin->driverdata)->hti; + + switch (rc) { + case SDL_HITTEST_DRAGGABLE: + case SDL_HITTEST_RESIZE_TOPLEFT: + case SDL_HITTEST_RESIZE_TOP: + case SDL_HITTEST_RESIZE_TOPRIGHT: + case SDL_HITTEST_RESIZE_RIGHT: + case SDL_HITTEST_RESIZE_BOTTOMRIGHT: + case SDL_HITTEST_RESIZE_BOTTOM: + case SDL_HITTEST_RESIZE_BOTTOMLEFT: + case SDL_HITTEST_RESIZE_LEFT: + // Store the action and mouse coordinates for later use + hti->htr = rc; + hti->point.x = imsg->ScreenMouseX; + hti->point.y = imsg->ScreenMouseY; + + return SDL_TRUE; + + default: + return SDL_FALSE; + } + } + + return SDL_FALSE; +} + +static int +OS4_GetButtonState(uint16 code) +{ + return (code & IECODE_UP_PREFIX) ? SDL_RELEASED : SDL_PRESSED; +} + +static int +OS4_GetButton(uint16 code) +{ + switch (code & ~IECODE_UP_PREFIX) { + case IECODE_LBUTTON: + return SDL_BUTTON_LEFT; + case IECODE_RBUTTON: + return SDL_BUTTON_RIGHT; + case IECODE_MBUTTON: + return SDL_BUTTON_MIDDLE; + default: + return 0; + } +} + +static void +OS4_HandleMouseButtons(_THIS, struct MyIntuiMessage * imsg) +{ + SDL_Window *sdlwin = OS4_FindWindow(_this, imsg->IDCMPWindow); + + if (sdlwin) { + uint8 button = OS4_GetButton(imsg->Code); + uint8 state = OS4_GetButtonState(imsg->Code); + + globalMouseState.buttonPressed[button] = state; + + dprintf("X:%d Y:%d button:%d state:%d\n", + imsg->WindowMouseX, imsg->WindowMouseY, button, state); + + if (button == SDL_BUTTON_LEFT) { + if (state == SDL_PRESSED) { + + if (OS4_HandleHitTest(_this, sdlwin, imsg)) { + return; + } + } else { + HitTestInfo *hti = &((SDL_WindowData *)sdlwin->driverdata)->hti; + + hti->htr = SDL_HITTEST_NORMAL; + // TODO: shape resize? OpenGL resize? + SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_RESIZED, + imsg->Width, imsg->Height); + } + } + + // TODO: can we support more buttons? + SDL_SendMouseButton(sdlwin, 0, state, button); + } +} + +static void +OS4_HandleMouseWheel(_THIS, struct MyIntuiMessage * imsg) +{ + SDL_Window *sdlwin = OS4_FindWindow(_this, imsg->IDCMPWindow); + + if (sdlwin) { + struct IntuiWheelData *data = (struct IntuiWheelData *)imsg->Gadget; + + if (data->WheelY < 0) { + SDL_SendMouseWheel(sdlwin, 0, 0, 1, SDL_MOUSEWHEEL_NORMAL); + } else if (data->WheelY > 0) { + SDL_SendMouseWheel(sdlwin, 0, 0, -1, SDL_MOUSEWHEEL_NORMAL); + } + + if (data->WheelX < 0) { + SDL_SendMouseWheel(sdlwin, 0, 1, 0, SDL_MOUSEWHEEL_NORMAL); + } else if (data->WheelX > 0) { + SDL_SendMouseWheel(sdlwin, 0, -1, 0, SDL_MOUSEWHEEL_NORMAL); + } + } +} + +static void +OS4_HandleResize(_THIS, struct MyIntuiMessage * imsg) +{ + SDL_Window *sdlwin = OS4_FindWindow(_this, imsg->IDCMPWindow); + + if (sdlwin) { + HitTestInfo *hti = &((SDL_WindowData *)sdlwin->driverdata)->hti; + + if (OS4_IsHitTestResize(hti)) { + // Intuition notifies about resize during hit test action, + // but it will confuse hit test logic. + // That is why we ignore these for now. + dprintf("Resize notification ignored because resize is still in progress\n"); + } else { + dprintf("Window resized to %d*%d\n", imsg->Width, imsg->Height); + + if (imsg->Width != sdlwin->w || imsg->Height != sdlwin->h) { + SDL_WindowData *data = (SDL_WindowData *)sdlwin->driverdata; + + SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_RESIZED, + imsg->Width, + imsg->Height); + + if (SDL_IsShapedWindow(sdlwin)) { + OS4_ResizeWindowShape(sdlwin); + } + + if (data->glContext /*sdlwin->flags & SDL_WINDOW_OPENGL*/ ) { + OS4_ResizeGlContext(_this, sdlwin); + } + } + } + } +} + +static void +OS4_HandleMove(_THIS, struct MyIntuiMessage * imsg) +{ + SDL_Window *sdlwin = OS4_FindWindow(_this, imsg->IDCMPWindow); + + if (sdlwin) { + SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_MOVED, + imsg->IDCMPWindow->LeftEdge, + imsg->IDCMPWindow->TopEdge); + + dprintf("Window %p changed\n", sdlwin); + } +} + +static void +OS4_HandleActivation(_THIS, struct MyIntuiMessage * imsg, SDL_bool activated) +{ + SDL_Window *sdlwin = OS4_FindWindow(_this, imsg->IDCMPWindow); + + if (sdlwin) { + if (activated) { + SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_SHOWN, 0, 0); + OS4_SyncKeyModifiers(_this); + + if (SDL_GetKeyboardFocus() != sdlwin) { + SDL_SetKeyboardFocus(sdlwin); + // TODO: do we want to set mouse colors as in SDL1? + } + } else { + if (SDL_GetKeyboardFocus() == sdlwin) { + SDL_SetKeyboardFocus(NULL); + // TODO: do we want to reset mouse colors as in SDL1? + } + } + + dprintf("Window %p activation %d\n", sdlwin, activated); + } +} + +static void +OS4_HandleClose(_THIS, struct MyIntuiMessage * imsg) +{ + SDL_Window *sdlwin = OS4_FindWindow(_this, imsg->IDCMPWindow); + + if (sdlwin) { + SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_CLOSE, 0, 0); + } +} + +static void +OS4_HandleTicks(_THIS, struct MyIntuiMessage * imsg) +{ + SDL_Window *sdlwin = OS4_FindWindow(_this, imsg->IDCMPWindow); + + if (sdlwin) { + if ((sdlwin->flags & SDL_WINDOW_INPUT_GRABBED) && !(sdlwin->flags & SDL_WINDOW_FULLSCREEN) && + (SDL_GetKeyboardFocus() == sdlwin)) { + + SDL_WindowData *data = sdlwin->driverdata; + + dprintf("Window %p ticks %d\n", imsg->IDCMPWindow, data->pointerGrabTicks); + + // Re-grab the window after our ticks have passed + if (++data->pointerGrabTicks >= POINTER_GRAB_TIMEOUT) { + data->pointerGrabTicks = 0; + + OS4_SetWindowGrabPrivate(_this, imsg->IDCMPWindow, TRUE); + } + } + } +} + +static void +OS4_HandleGadget(_THIS, struct MyIntuiMessage * msg) +{ + dprintf("Gadget event %p\n", msg->Gadget); + + if (msg->Gadget->GadgetID == GID_ICONIFY) { + SDL_Window *sdlwin = OS4_FindWindow(_this, msg->IDCMPWindow); + + if (sdlwin) { + dprintf("Iconify button pressed\n"); + OS4_IconifyWindow(_this, sdlwin); + } + } +} + +static void +OS4_HandleAppWindow(_THIS, struct AppMessage * msg) +{ + SDL_Window *window = (SDL_Window *)msg->am_UserData; + + int i; + for (i = 0; i < msg->am_NumArgs; i++) { + const size_t maxPathLen = 255; + char buf[maxPathLen]; + + if (IDOS->NameFromLock(msg->am_ArgList[i].wa_Lock, buf, sizeof(buf))) { + if (IDOS->AddPart(buf, msg->am_ArgList[i].wa_Name, sizeof(buf))) { + dprintf("%s\n", buf); + SDL_SendDropFile(window, buf); + } + } + } + + SDL_SendDropComplete(window); +} + +static void +OS4_HandleAppIcon(_THIS, struct AppMessage * msg) +{ + SDL_Window *window = (SDL_Window *)msg->am_UserData; + dprintf("Window ptr = %p\n", window); + + OS4_UniconifyWindow(_this, window); +} + +static void +OS4_CopyIdcmpMessage(struct IntuiMessage * src, struct MyIntuiMessage * dst) +{ + // Copy relevant fields. This makes it safer if the window goes away during + // this loop (re-open due to keystroke) + dst->Class = src->Class; + dst->Code = src->Code; + dst->Qualifier = src->Qualifier; + + dst->Gadget = (struct Gadget *) src->IAddress; + + dst->RelativeMouseX = src->MouseX; + dst->RelativeMouseY = src->MouseY; + + dst->IDCMPWindow = src->IDCMPWindow; + + if (src->IDCMPWindow) { + dst->WindowMouseX = src->IDCMPWindow->MouseX - src->IDCMPWindow->BorderLeft; + dst->WindowMouseY = src->IDCMPWindow->MouseY - src->IDCMPWindow->BorderTop; + + dst->ScreenMouseX = src->IDCMPWindow->WScreen->MouseX; + dst->ScreenMouseY = src->IDCMPWindow->WScreen->MouseY; + + dst->Width = src->IDCMPWindow->Width - src->IDCMPWindow->BorderLeft - src->IDCMPWindow->BorderRight; + dst->Height = src->IDCMPWindow->Height - src->IDCMPWindow->BorderTop - src->IDCMPWindow->BorderBottom; + } +} + +// TODO: we need to handle Intuition's window move (repositioning) event and update sdlwin's x&y +static void +OS4_HandleIdcmpMessages(_THIS, struct MsgPort * msgPort) +{ + struct IntuiMessage *imsg; + struct MyIntuiMessage msg; + + while ((imsg = (struct IntuiMessage *)IExec->GetMsg(msgPort))) { + + OS4_CopyIdcmpMessage(imsg, &msg); + + IExec->ReplyMsg((struct Message *) imsg); + + switch (msg.Class) { + case IDCMP_MOUSEMOVE: + OS4_HandleMouseMotion(_this, &msg); + break; + + case IDCMP_RAWKEY: + OS4_HandleKeyboard(_this, &msg); + break; + + case IDCMP_MOUSEBUTTONS: + OS4_HandleMouseButtons(_this, &msg); + break; + + case IDCMP_EXTENDEDMOUSE: + OS4_HandleMouseWheel(_this, &msg); + break; + + case IDCMP_NEWSIZE: + OS4_HandleResize(_this, &msg); + break; + + case IDCMP_CHANGEWINDOW: + OS4_HandleMove(_this, &msg); + OS4_HandleResize(_this, &msg); + break; + + case IDCMP_ACTIVEWINDOW: + OS4_HandleActivation(_this, &msg, SDL_TRUE); + break; + + case IDCMP_INACTIVEWINDOW: + OS4_HandleActivation(_this, &msg, SDL_FALSE); + break; + + case IDCMP_CLOSEWINDOW: + OS4_HandleClose(_this, &msg); + break; + + case IDCMP_INTUITICKS: + OS4_HandleTicks(_this, &msg); + break; + + case IDCMP_GADGETUP: + OS4_HandleGadget(_this, &msg); + break; + + default: + dprintf("Unknown event received class %d, code %d\n", msg.Class, msg.Code); + break; + } + } +} + +static void +OS4_HandleAppMessages(_THIS, struct MsgPort * msgPort) +{ + struct AppMessage *msg; + + while ((msg = (struct AppMessage *)IExec->GetMsg(msgPort))) { + switch (msg->am_Type) { + case AMTYPE_APPWINDOW: + OS4_HandleAppWindow(_this, msg); + break; + case AMTYPE_APPICON: + OS4_HandleAppIcon(_this, msg); + break; + default: + dprintf("Unknown AppMsg %d %p\n", msg->am_Type, (APTR)msg->am_UserData); + break; + } + + IExec->ReplyMsg((struct Message *) msg); + } +} + +void +OS4_PumpEvents(_THIS) +{ + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + + OS4_HandleIdcmpMessages(_this, data->userPort); + OS4_HandleAppMessages(_this, data->appMsgPort); +} + +#endif /* SDL_VIDEO_DRIVER_AMIGAOS4 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/amigaos4/SDL_os4events.h b/src/video/amigaos4/SDL_os4events.h new file mode 100644 index 0000000000000..96d194c11b6f8 --- /dev/null +++ b/src/video/amigaos4/SDL_os4events.h @@ -0,0 +1,30 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2020 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#ifndef _SDL_os4events_h +#define _SDL_os4events_h + +extern void OS4_PumpEvents(_THIS); + +#endif /* _SDL_os4events_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/amigaos4/SDL_os4framebuffer.c b/src/video/amigaos4/SDL_os4framebuffer.c new file mode 100644 index 0000000000000..cd04cd8078ac7 --- /dev/null +++ b/src/video/amigaos4/SDL_os4framebuffer.c @@ -0,0 +1,203 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2018 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_AMIGAOS4 + +#include "SDL_os4video.h" +#include "SDL_os4framebuffer.h" +#include "SDL_os4window.h" + +#define DEBUG +#include "../../main/amigaos4/SDL_os4debug.h" + +static Uint32 +OS4_PixfToSdlPixelFormat(PIX_FMT from) +{ + switch (from) { + // 32-bit + case PIXF_A8R8G8B8: return SDL_PIXELFORMAT_ARGB8888; + case PIXF_B8G8R8A8: return SDL_PIXELFORMAT_BGRA8888; + case PIXF_A8B8G8R8: return SDL_PIXELFORMAT_ABGR8888; + case PIXF_R8G8B8A8: return SDL_PIXELFORMAT_RGBA8888; + // 24-bit (WinUAE Picasso-IV may use one) + case PIXF_R8G8B8: return SDL_PIXELFORMAT_RGB888; + case PIXF_B8G8R8: return SDL_PIXELFORMAT_BGR888; + // 16-bit + case PIXF_R5G6B5: return SDL_PIXELFORMAT_RGB565; + // 8-bit + case PIXF_CLUT: return SDL_PIXELFORMAT_INDEX8; + // What else we have... + default: + dprintf("Unknown native pixel format %d\n", from); + return SDL_PIXELFORMAT_UNKNOWN; + } +} + +int +OS4_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int * pitch) +{ + SDL_WindowData *data = window->driverdata; + + if (data) { + APTR lock; + APTR base_address; + uint32 bytes_per_row; + uint32 depth; + PIX_FMT pixf; + + if (data->bitmap) { + dprintf("Freeing old bitmap %p\n", data->bitmap); + IGraphics->FreeBitMap(data->bitmap); + } + + if (!data->syswin) { + dprintf("No system window\n"); + return SDL_SetError("No system window"); + } + + pixf = IGraphics->GetBitMapAttr(data->syswin->RPort->BitMap, BMA_PIXELFORMAT); + depth = IGraphics->GetBitMapAttr(data->syswin->RPort->BitMap, BMA_BITSPERPIXEL); + + *format = OS4_PixfToSdlPixelFormat(pixf); + + dprintf("Native format %d, SDL format %d (%s)\n", pixf, *format, SDL_GetPixelFormatName(*format)); + dprintf("Allocating %d*%d*%d bitmap)\n", window->w, window->h, depth); + + data->bitmap = IGraphics->AllocBitMapTags( + window->w, + window->h, + depth, + BMATags_Clear, TRUE, + BMATags_UserPrivate, TRUE, + //BMATags_Friend, data->syswin->RPort->BitMap, + BMATags_PixelFormat, pixf, + TAG_DONE); + + if (!data->bitmap) { + dprintf("Failed to allocate bitmap\n"); + return SDL_SetError("Failed to allocate bitmap for framebuffer"); + } + + /* Lock the bitmap to get details. Since it's user private, + it should be safe to cache address and pitch. */ + lock = IGraphics->LockBitMapTags( + data->bitmap, + LBM_BaseAddress, &base_address, + LBM_BytesPerRow, &bytes_per_row, + TAG_DONE); + + if (lock) { + *pixels = base_address; + *pitch = bytes_per_row; + + IGraphics->UnlockBitMap(lock); + } else { + dprintf("Failed to lock bitmap\n"); + + IGraphics->FreeBitMap(data->bitmap); + data->bitmap = NULL; + + return SDL_SetError("Failed to lock framebuffer bitmap"); + } + } + + return 0; +} + +#ifndef MIN +# define MIN(x,y) ((x)<(y)?(x):(y)) +#endif + +int +OS4_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects) +{ + SDL_WindowData * data = window->driverdata; + int32 ret = -1; + + //dprintf("Called\n"); + + if (data && data->bitmap) { + if (data->syswin) { + + int i; + + struct Window *syswin = data->syswin; + + const struct IBox windowBox = { + syswin->BorderLeft, + syswin->BorderTop, + syswin->Width - syswin->BorderLeft - syswin->BorderRight, + syswin->Height - syswin->BorderTop - syswin->BorderBottom }; + + //dprintf("blit box %d*%d\n", windowBox.Width, windowBox.Height); + + ILayers->LockLayer(0, syswin->WLayer); + + for (i = 0; i < numrects; ++i) { + const SDL_Rect * r = &rects[i]; + + ret = IGraphics->BltBitMapTags( + BLITA_Source, data->bitmap, + //BLITA_SrcType, BLITT_BITMAP, + BLITA_Dest, syswin->RPort, + BLITA_DestType, BLITT_RASTPORT, + BLITA_SrcX, r->x, + BLITA_SrcY, r->y, + BLITA_DestX, r->x + windowBox.Left, + BLITA_DestY, r->y + windowBox.Top, + BLITA_Width, MIN(r->w, windowBox.Width), + BLITA_Height, MIN(r->h, windowBox.Height), + TAG_DONE); + + if (ret != -1) { + dprintf("BltBitMapTags() returned %d\n", ret); + } + } + + ILayers->UnlockLayer(syswin->WLayer); + } + } + + if (ret != -1) { + return SDL_SetError("BltBitMapTags failed"); + } + + return 0; +} + +void +OS4_DestroyWindowFramebuffer(_THIS, SDL_Window * window) +{ + SDL_WindowData *data = window->driverdata; + + if (data && data->bitmap) { + + dprintf("Freeing bitmap %p\n", data->bitmap); + + IGraphics->FreeBitMap(data->bitmap); + data->bitmap = NULL; + } +} + +#endif /* SDL_VIDEO_DRIVER_AMIGAOS4 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/amigaos4/SDL_os4framebuffer.h b/src/video/amigaos4/SDL_os4framebuffer.h new file mode 100644 index 0000000000000..91e6e6839b153 --- /dev/null +++ b/src/video/amigaos4/SDL_os4framebuffer.h @@ -0,0 +1,32 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2014 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#ifndef _SDL_os4framebuffer_h +#define _SDL_os4framebuffer_h + +extern int OS4_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch); +extern int OS4_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects); +extern void OS4_DestroyWindowFramebuffer(_THIS, SDL_Window * window); + +#endif /* _SDL_os4framebuffer_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/amigaos4/SDL_os4keyboard.c b/src/video/amigaos4/SDL_os4keyboard.c new file mode 100644 index 0000000000000..79d9f437e714e --- /dev/null +++ b/src/video/amigaos4/SDL_os4keyboard.c @@ -0,0 +1,164 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2018 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_AMIGAOS4 + +#include "SDL_os4video.h" +#include "SDL_os4keyboard.h" + +#include "../../events/SDL_keyboard_c.h" +#include "../../events/scancodes_amiga.h" + +#define DEBUG +#include "../../main/amigaos4/SDL_os4debug.h" + +static SDL_Keycode +OS4_MapRawKey(_THIS, int code) +{ + struct InputEvent ie; + int res; + char buffer[2] = {0, 0}; + + ie.ie_Class = IECLASS_RAWKEY; + ie.ie_SubClass = 0; + ie.ie_Code = code; + ie.ie_Qualifier = 0; + ie.ie_EventAddress = NULL; + + res = IKeymap->MapRawKey(&ie, buffer, sizeof(buffer), NULL); + if (res > 0) { + return (buffer[0] + buffer[1] * 256); + } else { + return 0; + } +} + +static void +OS4_UpdateKeymap(_THIS) +{ + int i; + SDL_Scancode scancode; + SDL_Keycode keymap[SDL_NUM_SCANCODES]; + + SDL_GetDefaultKeymap(keymap); + + for (i = 0; i < SDL_arraysize(amiga_scancode_table); i++) { + /* Make sure this scancode is a valid character scancode */ + scancode = amiga_scancode_table[i]; + if (scancode == SDL_SCANCODE_UNKNOWN ) { + continue; + } + + /* If this key is one of the non-mappable keys, ignore it */ + /* Don't allow the number keys right above the qwerty row to translate or the top left key (grave/backquote) */ + /* Not mapping numbers fixes the French layout, giving numeric keycodes for the number keys, which is the expected behavior */ + if ((keymap[scancode] & SDLK_SCANCODE_MASK) || + scancode == SDL_SCANCODE_GRAVE /*|| + (scancode >= SDL_SCANCODE_1 && scancode <= SDL_SCANCODE_0)*/ ) { + continue; + } + + keymap[scancode] = OS4_MapRawKey(_this, i); + } + + SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES); +} + +int +OS4_SetClipboardText(_THIS, const char *text) +{ + LONG result = ITextClip->WriteClipVector(text, SDL_strlen(text)); + + //dprintf("Result %s\n", result ? "OK" : "NOK"); + + return result ? 0 : -1; +} + +char * +OS4_GetClipboardText(_THIS) +{ + STRPTR from; + ULONG size; + char *to = NULL; + + LONG result = ITextClip->ReadClipVector(&from, &size); + + //dprintf("Read '%s' (%d bytes) from clipboard\n", from, size); + + if (result) { + + if (size) { + to = SDL_malloc( ++size ); + + if (to) { + SDL_strlcpy(to, from, size); + } else { + dprintf("Failed to allocate memory\n"); + } + } else { + to = SDL_strdup(""); + } + + ITextClip->DisposeClipVector(from); + } + + return to; +} + +SDL_bool +OS4_HasClipboardText(_THIS) +{ + /* This is silly but is there a better way to check? */ + char *to = OS4_GetClipboardText(_this); + + if (to) { + size_t len = SDL_strlen(to); + + SDL_free(to); + + if (len > 0) { + return SDL_TRUE; + } + } + + return SDL_FALSE; +} + +void +OS4_InitKeyboard(_THIS) +{ + OS4_UpdateKeymap(_this); + + //SDL_SetScancodeName(SDL_SCANCODE_APPLICATION, "Menu"); + SDL_SetScancodeName(SDL_SCANCODE_LGUI, "Left Amiga"); + SDL_SetScancodeName(SDL_SCANCODE_RGUI, "Right Amiga"); + SDL_SetScancodeName(SDL_SCANCODE_LCTRL, "Control"); +} + +void +OS4_QuitKeyboard(_THIS) +{ +} + +#endif /* SDL_VIDEO_DRIVER_AMIGAOS4 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/amigaos4/SDL_os4keyboard.h b/src/video/amigaos4/SDL_os4keyboard.h new file mode 100644 index 0000000000000..a7401f555d5e7 --- /dev/null +++ b/src/video/amigaos4/SDL_os4keyboard.h @@ -0,0 +1,35 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2014 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#ifndef _SDL_os4keyboard_h +#define _SDL_os4keyboard_h + +extern int OS4_SetClipboardText(_THIS, const char *text); +extern char * OS4_GetClipboardText(_THIS); +extern SDL_bool OS4_HasClipboardText(_THIS); + +extern void OS4_InitKeyboard(_THIS); +extern void OS4_QuitKeyboard(_THIS); + +#endif /* _SDL_os4keyboard_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/amigaos4/SDL_os4library.c b/src/video/amigaos4/SDL_os4library.c new file mode 100644 index 0000000000000..4d13f9d21b51f --- /dev/null +++ b/src/video/amigaos4/SDL_os4library.c @@ -0,0 +1,118 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2021 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_AMIGAOS4 + +#include "SDL_os4library.h" + +#define DEBUG +#include "../../main/amigaos4/SDL_os4debug.h" + +#include + +// These symbols are required when libSDL2.so is loaded manually using elf.library (RebelSDL). +struct ExecIFace* IExec; +struct Interface* INewlib; + +static struct Library* NewlibBase = NULL; + +static BOOL newlibOpened = FALSE; + +void _OS4_INIT(void) __attribute__((constructor)); +void _OS4_EXIT(void) __attribute__((destructor)); + +void _OS4_INIT(void) +{ + if (IExec) { + dprintf("IExec %p\n", IExec); + } else { + IExec = ((struct ExecIFace *)((*(struct ExecBase **)4)->MainInterface)); + } + + if (INewlib) { + dprintf("INewlib %p\n", INewlib); + } else { + NewlibBase = OS4_OpenLibrary("newlib.library", 53); + + if (NewlibBase) { + INewlib = OS4_GetInterface(NewlibBase); + newlibOpened = INewlib != NULL; + } + } + + dprintf("IExec %p, INewlib %p\n", IExec, INewlib); +} + +void _OS4_EXIT(void) +{ + if (newlibOpened && INewlib) { + OS4_DropInterface(&INewlib); + } + + if (NewlibBase) { + OS4_CloseLibrary(&NewlibBase); + } +} + +struct Library * +OS4_OpenLibrary(STRPTR name, ULONG version) +{ + struct Library* lib = IExec->OpenLibrary(name, version); + + dprintf("Opening '%s' version %u %s (address %p)\n", + name, version, lib ? "succeeded" : "FAILED", lib); + + return lib; +} + +struct Interface * +OS4_GetInterface(struct Library * lib) +{ + struct Interface* interface = IExec->GetInterface(lib, "main", 1, NULL); + + dprintf("Getting interface for libbase %p %s (address %p)\n", + lib, interface ? "succeeded" : "FAILED", interface); + + return interface; +} + +void +OS4_DropInterface(struct Interface ** interface) +{ + if (interface && *interface) { + dprintf("Dropping interface %p\n", *interface); + IExec->DropInterface(*interface); + *interface = NULL; + } +} + +void +OS4_CloseLibrary(struct Library ** library) +{ + if (library && *library) { + dprintf("Closing library %p\n", *library); + IExec->CloseLibrary(*library); + *library = NULL; + } +} + +#endif diff --git a/src/video/amigaos4/SDL_os4library.h b/src/video/amigaos4/SDL_os4library.h new file mode 100644 index 0000000000000..6d32a0637c908 --- /dev/null +++ b/src/video/amigaos4/SDL_os4library.h @@ -0,0 +1,38 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2017 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#ifndef _SDL_os4library_h +#define _SDL_os4library_h + +#include + +// A couple of helper functions for dealing with AmigaOS libraries + +extern struct Library * OS4_OpenLibrary(STRPTR name, ULONG version); + +extern struct Interface * OS4_GetInterface(struct Library * lib); + +extern void OS4_DropInterface(struct Interface ** interface); + +extern void OS4_CloseLibrary(struct Library ** library); + +#endif diff --git a/src/video/amigaos4/SDL_os4messagebox.c b/src/video/amigaos4/SDL_os4messagebox.c new file mode 100644 index 0000000000000..409bc6bf56eb9 --- /dev/null +++ b/src/video/amigaos4/SDL_os4messagebox.c @@ -0,0 +1,161 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2017 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_AMIGAOS4 + +#include + +#include "SDL_messagebox.h" +#include "SDL_os4messagebox.h" +#include "SDL_os4window.h" +#include "SDL_os4library.h" + +#define DEBUG +#include "../../main/amigaos4/SDL_os4debug.h" + +#define BUTTON_BUF_SIZE 1024 + +static struct Library *MB_IntuitionBase = NULL; +static struct IntuitionIFace *MB_IIntuition = NULL; + +/* Message box can be popped up without video initialization, +so let's fetch Intuition interface */ + +static BOOL +OS4_OpenIntuition() +{ + dprintf("Called\n"); + + MB_IntuitionBase = OS4_OpenLibrary("intuition.library", 51); + + if (MB_IntuitionBase) { + MB_IIntuition = (struct IntuitionIFace *) OS4_GetInterface(MB_IntuitionBase); + + if (MB_IIntuition) { + return TRUE; + } + } + + return FALSE; +} + +static void +OS4_CloseIntuition() +{ + dprintf("Called\n"); + + OS4_DropInterface((void *) &MB_IIntuition); + OS4_CloseLibrary(&MB_IntuitionBase); +} + +static char * +OS4_MakeButtonString(const SDL_MessageBoxData * messageboxdata) +{ + char *buttonBuffer = SDL_malloc(BUTTON_BUF_SIZE); + + if (buttonBuffer) { + int b; + + SDL_memset(buttonBuffer, 0, BUTTON_BUF_SIZE); + + /* Generate "Button 1|Button2... "*/ + for (b = 0; b < messageboxdata->numbuttons; b++) { + strncat(buttonBuffer, messageboxdata->buttons[b].text, BUTTON_BUF_SIZE - strlen(buttonBuffer) - 1); + + if (b != (messageboxdata->numbuttons - 1)) { + strncat(buttonBuffer, "|", BUTTON_BUF_SIZE - strlen(buttonBuffer) - 1); + } + } + + dprintf("String '%s'\n", buttonBuffer); + } + + return buttonBuffer; +} + +static struct Window * +OS4_GetWindow(const SDL_MessageBoxData * messageboxdata) +{ + struct Window * syswin = NULL; + + if (messageboxdata->window) { + SDL_WindowData *data = messageboxdata->window->driverdata; + syswin = data->syswin; + } + + return syswin; +} + +int +OS4_ShowMessageBox(const SDL_MessageBoxData * messageboxdata, int * buttonid) +{ + int result = -1; + + if (OS4_OpenIntuition()) { + + char *buttonString; + + if ((buttonString = OS4_MakeButtonString(messageboxdata))) { + + struct EasyStruct es = { + sizeof(struct EasyStruct), + 0, // Flags + messageboxdata->title, + messageboxdata->message, + buttonString, + NULL, // Screen + NULL // TagList + }; + + const int LAST_BUTTON = messageboxdata->numbuttons; + + /* Amiga button order is 1, 2, ..., N, 0! */ + int amigaButton = MB_IIntuition->EasyRequest(OS4_GetWindow(messageboxdata), &es, 0, NULL); + + dprintf("Button %d chosen\n", amigaButton); + + if (amigaButton >= 0 && amigaButton < LAST_BUTTON) { + if (amigaButton == 0) { + /* Last */ + *buttonid = messageboxdata->buttons[LAST_BUTTON - 1].buttonid; + } else { + *buttonid = messageboxdata->buttons[amigaButton - 1].buttonid; + } + + dprintf("Mapped button %d\n", *buttonid); + } + + SDL_free(buttonString); + result = 0; + } + } else { + dprintf("Failed to open IIntuition\n"); + } + + OS4_CloseIntuition(); + + return result; +} + +#endif /* SDL_VIDEO_DRIVER_AMIGAOS4 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/amigaos4/SDL_os4messagebox.h b/src/video/amigaos4/SDL_os4messagebox.h new file mode 100644 index 0000000000000..8275bffd61b16 --- /dev/null +++ b/src/video/amigaos4/SDL_os4messagebox.h @@ -0,0 +1,32 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2017 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#ifndef _SDL_os4messagebox_h +#define _SDL_os4messagebox_h + +struct SDL_MessageBoxData; + +extern int OS4_ShowMessageBox(const SDL_MessageBoxData * messageboxdata, int * buttonid); + +#endif /* _SDL_os4messagebox_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/amigaos4/SDL_os4modes.c b/src/video/amigaos4/SDL_os4modes.c new file mode 100644 index 0000000000000..293de5f698171 --- /dev/null +++ b/src/video/amigaos4/SDL_os4modes.c @@ -0,0 +1,309 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2021 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_AMIGAOS4 + +#include "SDL_os4video.h" +#include "SDL_os4modes.h" + +#define DEBUG +#include "../../main/amigaos4/SDL_os4debug.h" + +static SDL_bool +OS4_GetDisplayMode(_THIS, ULONG id, SDL_DisplayMode * mode) +{ + SDL_DisplayModeData *data; + APTR handle; + struct DimensionInfo diminfo; + struct DisplayInfo dispinfo; + + handle = IGraphics->FindDisplayInfo(id); + if (!handle) { + return SDL_FALSE; + } + + if (!IGraphics->GetDisplayInfoData(handle, (UBYTE *)&diminfo, sizeof(diminfo), DTAG_DIMS, 0)) { + dprintf("Failed to get dim info\n"); + return SDL_FALSE; + } + + if (!IGraphics->GetDisplayInfoData(handle, (UBYTE *)&dispinfo, sizeof(dispinfo), DTAG_DISP, 0)) { + dprintf("Failed to get disp info\n"); + return SDL_FALSE; + } + + data = (SDL_DisplayModeData *) SDL_malloc(sizeof(*data)); + if (!data) { + return SDL_FALSE; + } + + SDL_zero(*mode); + data->modeid = id; + data->x = diminfo.Nominal.MinX; + data->y = diminfo.Nominal.MinY; + mode->w = diminfo.Nominal.MaxX - diminfo.Nominal.MinX + 1; + mode->h = diminfo.Nominal.MaxY - diminfo.Nominal.MinY + 1; + mode->refresh_rate = 60; // grab DTAG_MNTR? + mode->format = SDL_PIXELFORMAT_UNKNOWN; + + // We are only interested in RTG modes + if (dispinfo.PropertyFlags & DIPF_IS_RTG) { + + dprintf("RTG mode %d: w=%d, h=%d, bits=%d\n", id, mode->w, mode->h, diminfo.MaxDepth); + + switch (diminfo.MaxDepth) { + case 32: + mode->format = SDL_PIXELFORMAT_ARGB8888; + break; + case 24: + mode->format = SDL_PIXELFORMAT_RGB888; + break; + case 16: + mode->format = SDL_PIXELFORMAT_RGB565; + break; + case 15: + mode->format = SDL_PIXELFORMAT_RGB555; + break; + case 8: + mode->format = SDL_PIXELFORMAT_INDEX8; + break; + } + } + + mode->driverdata = data; + + return SDL_TRUE; +} + +static SDL_bool +OS4_LockPubScreen(_THIS) +{ + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + + dprintf("Locking public screen\n"); + + data->publicScreen = IIntuition->LockPubScreen(NULL); + + if (data->publicScreen) { + dprintf("Public screen %p locked\n", data->publicScreen); + return SDL_TRUE; + } else { + dprintf("Failed to lock Workbench screen\n"); + return SDL_FALSE; + } +} + +static void +OS4_UnlockPubScreen(_THIS) +{ + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + + if (data->publicScreen) { + dprintf("Unlocking public screen %p\n", data->publicScreen); + + IIntuition->UnlockPubScreen(NULL, data->publicScreen); + data->publicScreen = NULL; + } +} + +int +OS4_InitModes(_THIS) +{ + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + SDL_VideoDisplay display; + SDL_DisplayMode current_mode; + SDL_DisplayData *displaydata; + ULONG modeid; + + dprintf("Called\n"); + + displaydata = (SDL_DisplayData *) SDL_malloc(sizeof(*displaydata)); + if (!displaydata) { + return SDL_OutOfMemory(); + } + + if (!OS4_LockPubScreen(_this)) { + SDL_free(displaydata); + return SDL_SetError("No displays available"); + } + + IIntuition->GetScreenAttrs(data->publicScreen, SA_DisplayID, &modeid, TAG_DONE); + if (!OS4_GetDisplayMode(_this, modeid, ¤t_mode)) { + dprintf("Failed to get display mode for %d\n", modeid); + SDL_free(displaydata); + return SDL_SetError("Couldn't get display mode\n"); + } + + /* OS4 has no multi-monitor support */ + SDL_zero(display); + display.desktop_mode = current_mode; + display.current_mode = current_mode; + display.driverdata = displaydata; + displaydata->screen = NULL; + + SDL_AddVideoDisplay(&display, SDL_FALSE); + + return 0; +} + +int +OS4_GetDisplayBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect) +{ + SDL_DisplayModeData *data = (SDL_DisplayModeData *) display->current_mode.driverdata; + + rect->x = data->x; + rect->y = data->y; + rect->w = display->current_mode.w; + rect->h = display->current_mode.h; + + dprintf("x=%d, y=%d, w=%d, h=%d\n", rect->x, rect->y, rect->w, rect->h); + + return 0; +} + +void +OS4_GetDisplayModes(_THIS, SDL_VideoDisplay * display) +{ + SDL_DisplayMode mode; + ULONG id = INVALID_ID; + + dprintf("Called\n"); + + while ((id = IGraphics->NextDisplayInfo(id)) != INVALID_ID) { + + if (OS4_GetDisplayMode(_this, id, &mode)) { + if (mode.format != SDL_PIXELFORMAT_UNKNOWN) { + if (!SDL_AddDisplayMode(display, &mode)) { + SDL_free(mode.driverdata); + } + } else { + SDL_free(mode.driverdata); + } + } else { + dprintf("Failed to get display mode for %d\n", id); + } + } +} + +void +OS4_CloseScreen(_THIS, struct Screen * screen) +{ + if (screen) { + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + + if (screen != data->publicScreen) { + dprintf("Closing screen %p\n", screen); + + if (IIntuition->CloseScreen(screen) == FALSE) { + dprintf("Screen has open window(s), cannot close\n"); + } else { + dprintf("Screen closed successfully\n"); + } + } else { + dprintf("Public screen, not closing\n"); + } + + } else { + dprintf("NULL pointer\n"); + } +} + +int +OS4_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) +{ + SDL_VideoData *driverdata = (SDL_VideoData *) _this->driverdata; + SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata; + SDL_DisplayModeData *data = (SDL_DisplayModeData *) mode->driverdata; + ULONG openError = 0; + int bpp = SDL_BITSPERPIXEL(mode->format); + + if (SDL_memcmp(mode, &display->desktop_mode, sizeof(SDL_DisplayMode)) == 0) { + // Don't create another "Workbench" + dprintf("Desktop mode passed\n"); + + //TODO: should we check the current display ID and reopen the screen when needed? + return 0; + } + + displaydata->screen = IIntuition->OpenScreenTags(NULL, + SA_Width, mode->w, + SA_Height, mode->h, + SA_Depth, bpp, + SA_DisplayID, data->modeid, + SA_Quiet, TRUE, + SA_Title, driverdata->appName, + SA_ShowTitle, FALSE, + SA_ErrorCode, &openError, + SA_LikeWorkbench, TRUE, + SA_Compositing, FALSE, + TAG_DONE); + + dprintf("Opened screen id %d: %d*%d*%d (address %p)\n", + data->modeid, mode->w, mode->h, bpp, displaydata->screen); + + if (!displaydata->screen) { + switch (openError) { + case OSERR_NOMONITOR: + SDL_SetError("Monitor for display mode not available"); + break; + case OSERR_NOCHIPS: + SDL_SetError("Newer custom chips required"); + break; + case OSERR_NOMEM: + case OSERR_NOCHIPMEM: + SDL_OutOfMemory(); + break; + case OSERR_PUBNOTUNIQUE: + SDL_SetError("Public screen name not unique"); + break; + case OSERR_UNKNOWNMODE: + case OSERR_TOODEEP: + SDL_SetError("Unknown display mode"); + break; + case OSERR_ATTACHFAIL: + SDL_SetError("Attachment failed"); + break; + default: + SDL_SetError("OpenScreen failed"); + break; + } + return -1; + } + + // Paint it black (it helps in cases where window doesn't fill the screen) + // ...do we need a backfill hook? + IGraphics->RectFillColor(&displaydata->screen->RastPort, 0, 0, mode->w - 1, mode->h - 1, 0xFF000000); + + return 0; +} + +void +OS4_QuitModes(_THIS) +{ + dprintf("Called\n"); + + OS4_UnlockPubScreen(_this); +} + +#endif /* SDL_VIDEO_DRIVER_AMIGAOS4 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/amigaos4/SDL_os4modes.h b/src/video/amigaos4/SDL_os4modes.h new file mode 100644 index 0000000000000..07547abefc0dd --- /dev/null +++ b/src/video/amigaos4/SDL_os4modes.h @@ -0,0 +1,48 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2018 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#ifndef _SDL_os4modes_h +#define _SDL_os4modes_h + +typedef struct +{ + struct Screen * screen; +} SDL_DisplayData; + +typedef struct +{ + ULONG modeid; + LONG x; + LONG y; +} SDL_DisplayModeData; + +extern int OS4_InitModes(_THIS); +extern int OS4_GetDisplayBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect); +extern void OS4_GetDisplayModes(_THIS, SDL_VideoDisplay * display); +extern int OS4_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode); +extern void OS4_QuitModes(_THIS); + +extern void OS4_CloseScreen(_THIS, struct Screen *screen); + +#endif /* _SDL_os4modes_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/amigaos4/SDL_os4mouse.c b/src/video/amigaos4/SDL_os4mouse.c new file mode 100644 index 0000000000000..691f13b5bae66 --- /dev/null +++ b/src/video/amigaos4/SDL_os4mouse.c @@ -0,0 +1,550 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_AMIGAOS4 + +#include + +#include "SDL_os4mouse.h" +#include "SDL_os4video.h" +#include "SDL_os4window.h" + +#include "SDL_hints.h" +#include "../../events/SDL_mouse_c.h" + +#define DEBUG +#include "../../main/amigaos4/SDL_os4debug.h" + +#include + +static SDL_Cursor *hidden; + +typedef struct SDL_CursorData { + int hot_x; + int hot_y; + ULONG type; + Object *object; + Uint32 *imageData; +} SDL_CursorData; + +static UWORD fallbackPointerData[2 * 16] = { 0 }; + +static struct BitMap fallbackPointerBitMap = { 2, 16, 0, 2, 0, + { (PLANEPTR)fallbackPointerData, (PLANEPTR)(fallbackPointerData + 16) } }; + + +OS4_GlobalMouseState globalMouseState; + +static Uint32 +OS4_GetDoubleClickTimeInMillis(_THIS) +{ + struct Preferences preferences; + Uint32 interval; + + IIntuition->GetPrefs(&preferences, sizeof(preferences)); + + interval = preferences.DoubleClick.Seconds * 1000 + + preferences.DoubleClick.Microseconds / 1000; + + dprintf("Doubleclick time %d ms\n", interval); + + return interval; +} + +static SDL_Cursor* +OS4_CreateCursorInternal() +{ + SDL_Cursor *cursor = SDL_calloc(1, sizeof(SDL_Cursor)); + + //dprintf("Called\n"); + + if (cursor) { + + SDL_CursorData *data = SDL_calloc(1, sizeof(SDL_CursorData)); + + if (data) { + cursor->driverdata = data; + } else { + dprintf("Failed to create cursor data\n"); + } + + } else { + dprintf("Failed to create cursor\n"); + } + + return cursor; + +} + +static SDL_Cursor* +OS4_CreateDefaultCursor() +{ + SDL_Cursor *cursor = OS4_CreateCursorInternal(); + + dprintf("%p\n", cursor); + + if (cursor && cursor->driverdata) { + SDL_CursorData *data = cursor->driverdata; + + data->type = POINTERTYPE_NORMAL; + } + + return cursor; +} + +static Uint32* +OS4_CopyImageData(SDL_Surface * surface) +{ + const size_t bytesPerRow = surface->w * sizeof(Uint32); + Uint32* buffer = SDL_malloc(bytesPerRow * surface->h); + + dprintf("Copying cursor data %d*%d from surface %p to buffer %p\n", + surface->w, surface->h, surface, buffer); + + if (buffer) { + + if (SDL_MUSTLOCK(surface)) { + SDL_LockSurface(surface); + } + + Uint8* source = surface->pixels; + Uint32* destination = buffer; + int y; + + for (y = 0; y < surface->h; y++) { + SDL_memcpy(destination, source, bytesPerRow); + destination += surface->w; + source += surface->pitch; + } + + if (SDL_MUSTLOCK(surface)) { + SDL_UnlockSurface(surface); + } + } else { + dprintf("Failed to allocate memory\n"); + } + + return buffer; +} + +static SDL_Cursor* +OS4_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) +{ + SDL_Cursor *cursor = OS4_CreateCursorInternal(); + + dprintf("Surface %p, cursor %p, hot_x %d, hot_y %d\n", surface, cursor, hot_x, hot_y); + + if (cursor && cursor->driverdata) { + + if (surface->w > 64) { + dprintf("Invalid width %d\n", surface->w); + } else if (surface->h > 64) { + dprintf("Invalid height %d\n", surface->h); + } else { + _THIS = SDL_GetVideoDevice(); + + Uint32* buffer = OS4_CopyImageData(surface); + + /* We need to pass some compatibility parameters + even though we are going to use just ARGB pointer */ + + Object *object = IIntuition->NewObject( + NULL, + POINTERCLASS, + POINTERA_BitMap, &fallbackPointerBitMap, + POINTERA_XOffset, hot_x, + POINTERA_YOffset, hot_y, + POINTERA_WordWidth, 1, + POINTERA_XResolution, POINTERXRESN_SCREENRES, + POINTERA_YResolution, POINTERYRESN_SCREENRES, + POINTERA_ImageData, buffer, + POINTERA_Width, surface->w, + POINTERA_Height, surface->h, + TAG_DONE); + + if (object) { + SDL_CursorData *data = cursor->driverdata; + data->object = object; + data->imageData = buffer; + } else { + dprintf("Failed to create pointer object\n"); + } + } + } + + return cursor; +} + +static SDL_Cursor* +OS4_CreateHiddenCursor() +{ + dprintf("Called\n"); + + /* Create invisible 1*1 cursor because system version (POINTERTYPE_NONE) has a shadow */ + + SDL_Cursor *cursor = NULL; + SDL_Surface *surface = SDL_CreateRGBSurface(0, 1, 1, 32, + 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF); + + if (surface) { + SDL_FillRect(surface, NULL, 0x0); + + cursor = OS4_CreateCursor(surface, 0, 0); + + SDL_FreeSurface(surface); + } + + return cursor; +} + + +static ULONG +OS4_MapCursorIdToNative(SDL_SystemCursor id) +{ + switch (id) { + case SDL_SYSTEM_CURSOR_ARROW: return POINTERTYPE_NORMAL; + //case SDL_SYSTEM_CURSOR_IBEAM: return POINTERTYPE_SELECT; 54.21 + case SDL_SYSTEM_CURSOR_WAITARROW: + case SDL_SYSTEM_CURSOR_WAIT: return POINTERTYPE_BUSY; + case SDL_SYSTEM_CURSOR_CROSSHAIR: return POINTERTYPE_CROSS; + case SDL_SYSTEM_CURSOR_SIZENWSE: return POINTERTYPE_NORTHWESTSOUTHEASTRESIZE; + case SDL_SYSTEM_CURSOR_SIZENESW: return POINTERTYPE_NORTHEASTSOUTHWESTRESIZE; + case SDL_SYSTEM_CURSOR_SIZEWE: return POINTERTYPE_EASTWESTRESIZE; + case SDL_SYSTEM_CURSOR_SIZENS: return POINTERTYPE_NORTHSOUTHRESIZE; + case SDL_SYSTEM_CURSOR_NO: return POINTERTYPE_NOTALLOWED; + case SDL_SYSTEM_CURSOR_HAND: return POINTERTYPE_HAND; + // + case SDL_SYSTEM_CURSOR_SIZEALL: + default: + dprintf("Unknown mapping from type %d\n", id); + return POINTERTYPE_NORMAL; + } +} + +static SDL_Cursor* +OS4_CreateSystemCursor(SDL_SystemCursor id) +{ + SDL_Cursor *cursor = OS4_CreateCursorInternal(); + + //dprintf("Called %d\n", id); + + if (cursor && cursor->driverdata) { + SDL_CursorData *data = cursor->driverdata; + + data->type = OS4_MapCursorIdToNative(id); + } + + return cursor; +} + +static void +OS4_SetPointerForEachWindow(ULONG type, Object * object) +{ + SDL_Window *sdlwin; + + _THIS = SDL_GetVideoDevice(); + + for (sdlwin = _this->windows; sdlwin; sdlwin = sdlwin->next) { + + SDL_WindowData *data = sdlwin->driverdata; + + if (data->syswin) { + + if (object || type) { + dprintf("Setting pointer object %p (type %d) for window %p\n", object, type, data->syswin); + } + + if (object) { + IIntuition->SetWindowPointer( + data->syswin, + WA_Pointer, object, + TAG_DONE); + } else { + IIntuition->SetWindowPointer( + data->syswin, + WA_PointerType, type, + TAG_DONE); + } + } + } +} + +static int +OS4_ShowCursor(SDL_Cursor * cursor) +{ + ULONG type = POINTERTYPE_NORMAL; + Object *object = NULL; + + if (cursor) { + SDL_CursorData *data = cursor->driverdata; + + //dprintf("Called %p %p\n", cursor, data); + + if (data) { + type = data->type; + object = data->object; + } else { + dprintf("No cursor data\n"); + return -1; + } + } else { + dprintf("Hiding cursor\n"); + + type = POINTERTYPE_NONE; + + if (hidden) { + SDL_CursorData *data = hidden->driverdata; + + if (data) { + object = data->object; + } + } + } + + OS4_SetPointerForEachWindow(type, object); + + return 0; +} + +static void +OS4_FreeCursor(SDL_Cursor * cursor) +{ + SDL_CursorData *data = cursor->driverdata; + + dprintf("Called %p\n", cursor); + + if (data) { + if (data->object) { + _THIS = SDL_GetVideoDevice(); + SDL_Mouse *mouse = SDL_GetMouse(); + + if (mouse->cur_cursor == cursor) { + dprintf("Reset to POINTERTYPE_NONE before object disposal\n"); + OS4_SetPointerForEachWindow(POINTERTYPE_NONE, NULL); + } + + IIntuition->DisposeObject(data->object); + data->object = NULL; + } + + if (data->imageData) { + SDL_free(data->imageData); + data->imageData = NULL; + } + + SDL_free(data); + cursor->driverdata = NULL; + } +} + +void +OS4_RefreshCursorState(void) +{ + SDL_Mouse *mouse = SDL_GetMouse(); + if (mouse) { + dprintf("Mouse shown %d\n", mouse->cursor_shown); + // Force cursor redraw + SDL_SetCursor(NULL); + } +} + +static int +OS4_WarpMouseInternal(struct Screen *screen, int x, int y) +{ + SDL_VideoDevice *device = SDL_GetVideoDevice(); + SDL_VideoData *videoData = device->driverdata; + int result = -1; + + if (videoData->inputReq != NULL) { + struct InputEvent *fakeEvent; + + /* We move the Workbench pointer by stuffing mouse + * movement events in input.device's queue. + * + * This in turn will cause mouse movement events to be + * sent back to us + */ + + fakeEvent = (struct InputEvent *)OS4_SaveAllocPooled( + device, sizeof(struct InputEvent) + sizeof(struct IEPointerPixel)); + + if (fakeEvent) { + struct IEPointerPixel *neoPix = (struct IEPointerPixel *) (fakeEvent + 1); + + neoPix->iepp_Screen = screen ? screen : videoData->publicScreen; + neoPix->iepp_Position.Y = y; + neoPix->iepp_Position.X = x; + + fakeEvent->ie_EventAddress = (APTR)neoPix; + fakeEvent->ie_NextEvent = NULL; + fakeEvent->ie_Class = IECLASS_NEWPOINTERPOS; + fakeEvent->ie_SubClass = IESUBCLASS_PIXEL; + fakeEvent->ie_Code = IECODE_NOBUTTON; + fakeEvent->ie_Qualifier = 0; + + videoData->inputReq->io_Data = (APTR)fakeEvent; + videoData->inputReq->io_Length = sizeof(struct InputEvent); + videoData->inputReq->io_Command = IND_WRITEEVENT; + + dprintf("Sending input event\n"); + + IExec->DoIO((struct IORequest *)videoData->inputReq); + + OS4_SaveFreePooled(device, (void *)fakeEvent, + sizeof(struct InputEvent) + sizeof(struct IEPointerPixel)); + + result = 0; + } + } + + return result; +} + +static int +OS4_WarpMouseGlobal(int x, int y) +{ + dprintf("Warping mouse to %d, %d\n", x, y); + + return OS4_WarpMouseInternal(NULL, x, y); +} + +static void +OS4_WarpMouse(SDL_Window * window, int x, int y) +{ + SDL_WindowData *winData = window->driverdata; + struct Window *syswin = winData->syswin; + + BOOL warpHostPointer; + + dprintf("Warping mouse to %d, %d\n", x, y); + + /* If the host mouse pointer is outside of the SDL window or the SDL + * window is inactive then we just need to warp SDL's notion of where + * the pointer position is - we don't need to move the Workbench + * pointer. In the former case, we don't pass mass movements on to + * to the app anyway and in the latter case we don't receive mouse + * movements events anyway. + */ + //warpHostPointer = (hidden->pointerState == pointer_inside_window) && !hidden->isMouseRelative + // && hidden->windowActive; + + // TODO: "inside window" logic needed/wanted? + warpHostPointer = !SDL_GetRelativeMouseMode() && (window == SDL_GetMouseFocus()); + + if (warpHostPointer) { + + struct Screen *screen = (window->flags & SDL_WINDOW_FULLSCREEN) ? + syswin->WScreen : NULL; + + OS4_WarpMouseInternal(screen, + x + syswin->BorderLeft + syswin->LeftEdge, + y + syswin->BorderTop + syswin->TopEdge); + + } else { + /* Just warp SDL's notion of the pointer position */ + SDL_SendMouseMotion(window, 0, SDL_GetRelativeMouseMode(), x, y); + } +} + +static int +OS4_SetRelativeMouseMode(SDL_bool enabled) +{ + return 0; +} + +static Uint32 +OS4_GetGlobalMouseState(int * x, int * y) +{ + uint32 buttons = 0; + + if (x) { + *x = globalMouseState.x; + } + + if (y) { + *y = globalMouseState.y; + } + + //dprintf("%d, %d\n", *x, *y); + + if (globalMouseState.buttonPressed[SDL_BUTTON_LEFT]) { + buttons |= SDL_BUTTON_LMASK; + } + + if (globalMouseState.buttonPressed[SDL_BUTTON_MIDDLE]) { + buttons |= SDL_BUTTON_MMASK; + } + + if (globalMouseState.buttonPressed[SDL_BUTTON_RIGHT]) { + buttons |= SDL_BUTTON_RMASK; + } + + return buttons; +} + +void +OS4_InitMouse(_THIS) +{ + //SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + + SDL_Mouse *mouse = SDL_GetMouse(); + char buffer[16]; + + mouse->CreateCursor = OS4_CreateCursor; + mouse->CreateSystemCursor = OS4_CreateSystemCursor; + mouse->ShowCursor = OS4_ShowCursor; + mouse->FreeCursor = OS4_FreeCursor; + mouse->WarpMouse = OS4_WarpMouse; + mouse->WarpMouseGlobal = OS4_WarpMouseGlobal; + mouse->SetRelativeMouseMode = OS4_SetRelativeMouseMode; + //mouse->CaptureMouse = OS4_CaptureMouse; + mouse->GetGlobalMouseState = OS4_GetGlobalMouseState; + + SDL_SetDefaultCursor( OS4_CreateDefaultCursor() ); + + hidden = OS4_CreateHiddenCursor(); + + SDL_SetHint(SDL_HINT_MOUSE_DOUBLE_CLICK_TIME, + SDL_uitoa(OS4_GetDoubleClickTimeInMillis(_this), buffer, 10)); +} + +void +OS4_QuitMouse(_THIS) +{ + SDL_Mouse *mouse = SDL_GetMouse(); + + if (mouse->def_cursor) { + OS4_FreeCursor(mouse->def_cursor); + mouse->def_cursor = NULL; + } + + if (hidden) { + OS4_FreeCursor(hidden); + hidden = NULL; + } + + mouse->cur_cursor = NULL; +} + +#endif /* SDL_VIDEO_DRIVER_AMIGAOS4 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/amigaos4/SDL_os4mouse.h b/src/video/amigaos4/SDL_os4mouse.h new file mode 100644 index 0000000000000..882cefff92593 --- /dev/null +++ b/src/video/amigaos4/SDL_os4mouse.h @@ -0,0 +1,42 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2017 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" +#include "SDL_os4video.h" +#include "SDL_mouse.h" + +#ifndef _SDL_os4mouse_h +#define _SDL_os4mouse_h + +typedef struct OS4_GlobalMouseState +{ + int x; + int y; + int buttonPressed[SDL_BUTTON_RIGHT+1]; +} OS4_GlobalMouseState; + +extern void OS4_RefreshCursorState(void); + +extern void OS4_InitMouse(_THIS); +extern void OS4_QuitMouse(_THIS); + +#endif /* _SDL_os4mouse_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/amigaos4/SDL_os4opengl.c b/src/video/amigaos4/SDL_os4opengl.c new file mode 100644 index 0000000000000..13b96b2bfd88f --- /dev/null +++ b/src/video/amigaos4/SDL_os4opengl.c @@ -0,0 +1,464 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2021 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_AMIGAOS4 + +#include "SDL_os4video.h" +#include "SDL_os4window.h" +#include "SDL_os4library.h" +#include "SDL_os4opengl.h" + +#include + +#include +//#include + +#define DEBUG +#include "../../main/amigaos4/SDL_os4debug.h" + +struct Library *MiniGLBase; +struct MiniGLIFace *IMiniGL; + +/* The client program needs access to this context pointer + * to be able to make GL calls. This presents no problems when + * it is statically linked against libSDL, but when linked + * against a shared library version this will require some + * trickery. + */ +DECLSPEC struct GLContextIFace *mini_CurrentContext = 0; + +void *AmiGetGLProc(const char *proc); + +static void +OS4_GL_LogLibraryError() +{ + dprintf("No MiniGL library available\n"); + SDL_SetError("No MiniGL library available"); +} + +int +OS4_GL_LoadLibrary(_THIS, const char * path) +{ + dprintf("Called %d\n", _this->gl_config.driver_loaded); + + if (!MiniGLBase) { + MiniGLBase = OS4_OpenLibrary("minigl.library", 2); + + if (!MiniGLBase) { + dprintf("Failed to open minigl.library\n"); + SDL_SetError("Failed to open minigl.library"); + return -1; + } + } + + if (!IMiniGL) { + IMiniGL = (struct MiniGLIFace *) OS4_GetInterface(MiniGLBase); + + if (!IMiniGL) { + dprintf("Failed to open MiniGL interace\n"); + SDL_SetError("Failed to open MiniGL interface"); + return -1; + } + + dprintf("MiniGL library opened\n"); + } + + return 0; +} + +void * +OS4_GL_GetProcAddress(_THIS, const char * proc) +{ + void *func = NULL; + + dprintf("Called for '%s' (current context %p)\n", proc, mini_CurrentContext); + + if (IMiniGL && mini_CurrentContext) { + func = AmiGetGLProc(proc); + } + + if (func == NULL) { + dprintf("Failed to load '%s'\n", proc); + } + + return func; +} + +void +OS4_GL_UnloadLibrary(_THIS) +{ + dprintf("Called %d\n", _this->gl_config.driver_loaded); + + OS4_DropInterface((void *) &IMiniGL); + OS4_CloseLibrary(&MiniGLBase); +} + +SDL_bool +OS4_GL_AllocateBuffers(_THIS, int width, int height, int depth, SDL_WindowData * data) +{ + dprintf("Allocate double buffer bitmaps %d*%d*%d\n", width, height, depth); + + if (data->glFrontBuffer || data->glBackBuffer) { + dprintf("Old front buffer pointer %p, back buffer pointer %p\n", + data->glFrontBuffer, data->glBackBuffer); + + OS4_GL_FreeBuffers(_this, data); + } + + if (!(data->glFrontBuffer = IGraphics->AllocBitMapTags( + width, + height, + depth, + BMATags_Displayable, TRUE, + BMATags_Friend, data->syswin->RPort->BitMap, + TAG_DONE))) { + + dprintf("Failed to allocate front buffer\n"); + return SDL_FALSE; + } + + if (!(data->glBackBuffer = IGraphics->AllocBitMapTags( + width, + height, + depth, + BMATags_Displayable, TRUE, + BMATags_Friend, data->syswin->RPort->BitMap, + TAG_DONE))) { + + dprintf("Failed to allocate back buffer\n"); + + IGraphics->FreeBitMap(data->glFrontBuffer); + data->glFrontBuffer = NULL; + + return SDL_FALSE; + } + + uint32 srcFmt = IGraphics->GetBitMapAttr(data->glBackBuffer, BMA_PIXELFORMAT); + uint32 src2Fmt = IGraphics->GetBitMapAttr(data->glFrontBuffer, BMA_PIXELFORMAT); + uint32 dstFmt = IGraphics->GetBitMapAttr(data->syswin->RPort->BitMap, BMA_PIXELFORMAT); + + dprintf("SRC FMT %u, SRC2 FMT %u, DST FMT %u\n", srcFmt, src2Fmt, dstFmt); + + return SDL_TRUE; +} + +void +OS4_GL_FreeBuffers(_THIS, SDL_WindowData * data) +{ + dprintf("Called\n"); + + if (data->glFrontBuffer) { + IGraphics->FreeBitMap(data->glFrontBuffer); + data->glFrontBuffer = NULL; + } + + if (data->glBackBuffer) { + IGraphics->FreeBitMap(data->glBackBuffer); + data->glBackBuffer = NULL; + } +} + +SDL_GLContext +OS4_GL_CreateContext(_THIS, SDL_Window * window) +{ + dprintf("Called\n"); + + if (IMiniGL) { + + int width, height; + uint32 depth; + + SDL_WindowData * data = window->driverdata; + + OS4_GetWindowActiveSize(window, &width, &height); + + if (data->glContext) { + struct GLContextIFace *IGL = (struct GLContextIFace *)data->glContext; + + dprintf("Old context %p found, deleting\n", data->glContext); + + IGL->DeleteContext(); + + data->glContext = NULL; + } + + depth = IGraphics->GetBitMapAttr(data->syswin->RPort->BitMap, BMA_BITSPERPIXEL); + + if (!OS4_GL_AllocateBuffers(_this, width, height, depth, data)) { + SDL_SetError("Failed to allocate MiniGL buffers"); + return NULL; + } + + data->glContext = IMiniGL->CreateContextTags( + MGLCC_PrivateBuffers, 2, + MGLCC_FrontBuffer, data->glFrontBuffer, + MGLCC_BackBuffer, data->glBackBuffer, + MGLCC_Buffers, 2, + MGLCC_PixelDepth, depth, + MGLCC_StencilBuffer, TRUE, + MGLCC_VertexBufferSize, 1 << 17, + TAG_DONE); + + if (data->glContext) { + + dprintf("MiniGL context %p created for window '%s'\n", + data->glContext, window->title); + + ((struct GLContextIFace *)data->glContext)->GLViewport(0, 0, width, height); + mglMakeCurrent(data->glContext); + mglLockMode(MGL_LOCK_SMART); + + return data->glContext; + + } else { + dprintf("Failed to create MiniGL context for window '%s'\n", window->title); + + SDL_SetError("Failed to create MiniGL context"); + + OS4_GL_FreeBuffers(_this, data); + + return NULL; + } + + } else { + OS4_GL_LogLibraryError(); + return NULL; + } +} + +int +OS4_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) +{ + int result = -1; + + if (!window || !context) { + dprintf("Called (window %p, context %p)\n", window, context); + } + + if (IMiniGL) { + mglMakeCurrent(context); + result = 0; + } else { + OS4_GL_LogLibraryError(); + } + + return result; +} + +void +OS4_GL_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h) +{ + OS4_WaitForResize(_this, window, w, h); +} + +int +OS4_GL_SetSwapInterval(_THIS, int interval) +{ + SDL_VideoData *data = _this->driverdata; + + switch (interval) { + case 0: + case 1: + data->vsyncEnabled = interval ? TRUE : FALSE; + dprintf("VSYNC %d\n", interval); + return 0; + default: + dprintf("Unsupported interval %d\n", interval); + return -1; + } +} + +int +OS4_GL_GetSwapInterval(_THIS) +{ + //dprintf("Called\n"); + + SDL_VideoData *data = _this->driverdata; + + return data->vsyncEnabled ? 1 : 0; +} + +int +OS4_GL_SwapWindow(_THIS, SDL_Window * window) +{ + //dprintf("Called\n"); + + if (IMiniGL) { + + SDL_WindowData *data = window->driverdata; + + if (data->glContext) { + SDL_VideoData *videodata = _this->driverdata; + + struct BitMap *temp; + int w, h; + GLint buf; + + int32 blitRet; + + mglUnlockDisplay(); + + ((struct GLContextIFace *)data->glContext)->MGLWaitGL(); // TODO: still needed? + + OS4_GetWindowSize(_this, data->syswin, &w, &h); + + if (videodata->vsyncEnabled) { + IGraphics->WaitTOF(); + } + + glGetIntegerv(GL_DRAW_BUFFER, &buf); + + if (buf == GL_BACK || buf == GL_FRONT) { + struct BitMap *from = (buf == GL_BACK) ? data->glBackBuffer : data->glFrontBuffer; + + BOOL ret = IGraphics->BltBitMapRastPort(from, 0, 0, data->syswin->RPort, + data->syswin->BorderLeft, data->syswin->BorderTop, w, h, 0xC0); + + if (!ret) { + dprintf("BltBitMapRastPort() failed\n"); + } + } + + blitRet = IGraphics->BltBitMapTags(BLITA_Source, data->glBackBuffer, + BLITA_SrcType, BLITT_BITMAP, + BLITA_SrcX, 0, + BLITA_SrcY, 0, + BLITA_Dest, data->glFrontBuffer, + BLITA_DestType,BLITT_BITMAP, + BLITA_DestX, 0, + BLITA_DestY, 0, + BLITA_Width, w, + BLITA_Height, h, + BLITA_Minterm, 0xC0, + TAG_DONE); + + if (blitRet == -1) { + temp = data->glFrontBuffer; + data->glFrontBuffer = data->glBackBuffer; + data->glBackBuffer = temp; + + ((struct GLContextIFace *)data->glContext)->MGLUpdateContextTags( + MGLCC_FrontBuffer,data->glFrontBuffer, + MGLCC_BackBuffer, data->glBackBuffer, + TAG_DONE); + return 0; + } else { + dprintf("BltBitMapTags() returned %d\n", blitRet); + return -1; + } + } else { + dprintf("No MiniGL context\n"); + } + } else { + OS4_GL_LogLibraryError(); + } + + return -1; +} + +void +OS4_GL_DeleteContext(_THIS, SDL_GLContext context) +{ + dprintf("Called with context=%p\n", context); + + if (IMiniGL) { + + if (context) { + SDL_Window *sdlwin; + Uint32 deletions = 0; + + for (sdlwin = _this->windows; sdlwin; sdlwin = sdlwin->next) { + + SDL_WindowData *data = sdlwin->driverdata; + + if (data->glContext == context) { + struct GLContextIFace *IGL = context; + + dprintf("Found MiniGL context, clearing window binding\n"); + + IGL->DeleteContext(); + + data->glContext = NULL; + deletions++; + } + } + + if (deletions == 0) { + dprintf("MiniGL context doesn't seem to have window binding\n"); + } + } else { + dprintf("No context to delete\n"); + } + } else { + OS4_GL_LogLibraryError(); + } +} + +SDL_bool +OS4_GL_ResizeContext(_THIS, SDL_Window * window) +{ + if (IMiniGL) { + SDL_WindowData *data = window->driverdata; + + if (data) { + int width, height; + + uint32 depth = IGraphics->GetBitMapAttr(data->syswin->RPort->BitMap, BMA_BITSPERPIXEL); + + OS4_GetWindowActiveSize(window, &width, &height); + + if (OS4_GL_AllocateBuffers(_this, width, height, depth, data)) { + + dprintf("Resizing MiniGL context to %d*%d\n", width, height); + + ((struct GLContextIFace *)data->glContext)->MGLUpdateContextTags( + MGLCC_FrontBuffer, data->glFrontBuffer, + MGLCC_BackBuffer, data->glBackBuffer, + TAG_DONE); + + ((struct GLContextIFace *)data->glContext)->GLViewport(0, 0, width, height); + + return SDL_TRUE; + + } else { + dprintf("Failed to re-allocate MiniGL buffers\n"); + //SDL_Quit(); + } + } else { + dprintf("Window data NULL\n"); + } + } else { + OS4_GL_LogLibraryError(); + } + + return SDL_FALSE; +} + +void +OS4_GL_UpdateWindowPointer(_THIS, SDL_Window * window) +{ + // Nothing to do for MiniGL +} + +#endif /* SDL_VIDEO_DRIVER_AMIGAOS4 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/amigaos4/SDL_os4opengl.h b/src/video/amigaos4/SDL_os4opengl.h new file mode 100644 index 0000000000000..dae6a8e321821 --- /dev/null +++ b/src/video/amigaos4/SDL_os4opengl.h @@ -0,0 +1,47 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#ifndef _SDL_os4opengl_h +#define _SDL_os4opengl_h + +#include "SDL_os4window.h" + +extern int OS4_GL_LoadLibrary(_THIS, const char *path); +extern void *OS4_GL_GetProcAddress(_THIS, const char *proc); +extern void OS4_GL_UnloadLibrary(_THIS); +extern SDL_GLContext OS4_GL_CreateContext(_THIS, SDL_Window * window); +extern int OS4_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context); +extern void OS4_GL_GetDrawableSize(_THIS, SDL_Window * window, int *w, int *h); +extern int OS4_GL_SetSwapInterval(_THIS, int interval); +extern int OS4_GL_GetSwapInterval(_THIS); +extern int OS4_GL_SwapWindow(_THIS, SDL_Window * window); +extern void OS4_GL_DeleteContext(_THIS, SDL_GLContext context); + +/* Non-SDL functions */ +extern SDL_bool OS4_GL_AllocateBuffers(_THIS, int width, int height, int depth, SDL_WindowData * data); +extern void OS4_GL_FreeBuffers(_THIS, SDL_WindowData * data); +extern SDL_bool OS4_GL_ResizeContext(_THIS, SDL_Window * window); +extern void OS4_GL_UpdateWindowPointer(_THIS, SDL_Window * window); + +#endif /* _SDL_os4opengl_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/amigaos4/SDL_os4opengles.c b/src/video/amigaos4/SDL_os4opengles.c new file mode 100644 index 0000000000000..59a9decb2e08b --- /dev/null +++ b/src/video/amigaos4/SDL_os4opengles.c @@ -0,0 +1,368 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_AMIGAOS4 + +#if SDL_VIDEO_OPENGL_ES2 + +#include "SDL_os4video.h" +#include "SDL_os4window.h" +#include "SDL_os4opengl.h" +#include "SDL_os4opengles.h" +#include "SDL_os4library.h" + +#include +#include + +#define DEBUG +#include "../../main/amigaos4/SDL_os4debug.h" + +static struct Library *OGLES2base; +struct OGLES2IFace *IOGLES2; + +void *AmiGetGLESProc(const char *proc); + +static void +OS4_GLES_LogLibraryError() +{ + dprintf("No OpenGL ES 2 library available\n"); + SDL_SetError("No OpenGL ES 2 library available"); +} + +int +OS4_GLES_LoadLibrary(_THIS, const char * path) +{ + dprintf("Called %d\n", _this->gl_config.driver_loaded); + + if (!OGLES2base) { + OGLES2base = OS4_OpenLibrary("ogles2.library", 0); + + if (!OGLES2base) { + dprintf("Failed to open ogles2.library\n"); + SDL_SetError("Failed to open ogles2.library"); + return -1; + } + } + + if (!IOGLES2) { + IOGLES2 = (struct OGLES2IFace *) OS4_GetInterface(OGLES2base); + + if (!IOGLES2) { + dprintf("Failed to open OpenGL ES 2 interface\n"); + SDL_SetError("Failed to open OpenGL ES 2 interface"); + return -1; + } + + dprintf("OpenGL ES 2 library opened\n"); + } + + return 0; +} + +void * +OS4_GLES_GetProcAddress(_THIS, const char * proc) +{ + void *func = NULL; + + dprintf("Called for '%s'\n", proc); + + if (IOGLES2) { + func = AmiGetGLESProc(proc); + } + + if (func == NULL) { + dprintf("Failed to load '%s'\n", proc); + SDL_SetError("Failed to load function"); + } + + return func; +} + +void +OS4_GLES_UnloadLibrary(_THIS) +{ + dprintf("Called %d\n", _this->gl_config.driver_loaded); + + OS4_DropInterface((void *) &IOGLES2); + OS4_CloseLibrary(&OGLES2base); +} + +SDL_GLContext +OS4_GLES_CreateContext(_THIS, SDL_Window * window) +{ + dprintf("Called\n"); + + if (IOGLES2) { + + int width, height; + + OS4_GetWindowActiveSize(window, &width, &height); + +#if MANAGE_BITMAP + uint32 depth; +#endif + + ULONG errCode = 0; + + SDL_WindowData *data = window->driverdata; + + if (data->glContext) { + dprintf("Old context %p found, deleting\n", data->glContext); + + aglDestroyContext(data->glContext); + + data->glContext = NULL; + } + +#if MANAGE_BITMAP + depth = IGraphics->GetBitMapAttr(data->syswin->RPort->BitMap, BMA_BITSPERPIXEL); + + if (!OS4_GL_AllocateBuffers(_this, width, height, depth, data)) { + SDL_SetError("Failed to allocate OpenGL ES 2 buffers"); + return NULL; + } +#endif + dprintf("Depth buffer size %d, stencil buffer size %d\n", + _this->gl_config.depth_size, _this->gl_config.stencil_size); + + data->glContext = aglCreateContextTags2( + &errCode, + OGLES2_CCT_WINDOW, (ULONG)data->syswin, + OGLES2_CCT_VSYNC, 0, +#if MANAGE_BITMAP + OGLES2_CCT_BITMAP, (ULONG)data->glBackBuffer, +#endif + OGLES2_CCT_DEPTH, _this->gl_config.depth_size, + OGLES2_CCT_STENCIL, _this->gl_config.stencil_size, + TAG_DONE); + + if (data->glContext) { + + dprintf("OpenGL ES 2 context %p created for window '%s'\n", + data->glContext, window->title); + + aglMakeCurrent(data->glContext); + glViewport(0, 0, width, height); + return data->glContext; + + } else { + dprintf("Failed to create OpenGL ES 2 context for window '%s' (error code %d)\n", + window->title, errCode); + + SDL_SetError("Failed to create OpenGL ES 2 context"); +#if MANAGE_BITMAP + OS4_GL_FreeBuffers(_this, data); +#endif + return NULL; + } + + } else { + OS4_GLES_LogLibraryError(); + return NULL; + } + + return NULL; +} + +int +OS4_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) +{ + int result = -1; + + if (!window || !context) { + dprintf("Called (window %p, context %p)\n", window, context); + } + + if (IOGLES2) { + aglMakeCurrent(context); + result = 0; + } else { + OS4_GLES_LogLibraryError(); + } + + return result; +} + +int +OS4_GLES_SwapWindow(_THIS, SDL_Window * window) +{ + //dprintf("Called\n"); + + if (IOGLES2) { + + SDL_WindowData *data = window->driverdata; + + if (data->glContext) { + SDL_VideoData *videodata = _this->driverdata; + +#if MANAGE_BITMAP + struct BitMap *temp; + int w, h; + BOOL blitRpRet; + int32 blitRet; + + OS4_GetWindowSize(_this, data->syswin, &w, &h); +#endif + + glFinish(); + + if (videodata->vsyncEnabled) { + IGraphics->WaitTOF(); + } + + aglSwapBuffers(); + +#if MANAGE_BITMAP + blitRpRet = IGraphics->BltBitMapRastPort(data->glBackBuffer, 0, 0, data->syswin->RPort, + data->syswin->BorderLeft, data->syswin->BorderTop, w, h, 0xC0); + + if (!blitRpRet) { + dprintf("BltBitMapRastPort() failed\n"); + } + + blitRet = IGraphics->BltBitMapTags(BLITA_Source, data->glBackBuffer, + BLITA_SrcType, BLITT_BITMAP, + BLITA_SrcX, 0, + BLITA_SrcY, 0, + BLITA_Dest, data->glFrontBuffer, + BLITA_DestType,BLITT_BITMAP, + BLITA_DestX, 0, + BLITA_DestY, 0, + BLITA_Width, w, + BLITA_Height, h, + BLITA_Minterm, 0xC0, + TAG_DONE); + + if (blitRet == -1) { + temp = data->glFrontBuffer; + data->glFrontBuffer = data->glBackBuffer; + data->glBackBuffer = temp; + + aglSetBitmap(data->glBackBuffer); + + return 0; + } else { + dprintf("BltBitMapTags() returned %d\n", blitRet); + } +#endif + } else { + dprintf("No OpenGL ES 2 context\n"); + } + } else { + OS4_GLES_LogLibraryError(); + } + + return -1; +} + +void +OS4_GLES_DeleteContext(_THIS, SDL_GLContext context) +{ + dprintf("Called with context=%p\n", context); + + if (IOGLES2) { + + if (context) { + SDL_Window *sdlwin; + Uint32 deletions = 0; + + for (sdlwin = _this->windows; sdlwin; sdlwin = sdlwin->next) { + + SDL_WindowData *data = sdlwin->driverdata; + + if (data->glContext == context) { + dprintf("Found OpenGL ES 2 context, clearing window binding\n"); + + aglDestroyContext(context); + + data->glContext = NULL; + deletions++; + } + } + + if (deletions == 0) { + dprintf("OpenGL ES 2 context doesn't seem to have window binding\n"); + } + } else { + dprintf("No context to delete\n"); + } + + } else { + OS4_GLES_LogLibraryError(); + } +} + +SDL_bool +OS4_GLES_ResizeContext(_THIS, SDL_Window * window) +{ + if (IOGLES2) { +#if MANAGE_BITMAP + SDL_WindowData *data = window->driverdata; + + if (data) { + int width, height; + + uint32 depth = IGraphics->GetBitMapAttr(data->syswin->RPort->BitMap, BMA_BITSPERPIXEL); + + OS4_GetWindowActiveSize(window, &width, &height); + + if (OS4_GL_AllocateBuffers(_this, width, height, depth, data)) { + + dprintf("Resizing context to %d*%d\n", width, height); + + aglSetBitmap(data->glBackBuffer); + + glViewport(0, 0, width, height); + return SDL_TRUE; + + } else { + dprintf("Failed to re-allocate OpenGL ES 2 buffers\n"); + //SDL_Quit(); + } + } +#endif + return SDL_TRUE; + } else { + OS4_GLES_LogLibraryError(); + } + + return SDL_FALSE; +} + +void +OS4_GLES_UpdateWindowPointer(_THIS, SDL_Window * window) +{ + if (IOGLES2) { + SDL_WindowData *data = window->driverdata; + + dprintf("Updating GLES2 window pointer %p\n", data->syswin); + aglSetParamsTags2(OGLES2_CCT_WINDOW, (ULONG)data->syswin, TAG_DONE); + } else { + OS4_GLES_LogLibraryError(); + } +} + +#endif /* SDL_VIDEO_OPENGL_ES2 */ + +#endif /* SDL_VIDEO_DRIVER_AMIGAOS4 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/amigaos4/SDL_os4opengles.h b/src/video/amigaos4/SDL_os4opengles.h new file mode 100644 index 0000000000000..f9138f1db4c16 --- /dev/null +++ b/src/video/amigaos4/SDL_os4opengles.h @@ -0,0 +1,39 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#ifndef _SDL_os4opengles_h +#define _SDL_os4opengles_h + +extern int OS4_GLES_LoadLibrary(_THIS, const char *path); +extern void *OS4_GLES_GetProcAddress(_THIS, const char *proc); +extern void OS4_GLES_UnloadLibrary(_THIS); +extern SDL_GLContext OS4_GLES_CreateContext(_THIS, SDL_Window * window); +extern int OS4_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context); +extern int OS4_GLES_SwapWindow(_THIS, SDL_Window * window); +extern void OS4_GLES_DeleteContext(_THIS, SDL_GLContext context); + +extern SDL_bool OS4_GLES_ResizeContext(_THIS, SDL_Window * window); +extern void OS4_GLES_UpdateWindowPointer(_THIS, SDL_Window * window); + +#endif /* _SDL_os4opengles_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/amigaos4/SDL_os4opengles2wrapper.c b/src/video/amigaos4/SDL_os4opengles2wrapper.c new file mode 100644 index 0000000000000..4e37f10aa7a36 --- /dev/null +++ b/src/video/amigaos4/SDL_os4opengles2wrapper.c @@ -0,0 +1,771 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "SDL_config.h" + +#if SDL_VIDEO_DRIVER_AMIGAOS4 + +#if SDL_VIDEO_OPENGL_ES2 + +#include +#include + +/* The OpenGL ES 2.0 API */ + +static void AmiglActiveTexture (GLenum texture) { + return glActiveTexture(texture); +} + +static void AmiglAttachShader (GLuint program, GLuint shader) { + return glAttachShader(program, shader); +} + +static void AmiglBindAttribLocation (GLuint program, GLuint index, const GLchar *name) { + return glBindAttribLocation(program, index, name); +} + +static void AmiglBindBuffer (GLenum target, GLuint buffer) { + return glBindBuffer(target, buffer); +} + +static void AmiglBindFramebuffer (GLenum target, GLuint framebuffer) { + return glBindFramebuffer(target, framebuffer); +} + +static void AmiglBindRenderbuffer (GLenum target, GLuint renderbuffer) { + return glBindRenderbuffer(target, renderbuffer); +} + +static void AmiglBindTexture (GLenum target, GLuint texture) { + return glBindTexture(target, texture); +} + +static void AmiglBlendColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { + return glBlendColor(red, green, blue, alpha); +} + +static void AmiglBlendEquation (GLenum mode) { + return glBlendEquation(mode); +} + +static void AmiglBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha) { + return glBlendEquationSeparate(modeRGB, modeAlpha); +} + +static void AmiglBlendFunc (GLenum sfactor, GLenum dfactor) { + return glBlendFunc(sfactor, dfactor); +} + +static void AmiglBlendFuncSeparate (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) { + return glBlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha); +} + +static void AmiglBufferData (GLenum target, GLsizeiptr size, const void *data, GLenum usage) { + return glBufferData(target, size, data, usage); +} + +static void AmiglBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void *data) { + return glBufferSubData(target, offset, size, data); +} + +static GLenum AmiglCheckFramebufferStatus (GLenum target) { + return glCheckFramebufferStatus(target); +} + +static void AmiglClear (GLbitfield mask) { + return glClear(mask); +} + +static void AmiglClearColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { + return glClearColor(red, green, blue, alpha); +} + +static void AmiglClearDepthf (GLfloat d) { + return glClearDepthf(d); +} + +static void AmiglClearStencil (GLint s) { + return glClearStencil(s); +} + +static void AmiglColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) { + return glColorMask(red, green, blue, alpha); +} + +static void AmiglCompileShader (GLuint shader) { + return glCompileShader(shader); +} + +static void AmiglCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data) { + return glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data); +} + +static void AmiglCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data) { + return glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data); +} + +static void AmiglCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) { + return glCopyTexImage2D(target, level, internalformat, x, y, width, height, border); +} + +static void AmiglCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) { + return glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); +} + +static GLuint AmiglCreateProgram (void) { + return glCreateProgram(); +} + +static GLuint AmiglCreateShader (GLenum type) { + return glCreateShader(type); +} + +static void AmiglCullFace (GLenum mode) { + return glCullFace(mode); +} + +static void AmiglDeleteBuffers (GLsizei n, const GLuint *buffers) { + return glDeleteBuffers(n, buffers); +} + +static void AmiglDeleteFramebuffers (GLsizei n, const GLuint *framebuffers) { + return glDeleteFramebuffers(n, framebuffers); +} + +static void AmiglDeleteProgram (GLuint program) { + return glDeleteProgram(program); +} + +static void AmiglDeleteRenderbuffers (GLsizei n, const GLuint *renderbuffers) { + return glDeleteRenderbuffers(n, renderbuffers); +} + +static void AmiglDeleteShader (GLuint shader) { + return glDeleteShader(shader); +} + +static void AmiglDeleteTextures (GLsizei n, const GLuint *textures) { + return glDeleteTextures(n, textures); +} + +static void AmiglDepthFunc (GLenum func) { + return glDepthFunc(func); +} + +static void AmiglDepthMask (GLboolean flag) { + return glDepthMask(flag); +} + +static void AmiglDepthRangef (GLfloat n, GLfloat f) { + return glDepthRangef(n, f); +} + +static void AmiglDetachShader (GLuint program, GLuint shader) { + return glDetachShader(program, shader); +} + +static void AmiglDisable (GLenum cap) { + return glDisable(cap); +} + +static void AmiglDisableVertexAttribArray (GLuint index) { + return glDisableVertexAttribArray(index); +} + +static void AmiglDrawArrays (GLenum mode, GLint first, GLsizei count) { + return glDrawArrays(mode, first, count); +} + +static void AmiglDrawElements (GLenum mode, GLsizei count, GLenum type, const void *indices) { + return glDrawElements(mode, count, type, indices); +} + +static void AmiglEnable (GLenum cap) { + return glEnable(cap); +} + +static void AmiglEnableVertexAttribArray (GLuint index) { + return glEnableVertexAttribArray(index); +} + +static void AmiglFinish (void) { + return glFinish(); +} + +static void AmiglFlush (void) { + return glFlush(); +} + +static void AmiglFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) { + return glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer); +} + +static void AmiglFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) { + return glFramebufferTexture2D(target, attachment, textarget, texture, level); +} + +static void AmiglFrontFace (GLenum mode) { + return glFrontFace(mode); +} + +static void AmiglGenBuffers (GLsizei n, GLuint *buffers) { + return glGenBuffers(n, buffers); +} + +static void AmiglGenerateMipmap (GLenum target) { + return glGenerateMipmap(target); +} + +static void AmiglGenFramebuffers (GLsizei n, GLuint *framebuffers) { + return glGenFramebuffers(n, framebuffers); +} + +static void AmiglGenRenderbuffers (GLsizei n, GLuint *renderbuffers) { + return glGenRenderbuffers(n, renderbuffers); +} + +static void AmiglGenTextures (GLsizei n, GLuint *textures) { + return glGenTextures(n, textures); +} + +static void AmiglGetActiveAttrib (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) { + return glGetActiveAttrib(program, index, bufSize, length, size, type, name); +} + +static void AmiglGetActiveUniform (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) { + return glGetActiveUniform(program, index, bufSize, length, size, type, name); +} + +static void AmiglGetAttachedShaders (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders) { + return glGetAttachedShaders(program, maxCount, count, shaders); +} + +static GLint AmiglGetAttribLocation (GLuint program, const GLchar *name) { + return glGetAttribLocation(program, name); +} + +static void AmiglGetBooleanv (GLenum pname, GLboolean *data) { + return glGetBooleanv(pname, data); +} + +static void AmiglGetBufferParameteriv (GLenum target, GLenum pname, GLint *params) { + return glGetBufferParameteriv(target, pname, params); +} + +static GLenum AmiglGetError (void) { + return glGetError(); +} + +static void AmiglGetFloatv (GLenum pname, GLfloat *data) { + return glGetFloatv(pname, data); +} + +static void AmiglGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint *params) { + return glGetFramebufferAttachmentParameteriv(target, attachment, pname, params); +} + +static void AmiglGetIntegerv (GLenum pname, GLint *data) { + return glGetIntegerv(pname, data); +} + +static void AmiglGetProgramiv (GLuint program, GLenum pname, GLint *params) { + return glGetProgramiv(program, pname, params); +} + +static void AmiglGetProgramInfoLog (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog) { + return glGetProgramInfoLog(program, bufSize, length, infoLog); +} + +static void AmiglGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint *params) { + return glGetRenderbufferParameteriv(target, pname, params); +} + +static void AmiglGetShaderiv (GLuint shader, GLenum pname, GLint *params) { + return glGetShaderiv(shader, pname, params); +} + +static void AmiglGetShaderInfoLog (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog) { + return glGetShaderInfoLog(shader, bufSize, length, infoLog); +} + +static void AmiglGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision) { + return glGetShaderPrecisionFormat(shadertype, precisiontype, range, precision); +} + +static void AmiglGetShaderSource (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source) { + return glGetShaderSource(shader, bufSize, length, source); +} + +static const GLubyte *AmiglGetString (GLenum name) { + return glGetString(name); +} + +static void AmiglGetTexParameterfv (GLenum target, GLenum pname, GLfloat *params) { + return glGetTexParameterfv(target, pname, params); +} + +static void AmiglGetTexParameteriv (GLenum target, GLenum pname, GLint *params) { + return glGetTexParameteriv(target, pname, params); +} + +static void AmiglGetUniformfv (GLuint program, GLint location, GLfloat *params) { + return glGetUniformfv(program, location, params); +} + +static void AmiglGetUniformiv (GLuint program, GLint location, GLint *params) { + return glGetUniformiv(program, location, params); +} + +static GLint AmiglGetUniformLocation (GLuint program, const GLchar *name) { + return glGetUniformLocation(program, name); +} + +static void AmiglGetVertexAttribfv (GLuint index, GLenum pname, GLfloat *params) { + return glGetVertexAttribfv(index, pname, params); +} + +static void AmiglGetVertexAttribiv (GLuint index, GLenum pname, GLint *params) { + return glGetVertexAttribiv(index, pname, params); +} + +static void AmiglGetVertexAttribPointerv (GLuint index, GLenum pname, void **pointer) { + return glGetVertexAttribPointerv(index, pname, pointer); +} + +static void AmiglHint (GLenum target, GLenum mode) { + return glHint(target, mode); +} + +static GLboolean AmiglIsBuffer (GLuint buffer) { + return glIsBuffer(buffer); +} + +static GLboolean AmiglIsEnabled (GLenum cap) { + return glIsEnabled(cap); +} + +static GLboolean AmiglIsFramebuffer (GLuint framebuffer) { + return glIsFramebuffer(framebuffer); +} + +static GLboolean AmiglIsProgram (GLuint program) { + return glIsProgram(program); +} + +static GLboolean AmiglIsRenderbuffer (GLuint renderbuffer) { + return glIsRenderbuffer(renderbuffer); +} + +static GLboolean AmiglIsShader (GLuint shader) { + return glIsShader(shader); +} + +static GLboolean AmiglIsTexture (GLuint texture) { + return glIsTexture(texture); +} + +static void AmiglLineWidth (GLfloat width) { + return glLineWidth(width); +} + +static void AmiglLinkProgram (GLuint program) { + return glLinkProgram(program); +} + +static void AmiglPixelStorei (GLenum pname, GLint param) { + return glPixelStorei(pname, param); +} + +static void AmiglPolygonOffset (GLfloat factor, GLfloat units) { + return glPolygonOffset(factor, units); +} + +static void AmiglReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels) { + return glReadPixels(x, y, width, height, format, type, pixels); +} + +static void AmiglReleaseShaderCompiler (void) { + return glReleaseShaderCompiler(); +} + +static void AmiglRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height) { + return glRenderbufferStorage(target, internalformat, width, height); +} + +static void AmiglSampleCoverage (GLfloat value, GLboolean invert) { + return glSampleCoverage(value, invert); +} + +static void AmiglScissor (GLint x, GLint y, GLsizei width, GLsizei height) { + return glScissor(x, y, width, height); +} + +static void AmiglShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length) { + return glShaderBinary(count, shaders, binaryformat, binary, length); +} + +static void AmiglShaderSource (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length) { + return glShaderSource(shader, count, string, length); +} + +static void AmiglStencilFunc (GLenum func, GLint ref, GLuint mask) { + return glStencilFunc(func, ref, mask); +} + +static void AmiglStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask) { + return glStencilFuncSeparate(face, func, ref, mask); +} + +static void AmiglStencilMask (GLuint mask) { + return glStencilMask(mask); +} + +static void AmiglStencilMaskSeparate (GLenum face, GLuint mask) { + return glStencilMaskSeparate(face, mask); +} + +static void AmiglStencilOp (GLenum fail, GLenum zfail, GLenum zpass) { + return glStencilOp(fail, zfail, zpass); +} + +static void AmiglStencilOpSeparate (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass) { + return glStencilOpSeparate(face, sfail, dpfail, dppass); +} + +static void AmiglTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels) { + return glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels); +} + +static void AmiglTexParameterf (GLenum target, GLenum pname, GLfloat param) { + return glTexParameterf(target, pname, param); +} + +static void AmiglTexParameterfv (GLenum target, GLenum pname, const GLfloat *params) { + return glTexParameterfv(target, pname, params); +} + +static void AmiglTexParameteri (GLenum target, GLenum pname, GLint param) { + return glTexParameteri(target, pname, param); +} + +static void AmiglTexParameteriv (GLenum target, GLenum pname, const GLint *params) { + return glTexParameteriv(target, pname, params); +} + +static void AmiglTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels) { + return glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); +} + +static void AmiglUniform1f (GLint location, GLfloat v0) { + return glUniform1f(location, v0); +} + +static void AmiglUniform1fv (GLint location, GLsizei count, const GLfloat *value) { + return glUniform1fv(location, count, value); +} + +static void AmiglUniform1i (GLint location, GLint v0) { + return glUniform1i(location, v0); +} + +static void AmiglUniform1iv (GLint location, GLsizei count, const GLint *value) { + return glUniform1iv(location, count, value); +} + +static void AmiglUniform2f (GLint location, GLfloat v0, GLfloat v1) { + return glUniform2f(location, v0, v1); +} + +static void AmiglUniform2fv (GLint location, GLsizei count, const GLfloat *value) { + return glUniform2fv(location, count, value); +} + +static void AmiglUniform2i (GLint location, GLint v0, GLint v1) { + return glUniform2i(location, v0, v1); +} + +static void AmiglUniform2iv (GLint location, GLsizei count, const GLint *value) { + return glUniform2iv(location, count, value); +} + +static void AmiglUniform3f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2) { + return glUniform3f(location, v0, v1, v2); +} + +static void AmiglUniform3fv (GLint location, GLsizei count, const GLfloat *value) { + return glUniform3fv(location, count, value); +} + +static void AmiglUniform3i (GLint location, GLint v0, GLint v1, GLint v2) { + return glUniform3i(location, v0, v1, v2); +} + +static void AmiglUniform3iv (GLint location, GLsizei count, const GLint *value) { + return glUniform3iv(location, count, value); +} + +static void AmiglUniform4f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) { + return glUniform4f(location, v0, v1, v2, v3); +} + +static void AmiglUniform4fv (GLint location, GLsizei count, const GLfloat *value) { + return glUniform4fv(location, count, value); +} + +static void AmiglUniform4i (GLint location, GLint v0, GLint v1, GLint v2, GLint v3) { + return glUniform4i(location, v0, v1, v2, v3); +} + +static void AmiglUniform4iv (GLint location, GLsizei count, const GLint *value) { + return glUniform4iv(location, count, value); +} + +static void AmiglUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) { + return glUniformMatrix2fv(location, count, transpose, value); +} + +static void AmiglUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) { + return glUniformMatrix3fv(location, count, transpose, value); +} + +static void AmiglUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) { + return glUniformMatrix4fv(location, count, transpose, value); +} + +static void AmiglUseProgram (GLuint program) { + return glUseProgram(program); +} + +static void AmiglValidateProgram (GLuint program) { + return glValidateProgram(program); +} + +static void AmiglVertexAttrib1f (GLuint index, GLfloat x) { + return glVertexAttrib1f(index, x); +} + +static void AmiglVertexAttrib1fv (GLuint index, const GLfloat *v) { + return glVertexAttrib1fv(index, v); +} + +static void AmiglVertexAttrib2f (GLuint index, GLfloat x, GLfloat y) { + return glVertexAttrib2f(index, x, y); +} + +static void AmiglVertexAttrib2fv (GLuint index, const GLfloat *v) { + return glVertexAttrib2fv(index, v); +} + +static void AmiglVertexAttrib3f (GLuint index, GLfloat x, GLfloat y, GLfloat z) { + return glVertexAttrib3f(index, x, y, z); +} + +static void AmiglVertexAttrib3fv (GLuint index, const GLfloat *v) { + return glVertexAttrib3fv(index, v); +} + +static void AmiglVertexAttrib4f (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { + return glVertexAttrib4f(index, x, y, z, w); +} + +static void AmiglVertexAttrib4fv (GLuint index, const GLfloat *v) { + return glVertexAttrib4fv(index, v); +} + +static void AmiglVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer) { + return glVertexAttribPointer(index, size, type, normalized, stride, pointer); +} + +static void AmiglViewport (GLint x, GLint y, GLsizei width, GLsizei height) { + return glViewport(x, y, width, height); +} + +struct MyGLFunc +{ + CONST_STRPTR name; + APTR func; +}; + +#define MY_GL_FUNC(name) {#name, Ami##name}, + + +void *AmiGetGLESProc(const char *proc) +{ + static CONST struct MyGLFunc table[] = { + MY_GL_FUNC(glActiveTexture) + MY_GL_FUNC(glAttachShader) + MY_GL_FUNC(glBindAttribLocation) + MY_GL_FUNC(glBindBuffer) + MY_GL_FUNC(glBindFramebuffer) + MY_GL_FUNC(glBindRenderbuffer) + MY_GL_FUNC(glBindTexture) + MY_GL_FUNC(glBlendColor) + MY_GL_FUNC(glBlendEquation) + MY_GL_FUNC(glBlendEquationSeparate) + MY_GL_FUNC(glBlendFunc) + MY_GL_FUNC(glBlendFuncSeparate) + MY_GL_FUNC(glBufferData) + MY_GL_FUNC(glBufferSubData) + MY_GL_FUNC(glCheckFramebufferStatus) + MY_GL_FUNC(glClear) + MY_GL_FUNC(glClearColor) + MY_GL_FUNC(glClearDepthf) + MY_GL_FUNC(glClearStencil) + MY_GL_FUNC(glColorMask) + MY_GL_FUNC(glCompileShader) + MY_GL_FUNC(glCompressedTexImage2D) + MY_GL_FUNC(glCompressedTexSubImage2D) + MY_GL_FUNC(glCopyTexImage2D) + MY_GL_FUNC(glCopyTexSubImage2D) + MY_GL_FUNC(glCreateProgram) + MY_GL_FUNC(glCreateShader) + MY_GL_FUNC(glCullFace) + MY_GL_FUNC(glDeleteBuffers) + MY_GL_FUNC(glDeleteFramebuffers) + MY_GL_FUNC(glDeleteProgram) + MY_GL_FUNC(glDeleteRenderbuffers) + MY_GL_FUNC(glDeleteShader) + MY_GL_FUNC(glDeleteTextures) + MY_GL_FUNC(glDepthFunc) + MY_GL_FUNC(glDepthMask) + MY_GL_FUNC(glDepthRangef) + MY_GL_FUNC(glDetachShader) + MY_GL_FUNC(glDisable) + MY_GL_FUNC(glDisableVertexAttribArray) + MY_GL_FUNC(glDrawArrays) + MY_GL_FUNC(glDrawElements) + MY_GL_FUNC(glEnable) + MY_GL_FUNC(glEnableVertexAttribArray) + MY_GL_FUNC(glFinish) + MY_GL_FUNC(glFlush) + MY_GL_FUNC(glFramebufferRenderbuffer) + MY_GL_FUNC(glFramebufferTexture2D) + MY_GL_FUNC(glFrontFace) + MY_GL_FUNC(glGenBuffers) + MY_GL_FUNC(glGenerateMipmap) + MY_GL_FUNC(glGenFramebuffers) + MY_GL_FUNC(glGenRenderbuffers) + MY_GL_FUNC(glGenTextures) + MY_GL_FUNC(glGetActiveAttrib) + MY_GL_FUNC(glGetActiveUniform) + MY_GL_FUNC(glGetAttachedShaders) + MY_GL_FUNC(glGetAttribLocation) + MY_GL_FUNC(glGetBooleanv) + MY_GL_FUNC(glGetBufferParameteriv) + MY_GL_FUNC(glGetError) + MY_GL_FUNC(glGetFloatv) + MY_GL_FUNC(glGetFramebufferAttachmentParameteriv) + MY_GL_FUNC(glGetIntegerv) + MY_GL_FUNC(glGetProgramiv) + MY_GL_FUNC(glGetProgramInfoLog) + MY_GL_FUNC(glGetRenderbufferParameteriv) + MY_GL_FUNC(glGetShaderiv) + MY_GL_FUNC(glGetShaderInfoLog) + MY_GL_FUNC(glGetShaderPrecisionFormat) + MY_GL_FUNC(glGetShaderSource) + MY_GL_FUNC(glGetString) + MY_GL_FUNC(glGetTexParameterfv) + MY_GL_FUNC(glGetTexParameteriv) + MY_GL_FUNC(glGetUniformfv) + MY_GL_FUNC(glGetUniformiv) + MY_GL_FUNC(glGetUniformLocation) + MY_GL_FUNC(glGetVertexAttribfv) + MY_GL_FUNC(glGetVertexAttribiv) + MY_GL_FUNC(glGetVertexAttribPointerv) + MY_GL_FUNC(glHint) + MY_GL_FUNC(glIsBuffer) + MY_GL_FUNC(glIsEnabled) + MY_GL_FUNC(glIsFramebuffer) + MY_GL_FUNC(glIsProgram) + MY_GL_FUNC(glIsRenderbuffer) + MY_GL_FUNC(glIsShader) + MY_GL_FUNC(glIsTexture) + MY_GL_FUNC(glLineWidth) + MY_GL_FUNC(glLinkProgram) + MY_GL_FUNC(glPixelStorei) + MY_GL_FUNC(glPolygonOffset) + MY_GL_FUNC(glReadPixels) + MY_GL_FUNC(glReleaseShaderCompiler) + MY_GL_FUNC(glRenderbufferStorage) + MY_GL_FUNC(glSampleCoverage) + MY_GL_FUNC(glScissor) + MY_GL_FUNC(glShaderBinary) + MY_GL_FUNC(glShaderSource) + MY_GL_FUNC(glStencilFunc) + MY_GL_FUNC(glStencilFuncSeparate) + MY_GL_FUNC(glStencilMask) + MY_GL_FUNC(glStencilMaskSeparate) + MY_GL_FUNC(glStencilOp) + MY_GL_FUNC(glStencilOpSeparate) + MY_GL_FUNC(glTexImage2D) + MY_GL_FUNC(glTexParameterf) + MY_GL_FUNC(glTexParameterfv) + MY_GL_FUNC(glTexParameteri) + MY_GL_FUNC(glTexParameteriv) + MY_GL_FUNC(glTexSubImage2D) + MY_GL_FUNC(glUniform1f) + MY_GL_FUNC(glUniform1fv) + MY_GL_FUNC(glUniform1i) + MY_GL_FUNC(glUniform1iv) + MY_GL_FUNC(glUniform2f) + MY_GL_FUNC(glUniform2fv) + MY_GL_FUNC(glUniform2i) + MY_GL_FUNC(glUniform2iv) + MY_GL_FUNC(glUniform3f) + MY_GL_FUNC(glUniform3fv) + MY_GL_FUNC(glUniform3i) + MY_GL_FUNC(glUniform3iv) + MY_GL_FUNC(glUniform4f) + MY_GL_FUNC(glUniform4fv) + MY_GL_FUNC(glUniform4i) + MY_GL_FUNC(glUniform4iv) + MY_GL_FUNC(glUniformMatrix2fv) + MY_GL_FUNC(glUniformMatrix3fv) + MY_GL_FUNC(glUniformMatrix4fv) + MY_GL_FUNC(glUseProgram) + MY_GL_FUNC(glValidateProgram) + MY_GL_FUNC(glVertexAttrib1f) + MY_GL_FUNC(glVertexAttrib1fv) + MY_GL_FUNC(glVertexAttrib2f) + MY_GL_FUNC(glVertexAttrib2fv) + MY_GL_FUNC(glVertexAttrib3f) + MY_GL_FUNC(glVertexAttrib3fv) + MY_GL_FUNC(glVertexAttrib4f) + MY_GL_FUNC(glVertexAttrib4fv) + MY_GL_FUNC(glVertexAttribPointer) + MY_GL_FUNC(glViewport) + { NULL, NULL } + }; + + CONST struct MyGLFunc *tb = table; + + do { + if (!strcmp(tb->name, proc)) { + return tb->func; + } + tb++; + } while (tb->name); + + return NULL; +} + +#endif /* SDL_VIDEO_OPENGL_ES2 */ +#endif /* SDL_VIDEO_DRIVER_AMIGAOS4 */ diff --git a/src/video/amigaos4/SDL_os4openglwrapper.c b/src/video/amigaos4/SDL_os4openglwrapper.c new file mode 100644 index 0000000000000..07b5d72d0d767 --- /dev/null +++ b/src/video/amigaos4/SDL_os4openglwrapper.c @@ -0,0 +1,1847 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "SDL_config.h" + +/* wrapper functions for MiniGL */ + +#if SDL_VIDEO_DRIVER_AMIGAOS4 + +#include +#include +#include + +#define NOT_IMPLEMENTED_FUNCS + +#include + +/* The GL API */ + +static void AmiglActiveTexture(GLenum unit) { + return glActiveTexture(unit); +} + +static void AmiglClientActiveTexture(GLenum texture) { + return glClientActiveTexture(texture); +} + +static void AmiglColorTable(GLenum target, GLenum internalformat, GLint width, GLenum format, GLenum type, const GLvoid* data) { + return glColorTable(target, internalformat, width, format, type, data); +} + +static void AmiglColorTableEXT(GLenum target, GLenum internalformat, GLint width, GLenum format, GLenum type, const GLvoid* data) { + return glColorTableEXT(target, internalformat, width, format, type, data); +} + +static void AmiglClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ) { + return glClearColor(red, green, blue, alpha); +} + +static void AmiglClear( GLbitfield mask ) { + return glClear(mask); +} + +static void AmiglColorMask( GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha ) { + return glColorMask(red, green, blue, alpha); +} + +static void AmiglAlphaFunc( GLenum func, GLclampf ref ) { + return glAlphaFunc(func, ref); +} + +static void AmiglBlendFunc( GLenum sfactor, GLenum dfactor ) { + return glBlendFunc(sfactor, dfactor); +} + +static void AmiglLogicOp( GLenum opcode ) { + return glLogicOp(opcode); +} + +static void AmiglCullFace( GLenum mode ) { + return glCullFace(mode); +} + +static void AmiglFrontFace( GLenum mode ) { + return glFrontFace(mode); +} + +static void AmiglPointSize( GLfloat size ) { + return glPointSize(size); +} + +static void AmiglLineWidth( GLfloat width ) { + return glLineWidth(width); +} + +static void AmiglLineStipple( GLint factor, GLushort pattern ) { + return glLineStipple(factor, pattern); +} + +static void AmiglPolygonMode( GLenum face, GLenum mode ) { + return glPolygonMode(face, mode); +} + +static void AmiglPolygonOffset( GLfloat factor, GLfloat units ) { + return glPolygonOffset(factor, units); +} + +static void AmiglPolygonStipple( GLubyte *mask ) { + return glPolygonStipple(mask); +} + +static void AmiglEdgeFlag( GLboolean flag ) { + return glEdgeFlag(flag); +} + +static void AmiglScissor( GLint x, GLint y, GLsizei width, GLsizei height) { + return glScissor(x, y, width, height); +} + +static void AmiglClipPlane( GLenum plane, const GLdouble *equation ) { + return glClipPlane(plane, (GLdouble *)equation); +} + +static void AmiglGetClipPlane( GLenum plane, GLdouble *equation ) { + return glGetClipPlane(plane, equation); +} + +static void AmiglDrawBuffer( GLenum mode ) { + return glDrawBuffer(mode); +} + +static void AmiglReadBuffer( GLenum mode ) { + return glReadBuffer(mode); +} + +static void AmiglEnable( GLenum cap ) { + return glEnable(cap); +} + +static void AmiglDisable( GLenum cap ) { + return glDisable(cap); +} + +static GLboolean AmiglIsEnabled( GLenum cap ) { + return glIsEnabled(cap); +} + +static void AmiglEnableClientState( GLenum cap ) { /* 1.1 */ + return glEnableClientState(cap); +} + +static void AmiglDisableClientState( GLenum cap ) { /* 1.1 */ + return glDisableClientState(cap); +} + +static void AmiglGetBooleanv( GLenum pname, GLboolean *params ) { + return glGetBooleanv(pname, params); +} + +static void AmiglGetDoublev( GLenum pname, GLdouble *params ) { + return glGetDoublev(pname, params); +} + +static void AmiglGetFloatv( GLenum pname, GLfloat *params ) { + return glGetFloatv(pname, params); +} + +static void AmiglGetIntegerv( GLenum pname, GLint *params ) { + return glGetIntegerv(pname, params); +} + +static void AmiglPushAttrib( GLbitfield mask ) { + return glPushAttrib(mask); +} + +static void AmiglPopAttrib( void ) { + return glPopAttrib(); +} + +static void AmiglPushClientAttrib( GLbitfield mask ) { /* 1.1 */ + return glPushClientAttrib(mask); +} + +static void AmiglPopClientAttrib( void ) { /* 1.1 */ + return glPopClientAttrib(); +} + +static GLint AmiglRenderMode( GLenum mode ) { + return glRenderMode(mode); +} + +static GLenum AmiglGetError( void ) { + return glGetError(); +} + +static const GLubyte* AmiglGetString( GLenum name ) { + return glGetString(name); +} + +static void AmiglFinish( void ) { + return glFinish(); +} + +static void AmiglFlush( void ) { + return glFlush(); +} + +static void AmiglHint( GLenum target, GLenum mode ) { + return glHint(target, mode); +} + +static void AmiglClearDepth( GLclampd depth ) { + return glClearDepth(depth); +} + +static void AmiglDepthFunc( GLenum func ) { + return glDepthFunc(func); +} + +static void AmiglDepthMask( GLboolean flag ) { + return glDepthMask(flag); +} + +static void AmiglDepthRange( GLclampd near_val, GLclampd far_val ) { + return glDepthRange(near_val, far_val); +} + +static void AmiglMatrixMode( GLenum mode ) { + return glMatrixMode(mode); +} + +static void AmiglOrtho( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val ) { + return glOrtho(left, right, bottom, top, near_val, far_val); +} + +static void AmiglFrustum( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val ) { + return glFrustum(left, right, bottom, top, near_val, far_val); +} + +static void AmiglViewport( GLint x, GLint y, GLsizei width, GLsizei height ) { + return glViewport(x, y, width, height); +} + +static void AmiglPushMatrix( void ) { + return glPushMatrix(); +} + +static void AmiglPopMatrix( void ) { + return glPopMatrix(); +} + +static void AmiglLoadIdentity( void ) { + return glLoadIdentity(); +} + +static void AmiglLoadMatrixd( const GLdouble *m ) { + return glLoadMatrixd(m); +} + +static void AmiglLoadMatrixf( const GLfloat *m ) { + return glLoadMatrixf(m); +} + +static void AmiglMultMatrixd( const GLdouble *m ) { + return glMultMatrixd(m); +} + +static void AmiglMultMatrixf( const GLfloat *m ) { + return glMultMatrixf(m); +} + +static void AmiglRotated( GLdouble angle, GLdouble x, GLdouble y, GLdouble z ) { + return glRotated(angle, x, y, z); +} + +static void AmiglRotatef( GLfloat angle, GLfloat x, GLfloat y, GLfloat z ) { + return glRotatef(angle, x, y, z); +} + +static void AmiglScaled( GLdouble x, GLdouble y, GLdouble z ) { + return glScaled(x, y, z); +} + +static void AmiglScalef( GLfloat x, GLfloat y, GLfloat z ) { + return glScalef(x, y, z); +} + +static void AmiglTranslated( GLdouble x, GLdouble y, GLdouble z ) { + return glTranslated(x, y, z); +} + +static void AmiglTranslatef( GLfloat x, GLfloat y, GLfloat z ) { + return glTranslatef(x, y, z); +} + +static GLboolean AmiglIsList( GLuint list ) { + return glIsList(list); +} + +static void AmiglDeleteLists( GLuint list, GLsizei range ) { + return glDeleteLists(list, range); +} + +static GLuint AmiglGenLists( GLsizei range ) { + return glGenLists(range); +} + +static void AmiglNewList( GLuint list, GLenum mode ) { + return glNewList(list, mode); +} + +static void AmiglEndList( void ) { + return glEndList(); +} + +static void AmiglCallList( GLuint list ) { + return glCallList(list); +} + +static void AmiglCallLists( GLsizei n, GLenum type, GLvoid *lists ) { + return glCallLists(n, type, lists); +} + +static void AmiglListBase( GLuint base ) { + return glListBase(base); +} + +static void AmiglBegin( GLenum mode ) { + return glBegin(mode); +} + +static void AmiglEnd( void ) { + return glEnd(); +} + +static void AmiglVertex2d( GLdouble x, GLdouble y ) { + return glVertex2d(x, y); +} + +static void AmiglVertex2f( GLfloat x, GLfloat y ) { + return glVertex2f(x, y); +} + +static void AmiglVertex2i( GLint x, GLint y ) { + return glVertex2i(x, y); +} + +static void AmiglVertex2s( GLshort x, GLshort y ) { + return glVertex2s(x, y); +} + +static void AmiglVertex3d( GLdouble x, GLdouble y, GLdouble z ) { + return glVertex3d(x, y, z); +} + +static void AmiglVertex3f( GLfloat x, GLfloat y, GLfloat z ) { + return glVertex3f(x, y, z); +} + +static void AmiglVertex3i( GLint x, GLint y, GLint z ) { + return glVertex3i(x, y, z); +} + +static void AmiglVertex3s( GLshort x, GLshort y, GLshort z ) { + return glVertex3s(x, y, z); +} + +static void AmiglVertex4d( GLdouble x, GLdouble y, GLdouble z, GLdouble w ) { + return glVertex4d(x, y, z, w); +} + +static void AmiglVertex4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w ) { + return glVertex4f(x, y, z, w); +} + +static void AmiglVertex4i( GLint x, GLint y, GLint z, GLint w ) { + return glVertex4i(x, y, z, w); +} + +static void AmiglVertex4s( GLshort x, GLshort y, GLshort z, GLshort w ) { + return glVertex4s(x, y, z, w); +} + +static void AmiglVertex2dv( GLdouble *v ) { + return glVertex2dv(v); +} + +static void AmiglVertex2fv( GLfloat *v ) { + return glVertex2fv(v); +} + +static void AmiglVertex2iv( GLint *v ) { + return glVertex2iv(v); +} + +static void AmiglVertex2sv( GLshort *v ) { + return glVertex2sv(v); +} + +static void AmiglVertex3dv( GLdouble *v ) { + return glVertex3dv(v); +} + +static void AmiglVertex3fv( GLfloat *v ) { + return glVertex3fv(v); +} + +static void AmiglVertex3iv( GLint *v ) { + return glVertex3iv(v); +} + +static void AmiglVertex3sv( GLshort *v ) { + return glVertex3sv(v); +} + +static void AmiglVertex4dv( GLdouble *v ) { + return glVertex4dv(v); +} + +static void AmiglVertex4fv( GLfloat *v ) { + return glVertex4fv(v); +} + +static void AmiglVertex4iv( GLint *v ) { + return glVertex4iv(v); +} + +static void AmiglVertex4sv( GLshort *v ) { + return glVertex4sv(v); +} + +static void AmiglNormal3b( GLbyte nx, GLbyte ny, GLbyte nz ) { + return glNormal3b(nx, ny, nz); +} + +static void AmiglNormal3d( GLdouble nx, GLdouble ny, GLdouble nz ) { + return glNormal3d(nx, ny, nz); +} + +static void AmiglNormal3f( GLfloat nx, GLfloat ny, GLfloat nz ) { + return glNormal3f(nx, ny, nz); +} + +static void AmiglNormal3i( GLint nx, GLint ny, GLint nz ) { + return glNormal3i(nx, ny, nz); +} + +static void AmiglNormal3s( GLshort nx, GLshort ny, GLshort nz ) { + return glNormal3s(nx, ny, nz); +} + +static void AmiglNormal3bv( const GLbyte *v ) { + return glNormal3bv(v); +} + +static void AmiglNormal3dv( const GLdouble *v ) { + return glNormal3dv(v); +} + +static void AmiglNormal3fv( GLfloat *v ) { + return glNormal3fv(v); +} + +static void AmiglNormal3iv( const GLint *v ) { + return glNormal3iv(v); +} + +static void AmiglNormal3sv( const GLshort *v ) { + return glNormal3sv(v); +} + +static void AmiglColor3b( GLbyte red, GLbyte green, GLbyte blue ) { + return glColor3b(red, green, blue); +} + +static void AmiglColor3d( GLdouble red, GLdouble green, GLdouble blue ) { + return glColor3d(red, green, blue); +} + +static void AmiglColor3f( GLfloat red, GLfloat green, GLfloat blue ) { + return glColor3f(red, green, blue); +} + +static void AmiglColor3i( GLint red, GLint green, GLint blue ) { + return glColor3i(red, green, blue); +} + +static void AmiglColor3s( GLshort red, GLshort green, GLshort blue ) { + return glColor3s(red, green, blue); +} + +static void AmiglColor3ub( GLubyte red, GLubyte green, GLubyte blue ) { + return glColor3ub(red, green, blue); +} + +static void AmiglColor3ui( GLuint red, GLuint green, GLuint blue ) { + return glColor3ui(red, green, blue); +} + +static void AmiglColor3us( GLushort red, GLushort green, GLushort blue ) { + return glColor3us(red, green, blue); +} + +static void AmiglColor4b( GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha ) { + return glColor4b(red, green, blue, alpha); +} + +static void AmiglColor4d( GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha ) { + return glColor4d(red, green, blue, alpha); +} + +static void AmiglColor4f( GLfloat red, GLfloat green,GLfloat blue, GLfloat alpha ) { + return glColor4f(red, green, blue, alpha); +} + +static void AmiglColor4i( GLint red, GLint green, GLint blue, GLint alpha ) { + return glColor4i(red, green, blue, alpha); +} + +static void AmiglColor4s( GLshort red, GLshort green, GLshort blue, GLshort alpha ) { + return glColor4s(red, green, blue, alpha); +} + +static void AmiglColor4ub( GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha ) { + return glColor4ub(red, green, blue, alpha); +} + +static void AmiglColor4ui( GLuint red, GLuint green, GLuint blue, GLuint alpha ) { + return glColor4ui(red, green, blue, alpha); +} + +static void AmiglColor4us( GLushort red, GLushort green, GLushort blue, GLushort alpha ) { + return glColor4us(red, green, blue, alpha); +} + +static void AmiglColor3bv( const GLbyte *v ) { + return glColor3bv(v); +} + +static void AmiglColor3dv( const GLdouble *v ) { + return glColor3dv(v); +} + +static void AmiglColor3fv( GLfloat *v ) { + return glColor3fv(v); +} + +static void AmiglColor3iv( const GLint *v ) { + return glColor3iv(v); +} + +static void AmiglColor3sv( const GLshort *v ) { + return glColor3sv(v); +} + +static void AmiglColor3ubv( GLubyte *v ) { + return glColor3ubv(v); +} + +static void AmiglColor3uiv( const GLuint *v ) { + return glColor3uiv(v); +} + +static void AmiglColor3usv( const GLushort *v ) { + glColor3usv(v); +} + +static void AmiglColor4bv( const GLbyte *v ) { + return glColor4bv(v); +} + +static void AmiglColor4dv( const GLdouble *v ) { + return glColor4dv(v); +} + +static void AmiglColor4fv( GLfloat *v ) { + return glColor4fv(v); +} + +static void AmiglColor4iv( const GLint *v ) { + return glColor4iv(v); +} + +static void AmiglColor4sv( const GLshort *v ) { + return glColor4sv(v); +} + +static void AmiglColor4ubv( GLubyte *v ) { + return glColor4ubv(v); +} + +static void AmiglColor4uiv( const GLuint *v ) { + return glColor4uiv(v); +} + +static void AmiglColor4usv( const GLushort *v ) { + return glColor4usv(v); +} + +static void AmiglTexCoord1d( GLdouble s ) { + return glTexCoord1d(s); +} + +static void AmiglTexCoord1f( GLfloat s ) { + return glTexCoord1f(s); +} + +static void AmiglTexCoord1i( GLint s ) { + return glTexCoord1i(s); +} + +static void AmiglTexCoord2d( GLdouble s, GLdouble t ) { + return glTexCoord2d(s, t); +} + +static void AmiglTexCoord2f( GLfloat s, GLfloat t ) { + return glTexCoord2f(s, t); +} + +static void AmiglTexCoord2i( GLint s, GLint t ) { + return glTexCoord2i(s, t); +} + +static void AmiglTexCoord3f( GLfloat s, GLfloat t, GLfloat r ) { + return glTexCoord3f(s, t, r); +} + +static void AmiglTexCoord4f( GLfloat s, GLfloat t, GLfloat r, GLfloat q ) { + return glTexCoord4f(s, t, r, q); +} + +static void AmiglTexCoord2fv( GLfloat *v ) { + return glTexCoord2fv(v); +} + +static void AmiglTexCoord2iv( const GLint *v ) { + return glTexCoord2iv(v); +} + +static void AmiglTexCoord3fv( GLfloat *v ) { + return glTexCoord3fv(v); +} + +static void AmiglTexCoord4fv( GLfloat *v ) { + return glTexCoord4fv(v); +} + +static void AmiglClientActiveTextureARB(GLenum texture) { + return glClientActiveTextureARB(texture); +} + +static void AmiglActiveTextureARB(GLenum unit) { + return glActiveTextureARB(unit); +} + +static void AmiglMultiTexCoord2f(GLenum unit, GLfloat s, GLfloat t) { + return glMultiTexCoord2f(unit, s, t); +} + +static void AmiglMultiTexCoord2fv(GLenum unit, GLfloat *v) { + return glMultiTexCoord2fv(unit, v); +} + +static void AmiglMultiTexCoord4f(GLenum unit, GLfloat s, GLfloat t, GLfloat r, GLfloat q) { + return glMultiTexCoord4f(unit, s, t, r, q); +} + +static void AmiglMultiTexCoord4fv(GLenum unit, GLfloat *v) { + return glMultiTexCoord4fv(unit, v); +} + +static void AmiglMultiTexCoord2fARB(GLenum unit, GLfloat s, GLfloat t) { + return glMultiTexCoord2fARB(unit, s, t); +} + +static void AmiglMultiTexCoord2fvARB(GLenum unit, GLfloat *v) { + return glMultiTexCoord2fvARB(unit, v); +} + +static void AmiglMultiTexCoord4fARB(GLenum unit, GLfloat s, GLfloat t, GLfloat r, GLfloat q) { + return glMultiTexCoord4fARB(unit, s, t, r, q); +} + +static void AmiglMultiTexCoord4fvARB(GLenum unit, GLfloat *v) { + return glMultiTexCoord4fvARB(unit, v); +} + +static void AmiglRasterPos2d( GLdouble x, GLdouble y ) { + return glRasterPos2d(x, y); +} + +static void AmiglRasterPos2f( GLfloat x, GLfloat y ) { + return glRasterPos2f(x, y); +} + +static void AmiglRasterPos2i( GLint x, GLint y ) { + return glRasterPos2i(x, y); +} + +static void AmiglRasterPos2s( GLshort x, GLshort y ) { + return glRasterPos2s(x, y); +} + +static void AmiglRasterPos3d( GLdouble x, GLdouble y, GLdouble z ) { + return glRasterPos3d(x, y, z); +} + +static void AmiglRasterPos3f( GLfloat x, GLfloat y, GLfloat z ) { + return glRasterPos3f(x, y, z); +} + +static void AmiglRasterPos3i( GLint x, GLint y, GLint z ) { + return glRasterPos3i(x, y, z); +} + +static void AmiglRasterPos3s( GLshort x, GLshort y, GLshort z ) { + return glRasterPos3s(x, y, z); +} + +static void AmiglRasterPos4d( GLdouble x, GLdouble y, GLdouble z, GLdouble w ) { + return glRasterPos4d(x, y, z, w); +} + +static void AmiglRasterPos4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w ) { + return glRasterPos4f(x, y, z, w); +} + +static void AmiglRasterPos4i( GLint x, GLint y, GLint z, GLint w ) { + return glRasterPos4i(x, y, z, w); +} + +static void AmiglRasterPos4s( GLshort x, GLshort y, GLshort z, GLshort w ) { + return glRasterPos4s(x, y, z, w); +} + +static void AmiglRasterPos2dv( GLdouble *v ) { + return glRasterPos2dv(v); +} + +static void AmiglRasterPos2fv( GLfloat *v ) { + return glRasterPos2fv((GLfloat *)v); +} + +static void AmiglRasterPos2iv( GLint *v ) { + return glRasterPos2iv(v); +} + +static void AmiglRasterPos2sv( GLshort *v ) { + return glRasterPos2sv(v); +} + +static void AmiglRasterPos3dv( GLdouble *v ) { + return glRasterPos3dv(v); +} + +static void AmiglRasterPos3fv( GLfloat *v ) { + return glRasterPos3fv((GLfloat *)v); +} + +static void AmiglRasterPos3iv( GLint *v ) { + return glRasterPos3iv(v); +} + +static void AmiglRasterPos3sv( GLshort *v ) { + return glRasterPos3sv(v); +} + +static void AmiglRasterPos4dv( GLdouble *v ) { + return glRasterPos4dv(v); +} + +static void AmiglRasterPos4fv( GLfloat *v ) { + return glRasterPos4fv(v); +} + +static void AmiglRasterPos4iv( GLint *v ) { + return glRasterPos4iv(v); +} + +static void AmiglRasterPos4sv( GLshort *v ) { + return glRasterPos4sv(v); +} + +static void AmiglRectd( GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2 ) { + return glRectd(x1, y1, x2, y2); +} + +static void AmiglRectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ) { + return glRectf(x1, y1, x2, y2); +} + +static void AmiglRecti( GLint x1, GLint y1, GLint x2, GLint y2 ) { + return glRecti(x1, y1, x2, y2); +} + +static void AmiglRects( GLshort x1, GLshort y1, GLshort x2, GLshort y2 ) { + return glRects(x1, y1, x2, y2); +} + +static void AmiglRectdv( GLdouble *v1, GLdouble *v2 ) { + return glRectdv(v1, v2); +} + +static void AmiglRectfv( GLfloat *v1, GLfloat *v2 ) { + return glRectfv(v1, v2); +} + +static void AmiglRectiv( GLint *v1, GLint *v2 ) { + return glRectiv(v1, v2); +} + +static void AmiglRectsv( GLshort *v1, GLshort *v2 ) { + return glRectsv(v1, v2); +} + +static void AmiglVertexPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *ptr ) { + return glVertexPointer(size, type, stride, ptr); +} + +static void AmiglNormalPointer( GLenum type, GLsizei stride, const GLvoid *ptr ) { + return glNormalPointer(type, stride, ptr); +} + +static void AmiglColorPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *ptr ) { + return glColorPointer(size, type, stride, ptr); +} + +static void AmiglTexCoordPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *ptr ) { + return glTexCoordPointer(size, type, stride, ptr); +} + +static void AmiglArrayElement( GLint i ) { + return glArrayElement(i); +} + +static void AmiglDrawArrays( GLenum mode, GLint first, GLsizei count ) { + return glDrawArrays(mode, first, count); +} + +static void AmiglDrawElements( GLenum mode, GLsizei count, GLenum type, GLvoid *indices ) { + return glDrawElements(mode, count, type, indices); +} + +static void AmiglInterleavedArrays( GLenum format, GLsizei stride, const GLvoid *pointer ) { + return glInterleavedArrays(format, stride, pointer); +} + +static void AmiglShadeModel( GLenum mode ) { + return glShadeModel(mode); +} + +static void AmiglLightf( GLenum light, GLenum pname, GLfloat param ) { + return glLightf(light, pname, param); +} + +static void AmiglLighti( GLenum light, GLenum pname, GLint param ) { + return glLighti(light, pname, param); +} + +static void AmiglLightfv( GLenum light, GLenum pname, GLfloat *params ) { + return glLightfv(light, pname, params); +} + +static void AmiglLightiv( GLenum light, GLenum pname, const GLint *params ) { + return glLightiv(light, pname, params); +} + +static void AmiglGetLightfv( GLenum light, GLenum pname, GLfloat *params ) { + return glGetLightfv(light, pname, params); +} + +static void AmiglGetLightiv( GLenum light, GLenum pname, GLint *params ) { + return glGetLightiv(light, pname, params); +} + +static void AmiglLightModelf( GLenum pname, GLfloat param ) { + return glLightModelf(pname, param); +} + +static void AmiglLightModeli( GLenum pname, GLint param ) { + return glLightModeli(pname, param); +} + +static void AmiglLightModelfv( GLenum pname, GLfloat *params ) { + return glLightModelfv(pname, params); +} + +static void AmiglLightModeliv( GLenum pname, const GLint *params ) { + return glLightModeliv(pname, params); +} + +static void AmiglMaterialf( GLenum face, GLenum pname, GLfloat param ) { + return glMaterialf(face, pname, param); +} + +static void AmiglMateriali( GLenum face, GLenum pname, GLint param ) { + return glMateriali(face, pname, param); +} + +static void AmiglMaterialfv( GLenum face, GLenum pname, GLfloat *params ) { + return glMaterialfv(face, pname, params); +} + +static void AmiglMaterialiv( GLenum face, GLenum pname, const GLint *params ) { + return glMaterialiv(face, pname, params); +} + +static void AmiglGetMaterialfv( GLenum face, GLenum pname, GLfloat *params ) { + return glGetMaterialfv(face, pname, params); +} + +static void AmiglGetMaterialiv( GLenum face, GLenum pname, GLint *params ) { + return glGetMaterialiv(face, pname, params); +} + +static void AmiglColorMaterial( GLenum face, GLenum mode ) { + return glColorMaterial(face, mode); +} + +static void AmiglPixelZoom( GLfloat xfactor, GLfloat yfactor ) { + return glPixelZoom(xfactor, yfactor); +} + +static void AmiglPixelStoref( GLenum pname, GLfloat param ) { + return glPixelStoref(pname, param); +} + +static void AmiglPixelStorei( GLenum pname, GLint param ) { + return glPixelStorei(pname, param); +} + +static void AmiglPixelTransferf( GLenum pname, GLfloat param ) { + return glPixelTransferf(pname, param); +} + +static void AmiglPixelTransferi( GLenum pname, GLint param ) { + return glPixelTransferi(pname, param); +} + +static void AmiglBitmap( GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap ) { + return glBitmap(width, height, xorig, yorig, xmove, ymove, bitmap); +} + +static void AmiglReadPixels( GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels ) { + return glReadPixels(x, y, width, height, format, type, pixels); +} + +static void AmiglDrawPixels( GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels ) { + return glDrawPixels(width, height, format, type, pixels); +} + +static void AmiglCopyPixels( GLint x, GLint y, GLsizei width, GLsizei height, GLenum type ) { + return glCopyPixels(x, y, width, height, type); +} + +static void AmiglStencilFunc( GLenum func, GLint ref, GLuint mask ) { + return glStencilFunc(func, ref, mask); +} + +static void AmiglStencilMask( GLuint mask ) { + return glStencilMask(mask); +} + +static void AmiglStencilOp( GLenum fail, GLenum zfail, GLenum zpass ) { + return glStencilOp(fail, zfail, zpass); +} + +static void AmiglClearStencil( GLint s ) { + return glClearStencil(s); +} + +static void AmiglTexGeni( GLenum coord, GLenum pname, GLint param ) { + return glTexGeni(coord, pname, param); +} + +static void AmiglTexGenfv( GLenum coord, GLenum pname, GLfloat *params ) { + return glTexGenfv(coord, pname, params); +} + +static void AmiglTexEnvf( GLenum target, GLenum pname, GLfloat param ) { + return glTexEnvf(target, pname, param); +} + +static void AmiglTexEnvi( GLenum target, GLenum pname, GLint param ) { + return glTexEnvi(target, pname, param); +} + +static void AmiglTexEnvfv( GLenum target, GLenum pname, const GLfloat *params ) { + return glTexEnvfv(target, pname, params); +} + +static void AmiglTexEnviv( GLenum target, GLenum pname, GLint *params ) { + return glTexEnviv(target, pname, params); +} + +static void AmiglGetTexEnviv( GLenum target, GLenum pname, GLint *params ) { + return glGetTexEnviv(target, pname, params); +} + +static void AmiglTexParameterf( GLenum target, GLenum pname, GLfloat param ) { + return glTexParameterf(target, pname, param); +} + +static void AmiglTexParameteri( GLenum target, GLenum pname, GLint param ) { + return glTexParameteri(target, pname, param); +} + +static void AmiglTexParameterfv( GLenum target, GLenum pname, GLfloat *params ) { + return glTexParameterfv(target, pname, params); +} + +static void AmiglTexParameteriv( GLenum target, GLenum pname, GLint *params ) { + return glTexParameteriv(target, pname, params); +} + +static void AmiglGetTexParameterfv( GLenum target, GLenum pname, GLfloat *params) { + return glGetTexParameterfv(target, pname, params); +} + +static void AmiglGetTexParameteriv( GLenum target, GLenum pname, GLint *params ) { + return glGetTexParameteriv(target, pname, params); +} + +static void AmiglGetTexLevelParameterfv( GLenum target, GLint level, GLenum pname, GLfloat *params ) { + return glGetTexLevelParameterfv(target, level, pname, params); +} + +static void AmiglGetTexLevelParameteriv( GLenum target, GLint level, GLenum pname, GLint *params ) { + return glGetTexLevelParameteriv(target, level, pname, params); +} + +static void AmiglTexImage1D( GLenum target, GLint level, GLint internalFormat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels ) { + return glTexImage1D(target, level, internalFormat, width, border, format, type, pixels); +} + +static void AmiglTexImage2D( GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLvoid *pixels ) { + return glTexImage2D(target, level, internalFormat, width, height, border, format, type, pixels); +} + +static void AmiglGetTexImage( GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels ) { + return glGetTexImage(target, level, format, type, pixels); +} + +static void AmiglGenTextures( GLsizei n, GLuint *textures ) { + return glGenTextures(n, textures); +} + +static void AmiglDeleteTextures( GLsizei n, const GLuint *textures) { + return glDeleteTextures(n, textures); +} + +static void AmiglBindTexture( GLenum target, GLuint texture ) { + return glBindTexture(target, texture); +} + +static void AmiglPrioritizeTextures( GLsizei n, const GLuint *textures, const GLclampf *priorities ) { + return glPrioritizeTextures(n, textures, priorities); +} + +static GLboolean AmiglAreTexturesResident( GLsizei n, GLuint *textures, GLboolean *residences ) { + return glAreTexturesResident(n, textures, residences); +} + +static GLboolean AmiglIsTexture( GLuint texture ) { + return glIsTexture(texture); +} + +static void AmiglTexSubImage1D( GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels ) { + return glTexSubImage1D(target, level, xoffset, width, format, type, pixels); +} + +static void AmiglTexSubImage2D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels ) { + return glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); +} + +static void AmiglCopyTexImage1D( GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border ) { + return glCopyTexImage1D(target, level, internalformat, x, y, width, border); +} + +static void AmiglCopyTexImage2D( GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border ) { + return glCopyTexImage2D(target, level, internalformat, x, y, width, height, border); +} + +static void AmiglCopyTexSubImage1D( GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width ) { + return glCopyTexSubImage1D(target, level, xoffset, x, y, width); +} + +static void AmiglCopyTexSubImage2D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height ) { + return glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); +} + +static void AmiglMap1d( GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points ) { + return glMap1d(target, u1, u2, stride, order, points); +} + +static void AmiglMap1f( GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points ) { + return glMap1f(target, u1, u2, stride, order, points); +} + +static void AmiglMap2d( GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points ) { + return glMap2d(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points); +} + +static void AmiglMap2f( GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points ) { + return glMap2f(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points); + } + +static void AmiglGetMapdv( GLenum target, GLenum query, GLdouble *v ) { + return glGetMapdv(target, query, v); +} + +static void AmiglGetMapfv( GLenum target, GLenum query, GLfloat *v ) { + return glGetMapfv(target, query, v); +} + +static void AmiglGetMapiv( GLenum target, GLenum query, GLint *v ) { + return glGetMapiv(target, query, v); +} + +static void AmiglEvalCoord1d( GLdouble u ) { + return glEvalCoord1d(u); +} + +static void AmiglEvalCoord1f( GLfloat u ) { + return glEvalCoord1f(u); +} + +static void AmiglEvalCoord1dv( GLdouble *u ) { + return glEvalCoord1dv(u); +} + +static void AmiglEvalCoord1fv( GLfloat *u ) { + return glEvalCoord1fv(u); +} + +static void AmiglEvalCoord2d( GLdouble u, GLdouble v ) { + return glEvalCoord2d(u, v); +} + +static void AmiglEvalCoord2f( GLfloat u, GLfloat v ) { + return glEvalCoord2f(u, v); +} + +static void AmiglEvalCoord2dv( GLdouble *u ) { + return glEvalCoord2dv(u); +} + +static void AmiglEvalCoord2fv( GLfloat *u ) { + return glEvalCoord2fv(u); +} + +static void AmiglMapGrid1d( GLint un, GLdouble u1, GLdouble u2 ) { + return glMapGrid1d(un, u1, u2); +} + +static void AmiglMapGrid1f( GLint un, GLfloat u1, GLfloat u2 ) { + return glMapGrid1f(un, u1, u2); +} + +static void AmiglMapGrid2d( GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2 ) { + return glMapGrid2d(un, u1, u2, vn, v1, v2); +} + +static void AmiglMapGrid2f( GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2 ) { + return glMapGrid2f(un, u1, u2, vn, v1, v2); +} + +static void AmiglEvalPoint1( GLint i ) { + return glEvalPoint1(i); +} + +static void AmiglEvalPoint2( GLint i, GLint j ) { + return glEvalPoint2(i, j); +} + +static void AmiglEvalMesh1( GLenum mode, GLint i1, GLint i2 ) { + return glEvalMesh1(mode, i1, i2); +} + +static void AmiglEvalMesh2( GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 ) { + return glEvalMesh2(mode, i1, i2, j1, j2); +} + +static void AmiglFogf( GLenum pname, GLfloat param ) { + return glFogf(pname, param); +} + +static void AmiglFogi( GLenum pname, GLint param ) { + return glFogi(pname, param); +} + +static void AmiglFogfv( GLenum pname, GLfloat *params ) { + return glFogfv(pname, params); +} + +static void AmiglSelectBuffer( GLsizei size, GLuint *buffer ) { + return glSelectBuffer(size, buffer); +} + +static void AmiglInitNames( void ) { + return glInitNames(); +} + +static void AmiglLoadName( GLuint name ) { + return glLoadName(name); +} + +static void AmiglPushName( GLuint name ) { + return glPushName(name); +} + +static void AmiglPopName( void ) { + return glPopName(); +} + +static void AmiglDrawRangeElements( GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, GLvoid *indices ) { + return glDrawRangeElements(mode, start, end, count, type, indices); +} + +static void AmiglLockArraysEXT( GLint first, GLint count ) { + return glLockArraysEXT(first, count); +} + +static void AmiglUnlockArraysEXT( void ) { + return glUnlockArraysEXT(); +} + +/* The GLU API */ + +/* + * + * GLU + * + */ + +static void AmigluLookAt( GLdouble eyex, GLdouble eyey, GLdouble eyez, GLdouble centerx, GLdouble centery, GLdouble centerz, GLdouble upx, GLdouble upy, GLdouble upz ) { + return gluLookAt(eyex, eyey, eyez, centerx, centery, centerz, upx, upy, upz); +} + +static void AmigluOrtho2D( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top ) { + return gluOrtho2D(left, right, bottom, top); +} + +static void AmigluPerspective( GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar ) { + return gluPerspective(fovy, aspect, zNear, zFar); +} + +static void AmigluPickMatrix( GLdouble x, GLdouble y, GLdouble width, GLdouble height, const GLint viewport[4] ) { + return gluPickMatrix(x, y, width, height, (GLint *)viewport); +} + +static GLint AmigluProject( GLdouble objx, GLdouble objy, GLdouble objz, const GLdouble modelMatrix[16], const GLdouble projMatrix[16], const GLint viewport[4], GLdouble *winx, GLdouble *winy, GLdouble *winz ) { + return gluProject(objx, objy, objz, modelMatrix, projMatrix, viewport, winx, winy, winz); +} + +static GLint AmigluUnProject( GLdouble winx, GLdouble winy, GLdouble winz, const GLdouble modelMatrix[16], const GLdouble projMatrix[16], const GLint viewport[4], GLdouble *objx, GLdouble *objy, GLdouble *objz ) { + return gluUnProject(winx, winy, winz, modelMatrix, projMatrix, viewport, objx, objy, objz); +} + +static const GLubyte* AmigluErrorString( GLenum errorCode ) { + return gluErrorString(errorCode); +} + +static GLint AmigluScaleImage( GLenum format, GLint widthin, GLint heightin, GLenum typein, const void *datain, GLint widthout, GLint heightout, GLenum typeout, void *dataout ) { + return gluScaleImage(format, widthin, heightin, typein, datain, widthout, heightout, typeout, dataout); +} + +#if 0 +static GLint AmigluBuild1DMipmaps( GLenum target, GLint components, GLint width, GLenum format, GLenum type, const void *data ) { +#ifndef __amigaos4__ + return gluBuild1DMipmaps(target, components, width, format, type, data); +#else + return 0; +#endif +} +#endif + +static GLint AmigluBuild2DMipmaps( GLenum target, GLint components, GLint width, GLint height, GLenum format, GLenum type, void *data ) { + return gluBuild2DMipmaps(target, components, width, height, format, type, data); +} + +static GLUquadricObj* AmigluNewQuadric( void ) { + return gluNewQuadric(); +} + +static void AmigluDeleteQuadric( GLUquadricObj *state ) { + return gluDeleteQuadric(state); +} + +static void AmigluQuadricDrawStyle( GLUquadricObj *quadObject, GLenum drawStyle ) { + return gluQuadricDrawStyle(quadObject, drawStyle); +} + +static void AmigluQuadricOrientation( GLUquadricObj *quadObject, GLenum orientation ) { + return gluQuadricOrientation(quadObject, orientation); +} + +static void AmigluQuadricNormals( GLUquadricObj *quadObject, GLenum normals ) { + return gluQuadricNormals(quadObject, normals); +} + +static void AmigluQuadricTexture( GLUquadricObj *quadObject, GLboolean textureCoords ) { + return gluQuadricTexture(quadObject, textureCoords); +} + +static void AmigluQuadricCallback( GLUquadricObj *qobj, GLenum which, void *fn) { + return gluQuadricCallback(qobj, which, fn); +} + +static void AmigluCylinder( GLUquadricObj *qobj, GLdouble baseRadius, GLdouble topRadius, GLdouble height, GLint slices, GLint stacks ) { + return gluCylinder(qobj, baseRadius, topRadius, height, slices, stacks); +} + +static void AmigluSphere( GLUquadricObj *qobj, GLdouble radius, GLint slices, GLint stacks ) { + return gluSphere(qobj, radius, slices, stacks); +} + +static void AmigluDisk( GLUquadricObj *qobj, GLdouble innerRadius, GLdouble outerRadius, GLint slices, GLint loops ) { + return gluDisk(qobj, innerRadius, outerRadius, slices, loops); +} + +static void AmigluPartialDisk( GLUquadricObj *qobj, GLdouble innerRadius, GLdouble outerRadius, GLint slices, GLint loops, GLdouble startAngle, GLdouble sweepAngle ) { + return gluPartialDisk(qobj, innerRadius, outerRadius, slices, loops, startAngle, sweepAngle); +} + +static GLUnurbsObj* AmigluNewNurbsRenderer( void ) { + return gluNewNurbsRenderer(); +} + +static void AmigluDeleteNurbsRenderer( GLUnurbsObj *nobj ) { + return gluDeleteNurbsRenderer(nobj); +} + +static void AmigluLoadSamplingMatrices( GLUnurbsObj *nobj, const GLfloat modelMatrix[16], const GLfloat projMatrix[16], const GLint viewport[4] ) { + return gluLoadSamplingMatrices(nobj, modelMatrix, projMatrix, viewport); +} + +static void AmigluNurbsProperty( GLUnurbsObj *nobj, GLenum property, GLfloat value ) { + return gluNurbsProperty(nobj, property, value); +} + +static void AmigluGetNurbsProperty( GLUnurbsObj *nobj, GLenum property, GLfloat *value ) { + return gluGetNurbsProperty(nobj, property, value); +} + +static void AmigluBeginCurve( GLUnurbsObj *nobj ) { + return gluBeginCurve(nobj); +} + +static void AmigluEndCurve( GLUnurbsObj * nobj ) { + return gluEndCurve(nobj); +} + +static void AmigluNurbsCurve( GLUnurbsObj *nobj, GLint nknots, GLfloat *knot, GLint stride, GLfloat *ctlarray, GLint order, GLenum type ) { + return gluNurbsCurve(nobj, nknots, knot, stride, ctlarray, order, type); +} + +static void AmigluBeginSurface( GLUnurbsObj *nobj ) { + return gluBeginSurface(nobj); +} + +static void AmigluEndSurface( GLUnurbsObj * nobj ) { + return gluEndSurface(nobj); +} + +static void AmigluNurbsSurface( GLUnurbsObj *nobj, GLint sknot_count, GLfloat *sknot, GLint tknot_count, GLfloat *tknot, GLint s_stride, GLint t_stride, GLfloat *ctlarray, GLint sorder, GLint torder, GLenum type ) { + return gluNurbsSurface(nobj, sknot_count, sknot, tknot_count, tknot, s_stride, t_stride, ctlarray, sorder, torder, type); +} + +static void AmigluBeginTrim( GLUnurbsObj *nobj ) { + return gluBeginTrim(nobj); +} + +static void AmigluEndTrim( GLUnurbsObj *nobj ) { + return gluEndTrim(nobj); +} + +static void AmigluPwlCurve( GLUnurbsObj *nobj, GLint count, GLfloat *array, GLint stride, GLenum type ) { + return gluPwlCurve(nobj, count, array, stride, type); +} + +static void AmigluNurbsCallback( GLUnurbsObj *nobj, GLenum which, void *fn ) { + return gluNurbsCallback(nobj, which, fn); +} + +static GLUtriangulatorObj* AmigluNewTess( void ) { + return gluNewTess(); +} + +static void AmigluTessCallback( GLUtriangulatorObj *tobj, GLenum which, void *fn ) { + return gluTessCallback(tobj, which, fn); +} + +static void AmigluDeleteTess( GLUtriangulatorObj *tobj ) { + return gluDeleteTess(tobj); +} + +static void AmigluBeginPolygon( GLUtriangulatorObj *tobj ) { + return gluBeginPolygon(tobj); +} + +static void AmigluEndPolygon( GLUtriangulatorObj *tobj ) { + return gluEndPolygon(tobj); +} + +static void AmigluNextContour( GLUtriangulatorObj *tobj, GLenum type ) { + return gluNextContour(tobj, type); +} + +static void AmigluTessVertex( GLUtriangulatorObj *tobj, GLdouble v[3], void *data ) { + return gluTessVertex(tobj, v, data); +} + +static void AmigluTessProperty(GLUtesselator* tess, GLenum which, GLdouble data) { + return gluTessProperty(tess, which, data); +} + +static void AmigluTessNormal(GLUtesselator* tess, GLdouble X, GLdouble Y, GLdouble Z) { + return gluTessNormal(tess, X, Y, Z); +} + +static void AmigluGetTessProperty(GLUtesselator* tess, GLenum which, GLdouble* data) { + return gluGetTessProperty(tess, which, data); +} + +static void AmigluTessBeginPolygon(GLUtesselator* tess, GLvoid* data) { + return gluTessBeginPolygon(tess, data); +} + +static void AmigluTessEndPolygon(GLUtesselator* tess) { + return gluTessEndPolygon(tess); +} + +static void AmigluTessBeginContour(GLUtesselator* tess) { + return gluTessBeginContour(tess); +} + +static void AmigluTessEndContour(GLUtesselator* tess) { + return gluTessEndContour(tess); +} + +static GLint AmigluBuild2DMipmapLevels(GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint level, GLint base, GLint max, const void *data) { + return gluBuild2DMipmapLevels(target, internalFormat, width, height, format, type, level, base, max, data); +} + +static GLint AmigluUnProject4(GLdouble winX, GLdouble winY, GLdouble winZ, GLdouble clipW, const GLdouble *model, const GLdouble *proj, const GLint *view, GLdouble nearVal, GLdouble farVal, GLdouble* objX, GLdouble* objY, GLdouble* objZ, GLdouble* objW) { + return gluUnProject4(winX, winY, winZ, clipW, model, proj, view, nearVal, farVal, objX, objY, objZ, objW); +} + +static GLboolean AmigluCheckExtension(const GLubyte *extName, const GLubyte *extString) { + return gluCheckExtension(extName, extString); +} + +static const GLubyte* AmigluGetString( GLenum name ) { + return gluGetString(name); +} + +static void AmigluNurbsCallbackData (GLUnurbs* r, void* userData) { + return gluNurbsCallbackData (r, userData); +} + +static void AmigluNurbsCallbackDataEXT(GLUnurbs* nurb, GLvoid* userData) { + return gluNurbsCallbackDataEXT(nurb, userData); +} + +#ifdef NOT_IMPLEMENTED_FUNCS + #include "SDL_os4_notimplemented_funcs.t" +#endif + +struct MyGLFunc +{ + CONST_STRPTR name; + APTR func; +}; + +void *AmiGetGLProc(const char *proc) +{ + static CONST struct MyGLFunc table[] = { + {"glClipPlane", AmiglClipPlane}, + {"glPolygonOffset", AmiglPolygonOffset}, + {"glTexEnviv", AmiglTexEnviv}, + {"glTexEnvfv", AmiglTexEnvfv}, + {"glGetTexEnviv", AmiglGetTexEnviv}, + {"glGetBooleanv", AmiglGetBooleanv}, + {"glGetIntegerv", AmiglGetIntegerv}, + {"glIsEnabled", AmiglIsEnabled}, + {"glAlphaFunc", AmiglAlphaFunc}, + {"glBegin", AmiglBegin}, + {"glBindTexture", AmiglBindTexture}, + {"glBlendFunc", AmiglBlendFunc}, + {"glClear", AmiglClear}, + {"glClearColor", AmiglClearColor}, + {"glClearDepth", AmiglClearDepth}, + {"glColor3b", AmiglColor3b}, + {"glColor3ub", AmiglColor3ub}, + {"glColor3bv", AmiglColor3bv}, + {"glColor3ubv", AmiglColor3ubv}, + {"glColor3s", AmiglColor3s}, + {"glColor3us", AmiglColor3us}, + {"glColor3sv", AmiglColor3sv}, + {"glColor3usv", AmiglColor3usv}, + {"glColor3i", AmiglColor3i}, + {"glColor3ui", AmiglColor3ui}, + {"glColor3iv", AmiglColor3iv}, + {"glColor3uiv", AmiglColor3uiv}, + {"glColor3f", AmiglColor3f}, + {"glColor3fv", AmiglColor3fv}, + {"glColor3d", AmiglColor3d}, + {"glColor3dv", AmiglColor3dv}, + {"glColor4b", AmiglColor4b}, + {"glColor4ub", AmiglColor4ub}, + {"glColor4bv", AmiglColor4bv}, + {"glColor4ubv", AmiglColor4ubv}, + {"glColor4s", AmiglColor4s}, + {"glColor4us", AmiglColor4us}, + {"glColor4sv", AmiglColor4sv}, + {"glColor4usv", AmiglColor4usv}, + {"glColor4i", AmiglColor4i}, + {"glColor4ui", AmiglColor4ui}, + {"glColor4iv", AmiglColor4iv}, + {"glColor4uiv", AmiglColor4uiv}, + {"glColor4f", AmiglColor4f}, + {"glColor4fv", AmiglColor4fv}, + {"glColor4d", AmiglColor4d}, + {"glColor4dv", AmiglColor4dv}, + {"glCullFace", AmiglCullFace}, + {"glVertex2s", AmiglVertex2s}, + {"glVertex2i", AmiglVertex2i}, + {"glVertex2f", AmiglVertex2f}, + {"glVertex2d", AmiglVertex2d}, + {"glVertex3s", AmiglVertex3s}, + {"glVertex3i", AmiglVertex3i}, + {"glVertex3f", AmiglVertex3f}, + {"glVertex3d", AmiglVertex3d}, + {"glVertex4s", AmiglVertex4s}, + {"glVertex4i", AmiglVertex4i}, + {"glVertex4f", AmiglVertex4f}, + {"glVertex4d", AmiglVertex4d}, + {"glVertex2sv", AmiglVertex2sv}, + {"glVertex2iv", AmiglVertex2iv}, + {"glVertex2fv", AmiglVertex2fv}, + {"glVertex2dv", AmiglVertex2dv}, + {"glVertex3sv", AmiglVertex3sv}, + {"glVertex3iv", AmiglVertex3iv}, + {"glVertex3fv", AmiglVertex3fv}, + {"glVertex3dv", AmiglVertex3dv}, + {"glVertex4sv", AmiglVertex4sv}, + {"glVertex4iv", AmiglVertex4iv}, + {"glVertex4fv", AmiglVertex4fv}, + {"glVertex4dv", AmiglVertex4dv}, + {"glDeleteTextures", AmiglDeleteTextures}, + {"glDepthFunc", AmiglDepthFunc}, + {"glDepthMask", AmiglDepthMask}, + {"glDepthRange", AmiglDepthRange}, + {"glDisable", AmiglDisable}, + {"glDrawBuffer", AmiglDrawBuffer}, + {"glEnable", AmiglEnable}, + {"glEnd", AmiglEnd}, + {"glFinish", AmiglFinish}, + {"glFlush", AmiglFlush}, + {"glFogf", AmiglFogf}, + {"glFogi", AmiglFogi}, + {"glFogfv", AmiglFogfv}, + {"glFrontFace", AmiglFrontFace}, + {"glFrustum", AmiglFrustum}, + {"glGenTextures", AmiglGenTextures}, + {"glGetError", AmiglGetError}, + {"glGetFloatv", AmiglGetFloatv}, + {"glGetString", AmiglGetString}, + {"glHint", AmiglHint}, + {"glLoadIdentity", AmiglLoadIdentity}, + {"glLoadMatrixd", AmiglLoadMatrixd}, + {"glLoadMatrixf", AmiglLoadMatrixf}, + {"glMatrixMode", AmiglMatrixMode}, + {"glMultMatrixd", AmiglMultMatrixd}, + {"glMultMatrixf", AmiglMultMatrixf}, + {"glNormal3f", AmiglNormal3f}, + {"glNormal3d", AmiglNormal3d}, + {"glNormal3i", AmiglNormal3i}, + {"glNormal3s", AmiglNormal3s}, + {"glNormal3b", AmiglNormal3b}, + {"glNormal3fv", AmiglNormal3fv}, + {"glNormal3dv", AmiglNormal3dv}, + {"glNormal3iv", AmiglNormal3iv}, + {"glNormal3sv", AmiglNormal3sv}, + {"glNormal3bv", AmiglNormal3bv}, + {"glOrtho", AmiglOrtho}, + {"glPixelStorei", AmiglPixelStorei}, + {"glPixelStoref", AmiglPixelStoref}, + {"glPolygonMode", AmiglPolygonMode}, + {"glPopMatrix", AmiglPopMatrix}, + {"glPushMatrix", AmiglPushMatrix}, + {"glReadPixels", AmiglReadPixels}, + {"glRectf", AmiglRectf}, + {"glRects", AmiglRects}, + {"glRecti", AmiglRecti}, + {"glRectd", AmiglRectd}, + {"glRectsv", AmiglRectsv}, + {"glRectiv", AmiglRectiv}, + {"glRectfv", AmiglRectfv}, + {"glRectdv", AmiglRectdv}, + {"glRotatef", AmiglRotatef}, + {"glRotated", AmiglRotated}, + {"glScalef", AmiglScalef}, + {"glScaled", AmiglScaled}, + {"glScissor", AmiglScissor}, + {"glShadeModel", AmiglShadeModel}, + {"glTexCoord1f", AmiglTexCoord1f}, + {"glTexCoord1d", AmiglTexCoord1d}, + {"glTexCoord1i", AmiglTexCoord1i}, + {"glTexCoord2f", AmiglTexCoord2f}, + {"glTexCoord2d", AmiglTexCoord2d}, + {"glTexCoord2i", AmiglTexCoord2i}, + {"glTexCoord2fv", AmiglTexCoord2fv}, + {"glTexCoord2iv", AmiglTexCoord2iv}, + {"glTexCoord3f", AmiglTexCoord3f}, + {"glTexCoord3fv", AmiglTexCoord3fv}, + {"glTexCoord4f", AmiglTexCoord4f}, + {"glTexCoord4fv", AmiglTexCoord4fv}, + {"glTexEnvf", AmiglTexEnvf}, + {"glTexEnvi", AmiglTexEnvi}, + {"glTexGeni", AmiglTexGeni}, + {"glTexGenfv", AmiglTexGenfv}, + {"glTexImage1D", AmiglTexImage1D}, + {"glTexImage2D", AmiglTexImage2D}, + {"glTexParameteri", AmiglTexParameteri}, + {"glTexParameterf", AmiglTexParameterf}, + {"glTexParameterfv", AmiglTexParameterfv}, + {"glTexParameteriv", AmiglTexParameteriv}, + {"glTexSubImage1D", AmiglTexSubImage1D}, + {"glTexSubImage2D", AmiglTexSubImage2D}, + {"glTranslated", AmiglTranslated}, + {"glTranslatef", AmiglTranslatef}, + {"glViewport", AmiglViewport}, + {"glColorTable", AmiglColorTable}, + {"glColorTableEXT", AmiglColorTableEXT}, + {"glEnableClientState", AmiglEnableClientState}, + {"glDisableClientState", AmiglDisableClientState}, + {"glClientActiveTexture", AmiglClientActiveTexture}, + {"glClientActiveTextureARB", AmiglClientActiveTextureARB}, + {"glTexCoordPointer", AmiglTexCoordPointer}, + {"glColorPointer", AmiglColorPointer}, + {"glNormalPointer", AmiglNormalPointer}, + {"glVertexPointer", AmiglVertexPointer}, + {"glInterleavedArrays", AmiglInterleavedArrays}, + {"glDrawElements", AmiglDrawElements}, + {"glDrawArrays", AmiglDrawArrays}, + {"glArrayElement", AmiglArrayElement}, + {"glLockArraysEXT", AmiglLockArraysEXT}, + {"glUnlockArraysEXT", AmiglUnlockArraysEXT}, + {"glPushAttrib", AmiglPushAttrib}, + {"glPopAttrib", AmiglPopAttrib}, + {"glActiveTextureARB", AmiglActiveTextureARB}, + {"glMultiTexCoord2fARB", AmiglMultiTexCoord2fARB}, + {"glMultiTexCoord2fvARB", AmiglMultiTexCoord2fvARB}, + {"glMultiTexCoord4fARB", AmiglMultiTexCoord4fARB}, + {"glMultiTexCoord4fvARB", AmiglMultiTexCoord4fvARB}, + {"glActiveTexture", AmiglActiveTexture}, + {"glMultiTexCoord2f", AmiglMultiTexCoord2f}, + {"glMultiTexCoord2fv", AmiglMultiTexCoord2fv}, + {"glMultiTexCoord4f", AmiglMultiTexCoord4f}, + {"glMultiTexCoord4fv", AmiglMultiTexCoord4fv}, + {"glMaterialf", AmiglMaterialf}, + {"glMateriali", AmiglMateriali}, + {"glMaterialfv", AmiglMaterialfv}, + {"glMaterialiv", AmiglMaterialiv}, + {"glGetMaterialiv", AmiglGetMaterialiv}, + {"glGetMaterialfv", AmiglGetMaterialfv}, + {"glLightf", AmiglLightf}, + {"glLighti", AmiglLighti}, + {"glLightfv", AmiglLightfv}, + {"glLightiv", AmiglLightiv}, + {"glLightModelf", AmiglLightModelf}, + {"glLightModeli", AmiglLightModeli}, + {"glLightModelfv", AmiglLightModelfv}, + {"glLightModeliv", AmiglLightModeliv}, + {"glColorMaterial", AmiglColorMaterial}, + {"glGetLightfv", AmiglGetLightfv}, + {"glGetLightiv", AmiglGetLightiv}, + {"glStencilOp", AmiglStencilOp}, + {"glStencilFunc", AmiglStencilFunc}, + {"glClearStencil", AmiglClearStencil}, + {"glStencilMask", AmiglStencilMask}, + {"glColorMask", AmiglColorMask}, + {"glLineWidth", AmiglLineWidth}, + {"glPointSize", AmiglPointSize}, + {"glBitmap", AmiglBitmap}, + {"glLineStipple", AmiglLineStipple}, + {"glPolygonStipple", AmiglPolygonStipple}, + {"glRasterPos2s", AmiglRasterPos2s}, + {"glRasterPos2i", AmiglRasterPos2i}, + {"glRasterPos2f", AmiglRasterPos2f}, + {"glRasterPos2d", AmiglRasterPos2d}, + {"glRasterPos3s", AmiglRasterPos3s}, + {"glRasterPos3i", AmiglRasterPos3i}, + {"glRasterPos3f", AmiglRasterPos3f}, + {"glRasterPos3d", AmiglRasterPos3d}, + {"glRasterPos4s", AmiglRasterPos4s}, + {"glRasterPos4i", AmiglRasterPos4i}, + {"glRasterPos4f", AmiglRasterPos4f}, + {"glRasterPos4d", AmiglRasterPos4d}, + {"glRasterPos2sv", AmiglRasterPos2sv}, + {"glRasterPos2iv", AmiglRasterPos2iv}, + {"glRasterPos2fv", AmiglRasterPos2fv}, + {"glRasterPos2dv", AmiglRasterPos2dv}, + {"glRasterPos3sv", AmiglRasterPos3sv}, + {"glRasterPos3iv", AmiglRasterPos3iv}, + {"glRasterPos3fv", AmiglRasterPos3fv}, + {"glRasterPos3dv", AmiglRasterPos3dv}, + {"glRasterPos4sv", AmiglRasterPos4sv}, + {"glRasterPos4iv", AmiglRasterPos4iv}, + {"glRasterPos4fv", AmiglRasterPos4fv}, + {"glRasterPos4dv", AmiglRasterPos4dv}, + {"glDrawPixels", AmiglDrawPixels}, + {"glCallList", AmiglCallList}, + {"glCallLists", AmiglCallLists}, + {"glDeleteLists", AmiglDeleteLists}, + {"glGenLists", AmiglGenLists}, + {"glNewList", AmiglNewList}, + {"glEndList", AmiglEndList}, + {"glIsList", AmiglIsList}, + {"glListBase", AmiglListBase}, + {"glGetDoublev", AmiglGetDoublev}, + {"glIsTexture", AmiglIsTexture}, + {"glAreTexturesResident", AmiglAreTexturesResident}, + {"glInitNames", AmiglInitNames}, + {"glLoadName", AmiglLoadName}, + {"glPushName", AmiglPushName}, + {"glPopName", AmiglPopName}, + {"glSelectBuffer", AmiglSelectBuffer}, + {"glRenderMode", AmiglRenderMode}, + {"glGetTexLevelParameterfv", AmiglGetTexLevelParameterfv}, + {"glGetTexLevelParameteriv", AmiglGetTexLevelParameteriv}, + {"glMap1f", AmiglMap1f}, + {"glMap1d", AmiglMap1d}, + {"glEvalCoord1f", AmiglEvalCoord1f}, + {"glEvalCoord1d", AmiglEvalCoord1d}, + {"glEvalCoord1fv", AmiglEvalCoord1fv}, + {"glEvalCoord1dv", AmiglEvalCoord1dv}, + {"glMapGrid1f", AmiglMapGrid1f}, + {"glMapGrid1d", AmiglMapGrid1d}, + {"glEvalMesh1", AmiglEvalMesh1}, + {"glEvalPoint1", AmiglEvalPoint1}, + {"glMap2f", AmiglMap2f}, + {"glMap2d", AmiglMap2d}, + {"glEvalCoord2f", AmiglEvalCoord2f}, + {"glEvalCoord2d", AmiglEvalCoord2d}, + {"glEvalCoord2fv", AmiglEvalCoord2fv}, + {"glEvalCoord2dv", AmiglEvalCoord2dv}, + {"glMapGrid2f", AmiglMapGrid2f}, + {"glMapGrid2d", AmiglMapGrid2d}, + {"glEvalMesh2", AmiglEvalMesh2}, + {"glEvalPoint2", AmiglEvalPoint2}, + {"glGetMapfv", AmiglGetMapfv}, + {"glGetMapdv", AmiglGetMapdv}, + {"glGetMapiv", AmiglGetMapiv}, + {"glPushClientAttrib", AmiglPushClientAttrib}, + {"glPopClientAttrib", AmiglPopClientAttrib}, + {"glPixelTransferi", AmiglPixelTransferi}, + {"glPixelTransferf", AmiglPixelTransferf}, + {"glGetTexImage", AmiglGetTexImage}, + {"glCopyTexImage1D", AmiglCopyTexImage1D}, + {"glCopyTexImage2D", AmiglCopyTexImage2D}, + {"glCopyTexSubImage1D", AmiglCopyTexSubImage1D}, + {"glCopyTexSubImage2D", AmiglCopyTexSubImage2D}, + {"glEdgeFlag", AmiglEdgeFlag}, + {"glReadBuffer", AmiglReadBuffer}, + {"glPrioritizeTextures", AmiglPrioritizeTextures}, + {"glDrawRangeElements", AmiglDrawRangeElements}, + {"glGetClipPlane", AmiglGetClipPlane}, + {"gluNewTess", AmigluNewTess}, + {"gluDeleteTess", AmigluDeleteTess}, + {"gluTessProperty", AmigluTessProperty}, + {"gluGetTessProperty", AmigluGetTessProperty}, + {"gluTessNormal", AmigluTessNormal}, + {"gluTessCallback", AmigluTessCallback}, + {"gluTessVertex", AmigluTessVertex}, + {"gluTessBeginPolygon", AmigluTessBeginPolygon}, + {"gluTessBeginContour", AmigluTessBeginContour}, + {"gluTessEndContour", AmigluTessEndContour}, + {"gluTessEndPolygon", AmigluTessEndPolygon}, + {"gluBeginPolygon", AmigluBeginPolygon}, + {"gluNextContour", AmigluNextContour}, + {"gluEndPolygon", AmigluEndPolygon}, + {"gluErrorString", AmigluErrorString}, + {"gluScaleImage", AmigluScaleImage}, + {"gluBuild2DMipmapLevels", AmigluBuild2DMipmapLevels}, + {"gluBuild2DMipmaps", AmigluBuild2DMipmaps}, + {"gluOrtho2D", AmigluOrtho2D}, + {"gluPerspective", AmigluPerspective}, + {"gluLookAt", AmigluLookAt}, + {"gluProject", AmigluProject}, + {"gluUnProject", AmigluUnProject}, + {"gluUnProject4", AmigluUnProject4}, + {"gluPickMatrix", AmigluPickMatrix}, + {"gluNewQuadric", AmigluNewQuadric}, + {"gluDeleteQuadric", AmigluDeleteQuadric}, + {"gluQuadricCallback", AmigluQuadricCallback}, + {"gluQuadricNormals", AmigluQuadricNormals}, + {"gluQuadricTexture", AmigluQuadricTexture}, + {"gluQuadricOrientation", AmigluQuadricOrientation}, + {"gluQuadricDrawStyle", AmigluQuadricDrawStyle}, + {"gluCylinder", AmigluCylinder}, + {"gluDisk", AmigluDisk}, + {"gluPartialDisk", AmigluPartialDisk}, + {"gluSphere", AmigluSphere}, + {"gluGetString", AmigluGetString}, + {"gluCheckExtension", AmigluCheckExtension}, + {"gluNurbsCallbackData", AmigluNurbsCallbackData}, + {"gluBeginCurve", AmigluBeginCurve}, + {"gluBeginSurface", AmigluBeginSurface}, + {"gluBeginTrim", AmigluBeginTrim}, + {"gluDeleteNurbsRenderer", AmigluDeleteNurbsRenderer}, + {"gluEndCurve", AmigluEndCurve}, + {"gluEndSurface", AmigluEndSurface}, + {"gluEndTrim", AmigluEndTrim}, + {"gluGetNurbsProperty", AmigluGetNurbsProperty}, + {"gluLoadSamplingMatrices", AmigluLoadSamplingMatrices}, + {"gluNewNurbsRenderer", AmigluNewNurbsRenderer}, + {"gluNurbsCallback", AmigluNurbsCallback}, + {"gluNurbsCallbackDataEXT", AmigluNurbsCallbackDataEXT}, + {"gluNurbsCurve", AmigluNurbsCurve}, + {"gluNurbsProperty", AmigluNurbsProperty}, + {"gluNurbsSurface", AmigluNurbsSurface}, + {"gluPwlCurve", AmigluPwlCurve}, + {"glGetTexParameteriv", AmiglGetTexParameteriv}, + {"glGetTexParameterfv", AmiglGetTexParameterfv}, + {"glPixelZoom", AmiglPixelZoom}, + {"glLogicOp", AmiglLogicOp}, + {"glCopyPixels", AmiglCopyPixels}, +#ifdef NOT_IMPLEMENTED_FUNCS + #include "SDL_os4_notimplemented_table.t" +#endif + { NULL, NULL } + }; + + CONST struct MyGLFunc *tb = table; + + do { + if (!strcmp(tb->name, proc)) { + return tb->func; + } + tb++; + } while (tb->name); + + return NULL; +} + +#endif /* SDL_VIDEO_DRIVER_AMIGAOS4 */ diff --git a/src/video/amigaos4/SDL_os4shape.c b/src/video/amigaos4/SDL_os4shape.c new file mode 100644 index 0000000000000..aba81e0dde516 --- /dev/null +++ b/src/video/amigaos4/SDL_os4shape.c @@ -0,0 +1,350 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2018 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_AMIGAOS4 + +/* NOTE: shaped windows need compositing enabled for the GUI! */ + +#include "SDL_os4video.h" +#include "SDL_os4shape.h" +#include "SDL_os4window.h" + +#include "SDL_shape.h" +#include "../SDL_shape_internals.h" +#include "SDL_assert.h" + +#define DEBUG +#include "../../main/amigaos4/SDL_os4debug.h" + +SDL_WindowShaper* +OS4_CreateShaper(SDL_Window * window) +{ + _THIS = SDL_GetVideoDevice(); + + SDL_WindowData *windowdata = window->driverdata; + SDL_WindowShaper *result = NULL; + LONG compositing = FALSE; + + dprintf("Called %p\n", window); + + IIntuition->GetScreenAttrs(windowdata->syswin->WScreen, + SA_Compositing, &compositing, + TAG_DONE); + + if (compositing) { + + result = SDL_malloc(sizeof(SDL_WindowShaper)); + + if (result) { + SDL_ShapeData *data = SDL_malloc(sizeof(SDL_ShapeData)); + + result->window = window; + result->mode.mode = ShapeModeDefault; + result->mode.parameters.binarizationCutoff = 1; + result->userx = 0; + result->usery = 0; + + if (data) { + int resized_properly; + + data->width = 0; + data->height = 0; + data->bitmap = NULL; + data->sysbm = NULL; + data->cliprect = NULL; + + result->driverdata = data; + + window->shaper = result; + resized_properly = OS4_ResizeWindowShape(window); + + SDL_assert(resized_properly == 0); + + } else { + dprintf("Failed to allocate driver data\n"); + SDL_free(result); + result = NULL; + } + + } else { + //SDL_SetError("Failed to create shaper"); + dprintf("Failed to create shaper\n"); + } + } else { + dprintf("Compositing not enabled!\n"); + } + + return result; +} + +static struct BitMap * +OS4_MakeAlphaBitMap(void * source, int width, int height) +{ + _THIS = SDL_GetVideoDevice(); + + struct BitMap *sysbm = IGraphics->AllocBitMapTags( + width, + height, + 8, + BMATags_PixelFormat, PIXF_ALPHA8, + BMATags_Displayable, TRUE, + TAG_DONE); + + dprintf("Creating alpha bitmap %d*%d, source %p\n", width, height, source); + + if (sysbm) { + uint32 bytesperrow; + APTR baseaddress; + + APTR lock = IGraphics->LockBitMapTags(sysbm, + LBM_BaseAddress, &baseaddress, + LBM_BytesPerRow, &bytesperrow, + TAG_DONE); + + if (lock) { + + int y; + + uint8 *src = source; + + for (y = 0; y < height; y++) { + + int x; + + uint8 *dst = (uint8 *)baseaddress + y * bytesperrow; + + for (x = 0; x < width; x++) { + *dst++ = *src++; + } + } + + IGraphics->UnlockBitMap(lock); + } else { + dprintf("Failed to lock bitmap\n"); + IGraphics->FreeBitMap(sysbm); + sysbm = NULL; + } + + } else { + dprintf("Couldn't allocate alpha bitmap\n"); + return NULL; + } + + return sysbm; +} + +static struct ClipRect* +OS4_SetAlphaLayer(struct Window * window, SDL_ShapeData * data) +{ + _THIS = SDL_GetVideoDevice(); + + struct ClipRect *cliprect; + struct ClipRect *oldCliprect = NULL; + + ILayers->LockLayerInfo(&window->WScreen->LayerInfo); + + if (data->cliprect) { + dprintf("Freeing old clip rect\n"); + ILayers->FreeClipRect(&window->WScreen->LayerInfo, data->cliprect); + } + + cliprect = ILayers->AllocClipRect(&window->WScreen->LayerInfo); + + if (cliprect) { + cliprect->BitMap = data->sysbm; + + // TODO: anything else to be done? + cliprect->bounds.MinX = 0; + cliprect->bounds.MinY = 0; + cliprect->bounds.MaxX = data->width - 1; + cliprect->bounds.MaxY = data->height - 1; + + oldCliprect = ILayers->ChangeLayerAlpha(window->WLayer, cliprect, NULL); + //IIntuition->SetWindowAttrs(window, WA_AlphaClips, cliprect, TAG_DONE); //TODO: which method is better? + } else { + dprintf("Failed to allocate cliprect\n"); + } + + ILayers->UnlockLayerInfo(&window->WScreen->LayerInfo); + + if (oldCliprect == (struct ClipRect *)-1) { + dprintf("Failed to install layer alpha\n"); + } + + return cliprect; //TODO +} + +void +OS4_DestroyShape(_THIS, SDL_Window * window) +{ + SDL_WindowShaper *shaper = window->shaper; + + dprintf("Called for '%s'\n", window->title); + + if (shaper && shaper->driverdata) { + + SDL_ShapeData *data = shaper->driverdata; + SDL_WindowData *windowdata = window->driverdata; + struct Window *syswin = windowdata->syswin; + + if (data->cliprect) { + ILayers->LockLayerInfo(&syswin->WScreen->LayerInfo); + + data->cliprect->BitMap = NULL; // TODO: is this valid approach?? + + dprintf("Freeing cliprect %p\n", data->cliprect); + + ILayers->FreeClipRect(&syswin->WScreen->LayerInfo, data->cliprect); + data->cliprect = NULL; + + ILayers->UnlockLayerInfo(&syswin->WScreen->LayerInfo); + } + + if (data->sysbm) { + dprintf("Freeing system bitmap %p\n", data->sysbm); + IGraphics->FreeBitMap(data->sysbm); + data->sysbm = NULL; + } + + if (data->bitmap) { + dprintf("Freeing SDL bitmap %p\n", data->bitmap); + SDL_free(data->bitmap); + data->bitmap = NULL; + } + + dprintf("Freeing shape data %p\n", data); + + SDL_free(data); + shaper->driverdata = NULL; + } else { + dprintf("No shaper or shape data\n"); + return; + } + +} + +int +OS4_SetWindowShape(SDL_WindowShaper * shaper, SDL_Surface * shape, SDL_WindowShapeMode * shape_mode) +{ + if (shaper && shape && shape_mode && shaper->driverdata) { + + SDL_ShapeData *data = shaper->driverdata; + SDL_WindowData *windowdata = shaper->window->driverdata; + + if (shape->format->Amask == 0 && SDL_SHAPEMODEALPHA(shape_mode->mode)) { + dprintf("Shape doesn't have alpha channel\n"); + return -2; + } + + if (shape->w != shaper->window->w || shape->h != shaper->window->h) { + + dprintf("Shape dimensions don't match window dimensions\n"); + return -3; + } + + if (data->bitmap) { + SDL_CalculateShapeBitmap(shaper->mode, shape, data->bitmap, 1); + + if (! (data->sysbm = OS4_MakeAlphaBitMap(data->bitmap, shape->w, shape->h))) { + dprintf("Couldn't allocate alpha bitmap\n"); + return -4; + } + + dprintf("Freeing temporary SDL bitmap %p\n", data->bitmap); + + SDL_free(data->bitmap); + data->bitmap = NULL; + + if (! (data->cliprect = OS4_SetAlphaLayer(windowdata->syswin, data))) { + dprintf("Failed to allocate clip rect\n"); + return -5; + } + + dprintf("New alpha layer applied for window '%s'\n", shaper->window->title); + + return 0; + + } else { + dprintf("NULL source bitmap\n"); + return -6; + } + + } else { + dprintf("No shaper, shape or shape_mode\n"); + return -7; + } +} + +int +OS4_ResizeWindowShape(SDL_Window * window) +{ + if (window->shaper) { + + SDL_ShapeData *data = window->shaper->driverdata; + + if (data) { + int width, height; + + OS4_GetWindowActiveSize(window, &width, &height); + + dprintf("Called for '%s'\n", window->title); + + if (data->width != width || + data->height != height || data->bitmap == NULL) { + + Uint32 bitmapsize = width * height; + + data->width = width; + data->height = height; + + if (data->bitmap) { + SDL_free(data->bitmap); + } + + data->bitmap = SDL_malloc(bitmapsize); + + if (data->bitmap) { + SDL_memset(data->bitmap, 0, bitmapsize); + } else { + dprintf("Failed to allocate SDL bitmap\n"); + return SDL_SetError("Could not allocate memory for shaped-window bitmap"); + } + } + + window->shaper->userx = window->x; + window->shaper->usery = window->y; + //SDL_SetWindowPosition(window, -1000, -1000);//?? + + return 0; + } else { + dprintf("No shape data\n"); + return -1; + } + } else { + dprintf("No shaper\n"); + return -1; + } +} + +#endif /* SDL_VIDEO_DRIVER_AMIGAOS4 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/amigaos4/SDL_os4shape.h b/src/video/amigaos4/SDL_os4shape.h new file mode 100644 index 0000000000000..26711ee73be0e --- /dev/null +++ b/src/video/amigaos4/SDL_os4shape.h @@ -0,0 +1,42 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2014 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#ifndef _SDL_os4shape_h +#define _SDL_os4shape_h + +typedef struct { + struct BitMap* sysbm; + struct ClipRect* cliprect; + void* bitmap; + int width; + int height; +} SDL_ShapeData; + +extern SDL_WindowShaper* OS4_CreateShaper(SDL_Window * window); +extern int OS4_SetWindowShape(SDL_WindowShaper * shaper, SDL_Surface * shape, SDL_WindowShapeMode * shape_mode); +extern int OS4_ResizeWindowShape(SDL_Window * window); + +extern void OS4_DestroyShape(_THIS, SDL_Window * window); + +#endif /* _SDL_os4shape_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/amigaos4/SDL_os4video.c b/src/video/amigaos4/SDL_os4video.c new file mode 100644 index 0000000000000..806055a0f0ffb --- /dev/null +++ b/src/video/amigaos4/SDL_os4video.c @@ -0,0 +1,601 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2021 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_AMIGAOS4 + +#include + +#include "SDL_video.h" +#include "SDL_hints.h" +#include "SDL_version.h" + +#include "../SDL_sysvideo.h" +#include "../SDL_pixels_c.h" +#include "../../events/SDL_events_c.h" + +#include "SDL_os4video.h" +#include "SDL_os4events.h" +#include "SDL_os4framebuffer.h" +#include "SDL_os4mouse.h" +#include "SDL_os4opengl.h" +#include "SDL_os4opengles.h" +#include "SDL_os4shape.h" +#include "SDL_os4messagebox.h" +#include "SDL_os4modes.h" +#include "SDL_os4keyboard.h" +#include "SDL_os4library.h" + +#define DEBUG +#include "../../main/amigaos4/SDL_os4debug.h" + +#define OS4VID_DRIVER_NAME "os4" + +static int OS4_VideoInit(_THIS); +static void OS4_VideoQuit(_THIS); + +SDL_bool (*OS4_ResizeGlContext)(_THIS, SDL_Window * window) = NULL; +void (*OS4_UpdateGlWindowPointer)(_THIS, SDL_Window * window) = NULL; + +#define MIN_LIB_VERSION 51 + +static SDL_bool +OS4_OpenLibraries(_THIS) +{ + dprintf("Opening libraries\n"); + + GfxBase = OS4_OpenLibrary("graphics.library", 54); + LayersBase = OS4_OpenLibrary("layers.library", 53); + IntuitionBase = OS4_OpenLibrary("intuition.library", MIN_LIB_VERSION); + IconBase = OS4_OpenLibrary("icon.library", MIN_LIB_VERSION); + WorkbenchBase = OS4_OpenLibrary("workbench.library", MIN_LIB_VERSION); + KeymapBase = OS4_OpenLibrary("keymap.library", MIN_LIB_VERSION); + TextClipBase = OS4_OpenLibrary("textclip.library", MIN_LIB_VERSION); + DOSBase = OS4_OpenLibrary("dos.library", MIN_LIB_VERSION); + + if (GfxBase && LayersBase && IntuitionBase && IconBase && + WorkbenchBase && KeymapBase && TextClipBase && DOSBase) { + + IGraphics = (struct GraphicsIFace *) OS4_GetInterface(GfxBase); + ILayers = (struct LayersIFace *) OS4_GetInterface(LayersBase); + IIntuition = (struct IntuitionIFace *) OS4_GetInterface(IntuitionBase); + IIcon = (struct IconIFace *) OS4_GetInterface(IconBase); + IWorkbench = (struct WorkbenchIFace *) OS4_GetInterface(WorkbenchBase); + IKeymap = (struct KeymapIFace *) OS4_GetInterface(KeymapBase); + ITextClip = (struct TextClipIFace *) OS4_GetInterface(TextClipBase); + IDOS = (struct DOSIFace *) OS4_GetInterface(DOSBase); + + if (IGraphics && ILayers && IIntuition && IIcon && + IWorkbench && IKeymap && ITextClip && IDOS) { + + dprintf("All library interfaces OK\n"); + + return SDL_TRUE; + + } else { + dprintf("Failed to get library interfaces\n"); + } + } else { + dprintf("Failed to open system libraries\n"); + } + + return SDL_FALSE; +} + +static void +OS4_CloseLibraries(_THIS) +{ + dprintf("Closing libraries\n"); + + OS4_DropInterface((void *)&IDOS); + OS4_DropInterface((void *)&ITextClip); + OS4_DropInterface((void *)&IKeymap); + OS4_DropInterface((void *)&IWorkbench); + OS4_DropInterface((void *)&IIcon); + OS4_DropInterface((void *)&IIntuition); + OS4_DropInterface((void *)&ILayers); + OS4_DropInterface((void *)&IGraphics); + + OS4_CloseLibrary(&DOSBase); + OS4_CloseLibrary(&TextClipBase); + OS4_CloseLibrary(&KeymapBase); + OS4_CloseLibrary(&WorkbenchBase); + OS4_CloseLibrary(&IconBase); + OS4_CloseLibrary(&IntuitionBase); + OS4_CloseLibrary(&LayersBase); + OS4_CloseLibrary(&GfxBase); +} + +static void +OS4_FindApplicationName(_THIS) +{ + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + + size_t size; + const size_t maxPathLen = 255; + char pathBuffer[maxPathLen]; + + if (IDOS->GetCliProgramName(pathBuffer, maxPathLen - 1)) { + dprintf("GetCliProgramName: '%s'\n", pathBuffer); + } else { + dprintf("Failed to get CLI program name, checking task node\n"); + + struct Task* me = IExec->FindTask(NULL); + SDL_snprintf(pathBuffer, maxPathLen, "%s", ((struct Node *)me)->ln_Name); + } + + size = SDL_strlen(pathBuffer) + 1; + + data->appName = SDL_malloc(size); + + if (data->appName) { + SDL_snprintf(data->appName, size, pathBuffer); + } + + dprintf("Application name: '%s'\n", data->appName); +} + +static SDL_bool +OS4_AllocSystemResources(_THIS) +{ + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + + dprintf("Called\n"); + + if (!OS4_OpenLibraries(_this)) { + return SDL_FALSE; + } + + OS4_FindApplicationName(_this); + + if (!(data->userPort = IExec->AllocSysObjectTags(ASOT_PORT, TAG_DONE))) { + SDL_SetError("Couldn't allocate message port"); + return SDL_FALSE; + } + + if (!(data->appMsgPort = IExec->AllocSysObjectTags(ASOT_PORT, TAG_DONE))) { + SDL_SetError("Couldn't allocate AppMsg port"); + return SDL_FALSE; + } + + /* Create the pool we'll be using (Shared, might be used from threads) */ + if (!(data->pool = IExec->AllocSysObjectTags(ASOT_MEMPOOL, + ASOPOOL_MFlags, MEMF_SHARED, + ASOPOOL_Threshold, 16384, + ASOPOOL_Puddle, 16384, + ASOPOOL_Protected, TRUE, + TAG_DONE))) { + + SDL_SetError("Couldn't allocate pool"); + return SDL_FALSE; + } + + /* inputPort, inputReq and and input.device are created for WarpMouse functionality. (In SDL1 + they were created in library constructor for an unknown reason) */ + if (!(data->inputPort = IExec->AllocSysObjectTags(ASOT_PORT, TAG_DONE))) { + + SDL_SetError("Couldn't allocate input port"); + return SDL_FALSE; + } + + if (!(data->inputReq = IExec->AllocSysObjectTags(ASOT_IOREQUEST, + ASOIOR_Size, sizeof(struct IOStdReq), + ASOIOR_ReplyPort, data->inputPort, + TAG_DONE))) { + + SDL_SetError("Couldn't allocate input request"); + return SDL_FALSE; + } + + if (IExec->OpenDevice("input.device", 0, (struct IORequest *)data->inputReq, 0)) + { + SDL_SetError("Couldn't open input.device"); + return SDL_FALSE; + } + + IInput = (struct InputIFace *)OS4_GetInterface((struct Library *)data->inputReq->io_Device); + if (!IInput) { + SDL_SetError("Failed to get IInput interface"); + return SDL_FALSE; + } + + return SDL_TRUE; +} + +static void +OS4_FreeSystemResources(_THIS) +{ + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + + dprintf("Called\n"); + + OS4_DropInterface((void *)&IInput); + + if (data->inputReq) { + dprintf("Closing input.device\n"); + //IExec->AbortIO((struct IORequest *)data->inputReq); + //IExec->WaitIO((struct IORequest *)data->inputReq); + IExec->CloseDevice((struct IORequest *)data->inputReq); + + dprintf("Freeing IORequest\n"); + IExec->FreeSysObject(ASOT_IOREQUEST, (void *)data->inputReq); + } + + if (data->inputPort) { + dprintf("Freeing MsgPort\n"); + IExec->FreeSysObject(ASOT_PORT, (void *)data->inputPort); + } + + if (data->pool) { + dprintf("Freeing memory pool\n"); + IExec->FreeSysObject(ASOT_MEMPOOL, data->pool); + } + + if (data->appMsgPort) { + struct Message *msg; + + dprintf("Replying app messages\n"); + + while ((msg = IExec->GetMsg(data->appMsgPort))) { + IExec->ReplyMsg((struct Message *) msg); + } + + dprintf("Freeing app message port\n"); + + IExec->FreeSysObject(ASOT_PORT, data->appMsgPort); + } + + if (data->userPort) { + dprintf("Freeing user port\n"); + IExec->FreeSysObject(ASOT_PORT, data->userPort); + } + + if (data->appName) { + SDL_free(data->appName); + } + + OS4_CloseLibraries(_this); +} + +static void +OS4_DeleteDevice(SDL_VideoDevice * device) +{ + dprintf("Called\n"); + + OS4_FreeSystemResources(device); + + SDL_free(device->driverdata); + SDL_free(device); +} + +static void +OS4_SetMiniGLFunctions(SDL_VideoDevice * device) +{ + device->GL_GetProcAddress = OS4_GL_GetProcAddress; + device->GL_UnloadLibrary = OS4_GL_UnloadLibrary; + device->GL_MakeCurrent = OS4_GL_MakeCurrent; + device->GL_GetDrawableSize = OS4_GL_GetDrawableSize; + device->GL_SetSwapInterval = OS4_GL_SetSwapInterval; + device->GL_GetSwapInterval = OS4_GL_GetSwapInterval; + device->GL_SwapWindow = OS4_GL_SwapWindow; + device->GL_CreateContext = OS4_GL_CreateContext; + device->GL_DeleteContext = OS4_GL_DeleteContext; + //device->GL_DefaultProfileConfig = OS4_GL_DefaultProfileConfig; + + OS4_ResizeGlContext = OS4_GL_ResizeContext; + OS4_UpdateGlWindowPointer = OS4_GL_UpdateWindowPointer; +} + +#if SDL_VIDEO_OPENGL_ES2 +static void +OS4_SetGLESFunctions(SDL_VideoDevice * device) +{ + /* Some functions are recycled from SDL_os4opengl.c 100% ... */ + device->GL_GetProcAddress = OS4_GLES_GetProcAddress; + device->GL_UnloadLibrary = OS4_GLES_UnloadLibrary; + device->GL_MakeCurrent = OS4_GLES_MakeCurrent; + device->GL_GetDrawableSize = OS4_GL_GetDrawableSize; + device->GL_SetSwapInterval = OS4_GL_SetSwapInterval; + device->GL_GetSwapInterval = OS4_GL_GetSwapInterval; + device->GL_SwapWindow = OS4_GLES_SwapWindow; + device->GL_CreateContext = OS4_GLES_CreateContext; + device->GL_DeleteContext = OS4_GLES_DeleteContext; + //device->GL_DefaultProfileConfig = OS4_GL(ES)_DefaultProfileConfig; + + OS4_ResizeGlContext = OS4_GLES_ResizeContext; + OS4_UpdateGlWindowPointer = OS4_GLES_UpdateWindowPointer; +} +#endif + +static SDL_bool +OS4_IsMiniGL(_THIS) +{ + if ((_this->gl_config.profile_mask == 0) && + (_this->gl_config.major_version == 1) && + (_this->gl_config.minor_version == 3)) { + dprintf("OpenGL 1.3 requested\n"); + return SDL_TRUE; + } + + return SDL_FALSE; +} + +#if SDL_VIDEO_OPENGL_ES2 +static SDL_bool +OS4_IsOpenGLES2(_THIS) +{ + if ((_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) && + (_this->gl_config.major_version == 2) && + (_this->gl_config.minor_version == 0)) { + dprintf("OpenGL ES 2.0 requested\n"); + return SDL_TRUE; + } + + return SDL_FALSE; +} +#endif + +static int +OS4_LoadGlLibrary(_THIS, const char * path) +{ + dprintf("Profile_mask %d, major ver %d, minor ver %d\n", + _this->gl_config.profile_mask, + _this->gl_config.major_version, + _this->gl_config.minor_version); + + if (OS4_IsMiniGL(_this)) { + OS4_SetMiniGLFunctions(_this); + return OS4_GL_LoadLibrary(_this, path); + } + +#if SDL_VIDEO_OPENGL_ES2 + if (OS4_IsOpenGLES2(_this)) { + OS4_SetGLESFunctions(_this); + return OS4_GLES_LoadLibrary(_this, path); + } +#endif + + dprintf("Invalid OpenGL version\n"); + SDL_SetError("Invalid OpenGL version"); + return -1; +} + +static void +OS4_SetFunctionPointers(SDL_VideoDevice * device) +{ + device->VideoInit = OS4_VideoInit; + device->VideoQuit = OS4_VideoQuit; + //device->ResetTouch = OS4_ResetTouch; + + device->GetDisplayBounds = OS4_GetDisplayBounds; + //device->GetDisplayUsableBounds = OS4_GetDisplayUsableBounds; + //device->GetDisplayDPI = OS4_GetDisplayDPI; + + device->GetDisplayModes = OS4_GetDisplayModes; + device->SetDisplayMode = OS4_SetDisplayMode; + + device->CreateSDLWindow = OS4_CreateWindow; + device->CreateSDLWindowFrom = OS4_CreateWindowFrom; + device->SetWindowTitle = OS4_SetWindowTitle; + //device->SetWindowIcon = OS4_SetWindowIcon; + device->SetWindowPosition = OS4_SetWindowPosition; + device->SetWindowSize = OS4_SetWindowSize; + + device->SetWindowMinimumSize = OS4_SetWindowMinMaxSize; + device->SetWindowMaximumSize = OS4_SetWindowMinMaxSize; + device->GetWindowBordersSize = OS4_GetWindowBordersSize; + + device->SetWindowOpacity = OS4_SetWindowOpacity; + // device->SetWindowModalFor = OS4_SetWindowModalFor; + // device->SetWindowInputFocus = OS4_SetWindowInputFocus; + + device->ShowWindow = OS4_ShowWindow; + device->HideWindow = OS4_HideWindow; + device->RaiseWindow = OS4_RaiseWindow; + + device->MaximizeWindow = OS4_MaximizeWindow; + device->MinimizeWindow = OS4_MinimizeWindow; + device->RestoreWindow = OS4_RestoreWindow; + + //device->SetWindowBordered = OS4_SetWindowBordered; // Not supported by SetWindowAttrs()? + device->SetWindowResizable = OS4_SetWindowResizable; + + device->SetWindowFullscreen = OS4_SetWindowFullscreen; + //device->SetWindowGammaRamp = OS4_SetWindowGammaRamp; + //device->GetWindowGammaRamp = OS4_GetWindowGammaRamp; + + device->SetWindowMouseGrab = OS4_SetWindowMouseGrab; + // device->SetWindowKeyboardGrab = OS4_SetWindowKeyboardGrab; + + device->DestroyWindow = OS4_DestroyWindow; + + device->CreateWindowFramebuffer = OS4_CreateWindowFramebuffer; + device->UpdateWindowFramebuffer = OS4_UpdateWindowFramebuffer; + device->DestroyWindowFramebuffer = OS4_DestroyWindowFramebuffer; + + //device->OnWindowEnter = OS4_OnWindowEnter; + + device->shape_driver.CreateShaper = OS4_CreateShaper; + device->shape_driver.SetWindowShape = OS4_SetWindowShape; + device->shape_driver.ResizeWindowShape = OS4_ResizeWindowShape; + + device->GetWindowWMInfo = OS4_GetWindowWMInfo; + + device->GL_LoadLibrary = OS4_LoadGlLibrary; + OS4_SetMiniGLFunctions(device); + + device->PumpEvents = OS4_PumpEvents; + //device->SuspendScreenSaver = OS4_SuspendScreenSaver; + + //device->StartTextInput = OS4_StartTextInput; + //device->StopTextInput = OS4_StopTextInput; + //device->SetTextInputRect = OS4_SetTextInputRect; + + //device->SetTextInputRect = OS4_SetTextInputRect; + //device->ShowScreenKeyboard = OS4_ShowScreenKeyboard; + //device->HideScreenKeyboard = OS4_HideScreenKeyboard; + //device->IsScreenKeyboardShown = OS4_IsScreenKeyboardShown; + + device->SetClipboardText = OS4_SetClipboardText; + device->GetClipboardText = OS4_GetClipboardText; + device->HasClipboardText = OS4_HasClipboardText; + //device->ShowMessageBox = OS4_ShowMessageBox; Can be called without video initialization + + device->SetWindowHitTest = OS4_SetWindowHitTest; + //device->AcceptDragAndDrop = OS4_AcceptDragAndDrop; + + device->free = OS4_DeleteDevice; +} + +static SDL_VideoDevice * +OS4_CreateDevice(int devindex) +{ + SDL_VideoDevice *device; + SDL_VideoData *data; + SDL_version version; + + SDL_GetVersion(&version); + + dprintf("*** SDL %d.%d.%d video initialization starts ***\n", + version.major, version.minor, version.patch); + +#ifdef __AMIGADATE__ + dprintf("Build date: " __AMIGADATE__ "\n"); +#endif + + /* Initialize all variables that we clean on shutdown */ + device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); + + if (device) { + data = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData)); + } else { + data = NULL; + } + + if (!data) { + SDL_free(device); + SDL_OutOfMemory(); + return NULL; + } + + device->driverdata = data; + + if (!OS4_AllocSystemResources(device)) { + /* If we return with NULL, SDL_VideoQuit() can't clean up OS4 stuff. So let's do it now. */ + OS4_FreeSystemResources(device); + + SDL_free(device); + SDL_free(data); + + SDL_Unsupported(); + + return NULL; + } + + OS4_SetFunctionPointers(device); + + return device; +} + +VideoBootStrap OS4_bootstrap = { + OS4VID_DRIVER_NAME, "SDL AmigaOS 4 video driver", + OS4_CreateDevice +}; + +int +OS4_VideoInit(_THIS) +{ + dprintf("Called\n"); + + if (OS4_InitModes(_this) < 0) { + return SDL_SetError("Failed to initialize modes"); + } + + OS4_InitKeyboard(_this); + OS4_InitMouse(_this); + + // We don't want SDL to change window setup in SDL_OnWindowFocusLost() + SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0"); + + return 0; +} + +void +OS4_VideoQuit(_THIS) +{ + dprintf("Called\n"); + + OS4_QuitMouse(_this); + OS4_QuitKeyboard(_this); + OS4_QuitModes(_this); +} + +void * +OS4_SaveAllocPooled(_THIS, uint32 size) +{ + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + + return IExec->AllocPooled(data->pool, size); +} + +void * +OS4_SaveAllocVecPooled(_THIS, uint32 size) +{ + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + + return IExec->AllocVecPooled(data->pool, size); +} + +void +OS4_SaveFreePooled(_THIS, void * mem, uint32 size) +{ + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + + IExec->FreePooled(data->pool, mem, size); +} + +void +OS4_SaveFreeVecPooled(_THIS, void * mem) +{ + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + + IExec->FreeVecPooled(data->pool, mem); +} + +/* Native window apps may be interested in calling this */ +struct MsgPort * +OS4_GetSharedMessagePort() +{ + SDL_VideoDevice *vd = SDL_GetVideoDevice(); + + if (vd) { + SDL_VideoData *data = (SDL_VideoData *) vd->driverdata; + if (data) { + return data->userPort; + } + } + + return NULL; +} + +#endif /* SDL_VIDEO_DRIVER_AMIGAOS4 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/amigaos4/SDL_os4video.h b/src/video/amigaos4/SDL_os4video.h new file mode 100644 index 0000000000000..193b505bf8782 --- /dev/null +++ b/src/video/amigaos4/SDL_os4video.h @@ -0,0 +1,105 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2018 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#ifndef _SDL_os4video_h +#define _SDL_os4video_h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../SDL_sysvideo.h" + +/* Private display data */ + +typedef struct +{ + STRPTR appName; + + struct Screen *publicScreen; + + struct MsgPort *userPort; + struct MsgPort *appMsgPort; + + struct MsgPort *inputPort; + struct IOStdReq *inputReq; + + APTR pool; + + struct Library *gfxbase; + struct Library *layersbase; + struct Library *intuitionbase; + struct Library *iconbase; + struct Library *workbenchbase; + struct Library *keymapbase; + struct Library *textclipbase; + struct Library *dosbase; + + struct GraphicsIFace *iGraphics; + struct LayersIFace *iLayers; + struct IntuitionIFace *iIntuition; + struct IconIFace *iIcon; + struct WorkbenchIFace *iWorkbench; + struct KeymapIFace *iKeymap; + struct TextClipIFace *iTextClip; + struct InputIFace *iInput; + struct DOSIFace *iDos; + + BOOL vsyncEnabled; +} SDL_VideoData; + +#define GfxBase ((SDL_VideoData *) _this->driverdata)->gfxbase +#define LayersBase ((SDL_VideoData *) _this->driverdata)->layersbase +#define IntuitionBase ((SDL_VideoData *) _this->driverdata)->intuitionbase +#define IconBase ((SDL_VideoData *) _this->driverdata)->iconbase +#define WorkbenchBase ((SDL_VideoData *) _this->driverdata)->workbenchbase +#define KeymapBase ((SDL_VideoData *) _this->driverdata)->keymapbase +#define TextClipBase ((SDL_VideoData *) _this->driverdata)->textclipbase +#define DOSBase ((SDL_VideoData *) _this->driverdata)->dosbase + +#define IGraphics ((SDL_VideoData *) _this->driverdata)->iGraphics +#define ILayers ((SDL_VideoData *) _this->driverdata)->iLayers +#define IIntuition ((SDL_VideoData *) _this->driverdata)->iIntuition +#define IIcon ((SDL_VideoData *) _this->driverdata)->iIcon +#define IWorkbench ((SDL_VideoData *) _this->driverdata)->iWorkbench +#define IKeymap ((SDL_VideoData *) _this->driverdata)->iKeymap +#define ITextClip ((SDL_VideoData *) _this->driverdata)->iTextClip +#define IInput ((SDL_VideoData *) _this->driverdata)->iInput +#define IDOS ((SDL_VideoData *) _this->driverdata)->iDos + +extern void * OS4_SaveAllocPooled(_THIS, uint32 size); +extern void * OS4_SaveAllocVecPooled(_THIS, uint32 size); +extern void OS4_SaveFreePooled(_THIS, void *mem, uint32 size); +extern void OS4_SaveFreeVecPooled(_THIS, void *mem); + +extern DECLSPEC struct MsgPort * OS4_GetSharedMessagePort(); + +#endif /* _SDL_os4video_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/amigaos4/SDL_os4window.c b/src/video/amigaos4/SDL_os4window.c new file mode 100644 index 0000000000000..fc84d533f2403 --- /dev/null +++ b/src/video/amigaos4/SDL_os4window.c @@ -0,0 +1,1161 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2021 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_AMIGAOS4 + +#include +#include +#include + +#include + +#include "SDL_os4video.h" +#include "SDL_os4shape.h" +#include "SDL_os4window.h" +#include "SDL_os4modes.h" +#include "SDL_os4opengl.h" +#include "SDL_os4mouse.h" +#include "SDL_os4events.h" + +#include "SDL_syswm.h" +#include "../../events/SDL_keyboard_c.h" +#include "../../events/SDL_events_c.h" + +#define DEBUG +#include "../../main/amigaos4/SDL_os4debug.h" + +extern SDL_bool (*OS4_ResizeGlContext)(_THIS, SDL_Window * window); +extern void (*OS4_UpdateGlWindowPointer)(_THIS, SDL_Window * window); + +static void OS4_CloseSystemWindow(_THIS, struct Window * window); +static void OS4_CloseWindow(_THIS, SDL_Window * sdlwin); + +void +OS4_GetWindowSize(_THIS, struct Window * window, int * width, int * height) +{ + LONG ret = IIntuition->GetWindowAttrs( + window, + WA_InnerWidth, width, + WA_InnerHeight, height, + TAG_DONE); + + if (ret) { + dprintf("GetWindowAttrs() returned %d\n", ret); + } +} + +void +OS4_GetWindowActiveSize(SDL_Window * window, int * width, int * height) +{ + if (window->flags & SDL_WINDOW_MAXIMIZED) { + *width = window->max_w; + *height = window->max_h; + } else { + *width = window->w; + *height = window->h; + } +} + +void +OS4_WaitForResize(_THIS, SDL_Window * window, int * width, int * height) +{ + SDL_WindowData * data = window->driverdata; + + int counter = 0; + int activeWidth, activeHeight; + int w = 0; + int h = 0; + + OS4_GetWindowActiveSize(window, &activeWidth, &activeHeight); + + while (counter++ < 100) { + OS4_GetWindowSize(_this, data->syswin, &w, &h); + + if (w == activeWidth && h == activeHeight) { + break; + } + + dprintf("Waiting for Intuition %d\n", counter); + dprintf("System window size (%d * %d), SDL window size (%d * %d)\n", + w, h, activeWidth, activeHeight); + usleep(1000); + } + + if (width) { + *width = w; + } + + if (height) { + *height = h; + } +} + +static SDL_bool +OS4_IsFullscreen(SDL_Window * window) +{ + return (window->flags & (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_FULLSCREEN_DESKTOP)); +} + +static void +OS4_RemoveAppWindow(_THIS, SDL_WindowData *data) +{ + if (data->appWin) { + dprintf("Removing AppWindow\n"); + + if (IWorkbench->RemoveAppWindow(data->appWin) == FALSE) { + dprintf("Failed to remove AppWindow\n"); + } + data->appWin = NULL; + } +} + +static void +OS4_RemoveAppIcon(_THIS, SDL_WindowData *data) +{ + if (data->appIcon) { + dprintf("Removing AppIcon\n"); + + if (IWorkbench->RemoveAppIcon(data->appIcon) == FALSE) { + dprintf("Failed to remove AppIcon\n"); + } + data->appIcon = NULL; + } +} + +static int +OS4_SetupWindowData(_THIS, SDL_Window * sdlwin, struct Window * syswin) +{ + SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; + + SDL_WindowData *data; + + if (sdlwin->driverdata) { + data = sdlwin->driverdata; + dprintf("Old window data %p exists\n", data); + } else { + data = (SDL_WindowData *) SDL_calloc(1, sizeof(*data)); + + if (!data) { + return SDL_OutOfMemory(); + } + + sdlwin->driverdata = data; + } + + data->sdlwin = sdlwin; + data->syswin = syswin; + data->pointerGrabTicks = 0; + + if (data->syswin) { + int width = 0; + int height = 0; + + OS4_GetWindowSize(_this, data->syswin, &width, &height); + + dprintf("'%s' dimensions %d*%d\n", sdlwin->title, width, height); + + sdlwin->w = width; + sdlwin->h = height; + } + + // Pass SDL window as user data + data->appWin = IWorkbench->AddAppWindow(0, (ULONG)sdlwin, syswin, + videodata->appMsgPort, TAG_DONE); + + if (!data->appWin) { + dprintf("Couldn't create AppWindow\n"); + // It's sad but don't fail because of this + } + + return 0; +} + +static uint32 +OS4_GetIDCMPFlags(SDL_Window * window, SDL_bool fullscreen) +{ + uint32 IDCMPFlags = IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE + | IDCMP_DELTAMOVE | IDCMP_RAWKEY | IDCMP_ACTIVEWINDOW + | IDCMP_INACTIVEWINDOW | IDCMP_INTUITICKS + | IDCMP_EXTENDEDMOUSE; + + dprintf("Called\n"); + + if (!fullscreen) { + if (!(window->flags & SDL_WINDOW_BORDERLESS)) { + IDCMPFlags |= IDCMP_CLOSEWINDOW | IDCMP_GADGETUP | IDCMP_CHANGEWINDOW; + } + + if (window->flags & SDL_WINDOW_RESIZABLE) { + //IDCMPFlags |= IDCMP_SIZEVERIFY; no handling so far + IDCMPFlags |= IDCMP_NEWSIZE; + } + } + + return IDCMPFlags; +} + +static uint32 +OS4_GetWindowFlags(SDL_Window * window, SDL_bool fullscreen) +{ + uint32 windowFlags = WFLG_REPORTMOUSE | WFLG_RMBTRAP | WFLG_SMART_REFRESH | WFLG_NOCAREREFRESH; + + dprintf("Called\n"); + + if (fullscreen) { + windowFlags |= WFLG_BORDERLESS | WFLG_BACKDROP; + } else { + windowFlags |= WFLG_NEWLOOKMENUS; + + if (window->flags & SDL_WINDOW_BORDERLESS) { + windowFlags |= WFLG_BORDERLESS; + } else { + windowFlags |= WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_CLOSEGADGET; + + if (window->flags & SDL_WINDOW_RESIZABLE) { + windowFlags |= WFLG_SIZEGADGET | WFLG_SIZEBBOTTOM; + } + } + } + + return windowFlags; +} + +static struct Screen * +OS4_GetScreenForWindow(_THIS, SDL_VideoDisplay * display) +{ + if (display) { + SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata; + + dprintf("Fullscreen\n"); + return displaydata->screen; + } else { + SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; + + dprintf("Window mode (public screen)\n"); + return videodata->publicScreen; + } +} + +static ULONG +OS4_BackFill(const struct Hook *hook, struct RastPort *rastport, struct BackFillMessage *message) +{ + struct Rectangle *rect = &message->Bounds; + struct GraphicsIFace *igfx = hook->h_Data; + + struct RastPort bfRastport; + + igfx->InitRastPort(&bfRastport); + bfRastport.BitMap = rastport->BitMap; + + igfx->RectFillColor(&bfRastport, rect->MinX, rect->MinY, rect->MaxX, rect->MaxY, 0xFF000000); + + return 0; +} + +static struct Hook OS4_BackFillHook = { + {0, 0}, /* h_MinNode */ + (void *)OS4_BackFill, /* h_Entry */ + 0, /* h_SubEntry */ + 0 /* h_Data */ +}; + +static void +OS4_CenterWindow(struct Screen * screen, SDL_Window * window) +{ + if (SDL_WINDOWPOS_ISCENTERED(window->windowed.x) || + SDL_WINDOWPOS_ISUNDEFINED(window->windowed.x)) { + + window->windowed.x = (screen->Width - window->windowed.w) / 2; + dprintf("X centered\n"); + } + + if (SDL_WINDOWPOS_ISCENTERED(window->windowed.y) || + SDL_WINDOWPOS_ISUNDEFINED(window->windowed.y)) { + + window->windowed.y = (screen->Height - window->windowed.h) / 2; + dprintf("Y centered\n"); + } +} + +static void +OS4_DefineWindowBox(SDL_Window * window, struct Screen * screen, SDL_bool fullscreen, SDL_Rect * box) +{ + if (fullscreen && screen) { + box->x = 0; // window->x; + box->y = 0; // window->y; + box->w = screen->Width; // window->w; + box->h = screen->Height; // window->h; + } else { + OS4_CenterWindow(screen, window); + + box->x = window->windowed.x; + box->y = window->windowed.y; + box->w = window->windowed.w; + box->h = window->windowed.h; + } +} + +static void +OS4_CreateIconifyGadget(_THIS, SDL_Window * window) +{ + SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; + SDL_WindowData *data = window->driverdata; + + dprintf("Called\n"); + + struct DrawInfo *di = IIntuition->GetScreenDrawInfo(videodata->publicScreen); + + if (di) { + data->image = (struct Image *)IIntuition->NewObject(NULL, SYSICLASS, + SYSIA_Which, ICONIFYIMAGE, + SYSIA_DrawInfo, di, + TAG_DONE); + + if (data->image) { + + dprintf("Image %p for gadget created\n", data->image); + + data->gadget = (struct Gadget *)IIntuition->NewObject(NULL, BUTTONGCLASS, + GA_Image, data->image, + GA_ID, GID_ICONIFY, + GA_TopBorder, TRUE, + GA_RelRight, TRUE, + GA_Titlebar, TRUE, + GA_RelVerify, TRUE, + TAG_DONE); + + if (data->gadget) { + struct Window *syswin = data->syswin; + + IIntuition->AddGadget(syswin, data->gadget, -1); + + dprintf("Gadget %p created and added\n", data->gadget); + } else { + dprintf("Failed to create button class\n"); + } + } else { + dprintf("Failed to create image class\n"); + } + + IIntuition->FreeScreenDrawInfo(videodata->publicScreen, di); + + } else { + dprintf("Failed to get screen draw info\n"); + } +} + +static void +OS4_CreateIconifyGadgetForWindow(_THIS, SDL_Window * window) +{ + if (!OS4_IsFullscreen(window) && !(window->flags & SDL_WINDOW_BORDERLESS)) { + if (window->w > 99 && window->h > 99) { + OS4_CreateIconifyGadget(_this, window); + } else { + dprintf("Don't add gadget for too small window %d*%d (OS4 bug)\n", + window->w, window->h); + } + } +} + +static struct Window * +OS4_CreateSystemWindow(_THIS, SDL_Window * window, SDL_VideoDisplay * display) +{ + SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; + + struct Window *syswin; + + SDL_bool fullscreen = display ? SDL_TRUE : SDL_FALSE; + + uint32 IDCMPFlags = OS4_GetIDCMPFlags(window, fullscreen); + uint32 windowFlags = OS4_GetWindowFlags(window, fullscreen); + + struct Screen *screen = OS4_GetScreenForWindow(_this, display); + + SDL_Rect box; + + OS4_BackFillHook.h_Data = IGraphics; // Smuggle interface ptr for the hook + + OS4_DefineWindowBox(window, screen, fullscreen, &box); + + dprintf("Opening window '%s' at (%d,%d) of size (%dx%d) on screen %p\n", + window->title, box.x, box.y, box.w, box.h, screen); + + syswin = IIntuition->OpenWindowTags( + NULL, + WA_PubScreen, screen, + WA_Title, fullscreen ? NULL : window->title, + WA_ScreenTitle, window->title, + WA_Left, box.x, + WA_Top, box.y, + WA_InnerWidth, box.w, + WA_InnerHeight, box.h, + WA_Flags, windowFlags, + WA_IDCMP, IDCMPFlags, + WA_Hidden, (window->flags & SDL_WINDOW_HIDDEN) ? TRUE : FALSE, + WA_GrabFocus, (window->flags & SDL_WINDOW_INPUT_GRABBED) ? POINTER_GRAB_TIMEOUT : 0, + WA_UserPort, videodata->userPort, + WA_BackFill, &OS4_BackFillHook, + TAG_DONE); + + if (syswin) { + dprintf("Window address %p\n", syswin); + } else { + dprintf("Couldn't create window\n"); + return NULL; + } + + if (window->flags & SDL_WINDOW_RESIZABLE) { + + // If this window is resizable, reset window size limits + // so that the user can actually resize it. + BOOL ret = IIntuition->WindowLimits(syswin, + syswin->BorderLeft + syswin->BorderRight + 100, + syswin->BorderTop + syswin->BorderBottom + 100, + -1, + -1); + + if (!ret) { + dprintf("Failed to set window limits\n"); + } + } + + return syswin; +} + +int +OS4_CreateWindow(_THIS, SDL_Window * window) +{ + struct Window *syswin = NULL; + + if (OS4_IsFullscreen(window)) { + // We may not have the screen opened yet, so let's wait that SDL calls us back with + // SDL_SetWindowFullscreen() and open the window then. + dprintf("Open fullscreen window with delay\n"); + } else { + if (!(syswin = OS4_CreateSystemWindow(_this, window, NULL))) { + return SDL_SetError("Failed to create system window"); + } + } + + if (OS4_SetupWindowData(_this, window, syswin) < 0) { + + // There is no AppWindow in this scenario + OS4_CloseSystemWindow(_this, syswin); + + return SDL_SetError("Failed to setup window data"); + } + + OS4_CreateIconifyGadgetForWindow(_this, window); + + return 0; +} + +int +OS4_CreateWindowFrom(_THIS, SDL_Window * window, const void * data) +{ + struct Window *syswin = (struct Window *) data; + + dprintf("Called for native window %p (flags 0x%X)\n", data, window->flags); + + if (syswin->Title && SDL_strlen(syswin->Title)) { + window->title = SDL_strdup(syswin->Title); + } + + if (OS4_SetupWindowData(_this, window, syswin) < 0) { + return -1; + } + + // TODO: OpenGL, (fullscreen may not be applicable here?) + + return 0; +} + +void +OS4_SetWindowTitle(_THIS, SDL_Window * window) +{ + SDL_WindowData *data = window->driverdata; + + //dprintf("Called\n"); + + if (data && data->syswin) { + STRPTR title = window->title ? window->title : ""; + + IIntuition->SetWindowTitles(data->syswin, title, title); + } +} + +void +OS4_SetWindowBox(_THIS, SDL_Window * window) +{ + SDL_WindowData *data = window->driverdata; + + if (data && data->syswin) { + int width, height; + LONG ret; + + OS4_GetWindowActiveSize(window, &width, &height); + + ret = IIntuition->SetWindowAttrs(data->syswin, + WA_Left, window->x, + WA_Top, window->y, + WA_InnerWidth, width, + WA_InnerHeight, height, + TAG_DONE); + + if (ret) { + dprintf("SetWindowAttrs() returned %d\n", ret); + } + + if (SDL_IsShapedWindow(window)) { + OS4_ResizeWindowShape(window); + } + + if (data->glContext) { + OS4_ResizeGlContext(_this, window); + } + } +} + +void +OS4_SetWindowPosition(_THIS, SDL_Window * window) +{ + SDL_WindowData *data = window->driverdata; + + dprintf("New window position %d, %d\n", window->x, window->y); + + if (data && data->syswin) { + + LONG ret = IIntuition->SetWindowAttrs(data->syswin, + WA_Left, window->x, + WA_Top, window->y, + TAG_DONE); + + if (ret) { + dprintf("SetWindowAttrs() returned %d\n", ret); + } + } +} + +static void +OS4_ResizeWindow(_THIS, SDL_Window * window, int width, int height) +{ + if (width > 0 && height > 0) { + SDL_WindowData *data = window->driverdata; + + if (data) { + LONG ret = IIntuition->SetWindowAttrs(data->syswin, + WA_InnerWidth, width, + WA_InnerHeight, height, + TAG_DONE); + + if (ret) { + dprintf("SetWindowAttrs() returned %d\n", ret); + } + + OS4_WaitForResize(_this, window, NULL, NULL); + + if (SDL_IsShapedWindow(window)) { + OS4_ResizeWindowShape(window); + } + + if (data->glContext) { + OS4_ResizeGlContext(_this, window); + } + } + } else { + dprintf("Invalid width %d or height %d\n", width, height); + } +} + +void +OS4_SetWindowSize(_THIS, SDL_Window * window) +{ + SDL_WindowData *data = window->driverdata; + + if (data && data->syswin) { + + int width = 0; + int height = 0; + + OS4_GetWindowSize(_this, data->syswin, &width, &height); + + if (width != window->w || height != window->h) { + + dprintf("New window size %d*%d\n", window->w, window->h); + + OS4_ResizeWindow(_this, window, window->w, window->h); + } else { + dprintf("Ignored size request %d*%d\n", width, height); + } + } +} + +void +OS4_ShowWindow(_THIS, SDL_Window * window) +{ + SDL_WindowData *data = window->driverdata; + + if (data && data->syswin) { + + LONG ret; + + dprintf("Showing window '%s'\n", window->title); + + // TODO: could use ShowWindow but what we pass for the Other? + ret = IIntuition->SetWindowAttrs(data->syswin, + WA_Hidden, FALSE, + TAG_DONE); + + if (ret) { + dprintf("SetWindowAttrs() returned %d\n", ret); + } + + if (OS4_IsFullscreen(window)) { + IIntuition->ScreenToFront(data->syswin->WScreen); + } + + IIntuition->ActivateWindow(data->syswin); + + window->flags |= SDL_WINDOW_INPUT_FOCUS; + + SDL_SetKeyboardFocus(window); + + // If cursor was disabled earlier, make sure also this window gets the news + OS4_RefreshCursorState(); + } +} + +void +OS4_HideWindow(_THIS, SDL_Window * window) +{ + SDL_WindowData *data = window->driverdata; + + if (window->is_destroying) { + dprintf("Ignore hide request, window '%s' is destroying\n", window->title); + return; + } + + if (data && data->syswin) { + BOOL result; + + dprintf("Hiding window '%s'\n", window->title); + + // TODO: how to hide a fullscreen window? Close the screen? + result = IIntuition->HideWindow(data->syswin); + + if (!result) { + dprintf("HideWindow() failed\n"); + } + } +} + +void +OS4_RaiseWindow(_THIS, SDL_Window * window) +{ + SDL_WindowData *data = window->driverdata; + + if (data && data->syswin) { + dprintf("Raising window '%s'\n", window->title); + + IIntuition->WindowToFront(data->syswin); + IIntuition->ActivateWindow(data->syswin); + } +} + +static void +OS4_CloseSystemWindow(_THIS, struct Window * window) +{ + if (window) { + dprintf("Closing window '%s' (address %p)\n", window->Title, window); + + struct Screen *screen = window->WScreen; + + IIntuition->CloseWindow(window); + + OS4_CloseScreen(_this, screen); + } else { + dprintf("NULL pointer\n"); + } +} + +static void +OS4_CloseWindow(_THIS, SDL_Window * sdlwin) +{ + SDL_WindowData *data = sdlwin->driverdata; + + if (data) { + OS4_RemoveAppWindow(_this, data); + OS4_RemoveAppIcon(_this, data); + + if (data->syswin) { + + OS4_CloseSystemWindow(_this, data->syswin); + data->syswin = NULL; + + if (data->gadget) { + dprintf("Disposing gadget %p\n", data->gadget); + //IIntuition->RemoveGadget(data->syswin, data->gadget); + IIntuition->DisposeObject((Object *)data->gadget); + data->gadget = NULL; + } + + if (data->image) { + dprintf("Disposing gadget image %p\n", data->image); + IIntuition->DisposeObject((Object *)data->image); + data->image = NULL; + } + } + } else { + dprintf("NULL pointer\n"); + } +} + +void +OS4_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen) +{ + if (window->is_destroying) { + // This function gets also called during window closing + dprintf("Window '%s' is being destroyed, mode change ignored\n", window->title); + } else { + SDL_WindowData *data = window->driverdata; + + dprintf("Trying to set '%s' into %s mode\n", window->title, + fullscreen ? "fullscreen" : "window"); + + if (window->flags & SDL_WINDOW_FOREIGN) { + dprintf("Native window '%s' (%p), mode change ignored\n", window->title, data->syswin); + } else { + + int oldWidth = 0; + int oldHeight = 0; + + if (fullscreen) { + // Detect dummy transition and keep calm + SDL_DisplayData *displayData = display->driverdata; + + if (displayData->screen && data->syswin) { + if (data->syswin->WScreen == displayData->screen) { + dprintf("Same screen, useless mode change ignored\n"); + return; + } + } + } + + if (data->syswin) { + dprintf("Reopening window '%s' (%p) due to mode change\n", + window->title, data->syswin); + + OS4_GetWindowSize(_this, data->syswin, &oldWidth, &oldHeight); + OS4_CloseWindow(_this, window); + + } else { + dprintf("System window doesn't exist yet, let's open it\n"); + } + + data->syswin = OS4_CreateSystemWindow(_this, window, fullscreen ? display : NULL); + + if (data->syswin) { + + OS4_CreateIconifyGadgetForWindow(_this, window); + + // Make sure the new window is active + OS4_ShowWindow(_this, window); + + if ((window->flags & SDL_WINDOW_OPENGL) && data->glContext) { + OS4_UpdateGlWindowPointer(_this, window); + } + + if (oldWidth && oldHeight) { + int width, height; + + OS4_GetWindowSize(_this, data->syswin, &width, &height); + + if (oldWidth != width || oldHeight != height) { + + dprintf("Inform SDL about window resize\n"); + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, + width, height); + } + } + + dprintf("Resetting keyboard\n"); + SDL_ResetKeyboard(); + } + } + } +} + +// This may be called from os4events.c +void +OS4_SetWindowGrabPrivate(_THIS, struct Window * w, SDL_bool activate) +{ + if (w) { + struct IBox grabBox = { + w->BorderLeft, + w->BorderTop, + w->Width - w->BorderLeft - w->BorderRight, + w->Height - w->BorderTop - w->BorderBottom + }; + + LONG ret; + + if (activate) { + // It seems to be that grabbed window should be active, otherwise some other + // window (like shell) may be grabbed? + IIntuition->ActivateWindow(w); + + ret = IIntuition->SetWindowAttrs(w, + WA_MouseLimits, &grabBox, + WA_GrabFocus, POINTER_GRAB_TIMEOUT, + TAG_DONE); + } else { + ret = IIntuition->SetWindowAttrs(w, + WA_MouseLimits, NULL, + WA_GrabFocus, 0, + TAG_DONE); + } + + if (ret) { + dprintf("SetWindowAttrs() returned %d\n", ret); + } else { + dprintf("Window %p ('%s') input was %s\n", + w, w->Title, activate ? "grabbed" : "released"); + } + } +} + +void +OS4_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed) +{ + SDL_WindowData *data = window->driverdata; + + if (data) { + OS4_SetWindowGrabPrivate(_this, data->syswin, grabbed); + data->pointerGrabTicks = 0; + } +} + +void +OS4_DestroyWindow(_THIS, SDL_Window * window) +{ + SDL_WindowData *data = window->driverdata; + + dprintf("Called for '%s' (flags 0x%X)\n", window->title, window->flags); + + if (data) { + + if (data->syswin) { + + if (!(window->flags & SDL_WINDOW_FOREIGN)) { + + if (SDL_IsShapedWindow(window)) { + OS4_DestroyShape(_this, window); + } + + OS4_CloseWindow(_this, window); + } else { + dprintf("Ignored for native window\n"); + } + } + + if (window->flags & SDL_WINDOW_OPENGL) { + OS4_GL_FreeBuffers(_this, data); + } + + SDL_free(data); + window->driverdata = NULL; + } +} + +SDL_bool +OS4_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo * info) +{ + if (info->version.major <= SDL_MAJOR_VERSION) { + struct Window *syswin = ((SDL_WindowData *) window->driverdata)->syswin; + + info->subsystem = SDL_SYSWM_OS4; + info->info.os4.window = syswin; + + dprintf("Window pointer %p\n", syswin); + + return SDL_TRUE; + } else { + dprintf("Application not compiled with SDL %d.%d\n", + SDL_MAJOR_VERSION, SDL_MINOR_VERSION); + + SDL_SetError("Application not compiled with SDL %d.%d", + SDL_MAJOR_VERSION, SDL_MINOR_VERSION); + + return SDL_FALSE; + } +} + +int +OS4_SetWindowHitTest(SDL_Window * window, SDL_bool enabled) +{ + return 0; // just succeed, the real work is done elsewhere +} + +int +OS4_SetWindowOpacity(_THIS, SDL_Window * window, float opacity) +{ + struct Window *syswin = ((SDL_WindowData *) window->driverdata)->syswin; + LONG ret; + + UBYTE value = opacity * 255; + + dprintf("Setting window '%s' opaqueness to %d\n", window->title, value); + + ret = IIntuition->SetWindowAttrs( + syswin, + WA_Opaqueness, value, + TAG_DONE); + + if (ret) { + dprintf("Failed to set window opaqueness to %d\n", value); + return -1; + } + + return 0; +} + +int +OS4_GetWindowBordersSize(_THIS, SDL_Window * window, int * top, int * left, int * bottom, int * right) +{ + struct Window *syswin = ((SDL_WindowData *) window->driverdata)->syswin; + + if (top) { + *top = syswin->BorderTop; + } + + if (left) { + *left = syswin->BorderLeft; + } + + if (bottom) { + *bottom = syswin->BorderBottom; + } + + if (right) { + *right = syswin->BorderRight; + } + + return 0; +} + +void +OS4_SetWindowMinMaxSize(_THIS, SDL_Window * window) +{ + if (window->driverdata) { + + dprintf("Window min size %d*%d, max size %d*%d\n", + window->min_w, window->min_h, + window->max_w, window->max_h); + + if (window->flags & SDL_WINDOW_RESIZABLE) { + + SDL_WindowData *data = window->driverdata; + + if (data->syswin) { + struct Window *syswin = data->syswin; + + int width = syswin->BorderLeft + syswin->BorderRight; + int height = syswin->BorderTop + syswin->BorderBottom; + + BOOL ret =IIntuition->WindowLimits(data->syswin, + window->min_w + width, window->min_h + height, + window->max_w + width, window->max_h + height); + + if (!ret) { + dprintf("Setting window limits failed\n"); + } + } else { + dprintf("NULL window\n"); + } + } else { + dprintf("Window is not resizable\n"); + } + } +} + +void +OS4_MaximizeWindow(_THIS, SDL_Window * window) +{ + dprintf("Maximizing '%s' to %d*%d\n", window->title, window->max_w, window->max_h); + + if (window->flags & SDL_WINDOW_MINIMIZED) { + OS4_UniconifyWindow(_this, window); + } + + // HACK: set flag temporarily so that shaped window and OpenGL + // context can be resized accordingly... + window->flags |= SDL_WINDOW_MAXIMIZED; + + OS4_ResizeWindow(_this, window, window->max_w, window->max_h); + + // ...then remove the flag so that user event can be triggered + window->flags &= ~SDL_WINDOW_MAXIMIZED; + + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MAXIMIZED, 0, 0); +} + +void +OS4_MinimizeWindow(_THIS, SDL_Window * window) +{ + dprintf("Minimizing '%s'\n", window->title); + + OS4_IconifyWindow(_this, window); +} + +void +OS4_RestoreWindow(_THIS, SDL_Window * window) +{ + dprintf("Restoring '%s' to %d*%d\n", window->title, window->w, window->h); + + if (window->flags & SDL_WINDOW_MINIMIZED) { + OS4_UniconifyWindow(_this, window); + } else if (window->flags & SDL_WINDOW_MAXIMIZED) { + OS4_ResizeWindow(_this, window, window->w, window->h); + + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESTORED, 0, 0); + } else { + dprintf("Don't know what to do\n"); + } +} + +static struct DiskObject* +OS4_GetDiskObject(_THIS) +{ + SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; + struct DiskObject *diskObject = NULL; + + if (videodata->appName) { + BPTR oldDir = IDOS->SetCurrentDir(IDOS->GetProgramDir()); + diskObject = IIcon->GetDiskObject(videodata->appName); + IDOS->SetCurrentDir(oldDir); + } + + if (!diskObject) { + CONST_STRPTR fallbackIconName = "ENVARC:Sys/def_window"; + + dprintf("Falling back to '%s'\n", fallbackIconName); + diskObject = IIcon->GetDiskObjectNew(fallbackIconName); + } + + return diskObject; +} + +void +OS4_IconifyWindow(_THIS, SDL_Window * window) +{ + if (window && window->driverdata) { + SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; + + SDL_WindowData *data = window->driverdata; + + if (window->flags & SDL_WINDOW_MINIMIZED) { + dprintf("Window '%s' is already iconified\n", window->title); + } else { + struct DiskObject *diskObject = OS4_GetDiskObject(_this); + + if (diskObject) { + diskObject->do_CurrentX = NO_ICON_POSITION; + diskObject->do_CurrentY = NO_ICON_POSITION; + + data->appIcon = IWorkbench->AddAppIcon( + 0, + (ULONG)window, + videodata->appName, + videodata->appMsgPort, + 0, + diskObject, + TAG_DONE); + + if (!data->appIcon) { + dprintf("Failed to add AppIcon\n"); + } else { + dprintf("Iconifying '%s'\n", window->title); + + OS4_HideWindow(_this, window); + + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MINIMIZED, 0, 0); + } + + IIcon->FreeDiskObject(diskObject); + } else { + dprintf("Failed to load icon\n"); + } + } + } +} + +void +OS4_UniconifyWindow(_THIS, SDL_Window * window) +{ + if (window && window->driverdata) { + if (window->flags & SDL_WINDOW_MINIMIZED) { + dprintf("Restoring '%s'\n", window->title); + + OS4_RemoveAppIcon(_this, window->driverdata); + OS4_ShowWindow(_this, window); + + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESTORED, 0, 0); + } else { + dprintf("Window '%s' isn't in iconified state\n", window->title); + } + } +} + +void +OS4_SetWindowResizable (_THIS, SDL_Window * window, SDL_bool resizable) +{ + if (window->flags & SDL_WINDOW_FOREIGN) { + dprintf("Cannot modify native window '%s'\n", window->title); + return; + } + + SDL_WindowData *data = window->driverdata; + + if (data->syswin) { + dprintf("Closing system window '%s' before re-creation\n", window->title); + OS4_CloseWindow(_this, window); + } + + data->syswin = OS4_CreateSystemWindow(_this, window, NULL); + + if (data->syswin) { + OS4_CreateIconifyGadgetForWindow(_this, window); + + // Make sure the new window is active + OS4_ShowWindow(_this, window); + + if ((window->flags & SDL_WINDOW_OPENGL) && data->glContext) { + OS4_UpdateGlWindowPointer(_this, window); + } + } else { + dprintf("Failed to re-create window '%s'\n", window->title); + } +} + +#endif /* SDL_VIDEO_DRIVER_AMIGAOS4 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/amigaos4/SDL_os4window.h b/src/video/amigaos4/SDL_os4window.h new file mode 100644 index 0000000000000..25fca89c2c0e4 --- /dev/null +++ b/src/video/amigaos4/SDL_os4window.h @@ -0,0 +1,105 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2021 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#ifndef _SDL_os4window_h +#define _SDL_os4window_h + +#include "../SDL_sysvideo.h" + +#define POINTER_GRAB_TIMEOUT 20 /* Number of ticks before pointer grab needs to be reactivated */ + +#define GID_ICONIFY 123 + +typedef struct HitTestInfo +{ + SDL_HitTestResult htr; + SDL_Point point; +} HitTestInfo; + +typedef struct +{ + SDL_Window * sdlwin; + struct Window * syswin; + struct BitMap * bitmap; + struct AppWindow * appWin; + struct AppIcon * appIcon; + + Uint32 pointerGrabTicks; + + void* * glContext; + struct BitMap * glFrontBuffer; + struct BitMap * glBackBuffer; + + HitTestInfo hti; + + struct Gadget * gadget; + struct Image * image; + +} SDL_WindowData; + +extern void OS4_GetWindowSize(_THIS, struct Window * window, int * width, int * height); +extern void OS4_GetWindowActiveSize(SDL_Window * window, int * width, int * height); +extern void OS4_WaitForResize(_THIS, SDL_Window * window, int * width, int * height); + +extern int OS4_CreateWindow(_THIS, SDL_Window * window); +extern int OS4_CreateWindowFrom(_THIS, SDL_Window * window, const void *data); +extern void OS4_SetWindowTitle(_THIS, SDL_Window * window); +//extern void OS4_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon); +extern void OS4_SetWindowBox(_THIS, SDL_Window * window); +extern void OS4_SetWindowPosition(_THIS, SDL_Window * window); +extern void OS4_SetWindowSize(_THIS, SDL_Window * window); +extern void OS4_ShowWindow(_THIS, SDL_Window * window); +extern void OS4_HideWindow(_THIS, SDL_Window * window); +extern void OS4_RaiseWindow(_THIS, SDL_Window * window); + +extern void OS4_SetWindowMinMaxSize(_THIS, SDL_Window * window); + +extern void OS4_MaximizeWindow(_THIS, SDL_Window * window); +extern void OS4_MinimizeWindow(_THIS, SDL_Window * window); +extern void OS4_RestoreWindow(_THIS, SDL_Window * window); + +extern void OS4_SetWindowResizable (_THIS, SDL_Window * window, SDL_bool resizable); + +//extern void OS4_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered); +extern void OS4_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen); +//extern int OS4_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp); +//extern int OS4_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp); + +extern void OS4_SetWindowGrabPrivate(_THIS, struct Window * w, SDL_bool activate); +extern void OS4_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed); +extern void OS4_DestroyWindow(_THIS, SDL_Window * window); +extern SDL_bool OS4_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info); + +//extern void OS4_OnWindowEnter(_THIS, SDL_Window * window); +//extern void OS4_UpdateClipCursor(SDL_Window *window); + +extern int OS4_SetWindowHitTest(SDL_Window * window, SDL_bool enabled); + +extern int OS4_SetWindowOpacity(_THIS, SDL_Window * window, float opacity); +extern int OS4_GetWindowBordersSize(_THIS, SDL_Window * window, int * top, int * left, int * bottom, int * right); + +extern void OS4_IconifyWindow(_THIS, SDL_Window * window); +extern void OS4_UniconifyWindow(_THIS, SDL_Window * window); + +#endif /* _SDL_os4window_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/test/Makefile.amigaos4 b/test/Makefile.amigaos4 new file mode 100644 index 0000000000000..24681247318fd --- /dev/null +++ b/test/Makefile.amigaos4 @@ -0,0 +1,290 @@ +# Makefile to build the AmigaOS4 SDL tests + +CC = ppc-amigaos-gcc +CFLAGS = -gstabs -O2 -Wall -g -I../include -DHAVE_OPENGL +LIBS = -L.. -use-dynld -lSDL2_test -lSDL2 -athread=native + +TARGETS = \ + checkkeys \ + controllermap \ + helloworld \ + loopwave \ + loopwavequeue \ + sdl2benchmark \ + testatomic \ + testaudiocapture \ + testaudiohotplug \ + testaudioinfo \ + testautomation \ + testbounds \ + testcustomcursor \ + testdisplayinfo \ + testdraw2 \ + testdrawchessboard \ + testdropfile \ + testerror \ + testfile \ + testfilesystem \ + testgamecontroller \ + testgesture \ + testgl2 \ + testgles \ + testgles2 \ + testhaptic \ + testhittesting \ + testhotplug \ + testiconv \ + testime \ + testintersections \ + testjoystick \ + testkeys \ + testloadso \ + testlock \ + testmessage \ + testmultiaudio \ + testnative \ + testoffscreen \ + testoverlay2 \ + testplatform \ + testpower \ + testqsort \ + testrelative \ + testrendercopyex \ + testrendertarget \ + testresample \ + testrumble \ + testscale \ + testsem \ + testsensor \ + testshader \ + testshape \ + testsprite2 \ + testspriteminimal \ + teststreaming \ + testthread \ + testtimer \ + testurl \ + testver \ + testviewport \ + testvulkan \ + testwm2 \ + testyuv \ + torturethread \ + +all: $(TARGETS) + +checkkeys: checkkeys.o + $(CC) -o $@ $^ $(LIBS) + +helloworld: helloworld.o + $(CC) -o $@ $^ $(LIBS) + +loopwave: loopwave.o + $(CC) -o $@ $^ $(LIBS) + +loopwavequeue: loopwavequeue.o + $(CC) -o $@ $^ $(LIBS) + +sdl2benchmark: sdl2benchmark.o + $(CC) -o $@ $^ $(LIBS) + +testresample: testresample.o + $(CC) -o $@ $^ $(LIBS) + +testaudioinfo: testaudioinfo.o + $(CC) -o $@ $^ $(LIBS) + +testautomation: testautomation.o \ + testautomation_audio.o \ + testautomation_clipboard.o \ + testautomation_events.o \ + testautomation_keyboard.o \ + testautomation_main.o \ + testautomation_mouse.o \ + testautomation_pixels.o \ + testautomation_platform.o \ + testautomation_rect.o \ + testautomation_render.o \ + testautomation_rwops.o \ + testautomation_sdltest.o \ + testautomation_stdlib.o \ + testautomation_surface.o \ + testautomation_syswm.o \ + testautomation_timer.o \ + testautomation_video.o \ + testautomation_hints.o + $(CC) -o $@ $^ $(LIBS) + +testmultiaudio: testmultiaudio.o + $(CC) -o $@ $^ $(LIBS) + +testaudiohotplug: testaudiohotplug.o + $(CC) -o $@ $^ $(LIBS) + +testaudiocapture: testaudiocapture.o + $(CC) -o $@ $^ $(LIBS) + +testatomic: testatomic.o + $(CC) -o $@ $^ $(LIBS) + +testintersections: testintersections.o + $(CC) -o $@ $^ $(LIBS) + +testrelative: testrelative.o + $(CC) -o $@ $^ $(LIBS) + +testhittesting: testhittesting.o + $(CC) -o $@ $^ $(LIBS) + +testdraw2: testdraw2.o + $(CC) -o $@ $^ $(LIBS) + +testdrawchessboard: testdrawchessboard.o + $(CC) -o $@ $^ $(LIBS) + +testdropfile: testdropfile.o + $(CC) -o $@ $^ $(LIBS) + +testerror: testerror.o + $(CC) -o $@ $^ $(LIBS) + +testfile: testfile.o + $(CC) -o $@ $^ $(LIBS) + +testgamecontroller: testgamecontroller.o + $(CC) -o $@ $^ $(LIBS) + +testgesture: testgesture.o + $(CC) -o $@ $^ $(LIBS) + +testgl2: testgl2.o + $(CC) -o $@ $^ $(LIBS) + +testgles: testgles.o + $(CC) -o $@ $^ $(LIBS) + +testgles2: testgles2.o + $(CC) -o $@ $^ $(LIBS) + +testhaptic: testhaptic.o + $(CC) -o $@ $^ $(LIBS) + +testhotplug: testhotplug.o + $(CC) -o $@ $^ $(LIBS) + +testrumble: testrumble.o + $(CC) -o $@ $^ $(LIBS) + +testthread: testthread.o + $(CC) -o $@ $^ $(LIBS) + +testiconv: testiconv.o + $(CC) -o $@ $^ $(LIBS) + +testime: testime.o + $(CC) -o $@ $^ $(LIBS) + +testjoystick: testjoystick.o + $(CC) -o $@ $^ $(LIBS) + +testkeys: testkeys.o + $(CC) -o $@ $^ $(LIBS) + +testloadso: testloadso.o + $(CC) -o $@ $^ $(LIBS) + +testlock: testlock.o + $(CC) -o $@ $^ $(LIBS) + +testnative: testnative.o testnativeamigaos4.o + $(CC) -o $@ $^ $(LIBS) + +testoffscreen: testoffscreen.o + $(CC) -o $@ $^ $(LIBS) + +testoverlay2: testoverlay2.o testyuv_cvt.o + $(CC) -o $@ $^ $(LIBS) + +testplatform: testplatform.o + $(CC) -o $@ $^ $(LIBS) + +testpower: testpower.o + $(CC) -o $@ $^ $(LIBS) + +testfilesystem: testfilesystem.o + $(CC) -o $@ $^ $(LIBS) + +testrendertarget: testrendertarget.o + $(CC) -o $@ $^ $(LIBS) + +testscale: testscale.o + $(CC) -o $@ $^ $(LIBS) + +testsem: testsem.o + $(CC) -o $@ $^ $(LIBS) + +testsensor: testsensor.o + $(CC) -o $@ $^ $(LIBS) + +testshader: testshader.o + $(CC) -o $@ $^ $(LIBS) + +testshape: testshape.o + $(CC) -o $@ $^ $(LIBS) + +testsprite2: testsprite2.o + $(CC) -o $@ $^ $(LIBS) + +testspriteminimal: testspriteminimal.o + $(CC) -o $@ $^ $(LIBS) + +teststreaming: teststreaming.o + $(CC) -o $@ $^ $(LIBS) + +testtimer: testtimer.o + $(CC) -o $@ $^ $(LIBS) + +testver: testver.o + $(CC) -o $@ $^ $(LIBS) + +testviewport: testviewport.o + $(CC) -o $@ $^ $(LIBS) + +testwm2: testwm2.o + $(CC) -o $@ $^ $(LIBS) + +testyuv: testyuv.o testyuv_cvt.o + $(CC) -o $@ $^ $(LIBS) + +torturethread: torturethread.o + $(CC) -o $@ $^ $(LIBS) + +testrendercopyex: testrendercopyex.o + $(CC) -o $@ $^ $(LIBS) + +testmessage: testmessage.o + $(CC) -o $@ $^ $(LIBS) + +testdisplayinfo: testdisplayinfo.o + $(CC) -o $@ $^ $(LIBS) + +testqsort: testqsort.o + $(CC) -o $@ $^ $(LIBS) + +testbounds: testbounds.o + $(CC) -o $@ $^ $(LIBS) + +testcustomcursor: testcustomcursor.o + $(CC) -o $@ $^ $(LIBS) + +controllermap: controllermap.o + $(CC) -o $@ $^ $(LIBS) + +testvulkan: testvulkan.o + $(CC) -o $@ $^ $(LIBS) + +testurl: testurl.o + $(CC) -o $@ $^ $(LIBS) + +clean: + rm -f $(TARGETS) *.o diff --git a/test/Makefile.in b/test/Makefile.in index 6cf97ed2c27fa..65fe1fd8436df 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -222,14 +222,21 @@ testnative$(EXE): $(srcdir)/testnative.c \ $(CC) -o $@ $^ $(CFLAGS) $(LIBS) @XLIB@ endif +ifeq (@ISAMIGAOS@,true) +testnative$(EXE): $(srcdir)/testnative.c $(srcdir)/testnativeamigaos4.c + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) +endif + #there's probably a better way of doing this ifeq (@ISMACOSX@,false) ifeq (@ISWINDOWS@,false) ifeq (@ISUNIX@,false) +ifeq (@ISAMIGAOS@,false) testnative$(EXE): ; endif endif endif +endif testoverlay2$(EXE): $(srcdir)/testoverlay2.c $(srcdir)/testyuv_cvt.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) diff --git a/test/configure b/test/configure index 59e027cd90df6..e1643c9027f46 100755 --- a/test/configure +++ b/test/configure @@ -603,6 +603,7 @@ PKG_CONFIG ISUNIX ISWINDOWS ISMACOSX +ISAMIGAOS MATHLIB EXE OSMESA_CONFIG @@ -2897,8 +2898,12 @@ fi ISUNIX="false" ISWINDOWS="false" ISMACOSX="false" +ISAMIGAOS="false" case "$host" in + *-*-amigaos*) + ISAMIGAOS="true" + ;; *-*-cygwin* | *-*-mingw*) ISWINDOWS="true" EXE=".exe" diff --git a/test/configure.ac b/test/configure.ac index e2067e3adda2e..110a74353cd35 100644 --- a/test/configure.ac +++ b/test/configure.ac @@ -18,9 +18,13 @@ dnl (Haiku, for example, sets none of these.) ISUNIX="false" ISWINDOWS="false" ISMACOSX="false" +ISAMIGAOS="false" dnl Figure out which math library to use case "$host" in + *-*-amigaos*) + ISAMIGAOS="true" + ;; *-*-cygwin* | *-*-mingw*) ISWINDOWS="true" EXE=".exe" diff --git a/test/helloworld.c b/test/helloworld.c new file mode 100644 index 0000000000000..7fb93760803bb --- /dev/null +++ b/test/helloworld.c @@ -0,0 +1,868 @@ +/* + +This is not an official SDL2 test. It's a collection of random tests +for doing ad-hoc testing related to AmigaOS 4 port. + +*/ + +#include +#include "SDL2/SDL.h" +#include "SDL2/SDL_opengl.h" + +#if SDL_BYTEORDER != SDL_BIG_ENDIAN +#warning "wrong endian?" +#endif + +static SDL_bool eventLoopInner(void) +{ + SDL_bool running = SDL_TRUE; + SDL_Event e; + + while(SDL_PollEvent(&e)) { + switch (e.type) { + case SDL_QUIT: + puts("Quit"); + running = SDL_FALSE; + break; + + case SDL_WINDOWEVENT: + { + SDL_WindowEvent * we = (SDL_WindowEvent *)&e; + printf("Window event %d window %d\n", we->event, we->windowID); + } + break; + + case SDL_SYSWMEVENT: + printf("Sys WM event\n"); + break; + + case SDL_KEYDOWN: + { + SDL_KeyboardEvent * ke = (SDL_KeyboardEvent *)&e; + printf("Key down scancode %d (%s), keycode %d (%s)\n", + ke->keysym.scancode, SDL_GetScancodeName(ke->keysym.scancode), + ke->keysym.sym, SDL_GetKeyName(ke->keysym.sym)); + } + break; + + case SDL_KEYUP: + { + SDL_KeyboardEvent * ke = (SDL_KeyboardEvent *)&e; + printf("Key up %d\n", ke->keysym.scancode); + } + break; + + case SDL_TEXTEDITING: + puts("Text editing"); + break; + + case SDL_TEXTINPUT: + { + SDL_TextEditingEvent * te = (SDL_TextEditingEvent *)&e; + SDL_Window * w = SDL_GetWindowFromID(te->windowID); + + printf("Text input '%s'\n", te->text); + + if (strcmp("q", te->text) == 0) { + running = SDL_FALSE; + } else if (strcmp("w", te->text) == 0) { + SDL_WarpMouseInWindow(w, 50, 50); + } else if (strcmp("f", te->text) == 0) { + static int t = 1; + + printf("Toggle fullscreen %d\n", t); + SDL_SetWindowFullscreen(w, t ? SDL_WINDOW_FULLSCREEN : 0); + + t ^= 1; + } else if (strcmp("t", te->text) == 0) { + puts("Change size..."); + SDL_SetWindowSize(w, rand() % 1000, rand() % 1000); + } else if (strcmp("c", te->text) == 0) { + static int c = 1; + SDL_ShowCursor(c); + c ^= 1; + } + } + break; + + case SDL_MOUSEMOTION: + { + SDL_MouseMotionEvent * me = (SDL_MouseMotionEvent *)&e; + printf("Mouse motion x=%d, y=%d, xrel=%d, yrel=%d\n", me->x, me->y, me->xrel, me->yrel); + } + break; + + case SDL_MOUSEBUTTONDOWN: + { + SDL_MouseButtonEvent * me = (SDL_MouseButtonEvent *)&me; + printf("Mouse button down %d, state %d\n", (int)me->button, (int)me->state); + } + break; + + case SDL_MOUSEBUTTONUP: + { + SDL_MouseButtonEvent * me = (SDL_MouseButtonEvent *)&me; + printf("Mouse button up %d, state %d\n", (int)me->button, (int)me->state); + } + break; + + case SDL_MOUSEWHEEL: + { + SDL_MouseWheelEvent * me = (SDL_MouseWheelEvent *)&me; + printf("Mouse wheel x=%d, y=%d\n", me->x, me->y); + } + break; + + default: + printf("Unhandled event %d\n", e.type); + break; + } + } + + return running; +} + +static void eventLoop() +{ + while (eventLoopInner()) { + SDL_Delay(1); + } +} + +static void testPath(void) +{ + char * bp = SDL_GetBasePath(); + printf("'%s'\n", bp); + SDL_free(bp); + + char* pp = SDL_GetPrefPath("foo", "bar"); + printf("'%s'\n", pp); + SDL_free(pp); +} + +static void testWindow() +{ + SDL_Window * w = SDL_CreateWindow("blah", 100, 100, 100, 100, SDL_WINDOW_RESIZABLE); + + if (w) { + SDL_SetWindowMinimumSize(w, 50, 50); + SDL_SetWindowMaximumSize(w, 200, 200); + + SDL_MinimizeWindow(w); + SDL_Delay(1000); + + SDL_RestoreWindow(w); + SDL_Delay(1000); + + SDL_MinimizeWindow(w); + SDL_Delay(1000); + + SDL_MaximizeWindow(w); + + eventLoop(); + + SDL_DestroyWindow(w); + } +} + +static void testManyWindows() +{ + SDL_Window * w = SDL_CreateWindow("blah", 100, 100, 100, 100, 0); + SDL_Window * w2 = SDL_CreateWindow("blah2", 200, 100, 100, 100, 0/*SDL_WINDOW_FULLSCREEN*/); + + if (w && w2) { + SDL_SetWindowGrab(w, SDL_TRUE); + + eventLoop(); + + SDL_DestroyWindow(w); + SDL_DestroyWindow(w2); + } +} + +static void testRelativeMouse() +{ + SDL_Window * w = SDL_CreateWindow("relative", 100, 100, 100, 100, 0); + + if (w) { + //SDL_SetRelativeMouseMode(SDL_FALSE); + //SDL_SetRelativeMouseMode(SDL_TRUE); + + eventLoop(); + + SDL_DestroyWindow(w); + } +} + +static void testFullscreen() +{ + SDL_Window * w = SDL_CreateWindow("Fullscreen", + SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, + 640, 480, + SDL_WINDOW_FULLSCREEN); + + if (w) { + //SDL_SetWindowSize(w, 1280, 960); + //SDL_SetWindowSize(w, 640, 480); + //SDL_SetWindowSize(w, 800, 600); + + //SDL_SetWindowFullscreen(w, SDL_WINDOW_FULLSCREEN); + //SDL_SetWindowFullscreen(w, SDL_WINDOW_FULLSCREEN); + //SDL_SetWindowFullscreen(w, 0); + //SDL_SetWindowFullscreen(w, 0); + + SDL_Delay(3000); + +#if 0 + SDL_DisplayMode dm; + dm.format = SDL_PIXELFORMAT_ARGB8888; + dm.w = 1280; + dm.h = 960; + dm.refresh_rate = 0; + dm.driverdata = NULL; + + SDL_SetWindowDisplayMode(w, &dm); + SDL_SetWindowFullscreen(w, SDL_WINDOW_FULLSCREEN); +#endif + eventLoop(); + + SDL_DestroyWindow(w); + } +} + +static void testFullscreenDesktop() +{ + SDL_Window * w = SDL_CreateWindow("Desktop mode", + SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, + 640, 400, + SDL_WINDOW_FULLSCREEN_DESKTOP); + + if (w) { + eventLoop(); + + SDL_DestroyWindow(w); + } +} + +// TODO: should load GL functions +// NOTE: will not work on OGLES2 (try testgles2.c instead of) +static void drawUsingFixedFunctionPipeline(SDL_Window *w) +{ + if (w) { + SDL_GLContext c = SDL_GL_CreateContext(w); + + if (c) { + + //SDL_GL_SetSwapInterval(1); + + Uint32 start = SDL_GetTicks(); + Uint32 frames = 0; + + while (eventLoopInner()) { + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + + glBegin(GL_TRIANGLES); + + glColor4f(1.0f, 0.0f, 0.0f, 1.0f); + glVertex3f(-0.5f, -0.5f, 0.0f); + + glColor4f(0.0f, 1.0f, 0.0f, 1.0f); + glVertex3f(0.5f, -0.5f, 0.0f); + + glColor4f(0.0f, 0.0f, 1.0f, 1.0f); + glVertex3f(0.0f, 0.5f, 0.0f); + + glEnd(); + + SDL_GL_SwapWindow(w); + frames++; + } + + Uint32 end = SDL_GetTicks(); + printf("%u frames in %u ms - %f\n", frames, end - start, 1000.f * frames / (end - start)); + + + SDL_GL_DeleteContext(c); + } + + SDL_DestroyWindow(w); + } + +} + +static SDL_Window* createWindow(const char *name) +{ + return SDL_CreateWindow(name, + SDL_WINDOWPOS_CENTERED, + SDL_WINDOWPOS_CENTERED, + 400, + 300, + SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL); +} + +static void testDeleteContext() +{ + SDL_Window* w = createWindow("Context deletion"); + if (w) { + SDL_GLContext c = SDL_GL_CreateContext(w); + + if (c) { + SDL_GL_DeleteContext(c); + + printf("Context after deletion: %p\n", SDL_GL_GetCurrentContext()); + + SDL_SetWindowSize(w, 101, 101); + + c = SDL_GL_CreateContext(w); + + if (c) { + SDL_GL_DeleteContext(c); + } + } + SDL_DestroyWindow(w); + } +} + +static void testOpenGL() +{ + SDL_Window * w = createWindow("Centered & Resizable OpenGL window"); + + drawUsingFixedFunctionPipeline(w); +} + +static void testOpenGLES2() +{ + int mask, major, minor; + + SDL_GL_GetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, &mask); + SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, &major); + SDL_GL_GetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, &minor); + + printf("Current GL mask %d, major version %d, minor version %d\n", mask, major, minor); + + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); + + SDL_Window * w = createWindow("Centered & Resizable OGLES2 window"); + + if (w) + { + SDL_GLContext c = SDL_GL_CreateContext(w); + + if (c) { + puts("OGLES2 context created, now exiting"); + SDL_GL_DeleteContext(c); + } else { + puts("Failed to create OGLES2 context"); + } + + SDL_DestroyWindow(w); + } else { + puts("Failed to create OGLES2 window"); + } + + // Restore flags + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, mask); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, major); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, minor); +} + + +static void testOpenGLSwitching() +{ + SDL_Window* w = createWindow("Centered & Resizable OpenGL window"); + + if (w) { + SDL_DestroyWindow(w); + } + + // Switch to OGLES2 + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); + + w = createWindow("Centered & Resizable OGLES2 window"); + + if (w) { + SDL_DestroyWindow(w); + } else { + printf("%s\n", SDL_GetError()); + } + + // Switch back to MiniGL + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, 0); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); + + w = createWindow("Centered & Resizable OpenGL window"); + + drawUsingFixedFunctionPipeline(w); +} + +static void testFullscreenOpenGL() +{ + SDL_Window * w = SDL_CreateWindow("Fullscreen", + SDL_WINDOWPOS_CENTERED, + SDL_WINDOWPOS_CENTERED, + 1200, + 900, + SDL_WINDOW_FULLSCREEN | SDL_WINDOW_OPENGL); + + drawUsingFixedFunctionPipeline(w); +} + +static void testOpenGLVersion() +{ + int mask, major, minor; + + SDL_GL_GetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, &mask); + SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, &major); + SDL_GL_GetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, &minor); + + printf("Current GL mask %d, major version %d, minor version %d\n", mask, major, minor); +} + +static void testRenderer() +{ + SDL_Window * r = SDL_CreateWindow("Red", 0, 0, 100, 100, SDL_WINDOW_RESIZABLE); + SDL_Window * g = SDL_CreateWindow("Green", 200, 200, 100, 100, SDL_WINDOW_RESIZABLE); + SDL_Window * b = SDL_CreateWindow("Blue", 400, 400, 100, 100, SDL_WINDOW_RESIZABLE); + + SDL_Renderer * rr = SDL_CreateRenderer(r, -1, SDL_RENDERER_SOFTWARE); + SDL_Renderer * gr = SDL_CreateRenderer(g, -1, SDL_RENDERER_SOFTWARE); + SDL_Renderer * br = SDL_CreateRenderer(b, -1, SDL_RENDERER_ACCELERATED); + + if (r && g && b && rr && gr && br) { + while (eventLoopInner()) { + SDL_SetRenderDrawColor(rr, 255, 0, 0, 255); + SDL_RenderClear(rr); + SDL_RenderPresent(rr); + + SDL_SetRenderDrawColor(gr, 0, 255, 0, 255); + SDL_RenderClear(gr); + SDL_RenderPresent(gr); + + SDL_SetRenderDrawColor(br, 0, 0, 255, 255); + SDL_RenderClear(br); + SDL_RenderPresent(br); + } + + SDL_DestroyRenderer(rr); + SDL_DestroyRenderer(gr); + SDL_DestroyRenderer(br); + + SDL_DestroyWindow(r); + SDL_DestroyWindow(g); + SDL_DestroyWindow(b); + } else { + printf("%s\n", SDL_GetError()); + } +} + +static void testDraw() +{ + SDL_Window * w = SDL_CreateWindow("Draw", 100, 100, 200, 200, SDL_WINDOW_RESIZABLE); + + SDL_Renderer * r = SDL_CreateRenderer(w, -1, /*SDL_RENDERER_SOFTWARE*/ SDL_RENDERER_ACCELERATED); + + if (w && r) { + while (eventLoopInner()) { + SDL_Rect rect; + + SDL_SetRenderDrawColor(r, 100, 100, 100, 255); + SDL_RenderClear(r); + + SDL_SetRenderDrawColor(r, 200, 200, 200, 255); + + rect.x = 10; + rect.y = 10; + rect.w = 100; + rect.h = 100; + + SDL_RenderFillRect(r, &rect); + + SDL_RenderPresent(r); + } + + SDL_DestroyRenderer(r); + SDL_DestroyWindow(w); + } +} + +static void testRenderVsync() +{ + SDL_Window * w = SDL_CreateWindow("Draw", 100, 100, 200, 200, SDL_WINDOW_RESIZABLE); + + SDL_SetHint(SDL_HINT_RENDER_VSYNC, "1"); + + SDL_Renderer * r = SDL_CreateRenderer(w, -1, /*SDL_RENDERER_SOFTWARE*/ SDL_RENDERER_ACCELERATED); + + if (w && r) { + while (eventLoopInner()) { + SDL_Rect rect; + + SDL_SetRenderDrawColor(r, 100, 100, 100, 255); + SDL_RenderClear(r); + + SDL_SetRenderDrawColor(r, 200, 200, 200, 255); + + rect.x = 10; + rect.y = 10; + rect.w = 100; + rect.h = 100; + + SDL_RenderFillRect(r, &rect); + + SDL_RenderPresent(r); + } + + SDL_DestroyRenderer(r); + SDL_DestroyWindow(w); + } +} + +static void testBmp() +{ + SDL_Surface *s = SDL_LoadBMP("sample.bmp"); + + if (s) { + SDL_FreeSurface(s); + } else { + printf("%s\n", SDL_GetError()); + } +} + +static void testMessageBox() +{ + int button = 0; + int result; + + const SDL_MessageBoxButtonData buttons[] = { + {0, 1, "button 1"}, // flags, id, text + {0, 2, "button 2"} // flags, id, text + }; + + const SDL_MessageBoxData mb = { + 0, // flags + 0, // window + "Title", + "Message", + SDL_arraysize(buttons), // numbuttons + buttons, + NULL + }; + + result = SDL_ShowMessageBox(&mb, &button); + + printf("MB returned %d, button %d\n", result, button); +} + +static void testAltivec() +{ + printf("AltiVec: %d\n", SDL_HasAltiVec()); +} + +static void testPC() +{ + Uint64 pc1 = SDL_GetPerformanceCounter(); + + SDL_Delay(1000); + + Uint64 pc2 = SDL_GetPerformanceCounter(); + + Uint64 f = SDL_GetPerformanceFrequency(); + + double result = (pc2 - pc1) / (double)f; + + printf("%f s\n", result); +} + +static void testSystemCursors() +{ + SDL_Window * w = SDL_CreateWindow("blah", 100, 100, 100, 100, 0); + + if (w) { + int c = 0; + + while (eventLoopInner()) { + + char buf[32]; + snprintf(buf, sizeof(buf), "Cursor %d", c); + + SDL_SetWindowTitle(w, buf); + + SDL_SetCursor( SDL_CreateSystemCursor(c) ); + SDL_ShowCursor(1); + + SDL_Delay(1000); + + if (++c == SDL_NUM_SYSTEM_CURSORS) { + c = 0; + SDL_ShowCursor(0); + SDL_SetWindowTitle(w, "Hidden"); + SDL_Delay(1000); + } + } + + SDL_DestroyWindow(w); + } +} + +static void testCustomCursor() +{ + int w = 64; + int h = 64; + + SDL_Surface *surface = SDL_CreateRGBSurface(0, w, h, 32, + 0x00FF0000, + 0x0000FF00, + 0x000000FF, + 0xFF000000); + + if (surface) { + + int x, y; + + //printf("pitch %d\n", surface->pitch); + + for (y = 0; y < h; y++) { + + Uint32 *p = (Uint32 *)((Uint8 *)surface->pixels + y * surface->pitch); + + Uint32 color = 0xFF000000 | rand(); + + for (x = 0; x < w; x++) { + p[x] = color; + } + } + + //SDL_FillRect(surface, NULL, 0xFFFFFFFF); + + SDL_Window * w = SDL_CreateWindow("Custom cursor", 100, 100, 100, 100, 0); + + if (w) { + + SDL_SetCursor( SDL_CreateColorCursor(surface, 0, 0)); + + while (eventLoopInner()) { + + SDL_Delay(1000); + } + + SDL_DestroyWindow(w); + } + + SDL_FreeSurface(surface); + } +} + + +static void testHiddenCursor() +{ + //SDL_ShowCursor(0); + + SDL_Window * w = SDL_CreateWindow("Hidden cursor", 0, 0, 640, 480, SDL_WINDOW_FULLSCREEN); + + if (w) { + while (eventLoopInner()) { + SDL_Delay(1000); + } + + SDL_DestroyWindow(w); + } +} + + +static void testClipboard() +{ + SDL_Window * w = SDL_CreateWindow("Clipboard", 100, 100, 100, 100, 0); + + if (w) { + + while (eventLoopInner()) { + + if (SDL_HasClipboardText()) { + printf("Text '%s' found\n", SDL_GetClipboardText()); + } + + SDL_Delay(1000); + } + + SDL_DestroyWindow(w); + } + + puts("Leaving message to clipboard"); + + SDL_SetClipboardText("Amiga rules!"); +} + +static void testHint() +{ + char *result1 = (char *)SDL_GetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS); + char *result2 = (char *)SDL_GetHint("SDL_VIDEO_MINIMIZE_ON_FOCUS_LOSS"); + + printf("%s, %s\n", result1, result2); +} + +static void testGlobalMouseState() +{ + SDL_Window * w = SDL_CreateWindow("Global Mouse State", 100, 100, 100, 100, 0); + + if (w) { + + while (eventLoopInner()) { + + int x = 0; + int y = 0; + + printf("State 0x%x (%d, %d)\n", SDL_GetGlobalMouseState(&x, &y), x, y); + SDL_Delay(1000); + } + + SDL_DestroyWindow(w); + } +} + +static void testGlobalMouseWarp() +{ + SDL_Window * w = SDL_CreateWindow("Global Mouse Warp", 100, 100, 100, 100, 0); + + if (w) { + + while (eventLoopInner()) { + + int x = rand() % 800; + int y = rand() % 600; + + printf("Warping to %d, %d\n", x, y); + SDL_WarpMouseGlobal(x, y); + + SDL_Delay(1000); + } + + SDL_DestroyWindow(w); + } +} + +static void testOpaqueWindow() +{ + SDL_Window * w = SDL_CreateWindow("Opaque window", 100, 100, 100, 100, 0); + + if (w) { + + while (eventLoopInner()) { + float opacity = 0.0f; + + while (opacity <= 1.1f) { + printf("Opacity %f\n", opacity); + SDL_SetWindowOpacity(w, opacity); + opacity += 0.1f; + SDL_Delay(100); + } + } + + SDL_DestroyWindow(w); + } +} + +static void testWindowBordersSize() +{ + SDL_Window * w = SDL_CreateWindow("BorderSizes window", 100, 100, 100, 100, SDL_WINDOW_RESIZABLE); + + if (w) { + + int top, left, bottom, right; + + SDL_GetWindowBordersSize(w, &top, &left, &bottom, &right); + + printf("top %d, left %d, bottom %d, right %d\n", top, left, bottom, right); + + while (eventLoopInner()) { + SDL_Delay(1000); + } + + SDL_DestroyWindow(w); + } +} + +static void testHiddenWindow() +{ + SDL_Window * w = SDL_CreateWindow("Hidden window", 100, 100, 100, 100, SDL_WINDOW_HIDDEN); + + if (w) { + int i = 0; + + while (eventLoopInner()) { + + SDL_Delay(1000); + + ((i++ % 2) == 0) ? SDL_ShowWindow(w) : SDL_HideWindow(w); + } + + SDL_DestroyWindow(w); + } +} + +static void testInitEverything() +{ + if (SDL_Init(SDL_INIT_EVERYTHING) == 0) { + puts("I works?"); + } else { + puts("Expected failure, there is no force feedback (haptic) here"); + } + + SDL_Quit(); +} + +int main(void) +{ + if (0) testInitEverything(); + + if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) == 0) { + if (1) testPath(); + if (0) testWindow(); + if (0) testManyWindows(); + if (0) testFullscreen(); + if (0) testFullscreenOpenGL(); + if (0) testDeleteContext(); + if (0) testOpenGL(); + if (0) testOpenGLES2(); + if (0) testOpenGLSwitching(); + if (0) testOpenGLVersion(); + if (0) testRenderer(); + if (0) testDraw(); + if (0) testMessageBox(); + if (0) testBmp(); + if (0) testAltivec(); + if (0) testFullscreenDesktop(); + if (0) testRenderVsync(); + if (0) testPC(); + if (0) testPC(); + if (0) testSystemCursors(); + if (0) testCustomCursor(); + if (0) testHiddenCursor(); + if (0) testClipboard(); + if (0) testHint(); + if (0) testGlobalMouseState(); + if (0) testGlobalMouseWarp(); + if (0) testOpaqueWindow(); + if (0) testWindowBordersSize(); + if (0) testHiddenWindow(); + if (0) testRelativeMouse(); + } else { + printf("%s\n", SDL_GetError()); + } + + SDL_Quit(); + + return 0; +} diff --git a/test/sdl2benchmark.c b/test/sdl2benchmark.c new file mode 100755 index 0000000000000..570b71af0e6cd --- /dev/null +++ b/test/sdl2benchmark.c @@ -0,0 +1,738 @@ +/* + +This is a simple SDL2 renderer benchmark tool. It test every active +renderer with available blend modes. + +On AmigaOS, result may be affected by Workbench screen depth in case +pixel conversion takes place. For example compositing renderer works +best with 32-bit screen mode. + +Some blend modes may not be supported for all renderers. These tests +will give failure. + +TODO: +- command line arguments for things like window size, iterations... + +*/ + +#include "SDL2/SDL.h" + +#define BENCHMARK_VERSION "0.6" + +#define WIDTH 800 +#define HEIGHT 600 + +#define RECTSIZE 100 + +#define DURATION 1.0 +#define OBJECTS 100 + +#define SLEEP 0 + +#ifdef __amigaos4__ +static const char stackCookie[] __attribute__((used)) = "$STACK:60000"; +#endif + +typedef struct { + SDL_Renderer *renderer; + SDL_Window *window; + SDL_Texture *texture; + SDL_Surface *surface; + SDL_BlendMode mode; + Uint32 width; + Uint32 height; + Uint32 rectsize; + Uint32 texturewidth; + Uint32 textureheight; + Uint64 frequency; + double duration; + Uint32 objects; + Uint32 sleep; + Uint32 frames; + Uint32 operations; + Uint32 *buffer; + SDL_bool running; + const char* rendname; +} Context; + +typedef struct { + const char *name; + SDL_bool (*testfp)(Context *); + SDL_bool usetexture; +} Test; + +typedef struct { + const char *name; + SDL_BlendMode mode; +} BlendMode; + +/* Test function prototypes */ +static SDL_bool testPoints(Context *); +static SDL_bool testLines(Context *); +static SDL_bool testFillRects(Context *); +static SDL_bool testRenderCopy(Context *); +static SDL_bool testRenderCopyEx(Context *); +static SDL_bool testColorModulation(Context *); +static SDL_bool testAlphaModulation(Context *); +static SDL_bool testUpdateTexture(Context *); +static SDL_bool testReadPixels(Context *); + +/* Insert here new tests */ +static const Test tests[] = { + { "Points", testPoints, SDL_FALSE }, + { "Lines", testLines, SDL_FALSE }, + { "FillRects", testFillRects, SDL_FALSE }, + { "RenderCopy", testRenderCopy, SDL_TRUE }, + { "RenderCopyEx", testRenderCopyEx, SDL_TRUE }, + { "Color modulation", testColorModulation, SDL_TRUE }, + { "Alpha modulation", testAlphaModulation, SDL_TRUE }, + { "UpdateTexture", testUpdateTexture, SDL_TRUE }, + { "ReadPixels", testReadPixels, SDL_TRUE } +}; + +static const BlendMode modes[] = { + { "None", SDL_BLENDMODE_NONE }, + { "Blend", SDL_BLENDMODE_BLEND }, + { "Add", SDL_BLENDMODE_ADD }, + { "Mod", SDL_BLENDMODE_MOD } +}; + +static const char *getModeName(SDL_BlendMode mode) +{ + int i; + + static const char *unknown = "Unknown"; + + for (i = 0; i < sizeof(modes) / sizeof(modes[0]); i++) + { + if (modes[i].mode == mode) { + return modes[i].name; + } + } + + return unknown; +} + +static void printInfo(Context *ctx) +{ + SDL_RendererInfo ri; + int result; + + result = SDL_GetRendererInfo(ctx->renderer, &ri); + + if (result) { + SDL_Log("Failed to get renderer info: %s\n", SDL_GetError()); + } else { + + SDL_Log("Starting to test renderer called [%s], flags 0x%X\n", ri.name, ri.flags); + } +} + +static void render(Context *ctx) +{ + SDL_RenderPresent(ctx->renderer); + ctx->frames++; +} + +static SDL_bool clearDisplay(Context *ctx) +{ + int result; + + if (ctx->mode != SDL_BLENDMODE_MOD) { + result = SDL_SetRenderDrawColor(ctx->renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); + } else { + result = SDL_SetRenderDrawColor(ctx->renderer, 255, 255, 255, SDL_ALPHA_OPAQUE); + } + + if (result) { + SDL_Log("[%s]Failed to set draw color: %s\n", __FUNCTION__, SDL_GetError()); + return SDL_FALSE; + } + + result = SDL_RenderClear(ctx->renderer); + + if (result) { + SDL_Log("[%s]Failed to clear: %s\n", __FUNCTION__, SDL_GetError()); + return SDL_FALSE; + } + + SDL_RenderPresent(ctx->renderer); + + return SDL_TRUE; +} + +/* +static float interpolate(float min, float max, float percentage) +{ + return min + percentage * (max - min); +} +*/ + +static Uint32 getRand(Uint32 max) +{ + return rand() % max; +} + +static void makeRandomTexture(Context *ctx) +{ + int i; + + SDL_memset(ctx->buffer, 0, ctx->texturewidth * ctx->textureheight * sizeof(Uint32)); + + for (i = 0; i < 100; i++) { + ctx->buffer[ + getRand(ctx->texturewidth) + + getRand(ctx->textureheight) * ctx->texturewidth] = 0xFFFFFFFF; + } +} + +static SDL_bool prepareTexture(Context *ctx) +{ + int result; + + result = SDL_SetColorKey(ctx->surface, 1, 0); + + if (result) { + SDL_Log("[%s]Failed to set color key: %s\n", __FUNCTION__, SDL_GetError()); + return SDL_FALSE; + } + + if (ctx->texture) { + SDL_Log("Old texture!\n"); + } + + ctx->texture = SDL_CreateTextureFromSurface(ctx->renderer, ctx->surface); + + if (!ctx->texture) { + SDL_Log("[%s]Failed to create texture: %s\n", __FUNCTION__, SDL_GetError()); + return SDL_FALSE; + } + + result = SDL_SetTextureBlendMode(ctx->texture, ctx->mode); + + if (result) { + SDL_Log("[%s]Failed to set texture blend mode: %s\n", __FUNCTION__, SDL_GetError()); + + SDL_DestroyTexture(ctx->texture); + ctx->texture = NULL; + + return SDL_FALSE; + } + + ctx->texturewidth = ctx->surface->w; + ctx->textureheight = ctx->surface->h; + + ctx->buffer = SDL_malloc(ctx->texturewidth * ctx->textureheight * sizeof(Uint32)); + + if (!ctx->buffer) { + SDL_Log("[%s]Failed to allocate texture buffer: %s\n", __FUNCTION__, SDL_GetError()); + SDL_DestroyTexture(ctx->texture); + ctx->texture = NULL; + return SDL_FALSE; + } + + makeRandomTexture(ctx); + + return SDL_TRUE; +} + +static SDL_bool prepareTest(Context *ctx, const Test *test) +{ + if (!clearDisplay(ctx)) { + return SDL_FALSE; + } + + if (test->usetexture) { + if (!prepareTexture(ctx)) { + return SDL_FALSE; + } + } + + ctx->frames = 0; + ctx->operations = 0; + + return SDL_TRUE; +} + +static void afterTest(Context *ctx) +{ + if (ctx->texture) { + SDL_DestroyTexture(ctx->texture); + ctx->texture = NULL; + } + + if (ctx->buffer) { + SDL_free(ctx->buffer); + ctx->buffer = NULL; + } + + if (ctx->sleep) { + SDL_Delay(ctx->sleep); + } +} + +static SDL_bool runTest(Context *ctx, const Test *test) +{ + Uint64 start, finish; + double duration; + float fps, ops; + + if (!prepareTest(ctx, test)) { + return SDL_FALSE; + } + + start = SDL_GetPerformanceCounter(); + + do { + if (!test->testfp(ctx)) { + afterTest(ctx); + return SDL_FALSE; + } + + finish = SDL_GetPerformanceCounter(); + + duration = (finish - start) / (double)ctx->frequency; + } while (duration < ctx->duration); + + if (duration == 0.0) { + SDL_Log("Division by zero!\n"); + afterTest(ctx); + return SDL_FALSE; + } + + fps = ctx->frames / duration; + ops = ctx->operations / duration; + + if (fps == ops) { + SDL_Log("%s [mode: %s]...%d frames drawn in %.3f seconds => %.1f frames per second\n", + test->name, getModeName(ctx->mode), ctx->frames, duration, fps); + } else { + SDL_Log("%s [mode: %s]...%d frames drawn in %.3f seconds => %.1f frames per second, %.1f operations per second\n", + test->name, getModeName(ctx->mode), ctx->frames, duration, fps, ops); + } + + afterTest(ctx); + + return SDL_TRUE; +} + +static SDL_bool setRandomColor(Context *ctx) +{ + int result; + + result = SDL_SetRenderDrawColor(ctx->renderer, + getRand(256), getRand(256), getRand(256), getRand(256)); + + if (result) { + SDL_Log("[%s]Failed to set color: %s\n", __FUNCTION__, SDL_GetError()); + return SDL_FALSE; + } + + return SDL_TRUE; +} + +static SDL_bool testPointsInner(Context *ctx, SDL_bool linemode) +{ + int result = SDL_SetRenderDrawBlendMode(ctx->renderer, ctx->mode); + + if (result) { + SDL_Log("[%s]Failed to set blend mode: %s\n", __FUNCTION__, SDL_GetError()); + return SDL_FALSE; + } + + SDL_Point points[ctx->objects]; + int object; + + if (!setRandomColor(ctx)) { + return SDL_FALSE; + } + + for (object = 0; object < ctx->objects; object++) { + points[object].x = getRand(ctx->width); + points[object].y = getRand(ctx->height); + } + + result = linemode ? + SDL_RenderDrawLines(ctx->renderer, points, ctx->objects) : + SDL_RenderDrawPoints(ctx->renderer, points, ctx->objects); + + ctx->operations++; + + if (result) { + SDL_Log("[%s]Failed to draw lines/points: %s\n", __FUNCTION__, SDL_GetError()); + return SDL_FALSE; + } + + render(ctx); + + return SDL_TRUE; +} + +static SDL_bool testPoints(Context *ctx) +{ + return testPointsInner(ctx, SDL_FALSE); +} + +static SDL_bool testLines(Context *ctx) +{ + return testPointsInner(ctx, SDL_TRUE); +} + +static SDL_bool testFillRects(Context *ctx) +{ + int result = SDL_SetRenderDrawBlendMode(ctx->renderer, ctx->mode); + + if (result) { + SDL_Log("[%s]Failed to set blend mode: %s\n", __FUNCTION__, SDL_GetError()); + return SDL_FALSE; + } + + SDL_Rect rects[ctx->objects]; + int object; + + if (!setRandomColor(ctx)) { + return SDL_FALSE; + } + + const int rectsize = ctx->rectsize + getRand(100); // + iteration + + for (object = 0; object < ctx->objects; object++) { + rects[object].x = getRand(ctx->width - rectsize); + rects[object].y = getRand(ctx->height - rectsize); + rects[object].w = rectsize; + rects[object].h = rectsize; + } + + result = SDL_RenderFillRects(ctx->renderer, rects, ctx->objects); + + if (result) { + SDL_Log("[%s]Failed to draw filled rectangles: %s\n", __FUNCTION__, SDL_GetError()); + return SDL_FALSE; + } + + ctx->operations++; + + render(ctx); + + return SDL_TRUE; +} + +static SDL_bool testRenderCopyInner(Context *ctx, SDL_bool ex) +{ + int result; + + //int object; + //const float scale = interpolate(0.5f, 2.0f, (float)ctx->iteration / ctx->iterations); + const float scale = (getRand(4) + 1) / 2.0f; + + int w = ctx->texturewidth * scale; + int h = ctx->textureheight * scale; + + //for (object = 0; object < ctx->objects; object++) { + SDL_Rect rect; + + rect.x = getRand(ctx->width - w); + rect.y = getRand(ctx->height - h); + rect.w = w; + rect.h = h; + + if (!ex) { + result = SDL_RenderCopy(ctx->renderer, ctx->texture, NULL, &rect); + } else { + result = SDL_RenderCopyEx( + ctx->renderer, + ctx->texture, + NULL, + &rect, + getRand(360), + NULL, + SDL_FLIP_NONE); + } + + if (result) { + SDL_Log("[%s]Failed to draw texture: %s\n", __FUNCTION__, SDL_GetError()); + return SDL_FALSE; + } + + ctx->operations++; + //} + + render(ctx); + + return SDL_TRUE; +} + +static SDL_bool testRenderCopy(Context *ctx) +{ + return testRenderCopyInner(ctx, SDL_FALSE); +} + +static SDL_bool testRenderCopyEx(Context *ctx) +{ + return testRenderCopyInner(ctx, SDL_TRUE); +} + +static const SDL_Color colors[] = { + {255, 0, 0, 255}, + {0, 255, 0, 255}, + {0, 0, 255, 255}, + {127, 127, 127, 255} +}; + +static const size_t count = sizeof(colors) / sizeof(colors[0]); + +static SDL_bool testColorModulation(Context *ctx) +{ + static int i = 0; + + const int c = i++ % count; + + if (SDL_SetTextureColorMod(ctx->texture, colors[c].r, colors[c].g, colors[c].b)) { + SDL_Log("[%s]Failed to set color modulation: %s\n", __FUNCTION__, SDL_GetError()); + return SDL_FALSE; + } + + return testRenderCopyInner(ctx, SDL_FALSE); +} + +static SDL_bool testAlphaModulation(Context *ctx) +{ + if (SDL_SetTextureAlphaMod(ctx->texture, 127)) { + SDL_Log("[%s]Failed to set alpha modulation: %s\n", __FUNCTION__, SDL_GetError()); + return SDL_FALSE; + } + + return testRenderCopyInner(ctx, SDL_FALSE); +} + +static SDL_bool testUpdateTexture(Context *ctx) +{ + static int i = 0; + + const int c = i++ % count; + + if (SDL_SetTextureColorMod(ctx->texture, colors[c].r, colors[c].g, colors[c].b)) { + SDL_Log("[%s]Failed to set color modulation: %s\n", __FUNCTION__, SDL_GetError()); + return SDL_FALSE; + } + + if (SDL_UpdateTexture(ctx->texture, NULL, ctx->buffer, ctx->texturewidth * sizeof(Uint32))) { + SDL_Log("[%s]Failed to update texture: %s\n", __FUNCTION__, SDL_GetError()); + return SDL_FALSE; + } + + ctx->operations++; + + return testRenderCopyInner(ctx, SDL_FALSE); +} + +static SDL_bool testReadPixels(Context *ctx) +{ + SDL_bool result = SDL_TRUE; + + SDL_Rect rect; + rect.x = getRand(ctx->width - ctx->texturewidth); + rect.y = getRand(ctx->height - ctx->textureheight); + rect.w = ctx->texturewidth; + rect.h = ctx->textureheight; + + if (SDL_RenderReadPixels( + ctx->renderer, + &rect, + SDL_PIXELFORMAT_ARGB8888, + ctx->buffer, + ctx->texturewidth * sizeof(Uint32)) != 0) { + + SDL_Log("[%s]Failed to read pixels: %s\n", __FUNCTION__, SDL_GetError()); + + result = SDL_FALSE; + } + + ctx->operations++; + + return result; +} + +static void checkEvents(Context *ctx) +{ + SDL_Event e; + + while (SDL_PollEvent(&e)) { + if (e.type == SDL_KEYDOWN) { + SDL_KeyboardEvent *ke = (SDL_KeyboardEvent *)&e; + + if (ke->keysym.sym == SDLK_ESCAPE) { + SDL_Log("Quitting...\n"); + ctx->running = SDL_FALSE; + } + } + } +} + +static void runTestSuite(Context *ctx) +{ + int m, t; + + for (t = 0; t < sizeof(tests) / sizeof(tests[0]); t++) { + for (m = 0; m < sizeof(modes) / sizeof(modes[0]); m++) { + ctx->mode = modes[m].mode; + + runTest(ctx, &tests[t]); + + checkEvents(ctx); + + if (!ctx->running) { + return; + } + } + } +} + +/* TODO: need proper handling */ +static void checkParameters(Context *ctx, int argc, char **argv) +{ + if (argc > 3) { + ctx->sleep = atoi(argv[3]); + } + + if (argc > 2) { + ctx->duration = atof(argv[2]); + } + + if (argc > 1) { + ctx->rendname = argv[1]; + } +} + +static void initContext(Context *ctx, int argc, char **argv) +{ + SDL_memset(ctx, 0, sizeof(Context)); + + ctx->frequency = SDL_GetPerformanceFrequency(); + + ctx->width = WIDTH; + ctx->height = HEIGHT; + ctx->rectsize = RECTSIZE; + ctx->duration = DURATION; + ctx->objects = OBJECTS; + ctx->sleep = SLEEP; + ctx->running = SDL_TRUE; + + checkParameters(ctx, argc, argv); + + SDL_Log("Parameters: width %d, height %d, renderer name '%s', duration %.3f s, objects %u, sleep %u\n", + ctx->width, ctx->height, ctx->rendname, ctx->duration, ctx->objects, ctx->sleep); +} + +static void checkPixelFormat(Context *ctx) +{ + Uint32 pf; + + pf = SDL_GetWindowPixelFormat(ctx->window); + + SDL_Log("Pixel format 0x%X (%s)\n", pf, SDL_GetPixelFormatName(pf)); + + if (pf != SDL_PIXELFORMAT_ARGB8888 && pf != SDL_PIXELFORMAT_RGB888) { + SDL_Log("NOTE: window's pixel format not ARGB8888 - possible bitmap conversion can slow down\n"); + } +} + +static void testRenderer(Context *ctx) +{ + if (ctx->renderer) { + printInfo(ctx); + + runTestSuite(ctx); + + SDL_DestroyRenderer(ctx->renderer); + } else { + SDL_Log("Failed to create renderer: %s\n", SDL_GetError()); + } +} + +static void testSpecificRenderer(Context *ctx) +{ + SDL_SetHint(SDL_HINT_RENDER_DRIVER, ctx->rendname); + + ctx->renderer = SDL_CreateRenderer(ctx->window, -1, 0); + + testRenderer(ctx); +} + +static void testAllRenderers(Context *ctx) +{ + int r; + + for (r = 0; r < SDL_GetNumRenderDrivers(); r++) { + + ctx->renderer = SDL_CreateRenderer(ctx->window, r, 0); + + testRenderer(ctx); + + if (!ctx->running) { + break; + } + } +} + +int main(int argc, char **argv) +{ + Context ctx; + SDL_version linked; + + if (SDL_Init(SDL_INIT_VIDEO)) { + SDL_Log("Init failed: %s\n", SDL_GetError()); + return -1; + } + + SDL_GetVersion(&linked); + + SDL_Log("SDL2 renderer benchmark v. " BENCHMARK_VERSION " (SDL version %d.%d.%d)\n", + linked.major, linked.minor, linked.patch); + + SDL_Log("This tool measures the speed of various 2D drawing features\n"); + SDL_Log("Press ESC key to quit\n"); + + initContext(&ctx, argc, argv); + + ctx.surface = SDL_LoadBMP("sample.bmp"); + + if (ctx.surface) { + + SDL_Log("Image size %d*%d\n", ctx.surface->w, ctx.surface->h); + + ctx.window = SDL_CreateWindow( + "SDL2 benchmark", + SDL_WINDOWPOS_CENTERED, + SDL_WINDOWPOS_CENTERED, + ctx.width, + ctx.height, + SDL_WINDOW_FULLSCREEN); + + if (ctx.window) { + + checkPixelFormat(&ctx); + + if (ctx.rendname) { + testSpecificRenderer(&ctx); + } else { + testAllRenderers(&ctx); + } + + SDL_DestroyWindow(ctx.window); + } else { + SDL_Log("Failed to create window: %s\n", SDL_GetError()); + } + + SDL_FreeSurface(ctx.surface); + + } else { + SDL_Log("Failed do load image: %s\n", SDL_GetError()); + } + + SDL_Log("Bye bye\n"); + + SDL_Quit(); + + return 0; +} diff --git a/test/testautomation_rwops.c b/test/testautomation_rwops.c index a7d3c32725ad2..879abe1a425b9 100644 --- a/test/testautomation_rwops.c +++ b/test/testautomation_rwops.c @@ -398,7 +398,11 @@ rwops_testFPRead(void) int result; /* Run read tests. */ +#ifdef __amigaos4__ + fp = fopen64(RWopsReadTestFilename, "r"); +#else fp = fopen(RWopsReadTestFilename, "r"); +#endif SDLTest_AssertCheck(fp != NULL, "Verify handle from opening file '%s' in read mode is not NULL", RWopsReadTestFilename); /* Bail out if NULL */ @@ -448,7 +452,11 @@ rwops_testFPWrite(void) int result; /* Run write tests. */ +#ifdef __amigaos4__ + fp = fopen64(RWopsWriteTestFilename, "w+"); +#else fp = fopen(RWopsWriteTestFilename, "w+"); +#endif SDLTest_AssertCheck(fp != NULL, "Verify handle from opening file '%s' in write mode is not NULL", RWopsWriteTestFilename); /* Bail out if NULL */ diff --git a/test/testgles2.c b/test/testgles2.c index 4a223755aaf64..3aa6cd6c6f5ef 100644 --- a/test/testgles2.c +++ b/test/testgles2.c @@ -21,7 +21,7 @@ #include "SDL_test_common.h" #if defined(__IPHONEOS__) || defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__NACL__) \ - || defined(__WINDOWS__) || defined(__LINUX__) + || defined(__WINDOWS__) || defined(__LINUX__) || defined(__AMIGAOS4__) #define HAVE_OPENGLES2 #endif @@ -31,7 +31,7 @@ typedef struct GLES2_Context { -#define SDL_PROC(ret,func,params) ret (APIENTRY *func) params; +#define SDL_PROC(ret,func,params) ret (APIENTRY *my##func) params; #include "../src/render/opengles2/SDL_gles2funcs.h" #undef SDL_PROC } GLES2_Context; @@ -53,12 +53,12 @@ static int LoadContext(GLES2_Context * data) #endif #if defined __SDL_NOGETPROCADDR__ -#define SDL_PROC(ret,func,params) data->func=func; +#define SDL_PROC(ret,func,params) data->my##func=func; #else #define SDL_PROC(ret,func,params) \ do { \ - data->func = SDL_GL_GetProcAddress(#func); \ - if ( ! data->func ) { \ + data->my##func = SDL_GL_GetProcAddress(#func); \ + if ( ! data->my##func ) { \ return SDL_SetError("Couldn't load GLES2 function %s: %s", #func, SDL_GetError()); \ } \ } while ( 0 ); @@ -92,7 +92,7 @@ quit(int rc) #define GL_CHECK(x) \ x; \ { \ - GLenum glError = ctx.glGetError(); \ + GLenum glError = ctx.myglGetError(); \ if(glError != GL_NO_ERROR) { \ SDL_Log("glGetError() = %i (0x%.8x) at line %i\n", glError, glError, __LINE__); \ quit(1); \ @@ -204,22 +204,22 @@ process_shader(GLuint *shader, const char * source, GLint shader_type) GLsizei length; /* Create shader and load into GL. */ - *shader = GL_CHECK(ctx.glCreateShader(shader_type)); + *shader = GL_CHECK(ctx.myglCreateShader(shader_type)); shaders[0] = source; - GL_CHECK(ctx.glShaderSource(*shader, 1, shaders, NULL)); + GL_CHECK(ctx.myglShaderSource(*shader, 1, shaders, NULL)); /* Clean up shader source. */ shaders[0] = NULL; /* Try compiling the shader. */ - GL_CHECK(ctx.glCompileShader(*shader)); - GL_CHECK(ctx.glGetShaderiv(*shader, GL_COMPILE_STATUS, &status)); + GL_CHECK(ctx.myglCompileShader(*shader)); + GL_CHECK(ctx.myglGetShaderiv(*shader, GL_COMPILE_STATUS, &status)); /* Dump debug info (source and log) if compilation failed. */ if(status != GL_TRUE) { - ctx.glGetProgramInfoLog(*shader, sizeof(buffer), &length, &buffer[0]); + ctx.myglGetProgramInfoLog(*shader, sizeof(buffer), &length, &buffer[0]); buffer[length] = '\0'; SDL_Log("Shader compilation failed: %s", buffer);fflush(stderr); quit(-1); @@ -396,7 +396,7 @@ Render(unsigned int width, unsigned int height, shader_data* data) perspective_matrix(45.0f, (float)width/height, 0.01f, 100.0f, matrix_perspective); multiply_matrix(matrix_perspective, matrix_modelview, matrix_mvp); - GL_CHECK(ctx.glUniformMatrix4fv(data->attr_mvp, 1, GL_FALSE, matrix_mvp)); + GL_CHECK(ctx.myglUniformMatrix4fv(data->attr_mvp, 1, GL_FALSE, matrix_mvp)); data->angle_x += 3; data->angle_y += 2; @@ -409,8 +409,8 @@ Render(unsigned int width, unsigned int height, shader_data* data) if(data->angle_z >= 360) data->angle_z -= 360; if(data->angle_z < 0) data->angle_z += 360; - GL_CHECK(ctx.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)); - GL_CHECK(ctx.glDrawArrays(GL_TRIANGLES, 0, 36)); + GL_CHECK(ctx.myglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)); + GL_CHECK(ctx.myglDrawArrays(GL_TRIANGLES, 0, 36)); } int done; @@ -440,7 +440,7 @@ void loop() } /* Change view port to the new window dimensions */ SDL_GL_GetDrawableSize(state->windows[i], &w, &h); - ctx.glViewport(0, 0, w, h); + ctx.myglViewport(0, 0, w, h); state->window_w = event.window.data1; state->window_h = event.window.data2; /* Update window content */ @@ -580,10 +580,10 @@ main(int argc, char *argv[]) SDL_GetCurrentDisplayMode(0, &mode); SDL_Log("Screen bpp: %d\n", SDL_BITSPERPIXEL(mode.format)); SDL_Log("\n"); - SDL_Log("Vendor : %s\n", ctx.glGetString(GL_VENDOR)); - SDL_Log("Renderer : %s\n", ctx.glGetString(GL_RENDERER)); - SDL_Log("Version : %s\n", ctx.glGetString(GL_VERSION)); - SDL_Log("Extensions : %s\n", ctx.glGetString(GL_EXTENSIONS)); + SDL_Log("Vendor : %s\n", ctx.myglGetString(GL_VENDOR)); + SDL_Log("Renderer : %s\n", ctx.myglGetString(GL_RENDERER)); + SDL_Log("Version : %s\n", ctx.myglGetString(GL_VERSION)); + SDL_Log("Extensions : %s\n", ctx.myglGetString(GL_EXTENSIONS)); SDL_Log("\n"); status = SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &value); @@ -655,7 +655,7 @@ main(int argc, char *argv[]) continue; } SDL_GL_GetDrawableSize(state->windows[i], &w, &h); - ctx.glViewport(0, 0, w, h); + ctx.myglViewport(0, 0, w, h); data = &datas[i]; data->angle_x = 0; data->angle_y = 0; data->angle_z = 0; @@ -665,32 +665,32 @@ main(int argc, char *argv[]) process_shader(&data->shader_frag, _shader_frag_src, GL_FRAGMENT_SHADER); /* Create shader_program (ready to attach shaders) */ - data->shader_program = GL_CHECK(ctx.glCreateProgram()); + data->shader_program = GL_CHECK(ctx.myglCreateProgram()); /* Attach shaders and link shader_program */ - GL_CHECK(ctx.glAttachShader(data->shader_program, data->shader_vert)); - GL_CHECK(ctx.glAttachShader(data->shader_program, data->shader_frag)); - GL_CHECK(ctx.glLinkProgram(data->shader_program)); + GL_CHECK(ctx.myglAttachShader(data->shader_program, data->shader_vert)); + GL_CHECK(ctx.myglAttachShader(data->shader_program, data->shader_frag)); + GL_CHECK(ctx.myglLinkProgram(data->shader_program)); /* Get attribute locations of non-fixed attributes like color and texture coordinates. */ - data->attr_position = GL_CHECK(ctx.glGetAttribLocation(data->shader_program, "av4position")); - data->attr_color = GL_CHECK(ctx.glGetAttribLocation(data->shader_program, "av3color")); + data->attr_position = GL_CHECK(ctx.myglGetAttribLocation(data->shader_program, "av4position")); + data->attr_color = GL_CHECK(ctx.myglGetAttribLocation(data->shader_program, "av3color")); /* Get uniform locations */ - data->attr_mvp = GL_CHECK(ctx.glGetUniformLocation(data->shader_program, "mvp")); + data->attr_mvp = GL_CHECK(ctx.myglGetUniformLocation(data->shader_program, "mvp")); - GL_CHECK(ctx.glUseProgram(data->shader_program)); + GL_CHECK(ctx.myglUseProgram(data->shader_program)); /* Enable attributes for position, color and texture coordinates etc. */ - GL_CHECK(ctx.glEnableVertexAttribArray(data->attr_position)); - GL_CHECK(ctx.glEnableVertexAttribArray(data->attr_color)); + GL_CHECK(ctx.myglEnableVertexAttribArray(data->attr_position)); + GL_CHECK(ctx.myglEnableVertexAttribArray(data->attr_color)); /* Populate attributes for position, color and texture coordinates etc. */ - GL_CHECK(ctx.glVertexAttribPointer(data->attr_position, 3, GL_FLOAT, GL_FALSE, 0, _vertices)); - GL_CHECK(ctx.glVertexAttribPointer(data->attr_color, 3, GL_FLOAT, GL_FALSE, 0, _colors)); + GL_CHECK(ctx.myglVertexAttribPointer(data->attr_position, 3, GL_FLOAT, GL_FALSE, 0, _vertices)); + GL_CHECK(ctx.myglVertexAttribPointer(data->attr_color, 3, GL_FLOAT, GL_FALSE, 0, _colors)); - GL_CHECK(ctx.glEnable(GL_CULL_FACE)); - GL_CHECK(ctx.glEnable(GL_DEPTH_TEST)); + GL_CHECK(ctx.myglEnable(GL_CULL_FACE)); + GL_CHECK(ctx.myglEnable(GL_DEPTH_TEST)); } /* Main render loop */ diff --git a/test/testnative.c b/test/testnative.c index 21aee04c1631f..11504f0fba292 100644 --- a/test/testnative.c +++ b/test/testnative.c @@ -32,6 +32,9 @@ static NativeWindowFactory *factories[] = { #ifdef TEST_NATIVE_COCOA &CocoaWindowFactory, #endif +#ifdef TEST_NATIVE_AMIGAOS4 + &AmigaOS4WindowFactory, +#endif #ifdef TEST_NATIVE_OS2 &OS2WindowFactory, #endif diff --git a/test/testnative.h b/test/testnative.h index 611d99147aba2..c02e505e99b87 100644 --- a/test/testnative.h +++ b/test/testnative.h @@ -36,6 +36,11 @@ extern NativeWindowFactory WindowsWindowFactory; extern NativeWindowFactory X11WindowFactory; #endif +#ifdef SDL_VIDEO_DRIVER_AMIGAOS4 +#define TEST_NATIVE_AMIGAOS4 +extern NativeWindowFactory AmigaOS4WindowFactory; +#endif + #ifdef SDL_VIDEO_DRIVER_COCOA /* Actually, we don't really do this, since it involves adding Objective C support to the build system, which is a little tricky. You can uncomment diff --git a/test/testnativeamigaos4.c b/test/testnativeamigaos4.c new file mode 100644 index 0000000000000..e01c572dc5971 --- /dev/null +++ b/test/testnativeamigaos4.c @@ -0,0 +1,92 @@ +/* + Copyright (C) 1997-2017 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely. +*/ + +#include "testnative.h" + +#ifdef TEST_NATIVE_AMIGAOS4 + +#include +#include + +#include "../src/video/amigaos4/SDL_os4video.h" + +static struct Library * MyIntuitionBase; +static struct IntuitionIFace * MyIIntuition; + +static void *CreateWindowAmigaOS4(int w, int h); +static void DestroyWindowAmigaOS4(void *window); + +NativeWindowFactory AmigaOS4WindowFactory = { + "os4", + CreateWindowAmigaOS4, + DestroyWindowAmigaOS4 +}; + +static SDL_bool +OS4_OpenIntuition() +{ + SDL_bool result = SDL_FALSE; + + if (MyIIntuition) { + result = SDL_TRUE; + } else { + MyIntuitionBase = IExec->OpenLibrary("intuition.library", 50); + + if (MyIntuitionBase) { + MyIIntuition = (struct IntuitionIFace *) IExec->GetInterface(MyIntuitionBase, "main", 1, NULL); + if (MyIIntuition) { + result = SDL_TRUE; + } + } + } + + return result; +} + +static void * +CreateWindowAmigaOS4(int w, int h) +{ + struct Window * window = NULL; + + if (OS4_OpenIntuition()) { + + struct MsgPort * userport = OS4_GetSharedMessagePort(); + + if (userport) { + window = MyIIntuition->OpenWindowTags( + NULL, + WA_Title, "Native window", + WA_InnerWidth, w, + WA_InnerHeight, h, + WA_Flags, WFLG_CLOSEGADGET, + WA_IDCMP, IDCMP_CLOSEWINDOW, + WA_UserPort, userport, + TAG_DONE); + } + } + + return (void *) window; +} + +static void +DestroyWindowAmigaOS4(void *window) +{ + if (OS4_OpenIntuition()) { + MyIIntuition->CloseWindow(window); + + IExec->DropInterface((struct Interface *)MyIIntuition); + IExec->CloseLibrary(MyIntuitionBase); + } +} + +#endif + diff --git a/test/testoverlay2.c b/test/testoverlay2.c index 6afac4940ed72..c06232e7e0daf 100644 --- a/test/testoverlay2.c +++ b/test/testoverlay2.c @@ -32,6 +32,10 @@ #define MOOSEFRAME_SIZE (MOOSEPIC_W * MOOSEPIC_H) #define MOOSEFRAMES_COUNT 10 +#ifdef __amigaos4__ +static const char STACK_COOKIE[] __attribute__((used)) = "$STACK:200000"; +#endif + SDL_Color MooseColors[84] = { {49, 49, 49, SDL_ALPHA_OPAQUE} , {66, 24, 0, SDL_ALPHA_OPAQUE}