From 92bbeab96bf61edf9b7caa125ed67e634258383e Mon Sep 17 00:00:00 2001 From: Eugenio Favalli Date: Sun, 26 Sep 2004 13:08:46 +0000 Subject: *** empty log message *** --- src/graphic/graphic.cpp | 256 +++++++++++++++++++++++++ src/graphic/graphic.h | 50 +++++ src/graphic/super_eagle.cpp | 450 ++++++++++++++++++++++++++++++++++++++++++++ src/graphic/super_eagle.h | 44 +++++ 4 files changed, 800 insertions(+) create mode 100644 src/graphic/graphic.cpp create mode 100644 src/graphic/graphic.h create mode 100644 src/graphic/super_eagle.cpp create mode 100644 src/graphic/super_eagle.h (limited to 'src/graphic') 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 +#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 +#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 +#include +#include + +#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 -- cgit v1.2.3-70-g09d2