summaryrefslogtreecommitdiff
path: root/src/graphic
diff options
context:
space:
mode:
Diffstat (limited to 'src/graphic')
-rw-r--r--src/graphic/graphic.cpp256
-rw-r--r--src/graphic/graphic.h50
-rw-r--r--src/graphic/super_eagle.cpp450
-rw-r--r--src/graphic/super_eagle.h44
4 files changed, 800 insertions, 0 deletions
diff --git a/src/graphic/graphic.cpp b/src/graphic/graphic.cpp
new file mode 100644
index 00000000..3a6e71a3
--- /dev/null
+++ b/src/graphic/graphic.cpp
@@ -0,0 +1,256 @@
+/**
+
+ The Mana World
+ Copyright 2004 The Mana World Development Team
+
+ This file is part of The Mana World.
+
+ The Mana World is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ any later version.
+
+ The Mana World is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with The Mana World; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ By ElvenProgrammer aka Eugenio Favalli (umperio@users.sourceforge.net)
+
+*/
+
+#include "graphic.h"
+
+#define TILESET_W 480
+#define TILESET_H 320
+
+#ifdef WIN32
+#pragma warning (disable:4312)
+#endif
+
+#include <allegro.h>
+#include "../game.h"
+#include "../map.h"
+#include "../being.h"
+#include "../Gui/chat.h"
+#include "../Gui/inventory.h"
+#include "../data/graphic/gfx_data.h"
+
+BITMAP *buffer, *double_buffer, *chat_background;
+DATAFILE *tileset;
+char page_num;
+int map_x, map_y;
+DIALOG_PLAYER *chat_player, *npc_player, *skill_player;
+char speech[255] = "";
+char npc_text[1000] = "";
+TmwInventory inventory;
+Chat chatlog("chatlog.txt", 20);
+int show_npc_dialog = 0;
+bool show_skill_dialog = false;
+
+DIALOG npc_dialog[] = {
+ /* (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) (dp2) (dp3) */
+ { tmw_dialog_proc, 300, 200, 260, 150, 0, 0, 0, 0, 0, 0, (char *)"NPC", NULL, NULL },
+ { tmw_button_proc, 508, 326, 50, 20, 255, 0, 'c', D_EXIT, 0, 0, (char *)"&Close", NULL, NULL },
+ { tmw_textbox_proc, 304, 224, 252, 100, 0, 0, 0, 0, 0, 0, npc_text, NULL, NULL },
+ { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
+};
+
+DIALOG chat_dialog[] = {
+ /* (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) (dp2) (dp3) */
+ { tmw_edit_proc, 0, 574, 592, 25, 0, 0, 'c', 0, 90, 0, speech, NULL, NULL },
+ { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
+};
+
+int get_x_offset(NODE *node) {
+ int offset = 0;
+ char direction = get_direction(node->coordinates);
+ if(node->action==WALK) {
+ if(direction==WEST || direction==EAST) {
+ offset = node->frame + 1;
+ if(offset==5)offset = 0;
+ offset *= 4;
+ if(direction==WEST) {
+ offset = -offset;
+ offset += 16;
+ } else offset -= 16;
+ }
+ }
+ return offset;
+}
+
+int get_y_offset(NODE *node) {
+ int offset = 0;
+ char direction = get_direction(node->coordinates);
+ if(node->action==WALK) {
+ if(direction==SOUTH || direction==NORTH) {
+ offset = node->frame + 1;
+ if(offset==5)offset = 0;
+ offset *= 4;
+ if(direction==NORTH) {
+ offset = -offset;
+ offset += 16;
+ } else offset -= 16;
+ }
+ }
+ return offset;
+}
+
+void init_graphic() {
+ tileset = load_datafile("./data/graphic/village.dat");
+ //if(!(gfx_capabilities & GFX_HW_VRAM_BLIT))allegro_message("Not supporting HW accelerated blit");
+ buffer = create_bitmap(SCREEN_W/2, SCREEN_H/2);
+ double_buffer = create_bitmap(SCREEN_W, SCREEN_H);
+
+ alfont_set_font_size(gui_font, 16);
+ clear_bitmap(screen);
+ chat_background = create_bitmap(592, 100);
+ clear_to_color(chat_background, makecol(0,0,0));
+
+ // Initialize gui
+ chat_player = init_dialog(chat_dialog, -1);
+ npc_player = init_dialog(npc_dialog, -1);
+ position_dialog(npc_dialog, 300, 200);
+ skill_player = init_dialog(skill_dialog, -1);
+ gui_bitmap = double_buffer;
+ alfont_text_mode(-1);
+ inventory.create(0, 0);
+}
+
+void do_graphic(void) {
+
+ map_x = (get_x(player_node->coordinates)-13)*16+get_x_offset(player_node);
+ map_y = (get_y(player_node->coordinates)-9)*16+get_y_offset(player_node);
+
+ int camera_x = map_x >> 4;
+ int camera_y = map_y >> 4;
+
+ int offset_x = map_x & 15;
+ int offset_y = map_y & 15;
+
+ sort();
+
+ for(int j=0;j<20;j++)
+ for(int i=0;i<26;i++) {
+ draw_rle_sprite(buffer, (RLE_SPRITE *)tileset[get_tile(i+camera_x, j+camera_y, 0)].dat, i*16-offset_x, j*16-offset_y);
+ if(get_tile(i+camera_x, j+camera_y, 1)!=0)draw_rle_sprite(buffer, (RLE_SPRITE *)tileset[get_tile(i+camera_x, j+camera_y, 1)].dat, i*16-offset_x, j*16-offset_y);
+ }
+
+ NODE *node = get_head();
+ NODE *old_node = NULL;
+ while(node) {
+ if((node->job>=100)&&(node->job<=110)) { // Draw a NPC
+ masked_blit((BITMAP *)graphic[NPCSET_BMP].dat, buffer, (get_direction(node->coordinates)/2+4*(node->job-100))*25, 0, (get_x(node->coordinates)-camera_x)*16-4-offset_x, (get_y(node->coordinates)-camera_y)*16-24-offset_y, 25, 40);
+ } else if(node->job<10) { // Draw a player
+
+ node->text_x = (get_x(node->coordinates)-camera_x)*16-34+get_x_offset(node)-offset_x;
+ node->text_y = (get_y(node->coordinates)-camera_y)*16-36+get_y_offset(node)-offset_y;
+ masked_blit((BITMAP *)graphic[PLAYERSET_BMP].dat, buffer, 80*(get_direction(node->coordinates)/2), 60*(node->frame+node->action), node->text_x, node->text_y, 80, 60);
+
+ if(node->emotion!=0) {
+ draw_sprite(buffer, (BITMAP *)emotions[node->emotion-1].dat, (get_x(node->coordinates)-camera_x)*16-5+get_x_offset(node)-offset_x, (get_y(node->coordinates)-camera_y)*16-45+get_y_offset(node)-offset_y);
+ node->emotion_time--;
+ if(node->emotion_time==0)
+ node->emotion = 0;
+ }
+
+ if(node->action!=STAND && node->action!=SIT) {
+ node->frame = (get_elapsed_time(node->tick_time)*4)/(node->speed);
+ if(node->frame>=4) {
+ node->frame = 0;
+ node->action = STAND;
+ node->tick_time;
+ if(node->id==player_node->id)
+ walk_status = 0;
+ }
+ }
+
+ } else if(node->job==45) { // Draw a warp
+ //rectfill(buffer, (get_x(node->coordinates)-map_x)*16-player_x-get_x_offset(node->frame, get_direction(node->coordinates)), (get_y(node->coordinates)-map_y)*16-player_y-get_y_offset(node->frame, get_direction(node->coordinates)), (get_x(node->coordinates)-map_x)*16-player_x-get_x_offset(node->frame, get_direction(node->coordinates))+16, (get_y(node->coordinates)-map_y)*16-player_y-get_y_offset(node->frame, get_direction(node->coordinates))+16, makecol(0,0,255));
+ } else { // Draw a monster
+
+ node->text_x = (get_x(node->coordinates)-camera_x)*16-20+get_x_offset(node)-offset_x;
+ node->text_y = (get_y(node->coordinates)-camera_y)*16-25+get_y_offset(node)-offset_y;
+
+ if(node->action==MONSTER_DEAD)node->frame = 0;
+ masked_blit((BITMAP *)graphic[MOBSET_BMP].dat, buffer, (get_direction(node->coordinates)/2)*60, 60*(node->frame+node->action), node->text_x, node->text_y, 60, 60);
+ if(node->action!=STAND) {
+ node->frame = (get_elapsed_time(node->tick_time)*4)/(node->speed);
+ if(node->frame>=4) {
+ if(node->action!=MONSTER_DEAD) {
+ if(node->path && node->action!=MONSTER_DEAD) {
+ PATH_NODE *old = node->path;
+ set_coordinates(node->coordinates, node->path->x, node->path->y, 0);
+ node->path = node->path->next;
+ if(old!=NULL)
+ free(old);
+ } else node->action = STAND;
+ if(node->action!=MONSTER_DEAD)node->frame = 0;
+ node->tick_time = tick_time;
+ }
+ }
+ }
+ }
+ old_node = node;
+ node = node->next;
+ if(old_node->action==MONSTER_DEAD && old_node->frame>=4)
+ remove_node(old_node->id);
+ }
+
+ for(int j=0;j<20;j++)
+ for(int i=0;i<26;i++) {
+ if(get_tile(i+camera_x, j+camera_y, 2)!=0)draw_rle_sprite(buffer, (RLE_SPRITE *)tileset[get_tile(i+camera_x, j+camera_y, 2)].dat, i*16-offset_x, j*16-offset_y);
+ }
+
+ stretch_blit(buffer, double_buffer, 0, 0, 400, 300, 0, 0, 800, 600);
+
+ // Draw player speech
+ node = get_head();
+ while(node) {
+ if(node->speech!=NULL) {
+ alfont_textprintf_aa(double_buffer, gui_font, node->text_x+260-alfont_text_length(gui_font, node->speech)/2, node->text_y+100, node->speech_color, "%s", node->speech);
+
+ node->speech_time--;
+ if(node->speech_time==0) {
+ free(node->speech);
+ node->speech = NULL;
+ }
+ }
+ node = node->next;
+ }
+
+ inventory.draw(double_buffer);
+
+ set_trans_blender(0, 0, 0, 110);
+ draw_trans_sprite(double_buffer, chat_background, 0, SCREEN_H-125);
+
+ chatlog.chat_draw(double_buffer, 8, gui_font);
+ gui_update(chat_player);
+
+ if(show_npc_dialog) {
+ dialog_message(npc_dialog,MSG_DRAW,0,0);
+ if(!(show_npc_dialog = gui_update(npc_player)))strcpy(npc_text, "");
+ }
+
+ if(show_skill_dialog) {
+ update_skill_dialog();
+ if(gui_update(skill_player)==0)show_skill_dialog = false;
+ }
+
+
+ alfont_textprintf_aa(double_buffer, gui_font, 0, 0, MAKECOL_WHITE, "FPS:%i", fps);
+
+ blit(double_buffer, screen, 0, 0, 0, 0, 800, 600);
+
+ frame++;
+}
+
+void exit_graphic() {
+ shutdown_dialog(npc_player);
+ shutdown_dialog(chat_player);
+ shutdown_dialog(skill_player);
+}
diff --git a/src/graphic/graphic.h b/src/graphic/graphic.h
new file mode 100644
index 00000000..c50def22
--- /dev/null
+++ b/src/graphic/graphic.h
@@ -0,0 +1,50 @@
+/**
+
+ The Mana World
+ Copyright 2004 The Mana World Development Team
+
+ This file is part of The Mana World.
+
+ The Mana World is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ any later version.
+
+ The Mana World is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with The Mana World; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ By ElvenProgrammer aka Eugenio Favalli (umperio@users.sourceforge.net)
+
+*/
+
+#ifndef _GRAPHIC_H
+#define _GRAPHIC_H
+
+#ifdef WIN32
+#pragma warning (disable:4312)
+#endif
+
+#include <allegro.h>
+#include "../Gui/chat.h"
+#include "../Gui/inventory.h"
+
+extern BITMAP *buffer, *double_buffer;
+extern char speech[255];
+extern char npc_text[1000];
+extern Chat chatlog;
+extern bool show_skill_dialog;
+extern int show_npc_dialog;
+extern TmwInventory inventory;
+extern int map_x, map_y;
+
+void do_graphic(void);
+void init_graphic(void);
+void exit_graphic(void);
+
+#endif
diff --git a/src/graphic/super_eagle.cpp b/src/graphic/super_eagle.cpp
new file mode 100644
index 00000000..78bb6fea
--- /dev/null
+++ b/src/graphic/super_eagle.cpp
@@ -0,0 +1,450 @@
+/**
+
+ The Mana World
+ Copyright 2004 The Mana World Development Team
+
+ This file is part of The Mana World.
+
+ The Mana World is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ any later version.
+
+ The Mana World is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with The Mana World; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+#include "SuperEagle.h"
+
+static uint32 colorMask = 0xF7DEF7DE;
+static uint32 lowPixelMask = 0x08210821;
+static uint32 qcolorMask = 0xE79CE79C;
+static uint32 qlowpixelMask = 0x18631863;
+static uint32 redblueMask = 0xF81F;
+static uint32 greenMask = 0x7E0;
+static int PixelsPerMask = 2;
+static int xsai_depth = 0;
+
+int Init_SuperEagle(int d) {
+ int minr = 0, ming = 0, minb = 0;
+ int i;
+
+ if (d != 15 && d != 16 && d != 24 && d != 32)
+ return -1;
+
+ /* Get lowest color bit */
+ for (i = 0; i < 255; i++) {
+ if (!minr)
+ minr = makecol(i, 0, 0);
+ if (!ming)
+ ming = makecol(0, i, 0);
+ if (!minb)
+ minb = makecol(0, 0, i);
+ }
+
+ colorMask = (makecol_depth(d, 255, 0, 0) - minr) | (makecol_depth(d, 0, 255, 0) - ming) | (makecol_depth(d, 0, 0, 255) - minb);
+ lowPixelMask = minr | ming | minb;
+ qcolorMask = (makecol_depth(d, 255, 0, 0) - 3 * minr) | (makecol_depth(d, 0, 255, 0) - 3 * ming) | (makecol_depth(d, 0, 0, 255) - 3 * minb);
+ qlowpixelMask = (minr * 3) | (ming * 3) | (minb * 3);
+ redblueMask = makecol_depth(d, 255, 0, 255);
+ greenMask = makecol_depth(d, 0, 255, 0);
+
+ PixelsPerMask = (d <= 16) ? 2 : 1;
+
+ if (PixelsPerMask == 2) {
+ colorMask |= (colorMask << 16);
+ qcolorMask |= (qcolorMask << 16);
+ lowPixelMask |= (lowPixelMask << 16);
+ qlowpixelMask |= (qlowpixelMask << 16);
+ }
+
+ TRACE("Color Mask: 0x%lX\n", colorMask);
+ TRACE("Low Pixel Mask: 0x%lX\n", lowPixelMask);
+ TRACE("QColor Mask: 0x%lX\n", qcolorMask);
+ TRACE("QLow Pixel Mask: 0x%lX\n", qlowpixelMask);
+
+ xsai_depth = d;
+
+ return 0;
+}
+
+/** unused /- kth5
+static int GetResult1(uint32 A, uint32 B, uint32 C, uint32 D) {
+ int x = 0;
+ int y = 0;
+ int r = 0;
+ if (A == C)
+ x += 1;
+ else if (B == C)
+ y += 1;
+ if (A == D)
+ x += 1;
+ else if (B == D)
+ y += 1;
+ if (x <= 1)
+ r += 1;
+ if (y <= 1)
+ r -= 1;
+ return r;
+}
+
+static int GetResult2(uint32 A, uint32 B, uint32 C, uint32 D, uint32 E) {
+ int x = 0;
+ int y = 0;
+ int r = 0;
+ if (A == C)
+ x += 1;
+ else if (B == C)
+ y += 1;
+ if (A == D)
+ x += 1;
+ else if (B == D)
+ y += 1;
+ if (x <= 1)
+ r -= 1;
+ if (y <= 1)
+ r += 1;
+ return r;
+}*/
+
+
+#define GET_RESULT(A, B, C, D) ((A != C || A != D) - (B != C || B != D))
+
+#define INTERPOLATE(A, B) (((A & colorMask) >> 1) + ((B & colorMask) >> 1) + (A & B & lowPixelMask))
+
+#define Q_INTERPOLATE(A, B, C, D) ((A & qcolorMask) >> 2) + ((B & qcolorMask) >> 2) + ((C & qcolorMask) >> 2) + ((D & qcolorMask) >> 2) \
+ + ((((A & qlowpixelMask) + (B & qlowpixelMask) + (C & qlowpixelMask) + (D & qlowpixelMask)) >> 2) & qlowpixelMask)
+
+
+/* Clipping Macro, stolen from Allegro, modified to work with 2xSaI */
+#define BLIT_CLIP2(src, dest, s_x, s_y, d_x, d_y, w, h, xscale, yscale) \
+ /* check for ridiculous cases */ \
+ if ((s_x >= src->cr) || (s_y >= src->cb) || \
+ (d_x >= dest->cr) || (d_y >= dest->cb)) \
+ return; \
+ \
+ if ((s_x + w < src->cl) || (s_y + h < src->ct) || \
+ (d_x + w * xscale < dest->cl) || (d_y + h * yscale < dest->ct)) \
+ return; \
+ \
+ if (xscale < 1 || yscale < 1) \
+ return; \
+ \
+ /* clip src left */ \
+ if (s_x < src->cl) { \
+ w += s_x; \
+ d_x -= s_x * xscale; \
+ s_x = src->cl; \
+ } \
+ \
+ /* clip src top */ \
+ if (s_y < src->ct) { \
+ h += s_y; \
+ d_y -= s_y * yscale; \
+ s_y = src->ct; \
+ } \
+ \
+ /* clip src right */ \
+ if (s_x + w > src->cr) \
+ w = src->cr - s_x; \
+ \
+ /* clip src bottom */ \
+ if (s_y + h > src->cb) \
+ h = src->cb - s_y; \
+ \
+ /* clip dest left */ \
+ if (d_x < dest->cl) { \
+ d_x -= dest->cl; \
+ w += d_x / xscale; \
+ s_x -= d_x / xscale; \
+ d_x = dest->cl; \
+ } \
+ \
+ /* clip dest top */ \
+ if (d_y < dest->ct) { \
+ d_y -= dest->ct; \
+ h += d_y / yscale; \
+ s_y -= d_y / yscale; \
+ d_y = dest->ct; \
+ } \
+ \
+ /* clip dest right */ \
+ if (d_x + w * xscale > dest->cr) \
+ w = (dest->cr - d_x) / xscale; \
+ \
+ /* clip dest bottom */ \
+ if (d_y + h * yscale > dest->cb) \
+ h = (dest->cb - d_y) / yscale; \
+ \
+ /* bottle out if zero size */ \
+ if ((w <= 0) || (h <= 0)) \
+ return;
+
+
+static unsigned char *src_line[4];
+static unsigned char *dst_line[2];
+
+
+
+void SuperEagle(BITMAP * src, BITMAP * dest, int s_x, int s_y, int d_x, int d_y, int w, int h) {
+ int sbpp, dbpp;
+
+ BITMAP *dst2 = NULL;
+
+ if (!src || !dest)
+ return;
+
+ sbpp = bitmap_color_depth(src);
+ dbpp = bitmap_color_depth(dest);
+
+ if ((sbpp != xsai_depth) || (sbpp != dbpp)) /* Must be same color depth */
+ return;
+
+ BLIT_CLIP2(src, dest, s_x, s_y, d_x, d_y, w, h, 2, 2);
+
+ if (w < 4 || h < 4) { /* Image is too small to be 2xSaI'ed. */
+ stretch_blit(src, dest, s_x, s_y, w, h, d_x, d_y, w * 2, h * 2);
+ return;
+ }
+
+ sbpp = BYTES_PER_PIXEL(sbpp);
+ if (d_x || d_y)
+ dst2 = create_sub_bitmap(dest, d_x, d_y, w * 2, h * 2);
+
+ SuperEagle_ex(src->line[s_y] + s_x * sbpp, (unsigned int)(src->line[1] - src->line[0]), NULL, dst2 ? dst2 : dest, w, h);
+
+ if (dst2)
+ destroy_bitmap(dst2);
+
+ return;
+}
+
+void SuperEagle_ex(uint8 *src, uint32 src_pitch, uint8 *unused, BITMAP *dest, uint32 width, uint32 height) {
+
+ int j, v;
+ unsigned int x, y;
+ int sbpp = BYTES_PER_PIXEL(bitmap_color_depth(dest));
+ unsigned long color[12];
+
+ /* Point to the first 3 lines. */
+ src_line[0] = src;
+ src_line[1] = src;
+ src_line[2] = src + src_pitch;
+ src_line[3] = src + src_pitch * 2;
+
+ /* Can we write the results directly? */
+ if (is_video_bitmap(dest) || is_planar_bitmap(dest)) {
+ dst_line[0] = (unsigned char *)malloc(sizeof(char) * sbpp * width);
+ dst_line[1] = (unsigned char *)malloc(sizeof(char) * sbpp * width);
+ v = 1;
+ }
+ else {
+ dst_line[0] = dest->line[0];
+ dst_line[1] = dest->line[1];
+ v = 0;
+ }
+
+ /* Set destination */
+ bmp_select(dest);
+
+ x = 0, y = 0;
+
+ if (PixelsPerMask == 2) {
+ unsigned short *sbp;
+ sbp = (unsigned short*)src_line[0];
+ color[0] = *sbp; color[1] = color[0]; color[2] = color[0]; color[3] = color[0];
+ color[4] = *(sbp + 1); color[5] = *(sbp + 2);
+ sbp = (unsigned short*)src_line[2];
+ color[6] = *sbp; color[7] = color[6]; color[8] = *(sbp + 1); color[9] = *(sbp + 2);
+ sbp = (unsigned short*)src_line[3];
+ color[10] = *sbp; color[11] = *(sbp + 1);
+ }
+ else {
+ unsigned long *lbp;
+ lbp = (unsigned long*)src_line[0];
+ color[0] = *lbp; color[1] = color[0]; color[2] = color[0]; color[3] = color[0];
+ color[4] = *(lbp + 1); color[5] = *(lbp + 2);
+ lbp = (unsigned long*)src_line[2];
+ color[6] = *lbp; color[7] = color[6]; color[8] = *(lbp + 1); color[9] = *(lbp + 2);
+ lbp = (unsigned long*)src_line[3];
+ color[10] = *lbp; color[11] = *(lbp + 1);
+ }
+
+ for (y = 0; y < height; y++) {
+
+ /* Todo: x = width - 2, x = width - 1 */
+
+ for (x = 0; x < width; x++) {
+ unsigned long product1a, product1b, product2a, product2b;
+
+//--------------------------------------- B1 B2 0 1
+// 4 5 6 S2 -> 2 3 4 5
+// 1 2 3 S1 6 7 8 9
+// A1 A2 10 11
+
+ if (color[7] == color[4] && color[3] != color[8]) {
+ product1b = product2a = color[7];
+
+ if ((color[6] == color[7]) || (color[4] == color[1]))
+ product1a = INTERPOLATE(color[7], INTERPOLATE(color[7], color[3]));
+ else
+ product1a = INTERPOLATE(color[3], color[4]);
+
+ if ((color[4] == color[5]) || (color[7] == color[10]))
+ product2b = INTERPOLATE(color[7], INTERPOLATE(color[7], color[8]));
+ else
+ product2b = INTERPOLATE(color[7], color[8]);
+ }
+ else if (color[3] == color[8] && color[7] != color[4]) {
+ product2b = product1a = color[3];
+
+ if ((color[0] == color[3]) || (color[5] == color[9]))
+ product1b = INTERPOLATE(color[3], INTERPOLATE(color[3], color[4]));
+ else
+ product1b = INTERPOLATE(color[3], color[1]);
+
+ if ((color[8] == color[11]) || (color[2] == color[3]))
+ product2a = INTERPOLATE(color[3], INTERPOLATE(color[3], color[2]));
+ else
+ product2a = INTERPOLATE(color[7], color[8]);
+
+ }
+ else if (color[3] == color[8] && color[7] == color[4]) {
+ register int r = 0;
+
+ r += GET_RESULT(color[4], color[3], color[6], color[10]);
+ r += GET_RESULT(color[4], color[3], color[2], color[0]);
+ r += GET_RESULT(color[4], color[3], color[11], color[9]);
+ r += GET_RESULT(color[4], color[3], color[1], color[5]);
+
+ if (r > 0) {
+ product1b = product2a = color[7];
+ product1a = product2b = INTERPOLATE(color[3], color[4]);
+ }
+ else if (r < 0) {
+ product2b = product1a = color[3];
+ product1b = product2a = INTERPOLATE(color[3], color[4]);
+ }
+ else {
+ product2b = product1a = color[3];
+ product1b = product2a = color[7];
+ }
+ }
+ else {
+ product2b = product1a = INTERPOLATE(color[7], color[4]);
+ product2b = Q_INTERPOLATE(color[8], color[8], color[8], product2b);
+ product1a = Q_INTERPOLATE(color[3], color[3], color[3], product1a);
+
+ product2a = product1b = INTERPOLATE(color[3], color[8]);
+ product2a = Q_INTERPOLATE(color[7], color[7], color[7], product2a);
+ product1b = Q_INTERPOLATE(color[4], color[4], color[4], product1b);
+ }
+
+ if (PixelsPerMask == 2) {
+ *((unsigned long *) (&dst_line[0][x * 4])) = product1a | (product1b << 16);
+ *((unsigned long *) (&dst_line[1][x * 4])) = product2a | (product2b << 16);
+ }
+ else {
+ *((unsigned long *) (&dst_line[0][x * 8])) = product1a;
+ *((unsigned long *) (&dst_line[0][x * 8 + 4])) = product1b;
+ *((unsigned long *) (&dst_line[1][x * 8])) = product2a;
+ *((unsigned long *) (&dst_line[1][x * 8 + 4])) = product2b;
+ }
+
+ /* Move color matrix forward */
+ color[0] = color[1];
+ color[2] = color[3]; color[3] = color[4]; color[4] = color[5];
+ color[6] = color[7]; color[7] = color[8]; color[8] = color[9];
+ color[10] = color[11];
+
+ if (x < width - 2) {
+ x += 2;
+ if (PixelsPerMask == 2) {
+ color[1] = *(((unsigned short*)src_line[0]) + x);
+ if (x < width) {
+ color[5] = *(((unsigned short*)src_line[1]) + x + 1);
+ color[9] = *(((unsigned short*)src_line[2]) + x + 1);
+ }
+ color[11] = *(((unsigned short*)src_line[3]) + x);
+ }
+ else {
+ color[1] = *(((unsigned long*)src_line[0]) + x);
+ if (x < width) {
+ color[5] = *(((unsigned long*)src_line[1]) + x + 1);
+ color[9] = *(((unsigned long*)src_line[2]) + x + 1);
+ }
+ color[11] = *(((unsigned long*)src_line[3]) + x);
+ }
+ x -= 2;
+ }
+ }
+
+ /* We're done with one line, so we shift the source lines up */
+ src_line[0] = src_line[1];
+ src_line[1] = src_line[2];
+ src_line[2] = src_line[3];
+
+ /* Read next line */
+ if (y + 3 >= height)
+ src_line[3] = src_line[2];
+ else
+ src_line[3] = src_line[2] + src_pitch;
+
+ /* Then shift the color matrix up */
+ if (PixelsPerMask == 2) {
+ unsigned short *sbp;
+ sbp = (unsigned short*)src_line[0];
+ color[0] = *sbp; color[1] = *(sbp + 1);
+ sbp = (unsigned short*)src_line[1];
+ color[2] = *sbp; color[3] = color[2]; color[4] = *(sbp + 1); color[5] = *(sbp + 2);
+ sbp = (unsigned short*)src_line[2];
+ color[6] = *sbp; color[7] = color[6]; color[8] = *(sbp + 1); color[9] = *(sbp + 2);
+ sbp = (unsigned short*)src_line[3];
+ color[10] = *sbp; color[11] = *(sbp + 1);
+ }
+ else {
+ unsigned long *lbp;
+ lbp = (unsigned long*)src_line[0];
+ color[0] = *lbp; color[1] = *(lbp + 1);
+ lbp = (unsigned long*)src_line[1];
+ color[2] = *lbp; color[3] = color[2]; color[4] = *(lbp + 1); color[5] = *(lbp + 2);
+ lbp = (unsigned long*)src_line[2];
+ color[6] = *lbp; color[7] = color[6]; color[8] = *(lbp + 1); color[9] = *(lbp + 2);
+ lbp = (unsigned long*)src_line[3];
+ color[10] = *lbp; color[11] = *(lbp + 1);
+ }
+
+
+ /* Write the 2 lines, if not already done so */
+ if (v) {
+ unsigned long dst_addr;
+
+ dst_addr = bmp_write_line(dest, y * 2);
+ for (j = 0; j < dest->w * sbpp; j += sizeof(long))
+ bmp_write32(dst_addr + j, *((unsigned long *) (dst_line[0] + j)));
+
+ dst_addr = bmp_write_line(dest, y * 2 + 1);
+ for (j = 0; j < dest->w * sbpp; j += sizeof(long))
+ bmp_write32(dst_addr + j, *((unsigned long *) (dst_line[1] + j)));
+ }
+ else {
+ if (y < height - 1) {
+ dst_line[0] = dest->line[y * 2 + 2];
+ dst_line[1] = dest->line[y * 2 + 3];
+ }
+ }
+ }
+ bmp_unwrite_line(dest);
+
+ if (v) {
+ free(dst_line[0]);
+ free(dst_line[1]);
+ }
+}
diff --git a/src/graphic/super_eagle.h b/src/graphic/super_eagle.h
new file mode 100644
index 00000000..64c763db
--- /dev/null
+++ b/src/graphic/super_eagle.h
@@ -0,0 +1,44 @@
+/**
+
+ The Mana World
+ Copyright 2004 The Mana World Development Team
+
+ This file is part of The Mana World.
+
+ The Mana World is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ any later version.
+
+ The Mana World is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with The Mana World; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+#ifdef WIN32
+ #pragma warning (disable:4312)
+#endif
+
+#ifndef _SUPER_EAGLE_H
+#define _SUPER_EAGLE_H
+
+#include <string.h>
+#include <allegro.h>
+#include <allegro/internal/aintern.h>
+
+#define uint32 unsigned long
+#define uint16 unsigned short
+#define uint8 unsigned char
+
+void SuperEagle(BITMAP * src, BITMAP * dest, int s_x, int s_y, int d_x, int d_y, int w, int h);
+void SuperEagle_ex(uint8 *src, uint32 src_pitch, uint8 *unused, BITMAP *dest, uint32 width, uint32 height);
+
+int Init_SuperEagle(int d);
+
+#endif