aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--field.c47
-rw-r--r--field.h2
-rw-r--r--util.h54
-rw-r--r--worm.c94
4 files changed, 130 insertions, 67 deletions
diff --git a/field.c b/field.c
index ea7ed77..cf4e4de 100644
--- a/field.c
+++ b/field.c
@@ -32,6 +32,7 @@
#endif
+#include "util.h"
#include "field.h"
#include "player.h"
@@ -141,6 +142,15 @@ int check_wall(WPLAYER *player)
return field[player->head->c_x][player->head->c_y] == CELLWALL ? DEAD : ALIVE;
}
+static void getcellrect(char cx, char cy, int xoffset, int yoffset,
+ int cellwidth, int cellheight, GRECT *rc)
+{
+ rc->g_x = xoffset + cx*cellwidth;
+ rc->g_y = yoffset + cy*cellheight;
+ rc->g_w = cellwidth;
+ rc->g_h = cellheight;
+}
+
void drawcell(WORD h_vdi, int type, char cx, char cy,
int xoffset, int yoffset, int cellwidth, int cellheight)
{
@@ -202,11 +212,12 @@ WUNIT *walker;
cellwidth, cellheight);
}
-void draw_field(WORD h_vdi, GRECT *play)
+void draw_field(WORD h_vdi, GRECT *play, GRECT *dirty)
{
char i,j;
WORD pts[4];
int cellwidth, cellheight;
+GRECT crc;
#ifdef VDEBUG
printf("%d: %d %d %d %d\n",h_vdi,play->g_x,play->g_y,play->g_w,play->g_h);
@@ -216,8 +227,14 @@ int cellwidth, cellheight;
/* Fill background */
vsf_color(h_vdi, (WORD)WHITE);
- pts[0] = play->g_x; pts[1] = play->g_y;
- pts[2] = play->g_x+play->g_w; pts[3] = play->g_y+play->g_h;
+
+ if(dirty == NULL) {
+ pts[0] = play->g_x; pts[1] = play->g_y;
+ pts[2] = play->g_x+play->g_w; pts[3] = play->g_y+play->g_h;
+ } else {
+ pts[0] = dirty->g_x; pts[1] = dirty->g_y;
+ pts[2] = dirty->g_x+dirty->g_w; pts[3] = dirty->g_y+dirty->g_h;
+ }
v_bar(h_vdi,pts);
cellwidth = max(1,play->g_w/CELLW);
@@ -226,10 +243,26 @@ int cellwidth, cellheight;
/* Draw all cells */
for(i=0;i<CELLW;i++) {
for(j=0;j<CELLH;j++) {
- if(field[i][j] != CELLBLANK)
- drawcell(h_vdi, field[i][j], i, j,
- play->g_x, play->g_y,
- cellwidth, cellheight);
+ if(field[i][j] != CELLBLANK) {
+ if(dirty == NULL)
+ drawcell(h_vdi, field[i][j], i, j,
+ play->g_x, play->g_y,
+ cellwidth, cellheight);
+ else {
+ getcellrect(i, j,
+ play->g_x, play->g_y,
+ cellwidth, cellheight,
+ &crc);
+
+ /* Only draw if inside the dirty */
+ if(rc_intersect(dirty, &crc)) {
+ drawcell(h_vdi, field[i][j], i, j,
+ play->g_x, play->g_y,
+ cellwidth, cellheight);
+
+ }
+ }
+ }
}
}
diff --git a/field.h b/field.h
index 4cd7bad..4224238 100644
--- a/field.h
+++ b/field.h
@@ -48,7 +48,7 @@ void field_init(void);
/* Checks if the player died due to wall collision */
int check_wall(WPLAYER *player);
-void draw_field(WORD h_vdi, GRECT *play);
+void draw_field(WORD h_vdi, GRECT *play, GRECT *dirty);
int update_field(WPLAYER *player);
diff --git a/util.h b/util.h
new file mode 100644
index 0000000..db82c04
--- /dev/null
+++ b/util.h
@@ -0,0 +1,54 @@
+#ifndef UTIL_WORM_HEADERS
+#define UTIL_WORM_HEADERS
+
+/* Mostly compatability stuff */
+
+#ifdef __GNUC__
+
+#include <gem.h>
+
+#define HIWORD(x) ((int16_t)((uint32_t)x >> 16))
+#define LOWORD(x) ((int16_t)((uint32_t)x & 0xFFFF))
+
+#else
+
+#include <portab.h>
+#include <aes.h>
+#include <vdi.h>
+
+#endif /* __GNUC__ */
+
+#ifndef WF_WXYWH
+#ifdef WF_WORKXYWH
+#define WF_WXYWH WF_WORKXYWH
+#endif
+#endif
+
+#ifndef WF_CXYWH
+#ifdef WF_CURRXYWH
+#define WF_CXYWH WF_CURRXYWH
+#endif
+#endif
+
+#define max(x,y) x>y ? x : y
+#define min(x,y) x<y ? x : y
+
+#ifndef MGEMLIB
+static int rc_intersect(const GRECT *one, GRECT *two)
+{
+WORD tx,ty,tw,th;
+
+ tw = min(one->g_x+one->g_w,two->g_x+two->g_w);
+ th = min(one->g_y+one->g_h,two->g_y+two->g_h);
+ tx = max(one->g_x,two->g_x);
+ ty = max(one->g_y,two->g_y);
+ two->g_x = tx;
+ two->g_y = ty;
+ two->g_w = tw-tx;
+ two->g_h = th-ty;
+ return ( (tw > tx) && (th > ty) );
+}
+#endif
+
+
+#endif /* UTIL_WORM_HEADERS */
diff --git a/worm.c b/worm.c
index 6b2addd..4870bde 100644
--- a/worm.c
+++ b/worm.c
@@ -43,6 +43,7 @@
#include "wormst.h"
#endif
+#include "util.h"
#include "field.h"
#include "player.h"
@@ -74,21 +75,6 @@ GRECT app_wdw; /* xywh of working area */
OBJECT FAR *app_menu;
OBJECT FAR *about_box;
-#ifndef WF_WXYWH
-#ifdef WF_WORKXYWH
-#define WF_WXYWH WF_WORKXYWH
-#endif
-#endif
-
-#ifndef WF_CXYWH
-#ifdef WF_CURRXYWH
-#define WF_CXYWH WF_CURRXYWH
-#endif
-#endif
-
-#define max(x,y) x>y ? x : y
-#define min(x,y) x<y ? x : y
-
#ifdef PCGEM
#define RCS_FILE "wormpc.rsc"
#else
@@ -100,23 +86,6 @@ OBJECT FAR *about_box;
#define STARTWIDTH 640
#define STARTHEIGHT 480
-#ifndef MGEMLIB
-int rc_intersect(const GRECT *one, GRECT *two)
-{
-WORD tx,ty,tw,th;
-
- tw = min(one->g_x+one->g_w,two->g_x+two->g_w);
- th = min(one->g_y+one->g_h,two->g_y+two->g_h);
- tx = max(one->g_x,two->g_x);
- ty = max(one->g_y,two->g_y);
- two->g_x = tx;
- two->g_y = ty;
- two->g_w = tw-tx;
- two->g_h = th-ty;
- return ( (tw > tx) && (th > ty) );
-}
-#endif
-
void hndl_about()
{
GRECT box,origin;
@@ -276,7 +245,7 @@ int sh;
#define PRINTRC(n,r) printf("%s -> x=%d y=%d w=%d h=%d\n", n, r.g_x, r.g_y, r.g_w, r.g_h)
/* Not necessary yet... */
-void do_redraw(WPLAYER *player, int playing)
+void do_redraw(WPLAYER *player, int playing, GRECT *dirty)
{
GRECT box, me, field, score, rc;
int updated_score;
@@ -310,37 +279,43 @@ WORD pts[4];
PRINTRC("field", field);
#endif
- memcpy(&rc, &field, sizeof(GRECT));
- if(rc_intersect(&box, &rc)) {
+ /* See if this rect intersects the reported dirty */
+ if(dirty == NULL || rc_intersect(dirty, &box)) {
+
+ memcpy(&rc, &field, sizeof(GRECT));
+ if(rc_intersect(&box, &rc)) {
#ifdef DEBUG
- printf("Field draw\n");
+ printf("Field draw\n");
#endif
- pts[0] = box.g_x;
- pts[1] = box.g_y;
- pts[2] = box.g_w+box.g_x-1;
- pts[3] = box.g_h+box.g_y-1;
- vs_clip(app_vh, 1, pts);
- draw_field(app_vh, &field);
- }
-
+ pts[0] = box.g_x;
+ pts[1] = box.g_y;
+ pts[2] = box.g_w+box.g_x-1;
+ pts[3] = box.g_h+box.g_y-1;
+ vs_clip(app_vh, 1, pts);
+ draw_field(app_vh, &field, &rc);
+ }
+
#ifdef DEBUG
- PRINTRC("box", box);
- PRINTRC("score", score);
+ PRINTRC("box", box);
+ PRINTRC("score", score);
#endif
-
- memcpy(&rc, &score, sizeof(GRECT));
- if(rc_intersect(&box, &rc)) {
+
+ memcpy(&rc, &score, sizeof(GRECT));
+ if(rc_intersect(&box, &rc)) {
#ifdef DEBUG
- printf("Score draw\n");
+ printf("Score draw\n");
#endif
- pts[0] = box.g_x;
- pts[1] = box.g_y;
- pts[2] = box.g_w+box.g_x-1;
- pts[3] = box.g_h+box.g_y-1;
- vs_clip(app_vh, 1, pts);
- do_redraw_score(player, &score, playing);
- /* updated_score = 1; */
+ pts[0] = box.g_x;
+ pts[1] = box.g_y;
+ pts[2] = box.g_w+box.g_x-1;
+ pts[3] = box.g_h+box.g_y-1;
+ vs_clip(app_vh, 1, pts);
+ do_redraw_score(player, &score, playing);
+ /* updated_score = 1; */
+ }
+
}
+
wind_get(app_wh, WF_NEXTXYWH, &box.g_x,
&box.g_y,
&box.g_w,
@@ -560,11 +535,12 @@ EVMULT_OUT evout;
do_window_change((GRECT *)&msg[4]);
memcpy(&field, &app_wdw, sizeof(GRECT));
window_to_field_rect(&field);
+ /*break;*/
/* Fall through */
case WM_REDRAW:
update_field(player);
- do_redraw(player, playing);
+ do_redraw(player, playing, (GRECT *)&msg[4]);
break;
case MN_SELECTED:
@@ -579,7 +555,7 @@ EVMULT_OUT evout;
playing = 1;
force_redraw_score(player, playing);
update_field(player);
- draw_field(app_vh, &field);
+ draw_field(app_vh, &field, NULL);
break;
case MABOUT:
hndl_about();