comparison src/ljgba.c @ 0:c84446dfb3f5

initial add
author paulo@localhost
date Fri, 13 Mar 2009 00:39:12 -0700
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:5e807afc5af3
1 /* GBA frontend for LOCKJAW, an implementation of the Soviet Mind Game
2
3 Copyright (C) 2006-2007 Damian Yerrick <tepples+lj@spamcop.net>
4
5 This work is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 Original game concept and design by Alexey Pajitnov.
20 The Software is not sponsored or endorsed by Alexey Pajitnov, Elorg,
21 or The Tetris Company LLC.
22
23 */
24
25 #include <stdio.h>
26 #include <string.h>
27 #include "ljgba.h"
28 #include "ljplay.h"
29 #include "options.h"
30
31 #if 1
32 #define LJ_VERSION "0.46 ("__DATE__")"
33 #else
34 #define LJ_VERSION "WIP ("__DATE__")"
35 #endif
36
37 #define SCREEN_W 30
38 #define SCREEN_H 20
39 #define DS_PFTOP 0
40 #define DS_PFLEFT 9
41 #include "ljgbads.inc"
42
43 static unsigned int nSprites;
44
45 LJBits readHWKeys(void) {
46 return (~REG_KEYINPUT) & 0x03FF;
47 }
48
49 void finishSprites() {
50 for (int i = nSprites - 1; i >= 0; --i) {
51 OAM[i].attr0 = 512;
52 }
53 nSprites = 128;
54 }
55
56 void vsync(void) {
57 VBlankIntrWait();
58 }
59
60 void openWindow(void) {
61 REG_DISPCNT = MODE_0 | BG0_ON | OBJ_ON;
62 BGCTRL[0] = BG_TILE_BASE(0) | BG_MAP_BASE(31);
63 BG_PALETTE[0] = RGB5(31, 31, 31);
64 BG_PALETTE[1] = RGB5(0, 0, 0);
65 SPRITE_PALETTE[0] = RGB5(31, 0, 31);
66 SPRITE_PALETTE[1] = RGB5(0, 0, 0);
67 setupPalette(srsColors);
68 }
69
70 void playSoundEffects(LJView *v, LJBits sounds, int countdown) {
71 if (sounds & LJSND_IRS) {
72 gba_play_sound(v->plat, 6);
73 } else if (sounds & LJSND_ROTATE) {
74 gba_play_sound(v->plat, 1);
75 }
76 if (sounds & LJSND_SHIFT) {
77 gba_play_sound(v->plat, 0);
78 }
79 if (sounds & LJSND_LAND) {
80 gba_play_sound(v->plat, 2);
81 }
82 if (sounds & LJSND_LOCK) {
83 gba_play_sound(v->plat, 3);
84 }
85 if (sounds & LJSND_B2B) {
86 gba_play_sound(v->plat, 8);
87 } else if (sounds & LJSND_SETB2B) {
88 gba_play_sound(v->plat, 7);
89 } else if (sounds & LJSND_LINE) {
90 gba_play_sound(v->plat, 4);
91 }
92 if (sounds & LJSND_HOLD) {
93 gba_play_sound(v->plat, 5);
94 }
95 if (sounds & LJSND_SECTIONUP) {
96 gba_play_sound(v->plat, 9);
97 }
98 gba_poll_sound(v->plat);
99 }
100
101 /**
102 * Draws a tetromino whose lower left corner of the bounding box is at (x, y)
103 * @param b the bitmap to draw to
104 * @param piece the piece to be drawn
105 * @param x distance from to left side of 4x4 box
106 * @param y distance from top of bitmap to bottom of 4x4 box
107 * @param the rotation state (0: U; 1: R; 2: D; 3: L; 4: Initial position)
108 * @param w width of each block
109 * @param h height of each block
110 * @param color Drawing style
111 * color == 0: draw shadow
112 * color == 0x10 through 0x70: draw in that color
113 * color == 0x80: draw as garbage
114 * color == -255 through -1: draw with 255 through 1 percent lighting
115 */
116 LJBits drawPiece(LJView *const v, void *const b,
117 int piece, int x, int y, int theta,
118 int color, int w, int h) {
119 // Don't try to draw the -1 that's the sentinel for no hold piece
120 if (piece < 0)
121 return 0;
122
123 LJBits rows = 0;
124 LJBlkSpec blocks[4];
125
126 expandPieceToBlocks(blocks, v->field, piece, 0, 0, theta);
127
128 for (int blk = 0; blk < 4; ++blk) {
129 int blkValue = blocks[blk].conn;
130 if (blkValue) {
131 int blkX = blocks[blk].x;
132 int blkY = blocks[blk].y;
133 const int dstX = x + w * blkX;
134 const int dstY = y + h * (-1 - blkY);
135
136 if (color == 0x80) {
137 blkValue = 0x8001; // garbage hold
138 } else if (color != 0) {
139 blkValue = ((blkValue & 0xF0) << 8) | 1;
140 } else if (color == 0) {
141 if (v->hideShadow == LJSHADOW_COLORED) {
142 blkValue = ((blkValue & 0xF0) << 8) | 2;
143 } else {
144 blkValue = 0x0002;
145 }
146 }
147
148 if (dstY > -8 && dstY < 160) {
149 --nSprites;
150 OAM[nSprites].attr0 = dstY & 0x00FF;
151 OAM[nSprites].attr1 = dstX & 0x01FF;
152 OAM[nSprites].attr2 = blkValue;
153 }
154
155 rows |= 1 << blkY;
156 }
157 }
158
159 return rows;
160 }
161
162 extern unsigned char prefs[OPTIONS_MENU_LEN];
163
164 #include "gbamenus.h"
165
166 int main(void) {
167 LJField p = {
168 .leftWall = 1,
169 .rightWall = 11,
170 .ceiling = 20
171 };
172 LJControl control = {
173 .dasSpeed = 1,
174 .dasDelay = 10,
175 .initialDAS = 1,
176 .allowDiagonals = 0,
177 .softDropSpeed = 0,
178 .softDropLock = 0,
179 .hardDropLock = 1
180 };
181 struct LJPCView platView;
182 LJView mainView = {
183 .field = &p,
184 .control = &control,
185 .smoothGravity = 1,
186 .plat = &platView,
187 .backDirty = ~0
188 };
189
190 videoSetMode(MODE_0_2D);
191 BG_PALETTE[0] = RGB5(31, 0, 0);
192 install_timer();
193 openWindow();
194 install_sound(&platView);
195 initOptions(customPrefs);
196 coprNotice();
197
198 while (1) {
199 LJView *const players[1] = {&mainView};
200 REG_DISPCNT = MODE_0 | BG0_ON;
201 BG_PALETTE[0] = RGB5(31, 31, 31);
202 setupPalette(srsColors);
203 options(&mainView, customPrefs);
204 unpackCommonOptions(&mainView, customPrefs);
205
206 p.seed = curTime ^ (curTime << 16);
207 play(players, 1);
208 BG_PALETTE[0] = (control.countdown > 0)
209 ? RGB5(31, 15, 15)
210 : RGB5(15, 31, 15);
211 if (control.countdown > 0) {
212 gba_play_sound(&platView, 10);
213 gba_play_sound(&platView, 11);
214 } else {
215 gba_play_sound(&platView, 12);
216 gba_play_sound(&platView, 13);
217 }
218 for (int i = 0; i < 60; ++i) {
219 vsync();
220 gba_poll_sound(&platView);
221 }
222 #if 1
223 debrief(&mainView);
224 #else
225 textout(" Press ", (SCREEN_W - 8) / 2, DS_PFTOP + 8, 0);
226 textout(" Start ", (SCREEN_W - 8) / 2, DS_PFTOP + 9, 0);
227 waitForStart();
228 #endif
229 }
230 }