5 #define MTYPE(x) (x & ~MAP_FORCECLEAR)
7 static switch_t g_sw
[MAX_SWITCHES
];
10 void sw_load(switch_t
*sw
, u16 num
) {
12 memcpy(g_sw
, sw
, sizeof(switch_t
)*num
);
15 static bool toggle(u8 sx
, u8 sy
, u8 from
, u8 to
) {
16 u8
*rowp
= g_cells
+ sy
*MAPW
+ sx
;
20 if (MTYPE(*rowp
) != from
)
23 // find x extents of the door
25 for (cellp
= rowp
- 1; sx
&& MTYPE(*cellp
) == from
; --sx
, --cellp
);
26 for (cellp
= rowp
+ 1; ex
< MAPW
&& MTYPE(*cellp
) == from
; ++ex
, ++cellp
);
28 // find y extents of the door
30 for (cellp
= rowp
- MAPW
; sy
&& MTYPE(*cellp
) == from
; --sy
, cellp
-= MAPW
);
31 for (cellp
= rowp
+ MAPW
; ey
< MAPH
&& MTYPE(*cellp
) == from
; ++ey
, cellp
+= MAPW
);
34 const u8 dx
= ex
- sx
;
35 rowp
= g_cells
+ sy
*MAPW
+ sx
;
36 for (u8 y
= sy
; y
< ey
; ++y
, rowp
+= MAPW
)
39 // update tiles that are on screen
40 if (MTYPE(to
) == MAP_OPENDOOR
)
41 map_clear_tile_rect(sx
, sy
, dx
, ey
-sy
);
43 map_set_tile_rect(sx
, sy
, dx
, ey
-sy
, g_map
->tiles
[tile_rowoff
[sy
] + sx
]);
48 static void door_open(switch_t
*sw
) {
49 if (toggle(sw
->a
, sw
->b
, MAP_DOOR
, MAP_OPENDOOR
| MAP_FORCECLEAR
)) {
50 g_cells
[sw
->b
*MAPW
+ sw
->a
] = MAP_OPENDOOR
; // clear the clear flag to keep it there
51 map_set_tile(sw
->a
, sw
->b
, g_map
->tiles
[tile_rowoff
[sw
->b
] + sw
->a
]);
55 static bool door_shut(switch_t
*sw
) {
56 toggle(sw
->a
, sw
->b
, MAP_OPENDOOR
, MAP_DOOR
);
60 static inline void sw_trigger(switch_t
*sw
, u16 f
) {
64 if (g_cells
[sw
->b
*MAPW
+ sw
->a
] != MAP_DOOR
)
71 if (MTYPE(g_cells
[sw
->b
*MAPW
+ sw
->a
]) != MAP_OPENDOOR
)
78 // swsnd = Z_sound(sndnoway, 128);
86 void sw_use(s16 x
, s16 y
, s16 r
, s16 h
, u16 f
) {
87 s16 i
, j
, sx
, sy
, row
;
89 sy
= (y
- h
+ 1) >> 3;
94 if (x
>= MAPW
) x
= MAPW
- 1;
95 if (y
>= MAPH
) y
= MAPH
- 1;
98 for (j
= sy
; j
<= y
; ++j
, row
+= MAPW
) {
99 for (i
= sx
; i
<= x
; ++i
) {
100 swid
= g_map
->swmap
[row
+ i
];
102 sw_trigger(g_sw
+ swid
, f
);