Example #1
0
TEST(File, SeveralSizes)
{
  she::ScopedHandle<she::System> system(she::CreateSystem());
  // Register all possible image formats.
  FileFormatsManager::instance().registerAllFormats();
  std::vector<char> fn(256);

  for (int w=10; w<=10+503*2; w+=503) {
    for (int h=10; h<=10+503*2; h+=503) {
      //std::sprintf(&fn[0], "test_%dx%d.ase", w, h);
      std::sprintf(&fn[0], "test.ase");

      {
        UniquePtr<Document> doc(Document::createBasicDocument(IMAGE_INDEXED, w, h, 256));
        doc->setFilename(&fn[0]);

        // Random pixels
        LayerImage* layer = dynamic_cast<LayerImage*>(doc->getSprite()->getFolder()->getFirstLayer());
        ASSERT_TRUE(layer != NULL);
        Image* image = doc->getSprite()->getStock()->getImage(layer->getCel(FrameNumber(0))->getImage());
        std::srand(w*h);
        int c = std::rand()%256;
        for (int y=0; y<h; y++) {
          for (int x=0; x<w; x++) {
            image_putpixel_fast<IndexedTraits>(image, x, y, c);
            if ((std::rand()&4) == 0)
              c = std::rand()%256;
          }
        }

        save_document(doc);
      }

      {
        UniquePtr<Document> doc(load_document(&fn[0]));
        ASSERT_EQ(w, doc->getSprite()->getWidth());
        ASSERT_EQ(h, doc->getSprite()->getHeight());

        // Same random pixels (see the seed)
        LayerImage* layer = dynamic_cast<LayerImage*>(doc->getSprite()->getFolder()->getFirstLayer());
        ASSERT_TRUE(layer != NULL);
        Image* image = doc->getSprite()->getStock()->getImage(layer->getCel(FrameNumber(0))->getImage());
        std::srand(w*h);
        int c = std::rand()%256;
        for (int y=0; y<h; y++) {
          for (int x=0; x<w; x++) {
            ASSERT_EQ(c, image_getpixel_fast<IndexedTraits>(image, x, y));
            if ((std::rand()&4) == 0)
              c = std::rand()%256;
          }
        }
      }
    }
  }
}
Example #2
0
Document* Document::createBasicDocument(PixelFormat format, int width, int height, int ncolors)
{
  // Create the sprite.
  UniquePtr<Sprite> sprite(new Sprite(format, width, height, ncolors));
  sprite->setTotalFrames(FrameNumber(1));

  // Create the main image.
  int indexInStock;
  {
    UniquePtr<Image> image(Image::create(format, width, height));

    // Clear the image with mask color.
    image_clear(image, 0);

    // Add image in the sprite's stock.
    indexInStock = sprite->getStock()->addImage(image);
    image.release();            // Release the image because it is in the sprite's stock.
  }

  // Create the first transparent layer.
  {
    UniquePtr<LayerImage> layer(new LayerImage(sprite));
    layer->setName("Layer 1");

    // Create the cel.
    {
      UniquePtr<Cel> cel(new Cel(FrameNumber(0), indexInStock));
      cel->setPosition(0, 0);

      // Add the cel in the layer.
      layer->addCel(cel);
      cel.release();            // Release the cel because it is in the layer
    }

    // Add the layer in the sprite.
    sprite->getFolder()->addLayer(layer.release()); // Release the layer because it's owned by the sprite
  }

  // Create the document with the new sprite.
  UniquePtr<Document> document(new Document(sprite));
  sprite.release();             // Release the sprite because it is in the document.

  document->setFilename("Sprite");
  return document.release();    // Release the document (it does not throw) returning the raw pointer
}
Example #3
0
raster::FrameNumber calculate_next_frame(
  raster::Sprite* sprite,
  raster::FrameNumber frame,
  IDocumentSettings* docSettings,
  bool& pingPongForward)
{
  FrameNumber first = FrameNumber(0);
  FrameNumber last = sprite->getLastFrame();

  if (docSettings->getLoopAnimation()) {
    FrameNumber loopBegin, loopEnd;
    docSettings->getLoopRange(&loopBegin, &loopEnd);
    if (loopBegin < first) loopBegin = first;
    if (loopEnd > last) loopEnd = last;

    first = loopBegin;
    last = loopEnd;
  }

  switch (docSettings->getAnimationDirection()) {

    case IDocumentSettings::AniDir_Normal:
      frame = frame.next();
      if (frame > last) frame = first;
      break;

    case IDocumentSettings::AniDir_Reverse:
      frame = frame.previous();
      if (frame < first) frame = last;
      break;

    case IDocumentSettings::AniDir_PingPong:
      if (pingPongForward) {
        frame = frame.next();
        if (frame > last) {
          frame = last.previous();
          if (frame < first) frame = first;
          pingPongForward = false;
        }
      }
      else {
        frame = frame.previous();
        if (frame < first) {
          frame = first.next();
          if (frame > last) frame = last;
          pingPongForward = true;
        }
      }
      break;
  }

  return frame;
}
Example #4
0
void Sprite::setTotalFrames(FrameNumber frames)
{
  frames = MAX(FrameNumber(1), frames);
  m_frlens.resize(frames);

  if (frames > m_frames) {
    for (FrameNumber c=m_frames; c<frames; ++c)
      m_frlens[c] = m_frlens[m_frames.previous()];
  }

  m_frames = frames;
}
Example #5
0
Sprite::Sprite(PixelFormat format, int width, int height, int ncolors)
  : Object(OBJECT_SPRITE)
  , m_format(format)
  , m_width(width)
  , m_height(height)
  , m_frames(1)
{
  ASSERT(width > 0 && height > 0);

  m_frlens.push_back(100);      // First frame with 100 msecs of duration
  m_stock = new Stock(format);
  m_folder = new LayerFolder(this);

  // Generate palette
  Palette pal(FrameNumber(0), ncolors);

  switch (format) {

    // For colored images
    case IMAGE_RGB:
    case IMAGE_INDEXED:
      pal.resize(ncolors);
      break;

    // For black and white images
    case IMAGE_GRAYSCALE:
    case IMAGE_BITMAP:
      for (int c=0; c<ncolors; c++) {
        int g = 255 * c / (ncolors-1);
        g = MID(0, g, 255);
        pal.setEntry(c, rgba(g, g, g, 255));
      }
      break;
  }

  // Initial RGB map
  m_rgbMap = NULL;

  // The transparent color for indexed images is 0 by default
  m_transparentColor = 0;

  setPalette(&pal, true);
}
Example #6
0
void Document::prepareExtraCel(int x, int y, int w, int h, int opacity)
{
  ASSERT(getSprite() != NULL);

  if (!m_extraCel)
    m_extraCel = new Cel(FrameNumber(0), 0); // Ignored fields for this cell (frame, and image index)

  m_extraCel->setPosition(x, y);
  m_extraCel->setOpacity(opacity);

  if (!m_extraImage ||
      m_extraImage->getPixelFormat() != getSprite()->getPixelFormat() ||
      m_extraImage->w != w ||
      m_extraImage->h != h) {
    delete m_extraImage;                // image
    m_extraImage = Image::create(getSprite()->getPixelFormat(), w, h);
    image_clear(m_extraImage,
                m_extraImage->mask_color = 0);
  }
}
Example #7
0
#include "raster/stock.h"
#include "undo_transaction.h"
#include "undoers/add_cel.h"
#include "undoers/add_image.h"
#include "undoers/remove_cel.h"
#include "undoers/remove_image.h"
#include "undoers/replace_image.h"
#include "undoers/set_cel_frame.h"
#include "undoers/set_cel_opacity.h"
#include "undoers/set_cel_position.h"

