OpenCores
URL https://opencores.org/ocsvn/layer2/layer2/trunk

Subversion Repositories layer2

[/] [layer2/] [trunk/] [sw/] [tennmino/] [tiles.c] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 idiolatrie
/******************************************************************************
2
 * Tennmino Version 0.1                                                       *
3
 ******************************************************************************
4
 * Copyright (C)2011  Mathias Hörtnagl <mathias.hoertnagl@gmail.com>          *
5
 *                                                                            *
6
 * This program is free software: you can redistribute it and/or modify       *
7
 * it under the terms of the GNU General Public License as published by       *
8
 * the Free Software Foundation, either version 3 of the License, or          *
9
 * (at your option) any later version.                                        *
10
 *                                                                            *
11
 * This program is distributed in the hope that it will be useful,            *
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
14
 * GNU General Public License for more details.                               *
15
 *                                                                            *
16
 * You should have received a copy of the GNU General Public License          *
17
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.      *
18
 ******************************************************************************/
19
#include "tiles.h"
20
 
21
/* The current tile. */
22
static Tile tile;
23
 
24
/* The state of the move. Can be either
25
      MOVE_CONTINUE when everything is okay to move or
26
      MOVE_BLOCKED  when the tile can not move down anymore. */
27
static uchar moveState = MOVE_CONTINUE;
28
 
29
/* The sequences of each tile
30
   A tile is represented by a 16bit unsigned number. Every 4bit represent a
31
   line of the 4x4 tile starting on the top. */
32
static ushort seq[7][4] = {
33
   {0x4444, 0x00f0, 0x4444, 0x00f0},   /* I */
34
   {0x0e20, 0x6440, 0x8e00, 0x44c0},   /* J */
35
   {0x02e0, 0x6220, 0xe800, 0x88c0},   /* L */
36
   {0x0660, 0x0660, 0x0660, 0x0660},   /* O */
37
   {0x0e40, 0x4c40, 0x4e00, 0x4640},   /* T */
38
   {0x06c0, 0x4620, 0x06c0, 0x4620},   /* S */
39
   {0x0c60, 0x2640, 0x0c60, 0x2640}    /* Z */
40
};
41
 
42
 
43
/******************************************************************************
44
 * Reading VGA RAM                                                            *
45
 ******************************************************************************/
46
/* Read contetnts of the VGA RAM at location (x,y). */
47
uchar getVGAContents(uchar x, uchar y) {
48
   return (VGA_MEMORY[ VGA_POS(x, y) ] & 0xff);
49
}
50
 
51
/* Read a 4x4 area of the VGA RAM starting at loaction (x,y). */
52
uint getVGAMask(uchar x, uchar y) {
53
 
54
   uint mask = 0;
55
 
56
   for(uchar i=0; i < 4; i++) {
57
      for(uchar j=0; j < 8; j+=2) {
58
         if( getVGAContents(x + j, y + i) == CHR_FULL )
59
            mask |= 1;
60
 
61
         mask <<= 1;
62
      }
63
   }
64
   return mask >> 1; // Shifting happens once too often.
65
}
66
 
67
 
68
/******************************************************************************
69
 * Tile Placement                                                             *
70
 ******************************************************************************/
71
/* Initialize a tile at te top of the board. */
72
void initTile(uchar type) {
73
   tile.type = type;
74
   tile.tile = seq[type][0];
75
   tile.ridx = 0;
76
   tile.pos.x = VGA_H/2 - 2;     // Center tile horizontally.
77
   tile.pos.y = 0;
78
   drawTile();
79
}
80
 
81
/* Print the current tile either visible or invisible to erase it from the
82
   screen. */
83
void printTile(uchar chr) {
84
 
85
   ushort pos;
86
   ushort mask = 0x8000;
87
 
88
   for(uchar i=0; i < 4; i++) {
89
      for(uchar j=0; j < 8; j+=2) {
90
         if(tile.tile & mask) {
91
            pos = VGA_POS(tile.pos.x + j, tile.pos.y + i);
92
            VGA_MEMORY[pos] = VGA_CHR(tile.type + 1, BLACK, chr);
93
            VGA_MEMORY[++pos] = VGA_CHR(tile.type + 1, BLACK, chr);
94
         }
95
         mask >>= 1;
96
      }
97
   }
98
}
99
 
