/***********************************************************
* Rocks'n'Diamonds -- McDuffin Strikes Back! *
*----------------------------------------------------------*
-* (c) 1995-2000 Artsoft Entertainment *
+* (c) 1995-2002 Artsoft Entertainment *
* Holger Schemel *
* Detmolder Strasse 189 *
* 33604 Bielefeld *
* tools.c *
***********************************************************/
-#include <stdarg.h>
-
-#if defined(PLATFORM_FREEBSD)
-#include <machine/joystick.h>
-#endif
-
#include "libgame/libgame.h"
#include "tools.h"
#include "game.h"
#include "events.h"
-#include "joystick.h"
#include "cartoons.h"
#include "network.h"
#include "tape.h"
-#if defined(PLATFORM_MSDOS)
-extern boolean wait_for_vsync;
-#endif
-
/* tool button identifiers */
#define TOOL_CTRL_ID_YES 0
#define TOOL_CTRL_ID_NO 1
}
}
+void RedrawPlayfield(boolean force_redraw, int x, int y, int width, int height)
+{
+ if (game_status == PLAYING)
+ {
+ if (force_redraw)
+ {
+ x = gfx.sx - TILEX;
+ y = gfx.sy - TILEY;
+ width = gfx.sxsize + 2 * TILEX;
+ height = gfx.sysize + 2 * TILEY;
+ }
+
+ if (force_redraw || setup.direct_draw)
+ {
+ int xx, yy;
+ int x1 = (x - SX) / TILEX, y1 = (y - SY) / TILEY;
+ int x2 = (x - SX + width) / TILEX, y2 = (y - SY + height) / TILEY;
+
+ if (setup.direct_draw)
+ SetDrawtoField(DRAW_BACKBUFFER);
+
+ for(xx=BX1; xx<=BX2; xx++)
+ for(yy=BY1; yy<=BY2; yy++)
+ if (xx >= x1 && xx <= x2 && yy >= y1 && yy <= y2)
+ DrawScreenField(xx, yy);
+ DrawAllPlayers();
+
+ if (setup.direct_draw)
+ SetDrawtoField(DRAW_DIRECT);
+ }
+
+ if (setup.soft_scrolling)
+ {
+ int fx = FX, fy = FY;
+
+ fx += (ScreenMovDir & (MV_LEFT|MV_RIGHT) ? ScreenGfxPos : 0);
+ fy += (ScreenMovDir & (MV_UP|MV_DOWN) ? ScreenGfxPos : 0);
+
+ BlitBitmap(fieldbuffer, backbuffer, fx,fy, SXSIZE,SYSIZE, SX,SY);
+ }
+ }
+
+ BlitBitmap(drawto, window, x, y, width, height, x, y);
+}
+
void BackToFront()
{
int x,y;
if (redraw_mask & REDRAW_FIELD)
redraw_mask &= ~REDRAW_TILES;
- if (!redraw_mask)
+ if (redraw_mask == REDRAW_NONE)
return;
if (global.fps_slowdown && game_status == PLAYING)
for(y=0; y<MAX_BUF_YSIZE; y++)
redraw[x][y] = 0;
redraw_tiles = 0;
- redraw_mask = 0;
+ redraw_mask = REDRAW_NONE;
}
void FadeToFront()
if (Store[last_jx][last_jy] && IS_DRAWABLE(last_element))
{
DrawLevelElement(last_jx, last_jy, Store[last_jx][last_jy]);
- DrawLevelFieldThruMask(last_jx, last_jy);
+ if (last_element == EL_DYNAMITE_ACTIVE)
+ DrawDynamite(last_jx, last_jy);
+ else
+ DrawLevelFieldThruMask(last_jx, last_jy);
}
else if (last_element == EL_DYNAMITE_ACTIVE)
DrawDynamite(last_jx, last_jy);
DrawLevelElement(jx, jy, Store[jx][jy]);
else if (!IS_ACTIVE_BOMB(element))
DrawLevelField(jx, jy);
+ else
+ DrawLevelElement(jx, jy, EL_LEERRAUM);
/* draw player himself */
DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic + phase, NO_CUTTING);
}
-void getGraphicSource(int graphic, int *bitmap_nr, int *x, int *y)
+void getGraphicSource(int graphic, Bitmap **bitmap, int *x, int *y)
{
- if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
+ if (graphic >= 0 && graphic_info[graphic].bitmap != NULL)
+ {
+ *bitmap = graphic_info[graphic].bitmap;
+ *x = graphic_info[graphic].src_x;
+ *y = graphic_info[graphic].src_y;
+ }
+ else if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
{
graphic -= GFX_START_ROCKSSCREEN;
- *bitmap_nr = PIX_BACK;
+ *bitmap = pix[PIX_BACK];
*x = SX + (graphic % GFX_PER_LINE) * TILEX;
*y = SY + (graphic / GFX_PER_LINE) * TILEY;
}
else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
{
graphic -= GFX_START_ROCKSHEROES;
- *bitmap_nr = PIX_HEROES;
+ *bitmap = pix[PIX_HEROES];
*x = (graphic % HEROES_PER_LINE) * TILEX;
*y = (graphic / HEROES_PER_LINE) * TILEY;
}
else if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
{
graphic -= GFX_START_ROCKSSP;
- *bitmap_nr = PIX_SP;
+ *bitmap = pix[PIX_SP];
*x = (graphic % SP_PER_LINE) * TILEX;
*y = (graphic / SP_PER_LINE) * TILEY;
}
else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
{
graphic -= GFX_START_ROCKSDC;
- *bitmap_nr = PIX_DC;
+ *bitmap = pix[PIX_DC];
*x = (graphic % DC_PER_LINE) * TILEX;
*y = (graphic / DC_PER_LINE) * TILEY;
}
else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
{
graphic -= GFX_START_ROCKSMORE;
- *bitmap_nr = PIX_MORE;
+ *bitmap = pix[PIX_MORE];
*x = (graphic % MORE_PER_LINE) * TILEX;
*y = (graphic / MORE_PER_LINE) * TILEY;
}
else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
{
graphic -= GFX_START_ROCKSFONT;
- *bitmap_nr = PIX_BIGFONT;
+ *bitmap = pix[PIX_BIGFONT];
*x = (graphic % FONT_CHARS_PER_LINE) * TILEX;
*y = ((graphic / FONT_CHARS_PER_LINE) * TILEY +
FC_SPECIAL1 * FONT_LINES_PER_FONT * TILEY);
}
else
{
- *bitmap_nr = PIX_SP;
+ *bitmap = pix[PIX_SP];
*x = 0;
*y = 0;
}
MarkTileDirty(x,y);
}
-void DrawGraphicExt(DrawBuffer *bitmap, int x, int y, int graphic)
+void DrawGraphicExt(DrawBuffer *dst_bitmap, int x, int y, int graphic)
{
- int bitmap_nr;
+ Bitmap *src_bitmap;
int src_x, src_y;
- getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
- BlitBitmap(pix[bitmap_nr], bitmap, src_x, src_y, TILEX, TILEY, x, y);
+ getGraphicSource(graphic, &src_bitmap, &src_x, &src_y);
+ BlitBitmap(src_bitmap, dst_bitmap, src_x, src_y, TILEX, TILEY, x, y);
}
void DrawGraphicThruMask(int x, int y, int graphic)
void DrawGraphicThruMaskExt(DrawBuffer *d, int dest_x, int dest_y, int graphic)
{
int tile = graphic;
- int bitmap_nr;
int src_x, src_y;
Bitmap *src_bitmap;
GC drawing_gc;
if (graphic == GFX_LEERRAUM)
return;
- getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
- src_bitmap = pix[bitmap_nr];
- drawing_gc = pix[bitmap_nr]->stored_clip_gc;
+ getGraphicSource(graphic, &src_bitmap, &src_x, &src_y);
+ drawing_gc = src_bitmap->stored_clip_gc;
if (tile_clipmask[tile] != None)
{
int cx = 0, cy = 0;
int src_x, src_y, dest_x, dest_y;
int tile = graphic;
- int bitmap_nr;
Bitmap *src_bitmap;
GC drawing_gc;
MarkTileDirty(x, y + SIGN(dy));
}
- getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
- src_bitmap = pix[bitmap_nr];
- drawing_gc = pix[bitmap_nr]->stored_clip_gc;
+ getGraphicSource(graphic, &src_bitmap, &src_x, &src_y);
+ drawing_gc = src_bitmap->stored_clip_gc;
src_x += cx;
src_y += cy;
}
}
else
- BlitBitmap(pix[bitmap_nr], drawto_field,
+ BlitBitmap(src_bitmap, drawto_field,
src_x, src_y, width, height, dest_x, dest_y);
MarkTileDirty(x,y);
else if ((element == EL_FELSBROCKEN ||
element == EL_SP_ZONK ||
element == EL_BD_ROCK ||
- IS_GEM(element)) && !cut_mode)
+ element == EL_SP_INFOTRON ||
+ IS_GEM(element))
+ && !cut_mode)
{
if (uy >= lev_fieldy-1 || !IS_BELT(Feld[ux][uy+1]))
{
}
}
else if (element == EL_MAGIC_WALL_EMPTY ||
+ element == EL_MAGIC_WALL_EMPTYING ||
element == EL_MAGIC_WALL_BD_EMPTY ||
+ element == EL_MAGIC_WALL_BD_EMPTYING ||
element == EL_MAGIC_WALL_FULL ||
element == EL_MAGIC_WALL_BD_FULL)
{
graphic += 3 + getGraphicAnimationPhase(4, 4, ANIM_REVERSE);
}
- else if (IS_AMOEBOID(element))
+ else if (IS_AMOEBOID(element) || element == EL_AMOEBA_DRIPPING)
{
graphic = (element == EL_AMOEBE_TOT ? GFX_AMOEBE_TOT : GFX_AMOEBE_LEBT);
graphic += (x + 2 * y + 4) % 4;
void DrawScreenField(int x, int y)
{
int ux = LEVELX(x), uy = LEVELY(y);
- int element;
+ int element, content;
if (!IN_LEV_FIELD(ux, uy))
{
}
element = Feld[ux][uy];
+ content = Store[ux][uy];
if (IS_MOVING(ux, uy))
{
int horiz_move = (MovDir[ux][uy] == MV_LEFT || MovDir[ux][uy] == MV_RIGHT);
boolean cut_mode = NO_CUTTING;
- if (Store[ux][uy] == EL_MORAST_LEER ||
- Store[ux][uy] == EL_MAGIC_WALL_EMPTY ||
- Store[ux][uy] == EL_MAGIC_WALL_BD_EMPTY ||
- Store[ux][uy] == EL_AMOEBE_NASS)
+ if (element == EL_QUICKSAND_EMPTYING ||
+ element == EL_MAGIC_WALL_EMPTYING ||
+ element == EL_MAGIC_WALL_BD_EMPTYING ||
+ element == EL_AMOEBA_DRIPPING)
cut_mode = CUT_ABOVE;
- else if (Store[ux][uy] == EL_MORAST_VOLL ||
- Store[ux][uy] == EL_MAGIC_WALL_FULL ||
- Store[ux][uy] == EL_MAGIC_WALL_BD_FULL)
+ else if (element == EL_QUICKSAND_FILLING ||
+ element == EL_MAGIC_WALL_FILLING ||
+ element == EL_MAGIC_WALL_BD_FILLING)
cut_mode = CUT_BELOW;
if (cut_mode == CUT_ABOVE)
- DrawScreenElementShifted(x, y, 0, 0, Store[ux][uy], NO_CUTTING);
+ DrawScreenElementShifted(x, y, 0, 0, element, NO_CUTTING);
else
DrawScreenElement(x, y, EL_LEERRAUM);
if (horiz_move)
DrawScreenElementShifted(x, y, MovPos[ux][uy], 0, element, NO_CUTTING);
- else
+ else if (cut_mode == NO_CUTTING)
DrawScreenElementShifted(x, y, 0, MovPos[ux][uy], element, cut_mode);
+ else
+ DrawScreenElementShifted(x, y, 0, MovPos[ux][uy], content, cut_mode);
- if (Store[ux][uy] == EL_SALZSAEURE)
+ if (content == EL_SALZSAEURE)
DrawLevelElementThruMask(ux, uy + 1, EL_SALZSAEURE);
}
else if (IS_BLOCKED(ux, uy))
int sx, sy;
int horiz_move;
boolean cut_mode = NO_CUTTING;
+ int element_old, content_old;
Blocked2Moving(ux, uy, &oldx, &oldy);
sx = SCREENX(oldx);
horiz_move = (MovDir[oldx][oldy] == MV_LEFT ||
MovDir[oldx][oldy] == MV_RIGHT);
- if (Store[oldx][oldy] == EL_MORAST_LEER ||
- Store[oldx][oldy] == EL_MAGIC_WALL_EMPTY ||
- Store[oldx][oldy] == EL_MAGIC_WALL_BD_EMPTY ||
- Store[oldx][oldy] == EL_AMOEBE_NASS)
+ element_old = Feld[oldx][oldy];
+ content_old = Store[oldx][oldy];
+
+ if (element_old == EL_QUICKSAND_EMPTYING ||
+ element_old == EL_MAGIC_WALL_EMPTYING ||
+ element_old == EL_MAGIC_WALL_BD_EMPTYING ||
+ element_old == EL_AMOEBA_DRIPPING)
cut_mode = CUT_ABOVE;
DrawScreenElement(x, y, EL_LEERRAUM);
- element = Feld[oldx][oldy];
if (horiz_move)
- DrawScreenElementShifted(sx,sy, MovPos[oldx][oldy],0,element,NO_CUTTING);
+ DrawScreenElementShifted(sx, sy, MovPos[oldx][oldy], 0, element_old,
+ NO_CUTTING);
+ else if (cut_mode == NO_CUTTING)
+ DrawScreenElementShifted(sx, sy, 0, MovPos[oldx][oldy], element_old,
+ cut_mode);
else
- DrawScreenElementShifted(sx,sy, 0,MovPos[oldx][oldy],element,cut_mode);
+ DrawScreenElementShifted(sx, sy, 0, MovPos[oldx][oldy], content_old,
+ cut_mode);
}
else if (IS_DRAWABLE(element))
DrawScreenElement(x, y, element);
return 0;
}
+#define MAX_REQUEST_LINES 13
+#define MAX_REQUEST_LINE_LEN 7
+
boolean Request(char *text, unsigned int req_state)
{
int mx, my, ty, result = -1;
ClearRectangle(drawto, DX, DY, DXSIZE, DYSIZE);
/* write text for request */
- for(ty=0; ty<13; ty++)
+ for(ty=0; ty < MAX_REQUEST_LINES; ty++)
{
+ char text_line[MAX_REQUEST_LINE_LEN + 1];
int tx, tl, tc;
- char txt[256];
if (!*text)
break;
- for(tl=0,tx=0; tx<7; tl++,tx++)
+ for(tl=0,tx=0; tx < MAX_REQUEST_LINE_LEN; tl++,tx++)
{
tc = *(text + tx);
- if (!tc || tc == 32)
+ if (!tc || tc == ' ')
break;
}
+
if (!tl)
{
text++;
ty--;
continue;
}
- sprintf(txt, text);
- txt[tl] = 0;
- DrawTextExt(drawto, DX + 51 - (tl * 14)/2, DY + 8 + ty * 16,
- txt, FS_SMALL, FC_YELLOW);
- text += tl + (tc == 32 ? 1 : 0);
+
+ strncpy(text_line, text, tl);
+ text_line[tl] = 0;
+
+ DrawTextExt(drawto, DX + 50 - (tl * 14)/2, DY + 8 + ty * 16,
+ text_line, FS_SMALL, FC_YELLOW);
+
+ text += tl + (tc == ' ' ? 1 : 0);
}
if (req_state & REQ_ASK)
break;
case EVENT_KEYRELEASE:
- key_joystick_mapping = 0;
+ ClearPlayerAction();
break;
default:
unsigned int GetDoorState()
{
- return(MoveDoor(DOOR_GET_STATE));
+ return MoveDoor(DOOR_GET_STATE);
+}
+
+unsigned int SetDoorState(unsigned int door_state)
+{
+ return MoveDoor(door_state | DOOR_SET_STATE);
}
unsigned int MoveDoor(unsigned int door_state)
if (door_state == DOOR_GET_STATE)
return(door1 | door2);
+ if (door_state & DOOR_SET_STATE)
+ {
+ if (door_state & DOOR_ACTION_1)
+ door1 = door_state & DOOR_ACTION_1;
+ if (door_state & DOOR_ACTION_2)
+ door2 = door_state & DOOR_ACTION_2;
+
+ return(door1 | door2);
+ }
+
if (door1 == DOOR_OPEN_1 && door_state & DOOR_OPEN_1)
door_state &= ~DOOR_OPEN_1;
else if (door1 == DOOR_CLOSE_1 && door_state & DOOR_CLOSE_1)
{
stepsize = 20;
door_delay_value = 0;
- StopSound(SND_OEFFNEN);
+ StopSound(SND_MENU_DOOR_OPENING);
+ StopSound(SND_MENU_DOOR_CLOSING);
}
if (door_state & DOOR_ACTION)
{
if (!(door_state & DOOR_NO_DELAY))
- PlaySoundStereo(SND_OEFFNEN, PSND_MAX_RIGHT);
+ {
+ /* opening door sound has priority over simultaneously closing door */
+ if (door_state & (DOOR_OPEN_1 | DOOR_OPEN_2))
+ PlaySoundStereo(SND_MENU_DOOR_OPENING, SOUND_MAX_RIGHT);
+ else if (door_state & (DOOR_CLOSE_1 | DOOR_CLOSE_2))
+ PlaySoundStereo(SND_MENU_DOOR_CLOSING, SOUND_MAX_RIGHT);
+ }
start = ((door_state & DOOR_NO_DELAY) ? DXSIZE : 0);
}
if (setup.quick_doors)
- StopSound(SND_OEFFNEN);
+ {
+ StopSound(SND_MENU_DOOR_OPENING);
+ StopSound(SND_MENU_DOOR_CLOSING);
+ }
if (door_state & DOOR_ACTION_1)
door1 = door_state & DOOR_ACTION_1;
}
};
-#if 0
-static void DoNotDisplayInfoText(void *ptr)
-{
- return;
-}
-#endif
-
void CreateToolButtons()
{
int i;
GDI_DECORATION_SIZE, MINI_TILEX, MINI_TILEY,
GDI_DECORATION_SHIFTING, 1, 1,
GDI_EVENT_MASK, event_mask,
-
-#if 0
- GDI_CALLBACK_INFO, DoNotDisplayInfoText,
-#endif
-
GDI_CALLBACK_ACTION, HandleToolButtons,
GDI_END);
request_gadget_id = gi->custom_id;
}
-int el2gfx(int element)
+int get_next_element(int element)
+{
+ switch(element)
+ {
+ case EL_QUICKSAND_FILLING: return EL_MORAST_VOLL;
+ case EL_QUICKSAND_EMPTYING: return EL_MORAST_LEER;
+ case EL_MAGIC_WALL_FILLING: return EL_MAGIC_WALL_FULL;
+ case EL_MAGIC_WALL_EMPTYING: return EL_MAGIC_WALL_EMPTY;
+ case EL_MAGIC_WALL_BD_FILLING: return EL_MAGIC_WALL_BD_FULL;
+ case EL_MAGIC_WALL_BD_EMPTYING: return EL_MAGIC_WALL_BD_EMPTY;
+ case EL_AMOEBA_DRIPPING: return EL_AMOEBE_NASS;
+
+ default: return element;
+ }
+}
+
+int el2gfx_OLD(int element)
{
switch(element)
{
case EL_DIAMANT: return GFX_DIAMANT;
case EL_MORAST_LEER: return GFX_MORAST_LEER;
case EL_MORAST_VOLL: return GFX_MORAST_VOLL;
+ case EL_QUICKSAND_EMPTYING: return GFX_MORAST_LEER;
case EL_TROPFEN: return GFX_TROPFEN;
case EL_BOMBE: return GFX_BOMBE;
case EL_MAGIC_WALL_OFF: return GFX_MAGIC_WALL_OFF;
case EL_MAGIC_WALL_EMPTY: return GFX_MAGIC_WALL_EMPTY;
+ case EL_MAGIC_WALL_EMPTYING:return GFX_MAGIC_WALL_EMPTY;
case EL_MAGIC_WALL_FULL: return GFX_MAGIC_WALL_FULL;
case EL_MAGIC_WALL_DEAD: return GFX_MAGIC_WALL_DEAD;
case EL_SALZSAEURE: return GFX_SALZSAEURE;
case EL_AMOEBE_VOLL: return GFX_AMOEBE_VOLL;
case EL_AMOEBE_BD: return GFX_AMOEBE_BD;
case EL_AMOEBA2DIAM: return GFX_AMOEBA2DIAM;
+ case EL_AMOEBA_DRIPPING: return GFX_AMOEBE_NASS;
case EL_KOKOSNUSS: return GFX_KOKOSNUSS;
case EL_LIFE: return GFX_LIFE;
case EL_LIFE_ASYNC: return GFX_LIFE_ASYNC;
case EL_MAMPFER2: return GFX_MAMPFER2;
case EL_MAGIC_WALL_BD_OFF: return GFX_MAGIC_WALL_BD_OFF;
case EL_MAGIC_WALL_BD_EMPTY:return GFX_MAGIC_WALL_BD_EMPTY;
+ case EL_MAGIC_WALL_BD_EMPTYING:return GFX_MAGIC_WALL_BD_EMPTY;
case EL_MAGIC_WALL_BD_FULL: return GFX_MAGIC_WALL_BD_FULL;
case EL_MAGIC_WALL_BD_DEAD: return GFX_MAGIC_WALL_BD_DEAD;
case EL_DYNABOMB_ACTIVE_1: return GFX_DYNABOMB;
}
}
}
+
+int el2gfx(int element)
+{
+ int graphic_NEW = element_info[element].graphic;
+
+#if DEBUG
+ int graphic_OLD = el2gfx_OLD(element);
+
+ if (element >= MAX_ELEMENTS)
+ {
+ Error(ERR_WARN, "el2gfx: element == %d >= MAX_ELEMENTS", element);
+ }
+
+ if (graphic_NEW != graphic_OLD)
+ {
+ Error(ERR_WARN, "el2gfx: graphic_NEW (%d) != graphic_OLD (%d)",
+ graphic_NEW, graphic_OLD);
+ }
+#endif
+
+ return graphic_NEW;
+}