// These variables indicate what cel to move (and the sprite's frame
// indicates where to move it).
static Layer* src_layer = NULL; // TODO warning not thread safe
static Layer* dst_layer = NULL;
static FrameNumber src_frame = FrameNumber(0);
static FrameNumber dst_frame = FrameNumber(0);

static void remove_cel(Sprite* sprite, UndoTransaction& undo, LayerImage* layer, Cel* cel);

void set_frame_to_handle(Layer* _src_layer, FrameNumber _src_frame,
                         Layer* _dst_layer, FrameNumber _dst_frame)
{
  src_layer = _src_layer;
  src_frame = _src_frame;
  dst_layer = _dst_layer;
  dst_frame = _dst_frame;
}

void move_cel(ContextWriter& writer)
{
Example #8
0
void set_black_palette()
{
  Palette* p = new Palette(FrameNumber(0), 256);
  set_current_palette(p, true);
  delete p;
}
Example #9
0
namespace app {
  
// These variables indicate what cel to move (and the sprite's frame
// indicates where to move it).
static Layer* src_layer = NULL; // TODO warning not thread safe
static Layer* dst_layer = NULL;
static FrameNumber src_frame = FrameNumber(0);
static FrameNumber dst_frame = FrameNumber(0);

static void remove_cel(Sprite* sprite, UndoTransaction& undo, LayerImage* layer, Cel* cel);

void set_frame_to_handle(Layer* _src_layer, FrameNumber _src_frame,
                         Layer* _dst_layer, FrameNumber _dst_frame)
{
  src_layer = _src_layer;
  src_frame = _src_frame;
  dst_layer = _dst_layer;
  dst_frame = _dst_frame;
}

void move_cel(ContextWriter& writer)
{
  Document* document = writer.document();
  Sprite* sprite = writer.sprite();
  Cel *src_cel, *dst_cel;

  ASSERT(src_layer != NULL);
  ASSERT(dst_layer != NULL);
  ASSERT(src_frame >= 0 && src_frame < sprite->getTotalFrames());
  ASSERT(dst_frame >= 0 && dst_frame < sprite->getTotalFrames());

  if (src_layer->isBackground()) {
    copy_cel(writer);
    return;
  }

  src_cel = static_cast<LayerImage*>(src_layer)->getCel(src_frame);
  dst_cel = static_cast<LayerImage*>(dst_layer)->getCel(dst_frame);

  UndoTransaction undo(writer.context(), "Move Cel", undo::ModifyDocument);

  /* remove the 'dst_cel' (if it exists) because it must be
     replaced with 'src_cel' */
  if ((dst_cel != NULL) && (!dst_layer->isBackground() || src_cel != NULL))
    remove_cel(sprite, undo, static_cast<LayerImage*>(dst_layer), dst_cel);

  /* move the cel in the same layer */
  if (src_cel != NULL) {
    if (src_layer == dst_layer) {
      if (undo.isEnabled())
        undo.pushUndoer(new undoers::SetCelFrame(undo.getObjects(), src_cel));

      src_cel->setFrame(dst_frame);
    }
    /* move the cel in different layers */
    else {
      if (undo.isEnabled())
        undo.pushUndoer(new undoers::RemoveCel(undo.getObjects(), src_layer, src_cel));
      static_cast<LayerImage*>(src_layer)->removeCel(src_cel);

      src_cel->setFrame(dst_frame);

      /* if we are moving a cel from a transparent layer to the
         background layer, we have to clear the background of the
         image */
      if (!src_layer->isBackground() &&
          dst_layer->isBackground()) {
        Image* src_image = sprite->getStock()->getImage(src_cel->getImage());
        Image* dst_image = crop_image(src_image,
                                      -src_cel->getX(),
                                      -src_cel->getY(),
                                      sprite->getWidth(),
                                      sprite->getHeight(), 0);

        if (undo.isEnabled()) {
          undo.pushUndoer(new undoers::ReplaceImage(undo.getObjects(),
              sprite->getStock(), src_cel->getImage()));
          undo.pushUndoer(new undoers::SetCelPosition(undo.getObjects(), src_cel));
          undo.pushUndoer(new undoers::SetCelOpacity(undo.getObjects(), src_cel));
        }

        clear_image(dst_image, app_get_color_to_clear_layer(dst_layer));
        composite_image(dst_image, src_image, src_cel->getX(), src_cel->getY(), 255, BLEND_MODE_NORMAL);

        src_cel->setPosition(0, 0);
        src_cel->setOpacity(255);

        sprite->getStock()->replaceImage(src_cel->getImage(), dst_image);
        delete src_image;
      }

      if (undo.isEnabled())
        undo.pushUndoer(new undoers::AddCel(undo.getObjects(), dst_layer, src_cel));

      static_cast<LayerImage*>(dst_layer)->addCel(src_cel);
    }
  }

  undo.commit();

  document->notifyCelMoved(src_layer, src_frame, dst_layer, dst_frame);
  set_frame_to_handle(NULL, FrameNumber(0), NULL, FrameNumber(0));
}

void copy_cel(ContextWriter& writer)
{
  Document* document = writer.document();
  Sprite* sprite = writer.sprite();
  UndoTransaction undo(writer.context(), "Move Cel", undo::ModifyDocument);
  Cel *src_cel, *dst_cel;

  ASSERT(src_layer != NULL);
  ASSERT(dst_layer != NULL);
  ASSERT(src_frame >= 0 && src_frame < sprite->getTotalFrames());
  ASSERT(dst_frame >= 0 && dst_frame < sprite->getTotalFrames());

  src_cel = static_cast<LayerImage*>(src_layer)->getCel(src_frame);
  dst_cel = static_cast<LayerImage*>(dst_layer)->getCel(dst_frame);

  // Remove the 'dst_cel' (if it exists) because it must be replaced
  // with 'src_cel'
  if ((dst_cel != NULL) && (!dst_layer->isBackground() || src_cel != NULL))
    remove_cel(sprite, undo, static_cast<LayerImage*>(dst_layer), dst_cel);

  // Move the cel in the same layer.
  if (src_cel != NULL) {
    Image *src_image = sprite->getStock()->getImage(src_cel->getImage());
    Image *dst_image;
    int image_index;
    int dst_cel_x;
    int dst_cel_y;
    int dst_cel_opacity;

    // If we are moving a cel from a transparent layer to the
    // background layer, we have to clear the background of the image.
    if (!src_layer->isBackground() &&
        dst_layer->isBackground()) {
      dst_image = crop_image(src_image,
                             -src_cel->getX(),
                             -src_cel->getY(),
                             sprite->getWidth(),
                             sprite->getHeight(), 0);

      clear_image(dst_image, app_get_color_to_clear_layer(dst_layer));
      composite_image(dst_image, src_image, src_cel->getX(), src_cel->getY(), 255, BLEND_MODE_NORMAL);

      dst_cel_x = 0;
      dst_cel_y = 0;
      dst_cel_opacity = 255;
    }
    else {
      dst_image = Image::createCopy(src_image);
      dst_cel_x = src_cel->getX();
      dst_cel_y = src_cel->getY();
      dst_cel_opacity = src_cel->getOpacity();
    }

    // Add the image in the stock
    image_index = sprite->getStock()->addImage(dst_image);
    if (undo.isEnabled())
      undo.pushUndoer(new undoers::AddImage(undo.getObjects(),
          sprite->getStock(), image_index));

    // Create the new cel
    dst_cel = new Cel(dst_frame, image_index);
    dst_cel->setPosition(dst_cel_x, dst_cel_y);
    dst_cel->setOpacity(dst_cel_opacity);

    if (undo.isEnabled())
      undo.pushUndoer(new undoers::AddCel(undo.getObjects(), dst_layer, dst_cel));

    static_cast<LayerImage*>(dst_layer)->addCel(dst_cel);
  }

  undo.commit();

  document->notifyCelCopied(src_layer, src_frame, dst_layer, dst_frame);
  set_frame_to_handle(NULL, FrameNumber(0), NULL, FrameNumber(0));
}

static void remove_cel(Sprite* sprite, UndoTransaction& undo, LayerImage *layer, Cel *cel)
{
  Image *image;
  Cel *it;
  bool used;

  if (sprite != NULL && layer->isImage() && cel != NULL) {
    /* find if the image that use the cel to remove, is used by
       another cels */
    used = false;
    for (FrameNumber frame(0); frame<sprite->getTotalFrames(); ++frame) {
      it = layer->getCel(frame);
      if (it != NULL && it != cel && it->getImage() == cel->getImage()) {
        used = true;
        break;
      }
    }

    if (!used) {
      // If the image is only used by this cel, we can remove the
      // image from the stock.
      image = sprite->getStock()->getImage(cel->getImage());

      if (undo.isEnabled())
        undo.pushUndoer(new undoers::RemoveImage(undo.getObjects(),
            sprite->getStock(), cel->getImage()));

      sprite->getStock()->removeImage(image);
      delete image;
    }

    if (undo.isEnabled()) {
      undo.pushUndoer(new undoers::RemoveCel(undo.getObjects(), layer, cel));
    }

    // Remove the cel
    layer->removeCel(cel);
    delete cel;
  }
}

} // namespace app
Example #10
0
bool FliFormat::onLoad(FileOp* fop)
{
#define SETPAL()                                                \
  do {                                                          \
      for (c=0; c<256; c++) {                                   \
        pal->setEntry(c, _rgba(cmap[c*3],                       \
                               cmap[c*3+1],                     \
                               cmap[c*3+2], 255));              \
      }                                                         \
      pal->setFrame(frpos_out);                                 \
      sprite->setPalette(pal, true);                            \
    } while (0)

  unsigned char cmap[768];
  unsigned char omap[768];
  s_fli_header fli_header;
  Image *bmp, *old, *image;
  Sprite *sprite;
  LayerImage *layer;
  Palette *pal;
  int c, w, h;
  FrameNumber frpos_in;
  FrameNumber frpos_out;
  int index = 0;
  Cel *cel;

  /* open the file to read in binary mode */
  FileHandle f(fop->filename.c_str(), "rb");

  fli_read_header(f, &fli_header);
  fseek(f, 128, SEEK_SET);

  if (fli_header.magic == NO_HEADER) {
    fop_error(fop, "The file doesn't have a FLIC header\n");
    return false;
  }

  /* size by frame */
  w = fli_header.width;
  h = fli_header.height;

  /* create the bitmaps */
  bmp = Image::create(IMAGE_INDEXED, w, h);
  old = Image::create(IMAGE_INDEXED, w, h);
  pal = new Palette(FrameNumber(0), 256);
  if (!bmp || !old || !pal) {
    fop_error(fop, "Not enough memory.\n");
    if (bmp) image_free(bmp);
    if (old) image_free(old);
    if (pal) delete pal;
    return false;
  }

  // Create the image
  sprite = new Sprite(IMAGE_INDEXED, w, h, 256);
  layer = new LayerImage(sprite);
  sprite->getFolder()->addLayer(layer);
  layer->configureAsBackground();

  // Set frames and speed
  sprite->setTotalFrames(FrameNumber(fli_header.frames));
  sprite->setDurationForAllFrames(fli_header.speed);

  /* write frame by frame */
  for (frpos_in = frpos_out = FrameNumber(0);
       frpos_in < sprite->getTotalFrames();
       ++frpos_in) {
    /* read the frame */
    fli_read_frame(f, &fli_header,
                   (unsigned char *)old->dat, omap,
                   (unsigned char *)bmp->dat, cmap);

    /* first frame, or the frames changes, or the palette changes */
    if ((frpos_in == 0) ||
        (image_count_diff(old, bmp))
#ifndef USE_LINK /* TODO this should be configurable through a check-box */
        || (memcmp(omap, cmap, 768) != 0)
#endif
        ) {
      /* the image changes? */
      if (frpos_in != 0)
        ++frpos_out;

      /* add the new frame */
      image = Image::createCopy(bmp);
      if (!image) {
        fop_error(fop, "Not enough memory\n");
        break;
      }

      index = sprite->getStock()->addImage(image);
      if (index < 0) {
        image_free(image);
        fop_error(fop, "Not enough memory\n");
        break;
      }

      cel = new Cel(frpos_out, index);
      layer->addCel(cel);

      /* first frame or the palette changes */
      if ((frpos_in == 0) || (memcmp(omap, cmap, 768) != 0))
        SETPAL();
    }
#ifdef USE_LINK
    /* the palette changes */
    else if (memcmp(omap, cmap, 768) != 0) {
      ++frpos_out;
      SETPAL();

      // Add link
      cel = new Cel(frpos_out, index);
      layer_add_cel(layer, cel);
    }
#endif
    // The palette and the image don't change: add duration to the last added frame
    else {
      sprite->setFrameDuration(frpos_out,
                               sprite->getFrameDuration(frpos_out)+fli_header.speed);
    }

    /* update the old image and color-map to the new ones to compare later */
    image_copy(old, bmp, 0, 0);
    memcpy(omap, cmap, 768);

    /* update progress */
    fop_progress(fop, (float)(frpos_in+1) / (float)(sprite->getTotalFrames()));
    if (fop_is_stop(fop))
      break;

    /* just one frame? */
    if (fop->oneframe)
      break;
  }

  // Update number of frames
  sprite->setTotalFrames(frpos_out.next());

  // Destroy the bitmaps
  image_free(bmp);
  image_free(old);
  delete pal;

  fop->document = new Document(sprite);
  return true;
}
Example #11
0
void KernelStart(char *cmd_args[], unsigned int pmem_size, UserContext *uctxt) {
	//mark the initial KernelBrk
	KernelBrk = KernelDataEnd;

	//FreeFrameCount is only used page_table.c
	FreeFrameCount = pmem_size / PAGESIZE;

	ipc_table = (ObjectNode **) malloc(sizeof(ObjectNode *) * HASH_LEN);
	if (NULL == ipc_table) {
		TracePrintf(0, "ipc_table cannot be initialized!\n");
		return;
	}
	memset(ipc_table, 0, sizeof(ObjectNode *) * HASH_LEN);

	ReadyQueue	= (Queue *) malloc(sizeof(Queue));
	DelayQueue	= (Queue *) malloc(sizeof(Queue));
	if (NULL == ReadyQueue) {
		TracePrintf(0, "ReadyQueue cannot be initialized!\n");
		return;
	}
	if (NULL == DelayQueue) {
		TracePrintf(0, "DelayQueue cannot be initialized!\n");
		return;
	}

	memset(ReadyQueue,	0, sizeof(Queue));
	memset(DelayQueue,	0, sizeof(Queue));

	u_int i;
	for (i = 0; i < NUM_TERMINALS; i++) {
		BufferQueue[i]		= (Queue *) malloc(sizeof(Queue));
		ReceiveQueue[i]		= (Queue *) malloc(sizeof(Queue));
		TransmitQueue[i]	= (Queue *) malloc(sizeof(Queue));
		if (NULL == BufferQueue[i]) {
			TracePrintf(0, "BufferQueue[%d] cannot be initialized!\n", i);
			return;
		}
		if (NULL == ReceiveQueue[i]) {
			TracePrintf(0, "ReceiveQueue[%d] cannot be initialized!\n", i);
			return;
		}
		if (NULL == TransmitQueue[i]) {
			TracePrintf(0, "TransmitQueue[%d] cannot be initialized!\n", i);
			return;
		}


		memset(BufferQueue[i], 0, sizeof(Queue));
		memset(ReceiveQueue[i], 0, sizeof(Queue));
		memset(TransmitQueue[i], 0, sizeof(Queue));
	}

	//create interrupt vector table in kernel
	void **interruptVectorTable =
			 (void **) malloc(sizeof(void *) * TRAP_VECTOR_SIZE);
	if (NULL == interruptVectorTable) {
		TracePrintf(0, "Interrupt Vector Table cannot be initialized!\n");
		return;
	}

	//fill each entry in table with pointer to correct handler
	interruptVectorTable[TRAP_KERNEL] 	= &TrapKernelHandler;
	interruptVectorTable[TRAP_CLOCK] 	= &TrapClockHandler;
	interruptVectorTable[TRAP_ILLEGAL] 	= &TrapIllegalHandler;
	interruptVectorTable[TRAP_MEMORY] 	= &TrapMemoryHandler;
	interruptVectorTable[TRAP_MATH] 	= &TrapMathHandler;
	interruptVectorTable[TRAP_TTY_RECEIVE] 	= &TrapTtyReceiveHandler;
	interruptVectorTable[TRAP_TTY_TRANSMIT]	= &TrapTtyTransmitHandler;
	interruptVectorTable[TRAP_DISK] 	= &TrapDiskHandler;
	for (i = 8; i < 16; i++) {
		interruptVectorTable[i] 	= &TrapErrorHandler;
	}	

	//point REG_VECTOR_BASE to interrupt vector table
	WriteRegister(REG_VECTOR_BASE, (u_int) interruptVectorTable);
	TracePrintf(0, "Interrupt vector table initialization completed.\n");

	//Build page table for Region 0
	KernelPageTable = (PTE *) malloc(sizeof(PTE) * MAX_PT_LEN);
	if (NULL == KernelPageTable) {
		TracePrintf(0, "KernelPageTable cannot be initialized!\n");
		return;
	}
	memset(KernelPageTable, 0, sizeof(PTE) * MAX_PT_LEN);

	TracePrintf(0, "Page tables built successfully.\n");

	//create kernel stack union
	KS = (KernelStack *) KERNEL_STACK_BASE;
	TracePrintf(0, "Kernel stack initialization completed.\n");

	//build input init process PCB
	KS->CurrentPCB = InitPCB = InitializePCB();
	if (NULL == InitPCB) {
		TracePrintf(0, "InitPCB cannot be initialized!\n");
		return;
	}

	// We enablePTE after using all the malloc in the kernel because
	// only in this way we can make sure the getFreeFrame will be called
	// and update the FreeFrameCount.
	enablePTE(0, Page(KernelDataStart), PROT_READ | PROT_EXEC);
	enablePTE(Page(KernelDataStart), Page(KernelBrk), PROT_READ | PROT_WRITE);
	enablePTE(INTERFACE, Page(KERNEL_STACK_LIMIT), PROT_READ | PROT_WRITE);

	// initialize virtual memory registers
	WriteRegister(REG_PTBR0, (u_int) KernelPageTable);
	WriteRegister(REG_PTLR0, MAX_PT_LEN);
	WriteRegister(REG_PTBR1, (u_int) KS->CurrentPCB->pagetable);
	WriteRegister(REG_PTLR1, MAX_PT_LEN);
	TracePrintf(0, "Table information loading to hardware completed.\n");

	//set up the link list to keep track of free frames
	//from KernelBrk to KERNEL_STACK_BASE
	*FrameNumber(INTERFACE) = Page(KernelBrk);
	for (i = Page(KernelBrk); i < INTERFACE - 1; i++) {
		*FrameNumber(i) = i + 1;
	}
	*FrameNumber(INTERFACE - 1) = Page(VMEM_0_LIMIT);
	for (i = Page(VMEM_0_LIMIT); i < Page(pmem_size - 1); i++) {
		*FrameNumber(i) = i + 1;
	}
	TracePrintf(0, "Free frames' linked list has been set up.\n");

	//enable virtual memory
	WriteRegister(REG_VM_ENABLE, 1);
	VM_ENABLED = 1;
	TracePrintf(0, "Virtual memory has been enabled.\n");

	TracePrintf(0, "Load input program. (Default init)\n");
	if (NULL != cmd_args[0]) {
		if (FAILURE == LoadProgram(cmd_args[0], cmd_args, InitPCB)) {
			TracePrintf(0, "Load input program failed!\n");
			return;
		}
	} else {
		char *args[] = {"init", NULL};
		if (FAILURE == LoadProgram(args[0], args, InitPCB)) {
			TracePrintf(0, "Load input program failed!\n");
			return;
		}
	}

	TracePrintf(0, "Build the Idle process.\n");
	//build kernel idle process PCB
	IdlePCB = InitializePCB();
	if (NULL == IdlePCB) {
		TracePrintf(0, "IdlePCB cannot be initialized!\n");
		return;
	}

	//sp = virtual address of top of stack
	IdlePCB->uctxt.sp  = (void *) (VMEM_1_LIMIT
				     - INITIAL_STACK_FRAME_SIZE
				     - POST_ARGV_NULL_SPACE);
	//pc = virtual address of DoIdle function
	IdlePCB->uctxt.pc  = &DoIdle;

	//enable user stack for idle process	
	IdlePCB->pagetable[MAX_PT_LEN - 1].valid = 1;
	IdlePCB->pagetable[MAX_PT_LEN - 1].prot = PROT_READ | PROT_WRITE;

	if (0 == FreeFrameCount) {
		TracePrintf(0, "No frame for Idle process pagetable!\n");
		return;
	}

	IdlePCB->pagetable[MAX_PT_LEN - 1].pfn = getFreeFrame(0);

	//use MyKCS initialize IdlePCB's KC and KS
	KernelContextSwitch(KCKSInit, (void *) IdlePCB, NULL);
	TracePrintf(0, "How many time will this line be printed?\n");

	//copy current context into hardware provided context
	*uctxt = KS->CurrentPCB->uctxt;

	TracePrintf(0, "KernelStart finished.\n");
}
Example #12
0
/* loads a COL file (Animator and Animator Pro format) */
Palette *load_col_file(const char *filename)
{
#if (MAKE_VERSION(4, 2, 1) >= MAKE_VERSION(ALLEGRO_VERSION,             \
                                           ALLEGRO_SUB_VERSION,         \
                                           ALLEGRO_WIP_VERSION))
  int size = file_size(filename);
