Commits (8)
  • Robert Sprowson's avatar
    Turn off close icon on transitory dbox · b10e0ce4
    Robert Sprowson authored
    The 'shapshot' window shouldn't have a close icon, otherwise it automatically gets an iconise icon, and you can't sensibly iconise or uniconise it as it's transitory.
    
    Version 2.18. Tagged as 'Paint-2_18'
    b10e0ce4
  • Jeffrey Lee's avatar
    Fix incorrect calculation of memory requirements for alpha-masked sprites · 2e0c3993
    Jeffrey Lee authored
    Detail:
      c/PSprite - Fix psprite_size to correctly calculate the memory required by alpha masks
    Admin:
      Tested on Raspberry Pi
      Fixes issue reported on forums with 'Not enough memory' errors from SpriteExtend when resizing or adding rows/columns to alpha-masked sprites: https://www.riscosopen.org/forum/forums/4/topics/3610
    
    
    Version 2.19. Tagged as 'Paint-2_19'
    2e0c3993
  • Jeffrey Lee's avatar
    Fix unreliable sorting of sprites · 617dbd01
    Jeffrey Lee authored
    Detail:
      c/Menus - Fix sprite sort code to take into account the fact that variable-length array allocations may cause flex blocks to be moved (due to CLib allocating the array from the heap)
    Admin:
      Tested on Raspberry Pi
      Appears to fix 'sort by name' sometimes resulting in a random sort order being used
      Will hopefully fix 'out of memory' error reported on forums (unable to reproduce here, but this is a likely cause)
      https://www.riscosopen.org/forum/forums/4/topics/3657
    
    
    Version 2.20. Tagged as 'Paint-2_20'
    617dbd01
  • ROOL's avatar
    Warning suppression · c2a2a721
    ROOL authored
    Detail:
      3 fewer compiler warnings.
    Admin:
      Submission for the Paint bounty.
      Built, but no run time testing.
    c2a2a721
  • ROOL's avatar
    Moderate spray can density based on time not CPU speed · 205da1f5
    ROOL authored
    Detail:
      The spray tool rate was ultimately determined by the number of wimp polls per second, which on a fast CPU can be 10,000's making the spray can more of a circle drawing tool.
      Use OS_ReadMonotonicTime to moderate the spray rate, so the speed of the CPU doesn't matter.
      Default density increased to 100 to achieve roughly the same density as a StrongARM Risc PC would previously.
    Admin:
      Submission for the Paint bounty.
    
    Version 2.21. Tagged as 'Paint-2_21'
    205da1f5
  • ROOL's avatar
    Add 4k and 64k new sprite selector · 6e3eb1c1
    ROOL authored
    Detail:
      Put in minimal support to create 4k and 64k sprites (currently, TBGR only) so that the User Guide chapter makes sense.
      Previously it was only possible to create such sprites by switching to that mode and doing a screen capture.
    Admin:
      Tested on RISC OS 4.02 (ie. without 4k & 64k support) and RISC OS 5.23 (ie. with).
    
    Version 2.22. Tagged as 'Paint-2_22'
    6e3eb1c1
  • ROOL's avatar
    Add mousewheel zoom/scroll and auto scrolling of selected tools · 82cd0dc4
    ROOL authored
    Detail:
      The mouse wheel can now be used to
      * scroll up/down
      * +shift to scroll left/right
      * +control to zoom in/out
      on an open sprite editing window.
      The sprite editing window will auto scroll when the mouse approaches the border with
      * the move whole sprite "hand" tool
      * the copy block "camera" tool
      * the move block "scissors" tool
    Admin:
      Submission for the Paint bounty.
    
    Version 2.23. Tagged as 'Paint-2_23'
    82cd0dc4
  • Robert Sprowson's avatar
    Makefile tweak for debug target · 72200567
    Robert Sprowson authored
    72200567
