/od-win32/picasso96_win.cpp
C++ | 6750 lines | 5706 code | 551 blank | 493 comment | 1153 complexity | a6c89be97c3e5a3b9a711fb653319ab0 MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- /*
- * UAE - The U*nix Amiga Emulator
- *
- * Picasso96 Support Module
- *
- * Copyright 1997-2001 Brian King <Brian_King@CodePoet.com>
- * Copyright 2000-2001 Bernd Roesch <>
- *
- * Theory of operation:
- * On the Amiga side, a Picasso card consists mainly of a memory area that
- * contains the frame buffer. On the UAE side, we allocate a block of memory
- * that will hold the frame buffer. This block is in normal memory, it is
- * never directly on the graphics card. All graphics operations, which are
- * mainly reads and writes into this block and a few basic operations like
- * filling a rectangle, operate on this block of memory.
- * Since the memory is not on the graphics card, some work must be done to
- * synchronize the display with the data in the Picasso frame buffer. There
- * are various ways to do this. One possibility is to allocate a second
- * buffer of the same size, and perform all write operations twice. Since
- * we never read from the second buffer, it can actually be placed in video
- * memory. The X11 driver could be made to use the Picasso frame buffer as
- * the data buffer of an XImage, which could then be XPutImage()d from time
- * to time. Another possibility is to translate all Picasso accesses into
- * Xlib (or GDI, or whatever your graphics system is) calls. This possibility
- * is a bit tricky, since there is a risk of generating very many single pixel
- * accesses which may be rather slow.
- *
- * TODO:
- * - we want to add a manual switch to override SetSwitch for hardware banging
- * programs started from a Picasso workbench.
- */
- #include "sysconfig.h"
- #include "sysdeps.h"
- #include <stdlib.h>
- #if defined(PICASSO96)
- #define MULTIDISPLAY 0
- #define WINCURSOR 1
- #define NEWTRAP 1
- #define OVERLAY 1
- #define USE_HARDWARESPRITE 1
- #define P96TRACING_ENABLED 0
- #define P96TRACING_LEVEL 0
- #define P96TRACING_SETUP_ENABLED 0
- #define P96SPRTRACING_ENABLED 0
- #include "options.h"
- #include "threaddep/thread.h"
- #include "memory.h"
- #include "custom.h"
- #include "events.h"
- #include "newcpu.h"
- #include "xwin.h"
- #include "savestate.h"
- #include "autoconf.h"
- #include "traps.h"
- #include "native2amiga.h"
- #include "drawing.h"
- #include "inputdevice.h"
- #include "debug.h"
- #include "registry.h"
- #include "dxwrap.h"
- #ifdef RETROPLATFORM
- #include "rp.h"
- #endif
- #include "picasso96_win.h"
- #include "win32gfx.h"
- #include "direct3d.h"
- #include "clipboard.h"
- #include "gfxboard.h"
- #include "gfxfilter.h"
- #include "dxwrap.h"
- #include "devices.h"
- int debug_rtg_blitter = 3;
- #define NOBLITTER (0 || !(debug_rtg_blitter & 1))
- #define NOBLITTER_BLIT (0 || !(debug_rtg_blitter & 2))
- #define NOBLITTER_ALL 0
- static int hwsprite = 0;
- static int picasso96_BT = BT_uaegfx;
- static int picasso96_GCT = GCT_Unknown;
- static int picasso96_PCT = PCT_Unknown;
- int mman_GetWriteWatch (PVOID lpBaseAddress, SIZE_T dwRegionSize, PVOID *lpAddresses, PULONG_PTR lpdwCount, PULONG lpdwGranularity);
- void mman_ResetWatch (PVOID lpBaseAddress, SIZE_T dwRegionSize);
- void picasso_flushpixels(int index, uae_u8 *src, int offset, bool render);
- int p96refresh_active;
- bool have_done_picasso = 1; /* For the JIT compiler */
- int p96syncrate;
- static int p96hsync_counter;
- static smp_comm_pipe *render_pipe;
- static volatile int render_thread_state;
- static CRITICAL_SECTION render_cs;
- #define PICASSO_STATE_SETDISPLAY 1
- #define PICASSO_STATE_SETPANNING 2
- #define PICASSO_STATE_SETGC 4
- #define PICASSO_STATE_SETDAC 8
- #define PICASSO_STATE_SETSWITCH 16
- #if defined(X86_MSVC_ASSEMBLY)
- #define SWAPSPEEDUP
- #endif
- #ifdef PICASSO96
- #ifdef DEBUG // Change this to _DEBUG for debugging
- #define P96TRACING_ENABLED 1
- #define P96TRACING_LEVEL 1
- #endif
- #if P96TRACING_ENABLED
- #define P96TRACE(x) do { write_log x; } while(0)
- #else
- #define P96TRACE(x)
- #endif
- #if P96TRACING_SETUP_ENABLED
- #define P96TRACE_SETUP(x) do { write_log x; } while(0)
- #else
- #define P96TRACE_SETUP(x)
- #endif
- #if P96SPRTRACING_ENABLED
- #define P96TRACE_SPR(x) do { write_log x; } while(0)
- #else
- #define P96TRACE_SPR(x)
- #endif
- #define P96TRACE2(x) do { write_log x; } while(0)
- #define TAG_DONE (0L) /* terminates array of TagItems. ti_Data unused */
- #define TAG_IGNORE (1L) /* ignore this item, not end of array */
- #define TAG_MORE (2L) /* ti_Data is pointer to another array of TagItems */
- #define TAG_SKIP (3L) /* skip this and the next ti_Data items */
- static uae_u8 all_ones_bitmap, all_zeros_bitmap; /* yuk */
- struct picasso96_state_struct picasso96_state[MAX_AMIGAMONITORS];
- //static struct picasso96_state_struct picasso96_state_uaegfx;
- struct picasso_vidbuf_description picasso_vidinfo[MAX_AMIGAMONITORS];
- static struct PicassoResolution *newmodes;
- /* These are the maximum resolutions... They are filled in by GetSupportedResolutions() */
- /* have to fill this in, otherwise problems occur on the Amiga side P96 s/w which expects
- /* data here. */
- static struct ScreenResolution planar = { 320, 240 };
- static struct ScreenResolution chunky = { 640, 480 };
- static struct ScreenResolution hicolour = { 640, 480 };
- static struct ScreenResolution truecolour = { 640, 480 };
- static struct ScreenResolution alphacolour = { 640, 480 };
- uae_u32 p96_rgbx16[65536];
- uae_u32 p96rc[256], p96gc[256], p96bc[256];
- static int newcursor_x, newcursor_y;
- static int cursorwidth, cursorheight, cursorok;
- static uae_u8 *cursordata;
- static uae_u32 cursorrgb[4], cursorrgbn[4];
- static int cursordeactivate, setupcursor_needed;
- static bool cursorvisible;
- static HCURSOR wincursor;
- static int wincursor_shown;
- static uaecptr boardinfo, ABI_interrupt;
- static int interrupt_enabled;
- float p96vblank;
- #define OVERLAY_DEBUG 1
- static int overlay_src_width_in, overlay_src_height_in;
- static int overlay_src_height, overlay_src_width;
- static uae_u32 overlay_format, overlay_color, overlay_color_unswapped;
- static uae_u32 overlay_modeformat, overlay_modeinfo;
- static uae_u32 overlay_brightness;
- static int overlay_x, overlay_y;
- static int overlay_w, overlay_h;
- static int overlay_clipleft, overlay_cliptop;
- static int overlay_clipwidth, overlay_clipheight;
- static int overlay_pix;
- static uaecptr overlay_bitmap, overlay_vram;
- static int overlay_vram_offset;
- static int overlay_active;
- static int overlay_convert;
- static int overlay_occlusion;
- static struct MyCLUTEntry overlay_clutc[256 * 2];
- static uae_u32 overlay_clut[256 * 2];
- static uae_u32 *p96_rgbx16_ovl;
- static bool delayed_set_switch;
- static int uaegfx_old, uaegfx_active;
- static uae_u32 reserved_gfxmem;
- static uaecptr uaegfx_resname,
- uaegfx_resid,
- uaegfx_init,
- uaegfx_base,
- uaegfx_rom;
- typedef enum {
- BLIT_FALSE,
- BLIT_NOR,
- BLIT_ONLYDST,
- BLIT_NOTSRC,
- BLIT_ONLYSRC,
- BLIT_NOTDST,
- BLIT_EOR,
- BLIT_NAND,
- BLIT_AND,
- BLIT_NEOR,
- BLIT_DST,
- BLIT_NOTONLYSRC,
- BLIT_SRC,
- BLIT_NOTONLYDST,
- BLIT_OR,
- BLIT_TRUE,
- BLIT_SWAP = 30
- } BLIT_OPCODE;
- #include "win32gui.h"
- #include "resource.h"
- static void init_picasso_screen(int);
- static uae_u32 p2ctab[256][2];
- static int set_gc_called = 0, init_picasso_screen_called = 0;
- //fastscreen
- static uaecptr oldscr = 0;
- extern addrbank gfxmem_bank;
- extern addrbank *gfxmem_banks[MAX_RTG_BOARDS];
- extern int rtg_index;
- void lockrtg(void)
- {
- if (currprefs.rtg_multithread && render_pipe)
- EnterCriticalSection(&render_cs);
- }
- void unlockrtg(void)
- {
- if (currprefs.rtg_multithread && render_pipe)
- LeaveCriticalSection(&render_cs);
- }
- STATIC_INLINE void endianswap (uae_u32 *vp, int bpp)
- {
- switch (bpp)
- {
- case 2:
- *vp = _byteswap_ushort(*vp);
- break;
- case 4:
- *vp = _byteswap_ulong(*vp);
- break;
- }
- }
- #if P96TRACING_ENABLED
- /*
- * Debugging dumps
- */
- static void DumpModeInfoStructure(TrapContext *ctx, uaecptr amigamodeinfoptr)
- {
- write_log (_T("ModeInfo Structure Dump:\n"));
- write_log (_T(" Node.ln_Succ = 0x%x\n"), trap_get_long(ctx, amigamodeinfoptr));
- write_log (_T(" Node.ln_Pred = 0x%x\n"), trap_get_long(ctx, amigamodeinfoptr + 4));
- write_log (_T(" Node.ln_Type = 0x%x\n"), trap_get_byte(ctx, amigamodeinfoptr + 8));
- write_log (_T(" Node.ln_Pri = %d\n"), trap_get_byte(ctx, amigamodeinfoptr + 9));
- /*write_log (_T(" Node.ln_Name = %s\n"), uaememptr->Node.ln_Name); */
- write_log (_T(" OpenCount = %d\n"), trap_get_word(ctx, amigamodeinfoptr + PSSO_ModeInfo_OpenCount));
- write_log (_T(" Active = %d\n"), trap_get_byte(ctx, amigamodeinfoptr + PSSO_ModeInfo_Active));
- write_log (_T(" Width = %d\n"), trap_get_word(ctx, amigamodeinfoptr + PSSO_ModeInfo_Width));
- write_log (_T(" Height = %d\n"), trap_get_word(ctx, amigamodeinfoptr + PSSO_ModeInfo_Height));
- write_log (_T(" Depth = %d\n"), trap_get_byte(ctx, amigamodeinfoptr + PSSO_ModeInfo_Depth));
- write_log (_T(" Flags = %d\n"), trap_get_byte(ctx, amigamodeinfoptr + PSSO_ModeInfo_Flags));
- write_log (_T(" HorTotal = %d\n"), trap_get_word(ctx, amigamodeinfoptr + PSSO_ModeInfo_HorTotal));
- write_log (_T(" HorBlankSize = %d\n"), trap_get_word(ctx, amigamodeinfoptr + PSSO_ModeInfo_HorBlankSize));
- write_log (_T(" HorSyncStart = %d\n"), trap_get_word(ctx, amigamodeinfoptr + PSSO_ModeInfo_HorSyncStart));
- write_log (_T(" HorSyncSize = %d\n"), trap_get_word(ctx, amigamodeinfoptr + PSSO_ModeInfo_HorSyncSize));
- write_log (_T(" HorSyncSkew = %d\n"), trap_get_byte(ctx, amigamodeinfoptr + PSSO_ModeInfo_HorSyncSkew));
- write_log (_T(" HorEnableSkew = %d\n"), trap_get_byte(ctx, amigamodeinfoptr + PSSO_ModeInfo_HorEnableSkew));
- write_log (_T(" VerTotal = %d\n"), trap_get_word(ctx, amigamodeinfoptr + PSSO_ModeInfo_VerTotal));
- write_log (_T(" VerBlankSize = %d\n"), trap_get_word(ctx, amigamodeinfoptr + PSSO_ModeInfo_VerBlankSize));
- write_log (_T(" VerSyncStart = %d\n"), trap_get_word(ctx, amigamodeinfoptr + PSSO_ModeInfo_VerSyncStart));
- write_log (_T(" VerSyncSize = %d\n"), trap_get_word(ctx, amigamodeinfoptr + PSSO_ModeInfo_VerSyncSize));
- write_log (_T(" Clock = %d\n"), trap_get_byte(ctx, amigamodeinfoptr + PSSO_ModeInfo_first_union));
- write_log (_T(" ClockDivide = %d\n"), trap_get_byte(ctx, amigamodeinfoptr + PSSO_ModeInfo_second_union));
- write_log (_T(" PixelClock = %d\n"), trap_get_long(ctx, amigamodeinfoptr + PSSO_ModeInfo_PixelClock));
- }
- static void DumpLibResolutionStructure(TrapContext *ctx, uaecptr amigalibresptr)
- {
- int i;
- uaecptr amigamodeinfoptr;
- struct LibResolution *uaememptr = (struct LibResolution *)get_mem_bank(amigalibresptr).xlateaddr(amigalibresptr);
- write_log (_T("LibResolution Structure Dump:\n"));
- if (trap_get_long(ctx, amigalibresptr + PSSO_LibResolution_DisplayID) == 0xFFFFFFFF) {
- write_log (_T(" Finished With LibResolutions...\n"));
- } else {
- write_log (_T(" Name = %s\n"), uaememptr->P96ID);
- write_log (_T(" DisplayID = 0x%x\n"), trap_get_long(ctx, amigalibresptr + PSSO_LibResolution_DisplayID));
- write_log (_T(" Width = %d\n"), trap_get_word(ctx, amigalibresptr + PSSO_LibResolution_Width));
- write_log (_T(" Height = %d\n"), trap_get_word(ctx, amigalibresptr + PSSO_LibResolution_Height));
- write_log (_T(" Flags = %d\n"), trap_get_word(ctx, amigalibresptr + PSSO_LibResolution_Flags));
- for (i = 0; i < MAXMODES; i++) {
- amigamodeinfoptr = trap_get_long(ctx, amigalibresptr + PSSO_LibResolution_Modes + i*4);
- write_log (_T(" ModeInfo[%d] = 0x%x\n"), i, amigamodeinfoptr);
- if (amigamodeinfoptr)
- DumpModeInfoStructure(ctx, amigamodeinfoptr);
- }
- write_log (_T(" BoardInfo = 0x%x\n"), trap_get_long(ctx, amigalibresptr + PSSO_LibResolution_BoardInfo));
- }
- }
- static TCHAR binary_byte[9] = { 0,0,0,0,0,0,0,0,0 };
- static TCHAR *BuildBinaryString (uae_u8 value)
- {
- int i;
- for (i = 0; i < 8; i++) {
- binary_byte[i] = (value & (1 << (7 - i))) ? '#' : '.';
- }
- return binary_byte;
- }
- static void DumpPattern (struct Pattern *patt)
- {
- uae_u8 *mem;
- int row, col;
- if (!patt->Memory)
- return;
- for (row = 0; row < (1 << patt->Size); row++) {
- mem = patt->Memory + row * 2;
- for (col = 0; col < 2; col++) {
- write_log (_T("%s "), BuildBinaryString (*mem++));
- }
- write_log (_T("\n"));
- }
- }
- static void DumpTemplate (struct Template *tmp, unsigned long w, unsigned long h)
- {
- uae_u8 *mem = tmp->Memory;
- unsigned int row, col, width;
-
- if (!mem)
- return;
- width = (w + 7) >> 3;
- write_log (_T("xoffset = %d, bpr = %d\n"), tmp->XOffset, tmp->BytesPerRow);
- for (row = 0; row < h; row++) {
- mem = tmp->Memory + row * tmp->BytesPerRow;
- for (col = 0; col < width; col++) {
- write_log (_T("%s "), BuildBinaryString (*mem++));
- }
- write_log (_T("\n"));
- }
- }
- static void DumpLine(struct Line *line)
- {
- if (line) {
- write_log (_T("Line->X = %d\n"), line->X);
- write_log (_T("Line->Y = %d\n"), line->Y);
- write_log (_T("Line->Length = %d\n"), line->Length);
- write_log (_T("Line->dX = %d\n"), line->dX);
- write_log (_T("Line->dY = %d\n"), line->dY);
- write_log (_T("Line->sDelta = %d\n"), line->sDelta);
- write_log (_T("Line->lDelta = %d\n"), line->lDelta);
- write_log (_T("Line->twoSDminusLD = %d\n"), line->twoSDminusLD);
- write_log (_T("Line->LinePtrn = %d\n"), line->LinePtrn);
- write_log (_T("Line->PatternShift = %d\n"), line->PatternShift);
- write_log (_T("Line->FgPen = 0x%x\n"), line->FgPen);
- write_log (_T("Line->BgPen = 0x%x\n"), line->BgPen);
- write_log (_T("Line->Horizontal = %d\n"), line->Horizontal);
- write_log (_T("Line->DrawMode = %d\n"), line->DrawMode);
- write_log (_T("Line->Xorigin = %d\n"), line->Xorigin);
- write_log (_T("Line->Yorigin = %d\n"), line->Yorigin);
- }
- }
- static void ShowSupportedResolutions (void)
- {
- int i = 0;
- write_log (_T("-----------------\n"));
- while (newmodes[i].depth >= 0) {
- write_log (_T("%s\n"), newmodes[i].name);
- i++;
- }
- write_log (_T("-----------------\n"));
- }
- #endif
- static void **gwwbuf[MAX_RTG_BOARDS];
- static int gwwbufsize[MAX_RTG_BOARDS], gwwpagesize[MAX_RTG_BOARDS], gwwpagemask[MAX_RTG_BOARDS];
- extern uae_u8 *natmem_offset;
- static uae_u8 GetBytesPerPixel (uae_u32 RGBfmt)
- {
- switch (RGBfmt)
- {
- case RGBFB_CLUT:
- case RGBFB_Y4U1V1:
- return 1;
- case RGBFB_A8R8G8B8:
- case RGBFB_A8B8G8R8:
- case RGBFB_R8G8B8A8:
- case RGBFB_B8G8R8A8:
- return 4;
- case RGBFB_B8G8R8:
- case RGBFB_R8G8B8:
- return 3;
- case RGBFB_R5G5B5:
- case RGBFB_R5G6B5:
- case RGBFB_R5G6B5PC:
- case RGBFB_R5G5B5PC:
- case RGBFB_B5G6R5PC:
- case RGBFB_B5G5R5PC:
- case RGBFB_Y4U2V2:
- return 2;
- }
- return 0;
- }
- STATIC_INLINE bool validatecoords2(TrapContext *ctx, struct RenderInfo *ri, uae_u32 *Xp, uae_u32 *Yp, uae_u32 *Widthp, uae_u32 *Heightp)
- {
- uae_u32 Width = *Widthp;
- uae_u32 Height = *Heightp;
- uae_u32 X = *Xp;
- uae_u32 Y = *Yp;
- if (!Width || !Height) {
- return true;
- }
- if (Width > 32767 || Height > 32767 || X > 32767 || Y > 32767) {
- return false;
- }
- if (ri) {
- int bpp = GetBytesPerPixel (ri->RGBFormat);
- if (X * bpp >= ri->BytesPerRow) {
- return false;
- }
- uae_u32 X2 = X + Width;
- if (X2 * bpp > ri->BytesPerRow) {
- X2 = ri->BytesPerRow / bpp;
- Width = X2 - X;
- *Widthp = Width;
- }
- uaecptr start = gfxmem_banks[0]->start;
- uae_u32 size = gfxmem_banks[0]->allocated_size;
- uaecptr mem = ri->AMemory;
- if (mem < start || mem >= start + size) {
- return false;
- }
- mem += (Y + Height - 1) * ri->BytesPerRow + (X + Width - 1) * bpp;
- if (mem < start || mem >= start + size) {
- return false;
- }
- }
- return true;
- }
- static bool validatecoords(TrapContext *ctx, struct RenderInfo *ri, uae_u32 *X, uae_u32 *Y, uae_u32 *Width, uae_u32 *Height)
- {
- if (validatecoords2(ctx, ri, X, Y, Width, Height))
- return true;
- write_log (_T("RTG invalid region: %08X:%d:%d (%dx%d)-(%dx%d)\n"), ri->AMemory, ri->BytesPerRow, ri->RGBFormat, *X, *Y, *Width, *Height);
- return false;
- }
- /*
- * Amiga <-> native structure conversion functions
- */
- static int CopyRenderInfoStructureA2U(TrapContext *ctx, uaecptr amigamemptr, struct RenderInfo *ri)
- {
- if (trap_valid_address(ctx, amigamemptr, PSSO_RenderInfo_sizeof)) {
- struct trapmd md[] =
- {
- { TRAPCMD_GET_LONG, { amigamemptr + PSSO_RenderInfo_Memory } },
- { TRAPCMD_GET_WORD, { amigamemptr + PSSO_RenderInfo_BytesPerRow } },
- { TRAPCMD_GET_LONG, { amigamemptr + PSSO_RenderInfo_RGBFormat } }
- };
- trap_multi(ctx, md, sizeof md / sizeof(struct trapmd));
- uaecptr memp = md[0].params[0];
- ri->AMemory = memp;
- ri->BytesPerRow = md[1].params[0];
- ri->RGBFormat = (RGBFTYPE)md[2].params[0];
- // Can't really validate this better at this point, no height.
- if (trap_valid_address(ctx, memp, ri->BytesPerRow)) {
- ri->Memory = get_real_address(memp);
- return 1;
- }
- }
- write_log (_T("ERROR - Invalid RenderInfo memory area...\n"));
- return 0;
- }
- static int CopyPatternStructureA2U(TrapContext *ctx, uaecptr amigamemptr, struct Pattern *pattern)
- {
- if (trap_valid_address(ctx, amigamemptr, PSSO_Pattern_sizeof)) {
- struct trapmd md[] =
- {
- { TRAPCMD_GET_LONG, { amigamemptr + PSSO_Pattern_Memory } },
- { TRAPCMD_GET_WORD, { amigamemptr + PSSO_Pattern_XOffset } },
- { TRAPCMD_GET_WORD, { amigamemptr + PSSO_Pattern_YOffset } },
- { TRAPCMD_GET_LONG, { amigamemptr + PSSO_Pattern_FgPen } },
- { TRAPCMD_GET_LONG, { amigamemptr + PSSO_Pattern_BgPen } },
- { TRAPCMD_GET_BYTE, { amigamemptr + PSSO_Pattern_Size } },
- { TRAPCMD_GET_BYTE, { amigamemptr + PSSO_Pattern_DrawMode } }
- };
- trap_multi(ctx, md, sizeof md / sizeof(struct trapmd));
- uaecptr memp = md[0].params[0];
- pattern->AMemory = memp;
- pattern->XOffset = md[1].params[0];
- pattern->YOffset = md[2].params[0];
- pattern->FgPen = md[3].params[0];
- pattern->BgPen = md[4].params[0];
- pattern->Size = md[5].params[0];
- pattern->DrawMode = md[6].params[0];
- if (trap_valid_address(ctx, memp, 2)) {
- if (trap_is_indirect())
- pattern->Memory = NULL;
- else
- pattern->Memory = get_real_address(memp);
- return 1;
- }
- }
- write_log (_T("ERROR - Invalid Pattern memory area...\n"));
- return 0;
- }
- static int CopyBitMapStructureA2U(TrapContext *ctx, uaecptr amigamemptr, struct BitMap *bm)
- {
- int i;
- struct trapmd md[] =
- {
- { TRAPCMD_GET_WORD, { amigamemptr + PSSO_BitMap_BytesPerRow } },
- { TRAPCMD_GET_WORD, { amigamemptr + PSSO_BitMap_Rows } },
- { TRAPCMD_GET_BYTE, { amigamemptr + PSSO_BitMap_Flags } },
- { TRAPCMD_GET_BYTE, { amigamemptr + PSSO_BitMap_Depth } },
- { TRAPCMD_GET_LONG, { amigamemptr + PSSO_BitMap_Planes + 0 } },
- { TRAPCMD_GET_LONG, { amigamemptr + PSSO_BitMap_Planes + 4 } },
- { TRAPCMD_GET_LONG, { amigamemptr + PSSO_BitMap_Planes + 8 } },
- { TRAPCMD_GET_LONG, { amigamemptr + PSSO_BitMap_Planes + 12 } },
- { TRAPCMD_GET_LONG, { amigamemptr + PSSO_BitMap_Planes + 16 } },
- { TRAPCMD_GET_LONG, { amigamemptr + PSSO_BitMap_Planes + 20 } },
- { TRAPCMD_GET_LONG, { amigamemptr + PSSO_BitMap_Planes + 24 } },
- { TRAPCMD_GET_LONG, { amigamemptr + PSSO_BitMap_Planes + 28} }
- };
- trap_multi(ctx, md, sizeof md / sizeof(struct trapmd));
- bm->BytesPerRow = md[0].params[0];
- bm->Rows = md[1].params[0];
- bm->Flags = md[2].params[0];
- bm->Depth = md[3].params[0];
- /* ARGH - why is THIS happening? */
- if(bm->Depth > 8)
- bm->Depth = 8;
- for (i = 0; i < bm->Depth; i++) {
- uaecptr plane = md[4 + i].params[0];
- bm->APlanes[i] = plane;
- switch (plane) {
- case 0:
- bm->Planes[i] = &all_zeros_bitmap;
- break;
- case 0xFFFFFFFF:
- bm->Planes[i] = &all_ones_bitmap;
- break;
- default:
- if (!trap_is_indirect() && trap_valid_address(ctx, plane, bm->BytesPerRow * bm->Rows))
- bm->Planes[i] = get_real_address(plane);
- else
- bm->Planes[i] = &all_zeros_bitmap;
- break;
- }
- }
- return 1;
- }
- static int CopyTemplateStructureA2U(TrapContext *ctx, uaecptr amigamemptr, struct Template *tmpl)
- {
- if (trap_valid_address(ctx, amigamemptr, PSSO_Template_sizeof)) {
- struct trapmd md[] =
- {
- { TRAPCMD_GET_LONG, { amigamemptr + PSSO_Template_Memory } },
- { TRAPCMD_GET_WORD, { amigamemptr + PSSO_Template_BytesPerRow } },
- { TRAPCMD_GET_BYTE, { amigamemptr + PSSO_Template_XOffset } },
- { TRAPCMD_GET_BYTE, { amigamemptr + PSSO_Template_DrawMode } },
- { TRAPCMD_GET_LONG, { amigamemptr + PSSO_Template_FgPen } },
- { TRAPCMD_GET_LONG, { amigamemptr + PSSO_Template_BgPen } }
- };
- trap_multi(ctx, md, sizeof md / sizeof(struct trapmd));
- uaecptr memp = md[0].params[0];
- if (trap_is_indirect()) {
- tmpl->Memory = NULL;
- } else {
- if (!trap_valid_address(ctx, memp, 1)) {
- write_log(_T("ERROR - Invalid Template memory region %08x...\n"), memp);
- return 0;
- }
- tmpl->Memory = get_real_address(memp);
- }
- tmpl->AMemory = memp;
- tmpl->BytesPerRow = md[1].params[0];
- tmpl->XOffset = md[2].params[0];
- tmpl->DrawMode = md[3].params[0];
- tmpl->FgPen = md[4].params[0];
- tmpl->BgPen = md[5].params[0];
- return 1;
- }
- write_log (_T("ERROR - Invalid Template memory area...\n"));
- return 0;
- }
- static int CopyLineStructureA2U(TrapContext *ctx, uaecptr amigamemptr, struct Line *line)
- {
- if (trap_valid_address(ctx, amigamemptr, sizeof(struct Line))) {
- line->X = trap_get_word(ctx, amigamemptr + PSSO_Line_X);
- line->Y = trap_get_word(ctx, amigamemptr + PSSO_Line_Y);
- line->Length = trap_get_word(ctx, amigamemptr + PSSO_Line_Length);
- line->dX = trap_get_word(ctx, amigamemptr + PSSO_Line_dX);
- line->dY = trap_get_word(ctx, amigamemptr + PSSO_Line_dY);
- line->lDelta = trap_get_word(ctx, amigamemptr + PSSO_Line_lDelta);
- line->sDelta = trap_get_word(ctx, amigamemptr + PSSO_Line_sDelta);
- line->twoSDminusLD = trap_get_word(ctx, amigamemptr + PSSO_Line_twoSDminusLD);
- line->LinePtrn = trap_get_word(ctx, amigamemptr + PSSO_Line_LinePtrn);
- line->PatternShift = trap_get_word(ctx, amigamemptr + PSSO_Line_PatternShift);
- line->FgPen = trap_get_long(ctx, amigamemptr + PSSO_Line_FgPen);
- line->BgPen = trap_get_long(ctx, amigamemptr + PSSO_Line_BgPen);
- line->Horizontal = trap_get_word(ctx, amigamemptr + PSSO_Line_Horizontal);
- line->DrawMode = trap_get_byte(ctx, amigamemptr + PSSO_Line_DrawMode);
- line->Xorigin = trap_get_word(ctx, amigamemptr + PSSO_Line_Xorigin);
- line->Yorigin = trap_get_word(ctx, amigamemptr + PSSO_Line_Yorigin);
- return 1;
- }
- write_log (_T("ERROR - Invalid Line structure...\n"));
- return 0;
- }
- /* list is Amiga address of list, in correct endian format for UAE
- * node is Amiga address of node, in correct endian format for UAE */
- static void AmigaListAddTail(TrapContext *ctx, uaecptr l, uaecptr n)
- {
- trap_put_long(ctx, n + 0, l + 4); // n->ln_Succ = (struct Node *)&l->lh_Tail;
- trap_put_long(ctx, n + 4, trap_get_long(ctx, l + 8)); // n->ln_Pred = l->lh_TailPred;
- trap_put_long(ctx, trap_get_long(ctx, l + 8) + 0, n); // l->lh_TailPred->ln_Succ = n;
- trap_put_long(ctx, l + 8, n); // l->lh_TailPred = n;
- }
- /*
- * Fill a rectangle in the screen.
- */
- static void do_fillrect_frame_buffer(struct RenderInfo *ri, int X, int Y, int Width, int Height, uae_u32 Pen, int Bpp)
- {
- int cols;
- uae_u8 *dst;
- int bpr = ri->BytesPerRow;
- dst = ri->Memory + X * Bpp + Y * bpr;
- endianswap (&Pen, Bpp);
- switch (Bpp)
- {
- case 1:
- for (int lines = 0; lines < Height; lines++, dst += bpr) {
- memset (dst, Pen, Width);
- }
- break;
- case 2:
- {
- Pen |= Pen << 16;
- for (int lines = 0; lines < Height; lines++, dst += bpr) {
- uae_u32 *p = (uae_u32*)dst;
- for (cols = 0; cols < (Width & ~15); cols += 16) {
- *p++ = Pen;
- *p++ = Pen;
- *p++ = Pen;
- *p++ = Pen;
- *p++ = Pen;
- *p++ = Pen;
- *p++ = Pen;
- *p++ = Pen;
- }
- while (cols < (Width & ~1)) {
- *p++ = Pen;
- cols += 2;
- }
- if (Width & 1) {
- ((uae_u16*)p)[0] = Pen;
- }
- }
- }
- break;
- case 3:
- {
- uae_u16 Pen1 = Pen & 0xffff;
- uae_u16 Pen2 = (Pen << 8) | ((Pen >> 16) & 0xff);
- uae_u16 Pen3 = Pen >> 8;
- bool same = (Pen & 0xff) == ((Pen >> 8) & 0xff) && (Pen & 0xff) == ((Pen >> 16) & 0xff);
- for (int lines = 0; lines < Height; lines++, dst += bpr) {
- uae_u16 *p = (uae_u16*)dst;
- if (same) {
- memset(p, Pen & 0xff, Width * 3);
- } else {
- for (cols = 0; cols < (Width & ~7); cols += 8) {
- *p++ = Pen1;
- *p++ = Pen2;
- *p++ = Pen3;
- *p++ = Pen1;
- *p++ = Pen2;
- *p++ = Pen3;
- *p++ = Pen1;
- *p++ = Pen2;
- *p++ = Pen3;
- *p++ = Pen1;
- *p++ = Pen2;
- *p++ = Pen3;
- }
- uae_u8 *p8 = (uae_u8*)p;
- while (cols < Width) {
- *p8++ = Pen >> 0;
- *p8++ = Pen >> 8;
- *p8++ = Pen >> 16;
- cols++;
- }
- }
- }
- }
- break;
- case 4:
- {
- for (int lines = 0; lines < Height; lines++, dst += bpr) {
- uae_u32 *p = (uae_u32*)dst;
- for (cols = 0; cols < (Width & ~7); cols += 8) {
- *p++ = Pen;
- *p++ = Pen;
- *p++ = Pen;
- *p++ = Pen;
- *p++ = Pen;
- *p++ = Pen;
- *p++ = Pen;
- *p++ = Pen;
- }
- while (cols < Width) {
- *p++ = Pen;
- cols++;
- }
- }
- }
- break;
- }
- }
- static void setupcursor(void)
- {
- uae_u8 *dptr;
- int bpp = 4;
- int pitch;
- struct rtgboardconfig *rbc = &currprefs.rtgboards[0];
- if (rbc->rtgmem_type >= GFXBOARD_HARDWARE || !currprefs.gfx_api)
- return;
- gfx_lock ();
- setupcursor_needed = 1;
- dptr = D3D_setcursorsurface(rbc->monitor_id, &pitch);
- if (dptr) {
- for (int y = 0; y < CURSORMAXHEIGHT; y++) {
- uae_u8 *p2 = dptr + pitch * y;
- memset (p2, 0, CURSORMAXWIDTH * bpp);
- }
- if (cursordata && cursorwidth && cursorheight) {
- for (int y = 0; y < cursorheight; y++) {
- uae_u8 *p1 = cursordata + cursorwidth * bpp * y;
- uae_u8 *p2 = dptr + pitch * y;
- memcpy (p2, p1, cursorwidth * bpp);
- }
- }
- D3D_setcursorsurface(rbc->monitor_id, NULL);
- setupcursor_needed = 0;
- P96TRACE_SPR((_T("cursorsurface3d updated\n")));
- } else {
- P96TRACE_SPR((_T("cursorsurfaced3d LockRect() failed %08x\n"), hr));
- }
- gfx_unlock ();
- }
- static void disablemouse (void)
- {
- cursorok = FALSE;
- cursordeactivate = 0;
- if (!hwsprite)
- return;
- if (!currprefs.gfx_api)
- return;
- D3D_setcursor(0, 0, 0, 0, 0, false, true);
- }
- static void mouseupdate(struct AmigaMonitor *mon)
- {
- struct picasso96_state_struct *state = &picasso96_state[mon->monitor_id];
- int x = newcursor_x;
- int y = newcursor_y;
- int forced = 0;
- if (!hwsprite)
- return;
- if (cursordeactivate > 0) {
- cursordeactivate--;
- if (cursordeactivate == 0) {
- disablemouse ();
- cursorvisible = false;
- }
- }
- if (!currprefs.gfx_api)
- return;
- if (currprefs.gf[1].gfx_filter_autoscale == RTG_MODE_CENTER) {
- D3D_setcursor(mon->monitor_id, x, y, WIN32GFX_GetWidth(mon), WIN32GFX_GetHeight(mon), cursorvisible, mon->scalepicasso == 2);
- } else {
- D3D_setcursor(mon->monitor_id, x, y, state->Width, state->Height, cursorvisible, false);
- }
- }
- static int p96_framecnt;
- int p96skipmode = -1;
- static int doskip (void)
- {
- if (p96_framecnt >= currprefs.gfx_framerate)
- p96_framecnt = 0;
- return p96_framecnt > 0;
- }
- void picasso_trigger_vblank(void)
- {
- TrapContext *ctx = NULL;
- if (!ABI_interrupt || !uaegfx_base || !interrupt_enabled || !currprefs.rtg_hardwareinterrupt)
- return;
- trap_put_long(ctx, uaegfx_base + CARD_IRQPTR, ABI_interrupt + PSSO_BoardInfo_SoftInterrupt);
- trap_put_byte(ctx, uaegfx_base + CARD_IRQFLAG, 1);
- if (currprefs.win32_rtgvblankrate != 0)
- INTREQ (0x8000 | 0x0008);
- }
- static bool is_uaegfx_active(void)
- {
- if (currprefs.rtgboards[0].rtgmem_type >= GFXBOARD_HARDWARE || !currprefs.rtgboards[0].rtgmem_size)
- return false;
- return true;
- }
- static void rtg_render(void)
- {
- int monid = currprefs.rtgboards[0].monitor_id;
- bool uaegfx_active = is_uaegfx_active();
- int uaegfx_index = 0;
- struct AmigaMonitor *mon = &AMonitors[monid];
- struct picasso96_state_struct *state = &picasso96_state[monid];
- struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid];
- struct amigadisplay *ad = &adisplays[monid];
- if (D3D_restore)
- D3D_restore(monid, true);
- if (doskip () && p96skipmode == 0) {
- ;
- } else {
- bool full = vidinfo->full_refresh > 0;
- if (uaegfx_active) {
- if (!currprefs.rtg_multithread) {
- picasso_flushpixels(0, gfxmem_banks[uaegfx_index]->start + natmem_offset, state->XYOffset - gfxmem_banks[uaegfx_index]->start, true);
- }
- } else {
- if (vidinfo->full_refresh < 0)
- vidinfo->full_refresh = 0;
- if (vidinfo->full_refresh > 0)
- vidinfo->full_refresh--;
- }
- gfxboard_vsync_handler(full, true);
- if (currprefs.rtg_multithread && uaegfx_active) {
- if (ad->pending_render) {
- ad->pending_render = false;
- gfx_unlock_picasso(mon->monitor_id, true);
- }
- write_comm_pipe_int(render_pipe, uaegfx_index, 0);
- }
- }
- }
- static void rtg_clear(int monid)
- {
- struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid];
- vidinfo->rtg_clear_flag = 2;
- }
- enum {
- /* DEST = RGBFB_B8G8R8A8,32 */
- RGBFB_A8R8G8B8_32 = 1,
- RGBFB_A8B8G8R8_32,
- RGBFB_R8G8B8A8_32,
- RGBFB_B8G8R8A8_32,
- RGBFB_R8G8B8_32,
- RGBFB_B8G8R8_32,
- RGBFB_R5G6B5PC_32,
- RGBFB_R5G5B5PC_32,
- RGBFB_R5G6B5_32,
- RGBFB_R5G5B5_32,
- RGBFB_B5G6R5PC_32,
- RGBFB_B5G5R5PC_32,
- RGBFB_CLUT_RGBFB_32,
- RGBFB_Y4U2V2_32,
- RGBFB_Y4U1V1_32,
- /* DEST = RGBFB_R5G6B5PC,16 */
- RGBFB_A8R8G8B8_16,
- RGBFB_A8B8G8R8_16,
- RGBFB_R8G8B8A8_16,
- RGBFB_B8G8R8A8_16,
- RGBFB_R8G8B8_16,
- RGBFB_B8G8R8_16,
- RGBFB_R5G6B5PC_16,
- RGBFB_R5G5B5PC_16,
- RGBFB_R5G6B5_16,
- RGBFB_R5G5B5_16,
- RGBFB_B5G6R5PC_16,
- RGBFB_B5G5R5PC_16,
- RGBFB_CLUT_RGBFB_16,
- RGBFB_Y4U2V2_16,
- RGBFB_Y4U1V1_16,
- /* DEST = RGBFB_CLUT,8 */
- RGBFB_CLUT_8
- };
- int getconvert(int rgbformat, int pixbytes)
- {
- int v = 0;
- int d = pixbytes;
- switch (rgbformat)
- {
- case RGBFB_CLUT:
- if (d == 1)
- v = RGBFB_CLUT_8;
- else if (d == 2)
- v = RGBFB_CLUT_RGBFB_16;
- else if (d == 4)
- v = RGBFB_CLUT_RGBFB_32;
- break;
- case RGBFB_B5G6R5PC:
- if (d == 2)
- v = RGBFB_B5G6R5PC_16;
- else if (d == 4)
- v = RGBFB_B5G6R5PC_32;
- break;
- case RGBFB_R5G6B5PC:
- if (d == 2)
- v = RGBFB_R5G6B5PC_16;
- else if (d == 4)
- v = RGBFB_R5G6B5PC_32;
- break;
- case RGBFB_R5G5B5PC:
- if (d == 4)
- v = RGBFB_R5G5B5PC_32;
- else if (d == 2)
- v = RGBFB_R5G5B5PC_16;
- break;
- case RGBFB_R5G6B5:
- if (d == 4)
- v = RGBFB_R5G6B5_32;
- else
- v = RGBFB_R5G6B5_16;
- break;
- case RGBFB_R5G5B5:
- if (d == 4)
- v = RGBFB_R5G5B5_32;
- else
- v = RGBFB_R5G5B5_16;
- break;
- case RGBFB_B5G5R5PC:
- if (d == 4)
- v = RGBFB_B5G5R5PC_32;
- else
- v = RGBFB_B5G5R5PC_16;
- break;
- case RGBFB_A8R8G8B8:
- if (d == 2)
- v = RGBFB_A8R8G8B8_16;
- else if (d == 4)
- v = RGBFB_A8R8G8B8_32;
- break;
- case RGBFB_R8G8B8:
- if (d == 2)
- v = RGBFB_R8G8B8_16;
- else if (d == 4)
- v = RGBFB_R8G8B8_32;
- break;
- case RGBFB_B8G8R8:
- if (d == 2)
- v = RGBFB_B8G8R8_16;
- else if (d == 4)
- v = RGBFB_B8G8R8_32;
- break;
- case RGBFB_A8B8G8R8:
- if (d == 2)
- v = RGBFB_A8B8G8R8_16;
- else if (d == 4)
- v = RGBFB_A8B8G8R8_32;
- break;
- case RGBFB_B8G8R8A8:
- if (d == 2)
- v = RGBFB_B8G8R8A8_16;
- else if (d == 4)
- v = RGBFB_B8G8R8A8_32;
- break;
- case RGBFB_R8G8B8A8:
- if (d == 2)
- v = RGBFB_R8G8B8A8_16;
- else if (d == 4)
- v = RGBFB_R8G8B8A8_32;
- break;
- case RGBFB_Y4U2V2:
- if (d == 4)
- v = RGBFB_Y4U2V2_32;
- else
- v = RGBFB_Y4U2V2_16;
- break;
- case RGBFB_Y4U1V1:
- if (d == 4)
- v = RGBFB_Y4U1V1_32;
- else
- v = RGBFB_Y4U1V1_16;
- break;
- }
- return v;
- }
- static void setconvert(int monid)
- {
- lockrtg();
- struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid];
- struct picasso96_state_struct *state = &picasso96_state[monid];
- vidinfo->picasso_convert = getconvert(state->RGBFormat, picasso_vidinfo[monid].pixbytes);
- if (currprefs.gfx_api) {
- vidinfo->host_mode = picasso_vidinfo[monid].pixbytes == 4 ? RGBFB_B8G8R8A8 : RGBFB_B5G6R5PC;
- } else {
- vidinfo->host_mode = DirectDraw_GetSurfacePixelFormat(NULL);
- }
- if (picasso_vidinfo[monid].pixbytes == 4)
- alloc_colors_rgb(8, 8, 8, 16, 8, 0, 0, 0, 0, 0, p96rc, p96gc, p96bc);
- else
- alloc_colors_rgb(5, 6, 5, 11, 5, 0, 0, 0, 0, 0, p96rc, p96gc, p96bc);
- gfx_set_picasso_colors(monid, state->RGBFormat);
- picasso_palette(state->CLUT, vidinfo->clut);
- if (vidinfo->host_mode != vidinfo->ohost_mode || state->RGBFormat != vidinfo->orgbformat) {
- write_log (_T("RTG conversion: Depth=%d HostRGBF=%d P96RGBF=%d Mode=%d\n"),
- picasso_vidinfo[monid].pixbytes, vidinfo->host_mode, state->RGBFormat, vidinfo->picasso_convert);
- vidinfo->ohost_mode = vidinfo->host_mode;
- vidinfo->orgbformat = state->RGBFormat;
- }
- vidinfo->full_refresh = 1;
- unlockrtg();
- }
- bool picasso_is_active(int monid)
- {
- struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid];
- return vidinfo->picasso_active;
- }
- /* Clear our screen, since we've got a new Picasso screen-mode, and refresh with the proper contents
- * This is called on several occasions:
- * 1. Amiga-->Picasso transition, via SetSwitch()
- * 2. Picasso-->Picasso transition, via SetPanning().
- * 3. whenever the graphics code notifies us that the screen contents have been lost.
- */
- void picasso_refresh(int monid)
- {
- struct RenderInfo ri;
- struct AmigaMonitor *mon = &AMonitors[monid];
- struct amigadisplay *ad = &adisplays[monid];
- struct picasso96_state_struct *state = &picasso96_state[monid];
- struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid];
- if (!ad->picasso_on)
- return;
- lockrtg();
- vidinfo->full_refresh = 1;
- setconvert(monid);
- setupcursor();
- rtg_clear(monid);
- if (currprefs.rtgboards[0].rtgmem_type >= GFXBOARD_HARDWARE) {
- gfxboard_refresh(monid);
- unlockrtg();
- return;
- }
- /* Make sure that the first time we show a Picasso video mode, we don't blit any crap.
- * We can do this by checking if we have an Address yet.
- */
- if (state->Address) {
- unsigned int width, height;
- /* blit the stuff from our static frame-buffer to the gfx-card */
- ri.Memory = gfxmem_bank.baseaddr + (state->Address - gfxmem_bank.start);
- ri.BytesPerRow = state->BytesPerRow;
- ri.RGBFormat = state->RGBFormat;
- if (vidinfo->set_panning_called) {
- width = (state->VirtualWidth < state->Width) ?
- state->VirtualWidth : state->Width;
- height = (state->VirtualHeight < state->Height) ?
- state->VirtualHeight : state->Height;
- // Let's put a black-border around the case where we've got a sub-screen...
- if (!state->BigAssBitmap) {
- if (state->XOffset || state->YOffset)
- DX_Fill(mon, 0, 0, state->Width, state->Height, 0);
- }
- } else {
- width = state->Width;
- height = state->Height;
- }
- } else {
- write_log (_T("ERROR - picasso_refresh() can't refresh!\n"));
- }
- unlockrtg();
- }
- static void picasso_handle_vsync2(struct AmigaMonitor *mon)
- {
- struct amigadisplay *ad = &adisplays[mon->monitor_id];
- struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[mon->monitor_id];
- static int vsynccnt;
- int thisisvsync = 1;
- int vsync = isvsync_rtg();
- int mult;
- bool rendered = false;
- bool uaegfx = currprefs.rtgboards[0].rtgmem_type < GFXBOARD_HARDWARE;
- bool uaegfx_active = is_uaegfx_active();
- int state = vidinfo->picasso_state_change;
- if (state)
- lockrtg();
- if (state & PICASSO_STATE_SETDAC) {
- atomic_and(&vidinfo->picasso_state_change, ~PICASSO_STATE_SETDAC);
- rtg_clear(mon->monitor_id);
- }
- if (state & PICASSO_STATE_SETGC) {
- atomic_and(&vidinfo->picasso_state_change, ~PICASSO_STATE_SETGC);
- set_gc_called = 1;
- vidinfo->picasso_changed = true;
- init_picasso_screen(mon->monitor_id);
- init_hz_p96(mon->monitor_id);
- if (delayed_set_switch) {
- delayed_set_switch = false;
- atomic_or(&vidinfo->picasso_state_change, PICASSO_STATE_SETSWITCH);
- ad->picasso_requested_on = 1;
- set_config_changed();
- }
- }
- if (state & PICASSO_STATE_SETSWITCH) {
- atomic_and(&vidinfo->picasso_state_change, ~PICASSO_STATE_SETSWITCH);
- /* Do not switch immediately. Tell the custom chip emulation about the
- * desired state, and wait for custom.c to call picasso_enablescreen
- * whenever it is ready to change the screen state. */
- if (ad->picasso_on == ad->picasso_requested_on && ad->picasso_requested_on && vidinfo->picasso_changed) {
- ad->picasso_requested_forced_on = true;
- }
- vidinfo->picasso_changed = false;
- vidinfo->picasso_active = ad->picasso_requested_on;
- }
- if (state & PICASSO_STATE_SETPANNING) {
- atomic_and(&vidinfo->picasso_state_change, ~PICASSO_STATE_SETPANNING);
- vidinfo->full_refresh = 1;
- vidinfo->set_panning_called = 1;
- init_picasso_screen(mon->monitor_id);
- vidinfo->set_panning_called = 0;
- }
- if (state & PICASSO_STATE_SETDISPLAY) {
- atomic_and(&vidinfo->picasso_state_change, ~PICASSO_STATE_SETDISPLAY);
- // do nothing
- }
- if (state)
- unlockrtg();
- if (ad->picasso_on) {
- #if 0
- if (vsync < 0) {
- vsync_busywait_end(NULL);
- vsync_busywait_do(NULL, false, false);
- }
- #endif
- }
- getvsyncrate(mon->monitor_id, currprefs.chipset_refreshrate, &mult);
- if (vsync && mult < 0) {
- vsynccnt++;
- if (vsynccnt < 2)
- thisisvsync = 0;
- else
- vsynccnt = 0;
- }
- p96_framecnt++;
- if (!uaegfx && !ad->picasso_on) {
- rtg_render();
- return;
- }
- if (!ad->picasso_on)
- return;
- if (uaegfx && uaegfx_active)
- if (setupcursor_needed)
- setupcursor();
- mouseupdate(mon);
- if (thisisvsync) {
- rtg_render();
- frame_drawn(mon->monitor_id);
- }
- if (uaegfx) {
- if (thisisvsync)
- picasso_trigger_vblank();
- }
- #if 0
- if (vsync < 0) {
- vsync_busywait_start();
- }
- #endif
- }
- static int p96hsync;
- void picasso_handle_vsync(void)
- {
- struct AmigaMonitor *mon = &AMonitors[currprefs.rtgboards[0].monitor_id];
- struct amigadisplay *ad = &adisplays[currprefs.rtgboards[0].monitor_id];
- bool uaegfx = currprefs.rtgboards[0].rtgmem_type < GFXBOARD_HARDWARE;
- bool uaegfx_active = is_uaegfx_active();
- if (currprefs.rtgboards[0].rtgmem_size == 0)
- return;
- if (!ad->picasso_on && uaegfx) {
- if (uaegfx_active) {
- createwindowscursor(mon->monitor_id, 0, 0, 0, 0, 0, 1);
- }
- picasso_trigger_vblank();
- if (!delayed_set_switch)
- return;
- }
- int vsync = isvsync_rtg();
- if (vsync < 0) {
- p96hsync = 0;
- picasso_handle_vsync2(mon);
- } else if (currprefs.win32_rtgvblankrate == 0) {
- picasso_handle_vsync2(mon);
- }
- }
- static void picasso_handle_hsync(void)
- {
- struct AmigaMonitor *mon = &AMonitors[currprefs.rtgboards[0].monitor_id];
- struct amigadisplay *ad = &adisplays[currprefs.rtgboards[0].monitor_id];
- bool uaegfx = currprefs.rtgboards[0].rtgmem_type < GFXBOARD_HARDWARE;
- bool uaegfx_active = is_uaegfx_active();
- if (currprefs.rtgboards[0].rtgmem_size == 0)
- return;
- if (ad->pending_render) {
- ad->pending_render = false;
- gfx_unlock_picasso(mon->monitor_id, true);
- }
- int vsync = isvsync_rtg();
- if (vsync < 0) {
- p96hsync++;
- if (p96hsync >= p96syncrate * 3) {
- p96hsync = 0;
- // kickstart vblank vsync_busywait stuff
- picasso_handle_vsync();
- }
- return;
- }
- if (currprefs.win32_rtgvblankrate == 0)
- return;
- p96hsync++;
- if (p96hsync >= p96syncrate) {
- if (!ad->picasso_on) {
- if (uaegfx) {
- if (uaegfx_active) {
- createwindowscursor(mon->monitor_id, 0, 0, 0, 0, 0, 1);
- }
- picasso_trigger_vblank();
- }
- gfxboard_vsync_handler(false, false);
- } else {
- picasso_handle_vsync2(mon);
- }
- p96hsync = 0;
- }
- }
- #define BLT_SIZE 4
- #define BLT_MULT 1
- #define BLT_NAME BLIT_FALSE_32
- #define BLT_FUNC(s,d) *d = 0
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_NOR_32
- #define BLT_FUNC(s,d) *d = ~((*s) | (*d))
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_ONLYDST_32
- #define BLT_FUNC(s,d) *d = (*d) & ~(*s)
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_NOTSRC_32
- #define BLT_FUNC(s,d) *d = ~(*s)
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_ONLYSRC_32
- #define BLT_FUNC(s,d) *d = (*s) & ~(*d)
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_NOTDST_32
- #define BLT_FUNC(s,d) *d = ~(*d)
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_EOR_32
- #define BLT_FUNC(s,d) *d = (*s) ^ (*d)
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_NAND_32
- #define BLT_FUNC(s,d) *d = ~((*s) & (*d))
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_AND_32
- #define BLT_FUNC(s,d) *d = (*s) & (*d)
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_NEOR_32
- #define BLT_FUNC(s,d) *d = ~((*s) ^ (*d))
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_NOTONLYSRC_32
- #define BLT_FUNC(s,d) *d = ~(*s) | (*d)
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_NOTONLYDST_32
- #define BLT_FUNC(s,d) *d = ~(*d) | (*s)
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_OR_32
- #define BLT_FUNC(s,d) *d = (*s) | (*d)
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_TRUE_32
- #define BLT_FUNC(s,d) *d = 0xffffffff
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_SWAP_32
- #define BLT_FUNC(s,d) tmp = *d ; *d = *s; *s = tmp;
- #define BLT_TEMP
- #include "../p96_blit.cpp"
- #undef BLT_SIZE
- #undef BLT_MULT
- #define BLT_SIZE 3
- #define BLT_MULT 1
- #define BLT_NAME BLIT_FALSE_24
- #define BLT_FUNC(s,d) *d = 0
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_NOR_24
- #define BLT_FUNC(s,d) *d = ~((*s) | (*d))
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_ONLYDST_24
- #define BLT_FUNC(s,d) *d = (*d) & ~(*s)
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_NOTSRC_24
- #define BLT_FUNC(s,d) *d = ~(*s)
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_ONLYSRC_24
- #define BLT_FUNC(s,d) *d = (*s) & ~(*d)
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_NOTDST_24
- #define BLT_FUNC(s,d) *d = ~(*d)
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_EOR_24
- #define BLT_FUNC(s,d) *d = (*s) ^ (*d)
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_NAND_24
- #define BLT_FUNC(s,d) *d = ~((*s) & (*d))
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_AND_24
- #define BLT_FUNC(s,d) *d = (*s) & (*d)
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_NEOR_24
- #define BLT_FUNC(s,d) *d = ~((*s) ^ (*d))
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_NOTONLYSRC_24
- #define BLT_FUNC(s,d) *d = ~(*s) | (*d)
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_NOTONLYDST_24
- #define BLT_FUNC(s,d) *d = ~(*d) | (*s)
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_OR_24
- #define BLT_FUNC(s,d) *d = (*s) | (*d)
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_TRUE_24
- #define BLT_FUNC(s,d) *d = 0xffffffff
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_SWAP_24
- #define BLT_FUNC(s,d) tmp = *d ; *d = *s; *s = tmp;
- #define BLT_TEMP
- #include "../p96_blit.cpp"
- #undef BLT_SIZE
- #undef BLT_MULT
- #define BLT_SIZE 2
- #define BLT_MULT 2
- #define BLT_NAME BLIT_FALSE_16
- #define BLT_FUNC(s,d) *d = 0
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_NOR_16
- #define BLT_FUNC(s,d) *d = ~((*s) | (*d))
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_ONLYDST_16
- #define BLT_FUNC(s,d) *d = (*d) & ~(*s)
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_NOTSRC_16
- #define BLT_FUNC(s,d) *d = ~(*s)
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_ONLYSRC_16
- #define BLT_FUNC(s,d) *d = (*s) & ~(*d)
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_NOTDST_16
- #define BLT_FUNC(s,d) *d = ~(*d)
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_EOR_16
- #define BLT_FUNC(s,d) *d = (*s) ^ (*d)
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_NAND_16
- #define BLT_FUNC(s,d) *d = ~((*s) & (*d))
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_AND_16
- #define BLT_FUNC(s,d) *d = (*s) & (*d)
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_NEOR_16
- #define BLT_FUNC(s,d) *d = ~((*s) ^ (*d))
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_NOTONLYSRC_16
- #define BLT_FUNC(s,d) *d = ~(*s) | (*d)
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_NOTONLYDST_16
- #define BLT_FUNC(s,d) *d = ~(*d) | (*s)
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_OR_16
- #define BLT_FUNC(s,d) *d = (*s) | (*d)
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_TRUE_16
- #define BLT_FUNC(s,d) *d = 0xffffffff
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_SWAP_16
- #define BLT_FUNC(s,d) tmp = *d ; *d = *s; *s = tmp;
- #define BLT_TEMP
- #include "../p96_blit.cpp"
- #undef BLT_SIZE
- #undef BLT_MULT
- #define BLT_SIZE 1
- #define BLT_MULT 4
- #define BLT_NAME BLIT_FALSE_8
- #define BLT_FUNC(s,d) *d = 0
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_NOR_8
- #define BLT_FUNC(s,d) *d = ~((*s) | (*d))
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_ONLYDST_8
- #define BLT_FUNC(s,d) *d = (*d) & ~(*s)
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_NOTSRC_8
- #define BLT_FUNC(s,d) *d = ~(*s)
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_ONLYSRC_8
- #define BLT_FUNC(s,d) *d = (*s) & ~(*d)
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_NOTDST_8
- #define BLT_FUNC(s,d) *d = ~(*d)
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_EOR_8
- #define BLT_FUNC(s,d) *d = (*s) ^ (*d)
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_NAND_8
- #define BLT_FUNC(s,d) *d = ~((*s) & (*d))
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_AND_8
- #define BLT_FUNC(s,d) *d = (*s) & (*d)
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_NEOR_8
- #define BLT_FUNC(s,d) *d = ~((*s) ^ (*d))
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_NOTONLYSRC_8
- #define BLT_FUNC(s,d) *d = ~(*s) | (*d)
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_NOTONLYDST_8
- #define BLT_FUNC(s,d) *d = ~(*d) | (*s)
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_OR_8
- #define BLT_FUNC(s,d) *d = (*s) | (*d)
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_TRUE_8
- #define BLT_FUNC(s,d) *d = 0xffffffff
- #include "../p96_blit.cpp"
- #define BLT_NAME BLIT_SWAP_8
- #define BLT_FUNC(s,d) tmp = *d ; *d = *s; *s = tmp;
- #define BLT_TEMP
- #include "../p96_blit.cpp"
- #undef BLT_SIZE
- #undef BLT_MULT
- #define PARMS width, height, src, dst, ri->BytesPerRow, dstri->BytesPerRow
- /*
- * Functions to perform an action on the frame-buffer
- */
- static int do_blitrect_frame_buffer (struct RenderInfo *ri, struct
- RenderInfo *dstri, unsigned long srcx, unsigned long srcy,
- unsigned long dstx, unsigned long dsty, unsigned long width, unsigned
- long height, uae_u8 mask, BLIT_OPCODE opcode)
- {
- uae_u8 *src, *dst;
- uae_u8 Bpp = GetBytesPerPixel (ri->RGBFormat);
- unsigned long total_width = width * Bpp;
- src = ri->Memory + srcx * Bpp + srcy * ri->BytesPerRow;
- dst = dstri->Memory + dstx * Bpp + dsty * dstri->BytesPerRow;
- if (mask != 0xFF && Bpp > 1) {
- write_log (_T("WARNING - BlitRect() has mask 0x%x with Bpp %d.\n"), mask, Bpp);
- }
- P96TRACE ((_T("(%dx%d)=(%dx%d)=(%dx%d)=%d\n"), srcx, srcy, dstx, dsty, width, height, opcode));
- if (mask == 0xFF || Bpp > 1) {
- if(opcode == BLIT_SRC) {
- /* handle normal case efficiently */
- if (ri->Memory == dstri->Memory && dsty == srcy) {
- unsigned long i;
- for (i = 0; i < height; i++, src += ri->BytesPerRow, dst += dstri->BytesPerRow)
- memmove (dst, src, total_width);
- } else if (dsty < srcy) {
- unsigned long i;
- for (i = 0; i < height; i++, src += ri->BytesPerRow, dst += dstri->BytesPerRow)
- memcpy (dst, src, total_width);
- } else {
- unsigned long i;
- src += (height - 1) * ri->BytesPerRow;
- dst += (height - 1) * dstri->BytesPerRow;
- for (i = 0; i < height; i++, src -= ri->BytesPerRow, dst -= dstri->BytesPerRow)
- memcpy (dst, src, total_width);
- }
- return 1;
- } else {
- if (Bpp == 4) {
- /* 32-bit optimized */
- switch (opcode)
- {
- case BLIT_FALSE: BLIT_FALSE_32 (PARMS); break;
- case BLIT_NOR: BLIT_NOR_32 (PARMS); break;
- case BLIT_ONLYDST: BLIT_ONLYDST_32 (PARMS); break;
- case BLIT_NOTSRC: BLIT_NOTSRC_32 (PARMS); break;
- case BLIT_ONLYSRC: BLIT_ONLYSRC_32 (PARMS); break;
- case BLIT_NOTDST: BLIT_NOTDST_32 (PARMS); break;
- case BLIT_EOR: BLIT_EOR_32 (PARMS); break;
- case BLIT_NAND: BLIT_NAND_32 (PARMS); break;
- case BLIT_AND: BLIT_AND_32 (PARMS); break;
- case BLIT_NEOR: BLIT_NEOR_32 (PARMS); break;
- case BLIT_NOTONLYSRC: BLIT_NOTONLYSRC_32 (PARMS); break;
- case BLIT_NOTONLYDST: BLIT_NOTONLYDST_32 (PARMS); break;
- case BLIT_OR: BLIT_OR_32 (PARMS); break;
- case BLIT_TRUE: BLIT_TRUE_32 (PARMS); break;
- case BLIT_SWAP: BLIT_SWAP_32 (PARMS); break;
- }
- } else if (Bpp == 3) {
- /* 24-bit (not very) optimized */
- switch (opcode)
- {
- case BLIT_FALSE: BLIT_FALSE_24 (PARMS); break;
- case BLIT_NOR: BLIT_NOR_24 (PARMS); break;
- case BLIT_ONLYDST: BLIT_ONLYDST_24 (PARMS); break;
- case BLIT_NOTSRC: BLIT_NOTSRC_24 (PARMS); break;
- case BLIT_ONLYSRC: BLIT_ONLYSRC_24 (PARMS); break;
- case BLIT_NOTDST: BLIT_NOTDST_24 (PARMS); break;
- case BLIT_EOR: BLIT_EOR_24 (PARMS); break;
- case BLIT_NAND: BLIT_NAND_24 (PARMS); break;
- case BLIT_AND: BLIT_AND_24 (PARMS); break;
- case BLIT_NEOR: BLIT_NEOR_24 (PARMS); break;
- case BLIT_NOTONLYSRC: BLIT_NOTONLYSRC_24 (PARMS); break;
- case BLIT_NOTONLYDST: BLIT_NOTONLYDST_24 (PARMS); break;
- case BLIT_OR: BLIT_OR_24 (PARMS); break;
- case BLIT_TRUE: BLIT_TRUE_24 (PARMS); break;
- case BLIT_SWAP: BLIT_SWAP_24 (PARMS); break;
- }
- } else if (Bpp == 2) {
- /* 16-bit optimized */
- switch (opcode)
- {
- case BLIT_FALSE: BLIT_FALSE_16 (PARMS); break;
- case BLIT_NOR: BLIT_NOR_16 (PARMS); break;
- case BLIT_ONLYDST: BLIT_ONLYDST_16 (PARMS); break;
- case BLIT_NOTSRC: BLIT_NOTSRC_16 (PARMS); break;
- case BLIT_ONLYSRC: BLIT_ONLYSRC_16 (PARMS); break;
- case BLIT_NOTDST: BLIT_NOTDST_16 (PARMS); break;
- case BLIT_EOR: BLIT_EOR_16 (PARMS); break;
- case BLIT_NAND: BLIT_NAND_16 (PARMS); break;
- case BLIT_AND: BLIT_AND_16 (PARMS); break;
- case BLIT_NEOR: BLIT_NEOR_16 (PARMS); break;
- case BLIT_NOTONLYSRC: BLIT_NOTONLYSRC_16 (PARMS); break;
- case BLIT_NOTONLYDST: BLIT_NOTONLYDST_16 (PARMS); break;
- case BLIT_OR: BLIT_OR_16 (PARMS); break;
- case BLIT_TRUE: BLIT_TRUE_16 (PARMS); break;
- case BLIT_SWAP: BLIT_SWAP_16 (PARMS); break;
- }
- } else if (Bpp == 1) {
- /* 8-bit optimized */
- switch (opcode)
- {
- case BLIT_FALSE: BLIT_FALSE_8 (PARMS); break;
- case BLIT_NOR: BLIT_NOR_8 (PARMS); break;
- case BLIT_ONLYDST: BLIT_ONLYDST_8 (PARMS); break;
- case BLIT_NOTSRC: BLIT_NOTSRC_8 (PARMS); break;
- case BLIT_ONLYSRC: BLIT_ONLYSRC_8 (PARMS); break;
- case BLIT_NOTDST: BLIT_NOTDST_8 (PARMS); break;
- case BLIT_EOR: BLIT_EOR_8 (PARMS); break;
- case BLIT_NAND: BLIT_NAND_8 (PARMS); break;
- case BLIT_AND: BLIT_AND_8 (PARMS); break;
- case BLIT_NEOR: BLIT_NEOR_8 (PARMS); break;
- case BLIT_NOTONLYSRC: BLIT_NOTONLYSRC_8 (PARMS); break;
- case BLIT_NOTONLYDST: BLIT_NOTONLYDST_8 (PARMS); break;
- case BLIT_OR: BLIT_OR_8 (PARMS); break;
- case BLIT_TRUE: BLIT_TRUE_8 (PARMS); break;
- case BLIT_SWAP: BLIT_SWAP_8 (PARMS); break;
- }
- }
- }
- return 1;
- }
- return 0;
- }
- /*
- SetSpritePosition:
- Synopsis: SetSpritePosition(bi, RGBFormat);
- Inputs: a0: struct BoardInfo *bi
- d7: RGBFTYPE RGBFormat
- */
- static uae_u32 REGPARAM2 picasso_SetSpritePosition (TrapContext *ctx)
- {
- int monid = currprefs.rtgboards[0].monitor_id;
- struct picasso96_state_struct *state = &picasso96_state[monid];
- struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid];
- …
Large files files are truncated, but you can click here to view the full file