2021-12-27 20:14:31 +01:00
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
// Anti-Grain Geometry - Version 2.4
|
|
|
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
|
|
|
//
|
|
|
|
// Permission to copy, use, modify, sell and distribute this software
|
|
|
|
// is granted provided this copyright notice appears in all copies.
|
|
|
|
// This software is provided "as is" without express or implied
|
|
|
|
// warranty, and with no claim as to its suitability for any purpose.
|
|
|
|
//
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
// Contact: mcseem@antigrain.com
|
|
|
|
// mcseemagg@yahoo.com
|
|
|
|
// http://www.antigrain.com
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// class platform_support
|
|
|
|
//
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
|
2021-12-27 21:08:55 +01:00
|
|
|
#define __USE_OLD_TIMEVAL__
|
|
|
|
|
2021-12-27 20:14:31 +01:00
|
|
|
#include "platform/agg_platform_support.h"
|
|
|
|
#include "util/agg_color_conv_rgb8.h"
|
|
|
|
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <cstring>
|
|
|
|
|
|
|
|
#include <classes/requester.h>
|
|
|
|
#include <classes/window.h>
|
|
|
|
#include <datatypes/pictureclass.h>
|
|
|
|
#include <proto/exec.h>
|
|
|
|
#include <proto/datatypes.h>
|
|
|
|
#include <proto/dos.h>
|
|
|
|
#include <proto/graphics.h>
|
|
|
|
#include <proto/intuition.h>
|
|
|
|
#include <proto/keymap.h>
|
|
|
|
#include <proto/utility.h>
|
|
|
|
|
|
|
|
Library* DataTypesBase = 0;
|
|
|
|
Library* GraphicsBase = 0;
|
|
|
|
Library* IntuitionBase = 0;
|
|
|
|
Library* KeymapBase = 0;
|
|
|
|
|
|
|
|
DataTypesIFace* IDataTypes = 0;
|
|
|
|
GraphicsIFace* IGraphics = 0;
|
|
|
|
IntuitionIFace* IIntuition = 0;
|
|
|
|
KeymapIFace* IKeymap = 0;
|
|
|
|
|
|
|
|
Class* RequesterClass = 0;
|
|
|
|
Class* WindowClass = 0;
|
|
|
|
|
2021-12-27 22:23:58 +01:00
|
|
|
struct RenderInfo {
|
|
|
|
APTR Memory;
|
|
|
|
UWORD BytesPerRow;
|
|
|
|
};
|
2021-12-27 20:14:31 +01:00
|
|
|
|
|
|
|
namespace agg
|
|
|
|
{
|
|
|
|
void handle_idcmp(Hook* hook, APTR win, IntuiMessage* msg);
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
class platform_specific
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
platform_specific(platform_support& support, pix_format_e format,
|
|
|
|
bool flip_y);
|
|
|
|
~platform_specific();
|
|
|
|
bool handle_input();
|
|
|
|
bool load_img(const char* file, unsigned idx, rendering_buffer* rbuf);
|
|
|
|
bool create_img(unsigned idx, rendering_buffer* rbuf, unsigned width,
|
|
|
|
unsigned height);
|
|
|
|
bool make_bitmap();
|
|
|
|
public:
|
|
|
|
platform_support& m_support;
|
2021-12-27 22:23:58 +01:00
|
|
|
enPixelFormat m_ftype;
|
2021-12-27 20:14:31 +01:00
|
|
|
pix_format_e m_format;
|
|
|
|
unsigned m_bpp;
|
|
|
|
BitMap* m_bitmap;
|
|
|
|
bool m_flip_y;
|
|
|
|
uint16 m_width;
|
|
|
|
uint16 m_height;
|
2021-12-27 21:08:55 +01:00
|
|
|
Object* m_window_obj;
|
2021-12-27 20:14:31 +01:00
|
|
|
Window* m_window;
|
|
|
|
Hook* m_idcmp_hook;
|
|
|
|
unsigned m_input_flags;
|
|
|
|
bool m_dragging;
|
|
|
|
double m_start_time;
|
|
|
|
uint16 m_last_key;
|
|
|
|
BitMap* m_img_bitmaps[platform_support::max_images];
|
|
|
|
};
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
platform_specific::platform_specific(platform_support& support,
|
|
|
|
pix_format_e format, bool flip_y) :
|
|
|
|
m_support(support),
|
2021-12-27 22:23:58 +01:00
|
|
|
m_ftype(PIXF_NONE),
|
2021-12-27 20:14:31 +01:00
|
|
|
m_format(format),
|
|
|
|
m_bpp(0),
|
|
|
|
m_bitmap(0),
|
|
|
|
m_flip_y(flip_y),
|
|
|
|
m_width(0),
|
|
|
|
m_height(0),
|
|
|
|
m_window_obj(0),
|
|
|
|
m_window(0),
|
|
|
|
m_idcmp_hook(0),
|
|
|
|
m_input_flags(0),
|
|
|
|
m_dragging(false),
|
|
|
|
m_start_time(0.0),
|
|
|
|
m_last_key(0)
|
|
|
|
{
|
|
|
|
switch ( format )
|
|
|
|
{
|
|
|
|
case pix_format_gray8:
|
|
|
|
// Not supported.
|
|
|
|
break;
|
|
|
|
case pix_format_rgb555:
|
2021-12-27 22:23:58 +01:00
|
|
|
m_ftype = PIXF_R5G5B5;
|
2021-12-27 20:14:31 +01:00
|
|
|
m_bpp = 15;
|
|
|
|
break;
|
|
|
|
case pix_format_rgb565:
|
2021-12-27 22:23:58 +01:00
|
|
|
m_ftype = PIXF_R5G6B5;
|
2021-12-27 20:14:31 +01:00
|
|
|
m_bpp = 16;
|
|
|
|
break;
|
|
|
|
case pix_format_rgb24:
|
2021-12-27 22:23:58 +01:00
|
|
|
m_ftype = PIXF_R8G8B8;
|
2021-12-27 20:14:31 +01:00
|
|
|
m_bpp = 24;
|
|
|
|
break;
|
|
|
|
case pix_format_bgr24:
|
2021-12-27 22:23:58 +01:00
|
|
|
m_ftype = PIXF_B8G8R8;
|
2021-12-27 20:14:31 +01:00
|
|
|
m_bpp = 24;
|
|
|
|
break;
|
|
|
|
case pix_format_bgra32:
|
2021-12-27 22:23:58 +01:00
|
|
|
m_ftype = PIXF_B8G8R8A8;
|
2021-12-27 20:14:31 +01:00
|
|
|
m_bpp = 32;
|
|
|
|
break;
|
|
|
|
case pix_format_abgr32:
|
2021-12-27 22:23:58 +01:00
|
|
|
m_ftype = PIXF_A8B8G8R8;
|
2021-12-27 20:14:31 +01:00
|
|
|
m_bpp = 32;
|
|
|
|
break;
|
|
|
|
case pix_format_argb32:
|
2021-12-27 22:23:58 +01:00
|
|
|
m_ftype = PIXF_A8R8G8B8;
|
2021-12-27 20:14:31 +01:00
|
|
|
m_bpp = 32;
|
|
|
|
break;
|
|
|
|
case pix_format_rgba32:
|
2021-12-27 22:23:58 +01:00
|
|
|
m_ftype = PIXF_R8G8B8A8;
|
2021-12-27 20:14:31 +01:00
|
|
|
m_bpp = 32;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
for ( unsigned i = 0; i < platform_support::max_images; ++i )
|
|
|
|
{
|
|
|
|
m_img_bitmaps[i] = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
platform_specific::~platform_specific()
|
|
|
|
{
|
|
|
|
IIntuition->DisposeObject(m_window_obj);
|
2021-12-27 21:08:55 +01:00
|
|
|
|
|
|
|
IGraphics->FreeBitMap(m_bitmap);
|
2021-12-27 20:14:31 +01:00
|
|
|
|
|
|
|
for ( unsigned i = 0; i < platform_support::max_images; ++i )
|
|
|
|
{
|
2021-12-27 21:08:55 +01:00
|
|
|
IGraphics->FreeBitMap(m_img_bitmaps[i]);
|
2021-12-27 20:14:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if ( m_idcmp_hook != 0 )
|
|
|
|
{
|
|
|
|
IExec->FreeSysObject(ASOT_HOOK, m_idcmp_hook);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
bool platform_specific::handle_input()
|
|
|
|
{
|
|
|
|
int16 code = 0;
|
|
|
|
uint32 result = 0;
|
2021-12-27 21:08:55 +01:00
|
|
|
Object* obj = m_window_obj;
|
2021-12-27 20:14:31 +01:00
|
|
|
|
|
|
|
while ( (result = IIntuition->IDoMethod(obj, WM_HANDLEINPUT,
|
|
|
|
&code)) != WMHI_LASTMSG )
|
|
|
|
{
|
|
|
|
switch ( result & WMHI_CLASSMASK )
|
|
|
|
{
|
|
|
|
case WMHI_CLOSEWINDOW:
|
|
|
|
return true;
|
|
|
|
break;
|
|
|
|
case WMHI_INTUITICK:
|
|
|
|
if ( !m_support.wait_mode() )
|
|
|
|
{
|
|
|
|
m_support.on_idle();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case WMHI_NEWSIZE:
|
|
|
|
if ( make_bitmap() )
|
|
|
|
{
|
|
|
|
m_support.trans_affine_resizing(m_width, m_height);
|
|
|
|
m_support.on_resize(m_width, m_height);
|
|
|
|
m_support.force_redraw();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
bool platform_specific::load_img(const char* file, unsigned idx,
|
|
|
|
rendering_buffer* rbuf)
|
|
|
|
{
|
|
|
|
if ( m_img_bitmaps[idx] != 0 )
|
|
|
|
{
|
2021-12-27 21:08:55 +01:00
|
|
|
IGraphics->FreeBitMap(m_img_bitmaps[idx]);
|
2021-12-27 20:14:31 +01:00
|
|
|
m_img_bitmaps[idx] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool result = false;
|
|
|
|
|
|
|
|
Object* picture = IDataTypes->NewDTObject(const_cast<STRPTR>(file),
|
|
|
|
DTA_GroupID, GID_PICTURE,
|
|
|
|
PDTA_DestMode, PMODE_V43,
|
|
|
|
PDTA_Remap, FALSE,
|
|
|
|
TAG_END);
|
|
|
|
if ( picture != 0 )
|
|
|
|
{
|
|
|
|
gpLayout layout;
|
|
|
|
layout.MethodID = DTM_PROCLAYOUT;
|
|
|
|
layout.gpl_GInfo = 0;
|
|
|
|
layout.gpl_Initial = 1;
|
|
|
|
ULONG loaded = IDataTypes->DoDTMethodA(picture, 0, 0,
|
|
|
|
reinterpret_cast<Msg>(&layout));
|
|
|
|
if ( loaded != 0 )
|
|
|
|
{
|
|
|
|
BitMap* src_bitmap = 0;
|
|
|
|
IDataTypes->GetDTAttrs(picture,
|
|
|
|
PDTA_ClassBitMap, &src_bitmap,
|
|
|
|
TAG_END);
|
|
|
|
|
|
|
|
bool supported = false;
|
|
|
|
|
2021-12-27 22:23:58 +01:00
|
|
|
enPixelFormat ftype = static_cast<enPixelFormat>(IGraphics->GetBitMapAttr(
|
2021-12-27 21:08:55 +01:00
|
|
|
src_bitmap, BMA_PIXELFORMAT));
|
2021-12-27 20:14:31 +01:00
|
|
|
|
|
|
|
switch ( ftype )
|
|
|
|
{
|
2021-12-27 22:23:58 +01:00
|
|
|
case PIXF_R8G8B8:
|
2021-12-27 20:14:31 +01:00
|
|
|
supported = true;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
m_support.message("File uses unsupported graphics mode.");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( supported ) {
|
2021-12-27 21:08:55 +01:00
|
|
|
uint32 width = IGraphics->GetBitMapAttr(src_bitmap,
|
|
|
|
BMA_WIDTH);
|
|
|
|
uint32 height = IGraphics->GetBitMapAttr(src_bitmap,
|
|
|
|
BMA_HEIGHT);
|
|
|
|
|
|
|
|
m_img_bitmaps[idx] = IGraphics->AllocBitMapTags(width, height, m_bpp,
|
|
|
|
BMATags_UserPrivate, TRUE,
|
|
|
|
BMATags_PixelFormat, m_ftype,
|
|
|
|
TAG_DONE);
|
2021-12-27 20:14:31 +01:00
|
|
|
|
|
|
|
if ( m_img_bitmaps[idx] != 0 )
|
|
|
|
{
|
|
|
|
int8u* buf = reinterpret_cast<int8u*>(
|
2021-12-27 21:08:55 +01:00
|
|
|
IGraphics->GetBitMapAttr(m_img_bitmaps[idx],
|
|
|
|
BMA_BASEADDRESS));
|
|
|
|
int bpr = IGraphics->GetBitMapAttr(m_img_bitmaps[idx],
|
|
|
|
BMA_BYTESPERROW);
|
|
|
|
|
2021-12-27 20:14:31 +01:00
|
|
|
int stride = (m_flip_y) ? -bpr : bpr;
|
|
|
|
rbuf->attach(buf, width, height, stride);
|
|
|
|
|
|
|
|
// P96 sets the alpha to zero so it can't be used to
|
|
|
|
// color convert true color modes.
|
|
|
|
if ( m_bpp == 32 )
|
|
|
|
{
|
|
|
|
RenderInfo ri;
|
2021-12-27 21:08:55 +01:00
|
|
|
APTR lock = IGraphics->LockBitMapTags(src_bitmap,
|
|
|
|
LBM_BaseAddress, reinterpret_cast<uint8*>(&ri),
|
|
|
|
TAG_DONE);
|
2021-12-27 20:14:31 +01:00
|
|
|
|
|
|
|
rendering_buffer rbuf_src;
|
|
|
|
rbuf_src.attach(
|
|
|
|
reinterpret_cast<int8u*>(ri.Memory),
|
|
|
|
width, height, (m_flip_y) ?
|
|
|
|
-ri.BytesPerRow : ri.BytesPerRow);
|
|
|
|
|
|
|
|
switch ( m_format )
|
|
|
|
{
|
|
|
|
case pix_format_bgra32:
|
|
|
|
color_conv(rbuf, &rbuf_src,
|
|
|
|
color_conv_rgb24_to_bgra32());
|
|
|
|
break;
|
|
|
|
case pix_format_abgr32:
|
|
|
|
color_conv(rbuf, &rbuf_src,
|
|
|
|
color_conv_rgb24_to_abgr32());
|
|
|
|
break;
|
|
|
|
case pix_format_argb32:
|
|
|
|
color_conv(rbuf, &rbuf_src,
|
|
|
|
color_conv_rgb24_to_argb32());
|
|
|
|
break;
|
|
|
|
case pix_format_rgba32:
|
|
|
|
color_conv(rbuf, &rbuf_src,
|
|
|
|
color_conv_rgb24_to_rgba32());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2021-12-27 21:08:55 +01:00
|
|
|
IGraphics->UnlockBitMap(lock);
|
2021-12-27 20:14:31 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
IGraphics->BltBitMap(src_bitmap, 0, 0,
|
|
|
|
m_img_bitmaps[idx], 0, 0, width, height,
|
2021-12-27 21:08:55 +01:00
|
|
|
MINTERM_ABC|MINTERM_ABNC, 0xFF, 0);
|
2021-12-27 20:14:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
result = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
IGraphics->WaitBlit();
|
|
|
|
IDataTypes->DisposeDTObject(picture);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
bool platform_specific::create_img(unsigned idx, rendering_buffer* rbuf,
|
|
|
|
unsigned width, unsigned height)
|
|
|
|
{
|
|
|
|
if ( m_img_bitmaps[idx] != 0 )
|
|
|
|
{
|
2021-12-27 21:08:55 +01:00
|
|
|
IGraphics->FreeBitMap(m_img_bitmaps[idx]);
|
2021-12-27 20:14:31 +01:00
|
|
|
m_img_bitmaps[idx] = 0;
|
|
|
|
}
|
|
|
|
|
2021-12-27 21:08:55 +01:00
|
|
|
m_img_bitmaps[idx] = IGraphics->AllocBitMapTags(width, height, m_bpp,
|
|
|
|
BMATags_UserPrivate, TRUE,
|
|
|
|
BMATags_Friend, m_bitmap,
|
|
|
|
BMATags_PixelFormat, m_ftype,
|
|
|
|
TAG_DONE);
|
|
|
|
|
2021-12-27 20:14:31 +01:00
|
|
|
if ( m_img_bitmaps[idx] != 0 )
|
|
|
|
{
|
|
|
|
int8u* buf = reinterpret_cast<int8u*>(
|
2021-12-27 21:08:55 +01:00
|
|
|
IGraphics->GetBitMapAttr(m_img_bitmaps[idx],
|
|
|
|
BMA_BASEADDRESS));
|
|
|
|
int bpr = IGraphics->GetBitMapAttr(m_img_bitmaps[idx],
|
|
|
|
BMA_BYTESPERROW);
|
|
|
|
|
2021-12-27 20:14:31 +01:00
|
|
|
int stride = (m_flip_y) ? -bpr : bpr;
|
|
|
|
|
|
|
|
rbuf->attach(buf, width, height, stride);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
bool platform_specific::make_bitmap()
|
|
|
|
{
|
|
|
|
uint32 width = 0;
|
|
|
|
uint32 height = 0;
|
|
|
|
IIntuition->GetWindowAttrs(m_window,
|
|
|
|
WA_InnerWidth, &width,
|
|
|
|
WA_InnerHeight, &height,
|
|
|
|
TAG_END);
|
|
|
|
|
2021-12-27 21:08:55 +01:00
|
|
|
BitMap* bm = IGraphics->AllocBitMapTags(width, height, m_bpp,
|
|
|
|
BMATags_UserPrivate, TRUE,
|
|
|
|
BMATags_Clear, TRUE,
|
|
|
|
BMATags_PixelFormat, m_ftype,
|
|
|
|
TAG_DONE);
|
|
|
|
|
2021-12-27 20:14:31 +01:00
|
|
|
if ( bm == 0 )
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
int8u* buf = reinterpret_cast<int8u*>(
|
2021-12-27 21:08:55 +01:00
|
|
|
IGraphics->GetBitMapAttr(bm, BMA_BASEADDRESS));
|
|
|
|
int bpr = IGraphics->GetBitMapAttr(bm, BMA_BYTESPERROW);
|
|
|
|
|
2021-12-27 20:14:31 +01:00
|
|
|
int stride = (m_flip_y) ? -bpr : bpr;
|
|
|
|
|
|
|
|
m_support.rbuf_window().attach(buf, width, height, stride);
|
|
|
|
|
|
|
|
if ( m_bitmap != 0 )
|
|
|
|
{
|
2021-12-27 21:08:55 +01:00
|
|
|
IGraphics->FreeBitMap(m_bitmap);
|
2021-12-27 20:14:31 +01:00
|
|
|
m_bitmap = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_bitmap = bm;
|
|
|
|
m_width = width;
|
|
|
|
m_height = height;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
platform_support::platform_support(pix_format_e format, bool flip_y) :
|
|
|
|
m_specific(new platform_specific(*this, format, flip_y)),
|
|
|
|
m_format(format),
|
|
|
|
m_bpp(m_specific->m_bpp),
|
|
|
|
m_window_flags(0),
|
|
|
|
m_wait_mode(true),
|
|
|
|
m_flip_y(flip_y),
|
|
|
|
m_initial_width(10),
|
|
|
|
m_initial_height(10)
|
|
|
|
{
|
|
|
|
std::strncpy(m_caption, "Anti-Grain Geometry", 256);
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
platform_support::~platform_support()
|
|
|
|
{
|
|
|
|
delete m_specific;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
void platform_support::caption(const char* cap)
|
|
|
|
{
|
|
|
|
std::strncpy(m_caption, cap, 256);
|
|
|
|
if ( m_specific->m_window != 0 )
|
|
|
|
{
|
|
|
|
const char* ignore = reinterpret_cast<const char*>(-1);
|
|
|
|
IIntuition->SetWindowAttr(m_specific->m_window,
|
|
|
|
WA_Title, m_caption, sizeof(char*));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
void platform_support::start_timer()
|
|
|
|
{
|
|
|
|
timeval tv;
|
|
|
|
gettimeofday(&tv, 0);
|
|
|
|
m_specific->m_start_time = tv.tv_secs + tv.tv_micro/1e6;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
double platform_support::elapsed_time() const
|
|
|
|
{
|
|
|
|
timeval tv;
|
|
|
|
gettimeofday(&tv, 0);
|
|
|
|
double end_time = tv.tv_secs + tv.tv_micro/1e6;
|
|
|
|
|
|
|
|
double elasped_seconds = end_time - m_specific->m_start_time;
|
|
|
|
double elasped_millis = elasped_seconds*1e3;
|
|
|
|
|
|
|
|
return elasped_millis;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
void* platform_support::raw_display_handler()
|
|
|
|
{
|
|
|
|
return 0; // Not available.
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
void platform_support::message(const char* msg)
|
|
|
|
{
|
|
|
|
APTR req = IIntuition->NewObject(RequesterClass, 0,
|
|
|
|
REQ_TitleText, "Anti-Grain Geometry",
|
|
|
|
REQ_Image, REQIMAGE_INFO,
|
|
|
|
REQ_BodyText, msg,
|
|
|
|
REQ_GadgetText, "_Ok",
|
|
|
|
TAG_END);
|
|
|
|
if ( req == 0 )
|
|
|
|
{
|
|
|
|
IDOS->Printf("Message: %s\n", msg);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
orRequest reqmsg;
|
|
|
|
reqmsg.MethodID = RM_OPENREQ;
|
|
|
|
reqmsg.or_Attrs = 0;
|
|
|
|
reqmsg.or_Window = m_specific->m_window;
|
|
|
|
reqmsg.or_Screen = 0;
|
|
|
|
|
|
|
|
IIntuition->IDoMethodA(reinterpret_cast<Object*>(req),
|
|
|
|
reinterpret_cast<Msg>(&reqmsg));
|
2021-12-27 21:08:55 +01:00
|
|
|
IIntuition->DisposeObject(reinterpret_cast<Object*>(req));
|
2021-12-27 20:14:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
bool platform_support::init(unsigned width, unsigned height,
|
|
|
|
unsigned flags)
|
|
|
|
{
|
2021-12-27 22:23:58 +01:00
|
|
|
if( m_specific->m_ftype == PIXF_NONE )
|
2021-12-27 20:14:31 +01:00
|
|
|
{
|
|
|
|
message("Unsupported mode requested.");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_window_flags = flags;
|
|
|
|
|
|
|
|
m_specific->m_idcmp_hook = reinterpret_cast<Hook*>(
|
|
|
|
IExec->AllocSysObjectTags(ASOT_HOOK,
|
|
|
|
ASOHOOK_Entry, handle_idcmp,
|
|
|
|
ASOHOOK_Data, this,
|
|
|
|
TAG_END));
|
|
|
|
if ( m_specific->m_idcmp_hook == 0 )
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_specific->m_window_obj = IIntuition->NewObject(WindowClass, 0,
|
|
|
|
WA_Title, m_caption,
|
|
|
|
WA_AutoAdjustDClip, TRUE,
|
|
|
|
WA_InnerWidth, width,
|
|
|
|
WA_InnerHeight, height,
|
|
|
|
WA_Activate, TRUE,
|
|
|
|
WA_SmartRefresh, TRUE,
|
|
|
|
WA_NoCareRefresh, TRUE,
|
|
|
|
WA_CloseGadget, TRUE,
|
|
|
|
WA_DepthGadget, TRUE,
|
|
|
|
WA_SizeGadget, (flags & agg::window_resize) ? TRUE : FALSE,
|
|
|
|
WA_DragBar, TRUE,
|
|
|
|
WA_AutoAdjust, TRUE,
|
|
|
|
WA_ReportMouse, TRUE,
|
|
|
|
WA_RMBTrap, TRUE,
|
|
|
|
WA_MouseQueue, 1,
|
|
|
|
WA_IDCMP,
|
|
|
|
IDCMP_NEWSIZE |
|
|
|
|
IDCMP_MOUSEBUTTONS |
|
|
|
|
IDCMP_MOUSEMOVE |
|
|
|
|
IDCMP_RAWKEY |
|
|
|
|
IDCMP_INTUITICKS,
|
|
|
|
WINDOW_IDCMPHook, m_specific->m_idcmp_hook,
|
|
|
|
WINDOW_IDCMPHookBits,
|
|
|
|
IDCMP_MOUSEBUTTONS |
|
|
|
|
IDCMP_MOUSEMOVE |
|
|
|
|
IDCMP_RAWKEY,
|
|
|
|
TAG_END);
|
|
|
|
if ( m_specific->m_window_obj == 0 )
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
Object* obj = reinterpret_cast<Object*>(m_specific->m_window_obj);
|
|
|
|
m_specific->m_window =
|
|
|
|
reinterpret_cast<Window*>(IIntuition->IDoMethod(obj, WM_OPEN));
|
|
|
|
if ( m_specific->m_window == 0 )
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-12-27 22:23:58 +01:00
|
|
|
enPixelFormat ftype = static_cast<enPixelFormat>(IGraphics->GetBitMapAttr(
|
2021-12-27 21:08:55 +01:00
|
|
|
m_specific->m_window->RPort->BitMap, BMA_PIXELFORMAT));
|
|
|
|
|
2021-12-27 20:14:31 +01:00
|
|
|
switch ( ftype )
|
|
|
|
{
|
2021-12-27 22:23:58 +01:00
|
|
|
case PIXF_A8R8G8B8:
|
|
|
|
case PIXF_B8G8R8A8:
|
|
|
|
case PIXF_R5G6B5PC:
|
2021-12-27 20:14:31 +01:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
message("Unsupported screen mode.\n");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !m_specific->make_bitmap() )
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_initial_width = width;
|
|
|
|
m_initial_height = height;
|
|
|
|
|
|
|
|
on_init();
|
|
|
|
on_resize(width, height);
|
|
|
|
force_redraw();
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
int platform_support::run()
|
|
|
|
{
|
|
|
|
uint32 window_mask = 0;
|
|
|
|
IIntuition->GetAttr(WINDOW_SigMask, m_specific->m_window_obj,
|
|
|
|
&window_mask);
|
|
|
|
uint32 wait_mask = window_mask | SIGBREAKF_CTRL_C;
|
|
|
|
|
|
|
|
bool done = false;
|
|
|
|
|
|
|
|
while ( !done )
|
|
|
|
{
|
|
|
|
uint32 sig_mask = IExec->Wait(wait_mask);
|
|
|
|
if ( sig_mask & SIGBREAKF_CTRL_C )
|
|
|
|
{
|
|
|
|
done = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
done = m_specific->handle_input();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
const char* platform_support::img_ext() const
|
|
|
|
{
|
|
|
|
return ".bmp";
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
const char* platform_support::full_file_name(const char* file_name)
|
|
|
|
{
|
|
|
|
return file_name;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
bool platform_support::load_img(unsigned idx, const char* file)
|
|
|
|
{
|
|
|
|
if ( idx < max_images )
|
|
|
|
{
|
|
|
|
static char fn[1024];
|
|
|
|
std::strncpy(fn, file, 1024);
|
|
|
|
int len = std::strlen(fn);
|
|
|
|
if ( len < 4 || std::strcmp(fn + len - 4, ".bmp") != 0 )
|
|
|
|
{
|
|
|
|
std::strncat(fn, ".bmp", 1024);
|
|
|
|
}
|
|
|
|
|
|
|
|
return m_specific->load_img(fn, idx, &m_rbuf_img[idx]);
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
bool platform_support::save_img(unsigned idx, const char* file)
|
|
|
|
{
|
|
|
|
message("Not supported");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
bool platform_support::create_img(unsigned idx, unsigned width,
|
|
|
|
unsigned height)
|
|
|
|
{
|
|
|
|
if ( idx < max_images )
|
|
|
|
{
|
|
|
|
if ( width == 0 )
|
|
|
|
{
|
|
|
|
width = m_specific->m_width;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( height == 0 )
|
|
|
|
{
|
|
|
|
height = m_specific->m_height;
|
|
|
|
}
|
|
|
|
|
|
|
|
return m_specific->create_img(idx, &m_rbuf_img[idx], width,
|
|
|
|
height);
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
void platform_support::force_redraw()
|
|
|
|
{
|
|
|
|
on_draw();
|
|
|
|
update_window();
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
void platform_support::update_window()
|
|
|
|
{
|
|
|
|
// Note this function does automatic color conversion.
|
|
|
|
IGraphics->BltBitMapRastPort(m_specific->m_bitmap, 0, 0,
|
|
|
|
m_specific->m_window->RPort, m_specific->m_window->BorderLeft,
|
|
|
|
m_specific->m_window->BorderTop, m_specific->m_width,
|
2021-12-27 21:08:55 +01:00
|
|
|
m_specific->m_height, MINTERM_ABC|MINTERM_ABNC);
|
2021-12-27 20:14:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
void platform_support::on_init() {}
|
|
|
|
void platform_support::on_resize(int sx, int sy) {}
|
|
|
|
void platform_support::on_idle() {}
|
|
|
|
void platform_support::on_mouse_move(int x, int y, unsigned flags) {}
|
|
|
|
void platform_support::on_mouse_button_down(int x, int y, unsigned flags) {}
|
|
|
|
void platform_support::on_mouse_button_up(int x, int y, unsigned flags) {}
|
|
|
|
void platform_support::on_key(int x, int y, unsigned key, unsigned flags) {}
|
|
|
|
void platform_support::on_ctrl_change() {}
|
|
|
|
void platform_support::on_draw() {}
|
|
|
|
void platform_support::on_post_draw(void* raw_handler) {}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
void handle_idcmp(Hook* hook, APTR obj, IntuiMessage* msg)
|
|
|
|
{
|
|
|
|
platform_support* app =
|
|
|
|
reinterpret_cast<platform_support*>(hook->h_Data);
|
|
|
|
Window* window = app->m_specific->m_window;
|
|
|
|
|
|
|
|
int16 x = msg->MouseX - window->BorderLeft;
|
|
|
|
|
|
|
|
int16 y = 0;
|
|
|
|
if ( app->flip_y() )
|
|
|
|
{
|
|
|
|
y = window->Height - window->BorderBottom - msg->MouseY;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
y = msg->MouseY - window->BorderTop;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch ( msg->Class )
|
|
|
|
{
|
|
|
|
case IDCMP_MOUSEBUTTONS:
|
|
|
|
if ( msg->Code & IECODE_UP_PREFIX )
|
|
|
|
{
|
|
|
|
if ( msg->Code == SELECTUP )
|
|
|
|
{
|
|
|
|
app->m_specific->m_input_flags = mouse_left;
|
|
|
|
app->m_specific->m_dragging = false;
|
|
|
|
}
|
|
|
|
else if ( msg->Code == MENUUP )
|
|
|
|
{
|
|
|
|
app->m_specific->m_input_flags = mouse_right;
|
|
|
|
app->m_specific->m_dragging = false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if ( app->m_ctrls.on_mouse_button_up(x, y) )
|
|
|
|
{
|
|
|
|
app->on_ctrl_change();
|
|
|
|
app->force_redraw();
|
|
|
|
}
|
|
|
|
|
|
|
|
app->on_mouse_button_up(x, y, app->m_specific->m_input_flags);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( msg->Code == SELECTDOWN )
|
|
|
|
{
|
|
|
|
app->m_specific->m_input_flags = mouse_left;
|
|
|
|
app->m_specific->m_dragging = true;
|
|
|
|
}
|
|
|
|
else if ( msg->Code == MENUDOWN )
|
|
|
|
{
|
|
|
|
app->m_specific->m_input_flags = mouse_right;
|
|
|
|
app->m_specific->m_dragging = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
app->m_ctrls.set_cur(x, y);
|
|
|
|
if ( app->m_ctrls.on_mouse_button_down(x, y) )
|
|
|
|
{
|
|
|
|
app->on_ctrl_change();
|
|
|
|
app->force_redraw();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( app->m_ctrls.in_rect(x, y) )
|
|
|
|
{
|
|
|
|
if ( app->m_ctrls.set_cur(x, y) )
|
|
|
|
{
|
|
|
|
app->on_ctrl_change();
|
|
|
|
app->force_redraw();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
app->on_mouse_button_down(x, y,
|
|
|
|
app->m_specific->m_input_flags);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case IDCMP_MOUSEMOVE:
|
|
|
|
if ( app->m_specific->m_dragging ) {
|
|
|
|
if ( app->m_ctrls.on_mouse_move(x, y,
|
|
|
|
app->m_specific->m_input_flags & mouse_left) != 0 )
|
|
|
|
{
|
|
|
|
app->on_ctrl_change();
|
|
|
|
app->force_redraw();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( !app->m_ctrls.in_rect(x, y) )
|
|
|
|
{
|
|
|
|
app->on_mouse_move(x, y,
|
|
|
|
app->m_specific->m_input_flags);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case IDCMP_RAWKEY:
|
|
|
|
{
|
|
|
|
static InputEvent ie = { 0 };
|
|
|
|
ie.ie_Class = IECLASS_RAWKEY;
|
|
|
|
ie.ie_Code = msg->Code;
|
|
|
|
ie.ie_Qualifier = msg->Qualifier;
|
|
|
|
|
|
|
|
static const unsigned BUF_SIZE = 16;
|
|
|
|
static char key_buf[BUF_SIZE];
|
|
|
|
int16 num_chars = IKeymap->MapRawKey(&ie, key_buf, BUF_SIZE, 0);
|
|
|
|
|
|
|
|
uint32 code = 0x00000000;
|
|
|
|
switch ( num_chars )
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
code = key_buf[0];
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
code = key_buf[0]<<8 | key_buf[1];
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
code = key_buf[0]<<16 | key_buf[1]<<8 | key_buf[2];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint16 key_code = 0;
|
|
|
|
|
|
|
|
if ( num_chars == 1 )
|
|
|
|
{
|
|
|
|
if ( code >= IECODE_ASCII_FIRST && code <= IECODE_ASCII_LAST )
|
|
|
|
{
|
|
|
|
key_code = code;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( key_code == 0 )
|
|
|
|
{
|
|
|
|
switch ( code )
|
|
|
|
{
|
|
|
|
case 0x00000008: key_code = key_backspace; break;
|
|
|
|
case 0x00000009: key_code = key_tab; break;
|
|
|
|
case 0x0000000D: key_code = key_return; break;
|
|
|
|
case 0x0000001B: key_code = key_escape; break;
|
|
|
|
case 0x0000007F: key_code = key_delete; break;
|
|
|
|
case 0x00009B41:
|
|
|
|
case 0x00009B54: key_code = key_up; break;
|
|
|
|
case 0x00009B42:
|
|
|
|
case 0x00009B53: key_code = key_down; break;
|
|
|
|
case 0x00009B43:
|
|
|
|
case 0x009B2040: key_code = key_right; break;
|
|
|
|
case 0x00009B44:
|
|
|
|
case 0x009B2041: key_code = key_left; break;
|
|
|
|
case 0x009B307E: key_code = key_f1; break;
|
|
|
|
case 0x009B317E: key_code = key_f2; break;
|
|
|
|
case 0x009B327E: key_code = key_f3; break;
|
|
|
|
case 0x009B337E: key_code = key_f4; break;
|
|
|
|
case 0x009B347E: key_code = key_f5; break;
|
|
|
|
case 0x009B357E: key_code = key_f6; break;
|
|
|
|
case 0x009B367E: key_code = key_f7; break;
|
|
|
|
case 0x009B377E: key_code = key_f8; break;
|
|
|
|
case 0x009B387E: key_code = key_f9; break;
|
|
|
|
case 0x009B397E: key_code = key_f10; break;
|
|
|
|
case 0x009B3F7E: key_code = key_scrollock; break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( ie.ie_Code & IECODE_UP_PREFIX )
|
|
|
|
{
|
|
|
|
if ( app->m_specific->m_last_key != 0 )
|
|
|
|
{
|
|
|
|
bool left = (key_code == key_left) ? true : false;
|
|
|
|
bool right = (key_code == key_right) ? true : false;
|
|
|
|
bool down = (key_code == key_down) ? true : false;
|
|
|
|
bool up = (key_code == key_up) ? true : false;
|
|
|
|
|
|
|
|
if ( app->m_ctrls.on_arrow_keys(left, right, down, up) )
|
|
|
|
{
|
|
|
|
app->on_ctrl_change();
|
|
|
|
app->force_redraw();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
app->on_key(x, y, app->m_specific->m_last_key, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
app->m_specific->m_last_key = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
app->m_specific->m_last_key = key_code;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
int agg_main(int argc, char* argv[]);
|
|
|
|
bool open_libs();
|
|
|
|
void close_libs();
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
bool open_libs()
|
|
|
|
{
|
|
|
|
DataTypesBase = IExec->OpenLibrary("datatypes.library", 51);
|
2021-12-27 21:08:55 +01:00
|
|
|
GraphicsBase = IExec->OpenLibrary("graphics.library", 54);
|
2021-12-27 20:14:31 +01:00
|
|
|
IntuitionBase = IExec->OpenLibrary("intuition.library", 51);
|
|
|
|
KeymapBase = IExec->OpenLibrary("keymap.library", 51);
|
|
|
|
|
|
|
|
IDataTypes = reinterpret_cast<DataTypesIFace*>(
|
|
|
|
IExec->GetInterface(DataTypesBase, "main", 1, 0));
|
|
|
|
IGraphics = reinterpret_cast<GraphicsIFace*>(
|
|
|
|
IExec->GetInterface(GraphicsBase, "main", 1, 0));
|
|
|
|
IIntuition = reinterpret_cast<IntuitionIFace*>(
|
|
|
|
IExec->GetInterface(IntuitionBase, "main", 1, 0));
|
|
|
|
IKeymap = reinterpret_cast<KeymapIFace*>(
|
|
|
|
IExec->GetInterface(KeymapBase, "main", 1, 0));
|
|
|
|
|
|
|
|
if ( IDataTypes == 0 ||
|
|
|
|
IGraphics == 0 ||
|
|
|
|
IIntuition == 0 ||
|
2021-12-27 21:08:55 +01:00
|
|
|
IKeymap == 0)
|
2021-12-27 20:14:31 +01:00
|
|
|
{
|
|
|
|
close_libs();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
void close_libs()
|
|
|
|
{
|
|
|
|
IExec->DropInterface(reinterpret_cast<Interface*>(IKeymap));
|
|
|
|
IExec->DropInterface(reinterpret_cast<Interface*>(IIntuition));
|
|
|
|
IExec->DropInterface(reinterpret_cast<Interface*>(IGraphics));
|
|
|
|
IExec->DropInterface(reinterpret_cast<Interface*>(IDataTypes));
|
|
|
|
|
|
|
|
IExec->CloseLibrary(KeymapBase);
|
|
|
|
IExec->CloseLibrary(IntuitionBase);
|
|
|
|
IExec->CloseLibrary(GraphicsBase);
|
|
|
|
IExec->CloseLibrary(DataTypesBase);
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
int main(int argc, char* argv[])
|
|
|
|
{
|
|
|
|
if ( !open_libs() ) {
|
|
|
|
IDOS->Printf("Can't open libraries.\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
ClassLibrary* requester =
|
|
|
|
IIntuition->OpenClass("requester.class", 51, &RequesterClass);
|
|
|
|
ClassLibrary* window =
|
|
|
|
IIntuition->OpenClass("window.class", 51, &WindowClass);
|
|
|
|
if ( requester == 0 || window == 0 )
|
|
|
|
{
|
|
|
|
IDOS->Printf("Can't open classes.\n");
|
|
|
|
IIntuition->CloseClass(requester);
|
|
|
|
IIntuition->CloseClass(window);
|
|
|
|
close_libs();
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int rc = agg_main(argc, argv);
|
|
|
|
|
|
|
|
IIntuition->CloseClass(window);
|
|
|
|
IIntuition->CloseClass(requester);
|
|
|
|
close_libs();
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|