......@@ -230,8 +230,7 @@ bbe-paint: bbe-generic
# debugging version:
#
abs.!RunImageD: ${OBJSD} ${RLIB} ${CLIB}
${LD} -o $@ ${OBJSD} ${RLIB} ${CLIB}
SetType $@ Absolute
${LD} -d -o $@ ${OBJSD} ${RLIB} ${CLIB}
debug.${APP}.!Boot: ${RDIR}.!Boot
${CP} ${RDIR}.!Boot $@ ${CPFLAGS}
......
......@@ -11,13 +11,13 @@
GBLS Module_HelpVersion
GBLS Module_ComponentName
GBLS Module_ComponentPath
Module_MajorVersion SETS "2.17"
Module_Version SETA 217
Module_MajorVersion SETS "2.23"
Module_Version SETA 223
Module_MinorVersion SETS ""
Module_Date SETS "31 Jul 2014"
Module_ApplicationDate SETS "31-Jul-14"
Module_Date SETS "11 Nov 2017"
Module_ApplicationDate SETS "11-Nov-17"
Module_ComponentName SETS "Paint"
Module_ComponentPath SETS "castle/RiscOS/Sources/Apps/Paint"
Module_FullVersion SETS "2.17"
Module_HelpVersion SETS "2.17 (31 Jul 2014)"
Module_FullVersion SETS "2.23"
Module_HelpVersion SETS "2.23 (11 Nov 2017)"
END
/* (2.17)
/* (2.23)
*
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1.
*
*/
#define Module_MajorVersion_CMHG 2.17
#define Module_MajorVersion_CMHG 2.23
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 31 Jul 2014
#define Module_Date_CMHG 11 Nov 2017
#define Module_MajorVersion "2.17"
#define Module_Version 217
#define Module_MajorVersion "2.23"
#define Module_Version 223
#define Module_MinorVersion ""
#define Module_Date "31 Jul 2014"
#define Module_Date "11 Nov 2017"
#define Module_ApplicationDate "31-Jul-14"
#define Module_ApplicationDate "11-Nov-17"
#define Module_ComponentName "Paint"
#define Module_ComponentPath "castle/RiscOS/Sources/Apps/Paint"
#define Module_FullVersion "2.17"
#define Module_HelpVersion "2.17 (31 Jul 2014)"
#define Module_LibraryVersionInfo "2:17"
#define Module_FullVersion "2.23"
#define Module_HelpVersion "2.23 (11 Nov 2017)"
#define Module_LibraryVersionInfo "2:23"
......@@ -257,7 +257,7 @@ static void display_sprite_info (main_sprite *sprite)
dbox_setfield(d, d_Info_DPI, "?");
else
{
sprintf(temp,msgs_lookup("PntGF"),180.0f/(1<<xeig),180.0f/(1<<yeig));
sprintf(temp,msgs_lookup("PntGF"),180.0f/(float)(1L<<xeig),180.0f/(float)(1L<<yeig));
dbox_setfield(d, d_Info_DPI, temp);
}
}
......@@ -1256,7 +1256,7 @@ void menus_insdel_frig (void)
insdel_pending = 0;
}
static void showmag (void *handle)
void menus_showmag (void *handle)
{ main_sprite_window *sprite = (main_sprite_window *) handle;
int m, d;
......@@ -1940,7 +1940,7 @@ void menus_sprite_handler (void *handle, char *hit)
case s_Zoom:
if (hit [1])
magnify_select (&sprw->blobsize.scale_xmul,
&sprw->blobsize.scale_xdiv, 999, 999, showmag, sprw);
&sprw->blobsize.scale_xdiv, 999, 999, menus_showmag, sprw);
break;
case s_Grid:
......@@ -2431,18 +2431,26 @@ void menus_file_handler (void *handle, char *hit)
case m_Misc_SBSize:
{ /* Sort by name or size */
sprite_area *unsorted = window->data->file.spritearea;
int count = unsorted->number;
if (count < 2) break; /* Not worth sorting */
sprite_tosort tosort[count];
sprite_tosort *tosortptr[count];
/* variable length array allocation may have caused flex blocks to move - re-fetch sprite area pointer */
tosort[0].orgsprite = NULL; /* Paranoia - try and ensure compiler doesn't postpone array allocation */
tosortptr[0] = NULL;
unsorted = window->data->file.spritearea;
sprite_area *sorted;
sprite_header *header;
int count = unsorted->number;
main_file *file = &window->data->file;
main_sprite *sprite;
int loop, next;
BOOL byname = (hit[1] == m_Misc_SBName);
sprite_tosort tosort[count];
sprite_tosort *tosortptr[count];
os_regset regs;
if (count < 2) break; /* Not worth sorting */
ftracef1 ("sort - sorting %d sprites\n", count);
count = 0;
......
......@@ -213,11 +213,20 @@ int psprite_size (int width, int height, int mode, int mask, int palette)
}
if ((unsigned) mode < 256u)
{
/*Old-format sprite.*/
spritesize += spritesize;
}
else if (mode & 0x80000000)
{
/*8bpp alpha mask.*/
spritesize += height*((width+3)&~3);
}
else
{
/*New format sprite - 1bpp mask.*/
spritesize += height*(width + 31 >> 5 << 2);
}
}
spritesize += sizeof (sprite_header) + palsize;
......@@ -2488,7 +2497,7 @@ static void Decode (int *lb_bpp_out, unsigned int *mode_out)
{ wimp_which_block which_block;
wimp_i results [7]; /*only 2 would be needed if function keys couldn't
wierdly set multiple icons in the same E S G*/
int x_eig = 0, y_eig = 0, lb_bpp = 0;
int x_eig = 0, y_eig = 0, lb_bpp = 0, cols = 0;
unsigned int mode;
ftracef0 ("Decode\n");
......@@ -2503,7 +2512,9 @@ static void Decode (int *lb_bpp_out, unsigned int *mode_out)
case d_Create_Colours_4: lb_bpp = 1; break;
case d_Create_Colours_16: lb_bpp = 2; break;
case d_Create_Colours_256: lb_bpp = 3; break;
case d_Create_Colours_32k: lb_bpp = 4; break;
case d_Create_Colours_4k: lb_bpp = 4, cols = 1<<12; break;
case d_Create_Colours_32k: lb_bpp = 4; cols = 1<<15; break;
case d_Create_Colours_64k: lb_bpp = 4; cols = 1<<16; break;
case d_Create_Colours_16M: lb_bpp = 5; break;
}
ftracef1 ("lb_bpp %d\n", lb_bpp);
......@@ -2539,6 +2550,15 @@ static void Decode (int *lb_bpp_out, unsigned int *mode_out)
mode = modes_2x2 [lb_bpp];
}
if ((mode == ~0u) && (lb_bpp == 4) && (cols != 1<<15))
{ /*Special handling of 16bpp.Always create TBGR for now.*/
if (cols == 1<<12)
mode = (15 << 27) | (16 << 20) | 0 | y_eig << 6 | x_eig << 4 | 1u;
else
mode = (10 << 27) | 180u >> y_eig << 14 | 180u >> x_eig << 1 | 1u;
ftracef1 ("mode 0x%X\n", mode);
}
if (mode == ~0u)
{ mode = lb_bpp + 1 << 27 | 180u >> y_eig << 14 | 180u >> x_eig << 1 | 1u;
ftracef1 ("mode 0x%X\n", mode);
......@@ -2876,10 +2896,22 @@ static BOOL Grey_Scale (int lb_bpp)
return TRUE;
}
static BOOL Have4k64k (void)
{
/*True if the OS can plot 4k and 64k TBGR, else false*/
/*The fallback for unknown sprite types in the kernel is 32bpp, so if
asking about 4k & 64k we get back 32bpp as the answer, the kernel
has used the fallback since it should be 16bpp*/
return (bbc_modevar (0x79004051u /* 4k TBGR */, bbc_Log2BPP) != 5 &&
bbc_modevar (0x501680B5u /* 64k TBGR */, bbc_Log2BPP) != 5);
}
static void Create_Handler (wimp_eventstr *e, void *handle)
{ int lb_bpp;
unsigned mode;
BOOL extd_16bpp = Have4k64k();
handle = handle;
......@@ -2896,11 +2928,15 @@ static void Create_Handler (wimp_eventstr *e, void *handle)
if (dbox_getnumeric (Create, d_Create_Palette_Colour) ||
dbox_getnumeric (Create, d_Create_Palette_Mono))
{ dbox_fadefield (Create, d_Create_Colours_32k);
{ dbox_fadefield (Create, d_Create_Colours_4k);
dbox_fadefield (Create, d_Create_Colours_32k);
dbox_fadefield (Create, d_Create_Colours_64k);
dbox_fadefield (Create, d_Create_Colours_16M);
}
else
{ dbox_unfadefield (Create, d_Create_Colours_32k);
{ if (extd_16bpp) dbox_unfadefield (Create, d_Create_Colours_4k);
dbox_unfadefield (Create, d_Create_Colours_32k);
if (extd_16bpp) dbox_unfadefield (Create, d_Create_Colours_64k);
dbox_unfadefield (Create, d_Create_Colours_16M);
}
......@@ -2935,8 +2971,8 @@ static void Create_Handler (wimp_eventstr *e, void *handle)
void psprite_create_show (main_window *window, BOOL auto_open,
char *sprite_name)
{ int width, height, x_eig, y_eig, lb_bpp;
BOOL grey_scale;
{ int width, height, x_eig, y_eig, lb_bpp, ncolour;
BOOL grey_scale, full_palette, extd_16bpp = Have4k64k();
wimp_w d_w;
ftracef0 ("psprite_create_show\n");
......@@ -2967,6 +3003,8 @@ void psprite_create_show (main_window *window, BOOL auto_open,
x_eig = bbc_modevar (-1, bbc_XEigFactor);
y_eig = bbc_modevar (-1, bbc_YEigFactor);
lb_bpp = bbc_modevar (-1, bbc_Log2BPP);
ncolour = bbc_modevar (-1, bbc_NColour);
full_palette = (bbc_modevar (-1, bbc_ModeFlags) & 0x80) != 0;
grey_scale = lb_bpp <= 3 && Grey_Scale (lb_bpp);
ftracef4 ("x_eig %d, y_eig %d, lb_bpp %d, grey_scale %s\n",
......@@ -2992,7 +3030,9 @@ void psprite_create_show (main_window *window, BOOL auto_open,
dbox_setnumeric (Create, d_Create_Colours_4, lb_bpp == 1);
dbox_setnumeric (Create, d_Create_Colours_16, lb_bpp == 2);
dbox_setnumeric (Create, d_Create_Colours_256, lb_bpp == 3);
dbox_setnumeric (Create, d_Create_Colours_32k, lb_bpp == 4);
dbox_setnumeric (Create, d_Create_Colours_4k, lb_bpp == 4 && (ncolour == 4095));
dbox_setnumeric (Create, d_Create_Colours_32k, lb_bpp == 4 && !full_palette);
dbox_setnumeric (Create, d_Create_Colours_64k, lb_bpp == 4 && full_palette);
dbox_setnumeric (Create, d_Create_Colours_16M, lb_bpp == 5);
ftracef1 ("bbc_modevar (6 << 27 | 1, bbc_Log2BPP) %d\n",
......@@ -3002,6 +3042,11 @@ void psprite_create_show (main_window *window, BOOL auto_open,
dbox_fadefield (Create, d_Create_Colours_32k);
dbox_fadefield (Create, d_Create_Colours_16M);
}
if (!extd_16bpp)
{ /*This OS can't do 4k and 64k.*/
dbox_fadefield (Create, d_Create_Colours_4k);
dbox_fadefield (Create, d_Create_Colours_64k);
}
Decode (&lb_bpp, &Mode);
......
......@@ -25,6 +25,7 @@
#include <swis.h>
#include "Global/FileTypes.h"
#include "Global/OsBytes.h"
#include "akbd.h"
#include "bbc.h"
......@@ -58,8 +59,9 @@ int main_current_options.zoom.div = 1;
int main_current_options.grid.colour = 255;*/
static wimp_w lastnullholder = -1;
static int scrolltime = 0;
/************************************+**
/***************************************
* *
* Set the extent of a file window. *
* *
......@@ -100,6 +102,73 @@ void sprwindow_set_work_extent (main_window *window, BOOL open)
main_force_redraw (window->handle);
}
/****************************************************
* *
* Scroll a sprite window at the specified speeds. *
* *
****************************************************/
void sprwindow_scroll (main_window *window, int scrollx, int scrolly)
{ wimp_wstate currinfo;
ftracef0 ("sprwindow_scroll\n");
int oldscrollx = scrollx;
int oldscrolly = scrolly;
int elapsed;
/* Adjust scrolling speed according to CPU speed */
os_swix1r(OS_ReadMonotonicTime, 0, &elapsed);
if (scrolltime > 0)
{ elapsed -= scrolltime;
/* Divide these by a bigger constant to slow down the scroll rate */
scrollx = (scrollx * elapsed) / 3;
scrolly = (scrolly * elapsed) / 3;
/* The scrolling will only go ahead when enough time's passed to scroll in every direction requested */
/* The elapsed >= 8 clause is like a frame rate cap to avoid excess CPU load and flicker */
if (!((scrollx || scrolly) && elapsed >= 8 && (scrollx || !oldscrollx) && (scrolly || !oldscrolly)))
{ /* Do nothing until more time has elapsed */
return;
}
}
else
{ scrolltime = elapsed;
/* Do nothing until more time has elapsed */
return;
}
wimpt_noerr (wimp_get_wind_state (window->handle, &currinfo));
int oldx = currinfo.o.x;
int oldy = currinfo.o.y;
/* Apply the scrolling */
currinfo.o.x += scrollx;
currinfo.o.y += scrolly;
ftracef3 ("scrollx: %d oldx: %d currinfo.o.x: %d\n", scrollx, oldx, currinfo.o.x);
ftracef3 ("scrolly: %d oldy: %d currinfo.o.y: %d\n", scrolly, oldy, currinfo.o.y);
wimpt_noerr (wimp_open_wind (&currinfo.o)); /* force resize */
/* Find out how much the window really scrolled by */
wimpt_noerr (wimp_get_wind_state (window->handle, &currinfo));
scrollx = (currinfo.o.x - oldx) / window->data->sprite.sprite->mode.scale_xmul;
scrolly = (currinfo.o.y - oldy) / window->data->sprite.sprite->mode.scale_ymul;
if (scrollx || scrolly)
{ /* Reset the timer */
scrolltime += elapsed;
}
}
/***********************************************************
* *
* Stop the auto-scroll timer used in sprwindow_scroll () *
* *
***********************************************************/
void sprwindow_stop_scroll (void)
{ scrolltime = 0;
}
/******************************************************
* Reset the titles of all windows open on the sprite *
......@@ -341,6 +410,8 @@ void sprwindow_release_idle_events (main_sprite *sprite)
{ main_claim_idle (lastnullholder);
break;
}
/* Reset the timer used in window auto-scrolling */
sprwindow_stop_scroll ();
}
static BOOL cant_extend_stack_buffer (char **b, int *s)
......@@ -365,6 +436,7 @@ void sprwindow_event_handler (wimp_eventstr *e, void *handle)
{ main_window *window = (main_window *) handle;
BOOL read_only = window->data->sprite.read_only;
int isMouseWheel = 1;
ftracef3
("sprwindow_event_handler: event type %d, main_window 0x%X, w 0x%X\n",
......@@ -505,6 +577,84 @@ void sprwindow_event_handler (wimp_eventstr *e, void *handle)
wimp_processkey (e->data.key.chcode);
break;
case wimp_ESCROLL: /* Support for mousewheel to scroll and zoom */
ftracef2("wimp_ESCROLL in sprite window. scroll.x: %d scroll.y: %d\n", e->data.scroll.x, e->data.scroll.y);
/* Workaround for RISC OS 5 mousewheel behaviour (5 scroll events sent per wheel step) */
static int eventCount = -1;
static int scrollFix = 0;
wimp_mousestr mouse;
wimpt_noerr (wimp_get_point_info (&mouse));
/* If the pointer is over the scroll bar / buttons and select / adjust clicked, don't skip any scroll events. */
if (((mouse.bbits & wimp_BRIGHT) || (mouse.bbits & wimp_BLEFT)) &&
((mouse.i <= -6 && mouse.i >= -8) || (mouse.i <= -10 && mouse.i >= -12)))
{ ftracef0("Mouse is over vertical scroll bar / buttons. Scroll fix inactive.\n");
if (eventCount > 0)
eventCount = 0;
isMouseWheel = 0;
}
if (eventCount <= 0 && (e->data.scroll.x || e->data.scroll.y))
{ /*Read keyboard state.*/
int r1 = 0;
int r2 = 255;
if (isMouseWheel)
os_byte (OsByte_RW_KeybStatus, &r1, &r2);
/*If Ctrl pressed, adjust the zoom level*/
if (r1 & 0x40)
{ if (e->data.scroll.y == -1)
{ /* Zoom out */
if (window->data->sprite.blobsize.scale_xmul > 1)
window->data->sprite.blobsize.scale_xmul--;
else if (window->data->sprite.blobsize.scale_xdiv < 999)
window->data->sprite.blobsize.scale_xdiv++;
menus_showmag (&window->data->sprite);
}
else if (e->data.scroll.y == 1)
{ /* Zoom in */
if (window->data->sprite.blobsize.scale_xdiv > 1)
window->data->sprite.blobsize.scale_xdiv--;
else if (window->data->sprite.blobsize.scale_xmul < 999)
window->data->sprite.blobsize.scale_xmul++;
menus_showmag (&window->data->sprite);
}
}
else
{ /*If Shift pressed, scroll horizontally with mousewheel*/
if ((r1 & 8) && e->data.scroll.y)
{ e->data.scroll.x = -e->data.scroll.y;
e->data.scroll.y = 0;
}
switch (e->data.scroll.x)
{ case -2: e->data.scroll.o.x -= (e->data.scroll.o.box.x1 - e->data.scroll.o.box.x0); break;
case -1: e->data.scroll.o.x -= 64; break;
case 1: e->data.scroll.o.x += 64; break;
case 2: e->data.scroll.o.x += (e->data.scroll.o.box.x1 - e->data.scroll.o.box.x0); break;
}
switch (e->data.scroll.y)
{ case -2: e->data.scroll.o.y -= (e->data.scroll.o.box.y1 - e->data.scroll.o.box.y0); break;
case -1: e->data.scroll.o.y -= 64; break;
case 1: e->data.scroll.o.y += 64; break;
case 2: e->data.scroll.o.y += (e->data.scroll.o.box.y1 - e->data.scroll.o.box.y0); break;
}
if (wimpt_complain (wimp_open_wind (&e->data.scroll.o)))
return;
}
}
if (eventCount == -1)
{ /* At time of writing, version 0.25 and up of the USBDriver has a "feature" that sends 5 scroll events per mouse wheel step */
os_error *err = os_cli("RMEnsure USBDriver 0.25");
/* If no error is generated by RMEnsure, the troublesome driver is present and we do need the fix */
scrollFix = (err == NULL);
eventCount = 0;
}
if (scrollFix)
{ eventCount++;
ftracef1("scrollFix active. eventCount %d\n", eventCount);
if (eventCount >=5)
eventCount = 0;
}
break;
case wimp_ECLOSE:
ftracef0 ("Window close event\n");
sprwindow_delete (window);
......@@ -723,6 +873,7 @@ void sprwindow_new (main_sprite *sprite)
main_allocate_position (&wind.box);
wind.colours [wimp_WCWKAREABACK] = '\377';
wind.titleflags = (wimp_iconflags) (wind.titleflags | wimp_INDIRECT);
wind.flags = (wimp_wflags) (wind.flags | wimp_WSCROLL_R1); /* Enable scroll requests for mouse wheel */
if ((wind.title.indirecttext.buffer = m_ALLOC (20)) == NULL)
{ m_FREE (sprite_window, sizeof (main_sprite_window));
......
......@@ -68,10 +68,11 @@ static int textxsize;
static int textysize;
static int textxspace;
char tools_spray_density [5] = "20";
char tools_spray_density [5] = "100";
char tools_spray_radius [5] = "30";
static int spraydensity;
static int sprayradius;
static int spraytime = 0;
/* SMC: The following are not sprite names. They are tokens which must be
* used to look up the real sprite name in the Messages file.
......@@ -199,17 +200,54 @@ static void tools_get_sprite_info_pixels(main_sprite *sprite, sprite_info *sin)
void tools_mouse_to_pixel(main_window *window, wimp_mousestr *mpos,
int *cx, int *cy)
{
/* Original code clamps coordinates overflowing the sprite bounds, so pass
NULL for new overflowx and overflowy args */
tools_mouse_to_pixel_overflow(window, mpos, cx, cy, NULL, NULL);
}
/********************************************************
* Convert mouse pos to the row or column that it is in *
* (0 <= x < width, 0 <= y < height) *
* If outside or near sprite bounds, an offset is *
* returned using overflowx and overflowy. *
********************************************************/
void tools_mouse_to_pixel_overflow(main_window *window, wimp_mousestr *mpos,
int *cx, int *cy, int *overflowx, int *overflowy)
{
sprite_info sin;
main_sprite *sprite = window->data->sprite.sprite;
wimp_winfo curr;
ftracef0 ("tools_mouse_to_pixel\n");
/* Default values for optional overflow parameters */
if (overflowx)
*overflowx = 0;
if (overflowy)
*overflowy = 0;
curr.w = window->handle;
wimpt_noerr (paintlib_get_wind_info (&curr));
tools_get_sprite_info_pixels(sprite,&sin);
/* See if we have dragged close to the edge of the window */
if (overflowx)
{
if (mpos->x >= curr.info.box.x1 - 10)
*overflowx = 1;
else if (mpos->x - curr.info.box.x0 < 10)
*overflowx = -1;
}
if (overflowy)
{
if (mpos->y >= curr.info.box.y1 - 10)
*overflowy = 1;
else if (mpos->y - curr.info.box.y0 < 10)
*overflowy = -1;
}
if (cx)
{
int x=tools_extent_to_pixel_x(&window->data->sprite, mpos->x - curr.info.box.x0 + curr.info.scx);
......@@ -1482,15 +1520,91 @@ static void order_rect (int *c)
if (c [3] < c [1]) {int t = c [1]; c [1] = c [3]; c [3] = t;}
}
/* Bound_Pointer() and Unbound_Pointer() were taken from Draw, to constrain
* the mouse pointer to the window bounds during auto scrolling */
static void Bound_Pointer (int x0, int y0, int x1, int y1)
{ int ox, oy;
char buf [20];
ftracef0 ("Tools: Bound_Pointer\n");
ox = bbc_vduvar (bbc_OrgX);
oy = bbc_vduvar (bbc_OrgY);
x0 -= ox, y0 -= oy;
x1 -= ox, y1 -= oy;
buf [0] = 1;
buf [1] = x0;
buf [2] = x0 >> 8;
buf [3] = y0;
buf [4] = y0 >> 8;
buf [5] = x1;
buf [6] = x1 >> 8;
buf [7] = y1;
buf [8] = y1 >> 8;
os_swi2 (OS_Word, 21, (int) buf);
}
static void Unbound_Pointer (void)
{ ftracef0 ("Tools: Unbound_Pointer\n");
Bound_Pointer
( 0,
0,
bbc_vduvar (bbc_XWindLimit) << bbc_vduvar (bbc_XEigFactor),
bbc_vduvar (bbc_YWindLimit) << bbc_vduvar (bbc_YEigFactor)
);
}
static void scissorpaint_null (main_window *window, wimp_mousestr *mpos)
{ main_sprite *sprite = window->data->sprite.sprite;
int state, x, y, coord = 3;
int overflowx, overflowy, scrollx, scrolly;
ftracef0 ("scissorpaint_null\n");
if (sprite->toolspace [0] < 0) return; /* we're inside an export */
tools_mouse_to_pixel (window, mpos, &x, &y);
tools_mouse_to_pixel_overflow (window, mpos, &x, &y, &overflowx, &overflowy);
/* Auto scroll if the rectangle was dragged to the edge of the window */
if ((sprite->toolspace [0] == 1 || sprite->toolspace [0] == 3) &&
(mpos->bbits & wimp_BLEFT))
{ wimp_wstate state;
/* Bound the mouse to this window while dragging / auto-scrolling, as Draw does */
wimpt_noerr (wimp_get_wind_state (window->handle,
&state));
Bound_Pointer (state.o.box.x0, state.o.box.y0,
state.o.box.x1, state.o.box.y1);
scrollx = scrolly = 0;
if (overflowx != 0)
scrollx = (overflowx>0)?20:-20;
if (overflowy != 0)
scrolly = (overflowy>0)?20:-20;
if (scrollx || scrolly)
{ /* Auto-scroll the window at a fixed speed */
sprwindow_scroll (window, scrollx, scrolly);
tools_mouse_to_pixel (window, mpos, &x, &y);
}
else
{ /* Reset the auto-scroll timer */
sprwindow_stop_scroll ();
}
}
else
{ /* Unbound the mouse */
Unbound_Pointer ();
/* Reset the auto-scroll timer */
sprwindow_stop_scroll ();
}
if ((state = sprite->toolspace [0]) == 1 && (mpos->bbits & 4) == 0)
{ /* button gone up on initial rect entry: step state */
......@@ -1688,6 +1802,10 @@ static void scissorpaint_stop (main_sprite *sprite)
sprite, sprite->toolspace [0]);
sprwindow_release_idle_events (sprite);
}
/* Unbound the mouse */
Unbound_Pointer ();
/* Reset the auto-scroll timer */
sprwindow_stop_scroll ();
}
static void copymovepaint_click (main_window *window, wimp_mousestr *mpos,
......@@ -2174,63 +2292,91 @@ static void spraycanpaint_splot (main_window *window, wimp_mousestr *mpos)
/*Do nothing if radius == 0. J R C 5th Oct 1993*/
if (sprayradius > 0)
{
int pxs, pys;
tools_mouse_to_pixel (window, mpos, &x, &y);
pxs=tools_pixel_to_point_x(&window->data->sprite, 1);
pys=tools_pixel_to_point_y(&window->data->sprite, 1);
int pxs, pys, elapsed, adjusted_density;
/*Adjust spray density according to CPU speed */
os_swix1r(OS_ReadMonotonicTime, 0, &elapsed);
if (spraytime > 0)
{
elapsed -= spraytime;
/*Divide this by a bigger constant to slow down the spray rate*/
adjusted_density = (spraydensity * elapsed) / 8;
if (adjusted_density > 0)
{
/*Reset the timer*/
spraytime += elapsed;
/*Sanity checks to stop unresponsiveness*/
if (adjusted_density > 999)
adjusted_density = 999;
if (adjusted_density > spraydensity * 2)
adjusted_density = spraydensity * 2;
}
}
else
{
/*Initial spray iteration*/
spraytime = elapsed;
adjusted_density = spraydensity / 10;
}
colour = colours_pack_colour(sprite, gcol);
mask = colours_pack_mask(sprite, gcol);
if (adjusted_density > 0)
{
tools_mouse_to_pixel (window, mpos, &x, &y);
pxs=tools_pixel_to_point_x(&window->data->sprite, 1);
pys=tools_pixel_to_point_y(&window->data->sprite, 1);
sprite->toolspace [0] = x;
sprite->toolspace [1] = y;
ftracef2 ("0x%X->toolspace [0]: 0x%X\n",
sprite, sprite->toolspace [0]);
colour = colours_pack_colour(sprite, gcol);
mask = colours_pack_mask(sprite, gcol);
sid.s.addr = psprite_address (sprite);
sid.tag = sprite_id_addr;
sprite->toolspace [0] = x;
sprite->toolspace [1] = y;
ftracef2 ("0x%X->toolspace [0]: 0x%X\n",
sprite, sprite->toolspace [0]);
dopix = gcol.alpha || (psprite_transparency_type(sprite) == transparency_type_alphachannel);
domask = psprite_hasmask (sprite);
sid.s.addr = psprite_address (sprite);
sid.tag = sprite_id_addr;
visdelay_begin ();
for (i = 0; i < spraydensity; i++)
{ int r, nx, ny;
double theta;
dopix = gcol.alpha || (psprite_transparency_type(sprite) == transparency_type_alphachannel);
domask = psprite_hasmask (sprite);
/*nx = (myrnd () >> 24) % sprayradius;
ny = (myrnd () >> 23) % sprayradius;*/
visdelay_begin ();
for (i = 0; i < adjusted_density; i++)
{ int r, nx, ny;
double theta;
/*nx = myrnd ()%sprayradius;
ny = myrnd ()%sprayradius;*/
/*nx = (myrnd () >> 24) % sprayradius;
ny = (myrnd () >> 23) % sprayradius;*/
r = myrnd ()%sprayradius;
theta = fmod ((double) myrnd (), 2*3.1415926);
/*nx = myrnd ()%sprayradius;
ny = myrnd ()%sprayradius;*/
nx = x + (int) (r*cos (theta))/pxs;
ny = y + (int) (r*sin (theta))/pys;
r = myrnd ()%sprayradius;
theta = fmod ((double) myrnd (), 2*3.1415926);
if (dopix)
{ sprite_colour newcolour = colour;
nx = x + (int) (r*cos (theta))/pxs;
ny = y + (int) (r*sin (theta))/pys;
MUNGE_PIXEL (nx, ny, &newcolour, &gcol, sarea, &sid, sprite)
ftracef2 ("sprite_writepixel (GCOL 0x%X, TINT 0x%X)\n",
newcolour.colour, newcolour.tint);
sprite_writepixel (sarea, &sid, nx, ny, &newcolour);
}
if (dopix)
{ sprite_colour newcolour = colour;
if (domask)
sprite_writemask (sarea, &sid, nx, ny, &mask);
}
visdelay_end ();
MUNGE_PIXEL (nx, ny, &newcolour, &gcol, sarea, &sid, sprite)
ftracef2 ("sprite_writepixel (GCOL 0x%X, TINT 0x%X)\n",
newcolour.colour, newcolour.tint);
sprite_writepixel (sarea, &sid, nx, ny, &newcolour);
}
if (domask)
sprite_writemask (sarea, &sid, nx, ny, &mask);
}
visdelay_end ();
redraw_area.x0=tools_pixel_to_point_x(&window->data->sprite, x) - sprayradius;
redraw_area.y0=tools_pixel_to_point_y(&window->data->sprite, y) - sprayradius;
redraw_area.x1=tools_pixel_to_point_x(&window->data->sprite, x+1) + sprayradius + 1;
redraw_area.y1=tools_pixel_to_point_y(&window->data->sprite, y+1) + sprayradius + 1;
sprwindow_redisplay (sprite, &redraw_area);
redraw_area.x0=tools_pixel_to_point_x(&window->data->sprite, x) - sprayradius;
redraw_area.y0=tools_pixel_to_point_y(&window->data->sprite, y) - sprayradius;
redraw_area.x1=tools_pixel_to_point_x(&window->data->sprite, x+1) + sprayradius + 1;
redraw_area.y1=tools_pixel_to_point_y(&window->data->sprite, y+1) + sprayradius + 1;
sprwindow_redisplay (sprite, &redraw_area);
}
}
}
......@@ -2273,7 +2419,11 @@ static void spraycanpaint_null (main_window *window, wimp_mousestr *mpos)
{ ftracef0 ("spraycanpaint_null\n");
if (mpos->bbits == 0) /*if the mouse button is now up, stop tracking*/
{
sprwindow_release_idle_events (window->data->sprite.sprite);
/*Reset spray timer*/
spraytime = 0;
}
else
spraycanpaint_splot (window, mpos);
}
......
......@@ -53,7 +53,7 @@ typedef struct Block_Header
int size; /*size excluding this header */
char *file; /*where first created */
int line; /*where first created */
int guard; /*an unlikely value */
unsigned int guard; /*an unlikely value */
}
Block_Header;
......
......@@ -45,7 +45,7 @@
typedef struct Block *Block;
struct Block
{ int guard;
{ unsigned int guard;
Block next;
Block prev;
int size;
......@@ -58,7 +58,7 @@ struct Block
#define BLOCK(N) \
struct \
{ int guard; \
{ unsigned int guard; \
Block next; \
Block prev; \
int size; \
......
......@@ -175,7 +175,9 @@
#define d_Create_Colours_4 9
#define d_Create_Colours_16 10
#define d_Create_Colours_256 11
#define d_Create_Colours_4k 33
#define d_Create_Colours_32k 12
#define d_Create_Colours_64k 32
#define d_Create_Colours_16M 13
#define d_Create_Mode_LabelL 6
#define d_Create_Mode 30
......
......@@ -69,4 +69,6 @@ extern void menus_sprite_new (main_window *, BOOL);
extern int menus_sprite_exists (sprite_area *, char *);
extern void menus_showmag (void *);
#endif
......@@ -25,6 +25,8 @@ extern main_template sprwindow_template;
extern void sprwindow_new (main_sprite *);
extern void sprwindow_delete (main_window *);
extern void sprwindow_set_work_extent(main_window *, BOOL);
extern void sprwindow_scroll (main_window *window, int scrollx, int scrolly);
extern void sprwindow_stop_scroll (void);
extern void sprwindow_swap_output_to_sprite (main_sprite *);
extern void sprwindow_remove_wastage (main_sprite *);
extern int sprwindow_swap_output_to_mask (main_sprite *, int);
......
......@@ -89,6 +89,9 @@ typedef enum
extern void tools_mouse_to_pixel (main_window *, wimp_mousestr *,
int *, int *);
extern void tools_mouse_to_pixel_overflow (main_window *, wimp_mousestr *,
int *, int *, int *, int *);
extern void tools_remove_brush (void);
extern void tools_replace_brush (void);
......