#else
  int size = file_size_ex(filename);
#endif
  int pro = (size == 768)? false: true; /* is Animator Pro format? */
  div_t d = div(size-8, 3);
  Palette *pal = NULL;
  int c, r, g, b;
  FILE *f;

  if (!(size) || (pro && d.rem)) /* invalid format */
    return NULL;

  f = fopen(filename, "rb");
  if (!f)
    return NULL;

  /* Animator format */
  if (!pro) {
    pal = new Palette(FrameNumber(0), 256);

    for (c=0; c<256; c++) {
      r = fgetc(f);
      g = fgetc(f);
      b = fgetc(f);
      if (ferror(f))
        break;

      pal->setEntry(c, _rgba(_rgb_scale_6[MID(0, r, 63)],
                             _rgb_scale_6[MID(0, g, 63)],
                             _rgb_scale_6[MID(0, b, 63)], 255));
    }
  }
  /* Animator Pro format */
  else {
    int magic, version;

    fgetl(f);                   /* skip file size */
    magic = fgetw(f);           /* file format identifier */
    version = fgetw(f);         /* version file */

    /* unknown format */
    if (magic != PROCOL_MAGIC_NUMBER || version != 0) {
      fclose(f);
      return NULL;
    }

    pal = new Palette(FrameNumber(0), MIN(d.quot, 256));

    for (c=0; c<pal->size(); c++) {
      r = fgetc(f);
      g = fgetc(f);
      b = fgetc(f);
      if (ferror(f))
        break;

      pal->setEntry(c, _rgba(MID(0, r, 255),
                             MID(0, g, 255),
                             MID(0, b, 255), 255));
    }
  }

  fclose(f);
  return pal;
}
  void onImport()
  {
    // The user don't select a sheet yet.
    if (!m_document) {
      Alert::show("Import Sprite Sheet<<Select a sprite first.||&Close");
      return;
    }

    // The list of frames imported from the sheet
    std::vector<Image*> animation;

    try {
      Sprite* sprite = m_document->getSprite();
      FrameNumber currentFrame = m_context->getActiveLocation().frame();

      // As first step, we cut each tile and add them into "animation" list.
      for (int y=m_rect.y; y<sprite->getHeight(); y += m_rect.h) {
        for (int x=m_rect.x; x<sprite->getWidth(); x += m_rect.w) {
          base::UniquePtr<Image> resultImage(Image::create(sprite->getPixelFormat(), m_rect.w, m_rect.h));

          // Clear the image with mask color.
          image_clear(resultImage, 0);

          // Render the portion of sheet.
          sprite->render(resultImage, -x, -y, currentFrame);
          animation.push_back(resultImage);
          resultImage.release();
        }
      }

      if (animation.size() == 0) {
        Alert::show("Import Sprite Sheet"
                    "<<The specified rectangle does not create any tile."
                    "<<Select a rectangle inside the sprite region."
                    "||&OK");
        return;
      }

      // The following steps modify the sprite, so we wrap all
      // operations in a undo-transaction.
      ContextWriter writer(m_context);
      UndoTransaction undoTransaction(writer.context(), "Import Sprite Sheet", undo::ModifyDocument);
      DocumentApi api = m_document->getApi();

      // Add the layer in the sprite.
      LayerImage* resultLayer = api.newLayer(sprite);

      // Add all frames+cels to the new layer
      for (size_t i=0; i<animation.size(); ++i) {
        int indexInStock;

        // Add the image into the sprite's stock
        indexInStock = api.addImageInStock(sprite, animation[i]);
        animation[i] = NULL;

        // Create the cel.
        base::UniquePtr<Cel> resultCel(new Cel(FrameNumber(i), indexInStock));

        // Add the cel in the layer.
        api.addCel(resultLayer, resultCel);
        resultCel.release();
      }

      // Copy the list of layers (because we will modify it in the iteration).
      LayerList layers = sprite->getFolder()->getLayersList();

      // Remove all other layers
      for (LayerIterator it=layers.begin(), end=layers.end(); it!=end; ++it) {
        if (*it != resultLayer)
          api.removeLayer(*it);
      }

      // Change the number of frames
      api.setTotalFrames(sprite, FrameNumber(animation.size()));

      // Set the size of the sprite to the tile size.
      api.setSpriteSize(sprite, m_rect.w, m_rect.h);

      undoTransaction.commit();
    }
    catch (...) {
      for (size_t i=0; i<animation.size(); ++i)
        delete animation[i];
      throw;
    }

    update_screen_for_document(m_document);
    closeWindow(NULL);
  }