100
 
101
/******************************************************************************
102
 * Tile Movement                                                              *
103
 ******************************************************************************/
104
/* Rotate the tile if its new rotation does not interfere with already present
105
   tiles or the game board. */
106
void rotate() {
107
 
108
   ushort mask;
109
   uchar ridx;
110
   ushort rtile;
111
 
112
   eraseTile();
113
 
114
   mask = (ushort) getVGAMask(tile.pos.x, tile.pos.y);
115
   ridx = ++tile.ridx & 3;              // Mod 4 counter.   
116
   rtile = seq[tile.type][ridx];
117
 
118
   // See if the rotated tile and the area share occupied blocks. 
119
   if(mask & rtile) {
120
      // If true we can not accept the rotation of the tile. Instead
121
      // draw the original tile once more.     
122
      moveState = MOVE_BLOCKED;
123
   }
124
   else {
125
      tile.ridx = ridx;
126
      tile.tile = rtile;
127
      moveState = MOVE_CONTINUE;
128
   }
129
 
130
   drawTile();
131
}
132
 
133
/* Move in any direction and check if the tile does not interfere with already
134
   present tiles or the borders of the game board. */
135
void move(char x, char y) {
136
 
137
   ushort mask;
138
 
139
   eraseTile();
140
 
141
   // Grab the area for the tiles next position. The old tile is erased and 
142
   // won't interfere with the match.
143
   mask = (ushort) getVGAMask(tile.pos.x + x, tile.pos.y + y);
144
 
145
   // See if the tile and the area share occupied blocks. 
146
   if(mask & tile.tile) {
147
      // If true we can not continue with the movement of the tile. Instead
148
      // draw the tile at the old position once more and change moveState.     
149
      moveState = MOVE_BLOCKED;
150
   }
151
   else {
152
      tile.pos.x += x;
153
      tile.pos.y += y;
154
      moveState = MOVE_CONTINUE;
155
   }
156
 
157
   drawTile();
158
}
159
 
160
 
161
/******************************************************************************
162
 * Game State                                                                 *
163
 ******************************************************************************/
164
/* Return the current game state. Can be either
165
      GAME_CONTINUE if the game can continue without further processing.
166
      GAME_NEW_TILE if the current tile is stuck and a new tile needs to be
167
                    initialized.
168
      GAME_OVER     if the current tile can not move down from the beginning.
169
 */
170
uchar getGameState() {
171
 
172
   switch(moveState) {
173
      case MOVE_BLOCKED:
174
         return (tile.pos.y == 0) ? GAME_OVER : GAME_NEW_TILE;
175
 
176
      default:
177
         return GAME_CONTINUE;
178
         break;
179
   }
180
}
181
 
182
 
183
/******************************************************************************
184
 * Deletion of Lines                                                          *
185
 ******************************************************************************/
186
/* Deletes one complete row and scrolls down the remaining board. */
187
uchar deleteCompletedRow(uchar x, uchar y, uchar w) {
188
 
189
   ushort pos = VGA_POS(x, y);
190
 
191
   for(uchar i=0; i<w; i++){
192
      if( (VGA_MEMORY[pos + i] & 0xff) != CHR_FULL )
193
         return 0;
194
   }
195
 
196
   for(uchar j = y; j>0; j--)
197
      for(uchar i=0; i<w; i++)
198
         VGA_MEMORY[VGA_POS( (x+i), j )] = VGA_MEMORY[VGA_POS( (x+i), (j-1) )];
199
 
200
   return 1;
201
}
202
 
203
/* Deletes up to four complete rows and scrolls down acordingly. Returns the
204
   number of deleted rows. For x deleted lines return
205
 
206
      1  ...   128 points
207
      2  ...   256 points
208
      3  ...   512 points
209
      4  ...  1024 points
210
 */
211
uint deleteCompletedRows(uchar x, uchar w) {
212
 
213
   uchar cnt = 0;
214
 
215
   for(uchar i=0; i<4; i++) {
216
      // Empty tile lines do not change anything. 
217
      if( tile.tile & (0xf000 >> (i*4)) )
218
         cnt += deleteCompletedRow(x, tile.pos.y + i, w);
219
   }
220
   return (cnt << 7);
221
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.