Example #14
0
Document* Document::duplicate(DuplicateType type) const
{
  const Sprite* sourceSprite = getSprite();
  UniquePtr<Sprite> spriteCopyPtr(new Sprite(sourceSprite->getPixelFormat(),
                                             sourceSprite->getWidth(),
                                             sourceSprite->getHeight(),
                                             sourceSprite->getPalette(FrameNumber(0))->size()));
  UniquePtr<Document> documentCopy(new Document(spriteCopyPtr));
  Sprite* spriteCopy = spriteCopyPtr.release();

  spriteCopy->setTotalFrames(sourceSprite->getTotalFrames());

  // Copy frames duration
  for (FrameNumber i(0); i < sourceSprite->getTotalFrames(); ++i)
    spriteCopy->setFrameDuration(i, sourceSprite->getFrameDuration(i));

  // Copy color palettes
  {
    PalettesList::const_iterator it = sourceSprite->getPalettes().begin();
    PalettesList::const_iterator end = sourceSprite->getPalettes().end();
    for (; it != end; ++it) {
      const Palette* pal = *it;
      spriteCopy->setPalette(pal, true);
    }
  }

  switch (type) {

    case DuplicateExactCopy:
      // Disable the undo
      documentCopy->getUndo()->setEnabled(false);

      // Copy the layer folder
      copyLayerContent(getSprite()->getFolder(), documentCopy, spriteCopy->getFolder());

      // Re-enable the undo
      documentCopy->getUndo()->setEnabled(true);
      break;

    case DuplicateWithFlattenLayers:
      {
        // Flatten layers
        ASSERT(sourceSprite->getFolder() != NULL);

        LayerImage* flatLayer = create_flatten_layer_copy
            (spriteCopy,
             sourceSprite->getFolder(),
             gfx::Rect(0, 0, sourceSprite->getWidth(), sourceSprite->getHeight()),
             FrameNumber(0), sourceSprite->getLastFrame());

        // Add and select the new flat layer
        spriteCopy->getFolder()->addLayer(flatLayer);

        // Configure the layer as background only if the original
        // sprite has a background layer.
        if (sourceSprite->getBackgroundLayer() != NULL)
          flatLayer->configureAsBackground();
      }
      break;
  }

  documentCopy->setMask(getMask());
  documentCopy->m_maskVisible = m_maskVisible;
  documentCopy->generateMaskBoundaries();

  return documentCopy.release();
}
Example #15
0
void copy_cel(ContextWriter& writer)
{
  Document* document = writer.document();
  Sprite* sprite = writer.sprite();
  UndoTransaction undo(writer.context(), "Move Cel", undo::ModifyDocument);
  Cel *src_cel, *dst_cel;

  ASSERT(src_layer != NULL);
  ASSERT(dst_layer != NULL);
  ASSERT(src_frame >= 0 && src_frame < sprite->getTotalFrames());
  ASSERT(dst_frame >= 0 && dst_frame < sprite->getTotalFrames());

  src_cel = static_cast<LayerImage*>(src_layer)->getCel(src_frame);
  dst_cel = static_cast<LayerImage*>(dst_layer)->getCel(dst_frame);

  // Remove the 'dst_cel' (if it exists) because it must be replaced
  // with 'src_cel'
  if ((dst_cel != NULL) && (!dst_layer->isBackground() || src_cel != NULL))
    remove_cel(sprite, undo, static_cast<LayerImage*>(dst_layer), dst_cel);

  // Move the cel in the same layer.
  if (src_cel != NULL) {
    Image *src_image = sprite->getStock()->getImage(src_cel->getImage());
    Image *dst_image;
    int image_index;
    int dst_cel_x;
    int dst_cel_y;
    int dst_cel_opacity;

    // If we are moving a cel from a transparent layer to the
    // background layer, we have to clear the background of the image.
    if (!src_layer->isBackground() &&
        dst_layer->isBackground()) {
      dst_image = image_crop(src_image,
                             -src_cel->getX(),
                             -src_cel->getY(),
                             sprite->getWidth(),
                             sprite->getHeight(), 0);

      image_clear(dst_image, app_get_color_to_clear_layer(dst_layer));
      image_merge(dst_image, src_image, src_cel->getX(), src_cel->getY(), 255, BLEND_MODE_NORMAL);

      dst_cel_x = 0;
      dst_cel_y = 0;
      dst_cel_opacity = 255;
    }
    else {
      dst_image = Image::createCopy(src_image);
      dst_cel_x = src_cel->getX();
      dst_cel_y = src_cel->getY();
      dst_cel_opacity = src_cel->getOpacity();
    }

    // Add the image in the stock
    image_index = sprite->getStock()->addImage(dst_image);
    if (undo.isEnabled())
      undo.pushUndoer(new undoers::AddImage(undo.getObjects(),
          sprite->getStock(), image_index));

    // Create the new cel
    dst_cel = new Cel(dst_frame, image_index);
    dst_cel->setPosition(dst_cel_x, dst_cel_y);
    dst_cel->setOpacity(dst_cel_opacity);

    if (undo.isEnabled())
      undo.pushUndoer(new undoers::AddCel(undo.getObjects(), dst_layer, dst_cel));

    static_cast<LayerImage*>(dst_layer)->addCel(dst_cel);
  }

  undo.commit();

  document->notifyCelCopied(src_layer, src_frame, dst_layer, dst_frame);
  set_frame_to_handle(NULL, FrameNumber(0), NULL, FrameNumber(0));
}
Example #16
0
void move_cel(ContextWriter& writer)
{
  Document* document = writer.document();
  Sprite* sprite = writer.sprite();
  Cel *src_cel, *dst_cel;

  ASSERT(src_layer != NULL);
  ASSERT(dst_layer != NULL);
  ASSERT(src_frame >= 0 && src_frame < sprite->getTotalFrames());
  ASSERT(dst_frame >= 0 && dst_frame < sprite->getTotalFrames());

  if (src_layer->isBackground()) {
    copy_cel(writer);
    return;
  }

  src_cel = static_cast<LayerImage*>(src_layer)->getCel(src_frame);
  dst_cel = static_cast<LayerImage*>(dst_layer)->getCel(dst_frame);

  UndoTransaction undo(writer.context(), "Move Cel", undo::ModifyDocument);

  /* remove the 'dst_cel' (if it exists) because it must be
     replaced with 'src_cel' */
  if ((dst_cel != NULL) && (!dst_layer->isBackground() || src_cel != NULL))
    remove_cel(sprite, undo, static_cast<LayerImage*>(dst_layer), dst_cel);

  /* move the cel in the same layer */
  if (src_cel != NULL) {
    if (src_layer == dst_layer) {
      if (undo.isEnabled())
        undo.pushUndoer(new undoers::SetCelFrame(undo.getObjects(), src_cel));

      src_cel->setFrame(dst_frame);
    }
    /* move the cel in different layers */
    else {
      if (undo.isEnabled())
        undo.pushUndoer(new undoers::RemoveCel(undo.getObjects(), src_layer, src_cel));
      static_cast<LayerImage*>(src_layer)->removeCel(src_cel);

      src_cel->setFrame(dst_frame);

      /* if we are moving a cel from a transparent layer to the
         background layer, we have to clear the background of the
         image */
      if (!src_layer->isBackground() &&
          dst_layer->isBackground()) {
        Image *src_image = sprite->getStock()->getImage(src_cel->getImage());
        Image *dst_image = image_crop(src_image,
                                      -src_cel->getX(),
                                      -src_cel->getY(),
                                      sprite->getWidth(),
                                      sprite->getHeight(), 0);

        if (undo.isEnabled()) {
          undo.pushUndoer(new undoers::ReplaceImage(undo.getObjects(),
              sprite->getStock(), src_cel->getImage()));
          undo.pushUndoer(new undoers::SetCelPosition(undo.getObjects(), src_cel));
          undo.pushUndoer(new undoers::SetCelOpacity(undo.getObjects(), src_cel));
        }

        image_clear(dst_image, app_get_color_to_clear_layer(dst_layer));
        image_merge(dst_image, src_image, src_cel->getX(), src_cel->getY(), 255, BLEND_MODE_NORMAL);

        src_cel->setPosition(0, 0);
        src_cel->setOpacity(255);

        sprite->getStock()->replaceImage(src_cel->getImage(), dst_image);
        image_free(src_image);
      }

      if (undo.isEnabled())
        undo.pushUndoer(new undoers::AddCel(undo.getObjects(), dst_layer, src_cel));

      static_cast<LayerImage*>(dst_layer)->addCel(src_cel);
    }
  }

  undo.commit();

  document->notifyCelMoved(src_layer, src_frame, dst_layer, dst_frame);
  set_frame_to_handle(NULL, FrameNumber(0), NULL, FrameNumber(0));
}
Example #17
0
void DocumentApi::setPixelFormat(Sprite* sprite, PixelFormat newFormat, DitheringMethod dithering_method)
{
  Image* old_image;
  Image* new_image;
  int c;

  if (sprite->getPixelFormat() == newFormat)
    return;

  // Change pixel format of the stock of images.
  DocumentUndo* undo = m_document->getUndo();
  if (undo->isEnabled())
    m_undoers->pushUndoer(new undoers::SetStockPixelFormat(getObjects(), sprite->getStock()));

  sprite->getStock()->setPixelFormat(newFormat);

  // TODO Review this, why we use the palette in frame 0?
  FrameNumber frame(0);

  // Use the rgbmap for the specified sprite
  const RgbMap* rgbmap = sprite->getRgbMap(frame);

  for (c=0; c<sprite->getStock()->size(); c++) {
    old_image = sprite->getStock()->getImage(c);
    if (!old_image)
      continue;

    new_image = quantization::convert_pixel_format
      (old_image, newFormat, dithering_method, rgbmap,
       sprite->getPalette(frame),
       sprite->getBackgroundLayer() != NULL);

    replaceStockImage(sprite, c, new_image);
  }

  // Change sprite's pixel format.
  if (undo->isEnabled())
    m_undoers->pushUndoer(new undoers::SetSpritePixelFormat(getObjects(), sprite));

  sprite->setPixelFormat(newFormat);

  // Regenerate extras
  m_document->destroyExtraCel();

  // When we are converting to grayscale color mode, we've to destroy
  // all palettes and put only one grayscaled-palette at the first
  // frame.
  if (newFormat == IMAGE_GRAYSCALE) {
    // Add undoers to revert all palette changes.
    if (undo->isEnabled()) {
      PalettesList palettes = sprite->getPalettes();
      for (PalettesList::iterator it = palettes.begin(); it != palettes.end(); ++it) {
        Palette* palette = *it;
        m_undoers->pushUndoer(new undoers::RemovePalette(
            getObjects(), sprite, palette->getFrame()));
      }

      m_undoers->pushUndoer(new undoers::AddPalette(
        getObjects(), sprite, FrameNumber(0)));
    }

    // It's a UniquePtr because setPalette'll create a copy of "graypal".
    UniquePtr<Palette> graypal(Palette::createGrayscale());

    sprite->resetPalettes();
    sprite->setPalette(graypal, true);
  }
}